irda_transmit.c 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. #include "irda.h"
  2. #include <stdint.h>
  3. #include <stdbool.h>
  4. #include <stddef.h>
  5. #include <furi.h>
  6. #include <api-hal-irda.h>
  7. #include <api-hal-delay.h>
  8. static void irda_set_tx(uint32_t duration, bool level) {
  9. if (level) {
  10. api_hal_irda_pwm_set(IRDA_COMMON_DUTY_CYCLE, IRDA_COMMON_CARRIER_FREQUENCY);
  11. delay_us(duration);
  12. } else {
  13. api_hal_irda_pwm_stop();
  14. delay_us(duration);
  15. }
  16. }
  17. void irda_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) {
  18. __disable_irq();
  19. for (uint32_t i = 0; i < timings_cnt; ++i) {
  20. irda_set_tx(timings[i], (i % 2) ^ start_from_mark);
  21. }
  22. irda_set_tx(0, false);
  23. __enable_irq();
  24. }
  25. void irda_send(const IrdaMessage* message, int times) {
  26. furi_assert(message);
  27. furi_assert(irda_is_protocol_valid(message->protocol));
  28. IrdaStatus status;
  29. uint32_t duration = 0;
  30. bool level = false;
  31. IrdaEncoderHandler* handler = irda_alloc_encoder();
  32. irda_reset_encoder(handler, message);
  33. /* Hotfix: first timings is space timing, so make delay instead of locking
  34. * whole system for that long. Replace when async timing lib will be ready.
  35. * This timing doesn't have to be precise.
  36. */
  37. status = irda_encode(handler, &duration, &level);
  38. furi_assert(status != IrdaStatusError);
  39. furi_assert(level == false);
  40. delay_us(duration);
  41. __disable_irq();
  42. while (times) {
  43. status = irda_encode(handler, &duration, &level);
  44. if (status != IrdaStatusError) {
  45. irda_set_tx(duration, level);
  46. } else {
  47. furi_assert(0);
  48. break;
  49. }
  50. if (status == IrdaStatusDone)
  51. --times;
  52. }
  53. irda_set_tx(0, false);
  54. __enable_irq();
  55. irda_free_encoder(handler);
  56. }