]> git.gir.st - tmk_keyboard.git/blob - mykey.c
94cbbfb5a183fda226d1be862b3c71e3177597ec
[tmk_keyboard.git] / mykey.c
1 /* 2010/08/23 noname
2 * keyboard firmware based on PJRC USB keyboard example
3 */
4 /* Keyboard example with debug channel, for Teensy USB Development Board
5 * http://www.pjrc.com/teensy/usb_keyboard.html
6 * Copyright (c) 2008 PJRC.COM, LLC
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 * THE SOFTWARE.
25 */
26
27 #include <stdbool.h>
28 #include <avr/io.h>
29 #include <avr/pgmspace.h>
30 #include <avr/interrupt.h>
31 #include <util/delay.h>
32
33 #include "usb_device.h"
34 #include "print.h"
35 #include "matrix.h"
36 #include "keymap.h"
37 #include "jump_bootloader.h"
38
39 #define LED_CONFIG (DDRD |= (1<<6))
40 #define LED_ON (PORTD &= ~(1<<6))
41 #define LED_OFF (PORTD |= (1<<6))
42 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
43
44 static void print_matrix(void);
45
46
47 uint16_t idle_count=0;
48
49
50
51 int main(void)
52 {
53 bool modified = false;
54 bool has_ghost = false;
55 uint8_t key_index = 0;
56
57 // set for 16 MHz clock
58 CPU_PRESCALE(0);
59
60 matrix_init();
61
62
63 // Initialize the USB, and then wait for the host to set configuration.
64 // If the Teensy is powered without a PC connected to the USB port,
65 // this will wait forever.
66 usb_init();
67 while (!usb_configured()) /* wait */ ;
68
69 // Wait an extra second for the PC's operating system to load drivers
70 // and do whatever it does to actually be ready for input
71 _delay_ms(1000);
72
73 // Configure timer 0 to generate a timer overflow interrupt every
74 // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
75 // This demonstrates how to use interrupts to implement a simple
76 // inactivity timeout.
77 TCCR0A = 0x00;
78 TCCR0B = 0x05;
79 TIMSK0 = (1<<TOIE0);
80
81 print("firmware 0.2 for t.m.k.\n");
82
83 int loop_count = 0;
84 while (1) {
85 int layer = 0;
86
87 matrix_scan();
88 layer = get_layer();
89
90 modified = matrix_is_modified();
91 has_ghost = matrix_has_ghost();
92
93 // doesnt send keys during ghost occurs
94 if (modified && !has_ghost) {
95 key_index = 0;
96 keyboard_modifier_keys = 0;
97 for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
98
99 for (int row = 0; row < MATRIX_ROWS; row++) {
100 for (int col = 0; col < MATRIX_COLS; col++) {
101 if (matrix[row] & 1<<col) continue;
102
103 uint8_t code = get_keycode(layer, row, col);
104 if (code == KB_NO) {
105 continue;
106 } else if (KB_LCTRL <= code && code <= KB_RGUI) {
107 // modifier keycode: 0xE0-0xE7
108 keyboard_modifier_keys |= 1<<(code & 0x07);
109 } else {
110 if (key_index < 6)
111 keyboard_keys[key_index] = code;
112 key_index++;
113 }
114 }
115 }
116
117 // run bootloader when 4 left modifier keys down
118 if (keyboard_modifier_keys == (MOD_LCTRL | MOD_LSHIFT | MOD_LALT | MOD_LGUI)) {
119 // cancel all keys
120 keyboard_modifier_keys = 0;
121 for (int i = 0; i < 6; i++) keyboard_keys[i] = KB_NO;
122 usb_keyboard_send();
123
124 print("jump to bootloader...\n");
125 _delay_ms(1000);
126 jump_bootloader();
127 }
128
129 if (key_index > 6) {
130 //Rollover
131 }
132
133 usb_keyboard_send();
134
135
136 // variables shared with interrupt routines must be
137 // accessed carefully so the interrupt routine doesn't
138 // try to use the variable in the middle of our access
139 cli();
140 //idle_count = 0;
141 sei();
142 }
143
144 // print matrix state for debug
145 if (modified) {
146 print_matrix();
147
148 // LED flush
149 DDRD |= 1<<PD6;
150 PORTD |= 1<<PD6;
151 }
152
153 /*
154 // print counts for debug
155 if ((loop_count % 0x1000) == 0) {
156 //print(".");
157 print("idle_count: "); phex((idle_count & 0xFF00) >> 8); phex(idle_count & 0xFF); print("\n");
158 print("loop_count: "); phex((loop_count & 0xFF00) >> 8); phex(loop_count & 0xFF); print("\n");
159 print_matrix();
160 }
161
162 // teensy LED flush for debug
163 if ((loop_count & 0x100) == 0) {
164 DDRD |= 1<<PD6;
165 PORTD |= 1<<PD6;
166 }
167 */
168
169 // now the current pins will be the previous, and
170 // wait a short delay so we're not highly sensitive
171 // to mechanical "bounce".
172 _delay_ms(2);
173 loop_count++;
174 }
175 }
176
177 static void print_matrix(void) {
178 print("\nr/c 01234567\n");
179 for (int row = 0; row < MATRIX_ROWS; row++) {
180 phex(row); print(": ");
181 pbin_reverse(matrix[row]);
182 if (matrix_has_ghost_in_row(row)) {
183 print(" <ghost");
184 }
185 print("\n");
186 }
187 print("keys: ");
188 for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); }
189 print("\n");
190 print("mod: "); phex(keyboard_modifier_keys); print("\n");
191 }
192
193 // This interrupt routine is run approx 61 times per second.
194 // A very simple inactivity timeout is implemented, where we
195 // will send a space character and print a message to the
196 // hid_listen debug message window.
197 ISR(TIMER0_OVF_vect)
198 {
199 idle_count++;
200 }
Imprint / Impressum