RP2040裸机环境下DMA通道挂起问题排查求助
RP2040裸机DMA内存传输故障排查
尝试在RP2040裸机环境下使用DMA通道完成SRAM内内存到内存传输,遇到以下问题:
- 通道触发忙标志但传输计数无变化
- 芯片卡在
rst_dma循环(该循环用于等待通道清除忙标志) - 移除
rst_dma循环后内存测试失败,且通道未抛出AHB错误
汇编代码
;reset dma ldr r0, *resets_clr ;clear reset mov r1, 4 str r1, (r0, 0) ldr r0, *resets_rw ;confirm reset clear *rst_dma ldr r2, (r0, 2) and r2, r1 beq *rst_dma ;start dma channel ldr r0, *dma_rw adr r1, *var str r1, (r0, 0) ;read addr ldr r1, *sram_addr str r1, (r0, 1) ;write addr mov r1, 8 str r1, (r0, 2) ;trans count mov r1, 47 ;incr_write | size_word | high_priority | en str r1, (r0, 3) ;ctrl trig ;wait for transfer marked complete mov r2, 1 lsl r2, r2, 24 *busy_dma ldr r1, (r0, 3) and r1, r2 bne *busy_dma ;test ldr r0, *sram_addr ldr r1, (r0, 0) mov lr, pc cmp r1, 7 beq *led_on
相关变量值
resets_rw 0x4000c000 resets_clr 0x4000f000 var 7 dma_rw 0x50000000 sram_addr 0x20001000
问题排查与修复
1. 复位等待逻辑错误(循环卡死核心原因)
当前代码读取
(r0, 2)判断复位完成是错误的地址偏移:resets_rw对应RESETS模块的RESET寄存器(0x4000c000),用于控制复位- 复位完成状态需读取
RESET_DONE寄存器,地址为0x4000c008(相对于resets_rw的字节偏移为8) (r0, 2)是字节偏移2,指向无效寄存器地址,导致永远检测不到复位完成,循环卡死
修复后的复位等待代码:
ldr r0, *resets_rw ;RESET寄存器地址0x4000c000 add r0, r0, #8 ;偏移到RESET_DONE寄存器0x4000c008
*rst_dma
ldr r2, [r0] ;读取RESET_DONE寄存器
and r2, r2, #4 ;检查DMA复位完成位(位2)
beq *rst_dma ;未完成则继续等待
#### 2. DMA控制寄存器配置错误 - 控制值`47`(二进制`0b101111`)的SIZE字段配置错误: - SIZE字段对应位2-3:`0b01`表示半字传输,而非注释的字传输 - 若要进行32位字传输,SIZE字段需设为`0b10`,对应数值为8(位3置1) - 正确控制值应为:`INCR_WRITE(32) + SIZE_WORD(8) + HIGH_PRIORITY(2) + EN(1) = 43`(二进制`0b101011`) - 源地址`var`是单个32位变量,无需地址递增,当前`INCR_READ`未置位(默认关闭)的配置正确,无需修改。 #### 3. 复位操作补充说明 - RP2040的`RESETS_CLR`寄存器写1对应位是解除外设复位,你的复位解除操作正确,但必须等待`RESET_DONE`对应位变为1,才能确认外设已退出复位状态。 --- 内容的提问来源于stack exchange,提问作者Will Thomas
相关产品推荐
相关产品推荐

