use field_offset::offset_of; use stm32l4xx_hal::prelude::_embedded_hal_blocking_i2c_Write; use tock_registers::{ interfaces::{ReadWriteable, Readable}, register_bitfields, register_structs, registers::InMemoryRegister, }; register_bitfields![ u8, // Connection status register ConnStatus1 [ // Indicates that active cable has been plugged in ACTIVE_CABLE_DETECTION OFFSET(0) NUMBITS(1) [], // Read by the application to determine if accessory was attached ACCESSORY_CONNECTED OFFSET(1) NUMBITS(3) [ None = 0, Audio = 4, AudioCharged = 5, DebugDfp = 6, DebugUfp = 7, ], // Set in UFP mode with the detected current mode CURRENT_MODE_DETECT OFFSET(4) NUMBITS(2) [ Default = 0, Medium = 1, ChargeThrough = 2, High = 3, ], // Programmed by application to change current advertisement CURRENT_MODE_ADVERTISE OFFSET(6) NUMBITS(2) [ Default = 0, Mid = 1, High = 2, Reserved = 3, ], ], // Connection status and control register ConnStatus2 [ // Setting this field will disable UFP accessory support DISABLE_UFP_ACCESSORY OFFSET(0) NUMBITS(1) [], // Percentage of time that a DRP advertised DFP during tDRP DRP_DUTY_CYCLE OFFSET(1) NUMBITS(2) [ p30 = 0, p40 = 1, p50 = 2, p60 = 3, ], // Set when over-current limit is triggered VCONN_FAULT OFFSET(3) NUMBITS(1) [], // Pulled low when a control or status register changes INTERRUPT_STATUS OFFSET(4) NUMBITS(1) [ Clear = 0, Changed = 1, ], // Cable orientation CABLE_DIR OFFSET(5) NUMBITS(1) [ CC1 = 0, CC2 = 1, ], // Attached state (same as ID pin) ATTACHED_STATE OFFSET(6) NUMBITS(2) [ NotAttached = 0, AttachedSrc_DFP = 1, AttachedSnk_UFP = 2, AttachedAccessory = 3, ], ], // General control register Control [ // Disable CC pin termination DISABLE_TERM OFFSET(0) NUMBITS(1) [], // Control behavior when configured as DRP SOURCE_PERF OFFSET(1) NUMBITS(2) [ StandardDrp = 0, DrpTrySnk = 1, Reserved = 2, DrpTrySrc = 3, ], // Soft reset internal logic (self-clearing) I2C_SOFT_RESET OFFSET(3) NUMBITS(1) [], // Configure device operation mode MODE_SELECT OFFSET(4) NUMBITS(2) [ Drp = 0, Ufp = 1, Dfp = 2, ], // Debounce time on CC pins DEBOUNCE OFFSET(6) NUMBITS(2) [ ms168 = 0, ms118 = 1, ms134 = 2, ms152 = 3, ], ], ]; register_structs! { Tusb322Registers { (0x00 => id: [u8; 8]), (0x08 => stat1: InMemoryRegister), (0x09 => stat2: InMemoryRegister), (0x0A => ctrl: InMemoryRegister), (0x0B => @END), } } pub fn init(address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) { let stat1: InMemoryRegister = InMemoryRegister::new(0); let stat2: InMemoryRegister = InMemoryRegister::new(0); let ctrl: InMemoryRegister = InMemoryRegister::new(0); // Disable UFP accessory support (otherwise IC stays in DRP mode) stat2.modify(ConnStatus2::DISABLE_UFP_ACCESSORY::SET); // Disable CC termination to change to UFP mode ctrl.modify(Control::DISABLE_TERM::SET + Control::MODE_SELECT::Ufp); 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!(), } // Re-enable CC termination ctrl.modify(Control::DISABLE_TERM::CLEAR); 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!(), } }