#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/wdt.h>
#include <util/delay.h>
#include <string.h>
#include <stdio.h>
#include "usbdrv.h"
#include "keycodes.h"
Go to the source code of this file.
Data Structures | |
struct | Key |
This structure can be used as a container for a single 'key'. More... | |
Defines | |
#define | F_CPU 12000000L |
we use a 12MHz crystal | |
#define | PORTCOLUMNS PORTB |
port on which we read the state of the columns | |
#define | PINCOLUMNS PINB |
port on which we read the state of the columns | |
#define | DDRCOLUMNS DDRB |
port on which we read the state of the columns | |
#define | PORTROWS1 PORTA |
first port connected to the matrix rows | |
#define | PINROWS1 PINA |
first port connected to the matrix rows | |
#define | DDRROWS1 DDRA |
first port connected to the matrix rows | |
#define | PORTROWS2 PORTC |
second port connected to the matrix rows | |
#define | PINROWS2 PINC |
second port connected to the matrix rows | |
#define | DDRROWS2 DDRC |
second port connected to the matrix rows | |
#define | PORTLEDS PORTD |
port on which the LEDs are connected | |
#define | PINLEDS PIND |
port on which the LEDs are connected | |
#define | DDRLEDS DDRD |
port on which the LEDs are connected | |
#define | LEDSCROLL PIND4 |
address of the scroll-lock LED | |
#define | LEDCAPS PIND5 |
address of the caps-lock LED | |
#define | LEDNUM PIND6 |
address of the num-lock LED | |
#define | PORTJUMPERS PORTD |
port for additional jumpers | |
#define | PINJUMPERS PIND |
port for additional jumpers | |
#define | DDRJUMPERS DDRD |
port for additional jumpers | |
#define | JUMPER0 PD1 |
address for jumper 0 | |
#define | JUMPER1 PD3 |
address for jumper 1 | |
#define | JUMPER2 PD7 |
address for jumper 2 | |
#define | LED_NUM 0x01 |
num LED on a boot-protocol keyboard | |
#define | LED_CAPS 0x02 |
caps LED on a boot-protocol keyboard | |
#define | LED_SCROLL 0x04 |
scroll LED on a boot-protocol keyboard | |
#define | LED_COMPOSE 0x08 |
compose LED on a boot-protocol keyboard | |
#define | LED_KANA 0x10 |
kana LED on a boot-protocol keyboard | |
Functions | |
uint8_t | usbFunctionSetup (uint8_t data[8]) |
This function is called whenever we receive a setup request via USB. | |
uint8_t | usbFunctionWrite (uchar *data, uchar len) |
The write function is called when LEDs should be set. | |
void | usbSendReport (uint8_t mode, uint8_t key) |
Send a single report to the computer. | |
Key | charToKey (char character) |
Convert an ASCII-character to the corresponding key-code and modifier-code combination. | |
void | sendKey (Key keytosend) |
Send a key to the computer, followed by the release of all keys. | |
void | sendString (char *string) |
Send a string to the computer. | |
void | printMatrix (void) |
Print the current state of the keyboard in a readable form. | |
uint8_t | scankeys (void) |
Scan and debounce keypresses. | |
int | main (void) |
Main function, containing the main loop that manages timer- and USB-functionality. | |
Variables | |
uint8_t | expectReport = 0 |
flag to indicate if we expect an USB-report | |
uint8_t | LEDstate = 0 |
current state of the LEDs | |
char PROGMEM | usbHidReportDescriptor [USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] |
USB report descriptor (length is defined in usbconfig.h). | |
uint8_t | curmatrix [16] |
contains current state of the keyboard | |
const uint8_t PROGMEM | keymatrix [16][8] |
The keymatrix-array contains positions of keys in the matrix. | |
const uint8_t PROGMEM | modmatrix [16][8] |
The modmatrix-array contains positions of the modifier-keys in the matrix. |
License: GNU GPL v2 (see License.txt)
Definition in file main.c.
#define DDRCOLUMNS DDRB |
#define DDRROWS1 DDRA |
first port connected to the matrix rows
Definition at line 228 of file main.c.
Referenced by scankeys().
#define DDRROWS2 DDRC |
second port connected to the matrix rows
Definition at line 231 of file main.c.
Referenced by scankeys().
#define LED_CAPS 0x02 |
caps LED on a boot-protocol keyboard
Definition at line 291 of file main.c.
Referenced by usbFunctionWrite().
#define LED_COMPOSE 0x08 |
#define LED_NUM 0x01 |
num LED on a boot-protocol keyboard
Definition at line 290 of file main.c.
Referenced by usbFunctionWrite().
#define LED_SCROLL 0x04 |
scroll LED on a boot-protocol keyboard
Definition at line 292 of file main.c.
Referenced by usbFunctionWrite().
#define LEDCAPS PIND5 |
address of the caps-lock LED
Definition at line 237 of file main.c.
Referenced by usbFunctionWrite().
#define LEDNUM PIND6 |
address of the num-lock LED
Definition at line 238 of file main.c.
Referenced by usbFunctionWrite().
#define LEDSCROLL PIND4 |
address of the scroll-lock LED
Definition at line 236 of file main.c.
Referenced by usbFunctionWrite().
#define PINCOLUMNS PINB |
port on which we read the state of the columns
Definition at line 224 of file main.c.
Referenced by scankeys().
#define PINROWS1 PINA |
#define PINROWS2 PINC |
#define PORTCOLUMNS PORTB |
#define PORTLEDS PORTD |
port on which the LEDs are connected
Definition at line 233 of file main.c.
Referenced by usbFunctionWrite().
#define PORTROWS1 PORTA |
first port connected to the matrix rows
Definition at line 226 of file main.c.
Referenced by scankeys().
#define PORTROWS2 PORTC |
second port connected to the matrix rows
Definition at line 229 of file main.c.
Referenced by scankeys().
Key charToKey | ( | char | character | ) |
Convert an ASCII-character to the corresponding key-code and modifier-code combination.
character ASCII-character to convert
Definition at line 493 of file main.c.
References Key::key, KEY_0, KEY_1, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_apostroph, KEY_backslash, KEY_comma, KEY_dot, KEY_equals, KEY_grave, KEY_hash, KEY_lbracket, KEY_minus, KEY_rbracket, KEY_Reserved, KEY_semicolon, KEY_slash, KEY_Spacebar, MOD_NONE, MOD_SHIFT_LEFT, and Key::mode.
Referenced by sendString().
int main | ( | void | ) |
Main function, containing the main loop that manages timer- and USB-functionality.
/return the obligatory integer that nobody cares about...
Definition at line 755 of file main.c.
References scankeys().
void printMatrix | ( | void | ) |
Print the current state of the keyboard in a readable form.
This function is used for debug-purposes only.
Definition at line 642 of file main.c.
References curmatrix, and sendString().
uint8_t scankeys | ( | void | ) |
Scan and debounce keypresses.
This is the main worker function for normal keyboard operation, the code contains lot of comments. Basically, it first scans the keyboard state. If a change is detected, it initializes a counter that is decreased each time this function is called. If the counter reaches 1, that means that the same scan result has been scanned ten times in a row, so we can be pretty sure that the keys are in a certain state (as in: not bouncing). Then, the codes for keys and modifiers are searched from the two arrays, the USB-message to send the state is prepared. The return value of this function indicates if the message has to be sent.
Definition at line 679 of file main.c.
References curmatrix, DDRROWS1, DDRROWS2, KEY_ErrorRollOver, KEY_Reserved, keymatrix, MOD_NONE, modmatrix, PINCOLUMNS, PORTROWS1, and PORTROWS2.
Referenced by main().
void sendKey | ( | Key | keytosend | ) |
Send a key to the computer, followed by the release of all keys.
This can be used repetitively to send a string.
keytosend | key structure to send |
Definition at line 621 of file main.c.
References Key::key, Key::mode, and usbSendReport().
Referenced by sendString().
void sendString | ( | char * | string | ) |
Send a string to the computer.
This function converts each character of an ASCII-string to a key-structure and uses sendKey() to send it.
string | string to send |
Definition at line 631 of file main.c.
References charToKey(), and sendKey().
Referenced by printMatrix().
uint8_t usbFunctionSetup | ( | uint8_t | data[8] | ) |
This function is called whenever we receive a setup request via USB.
data[8] | eight bytes of data we received |
Definition at line 343 of file main.c.
References expectReport.
uint8_t usbFunctionWrite | ( | uchar * | data, | |
uchar | len | |||
) |
The write function is called when LEDs should be set.
Normally, we get only one byte that contains info about the LED states.
data | pointer to received data | |
len | number ob bytes received |
Definition at line 384 of file main.c.
References expectReport, LED_CAPS, LED_NUM, LED_SCROLL, LEDCAPS, LEDNUM, LEDSCROLL, LEDstate, and PORTLEDS.
void usbSendReport | ( | uint8_t | mode, | |
uint8_t | key | |||
) |
uint8_t curmatrix[16] |
contains current state of the keyboard
Definition at line 424 of file main.c.
Referenced by printMatrix(), and scankeys().
uint8_t expectReport = 0 |
flag to indicate if we expect an USB-report
Definition at line 288 of file main.c.
Referenced by usbFunctionSetup(), and usbFunctionWrite().
const uint8_t PROGMEM keymatrix[16][8] |
Initial value:
{ {KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved }, {KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved }, {KEY_ESCAPE, KEY_Tab, KEY_grave, KEY_1, KEY_Q, KEY_A, KEY_Z, KEY_Reserved }, {KEY_Euro, KEY_capslock, KEY_F1, KEY_2, KEY_W, KEY_S, KEY_X, KEY_Reserved }, {KEY_F4, KEY_F3, KEY_F2, KEY_3, KEY_E, KEY_D, KEY_C, KEY_Reserved }, {KEY_G, KEY_T, KEY_5, KEY_4, KEY_R, KEY_F, KEY_V, KEY_B }, {KEY_F5, KEY_DELETE, KEY_F9, KEY_F10, KEY_Reserved, KEY_Reserved, KEY_Return, KEY_Spacebar }, {KEY_H, KEY_Y, KEY_6, KEY_7, KEY_U, KEY_J, KEY_M, KEY_N }, {KEY_F6, KEY_rbracket, KEY_equals, KEY_8, KEY_I, KEY_K, KEY_comma, KEY_Reserved }, {KEY_Reserved, KEY_F7, KEY_F8, KEY_9, KEY_O, KEY_L, KEY_dot, KEY_Reserved }, {KEY_apostroph, KEY_lbracket, KEY_minus, KEY_0, KEY_P, KEY_semicolon, KEY_hash, KEY_slash }, {KEY_Reserved, KEY_KP4, KEY_DeleteForward, KEY_F11, KEY_KP7, KEY_KP1, KEY_NumLock, KEY_DownArrow }, {KEY_KP0, KEY_KP5, KEY_Insert, KEY_F12, KEY_KP8, KEY_KP2, KEY_KPslash, KEY_RightArrow }, {KEY_KPcomma, KEY_KP6, KEY_PageUp, KEY_PageDown, KEY_KP9, KEY_KP3, KEY_KPasterisk, KEY_KPminus }, {KEY_UpArrow, KEY_Reserved, KEY_Home, KEY_End, KEY_KPplus, KEY_KPenter, KEY_Pause, KEY_LeftArrow }, {KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_PrintScreen, KEY_ScrollLock, KEY_Reserved, KEY_Reserved, KEY_Reserved }, }
Here you can see which row is connected to which column when a key is pressed. This array probably has to be modified if this firmware is ported to a different keyboard.
Definition at line 433 of file main.c.
Referenced by scankeys().
uint8_t LEDstate = 0 |
const uint8_t PROGMEM modmatrix[16][8] |
Initial value:
{ {MOD_NONE, MOD_NONE, MOD_CONTROL_LEFT, MOD_NONE, MOD_NONE, MOD_NONE, MOD_CONTROL_RIGHT, MOD_NONE }, {MOD_NONE, MOD_SHIFT_LEFT, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_SHIFT_RIGHT, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE }, {MOD_ALT_LEFT, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_ALT_RIGHT}, }
It is built in the same way as the keymatrix-array.
Definition at line 458 of file main.c.
Referenced by scankeys().
char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] |
USB report descriptor (length is defined in usbconfig.h).
The report descriptor has been created with usb.org's "HID Descriptor Tool" which can be downloaded from http://www.usb.org/developers/hidpage/ (it's an .exe, but it even runs under Wine).