2020-01-03 12:50 PM
Hi!
I have a Nucleo F401RE that works great! But the problem I have is that the board cannot be call the function HAL_UART_RxCpltCallback after it has recieve its bytes.
I have:
I'm expecting a LED lamp to light up, the one in the function below. But it does not light up because the function won't be called, why?
But when I try to send some bytes via CuteCom software, nothing happens. Here is a minimal C-code from me.
This code waits until it have got 41 bytes, then this function will be called.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) {
HAL_GPIO_WritePin(Digital0_GPIO_Port, Digital0_Pin, 1); // If this method be called, then light up LED lamp
// Convert ADC values to
TXData[0] = (uint8_t) (ADCValues[0] >> 8);
TXData[1] = (uint8_t) (ADCValues[0] & 0xFF);
TXData[2] = (uint8_t) (ADCValues[1] >> 8);
TXData[3] = (uint8_t) (ADCValues[1] & 0xFF);
TXData[4] = (uint8_t) (ADCValues[2] >> 8);
TXData[5] = (uint8_t) (ADCValues[2] & 0xFF);
TXData[6] = (uint8_t) (ADCValues[3] >> 8);
TXData[7] = (uint8_t) (ADCValues[3] & 0xFF);
TXData[8] = (uint8_t) (ADCValues[4] >> 8);
TXData[9] = (uint8_t) (ADCValues[4] & 0xFF);
TXData[10] = (uint8_t) (ADCValues[5] >> 8);
TXData[11] = (uint8_t) (ADCValues[5] & 0xFF);
// Send data to JLoggerServer in about 5 milliseconds
HAL_UART_Transmit(&huart2, TXData, sizeof(TXData) / sizeof(TXData[0]), 5);
// Listen for a new receive
HAL_UART_Receive_DMA(&huart2, RXData, sizeof(RXData) / sizeof(RXData[0]));
}
My USART2 and DMA configuration.
/**
* @brief USART2 Initialization Function
* @param None
* @retval None
*/
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
/**
* Enable DMA controller clock
*/
static void MX_DMA_Init(void)
{
/* DMA controller clock enable */
__HAL_RCC_DMA2_CLK_ENABLE();
__HAL_RCC_DMA1_CLK_ENABLE();
/* DMA interrupt init */
/* DMA1_Stream5_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA1_Stream5_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA1_Stream5_IRQn);
/* DMA2_Stream0_IRQn interrupt configuration */
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
And at the main function. I'm calling these functions as well.
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_USART2_UART_Init();
MX_DMA_Init();
MX_ADC1_Init();
MX_TIM1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
// Enable ADC1 AND UART RX with DMA
HAL_ADC_Start_DMA(&hadc1, ADCValues, sizeof(ADCValues) / sizeof(ADCValues[0]));
HAL_UART_Receive_DMA(&huart2, RXData, sizeof(RXData) / sizeof(RXData[0]));
The fields are declared as
uint32_t ADCValues[6];
uint8_t RXData[12 + 28 + 1]; // 12 = sliders, 28 = digitals, 1 = send state
uint8_t TXData[12];
I hope this information helps. Else, ask for more.
Best regards
Solved! Go to Solution.
2020-01-04 05:35 AM
You probably need to initialize DMA before UART in the main().
2020-01-03 04:45 PM
Could be a host of things, you'll need to debug your situation.
It doesn't receive any data.
Errors in the receive side of the UART, ie framing, noise or parity.
Errors on the DMA side, addresses or otherwise.
Is there an error callback for UART or DMA?
Any of the buffer fill with data?
Any errors returned by the called functions?
IRQ Handlers defined and called/working?
Try with byte level UART IRQ
2020-01-04 03:50 AM
Hi!
I don't have the equipment to check if there is nose or parity in the UART. But I tried to check if the DMA is working by code and it does!
if (HAL_UART_Receive_DMA(&huart2, RXData, sizeof(RXData) / sizeof(RXData[0])) == HAL_OK){
HAL_GPIO_WritePin(Digital0_GPIO_Port, Digital0_Pin, 1); // It works!
}
And for the UART. No error here.
static void MX_USART2_UART_Init(void)
{
/* USER CODE BEGIN USART2_Init 0 */
/* USER CODE END USART2_Init 0 */
/* USER CODE BEGIN USART2_Init 1 */
/* USER CODE END USART2_Init 1 */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX_RX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart2.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}else{
HAL_GPIO_WritePin(Digital0_GPIO_Port, Digital0_Pin, 1); // It works!
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
Sending from Nucleo -> PC works perfect
while (1)
{
/* USER CODE END WHILE */
HAL_UART_Transmit(&huart2, TXData, 3, 5); // This works
HAL_Delay(1000);
/* USER CODE BEGIN 3 */
}
It's also working to send data from PC -> Nucleo
while (1)
{
/* USER CODE END WHILE */
HAL_UART_Receive(&huart2, TXData, 1, 5);
if(TXData[0] == 50){
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1); // Flash LED 1 second
HAL_Delay(1000);
}
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 0);
/* USER CODE BEGIN 3 */
}
So that confirms that the UART is OK. But why not the DMA?
How can I check if there is any errors for the DMA?
Thank you for your response.
EDIT:
I know the issue now! The function is not declared yet. How can I declare that function so DMA knows that it exist?
/* USER CODE BEGIN 4 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, 1); // Nothing happens here
}
/* USER CODE END 4 */
The function is avaiable in stm32f4xx_hal_uart.c file.
/**
* @brief Rx Transfer completed callbacks.
* @param huart Pointer to a UART_HandleTypeDef structure that contains
* the configuration information for the specified UART module.
* @retval None
*/
__weak void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_RxCpltCallback could be implemented in the user file
*/
}
But if I hover the mouse over the function it looks like this
I'm also got some weird errors on DMA C-code. These errors says Missing ';'
2020-01-04 05:35 AM
You probably need to initialize DMA before UART in the main().
2020-01-04 06:15 AM
But I'm using STMCubeIDE. That should be generated by itself. Or is it a bug?
2020-01-04 06:27 AM
2020-01-04 11:58 AM
Thank you! That solved my issue. I init the functions like this
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_DMA_Init();
MX_USART2_UART_Init();
MX_ADC1_Init();
MX_TIM1_Init();
MX_TIM2_Init();
/* USER CODE BEGIN 2 */
And I have version 1.24.2 and not 1.24.1 as in the thread you send me.
2020-01-04 11:59 AM
Can an employee of ST mark this thread as a bug in version 1.24.2 ?
2020-01-05 07:45 PM
2020-01-09 02:12 PM
Yes! I know. Se the answer above.