Post Go back to editing

ADSP-21569 SPORT 2/3 enable function hanging

Category: Software
Product Number: ADSP-21569
Software Version: CCES 2.11.1

Hello,

I'm trying to get a simple I2S In --> Out to work on ADSP21569.
Fs: 48 kHz
MCLK: input from local osc on DAI pin; 24.576 MHz; routed to PCG A to generate the clocks. Clocks and routing is working (checked with scope).

Enabling SPORT4A (ADC) works without problems. The enable function with the same settings for SPORT2A (DAC) gets stuck. I also tried it with SPORT3A, but the enable function gets stuck too.
SPU is configured to generate secure transactions. DMA is used in Linked list mode. SRU settings should be correct (at least working for the clocks).

Is it necessary to configure a secure transaction for the SPORTx and the corresponding DMA channel as I did in SPU_Init function?
Is it neccessary to configure the static sport config additionally/identical to my SPORT_Init function where I call the config functions for data and clocks?
Please explain the data format in adi_sport_ConfigData function. I just want to handle standard PCM samples in I2S mode.
What does nClockRatio do in adi_sport_ConfigClock function? Is that the setting of the bitclock? But the BCLK is an input at 3.072 MHz... The description/documentation is unclear.


Is there anything I looked over?
See the important sections of the code below.

Kind regards,
Markus

Code:

int main(int argc, char *argv[])
{
	//Initialize managed drivers and/or services that have been added to the project.
	adi_initComponents();
	
	//Init system protection unit
	SPU_init();

	//Init Debug interface (JTAG or UART)
	Debug_Init(DBG_INT_JTAG);

	//Init GPIOs
	GPIO_Init();

	//Init precision clock generator
	PCG_Init();

	//Init system routing unit
	SRU_Init();

	//DMA Init
	DMA_Init();

	//Init SPORT
	SPORT_Init();

	DEBUG_PRINT("-----------------------\n");
	DEBUG_PRINT("DSP in normal operation\n");

	while(1){

	}

}


//----------------  Functions  --------------------------

//SPU IDs, p.
#define UART0_SPU_PID       29
#define UART0_Rx_DMA_SPU    65
#define UART0_Tx_DMA_SPU    66

#define SPORT_0A_SPU  		13
#define SPORT_0B_SPU  		14
#define SPORT_1A_SPU  		15
#define SPORT_1B_SPU  		16
#define SPORT_2A_SPU  		17
#define SPORT_2B_SPU  		18
#define SPORT_3A_SPU  		19
#define SPORT_3B_SPU  		20
#define SPORT_4A_SPU  		21
#define SPORT_4B_SPU   		22
#define SPORT_5A_SPU  		23
#define SPORT_5B_SPU   		24
#define SPORT_6A_SPU  		25
#define SPORT_6B_SPU   		26
#define SPORT_7A_SPU  		27
#define SPORT_7B_SPU   		28

#define SPORT_0A_DMA_SPU  	49
#define SPORT_0B_DMA_SPU  	50
#define SPORT_1A_DMA_SPU  	51
#define SPORT_1B_DMA_SPU  	52
#define SPORT_2A_DMA_SPU  	53
#define SPORT_2B_DMA_SPU  	54
#define SPORT_3A_DMA_SPU  	55
#define SPORT_3B_DMA_SPU  	56
#define SPORT_4A_DMA_SPU  	57
#define SPORT_4B_DMA_SPU   	58
#define SPORT_5A_DMA_SPU  	59
#define SPORT_5B_DMA_SPU   	60
#define SPORT_6A_DMA_SPU  	61
#define SPORT_6B_DMA_SPU   	62
#define SPORT_7A_DMA_SPU  	63
#define SPORT_7B_DMA_SPU   	64

//Variables
static uint8_t SpuMemory[ADI_SPU_MEMORY_SIZE];

static ADI_SPU_HANDLE hSpu;			//SPU handle

//Prepares System Protection Unit (SPU) configuration
void SPU_init(void)
{
	ADI_SPU_RESULT  eResult;

	//Init
    eResult = adi_spu_Init(0, SpuMemory, NULL, NULL, &hSpu);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    //UART
    //Make UART0 to generate secure transactions
    eResult = adi_spu_EnableMasterSecure(hSpu, UART0_SPU_PID, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    //Make UART0 Tx DMA to generate secure transactions
    eResult = adi_spu_EnableMasterSecure(hSpu, UART0_Tx_DMA_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    //Make UART0 Rx DMA to generate secure transactions
    eResult = adi_spu_EnableMasterSecure(hSpu, UART0_Rx_DMA_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }


	//SPORT - Make SPORTs to generate secure transactions
    //ADC
    eResult = adi_spu_EnableMasterSecure(hSpu, SPORT_4A_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    eResult = adi_spu_EnableMasterSecure(hSpu, SPORT_4A_DMA_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    //MCU
    eResult = adi_spu_EnableMasterSecure(hSpu, SPORT_7A_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    eResult = adi_spu_EnableMasterSecure(hSpu, SPORT_7A_DMA_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    //DAC
    eResult = adi_spu_EnableMasterSecure(hSpu, SPORT_2A_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

    eResult = adi_spu_EnableMasterSecure(hSpu, SPORT_2A_DMA_SPU, true);
    if(eResult != ADI_SPU_SUCCESS){
    	printf("Error: SPU Secure Transfer not possible! Errorcode: 0x%08X\n", eResult);
    }

}

void Debug_Init(uint8_t Interface){


	//Init power service
	if(adi_pwr_Init(0u, 25000000) != ADI_PWR_SUCCESS)
	{
		printf("Failed to initialize power service \n");
	}


    // Initialize the STDIO service
    if((eResult = adi_stdio_Init(&hSTDIOJTAG)) != ADI_STDIO_RESULT_SUCCESS)
    {
        printf("Failed to initialize STDIO service, Error Code: 0x%08X\n", eResult);
    }

	switch(Interface){
		case DBG_INT_JTAG:
			//JTAG is the standard interface for printf
			break;
		case DBG_INT_UART:
			UART_Init();
			break;
		default:
			printf("Selected debug interface not valid! \n");
			return;;
	}

	DEBUG_PRINT("Debug interface initialized\n");

}

void PCG_Init(void){

	//BCLK config TDM16
	ADI_PCG_CLK_INFO PCG_CLK_Inf_TDM16 =
	{
		ADI_PCG_CLK_EXT,              	//Clock Source
		1u,          					//Clock Divisor for 24.576 MHz
		false                           //External Trigger
	};

	//BCLK config I2S
	ADI_PCG_CLK_INFO PCG_CLK_Inf_I2S =
	{
		ADI_PCG_CLK_EXT,              	//Clock Source
		8u,          					//Clock Divisor for 3.072 MHz
		false                           //External Trigger
	};

	//FS config for 48 kHz
	ADI_PCG_FS_INFO PCG_FS_Inf =
	{
		ADI_PCG_FS_EXT,                	//Clock Source
		512u,     					   	//Frame Sync Divisor 48 KHz
		256u,                           //Pulse Width
		1u,                            	//Phase
		false,                         	//External Trigger
		ADI_PCG_FSBYPASS_MODE_NORMAL   	//Bypass Mode normal
	};

	//Init
	adi_pcg_Init(ADI_PCG_DEV_A, &PCG_CLK_Inf_I2S, &PCG_FS_Inf);
	adi_pcg_Init(ADI_PCG_DEV_B, &PCG_CLK_Inf_TDM16, &PCG_FS_Inf);

	DEBUG_PRINT("PCG initialized\n");
}


//Prepares SRU configuration.
void SRU_Init(void)
{

	//Port Input Enable Control Register
	*pREG_PADS0_DAI0_IE = BITM_PADS_DAI0_IE_VALUE;
	*pREG_PADS0_DAI1_IE = BITM_PADS_DAI1_IE_VALUE;


		//---- MCLK Input ----
		SRU(LOW, DAI0_PBEN04_I);			//Set pinbuf to input
		SRU(DAI0_PB04_O, PCG0_EXTCLKA_I);	//Route clock input to PCG A
		SRU(DAI0_PB04_O, PCG0_EXTCLKB_I);	//Route clock input to PCG B

		//---- Clocks ----
		//A2B
		SRU(HIGH, DAI0_PBEN09_I);			//Output
		SRU(PCG0_CLKB_O, DAI0_PB09_I);		//PCG B clk to A2B BCLK pin
		SRU(PCG0_CLKB_O, SPT0_ACLK_I); 		//PCG B clk to SPORT 0A
		SRU(PCG0_CLKB_O, SPT0_BCLK_I); 		//PCG B clk to SPORT 0B
		SRU(PCG0_CLKB_O, SPT1_ACLK_I); 		//PCG B clk to SPORT 1A
		SRU(PCG0_CLKB_O, SPT1_BCLK_I); 		//PCG B clk to SPORT 1B

		SRU(HIGH, DAI0_PBEN11_I);			//Output
		SRU(PCG0_FSB_O, DAI0_PB11_I);		//PCG B fs to A2B LRCLK pin
		SRU(PCG0_FSB_O, SPT0_AFS_I); 		//PCG B fs to SPORT 0A
		SRU(PCG0_FSB_O, SPT0_BFS_I); 		//PCG B fs to SPORT 0B
		SRU(PCG0_FSB_O, SPT1_AFS_I); 		//PCG B fs to SPORT 1A
		SRU(PCG0_FSB_O, SPT1_BFS_I); 		//PCG B fs to SPORT 1B

		//DAC
		SRU(HIGH, DAI0_PBEN03_I);			//Output
		SRU(PCG0_CLKA_O, DAI0_PB03_I);		//PCG A clk to DAC MCLK pin

		SRU(HIGH, DAI0_PBEN06_I);			//Output
		SRU(PCG0_CLKA_O, DAI0_PB06_I);		//PCG A clk to DAC BCLK pin
		SRU(PCG0_CLKA_O, SPT3_ACLK_I);		//PCG A clk to SPORT 2A

		SRU(HIGH, DAI0_PBEN02_I);			//Output
		SRU(PCG0_FSA_O, DAI0_PB02_I);		//PCG A fs to DAC LRCLK pin
		SRU(PCG0_FSA_O, SPT3_AFS_I);		//PCG A clk to SPORT 2A

		//ADC
		SRU(HIGH, DAI0_PBEN12_I);			//Output
		SRU(PCG0_CLKA_O, DAI0_PB12_I);		//PCG A clk to ADC MCLK pin

		SRU(HIGH, DAI0_PBEN20_I);			//Output
		SRU(PCG0_CLKA_O, DAI0_PB20_I);		//PCG A clk to ADC BCLK pin
		SRU2(PCG0_CRS_CLKA_O, SPT4_ACLK_I);	//PCG A clk to SPORT 4A (CRS)

		SRU(HIGH, DAI0_PBEN19_I);			//Output
		SRU(PCG0_FSA_O, DAI0_PB19_I);		//PCG A fs to ADC LRCLK pin
		SRU2(PCG0_CRS_FSA_O, SPT4_AFS_I);	//PCG A fs to SPORT 4A (CRS)

		//MCU (CRS)
		SRU2(HIGH, DAI1_PBEN04_I);			//Output
		SRU2(PCG0_CRS_CLKA_O, DAI1_PB04_I);	//PCG A clk to MCU MCLK pin (CRS)

		SRU2(HIGH, DAI1_PBEN02_I);			//Output
		SRU2(PCG0_CRS_CLKA_O, DAI1_PB02_I);	//PCG A clk to MCU BCLK pin (CRS)
		SRU2(PCG0_CRS_CLKA_O, SPT7_ACLK_I);	//PCG A clk to SPORT 7A (CRS)

		SRU2(HIGH, DAI1_PBEN01_I);			//Output
		SRU2(PCG0_CRS_FSA_O, DAI1_PB01_I);	//PCG A fs to MCU LRCLK pin (CRS)
		SRU2(PCG0_CRS_CLKA_O, SPT7_AFS_I);	//PCG A fs to SPORT 7A (CRS)

		//---- Data pins ----
		//A2B
		SRU(HIGH, DAI0_PBEN08_I);			//Output
	    SRU(SPT0_AD0_O, DAI0_PB08_I); 		//SPORT 0A (SHT0)
		SRU(HIGH, DAI0_PBEN10_I);			//Output
	    SRU(SPT0_BD0_O, DAI0_PB10_I); 		//SPORT 0B (SHT1)

		SRU(HIGH, DAI0_PBEN07_I);			//Output
	    SRU(SPT1_AD0_O, DAI0_PB07_I); 		//SPORT 1A (SHT2)
		SRU(HIGH, DAI0_PBEN05_I);			//Output
	    SRU(SPT1_BD0_O, DAI0_PB05_I); 		//SPORT 1B (HT-MT)

		//DAC
		SRU(HIGH, DAI0_PBEN01_I);			//Output
	    SRU(SPT3_AD0_O, DAI0_PB01_I); 		//SPORT 2A

		//ADC
		SRU2(LOW, DAI1_PBEN19_I);			//Input
	    SRU2(DAI1_PB19_O, SPT4_AD0_I); 		//SPORT 4A

		//AES3
		SRU2(LOW, DAI1_PBEN09_I);			//Input
	    SRU2(DAI1_PB09_O, SPT6_AD0_I); 		//SPORT 6A

		//MCU
		SRU2(LOW, DAI1_PBEN03_I);			//Input
	    SRU2(DAI1_PB03_O, SPT7_AD0_I); 		//SPORT 7A

	    DEBUG_PRINT("SRU initialized for local MCLK\n");

}

//Descriptors
ADI_PDMA_DESC_LIST DMA_Desc_SP4A[DMA_NUM_DESC];
ADI_PDMA_DESC_LIST DMA_Desc_SP7A[DMA_NUM_DESC];
ADI_PDMA_DESC_LIST DMA_Desc_SP2A[DMA_NUM_DESC];


void DMA_Init(void){

	//4A
	//ADC buffer
	DMA_Desc_SP4A[0].pStartAddr	= (void *)SP4ABuffer[0][0];
	DMA_Desc_SP4A[0].Config		= ENUM_DMA_CFG_XCNT_INT;
	DMA_Desc_SP4A[0].XCount		= BLOCKSIZE * I2S_NB_CH;
	DMA_Desc_SP4A[0].XModify	= 4;
	DMA_Desc_SP4A[0].YCount		= 0;
	DMA_Desc_SP4A[0].YModify	= 0;
	DMA_Desc_SP4A[0].pNxtDscp	= &DMA_Desc_SP4A[1];

	DMA_Desc_SP4A[1].pStartAddr	= (void *)SP4ABuffer[1][0];
	DMA_Desc_SP4A[1].Config		= ENUM_DMA_CFG_XCNT_INT;
	DMA_Desc_SP4A[1].XCount		= BLOCKSIZE * I2S_NB_CH;
	DMA_Desc_SP4A[1].XModify	= 4;
	DMA_Desc_SP4A[1].YCount		= 0;
	DMA_Desc_SP4A[1].YModify	= 0;
	DMA_Desc_SP4A[1].pNxtDscp	= &DMA_Desc_SP4A[0];

	//7A
	//MCU buffer
	DMA_Desc_SP7A[0].pStartAddr	= (void *)SP7ABuffer[0][0];
	DMA_Desc_SP7A[0].Config		= ENUM_DMA_CFG_XCNT_INT;
	DMA_Desc_SP7A[0].XCount		= BLOCKSIZE * I2S_NB_CH;
	DMA_Desc_SP7A[0].XModify	= 4;
	DMA_Desc_SP7A[0].YCount		= 0;
	DMA_Desc_SP7A[0].YModify	= 0;
	DMA_Desc_SP7A[0].pNxtDscp	= &DMA_Desc_SP7A[1];

	DMA_Desc_SP7A[1].pStartAddr	= (void *)SP7ABuffer[1][0];
	DMA_Desc_SP7A[1].Config		= ENUM_DMA_CFG_XCNT_INT;
	DMA_Desc_SP7A[1].XCount		= BLOCKSIZE * I2S_NB_CH;
	DMA_Desc_SP7A[1].XModify	= 4;
	DMA_Desc_SP7A[1].YCount		= 0;
	DMA_Desc_SP7A[1].YModify	= 0;
	DMA_Desc_SP7A[1].pNxtDscp	= &DMA_Desc_SP7A[0];

	//2A
	//DAC buffer
	DMA_Desc_SP2A[0].pStartAddr	= (void *)SP2ABuffer[0][0];
	DMA_Desc_SP2A[0].Config		= ENUM_DMA_CFG_XCNT_INT;
	DMA_Desc_SP2A[0].XCount		= BLOCKSIZE * I2S_NB_CH;
	DMA_Desc_SP2A[0].XModify	= 4;
	DMA_Desc_SP2A[0].YCount		= 0;
	DMA_Desc_SP2A[0].YModify	= 0;
	DMA_Desc_SP2A[0].pNxtDscp	= &DMA_Desc_SP2A[1];

	DMA_Desc_SP2A[1].pStartAddr	= (void *)SP2ABuffer[1][0];
	DMA_Desc_SP2A[1].Config		= ENUM_DMA_CFG_XCNT_INT;
	DMA_Desc_SP2A[1].XCount		= BLOCKSIZE * I2S_NB_CH;
	DMA_Desc_SP2A[1].XModify	= 4;
	DMA_Desc_SP2A[1].YCount		= 0;
	DMA_Desc_SP2A[1].YModify	= 0;
	DMA_Desc_SP2A[1].pNxtDscp	= &DMA_Desc_SP2A[0];


	DEBUG_PRINT("DMA descriptors initialized\n");
}

//Memory required for SPORTs
static uint8_t SPORTMemory0A[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory0B[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory1A[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory1B[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory2A[ADI_SPORT_MEMORY_SIZE];

static uint8_t SPORTMemory4A[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory5A[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory5B[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory6A[ADI_SPORT_MEMORY_SIZE];
static uint8_t SPORTMemory7A[ADI_SPORT_MEMORY_SIZE];

//SPORT Handles
static ADI_SPORT_HANDLE hSPORT_0A;
static ADI_SPORT_HANDLE hSPORT_0B;
static ADI_SPORT_HANDLE hSPORT_1A;
static ADI_SPORT_HANDLE hSPORT_1B;
static ADI_SPORT_HANDLE hSPORT_2A;		//DAC: I2S mode, p. 8/35/73

static ADI_SPORT_HANDLE hSPORT_4A;		//ADC: I2S mode, p. 33
static ADI_SPORT_HANDLE hSPORT_5A;
static ADI_SPORT_HANDLE hSPORT_5B;
static ADI_SPORT_HANDLE hSPORT_6A;
static ADI_SPORT_HANDLE hSPORT_7A;		//MCU: I2S mode

static bool block_number = 0;

ADI_CACHE_ALIGN volatile int32_t SP4ABuffer[DMA_NUM_DESC][BLOCKSIZE * I2S_NB_CH] = {};
ADI_CACHE_ALIGN volatile int32_t SP7ABuffer[DMA_NUM_DESC][BLOCKSIZE * I2S_NB_CH] = {};
ADI_CACHE_ALIGN volatile int32_t SP2ABuffer[DMA_NUM_DESC][BLOCKSIZE * I2S_NB_CH] = {};

//Function prototypes
void SPORT4A_RX_Cb(void *pAppHandle, uint32_t nEvent, void *pArg);

//Function definitions
void SPORT_Init(void){

    ADI_SPORT_RESULT eResult;

    //Memset of buffers

    //---- Inputs ----
	//SPORT Device 4A - ADC
	eResult = adi_sport_Open(4u, ADI_HALF_SPORT_A, ADI_SPORT_DIR_RX, ADI_SPORT_I2S_MODE, SPORTMemory4A, ADI_SPORT_MEMORY_SIZE, &hSPORT_4A);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure data: 32 bit, msb first, not packed, left-justified
	eResult = adi_sport_ConfigData(hSPORT_4A, ADI_SPORT_DTYPE_SIGN_FILL, 31, false, false, false);		//ADI_SPORT_DTYPE_ZERO_FILL
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure clock: div = 32, external clock, data driven on rising edge, disable gated clock
	//CLKDIV = (SCLK/SPORT_ACLK)-1 = (125 / 3,072)-1 = 39,7
	eResult = adi_sport_ConfigClock(hSPORT_4A, 0, false, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure frame sync: 32 bit, fs required, external fs, data-dependent fs, active high fs, use early fs, fs is level sensitive
	eResult = adi_sport_ConfigFrameSync(hSPORT_4A, 31, true, false, false, true, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 4A initialized\n");

	//SPORT Device 7A - MCU
	eResult = adi_sport_Open(7u, ADI_HALF_SPORT_A, ADI_SPORT_DIR_RX, ADI_SPORT_I2S_MODE, SPORTMemory7A, ADI_SPORT_MEMORY_SIZE, &hSPORT_7A);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure data: 32 bit, msb first, not packed, left-justified
	eResult = adi_sport_ConfigData(hSPORT_7A, ADI_SPORT_DTYPE_SIGN_FILL, 31, false, false, false);		//ADI_SPORT_DTYPE_ZERO_FILL
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure clock: div = 32, external clock, data driven on rising edge, disable gated clock
	//CLKDIV = (SCLK/SPORT_ACLK)-1 = (125 / 3,072)-1 = 39,7
	eResult = adi_sport_ConfigClock(hSPORT_7A, 0, false, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure frame sync: 32 bit, fs required, external fs, data-dependent fs, active high fs, use early fs, fs is level sensitive
	eResult = adi_sport_ConfigFrameSync(hSPORT_7A, 31, true, false, false, true, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 7A initialized\n");


	//---- Outputs ----
	//SPORT Device 2A - DAC
	eResult = adi_sport_Open(2u, ADI_HALF_SPORT_A, ADI_SPORT_DIR_TX, ADI_SPORT_I2S_MODE, SPORTMemory2A, ADI_SPORT_MEMORY_SIZE, &hSPORT_2A);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure data: 32 bit, msb first, not packed, left-justified
	eResult = adi_sport_ConfigData(hSPORT_2A, ADI_SPORT_DTYPE_SIGN_FILL, 31, false, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure clock
	//eResult = adi_sport_ConfigClock(hSPORT_2A, 31, true, false, false);
	eResult = adi_sport_ConfigClock(hSPORT_2A, 0, false, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	//Configure frame sync
	eResult = adi_sport_ConfigFrameSync(hSPORT_2A, 31, true, false, false, true, false, false);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 2A initialized\n");


	//--------
	//Submit the first buffer for Rx
	eResult = adi_sport_DMATransfer(hSPORT_4A, &DMA_Desc_SP4A[0], DMA_NUM_DESC, ADI_PDMA_DESCRIPTOR_LIST, ADI_SPORT_CHANNEL_PRIM);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 4A dma started\n");

	eResult = adi_sport_DMATransfer(hSPORT_7A, &DMA_Desc_SP7A[0], DMA_NUM_DESC, ADI_PDMA_DESCRIPTOR_LIST, ADI_SPORT_CHANNEL_PRIM);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 7A dma started\n");

	//Submit the first buffer for Tx
	eResult = adi_sport_DMATransfer(hSPORT_2A, &DMA_Desc_SP2A[0], DMA_NUM_DESC, ADI_PDMA_DESCRIPTOR_LIST, ADI_SPORT_CHANNEL_PRIM);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 2A dma started\n");


	//--------
	//Enable the Sport Device 4A
	eResult = adi_sport_Enable(hSPORT_4A, true);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 4A enabled\n");

	//Enable the Sport Device 7A
	eResult = adi_sport_Enable(hSPORT_7A, true);
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 7A enabled\n");

	//Enable the Sport Device 2A
	eResult = adi_sport_Enable(hSPORT_2A, true);
	// ================> CODE DOESN'T RECH THIS STEP <=======================
	if(eResult != ADI_SPORT_SUCCESS) {printf("SPORT Error! Errorcode: 0x%08X\n", eResult);}
	DEBUG_PRINT("SPORT 2A enabled\n");



	DEBUG_PRINT("SPORTs initialized\n");
}



Added questions
[edited by: MKrautter at 8:47 AM (GMT -5) on 28 Feb 2023]
Parents
  • Hello,

    I changed the SPORT configuration to static config. That is a thing, which is NOT consistently implemented in the example projects! Some use the static configuration, some use API functions... What is the way to go?

    I was able to enclose the problem with sport enable function getting stuck. If I delete 
    adi_sport_DMATransfer(hSPORT_2A, &DMA_Desc_SP2A[0], DMA_NUM_DESC, ADI_PDMA_DESCRIPTOR_LIST, ADI_SPORT_CHANNEL_PRIM);
    the code runs through. I conclude that something with the DMA settings of SPORT2A is not correct. I checked the dma descriptors. They are equally build up.

    Please have a look at the problem.

    Regards,
    Markus

  • Hi MKrautter,
                           
    Regrading "Is it necessary to configure a secure transaction for the SPORTx and the corresponding DMA channel as I did in SPU_Init function?"
    >>Yes, it's necessary to configure a secure transaction for the SPORTx and Sportx DMA channel.
    The system protection unit (SPU) provides write-protection against MMRs peripherals and its own write-protect registers. If a write attempt is made to any locked MMR peripheral the SPU has write protected, it blocks the write. The SPU generates a bus error to the master that attempted the write. So, the peripherals which are used in your application need to be configured for the secure privileges on the SPU_SECUREP(n) registers.

    Regrading "Is it neccessary to configure the static sport config additionally/identical to my SPORT_Init function where I call the config functions for data and clocks?"
    >>>SSLDD 3.0 Device Drivers support the static configuration of the peripherals i.e. users can provide the required configuration parameters beforehand so that device driver can configure the peripheral in the initialization API. Static configuration header files contain set of configuration macros which device drivers use to configure the peripheral. 

    adi_sport_config_2156x.h is available in project > system > drivers> sport

    Either you can modify your static file or you can use API functions.

    Regarding "Please explain the data format in adi_sport_ConfigData function. I just want to handle standard PCM samples in I2S mode."
    >> adi_sport_ConfigData function sets data format for the specified SPORT device (i.e., Sets data type, Big endian (MSB first) OR Little endian (LSB first) and word length(in bits) for the specified SPORT device)

    Regarding "What does nClockRatio do in adi_sport_ConfigClock function?
    >>The nClockRatio is used to set the divider value for the SPORT Clock. We suggest to refer the Serial Clock [Page No:1093/2453] in ADSP-21569 Hardware Reference Manual is given below,
    www.analog.com/.../adsp-2156x_hwr.pdf

    Regarding " Is that the setting of the bitclock?"
    >>>It is used to configure the clock for the specified SPORT device. It is configuring the SPORT device to use the "internal/external " rising/falling clock edge, clock edge and for enabling the gated Clock Mode.

    In the below mentioned BSP example code, it is configured as external clock in Static configuration header file. So, SPORT device gets its clock from PCG.

    It seems like your SRU configurations are incorrect with your SPORT configuration (i.e., if you are giving clock from PCG to DAC and SPORT then please remove the below configuration.
                //---- MCLK Input ----
                SRU(LOW, DAI0_PBEN04_I);                  //Set pinbuf to input
                SRU(DAI0_PB04_O, PCG0_EXTCLKA_I);   //Route clock input to PCG A
                SRU(DAI0_PB04_O, PCG0_EXTCLKB_I);   //Route clock input to PCG

    SRU(PCG0_FSA_O, DAI0_PB19_I) you are giving pcg0 frame sync output to input in DAI0_19.
    SRU2(DAI1_PB19_O, SPT4_AD0_I) then the output of this DAI Pin given as an input of SPORT Data pin.  You cannot give the Frame sync to data pin.
    Also, You are not configuring any clock and Frame sync for SPORT2.)  

    Can you please explain your application in detail.
     
    Also, we would suggest to refer the example project "Audio_Passthrough_I2S" in BSP of ADSP-2156x which might be helpful for you. You can download the BSP using below link.
    download.analog.com/.../ADI_ADSP-2156x_EZ-KIT-Rel1.0.1.exe      

    After installation, please navigate as given below:
    <installation path>:\Analog Devices\ADSP-2156x_EZ-KIT-Rel1.0.1\ADSP-2156x_EZ-KIT\Examples\drivers\adc\Audio_Passthrough_I2S

    If possible, can we get simple project to simulate issue in our end

    Regards,
    Divya.P

Reply
  • Hi MKrautter,
                           
    Regrading "Is it necessary to configure a secure transaction for the SPORTx and the corresponding DMA channel as I did in SPU_Init function?"
    >>Yes, it's necessary to configure a secure transaction for the SPORTx and Sportx DMA channel.
    The system protection unit (SPU) provides write-protection against MMRs peripherals and its own write-protect registers. If a write attempt is made to any locked MMR peripheral the SPU has write protected, it blocks the write. The SPU generates a bus error to the master that attempted the write. So, the peripherals which are used in your application need to be configured for the secure privileges on the SPU_SECUREP(n) registers.

    Regrading "Is it neccessary to configure the static sport config additionally/identical to my SPORT_Init function where I call the config functions for data and clocks?"
    >>>SSLDD 3.0 Device Drivers support the static configuration of the peripherals i.e. users can provide the required configuration parameters beforehand so that device driver can configure the peripheral in the initialization API. Static configuration header files contain set of configuration macros which device drivers use to configure the peripheral. 

    adi_sport_config_2156x.h is available in project > system > drivers> sport

    Either you can modify your static file or you can use API functions.

    Regarding "Please explain the data format in adi_sport_ConfigData function. I just want to handle standard PCM samples in I2S mode."
    >> adi_sport_ConfigData function sets data format for the specified SPORT device (i.e., Sets data type, Big endian (MSB first) OR Little endian (LSB first) and word length(in bits) for the specified SPORT device)

    Regarding "What does nClockRatio do in adi_sport_ConfigClock function?
    >>The nClockRatio is used to set the divider value for the SPORT Clock. We suggest to refer the Serial Clock [Page No:1093/2453] in ADSP-21569 Hardware Reference Manual is given below,
    www.analog.com/.../adsp-2156x_hwr.pdf

    Regarding " Is that the setting of the bitclock?"
    >>>It is used to configure the clock for the specified SPORT device. It is configuring the SPORT device to use the "internal/external " rising/falling clock edge, clock edge and for enabling the gated Clock Mode.

    In the below mentioned BSP example code, it is configured as external clock in Static configuration header file. So, SPORT device gets its clock from PCG.

    It seems like your SRU configurations are incorrect with your SPORT configuration (i.e., if you are giving clock from PCG to DAC and SPORT then please remove the below configuration.
                //---- MCLK Input ----
                SRU(LOW, DAI0_PBEN04_I);                  //Set pinbuf to input
                SRU(DAI0_PB04_O, PCG0_EXTCLKA_I);   //Route clock input to PCG A
                SRU(DAI0_PB04_O, PCG0_EXTCLKB_I);   //Route clock input to PCG

    SRU(PCG0_FSA_O, DAI0_PB19_I) you are giving pcg0 frame sync output to input in DAI0_19.
    SRU2(DAI1_PB19_O, SPT4_AD0_I) then the output of this DAI Pin given as an input of SPORT Data pin.  You cannot give the Frame sync to data pin.
    Also, You are not configuring any clock and Frame sync for SPORT2.)  

    Can you please explain your application in detail.
     
    Also, we would suggest to refer the example project "Audio_Passthrough_I2S" in BSP of ADSP-2156x which might be helpful for you. You can download the BSP using below link.
    download.analog.com/.../ADI_ADSP-2156x_EZ-KIT-Rel1.0.1.exe      

    After installation, please navigate as given below:
    <installation path>:\Analog Devices\ADSP-2156x_EZ-KIT-Rel1.0.1\ADSP-2156x_EZ-KIT\Examples\drivers\adc\Audio_Passthrough_I2S

    If possible, can we get simple project to simulate issue in our end

    Regards,
    Divya.P

Children
  • Hi Divya,

    Regarding "Please explain the data format in adi_sport_ConfigData function. I just want to handle standard PCM samples in I2S mode."
    >> adi_sport_ConfigData function sets data format for the specified SPORT device (i.e., Sets data type, Big endian (MSB first) OR Little endian (LSB first) and word length(in bits) for the specified SPORT device)

    Please answer my question precisely. What do I need to set the following definition to, if I want to use simple I2S with standard PCM samples, left-justified:

    /*! Selects the Data Type Formatting for Half-Sport's Data transfer.
    * Configurable for DSP serial mode/Multi-channel(TDM)/Packed I2S mode.
    * Configured as :
    * 0 : Right-justify data, zero-fill unused MSBs
    * 1 : Right-justify data, sign-extend unused MSBs
    * 2 : u-law compand data
    * 3 : A-law compand data*/
    #define ADI_SPORT0A_CTL_DTYPE 0ul

    Regarding "What does nClockRatio do in adi_sport_ConfigClock function?
    >>The nClockRatio is used to set the divider value for the SPORT Clock. We suggest to refer the Serial Clock [Page No:1093/2453] in ADSP-21569 Hardware Reference Manual is given below,

    I rered the passage in the manual. I think I came to the point. I configured the sport clock to external clock (because it is sourced by the PCG). In that mode, the clock divider will be ignored.

    Concerning your change requests in the SRU config:
    //---- MCLK Input ----
    SRU(LOW, DAI0_PBEN04_I); //Set pinbuf to input
    SRU(DAI0_PB04_O, PCG0_EXTCLKA_I); //Route clock input to PCG A
    SRU(DAI0_PB04_O, PCG0_EXTCLKB_I); //Route clock input to PCG B

    I can't remove that config, because without clock input (24.576 MHz) the PCG won't generate any clocks...

    SRU(PCG0_FSA_O, DAI0_PB19_I)
    That's a pin of DAI0 (zero)

    SRU2(DAI1_PB19_O, SPT4_AD0_I)
    That's a pin of DAI1 (one). So these pins are not identical. Therefore the config should be correct.

    Also, You are not configuring any clock and Frame sync for SPORT2
    Yes, you are right. That was because I tried if the config would work with SPORT3A and forgot to correct it back to SPORT2A.

    Please have a look at my final routing config and confirm if that is correct. The changes didn't fix the issue of sport enable function getting stuck for SPORT2A.

    	//---- MCLK Input ----
    	SRU(LOW, DAI0_PBEN04_I);			//Set pinbuf to input
    	SRU(DAI0_PB04_O, PCG0_EXTCLKA_I);	//Route clock input to PCG A
    	SRU(DAI0_PB04_O, PCG0_EXTCLKB_I);	//Route clock input to PCG B
    
    
    	//---- Clocks ----
    	//DAC - SPORT2A
    	SRU(HIGH, DAI0_PBEN03_I);			//Output
    	SRU(PCG0_CLKA_O, DAI0_PB03_I);		//PCG A clk to DAC MCLK pin
    
    	SRU(HIGH, DAI0_PBEN06_I);			//Output
    	SRU(PCG0_CLKA_O, DAI0_PB06_I);		//PCG A clk to DAC BCLK pin
    	SRU(PCG0_CLKA_O, SPT2_ACLK_I);		//PCG A clk to SPORT 2A
    
    	SRU(HIGH, DAI0_PBEN02_I);			//Output
    	SRU(PCG0_FSA_O, DAI0_PB02_I);		//PCG A fs to DAC LRCLK pin
    	SRU(PCG0_FSA_O, SPT2_AFS_I);		//PCG A clk to SPORT 2A
    
    	//ADC - SPORT4A
    	SRU(HIGH, DAI0_PBEN12_I);			//Output
    	SRU(PCG0_CLKA_O, DAI0_PB12_I);		//PCG A clk to ADC MCLK pin
    
    	SRU(HIGH, DAI0_PBEN20_I);			//Output
    	SRU(PCG0_CLKA_O, DAI0_PB20_I);		//PCG A clk to ADC BCLK pin
    	SRU2(PCG0_CRS_CLKA_O, SPT4_ACLK_I);	//PCG A clk to SPORT 4A (CRS)
    
    	SRU(HIGH, DAI0_PBEN19_I);			//Output
    	SRU(PCG0_FSA_O, DAI0_PB19_I);		//PCG A fs to ADC LRCLK pin
    	SRU2(PCG0_CRS_FSA_O, SPT4_AFS_I);	//PCG A fs to SPORT 4A (CRS)
    
    
    	//---- Data pins ----
    	//DAC
    	SRU(HIGH, DAI0_PBEN01_I);			//Output
    	SRU(SPT2_AD0_O, DAI0_PB01_I); 		//SPORT 2A
    
    	//ADC
    	SRU2(LOW, DAI1_PBEN19_I);			//Input
    	SRU2(DAI1_PB19_O, SPT4_AD0_I); 		//SPORT 4A

    Kind regards,
    Markus

  • Hi Markus,

    We understand that you have already contacted our private support. To avoid duplication of efforts, please continue the discussion there.

    Regards,
    Divya.P

  • To at least offer others a solution to the problem:

    I had to use dedicated data buffers for one SPORT, storing them together in an array caused the problem. It is inexplicable to me why.

  • Hi Markus,

    You have used 2Dimension buffer. So, you have to provide YCount & YModify in Descriptor list. Also,  adi_sport_DMATransfer support data transfer through SPORT using 1D DMA. So, adi_sport_2DDMATransfer need to use for 2D DMA transfer.

    Regards,
    Divya.P