]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - mykey.c
94cbbfb5a183fda226d1be862b3c71e3177597ec
[max/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 }