1

Im using the STM32F4xx and want to learn to programm with the ST-HAL. In the moment I try to send/ receive SPI over interrupts.

I used the following functions to receive data over INT.:

Init function:

void HAL_MspInit(void)
{
  /* USER CODE BEGIN MspInit 0 */

  /* USER CODE END MspInit 0 */

  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_0);

  /* System interrupt init*/
  /* MemoryManagement_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
  /* BusFault_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
  /* UsageFault_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
  /* SVCall_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
  /* DebugMonitor_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
  /* PendSV_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(PendSV_IRQn, 0, 0);
  /* SysTick_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);

  /* USER CODE BEGIN MspInit 1 */
    /* Peripheral interrupt init */

    HAL_NVIC_SetPriority(SPI1_IRQn, 1, 1); //<--------------------
    HAL_NVIC_EnableIRQ(SPI1_IRQn);         //<--------------------

  /* USER CODE END MspInit 1 */
}

Start function:

void main(void)
{
    HAL_SPI_Receive_IT(&hspi1, buff, size);//Start the receiving process?   

    while(1)
    {
     . . . 
    }
}

Interrputhandler:

void SPI1_IRQHandler(void)
{
  /* USER CODE BEGIN SPI1_IRQn 0 */

  /* USER CODE END SPI1_IRQn 0 */
    HAL_SPI_IRQHandler(&hspi1);
    /* USER CODE BEGIN SPI1_IRQn 1 */

      /* USER CODE END SPI1_IRQn 1 */
}

Callbackfunction (defined in main file):

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
    volatile uint8_t y = 5;
}

Before my question: Using the "normal" SPI_Transmit&Receive functions, I transmit & receive correctly.

My problem is that I dont understand how I should use this functions. e.g.: Where should I call the start" function" when comes the Callback function, an do I have to clear Interruptflags, and so on...

At the moment I use "HAL_SPI_Transmit_IT" & "HAL_SPI_Receive_IT" in the while(1) loop. In the Rx and Tx callbackfunctions I have counter variables. I see that the tmpCounterRx counts up but the tmpCounterTx dosnt???

E.G.:

while (1)
{
    HAL_SPI_Transmit_IT(&hspi1, buff, size);
    HAL_Delay(500);
    HAL_SPI_Receive_IT(&hspi1, buff, size);  
}
}

void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)
{
    tmpCounterTx++;
    volatile uint8_t x = 5;
}

void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)
{
    tmpCounterRx++;
    volatile uint8_t y = 5;
}

Rev. 1:

Thanks for reply, here my SPI init function:

void MX_SPI1_Init(void)
{
    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();
    }
}
3
  • Show your SPI init code please. Commented Aug 2, 2017 at 13:20
  • I would suggest the bare register approach. Commented Aug 2, 2017 at 16:31
  • Hm... I liked the way which interrupt handling works with the StdLib. But I have to learn using HAL and I dont know if its recomended to mix HAL and bare register approach ... ? Commented Aug 2, 2017 at 16:35

1 Answer 1

1

Try this. I assume that counters are volatile. At least you will know what interrupts are triggered and if it a HAL callback configuration problem.

volatile uint32_t tmpCounterRx1 = 0, tmpCounterTx1 = 0;

void SPI1_IRQHandler(void)
{
  if((SPI1 -> SR & SPI_SR_RXNE)) 
  {
    tmpCounterRx1++;
  } else    // intentional else do not remove
  if((SPI1 -> SR & SPI_SR_TXE)) 
  {
    tmpCounterTx1++;
  }
  /* USER CODE BEGIN SPI1_IRQn 0 */

  /* USER CODE END SPI1_IRQn 0 */
    HAL_SPI_IRQHandler(&hspi1);
    /* USER CODE BEGIN SPI1_IRQn 1 */

      /* USER CODE END SPI1_IRQn 1 */
}

PS I know it should be the comment but it is quite difficult to place longer pieces of the code in comments

Sign up to request clarification or add additional context in comments.

4 Comments

Hey! Thanks for your reply! I can confirm that the interrupt trigger. But the problem that interrupt triggered SPI communication have no effect to writing or reading my EEPROM. Damn!
now you have to connect the logic analyser. No other way. Check if you have the correct clock polarity and active edge. Some time ago I have tried to use HAL (I was just curious). For anything less complex than USB or Ethernet is just not worth.
Yes I total agree. Basically I learned that the ISR shall as short as possible. But if I see how many code only the HAL_SPI_IRQHandler() has, it seems to be not very efficent. Am I wrong? Anyway, do you think ist "ok" to mix HAL and own bare metal ISR handling?
I do not see anything wrong in it. The only pointless part is if mix for the same hardware. HAL has a lots of bugs as well, and the only point of using it is the faster track of some certification. st.com/en/embedded-software/x-cube-classb.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.