Pinscape Controller version 1 fork. This is a fork to allow for ongoing bug fixes to the original controller version, from before the major changes for the expansion board project.

Dependencies:   FastIO FastPWM SimpleDMA mbed

Fork of Pinscape_Controller by Mike R

Files at this revision

API Documentation at this revision

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

USBDevice.lib Show annotated file Show diff for this revision Revisions of this file
USBJoystick/USBJoystick.cpp Show annotated file Show diff for this revision Revisions of this file
USBJoystick/USBJoystick.h 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
--- 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);