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.

Fork of FastAnalogIn by Erik -

Obsolete!

Has been already merged with Erik's original repository => take the original!

  • Added support for LPC4088.
  • Fixed linker error (missing definition of static member "channel_usage")
Committer:
frankvnk
Date:
Sat Mar 08 15:44:57 2014 +0000
Revision:
2:9b61d0792927
Child:
3:a9b753c25073
Added KLxx support

Who changed what in which revision?

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