Browse Source

Rework to make drivers more generic

Kevin Lee 2 years ago
parent
commit
172314754a

+ 95 - 125
Nixie_Firmware_Rust/src/ds3231.rs

@@ -8,8 +8,6 @@ use tock_registers::{
     registers::InMemoryRegister,
 };
 
-const DS3231_ADDR: u8 = 0x68;
-
 register_bitfields![
     u8,
     T_SECOND [
@@ -133,98 +131,11 @@ impl From<u8> for Weekday {
     }
 }
 
-impl Ds3231Registers {
-    const fn default() -> Self {
-        Self {
-            second: InMemoryRegister::new(0x00),
-            minute: InMemoryRegister::new(0x00),
-            hour: InMemoryRegister::new(0x00),
-            weekday: InMemoryRegister::new(0x00),
-            day: InMemoryRegister::new(0x00),
-            month: InMemoryRegister::new(0x00),
-            year: InMemoryRegister::new(0x00),
-            a1_second: InMemoryRegister::new(0x00),
-            a1_minute: InMemoryRegister::new(0x00),
-            a1_hour: InMemoryRegister::new(0x00),
-            a1_day_date: InMemoryRegister::new(0x00),
-            a2_minute: InMemoryRegister::new(0x00),
-            a2_hour: InMemoryRegister::new(0x00),
-            a2_day_date: InMemoryRegister::new(0x00),
-            control_1: InMemoryRegister::new(0x00),
-            control_2: InMemoryRegister::new(0x00),
-            aging_offset: InMemoryRegister::new(0x00),
-            temp_msb: InMemoryRegister::new(0x00),
-            temp_lsb: InMemoryRegister::new(0x00),
-        }
-    }
-    fn i2c_write_ctrl(&self, address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
-        let mut buffer: [u8; 3] = [0; 3];
-        buffer[0] = offset_of!(Ds3231Registers => control_1).get_byte_offset() as u8;
-        buffer[1] = self.control_1.get();
-        buffer[2] = self.control_2.get();
-
-        match i2c.write(address, &buffer) {
-            Ok(_) => (),
-            Err(_) => panic!(),
-        }
-    }
-    fn i2c_write_time(&self, address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
-        let mut buffer: [u8; 4] = [0; 4];
-        buffer[0] = offset_of!(Ds3231Registers => second).get_byte_offset() as u8;
-        buffer[1] = self.second.get();
-        buffer[2] = self.minute.get();
-        buffer[3] = self.hour.get();
-
-        match i2c.write(address, &buffer) {
-            Ok(_) => (),
-            Err(_) => panic!(),
-        }
-    }
-    fn i2c_write_date(&self, address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
-        let mut buffer: [u8; 5] = [0; 5];
-        buffer[0] = offset_of!(Ds3231Registers => weekday).get_byte_offset() as u8;
-        buffer[1] = self.weekday.get();
-        buffer[2] = self.day.get();
-        buffer[3] = self.month.get();
-        buffer[4] = self.year.get();
-
-        match i2c.write(address, &buffer) {
-            Ok(_) => (),
-            Err(_) => panic!(),
-        }
-    }
-    // Returns the second, minute, and hour from the RTC
-    fn i2c_read_time(&mut self, address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_WriteRead) {
-        let mut buffer: [u8; 3] = [0; 3];
-
-        match i2c.write_read(
-            address,
-            &[offset_of!(Ds3231Registers => second).get_byte_offset() as u8],
-            &mut buffer,
-        ) {
-            Ok(_) => (),
-            Err(_) => panic!(),
-        }
-    }
-    // Returns the weekday, day, month, year, and century from the RTC
-    fn i2c_read_date(&mut self, address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_WriteRead) {
-        let mut buffer: [u8; 4] = [0; 4];
-
-        match i2c.write_read(
-            address,
-            &[offset_of!(Ds3231Registers => weekday).get_byte_offset() as u8],
-            &mut buffer,
-        ) {
-            Ok(_) => (),
-            Err(_) => panic!(),
-        }
-    }
-}
-
-pub fn init(i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
-    let regs = Ds3231Registers::default();
+pub fn init(address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
+    let ctrl1: InMemoryRegister<u8, CONTROL_1::Register> = InMemoryRegister::new(0);
+    let ctrl2: InMemoryRegister<u8, CONTROL_2::Register> = InMemoryRegister::new(0);
 
-    regs.control_1.modify(
+    ctrl1.modify(
         CONTROL_1::nEOSC::CLEAR // Enable internal oscillator on VBAT
             + CONTROL_1::BBSQW::CLEAR // Disable outputs on VBAT
             + CONTROL_1::RS1::CLEAR   // Set square wave output to 1Hz
@@ -235,29 +146,50 @@ pub fn init(i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
     );
 
     // Disable 32kHz output
-    regs.control_2.modify(CONTROL_2::EN32KHZ::CLEAR);
+    ctrl2.modify(CONTROL_2::EN32KHZ::CLEAR);
+
+    let buffer: [u8; 3] = [
+        offset_of!(Ds3231Registers => control_1).get_byte_offset() as u8,
+        ctrl1.get(),
+        ctrl2.get(),
+    ];
 
-    regs.i2c_write_ctrl(DS3231_ADDR, i2c);
+    match i2c.write(address, &buffer) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 }
 
 pub fn set_time(
+    address: u8,
     i2c: &mut impl _embedded_hal_blocking_i2c_Write,
     second: u32,
     minute: u32,
     hour: u32,
 ) {
-    let regs = Ds3231Registers::default();
-
-    regs.second
-        .write(T_SECOND::Value.val(decimal_to_bcd(second)));
-    regs.minute
-        .write(T_MINUTE::Value.val(decimal_to_bcd(minute)));
-    regs.hour.write(T_HOUR::Value.val(decimal_to_bcd(hour)));
-
-    regs.i2c_write_time(DS3231_ADDR, i2c);
+    let second_reg: InMemoryRegister<u8, T_SECOND::Register> = InMemoryRegister::new(0);
+    let minute_reg: InMemoryRegister<u8, T_MINUTE::Register> = InMemoryRegister::new(0);
+    let hour_reg: InMemoryRegister<u8, T_HOUR::Register> = InMemoryRegister::new(0);
+
+    second_reg.write(T_SECOND::Value.val(decimal_to_bcd(second)));
+    minute_reg.write(T_MINUTE::Value.val(decimal_to_bcd(minute)));
+    hour_reg.write(T_HOUR::Value.val(decimal_to_bcd(hour)));
+
+    let buffer: [u8; 4] = [
+        offset_of!(Ds3231Registers => second).get_byte_offset() as u8,
+        second_reg.get(),
+        minute_reg.get(),
+        hour_reg.get(),
+    ];
+
+    match i2c.write(address, &buffer) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 }
 
 pub fn set_date(
+    address: u8,
     i2c: &mut impl _embedded_hal_blocking_i2c_Write,
     weekday: Weekday,
     day: u32,
@@ -265,45 +197,83 @@ pub fn set_date(
     year: u32,
     century: u32,
 ) {
-    let regs = Ds3231Registers::default();
-
-    regs.weekday
-        .write(T_WEEKDAY::Value.val(decimal_to_bcd(weekday as u32)));
-    regs.day.write(T_DAY::Value.val(decimal_to_bcd(day)));
-    regs.month.modify(
+    let weekday_reg: InMemoryRegister<u8, T_WEEKDAY::Register> = InMemoryRegister::new(0);
+    let day_reg: InMemoryRegister<u8, T_DAY::Register> = InMemoryRegister::new(0);
+    let month_reg: InMemoryRegister<u8, T_MONTH::Register> = InMemoryRegister::new(0);
+    let year_reg: InMemoryRegister<u8, T_YEAR::Register> = InMemoryRegister::new(0);
+
+    weekday_reg.write(T_WEEKDAY::Value.val(decimal_to_bcd(weekday as u32)));
+    day_reg.write(T_DAY::Value.val(decimal_to_bcd(day)));
+    month_reg.modify(
         T_MONTH::Value.val(decimal_to_bcd(month)) + T_MONTH::Century.val(decimal_to_bcd(century)),
     );
-    regs.year.write(T_YEAR::Value.val(decimal_to_bcd(year)));
-
-    regs.i2c_write_time(DS3231_ADDR, i2c);
+    year_reg.write(T_YEAR::Value.val(decimal_to_bcd(year)));
+
+    let buffer: [u8; 5] = [
+        offset_of!(Ds3231Registers => weekday).get_byte_offset() as u8,
+        weekday_reg.get(),
+        day_reg.get(),
+        month_reg.get(),
+        year_reg.get(),
+    ];
+
+    match i2c.write(address, &buffer) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 }
 
 pub fn get_time(
+    address: u8,
     i2c: &mut impl _embedded_hal_blocking_i2c_WriteRead,
 ) -> (u32, u32, u32) {
-    let mut regs = Ds3231Registers::default();
+    let mut buffer: [u8; 3] = [0; 3];
+
+    match i2c.write_read(
+        address,
+        &[offset_of!(Ds3231Registers => second).get_byte_offset() as u8],
+        &mut buffer,
+    ) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 
-    regs.i2c_read_time(DS3231_ADDR, i2c);
+    let second_reg: InMemoryRegister<u8, T_SECOND::Register> = InMemoryRegister::new(buffer[0]);
+    let minute_reg: InMemoryRegister<u8, T_MINUTE::Register> = InMemoryRegister::new(buffer[1]);
+    let hour_reg: InMemoryRegister<u8, T_HOUR::Register> = InMemoryRegister::new(buffer[2]);
 
-    let second = bcd_to_decimal(regs.second.read(T_SECOND::Value));
-    let minute = bcd_to_decimal(regs.minute.read(T_MINUTE::Value));
-    let hour = bcd_to_decimal(regs.hour.read(T_HOUR::Value));
+    let second = bcd_to_decimal(second_reg.read(T_SECOND::Value));
+    let minute = bcd_to_decimal(minute_reg.read(T_MINUTE::Value));
+    let hour = bcd_to_decimal(hour_reg.read(T_HOUR::Value));
 
     (second, minute, hour)
 }
 
 pub fn get_date(
+    address: u8,
     i2c: &mut impl _embedded_hal_blocking_i2c_WriteRead,
 ) -> (Weekday, u32, u32, u32, u32) {
-    let mut regs = Ds3231Registers::default();
+    let mut buffer: [u8; 4] = [0; 4];
+
+    match i2c.write_read(
+        address,
+        &[offset_of!(Ds3231Registers => weekday).get_byte_offset() as u8],
+        &mut buffer,
+    ) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 
-    regs.i2c_read_date(DS3231_ADDR, i2c);
+    let weekday_reg: InMemoryRegister<u8, T_WEEKDAY::Register> = InMemoryRegister::new(buffer[0]);
+    let day_reg: InMemoryRegister<u8, T_DAY::Register> = InMemoryRegister::new(buffer[1]);
+    let month_reg: InMemoryRegister<u8, T_MONTH::Register> = InMemoryRegister::new(buffer[2]);
+    let year_reg: InMemoryRegister<u8, T_YEAR::Register> = InMemoryRegister::new(buffer[3]);
 
-    let weekday: Weekday = regs.weekday.read(T_WEEKDAY::Value).into();
-    let day = bcd_to_decimal(regs.day.read(T_DAY::Value));
-    let month = bcd_to_decimal(regs.month.read(T_MONTH::Value));
-    let year = bcd_to_decimal(regs.year.read(T_YEAR::Value));
-    let century = bcd_to_decimal(regs.month.read(T_MONTH::Century));
+    let weekday: Weekday = weekday_reg.read(T_WEEKDAY::Value).into();
+    let day = bcd_to_decimal(day_reg.read(T_DAY::Value));
+    let month = bcd_to_decimal(month_reg.read(T_MONTH::Value));
+    let year = bcd_to_decimal(year_reg.read(T_YEAR::Value));
+    let century = bcd_to_decimal(month_reg.read(T_MONTH::Century));
 
     (weekday, day, month, year, century)
 }

+ 29 - 9
Nixie_Firmware_Rust/src/main.rs

@@ -1,11 +1,9 @@
 #![cfg_attr(test, allow(unused_imports))]
 #![cfg_attr(not(test), no_std)]
 #![cfg_attr(not(test), no_main)]
-
 // #![feature(generic_const_exprs)]
 #![feature(half_open_range_patterns)]
 #![feature(exclusive_range_pattern)]
-
 #![allow(dead_code)]
 
 // custom panic handler
@@ -19,8 +17,9 @@ use cortex_m_rt::entry;
 // use cortex_m_semihosting::hprintln;
 use stm32l4xx_hal::{
     delay::Delay,
-    gpio::State,
-    gpio::{Edge, Input, Output, PullUp, PushPull, PA3, PC15},
+    device::I2C1,
+    gpio::{Alternate, Edge, Input, OpenDrain, Output, PullUp, PushPull, AF4, PA3, PC15},
+    gpio::{State, PA10, PA9},
     i2c::I2c,
     interrupt, pac,
     prelude::*,
@@ -28,13 +27,30 @@ use stm32l4xx_hal::{
     stm32::Interrupt,
 };
 
-mod tusb322;
 mod ds3231;
-mod pca9685;
+// mod pca9685;
+mod tusb322;
 
 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));
-
+static I2C: Mutex<
+    RefCell<
+        Option<
+            I2c<
+                I2C1,
+                (
+                    PA9<Alternate<AF4, Output<OpenDrain>>>,
+                    PA10<Alternate<AF4, Output<OpenDrain>>>,
+                ),
+            >,
+        >,
+    >,
+> = Mutex::new(RefCell::new(None));
+
+const DS3231_ADDR: u8 = 0x68;
+const TUSB322_ADDR: u8 = 0x47;
+
+// NewType wrapper for the
 // unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
 //     core::slice::from_raw_parts(
 //         (p as *const T) as *const u8,
@@ -137,9 +153,13 @@ fn main() -> ! {
     // Initialize I2C
     let mut i2c = I2c::i2c1(dp.I2C1, (scl, sda), 100.khz(), clocks, &mut rcc.apb1r1);
 
-    tusb322::init(&mut i2c);
+    tusb322::init(TUSB322_ADDR, &mut i2c);
+
+    ds3231::init(DS3231_ADDR, &mut i2c);
 
-    ds3231::init(&mut i2c);
+    free(|cs| {
+        I2C.borrow(cs).replace(Some(i2c));
+    });
 
     // Configure abstract timer that operates off systick timer
     let mut timer = Delay::new(cp.SYST, clocks);

+ 1 - 1
Nixie_Firmware_Rust/src/pca9685.rs

@@ -81,7 +81,7 @@ impl Pca9685Registers {
 const MAP_ADDR: usize = 0;
 const MAP_PIN: usize = 1;
 
-static MAPPING: [[[u8; 2]; 10]; 4] = [
+static PCA9685_MAPPING: [[[u8; 2]; 10]; 4] = [
     [
         [PCA9685_ADDR_1, 8],  // Tube 0 Digit 0
         [PCA9685_ADDR_1, 9],  // Tube 0 Digit 1

+ 28 - 34
Nixie_Firmware_Rust/src/tusb322.rs

@@ -6,8 +6,6 @@ use tock_registers::{
     registers::InMemoryRegister,
 };
 
-const TUSB322_ADDR: u8 = 0x47;
-
 register_bitfields![
     u8,
     // Connection status register
@@ -107,46 +105,42 @@ register_structs! {
     }
 }
 
-impl Tusb322Registers {
-    const fn default() -> Self {
-        Self {
-            id: [0; 8],
-            stat1: InMemoryRegister::new(0x00),
-            stat2: InMemoryRegister::new(0x00),
-            ctrl: InMemoryRegister::new(0x00),
-        }
-    }
-    // Program control registers
-    fn i2c_write_regs(&self, address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
-        let mut buffer: [u8; 4] = [0; 4];
-        buffer[0] = offset_of!(Tusb322Registers => stat1).get_byte_offset() as u8;
-        buffer[1] = self.stat1.get();
-        buffer[2] = self.stat2.get();
-        buffer[3] = self.ctrl.get();
-
-        match i2c.write(address, &buffer) {
-            Ok(_) => (),
-            Err(_) => panic!(),
-        }
-    }
-}
+pub fn init(address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
 
-pub fn init(i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
-    let reg: Tusb322Registers = Tusb322Registers::default();
+    let stat1: InMemoryRegister<u8, ConnStatus1::Register> = InMemoryRegister::new(0);
+    let stat2: InMemoryRegister<u8, ConnStatus2::Register> = InMemoryRegister::new(0);
+    let ctrl: InMemoryRegister<u8, Control::Register> = InMemoryRegister::new(0);
 
     // Disable UFP accessory support (otherwise IC stays in DRP mode)
-    reg.stat2.modify(ConnStatus2::DISABLE_UFP_ACCESSORY::SET);
+    stat2.modify(ConnStatus2::DISABLE_UFP_ACCESSORY::SET);
 
     // Disable CC termination to change to UFP mode
-    reg.ctrl.modify(Control::DISABLE_TERM::SET);
+    ctrl.modify(Control::DISABLE_TERM::SET + Control::MODE_SELECT::Ufp);
 
-    // For operation in UFP mode
-    reg.ctrl.modify(Control::MODE_SELECT::Ufp);
+    let buffer: [u8; 4] = [
+        offset_of!(Tusb322Registers => stat1).get_byte_offset() as u8,
+        stat1.get(),
+        stat2.get(),
+        ctrl.get(),
+    ];
 
-    reg.i2c_write_regs(TUSB322_ADDR, i2c);
+    match i2c.write(address, &buffer) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 
     // Re-enable CC termination
-    reg.ctrl.modify(Control::DISABLE_TERM::CLEAR);
+    ctrl.modify(Control::DISABLE_TERM::CLEAR);
 
-    reg.i2c_write_regs(TUSB322_ADDR, i2c);
+    let buffer: [u8; 4] = [
+        offset_of!(Tusb322Registers => stat1).get_byte_offset() as u8,
+        stat1.get(),
+        stat2.get(),
+        ctrl.get(),
+    ];
+
+    match i2c.write(address, &buffer) {
+        Ok(_) => (),
+        Err(_) => panic!(),
+    }
 }