encoder_metakom.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include "encoder_metakom.h"
  2. #include <furi_hal.h>
  3. #define METAKOM_DATA_SIZE sizeof(uint32_t)
  4. #define METAKOM_PERIOD (125 * furi_hal_cortex_instructions_per_microsecond())
  5. #define METAKOM_0_LOW (METAKOM_PERIOD * 0.33f)
  6. #define METAKOM_0_HI (METAKOM_PERIOD * 0.66f)
  7. #define METAKOM_1_LOW (METAKOM_PERIOD * 0.66f)
  8. #define METAKOM_1_HI (METAKOM_PERIOD * 0.33f)
  9. #define METAKOM_SET_DATA(level, len) \
  10. *polarity = !level; \
  11. *length = len;
  12. struct EncoderMetakom {
  13. uint32_t data;
  14. uint32_t index;
  15. };
  16. EncoderMetakom* encoder_metakom_alloc() {
  17. EncoderMetakom* metakom = malloc(sizeof(EncoderMetakom));
  18. encoder_metakom_reset(metakom);
  19. return metakom;
  20. }
  21. void encoder_metakom_free(EncoderMetakom* metakom) {
  22. free(metakom);
  23. }
  24. void encoder_metakom_reset(EncoderMetakom* metakom) {
  25. metakom->data = 0;
  26. metakom->index = 0;
  27. }
  28. void encoder_metakom_set_data(EncoderMetakom* metakom, const uint8_t* data, size_t data_size) {
  29. furi_assert(metakom);
  30. furi_check(data_size >= METAKOM_DATA_SIZE);
  31. memcpy(&metakom->data, data, METAKOM_DATA_SIZE);
  32. }
  33. void encoder_metakom_get_pulse(EncoderMetakom* metakom, bool* polarity, uint32_t* length) {
  34. if(metakom->index == 0) {
  35. // sync bit
  36. METAKOM_SET_DATA(true, METAKOM_PERIOD);
  37. } else if(metakom->index >= 1 && metakom->index <= 6) {
  38. // start word (0b010)
  39. switch(metakom->index) {
  40. case 1:
  41. METAKOM_SET_DATA(false, METAKOM_0_LOW);
  42. break;
  43. case 2:
  44. METAKOM_SET_DATA(true, METAKOM_0_HI);
  45. break;
  46. case 3:
  47. METAKOM_SET_DATA(false, METAKOM_1_LOW);
  48. break;
  49. case 4:
  50. METAKOM_SET_DATA(true, METAKOM_1_HI);
  51. break;
  52. case 5:
  53. METAKOM_SET_DATA(false, METAKOM_0_LOW);
  54. break;
  55. case 6:
  56. METAKOM_SET_DATA(true, METAKOM_0_HI);
  57. break;
  58. }
  59. } else {
  60. // data
  61. uint8_t data_start_index = metakom->index - 7;
  62. bool clock_polarity = (data_start_index) % 2;
  63. uint8_t bit_index = (data_start_index) / 2;
  64. bool bit_value = (metakom->data >> (32 - 1 - bit_index)) & 1;
  65. if(!clock_polarity) {
  66. if(bit_value) {
  67. METAKOM_SET_DATA(false, METAKOM_1_LOW);
  68. } else {
  69. METAKOM_SET_DATA(false, METAKOM_0_LOW);
  70. }
  71. } else {
  72. if(bit_value) {
  73. METAKOM_SET_DATA(true, METAKOM_1_HI);
  74. } else {
  75. METAKOM_SET_DATA(true, METAKOM_0_HI);
  76. }
  77. }
  78. }
  79. metakom->index++;
  80. if(metakom->index >= (1 + 3 * 2 + 32 * 2)) {
  81. metakom->index = 0;
  82. }
  83. }