AON tick generation: selection of the LPOSC as timer source when XOSC is not the reference clock #3107
Labels
No labels
bazel
bluetooth
board settings
boot_stage2
bug
build
c++
can't reproduce
clang
clib-interface
cmsis
code cleanliness
code size
compiler version issues
cyw43_driver
debug
discussion
documentation
duplicate
dynamic_clock
elf2uf2
enhancement
errata
filesystem
flash layout
floating point
FreeRTOS
hardware_adc
hardware_claim
hardware_clocks
hardware_dma
hardware_exception
hardware_flash
hardware_gpio
hardware_i2c
hardware_irq
hardware_pio
hardware_pwm
hardware_rcp
hardware_rtc
hardware_spi
hardware_sync
hardware_uart
hardware_vreg
hardware_watchdog
hardware_xosc
help wanted
host
IAR
installation
invalid
linker scripts
lto
lwip
mbedtls
missing API
needs reporter detail
networking
newlib
newlib-multicore
non-c
non-cmake
non-gcc
openocd
orphan PR
OS integration
pico_async_context
pico_base
pico_binary_info
pico_flash
picolibc
pico_lwip
pico_malloc
pico_multicore
pico_printf
pico_runtime
pico_stdio
pico_stdio_usb
pico_sync
pico_time
pico_util
pioasm
port
question
review
review2
rtos interop
runtime init
static library
svd
test
tinyusb
vscode
wifi integration
wontfix
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
gh-raspberrypi/pico-sdk#3107
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Board: Pico 2 (RP2350)
SDK version: 2.3.0 (current master branch)
In
rp2_common/pico_aon_timer/aon_timer.c, theaon_timer_startfunction always uses the XOSC as reference clock to generate ticks. In some experiments I did, I needed to turn off the XOSC and change the reference clock. The datasheet (12.10.5.1.) mentions the possibility to use the LPOSC instead of the XOSC to generate ticks when the latter isn't in use. The sdk provides a method to this end:powman_timer_set_1khz_tick_source_lposc(). The datasheet (12.10.5.3.) also mentions theCLK_REF_SELECTEDregister which specifies which clock source is used as reference clock.In my experiments, I ended up modying the
aon_timer_startfunction like the following:The code above was working for me when using the ROSC or LPOSC as reference clocks. The only issue was that when using the LPOSC to generate ticks, the default frequency specified by the sdk (32768) was slightly too fast compared to the one I measured on my board (between 29 and 30kHz). So maybe it would be relevant to let the user specify its own frequency when using the LPOSC as 1khz tick instead of relying on the default.
Note that I haven't found the
CLK_REF_SELECTEDregister inclock_hwso I couldn't use this struct to access the value. This is why I was reading the value directly from the memory without using theclock_hwstruct.I believe this is what the
TRIMregister in the LPOSC is for - see 8.4.1. in the datasheet. (I think the intention is that you'd measure the frequency of the LPOSC whilst still running from the XOSC, and then trim the LPOSC so that it's running as close as possible to 32768 Hz, before then switching over to the LPOSC? I only know this because it previously came up in #2856 )I can't say for certain, but looking at https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2350/hardware_regs/include/hardware/regs/clocks.h and https://github.com/raspberrypi/pico-sdk/blob/develop/src/rp2350/hardware_structs/include/hardware/structs/clocks.h it looks like you might be able to get the value you need from
clocks_hw->clk[clk_ref].selected? (see also https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/pico_runtime_init/runtime_init_clocks.c#L56 )P.S. It's probably not worth it, but I guess you could replace your
0x4with1 << CLOCKS_CLK_REF_CTRL_SRC_VALUE_XOSC_CLKSRC😉I don’t think you need to use
TRIMin this scenario - as of SDK 2.3.0 there is a new weakpowman_timer_get_lposc_calib_freqwhich reads the frequency from the OTP by default, but you can override that function to return the measured frequency instead (seehardware_powmanin the release notes).I updated my code, thanks!
It turns out that on my board, the OTP value for the LPOSC frequency returns 61.364 kHz, which is above the upper boundary specified by the sdk (40 kHz). Due to that,
powman_timer_get_lposc_calib_freq()returns 0. Because of that,powman_timer_set_1khz_tick_source_lposc_with_hzends up not modifying the LPOSC frequency at all (which stays at 32.786 kHz).I am not sure why I have such a high value from the OTP. So I ended up overriding the
powman_timer_get_lposc_calib_freq()function and returning the value from the frequency counter. This way I get much better timings. Thanks!Also, is the code in my first post worth a pull request? It may be too ad-hoc and need more thought to it but if it is relevant I can open one?
Can you post a picture of the topside of the Pico 2 with the chip markings visible? You may need to provide angled illumination.
I think a better way would be a new inline
powman_timer_set_1khz_tick_source_defaultfunction, which can be toggled using a#definebetween XOSC and LPOSC, becausepowman_timer_set_1khz_tick_source_xoscis used in multiple places in the SDK - I'll submit a PR to do thatI have opened a PR to do that https://github.com/raspberrypi/pico-sdk/pull/3110 - should allow setting
PICO_POWMAN_DEFAULT_TICK_SOURCE_XOSC=0to use the LPOSC instead inaon_timer_startandpico_low_power