2 Copyright 2012 Jun Wako <wakojun@gmail.com>
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.
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.
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/>.
35 * COL: input with pullup to sense
36 * PTD6 PTD5 PTD4 PTD3 PTA19 PTA18 PTA4 PTA2 PTA1 PTE25 PTE24 PTE30 PTE29 PTE21
38 * ROW: output low to strobe
39 * PTB3 PTB16 PTB17 PTC0 PTC1
43 static matrix_row_t matrix
[MATRIX_ROWS
];
44 static matrix_row_t matrix_debouncing
[MATRIX_ROWS
];
45 static bool debouncing
= false;
46 static uint16_t debouncing_time
= 0;
50 uint8_t matrix_rows(void)
56 uint8_t matrix_cols(void)
61 void matrix_init(void)
64 memset(matrix
, 0, MATRIX_ROWS
);
65 memset(matrix_debouncing
, 0, MATRIX_ROWS
);
67 // COL: internal pull-up
68 palSetPadMode(GPIOD
, 6, PAL_MODE_INPUT_PULLUP
);
69 palSetPadMode(GPIOD
, 5, PAL_MODE_INPUT_PULLUP
);
70 palSetPadMode(GPIOD
, 4, PAL_MODE_INPUT_PULLUP
);
71 palSetPadMode(GPIOD
, 3, PAL_MODE_INPUT_PULLUP
);
73 palSetPadMode(GPIOA
, 19, PAL_MODE_INPUT_PULLUP
);
74 palSetPadMode(GPIOA
, 18, PAL_MODE_INPUT_PULLUP
);
75 palSetPadMode(GPIOA
, 4, PAL_MODE_INPUT_PULLUP
);
76 palSetPadMode(GPIOA
, 2, PAL_MODE_INPUT_PULLUP
);
77 palSetPadMode(GPIOA
, 1, PAL_MODE_INPUT_PULLUP
);
79 palSetPadMode(GPIOE
, 25, PAL_MODE_INPUT_PULLUP
);
80 palSetPadMode(GPIOE
, 24, PAL_MODE_INPUT_PULLUP
);
81 palSetPadMode(GPIOE
, 30, PAL_MODE_INPUT_PULLUP
);
82 palSetPadMode(GPIOE
, 29, PAL_MODE_INPUT_PULLUP
);
83 palSetPadMode(GPIOE
, 21, PAL_MODE_INPUT_PULLUP
);
86 palSetPadMode(GPIOB
, 3, PAL_MODE_OUTPUT_PUSHPULL
);
87 palSetPadMode(GPIOB
, 16, PAL_MODE_OUTPUT_PUSHPULL
);
88 palSetPadMode(GPIOB
, 17, PAL_MODE_OUTPUT_PUSHPULL
);
89 palSetPadMode(GPIOC
, 0, PAL_MODE_OUTPUT_PUSHPULL
);
90 palSetPadMode(GPIOC
, 1, PAL_MODE_OUTPUT_PUSHPULL
);
99 palSetPadMode(GPIOD
, 7, PAL_MODE_OUTPUT_PUSHPULL
);
101 chThdSleepMilliseconds(200);
102 palClearPad(GPIOD
, 7);
103 chThdSleepMilliseconds(200);
105 chThdSleepMilliseconds(200);
106 palClearPad(GPIOD
, 7);
109 uint8_t matrix_scan(void)
111 for (int row
= 0; row
< MATRIX_ROWS
; row
++) {
112 matrix_row_t data
= 0;
116 case 0: palClearPad(GPIOB
, 3); break;
117 case 1: palClearPad(GPIOB
, 16); break;
118 case 2: palClearPad(GPIOB
, 17); break;
119 case 3: palClearPad(GPIOC
, 0); break;
120 case 4: palClearPad(GPIOC
, 1); break;
124 //chThdSleepMicroseconds(1); // TODO: sleep around 1ms for some reason
125 //chThdSleepMilliseconds(1); // seems to work correctly
127 data
= (!palReadPad(GPIOD
, 6) << 0UL) |
128 (!palReadPad(GPIOD
, 5) << 1UL) |
129 (!palReadPad(GPIOD
, 4) << 2UL) |
130 (!palReadPad(GPIOD
, 3) << 3UL) |
131 (!palReadPad(GPIOA
, 19) << 4UL) |
132 (!palReadPad(GPIOA
, 18) << 5UL) |
133 (!palReadPad(GPIOA
, 4) << 6UL) |
134 (!palReadPad(GPIOA
, 2) << 7UL) |
135 (!palReadPad(GPIOA
, 1) << 8UL) |
136 (!palReadPad(GPIOE
, 25) << 9UL) |
137 (!palReadPad(GPIOE
, 24) << 10UL) |
138 (!palReadPad(GPIOE
, 30) << 11UL) |
139 (!palReadPad(GPIOE
, 29) << 12UL) |
140 (!palReadPad(GPIOE
, 21) << 13UL);
144 case 0: palSetPad(GPIOB
, 3); break;
145 case 1: palSetPad(GPIOB
, 16); break;
146 case 2: palSetPad(GPIOB
, 17); break;
147 case 3: palSetPad(GPIOC
, 0); break;
148 case 4: palSetPad(GPIOC
, 1); break;
151 if (matrix_debouncing
[row
] != data
) {
152 matrix_debouncing
[row
] = data
;
154 debouncing_time
= timer_read();
158 if (debouncing
&& timer_elapsed(debouncing_time
) > DEBOUNCE
) {
159 for (int row
= 0; row
< MATRIX_ROWS
; row
++) {
160 matrix
[row
] = matrix_debouncing
[row
];
168 bool matrix_is_on(uint8_t row
, uint8_t col
)
170 return (matrix
[row
] & (1<<col
));
174 matrix_row_t
matrix_get_row(uint8_t row
)
179 void matrix_print(void)
182 xprintf("\nr/c 0123456789ABCDEF\n");
183 for (uint8_t row
= 0; row
< MATRIX_ROWS
; row
++) {
184 xprintf("%02X: ", row
);
185 matrix_row_t data
= matrix_get_row(row
);
186 for (int col
= 0; col
< MATRIX_COLS
; col
++) {
200 void led_set(uint8_t usb_led
) {
201 if (usb_led
& (1<<USB_LED_CAPS_LOCK
)) {
203 palSetPadMode(GPIOD
, 7, PAL_MODE_OUTPUT_PUSHPULL
);
207 palSetPadMode(GPIOD
, 7, PAL_MODE_INPUT
);
215 const uint8_t keymaps
[][MATRIX_ROWS
][MATRIX_COLS
] = {
217 { KC_ESC
, KC_1
, KC_2
, KC_3
, KC_4
, KC_5
, KC_6
, KC_7
, KC_8
, KC_9
, KC_0
, KC_MINS
, KC_EQL
, KC_BSLS
},
218 { KC_TAB
, KC_Q
, KC_W
, KC_E
, KC_R
, KC_T
, KC_Y
, KC_U
, KC_I
, KC_O
, KC_P
, KC_LBRC
, KC_RBRC
, KC_BSPC
},
219 { KC_LCTL
, KC_A
, KC_S
, KC_D
, KC_F
, KC_G
, KC_H
, KC_J
, KC_K
, KC_L
, KC_SCLN
, KC_QUOT
, KC_ENT
, KC_NO
},
220 { KC_LSFT
, KC_Z
, KC_X
, KC_C
, KC_V
, KC_B
, KC_N
, KC_M
, KC_COMM
, KC_DOT
, KC_SLSH
, KC_RSFT
, KC_NO
, KC_FN0
},
221 { KC_LCTL
, KC_LGUI
, KC_LALT
, KC_NO
, KC_SPC
, KC_NO
, KC_NO
, KC_NO
, KC_NLCK
, KC_CAPS
, KC_MENU
, KC_RALT
, KC_RGUI
, KC_RCTL
},
224 { KC_ESC
, KC_F1
, KC_F2
, KC_F3
, KC_F4
, KC_F5
, KC_F6
, KC_F7
, KC_F8
, KC_F9
, KC_F10
, KC_F11
, KC_F12
, KC_DEL
},
225 { KC_CAPS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_PSCR
, KC_SLCK
, KC_PAUS
, KC_UP
, KC_INS
, KC_TRNS
},
226 { KC_TRNS
, KC_VOLD
, KC_VOLU
, KC_MUTE
, KC_TRNS
, KC_TRNS
, KC_PAST
, KC_PSLS
, KC_HOME
, KC_PGUP
, KC_LEFT
, KC_RGHT
, KC_PENT
, KC_TRNS
},
227 { KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_PPLS
, KC_PMNS
, KC_END
, KC_PGDN
, KC_DOWN
, KC_TRNS
, KC_TRNS
, KC_TRNS
},
228 { KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
, KC_TRNS
},
232 const action_t fn_actions
[] = {
233 [0] = ACTION_LAYER_TAP_KEY(1, KC_GRV
),