Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of Pinscape_Controller by
Revision 10:976666ffa4ef, committed 2014-08-23
- Comitter:
- mjr
- Date:
- Sat Aug 23 01:24:36 2014 +0000
- Parent:
- 9:fd65b0a94720
- Child:
- 11:bd9da7088e6e
- Commit message:
- Add raw pixel dump support for use by the Windows config tool
Changed in this revision
--- a/USBDevice.lib Mon Aug 18 21:46:10 2014 +0000 +++ b/USBDevice.lib Sat Aug 23 01:24:36 2014 +0000 @@ -1,1 +1,1 @@ -http://mbed.org/users/mjr/code/USBDevice/#81f57ea86f8f +http://mbed.org/users/mjr/code/USBDevice/#a8eb758f4074
--- a/USBJoystick/USBJoystick.cpp Mon Aug 18 21:46:10 2014 +0000
+++ b/USBJoystick/USBJoystick.cpp Sat Aug 23 01:24:36 2014 +0000
@@ -26,7 +26,7 @@
_y = y;
_z = z;
_buttons = buttons;
- _status = (uint8_t)status;
+ _status = status;
// send the report
return update();
@@ -37,15 +37,38 @@
// Fill the report according to the Joystick Descriptor
#define put(idx, val) (report.data[idx] = (val) & 0xff, report.data[(idx)+1] = ((val) >> 8) & 0xff)
- put(0, _buttons);
- put(2, _x);
- put(4, _y);
- put(6, _z);
- report.data[8] = _status;
- report.length = 9;
+ put(0, _status);
+ put(2, 0); // second byte of status isn't used in normal reports
+ put(4, _buttons);
+ put(6, _x);
+ put(8, _y);
+ put(10, _z);
+ report.length = 12;
// send the report
- return sendNB(&report);
+ return sendTO(&report, 100);
+}
+
+bool USBJoystick::updateExposure(int &idx, int npix, const uint16_t *pix)
+{
+ HID_REPORT report;
+
+ // Set the special status bits to indicate it's an exposure report.
+ // The high 5 bits of the status word are set to 10000, and the
+ // low 11 bits are the current pixel index.
+ uint16_t s = idx | 0x8000;
+ put(0, s);
+
+ // now fill out the remaining words with exposure values
+ report.length = 12;
+ for (int ofs = 2 ; ofs + 1 < report.length ; ofs += 2)
+ {
+ uint16_t p = (idx < npix ? pix[idx++] : 0);
+ put(ofs, p);
+ }
+
+ // send the report
+ return send(&report);
}
bool USBJoystick::move(int16_t x, int16_t y) {
@@ -106,6 +129,15 @@
// COLLECTION(1), 0x00, // Physical
// input report (device to host)
+
+ USAGE_PAGE(1), 0x06, // generic device controls - for config status
+ USAGE(1), 0x00, // undefined device control
+ LOGICAL_MINIMUM(1), 0x00, // 8-bit values
+ LOGICAL_MAXIMUM(1), 0xFF,
+ REPORT_SIZE(1), 0x08, // 8 bits per report
+ REPORT_COUNT(1), 0x04, // 4 reports (4 bytes)
+ INPUT(1), 0x02, // Data, Variable, Absolute
+
USAGE_PAGE(1), 0x09, // Buttons
USAGE_MINIMUM(1), 0x01, // { buttons }
USAGE_MAXIMUM(1), 0x10, // { 1-16 }
@@ -127,14 +159,6 @@
REPORT_COUNT(1), 0x03, // 3 reports (X, Y, Z)
INPUT(1), 0x02, // Data, Variable, Absolute
- USAGE_PAGE(1), 0x06, // generic device controls - for config status
- USAGE(1), 0x00, // undefined device control
- LOGICAL_MINIMUM(1), 0x00, // 1-bit flags
- LOGICAL_MAXIMUM(1), 0x01,
- REPORT_SIZE(1), 0x01, // 1 bit per report
- REPORT_COUNT(1), 0x08, // 8 reports (8 bits)
- INPUT(1), 0x02, // Data, Variable, Absolute
-
// output report (host to device)
REPORT_SIZE(1), 0x08, // 8 bits per report
REPORT_COUNT(1), 0x08, // output report count (LEDWiz messages)
--- a/USBJoystick/USBJoystick.h Mon Aug 18 21:46:10 2014 +0000
+++ b/USBJoystick/USBJoystick.h Sat Aug 23 01:24:36 2014 +0000
@@ -107,6 +107,18 @@
* @returns true if there is no error, false otherwise
*/
bool update(int16_t x, int16_t y, int16_t z, uint16_t buttons, uint16_t status);
+
+ /**
+ * Write an exposure report. We'll fill out a report with as many pixels as
+ * will fit in the packet, send the report, and update the index to the next
+ * pixel to send. The caller should call this repeatedly to send reports for
+ * all pixels.
+ *
+ * @param idx current index in pixel array, updated to point to next pixel to send
+ * @param npix number of pixels in the overall array
+ * @param pix pixel array
+ */
+ bool updateExposure(int &idx, int npix, const uint16_t *pix);
/**
* Write a state of the mouse
@@ -156,7 +168,7 @@
int16_t _y;
int16_t _z;
uint16_t _buttons;
- uint8_t _status;
+ uint16_t _status;
void _init();
};
--- a/main.cpp Mon Aug 18 21:46:10 2014 +0000
+++ b/main.cpp Sat Aug 23 01:24:36 2014 +0000
@@ -181,6 +181,31 @@
// byte 0 = 65 (0x41)
// byte 1 = 2 (0x02)
//
+// Exposure reports: the host can request a report of the full set of pixel
+// values for the next frame by sending this special packet:
+//
+// length = 8 bytes
+// byte 0 = 65 (0x41)
+// byte 1 = 3 (0x03)
+//
+// We'll respond with a series of special reports giving the exposure status.
+// Each report has the following structure:
+//
+// bytes 0:1 = 11-bit index, with high 5 bits set to 10000. For
+// example, 0x04 0x80 indicates index 4. This is the
+// starting pixel number in the report. The first report
+// will be 0x00 0x80 to indicate pixel #0.
+// bytes 2:3 = 16-bit unsigned int brightness level of pixel at index
+// bytes 4:5 = brightness of pixel at index+1
+// etc for the rest of the packet
+//
+// This still has the form of a joystick packet at the USB level, but
+// can be differentiated by the host via the status bits. It would have
+// been cleaner to use a different Report ID at the USB level, but this
+// would have necessitated a different container structure in the report
+// descriptor, which would have broken LedWiz compatibility. Given that
+// constraint, we have to re-use the joystick report type, making for
+// this somewhat kludgey approach.
#include "mbed.h"
#include "math.h"
@@ -983,6 +1008,9 @@
// of these bits:
// 0x01 -> plunger sensor enabled
uint16_t statusFlags = (cfg.d.ccdEnabled ? 0x01 : 0x00);
+
+ // flag: send a pixel dump after the next read
+ bool reportPix = false;
// we're all set up - now just loop, processing sensor reports and
// host requests
@@ -1064,6 +1092,17 @@
calBtnTimer.reset();
cfg.resetPlunger();
}
+ else if (data[1] == 3)
+ {
+ // 3 = pixel dump
+ // (No parameters)
+ reportPix = true;
+
+ // show purple until we finish sending the report
+ ledR = 0;
+ ledB = 0;
+ ledG = 1;
+ }
}
else
{
@@ -1193,6 +1232,7 @@
}
// read the plunger sensor, if it's enabled
+ uint16_t pix[npix];
if (cfg.d.ccdEnabled)
{
// start with the previous reading, in case we don't have a
@@ -1200,7 +1240,6 @@
int znew = z;
// read the array
- uint16_t pix[npix];
ccd.read(pix, npix);
// get the average brightness at each end of the sensor
@@ -1338,14 +1377,6 @@
int fireTol = z/3 > JOYMAX/6 ? z/3 : JOYMAX/6;
static const int firePattern[] = {
-JOYMAX/12, -JOYMAX/12, -JOYMAX/12,
- 0, 0, 0,
- JOYMAX/16, JOYMAX/16, JOYMAX/16,
- 0, 0, 0,
- -JOYMAX/20, -JOYMAX/20, -JOYMAX/20,
- 0, 0, 0,
- JOYMAX/24, JOYMAX/24, JOYMAX/24,
- 0, 0, 0,
- -JOYMAX/30, -JOYMAX/30, -JOYMAX/30
};
if (firing != 0)
{
@@ -1442,6 +1473,27 @@
// joystick and Y Axis = Y on the joystick.
js.update(y, x, z, 0, statusFlags);
+ // If we're in pixel dump mode, report all pixel exposure values
+ if (reportPix)
+ {
+ // we have satisfied this request
+ reportPix = false;
+
+ // send reports for all pixels
+ int idx = 0;
+ while (idx < npix)
+ js.updateExposure(idx, npix, pix);
+
+ // The pixel dump requires many USB reports, since each report
+ // can only send a few pixel values. An integration cycle has
+ // been running all this time, since each read starts a new
+ // cycle. Our timing is longer than usual on this round, so
+ // the integration won't be comparable to a normal cycle. Throw
+ // this one away by doing a read now, and throwing it away - that
+ // will get the timing of the *next* cycle roughly back to normal.
+ ccd.read(pix, npix);
+ }
+
#ifdef DEBUG_PRINTF
if (x != 0 || y != 0)
printf("%d,%d\r\n", x, y);
