Embedded system Fun Blog
























































Find out all the best information, libraries and circuit about the latest Embedded systems.
Showing posts with label fast. Show all posts
Showing posts with label fast. Show all posts

Sunday, 8 January 2012

MBED: FastXML parser library

.from: http://mbed.org/users/rolf/programs/fastxml/gpdz45

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx fastxml.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#include "fastxml.h"

/*!
**
** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliffscarab@gmail.com
**
** The MIT license:
**
** Permission is hereby granted, MEMALLOC_FREE of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is furnished
** to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.

** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/


class MyFastXml : public FastXml {
public:
  enum CharType {
    CT_DATA,
    CT_EOF,
    CT_SOFT,
    CT_END_OF_ELEMENT, // either a forward slash or a greater than symbol
    CT_END_OF_LINE,
  };

  MyFastXml(void) {
    mInputData = 0;
    memset(mTypes,CT_DATA,256);
    mTypes[0] = CT_EOF;
    mTypes[32] = CT_SOFT;
    mTypes[9] = CT_SOFT;
    mTypes['/'] = CT_END_OF_ELEMENT;
    mTypes['>'] = CT_END_OF_ELEMENT;
    mTypes['?'] = CT_END_OF_ELEMENT;
    mTypes[10] = CT_END_OF_LINE;
    mTypes[13] = CT_END_OF_LINE;
    mError = 0;
  }
  ~MyFastXml(void) {
    release();
  }

  void release(void) {
    if(mInputData) {
      free(mInputData);
      mInputData = 0;
    }
    mError = 0;
  }

  inline char *nextSoft(char *scan) {
    while ( *scan && mTypes[*scan] != CT_SOFT ) scan++;
    return scan;
  }

  inline char *nextSoftOrClose(char *scan,bool &close) {
    while ( *scan && mTypes[*scan] != CT_SOFT && *scan != '>' ) scan++;
    close = *scan == '>';
    return scan;
  }

  inline char *nextSep(char *scan) {
    while ( *scan && mTypes[*scan] != CT_SOFT && *scan != '=' ) scan++;
    return scan;
  }

  inline char * skipNextData(char *scan) {
    // while we have data, and we encounter soft seperators or line feeds...
    while ( *scan && mTypes[*scan] == CT_SOFT || mTypes[*scan] == CT_END_OF_LINE ) {
      if ( *scan == 13 ) mLineNo++;
      scan++;
    }
    return scan;
  }

  char * processClose(char c,const char *element,char *scan,int argc,const char **argv,FastXmlInterface *iface) {
    if ( c == '/' || c == '?' ) {
      if ( *scan != '>' ) { // unexepected character!
        mError = "Expected an element close character immediately after the '/' or '?' character.";
        return 0;
      }
      scan++;
      bool ok = iface->processElement(element,argc,argv,0,mLineNo);
      if ( !ok )
      {
        mError = "User aborted the parsing process";
        return 0;
      }
    }
    else
    {
      scan = skipNextData(scan);
      char *data = scan; // this is the data portion of the element, only copies memory if we encounter line feeds
      char *dest_data = 0;
      while ( *scan && *scan != '<' )
      {
        if ( mTypes[*scan] == CT_END_OF_LINE )
        {
          if ( *scan == 13 ) mLineNo++;
          dest_data = scan;
          *dest_data++ = 32; // replace the linefeed with a space...
          scan = skipNextData(scan);
          while ( *scan && *scan != '<' )
          {
            if ( mTypes[*scan] == CT_END_OF_LINE )
            {
             if ( *scan == 13 ) mLineNo++;
             *dest_data++ = 32; // replace the linefeed with a space...
              scan = skipNextData(scan);
            }
            else
            {
              *dest_data++ = *scan++;
            }
          }
          break;
        }
        else
          scan++;
      }
      if ( *scan == '<' )
      {
        if ( dest_data )
        {
          *dest_data = 0;
        }
        else
        {
          *scan = 0;
        }
        scan++; // skip it..
        if ( *data == 0 ) data = 0;
        bool ok = iface->processElement(element,argc,argv,data,mLineNo);
        if ( !ok )
        {
          mError = "User aborted the parsing process";
          return 0;
        }
        if ( *scan == '/' )
        {
          while ( *scan && *scan != '>' ) scan++;
          scan++;
        }
      }
      else
      {
        mError = "Data portion of an element wasn't terminated properly";
        return 0;
      }
    }
    return scan;
  }

  virtual bool processXml(const char *inputData,unsigned int dataLen,FastXmlInterface *iface)
  {
    bool ret = true;

    #define MAX_ATTRIBUTE 2048 // can't imagine having more than 2,048 attributes in a single element right?

    release();
    mInputData = (char *)malloc(dataLen+1);
    memcpy(mInputData,inputData,dataLen);
    mInputData[dataLen] = 0;

    mLineNo = 1;

    char *element;

    char *scan = mInputData;
    if ( *scan == '<' )
    {
      scan++;
      while ( *scan )
      {
        scan = skipNextData(scan);
        if ( *scan == 0 ) return ret;
        if ( *scan == '<' )
        {
          scan++;
        }
        if ( *scan == '/' || *scan == '?' )
        {
          while ( *scan && *scan != '>' ) scan++;
          scan++;
        }
        else
        {
          element = scan;
          int argc = 0;
          const char *argv[MAX_ATTRIBUTE];
          bool close;
          scan = nextSoftOrClose(scan,close);
          if ( close )
          {
            char c = *(scan-1);
            if ( c != '?' && c != '/' )
            {
              c = '>';
            }
            *scan = 0;
            scan++;
            scan = processClose(c,element,scan,argc,argv,iface);
            if ( !scan ) return false;
          }
          else
          {
            if ( *scan == 0 ) return ret;
            *scan = 0; // place a zero byte to indicate the end of the element name...
            scan++;

            while ( *scan )
            {
              scan = skipNextData(scan); // advance past any soft seperators (tab or space)

              if ( mTypes[*scan] == CT_END_OF_ELEMENT )
              {
                char c = *scan++;
                scan = processClose(c,element,scan,argc,argv,iface);
                if ( !scan ) return false;
                break;
              }
              else
              {
                if ( argc >= MAX_ATTRIBUTE )
                {
                  mError = "encountered too many attributes";
                  return false;
                }
                argv[argc] = scan;
                scan = nextSep(scan);  // scan up to a space, or an equal
                if ( *scan )
                {
                  if ( *scan != '=' )
                  {
                    *scan = 0;
                    scan++;
                    while ( *scan && *scan != '=' ) scan++;
                    if ( *scan == '=' ) scan++;
                  }
                  else
                  {
                    *scan=0;
                    scan++;
                  }
                  if ( *scan ) // if not eof...
                  {
                    scan = skipNextData(scan);
                    if ( *scan == 34 )
                    {
                      scan++;
                      argc++;
                      argv[argc] = scan;
                      argc++;
                      while ( *scan && *scan != 34 ) scan++;
                      if ( *scan == 34 )
                      {
                        *scan = 0;
                        scan++;
                      }
                      else
                      {
                        mError = "Failed to find closing quote for attribute";
                        return false;
                      }
                    }
                    else
                    {
                      mError = "Expected quote to begin attribute";
                      return false;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    else
    {
      mError = "Expected the start of an element '<' at this location.";
      ret = false; // unexpected character!?
    }

    return ret;
  }

  virtual const char *getError(int &lineno) {
    const char *ret = mError;
    lineno = mLineNo;
    mError = 0;
    return ret;
  }

private:
  char         mTypes[256];
  char        *mInputData;
  int          mLineNo;
  const char  *mError;
};



FastXml *createFastXml(void) {
  MyFastXml *f = new MyFastXml;
  return static_cast< FastXml *>(f);
}

void releaseFastXml(FastXml *f) {
  MyFastXml *m = static_cast< MyFastXml *>(f);
  delete m;
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx fastxml.h XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

#ifndef FAST_XML_H
#define FAST_XML_H

/*!
**
** Copyright (c) 2009 by John W. Ratcliff mailto:jratcliff@infiniplex.net
**
** The MIT license:
**
** Permission is hereby granted, MEMALLOC_FREE of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is furnished
** to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.

** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
** WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
** CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

*/


// This code snippet provides an extremely lightweight and fast XML parser.
// This parser only handles data elements as if they were streamed data.
// It is important to note that all pointers returned by this parser are
// persistent for the lifetime of the FastXml class.  This means you can cache
// copies of the pointers (rather than copying any data) if this matches your
// needs.


// Simpy call createFastXml to get a copy of the FastXml parsing interface
// To parse an XML file, have your application inherit the pure virtual
// interface called 'FastXmlInterface' and implement the single method 'processElement'
//
// For each element in the XML file you will get a callback with the following
// data.
//
// 'elementName' the name of the element (this pointer is persistent)
// 'argc'  The total number of attributes and values for this element.
//         The number of attribute/value pairs is equal to argc/2
// 'argv'  The attribute/value pairs in the form of attribute/value, attribute/value..
//         These pointers are persistent and can be cached if needed (until FastXml is released)
// 'elementData' optional data (i.e. text) associated with the element.  If this is a null pointer
//         then the element had no data.  This pointer is persistent.
// 'lineno'  The line number in the source XML file.
//
// After calling your routine 'processElement' you must return 'true' to continue parsing
// If you want to stop parsing early, return false.
//
// If the call to process an XML file fails, it will return false.
// You can then call the method 'getError' to get a description of why it failed
// and on what line number of the source XML file it occurred.

class FastXmlInterface {
  public:
    // return true to continue processing the XML document, false to skip.
    virtual bool processElement(const char *elementName,         // name of the element
                                int         argc,                // number of attributes
                                const char **argv,               // list of attributes.
                                const char  *elementData,        // element data, null if none
                                int         lineno) = 0;         // line number in the source XML file

};

class FastXml {
  public:
    virtual bool processXml(const char *inputData,unsigned int dataLen,FastXmlInterface *iface) = 0;
    virtual const char * getError(int &lineno) = 0; // report the reason for a parsing error, and the line number where it occurred.
};

FastXml *createFastXml(void);
void releaseFastXml(FastXml *f);

#endif

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx main.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

#include "mbed.h"
#include "fastxml.h"

DigitalOut myled(LED1);

class tmpr : public FastXmlInterface {
  public:
    virtual bool processElement(const char *name, int argc, const char **argv, const char *data, int lineno) {
      printf("::%s\n", name);
      if(strncmp(name, "tmpr", 4)==0) {
        printf("tmpr: %s\n", data);
      }
      return true;
    }
};

const char *code = {
  "<root>\r\n"
  "  <chan1>\r\n"
  "    <tmpr>23.7</tmpr>\r\n"
  "  </chan1>\r\n"
  "  <chan2>\r\n"
  "    <tmpr>23.7</tmpr>\r\n"
  "  </chan2>\r\n"
  "</root>\r\n"
};

int main() {
    FastXml *xml = createFastXml();
    FastXmlInterface *tmp = new tmpr();
    xml->processXml(code, strlen(code), tmp);
    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);
    }
}
XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

MBED: Super High Speed AnalogIn Class

.from: http://mbed.org/users/shintamainjp/libraries/HighSpeedAnalogIn/lm3z05

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx HighSpeedAnalogIn.cpp XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

#include "HighSpeedAnalogIn.h"

HighSpeedAnalogIn *HighSpeedAnalogIn::instance;
int HighSpeedAnalogIn::refcnt = 0;

HighSpeedAnalogIn::HighSpeedAnalogIn(PinName pin0, PinName pin1, PinName pin2, PinName pin3, PinName pin4, PinName pin5) {

    refcnt++;
    if (refcnt > 1) {
        error("Please do not use over an object.");
    }

    static const int sample_rate = 200000;
    static const int cclk_div = 1;

    int adc_clk_freq = CLKS_PER_SAMPLE * sample_rate;
    int m = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
    int n = (LPC_SC->PLL0CFG >> 16) + 1;
    int cclkdiv = LPC_SC->CCLKCFG + 1;
    int Fcco = (2 * m * XTAL_FREQ) / n;
    int cclk = Fcco / cclkdiv;

    LPC_SC->PCONP |= (1 << 12);
    LPC_SC->PCLKSEL0 &= ~(0x3 << 24);
    switch (cclk_div) {
        case 1:
            LPC_SC->PCLKSEL0 |= 0x1 << 24;
            break;
        case 2:
            LPC_SC->PCLKSEL0 |= 0x2 << 24;
            break;
        case 4:
            LPC_SC->PCLKSEL0 |= 0x0 << 24;
            break;
        case 8:
            LPC_SC->PCLKSEL0 |= 0x3 << 24;
            break;
        default:
            fprintf(stderr, "Warning: ADC CCLK clock divider must be 1, 2, 4 or 8. %u supplied.\n", cclk_div);
            fprintf(stderr, "Defaulting to 1.\n");
            LPC_SC->PCLKSEL0 |= 0x1 << 24;
            break;
    }
    int pclk = cclk / cclk_div;
    int clock_div = pclk / adc_clk_freq;

    if (clock_div > 0xFF) {
        fprintf(stderr, "Warning: Clock division is %u which is above 255 limit. Re-Setting at limit.\n", clock_div);
        clock_div = 0xFF;
    }
    if (clock_div == 0) {
        fprintf(stderr, "Warning: Clock division is 0. Re-Setting to 1.\n");
        clock_div = 1;
    }

    int _adc_clk_freq = pclk / clock_div;
    if (_adc_clk_freq > MAX_ADC_CLOCK) {
        fprintf(stderr, "Warning: Actual ADC sample rate of %u which is above %u limit\n", _adc_clk_freq / CLKS_PER_SAMPLE, MAX_ADC_CLOCK / CLKS_PER_SAMPLE);
        int max_div = 1;
        while ((pclk / max_div) > MAX_ADC_CLOCK) {
            max_div++;
        }
        fprintf(stderr, "Maximum recommended sample rate is %u\n", (pclk / max_div) / CLKS_PER_SAMPLE);
    }

    LPC_ADC->ADCR = ((clock_div - 1) << 8) | (1 << 21);
    LPC_ADC->ADCR &= ~0xFF;

    for (int i = 0; i < 8; i++) {
        _adc_data[i] = 0;
    }

    // Attach IRQ
    instance = this;
    NVIC_SetVector(ADC_IRQn, (uint32_t)&static_adcisr);

    // Disable global interrupt
    LPC_ADC->ADINTEN &= ~0x100;

    // Clock frequency.
    printf("Clock frequency:%d\n", _adc_clk_freq);

    // Actual sampling rate.
    printf("Actual sampling rate:%d\n", _adc_clk_freq / CLKS_PER_SAMPLE);
   
    int tmp = LPC_ADC->ADCR & ~(0x0F << 24);
    tmp |= ((0x0 & 7) << 24) | ((0x0 & 1) << 27);
    LPC_ADC->ADCR = tmp;
    LPC_ADC->ADCR |= (1 << 16);

    if (pin0 != NC) setup(pin0, 1);
    if (pin1 != NC) setup(pin1, 1);
    if (pin2 != NC) setup(pin2, 1);
    if (pin3 != NC) setup(pin3, 1);
    if (pin4 != NC) setup(pin4, 1);
    if (pin5 != NC) setup(pin5, 1);

    interrupt_state(pin0, 1);
}

HighSpeedAnalogIn::~HighSpeedAnalogIn() {
}

void HighSpeedAnalogIn::static_adcisr(void) {
    instance->adcisr();
}

void HighSpeedAnalogIn::adcisr(void) {
    uint32_t stat = LPC_ADC->ADSTAT;
    // Scan channels for over-run or done and update array
    if (stat & 0x0101) _adc_data[0] = LPC_ADC->ADDR0;
    if (stat & 0x0202) _adc_data[1] = LPC_ADC->ADDR1;
    if (stat & 0x0404) _adc_data[2] = LPC_ADC->ADDR2;
    if (stat & 0x0808) _adc_data[3] = LPC_ADC->ADDR3;
    if (stat & 0x1010) _adc_data[4] = LPC_ADC->ADDR4;
    if (stat & 0x2020) _adc_data[5] = LPC_ADC->ADDR5;
    if (stat & 0x4040) _adc_data[6] = LPC_ADC->ADDR6;
    if (stat & 0x8080) _adc_data[7] = LPC_ADC->ADDR7;
}

int HighSpeedAnalogIn::get_channel(PinName pin) {
    int ch;
    switch (pin) {
        case p15:// =p0.23 of LPC1768
            ch = 0;
            break;
        case p16:// =p0.24 of LPC1768
            ch = 1;
            break;
        case p17:// =p0.25 of LPC1768
            ch = 2;
            break;
        case p18:// =p0.26 of LPC1768
            ch = 3;
            break;
        case p19:// =p1.30 of LPC1768
            ch = 4;
            break;
        case p20:// =p1.31 of LPC1768
            ch = 5;
            break;
        default:
            ch = 0;
            break;
    }
    return ch;
}

uint32_t HighSpeedAnalogIn::get_data(PinName pin) {
    // If in burst mode and at least one interrupt enabled then
    // take all values from _adc_data
    if (LPC_ADC->ADINTEN & 0x3F) {
        return (_adc_data[get_channel(pin)]);
    } else {
        // Return current register value or last value from interrupt
        switch (pin) {
            case p15:// =p0.23 of LPC1768
                return ((LPC_ADC->ADINTEN & 0x01) ? _adc_data[0] : LPC_ADC->ADDR0);
            case p16:// =p0.24 of LPC1768
                return ((LPC_ADC->ADINTEN & 0x02) ? _adc_data[1] : LPC_ADC->ADDR1);
            case p17:// =p0.25 of LPC1768
                return ((LPC_ADC->ADINTEN & 0x04) ? _adc_data[2] : LPC_ADC->ADDR2);
            case p18:// =p0.26 of LPC1768:
                return ((LPC_ADC->ADINTEN & 0x08) ? _adc_data[3] : LPC_ADC->ADDR3);
            case p19:// =p1.30 of LPC1768
                return ((LPC_ADC->ADINTEN & 0x10) ? _adc_data[4] : LPC_ADC->ADDR4);
            case p20:// =p1.31 of LPC1768
                return ((LPC_ADC->ADINTEN & 0x20) ? _adc_data[5] : LPC_ADC->ADDR5);
            default:
                return 0;
        }
    }
}

// Enable or disable an HighSpeedAnalogIn pin
void HighSpeedAnalogIn::setup(PinName pin, int state) {
    int ch = get_channel(pin);
    if ((state & 1) == 1) {
        switch (pin) {
            case p15:// =p0.23 of LPC1768
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 14);
                LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 14;
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 14);
                LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 14;
                break;
            case p16:// =p0.24 of LPC1768
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 16);
                LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 16;
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 16);
                LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 16;
                break;
            case p17:// =p0.25 of LPC1768
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 18);
                LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 18;
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 18);
                LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 18;
                break;
            case p18:// =p0.26 of LPC1768:
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 20);
                LPC_PINCON->PINSEL1 |= (unsigned int)0x1 << 20;
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 20);
                LPC_PINCON->PINMODE1 |= (unsigned int)0x2 << 20;
                break;
            case p19:// =p1.30 of LPC1768
                LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 28);
                LPC_PINCON->PINSEL3 |= (unsigned int)0x3 << 28;
                LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 28);
                LPC_PINCON->PINMODE3 |= (unsigned int)0x2 << 28;
                break;
            case p20:// =p1.31 of LPC1768
                LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 30);
                LPC_PINCON->PINSEL3 |= (unsigned int)0x3 << 30;
                LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 30);
                LPC_PINCON->PINMODE3 |= (unsigned int)0x2 << 30;
                break;
            default:
                error("Invalid pin.");
                break;
        }
        // Select channel
        LPC_ADC->ADCR |= (1 << ch);
    } else {
        switch (pin) {
            case p15://=p0.23 of LPC1768
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 14);
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 14);
                break;
            case p16://=p0.24 of LPC1768
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 16);
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 16);
                break;
            case p17://=p0.25 of LPC1768
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 18);
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 18);
                break;
            case p18://=p0.26 of LPC1768:
                LPC_PINCON->PINSEL1 &= ~((unsigned int)0x3 << 20);
                LPC_PINCON->PINMODE1 &= ~((unsigned int)0x3 << 20);
                break;
            case p19://=p1.30 of LPC1768
                LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 28);
                LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 28);
                break;
            case p20://=p1.31 of LPC1768
                LPC_PINCON->PINSEL3 &= ~((unsigned int)0x3 << 30);
                LPC_PINCON->PINMODE3 &= ~((unsigned int)0x3 << 30);
                break;
            default:
                error("Invalid pin.");
                break;
        }
        LPC_ADC->ADCR &= ~(1 << ch);
    }
}

void HighSpeedAnalogIn::interrupt_state(PinName pin, int state) {
    int ch = get_channel(pin);
    if (state == 1) {
        LPC_ADC->ADINTEN &= ~0x100;
        LPC_ADC->ADINTEN |= 1 << ch;
        /* Enable the HighSpeedAnalogIn Interrupt */
        NVIC_EnableIRQ(ADC_IRQn);
    } else {
        LPC_ADC->ADINTEN &= ~(1 << ch);
        //Disable interrrupt if no active pins left
        if ((LPC_ADC->ADINTEN & 0xFF) == 0)
            NVIC_DisableIRQ(ADC_IRQn);
    }
}

float HighSpeedAnalogIn::read(PinName pin) {
    /*
     * Reset DONE and OVERRUN.
     *
     * bit 31 : DONE
     * bit 30 : OVERRUN
     */
    _adc_data[get_channel(pin)] &= ~(((uint32_t)0x01 << 31) | ((uint32_t)0x01 << 30));
    return (float)((get_data(pin) >> 4) & 0xFFF) / (float)0xFFF;
}

unsigned short HighSpeedAnalogIn::read_u16(PinName pin) {
    /*
     * Reset DONE and OVERRUN.
     *
     * bit 31 : DONE
     * bit 30 : OVERRUN
     */
    _adc_data[get_channel(pin)] &= ~(((uint32_t)0x01 << 31) | ((uint32_t)0x01 << 30));
    return ((get_data(pin) >> 4) & 0xFFF);
}

XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx HighSpeedAnalogIn.h XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx

#ifndef HIGH_SPEED_ANALOG_IN_H
#define HIGH_SPEED_ANALOG_IN_H

#include "mbed.h"

class HighSpeedAnalogIn {
public:

    HighSpeedAnalogIn(PinName pin0, PinName pin1 = NC, PinName pin2 = NC, PinName pin3 = NC, PinName pin4 = NC, PinName pin5 = NC);
    ~HighSpeedAnalogIn();
    float read(PinName pin);
    unsigned short read_u16(PinName pin);

private:

    HighSpeedAnalogIn();
    uint32_t _adc_data[8];

    static const int XTAL_FREQ = 12000000;
    static const int MAX_ADC_CLOCK = 13000000;
    static const int CLKS_PER_SAMPLE = 64;
   
    static HighSpeedAnalogIn *instance;
    static int refcnt;

    static void static_adcisr(void);

    int get_channel(PinName pin);
    uint32_t get_data(PinName pin);
    void adcisr(void);
    void setup(PinName pin, int state);
    void interrupt_state(PinName pin, int state);
};

#endif
XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx EOF XxXxXxXxXxXxXxXxXxXxXxXxXxXxXxXx