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"
17 #error Invalid radio configuration!
20 #if defined(PLATFORM_ESP32)
21 #include <soc/soc_caps.h>
22 #define MULTICORE (SOC_CPU_CORES_NUM > 1)
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};
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()
42 #define CURRENT_CORE -1
45 void devicesRegister(device_affinity_t
*devices
, uint8_t count
)
51 taskSemaphore
= xSemaphoreCreateBinary();
52 completeSemaphore
= xSemaphoreCreateBinary();
54 xTaskCreatePinnedToCore(deviceTask
, "deviceTask", 32768, NULL
, 0, &xDeviceTask
, 0);
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;
74 xSemaphoreGive(taskSemaphore
);
75 xSemaphoreTake(completeSemaphore
, portMAX_DELAY
);
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
;
99 xSemaphoreGive(taskSemaphore
);
100 xSemaphoreTake(completeSemaphore
, portMAX_DELAY
);
108 vTaskDelete(xDeviceTask
);
112 void devicesTriggerEvent(uint32_t events
)
114 eventFired
[0] |= events
;
115 eventFired
[1] |= events
;
117 // Release the semaphore so the tasks on core 0 run now
118 xSemaphoreGive(taskSemaphore
);
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
;
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
)
174 [[noreturn
]] static void deviceTask(void *pvArgs
)
176 xSemaphoreTake(taskSemaphore
, portMAX_DELAY
);
178 xSemaphoreGive(completeSemaphore
);
179 xSemaphoreTake(taskSemaphore
, portMAX_DELAY
);
181 xSemaphoreGive(completeSemaphore
);
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
));