cancel
Showing results for 
Search instead for 
Did you mean: 

STM Nucleo L552ZE_Q LPUART configuration

krook
Associate II

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.

3 REPLIES 3
TDK
Super User

Where are you measuring the pin? They're not connected to headers by default.

TDK_0-1751057205618.png

 

Doe TXE/TC flags get set and cleared as expected?

 

If you feel a post has answered your question, please click "Accept as Solution".
krook
Associate II

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.

Pavel A.
Super User

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?