Browse Source

Finalize support for TUSB322

Kevin Lee 2 years ago
parent
commit
c45bf25cfe
3 changed files with 48 additions and 21 deletions
  1. 1 0
      Nixie_Firmware_Rust/Cargo.toml
  2. 19 2
      Nixie_Firmware_Rust/src/main.rs
  3. 28 19
      Nixie_Firmware_Rust/src/tusb322.rs

+ 1 - 0
Nixie_Firmware_Rust/Cargo.toml

@@ -11,6 +11,7 @@ cortex-m-rt = "0.6.10"
 cortex-m-semihosting = "0.3.3"
 # panic-halt = "0.2.0"
 tock-registers = "0.7.0"
+field-offset = "0.3.4"
 
 # Uncomment for the panic example.
 # panic-itm = "0.4.1"

+ 19 - 2
Nixie_Firmware_Rust/src/main.rs

@@ -1,6 +1,7 @@
 #![cfg_attr(test, allow(unused_imports))]
 #![cfg_attr(not(test), no_std)]
 #![cfg_attr(not(test), no_main)]
+// #![feature(generic_const_exprs)]
 
 // custom panic handler
 #[cfg(not(test))]
@@ -22,11 +23,28 @@ use stm32l4xx_hal::{
     stm32::Interrupt,
 };
 
+const TUSB322_ADDR: u8 = 0x47;
+
 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));
 
+// unsafe fn any_as_u8_slice<T: Sized>(p: &T) -> &[u8] {
+//     core::slice::from_raw_parts(
+//         (p as *const T) as *const u8,
+//         core::mem::size_of::<T>(),
+//     )
+// }
+
+// pub fn concat<T: Copy + Default, const A: usize, const B: usize>(a: &[T; A], b: &[T; B]) -> [T; A+B] {
+//     let mut whole: [T; A+B] = [Default::default(); A+B];
+//     let (one, two) = whole.split_at_mut(A);
+//     one.copy_from_slice(a);
+//     two.copy_from_slice(b);
+//     whole
+// }
+
 #[cfg(not(test))]
 #[entry]
 fn main() -> ! {
@@ -37,7 +55,6 @@ fn main() -> ! {
     // Acquire a singleton instance for the chip's peripherals
     let mut dp = pac::Peripherals::take().unwrap();
     let cp = pac::CorePeripherals::take().unwrap();
-    // let cp = cortex_m::Peripherals::take().unwrap();
 
     // Consume the raw peripheral and return a new object that implements a higher level API
     let mut flash = dp.FLASH.constrain();
@@ -115,7 +132,7 @@ 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);
 
     // Configure abstract timer that operates off systick timer
     let mut timer = Delay::new(cp.SYST, clocks);

+ 28 - 19
Nixie_Firmware_Rust/src/tusb322.rs

@@ -1,6 +1,9 @@
-use stm32l4xx_hal::{prelude::_embedded_hal_blocking_i2c_Write};
+use field_offset::offset_of;
+use stm32l4xx_hal::prelude::_embedded_hal_blocking_i2c_Write;
 use tock_registers::{
-    interfaces::ReadWriteable, register_bitfields, register_structs, registers::InMemoryRegister,
+    interfaces::{ReadWriteable, Readable},
+    register_bitfields, register_structs,
+    registers::InMemoryRegister,
 };
 
 register_bitfields![
@@ -102,18 +105,31 @@ register_structs! {
     }
 }
 
-impl Default for Tusb322Registers {
-    fn default() -> Self {
+impl Tusb322Registers {
+    const fn default() -> Self {
         Self {
             id: [0; 8],
-            stat1: InMemoryRegister::new(0),
-            stat2: InMemoryRegister::new(0),
-            ctrl: InMemoryRegister::new(0),
+            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(i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
+pub fn init(address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
     let reg: Tusb322Registers = Tusb322Registers::default();
 
     // Disable UFP accessory support (otherwise IC stays in DRP mode)
@@ -125,17 +141,10 @@ pub fn init(i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
     // For operation in UFP mode
     reg.ctrl.modify(Control::MODE_SELECT::Ufp);
 
-    const TUSB322_ADDR: u8 = 0x47;
+    reg.i2c_write_regs(address, i2c);
 
-    // For some reason i2c.write().unwrap() doesn't work here as it complains
-    // about an unsatisfied trait bound where the returned error value
-    // (_embedded_hal_blocking_i2c_Write::Error) doesnt implement trait Debug.
-    // Calling .unwrap() does work though if it's the caller that is doing so.
-
-    match i2c.write(TUSB322_ADDR, &[0x00]) {
-        Ok(_) => (),
-        Err(_) => panic!()
-    }
+    // Re-enable CC termination
+    reg.ctrl.modify(Control::DISABLE_TERM::CLEAR);
 
+    reg.i2c_write_regs(address, i2c);
 }
-