infrared_controller.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include "infrared_controller.h"
  2. #include <furi.h>
  3. #include <furi_hal.h>
  4. #include <infrared.h>
  5. #include <infrared_worker.h>
  6. #include <stdlib.h>
  7. #define TAG "LaserTagInfrared"
  8. #define IR_COMMAND_RED_TEAM 0xA1
  9. #define IR_COMMAND_BLUE_TEAM 0xB2
  10. struct InfraredController {
  11. LaserTagTeam team;
  12. InfraredWorker* worker;
  13. FuriThread* rx_thread;
  14. volatile bool rx_running;
  15. volatile bool hit_received;
  16. };
  17. static void infrared_rx_callback(void* context, InfraredWorkerSignal* received_signal) {
  18. InfraredController* controller = (InfraredController*)context;
  19. const InfraredMessage* message = infrared_worker_get_decoded_signal(received_signal);
  20. if (message != NULL) {
  21. uint32_t received_command = message->address;
  22. if((controller->team == TeamRed && received_command == IR_COMMAND_BLUE_TEAM) ||
  23. (controller->team == TeamBlue && received_command == IR_COMMAND_RED_TEAM)) {
  24. controller->hit_received = true;
  25. }
  26. }
  27. }
  28. static int32_t infrared_rx_thread(void* context) {
  29. InfraredController* controller = (InfraredController*)context;
  30. while(controller->rx_running) {
  31. infrared_worker_rx_start(controller->worker);
  32. furi_thread_flags_wait(0, FuriFlagWaitAny, 10);
  33. }
  34. return 0;
  35. }
  36. InfraredController* infrared_controller_alloc() {
  37. InfraredController* controller = malloc(sizeof(InfraredController));
  38. controller->team = TeamRed;
  39. controller->worker = infrared_worker_alloc();
  40. controller->rx_running = true;
  41. controller->hit_received = false;
  42. infrared_worker_rx_set_received_signal_callback(controller->worker, infrared_rx_callback, controller);
  43. controller->rx_thread = furi_thread_alloc();
  44. furi_thread_set_name(controller->rx_thread, "IR_Rx_Thread");
  45. furi_thread_set_stack_size(controller->rx_thread, 1024);
  46. furi_thread_set_context(controller->rx_thread, controller);
  47. furi_thread_set_callback(controller->rx_thread, infrared_rx_thread);
  48. furi_thread_start(controller->rx_thread);
  49. infrared_worker_rx_start(controller->worker);
  50. return controller;
  51. }
  52. void infrared_controller_free(InfraredController* controller) {
  53. furi_assert(controller);
  54. controller->rx_running = false;
  55. furi_thread_join(controller->rx_thread);
  56. furi_thread_free(controller->rx_thread);
  57. infrared_worker_rx_stop(controller->worker);
  58. infrared_worker_free(controller->worker);
  59. free(controller);
  60. }
  61. void infrared_controller_set_team(InfraredController* controller, LaserTagTeam team) {
  62. furi_assert(controller);
  63. controller->team = team;
  64. }
  65. void infrared_controller_send(InfraredController* controller) {
  66. furi_assert(controller);
  67. uint32_t command = (controller->team == TeamRed) ? IR_COMMAND_RED_TEAM : IR_COMMAND_BLUE_TEAM;
  68. InfraredMessage message = {
  69. .protocol = InfraredProtocolNEC,
  70. .address = 0x00,
  71. .command = command,
  72. .repeat = false
  73. };
  74. infrared_worker_set_decoded_signal(controller->worker, &message);
  75. infrared_worker_tx_set_get_signal_callback(
  76. controller->worker,
  77. infrared_worker_tx_get_signal_steady_callback,
  78. NULL);
  79. infrared_worker_tx_start(controller->worker);
  80. furi_delay_ms(250); // Delay to ensure the signal is sent
  81. infrared_worker_tx_stop(controller->worker);
  82. }
  83. bool infrared_controller_receive(InfraredController* controller) {
  84. furi_assert(controller);
  85. bool hit = controller->hit_received;
  86. controller->hit_received = false;
  87. return hit;
  88. }