RKTK API Docs RKTK Home Repo

rktk_drivers_rp/
system.rs

1use core::{mem::MaybeUninit, ptr::write_volatile};
2
3use embassy_time::{Duration, Timer};
4use rktk::drivers::interface::system::SystemDriver;
5
6const BOOTLOADER_MAGIC: u32 = 0xABCD_EF01;
7
8#[unsafe(link_section = ".uninit")]
9static mut FLAG: MaybeUninit<u32> = MaybeUninit::uninit();
10
11pub struct RpSystemDriver;
12
13impl SystemDriver for RpSystemDriver {
14    async fn double_reset_usb_boot(&self, timeout: Duration) {
15        unsafe {
16            let flag = core::ptr::read(&raw const FLAG);
17            let flag = flag.assume_init();
18
19            if flag == BOOTLOADER_MAGIC {
20                // double reset is triggered. rebooting to bootloader.
21                write_volatile(&raw mut FLAG, MaybeUninit::new(0));
22                embassy_rp::rom_data::reset_to_usb_boot(0, 0);
23            }
24
25            // write flag and wait for double reset
26            write_volatile(&raw mut FLAG, MaybeUninit::new(BOOTLOADER_MAGIC));
27            Timer::after(timeout).await;
28            // double-tap reset is not performed. reset flag and normal start
29            write_volatile(&raw mut FLAG, MaybeUninit::new(0));
30        }
31    }
32
33    fn reset(&self) {
34        // not supported
35    }
36
37    fn reset_to_bootloader(&self) {
38        embassy_rp::rom_data::reset_to_usb_boot(0, 0);
39    }
40}