work in progress
Dependencies: FastAnalogIn FastIO USBDevice mbed FastPWM SimpleDMA
Fork of Pinscape_Controller by
main.cpp@0:5acbbe3f4cf4, 2014-07-11 (annotated)
- Committer:
- mjr
- Date:
- Fri Jul 11 03:26:11 2014 +0000
- Revision:
- 0:5acbbe3f4cf4
- Child:
- 1:d913e0afb2ac
Initial testing setup, before starting on real configuration
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 0:5acbbe3f4cf4 | 1 | #include "mbed.h" |
mjr | 0:5acbbe3f4cf4 | 2 | #include "USBJoystick.h" |
mjr | 0:5acbbe3f4cf4 | 3 | #include "MMA8451Q.h" |
mjr | 0:5acbbe3f4cf4 | 4 | #include "tls1410r.h" |
mjr | 0:5acbbe3f4cf4 | 5 | |
mjr | 0:5acbbe3f4cf4 | 6 | PwmOut led1(LED1), led2(LED2), led3(LED3); |
mjr | 0:5acbbe3f4cf4 | 7 | DigitalOut out1(PTE29); |
mjr | 0:5acbbe3f4cf4 | 8 | |
mjr | 0:5acbbe3f4cf4 | 9 | |
mjr | 0:5acbbe3f4cf4 | 10 | |
mjr | 0:5acbbe3f4cf4 | 11 | static int pbaIdx = 0; |
mjr | 0:5acbbe3f4cf4 | 12 | |
mjr | 0:5acbbe3f4cf4 | 13 | // on/off state for each LedWiz output |
mjr | 0:5acbbe3f4cf4 | 14 | static uint8_t ledOn[32]; |
mjr | 0:5acbbe3f4cf4 | 15 | |
mjr | 0:5acbbe3f4cf4 | 16 | // profile (brightness/blink) state for each LedWiz output |
mjr | 0:5acbbe3f4cf4 | 17 | static uint8_t ledVal[32] = { |
mjr | 0:5acbbe3f4cf4 | 18 | 0, 0, 0, 0, 0, 0, 0, 0, |
mjr | 0:5acbbe3f4cf4 | 19 | 0, 0, 0, 0, 0, 0, 0, 0, |
mjr | 0:5acbbe3f4cf4 | 20 | 0, 0, 0, 0, 0, 0, 0, 0, |
mjr | 0:5acbbe3f4cf4 | 21 | 0, 0, 0, 0, 0, 0, 0, 0 |
mjr | 0:5acbbe3f4cf4 | 22 | }; |
mjr | 0:5acbbe3f4cf4 | 23 | |
mjr | 0:5acbbe3f4cf4 | 24 | static double ledState(int idx) |
mjr | 0:5acbbe3f4cf4 | 25 | { |
mjr | 0:5acbbe3f4cf4 | 26 | if (ledOn[idx]) { |
mjr | 0:5acbbe3f4cf4 | 27 | // on - map profile brightness state to PWM level |
mjr | 0:5acbbe3f4cf4 | 28 | uint8_t val = ledVal[idx]; |
mjr | 0:5acbbe3f4cf4 | 29 | if (val >= 1 && val <= 48) |
mjr | 0:5acbbe3f4cf4 | 30 | return 1.0 - val/48.0; |
mjr | 0:5acbbe3f4cf4 | 31 | else if (val >= 129 && val <= 132) |
mjr | 0:5acbbe3f4cf4 | 32 | return 0.0; |
mjr | 0:5acbbe3f4cf4 | 33 | else |
mjr | 0:5acbbe3f4cf4 | 34 | return 1.0; |
mjr | 0:5acbbe3f4cf4 | 35 | } |
mjr | 0:5acbbe3f4cf4 | 36 | else { |
mjr | 0:5acbbe3f4cf4 | 37 | // off |
mjr | 0:5acbbe3f4cf4 | 38 | return 1.0; |
mjr | 0:5acbbe3f4cf4 | 39 | } |
mjr | 0:5acbbe3f4cf4 | 40 | } |
mjr | 0:5acbbe3f4cf4 | 41 | |
mjr | 0:5acbbe3f4cf4 | 42 | static void updateLeds() |
mjr | 0:5acbbe3f4cf4 | 43 | { |
mjr | 0:5acbbe3f4cf4 | 44 | led1 = ledState(0); |
mjr | 0:5acbbe3f4cf4 | 45 | led2 = ledState(1); |
mjr | 0:5acbbe3f4cf4 | 46 | led3 = ledState(2); |
mjr | 0:5acbbe3f4cf4 | 47 | } |
mjr | 0:5acbbe3f4cf4 | 48 | |
mjr | 0:5acbbe3f4cf4 | 49 | int main(void) |
mjr | 0:5acbbe3f4cf4 | 50 | { |
mjr | 0:5acbbe3f4cf4 | 51 | led1 = 1; |
mjr | 0:5acbbe3f4cf4 | 52 | led2 = 1; |
mjr | 0:5acbbe3f4cf4 | 53 | led3 = 1; |
mjr | 0:5acbbe3f4cf4 | 54 | Timer timer; |
mjr | 0:5acbbe3f4cf4 | 55 | |
mjr | 0:5acbbe3f4cf4 | 56 | // set up a timer for spacing USB reports |
mjr | 0:5acbbe3f4cf4 | 57 | timer.start(); |
mjr | 0:5acbbe3f4cf4 | 58 | float t0 = timer.read_ms(); |
mjr | 0:5acbbe3f4cf4 | 59 | float tout1 = timer.read_ms(); |
mjr | 0:5acbbe3f4cf4 | 60 | |
mjr | 0:5acbbe3f4cf4 | 61 | // Create the joystick USB client. Show a read LED while connecting, and |
mjr | 0:5acbbe3f4cf4 | 62 | // change to green when connected. |
mjr | 0:5acbbe3f4cf4 | 63 | led1 = 0.75; |
mjr | 0:5acbbe3f4cf4 | 64 | USBJoystick js(0xFAFA, 0x00F7, 0x0001); |
mjr | 0:5acbbe3f4cf4 | 65 | led1 = 1; |
mjr | 0:5acbbe3f4cf4 | 66 | led2 = 0.75; |
mjr | 0:5acbbe3f4cf4 | 67 | |
mjr | 0:5acbbe3f4cf4 | 68 | // create the accelerometer object |
mjr | 0:5acbbe3f4cf4 | 69 | const int MMA8451_I2C_ADDRESS = (0x1d<<1); |
mjr | 0:5acbbe3f4cf4 | 70 | MMA8451Q accel(PTE25, PTE24, MMA8451_I2C_ADDRESS); |
mjr | 0:5acbbe3f4cf4 | 71 | printf("MMA8451 ID: %d\r\n", accel.getWhoAmI()); |
mjr | 0:5acbbe3f4cf4 | 72 | |
mjr | 0:5acbbe3f4cf4 | 73 | // create the CCD array object |
mjr | 0:5acbbe3f4cf4 | 74 | TLS1410R ccd(PTE20, PTE21, PTB0); |
mjr | 0:5acbbe3f4cf4 | 75 | |
mjr | 0:5acbbe3f4cf4 | 76 | // process sensor reports and LedWiz requests forever |
mjr | 0:5acbbe3f4cf4 | 77 | int x = 0, y = 127, z = 0; |
mjr | 0:5acbbe3f4cf4 | 78 | for (;;) |
mjr | 0:5acbbe3f4cf4 | 79 | { |
mjr | 0:5acbbe3f4cf4 | 80 | // Look for an incoming report. Continue processing input as |
mjr | 0:5acbbe3f4cf4 | 81 | // long as there's anything pending - this ensures that we |
mjr | 0:5acbbe3f4cf4 | 82 | // handle input in as timely a fashion as possible by deferring |
mjr | 0:5acbbe3f4cf4 | 83 | // output tasks as long as there's input to process. |
mjr | 0:5acbbe3f4cf4 | 84 | HID_REPORT report; |
mjr | 0:5acbbe3f4cf4 | 85 | while (js.readNB(&report) && report.length == 8) |
mjr | 0:5acbbe3f4cf4 | 86 | { |
mjr | 0:5acbbe3f4cf4 | 87 | uint8_t *data = report.data; |
mjr | 0:5acbbe3f4cf4 | 88 | if (data[0] == 64) { |
mjr | 0:5acbbe3f4cf4 | 89 | // LWZ-SBA - first four bytes are bit-packed on/off flags |
mjr | 0:5acbbe3f4cf4 | 90 | // for the outputs; 5th byte is the pulse speed (0-7) |
mjr | 0:5acbbe3f4cf4 | 91 | //printf("LWZ-SBA %02x %02x %02x %02x ; %02x\r\n", |
mjr | 0:5acbbe3f4cf4 | 92 | // data[1], data[2], data[3], data[4], data[5]); |
mjr | 0:5acbbe3f4cf4 | 93 | |
mjr | 0:5acbbe3f4cf4 | 94 | // update all on/off states |
mjr | 0:5acbbe3f4cf4 | 95 | for (int i = 0, bit = 1, ri = 1 ; i < 32 ; ++i, bit <<= 1) |
mjr | 0:5acbbe3f4cf4 | 96 | { |
mjr | 0:5acbbe3f4cf4 | 97 | if (bit == 0x100) { |
mjr | 0:5acbbe3f4cf4 | 98 | bit = 1; |
mjr | 0:5acbbe3f4cf4 | 99 | ++ri; |
mjr | 0:5acbbe3f4cf4 | 100 | } |
mjr | 0:5acbbe3f4cf4 | 101 | ledOn[i] = ((data[ri] & bit) != 0); |
mjr | 0:5acbbe3f4cf4 | 102 | } |
mjr | 0:5acbbe3f4cf4 | 103 | |
mjr | 0:5acbbe3f4cf4 | 104 | // update the physical LED state |
mjr | 0:5acbbe3f4cf4 | 105 | updateLeds(); |
mjr | 0:5acbbe3f4cf4 | 106 | |
mjr | 0:5acbbe3f4cf4 | 107 | // reset the PBA counter |
mjr | 0:5acbbe3f4cf4 | 108 | pbaIdx = 0; |
mjr | 0:5acbbe3f4cf4 | 109 | } |
mjr | 0:5acbbe3f4cf4 | 110 | else { |
mjr | 0:5acbbe3f4cf4 | 111 | // LWZ-PBA - full state dump; each byte is one output |
mjr | 0:5acbbe3f4cf4 | 112 | // in the current bank. pbaIdx keeps track of the bank; |
mjr | 0:5acbbe3f4cf4 | 113 | // this is incremented implicitly by each PBA message. |
mjr | 0:5acbbe3f4cf4 | 114 | //printf("LWZ-PBA[%d] %02x %02x %02x %02x %02x %02x %02x %02x\r\n", |
mjr | 0:5acbbe3f4cf4 | 115 | // pbaIdx, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7]); |
mjr | 0:5acbbe3f4cf4 | 116 | |
mjr | 0:5acbbe3f4cf4 | 117 | // update all output profile settings |
mjr | 0:5acbbe3f4cf4 | 118 | for (int i = 0 ; i < 8 ; ++i) |
mjr | 0:5acbbe3f4cf4 | 119 | ledVal[pbaIdx + i] = data[i]; |
mjr | 0:5acbbe3f4cf4 | 120 | |
mjr | 0:5acbbe3f4cf4 | 121 | // update the physical LED state if this is the last bank |
mjr | 0:5acbbe3f4cf4 | 122 | if (pbaIdx == 24) |
mjr | 0:5acbbe3f4cf4 | 123 | updateLeds(); |
mjr | 0:5acbbe3f4cf4 | 124 | |
mjr | 0:5acbbe3f4cf4 | 125 | // advance to the next bank |
mjr | 0:5acbbe3f4cf4 | 126 | pbaIdx = (pbaIdx + 8) & 31; |
mjr | 0:5acbbe3f4cf4 | 127 | } |
mjr | 0:5acbbe3f4cf4 | 128 | } |
mjr | 0:5acbbe3f4cf4 | 129 | |
mjr | 0:5acbbe3f4cf4 | 130 | #if 1 |
mjr | 0:5acbbe3f4cf4 | 131 | // check the accelerometer |
mjr | 0:5acbbe3f4cf4 | 132 | { |
mjr | 0:5acbbe3f4cf4 | 133 | // read the accelerometer |
mjr | 0:5acbbe3f4cf4 | 134 | float xa = accel.getAccX(); |
mjr | 0:5acbbe3f4cf4 | 135 | float ya = accel.getAccY(); |
mjr | 0:5acbbe3f4cf4 | 136 | |
mjr | 0:5acbbe3f4cf4 | 137 | // figure the new joystick position |
mjr | 0:5acbbe3f4cf4 | 138 | int xnew = (int)(127 * xa); |
mjr | 0:5acbbe3f4cf4 | 139 | int ynew = (int)(127 * ya); |
mjr | 0:5acbbe3f4cf4 | 140 | |
mjr | 0:5acbbe3f4cf4 | 141 | // send an update if the position has changed |
mjr | 0:5acbbe3f4cf4 | 142 | if (xnew != x || ynew != y) |
mjr | 0:5acbbe3f4cf4 | 143 | { |
mjr | 0:5acbbe3f4cf4 | 144 | x = xnew; |
mjr | 0:5acbbe3f4cf4 | 145 | y = ynew; |
mjr | 0:5acbbe3f4cf4 | 146 | |
mjr | 0:5acbbe3f4cf4 | 147 | // send the status report |
mjr | 0:5acbbe3f4cf4 | 148 | js.update(x, y, z, 0); |
mjr | 0:5acbbe3f4cf4 | 149 | } |
mjr | 0:5acbbe3f4cf4 | 150 | } |
mjr | 0:5acbbe3f4cf4 | 151 | #else |
mjr | 0:5acbbe3f4cf4 | 152 | // Send a joystick report if it's been long enough since the |
mjr | 0:5acbbe3f4cf4 | 153 | // last report |
mjr | 0:5acbbe3f4cf4 | 154 | if (timer.read_ms() - t0 > 250) |
mjr | 0:5acbbe3f4cf4 | 155 | { |
mjr | 0:5acbbe3f4cf4 | 156 | // send the current joystick status report |
mjr | 0:5acbbe3f4cf4 | 157 | js.update(x, y, z, 0); |
mjr | 0:5acbbe3f4cf4 | 158 | |
mjr | 0:5acbbe3f4cf4 | 159 | // update our internal joystick position record |
mjr | 0:5acbbe3f4cf4 | 160 | x += dx; |
mjr | 0:5acbbe3f4cf4 | 161 | y += dy; |
mjr | 0:5acbbe3f4cf4 | 162 | z += dz; |
mjr | 0:5acbbe3f4cf4 | 163 | if (x > xmax || x < xmin) { |
mjr | 0:5acbbe3f4cf4 | 164 | dx = -dx; |
mjr | 0:5acbbe3f4cf4 | 165 | x += 2*dx; |
mjr | 0:5acbbe3f4cf4 | 166 | } |
mjr | 0:5acbbe3f4cf4 | 167 | if (y > ymax || y < ymin) { |
mjr | 0:5acbbe3f4cf4 | 168 | dy = -dy; |
mjr | 0:5acbbe3f4cf4 | 169 | y += 2*dy; |
mjr | 0:5acbbe3f4cf4 | 170 | } |
mjr | 0:5acbbe3f4cf4 | 171 | if (z > zmax || z < zmin) { |
mjr | 0:5acbbe3f4cf4 | 172 | dz = -dz; |
mjr | 0:5acbbe3f4cf4 | 173 | z += 2*dz; |
mjr | 0:5acbbe3f4cf4 | 174 | } |
mjr | 0:5acbbe3f4cf4 | 175 | |
mjr | 0:5acbbe3f4cf4 | 176 | // note the time of the last report |
mjr | 0:5acbbe3f4cf4 | 177 | t0 = timer.read_ms(); |
mjr | 0:5acbbe3f4cf4 | 178 | } |
mjr | 0:5acbbe3f4cf4 | 179 | #endif |
mjr | 0:5acbbe3f4cf4 | 180 | |
mjr | 0:5acbbe3f4cf4 | 181 | // pulse E29 |
mjr | 0:5acbbe3f4cf4 | 182 | if (timer.read_ms() - tout1 > 2000) |
mjr | 0:5acbbe3f4cf4 | 183 | { |
mjr | 0:5acbbe3f4cf4 | 184 | out1 = !out1; |
mjr | 0:5acbbe3f4cf4 | 185 | tout1 = timer.read_ms(); |
mjr | 0:5acbbe3f4cf4 | 186 | } |
mjr | 0:5acbbe3f4cf4 | 187 | } |
mjr | 0:5acbbe3f4cf4 | 188 | } |