cyfral_emulator.h 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #pragma once
  2. #include "flipper.h"
  3. #include "flipper_v2.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. gpio_write(&ibutton_gpio, false);
  43. delay_us(CyfralTiming::ZERO_LOW);
  44. gpio_write(&ibutton_gpio, true);
  45. delay_us(CyfralTiming::ZERO_HIGH);
  46. gpio_write(&ibutton_gpio, false);
  47. delay_us(CyfralTiming::ZERO_LOW);
  48. } else {
  49. gpio_write(&ibutton_gpio, true);
  50. delay_us(CyfralTiming::ONE_HIGH);
  51. 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. gpio_init(emulate_pin_record, GpioModeOutputOpenDrain);
  76. gpio_write(emulate_pin_record, false);
  77. }
  78. void CyfralEmulator::stop(void) {
  79. gpio_init(emulate_pin_record, GpioModeAnalog);
  80. }