one_wire_gpio.h 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. #pragma once
  2. #include "flipper.h"
  3. #include "flipper_v2.h"
  4. #include "one_wire_timings.h"
  5. class OneWireGpio {
  6. private:
  7. const GpioPin* gpio;
  8. public:
  9. OneWireGpio(const GpioPin* one_wire_gpio);
  10. ~OneWireGpio();
  11. bool reset(void);
  12. bool read_bit(void);
  13. uint8_t read(void);
  14. void read_bytes(uint8_t* buf, uint16_t count);
  15. void write_bit(bool value);
  16. void write(uint8_t value);
  17. void start(void);
  18. void stop(void);
  19. };
  20. OneWireGpio::OneWireGpio(const GpioPin* one_wire_gpio) {
  21. gpio = one_wire_gpio;
  22. }
  23. OneWireGpio::~OneWireGpio() {
  24. stop();
  25. }
  26. void OneWireGpio::start(void) {
  27. gpio_init(gpio, GpioModeOutputOpenDrain);
  28. }
  29. void OneWireGpio::stop(void) {
  30. gpio_init(gpio, GpioModeAnalog);
  31. }
  32. bool OneWireGpio::reset(void) {
  33. uint8_t r;
  34. uint8_t retries = 125;
  35. // wait until the gpio is high
  36. gpio_write(gpio, true);
  37. do {
  38. if(--retries == 0) return 0;
  39. delay_us(2);
  40. } while(!gpio_read(gpio));
  41. // pre delay
  42. delay_us(OneWireTiming::RESET_DELAY_PRE);
  43. // drive low
  44. gpio_write(gpio, false);
  45. delay_us(OneWireTiming::RESET_DRIVE);
  46. // release
  47. gpio_write(gpio, true);
  48. delay_us(OneWireTiming::RESET_RELEASE);
  49. // read and post delay
  50. r = !gpio_read(gpio);
  51. delay_us(OneWireTiming::RESET_DELAY_POST);
  52. return r;
  53. }
  54. bool OneWireGpio::read_bit(void) {
  55. bool result;
  56. // drive low
  57. gpio_write(gpio, false);
  58. delay_us(OneWireTiming::READ_DRIVE);
  59. // release
  60. gpio_write(gpio, true);
  61. delay_us(OneWireTiming::READ_RELEASE);
  62. // read and post delay
  63. result = gpio_read(gpio);
  64. delay_us(OneWireTiming::READ_DELAY_POST);
  65. return result;
  66. }
  67. void OneWireGpio::write_bit(bool value) {
  68. if(value) {
  69. // drive low
  70. gpio_write(gpio, false);
  71. delay_us(OneWireTiming::WRITE_1_DRIVE);
  72. // release
  73. gpio_write(gpio, true);
  74. delay_us(OneWireTiming::WRITE_1_RELEASE);
  75. } else {
  76. // drive low
  77. gpio_write(gpio, false);
  78. delay_us(OneWireTiming::WRITE_0_DRIVE);
  79. // release
  80. gpio_write(gpio, true);
  81. delay_us(OneWireTiming::WRITE_0_RELEASE);
  82. }
  83. }
  84. uint8_t OneWireGpio::read(void) {
  85. uint8_t result = 0;
  86. for(uint8_t bitMask = 0x01; bitMask; bitMask <<= 1) {
  87. if(read_bit()) {
  88. result |= bitMask;
  89. }
  90. }
  91. return result;
  92. }
  93. void OneWireGpio::read_bytes(uint8_t* buffer, uint16_t count) {
  94. for(uint16_t i = 0; i < count; i++) {
  95. buffer[i] = read();
  96. }
  97. }
  98. void OneWireGpio::write(uint8_t value) {
  99. uint8_t bitMask;
  100. for(bitMask = 0x01; bitMask; bitMask <<= 1) {
  101. write_bit((bitMask & value) ? 1 : 0);
  102. }
  103. }