2021-11-09 03:55 AM - last edited on 2024-07-23 08:37 AM by Andrew Neil
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.
2021-11-10 05:59 AM
As I already wrote above: do you correctly set/clear *all* fields of the init struct before initializing LSE/RTC?
Post code.
JW
2021-11-10 06:35 AM
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);
}
...}
2021-11-10 12:49 PM
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.
2021-11-10 01:51 PM
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
2021-11-10 02:32 PM
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
2021-11-10 11:57 PM
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.
2022-07-13 12:58 AM
10 test systems here with STM32L451RCT6 and identical HW/SW.
One of the 10 produces the problem quite often. Not observed on the 9 others.
Once it appears, it reappears at every following startup.
I noticed that after power down there is a residual VDD voltage of about 0.5 VDC.
The problem goes away if I short circuit VDD to GND and release the short afterwards.
It is completely reproducible, bringing VDD to 0 V clears the fault.
The error can reappear after a further power off. BOR ist set to level 1.
2022-07-13 01:22 AM
Everything wrote above applies. Check with debugger - or by instrumenting the code in any available way - the backup domain register settings, especially after the problem occurs.
JW
2022-07-13 06:00 AM
How can the variation between chips be explained, HW/SW being identical?
2022-07-13 08:23 AM
That's not "between chips", it's "between boards"; and there is nothing like "identical". There's an infinite number of small variations, e.g. leakages between pins, exact timing of power up ramp on individual power pins depending on minor variations in capacitors capacitance and a myriad of other things on the board, different exact thresholds of a couple of million transistors on the chip, and its consequence, which may be quite likely the case here, the inherent tendency of a SRAM cell to power up in a given state. I am no clairvoyant.
Try to find the mechanism how this happens, that may lead you to the explanation of the variation. Start with reading out the backup domain registers and compare for "good" and "bad" state.
JW