]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/infinity60/matrix.c
Merge remote-tracking branch 'upstream/master'
[qmk_firmware.git] / keyboards / infinity60 / matrix.c
1 #include <stdint.h>
2 #include <stdbool.h>
3 #include <string.h>
4 #include "hal.h"
5 #include "timer.h"
6 #include "wait.h"
7 #include "print.h"
8 #include "matrix.h"
9
10
11 /*
12  * Infinity Pinusage:
13  * Column pins are input with internal pull-down. Row pins are output and strobe with high.
14  * Key is high or 1 when it turns on.
15  *  INFINITY PRODUCTION (NO LED)
16  *     col: { PTD1, PTD2, PTD3, PTD4, PTD5, PTD6, PTD7 }
17  *     row: { PTB0, PTB1, PTB2, PTB3, PTB16, PTB17, PTC4, PTC5, PTD0 }
18  *  INFINITY PRODUCTION (WITH LED)
19  *     col: { PTD1, PTD2, PTD3, PTD4, PTD5, PTD6, PTD7 }
20  *     row: { PTC0, PTC1, PTC2, PTC3, PTC4, PTC5, PTC6, PTC7, PTD0 }
21  */
22 /* matrix state(1:on, 0:off) */
23 static matrix_row_t matrix[MATRIX_ROWS];
24 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
25 static bool debouncing = false;
26 static uint16_t debouncing_time = 0;
27
28
29 void matrix_init(void)
30 {
31     /* Column(sense) */
32     palSetPadMode(GPIOD, 1,  PAL_MODE_INPUT_PULLDOWN);
33     palSetPadMode(GPIOD, 2,  PAL_MODE_INPUT_PULLDOWN);
34     palSetPadMode(GPIOD, 3,  PAL_MODE_INPUT_PULLDOWN);
35     palSetPadMode(GPIOD, 4,  PAL_MODE_INPUT_PULLDOWN);
36     palSetPadMode(GPIOD, 5,  PAL_MODE_INPUT_PULLDOWN);
37     palSetPadMode(GPIOD, 6,  PAL_MODE_INPUT_PULLDOWN);
38     palSetPadMode(GPIOD, 7,  PAL_MODE_INPUT_PULLDOWN);
39
40 #ifdef INFINITY_LED
41     /* Row(strobe) */
42     palSetPadMode(GPIOC, 0,  PAL_MODE_OUTPUT_PUSHPULL);
43     palSetPadMode(GPIOC, 1,  PAL_MODE_OUTPUT_PUSHPULL);
44     palSetPadMode(GPIOC, 2,  PAL_MODE_OUTPUT_PUSHPULL);
45     palSetPadMode(GPIOC, 3,  PAL_MODE_OUTPUT_PUSHPULL);
46     palSetPadMode(GPIOC, 4,  PAL_MODE_OUTPUT_PUSHPULL);
47     palSetPadMode(GPIOC, 5,  PAL_MODE_OUTPUT_PUSHPULL);
48     palSetPadMode(GPIOC, 6,  PAL_MODE_OUTPUT_PUSHPULL);
49     palSetPadMode(GPIOC, 7,  PAL_MODE_OUTPUT_PUSHPULL);
50     palSetPadMode(GPIOD, 0,  PAL_MODE_OUTPUT_PUSHPULL);
51 #else
52     /* Row(strobe) */
53     palSetPadMode(GPIOB, 0,  PAL_MODE_OUTPUT_PUSHPULL);
54     palSetPadMode(GPIOB, 1,  PAL_MODE_OUTPUT_PUSHPULL);
55     palSetPadMode(GPIOB, 2,  PAL_MODE_OUTPUT_PUSHPULL);
56     palSetPadMode(GPIOB, 3,  PAL_MODE_OUTPUT_PUSHPULL);
57     palSetPadMode(GPIOB, 16, PAL_MODE_OUTPUT_PUSHPULL);
58     palSetPadMode(GPIOB, 17, PAL_MODE_OUTPUT_PUSHPULL);
59     palSetPadMode(GPIOC, 4,  PAL_MODE_OUTPUT_PUSHPULL);
60     palSetPadMode(GPIOC, 5,  PAL_MODE_OUTPUT_PUSHPULL);
61     palSetPadMode(GPIOD, 0,  PAL_MODE_OUTPUT_PUSHPULL);
62 #endif
63     memset(matrix, 0, MATRIX_ROWS);
64     memset(matrix_debouncing, 0, MATRIX_ROWS);
65 }
66
67 uint8_t matrix_scan(void)
68 {
69     for (int row = 0; row < MATRIX_ROWS; row++) {
70         matrix_row_t data = 0;
71     #ifdef INFINITY_LED
72         // strobe row
73         switch (row) {
74             case 0: palSetPad(GPIOC, 0);    break;
75             case 1: palSetPad(GPIOC, 1);    break;
76             case 2: palSetPad(GPIOC, 2);    break;
77             case 3: palSetPad(GPIOC, 3);    break;
78             case 4: palSetPad(GPIOC, 4);    break;
79             case 5: palSetPad(GPIOC, 5);    break;
80             case 6: palSetPad(GPIOC, 6);    break;
81             case 7: palSetPad(GPIOC, 7);    break;
82             case 8: palSetPad(GPIOD, 0);    break;
83         }
84     #else
85         // strobe row
86         switch (row) {
87             case 0: palSetPad(GPIOB, 0);    break;
88             case 1: palSetPad(GPIOB, 1);    break;
89             case 2: palSetPad(GPIOB, 2);    break;
90             case 3: palSetPad(GPIOB, 3);    break;
91             case 4: palSetPad(GPIOB, 16);   break;
92             case 5: palSetPad(GPIOB, 17);   break;
93             case 6: palSetPad(GPIOC, 4);    break;
94             case 7: palSetPad(GPIOC, 5);    break;
95             case 8: palSetPad(GPIOD, 0);    break;
96         }
97     #endif
98
99         // need wait to settle pin state
100         // if you wait too short, or have a too high update rate
101         // the keyboard might freeze, or there might not be enough
102         // processing power to update the LCD screen properly.
103         // 20us, or two ticks at 100000Hz seems to be OK
104         wait_us(20);
105
106         // read col data
107         data = (palReadPort(GPIOD)>>1);
108     #ifdef INFINITY_LED
109         // un-strobe row
110         switch (row) {
111             case 0: palClearPad(GPIOC, 0);    break;
112             case 1: palClearPad(GPIOC, 1);    break;
113             case 2: palClearPad(GPIOC, 2);    break;
114             case 3: palClearPad(GPIOC, 3);    break;
115             case 4: palClearPad(GPIOC, 4);    break;
116             case 5: palClearPad(GPIOC, 5);    break;
117             case 6: palClearPad(GPIOC, 6);    break;
118             case 7: palClearPad(GPIOC, 7);    break;
119             case 8: palClearPad(GPIOD, 0);    break;
120         }
121     #else
122         // un-strobe row
123         switch (row) {
124             case 0: palClearPad(GPIOB, 0);    break;
125             case 1: palClearPad(GPIOB, 1);    break;
126             case 2: palClearPad(GPIOB, 2);    break;
127             case 3: palClearPad(GPIOB, 3);    break;
128             case 4: palClearPad(GPIOB, 16);   break;
129             case 5: palClearPad(GPIOB, 17);   break;
130             case 6: palClearPad(GPIOC, 4);    break;
131             case 7: palClearPad(GPIOC, 5);    break;
132             case 8: palClearPad(GPIOD, 0);    break;
133         }
134     #endif
135
136         if (matrix_debouncing[row] != data) {
137             matrix_debouncing[row] = data;
138             debouncing = true;
139             debouncing_time = timer_read();
140         }
141     }
142
143     if (debouncing && timer_elapsed(debouncing_time) > DEBOUNCE) {
144         for (int row = 0; row < MATRIX_ROWS; row++) {
145             matrix[row] = matrix_debouncing[row];
146         }
147         debouncing = false;
148     }
149     return 1;
150 }
151
152 bool matrix_is_on(uint8_t row, uint8_t col)
153 {
154     return (matrix[row] & (1<<col));
155 }
156
157 matrix_row_t matrix_get_row(uint8_t row)
158 {
159     return matrix[row];
160 }
161
162 void matrix_print(void)
163 {
164     xprintf("\nr/c 01234567\n");
165     for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
166         xprintf("%02X: ");
167         matrix_row_t data = matrix_get_row(row);
168         for (int col = 0; col < MATRIX_COLS; col++) {
169             if (data & (1<<col))
170                 xprintf("1");
171             else
172                 xprintf("0");
173         }
174         xprintf("\n");
175     }
176 }