Sep 28, 2020
07:48 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 28, 2020
07:48 AM
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?
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);
}
- Tags:
- IFX
2 Replies
Sep 28, 2020
02:06 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 28, 2020
02:06 PM
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.
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.
Sep 29, 2020
12:29 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Sep 29, 2020
12:29 PM
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.
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.