]> git.donarmstrong.com Git - qmk_firmware.git/blob - keyboards/handwired/bluepill/bluepill70/matrix.c
Add Bluepill (stm32f103) handwired keyboard (#4126)
[qmk_firmware.git] / keyboards / handwired / bluepill / bluepill70 / matrix.c
1 /*
2 Copyright 2012 Jun Wako <wakojun@gmail.com>
3
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17
18 #include "ch.h"
19 #include "hal.h"
20
21 /*
22  * scan matrix
23  */
24 #include "print.h"
25 #include "debug.h"
26 #include "util.h"
27 #include "matrix.h"
28 #include "wait.h"
29
30 //#include "pwm.c"
31
32 #ifndef DEBOUNCE
33 #   define DEBOUNCE 5
34 #endif
35 static uint8_t debouncing = DEBOUNCE;
36
37 /* matrix state(1:on, 0:off) */
38 static matrix_row_t matrix[MATRIX_ROWS];
39 static matrix_row_t matrix_debouncing[MATRIX_ROWS];
40
41 static matrix_row_t read_cols(void);
42 static void init_cols(void);
43 static void unselect_rows(void);
44 static void select_row(uint8_t row);
45
46 inline uint8_t matrix_rows(void){
47   return MATRIX_ROWS;
48 }
49
50 inline uint8_t matrix_cols(void){
51   return MATRIX_COLS;
52 }
53
54 /* generic STM32F103C8T6 board */
55 #ifdef BOARD_GENERIC_STM32_F103
56 // This could be removed, only used now in matrix_init()
57 #define LED_ON()    do { palClearPad(GPIOA, 1) ;} while (0)
58 #define LED_OFF()   do { palSetPad(GPIOA, 1); } while (0)
59 #endif
60
61 __attribute__ ((weak))
62 void matrix_init_kb(void) {
63     matrix_init_user();
64 }
65
66 __attribute__ ((weak))
67 void matrix_scan_kb(void) {
68     matrix_scan_user();
69 }
70
71 __attribute__ ((weak))
72 void matrix_init_user(void) {
73 }
74
75 __attribute__ ((weak))
76 void matrix_scan_user(void) {
77 }
78
79 void matrix_init(void)
80 {
81   // initialize row and col
82   unselect_rows();
83   init_cols();
84   // initialize matrix state: all keys off
85   for (uint8_t i=0; i < MATRIX_ROWS; i++) {
86     matrix[i] = 0;
87     matrix_debouncing[i] = 0;
88   }
89   //debug
90   debug_matrix = true;
91   LED_ON();
92   wait_ms(500);
93   LED_OFF();
94
95   matrix_init_quantum();
96 }
97
98 uint8_t matrix_scan(void){
99   for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
100     select_row(i);
101     wait_us(30);  // without this wait read unstable value.
102     matrix_row_t cols = read_cols();
103     if (matrix_debouncing[i] != cols) {
104       matrix_debouncing[i] = cols;
105       if (debouncing) {
106         debug("bounce!: "); debug_hex(debouncing); debug("\n");
107       }
108     debouncing = DEBOUNCE;
109     }
110     unselect_rows();
111   }
112
113   if (debouncing) {
114     if (--debouncing) {
115       wait_ms(1);
116     } else {
117       for (uint8_t i = 0; i < MATRIX_ROWS; i++) {
118         matrix[i] = matrix_debouncing[i];
119       }
120     }
121   }
122   matrix_scan_quantum();
123   return 1;
124 }
125
126 inline bool matrix_is_on(uint8_t row, uint8_t col){
127   return (matrix[row] & ((matrix_row_t)1<<col));
128 }
129
130 inline matrix_row_t matrix_get_row(uint8_t row){
131   return matrix[row];
132 }
133
134 void matrix_print(void){
135   print("\nr/c 0123456789ABCDEF\n");
136   for (uint8_t row = 0; row < MATRIX_ROWS; row++) {
137     phex(row); print(": ");
138     pbin_reverse16(matrix_get_row(row));
139     print("\n");
140   }
141 }
142
143 /* Column pin configuration
144  */
145 //  Modified by Xydane
146 static void  init_cols(void){
147   palSetPadMode(GPIOA, 5, PAL_MODE_INPUT_PULLUP);
148   palSetPadMode(GPIOA, 15, PAL_MODE_INPUT_PULLUP);
149   palSetPadMode(GPIOA, 10, PAL_MODE_INPUT_PULLUP);
150   palSetPadMode(GPIOA, 9, PAL_MODE_INPUT_PULLUP);
151   palSetPadMode(GPIOA, 8, PAL_MODE_INPUT_PULLUP);
152   palSetPadMode(GPIOB, 15, PAL_MODE_INPUT_PULLUP);
153   palSetPadMode(GPIOB, 14, PAL_MODE_INPUT_PULLUP);
154   palSetPadMode(GPIOB, 13, PAL_MODE_INPUT_PULLUP);
155   palSetPadMode(GPIOB, 12, PAL_MODE_INPUT_PULLUP);
156   palSetPadMode(GPIOB, 11, PAL_MODE_INPUT_PULLUP);
157   palSetPadMode(GPIOB, 10, PAL_MODE_INPUT_PULLUP);
158   palSetPadMode(GPIOB, 1, PAL_MODE_INPUT_PULLUP);
159   palSetPadMode(GPIOB, 0, PAL_MODE_INPUT_PULLUP);
160   palSetPadMode(GPIOA, 7, PAL_MODE_INPUT_PULLUP);
161   palSetPadMode(GPIOA, 6, PAL_MODE_INPUT_PULLUP);
162 }
163
164 /* Returns status of switches(1:on, 0:off) */
165 //  Modified by Xydane
166 static matrix_row_t read_cols(void){
167   return ((palReadPad(GPIOA, 5)==PAL_HIGH) ? 0 : (1<<0))
168     | ((palReadPad(GPIOA, 15)==PAL_HIGH) ? 0 : (1<<1))
169     | ((palReadPad(GPIOA, 10)==PAL_HIGH) ? 0 : (1<<2))
170     | ((palReadPad(GPIOA, 9)==PAL_HIGH) ? 0 : (1<<3))
171     | ((palReadPad(GPIOA, 8)==PAL_HIGH) ? 0 : (1<<4))
172     | ((palReadPad(GPIOB, 15)==PAL_HIGH) ? 0 : (1<<5))
173     | ((palReadPad(GPIOB, 14)==PAL_HIGH) ? 0 : (1<<6))
174     | ((palReadPad(GPIOB, 13)==PAL_HIGH) ? 0 : (1<<7))
175     | ((palReadPad(GPIOB, 12)==PAL_HIGH) ? 0 : (1<<8))
176     | ((palReadPad(GPIOB, 11)==PAL_HIGH) ? 0 : (1<<9))
177     | ((palReadPad(GPIOB, 10)==PAL_HIGH) ? 0 : (1<<10))
178     | ((palReadPad(GPIOB, 1)==PAL_HIGH) ? 0 : (1<<11))
179     | ((palReadPad(GPIOB, 0)==PAL_HIGH) ? 0 : (1<<12))
180     | ((palReadPad(GPIOA, 7)==PAL_HIGH) ? 0 : (1<<13))
181     | ((palReadPad(GPIOA, 6)==PAL_HIGH) ? 0 : (1<<14));
182 }
183
184 /* Row pin configuration
185  */
186 //  Modified by Xydane
187 static void unselect_rows(void){
188   palSetPadMode(GPIOB, 9, PAL_MODE_INPUT);
189   palSetPadMode(GPIOB, 8, PAL_MODE_INPUT);
190   palSetPadMode(GPIOB, 7, PAL_MODE_INPUT);
191   palSetPadMode(GPIOB, 6, PAL_MODE_INPUT);
192   palSetPadMode(GPIOB, 5, PAL_MODE_INPUT);
193   palSetPadMode(GPIOA, 4, PAL_MODE_INPUT);
194 }
195
196 //  Modified by Xydane
197 static void select_row(uint8_t row){
198   (void)row;
199   switch (row) {
200     case 0:
201       palSetPadMode(GPIOB, 9, PAL_MODE_OUTPUT_PUSHPULL);
202       palClearPad(GPIOB, 9);
203       break;
204     case 1:
205       palSetPadMode(GPIOB, 8, PAL_MODE_OUTPUT_PUSHPULL);
206       palClearPad(GPIOB, 8);
207       break;
208     case 2:
209       palSetPadMode(GPIOB, 7, PAL_MODE_OUTPUT_PUSHPULL);
210       palClearPad(GPIOB, 7);
211       break;
212     case 3:
213       palSetPadMode(GPIOB, 6, PAL_MODE_OUTPUT_PUSHPULL);
214       palClearPad(GPIOB, 6);
215       break;
216     case 4:
217       palSetPadMode(GPIOB, 5, PAL_MODE_OUTPUT_PUSHPULL);
218       palClearPad(GPIOB, 5);
219       break;
220     case 5:
221       palSetPadMode(GPIOA, 4, PAL_MODE_OUTPUT_PUSHPULL);
222       palClearPad(GPIOA, 4);
223       break;
224   }
225 }