2 * keyboard firmware based on PJRC USB keyboard example
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
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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
28 #include <avr/pgmspace.h>
29 #include <avr/interrupt.h>
30 #include <util/delay.h>
31 #include "usb_keyboard_debug.h"
36 #define LED_CONFIG (DDRD |= (1<<6))
37 #define LED_ON (PORTD &= ~(1<<6))
38 #define LED_OFF (PORTD |= (1<<6))
39 #define CPU_PRESCALE(n) (CLKPR = 0x80, CLKPR = (n))
42 uint16_t idle_count=0;
49 uint8_t key_index = 0;
51 // set for 16 MHz clock
57 // Initialize the USB, and then wait for the host to set configuration.
58 // If the Teensy is powered without a PC connected to the USB port,
59 // this will wait forever.
61 while (!usb_configured()) /* wait */ ;
63 // Wait an extra second for the PC's operating system to load drivers
64 // and do whatever it does to actually be ready for input
67 // Configure timer 0 to generate a timer overflow interrupt every
68 // 256*1024 clock cycles, or approx 61 Hz when using 16 MHz clock
69 // This demonstrates how to use interrupts to implement a simple
70 // inactivity timeout.
75 print("keyboard firmware 0.1 for t.m.k.\n");
78 uint8_t row, col, code;
84 keyboard_modifier_keys = 0;
85 for (int i = 0; i < 6; i++)
86 keyboard_keys[i] = KB_NO;
89 for (row = 0; row < MATRIX_ROWS; row++) {
90 if (matrix[row] != prev_matrix[row]) {
94 for (col = 0; col < MATRIX_COLS; col++) {
95 if (matrix[row] & 1<<col) continue;
96 code = get_keycode(row, col);
98 // Modifier keycode: 0xE0-0xE7
99 if (KB_LCTRL <= code && code <= KB_RGUI) {
100 keyboard_modifier_keys |= 1<<(code&0x07);
103 keyboard_keys[key_index] = code;
117 // if any keypresses were detected, reset the idle counter
119 print(" 01234567\n");
120 for (row = 0; row < MATRIX_ROWS; row++) {
121 phex(row); print(": "); pbin_reverse(matrix[row]); print("\n");
124 for (int i = 0; i < 6; i++) { phex(keyboard_keys[i]); print(" "); }
126 print("mod: "); phex(keyboard_modifier_keys); print("\n");
129 // variables shared with interrupt routines must be
130 // accessed carefully so the interrupt routine doesn't
131 // try to use the variable in the middle of our access
137 // now the current pins will be the previous, and
138 // wait a short delay so we're not highly sensitive
139 // to mechanical "bounce".
144 // This interrupt routine is run approx 61 times per second.
145 // A very simple inactivity timeout is implemented, where we
146 // will send a space character and print a message to the
147 // hid_listen debug message window.
151 if (idle_count > 61 * 8) {
153 //print("Timer Event :)\n");
154 //usb_keyboard_press(KEY_SPACE, 0);