fsk_demod.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. #include <furi.h>
  2. #include "fsk_demod.h"
  3. struct FSKDemod {
  4. uint32_t low_time;
  5. uint32_t low_pulses;
  6. uint32_t hi_time;
  7. uint32_t hi_pulses;
  8. bool invert;
  9. uint32_t mid_time;
  10. uint32_t time;
  11. uint32_t count;
  12. bool last_pulse;
  13. };
  14. FSKDemod*
  15. fsk_demod_alloc(uint32_t low_time, uint32_t low_pulses, uint32_t hi_time, uint32_t hi_pulses) {
  16. FSKDemod* demod = malloc(sizeof(FSKDemod));
  17. demod->invert = false;
  18. if(low_time > hi_time) {
  19. uint32_t tmp;
  20. tmp = hi_time;
  21. hi_time = low_time;
  22. low_time = tmp;
  23. tmp = hi_pulses;
  24. hi_pulses = low_pulses;
  25. low_pulses = tmp;
  26. demod->invert = true;
  27. }
  28. demod->low_time = low_time;
  29. demod->low_pulses = low_pulses;
  30. demod->hi_time = hi_time;
  31. demod->hi_pulses = hi_pulses;
  32. demod->mid_time = (hi_time - low_time) / 2 + low_time;
  33. demod->time = 0;
  34. demod->count = 0;
  35. demod->last_pulse = false;
  36. return demod;
  37. }
  38. void fsk_demod_free(FSKDemod* demod) {
  39. free(demod);
  40. }
  41. void fsk_demod_feed(FSKDemod* demod, bool polarity, uint32_t time, bool* value, uint32_t* count) {
  42. *count = 0;
  43. if(polarity) {
  44. // accumulate time
  45. demod->time = time;
  46. } else {
  47. demod->time += time;
  48. // check for valid pulse
  49. if(demod->time >= demod->low_time && demod->time < demod->hi_time) {
  50. bool pulse;
  51. if(demod->time < demod->mid_time) {
  52. pulse = false;
  53. } else {
  54. pulse = true;
  55. }
  56. demod->count++;
  57. // check for edge transition
  58. if(demod->last_pulse != pulse) {
  59. uint32_t data_count = demod->count + 1;
  60. if(demod->last_pulse) {
  61. data_count /= demod->hi_pulses;
  62. *value = !demod->invert;
  63. } else {
  64. data_count /= demod->low_pulses;
  65. *value = demod->invert;
  66. }
  67. *count = data_count;
  68. demod->count = 0;
  69. demod->last_pulse = pulse;
  70. }
  71. } else {
  72. demod->count = 0;
  73. }
  74. }
  75. }