/* * dma.c * * Created on: 2022Äê1ÔÂ7ÈÕ * Author: graydon */ #include #include #include #include "dma.h" struct DMARegs { volatile void* dscptr_next; volatile uint32_t addrstart; volatile uint32_t cfg; volatile uint32_t xcnt; volatile uint32_t xmod; volatile uint32_t ycnt; volatile uint32_t ymod; volatile void* dscptr_cur; volatile void* dscptr_prv; volatile uint32_t addr_cur; volatile uint32_t stat; volatile uint32_t xcnt_cur; volatile uint32_t ycnt_cur; volatile uint32_t bwlcnt; volatile uint32_t bwlcnt_cur; volatile uint32_t bwmcnt; volatile uint32_t bwmcnt_cur; }; #define MSIZE 2 #define PSIZE 2 #define DMACONFIG ((PSIZE<<4)|(MSIZE<<8)|(4<<12)|(1<<20)|(1<<16)) static volatile DMARegsDef* gSportsDMA[16] = { DMA0,DMA1,DMA2,DMA3,DMA4,DMA5,DMA6,DMA7, DMA10,DMA11,DMA12,DMA13,DMA14,DMA15,DMA16,DMA17 }; static uint32_t iid[16] = { INTR_SPORT0_A_DMA,INTR_SPORT0_B_DMA,INTR_SPORT1_A_DMA,INTR_SPORT1_B_DMA, INTR_SPORT2_A_DMA,INTR_SPORT2_B_DMA,INTR_SPORT3_A_DMA,INTR_SPORT3_B_DMA, INTR_SPORT4_A_DMA,INTR_SPORT4_B_DMA,INTR_SPORT5_A_DMA,INTR_SPORT5_B_DMA, INTR_SPORT6_A_DMA,INTR_SPORT6_B_DMA,INTR_SPORT7_A_DMA,INTR_SPORT7_B_DMA }; volatile DMARegsDef* get_dma_regs(uint32_t sportid) { if(sportid < 16) { return gSportsDMA[sportid]; } return 0; } static uvoid DMACallBack (u32 iid, uvoidptr arg) { // disable_interrupts(); AudioProcCallBack(); switch(iid) { case INTR_SPORT0_A_DMA: *pREG_DMA0_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT0_B_DMA: *pREG_DMA1_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT1_A_DMA: *pREG_DMA2_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT1_B_DMA: *pREG_DMA3_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT2_A_DMA: *pREG_DMA4_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT2_B_DMA: *pREG_DMA5_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT3_A_DMA: *pREG_DMA6_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT3_B_DMA: *pREG_DMA7_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT4_A_DMA: *pREG_DMA10_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT4_B_DMA: *pREG_DMA11_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT5_A_DMA: *pREG_DMA12_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT5_B_DMA: *pREG_DMA13_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT6_A_DMA: *pREG_DMA14_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT6_B_DMA: *pREG_DMA15_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT7_A_DMA: *pREG_DMA16_STAT|=BITM_DMA_STAT_IRQDONE; break; case INTR_SPORT7_B_DMA: *pREG_DMA17_STAT|=BITM_DMA_STAT_IRQDONE; break; } //adi_int_ClearPending(iid); // enable_interrupts(); } void dma_install_interrupt(uint32_t sportid) { if(sportid < 16) { adi_sec_SetPriority(iid[sportid], 48); adi_int_InstallHandler(iid[sportid], DMACallBack, 0, true); } } void dma_config(volatile DMARegsDef* regs, uint32_t desc_address, uint32_t cnt, ubool rx) { regs->cfg = 0; regs->dscptr_next = (void*)desc_address; regs->xcnt = cnt; regs->xmod = 4; if(rx) { regs->cfg = (1<<1)|DMACONFIG ; } else { regs->cfg = DMACONFIG ; } } void dma_enable(volatile DMARegsDef* regs) { regs->cfg |= 1 ; }