tusb322.rs 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. use field_offset::offset_of;
  2. use stm32l4xx_hal::prelude::_embedded_hal_blocking_i2c_Write;
  3. use tock_registers::{
  4. interfaces::{ReadWriteable, Readable},
  5. register_bitfields, register_structs,
  6. registers::InMemoryRegister,
  7. };
  8. register_bitfields![
  9. u8,
  10. // Connection status register
  11. ConnStatus1 [
  12. // Indicates that active cable has been plugged in
  13. ACTIVE_CABLE_DETECTION OFFSET(0) NUMBITS(1) [],
  14. // Read by the application to determine if accessory was attached
  15. ACCESSORY_CONNECTED OFFSET(1) NUMBITS(3) [
  16. None = 0,
  17. Audio = 4,
  18. AudioCharged = 5,
  19. DebugDfp = 6,
  20. DebugUfp = 7,
  21. ],
  22. // Set in UFP mode with the detected current mode
  23. CURRENT_MODE_DETECT OFFSET(4) NUMBITS(2) [
  24. Default = 0,
  25. Medium = 1,
  26. ChargeThrough = 2,
  27. High = 3,
  28. ],
  29. // Programmed by application to change current advertisement
  30. CURRENT_MODE_ADVERTISE OFFSET(6) NUMBITS(2) [
  31. Default = 0,
  32. Mid = 1,
  33. High = 2,
  34. Reserved = 3,
  35. ],
  36. ],
  37. // Connection status and control register
  38. ConnStatus2 [
  39. // Setting this field will disable UFP accessory support
  40. DISABLE_UFP_ACCESSORY OFFSET(0) NUMBITS(1) [],
  41. // Percentage of time that a DRP advertised DFP during tDRP
  42. DRP_DUTY_CYCLE OFFSET(1) NUMBITS(2) [
  43. p30 = 0,
  44. p40 = 1,
  45. p50 = 2,
  46. p60 = 3,
  47. ],
  48. // Set when over-current limit is triggered
  49. VCONN_FAULT OFFSET(3) NUMBITS(1) [],
  50. // Pulled low when a control or status register changes
  51. INTERRUPT_STATUS OFFSET(4) NUMBITS(1) [
  52. Clear = 0,
  53. Changed = 1,
  54. ],
  55. // Cable orientation
  56. CABLE_DIR OFFSET(5) NUMBITS(1) [
  57. CC1 = 0,
  58. CC2 = 1,
  59. ],
  60. // Attached state (same as ID pin)
  61. ATTACHED_STATE OFFSET(6) NUMBITS(2) [
  62. NotAttached = 0,
  63. AttachedSrc_DFP = 1,
  64. AttachedSnk_UFP = 2,
  65. AttachedAccessory = 3,
  66. ],
  67. ],
  68. // General control register
  69. Control [
  70. // Disable CC pin termination
  71. DISABLE_TERM OFFSET(0) NUMBITS(1) [],
  72. // Control behavior when configured as DRP
  73. SOURCE_PERF OFFSET(1) NUMBITS(2) [
  74. StandardDrp = 0,
  75. DrpTrySnk = 1,
  76. Reserved = 2,
  77. DrpTrySrc = 3,
  78. ],
  79. // Soft reset internal logic (self-clearing)
  80. I2C_SOFT_RESET OFFSET(3) NUMBITS(1) [],
  81. // Configure device operation mode
  82. MODE_SELECT OFFSET(4) NUMBITS(2) [
  83. Drp = 0,
  84. Ufp = 1,
  85. Dfp = 2,
  86. ],
  87. // Debounce time on CC pins
  88. DEBOUNCE OFFSET(6) NUMBITS(2) [
  89. ms168 = 0,
  90. ms118 = 1,
  91. ms134 = 2,
  92. ms152 = 3,
  93. ],
  94. ],
  95. ];
  96. register_structs! {
  97. Tusb322Registers {
  98. (0x00 => id: [u8; 8]),
  99. (0x08 => stat1: InMemoryRegister<u8, ConnStatus1::Register>),
  100. (0x09 => stat2: InMemoryRegister<u8, ConnStatus2::Register>),
  101. (0x0A => ctrl: InMemoryRegister<u8, Control::Register>),
  102. (0x0B => @END),
  103. }
  104. }
  105. pub fn init(address: u8, i2c: &mut impl _embedded_hal_blocking_i2c_Write) {
  106. let stat1: InMemoryRegister<u8, ConnStatus1::Register> = InMemoryRegister::new(0);
  107. let stat2: InMemoryRegister<u8, ConnStatus2::Register> = InMemoryRegister::new(0);
  108. let ctrl: InMemoryRegister<u8, Control::Register> = InMemoryRegister::new(0);
  109. // Disable UFP accessory support (otherwise IC stays in DRP mode)
  110. stat2.modify(ConnStatus2::DISABLE_UFP_ACCESSORY::SET);
  111. // Disable CC termination to change to UFP mode
  112. ctrl.modify(Control::DISABLE_TERM::SET + Control::MODE_SELECT::Ufp);
  113. let buffer: [u8; 4] = [
  114. offset_of!(Tusb322Registers => stat1).get_byte_offset() as u8,
  115. stat1.get(),
  116. stat2.get(),
  117. ctrl.get(),
  118. ];
  119. match i2c.write(address, &buffer) {
  120. Ok(_) => (),
  121. Err(_) => panic!(),
  122. }
  123. // Re-enable CC termination
  124. ctrl.modify(Control::DISABLE_TERM::CLEAR);
  125. let buffer: [u8; 4] = [
  126. offset_of!(Tusb322Registers => stat1).get_byte_offset() as u8,
  127. stat1.get(),
  128. stat2.get(),
  129. ctrl.get(),
  130. ];
  131. match i2c.write(address, &buffer) {
  132. Ok(_) => (),
  133. Err(_) => panic!(),
  134. }
  135. }