first release for keyboard
Dependencies: F401RE-USBHost2 mbed
main.cpp
00001 // TODO: work off controler 3.3v if possible 00002 00003 #include "mbed.h" 00004 #include "USBHostKeyboard.h" 00005 #include "stm32f4xx_flash.h" 00006 00007 DigitalOut myled(LED1); 00008 Serial pc(USBTX, USBRX); // tx, rx 00009 DigitalInOut data(PA_8); 00010 DigitalIn button(PC_13); // eventually code to set controls 00011 00012 extern "C" void my_wait_us_asm (int n); 00013 00014 enum STATE {NORMAL=0, A_UP, A_DOWN, A_LEFT, A_RIGHT, DPAD_UP, DPAD_DOWN, DPAD_LEFT, DPAD_RIGHT, BUTTON_START, BUTTON_B, BUTTON_A, C_UP, C_DOWN, C_LEFT, C_RIGHT, BUTTON_L, BUTTON_R, BUTTON_Z}; 00015 uint8_t state = NORMAL; //done remapping when >= 19 00016 00017 bool KeyboardButtonPressed = false; 00018 void LoadControls(); 00019 void SaveControls(); 00020 00021 struct __attribute__((packed)) N64ControllerData // all bits are in the correct order 00022 { 00023 unsigned int a : 1; // 1 bit wide 00024 unsigned int b : 1; 00025 unsigned int z : 1; 00026 unsigned int start : 1; 00027 unsigned int up : 1; 00028 unsigned int down : 1; 00029 unsigned int left : 1; 00030 unsigned int right : 1; 00031 00032 unsigned int dummy1 : 1; 00033 unsigned int dummy2 : 1; 00034 unsigned int l :1 ; 00035 unsigned int r : 1; 00036 unsigned int c_up : 1; 00037 unsigned int c_down : 1; 00038 unsigned int c_left : 1; 00039 unsigned int c_right : 1; 00040 00041 char x_axis; 00042 00043 char y_axis; 00044 00045 } n64_data; 00046 00047 struct __attribute__((packed)) KeyboardControls 00048 { 00049 uint8_t KEYBOARD_a; 00050 uint8_t KEYBOARD_b; 00051 uint8_t KEYBOARD_z; 00052 uint8_t KEYBOARD_start; 00053 00054 uint8_t KEYBOARD_d_up; 00055 uint8_t KEYBOARD_d_down; 00056 uint8_t KEYBOARD_d_left; 00057 uint8_t KEYBOARD_d_right; 00058 00059 uint8_t KEYBOARD_l; 00060 uint8_t KEYBOARD_r; 00061 uint8_t KEYBOARD_c_up; 00062 uint8_t KEYBOARD_c_down; 00063 00064 uint8_t KEYBOARD_c_left; 00065 uint8_t KEYBOARD_c_right; 00066 uint8_t KEYBOARD_a_up; 00067 uint8_t KEYBOARD_a_down; 00068 00069 uint8_t KEYBOARD_a_left; 00070 uint8_t KEYBOARD_a_right; 00071 00072 KeyboardControls() 00073 { 00074 LoadDefault(); 00075 } 00076 00077 void LoadDefault() 00078 { 00079 KEYBOARD_a = 0x0E; 00080 KEYBOARD_b = 0x0D; 00081 KEYBOARD_z = 0x0F; 00082 KEYBOARD_start = 0x0B; 00083 KEYBOARD_d_up = 0x1D; 00084 KEYBOARD_d_down = 0x1B; 00085 KEYBOARD_d_left = 0x06; 00086 KEYBOARD_d_right = 0x19; 00087 KEYBOARD_l = 0x1A; 00088 KEYBOARD_r = 0x12; 00089 KEYBOARD_c_up = 0x17; 00090 KEYBOARD_c_down = 0x1C; 00091 KEYBOARD_c_left = 0x18; 00092 KEYBOARD_c_right = 0x0C; 00093 KEYBOARD_a_up = 0x08; 00094 KEYBOARD_a_down = 0x07; 00095 KEYBOARD_a_left = 0x16; 00096 KEYBOARD_a_right = 0x09; 00097 } 00098 00099 void LoadBlank() 00100 { 00101 KEYBOARD_a = 0x00; 00102 KEYBOARD_b = 0x00; 00103 KEYBOARD_z = 0x00; 00104 KEYBOARD_start = 0x00; 00105 KEYBOARD_d_up = 0x00; 00106 KEYBOARD_d_down = 0x00; 00107 KEYBOARD_d_left = 0x00; 00108 KEYBOARD_d_right = 0x00; 00109 KEYBOARD_l = 0x00; 00110 KEYBOARD_r = 0x00; 00111 KEYBOARD_c_up = 0x00; 00112 KEYBOARD_c_down = 0x00; 00113 KEYBOARD_c_left = 0x00; 00114 KEYBOARD_c_right = 0x00; 00115 KEYBOARD_a_up = 0x00; 00116 KEYBOARD_a_down = 0x00; 00117 KEYBOARD_a_left = 0x00; 00118 KEYBOARD_a_right = 0x00; 00119 } 00120 }; 00121 00122 KeyboardControls kc; 00123 00124 const int SAVE_ADDR = 0x0800C000; // sector 3 00125 KeyboardControls* saveData = (KeyboardControls*)SAVE_ADDR; 00126 00127 // 0 is 3 microseconds low followed by 1 microsecond high 00128 // 1 is 1 microsecond low followed by 3 microseconds high 00129 unsigned int GetMiddleOfPulse() 00130 { 00131 // wait for line to go high 00132 while(1) 00133 { 00134 if(data.read() == 1) break; 00135 } 00136 00137 // wait for line to go low 00138 while(1) 00139 { 00140 if(data.read() == 0) break; 00141 } 00142 00143 // now we have the falling edge 00144 // wait 2 microseconds to be in the middle of the pulse, and read. high --> 1. low --> 0. 00145 my_wait_us_asm(2); 00146 return (unsigned int) data.read(); 00147 } 00148 00149 // continuously read bits until at least 9 are read, confirm valid command, return without stop bit 00150 unsigned int readCommand() 00151 { 00152 unsigned int command = GetMiddleOfPulse(), bits_read = 1; 00153 00154 while(1) // read at least 9 bits (2 bytes + stop bit) 00155 { 00156 //my_wait_us_asm(4); 00157 command = command << 1; // make room for the new bit 00158 //command += data.read(); // place the new bit into the command 00159 command += GetMiddleOfPulse(); 00160 command &= 0x1FF; // remove all except the last 9 bits 00161 00162 bits_read++; 00163 00164 if(bits_read >= 9) // only consider when at least a whole command's length has been read 00165 { 00166 if(command == 0x3 || command == 0x1 || command == 0x1FF || command == 0x5 || command == 0x7) 00167 { 00168 // 0x3 = 0x1 + stop bit --> get controller state 00169 // 0x1 = 0x0 + stop bit --> who are you? 00170 // 0x1FF = 0xFF + stop bit --> reset signal 00171 // 0x5 = 0x10 + stop bit --> read 00172 // 0x7 = 0x11 + stop bit --> write 00173 command = command >> 1; // get rid of the stop bit 00174 return command; 00175 } 00176 } 00177 } 00178 } 00179 00180 void write_1() 00181 { 00182 data = 0; 00183 my_wait_us_asm(1); 00184 data = 1; 00185 my_wait_us_asm(3); 00186 //pc.printf("1"); 00187 } 00188 00189 void write_0() 00190 { 00191 data = 0; 00192 my_wait_us_asm(3); 00193 data = 1; 00194 my_wait_us_asm(1); 00195 //pc.printf("0"); 00196 } 00197 00198 00199 void SendStop() 00200 { 00201 data = 0; 00202 my_wait_us_asm(1); 00203 data = 1; 00204 } 00205 00206 // send a byte from LSB to MSB (proper serialization) 00207 void SendByte(unsigned char b) 00208 { 00209 for(int i = 0;i < 8;i++) // send all 8 bits, one at a time 00210 { 00211 if((b >> i) & 1) 00212 { 00213 write_1(); 00214 } 00215 else 00216 { 00217 write_0(); 00218 } 00219 } 00220 } 00221 00222 void SendIdentity() 00223 { 00224 // reply 0x05, 0x00, 0x02 00225 SendByte(0x05); 00226 SendByte(0x00); 00227 SendByte(0x02); 00228 SendStop(); 00229 } 00230 00231 void SendControllerData() 00232 { 00233 unsigned long data = *(unsigned long*)&n64_data; 00234 unsigned int size = sizeof(data) * 8; // should be 4 bytes * 8 = 32 bits 00235 00236 for(unsigned int i = 0;i < size;i++) 00237 { 00238 if((data >> i) & 1) 00239 { 00240 write_1(); 00241 } 00242 else 00243 { 00244 write_0(); 00245 } 00246 } 00247 00248 SendStop(); 00249 } 00250 00251 char reverse(char b) 00252 { 00253 b = (b & 0xF0) >> 4 | (b & 0x0F) << 4; 00254 b = (b & 0xCC) >> 2 | (b & 0x33) << 2; 00255 b = (b & 0xAA) >> 1 | (b & 0x55) << 1; 00256 return b; 00257 } 00258 00259 void ChangeButtonMapping(uint8_t bt) 00260 { 00261 // analog settings must be hardcoded, cannot change on the fly 00262 if(state == A_UP) // state = 1 --> analog up 00263 { 00264 kc.KEYBOARD_a_up = bt; 00265 } 00266 else if(state == A_DOWN) // state = 2 --> analog up 00267 { 00268 kc.KEYBOARD_a_down = bt; 00269 } 00270 else if(state == A_LEFT) // state = 3 --> analog up 00271 { 00272 kc.KEYBOARD_a_left = bt; 00273 } 00274 else if(state == A_RIGHT) // state = 4 --> analog up 00275 { 00276 kc.KEYBOARD_a_right = bt; 00277 } 00278 else if(state == DPAD_UP) // state = 5 --> dpad up 00279 { 00280 kc.KEYBOARD_d_up = bt; 00281 } 00282 else if(state == DPAD_DOWN) // state = 6 --> dpad down 00283 { 00284 kc.KEYBOARD_d_down = bt; 00285 } 00286 else if(state == DPAD_LEFT) // state = 7 --> dpad left 00287 { 00288 kc.KEYBOARD_d_left = bt; 00289 } 00290 else if(state == DPAD_RIGHT) // state = 8 --> dpad right 00291 { 00292 kc.KEYBOARD_d_right = bt; 00293 } 00294 else if(state == BUTTON_START) // state = 9 --> start 00295 { 00296 kc.KEYBOARD_start = bt; 00297 } 00298 else if(state == BUTTON_B) // state = 10 --> B 00299 { 00300 kc.KEYBOARD_b = bt; 00301 } 00302 else if(state == BUTTON_A) // state = 11 --> A 00303 { 00304 kc.KEYBOARD_a = bt; 00305 } 00306 else if(state == C_UP) // state = 12 --> c up 00307 { 00308 kc.KEYBOARD_c_up = bt; 00309 } 00310 else if(state == C_DOWN) // state = 13 --> c down 00311 { 00312 kc.KEYBOARD_c_down = bt; 00313 } 00314 else if(state == C_LEFT) // state = 14 --> c left 00315 { 00316 kc.KEYBOARD_c_left = bt; 00317 } 00318 else if(state == C_RIGHT) // state = 15 --> c right 00319 { 00320 kc.KEYBOARD_c_right = bt; 00321 } 00322 else if(state == BUTTON_L) // state = 16 --> L 00323 { 00324 kc.KEYBOARD_l = bt; 00325 } 00326 else if(state == BUTTON_R) // state = 17 --> R 00327 { 00328 kc.KEYBOARD_r = bt; 00329 } 00330 else if(state == BUTTON_Z) // state = 18 --> Z 00331 { 00332 kc.KEYBOARD_z = bt; 00333 } 00334 } 00335 00336 void AdvanceState() 00337 { 00338 state++; 00339 if(state >= 19) // we're done mapping the controls 00340 { 00341 SaveControls(); // write directly to flash 00342 state = NORMAL; // back to normal controller operation 00343 } 00344 } 00345 00346 void onKeyboardEvent(uint8_t rep[9]) 00347 { 00348 // the buttons all become 1 if overflow, i think. or in short, [2] == [3] 00349 if(rep[2] == rep[3] && rep[2] == 1) 00350 return; 00351 00352 if(state == NORMAL) 00353 { 00354 memset(&n64_data,0,4); // clear controller state 00355 00356 // keyboard buttons are stored in cells 2 3 4 5 6 7? cell 0 and 1 are modifiers? cell8 is an F? 00357 for(int index = 2;index < 8;index++) 00358 { 00359 if(rep[index] == 0) // no key to process 00360 { 00361 continue; 00362 } 00363 if(rep[index] == kc.KEYBOARD_a) 00364 { 00365 n64_data.a = 1; 00366 continue; 00367 } 00368 if(rep[index] == kc.KEYBOARD_b) 00369 { 00370 n64_data.b = 1; 00371 continue; 00372 } 00373 if(rep[index] == kc.KEYBOARD_z) 00374 { 00375 n64_data.z = 1; 00376 continue; 00377 } 00378 if(rep[index] == kc.KEYBOARD_start) 00379 { 00380 n64_data.start = 1; 00381 continue; 00382 } 00383 if(rep[index] == kc.KEYBOARD_d_up) 00384 { 00385 n64_data.up = 1; 00386 continue; 00387 } 00388 if(rep[index] == kc.KEYBOARD_d_down) 00389 { 00390 n64_data.down = 1; 00391 continue; 00392 } 00393 if(rep[index] == kc.KEYBOARD_d_left) 00394 { 00395 n64_data.left = 1; 00396 continue; 00397 } 00398 if(rep[index] == kc.KEYBOARD_d_right) 00399 { 00400 n64_data.right = 1; 00401 continue; 00402 } 00403 if(rep[index] == kc.KEYBOARD_l) 00404 { 00405 n64_data.l = 1; 00406 continue; 00407 } 00408 if(rep[index] == kc.KEYBOARD_r) 00409 { 00410 n64_data.r = 1; 00411 continue; 00412 } 00413 if(rep[index] == kc.KEYBOARD_c_up) 00414 { 00415 n64_data.c_up = 1; 00416 continue; 00417 } 00418 if(rep[index] == kc.KEYBOARD_c_down) 00419 { 00420 n64_data.c_down = 1; 00421 continue; 00422 } 00423 if(rep[index] == kc.KEYBOARD_c_left) 00424 { 00425 n64_data.c_left = 1; 00426 continue; 00427 } 00428 if(rep[index] == kc.KEYBOARD_c_right) 00429 { 00430 n64_data.c_right = 1; 00431 continue; 00432 } 00433 // NOTE: THESE BITS MUST BE WRITTEN IN REVERSE ORDER. HIGH BIT IS IN THE LOW POSITION 00434 if(rep[index] == kc.KEYBOARD_a_up) 00435 { 00436 //n64_data.y_axis = 0x0A; // 80(dec) bit reversed 00437 n64_data.y_axis = 0xB4; // 2D = 45 = 35% = no tap jump. bit reverse 2D (00101101) to get B4 (10110100) 00438 continue; 00439 } 00440 if(rep[index] == kc.KEYBOARD_a_down) 00441 { 00442 n64_data.y_axis = 0x0D; // -80(dec) bit reversed 00443 continue; 00444 } 00445 if(rep[index] == kc.KEYBOARD_a_left) 00446 { 00447 n64_data.x_axis = 0x0D; 00448 continue; 00449 } 00450 if(rep[index] == kc.KEYBOARD_a_right) 00451 { 00452 n64_data.x_axis = 0x0A; 00453 continue; 00454 } 00455 } 00456 } 00457 else // state > 0 so we are in the process of changing controls 00458 { 00459 uint8_t b = rep[2]; // read for button presses (just take first pressed if many are pressed) 00460 if(b != 0) /*button was actually is pressed*/ 00461 { 00462 if(KeyboardButtonPressed == false) 00463 { 00464 KeyboardButtonPressed = true; 00465 ChangeButtonMapping(b); 00466 AdvanceState(); 00467 } 00468 } 00469 else 00470 { 00471 KeyboardButtonPressed = false; 00472 } 00473 } 00474 } 00475 00476 void PrintBytes(char *ptr, int numBytes) 00477 { 00478 pc.printf("["); 00479 for(int i=0;i < numBytes;i++) 00480 { 00481 pc.printf(" %X ",*ptr); 00482 ptr++; 00483 } 00484 pc.printf("]\r\n"); 00485 } 00486 00487 void SaveControls() 00488 { 00489 FLASH_Unlock(); //unlock flash writing 00490 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | 00491 FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR); 00492 FLASH_EraseSector(FLASH_Sector_3,VoltageRange_3); // 0x0800C000 - 0x0800FFFF 00493 00494 uint32_t* data = (uint32_t*)&kc; 00495 00496 // total size is 18 bytes 00497 // Note: ProgramDoubleWord requires a higher voltage 00498 FLASH_ProgramWord(SAVE_ADDR,*data); // write word 1 (4 bytes) 00499 data++; 00500 FLASH_ProgramWord(SAVE_ADDR+0x04,*data); // write word 2 (4 bytes) 00501 data++; 00502 FLASH_ProgramWord(SAVE_ADDR+0x08,*data); // write word 3 (4 bytes) 00503 data++; 00504 FLASH_ProgramWord(SAVE_ADDR+0x0C,*data); // write word 4 (4 bytes) 00505 data++; 00506 FLASH_ProgramHalfWord(SAVE_ADDR+0x10,*data); // write final half word (2 bytes) 00507 00508 FLASH_Lock(); // lock it back up 00509 } 00510 00511 00512 00513 void LoadControls() 00514 { 00515 memcpy(&kc,saveData,sizeof(KeyboardControls)); 00516 pc.printf("Controls have been loaded!\r\n"); 00517 } 00518 00519 int main() 00520 { 00521 bool buttonPressed = false; 00522 00523 pc.printf("\r\nNow loaded! SystemCoreClock = %d Hz\r\n", SystemCoreClock); 00524 LoadControls(); 00525 00526 USBHostKeyboard kb; 00527 if (!kb.connect()) { 00528 pc.printf("Error: USB kb not found.\n"); 00529 } 00530 // when connected, attach handler called on kb event 00531 kb.attach(onKeyboardEvent); 00532 00533 while(1) 00534 { 00535 if(state == NORMAL) 00536 { 00537 if(!button) // user wants to change controls 00538 { 00539 if(!buttonPressed) // make sure it's a separate button press 00540 { 00541 buttonPressed = true; 00542 state++; 00543 continue; 00544 } 00545 } 00546 else 00547 { 00548 buttonPressed = false; 00549 } 00550 00551 // Set pin mode to input 00552 data.input(); 00553 00554 USBHost::poll(); 00555 00556 __disable_irq(); // Disable Interrupts 00557 00558 // Read 64 command 00559 unsigned int cmd = readCommand(); 00560 00561 my_wait_us_asm(2); // wait a small amount of time before replying 00562 00563 //-------- SEND RESPONSE 00564 // Set pin mode to output 00565 data.output(); 00566 00567 switch(cmd) 00568 { 00569 case 0x00: // identity 00570 case 0xFF: // reset 00571 SendIdentity(); 00572 break; 00573 case 0x01: // poll for state 00574 SendControllerData(); 00575 break; 00576 default: 00577 // we do not process the read and write commands (memory pack) 00578 break; 00579 } 00580 __enable_irq(); // Enable Interrupts 00581 //-------- DONE SENDING RESPOSE 00582 } 00583 else 00584 { 00585 if(!button) // user wants to cancel and return to regular mode 00586 { 00587 if(!buttonPressed) // make sure it's a separate button press 00588 { 00589 state = NORMAL; 00590 buttonPressed = true; 00591 continue; 00592 } 00593 } 00594 else 00595 { 00596 buttonPressed = false; 00597 } 00598 00599 myled = !myled; 00600 USBHost::poll(); 00601 wait(0.1); 00602 00603 if(state == NORMAL) // about to return to normal operation, make sure the LED remains off 00604 { 00605 myled = false; 00606 KeyboardButtonPressed = false; 00607 } 00608 } 00609 } 00610 }
Generated on Sat Jul 16 2022 08:16:57 by 1.7.2