PD Buddy Sink Firmware
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

hard_reset.c 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. /*
  2. * PD Buddy Firmware Library - USB Power Delivery for everyone
  3. * Copyright 2017-2018 Clayton G. Hobbs
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. #include "hard_reset.h"
  18. #include <pd.h>
  19. #include "priorities.h"
  20. #include "policy_engine.h"
  21. #include "protocol_rx.h"
  22. #include "protocol_tx.h"
  23. #include "fusb302b.h"
  24. /*
  25. * Hard Reset machine states
  26. */
  27. enum hardrst_state {
  28. PRLHRResetLayer,
  29. PRLHRIndicateHardReset,
  30. PRLHRRequestHardReset,
  31. PRLHRWaitPHY,
  32. PRLHRHardResetRequested,
  33. PRLHRWaitPE,
  34. PRLHRComplete
  35. };
  36. /*
  37. * PRL_HR_Reset_Layer state
  38. */
  39. static enum hardrst_state hardrst_reset_layer(struct pdb_config *cfg)
  40. {
  41. /* First, wait for the signal to run a hard reset. */
  42. eventmask_t evt = chEvtWaitAny(PDB_EVT_HARDRST_RESET
  43. | PDB_EVT_HARDRST_I_HARDRST);
  44. /* Reset the stored message IDs */
  45. cfg->prl._rx_messageid = 0;
  46. cfg->prl._tx_messageidcounter = 0;
  47. /* Reset the Protocol RX machine */
  48. chEvtSignal(cfg->prl.rx_thread, PDB_EVT_PRLRX_RESET);
  49. chThdYield();
  50. /* Reset the Protocol TX machine */
  51. chEvtSignal(cfg->prl.tx_thread, PDB_EVT_PRLTX_RESET);
  52. chThdYield();
  53. /* Continue the process based on what event started the reset. */
  54. if (evt & PDB_EVT_HARDRST_RESET) {
  55. /* Policy Engine started the reset. */
  56. return PRLHRRequestHardReset;
  57. } else {
  58. /* PHY started the reset */
  59. return PRLHRIndicateHardReset;
  60. }
  61. }
  62. static enum hardrst_state hardrst_indicate_hard_reset(struct pdb_config *cfg)
  63. {
  64. /* Tell the PE that we're doing a hard reset */
  65. chEvtSignal(cfg->pe.thread, PDB_EVT_PE_RESET);
  66. return PRLHRWaitPE;
  67. }
  68. static enum hardrst_state hardrst_request_hard_reset(struct pdb_config *cfg)
  69. {
  70. (void) cfg;
  71. /* Tell the PHY to send a hard reset */
  72. fusb_send_hardrst(&cfg->fusb);
  73. return PRLHRWaitPHY;
  74. }
  75. static enum hardrst_state hardrst_wait_phy(struct pdb_config *cfg)
  76. {
  77. (void) cfg;
  78. /* Wait for the PHY to tell us that it's done sending the hard reset */
  79. chEvtWaitAnyTimeout(PDB_EVT_HARDRST_I_HARDSENT, PD_T_HARD_RESET_COMPLETE);
  80. /* Move on no matter what made us stop waiting. */
  81. return PRLHRHardResetRequested;
  82. }
  83. static enum hardrst_state hardrst_hard_reset_requested(struct pdb_config *cfg)
  84. {
  85. /* Tell the PE that the hard reset was sent */
  86. chEvtSignal(cfg->pe.thread, PDB_EVT_PE_HARD_SENT);
  87. return PRLHRWaitPE;
  88. }
  89. static enum hardrst_state hardrst_wait_pe(struct pdb_config *cfg)
  90. {
  91. (void) cfg;
  92. /* Wait for the PE to tell us that it's done */
  93. chEvtWaitAny(PDB_EVT_HARDRST_DONE);
  94. return PRLHRComplete;
  95. }
  96. static enum hardrst_state hardrst_complete(struct pdb_config *cfg)
  97. {
  98. (void) cfg;
  99. /* I'm not aware of anything we have to tell the FUSB302B, so just finish
  100. * the reset routine. */
  101. return PRLHRResetLayer;
  102. }
  103. /*
  104. * Hard Reset state machine thread
  105. */
  106. static THD_FUNCTION(HardReset, cfg) {
  107. enum hardrst_state state = PRLHRResetLayer;
  108. while (true) {
  109. switch (state) {
  110. case PRLHRResetLayer:
  111. state = hardrst_reset_layer(cfg);
  112. break;
  113. case PRLHRIndicateHardReset:
  114. state = hardrst_indicate_hard_reset(cfg);
  115. break;
  116. case PRLHRRequestHardReset:
  117. state = hardrst_request_hard_reset(cfg);
  118. break;
  119. case PRLHRWaitPHY:
  120. state = hardrst_wait_phy(cfg);
  121. break;
  122. case PRLHRHardResetRequested:
  123. state = hardrst_hard_reset_requested(cfg);
  124. break;
  125. case PRLHRWaitPE:
  126. state = hardrst_wait_pe(cfg);
  127. break;
  128. case PRLHRComplete:
  129. state = hardrst_complete(cfg);
  130. break;
  131. default:
  132. /* This is an error. It really shouldn't happen. We might
  133. * want to handle it anyway, though. */
  134. break;
  135. }
  136. }
  137. }
  138. void pdb_hardrst_run(struct pdb_config *cfg)
  139. {
  140. cfg->prl.hardrst_thread = chThdCreateStatic(cfg->prl._hardrst_wa,
  141. sizeof(cfg->prl._hardrst_wa), PDB_PRIO_PRL, HardReset, cfg);
  142. }