#include #include //#include //#include #include #include #include #include #include "sport.h" #include "memory.h" #include "config.h" #include "dma.h" struct DMA_Desc{ u32 next; u32 bsize; u32 asize; u32 buffer; }; //unsigned int SAMPLE_RATE = 48000; //unsigned int SAMPLE_NUM = 64; u16 mCodecNum = 0; struct AudioCodec mAudioCodec[16]; static struct DMA_Desc sp_desc[32];//0a_ping,0a_pong,0b_ping,0b_pong,... #if 0 //#define NUM_SAMPLES 64 int sport0a_buf[2][SAMPLE_NUM*SLOTS]; int sport0b_buf[2][SAMPLE_NUM*SLOTS]; int sport1a_buf[2][SAMPLE_NUM*SLOTS]; int sport1b_buf[2][SAMPLE_NUM*SLOTS]; int sport2a_buf[2][SAMPLE_NUM*SLOTS]; int sport2b_buf[2][SAMPLE_NUM*SLOTS]; int sport3a_buf[2][SAMPLE_NUM*SLOTS]; int sport3b_buf[2][SAMPLE_NUM*SLOTS]; int sport4a_buf[2][SAMPLE_NUM*SLOTS]; int sport4b_buf[2][SAMPLE_NUM*SLOTS]; int sport5a_buf[2][SAMPLE_NUM*SLOTS]; int sport5b_buf[2][SAMPLE_NUM*SLOTS]; int sport6a_buf[2][SAMPLE_NUM*SLOTS]; int sport6b_buf[2][SAMPLE_NUM*SLOTS]; int sport7a_buf[2][SAMPLE_NUM*SLOTS]; int sport7b_buf[2][SAMPLE_NUM*SLOTS]; //int xt[1024*1024]; //2 For ping-pong ,each TCB has four registers. int sport0a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport0a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport0a_buf[1]} }; int sport0b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport0b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport0b_buf[1]} }; int sport1a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport1a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport1a_buf[1]} }; int sport1b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport1b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport1b_buf[1]} }; int sport2a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport2a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport2a_buf[1]} }; int sport2b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport2b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport2b_buf[1]} }; int sport3a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport3a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport3a_buf[1]} }; int sport3b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport3b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport3b_buf[1]} }; int sport4a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport4a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport4a_buf[1]} }; int sport4b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport4b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport4b_buf[1]} }; int sport5a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport5a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport5a_buf[1]} }; int sport5b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport5b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport5b_buf[1]} }; int sport6a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport6a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport6a_buf[1]} }; int sport6b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport6b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport6b_buf[1]} }; int sport7a_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport7a_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport7a_buf[1]} }; int sport7b_tcb[2][4] = { {0, SAMPLE_NUM*SLOTS, 1, (int) sport7b_buf[0]}, {0, SAMPLE_NUM*SLOTS, 1, (int) sport7b_buf[1]} }; /* sport 0,2 TDMÊä³ö sport 1,3 TDMÊäÈë sport 4 i2s Êä³ö sport 5, i2s ÊäÈë sport 6 tdmÊä³ö sport 7 tdmÊäÈë */ void InitSPORT(int mask,int sampleRate) { int i; int reg; /* External clock and frame syncs generated by AD1939 */ *pDIV0 = 0x00000000; // Transmitter (SPORT0) *pDIV1 = 0x00000000; // Receiver (SPORT1) at 12.288 MHz SCLK and 48 kHz sample rate sport0a_tcb[0][0]= ((int)sport0a_tcb[1] + 3)&0x7ffff | (1<<19); sport0a_tcb[1][0]= ((int)sport0a_tcb[0] + 3)&0x7ffff | (1<<19); sport0b_tcb[0][0]= ((int)sport0b_tcb[1] + 3)&0x7ffff | (1<<19); sport0b_tcb[1][0]= ((int)sport0b_tcb[0] + 3)&0x7ffff | (1<<19); sport1a_tcb[0][0]= ((int)sport1a_tcb[1] + 3)&0x7ffff | (1<<19); sport1a_tcb[1][0]= ((int)sport1a_tcb[0] + 3)&0x7ffff | (1<<19); sport1b_tcb[0][0]= ((int)sport1b_tcb[1] + 3)&0x7ffff | (1<<19); sport1b_tcb[1][0]= ((int)sport1b_tcb[0] + 3)&0x7ffff | (1<<19); sport2a_tcb[0][0]= ((int)sport2a_tcb[1] + 3)&0x7ffff | (1<<19); sport2a_tcb[1][0]= ((int)sport2a_tcb[0] + 3)&0x7ffff | (1<<19); sport2b_tcb[0][0]= ((int)sport2b_tcb[1] + 3)&0x7ffff | (1<<19); sport2b_tcb[1][0]= ((int)sport2b_tcb[0] + 3)&0x7ffff | (1<<19); sport3a_tcb[0][0]= ((int)sport3a_tcb[1] + 3)&0x7ffff | (1<<19); sport3a_tcb[1][0]= ((int)sport3a_tcb[0] + 3)&0x7ffff | (1<<19); sport3b_tcb[0][0]= ((int)sport3b_tcb[1] + 3)&0x7ffff | (1<<19); sport3b_tcb[1][0]= ((int)sport3b_tcb[0] + 3)&0x7ffff | (1<<19); sport4a_tcb[0][0]= ((int)sport4a_tcb[1] + 3)&0x7ffff | (1<<19); sport4a_tcb[1][0]= ((int)sport4a_tcb[0] + 3)&0x7ffff | (1<<19); sport4b_tcb[0][0]= ((int)sport4b_tcb[1] + 3)&0x7ffff | (1<<19); sport4b_tcb[1][0]= ((int)sport4b_tcb[0] + 3)&0x7ffff | (1<<19); sport5a_tcb[0][0]= ((int)sport5a_tcb[1] + 3)&0x7ffff | (1<<19); sport5a_tcb[1][0]= ((int)sport5a_tcb[0] + 3)&0x7ffff | (1<<19); sport5b_tcb[0][0]= ((int)sport5b_tcb[1] + 3)&0x7ffff | (1<<19); sport5b_tcb[1][0]= ((int)sport5b_tcb[0] + 3)&0x7ffff | (1<<19); sport6a_tcb[0][0]= ((int)sport6a_tcb[1] + 3)&0x7ffff | (1<<19); sport6a_tcb[1][0]= ((int)sport6a_tcb[0] + 3)&0x7ffff | (1<<19); sport6b_tcb[0][0]= ((int)sport6b_tcb[1] + 3)&0x7ffff | (1<<19); sport6b_tcb[1][0]= ((int)sport6b_tcb[0] + 3)&0x7ffff | (1<<19); sport7a_tcb[0][0]= ((int)sport7a_tcb[1] + 3)&0x7ffff | (1<<19); sport7a_tcb[1][0]= ((int)sport7a_tcb[0] + 3)&0x7ffff | (1<<19); sport7b_tcb[0][0]= ((int)sport7b_tcb[1] + 3)&0x7ffff | (1<<19); sport7b_tcb[1][0]= ((int)sport7b_tcb[0] + 3)&0x7ffff | (1<<19); *pSPCTL0 = *pSPCTL1 = *pSPCTL2=*pSPCTL3=*pSPCTL4=*pSPCTL5=*pSPCTL6=*pSPCTL7=0; *pSPMCTL0 = *pSPMCTL1=*pSPMCTL2=*pSPMCTL3=*pSPMCTL4=*pSPMCTL5 =*pSPMCTL6=*pSPMCTL7=0; *pSPCTLN0 =*pSPCTLN1=*pSPCTLN2=*pSPCTLN3=*pSPCTLN4=*pSPCTLN5 =*pSPCTLN6 =*pSPCTLN7=0; *pCPSP0A = sport0a_tcb[0][0]; *pCPSP0B = sport0b_tcb[0][0]; *pCPSP1A = sport1a_tcb[0][0]; *pCPSP1B = sport1b_tcb[0][0]; *pCPSP2A = sport2a_tcb[0][0]; *pCPSP2B = sport2b_tcb[0][0]; *pCPSP3A = sport3a_tcb[0][0]; *pCPSP3B = sport3b_tcb[0][0]; *pCPSP4A = sport4a_tcb[0][0]; *pCPSP4B = sport4b_tcb[0][0]; *pCPSP5A = sport5a_tcb[0][0]; *pCPSP5B = sport5b_tcb[0][0]; *pCPSP6A = sport6a_tcb[0][0]; *pCPSP6B = sport6b_tcb[0][0]; *pCPSP7A = sport7a_tcb[0][0]; *pCPSP7B = sport7b_tcb[0][0]; reg = (SPTRAN| OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A | SPEN_B | SCHEN_B | SDEN_B); // send *pSPCTL0 = reg; *pSPCTL6 = reg; //*pSPCTL2 = reg; reg = (SPTRAN| OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A); //output *pSPCTL2 = reg; *pSPCTL4 = reg; reg = (OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A | SPEN_B | SCHEN_B | SDEN_B); // recv *pSPCTL1 = reg; *pSPCTL3 = reg; *pSPCTL7 = reg; //*pSPCTL3 = reg; reg = (OPMODE | SLEN32 | SPEN_A | SCHEN_A | SDEN_A ); *pSPCTL5 = reg; adi_int_InstallHandler(ADI_CID_SP1I, DMACallBack, 0, true); } #endif void sport_config(struct SportDef * config) { u32 i; volatile u32 *pSPCTLn[8] = {pSPCTL0,pSPCTL1,pSPCTL2,pSPCTL3,pSPCTL4,pSPCTL5,pSPCTL6,pSPCTL7}; volatile u32 *pSPnCS0[8] = {pSP0CS0,pSP1CS0,pSP2CS0,pSP3CS0,pSP4CS0,pSP5CS0,pSP6CS0,pSP7CS0}; volatile u32 *pSPMCTLn[8] = {pSPMCTL0,pSPMCTL1,pSPMCTL2,pSPMCTL3,pSPMCTL4,pSPMCTL5,pSPMCTL6,pSPMCTL7}; volatile u32 *pCPSPnAB[16] = {pCPSP0A,pCPSP0B,pCPSP1A,pCPSP1B,pCPSP2A,pCPSP2B,pCPSP3A,pCPSP3B ,pCPSP4A,pCPSP4B,pCPSP5A,pCPSP5B,pCPSP6A,pCPSP6B,pCPSP7A,pCPSP7B}; struct DMA_Desc* desca_0 = &sp_desc[config->spid*4 + 0]; struct DMA_Desc* desca_1 = &sp_desc[config->spid*4 + 1]; u32 dmaBufferLen = config->slots*SAMPLE_NUM; u32 bufLen = dmaBufferLen; s32* dmaBuffer_ping, *dmaBuffer_pong; if(config->interrupt ) { u32 iid[] = {ADI_CID_SP0I,ADI_CID_SP1I,ADI_CID_SP2I,ADI_CID_SP3I ,ADI_CID_SP4I,ADI_CID_SP5I,ADI_CID_SP6I,ADI_CID_SP7I}; adi_int_InstallHandler(iid[config->spid], DMACallBack, 0, true); } if(config->enable_sec) { bufLen *= 2; } dmaBuffer_ping = (s32*)SRAMMalloc(bufLen* 2*sizeof(s32));//for ping-pong. if(dmaBuffer_ping == NULL) { printf("dmaBuffer malloc fail.\n"); } memset(dmaBuffer_ping, 0 , bufLen* 2 *sizeof(s32)); dmaBuffer_pong = dmaBuffer_ping + dmaBufferLen; mAudioCodec[mCodecNum].dataPtr[0] = dmaBuffer_ping; mAudioCodec[mCodecNum].dataPtr[1] = dmaBuffer_pong; mAudioCodec[mCodecNum].slot_num = config->slots; mAudioCodec[mCodecNum].channel_num = config->vld_a; mAudioCodec[mCodecNum].rx = config->rx; mCodecNum++; desca_0->next = ((u32)desca_1 + 3)&0x7ffff | (1<<19); desca_0->buffer = (u32)dmaBuffer_ping; desca_0->asize = sizeof(s32); desca_0->bsize = config->slots*SAMPLE_NUM; desca_1->next = ((uint32_t)desca_0 + 3)&0x7ffff | (1<<19); desca_1->buffer = (u32)dmaBuffer_pong; desca_1->asize = sizeof(s32); desca_1->bsize = config->slots*SAMPLE_NUM; *pCPSPnAB[config->spid*2] = desca_1->next; if(config->enable_sec) { struct DMA_Desc* desca_2 = &sp_desc[config->spid*4 + 2]; struct DMA_Desc* desca_3 = &sp_desc[config->spid*4 + 3]; dmaBuffer_ping = dmaBuffer_pong + dmaBufferLen; dmaBuffer_pong = dmaBuffer_ping + dmaBufferLen; mAudioCodec[mCodecNum].dataPtr[0] = dmaBuffer_ping; mAudioCodec[mCodecNum].dataPtr[1] = dmaBuffer_pong; mAudioCodec[mCodecNum].slot_num = config->slots; mAudioCodec[mCodecNum].channel_num = config->vld_b; mAudioCodec[mCodecNum].rx = config->rx; mCodecNum++; desca_2->next = ((u32)desca_3 + 3)&0x7ffff | (1<<19); desca_2->buffer = (u32)dmaBuffer_ping; desca_2->asize = sizeof(s32); desca_2->bsize = config->slots*SAMPLE_NUM; desca_3->next = ((u32)desca_2 + 3)&0x7ffff | (1<<19); desca_3->buffer = (u32)dmaBuffer_pong; desca_3->asize = sizeof(s32); desca_3->bsize = config->slots*SAMPLE_NUM; *pCPSPnAB[config->spid*2+1] = desca_3->next; } if(config->opmode) { //iis u32 reg = SLEN32 | OPMODE | SPEN_A | SCHEN_A |SDEN_A |(config->lfs?(LFS):0) | (config->clke?CKRE:0); // *pSPCTL6 = SPTRAN | SLEN32 | OPMODE | SPEN_A | SCHEN_A |SDEN_A | SPEN_B | SCHEN_B |SDEN_B;// Êä³ö // *pSPCTL7 = SLEN32 | OPMODE | SPEN_A | SCHEN_A |SDEN_A | SPEN_B | SCHEN_B |SDEN_B; //ÊäÈë if(config->enable_sec) { reg |= SPEN_B | SCHEN_B |SDEN_B ; } if(config->rx == ufalse) { reg |= SPTRAN; } *pSPCTLn[config->spid] = reg; } else { //tdm u32 reg = SLEN32 | SCHEN_A |SDEN_A | FSR | (config->clke?CKRE:0) | (config->lfs?LFS:0); if(config->enable_sec) { reg |= SCHEN_B |SDEN_B; } if(config->rx == ufalse) { reg |= SPTRAN; } *pSPCTLn[config->spid] = reg; reg = 0; for(i=0 ;i < config->slots ;i ++ ){ reg |= (1<spid] = reg; *pSPMCTLn[config->spid] = ((config->slots-1)<<5) | (config->mfd << 1) | MCEA| (config->enable_sec?MCEB:0); } } uvoid sport_enable(struct SportDef * config) { u32 reg = SDEN_A; volatile u32 *pSPCTLn[8] = {pSPCTL0,pSPCTL1,pSPCTL2,pSPCTL3,pSPCTL4,pSPCTL5,pSPCTL6,pSPCTL7}; if(config->enable_sec) { reg |= SDEN_B; } *pSPCTLn[config->spid] |= reg; } uvoid DMACallBack (u32 iid, uvoidptr arg) { adi_int_ClearPending(iid); AudioProcCallBack(); }