From e9050fa59e5870de01e4a124ad04bb38792b310e Mon Sep 17 00:00:00 2001 From: Dominic Date: Sun, 8 Oct 2023 20:03:13 +0200 Subject: [PATCH 1/3] attempt to use dcf77_utils --- Cargo.lock | 16 +++++++++++++++ Cargo.toml | 1 + src/main.rs | 56 ++++++++++++++++++++++++----------------------------- 3 files changed, 42 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d32835..de84cc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,6 +168,15 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "dcf77_utils" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "824d8617af2b569a01b5498c76efa9dca0acba748d4b339d5fbe3c7e28cb4cfb" +dependencies = [ + "radio_datetime_utils", +] + [[package]] name = "defmt" version = "0.3.5" @@ -225,6 +234,7 @@ version = "0.1.0" dependencies = [ "cortex-m", "cortex-m-rt", + "dcf77_utils", "defmt", "defmt-rtt", "embassy-executor", @@ -691,6 +701,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radio_datetime_utils" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95cdd3b90edcd89072979b07d58b98573e6042d7d79f9b3c43aa14ceea645d6e" + [[package]] name = "rand_core" version = "0.6.4" diff --git a/Cargo.toml b/Cargo.toml index 42d46b8..512be88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ edition = "2021" [dependencies] cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7" +dcf77_utils = "0.5" defmt = "0.3" defmt-rtt = "0.3" # potentially use executor-interrupt instead of executor-thread for cortex-m architectures diff --git a/src/main.rs b/src/main.rs index 9b1d7db..7a86197 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,8 @@ mod static_mutex; -use defmt::*; +use dcf77_utils::DCF77Utils; +use defmt::{assert, info, println, unwrap}; use defmt_rtt as _; use embassy_executor::Spawner; use embassy_stm32::{ @@ -62,39 +63,32 @@ async fn query_time(mut pon: POn, mut tco: Tco, interval: Duration) { pon.set_low(); info!("Waiting"); tco.wait_for_falling_edge().await; - // for _ in 0 .. 10 { - // info!("Receiving"); - // let mut bytes = 0u64; - // for _ in 0 .. 60 { - // bytes = (bytes << 1) | (tco.is_low() as u64); - // Timer::after(Duration::from_millis(100)).await; - // } - // info!("DCF77: {:X}", bytes); - // } + info!("Receiving"); + + let mut dcf77 = DCF77Utils::new(); let start = Instant::now(); - let mut next = start; - for _ in 0 .. 120 { - let mut bytes = 0u16; - for _ in 0 .. 10 { - bytes = (bytes << 1) | (tco.is_low() as u16); - next += Duration::from_millis(100); - Timer::at(next).await; + loop { + tco.wait_for_any_edge().await; + let elapsed = start.elapsed(); + while elapsed.as_secs() > dcf77.get_second() as u64 { + dcf77.increase_second(); + } + dcf77.handle_new_edge(tco.is_low(), start.elapsed().as_millis() as u32); + if dcf77.get_second() + 1 == dcf77.get_next_minute_length() { + dcf77.decode_time(); + let datetime = dcf77.get_radio_datetime(); + println!( + "{}.{}.{} {}:{}", + datetime.get_day(), + datetime.get_month(), + datetime.get_year(), + datetime.get_hour(), + datetime.get_minute() + ); + break; } - println!( - "{}{}{}{}{}{}{}{}{}{} ({})", - (bytes >> 9) & 1, - (bytes >> 8) & 1, - (bytes >> 7) & 1, - (bytes >> 6) & 1, - (bytes >> 5) & 1, - (bytes >> 4) & 1, - (bytes >> 3) & 1, - (bytes >> 2) & 1, - (bytes >> 1) & 1, - bytes & 1, - start.elapsed().as_millis() - ); } + pon.set_high(); Timer::after(interval).await; From 4da353ab28172003580b0d3e827f40c0b9b7db04 Mon Sep 17 00:00:00 2001 From: Dominic Date: Sun, 8 Oct 2023 23:06:19 +0200 Subject: [PATCH 2/3] try decoding the dcf77 bits myself --- Cargo.lock | 16 ------------- Cargo.toml | 1 - src/main.rs | 68 ++++++++++++++++++++++++++++++++++------------------- 3 files changed, 44 insertions(+), 41 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index de84cc3..6d32835 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -168,15 +168,6 @@ dependencies = [ "syn 2.0.37", ] -[[package]] -name = "dcf77_utils" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824d8617af2b569a01b5498c76efa9dca0acba748d4b339d5fbe3c7e28cb4cfb" -dependencies = [ - "radio_datetime_utils", -] - [[package]] name = "defmt" version = "0.3.5" @@ -234,7 +225,6 @@ version = "0.1.0" dependencies = [ "cortex-m", "cortex-m-rt", - "dcf77_utils", "defmt", "defmt-rtt", "embassy-executor", @@ -701,12 +691,6 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "radio_datetime_utils" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95cdd3b90edcd89072979b07d58b98573e6042d7d79f9b3c43aa14ceea645d6e" - [[package]] name = "rand_core" version = "0.6.4" diff --git a/Cargo.toml b/Cargo.toml index 512be88..42d46b8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ edition = "2021" [dependencies] cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } cortex-m-rt = "0.7" -dcf77_utils = "0.5" defmt = "0.3" defmt-rtt = "0.3" # potentially use executor-interrupt instead of executor-thread for cortex-m architectures diff --git a/src/main.rs b/src/main.rs index 7a86197..ed01a08 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,11 +3,14 @@ #![feature(async_fn_track_caller, type_alias_impl_trait)] #![warn(rust_2018_idioms)] #![forbid(elided_lifetimes_in_paths, unsafe_code)] +// STOP HIGHLIGHTING MY ENTIRE CODE RED YOU MOTHERFUCKING PEACE OF GARBAGE SOFTWARE +// SOMETIMES I AM WRITING CODE BEFORE I INSERT A BREAK SOMEWHERE +// ARE YOU AWARE THAT CODING DOESN'T PRODUCE FINISHED CODE IN A MILLISECOND??????? +#![allow(clippy::never_loop, unreachable_code)] mod static_mutex; -use dcf77_utils::DCF77Utils; -use defmt::{assert, info, println, unwrap}; +use defmt::{info, println, unwrap}; use defmt_rtt as _; use embassy_executor::Spawner; use embassy_stm32::{ @@ -62,34 +65,51 @@ async fn query_time(mut pon: POn, mut tco: Tco, interval: Duration) { loop { pon.set_low(); info!("Waiting"); - tco.wait_for_falling_edge().await; - info!("Receiving"); - let mut dcf77 = DCF77Utils::new(); - let start = Instant::now(); + // we need to find the minute marker + // that means we won't receive a transmission for an entire second + tco.wait_for_rising_edge().await; loop { - tco.wait_for_any_edge().await; - let elapsed = start.elapsed(); - while elapsed.as_secs() > dcf77.get_second() as u64 { - dcf77.increase_second(); - } - dcf77.handle_new_edge(tco.is_low(), start.elapsed().as_millis() as u32); - if dcf77.get_second() + 1 == dcf77.get_next_minute_length() { - dcf77.decode_time(); - let datetime = dcf77.get_radio_datetime(); - println!( - "{}.{}.{} {}:{}", - datetime.get_day(), - datetime.get_month(), - datetime.get_year(), - datetime.get_hour(), - datetime.get_minute() - ); + tco.wait_for_falling_edge().await; + let start = Instant::now(); + tco.wait_for_rising_edge().await; + // our starting edge should have at least 800ms from the previous second, + // and then a full second. + if start.elapsed().as_millis() > 1500 { break; } } + let mut start = Instant::now(); + + info!("Receiving"); + + // we always start on the rising edge, with `start` set already + const SECONDS: usize = 60; + let mut bytes = [0u64; SECONDS]; + let mut timing = [0u64; SECONDS]; + for i in 0 .. SECONDS { + tco.wait_for_falling_edge().await; + bytes[i] = start.elapsed().as_millis(); + tco.wait_for_rising_edge().await; + timing[i] = start.elapsed().as_millis(); + start = Instant::now(); + } pon.set_high(); + info!("Done"); + + for i in 0 .. SECONDS { + let data = match (bytes[i], timing[i]) { + (75 ..= 174, 900 ..= 1100) => "0", + (175 ..= 300, 900 ..= 1100) => "1", + _ => "GARBAGE" + }; + println!( + "Bit {:02}: on for {:04} ms of {:04} ms total -- {:02}: {}", + i, bytes[i], timing[i], i, data + ); + Timer::after(Duration::from_millis(50)).await; + } Timer::after(interval).await; } @@ -107,6 +127,6 @@ async fn main(spawner: Spawner) { LED.init(Output::new(p.PA5, Level::Low, Speed::Low)).await; let button = ExtiInput::new(Input::new(p.PC13, Pull::Up), p.EXTI13); - unwrap!(spawner.spawn(blinker(Duration::from_millis(500)))); + unwrap!(spawner.spawn(blinker(Duration::from_millis(120)))); unwrap!(spawner.spawn(button_handler(button))); } From 3c7a6186d4ac04482393a569d15a1ba3f74b3aed Mon Sep 17 00:00:00 2001 From: Dominic Date: Sun, 8 Oct 2023 23:36:58 +0200 Subject: [PATCH 3/3] restart on garbage --- src/main.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/src/main.rs b/src/main.rs index ed01a08..906410e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -87,22 +87,42 @@ async fn query_time(mut pon: POn, mut tco: Tco, interval: Duration) { const SECONDS: usize = 60; let mut bytes = [0u64; SECONDS]; let mut timing = [0u64; SECONDS]; - for i in 0 .. SECONDS { + let mut i = 0; + while i < SECONDS { tco.wait_for_falling_edge().await; bytes[i] = start.elapsed().as_millis(); tco.wait_for_rising_edge().await; timing[i] = start.elapsed().as_millis(); start = Instant::now(); + + // verify that the transmission wasn't just noise of the previous one + if i > 0 && bytes[i] < 100 && timing[i - 1] - bytes[i - 1] < 100 { + bytes[i - 1] += timing[i - 1] + bytes[i]; + timing[i - 1] += timing[i]; + } + // and verify that the transmission wasn't a minute marker + else if timing[i] >= 1500 { + info!("Retrying"); + i = 0; + } + // otherwise advance the second + else { + i += 1; + } } pon.set_high(); info!("Done"); + let mut garbage = false; for i in 0 .. SECONDS { let data = match (bytes[i], timing[i]) { (75 ..= 174, 900 ..= 1100) => "0", (175 ..= 300, 900 ..= 1100) => "1", - _ => "GARBAGE" + _ => { + garbage = true; + "GARBAGE" + } }; println!( "Bit {:02}: on for {:04} ms of {:04} ms total -- {:02}: {}", @@ -111,7 +131,9 @@ async fn query_time(mut pon: POn, mut tco: Tco, interval: Duration) { Timer::after(Duration::from_millis(50)).await; } - Timer::after(interval).await; + if !garbage { + Timer::after(interval).await; + } } } @@ -122,11 +144,11 @@ async fn main(spawner: Spawner) { let pon = Output::new(p.PA0, Level::High, Speed::Low); let tco = ExtiInput::new(Input::new(p.PA1, Pull::None), p.EXTI1); - unwrap!(spawner.spawn(query_time(pon, tco, Duration::from_secs(300)))); + unwrap!(spawner.spawn(query_time(pon, tco, Duration::from_secs(120)))); LED.init(Output::new(p.PA5, Level::Low, Speed::Low)).await; let button = ExtiInput::new(Input::new(p.PC13, Pull::Up), p.EXTI13); - unwrap!(spawner.spawn(blinker(Duration::from_millis(120)))); + unwrap!(spawner.spawn(blinker(Duration::from_millis(500)))); unwrap!(spawner.spawn(button_handler(button))); }