hardware-dma
DMA 控制器 API。
详细描述
RP 系列微控制器直接内存访问(DMA)主控器代表处理器执行批量数据传输,使处理器可以专注于其他任务或进入低功耗睡眠状态。DMA 的数据吞吐量也显著高于 RP 系列微控制器的处理器。
DMA 每个时钟周期可执行一次读访问和一次写访问,每次最多 32 位。共有 12 个独立通道,每个通道监管一系列总线传输,通常适用于以下场景:
-
内存到外设
-
外设到内存
-
内存到内存
模块
channel_config
DMA 通道配置。
宏
#define DMA_IRQ_NUM(irq_index)
类型定义
typedef enum dreq_num_rp2350 dreq_num_t RP2350
RP2350 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
typedef enum dreq_num_rp2040 dreq_num_t RP2040
RP2040 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
- typedef enum dma_channel_transfer_size dma_channel_transfer_size_t: 可用 DMA 通道传输大小的枚举。
- typedef enum dma_address_update_type dma_address_update_type_t: 每次传输后可对 DMA 读写地址进行的更新类型枚举。
枚举
enum dreq_num_rp2350 { [DREQ_PIO0_TX0] = 0, [DREQ_PIO0_TX1] = 1, [DREQ_PIO0_TX2] = 2, [DREQ_PIO0_TX3] = 3, [DREQ_PIO0_RX0] = 4, [DREQ_PIO0_RX1] = 5, [DREQ_PIO0_RX2] = 6, [DREQ_PIO0_RX3] = 7, [DREQ_PIO1_TX0] = 8, [DREQ_PIO1_TX1] = 9, [DREQ_PIO1_TX2] = 10, [DREQ_PIO1_TX3] = 11, [DREQ_PIO1_RX0] = 12, [DREQ_PIO1_RX1] = 13, [DREQ_PIO1_RX2] = 14, [DREQ_PIO1_RX3] = 15, [DREQ_PIO2_TX0] = 16, [DREQ_PIO2_TX1] = 17, [DREQ_PIO2_TX2] = 18, [DREQ_PIO2_TX3] = 19, [DREQ_PIO2_RX0] = 20, [DREQ_PIO2_RX1] = 21, [DREQ_PIO2_RX2] = 22, [DREQ_PIO2_RX3] = 23, [DREQ_SPI0_TX] = 24, [DREQ_SPI0_RX] = 25, [DREQ_SPI1_TX] = 26, [DREQ_SPI1_RX] = 27, [DREQ_UART0_TX] = 28, [DREQ_UART0_RX] = 29, [DREQ_UART1_TX] = 30, [DREQ_UART1_RX] = 31, [DREQ_PWM_WRAP0] = 32, [DREQ_PWM_WRAP1] = 33, [DREQ_PWM_WRAP2] = 34, [DREQ_PWM_WRAP3] = 35, [DREQ_PWM_WRAP4] = 36, [DREQ_PWM_WRAP5] = 37, [DREQ_PWM_WRAP6] = 38, [DREQ_PWM_WRAP7] = 39, [DREQ_PWM_WRAP8] = 40, [DREQ_PWM_WRAP9] = 41, [DREQ_PWM_WRAP10] = 42, [DREQ_PWM_WRAP11] = 43, [DREQ_I2C0_TX] = 44, [DREQ_I2C0_RX] = 45, [DREQ_I2C1_TX] = 46, [DREQ_I2C1_RX] = 47, [DREQ_ADC] = 48, [DREQ_XIP_STREAM] = 49, [DREQ_XIP_QMITX] = 50, [DREQ_XIP_QMIRX] = 51, [DREQ_HSTX] = 52, [DREQ_CORESIGHT] = 53, [DREQ_SHA256] = 54, [DREQ_DMA_TIMER0] = 59, [DREQ_DMA_TIMER1] = 60, [DREQ_DMA_TIMER2] = 61, [DREQ_DMA_TIMER3] = 62, [DREQ_FORCE] = 63, DREQ_COUNT } RP2350
RP2350 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
enum dreq_num_rp2040 { [DREQ_PIO0_TX0] = 0, [DREQ_PIO0_TX1] = 1, [DREQ_PIO0_TX2] = 2, [DREQ_PIO0_TX3] = 3, [DREQ_PIO0_RX0] = 4, [DREQ_PIO0_RX1] = 5, [DREQ_PIO0_RX2] = 6, [DREQ_PIO0_RX3] = 7, [DREQ_PIO1_TX0] = 8, [DREQ_PIO1_TX1] = 9, [DREQ_PIO1_TX2] = 10, [DREQ_PIO1_TX3] = 11, [DREQ_PIO1_RX0] = 12, [DREQ_PIO1_RX1] = 13, [DREQ_PIO1_RX2] = 14, [DREQ_PIO1_RX3] = 15, [DREQ_SPI0_TX] = 16, [DREQ_SPI0_RX] = 17, [DREQ_SPI1_TX] = 18, [DREQ_SPI1_RX] = 19, [DREQ_UART0_TX] = 20, [DREQ_UART0_RX] = 21, [DREQ_UART1_TX] = 22, [DREQ_UART1_RX] = 23, [DREQ_PWM_WRAP0] = 24, [DREQ_PWM_WRAP1] = 25, [DREQ_PWM_WRAP2] = 26, [DREQ_PWM_WRAP3] = 27, [DREQ_PWM_WRAP4] = 28, [DREQ_PWM_WRAP5] = 29, [DREQ_PWM_WRAP6] = 30, [DREQ_PWM_WRAP7] = 31, [DREQ_I2C0_TX] = 32, [DREQ_I2C0_RX] = 33, [DREQ_I2C1_TX] = 34, [DREQ_I2C1_RX] = 35, [DREQ_ADC] = 36, [DREQ_XIP_STREAM] = 37, [DREQ_XIP_SSITX] = 38, [DREQ_XIP_SSIRX] = 39, [DREQ_DMA_TIMER0] = 59, [DREQ_DMA_TIMER1] = 60, [DREQ_DMA_TIMER2] = 61, [DREQ_DMA_TIMER3] = 62, [DREQ_FORCE] = 63, DREQ_COUNT } RP2040
RP2040 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
enum dma_channel_transfer_size { [DMA_SIZE_8] = 0, [DMA_SIZE_16] = 1, [DMA_SIZE_32] = 2 }: 可用 DMA 通道传输大小的枚举。enum dma_address_update_type { [DMA_ADDRESS_UPDATE_NONE] = 0, [DMA_ADDRESS_UPDATE_INCREMENT] = 1 }: 每次传输后可对 DMA 读写地址进行的更新类型枚举。
函数
void dma_channel_claim (uint channel): 将 DMA 通道标记为已使用。void dma_claim_mask (uint32_t channel_mask): 将多个 DMA 通道标记为已使用。void dma_channel_unclaim (uint channel): 将 DMA 通道标记为不再使用。void dma_unclaim_mask (uint32_t channel_mask): 将多个 DMA 通道标记为不再使用。int dma_claim_unused_channel (bool required): 申请一个空闲的 DMA 通道。bool dma_channel_is_claimed (uint channel): 判断 DMA 通道是否已被申请。static void dma_channel_set_config (uint channel, const dma_channel_config_t *config, bool trigger)
设置通道配置。
static void dma_channel_set_read_addr (uint channel, const volatile void *read_addr, bool trigger)
设置 DMA 初始读取地址。
static void dma_channel_set_write_addr (uint channel, volatile void *write_addr, bool trigger)
设置 DMA 初始写入地址。
static uint32_t dma_encode_transfer_count (uint transfer_count): 将指定传输长度编码为适合相关方法的"encoded_transfer_length"值。static uint32_t dma_encode_transfer_count_with_self_trigger (uint transfer_count): 将指定传输长度以及自触发标志编码为适合相关方法的"encoded_transfer_length"值。static uint32_t dma_encode_endless_transfer_count (void): 返回无限传输的"encoded_transfer_length"值。static void dma_channel_set_transfer_count (uint channel, uint32_t encoded_transfer_count, bool trigger): 设置通道将执行的总线传输次数。static void dma_channel_configure (uint channel, const dma_channel_config_t **config, volatile void **write_addr, const volatile void *read_addr, uint32_t encoded_transfer_count, bool trigger)
配置所有 DMA 参数并可选地启动传输。
static void dma_channel_transfer_from_buffer_now (uint channel, const volatile void *read_addr, uint32_t encoded_transfer_count)
立即从缓冲区启动 DMA 传输。
static void dma_channel_transfer_to_buffer_now (uint channel, volatile void *write_addr, uint32_t encoded_transfer_count)
立即向缓冲区启动 DMA 传输。
static void dma_start_channel_mask (uint32_t chan_mask): 同时启动一个或多个通道。static void dma_channel_start (uint channel): 启动单个 DMA 通道。static void dma_channel_abort (uint channel): 停止 DMA 传输。static void dma_channel_set_irq0_enabled (uint channel, bool enabled): 通过 DMA_IRQ_0 启用单个 DMA 通道的中断。static void dma_set_irq0_channel_mask_enabled (uint32_t channel_mask, bool enabled): 通过 DMA_IRQ_0 启用多个 DMA 通道的中断。static void dma_channel_set_irq1_enabled (uint channel, bool enabled): 通过 DMA_IRQ_1 启用单个 DMA 通道的中断。static void dma_set_irq1_channel_mask_enabled (uint32_t channel_mask, bool enabled): 通过 DMA_IRQ_1 启用多个 DMA 通道的中断。static void dma_irqn_set_channel_enabled (uint irq_index, uint channel, bool enabled): 在 DMA_IRQ_0 或 DMA_IRQ_1 上启用单个 DMA 通道中断。static void dma_irqn_set_channel_mask_enabled (uint irq_index, uint32_t channel_mask, bool enabled): 通过 DMA_IRQ_0 或 DMA_IRQ_1 启用多个 DMA 通道的中断。static bool dma_channel_get_irq0_status (uint channel): 判断特定通道是否是 DMA_IRQ_0 的触发原因。static bool dma_channel_get_irq1_status (uint channel): 判断特定通道是否是 DMA_IRQ_1 的触发原因。static bool dma_irqn_get_channel_status (uint irq_index, uint channel): 判断特定通道是否是 DMA_IRQ_N 的触发原因。static void dma_channel_acknowledge_irq0 (uint channel): 确认通道 IRQ,将其从 DMA_IRQ_0 的触发原因中清除。static void dma_channel_acknowledge_irq1 (uint channel): 确认通道 IRQ,将其从 DMA_IRQ_1 的触发原因中清除。static void dma_irqn_acknowledge_channel (uint irq_index, uint channel): 确认通道 IRQ,将其从 DMA_IRQ_N 的触发原因中清除。static bool dma_channel_is_busy (uint channel): 检查 DMA 通道是否忙碌。static void dma_channel_wait_for_finish_blocking (uint channel): 等待 DMA 通道传输完成。static void dma_sniffer_enable (uint channel, uint mode, bool force_channel_enable): 启用针对指定通道的 DMA 嗅探器。static void dma_sniffer_set_byte_swap_enabled (bool swap): 启用嗅探器字节交换功能。static void dma_sniffer_set_output_invert_enabled (bool invert): 启用嗅探器输出反转功能。static void dma_sniffer_set_output_reverse_enabled (bool reverse): 启用嗅探器输出位反转功能。static void dma_sniffer_disable (void): 禁用 DMA 嗅探器。static void dma_sniffer_set_data_accumulator (uint32_t seed_value): 用初始值设置嗅探器的数据累加器。static uint32_t dma_sniffer_get_data_accumulator (void): 获取嗅探器的数据累加器值。void dma_timer_claim (uint timer): 将 DMA 定时器标记为已使用。void dma_timer_unclaim (uint timer): 将 DMA 定时器标记为不再使用。int dma_claim_unused_timer (bool required): 申请一个空闲的 DMA 定时器。bool dma_timer_is_claimed (uint timer): 判断 DMA 定时器是否已被申请。static void dma_timer_set_fraction (uint timer, uint16_t numerator, uint16_t denominator): 设置给定 DMA 定时器的乘数。static uint dma_get_timer_dreq (uint timer_num): 返回给定 DMA 定时器的 DREQ 编号。static int dma_get_irq_num (uint irq_index): 返回 DMA_IRQ_<irqn>void dma_channel_cleanup (uint channel): 使用后对 DMA 通道进行清理。
宏定义文档
DMA_IRQ_NUM
#define DMA_IRQ_NUM(irq_index)
返回第 n 个 DMA 中断的 irq_num_t。
注意此宏旨在在编译期求值,不做参数检查。
类型定义文档
dreq_num_t RP2350
typedef enum dreq_num_rp2350 dreq_num_t
RP2350 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
dreq_num_t RP2040
typedef enum dreq_num_rp2040 dreq_num_t
RP2040 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
dma_channel_transfer_size_t
typedef enum dma_channel_transfer_size dma_channel_transfer_size_t
可用 DMA 通道传输大小的枚举。
名称表示位数。
dma_address_update_type_t
typedef enum dma_address_update_type dma_address_update_type_t
每次传输后可对 DMA 读写地址进行的更新类型枚举。
枚举类型文档
dreq_num_rp2350 RP2350
enum dreq_num_rp2350
RP2350 上 DMA 节拍的 DREQ 编号(用作 typedef dreq_num_t)
| 枚举值 | 说明 |
|---|---|
| DREQ_PIO0_TX0 | 选择 PIO0 的 TX FIFO 0 作为 DREQ。 |
| DREQ_PIO0_TX1 | 选择 PIO0 的 TX FIFO 1 作为 DREQ。 |
| DREQ_PIO0_TX2 | 选择 PIO0 的 TX FIFO 2 作为 DREQ。 |
| DREQ_PIO0_TX3 | 选择 PIO0 的 TX FIFO 3 作为 DREQ。 |
| DREQ_PIO0_RX0 | 选择 PIO0 的 RX FIFO 0 作为 DREQ。 |
| DREQ_PIO0_RX1 | 选择 PIO0 的 RX FIFO 1 作为 DREQ。 |
| DREQ_PIO0_RX2 | 选择 PIO0 的 RX FIFO 2 作为 DREQ。 |
| DREQ_PIO0_RX3 | 选择 PIO0 的 RX FIFO 3 作为 DREQ。 |
| DREQ_PIO1_TX0 | 选择 PIO1 的 TX FIFO 0 作为 DREQ。 |
| DREQ_PIO1_TX1 | 选择 PIO1 的 TX FIFO 1 作为 DREQ。 |
| DREQ_PIO1_TX2 | 选择 PIO1 的 TX FIFO 2 作为 DREQ。 |
| DREQ_PIO1_TX3 | 选择 PIO1 的 TX FIFO 3 作为 DREQ。 |
| DREQ_PIO1_RX0 | 选择 PIO1 的 RX FIFO 0 作为 DREQ。 |
| DREQ_PIO1_RX1 | 选择 PIO1 的 RX FIFO 1 作为 DREQ。 |
| DREQ_PIO1_RX2 | 选择 PIO1 的 RX FIFO 2 作为 DREQ。 |
| DREQ_PIO1_RX3 | 选择 PIO1 的 RX FIFO 3 作为 DREQ。 |
| DREQ_PIO2_TX0 | 选择 PIO2 的 TX FIFO 0 作为 DREQ。 |
| DREQ_PIO2_TX1 | 选择 PIO2 的 TX FIFO 1 作为 DREQ。 |
| DREQ_PIO2_TX2 | 选择 PIO2 的 TX FIFO 2 作为 DREQ。 |
| DREQ_PIO2_TX3 | 选择 PIO2 的 TX FIFO 3 作为 DREQ。 |
| DREQ_PIO2_RX0 | 选择 PIO2 的 RX FIFO 0 作为 DREQ。 |
| DREQ_PIO2_RX1 | 选择 PIO2 的 RX FIFO 1 作为 DREQ。 |
| DREQ_PIO2_RX2 | 选择 PIO2 的 RX FIFO 2 作为 DREQ。 |
| DREQ_PIO2_RX3 | 选择 PIO2 的 RX FIFO 3 作为 DREQ。 |
| DREQ_SPI0_TX | 选择 SPI0 的 TX FIFO 作为 DREQ。 |
| DREQ_SPI0_RX | 选择 SPI0 的 RX FIFO 作为 DREQ。 |
| DREQ_SPI1_TX | 选择 SPI1 的 TX FIFO 作为 DREQ。 |
| DREQ_SPI1_RX | 选择 SPI1 的 RX FIFO 作为 DREQ。 |
| DREQ_UART0_TX | 选择 UART0 的 TX FIFO 作为 DREQ。 |
| DREQ_UART0_RX | 选择 UART0 的 RX FIFO 作为 DREQ。 |
| DREQ_UART1_TX | 选择 UART1 的 TX FIFO 作为 DREQ。 |
| DREQ_UART1_RX | 选择 UART1 的 RX FIFO 作为 DREQ。 |
| DREQ_PWM_WRAP0 | 选择 PWM 计数器 0 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP1 | 选择 PWM 计数器 1 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP2 | 选择 PWM 计数器 2 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP3 | 选择 PWM 计数器 3 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP4 | 选择 PWM 计数器 4 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP5 | 选择 PWM 计数器 5 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP6 | 选择 PWM 计数器 6 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP7 | 选择 PWM 计数器 7 的环绕值作为 DREQ。 |
| DREQ_PWM_WRAP8 |