rtc_hal/bcd.rs
1//! # BCD (Binary Coded Decimal) conversion utilities for RTC operations
2//!
3//! This module provides conversion functions between BCD and decimal formats
4//! commonly used in Real-Time Clock (RTC) chips like the DS1307.
5//!
6//! ## BCD Format Overview
7//!
8//! Binary Coded Decimal (BCD) represents decimal digits using 4-bit binary patterns:
9//! - Each decimal digit (0-9) is encoded in 4 bits
10//! - One byte can hold two decimal digits (00-99)
11//! - High nibble = tens digit, low nibble = ones digit
12//!
13//! ## Format Examples
14//!
15//! | Decimal | BCD Binary | BCD Hex |
16//! |---------|--------------|---------|
17//! | 00 | 0000 0000 | 0x00 |
18//! | 01 | 0000 0001 | 0x01 |
19//! | 09 | 0000 1001 | 0x09 |
20//! | 10 | 0001 0000 | 0x10 |
21//! | 23 | 0010 0011 | 0x23 |
22//! | 59 | 0101 1001 | 0x59 |
23//! | 99 | 1001 1001 | 0x99 |
24//!
25
26/// Convert a BCD encoded byte to decimal
27/// First 4 bits are tens of the number
28/// Last 4 bits are ones of the number
29pub fn to_decimal(bcd: u8) -> u8 {
30 ((bcd >> 4) * 10) + (bcd & 0x0F)
31}
32
33/// Convert decimal byte to BCD encoding
34pub fn from_decimal(decimal: u8) -> u8 {
35 debug_assert!(decimal <= 99, "Decimal value must be <= 99 for BCD");
36 ((decimal / 10) << 4) | (decimal % 10)
37}
38
39#[cfg(test)]
40mod tests {
41 use super::*;
42
43 #[test]
44 fn test_to_decimal() {
45 assert_eq!(to_decimal(0x00), 0);
46 assert_eq!(to_decimal(0x01), 1);
47 assert_eq!(to_decimal(0x09), 9);
48 assert_eq!(to_decimal(0x10), 10);
49 assert_eq!(to_decimal(0x23), 23);
50 assert_eq!(to_decimal(0x45), 45);
51 assert_eq!(to_decimal(0x59), 59);
52 assert_eq!(to_decimal(0x99), 99);
53 }
54
55 #[test]
56 fn test_from_decimal() {
57 assert_eq!(from_decimal(0), 0x00);
58 assert_eq!(from_decimal(1), 0x01);
59 assert_eq!(from_decimal(9), 0x09);
60 assert_eq!(from_decimal(10), 0x10);
61 assert_eq!(from_decimal(23), 0x23);
62 assert_eq!(from_decimal(45), 0x45);
63 assert_eq!(from_decimal(59), 0x59);
64 assert_eq!(from_decimal(99), 0x99);
65 }
66
67 #[test]
68 fn test_bcd_round_trip() {
69 for i in 0..=99 {
70 let bcd = from_decimal(i);
71 let decimal = to_decimal(bcd);
72 assert_eq!(i, decimal);
73 }
74 }
75
76 #[test]
77 fn test_bcd_edge_cases() {
78 // Test boundary values commonly used in RTC
79 let test_cases = [0, 1, 9, 10, 23, 31, 59, 99];
80
81 for &value in &test_cases {
82 let bcd = from_decimal(value);
83 let back = to_decimal(bcd);
84 assert_eq!(value, back, "Failed for value: {value}");
85 }
86 }
87}