Skip to main content
WM_IR
Associate III
May 10, 2021
Question

WHY MISO ECHO BACK WHAT MOSI SENT, EVEN THE MISO PIN IS ALREADY DISABLED.

  • May 10, 2021
  • 5 replies
  • 4902 views

I make a code that is just send SPI data, and the MISO should not return anything. Here is my code:

int main(void)

{

char user_data[] = "Hello World!";

GPIO_ButtonInit();

SPI2_GPIOInits();

SPI2_Inits();

SPI_SSOEConfig(SPI2,ENABLE);

  while(1)

  {

while(GPIO_ReadFromInputPin(GPIOC,GPIO_PIN_NO_13));

delay();

SPI_PeripheralControl(SPI2,ENABLE);

uint8_t dataLen = strlen(user_data);

SPI_SendData(SPI2,&dataLen,1);

SPI_SendData(SPI2,(uint8_t*)user_data,strlen(user_data));

while(SPI_GetFlagStatus(SPI2,SPI_BUSY_FLAG));

SPI_PeripheralControl(SPI2,DISABLE);

  }

return 0;

}

So, there should be no any SPI receivedata from MISO, but when I look the data at the logic analyzer, the MISO sent back the data from MOSI. It is like echoing, Or Is it because of the SPI nature?

this code I sent "Hello world!" the string length is 12.

First, I send the length of the string to the slave, Then, I send the Hello world! sentence to the slave.

the thing is, every data transmit from the MOSI, there will be a data sent back from MISO which is the sentence of the Hello world!

example in my picture, when I send the length 12, the MISO will exchange the " ! ". which is the last letter of hello world!

Then, when letter H is being sent, the MISO will reply back the length of the string data which is sent previously. Why is this happening? anyone can help me?

0693W00000ANsncQAD.png

This topic has been closed for replies.

5 replies

Javier1
Principal
May 10, 2021

CAN YOU TELL US WHAT HARDWARE ARE YOU USING?

MAYBE A NUCLEO BOARD?

hit me up in https://www.linkedin.com/in/javiermuñoz/
WM_IR
WM_IRAuthor
Associate III
May 10, 2021

Yes, Im using nucleo board stm32F302R8 as my master, and slave is arduino UNO

Javier1
Principal
May 10, 2021

i love your oscilloscope, you have any analog channels available?

you should measure analog AND digital MISO and MOSI at the same time, maybe you see some noise false triggering your gpios----

hit me up in https://www.linkedin.com/in/javiermuñoz/
waclawek.jan
Super User
May 10, 2021

> slave is arduino UNO

MISO means Master-In-Slave-Out, so it's the slave (i.e. the Arduino) which drives the MISO line, not the STM32.

JW

TDK
Super User
May 10, 2021

> the MISO should not return anything.

"nothing" is not an option. It's a digital line, it can be either 0 or 1. But whatever it's doing is defined by the Arduino code and not the STM32.

"If you feel a post has answered your question, please click ""Accept as Solution""."
WM_IR
WM_IRAuthor
Associate III
May 10, 2021

Actually, im following stm32 course from udemy, so the arduino code is provided from the instructor. Here is my arduino code, in the void loop, the slave will receive the data at the line:

 for(i = 0 ; i < dataLen ; i++ )

 {

  dataBuff[i] = SPI_SlaveReceive();

 }

So, inside of the SPI_SlaveReceive() function is:

uint8_t SPI_SlaveReceive(void)

{

 /* Wait for reception complete */

 while(!(SPSR & (1<<SPIF)));

 /* Return Data Register */

 return SPDR;

}

so in the code, return SPDR only store in dataBuff[i] array. It did not transmit any data from the slave. Below, I attached the full arduino code:

#include <SPI.h>

#include<stdint.h>

#define SPI_SCK 13

#define SPI_MISO 12

#define SPI_MOSI 11

#define SPI_SS 10

char dataBuff[500];

//Initialize SPI slave.

void SPI_SlaveInit(void) 

 #if 0 

 // Initialize SPI pins.

 pinMode(SPI_SCK, INPUT);

 pinMode(SPI_MOSI, INPUT);

 pinMode(SPI_MISO, OUTPUT);

 pinMode(SPI_SS, INPUT);

  

 // Enable SPI as slave.

 SPCR = (1 << SPE);

 #endif 

 

  // Initialize SPI pins.

 pinMode(SCK, INPUT);

 pinMode(MOSI, INPUT);

 pinMode(MISO, OUTPUT);

 pinMode(SS, INPUT);

 //make SPI as slave

  

 // Enable SPI as slave.

 SPCR = (1 << SPE);

}

//This function returns SPDR Contents 

uint8_t SPI_SlaveReceive(void)

{

 /* Wait for reception complete */

 while(!(SPSR & (1<<SPIF)));

 /* Return Data Register */

 return SPDR;

}

//sends one byte of data 

void SPI_SlaveTransmit(char data)

{

 /* Start transmission */

 SPDR = data;

  

 /* Wait for transmission complete */

 while(!(SPSR & (1<<SPIF)));

}

  

// The setup() function runs right after reset.

void setup() 

{

 // Initialize serial communication 

 Serial.begin(9600);

  

 // Initialize SPI Slave.

 SPI_SlaveInit();

  

 Serial.println("Slave Initialized");

}

 uint16_t dataLen = 0;

 uint32_t i = 0;

  

// The loop function runs continuously after setup().

void loop() 

{

 Serial.println("Slave waiting for ss to go low");

 while(digitalRead(SS) );

 i = 0;

 dataLen = SPI_SlaveReceive();

 for(i = 0 ; i < dataLen ; i++ )

 {

  dataBuff[i] = SPI_SlaveReceive();

 }

 dataBuff[i] = '\0';

  

 Serial.println("Rcvd:");

 Serial.println(dataBuff);

 Serial.print("Length:");

 Serial.println(dataLen);

  

}

OR IS IT MY SPI_SendData() function is wrong?

void SPI_SendData(SPI_RegDef_t *pSPIx, uint8_t *pTxBuffer, uint32_t Len)

{   

  while(Len > 0)

  {

  

   while(SPI_GetFlagStatus(pSPIx, SPI_TXE_FLAG) == FLAG_RESET);

   if(pSPIx->CR1 & (1 << SPI_CR1_CRCL))

   {

   //16 bit data frame format

   //1. Load the data into Data Register(DR)

   pSPIx->DR = *((uint16_t*)pTxBuffer);

   Len--;

   Len--;

   (uint16_t*)pTxBuffer++;

   }

   else

   {

   //8 bit data frame format

   //1. Load the data into Data Register(DR)

   *((volatile uint8_t *)&pSPIx->DR) = *pTxBuffer;

  

   Len--;

   pTxBuffer++;

   }

  }

}

  

  

waclawek.jan
Super User
May 11, 2021

In AVR (ATMega8 or whichever you have in the Arduino), SPI is a true 8-bit shift register, so if it is set to slave, with no writing to it, this is exactly how it behaves, i.e. MISO copies MOSI with an 8-bit delay. Read the AVR datasheet SPI chapter.

JW

WM_IR
WM_IRAuthor
Associate III
May 12, 2021

So, does the copied data from MISO is stored into my master Data register? If yes, do I need to clear it with dummy read in master?