A personal rust firmware for the Badger 2040 W
at main 67 lines 2.6 kB view raw
1//! All date and time-related functions will be defined here. 2//! 3//! Reading and setting single elements (seconds, hours, months) will NOT be implemented 4//! following the recommendations in the NXP datasheet to set and read all the seven date and time registers in one go. 5//! 6//! TO DO: As the chip may be used for devices that are clocks only, without the calendar function 7//! a convenient set_time() function could be added (sets only seconds, minutes and hours) 8 9use super::{DEVICE_ADDRESS, Error, PCF85063, Register, decode_bcd, encode_bcd}; 10use embassy_rp::rtc::DateTime; 11use embedded_hal_1::i2c::I2c; 12use time::{Date, PrimitiveDateTime, Time}; 13 14impl<I2C, E> PCF85063<I2C> 15where 16 I2C: I2c<Error = E>, 17{ 18 /// Read date and time all at once. 19 pub fn get_datetime(&mut self) -> Result<PrimitiveDateTime, Error<E>> { 20 let mut data = [0; 7]; 21 self.i2c 22 .write_read(DEVICE_ADDRESS, &[Register::SECONDS], &mut data) 23 .map_err(Error::I2C)?; 24 25 Ok(PrimitiveDateTime::new( 26 Date::from_calendar_date( 27 2000 + decode_bcd(data[6]) as i32, 28 decode_bcd(data[5] & 0x1f).try_into()?, 29 decode_bcd(data[3] & 0x3f), 30 )?, 31 Time::from_hms( 32 decode_bcd(data[2] & 0x3f), 33 decode_bcd(data[1] & 0b0111_1111), 34 decode_bcd(data[0] & 0b0111_1111), 35 )?, 36 )) 37 } 38 39 /// Set date and time all at once. 40 pub fn set_datetime(&mut self, datetime: &DateTime) -> Result<(), Error<E>> { 41 let payload = [ 42 Register::SECONDS, //first register 43 encode_bcd(datetime.second), 44 encode_bcd(datetime.minute), 45 encode_bcd(datetime.hour), 46 encode_bcd(datetime.day), 47 //Not sure if this is correct 48 encode_bcd(datetime.day_of_week as u8), 49 encode_bcd(datetime.month), 50 encode_bcd((datetime.year - 2000) as u8), 51 ]; 52 self.i2c.write(DEVICE_ADDRESS, &payload).map_err(Error::I2C) 53 } 54 55 /// Set only the time, date remains unchanged. 56 /// 57 /// Will return an 'Error::InvalidInputData' if any of the parameters is out of range. 58 pub fn set_time(&mut self, time: &Time) -> Result<(), Error<E>> { 59 let payload = [ 60 Register::SECONDS, //first register 61 encode_bcd(time.second()), 62 encode_bcd(time.minute()), 63 encode_bcd(time.hour()), 64 ]; 65 self.i2c.write(DEVICE_ADDRESS, &payload).map_err(Error::I2C) 66 } 67}