Why we need Read bit in SPI and what is a dummy byte ?

Thread Starter

Xenon02

Joined Feb 24, 2021
495
Hello !

I've been reading how SPI works and did some example

C:
uint8_t spi_tx_buff[10], spi_rx_buff[10];

  spi_tx_buff[0] = (0x01 << 7) | 0x0F;

  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_RESET);

  HAL_SPI_Transmit(&hspi1, spi_tx_buff, 1, 50);
  HAL_SPI_Receive(&hspi1, spi_rx_buff, 1, 50);

  HAL_GPIO_WritePin(GPIOE, GPIO_PIN_3, GPIO_PIN_SET);

  printf("Expected 11010100 (212 in decimal) : %d\n ", spi_rx_buff[0]);
First of all in tx_buff[0] I add one bit which is shifted to the left << 7. I know it is a Write bit, and I read from this address the data which is received in HAL_SPI_Receive.
The thing is why I don't use the Read bit anywhere but I use only Write bit?
Second thing is why in HAL_SPI_Receive why I don't send the address again with the Read bit ?
It's weird at most.

Second question was about dummy data. Which I don't understand. If the first byte is to send the address of the device then the second byte which is 0x00 a dummy data doesn't overwrite the register I was pointing to in the first byte ?
Is it also present in my code ?

I've read about dummy data while trying to find answer about this Read bit.
 

Ian0

Joined Aug 7, 2020
9,502
There's no such thing as a "read" or "write" bit in SPI. There may be certain SPI peripherals that need such things.
Read and Write bits belong to I2C.

Whenever you write a byte to SPI, a byte is simultaneously transferred the other way.
If the byte you write initiates some transaction, then the byte you read will be a dummy byte, because the byte you receive will have been loaded into the peripheral's transmitting register before the peripheral had chance to see the command you sent.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
There's no such thing as a "read" or "write" bit in SPI. There may be certain SPI peripherals that need such things.
Read and Write bits belong to I2C.
Oh good to know. I was reading the data sheet and I thought that Write/Read is universal in every SPI. Would make sense to me then.


Whenever you write a byte to SPI, a byte is simultaneously transferred the other way.
If the byte you write initiates some transaction, then the byte you read will be a dummy byte, because the byte you receive will have been loaded into the peripheral's transmitting register before the peripheral had chance to see the command you sent.
I don't quite understand it.
So in my example what I receive in HAL_SPI_Receive is the dummy byte ? Even though it sends the expected data ?
Or rather I send the data with HAL_SPI_Transmit and something is already going back to me even though I didn't call HAL_SPI_Receive ? How does it work and why it works like that ?
 

nsaspook

Joined Aug 27, 2009
12,795
HAL_SPI_Receive sends a 'dummy transmit byte from the master so it can clock in the data requested (if that's the device functionality that might take multi-byte commands before sending real data) from the HAL_SPI_Transmit command to the slave. You could have used HAL_SPI_TransmitReceive instead for both but making them separate functions clarifies code intent and handles the dummy business for you. You need to check the SPI client datasheet for the correct data exchange protocol as some slave devices send a status in the first byte(s).

https://community.st.com/t5/stm32-m...treceive-purpose-and-how-it-works/td-p/337551
 
Last edited:

Thread Starter

Xenon02

Joined Feb 24, 2021
495
HAL_SPI_Receive sends a 'dummy transmit byte from the master so it can clock in the data requested (if that's the device functionality) from the HAL_SPI_Transmit command to the slave. You could have used HAL_SPI_TransmitReceive instead for both but making them separate functions clarifies code intent and handles the dummy business for you.

https://community.st.com/t5/stm32-m...treceive-purpose-and-how-it-works/td-p/337551
So I understand that the dummy trasmit is in HAL_SPI_TransmitReceive ? That's what I understood from the link.
That If I have it separate like in my code I send one byte and receive one byte. But If I had HAL_SPI_TransmitReceive then when the data is sent then at the same time Receive is working, So while Transmision is sending the data the Receive already getting something but the data wasn't sent fully from the Transmision.
Am I somehow correct ? Why it works like that ? And how does it work for separate functions (I've read somewhere here that slave also sends data even before the Transmision is over, but maybe it is only in HAL_SPI_TransmitReceive) ?
 

Ian0

Joined Aug 7, 2020
9,502
Oh good to know. I was reading the data sheet and I thought that Write/Read is universal in every SPI. Would make sense to me then.
You don't need to tell it whether you are reading or writing, because you have separate connections for reading and writing.
 

Ian0

Joined Aug 7, 2020
9,502
So I understand that the dummy trasmit is in HAL_SPI_TransmitReceive ? That's what I understood from the link.
That If I have it separate like in my code I send one byte and receive one byte. But If I had HAL_SPI_TransmitReceive then when the data is sent then at the same time Receive is working, So while Transmision is sending the data the Receive already getting something but the data wasn't sent fully from the Transmision.
Am I somehow correct ? Why it works like that ? And how does it work for separate functions (I've read somewhere here that slave also sends data even before the Transmision is over, but maybe it is only in HAL_SPI_TransmitReceive) ?
You can't send a byte unless you receive one, and you can't receive a byte unless you send one.*

So, if you want to receive data but you have nothing to send, you must send a dummy byte (the driver will do it automatically)
Similarly, if you want to send data but the peripheral has nothing to send back, then you will receive a dummy byte.
Generally you will have to read the dummy byte from the data received register, because otherwise it might not be able to place any new bytes in the data-received register until the one that is in there has been read.

* In some hardware, you can switch off the receiver.
 

nsaspook

Joined Aug 27, 2009
12,795
So I understand that the dummy trasmit is in HAL_SPI_TransmitReceive ? That's what I understood from the link.
That If I have it separate like in my code I send one byte and receive one byte. But If I had HAL_SPI_TransmitReceive then when the data is sent then at the same time Receive is working, So while Transmision is sending the data the Receive already getting something but the data wasn't sent fully from the Transmision.
Am I somehow correct ? Why it works like that ? And how does it work for separate functions (I've read somewhere here that slave also sends data even before the Transmision is over, but maybe it is only in HAL_SPI_TransmitReceive) ?
The separate transmit and receive functions all use HAL_SPI_TransmitReceive internally as the actual transfer function because it's always a full exchange on the wire even if the slave is idle.

Purely using SPI, there is a need to sequence actions on the slave because what's in the slaves current receive buffer starts to send to the master before the mater transmit byte is completely received by the slave.

One way around this is to have the SPI slave send a interrupt or other signal to the master first letting the master know valid data is ready (ADC conversion complete, IMU position data complete, etc...) to be clocked out of the buffer on the first transaction after the interrupt or signal.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
You don't need to tell it whether you are reading or writing, because you have separate connections for reading and writing.
So why there is this Read and Write bit ? And how does it know I want to Read or Write (I mean the connection).


You can't send a byte unless you receive one, and you can't receive a byte unless you send one.*

So, if you want to receive data but you have nothing to send, you must send a dummy byte (the driver will do it automatically)
Similarly, if you want to send data but the peripheral has nothing to send back, then you will receive a dummy byte.
Generally you will have to read the dummy byte from the data received register, because otherwise it might not be able to place any new bytes in the data-received register until the one that is in there has been read.

* In some hardware, you can switch off the receiver.
If I want to send data I need to first set the addres I want to send or receive the data which is the address to the certain register. So Sending a dummy byte won't overwrite the address ? Hence change where I want to receive/send the data ?

So I understand that in HAL_SPI_Trasmit , HAL_SPI_Receive and in HAL_SPI_TrasmitReceive I always send/receive a dummy byte ? But in this separate it does it automatically and in HAL_SPI_TrasmitReceive it doesn't ?

I don't know how to imagine it how it works. I base my knowladge a bit from the diagram.

1698953079604.png
It is from a datasheet I3G4250D

Or this one :

1698953339493.png

I also found this one :

1698953349510.png

But it didn't make sense to me at the moment because then the register changes it's internal value from default to it's own address value and the address value in master is changed into what slave stored at the same time.



Is there any picture that most likely tells how SPI works ?
 

Ian0

Joined Aug 7, 2020
9,502
The read-write bit is an instruction to the device, it is specific to the device, and not generic to the SPI interface.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
Is the TS thinking of read/write bit in I2C?
Not really, I've sent the picture of a datasheet of an device that uses SPI.

I might something understood I guess.
Let's say I've 2 bytes to transmit. Let's say first byte is 01001111 and 00000011. The slave register has at the moment 00000000 so the the whole 1st byte is shifted from master (01001111) to the slave (00000000) and now the slave has (01001111) and the master has (00000000).

Now there are 2 senerios which one is correct ? :

1. The slave still has (01001111) and the master is overwriten from (00000000 to -> 00000011) and it transmits, and at the end slave has (00000011) and the master has (01001111) ?

2. The slave still is cleared (01001111 to -> 00000000) and the master is overwriten from (00000000 to -> 00000011) and it transmits, and at the end slave has (00000011) and the master has (00000000) ?

Same goes when I want to read the data ?

But first I need to send one byte and receive as much as I want ? Like first byte is transmited 01001111 and the received is 00110000 and 00000101.

So it goes similar to above but it depends on which scenerio it is.



The read-write bit is an instruction to the device, it is specific to the device, and not generic to the SPI interface.
I just understood that the slave register isn't the same as the device register. So the device reads from slave register what to do and sends the data it was requested also to the slave register to send it back or overwrited what is inside of the device register.
So that's why there is Read and Write bit.
 

MrChips

Joined Oct 2, 2009
30,488
Neither scenario is correct.

If the master is expecting data from the slave, then the master sends data and simultaneously receives data.
If the master is expecting a reply from the slave after the first transmission, then the master has to send one more time.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
Neither scenario is correct.

If the master is expecting data from the slave, then the master sends data and simultaneously receives data.
If the master is expecting a reply from the slave after the first transmission, then the master has to send one more time.
That's weird because that's how I interpreted this diagram :

1698956014143.png

I thought that the master wants to send 01001111 so the master has 01001111 and the slave maybe let's say has 00000000. So it is shifted and now master has 00000000 and slave has 01001111. Now next byte is sent from master to slave so either slave is cleared or passes it's old content to the master and master is just overwritten.

I don't see any other option here because it does what you said both it sends and receives the data from the slave (although it is an old data from slave).

So I thought scenerio nr.1 was more logical.

Or you can tell me from the numbers or examples I've given.


If the master is expecting data from the slave, then the master sends data and simultaneously receives data.
Ok so master expect data so first we need to transmit that we want to read from slave so let's say master sends 01010000 to the slave and slave had some random value or was just cleared (let's assume it was 00000000 it will be easier).

So now master has 01010000 and slave has 00000000 the transmission goes and master sent 01010000 and received at the moment 00000000. Now slave received 01010000 and the device reads it as a Info that master wants to read the register so it overwrites the Slave with new data (let's say 01100000) now slave from 01010000 becomes 01100000 it is sent to the master but master has to sent data as well so he sent old data he stored which was 00000000. At the end Slave again has 00000000 and Master has 01100000. At the end We received the data.

That's how I imagined it looking at the diagram.

Same goes if we want to overwrite the device register.

1. Master sends the device address (which will be 11000000) and Slave has lets say 00000011 (some random old info), So now Master has 00000011 and Slave has 11000000 it know it has to receive next data from Master so it doesn't overwrite the Slave.
2. Master sends another byte which is not the address but the new value (let's say 01001000) But slave still has 11000000, so at the end Master has 11000000 and Slave has 01001000. That's all. If we want to send more bytes to the same register the proces of nr.2 repeats.

I don't know if this is wrong then I don't know what is right ;)
 

MrChips

Joined Oct 2, 2009
30,488
Your diagram is correct.
After one transfer, data is exchanged between the master and the slave.
The question is, when was the data register updated by the master and when was the data register updated by the slave?
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
Your diagram is correct.
After one transfer, data is exchanged between the master and the slave.
The question is, when was the data register updated by the master and when was the data register updated by the slave?
That is a good question.

I believe that master or slave is updated after the full transmission of 1 byte. It would be logical because overwriting the data that is transmited wouldn't make sense because how to get any info out of it.

That's why I suggested the first scenario to be the closest to be correct or being correct itself.
Because the device register and slave register isn't the same so what happens to Slave depends on the device (either to overwrite the Slave register to send it back to Master or leave the Slave to receive new data that is going to be used by the device).

I also assume that I interpreted the diagram correctly how the data is sent ? But the problem is when the Slave or Master is updated, you mean when it is overwritten with new command/data to be sent/received ?
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
PS.
1698958893829.png

I found this which more likely shows that the scenario 2 is more possible which is that after the "transaction" of 1 byte like sending data from master to slave then master or slave is cleared to 00000000. Like if I want to send from master to slave again then slave is cleared from previous transaction to 00000000.

Which is why I was confused and as was wondering what was wrong with my understanding :


Neither scenario is correct.

If the master is expecting data from the slave, then the master sends data and simultaneously receives data.
If the master is expecting a reply from the slave after the first transmission, then the master has to send one more time.
And what was exactly wrong in them if they were like you said master sends and receives in both scenerios I've said.
 

Ian0

Joined Aug 7, 2020
9,502
I just understood that the slave register isn't the same as the device register. So the device reads from slave register what to do and sends the data it was requested also to the slave register to send it back or overwrited what is inside of the device register.
So that's why there is Read and Write bit.
In this case the device needs to know which you want to do.
If you don't tell it that you wish to read the data, it would receive a dummy byte which it would construe as real data and overwrite the data in the register.
But this is a very specific case.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
495
In this case the device needs to know which you want to do.
If you don't tell it that you wish to read the data, it would receive a dummy byte which it would construe as real data and overwrite the data in the register.
But this is a very specific case.
This part I guess I understood. Which is why slave register and device registers are two different things.
Which is why the bit which is read/write is important for device to know what to do with Slave to either leave it to receive new info from master or overwrite the slave register to send the info back to master.

I was just wondering which scenario I've said is correct, or which example I've said is somewhat correct. Because master and slave takes and sends the data at the same time but which scenario is correct to this matter that both of them send and receive the data.

PS.
Because if theory 1 is correct then dummy data is an old data that was left in master or slave register.
Or theory 2 is correct which is that after sending master or slave is cleared to the state of 00000000 and the 00000000 is the dummy data that is sent to the slave or master and the receiving register is clearing to 00000000 and receives new data from the sender.

So the example again. I want to send 2 bytes to the device. So first byte is 10000000 and the second 01010000, slave is then 00000000. To now Master has 10000000 and Slave has 00000000 at the end of the transaction the Slave has 10000000 and Master has 00000000, after that the Slave is restarted to 00000000 and Master is overwritten with 01010000 and the cycle goes again which is that Slave at the end has 01010000 and Master has 00000000. That's the end, I guess.
 
Last edited:

MrChips

Joined Oct 2, 2009
30,488
Let's ignore what binary bits are being sent.

If the master wants to send data to the slave, the master loads the shift register and sends the data.

If the master wants to receive data from the slave after the initial transmission, the master sends data to the slave (which could be a command that expects n bytes to be returned). The master then sends n bytes and receives n bytes from the slave.
 
Top