one_wire_slave_gpio.h 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. #pragma once
  2. #include "flipper.h"
  3. #include "flipper_v2.h"
  4. #include "one_wire_timings.h"
  5. class OneWireGpioSlave {
  6. private:
  7. GpioPin* gpio;
  8. public:
  9. OneWireGpioSlave(GpioPin* one_wire_gpio);
  10. ~OneWireGpioSlave();
  11. void start(void);
  12. void stop(void);
  13. bool emulate(uint8_t* buffer, uint8_t length);
  14. bool check_reset(void);
  15. bool show_presence(void);
  16. bool receive_and_process_cmd(void);
  17. bool receive(uint8_t* data, const uint8_t data_length);
  18. bool receiveBit(void);
  19. bool overdrive_mode = false;
  20. OneWiteTimeType wait_while_gpio(volatile OneWiteTimeType retries, const bool pin_value);
  21. };
  22. OneWireGpioSlave::OneWireGpioSlave(GpioPin* one_wire_gpio) {
  23. gpio = one_wire_gpio;
  24. }
  25. OneWireGpioSlave::~OneWireGpioSlave() {
  26. stop();
  27. }
  28. void OneWireGpioSlave::start(void) {
  29. gpio_init(gpio, GpioModeOutputOpenDrain);
  30. }
  31. void OneWireGpioSlave::stop(void) {
  32. gpio_init(gpio, GpioModeAnalog);
  33. }
  34. bool OneWireGpioSlave::emulate(uint8_t* buffer, uint8_t length) {
  35. if(!check_reset()) {
  36. printf("reset error\n");
  37. return false;
  38. }
  39. if(!show_presence()) {
  40. printf("presence error\n");
  41. return false;
  42. }
  43. if(!receive_and_process_cmd()) {
  44. printf("receive_and_process_cmd error\n");
  45. return false;
  46. }
  47. printf("ok\n");
  48. return true;
  49. }
  50. OneWiteTimeType OneWireGpioSlave::wait_while_gpio(OneWiteTimeType time, const bool pin_value) {
  51. uint32_t start = DWT->CYCCNT;
  52. uint32_t time_ticks = time * (SystemCoreClock / 1000000.0f);
  53. while(((DWT->CYCCNT - start) < time_ticks)) {
  54. if(gpio_read(gpio) != pin_value) {
  55. uint32_t time = (DWT->CYCCNT - start);
  56. time /= (SystemCoreClock / 1000000.0f);
  57. return time;
  58. }
  59. }
  60. return 0;
  61. }
  62. bool OneWireGpioSlave::check_reset(void) {
  63. while(gpio_read(gpio) == true) {
  64. }
  65. /*if(wait_while_gpio(OneWireEmulateTiming::RESET_TIMEOUT * 20, true) == 0) {
  66. printf("RESET_TIMEOUT\n");
  67. return false;
  68. }*/
  69. const OneWiteTimeType time_remaining =
  70. wait_while_gpio(OneWireEmulateTiming::RESET_MAX[0], false);
  71. if(time_remaining == 0) {
  72. return false;
  73. }
  74. if(overdrive_mode && ((OneWireEmulateTiming::RESET_MAX[0] -
  75. OneWireEmulateTiming::RESET_MIN[0]) <= time_remaining)) {
  76. // normal reset detected
  77. overdrive_mode = false;
  78. };
  79. bool result = (time_remaining <= OneWireEmulateTiming::RESET_MAX[0]) &&
  80. time_remaining >= OneWireEmulateTiming::RESET_MIN[overdrive_mode];
  81. return result;
  82. }
  83. bool OneWireGpioSlave::show_presence(void) {
  84. wait_while_gpio(OneWireEmulateTiming::PRESENCE_TIMEOUT, true);
  85. gpio_write(gpio, false);
  86. delay_us(OneWireEmulateTiming::PRESENCE_MIN[overdrive_mode]);
  87. gpio_write(gpio, true);
  88. /*OneWiteTimeType wait_time = OneWireEmulateTiming::PRESENCE_MAX[overdrive_mode] -
  89. OneWireEmulateTiming::PRESENCE_MIN[overdrive_mode];
  90. if(wait_while_gpio(wait_time, false) == 0) {
  91. return false;
  92. }*/
  93. return true;
  94. }
  95. bool OneWireGpioSlave::receive_and_process_cmd(void) {
  96. uint8_t cmd;
  97. receive(&cmd, 1);
  98. printf("cmd %x\n", cmd);
  99. return false;
  100. }
  101. bool OneWireGpioSlave::receiveBit(void) {
  102. // wait while bus is HIGH
  103. OneWiteTimeType time = OneWireEmulateTiming::SLOT_MAX[overdrive_mode];
  104. time = wait_while_gpio(time, true);
  105. if(time == 0) {
  106. printf("RESET_IN_PROGRESS\n");
  107. return false;
  108. }
  109. /*while ((DIRECT_READ(pin_baseReg, pin_bitMask) == 0) && (--retries != 0));
  110. if (retries == 0)
  111. {
  112. _error = Error::RESET_IN_PROGRESS;
  113. return false;
  114. }*/
  115. // wait while bus is LOW
  116. time = OneWireEmulateTiming::MSG_HIGH_TIMEOUT;
  117. time = wait_while_gpio(time, false);
  118. if(time == 0) {
  119. printf("TIMEOUT_HIGH\n");
  120. return false;
  121. }
  122. /*while ((DIRECT_READ(pin_baseReg, pin_bitMask) != 0) && (--retries != 0));
  123. if (retries == 0)
  124. {
  125. _error = Error::AWAIT_TIMESLOT_TIMEOUT_HIGH;
  126. return false;
  127. }*/
  128. // wait a specific time to do a read (data is valid by then), // first difference to inner-loop of write()
  129. time = OneWireEmulateTiming::READ_MIN[overdrive_mode];
  130. time = wait_while_gpio(time, true);
  131. //while ((DIRECT_READ(pin_baseReg, pin_bitMask) == 0) && (--retries != 0));
  132. return (time > 0);
  133. }
  134. bool OneWireGpioSlave::receive(uint8_t* data, const uint8_t data_length) {
  135. uint8_t bytes_received = 0;
  136. for(; bytes_received < data_length; ++bytes_received) {
  137. uint8_t value = 0;
  138. for(uint8_t bitMask = 0x01; bitMask != 0; bitMask <<= 1) {
  139. if(receiveBit()) value |= bitMask;
  140. }
  141. data[bytes_received] = value;
  142. }
  143. return (bytes_received != data_length);
  144. }