Dependencies:   mbed

main.cpp

Committer:
Bobty
Date:
2010-01-05
Revision:
0:f75c555dc52b

File content as of revision 0:f75c555dc52b:

// analog input p20 (ADC0[5], pin 3) test with stats

#include "mbed.h"

// Code from Simon Ford 2010-01-04
void mbedAdcInit()
{
    // power on, clk divider /4
    LPC_SC->PCONP |= (1 << 12);          
    LPC_SC->PCLKSEL0 &= ~(0x3 << 24);    

    // software-controlled ADC settings
    LPC_ADC->ADCR = (0 << 0) // SEL: 0 = no channels selected
              | (200 << 8)    // CLKDIV: PCLK max ~= 25MHz, /25 to give safe 1MHz
              | (0 << 16)    // BURST: 0 = software control 
              | (0 << 17)    // CLKS: not applicable 
              | (1 << 21)    // PDN: 1 = operational
              | (0 << 24)    // START: 0 = no start
              | (0 << 27);   // EDGE: not applicable

    // setup P1_31 as sel 3 (ADC), mode 2 (no pull)    
    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;

}

unsigned int mbedGetVal()
{
    // Select channel and start conversion
    LPC_ADC->ADCR &= ~0xFF;
    LPC_ADC->ADCR |= 1 << 5; // ADC0[5]
    LPC_ADC->ADCR |= 1 << 24;

    // Repeatedly get the sample data until DONE bit
    unsigned int data;
    do {
       data = LPC_ADC->ADGDR;
    } while ((data & ((unsigned int)1 << 31)) == 0);
       data = LPC_ADC->ADGDR;

    // Stop conversion    
    LPC_ADC->ADCR &= ~(1 << 24);

    return data;
}

// Code gleaned from MBED forum
void DispInfo()
{
    printf("SystemCoreClock = %d Hz\n", SystemCoreClock);
 
    int Fin = 12000000; // 12MHz XTAL
    
    printf("PLL Registers:\n");
    printf(" - PLL0CFG = 0x%08X\n", LPC_SC->PLL0CFG);
    printf(" - CLKCFG  = 0x%08X\n", LPC_SC->CCLKCFG);
    
    int M = (LPC_SC->PLL0CFG & 0xFFFF) + 1;
    int N = (LPC_SC->PLL0CFG >> 16) + 1;
    int CCLKDIV = LPC_SC->CCLKCFG + 1;

    printf("Clock Variables:\n");
    printf(" - Fin = %d\n", Fin);
    printf(" - M   = %d\n", M);
    printf(" - N   = %d\n", N);
    printf(" - CCLKDIV = %d\n", CCLKDIV);

    int Fcco = (2 * M * 12000000) / N;
    int CCLK = Fcco / CCLKDIV;

    printf("Clock Results:\n");    
    printf(" - Fcco = %d\n", Fcco);
    printf(" - CCLK = %d\n", CCLK);    

    printf("PCLKSEL0 = 0x%08x\n",  LPC_SC->PCLKSEL0);    
    printf("PCLKSEL1 = 0x%08x\n",  LPC_SC->PCLKSEL1);    
    
}

int main() {

    const int NUM_LOOPS = 100;
    const int NUM_SAMPS = 1024;
    
    mbedAdcInit();
    wait_ms(100);

    DispInfo();

    // Table of deviation counts
    const int DEV_HIST_SIZE = 10;
    int devTable[DEV_HIST_SIZE+1];
    for (int i = 0; i < DEV_HIST_SIZE+1; i++)
        devTable[i] = 0;

    // Run many times
    double mean;
    double lowestStdDev = 1024;
    double highestStdDev = 0;
    double sumForMean = 0;
    for (int j = 0; j < NUM_LOOPS; j++)
    {
        // Get ADC readings
        unsigned int adgdrVals[NUM_SAMPS];
        unsigned int samples[NUM_SAMPS];
        for(int i=0; i<NUM_SAMPS; i++) {
            adgdrVals[i] = mbedGetVal();
            samples[i] = (adgdrVals[i] >> 5) & 0x3ff;
            wait_ms(1);
        }
    
        // Calculate mean
        double localSum = 0;
        for(int i=0; i<NUM_SAMPS; i++)
            localSum += samples[i];
        double localMean = localSum / NUM_SAMPS;
        sumForMean += localSum;
        
        // Calculate std-dev sum
        double sumSqrDiffs = 0;
        for(int i=0; i<NUM_SAMPS; i++)
            sumSqrDiffs += (samples[i] - localMean) * (samples[i] - localMean);
            
        // Calculate stdDev and see if low/high
        double stdDev = sqrt(sumSqrDiffs / NUM_SAMPS);
        if (lowestStdDev > stdDev)
            lowestStdDev = stdDev;
        if (highestStdDev < stdDev)
            highestStdDev = stdDev;
        
        // Histogram of values
        for (int i = 0; i < NUM_SAMPS; i++)
        {
            int outOfBoundsDist = int(fabs(samples[i] - localMean));
            if (outOfBoundsDist >= DEV_HIST_SIZE)
                devTable[DEV_HIST_SIZE]++;
            else
                devTable[outOfBoundsDist]++;
        }
        
        // Show results that are out of bounds
        printf("Results out of bounds for pass %d:\n", j);
        for(int i=0; i<NUM_SAMPS; i++) {
            if (fabs(samples[i] - localMean) > 5)
                printf("%5d, 0x%04X, %d\n", i, adgdrVals[i], samples[i]);
        }
    }
    
    // Show overall stats
    mean = sumForMean / NUM_SAMPS / NUM_LOOPS;
    printf("Mean: %.2f\n", mean);
    printf("Std-dev (highest, lowest): %.2f, %.2f\n", highestStdDev, lowestStdDev);
    printf("Deviation Table\n");
    printf("Dist.\tCount\n");
    for (int i = 0; i < DEV_HIST_SIZE+1; i++)
        printf("%s%d\t%d\n", i == DEV_HIST_SIZE ? "> " : "", i, devTable[i]);
}