Skip to content

Commit 090aa87

Browse files
committed
Semaphore: refactors - move sending and scheduling stuff around.
1 parent e99907f commit 090aa87

18 files changed

Lines changed: 697 additions & 528 deletions

device/src/messenger.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#if DEVICE_IS_UHK_DONGLE
3636
#include <zephyr/kernel.h>
3737
#include "usb_report_updater.h"
38+
#include "usb_report_sender.h"
3839

3940
static K_SEM_DEFINE(dongleUsbSem, 0, 1);
4041

@@ -241,8 +242,8 @@ static void processSyncablePropertyDongle(device_id_t src, const uint8_t* data,
241242

242243
#if DEVICE_IS_UHK_DONGLE
243244
uint8_t retryCounter = 0;
244-
while (ShouldResendReport(ret, &retryCounter)) {
245-
uint16_t delay = GetResendThrottleDelay(retryCounter);
245+
while (!UsbReportSender_ShouldGiveUp(ret, &retryCounter)) {
246+
uint16_t delay = UsbReportSender_ComputeResendDelay(retryCounter);
246247
k_sleep(K_MSEC(delay));
247248
k_sem_take(&dongleUsbSem, K_MSEC(128));
248249
ret = sendDongleReport(propertyId, message);

right/src/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,9 @@ target_sources(${PROJECT_NAME} PRIVATE
6868
$<$<BOOL:${IS_MCUX_SDK}>:${CMAKE_CURRENT_SOURCE_DIR}/trace_reasons.c>
6969
usb_log_buffer.c
7070
usb_protocol_handler.c
71+
usb_report_sender.c
72+
usb_scheduler.c
73+
usb_semaphore.c
7174
usb_report_updater.c
7275
usb_state.c
7376
user_logic.c

right/src/event_scheduler.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include "peripherals/merge_sensor.h"
1212
#include "power_mode.h"
1313
#include "usb_report_updater.h"
14+
#include "usb_semaphore.h"
1415
#include "oneshot.h"
1516
#include "trace.h"
1617

@@ -255,7 +256,7 @@ static void processEvt(event_scheduler_event_t evt)
255256
case EventSchedulerEvent_UpdateUsbSemaphore:
256257
// Drives the semaphore timeout so a stuck (unconfirmed) report gets resent
257258
// even if nothing else wakes the event loop.
258-
UsbReadyForTransfers();
259+
UsbSemaphore_RecalculateIsReady();
259260
break;
260261
case EventSchedulerEvent_CheckLeftBleVsUart:
261262
#if DEVICE_IS_UHK80_LEFT

right/src/hid/transport.cpp

Lines changed: 22 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ extern "C" {
1616
#include "timer.h"
1717
#include "trace.h"
1818
#include "usb_report_updater.h"
19+
#include "usb_semaphore.h"
20+
#include "usb_scheduler.h"
1921
#include "led_display.h"
2022
#include "jitter_test.h"
2123
#include "usb_state.h"
@@ -32,83 +34,25 @@ extern "C" {
3234
#error "Either CONFIG_DEBUG or NDEBUG must be defined"
3335
#endif
3436

35-
typedef enum {
36-
ReportSink_Invalid,
37-
ReportSink_Usb,
38-
ReportSink_BleHid,
39-
ReportSink_Dongle,
40-
ReportSink_TestSuite,
41-
} report_sink_t;
37+
#ifdef __ZEPHYR__
38+
#include <zephyr/logging/log.h>
39+
LOG_MODULE_REGISTER(Transport, LOG_LEVEL_INF);
40+
#endif
41+
// On mcux, logger.h provides the LOG_WRN / LOG_ERR / ... redirects.
4242

4343
// Exponential moving average (alpha=1/8) of the measured delay between a
4444
// BLE HID report being handed to the stack and the corresponding sent callback
45-
// firing. Populated when DEBUG_BLE_LATENCY_STATS is enabled; useful for
46-
// observing whether the send pipeline is saturated.
45+
// firing. Populated when DEBUG_BLE_LATENCY_STATS is enabled (in usb_report_sender.c);
46+
// useful for observing whether the send pipeline is saturated.
4747
extern "C" {
4848
float HidReportBleLatencyAvgMs = 0;
4949
}
50-
static uint32_t dispatchTimeMs = 0;
51-
52-
// Approximate transport window intervals (ms) used by the report-construction
53-
// throttle. After dispatch we estimate the next free window at "now + 2 *
54-
// interval" (worst case: we just missed a window). The send-completion
55-
// callback then reduces the estimate to "now + interval".
56-
static constexpr uint32_t USB_REPORT_INTERVAL_MS = 1;
5750

5851
bool UnreliableTransportTestMode = false;
5952

60-
static uint32_t reportIntervalForSink(report_sink_t sink)
61-
{
62-
switch (sink) {
63-
case ReportSink_Usb:
64-
return USB_REPORT_INTERVAL_MS;
65-
case ReportSink_BleHid:
66-
case ReportSink_Dongle:
67-
#if DEVICE_IS_UHK80_RIGHT
68-
return BtConn_GetReportIntervalMs(ActiveHostConnectionId);
69-
#else
70-
return 11;
71-
#endif
72-
default:
73-
return 1;
74-
}
75-
}
76-
77-
static void noteReportDispatched(report_sink_t sink)
78-
{
79-
if (DEBUG_BLE_LATENCY_STATS) {
80-
if (dispatchTimeMs == 0) {
81-
dispatchTimeMs = Timer_GetCurrentTime();
82-
}
83-
}
84-
UsbReportWindowEstimate = UsbReportWindowEstimateLast + 2 * reportIntervalForSink(sink);
85-
}
86-
87-
static void noteReportSent(report_sink_t transport)
88-
{
89-
if (DEBUG_BLE_LATENCY_STATS) {
90-
if (dispatchTimeMs != 0) {
91-
uint32_t delta = Timer_GetCurrentTime() - dispatchTimeMs;
92-
HidReportBleLatencyAvgMs = (HidReportBleLatencyAvgMs * 7 + delta) / 8;
93-
dispatchTimeMs = 0;
94-
}
95-
}
96-
uint32_t reportInterval = reportIntervalForSink(transport);
97-
uint32_t currentTime = Timer_GetCurrentTime();
98-
int16_t jitterGuess = (currentTime - UsbReportWindowEstimateLast - reportInterval + 1) / 2;
99-
jitterGuess = MAX(0, jitterGuess);
100-
UsbReportWindowEstimateLast = currentTime - jitterGuess;
101-
UsbReportWindowEstimate = currentTime - jitterGuess + reportInterval;
102-
uint32_t nextIn = UsbReportWindowEstimate - USB_REPORT_WINDOW_LOOKAHEAD_MS;
103-
104-
if (DEVICE_IS_UHK80_RIGHT) {
105-
EventScheduler_Schedule(nextIn, EventSchedulerEvent_Postponer, "Report sent. Recalculate report throttles");
106-
}
107-
}
108-
10953
extern "C" void HidTransport_NoteNusReportSent(void)
11054
{
111-
noteReportSent(ReportSink_Dongle);
55+
UsbScheduler_ReportDelivered(ReportSink_Dongle);
11256
}
11357

11458
static report_sink_t determineSink()
@@ -180,7 +124,7 @@ extern "C" void Hid_TransportStateChanged(
180124
extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
181125
{
182126
report_sink_t sink = determineSink();
183-
noteReportDispatched(sink);
127+
UsbScheduler_ReportAcceptedByTransport(sink);
184128
Trace_Printf("z11,%d", sink);
185129
errno_t err;
186130
if (UnreliableTransportTestMode && Utils_Random() % 7 == 0) {
@@ -201,7 +145,7 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
201145
if (err != 0) {
202146
printk("Failed to send keyboard report to dongle: %d\n", err);
203147
} else {
204-
UsbReportUpdater_ConfirmKeyboardReportSent();
148+
UsbSemaphore_Release(&UsbSemaphore.keyboard);
205149
}
206150
break;
207151
#endif
@@ -226,8 +170,8 @@ extern "C" void Hid_KeyboardReportSentCallback(hid_transport_t transport)
226170
if (UnreliableTransportTestMode && Utils_Random() % 7 == 0) {
227171
return;
228172
}
229-
UsbReportUpdater_ConfirmKeyboardReportSent();
230-
noteReportSent(transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
173+
UsbSemaphore_Release(&UsbSemaphore.keyboard);
174+
UsbScheduler_ReportDelivered(transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
231175
#if DEVICE_IS_UHK_DONGLE
232176
Dongle_SignalUsbReportSent();
233177
#endif
@@ -236,7 +180,7 @@ extern "C" void Hid_KeyboardReportSentCallback(hid_transport_t transport)
236180
extern "C" errno_t Hid_SendMouseReport(const hid_mouse_report_t *report)
237181
{
238182
report_sink_t sink = determineSink();
239-
noteReportDispatched(sink);
183+
UsbScheduler_ReportAcceptedByTransport(sink);
240184
Trace_Printf("z21,%d", sink);
241185
errno_t err;
242186
switch (sink) {
@@ -254,7 +198,7 @@ extern "C" errno_t Hid_SendMouseReport(const hid_mouse_report_t *report)
254198
if (err != 0) {
255199
printk("Failed to send mouse report to dongle: %d\n", err);
256200
} else {
257-
UsbReportUpdater_ConfirmMouseReportSent();
201+
UsbSemaphore_Release(&UsbSemaphore.mouse);
258202
}
259203
break;
260204
#endif
@@ -274,8 +218,8 @@ extern "C" errno_t Hid_SendMouseReport(const hid_mouse_report_t *report)
274218

275219
extern "C" void Hid_MouseReportSentCallback(hid_transport_t transport)
276220
{
277-
UsbReportUpdater_ConfirmMouseReportSent();
278-
noteReportSent( transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
221+
UsbSemaphore_Release(&UsbSemaphore.mouse);
222+
UsbScheduler_ReportDelivered( transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
279223
#if DEVICE_IS_UHK_DONGLE
280224
Dongle_SignalUsbReportSent();
281225
#endif
@@ -284,7 +228,7 @@ extern "C" void Hid_MouseReportSentCallback(hid_transport_t transport)
284228
extern "C" errno_t Hid_SendControlsReport(const hid_controls_report_t *report)
285229
{
286230
report_sink_t sink = determineSink();
287-
noteReportDispatched(sink);
231+
UsbScheduler_ReportAcceptedByTransport(sink);
288232
Trace_Printf("z31,%d", sink);
289233
errno_t err;
290234
switch (sink) {
@@ -302,7 +246,7 @@ extern "C" errno_t Hid_SendControlsReport(const hid_controls_report_t *report)
302246
if (err != 0) {
303247
printk("Failed to send controls report to dongle: %d\n", err);
304248
} else {
305-
UsbReportUpdater_ConfirmControlsReportSent();
249+
UsbSemaphore_Release(&UsbSemaphore.controls);
306250
}
307251
break;
308252
#endif
@@ -319,8 +263,8 @@ extern "C" errno_t Hid_SendControlsReport(const hid_controls_report_t *report)
319263

320264
extern "C" void Hid_ControlsReportSentCallback(hid_transport_t transport)
321265
{
322-
UsbReportUpdater_ConfirmControlsReportSent();
323-
noteReportSent( transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
266+
UsbSemaphore_Release(&UsbSemaphore.controls);
267+
UsbScheduler_ReportDelivered( transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
324268
#if DEVICE_IS_UHK_DONGLE
325269
Dongle_SignalUsbReportSent();
326270
#endif

right/src/hid/transport.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,16 @@ typedef enum {
1818
HID_TRANSPORT_BLE,
1919
} hid_transport_t;
2020

21+
// Which physical sink a report is dispatched to. Determined by transport.c's
22+
// determineSink(); shared so the report-sender module can size transport windows per sink.
23+
typedef enum {
24+
ReportSink_Invalid,
25+
ReportSink_Usb,
26+
ReportSink_BleHid,
27+
ReportSink_Dongle,
28+
ReportSink_TestSuite,
29+
} report_sink_t;
30+
2131
typedef enum
2232
{
2333
ROLLOVER_N_KEY = 0,

right/src/hid/transport_usb.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ extern "C" {
66
#include "usb_state.h"
77
#include "timer.h"
88
#include "usb_report_updater.h"
9+
#include "usb_semaphore.h"
910
#include "user_logic.h"
1011
#include "logger.h"
1112
#ifdef __ZEPHYR__
@@ -131,7 +132,7 @@ struct usb_manager {
131132
}
132133
if ((ev & event::CONFIGURATION_CHANGE) != event::NONE) {
133134
// reset the semaphore on USB configuration or reset
134-
UsbReportUpdater_ClearSemaphore(0xFF);
135+
UsbSemaphore_Clear();
135136
}
136137
});
137138
}

right/src/main.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include "peripherals/reset_button.h"
2323
#include "config_parser/config_globals.h"
2424
#include "usb_report_updater.h"
25+
#include "usb_semaphore.h"
2526
#include "macro_events.h"
2627
#include "macros/shortcut_parser.h"
2728
#include "macros/keyid_parser.h"
@@ -86,14 +87,14 @@ static void sendFirstReport()
8687
errno_t ret = -1;
8788
// Wait until sending a report is successful, but don't block longer than 5 seconds.
8889
while (ret && Timer_GetCurrentTime() < 5000) {
89-
UsbReportUpdater_SetSemaphore(UsbReportUpdate_Keyboard);
90+
UsbSemaphore_Set(UsbReportUpdate_Keyboard);
9091
ret = Hid_SendKeyboardReport(&emptyReport);
9192
if (ret) {
92-
UsbReportUpdater_ClearSemaphore(UsbReportUpdate_Keyboard);
93+
UsbSemaphore_Clear();
9394
__WFI();
9495
}
9596
}
96-
while (UsbReportUpdater_GetSemaphore()) {
97+
while (UsbSemaphore_Get()) {
9798
__WFI();
9899
}
99100
}

right/src/usb_commands/usb_command_get_variable.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "key_matrix.h"
44
#include "test_switches.h"
55
#include "usb_report_updater.h"
6+
#include "usb_semaphore.h"
67
#include "macros/core.h"
78
#include "config_manager.h"
89

@@ -29,7 +30,7 @@ void UsbCommand_GetVariable(const uint8_t *GenericHidOutBuffer, uint8_t *Generic
2930
SetUsbTxBufferUint8(1, Cfg.DebounceTimeRelease);
3031
break;
3132
case UsbVariable_UsbReportSemaphore:
32-
SetUsbTxBufferUint8(1, UsbReportUpdater_GetSemaphore());
33+
SetUsbTxBufferUint8(1, UsbSemaphore_Get());
3334
break;
3435
case UsbVariable_StatusBuffer:
3536
for (uint8_t i = 1; i < USB_COMMAND_BUFFER_LENGTH; i++) {

right/src/usb_commands/usb_command_set_variable.c

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "key_matrix.h"
66
#include "test_switches.h"
77
#include "usb_report_updater.h"
8+
#include "usb_semaphore.h"
89
#include "config_manager.h"
910
#include "ledmap.h"
1011

@@ -37,12 +38,10 @@ void UsbCommand_SetVariable(const uint8_t *GenericHidOutBuffer, uint8_t *Generic
3738
case UsbVariable_DebounceTimeRelease:
3839
Cfg.DebounceTimeRelease = GetUsbRxBufferUint8(2);
3940
break;
40-
case UsbVariable_UsbReportSemaphore: {
41-
uint8_t bits = GetUsbRxBufferUint8(2);
42-
UsbReportUpdater_ClearSemaphore((uint8_t)~bits);
43-
UsbReportUpdater_SetSemaphore(bits);
41+
case UsbVariable_UsbReportSemaphore:
42+
// Set overwrites all three in-flight flags from the bitfield.
43+
UsbSemaphore_Set(GetUsbRxBufferUint8(2));
4444
break;
45-
}
4645
case UsbVariable_StatusBuffer:
4746
break;
4847
case UsbVariable_LedAudioRegisters:

0 commit comments

Comments
 (0)