XMC1400 Quad SPI mode

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 am trying to generate 4 synchronised PRBS using a USIC SPI peripheral on a XMC1400. I am currently testing this on a XMC1400 Boot Kit. I have setup a USIC channel in SPI mode and configured a TXFIFO. The ISR re-fills the FIFO every time it is empty. I have this setup working using a single SPI output and would like to get it working in Quad-SPI mode.

Specific changes that I made are:

  • Enable Hardware Port Control Mode: USIC1_CH0->TCSR |= USIC_CH_TCSR_HPCMD_Msk;
  • Set transmission mode to Quad-SPI: XMC_SPI_CH_SetTransmitMode(XMC_SPI1_CH0, XMC_SPI_CH_MODE_QUAD);
  • Configure GPIO's for Hardware COntrol: XMC_GPIO_SetHardwareControl(P3_1, P3_1_HWCTRL_U1C0_DOUT3);


Unfortunately this is not enough: I have a clock output, but no data on any of DOUT[0:3].

Any help or example code is appreciated.

Thanks,
Andrew



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

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

#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[8] = {0x55, 0x33, 0x0f, 0xff, 0xf0, 0xcc, 0xaa, 0x00};


/* USIC1.SR0 Interrupt Handler */
__RAM_FUNC void IRQ9_Handler(void)
{
static uint8_t i = 0;

if (XMC_USIC_CH_TXFIFO_GetEvent(XMC_SPI1_CH0) & XMC_USIC_CH_TXFIFO_EVENT_STANDARD)
{
XMC_USIC_CH_TXFIFO_ClearEvent(XMC_SPI1_CH0, XMC_USIC_CH_TXFIFO_EVENT_STANDARD);
XMC_USIC_CH_TXFIFO_DisableEvent(XMC_SPI1_CH0, XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);

while (!XMC_USIC_CH_TXFIFO_IsFull(XMC_SPI1_CH0))
{
XMC_USIC_CH_TXFIFO_PutData(XMC_SPI1_CH0, data);
i = (i + 1) & 0x07;
}

XMC_USIC_CH_TXFIFO_EnableEvent(XMC_SPI1_CH0, XMC_USIC_CH_TXFIFO_EVENT_CONF_STANDARD);

/* 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);

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_SPI1_CH0, &spi_config);
XMC_SPI_CH_SetWordLength(XMC_SPI1_CH0, 8);
XMC_SPI_CH_SetBitOrderMsbFirst(XMC_SPI1_CH0);
XMC_SPI_CH_ConfigureShiftClockOutput(XMC_SPI1_CH0, XMC_USIC_CH_BRG_SHIFT_CLOCK_PASSIVE_LEVEL_0_DELAY_ENABLED, XMC_USIC_CH_BRG_SHIFT_CLOCK_OUTPUT_SCLK);

USIC1_CH0->TCSR |= USIC_CH_TCSR_HPCMD_Msk;
XMC_SPI_CH_SetTransmitMode(XMC_SPI1_CH0, XMC_SPI_CH_MODE_QUAD);

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

/* Start SPI */
XMC_SPI_CH_Start(XMC_SPI1_CH0);

/* GPIO pin configuration */
XMC_GPIO_SetMode(P0_2, XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P0_2_AF_U1C0_SCLKOUT);
XMC_GPIO_SetHardwareControl(P3_1, P3_1_HWCTRL_U1C0_DOUT3);
XMC_GPIO_SetHardwareControl(P3_2, P3_2_HWCTRL_U1C0_DOUT2);
XMC_GPIO_SetHardwareControl(P3_3, P3_3_HWCTRL_U1C0_DOUT1);
XMC_GPIO_SetHardwareControl(P3_4, P3_4_HWCTRL_U1C0_DOUT0);

/* Initialize NVIC */
XMC_SCU_SetInterruptControl(IRQ9_IRQn, XMC_SCU_IRQCTRL_USIC1_SR0_IRQ9);
NVIC_SetPriority(IRQ9_IRQn, 0U);
NVIC_EnableIRQ(IRQ9_IRQn);
}


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

/* Start SysTick periodic timer */
SysTick_Config(SystemCoreClock / TICKS_PER_SECOND);

/* Manually trigger the first interrupt */
USIC1_CH0->TRBSR |= USIC_CH_TRBSR_STBI_Msk;
XMC_USIC_CH_TriggerServiceRequest(XMC_SPI1_CH0, 0);

while(1)
{
}

return(0);
}
0 Likes
1 Reply
User15087
Level 2
Level 2
First like received
Found a solution.The main thing is to replace:

XMC_USIC_CH_TXFIFO_PutData(XMC_SPI1_CH0, data);

with:

XMC_SPI1_CH0->IN[7] = data;
0 Likes