mirror of
				https://github.com/Djeeberjr/fw-anwesenheit.git
				synced 2025-11-04 07:34:10 +00:00 
			
		
		
		
	rtc is synchronized with compile time. start pub sub approach to share time
This commit is contained in:
		
							parent
							
								
									5950279dc4
								
							
						
					
					
						commit
						2f502e908e
					
				@ -1,108 +1,164 @@
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use log::info;
 | 
			
		||||
use core::time;
 | 
			
		||||
 | 
			
		||||
use chrono::NaiveDate;
 | 
			
		||||
use ds3231::{
 | 
			
		||||
    Alarm1Config, Config, DS3231, DS3231Error, InterruptControl, Oscillator, Seconds,
 | 
			
		||||
    SquareWaveFrequency, TimeRepresentation,
 | 
			
		||||
};
 | 
			
		||||
use embassy_time::{Duration, Timer, WithTimeout};
 | 
			
		||||
use esp_hal::{
 | 
			
		||||
    Async,
 | 
			
		||||
    i2c::{self, master::I2c},
 | 
			
		||||
    peripherals,
 | 
			
		||||
};
 | 
			
		||||
use log::{debug, error, info};
 | 
			
		||||
 | 
			
		||||
use crate::{FEEDBACK_STATE, UTC_TIME, drivers, feedback, init};
 | 
			
		||||
use chrono::{NaiveDateTime, TimeZone, Utc};
 | 
			
		||||
 | 
			
		||||
include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
 | 
			
		||||
 | 
			
		||||
const RTC_ADDRESS: u8 = 0x68;
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
pub async fn rtc_task() {
 | 
			
		||||
    info!("RTC task started");
 | 
			
		||||
    // Initialize I2C and RTC here
 | 
			
		||||
pub async fn rtc_task(
 | 
			
		||||
    i2c: i2c::master::I2c<'static, Async>,
 | 
			
		||||
    sqw_pin: peripherals::GPIO21<'static>,
 | 
			
		||||
) {
 | 
			
		||||
    UTC_TIME.signal(BUILD_UNIX_TIME);
 | 
			
		||||
    info!("Build time: {}", BUILD_UNIX_TIME);
 | 
			
		||||
 | 
			
		||||
    // i2c.write_async(RTC_ADDRESS, &[0x0E, 0b00000000]) // Clear control register
 | 
			
		||||
    // .await
 | 
			
		||||
    // .unwrap_or_else(|e| {
 | 
			
		||||
    //     FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
 | 
			
		||||
    //     error!("Failed to clear RTC control register: {:?}", e);
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    // debug!("init rtc interrupt");
 | 
			
		||||
    // let mut rtc_interrupt = init::hardware::setup_rtc_iterrupt(sqw_pin).await;
 | 
			
		||||
 | 
			
		||||
    debug!("configuring rtc");
 | 
			
		||||
    let mut rtc = drivers::rtc::rtc_config(i2c).await;
 | 
			
		||||
 | 
			
		||||
    debug!("rtc up");
 | 
			
		||||
    loop {
 | 
			
		||||
        // Read RTC time and update UTC_TIME signal
 | 
			
		||||
        // let utc_time = read_rtc_time(&mut rtc).await.unwrap();
 | 
			
		||||
        // UTC_TIME.signal(utc_time);
 | 
			
		||||
        //set_rtc_alarm(&mut rtc).await;
 | 
			
		||||
        // debug!("Waiting for RTC interrupt...");
 | 
			
		||||
        // rtc_interrupt.wait_for_falling_edge().await;
 | 
			
		||||
        // debug!("RTC interrupt triggered");
 | 
			
		||||
 | 
			
		||||
        // Simulate waiting for an interrupt or event
 | 
			
		||||
        Timer::after(Duration::from_millis(1000)).await;
 | 
			
		||||
        info!("RTC tick");
 | 
			
		||||
        //TODO use pub sub channel or something similar to send the time when needed
 | 
			
		||||
        let timestamp = drivers::rtc::read_rtc_time(&mut rtc).await;
 | 
			
		||||
        match timestamp {
 | 
			
		||||
            Ok(ts) => {
 | 
			
		||||
                UTC_TIME.signal(ts);
 | 
			
		||||
                info!("Current UTC time: {}", UTC_TIME.wait().await);
 | 
			
		||||
            }
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
 | 
			
		||||
                error!("Failed to read RTC datetime: {:?}", e);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>> {
 | 
			
		||||
    let mut rtc: DS3231<I2c<'static, Async>> = DS3231::new(i2c, RTC_ADDRESS);
 | 
			
		||||
    let naive_dt = Utc
 | 
			
		||||
        .timestamp_opt(BUILD_UNIX_TIME as i64, 0)
 | 
			
		||||
        .single()
 | 
			
		||||
        .unwrap()
 | 
			
		||||
        .naive_utc();
 | 
			
		||||
 | 
			
		||||
    let rtc_config = Config {
 | 
			
		||||
        time_representation: TimeRepresentation::TwentyFourHour,
 | 
			
		||||
        square_wave_frequency: SquareWaveFrequency::Hz1,
 | 
			
		||||
        interrupt_control: InterruptControl::Interrupt, // Enable interrupt mode
 | 
			
		||||
        battery_backed_square_wave: false,
 | 
			
		||||
        oscillator_enable: Oscillator::Disabled,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    match rtc.configure(&rtc_config).await {
 | 
			
		||||
        Ok(_) => info!("DS3231 configured successfully"),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            info!("Failed to configure DS3231: {:?}", e);
 | 
			
		||||
            panic!("DS3231 configuration failed");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtc.set_datetime(&naive_dt).await.unwrap_or_else(|e| {
 | 
			
		||||
        FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
 | 
			
		||||
        error!("Failed to set RTC datetime: {:?}", e);
 | 
			
		||||
    });
 | 
			
		||||
    info!("RTC datetime set to: {}", naive_dt);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    match rtc.status().await {
 | 
			
		||||
        Ok(mut status) => {
 | 
			
		||||
            status.set_alarm1_flag(false);
 | 
			
		||||
            status.set_alarm2_flag(false);
 | 
			
		||||
            match rtc.set_status(status).await {
 | 
			
		||||
                Ok(_) => info!("Alarm flags cleared"),
 | 
			
		||||
                Err(e) => info!("Failed to clear alarm flags: {:?}", e),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Err(e) => info!("Failed to read status: {:?}", e),
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    rtc
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub async fn read_rtc_time<'a>(
 | 
			
		||||
    rtc: &'a mut DS3231<I2c<'static, Async>>,
 | 
			
		||||
) -> Result<u64, DS3231Error<esp_hal::i2c::master::Error>> {
 | 
			
		||||
    let timestamp_result = rtc.datetime().await?;
 | 
			
		||||
    Ok(timestamp_result.and_utc().timestamp() as u64)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************************** */
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
// use ds3231::{Alarm1Config, DS3231, DS3231Error, Seconds};
 | 
			
		||||
// use embassy_time::{Duration, Timer};
 | 
			
		||||
// use esp_hal::{
 | 
			
		||||
//     Async,
 | 
			
		||||
//     i2c::{self, master::I2c},
 | 
			
		||||
//     peripherals,
 | 
			
		||||
// };
 | 
			
		||||
// use log::{debug, error, info};
 | 
			
		||||
 | 
			
		||||
// use crate::{UTC_TIME, drivers, init};
 | 
			
		||||
 | 
			
		||||
// const RTC_ADDRESS: u8 = 0x57;
 | 
			
		||||
 | 
			
		||||
// #[embassy_executor::task]
 | 
			
		||||
// pub async fn rtc_task(
 | 
			
		||||
//     //i2c: i2c::master::I2c<'static, Async>,
 | 
			
		||||
//     //sqw_pin: peripherals::GPIO21<'static>,
 | 
			
		||||
// ) {
 | 
			
		||||
//     //UTC_TIME.signal(155510);
 | 
			
		||||
 | 
			
		||||
//     // debug!("init rtc interrupt");
 | 
			
		||||
//     // let mut rtc_interrupt = init::hardware::setup_rtc_iterrupt(sqw_pin).await;
 | 
			
		||||
//     // debug!("configuring rtc");
 | 
			
		||||
//     // let mut rtc = drivers::rtc::rtc_config(i2c).await;
 | 
			
		||||
 | 
			
		||||
//     // let timestamp_result = drivers::rtc::read_rtc_time(&mut rtc).await;
 | 
			
		||||
//     // UTC_TIME.signal(timestamp_result.unwrap());
 | 
			
		||||
 | 
			
		||||
//     debug!("rtc up");
 | 
			
		||||
//     loop {
 | 
			
		||||
//         info!("Current UTC time: {}", UTC_TIME.wait().await);
 | 
			
		||||
//         // debug!("Waiting for RTC interrupt...");
 | 
			
		||||
//         // rtc_interrupt.wait_for_falling_edge().await;
 | 
			
		||||
//         // debug!("RTC interrupt triggered");
 | 
			
		||||
//         // let timestamp_result = drivers::rtc::read_rtc_time(&mut rtc).await;
 | 
			
		||||
//         // UTC_TIME.signal(timestamp_result.unwrap());
 | 
			
		||||
//         // Timer::after(Duration::from_secs(1)).await; // Debounce delay
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>> {
 | 
			
		||||
//     let mut rtc: DS3231<I2c<'static, Async>> = DS3231::new(i2c, RTC_ADDRESS);
 | 
			
		||||
//     let daily_alarm = Alarm1Config::AtTime {
 | 
			
		||||
//         hours: 0, // set alarm every day 00:00:00 to sync time
 | 
			
		||||
//         minutes: 0,
 | 
			
		||||
//         seconds: 10,
 | 
			
		||||
//         is_pm: None, // 24-hour mode
 | 
			
		||||
//     };
 | 
			
		||||
 | 
			
		||||
    // let naive_dt = chrono::NaiveDateTime::from_timestamp_opt(*utc_time as i64, 0)
 | 
			
		||||
    //     .expect("Invalid timestamp for NaiveDateTime");
 | 
			
		||||
    // rtc.set_datetime(&naive_dt).await.unwrap_or_else(|e| {
 | 
			
		||||
    //     error!("Failed to set RTC datetime: {:?}", e);
 | 
			
		||||
    //     panic!();
 | 
			
		||||
    // });
 | 
			
		||||
 | 
			
		||||
    // if let Err(e) = rtc.set_alarm1(&daily_alarm).await {
 | 
			
		||||
    //     error!("Failed to configure RTC: {:?}", e);
 | 
			
		||||
    //     panic!();
 | 
			
		||||
    // }
 | 
			
		||||
//     rtc
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// pub async fn read_rtc_time<'a>(
 | 
			
		||||
//     rtc: &'a mut DS3231<I2c<'static, Async>>,
 | 
			
		||||
// ) -> Result<u64, DS3231Error<esp_hal::i2c::master::Error>> {
 | 
			
		||||
//     match rtc.datetime().await {
 | 
			
		||||
//         Ok(datetime) => {
 | 
			
		||||
//             let utc_time = datetime.and_utc().timestamp() as u64;
 | 
			
		||||
//             Ok(utc_time)
 | 
			
		||||
//         }
 | 
			
		||||
//         Err(e) => {
 | 
			
		||||
//             FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
 | 
			
		||||
//             error!("Failed to read RTC datetime: {:?}", e);
 | 
			
		||||
//             Err(e)
 | 
			
		||||
//         }
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
    // let alarm_config = Alarm1Config::AtSeconds { seconds: 0};
 | 
			
		||||
 | 
			
		||||
    // match rtc.set_alarm1(&alarm_config).await {
 | 
			
		||||
    //     Ok(_) => info!("Alarm 1 set to trigger at seconds"),
 | 
			
		||||
    //     Err(e) => {
 | 
			
		||||
    //         FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
 | 
			
		||||
    //         error!("Failed to set Alarm 1: {:?}", e);
 | 
			
		||||
    //     }
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
/* ************************************************************************************** */
 | 
			
		||||
 | 
			
		||||
// #[embassy_executor::task]
 | 
			
		||||
// pub async fn rtc_task() {
 | 
			
		||||
//     info!("RTC task started");
 | 
			
		||||
//     // Initialize I2C and RTC here
 | 
			
		||||
 | 
			
		||||
//     loop {
 | 
			
		||||
//         // Read RTC time and update UTC_TIME signal
 | 
			
		||||
//         // let utc_time = read_rtc_time(&mut rtc).await.unwrap();
 | 
			
		||||
//         // UTC_TIME.signal(utc_time);
 | 
			
		||||
 | 
			
		||||
//         // Simulate waiting for an interrupt or event
 | 
			
		||||
//         Timer::after(Duration::from_millis(1000)).await;
 | 
			
		||||
//         info!("RTC tick");
 | 
			
		||||
//     }
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// }
 | 
			
		||||
 | 
			
		||||
// TODO Update time when device is connected other device over Wifi
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,15 @@ pub async fn feedback_task(buzzer: peripherals::GPIO19<'static>) {
 | 
			
		||||
                Timer::after(Duration::from_millis(100)).await;
 | 
			
		||||
                buzzer.set_low();
 | 
			
		||||
            }
 | 
			
		||||
            FeedbackState::Error => {}
 | 
			
		||||
            FeedbackState::Error => {
 | 
			
		||||
                buzzer.set_high();
 | 
			
		||||
                Timer::after(Duration::from_millis(500)).await;
 | 
			
		||||
                buzzer.set_low();
 | 
			
		||||
                Timer::after(Duration::from_millis(500)).await;
 | 
			
		||||
                buzzer.set_high();
 | 
			
		||||
                Timer::after(Duration::from_millis(500)).await;
 | 
			
		||||
                buzzer.set_low();
 | 
			
		||||
            }
 | 
			
		||||
            FeedbackState::Startup => {
 | 
			
		||||
                buzzer.set_high();
 | 
			
		||||
                Timer::after(Duration::from_millis(10)).await;
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										17
									
								
								src/main.rs
									
									
									
									
									
								
							@ -3,11 +3,10 @@
 | 
			
		||||
#![feature(type_alias_impl_trait)]
 | 
			
		||||
#![feature(impl_trait_in_assoc_type)]
 | 
			
		||||
 | 
			
		||||
use esp_alloc::EspHeap;
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::Stack;
 | 
			
		||||
use embassy_sync::{
 | 
			
		||||
    blocking_mutex::raw::{NoopRawMutex, CriticalSectionRawMutex},
 | 
			
		||||
    blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex},
 | 
			
		||||
    pubsub::{
 | 
			
		||||
        PubSubChannel, Publisher,
 | 
			
		||||
        WaitResult::{Lagged, Message},
 | 
			
		||||
@ -15,19 +14,18 @@ use embassy_sync::{
 | 
			
		||||
    signal::Signal,
 | 
			
		||||
};
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_alloc::EspHeap;
 | 
			
		||||
use log::{debug, info};
 | 
			
		||||
use static_cell::make_static;
 | 
			
		||||
 | 
			
		||||
use crate::{store::TallyID, webserver::start_webserver};
 | 
			
		||||
 | 
			
		||||
mod init;
 | 
			
		||||
mod drivers;
 | 
			
		||||
mod feedback;
 | 
			
		||||
mod init;
 | 
			
		||||
mod store;
 | 
			
		||||
mod webserver;
 | 
			
		||||
 | 
			
		||||
include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
 | 
			
		||||
 | 
			
		||||
static UTC_TIME: Signal<CriticalSectionRawMutex, u64> = Signal::new();
 | 
			
		||||
static FEEDBACK_STATE: Signal<CriticalSectionRawMutex, feedback::FeedbackState> = Signal::new();
 | 
			
		||||
 | 
			
		||||
@ -36,7 +34,6 @@ type TallyPublisher = Publisher<'static, NoopRawMutex, TallyID, 8, 2, 1>;
 | 
			
		||||
 | 
			
		||||
#[esp_hal_embassy::main]
 | 
			
		||||
async fn main(mut spawner: Spawner) {
 | 
			
		||||
 | 
			
		||||
    let (uart_device, stack, _i2c, sqw_pin, buzzer_gpio) =
 | 
			
		||||
        init::hardware::hardware_init(&mut spawner).await;
 | 
			
		||||
 | 
			
		||||
@ -58,7 +55,7 @@ async fn main(mut spawner: Spawner) {
 | 
			
		||||
    ));
 | 
			
		||||
 | 
			
		||||
    debug!("spawing rtc task");
 | 
			
		||||
    spawner.must_spawn(drivers::rtc::rtc_task());
 | 
			
		||||
    spawner.must_spawn(drivers::rtc::rtc_task(_i2c, sqw_pin));
 | 
			
		||||
 | 
			
		||||
    debug!("spawing feedback task..");
 | 
			
		||||
    spawner.must_spawn(feedback::feedback_task(buzzer_gpio));
 | 
			
		||||
@ -66,13 +63,11 @@ async fn main(mut spawner: Spawner) {
 | 
			
		||||
 | 
			
		||||
    let mut sub = chan.subscriber().unwrap();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    debug!("everythig spwawned");
 | 
			
		||||
    debug!("everything spawned");
 | 
			
		||||
    FEEDBACK_STATE.signal(feedback::FeedbackState::Startup);
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
 | 
			
		||||
        info!("runnung in main loop");
 | 
			
		||||
        info!("running in main loop");
 | 
			
		||||
        Timer::after(Duration::from_millis(1000)).await;
 | 
			
		||||
        // let wait_result = sub.next_message().await;
 | 
			
		||||
        // match wait_result {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user