2025-09-21 12:11 AM
Hello STM32 Community,
I'm having trouble getting UART communication working on my NUCLEO-L4R5ZI-P board and would appreciate any guidance.
Board Details:
Problem: No UART output appears in any terminal program, despite testing multiple configurations. The virtual COM port is detected by both macOS and Windows, but no TX activity occurs (TX indicator never lights up in terminal programs).
What I've Tested:
Hardware Verification:
Sample Code Tested ( I can upload the full code if that is helpful):
// Basic USART2 test on PD5
RCC_AHB2ENR |= (1U << 3); // Enable GPIOD
RCC_APB1ENR1 |= (1U << 17); // Enable USART2
GPIOD_MODER |= (2U << 10); // PD5 alternate function
GPIOD_AFRL |= (7U << 20); // AF7
USART2_BRR = 417; // 9600 baud @ 4MHz
USART2_CR1 = (1U << 3) | (1U << 0); // TE | UE
// Send loop with TXE flag checking
Questions:
Any insights would be greatly appreciated. I've exhausted the standard troubleshooting approaches and am wondering if this board variant has specific requirements I'm missing.
Thank you for your time and assistance.
2025-09-21 2:04 AM
Maybe better is open schematic and no to shoot blindy.
Then use only LPUART1 for testing... And sorry but your bare metal tests "basic" is absurd
2025-09-21 2:17 AM
Thank you for your response. I looked at the schematic and tried the LPUART1. I checked that the solder bridge is closed on the board as well, but it is still not working. I understand that the bare metal coding is not the best, and I first tried using the standard setup on STMCubeIDE and coding with the HAL libraries, but couldn't get anything to work (not even an LED to flash). That is why I resorted to bare metal coding because I have been able to directly get the pins to work through this, but have not been successful with UART communication. Any suggestions on why the LPUART isn't working? I have included my full code, which I used to test this, below.
/*
* LPUART1 Test - PG7 (TX) and PG8 (RX)
* Based on forum confirmation that NUCLEO-L4R5ZI-P uses LPUART1
* with SB130 and SB131 closed for virtual COM port
*/
#include <stdint.h>
// Base addresses
#define RCC_BASE 0x40021000U
#define GPIOG_BASE 0x48001800U
#define LPUART1_BASE 0x40008000U
// RCC registers
#define RCC_AHB2ENR (*(volatile uint32_t*)(RCC_BASE + 0x4C))
#define RCC_APB1ENR2 (*(volatile uint32_t*)(RCC_BASE + 0x5C))
// GPIO registers
#define GPIOG_MODER (*(volatile uint32_t*)(GPIOG_BASE + 0x00))
#define GPIOG_AFRL (*(volatile uint32_t*)(GPIOG_BASE + 0x20))
#define GPIOG_AFRH (*(volatile uint32_t*)(GPIOG_BASE + 0x24))
// LPUART1 registers
#define LPUART1_CR1 (*(volatile uint32_t*)(LPUART1_BASE + 0x00))
#define LPUART1_BRR (*(volatile uint32_t*)(LPUART1_BASE + 0x0C))
#define LPUART1_ISR (*(volatile uint32_t*)(LPUART1_BASE + 0x1C))
#define LPUART1_TDR (*(volatile uint32_t*)(LPUART1_BASE + 0x28))
void delay(volatile uint32_t count)
{
while (count--) {
asm("nop");
}
}
int main(void)
{
// Enable clocks
RCC_AHB2ENR |= (1U << 6); // Enable GPIOG clock
RCC_APB1ENR2 |= (1U << 0); // Enable LPUART1 clock
// Configure PG7 (TX) as alternate function
GPIOG_MODER &= ~(3U << 14); // Clear PG7 mode bits (bits 14-15)
GPIOG_MODER |= (2U << 14); // Set PG7 as alternate function (10 binary)
// Configure PG8 (RX) as alternate function
GPIOG_MODER &= ~(3U << 16); // Clear PG8 mode bits (bits 16-17)
GPIOG_MODER |= (2U << 16); // Set PG8 as alternate function (10 binary)
// Set PG7 to AF8 (LPUART1_TX) - PG7 uses AFRL register
GPIOG_AFRL &= ~(0xF << 28); // Clear AF bits for PG7 (bits 28-31)
GPIOG_AFRL |= (8U << 28); // Set AF8 for PG7
// Set PG8 to AF8 (LPUART1_RX) - PG8 uses AFRH register
GPIOG_AFRH &= ~(0xF << 0); // Clear AF bits for PG8 (bits 0-3)
GPIOG_AFRH |= (8U << 0); // Set AF8 for PG8
// Configure LPUART1 for 9600 baud with 4MHz clock
// LPUART BRR = (256 * clock_freq) / baud_rate
// BRR = (256 * 4000000) / 9600 = 106666
LPUART1_BRR = 106666;
// Enable transmitter, receiver, and LPUART1
LPUART1_CR1 = (1U << 3) | (1U << 2) | (1U << 0); // TE | RE | UE
while (1)
{
// Wait until transmit data register is empty
while (!(LPUART1_ISR & (1U << 7))); // Wait for TXE flag (bit 7)
// Send single letter 'X'
LPUART1_TDR = 'X';
delay(1000000); // 1 second delay between 'X' characters
}
}