···11-//! This example test the RP Pico W on board LED.
22-//!
33-//! It does not work with the RP Pico board.
44-51#![no_std]
62#![no_main]
73···1713use cyw43_pio::{DEFAULT_CLOCK_DIVIDER, PioSpi};
1814use defmt::info;
1915use defmt::*;
1616+use embassy_embedded_hal::shared_bus::blocking::i2c::I2cDevice;
2017use embassy_executor::Spawner;
2118use embassy_net::StackResources;
2219use embassy_net::dns::DnsSocket;
···3936use gpio::{Level, Output, Pull};
4037use heapless::{String, Vec};
4138use helpers::easy_format;
3939+use pcf85063a::PCF85063;
4240use reqwless::client::{HttpClient, TlsConfig, TlsVerify};
4341use reqwless::request::Method;
4442use save::{Save, read_postcard_from_flash, save_postcard_to_flash};
···5048mod badge_display;
5149mod env;
5250mod helpers;
5151+mod pcf85063a;
5352mod save;
5453mod temp_sensor;
5554···213212 &mut tls_write_buffer,
214213 TlsVerify::None,
215214 );
215215+ // let mut http_client = HttpClient::new(&tcp_client, &dns_client);
216216+ let mut http_client = HttpClient::new_with_tls(&tcp_client, &dns_client, tls_config);
216217217217- let mut http_client = HttpClient::new_with_tls(&tcp_client, &dns_client, tls_config);
218218 let url = env_value("TIME_API");
219219 info!("connecting to {}", &url);
220220221221- let mut request = match http_client.request(Method::GET, &url).await {
222222- Ok(req) => req,
223223- Err(e) => {
224224- error!("Failed to make HTTP request: {:?}", e);
225225- return; // handle the error
226226- }
227227- };
228228-229229- let response = match request.send(&mut rx_buffer).await {
230230- Ok(resp) => resp,
231231- Err(_e) => {
232232- error!("Failed to send HTTP request");
233233- return; // handle the error;
234234- }
235235- };
236236-237237- let body = match from_utf8(response.body().read_to_end().await.unwrap()) {
238238- Ok(b) => b,
239239- Err(_e) => {
240240- error!("Failed to read response body");
241241- return; // handle the error
242242- }
243243- };
244244- info!("Response body: {:?}", &body);
221221+ //If the call goes through set the rtc
222222+ match http_client.request(Method::GET, &url).await {
223223+ Ok(mut request) => {
224224+ let response = match request.send(&mut rx_buffer).await {
225225+ Ok(resp) => resp,
226226+ Err(e) => {
227227+ error!("Failed to send HTTP request: {:?}", e);
228228+ // error!("Failed to send HTTP request");
229229+ return; // handle the error;
230230+ }
231231+ };
245232246246- let bytes = body.as_bytes();
247247- match serde_json_core::de::from_slice::<TimeApiResponse>(bytes) {
248248- Ok((output, _used)) => {
249249- //Deadlines am i right?
250250- info!("Datetime: {:?}", output.datetime);
251251- //split at T
252252- let datetime = output.datetime.split('T').collect::<Vec<&str, 2>>();
253253- //split at -
254254- let date = datetime[0].split('-').collect::<Vec<&str, 3>>();
255255- let year = date[0].parse::<u16>().unwrap();
256256- let month = date[1].parse::<u8>().unwrap();
257257- let day = date[2].parse::<u8>().unwrap();
258258- //split at :
259259- let time = datetime[1].split(':').collect::<Vec<&str, 4>>();
260260- let hour = time[0].parse::<u8>().unwrap();
261261- let minute = time[1].parse::<u8>().unwrap();
262262- //split at .
263263- let second_split = time[2].split('.').collect::<Vec<&str, 2>>();
264264- let second = second_split[0].parse::<f64>().unwrap();
265265- let rtc_time = DateTime {
266266- year: year,
267267- month: month,
268268- day: day,
269269- day_of_week: match output.day_of_week {
270270- 0 => DayOfWeek::Sunday,
271271- 1 => DayOfWeek::Monday,
272272- 2 => DayOfWeek::Tuesday,
273273- 3 => DayOfWeek::Wednesday,
274274- 4 => DayOfWeek::Thursday,
275275- 5 => DayOfWeek::Friday,
276276- 6 => DayOfWeek::Saturday,
277277- _ => DayOfWeek::Sunday,
278278- },
279279- hour,
280280- minute,
281281- second: second as u8,
233233+ let body = match from_utf8(response.body().read_to_end().await.unwrap()) {
234234+ Ok(b) => b,
235235+ Err(_e) => {
236236+ error!("Failed to read response body");
237237+ return; // handle the error
238238+ }
282239 };
283283- rtc.set_datetime(rtc_time).unwrap();
284284- time_was_set = true;
285285- let _ = control.leave().await;
240240+ info!("Response body: {:?}", &body);
241241+242242+ let bytes = body.as_bytes();
243243+ match serde_json_core::de::from_slice::<TimeApiResponse>(bytes) {
244244+ Ok((output, _used)) => {
245245+ //Deadlines am i right?
246246+ info!("Datetime: {:?}", output.datetime);
247247+ //split at T
248248+ let datetime = output.datetime.split('T').collect::<Vec<&str, 2>>();
249249+ //split at -
250250+ let date = datetime[0].split('-').collect::<Vec<&str, 3>>();
251251+ let year = date[0].parse::<u16>().unwrap();
252252+ let month = date[1].parse::<u8>().unwrap();
253253+ let day = date[2].parse::<u8>().unwrap();
254254+ //split at :
255255+ let time = datetime[1].split(':').collect::<Vec<&str, 4>>();
256256+ let hour = time[0].parse::<u8>().unwrap();
257257+ let minute = time[1].parse::<u8>().unwrap();
258258+ //split at .
259259+ let second_split = time[2].split('.').collect::<Vec<&str, 2>>();
260260+ let second = second_split[0].parse::<f64>().unwrap();
261261+ let rtc_time = DateTime {
262262+ year: year,
263263+ month: month,
264264+ day: day,
265265+ day_of_week: match output.day_of_week {
266266+ 0 => DayOfWeek::Sunday,
267267+ 1 => DayOfWeek::Monday,
268268+ 2 => DayOfWeek::Tuesday,
269269+ 3 => DayOfWeek::Wednesday,
270270+ 4 => DayOfWeek::Thursday,
271271+ 5 => DayOfWeek::Friday,
272272+ 6 => DayOfWeek::Saturday,
273273+ _ => DayOfWeek::Sunday,
274274+ },
275275+ hour,
276276+ minute,
277277+ second: second as u8,
278278+ };
279279+ rtc.set_datetime(rtc_time).unwrap();
280280+ time_was_set = true;
281281+ let _ = control.leave().await;
282282+ }
283283+ Err(_e) => {
284284+ error!("Failed to parse response body");
285285+ // return; // handle the error
286286+ }
287287+ }
286288 }
287287- Err(_e) => {
288288- error!("Failed to parse response body");
289289+ Err(e) => {
290290+ error!("Failed to make HTTP request: {:?}", e);
289291 // return; // handle the error
290292 }
291291- }
293293+ };
292294 }
293295294296 //Set up saving
···302304 static I2C_BUS: StaticCell<I2c0Bus> = StaticCell::new();
303305 let i2c_bus = NoopMutex::new(RefCell::new(i2c));
304306 let i2c_bus = I2C_BUS.init(i2c_bus);
307307+308308+ let i2c_dev = I2cDevice::new(i2c_bus);
309309+ let mut rtc_device = PCF85063::new(i2c_dev);
305310306311 //Task spawning
307312 spawner.must_spawn(run_the_temp_sensor(i2c_bus));
+281
src/pcf85063a/alarm.rs
···11+use super::{BitFlags, Control, DEVICE_ADDRESS, Error, PCF85063, Register, decode_bcd, encode_bcd};
22+use embedded_hal_async::i2c::I2c;
33+use time::Time;
44+55+impl<I2C, E> PCF85063<I2C>
66+where
77+ I2C: I2c<Error = E>,
88+{
99+ /// Set the alarm seconds, minutes and hours, keeping the AE bit unchanged.
1010+ pub async fn set_alarm_time(&mut self, time: Time) -> Result<(), Error<E>> {
1111+ self.set_alarm_seconds(time.second()).await?;
1212+ self.set_alarm_minutes(time.minute()).await?;
1313+ self.set_alarm_hours(time.hour()).await?;
1414+ Ok(())
1515+ }
1616+1717+ /// Set the alarm seconds [0-59], keeping the AE bit unchanged.
1818+ pub fn set_alarm_seconds(&mut self, seconds: u8) -> Result<(), Error<E>> {
1919+ if seconds > 59 {
2020+ return Err(Error::InvalidInputData);
2121+ }
2222+ let data: u8 = self.read_register(Register::SECOND_ALARM)?; // read current value
2323+ let data: u8 = data & BitFlags::AE; // keep the AE bit as is
2424+ let setting: u8 = encode_bcd(seconds);
2525+ let data: u8 = data | setting;
2626+ self.write_register(Register::SECOND_ALARM, data).await
2727+ }
2828+2929+ /// Set the alarm minutes [0-59], keeping the AE bit unchanged.
3030+ pub async fn set_alarm_minutes(&mut self, minutes: u8) -> Result<(), Error<E>> {
3131+ if minutes > 59 {
3232+ return Err(Error::InvalidInputData);
3333+ }
3434+ let data: u8 = self.read_register(Register::MINUTE_ALARM).await?; // read current value
3535+ let data: u8 = data & BitFlags::AE; // keep the AE bit as is
3636+ let setting: u8 = encode_bcd(minutes);
3737+ let data: u8 = data | setting;
3838+ self.write_register(Register::MINUTE_ALARM, data).await
3939+ }
4040+4141+ /// Set the alarm hours [0-23], keeping the AE bit unchanged.
4242+ pub async fn set_alarm_hours(&mut self, hours: u8) -> Result<(), Error<E>> {
4343+ if hours > 23 {
4444+ return Err(Error::InvalidInputData);
4545+ }
4646+ let data: u8 = self.read_register(Register::HOUR_ALARM).await?; // read current value
4747+ let data: u8 = data & BitFlags::AE; // keep the AE bit as is
4848+ let setting: u8 = encode_bcd(hours);
4949+ let data: u8 = data | setting;
5050+ self.write_register(Register::HOUR_ALARM, data).await
5151+ }
5252+5353+ /// Set the alarm day [1-31], keeping the AE bit unchanged.
5454+ pub async fn set_alarm_day(&mut self, day: u8) -> Result<(), Error<E>> {
5555+ if !(1..=31).contains(&day) {
5656+ return Err(Error::InvalidInputData);
5757+ }
5858+ let data: u8 = self.read_register(Register::DAY_ALARM).await?; // read current value
5959+ let data: u8 = data & BitFlags::AE; // keep the AE bit as is
6060+ let setting: u8 = encode_bcd(day);
6161+ let data: u8 = data | setting;
6262+ self.write_register(Register::DAY_ALARM, data).await
6363+ }
6464+6565+ /// Set the alarm weekday [0-6], keeping the AE bit unchanged.
6666+ pub async fn set_alarm_weekday(&mut self, weekday: u8) -> Result<(), Error<E>> {
6767+ if weekday > 6 {
6868+ return Err(Error::InvalidInputData);
6969+ }
7070+ let data: u8 = self.read_register(Register::WEEKDAY_ALARM).await?; // read current value
7171+ let data: u8 = data & BitFlags::AE; // keep the AE bit as is
7272+ let setting: u8 = encode_bcd(weekday);
7373+ let data: u8 = data | setting;
7474+ self.write_register(Register::WEEKDAY_ALARM, data).await
7575+ }
7676+7777+ /// Control alarm seconds (On: alarm enabled, Off: alarm disabled).
7878+ pub async fn control_alarm_seconds(&mut self, status: Control) -> Result<(), Error<E>> {
7979+ match status {
8080+ Control::Off => {
8181+ self.set_register_bit_flag(Register::SECOND_ALARM, BitFlags::AE)
8282+ .await
8383+ }
8484+ Control::On => {
8585+ self.clear_register_bit_flag(Register::SECOND_ALARM, BitFlags::AE)
8686+ .await
8787+ }
8888+ }
8989+ }
9090+9191+ /// Is alarm seconds enabled?
9292+ pub async fn is_alarm_seconds_enabled(&mut self) -> Result<bool, Error<E>> {
9393+ Ok(!self
9494+ .is_register_bit_flag_high(Register::SECOND_ALARM, BitFlags::AE)
9595+ .await?)
9696+ }
9797+9898+ /// Control alarm minutes (On: alarm enabled, Off: alarm disabled).
9999+ pub async fn control_alarm_minutes(&mut self, status: Control) -> Result<(), Error<E>> {
100100+ match status {
101101+ Control::Off => {
102102+ self.set_register_bit_flag(Register::MINUTE_ALARM, BitFlags::AE)
103103+ .await
104104+ }
105105+ Control::On => {
106106+ self.clear_register_bit_flag(Register::MINUTE_ALARM, BitFlags::AE)
107107+ .await
108108+ }
109109+ }
110110+ }
111111+112112+ /// Is alarm minutes enabled?
113113+ pub async fn is_alarm_minutes_enabled(&mut self) -> Result<bool, Error<E>> {
114114+ Ok(!self
115115+ .is_register_bit_flag_high(Register::MINUTE_ALARM, BitFlags::AE)
116116+ .await?)
117117+ }
118118+119119+ /// Control alarm hours (On: alarm enabled, Off: alarm disabled).
120120+ pub async fn control_alarm_hours(&mut self, status: Control) -> Result<(), Error<E>> {
121121+ match status {
122122+ Control::Off => {
123123+ self.set_register_bit_flag(Register::HOUR_ALARM, BitFlags::AE)
124124+ .await
125125+ }
126126+ Control::On => {
127127+ self.clear_register_bit_flag(Register::HOUR_ALARM, BitFlags::AE)
128128+ .await
129129+ }
130130+ }
131131+ }
132132+133133+ /// Is alarm hours enabled?
134134+ pub async fn is_alarm_hours_enabled(&mut self) -> Result<bool, Error<E>> {
135135+ Ok(!self
136136+ .is_register_bit_flag_high(Register::HOUR_ALARM, BitFlags::AE)
137137+ .await?)
138138+ }
139139+140140+ /// Control alarm day (On: alarm enabled, Off: alarm disabled).
141141+ pub async fn control_alarm_day(&mut self, status: Control) -> Result<(), Error<E>> {
142142+ match status {
143143+ Control::Off => {
144144+ self.set_register_bit_flag(Register::DAY_ALARM, BitFlags::AE)
145145+ .await
146146+ }
147147+ Control::On => {
148148+ self.clear_register_bit_flag(Register::DAY_ALARM, BitFlags::AE)
149149+ .await
150150+ }
151151+ }
152152+ }
153153+154154+ /// Is alarm day enabled?
155155+ pub async fn is_alarm_day_enabled(&mut self) -> Result<bool, Error<E>> {
156156+ Ok(!self
157157+ .is_register_bit_flag_high(Register::DAY_ALARM, BitFlags::AE)
158158+ .await?)
159159+ }
160160+161161+ /// Control alarm weekday (On: alarm enabled, Off: alarm disabled).
162162+ pub async fn control_alarm_weekday(&mut self, status: Control) -> Result<(), Error<E>> {
163163+ match status {
164164+ Control::Off => {
165165+ self.set_register_bit_flag(Register::WEEKDAY_ALARM, BitFlags::AE)
166166+ .await
167167+ }
168168+ Control::On => {
169169+ self.clear_register_bit_flag(Register::WEEKDAY_ALARM, BitFlags::AE)
170170+ .await
171171+ }
172172+ }
173173+ }
174174+175175+ /// Is alarm weekday enabled?
176176+ pub async fn is_alarm_weekday_enabled(&mut self) -> Result<bool, Error<E>> {
177177+ Ok(!self
178178+ .is_register_bit_flag_high(Register::WEEKDAY_ALARM, BitFlags::AE)
179179+ .await?)
180180+ }
181181+182182+ /// Enable or disable alarm interrupt.
183183+ pub async fn control_alarm_interrupt(&mut self, status: Control) -> Result<(), Error<E>> {
184184+ match status {
185185+ Control::On => {
186186+ self.set_register_bit_flag(Register::CONTROL_2, BitFlags::AIE)
187187+ .await
188188+ }
189189+ Control::Off => {
190190+ self.clear_register_bit_flag(Register::CONTROL_2, BitFlags::AIE)
191191+ .await
192192+ }
193193+ }
194194+ }
195195+196196+ pub async fn get_alarm_time(&mut self) -> Result<Time, Error<E>> {
197197+ Ok(Time::from_hms(
198198+ self.get_alarm_hours().await?,
199199+ self.get_alarm_minutes().await?,
200200+ self.get_alarm_seconds().await?,
201201+ )?)
202202+ }
203203+204204+ /// Read the alarm seconds setting.
205205+ pub async fn get_alarm_seconds(&mut self) -> Result<u8, Error<E>> {
206206+ let mut data = [0];
207207+ self.i2c
208208+ .write_read(DEVICE_ADDRESS, &[Register::SECOND_ALARM], &mut data)
209209+ .await
210210+ .map_err(Error::I2C)?;
211211+ Ok(decode_bcd(data[0]))
212212+ }
213213+214214+ /// Read the alarm minutes setting.
215215+ pub async fn get_alarm_minutes(&mut self) -> Result<u8, Error<E>> {
216216+ let mut data = [0];
217217+ self.i2c
218218+ .write_read(DEVICE_ADDRESS, &[Register::MINUTE_ALARM], &mut data)
219219+ .await
220220+ .map_err(Error::I2C)?;
221221+ Ok(decode_bcd(data[0]))
222222+ }
223223+224224+ /// Read the alarm hours setting.
225225+ pub async fn get_alarm_hours(&mut self) -> Result<u8, Error<E>> {
226226+ let mut data = [0];
227227+ self.i2c
228228+ .write_read(DEVICE_ADDRESS, &[Register::HOUR_ALARM], &mut data)
229229+ .await
230230+ .map_err(Error::I2C)?;
231231+ Ok(decode_bcd(data[0]))
232232+ }
233233+234234+ /// Read the alarm day setting.
235235+ pub async fn get_alarm_day(&mut self) -> Result<u8, Error<E>> {
236236+ let mut data = [0];
237237+ self.i2c
238238+ .write_read(DEVICE_ADDRESS, &[Register::DAY_ALARM], &mut data)
239239+ .await
240240+ .map_err(Error::I2C)?;
241241+ Ok(decode_bcd(data[0]))
242242+ }
243243+244244+ /// Read the alarm weekday setting.
245245+ pub async fn get_alarm_weekday(&mut self) -> Result<u8, Error<E>> {
246246+ let mut data = [0];
247247+ self.i2c
248248+ .write_read(DEVICE_ADDRESS, &[Register::WEEKDAY_ALARM], &mut data)
249249+ .await
250250+ .map_err(Error::I2C)?;
251251+ Ok(decode_bcd(data[0]))
252252+ }
253253+254254+ /// Get the alarm flag (if true, alarm event happened).
255255+ pub async fn get_alarm_flag(&mut self) -> Result<bool, Error<E>> {
256256+ self.is_register_bit_flag_high(Register::CONTROL_2, BitFlags::AF)
257257+ .await
258258+ }
259259+260260+ /// Clear the alarm flag.
261261+ pub async fn clear_alarm_flag(&mut self) -> Result<(), Error<E>> {
262262+ self.clear_register_bit_flag(Register::CONTROL_2, BitFlags::AF)
263263+ .await
264264+ }
265265+266266+ /// Check if alarm interrupt is enabled.
267267+ pub async fn is_alarm_interrupt_enabled(&mut self) -> Result<bool, Error<E>> {
268268+ self.is_register_bit_flag_high(Register::CONTROL_2, BitFlags::AIE)
269269+ .await
270270+ }
271271+272272+ /// Shut off the alarms at once.
273273+ pub async fn disable_all_alarms(&mut self) -> Result<(), Error<E>> {
274274+ self.control_alarm_seconds(Control::Off).await?;
275275+ self.control_alarm_minutes(Control::Off).await?;
276276+ self.control_alarm_hours(Control::Off).await?;
277277+ self.control_alarm_day(Control::Off).await?;
278278+ self.control_alarm_weekday(Control::Off).await?;
279279+ Ok(())
280280+ }
281281+}
+72
src/pcf85063a/datetime.rs
···11+//! All date and time-related functions will be defined here.
22+//!
33+//! Reading and setting single elements (seconds, hours, months) will NOT be implemented
44+//! following the recommendations in the NXP datasheet to set and read all the seven date and time registers in one go.
55+//!
66+//! TO DO: As the chip may be used for devices that are clocks only, without the calendar function
77+//! a convenient set_time() function could be added (sets only seconds, minutes and hours)
88+99+use super::{DEVICE_ADDRESS, Error, PCF85063, Register, decode_bcd, encode_bcd};
1010+use embedded_hal_async::i2c::I2c;
1111+use time::{Date, PrimitiveDateTime, Time};
1212+1313+impl<I2C, E> PCF85063<I2C>
1414+where
1515+ I2C: I2c<Error = E>,
1616+{
1717+ /// Read date and time all at once.
1818+ pub async fn get_datetime(&mut self) -> Result<PrimitiveDateTime, Error<E>> {
1919+ let mut data = [0; 7];
2020+ self.i2c
2121+ .write_read(DEVICE_ADDRESS, &[Register::SECONDS], &mut data)
2222+ .await
2323+ .map_err(Error::I2C)?;
2424+2525+ Ok(PrimitiveDateTime::new(
2626+ Date::from_calendar_date(
2727+ 2000 + decode_bcd(data[6]) as i32,
2828+ decode_bcd(data[5] & 0x1f).try_into()?,
2929+ decode_bcd(data[3] & 0x3f),
3030+ )?,
3131+ Time::from_hms(
3232+ decode_bcd(data[2] & 0x3f),
3333+ decode_bcd(data[1] & 0b0111_1111),
3434+ decode_bcd(data[0] & 0b0111_1111),
3535+ )?,
3636+ ))
3737+ }
3838+3939+ /// Set date and time all at once.
4040+ pub async fn set_datetime(&mut self, datetime: &PrimitiveDateTime) -> Result<(), Error<E>> {
4141+ let payload = [
4242+ Register::SECONDS, //first register
4343+ encode_bcd(datetime.second()),
4444+ encode_bcd(datetime.minute()),
4545+ encode_bcd(datetime.hour()),
4646+ encode_bcd(datetime.day()),
4747+ encode_bcd(datetime.weekday().number_days_from_sunday()),
4848+ encode_bcd(datetime.month().into()),
4949+ encode_bcd((datetime.year() - 2000) as u8),
5050+ ];
5151+ self.i2c
5252+ .write(DEVICE_ADDRESS, &payload)
5353+ .await
5454+ .map_err(Error::I2C)
5555+ }
5656+5757+ /// Set only the time, date remains unchanged.
5858+ ///
5959+ /// Will return an 'Error::InvalidInputData' if any of the parameters is out of range.
6060+ pub async fn set_time(&mut self, time: &Time) -> Result<(), Error<E>> {
6161+ let payload = [
6262+ Register::SECONDS, //first register
6363+ encode_bcd(time.second()),
6464+ encode_bcd(time.minute()),
6565+ encode_bcd(time.hour()),
6666+ ];
6767+ self.i2c
6868+ .write(DEVICE_ADDRESS, &payload)
6969+ .await
7070+ .map_err(Error::I2C)
7171+ }
7272+}