/*
|
* dma.c
|
*
|
* Created on: 2022Äê1ÔÂ7ÈÕ
|
* Author: graydon
|
*/
|
#include <stdint.h>
|
#include <services/int/adi_int.h>
|
#include <signal.h>
|
#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 ;
|
}
|