An I/O controller for virtual pinball machines: accelerometer nudge sensing, analog plunger input, button input encoding, LedWiz compatible output controls, and more.

Dependencies:   mbed FastIO FastPWM USBDevice

Fork of Pinscape_Controller by Mike R

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers TCD1103.h Source File

TCD1103.h

00001 // Toshiba TCD1103 linear CCD image sensor, 1x1500 pixels.
00002 //
00003 // This sensor is conceptually similar to the TAOS TSL1410R (the original 
00004 // Pinscape sensor!).  Like the TSL1410R, it has a linear array of optical
00005 // sensor pixels that convert incident photons into electrical charge, an
00006 // internal shift register connected to the pixel file that acts as an 
00007 // electronic shutter, and a serial interface that clocks the pixels out
00008 // to the host in analog voltage level format.
00009 //
00010 // The big physical difference between this sensor and the old TAOS sensors
00011 // is the size.  The TAOS sensors were (by some miracle) approximately the
00012 // same size as the plunger travel range, so we were able to take "contact"
00013 // images without any optics, by placing the plunger close to the sensor,
00014 // back-lighting it, and essentially taking a picture of its shadow.  The
00015 // Toshiba sensor, in contrast, has a pixel window that's only 8mm long, so
00016 // the contact image approach won't work.  Instead, we have to use a lens
00017 // to focus a reduced image (about 1:10 scale) on the sensor.  That makes
00018 // the physical setup more complex, but it has the great advantage that we
00019 // get a focused image.  The shadow was always fuzzy in  the old contact 
00020 // image approach, which reduced the effective resolution when determining 
00021 // the plunger position.  With a focused image, we can get single-pixel 
00022 // resolution.  With this Toshiba sensor's 1500 pixels, that's about 500 
00023 // dpi, which beats every other sensor we've come up with.
00024 //
00025 // The electronic interface to this sensor is similar to the TAOS, but it
00026 // has enough differences that we can't share the same code base.
00027 //
00028 // As with the 1410R, we have to use DMA for the ADC transfers in order
00029 // to keep up with the high data rate without overloading the KL25Z CPU.
00030 // With the 1410R, we're able to use the ADC itself as the clock source,
00031 // by running the ADC in continous mode and using its "sample ready" signal
00032 // to trigger the DMA transfer.  We used this to generate the external clock
00033 // signal for the sensor by "linking" the ADC's DMA channel to another pair
00034 // of DMA channels that generated the clock up/down signal each time an ADC
00035 // sample completed.  This strategy won't work with the Toshiba sensor,
00036 // though, because the Toshiba sensor's timing sequence requires *two* clock
00037 // pulses per pixel.  I can't come up with a way to accomplish that with the
00038 // linked-DMA approach.  Instead, we'll have to generate a true clock signal
00039 // for the sensor, and drive the DMA conversions off of that clock.
00040 //
00041 // The obvious (and, as far as I can tell, only) way to generate the clock
00042 // signal with the KL25Z at the high frequency required is to use a TPM -
00043 // the KL25Z module that drives PWM outputs.  TPM channels are designed
00044 // precisely for this kind of work, so this is the right approach in terms of
00045 // suitability, but it has the downside that TPM units are an extremely scarce
00046 // resource on the KL25Z.  We only have three of them to work with.  Luckily,
00047 // the rest of the Pinscape software only requires two of them: one for the
00048 // IR transmitter (which uses a TPM channel to generate the 41-48 kHz carrier
00049 // wave used by nearly all consumer IR remotes), and one for the TLC5940
00050 // driver (which uses it to generate the grayscale clock signal).  Note that
00051 // we also use PWM channels for feedback device output ports, but those don't
00052 // have any dependency on the TPM period - they'll work with whatever period
00053 // the underlying TPM is set to use.  So the feedback output ports can all
00054 // happily use free channels on TPM units claimed by any of the dedicated
00055 // users (IR, TLC5940, and us).
00056 //
00057 // But what do we do about the 2:1 ratio between master clock pulses and ADC
00058 // samples?  The "right" way would be to allocate a second TPM unit to
00059 // generate a second clock signal at half the frequency of the master clock, 
00060 // and use that as the ADC trigger.  But as we just said, we only have three 
00061 // TPM units in the whole system, and two of them are already claimed for 
00062 // other uses, so we only have one unit available for our use here.
00063 //
00064 // Fortunately, we can make do with one TPM unit, by taking advantage of a 
00065 // feature/quirk of the KL25Z ADC.  The quirk lets us take ADC samples at
00066 // exactly half of the master clock rate, in perfect sync.  The trick is to
00067 // pick a combination of master clock rate and ADC sample mode such that the
00068 // ADC conversion time is *almost but not quite* twice as long as the master
00069 // clock rate.  With that combination of timings, we can trigger the ADC
00070 // from the TPM, and we'll get an ADC sample on exactly every other tick of
00071 // the master clock.  The reason this works is that the KL25Z ADC ignores
00072 // hardware triggers (the TPM trigger is a hardware trigger) that occur when
00073 // a conversion is already in progress.  So if the ADC sampling time is more
00074 // than one master clock period, the ADC will always be busy one clock tick
00075 // after a sample starts, so it'll ignore that first clock tick.  But as 
00076 // long as the sampling time is less than *two* master clock periods, the
00077 // ADC will always be ready again on the second tick.  So we'll get one ADC
00078 // sample for every two master clock ticks, exactly as we need.
00079 //
00080 // This is all possible because the ADC timing is deterministic, and runs on
00081 // the same clock as the TPM.  The KL25Z Subfamily Reference Manual explains
00082 // how to calculate the ADC conversion time for a given combination of mode
00083 // bits.  So we just have to pick an ADC mode, calculate its conversion time,
00084 // and then select a TPM period that's slightly more than 1/2 of the ADC
00085 // conversion time.
00086 //
00087 // I know this sounds like it should be prone to unpredictable timing bugs,
00088 // but it's actually 100% deterministic!  It's truly deterministic because
00089 // the underlying clock for the TPM and ADC is shared.  Intuitively, we
00090 // think of time-based processes as inherently stochastic because clocks
00091 // are never perfect, so if you have two time-based processes based on
00092 // separate clocks, the two processes are never perfectly in sync because
00093 // their separate clocks will drift slightly relative to one another.  But
00094 // that's not what's going on here.  The time-based processes we're talking
00095 // about are tied to the same underlying clock, so there's absolutely no
00096 // possibility of clock drift or phase shift or anything else that feeds
00097 // into that intuition about stochasticness in time-based processes.  In
00098 // addition, the key ADC feature we're exploiting for the clock doubling -
00099 // that the ADC ignores hardware triggers during an active cycle - isn't
00100 // some accidental behavior we observed empirically.  It's by design and
00101 // it's documented.  We can count on it always being the case with this
00102 // ADC.  Between those two factors (synchronous clock, designed and
00103 // documented ADC behavior), we can count on the timing being EXACTLY the
00104 // same on EVERY sample.  We're not counting on being "lucky".
00105 //
00106 // Note that there are several other, similar Toshiba sensors with the same
00107 // electrical interface and almost the same signal timing, but with a 4:1
00108 // ratio between the master clock ticks and the pixel outputs.  This code
00109 // could be adapted to those sensors using the same "trick" we use for the
00110 // 2:1 timing ratio, by choosing an ADC mode with a sampling rate that's
00111 // between 3*fM and 4*fM.  That will make the ADC ignore the first three
00112 // master clocks in each cycle, triggering a new sample reading on every
00113 // fourth master clock tick, achieving the desired 4:1 ratio.  We don't
00114 // provide an option for that because there are no such Toshiba sensors in
00115 // production that are of interest to us as plunger sensors, and because
00116 // the selection of a suitable fM timing and ADC mode are both dependent
00117 // on the constraints of your application, so it's not feasible to automate
00118 // the selection of either based on simple numeric parameters.  If you want
00119 // to adapt the code, start by figuring out the range of fM timing you can
00120 // accept, then look at the KL25Z manual to work out the ADC cycle timing
00121 // for various modes with the properties you want.  You can then adjust
00122 // either or both the fM timing and ADC settings until you find a suitable
00123 // balance in the timing.  The Toshiba sensors can generally accept a wide
00124 // range of fM rates, so you can count both the clock rate and ADC modes as
00125 // free variables, within the constraints of your application in terms of
00126 // required frame rate and ADC sampling quality.
00127 //
00128 //
00129 // Pixel output signal
00130 //
00131 // The pixel output signal from this sensor is an analog voltage level.  It's
00132 // inverted from the brightness: higher brightness is represented by lower
00133 // voltage.  The dynamic range is only about 1V, with a 1V floor.  So dark 
00134 // pixels read at about 2V, and saturated pixels read at about 1V.
00135 //
00136 // The output pin from the sensor connects to what is essentially a very
00137 // small capacitor containing a tiny amount of charge.  This isn't a good
00138 // source for the ADC to sample, so some additional circuitry is required
00139 // to convert the charge to a low-impedance voltage source suitable for
00140 // connecting to an ADC.  The driver circuit recommended in the Toshiba
00141 // data sheet consists of a high-gain PNP transistor and a few resistors.
00142 // See "How to connect to the KL25Z" below for the component types and
00143 // values we've tested successfully.
00144 //
00145 //
00146 // Inverted logic signals
00147 //
00148 // The Toshiba data sheet recommends buffering the logic signal inputs from 
00149 // an MCU through a 74HC04 inverter, because the sensor's logic gates have
00150 // relatively high input capacitance that an MCU might not be able to drive 
00151 // fast enough directly to keep up with the sensor's timing requirements.  
00152 // SH in particular might be a problem because of its 150pF capacitance,
00153 // which implies about a 2us rise/fall time if driven directly by KL25Z
00154 // GPIOs, which is too slow.
00155 //
00156 // The software will work with or without the logic inversion, in case anyone
00157 // wants to try implementing it with direct GPIO drive (not recommended) or 
00158 // with a non-inverting buffer in place of the 74HC04.  Simply instantiate the
00159 // class with the 'invertedLogicGates' template parameter set to false to use 
00160 // non-inverted logic.
00161 //
00162 //
00163 // How to connect to the KL25Z
00164 //
00165 // Follow the "typical drive circuit" presented in the Toshiba data sheet.
00166 // They leave some of the parts unspecified, so here are the specific values
00167 // we used for our reference implementation:
00168 //
00169 //   - 3.3V power supply
00170 //   - 74HC04N hex inverter for the logic gate inputs (fM, SH, ICG)
00171 //   - 0.1uF ceramic + 10uF electrolytic decoupling capacitors (GND to Vcc))
00172 //   - BC212A PNP transistor for the output drive (OS), with:
00173 //     - 150 ohm resistor on the base
00174 //     - 150 ohm resistor between collector and GND
00175 //     - 2.2K ohm resistor between emitter and Vcc
00176 //
00177 
00178 #include "config.h"
00179 #include "NewPwm.h"
00180 #include "AltAnalogIn.h"
00181 #include "SimpleDMA.h"
00182 #include "DMAChannels.h"
00183 
00184 
00185 template<bool invertedLogicGates> class TCD1103
00186 {
00187 public:
00188     TCD1103(PinName fmPin, PinName osPin, PinName icgPin, PinName shPin) :
00189        fm(fmPin, invertedLogicGates),
00190        os(osPin, false, 6, 1),    // single sample, 6-cycle long sampling mode, no averaging
00191        icg(icgPin), 
00192        sh(shPin),
00193        os_dma(DMAch_TDC_ADC)
00194     {
00195         // Idle conditions: SH low, ICG high.
00196         sh = logicLow;
00197         icg = logicHigh;
00198 
00199         // Set a zero minimum integration time by default.  Note that tIntMin
00200         // has no effect when it's less than the absolute minimum, which is
00201         // the pixel transfer time for one frame (around 3ms).  tIntMin only
00202         // kicks in when it goes above that absolute minimum, at which point
00203         // we'll wait for any additional time needed to reach tIntMin before
00204         // starting the next integration cycle.
00205         tIntMin = 0;
00206 
00207         // Calibrate the ADC for best accuracy
00208         os.calibrate();
00209         
00210         // ADC sample conversion time.  This must be calculated based on the
00211         // combination of parameters selected for the os() initializer above.
00212         // See the KL25 Sub-Family Reference Manual, section 28.4.4.5, for the
00213         // formula.  We operate in single-sample mode, so when you read the
00214         // Reference Manual tables, the sample time value to use is the
00215         // "First or Single" value.
00216         const float ADC_TIME = 2.1041667e-6f; // 6-cycle long sampling, no averaging
00217 
00218         // Set the TPM cycle time to satisfy our timing constraints:
00219         // 
00220         //   Tm + epsilon1 < A < 2*Tm - epsilon2
00221         //
00222         // where A is the ADC conversion time and Tm is the master clock
00223         // period, and the epsilons provide a margin of safety for any 
00224         // non-deterministic component to the timing of A and Tm.  The
00225         // epsilons could be zero if the timing of the ADC is perfectly
00226         // deterministic; this must be determined empirically.
00227         //
00228         // The most conservative solution would be to make epsilon as large
00229         // as possible, which means bisecting the time window by making
00230         // A = 1.5*T, or, equivalently, T = A/1.5 (the latter form being more 
00231         // useful because T is the free variable here, as we can only control
00232         // A to the extent that we can choose the ADC parameters).
00233         //
00234         // But we'd also like to make T as short as possible while maintaining
00235         // reliable operation.  Shorter T yields a higher frame rate, and we
00236         // want the frame rate to be as high as possible so that we can track
00237         // fast plunger motion accurately.  Empirically, we can get reliable
00238         // results by using half of the ADC time plus a small buffer time.
00239         //
00240         fm.getUnit()->period(masterClockPeriod = ADC_TIME/2 + 0.25e-6f);
00241         
00242         // Start the master clock running with a 50% duty cycle
00243         fm.write(0.5f);
00244 
00245         // Allocate our double pixel buffers.  
00246         pix1 = new uint8_t[nPixAlo * 2];
00247         pix2 = pix1 + nPixAlo;
00248         
00249         // put the first DMA transfer into the first buffer (pix1)
00250         pixDMA = 0;
00251         clientOwnsStablePix = false;
00252 
00253         // start the sample timer with an arbitrary epoch of "now"
00254         t.start();
00255 
00256         // Set up the ADC transfer DMA channel.  This channel transfers
00257         // the current analog sampling result from the ADC output register
00258         // to our pixel array.
00259         os.initDMA(&os_dma);
00260 
00261         // Register an interrupt callback so that we're notified when
00262         // the last ADC transfer completes.
00263         os_dma.attach(this, &TCD1103::transferDone);
00264         
00265         // Set up the ADC to trigger on the master clock's TPM channel
00266         os.setTriggerTPM(fm.getUnitNum());
00267         
00268         // clear the timing statistics        
00269         totalXferTime = 0.0; 
00270         maxXferTime = 0;
00271         minXferTime = 0xffffffff;
00272         nRuns = 0;
00273 
00274         // start the first transfer
00275         startTransfer();
00276     }
00277         
00278     // logic gate levels, based on whether or not the logic gate connections
00279     // in the hardware are buffered through inverters
00280     static const int logicLow = invertedLogicGates ? 1 : 0;
00281     static const bool logicHigh = invertedLogicGates ? 0 : 1;
00282     
00283     // ready to read
00284     bool ready() { return clientOwnsStablePix; }
00285         
00286     // Get the stable pixel array.  This is the image array from the
00287     // previous capture.  It remains valid until the next startCapture()
00288     // call, at which point this buffer will be reused for the new capture.
00289     void getPix(uint8_t * &pix, uint32_t &t)
00290     {
00291         // Return the pixel array that ISN'T assigned to the DMA.
00292         if (pixDMA)
00293         {
00294             // DMA owns pix2, so the stable array is pix1
00295             pix = pix1;
00296             t = t1;
00297         }
00298         else
00299         {
00300             // DMA owns pix1, so the stable array is pix2
00301             pix = pix2;
00302             t = t2;
00303         }
00304     }
00305     
00306     // release the client's pixel buffer
00307     void releasePix() { clientOwnsStablePix = false; }
00308     
00309     // figure the average scan time from the running totals
00310     uint32_t getAvgScanTime() { return static_cast<uint32_t>(totalXferTime / nRuns);}
00311 
00312     // Set the requested minimum integration time.  If this is less than the
00313     // sensor's physical minimum time, the physical minimum applies.
00314     virtual void setMinIntTime(uint32_t us)
00315     {
00316         tIntMin = us;
00317     }
00318     
00319 protected:
00320     // Start an image capture from the sensor.  Waits the previous
00321     // capture to finish if it's still running, then starts a new one
00322     // and returns immediately.  The new capture proceeds asynchronously 
00323     // via DMA hardware transfer, so the client can continue with other 
00324     // processing during the capture.
00325     void startTransfer()
00326     {
00327         // if we own the stable buffer, swap buffers
00328         if (!clientOwnsStablePix)
00329         {
00330             // swap buffers
00331             pixDMA ^= 1;
00332             
00333             // release the prior DMA buffer to the client
00334             clientOwnsStablePix = true;
00335         }
00336         
00337         // figure our destination buffer
00338         uint8_t *dst = pixDMA ? pix2 : pix1;
00339         
00340         // Set up the active pixel array as the destination buffer for 
00341         // the ADC DMA channel. 
00342         os_dma.destination(dst, true);
00343         
00344         // Start the read cycle by sending the ICG/SH pulse sequence
00345         uint32_t tNewInt = gen_SH_ICG_pulse(true);
00346 
00347         // Set the timestamp for the current active buffer.  The ICG/SH
00348         // gymnastics we just did transferred the CCD pixels into the sensor's
00349         // internal shift register and reset the pixels, starting a new
00350         // integration cycle.  So the pixels we just shifted started
00351         // integrating the *last* time we did that, which we recorded as
00352         // tInt at the time.  The image we're about to transfer therefore 
00353         // represents the light collected between tInt and the SH pulse we
00354         // just did.  The image covers a time range rather than a single 
00355         // point in time, but we still have to give it a single timestamp. 
00356         // Use the midpoint of the integration period.
00357         uint32_t tmid = (tNewInt + tInt) >> 1;
00358         if (pixDMA)
00359             t2 = tmid;
00360         else
00361             t1 = tmid;
00362 
00363         // Record the start time of the currently active integration period
00364         tInt = tNewInt;
00365     }
00366     
00367     // End of transfer notification.  This runs as an interrupt handler when
00368     // the DMA transfer completes.
00369     void transferDone()
00370     {
00371         // stop the ADC triggering
00372         os.stop();
00373 
00374         // add this sample to the timing statistics (for diagnostics and
00375         // performance measurement)
00376         uint32_t now = t.read_us();
00377         uint32_t dt = dtPixXfer = static_cast<uint32_t>(now - tXfer);
00378         totalXferTime += dt;
00379         nRuns += 1;
00380         
00381         // collect debug statistics
00382         if (dt < minXferTime) minXferTime = dt;
00383         if (dt > maxXferTime) maxXferTime = dt;
00384 
00385         // figure how long we've been integrating so far on this cycle 
00386         uint32_t dtInt = now - tInt;
00387         
00388         // Figure the time to the start of the next transfer.  Wait for the
00389         // remainder of the current integration period if we haven't yet
00390         // reached the requested minimum, otherwise just start almost
00391         // immediately.  (Not *actually* immediately: we don't want to start 
00392         // the new transfer within this interrupt handler, because the DMA
00393         // IRQ doesn't reliably clear if we start a new transfer immediately.)
00394         uint32_t dtNext = dtInt < tIntMin ? tIntMin - dtInt : 1;
00395         
00396         // Schedule the next transfer
00397         integrationTimeout.attach_us(this, &TCD1103::startTransfer, dtNext);
00398     }
00399 
00400     // Generate an SH/ICG pulse.  This transfers the pixel data from the live
00401     // sensor photoreceptors into the sensor's internal shift register, clears
00402     // the live pixels, and starts a new integration cycle.
00403     //
00404     // If start_dma_xfer is true, we'll start the DMA transfer for the ADC
00405     // pixel data.  We handle this here because the sensor starts clocking
00406     // out pixels precisely at the end of the ICG pulse, so we have to be
00407     // be very careful about the timing.
00408     //
00409     // Returns the timestamp (relative to our image timer 't') of the end
00410     // of the SH pulse, which is the moment the new integration cycle starts.
00411     //
00412     // Note that we send these pulses synchronously - that is, this routine
00413     // blocks until the pulses have been sent.  The overall sequence takes 
00414     // about 2.5us to 3us, so it's not a significant interruption of the 
00415     // main loop.
00416     //
00417     uint32_t gen_SH_ICG_pulse(bool start_dma_xfer)
00418     {
00419         // Make sure the ADC is stopped
00420         os.stop();
00421 
00422         // If desired, prepare to start the DMA transfer for the ADC data.
00423         // (Set up a dummy location to write in lieu of the DMA register if
00424         // DMA initiation isn't required, so that we don't have to take the
00425         // time for a conditional when we're ready to start the DMA transfer.
00426         // The timing there will be extremely tight, and we can't afford the
00427         // extra instructions to test a condition.)
00428         uint8_t dma_chcfg_dummy = 0;
00429         volatile uint8_t *dma_chcfg = start_dma_xfer ? os_dma.prepare(nPixSensor, true) : &dma_chcfg_dummy;
00430         
00431         // The basic idea is to take ICG low, and while holding ICG low,
00432         // pulse SH.  The coincidence of the two pulses transfers the charge
00433         // from the live pixels into the shift register, which effectively
00434         // discharges the live pixels and thereby starts a new integration
00435         // cycle.
00436         //
00437         // The timing of the pulse sequence is rather tightly constrained 
00438         // per the data sheet, so we have to take some care in executing it:
00439         //
00440         //   ICG ->  LOW
00441         //   100-1000 ns delay   (*)
00442         //   SH -> HIGH
00443         //   >1000ns delay
00444         //   SH -> LOW
00445         //   >1000ns delay
00446         //   ICG -> high         (**)
00447         //
00448         // There are two steps here that are tricky:
00449         //
00450         // (*) is a narrow window that we can't achieve with an mbed 
00451         // microsecond timer.  Instead, we'll do a couple of extra writes 
00452         // to the ICG register, which take about 60ns each.
00453         //
00454         // (**) has the rather severe constraint that the transition must 
00455         // occur AND complete while the master clock is high.  Other people 
00456         // working with similar Toshiba chips in MCU projects have suggested
00457         // that this constraint can safely be ignored, so maybe the data
00458         // sheet's insistence about it is obsolete advice from past Toshiba
00459         // sensors that the doc writers carried forward by copy-and-paste.
00460         // Toshiba has been making these sorts of chips for a very long time,
00461         // and the data sheets for many of them are obvious copy-and-paste
00462         // jobs.  But let's take the data sheet at its word and assume that 
00463         // this is important for proper operation.  Our best hope of 
00464         // satisfying this constraint is to synchronize the start of the
00465         // ICG->high transition with the start of a TPM cycle on the master
00466         // clock.  That guarantees that the ICG transition starts when the
00467         // clock signal is high (as each TPM cycle starts out high), and
00468         // gives us the longest possible runway for the transition to
00469         // complete while the clock is still high, as we get the full
00470         // length of the high part of the cycle to work with.  To quantify,
00471         // it gives us about 600ns.  The register write takes about 60ns, 
00472         // and waitEndCycle() adds several instructions of overhead, perhaps
00473         // 200ns, so we get around 300ns for the transition to finish.  That
00474         // should be a gracious plenty assuming that the hardware is set up 
00475         // with an inverter to buffer the clock signals.  The inverter should
00476         // be able to pull up the 35pF on ICG in a "typical" 30ns (rise time
00477         // plus propagation delay, per the 74HC04 data sheet) and max 150ns.
00478         // This seems to be one place where the inverter might really be
00479         // necessary to meet the timing requirements, as the KL25Z GPIO
00480         // might need more like 2us to pull that load up.
00481         //
00482         // There's an additional constraint on the timing at the end of the
00483         // ICG pulse.  The sensor starts clocking out pixels on the rising
00484         // edge of the ICG pulse.  So we need the ICG pulse end to align
00485         // with the start of an ADC cycle.  If we get that wrong, all of our
00486         // ADC samples will be off by half a clock, so every sample will be
00487         // the average of two adjacent pixels instead of one pixel.  That
00488         // would have the effect of shifting the image by half a pixel,
00489         // which could make our edge detection jitter by one pixel from one
00490         // frame to the next.  So we definitely want to avoid this.
00491         //
00492         // The end of the SH pulse triggers the start of a new integration 
00493         // cycle, so note the time of that pulse for image timestamping 
00494         // purposes.  That will be the start time of the NEXT image we 
00495         // transfer after we shift out the current sensor pixels, which 
00496         // represent the pixels from the last time we pulsed SH.
00497         //
00498         icg = logicLow;
00499         icg = logicLow;  // for timing, adds about 150ns > min 100ns
00500 
00501         sh = logicHigh;  // take SH high
00502         
00503         wait_us(1);      // >1000ns delay
00504         sh = logicHigh;  // a little more padding to be sure we're over the minimum
00505         
00506         sh = logicLow;   // take SH low
00507         
00508         uint32_t t_sh = t.read_us();  // this is the start time of the NEXT integration
00509         
00510         wait_us(3);      // >1000ns delay, 5000ns typical; 3us should get us most
00511                          // of the way there, considering that we have some more
00512                          // work to do before we end the ICG pulse
00513         
00514         // Now the tricky part!  We have to end the ICG pulse (take ICG high)
00515         // at the start of a master clock cycle, AND at the start of an ADC 
00516         // sampling cycle.  The sensor will start clocking out pixels the
00517         // instance ICG goes high, so we have to align our ADC cycle so that
00518         // we start a sample at almost exactly the same time we take ICG
00519         // high.
00520         //
00521         // Now, every ADC sampling cycle always starts at a rising edge of 
00522         // the master clock, since the master clock is the ADC trigger.  BUT,
00523         // the converse is NOT true: every rising edge of the master clock
00524         // is NOT an ADC sample start.  Recall that we've contrived the timing
00525         // so that every OTHER master clock rising edge starts an ADC sample.
00526         // 
00527         // So how do we detect which part of the clock cycle we're in?  We
00528         // could conceivably use the COCO bit in the ADC status register to
00529         // detect the little window between the end of one sample and the
00530         // start of the next.  Unfortunately, this doesn't work: the COCO
00531         // bit is never actually set for the duration of even a single CPU
00532         // instruction in our setup, no matter how loose we make the timing
00533         // between the ADC and the fM cycle.  I think the reason is the DMA
00534         // setup: the COCO bit triggers the DMA, and the DMA controller
00535         // reads the ADC result register (the DMA source in our setup),
00536         // which has the side effect of clearing COCO.  I've experimented
00537         // with this using different timing parameters, and the result is
00538         // always the same: the CPU *never* sees the COCO bit set.  The DMA
00539         // trigger timing is evidently deterministic such that the DMA unit
00540         // invariably gets its shot at reading ADC0->R before the CPU does.
00541         //
00542         // The COCO approach would be a little iffy anyway, since we want the
00543         // ADC idle time to be as short as possible, which wouldn't give us
00544         // much time to do all we have to do in the COCO period, even if
00545         // there were one.  What we can do instead is seize control of the
00546         // ADC cycle timing: rather than trying to detect when the cycle
00547         // ends, we can specify when it begins.  We can do this by canceling
00548         // the TPM->ADC trigger and aborting any conversion in progress, then
00549         // reprogramming the TPM->ADC trigger at our leisure.  What we *can*
00550         // detect reliably is the start of a TPM cycle.  So here's our
00551         // strategy:
00552         //
00553         //   - Turn off the TPM->ADC trigger and abort the current conversion
00554         //   - Wait until a new TPM cycle starts
00555         //   - Reset the TPM->ADC trigger.  The first new conversion will
00556         //     start on the next TPM cycle, so we have the remainder of
00557         //     the current TPM cycle to make this happen (about 1us, enough
00558         //     for 16 CPU instructions - plenty for this step)
00559         //   - Wait for the new TPM cycle
00560         //   - End the ICG pulse
00561         //
00562         
00563         // Enable the DMA controller for the new transfer from the ADC.
00564         // The sensor will start clocking out new samples at the ICG rising
00565         // edge, so the next ADC sample to complete will represent the first
00566         // pixel in the new frame.  So we need the DMA ready to go at the
00567         // very next sample.  Recall that the DMA is triggered by ADC
00568         // completion, and ADC is stopped right now, so enabling the DMA 
00569         // won't have any immediate effect - it just spools it up so that
00570         // it's ready to move samples as soon as we resume the ADC.
00571         *dma_chcfg |= DMAMUX_CHCFG_ENBL_MASK;
00572         
00573         // wait for the start of a new master clock cycle
00574         fm.waitEndCycle();
00575         
00576         // Wait one more cycle to be sure the DMA is ready.  Empirically,
00577         // this extra wait is actually required; evidently DMA startup has
00578         // some non-deterministic timing element or perhaps an asynchronous
00579         // external dependency.  In any case, *without* this extra wait,
00580         // the DMA transfer sporadically (about 20% probability) misses the
00581         // very first pixel that the sensor clocks out, so the entire image
00582         // is shifted "left" by one pixel.  That makes the position sensing
00583         // jitter by a pixel from one frame to the next according to whether
00584         // or not we had that one-pixel delay in the DMA startup.  Happily,
00585         // padding the timing by an fM cycle seems to make the DMA startup
00586         // perfectly reliable.
00587         fm.waitEndCycle();
00588         
00589         // Okay, a master clock cycle just started, so we have about 1us 
00590         // (about 16 CPU instructions) before the next one begins.  Resume 
00591         // ADC sampling.  The first new sample will start with the next
00592         // TPM cycle 1us from now.  This step itself takes about 3 machine
00593         // instructions for 180ns, so we have about 820ns left to go.
00594         os.resume();
00595         
00596         // Eerything is queued up!  We just have to fire the starting gun
00597         // on the sensor at the right moment.  And that right moment is the 
00598         // start of the next TPM cycle.  Wait for it...
00599         fm.waitEndCycle();
00600         
00601         // And go!
00602         icg = logicHigh;
00603         
00604         // note the start time of the transfer
00605         tXfer = t.read_us();
00606         
00607         // return the timestamp of the end of the SH pulse - this is the start
00608         // of the new integration period that we just initiated
00609         return t_sh;
00610     }
00611 
00612     // master clock
00613     NewPwmOut fm;
00614     
00615     // analog input for reading the pixel voltage level
00616     AltAnalogIn_8bit os;
00617     
00618     // Integration Clear Gate output
00619     DigitalOut icg;
00620     
00621     // Shift Gate output
00622     DigitalOut sh;
00623     
00624     // DMA channel for the analog input
00625     SimpleDMA os_dma;
00626     
00627     // Master clock period, in seconds, calculated based on the ADC timing
00628     float masterClockPeriod;
00629     
00630     // Number of pixels.  The TCD1103 has 1500 image pixels, plus 32 dummy
00631     // pixels at the front end (before the first image pixel) and another 14
00632     // dummy pixels at the back end.  The sensor always transfers the full
00633     // file on each read cycle, including the dummies, so we have to make
00634     // room for the dummy pixels during each read.
00635     static const int nPixSensor = 1546;
00636     
00637     // Figure the number of pixels to allocate per pixel buffer.  Round
00638     // up to the next 4-byte boundary, so that the buffers are both DWORD-
00639     // aligned.  (This allows using DWORD pointers into the buffer to 
00640     // operate on buffer pixels four at a time, such as in the negative 
00641     // image inversion code in the generic PlungerSensorImage base class.)
00642     static const int nPixAlo = (nPixSensor + 3) & ~3;
00643     
00644     // pixel buffers - we keep two buffers so that we can transfer the
00645     // current sensor data into one buffer via DMA while we concurrently
00646     // process the last buffer
00647     uint8_t *pix1;            // pixel array 1
00648     uint8_t *pix2;            // pixel array 2
00649     
00650     // Timestamps of pix1 and pix2 arrays, in microseconds, in terms of the 
00651     // sample timer (this->t).
00652     uint32_t t1;
00653     uint32_t t2;
00654     
00655     // DMA target buffer.  This is the buffer for the next DMA transfer.
00656     // 0 means pix1, 1 means pix2.  The other buffer contains the stable 
00657     // data from the last transfer.
00658     uint8_t pixDMA;
00659     
00660     // Stable buffer ownership.  At any given time, the DMA subsystem owns
00661     // the buffer specified by pixDMA.  The other buffer - the "stable" buffer,
00662     // which contains the most recent completed frame, can be owned by EITHER
00663     // the client or by the DMA subsystem.  Each time a DMA transfer completes,
00664     // the DMA subsystem looks at the stable buffer owner flag to determine 
00665     // what to do:
00666     //
00667     // - If the DMA subsystem owns the stable buffer, it swaps buffers.  This
00668     //   makes the newly completed DMA buffer the new stable buffer, and makes
00669     //   the old stable buffer the new DMA buffer.  At this time, the DMA 
00670     //   subsystem also changes the stable buffer ownership to CLIENT.
00671     //
00672     // - If the CLIENT owns the stable buffer, the DMA subsystem can't swap
00673     //   buffers, because the client is still using the stable buffer.  It
00674     //   simply leaves things as they are.
00675     //
00676     // In either case, the DMA system starts a new transfer at this point.
00677     //
00678     // The client, meanwhile, is free to access the stable buffer when it has
00679     // ownership.  If the client *doesn't* have ownership, it must wait for
00680     // the ownership to be transferred, which can only be done by the DMA
00681     // subsystem on completing a transfer.
00682     //
00683     // When the client is done with the stable buffer, it transfers ownership
00684     // back to the DMA subsystem.
00685     //
00686     // Transfers of ownership from DMA to CLIENT are done only by DMA.
00687     // Transfers from CLIENT to DMA are done only by CLIENT.  So whoever has
00688     // ownership now is responsible for transferring ownership.
00689     //
00690     volatile bool clientOwnsStablePix;
00691     
00692     // Minimum requested integration time, in microseconds
00693     uint32_t tIntMin;
00694     
00695     // Timeout for generating an interrupt at the end of the integration period
00696     Timeout integrationTimeout;
00697         
00698     // timing statistics
00699     Timer t;                  // sample timer
00700     uint32_t tInt;            // start time (us) of current integration period
00701     uint32_t tXfer;           // start time (us) of current pixel transfer
00702     uint32_t dtPixXfer;       // pixel transfer time of last frame
00703     uint64_t totalXferTime;   // total time consumed by all reads so far
00704     uint32_t nRuns;           // number of runs so far
00705     
00706     // debugging - min/max transfer time statistics
00707     uint32_t minXferTime;
00708     uint32_t maxXferTime;
00709 };