目录

RP2040的DMA数据传输

1. Rp2040的DMA介绍

RP2040 DMA设计用于以下系统:

此外,DMA的传输fifo和双主结构允许对同一外设同时进行多个访问,以提高总吞吐量。因此,DREQ机制的选择至关重要:

RP2040 DMA使用基于信用的DREQ机制。对于每个外设,DMA尝试保持外设容量所能容纳的传输量。这使得在没有fabric延迟或争用的情况下,通过8深外围FIFO实现全总线吞吐量(每个时钟1个字),而不存在溢出或下流的可能性。

对于每个通道,DMA维护一个计数器。dreq信号上的每个1时钟脉冲将增加计数器(饱和)。当非0时,通道请求从DMA的内部仲裁器进行传输,当将传输发送到地址fifo时,计数器将减少。此时转移正在进行中,但还没有完成。 其效果是根据外围FIFO中可用的空间或数据的数量上限。在稳定状态下,这提供了最大的流量,但不能底流或底流。 需要注意的是,用户不能访问当前由DMA服务的FIFO。这将导致通道和外围设备变得不同步,并可能导致数据损坏或丢失。 另一个警告是,多个通道不应该连接到同一个DREQ。

2. 寄存器列表

3. 示例

void dma_handler() {
    static int pwm_level = 0;
    static uint32_t wavetable[N_PWM_LEVELS];
    static bool first_run = true;
    // Entry number `i` has `i` one bits and `(32 - i)` zero bits. 
    if (first_run) {
        first_run = false;
        for (int i = 0; i < N_PWM_LEVELS; ++i)
            wavetable[i] = ~(~0u << i); 
     }
     // Clear the interrupt request.
 
     dma_hw->ints0 = 1u << dma_chan;
     // Give the channel a new wave table entry to read from, and re-trigger it
     dma_channel_set_read_addr(dma_chan, &wavetable[pwm_level], true);
 
     pwm_level = (pwm_level + 1) % N_PWM_LEVELS;
}