summaryrefslogtreecommitdiff
path: root/keyboards/converter/siemens_tastatur/matrix.c
blob: b7654e6e12f10b383905ad4eb0ea8b9ad02e0e4c (plain)
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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
/*
Copyright 2019 Yiancar

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include "quantum.h"
#include "timer.h"
#include "wait.h"
#include "print.h"
#include "matrix.h"
#include "ch.h"
#include "hal.h"

static matrix_row_t matrix[MATRIX_ROWS];
static matrix_row_t matrix_debouncing[MATRIX_ROWS];

volatile uint16_t porta_buffer = 0;
volatile uint16_t portb_buffer = 0;

static uint32_t switch_buffer = 0;

// Trigger on negative edge of any of the sense lines.
static void extcb1(EXTDriver *extp, expchannel_t channel) {

    (void)extp;
    (void)channel;
    chSysLockFromISR();
    porta_buffer = palReadPort(GPIOA);
    portb_buffer = palReadPort(GPIOB);
    //Disable further interrupts that might occur on same button press.
    extChannelDisable(&EXTD1,0);
    extChannelDisable(&EXTD1,1);
    extChannelDisable(&EXTD1,2);
    extChannelDisable(&EXTD1,9);
    extChannelDisable(&EXTD1,10);
    extChannelDisable(&EXTD1,12);
    extChannelDisable(&EXTD1,13);
    extChannelDisable(&EXTD1,14);
    extChannelDisable(&EXTD1,15);

    extChannelEnable(&EXTD1,0);
    extChannelEnable(&EXTD1,1);
    extChannelEnable(&EXTD1,2);
    extChannelEnable(&EXTD1,9);
    extChannelEnable(&EXTD1,10);
    extChannelEnable(&EXTD1,12);
    extChannelEnable(&EXTD1,13);
    extChannelEnable(&EXTD1,14);
    extChannelEnable(&EXTD1,15);
    chSysUnlockFromISR();
}

static const EXTConfig extcfg = {
    {
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //0
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //1
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //2
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //9
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOA, extcb1 }, //10
        {EXT_CH_MODE_DISABLED, NULL},
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }, //12
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }, //13
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }, //14
        {EXT_CH_MODE_FALLING_EDGE | EXT_CH_MODE_AUTOSTART | EXT_MODE_GPIOB, extcb1 }  //15
    },
};

void matrix_init(void) {
    //Set I/O as pull-up inputs to read states
    setPinInputHigh(A0);
    setPinInputHigh(A1);
    setPinInputHigh(A2);
    setPinInputHigh(A3);
    setPinInputHigh(A4);
    setPinInputHigh(A5);
    setPinInputHigh(A6);
    setPinInputHigh(A7);
    setPinInputHigh(A8);
    setPinInputHigh(A9);
    setPinInputHigh(A10);
    setPinInputHigh(B3);
    setPinInputHigh(B4);
    setPinInputHigh(B5);
    setPinInputHigh(B6);
    setPinInputHigh(B7);
    setPinInputHigh(B8);
    setPinInputHigh(B9);
    setPinInputHigh(B11);
    setPinInputHigh(B12);
    setPinInputHigh(B13);
    setPinInputHigh(B14);
    setPinInputHigh(B15);

    memset(matrix, 0, MATRIX_ROWS * sizeof(matrix_row_t));
    memset(matrix_debouncing, 0, MATRIX_ROWS * sizeof(matrix_row_t));

    matrix_init_quantum();
    //Start interrupt driver
    extStart(&EXTD1, &extcfg);
}

uint8_t matrix_scan(void) {
    switch_buffer = ((uint32_t)(porta_buffer & 0x7FF)) | ((uint32_t)(portb_buffer & 0x3F8) << 8);

    switch (switch_buffer) {
        case 0x1134E: matrix[0] = 0x01; break;
        case 0x3774D: matrix[0] = 0x02; break;
        case 0x10BCC: matrix[0] = 0x04; break;
        case 0x16B4B: matrix[0] = 0x08; break;
        case 0x167CA: matrix[0] = 0x10; break;
        case 0x35FC9: matrix[0] = 0x20; break;
        case 0x15B48: matrix[0] = 0x40; break;
        case 0x28347: matrix[0] = 0x80; break;
        case 0x173C6: matrix[0] = 0x100; break;
        case 0x143CF: matrix[0] = 0x200; break;
        case 0x3FDC5: matrix[0] = 0x400; break;
        case 0x3FD21: matrix[0] = 0x800; break;
        case 0x3FD77: matrix[0] = 0x1000; break;
        case 0x3FD72: matrix[0] = 0x2000; break;
        //Special pin
        case 0x3E7FA: matrix[0] = 0x8000; break;
        case 0x183EE: matrix[0] = 0x10000; break;
        case 0x197F3: matrix[0] = 0x20000; break;
        case 0x1AB7E: matrix[0] = 0x40000; break;

        case 0x107C3: matrix[1] = 0x01; break;
        case 0x3FD2E: matrix[1] = 0x02; break;
        case 0x3FD28: matrix[1] = 0x04; break;
        case 0x3FD3A: matrix[1] = 0x08; break;
        case 0x3FD2D: matrix[1] = 0x10; break;
        case 0x3FD2B: matrix[1] = 0x20; break;
        case 0x3FDA5: matrix[1] = 0x40; break;
        case 0x3FDAA: matrix[1] = 0x80; break;
        case 0x3FD36: matrix[1] = 0x100; break;
        case 0x3FD30: matrix[1] = 0x200; break;
        case 0x3FDAF: matrix[1] = 0x400; break;
        case 0x3FD22: matrix[1] = 0x800; break;
        case 0x157D4: matrix[1] = 0x1000; break;
        //Does not exist in matrix
        //Special pin
        case 0x1C778: matrix[1] = 0x8000; break;
        case 0x387ED: matrix[1] = 0x10000; break;
        case 0x19B74: matrix[1] = 0x20000; break;
        case 0x3FD7D: matrix[1] = 0x40000; break;

        //Special pin
        case 0x3FDBE: matrix[2] = 0x02; break;
        case 0x3FDAC: matrix[2] = 0x04; break;
        case 0x3FDBB: matrix[2] = 0x08; break;
        case 0x3FD39: matrix[2] = 0x10; break;
        case 0x3FDB8: matrix[2] = 0x20; break;
        case 0x3FDB7: matrix[2] = 0x40; break;
        case 0x3FD35: matrix[2] = 0x80; break;
        case 0x3FDB4: matrix[2] = 0x100; break;
        case 0x3FD33: matrix[2] = 0x200; break;
        case 0x3FDA3: matrix[2] = 0x400; break;
        case 0x3FD24: matrix[2] = 0x800; break;
        case 0x0FFDB: matrix[2] = 0x1000; break;
        case 0x3FDF5: matrix[2] = 0x2000; break;
        case 0x3FDFF: matrix[2] = 0x4000; break;
        case 0x3C3E4: matrix[2] = 0x8000; break;
        case 0x38B6C: matrix[2] = 0x10000; break;
        case 0x39FF6: matrix[2] = 0x20000; break;
        case 0x3FDFC: matrix[2] = 0x40000; break;

        //Special pin
        case 0x3FDA6: matrix[3] = 0x02; break;
        case 0x3FD27: matrix[3] = 0x04; break;
        case 0x3FD3C: matrix[3] = 0x08; break;
        case 0x3FDA9: matrix[3] = 0x10; break;
        case 0x3FDBD: matrix[3] = 0x20; break;
        case 0x3FDB1: matrix[3] = 0x40; break;
        case 0x3FDB2: matrix[3] = 0x80; break;
        case 0x30353: matrix[3] = 0x100; break;
        case 0x37BD1: matrix[3] = 0x200; break;
        case 0x363D2: matrix[3] = 0x400; break;
        case 0x3FD5F: matrix[3] = 0x800; break;
        //Does not exist in matrix
        //Does not exist in matrix
        //Special pin
        case 0x1BF00: matrix[3] = 0x8000; break;
        case 0x18FEB: matrix[3] = 0x10000; break;
        case 0x3FF69: matrix[3] = 0x20000; break;
        case 0x3A37B: matrix[3] = 0x40000; break;
        default: 
                 if ((portb_buffer & 0x1000) == 0) { matrix[1] = 0x4000; break; }
                 if ((portb_buffer & 0x2000) == 0) { matrix[3] = 0x4000; break; }
                 if ((portb_buffer & 0x4000) == 0) { matrix[0] = 0x4000; break; }
                 if ((portb_buffer & 0x8000) == 0) { matrix[2] = 0x01; break; }
                 matrix[0] = 0x00;
                 matrix[1] = 0x00;
                 matrix[2] = 0x00;
                 matrix[3] = 0x00;
    }
    //Special case for Shift
    if (readPin(B11) == 0) { matrix[3] |= 0x01; }

    porta_buffer = 65535;
    portb_buffer = 65535;

    matrix_scan_quantum();
    return 1;
}

matrix_row_t matrix_get_row(uint8_t row)
{
    return matrix[row];
}

void matrix_print(void)
{

}

__attribute__ ((weak))
void matrix_init_kb(void) {
    matrix_init_user();
}

__attribute__ ((weak))
void matrix_scan_kb(void) {
    matrix_scan_user();
}

__attribute__ ((weak))
void matrix_init_user(void) {
}

__attribute__ ((weak))
void matrix_scan_user(void) {
}