4 years, 10 months ago.

SPI Slave sending wrong Data

Hi, I am trying to connect two STM32F7 with Mbed OS over SPI to benchmark the communication. The MOSI communication is working without problems. The slave also sends some right messages, but after sometime it sends a wrong byte and then the error is continuing. My main question is why the slave shifts the bytes wrong into the buffer? I think the error continuing is because of the FIFO buffer. Here is my Slave Code:

slave.cpp

#include "mbed.h"

SPISlave slave(PB_5, PB_4, PB_3, PA_4); // mosi, miso, sclk, ssel

DigitalOut GpioEn(PA_7,1); 
DigitalIn TestStart(PA_6);



void clearBuf(char *buffer,int size){
    for(int i=0;i<size;i++) buffer[i]=1;
    }
unsigned int compare(char *buffer, char *buffer2,int size){
     for(int i=0;i<size;i++) {
             if(buffer[i]!=buffer2[i]) {
                 return 1;
                 }
             }
             return 0;
    }
void printbuf(char *buffer, int size){
    for(int i=0;i<size;i++) printf("%c",buffer[i]);
    printf("\r\n"); 
    }
/////////////////////////////
////////PROGRAMMSTART////////
/////////////////////////////

int main() 
{
     //  COUNTER VARS  //
     
    unsigned int ErrCount = 0;
    unsigned int mosi = 0;
    /////////\\\\\\\\\\\\
    //BUFFER INITS START//
    volatile char sendBuf[]="Slave!";
    char recBuf[7]={'0'};
    char cmp[]="Master";
    //BUFFER INITS END//
    
    //SPI INIT START//
    slave.frequency(1000);//max 54000000
    slave.format(8,0);
    //SPI INIT END//
    wait(1);    
    slave.reply('a');   
    while(TestStart.read()==0) ;
        while(TestStart.read()==1)
        {
            GpioEn=0;
            if(slave.receive()) 
            {
                GpioEn=1;
                for(int i=0;i<6;i++) 
                {
                    slave.reply(sendBuf[i]);
                    recBuf[i] = slave.read(); 
                }  
                mosi++;
                ErrCount+=compare(recBuf,cmp,6);
                printbuf(recBuf,6);
                clearBuf(recBuf,6);
            }
        }      
        printf("Slave: Messages received:%d Error:%d\r\n",mosi,ErrCount);    
    while(1);
}

And this is the master Code:

master.cpp

#include "mbed.h"

#define DURATION 5
Timer t;

SPI master(PB_5, PB_4, PB_3); // mosi, miso, sclk, ssel
DigitalOut cs(PA_4);
DigitalIn GpioEn(PA_7);
DigitalOut TestStart(PA_6,0);


void senddata(char *buffer,int size)
{
for(int i=0;i<size;i++){
        master.write(buffer[i]);
        }
}

void send_rec_data(char *sendbuf,char *recbuf, int size)
{
for(int i=0;i<size;i++){
       recbuf[i]= master.write(sendbuf[i]);
        }
}



void clearBuf(char *buffer,int size){
    for(int i=0;i<size;i++) buffer[i]=1;
    }
unsigned int compare(char *buffer, char *buffer2,int size){
     for(int i=0;i<size;i++) {
             if(buffer[i]!=buffer2[i]) {
                 return 1;
                 }
             }
             return 0;
    }
void printbuf(char *buffer, int size){
    for(int i=0;i<size;i++) printf("%c",buffer[i]);
    printf("\r\n"); 
    }

int main() 
{
    char sendBuf[7]="Master";
    char recBuf[7]={'0'};
    char cmp [7]= "Slave!";
    unsigned int mosi =0;
    unsigned int error =0;
    master.format(8,0);
    master.frequency(1000);
    wait(2);
    master.write('a');
    cs=1;
    t.start();
    TestStart=1;
    while(t.read()<DURATION)
     {  
        if(GpioEn.read()==0)
        {
            cs=0;
            send_rec_data(sendBuf,recBuf,6);
            mosi++;
            cs=1;
            error+=compare(recBuf,cmp,6);
            printbuf(recBuf,6);
            clearBuf(recBuf,6);
        }  
    }
    t.stop();
    TestStart=0;
    printf("Master Data: Time: %f seconds Mesages Transmittet:%d Error:%d\r\n", t.read(),mosi,error);
    while(1);
}

The normal communication should be like this:

In the beginning it sends Master: Master Slave: Slave! After about 30-60 transmitted messages this error occurs: /media/uploads/lollo181/start_of_the_error.png

after this the the communication is Master: Master Slave: !Slave

How can i solve the error that the slave is sending the bytes in the wrong order? Thank u Adrian

2 Answers

4 years, 10 months ago.

You've set the slave frequency to 1000, should you not match this on your master?

Was just a copy paste error. In the code it is set to 1000 on both sides. But Thanks for the answer :)

posted by Adrian Leher 04 Jun 2019
4 years, 10 months ago.

I think you have a misunderstanding on how SPI slaves work.

Since the slave data is sent out while the master data is coming in you need to pre-load the reply.

When you say slave.reply('a') you aren't telling it to immediately sent a reply of 'a' to the byte just received. You are telling it that as the next byte is received it should send a reply of 'a'.

So with your current code 'S' should be sent as the 'a' arrives, 'l' at the same time as 's' etc...

Thanks for the tip. I have seen that some pictures didn't loaded into the Question. The error that is in the picture occurs after some messages and is not from the slave.reply('a"); i also updated it in the question.

posted by Adrian Leher 07 Jun 2019

The images were there, you just needed to remove the %20 from the end of the link address, urls don't normally end in a space.

posted by Andy A 07 Jun 2019