cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6 (USART1)

Franzi.Edo
Senior

Dear all,

I'm currently trying to work with USART1 on my Nucleo-N6 board.

Here's how I attempted to initialize the board:

CPU Frequency: 600 MHz
Peripheral Bus (PB1, PB2, PB4, PB5): 50 MHz

GPIO Configuration:
PE5: Alternate function, push-pull — USART1_TX (AF7)
PE6: Alternate function, pull-up     — USART1_RX (AF7)

I configured CCIPR13 to set the USART1 clock source to f PB2:

RCC->CCIPR13 &= ~RCC_CCIPR13_USART1SEL;

Here is my minimal USART1 initialization code:

RCC->APB2ENR |= RCC_APB2ENR_USART1EN;

USART1->BRR = 50000000 / 115200;
USART1->CR1 = (USART_CR1_FIFO_UE | USART_CR1_FIFO_TE | USART_CR1_FIFO_RE);

Unfortunately, I'm unable to send data. I verified with a logic analyzer and there’s no activity on PE5.
Any suggestions would be greatly appreciated.

Best regards,
Edo

1 ACCEPTED SOLUTION

Accepted Solutions

Dear all,
The problem is now "solved", but something remains unclear.

According to the ST datasheet (DS14791 Rev 1), page 136, the maximum clock frequency for APB buses should be:

fAPB_max = fHCLKx / 4

This is exactly what I initially configured on my board:
sysb_ck = 400 MHz (driven by IC2), which is the max bus frequency (FBus_max)
TIMPRE is set to 4 → resulting timer clock: 100 MHz
HPRE is set to 2 → AHB clock: 200 MHz
Therefore, by the datasheet, fAPB_max = 50 MHz

I set PPRE1, PPRE2, PPRE4, and PPRE5 = 4
However, with this configuration, USART1 does not work.
Then, I changed fAPB2 to 200 MHz by setting PPRE2 = 1, and now USART1 works as expected.

After additional tests, it turns out that PPRE2 must be set to 1 — any other setting results in a non-functional UART.
This contradicts the datasheet limitations.

The ST errata does mention issues on PB2, but it’s still unclear whether this behavior is related.

So for now, I can continue with my design, even if it's technically out of spec per DS14791 Rev 1, page 136.

ST, any insights or feedback would be appreciated.

Best regards,
Edo

View solution in original post

7 REPLIES 7
TDK
Super User

Configure it with HAL to ensure it works, then compare your register configurations to HAL.

 

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

Hi TDK,

Thank you for your advice.

For my project, I’m not allowed to use Cube.
Of course, I could try reverse-engineering the generated code, but that would be quite a tedious job.

I was hoping to find from ST some basic documentation for a minimal UART setup (for the 32N657) , covering at least:

- GPIO configuration
- Clock muxes
- Required clocks

So, a minimal UART setup to send a byte.
Anyway, thanks again for your help.
Best regards,
Edo

 

RomainR.
ST Employee

Hello @Franzi.Edo 

Have you also activated the GPIOE clock?

You can also refer to the UART_Printf example below, and compare with debugger all the configurations of the RCC, USART and GPIO registers with your code.

https://github.com/STMicroelectronics/STM32CubeN6/tree/main/Projects/NUCLEO-N657X0-Q/Examples/UART/UART_Printf

Best regards,

Romain,

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Enable clocks first, before configuring anything else

Most have initial startup hazard over APB/AHB, where the Write-Buffers basically allow for cycle-after-cycle writing to the registers. Generally you need to provide some fencing, to force in-order completion. ST typically writing a value, and then reading back that location, forcing the write to run to completion, and not just deferred, ie forcing a bubble on the pipe-line.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

Thank you, Roman and DeLorean.
Unfortunately, I'm unable to get any characters out of USART1.

Here's the sequence I'm using:

1. Power Configuration (to enable MCOx outputs via PWR)
VDDIO4VMEN, VDDIO4SV, VDDIO5VMEN, VDDIO5SV

2. Enable GPIO Clocks (via RCC->AHB4ENR)
GPIOAEN, B, C, D, E, F, G, H

3. PLL Initialization
PLL1 -> 600-MHz
PLL2 -> 800-MHz
PLL3 -> 400-MHz
PLL4 -> 400-MHz

Assignments:
IC1 powered by PLL1 and clock / 1
IC2 powered by PLL4 and clock / 1

To observe with MCO2
IC15 powered by PLL2 and clock / 2
IC20 powered by PLL3 and clock / 3

RCC->CFGR1
CPU set to IC1 (600-MHz)
SYS set to IC2 (400-MHz)

RCC->CCIPR7
PERSEL set to 0 (HSI)

RCC->CFGR2
TIMPRE set to 2 (100-MHz)
HPRE set to 1 (200-MHz)
PPRE1 set to 2 (50-MHz)
PPRE2 set to 2 (50-MHz)
PPRE4 set to 2 (50-MHz)
PPRE5 set to 2 (50-MHz)

At this point, I'm able to verify all the clock settings using MCO2.
I also changed PE5 to GPIO mode and toggled it to verify physical TX pin output.

Now the USART1

4. Enabled USART1 clock (via APB2ENR)

5. Set USART1SEL to 1, clock per_ck.
(I tried other possible clocks, 0 -> pclk and 6 -> hsi_div_ck)

6. USART1->CR1 = 0;
USART1->CR2 = 0;
USART1->CR3 = 0;
USART1->PRESC = 1;
USART1->BRR = 50000000/57600;

USART1->CR1 = TE | RE | FIFOEN;
USART1->CR1 |= UE;

Between each step, I inserted (void)(USART1->XYZ) statements, along with isb(), dsb(), and dmb() to ensure ordering and completion

7. Cyclically tried to fill the USART1->TDR but no activity on the scope.

I suspect I'm missing an important clock or dependency, but I can't identify which one.
Any insights or suggestions would be greatly appreciated.

Thanks,
Edo

 

Dear all,
The problem is now "solved", but something remains unclear.

According to the ST datasheet (DS14791 Rev 1), page 136, the maximum clock frequency for APB buses should be:

fAPB_max = fHCLKx / 4

This is exactly what I initially configured on my board:
sysb_ck = 400 MHz (driven by IC2), which is the max bus frequency (FBus_max)
TIMPRE is set to 4 → resulting timer clock: 100 MHz
HPRE is set to 2 → AHB clock: 200 MHz
Therefore, by the datasheet, fAPB_max = 50 MHz

I set PPRE1, PPRE2, PPRE4, and PPRE5 = 4
However, with this configuration, USART1 does not work.
Then, I changed fAPB2 to 200 MHz by setting PPRE2 = 1, and now USART1 works as expected.

After additional tests, it turns out that PPRE2 must be set to 1 — any other setting results in a non-functional UART.
This contradicts the datasheet limitations.

The ST errata does mention issues on PB2, but it’s still unclear whether this behavior is related.

So for now, I can continue with my design, even if it's technically out of spec per DS14791 Rev 1, page 136.

ST, any insights or feedback would be appreciated.

Best regards,
Edo

Hello @Franzi.Edo 

I refer to ES0620 - Rev 1: errata 2.2.1 Incorrect APB prescaler setting.

This limitation concerns the configuration of all PPREx[2:0] bits in RCC_CFGR2, thus forcing
the APBx frequency = AHB.
To configure different frequencies on APB than AHB, use alternative peripheral clock sources by configuring the peripheral Source Mux and PER or internal clock sources and leave the PPERx[2:0] bits with the default value 0b000.

At the same time, I requested a clarification of this errata in the next version of the ES0620.
Sorry for the misunderstanding caused.

Best regards,

Romain,

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.