cancel
Showing results for 
Search instead for 
Did you mean: 

STM32C011F4P6: transparent USART1 / USART2 transceiver

polemon
Associate II

I'd like to use an STM32C011F4P6 as a transceiver between USARTs 1 and 2.

As a first approach, I've set both USARTs to 9600bd, and I want anything that's incoming on one of them to be directly sent to the other. In both directions at the same time.

In the USART1 and USART2 configuration I enabled NVIC interrupts for both of them.

I then created a HAL_UART_RxCpltCallback() in section 4 in my main.c:

 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
  /* Prevent unused argument(s) compilation warning */
  //UNUSED(huart);
  if (huart->Instance == USART1) {
	  HAL_UART_Transmit_IT(&huart2, huart1.pRxBuffPtr, 1);
	  HAL_UART_Receive_IT(&huart1, huart1.pRxBuffPtr, 1);
  } else if (huart->Instance == USART2) {
	  HAL_UART_Transmit_IT(&huart1, huart2.pRxBuffPtr, 1);
	  HAL_UART_Receive_IT(&huart2, huart2.pRxBuffPtr, 1);
  }

  /* NOTE : This function should not be modified, when the callback is needed,
            the HAL_UART_RxCpltCallback can be implemented in the user file.
   */
}

 

I know this is a very naïve approach, however this is a first test, just to get things working.

in my main() I've enabled receive interrupts like so:

 

  HAL_UART_Receive_IT(&huart1, huart1.pRxBuffPtr, 1);
  HAL_UART_Receive_IT(&huart2, huart2.pRxBuffPtr, 1);

 

This happens right before the endless-while-loop, the rest of the code was generated by the IDE.

Now here's my problem: the callback function HAL_UART_RxCpltCallback() is never called! I've set breakpoints in there and used SWD to debug the code, but either the interrupt never occurs, or for some reason the function is never called, I don't know what I'm doing wrong here...

Can anyone help me out?

I'll be happy to provide additional information in case it's unclear what I'm trying to accomplish or how my setup looks, but I'm unsure what I additional info I should provide.

Thanks in advance!

--polemon

8 REPLIES 8
Karl Yamashita
Lead II

Did you enable NVIC?

If you find my answers useful, click the accept button so that way others can see the solution.
Imen.D
ST Employee

Hello @polemon ,

 Use a breakpoint to stop the program after data is received, and check pRxBuffPtr[] value. 

Try using the while() loops for the transmit.

I recommend you have a look at this wiki: Getting started with UART.  This article will help you on how to use and set up UART example.

 

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
SofLit
ST Employee

Hello,

Don't know if you're using CubeMx or not but as already said, is UART NVIC is enabled for both UART1 and UART2?

I add: do you have the UART IRQ handler:

void USART1_IRQHandler(void)
{
  HAL_UART_IRQHandler(&UartHandle1);
}

and 

void USART2_IRQHandler(void)
{
  HAL_UART_IRQHandler(&UartHandle2);
}

Also for the transmit, I don't think you need to use the interrupt so simply use HAL_UART_Transmit(). This prevents the CPU to be overloaded by unused interrupts.

You can share your project to get an efficient help.

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.

As I said in my Op, I did put a breakpoint in side my HAL_UART_RxCpltCallback(), but that breakpoint is never reached, hence me asking.

At one point, I also had a __NOP() right at the beginning of that function and put the breakpoint there, but it was also never reached.

I did read that Wiki article about getting started with UART, but the problem is it never talks about using two UARTs at the same time, with no main loop interaction. The idea is, that the entire function is done using callbacks and interrupts, and not through polling. The reason is, that both UARTs are at different speeds, so there is buffering to be needed. However that functionality is for something a little further down the line, for now I'd just like to have both UARTs working correctly, etc.

I'm just using STM32CubeIDE. I build and program from within there, most of it is just defaults, etc.

Building and programming works fine, I never had problems with that. SWD also works fine.

NVIC is enabled for both, yes, I neabled it in the IOC.

Where should I expect the USART1_IRQHandler() function? Is it like generated in my main.c?

The reason I'd like to use HAL_UART_Transmit_IT() is because I want to be able to receive while the controller is transmitting, etc. It has to be a fully transparent, and full duplex.

Since one of the UARTs will be slower than the other, there will be some buffering required in one direction and very little in the other, however I'd like to deal with the buffering issue at some later time, for now I just want to have both UARTs working in both directions, at the same time, with the same speed, etc. I plan to deal with buffering and changing transmission speeds later, once the basic setup works, etc.

I'm not sure how I should share my project? Just upload to Github / Gitlab and share the link?

Karl Yamashita
Lead II

Have you checked with oscilloscope to see if other devices are transmitting at correct baud rate?

Try tying the same uart Rx and TX together and do a loop back test.

 

See this project for using multiple uarts at same time https://github.com/karlyamashita/Nucleo-G431RB_Three_UART

If you find my answers useful, click the accept button so that way others can see the solution.
Pavel A.
Evangelist III

Where should I expect the USART1_IRQHandler() function? Is it like generated in my main.c?

Normally should be generated in stm32....._it.c

 

Got it:

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */

  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&huart1);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

/**
  * @brief This function handles USART2 interrupt.
  */
void USART2_IRQHandler(void)
{
  /* USER CODE BEGIN USART2_IRQn 0 */

  /* USER CODE END USART2_IRQn 0 */
  HAL_UART_IRQHandler(&huart2);
  /* USER CODE BEGIN USART2_IRQn 1 */

  /* USER CODE END USART2_IRQn 1 */
}

This is inside my stm32c0xx_it.c, so I guess this is generating fine.