2020-11-03 06:46 PM
Hi,
I am learning how to use LPUART1 on the Nucleo-64 (STM32L433RCT6P) to generate messages on the COM4 port of my Windows 10 laptop. A "Hello World\r\n" message should be printed every time the blue User Button on the board gets pressed.
Here are the relevant variables used:
UART_HandleTypeDef hlpuart1;
/* Buffer used for transmission */
uint8_t aTxBuffer[13] = "Hello World\r\n";
/* Flag for push button */
__IO FlagStatus xPush = RESET;
The LPUART1 Initialization:
static void MX_LPUART1_UART_Init(void)
{
/* USER CODE BEGIN LPUART1_Init 0 */
/* USER CODE END LPUART1_Init 0 */
/* USER CODE BEGIN LPUART1_Init 1 */
/* USER CODE END LPUART1_Init 1 */
hlpuart1.Instance = LPUART1;
hlpuart1.Init.BaudRate = 9600;
hlpuart1.Init.WordLength = UART_WORDLENGTH_8B;
hlpuart1.Init.StopBits = UART_STOPBITS_1;
hlpuart1.Init.Parity = UART_PARITY_NONE;
hlpuart1.Init.Mode = UART_MODE_TX_RX;
hlpuart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
hlpuart1.Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
hlpuart1.AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&hlpuart1) != HAL_OK)
{
Error_Handler();
}
/* USER CODE BEGIN LPUART1_Init 2 */
/* USER CODE END LPUART1_Init 2 */
}
The main code:
int main(void)
{
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* Configure the system clock */
SystemClock_Config();
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_LPUART1_UART_Init();
/* Infinite loop */
while (1)
{
/* xPush is a variable that is SET inside a GPIO IRQ Handler */
if(xPush == SET)
{
if(HAL_UART_Transmit(&hlpuart1, (uint8_t*)aTxBuffer, 13, 5000)!= HAL_OK)
{
Error_Handler();
}
HAL_Delay(100);
xPush = RESET;
}
}
}
Here is the clock initialization (I am using HSI16 as the system clock, and the PCLK1 powers the LPUART1):
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
/** Initializes the RCC Oscillators according to the specified parameters
* in the RCC_OscInitTypeDef structure.
*/
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
/** Initializes the CPU, AHB and APB buses clocks
*/
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; // LPUART1
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV8; // USART1
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK)
{
Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_LPTIM1|RCC_PERIPHCLK_LPUART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_PCLK1;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
Error_Handler();
}
/** Configure the main internal regulator output voltage
*/
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
Error_Handler();
}
}
And this is what I am seeing in the PuTTY Terminal with one button press:
I believe this is caused by a mismatch in the baud rate, even though the LPUART1's baud rate configuration is 9600 and the PuTTY's baud rate configuration is 9600. I also matched and verified that all the parameters are the same: 8 Data bits (in PuTTY) where LPUART1 has wordlength 8 bits (including parity, although parity is 0), 1 stop bits on both PuTTY and LPUART1, no parity on both, and no flow control on both. Here is the PuTTY configuration:
And here is a screenshot of the Device Manager showing that COM4 is connected to the board's ST-LINK. I also disconnected/reconnected the STM32 from my laptop to verify that COM4 is the port that I should be using:
I have also read the user manual here and confirmed that LPUART1 has a connection with the ST-LINK, and that SB66 and SB75 is soldered. Regarding the pins that I am using, I am using PA2 as LPUART1_TX and PA3 as LPUART1_RX, both configured to Alternate Function 8 (LPUART1) with no pull-up or pull-down resistors.
What could be the issue here? I tried varying the baud rate on PuTTY to initially make sure that the amount of characters I receive and I am sending are the same based on a suggestion here. I also tried increasing the APB1 clock peripheral's divider (PCLK1 clocks the LPUART1 here). Would using HSI also be fine in this application?
Any help would be appreciated. Thanks!
2020-11-03 07:35 PM
Possibly RCC_HSICALIBRATION_DEFAULT is the wrong value. See what HSITRIM is after reset and ensure it doesn't change.
2020-11-03 08:34 PM
Hi,
The HSITRIM value before running the program is 0x10. Immediately after the code 'Runs', HSITRIM turns to 0x00. The HSITRIM value stays in 0x00 afterwards though. Should this HSITRIM stay in 0x10 all the time?
Could you also explain how the HSI16 clock trimming affect the HSI clock speed? Does the microcontroller automatically decrease the clock speed if there are variations in voltage/temperature?
Update: I tried inserting the code below exactly after configuring the system clock to make sure that HSITRIM goes back to 0x10 after 0x00:
RCC->ICSCR |= RCC_ICSCR_HSITRIM_4;
I noticed that HSICAL went from 0x73 to 0xB3. The output on the PuTTY terminal is still random symbols (but different than the symbols in the picture above).
Thanks!
2020-11-04 06:04 AM
The RM says HSITRIM should be 0x40, I think. I remember this issue coming up a few times in the forum. But whatever it is after reset is very likely to be the correct value.
> Could you also explain how the HSI16 clock trimming affect the HSI clock speed?
It just trims it up/down based on the HSITRIM value. The HSI output can vary based on chip to chip variations, temperature, and probably other things. This gives the user a means to calibrate it.
Not real sure what the underlying issue is, if it's not HSITRIM. If you had a scope or logic analyzer, you could narrow things down.
2020-11-04 12:52 PM
Hi,
Thanks for pointing out that the reset value for HSITRIM should be 0x40, I did not notice that initially. I don't know how the HSITRIM value on my device at reset is 0x10. Since the HSICAL value also changes after reset, should I try to put it to reset value? The RM does not say anything about the HSICAL reset value (the value is XX: Factory programmed), but the reset value on my device seems to be always 0x73.
I actually have a logic analyzer with me, I scoped the LPUART1 Tx pin but I get framing error messages on my logic analyzer. I have attached a screen capture of the logic analyzer showing the UART signals when I press the blue user button to do a UART transmit:
When there is no framing error (on the 0xE9 and 0x27 message), when the waveform transitions to high for around a bit, the signals stay high for 90.87 microseconds, which should be too short for a 9600 baud rate (I searched somewhere that it probably should be around 104 microseconds?).
Aside from scoping the LPUART signals, what other signals could I scope?
I should also note that it actually might be a clock issue as you mentioned, because I am also having issues printing out statements with printf(), which normally happens if I do not get the Core Clock settings correct on Keil.
Thanks!
2020-11-04 01:36 PM
Hi TDK,
I decided to try adjusting the PuTTY terminal's baud rate based on the signals on the Logic Analyzer. Using the value 90.85 microseconds (one bit's high full duration on the previous image) to get a baud rate of 11007, and then using that value for the PuTTY terminal seemed to work for me. I do get the Hello World messages on my terminal now.
So, for some reason, even though the LPUART1's baud rate configuration is 9600, it drifted by around 14.65% to 11007. Could the clock source cause this kind of problem? Is there a certain range of bus clock speeds (APB1 clock speed in my case) that I should configure for the LPUART1? My APB1 divider is set to 4, and since the HSI16 is around 16MHz, would 4MHz be too low/high for the baud rate to be accurate?
Thank you for helping me with this, TDK!
Edit: I have also attached the Logic Analyzer's readings of the button press. The Logic Analyzer also detects the message at BaudRate = 11007:
Update: I also checked the SystemClock_Config() function, and the RCC_HSICALIBRATION_DEFAULT macro is actually 0x40:
#define RCC_HSICALIBRATION_DEFAULT 0x40U /*!< Default HSI calibration trimming value 64 on devices other than STM32L47x/STM32L48x */
For some reason, it does not go to 0x40 at all anytime during the code (I set breakpoints at HAL_Init(), SystemClock_Config(), and MX_GPIO_Init()). I should also note that with the above working, I did set HSITRIM value back to 0x40.
2020-11-04 02:52 PM
Glad you got it up and running. Based on your data, I'm not convinced 0x40 is the correct value. I would check to see what actual baud rate 0x10 produces. If that's the value on reset, it's probably correct, despite that the RM says.
HSICAL shouldn't/can't be modified directly. It's set by the factory and then adjusted via HSITRIM.
2020-11-04 03:19 PM
Hi,
I tested the system when HSITRIM is 0x10, and one-bit-high duration is still the same at roughly 90.85 microseconds. However, when I leave HSITRIM to be 0x00, the width/time-duration is 95 microseconds, closer to the 104 microseconds that should be the case for a baud rate of 9600. Strangely enough, using a baudrate of 11007 works for both configurations. (The 9600 baud rate does not work with HSITRIM at 0x00)
Thanks!
2020-11-04 03:28 PM
2020-11-04 03:59 PM
If the baud rate in this case is off by 14%, does that mean that the clock might be off by 14% too (14% higher than 16MHz)? Is there also a way to scope the HSI16 clock rate? If I read the global variable SystemCoreClock, the global variable holds the value 16000000.
I also checked the LPUART1->BRR register and its value is 0x1A0AB = 106667 (in decimal). Since my APB1 clock is 4MHz, based on the RM, the baudrate settings is: 256 * 4MHz/106667 = 9599.97. So I guess the baud rate configuration is correct in the registers.
Yes, it is odd, because I believe the datasheet says that HSI16's maximum frequency could be 16.08MHz, and with trimming it can be off by another 8% if I am reading it correctly. The LPUART1's error calculation on p1274 of the RM also says that the max % error for baud rate difference is 0.1%.
Thanks!