Mirror with some correction

Dependencies:   mbed FastIO FastPWM USBDevice

Committer:
arnoz
Date:
Fri Oct 01 08:19:46 2021 +0000
Revision:
116:7a67265d7c19
Parent:
100:1ff35c07217c
- Correct information regarding your last merge

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mjr 43:7a6364d82a41 1 #if defined(TARGET_KLXX) || defined(TARGET_K20D50M)
mjr 43:7a6364d82a41 2
mjr 43:7a6364d82a41 3 #include "AltAnalogIn.h"
mjr 43:7a6364d82a41 4 #include "clk_freqs.h"
mjr 43:7a6364d82a41 5
mjr 43:7a6364d82a41 6 #ifdef TARGET_K20D50M
mjr 43:7a6364d82a41 7 static const PinMap PinMap_ADC[] = {
mjr 43:7a6364d82a41 8 {PTC2, ADC0_SE4b, 0},
mjr 43:7a6364d82a41 9 {PTD1, ADC0_SE5b, 0},
mjr 43:7a6364d82a41 10 {PTD5, ADC0_SE6b, 0},
mjr 43:7a6364d82a41 11 {PTD6, ADC0_SE7b, 0},
mjr 43:7a6364d82a41 12 {PTB0, ADC0_SE8, 0},
mjr 43:7a6364d82a41 13 {PTB1, ADC0_SE9, 0},
mjr 43:7a6364d82a41 14 {PTB2, ADC0_SE12, 0},
mjr 43:7a6364d82a41 15 {PTB3, ADC0_SE13, 0},
mjr 43:7a6364d82a41 16 {PTC0, ADC0_SE14, 0},
mjr 43:7a6364d82a41 17 {PTC1, ADC0_SE15, 0},
mjr 43:7a6364d82a41 18 {NC, NC, 0}
mjr 43:7a6364d82a41 19 };
mjr 43:7a6364d82a41 20 #endif
mjr 43:7a6364d82a41 21
mjr 100:1ff35c07217c 22 // statics
mjr 100:1ff35c07217c 23 int AltAnalogIn::lastMux = -1;
mjr 100:1ff35c07217c 24 uint32_t AltAnalogIn::lastId = 0;
mjr 100:1ff35c07217c 25
mjr 100:1ff35c07217c 26 AltAnalogIn::AltAnalogIn(PinName pin, bool continuous, int long_sample_clocks, int averaging, int sample_bits)
mjr 43:7a6364d82a41 27 {
mjr 45:c42166b2878c 28 // set our unique ID
mjr 45:c42166b2878c 29 static uint32_t nextID = 1;
mjr 45:c42166b2878c 30 id = nextID++;
mjr 45:c42166b2878c 31
mjr 100:1ff35c07217c 32 // presume no DMA or interrupts
mjr 45:c42166b2878c 33 dma = 0;
mjr 100:1ff35c07217c 34 sc1_aien = 0;
mjr 45:c42166b2878c 35
mjr 43:7a6364d82a41 36 // do nothing if explicitly not connected
mjr 43:7a6364d82a41 37 if (pin == NC)
mjr 43:7a6364d82a41 38 return;
mjr 100:1ff35c07217c 39
mjr 100:1ff35c07217c 40 // validate the sample bit size, and figure the ADC_xxBIT code for it
mjr 100:1ff35c07217c 41 uint32_t adc_xxbit = ADC_8BIT;
mjr 100:1ff35c07217c 42 switch (sample_bits)
mjr 100:1ff35c07217c 43 {
mjr 100:1ff35c07217c 44 case 8:
mjr 100:1ff35c07217c 45 adc_xxbit = ADC_8BIT;
mjr 100:1ff35c07217c 46 break;
mjr 100:1ff35c07217c 47
mjr 100:1ff35c07217c 48 case 10:
mjr 100:1ff35c07217c 49 adc_xxbit = ADC_10BIT;
mjr 100:1ff35c07217c 50 break;
mjr 100:1ff35c07217c 51
mjr 100:1ff35c07217c 52 case 12:
mjr 100:1ff35c07217c 53 adc_xxbit = ADC_12BIT;
mjr 100:1ff35c07217c 54 break;
mjr 100:1ff35c07217c 55
mjr 100:1ff35c07217c 56 case 16:
mjr 100:1ff35c07217c 57 adc_xxbit = ADC_16BIT;
mjr 100:1ff35c07217c 58 break;
mjr 100:1ff35c07217c 59
mjr 100:1ff35c07217c 60 default:
mjr 100:1ff35c07217c 61 error("invalid sample size for AltAnalogIn - must be 8, 10, 12, or 16 bits");
mjr 100:1ff35c07217c 62 }
mjr 100:1ff35c07217c 63
mjr 100:1ff35c07217c 64 // validate the long sample mode
mjr 100:1ff35c07217c 65 uint32_t cfg1_adlsmp = ADC_CFG1_ADLSMP;
mjr 100:1ff35c07217c 66 uint32_t cfg2_adlsts = ADC_CFG2_ADLSTS(3);
mjr 100:1ff35c07217c 67 switch (long_sample_clocks)
mjr 100:1ff35c07217c 68 {
mjr 100:1ff35c07217c 69 case 0:
mjr 100:1ff35c07217c 70 // disable long sample mode
mjr 100:1ff35c07217c 71 cfg1_adlsmp = 0;
mjr 100:1ff35c07217c 72 cfg2_adlsts = ADC_CFG2_ADLSTS(3);
mjr 100:1ff35c07217c 73 break;
mjr 100:1ff35c07217c 74
mjr 100:1ff35c07217c 75 case 6:
mjr 100:1ff35c07217c 76 cfg1_adlsmp = ADC_CFG1_ADLSMP; // enable long sample mode
mjr 100:1ff35c07217c 77 cfg2_adlsts = ADC_CFG2_ADLSTS(3); // Long sample time mode 3 -> 6 ADCK cycles total
mjr 100:1ff35c07217c 78 break;
mjr 100:1ff35c07217c 79
mjr 100:1ff35c07217c 80 case 10:
mjr 100:1ff35c07217c 81 cfg1_adlsmp = ADC_CFG1_ADLSMP; // enable long sample mode
mjr 100:1ff35c07217c 82 cfg2_adlsts = ADC_CFG2_ADLSTS(2); // Long sample time mode 2 -> 10 ADCK cycles total
mjr 100:1ff35c07217c 83 break;
mjr 100:1ff35c07217c 84
mjr 100:1ff35c07217c 85 case 16:
mjr 100:1ff35c07217c 86 cfg1_adlsmp = ADC_CFG1_ADLSMP; // enable long sample mode
mjr 100:1ff35c07217c 87 cfg2_adlsts = ADC_CFG2_ADLSTS(1); // Long sample time mode 1 -> 16 ADCK cycles total
mjr 100:1ff35c07217c 88 break;
mjr 100:1ff35c07217c 89
mjr 100:1ff35c07217c 90 case 24:
mjr 100:1ff35c07217c 91 cfg1_adlsmp = ADC_CFG1_ADLSMP; // enable long sample mode
mjr 100:1ff35c07217c 92 cfg2_adlsts = ADC_CFG2_ADLSTS(0); // Long sample time mode 0 -> 24 ADCK cycles total
mjr 100:1ff35c07217c 93 break;
mjr 100:1ff35c07217c 94
mjr 100:1ff35c07217c 95 default:
mjr 100:1ff35c07217c 96 error("invalid long sample mode clock count - must be 0 (disabled), 6, 10, 16, or 24");
mjr 100:1ff35c07217c 97 }
mjr 100:1ff35c07217c 98
mjr 100:1ff35c07217c 99 // figure the averaging bits
mjr 100:1ff35c07217c 100 uint32_t sc3_avg = 0;
mjr 100:1ff35c07217c 101 switch (averaging)
mjr 100:1ff35c07217c 102 {
mjr 100:1ff35c07217c 103 case 0:
mjr 100:1ff35c07217c 104 case 1:
mjr 100:1ff35c07217c 105 // 0/1 = no averaging
mjr 100:1ff35c07217c 106 sc3_avg = 0;
mjr 100:1ff35c07217c 107 break;
mjr 100:1ff35c07217c 108
mjr 100:1ff35c07217c 109 case 4:
mjr 100:1ff35c07217c 110 sc3_avg = ADC_SC3_AVGE | ADC_SC3_AVGS_4;
mjr 100:1ff35c07217c 111 break;
mjr 100:1ff35c07217c 112
mjr 100:1ff35c07217c 113 case 8:
mjr 100:1ff35c07217c 114 sc3_avg = ADC_SC3_AVGE | ADC_SC3_AVGS_8;
mjr 100:1ff35c07217c 115 break;
mjr 100:1ff35c07217c 116
mjr 100:1ff35c07217c 117 case 16:
mjr 100:1ff35c07217c 118 sc3_avg = ADC_SC3_AVGE | ADC_SC3_AVGS_16;
mjr 100:1ff35c07217c 119 break;
mjr 100:1ff35c07217c 120
mjr 100:1ff35c07217c 121 case 32:
mjr 100:1ff35c07217c 122 sc3_avg = ADC_SC3_AVGE | ADC_SC3_AVGS_32;
mjr 100:1ff35c07217c 123 break;
mjr 100:1ff35c07217c 124
mjr 100:1ff35c07217c 125 default:
mjr 100:1ff35c07217c 126 error("invalid ADC averaging count: must be 1, 4, 8, 16, or 32");
mjr 100:1ff35c07217c 127 }
mjr 43:7a6364d82a41 128
mjr 43:7a6364d82a41 129 // figure our ADC number
mjr 43:7a6364d82a41 130 ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
mjr 43:7a6364d82a41 131 if (ADCnumber == (ADCName)NC) {
mjr 43:7a6364d82a41 132 error("ADC pin mapping failed");
mjr 43:7a6364d82a41 133 }
mjr 43:7a6364d82a41 134
mjr 43:7a6364d82a41 135 // figure our multiplexer channel (A or B)
mjr 43:7a6364d82a41 136 ADCmux = (ADCnumber >> CHANNELS_A_SHIFT) ^ 1;
mjr 43:7a6364d82a41 137
mjr 43:7a6364d82a41 138 // enable the ADC0 clock in the system control module
mjr 43:7a6364d82a41 139 SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
mjr 43:7a6364d82a41 140
mjr 43:7a6364d82a41 141 // enable the port clock gate for the port containing our GPIO pin
mjr 43:7a6364d82a41 142 uint32_t port = (uint32_t)pin >> PORT_SHIFT;
mjr 43:7a6364d82a41 143 SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
mjr 43:7a6364d82a41 144
mjr 43:7a6364d82a41 145 // Figure the maximum clock frequency. In 12-bit mode or less, we can
mjr 43:7a6364d82a41 146 // run the ADC at up to 18 MHz per the KL25Z data sheet. (16-bit mode
mjr 43:7a6364d82a41 147 // is limited to 12 MHz.)
mjr 43:7a6364d82a41 148 int clkdiv = 0;
mjr 45:c42166b2878c 149 uint32_t adcfreq = bus_frequency();
mjr 100:1ff35c07217c 150 uint32_t maxfreq = sample_bits <= 12 ? MAX_FADC_12BIT : MAX_FADC_16BIT;
mjr 100:1ff35c07217c 151 for ( ; adcfreq > maxfreq ; adcfreq /= 2, clkdiv += 1) ;
mjr 43:7a6364d82a41 152
mjr 45:c42166b2878c 153 // The "high speed configuration" bit is required if the ADC clock
mjr 45:c42166b2878c 154 // frequency is above a certain threshold. The actual threshold is
mjr 45:c42166b2878c 155 // poorly documented: the reference manual only says that it's required
mjr 45:c42166b2878c 156 // when running the ADC at "high speed" but doesn't define how high
mjr 45:c42166b2878c 157 // "high" is. The only numerical figure I can find is in the Freescale
mjr 45:c42166b2878c 158 // ADC sample time calculator tool (a Windows program downloadable from
mjr 45:c42166b2878c 159 // the Freescale site), which has a little notation on the checkbox for
mjr 45:c42166b2878c 160 // the ADHSC bit that says to use it when the ADC clock is 8 MHz or
mjr 45:c42166b2878c 161 // higher.
mjr 45:c42166b2878c 162 //
mjr 45:c42166b2878c 163 // Note that this bit is somewhat confusingly named. It doesn't mean
mjr 45:c42166b2878c 164 // "make the ADC go faster". It actually means just the opposite.
mjr 45:c42166b2878c 165 // What it really means is that the external clock is running so fast
mjr 45:c42166b2878c 166 // that the ADC has to pad out its sample time slightly to compensate,
mjr 45:c42166b2878c 167 // by adding a couple of extra clock cycles to each sampling interval.
mjr 45:c42166b2878c 168 const uint32_t ADHSC_SPEED_LIMIT = 8000000;
mjr 45:c42166b2878c 169 uint32_t adhsc_bit = (adcfreq >= ADHSC_SPEED_LIMIT ? ADC_CFG2_ADHSC_MASK : 0);
mjr 43:7a6364d82a41 170
mjr 45:c42166b2878c 171 // map the GPIO pin in the system multiplexer to the ADC
mjr 45:c42166b2878c 172 pinmap_pinout(pin, PinMap_ADC);
mjr 45:c42166b2878c 173
mjr 45:c42166b2878c 174 // set up the ADC control registers - these are common to all users of this class
mjr 45:c42166b2878c 175
mjr 47:df7a88cd249c 176 ADC0->CFG1 = ADC_CFG1_ADIV(clkdiv) // Clock Divide Select (as calculated above)
mjr 100:1ff35c07217c 177 | cfg1_adlsmp // Long sample time
mjr 100:1ff35c07217c 178 | ADC_CFG1_MODE(adc_xxbit) // Sample precision
mjr 47:df7a88cd249c 179 | ADC_CFG1_ADICLK(0); // Input Clock = bus clock
mjr 43:7a6364d82a41 180
mjr 47:df7a88cd249c 181 ADC0->CFG2 = adhsc_bit // High-Speed Configuration, if needed
mjr 100:1ff35c07217c 182 | cfg2_adlsts; // long sample time mode
mjr 43:7a6364d82a41 183
mjr 45:c42166b2878c 184 // Figure our SC1 register bits
mjr 100:1ff35c07217c 185 sc1 = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT))
mjr 100:1ff35c07217c 186 | sc1_aien;
mjr 43:7a6364d82a41 187
mjr 45:c42166b2878c 188 // figure our SC2 register bits
mjr 100:1ff35c07217c 189 sc2 = ADC_SC2_REFSEL(0); // Default Voltage Reference
mjr 45:c42166b2878c 190
mjr 45:c42166b2878c 191 // Set our SC3 bits. The defaults (0 bits) are calibration mode off,
mjr 45:c42166b2878c 192 // single sample, averaging disabled.
mjr 100:1ff35c07217c 193 sc3 = (continuous ? ADC_SC3_CONTINUOUS : 0) // enable continuous mode if desired
mjr 100:1ff35c07217c 194 | sc3_avg; // sample averaging mode bits
mjr 100:1ff35c07217c 195 }
mjr 100:1ff35c07217c 196
mjr 100:1ff35c07217c 197 void AltAnalogIn::calibrate()
mjr 100:1ff35c07217c 198 {
mjr 100:1ff35c07217c 199 // Select our channel to set up the MUX and SC2/SC3 registers. This
mjr 100:1ff35c07217c 200 // will set up the clock source and sample time we'll use to take
mjr 100:1ff35c07217c 201 // actual samples.
mjr 100:1ff35c07217c 202 selectChannel();
mjr 100:1ff35c07217c 203
mjr 100:1ff35c07217c 204 // Make sure DMA is disabled on the channel, so that we can see COCO.
mjr 100:1ff35c07217c 205 // Also make sure that software triggering is in effect.
mjr 100:1ff35c07217c 206 ADC0->SC2 &= ~(ADC_SC2_DMAEN | ADC_SC2_ADTRG);
mjr 100:1ff35c07217c 207
mjr 100:1ff35c07217c 208 // clear any past calibration results
mjr 100:1ff35c07217c 209 ADC0->SC3 |= ADC_SC3_CALF;
mjr 100:1ff35c07217c 210
mjr 100:1ff35c07217c 211 // select 32X averaging mode for highest accuracy, and begin calibration
mjr 100:1ff35c07217c 212 ADC0->SC3 = (sc3 & ~ADC_SC3_AVGS_MASK) | ADC_SC3_AVGS_32 | ADC_SC3_CAL;
mjr 100:1ff35c07217c 213
mjr 100:1ff35c07217c 214 // Wait for calibration to finish, but not more than 10ms, just in
mjr 100:1ff35c07217c 215 // case something goes wrong in the setup.
mjr 100:1ff35c07217c 216 Timer t;
mjr 100:1ff35c07217c 217 t.start();
mjr 100:1ff35c07217c 218 uint32_t t0 = t.read_us();
mjr 100:1ff35c07217c 219 while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) == 0 && static_cast<uint32_t>(t.read_us() - t0) < 10000) ;
mjr 100:1ff35c07217c 220
mjr 100:1ff35c07217c 221 // debugging
mjr 100:1ff35c07217c 222 // printf("ADC calibration %s, run time %u us\r\n",
mjr 100:1ff35c07217c 223 // (ADC0->SC3 & ADC_SC3_CALF) != 0 ? "error" : "ok",
mjr 100:1ff35c07217c 224 // static_cast<uint32_t>(t.read_us() - t0));
mjr 100:1ff35c07217c 225
mjr 100:1ff35c07217c 226 // Check results
mjr 100:1ff35c07217c 227 if ((ADC0->SC3 & ADC_SC3_CALF) == 0)
mjr 100:1ff35c07217c 228 {
mjr 100:1ff35c07217c 229 // Success - calculate the plus-side calibration results and store
mjr 100:1ff35c07217c 230 // in the PG register. (This procedure is from reference manual.)
mjr 100:1ff35c07217c 231 uint16_t sum = 0;
mjr 100:1ff35c07217c 232 sum += ADC0->CLP0;
mjr 100:1ff35c07217c 233 sum += ADC0->CLP1;
mjr 100:1ff35c07217c 234 sum += ADC0->CLP2;
mjr 100:1ff35c07217c 235 sum += ADC0->CLP3;
mjr 100:1ff35c07217c 236 sum += ADC0->CLP4;
mjr 100:1ff35c07217c 237 sum += ADC0->CLPS;
mjr 100:1ff35c07217c 238 sum /= 2;
mjr 100:1ff35c07217c 239 sum |= 0x8000;
mjr 100:1ff35c07217c 240 ADC0->PG = sum;
mjr 100:1ff35c07217c 241
mjr 100:1ff35c07217c 242 // do the same for the minus-side results
mjr 100:1ff35c07217c 243 sum = 0;
mjr 100:1ff35c07217c 244 sum += ADC0->CLM0;
mjr 100:1ff35c07217c 245 sum += ADC0->CLM1;
mjr 100:1ff35c07217c 246 sum += ADC0->CLM2;
mjr 100:1ff35c07217c 247 sum += ADC0->CLM3;
mjr 100:1ff35c07217c 248 sum += ADC0->CLM4;
mjr 100:1ff35c07217c 249 sum += ADC0->CLMS;
mjr 100:1ff35c07217c 250 sum /= 2;
mjr 100:1ff35c07217c 251 sum |= 0x8000;
mjr 100:1ff35c07217c 252 ADC0->MG = sum;
mjr 100:1ff35c07217c 253 }
mjr 100:1ff35c07217c 254
mjr 100:1ff35c07217c 255 // Clear any error (this is one of those perverse cases where we clear
mjr 100:1ff35c07217c 256 // a bit in a peripheral by writing 1 to the bit)
mjr 100:1ff35c07217c 257 ADC0->SC3 |= ADC_SC3_CALF;
mjr 100:1ff35c07217c 258
mjr 100:1ff35c07217c 259 // restore our normal SC2 and SC3 settings
mjr 100:1ff35c07217c 260 ADC0->SC2 = sc2;
mjr 100:1ff35c07217c 261 ADC0->SC3 = sc3;
mjr 100:1ff35c07217c 262
mjr 100:1ff35c07217c 263 // un-select the channel so that we reset all registers next time
mjr 100:1ff35c07217c 264 unselectChannel();
mjr 100:1ff35c07217c 265 }
mjr 100:1ff35c07217c 266
mjr 100:1ff35c07217c 267 void AltAnalogIn::enableInterrupts()
mjr 100:1ff35c07217c 268 {
mjr 100:1ff35c07217c 269 sc1_aien = ADC_SC1_AIEN;
mjr 100:1ff35c07217c 270 sc1 |= ADC_SC1_AIEN;
mjr 43:7a6364d82a41 271 }
mjr 43:7a6364d82a41 272
mjr 45:c42166b2878c 273 void AltAnalogIn::initDMA(SimpleDMA *dma)
mjr 45:c42166b2878c 274 {
mjr 45:c42166b2878c 275 // remember the DMA interface object
mjr 45:c42166b2878c 276 this->dma = dma;
mjr 45:c42166b2878c 277
mjr 45:c42166b2878c 278 // set to read from the ADC result register
mjr 47:df7a88cd249c 279 dma->source(&ADC0->R[0], false, 8);
mjr 45:c42166b2878c 280
mjr 45:c42166b2878c 281 // set to trigger on the ADC
mjr 45:c42166b2878c 282 dma->trigger(Trigger_ADC0);
mjr 45:c42166b2878c 283
mjr 45:c42166b2878c 284 // enable DMA in our SC2 bits
mjr 45:c42166b2878c 285 sc2 |= ADC_SC2_DMAEN;
mjr 45:c42166b2878c 286 }
mjr 45:c42166b2878c 287
mjr 100:1ff35c07217c 288 void AltAnalogIn::setTriggerTPM(int tpmUnitNumber)
mjr 100:1ff35c07217c 289 {
mjr 100:1ff35c07217c 290 // select my channel
mjr 100:1ff35c07217c 291 selectChannel();
mjr 100:1ff35c07217c 292
mjr 100:1ff35c07217c 293 // set the hardware trigger for the ADC to the specified TPM unit
mjr 100:1ff35c07217c 294 SIM->SOPT7 = ADC0ALTTRGEN | ADC0TRGSEL_TPM(tpmUnitNumber);
mjr 100:1ff35c07217c 295
mjr 100:1ff35c07217c 296 // set the ADC to hardware trigger mode
mjr 100:1ff35c07217c 297 ADC0->SC2 = sc2 | ADC_SC2_ADTRG;
mjr 100:1ff35c07217c 298
mjr 100:1ff35c07217c 299 // set SC1a and SC1b
mjr 100:1ff35c07217c 300 ADC0->SC1[0] = sc1;
mjr 100:1ff35c07217c 301 ADC0->SC1[1] = sc1;
mjr 100:1ff35c07217c 302 }
mjr 45:c42166b2878c 303
mjr 43:7a6364d82a41 304 #endif //defined TARGET_KLXX