diff options
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/rp/Cargo.toml | 6 | ||||
| -rw-r--r-- | tests/rp/src/bin/rtc.rs | 113 |
2 files changed, 119 insertions, 0 deletions
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index 809346bed..19461520a 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml | |||
| @@ -64,6 +64,12 @@ name = "float" | |||
| 64 | path = "src/bin/float.rs" | 64 | path = "src/bin/float.rs" |
| 65 | required-features = [ "rp2040",] | 65 | required-features = [ "rp2040",] |
| 66 | 66 | ||
| 67 | # RTC is only available on RP2040 | ||
| 68 | [[bin]] | ||
| 69 | name = "rtc" | ||
| 70 | path = "src/bin/rtc.rs" | ||
| 71 | required-features = [ "rp2040",] | ||
| 72 | |||
| 67 | [profile.dev] | 73 | [profile.dev] |
| 68 | debug = 2 | 74 | debug = 2 |
| 69 | debug-assertions = true | 75 | debug-assertions = true |
diff --git a/tests/rp/src/bin/rtc.rs b/tests/rp/src/bin/rtc.rs new file mode 100644 index 000000000..8d1d4ee14 --- /dev/null +++ b/tests/rp/src/bin/rtc.rs | |||
| @@ -0,0 +1,113 @@ | |||
| 1 | #![no_std] | ||
| 2 | #![no_main] | ||
| 3 | #[cfg(feature = "rp2040")] | ||
| 4 | teleprobe_meta::target!(b"rpi-pico"); | ||
| 5 | |||
| 6 | use defmt::{assert, *}; | ||
| 7 | use embassy_executor::Spawner; | ||
| 8 | use embassy_futures::select::{select, Either}; | ||
| 9 | use embassy_rp::bind_interrupts; | ||
| 10 | use embassy_rp::rtc::{DateTime, DateTimeFilter, DayOfWeek, Rtc}; | ||
| 11 | use embassy_time::{Duration, Instant, Timer}; | ||
| 12 | use {defmt_rtt as _, panic_probe as _}; | ||
| 13 | |||
| 14 | // Bind the RTC interrupt to the handler | ||
| 15 | bind_interrupts!(struct Irqs { | ||
| 16 | RTC_IRQ => embassy_rp::rtc::InterruptHandler; | ||
| 17 | }); | ||
| 18 | |||
| 19 | #[embassy_executor::main] | ||
| 20 | async fn main(_spawner: Spawner) { | ||
| 21 | let p = embassy_rp::init(Default::default()); | ||
| 22 | let mut rtc = Rtc::new(p.RTC, Irqs); | ||
| 23 | |||
| 24 | info!("RTC test started"); | ||
| 25 | |||
| 26 | // Initialize RTC if not running | ||
| 27 | if !rtc.is_running() { | ||
| 28 | info!("Starting RTC"); | ||
| 29 | let now = DateTime { | ||
| 30 | year: 2000, | ||
| 31 | month: 1, | ||
| 32 | day: 1, | ||
| 33 | day_of_week: DayOfWeek::Saturday, | ||
| 34 | hour: 0, | ||
| 35 | minute: 0, | ||
| 36 | second: 0, | ||
| 37 | }; | ||
| 38 | rtc.set_datetime(now).unwrap(); | ||
| 39 | } | ||
| 40 | |||
| 41 | // Test 1: Basic RTC functionality - read current time | ||
| 42 | let initial_time = rtc.now().unwrap(); | ||
| 43 | info!( | ||
| 44 | "Initial time: {}-{:02}-{:02} {}:{:02}:{:02}", | ||
| 45 | initial_time.year, | ||
| 46 | initial_time.month, | ||
| 47 | initial_time.day, | ||
| 48 | initial_time.hour, | ||
| 49 | initial_time.minute, | ||
| 50 | initial_time.second | ||
| 51 | ); | ||
| 52 | |||
| 53 | // Test 2: Schedule and wait for alarm | ||
| 54 | info!("Testing alarm scheduling"); | ||
| 55 | |||
| 56 | // Schedule alarm for 3 seconds from now | ||
| 57 | let alarm_second = (initial_time.second + 3) % 60; | ||
| 58 | let alarm_filter = DateTimeFilter::default().second(alarm_second); | ||
| 59 | |||
| 60 | info!("Scheduling alarm for second: {}", alarm_second); | ||
| 61 | rtc.schedule_alarm(alarm_filter); | ||
| 62 | |||
| 63 | // Verify alarm is scheduled | ||
| 64 | let scheduled = rtc.alarm_scheduled(); | ||
| 65 | assert!(scheduled.is_some(), "Alarm should be scheduled"); | ||
| 66 | info!("Alarm scheduled successfully: {}", scheduled.unwrap()); | ||
| 67 | |||
| 68 | // Wait for alarm with timeout | ||
| 69 | let alarm_start = Instant::now(); | ||
| 70 | match select(Timer::after_secs(5), rtc.wait_for_alarm()).await { | ||
| 71 | Either::First(_) => { | ||
| 72 | core::panic!("Alarm timeout - alarm should have triggered within 5 seconds"); | ||
| 73 | } | ||
| 74 | Either::Second(_) => { | ||
| 75 | let alarm_duration = Instant::now() - alarm_start; | ||
| 76 | info!("ALARM TRIGGERED after {:?}", alarm_duration); | ||
| 77 | |||
| 78 | // Verify timing is reasonable (should be around 3 seconds, allow some margin) | ||
| 79 | assert!( | ||
| 80 | alarm_duration >= Duration::from_secs(2) && alarm_duration <= Duration::from_secs(4), | ||
| 81 | "Alarm timing incorrect: {:?}", | ||
| 82 | alarm_duration | ||
| 83 | ); | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | // Test 3: Verify RTC is still running and time has advanced | ||
| 88 | let final_time = rtc.now().unwrap(); | ||
| 89 | info!( | ||
| 90 | "Final time: {}-{:02}-{:02} {}:{:02}:{:02}", | ||
| 91 | final_time.year, final_time.month, final_time.day, final_time.hour, final_time.minute, final_time.second | ||
| 92 | ); | ||
| 93 | |||
| 94 | // Verify time has advanced (allowing for minute/hour rollover) | ||
| 95 | let time_diff = if final_time.second >= initial_time.second { | ||
| 96 | final_time.second - initial_time.second | ||
| 97 | } else { | ||
| 98 | 60 - initial_time.second + final_time.second | ||
| 99 | }; | ||
| 100 | |||
| 101 | assert!(time_diff >= 3, "RTC should have advanced by at least 3 seconds"); | ||
| 102 | info!("Time advanced by {} seconds", time_diff); | ||
| 103 | |||
| 104 | // Test 4: Verify alarm is no longer scheduled after triggering | ||
| 105 | let post_alarm_scheduled = rtc.alarm_scheduled(); | ||
| 106 | assert!( | ||
| 107 | post_alarm_scheduled.is_none(), | ||
| 108 | "Alarm should not be scheduled after triggering" | ||
| 109 | ); | ||
| 110 | |||
| 111 | info!("Test OK"); | ||
| 112 | cortex_m::asm::bkpt(); | ||
| 113 | } | ||
