-
Notifications
You must be signed in to change notification settings - Fork 4
/
KeyMatrix.c
69 lines (56 loc) · 2.32 KB
/
KeyMatrix.c
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
/** \file
*
* Keyboard matrix functions.
*/
#include "KeyMatrix.h"
void KeyMatrix_Init(KeyMatrix_t *KeyMatrix, const __flash KeyMatrixInfo_t *KeyMatrixInfo, uint8_t *KeyMatrixData)
{
uint8_t RowNum = KeyMatrixInfo->RowNum;
uint8_t ColNum = KeyMatrixInfo->ColNum;
KeyMatrix->Info = KeyMatrixInfo;
KeyMatrix->Matrix = KeyMatrixData;
if (!KeyMatrixInfo->ShouldSetDDR) {
return;
}
for (uint8_t Col=0; Col<ColNum; Col++) {
const Pin_t *ColPort = KeyMatrixInfo->ColPorts + Col;
*ColPort->Direction |= 1 << ColPort->Number; // Set DDR bit as output.
}
for (uint8_t Row=0; Row<RowNum; Row++) {
const Pin_t *RowPin = KeyMatrixInfo->RowPins + Row;
*RowPin->Direction &= ~(1 << RowPin->Number); // Set DDR bit as input.
}
}
uint8_t KeyMatrix_GetElement(KeyMatrix_t *KeyMatrix, uint8_t Row, uint8_t Col)
{
return KeyMatrix->Matrix[Col*KeyMatrix->Info->RowNum + Row];
}
void KeyMatrix_SetElement(KeyMatrix_t *KeyMatrix, uint8_t Row, uint8_t Col, uint8_t Element)
{
KeyMatrix->Matrix[Col*KeyMatrix->Info->RowNum + Row] = Element;
}
void KeyMatrix_Scan(KeyMatrix_t *KeyMatrix, uint8_t SetColCallback(uint8_t))
{
for (uint8_t Col=0; Col<KeyMatrix->Info->ColNum; Col++) {
uint8_t ColumnAlreadyEnabled = SetColCallback == NULL ? 0 : SetColCallback(Col);
const Pin_t *ColPort = KeyMatrix->Info->ColPorts + Col;
if (!ColumnAlreadyEnabled) {
// Enable the output port of the column.
*ColPort->Name |= 1<<ColPort->Number;
}
for (uint8_t Row=0; Row<KeyMatrix->Info->RowNum; Row++) {
const Pin_t *RowPin = KeyMatrix->Info->RowPins + Row;
// Read the input pin of the row.
uint8_t KeyState = KeyMatrix_GetElement(KeyMatrix, Row, Col);
uint8_t WasKeyPressed = KEY_STATE_IS_PRESSED(KeyState);
uint8_t IsKeyPressed = *RowPin->Name & 1<<RowPin->Number;
uint8_t IsKeySuppressed = KEY_STATE_IS_SUPPRESSED(KeyState);
uint8_t NewKeyState = CONSTRUCT_KEY_STATE(WasKeyPressed, IsKeyPressed, IsKeySuppressed);
KeyMatrix_SetElement(KeyMatrix, Row, Col, NewKeyState);
}
if (!ColumnAlreadyEnabled) {
// Disable the output port of the column.
*(ColPort->Name) &= ~(1<<ColPort->Number);
}
}
}