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