Skip to content

Commit 00611c1

Browse files
committed
Safer HID API
1 parent 8b6ac51 commit 00611c1

File tree

1 file changed

+64
-20
lines changed

1 file changed

+64
-20
lines changed

OS/HID/Keyboard.cpp

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "MatrixOS.h"
22
#include "USB.h"
33
#include "tusb.h"
4+
#include "task.h"
45

56
#define NKRO_KEY_COUNT (8*13)
67

@@ -20,6 +21,13 @@ typedef union __attribute__((packed, aligned(1))) {
2021
namespace MatrixOS::HID::Keyboard
2122
{
2223
HID_KeyboardReport_Data_t _keyReport;
24+
static TaskHandle_t _sendTaskHandle = nullptr;
25+
static StaticTask_t _sendTaskBuffer;
26+
static StackType_t _sendTaskStack[configMINIMAL_STACK_SIZE];
27+
static uint64_t _lastSendMicros = 0;
28+
29+
static void SendTask(void* param);
30+
static void EnsureSendTask();
2331

2432
// Internal API
2533
bool Set(KeyboardKeycode k, bool s)
@@ -85,20 +93,56 @@ namespace MatrixOS::HID::Keyboard
8593
return false;
8694
}
8795

88-
void Send()
96+
static void SendTask(void* param)
8997
{
90-
if(!HID::Ready()) {
91-
return;
98+
(void)param;
99+
100+
while(true)
101+
{
102+
ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
103+
104+
if(!HID::Ready())
105+
{
106+
continue;
107+
}
108+
109+
if (tud_suspended())
110+
{
111+
// Wake up host if we are in suspend mode
112+
// and REMOTE_WAKEUP feature is enabled by host
113+
tud_remote_wakeup();
114+
}
115+
116+
uint64_t nowMicros = MatrixOS::SYS::Micros();
117+
if(_lastSendMicros != 0)
118+
{
119+
uint64_t elapsed = nowMicros - _lastSendMicros;
120+
if(elapsed < 1000) // keep at least 1ms gap
121+
{
122+
MatrixOS::SYS::DelayMs(1);
123+
}
124+
}
125+
126+
tud_hid_n_report(0, REPORT_ID_KEYBOARD, &_keyReport, sizeof(_keyReport));
127+
_lastSendMicros = MatrixOS::SYS::Micros();
92128
}
129+
}
93130

94-
if (tud_suspended())
131+
static void EnsureSendTask()
132+
{
133+
if(_sendTaskHandle == nullptr)
95134
{
96-
// Wake up host if we are in suspend mode
97-
// and REMOTE_WAKEUP feature is enabled by host
98-
tud_remote_wakeup();
135+
_sendTaskHandle = xTaskCreateStatic(SendTask, "kbd_send", configMINIMAL_STACK_SIZE, nullptr, 2, _sendTaskStack, &_sendTaskBuffer);
136+
}
137+
}
138+
139+
void Send()
140+
{
141+
EnsureSendTask();
142+
if(_sendTaskHandle != nullptr)
143+
{
144+
xTaskNotifyGive(_sendTaskHandle);
99145
}
100-
101-
tud_hid_n_report(0, REPORT_ID_KEYBOARD, &_keyReport, sizeof(_keyReport));
102146
}
103147

104148
// User API
@@ -115,25 +159,25 @@ namespace MatrixOS::HID::Keyboard
115159

116160
bool Press(KeyboardKeycode k)
117161
{
118-
bool ret = Set(k, true);
119-
if(ret){
120-
Send();
121-
}
122-
return ret;
162+
bool ret = Set(k, true);
163+
if(ret){
164+
Send();
165+
}
166+
return ret;
123167
}
124168

125169
bool Release(KeyboardKeycode k)
126170
{
127-
bool ret = Set(k, false);
128-
if(ret){
129-
Send();
130-
}
131-
return ret;
171+
bool ret = Set(k, false);
172+
if(ret){
173+
Send();
174+
}
175+
return ret;
132176
}
133177

134178
void ReleaseAll(void)
135179
{
136180
memset(&_keyReport, 0, sizeof(_keyReport));
137181
Send();
138182
}
139-
}
183+
}

0 commit comments

Comments
 (0)