Question

It's the first time I try to use the SPI protocol. I am trying to understand an example code that came with my development kit (which has a STM32F207VCT6 microcontroller). This code implements communication (reading and writing) with a AT45DB041D flash memory.

Every time this example code manages to read the memory it not only sends information about what to be read but also asks to receive data rigth away. This data received isn't used for any purpose (apparently). The real data to be read will be asked again by the receive command later by sending a 0x00 byte first. The following code shows that:

void AT45DBXX_Read_ID(u8 *IData){
u8 i;
AT45DBXX_BUSY();
AT45DBXX_Enable;  //Chip Select drive to low
SPIx_Send_byte(Read_ID);        
for(i=0;i<4;i++)
{
    IData[i] = SPIx_Receive_byte();
}
AT45DBXX_Disable; //Chip Select drive to high
}

Definitions:

void SPIx_Send_byte(u16 data){
while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open207V_SPIx,data);

while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_RXNE)==RESET);
SPI_I2S_ReceiveData(Open207V_SPIx);
}

u16 SPIx_Receive_byte(void){
while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_TXE)==RESET);
SPI_I2S_SendData(Open207V_SPIx,0x00);

while(SPI_I2S_GetFlagStatus(Open207V_SPIx, SPI_I2S_FLAG_RXNE)==RESET);
return SPI_I2S_ReceiveData(Open207V_SPIx);
}

As you can see the SPIx_Send_byte code is not only sending what to be read but also receiving information that won't be used.

Can someone help me understand why that needs to be done and why its needed to send the 0x00 byte to actually receive the data?

Thanks!

Was it helpful?

Solution

SPI is a full-duplex, bi-directional bus where data is both sent to the slave and received from the slave at the same time. Your SPI controller doesn't know if a given byte is glong from the master, or from the slave, or both. Therefore, whenever you send a byte, you must also read a byte, if only to throw it away. By the same token, you cannot receive a byte without sending a byte, even if the slave will throw it away.

Take a look at Wikipedia.

So, what you code is doing is

  1. Sending Read_ID to the slave.
  2. Reading and throwing away the byte simultaneously read out of the slave.
  3. Write 0 to the slave to enable the slave to send a byte of data.
  4. Read the data byte that was simultaneously read out of the slave.
  5. Loop back to #3.

By the way, such questions would be better suited for the EE Stack Exchange as it is more about the hardware protocol as opposed to programming.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top