Skip to content

Commit 79e1af7

Browse files
Add Keyboard LED callback for USB and BT (not BLE) (#1265)
BLE seems to require some kind of characteristic callback that is not yeet implemented here. USB and BT tested and examples updated.
1 parent 173c444 commit 79e1af7

File tree

7 files changed

+51
-1
lines changed

7 files changed

+51
-1
lines changed

cores/rp2040/RP2040USB.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@ void __USBStart() {
383383
// Invoked when received GET_REPORT control request
384384
// Application must fill buffer report's content and return its length.
385385
// Return zero will cause the stack to STALL request
386+
extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) __attribute__((weak));
386387
extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t* buffer, uint16_t reqlen) {
387388
// TODO not implemented
388389
(void) instance;
@@ -396,6 +397,7 @@ extern "C" uint16_t tud_hid_get_report_cb(uint8_t instance, uint8_t report_id, h
396397

397398
// Invoked when received SET_REPORT control request or
398399
// received data on OUT endpoint ( Report ID = 0, Type = 0 )
400+
extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) __attribute__((weak));
399401
extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
400402
// TODO set LED based on CAPLOCK, NUMLOCK etc...
401403
(void) instance;

libraries/Keyboard/examples/KeyboardPassword/KeyboardPassword.ino

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,20 @@
33

44
#include <Keyboard.h>
55

6+
void ledCB(bool numlock, bool capslock, bool scrolllock, bool compose, bool kana, void *cbData) {
7+
(void) numlock;
8+
(void) scrolllock;
9+
(void) compose;
10+
(void) kana;
11+
(void) cbData;
12+
digitalWrite(LED_BUILTIN, capslock ? HIGH : LOW);
13+
}
14+
615
void setup() {
716
Serial.begin(115200);
17+
pinMode(LED_BUILTIN, OUTPUT);
18+
digitalWrite(LED_BUILTIN, LOW);
19+
Keyboard.onLED(ledCB);
820
Keyboard.begin();
921
delay(5000);
1022
Serial.printf("Arduino USB Password Typer\n");

libraries/Keyboard/src/Keyboard.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,14 @@ void Keyboard_::sendReport(KeyReport* keys) {
4646
tud_task();
4747
}
4848

49+
extern "C" void tud_hid_set_report_cb(uint8_t instance, uint8_t report_id, hid_report_type_t report_type, uint8_t const* buffer, uint16_t bufsize) {
50+
(void) report_id;
51+
(void) instance;
52+
53+
if ((report_type == HID_REPORT_TYPE_OUTPUT) && (bufsize > 0) && (Keyboard._ledCB)) {
54+
uint8_t const kbd_leds = buffer[0];
55+
Keyboard._ledCB(kbd_leds & KEYBOARD_LED_NUMLOCK, kbd_leds & KEYBOARD_LED_CAPSLOCK, kbd_leds & KEYBOARD_LED_SCROLLLOCK, kbd_leds & KEYBOARD_LED_COMPOSE, kbd_leds & KEYBOARD_LED_KANA, Keyboard._ledCBdata);
56+
}
57+
}
58+
4959
Keyboard_ Keyboard;

libraries/Keyboard/src/Keyboard.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
class Keyboard_ : public HID_Keyboard {
2929
protected:
3030
virtual void sendReport(KeyReport* keys) override;
31+
3132
public:
3233
Keyboard_(void);
3334
};

libraries/KeyboardBT/examples/BTKeyboardPassword/BTKeyboardPassword.ino

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,22 @@
33

44
#include <KeyboardBT.h>
55

6+
void ledCB(bool numlock, bool capslock, bool scrolllock, bool compose, bool kana, void *cbData) {
7+
(void) numlock;
8+
(void) scrolllock;
9+
(void) compose;
10+
(void) kana;
11+
(void) cbData;
12+
digitalWrite(LED_BUILTIN, capslock ? HIGH : LOW);
13+
}
14+
615
void setup() {
716
Serial.begin(115200);
817
KeyboardBT.begin("PicoW Password");
18+
pinMode(LED_BUILTIN, OUTPUT);
19+
digitalWrite(LED_BUILTIN, LOW);
20+
KeyboardBT.onLED(ledCB);
21+
KeyboardBT.begin();
922
delay(5000);
1023
Serial.printf("Arduino USB Password Typer\n");
1124
Serial.printf("Press BOOTSEL to enter your super-secure(not!) password\n\n");

libraries/KeyboardBT/src/KeyboardBT.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ KeyboardBT_::KeyboardBT_(void) {
3636

3737
static const uint8_t desc_keyboard[] = {TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(REPORT_ID))};
3838

39+
static void _hidReportCB(uint16_t cid, hid_report_type_t report_type, uint16_t report_id, int report_size, uint8_t *report) {
40+
(void) cid;
41+
(void) report_id;
42+
if ((report_type == HID_REPORT_TYPE_OUTPUT) && (report_size > 0) && (KeyboardBT._ledCB)) {
43+
uint8_t const kbd_leds = report[0];
44+
KeyboardBT._ledCB(kbd_leds & KEYBOARD_LED_NUMLOCK, kbd_leds & KEYBOARD_LED_CAPSLOCK, kbd_leds & KEYBOARD_LED_SCROLLLOCK, kbd_leds & KEYBOARD_LED_COMPOSE, kbd_leds & KEYBOARD_LED_KANA, KeyboardBT._ledCBdata);
45+
}
46+
}
47+
3948
void KeyboardBT_::begin(const char *localName, const char *hidName, const uint8_t *layout) {
4049
if (!localName) {
4150
localName = "PicoW BT Keyboard";
@@ -44,6 +53,9 @@ void KeyboardBT_::begin(const char *localName, const char *hidName, const uint8_
4453
hidName = localName;
4554
}
4655
_asciimap = layout;
56+
// Required because the hid_report_type_t overlap in BTStack and TUSB
57+
auto *fcn = (void (*)(short unsigned int, hid_report_type_t_bt, short unsigned int, int, unsigned char*))_hidReportCB;
58+
hid_device_register_report_data_callback(fcn);
4759
PicoBluetoothHID.startHID(localName, hidName, 0x2540, 33, desc_keyboard, sizeof(desc_keyboard));
4860
}
4961

0 commit comments

Comments
 (0)