FIFO corruption when using two channels on one FIFO

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

cross mob
lock attach
Attachments are accessible only for community members.
User20411
Level 1
Level 1
First question asked
Hi,

I am trying to operate SPI and I2C at the same time on the two different channels of a USIC module of an XMC4800 using the FIFO.
Transferring words separately works without any issue. But when I enable a lot of I2C devices and an SPI device at the same time,
several RX words of the SPI device get corrupted (reading 0x0400 which makes no sense). It seems to happen when I receive data from both channels at the same time.
I can reproduce the issue on every transfer when continuously reading out an i2c device while communicating with the SPI device. This seems to be a problem with the
configuration of the FIFOs. My configuration is

XMC_USIC_CH_RXFIFO_Configure(XMC_SPI0_CH0, 0, XMC_USIC_CH_FIFO_SIZE_16WORDS, 0U);
XMC_USIC_CH_RXFIFO_SetInterruptNodePointer(XMC_SPI0_CH0, XMC_USIC_CH_RXFIFO_INTERRUPT_NODE_POINTER_STANDARD, 0);
XMC_USIC_CH_RXFIFO_EnableEvent(XMC_SPI0_CH0, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD);

XMC_USIC_CH_TXFIFO_Configure(XMC_SPI0_CH0, 16, XMC_USIC_CH_FIFO_SIZE_16WORDS, 1U);
XMC_USIC_CH_TXFIFO_SetInterruptNodePointer(XMC_SPI0_CH0, XMC_USIC_CH_TXFIFO_INTERRUPT_NODE_POINTER_STANDARD, 1);
XMC_USIC_CH_TXFIFO_EnableEvent(XMC_SPI0_CH0, XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);

XMC_USIC_CH_RXFIFO_Configure(XMC_I2C0_CH1, 32, XMC_USIC_CH_FIFO_SIZE_16WORDS, 0U);
XMC_USIC_CH_RXFIFO_SetInterruptNodePointer(XMC_I2C0_CH1, XMC_USIC_CH_RXFIFO_INTERRUPT_NODE_POINTER_STANDARD, 3);
XMC_USIC_CH_RXFIFO_EnableEvent(XMC_I2C0_CH1, XMC_USIC_CH_RXFIFO_EVENT_CONF_STANDARD);

XMC_USIC_CH_TXFIFO_Configure(XMC_I2C0_CH1, 48, XMC_USIC_CH_FIFO_SIZE_16WORDS, 1U);
XMC_USIC_CH_TXFIFO_SetInterruptNodePointer(XMC_I2C0_CH1, XMC_USIC_CH_TXFIFO_INTERRUPT_NODE_POINTER_STANDARD, 4);
XMC_USIC_CH_TXFIFO_EnableEvent(XMC_I2C0_CH1, XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);


can you see something that is wrong or is the ordering of the different FIFO channels important?
I attached a minimal example program (without the interrupt handling but waiting).

Kind regards,
Elias


#include "xmc_gpio.h"
#include "xmc_usic.h"
#include "xmc_spi.h"
#include "xmc_i2c.h"

void _configureSpi(void)
{
XMC_GPIO_CONFIG_t config = {
.mode = XMC_GPIO_MODE_INPUT_TRISTATE,
};
XMC_GPIO_Init(XMC_GPIO_PORT1, 4, &config); //MISO

config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P1_5_AF_U0C0_DOUT0;
config.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH;
config.output_strength = XMC_GPIO_OUTPUT_STRENGTH_STRONG_SOFT_EDGE;
XMC_GPIO_Init(XMC_GPIO_PORT1, 5, &config); //MOSI

config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P1_6_AF_U0C0_SCLKOUT;
XMC_GPIO_Init(XMC_GPIO_PORT1, 6, &config); //SCLK

config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P4_6_AF_U0C0_SELO2;
XMC_GPIO_Init(XMC_GPIO_PORT4, 6, &config); //SELO2 resolver

config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P4_5_AF_U0C0_SELO3;
XMC_GPIO_Init(XMC_GPIO_PORT4, 5, &config); //SELO3 brake


XMC_SPI_CH_CONFIG_t spiChConfig = {
.baudrate = 1000000,
.normal_divider_mode = false,
.bus_mode = XMC_SPI_CH_BUS_MODE_MASTER,
.selo_inversion = false,
.parity_mode = false};

XMC_SPI_CH_Init(XMC_SPI0_CH0, &spiChConfig);
XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_DIN0, USIC0_C0_DX0_P1_4);
XMC_SPI_CH_DisableDelayCompensation(XMC_SPI0_CH0);
XMC_SPI_CH_SetSlaveSelectPolarity(XMC_SPI0_CH0, XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS);
XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI0_CH0);
XMC_SPI_CH_DataLatchedInTrailingEdge(XMC_SPI0_CH0);
XMC_SPI_CH_DisableInputInversion(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_DIN0);
XMC_SPI_CH_SetInterwordDelay(XMC_SPI0_CH0, 10);
XMC_SPI_CH_EnableInterwordDelay(XMC_SPI0_CH0);
XMC_SPI_CH_ConfigureShiftClockOutput(XMC_SPI0_CH0,XMC_SPI_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_DISABLED, XMC_SPI_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);
XMC_SPI_CH_SetSlaveSelectDelay(XMC_SPI0_CH0, 2);
XMC_SPI_CH_SetWordLength(XMC_SPI0_CH0, 16);
XMC_SPI_CH_SetFrameLength(XMC_SPI0_CH0, 16);
XMC_SPI_CH_EnableSlaveSelect(XMC_SPI0_CH0, XMC_SPI_CH_SLAVE_SELECT_3);

XMC_USIC_CH_RXFIFO_Configure(XMC_SPI0_CH0, 0, XMC_USIC_CH_FIFO_SIZE_16WORDS, 0U);
XMC_USIC_CH_TXFIFO_Configure(XMC_SPI0_CH0, 16, XMC_USIC_CH_FIFO_SIZE_16WORDS, 1U);

XMC_SPI_CH_Start(XMC_SPI0_CH0);
}

void _configureI2c(void)
{
XMC_GPIO_CONFIG_t config = {
.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN | P2_5_AF_U0C1_DOUT0, //this is not doen in actual code
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH,
.output_strength =
XMC_GPIO_OUTPUT_STRENGTH_STRONG_SOFT_EDGE,
};
XMC_GPIO_Init(XMC_GPIO_PORT2, 5, &config); //SDA
config.mode = XMC_GPIO_MODE_OUTPUT_OPEN_DRAIN | P2_4_AF_U0C1_SCLKOUT,
XMC_GPIO_Init(XMC_GPIO_PORT2, 4, &config); //SCL

XMC_I2C_CH_CONFIG_t channelConf = {
.baudrate = 100000,
.normal_divider_mode = false,
.address = 0,
};
XMC_I2C_CH_Init(XMC_I2C0_CH1, &channelConf);
XMC_I2C_CH_SetInputSource(XMC_I2C0_CH1, XMC_I2C_CH_INPUT_SDA, USIC0_C1_DX0_P2_5);
XMC_I2C_CH_SetInputSource(XMC_I2C0_CH1, XMC_I2C_CH_INPUT_SCL, USIC0_C1_DX1_P2_4);
XMC_USIC_CH_RXFIFO_Configure(XMC_I2C0_CH1, 32, XMC_USIC_CH_FIFO_SIZE_16WORDS, 0U);
XMC_USIC_CH_TXFIFO_Configure(XMC_I2C0_CH1, 48, XMC_USIC_CH_FIFO_SIZE_16WORDS, 1U);
XMC_I2C_CH_Start(XMC_I2C0_CH1);
};

int main(void)
{
_configureI2c();
_configureSpi();

uint16_t rec_spi = 0;
uint8_t rec_i2c = 0;

uint8_t i2c_addr = 0b01010000;
uint8_t i2c_subaddr = 0;

XMC_I2C_CH_MasterStart(XMC_I2C0_CH1,i2c_addr << 1,XMC_I2C_CH_CMD_WRITE);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C0_CH1) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C0_CH1, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);

XMC_I2C_CH_MasterTransmit(XMC_I2C0_CH1, i2c_subaddr);
while((XMC_I2C_CH_GetStatusFlag(XMC_I2C0_CH1) & XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED) == 0U){}
XMC_I2C_CH_ClearStatusFlag(XMC_I2C0_CH1, XMC_I2C_CH_STATUS_FLAG_ACK_RECEIVED);
XMC_I2C_CH_MasterRepeatedStart(XMC_I2C0_CH1,i2c_addr << 1,XMC_I2C_CH_CMD_READ);
while (XMC_USIC_CH_RXFIFO_IsEmpty(XMC_I2C0_CH1)){}
rec_i2c = XMC_I2C_CH_GetReceivedData(XMC_I2C0_CH1);
XMC_I2C_CH_MasterReceiveAck(XMC_I2C0_CH1);

while (1)
{
// This indefinitely continues reading out the i2c device
while (XMC_USIC_CH_RXFIFO_IsEmpty(XMC_I2C0_CH1)){}
rec_i2c = XMC_I2C_CH_GetReceivedData(XMC_I2C0_CH1);
XMC_I2C_CH_MasterReceiveAck(XMC_I2C0_CH1);

XMC_SPI_CH_Transmit(XMC_SPI0_CH0, 0xF001, XMC_SPI_CH_MODE_STANDARD);
while (XMC_USIC_CH_RXFIFO_IsEmpty(XMC_SPI0_CH0)){}
XMC_SPI_CH_GetReceivedData(XMC_SPI0_CH0);

XMC_SPI_CH_Receive(XMC_SPI0_CH0, XMC_SPI_CH_MODE_STANDARD);
while (XMC_USIC_CH_RXFIFO_IsEmpty(XMC_SPI0_CH0)){}
rec_spi = XMC_SPI_CH_GetReceivedData(XMC_SPI0_CH0);
}
}
0 Likes
0 Replies