RTC LSE/LSI selection
The patches offered by @chuckbook aimed to solve two problems. The first was an issue with oscillator initialisation, now subject to a PR. The second, by my (incomplete) understanding of the code, aimed to select the LSE or LSI oscillator at runtime. The aim of this issue is to solicit comments on the relevance and design of this proposed feature, notably from @chuckbook.
The LSI oscillator is a low precision RC oscillator internal to the chip, while the LSE is an oscillator requiring external components to achieve substantially improved accuracy. The LSE is implemented with a 32.768KHz crystal on the Pyboard.
To initiate the discussion I'd like to raise the following questions.
- Does the LSI have merit other than in extremely cost constrained systems? Is it relevant to actual or proposed MicroPython target boards? Or does it have other relevance e.g. fault tolerance?
- If it is relevant, is there a reason for performing the selection at runtime, rather than making it a target specific compile time option?
- If done at runtime, when should selection occur? At initial power up? On soft boot or recovery from standby? Or must the choice be iterated or event driven and, if so, in response to what events?
- If hardware containing an LSE can fall back to the LSI at runtime, from the user perspective this is a fault condition. I would submit that this should raise an exception.
delayed RTC initialization with LSI fallback
Also included:
MICROPY_HW_RTC_USE_US
option to present datetime sub-seconds in µs
MICROPY_HW_RTC_USE_LASTFREQ
hold pyb.freq() parameters in RTC backup reg
MICROPY_HW_RTC_USE_CALOUT
option to enable RTC calibration output
Sample main.py to test some parameters:
import pyb
stupt=pyb.micros()
import stm
rtc=pyb.RTC()
info0=rtc.info()
ts0=pyb.micros()
res=rtc.datetime()
stm.mem32[stm.RTC+0x60]+=1
if False:
#if res[6] // 10 != 0:
stm.mem32[stm.RTC+stm.RTC_BKP17R]=stm.mem32[stm.RTC+stm.RTC_BKP16R]
stm.mem32[stm.RTC+stm.RTC_BKP16R]=(stm.mem32[stm.RTC] << 8) | (stm.mem32[stm.RTC+stm.RTC_SSR] & 0xff)
stm.mem32[stm.RTC+stm.RTC_BKP19R]+=1
import mymain
dt=rtc.datetime()
info1=rtc.info()
ts1=pyb.micros()
print('\n%d us 0x%x %d us 0x%x %d us LSx_dt: %d us' % (stupt, info0, ts0-stupt, info1, ts1-stupt, ts1-ts0))
print('%d-%02d-%02d %02d:%02d:%02d.%06d' % (res[0], res[1], res[2], res[4], res[5], res[6], res[7]))
adc=pyb.ADCAll(12)
try:
vref = adc.read_vref()
except:
vref = 3.3
print('Tcore: %.1f C Vcore_ref: %.3f V Vbat: %.3f V Vref: %.3f V' % (adc.read_core_temp(), adc.read_core_vref(), adc.read_core_vbat(), vref))
print('freq: ', pyb.freq())
Sample mymain.py
import pyb
rtc = pyb.RTC()
rtc.wakeup(10000-96)
pyb.standby()