first release for keyboard

Dependencies:   F401RE-USBHost2 mbed

Files at this revision

API Documentation at this revision

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

F401RE-USBHost.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /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