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

[draft] Don't reset the RTC time from gettimeofday(), plus other RTC cleanups #210

Merged
merged 3 commits into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion platform/source/mbed_rtc_time.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ int gettimeofday(struct timeval *tv, MBED_UNUSED void *tz)
_mutex->lock();
if (_rtc_isenabled != NULL) {
if (!(_rtc_isenabled())) {
set_time(0);
_rtc_init();
JohnK1987 marked this conversation as resolved.
Show resolved Hide resolved
}
}

Expand Down
42 changes: 17 additions & 25 deletions targets/TARGET_STM/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,14 +383,11 @@ Sometimes, pin is explicitly removed by default to avoid issues (but you can unc

#### System clock

System Core Clock is based on an high-speed clock.

- the HSI is the high-speed internal (MCU) clock with low accuracy
- the HSE is the high-speed external clock with higher accuray
System Core Clock is based on the high-speed clock, which is selected by the `target.clock_source` option.

For each target, a default choice has been made in the "clock_source" config settings in the targets.json file.

For main targets, it is something like:
By default, it is set to something like:

```
"clock_source": {
Expand All @@ -401,33 +398,28 @@ Meaning that:
- PLL with the external HSE clock is first configured
- if it fails, PLL with HSI is then configured

The specific choice of oscillator for your custom board is outside the scope of this README. However, in general, using a crystal for the clock will provide good accuracy, but uses a bit more power and requires an external component. Additionally, crystals can require careful design and tuning of the circuit board for best reliability and accuracy. To make the PCB simpler, a logic level oscillator can be used instead, though this is slightly more expensive.

#### Low power clock
If you wish to omit a high speed oscillator, then all STM32 parts can run from their internal oscillators (HSI). However, the clock accuracy of this oscillator is limited -- it can be as bad as +-10% over the full temperature range! So, if you are trying to do anything that relies on accurate clock speed, like USB, then you might run into trouble. To solve that issue, some STM32 parts (L4, L5, U5) provide an MSI oscillator. This works like the HSI oscillator, but trims itself using the 32kHz LSE crystal to stay at an accurate frequency. So, if you want USB but would prefer to have a 32kHz crystal than a MHz crystal, the MSI may be for you.

Low power ticker and RTC are based on an low-speed clock.
The options for the `target.clock_source` option include:

- the LSI is the low-speed internal clock with low accuracy
- the LSE is the low-speed external clock connected to 32.768 kHz quartz crystal
- `USE_PLL_HSE` - Use the High Speed External clock, with a crystal attached. The frequency expected for the crystal depends on the target, check the value of the `HSE_VALUE` define.
- `USE_PLL_HSE_EXTC` - Same as above but expect a logic level square wave instead of a crystal. Nucleo boards mostly use this configuration because the ST-Link outputs a clock signal for the MCU to use.
- `USE_PLL_HSI` - Use the High Speed Internal clock. No external parts needed.
- `USE_PLL_MSI` - Use the MSI oscillator (L4/L5/U5 only). If a 32kHz crystal is present, then this will be more accurate than HSI.

In targets.json file, it is supposed that a LSE is provided in the board
#### Low power clock

```
"config": {
"lse_available": {
"value": "1"
```
The low power ticker and the RTC are based on a low-speed (32kHz) clock. This clock source is designed to stay on even when most of the CPU is in sleep mode.

You can change this in you local mbed_app.json:
```
{
"target_overrides":
{
"XXXX": {
"target.lse_available": "0"
}
}
}
By default, Mbed expects a 32kHz crystal to be present on the LSE (Low Speed External) oscillator pins. If your board does not have such a crystal, you should set the `target.lse_available` option to 0 in mbed_app.json. This will switch Mbed to use the internal oscillator instead. Just be aware that the timing accuracy of the RTC, as well as of some Mbed RTOS operations like thread sleeps and LowPowerTimer, will be reduced to +-10%.

Note that, by default, Mbed uses low drive strength for the LSE crystal. This can be a problem on custom boards, where the LSE might need a bit more oomph to get started. If your LSE is not starting, or it's taking a long time to start, try adding
```json
"target.lse_drive_load_level": "RCC_LSEDRIVE_HIGH"
```
to your mbed_app.json and see if that fixes the issue. If so, you might need to revisit your board design or just keep the LSE drive at a higher setting. Be careful because this setting may require a complete power cycle (not just a reset!) of the target to take effect.

#### I2C Timing calculation algorithm

Expand Down
31 changes: 0 additions & 31 deletions targets/TARGET_STM/mbed_overrides.c
Original file line number Diff line number Diff line change
Expand Up @@ -287,37 +287,6 @@ void mbed_sdk_init()
SystemCoreClockUpdate();
#endif /* DUAL_CORE */

/* Start LSI clock for RTC */
#if DEVICE_RTC
#if (MBED_CONF_TARGET_RTC_CLOCK_SOURCE == USE_RTC_CLK_HSE)
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC;
#if defined(RCC_RTCCLKSOURCE_HSE_DIVX)
PeriphClkInitStruct.RTCClockSelection = (RCC_RTCCLKSOURCE_HSE_DIVX | RTC_HSE_DIV << 16);
#else
PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_HSE_DIV128;
#endif
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
error("PeriphClkInitStruct RTC failed with HSE\n");
}
#elif ((MBED_CONF_TARGET_RTC_CLOCK_SOURCE == USE_RTC_CLK_LSE_OR_LSI) && !MBED_CONF_TARGET_LSE_AVAILABLE) || (MBED_CONF_TARGET_RTC_CLOCK_SOURCE == USE_RTC_CLK_LSI)
RCC_OscInitTypeDef RCC_OscInitStruct = {0};

if (__HAL_RCC_GET_RTC_SOURCE() != RCC_RTCCLKSOURCE_NO_CLK) {
#if TARGET_STM32WB
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI1;
#else
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSI;
#endif
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
RCC_OscInitStruct.LSIState = RCC_LSI_ON;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
error("Init : cannot initialize LSI\n");
}
}
#endif /* ! MBED_CONF_TARGET_LSE_AVAILABLE */
#endif /* DEVICE_RTC */

#ifndef MBED_DEBUG
#if MBED_CONF_TARGET_GPIO_RESET_AT_INIT
/* Reset all GPIO */
Expand Down
11 changes: 6 additions & 5 deletions targets/targets.json5
Original file line number Diff line number Diff line change
Expand Up @@ -1219,6 +1219,10 @@
"help": "Define if a Low Speed External xtal (LSE) is available on the board (0 = No, 1 = Yes). If Yes, the LSE will be used to clock the RTC, LPUART, ... otherwise the Low Speed Internal clock (LSI) will be used",
"value": "1"
},
"lse_bypass": {
"help": "Change to 1 to use a logic level oscillator (not a crystal) on 32k LSE",
"value": "0"
},
"rtc_clock_source": {
"help": "Define the RTC clock source. USE_RTC_CLK_LSE_OR_LSI, USE_RTC_CLK_LSI, USE_RTC_CLK_HSE. LPTICKER is not available for HSE and should be removed from the target configuration.",
"value": "USE_RTC_CLK_LSE_OR_LSI"
Expand Down Expand Up @@ -3626,10 +3630,6 @@
"value": "25000000",
"macro_name": "HSE_VALUE"
},
"lse_bypass": {
"help": "1 to use an oscillator (not a crystal) on 32k LSE",
"value": "1"
},
"usb_speed": {
"help": "USE_USB_OTG_FS or USE_USB_OTG_HS or USE_USB_HS_IN_FS",
"value": "USE_USB_OTG_HS"
Expand Down Expand Up @@ -3662,6 +3662,7 @@
"system_power_supply": "PWR_SMPS_1V8_SUPPLIES_LDO",
"clock_source": "USE_PLL_HSE_EXTC",
"lse_available": 1,
"lse_bypass": 1,
"lpticker_delay_ticks": 0,
"network-default-interface-type": "ETHERNET",
"i2c_timing_value_algo": true
Expand Down Expand Up @@ -9763,7 +9764,7 @@
"RTC"
]
},
"RASPBERRY_PI_PICO": {
"RASPBERRY_PI_PICO_SWD": {
JohnK1987 marked this conversation as resolved.
Show resolved Hide resolved
"inherits": ["RP2040"],
"macros_add": [
"PICO_RP2040_USB_DEVICE_ENUMERATION_FIX=1",
Expand Down