1use super::{I2c, RegisterInterface, bisync, only_async, only_sync};
2use crate::{
3 Alarm, ClkoutFrequency, DateTime, PCF8563_I2C_ADDR, Pcf8563Interface, Pcf8563LowLevel,
4 RtcError, Time, TimerFrequency, bcd_to_dec, dec_to_bcd,
5};
6#[cfg(feature = "rtcc")]
7#[only_sync]
8use rtcc::{
9 Datelike as RtccDatelike, Hours as RtccHours, NaiveDate as RtccNaiveDate,
10 NaiveDateTime as RtccNaiveDateTime, NaiveTime as RtccNaiveTime, Timelike as RtccTimelike,
11};
12
13#[bisync]
14impl<I2CBus, E> RegisterInterface for Pcf8563Interface<I2CBus>
15where
16 I2CBus: I2c<Error = E>,
17 E: core::fmt::Debug,
18{
19 type AddressType = u8;
20 type Error = RtcError<E>;
21 async fn read_register(
22 &mut self,
23 address: u8,
24 _size_bits: u32,
25 data: &mut [u8],
26 ) -> Result<(), Self::Error> {
27 self.i2c_bus
28 .write_read(PCF8563_I2C_ADDR, &[address], data)
29 .await
30 .map_err(RtcError::I2c)
31 }
32 async fn write_register(
33 &mut self,
34 address: u8,
35 _size_bits: u32,
36 data: &[u8],
37 ) -> Result<(), Self::Error> {
38 let mut buffer = [0u8; 9]; if (1 + data.len()) > buffer.len() {
40 return Err(RtcError::InvalidInputData);
41 }
42 buffer[0] = address;
43 buffer[1..1 + data.len()].copy_from_slice(data);
44 self.i2c_bus
45 .write(PCF8563_I2C_ADDR, &buffer[..1 + data.len()])
46 .await
47 .map_err(RtcError::I2c)
48 }
49}
50
51pub struct Pcf8563<
52 I2CImpl: RegisterInterface<AddressType = u8, Error = RtcError<I2CBusErr>>,
53 I2CBusErr: core::fmt::Debug,
54> {
55 pub ll: Pcf8563LowLevel<I2CImpl>,
56 _marker: core::marker::PhantomData<I2CBusErr>,
57}
58
59impl<I2CBus, E> Pcf8563<Pcf8563Interface<I2CBus>, E>
60where
61 I2CBus: I2c<Error = E>,
62 E: core::fmt::Debug,
63{
64 pub fn new(i2c: I2CBus) -> Self {
65 Self {
66 ll: Pcf8563LowLevel::new(Pcf8563Interface::new(i2c)),
67 _marker: core::marker::PhantomData,
68 }
69 }
70}
71
72include!("bisync_helpers.rs");
73
74impl<I2CImpl, I2CBusErr> Pcf8563<I2CImpl, I2CBusErr>
75where
76 I2CImpl: RegisterInterface<AddressType = u8, Error = RtcError<I2CBusErr>>,
77 I2CBusErr: core::fmt::Debug,
78{
79 #[bisync]
88 pub async fn get_datetime(&mut self) -> Result<DateTime, RtcError<I2CBusErr>> {
89 let mut buf = [0u8; 7];
98 self.ll.interface().read_register(0x02, 0, &mut buf).await?;
99
100 Ok(DateTime {
101 seconds: bcd_to_dec(buf[0] & 0x7F), minutes: bcd_to_dec(buf[1] & 0x7F),
103 hours: bcd_to_dec(buf[2] & 0x3F),
104 day: bcd_to_dec(buf[3] & 0x3F),
105 weekday: buf[4] & 0x07,
106 month: bcd_to_dec(buf[5] & 0x1F), year: bcd_to_dec(buf[6]),
108 })
109 }
110
111 #[bisync]
116 pub async fn set_datetime(&mut self, dt: &DateTime) -> Result<(), RtcError<I2CBusErr>> {
117 if dt.year > 99
119 || dt.month < 1
120 || dt.month > 12
121 || dt.weekday > 6
122 || dt.day < 1
123 || dt.day > 31
124 || dt.hours > 23
125 || dt.minutes > 59
126 || dt.seconds > 59
127 {
128 return Err(RtcError::InvalidInputData);
129 }
130
131 let buf = [
133 dec_to_bcd(dt.seconds) & 0x7F, dec_to_bcd(dt.minutes),
135 dec_to_bcd(dt.hours),
136 dec_to_bcd(dt.day),
137 dt.weekday,
138 dec_to_bcd(dt.month), dec_to_bcd(dt.year),
140 ];
141 self.ll.interface().write_register(0x02, 0, &buf).await?;
142
143 Ok(())
144 }
145
146 #[bisync]
148 pub async fn set_time(&mut self, time: &Time) -> Result<(), RtcError<I2CBusErr>> {
149 if time.hours > 23 || time.minutes > 59 || time.seconds > 59 {
150 return Err(RtcError::InvalidInputData);
151 }
152
153 let seconds_bcd = dec_to_bcd(time.seconds);
154 let minutes_bcd = dec_to_bcd(time.minutes);
155 let hours_bcd = dec_to_bcd(time.hours);
156
157 let mut op_sec = self.ll.seconds();
158 write_internal(&mut op_sec, |r| {
159 r.set_vl(false);
160 r.set_seconds_ten(seconds_bcd >> 4);
161 r.set_seconds_unit(seconds_bcd & 0x0F);
162 })
163 .await?;
164
165 let mut op_min = self.ll.minutes();
166 write_internal(&mut op_min, |r| {
167 r.set_minutes_ten(minutes_bcd >> 4);
168 r.set_minutes_unit(minutes_bcd & 0x0F);
169 })
170 .await?;
171
172 let mut op_hr = self.ll.hours();
173 write_internal(&mut op_hr, |r| {
174 r.set_hours_ten(hours_bcd >> 4);
175 r.set_hours_unit(hours_bcd & 0x0F);
176 })
177 .await?;
178
179 Ok(())
180 }
181
182 #[bisync]
191 pub async fn is_clock_valid(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
192 let mut op = self.ll.seconds();
193 let reg = read_internal(&mut op).await?;
194 Ok(!reg.vl())
195 }
196
197 #[bisync]
201 pub async fn clear_voltage_low_flag(&mut self) -> Result<(), RtcError<I2CBusErr>> {
202 let mut op = self.ll.seconds();
203 modify_internal(&mut op, |r| r.set_vl(false)).await
204 }
205
206 #[bisync]
214 pub async fn get_century_flag(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
215 let mut op = self.ll.century_months();
216 let reg = read_internal(&mut op).await?;
217 Ok(reg.century())
218 }
219
220 #[bisync]
222 pub async fn set_century_flag(&mut self, century: bool) -> Result<(), RtcError<I2CBusErr>> {
223 let mut op = self.ll.century_months();
224 modify_internal(&mut op, |r| r.set_century(century)).await
225 }
226
227 #[bisync]
233 pub async fn set_clock_running(&mut self, running: bool) -> Result<(), RtcError<I2CBusErr>> {
234 let mut op = self.ll.control_status_1();
235 modify_internal(&mut op, |r| r.set_stop(!running)).await
236 }
237
238 #[bisync]
240 pub async fn is_clock_running(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
241 let mut op = self.ll.control_status_1();
242 let reg = read_internal(&mut op).await?;
243 Ok(!reg.stop())
244 }
245
246 #[bisync]
252 pub async fn get_alarm(&mut self) -> Result<Alarm, RtcError<I2CBusErr>> {
253 let mut op_min = self.ll.minute_alarm();
254 let min_reg = read_internal(&mut op_min).await?;
255
256 let mut op_hr = self.ll.hour_alarm();
257 let hr_reg = read_internal(&mut op_hr).await?;
258
259 let mut op_day = self.ll.day_alarm();
260 let day_reg = read_internal(&mut op_day).await?;
261
262 let mut op_wd = self.ll.weekday_alarm();
263 let wd_reg = read_internal(&mut op_wd).await?;
264
265 Ok(Alarm {
266 minute: if min_reg.ae_m() {
267 None
268 } else {
269 Some(bcd_to_dec(
270 (min_reg.minute_alarm_ten() << 4) as u8 | min_reg.minute_alarm_unit() as u8,
271 ))
272 },
273 hour: if hr_reg.ae_h() {
274 None
275 } else {
276 Some(bcd_to_dec(
277 (hr_reg.hour_alarm_ten() << 4) as u8 | hr_reg.hour_alarm_unit() as u8,
278 ))
279 },
280 day: if day_reg.ae_d() {
281 None
282 } else {
283 Some(bcd_to_dec(
284 (day_reg.day_alarm_ten() << 4) as u8 | day_reg.day_alarm_unit() as u8,
285 ))
286 },
287 weekday: if wd_reg.ae_w() {
288 None
289 } else {
290 Some(wd_reg.weekday_alarm() as u8)
291 },
292 })
293 }
294
295 #[bisync]
300 pub async fn set_alarm(&mut self, alarm: &Alarm) -> Result<(), RtcError<I2CBusErr>> {
301 let mut op_min = self.ll.minute_alarm();
303 write_internal(&mut op_min, |r| {
304 if let Some(min) = alarm.minute {
305 let bcd = dec_to_bcd(min);
306 r.set_ae_m(false); r.set_minute_alarm_ten(bcd >> 4);
308 r.set_minute_alarm_unit(bcd & 0x0F);
309 } else {
310 r.set_ae_m(true); }
312 })
313 .await?;
314
315 let mut op_hr = self.ll.hour_alarm();
317 write_internal(&mut op_hr, |r| {
318 if let Some(hr) = alarm.hour {
319 let bcd = dec_to_bcd(hr);
320 r.set_ae_h(false); r.set_hour_alarm_ten(bcd >> 4);
322 r.set_hour_alarm_unit(bcd & 0x0F);
323 } else {
324 r.set_ae_h(true); }
326 })
327 .await?;
328
329 let mut op_day = self.ll.day_alarm();
331 write_internal(&mut op_day, |r| {
332 if let Some(day) = alarm.day {
333 let bcd = dec_to_bcd(day);
334 r.set_ae_d(false); r.set_day_alarm_ten(bcd >> 4);
336 r.set_day_alarm_unit(bcd & 0x0F);
337 } else {
338 r.set_ae_d(true); }
340 })
341 .await?;
342
343 let mut op_wd = self.ll.weekday_alarm();
345 write_internal(&mut op_wd, |r| {
346 if let Some(wd) = alarm.weekday {
347 r.set_ae_w(false); r.set_weekday_alarm(wd);
349 } else {
350 r.set_ae_w(true); }
352 })
353 .await?;
354
355 Ok(())
356 }
357
358 #[bisync]
360 pub async fn disable_alarm(&mut self) -> Result<(), RtcError<I2CBusErr>> {
361 self.set_alarm(&Alarm::default()).await
362 }
363
364 #[bisync]
366 pub async fn get_alarm_flag(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
367 let mut op = self.ll.control_status_2();
368 let reg = read_internal(&mut op).await?;
369 Ok(reg.af())
370 }
371
372 #[bisync]
374 pub async fn clear_alarm_flag(&mut self) -> Result<(), RtcError<I2CBusErr>> {
375 let mut op = self.ll.control_status_2();
376 modify_internal(&mut op, |r| r.set_af(false)).await
377 }
378
379 #[bisync]
381 pub async fn set_alarm_interrupt(&mut self, enable: bool) -> Result<(), RtcError<I2CBusErr>> {
382 let mut op = self.ll.control_status_2();
383 modify_internal(&mut op, |r| r.set_aie(enable)).await
384 }
385
386 #[bisync]
388 pub async fn is_alarm_interrupt_enabled(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
389 let mut op = self.ll.control_status_2();
390 let reg = read_internal(&mut op).await?;
391 Ok(reg.aie())
392 }
393
394 #[bisync]
400 pub async fn set_timer_value(&mut self, value: u8) -> Result<(), RtcError<I2CBusErr>> {
401 let mut op = self.ll.timer();
402 write_internal(&mut op, |r| r.set_timer_value(value)).await
403 }
404
405 #[bisync]
407 pub async fn get_timer_value(&mut self) -> Result<u8, RtcError<I2CBusErr>> {
408 let mut op = self.ll.timer();
409 let reg = read_internal(&mut op).await?;
410 Ok(reg.timer_value() as u8)
411 }
412
413 #[bisync]
415 pub async fn set_timer_frequency(
416 &mut self,
417 freq: TimerFrequency,
418 ) -> Result<(), RtcError<I2CBusErr>> {
419 let mut op = self.ll.timer_control();
420 modify_internal(&mut op, |r| r.set_td(freq)).await
421 }
422
423 #[bisync]
425 pub async fn get_timer_frequency(&mut self) -> Result<TimerFrequency, RtcError<I2CBusErr>> {
426 let mut op = self.ll.timer_control();
427 let reg = read_internal(&mut op).await?;
428 Ok(reg.td())
429 }
430
431 #[bisync]
433 pub async fn set_timer_enabled(&mut self, enable: bool) -> Result<(), RtcError<I2CBusErr>> {
434 let mut op = self.ll.timer_control();
435 modify_internal(&mut op, |r| r.set_te(enable)).await
436 }
437
438 #[bisync]
440 pub async fn is_timer_enabled(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
441 let mut op = self.ll.timer_control();
442 let reg = read_internal(&mut op).await?;
443 Ok(reg.te())
444 }
445
446 #[bisync]
448 pub async fn get_timer_flag(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
449 let mut op = self.ll.control_status_2();
450 let reg = read_internal(&mut op).await?;
451 Ok(reg.tf())
452 }
453
454 #[bisync]
456 pub async fn clear_timer_flag(&mut self) -> Result<(), RtcError<I2CBusErr>> {
457 let mut op = self.ll.control_status_2();
458 modify_internal(&mut op, |r| r.set_tf(false)).await
459 }
460
461 #[bisync]
463 pub async fn set_timer_interrupt(&mut self, enable: bool) -> Result<(), RtcError<I2CBusErr>> {
464 let mut op = self.ll.control_status_2();
465 modify_internal(&mut op, |r| r.set_tie(enable)).await
466 }
467
468 #[bisync]
470 pub async fn is_timer_interrupt_enabled(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
471 let mut op = self.ll.control_status_2();
472 let reg = read_internal(&mut op).await?;
473 Ok(reg.tie())
474 }
475
476 #[bisync]
478 pub async fn set_timer_interrupt_pulse_mode(
479 &mut self,
480 pulse: bool,
481 ) -> Result<(), RtcError<I2CBusErr>> {
482 let mut op = self.ll.control_status_2();
483 modify_internal(&mut op, |r| r.set_ti_tp(pulse)).await
484 }
485
486 #[bisync]
492 pub async fn set_clkout_enabled(&mut self, enable: bool) -> Result<(), RtcError<I2CBusErr>> {
493 let mut op = self.ll.clkout_control();
494 modify_internal(&mut op, |r| r.set_fe(enable)).await
495 }
496
497 #[bisync]
499 pub async fn is_clkout_enabled(&mut self) -> Result<bool, RtcError<I2CBusErr>> {
500 let mut op = self.ll.clkout_control();
501 let reg = read_internal(&mut op).await?;
502 Ok(reg.fe())
503 }
504
505 #[bisync]
507 pub async fn set_clkout_frequency(
508 &mut self,
509 freq: ClkoutFrequency,
510 ) -> Result<(), RtcError<I2CBusErr>> {
511 let mut op = self.ll.clkout_control();
512 modify_internal(&mut op, |r| r.set_fd(freq)).await
513 }
514
515 #[bisync]
517 pub async fn get_clkout_frequency(&mut self) -> Result<ClkoutFrequency, RtcError<I2CBusErr>> {
518 let mut op = self.ll.clkout_control();
519 let reg = read_internal(&mut op).await?;
520 Ok(reg.fd())
521 }
522
523 #[bisync]
534 pub async fn init(&mut self) -> Result<(), RtcError<I2CBusErr>> {
535 let mut op1 = self.ll.control_status_1();
537 write_internal(&mut op1, |r| {
538 r.set_test1(false);
539 r.set_stop(false);
540 r.set_testc(false);
541 })
542 .await?;
543
544 let mut op2 = self.ll.control_status_2();
546 write_internal(&mut op2, |r| {
547 r.set_ti_tp(false);
548 r.set_af(false);
549 r.set_tf(false);
550 r.set_aie(false);
551 r.set_tie(false);
552 })
553 .await?;
554
555 self.clear_voltage_low_flag().await?;
557
558 self.disable_alarm().await?;
560
561 self.set_timer_frequency(TimerFrequency::Freq160Hz).await?;
563
564 Ok(())
565 }
566}
567
568#[cfg(feature = "rtcc")]
569#[only_sync]
570impl<I2CImpl, I2CBusErr> rtcc::DateTimeAccess for Pcf8563<I2CImpl, I2CBusErr>
571where
572 I2CImpl: RegisterInterface<AddressType = u8, Error = RtcError<I2CBusErr>>,
573 I2CBusErr: core::fmt::Debug,
574{
575 type Error = RtcError<I2CBusErr>;
576
577 fn datetime(&mut self) -> Result<RtccNaiveDateTime, Self::Error> {
578 let dt = self.get_datetime()?;
579 let century_flag = self.get_century_flag()?;
580 let base_year = if century_flag { 1900 } else { 2000 };
581
582 let date =
583 RtccNaiveDate::from_ymd_opt(base_year + dt.year as i32, dt.month as u32, dt.day as u32)
584 .ok_or(RtcError::InvalidInputData)?;
585 let time =
586 RtccNaiveTime::from_hms_opt(dt.hours as u32, dt.minutes as u32, dt.seconds as u32)
587 .ok_or(RtcError::InvalidInputData)?;
588
589 Ok(RtccNaiveDateTime::new(date, time))
590 }
591
592 fn set_datetime(&mut self, datetime: &RtccNaiveDateTime) -> Result<(), Self::Error> {
593 let date = datetime.date();
594 let time = datetime.time();
595 let year = date.year();
596
597 if !(1900..=2099).contains(&year) {
598 return Err(RtcError::InvalidInputData);
599 }
600
601 let dt = DateTime {
602 year: (year % 100) as u8,
603 month: date.month() as u8,
604 day: date.day() as u8,
605 weekday: date.weekday().num_days_from_sunday() as u8,
606 hours: time.hour() as u8,
607 minutes: time.minute() as u8,
608 seconds: time.second() as u8,
609 };
610
611 self.set_century_flag(year < 2000)?;
612 self.set_datetime(&dt)
613 }
614}
615
616#[cfg(feature = "rtcc")]
617#[only_sync]
618impl<I2CImpl, I2CBusErr> rtcc::Rtcc for Pcf8563<I2CImpl, I2CBusErr>
619where
620 I2CImpl: RegisterInterface<AddressType = u8, Error = RtcError<I2CBusErr>>,
621 I2CBusErr: core::fmt::Debug,
622{
623 fn seconds(&mut self) -> Result<u8, Self::Error> {
624 Ok(self.get_datetime()?.seconds)
625 }
626
627 fn minutes(&mut self) -> Result<u8, Self::Error> {
628 Ok(self.get_datetime()?.minutes)
629 }
630
631 fn hours(&mut self) -> Result<RtccHours, Self::Error> {
632 let hours = self.get_datetime()?.hours;
633 if hours > 23 {
634 Err(RtcError::InvalidInputData)
635 } else {
636 Ok(RtccHours::H24(hours))
637 }
638 }
639
640 fn time(&mut self) -> Result<RtccNaiveTime, Self::Error> {
641 let dt = self.get_datetime()?;
642 RtccNaiveTime::from_hms_opt(dt.hours as u32, dt.minutes as u32, dt.seconds as u32)
643 .ok_or(RtcError::InvalidInputData)
644 }
645
646 fn weekday(&mut self) -> Result<u8, Self::Error> {
647 let weekday = self.get_datetime()?.weekday;
648 if weekday > 6 {
649 Err(RtcError::InvalidInputData)
650 } else {
651 Ok(weekday + 1)
652 }
653 }
654
655 fn day(&mut self) -> Result<u8, Self::Error> {
656 Ok(self.get_datetime()?.day)
657 }
658
659 fn month(&mut self) -> Result<u8, Self::Error> {
660 Ok(self.get_datetime()?.month)
661 }
662
663 fn year(&mut self) -> Result<u16, Self::Error> {
664 let datetime = <Self as rtcc::DateTimeAccess>::datetime(self)?;
665 Ok(datetime.date().year() as u16)
666 }
667
668 fn date(&mut self) -> Result<RtccNaiveDate, Self::Error> {
669 Ok(<Self as rtcc::DateTimeAccess>::datetime(self)?.date())
670 }
671
672 fn set_seconds(&mut self, seconds: u8) -> Result<(), Self::Error> {
673 let mut dt = self.get_datetime()?;
674 dt.seconds = seconds;
675 self.set_datetime(&dt)
676 }
677
678 fn set_minutes(&mut self, minutes: u8) -> Result<(), Self::Error> {
679 let mut dt = self.get_datetime()?;
680 dt.minutes = minutes;
681 self.set_datetime(&dt)
682 }
683
684 fn set_hours(&mut self, hours: RtccHours) -> Result<(), Self::Error> {
685 let hours_24 = match hours {
686 RtccHours::H24(h) if h < 24 => h,
687 RtccHours::AM(h) if (1..=12).contains(&h) => {
688 if h == 12 {
689 0
690 } else {
691 h
692 }
693 }
694 RtccHours::PM(h) if (1..=12).contains(&h) => {
695 if h == 12 {
696 12
697 } else {
698 h + 12
699 }
700 }
701 _ => return Err(RtcError::InvalidInputData),
702 };
703
704 let mut dt = self.get_datetime()?;
705 dt.hours = hours_24;
706 self.set_datetime(&dt)
707 }
708
709 fn set_time(&mut self, time: &RtccNaiveTime) -> Result<(), Self::Error> {
710 let time = Time {
711 hours: time.hour() as u8,
712 minutes: time.minute() as u8,
713 seconds: time.second() as u8,
714 };
715 self.set_time(&time)
716 }
717
718 fn set_weekday(&mut self, weekday: u8) -> Result<(), Self::Error> {
719 if !(1..=7).contains(&weekday) {
720 return Err(RtcError::InvalidInputData);
721 }
722
723 let mut dt = self.get_datetime()?;
724 dt.weekday = weekday - 1;
725 self.set_datetime(&dt)
726 }
727
728 fn set_day(&mut self, day: u8) -> Result<(), Self::Error> {
729 let mut dt = self.get_datetime()?;
730 dt.day = day;
731 self.set_datetime(&dt)
732 }
733
734 fn set_month(&mut self, month: u8) -> Result<(), Self::Error> {
735 let mut dt = self.get_datetime()?;
736 dt.month = month;
737 self.set_datetime(&dt)
738 }
739
740 fn set_year(&mut self, year: u16) -> Result<(), Self::Error> {
741 if !(1900..=2099).contains(&year) {
742 return Err(RtcError::InvalidInputData);
743 }
744
745 let mut dt = self.get_datetime()?;
746 dt.year = (year % 100) as u8;
747 self.set_century_flag(year < 2000)?;
748 self.set_datetime(&dt)
749 }
750
751 fn set_date(&mut self, date: &RtccNaiveDate) -> Result<(), Self::Error> {
752 let year = date.year();
753 if !(1900..=2099).contains(&year) {
754 return Err(RtcError::InvalidInputData);
755 }
756
757 let mut dt = self.get_datetime()?;
758 dt.year = (year % 100) as u8;
759 dt.month = date.month() as u8;
760 dt.day = date.day() as u8;
761 dt.weekday = date.weekday().num_days_from_sunday() as u8;
762
763 self.set_century_flag(year < 2000)?;
764 self.set_datetime(&dt)
765 }
766}