Support KL25z USB logger

Dependents:   kl25z_Usb_Logger

Fork of FastAnalogIn by Erik -

Revision:
9:31184aa1449c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FastAnalogIn_KLXX_K20D50M.cpp	Sat Jul 12 10:39:37 2014 +0000
@@ -0,0 +1,114 @@
+#if defined(TARGET_KLXX) || defined(TARGET_K20D50M)
+
+#include "FastAnalogIn.h"
+#include "clk_freqs.h"
+
+#define MAX_FADC            6000000
+#define CHANNELS_A_SHIFT    5
+
+#ifdef TARGET_K20D50M
+static const PinMap PinMap_ADC[] = {
+    {PTC2, ADC0_SE4b, 0},
+    {PTD1, ADC0_SE5b, 0},
+    {PTD5, ADC0_SE6b, 0},
+    {PTD6, ADC0_SE7b, 0},
+    {PTB0, ADC0_SE8,  0},
+    {PTB1, ADC0_SE9,  0},
+    {PTB2, ADC0_SE12, 0},
+    {PTB3, ADC0_SE13, 0},
+    {PTC0, ADC0_SE14, 0},
+    {PTC1, ADC0_SE15, 0},
+    {NC,   NC,        0}
+};
+#endif
+
+FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
+{
+    ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
+    if (ADCnumber == (ADCName)NC) {
+        error("ADC pin mapping failed");
+    }
+
+    SIM->SCGC6 |= SIM_SCGC6_ADC0_MASK;
+
+    uint32_t port = (uint32_t)pin >> PORT_SHIFT;
+    SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port);
+
+    uint32_t cfg2_muxsel = ADC_CFG2_MUXSEL_MASK;
+    if (ADCnumber & (1 << CHANNELS_A_SHIFT)) {
+        cfg2_muxsel = 0;
+    }
+    
+    // bus clk
+    uint32_t PCLK = bus_frequency();
+    uint32_t clkdiv;
+    for (clkdiv = 0; clkdiv < 4; clkdiv++) {
+        if ((PCLK >> clkdiv) <= MAX_FADC)
+            break;
+    }
+    if (clkdiv == 4)                    //Set max div
+        clkdiv = 0x7;
+
+    ADC0->SC1[1] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT));
+
+    ADC0->CFG1 = ADC_CFG1_ADIV(clkdiv & 0x3)    // Clock Divide Select: (Input Clock)/8
+               | ADC_CFG1_MODE(3)               // (16)bits Resolution
+               | ADC_CFG1_ADICLK(clkdiv >> 2);  // Input Clock: (Bus Clock)/2
+
+    ADC0->CFG2 = cfg2_muxsel            // ADxxb or ADxxa channels
+               | ADC_CFG2_ADACKEN_MASK  // Asynchronous Clock Output Enable
+               | ADC_CFG2_ADHSC_MASK;   // High-Speed Configuration
+
+    ADC0->SC2 = ADC_SC2_REFSEL(0);      // Default Voltage Reference
+
+    pinmap_pinout(pin, PinMap_ADC);
+
+    //Enable channel
+    running = false;
+    enable(enabled);
+}
+
+void FastAnalogIn::enable(bool enabled)
+{
+    //If currently not running
+    if (!running) {
+        if (enabled) {
+            //Enable the ADC channel
+            ADC0->SC3 |= ADC_SC3_ADCO_MASK;       // Enable continuous conversion
+            ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT));  //Start conversion
+            running = true;
+        } else
+            disable();
+    }
+}
+ 
+void FastAnalogIn::disable( void )
+{
+    //If currently running
+    if (running) {
+        ADC0->SC3 &= ~ADC_SC3_ADCO_MASK;      // Disable continuous conversion
+    }
+    running = false;
+}
+
+uint16_t FastAnalogIn::read_u16()
+{
+    if (!running)
+    {
+        // start conversion
+        ADC0->SC1[0] = ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT));
+        // Wait Conversion Complete
+        while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
+    }
+    if(running && ((ADC0->SC1[0]&ADC_SC1_ADCH_MASK) != (ADC_SC1_ADCH(ADCnumber & ~(1 << CHANNELS_A_SHIFT)))))
+    {
+        running = false;
+        enable();
+        while ((ADC0->SC1[0] & ADC_SC1_COCO_MASK) != ADC_SC1_COCO_MASK);
+    }
+    // Return value
+    return (uint16_t)ADC0->R[0];
+}
+
+#endif //defined TARGET_KLXX
+