encoder-emmarine.cpp 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. #include "encoder-emmarine.h"
  2. #include <furi.h>
  3. void EncoderEM::init(const uint8_t* data, const uint8_t data_size) {
  4. furi_check(data_size == 5);
  5. // header
  6. card_data = 0b111111111;
  7. // data
  8. for(uint8_t i = 0; i < 5; i++) {
  9. write_nibble(false, data[i]);
  10. write_nibble(true, data[i]);
  11. }
  12. // column parity and stop bit
  13. uint8_t parity_sum;
  14. for(uint8_t c = 0; c < 4; c++) {
  15. parity_sum = 0;
  16. for(uint8_t i = 1; i <= 10; i++) {
  17. uint8_t parity_bit = (card_data >> (i * 5 - 1)) & 1;
  18. parity_sum += parity_bit;
  19. }
  20. card_data = (card_data << 1) | ((parity_sum % 2) & 1);
  21. }
  22. // stop bit
  23. card_data = (card_data << 1) | 0;
  24. card_data_index = 0;
  25. }
  26. void EncoderEM::write_nibble(bool low_nibble, uint8_t data) {
  27. uint8_t parity_sum = 0;
  28. uint8_t start = 0;
  29. if(!low_nibble) start = 4;
  30. for(int8_t i = (start + 3); i >= start; i--) {
  31. parity_sum += (data >> i) & 1;
  32. card_data = (card_data << 1) | ((data >> i) & 1);
  33. }
  34. card_data = (card_data << 1) | ((parity_sum % 2) & 1);
  35. }
  36. // data transmitted as manchester encoding
  37. // 0 - high2low
  38. // 1 - low2high
  39. void EncoderEM::get_next(bool* polarity, uint16_t* period, uint16_t* pulse) {
  40. *period = clocks_per_bit;
  41. *pulse = clocks_per_bit / 2;
  42. *polarity = (card_data >> (63 - card_data_index)) & 1;
  43. card_data_index++;
  44. if(card_data_index >= 64) {
  45. card_data_index = 0;
  46. }
  47. }