DAVE 4 - SPI Example does not work

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

cross mob
Not applicable
Hello,

at the moment I'm trying to implement the SPI app in my project. In the final state I need 3 Slaves. For this I'm experimenting with the Dave4 SPI example "Usage1" you find in the APP documentation.I have a XMC 4500 Board and tried to follow the example with one slave step by step, configuerd the app and copied the code.
In the Manual Pin Allocator I used other pins than in the example code. In my case:

Master - Slave:
MOSI: 0.0 - 1.2
MISO: 0.1 - 1.3
SCLKOUT: 0.10 - 0.5
SS: 0.9 - 0.3

For this I just altered the #defines for SPI_SLAVE_0_MOSI_Pin .. etc. and connected the master and slave pins on the board directly to each other. But it simply doesn't work. Shouldn't the arrays master_rec_data, slave_send_data and slave_rec_data have the same values as master_send_data ,after reaching the infinite while loop? In my case they stay 0 (except master_send_data).

In debug mode it also never activates/ reaches the ISR handlers for rx and tx.
1.) Is this the problem? Do I need also two interrupt apps?
2.) And why are you using IRQ_Hdlr_13 and IRQ_Hdlr_9? In the XMC4500 I see they are not definded, but IRQ_Hdlr_14 for SPI_SLAVE_0_protocol_handler already has the definition VADC0_C0_0_IRQHandler.
3.) And what does SPI_SLAVE_DX1C/DX0C/DX2B mean?
3.) When I need three slaves, do I simply have to define new SPI_SLAVE_1_MOSI_PIn etc.? (I guess the pins will stay the same except for SlaveSelect)


I hope you can help me. I'm very new in programming SPI.
Tanks a lot!
0 Likes
3 Replies
Not applicable
Hi,

1) No, no INTERRUPT APPs needed. Interrupt is configured in Slave code using LLD.
2) IRQ_Hdlr_9/13/14 are the USIC interrupt service request numbers for XMC1000. You need to change for XMC4500.
3) SPI_SLAVE_DX1C/DX0C/DX2B are Slave Transmit/Clock/Select inputs (refer to Figure 17-35 of "xmc4500_rm_v1.5_2014_07".
4) You need to define 3 sets of slave channels.

Best regards,
Sophia
0 Likes
Not applicable
First of all:
Thank you for the tips!

Today I tried to do it like you said. But it still doesn't work. Interrupts work, but just for one time I guess, and the code gets stuck in SPI_SLAVE_0_tx_handler -> XMC_SPI_CH_Transmit - > XMC_USIC_CH_GetTransmitBufferStatus. When i pause debugger, it's always trying to get the BufferStatus in an endless loop..
slave_rec_data[0] contains the value 128. The rest is 0. But even 128 is wrong. It should be 0x55..

I changed so far the following:
1.)
MASTER - SLAVE:
MOSI: P0_1 - P0_4
MISO: P0_0 - P0_5
SCLKOUT: P0_10 - P0_11
SLAVE SELECT: P0_9 - P0_6

2.) Defining and replacing:

#define SPI_SLAVE_0_tx_handler IRQ_Hdlr_93
#define SPI_SLAVE_0_rx_handler IRQ_Hdlr_94
#define SPI_SLAVE_0_protocol_handler IRQ_Hdlr_95
#define SPI_SLAVE_0_Channel XMC_SPI1_CH0 // cause MASTER is XMC_SPI1_CH1

SPI_SLAVE_DX1A 0U
SPI_SLAVE_DX0A 0U
SPI_SLAVE_DX2A 0U

3.) changing SLAVE_MISO to be hardware controlled (from XMC4500 - Table 25-12)

/* Port configuration for slave */ //
SPI_MASTER_GPIO_CONFIG_t SPI_SLAVE_0_MISO_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_INPUT_TRISTATE,
},
.hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1
};

4.) // adjusting SPI_MASTER_SR_ID_X

XMC_USIC_CH_SetInterruptNodePointer(SPI_SLAVE_0_Channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_TRANSMIT_BUFFER,
(uint32_t)SPI_MASTER_SR_ID_3);
XMC_USIC_CH_SetInterruptNodePointer(SPI_SLAVE_0_Channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_RECEIVE,
(uint32_t)SPI_MASTER_SR_ID_4);
XMC_USIC_CH_SetInterruptNodePointer(SPI_SLAVE_0_Channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_ALTERNATE_RECEIVE,
(uint32_t)SPI_MASTER_SR_ID_4);
XMC_USIC_CH_SetInterruptNodePointer(SPI_SLAVE_0_Channel,
XMC_USIC_CH_INTERRUPT_NODE_POINTER_PROTOCOL,
(uint32_t)SPI_MASTER_SR_ID_5);

and

NVIC_SetPriority((IRQn_Type)93, 3U);
NVIC_SetPriority((IRQn_Type)94, 3U);
NVIC_SetPriority((IRQn_Type)95, 3U);

NVIC_EnableIRQ((IRQn_Type)93);
NVIC_EnableIRQ((IRQn_Type)94);
NVIC_EnableIRQ((IRQn_Type)95);

The rest of the code stayed the same.
Can you see a problem? What do I have to do next? I can't find any problem to solve.. But it's still not working..



EDIT:
Actually now it's half working I think..
I didn't change anything, but now, slave slave_rec_data[BUFFER_SIZE] gets data. But just when I set the last parameter count of SPI_MASTER_Receive to zero. Problem is: the programm stays in while(SPI_MASTER_0.dynamic_config->rx_busy) forever...

When count is1 or higher, it starts to overwrite the results of slave_rec_data with 255. So, when both count from SPI_MASTER_Transmit and _recieve are set to 8, slave_rec_data gets full with 255 and even master_rec has 5 values with 255...

.. I don't understand 😞
0 Likes
Not applicable
Hi,

The following configuration in 3) is wrong:
.hw_control = XMC_GPIO_HWCTRL_PERIPHERAL1

Hw_control is intended to be used for QuadSPI and DUALSPI only, never for normal modes of SPI (refer to 17.11.3.1 Channel Control Register of "xmc4500_rm_v1.5_2014_07").
Note: The hardware port control feature is useful only
for SSC protocols in half-duplex configurations,
such as dual- and quad-SSC. For all other
protocols HPCEN must always be written with
00B.


Below is for your reference:
/* Port configuration for slave */
SPI_MASTER_GPIO_CONFIG_t SPI_SLAVE_0_MISO_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_OUTPUT_PUSH_PULL_ALT2,
.output_level = XMC_GPIO_OUTPUT_LEVEL_HIGH
},
.hw_control = XMC_GPIO_HWCTRL_DISABLED
};

SPI_MASTER_GPIO_CONFIG_t SPI_SLAVE_0_MOSI_Config =
{
.port_config =
{
.mode = XMC_GPIO_MODE_INPUT_TRISTATE,
},
};


Best regards,
Sophia
0 Likes