Post Go back to editing

Descriptor list mode Sports DMA - some question in timing in the SC598 SHARC TDM DAC/ADC loopback example

Category: Software
Product Number: ADSP-SC598

I was trying out the example in the SC598 TDM DAC/ADC loopback example, and I noticed that they used the descriptor list mode for SPORT DMA, which can be quite handy. However, I noticed that in the Sports_Init() function, only the callback for the receiving side is registered, as well as there are two separate DMA transfer, and two separate sports enable function at the end. While I understand that the receiving side and transmission side should share the same clock so they are sync, I want to make sure my understanding in its timing is right. Using the terminology from the example code, is the timing diagram correct?

Additionally, I also noticed that in the Sports callback function, they uses a circular counter method so counter = 0 correspond to buffer 1,4; counter=1 correspond to buffer 2,5 and so on. The code for the callback from the example is shown below:

static void SPORTCallback(void *pAppHandle, uint32_t nEvent, void *pArg)
{
int i; // Sport_buffer_count (input)
int j; // Sport buffer_count (output)

/* CASEOF (event type) */
switch (nEvent)
{
/* CASE (buffer processed) */
case ADI_SPORT_EVENT_RX_BUFFER_PROCESSED:
TestCallbackCount += 1;
CallbackCount +=1; // if callback = 1, deal with buffer 1 and buffer 4; if 0, deal with buffer 2 and buffer 5.

if(CallbackCount==1) // Deal with t=n to n+SPORTS_BUFFER_SIZE-1
{
for(i=0,j=0;i<SPORT_BUFFER_SIZE_TOTAL_ADC;i+=4,j+=8)
{
// J19(DAC5/6), L_n // ADC1/2 Left_n
int_SP0ABuffer1[j] =int_SP0ABuffer4[i];/*Copy ADC buffer to DAC buffer */

// J19(DAC5/6), R_n // ADC1/2 Right n
int_SP0ABuffer1[j+1]=int_SP0ABuffer4[i+1];/*Copy ADC buffer to DAC buffer */

// J20(DAC7/8), L_n // ADC3/4 Left_n
int_SP0ABuffer1[j+2]=int_SP0ABuffer4[i+2];/*Copy ADC buffer to DAC buffer */

// J20(DAC7/8), R_n // ADC3/4 Right_n
int_SP0ABuffer1[j+3]=int_SP0ABuffer4[i+3];/*Copy ADC buffer to DAC buffer */

// J17(DAC1/2), L_n // ADC1/2 Left_n
int_SP0ABuffer1[j+4]=int_SP0ABuffer4[i];/*Copy ADC buffer to DAC buffer */

// J17(DAC1/2), R_n // ADC1/2 Right_n
int_SP0ABuffer1[j+5]=int_SP0ABuffer4[i+1];/*Copy ADC buffer to DAC buffer */

// J18(DAC3/4), L_n // ADC3/4 Left_n
int_SP0ABuffer1[j+6]=int_SP0ABuffer4[i+2];/*Copy ADC buffer to DAC buffer */

// J18(DAC3/4), R_n // ADC3/4 Right_n
int_SP0ABuffer1[j+7]=int_SP0ABuffer4[i+3];/*Copy ADC buffer to DAC buffer */
}
}

if(CallbackCount==2) // Deal with t=n+SPORTS_BUFFER_SIZE and n+2*SPORTS_BUFFER_SIZE-1
{
for(i=0,j=0;i<SPORT_BUFFER_SIZE_TOTAL_ADC;i+=4,j+=8)
{
// J19(DAC5/6), L_n // ADC1/2 Left_n
int_SP0ABuffer2[j] =int_SP0ABuffer5[i];/*Copy ADC buffer to DAC buffer */

// J19(DAC5/6), R_n // ADC1/2 Right n
int_SP0ABuffer2[j+1]=int_SP0ABuffer5[i+1];/*Copy ADC buffer to DAC buffer */

// J20(DAC7/8), L_n // ADC3/4 Left_n
int_SP0ABuffer2[j+2]=int_SP0ABuffer5[i+2];/*Copy ADC buffer to DAC buffer */

// J20(DAC7/8), R_n // ADC3/4 Right_n
int_SP0ABuffer2[j+3]=int_SP0ABuffer5[i+3];/*Copy ADC buffer to DAC buffer */


// J17(DAC1/2), L_n // ADC1/2 Left_n
int_SP0ABuffer2[j+4]=int_SP0ABuffer5[i];/*Copy ADC buffer to DAC buffer */

// J17(DAC1/2), R_n // ADC1/2 Right_n
int_SP0ABuffer2[j+5]=int_SP0ABuffer5[i+1];/*Copy ADC buffer to DAC buffer */

// J18(DAC3/4), L_n // ADC3/4 Left_n
int_SP0ABuffer2[j+6]=int_SP0ABuffer5[i+2];/*Copy ADC buffer to DAC buffer */

// J18(DAC3/4), R_n // ADC3/4 Right_n
int_SP0ABuffer2[j+7]=int_SP0ABuffer5[i+3];/*Copy ADC buffer to DAC buffer */
}
CallbackCount=0;
}

break;
default:
break;
}
/* return */
}



However, I am not 100% sure in this method, in particular in the case when you have additional interrupt function that is long enough so some of the callback function is skipped but processing the wrong buffer pointer, leading to some distorted sine wave shown in the picture below.

In here, we code some extra things inside the callback function so one of the DAC port will emit a sine wave. During the generation, we tried pressing the button as gpio interrupt once (and doing some stuff), and after letting go, the generated sine wave (not from loopback - it's generated from within) becomes something like this:


I am not 100% sure what is going on here, but i suspect it has something to do with how the callback function assign which buffer group to read write. Is there any way that allows me to know which buffer pointer has been processed in a descriptor list mode in the callback, rather than relying on the callbackCount variable?