5
5
*/
6
6
7
7
#include <stdint.h>
8
+ #include <nrf_error.h>
8
9
#include <nrf_sdh.h>
9
10
#include <nrf_sdh_ble.h>
10
11
#include <nrf_soc.h>
11
- #include <event_scheduler.h>
12
12
#include <ble_adv.h>
13
13
#include <ble_gap.h>
14
14
#include <ble_types.h>
15
- #include <nrf_error.h>
16
15
#include <bluetooth/services/common.h>
17
16
#include <bluetooth/services/ble_dis.h>
18
17
#include <bluetooth/services/ble_hids.h>
18
+ #include <event_scheduler.h>
19
19
#include <zephyr/toolchain.h>
20
20
#include <zephyr/sys/printk.h>
21
21
#include <zephyr/logging/log.h>
22
22
#include <zephyr/logging/log_ctrl.h>
23
23
#include <bm_buttons.h>
24
-
24
+ #include <hal/nrf_gpio.h>
25
25
#include <board-config.h>
26
26
27
27
LOG_MODULE_REGISTER (app , CONFIG_BLE_HIDS_KEYBOARD_SAMPLE_LOG_LEVEL );
28
28
29
29
#define BASE_USB_HID_SPEC_VERSION 0x0101
30
30
31
- #define INPUT_REPORT_KEYS_INDEX 0 /**< Index of Input Report. */
32
- #define INPUT_REPORT_KEYS_MAX_LEN 8 /**< Maximum length of the Input Report characteristic. */
33
- #define INPUT_REP_REF_ID 0 /**< Id of reference to Keyboard Input Report. */
34
-
35
- #define OUTPUT_REPORT_INDEX 0 /**< Index of Output Report. */
36
- #define OUTPUT_REPORT_MAX_LEN 1 /**< Maximum length of the Output Report characteristic. */
37
- #define OUTPUT_REP_REF_ID 0 /**< Id of reference to Keyboard Output Report. */
38
-
39
- #define FEATURE_REPORT_INDEX 0 /**< Index of Feature Report. */
40
- #define FEATURE_REPORT_MAX_LEN 2 /**< Maximum length of the Feature Report characteristic. */
41
- #define FEATURE_REP_REF_ID 0 /**< Id of reference to Keyboard Feature Report. */
31
+ /* Control key codes - required 8 of them */
32
+ #define INPUT_REPORT_KEYS_CTRL_CODE_MIN 224
33
+ /* Control key codes - required 8 of them */
34
+ #define INPUT_REPORT_KEYS_CTRL_CODE_MAX 231
35
+ /* Index of Input Report. */
36
+ #define INPUT_REPORT_KEYS_INDEX 0
37
+ /* Maximum length of the Input Report characteristic. */
38
+ #define INPUT_REPORT_KEYS_MAX_LEN 8
39
+ /* Id of reference to Keyboard Input Report. */
40
+ #define INPUT_REP_REF_ID 0
41
+
42
+ /* Index of Output Report. */
43
+ #define OUTPUT_REPORT_INDEX 0
44
+ /* Maximum length of the Output Report characteristic. */
45
+ #define OUTPUT_REPORT_MAX_LEN 1
46
+ /* Id of reference to Keyboard Output Report. */
47
+ #define OUTPUT_REP_REF_ID 0
48
+ /* Index of Feature Report. */
49
+ #define FEATURE_REPORT_INDEX 0
50
+ /* Maximum length of the Feature Report characteristic. */
51
+ #define FEATURE_REPORT_MAX_LEN 2
52
+ /* Id of reference to Keyboard Feature Report. */
53
+ #define FEATURE_REP_REF_ID 0
54
+ /* CAPS LOCK bit in Output Report (based on 'LED Page (0x08)' of the
55
+ * Universal Serial Bus HID Usage Tables).
56
+ */
57
+ #define OUTPUT_REPORT_BIT_MASK_CAPS_LOCK 0x02
42
58
43
59
#define BTN_PRESSED 1
44
60
@@ -50,6 +66,8 @@ BLE_ADV_DEF(ble_adv);
50
66
/* BLE Connection handle */
51
67
static uint16_t conn_handle = BLE_CONN_HANDLE_INVALID ;
52
68
69
+ static uint8_t keys_report [INPUT_REPORT_KEYS_MAX_LEN ];
70
+
53
71
static void on_ble_evt (const ble_evt_t * evt , void * ctx )
54
72
{
55
73
uint32_t nrf_err ;
@@ -260,44 +278,105 @@ static uint32_t hids_init(void)
260
278
return ble_hids_init (& ble_hids , & hids_config );
261
279
}
262
280
263
- static int register_key ( struct ble_hids * hids , const char key , bool pressed )
281
+ static uint8_t button_ctrl_code_get ( uint8_t key )
264
282
{
265
- uint32_t nrf_err ;
266
- uint8_t report [INPUT_REPORT_KEYS_MAX_LEN ] = {};
283
+ if (INPUT_REPORT_KEYS_CTRL_CODE_MIN <= key && key <= INPUT_REPORT_KEYS_CTRL_CODE_MAX ) {
284
+ return (uint8_t )(1U << (key - INPUT_REPORT_KEYS_CTRL_CODE_MIN ));
285
+ }
286
+ return 0 ;
287
+ }
288
+
289
+
290
+ static int key_set (struct ble_hids * hids , uint8_t * report , size_t report_size , uint8_t key )
291
+ {
292
+ uint8_t ctrl_mask = button_ctrl_code_get (key );
293
+
294
+ if (ctrl_mask ) {
295
+ report [0 ] |= ctrl_mask ;
296
+ return 0 ;
297
+ }
298
+ for (size_t i = 0 ; i < (report_size - 2 ); ++ i ) {
299
+ if (report [i + 2 ] == 0 ) {
300
+ report [i + 2 ] = key ;
301
+ return 0 ;
302
+ }
303
+ }
304
+ /* All slots busy */
305
+ return - EBUSY ;
306
+ }
307
+
308
+
309
+ static int key_clear (struct ble_hids * hids , uint8_t * report , size_t report_size , uint8_t key )
310
+ {
311
+ uint8_t ctrl_mask = button_ctrl_code_get (key );
267
312
268
- #define DATA_OFFSET 2
313
+ if (ctrl_mask ) {
314
+ report [0 ] &= ~ctrl_mask ;
315
+ return 0 ;
316
+ }
317
+ for (size_t i = 0 ; i < (report_size - 2 ); ++ i ) {
318
+ if (report [i + 2 ] == key ) {
319
+ report [i + 2 ] = 0 ;
320
+ return 0 ;
321
+ }
322
+ }
323
+
324
+ /* Key not found */
325
+ return - EINVAL ;
326
+ }
327
+
328
+ static int on_key_press (struct ble_hids * hids , const char key , bool pressed )
329
+ {
330
+ uint32_t nrf_err ;
269
331
270
332
if (pressed ) {
271
- memcpy (report + DATA_OFFSET , & key , sizeof (key ));
333
+ key_set (hids , keys_report , sizeof (keys_report ), key );
334
+ } else {
335
+ key_clear (hids , keys_report , sizeof (keys_report ), key );
272
336
}
273
337
274
- nrf_err = ble_hids_inp_rep_send (hids , conn_handle , INPUT_REPORT_KEYS_INDEX , & report ,
275
- sizeof (report ));
276
- if (nrf_err ) {
277
- printk ("Failed to send input report, nrf_error %#x" , nrf_err );
338
+ nrf_err = ble_hids_inp_rep_send (hids , conn_handle , INPUT_REPORT_KEYS_INDEX , keys_report ,
339
+ sizeof (keys_report ));
340
+ if (nrf_err != NRF_SUCCESS ) {
341
+ LOG_ERR ("Failed to send input report, nrf_error %#x" , nrf_err );
278
342
}
279
343
280
344
return 0 ;
281
345
}
282
346
283
347
static void button_handler (uint8_t pin , uint8_t action )
284
348
{
349
+ static const char hello_world_str [] = {
350
+ 0x0b , /* Key h */
351
+ 0x08 , /* Key e */
352
+ 0x0f , /* Key l */
353
+ 0x0f , /* Key l */
354
+ 0x12 , /* Key o */
355
+ 0x28 , /* Key Return */
356
+ };
357
+ static const char * chr = hello_world_str ;
358
+
285
359
if (conn_handle == BLE_CONN_HANDLE_INVALID ) {
286
360
return ;
287
361
}
288
362
289
363
switch (pin ) {
290
364
case BOARD_PIN_BTN_0 :
291
- register_key (& ble_hids , 0x04 , action == BTN_PRESSED ); /* Key a */
365
+ if (action == BTN_PRESSED ) {
366
+ on_key_press (& ble_hids , * chr , true);
367
+ } else {
368
+ on_key_press (& ble_hids , * chr , false);
369
+ if (++ chr == (hello_world_str + sizeof (hello_world_str ))) {
370
+ chr = hello_world_str ;
371
+ }
372
+ }
292
373
break ;
293
374
case BOARD_PIN_BTN_1 :
294
- register_key (& ble_hids , 0x05 , action == BTN_PRESSED ); /* Key b */
375
+ on_key_press (& ble_hids , 0xE1 , action == BTN_PRESSED ); /* Shift */
295
376
break ;
296
377
case BOARD_PIN_BTN_2 :
297
- register_key (& ble_hids , 0x06 , action == BTN_PRESSED ); /* Key c */
298
- break ;
299
378
case BOARD_PIN_BTN_3 :
300
- register_key ( & ble_hids , 0x07 , action == BTN_PRESSED ); /* Key d */
379
+ /* Reserved for pairing */
301
380
break ;
302
381
}
303
382
}
@@ -343,6 +422,8 @@ int main(void)
343
422
},
344
423
};
345
424
425
+ nrf_gpio_cfg_output (BOARD_PIN_LED_0 );
426
+
346
427
err = bm_buttons_init (configs , ARRAY_SIZE (configs ), BM_BUTTONS_DETECTION_DELAY_MIN_US );
347
428
if (err ) {
348
429
printk ("Failed to initialize buttons, err %d\n" , err );
0 commit comments