I got a question regarding the SPI.h driver which is available in Arduino IDE examples. it seems there is only a function for transmission and there is no function for receiving data using SPI.
Here is the function used for transfer:
uint8_t transfer(uint8_t data);
which is defined in this class:
uint8_t SPIClass::transfer(uint8_t data)
{
if(_inTransaction){
return spiTransferByteNL(_spi, data);
}
return spiTransferByte(_spi, data);
}
and here is the implemention of the function:
uint8_t spiTransferByte(spi_t * spi, uint8_t data)
{
if(!spi) {
return 0;
}
SPI_MUTEX_LOCK();
spi->dev->mosi_dlen.usr_mosi_dbitlen = 7;
spi->dev->miso_dlen.usr_miso_dbitlen = 7;
spi->dev->data_buf[0] = data;
#if CONFIG_IDF_TARGET_ESP32C3 || CONFIG_IDF_TARGET_ESP32S3
spi->dev->cmd.update = 1;
while (spi->dev->cmd.update);
#endif
spi->dev->cmd.usr = 1;
while(spi->dev->cmd.usr);
data = spi->dev->data_buf[0] & 0xFF;
SPI_MUTEX_UNLOCK();
return data;
}
Is the value returned by this function, data, the byte sent by SPI Slave ?? I mean is the buf[0] & 0xFF value the received value from the slave side? it should be so strange if the SPI.h driver does not have a function to receive the value from the Slave side.
Short answer is yes, that could be the data send back from the Slave.
A more detail answer:
The function transfer()
in SPI is bi-directional, as SPI has separate output (MOSI) and input (MISO) line, when you clock-out one byte, it also clock-in one byte from Slave. Technically you can receiving data while sending data. But more often, you need to tell the slave of what kind of data you want from the slave. So it is often, for example, that if you send one byte command (to tell slave what you want to read) and expecting 3 bytes data return from the slave, then you might need to transfer((uint8_t buffer), 4)
to send 4 bytes data (one byte cmd and 3 bytes dummy) in order to get the 3 bytes data back. How this is actually implemented varies from device to device, so you need to consult the datasheet of the device you are working with.