Changeset 08d5388 in avrstuff for aktoserial/code/main.c
- Timestamp:
- Jul 31, 2010, 9:35:39 AM (14 years ago)
- Branches:
- main
- Children:
- 38f2eef
- Parents:
- c6e02cf
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
aktoserial/code/main.c
rc6e02cf r08d5388 1 #define F_CPU 16000000UL2 3 1 #include <avr/io.h> 2 #include <avr/interrupt.h> 3 #include <avr/wdt.h> 4 #include <avr/pgmspace.h> 5 #include <util/delay.h> 6 7 #include <string.h> 4 8 5 9 #include "amiga_keyboard/amiga_keyboard.h" 6 #include "usart/usart.h" 10 #include "usbdrv/usbdrv.h" 11 #include "keycodes.h" 12 13 const uint8_t PROGMEM keymatrix[128] = { 14 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 15 KEY_grave, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, KEY_minus, KEY_equals, KEY_backslash, KEY_Reserved, KEY_KP0, //0 16 KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_rbracket, KEY_lbracket, KEY_Reserved, KEY_KP1, KEY_KP2, KEY_KP3, //1 17 KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, KEY_semicolon, KEY_apostroph,KEY_hash, KEY_Reserved, KEY_KP4, KEY_KP5, KEY_KP6, //2 18 KEY_Euro, KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, KEY_comma, KEY_dot, KEY_slash, KEY_Reserved, KEY_KPcomma, KEY_KP7, KEY_KP8, KEY_KP9, //3 19 KEY_Spacebar,KEY_DeleteForward,KEY_Tab, KEY_KPenter, KEY_Return,KEY_ESCAPE,KEY_DELETE, KEY_Reserved,KEY_Reserved,KEY_Reserved, KEY_KPminus, KEY_Reserved, KEY_UpArrow, KEY_DownArrow, KEY_RightArrow,KEY_LeftArrow,//4 20 KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_KPRParen, KEY_KPLParen, KEY_KPslash, KEY_KPasterisk,KEY_KPplus, KEY_Help, //5 21 KEY_Reserved,KEY_Reserved, KEY_capslock,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, //6 22 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, //7 23 }; 24 25 /** 26 * The modmatrix-array contains positions of the modifier-keys in the matrix. 27 * It is built in the same way as the keymatrix-array. 28 * \sa keymatrix 29 */ 30 const uint8_t PROGMEM modmatrix[8] = { // contains positions of modifiers in the matrix 31 // 0 1 2 3 4 5 6 7 32 MOD_SHIFT_LEFT,MOD_SHIFT_RIGHT,MOD_NONE,MOD_CONTROL_LEFT,MOD_ALT_LEFT,MOD_NONE, MOD_GUI_LEFT, MOD_GUI_RIGHT, 33 }; 34 35 static uint8_t idleRate; 36 static uint8_t reportBuffer[8]; 37 38 void fillReportBuffer(uint8_t key_code) { 39 uint8_t key, modifier; 40 uint8_t reportIndex = 2; // reportBuffer[0] contains modifiers 41 memset(reportBuffer, 0, sizeof(reportBuffer)); // clear report buffer 42 key = pgm_read_byte(&keymatrix[key_code]); 43 if (key_code >= 0x60 && key_code < 0x68) 44 modifier = pgm_read_byte(&modmatrix[key_code - 0x60]); 45 else 46 modifier = MOD_NONE; 47 if (key != KEY_Reserved) { 48 reportBuffer[reportIndex] = key; // set next available entry 49 reportIndex++; 50 } 51 reportBuffer[0] |= modifier; 52 } 53 54 55 void usbSendReport(uint8_t mode, uint8_t key) { 56 // buffer for HID reports. we use a private one, so nobody gets disturbed 57 uint8_t repBuffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 58 repBuffer[0] = mode; 59 repBuffer[2] = key; 60 while (!usbInterruptIsReady()); // wait 61 usbSetInterrupt(repBuffer, sizeof(repBuffer)); // send 62 } 63 7 64 8 65 int main() { 9 //debug LED - output 10 DDRD |= (1<<PD6); 11 12 USARTInit(51); 13 ak_init_keyboard(); 14 15 uint8_t key_code = 0; 16 17 // Ready! 18 USARTWriteChar('R'); 19 20 while(1) { 21 key_code = ak_read_scancode(); 22 //USARTWriteChar(ak_scancode_to_ascii(key_code)); 23 USARTWriteHex((key_code >> 1) |(key_code << 7)); 24 USARTWriteChar(' '); 25 } 26 27 return 0; 28 } 29 66 uint8_t idleCounter = 0; 67 uint8_t updateNeeded = 0; 68 69 wdt_enable(WDTO_2S); 70 // configure timer 0 for a rate of 12M/(1024 * 256) = 45.78Hz (~22ms) 71 TCCR0 = 5; // timer 0 prescaler: 1024 72 73 //debug LED - output 74 DDRD |= (1<<PD6); 75 76 // Keyboard 77 uint8_t key_code = 0; 78 79 // USB 80 usbInit(); 81 ak_init_keyboard(); 82 sei(); 83 84 while(1) { 85 wdt_reset(); 86 usbPoll(); 87 88 updateNeeded = char_waiting; 89 90 if (char_waiting) { 91 key_code = ak_read_scancode(); 92 } 93 94 // check timer if we need periodic reports 95 if (TIFR & (1 << TOV0)) { 96 TIFR = (1 << TOV0); // reset flag 97 if (idleRate != 0) { // do we need periodic reports? 98 if(idleCounter > 4){ // yes, but not yet 99 idleCounter -= 5; // 22ms in units of 4ms 100 } else { // yes, it is time now 101 updateNeeded = 1; 102 idleCounter = idleRate; 103 } 104 } 105 106 } 107 // if an update is needed, send the report 108 if (updateNeeded && usbInterruptIsReady()) { 109 updateNeeded = 0; 110 //fillReportBuffer(key_code); 111 fillReportBuffer(KEY_Y); 112 usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 113 PORTD ^= (1<<PD6); 114 } 115 } 116 117 return 0; 118 } 119 120 static uint8_t protocolVer = 1; 121 uint8_t expectReport = 0; 122 123 #define LED_NUM 0x01 ///< num LED on a boot-protocol keyboard 124 #define LED_CAPS 0x02 ///< caps LED on a boot-protocol keyboard 125 #define LED_SCROLL 0x04 ///< scroll LED on a boot-protocol keyboard 126 #define LED_COMPOSE 0x08 ///< compose LED on a boot-protocol keyboard 127 #define LED_KANA 0x10 ///< kana LED on a boot-protocol keyboard 128 uint8_t LEDstate = 0; ///< current state of the LEDs 129 130 131 char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { 132 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 133 0x09, 0x06, // USAGE (Keyboard) 134 0xa1, 0x01, // COLLECTION (Application) 135 0x05, 0x07, // USAGE_PAGE (Keyboard) 136 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 137 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 138 0x15, 0x00, // LOGICAL_MINIMUM (0) 139 0x25, 0x01, // LOGICAL_MAXIMUM (1) 140 0x75, 0x01, // REPORT_SIZE (1) 141 0x95, 0x08, // REPORT_COUNT (8) 142 0x81, 0x02, // INPUT (Data,Var,Abs) 143 0x95, 0x01, // REPORT_COUNT (1) 144 0x75, 0x08, // REPORT_SIZE (8) 145 0x81, 0x03, // INPUT (Cnst,Var,Abs) 146 0x95, 0x05, // REPORT_COUNT (5) 147 0x75, 0x01, // REPORT_SIZE (1) 148 0x05, 0x08, // USAGE_PAGE (LEDs) 149 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 150 0x29, 0x05, // USAGE_MAXIMUM (Kana) 151 0x91, 0x02, // OUTPUT (Data,Var,Abs) 152 0x95, 0x01, // REPORT_COUNT (1) 153 0x75, 0x03, // REPORT_SIZE (3) 154 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 155 0x95, 0x06, // REPORT_COUNT (6) 156 0x75, 0x08, // REPORT_SIZE (8) 157 0x15, 0x00, // LOGICAL_MINIMUM (0) 158 0x25, 0x65, // LOGICAL_MAXIMUM (101) 159 0x05, 0x07, // USAGE_PAGE (Keyboard) 160 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 161 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 162 0x81, 0x00, // INPUT (Data,Ary,Abs) 163 0xc0 // END_COLLECTION 164 }; 165 166 167 168 169 uint8_t usbFunctionSetup(uint8_t data[8]) { 170 usbRequest_t *rq = (void *)data; 171 usbMsgPtr = reportBuffer; 172 if ((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) { 173 // class request type 174 if (rq->bRequest == USBRQ_HID_GET_REPORT) { 175 // wValue: ReportType (highbyte), ReportID (lowbyte) 176 // we only have one report type, so don't look at wValue 177 return sizeof(reportBuffer); 178 } else if (rq->bRequest == USBRQ_HID_SET_REPORT) { 179 if (rq->wLength.word == 1) { 180 // We expect one byte reports 181 expectReport = 1; 182 return 0xff; // Call usbFunctionWrite with data 183 } 184 } else if (rq->bRequest == USBRQ_HID_GET_IDLE) { 185 usbMsgPtr = &idleRate; 186 return 1; 187 } else if (rq->bRequest == USBRQ_HID_SET_IDLE) { 188 idleRate = rq->wValue.bytes[1]; 189 } else if (rq->bRequest == USBRQ_HID_GET_PROTOCOL) { 190 if (rq->wValue.bytes[1] < 1) { 191 protocolVer = rq->wValue.bytes[1]; 192 } 193 } else if(rq->bRequest == USBRQ_HID_SET_PROTOCOL) { 194 usbMsgPtr = &protocolVer; 195 return 1; 196 } 197 } else { 198 // no vendor specific requests implemented 199 } 200 return 0; 201 } 202 203 /** 204 * The write function is called when LEDs should be set. Normally, we get only 205 * one byte that contains info about the LED states. 206 * \param data pointer to received data 207 * \param len number ob bytes received 208 * \return 0x01 209 */ 210 uint8_t usbFunctionWrite(uchar *data, uchar len) { 211 if (expectReport && (len == 1)) { 212 LEDstate = data[0]; // Get the state of all 5 LEDs 213 /* TODO 214 if (LEDstate & LED_NUM) { // light up caps lock 215 PORTLEDS &= ~(1 << LEDNUM); 216 } else { 217 PORTLEDS |= (1 << LEDNUM); 218 } 219 if (LEDstate & LED_CAPS) { // light up caps lock 220 PORTLEDS &= ~(1 << LEDCAPS); 221 } else { 222 PORTLEDS |= (1 << LEDCAPS); 223 } 224 if (LEDstate & LED_SCROLL) { // light up caps lock 225 PORTLEDS &= ~(1 << LEDSCROLL); 226 } else { 227 PORTLEDS |= (1 << LEDSCROLL); 228 } 229 */ 230 } 231 expectReport = 0; 232 return 0x01; 233 } 234
Note:
See TracChangeset
for help on using the changeset viewer.