2021-10-09 08:55 AM
Hello Everyone!
I would really need some help. I have a B-L072Z-LRWAN1 board and I use the LoRa end node project provided by ST. I'd like to add UART1 to this project with interrupt. However, the code stops working when I initialize the UART1. Could you please help me with how to correctly initialize the UART1 and the clock source for this?
Thank you very much!
Adam
2021-10-09 12:26 PM
Not clear what's causing your failure, likely going to need to debug to understand exact mode of failure, or what pins you're using here, and for what.
Watch that the IRQ Handlers service the underlying cause otherwise they will continually re-enter (tail-chain) and prevent foreground execution.
Pretty sure its running from APB2 in this context.
//****************************************************************************
void USART1_Init(int BaudRate)
{
static UART_HandleTypeDef UartHandle = {0};
GPIO_InitTypeDef GPIO_InitStruct = {0};
__USART1_CLK_ENABLE();
__GPIOA_CLK_ENABLE();
/* USART1 PA.9 USART1_TX, PA.10 USART1_RX */
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL; // GPIO_PULLUP
GPIO_InitStruct.Speed = GPIO_SPEED_LOW;
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
UartHandle.Instance = USART1;
UartHandle.Init.BaudRate = BaudRate;
UartHandle.Init.WordLength = UART_WORDLENGTH_8B;
UartHandle.Init.StopBits = UART_STOPBITS_1;
UartHandle.Init.Parity = UART_PARITY_NONE;
UartHandle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle.Init.Mode = UART_MODE_TX_RX;
if (HAL_UART_Init(&UartHandle) != HAL_OK)
{
PRINTF("USART1_Init failed\n");
/* Initialization Error */
Error_Handler();
}
HAL_NVIC_SetPriority(USART1_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
#ifdef USE_DMA
InitUSART1DMA();
#else // USE_DMA
USART1->CR1 |= USART_CR1_RXNEIE;
#endif // USE_DMA
}
//****************************************************************************
When I remapped the USARTX, had used this in V1.1.1 builds
#ifdef USE_DEBUG_USART1_PA9_PA10
#define USARTX USART1
#define USARTX_CLK_ENABLE() __USART1_CLK_ENABLE()
#define USARTX_RX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
#define USARTX_TX_GPIO_CLK_ENABLE() __GPIOA_CLK_ENABLE()
#define USARTX_FORCE_RESET() __USART1_FORCE_RESET()
#define USARTX_RELEASE_RESET() __USART1_RELEASE_RESET()
#define USARTX_TX_PIN GPIO_PIN_9
#define USARTX_TX_GPIO_PORT GPIOA
#define USARTX_TX_AF GPIO_AF4_USART1
#define USARTX_RX_PIN GPIO_PIN_10
#define USARTX_RX_GPIO_PORT GPIOA
#define USARTX_RX_AF GPIO_AF4_USART1
/* Definition for USARTx's NVIC */
#define USARTX_IRQn USART1_IRQn
#define USARTX_IRQHandler USART1_IRQHandler
#endif // USE_DEBUG_USART1_PA9_PA10
2021-10-09 01:59 PM
H, Tesla DeLorean, thank you for the help! I will check the code.
I add here the relevant code of UART1 that I try to use. Maybe this will make it easier to debug the problem.
System clock config:
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
/* Enable HSE Oscillator and Activate PLL with HSE as source */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSEState = RCC_HSE_OFF;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLLMUL_6;
RCC_OscInitStruct.PLL.PLLDIV = RCC_PLLDIV_3;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/* Set Voltage scale1 as MCU will run at 32MHz */
__HAL_RCC_PWR_CLK_ENABLE();
__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
/* Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0 */
while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};
/* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
clocks dividers */
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
{
Error_Handler();
}
}
usart.c
#include "usart.h"
#include "dma.h"
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
DMA_HandleTypeDef hdma_usart2_tx;
/* USART1 init function */
void MX_USART1_UART_Init(void)
{
/* USER CODE BEGIN USART1_Init 0 */
/* USER CODE END USART1_Init 0 */
/* USER CODE BEGIN USART1_Init 1 */
/* USER CODE END USART1_Init 1 */
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
huart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
huart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
}
/* USER CODE BEGIN USART1_Init 2 */
/* USER CODE END USART1_Init 2 */
/* USART2 init function */
//}
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 = USART_BAUDRATE;
huart2.Init.WordLength = UART_WORDLENGTH_8B;
huart2.Init.StopBits = UART_STOPBITS_1;
huart2.Init.Parity = UART_PARITY_NONE;
huart2.Init.Mode = UART_MODE_TX;
huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;
if (HAL_UART_Init(&huart2) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN USART2_Init 2 */
/* USER CODE END USART2_Init 2 */
}
void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspInit 0 */
/* USER CODE END USART1_MspInit 0 */
/* USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
/* Select SYSTEM clock for USART1 commuincation TX/RX */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/**USART1 GPIO Configuration
PA10 ------> USART1_RX
PA9 ------> USART1_TX
*/
GPIO_InitStruct.Pin = GPIO_PIN_10|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* USART1 interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspInit 1 */
/* USER CODE END USART1_MspInit 1 */
}
else if (uartHandle->Instance == USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Enable peripherals and GPIO Clocks */
/* Enable GPIO TX/RX clock */
USARTx_TX_GPIO_CLK_ENABLE();
USARTx_RX_GPIO_CLK_ENABLE();
/* Enable USARTx clock */
__USART2_CLK_ENABLE();
/* Enable DMA clock */
DMAx_CLK_ENABLE();
/* USART2 clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
/* Select SYSTEM clock for USART2 commuincation TX/RX */
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2;
PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_SYSCLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
/**USART2 GPIO Configuration
PA3 ------> USART2_RX
PA2 ------> USART2_TX
*/
GPIO_InitStruct.Pin = USARTx_TX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = USARTx_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_Port, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_TX Init */
/* Configure the DMA handler for Transmission process */
hdma_usart2_tx.Instance = USARTx_TX_DMA_CHANNEL;
hdma_usart2_tx.Init.Request = USARTx_TX_DMA_REQUEST;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_LOW;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
Error_Handler();
}
/* Associate the initialized DMA handle to the UART handle */
__HAL_LINKDMA(uartHandle, hdmatx, hdma_usart2_tx);
/* Configure the NVIC for DMA */
/* NVIC configuration for DMA transfer complete interrupt (USART1_TX) */
HAL_NVIC_SetPriority(USARTx_DMA_TX_IRQn, USARTx_Priority, 1);
HAL_NVIC_EnableIRQ(USARTx_DMA_TX_IRQn);
/* NVIC for USART, to catch the TX complete */
HAL_NVIC_SetPriority(USARTx_IRQn, USARTx_DMA_Priority, 1);
HAL_NVIC_EnableIRQ(USARTx_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
}
void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle)
{
if(uartHandle->Instance==USART1)
{
/* USER CODE BEGIN USART1_MspDeInit 0 */
/* USER CODE END USART1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART1_CLK_DISABLE();
/**USART1 GPIO Configuration
PA10 ------> USART1_RX
PA9 ------> USART1_TX
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_10|GPIO_PIN_9);
/* USART1 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART1_IRQn);
/* USER CODE BEGIN USART1_MspDeInit 1 */
/* USER CODE END USART1_MspDeInit 1 */
}
else if (uartHandle->Instance == USART2)
{
/* USER CODE BEGIN USART2_MspDeInit 0 */
/* USER CODE END USART2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USART2_CLK_DISABLE();
/**USART2 GPIO Configuration
PA3 ------> USART2_RX
PA2 ------> USART2_TX
*/
HAL_GPIO_DeInit(GPIOA, USARTx_RX_Pin | USARTx_TX_Pin);
/* USART2 DMA DeInit */
HAL_DMA_DeInit(uartHandle->hdmatx);
/* USART2 interrupt Deinit */
HAL_NVIC_DisableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspDeInit 1 */
/* USER CODE END USART2_MspDeInit 1 */
}
}
In STM32L0xx_IT the IRQHandler is implemented for UART1.
Actually, I've spent days trying to debug this but I didn't find the solution (probably I don't see what is missing).
2021-10-09 02:28 PM
>>Actually, I've spent days trying to debug this but I didn't find the solution
Ok, but it conveys very little detail on what you did, or any observations that would help others to guess at what's happening and exact what it is that isn't working.
>> However, the code stops working when I initialize the UART1.
Stops working where?
Stuck in a loop? Error or Fault Handler?
Interrupt?
You could perhaps start with a peripheral view, inspecting RCC, GPIO and USART1 registers.
If the baud rate or clocking is wrong you could see this on a scope whilst sending a stream of U characters.
2021-10-14 03:39 PM
Do you have the UART1 code working on its own - independent of the LoRa end node project ?