2015-03-26 02:17 AM
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, Patrik2015-03-27 02:36 AM
dspi
->MCR
.B
.MSTR
= 0
and update spi_config_high_speed (like below)CTAR_0 should be set : (Cf below Reference Manual)==================Field DescriptionsSLAVE_FMSZSlave 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_CPOLClock Polarity. The CPOL bit selects the inactive state of the Serial Communications Clock (SCK).0 The inactive state value of SCK is low1 The inactive state value of SCK is highSLAVE_CPHAClock Phase. The CPHA bit selects which edge of SCK causes data to change and which edgecauses data to be captured.0 Data is captured on the leading edge of SCK and changed on the following edge1 Data is changed on the leading edge of SCK and captured on the following edgeSLAVE_PEParity Enable. PE bit enables parity bit transmission and reception for the frame0 No parity bit included/checked.1 Parity bit is transmitted instead of last data bit in frame, parity checked for received frame.SLAVE_PPParity Polarity. PP bit controls polarity of the parity bit transmitted and checked0 Even Parity: number of “1� bits in the transmitted frame is even. The DSPI_SR[SPEF] bit is set if inthe 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 inthe 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 Erwan2015-03-29 11:14 PM
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
2015-03-30 03:36 AM
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
2015-03-31 01:02 AM
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 Erwan2015-03-31 07:04 AM
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=false2015-04-01 09:13 AM
Hello Patrik,
According to the slave configuration , (Leopard)FrameSize is 11 Bits (0xA + 1)CPOL/CPHA is equals to 0Did you configure the Master Configuration (Bolero) to the same configurationCPOL/CPHA 0 and FrameSize 11 BitsTomorrow , we will try to build a practical work on this subject. Best regards Erwan2015-04-02 03:29 AM
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, Patrik2015-04-29 08:59 AM
Hello Patrik ,
Master & slave should have the same configuration.did you try 8x11bits for master & Slave ? Best regards Erwan2015-05-07 01:34 AM
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