Browse Source

Initial support for DS3231

Kevin Lee 2 years ago
parent
commit
b5ad436cf3
3 changed files with 225 additions and 19 deletions
  1. 216 0
      Nixie_Firmware_Rust/src/ds3231.rs
  2. 5 15
      Nixie_Firmware_Rust/src/main.rs
  3. 4 4
      Nixie_Firmware_Rust/src/tusb322.rs

+ 216 - 0
Nixie_Firmware_Rust/src/ds3231.rs

@@ -0,0 +1,216 @@
+use field_offset::offset_of;
+use stm32l4xx_hal::{
+    prelude::{_embedded_hal_blocking_i2c_Read, _embedded_hal_blocking_i2c_Write},
+};
+use tock_registers::{
+    interfaces::{ReadWriteable, Readable},
+    register_bitfields, register_structs,
+    registers::InMemoryRegister,
+};
+
+register_bitfields![
+    u8,
+    T_SECOND [
+        Value OFFSET(0) NUMBITS(7) [],
+    ],
+    T_MINUTE [
+        Value OFFSET(0) NUMBITS(7) [],
+    ],
+    T_HOUR [
+        Value OFFSET(0) NUMBITS(6) [],
+        n24 OFFSET(6) NUMBITS(1) [],
+    ],
+    T_DAY [
+        Value OFFSET(0) NUMBITS(3) [],
+    ],
+    T_DATE [
+        Value OFFSET(0) NUMBITS(6) [],
+    ],
+    T_MONTH [
+        Value OFFSET(0) NUMBITS(5) [],
+        Century OFFSET(7) NUMBITS(1) [],
+    ],
+    T_YEAR [
+        Value OFFSET(0) NUMBITS(8) [],
+    ],
+    A_SECOND [
+        Value OFFSET(0) NUMBITS(7) [],
+        M1 OFFSET(7) NUMBITS(1) [],
+    ],
+    A_MINUTE [
+        Value OFFSET(0) NUMBITS(7) [],
+        M2 OFFSET(7) NUMBITS(1) [],
+    ],
+    A_HOUR [
+        Value OFFSET(0) NUMBITS(6) [],
+        n24 OFFSET(6) NUMBITS(1) [],
+        M3 OFFSET(7) NUMBITS(1) [],
+    ],
+    A_DAY_DATE [
+        Value OFFSET(0) NUMBITS(6) [],
+        nDT OFFSET(6) NUMBITS(1) [],
+        M4 OFFSET(7) NUMBITS(1) [],
+    ],
+    CONTROL_1 [
+        A1IE 0,
+        A2IE 1,
+        INTCN 2,
+        RS1 3,
+        RS2 4,
+        CONV 5,
+        BBSQW 6,
+        nEOSC 7,
+    ],
+    CONTROL_2 [
+        A1F 0,
+        A2F 1,
+        BSY 2,
+        EN32KHZ 3,
+        OSF 7,
+    ],
+    AGING_OFFSET [
+        Value OFFSET(0) NUMBITS(7) [],
+        Sign OFFSET(7) NUMBITS(1) [],
+    ],
+    TEMP_MSB [
+        Value OFFSET(0) NUMBITS(7) [],
+        Sign OFFSET(7) NUMBITS(1) [],
+    ],
+    TEMP_LSB [
+        Value OFFSET(6) NUMBITS(2) [],
+    ],
+];
+
+register_structs! {
+    Ds3231Registers {
+        (0x00 => t_second: InMemoryRegister<u8, T_SECOND::Register>),
+        (0x01 => t_minute: InMemoryRegister<u8, T_MINUTE::Register>),
+        (0x02 => t_hour: InMemoryRegister<u8, T_HOUR::Register>),
+        (0x03 => t_weekday: InMemoryRegister<u8, T_DAY::Register>),
+        (0x04 => t_day: InMemoryRegister<u8, T_DATE::Register>),
+        (0x05 => t_month: InMemoryRegister<u8, T_MONTH::Register>),
+        (0x06 => t_year: InMemoryRegister<u8, T_YEAR::Register>),
+        (0x07 => a1_second: InMemoryRegister<u8, A_SECOND::Register>),
+        (0x08 => a1_minute: InMemoryRegister<u8, A_MINUTE::Register>),
+        (0x09 => a1_hour: InMemoryRegister<u8, A_HOUR::Register>),
+        (0x0A => a1_day_date: InMemoryRegister<u8, A_DAY_DATE::Register>),
+        (0x0B => a2_minute: InMemoryRegister<u8, A_MINUTE::Register>),
+        (0x0C => a2_hour: InMemoryRegister<u8, A_HOUR::Register>),
+        (0x0D => a2_day_date: InMemoryRegister<u8, A_DAY_DATE::Register>),
+        (0x0E => control_1: InMemoryRegister<u8, CONTROL_1::Register>),
+        (0x0F => control_2: InMemoryRegister<u8, CONTROL_2::Register>),
+        (0x10 => aging_offset: InMemoryRegister<u8, AGING_OFFSET::Register>),
+        (0x11 => temp_msb: InMemoryRegister<u8, TEMP_MSB::Register>),
+        (0x12 => temp_lsb: InMemoryRegister<u8, TEMP_LSB::Register>),
+        (0x13 => @END),
+    }
+}
+
+pub enum Weekday {
+    SUNDAY = 0,
+    MONDAY = 1,
+    TUESDAY = 2,
+    WEDNESDAY = 3,
+    THURSDAY = 4,
+    FRIDAY = 5,
+    SATURDAY = 6,
+}
+
+impl Ds3231Registers {
+    fn i2c_read_regs(&mut self, i2c: &mut impl _embedded_hal_blocking_i2c_Read) {}
+    fn set_time(second: &u32, minute: &u32, hour: &u32) {}
+    fn set_date(weekday: &Weekday, day: &u32, month: &u32, year: &u32, century: &u32) {}
+    fn get_time(second: &mut u32, minute: &mut u32, hour: &mut u32) {}
+    fn get_date(
+        weekday: &mut Weekday,
+        day: &mut u32,
+        month: &mut u32,
+        year: &mut u32,
+        century: &mut u32,
+    ) {
+    }
+}
+
+pub fn in_dst(weekday: Weekday, day: u32, month: u32, hour_24: u32) -> bool {
+    let prev_sunday: i32 = day as i32 - weekday as i32;
+    match month {
+        0..=2 | 12.. => false,
+        4..=10 => true,
+        3 => {
+            if prev_sunday < 8 {
+                false
+            } else if prev_sunday > 14 {
+                true
+            } else if prev_sunday == day as i32 {
+                hour_24 >= 2
+            } else {
+                true
+            }
+        }
+        11 => {
+            if prev_sunday <= 0 {
+                true
+            } else if day > 7 {
+                false
+            } else if prev_sunday == day as i32 {
+                hour_24 < 2
+            } else {
+                false
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn dst_test() {
+        // 2020 - begins Mar 8th @ 2AM (Sunday), ends Nov 1st @ 2AM (Sunday)
+        assert!(in_dst(Weekday::SUNDAY, 8, 3, 1) == false);
+        assert!(in_dst(Weekday::SUNDAY, 8, 3, 2) == true);
+        assert!(in_dst(Weekday::SUNDAY, 8, 3, 3) == true);
+        assert!(in_dst(Weekday::SUNDAY, 1, 11, 1) == true);
+        assert!(in_dst(Weekday::SUNDAY, 1, 11, 2) == false);
+        assert!(in_dst(Weekday::SUNDAY, 1, 11, 3) == false);
+
+        // 2021 - begins Mar 14th @ 2AM (Sunday), ends Nov 7th @ 2AM (Sunday)
+        assert!(in_dst(Weekday::SUNDAY, 14, 3, 1) == false);
+        assert!(in_dst(Weekday::SUNDAY, 14, 3, 2) == true);
+        assert!(in_dst(Weekday::SUNDAY, 14, 3, 3) == true);
+        assert!(in_dst(Weekday::SUNDAY, 7, 11, 1) == true);
+        assert!(in_dst(Weekday::SUNDAY, 7, 11, 2) == false);
+        assert!(in_dst(Weekday::SUNDAY, 7, 11, 3) == false);
+
+        // 2022 - begins Mar 13th @ 2AM (Sunday), ends Nov 6th @ 2AM (Sunday)
+        assert!(in_dst(Weekday::SUNDAY, 13, 3, 1) == false);
+        assert!(in_dst(Weekday::SUNDAY, 13, 3, 2) == true);
+        assert!(in_dst(Weekday::SUNDAY, 13, 3, 3) == true);
+        assert!(in_dst(Weekday::SUNDAY, 6, 11, 1) == true);
+        assert!(in_dst(Weekday::SUNDAY, 6, 11, 2) == false);
+        assert!(in_dst(Weekday::SUNDAY, 6, 11, 3) == false);
+
+        // 2023 - begins Mar 12th @ 2AM (Sunday), ends Nov 5th @ 2AM (Sunday)
+        assert!(in_dst(Weekday::SUNDAY, 12, 3, 1) == false);
+        assert!(in_dst(Weekday::SUNDAY, 12, 3, 2) == true);
+        assert!(in_dst(Weekday::SUNDAY, 12, 3, 3) == true);
+        assert!(in_dst(Weekday::SUNDAY, 5, 11, 1) == true);
+        assert!(in_dst(Weekday::SUNDAY, 5, 11, 2) == false);
+        assert!(in_dst(Weekday::SUNDAY, 5, 11, 3) == false);
+
+        // Sanity check other dates in 2021
+        assert!(in_dst(Weekday::FRIDAY, 1, 1, 0) == false);
+        assert!(in_dst(Weekday::MONDAY, 1, 2, 0) == false);
+        assert!(in_dst(Weekday::MONDAY, 1, 3, 0) == false);
+        assert!(in_dst(Weekday::THURSDAY, 1, 4, 0) == true);
+        assert!(in_dst(Weekday::SATURDAY, 1, 5, 0) == true);
+        assert!(in_dst(Weekday::TUESDAY, 1, 6, 0) == true);
+        assert!(in_dst(Weekday::THURSDAY, 1, 7, 0) == true);
+        assert!(in_dst(Weekday::SUNDAY, 1, 8, 0) == true);
+        assert!(in_dst(Weekday::WEDNESDAY, 1, 9, 0) == true);
+        assert!(in_dst(Weekday::FRIDAY, 1, 10, 0) == true);
+        assert!(in_dst(Weekday::MONDAY, 1, 11, 0) == true);
+        assert!(in_dst(Weekday::WEDNESDAY, 1, 12, 0) == false);
+    }
+}

+ 5 - 15
Nixie_Firmware_Rust/src/main.rs

@@ -24,8 +24,13 @@ use stm32l4xx_hal::{
 };
 
 const TUSB322_ADDR: u8 = 0x47;
+const DS3231_ADDR: u8 = 0x68;
+const PCA9685_ADDR1: u8 = 0x41;
+const PCA9685_ADDR2: u8 = 0x42;
+const PCA9685_ADDR3: u8 = 0x43;
 
 mod tusb322;
+mod ds3231;
 
 static FAULT_INT: Mutex<RefCell<Option<PA3<Input<PullUp>>>>> = Mutex::new(RefCell::new(None));
 static FAULT_LED: Mutex<RefCell<Option<PC15<Output<PushPull>>>>> = Mutex::new(RefCell::new(None));
@@ -190,18 +195,3 @@ fn panic(_info: &PanicInfo) -> ! {
         continue;
     }
 }
-
-#[cfg(test)]
-mod test {
-    use super::*;
-
-    fn add(a: i32, b: i32) -> i32 {
-        a + b
-    }
-
-    #[test]
-    fn foo() {
-        println!("tests work!");
-        assert!(2 == add(1, 1));
-    }
-}

+ 4 - 4
Nixie_Firmware_Rust/src/tusb322.rs

@@ -98,10 +98,10 @@ register_bitfields![
 register_structs! {
     Tusb322Registers {
         (0x00 => id:    [u8; 8]),
-        (0x09 => stat1: InMemoryRegister<u8, ConnStatus1::Register>),
-        (0x0A => stat2: InMemoryRegister<u8, ConnStatus2::Register>),
-        (0x0B => ctrl:  InMemoryRegister<u8, Control::Register>),
-        (0x0C => @END),
+        (0x08 => stat1: InMemoryRegister<u8, ConnStatus1::Register>),
+        (0x09 => stat2: InMemoryRegister<u8, ConnStatus2::Register>),
+        (0x0A => ctrl:  InMemoryRegister<u8, Control::Register>),
+        (0x0B => @END),
     }
 }