tusb322.rs 4.3 KB

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