123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152 |
- 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,
- };
- const TUSB322_ADDR: u8 = 0x47;
- 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<u8, ConnStatus1::Register>),
- (0x09 => stat2: InMemoryRegister<u8, ConnStatus2::Register>),
- (0x0A => ctrl: InMemoryRegister<u8, Control::Register>),
- (0x0B => @END),
- }
- }
- 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(i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
- let reg: Tusb322Registers = Tusb322Registers::default();
- // Disable UFP accessory support (otherwise IC stays in DRP mode)
- reg.stat2.modify(ConnStatus2::DISABLE_UFP_ACCESSORY::SET);
- // Disable CC termination to change to UFP mode
- reg.ctrl.modify(Control::DISABLE_TERM::SET);
- // For operation in UFP mode
- reg.ctrl.modify(Control::MODE_SELECT::Ufp);
- reg.i2c_write_regs(TUSB322_ADDR, i2c);
- // Re-enable CC termination
- reg.ctrl.modify(Control::DISABLE_TERM::CLEAR);
- reg.i2c_write_regs(TUSB322_ADDR, i2c);
- }
|