cancel
Showing results for 
Search instead for 
Did you mean: 

[solved] SPI slave configuration for SPC56EL

Patriks
Senior
Posted on March 26, 2015 at 10:17

Hello,

I would like to implement a SPI communication between an SPC560D and an SPC56EL Discovery Board. The SPC56EL should act as slave, the SPC560D as master. For both boards, I am using the corresponding DSPI example applications in SPC5Studio.

Nevertheless, I am not able to get a communication between the two boards.

The master sends every 20ms seven 12bit SPI frames to the slave. It was no problem to adapt the DSPI example for SPC560D to get this functionality.

The problem is the slave (SPC56EL) configuration. I set the device in slave mode by adding the line

spip->

dspi

->

MCR

.

B

.

MSTR

= 0

in the spi_lld_start function (spi_lld.c) and adapted the frame size in CTAR0 register. Additionally, DMA is set to RX only. After that, the SOUT pin from slave is set to high when master sets the CS to low. Nevertheless, the SPC56EL neither receives any data (DSPI_RXFR registers are empty) or sends data back to the master device

What would be the correct configuration steps to use the SPC56EL in slave mode?

Best regards,

Patrik 

9 REPLIES 9
Erwan YVIN
ST Employee
Posted on March 27, 2015 at 10:36

Hello Patrik ,

if you want to put EL Discovery board in Slave

yes ,  you have well to set your DSPI Settings in spip->

dspi

->

MCR

.

B

.

MSTR

 = 0

and update spi_config_high_speed (like below)

CTAR_0 should be set : (Cf below Reference Manual)

==================

Field Descriptions

SLAVE_FMSZ

Slave frame size. The number of bits transferred per frame is equal SLAVE_FMSZ field value plus 1.

Minimum valid SLAVE_FMSZ field value is 3.

SLAVE_CPOL

Clock Polarity. The CPOL bit selects the inactive state of the Serial Communications Clock (SCK).

0 The inactive state value of SCK is low

1 The inactive state value of SCK is high

SLAVE_CPHA

Clock Phase. The CPHA bit selects which edge of SCK causes data to change and which edge

causes data to be captured.

0 Data is captured on the leading edge of SCK and changed on the following edge

1 Data is changed on the leading edge of SCK and captured on the following edge

SLAVE_PE

Parity Enable. PE bit enables parity bit transmission and reception for the frame

0 No parity bit included/checked.

1 Parity bit is transmitted instead of last data bit in frame, parity checked for received frame.

SLAVE_PP

Parity Polarity. PP bit controls polarity of the parity bit transmitted and checked

0 Even Parity: number of “1� bits in the transmitted frame is even. The DSPI_SR[SPEF] bit is set if in

the received frame number of “1� bits is odd.

1 Odd Parity: number of “1� bits in the transmitted frame is odd. The DSPI_SR[SPEF] bit is set if in

the received frame number of “1� bits is even.

On chapter 17.4 , they have some useful informations  on EL Reference Manual.

The clock is given by the MASTER.

I am checking with DSPI experts.

               Best regards

                            Erwan

Patriks
Senior
Posted on March 30, 2015 at 08:14

Hello Erwan,

Thanks for your explanations. Changingthespi_config_high_speed leads to the same behavior. I tried to use both DMA and interrupt configuration for RX, but see no effect. I expected, that after slave configuration an interrupt or DMA event should be triggered when data is send from master. But it didn´t. Finally, I was able to configure SPC56EL to run as SPI slave after I found a detailed configuration example in a freescale application note.

/* INIT DSPI2 */ 
DSPI_1.MCR.R = 0x00010001; /* Configure DSPI_B as slave */ 
DSPI_1.CTAR[0].R = 0x78000000; /* Configure CTAR0 */ 
DSPI_1.CTAR[0].B.FMSZ = 0xA; 
DSPI_1.RSER.B.RFDF_RE = 1; 
DSPI_1.MCR.B.HALT = 0x0; /* Exit HALT mode: go from STOPPED to RUNNING state*/ 

This configuration basically works, but now I have problems loosing SPI Frames. The SPI master sends totally 88 bits to the slave (5x16bit + 1x8bit). I configured the salve as shown above to receive 11bit frames (to have eight frames with same length). After each received 11bit frame, an interrupt event is triggered towrite the data into an uint16 array until the FIFO is empty. This is the interrupt handler:

OSAL_IRQ_HANDLER(SPC5_DSPI1_RFDF_HANDLER) { 
OSAL_IRQ_PROLOGUE(); 
DSPI_1.SR.R = 0x80020000; /* Clear TCF, RDRF flags by writing 1 to them */ 
static uint8_t i=0; 
static uint8_t m=0; 
//spi_serve_dspi_rfdf(&SPID1); 
while(DSPI_1.SR.B.RXCTR > 0) 
{ 
FIFOcounter[m] = DSPI_1.SR.B.RXCTR; 
m++; 
if(m>79){ 
m=0; 
} 
RecDataSlave[i] = DSPI_1.POPR.R; /* Read data received by slave SPI */ 
i++; 
} 
if(i > 79) 
{ 
i=0; 
} 
OSAL_IRQ_EPILOGUE(); 
}

It seems to me (only a suggestion), that the slave is sometimes not fast enough to read data from the RX FIFO. But even when I send the data really slow (around 20kHz), the salve is loosing data. Is there a way to use the givenSPI Driver functionality when the device runs as slave? Best regards, Patrik
Patriks
Senior
Posted on March 30, 2015 at 12:36

Hello,

Finally, I solved my issue. The main problem was, that I didn´t understand how to use the SPI driver functions in spi.c. I thought all driver function are only to use in master configurations. After I understand that they are independent from master/slave config, all I had to do was adapting the spi_config structure and adding one line in the spiStart() function to setSPI slave mode. Here is my final test code:

/* Starting driver for test, DSPI_0 I/O pins setup.*/ 
SIU.PCR[6].R = PAL_MODE_OUTPUT_ALTERNATE(1); /* SCK */ 
SIU.PCR[7].R = PAL_MODE_OUTPUT_ALTERNATE(1); /* SOUT */ 
SIU.PCR[5].R = PAL_MODE_OUTPUT_ALTERNATE(1); /* CS[0] */ 
SIU.PCR[8].R = PAL_MODE_INPUT; /* SIN */ 
spiStart(&SPID2, &spi_config_low_speed_slave); /* Setup parameters. */ 
uint16_t k = 0; 
uint16_t l = 0; 
uint16_t m = 8; 
/* Application main loop, two SPI configuration are used alternating them.*/ 
while (1) { 
if((DSPI_1.SR.B.TXRXS == 0) || (k == 0)) 
{ 
spiStartExchange(&SPID2,8,&RecDataSlave[m],&RecDataSlave[l]); 
l+=8; 
m+=8; 
if(l >= 15) 
{ 
l=0; 
} 
if(m >= 15) 
{ 
m=0; 
} 
} 
k=1; 
}

Best regards, Patrik
Erwan YVIN
ST Employee
Posted on March 31, 2015 at 10:02

Good news , your are becoming a SPI Expert 😉

Do not forget that all the differences between original HAL Files and your patched file are in the file ''patch.xml''.

Do not remove it 😉

       Best Regards

             Erwan

Patriks
Senior
Posted on March 31, 2015 at 16:04

Hello Erwan,

Thanks, but it seems that it is not so easy to become an SPI expert 😉

I investigated an unexpected behavior with another master device and faster SPI transmission (please see attached oscilloscope picture).

The SPI master sends data to the slave device (SPC56EL discovery board) with around 4MHz. The yellow line (MISO) shows the data send back from SPI slave to master device. For testing purpose, the slave ignores the received data and just sends back 8x11bits. Therefore, I used the spiStartSend function from SPI driver and changed the code in main.c as followed:

uint8_t endLoop = 0; 
uint16_t RecDataSlave[20]; 
uint16_t dummyData[20]; 
/* 
* Application entry point. 
*/
int
main(
void
) { 
unsigned i; 
for
(endLoop = 0; endLoop < 20; endLoop++) 
{ 
RecDataSlave[endLoop] = 0; 
dummyData[endLoop] = 0, 
} 
/* Initialization of all the imported components in the order specified in 
the application wizard. The function is generated automatically.*/
componentsInit(); 
/* Starting driver for test, DSPI_0 I/O pins setup.*/
spiStart(&SPID1, &spi_config_high_speed); 
SIU.PCR[6].R = PAL_MODE_OUTPUT_ALTERNATE(1); 
/* SCK */
SIU.PCR[7].R = PAL_MODE_OUTPUT_ALTERNATE(1); 
/* SOUT */
SIU.PCR[5].R = PAL_MODE_OUTPUT_ALTERNATE(1); 
/* CS[0] */
SIU.PCR[8].R = PAL_MODE_INPUT; 
/* SIN */
spiStart(&SPID2, &spi_config_low_speed_slave); 
/* Setup parameters. */
uint16_t k = 0; 
uint16_t l = 0; 
uint16_t m = 8; 
/* Application main loop, two SPI configuration are used alternating them.*/
while
(1) { 
if
((DSPI_1.SR.B.TXRXS == 0) || (k == 0)){ 
spiStartSend(&SPID2,8,&dummyData[0]); 
k++; 
l+=8; 
m+=8; 
if
(l >= 15) 
{ 
l=0; 
} 
if
(m >= 15) 
{ 
m=0; 
} 
} 

For my understanding, the controller should now ignore the received data and send the first eight elements of array dummyData back to the master. As all array elements are 0, the slave should send 88bits with value 0. But when you look at the attached picture, the slave sometimes returns at least one bit with the value 1.

I saw the same effect when I fill the data array with valid values. Then the slave sends completely wrong values back to the master.

Do you have an explanation for that behavior? Is there something I forgot to do?

Best regards,

Patrik

________________

Attachments :

Ansteuerung_0x0000.png : https://st--c.eu10.content.force.com/sfc/dist/version/download/?oid=00Db0000000YtG6&ids=0680X000006I0SR&d=%2Fa%2F0X0000000bZ9%2FCURCdRVAnUphgIZJhNaZDMKfhJK20Bh0EYTIUCFqkKA&asPdf=false
Erwan YVIN
ST Employee
Posted on April 01, 2015 at 18:13

Hello Patrik,

According to the slave configuration , (Leopard)

FrameSize is 11 Bits (0xA + 1)

CPOL/CPHA is equals to 0

Did you configure the Master Configuration (Bolero) to the same configuration

CPOL/CPHA 0 and FrameSize 11 Bits

Tomorrow , we will try to build a practical work on this subject.

              Best regards

                             Erwan

Patriks
Senior
Posted on April 02, 2015 at 12:29

Hello Erwan,

Yes, they use both the same configuration.

One additional question to the frame length FMSZ:

For example if the master send 5x16bits and 1x8bits (totally 88bits for one transfer). Would the transmission also work if the slave is configured to receive 8x11bits?

Best regards,

Patrik

Erwan YVIN
ST Employee
Posted on April 29, 2015 at 17:59

Hello Patrik ,

Master & slave should have the same configuration.

did you try 8x11bits for master & Slave ?

   Best regards

                        Erwan

Patriks
Senior
Posted on May 07, 2015 at 10:34

Hello Erwan,

The master sends 88bits (5x16bit + 1x8bit) within one SPI frame. I configured the slave to receive 11x8bits. But this wasn´t a problem. 

My problems with SPI communications were more or less timing issues. Finally I solved them by using DMA for RX and TX. Additionally, it seems to me that the SPC5 Studio SPI driver is not optimized for high data rates and continuously data stream over SPI. In the end, I only used the driver function for initialization. For communication control, I directly wrote the registers.

Best regards,

Patrik