Changeset bf42f57 in avrstuff for starkadroid/code/main.c
- Timestamp:
- Oct 17, 2010, 9:49:32 PM (14 years ago)
- Branches:
- main
- Children:
- 1dc9759
- Parents:
- be9ba97
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
starkadroid/code/main.c
rbe9ba97 rbf42f57 8 8 #include <stdbool.h> 9 9 10 #include "amiga_keyboard/amiga_keyboard.h"11 10 #include "usbdrv/usbdrv.h" 12 #include "keycodes.h"13 11 14 #define LEDSWAP PORTD ^= (1<<PD6) 15 #define LEDON PORTD |= 1<<PD6 16 #define LEDOFF PORTD &= ~(1<<PD6) 12 static uint8_t reportBuffer[5]; 13 static uint8_t idleRate; 17 14 18 static uint8_t pressingCaps = 0; 19 20 const uint8_t PROGMEM keymatrix[0x70] = { 21 // 0 1 2 3 4 5 6 7 8 9 A B C D E F 22 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_F11, KEY_Reserved, KEY_KP0, //0 23 KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, KEY_lbracket, KEY_rbracket, KEY_Reserved, KEY_KP1, KEY_KP2, KEY_KP3, //1 24 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 25 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 26 KEY_Spacebar,KEY_DELETE, KEY_Tab, KEY_KPenter, KEY_Return,KEY_ESCAPE,KEY_DeleteForward,KEY_Reserved,KEY_Reserved,KEY_Reserved, KEY_KPminus, KEY_Reserved, KEY_UpArrow, KEY_DownArrow, KEY_RightArrow,KEY_LeftArrow,//4 27 KEY_F1, KEY_F2, KEY_F3, KEY_F4, KEY_F5, KEY_F6, KEY_F7, KEY_F8, KEY_F9, KEY_F10, KEY_KPLParen, KEY_KPRParen, KEY_KPslash, KEY_KPasterisk,KEY_KPplus, KEY_Help, //5 28 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 29 }; 30 31 /** 32 * The modmatrix-array contains positions of the modifier-keys in the matrix. 33 * It is built in the same way as the keymatrix-array. 34 * \sa keymatrix 35 */ 36 const uint8_t PROGMEM modmatrix[8] = { // contains positions of modifiers in the matrix 37 // 0 1 2 3 4 5 6 7 38 MOD_SHIFT_LEFT,MOD_SHIFT_RIGHT,MOD_NONE,MOD_CONTROL_LEFT,MOD_ALT_LEFT,MOD_ALT_RIGHT, MOD_GUI_LEFT, MOD_GUI_RIGHT, 39 }; 40 41 static uint8_t idleRate; 42 static uint8_t reportIndex = 2; 43 static uint8_t reportBuffer[8]; 44 45 void fillReportBuffer(uint8_t key_code) { 46 uint8_t key, modifier; 47 key = pgm_read_byte(&keymatrix[key_code]); 48 if (key_code >= 0x60 && key_code < 0x68) 49 modifier = pgm_read_byte(&modmatrix[key_code - 0x60]); 50 else 51 modifier = MOD_NONE; 52 53 if (key != KEY_Reserved && reportIndex < 8) { 54 reportBuffer[reportIndex] = key; // set next available entry 55 reportIndex++; 56 if (key == KEY_capslock) 57 pressingCaps = 1; 58 } 59 reportBuffer[0] |= modifier; 60 } 61 62 63 void emptyReportBuffer(uint8_t key_code) { 64 65 uint8_t key, modifier; 66 uint8_t i; 67 key = pgm_read_byte(&keymatrix[key_code]); 68 if (key_code >= 0x60 && key_code < 0x68) 69 modifier = pgm_read_byte(&modmatrix[key_code - 0x60]); 70 else 71 modifier = MOD_NONE; 72 73 if (key == KEY_capslock) { 74 if (reportIndex < 8) { 75 reportBuffer[reportIndex] = key; // set next available entry 76 reportIndex++; 77 pressingCaps = 1; 78 } 79 } else if (key != KEY_Reserved) { 80 for (i = 2; i < reportIndex; i++) { 81 if (reportBuffer[i] == key) { 82 for (; i < 7; i++) 83 reportBuffer[i] = reportBuffer[i+1]; 84 reportBuffer[7] = 0; 85 reportIndex--; 86 } 87 } 88 } 89 reportBuffer[0] &= ~modifier; 90 } 91 92 93 /* 94 void usbSendReport(uint8_t mode, uint8_t key) { 95 // buffer for HID reports. we use a private one, so nobody gets disturbed 96 uint8_t repBuffer[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; 97 repBuffer[0] = mode; 98 repBuffer[2] = key; 99 while (!usbInterruptIsReady()); // wait 100 usbSetInterrupt(repBuffer, sizeof(repBuffer)); // send 101 } 102 */ 103 104 int main() { 15 void main() { 105 16 uint8_t idleCounter = 0; 106 uint8_t updateNeeded = 0;107 int capsDelay = 16;108 17 109 18 wdt_enable(WDTO_2S); 110 // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz111 TCCR0 = 4; // timer 0 prescaler: 256112 113 //debug LED - output114 DDRD |= (1<<PD6);115 116 // Keyboard117 uint8_t key_code = 255;118 memset(reportBuffer, 0, sizeof(reportBuffer)); // clear report buffer119 19 120 20 // USB 121 21 usbInit(); 122 ak_init_keyboard();123 22 sei(); 124 bool doReport = false; 125 bool doRelease = false; 23 bool doReport; 126 24 25 DDRB = 0; // Keyboard matrix out 26 PORTB = 255; // Enable pull up 27 // We put all pins as input then output a 0 in only one at a time. 28 // All the other pins are high-Z to avoid short circuits when many buttons are pressed. 29 DDRC = 0; // Keyboard matrix in 30 PORTC = 255; // Enable pull up 31 32 // configure timer 0 for a rate of 16M/(256 * 256) = ~244Hz 33 TCCR0 = 4; // timer 0 prescaler: 256 34 127 35 while(1) { 128 36 wdt_reset(); 129 37 usbPoll(); 130 38 131 updateNeeded = char_waiting; 132 133 if (char_waiting) { 134 key_code = ak_read_scancode(); 135 // if an update is needed, send the report 136 if ((key_code & 1) == 0) { 137 fillReportBuffer(key_code>>1); 138 LEDON; 139 doReport = true; 140 } else { 141 emptyReportBuffer(key_code>>1); 142 doRelease = true; 143 } 39 doReport = false; 40 for(int i=0; i < 5; i++) { 41 DDRB = ~(1<<i); 42 PORTB = ~(1<<i); 43 reportBuffer[i] = (~PINC)&0x3F; 144 44 } 145 45 146 if (doReport && usbInterruptIsReady()) { 46 DDRB = ~(1<<5); 47 PORTB = ~(1<<5); 48 reportBuffer[0] |= (~PINC)<<6 & 0xC0; 49 reportBuffer[1] |= (~PINC)<<4 & 0xC0; 50 reportBuffer[2] |= (~PINC)<<2 & 0xC0; 51 // reportBuffer[3] |= (~PINC)<<0 & 0xC0; // These are not existing pins... 52 53 DDRB = 255; 54 PORTB = 255; 55 56 if (usbInterruptIsReady()) { 147 57 usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 148 LEDOFF;58 // LEDOFF; 149 59 doReport = false; 150 60 } 151 61 152 153 // check timer if we need periodic reports154 62 if (TIFR & (1 << TOV0)) { 155 63 TIFR = (1 << TOV0); // reset flag 156 64 157 if (pressingCaps) { 158 if (--capsDelay == 0) { 159 capsDelay = 16; 160 pressingCaps = 0; 161 162 int i; 163 for (i = 2; i < reportIndex; i++) { 164 if (reportBuffer[i] == KEY_capslock) { 165 for (; i < 7; i++) 166 reportBuffer[i] = reportBuffer[i+1]; 167 reportBuffer[7] = 0; 168 reportIndex--; 169 } 170 } 171 } 172 } 173 174 ++idleCounter; 175 if(idleCounter > 4){ // yes, but not yet 65 if(++idleCounter > 4){ // yes, but not yet 176 66 idleCounter -= 5; // 22ms in units of 4ms 177 67 } else { // yes, it is time now 178 68 idleCounter = idleRate; 179 /* 180 if (pressingCaps) { 181 emptyReportBuffer(0x62); 182 pressingCaps = 0; 183 } 184 */ 185 if (doRelease && usbInterruptIsReady()) { 69 if (usbInterruptIsReady()) { 186 70 usbSetInterrupt(reportBuffer, sizeof(reportBuffer)); 187 doRelease = false;188 71 } 189 72 } 190 73 } 191 74 } 75 } 192 76 193 return 0;194 }195 77 196 78 static uint8_t protocolVer = 1; 197 79 uint8_t expectReport = 0; 198 80 199 #define LED_NUM 0x01 ///< num LED on a boot-protocol keyboard200 #define LED_CAPS 0x02 ///< caps LED on a boot-protocol keyboard201 #define LED_SCROLL 0x04 ///< scroll LED on a boot-protocol keyboard202 #define LED_COMPOSE 0x08 ///< compose LED on a boot-protocol keyboard203 #define LED_KANA 0x10 ///< kana LED on a boot-protocol keyboard204 uint8_t LEDstate = 0; ///< current state of the LEDs205 206 81 207 82 char PROGMEM usbHidReportDescriptor[USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH] = { 208 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 209 0x09, 0x06, // USAGE (Keyboard) 210 0xa1, 0x01, // COLLECTION (Application) 211 0x05, 0x07, // USAGE_PAGE (Keyboard) 212 0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl) 213 0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI) 214 0x15, 0x00, // LOGICAL_MINIMUM (0) 215 0x25, 0x01, // LOGICAL_MAXIMUM (1) 216 0x75, 0x01, // REPORT_SIZE (1) 217 0x95, 0x08, // REPORT_COUNT (8) 218 0x81, 0x02, // INPUT (Data,Var,Abs) 219 0x95, 0x01, // REPORT_COUNT (1) 220 0x75, 0x08, // REPORT_SIZE (8) 221 0x81, 0x03, // INPUT (Cnst,Var,Abs) 222 0x95, 0x05, // REPORT_COUNT (5) 223 0x75, 0x01, // REPORT_SIZE (1) 224 0x05, 0x08, // USAGE_PAGE (LEDs) 225 0x19, 0x01, // USAGE_MINIMUM (Num Lock) 226 0x29, 0x05, // USAGE_MAXIMUM (Kana) 227 0x91, 0x02, // OUTPUT (Data,Var,Abs) 228 0x95, 0x01, // REPORT_COUNT (1) 229 0x75, 0x03, // REPORT_SIZE (3) 230 0x91, 0x03, // OUTPUT (Cnst,Var,Abs) 231 0x95, 0x06, // REPORT_COUNT (6) 232 0x75, 0x08, // REPORT_SIZE (8) 233 0x15, 0x00, // LOGICAL_MINIMUM (0) 234 0x25, 0x65, // LOGICAL_MAXIMUM (101) 235 0x05, 0x07, // USAGE_PAGE (Keyboard) 236 0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated)) 237 0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application) 238 0x81, 0x00, // INPUT (Data,Ary,Abs) 239 0xc0 // END_COLLECTION 83 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 84 0x09, 0x05, // USAGE (Game Pad) 85 0xa1, 0x01, // COLLECTION (Application) 86 0x09, 0x01, // USAGE (Pointer) 87 0xa1, 0x00, // COLLECTION (Physical) 88 0x09, 0x30, // USAGE (X) 89 0x09, 0x31, // USAGE (Y) 90 0x15, 0xff, // LOGICAL_MINIMUM (-1) 91 0x25, 0x01, // LOGICAL_MAXIMUM (1) 92 0x75, 0x02, // REPORT_SIZE (2) 93 0x95, 0x02, // REPORT_COUNT (2) 94 0x81, 0x02, // INPUT (Data,Var,Abs) 95 0xc0, // END_COLLECTION 96 0x05, 0x09, // USAGE_PAGE (Button) 97 0x19, 0x01, // USAGE_MINIMUM (Button 1) 98 0x29, 0x24, // USAGE_MAXIMUM (Button 36) 99 0x15, 0x00, // LOGICAL_MINIMUM (0) 100 0x25, 0x01, // LOGICAL_MAXIMUM (1) 101 0x75, 0x01, // REPORT_SIZE (1) 102 0x95, 0x24, // REPORT_COUNT (36) 103 0x81, 0x02, // INPUT (Data,Var,Abs) 104 0xc0 // END_COLLECTION 240 105 }; 241 242 243 106 244 107 … … 277 140 } 278 141 279 /**280 * The write function is called when LEDs should be set. Normally, we get only281 * one byte that contains info about the LED states.282 * \param data pointer to received data283 * \param len number ob bytes received284 * \return 0x01285 */286 142 uint8_t usbFunctionWrite(uchar *data, uchar len) { 287 if (expectReport && (len == 1)) {288 LEDstate = data[0]; // Get the state of all 5 LEDs289 /* TODO290 if (LEDstate & LED_NUM) { // light up caps lock291 PORTLEDS &= ~(1 << LEDNUM);292 } else {293 PORTLEDS |= (1 << LEDNUM);294 }295 if (LEDstate & LED_CAPS) { // light up caps lock296 PORTLEDS &= ~(1 << LEDCAPS);297 } else {298 PORTLEDS |= (1 << LEDCAPS);299 }300 if (LEDstate & LED_SCROLL) { // light up caps lock301 PORTLEDS &= ~(1 << LEDSCROLL);302 } else {303 PORTLEDS |= (1 << LEDSCROLL);304 }305 */306 }307 143 expectReport = 0; 308 144 return 0x01;
Note:
See TracChangeset
for help on using the changeset viewer.