4

I'm using a STM32F411RE-Nucleo board and generating a project with Cube MX for System Workbench. The problem is that HAL_UART_Receive function doesn't receive input from the user, even though I don't change any UART, GPIO, RCC or NVIC configuration.

Surprisingly, when I comment two lines in SysTick Interrupt Handler function i.e. SysTick_Handler, HAL_UART_Receive starts working but this comes with another problem.

void SysTick_Handler(void)
{
     HAL_IncTick();
     HAL_SYSTICK_IRQHandler();
}

HAL_Delay() function doesn't work when I disable those two lines. I guess it's because the processor can't handle the ticks.

How to work HAL_UART_Receive and HAL_Delay work at the same time? I'm a bit new in embedded programming and I'm sorry if I couldn't get myself clear.

Thanks.

Edit:

I use this function for receiving user input:

  if( HAL_UART_Receive_IT(&huart2, (uint8_t*) RxMessage, RXBUFFERSIZE) != HAL_OK )
  {
      while(1)
      {

      }
  }

I don't want the timer to run while using HAL_UART_Receive() function, which is the same as HAL_UART_Receive_IT() but with an additional TIMEOUT parameter. As the TIMEOUT might call the SYSTICK interrupt, I decided to use HAL_UART_Receive_IT().

Also, the full assert is OFF, if it's necessary to know.

Other parts of my code are as follows:

#define RXBUFFERSIZE        3
uint8_t RxMessage[RXBUFFERSIZE];

void SysTick_Handler(void)
{
HAL_IncTick(); //enabled
HAL_SYSTICK_IRQHandler(); //enabled
}

void HAL_SYSTICK_IRQHandler(void)
{
  HAL_SYSTICK_Callback();
}

/**
  * @brief  SYSTICK callback.
  * @retval None
  */
__weak void HAL_SYSTICK_Callback(void)
{
  /* NOTE: This function Should not be modified, when the callback is needed,
            the HAL_SYSTICK_Callback could be implemented in the user file
   */
}
RoyC
  • 8,418
  • 6
  • 25
  • 40
baqx0r
  • 311
  • 1
  • 4
  • 13
  • Why would you want to call `HAL_SYSTICK_IRQHandler` inside `SysTick_Handler`? It makes sense only if you are polling the RX rather than using the interrupt. And the `HAL_Delay` function is heavily depending on the counter incremented by `HAL_IncTick`, this is why it is not working if you comment it out. And I think, you are not supposed to use `HAL_UART_Receive` directly with this method.. – Eugene Sh. Dec 11 '15 at 14:55
  • @EugeneSh. I'm not very familiar with the cube stuff, but wouldn't `HAL_SYSTICK_IRQHandler` be a way to get a user function to be executed in addition to the `HAL_IncTick()`? It's the ST HAL, so it shouldn't be modified by the user, but how would he get a callback/additional method to be handled on systick? (not that it would be a great idea to do much on the timer basis, but who knows) – Arsenal Dec 11 '15 at 15:06
  • @Arsenal I am not a pro with the Cube either and I don't have it right now, but I believe there is a section in the handler which is modifiable by user. But it could also be that this type of project is assuming using the HAL_delay only for timings.. – Eugene Sh. Dec 11 '15 at 15:11
  • 2
    @EugeneSh. I've downloaded it and found: `void HAL_SYSTICK_IRQHandler(void) { HAL_SYSTICK_Callback(); }` and `__weak void HAL_SYSTICK_Callback(void)` so the call of `HAL_SYSTICK_IRQHandler()` is indeed placed by ST and there to call a callback (why they use another function just to call the callback is beyond me). I could imagine that the MCU is clocked too slowly for it to handle the UART and SysTick in a timely enough manner. – Arsenal Dec 11 '15 at 15:44
  • 1
    Oh.. It looks like I got confused with all of the names. I was considering `HAL_SYSTICK_IRQHandler` to be a UART interrupt handler. So perhaps the OP have added some code to the callback, so it is blocking or breaking something? – Eugene Sh. Dec 11 '15 at 15:48
  • I am quite surprised you get anything at all when calling ``HAL_UART_Receive()`` with the systick turned off, as this function is basically ``HAL_UART_Receive_IT()`` with a busy loop waiting for either completion or timeout - and the timeout uses the systick. FWIW ``HAL_Delay()`` also uses the systick (hence it's 1 ms precision) and is indeed not functional when systick is disabled. –  Dec 14 '15 at 14:08
  • So, do you inspect the return value of ``HAL_UART_Receive[_IT]()`` ? Have you turned ON the "full assertion" checks (in CubeMX) ? Do you check the error state of the UART at some point? Quite like C++ streams, the HAL driver and/or the hardware will put itself in error mode (e.g. on overrun) and stop working until both CR and DR registers are read. –  Dec 14 '15 at 14:10
  • Thing's that HAL_UART_Receive_IT returns HAL_OK even though I don't enter any input from keyboard. – baqx0r Dec 15 '15 at 11:18
  • I think the CubeMX project is buggy and there's not much to do with it. I'll give a try using only Standard Peripheral library and take the pinout configuration from Cube. Hope it'll be fixed this way. – baqx0r Dec 17 '15 at 09:05
  • I also want to give GCC4Mbed a try. Seems like "less buggy" than Cube. – baqx0r Dec 17 '15 at 09:06
  • ``HAL_UART_Receive_IT`` returns HAL_OK if it correctly enters reception mode (interrupt enabled). The interrupt will be disabled once the specified amount of bytes have been read. If you want a blocking call (that is, one that returns only when all bytes have been received) use ``HAL_UART_Receive``. Besides, the HAL libs are not perfect, but they happen to work, so I doubt switching to the StdPeriphLib can improve the situation. Maybe you will be able to fix the bug with a side-effect: that of needing to restart from scratch. –  Dec 18 '15 at 10:03
  • 1
    @Tibo, I really think it's a CubeMX problem, since it's always mentioned as a buggy project and is under development by ST engineers. Seriously thinking of switching to SPL (Std Peripheral Lib) soon. – baqx0r Dec 18 '15 at 10:24

0 Answers0