#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>
#include <string.h>
#include "usbdrv.h"
#include "irrx.h"
#include "oddebug.h"
#include "uart_io.h"
#include "ir_keyboard_2.hid.h"
Go to the source code of this file.
Data Structures | |
struct | virtual_keyboard_buffer_t |
Defines | |
#define | elements_of(array) (sizeof(array) / sizeof(array[0])) |
#define | LED_RED_CHANGE() PORTB ^= _BV(PB2) |
#define | LED_RED_ON() PORTB |= _BV(PB2) |
#define | LED_RED_OFF() PORTB &= ~_BV(PB2) |
#define | LED_RED_INIT() DDRB |= _BV(PB2) | _BV(PB1);PORTB &= ~_BV(PB1);LED_RED_OFF() |
#define | LED_GREEN_CHANGE() PORTC ^= _BV(PC3) |
#define | LED_GREEN_ON() PORTC |= _BV(PC3) |
#define | LED_GREEN_OFF() PORTC &= ~_BV(PC3) |
#define | LED_GREEN_INIT() PORTC |= _BV(PC3);LED_RED_OFF() |
#define | SWITCH_PGM_IS_PRESSED() bit_is_clear(PINC,4) |
#define | SWITCH_PGM_INIT() DDRC &=~_BV(PC4);PORTC|=_BV(PC4) |
#define | STATIC_ASSERT(expr) extern char static_assert[ (!!(expr))*2 - 1] |
#define | LEFT_SHIFT_BIT 0x80 |
#define | USB_HID_KEY_a_A 0x04 |
#define | USB_HID_KEY_0 0x27 |
#define | USB_HID_KEY_1 0x1E |
#define | USB_HID_KEY_RETURN 0x28 |
#define | USB_HID_KEY_SPACEBAR 0x2C |
#define | USB_HID_KEY_DOT 0x37 |
#define | USB_HID_KEY_COMMA 0x36 |
#define | NUM_HARDWARE_KEYS 17 |
#define | NUM_KEYS (NUM_HARDWARE_KEYS + NUM_IR_KEYS) |
#define | NUM_IR_KEYS elements_of(button_labels) |
#define | ReportDescriptor usbHidReportDescriptor |
#define | IR_TIMER_TIMEOUT 10 |
#define | BLINK_TIMER_TIMEOUT 30 |
Enumerations | |
enum | { ProgramingMode_Not = 0, ProgramingMode_LAST = NUM_IR_KEYS } |
enum | report_id_t { report_id_none = 0, report_id_irremote = 1, report_id_virtualkeyboard = 2 } |
Functions | |
STATIC_ASSERT (sizeof(virtual_keyboard_buffer.data)==128||sizeof(virtual_keyboard_buffer.data)==256||sizeof(virtual_keyboard_buffer.data)==64) | |
PROGMEM | STATIC_ASSERT (sizeof(usbHidReportDescriptor)==USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH) |
uchar | usbFunctionSetup (uchar data[8]) |
int | main (void) |
Variables | |
const char label00[] | PROGMEM = "Press button\n" |
#define elements_of | ( | array | ) | (sizeof(array) / sizeof(array[0])) |
#define LED_GREEN_INIT | ( | ) | PORTC |= _BV(PC3);LED_RED_OFF() |
#define LED_GREEN_OFF | ( | ) | PORTC &= ~_BV(PC3) |
#define LED_RED_CHANGE | ( | ) | PORTB ^= _BV(PB2) |
#define LED_RED_INIT | ( | ) | DDRB |= _BV(PB2) | _BV(PB1);PORTB &= ~_BV(PB1);LED_RED_OFF() |
#define LED_RED_OFF | ( | ) | PORTB &= ~_BV(PB2) |
#define LED_RED_ON | ( | ) | PORTB |= _BV(PB2) |
#define ReportDescriptor usbHidReportDescriptor |
The 2 byte report looks like this:
------------------------------------------------------------------------------------------ | Shift 0/1 | Keyboard (0-127) | IR consumer code (0-0xFF) | ------------------------------------------------------------------------------------------
#define STATIC_ASSERT | ( | expr | ) | extern char static_assert[ (!!(expr))*2 - 1] |
#define SWITCH_PGM_INIT | ( | ) | DDRC &=~_BV(PC4);PORTC|=_BV(PC4) |
#define SWITCH_PGM_IS_PRESSED | ( | ) | bit_is_clear(PINC,4) |
anonymous enum |
Definition at line 403 of file main.c.
00404 { 00405 ProgramingMode_Not = 0, 00406 ProgramingMode_LAST = NUM_IR_KEYS 00407 00408 };
enum report_id_t |
Definition at line 433 of file main.c.
00434 { 00435 report_id_none = 0, 00436 report_id_irremote = 1, 00437 report_id_virtualkeyboard = 2 00438 } report_id_t;
int main | ( | void | ) |
Definition at line 489 of file main.c.
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 /* main event loop */ 00517 for (;;) 00518 { 00519 //Watchdog 00520 wdt_reset(); 00521 00522 //usb 00524 usbPoll(); 00525 00526 //IR Remote 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) //Is key already programmed? 00546 { 00547 //No, 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 //Yes 00561 fprintf_P(stdout,PSTR("\n")); 00562 print_button_label(programming_mode_type); 00563 } 00564 } 00565 } 00566 else 00567 { 00568 //fprintf_P(stdout,PSTR("A")); 00569 keyDidChange = report_id_irremote; 00570 } 00571 } 00572 00573 //Key presses 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 //Virtual keyboard (printf) 00598 if (virtual_keyboard_buffer_not_empty() && virtual_keyboard_timer == 0) 00599 { 00600 virtual_keyboard_timer = 3; 00601 } 00602 00603 //USB interrupt 00605 if (keyDidChange && usbInterruptIsReady()) 00606 { 00607 /* use last key and not current key status in order to avoid lost changes in key status. */ 00608 buildReport(keyDidChange, ir_key_pressed, vtLastKey); 00609 usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 00610 keyDidChange = 0; 00611 } 00612 00613 //Timer 00615 00616 if (TIFR & _BV(TOV0)) 00617 { 00618 /* 22 ms timer */ 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; /* 22 ms in units of 4 ms */ 00666 } 00667 else 00668 { 00669 idleCounter = idleRate; 00670 //keyDidChange = 1; 00671 } 00672 } 00673 } 00674 } 00675 return 0; 00676 }
PROGMEM STATIC_ASSERT | ( | sizeof(usbHidReportDescriptor) | = =USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH |
) |
STATIC_ASSERT | ( | sizeof(virtual_keyboard_buffer.data) | = =128||sizeof(virtual_keyboard_buffer.data)==256||sizeof(virtual_keyboard_buffer.data)==64 |
) |
uchar usbFunctionSetup | ( | uchar | data[8] | ) |
Definition at line 453 of file main.c.
00454 { 00455 usbRequest_t* rq = (void *)data; 00456 usbMsgPtr = reportBuffer; 00457 if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) 00458 { 00459 /* class request type */ 00460 if(rq->bRequest == USBRQ_HID_GET_REPORT) 00461 { 00462 /* wValue: ReportType (highbyte), ReportID (lowbyte) */ 00463 /* we only have one report type, so don't look at wValue */ 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 /* no vendor specific requests implemented */ 00480 } 00481 return 0; 00482 }