XMC4500 I2S Data reception, DAVE4

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
User15058
Level 1
Level 1
Hello All,
I am currently working on an audio project where I am required to collect audio samples for something similar to speech processing. I
am using the XMC4500 hexagon application kit for this purpose. I am using the on board TLV320AIC audio codec to recieve the data.
This codec serves me as an I2S slave. I am using the USIC0_Channel1 as the I2S master. I am working on 48 kHz sampling rate.
The baud rate for communication is 1536105 hz. Following is the code for the initialization of the (USIC0_CH1) I2S channel.

I tested the audio trannsmission and it works fine. I can hear exactly the audio I send (DAC functionality of the codec).Whatever I sent
on the left channel I could hear in my left ear piece and similarly on the right ear piece. But when I try to get the recorded audio data
from the codec (using ADC functionality of the codec), it doesnot work the way exactly I want. The hardware configuration of the codec
is made such that only the left channel of the microphone is enabled inside the codec for sampling. The right channel of the microphone
is grounded. I have moreoever, as seen in the code, used separate interrupt nodes for STANDARD_RECEIVE (left channel data
interrupt) and ALTERNATE_RECEIVE (right channel data interrupt) events. Hence, according to me I should only receive data in the
left channel interrupt and no data in the right channel interrupt. By this I mean that, in the left channel i should have some meaningful
data, whereas in the right channel I should receive only '0'(since it is grounded). But I receive data in both the channels. And to my
suprise, I have more number of zeros in the left channel buffer whereas not a single buffer element is '0' in the right channel buffer.

Before this, I have also tried to test my receive interrupt routine using the internal loopback mode available in the USIC channel
(the transmitter is directly connected to the receiver internally, disconnecting the external pins). In this case, it worked well, I could get
the data exactly as I had sent. But the only problem was that, the channels were interchanged. The left_channel_buffer had all the
data tranmitted on the right channel in my trnamission routine and right_channel_buffer had all the data transmitted on the left_channel
I investigated but could not find any reason behind this behaviour.

I highly doubt that there is something wrong in my receive interrupt routine. I am very frustated at this point. It would really be a great
help if somebody can help me.
Thanks in advance.


void AudioI2S_INIT(void){

XMC_GPIO_Init(PIN_I2S_MRST, &I2S_MRST);
XMC_GPIO_Init(PIN_I2S_MTSR, &I2S_MTSR);
XMC_GPIO_Init(PIN_I2S_SCLK, &I2S_SCLK);
XMC_GPIO_Init(PIN_I2S_WA, &I2S_WA);

/* Initialize USIC channel in I2S mode */
XMC_I2S_CH_Init(XMC_I2S0_CH1, &I2S_CONFIG_0_channel_config);

/* Set the frame length, word length and system word length */
XMC_I2S_CH_SetWordLength(XMC_I2S0_CH1, 16U);
XMC_I2S_CH_SetFrameLength(XMC_I2S0_CH1, 16U);
XMC_I2S_CH_SetSystemWordLength(XMC_I2S0_CH1, 16U);

/* Set MSB data shift direction */
XMC_I2S_CH_SetBitOrderMsbFirst(XMC_I2S0_CH1);

/* Set input source for input stage dx0 (receive pin) */
XMC_I2S_CH_SetInputSource(XMC_I2S0_CH1, XMC_I2S_CH_INPUT_DIN0, USIC0_CH1_DX0B);

/* Configure the clock polarity and clock delay */
XMC_I2S_CH_ConfigureShiftClockOutput(XMC_I2S0_CH1, XMC_I2S_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK); //to be tested

NVIC_SetPriority(I2S_LEFTCHANNEL_RX_INT, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),RX_PREEMPT_PRIOR, RXTX_SUB_PRIOR));
NVIC_EnableIRQ(I2S_LEFTCHANNEL_RX_INT);

NVIC_SetPriority(I2S_RIGHTCHANNEL_RX_INT, NVIC_EncodePriority(NVIC_GetPriorityGrouping(),RX_PREEMPT_PRIOR, RXTX_SUB_PRIOR));
NVIC_EnableIRQ(I2S_RIGHTCHANNEL_RX_INT);

/* Set the service request line for the standard receive event*/
XMC_I2S_CH_SelectInterruptNodePointer(XMC_I2S0_CH1, XMC_I2S_CH_INTERRUPT_NODE_POINTER_RECEIVE, SR_RQ2);

/*Set the service request line for the alternative receive event*/
XMC_I2S_CH_SelectInterruptNodePointer(XMC_I2S0_CH1, XMC_I2S_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, SR_RQ3);

/* Enable the standard receive event and alternate receive event */
XMC_I2S_CH_EnableEvent(XMC_I2S0_CH1, XMC_I2S_CH_EVENT_STANDARD_RECEIVE | XMC_I2S_CH_EVENT_ALTERNATIVE_RECEIVE);

/* Start the I2S channel */
XMC_I2S_CH_Start(XMC_I2S0_CH1);
}

void left_channel_rx_handler(void){

if(XMC_I2S_CH_GetStatusFlag(XMC_I2S0_CH1) & XMC_I2S_CH_STATUS_FLAG_RECEIVE_INDICATION){ //Left channel

XMC_I2S_CH_DisableEvent(XMC_I2S0_CH1, XMC_I2S_CH_EVENT_STANDARD_RECEIVE);
RecDataTemp2 = (uint16_t) XMC_I2S_CH_GetReceivedData(XMC_I2S0_CH1);
XMC_I2S_CH_ClearStatusFlag(XMC_I2S0_CH1, XMC_I2S_CH_STATUS_FLAG_RECEIVE_INDICATION);
left_channel_buff[left_channel_index] = RecDataTemp2;
left_channel_index++;

if(left_channel_index >= size_of_rx_buff){
left_channel_index = 0;
new_ldata_flag = true;
}
XMC_I2S_CH_EnableEvent(XMC_I2S0_CH1, XMC_I2S_CH_EVENT_STANDARD_RECEIVE);
}
}

void right_channel_rx_handler(void){

if(XMC_I2S_CH_GetStatusFlag(XMC_I2S0_CH1) & XMC_I2S_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION){ //Right channel

XMC_I2S_CH_DisableEvent(XMC_I2S0_CH1, XMC_I2S_CH_EVENT_ALTERNATIVE_RECEIVE);
RecDataTemp2 = (uint16_t) XMC_I2S_CH_GetReceivedData(XMC_I2S0_CH1);
XMC_I2S_CH_ClearStatusFlag(XMC_I2S0_CH1, XMC_I2S_CH_STATUS_FLAG_ALTERNATIVE_RECEIVE_INDICATION);
right_channel_buff[right_channel_index] = RecDataTemp2;
right_channel_index++;

if(right_channel_index >= size_of_rx_buff){
right_channel_index = 0;
new_rdata_flag = true;
}
XMC_I2S_CH_EnableEvent(XMC_I2S0_CH1, XMC_I2S_CH_EVENT_ALTERNATIVE_RECEIVE);
}
}



P.S: I am not using RXFIFO (RXFIFO size is '0'). I am right now reading directly from the RBUF.
0 Likes
4 Replies
User15058
Level 1
Level 1
Hello Members,
as a matter of fact, I also analyzed the received data (sent on the I2S_MRST pin, from the codec to the xmc4500) on the oscilloscope to
see if there is any data being sent on the right channel. As expected, there is no data being sent on the right channel whereas left
channel had some random data, which makes complete sense. So now I am sure that some error resides in my code.

Could anybody please help me ? I expect some support atleast from Infineon employees.
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi,

can you please post also the "I2S_CONFIG_0_channel_config" structure so I can see what configuration have you been using for your example?

Best regards,
Deni
0 Likes
User15058
Level 1
Level 1

const XMC_I2S_CH_CONFIG_t I2S_CONFIG_0_channel_config =
{
#ifdef FREQ_44KHZ
.baudrate = 1411271U, /* 1411271U - 44khz frequency , 1536105U - 48khz */
#else
.baudrate = 1536105U,
#endif
.data_bits = 16U,
.frame_length = 16U,
.data_delayed_sclk_periods = 1U,
.wa_inversion = XMC_I2S_CH_WA_POLARITY_DIRECT,
.bus_mode = XMC_I2S_CH_BUS_MODE_MASTER /* I2S in Master Mode */
};
0 Likes
lock attach
Attachments are accessible only for community members.
DRubeša
Employee
Employee
First solution authored First like received
Hi,

so I have been taking a look at your code and I don´t see anything obviously wrong. What is saw from the application reference guide of a codec there are set of ADC processing blocks that can be used. I don´t know what option are you using but I guess it´s stereo while the other option ("right channel") doesn´t make sense in your case while you said right channel is grounded. So, you´re kind of sending both channels even if one is grounded (or maybe there is another option to select in the codec, haven´t check whole document).
Due to the fact you´re setting XMC as a master, I guess that it´s also generating WA signal to distinguish right and left channel. So, even if you expect the data from one channel, you will get the interrupts for both channels because of WA generation (it´s explained in the user manual). What you can do, and what we have done in the CMSIS compliant library for I2S (the .c file is attached) is to use same service request number. So both XMC_I2S_CH_INTERRUPT_NODE_POINTER_RECEIVE and XMC_I2S_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE will lead to same interrupt service routine.

Additionally, please check the attached the .c file. I was trying to compare your initialization code with the one that is provided in .c file and I don´t see some differences that would raise a concern. However, you should also double check so we didn´t miss something important:

Regards,
Deni

0 Likes