| 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 |