2025-06-27 1:05 PM - edited 2025-06-27 2:21 PM
I am trying to configure the LPUART on my board, but appear to be getting nowhere. I've already configured the PLL to run at 110 MHz, and I changed the appropriate registers (`SW`) to use PLL as the system clock.
I've tried flashing the board with Zephyr OS just to make sure that it works, and it indeed works. When I use GDB to inspect the relevant registers (the ones changed by my code below) they appear to all have the values that I expect. I can't for the life of me figure out what is going on.
Using a logic analyzer, I see 0 activity on the TX pin, which is in a constant state of high.
Here is my code for configuring my LPUART (I am using CMSIS). I want a baud rate of 115200, and my board is configured to run at 110 MHz.
```
#include <stdint.h>
#include "stm32l5xx.h"
void enable_lpuart1(void) {
volatile uint32_t dummy;
RCC->CCIPR1 &= ~(3 << RCC_CCIPR1_LPUART1SEL_Pos);
RCC->CCIPR1 |= (1 << RCC_CCIPR1_LPUART1SEL_Pos);
// turn on the LPUART
RCC->APB1ENR2 |= (1 << RCC_APB1ENR2_LPUART1EN_Pos);
dummy = RCC->APB1ENR2;
dummy = RCC->APB1ENR2;
RCC->AHB2ENR |= 0x000000ff; // RCC_AHB2ENR_GPIOGEN_Msk;
dummy = RCC->AHB2ENR;
dummy = RCC->AHB2ENR;
GPIOG->MODER &= ~(GPIO_MODER_MODE7_Msk | GPIO_MODER_MODE8_Msk);
GPIOG->MODER |= (0b10 << GPIO_MODER_MODE7_Pos) | (0b10 << GPIO_MODER_MODE8_Pos);
GPIOG->PUPDR &= ~(0b11 << GPIO_PUPDR_PUPD7_Pos);
GPIOG->PUPDR |= (0b01 << GPIO_PUPDR_PUPD7_Pos);
GPIOG->PUPDR &= ~(0b11 << GPIO_PUPDR_PUPD8_Pos);
GPIOG->PUPDR |= (0b01 << GPIO_PUPDR_PUPD8_Pos);
GPIOG->AFR[0] &= ~GPIO_AFRL_AFSEL7;
GPIOG->AFR[1] &= ~GPIO_AFRH_AFSEL8;
GPIOG->AFR[0] |= (8 << GPIO_AFRL_AFSEL7_Pos);
GPIOG->AFR[1] |= (8 << GPIO_AFRH_AFSEL8_Pos);
LPUART1->BRR = 244444;
dummy = RCC->AHB2ENR;
dummy = RCC->AHB2ENR;
LPUART1->CR1 |= USART_CR1_UE | USART_CR1_TE | USART_CR1_RE;
}
void lpuart1_write(char c) {
// Wait until the transmit data register is empty
while (!(LPUART1->ISR & USART_ISR_TXE)); // Check TXE flag
LPUART1->TDR = c; // Write character to transmit
while (!(LPUART1->ISR & USART_ISR_TC)); // Wait for transmission to complete
}
I invoke this from my main.c in a loop. The LED starts blinking as expected, but neither minicom nor my logic analyser shows any activity. Does anyone have any guess of something that I've forgot, or something that looks wonky? It's my first time trying to do these things bare metal. It is a necessity for my project.
Here is main.c
void main(void) {
configure_clock();
SysTick_Config(110000);
__enable_irq();
enable_lpuart1();
// enable the peripheral clock
RCC->AHB2ENR |= (1 << RCC_AHB2ENR_GPIOAEN_Pos);
volatile uint32_t dummy;
dummy = RCC->AHB2ENR;
dummy = RCC->AHB2ENR;
// set PA9 as output
GPIOA->MODER &= ~(GPIO_MODER_MODE9_Msk);
GPIOA->MODER |= (1 << GPIO_MODER_MODE9_Pos);
// toggle the pin on and off
while(1) {
GPIOA->ODR ^= (1 << LED_PIN);
// lpuart1_write('A');
delay_ms(500);
}
}
NOTE: in the code above the lpuart1_write('A') call is commented out. It is of course commented _in_ in the program I am executing. I made a mistake while pasting the code here.
2025-06-27 1:48 PM
Where are you measuring the pin? They're not connected to headers by default.
Doe TXE/TC flags get set and cleared as expected?
2025-06-27 2:20 PM
I attach an image showing my setup. To my understanding, even though the pins are connected to the ST-LINK, I can still observe their values through the sockets? When I flash the board with Zephyr, I observe some activity on this pin using this setup every 500 ms when my program writes a character. The little wire is placed into the socket designated PG7.
I am unable to verify that the pins are correctly set right now (will have to wait until tomorrow), but my writing is done in a loop that also blinks an LED, and the LED blinks as expected. Clearly my program is not halting on one of my conditions. Perhaps my conditions are not correct?
Also, I now see that in the code I posted the actual writing of a character is commented out. Of course this is commented _in_ in the code that I am executing. I will try to edit my post.
2025-06-27 3:57 PM
> Here is my code for configuring my LPUART (I am using CMSIS).
In Zephyr the peripherals and clocks are configured by device tree. It could clobber something. Can you try a simple bare metal test?