irda.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. #include <stdbool.h>
  2. #include <stdint.h>
  3. #include <stdlib.h>
  4. #include <furi.h>
  5. #include "irda_i.h"
  6. struct IrdaHandler {
  7. void** ctx;
  8. };
  9. typedef struct {
  10. IrdaAlloc alloc;
  11. IrdaDecode decode;
  12. IrdaFree free;
  13. } IrdaDecoders;
  14. typedef struct {
  15. IrdaEncode encode;
  16. } IrdaEncoders;
  17. typedef struct {
  18. IrdaProtocol protocol;
  19. const char* name;
  20. IrdaDecoders decoder;
  21. IrdaEncoders encoder;
  22. } IrdaProtocolImplementation;
  23. // TODO: replace with key-value, Now we refer by enum index, which is dangerous.
  24. static const IrdaProtocolImplementation irda_protocols[] = {
  25. // #0
  26. { .protocol = IrdaProtocolSamsung32,
  27. .name ="Samsung32",
  28. .decoder = {
  29. .alloc = irda_decoder_samsung32_alloc,
  30. .decode = irda_decoder_samsung32_decode,
  31. .free = irda_decoder_samsung32_free},
  32. .encoder = {
  33. .encode = irda_encoder_samsung32_encode}
  34. },
  35. // #1
  36. { .protocol = IrdaProtocolNEC,
  37. .name = "NEC",
  38. .decoder = {
  39. .alloc = irda_decoder_nec_alloc,
  40. .decode = irda_decoder_nec_decode,
  41. .free = irda_decoder_nec_free},
  42. .encoder = {
  43. .encode = irda_encoder_nec_encode}
  44. },
  45. };
  46. const IrdaMessage* irda_decode(IrdaHandler* handler, bool level, uint32_t duration) {
  47. furi_assert(handler);
  48. IrdaMessage* message = NULL;
  49. IrdaMessage* result = NULL;
  50. for (int i = 0; i < COUNT_OF(irda_protocols); ++i) {
  51. message = irda_protocols[i].decoder.decode(handler->ctx[i], level, duration);
  52. if (!result && message) {
  53. message->protocol = irda_protocols[i].protocol;
  54. result = message;
  55. }
  56. }
  57. return result;
  58. }
  59. IrdaHandler* irda_alloc_decoder(void) {
  60. IrdaHandler* handler = furi_alloc(sizeof(IrdaHandler));
  61. handler->ctx = furi_alloc(sizeof(void*) * COUNT_OF(irda_protocols));
  62. for (int i = 0; i < COUNT_OF(irda_protocols); ++i) {
  63. handler->ctx[i] = irda_protocols[i].decoder.alloc();
  64. furi_check(handler->ctx[i]);
  65. }
  66. return handler;
  67. }
  68. void irda_free_decoder(IrdaHandler* handler) {
  69. furi_assert(handler);
  70. furi_assert(handler->ctx);
  71. for (int i = 0; i < COUNT_OF(irda_protocols); ++i) {
  72. irda_protocols[i].decoder.free(handler->ctx[i]);
  73. }
  74. free(handler->ctx);
  75. free(handler);
  76. }
  77. void irda_send(const IrdaMessage* message, int times) {
  78. furi_assert(message);
  79. for (int i = 0; i < times; ++i) {
  80. osKernelLock();
  81. __disable_irq();
  82. irda_protocols[message->protocol].encoder.encode(message->address, message->command, !!i);
  83. __enable_irq();
  84. osKernelUnlock();
  85. }
  86. }
  87. const char* irda_get_protocol_name(IrdaProtocol protocol) {
  88. return irda_protocols[protocol].name;
  89. }