Skip to main content
Visitor II
November 9, 2021
Question

constant square wave on USART2_TX (PA2) after a power cycle (brown-out)

  • November 9, 2021
  • 24 replies
  • 9005 views

We get a constant square wave on USART2_TX (PA2) on some of our STM32L451CEU6TR products. This seems to happen sometimes after a power cycle (brown-out). The square wave is a around 32kHz.

 

As mentioned, this only happens on a few of our units, and after it has happened it doesn't seem to go away. It comes back after a power cycle event or a reset. One of the first thing we do, is to write on the UART, but we never see this, the oscillations starts before that (and the UART data will not come through after that). But the USART2_RX (PA3) still works. We can still send data to the MCU. The 32kHz isn't the same as the 32,768kHz. It's a little bit lower (like 31,9...). This was one of our thoughts that there had happened some HW changes inside the MCU so the RTC-clock was ported out here. But this doesn't seem to be the case.

    This topic has been closed for replies.

    24 replies

    Super User
    November 9, 2021

    Can you connect with debugger? If yes, read out and check/post content of GPIOA_MODER/GPIOA_AFR and RCC_BDCR.

    JW

    naAuthor
    Visitor II
    November 9, 2021

    Sorry, but no. We can't connect a debugger. It's protected, so if we connect a debugger it will erase everything. We have our own debug-output on this UART....

    Graduate II
    November 9, 2021

    Does your design pull BOOT0 low?​

    naAuthor
    Visitor II
    November 9, 2021

    Boot0 is pulled low (by a 10k resistor).

    Super User
    November 9, 2021

    Do you have a battery connected on VBAT? Do you have a 32.768kHz crystal connected and used as LSE?

    Do you use Cube/HAL to initialize LSE and/or RTC? If yes, do you correctly set/clear *all* fields of the init struct before initializing LSE/RTC?

    JW

    naAuthor
    Visitor II
    November 9, 2021

    I'm using a PSU (tried with several different ones). The unit can be out of power for a long time, and when it starts up it starts to generate this wave again.

    I'm not sure how this initilize is done (it's not me who have made it), but we suspect that it's not a SW thing. We have produced several 1000 of this PCB and we only see this on very few units. Units where the power have been cycled on/off for many times (mainly in our test system).

    And yes, we have a 32,768kHz on the OSC32-pins. That was my first thought that it was that clock being routed to this pin, (for some strange reason), but it's not the same frequency. I can run a test-command and put out our 32,678 clock on another pin, so I measured both at the same time with the oscilloscope, and they differed.

    Super User
    November 9, 2021

    > we suspect that it's not a SW thing

    Show code which performs the LSE/RTC initialization.

    > I can run a test-command and put out our 32,678 clock on another pin,

    Using those test commands, can you read out RCC_BDCR somehow?

    Or output LSI?

    JW

    Visitor II
    November 10, 2021

    Does your application meet all the stm32 electrical requirements respective to power up and sown supplies, slope, droops? What happen if you add say a 1 sec sw delay when the mcu is leaving low power mode? Is the pin configuration atomic in case or RTOS or gpio configured within interrupt/callback? Does the pin has MCO alternate on LSI ?

    naAuthor
    Visitor II
    November 10, 2021

    Since we found out that, according to STM32 Application Note, LSCO can be output on PA2, it's safe to assume this is what we see. Question is, how can RCC_BDCR:LSCOEN suddenly be enabled? I don't think we ever touch this register except for setting RTCSEL and RTCEN, which we do via HAL/LL.

    Super User
    November 10, 2021

    As I already wrote above: do you correctly set/clear *all* fields of the init struct before initializing LSE/RTC?

    Post code.

    JW

    naAuthor
    Visitor II
    November 10, 2021

    static void hsiPllConfig(void)

    {

    RCC_OscInitTypeDef RCC_OscInitStruct;

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;

    RCC_OscInitStruct.HSIState = RCC_HSI_ON;

    RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;

    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;

    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;

    RCC_OscInitStruct.PLL.PLLM = 2;

    RCC_OscInitStruct.PLL.PLLN = 8;

    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;

    RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;

    RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

    {

    configASSERT(NULL);

    }

    }

    static void lseConfig(void)

    {

    RCC_OscInitTypeDef RCC_OscInitStruct;

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE;

    RCC_OscInitStruct.LSEState = RCC_LSE_ON;

    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)

    {

    configASSERT(NULL);

    }

    }

    static void busClockConfig(void)

    {

    RCC_ClkInitTypeDef RCC_ClkInitStruct;

    /**Initializes the CPU, AHB and APB busses clocks */

    RCC_ClkInitStruct.ClockType

    = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;

    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;

    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;

    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;

    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)

    {

    configASSERT(NULL);

    }

    }

    static void SystemClock_Config(void)

    {

    RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /* Setup oscillators */

    lseConfig();

    hsiPllConfig();

    /* Setup bus clocks */

    busClockConfig();

    /* Setup peripheral clocks */

    PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_RTC | RCC_PERIPHCLK_USART1

    | RCC_PERIPHCLK_LPUART1 | RCC_PERIPHCLK_USART2

    | RCC_PERIPHCLK_I2C1 | RCC_PERIPHCLK_I2C2

    | RCC_PERIPHCLK_ADC | RCC_PERIPHCLK_LPTIM1;

    PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;

    PeriphClkInit.Lpuart1ClockSelection = RCC_LPUART1CLKSOURCE_HSI;

    PeriphClkInit.Usart2ClockSelection = RCC_USART2CLKSOURCE_PCLK1;

    PeriphClkInit.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;

    PeriphClkInit.I2c2ClockSelection = RCC_I2C2CLKSOURCE_PCLK1;

    PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK;

    PeriphClkInit.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;

    PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;

    if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)

    {

    configASSERT(NULL);

    }

    ...}

    Super User
    November 10, 2021

    To make SURE that all structure elements are initialized (as @Community member​ mentioned), change your structure declarations in your clock fonfig functions from this:

    RCC_OscInitTypeDef RCC_OscInitStruct;

    to this:

    RCC_OscInitTypeDef RCC_OscInitStruct = { 0 };

    This guarantees that and member you don't explicitly init gets set to zero. Otherwise it contains somewhat random data, depending on the stack contents.

    Graduate II
    November 10, 2021

    This

    Failure to initialize auto/local variables properly, especially large structures ST is apt to using is a primary cause of undefined/indeterminate operation.

    They've caught this on a lot of the examples/autogens, but it's one of those gifts that keeps giving.

    They can get away with it with globals as the C run-time library has a contract to clear them and initialize the statics during startup.

    #SituationalAwareness

    Super User
    November 10, 2021

    While BobS is generally right, in this particular case, I went through relevant functions in current CubeL4 I can't see anything problematic there... I am out of ideas, sorry.

    You should first try to confirm as much as possible that this is indeed related to RCC_BDCR.LSCOEN. On an affected system, perform backup domain reset, i.e. remove *both* VDD *and* the backup battery from VBAT; after placing them back the issue should go away.

    Then you should try to reproduce the problem on an "unlocked" development version of the device, while having a data breakpoint (watchpoint) set on RCC_BDCR so you can catch the code which caused the problem.

    Bat keep your mind open - there's still chance that this is something else and we just misinterpret the symptoms.

    I know this is not simple. Sorry I cannot help more.

    JW

    Visitor II
    November 11, 2021

    Thank you all for good advice,

    I'm fully aware about the uninitialized struct parts, but checking the code all relevant fields were initialized ok, so I guess we're happy with that.

    At least we found out (most likely) what is actually causing the problem. We've already verified that removing all power from both VDD and VBAT "solves" the problem. We will continue to investigate the root-cause of the problem.