FastAnalogIn

Fork of FastAnalogIn by Erik -

Files at this revision

API Documentation at this revision

Comitter:
humlet
Date:
Sun Apr 20 16:23:19 2014 +0000
Parent:
3:a9b753c25073
Child:
5:55274430c8df
Commit message:
Added support for LPC4088,; Fixed linker error (missing definition of static member)

Changed in this revision

FastAnalogIn.h Show annotated file Show diff for this revision Revisions of this file
FastAnalogIn_LPC1768.cpp Show annotated file Show diff for this revision Revisions of this file
FastAnalogIn_LPC408X.cpp Show annotated file Show diff for this revision Revisions of this file
--- a/FastAnalogIn.h	Sat Mar 08 16:01:36 2014 +0000
+++ b/FastAnalogIn.h	Sun Apr 20 16:23:19 2014 +0000
@@ -7,7 +7,7 @@
 #include "mbed.h"
 #include "pinmap.h"
 
-#if !defined TARGET_LPC1768 && !defined TARGET_KL25Z && !defined TARGET_KL46Z && !defined TARGET_KL05Z
+#if !defined TARGET_LPC1768 && !defined TARGET_KL25Z && !defined TARGET_KL46Z && !defined TARGET_KL05Z && !defined TARGET_LPC408X
     #error "Target not supported"
 #endif
 
@@ -107,7 +107,7 @@
     float read( void )
     {
         unsigned short value = read_u16();
-        return (float)value/65535;
+        return (float)value * (1.0f/65535.0f);
     }
     
     /** An operator shorthand for read()
--- a/FastAnalogIn_LPC1768.cpp	Sat Mar 08 16:01:36 2014 +0000
+++ b/FastAnalogIn_LPC1768.cpp	Sun Apr 20 16:23:19 2014 +0000
@@ -18,6 +18,8 @@
     NC,    NC,     0
 };
 
+int FastAnalogIn::channel_usage[8] = {0,0,0,0,0,0,0,0};
+
 FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
 {
     ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/FastAnalogIn_LPC408X.cpp	Sun Apr 20 16:23:19 2014 +0000
@@ -0,0 +1,128 @@
+#ifdef TARGET_LPC408X
+
+#include "FastAnalogIn.h"
+
+static inline int div_round_up(int x, int y)
+{
+    return (x + (y - 1)) / y;
+}
+
+static const PinMap PinMap_ADC[] = {
+    {P0_23, ADC0_0, 0x01},
+    {P0_24, ADC0_1, 0x01},
+    {P0_25, ADC0_2, 0x01},
+    {P0_26, ADC0_3, 0x01},
+    {P1_30, ADC0_4, 0x03},
+    {P1_31, ADC0_5, 0x03},
+    {P0_12, ADC0_6, 0x03},
+    {P0_13, ADC0_7, 0x03},
+    {NC   , NC    , 0   }
+};
+
+int FastAnalogIn::channel_usage[8] = {0,0,0,0,0,0,0,0};
+
+FastAnalogIn::FastAnalogIn(PinName pin, bool enabled)
+{
+    ADCnumber = (ADCName)pinmap_peripheral(pin, PinMap_ADC);
+    if (ADCnumber == (uint32_t)NC)
+        error("ADC pin mapping failed");
+    //printf("ADC_ID=%u\n",ADCnumber);
+    datareg = (uint32_t*) (&LPC_ADC->DR[ADCnumber]);
+
+    wait_us(1000); // we need either the debug printf above or a wait before we try to initialize the ADC
+
+    // ensure power is turned on
+    LPC_SC->PCONP |= (1 << 12);
+
+    uint32_t PCLK = PeripheralClock;
+
+    // calculate minimum clock divider
+    //  clkdiv = divider - 1
+    uint32_t MAX_ADC_CLK = 12400000;
+    uint32_t clkdiv = div_round_up(PCLK, MAX_ADC_CLK) - 1;
+    // Set the clkdiv
+    LPC_ADC->CR &= ~(255<<8);
+    LPC_ADC->CR |= clkdiv<<8;
+
+    //Enable ADC:
+    LPC_ADC->CR |= 1<<21;
+
+    //Enable burstmode, set start as zero
+    LPC_ADC->CR |= 1<<16;
+    LPC_ADC->CR &= ~(7<<24);
+
+    // must enable analog mode (ADMODE = 0)   ... ???  just copied from official LPC408X analogin_api.c
+    __IO uint32_t *reg = (__IO uint32_t*) (LPC_IOCON_BASE + 4 * pin);
+    *reg &= ~(1 << 7);
+
+    //Map pins
+    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
+            channel_usage[ADCnumber]++;
+            LPC_ADC->CR |= (1<<ADCnumber);
+            running = true;
+        } else
+            disable();
+    }
+}
+
+void FastAnalogIn::disable( void )
+{
+    //If currently running
+    if (running) {
+        channel_usage[ADCnumber]--;
+        
+        if (channel_usage[ADCnumber]==0)
+            LPC_ADC->CR &= ~(1<<ADCnumber);
+    }
+    running = false;
+}
+
+unsigned short FastAnalogIn::read_u16( void )
+{
+    volatile unsigned int retval;
+    //If object is enabled return current value of datareg
+    if (running ){
+        retval = *datareg;
+    //If it isn't running, enable it and wait until new value is written to datareg
+    }else {
+        //Force a read to clear done bit, enable the ADC channel
+        retval = *datareg;
+        enable();
+        //Wait until it is converted
+        while(1) {
+            wait_us(1);
+            retval = *datareg;
+            if ((retval>>31) == 1)
+                break;
+        }
+        //Do a second conversion since first one always fails for some reason
+        while(1) {
+            wait_us(1);
+            retval = *datareg;
+            if ((retval>>31) == 1)
+                break;
+        }
+        //Disable again
+        disable();
+    }
+    
+    //Do same thing as standard mbed lib, unused bit 0-3, replicate 4-7 in it
+    retval &= ~0xFFFF000F;
+    retval |= (retval >> 8) & 0x000F;
+    return retval;
+
+}
+#endif //defined TARGET_LPC408X