mirror of
				https://github.com/Djeeberjr/fw-anwesenheit.git
				synced 2025-11-04 07:34:10 +00:00 
			
		
		
		
	reworked RTC without alarms and without own thread
This commit is contained in:
		
							parent
							
								
									2f502e908e
								
							
						
					
					
						commit
						1ae5250449
					
				@ -1,64 +1,43 @@
 | 
			
		||||
use core::time;
 | 
			
		||||
 | 
			
		||||
use chrono::NaiveDate;
 | 
			
		||||
use ds3231::{
 | 
			
		||||
    Alarm1Config, Config, DS3231, DS3231Error, InterruptControl, Oscillator, Seconds,
 | 
			
		||||
    SquareWaveFrequency, TimeRepresentation,
 | 
			
		||||
    Config, DS3231, DS3231Error, InterruptControl, Oscillator, 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};
 | 
			
		||||
use crate::{FEEDBACK_STATE, drivers, feedback};
 | 
			
		||||
use chrono::{TimeZone, Utc};
 | 
			
		||||
 | 
			
		||||
include!(concat!(env!("OUT_DIR"), "/build_time.rs"));
 | 
			
		||||
 | 
			
		||||
const RTC_ADDRESS: u8 = 0x68;
 | 
			
		||||
 | 
			
		||||
#[embassy_executor::task]
 | 
			
		||||
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);
 | 
			
		||||
pub struct RTCClock {
 | 
			
		||||
    dev: DS3231<I2c<'static, Async>>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
    // 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);
 | 
			
		||||
    // });
 | 
			
		||||
impl RTCClock {
 | 
			
		||||
    pub async fn new(i2c: i2c::master::I2c<'static, Async>) -> Self {
 | 
			
		||||
        debug!("configuring rtc...");
 | 
			
		||||
        let rtc = drivers::rtc::rtc_config(i2c).await;
 | 
			
		||||
        debug!("rtc up");
 | 
			
		||||
 | 
			
		||||
    // debug!("init rtc interrupt");
 | 
			
		||||
    // let mut rtc_interrupt = init::hardware::setup_rtc_iterrupt(sqw_pin).await;
 | 
			
		||||
        RTCClock { dev: rtc }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    debug!("configuring rtc");
 | 
			
		||||
    let mut rtc = drivers::rtc::rtc_config(i2c).await;
 | 
			
		||||
 | 
			
		||||
    debug!("rtc up");
 | 
			
		||||
    loop {
 | 
			
		||||
        //set_rtc_alarm(&mut rtc).await;
 | 
			
		||||
        // debug!("Waiting for RTC interrupt...");
 | 
			
		||||
        // rtc_interrupt.wait_for_falling_edge().await;
 | 
			
		||||
        // debug!("RTC interrupt triggered");
 | 
			
		||||
 | 
			
		||||
        Timer::after(Duration::from_millis(1000)).await;
 | 
			
		||||
        //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);
 | 
			
		||||
    pub async fn get_time(&mut self) -> u64 {
 | 
			
		||||
        match self.dev.datetime().await {
 | 
			
		||||
            Ok(datetime) => {
 | 
			
		||||
                let utc_time = datetime.and_utc().timestamp() as u64;
 | 
			
		||||
                utc_time
 | 
			
		||||
            }
 | 
			
		||||
            Err(e) => {
 | 
			
		||||
                FEEDBACK_STATE.signal(feedback::FeedbackState::Error);
 | 
			
		||||
                error!("Failed to read RTC datetime: {:?}", e);
 | 
			
		||||
                0
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@ -94,7 +73,6 @@ pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>>
 | 
			
		||||
    });
 | 
			
		||||
    info!("RTC datetime set to: {}", naive_dt);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    match rtc.status().await {
 | 
			
		||||
        Ok(mut status) => {
 | 
			
		||||
            status.set_alarm1_flag(false);
 | 
			
		||||
@ -110,67 +88,9 @@ pub async fn rtc_config(i2c: I2c<'static, Async>) -> DS3231<I2c<'static, Async>>
 | 
			
		||||
    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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//     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
 | 
			
		||||
/* pub async fn update_rtc_time<'a>(rtc: &'a mut DS3231<I2c<'static, Async>>, datetime: u64) -> Result<(), DS3231Error<esp_hal::i2c::master::Error>> {
 | 
			
		||||
 | 
			
		||||
    match rtc.set_datetime(datetime).await {
 | 
			
		||||
        info!("RTC datetime updated to: {}", datetime);
 | 
			
		||||
        Ok(_) => Ok(()),
 | 
			
		||||
        Err(e) => {
 | 
			
		||||
            error!("Failed to update RTC datetime: {:?}", e);
 | 
			
		||||
            Err(e)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
@ -1,32 +1,35 @@
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::{driver, Stack};
 | 
			
		||||
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
 | 
			
		||||
use embassy_net::{Stack, driver};
 | 
			
		||||
use embassy_sync::blocking_mutex::Mutex;
 | 
			
		||||
use embassy_sync::blocking_mutex::raw::NoopRawMutex;
 | 
			
		||||
use esp_hal::config;
 | 
			
		||||
use esp_hal::gpio::{Input, Pull};
 | 
			
		||||
use esp_hal::i2c::master::Config;
 | 
			
		||||
use esp_hal::peripherals::{self, GPIO0, GPIO1, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO19, GPIO21, GPIO22, GPIO23, I2C0, UART1};
 | 
			
		||||
use esp_hal::peripherals::{
 | 
			
		||||
    self, GPIO0, GPIO1, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, GPIO19, GPIO21, GPIO22, GPIO23, I2C0,
 | 
			
		||||
    UART1,
 | 
			
		||||
};
 | 
			
		||||
use esp_hal::time::Rate;
 | 
			
		||||
use esp_hal::{
 | 
			
		||||
    Async,
 | 
			
		||||
    clock::CpuClock,
 | 
			
		||||
    gpio::{Output, OutputConfig},
 | 
			
		||||
    i2c::master::I2c,
 | 
			
		||||
    timer::{systimer::SystemTimer, timg::TimerGroup},
 | 
			
		||||
    uart::Uart,
 | 
			
		||||
    i2c::master::I2c,
 | 
			
		||||
    gpio::{Output, OutputConfig}
 | 
			
		||||
};
 | 
			
		||||
use esp_println::logger::init_logger;
 | 
			
		||||
use log::{debug, error};
 | 
			
		||||
 | 
			
		||||
use crate::init::wifi;
 | 
			
		||||
use crate::init::network;
 | 
			
		||||
use crate::init::wifi;
 | 
			
		||||
 | 
			
		||||
/*************************************************
 | 
			
		||||
 * GPIO Pinout Xiao Esp32c6 
 | 
			
		||||
 * GPIO Pinout Xiao Esp32c6
 | 
			
		||||
 *
 | 
			
		||||
 * D0 -> GPIO0  -> Level Shifter OE
 | 
			
		||||
 * D1 -> GPIO1  -> Level Shifter A0 -> LED
 | 
			
		||||
 * D3 -> GPIO21 -> SQW Interrupt RTC
 | 
			
		||||
 * D3 -> GPIO21 -> SQW Interrupt RTC //not in use anymore
 | 
			
		||||
 * D4 -> GPIO22 -> SDA
 | 
			
		||||
 * D5 -> GPIO23 -> SCL
 | 
			
		||||
 * D7 -> GPIO17 -> Level Shifter A1 -> NFC Reader
 | 
			
		||||
@ -41,9 +44,14 @@ fn panic(_: &core::panic::PanicInfo) -> ! {
 | 
			
		||||
 | 
			
		||||
esp_bootloader_esp_idf::esp_app_desc!();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
pub async fn hardware_init(spawner: &mut Spawner) -> (Uart<'static, Async>, Stack<'static>, I2c<'static, Async>, GPIO21<'static>, GPIO19<'static>) {
 | 
			
		||||
pub async fn hardware_init(
 | 
			
		||||
    spawner: &mut Spawner,
 | 
			
		||||
) -> (
 | 
			
		||||
    Uart<'static, Async>,
 | 
			
		||||
    Stack<'static>,
 | 
			
		||||
    I2c<'static, Async>,
 | 
			
		||||
    GPIO19<'static>,
 | 
			
		||||
) {
 | 
			
		||||
    let config = esp_hal::Config::default().with_cpu_clock(CpuClock::max());
 | 
			
		||||
    let peripherals = esp_hal::init(config);
 | 
			
		||||
 | 
			
		||||
@ -68,19 +76,17 @@ pub async fn hardware_init(spawner: &mut Spawner) -> (Uart<'static, Async>, Stac
 | 
			
		||||
 | 
			
		||||
    let i2c_device = setup_i2c(peripherals.I2C0, peripherals.GPIO22, peripherals.GPIO23);
 | 
			
		||||
 | 
			
		||||
    //RTC Interrupt pin
 | 
			
		||||
    let sqw_pin = peripherals.GPIO21;
 | 
			
		||||
 | 
			
		||||
    let buzzer_gpio = peripherals.GPIO19;
 | 
			
		||||
 | 
			
		||||
    debug!("hardware init done");
 | 
			
		||||
 | 
			
		||||
    (uart_device, stack, i2c_device, sqw_pin, buzzer_gpio)
 | 
			
		||||
    (uart_device, stack, i2c_device, buzzer_gpio)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initialize the level shifter for the NFC reader and LED (output-enable (OE) input is low, all outputs are placed in the high-impedance (Hi-Z) state)
 | 
			
		||||
fn init_lvl_shifter(oe_pin: GPIO0<'static>){
 | 
			
		||||
    let mut oe_lvl_shifter = Output::new(oe_pin, esp_hal::gpio::Level::Low, OutputConfig::default());
 | 
			
		||||
fn init_lvl_shifter(oe_pin: GPIO0<'static>) {
 | 
			
		||||
    let mut oe_lvl_shifter =
 | 
			
		||||
        Output::new(oe_pin, esp_hal::gpio::Level::Low, OutputConfig::default());
 | 
			
		||||
    oe_lvl_shifter.set_high();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -125,13 +131,11 @@ pub async fn setup_rtc_iterrupt(sqw_pin: GPIO21<'static>) -> Input<'static> {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn setup_buzzer(buzzer_gpio: GPIO19<'static>) -> Output<'static> {
 | 
			
		||||
    let config = esp_hal::gpio::OutputConfig::default().with_drive_strength(esp_hal::gpio::DriveStrength::_40mA);
 | 
			
		||||
    let config = esp_hal::gpio::OutputConfig::default()
 | 
			
		||||
        .with_drive_strength(esp_hal::gpio::DriveStrength::_40mA);
 | 
			
		||||
    let buzzer = Output::new(buzzer_gpio, esp_hal::gpio::Level::Low, config);
 | 
			
		||||
 | 
			
		||||
    buzzer
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fn setup_spi_led() {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
fn setup_spi_led() {}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										19
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								src/main.rs
									
									
									
									
									
								
							@ -6,15 +6,12 @@
 | 
			
		||||
use embassy_executor::Spawner;
 | 
			
		||||
use embassy_net::Stack;
 | 
			
		||||
use embassy_sync::{
 | 
			
		||||
    blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex},
 | 
			
		||||
    pubsub::{
 | 
			
		||||
    blocking_mutex::raw::{CriticalSectionRawMutex, NoopRawMutex}, channel::Channel, pubsub::{
 | 
			
		||||
        PubSubChannel, Publisher,
 | 
			
		||||
        WaitResult::{Lagged, Message},
 | 
			
		||||
    },
 | 
			
		||||
    signal::Signal,
 | 
			
		||||
    }, signal::Signal
 | 
			
		||||
};
 | 
			
		||||
use embassy_time::{Duration, Timer};
 | 
			
		||||
use esp_alloc::EspHeap;
 | 
			
		||||
use log::{debug, info};
 | 
			
		||||
use static_cell::make_static;
 | 
			
		||||
 | 
			
		||||
@ -26,7 +23,6 @@ mod init;
 | 
			
		||||
mod store;
 | 
			
		||||
mod webserver;
 | 
			
		||||
 | 
			
		||||
static UTC_TIME: Signal<CriticalSectionRawMutex, u64> = Signal::new();
 | 
			
		||||
static FEEDBACK_STATE: Signal<CriticalSectionRawMutex, feedback::FeedbackState> = Signal::new();
 | 
			
		||||
 | 
			
		||||
type TallyChannel = PubSubChannel<NoopRawMutex, TallyID, 8, 2, 1>;
 | 
			
		||||
@ -34,7 +30,7 @@ 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) =
 | 
			
		||||
    let (uart_device, stack, _i2c, buzzer_gpio) =
 | 
			
		||||
        init::hardware::hardware_init(&mut spawner).await;
 | 
			
		||||
 | 
			
		||||
    wait_for_stack_up(stack).await;
 | 
			
		||||
@ -47,6 +43,8 @@ async fn main(mut spawner: Spawner) {
 | 
			
		||||
 | 
			
		||||
    let publisher = chan.publisher().unwrap();
 | 
			
		||||
 | 
			
		||||
    let mut rtc = drivers::rtc::RTCClock::new(_i2c).await;
 | 
			
		||||
 | 
			
		||||
    /****************************** Spawning tasks ***********************************/
 | 
			
		||||
    debug!("spawing NFC reader task...");
 | 
			
		||||
    spawner.must_spawn(drivers::nfc_reader::rfid_reader_task(
 | 
			
		||||
@ -54,9 +52,6 @@ async fn main(mut spawner: Spawner) {
 | 
			
		||||
        publisher,
 | 
			
		||||
    ));
 | 
			
		||||
 | 
			
		||||
    debug!("spawing rtc task");
 | 
			
		||||
    spawner.must_spawn(drivers::rtc::rtc_task(_i2c, sqw_pin));
 | 
			
		||||
 | 
			
		||||
    debug!("spawing feedback task..");
 | 
			
		||||
    spawner.must_spawn(feedback::feedback_task(buzzer_gpio));
 | 
			
		||||
    /******************************************************************************/
 | 
			
		||||
@ -67,8 +62,10 @@ async fn main(mut spawner: Spawner) {
 | 
			
		||||
    FEEDBACK_STATE.signal(feedback::FeedbackState::Startup);
 | 
			
		||||
 | 
			
		||||
    loop {
 | 
			
		||||
        info!("running in main loop");
 | 
			
		||||
        rtc.get_time().await;
 | 
			
		||||
        info!("Current RTC time: {}", rtc.get_time().await);
 | 
			
		||||
        Timer::after(Duration::from_millis(1000)).await;
 | 
			
		||||
 | 
			
		||||
        // let wait_result = sub.next_message().await;
 | 
			
		||||
        // match wait_result {
 | 
			
		||||
        //     Lagged(_) => debug!("Lagged"),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user