I2S with XMC1400

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

cross mob
Not applicable
Hi,

I am trying to read out a mems microphone through I2S (so i am I2S master). I want to use the FIFO. Here is the code that i currently have:


#define ICS43432_USIC_CHANNEL USIC0_CH0
#define ICS43432_USIC XMC_I2S0_CH0

#define ICS43432_WS_PIN P1_4
#define ICS43432_WS_PIN_AF (XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT6 | P1_4_AF_U0C0_SELO0)

#define ICS43432_SCK_PIN P0_14
#define ICS43432_SCK_PIN_AF (XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT7 | P0_14_AF_U0C0_SCLKOUT)

#define ICS43432_SD_PIN P0_15
#define ICS43432_SD_INPUT XMC_USIC_CH_INPUT_DX0
#define ICS43432_SD_SOURCE 0b001 // DX0B

#define ICS43432_SERVICE_REQUEST_SD 2 // receive
#define ICS43432_IRQ_SD 11
#define ICS43432_IRQ_SD_PRIORITY 0
#define ICS43432_IRQCTRL_SD XMC_SCU_IRQCTRL_USIC0_SR2_IRQ11


void ics43432_init(void) {
// WS pin configuration
const XMC_GPIO_CONFIG_t ws_pin_config = {
.mode = ICS43432_WS_PIN_AF,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH
};

// SCK pin configuration
const XMC_GPIO_CONFIG_t sck_pin_config = {
.mode = ICS43432_SCK_PIN_AF,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH
};

// SD pin configuration
const XMC_GPIO_CONFIG_t sd_pin_config = {
.mode = XMC_GPIO_MODE_INPUT_PULL_UP,
.input_hysteresis = XMC_GPIO_INPUT_HYSTERESIS_STANDARD
};


// Configure pins
XMC_GPIO_Init(ICS43432_WS_PIN, &ws_pin_config);
XMC_GPIO_Init(ICS43432_SCK_PIN, &sck_pin_config);
XMC_GPIO_Init(ICS43432_SD_PIN, &sd_pin_config);

const XMC_I2S_CH_CONFIG_t config = {
.baudrate = 19200*160,
.data_bits = 24,
.frame_length = 64,
.data_delayed_sclk_periods = 1,
.wa_inversion = XMC_I2S_CH_WA_POLARITY_DIRECT,
.bus_mode = XMC_I2S_CH_BUS_MODE_MASTER
};

// Initialize USIC channel in I2S mode
XMC_I2S_CH_Init(ICS43432_USIC, &config);

// Set the frame length, word length and system word length
XMC_I2S_CH_SetFrameLength(ICS43432_USIC, 64);
XMC_I2S_CH_SetWordLength(ICS43432_USIC, 24);
XMC_I2S_CH_SetSystemWordLength(ICS43432_USIC, 64);

// Set MSB data shift direction
XMC_I2S_CH_SetBitOrderMsbFirst(ICS43432_USIC);

// Set input source for input stage dx0 (receive pin)
XMC_I2S_CH_SetInputSource(ICS43432_USIC, ICS43432_SD_INPUT, ICS43432_SD_SOURCE);

// Configure the clock polarity and clock delay
XMC_USIC_CH_ConfigureShiftClockOutput(ICS43432_USIC, XMC_USIC_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_DISABLED, XMC_USIC_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);

// Set the service request line for the Data Lost, Baud Rate Generator and I2S protocol events
XMC_USIC_CH_SetInterruptNodePointer(ICS43432_USIC, XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL, 0);

// Configure the receive FIFO
XMC_USIC_CH_RXFIFO_Configure(ICS43432_USIC, 32, XMC_USIC_CH_FIFO_SIZE_16WORDS, 1);

XMC_USIC_CH_RXFIFO_SetInterruptNodePointer(ICS43432_USIC, XMC_USIC_CH_RXFIFO_INTERRUPT_NODE_POINTER_STANDARD, ICS43432_SERVICE_REQUEST_SD);
XMC_USIC_CH_RXFIFO_SetInterruptNodePointer(ICS43432_USIC, XMC_USIC_CH_RXFIFO_INTERRUPT_NODE_POINTER_ALTERNATE, ICS43432_SERVICE_REQUEST_SD);

XMC_I2S_CH_EnableEvent(ICS43432_USIC, XMC_I2S_CH_EVENT_STANDARD_RECEIVE | XMC_I2S_CH_EVENT_ALTERNATIVE_RECEIVE);

// Set priority and enable NVIC node for receive interrupt
NVIC_SetPriority(ICS43432_IRQ_SD, ICS43432_IRQ_SD_PRIORITY);
XMC_SCU_SetInterruptControl(ICS43432_IRQ_SD, ICS43432_IRQCTRL_SD);
NVIC_EnableIRQ(ICS43432_IRQ_SD);

XMC_I2S_CH_EnableMasterClock(ICS43432_USIC);
XMC_I2S_CH_Start(ICS43432_USIC);
}


In a loop i regularly call
XMC_I2S_CH_Receive(ICS43432_USIC, XMC_I2S_CH_CHANNEL_1_LEFT);


If i call
XMC_I2S_CH_GetReceivedData(ICS43432_USIC)

I do sometimes get same data back (always 8 bit???) and the signals WS/SCK/SD signals look good if i look at them with an oscilloscope.

But the IRQ is never triggered.

Has anybody an idea what i am missing?

As far as i can tell there are no example apps for I2S. Would it be possible for Infineon to make one? I find it really hard to start from scratch here without any examples.

Thanks!
0 Likes
4 Replies
DRubeša
Employee
Employee
First solution authored First like received
Hi borg,

as a matter of fact we have something that could be helpful for you. In our CMSIS pack () for XMC1000 family we have SAI driver. SAI stands for Serial Audio Interface and it´s implemented ..."http://dave.infineon.com/Libraries/CMSIS_PACK/Infineon.XMC1000_DFP.2.7.0.pack"XMC1000 family CMSIS pack and then under "RTE_Driver" you can find both SAI.c and SAI.h. Take a look at those files how the configuration for I2S is done. Additionally, there is also an example using SAI driver. Download XMC4000 family CMSIS pack (Download here) and under "Boards->Infineon->XMC4500 Application Kit" you can find a working example. It´s just to see maybe an order of commands and which XMCLibs functions should be called.

P.S. The downloaded file is a .pack file. For manual inspections it can be renamed to a . Zip file and unzipped as usual.

Best regards,
Deni
0 Likes
Not applicable
Hello Deni,

Thank you for the links, after careful comparison of the source codes i found the difference. Instead of only

XMC_I2S_CH_EnableEvent(ICS43432_USIC, XMC_I2S_CH_EVENT_STANDARD_RECEIVE | XMC_I2S_CH_EVENT_ALTERNATIVE_RECEIVE);


i need to use

XMC_I2S_CH_EnableEvent(ICS43432_USIC, XMC_I2S_CH_EVENT_STANDARD_RECEIVE | XMC_I2S_CH_EVENT_ALTERNATIVE_RECEIVE);
XMC_USIC_CH_RXFIFO_EnableEvent(ICS43432_USIC, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD | XMC_USIC_CH_RXFIFO_EVENT_CONF_ALTERNATIVE);


So the event was actually not enabled for the FIFO and only for I2S i guess.
0 Likes
DRubeša
Employee
Employee
First solution authored First like received
Hi borg,

and now is it working or you still have some issues?

Regards,
Deni
0 Likes
Not applicable
It is working now!
0 Likes