January 15, 2024

STM32CubeMX - Uart initialization

I now have a serial demo running and sending messages over UART1. Using "picocom /dev/ttyACM0" I see:
Hello Cowboy!
Hello Cowboy!
Hello Cowboy!
...
I use gdb to investigate the uart registers (this is UART1 at 0x40011000).
CR1 - 0x40011000 -- 0x0000000d
CR2 - 0x40011004 -- 0
CR3 - 0x40011008 -- 0
BRR - 0x4001100c -- 0x0000022c
GTP - 0x40011010 -- 0
RTO - 0x40011014 -- 0
ROR - 0x40011018 -- 0
ISR - 0x4001101c -- 0x000000d0
ICR - 0x40011020 -- 0
RDR - 0x40011024 -- 0
TDR - 0x40011028 -- 0
PRE - 0x4001102c -- 0
CR1 is 0xd = 1101 -- this is TE, RE, and UE (transmitter, receiver, and uart enable).
BRR is 0x22c = 556. The baud rate is 115200, so the input clock is 64,051,200?
ISR is 0xD0 = 1101_0000 -- TXE, TC, IDLE (Tx empty, Tx cmplete, line idle)

All this is believable, and amazingly simple. What about that input clock?

Also note that this is working using HAL_Delay(), which didn't seem to work along with my blink demo, but that is another issue.

Use ctags to chase down the uart (usart) initialization code

main.c   MX_USART1_UART_Init();
usart.c  s = HAL_UART_Init(&huart1);
Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
UART_SetConfig () in the same file

(Note: stm32h7xx_hal_uart.c is 4727 lines of code!)

I edit stm32h7xx_hal_uart.c and introduce "tom_pclk" as a variable. GDB shows me this is set to 64000000! And 64000000/115200 = 555.555

Next, I edit stm32h7xx_hal_uart.c and introduce "tom_source" as a variable. GDB shows me this is set to UART_CLOCKSOURCE_D2PCLK2. It is nice that GDB shows me this enum in symbolic form rather than as an integer that I need to translate!

I look at figure 59 (page 387) in the TRM and this must be "rcc_pclk2", which is the APB2 peripheral clock. I examine several other RCC registers and conclude that the system clock is 64 Mhz from the raw HSI and that HPRE does not divide this (so hclk is 64 Mhz), as is rcc_pclk2.


Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org