one_wire_gpio.h 2.6 KB

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