Class similar to AnalogIn that uses burst mode to run continious background conversions so when the input is read, the last value can immediatly be returned. This slightly modified version allows NC pins.

Dependents:   Pinscape_Controller

Fork of FastAnalogIn by Erik -

Committer:
mjr
Date:
Sat Dec 19 06:36:25 2015 +0000
Revision:
11:234c5cd2b8de
Parent:
9:31184aa1449c
Minor changes

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Sissors 9:31184aa1449c 1 #if defined(TARGET_KLXX) || defined(TARGET_K20D50M)
Sissors 9:31184aa1449c 2
Sissors 9:31184aa1449c 3 #include "FastAnalogIn.h"
Sissors 9:31184aa1449c 4 #include "clk_freqs.h"
Sissors 9:31184aa1449c 5
Sissors 9:31184aa1449c 6 #define MAX_FADC 6000000
Sissors 9:31184aa1449c 7 #define CHANNELS_A_SHIFT 5
Sissors 9:31184aa1449c 8
Sissors 9:31184aa1449c 9 #ifdef TARGET_K20D50M
Sissors 9:31184aa1449c 10 static const PinMap PinMap_ADC[] = {
Sissors 9:31184aa1449c 11 {PTC2, ADC0_SE4b, 0},
Sissors 9:31184aa1449c 12 {PTD1, ADC0_SE5b, 0},
Sissors 9:31184aa1449c 13 {PTD5, ADC0_SE6b, 0},
Sissors 9:31184aa1449c 14 {PTD6, ADC0_SE7b, 0},
Sissors 9:31184aa1449c 15 {PTB0, ADC0_SE8, 0},
Sissors 9:31184aa1449c 16 {PTB1, ADC0_SE9, 0},
Sissors 9:31184aa1449c 17 {PTB2, ADC0_SE12, 0},
Sissors 9:31184aa1449c 18 {PTB3, ADC0_SE13, 0},
Sissors 9:31184aa1449c 19 {PTC0, ADC0_SE14, 0},
Sissors 9:31184aa1449c 20 {PTC1, ADC0_SE15, 0},
Sissors 9:31184aa1449c 21 {NC, NC, 0}
Sissors 9:31184aa1449c 22 };
Sissors 9:31184aa1449c 23 #endif
Sissors 9:31184aa1449c 24
Sissors 9:31184aa1449c 25 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
Sissors 9:31184aa1449c 26 {
mjr 11:234c5cd2b8de 27 if (pin == NC)
mjr 11:234c5cd2b8de 28 return;
mjr 11:234c5cd2b8de 29
Sissors 9:31184aa1449c 30 ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
Sissors 9:31184aa1449c 31 if (ADCnumber == (ADCName)NC) {
Sissors 9:31184aa1449c 32 error("ADC pin mapping failed");
Sissors 9:31184aa1449c 33 }
Sissors 9:31184aa1449c 34
Sissors 9:31184aa1449c 35 SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
Sissors 9:31184aa1449c 36
Sissors 9:31184aa1449c 37 uint32_t port = (uint32_t)pin >> PORT_SHIFT;
Sissors 9:31184aa1449c 38 SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
Sissors 9:31184aa1449c 39
Sissors 9:31184aa1449c 40 uint32_t cfg2_muxsel = ADC_CFG2_MUXSEL_MASK;
Sissors 9:31184aa1449c 41 if (ADCnumber & (1 << CHANNELS_A_SHIFT)) {
Sissors 9:31184aa1449c 42 cfg2_muxsel = 0;
Sissors 9:31184aa1449c 43 }
Sissors 9:31184aa1449c 44
Sissors 9:31184aa1449c 45 // bus clk
Sissors 9:31184aa1449c 46 uint32_t PCLK = bus_frequency();
Sissors 9:31184aa1449c 47 uint32_t clkdiv;
Sissors 9:31184aa1449c 48 for (clkdiv = 0; clkdiv < 4; clkdiv++) {
Sissors 9:31184aa1449c 49 if ((PCLK >> clkdiv) <= MAX_FADC)
Sissors 9:31184aa1449c 50 break;
Sissors 9:31184aa1449c 51 }
Sissors 9:31184aa1449c 52 if (clkdiv == 4) //Set max div
Sissors 9:31184aa1449c 53 clkdiv = 0x7;
Sissors 9:31184aa1449c 54
Sissors 9:31184aa1449c 55 ADC0->SC1[1] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT));
Sissors 9:31184aa1449c 56
Sissors 9:31184aa1449c 57 ADC0->CFG1 = ADC_CFG1_ADIV(clkdiv & 0x3) // Clock Divide Select: (Input Clock)/8
Sissors 9:31184aa1449c 58 | ADC_CFG1_MODE(3) // (16)bits Resolution
Sissors 9:31184aa1449c 59 | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock: (Bus Clock)/2
Sissors 9:31184aa1449c 60
Sissors 9:31184aa1449c 61 ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels
Sissors 9:31184aa1449c 62 | ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable
Sissors 9:31184aa1449c 63 | ADC_CFG2_ADHSC_MASK; // High-Speed Configuration
Sissors 9:31184aa1449c 64
Sissors 9:31184aa1449c 65 ADC0->SC2 = ADC_SC2_REFSEL(0); // Default Voltage Reference
Sissors 9:31184aa1449c 66
Sissors 9:31184aa1449c 67 pinmap_pinout(pin, PinMap_ADC);
Sissors 9:31184aa1449c 68
Sissors 9:31184aa1449c 69 //Enable channel
Sissors 9:31184aa1449c 70 running = false;
Sissors 9:31184aa1449c 71 enable(enabled);
Sissors 9:31184aa1449c 72 }
Sissors 9:31184aa1449c 73
Sissors 9:31184aa1449c 74 void FastAnalogIn::enable(bool enabled)
Sissors 9:31184aa1449c 75 {
Sissors 9:31184aa1449c 76 //If currently not running
Sissors 9:31184aa1449c 77 if (!running) {
Sissors 9:31184aa1449c 78 if (enabled) {
Sissors 9:31184aa1449c 79 //Enable the ADC channel
Sissors 9:31184aa1449c 80 ADC0->SC3 |= ADC_SC3_ADCO_MASK; // Enable continuous conversion
Sissors 9:31184aa1449c 81 ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)); //Start conversion
Sissors 9:31184aa1449c 82 running = true;
Sissors 9:31184aa1449c 83 } else
Sissors 9:31184aa1449c 84 disable();
Sissors 9:31184aa1449c 85 }
Sissors 9:31184aa1449c 86 }
Sissors 9:31184aa1449c 87
Sissors 9:31184aa1449c 88 void FastAnalogIn::disable( void )
Sissors 9:31184aa1449c 89 {
Sissors 9:31184aa1449c 90 //If currently running
Sissors 9:31184aa1449c 91 if (running) {
Sissors 9:31184aa1449c 92 ADC0->SC3 &= ~ADC_SC3_ADCO_MASK; // Disable continuous conversion
Sissors 9:31184aa1449c 93 }
Sissors 9:31184aa1449c 94 running = false;
Sissors 9:31184aa1449c 95 }
Sissors 9:31184aa1449c 96
Sissors 9:31184aa1449c 97 uint16_t FastAnalogIn::read_u16()
Sissors 9:31184aa1449c 98 {
Sissors 9:31184aa1449c 99 if (!running)
Sissors 9:31184aa1449c 100 {
Sissors 9:31184aa1449c 101 // start conversion
Sissors 9:31184aa1449c 102 ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT));
Sissors 9:31184aa1449c 103 // Wait Conversion Complete
Sissors 9:31184aa1449c 104 while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
Sissors 9:31184aa1449c 105 }
Sissors 9:31184aa1449c 106 if(running && ((ADC0->SC1[0]&ADC_SC1_ADCH_MASK) != (ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)))))
Sissors 9:31184aa1449c 107 {
Sissors 9:31184aa1449c 108 running = false;
Sissors 9:31184aa1449c 109 enable();
Sissors 9:31184aa1449c 110 while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
Sissors 9:31184aa1449c 111 }
Sissors 9:31184aa1449c 112 // Return value
Sissors 9:31184aa1449c 113 return (uint16_t)ADC0->R[0];
Sissors 9:31184aa1449c 114 }
Sissors 9:31184aa1449c 115
Sissors 9:31184aa1449c 116 #endif //defined TARGET_KLXX
Sissors 9:31184aa1449c 117