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 14:df700b22ca08, committed 2014-09-26
- Comitter:
- mjr
- Date:
- Fri Sep 26 20:51:02 2014 +0000
- Parent:
- 13:72dda449c3c0
- Child:
- 15:eb8aac252eba
- Commit message:
- Reduce button input latency by reducing debounce time and polling during CCD read cycle
Changed in this revision
--- a/TSL1410R/tsl1410r.h Sat Sep 13 23:47:32 2014 +0000
+++ b/TSL1410R/tsl1410r.h Fri Sep 26 20:51:02 2014 +0000
@@ -34,7 +34,11 @@
// If the caller has other work to tend to that takes longer than the
// desired maximum integration time, it can call clear() to clock out
// the current pixels and start a fresh integration cycle.
- void read(uint16_t *pix, int n);
+ void read(uint16_t *pix, int n) { read(pix, n, 0, 0, 0); }
+
+ // Read with interval callback. We'll call the callback the given
+ // number of times per read cycle.
+ void read(uint16_t *pix, int n, void (*cb)(void *ctx), void *cbctx, int cbcnt);
// Clock through all pixels to clear the array. Pulses SI at the
// beginning of the operation, which starts a new integration cycle.
--- a/TSL1410R/tsl410r.cpp Sat Sep 13 23:47:32 2014 +0000
+++ b/TSL1410R/tsl410r.cpp Fri Sep 26 20:51:02 2014 +0000
@@ -24,7 +24,7 @@
}
}
-void TSL1410R::read(uint16_t *pix, int n)
+void TSL1410R::read(uint16_t *pix, int n, void (*cb)(void *ctx), void *cbctx, int cbcnt)
{
// start the next integration cycle by pulsing SI and one clock
si = 1;
@@ -34,22 +34,41 @@
// figure how many pixels to skip on each read
int skip = nPix/n - 1;
+
+ // figure the callback interval
+ int cbInterval = nPix;
+ if (cb != 0)
+ cbInterval = nPix/(cbcnt+1);
- // read the pixels
- for (int src = 0, dst = 0 ; src < nPix ; ++src)
+ // read all of the pixels
+ for (int src = 0, dst = 0 ; src < nPix ; )
{
- // read this pixel
- pix[dst++] = ao.read_u16();
+ // figure the end of this callback interval
+ int srcEnd = src + cbInterval;
+ if (srcEnd > nPix)
+ srcEnd = nPix;
- // clock in the next pixel
- clock = 1;
- clock = 0;
+ // read one callback chunk of pixels
+ for ( ; src < srcEnd ; ++src)
+ {
+ // read this pixel
+ pix[dst++] = ao.read_u16();
- // clock skipped pixels
- for (int i = 0 ; i < skip ; ++i, ++src) {
+ // clock in the next pixel
clock = 1;
clock = 0;
+
+ // clock skipped pixels
+ for (int i = 0 ; i < skip ; ++i, ++src)
+ {
+ clock = 1;
+ clock = 0;
+ }
}
+
+ // call the callback, if we're not at the last pixel
+ if (cb != 0 && src < nPix)
+ (*cb)(cbctx);
}
// clock out one extra pixel to leave A1 in the high-Z state
--- a/main.cpp Sat Sep 13 23:47:32 2014 +0000
+++ b/main.cpp Fri Sep 26 20:51:02 2014 +0000
@@ -706,9 +706,9 @@
// start timing the next interval
buttonTimer.reset();
- // AND together readings over 50ms
+ // AND together readings over 25ms
int ms = 0;
- for (int i = 1 ; i < countof(readings) && ms < 50 ; ++i)
+ for (int i = 1 ; i < countof(readings) && ms < 25 ; ++i)
{
// find the next prior reading, wrapping in the circular buffer
int j = ri - i;
@@ -1125,11 +1125,19 @@
// ---------------------------------------------------------------------------
//
-// Clear the I2C bus for the MMA8451!. This seems necessary some of the time
+// Clear the I2C bus for the MMA8451Q. This seems necessary some of the time
// for reasons that aren't clear to me. Doing a hard power cycle has the same
// effect, but when we do a soft reset, the hardware sometimes seems to leave
// the MMA's SDA line stuck low. Forcing a series of 9 clock pulses through
-// the SCL line is supposed to clear this conidtion.
+// the SCL line is supposed to clear this condition. I'm not convinced this
+// actually works with the way this component is wired on the KL25Z, but it
+// seems harmless, so we'll do it on reset in case it does some good. What
+// we really seem to need is a way to power cycle the MMA8451Q if it ever
+// gets stuck, but this is simply not possible in software on the KL25Z.
+//
+// If the accelerometer does get stuck, and a software reboot doesn't reset
+// it, the only workaround is to manually power cycle the whole KL25Z by
+// unplugging both of its USB connections.
//
void clear_i2c()
{
@@ -1146,6 +1154,21 @@
wait_us(20);
}
}
+
+// ---------------------------------------------------------------------------
+//
+// CCD read interval callback. When reading the CCD, we'll call this
+// several times over the course of the read loop to refresh the button
+// states. This allows us to debounce the buttons while the long CCD
+// read cycle is taking place, so that we can reliably report button
+// states after each CCD read cycle. (The read cycle takes about 30ms,
+// which should be enough time to reliably debounce the buttons.)
+//
+void ccdReadCB(void *)
+{
+ // read the keyboard
+ readButtonsDebounced();
+}
// ---------------------------------------------------------------------------
//
@@ -1496,7 +1519,7 @@
int znew = z;
// read the array
- ccd.read(pix, npix);
+ ccd.read(pix, npix, ccdReadCB, 0, 3);
// get the average brightness at each end of the sensor
long avg1 = (long(pix[0]) + long(pix[1]) + long(pix[2]) + long(pix[3]) + long(pix[4]))/5;
