GamePortAdapter
Dependencies: mbed-rtos mbed USBDevice USBJoystick
main.cpp@6:43b59cb5dcd9, 2017-12-21 (annotated)
- Committer:
- obsoleet37
- Date:
- Thu Dec 21 01:11:16 2017 +0000
- Revision:
- 6:43b59cb5dcd9
- Parent:
- 5:c2e3d6e70d85
Converted axis measurement code to object, added analog centering and scaling
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
cblackstone7 | 0:8b4f60bf3f80 | 1 | #include "mbed.h" |
obsoleet37 | 3:20f3136e49fa | 2 | #include "USBMouseKeyboard.h" |
obsoleet37 | 3:20f3136e49fa | 3 | #include "USBJoystick.h" |
cblackstone7 | 0:8b4f60bf3f80 | 4 | #include "rtos.h" |
obsoleet37 | 3:20f3136e49fa | 5 | #include "string.h" |
obsoleet37 | 3:20f3136e49fa | 6 | |
obsoleet37 | 6:43b59cb5dcd9 | 7 | #define min(a, b) (a)<(b) ? (a) : (b) |
obsoleet37 | 6:43b59cb5dcd9 | 8 | #define max(a, b) (a)>(b) ? (a) : (b) |
obsoleet37 | 6:43b59cb5dcd9 | 9 | #define clamp(val, floor, ceil) min(max(val, floor), ceil) |
obsoleet37 | 6:43b59cb5dcd9 | 10 | |
obsoleet37 | 5:c2e3d6e70d85 | 11 | extern "C" void mbed_reset(); |
obsoleet37 | 5:c2e3d6e70d85 | 12 | |
cblackstone7 | 0:8b4f60bf3f80 | 13 | Serial pc(USBTX, USBRX); |
cblackstone7 | 0:8b4f60bf3f80 | 14 | //macOS: screen /dev/tty.usbmodem{num} {baud rate} |
obsoleet37 | 6:43b59cb5dcd9 | 15 | //Windows: Realterm |
cblackstone7 | 0:8b4f60bf3f80 | 16 | |
obsoleet37 | 6:43b59cb5dcd9 | 17 | class Axis { |
obsoleet37 | 6:43b59cb5dcd9 | 18 | public: |
obsoleet37 | 6:43b59cb5dcd9 | 19 | Axis(PinName pin) : _pin(pin) { |
obsoleet37 | 6:43b59cb5dcd9 | 20 | _t.reset(); |
obsoleet37 | 6:43b59cb5dcd9 | 21 | _center = 0; |
obsoleet37 | 6:43b59cb5dcd9 | 22 | _scale = 1.0; |
obsoleet37 | 6:43b59cb5dcd9 | 23 | _pin.rise(this, &Axis::start); |
obsoleet37 | 6:43b59cb5dcd9 | 24 | _pin.fall(this, &Axis::stop); |
obsoleet37 | 6:43b59cb5dcd9 | 25 | } |
obsoleet37 | 6:43b59cb5dcd9 | 26 | |
obsoleet37 | 6:43b59cb5dcd9 | 27 | int8_t read() { |
obsoleet37 | 6:43b59cb5dcd9 | 28 | int val = _t.read_us(); |
obsoleet37 | 6:43b59cb5dcd9 | 29 | return val < 1000 ? clamp((val - _center)*_scale, -128, 127) : -128; |
obsoleet37 | 6:43b59cb5dcd9 | 30 | } |
obsoleet37 | 6:43b59cb5dcd9 | 31 | |
obsoleet37 | 6:43b59cb5dcd9 | 32 | int16_t read_raw() { |
obsoleet37 | 6:43b59cb5dcd9 | 33 | return _t.read_us(); |
obsoleet37 | 6:43b59cb5dcd9 | 34 | } |
obsoleet37 | 6:43b59cb5dcd9 | 35 | |
obsoleet37 | 6:43b59cb5dcd9 | 36 | void setup(int center, int range) { |
obsoleet37 | 6:43b59cb5dcd9 | 37 | _center = center; |
obsoleet37 | 6:43b59cb5dcd9 | 38 | _scale = 255.0/range; |
obsoleet37 | 6:43b59cb5dcd9 | 39 | } |
obsoleet37 | 6:43b59cb5dcd9 | 40 | |
obsoleet37 | 6:43b59cb5dcd9 | 41 | bool connected() { |
obsoleet37 | 6:43b59cb5dcd9 | 42 | int val = _t.read_us(); |
obsoleet37 | 6:43b59cb5dcd9 | 43 | return val == clamp(val, 10, 1000); |
obsoleet37 | 6:43b59cb5dcd9 | 44 | } |
obsoleet37 | 6:43b59cb5dcd9 | 45 | |
obsoleet37 | 6:43b59cb5dcd9 | 46 | private: |
obsoleet37 | 6:43b59cb5dcd9 | 47 | InterruptIn _pin; |
obsoleet37 | 6:43b59cb5dcd9 | 48 | Timer _t; |
obsoleet37 | 6:43b59cb5dcd9 | 49 | int _center; |
obsoleet37 | 6:43b59cb5dcd9 | 50 | float _scale; |
obsoleet37 | 6:43b59cb5dcd9 | 51 | |
obsoleet37 | 6:43b59cb5dcd9 | 52 | void start() { |
obsoleet37 | 6:43b59cb5dcd9 | 53 | _t.reset(); |
obsoleet37 | 6:43b59cb5dcd9 | 54 | _t.start(); |
obsoleet37 | 6:43b59cb5dcd9 | 55 | } |
cblackstone7 | 0:8b4f60bf3f80 | 56 | |
obsoleet37 | 6:43b59cb5dcd9 | 57 | void stop() { |
obsoleet37 | 6:43b59cb5dcd9 | 58 | _t.stop(); |
obsoleet37 | 6:43b59cb5dcd9 | 59 | } |
obsoleet37 | 6:43b59cb5dcd9 | 60 | |
obsoleet37 | 6:43b59cb5dcd9 | 61 | }; |
obsoleet37 | 6:43b59cb5dcd9 | 62 | |
obsoleet37 | 6:43b59cb5dcd9 | 63 | Axis x1 = Axis(p15); |
obsoleet37 | 6:43b59cb5dcd9 | 64 | Axis y1 = Axis(p16); |
obsoleet37 | 6:43b59cb5dcd9 | 65 | Axis x2 = Axis(p17); |
obsoleet37 | 6:43b59cb5dcd9 | 66 | Axis y2 = Axis(p18); |
obsoleet37 | 6:43b59cb5dcd9 | 67 | |
obsoleet37 | 3:20f3136e49fa | 68 | volatile int buttons; |
cblackstone7 | 0:8b4f60bf3f80 | 69 | |
cblackstone7 | 0:8b4f60bf3f80 | 70 | DigitalOut trig(p19); |
cblackstone7 | 0:8b4f60bf3f80 | 71 | |
obsoleet37 | 6:43b59cb5dcd9 | 72 | //1st row: necessary garbage, size, mode, reserved, reserved |
obsoleet37 | 6:43b59cb5dcd9 | 73 | //2nd row: x1 center, x1 range, y1 center, y1 range, reserved |
obsoleet37 | 6:43b59cb5dcd9 | 74 | //3rd row: x2 center, x2 range, y2 center, y2 range, reserved |
obsoleet37 | 5:c2e3d6e70d85 | 75 | //following rows: input, min, max, output, value |
obsoleet37 | 5:c2e3d6e70d85 | 76 | int bindings[128][5]; |
obsoleet37 | 6:43b59cb5dcd9 | 77 | /*int bindings[128][5] = {{0xFFFFFFFF, 9, 0, 0, 0}, |
obsoleet37 | 6:43b59cb5dcd9 | 78 | {128, 255, 128, 255, 0}, |
obsoleet37 | 6:43b59cb5dcd9 | 79 | {128, 255, 128, 255, 0}, |
obsoleet37 | 5:c2e3d6e70d85 | 80 | {0, 0, 100, 4, (int)'a'}, |
obsoleet37 | 4:17b8ede8063a | 81 | {0, 400, 1000, 4, (int)'d'}, |
obsoleet37 | 4:17b8ede8063a | 82 | {1, 0, 100, 4, (int)'w'}, |
obsoleet37 | 4:17b8ede8063a | 83 | {1, 400, 1000, 4, (int)'s'}, |
obsoleet37 | 4:17b8ede8063a | 84 | {4, 128, 255, 4, (int)'1'}, |
obsoleet37 | 4:17b8ede8063a | 85 | {5, 128, 255, 4, (int)'2'}};*/ |
obsoleet37 | 4:17b8ede8063a | 86 | |
obsoleet37 | 5:c2e3d6e70d85 | 87 | /*int bindings[8][5] = {{0, 0, 1000, 0, 0}, |
obsoleet37 | 4:17b8ede8063a | 88 | {1, 0, 1000, 1, 0}, |
obsoleet37 | 4:17b8ede8063a | 89 | {4, 128, 255, 4, 0x1}, |
obsoleet37 | 5:c2e3d6e70d85 | 90 | {5, 128, 255, 4, 0x2}};*/ |
obsoleet37 | 4:17b8ede8063a | 91 | |
obsoleet37 | 5:c2e3d6e70d85 | 92 | LocalFileSystem local("local"); |
obsoleet37 | 2:c7f76dac3723 | 93 | |
obsoleet37 | 6:43b59cb5dcd9 | 94 | void analog_trig() { |
obsoleet37 | 6:43b59cb5dcd9 | 95 | trig = 0; |
cblackstone7 | 0:8b4f60bf3f80 | 96 | trig = 1; |
cblackstone7 | 0:8b4f60bf3f80 | 97 | } |
cblackstone7 | 0:8b4f60bf3f80 | 98 | |
obsoleet37 | 3:20f3136e49fa | 99 | |
obsoleet37 | 3:20f3136e49fa | 100 | void debug_thread() { |
cblackstone7 | 0:8b4f60bf3f80 | 101 | pc.printf("Beginning Joystick Test...\r\n"); |
cblackstone7 | 0:8b4f60bf3f80 | 102 | pc.printf("---------------------------------\r\n"); |
cblackstone7 | 0:8b4f60bf3f80 | 103 | |
cblackstone7 | 0:8b4f60bf3f80 | 104 | while(1) { |
obsoleet37 | 6:43b59cb5dcd9 | 105 | pc.printf("Joystick 1 - %d, %d, %X \r\n", x1.read_raw(), y1.read_raw(), buttons&0x3); |
obsoleet37 | 6:43b59cb5dcd9 | 106 | pc.printf("Joystick 2 - %d, %d, %X \r\n", x2.read_raw(), y2.read_raw(), (buttons>>2)&0x3); |
cblackstone7 | 0:8b4f60bf3f80 | 107 | pc.printf("\r\n"); |
obsoleet37 | 3:20f3136e49fa | 108 | Thread::wait(500); |
cblackstone7 | 0:8b4f60bf3f80 | 109 | } |
cblackstone7 | 0:8b4f60bf3f80 | 110 | } |
obsoleet37 | 3:20f3136e49fa | 111 | |
obsoleet37 | 3:20f3136e49fa | 112 | |
obsoleet37 | 4:17b8ede8063a | 113 | void keys_mouse_output_thread() { |
obsoleet37 | 4:17b8ede8063a | 114 | USBMouseKeyboard keys_mouse; |
obsoleet37 | 6:43b59cb5dcd9 | 115 | BusIn buttons_raw(p21, p22, p23, p24); |
obsoleet37 | 6:43b59cb5dcd9 | 116 | buttons_raw.mode(PullUp); |
obsoleet37 | 6:43b59cb5dcd9 | 117 | |
obsoleet37 | 3:20f3136e49fa | 118 | int mouse[4]; |
obsoleet37 | 3:20f3136e49fa | 119 | int value, trigval; |
obsoleet37 | 3:20f3136e49fa | 120 | |
obsoleet37 | 5:c2e3d6e70d85 | 121 | while(true) { |
obsoleet37 | 3:20f3136e49fa | 122 | memset(mouse, 0, sizeof(mouse)); |
obsoleet37 | 6:43b59cb5dcd9 | 123 | buttons = ~buttons_raw&0xF; |
obsoleet37 | 3:20f3136e49fa | 124 | |
obsoleet37 | 6:43b59cb5dcd9 | 125 | for (int i=3; i<bindings[0][1]; i++) { |
obsoleet37 | 3:20f3136e49fa | 126 | //pc.printf("Checking %d: ", i); |
obsoleet37 | 4:17b8ede8063a | 127 | switch (bindings[i][0]) { |
obsoleet37 | 6:43b59cb5dcd9 | 128 | case 0: trigval = x1.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 129 | case 1: trigval = y1.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 130 | case 2: trigval = x2.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 131 | case 3: trigval = y2.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 132 | case 4: trigval = (buttons & 0x1)*127; break; |
obsoleet37 | 6:43b59cb5dcd9 | 133 | case 5: trigval = ((buttons>>1) & 0x1)*127; break; |
obsoleet37 | 6:43b59cb5dcd9 | 134 | case 6: trigval = ((buttons>>2) & 0x1)*127; break; |
obsoleet37 | 6:43b59cb5dcd9 | 135 | case 7: trigval = ((buttons>>3) & 0x1)*127; break; |
obsoleet37 | 4:17b8ede8063a | 136 | } |
obsoleet37 | 6:43b59cb5dcd9 | 137 | value = bindings[i][4]; |
obsoleet37 | 4:17b8ede8063a | 138 | |
obsoleet37 | 4:17b8ede8063a | 139 | if (trigval >= bindings[i][1] && trigval <= bindings[i][2]) { |
obsoleet37 | 6:43b59cb5dcd9 | 140 | //pc.printf("Triggered : %d, %d, %d\r\n", i, trigval, value); |
obsoleet37 | 4:17b8ede8063a | 141 | switch (bindings[i][3]) { |
obsoleet37 | 6:43b59cb5dcd9 | 142 | case 0: mouse[0] = trigval/value; break; //Mouse X |
obsoleet37 | 6:43b59cb5dcd9 | 143 | case 1: mouse[1] = trigval/value; break; //Mouse Y |
obsoleet37 | 6:43b59cb5dcd9 | 144 | case 2: mouse[2] |= value; break; //Mouse buttons |
obsoleet37 | 6:43b59cb5dcd9 | 145 | case 3: mouse[3] = trigval/value; break; //Mouse scroll |
obsoleet37 | 6:43b59cb5dcd9 | 146 | case 4: keys_mouse.keyCode(value); break; //Keypress |
obsoleet37 | 4:17b8ede8063a | 147 | } |
obsoleet37 | 4:17b8ede8063a | 148 | } |
obsoleet37 | 4:17b8ede8063a | 149 | } |
obsoleet37 | 4:17b8ede8063a | 150 | keys_mouse.update(mouse[0], mouse[1], mouse[2], mouse[3]); |
obsoleet37 | 6:43b59cb5dcd9 | 151 | Thread::wait(15); |
obsoleet37 | 4:17b8ede8063a | 152 | } |
obsoleet37 | 4:17b8ede8063a | 153 | } |
obsoleet37 | 4:17b8ede8063a | 154 | |
obsoleet37 | 4:17b8ede8063a | 155 | |
obsoleet37 | 4:17b8ede8063a | 156 | void joystick_output_thread() { |
obsoleet37 | 4:17b8ede8063a | 157 | USBJoystick joystick; |
obsoleet37 | 6:43b59cb5dcd9 | 158 | BusIn buttons_raw(p21, p22, p23, p24); |
obsoleet37 | 6:43b59cb5dcd9 | 159 | buttons_raw.mode(PullUp); |
obsoleet37 | 6:43b59cb5dcd9 | 160 | |
obsoleet37 | 4:17b8ede8063a | 161 | int joy[6]; |
obsoleet37 | 4:17b8ede8063a | 162 | int value, trigval; |
obsoleet37 | 4:17b8ede8063a | 163 | |
obsoleet37 | 5:c2e3d6e70d85 | 164 | while(true) { |
obsoleet37 | 4:17b8ede8063a | 165 | memset(joy, 0, sizeof(joy)); |
obsoleet37 | 6:43b59cb5dcd9 | 166 | buttons = ~buttons_raw&0xF; |
obsoleet37 | 4:17b8ede8063a | 167 | |
obsoleet37 | 6:43b59cb5dcd9 | 168 | for (int i=3; i<bindings[0][1]; i++) { |
obsoleet37 | 4:17b8ede8063a | 169 | //pc.printf("Checking %d: ", i); |
obsoleet37 | 4:17b8ede8063a | 170 | switch (bindings[i][0]) { |
obsoleet37 | 6:43b59cb5dcd9 | 171 | case 0: trigval = x1.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 172 | case 1: trigval = y1.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 173 | case 2: trigval = x2.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 174 | case 3: trigval = y2.read(); break; |
obsoleet37 | 6:43b59cb5dcd9 | 175 | case 4: trigval = (buttons & 0x1)*127; break; |
obsoleet37 | 6:43b59cb5dcd9 | 176 | case 5: trigval = ((buttons>>1) & 0x1)*127; break; |
obsoleet37 | 6:43b59cb5dcd9 | 177 | case 6: trigval = ((buttons>>2) & 0x1)*127; break; |
obsoleet37 | 6:43b59cb5dcd9 | 178 | case 7: trigval = ((buttons>>3) & 0x1)*127; break; |
obsoleet37 | 3:20f3136e49fa | 179 | } |
obsoleet37 | 6:43b59cb5dcd9 | 180 | value = bindings[i][4]; |
obsoleet37 | 3:20f3136e49fa | 181 | |
obsoleet37 | 3:20f3136e49fa | 182 | if (trigval >= bindings[i][1] && trigval <= bindings[i][2]) { |
obsoleet37 | 3:20f3136e49fa | 183 | //pc.printf("Triggered : %d, %d, %d\r\n", i, trigval, value); |
obsoleet37 | 4:17b8ede8063a | 184 | switch (bindings[i][3]) { |
obsoleet37 | 6:43b59cb5dcd9 | 185 | case 0: joy[2] = trigval/value; break;//Joy X |
obsoleet37 | 6:43b59cb5dcd9 | 186 | case 1: joy[3] = trigval/value; break; //Joy Y |
obsoleet37 | 6:43b59cb5dcd9 | 187 | case 2: joy[0] = trigval/value; break; //Joy throttle |
obsoleet37 | 6:43b59cb5dcd9 | 188 | case 3: joy[1] = trigval/value; break; //Joy rudder |
obsoleet37 | 6:43b59cb5dcd9 | 189 | case 4: joy[4] |= value; break; //Joy buttons |
obsoleet37 | 6:43b59cb5dcd9 | 190 | case 5: joy[5] |= value; break; //Joy hat |
obsoleet37 | 3:20f3136e49fa | 191 | } |
obsoleet37 | 3:20f3136e49fa | 192 | } |
obsoleet37 | 3:20f3136e49fa | 193 | } |
obsoleet37 | 4:17b8ede8063a | 194 | joystick.update(joy[0], joy[1], joy[2], joy[3], joy[4], joy[5]); |
obsoleet37 | 6:43b59cb5dcd9 | 195 | Thread::wait(15); |
obsoleet37 | 3:20f3136e49fa | 196 | } |
obsoleet37 | 3:20f3136e49fa | 197 | } |
obsoleet37 | 3:20f3136e49fa | 198 | |
obsoleet37 | 3:20f3136e49fa | 199 | |
obsoleet37 | 3:20f3136e49fa | 200 | int main() { |
obsoleet37 | 5:c2e3d6e70d85 | 201 | |
obsoleet37 | 5:c2e3d6e70d85 | 202 | //Load bindings from file |
obsoleet37 | 5:c2e3d6e70d85 | 203 | FILE *bf = fopen("/local/bindings", "rb"); |
obsoleet37 | 5:c2e3d6e70d85 | 204 | fread(bindings, 5*sizeof(int), 1, bf); |
obsoleet37 | 5:c2e3d6e70d85 | 205 | fread(bindings[1], 5*sizeof(int), bindings[0][1]-1, bf); |
obsoleet37 | 5:c2e3d6e70d85 | 206 | fclose(bf); |
obsoleet37 | 5:c2e3d6e70d85 | 207 | |
obsoleet37 | 6:43b59cb5dcd9 | 208 | x1.setup(bindings[1][0], bindings[1][1]); |
obsoleet37 | 6:43b59cb5dcd9 | 209 | y1.setup(bindings[1][2], bindings[1][3]); |
obsoleet37 | 6:43b59cb5dcd9 | 210 | x2.setup(bindings[2][0], bindings[2][1]); |
obsoleet37 | 6:43b59cb5dcd9 | 211 | y2.setup(bindings[2][2], bindings[2][3]); |
obsoleet37 | 3:20f3136e49fa | 212 | |
obsoleet37 | 6:43b59cb5dcd9 | 213 | //Thread analogThread(analog_thread); |
obsoleet37 | 6:43b59cb5dcd9 | 214 | Ticker analog_ticker; |
obsoleet37 | 6:43b59cb5dcd9 | 215 | analog_ticker.attach(&analog_trig, 0.05); |
obsoleet37 | 6:43b59cb5dcd9 | 216 | |
obsoleet37 | 6:43b59cb5dcd9 | 217 | Thread outputThread; |
obsoleet37 | 6:43b59cb5dcd9 | 218 | //Thread::wait(100); |
obsoleet37 | 5:c2e3d6e70d85 | 219 | switch(bindings[0][2]) { |
obsoleet37 | 5:c2e3d6e70d85 | 220 | case 0: outputThread.start(keys_mouse_output_thread); break; |
obsoleet37 | 5:c2e3d6e70d85 | 221 | case 1: outputThread.start(joystick_output_thread); break; |
obsoleet37 | 5:c2e3d6e70d85 | 222 | } |
obsoleet37 | 3:20f3136e49fa | 223 | |
obsoleet37 | 6:43b59cb5dcd9 | 224 | Thread debugThread(debug_thread); |
obsoleet37 | 3:20f3136e49fa | 225 | |
obsoleet37 | 3:20f3136e49fa | 226 | while(1) Thread::yield(); |
obsoleet37 | 3:20f3136e49fa | 227 | } |