USIC TXFIFO ISR triggered twice

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

cross mob
User15087
Level 2
Level 2
First like received
Hi!

I have made a short program that I am running on a XMC1400 Boot Kit. I have included the source code below. The goal is to use a USIC in SPI mode to send out a PRBS. I have setup the TXFIFO and want to trigger an USIC interrupt when the TXFIFO is (almost) empty to refill it, thereby creating a continuous stream of bits with no or minimal jitter on the SCLK.

The example code below is to demonstrate an issue that I am facing. Every 100 ms two words are put into the TXFIFO; which is handled by the SysTick ISR. These words are then transmitted by the USIC as I can see on the oscilloscope. I expect the USIC ISR to trigger only once when the last word is being transmitted, but instead the ISR is called twice shortly after each other (~1.8 us) causing only a short pulse on the GPIO. What am I missing here?


#include "xmc_gpio.h"
#include "xmc_spi.h"

#define USIC0_0_IRQn IRQ9_IRQn
#define USIC0_0_IRQHandler IRQ9_Handler

#define LED1 P4_0
#define LED2 P4_1
#define LED3 P4_2
#define LED4 P4_3

#define SPI_MISO P2_0
#define SPI_MOSI P2_1
#define SPI_SS P1_4
#define SPI_SCLK P1_6

#define TICKS_PER_SECOND 1000
#define TICKS_WAIT 100


const XMC_SPI_CH_CONFIG_t spi_config =
{
.baudrate = 2000000,
.bus_mode = XMC_SPI_CH_BUS_MODE_MASTER,
.selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS,
.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE
};

const uint16_t data[2] = {0x0084, 0x02aa};


/* USIC0.SR0 Interrupt Handler */
__RAM_FUNC void USIC0_0_IRQHandler(void)
{
uint32_t event;

event = XMC_USIC_CH_TXFIFO_GetEvent(XMC_SPI0_CH0);
XMC_USIC_CH_TXFIFO_ClearEvent(XMC_SPI0_CH0, event);

/* Toggle Debug LED */
XMC_GPIO_ToggleOutput(LED1);
}

void SysTick_Handler(void)
{
static uint32_t ticks = 0;
ticks++;

if (ticks == TICKS_WAIT)
{
/* Toggle Debug LED */
XMC_GPIO_ToggleOutput(LED4);

/* Load the TX FIFO with 2 words */
XMC_SPI_CH_DisableDataTransmission(XMC_SPI0_CH0);
XMC_USIC_CH_TXFIFO_PutData(XMC_SPI0_CH0, data[0]);
XMC_USIC_CH_TXFIFO_PutData(XMC_SPI0_CH0, data[1]);
XMC_SPI_CH_EnableDataTransmission(XMC_SPI0_CH0);

ticks = 0;
}
}


void LED_Init(void)
{
XMC_GPIO_SetMode(LED1, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetMode(LED2, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetMode(LED3, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);
XMC_GPIO_SetMode(LED4, XMC_GPIO_MODE_OUTPUT_PUSH_PULL);

/* Output 'Low' to enable LED */
XMC_GPIO_SetOutputHigh(LED1);
XMC_GPIO_SetOutputHigh(LED2);
XMC_GPIO_SetOutputHigh(LED3);
XMC_GPIO_SetOutputHigh(LED4);
}


void SPI_Init(void)
{
/* Initialize SPI */
XMC_SPI_CH_Init(XMC_SPI0_CH0, &spi_config);
XMC_SPI_CH_SetWordLength(XMC_SPI0_CH0, 10);
XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI0_CH0);
XMC_SPI_CH_ConfigureShiftClockOutput(XMC_SPI0_CH0, XMC_USIC_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_ENABLED, XMC_USIC_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);

/* Input source selection */
XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_DIN0, USIC0_C0_DX0_P2_0);

/* Configure FIFO */
XMC_USIC_CH_TXFIFO_Configure(XMC_SPI0_CH0, 0, XMC_USIC_CH_FIFO_SIZE_32WORDS, 1);
XMC_USIC_CH_TXFIFO_EnableEvent(XMC_SPI0_CH0, XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);
XMC_USIC_CH_TXFIFO_SetInterruptNodePointer(XMC_SPI0_CH0, XMC_USIC_CH_TXFIFO_INTERRUPT_NODE_POINTER_STANDARD, 0);

/* Start SPI */
XMC_SPI_CH_Start(XMC_SPI0_CH0);

/* GPIO pin configuration */
XMC_GPIO_EnableDigitalInput(P2_0);
XMC_GPIO_EnableDigitalInput(P2_1);
XMC_GPIO_SetMode(SPI_MISO, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_GPIO_SetMode(SPI_MOSI, XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P2_1_AF_U0C0_DOUT0);
XMC_GPIO_SetMode(SPI_SS, XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P1_4_AF_U0C0_SELO0);
XMC_GPIO_SetMode(SPI_SCLK, XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P1_6_AF_U0C0_SCLKOUT);

/* Initialize NVIC */
NVIC_SetPriority(USIC0_0_IRQn, 0U);
NVIC_EnableIRQ(USIC0_0_IRQn);
}


int main(void)
{
LED_Init();
SPI_Init();

/* Start sending periodic message */
SysTick_Config(SystemCoreClock / TICKS_PER_SECOND);

while(1)
{
}

return(0);
}
0 Likes
2 Replies
User11773
Level 4
Level 4
First like received First solution authored
Hi Andrew,

Possibly, when the first word is put in FIFO, it transfers to USIC register. So say, you put 5 words into FIFO and quickly. the FIFO depth could be : 0, 1 , 0, 1, 2, 3, 4.
I haven't looked at your code, but I've seen this behavior. I have a post about changing the FIFO level on the fly, Don't.
0 Likes
User15087
Level 2
Level 2
First like received
Hi TimFlynn,

I think you're right and that's exactly what's happening. I expected that wrapping the call to XMC_USIC_CH_TXFIFO_PutData() in between calls to XMC_SPI_CH_DisableDataTransmission() and XMC_SPI_CH_EnableDataTransmission() would prevent this.

Solved now by disabling the TXFIFO event before loading the FIFO.
0 Likes