cancel
Showing results for 
Search instead for 
Did you mean: 

SPI receive in interrupt mode lost last 2 bytes (STM32F103RC)

IMuly
Associate II

Hello!

I'm testing the communications between SPI1 and SPI3 in STM32F103RC.

SPI1 and SPI3 are using interrupts, dma is off.

When I try to read received bytes I found that rdata[6] = 0 and rdata[7] = 0, but must be 0x7 and 0x8 respectively.

When I use DMA on both sides everything is OK.

And when I use transmit function in blocking mode(i.e HAL_SPI_Transmit()) everything is OK.

Speed_medium means prescaller_16.

HSE = 8MHz

RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;

RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

spi_mode0 is CPOL=0, CPHA =0;

nss controlled by hardware.

uint8_t tdata[8] = {0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8};

uint8_t rdata[8] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };

er = initSPI(SPI3, type_master, spi_mode0, speed_medium, dma_disable, NULL, tcv, size_8bit, dir_RXTX, firstbit_LSB, crc_disable);

   TEST_ASSERT_MESSAGE(HAL_OK == er, "SPI3 Init failed");

er = initSPI(SPI1, type_slave, spi_mode0, speed_medium, dma_disable, rcv, NULL, size_8bit, dir_RXTX, firstbit_LSB, crc_disable);

TEST_ASSERT_MESSAGE(HAL_OK == er, "SPI1 Init failed");

TEST_ASSERT_MESSAGE(HAL_SPI_Receive_IT(&hspi1, rdata, 8) == HAL_OK, "SPI1 receive failed");

   TEST_ASSERT_MESSAGE(HAL_SPI_Transmit_IT(&hspi3, tdata, 8) == HAL_OK, "SPI3 transmit failed");

   TEST_ASSERT_EQUAL_INT(hspi1.ErrorCode, 0);

   TEST_ASSERT_EQUAL_INT(hspi3.ErrorCode, 0);

I found the solution in driver HAL.

In SPI_TxISR_8BIT I added small delay.

static void SPI_TxISR_8BIT(struct __SPI_HandleTypeDef *hspi)

{

 *(__IO uint8_t *)&hspi->Instance->DR = (*hspi->pTxBuffPtr);

 hspi->pTxBuffPtr++;

 hspi->TxXferCount--;

 HAL_Delay(1);

 if (hspi->TxXferCount == 0U)

 {

#if (USE_SPI_CRC != 0U)

   if (hspi->Init.CRCCalculation == SPI_CRCCALCULATION_ENABLE)

   {

     /* Enable CRC Transmission */

     SET_BIT(hspi->Instance->CR1, SPI_CR1_CRCNEXT);

   }

#endif /* USE_SPI_CRC */

   SPI_CloseTx_ISR(hspi);

 }

}

Do you think this is a normal solution or is there a more elegant solution?

1 ACCEPTED SOLUTION

Accepted Solutions

Set mutual priorities of the interrupts so that the Rx interrupt service routine (ISR) can nest into ("preempt") the Tx ISR (and don't forget to set NVIC_SetPriorityGrouping() appropriately).

JW

View solution in original post

3 REPLIES 3

Set mutual priorities of the interrupts so that the Rx interrupt service routine (ISR) can nest into ("preempt") the Tx ISR (and don't forget to set NVIC_SetPriorityGrouping() appropriately).

JW

IMuly
Associate II

Thank you for your answer!

But there are no separate interrupts in HAL for Rx and Tx. only for global SPI.

35 42 settable SPI1 SPI1 global interrupt 0x0000_00CC

36 43 settable SPI2 SPI2 global interrupt 0x0000_00D0

51 58 settable SPI3 SPI3 global interrupt 0x0000_010C

IMuly
Associate II

I decrease the priority of SPI3, and increase SPI1.

Everything is working fine.

Thank you again!