
first release for keyboard
Dependencies: F401RE-USBHost2 mbed
Revision 1:3c21da72660d, committed 2016-10-31
- Comitter:
- Ownasaurus
- Date:
- Mon Oct 31 19:26:40 2016 +0000
- Parent:
- 0:eb2258e8c4b5
- Child:
- 2:77b20c9b1933
- Commit message:
- Functional KB<-->N64
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/F401RE-USBHost.lib Mon Oct 31 19:26:40 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/va009039/code/F401RE-USBHost/#75435a7ab25b
--- a/main.cpp Wed Oct 26 02:02:09 2016 +0000 +++ b/main.cpp Mon Oct 31 19:26:40 2016 +0000 @@ -1,11 +1,61 @@ +//TODO: save controller layout to sram +// finish and make 100% functional for keyboard players +// duplicate program and modify to work with x360 + #include "mbed.h" +#include "USBHostKeyboard.h" extern "C" void my_wait_us_asm (int n); +struct __attribute__((packed)) N64ControllerData // all bits are in the correct order +{ + unsigned int a : 1; // 1 bit wide + unsigned int b : 1; + unsigned int z : 1; + unsigned int start : 1; + unsigned int up : 1; + unsigned int down : 1; + unsigned int left : 1; + unsigned int right : 1; + + unsigned int dummy1 : 1; + unsigned int dummy2 : 1; + unsigned int l :1 ; + unsigned int r : 1; + unsigned int c_up : 1; + unsigned int c_down : 1; + unsigned int c_left : 1; + unsigned int c_right : 1; + + char x_axis; + + char y_axis; + +} n64_data; + +const uint8_t KEYBOARD_a = 0x0E; +const uint8_t KEYBOARD_b = 0x0D; +const uint8_t KEYBOARD_z = 0x0F; +const uint8_t KEYBOARD_start = 0x0B; +const uint8_t KEYBOARD_d_up = 0x1D; +const uint8_t KEYBOARD_d_down = 0x1B; +const uint8_t KEYBOARD_d_left = 0x06; +const uint8_t KEYBOARD_d_right = 0x19; +const uint8_t KEYBOARD_l = 0x1A; +const uint8_t KEYBOARD_r = 0x12; +const uint8_t KEYBOARD_c_up = 0x17; +const uint8_t KEYBOARD_c_down = 0x1C; +const uint8_t KEYBOARD_c_left = 0x18; +const uint8_t KEYBOARD_c_right = 0x0C; +const uint8_t KEYBOARD_a_up = 0x08; +const uint8_t KEYBOARD_a_down = 0x07; +const uint8_t KEYBOARD_a_left = 0x16; +const uint8_t KEYBOARD_a_right = 0x09; + DigitalOut myled(LED1); Serial pc(USBTX, USBRX); // tx, rx DigitalInOut data(PA_8); -DigitalIn button(PC_13); +//DigitalIn button(PC_13); // eventually code to set controlls // 0 is 3 microseconds low followed by 1 microsecond high // 1 is 1 microsecond low followed by 3 microseconds high @@ -46,11 +96,13 @@ if(bits_read >= 9) // only consider when at least a whole command's length has been read { - if(command == 0x3 || command == 0x1 || command == 0x1FF) + if(command == 0x3 || command == 0x1 || command == 0x1FF || command == 0x5 || command == 0x7) { // 0x3 = 0x1 + stop bit --> get controller state // 0x1 = 0x0 + stop bit --> who are you? // 0x1FF = 0xFF + stop bit --> reset signal + // 0x5 = 0x10 + stop bit --> read + // 0x7 = 0x11 + stop bit --> write command = command >> 1; // get rid of the stop bit return command; } @@ -64,7 +116,6 @@ my_wait_us_asm(1); data = 1; my_wait_us_asm(3); - //data = 0; //pc.printf("1"); } @@ -74,23 +125,21 @@ my_wait_us_asm(3); data = 1; my_wait_us_asm(1); - //data = 0; //pc.printf("0"); } -void sendStop() +void SendStop() { data = 0; my_wait_us_asm(1); data = 1; } -void sendByte(unsigned char b) +// send a byte from LSB to MSB (proper serialization) +void SendByte(unsigned char b) { - //pc.printf("\nTrying to send 0x%x\n",b); for(int i = 0;i < 8;i++) // send all 8 bits, one at a time - //for(int i = 7;i >= 0;i--) // send all 8 bits, in reverse order, one at a time { if((b >> i) & 1) { @@ -103,23 +152,145 @@ } } +void SendIdentity() +{ + // reply 0x05, 0x00, 0x02 + SendByte(0x05); + SendByte(0x00); + SendByte(0x02); + SendStop(); +} + +void SendControllerData() +{ + unsigned long data = *(unsigned long*)&n64_data; + unsigned int size = sizeof(data) * 8; // should be 4 bytes * 8 = 32 bits + + for(unsigned int i = 0;i < size;i++) + { + if((data >> i) & 1) + { + write_1(); + } + else + { + write_0(); + } + } + + SendStop(); +} + +// keyboard buttons are stored in cells 2 3 4 5 6 7? cell 0 and 1 are modifiers? cell8 is an F? +// the buttons all become 1 if overflow, i think. or in short, [2] == [3] +void onKeyboardEvent(uint8_t rep[9]) +{ + /*printf("Report = ["); + for(int i = 0;i < 8;i++) + { + printf("%X, ", rep[i]); + } + printf("%X]\r\n", rep[8]);*/ + + memset(&n64_data,0,4); // clear controller state + + bool leaveLoop = false; + + for(int index = 2;index < 8;index++) + { + switch(rep[index]) // the key code + { + case 0: // no more keys to process + leaveLoop = true; + break; + case KEYBOARD_a: + n64_data.a = 1; + break; + case KEYBOARD_b: + n64_data.b = 1; + break; + case KEYBOARD_z: + n64_data.z = 1; + break; + case KEYBOARD_start: + n64_data.start = 1; + break; + case KEYBOARD_d_up: + n64_data.up = 1; + break; + case KEYBOARD_d_down: + n64_data.down = 1; + break; + case KEYBOARD_d_left: + n64_data.left = 1; + break; + case KEYBOARD_d_right: + n64_data.right = 1; + break; + case KEYBOARD_l: + n64_data.l = 1; + break; + case KEYBOARD_r: + n64_data.r = 1; + break; + case KEYBOARD_c_up: + n64_data.c_up = 1; + break; + case KEYBOARD_c_down: + n64_data.c_down = 1; + break; + case KEYBOARD_c_left: + n64_data.c_left = 1; + break; + case KEYBOARD_c_right: + n64_data.c_right = 1; + break; + // NOTE: THESE BITS MUST BE WRITTEN IN REVERSE ORDER. HIGH BIT IS IN THE LOW POSITION + case KEYBOARD_a_up: + n64_data.y_axis = 0x0A; + break; + case KEYBOARD_a_down: + n64_data.y_axis = 0x0D; + break; + case KEYBOARD_a_left: + n64_data.x_axis = 0x0D; + break; + case KEYBOARD_a_right: + n64_data.x_axis = 0x0A; + break; + } + + if(leaveLoop) break; + } +} + int main() { - __disable_irq(); // Disable Interrupts - pc.printf("SystemCoreClock = %d Hz\n", SystemCoreClock); + pc.printf("Now loaded! SystemCoreClock = %d Hz\r\n", SystemCoreClock); + memset(&n64_data,0,4); // start controller in the neutral state + + USBHostKeyboard kb; + if (!kb.connect()) { + pc.printf("Error: USB kb not found.\n"); + } + // when connected, attach handler called on kb event + kb.attach(onKeyboardEvent); while(1) { // Set pin mode to input data.input(); - // Read command + // Read keyboard state? + USBHost::poll(); + + __disable_irq(); // Disable Interrupts + // Read 64 command unsigned int cmd = readCommand(); - //pc.printf("Read command: %u\n", cmd); - my_wait_us_asm(2); // wait a small amount of time before replying - + + //-------- SEND RESPONSE // Set pin mode to output data.output(); @@ -127,33 +298,16 @@ { case 0x00: // identity case 0xFF: // reset - //pc.printf("Received identity "); - // reply 0x05, 0x00, 0x02 - sendByte(0x05); - sendByte(0x00); - sendByte(0x02); - sendStop(); + SendIdentity(); break; case 0x01: // poll for state - if(!button.read()) // simulate Start pressed - { - sendByte(0x08); // I think this is start, 4th bit - sendByte(0x00); - sendByte(0x00); - sendByte(0x00); - sendStop(); - break; - } - else - { - // respond with controller state - sendByte(0x00); - sendByte(0x00); - sendByte(0x00); - sendByte(0x00); - sendStop(); - break; - } + SendControllerData(); + break; + default: + // we do not process the read and write commands (memory pack) + break; } + __enable_irq(); // Enable Interrupts + //-------- DONE SENDING RESPOSE } }
--- a/mbed.bld Wed Oct 26 02:02:09 2016 +0000 +++ b/mbed.bld Mon Oct 31 19:26:40 2016 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mbed_official/code/mbed/builds/25aea2a3f4e3 \ No newline at end of file +http://mbed.org/users/mbed_official/code/mbed/builds/aae6fcc7d9bb \ No newline at end of file