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.
Dependencies: mbed FastIO FastPWM USBDevice
Fork of Pinscape_Controller by
Diff: TSL1410R/tsl1410r.h
- Revision:
- 35:e959ffba78fd
- Parent:
- 25:e22b88bd783a
- Child:
- 40:cc0d9814522b
--- a/TSL1410R/tsl1410r.h Thu Dec 03 07:34:57 2015 +0000 +++ b/TSL1410R/tsl1410r.h Sat Dec 19 06:37:19 2015 +0000 @@ -4,25 +4,51 @@ * This provides a high-level interface for the Taos TSL1410R linear CCD array sensor. */ - #include "mbed.h" - #include "config.h" - #include "FastIO.h" - #include "FastAnalogIn.h" +#include "mbed.h" +#include "config.h" +#include "FastAnalogIn.h" - #ifndef TSL1410R_H - #define TSL1410R_H +#ifndef TSL1410R_H +#define TSL1410R_H + +// For faster GPIO on the clock pin, we write the IOPORT registers directly. +// PORT_BASE gives us the memory mapped location of the IOPORT register set +// for a pin; PINMASK gives us the bit pattern to write to the registers. +// +// - To turn a pin ON: PORT_BASE(pin)->PSOR |= PINMASK(pin) +// - To turn a pin OFF: PORT_BASE(pin)->PCOR |= PINMASK(pin) +// - To toggle a pin: PORT_BASE(pin)->PTOR |= PINMASK(pin) +// +// When used in a loop where the port address and pin mask are cached in +// local variables, this runs at the same speed as the FastIO library - about +// 78ns per pin write on the KL25Z. Not surprising since it's doing the same +// thing, and the compiler should be able to reduce a pin write to a single ARM +// instruction when the port address and mask are in local register variables. +// The advantage over the FastIO library is that this approach allows for pins +// to be assigned dynamically at run-time, which we prefer because it allows for +// configuration changes to be made on the fly rather than having to recompile +// the program. +#define GPIO_PORT_BASE(pin) ((FGPIO_Type *)(FPTA_BASE + ((unsigned int)pin >> PORT_SHIFT) * 0x40)) +#define GPIO_PINMASK(pin) (1 << ((pin & 0x7F) >> 2)) -template <PinName siPin, PinName clockPin> class TSL1410R +class TSL1410R { public: - // set up the analog in port for reading the currently selected - // pixel value - TSL1410R(PinName aoPin) : ao(aoPin) + TSL1410R(int nPix, PinName siPin, PinName clockPin, PinName ao1Pin, PinName ao2Pin) + : nPix(nPix), si(siPin), clock(clockPin), ao1(ao1Pin), ao2(ao2Pin) { + // we're in parallel mode if ao2 is a valid pin + parallel = (ao2Pin != NC); + + // remember the clock pin port base and pin mask for fast access + clockPort = GPIO_PORT_BASE(clockPin); + clockMask = GPIO_PINMASK(clockPin); + // disable continuous conversion mode in FastAnalogIn - since we're // reading discrete pixel values, we want to control when the samples // are taken rather than continuously averaging over time - ao.disable(); + ao1.disable(); + if (parallel) ao2.disable(); // clear out power-on noise by clocking through all pixels twice clear(); @@ -66,38 +92,84 @@ // the current pixels and start a fresh integration cycle. void read(uint16_t *pix, int n) { + // get the clock pin pointers into local variables for fast access + register FGPIO_Type *clockPort = this->clockPort; + register uint32_t clockMask = this->clockMask; + // start the next integration cycle by pulsing SI and one clock si = 1; - clock = 1; + clockPort->PSOR |= clockMask; // turn the clock pin on (clock = 1) si = 0; - clock = 0; + clockPort->PCOR |= clockMask; // turn the clock pin off (clock = 0) // figure how many pixels to skip on each read int skip = nPix/n - 1; // read all of the pixels - for (int src = 0, dst = 0 ; src < nPix ; ++src) + if (parallel) { - // clock in and read the next pixel - clock = 1; - ao.enable(); - wait_us(1); - clock = 0; - wait_us(11); - pix[dst++] = ao.read_u16(); - ao.disable(); - - // clock skipped pixels - for (int i = 0 ; i < skip ; ++i, ++src) + // parallel mode - read pixels from each half sensor concurrently + int nPixHalf = nPix/2; + for (int src = 0, dst = 0 ; src < nPixHalf ; ++src) { - clock = 1; - clock = 0; + // pulse the clock and start the ADC sampling + clockPort->PSOR |= clockMask; + ao1.enable(); + ao2.enable(); + wait_us(1); + clockPort->PCOR |= clockMask; + + // wait for the ADCs to stabilize + wait_us(11); + + // read the pixels + pix[dst] = ao1.read_u16(); + pix[dst+n/2] = ao2.read_u16(); + + // turn off the ADC until the next pixel is ready + ao1.disable(); + ao2.disable(); + + // clock skipped pixels + for (int i = 0 ; i < skip ; ++i, ++src) + { + clockPort->PSOR |= clockMask; + clockPort->PCOR |= clockMask; + } + } + } + else + { + // serial mode - read all pixels in a single file + for (int src = 0, dst = 0 ; src < nPix ; ++src) + { + // pulse the clock and start the ADC sampling + clockPort->PSOR |= clockMask; + ao1.enable(); + wait_us(1); + clockPort->PCOR |= clockMask; + + // wait for the ADC sample to stabilize + wait_us(11); + + // read the ADC sample + pix[dst++] = ao1.read_u16(); + + // turn off the ADC until the next pixel is ready + ao1.disable(); + + // clock skipped pixels + for (int i = 0 ; i < skip ; ++i, ++src) + { + clockPort->PSOR |= clockMask; + clockPort->PCOR |= clockMask; + } } } // clock out one extra pixel to leave A1 in the high-Z state - clock = 1; - clock = 0; + clockPort->PSOR |= clockMask; + clockPort->PCOR |= clockMask; } // Clock through all pixels to clear the array. Pulses SI at the @@ -106,27 +178,32 @@ // integrated while the clear() was taking place. void clear() { + // get the clock pin pointers into local variables for fast access + register FGPIO_Type *clockPort = this->clockPort; + register uint32_t clockMask = this->clockMask; + // clock in an SI pulse si = 1; - clock = 1; - clock = 0; + clockPort->PSOR |= clockMask; si = 0; + clockPort->PCOR |= clockMask; // clock out all pixels for (int i = 0 ; i < nPix + 1 ; ++i) { - clock = 1; - clock = 0; + clockPort->PSOR |= clockMask; + clockPort->PCOR |= clockMask; } } - // number of pixels in the array - static const int nPix = CCD_NPIXELS; - - private: - FastOut<siPin> si; - FastOut<clockPin> clock; - FastAnalogIn ao; + int nPix; // number of pixels in physical sensor array + DigitalOut si; + DigitalOut clock; + FGPIO_Type *clockPort; // IOPORT base address for clock pin, for fast writes + uint32_t clockMask; // IOPORT register bit mask for clock pin + FastAnalogIn ao1; + FastAnalogIn ao2; // valid iff running in parallel mode + bool parallel; // true -> running in parallel mode }; #endif /* TSL1410R_H */