cyfral_emulator.h 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #pragma once
  2. #include <furi.h>
  3. #include <api-hal.h>
  4. class CyfralTiming {
  5. public:
  6. constexpr static const uint8_t ZERO_HIGH = 50;
  7. constexpr static const uint8_t ZERO_LOW = 70;
  8. constexpr static const uint8_t ONE_HIGH = 100;
  9. constexpr static const uint8_t ONE_LOW = 70;
  10. };
  11. class CyfralEmulator {
  12. private:
  13. void send_nibble(uint8_t nibble);
  14. void send_byte(uint8_t data);
  15. inline void send_bit(bool bit);
  16. const GpioPin* emulate_pin_record;
  17. public:
  18. CyfralEmulator(const GpioPin* emulate_pin);
  19. ~CyfralEmulator();
  20. void send(uint8_t* data, uint8_t count = 1, uint8_t repeat = 1);
  21. void start(void);
  22. void stop(void);
  23. };
  24. // 7 = 0 1 1 1
  25. // B = 1 0 1 1
  26. // D = 1 1 0 1
  27. // E = 1 1 1 0
  28. void CyfralEmulator::send_nibble(uint8_t nibble) {
  29. for(uint8_t i = 0; i < 4; i++) {
  30. bool bit = nibble & (0b1000 >> i);
  31. send_bit(bit);
  32. }
  33. }
  34. void CyfralEmulator::send_byte(uint8_t data) {
  35. for(uint8_t i = 0; i < 8; i++) {
  36. bool bit = data & (0b10000000 >> i);
  37. send_bit(bit);
  38. }
  39. }
  40. void CyfralEmulator::send_bit(bool bit) {
  41. if(!bit) {
  42. hal_gpio_write(&ibutton_gpio, false);
  43. delay_us(CyfralTiming::ZERO_LOW);
  44. hal_gpio_write(&ibutton_gpio, true);
  45. delay_us(CyfralTiming::ZERO_HIGH);
  46. hal_gpio_write(&ibutton_gpio, false);
  47. delay_us(CyfralTiming::ZERO_LOW);
  48. } else {
  49. hal_gpio_write(&ibutton_gpio, true);
  50. delay_us(CyfralTiming::ONE_HIGH);
  51. hal_gpio_write(&ibutton_gpio, false);
  52. delay_us(CyfralTiming::ONE_LOW);
  53. }
  54. }
  55. CyfralEmulator::CyfralEmulator(const GpioPin* emulate_pin) {
  56. emulate_pin_record = emulate_pin;
  57. }
  58. CyfralEmulator::~CyfralEmulator() {
  59. }
  60. void CyfralEmulator::send(uint8_t* data, uint8_t count, uint8_t repeat) {
  61. osKernelLock();
  62. __disable_irq();
  63. for(uint8_t i = 0; i < repeat; i++) {
  64. // start sequence
  65. send_nibble(0x01);
  66. // send data
  67. for(uint8_t i = 0; i < count; i++) {
  68. send_byte(data[i]);
  69. }
  70. }
  71. __enable_irq();
  72. osKernelUnlock();
  73. }
  74. void CyfralEmulator::start(void) {
  75. hal_gpio_init(emulate_pin_record, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
  76. hal_gpio_write(emulate_pin_record, false);
  77. }
  78. void CyfralEmulator::stop(void) {
  79. hal_gpio_init(emulate_pin_record, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
  80. }