@@ -16,9 +16,13 @@ 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"
24+ #include " utils.h"
25+ #include " test_suite/test_hooks.h"
2226}
2327#include " command_app.hpp"
2428#include " controls_app.hpp"
@@ -30,87 +34,37 @@ extern "C" {
3034 #error "Either CONFIG_DEBUG or NDEBUG must be defined"
3135#endif
3236
33- typedef enum {
34- ReportSink_Invalid,
35- ReportSink_Usb,
36- ReportSink_BleHid,
37- ReportSink_Dongle,
38- } 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.
3942
4043// Exponential moving average (alpha=1/8) of the measured delay between a
4144// BLE HID report being handed to the stack and the corresponding sent callback
42- // firing. Populated when DEBUG_BLE_LATENCY_STATS is enabled; useful for
43- // 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.
4447extern " C" {
4548float HidReportBleLatencyAvgMs = 0 ;
4649}
47- static uint32_t dispatchTimeMs = 0 ;
4850
49- // Approximate transport window intervals (ms) used by the report-construction
50- // throttle. After dispatch we estimate the next free window at "now + 2 *
51- // interval" (worst case: we just missed a window). The send-completion
52- // callback then reduces the estimate to "now + interval".
53- static constexpr uint32_t USB_REPORT_INTERVAL_MS = 1 ;
54-
55- static uint32_t reportIntervalForSink (report_sink_t sink)
56- {
57- switch (sink) {
58- case ReportSink_Usb:
59- return USB_REPORT_INTERVAL_MS ;
60- case ReportSink_BleHid:
61- case ReportSink_Dongle:
62- #if DEVICE_IS_UHK80_RIGHT
63- return BtConn_GetReportIntervalMs (ActiveHostConnectionId);
64- #else
65- return 11 ;
66- #endif
67- default :
68- return 0 ;
69- }
70- }
71-
72- static void noteReportDispatched (report_sink_t sink)
73- {
74- if (DEBUG_BLE_LATENCY_STATS ) {
75- if (dispatchTimeMs == 0 ) {
76- dispatchTimeMs = Timer_GetCurrentTime ();
77- }
78- }
79- UsbReportWindowEstimate = UsbReportWindowEstimateLast + 2 * reportIntervalForSink (sink);
80- }
81-
82- static void noteReportSent (report_sink_t transport)
83- {
84- if (DEBUG_BLE_LATENCY_STATS ) {
85- if (dispatchTimeMs != 0 ) {
86- uint32_t delta = Timer_GetCurrentTime () - dispatchTimeMs;
87- HidReportBleLatencyAvgMs = (HidReportBleLatencyAvgMs * 7 + delta) / 8 ;
88- dispatchTimeMs = 0 ;
89- }
90- }
91- uint32_t reportInterval = reportIntervalForSink (transport);
92- uint32_t currentTime = Timer_GetCurrentTime ();
93- int16_t jitterGuess = (currentTime - UsbReportWindowEstimateLast - reportInterval + 1 ) / 2 ;
94- jitterGuess = MAX (0 , jitterGuess);
95- UsbReportWindowEstimateLast = currentTime - jitterGuess;
96- UsbReportWindowEstimate = currentTime - jitterGuess + reportInterval;
97- uint32_t nextIn = UsbReportWindowEstimate - USB_REPORT_WINDOW_LOOKAHEAD_MS ;
98-
99- if (DEVICE_IS_UHK80_RIGHT ) {
100- EventScheduler_Schedule (nextIn, EventSchedulerEvent_Postponer, " Report sent. Recalculate report throttles" );
101- }
102- }
51+ bool UnreliableTransportTestMode = false ;
10352
10453extern " C" void HidTransport_NoteNusReportSent (void )
10554{
106- noteReportSent (ReportSink_Dongle);
55+ UsbScheduler_ReportDelivered (ReportSink_Dongle);
10756}
10857
10958static report_sink_t determineSink ()
11059{
60+ if (TestHooks_Active) {
61+ return ReportSink_TestSuite;
62+ }
63+
11164#if DEVICE_IS_UHK_DONGLE || DEVICE_IS_UHK60
11265 return ReportSink_Usb;
11366#else
67+
11468 connection_type_t connectionType = Connections_Type (ActiveHostConnectionId);
11569
11670 if (!Connections_IsReady (ActiveHostConnectionId)) {
@@ -170,9 +124,12 @@ extern "C" void Hid_TransportStateChanged(
170124extern " C" errno_t Hid_SendKeyboardReport (const hid_keyboard_report_t *report)
171125{
172126 report_sink_t sink = determineSink ();
173- noteReportDispatched (sink);
127+ UsbScheduler_ReportAcceptedByTransport (sink);
174128 Trace_Printf (" z11,%d" , sink);
175129 errno_t err;
130+ if (UnreliableTransportTestMode && Utils_Random () % 7 == 0 ) {
131+ return -EAGAIN ;
132+ }
176133 switch (sink) {
177134 case ReportSink_Usb:
178135 err = keyboard_app::usb_handle ().send_report (*report);
@@ -187,9 +144,16 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
187144 err = Messenger_Send2 (DeviceId_Uhk_Dongle, MessageId_SyncableProperty, SyncablePropertyId_KeyboardReport, (const uint8_t *)report, sizeof (*report));
188145 if (err != 0 ) {
189146 printk (" Failed to send keyboard report to dongle: %d\n " , err);
147+ } else {
148+ UsbSemaphore_Release (&UsbSemaphore.keyboard );
190149 }
191150 break ;
192151#endif
152+ case ReportSink_TestSuite:
153+ err = 0 ;
154+ TestHooks_CaptureReport (report);
155+ Hid_KeyboardReportSentCallback (HID_TRANSPORT_USB );
156+ break ;
193157 default :
194158#ifdef __ZEPHYR__
195159 printk (" Unhandled and unexpected switch state!\n " );
@@ -203,8 +167,11 @@ extern "C" errno_t Hid_SendKeyboardReport(const hid_keyboard_report_t *report)
203167
204168extern " C" void Hid_KeyboardReportSentCallback (hid_transport_t transport)
205169{
206- UsbReportUpdateSemaphore &= ~UsbReportUpdate_Keyboard;
207- noteReportSent (transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
170+ if (UnreliableTransportTestMode && Utils_Random () % 7 == 0 ) {
171+ return ;
172+ }
173+ UsbSemaphore_Release (&UsbSemaphore.keyboard );
174+ UsbScheduler_ReportDelivered (transport == HID_TRANSPORT_USB ? ReportSink_Usb : ReportSink_BleHid);
208175#if DEVICE_IS_UHK_DONGLE
209176 Dongle_SignalUsbReportSent ();
210177#endif
@@ -213,7 +180,7 @@ extern "C" void Hid_KeyboardReportSentCallback(hid_transport_t transport)
213180extern " C" errno_t Hid_SendMouseReport (const hid_mouse_report_t *report)
214181{
215182 report_sink_t sink = determineSink ();
216- noteReportDispatched (sink);
183+ UsbScheduler_ReportAcceptedByTransport (sink);
217184 Trace_Printf (" z21,%d" , sink);
218185 errno_t err;
219186 switch (sink) {
@@ -230,6 +197,8 @@ extern "C" errno_t Hid_SendMouseReport(const hid_mouse_report_t *report)
230197 err = Messenger_Send2 (DeviceId_Uhk_Dongle, MessageId_SyncableProperty, SyncablePropertyId_MouseReport, (const uint8_t *)report, sizeof (*report));
231198 if (err != 0 ) {
232199 printk (" Failed to send mouse report to dongle: %d\n " , err);
200+ } else {
201+ UsbSemaphore_Release (&UsbSemaphore.mouse );
233202 }
234203 break ;
235204#endif
@@ -249,8 +218,8 @@ extern "C" errno_t Hid_SendMouseReport(const hid_mouse_report_t *report)
249218
250219extern " C" void Hid_MouseReportSentCallback (hid_transport_t transport)
251220{
252- UsbReportUpdateSemaphore &= ~UsbReportUpdate_Mouse ;
253- 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);
254223#if DEVICE_IS_UHK_DONGLE
255224 Dongle_SignalUsbReportSent ();
256225#endif
@@ -259,7 +228,7 @@ extern "C" void Hid_MouseReportSentCallback(hid_transport_t transport)
259228extern " C" errno_t Hid_SendControlsReport (const hid_controls_report_t *report)
260229{
261230 report_sink_t sink = determineSink ();
262- noteReportDispatched (sink);
231+ UsbScheduler_ReportAcceptedByTransport (sink);
263232 Trace_Printf (" z31,%d" , sink);
264233 errno_t err;
265234 switch (sink) {
@@ -276,6 +245,8 @@ extern "C" errno_t Hid_SendControlsReport(const hid_controls_report_t *report)
276245 err = Messenger_Send2 (DeviceId_Uhk_Dongle, MessageId_SyncableProperty, SyncablePropertyId_ControlsReport, (const uint8_t *)report, sizeof (*report));
277246 if (err != 0 ) {
278247 printk (" Failed to send controls report to dongle: %d\n " , err);
248+ } else {
249+ UsbSemaphore_Release (&UsbSemaphore.controls );
279250 }
280251 break ;
281252#endif
@@ -292,8 +263,8 @@ extern "C" errno_t Hid_SendControlsReport(const hid_controls_report_t *report)
292263
293264extern " C" void Hid_ControlsReportSentCallback (hid_transport_t transport)
294265{
295- UsbReportUpdateSemaphore &= ~UsbReportUpdate_Controls ;
296- 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);
297268#if DEVICE_IS_UHK_DONGLE
298269 Dongle_SignalUsbReportSent ();
299270#endif
0 commit comments