Thanks to visit codestin.com
Credit goes to www.scribd.com

0% found this document useful (0 votes)
80 views20 pages

rp23 Part60

Uploaded by

vuz5udyg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
80 views20 pages

rp23 Part60

Uploaded by

vuz5udyg
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

RP2350 Datasheet

60 }
61
62 int main() {
63 stdio_init_all();
64 printf("Timer lowlevel!\n");
65
66 // Set alarm every 2 seconds
67 while (1) {
68 alarm_fired = false;
69 alarm_in_us(1000000 * 2);
70 // Wait for alarm to fire
71 while (!alarm_fired);
72 }
73 }

12.8.4.3. Busy wait

If you don’t want to use an alarm to wait for a period of time, use a while loop instead. The SDK provides various
busy_wait_ functions to do this:

SDK: https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_timer/timer.c Lines 77 - 122

77 void timer_busy_wait_us_32(timer_hw_t *timer, uint32_t delay_us) {


78 if (0 <= (int32_t)delay_us) {
79 // we only allow 31 bits, otherwise we could have a race in the loop below with
80 // values very close to 2^32
81 uint32_t start = timer->timerawl;
82 while (timer->timerawl - start < delay_us) {
83 tight_loop_contents();
84 }
85 } else {
86 busy_wait_us(delay_us);
87 }
88 }
89
90 void timer_busy_wait_us(timer_hw_t *timer, uint64_t delay_us) {
91 uint64_t base = timer_time_us_64(timer);
92 uint64_t target = base + delay_us;
93 if (target < base) {
94 target = (uint64_t)-1;
95 }
96 absolute_time_t t;
97 update_us_since_boot(&t, target);
98 timer_busy_wait_until(timer, t);
99 }
100
101 void timer_busy_wait_ms(timer_hw_t *timer, uint32_t delay_ms)
102 {
103 if (delay_ms <= 0x7fffffffu / 1000) {
104 timer_busy_wait_us_32(timer, delay_ms * 1000);
105 } else {
106 timer_busy_wait_us(timer, delay_ms * 1000ull);
107 }
108 }
109
110 void timer_busy_wait_until(timer_hw_t *timer, absolute_time_t t) {
111 uint64_t target = to_us_since_boot(t);
112 uint32_t hi_target = (uint32_t)(target >> 32u);
113 uint32_t hi = timer->timerawh;
114 while (hi < hi_target) {

12.8. System Timers 1180


RP2350 Datasheet

115 hi = timer->timerawh;
116 tight_loop_contents();
117 }
118 while (hi == hi_target && timer->timerawl < (uint32_t) target) {
119 hi = timer->timerawh;
120 tight_loop_contents();
121 }
122 }

12.8.4.4. Complete example using SDK

Pico Examples: https://github.com/raspberrypi/pico-examples/blob/master/timer/hello_timer/hello_timer.c Lines 11 - 57

11 volatile bool timer_fired = false;


12
13 int64_t alarm_callback(alarm_id_t id, __unused void *user_data) {
14 printf("Timer %d fired!\n", (int) id);
15 timer_fired = true;
16 // Can return a value here in us to fire in the future
17 return 0;
18 }
19
20 bool repeating_timer_callback(__unused struct repeating_timer *t) {
21 printf("Repeat at %lld\n", time_us_64());
22 return true;
23 }
24
25 int main() {
26 stdio_init_all();
27 printf("Hello Timer!\n");
28
29 // Call alarm_callback in 2 seconds
30 add_alarm_in_ms(2000, alarm_callback, NULL, false);
31
32 // Wait for alarm callback to set timer_fired
33 while (!timer_fired) {
34 tight_loop_contents();
35 }
36
37 // Create a repeating timer that calls repeating_timer_callback.
38 // If the delay is > 0 then this is the delay between the previous callback ending and the
next starting.
39 // If the delay is negative (see below) then the next call to the callback will be exactly
500ms after the
40 // start of the call to the last callback
41 struct repeating_timer timer;
42 add_repeating_timer_ms(500, repeating_timer_callback, NULL, &timer);
43 sleep_ms(3000);
44 bool cancelled = cancel_repeating_timer(&timer);
45 printf("cancelled... %d\n", cancelled);
46 sleep_ms(2000);
47
48 // Negative delay so means we will call repeating_timer_callback, and call it again
49 // 500ms later regardless of how long the callback took to execute
50 add_repeating_timer_ms(-500, repeating_timer_callback, NULL, &timer);
51 sleep_ms(3000);
52 cancelled = cancel_repeating_timer(&timer);
53 printf("cancelled... %d\n", cancelled);
54 sleep_ms(2000);
55 printf("Done\n");

12.8. System Timers 1181


RP2350 Datasheet

56 return 0;
57 }

12.8.5. List of Registers


The TIMER0 and TIMER1 registers start at base addresses of 0x400b0000 and 0x400b8000 respectively (defined as
TIMER0_BASE and TIMER1_BASE in SDK).

Table 1226. List of


Offset Name Info
TIMER registers

0x00 TIMEHW Write to bits 63:32 of time


always write timelw before timehw

0x04 TIMELW Write to bits 31:0 of time


writes do not get copied to time until timehw is written

0x08 TIMEHR Read from bits 63:32 of time


always read timelr before timehr

0x0c TIMELR Read from bits 31:0 of time

0x10 ALARM0 Arm alarm 0, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM0 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

0x14 ALARM1 Arm alarm 1, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM1 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

0x18 ALARM2 Arm alarm 2, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM2 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

0x1c ALARM3 Arm alarm 3, and configure the time it will fire.
Once armed, the alarm fires when TIMER_ALARM3 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

0x20 ARMED Indicates the armed/disarmed status of each alarm.


A write to the corresponding ALARMx register arms the alarm.
Alarms automatically disarm upon firing, but writing ones here
will disarm immediately without waiting to fire.

0x24 TIMERAWH Raw read from bits 63:32 of time (no side effects)

0x28 TIMERAWL Raw read from bits 31:0 of time (no side effects)

0x2c DBGPAUSE Set bits high to enable pause when the corresponding debug
ports are active

0x30 PAUSE Set high to pause the timer

0x34 LOCKED Set locked bit to disable write access to timer


Once set, cannot be cleared (without a reset)

12.8. System Timers 1182


RP2350 Datasheet

Offset Name Info

0x38 SOURCE Selects the source for the timer. Defaults to the normal tick
configured in the ticks block (typically configured to 1
microsecond). Writing to 1 will ignore the tick and count clk_sys
cycles instead.

0x3c INTR Raw Interrupts

0x40 INTE Interrupt Enable

0x44 INTF Interrupt Force

0x48 INTS Interrupt status after masking & forcing

TIMER: TIMEHW Register


Offset: 0x00

Table 1227. TIMEHW


Bits Description Type Reset
Register

31:0 Write to bits 63:32 of time WF 0x00000000


always write timelw before timehw

TIMER: TIMELW Register


Offset: 0x04

Table 1228. TIMELW


Bits Description Type Reset
Register

31:0 Write to bits 31:0 of time WF 0x00000000


writes do not get copied to time until timehw is written

TIMER: TIMEHR Register


Offset: 0x08

Table 1229. TIMEHR


Bits Description Type Reset
Register

31:0 Read from bits 63:32 of time RO 0x00000000


always read timelr before timehr

TIMER: TIMELR Register


Offset: 0x0c

Table 1230. TIMELR


Bits Description Type Reset
Register

31:0 Read from bits 31:0 of time RO 0x00000000

TIMER: ALARM0 Register


Offset: 0x10

12.8. System Timers 1183


RP2350 Datasheet

Table 1231. ALARM0


Bits Description Type Reset
Register

31:0 Arm alarm 0, and configure the time it will fire. RW 0x00000000
Once armed, the alarm fires when TIMER_ALARM0 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

TIMER: ALARM1 Register


Offset: 0x14

Table 1232. ALARM1


Bits Description Type Reset
Register

31:0 Arm alarm 1, and configure the time it will fire. RW 0x00000000
Once armed, the alarm fires when TIMER_ALARM1 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

TIMER: ALARM2 Register


Offset: 0x18

Table 1233. ALARM2


Bits Description Type Reset
Register

31:0 Arm alarm 2, and configure the time it will fire. RW 0x00000000
Once armed, the alarm fires when TIMER_ALARM2 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

TIMER: ALARM3 Register


Offset: 0x1c

Table 1234. ALARM3


Bits Description Type Reset
Register

31:0 Arm alarm 3, and configure the time it will fire. RW 0x00000000
Once armed, the alarm fires when TIMER_ALARM3 == TIMELR.
The alarm will disarm itself once it fires, and can
be disarmed early using the ARMED status register.

TIMER: ARMED Register


Offset: 0x20

Table 1235. ARMED


Bits Description Type Reset
Register

31:4 Reserved. - -

3:0 Indicates the armed/disarmed status of each alarm. WC 0x0


A write to the corresponding ALARMx register arms the alarm.
Alarms automatically disarm upon firing, but writing ones here
will disarm immediately without waiting to fire.

TIMER: TIMERAWH Register


Offset: 0x24

12.8. System Timers 1184


RP2350 Datasheet

Table 1236.
Bits Description Type Reset
TIMERAWH Register

31:0 Raw read from bits 63:32 of time (no side effects) RO 0x00000000

TIMER: TIMERAWL Register


Offset: 0x28

Table 1237.
Bits Description Type Reset
TIMERAWL Register

31:0 Raw read from bits 31:0 of time (no side effects) RO 0x00000000

TIMER: DBGPAUSE Register


Offset: 0x2c

Description
Set bits high to enable pause when the corresponding debug ports are active

Table 1238.
Bits Description Type Reset
DBGPAUSE Register

31:3 Reserved. - -

2 DBG1: Pause when processor 1 is in debug mode RW 0x1

1 DBG0: Pause when processor 0 is in debug mode RW 0x1

0 Reserved. - -

TIMER: PAUSE Register


Offset: 0x30

Table 1239. PAUSE


Bits Description Type Reset
Register

31:1 Reserved. - -

0 Set high to pause the timer RW 0x0

TIMER: LOCKED Register


Offset: 0x34

Table 1240. LOCKED


Bits Description Type Reset
Register

31:1 Reserved. - -

0 Set locked bit to disable write access to timer RW 0x0


Once set, cannot be cleared (without a reset)

TIMER: SOURCE Register


Offset: 0x38

Description
Selects the source for the timer. Defaults to the normal tick configured in the ticks block (typically configured to 1
microsecond). Writing to 1 will ignore the tick and count clk_sys cycles instead.

Table 1241. SOURCE


Bits Description Type Reset
Register

31:1 Reserved. - -

0 CLK_SYS RW 0x0

12.8. System Timers 1185


RP2350 Datasheet

Bits Description Type Reset

Enumerated values:

0x0 → TICK

0x1 → CLK_SYS

TIMER: INTR Register


Offset: 0x3c

Description
Raw Interrupts

Table 1242. INTR


Bits Description Type Reset
Register

31:4 Reserved. - -

3 ALARM_3 WC 0x0

2 ALARM_2 WC 0x0

1 ALARM_1 WC 0x0

0 ALARM_0 WC 0x0

TIMER: INTE Register


Offset: 0x40

Description
Interrupt Enable

Table 1243. INTE


Bits Description Type Reset
Register

31:4 Reserved. - -

3 ALARM_3 RW 0x0

2 ALARM_2 RW 0x0

1 ALARM_1 RW 0x0

0 ALARM_0 RW 0x0

TIMER: INTF Register


Offset: 0x44

Description
Interrupt Force

Table 1244. INTF


Bits Description Type Reset
Register

31:4 Reserved. - -

3 ALARM_3 RW 0x0

2 ALARM_2 RW 0x0

1 ALARM_1 RW 0x0

0 ALARM_0 RW 0x0

TIMER: INTS Register

12.8. System Timers 1186


RP2350 Datasheet

Offset: 0x48

Description
Interrupt status after masking & forcing

Table 1245. INTS


Bits Description Type Reset
Register

31:4 Reserved. - -

3 ALARM_3 RO 0x0

2 ALARM_2 RO 0x0

1 ALARM_1 RO 0x0

0 ALARM_0 RO 0x0

12.9. Watchdog

12.9.1. Overview
The watchdog is a countdown timer which can be configured to reset selected components when it reaches zero. In
normal operation it is periodically loaded with a non-zero value to prevent the reset occuring. If the chip locks up or
software gets stuck in a loop, the reset allows recovery.

The watchdog is reset by any chip-level reset (see Section 7.3). The sources of the chip-level reset are:

• Power-On Reset (POR)


• Brown-out Detection (BOD)
• External Reset (from the RUN pin)
• Debugger Reset Request
• Rescue Debug Port Request
• Watchdog - a chip-level reset triggered by the Watchdog will reset the Watchdog
• SWCORE powerdown
• Glitch Detector
• Debugger HZD Reset Request
These are described in Section 7.3.3.

12.9.2. Changes from RP2040


On RP2040, the watchdog contained a tick generator used to generate a 1μs tick for the watchdog. This was also
distributed to the system timer. On RP2350, the watchdog instead takes a tick input from the system-level ticks block.
See Section 8.5.

As on RP2040 the watchdog can trigger a PSM (Power-on State Machine) sequence to reset system components or it
can be used to reset selected subsystem components. On RP2350, the watchdog can also trigger a chip level reset.

12.9.3. Watchdog Counter


The watchdog counter is loaded by the LOAD register. The current value can be seen in CTRL.TIME.

12.9. Watchdog 1187


RP2350 Datasheet

12.9.4. Control Watchdog Reset Levels


To control the level of reset triggered by a watchdog event, use the registers outside the watchdog register block:

• POWMAN_WATCHDOG allows the watchdog to trigger chip level resets


• PSM_WDSEL allows the watchdog to trigger system resets by running a full or partial PSM sequence (Power-on State
Machine)

• RESETS_WDSEL allows the watchdog to trigger subsystem resets


These are described in the Resets section, see Chapter 7.

12.9.5. Scratch Registers


The watchdog contains eight 32-bit scratch registers that can store information between soft resets of the chip. The
scratch registers reset when:

• the watchdog is used to to trigger a chip level reset


• a rst_n_run event occurs, triggered by toggling the RUN pin or cycling the digital core supply (DVDD)
The bootrom checks the watchdog scratch registers for a magic number on boot. You can use this to soft reset the chip
into user-specified code. See Section 5.2.4 for more information.

 NOTE

Additional general-purpose scratch registers are available in POWMAN SCRATCH0 through SCRATCH7. These
registers also survive power cycling the switched core domain.

12.9.6. Programmer’s Model


The SDK provides a hardware_watchdog driver to control the watchdog.

12.9.6.1. Enabling the watchdog

SDK: https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_watchdog/watchdog.c Lines 42 - 74

42 // Helper function used by both watchdog_enable and watchdog_reboot


43 void _watchdog_enable(uint32_t delay_ms, bool pause_on_debug) {
44 valid_params_if(HARDWARE_WATCHDOG, delay_ms <= WATCHDOG_LOAD_BITS / (1000 *
WATCHDOG_XFACTOR));
45 hw_clear_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);
46
47 // Reset everything apart from ROSC and XOSC
48 hw_set_bits(&psm_hw->wdsel, PSM_WDSEL_BITS & ~(PSM_WDSEL_ROSC_BITS |
PSM_WDSEL_XOSC_BITS));
49
50 uint32_t dbg_bits = WATCHDOG_CTRL_PAUSE_DBG0_BITS |
51 WATCHDOG_CTRL_PAUSE_DBG1_BITS |
52 WATCHDOG_CTRL_PAUSE_JTAG_BITS;
53
54 if (pause_on_debug) {
55 hw_set_bits(&watchdog_hw->ctrl, dbg_bits);
56 } else {
57 hw_clear_bits(&watchdog_hw->ctrl, dbg_bits);
58 }
59

12.9. Watchdog 1188


RP2350 Datasheet

60 if (!delay_ms) {
61 hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_TRIGGER_BITS);
62 } else {
63 load_value = delay_ms * 1000;
64 if (load_value > WATCHDOG_LOAD_BITS)
65 load_value = WATCHDOG_LOAD_BITS;
66
67 watchdog_update();
68
69 hw_set_bits(&watchdog_hw->ctrl, WATCHDOG_CTRL_ENABLE_BITS);
70 }
71 }

12.9.6.2. Updating the watchdog counter

SDK: https://github.com/raspberrypi/pico-sdk/blob/master/src/rp2_common/hardware_watchdog/watchdog.c Lines 24 - 28

24 static uint32_t load_value;


25
26 void watchdog_update(void) {
27 watchdog_hw->load = load_value;
28 }

12.9.6.3. Usage

The Pico Examples repository provides a hello_watchdog example that uses the hardware_watchdog to demonstrate use of
the watchdog.

Pico Examples: https://github.com/raspberrypi/pico-examples/blob/master/watchdog/hello_watchdog/hello_watchdog.c Lines 11 - 33

11 int main() {
12 stdio_init_all();
13
14 if (watchdog_caused_reboot()) {
15 printf("Rebooted by Watchdog!\n");
16 return 0;
17 } else {
18 printf("Clean boot\n");
19 }
20
21 // Enable the watchdog, requiring the watchdog to be updated every 100ms or the chip will
reboot
22 // second arg is pause on debug which means the watchdog will pause when stepping through
code
23 watchdog_enable(100, 1);
24
25 for (uint i = 0; i < 5; i++) {
26 printf("Updating watchdog %d\n", i);
27 watchdog_update();
28 }
29
30 // Wait in an infinite loop and don't update the watchdog so it reboots us
31 printf("Waiting to be rebooted by watchdog\n");
32 while(1);
33 }

12.9. Watchdog 1189


RP2350 Datasheet

12.9.7. List of Registers


The watchdog registers start at a base address of 0x400d8000 (defined as WATCHDOG_BASE in SDK).

Table 1246. List of


Offset Name Info
WATCHDOG registers

0x00 CTRL Watchdog control


The rst_wdsel register determines which subsystems are reset
when the watchdog is triggered.
The watchdog can be triggered in software.

0x04 LOAD Load the watchdog timer. The maximum setting is 0xffffff which
corresponds to approximately 16 seconds.

0x08 REASON Logs the reason for the last reset. Both bits are zero for the case
of a hardware reset.

Additionally, as of RP2350, a debugger warm reset of either core


(SYSRESETREQ or hartreset) will also clear the watchdog reason
register, so that software loaded under the debugger following a
watchdog timeout will not continue to see the timeout condition.

0x0c SCRATCH0 Scratch register. Information persists through soft reset of the
chip.

0x10 SCRATCH1 Scratch register. Information persists through soft reset of the
chip.

0x14 SCRATCH2 Scratch register. Information persists through soft reset of the
chip.

0x18 SCRATCH3 Scratch register. Information persists through soft reset of the
chip.

0x1c SCRATCH4 Scratch register. Information persists through soft reset of the
chip.

0x20 SCRATCH5 Scratch register. Information persists through soft reset of the
chip.

0x24 SCRATCH6 Scratch register. Information persists through soft reset of the
chip.

0x28 SCRATCH7 Scratch register. Information persists through soft reset of the
chip.

WATCHDOG: CTRL Register


Offset: 0x00

Description
Watchdog control
The rst_wdsel register determines which subsystems are reset when the watchdog is triggered.
The watchdog can be triggered in software.

Table 1247. CTRL


Bits Description Type Reset
Register

31 TRIGGER: Trigger a watchdog reset SC 0x0

30 ENABLE: When not enabled the watchdog timer is paused RW 0x0

29:27 Reserved. - -

26 PAUSE_DBG1: Pause the watchdog timer when processor 1 is in debug mode RW 0x1

12.9. Watchdog 1190


RP2350 Datasheet

Bits Description Type Reset

25 PAUSE_DBG0: Pause the watchdog timer when processor 0 is in debug mode RW 0x1

24 PAUSE_JTAG: Pause the watchdog timer when JTAG is accessing the bus RW 0x1
fabric

23:0 TIME: Indicates the time in usec before a watchdog reset will be triggered RO 0x000000

WATCHDOG: LOAD Register


Offset: 0x04

Table 1248. LOAD


Bits Description Type Reset
Register

31:24 Reserved. - -

23:0 Load the watchdog timer. The maximum setting is 0xffffff which corresponds WF 0x000000
to approximately 16 seconds.

WATCHDOG: REASON Register


Offset: 0x08

Description
Logs the reason for the last reset. Both bits are zero for the case of a hardware reset.

Additionally, as of RP2350, a debugger warm reset of either core (SYSRESETREQ or hartreset) will also clear the
watchdog reason register, so that software loaded under the debugger following a watchdog timeout will not continue
to see the timeout condition.

Table 1249. REASON


Bits Description Type Reset
Register

31:2 Reserved. - -

1 FORCE RO 0x0

0 TIMER RO 0x0

WATCHDOG: SCRATCH0, SCRATCH1, …, SCRATCH6, SCRATCH7 Registers


Offsets: 0x0c, 0x10, …, 0x24, 0x28

Table 1250.
Bits Description Type Reset
SCRATCH0,
SCRATCH1, …,
31:0 Scratch register. Information persists through soft reset of the chip. RW 0x00000000
SCRATCH6,
SCRATCH7 Registers

12.10. Always-On Timer

12.10.1. Overview
The always-on timer (AON Timer) is the only timer that operates in all power modes. It can be used as a real-time
counter or an interval timer and incorporates an alarm which can be used to trigger a power-up event or an interrupt. It
incorporates a 64-bit counter intended to count 1ms ticks, but the tick generator can be configured to run faster or
slower if required. Note that the AON Timer tick generator is independent of all other tick generators on the chip.

The default tick source is the 32kHz on-chip low-power oscillator (LPOSC), see Section 8.4. The LPOSC frequency is not
precise and may vary with voltage and temperature. When the chip core is powered, the tick source can be switched to
the on-chip crystal oscillator (XOSC) for greater precision. If greater precision is also required when the chip core is

12.10. Always-On Timer 1191


RP2350 Datasheet

unpowered, then a 32kHz clock or a 1ms tick can be supplied from an external source. Alternatively, the AON Timer can
be synchronised to an external 1Hz source.

The AON Timer is integrated with the power manager (POWMAN) and shares the POWMAN register block. Writes are
limited to 16 bits because a key (0x5afe) is required in the top 16 bits to prevent erroneous writes from locking up the
chip. Most AON Timer registers can be enabled for write by Non-secure software, unlike other POWMAN registers.
However, the registers used to select an external clock, select an external tick source, and enable power-up on alarm
can only be written by Secure software.

12.10.2. Changes from RP2040


The RP2040 Real Time Clock (RTC) is not used in RP2350. Instead, RP2350 has a timer in the Always-On power domain
which is used for scheduling power-up events and can also be used as a real-time counter. The AON Timer works
differently from the RP2040 RTC. It counts milliseconds to 64 bits and this value can be used to calculate the date and
time in software if required.

12.10.3. Accessing the AON Timer


To start and stop the AON Timer, write to TIMER.RUN.

To read the current 64-bit AON Timer value, use the following 2 × 32-bit read-only registers:

• READ_TIME_UPPER
• READ_TIME_LOWER
Because the AON Timer can increment during a read, use the following procedure to protect against erroneous reads:

1. Read READ_TIME_UPPER

2. Read READ_TIME_LOWER

3. Read READ_TIME_UPPER

4. If the READ_TIME_UPPER value changes between steps 1 and 3, repeat the whole procedure

When used as a real time clock, the 64-bit time value is set using 4 × 16-bit registers. These registers can only be written
when the AON Timer is stopped by writing a 0 to TIMER.RUN:

• SET_TIME_63TO48
• SET_TIME_47TO32
• SET_TIME_31TO16
• SET_TIME_15TO0
These registers cannot be used to read the time value.

When used as an interval timer, write a 1 to TIMER.CLEAR to clear the timer value. It is not necessary to stop the AON
Timer to do this. The TIMER.CLEAR register is self-clearing: it returns to 0 when the operation completes. This allows
easy implementation of an alarm that wakes the chip or generates an interrupt at regular intervals.

12.10.4. Using the Alarm


To set the alarm time, use the following 4 × 16-bit registers:

• ALARM_TIME_63TO48
• ALARM_TIME_47TO32

12.10. Always-On Timer 1192


RP2350 Datasheet

• ALARM_TIME_31TO16
• ALARM_TIME_15TO0
To avoid false alarms, disable the alarm before setting the alarm time.

To enable the alarm, use TIMER.ALARM_ENAB.

When the alarm fires, the AON Timer sets the alarm status flag TIMER.ALARM.

To clear the alarm status flag, write a 1 to the alarm status flag.

To configure the alarm to trigger a power-up, set TIMER.PWRUP_ON_ALARM. This feature is not available to Non-secure
code.

The alarm can be configured to trigger an interrupt. The interrupt is handled in the standard way using the following
register fields:

• INTR.TIMER - raw interrupt


• INTE.TIMER - interrupt enable
• INTF.TIMER - force interrupt
• INTS.TIMER - interrupt status

12.10.5. Selecting the AON Timer Tick Source


The AON Timer indicates the current configuration with read-only flags. Table 1251 provides a list of sources supported
by the 1kHz AON Timer tick.

Table 1251. AON


Tick source Read-only flag
Timer tick generators

LPOSC clock division TIMER.USING_LPOSC

XOSC clock division TIMER.USING_XOSC

external 1kHz tick TIMER.USING_GPIO_1KHZ

 NOTE

The LPOSC clock can be substituted by an external 32kHz clock.

12.10.5.1. Using LPOSC as the AON Timer Tick Source

LPOSC is the default source and can be used in all power modes. It nominally runs at 32.768kHz and can only be tuned
to 1% accuracy. The AON Timer derives the 1ms tick from the LPOSC using a 6.16 bit fractional divider whose divisor is
initialised to 32.768. The divisor can be modified to achieve greater accuracy. Because the LPOSC frequency varies with
supply voltage and temperature, accuracy is limited unless supply voltage and temperature are stable. To modify the
divisor, write to the following registers:

• LPOSC_FREQ_KHZ_INT (default value: 32)


• LPOSC_FREQ_KHZ_FRAC (default value: 0.768)
These registers should only be written when TIMER.RUN = 0 or TIMER.USING_LPOSC = 0.

If the tick source is not LPOSC, you can switch it back to LPOSC by writing a 1 to TIMER.USE_LPOSC. It is not necessary
to stop the AON Timer to do this. The newly selected tick will be synchronised to the current tick, so the operation may
take up to 1 tick cycle (1ms in normal operation). When the operation is complete, TIMER.USE_LPOSC will self-clear and
TIMER.USING_LPOSC will be set. Due to sampling, a small error of up to 2 periods of the newly selected clock will be
subtracted from the time. When switching to LPOSC at 32kHz, an error of up to 62μs will be subtracted.

12.10. Always-On Timer 1193


RP2350 Datasheet

12.10.5.2. Using an External Clock in Place of LPOSC

If LPOSC is not sufficiently accurate, an external 32.768kHz clock can be used. This will be multiplexed onto the internal
low-power clock and will therefore drive all components that are driven by that clock, including the power sequencer
components. The external clock can be used in all power modes. When an external clock is in use, you can stop the
LPOSC (see Section 8.4).

To select an external 32kHz clock:

1. Configure the GPIO source as described in Section 12.10.7.

2. Switch to the external LPOSC by setting EXT_TIME_REF.DRIVE_LPCK. This register should only be written when
TIMER.RUN = 0 and the power sequencer is inactive. You can only write to this register from Secure code.

The external 32kHz clock replaces the clock from LPOSC. Therefore the same registers are used for AON Timer
configuration (see Section 12.10.5.1):

• TIMER.USE_LPOSC
• TIMER.USING_LPOSC
• LPOSC_FREQ_KHZ_INT
• LPOSC_FREQ_KHZ_FRAC

12.10.5.3. Using the XOSC as the AON Timer Tick Source

The XOSC clock is provided via the reference clock (clk_ref). The user must ensure the reference clock is being driven
from the XOSC before selecting it as the source of the AON Timer tick. This is the normal configuration following boot.
To check, look for CLK_REF_SELECTED = 0x4. The reference clock may be a divided version of the XOSC. The divisor
defaults to 1 and can be read from CLK_REF_DIV.INT. If the chip is operated with a faster XOSC, the clock sent to the
AON Timer must not exceed 29MHz.

The AON Timer derives the 1ms tick from the XOSC using a 16.16 bit fractional divider whose divisor is initialised to
12000.0. This assumes a 12MHz crystal is used and the reference clock divisor is 1. If that is not the case, the divisor in
the AON Timer can be modified by writing to the following registers:

• XOSC_FREQ_KHZ_INT (default value: 12000)


• XOSC_FREQ_KHZ_FRAC (default value: 0)
These registers should only be written when TIMER.RUN = 0 or TIMER.USING_XOSC = 0.

To select the XOSC as the AON Timer tick source, write a 1 to TIMER.USE_XOSC. It is not necessary to stop the AON
Timer to do this. The newly selected tick will be synchronised to the current tick, so the operation may take up to 1 tick
cycle (1ms in normal operation). When the operation is complete TIMER.USE_XOSC will self-clear and
TIMER.USING_XOSC will be set. Due to sampling, a small error of up to 2 periods of the newly selected clock will be
subtracted from the time. When switching to XOSC at 12MHz an error of up to 167ns will be subtracted.

When the chip core is powered down the XOSC will stop. If TIMER.USING_XOSC is set, the power-down sequencer
automatically reverts to TIMER.USING_LPOSC before the XOSC stops.

12.10.5.4. Using an External 1ms Tick Source

To select an external 1ms tick source, configure the GPIO source as described in Section 12.10.7. Then, write a 1 to
TIMER.USE_GPIO_1KHZ. It is not necessary to stop the AON Timer to do this, however the newly selected tick will not be
synchronised to the current tick, so the operation so the operation will advance the time by up to 1ms. If using an
external 1ms tick it is recommended to set the time after selecting the source. When the operation is complete
TIMER.USE_GPIO_1KHZ will self-clear and TIMER.USING_GPIO_1KHZ will be set.

The tick is triggered from the falling edge of the selected GPIO. For correct sampling, the GPIO pulse width and interval
must both be greater than the period of LPOSC (>31us). This limits the maximum frequency of the external tick to

12.10. Always-On Timer 1194


RP2350 Datasheet

16kHz.

The external 1ms tick can be used in all power modes.

12.10.6. Synchronising the AON Timer to an External 1Hz Clock


In applications that use GPS, a 1s tick may be available. This can be used to synchronise the AON Timer and thus
compensate for inaccuracy in the LPOSC frequency. It can be used with any tick source, but there is little to be gained if
the selected source is already reasonably accurate.

If the LPOSC is fast, the ms counter pauses at a 1 second step until the 1s tick is received. If the LPOSC is slow, the 1s
tick causes the ms counter to run very quickly until reaching the 1 second step. This ensures that all ms values are
counted, ensuring that any alarm set to ms precision will fire. A more sophisticated synchronisation method can be
implemented in software.

To use the hardware synchronisation feature, configure the GPIO source as described in Section 12.10.7. Then, enable
the feature by writing a 1 to TIMER.USE_GPIO_1HZ. This can be set at any time, it is not necessary to stop the AON
Timer. When the operation is complete TIMER.USE_GPIO_1HZ will self-clear and TIMER.USING_GPIO_1HZ will be set.

The tick is triggered from the falling edge of the selected GPIO. For correct sampling, the GPIO pulse width and interval
must be greater than the period of LPOSC (>31us).

The external 1s tick can be used in all power modes.

12.10.7. Using an external clock or tick from GPIO


The following features use a GPIO as a clock or a tick:

• external 32kHz clock source


• external 1kHz tick
• external 1Hz tick
Only 4 GPIOs are available for these features. You can only select one, because they share the same GPIO selection
logic. The set of 4 GPIOs differs between package types. The selection is controlled by a 2-bit register field.

The AON Timer uses the following GPIOs:

• EXT_TIME_REF.SOURCE_SEL = 0 → GPIO12
• EXT_TIME_REF.SOURCE_SEL = 1 → GPIO20
• EXT_TIME_REF.SOURCE_SEL = 2 → GPIO14
• EXT_TIME_REF.SOURCE_SEL = 3 → GPIO22

12.10.8. Using a Tick Faster than 1ms


The tick rate can be increased by scaling the value written to the LPOSC and XOSC frequency registers. For example, if
the frequency value is divided by 4 then the AON Timer will tick 4 times per ms. The minimum value that can be written
to the frequency registers is 2.0, therefore the maximum upscaling using this method with LPOSC is 16, giving a time
resolution of 1/16th of 1 ms (= 62.5us).

As described previously, the external tick is limited to 16kHz, so the maximum upscaling using this method is also 16.
This gives a time resolution of 1/16th of 1 ms (62.5μs).

These limitations can be overcome either by using a faster external clock (see Section 12.10.5.2) or keeping the chip
core powered so the AON Timer is always running from the XOSC. If a faster external clock is used then the power
sequencer timings will also need to be adjusted.

12.10. Always-On Timer 1195


RP2350 Datasheet

For example, suppose 1μsec timer precision is required. The user could supply an external 2-25MHz clock in place of
the LPOSC and program both the LPOSC and XOSC frequency registers in MHz units rather than kHz. The maximum
frequency of the external clock is 29MHz.

12.10.9. List of Registers


The AON Timer shares a register address space with the power management subsystems in the always-on domain. The
address space is referred to as POWMAN elsewhere in this document and a complete list of POWMAN registers is provided in
Section 6.4. The registers associated with the AON Timer are:

• SET_TIME_63TO48
• SET_TIME_47TO32
• SET_TIME_31TO16
• SET_TIME_15TO0
• READ_TIME_UPPER
• READ_TIME_LOWER
• ALARM_TIME_63TO48
• ALARM_TIME_47TO32
• ALARM_TIME_31TO16
• ALARM_TIME_15TO0
• TIMER

12.11. HSTX
The high-speed serial transmit (HSTX) streams data from the system clock domain to up to 8 GPIOs at a rate
independent of the system clock. On RP2350, GPIOs 12 through 19 are HSTX-capable. HSTX is output-only.

Figure 125. A 32-bit-


wide asynchronous
FIFO provides high-
Domain: Domain:
clk_sys clk_hstx
bandwidth access
from the system DMA.
PIO Outputs
The command
(If clk_hstx is
expander manipulates
clk_sys)
the datastream, and
the output shift /8

register portions the


32-bit data over
Bit Crossbar DDR Output
successive HSTX AHB Async FIFO Command Output
/32 w/ Optional /16 Registers /8
clock cycles, swizzled (HSTX_FIFO) 8 × 32b Expander Shifter
Inversion ×8
by the bit crossbar.
Outputs are double-
data-rate: two bits per /1
pin per cycle.
APB APB Async Control Clock
(HSTX_CTRL) Bridge Registers Generator

HSTX drives data through GPIOs using DDR output registers to transfer up to two bits per clock cycle per pin. The HSTX
balances all delays to GPIO outputs within 300 picoseconds, minimising common-mode components when using
neighbouring GPIOs as a pseudo-differential driver. This also helps maintain destination setup and hold time when a
clock is driven alongside the output data.

The maximum frequency for the HSTX clock is 150 MHz, the same as the system clock. With DDR output operation, this

12.11. HSTX 1196


RP2350 Datasheet

is a maximum data rate of 300 Mb/s per pin. There are no limits on the frequency ratio of the system and HSTX clocks,
however each clock must be individually fast enough to maintain your required throughput. Very low system clock
frequencies coupled with very high HSTX frequencies may encounter system DMA bandwidth limitations, since the
DMA is capped at one HSTX FIFO write per system clock cycle.

12.11.1. Data FIFO


An 8-entry, 32-bit-wide FIFO buffers data between the system clock domain (clk_sys) and the HSTX clock domain
(clk_hstx). This is accessed through the AHB FASTPERI arbiter, providing single-cycle write access from the DMA. The
FIFO status is also available through this same bus interface, for faster polled processor IO; see Section 12.11.8.

The FIFO is accessed through a bus interface separate from the control registers (Section 12.11.7), which take multiple
cycles to access due to the asynchronous bus crossing. This design avoids incurring bus stalls on the system DMA or
the FASTPERI arbiter when accessing the FIFO.

The HSTX side also pops 32 bits at a time from the FIFO. The word data stream from the FIFO is optionally manipulated
by the command expander (Section 12.11.5) before being passed to the output shift register.

12.11.2. Output Shift Register


Figure 126. Every
cycle, the output shift N_SHIFTS reached?
register either refills
32 bits from the FIFO
or recirculates data 1 Output Shift
Data FIFO
through a right-rotate System Register /32 Bit Crossbar
(8 x 32b async)
function. The rotate 0 (32 bits)
can be used to
perform left or right
shifts, and to repeat
data. Right-rotate
SHIFT = 0-31

The HSTX’s internal data paths are 32 bits wide, but the output is narrower: no more than 16 bits can be output per
HSTX cycle (8 GPIOs × DDR). The output shift register adapts these mismatched data widths. The output shift register
is a 32-bit shift register, which always refills 32 bits at a time, either from the command expander output or directly from
the data FIFO.

The source of data for the output shift register is configured by the CSR.EXPAND_EN field:

• when set, the command expander interposes the FIFO and the output shift register
• when clear, the command expander is bypassed, popping the FIFO directly into the shift register
Whenever CSR.EN is low, the shift register is flushed to empty. Once HSTX has been configured, and EN is set high, the
shift register is ready to accept data, and will pop data as soon as it becomes available.

After popping the first data word, the shift register will now shift every HSTX clock cycle until it becomes empty. The
shift behaviour is configured by:

• CSR.N_SHIFTS, which determines how many times to shift before the register is considered empty
• CSR.SHIFT, which is a right-rotate applied to the shift register every cycle
CSR.N_SHIFTS and CSR.SHIFT must only be changed when CSR.EN is low. It is safe to change these fields in the same
register write that sets EN from low to high.

SHIFT × N_SHIFTS is not necessarily less than or equal to 32. For example, a SHIFT of 31 might be used to shift the register
left by one bit per cycle, since right-rotate is a modular operation, and -1 is equal to 31 under a modulus of 32.

When the shift register is about to become empty, it will immediately refill with fresh data from the command expander
or FIFO if data is available. When data is available, the shift register is never empty for any cycle. If data is not available,

12.11. HSTX 1197


RP2350 Datasheet

the shift register becomes empty and stops shifting until more data is provided. Once data is provided, the shift register
refills and begins shifting once again.

12.11.3. Bit Crossbar


The bit crossbar controls which bits of the output shift register appear on which GPIOs during the first and second half
of each HSTX clock cycle. There is a configuration register for each pin, BIT0 through BIT7:

• BITx.SEL_P selects which shift register bit (0 through 31) is output for the first half of each HSTX clock cycle
• BITx.SEL_N selects which shift register bit (0 through 31) is output for the second half of each clock cycle
• BITx.INV inverts the output (logical NOT)
• BITx.CLK indicates that this pin should be connected to the clock generator (Section 12.11.4) rather than the output
shift register

To disable DDR behaviour set SEL_N equal to SEL_P. To implement a differential output, configure two pins identically
except for the INV bit, which should be set for one pin and clear for the other.

12.11.3.1. Examples: One Pin

Together with the SHIFT and N_SHIFTS controls for the shift register, the pin configuration determines the data layout
passed through the HSTX. Since not all of us are accustomed to thinking in four dimensions, it’s worth going through
some examples with a single pin:

• N_SHIFTS = 32, SHIFT = 1, SEL_P = 0, SEL_N = 0:


◦ Shift out one bit per HSTX clock cycle, LSB-first.
◦ Each cycle, the shift register advances to the right by one, and the least-significant bit at that time is
presented to the pin for both halves of the cycle, since SEL_P and SEL_N both select the same bit.

• N_SHIFTS = 32, SHIFT = 31, SEL_P = 31, SEL_N = 31:


◦ Shift out one bit per HSTX clock cycle, MSB-first.
◦ Each cycle, the shift register advances to the left by one (or rather, wraps around the right-hand edge of the
register and ends up one bit left of where it started), and the most-significant bit at that time is presented to
the pin.

• N_SHIFTS = 16, SHIFT = 2, SEL_P = 0, SEL_N = 1:


◦ Shift out two bits per HSTX clock cycle, LSB-first.
◦ Each cycle, the shift register advances to the right by two. The least-significant bit is presented to the pin for
the first half of that cycle, and the neighbouring bit is presented for the second half.

• N_SHIFTS = 16, SHIFT = 30, SEL_P = 31, SEL_N = 30:


◦ Shift out two bits per HSTX clock cycle, MSB-first.
◦ Each cycle, the shift register advances to the left by two. The most-significant bit is presented to the pin for
the first half of that cycle, and the neighbouring bit is presented for the latter half.

• N_SHIFTS = 8, SHIFT = 4, SEL_P = 0, SEL_N = 0:


◦ Shift out the least-significant bit in each group of 4 bits, over the course of 8 clock cycles.
◦ Each cycle, the shift register advances by to the right by four. The least-significant bit of the shift register is
presented to the pin. The bit indices presented to the pin are therefore 0, 4, 8, 12, 16, 20, 24, and 28.

• N_SHIFTS = 32, SHIFT = 4, SEL_P = 0, SEL_N = 0:

12.11. HSTX 1198


RP2350 Datasheet

◦ Same as the previous, but repeats the 8-cycle pattern four times before refreshing the shift register.
◦ Rotating by 32 restores the original value that was popped into the shift register from the FIFO or command
expander.

12.11.3.2. Examples: Multiple Pins

The separation of shift register and bit crossbar allows both zipped and unzipped multi-bit records, once multiple pins
are involved. For example, compare these two configurations:

• N_SHIFTS = 8, SHIFT = 4, BIT0.SEL_P = 0, BIT0.SEL_N = 2, BIT1.SEL_P = 1, BIT1.SEL_N = 3:


◦ Each 32-bit word consists of 16 bit-pairs, and a new bit-pair is presented to BIT0 and BIT1 twice per cycle.
◦ The shift register advances by 4 every cycle, introducing two new bit-pairs to the rightmost four bits of the
shift register

• N_SHIFTS = 8, SHIFT = 2, BIT0.SEL_P = 0, BIT0.SEL_N = 1, BIT1.SEL_P = 16, BIT1.SEL_N = 17:


◦ Each 32-bit word consists of a pair of 16-bit values, each of which is shifted to one pin out of BIT0 and BIT1 at
a rate of two bits per cycle.

◦ The shift register advances by two every cycle, introducing a new bit-pair to bits 1:0 for the BIT0 pin, and also
introducing a new bit-pair to bits 17:16 for the BIT1 pin.

Depending on software needs, it may be preferable to pack together all of the bits output on the same cycle (zipped
records), or all of the bits that go through the same pin (unzipped records), so HSTX supports both.

As a final, concrete example, take TMDS (used in DVI): here each 32-bit word contains 3 × 10-bit TMDS symbols, each of
which is serialised to a differential pair over the course of 10 TMDS bit times. For performance, it’s preferable to make
each HSTX clock period equal to two TMDS bit periods, by leveraging the DDR capability. A possible configuration would
therefore be:

• CSR: N_SHIFTS = 5, SHIFT = 2


• BIT0: SEL_P = 0, SEL_N = 1, INV = 0
• BIT1: SEL_P = 0, SEL_N = 1, INV = 1
• BIT2: SEL_P = 10, SEL_N = 11, INV = 0
• BIT3: SEL_P = 10, SEL_N = 11, INV = 1
• BIT4: SEL_P = 20, SEL_N = 21, INV = 0
• BIT5: SEL_P = 20, SEL_N = 21, INV = 1
The missing piece for TMDS is the clock, which has a period of 10 TMDS bit periods, or 5 HSTX clock periods when
shifting two bits per cycle per pin. HSTX has a special-purpose clock generator so that pseudo-clock bits do not have to
be packed into the FIFO data stream. The clock generator is covered in the next section.

12.11.4. Clock Generator


The clock generator is a counter which provides a periodic signal over the course of n HSTX clock cycles, configured by
CSR.CLKDIV. The clock period is always an integer number of HSTX clock cycles, in the range 1 to 16 inclusive. The
clock generator supports both odd and even periods, using the DDR outputs to support mid-HSTX-cycle output
transitions. There is only a single clock generator — to emulate multiple clocks, pack pseudo-clock bits into FIFO data.

The clock generator increments on cycles where the output shift register is shifted. Generally, the clock period will be a
divisor of CSR.N_SHIFTS so that clock and data maintain a consistent alignment. In the TMDS example in the previous
section, a CLKDIV of 5 would be suitable, so that the clock repeats every time the shift register refreshes. This matches
the requirement for a TMDS clock period of 10 bit periods, since two bits are transferred every cycle.

The clock generator output is connected to any pin whose BITx.CLK bit is set (e.g. BIT0.CLK). To produce differential

12.11. HSTX 1199

You might also like