irda_transmit.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. #include "irda.h"
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <furi.h>
  6. #include <furi-hal-irda.h>
  7. #include <furi-hal-delay.h>
  8. static uint32_t irda_tx_number_of_transmissions = 0;
  9. static uint32_t irda_tx_raw_timings_index = 0;
  10. static uint32_t irda_tx_raw_timings_number = 0;
  11. static uint32_t irda_tx_raw_start_from_mark = 0;
  12. static bool irda_tx_raw_add_silence = false;
  13. FuriHalIrdaTxGetDataState irda_get_raw_data_callback (void* context, uint32_t* duration, bool* level) {
  14. furi_assert(duration);
  15. furi_assert(level);
  16. furi_assert(context);
  17. FuriHalIrdaTxGetDataState state = FuriHalIrdaTxGetDataStateOk;
  18. const uint32_t* timings = context;
  19. if (irda_tx_raw_add_silence && (irda_tx_raw_timings_index == 0)) {
  20. irda_tx_raw_add_silence = false;
  21. *level = false;
  22. *duration = 180000; // 180 ms delay between raw packets
  23. } else {
  24. *level = irda_tx_raw_start_from_mark ^ (irda_tx_raw_timings_index % 2);
  25. *duration = timings[irda_tx_raw_timings_index++];
  26. }
  27. if (irda_tx_raw_timings_number == irda_tx_raw_timings_index) {
  28. state = FuriHalIrdaTxGetDataStateLastDone;
  29. }
  30. return state;
  31. }
  32. void irda_send_raw_ext(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark, uint32_t frequency, float duty_cycle) {
  33. furi_assert(timings);
  34. furi_assert(timings_cnt > 1);
  35. irda_tx_raw_start_from_mark = start_from_mark;
  36. irda_tx_raw_timings_index = 0;
  37. irda_tx_raw_timings_number = timings_cnt;
  38. irda_tx_raw_add_silence = start_from_mark;
  39. furi_hal_irda_async_tx_set_data_isr_callback(irda_get_raw_data_callback, (void*) timings);
  40. furi_hal_irda_async_tx_start(frequency, duty_cycle);
  41. furi_hal_irda_async_tx_wait_termination();
  42. furi_assert(!furi_hal_irda_is_busy());
  43. }
  44. void irda_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) {
  45. irda_send_raw_ext(timings, timings_cnt, start_from_mark, IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE);
  46. }
  47. FuriHalIrdaTxGetDataState irda_get_data_callback (void* context, uint32_t* duration, bool* level) {
  48. FuriHalIrdaTxGetDataState state = FuriHalIrdaTxGetDataStateError;
  49. IrdaEncoderHandler* handler = context;
  50. IrdaStatus status = IrdaStatusError;
  51. if (irda_tx_number_of_transmissions > 0) {
  52. status = irda_encode(handler, duration, level);
  53. }
  54. if (status == IrdaStatusError) {
  55. state = FuriHalIrdaTxGetDataStateError;
  56. } else if (status == IrdaStatusOk) {
  57. state = FuriHalIrdaTxGetDataStateOk;
  58. } else if (status == IrdaStatusDone) {
  59. state = FuriHalIrdaTxGetDataStateDone;
  60. if (--irda_tx_number_of_transmissions == 0) {
  61. state = FuriHalIrdaTxGetDataStateLastDone;
  62. }
  63. } else {
  64. furi_assert(0);
  65. state = FuriHalIrdaTxGetDataStateError;
  66. }
  67. return state;
  68. }
  69. void irda_send(const IrdaMessage* message, int times) {
  70. furi_assert(message);
  71. furi_assert(times);
  72. furi_assert(irda_is_protocol_valid(message->protocol));
  73. IrdaEncoderHandler* handler = irda_alloc_encoder();
  74. irda_reset_encoder(handler, message);
  75. irda_tx_number_of_transmissions = times;
  76. furi_hal_irda_async_tx_set_data_isr_callback(irda_get_data_callback, handler);
  77. furi_hal_irda_async_tx_start(IRDA_COMMON_CARRIER_FREQUENCY, IRDA_COMMON_DUTY_CYCLE);
  78. furi_hal_irda_async_tx_wait_termination();
  79. irda_free_encoder(handler);
  80. furi_assert(!furi_hal_irda_is_busy());
  81. }