cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 act as SPI Master and slave for Echo of 1byte Data

adityatiwari
Associate II

MASTER SIDE

 

uint8_t txByte_master = 0xA5; // Byte to send

uint8_t rxByte_master = 0x00; // Received byte

volatile uint16_t count = 0;

uint8_t dummyTx = 0x00;

uint8_t dummyRx = 0x00;

volatile uint8_t spi_ready = 0; // Flag to indicate SPI transfer complete

 

void SystemClock_Config(void);

static void MX_GPIO_Init(void);

static void MX_USART2_UART_Init(void);

static void MX_SPI1_Init(void);

 

int main(void)

{

HAL_Init();

 

MX_GPIO_Init();

MX_USART2_UART_Init();

MX_SPI1_Init();

while (1)

{

spi_ready = 0; // Reset flag

 

// Start SPI communication

HAL_SPI_TransmitReceive_IT(&hspi1, &txByte_master, &rxByte_master, 1);

 

// Wait until the transaction completes

while (spi_ready == 0);

 

// Check if received data is correct

if (rxByte_master== 0xA5) {

HAL_SPI_DeInit(&hspi1);// HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13); // Blink LED if correct

}

 

HAL_Delay(500); // Delay for visibility

 

}

/* USER CODE END 3 */

}
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi) {
    if (hspi->Instance == SPI1) {
        spi_ready = 1;  // Set flag to indicate transfer complete
    }
}

 

 

SLAVE SIDE

 

uint8_t rxByte_slave = 0x00; // Received byte

uint8_t txByte_slave = 0x00; // Byte to send back (Echo)

uint8_t txByte_slave_check = 0xCE; // Byte to send back for check

volatile uint8_t spi_ready = 0; // Flag to indicate SPI transfer complete





int main(void)

{

HAL_Init();

MX_GPIO_Init();

MX_USART2_UART_Init();

MX_SPI1_Init();

while (1)

{

spi_ready = 0; // Reset flag

HAL_SPI_Receive_IT(&hspi1, &rxByte_slave, 1);

while (spi_ready == 0);

txByte_slave = rxByte_slave;

spi_ready = 0; // Reset flag

HAL_SPI_Transmit_IT(&hspi1, &txByte_slave, 1);

while (spi_ready == 0);

}

}



void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) {

if (hspi->Instance == SPI1) {

spi_ready = 1; // Set flag indicating reception complete

}

}



void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi) {

if (hspi->Instance == SPI1) {

spi_ready = 1; // Set flag indicating transmission complete

}

}

 

Above written code is for master and slave in which I am trying to echo 1 Byte of Data

through SPI Protocol, here on I am able to capture exact 8 bit of data on slave side but

when slave transmit the same data to master, then master is unable to capture the exact data

and capture some random data.

try to help me in order to solve this problem....

Both side means Master and Slave the board I am using is NUCLEO-F401RE

 

Note :

I have set the slave side on External oscillator.

 

 

 

 

7 REPLIES 7
gbm
Principal

Have a look at this:

https://community.st.com/t5/stm32-mcus-products/regarding-function-calls-when-performing-spi-communication-in/m-p/738412#M265178

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
adityatiwari
Associate II

@gbm Thank you for your reply but this is not enough for me because I had already post my code. So, I can only request that firstly go through this and try to figure out problem in that code and try to reply in respect of this. 
Please consider my point 

The problem with your code is described in the post I linked. You  can't "echo" in this way. Slave must start Transmit before it receives anything. Usually the MCU slave might respond to what it receives in the third frame of a transfer. The simplest echo loos like this:

Master: <data><dummy><dummy>

Slave: <dummy><dummy><echo data>

Note that the two dummy bytes sent by slave must be ready before the transfer starts.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Saket_Om
ST Employee

Hello @adityatiwari 

In SPI communication, it is crucial for the slave device to be ready to respond to the master, as the master controls the clock. To ensure proper operation of your application, you need to synchronize the two devices. This involves making sure that the slave has executed the transmit API before the master initiates the transmission. Proper synchronization between the master and slave devices is essential for reliable data transfer.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar
gbm
Principal

The updated code is still incorrect. For single- or two-frame transfer, use TransmitReceive on slave side, or call Transmit_IT and Receive_IT without waiting between them. Even then, I am not sure whether the HAL based code is able to handle this, cause you must be able to handle Rx and Tx interrupts after every byte without suspending the transmission (disabling the SPI interface).

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice

clock.PNG

@Saket_Om Thanks for your reply. This image shows the clock configuration for spi protocol as per this I have set my peripheral clock after this also I didn't get the correct byte from slave side. could you please cross check my edited code and put your views on this.

Hello @adityatiwari 

You should use HAL_SPI_TransmitReceive_IT() in the Master side and also in the slave side. 

Please check the example Projects/STM32F4-Discovery/Examples/SPI/SPI_FullDuplex_ComIT and update your code.

If your question is answered, please close this topic by clicking "Accept as Solution".

Thanks
Omar