From 00fe25b28c2ecfca015ce308f66e8467738b2ea4 Mon Sep 17 00:00:00 2001 From: bunnie Date: Mon, 22 Dec 2025 02:06:22 +0800 Subject: [PATCH] fix RTC setting bug - don't reset if it's already set the backup RAM region is being used as a way to check if the system is coming out of a cold power-on. Deep sleep is indistinguishable from a power-on from the hashing perspective. Check if the RTC is *enabled* and if not, enable it and reset the time; don't always reset it if the backup ram is scrambled. --- bao1x-boot/boot1/src/platform/bao1x/bao1x.rs | 38 +++++++++++++------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/bao1x-boot/boot1/src/platform/bao1x/bao1x.rs b/bao1x-boot/boot1/src/platform/bao1x/bao1x.rs index 81fa21c6d..0ea6ac616 100644 --- a/bao1x-boot/boot1/src/platform/bao1x/bao1x.rs +++ b/bao1x-boot/boot1/src/platform/bao1x/bao1x.rs @@ -110,21 +110,27 @@ pub fn setup_backup_region() -> u32 { acc += i as u32; } - // enable the RTC if it isn't already - on a cold boot, it would be off let mut ao_sysctrl = CSR::new(utralib::HW_AO_SYSCTRL_BASE as *mut u32); - // set effective tick to 1/1024th of a second - // this causes the RTC to roll over every 48 days - the code before had some deniability about - // RTC offset because it would roll over every 168 years, but I think once every 48 days is within - // a reasonable window of deniability (previously it was a random number from 0-6 months) and - // also the system has to be powered on at least once every rollover window to capture the rollover. - // The device won't last 48 days on RTC battery alone - and every time a QR code is scanned you - // update the RTC offset. So I think this is a reasonable window to just leave "as so". The - // initial value is set to within minutes of a roll-over, so that an error in rollover handling - // would be detected quickly. - ao_sysctrl.wo(utra::ao_sysctrl::CR_CLK1HZFD, 15); let mut rtc = CSR::new(bao1x_hal::rtc::HW_RTC_BASE as *mut u32); - rtc.wo(bao1x_hal::rtc::LR, 0xFFFE_2000); // set base to "roll over" in 2 minutes - forces an edge case in testing - rtc.wfo(bao1x_hal::rtc::CR_EN, 1); + // enable the RTC if it isn't already - on a cold boot, it would be off + if rtc.rf(bao1x_hal::rtc::CR_EN) != 1 { + // set effective tick to 1/1024th of a second + // this causes the RTC to roll over every 48 days - the code before had some deniability about + // RTC offset because it would roll over every 168 years, but I think once every 48 days is within + // a reasonable window of deniability (previously it was a random number from 0-6 months) and + // also the system has to be powered on at least once every rollover window to capture the + // rollover. The device won't last 48 days on RTC battery alone - and every time a QR + // code is scanned you update the RTC offset. So I think this is a reasonable window + // to just leave "as so". The initial value is set to within minutes of a roll-over, + // so that an error in rollover handling would be detected quickly. + ao_sysctrl.wo(utra::ao_sysctrl::CR_CLK1HZFD, 15); + rtc.wo(bao1x_hal::rtc::LR, 0xFFFE_2000); // set base to "roll over" in 2 minutes - forces an edge case in testing + rtc.wfo(bao1x_hal::rtc::CR_EN, 1); + + let mut backup_flags = bu_mgr.get_flags(); + backup_flags.set_rtc_synchronized(false); + bu_mgr.set_flags(backup_flags); + } // soft-reset the system let mut rcurst = CSR::new(utra::sysctrl::HW_SYSCTRL_BASE as *mut u32); @@ -162,6 +168,12 @@ pub fn early_init(mut board_type: bao1x_api::BoardTypeCoding) -> (bao1x_api::Boa if setup_backup_region() == 0 { crate::println!("backup region is clean!"); } + /* // debug RTC setting - remove once confident + let rtc = CSR::new(bao1x_hal::rtc::HW_RTC_BASE as *mut u32); + for i in 0..8 { + crate::println_d!("rtc {}: {:x}", i, unsafe { rtc.base().add(i).read_volatile() }); + } + */ // setup board-specific I/Os - early boot set. These are items that have to be // done in a time-sensitive fashion.