]> git.friedersdorff.com Git - max/tmk_keyboard.git/blob - mykey.c
098bb4e51fcb937bca54fbbe2a4e5e989782dca7
[max/tmk_keyboard.git] / mykey.c
1 /* Keyboard example with debug channel, for Teensy USB Development Board
2  * http://www.pjrc.com/teensy/usb_keyboard.html
3  * Copyright (c) 2008 PJRC.COM, LLC
4  * 
5  * Permission is hereby granted, free of charge, to any person obtaining a copy
6  * of this software and associated documentation files (the "Software"), to deal
7  * in the Software without restriction, including without limitation the rights
8  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9  * copies of the Software, and to permit persons to whom the Software is
10  * furnished to do so, subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21  * THE SOFTWARE.
22  */
23
24 #include <avr/io.h>
25 #include <avr/pgmspace.h>
26 #include <avr/interrupt.h>
27 #include <util/delay.h>
28 #include "usb_keyboard_debug.h"
29 #include "print.h"
30 #include "keymap.h"
31
32 #define LED_CONFIG      (DDRD |= (1<<6))
33 #define LED_ON          (PORTD &= ~(1<<6))
34 #define LED_OFF         (PORTD |= (1<<6))
35 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
36
37 uint8_t number_keys[10]=
38         {KEY_0,KEY_1,KEY_2,KEY_3,KEY_4,KEY_5,KEY_6,KEY_7,KEY_8,KEY_9};
39
40 uint16_t idle_count=0;
41
42
43
44 //
45 // scan matrix
46 //
47 uint8_t MAX_ROW = 9;
48
49 // initialize ports for matrix
50 void port_setup(void)
51 {
52         // Column: input w/pullup
53         DDRB = 0x00;
54         PORTB = 0xFF;
55
56         // Row: Hi-Z(unselected)
57         // PD:0,1,2,3,6,7
58         // PC:6,7
59         // PF:7
60         DDRD = 0x00;
61         PORTD = 0x00;
62         DDRC = 0x00;
63         PORTC = 0x00;
64         DDRF = 0x00;
65         PORTF = 0x00;
66 }
67
68 // select a row of matrix for read
69 void select_row(uint8_t row)
70 {
71     switch (row) {
72         case 0:
73             DDRD  = (1<<0);
74             PORTD = 0x00;
75             DDRC  = 0x00;
76             PORTC = 0x00;
77             DDRF  = 0x00;
78             PORTF = 0x00;
79             break;
80         case 1:
81             DDRD  = (1<<1);
82             PORTD = 0x00;
83             DDRC  = 0x00;
84             PORTC = 0x00;
85             DDRF  = 0x00;
86             PORTF = 0x00;
87             break;
88         case 2:
89             DDRD  = (1<<2);
90             PORTD = 0x00;
91             DDRC  = 0x00;
92             PORTC = 0x00;
93             DDRF  = 0x00;
94             PORTF = 0x00;
95             break;
96         case 3:
97             DDRD  = (1<<3);
98             PORTD = 0x00;
99             DDRC  = 0x00;
100             PORTC = 0x00;
101             DDRF  = 0x00;
102             PORTF = 0x00;
103             break;
104         case 4:
105             DDRD  = (1<<6);
106             PORTD = 0x00;
107             DDRC  = 0x00;
108             PORTC = 0x00;
109             DDRF  = 0x00;
110             PORTF = 0x00;
111             break;
112         case 5:
113             DDRD  = (1<<7);
114             PORTD = 0x00;
115             DDRC  = 0x00;
116             PORTC = 0x00;
117             DDRF  = 0x00;
118             PORTF = 0x00;
119             break;
120         case 6:
121             DDRD  = 0x00;
122             PORTD = 0x00;
123             DDRC  = (1<<6);
124             PORTC = 0x00;
125             DDRF  = 0x00;
126             PORTF = 0x00;
127             break;
128         case 7:
129             DDRD  = 0x00;
130             PORTD = 0x00;
131             DDRC  = (1<<7);
132             PORTC = 0x00;
133             DDRF  = 0x00;
134             PORTF = 0x00;
135             break;
136         case 8:
137             DDRD  = 0x00;
138             PORTD = 0x00;
139             DDRC  = 0x00;
140             PORTC = 0x00;
141             DDRF  = (1<<7);
142             PORTF = 0x00;
143             break;
144     }
145 }
146
147 uint8_t read_col(void)
148 {
149     return PINB;
150 }
151
152 int main(void)
153 {
154         uint8_t i, reset_idle;
155         uint8_t prev_state[MAX_ROW];
156         for (int i=0; i < MAX_ROW; i++) prev_state[i] = 0xFF;
157
158         // set for 16 MHz clock
159         CPU_PRESCALE(0);
160
161         port_setup();
162
163
164         // Initialize the USB, and then wait for the host to set configuration.
165         // If the Teensy is powered without a PC connected to the USB port,
166         // this will wait forever.
167         usb_init();
168         while (!usb_configured()) /* wait */ ;
169
170         // Wait an extra second for the PC's operating system to load drivers
171         // and do whatever it does to actually be ready for input
172         _delay_ms(1000);
173
174         // Configure timer 0 to generate a timer overflow interrupt every
175         // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
176         // This demonstrates how to use interrupts to implement a simple
177         // inactivity timeout.
178         TCCR0A = 0x00;
179         TCCR0B = 0x05;
180         TIMSK0 = (1<<TOIE0);
181
182         print("Begin keyboard example program\n");
183         print("All Port B or Port D pins are inputs with pullup resistors.\n");
184         print("Any connection to ground on Port B or D pins will result in\n");
185         print("keystrokes sent to the PC (and debug messages here).\n");
186
187         uint8_t col;
188         uint8_t code;
189         while (1) {
190             reset_idle = 0;
191
192             for (uint8_t r=0; r < MAX_ROW; r++) {
193                 select_row(r);
194
195                 // without this read unstable value.
196                 _delay_us(30);
197
198                 col = read_col();
199                 if (col != prev_state[r]) {
200                     prev_state[r] = col;
201                     phex(r);
202                     print(": ");
203                     pbin(col);
204                     print("\n");
205
206                     for (int c = 0; c < 8; c++) {
207                         if (col & 1<<c) continue;
208                         code = get_keycode(r, c);
209                         phex(code);
210                         print("\n");
211                         usb_keyboard_press(code, 0);
212                     }
213
214                     reset_idle = 1;
215                 }
216             }
217                 
218
219
220                 // if any keypresses were detected, reset the idle counter
221                 if (reset_idle) {
222                         // variables shared with interrupt routines must be
223                         // accessed carefully so the interrupt routine doesn't
224                         // try to use the variable in the middle of our access
225                         cli();
226                         idle_count = 0;
227                         sei();
228                 }
229
230                 // now the current pins will be the previous, and
231                 // wait a short delay so we're not highly sensitive
232                 // to mechanical "bounce".
233                 _delay_ms(2);
234         }
235 }
236
237 // This interrupt routine is run approx 61 times per second.
238 // A very simple inactivity timeout is implemented, where we
239 // will send a space character and print a message to the
240 // hid_listen debug message window.
241 ISR(TIMER0_OVF_vect)
242 {
243         idle_count++;
244         if (idle_count > 61 * 8) {
245                 idle_count = 0;
246                 print("Timer Event :)\n");
247                 //usb_keyboard_press(KEY_SPACE, 0);
248         }
249 }
250
251