2022-12-09 07:18 AM
Hello
I've been working for a few days with a BL475e IoT node that has a SMT32L475VGT6 microprocessor as standard.
I am trying to communicate via UART with an Arduino UNO without satisfactory results. Below I share the code:
I call from main() the following function:
# MX_UART4_UART_Init #
void MX_UART4_UART_Init(void) {
huart4.Instance = UART4;
huart4.Init.BaudRate = 9600;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
huart4.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart4.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
HAL_UART_MspInit(&huart4);
if (HAL_UART_Init(&huart4) != HAL_OK) {
Error_Handler();
}
}
The HAL_UART_MspInit function is inside the same .c file as the MX_UART4_UART_Init function. Plus I also wanted to configure from the MX Programmer UART1 and UART3 (although I don't use them).
# HAL_UART_MspInit #
void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) {
GPIO_InitTypeDef GPIO_InitStruct = { 0 };
RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 };
if (uartHandle->Instance == UART4) {
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_UART4;
PeriphClkInit.Uart4ClockSelection = RCC_UART4CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}
/* UART4 clock enable */
__HAL_RCC_UART4_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/**UART4 GPIO Configuration
PA0 ------> UART4_TX
PA1 ------> UART4_RX
*/
GPIO_InitStruct.Pin = ARD_D1_Pin | ARD_D0_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF8_UART4;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
}
else if (uartHandle->Instance == USART1) {
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**USART1 GPIO Configuration
PB6 ------> USART1_TX
PB7 ------> USART1_RX
*/
GPIO_InitStruct.Pin = ST_LINK_UART1_TX_Pin | ST_LINK_UART1_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
else if (uartHandle->Instance == USART3) {
/** Initializes the peripherals clock
*/
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART3;
PeriphClkInit.Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) {
Error_Handler();
}
/* USART3 clock enable */
__HAL_RCC_USART3_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**USART3 GPIO Configuration
PD8 ------> USART3_TX
PD9 ------> USART3_RX
*/
GPIO_InitStruct.Pin = INTERNAL_UART3_TX_Pin | INTERNAL_UART3_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART3;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
}
}
From another function, which is also called from main(), I try to receive the data. I use getters & setters to move the handles from one function to another.
# SerialUART4Init #
/* Serial UART Init function */
void SerialUART4Init(void) {
UART_HandleTypeDef gUart;
gUart = GetUART4Handle();
uint8_t myRxData[10] = { 0 };
while (1) {
HAL_UART_Receive(&gUart, myRxData, 10, 10);
}
}
The huart4 handle is declared as a global variable, inside the .c file in which the MX_UART4_UART_Init function is contained.
# GetUART4Handle #
UART_HandleTypeDef GetUART4Handle(void) {
return huart4;
}
When I try to receive the data, in polling mode, I see that I need to have the UART_FLAG_RXNE flag reset, so I get back "HAL_TIMEOUT". How can I reset this flag?
However, debugging the program, I see that the huart->Instance->RDR register is always set to 0.
Regardless of whether or not I am able to save the value of this register, if I am actually reading data, should RDR be at a value other than 0?
To rule out options, I do a sanity check and connect to +3V3 the PA1 pin (UART4_RX). In this way, I understand that the transmission would be a constant high logic level. Well, RDR is still at 0.
What is the problem? Thank you very much in advance.
Solved! Go to Solution.
2022-12-13 03:07 AM
What is UART ORE?
> I need for some reason to disconnect the cable connected to the TX pin of the STM32 and
> reconnect it to start the transmission: is there any way to correct this by software?
Do you mean you want to detect the cable being connected to Tx pin? You cannot test that reliably without some sort of loopback, i.e. having an extra contact in connector and an extra pin.
JW
2022-12-09 09:25 AM
Pulling RX High is going to result in no data reception.
The Start Bit on ASYNC serial is LOW, perhaps review how serial data gets transmitted?
The receive will timeout after 10ms in the absence of any data transmission.
RXNE will need to signal in the status register for any data to be in the receiver data register.
2022-12-12 11:45 PM
First of all, thanks for your answer!
Well, I found out that I had to clear some flags before starting the data reception.
__HAL_UART_CLEAR_OREFLAG(&gUart);
__HAL_UART_CLEAR_NEFLAG(&gUart);
Although I have looked up what "OREFLAG" means but I can't find much information on what it is. What is UART ORE?
And I still have a problem: I need for some reason to disconnect the cable connected to the TX pin of the STM32 and reconnect it to start the transmission: is there any way to correct this by software? I have tried to simulate the signal at LOW and HIGH levels using a delay in between, but it doesn't work.
2022-12-13 03:07 AM
What is UART ORE?
> I need for some reason to disconnect the cable connected to the TX pin of the STM32 and
> reconnect it to start the transmission: is there any way to correct this by software?
Do you mean you want to detect the cable being connected to Tx pin? You cannot test that reliably without some sort of loopback, i.e. having an extra contact in connector and an extra pin.
JW
2022-12-14 12:16 AM
Thank you very much!
I didn't really have the manual with me, I only managed to find a very elaborate datasheet of my IoT node.
The problem with me having to connect and disconnect the Tx pin is also solved by resetting the MCU, and reading this fantastic manual I have come to the conclusion that I am overlooking not setting the RXNE flag to "1" nor clearing the RQR register to be able to empty the RDR buffer.
I have tried implementing these two lines of code in the "HAL_UART_Receive()" function but my problem persists.
/* Clear RXFRQ bit on RDR register and set RXNE flag */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_RXNE);
ATOMIC_SET_BIT(huart->Instance->RQR, USART_RQR_RXFRQ);
Anyway, I will keep an eye on some example of how to receive data but using interrupts or DMA, as I have seen that in polling mode is not the most recommended.
If you have a guide or demo of the latter you would make me very happy, but I can really take the question as solved.
Thanks a lot to both of you!