本帖最后由 xch 于 2026-6-4 21:25 编辑
- #define MAXIUM_DMA_BLOCK_SIZE ( 65536-4 )
- typedef struct{
- uint32_t BR1; //数据量
- uint32_t DAR; //填充仅需要更新目标地址
- uint32_t DSR; //填充仅需要更新目标地址
- uint32_t LLR; //数据链
- }tDMA_LLS;
- /*******链表结构必须在同一个64K区域*******/
- tDMA_LLS DMA_MEM_LLS[MAX_LLS_ARRAY_NUM] @0x20000000 ;
- void DmaCopyHalfWordBlock (uint32_t bytes, uint16_t * dst ,uint16_t *src)
- {
-
- DMA_MEM_CH->CTR1 = DMA_CTR1_SAP|DMA_CTR1_DINC|DMA_CTR1_SINC|\
- (DMA_DEST_DATAWIDTH_HALFWORD)|(DMA_DEST_DATAWIDTH_HALFWORD);
- DMA_MEM_CH ->CTR2 = DMA_REQUEST_SW|DMA_BREQ_BLOCK|DMA_TCEM_EACH_LL_ITEM_TRANSFER; //使用软件 DMA请求
- DMA_MEM_CH ->CSAR = (uint32_t)(uint64_t)src;
- DMA_MEM_CH ->CDAR = (uint32_t)(uint64_t)dst;
- if( bytes <=MAXIUM_DMA_BLOCK_SIZE ){
- DMA_MEM_CH ->CBR1 = bytes ;
- }
- else{
- DMA_MEM_CH ->CBR1 = MAXIUM_DMA_BLOCK_SIZE;
- uint32_t lls = DMA_CLLR_UB1|DMA_CLLR_UDA|DMA_CLLR_USA|DMA_CLLR_ULL;
- uint32_t base = (uint32_t )(uint64_t)DMA_MEM_LLS;
- DMA_MEM_CH ->CLLR = lls|(uint16_t)base;
- DMA_MEM_CH ->CLBAR = (uint32_t)base&0xffff0000; //MSB,LLS BASE
- DMA_LLS_Config ( DMA_MEM_LLS,\
- bytes - MAXIUM_DMA_BLOCK_SIZE,\
- (uint32_t)(uint64_t)dst+MAXIUM_DMA_BLOCK_SIZE, (uint32_t)(uint64_t)src+MAXIUM_DMA_BLOCK_SIZE,lls);
- }
- //启动传输
- DMA_MEM_CH ->CCR = DMA_CCR_EN;
- }
- /****************************************
- 填充一片区域,超出65535需要使用动态链表
- size 是 uint32_t 的数量,按照字节数计算一个传输链
- 不得超出16383*4 字节
- ***********************************************/
- static void DMA_LLS_Config ( tDMA_LLS *plls,uint32_t bytes,uint32_t dar, uint32_t sar, uint32_t lls)
- {
- uint8_t max = (bytes +MAXIUM_DMA_BLOCK_SIZE-1)/MAXIUM_DMA_BLOCK_SIZE-1;
- uint8_t i =0;
- for (;i<max;i++){
- plls[i].DAR = dar +i*(MAXIUM_DMA_BLOCK_SIZE);
- plls[i].SAR = sar +i*(MAXIUM_DMA_BLOCK_SIZE);
- plls[i].BR1 = MAXIUM_DMA_BLOCK_SIZE; //当前传输数量
- plls[i].LLR = lls|(uint16_t)(uint64_t)&plls[i+1];//指向下一个链表的低16位
- }
- plls[i].DAR = dar +i*(MAXIUM_DMA_BLOCK_SIZE); //新内存地址
- plls[i].SAR = sar +i*(MAXIUM_DMA_BLOCK_SIZE); //新内存地址
- plls[i].BR1 = bytes % MAXIUM_DMA_BLOCK_SIZE; //剩余数据量
- plls[i].LLR = 0; //表示链表结束
- }
|