no reception of data by SPI slave on XMC1100

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

cross mob
User16189
Level 1
Level 1
Hi,

Trying to get an SPI slave up and running.
After trying the APP stuff without luck, I moved down to the bare XMClib to make it simpler and get a better understanding.


The goal:

Implement a SPI slave (on USIC0, channel 0) on a XMC1100 device on the cute 2Go development kit.
First target is to receive one byte '0x55' from an external SPI master sending in mode 0 on 1 Mhz, with slave select (active low).
Pins used on the 2Go board:

MISO P0.14
MOSI P2.0
SCLK P0.8
SS P0.9


Started with a stripped XMClib USIC SPI example, with the following changes:
- removed SPI master code
- changed to XMC1100 target device (instead of XMC4400)
- changed pin configuration
- changed word length

This resulted in the following - pretty straightforward - code:


/*
* Copyright (C) 2014 Infineon Technologies AG. All rights reserved.
*
* Infineon Technologies AG (Infineon) is supplying this software for use with
* Infineon's microcontrollers.
* This file can be freely distributed within development tools that are
* supporting such microcontrollers.
*
* THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
* OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
* INFINEON SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
* OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*/

/**
* @file
* @date 02 december,2014
* @version 0.1.0
*
* @brief SPI demo example
*
* Example of configuration for SSC Full-Duplex Communication, MasterMode and SlaveMode
*
* History

*
* Version 0.1.0 Initial

*/
#include
#include //Declarations from DAVE Code Generation (includes SFR declaration)

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

XMC_USIC_CH_t *spi_slave_ch = XMC_SPI0_CH0;

//Slave Mode U0C0
XMC_GPIO_CONFIG_t slave_rx_pin_config;
XMC_GPIO_CONFIG_t slave_tx_pin_config;
XMC_GPIO_CONFIG_t slave_selo_pin_config;
XMC_GPIO_CONFIG_t slave_clck_pin_config;

XMC_GPIO_PORT_t *slave_rx_pin = XMC_GPIO_PORT2;
XMC_GPIO_PORT_t *slave_tx_pin = XMC_GPIO_PORT0;
XMC_GPIO_PORT_t *slave_selo_pin = XMC_GPIO_PORT0;
XMC_GPIO_PORT_t *slave_clck_pin = XMC_GPIO_PORT0;
/**
* @brief SPI configuration structure
*/

XMC_SPI_CH_CONFIG_t spi_config_slaveMode;

int main(void)
{

uint16_t received_data = 0x0ACE;
uint16_t transmit_data = 0x0FAE;

//Slave Mode
spi_config_slaveMode.bus_mode = XMC_SPI_CH_BUS_MODE_SLAVE;
spi_config_slaveMode.parity_mode = XMC_USIC_CH_PARITY_MODE_NONE;

/*Initialize SPI*/
XMC_SPI_CH_Init(spi_slave_ch, &spi_config_slaveMode);

/*Start SPI*/
XMC_SPI_CH_Start(spi_slave_ch);

XMC_SPI_CH_SetWordLength(spi_slave_ch, 8);

/*Input source selected*/
XMC_SPI_CH_SetInputSource(spi_slave_ch, XMC_SPI_CH_INPUT_DIN0 ,USIC0_C0_DX0_P2_0);
XMC_SPI_CH_SetInputSource(spi_slave_ch, XMC_SPI_CH_INPUT_SLAVE_SCLKIN ,USIC0_C0_DX1_P0_8);
XMC_SPI_CH_SetInputSource(spi_slave_ch, XMC_SPI_CH_INPUT_SLAVE_SELIN ,USIC0_C0_DX2_P0_9);

/*GPIO Input pin configuration*/
slave_rx_pin_config.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
XMC_GPIO_Init(slave_rx_pin, 0, &slave_rx_pin_config);

/*GPIO Output pin configuration*/
slave_tx_pin_config.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2;
XMC_GPIO_Init(slave_tx_pin, 14, &slave_tx_pin_config);

/*GPIO Slave Select line pin configuration*/
slave_selo_pin_config.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
XMC_GPIO_Init(slave_selo_pin, 9, &slave_selo_pin_config);

/*GPIO Clock pin configuration*/
slave_clck_pin_config.mode = XMC_GPIO_MODE_INPUT_TRISTATE;
XMC_GPIO_Init(slave_clck_pin, 8, &slave_clck_pin_config);

while (1) {
received_data = XMC_SPI_CH_GetReceivedData(spi_slave_ch);
}

return 1;
}



The wires from the SPI master are soldered to the 2Go board.
With my scope, I see the clock, the MOSI and SS signals toggling.


However, when stepping with the debugger through the main loop, I do not receive the byte '0x55'.
Nothing is received at all. The PSR register is and remains 0x2, also after sending the byte from the master.
So, no receive indication flag, and also RBUF remains 0x00.

It looks likes the connections are not setup properly, or that something still has to be enabled.
Checked everything multiple times, but can not find the issue.

Any help is appreciated.
0 Likes
3 Replies
User16189
Level 1
Level 1
Already 14 days fighting with the USIC module.

Still not able to receive a single byte with the SPI slave.

Any help from Infineon would be really, really appreciated.

Even a hint on how to debug this.

I run the code above in the debugger till the XMC_SPI_CH_GetReceivedData(...) function in the main loop.
Just before executing the receive function, I send a byte '0x55' from the SPI master.

The register RBUF01SR changes from 0x00 to some value after transmission of the byte from the master. So, some signal seems to be received.
However, the behaviour is not consistent. I get different values (after restarting the whole application). That is weird and suspicious (in my eyes).
I attached three different values of RBUF01SR in the png files, after restarting the application.
WLEN is always 0, so it seems that no bit has been received. Also, RBUF0 and RBUF1 are always still 0x00.
Sometimes, PERR is set. According the documentation the 'protocol related argument PAR' doesn't not match the expected value.
This does not help me either.

The two bmp files show the communication from the SPI master to the slave:
- the clock and the MOSI line (20150905_232628.bmp)
- the clock and the SS line (20150905_232807.bmp)








3392.attach


3393.attach
0 Likes
jferreira
Employee
Employee
10 sign-ins 5 sign-ins First like received
Hi,

See code below:
#include 
#include

#define LED1 P1_1
#define LED2 P1_0

#define SPI_TX P0_14
#define SPI_RX P2_0
#define SPI_SS P0_9
#define SPI_SCLK P0_8

const XMC_SPI_CH_CONFIG_t spi_config =
{
.bus_mode = XMC_SPI_CH_BUS_MODE_SLAVE,
.selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS
};

const XMC_GPIO_CONFIG_t gpio_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL,
.output_level = XMC_GPIO_OUTPUT_LEVEL_LOW
};

volatile uint8_t received_byte;

void USIC0_0_IRQHandler(void)
{
received_byte = XMC_SPI_CH_GetReceivedData(XMC_SPI0_CH0);
}

int main(void)
{
XMC_GPIO_Init(LED1, &gpio_config);
XMC_GPIO_Init(LED2, &gpio_config);

XMC_SPI_CH_Init(XMC_SPI0_CH0, &spi_config);

XMC_GPIO_SetMode(SPI_SCLK, XMC_GPIO_MODE_INPUT_TRISTATE);
XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_DIN0, USIC0_C0_DX0_P2_0);
XMC_GPIO_SetMode(SPI_SCLK, XMC_GPIO_MODE_INPUT_PULL_UP);
XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_SLAVE_SCLKIN, USIC0_C0_DX1_P0_8);
XMC_GPIO_SetMode(SPI_SS, XMC_GPIO_MODE_INPUT_PULL_UP);
XMC_SPI_CH_SetInputSource(XMC_SPI0_CH0, XMC_SPI_CH_INPUT_SLAVE_SELIN, USIC0_C0_DX2_P0_9);

XMC_USIC_CH_SetInterruptNodePointer(XMC_SPI0_CH0, XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE, 0);
XMC_USIC_CH_SetInterruptNodePointer(XMC_SPI0_CH0, XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE, 0);
XMC_SPI_CH_EnableEvent(XMC_SPI0_CH0, XMC_SPI_CH_EVENT_STANDARD_RECEIVE | XMC_SPI_CH_EVENT_ALTERNATIVE_RECEIVE);

NVIC_SetPriority(USIC0_0_IRQn, 3);
NVIC_EnableIRQ(USIC0_0_IRQn);

XMC_SPI_CH_SetWordLength(XMC_SPI0_CH0, 8);

XMC_SPI_CH_Start(XMC_SPI0_CH0);

XMC_GPIO_SetMode(SPI_TX, XMC_GPIO_MODE_OUTPUT_PUSH_PULL | P0_14_AF_U0C0_DOUT0);

/* Placeholder for user application code. The while loop below can be replaced with user application code. */
while(1U)
{

}
}


You should call the function XMC_SPI_CH_GetReceivedData() after you have received something. In the example above it is done with interrupts but you could also poll on the flags.

Hope this helps.

Regards,
Jesus
0 Likes
User16189
Level 1
Level 1
Hi Jesus,

Thanks for your clear and structured code.
Unfortunately, rewriting the code to an interrupt based structure did not address the core problem.

Application Note Universal Serial Interface Channel (USIC) AP3230332303, page 26 did help me:
If a ’low’ active Chip Select line (CS) is used as input signal for the slave SPI device, its polarity must be inverted (via DX2CR.DPOL).
The default for the chip select line is active high, which is quite unusual for a chip select.

So, the code
XMC_USIC_CH_EnableInputInversion(XMC_SPI0_CH0, XMC_USIC_CH_INPUT_DX2);

did the trick.

The code line
.selo_inversion = XMC_SPI_CH_SLAVE_SEL_INV_TO_MSLS

did not work. I think that this also inverts the chip select signal, but for the output chip select line of an SPI master.

A note to other forum readers using the interrupt code:
In the first call of XMC_GPIO_SetMode, SPI_CLK should be SPI_RX.
And I guess that the CLK pin should have mode XMC_GPIO_MODE_INPUT_TRISTATE. And maybe the SS pin too.

Thanks.
0 Likes