Navigation

    全志在线开发者论坛

    • Register
    • Login
    • Search
    • Categories
    • Tags
    • 在线文档
    • 社区主页

    D1 裸机 DMA

    D1系列-RISC-V
    2
    2
    316
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • S
      secret LV 2 last edited by YuzukiTsuru

      小白尝试编写裸机下的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);  
                               //关闭相应通道使能
      }
      

      还望大佬不吝赐教!!

      S 1 Reply Last reply Reply Quote Share 1
      • S
        smiletiger LV 6 @secret last edited by

        @secret 在 D1 裸机 DMA 中说:

        dma_init

        好像那个地址不需要高30位低2位互换

        1 Reply Last reply Reply Quote Share 0
        • 1 / 1
        • First post
          Last post

        Copyright © 2022 深圳全志在线有限公司 粤ICP备2021084185号 粤公网安备44030502007680号

        行为准则 | 用户协议 | 隐私权政策