Mike R / Mbed 2 deprecated Pinscape_Controller_V2

Dependencies:   mbed FastIO FastPWM USBDevice

Fork of Pinscape_Controller by Mike R

Committer:
mjr
Date:
Mon Feb 15 20:30:32 2016 +0000
Revision:
45:c42166b2878c
Parent:
43:7a6364d82a41
Child:
47:df7a88cd249c
More work in progress on CCD speedups;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 45:c42166b2878c 1 // DMA VERSION - NOT WORKING
mjr 45:c42166b2878c 2
mjr 45:c42166b2878c 3 // I'm saving this code for now, since it was somewhat promising but doesn't
mjr 45:c42166b2878c 4 // quite work. The idea here was to read the ADC via DMA, operating the ADC
mjr 45:c42166b2878c 5 // in continuous mode. This speeds things up pretty impressively (by about
mjr 45:c42166b2878c 6 // a factor of 3 vs having the MCU read each result from the ADC sampling
mjr 45:c42166b2878c 7 // register), but I can't figure out how to get a stable enough signal out of
mjr 45:c42166b2878c 8 // it. I think the problem is that the timing isn't precise enough in detecting
mjr 45:c42166b2878c 9 // when the DMA completes each write. We have to clock the next pixel onto the
mjr 45:c42166b2878c 10 // CCD output each time we complete a sample, and we have to do so quickly so
mjr 45:c42166b2878c 11 // that the next pixel charge is stable at the ADC input pin by the time the
mjr 45:c42166b2878c 12 // ADC sample interval starts. I'm seeing a ton of noise, which I think means
mjr 45:c42166b2878c 13 // that the new pixel isn't ready for the ADC in time.
mjr 45:c42166b2878c 14 //
mjr 45:c42166b2878c 15 // I've tried a number of approaches, none of which works:
mjr 45:c42166b2878c 16 //
mjr 45:c42166b2878c 17 // - Skip every other sample, so that we can spend one whole sample just
mjr 45:c42166b2878c 18 // clocking in the next pixel. We discard the "odds" samples that are taken
mjr 45:c42166b2878c 19 // during pixel changes, and use only the "even" samples where the pixel is
mjr 45:c42166b2878c 20 // stable the entire time. I'd think the extra sample would give us plenty
mjr 45:c42166b2878c 21 // of time to stabilize the next pixel, but it doesn't seem to work out that
mjr 45:c42166b2878c 22 // way. I think the problem might be that the latency of the MCU responding
mjr 45:c42166b2878c 23 // to each sample completion is long enough relative to the sampling interval
mjr 45:c42166b2878c 24 // that we can't reliably respond to the ADC done condition fast enough. I've
mjr 45:c42166b2878c 25 // tried basing the sample completion detection on the DMA byte counter and
mjr 45:c42166b2878c 26 // the ADC interrupt. The DMA byte counter is updated after the DMA transfer
mjr 45:c42166b2878c 27 // is done, so that's probably just too late in the cycle. The ADC interrupt
mjr 45:c42166b2878c 28 // should be concurrent with the DMA transfer starting, but in practice it
mjr 45:c42166b2878c 29 // still doesn't give us good results.
mjr 45:c42166b2878c 30 //
mjr 45:c42166b2878c 31 // - Use DMA, but with the ADC in single-sample mode. This bypasses the latency
mjr 45:c42166b2878c 32 // problem by ensuring that the ADC doesn't start a new sample until we've
mjr 45:c42166b2878c 33 // definitely finished clocking in the next pixel. But it defeats the whole
mjr 45:c42166b2878c 34 // purpose by eliminating the speed improvement - the speeds are comparable to
mjr 45:c42166b2878c 35 // doing the transfers via the MCU. This surprises me because I'd have expected
mjr 45:c42166b2878c 36 // that the DMA would run concurrently with the MCU pixel clocking code, but
mjr 45:c42166b2878c 37 // maybe there's enough bus contention between the MCU and DMA in this case that
mjr 45:c42166b2878c 38 // there's no true overlapping of the operation. Or maybe the interrupt dispatch
mjr 45:c42166b2878c 39 // adds enough overhead to negate any overlapping. I haven't actually been able
mjr 45:c42166b2878c 40 // to get good data out of this mode, either, but I gave up early because of the
mjr 45:c42166b2878c 41 // lack of any speed improvement.
mjr 45:c42166b2878c 42
mjr 2:c174f9ee414a 43 /*
mjr 2:c174f9ee414a 44 * TSL1410R interface class.
mjr 2:c174f9ee414a 45 *
mjr 2:c174f9ee414a 46 * This provides a high-level interface for the Taos TSL1410R linear CCD array sensor.
mjr 2:c174f9ee414a 47 */
mjr 2:c174f9ee414a 48
mjr 35:e959ffba78fd 49 #include "mbed.h"
mjr 35:e959ffba78fd 50 #include "config.h"
mjr 43:7a6364d82a41 51 #include "AltAnalogIn.h"
mjr 45:c42166b2878c 52 #include "SimpleDMA.h"
mjr 2:c174f9ee414a 53
mjr 35:e959ffba78fd 54 #ifndef TSL1410R_H
mjr 35:e959ffba78fd 55 #define TSL1410R_H
mjr 45:c42166b2878c 56 #define TSL1410R_DMA
mjr 35:e959ffba78fd 57
mjr 35:e959ffba78fd 58 // For faster GPIO on the clock pin, we write the IOPORT registers directly.
mjr 35:e959ffba78fd 59 // PORT_BASE gives us the memory mapped location of the IOPORT register set
mjr 35:e959ffba78fd 60 // for a pin; PINMASK gives us the bit pattern to write to the registers.
mjr 35:e959ffba78fd 61 //
mjr 35:e959ffba78fd 62 // - To turn a pin ON: PORT_BASE(pin)->PSOR |= PINMASK(pin)
mjr 35:e959ffba78fd 63 // - To turn a pin OFF: PORT_BASE(pin)->PCOR |= PINMASK(pin)
mjr 35:e959ffba78fd 64 // - To toggle a pin: PORT_BASE(pin)->PTOR |= PINMASK(pin)
mjr 35:e959ffba78fd 65 //
mjr 35:e959ffba78fd 66 // When used in a loop where the port address and pin mask are cached in
mjr 35:e959ffba78fd 67 // local variables, this runs at the same speed as the FastIO library - about
mjr 35:e959ffba78fd 68 // 78ns per pin write on the KL25Z. Not surprising since it's doing the same
mjr 35:e959ffba78fd 69 // thing, and the compiler should be able to reduce a pin write to a single ARM
mjr 35:e959ffba78fd 70 // instruction when the port address and mask are in local register variables.
mjr 35:e959ffba78fd 71 // The advantage over the FastIO library is that this approach allows for pins
mjr 35:e959ffba78fd 72 // to be assigned dynamically at run-time, which we prefer because it allows for
mjr 35:e959ffba78fd 73 // configuration changes to be made on the fly rather than having to recompile
mjr 35:e959ffba78fd 74 // the program.
mjr 43:7a6364d82a41 75 #define GPIO_PORT(pin) (((unsigned int)(pin)) >> PORT_SHIFT)
mjr 43:7a6364d82a41 76 #define GPIO_PORT_BASE(pin) ((FGPIO_Type *)(FPTA_BASE + GPIO_PORT(pin) * 0x40))
mjr 43:7a6364d82a41 77 #define GPIO_PINMASK(pin) gpio_set(pin)
mjr 2:c174f9ee414a 78
mjr 35:e959ffba78fd 79 class TSL1410R
mjr 2:c174f9ee414a 80 {
mjr 2:c174f9ee414a 81 public:
mjr 43:7a6364d82a41 82 TSL1410R(int nPixSensor, PinName siPin, PinName clockPin, PinName ao1Pin, PinName ao2Pin)
mjr 43:7a6364d82a41 83 : nPixSensor(nPixSensor), si(siPin), clock(clockPin), ao1(ao1Pin), ao2(ao2Pin)
mjr 17:ab3cec0c8bf4 84 {
mjr 35:e959ffba78fd 85 // we're in parallel mode if ao2 is a valid pin
mjr 35:e959ffba78fd 86 parallel = (ao2Pin != NC);
mjr 35:e959ffba78fd 87
mjr 35:e959ffba78fd 88 // remember the clock pin port base and pin mask for fast access
mjr 35:e959ffba78fd 89 clockPort = GPIO_PORT_BASE(clockPin);
mjr 35:e959ffba78fd 90 clockMask = GPIO_PINMASK(clockPin);
mjr 35:e959ffba78fd 91
mjr 43:7a6364d82a41 92 // clear out power-on random data by clocking through all pixels twice
mjr 17:ab3cec0c8bf4 93 clear();
mjr 17:ab3cec0c8bf4 94 clear();
mjr 43:7a6364d82a41 95
mjr 45:c42166b2878c 96 // set up our DMA channel for reading from our analog in pin
mjr 45:c42166b2878c 97 ao1.initDMA(&adc_dma);
mjr 45:c42166b2878c 98
mjr 45:c42166b2878c 99 // Set up our DMA channel for writing the sensor SCLK - we use the PTOR
mjr 45:c42166b2878c 100 // (toggle) register to flip the bit on each write. To pad the timing
mjr 45:c42166b2878c 101 // to the rate required by the CCD, do a no-op 0 write to PTOR after
mjr 45:c42166b2878c 102 // each toggle. This gives us a 16-byte buffer, which we can make
mjr 45:c42166b2878c 103 // circular in the DMA controller.
mjr 45:c42166b2878c 104 static const uint32_t clkseq[] = { clockMask, 0, clockMask, 0 };
mjr 45:c42166b2878c 105 clk_dma.destination(&clockPort->PTOR, false, 32);
mjr 45:c42166b2878c 106 clk_dma.source(clkseq, true, 32, 16); // set up our circular source buffer
mjr 45:c42166b2878c 107 clk_dma.trigger(Trigger_ADC0); // software trigger
mjr 45:c42166b2878c 108 clk_dma.setCycleSteal(false); // do the entire transfer on each trigger
mjr 45:c42166b2878c 109
mjr 43:7a6364d82a41 110 totalTime = 0.0; nRuns = 0; // $$$
mjr 17:ab3cec0c8bf4 111 }
mjr 43:7a6364d82a41 112
mjr 43:7a6364d82a41 113 float totalTime; int nRuns; // $$$
mjr 2:c174f9ee414a 114
mjr 45:c42166b2878c 115 // ADC interrupt handler - on each ADC event,
mjr 45:c42166b2878c 116 static TSL1410R *instance;
mjr 45:c42166b2878c 117 static void _aiIRQ() { }
mjr 45:c42166b2878c 118
mjr 17:ab3cec0c8bf4 119 // Read the pixels.
mjr 17:ab3cec0c8bf4 120 //
mjr 17:ab3cec0c8bf4 121 // 'n' specifies the number of pixels to sample, and is the size of
mjr 17:ab3cec0c8bf4 122 // the output array 'pix'. This can be less than the full number
mjr 17:ab3cec0c8bf4 123 // of pixels on the physical device; if it is, we'll spread the
mjr 17:ab3cec0c8bf4 124 // sample evenly across the full length of the device by skipping
mjr 17:ab3cec0c8bf4 125 // one or more pixels between each sampled pixel to pad out the
mjr 17:ab3cec0c8bf4 126 // difference between the sample size and the physical CCD size.
mjr 17:ab3cec0c8bf4 127 // For example, if the physical sensor has 1280 pixels, and 'n' is
mjr 17:ab3cec0c8bf4 128 // 640, we'll read every other pixel and skip every other pixel.
mjr 17:ab3cec0c8bf4 129 // If 'n' is 160, we'll read every 8th pixel and skip 7 between
mjr 17:ab3cec0c8bf4 130 // each sample.
mjr 17:ab3cec0c8bf4 131 //
mjr 17:ab3cec0c8bf4 132 // The reason that we provide this subset mode (where 'n' is less
mjr 17:ab3cec0c8bf4 133 // than the physical pixel count) is that reading a pixel is the most
mjr 17:ab3cec0c8bf4 134 // time-consuming part of the scan. For each pixel we read, we have
mjr 17:ab3cec0c8bf4 135 // to wait for the pixel's charge to transfer from its internal smapling
mjr 17:ab3cec0c8bf4 136 // capacitor to the CCD's output pin, for that charge to transfer to
mjr 17:ab3cec0c8bf4 137 // the KL25Z input pin, and for the KL25Z ADC to get a stable reading.
mjr 17:ab3cec0c8bf4 138 // This all takes on the order of 20us per pixel. Skipping a pixel
mjr 17:ab3cec0c8bf4 139 // only requires a clock pulse, which takes about 350ns. So we can
mjr 17:ab3cec0c8bf4 140 // skip 60 pixels in the time it takes to sample 1 pixel.
mjr 2:c174f9ee414a 141 //
mjr 2:c174f9ee414a 142 // We clock an SI pulse at the beginning of the read. This starts the
mjr 2:c174f9ee414a 143 // next integration cycle: the pixel array will reset on the SI, and
mjr 17:ab3cec0c8bf4 144 // the integration starts 18 clocks later. So by the time this method
mjr 17:ab3cec0c8bf4 145 // returns, the next sample will have been integrating for npix-18 clocks.
mjr 17:ab3cec0c8bf4 146 // That's usually enough time to allow immediately reading the next
mjr 17:ab3cec0c8bf4 147 // sample. If more integration time is required, the caller can simply
mjr 2:c174f9ee414a 148 // sleep/spin for the desired additional time, or can do other work that
mjr 17:ab3cec0c8bf4 149 // takes the desired additional time.
mjr 2:c174f9ee414a 150 //
mjr 2:c174f9ee414a 151 // If the caller has other work to tend to that takes longer than the
mjr 2:c174f9ee414a 152 // desired maximum integration time, it can call clear() to clock out
mjr 2:c174f9ee414a 153 // the current pixels and start a fresh integration cycle.
mjr 43:7a6364d82a41 154 void read(register uint16_t *pix, int n)
mjr 17:ab3cec0c8bf4 155 {
mjr 45:c42166b2878c 156 Timer t; t.start(); //float tDMA, tPix; // $$$
mjr 43:7a6364d82a41 157
mjr 35:e959ffba78fd 158 // get the clock pin pointers into local variables for fast access
mjr 45:c42166b2878c 159 register volatile uint32_t *clockPTOR = &clockPort->PTOR;
mjr 43:7a6364d82a41 160 register const uint32_t clockMask = this->clockMask;
mjr 35:e959ffba78fd 161
mjr 17:ab3cec0c8bf4 162 // start the next integration cycle by pulsing SI and one clock
mjr 17:ab3cec0c8bf4 163 si = 1;
mjr 43:7a6364d82a41 164 clock = 1;
mjr 17:ab3cec0c8bf4 165 si = 0;
mjr 43:7a6364d82a41 166 clock = 0;
mjr 17:ab3cec0c8bf4 167
mjr 17:ab3cec0c8bf4 168 // figure how many pixels to skip on each read
mjr 43:7a6364d82a41 169 int skip = nPixSensor/n - 1;
mjr 17:ab3cec0c8bf4 170
mjr 43:7a6364d82a41 171 ///$$$
mjr 43:7a6364d82a41 172 static int done=0;
mjr 43:7a6364d82a41 173 if (done++ == 0) printf("nPixSensor=%d, n=%d, skip=%d, parallel=%d\r\n", nPixSensor, n, skip, parallel);
mjr 43:7a6364d82a41 174
mjr 17:ab3cec0c8bf4 175 // read all of the pixels
mjr 43:7a6364d82a41 176 int dst;
mjr 35:e959ffba78fd 177 if (parallel)
mjr 17:ab3cec0c8bf4 178 {
mjr 43:7a6364d82a41 179 // Parallel mode - read pixels from each half sensor concurrently.
mjr 43:7a6364d82a41 180 // Divide 'n' (the output pixel count) by 2 to get the loop count,
mjr 43:7a6364d82a41 181 // since we're going to do 2 pixels on each iteration.
mjr 43:7a6364d82a41 182 for (n /= 2, dst = 0 ; dst < n ; ++dst)
mjr 17:ab3cec0c8bf4 183 {
mjr 43:7a6364d82a41 184 // Take the clock high. The TSL1410R will connect the next
mjr 43:7a6364d82a41 185 // pixel pair's hold capacitors to the A01 and AO2 lines
mjr 43:7a6364d82a41 186 // (respectively) on the clock rising edge.
mjr 45:c42166b2878c 187 *clockPTOR = clockMask;
mjr 43:7a6364d82a41 188
mjr 43:7a6364d82a41 189 // Start the ADC sampler for AO1. The TSL1410R sample
mjr 43:7a6364d82a41 190 // stabilization time per the data sheet is 120ns. This is
mjr 43:7a6364d82a41 191 // fast enough that we don't need an explicit delay, since
mjr 43:7a6364d82a41 192 // the instructions to execute this call will take longer
mjr 43:7a6364d82a41 193 // than that.
mjr 43:7a6364d82a41 194 ao1.start();
mjr 35:e959ffba78fd 195
mjr 43:7a6364d82a41 196 // take the clock low while we're waiting for the reading
mjr 45:c42166b2878c 197 *clockPTOR = clockMask;
mjr 43:7a6364d82a41 198
mjr 43:7a6364d82a41 199 // Read the first half-sensor pixel from AO1
mjr 35:e959ffba78fd 200 pix[dst] = ao1.read_u16();
mjr 35:e959ffba78fd 201
mjr 43:7a6364d82a41 202 // Read the second half-sensor pixel from AO2, and store it
mjr 43:7a6364d82a41 203 // in the destination array at the current index PLUS 'n',
mjr 43:7a6364d82a41 204 // which you will recall contains half the output pixel count.
mjr 43:7a6364d82a41 205 // This second pixel is halfway up the sensor from the first
mjr 43:7a6364d82a41 206 // pixel, so it goes halfway up the output array from the
mjr 43:7a6364d82a41 207 // current output position.
mjr 43:7a6364d82a41 208 ao2.start();
mjr 43:7a6364d82a41 209 pix[dst + n] = ao2.read_u16();
mjr 35:e959ffba78fd 210
mjr 43:7a6364d82a41 211 // Clock through the skipped pixels
mjr 43:7a6364d82a41 212 for (int i = skip ; i > 0 ; --i)
mjr 35:e959ffba78fd 213 {
mjr 45:c42166b2878c 214 *clockPTOR = clockMask;
mjr 45:c42166b2878c 215 *clockPTOR = clockMask;
mjr 45:c42166b2878c 216 *clockPTOR = 0; // pad the timing with an extra nop write
mjr 35:e959ffba78fd 217 }
mjr 35:e959ffba78fd 218 }
mjr 35:e959ffba78fd 219 }
mjr 35:e959ffba78fd 220 else
mjr 35:e959ffba78fd 221 {
mjr 35:e959ffba78fd 222 // serial mode - read all pixels in a single file
mjr 45:c42166b2878c 223
mjr 45:c42166b2878c 224 // clock in the first pixel
mjr 45:c42166b2878c 225 clock = 1;
mjr 45:c42166b2878c 226 clock = 0;
mjr 45:c42166b2878c 227
mjr 45:c42166b2878c 228 // start the ADC DMA transfer
mjr 45:c42166b2878c 229 ao1.startDMA(pix, n, true);
mjr 45:c42166b2878c 230
mjr 45:c42166b2878c 231 // We do 4 clock PTOR writes per clocked pixel (the skipped pixels
mjr 45:c42166b2878c 232 // plus the pixel we actually want to sample), at 32 bits (4 bytes)
mjr 45:c42166b2878c 233 // each, giving 16 bytes per pixel for the overall write.
mjr 45:c42166b2878c 234 int clk_dma_len = (skip+1)*16;
mjr 45:c42166b2878c 235 clk_dma.start(clk_dma_len);
mjr 45:c42166b2878c 236
mjr 45:c42166b2878c 237 // start the first sample
mjr 45:c42166b2878c 238 ao1.start();
mjr 45:c42166b2878c 239
mjr 45:c42166b2878c 240 // read all pixels
mjr 45:c42166b2878c 241 for (dst = n*2 ; dst > 0 ; dst -= 2)
mjr 35:e959ffba78fd 242 {
mjr 45:c42166b2878c 243 // wait for the current ADC sample to finish
mjr 45:c42166b2878c 244 while (adc_dma.remaining() >= dst) { }
mjr 35:e959ffba78fd 245
mjr 45:c42166b2878c 246 // start the next analog read while we're finishing the DMA transfers
mjr 43:7a6364d82a41 247 ao1.start();
mjr 35:e959ffba78fd 248
mjr 45:c42166b2878c 249 // re-arm the clock DMA
mjr 45:c42166b2878c 250 //clk_dma.restart(clk_dma_len);
mjr 17:ab3cec0c8bf4 251 }
mjr 45:c42166b2878c 252
mjr 45:c42166b2878c 253 // wait for the DMA transfer to finish
mjr 45:c42166b2878c 254 while (adc_dma.isBusy()) { }
mjr 45:c42166b2878c 255
mjr 45:c42166b2878c 256 // apply the 12-bit to 16-bit rescaling to all values
mjr 45:c42166b2878c 257 for (int i = 0 ; i < n ; ++i)
mjr 45:c42166b2878c 258 pix[i] <<= 4;
mjr 17:ab3cec0c8bf4 259 }
mjr 17:ab3cec0c8bf4 260
mjr 43:7a6364d82a41 261 //$$$
mjr 43:7a6364d82a41 262 if (done==1) printf(". done: dst=%d\r\n", dst);
mjr 43:7a6364d82a41 263
mjr 17:ab3cec0c8bf4 264 // clock out one extra pixel to leave A1 in the high-Z state
mjr 45:c42166b2878c 265 *clockPTOR = clockMask;
mjr 45:c42166b2878c 266 *clockPTOR = clockMask;
mjr 43:7a6364d82a41 267
mjr 45:c42166b2878c 268 if (n >= 64) { totalTime += t.read(); nRuns += 1; } // $$$
mjr 17:ab3cec0c8bf4 269 }
mjr 2:c174f9ee414a 270
mjr 2:c174f9ee414a 271 // Clock through all pixels to clear the array. Pulses SI at the
mjr 2:c174f9ee414a 272 // beginning of the operation, which starts a new integration cycle.
mjr 2:c174f9ee414a 273 // The caller can thus immediately call read() to read the pixels
mjr 2:c174f9ee414a 274 // integrated while the clear() was taking place.
mjr 17:ab3cec0c8bf4 275 void clear()
mjr 17:ab3cec0c8bf4 276 {
mjr 35:e959ffba78fd 277 // get the clock pin pointers into local variables for fast access
mjr 35:e959ffba78fd 278 register FGPIO_Type *clockPort = this->clockPort;
mjr 35:e959ffba78fd 279 register uint32_t clockMask = this->clockMask;
mjr 35:e959ffba78fd 280
mjr 17:ab3cec0c8bf4 281 // clock in an SI pulse
mjr 17:ab3cec0c8bf4 282 si = 1;
mjr 43:7a6364d82a41 283 clockPort->PSOR = clockMask;
mjr 17:ab3cec0c8bf4 284 si = 0;
mjr 43:7a6364d82a41 285 clockPort->PCOR = clockMask;
mjr 17:ab3cec0c8bf4 286
mjr 40:cc0d9814522b 287 // if in serial mode, clock all pixels across both sensor halves;
mjr 40:cc0d9814522b 288 // in parallel mode, the pixels are clocked together
mjr 43:7a6364d82a41 289 int n = parallel ? nPixSensor/2 : nPixSensor;
mjr 40:cc0d9814522b 290
mjr 17:ab3cec0c8bf4 291 // clock out all pixels
mjr 40:cc0d9814522b 292 for (int i = 0 ; i < n + 1 ; ++i) {
mjr 43:7a6364d82a41 293 clock = 1; // $$$clockPort->PSOR = clockMask;
mjr 43:7a6364d82a41 294 clock = 0; // $$$clockPort->PCOR = clockMask;
mjr 17:ab3cec0c8bf4 295 }
mjr 17:ab3cec0c8bf4 296 }
mjr 2:c174f9ee414a 297
mjr 2:c174f9ee414a 298 private:
mjr 45:c42166b2878c 299 SimpleDMA adc_dma; // DMA controller for reading the analog input
mjr 45:c42166b2878c 300 SimpleDMA clk_dma; // DMA controller for the sensor SCLK (writes the PTOR register to toggle the clock bit)
mjr 45:c42166b2878c 301 char *dmabuf; // buffer for DMA transfers
mjr 43:7a6364d82a41 302 int nPixSensor; // number of pixels in physical sensor array
mjr 40:cc0d9814522b 303 DigitalOut si; // GPIO pin for sensor SI (serial data)
mjr 40:cc0d9814522b 304 DigitalOut clock; // GPIO pin for sensor SCLK (serial clock)
mjr 40:cc0d9814522b 305 FGPIO_Type *clockPort; // IOPORT base address for clock pin - cached for fast writes
mjr 35:e959ffba78fd 306 uint32_t clockMask; // IOPORT register bit mask for clock pin
mjr 43:7a6364d82a41 307 AltAnalogIn ao1; // GPIO pin for sensor AO1 (analog output 1) - we read sensor data from this pin
mjr 43:7a6364d82a41 308 AltAnalogIn ao2; // GPIO pin for sensor AO2 (analog output 2) - 2nd sensor data pin, when in parallel mode
mjr 40:cc0d9814522b 309 bool parallel; // true -> running in parallel mode (we read AO1 and AO2 separately on each clock)
mjr 2:c174f9ee414a 310 };
mjr 2:c174f9ee414a 311
mjr 2:c174f9ee414a 312 #endif /* TSL1410R_H */
mjr 45:c42166b2878c 313