forked from adafruit/circuitpython
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathKeys.c
More file actions
84 lines (67 loc) · 2.91 KB
/
Keys.c
File metadata and controls
84 lines (67 loc) · 2.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
// This file is part of the CircuitPython project: https://circuitpython.org
//
// SPDX-FileCopyrightText: Copyright (c) 2021 Dan Halbert for Adafruit Industries
//
// SPDX-License-Identifier: MIT
#include <string.h>
#include "py/gc.h"
#include "py/runtime.h"
#include "shared-bindings/digitalio/DigitalInOut.h"
#include "shared-bindings/keypad/EventQueue.h"
#include "shared-bindings/keypad/Keys.h"
#include "shared-bindings/keypad/__init__.h"
#include "shared-bindings/supervisor/__init__.h"
#include "supervisor/port.h"
#include "supervisor/shared/tick.h"
static void keypad_keys_scan_now(void *self_in, mp_obj_t timestamp);
static size_t keys_get_key_count(void *self_in);
static keypad_scanner_funcs_t keys_funcs = {
.scan_now = keypad_keys_scan_now,
.get_key_count = keys_get_key_count,
};
void common_hal_keypad_keys_construct(keypad_keys_obj_t *self, mp_uint_t num_pins, const mcu_pin_obj_t *pins[], bool value_when_pressed, bool pull, mp_float_t interval, size_t max_events, uint8_t debounce_threshold) {
mp_obj_t dios[num_pins];
for (size_t i = 0; i < num_pins; i++) {
digitalio_digitalinout_obj_t *dio =
mp_obj_malloc(digitalio_digitalinout_obj_t, &digitalio_digitalinout_type);
common_hal_digitalio_digitalinout_construct(dio, pins[i]);
if (pull) {
common_hal_digitalio_digitalinout_set_pull(dio, value_when_pressed ? PULL_DOWN : PULL_UP);
}
dios[i] = dio;
}
self->digitalinouts = mp_obj_new_tuple(num_pins, dios);
self->value_when_pressed = value_when_pressed;
self->funcs = &keys_funcs;
keypad_construct_common((keypad_scanner_obj_t *)self, interval, max_events, debounce_threshold);
}
void common_hal_keypad_keys_deinit(keypad_keys_obj_t *self) {
if (common_hal_keypad_deinited(self)) {
return;
}
// Remove self from the list of active keypad scanners first.
keypad_deregister_scanner((keypad_scanner_obj_t *)self);
for (size_t key = 0; key < keys_get_key_count(self); key++) {
common_hal_digitalio_digitalinout_deinit(self->digitalinouts->items[key]);
}
self->digitalinouts = MP_ROM_NONE;
common_hal_keypad_deinit_core(self);
}
size_t keys_get_key_count(void *self_in) {
keypad_keys_obj_t *self = self_in;
return self->digitalinouts->len;
}
static void keypad_keys_scan_now(void *self_in, mp_obj_t timestamp) {
keypad_keys_obj_t *self = self_in;
size_t key_count = keys_get_key_count(self);
for (mp_uint_t key_number = 0; key_number < key_count; key_number++) {
// Get the current state.
const bool current =
common_hal_digitalio_digitalinout_get_value(self->digitalinouts->items[key_number]) ==
self->value_when_pressed;
// Record any transitions.
if (keypad_debounce((keypad_scanner_obj_t *)self, key_number, current)) {
keypad_eventqueue_record(self->events, key_number, current, timestamp);
}
}
}