GCC Code Coverage Report


Directory: main/
File: adapter/kb_monitor.c
Date: 2025-10-04 14:03:00
Exec Total Coverage
Lines: 0 60 0.0%
Functions: 0 6 0.0%
Branches: 0 24 0.0%

Line Branch Exec Source
1 /*
2 * Copyright (c) 2019-2020, Jacques Gagnon
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #include <stdio.h>
7 #include <string.h>
8 #include <esp_timer.h>
9 #include "queue_bss.h"
10 #include "zephyr/types.h"
11 #include "tools/util.h"
12 #include "kb_monitor.h"
13
14 struct kb_monitor {
15 uint32_t dev_id;
16 kbmon_id_to_code_t callback;
17 queue_bss_handle_t scq_hdl;
18 uint32_t keys_state[4];
19 uint32_t tm_delay;
20 uint32_t tm_rate;
21 esp_timer_handle_t tm_timer_hdl;
22 uint8_t tm_key_id;
23 uint8_t tm_state;
24 };
25
26 static struct kb_monitor kb_monitors[BT_MAX_DEV] = {0};
27
28 static void kbmon_typematic_cb(void *arg) {
29 struct kb_monitor *kbmon = (struct kb_monitor *)arg;
30
31 kbmon->callback(kbmon->dev_id, KBMON_TYPE_MAKE, kbmon->tm_key_id);
32 esp_timer_start_once(kbmon->tm_timer_hdl, kbmon->tm_rate);
33 }
34
35 void kbmon_init(uint32_t dev_id, kbmon_id_to_code_t callback) {
36 if (dev_id < BT_MAX_DEV) {
37 esp_timer_create_args_t tm_timer_args = {
38 .callback = &kbmon_typematic_cb,
39 .arg = (void *)&kb_monitors[dev_id],
40 .name = "kbmon_typematic_cb"
41 };
42 esp_timer_create(&tm_timer_args, &kb_monitors[dev_id].tm_timer_hdl);
43 kb_monitors[dev_id].tm_state = 0;
44 kb_monitors[dev_id].dev_id = dev_id;
45 kb_monitors[dev_id].callback = callback;
46 kb_monitors[dev_id].scq_hdl = queue_bss_init(32, 16);
47 if (kb_monitors[dev_id].scq_hdl == NULL) {
48 printf("# Failed to create KBMON:%ld ring buffer\n", dev_id);
49 }
50 }
51 }
52
53 void kbmon_update(uint32_t dev_id, struct wired_ctrl *ctrl_data) {
54 struct kb_monitor *kbmon = &kb_monitors[dev_id];
55 uint32_t keys_change[4];
56
57 for (uint32_t i = 0; i < 4; i++) {
58 keys_change[i] = ctrl_data->btns[i].value ^ kbmon->keys_state[i];
59 kbmon->keys_state[i] = ctrl_data->btns[i].value;
60 }
61
62 for (uint32_t i = 0; i < KBM_MAX; i++) {
63 if (ctrl_data->map_mask[i / 32] & BIT(i & 0x1F)) {
64 if (keys_change[i / 32] & BIT(i & 0x1F)) {
65 esp_timer_stop(kbmon->tm_timer_hdl);
66 if (ctrl_data->btns[i / 32].value & BIT(i & 0x1F)) {
67 kbmon->callback(dev_id, KBMON_TYPE_MAKE, i);
68 if (kbmon->tm_state) {
69 kbmon->tm_key_id = i;
70 esp_timer_start_once(kbmon->tm_timer_hdl, kbmon->tm_delay);
71 }
72 }
73 else {
74 kb_monitors[dev_id].callback(dev_id, KBMON_TYPE_BREAK, i);
75 }
76 }
77 }
78 }
79 }
80
81 int32_t kbmon_set_code(uint32_t dev_id, uint8_t *code, uint32_t len) {
82 struct kb_monitor *kbmon = &kb_monitors[dev_id];
83 int32_t ret = -1;
84
85 if (kbmon->scq_hdl) {
86 ret = queue_bss_enqueue(kbmon->scq_hdl, code, len);
87 if (ret) {
88 printf("# %s KBMON:%ld scq full!\n", __FUNCTION__, dev_id);
89 }
90 }
91 return ret;
92 }
93
94 int32_t IRAM_ATTR kbmon_get_code(uint32_t dev_id, uint8_t *code, uint32_t *len) {
95 struct kb_monitor *kbmon = &kb_monitors[dev_id];
96 int32_t ret = -1;
97 uint32_t *qlen;
98 if (kbmon->scq_hdl) {
99 uint8_t *qcode = queue_bss_dequeue(kbmon->scq_hdl, &qlen);
100 if (qcode) {
101 memcpy(code, qcode, *qlen);
102 queue_bss_return(kbmon->scq_hdl, qcode, qlen);
103 *len = *qlen;
104 ret = 0;
105 }
106 }
107 return ret;
108 }
109
110 void kbmon_set_typematic(uint32_t dev_id, uint8_t state, uint32_t delay, uint32_t rate) {
111 struct kb_monitor *kbmon = &kb_monitors[dev_id];
112
113 kbmon->tm_state = state;
114 kbmon->tm_delay = delay;
115 kbmon->tm_rate = rate;
116 }
117
118