/* * dma.c * * Created on: 2022Äê1ÔÂ7ÈÕ * Author: graydon */ #include #include #include #include #include "dma.h" #include "linkport.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)|(1<<20)) static volatile DMARegsDef* gDMARegs[] = { DMA0,DMA1,DMA2,DMA3,DMA4,DMA5,DMA6,DMA7, DMA10,DMA11,DMA12,DMA13,DMA14,DMA15,DMA16,DMA17, DMA30,DMA36 }; static uint32_t iid[] = { 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, INTR_LP0_DMA,INTR_LP1_DMA }; volatile DMARegsDef* get_dma_regs(uint32_t id) { if(id < sizeof(gDMARegs)/sizeof(DMARegsDef*)) { return gDMARegs[id]; } return 0; } static uvoid DMACallBack (u32 int_id, uvoidptr arg) { // extern u32 master_intr; // extern ubool LinkPortStart; // disable_interrupts(); switch(int_id) { 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; case INTR_LP0_DMA: *pREG_DMA30_STAT|= BITM_DMA_STAT_IRQDONE; break; case INTR_LP1_DMA: *pREG_DMA36_STAT|= BITM_DMA_STAT_IRQDONE; break; } AudioProcCallBack(int_id); //ÐèÒªµÈ´ý½ÓÊÕ·½×¼±¸ºÃ£¬·ñÔò»á³ö´í... // if(LinkPortStart && master_intr == int_id) { // LP_transmit();//config output . // } //adi_int_ClearPending(iid); // enable_interrupts(); } void dma_install_interrupt(uint32_t id) { if(id < sizeof(iid)/sizeof(uint32_t)) { adi_sec_SetPriority(iid[id], 48); adi_int_InstallHandler(iid[id], DMACallBack, 0, true); } } void dma_config(volatile DMARegsDef* regs, uint32_t desc_address, uint32_t cnt, ubool rx, ubool stop_mode) { u32 cfg = 0; regs->cfg = 0; regs->xcnt = cnt; regs->xmod = 4; if(stop_mode) { cfg = (0<<12)|(0<<16)|DMACONFIG; // stop Flow Mode regs->addrstart = desc_address; } else { cfg = (4<<12)|(1<<16)|DMACONFIG; //Descriptor List Mode regs->dscptr_next = (void*)desc_address; } if(rx) { regs->cfg = cfg | (1<<1) ; } else { regs->cfg = cfg ; } } void dma_enable(volatile DMARegsDef* regs) { regs->cfg |= 1 ; }