00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00108 #include <avr/io.h>
00109 #include <avr/interrupt.h>
00110 #include <avr/pgmspace.h>
00111 #include <avr/eeprom.h>
00112 #include <avr/wdt.h>
00113
00114 #include <string.h>
00115
00116 #include "usbdrv.h"
00117 #include "irrx.h"
00118 #include "oddebug.h"
00119 #include "uart_io.h"
00120
00121 #define elements_of(array) (sizeof(array) / sizeof(array[0]))
00122
00123 #define LED_RED_CHANGE() PORTB ^= _BV(PB2)
00124 #define LED_RED_ON() PORTB |= _BV(PB2)
00125 #define LED_RED_OFF() PORTB &= ~_BV(PB2)
00126 #define LED_RED_INIT() DDRB |= _BV(PB2) | _BV(PB1);PORTB &= ~_BV(PB1);LED_RED_OFF()
00127
00128 #define LED_GREEN_CHANGE() PORTC ^= _BV(PC3)
00129 #define LED_GREEN_ON() PORTC |= _BV(PC3)
00130 #define LED_GREEN_OFF() PORTC &= ~_BV(PC3)
00131 #define LED_GREEN_INIT() PORTC |= _BV(PC3);LED_RED_OFF()
00132
00133 #define SWITCH_PGM_IS_PRESSED() bit_is_clear(PINC,4)
00134 #define SWITCH_PGM_INIT() DDRC &=~_BV(PC4);PORTC|=_BV(PC4)
00135
00136
00137
00138
00139 #define STATIC_ASSERT(expr) extern char static_assert[ (!!(expr))*2 - 1]
00140
00141 typedef struct
00142 {
00143 uint8_t put;
00144 uint8_t get;
00145 uint8_t data[128];
00146 } virtual_keyboard_buffer_t;
00147
00148 static int virtual_keyboard_ioputchar(char c, FILE *stream);
00149
00150 static virtual_keyboard_buffer_t virtual_keyboard_buffer =
00151 { 0, 0,
00152 { 0 } };
00153
00154 STATIC_ASSERT(sizeof(virtual_keyboard_buffer.data) == 128 || sizeof(virtual_keyboard_buffer.data) == 256 || sizeof(virtual_keyboard_buffer.data) == 64);
00155
00156 static FILE virtual_keyboard_file_io= FDEV_SETUP_STREAM(virtual_keyboard_ioputchar, NULL, _FDEV_SETUP_WRITE);
00157
00158 static int virtual_keyboard_ioputchar(char c, FILE *stream)
00159 {
00160 uint8_t next = (virtual_keyboard_buffer.put + 1)
00161 & (sizeof(virtual_keyboard_buffer.data) - 1);
00162 if (c == '\n')
00163 {
00164 c = '\r';
00165 }
00166 if (next == virtual_keyboard_buffer.get)
00167 {
00168 return 0;
00169 }
00170 virtual_keyboard_buffer.data[virtual_keyboard_buffer.put] = c;
00171 virtual_keyboard_buffer.put = next;
00172 return 0;
00173 }
00174
00175 static int virtual_keyboard_buffer_not_empty(void)
00176 {
00177 return (virtual_keyboard_buffer.put != virtual_keyboard_buffer.get);
00178 }
00179
00180 static int virtual_keyboard_iogetchar(void)
00181 {
00182 if (virtual_keyboard_buffer.put == virtual_keyboard_buffer.get)
00183 {
00184 return -1;
00185 }
00186 else
00187 {
00188 int c;
00189 c = virtual_keyboard_buffer.data[virtual_keyboard_buffer.get];
00190 virtual_keyboard_buffer.get = (virtual_keyboard_buffer.get + 1)
00191 & (sizeof(virtual_keyboard_buffer.data) - 1);
00192 return c;
00193 }
00194 }
00195
00196 #define LEFT_SHIFT_BIT 0x80
00197
00198 #define USB_HID_KEY_a_A 0x04
00199 #define USB_HID_KEY_0 0x27
00200 #define USB_HID_KEY_1 0x1E
00201 #define USB_HID_KEY_RETURN 0x28
00202 #define USB_HID_KEY_SPACEBAR 0x2C
00203 #define USB_HID_KEY_DOT 0x37
00204 #define USB_HID_KEY_COMMA 0x36
00205
00207
00208
00214 static uint8_t virtual_keyboard_translate_to_hid(int c)
00215 {
00216 if (c <= 0)
00217 {
00218 return 0;
00219 }
00220 else if ('a' <= c && c <= 'z')
00221 {
00222 return (c - 'a' + USB_HID_KEY_a_A);
00223 }
00224 else if ('A' <= c && c <= 'Z')
00225 {
00226 return (c - 'A' + USB_HID_KEY_a_A) | LEFT_SHIFT_BIT;
00227 }
00228 else if ('1' <= c && c <= '9')
00229 {
00230 return (c - '1' + USB_HID_KEY_1);
00231 }
00232 else if ('0' == c)
00233 {
00234 return (USB_HID_KEY_0);
00235 }
00236 else if ('.' == c)
00237 {
00238 return (USB_HID_KEY_DOT);
00239 }
00240 else if (',' == c)
00241 {
00242 return (USB_HID_KEY_COMMA);
00243 }
00244 else if ('\r' == c)
00245 {
00246 return (USB_HID_KEY_RETURN);
00247 }
00248 else if (' ' == c || '\t' == c)
00249 {
00250 return (USB_HID_KEY_SPACEBAR);
00251 }
00252 else
00253 {
00254 return (USB_HID_KEY_SPACEBAR);
00255 }
00256 }
00257
00258 static uchar vtLastKey = 0;
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287 static void hardwareInit(void)
00288 {
00289 uchar i, j;
00290 PORTD = 0xfa;
00291
00292 DDRD = 0x07;
00293
00294 j = 0;
00295 while (--j)
00296 {
00297 i = 0;
00298 while (--i)
00299 ;
00300 }
00301 DDRD = 0x02;
00302
00303
00304 TCCR0 = 5;
00305
00306 }
00307
00308
00309
00310 #define NUM_HARDWARE_KEYS 17
00311
00312 #define NUM_KEYS (NUM_HARDWARE_KEYS + NUM_IR_KEYS)
00313
00314
00315
00316
00317
00318 static uchar reportBuffer[2];
00319 static uchar idleRate;
00320
00321
00322
00323 const char label00[] PROGMEM = "Press button\n";
00324 const char label01[] PROGMEM = "Scan Next Track";
00325 const char label02[] PROGMEM = "Scan Previous Track";
00326 const char label03[] PROGMEM = "Rewind";
00327 const char label04[] PROGMEM = "Play";
00328 const char label05[] PROGMEM = "Fast Forward";
00329 const char label06[] PROGMEM = "Pause";
00330 const char label07[] PROGMEM = "Record";
00331 const char label08[] PROGMEM = "Stop";
00332 const char label09[] PROGMEM = "Menu";
00333 const char label10[] PROGMEM = "Menu Escape";
00334 const char label11[] PROGMEM = "Menu Up";
00335 const char label12[] PROGMEM = "Menu Down";
00336 const char label13[] PROGMEM = "Menu Left";
00337 const char label14[] PROGMEM = "Menu Right";
00338 const char label15[] PROGMEM = "Menu Pick";
00339 const char label16[] PROGMEM = "Menu Value Decrease";
00340 const char label17[] PROGMEM = "Menu Value Increase";
00341 const char label18[] PROGMEM = "Volume Down";
00342 const char label19[] PROGMEM = "Volume Up";
00343 const char label20[] PROGMEM = "Mute";
00344 const char label21[] PROGMEM = "Channel Decrement";
00345 const char label22[] PROGMEM = "Channel Increment";
00346 const char label23[] PROGMEM = "Closed Caption Select";
00347 const char label24[] PROGMEM = "Closed Caption";
00348 const char label25[] PROGMEM = "DONE\n\n";
00349
00350 PGM_P button_labels[] PROGMEM =
00351 {
00352 label00,
00353 label01,
00354 label02,
00355 label03,
00356 label04,
00357 label05,
00358 label06,
00359 label07,
00360 label08,
00361 label09,
00362 label10,
00363 label11,
00364 label12,
00365 label13,
00366 label14,
00367 label15,
00368 label16,
00369 label17,
00370 label18,
00371 label19,
00372 label20,
00373 label21,
00374 label22,
00375 label23,
00376 label24,
00377 label25
00378 };
00379
00380 #define NUM_IR_KEYS elements_of(button_labels)
00381
00382 static irrx_code_t ir_codes[NUM_IR_KEYS];
00383
00384 static uchar get_ir_key(irrx_code_t ircode)
00385 {
00386 uchar i;
00387 for (i = 0; i < elements_of(ir_codes); i++)
00388 {
00389 if (ircode != IRRX_NO_CODE && ir_codes[i] == ircode)
00390 return i + 1;
00391 }
00392 return 0;
00393 }
00394
00395 static void clear_ir_codes(void)
00396 {
00397 memset(ir_codes, 0, sizeof(ir_codes));
00398 }
00399
00400 static irrx_code_t ir_code= IRRX_NO_CODE;
00401 static uchar ir_key_pressed = 0;
00402
00403 enum
00404 {
00405 ProgramingMode_Not = 0,
00406 ProgramingMode_LAST = NUM_IR_KEYS
00407
00408 };
00409
00418 #define ReportDescriptor usbHidReportDescriptor
00419
00420 PROGMEM
00421 #include "ir_keyboard_2.hid.h"
00422
00423 STATIC_ASSERT(sizeof(usbHidReportDescriptor) == USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH);
00424
00425 static void print_button_label(uint8_t programming_mode_type)
00426 {
00427
00428 PGM_P p;
00429 memcpy_P(&p, &button_labels[programming_mode_type], sizeof(PGM_P));
00430 fprintf_P(stdout,p);
00431 }
00432
00433 typedef enum
00434 {
00435 report_id_none = 0,
00436 report_id_irremote = 1,
00437 report_id_virtualkeyboard = 2
00438 } report_id_t;
00439
00440 static void buildReport(report_id_t id, uchar irkey, uchar vtLastKey)
00441 {
00442 reportBuffer[0] = id;
00443 if (id == report_id_irremote)
00444 {
00445 reportBuffer[1] = irkey;
00446 }
00447 else if (id == report_id_virtualkeyboard)
00448 {
00449 reportBuffer[1] = vtLastKey;
00450 }
00451 }
00452
00453 uchar usbFunctionSetup(uchar data[8])
00454 {
00455 usbRequest_t* rq = (void *)data;
00456 usbMsgPtr = reportBuffer;
00457 if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS)
00458 {
00459
00460 if(rq->bRequest == USBRQ_HID_GET_REPORT)
00461 {
00462
00463
00464 buildReport(rq->wValue.bytes[0],ir_key_pressed,vtLastKey);
00465 return sizeof(reportBuffer);
00466 }
00467 else if(rq->bRequest == USBRQ_HID_GET_IDLE)
00468 {
00469 usbMsgPtr = &idleRate;
00470 return 1;
00471 }
00472 else if(rq->bRequest == USBRQ_HID_SET_IDLE)
00473 {
00474 idleRate = rq->wValue.bytes[1];
00475 }
00476 }
00477 else
00478 {
00479
00480 }
00481 return 0;
00482 }
00483
00484
00485
00486 #define IR_TIMER_TIMEOUT 10 //10 x 22ms
00487 #define BLINK_TIMER_TIMEOUT 30 //5 x 22ms
00488
00489 int main(void)
00490 {
00491 uchar key = 0;
00492 uchar lastKey = 0;
00493 report_id_t keyDidChange = report_id_none;
00494 uchar idleCounter = 0;
00495 unsigned int virtual_keyboard_timer = 0;
00496 unsigned int ir_timer=0;
00497 unsigned int programming_mode_type = 0;
00498 unsigned int blink_timer=0;
00499 irrx_code_t last_ir_code = 0;
00500 usbDeviceDisconnect();
00501 wdt_enable(WDTO_2S);
00502 hardwareInit();odDebugInit();
00503 usbInit();
00504 irrx_init();
00505 irrx_power_on();
00506 LED_RED_INIT();
00507 LED_GREEN_INIT();
00508 SWITCH_PGM_INIT();
00509 sei();
00510 DBG1(0x00, 0, 0);
00511 eeprom_read_block(&ir_codes, 0, sizeof(ir_codes));
00512
00513 stdout = &virtual_keyboard_file_io;
00514 uart_io_init();
00515 usbDeviceConnect();
00516
00517 for (;;)
00518 {
00519
00520 wdt_reset();
00521
00522
00524 usbPoll();
00525
00526
00528 ir_code = irrx_getcode();
00529 if (ir_code != last_ir_code)
00530 {
00531 last_ir_code = ir_code;
00532 ir_key_pressed = get_ir_key(ir_code);
00533 if (ir_key_pressed != 0)
00534 {
00535 LED_RED_ON();
00536 }
00537 else
00538 {
00539 LED_RED_OFF();
00540 }
00541 if (programming_mode_type > ProgramingMode_Not)
00542 {
00543 if (ir_code != IRRX_NO_CODE)
00544 {
00545 if (ir_key_pressed == 0)
00546 {
00547
00548 ir_codes[programming_mode_type - 1] = ir_code;
00549 fprintf_P(stdout,PSTR(" 0x%04x\n"),ir_code);
00550 programming_mode_type++;
00551 print_button_label(programming_mode_type);
00552 if (programming_mode_type >= ProgramingMode_LAST)
00553 {
00554 eeprom_write_block(&ir_codes, 0, sizeof(ir_codes));
00555 programming_mode_type = ProgramingMode_Not;
00556 }
00557 }
00558 else
00559 {
00560
00561 fprintf_P(stdout,PSTR("\n"));
00562 print_button_label(programming_mode_type);
00563 }
00564 }
00565 }
00566 else
00567 {
00568
00569 keyDidChange = report_id_irremote;
00570 }
00571 }
00572
00573
00575 key = SWITCH_PGM_IS_PRESSED();
00576 if (lastKey != key)
00577 {
00578 if (key)
00579 {
00580 if (programming_mode_type == ProgramingMode_Not)
00581 {
00582 clear_ir_codes();
00583 fprintf_P(stdout,PSTR("\nIR Keyboard (C) 2007 jorgen.birkler@gmail.com\n"));
00584 print_button_label(programming_mode_type);
00585 programming_mode_type++;
00586 print_button_label(programming_mode_type);
00587 }
00588 else
00589 {
00590 programming_mode_type = ProgramingMode_Not;
00591 LED_RED_OFF();
00592 }
00593 }
00594 lastKey = key;
00595 }
00596
00598 if (virtual_keyboard_buffer_not_empty() && virtual_keyboard_timer == 0)
00599 {
00600 virtual_keyboard_timer = 3;
00601 }
00602
00603
00605 if (keyDidChange && usbInterruptIsReady())
00606 {
00607
00608 buildReport(keyDidChange, ir_key_pressed, vtLastKey);
00609 usbSetInterrupt(reportBuffer, sizeof(reportBuffer));
00610 keyDidChange = 0;
00611 }
00612
00613
00615
00616 if (TIFR & _BV(TOV0))
00617 {
00618
00619 TIFR = 1<<TOV0;
00620 if (programming_mode_type != ProgramingMode_Not)
00621 {
00622 if (blink_timer == 0)
00623 {
00624 LED_RED_CHANGE();
00625 blink_timer = BLINK_TIMER_TIMEOUT;
00626 }
00627 blink_timer--;
00628 }
00629 if (virtual_keyboard_timer > 0)
00630 {
00631 virtual_keyboard_timer--;
00632 if (virtual_keyboard_timer == 1)
00633 {
00634 vtLastKey = 0;
00635 keyDidChange = report_id_virtualkeyboard;
00636 }
00637 else if (virtual_keyboard_timer == 0)
00638 {
00639 keyDidChange = report_id_virtualkeyboard;
00640 vtLastKey
00641 = virtual_keyboard_translate_to_hid(virtual_keyboard_iogetchar());
00642 if (vtLastKey != 0)
00643 {
00644 virtual_keyboard_timer = 2;
00645 }
00646 }
00647 }
00648
00649 if (ir_timer > 0)
00650 {
00651 ir_timer--;
00652 if (ir_timer == 0)
00653 {
00654 LED_RED_OFF();
00655 LED_GREEN_OFF();
00656 ir_key_pressed = 0;
00657 ir_code = IRRX_NO_CODE;
00658 keyDidChange = 1;
00659 }
00660 }
00661 if (idleRate != 0)
00662 {
00663 if (idleCounter > 4)
00664 {
00665 idleCounter -= 5;
00666 }
00667 else
00668 {
00669 idleCounter = idleRate;
00670
00671 }
00672 }
00673 }
00674 }
00675 return 0;
00676 }
00677
00678
00679