#include "pdma.h" pdma_mem_channel* get_pdma_dev(int dma_id) { if(dma_id < 0 || dma_id > 7) { return 0; } return &(_MemCh[dma_id]); } int pdma_configure(int dma_id, void * dst, const void * src, int size) { if(size <= 0) return 0; if (dma_id <0 || dma_id >7) return 0; pdma_mem_channel* dma_ch = get_pdma_dev(dma_id); if (dma_ch == 0) return 0; if (ChEnReg & (1<<dma_id)) return 0; dma_ch->SAR = (unsigned)src; dma_ch->DAR = (unsigned)dst; unsigned long long size_shifted = size>>2; size_shifted = size_shifted<<32; dma_ch->CTL = size_shifted | 0x4824; DmaCfgReg = 1; return 1; } int pdma_run(int dma_id) { ChEnReg |= (1<<dma_id) | (1<<(dma_id+8)); return 1; } int pdma_wait(int dma_id) { while(1) { int is_run = ChEnReg&(1<<dma_id); if (!is_run) break; } return 1; } int pdma_copy(unsigned int dma_id, void * dst, const void * src, unsigned int size) { int n_blocks = 0; unsigned int current_shift = 0; int i = 0; int size_w = size>>2; n_blocks = size_w/PDMA_MAX_BLOCK_SIZE; unsigned int src_t, dst_t; for (i=0;i<n_blocks;i++) { current_shift = (i*PDMA_MAX_BLOCK_SIZE*4); dst_t = (unsigned int)dst + current_shift; src_t = (unsigned int)src + current_shift; if(pdma_configure(dma_id, (void*)(dst_t), (void*)(src_t), PDMA_MAX_BLOCK_SIZE*4)) { pdma_run(dma_id); pdma_wait(dma_id); } else return 0; } if ((size_w%PDMA_MAX_BLOCK_SIZE)!=0) { current_shift = (n_blocks*PDMA_MAX_BLOCK_SIZE*4); dst_t = (unsigned int)dst + current_shift; src_t = (unsigned int)src + current_shift; int wsize = (size_w%PDMA_MAX_BLOCK_SIZE)<<2; if(pdma_configure(dma_id, (void*)(dst_t), (void*)(src_t), wsize)) { pdma_run(dma_id); pdma_wait(dma_id); } else return 0; } return 1; } pdma_mem_chain * pdma_fill_link(pdma_mem_chain *link, void * dst, void * src, unsigned int size, unsigned int llp_en) { link->DAR = (unsigned int)dst; link->SAR = (unsigned int)src; link->LLP = (unsigned int)(link+1); unsigned long long size_shifted = size>>2; size_shifted = size_shifted<<32; link->CTL = size_shifted | 0x4824; if (llp_en == 1) link->CTL |= 0x18000000; } int pdma_start_chain(int dma_id, pdma_mem_chain *link) { pdma_mem_channel* dma_ch = get_pdma_dev(dma_id); if (dma_ch == 0) return 0; if (ChEnReg & (1<<dma_id)) return 0; dma_ch->DAR = link->DAR; dma_ch->SAR = link->SAR; dma_ch->CTL = link->CTL; DmaCfgReg = 1; pdma_run(dma_id); }