first release for keyboard

Dependencies:   F401RE-USBHost2 mbed

Committer:
Ownasaurus
Date:
Mon May 29 14:51:08 2017 +0000
Revision:
4:dbb0d3d2ad8b
Parent:
2:77b20c9b1933
fix for certain types of keyboards

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Ownasaurus 2:77b20c9b1933 1 // TODO: work off controler 3.3v if possible
Ownasaurus 1:3c21da72660d 2
Ownasaurus 0:eb2258e8c4b5 3 #include "mbed.h"
Ownasaurus 1:3c21da72660d 4 #include "USBHostKeyboard.h"
Ownasaurus 2:77b20c9b1933 5 #include "stm32f4xx_flash.h"
Ownasaurus 2:77b20c9b1933 6
Ownasaurus 2:77b20c9b1933 7 DigitalOut myled(LED1);
Ownasaurus 2:77b20c9b1933 8 Serial pc(USBTX, USBRX); // tx, rx
Ownasaurus 2:77b20c9b1933 9 DigitalInOut data(PA_8);
Ownasaurus 2:77b20c9b1933 10 DigitalIn button(PC_13); // eventually code to set controls
Ownasaurus 0:eb2258e8c4b5 11
Ownasaurus 0:eb2258e8c4b5 12 extern "C" void my_wait_us_asm (int n);
Ownasaurus 0:eb2258e8c4b5 13
Ownasaurus 2:77b20c9b1933 14 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};
Ownasaurus 2:77b20c9b1933 15 uint8_t state = NORMAL; //done remapping when >= 19
Ownasaurus 2:77b20c9b1933 16
Ownasaurus 2:77b20c9b1933 17 bool KeyboardButtonPressed = false;
Ownasaurus 2:77b20c9b1933 18 void LoadControls();
Ownasaurus 2:77b20c9b1933 19 void SaveControls();
Ownasaurus 2:77b20c9b1933 20
Ownasaurus 1:3c21da72660d 21 struct __attribute__((packed)) N64ControllerData // all bits are in the correct order
Ownasaurus 1:3c21da72660d 22 {
Ownasaurus 1:3c21da72660d 23 unsigned int a : 1; // 1 bit wide
Ownasaurus 1:3c21da72660d 24 unsigned int b : 1;
Ownasaurus 1:3c21da72660d 25 unsigned int z : 1;
Ownasaurus 1:3c21da72660d 26 unsigned int start : 1;
Ownasaurus 1:3c21da72660d 27 unsigned int up : 1;
Ownasaurus 1:3c21da72660d 28 unsigned int down : 1;
Ownasaurus 1:3c21da72660d 29 unsigned int left : 1;
Ownasaurus 1:3c21da72660d 30 unsigned int right : 1;
Ownasaurus 1:3c21da72660d 31
Ownasaurus 1:3c21da72660d 32 unsigned int dummy1 : 1;
Ownasaurus 1:3c21da72660d 33 unsigned int dummy2 : 1;
Ownasaurus 1:3c21da72660d 34 unsigned int l :1 ;
Ownasaurus 1:3c21da72660d 35 unsigned int r : 1;
Ownasaurus 1:3c21da72660d 36 unsigned int c_up : 1;
Ownasaurus 1:3c21da72660d 37 unsigned int c_down : 1;
Ownasaurus 1:3c21da72660d 38 unsigned int c_left : 1;
Ownasaurus 1:3c21da72660d 39 unsigned int c_right : 1;
Ownasaurus 1:3c21da72660d 40
Ownasaurus 1:3c21da72660d 41 char x_axis;
Ownasaurus 1:3c21da72660d 42
Ownasaurus 1:3c21da72660d 43 char y_axis;
Ownasaurus 1:3c21da72660d 44
Ownasaurus 1:3c21da72660d 45 } n64_data;
Ownasaurus 1:3c21da72660d 46
Ownasaurus 2:77b20c9b1933 47 struct __attribute__((packed)) KeyboardControls
Ownasaurus 2:77b20c9b1933 48 {
Ownasaurus 2:77b20c9b1933 49 uint8_t KEYBOARD_a;
Ownasaurus 2:77b20c9b1933 50 uint8_t KEYBOARD_b;
Ownasaurus 2:77b20c9b1933 51 uint8_t KEYBOARD_z;
Ownasaurus 2:77b20c9b1933 52 uint8_t KEYBOARD_start;
Ownasaurus 2:77b20c9b1933 53
Ownasaurus 2:77b20c9b1933 54 uint8_t KEYBOARD_d_up;
Ownasaurus 2:77b20c9b1933 55 uint8_t KEYBOARD_d_down;
Ownasaurus 2:77b20c9b1933 56 uint8_t KEYBOARD_d_left;
Ownasaurus 2:77b20c9b1933 57 uint8_t KEYBOARD_d_right;
Ownasaurus 2:77b20c9b1933 58
Ownasaurus 2:77b20c9b1933 59 uint8_t KEYBOARD_l;
Ownasaurus 2:77b20c9b1933 60 uint8_t KEYBOARD_r;
Ownasaurus 2:77b20c9b1933 61 uint8_t KEYBOARD_c_up;
Ownasaurus 2:77b20c9b1933 62 uint8_t KEYBOARD_c_down;
Ownasaurus 2:77b20c9b1933 63
Ownasaurus 2:77b20c9b1933 64 uint8_t KEYBOARD_c_left;
Ownasaurus 2:77b20c9b1933 65 uint8_t KEYBOARD_c_right;
Ownasaurus 2:77b20c9b1933 66 uint8_t KEYBOARD_a_up;
Ownasaurus 2:77b20c9b1933 67 uint8_t KEYBOARD_a_down;
Ownasaurus 2:77b20c9b1933 68
Ownasaurus 2:77b20c9b1933 69 uint8_t KEYBOARD_a_left;
Ownasaurus 2:77b20c9b1933 70 uint8_t KEYBOARD_a_right;
Ownasaurus 2:77b20c9b1933 71
Ownasaurus 2:77b20c9b1933 72 KeyboardControls()
Ownasaurus 2:77b20c9b1933 73 {
Ownasaurus 2:77b20c9b1933 74 LoadDefault();
Ownasaurus 2:77b20c9b1933 75 }
Ownasaurus 2:77b20c9b1933 76
Ownasaurus 2:77b20c9b1933 77 void LoadDefault()
Ownasaurus 2:77b20c9b1933 78 {
Ownasaurus 2:77b20c9b1933 79 KEYBOARD_a = 0x0E;
Ownasaurus 2:77b20c9b1933 80 KEYBOARD_b = 0x0D;
Ownasaurus 2:77b20c9b1933 81 KEYBOARD_z = 0x0F;
Ownasaurus 2:77b20c9b1933 82 KEYBOARD_start = 0x0B;
Ownasaurus 2:77b20c9b1933 83 KEYBOARD_d_up = 0x1D;
Ownasaurus 2:77b20c9b1933 84 KEYBOARD_d_down = 0x1B;
Ownasaurus 2:77b20c9b1933 85 KEYBOARD_d_left = 0x06;
Ownasaurus 2:77b20c9b1933 86 KEYBOARD_d_right = 0x19;
Ownasaurus 2:77b20c9b1933 87 KEYBOARD_l = 0x1A;
Ownasaurus 2:77b20c9b1933 88 KEYBOARD_r = 0x12;
Ownasaurus 2:77b20c9b1933 89 KEYBOARD_c_up = 0x17;
Ownasaurus 2:77b20c9b1933 90 KEYBOARD_c_down = 0x1C;
Ownasaurus 2:77b20c9b1933 91 KEYBOARD_c_left = 0x18;
Ownasaurus 2:77b20c9b1933 92 KEYBOARD_c_right = 0x0C;
Ownasaurus 2:77b20c9b1933 93 KEYBOARD_a_up = 0x08;
Ownasaurus 2:77b20c9b1933 94 KEYBOARD_a_down = 0x07;
Ownasaurus 2:77b20c9b1933 95 KEYBOARD_a_left = 0x16;
Ownasaurus 2:77b20c9b1933 96 KEYBOARD_a_right = 0x09;
Ownasaurus 2:77b20c9b1933 97 }
Ownasaurus 2:77b20c9b1933 98
Ownasaurus 2:77b20c9b1933 99 void LoadBlank()
Ownasaurus 2:77b20c9b1933 100 {
Ownasaurus 2:77b20c9b1933 101 KEYBOARD_a = 0x00;
Ownasaurus 2:77b20c9b1933 102 KEYBOARD_b = 0x00;
Ownasaurus 2:77b20c9b1933 103 KEYBOARD_z = 0x00;
Ownasaurus 2:77b20c9b1933 104 KEYBOARD_start = 0x00;
Ownasaurus 2:77b20c9b1933 105 KEYBOARD_d_up = 0x00;
Ownasaurus 2:77b20c9b1933 106 KEYBOARD_d_down = 0x00;
Ownasaurus 2:77b20c9b1933 107 KEYBOARD_d_left = 0x00;
Ownasaurus 2:77b20c9b1933 108 KEYBOARD_d_right = 0x00;
Ownasaurus 2:77b20c9b1933 109 KEYBOARD_l = 0x00;
Ownasaurus 2:77b20c9b1933 110 KEYBOARD_r = 0x00;
Ownasaurus 2:77b20c9b1933 111 KEYBOARD_c_up = 0x00;
Ownasaurus 2:77b20c9b1933 112 KEYBOARD_c_down = 0x00;
Ownasaurus 2:77b20c9b1933 113 KEYBOARD_c_left = 0x00;
Ownasaurus 2:77b20c9b1933 114 KEYBOARD_c_right = 0x00;
Ownasaurus 2:77b20c9b1933 115 KEYBOARD_a_up = 0x00;
Ownasaurus 2:77b20c9b1933 116 KEYBOARD_a_down = 0x00;
Ownasaurus 2:77b20c9b1933 117 KEYBOARD_a_left = 0x00;
Ownasaurus 2:77b20c9b1933 118 KEYBOARD_a_right = 0x00;
Ownasaurus 2:77b20c9b1933 119 }
Ownasaurus 2:77b20c9b1933 120 };
Ownasaurus 1:3c21da72660d 121
Ownasaurus 2:77b20c9b1933 122 KeyboardControls kc;
Ownasaurus 2:77b20c9b1933 123
Ownasaurus 2:77b20c9b1933 124 const int SAVE_ADDR = 0x0800C000; // sector 3
Ownasaurus 2:77b20c9b1933 125 KeyboardControls* saveData = (KeyboardControls*)SAVE_ADDR;
Ownasaurus 0:eb2258e8c4b5 126
Ownasaurus 0:eb2258e8c4b5 127 // 0 is 3 microseconds low followed by 1 microsecond high
Ownasaurus 0:eb2258e8c4b5 128 // 1 is 1 microsecond low followed by 3 microseconds high
Ownasaurus 0:eb2258e8c4b5 129 unsigned int GetMiddleOfPulse()
Ownasaurus 0:eb2258e8c4b5 130 {
Ownasaurus 0:eb2258e8c4b5 131 // wait for line to go high
Ownasaurus 0:eb2258e8c4b5 132 while(1)
Ownasaurus 0:eb2258e8c4b5 133 {
Ownasaurus 0:eb2258e8c4b5 134 if(data.read() == 1) break;
Ownasaurus 0:eb2258e8c4b5 135 }
Ownasaurus 0:eb2258e8c4b5 136
Ownasaurus 0:eb2258e8c4b5 137 // wait for line to go low
Ownasaurus 0:eb2258e8c4b5 138 while(1)
Ownasaurus 0:eb2258e8c4b5 139 {
Ownasaurus 0:eb2258e8c4b5 140 if(data.read() == 0) break;
Ownasaurus 0:eb2258e8c4b5 141 }
Ownasaurus 0:eb2258e8c4b5 142
Ownasaurus 0:eb2258e8c4b5 143 // now we have the falling edge
Ownasaurus 0:eb2258e8c4b5 144 // wait 2 microseconds to be in the middle of the pulse, and read. high --> 1. low --> 0.
Ownasaurus 0:eb2258e8c4b5 145 my_wait_us_asm(2);
Ownasaurus 0:eb2258e8c4b5 146 return (unsigned int) data.read();
Ownasaurus 0:eb2258e8c4b5 147 }
Ownasaurus 0:eb2258e8c4b5 148
Ownasaurus 0:eb2258e8c4b5 149 // continuously read bits until at least 9 are read, confirm valid command, return without stop bit
Ownasaurus 0:eb2258e8c4b5 150 unsigned int readCommand()
Ownasaurus 0:eb2258e8c4b5 151 {
Ownasaurus 0:eb2258e8c4b5 152 unsigned int command = GetMiddleOfPulse(), bits_read = 1;
Ownasaurus 0:eb2258e8c4b5 153
Ownasaurus 0:eb2258e8c4b5 154 while(1) // read at least 9 bits (2 bytes + stop bit)
Ownasaurus 0:eb2258e8c4b5 155 {
Ownasaurus 0:eb2258e8c4b5 156 //my_wait_us_asm(4);
Ownasaurus 0:eb2258e8c4b5 157 command = command << 1; // make room for the new bit
Ownasaurus 0:eb2258e8c4b5 158 //command += data.read(); // place the new bit into the command
Ownasaurus 0:eb2258e8c4b5 159 command += GetMiddleOfPulse();
Ownasaurus 0:eb2258e8c4b5 160 command &= 0x1FF; // remove all except the last 9 bits
Ownasaurus 0:eb2258e8c4b5 161
Ownasaurus 0:eb2258e8c4b5 162 bits_read++;
Ownasaurus 0:eb2258e8c4b5 163
Ownasaurus 0:eb2258e8c4b5 164 if(bits_read >= 9) // only consider when at least a whole command's length has been read
Ownasaurus 0:eb2258e8c4b5 165 {
Ownasaurus 1:3c21da72660d 166 if(command == 0x3 || command == 0x1 || command == 0x1FF || command == 0x5 || command == 0x7)
Ownasaurus 0:eb2258e8c4b5 167 {
Ownasaurus 0:eb2258e8c4b5 168 // 0x3 = 0x1 + stop bit --> get controller state
Ownasaurus 0:eb2258e8c4b5 169 // 0x1 = 0x0 + stop bit --> who are you?
Ownasaurus 0:eb2258e8c4b5 170 // 0x1FF = 0xFF + stop bit --> reset signal
Ownasaurus 1:3c21da72660d 171 // 0x5 = 0x10 + stop bit --> read
Ownasaurus 1:3c21da72660d 172 // 0x7 = 0x11 + stop bit --> write
Ownasaurus 0:eb2258e8c4b5 173 command = command >> 1; // get rid of the stop bit
Ownasaurus 0:eb2258e8c4b5 174 return command;
Ownasaurus 0:eb2258e8c4b5 175 }
Ownasaurus 0:eb2258e8c4b5 176 }
Ownasaurus 0:eb2258e8c4b5 177 }
Ownasaurus 0:eb2258e8c4b5 178 }
Ownasaurus 0:eb2258e8c4b5 179
Ownasaurus 0:eb2258e8c4b5 180 void write_1()
Ownasaurus 0:eb2258e8c4b5 181 {
Ownasaurus 0:eb2258e8c4b5 182 data = 0;
Ownasaurus 0:eb2258e8c4b5 183 my_wait_us_asm(1);
Ownasaurus 0:eb2258e8c4b5 184 data = 1;
Ownasaurus 0:eb2258e8c4b5 185 my_wait_us_asm(3);
Ownasaurus 0:eb2258e8c4b5 186 //pc.printf("1");
Ownasaurus 0:eb2258e8c4b5 187 }
Ownasaurus 0:eb2258e8c4b5 188
Ownasaurus 0:eb2258e8c4b5 189 void write_0()
Ownasaurus 0:eb2258e8c4b5 190 {
Ownasaurus 0:eb2258e8c4b5 191 data = 0;
Ownasaurus 0:eb2258e8c4b5 192 my_wait_us_asm(3);
Ownasaurus 0:eb2258e8c4b5 193 data = 1;
Ownasaurus 0:eb2258e8c4b5 194 my_wait_us_asm(1);
Ownasaurus 0:eb2258e8c4b5 195 //pc.printf("0");
Ownasaurus 0:eb2258e8c4b5 196 }
Ownasaurus 0:eb2258e8c4b5 197
Ownasaurus 0:eb2258e8c4b5 198
Ownasaurus 1:3c21da72660d 199 void SendStop()
Ownasaurus 0:eb2258e8c4b5 200 {
Ownasaurus 0:eb2258e8c4b5 201 data = 0;
Ownasaurus 0:eb2258e8c4b5 202 my_wait_us_asm(1);
Ownasaurus 0:eb2258e8c4b5 203 data = 1;
Ownasaurus 0:eb2258e8c4b5 204 }
Ownasaurus 0:eb2258e8c4b5 205
Ownasaurus 1:3c21da72660d 206 // send a byte from LSB to MSB (proper serialization)
Ownasaurus 1:3c21da72660d 207 void SendByte(unsigned char b)
Ownasaurus 0:eb2258e8c4b5 208 {
Ownasaurus 0:eb2258e8c4b5 209 for(int i = 0;i < 8;i++) // send all 8 bits, one at a time
Ownasaurus 0:eb2258e8c4b5 210 {
Ownasaurus 0:eb2258e8c4b5 211 if((b >> i) & 1)
Ownasaurus 0:eb2258e8c4b5 212 {
Ownasaurus 0:eb2258e8c4b5 213 write_1();
Ownasaurus 0:eb2258e8c4b5 214 }
Ownasaurus 0:eb2258e8c4b5 215 else
Ownasaurus 0:eb2258e8c4b5 216 {
Ownasaurus 0:eb2258e8c4b5 217 write_0();
Ownasaurus 0:eb2258e8c4b5 218 }
Ownasaurus 0:eb2258e8c4b5 219 }
Ownasaurus 0:eb2258e8c4b5 220 }
Ownasaurus 0:eb2258e8c4b5 221
Ownasaurus 1:3c21da72660d 222 void SendIdentity()
Ownasaurus 1:3c21da72660d 223 {
Ownasaurus 1:3c21da72660d 224 // reply 0x05, 0x00, 0x02
Ownasaurus 1:3c21da72660d 225 SendByte(0x05);
Ownasaurus 1:3c21da72660d 226 SendByte(0x00);
Ownasaurus 1:3c21da72660d 227 SendByte(0x02);
Ownasaurus 1:3c21da72660d 228 SendStop();
Ownasaurus 1:3c21da72660d 229 }
Ownasaurus 1:3c21da72660d 230
Ownasaurus 1:3c21da72660d 231 void SendControllerData()
Ownasaurus 1:3c21da72660d 232 {
Ownasaurus 1:3c21da72660d 233 unsigned long data = *(unsigned long*)&n64_data;
Ownasaurus 1:3c21da72660d 234 unsigned int size = sizeof(data) * 8; // should be 4 bytes * 8 = 32 bits
Ownasaurus 1:3c21da72660d 235
Ownasaurus 1:3c21da72660d 236 for(unsigned int i = 0;i < size;i++)
Ownasaurus 1:3c21da72660d 237 {
Ownasaurus 1:3c21da72660d 238 if((data >> i) & 1)
Ownasaurus 1:3c21da72660d 239 {
Ownasaurus 1:3c21da72660d 240 write_1();
Ownasaurus 1:3c21da72660d 241 }
Ownasaurus 1:3c21da72660d 242 else
Ownasaurus 1:3c21da72660d 243 {
Ownasaurus 1:3c21da72660d 244 write_0();
Ownasaurus 1:3c21da72660d 245 }
Ownasaurus 1:3c21da72660d 246 }
Ownasaurus 1:3c21da72660d 247
Ownasaurus 1:3c21da72660d 248 SendStop();
Ownasaurus 1:3c21da72660d 249 }
Ownasaurus 1:3c21da72660d 250
Ownasaurus 2:77b20c9b1933 251 char reverse(char b)
Ownasaurus 2:77b20c9b1933 252 {
Ownasaurus 2:77b20c9b1933 253 b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
Ownasaurus 2:77b20c9b1933 254 b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
Ownasaurus 2:77b20c9b1933 255 b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
Ownasaurus 2:77b20c9b1933 256 return b;
Ownasaurus 2:77b20c9b1933 257 }
Ownasaurus 2:77b20c9b1933 258
Ownasaurus 2:77b20c9b1933 259 void ChangeButtonMapping(uint8_t bt)
Ownasaurus 2:77b20c9b1933 260 {
Ownasaurus 2:77b20c9b1933 261 // analog settings must be hardcoded, cannot change on the fly
Ownasaurus 2:77b20c9b1933 262 if(state == A_UP) // state = 1 --> analog up
Ownasaurus 2:77b20c9b1933 263 {
Ownasaurus 2:77b20c9b1933 264 kc.KEYBOARD_a_up = bt;
Ownasaurus 2:77b20c9b1933 265 }
Ownasaurus 2:77b20c9b1933 266 else if(state == A_DOWN) // state = 2 --> analog up
Ownasaurus 2:77b20c9b1933 267 {
Ownasaurus 2:77b20c9b1933 268 kc.KEYBOARD_a_down = bt;
Ownasaurus 2:77b20c9b1933 269 }
Ownasaurus 2:77b20c9b1933 270 else if(state == A_LEFT) // state = 3 --> analog up
Ownasaurus 2:77b20c9b1933 271 {
Ownasaurus 2:77b20c9b1933 272 kc.KEYBOARD_a_left = bt;
Ownasaurus 2:77b20c9b1933 273 }
Ownasaurus 2:77b20c9b1933 274 else if(state == A_RIGHT) // state = 4 --> analog up
Ownasaurus 2:77b20c9b1933 275 {
Ownasaurus 2:77b20c9b1933 276 kc.KEYBOARD_a_right = bt;
Ownasaurus 2:77b20c9b1933 277 }
Ownasaurus 2:77b20c9b1933 278 else if(state == DPAD_UP) // state = 5 --> dpad up
Ownasaurus 2:77b20c9b1933 279 {
Ownasaurus 2:77b20c9b1933 280 kc.KEYBOARD_d_up = bt;
Ownasaurus 2:77b20c9b1933 281 }
Ownasaurus 2:77b20c9b1933 282 else if(state == DPAD_DOWN) // state = 6 --> dpad down
Ownasaurus 2:77b20c9b1933 283 {
Ownasaurus 2:77b20c9b1933 284 kc.KEYBOARD_d_down = bt;
Ownasaurus 2:77b20c9b1933 285 }
Ownasaurus 2:77b20c9b1933 286 else if(state == DPAD_LEFT) // state = 7 --> dpad left
Ownasaurus 2:77b20c9b1933 287 {
Ownasaurus 2:77b20c9b1933 288 kc.KEYBOARD_d_left = bt;
Ownasaurus 2:77b20c9b1933 289 }
Ownasaurus 2:77b20c9b1933 290 else if(state == DPAD_RIGHT) // state = 8 --> dpad right
Ownasaurus 2:77b20c9b1933 291 {
Ownasaurus 2:77b20c9b1933 292 kc.KEYBOARD_d_right = bt;
Ownasaurus 2:77b20c9b1933 293 }
Ownasaurus 2:77b20c9b1933 294 else if(state == BUTTON_START) // state = 9 --> start
Ownasaurus 2:77b20c9b1933 295 {
Ownasaurus 2:77b20c9b1933 296 kc.KEYBOARD_start = bt;
Ownasaurus 2:77b20c9b1933 297 }
Ownasaurus 2:77b20c9b1933 298 else if(state == BUTTON_B) // state = 10 --> B
Ownasaurus 2:77b20c9b1933 299 {
Ownasaurus 2:77b20c9b1933 300 kc.KEYBOARD_b = bt;
Ownasaurus 2:77b20c9b1933 301 }
Ownasaurus 2:77b20c9b1933 302 else if(state == BUTTON_A) // state = 11 --> A
Ownasaurus 2:77b20c9b1933 303 {
Ownasaurus 2:77b20c9b1933 304 kc.KEYBOARD_a = bt;
Ownasaurus 2:77b20c9b1933 305 }
Ownasaurus 2:77b20c9b1933 306 else if(state == C_UP) // state = 12 --> c up
Ownasaurus 2:77b20c9b1933 307 {
Ownasaurus 2:77b20c9b1933 308 kc.KEYBOARD_c_up = bt;
Ownasaurus 2:77b20c9b1933 309 }
Ownasaurus 2:77b20c9b1933 310 else if(state == C_DOWN) // state = 13 --> c down
Ownasaurus 2:77b20c9b1933 311 {
Ownasaurus 2:77b20c9b1933 312 kc.KEYBOARD_c_down = bt;
Ownasaurus 2:77b20c9b1933 313 }
Ownasaurus 2:77b20c9b1933 314 else if(state == C_LEFT) // state = 14 --> c left
Ownasaurus 2:77b20c9b1933 315 {
Ownasaurus 2:77b20c9b1933 316 kc.KEYBOARD_c_left = bt;
Ownasaurus 2:77b20c9b1933 317 }
Ownasaurus 2:77b20c9b1933 318 else if(state == C_RIGHT) // state = 15 --> c right
Ownasaurus 2:77b20c9b1933 319 {
Ownasaurus 2:77b20c9b1933 320 kc.KEYBOARD_c_right = bt;
Ownasaurus 2:77b20c9b1933 321 }
Ownasaurus 2:77b20c9b1933 322 else if(state == BUTTON_L) // state = 16 --> L
Ownasaurus 2:77b20c9b1933 323 {
Ownasaurus 2:77b20c9b1933 324 kc.KEYBOARD_l = bt;
Ownasaurus 2:77b20c9b1933 325 }
Ownasaurus 2:77b20c9b1933 326 else if(state == BUTTON_R) // state = 17 --> R
Ownasaurus 2:77b20c9b1933 327 {
Ownasaurus 2:77b20c9b1933 328 kc.KEYBOARD_r = bt;
Ownasaurus 2:77b20c9b1933 329 }
Ownasaurus 2:77b20c9b1933 330 else if(state == BUTTON_Z) // state = 18 --> Z
Ownasaurus 2:77b20c9b1933 331 {
Ownasaurus 2:77b20c9b1933 332 kc.KEYBOARD_z = bt;
Ownasaurus 2:77b20c9b1933 333 }
Ownasaurus 2:77b20c9b1933 334 }
Ownasaurus 2:77b20c9b1933 335
Ownasaurus 2:77b20c9b1933 336 void AdvanceState()
Ownasaurus 2:77b20c9b1933 337 {
Ownasaurus 2:77b20c9b1933 338 state++;
Ownasaurus 2:77b20c9b1933 339 if(state >= 19) // we're done mapping the controls
Ownasaurus 2:77b20c9b1933 340 {
Ownasaurus 2:77b20c9b1933 341 SaveControls(); // write directly to flash
Ownasaurus 2:77b20c9b1933 342 state = NORMAL; // back to normal controller operation
Ownasaurus 2:77b20c9b1933 343 }
Ownasaurus 2:77b20c9b1933 344 }
Ownasaurus 2:77b20c9b1933 345
Ownasaurus 1:3c21da72660d 346 void onKeyboardEvent(uint8_t rep[9])
Ownasaurus 1:3c21da72660d 347 {
Ownasaurus 2:77b20c9b1933 348 // the buttons all become 1 if overflow, i think. or in short, [2] == [3]
Ownasaurus 2:77b20c9b1933 349 if(rep[2] == rep[3] && rep[2] == 1)
Ownasaurus 2:77b20c9b1933 350 return;
Ownasaurus 1:3c21da72660d 351
Ownasaurus 2:77b20c9b1933 352 if(state == NORMAL)
Ownasaurus 1:3c21da72660d 353 {
Ownasaurus 2:77b20c9b1933 354 memset(&n64_data,0,4); // clear controller state
Ownasaurus 2:77b20c9b1933 355
Ownasaurus 2:77b20c9b1933 356 // keyboard buttons are stored in cells 2 3 4 5 6 7? cell 0 and 1 are modifiers? cell8 is an F?
Ownasaurus 2:77b20c9b1933 357 for(int index = 2;index < 8;index++)
Ownasaurus 1:3c21da72660d 358 {
Ownasaurus 4:dbb0d3d2ad8b 359 if(rep[index] == 0) // no key to process
Ownasaurus 2:77b20c9b1933 360 {
Ownasaurus 4:dbb0d3d2ad8b 361 continue;
Ownasaurus 2:77b20c9b1933 362 }
Ownasaurus 2:77b20c9b1933 363 if(rep[index] == kc.KEYBOARD_a)
Ownasaurus 2:77b20c9b1933 364 {
Ownasaurus 2:77b20c9b1933 365 n64_data.a = 1;
Ownasaurus 2:77b20c9b1933 366 continue;
Ownasaurus 2:77b20c9b1933 367 }
Ownasaurus 2:77b20c9b1933 368 if(rep[index] == kc.KEYBOARD_b)
Ownasaurus 2:77b20c9b1933 369 {
Ownasaurus 2:77b20c9b1933 370 n64_data.b = 1;
Ownasaurus 2:77b20c9b1933 371 continue;
Ownasaurus 2:77b20c9b1933 372 }
Ownasaurus 2:77b20c9b1933 373 if(rep[index] == kc.KEYBOARD_z)
Ownasaurus 2:77b20c9b1933 374 {
Ownasaurus 2:77b20c9b1933 375 n64_data.z = 1;
Ownasaurus 2:77b20c9b1933 376 continue;
Ownasaurus 2:77b20c9b1933 377 }
Ownasaurus 2:77b20c9b1933 378 if(rep[index] == kc.KEYBOARD_start)
Ownasaurus 2:77b20c9b1933 379 {
Ownasaurus 2:77b20c9b1933 380 n64_data.start = 1;
Ownasaurus 2:77b20c9b1933 381 continue;
Ownasaurus 2:77b20c9b1933 382 }
Ownasaurus 2:77b20c9b1933 383 if(rep[index] == kc.KEYBOARD_d_up)
Ownasaurus 2:77b20c9b1933 384 {
Ownasaurus 2:77b20c9b1933 385 n64_data.up = 1;
Ownasaurus 2:77b20c9b1933 386 continue;
Ownasaurus 2:77b20c9b1933 387 }
Ownasaurus 2:77b20c9b1933 388 if(rep[index] == kc.KEYBOARD_d_down)
Ownasaurus 2:77b20c9b1933 389 {
Ownasaurus 2:77b20c9b1933 390 n64_data.down = 1;
Ownasaurus 2:77b20c9b1933 391 continue;
Ownasaurus 2:77b20c9b1933 392 }
Ownasaurus 2:77b20c9b1933 393 if(rep[index] == kc.KEYBOARD_d_left)
Ownasaurus 2:77b20c9b1933 394 {
Ownasaurus 2:77b20c9b1933 395 n64_data.left = 1;
Ownasaurus 2:77b20c9b1933 396 continue;
Ownasaurus 2:77b20c9b1933 397 }
Ownasaurus 2:77b20c9b1933 398 if(rep[index] == kc.KEYBOARD_d_right)
Ownasaurus 2:77b20c9b1933 399 {
Ownasaurus 1:3c21da72660d 400 n64_data.right = 1;
Ownasaurus 2:77b20c9b1933 401 continue;
Ownasaurus 2:77b20c9b1933 402 }
Ownasaurus 2:77b20c9b1933 403 if(rep[index] == kc.KEYBOARD_l)
Ownasaurus 2:77b20c9b1933 404 {
Ownasaurus 1:3c21da72660d 405 n64_data.l = 1;
Ownasaurus 2:77b20c9b1933 406 continue;
Ownasaurus 2:77b20c9b1933 407 }
Ownasaurus 2:77b20c9b1933 408 if(rep[index] == kc.KEYBOARD_r)
Ownasaurus 2:77b20c9b1933 409 {
Ownasaurus 1:3c21da72660d 410 n64_data.r = 1;
Ownasaurus 2:77b20c9b1933 411 continue;
Ownasaurus 2:77b20c9b1933 412 }
Ownasaurus 2:77b20c9b1933 413 if(rep[index] == kc.KEYBOARD_c_up)
Ownasaurus 2:77b20c9b1933 414 {
Ownasaurus 1:3c21da72660d 415 n64_data.c_up = 1;
Ownasaurus 2:77b20c9b1933 416 continue;
Ownasaurus 2:77b20c9b1933 417 }
Ownasaurus 2:77b20c9b1933 418 if(rep[index] == kc.KEYBOARD_c_down)
Ownasaurus 2:77b20c9b1933 419 {
Ownasaurus 1:3c21da72660d 420 n64_data.c_down = 1;
Ownasaurus 2:77b20c9b1933 421 continue;
Ownasaurus 2:77b20c9b1933 422 }
Ownasaurus 2:77b20c9b1933 423 if(rep[index] == kc.KEYBOARD_c_left)
Ownasaurus 2:77b20c9b1933 424 {
Ownasaurus 1:3c21da72660d 425 n64_data.c_left = 1;
Ownasaurus 2:77b20c9b1933 426 continue;
Ownasaurus 2:77b20c9b1933 427 }
Ownasaurus 2:77b20c9b1933 428 if(rep[index] == kc.KEYBOARD_c_right)
Ownasaurus 2:77b20c9b1933 429 {
Ownasaurus 1:3c21da72660d 430 n64_data.c_right = 1;
Ownasaurus 2:77b20c9b1933 431 continue;
Ownasaurus 2:77b20c9b1933 432 }
Ownasaurus 1:3c21da72660d 433 // NOTE: THESE BITS MUST BE WRITTEN IN REVERSE ORDER. HIGH BIT IS IN THE LOW POSITION
Ownasaurus 2:77b20c9b1933 434 if(rep[index] == kc.KEYBOARD_a_up)
Ownasaurus 2:77b20c9b1933 435 {
Ownasaurus 4:dbb0d3d2ad8b 436 //n64_data.y_axis = 0x0A; // 80(dec) bit reversed
Ownasaurus 4:dbb0d3d2ad8b 437 n64_data.y_axis = 0xB4; // 2D = 45 = 35% = no tap jump. bit reverse 2D (00101101) to get B4 (10110100)
Ownasaurus 2:77b20c9b1933 438 continue;
Ownasaurus 2:77b20c9b1933 439 }
Ownasaurus 2:77b20c9b1933 440 if(rep[index] == kc.KEYBOARD_a_down)
Ownasaurus 2:77b20c9b1933 441 {
Ownasaurus 2:77b20c9b1933 442 n64_data.y_axis = 0x0D; // -80(dec) bit reversed
Ownasaurus 2:77b20c9b1933 443 continue;
Ownasaurus 2:77b20c9b1933 444 }
Ownasaurus 2:77b20c9b1933 445 if(rep[index] == kc.KEYBOARD_a_left)
Ownasaurus 2:77b20c9b1933 446 {
Ownasaurus 1:3c21da72660d 447 n64_data.x_axis = 0x0D;
Ownasaurus 2:77b20c9b1933 448 continue;
Ownasaurus 2:77b20c9b1933 449 }
Ownasaurus 2:77b20c9b1933 450 if(rep[index] == kc.KEYBOARD_a_right)
Ownasaurus 2:77b20c9b1933 451 {
Ownasaurus 1:3c21da72660d 452 n64_data.x_axis = 0x0A;
Ownasaurus 2:77b20c9b1933 453 continue;
Ownasaurus 2:77b20c9b1933 454 }
Ownasaurus 2:77b20c9b1933 455 }
Ownasaurus 2:77b20c9b1933 456 }
Ownasaurus 2:77b20c9b1933 457 else // state > 0 so we are in the process of changing controls
Ownasaurus 2:77b20c9b1933 458 {
Ownasaurus 2:77b20c9b1933 459 uint8_t b = rep[2]; // read for button presses (just take first pressed if many are pressed)
Ownasaurus 2:77b20c9b1933 460 if(b != 0) /*button was actually is pressed*/
Ownasaurus 2:77b20c9b1933 461 {
Ownasaurus 2:77b20c9b1933 462 if(KeyboardButtonPressed == false)
Ownasaurus 2:77b20c9b1933 463 {
Ownasaurus 2:77b20c9b1933 464 KeyboardButtonPressed = true;
Ownasaurus 2:77b20c9b1933 465 ChangeButtonMapping(b);
Ownasaurus 2:77b20c9b1933 466 AdvanceState();
Ownasaurus 2:77b20c9b1933 467 }
Ownasaurus 2:77b20c9b1933 468 }
Ownasaurus 2:77b20c9b1933 469 else
Ownasaurus 2:77b20c9b1933 470 {
Ownasaurus 2:77b20c9b1933 471 KeyboardButtonPressed = false;
Ownasaurus 1:3c21da72660d 472 }
Ownasaurus 2:77b20c9b1933 473 }
Ownasaurus 2:77b20c9b1933 474 }
Ownasaurus 2:77b20c9b1933 475
Ownasaurus 2:77b20c9b1933 476 void PrintBytes(char *ptr, int numBytes)
Ownasaurus 2:77b20c9b1933 477 {
Ownasaurus 2:77b20c9b1933 478 pc.printf("[");
Ownasaurus 2:77b20c9b1933 479 for(int i=0;i < numBytes;i++)
Ownasaurus 2:77b20c9b1933 480 {
Ownasaurus 2:77b20c9b1933 481 pc.printf(" %X ",*ptr);
Ownasaurus 2:77b20c9b1933 482 ptr++;
Ownasaurus 2:77b20c9b1933 483 }
Ownasaurus 2:77b20c9b1933 484 pc.printf("]\r\n");
Ownasaurus 2:77b20c9b1933 485 }
Ownasaurus 2:77b20c9b1933 486
Ownasaurus 2:77b20c9b1933 487 void SaveControls()
Ownasaurus 2:77b20c9b1933 488 {
Ownasaurus 2:77b20c9b1933 489 FLASH_Unlock(); //unlock flash writing
Ownasaurus 2:77b20c9b1933 490 FLASH_ClearFlag(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
Ownasaurus 2:77b20c9b1933 491 FLASH_FLAG_PGAERR | FLASH_FLAG_PGPERR|FLASH_FLAG_PGSERR);
Ownasaurus 2:77b20c9b1933 492 FLASH_EraseSector(FLASH_Sector_3,VoltageRange_3); // 0x0800C000 - 0x0800FFFF
Ownasaurus 2:77b20c9b1933 493
Ownasaurus 2:77b20c9b1933 494 uint32_t* data = (uint32_t*)&kc;
Ownasaurus 2:77b20c9b1933 495
Ownasaurus 2:77b20c9b1933 496 // total size is 18 bytes
Ownasaurus 2:77b20c9b1933 497 // Note: ProgramDoubleWord requires a higher voltage
Ownasaurus 2:77b20c9b1933 498 FLASH_ProgramWord(SAVE_ADDR,*data); // write word 1 (4 bytes)
Ownasaurus 2:77b20c9b1933 499 data++;
Ownasaurus 2:77b20c9b1933 500 FLASH_ProgramWord(SAVE_ADDR+0x04,*data); // write word 2 (4 bytes)
Ownasaurus 2:77b20c9b1933 501 data++;
Ownasaurus 2:77b20c9b1933 502 FLASH_ProgramWord(SAVE_ADDR+0x08,*data); // write word 3 (4 bytes)
Ownasaurus 2:77b20c9b1933 503 data++;
Ownasaurus 2:77b20c9b1933 504 FLASH_ProgramWord(SAVE_ADDR+0x0C,*data); // write word 4 (4 bytes)
Ownasaurus 2:77b20c9b1933 505 data++;
Ownasaurus 2:77b20c9b1933 506 FLASH_ProgramHalfWord(SAVE_ADDR+0x10,*data); // write final half word (2 bytes)
Ownasaurus 1:3c21da72660d 507
Ownasaurus 2:77b20c9b1933 508 FLASH_Lock(); // lock it back up
Ownasaurus 2:77b20c9b1933 509 }
Ownasaurus 2:77b20c9b1933 510
Ownasaurus 2:77b20c9b1933 511
Ownasaurus 2:77b20c9b1933 512
Ownasaurus 2:77b20c9b1933 513 void LoadControls()
Ownasaurus 2:77b20c9b1933 514 {
Ownasaurus 2:77b20c9b1933 515 memcpy(&kc,saveData,sizeof(KeyboardControls));
Ownasaurus 2:77b20c9b1933 516 pc.printf("Controls have been loaded!\r\n");
Ownasaurus 1:3c21da72660d 517 }
Ownasaurus 1:3c21da72660d 518
Ownasaurus 0:eb2258e8c4b5 519 int main()
Ownasaurus 0:eb2258e8c4b5 520 {
Ownasaurus 2:77b20c9b1933 521 bool buttonPressed = false;
Ownasaurus 2:77b20c9b1933 522
Ownasaurus 2:77b20c9b1933 523 pc.printf("\r\nNow loaded! SystemCoreClock = %d Hz\r\n", SystemCoreClock);
Ownasaurus 2:77b20c9b1933 524 LoadControls();
Ownasaurus 1:3c21da72660d 525
Ownasaurus 1:3c21da72660d 526 USBHostKeyboard kb;
Ownasaurus 1:3c21da72660d 527 if (!kb.connect()) {
Ownasaurus 1:3c21da72660d 528 pc.printf("Error: USB kb not found.\n");
Ownasaurus 1:3c21da72660d 529 }
Ownasaurus 1:3c21da72660d 530 // when connected, attach handler called on kb event
Ownasaurus 1:3c21da72660d 531 kb.attach(onKeyboardEvent);
Ownasaurus 0:eb2258e8c4b5 532
Ownasaurus 0:eb2258e8c4b5 533 while(1)
Ownasaurus 0:eb2258e8c4b5 534 {
Ownasaurus 2:77b20c9b1933 535 if(state == NORMAL)
Ownasaurus 0:eb2258e8c4b5 536 {
Ownasaurus 2:77b20c9b1933 537 if(!button) // user wants to change controls
Ownasaurus 2:77b20c9b1933 538 {
Ownasaurus 2:77b20c9b1933 539 if(!buttonPressed) // make sure it's a separate button press
Ownasaurus 2:77b20c9b1933 540 {
Ownasaurus 2:77b20c9b1933 541 buttonPressed = true;
Ownasaurus 2:77b20c9b1933 542 state++;
Ownasaurus 2:77b20c9b1933 543 continue;
Ownasaurus 2:77b20c9b1933 544 }
Ownasaurus 2:77b20c9b1933 545 }
Ownasaurus 2:77b20c9b1933 546 else
Ownasaurus 2:77b20c9b1933 547 {
Ownasaurus 2:77b20c9b1933 548 buttonPressed = false;
Ownasaurus 2:77b20c9b1933 549 }
Ownasaurus 2:77b20c9b1933 550
Ownasaurus 2:77b20c9b1933 551 // Set pin mode to input
Ownasaurus 2:77b20c9b1933 552 data.input();
Ownasaurus 2:77b20c9b1933 553
Ownasaurus 2:77b20c9b1933 554 USBHost::poll();
Ownasaurus 2:77b20c9b1933 555
Ownasaurus 2:77b20c9b1933 556 __disable_irq(); // Disable Interrupts
Ownasaurus 2:77b20c9b1933 557
Ownasaurus 2:77b20c9b1933 558 // Read 64 command
Ownasaurus 2:77b20c9b1933 559 unsigned int cmd = readCommand();
Ownasaurus 2:77b20c9b1933 560
Ownasaurus 2:77b20c9b1933 561 my_wait_us_asm(2); // wait a small amount of time before replying
Ownasaurus 2:77b20c9b1933 562
Ownasaurus 2:77b20c9b1933 563 //-------- SEND RESPONSE
Ownasaurus 2:77b20c9b1933 564 // Set pin mode to output
Ownasaurus 2:77b20c9b1933 565 data.output();
Ownasaurus 2:77b20c9b1933 566
Ownasaurus 2:77b20c9b1933 567 switch(cmd)
Ownasaurus 2:77b20c9b1933 568 {
Ownasaurus 2:77b20c9b1933 569 case 0x00: // identity
Ownasaurus 2:77b20c9b1933 570 case 0xFF: // reset
Ownasaurus 2:77b20c9b1933 571 SendIdentity();
Ownasaurus 2:77b20c9b1933 572 break;
Ownasaurus 2:77b20c9b1933 573 case 0x01: // poll for state
Ownasaurus 2:77b20c9b1933 574 SendControllerData();
Ownasaurus 2:77b20c9b1933 575 break;
Ownasaurus 2:77b20c9b1933 576 default:
Ownasaurus 2:77b20c9b1933 577 // we do not process the read and write commands (memory pack)
Ownasaurus 2:77b20c9b1933 578 break;
Ownasaurus 2:77b20c9b1933 579 }
Ownasaurus 2:77b20c9b1933 580 __enable_irq(); // Enable Interrupts
Ownasaurus 2:77b20c9b1933 581 //-------- DONE SENDING RESPOSE
Ownasaurus 0:eb2258e8c4b5 582 }
Ownasaurus 2:77b20c9b1933 583 else
Ownasaurus 2:77b20c9b1933 584 {
Ownasaurus 2:77b20c9b1933 585 if(!button) // user wants to cancel and return to regular mode
Ownasaurus 2:77b20c9b1933 586 {
Ownasaurus 2:77b20c9b1933 587 if(!buttonPressed) // make sure it's a separate button press
Ownasaurus 2:77b20c9b1933 588 {
Ownasaurus 2:77b20c9b1933 589 state = NORMAL;
Ownasaurus 2:77b20c9b1933 590 buttonPressed = true;
Ownasaurus 2:77b20c9b1933 591 continue;
Ownasaurus 2:77b20c9b1933 592 }
Ownasaurus 2:77b20c9b1933 593 }
Ownasaurus 2:77b20c9b1933 594 else
Ownasaurus 2:77b20c9b1933 595 {
Ownasaurus 2:77b20c9b1933 596 buttonPressed = false;
Ownasaurus 2:77b20c9b1933 597 }
Ownasaurus 2:77b20c9b1933 598
Ownasaurus 2:77b20c9b1933 599 myled = !myled;
Ownasaurus 2:77b20c9b1933 600 USBHost::poll();
Ownasaurus 2:77b20c9b1933 601 wait(0.1);
Ownasaurus 2:77b20c9b1933 602
Ownasaurus 2:77b20c9b1933 603 if(state == NORMAL) // about to return to normal operation, make sure the LED remains off
Ownasaurus 2:77b20c9b1933 604 {
Ownasaurus 2:77b20c9b1933 605 myled = false;
Ownasaurus 2:77b20c9b1933 606 KeyboardButtonPressed = false;
Ownasaurus 2:77b20c9b1933 607 }
Ownasaurus 2:77b20c9b1933 608 }
Ownasaurus 0:eb2258e8c4b5 609 }
Ownasaurus 0:eb2258e8c4b5 610 }