00001
00207 #define F_CPU 12000000L
00208
00209 #include <avr/io.h>
00210 #include <avr/interrupt.h>
00211 #include <avr/pgmspace.h>
00212 #include <avr/wdt.h>
00213 #include <util/delay.h>
00214 #include <string.h>
00215 #include <stdio.h>
00216
00217 #include "usbdrv.h"
00218 #include "keycodes.h"
00219
00220
00221
00222
00223 #define PORTCOLUMNS PORTB
00224 #define PINCOLUMNS PINB
00225 #define DDRCOLUMNS DDRB
00226 #define PORTROWS1 PORTA
00227 #define PINROWS1 PINA
00228 #define DDRROWS1 DDRA
00229 #define PORTROWS2 PORTC
00230 #define PINROWS2 PINC
00231 #define DDRROWS2 DDRC
00232
00233 #define PORTLEDS PORTD
00234 #define PINLEDS PIND
00235 #define DDRLEDS DDRD
00236 #define LEDSCROLL PIND4
00237 #define LEDCAPS PIND5
00238 #define LEDNUM PIND6
00239
00240 #define PORTJUMPERS PORTD
00241 #define PINJUMPERS PIND
00242 #define DDRJUMPERS DDRD
00243 #define JUMPER0 PD1
00244 #define JUMPER1 PD3
00245 #define JUMPER2 PD7
00246
00247
00251 static void hardwareInit(void) {
00252
00253 PORTCOLUMNS = 0xff;
00254 DDRCOLUMNS = 0x00;
00255
00256
00257 PORTROWS1 = 0xff;
00258 DDRROWS1 = 0x00;
00259 PORTROWS2 = 0xff;
00260 DDRROWS2 = 0x00;
00261
00262
00263
00264
00265
00266 PORTD = 0xfa;
00267 DDRD = 0x75;
00268
00269 _delay_us(11);
00270 DDRD = 0x70;
00271
00272
00273 TCCR0 = 5;
00274
00275
00276 PORTLEDS &= ~((1 << LEDNUM) | (1 << LEDCAPS) | (1 << LEDSCROLL));
00277 _delay_ms(50);
00278 PORTLEDS |= ((1 << LEDNUM) | (1 << LEDCAPS) | (1 << LEDSCROLL));
00279 }
00280
00281
00282
00283
00284
00285 static uint8_t reportBuffer[8];
00286 static uint8_t idleRate;
00287 static uint8_t protocolVer = 1;
00288 uint8_t expectReport = 0;
00289
00290 #define LED_NUM 0x01
00291 #define LED_CAPS 0x02
00292 #define LED_SCROLL 0x04
00293 #define LED_COMPOSE 0x08
00294 #define LED_KANA 0x10
00295 uint8_t LEDstate = 0;
00296
00297
00302 char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = {
00303 0x05, 0x01,
00304 0x09, 0x06,
00305 0xa1, 0x01,
00306 0x05, 0x07,
00307 0x19, 0xe0,
00308 0x29, 0xe7,
00309 0x15, 0x00,
00310 0x25, 0x01,
00311 0x75, 0x01,
00312 0x95, 0x08,
00313 0x81, 0x02,
00314 0x95, 0x01,
00315 0x75, 0x08,
00316 0x81, 0x03,
00317 0x95, 0x05,
00318 0x75, 0x01,
00319 0x05, 0x08,
00320 0x19, 0x01,
00321 0x29, 0x05,
00322 0x91, 0x02,
00323 0x95, 0x01,
00324 0x75, 0x03,
00325 0x91, 0x03,
00326 0x95, 0x06,
00327 0x75, 0x08,
00328 0x15, 0x00,
00329 0x25, 0x65,
00330 0x05, 0x07,
00331 0x19, 0x00,
00332 0x29, 0x65,
00333 0x81, 0x00,
00334 0xc0
00335 };
00336
00343 uint8_t usbFunctionSetup(uint8_t data[8]) {
00344 usbRequest_t *rq = (void *)data;
00345 usbMsgPtr = reportBuffer;
00346 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {
00347
00348 if (rq->bRequest == USBRQ_HID_GET_REPORT) {
00349
00350
00351 return sizeof(reportBuffer);
00352 } else if (rq->bRequest == USBRQ_HID_SET_REPORT) {
00353 if (rq->wLength.word == 1) {
00354
00355 expectReport = 1;
00356 return 0xff;
00357 }
00358 } else if (rq->bRequest == USBRQ_HID_GET_IDLE) {
00359 usbMsgPtr = &idleRate;
00360 return 1;
00361 } else if (rq->bRequest == USBRQ_HID_SET_IDLE) {
00362 idleRate = rq->wValue.bytes[1];
00363 } else if (rq->bRequest == USBRQ_HID_GET_PROTOCOL) {
00364 if (rq->wValue.bytes[1] < 1) {
00365 protocolVer = rq->wValue.bytes[1];
00366 }
00367 } else if(rq->bRequest == USBRQ_HID_SET_PROTOCOL) {
00368 usbMsgPtr = &protocolVer;
00369 return 1;
00370 }
00371 } else {
00372
00373 }
00374 return 0;
00375 }
00376
00384 uint8_t usbFunctionWrite(uchar *data, uchar len) {
00385 if (expectReport && (len == 1)) {
00386 LEDstate = data[0];
00387 if (LEDstate & LED_NUM) {
00388 PORTLEDS &= ~(1 << LEDNUM);
00389 } else {
00390 PORTLEDS |= (1 << LEDNUM);
00391 }
00392 if (LEDstate & LED_CAPS) {
00393 PORTLEDS &= ~(1 << LEDCAPS);
00394 } else {
00395 PORTLEDS |= (1 << LEDCAPS);
00396 }
00397 if (LEDstate & LED_SCROLL) {
00398 PORTLEDS &= ~(1 << LEDSCROLL);
00399 } else {
00400 PORTLEDS |= (1 << LEDSCROLL);
00401 }
00402 }
00403 expectReport = 0;
00404 return 0x01;
00405 }
00406
00413 void usbSendReport(uint8_t mode, uint8_t key) {
00414
00415 uint8_t repBuffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
00416 repBuffer[0] = mode;
00417 repBuffer[2] = key;
00418 while (!usbInterruptIsReady());
00419 usbSetInterrupt(repBuffer, sizeof(repBuffer));
00420 }
00421
00422
00423
00424 uint8_t curmatrix[16];
00425
00433 const uint8_t PROGMEM keymatrix[16][8] = {
00434
00435 {KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved },
00436 {KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_Reserved },
00437 {KEY_ESCAPE, KEY_Tab, KEY_grave, KEY_1, KEY_Q, KEY_A, KEY_Z, KEY_Reserved },
00438 {KEY_Euro, KEY_capslock, KEY_F1, KEY_2, KEY_W, KEY_S, KEY_X, KEY_Reserved },
00439 {KEY_F4, KEY_F3, KEY_F2, KEY_3, KEY_E, KEY_D, KEY_C, KEY_Reserved },
00440 {KEY_G, KEY_T, KEY_5, KEY_4, KEY_R, KEY_F, KEY_V, KEY_B },
00441 {KEY_F5, KEY_DELETE, KEY_F9, KEY_F10, KEY_Reserved, KEY_Reserved, KEY_Return, KEY_Spacebar },
00442 {KEY_H, KEY_Y, KEY_6, KEY_7, KEY_U, KEY_J, KEY_M, KEY_N },
00443 {KEY_F6, KEY_rbracket, KEY_equals, KEY_8, KEY_I, KEY_K, KEY_comma, KEY_Reserved },
00444 {KEY_Reserved, KEY_F7, KEY_F8, KEY_9, KEY_O, KEY_L, KEY_dot, KEY_Reserved },
00445 {KEY_apostroph, KEY_lbracket, KEY_minus, KEY_0, KEY_P, KEY_semicolon, KEY_hash, KEY_slash },
00446 {KEY_Reserved, KEY_KP4, KEY_DeleteForward, KEY_F11, KEY_KP7, KEY_KP1, KEY_NumLock, KEY_DownArrow },
00447 {KEY_KP0, KEY_KP5, KEY_Insert, KEY_F12, KEY_KP8, KEY_KP2, KEY_KPslash, KEY_RightArrow },
00448 {KEY_KPcomma, KEY_KP6, KEY_PageUp, KEY_PageDown, KEY_KP9, KEY_KP3, KEY_KPasterisk, KEY_KPminus },
00449 {KEY_UpArrow, KEY_Reserved, KEY_Home, KEY_End, KEY_KPplus, KEY_KPenter, KEY_Pause, KEY_LeftArrow },
00450 {KEY_Reserved, KEY_Reserved, KEY_Reserved, KEY_PrintScreen, KEY_ScrollLock, KEY_Reserved, KEY_Reserved, KEY_Reserved },
00451 };
00452
00458 const uint8_t PROGMEM modmatrix[16][8] = {
00459
00460 {MOD_NONE, MOD_NONE, MOD_CONTROL_LEFT, MOD_NONE, MOD_NONE, MOD_NONE, MOD_CONTROL_RIGHT, MOD_NONE },
00461 {MOD_NONE, MOD_SHIFT_LEFT, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_SHIFT_RIGHT, MOD_NONE },
00462 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00463 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00464 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00465 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00466 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00467 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00468 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00469 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00470 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00471 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00472 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00473 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00474 {MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE },
00475 {MOD_ALT_LEFT, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_NONE, MOD_ALT_RIGHT},
00476 };
00477
00482 typedef struct {
00483 uint8_t mode;
00484 uint8_t key;
00485 } Key;
00486
00493 Key charToKey(char character) {
00494 Key key;
00495
00496 key.mode = MOD_NONE;
00497 key.key = KEY_Reserved;
00498 if ((character >= 'a') && (character <= 'z')) {
00499
00500 key.key = (character - 'a') + 0x04;
00501 } else if ((character >= 'A') && (character <= 'Z')) {
00502
00503 key.mode = MOD_SHIFT_LEFT;
00504 key.key = (character - 'A') + 0x04;
00505 } else if ((character >= '1') && (character <= '9')) {
00506
00507 key.key = (character - '1') + 0x1E;
00508 }
00509
00510 switch (character) {
00511 case '0':
00512 key.key = KEY_0; break;
00513 case '!':
00514 key.mode = MOD_SHIFT_LEFT;
00515 key.key = KEY_1; break;
00516
00517
00518
00519
00520
00521
00522
00523
00524 case '$':
00525 key.mode = MOD_SHIFT_LEFT;
00526 key.key = KEY_4; break;
00527 case '%':
00528 key.mode = MOD_SHIFT_LEFT;
00529 key.key = KEY_5; break;
00530 case '^':
00531 key.mode = MOD_SHIFT_LEFT;
00532 key.key = KEY_6; break;
00533 case '&':
00534 key.mode = MOD_SHIFT_LEFT;
00535 key.key = KEY_7; break;
00536 case '*':
00537 key.mode = MOD_SHIFT_LEFT;
00538 key.key = KEY_8; break;
00539 case '(':
00540 key.mode = MOD_SHIFT_LEFT;
00541 key.key = KEY_9; break;
00542 case ')':
00543 key.mode = MOD_SHIFT_LEFT;
00544 key.key = KEY_0; break;
00545 case ' ':
00546 key.key = KEY_Spacebar; break;
00547 case '-':
00548 key.key = KEY_minus; break;
00549 case '_':
00550 key.mode = MOD_SHIFT_LEFT;
00551 key.key = KEY_minus; break;
00552 case '=':
00553 key.key = KEY_equals; break;
00554 case '+':
00555 key.mode = MOD_SHIFT_LEFT;
00556 key.key = KEY_equals; break;
00557 case '[':
00558 key.key = KEY_lbracket; break;
00559 case '{':
00560 key.mode = MOD_SHIFT_LEFT;
00561 key.key = KEY_lbracket; break;
00562 case ']':
00563 key.key = KEY_rbracket; break;
00564 case '}':
00565 key.mode = MOD_SHIFT_LEFT;
00566 key.key = KEY_rbracket; break;
00567 case '\\':
00568 key.key = KEY_backslash; break;
00569 case '|':
00570 key.mode = MOD_SHIFT_LEFT;
00571 key.key = KEY_backslash; break;
00572 case '#':
00573 key.key = KEY_hash; break;
00574 case '@':
00575 key.mode = MOD_SHIFT_LEFT;
00576 key.key = KEY_hash; break;
00577 case ';':
00578 key.key = KEY_semicolon; break;
00579 case ':':
00580 key.mode = MOD_SHIFT_LEFT;
00581 key.key = KEY_semicolon; break;
00582 case '\'':
00583 key.key = KEY_apostroph; break;
00584 case '"':
00585 key.mode = MOD_SHIFT_LEFT;
00586 key.key = KEY_apostroph; break;
00587 case '`':
00588 key.key = KEY_grave; break;
00589 case '~':
00590 key.mode = MOD_SHIFT_LEFT;
00591 key.key = KEY_grave; break;
00592 case ',':
00593 key.key = KEY_comma; break;
00594 case '<':
00595 key.mode = MOD_SHIFT_LEFT;
00596 key.key = KEY_comma; break;
00597 case '.':
00598 key.key = KEY_dot; break;
00599 case '>':
00600 key.mode = MOD_SHIFT_LEFT;
00601 key.key = KEY_dot; break;
00602 case '/':
00603 key.key = KEY_slash; break;
00604 case '?':
00605 key.mode = MOD_SHIFT_LEFT;
00606 key.key = KEY_slash; break;
00607 }
00608 if (key.key == KEY_Reserved) {
00609
00610 key.mode = MOD_SHIFT_LEFT;
00611 key.key = KEY_slash;
00612 }
00613 return key;
00614 }
00615
00621 void sendKey(Key keytosend) {
00622 usbSendReport(keytosend.mode, keytosend.key);
00623 usbSendReport(0, 0);
00624 }
00625
00631 void sendString(char* string) {
00632 for (uint8_t i = 0; i < strlen(string); i++) {
00633 Key key = charToKey(string[i]);
00634 sendKey(key);
00635 }
00636 }
00637
00642 void printMatrix(void) {
00643 for (uint8_t i = 0; i <= 15; i++) {
00644 char buffer[10];
00645
00646
00647
00648
00649
00650
00651
00652
00653
00654
00655
00656 sprintf(buffer, "%2x", curmatrix[i]);
00657 sendString(buffer);
00658 if (i == 7) {
00659 sendString(":");
00660 } else {
00661 sendString(".");
00662 }
00663 }
00664 sendString("---");
00665 }
00666
00679 uint8_t scankeys(void) {
00680 static uint8_t debounce = 5;
00681 uint8_t retval = 0;
00682 for (uint8_t row = 0; row <= 15; row++) {
00683 if (row <= 7) {
00684 DDRROWS1 = (1 << row);
00685 PORTROWS1 = ~(1 << row);
00686 DDRROWS2 = 0x00;
00687 PORTROWS2 = 0xff;
00688 } else {
00689 DDRROWS1 = 0x00;
00690 PORTROWS1 = 0xff;
00691
00692
00693
00694
00695 DDRROWS2 = (1 << (15 - row));
00696 PORTROWS2 = ~(1 << (15 - row));
00697 }
00698 _delay_us(30);
00699 uint8_t data = ~PINCOLUMNS;
00700 if (data != curmatrix[row]) {
00701
00702 debounce = 10;
00703 curmatrix[row] = data;
00704 }
00705 }
00706 if (debounce) {
00707
00708 debounce--;
00709 }
00710 if (debounce == 1) {
00711
00712 uint8_t reportIndex = 2;
00713 memset(reportBuffer, 0, sizeof(reportBuffer));
00714 for (uint8_t row = 0; row <= 15; row++) {
00715 uint8_t data = curmatrix[row];
00716 if (data != 0xff) {
00717 for (uint8_t col = 0; col <= 7; col++) {
00718 uint8_t key, modifier;
00719 if (data & (1 << col)) {
00720 key = pgm_read_byte(&keymatrix[row][col]);
00721 modifier = pgm_read_byte(&modmatrix[row][col]);
00722 } else {
00723 key = KEY_Reserved;
00724 modifier = MOD_NONE;
00725 }
00726 if (key != KEY_Reserved) {
00727 if (reportIndex >= sizeof(reportBuffer)) {
00728 if (!retval & 0x02) {
00729 memset(reportBuffer+2, KEY_ErrorRollOver, sizeof(reportBuffer)-2);
00730 retval |= 0x02;
00731 }
00732 } else {
00733 reportBuffer[reportIndex] = key;
00734 reportIndex++;
00735 }
00736 }
00737 if (modifier != MOD_NONE) {
00738 reportBuffer[0] |= modifier;
00739 }
00740 }
00741 }
00742 }
00743 retval |= 0x01;
00744 }
00745 return retval;
00746 }
00747
00748
00749
00755 int main(void) {
00756 uint8_t updateNeeded = 0;
00757 uint8_t idleCounter = 0;
00758 wdt_enable(WDTO_2S);
00759 hardwareInit();
00760 usbInit();
00761 sei();
00762
00763 scankeys();
00764 while (1) {
00765
00766 wdt_reset();
00767 usbPoll();
00768
00769 updateNeeded = scankeys();
00770
00771
00772 if (TIFR & (1 << TOV0)) {
00773 TIFR = (1 << TOV0);
00774 if (idleRate != 0) {
00775 if(idleCounter > 4){
00776 idleCounter -= 5;
00777 } else {
00778 updateNeeded = 1;
00779 idleCounter = idleRate;
00780 }
00781 }
00782 }
00783
00784 if (updateNeeded && usbInterruptIsReady()) {
00785 updateNeeded = 0;
00786 usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
00787 }
00788 }
00789 return 0;
00790 }
00791
00792