diff --git a/src/drivers/rtc.rs b/src/drivers/rtc.rs index 14162d4..1575e4e 100644 --- a/src/drivers/rtc.rs +++ b/src/drivers/rtc.rs @@ -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.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> }); 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> rtc } - pub async fn read_rtc_time<'a>( rtc: &'a mut DS3231>, ) -> Result> { 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>, datetime: u64) -> Result<(), DS3231Error> { - - 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) - } - } -} - */ diff --git a/src/init/hardware.rs b/src/init/hardware.rs index 2fbc198..8ff1ea0 100644 --- a/src/init/hardware.rs +++ b/src/init/hardware.rs @@ -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() { - -} \ No newline at end of file +fn setup_spi_led() {} diff --git a/src/main.rs b/src/main.rs index 238854e..c127d56 100644 --- a/src/main.rs +++ b/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 = Signal::new(); static FEEDBACK_STATE: Signal = Signal::new(); type TallyChannel = PubSubChannel; @@ -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"),