mp_flipper_modflipperzero_infrared.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. #include <furi_hal.h>
  2. #include <furi_hal_infrared.h>
  3. #include <mp_flipper_modflipperzero.h>
  4. #include <mp_flipper_runtime.h>
  5. #include "mp_flipper_context.h"
  6. inline static void on_rx(void* ctx, bool level, uint32_t duration) {
  7. mp_flipper_infrared_rx_t* session = ctx;
  8. if(session->pointer == 0 && !level) {
  9. return;
  10. }
  11. if(session->pointer < session->size) {
  12. session->buffer[session->pointer] = duration;
  13. session->pointer++;
  14. } else {
  15. session->running = false;
  16. }
  17. }
  18. inline static void on_rx_timeout(void* ctx) {
  19. mp_flipper_infrared_rx_t* session = ctx;
  20. session->running = false;
  21. }
  22. inline static FuriHalInfraredTxGetDataState on_tx(void* ctx, uint32_t* duration, bool* level) {
  23. mp_flipper_infrared_tx_t* session = ctx;
  24. *duration = session->provider(session->signal, session->index);
  25. *level = session->level;
  26. session->index++;
  27. if(session->index >= session->size) {
  28. session->index = 0;
  29. session->repeat--;
  30. }
  31. session->level = !session->level;
  32. return session->repeat > 0 ? FuriHalInfraredTxGetDataStateOk :
  33. FuriHalInfraredTxGetDataStateLastDone;
  34. }
  35. inline uint32_t* mp_flipper_infrared_receive(uint32_t timeout, size_t* length) {
  36. const mp_flipper_context_t* ctx = mp_flipper_context;
  37. mp_flipper_infrared_rx_t* session = ctx->infrared_rx;
  38. if(!furi_hal_infrared_is_busy()) {
  39. session->pointer = 0;
  40. session->running = true;
  41. furi_hal_infrared_async_rx_set_capture_isr_callback(on_rx, session);
  42. furi_hal_infrared_async_rx_set_timeout_isr_callback(on_rx_timeout, session);
  43. furi_hal_infrared_async_rx_start();
  44. furi_hal_infrared_async_rx_set_timeout(timeout);
  45. while(session->running) {
  46. furi_delay_tick(10);
  47. }
  48. furi_hal_infrared_async_rx_stop();
  49. *length = session->pointer;
  50. } else {
  51. *length = 0;
  52. }
  53. return session->buffer;
  54. }
  55. inline bool mp_flipper_infrared_transmit(
  56. void* signal,
  57. size_t length,
  58. mp_flipper_infrared_signal_tx_provider callback,
  59. uint32_t repeat,
  60. uint32_t frequency,
  61. float duty,
  62. bool use_external_pin) {
  63. if(furi_hal_infrared_is_busy() || length == 0) {
  64. return false;
  65. }
  66. const mp_flipper_context_t* ctx = mp_flipper_context;
  67. mp_flipper_infrared_tx_t* session = ctx->infrared_tx;
  68. session->index = 0;
  69. session->level = true;
  70. session->provider = callback;
  71. session->signal = signal;
  72. session->repeat = repeat;
  73. session->size = length;
  74. const FuriHalInfraredTxPin output = use_external_pin ? FuriHalInfraredTxPinExtPA7 :
  75. FuriHalInfraredTxPinInternal;
  76. furi_hal_infrared_set_tx_output(output);
  77. furi_hal_infrared_async_tx_set_data_isr_callback(on_tx, session);
  78. furi_hal_infrared_async_tx_start(frequency, duty);
  79. furi_hal_infrared_async_tx_wait_termination();
  80. return true;
  81. }
  82. inline bool mp_flipper_infrared_is_busy() {
  83. return furi_hal_infrared_is_busy();
  84. }