Mirror with some correction
Dependencies: mbed FastIO FastPWM USBDevice
AltAnalogIn/AltAnalogIn.h@48:058ace2aed1d, 2016-02-26 (annotated)
- Committer:
- mjr
- Date:
- Fri Feb 26 18:42:03 2016 +0000
- Revision:
- 48:058ace2aed1d
- Parent:
- 47:df7a88cd249c
- Child:
- 100:1ff35c07217c
New plunger processing 1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mjr | 43:7a6364d82a41 | 1 | #ifndef ALTANALOGIN_H |
mjr | 43:7a6364d82a41 | 2 | #define ALTANALOGIN_H |
mjr | 43:7a6364d82a41 | 3 | |
mjr | 48:058ace2aed1d | 4 | // This is a modified version of Scissors's FastAnalogIn, customized |
mjr | 48:058ace2aed1d | 5 | // for the needs of the Pinscape TSL1410R reader. We use 8-bit samples |
mjr | 48:058ace2aed1d | 6 | // to save memory (since we need to collect 1280 or 1536 samples, |
mjr | 48:058ace2aed1d | 7 | // depending on the sensor subtype), and we use the fastest sampling |
mjr | 48:058ace2aed1d | 8 | // parameters (determined through testing). For maximum throughput, |
mjr | 48:058ace2aed1d | 9 | // we put the ADC in continuous mode and read samples with a DMA |
mjr | 48:058ace2aed1d | 10 | // channel. |
mjr | 48:058ace2aed1d | 11 | // |
mjr | 48:058ace2aed1d | 12 | // This modified version only works for the KL25Z. |
mjr | 43:7a6364d82a41 | 13 | // |
mjr | 48:058ace2aed1d | 14 | // Important! This class can't coexist in the same program with the |
mjr | 48:058ace2aed1d | 15 | // standard mbed library version of AnalogIn, or with the original |
mjr | 48:058ace2aed1d | 16 | // version of FastAnalogIn. All of these classes program the ADC |
mjr | 48:058ace2aed1d | 17 | // configuration registers with their own custom settings. These |
mjr | 48:058ace2aed1d | 18 | // registers are a global resource, and the different classes all |
mjr | 48:058ace2aed1d | 19 | // assume they have exclusive control, so they don't try to coordinate |
mjr | 48:058ace2aed1d | 20 | // with anyone else programming the registers. A program that uses |
mjr | 48:058ace2aed1d | 21 | // AltAnalogIn in one place will have to use AltAnalogIn exclusively |
mjr | 48:058ace2aed1d | 22 | // throughout the program for all ADC interaction. |
mjr | 43:7a6364d82a41 | 23 | |
mjr | 43:7a6364d82a41 | 24 | /* |
mjr | 43:7a6364d82a41 | 25 | * Includes |
mjr | 43:7a6364d82a41 | 26 | */ |
mjr | 43:7a6364d82a41 | 27 | #include "mbed.h" |
mjr | 43:7a6364d82a41 | 28 | #include "pinmap.h" |
mjr | 45:c42166b2878c | 29 | #include "SimpleDMA.h" |
mjr | 45:c42166b2878c | 30 | |
mjr | 45:c42166b2878c | 31 | // KL25Z definitions |
mjr | 45:c42166b2878c | 32 | #if defined TARGET_KLXX |
mjr | 45:c42166b2878c | 33 | |
mjr | 45:c42166b2878c | 34 | // Maximum ADC clock for KL25Z in 12-bit mode - 18 MHz per the data sheet |
mjr | 45:c42166b2878c | 35 | #define MAX_FADC_12BIT 18000000 |
mjr | 45:c42166b2878c | 36 | |
mjr | 45:c42166b2878c | 37 | #define CHANNELS_A_SHIFT 5 // bit position in ADC channel number of A/B mux |
mjr | 45:c42166b2878c | 38 | #define ADC_CFG1_ADLSMP 0x10 // long sample time mode |
mjr | 45:c42166b2878c | 39 | #define ADC_SC1_AIEN 0x40 // interrupt enable |
mjr | 45:c42166b2878c | 40 | #define ADC_SC2_ADLSTS(mode) (mode) // long sample time select - bits 1:0 of CFG2 |
mjr | 45:c42166b2878c | 41 | #define ADC_SC2_DMAEN 0x04 // DMA enable |
mjr | 45:c42166b2878c | 42 | #define ADC_SC3_CONTINUOUS 0x08 // continuous conversion mode |
mjr | 45:c42166b2878c | 43 | |
mjr | 47:df7a88cd249c | 44 | #define ADC_8BIT 0 // 8-bit resolution |
mjr | 47:df7a88cd249c | 45 | #define ADC_12BIT 1 // 12-bit resolution |
mjr | 47:df7a88cd249c | 46 | #define ADC_10BIT 2 // 10-bit resolution |
mjr | 47:df7a88cd249c | 47 | #define ADC_16BIT 3 // 16-bit resolution |
mjr | 47:df7a88cd249c | 48 | |
mjr | 45:c42166b2878c | 49 | #else |
mjr | 45:c42166b2878c | 50 | #error "This target is not currently supported" |
mjr | 45:c42166b2878c | 51 | #endif |
mjr | 43:7a6364d82a41 | 52 | |
mjr | 43:7a6364d82a41 | 53 | #if !defined TARGET_LPC1768 && !defined TARGET_KLXX && !defined TARGET_LPC408X && !defined TARGET_LPC11UXX && !defined TARGET_K20D5M |
mjr | 43:7a6364d82a41 | 54 | #error "Target not supported" |
mjr | 43:7a6364d82a41 | 55 | #endif |
mjr | 43:7a6364d82a41 | 56 | |
mjr | 48:058ace2aed1d | 57 | |
mjr | 43:7a6364d82a41 | 58 | class AltAnalogIn { |
mjr | 43:7a6364d82a41 | 59 | |
mjr | 43:7a6364d82a41 | 60 | public: |
mjr | 43:7a6364d82a41 | 61 | /** Create an AltAnalogIn, connected to the specified pin |
mjr | 43:7a6364d82a41 | 62 | * |
mjr | 43:7a6364d82a41 | 63 | * @param pin AnalogIn pin to connect to |
mjr | 43:7a6364d82a41 | 64 | * @param enabled Enable the ADC channel (default = true) |
mjr | 43:7a6364d82a41 | 65 | */ |
mjr | 45:c42166b2878c | 66 | AltAnalogIn(PinName pin, bool continuous = false); |
mjr | 43:7a6364d82a41 | 67 | |
mjr | 43:7a6364d82a41 | 68 | ~AltAnalogIn( void ) |
mjr | 43:7a6364d82a41 | 69 | { |
mjr | 43:7a6364d82a41 | 70 | } |
mjr | 43:7a6364d82a41 | 71 | |
mjr | 45:c42166b2878c | 72 | // Initialize DMA. This connects the analog in port to the |
mjr | 45:c42166b2878c | 73 | // given DMA object. |
mjr | 45:c42166b2878c | 74 | // |
mjr | 45:c42166b2878c | 75 | // DMA transfers from the analog in port often use continuous |
mjr | 45:c42166b2878c | 76 | // conversion mode. Note, however, that we don't automatically |
mjr | 45:c42166b2878c | 77 | // assume this - single sample mode is the default, which means |
mjr | 45:c42166b2878c | 78 | // that you must manually start each sample. If you want to use |
mjr | 45:c42166b2878c | 79 | // continuous mode, you need to set that separately (via the |
mjr | 45:c42166b2878c | 80 | // constructor). |
mjr | 45:c42166b2878c | 81 | void initDMA(SimpleDMA *dma); |
mjr | 45:c42166b2878c | 82 | |
mjr | 43:7a6364d82a41 | 83 | /** Start a sample. This sets the ADC multiplexer to read from |
mjr | 43:7a6364d82a41 | 84 | * this input and activates the sampler. |
mjr | 43:7a6364d82a41 | 85 | */ |
mjr | 43:7a6364d82a41 | 86 | inline void start() |
mjr | 43:7a6364d82a41 | 87 | { |
mjr | 43:7a6364d82a41 | 88 | // update the MUX bit in the CFG2 register only if necessary |
mjr | 43:7a6364d82a41 | 89 | static int lastMux = -1; |
mjr | 43:7a6364d82a41 | 90 | if (lastMux != ADCmux) |
mjr | 43:7a6364d82a41 | 91 | { |
mjr | 43:7a6364d82a41 | 92 | // remember the new register value |
mjr | 43:7a6364d82a41 | 93 | lastMux = ADCmux; |
mjr | 43:7a6364d82a41 | 94 | |
mjr | 43:7a6364d82a41 | 95 | // select the multiplexer for our ADC channel |
mjr | 43:7a6364d82a41 | 96 | if (ADCmux) |
mjr | 43:7a6364d82a41 | 97 | ADC0->CFG2 |= ADC_CFG2_MUXSEL_MASK; |
mjr | 43:7a6364d82a41 | 98 | else |
mjr | 43:7a6364d82a41 | 99 | ADC0->CFG2 &= ~ADC_CFG2_MUXSEL_MASK; |
mjr | 43:7a6364d82a41 | 100 | } |
mjr | 43:7a6364d82a41 | 101 | |
mjr | 45:c42166b2878c | 102 | // update the SC2 and SC3 bits only if we're changing inputs |
mjr | 45:c42166b2878c | 103 | static uint32_t lastid = 0; |
mjr | 45:c42166b2878c | 104 | if (id != lastid) |
mjr | 45:c42166b2878c | 105 | { |
mjr | 45:c42166b2878c | 106 | // set our ADC0 SC2 and SC3 configuration bits |
mjr | 45:c42166b2878c | 107 | ADC0->SC2 = sc2; |
mjr | 45:c42166b2878c | 108 | ADC0->SC3 = sc3; |
mjr | 45:c42166b2878c | 109 | |
mjr | 45:c42166b2878c | 110 | // we're the active one now |
mjr | 45:c42166b2878c | 111 | lastid = id; |
mjr | 45:c42166b2878c | 112 | } |
mjr | 45:c42166b2878c | 113 | |
mjr | 45:c42166b2878c | 114 | // set our SC1 bits - this initiates the sample |
mjr | 45:c42166b2878c | 115 | ADC0->SC1[0] = sc1; |
mjr | 43:7a6364d82a41 | 116 | } |
mjr | 43:7a6364d82a41 | 117 | |
mjr | 45:c42166b2878c | 118 | // stop sampling |
mjr | 45:c42166b2878c | 119 | void stop() |
mjr | 45:c42166b2878c | 120 | { |
mjr | 45:c42166b2878c | 121 | // set the channel bits to binary 11111 to disable sampling |
mjr | 45:c42166b2878c | 122 | ADC0->SC1[0] = 0x1F; |
mjr | 45:c42166b2878c | 123 | } |
mjr | 45:c42166b2878c | 124 | |
mjr | 45:c42166b2878c | 125 | // wait for the current sample to complete |
mjr | 45:c42166b2878c | 126 | inline void wait() |
mjr | 45:c42166b2878c | 127 | { |
mjr | 45:c42166b2878c | 128 | while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) == 0); |
mjr | 45:c42166b2878c | 129 | } |
mjr | 43:7a6364d82a41 | 130 | |
mjr | 43:7a6364d82a41 | 131 | |
mjr | 43:7a6364d82a41 | 132 | /** Returns the raw value |
mjr | 43:7a6364d82a41 | 133 | * |
mjr | 43:7a6364d82a41 | 134 | * @param return Unsigned integer with converted value |
mjr | 43:7a6364d82a41 | 135 | */ |
mjr | 43:7a6364d82a41 | 136 | inline uint16_t read_u16() |
mjr | 43:7a6364d82a41 | 137 | { |
mjr | 43:7a6364d82a41 | 138 | // wait for the hardware to signal that the sample is completed |
mjr | 45:c42166b2878c | 139 | wait(); |
mjr | 43:7a6364d82a41 | 140 | |
mjr | 43:7a6364d82a41 | 141 | // return the result register value |
mjr | 48:058ace2aed1d | 142 | return (uint16_t)ADC0->R[0] << 8; // convert 16-bit to 16-bit, padding with zeroes |
mjr | 43:7a6364d82a41 | 143 | } |
mjr | 43:7a6364d82a41 | 144 | |
mjr | 43:7a6364d82a41 | 145 | /** Returns the scaled value |
mjr | 43:7a6364d82a41 | 146 | * |
mjr | 43:7a6364d82a41 | 147 | * @param return Float with scaled converted value to 0.0-1.0 |
mjr | 43:7a6364d82a41 | 148 | */ |
mjr | 43:7a6364d82a41 | 149 | float read(void) |
mjr | 43:7a6364d82a41 | 150 | { |
mjr | 43:7a6364d82a41 | 151 | unsigned short value = read_u16(); |
mjr | 43:7a6364d82a41 | 152 | return value / 65535.0f; |
mjr | 43:7a6364d82a41 | 153 | } |
mjr | 43:7a6364d82a41 | 154 | |
mjr | 43:7a6364d82a41 | 155 | /** An operator shorthand for read() |
mjr | 43:7a6364d82a41 | 156 | */ |
mjr | 43:7a6364d82a41 | 157 | operator float() { return read(); } |
mjr | 43:7a6364d82a41 | 158 | |
mjr | 43:7a6364d82a41 | 159 | |
mjr | 43:7a6364d82a41 | 160 | private: |
mjr | 45:c42166b2878c | 161 | uint32_t id; // unique ID |
mjr | 45:c42166b2878c | 162 | SimpleDMA *dma; // DMA controller, if used |
mjr | 45:c42166b2878c | 163 | char ADCnumber; // ADC number of our input pin |
mjr | 45:c42166b2878c | 164 | char ADCmux; // multiplexer for our input pin (0=A, 1=B) |
mjr | 45:c42166b2878c | 165 | uint32_t sc1; // SC1 register settings for this input |
mjr | 45:c42166b2878c | 166 | uint32_t sc2; // SC2 register settings for this input |
mjr | 45:c42166b2878c | 167 | uint32_t sc3; // SC3 register settings for this input |
mjr | 43:7a6364d82a41 | 168 | }; |
mjr | 43:7a6364d82a41 | 169 | |
mjr | 43:7a6364d82a41 | 170 | #endif |