Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions Documentation/platforms/arm/rp23xx/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ SRAM Boot Working Requires external SWD debugger
PSRAM Working Three modes of heap allocation described below
TRNG Working Hardware RNG at /dev/random and /dev/urandom
Flash MTD Working Unused flash tail as an MTD device, answers BIOC_XIPBASE
Timer Working /dev/timerN on TIMER0/TIMER1, 1 us resolution
Tickless Working Optional, RP2350 TIMER via the alarm/oneshot
============== ============ =====

Installation
Expand Down Expand Up @@ -171,6 +173,51 @@ external PSRAM is configured as a separate user heap called
`psram` and can be used through the global variable
`g_psramheap` after including `rp23xx_heaps.h`

Timer
=====

The RP2350 has two system timer blocks, TIMER0 and TIMER1, each a
free-running 64-bit counter incremented once per microsecond. They are
independent of the ARM SysTick that drives the OS tick, so they are
available for application timers.

Enable the driver with `RP23XX_TIMER` (which selects `TIMER`), then turn on
each block you want: `RP23XX_TIMER0` registers `/dev/timer0` (TIMER0) and
`RP23XX_TIMER1` registers `/dev/timer1` (TIMER1). Each device implements the
standard NuttX timer lower-half: single-shot or periodic timeouts with 1 us
resolution and a maximum interval of 2^32 - 1 us (about 71.5 minutes), driven
by ALARM0 of the block.

A block claimed by the tickless-OS oneshot
(`RP23XX_SYSTIMER_TICKLESS`) is removed from the choices above, so a
`/dev/timer` device and the tickless OS time source never collide on the same
block -- you can run both at once (e.g. tickless on TIMER0, `/dev/timer1` on
TIMER1). With tickless disabled, both `/dev/timer0` and
`/dev/timer1` are available. The `examples/timer` application can exercise a
device; point `CONFIG_EXAMPLES_TIMER_DEVNAME` at the block you enabled.

Tickless OS
===========

By default the OS tick is a periodic ARM SysTick interrupt. The RP2350 can
instead run tickless, driving the scheduler from a hardware alarm so the CPU
is only interrupted when a timer actually expires.

Enable `RP23XX_SYSTIMER_TICKLESS` together with `SCHED_TICKLESS` and
`SCHED_TICKLESS_ALARM`. Choose the timer block with the "Tickless timer
block" option (`RP23XX_SYSTIMER_TICKLESS_TIMER0`, the default, or
`RP23XX_SYSTIMER_TICKLESS_TIMER1`). The system time is then taken from that
block -- a free-running 64-bit microsecond counter -- and its ALARM0 provides
the next-event interrupt through the alarm/oneshot lower-half
(`rp23xx_oneshot.c`). Because the 64-bit counter is the monotonic time base,
timekeeping is exact to 1 us, and a single alarm can schedule up to ~71
minutes ahead, so long idle periods need no wake-ups. This is mutually
exclusive with `RP23XX_SYSTIMER_SYSTICK`.

The block chosen here is claimed exclusively by the scheduler and is removed
from the `/dev/timer` driver's choices (see the Timer section), so the tickless
clock and a `/dev/timer` device can run at the same time on different blocks.

Programming
============

Expand Down
1 change: 1 addition & 0 deletions arch/arm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ config ARCH_CHIP_RP23XX
select ARM_HAVE_DSP
select ARCH_HAVE_FPU
select ARCH_HAVE_CUSTOM_TESTSET
select ARCH_HAVE_TICKLESS
select ARCH_BOARD_COMMON
---help---
Raspberry Pi RP23XX architectures (ARM dual Cortex-M33 or RISC-V).
Expand Down
8 changes: 8 additions & 0 deletions arch/arm/src/rp23xx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,14 @@ if(CONFIG_RP23XX_PWM)
list(APPEND SRCS rp23xx_pwm.c)
endif()

if(CONFIG_RP23XX_TIMER)
list(APPEND SRCS rp23xx_timer.c)
endif()

if(CONFIG_RP23XX_SYSTIMER_TICKLESS)
list(APPEND SRCS rp23xx_oneshot.c)
endif()

if(CONFIG_RP23XX_I2C)
list(APPEND SRCS rp23xx_i2c.c)
endif()
Expand Down
74 changes: 74 additions & 0 deletions arch/arm/src/rp23xx/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,40 @@ config RP23XX_SYSTIMER_SYSTICK
---help---
Use ARM SysTick.

config RP23XX_SYSTIMER_TICKLESS
bool "Tickless OS using the RP2350 hardware TIMER"
default n
depends on !RP23XX_SYSTIMER_SYSTICK
select ONESHOT
select ONESHOT_COUNT
select ALARM_ARCH
---help---
Use an RP2350 system timer block (TIMER0 or TIMER1, chosen below)
as the OS time source and drive the scheduler through the
alarm/oneshot interface. Each block is a free-running 64-bit
microsecond counter, independent of the ARM SysTick. This is the
arch-side support required by CONFIG_SCHED_TICKLESS (with
CONFIG_SCHED_TICKLESS_ALARM) and gives long tickless idle intervals
-- up to ~71 minutes per alarm -- with 1 us resolution.

choice
prompt "Tickless timer block"
default RP23XX_SYSTIMER_TICKLESS_TIMER0
depends on RP23XX_SYSTIMER_TICKLESS
---help---
Which RP2350 system timer block drives the tickless OS clock. The
block used here is claimed exclusively by the scheduler; the other
block stays available for the /dev/timer driver (CONFIG_RP23XX_TIMER),
so both features can be enabled at once.

config RP23XX_SYSTIMER_TICKLESS_TIMER0
bool "TIMER0"

config RP23XX_SYSTIMER_TICKLESS_TIMER1
bool "TIMER1"

endchoice

#####################################################################
# UART Configuration
#####################################################################
Expand Down Expand Up @@ -736,6 +770,46 @@ config RP23XX_SPISD_SPI_CH

endif # SPISD Configuration

#####################################################################
# Timer Configuration
#####################################################################

menuconfig RP23XX_TIMER
bool "System timer (/dev/timer) support"
default n
select TIMER
---help---
Build the /dev/timerN driver on top of the RP2350 system timer
blocks (TIMER0 and TIMER1). Each block is a free-running 64-bit
microsecond counter, independent of the ARM SysTick that drives
the OS tick, so it is available for application timers. The
driver uses ALARM0 of a block for a single-shot or periodic
timeout with 1 us resolution.

Enable one or both blocks below. A block claimed by the tickless
oneshot (CONFIG_RP23XX_SYSTIMER_TICKLESS) is removed from the list
so the two features never collide on the same block.

if RP23XX_TIMER

config RP23XX_TIMER0
bool "Register TIMER0 as /dev/timer0"
default y
depends on !RP23XX_SYSTIMER_TICKLESS_TIMER0
---help---
Bind the TIMER0 block to /dev/timer0. Unavailable when the
tickless oneshot is configured to use TIMER0.

config RP23XX_TIMER1
bool "Register TIMER1 as /dev/timer1"
default n
depends on !RP23XX_SYSTIMER_TICKLESS_TIMER1
---help---
Bind the TIMER1 block to /dev/timer1. Unavailable when the
tickless oneshot is configured to use TIMER1.

endif # RP23XX_TIMER

#####################################################################
# ADC Configuration
#####################################################################
Expand Down
8 changes: 8 additions & 0 deletions arch/arm/src/rp23xx/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ ifeq ($(CONFIG_RP23XX_PWM),y)
CHIP_CSRCS += rp23xx_pwm.c
endif

ifeq ($(CONFIG_RP23XX_TIMER),y)
CHIP_CSRCS += rp23xx_timer.c
endif

ifeq ($(CONFIG_RP23XX_SYSTIMER_TICKLESS),y)
CHIP_CSRCS += rp23xx_oneshot.c
endif

ifeq ($(CONFIG_RP23XX_I2C),y)
CHIP_CSRCS += rp23xx_i2c.c
endif
Expand Down
Loading
Loading