irda_transmit.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  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. #define IRDA_SET_TX_COMMON(d, l) irda_set_tx((d), (l), IRDA_COMMON_DUTY_CYCLE, IRDA_COMMON_CARRIER_FREQUENCY)
  9. static void irda_set_tx(uint32_t duration, bool level, float duty_cycle, float frequency) {
  10. if (level) {
  11. api_hal_irda_pwm_set(duty_cycle, frequency);
  12. delay_us(duration);
  13. } else {
  14. api_hal_irda_pwm_stop();
  15. delay_us(duration);
  16. }
  17. }
  18. void irda_send_raw_ext(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark, float duty_cycle, float frequency) {
  19. __disable_irq();
  20. for (uint32_t i = 0; i < timings_cnt; ++i) {
  21. irda_set_tx(timings[i], (i % 2) ^ start_from_mark, duty_cycle, frequency);
  22. }
  23. IRDA_SET_TX_COMMON(0, false);
  24. __enable_irq();
  25. }
  26. void irda_send_raw(const uint32_t timings[], uint32_t timings_cnt, bool start_from_mark) {
  27. __disable_irq();
  28. for (uint32_t i = 0; i < timings_cnt; ++i) {
  29. IRDA_SET_TX_COMMON(timings[i], (i % 2) ^ start_from_mark);
  30. }
  31. IRDA_SET_TX_COMMON(0, false);
  32. __enable_irq();
  33. }
  34. void irda_send(const IrdaMessage* message, int times) {
  35. furi_assert(message);
  36. furi_assert(irda_is_protocol_valid(message->protocol));
  37. IrdaStatus status;
  38. uint32_t duration = 0;
  39. bool level = false;
  40. IrdaEncoderHandler* handler = irda_alloc_encoder();
  41. irda_reset_encoder(handler, message);
  42. /* Hotfix: first timings is space timing, so make delay instead of locking
  43. * whole system for that long. Replace when async timing lib will be ready.
  44. * This timing doesn't have to be precise.
  45. */
  46. status = irda_encode(handler, &duration, &level);
  47. furi_assert(status != IrdaStatusError);
  48. furi_assert(level == false);
  49. delay_us(duration);
  50. __disable_irq();
  51. while (times) {
  52. status = irda_encode(handler, &duration, &level);
  53. if (status != IrdaStatusError) {
  54. IRDA_SET_TX_COMMON(duration, level);
  55. } else {
  56. furi_assert(0);
  57. break;
  58. }
  59. if (status == IrdaStatusDone)
  60. --times;
  61. }
  62. IRDA_SET_TX_COMMON(0, false);
  63. __enable_irq();
  64. irda_free_encoder(handler);
  65. }