BF607 wrong SPORT Sequence at hSport2RxB with AD7771

Hi 

I'm currently using AD7771 and BF607 collect three phase voltage and current. And I found some strange issue during the test.

The connection setup is shown below:

I'm using SPORT2 RxA and RxB to receive data from AD7771. I have set up RxA 0 and 1 to receive DOUT0 and DOUT1,   RxB 0 and 1 to receive DOUT2 and DOUT3.

During the test I noticed that there is small chance, the data sequence at RxB is wrong. For example: The right sequence I received at DSP RxB should be  CH4 ->CH5 -> CH6 -> CH7, most of time the received data follow that sequence. But some times, especially just power on the system, the received data sequence at RxB is CH5 ->CH4 -> CH7 -> CH6. Most of time if I reload the program the issue is gone. And this issue has never been found at RxA channel. I have checked the output signal at ADC side, there is no difference between these two conditions. 

I attached the SPORT config file, please take a look, thank you.

static void SPORTCallbackRxA(
void *pAppHandle,
uint32_t nEvent,
void *pArg
)
{

ADI_SPORT_RESULT eResult;
switch (nEvent)
{
/* CASE (buffer processed) */
case (uint32_t)ADI_SPORT_EVENT_RX_BUFFER_PROCESSED:
ptrBufferSportRxACallback = pArg;
adi_sport_SubmitBuffer( hSport2RxA, ptrBufferSportRxACallback, SIZE_OF_RX_BUFFER);
AD7770_SportRxBufferAPtr = (uint32_t *)pArg;

AD7770_IsBufferReady &= 0xF0;

break;
default:
/* Unexpected event occurred */
printf("%i - SportA_CB - default %i \n", nRxCallbackA_Counter, nEvent);
break;
}
nRxCallbackA_Counter++;
}

/*********************************************************************

Function: SPORTCallbackRx (B)

Description: This is a callback frunction registered with the driver.
This function will be called when the RX completes the data
transfer.

*********************************************************************/
//#pragma optimize_for_speed
static void SPORTCallbackRxB(
void *pAppHandle,
uint32_t nEvent,
void *pArg
)
{
ADI_SPORT_RESULT eResult;
switch (nEvent)
{
/* CASE (buffer processed) */
case (uint32_t)ADI_SPORT_EVENT_RX_BUFFER_PROCESSED:
ptrBufferSportRxBCallback = pArg;
adi_sport_SubmitBuffer( hSport2RxB, ptrBufferSportRxBCallback, SIZE_OF_RX_BUFFER);

AD7770_SportRxBufferBPtr = (uint32_t *)pArg;

AD7770_IsBufferReady &= 0x0F;

break;
default:
printf("%i - SportB_CB - default %i \n", nRxCallbackB_Counter, nEvent);
break;
}
nRxCallbackB_Counter++;
}

ADI_SPORT_RESULT AD7770_ConfigureRx(void)
{
ADI_SPORT_RESULT eResult;

/* SPORT_HALF_A */
/* configure the sport for data length, LSB first etc */
if( (eResult = adi_sport_ConfigData(hSport2RxA,
ADI_SPORT_DTYPE_ZERO_FILL,
31U, // word size (bits length - 1)
false, // isLSBFirst
false, // isPackEnabled
false) //isRightJustifiedMode
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}
/* configure the clock for the SPORT. This API set the whether use the internal clock, SPORT clock etc.
* Since this example, RX gets the clock and Frame sync from TX. */
//SerialClock ratio is ignore, as we use external DCLK
if( (eResult = adi_sport_ConfigClock(hSport2RxA,
0, // CLKDIV: SPT_ACLK = [SCLK � ( SPORT_DIV_A.CLKDIV + 1)]
false, // isUsingInternalClock (false = external)
true, // isDataAndFS read on clk falling edge
false) // isGatedClockEnabled
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}

/* BEFORE ENABLING MC mode - Configure Active channel selection registers */
/*
* Setting Starting CHannel to 0 and ending channel to 0, enaable CHO0 only.
*/
if( (eResult = adi_sport_SelectChannel( hSport2RxA,
0U, // Starting channel
1U) // Ending channel
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}

/* Configure Multi channel */
if( (eResult = adi_sport_ConfigMC( hSport2RxA,
0u, // nFrame delay (BITP_SPORT_MCTL_MFD)
1, // nNumSlot (BITP_SPORT_MCTL_WSIZE) // Number of channel slot - 1
0, // nWindowSize (BITP_SPORT_MCTL_WOFFSET)
false) // isDmaPackEnabled
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}



/* Configure the frame sync. This API configure the SPORT whether to use frame sync or not , external or internal framesync etc */
if( (eResult = adi_sport_ConfigFrameSync(hSport2RxA,
0, // FS divisor (ignored in receiver mode)
true, // isFSRequired (false is for continuous mode...)
false, // useInternalFrameSync (false = External)
false, // useDataIndependantFrameSync (false = Data-Dependant) --> I am not sure about the purpose of this parameter
true, // isActiveHighFrameSync (true = active low... opposite of parameter name...)
false, // isLateFrameSync (false = Early)
false) // isEdgeSensitive (false = level sensitive)
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}
/* SPORT_HALF_A --- END ----*/

/* SPORT_HALF_B --- START ----*/
/* configure the sport for data length, LSB first etc */
if( (eResult = adi_sport_ConfigData(hSport2RxB,
ADI_SPORT_DTYPE_ZERO_FILL,
31U, // word size (bits length - 1)
false, // isLSBFirst
false, // isPackEnabled
false) //isRightJustifiedMode
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}
/* configure the clock for the SPORT. This API set the whether use the internal clock, SPORT clock etc.
* Since this example, RX gets the clock and Frame sync from TX. */
//SerialClock ratio is ignore, as we use external DCLK
if( (eResult = adi_sport_ConfigClock(hSport2RxB,
0, // CLKDIV: SPT_ACLK = [SCLK � ( SPORT_DIV_A.CLKDIV + 1)]
false, // isUsingInternalClock (false = external)
true, // isDataAndFS read on clk falling edge
false) // isGatedClockEnabled
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}

/* BEFORE ENABLING MC mode - Configure Active channel selection registers */
/*
* Setting Starting CHannel to 0 and ending channel to 0, enaable CHO0 only.
*/
if( (eResult = adi_sport_SelectChannel( hSport2RxB,
2U, // Starting channel
3U) // Ending channel
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}

/* Configure Multi channel */
if( (eResult = adi_sport_ConfigMC( hSport2RxB,
0u, // nFrame delay (BITP_SPORT_MCTL_MFD)
1, // nNumSlot (BITP_SPORT_MCTL_WSIZE) // Number of channel slot - 1
0, // nWindowSize (BITP_SPORT_MCTL_WOFFSET)
false) // isDmaPackEnabled
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}



/* Configure the frame sync. This API configure the SPORT whether to use frame sync or not , external or internal framesync etc */
if( (eResult = adi_sport_ConfigFrameSync(hSport2RxB,
0, // FS divisor (ignored in receiver mode)
true, // isFSRequired (false is for continuous mode...)
false, // useInternalFrameSync (false = External)
false, // useDataIndependantFrameSync (false = Data-Dependant) --> I am not sure about the purpose of this parameter
true, // isActiveHighFrameSync (true = active low... opposite of parameter name...)
false, // isLateFrameSync (false = Early)
false) // isEdgeSensitive (false = level sensitive)
) != ADI_SPORT_SUCCESS)
{
return(eResult);
}
#if 1
if( (eResult = adi_sport_MuxHalfSport(hSport2RxB, true, true)) != ADI_SPORT_SUCCESS)
{
return(eResult);
}
#endif

/* SPORT_HALF_B --- END ----*/
return(eResult);

}

void AD7770_SPORT_INIT(void)
{
ADI_SPORT_RESULT eSportResult;

// Configuration
if(adi_sport_Open( AD7770_SPORT_DEVICE_NUM, //Using Sport #2
ADI_HALF_SPORT_A,
ADI_SPORT_DIR_RX,
ADI_SPORT_MC_MODE,
sport_handlerRxA,
(uint32_t)(SPORT_MEM_SIZE),
&hSport2RxA
)!= ADI_SPORT_SUCCESS)
{
printf("\n\tFailed to open the device in Rx mode ");
}

if(adi_sport_Open( AD7770_SPORT_DEVICE_NUM, //Using Sport #2
ADI_HALF_SPORT_B,
ADI_SPORT_DIR_RX,
ADI_SPORT_MC_MODE,
sport_handlerRxB,
(uint32_t)(SPORT_MEM_SIZE),
&hSport2RxB
)!= ADI_SPORT_SUCCESS)
{
printf("\n\tFailed to open the device in RxB mode ");
}

if((eSportResult = AD7770_ConfigureRx())!= ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to configure RX: %d",eSportResult);
}

/* Enable the DMA associated with device if it is expected to work with DMA mode */
if((eSportResult = adi_sport_EnableDMAMode(hSport2RxA,true))!= ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to enable the DMA mode for RX: %d",eSportResult);
}

/* Enable the DMA associated with device if it is expected to work with DMA mode */
if((eSportResult = adi_sport_EnableDMAMode(hSport2RxB,true))!= ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to enable the DMA mode for RXB: %d",eSportResult);
}

if((eSportResult = adi_sport_Enable(hSport2RxA,false))!= ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to disable the Tx: %d",eSportResult);
}

/* Disable the Rx */
if((eSportResult = adi_sport_Enable(hSport2RxB,false))!= ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to disable the Tx: %d",eSportResult);
}

/* SPORT-ATwo large buffers (Ping-Pong) of 320*4 frames (4 channels per frame) */
adi_sport_SubmitBuffer( hSport2RxA, sportRxBufferA1, SIZE_OF_RX_BUFFER);
adi_sport_SubmitBuffer( hSport2RxA, sportRxBufferA2, SIZE_OF_RX_BUFFER);

/* SPORT-B Two large buffers (Ping-Pong) of 320*4 frames (4 channels per frame) */
adi_sport_SubmitBuffer( hSport2RxB, sportRxBufferB1, SIZE_OF_RX_BUFFER);
adi_sport_SubmitBuffer( hSport2RxB, sportRxBufferB2, SIZE_OF_RX_BUFFER);

// SPORT2-A
if( (eSportResult = adi_sport_RegisterCallback(hSport2RxA,SPORTCallbackRxA,NULL)) != ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to register the call back for Rx : %d",eSportResult);
}

if( (eSportResult = adi_sport_RegisterCallback(hSport2RxB,SPORTCallbackRxB,NULL)) != ADI_SPORT_SUCCESS)
{
printf("\n\t Failed to register the call back for Rx : %d",eSportResult);
}
}