cyfral_emulator.h 2.2 KB

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