cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 HAL SPI continues to transmit bytes while I am tryin to read using HAL_SPI_Receive

selcukozb
Associate III

I encountered this problem when I attempted to send a one byte command using HAL_SPI_Transmit(..), and then trying to read 2 byte response from Miso, using HAL_SPI_Receive(..)

My test code is plain as follows, no intterupts, nothing connected to SPI port.

/* USER CODE BEGIN 2 */

uint8_t data = 0xd0;

uint8_t received[16];

HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_SET); // unselect slave

HAL_Delay(10);

while (1) {

HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_RESET); // select slave

while (HAL_SPI_Transmit(&hspi1, &data, 1, 100) != HAL_OK); // Transmit 1 byte command

while (HAL_SPI_Receive(&hspi1, received, 16, 100) != HAL_OK); // Receive 16 bytes

HAL_GPIO_WritePin(TP_CS_GPIO_Port, TP_CS_Pin, GPIO_PIN_SET); // unselect slave

__NOP();

}

/* USER CODE END 2 */

Trace on logic analyser is as seen on attached image, only the first byte 0xd0 on MOSI is transmitted by my code, following bytes are parasitics :0693W000005BPqJQAW.png

SPI configuration is as follows :

static void MX_SPI1_Init(void)

{

 /* USER CODE BEGIN SPI1_Init 0 */

 /* USER CODE END SPI1_Init 0 */

 /* USER CODE BEGIN SPI1_Init 1 */

 /* USER CODE END SPI1_Init 1 */

 /* SPI1 parameter configuration*/

 hspi1.Instance = SPI1;

 hspi1.Init.Mode = SPI_MODE_MASTER;

 hspi1.Init.Direction = SPI_DIRECTION_2LINES;

 hspi1.Init.DataSize = SPI_DATASIZE_8BIT;

 hspi1.Init.CLKPolarity = SPI_POLARITY_LOW;

 hspi1.Init.CLKPhase = SPI_PHASE_1EDGE;

 hspi1.Init.NSS = SPI_NSS_SOFT;

 hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_32;

 hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;

 hspi1.Init.TIMode = SPI_TIMODE_DISABLE;

 hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;

 hspi1.Init.CRCPolynomial = 10;

 if (HAL_SPI_Init(&hspi1) != HAL_OK)

 {

  Error_Handler();

 }

My computer is Mac Pro Catalina, I am using STM32 cubeIDE 1.4.2

Any comments ?

Edit : A further diagnosis has shown that, these parasitic transmission of bytes happen in the first 12 read cycles (1 byte each) after reset. Then on subsequent transmit/receive sequences, no more byte transmissions happen, only first one that I transmitted is emitted on MOSI. If there is residual data on Tx Buffer, does that cause this? If so, how to flush tx Buffer?

BR

Best regards

3 REPLIES 3
TDK
Guru

MOSI has to have a signal on it, that's how SPI works. If you care about what that signal is, for instance if you want it to be all 0x00 bytes, you can do HAL_SPI_TransmitReceive instead of just HAL_SPI_Receive. In the current implementation, in two line master mode, HAL_SPI_Receive will transmit the current content of your receive buffer. Zeroing your receive buffer will have it transmit zeroes.

https://github.com/STMicroelectronics/STM32CubeF1/blob/003dfc9e6c2e424c19a25df3934afaf7fce660d6/Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_spi.c#L969

If you feel a post has answered your question, please click "Accept as Solution".
selcukozb
Associate III

Thanks a lot TDK. That means I have to study SPI Protocol once more. I have been using it to drive my TFT displays and SD cards without hitting this issue since years. I want to learn how I could survive so far. 😀

Typically in an SPI transaction, there are parts where MOSI is ignored and other parts where MISO is ignored. That is probably the case here, so it doesn't matter that the buffer isn't zeroed. That information would be in the datasheet of whatever device you're interfacing with.

If you feel a post has answered your question, please click "Accept as Solution".