Clean up MSP_STATUS for DJI O4 (#3107)
[ExpressLRS.git] / src / lib / DEVICE / device.cpp
blob515c537b2dc2e63cc198043778f5597c762eafbe
1 #include "targets.h"
2 #include "common.h"
3 #include "logging.h"
4 #include "helpers.h"
5 #include "device.h"
7 ///////////////////////////////////////
8 // Even though we aren't using anything this keeps the PIO dependency analyzer happy!
10 #if defined(RADIO_SX127X)
11 #include "SX127xDriver.h"
12 #elif defined(RADIO_LR1121)
13 #include "LR1121Driver.h"
14 #elif defined(RADIO_SX128X)
15 #include "SX1280Driver.h"
16 #else
17 #error Invalid radio configuration!
18 #endif
20 #if defined(PLATFORM_ESP32)
21 #include <soc/soc_caps.h>
22 #define MULTICORE (SOC_CPU_CORES_NUM > 1)
23 #endif
25 ///////////////////////////////////////
27 static device_affinity_t *uiDevices;
28 static uint8_t deviceCount;
30 static uint32_t eventFired[2] = {0, 0};
31 static bool lastModelMatch[2] = {false, false};
33 static unsigned long deviceTimeout[16] = {0};
35 #if MULTICORE
36 static TaskHandle_t xDeviceTask = NULL;
37 static SemaphoreHandle_t taskSemaphore;
38 static SemaphoreHandle_t completeSemaphore;
39 [[noreturn]] static void deviceTask(void *pvArgs);
40 #define CURRENT_CORE xPortGetCoreID()
41 #else
42 #define CURRENT_CORE -1
43 #endif
45 void devicesRegister(device_affinity_t *devices, uint8_t count)
47 uiDevices = devices;
48 deviceCount = count;
50 #if MULTICORE
51 taskSemaphore = xSemaphoreCreateBinary();
52 completeSemaphore = xSemaphoreCreateBinary();
53 disableCore0WDT();
54 xTaskCreatePinnedToCore(deviceTask, "deviceTask", 32768, NULL, 0, &xDeviceTask, 0);
55 #endif
58 void devicesInit()
60 int32_t core = CURRENT_CORE;
62 for(size_t i=0 ; i<deviceCount ; i++) {
63 if (uiDevices[i].core == core || core == -1) {
64 if (uiDevices[i].device->initialize && !(uiDevices[i].device->initialize)()) {
65 uiDevices[i].device->start = nullptr;
66 uiDevices[i].device->event = nullptr;
67 uiDevices[i].device->timeout = nullptr;
71 #if MULTICORE
72 if (core == 1)
74 xSemaphoreGive(taskSemaphore);
75 xSemaphoreTake(completeSemaphore, portMAX_DELAY);
77 #endif
80 void devicesStart()
82 int32_t core = CURRENT_CORE;
83 unsigned long now = millis();
85 for(size_t i=0 ; i<deviceCount ; i++)
87 if (uiDevices[i].core == core || core == -1) {
88 deviceTimeout[i] = 0xFFFFFFFF;
89 if (uiDevices[i].device->start)
91 int delay = (uiDevices[i].device->start)();
92 deviceTimeout[i] = delay == DURATION_NEVER ? 0xFFFFFFFF : now + delay;
96 #if MULTICORE
97 if (core == 1)
99 xSemaphoreGive(taskSemaphore);
100 xSemaphoreTake(completeSemaphore, portMAX_DELAY);
102 #endif
105 void devicesStop()
107 #if MULTICORE
108 vTaskDelete(xDeviceTask);
109 #endif
112 void devicesTriggerEvent(uint32_t events)
114 eventFired[0] |= events;
115 eventFired[1] |= events;
116 #if MULTICORE
117 // Release the semaphore so the tasks on core 0 run now
118 xSemaphoreGive(taskSemaphore);
119 #endif
122 static int _devicesUpdate(unsigned long now)
124 const int32_t core = CURRENT_CORE;
125 const int32_t coreMulti = (core == -1) ? 0 : core;
127 bool newModelMatch = connectionHasModelMatch && teamraceHasModelMatch;
128 uint32_t events = eventFired[coreMulti];
129 eventFired[coreMulti] = 0;
130 bool handleEvents = events != 0 || lastModelMatch[coreMulti] != newModelMatch;
131 lastModelMatch[coreMulti] = newModelMatch;
133 if (handleEvents)
135 for(size_t i=0 ; i<deviceCount ; i++)
137 if ((uiDevices[i].core == core || core == -1) && (uiDevices[i].device->event && (uiDevices[i].device->subscribe & events) != 0))
139 int delay = (uiDevices[i].device->event)();
140 if (delay != DURATION_IGNORE)
142 deviceTimeout[i] = delay == DURATION_NEVER ? 0xFFFFFFFF : now + delay;
148 int smallest_delay = DURATION_NEVER;
149 for(size_t i=0 ; i<deviceCount ; i++)
151 if ((uiDevices[i].core == core || core == -1) && uiDevices[i].device->timeout)
153 int delay = deviceTimeout[i] == 0xFFFFFFFF ? DURATION_NEVER : (int)(deviceTimeout[i]-now);
154 if (now >= deviceTimeout[i])
156 delay = (uiDevices[i].device->timeout)();
157 deviceTimeout[i] = delay == DURATION_NEVER ? 0xFFFFFFFF : now + delay;
159 if (delay != DURATION_NEVER)
161 smallest_delay = (smallest_delay == DURATION_NEVER) ? delay : std::min(smallest_delay, delay);
165 return smallest_delay;
168 void devicesUpdate(unsigned long now)
170 _devicesUpdate(now);
173 #if MULTICORE
174 [[noreturn]] static void deviceTask(void *pvArgs)
176 xSemaphoreTake(taskSemaphore, portMAX_DELAY);
177 devicesInit();
178 xSemaphoreGive(completeSemaphore);
179 xSemaphoreTake(taskSemaphore, portMAX_DELAY);
180 devicesStart();
181 xSemaphoreGive(completeSemaphore);
182 for (;;)
184 int delay = _devicesUpdate(millis());
185 // sleep the core until the desired time, or it's awakened by an event
186 xSemaphoreTake(taskSemaphore, delay == DURATION_NEVER ? portMAX_DELAY : pdMS_TO_TICKS(delay));
189 #endif