8 years, 4 months ago.

SPI strange issues

Hello and thanks for your help.

I have finished programming my Nucleo with SPI (using the SPI2 module). Basically I have another microprocessor that acts like a mirror slave. It transmits back everything it receives. The Nucleo is connected to a text LCD which shows what the master sends and what it receives from the slave.

Everything works fine. Of course there is a delay of 1, meaning that for example when I send one by one "Adapt LAB", when I send the "A" I receive garbage, and I receive that "A" (or I should!) when I transmit the "d". That is what in theory it should happen.

Well, it does happen like this with all character except the first one! When I send the first one and receive garbage, then I send the second one and again receive a weird character. After that everything works like wonders. but that first mistake is bugging me. Can anyone help me with what is going on here??

- By the way, I solved the above problem by first sending a 0x00, before starting sending anything, (by the way I tried the clear_transfer_buffer method as indicated in the documentation but >>it does not exist<< (at least that is what mbed said- as well as abort_transfer)

Is this how it should be done in mbed? or with Nucleo?? (I have programmed SPI in other architectures and this was not necessary)

I leave here my code if anyone wants to see it. (you can see that I repeat the same thing twice- it was done just to see that it fails the first time but works ok the second time)

#include "mbed.h"
 
 
#define MASK (0xFF) // Pins 0,1,4,5,6,7
PortOut lcd_port(PortA,MASK);   // For data we are going to use only PA_4 to PA_7

DigitalOut LCD_ENout(PA_0);      //Enable
DigitalOut LCD_RSout(PA_1);      // RS

#define lcdLINE1 0x00
#define lcdLINE2 0x40

SPI device(PB_15, PB_14, PB_13);
DigitalOut CS(PB_12);

void strobeLCD(void){
  LCD_ENout=1;
  wait_us(2);// 2 us  // is there a way to delay micro seconds???
  LCD_ENout=0;  
}

void writeLCD(unsigned char dat){
  lcd_port = lcd_port & 0x0F; //clear the bits 4 to 7
  lcd_port = lcd_port | (dat & 0xF0); //combine with upper nibble leave lower the same
  strobeLCD();
  
  wait_us(1);
  
  lcd_port = lcd_port & 0x0f; //clear upper bits
  lcd_port = lcd_port | ((dat<<4)&(0xF0)); //combine with lower nibbles leave lowe the same
  strobeLCD();
  wait_ms(2);  
}
void lcd_cmd(unsigned char cmd){
LCD_RSout=0;  //select command   
 wait_us(1);
 writeLCD(cmd);       
}
void lcd_data(unsigned char dat){
 LCD_RSout=1;   //select data
 wait_us(1);
 writeLCD(dat);   
}
void lcd_init(void){
    lcd_port =lcd_port &0x0F;  //clear upper bits
    lcd_port = lcd_port |0x30;  // directr data to LCD 7-4
    LCD_RSout=0;
    strobeLCD();
    wait_ms(10);
    strobeLCD();
    wait_ms(10);
    strobeLCD();
    wait_ms(10);
    
    lcd_port =lcd_port &0x0F;  //clear upper bits
    lcd_port =lcd_port |0x20;  // directr data to LCD 7-4
    strobeLCD();
    wait_ms(10);
   
    lcd_cmd(0x28); //Function set 4-bit mode 2 line 5x7 font
    lcd_cmd(0x0E); //Display ON cursor ON blink OFF
    lcd_cmd(0x06); // automatic increament no display shift
    lcd_cmd(0x80); //Address DDRAM with 0 offset 80h
    
}

void lcd_WriteStr(const unsigned char *c){
  while(*c!='\0'){
       lcd_data(*c);
       c++;
      }  
}
void lcd_SetCursor(unsigned char loc){
 lcd_cmd(loc|0x80); //send "set DDRAM address cmd   
}
void lcd_LINE1(void){
    lcd_SetCursor(lcdLINE1);
} 
void lcd_LINE2(void){
    lcd_SetCursor(lcdLINE2);
}
void lcd_clear(void){
    lcd_cmd(0x01);
} 

int main(){
  unsigned char spi_read_data;
  unsigned char data3[]="Adapt LAB";
  
  wait(0.3);
  lcd_init();
  lcd_clear();
  
  lcd_LINE1();
  lcd_WriteStr("Salvor HardinSMT");
  lcd_LINE2();
  lcd_WriteStr("Demo SPI");
  wait(2);
  
    device.format(8,1);  //change mode
    
//    device.clear_transfer_buffer();
  //  device. clear_transfer_buffer();
   //  device.abort_transfer();
    CS=0;
    device.write(0x00);
    CS=1;
 //   device.write(0x00);
    
   lcd_clear();
   lcd_LINE1();
   lcd_WriteStr("M: ");
   lcd_LINE2();
   lcd_WriteStr("S: ");

   lcd_SetCursor(lcdLINE1+3);
   lcd_WriteStr(data3);

  unsigned int i=0,b=3;
  
  
  // device.write(data3[0]);
  // device.write(data3[1]);
  
  
  
   while ( data3 [i] != '\0' )
   {
     // here write and read SPI
      CS=0;
     spi_read_data= device.write(data3[i]);
      CS=1; 
      if(i!=0) //skip garbage
       {
         lcd_SetCursor(lcdLINE2+b);
         lcd_data(spi_read_data);
         b++;
       }
     i++;

   }// while

  //last one
  // here read and write SPI  
   CS=0;
   spi_read_data= device.write(0x00);   
   CS=1; 
   lcd_SetCursor(lcdLINE2+b);
   lcd_data(spi_read_data);

  wait(2);

 lcd_clear();
   lcd_LINE1();
   lcd_WriteStr("M: ");
   lcd_LINE2();
   lcd_WriteStr("S: ");

   lcd_SetCursor(lcdLINE1+3);
   lcd_WriteStr(data3);

   i=0;b=3;
  
   while ( data3 [i] != '\0' )
   {
     // here write and read SPI
      CS=0;
     spi_read_data= device.write(data3[i]);
      CS=1; 
      if(i!=0) //skip garbage
       {
         lcd_SetCursor(lcdLINE2+b);
         lcd_data(spi_read_data);
         b++;
       }
     i++;

   }// while

  //last one
  // here read and write SPI  
   CS=0;
   spi_read_data= device.write(0x00);   
   CS=1; 
   lcd_SetCursor(lcdLINE2+b);
   lcd_data(spi_read_data);



  
  while(1);  
    
 } 
 
Be the first to answer this question.