#include <stdio.h>
|
#include <stdlib.h>
|
//#include <def1802.h>
|
//#include <cdef1802.h>
|
#include <def21489.h>
|
#include <cdef21489.h>
|
#include <services/int/adi_int.h>
|
#include <string.h>
|
#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<<i);
|
}
|
*pSPnCS0[config->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();
|
}
|