D1 裸机 DMA
-
小白尝试编写裸机下的DMA驱动
按照指导手册将描述符的地址写入到寄存器中,DMA就能获得相应的信息,但是操作后始终得不到,想请问可能的原因是什么。手册中的指导步骤中有一步 将描述符写入内存具体是什么意思呢。
有参考xboot大佬代码struct dma_d1_desc_t { uint32_t config; uint32_t src; uint32_t dst; uint32_t count; uint32_t para; uint32_t link; uint32_t reserved[2]; }; #pragma pack () /*取消指定对齐,恢复缺省对齐*/ struct dma_d1_desc_t DMA_DESCRIPTION; uint8_t dma_init(uint8_t dmaNo) { virtual_addr_t addr; uint32_t val; write32(D1_CCU_BASE + CCU_PSI_CLK_REG, (2 << 0) | (0 << 8)); write32(D1_CCU_BASE + CCU_PSI_CLK_REG, read32(D1_CCU_BASE + CCU_PSI_CLK_REG) | (0x03 << 24)); sdelaydma(20); /* Dma reset */ write32(D1_CCU_BASE + CCU_DMA_BGR_REG, read32(D1_CCU_BASE + CCU_DMA_BGR_REG) | (1 << 16)); sdelaydma(20); /* Enable gating clock for dma */ write32(D1_CCU_BASE + CCU_DMA_BGR_REG, read32(D1_CCU_BASE + CCU_DMA_BGR_REG) | (1 << 0)); //判断通道是否空闲 addr = DMA_BASE+DMA_STA_REG; val = read32(addr); if(val & (1<<dmaNo)) //当前通道繁忙 { return 0; } else { addr = DMA_BASE + DMA_AUTO_GATE_REG; write32(addr,0x0); addr = DMA_BASE+DMA_EN_REGN(dmaNo); write32(addr,0x0); addr = DMA_BASE+DMA_PAU_REGN(dmaNo); write32(addr,0x1); addr = DMA_BASE+DMA_DESC_ADDR_REGN(dmaNo); write32(addr,0xfffff800); addr = DMA_BASE+DMA_MODE_REFEN(dmaNo); write32(addr,0x0); return 1; } } void dma_send(uint8_t dmaNo,uint32_t sourceaddress,uint32_t length) { DMA_DESCRIPTION.config = DMA_SET_CONFIG();//设置描述符中的config DMA_DESCRIPTION.src = (uint32_t)sourceaddress; //设置描述符中的源地址为要发送的数据数组地址 DMA_DESCRIPTION.dst = (uint32_t)(UART0_BASE+UART_THR); //设置描述符中的目标地址为Uart0的数据发送寄存器地址 DMA_DESCRIPTION.count = (uint32_t)length; //设置描述符中的发送数据的长度 DMA_DESCRIPTION.para = DMA_SET_PARA(); //设置描述符中的参数 DMA_DESCRIPTION.link = 0xfffff800; //设置描述符中的连接地址 uint32_t configaddr = (uint32_t)(&DMA_DESCRIPTION); uint32_t addr_true = (uint32_t)((configaddr <<2)|(configaddr >>30)); smp_mb(); write32(DMA_BASE + DMA_DESC_ADDR_REGN(dmaNo), (uint32_t)addr_true ****粗体字****); //将描述符地址写入描述符地址寄存器 write32(DMA_BASE + DMA_EN_REGN(dmaNo), 1); //使能对应的通道 delay_ms(3000); write32(DMA_BASE + DMA_PAU_REGN(dmaNo), 0); //恢复通道传输 write32(DMA_BASE + DMA_EN_REGN(dmaNo), 0); //关闭相应通道使能 }
还望大佬不吝赐教!!
-
Copyright © 2024 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号