irda_nec.c 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. #include <furi.h>
  2. #include <api-hal.h>
  3. #include "irda_nec.h"
  4. #include "irda_protocols.h"
  5. void ir_nec_preambula(void) {
  6. // 9ms carrier + 4.5ms pause
  7. irda_pwm_set(NEC_DUTY_CYCLE, NEC_CARRIER_FREQUENCY);
  8. delay_us(9000);
  9. irda_pwm_stop();
  10. delay_us(4500);
  11. }
  12. void ir_nec_send_bit(bool bit) {
  13. // 0 is 562.5us carrier + 1687.5us pause
  14. // 1 is 562.5us carrier + 562.5us pause
  15. irda_pwm_set(NEC_DUTY_CYCLE, NEC_CARRIER_FREQUENCY);
  16. delay_us(562.5);
  17. irda_pwm_stop();
  18. if(bit) {
  19. delay_us(562.5);
  20. } else {
  21. delay_us(1687.5);
  22. }
  23. }
  24. void ir_nec_send_byte(uint8_t data) {
  25. for(uint8_t i = 0; i < 8; i++) {
  26. ir_nec_send_bit((data & (1 << (i))) != 0);
  27. }
  28. }
  29. void ir_nec_send(uint16_t addr, uint8_t data) {
  30. // nec protocol is:
  31. // preambula + addr + inverse addr + command + inverse command + bit pulse
  32. //
  33. // oddly enough, my analyzer (https://github.com/ukw100/IRMP) displays the reverse command
  34. // and I don’t know if this is my fault or a feature of the analyzer
  35. // TODO: check the dictionary and check with a known remote
  36. uint8_t nec_packet[4] = {~(uint8_t)addr, ~(uint8_t)(addr >> 8), ~(uint8_t)data, data};
  37. osKernelLock();
  38. __disable_irq();
  39. ir_nec_preambula();
  40. ir_nec_send_byte(nec_packet[0]);
  41. ir_nec_send_byte(nec_packet[1]);
  42. ir_nec_send_byte(nec_packet[2]);
  43. ir_nec_send_byte(nec_packet[3]);
  44. ir_nec_send_bit(1);
  45. __enable_irq();
  46. osKernelUnlock();
  47. }