Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

STM32WL USART2@2400 not working with every device #15463

Open
hallard opened this issue Nov 8, 2023 · 6 comments
Open

STM32WL USART2@2400 not working with every device #15463

hallard opened this issue Nov 8, 2023 · 6 comments

Comments

@hallard
Copy link
Contributor

hallard commented Nov 8, 2023

Description of defect

As #15285 we've got some issues with USART2 at 2400bps. We use classic BufferedSerial

We have different brand of connected devices working at 2400 bps and when using USART2 some have issues and are not responding

All devices work with USART1, LPUART1 at 2400 bps without any issue.

Issue is just on USART2 and at 2400 bps we tried 1200 bps on USART2 with great success (we can't go above 2400 on the devices we have)

We measured baud rate and looks like some shifting (more like 2450 than 2400) and may be some client devices are less or more strict than others on rate.

Target(s) affected by this defect ?

STM32WL

Toolchain(s) (name and version) displaying this defect ?

image

What version of Mbed-os are you using (tag or sha) ?

mbed-os-99.99.99

What version(s) of tools are you using. List all that apply (E.g. mbed-cli)

MBED Studio V1.4.5

How is this defect reproduced ?

Connect different devices on USART pins, send frame and wait answer, then do the same changing USART baud rate.

At 2400 bps on USART2 some devices are not responding (always the same)

I tried to use different clock source LSE (recommended for low baud rate) but not sure it's applied on USART2

            "target.lpuart_clock_source": "USE_LPUART_CLK_LSE",
            "target.lpuart_clock_source": "USE_LPUART_CLK_HSI",

I also changed prescaler value (1 2 4 8 16) nothing changed that's very strange.

@jeromecoutant any hints on configuration we could try (even calling HAL API) would be greatly appreciated, in the meanway we continue investigation.

@mbedmain
Copy link

mbedmain commented Nov 8, 2023

@hallard thank you for raising this issue.Please take a look at the following comments:

It would help if you could also specify the versions of any tools you are using?

NOTE: If there are fields which are not applicable then please just add 'n/a' or 'None'. This indicates to us that at least all the fields have been considered.
Please update the issue header with the missing information.

@hallard
Copy link
Contributor Author

hallard commented Nov 10, 2023

To add some follow up, we succeded to speak at 2400 on USART2 setting baud rate to 2500

setting 2400 measured baud rate with logic analyser => 2310
setting 2500 measured baud rate with logic analyser => 2410

I was unable to find for USART2 where the clock source is selected (which one and frequency) on STM32WL for USART2.

No idea, even in MBed nor HAL, would be curious to know that @jeromecoutant :-)

@jeromecoutant
Copy link
Collaborator

From CubeMX, I could see settings:
image
I suppose that, as we don't configure usart2 clock, default values are ok...
https://github.com/ARMmbed/mbed-os/blob/master/targets/TARGET_STM/serial_api.c#L635

@hallard
Copy link
Contributor Author

hallard commented Nov 10, 2023

Interesting so default configuration (As USART1) 2400 do 16 prescaler so 3MHz that should be fast enough to be precise, don't understand why it works with USART1 and not USART2.

I May try to configure USART2 from code issued from cubeMX just to test.

image

@hallard
Copy link
Contributor Author

hallard commented Nov 14, 2023

Ok some investigations,

I succeeded talking device with some code in serial_baud of serial_api.c to set UART2 to HSI

#endif /* LPUART1_BASE */

    if (obj_s->uart == USART2) {
        RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
        PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2;

        if (!__HAL_RCC_GET_FLAG(RCC_FLAG_HSIRDY)) {
            RCC_OscInitTypeDef RCC_OscInitStruct = {0};
            RCC_OscInitStruct.OscillatorType      = RCC_OSCILLATORTYPE_HSI;
            RCC_OscInitStruct.HSIState            = RCC_HSI_ON;
            RCC_OscInitStruct.PLL.PLLState        = RCC_PLL_OFF;
            RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
            HAL_RCC_OscConfig(&RCC_OscInitStruct);
            PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_HSI;
        }
       
        HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
    }

    if (init_uart(obj) != HAL_OK) {
        debug("Cannot initialize UART with baud rate %u\n", baudrate);
    }
}

This works, and looking in cube IDE since STM32WL MSI is 48MHz HSI for USART2 is 16MHz (stil don't understand why USART2 with PCLK1 set to 48MHz it does not work)

image

Anyway I decided to give a try, setting MSI RC to 32MHz and ABP1 prescaler to 2 in SetSysClock()

RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_10; 
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;

Giving same frequency on UART2

image

And this one does not work, this is drving me mad.

of course I changed into serial_baud()

#endif /* LPUART1_BASE */

    if (obj_s->uart == USART2) {
        RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
        PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART2;
        PeriphClkInitStruct.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;
        HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
    }

    if (init_uart(obj) != HAL_OK) {
        debug("Cannot initialize UART with baud rate %u\n", baudrate);
    }
}

@hallard
Copy link
Contributor Author

hallard commented Dec 12, 2023

Ok, I took the logic analyzer to measure baud rate on different configuration on TX line, results are BTW amazing, I've done all test on LP_UART1 because this one has lot of clock option in mbed.

All test are running with default frequencies and prescaler with STM32WL5 I mean

  • SysClk 48MHz
  • PCLK1 48MHz
  • HSI 16MHz

be prepared here are results with different values of lpuart_clock_source in mbed_app.json

please take into account that if multiple values are defined such as default value
USE_LPUART_CLK_LSE|USE_LPUART_CLK_PCLK1|USE_LPUART_CLK_PCLK3

order in config if done the following (in init_uart() of serial_api.c):

  • LSE (only if baud <=9600)
  • PCLK1
  • PCLK3
  • SYSCLK

Please note also that if baud rate is < 4800 then UART prescaler is set to 16 instead of 1, you can check mbed original code here

{ "target.lpuart_clock_source": "USE_LPUART_CLK_PCLK1" }

USE_LPUART_CLK_PCLK1

  • 1200 bps measured 1165
  • 2400 bps measured 2330
  • 4800 bps nothing goes out from serial
  • 9600 bps nothing goes out from serial

USE_LPUART_CLK_LSE

  • 1200 bps measured 1165
  • 2400 bps measured 2330
  • 4800 bps measured 4700
  • 9600 bps measured 9450

USE_LPUART_CLK_HSI

  • 1200 bps measured 1200
  • 2400 bps measured 2403
  • 4800 bps measured 4806
  • 9600 bps measured 9615

No option in lpuart_clock_source

so in this case default values from mbed applies (see above), so mainly LSE as it's the first in the list.

  • 1200 bps measured 1165
  • 2400 bps measured 2330
  • 4800 bps measured 4700
  • 9600 bps measured 9450

What to think? not really sure if there is something wrong somewhere I digged into the code and did not found visible error. But why with PCLK1 nothing goes out from serial at 4800 and 9600 I have no idea.

Anyway looks like best option is to use HSI for baud rate below or equal to 9600 (not sure for higher speed)

First idea would be to set system clock to 16Mhz and expect same results than HSI, but this does not works either, baud rate shift is always there.

If someone has ability to test with another board (NUCLEO WL55 for example) would be great to confirm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Untriaged
Status: Needs Triage
Development

No branches or pull requests

3 participants