Attachments are accessible only for community members.
Feb 11, 2021
02:05 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Feb 11, 2021
02:05 AM
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
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
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);
}
}
Labels
- Labels:
-
Technical Center
0 Replies