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
TSL1410R/tsl1410r.h@25:e22b88bd783a, 2015-09-01 (annotated)
- Committer:
- mjr
- Date:
- Tue Sep 01 04:27:15 2015 +0000
- Revision:
- 25:e22b88bd783a
- Parent:
- 18:5e890ebd0023
- Child:
- 35:e959ffba78fd
Centralized the CCD pixel count setting to a single config.h option; added an option to config.h to select the board's mounting orientation for the accelerometer
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 2:c174f9ee414a | 1 | /* |
mjr | 2:c174f9ee414a | 2 | * TSL1410R interface class. |
mjr | 2:c174f9ee414a | 3 | * |
mjr | 2:c174f9ee414a | 4 | * This provides a high-level interface for the Taos TSL1410R linear CCD array sensor. |
mjr | 2:c174f9ee414a | 5 | */ |
mjr | 2:c174f9ee414a | 6 | |
mjr | 2:c174f9ee414a | 7 | #include "mbed.h" |
mjr | 25:e22b88bd783a | 8 | #include "config.h" |
mjr | 17:ab3cec0c8bf4 | 9 | #include "FastIO.h" |
mjr | 17:ab3cec0c8bf4 | 10 | #include "FastAnalogIn.h" |
mjr | 2:c174f9ee414a | 11 | |
mjr | 2:c174f9ee414a | 12 | #ifndef TSL1410R_H |
mjr | 2:c174f9ee414a | 13 | #define TSL1410R_H |
mjr | 2:c174f9ee414a | 14 | |
mjr | 17:ab3cec0c8bf4 | 15 | template <PinName siPin, PinName clockPin> class TSL1410R |
mjr | 2:c174f9ee414a | 16 | { |
mjr | 2:c174f9ee414a | 17 | public: |
mjr | 17:ab3cec0c8bf4 | 18 | // set up the analog in port for reading the currently selected |
mjr | 17:ab3cec0c8bf4 | 19 | // pixel value |
mjr | 17:ab3cec0c8bf4 | 20 | TSL1410R(PinName aoPin) : ao(aoPin) |
mjr | 17:ab3cec0c8bf4 | 21 | { |
mjr | 17:ab3cec0c8bf4 | 22 | // disable continuous conversion mode in FastAnalogIn - since we're |
mjr | 17:ab3cec0c8bf4 | 23 | // reading discrete pixel values, we want to control when the samples |
mjr | 17:ab3cec0c8bf4 | 24 | // are taken rather than continuously averaging over time |
mjr | 17:ab3cec0c8bf4 | 25 | ao.disable(); |
mjr | 17:ab3cec0c8bf4 | 26 | |
mjr | 17:ab3cec0c8bf4 | 27 | // clear out power-on noise by clocking through all pixels twice |
mjr | 17:ab3cec0c8bf4 | 28 | clear(); |
mjr | 17:ab3cec0c8bf4 | 29 | clear(); |
mjr | 17:ab3cec0c8bf4 | 30 | } |
mjr | 2:c174f9ee414a | 31 | |
mjr | 17:ab3cec0c8bf4 | 32 | // Read the pixels. |
mjr | 17:ab3cec0c8bf4 | 33 | // |
mjr | 17:ab3cec0c8bf4 | 34 | // 'n' specifies the number of pixels to sample, and is the size of |
mjr | 17:ab3cec0c8bf4 | 35 | // the output array 'pix'. This can be less than the full number |
mjr | 17:ab3cec0c8bf4 | 36 | // of pixels on the physical device; if it is, we'll spread the |
mjr | 17:ab3cec0c8bf4 | 37 | // sample evenly across the full length of the device by skipping |
mjr | 17:ab3cec0c8bf4 | 38 | // one or more pixels between each sampled pixel to pad out the |
mjr | 17:ab3cec0c8bf4 | 39 | // difference between the sample size and the physical CCD size. |
mjr | 17:ab3cec0c8bf4 | 40 | // For example, if the physical sensor has 1280 pixels, and 'n' is |
mjr | 17:ab3cec0c8bf4 | 41 | // 640, we'll read every other pixel and skip every other pixel. |
mjr | 17:ab3cec0c8bf4 | 42 | // If 'n' is 160, we'll read every 8th pixel and skip 7 between |
mjr | 17:ab3cec0c8bf4 | 43 | // each sample. |
mjr | 17:ab3cec0c8bf4 | 44 | // |
mjr | 17:ab3cec0c8bf4 | 45 | // The reason that we provide this subset mode (where 'n' is less |
mjr | 17:ab3cec0c8bf4 | 46 | // than the physical pixel count) is that reading a pixel is the most |
mjr | 17:ab3cec0c8bf4 | 47 | // time-consuming part of the scan. For each pixel we read, we have |
mjr | 17:ab3cec0c8bf4 | 48 | // to wait for the pixel's charge to transfer from its internal smapling |
mjr | 17:ab3cec0c8bf4 | 49 | // capacitor to the CCD's output pin, for that charge to transfer to |
mjr | 17:ab3cec0c8bf4 | 50 | // the KL25Z input pin, and for the KL25Z ADC to get a stable reading. |
mjr | 17:ab3cec0c8bf4 | 51 | // This all takes on the order of 20us per pixel. Skipping a pixel |
mjr | 17:ab3cec0c8bf4 | 52 | // only requires a clock pulse, which takes about 350ns. So we can |
mjr | 17:ab3cec0c8bf4 | 53 | // skip 60 pixels in the time it takes to sample 1 pixel. |
mjr | 2:c174f9ee414a | 54 | // |
mjr | 2:c174f9ee414a | 55 | // We clock an SI pulse at the beginning of the read. This starts the |
mjr | 2:c174f9ee414a | 56 | // next integration cycle: the pixel array will reset on the SI, and |
mjr | 17:ab3cec0c8bf4 | 57 | // the integration starts 18 clocks later. So by the time this method |
mjr | 17:ab3cec0c8bf4 | 58 | // returns, the next sample will have been integrating for npix-18 clocks. |
mjr | 17:ab3cec0c8bf4 | 59 | // That's usually enough time to allow immediately reading the next |
mjr | 17:ab3cec0c8bf4 | 60 | // sample. If more integration time is required, the caller can simply |
mjr | 2:c174f9ee414a | 61 | // sleep/spin for the desired additional time, or can do other work that |
mjr | 17:ab3cec0c8bf4 | 62 | // takes the desired additional time. |
mjr | 2:c174f9ee414a | 63 | // |
mjr | 2:c174f9ee414a | 64 | // If the caller has other work to tend to that takes longer than the |
mjr | 2:c174f9ee414a | 65 | // desired maximum integration time, it can call clear() to clock out |
mjr | 2:c174f9ee414a | 66 | // the current pixels and start a fresh integration cycle. |
mjr | 18:5e890ebd0023 | 67 | void read(uint16_t *pix, int n) |
mjr | 17:ab3cec0c8bf4 | 68 | { |
mjr | 17:ab3cec0c8bf4 | 69 | // start the next integration cycle by pulsing SI and one clock |
mjr | 17:ab3cec0c8bf4 | 70 | si = 1; |
mjr | 17:ab3cec0c8bf4 | 71 | clock = 1; |
mjr | 17:ab3cec0c8bf4 | 72 | si = 0; |
mjr | 17:ab3cec0c8bf4 | 73 | clock = 0; |
mjr | 17:ab3cec0c8bf4 | 74 | |
mjr | 17:ab3cec0c8bf4 | 75 | // figure how many pixels to skip on each read |
mjr | 17:ab3cec0c8bf4 | 76 | int skip = nPix/n - 1; |
mjr | 17:ab3cec0c8bf4 | 77 | |
mjr | 17:ab3cec0c8bf4 | 78 | // read all of the pixels |
mjr | 18:5e890ebd0023 | 79 | for (int src = 0, dst = 0 ; src < nPix ; ++src) |
mjr | 17:ab3cec0c8bf4 | 80 | { |
mjr | 18:5e890ebd0023 | 81 | // clock in and read the next pixel |
mjr | 18:5e890ebd0023 | 82 | clock = 1; |
mjr | 18:5e890ebd0023 | 83 | ao.enable(); |
mjr | 18:5e890ebd0023 | 84 | wait_us(1); |
mjr | 18:5e890ebd0023 | 85 | clock = 0; |
mjr | 18:5e890ebd0023 | 86 | wait_us(11); |
mjr | 18:5e890ebd0023 | 87 | pix[dst++] = ao.read_u16(); |
mjr | 18:5e890ebd0023 | 88 | ao.disable(); |
mjr | 18:5e890ebd0023 | 89 | |
mjr | 18:5e890ebd0023 | 90 | // clock skipped pixels |
mjr | 18:5e890ebd0023 | 91 | for (int i = 0 ; i < skip ; ++i, ++src) |
mjr | 17:ab3cec0c8bf4 | 92 | { |
mjr | 17:ab3cec0c8bf4 | 93 | clock = 1; |
mjr | 17:ab3cec0c8bf4 | 94 | clock = 0; |
mjr | 17:ab3cec0c8bf4 | 95 | } |
mjr | 17:ab3cec0c8bf4 | 96 | } |
mjr | 17:ab3cec0c8bf4 | 97 | |
mjr | 17:ab3cec0c8bf4 | 98 | // clock out one extra pixel to leave A1 in the high-Z state |
mjr | 17:ab3cec0c8bf4 | 99 | clock = 1; |
mjr | 17:ab3cec0c8bf4 | 100 | clock = 0; |
mjr | 17:ab3cec0c8bf4 | 101 | } |
mjr | 2:c174f9ee414a | 102 | |
mjr | 2:c174f9ee414a | 103 | // Clock through all pixels to clear the array. Pulses SI at the |
mjr | 2:c174f9ee414a | 104 | // beginning of the operation, which starts a new integration cycle. |
mjr | 2:c174f9ee414a | 105 | // The caller can thus immediately call read() to read the pixels |
mjr | 2:c174f9ee414a | 106 | // integrated while the clear() was taking place. |
mjr | 17:ab3cec0c8bf4 | 107 | void clear() |
mjr | 17:ab3cec0c8bf4 | 108 | { |
mjr | 17:ab3cec0c8bf4 | 109 | // clock in an SI pulse |
mjr | 17:ab3cec0c8bf4 | 110 | si = 1; |
mjr | 17:ab3cec0c8bf4 | 111 | clock = 1; |
mjr | 17:ab3cec0c8bf4 | 112 | clock = 0; |
mjr | 17:ab3cec0c8bf4 | 113 | si = 0; |
mjr | 17:ab3cec0c8bf4 | 114 | |
mjr | 17:ab3cec0c8bf4 | 115 | // clock out all pixels |
mjr | 17:ab3cec0c8bf4 | 116 | for (int i = 0 ; i < nPix + 1 ; ++i) { |
mjr | 17:ab3cec0c8bf4 | 117 | clock = 1; |
mjr | 17:ab3cec0c8bf4 | 118 | clock = 0; |
mjr | 17:ab3cec0c8bf4 | 119 | } |
mjr | 17:ab3cec0c8bf4 | 120 | } |
mjr | 2:c174f9ee414a | 121 | |
mjr | 2:c174f9ee414a | 122 | // number of pixels in the array |
mjr | 25:e22b88bd783a | 123 | static const int nPix = CCD_NPIXELS; |
mjr | 2:c174f9ee414a | 124 | |
mjr | 2:c174f9ee414a | 125 | |
mjr | 2:c174f9ee414a | 126 | private: |
mjr | 17:ab3cec0c8bf4 | 127 | FastOut<siPin> si; |
mjr | 17:ab3cec0c8bf4 | 128 | FastOut<clockPin> clock; |
mjr | 17:ab3cec0c8bf4 | 129 | FastAnalogIn ao; |
mjr | 2:c174f9ee414a | 130 | }; |
mjr | 2:c174f9ee414a | 131 | |
mjr | 2:c174f9ee414a | 132 | #endif /* TSL1410R_H */ |