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:
- 43:7a6364d82a41
- Parent:
- 40:cc0d9814522b
- Child:
- 45:c42166b2878c
--- a/TSL1410R/tsl1410r.h Wed Feb 03 22:57:25 2016 +0000 +++ b/TSL1410R/tsl1410r.h Sat Feb 06 20:21:48 2016 +0000 @@ -6,7 +6,7 @@ #include "mbed.h" #include "config.h" -#include "FastAnalogIn.h" +#include "AltAnalogIn.h" #ifndef TSL1410R_H #define TSL1410R_H @@ -28,14 +28,15 @@ // 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)) +#define GPIO_PORT(pin) (((unsigned int)(pin)) >> PORT_SHIFT) +#define GPIO_PORT_BASE(pin) ((FGPIO_Type *)(FPTA_BASE + GPIO_PORT(pin) * 0x40)) +#define GPIO_PINMASK(pin) gpio_set(pin) class TSL1410R { public: - TSL1410R(int nPix, PinName siPin, PinName clockPin, PinName ao1Pin, PinName ao2Pin) - : nPix(nPix), si(siPin), clock(clockPin), ao1(ao1Pin), ao2(ao2Pin) + TSL1410R(int nPixSensor, PinName siPin, PinName clockPin, PinName ao1Pin, PinName ao2Pin) + : nPixSensor(nPixSensor), si(siPin), clock(clockPin), ao1(ao1Pin), ao2(ao2Pin) { // we're in parallel mode if ao2 is a valid pin parallel = (ao2Pin != NC); @@ -44,16 +45,14 @@ 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 - ao1.disable(); - if (parallel) ao2.disable(); - - // clear out power-on noise by clocking through all pixels twice + // clear out power-on random data by clocking through all pixels twice clear(); clear(); + + totalTime = 0.0; nRuns = 0; // $$$ } + + float totalTime; int nRuns; // $$$ // Read the pixels. // @@ -90,86 +89,109 @@ // 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(register uint16_t *pix, int n) { + Timer t; t.start(); // $$$ + // get the clock pin pointers into local variables for fast access - register FGPIO_Type *clockPort = this->clockPort; - register uint32_t clockMask = this->clockMask; + register volatile uint32_t *clockPSOR = &clockPort->PSOR; + register volatile uint32_t *clockPCOR = &clockPort->PCOR; + register const uint32_t clockMask = this->clockMask; // start the next integration cycle by pulsing SI and one clock si = 1; - clockPort->PSOR |= clockMask; // turn the clock pin on (clock = 1) + clock = 1; si = 0; - clockPort->PCOR |= clockMask; // turn the clock pin off (clock = 0) + clock = 0; // figure how many pixels to skip on each read - int skip = nPix/n - 1; + int skip = nPixSensor/n - 1; +///$$$ +static int done=0; +if (done++ == 0) printf("nPixSensor=%d, n=%d, skip=%d, parallel=%d\r\n", nPixSensor, n, skip, parallel); + + // get the clock PSOR and PCOR register addresses for fast access + // read all of the pixels + int dst; if (parallel) { - // parallel mode - read pixels from each half sensor concurrently - int nPixHalf = nPix/2; - for (int src = 0, dst = 0 ; src < nPixHalf ; ++src) + // Parallel mode - read pixels from each half sensor concurrently. + // Divide 'n' (the output pixel count) by 2 to get the loop count, + // since we're going to do 2 pixels on each iteration. + for (n /= 2, dst = 0 ; dst < n ; ++dst) { - // 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); + // Take the clock high. The TSL1410R will connect the next + // pixel pair's hold capacitors to the A01 and AO2 lines + // (respectively) on the clock rising edge. + *clockPSOR = clockMask; + + // Start the ADC sampler for AO1. The TSL1410R sample + // stabilization time per the data sheet is 120ns. This is + // fast enough that we don't need an explicit delay, since + // the instructions to execute this call will take longer + // than that. + ao1.start(); - // read the pixels + // take the clock low while we're waiting for the reading + *clockPCOR = clockMask; + + // Read the first half-sensor pixel from AO1 pix[dst] = ao1.read_u16(); - pix[dst+n/2] = ao2.read_u16(); - // turn off the ADC until the next pixel is clocked out - ao1.disable(); - ao2.disable(); + // Read the second half-sensor pixel from AO2, and store it + // in the destination array at the current index PLUS 'n', + // which you will recall contains half the output pixel count. + // This second pixel is halfway up the sensor from the first + // pixel, so it goes halfway up the output array from the + // current output position. + ao2.start(); + pix[dst + n] = ao2.read_u16(); - // clock skipped pixels - for (int i = 0 ; i < skip ; ++i, ++src) + // Clock through the skipped pixels + for (int i = skip ; i > 0 ; --i) { - clockPort->PSOR |= clockMask; - clockPort->PCOR |= clockMask; + *clockPSOR = clockMask; + *clockPCOR = clockMask; } } } else { // serial mode - read all pixels in a single file - for (int src = 0, dst = 0 ; src < nPix ; ++src) + for (dst = 0 ; dst < n ; ++dst) { - // pulse the clock and start the ADC sampling - clockPort->PSOR |= clockMask; - ao1.enable(); - wait_us(1); - clockPort->PCOR |= clockMask; + // Clock the next pixel onto the sensor A0 line + *clockPSOR = clockMask; - // wait for the ADC sample to stabilize - wait_us(11); + // start the ADC sampler + ao1.start(); - // read the ADC sample - pix[dst++] = ao1.read_u16(); - - // turn off the ADC until the next pixel is ready - ao1.disable(); + // take the clock low while we're waiting for the analog reading + *clockPCOR = clockMask; - // clock skipped pixels - for (int i = 0 ; i < skip ; ++i, ++src) + // wait for and read the ADC sample; plug it into the output + // array, and increment the output pointer to the next position + pix[dst] = ao1.read_u16(); + + // clock through the skipped pixels + for (int i = skip ; i > 0 ; --i) { - clockPort->PSOR |= clockMask; - clockPort->PCOR |= clockMask; + *clockPSOR = clockMask; + *clockPCOR = clockMask; } } } +//$$$ +if (done==1) printf(". done: dst=%d\r\n", dst); + // clock out one extra pixel to leave A1 in the high-Z state - clockPort->PSOR |= clockMask; - clockPort->PCOR |= clockMask; + clock = 1; + clock = 0; + + if (n >= 80) { totalTime += t.read(); nRuns += 1; } // $$$ } // Clock through all pixels to clear the array. Pulses SI at the @@ -184,29 +206,29 @@ // clock in an SI pulse si = 1; - clockPort->PSOR |= clockMask; + clockPort->PSOR = clockMask; si = 0; - clockPort->PCOR |= clockMask; + clockPort->PCOR = clockMask; // if in serial mode, clock all pixels across both sensor halves; // in parallel mode, the pixels are clocked together - int n = parallel ? nPix/2 : nPix; + int n = parallel ? nPixSensor/2 : nPixSensor; // clock out all pixels for (int i = 0 ; i < n + 1 ; ++i) { - clockPort->PSOR |= clockMask; - clockPort->PCOR |= clockMask; + clock = 1; // $$$clockPort->PSOR = clockMask; + clock = 0; // $$$clockPort->PCOR = clockMask; } } private: - int nPix; // number of pixels in physical sensor array + int nPixSensor; // number of pixels in physical sensor array DigitalOut si; // GPIO pin for sensor SI (serial data) DigitalOut clock; // GPIO pin for sensor SCLK (serial clock) FGPIO_Type *clockPort; // IOPORT base address for clock pin - cached for fast writes uint32_t clockMask; // IOPORT register bit mask for clock pin - FastAnalogIn ao1; // GPIO pin for sensor AO1 (analog output 1) - we read sensor data from this pin - FastAnalogIn ao2; // GPIO pin for sensor AO2 (analog output 2) - 2nd sensor data pin, when in parallel mode + AltAnalogIn ao1; // GPIO pin for sensor AO1 (analog output 1) - we read sensor data from this pin + AltAnalogIn ao2; // GPIO pin for sensor AO2 (analog output 2) - 2nd sensor data pin, when in parallel mode bool parallel; // true -> running in parallel mode (we read AO1 and AO2 separately on each clock) };