Simple guitar tuner

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
adurand
Date:
Mon Oct 24 23:03:27 2011 +0000
Child:
1:ae7d0cf78b3e
Commit message:

Changed in this revision

ADC_full/adc.cpp Show annotated file Show diff for this revision Revisions of this file
ADC_full/adc.h Show annotated file Show diff for this revision Revisions of this file
NokiaLCD/NokiaLCD.cpp Show annotated file Show diff for this revision Revisions of this file
NokiaLCD/NokiaLCD.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADC_full/adc.cpp	Mon Oct 24 23:03:27 2011 +0000
@@ -0,0 +1,439 @@
+/* mbed Library - ADC
+ * Copyright (c) 2010, sblandford
+ * released under MIT license http://mbed.org/licence/mit
+ */
+#include "mbed.h"
+#include "adc.h"
+
+
+ADC *ADC::instance;
+
+ADC::ADC(int sample_rate, int cclk_div)
+    {
+
+    int i, adc_clk_freq, pclk, clock_div, max_div=1;
+
+    //Work out CCLK
+    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;
+
+    //Power up the ADC        
+    LPC_SC->PCONP |= (1 << 12);
+    //Set clock at cclk / 1.
+    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;
+    }
+    pclk = cclk / cclk_div;
+    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;
+    }
+
+    _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);
+        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 ) |    //Clkdiv
+        ( 1 << 21 );                  //A/D operational
+
+    //Default no channels enabled
+    LPC_ADC->ADCR &= ~0xFF;
+    //Default NULL global custom isr
+    _adc_g_isr = NULL;
+    //Initialize arrays
+    for (i=7; i>=0; i--) {
+        _adc_data[i] = 0;
+        _adc_isr[i] = NULL;
+    }
+
+
+    //* Attach IRQ
+    instance = this;
+    NVIC_SetVector(ADC_IRQn, (uint32_t)&_adcisr);
+
+    //Disable global interrupt
+    LPC_ADC->ADINTEN &= ~0x100;
+
+};
+
+void ADC::_adcisr(void)
+{
+    instance->adcisr();
+}
+
+
+void ADC::adcisr(void)  
+{
+    uint32_t stat;
+    int chan;
+
+    // Read status
+    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;
+
+    // Channel that triggered interrupt
+    chan = (LPC_ADC->ADGDR >> 24) & 0x07;
+    //User defined interrupt handlers
+    if (_adc_isr[chan] != NULL)
+        _adc_isr[chan](_adc_data[chan]);
+    if (_adc_g_isr != NULL)
+        _adc_g_isr(chan, _adc_data[chan]); 
+    return;
+}
+
+int ADC::_pin_to_channel(PinName pin) {
+    int chan;
+    switch (pin) {
+        case p15://=p0.23 of LPC1768
+        default:
+            chan=0;
+            break;
+        case p16://=p0.24 of LPC1768
+            chan=1;
+            break;
+        case p17://=p0.25 of LPC1768
+            chan=2;
+            break;
+        case p18://=p0.26 of LPC1768
+            chan=3;
+            break;
+        case p19://=p1.30 of LPC1768
+            chan=4;
+            break;
+        case p20://=p1.31 of LPC1768
+            chan=5;
+            break;
+    }
+    return(chan);
+}
+
+PinName ADC::channel_to_pin(int chan) {
+    const PinName pin[8]={p15, p16, p17, p18, p19, p20, p15, p15};
+    
+    if ((chan < 0) || (chan > 5))
+        fprintf(stderr, "ADC channel %u is outside range available to MBED pins.\n", chan);
+    return(pin[chan & 0x07]);
+} 
+
+
+int ADC::channel_to_pin_number(int chan) {
+    const int pin[8]={15, 16, 17, 18, 19, 20, 0, 0};
+    
+    if ((chan < 0) || (chan > 5))
+        fprintf(stderr, "ADC channel %u is outside range available to MBED pins.\n", chan);
+    return(pin[chan & 0x07]);
+} 
+
+
+uint32_t ADC::_data_of_pin(PinName pin) {
+    //If in burst mode and at least one interrupt enabled then
+    //take all values from _adc_data
+    if (burst() && (LPC_ADC->ADINTEN & 0x3F)) {
+        return(_adc_data[_pin_to_channel(pin)]);
+    } else {
+        //Return current register value or last value from interrupt
+        switch (pin) {
+            case p15://=p0.23 of LPC1768
+            default:
+                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);
+        }
+    }
+}
+
+//Enable or disable an ADC pin
+void ADC::setup(PinName pin, int state) {
+    int chan;    
+    chan=_pin_to_channel(pin);
+    if ((state & 1) == 1) {
+        switch(pin) {
+            case p15://=p0.23 of LPC1768
+            default:
+                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;
+        }
+        //Only one channel can be selected at a time if not in burst mode
+        if (!burst()) LPC_ADC->ADCR &= ~0xFF;
+        //Select channel
+        LPC_ADC->ADCR |= (1 << chan);
+    }
+    else {
+        switch(pin) {
+            case p15://=p0.23 of LPC1768
+            default:
+                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;
+        }
+        LPC_ADC->ADCR &= ~(1 << chan);
+    }
+}
+//Return channel enabled/disabled state
+int ADC::setup(PinName pin) {
+    int chan;
+    
+    chan = _pin_to_channel(pin);
+    return((LPC_ADC->ADCR & (1 << chan)) >> chan);
+}
+
+//Select channel already setup
+void ADC::select(PinName pin) {
+    int chan;
+    
+    //Only one channel can be selected at a time if not in burst mode
+    if (!burst()) LPC_ADC->ADCR &= ~0xFF;
+    //Select channel
+    chan = _pin_to_channel(pin);
+    LPC_ADC->ADCR |= (1 << chan);
+}
+
+//Enable or disable burst mode
+void ADC::burst(int state) {
+    if ((state & 1) == 1) {
+        if (startmode(0) != 0)
+            fprintf(stderr, "Warning. startmode is %u. Must be 0 for burst mode.\n", startmode(0));
+        LPC_ADC->ADCR |= (1 << 16);
+    }
+    else 
+        LPC_ADC->ADCR &= ~(1 << 16);
+}
+//Return burst mode state
+int  ADC::burst(void) {
+    return((LPC_ADC->ADCR & (1 << 16)) >> 16);
+}
+
+//Set startmode and edge
+void ADC::startmode(int mode, int edge) {
+    int lpc_adc_temp;
+    
+    //Reset start mode and edge bit, 
+    lpc_adc_temp = LPC_ADC->ADCR & ~(0x0F << 24);
+    //Write with new values
+    lpc_adc_temp |= ((mode & 7) << 24) | ((edge & 1) << 27);
+    LPC_ADC->ADCR = lpc_adc_temp;
+}
+
+//Return startmode state according to mode_edge=0: mode and mode_edge=1: edge
+int ADC::startmode(int mode_edge){
+    switch (mode_edge) {
+        case 0:
+        default:
+            return((LPC_ADC->ADCR >> 24) & 0x07);
+        case 1:
+            return((LPC_ADC->ADCR >> 27) & 0x01);
+    }
+}
+
+//Start ADC conversion
+void ADC::start(void) {
+    startmode(1,0);
+}
+
+
+//Set interrupt enable/disable for pin to state
+void ADC::interrupt_state(PinName pin, int state) {
+    int chan;
+    
+    chan = _pin_to_channel(pin);
+    if (state == 1) {
+        LPC_ADC->ADINTEN &= ~0x100;
+        LPC_ADC->ADINTEN |= 1 << chan;
+        /* Enable the ADC Interrupt */
+        NVIC_EnableIRQ(ADC_IRQn);
+    } else {
+        LPC_ADC->ADINTEN &= ~( 1 << chan );
+        //Disable interrrupt if no active pins left
+        if ((LPC_ADC->ADINTEN & 0xFF) == 0)
+            NVIC_DisableIRQ(ADC_IRQn);
+    }
+}
+
+//Return enable/disable state of interrupt for pin
+int ADC::interrupt_state(PinName pin) {
+    int chan;
+        
+    chan = _pin_to_channel(pin);
+    return((LPC_ADC->ADINTEN >> chan) & 0x01);
+}
+
+
+//Attach custom interrupt handler replacing default
+void ADC::attach(void(*fptr)(void)) {
+    //* Attach IRQ
+    NVIC_SetVector(ADC_IRQn, (uint32_t)fptr);
+}
+
+//Restore default interrupt handler
+void ADC::detach(void) {
+    //* Attach IRQ
+    instance = this;
+    NVIC_SetVector(ADC_IRQn, (uint32_t)&_adcisr);
+}
+
+
+//Append interrupt handler for pin to function isr
+void ADC::append(PinName pin, void(*fptr)(uint32_t value)) {
+    int chan;
+        
+    chan = _pin_to_channel(pin);
+    _adc_isr[chan] = fptr;
+}
+
+//Append interrupt handler for pin to function isr
+void ADC::unappend(PinName pin) {
+    int chan;
+        
+    chan = _pin_to_channel(pin);
+    _adc_isr[chan] = NULL;
+}
+
+//Unappend global interrupt handler to function isr
+void ADC::append(void(*fptr)(int chan, uint32_t value)) {
+    _adc_g_isr = fptr;
+}
+
+//Detach global interrupt handler to function isr
+void ADC::unappend() {
+    _adc_g_isr = NULL;
+}
+
+//Set ADC offset
+void offset(int offset) {
+    LPC_ADC->ADTRM &= ~(0x07 << 4);
+    LPC_ADC->ADTRM |= (offset & 0x07) << 4;
+}
+
+//Return current ADC offset
+int offset(void) {
+    return((LPC_ADC->ADTRM >> 4) & 0x07);
+}
+
+//Return value of ADC on pin
+int ADC::read(PinName pin) {
+    //Reset DONE and OVERRUN flags of interrupt handled ADC data
+    _adc_data[_pin_to_channel(pin)] &= ~(((uint32_t)0x01 << 31) | ((uint32_t)0x01 << 30));
+    //Return value
+    return((_data_of_pin(pin) >> 4) & 0xFFF);
+}
+
+//Return DONE flag of ADC on pin
+int ADC::done(PinName pin) {
+    return((_data_of_pin(pin) >> 31) & 0x01);
+}
+
+//Return OVERRUN flag of ADC on pin
+int ADC::overrun(PinName pin) {
+    return((_data_of_pin(pin) >> 30) & 0x01);
+}
+
+int ADC::actual_adc_clock(void) {
+    return(_adc_clk_freq);
+}
+
+int ADC::actual_sample_rate(void) {
+    return(_adc_clk_freq / CLKS_PER_SAMPLE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ADC_full/adc.h	Mon Oct 24 23:03:27 2011 +0000
@@ -0,0 +1,131 @@
+/* mbed Library - ADC
+ * Copyright (c) 2010, sblandford
+ * released under MIT license http://mbed.org/licence/mit
+ */
+
+#ifndef MBED_ADC_H
+#define MBED_ADC_H
+ 
+#include "mbed.h"
+#define XTAL_FREQ       12000000
+#define MAX_ADC_CLOCK   13000000
+#define CLKS_PER_SAMPLE 64
+
+class ADC {
+public:
+
+    //Initialize ADC with ADC maximum sample rate of
+    //sample_rate and system clock divider of cclk_div
+    //Maximum recommened sample rate is 184000
+    ADC(int sample_rate, int cclk_div);
+
+    //Enable/disable ADC on pin according to state
+    //and also select/de-select for next conversion
+    void setup(PinName pin, int state);
+
+    //Return enabled/disabled state of ADC on pin
+    int setup(PinName pin);
+
+    //Enable/disable burst mode according to state
+    void burst(int state);
+
+    //Select channel already setup
+    void select(PinName pin);
+
+    //Return burst mode enabled/disabled
+    int burst(void);
+
+    /*Set start condition and edge according to mode:
+    0 - No start (this value should be used when clearing PDN to 0).
+    1 - Start conversion now.
+    2 - Start conversion when the edge selected by bit 27 occurs on the P2.10 / EINT0 / NMI pin.
+    3 - Start conversion when the edge selected by bit 27 occurs on the P1.27 / CLKOUT /
+        USB_OVRCRn / CAP0.1 pin.
+    4 - Start conversion when the edge selected by bit 27 occurs on MAT0.1. Note that this does
+        not require that the MAT0.1 function appear on a device pin.
+    5 - Start conversion when the edge selected by bit 27 occurs on MAT0.3. Note that it is not
+        possible to cause the MAT0.3 function to appear on a device pin.
+    6 - Start conversion when the edge selected by bit 27 occurs on MAT1.0. Note that this does
+        not require that the MAT1.0 function appear on a device pin.
+    7 - Start conversion when the edge selected by bit 27 occurs on MAT1.1. Note that this does
+        not require that the MAT1.1 function appear on a device pin.
+    When mode >= 2, conversion is triggered by edge:
+    0 - Rising edge
+    1 - Falling edge
+    */
+    void startmode(int mode, int edge);
+    
+    //Return startmode state according to mode_edge=0: mode and mode_edge=1: edge
+    int startmode(int mode_edge);
+    
+    //Start ADC conversion
+    void start(void);
+
+    //Set interrupt enable/disable for pin to state
+    void interrupt_state(PinName pin, int state);
+    
+    //Return enable/disable state of interrupt for pin
+    int interrupt_state(PinName pin);
+
+    //Attach custom interrupt handler replacing default
+    void attach(void(*fptr)(void));
+
+    //Restore default interrupt handler
+    void detach(void);
+
+    //Append custom interrupt handler for pin
+    void append(PinName pin, void(*fptr)(uint32_t value));
+
+    //Unappend custom interrupt handler for pin
+    void unappend(PinName pin);
+
+    //Append custom global interrupt handler
+    void append(void(*fptr)(int chan, uint32_t value));
+
+    //Unappend custom global interrupt handler
+    void unappend(void);
+
+    //Set ADC offset to a value 0-7
+    void offset(int offset);
+    
+    //Return current ADC offset
+    int offset(void);
+
+    //Return value of ADC on pin
+    int read(PinName pin);
+
+    //Return DONE flag of ADC on pin
+    int done(PinName pin);
+    
+    //Return OVERRUN flag of ADC on pin
+    int overrun(PinName pin);
+
+    //Return actual ADC clock
+    int actual_adc_clock(void);
+    
+    //Return actual maximum sample rate
+    int actual_sample_rate(void);
+
+    //Return pin ID of ADC channel
+    PinName channel_to_pin(int chan);
+
+    //Return pin number of ADC channel
+    int channel_to_pin_number(int chan);
+
+
+private:
+    int _pin_to_channel(PinName pin);
+    uint32_t _data_of_pin(PinName pin);
+
+    int _adc_clk_freq;
+    void adcisr(void);
+    static void _adcisr(void);
+    static ADC *instance;
+    
+    uint32_t _adc_data[8];
+    void(*_adc_isr[8])(uint32_t value);
+    void(*_adc_g_isr)(int chan, uint32_t value);
+    void(*_adc_m_isr)(void);
+};
+
+#endif
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NokiaLCD/NokiaLCD.cpp	Mon Oct 24 23:03:27 2011 +0000
@@ -0,0 +1,458 @@
+/* mbed Nokia LCD Library
+ * Copyright (c) 2007-2010, sford
+ */
+
+#include "NokiaLCD.h"
+
+#include "mbed.h"
+
+#define NOKIALCD_ROWS 16
+#define NOKIALCD_COLS 16
+#define NOKIALCD_WIDTH 130
+#define NOKIALCD_HEIGHT 132
+#define NOKIALCD_FREQUENCY 5000000
+
+NokiaLCD::NokiaLCD(PinName mosi, PinName sclk, PinName cs, PinName rst, LCDType type)
+        : _spi(mosi, NC, sclk)
+        , _rst(rst)
+        , _cs(cs) {
+
+    _type = type;
+
+    _row = 0;
+    _column = 0;
+    _foreground = 0x00FFFFFF;
+    _background = 0x00000000;
+
+    reset();
+}
+
+void NokiaLCD::reset() {
+
+    // setup the SPI interface and bring display out of reset
+    _cs = 1;
+    _rst = 0;
+    _spi.format(9);
+    _spi.frequency(NOKIALCD_FREQUENCY);
+    wait_ms(1);
+    _rst = 1;
+    wait_ms(1);
+
+    _cs = 0;
+
+    switch (_type) {
+        case LCD6100:
+            command(0xCA); // display control
+            data(0);
+            data(32);
+            data(0);
+            command(0xBB);
+            data(1);
+            command(0xD1); // oscillator on
+            command(0x94); // sleep out
+            command(0x20); // power control
+            data(0x0F);
+            command(0xA7); // invert display
+            command(0x81); // Voltage control
+            data(39);      // contrast setting: 0..63
+            data(3);       // resistance ratio
+            wait_ms(1);
+            command(0xBC);
+            data(0);
+            data(1);
+            data(4);
+            command(0xAF);  // turn on the display
+            break;
+            
+        case LCD6610:
+            command(0xCA);    // display control
+            data(0);
+            data(32);
+            data(0);
+            command(0xBB);
+            data(1);
+            command(0xD1); // oscillator on
+            command(0x94); // sleep out
+            command(0x20); // power control
+            data(0x0F);
+            command(0xA7); // invert display
+            command(0x81); // Voltage control
+            data(39);      // contrast setting: 0..63
+            data(3);       // resistance ratio
+            wait_ms(1);
+            command(0xBC);
+            data(0);
+            data(0);
+            data(2);
+            command(0xAF);  // turn on the display
+            break;
+            
+        case PCF8833:
+            command(0x11);  // sleep out
+            command(0x3A);  // column mode
+            data(0x05);
+            command(0x36);  // madctl
+            data(0x60);     // vertical RAM, flip x
+            command(0x25);  // setcon
+            data(0x30);// contrast 0x30
+            wait_ms(2);
+            command(0x29);//DISPON
+            command(0x03);//BSTRON
+            break;
+    }
+
+    _cs = 1;
+
+    cls();
+}
+
+void NokiaLCD::command(int value) {
+    _spi.write(value & 0xFF);
+}
+
+void NokiaLCD::data(int value) {
+    _spi.write(value | 0x100);
+}
+
+void NokiaLCD::_window(int x, int y, int width, int height) {
+    int x1 = x + 0;
+    int y1 = y + 0;
+    int x2 = x1 + width - 1;
+    int y2 = y1 + height - 1;
+
+    switch (_type) {
+        case LCD6100:
+        case LCD6610:
+            command(0x15); // column
+            data(x1);
+            data(x2);
+            command(0x75); // row
+            data(y1);
+            data(y2);
+            command(0x5C); // start write to ram
+            break;
+        case PCF8833:
+            command(0x2A);  // column
+            data(x1);
+            data(x2);
+            command(0x2B); // row
+            data(y1);
+            data(y2);
+            command(0x2C); // start write to ram
+            break;
+    }
+}
+
+void NokiaLCD::_putp(int colour) {
+    int gr = ((colour >> 20) & 0x0F)
+             | ((colour >> 8 ) & 0xF0);
+    int nb = ((colour >> 4 ) & 0x0F);
+    data(nb);
+    data(gr);
+}
+
+const unsigned char FONT8x8[97][8] = {
+    0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, // columns, rows, num_bytes_per_char
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // space 0x20
+    0x30,0x78,0x78,0x30,0x30,0x00,0x30,0x00, // !
+    0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00, // "
+    0x6C,0x6C,0xFE,0x6C,0xFE,0x6C,0x6C,0x00, // #
+    0x18,0x3E,0x60,0x3C,0x06,0x7C,0x18,0x00, // $
+    0x00,0x63,0x66,0x0C,0x18,0x33,0x63,0x00, // %
+    0x1C,0x36,0x1C,0x3B,0x6E,0x66,0x3B,0x00, // &
+    0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00, // '
+    0x0C,0x18,0x30,0x30,0x30,0x18,0x0C,0x00, // (
+    0x30,0x18,0x0C,0x0C,0x0C,0x18,0x30,0x00, // )
+    0x00,0x66,0x3C,0xFF,0x3C,0x66,0x00,0x00, // *
+    0x00,0x30,0x30,0xFC,0x30,0x30,0x00,0x00, // +
+    0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x30, // ,
+    0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00, // -
+    0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00, // .
+    0x03,0x06,0x0C,0x18,0x30,0x60,0x40,0x00, // / (forward slash)
+    0x3E,0x63,0x63,0x6B,0x63,0x63,0x3E,0x00, // 0 0x30
+    0x18,0x38,0x58,0x18,0x18,0x18,0x7E,0x00, // 1
+    0x3C,0x66,0x06,0x1C,0x30,0x66,0x7E,0x00, // 2
+    0x3C,0x66,0x06,0x1C,0x06,0x66,0x3C,0x00, // 3
+    0x0E,0x1E,0x36,0x66,0x7F,0x06,0x0F,0x00, // 4
+    0x7E,0x60,0x7C,0x06,0x06,0x66,0x3C,0x00, // 5
+    0x1C,0x30,0x60,0x7C,0x66,0x66,0x3C,0x00, // 6
+    0x7E,0x66,0x06,0x0C,0x18,0x18,0x18,0x00, // 7
+    0x3C,0x66,0x66,0x3C,0x66,0x66,0x3C,0x00, // 8
+    0x3C,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00, // 9
+    0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x00, // :
+    0x00,0x18,0x18,0x00,0x00,0x18,0x18,0x30, // ;
+    0x0C,0x18,0x30,0x60,0x30,0x18,0x0C,0x00, // <
+    0x00,0x00,0x7E,0x00,0x00,0x7E,0x00,0x00, // =
+    0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x00, // >
+    0x3C,0x66,0x06,0x0C,0x18,0x00,0x18,0x00, // ?
+    0x3E,0x63,0x6F,0x69,0x6F,0x60,0x3E,0x00, // @ 0x40
+    0x18,0x3C,0x66,0x66,0x7E,0x66,0x66,0x00, // A
+    0x7E,0x33,0x33,0x3E,0x33,0x33,0x7E,0x00, // B
+    0x1E,0x33,0x60,0x60,0x60,0x33,0x1E,0x00, // C
+    0x7C,0x36,0x33,0x33,0x33,0x36,0x7C,0x00, // D
+    0x7F,0x31,0x34,0x3C,0x34,0x31,0x7F,0x00, // E
+    0x7F,0x31,0x34,0x3C,0x34,0x30,0x78,0x00, // F
+    0x1E,0x33,0x60,0x60,0x67,0x33,0x1F,0x00, // G
+    0x66,0x66,0x66,0x7E,0x66,0x66,0x66,0x00, // H
+    0x3C,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // I
+    0x0F,0x06,0x06,0x06,0x66,0x66,0x3C,0x00, // J
+    0x73,0x33,0x36,0x3C,0x36,0x33,0x73,0x00, // K
+    0x78,0x30,0x30,0x30,0x31,0x33,0x7F,0x00, // L
+    0x63,0x77,0x7F,0x7F,0x6B,0x63,0x63,0x00, // M
+    0x63,0x73,0x7B,0x6F,0x67,0x63,0x63,0x00, // N
+    0x3E,0x63,0x63,0x63,0x63,0x63,0x3E,0x00, // O
+    0x7E,0x33,0x33,0x3E,0x30,0x30,0x78,0x00, // P 0x50
+    0x3C,0x66,0x66,0x66,0x6E,0x3C,0x0E,0x00, // Q
+    0x7E,0x33,0x33,0x3E,0x36,0x33,0x73,0x00, // R
+    0x3C,0x66,0x30,0x18,0x0C,0x66,0x3C,0x00, // S
+    0x7E,0x5A,0x18,0x18,0x18,0x18,0x3C,0x00, // T
+    0x66,0x66,0x66,0x66,0x66,0x66,0x7E,0x00, // U
+    0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x00, // V
+    0x63,0x63,0x63,0x6B,0x7F,0x77,0x63,0x00, // W
+    0x63,0x63,0x36,0x1C,0x1C,0x36,0x63,0x00, // X
+    0x66,0x66,0x66,0x3C,0x18,0x18,0x3C,0x00, // Y
+    0x7F,0x63,0x46,0x0C,0x19,0x33,0x7F,0x00, // Z
+    0x3C,0x30,0x30,0x30,0x30,0x30,0x3C,0x00, // [
+    0x60,0x30,0x18,0x0C,0x06,0x03,0x01,0x00, // \ (back slash)
+    0x3C,0x0C,0x0C,0x0C,0x0C,0x0C,0x3C,0x00, // ]
+    0x08,0x1C,0x36,0x63,0x00,0x00,0x00,0x00, // ^
+    0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, // _
+    0x18,0x18,0x0C,0x00,0x00,0x00,0x00,0x00, // ` 0x60
+    0x00,0x00,0x3C,0x06,0x3E,0x66,0x3B,0x00, // a
+    0x70,0x30,0x3E,0x33,0x33,0x33,0x6E,0x00, // b
+    0x00,0x00,0x3C,0x66,0x60,0x66,0x3C,0x00, // c
+    0x0E,0x06,0x3E,0x66,0x66,0x66,0x3B,0x00, // d
+    0x00,0x00,0x3C,0x66,0x7E,0x60,0x3C,0x00, // e
+    0x1C,0x36,0x30,0x78,0x30,0x30,0x78,0x00, // f
+    0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x7C, // g
+    0x70,0x30,0x36,0x3B,0x33,0x33,0x73,0x00, // h
+    0x18,0x00,0x38,0x18,0x18,0x18,0x3C,0x00, // i
+    0x06,0x00,0x06,0x06,0x06,0x66,0x66,0x3C, // j
+    0x70,0x30,0x33,0x36,0x3C,0x36,0x73,0x00, // k
+    0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00, // l
+    0x00,0x00,0x66,0x7F,0x7F,0x6B,0x63,0x00, // m
+    0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x00, // n
+    0x00,0x00,0x3C,0x66,0x66,0x66,0x3C,0x00, // o
+    0x00,0x00,0x6E,0x33,0x33,0x3E,0x30,0x78, // p
+    0x00,0x00,0x3B,0x66,0x66,0x3E,0x06,0x0F, // q
+    0x00,0x00,0x6E,0x3B,0x33,0x30,0x78,0x00, // r
+    0x00,0x00,0x3E,0x60,0x3C,0x06,0x7C,0x00, // s
+    0x08,0x18,0x3E,0x18,0x18,0x1A,0x0C,0x00, // t
+    0x00,0x00,0x66,0x66,0x66,0x66,0x3B,0x00, // u
+    0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x00, // v
+    0x00,0x00,0x63,0x6B,0x7F,0x7F,0x36,0x00, // w
+    0x00,0x00,0x63,0x36,0x1C,0x36,0x63,0x00, // x
+    0x00,0x00,0x66,0x66,0x66,0x3E,0x06,0x7C, // y
+    0x00,0x00,0x7E,0x4C,0x18,0x32,0x7E,0x00, // z
+    0x0E,0x18,0x18,0x70,0x18,0x18,0x0E,0x00, // {
+    0x0C,0x0C,0x0C,0x00,0x0C,0x0C,0x0C,0x00, // |
+    0x70,0x18,0x18,0x0E,0x18,0x18,0x70,0x00, // }
+    0x3B,0x6E,0x00,0x00,0x00,0x00,0x00,0x00, // ~
+    0x1C,0x36,0x36,0x1C,0x00,0x00,0x00,0x00
+}; // DEL
+
+void NokiaLCD::locate(int column, int row) {
+    _column = column;
+    _row = row;
+}
+
+void NokiaLCD::newline() {
+    _column = 0;
+    _row++;
+    if (_row >= _rows) {
+        _row = 0;
+    }
+}
+
+int NokiaLCD::_putc(int value) {
+    int x = _column * 8;  // FIXME: Char sizes
+    int y = _row * 8;
+    bitblit(x + 1, y + 1, 8, 8, (char*)&(FONT8x8[value - 0x1F][0]));
+
+    _column++;
+
+    if (_column >= NOKIALCD_COLS) {
+        _row++;
+        _column = 0;
+    }
+
+    if (_row >= NOKIALCD_ROWS) {
+        _row = 0;
+    }
+
+    return value;
+}
+
+void NokiaLCD::cls() {
+    fill(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT, _background);
+    _row = 0;
+    _column = 0;
+}
+
+
+void NokiaLCD::window(int x, int y, int width, int height) {
+    _cs = 0;
+    _window(x, y, width, height);
+    _cs = 1;
+}
+
+void NokiaLCD::putp(int colour) {
+    _cs = 0;
+    _putp(colour);
+    _cs = 1;
+}
+
+void NokiaLCD::pixel(int x, int y, int colour) {
+    _cs = 0;
+    _window(x, y, 1, 1);
+     switch (_type) {
+        case LCD6100:
+        case PCF8833:
+           
+                _putp(colour);
+            
+            break;
+        case LCD6610:
+           
+                int r4 = (colour >> (16 + 4)) & 0xF;
+                int g4 = (colour >> (8 + 4)) & 0xF;
+                int b4 = (colour >> (0 + 4)) & 0xF;
+                int d1 = (r4 << 4) | g4;
+                int d2 = (b4 << 4) | r4;
+                int d3 = (g4 << 4) | b4;
+                data(d1); 
+                data(d2);   
+                data(d3);
+            
+            break;
+            }
+    _cs = 1;
+}
+
+void NokiaLCD::fill(int x, int y, int width, int height, int colour) {
+    _cs = 0;
+    _window(x, y, width, height);
+    switch (_type) {
+        case LCD6100:
+        case PCF8833:
+            for (int i=0; i<width*height; i++) {
+                _putp(colour);
+            }
+            break;
+        case LCD6610:
+            for (int i=0; i<width*height/2; i++) {
+                int r4 = (colour >> (16 + 4)) & 0xF;
+                int g4 = (colour >> (8 + 4)) & 0xF;
+                int b4 = (colour >> (0 + 4)) & 0xF;
+                int d1 = (r4 << 4) | g4;
+                int d2 = (b4 << 4) | r4;
+                int d3 = (g4 << 4) | b4;
+                data(d1); 
+                data(d2);   
+                data(d3);
+            }
+            break;
+    }
+    _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
+    _cs = 1;
+}
+
+void NokiaLCD::blit(int x, int y, int width, int height, const int* colour) {
+    _cs = 0;
+    _window(x, y, width, height);
+
+    switch (_type) {
+        case LCD6100:
+        case PCF8833:
+            for (int i=0; i<width*height; i++) {
+                 _putp(colour[i]);
+             }
+             break;
+        case LCD6610:
+            for (int i=0; i<width*height/2; i++) {
+                int r41 = (colour[i*2] >> (16 + 4)) & 0xF;
+                int g41 = (colour[i*2] >> (8 + 4)) & 0xF;
+                int b41 = (colour[i*2] >> (0 + 4)) & 0xF;
+           
+                int r42 = (colour[i*2+1] >> (16 + 4)) & 0xF;
+                int g42 = (colour[i*2+1] >> (8 + 4)) & 0xF;
+                int b42 = (colour[i*2+1] >> (0 + 4)) & 0xF;   
+                int d1 = (r41 << 4) | g41;
+                int d2 = (b41 << 4) | r42;
+                int d3 = (g42 << 4) | b42;               
+                   data(d1); 
+                data(d2); 
+                data(d3); 
+            }
+            break;
+     }            
+    _window(0, 0, NOKIALCD_WIDTH, NOKIALCD_HEIGHT);
+    _cs = 1;
+}
+
+void NokiaLCD::bitblit(int x, int y, int width, int height, const char* bitstream) {
+    _cs = 0;
+    _window(x, y, width, height);
+
+    switch (_type) {
+        case LCD6100:
+        case PCF8833:
+            for (int i=0; i<height*width; i++) {
+                int byte = i / 8;
+                int bit = i % 8;
+                int colour = ((bitstream[byte] << bit) & 0x80) ? _foreground : _background;
+                _putp(colour);
+            }
+            break;
+        case LCD6610:
+            for(int i=0; i<height*width/2; i++) {
+                int byte1 = (i*2) / 8;
+                int bit1 = (i*2) % 8;   
+                int colour1 = ((bitstream[byte1] << bit1) & 0x80) ? _foreground : _background;
+                int byte2 = (i*2+1) / 8;
+                int bit2 = (i*2+1) % 8;   
+                int colour2 = ((bitstream[byte2] << bit2) & 0x80) ? _foreground : _background;
+    
+                int r41 = (colour1 >> (16 + 4)) & 0xF;
+                int g41 = (colour1 >> (8 + 4)) & 0xF;
+                int b41 = (colour1 >> (0 + 4)) & 0xF;
+           
+                int r42 = (colour2 >> (16 + 4)) & 0xF;
+                int g42 = (colour2 >> (8 + 4)) & 0xF;
+                int b42 = (colour2 >> (0 + 4)) & 0xF;   
+                int d1 = (r41 << 4) | g41;
+                int d2 = (b41 << 4) | r42;
+                int d3 = (g42 << 4) | b42;               
+                   data(d1); 
+                data(d2); 
+                data(d3); 
+            }
+            break;
+     }
+    _window(0, 0, _width, _height);
+    _cs = 1;
+}
+
+void NokiaLCD::foreground(int c) {
+    _foreground = c;
+}
+
+void NokiaLCD::background(int c) {
+    _background = c;
+}
+
+int NokiaLCD::width() {
+    return NOKIALCD_WIDTH;
+}
+
+int NokiaLCD::height() {
+    return NOKIALCD_HEIGHT;
+}
+
+int NokiaLCD::columns() {
+    return NOKIALCD_COLS;
+}
+
+int NokiaLCD::rows() {
+    return NOKIALCD_ROWS;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NokiaLCD/NokiaLCD.h	Mon Oct 24 23:03:27 2011 +0000
@@ -0,0 +1,151 @@
+/* mbed NokiaLCD Library, for a 130x130 Nokia colour LCD
+ * Copyright (c) 2007-2010, sford
+ *
+ * Permission is hereby granted, 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.
+ */
+
+#ifndef MBED_NOKIALCD_H
+#define MBED_NOKIALCD_H
+
+#include "mbed.h"
+
+/** An interface for the 130x130 Nokia Mobile phone screens
+ *
+ * @code
+ * #include "mbed.h"
+ * #include "NokiaLCD.h"
+ *
+ * NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::6610); // mosi, sclk, cs, rst, type
+ *
+ * int main() {
+ *     lcd.printf("Hello World!");
+ * }
+ * @endcode
+ */
+class NokiaLCD : public Stream {
+
+public:
+    /** LCD panel format */
+    enum LCDType {
+        LCD6100     /**< Nokia 6100, as found on sparkfun board (default) */
+        , LCD6610   /**< Nokia 6610, as found on olimex board */
+        , PCF8833
+    };
+
+    /** Create and Nokia LCD interface, using a SPI and two DigitalOut interfaces
+     *
+     * @param mosi SPI data out
+     * @param sclk SPI clock
+     * @param cs Chip Select (DigitalOut)
+     * @param rst Reset (DigitalOut)
+     * @param type The LCDType to select driver chip variants
+     */
+    NokiaLCD(PinName mosi, PinName sclk, PinName cs, PinName rst, LCDType type = LCD6100);
+
+#if DOXYGEN_ONLY
+    /** Write a character to the LCD
+     *
+     * @param c The character to write to the display
+     */
+    int putc(int c);
+
+    /** Write a formated string to the LCD
+     *
+     * @param format A printf-style format string, followed by the
+     *               variables to use in formating the string.
+     */
+    int printf(const char* format, ...);
+#endif
+
+    /** Locate to a screen column and row
+     *
+     * @param column  The horizontal position from the left, indexed from 0
+     * @param row     The vertical position from the top, indexed from 0
+     */
+    void locate(int column, int row);
+
+    /** Clear the screen and locate to 0,0 */
+    void cls();
+
+    /** Set a pixel on te screen
+     * 
+     * @param x horizontal position from left
+     * @param y vertical position from top
+     * @param colour 24-bit colour in format 0x00RRGGBB
+     */
+    void pixel(int x, int y, int colour);
+    
+    /** Fill an area of the screen
+     * 
+     * @param x horizontal position from left
+     * @param y vertical position from top
+     * @param width width in pixels
+     * @param height height in pixels
+     * @param colour 24-bit colour in format 0x00RRGGBB
+     */    
+    void fill(int x, int y, int width, int height, int colour);
+
+    void blit(int x, int y, int width, int height, const int* colour);
+    void bitblit(int x, int y, int width, int height, const char* bitstream);
+
+    int width();
+    int height();
+    int columns();
+    int rows();
+
+    void reset();
+
+    /** Set the foreground colour
+     * 
+     * @param c 24-bit colour
+     */
+    void foreground(int c);
+
+    /** Set the background colour
+     * 
+     * @param c 24-bit colour
+     */
+    void background(int c);
+
+protected:
+    virtual void _window(int x, int y, int width, int height);
+    virtual void _putp(int colour);
+
+    void command(int value);
+    void data(int value);
+
+    void newline();
+    virtual int _putc(int c);
+    virtual int _getc() {
+        return 0;
+    }
+    void putp(int v);
+    void window(int x, int y, int width, int height);
+
+    SPI _spi;
+    DigitalOut _rst;
+    DigitalOut _cs;
+
+    LCDType _type;
+    int _row, _column, _rows, _columns, _foreground, _background, _width, _height;
+};
+
+#endif
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Oct 24 23:03:27 2011 +0000
@@ -0,0 +1,177 @@
+    //////////////////////////////////////////
+  //                                          //
+//    Guitar Tuner via Goertzel's Algorithm     //
+//          Created by: Andrew Durand           //
+  //                                          //
+    //////////////////////////////////////////
+
+#include "mbed.h"
+#include "adc.h"
+#include "NokiaLCD.h"
+
+#define PI 3.1415
+#define SAMPLE_RATE 24000
+
+DigitalOut led_low(LED1);
+DigitalOut led_ok(LED2);
+DigitalOut led_high(LED4);
+InterruptIn button1(p12);
+
+//LCD and Other Random Variables
+NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
+int string_select = 0;
+float high, high1, high2, high3, high4, high5, high6, high7, high8, in_tune, in_tune1, in_tune2, in_tune3,
+low, low1, low2, low3, low4, low5, low6, low7, low8, note;
+char* key;
+int Counter = 0;
+int Buffer[6000];
+
+float goertzelFilter(int samples[], float freq, int N) {
+    float s_prev = 0.0;
+    float s_prev2 = 0.0;
+    float coeff,normalizedfreq,power,s,k;
+    int i;
+    normalizedfreq = freq / SAMPLE_RATE;
+    coeff = 2*cos(2*PI*normalizedfreq);
+    for (i=0; i<N; i++) {
+        s = samples[i] + coeff * s_prev - s_prev2;
+        s_prev2 = s_prev;
+        s_prev = s;
+    }
+    power = s_prev2*s_prev2+s_prev*s_prev-coeff*s_prev*s_prev2;
+    return power;
+}
+
+ADC adc(SAMPLE_RATE, 1);
+
+void sample_audio(int chan, uint32_t value) {
+    Buffer[Counter] = adc.read(p20);
+    Counter += 1;
+}
+
+void button1_pressed() {
+    string_select++;
+    if (string_select > 5) string_select = 0;
+}
+
+int main() {
+    //Interupt for Switching Strings
+    button1.mode(PullDown);
+    button1.rise(&button1_pressed);
+
+    //Setup LCD
+    lcd.background(0xF0000F);
+    lcd.cls();
+
+    while (1) {
+
+        switch (string_select) {
+            case 0:
+                note = 82;
+                key= "E2";
+                break;
+            case 1:
+                note = 110;
+                key= "A2";
+                break;
+            case 2:
+                note = 147;
+                key= "D3";
+                break;
+            case 3:
+                note = 196;
+                key= "G3";
+                break;
+            case 4:
+                note = 247;
+                key= "B3";
+                break;
+            case 5:
+                note = 330;
+                key= "E4";
+                break;
+        }
+
+        //Prepare for burst mode on all ADC pins and set up interrupt handler (using ADC library from Simon Blandford
+        adc.append(sample_audio);
+        adc.startmode(0,0);
+        adc.burst(1);
+        adc.setup(p20,1);
+
+        //start the interrupt and wait for about 4096 samples
+        adc.interrupt_state(p20,1);
+        wait(.2);
+
+        //Finsh up - Unset pin 20
+        adc.interrupt_state(p20,0);
+        adc.setup(p20,0);
+        int actual_rate = adc.actual_sample_rate();
+
+        //for debugging tell the terminal sample rate and how many samples we took
+        printf("Requested max sample rate is %u, actual max sample rate is %u.\n",
+               SAMPLE_RATE, actual_rate);
+        printf("We did %i samples\n",Counter);
+
+        high1 = goertzelFilter(Buffer, (note+18), Counter);
+        high2 = goertzelFilter(Buffer, (note+16), Counter);
+        high3 = goertzelFilter(Buffer, (note+14), Counter);
+        high4 = goertzelFilter(Buffer, (note+12), Counter);
+        high5 = goertzelFilter(Buffer, (note+10), Counter);
+        high6 = goertzelFilter(Buffer, (note+8), Counter);
+        high7 = goertzelFilter(Buffer, (note+6), Counter);
+        high8 = goertzelFilter(Buffer, (note+4), Counter);
+        in_tune1 =  goertzelFilter(Buffer, (note+0.5), Counter);
+        in_tune2 =  goertzelFilter(Buffer, note, Counter);
+        in_tune3 =  goertzelFilter(Buffer, (note-0.5), Counter);
+        low1 = goertzelFilter(Buffer, (note-4), Counter);
+        low2 = goertzelFilter(Buffer, (note-6), Counter);
+        low3 = goertzelFilter(Buffer, (note-8), Counter);
+        low4 = goertzelFilter(Buffer, (note-10), Counter);
+        low5 = goertzelFilter(Buffer, (note-12), Counter);
+        low6 = goertzelFilter(Buffer, (note-14), Counter);
+        low7 = goertzelFilter(Buffer, (note-16), Counter);
+        low8 = goertzelFilter(Buffer, (note-18), Counter);
+
+        in_tune = (in_tune1 + in_tune2 + in_tune3)/3;
+        high = (high1 + high2 + high3 + high4 + high5 + high6 + high7 + high8)/8;
+        low = (low1 + low2 + low3 + low4 + low5 + low6 + low7 + low8)/8;
+
+        if ((in_tune > high) && (in_tune > low)) {
+            led_high = 0;
+            led_ok = 1;
+            led_low = 0;
+        } else if (high > in_tune) {
+            led_high = 1;
+            led_ok = 0;
+            led_low = 0;
+        } else if (low > in_tune) {
+            led_high = 0;
+            led_ok = 0;
+            led_low = 1;
+        } else {
+            led_high = 0;
+            led_ok = 0;
+            led_low = 0;
+
+        }
+
+        // Display on the LCD
+        lcd.locate(0,1);
+        lcd.printf("::Guitar Tuner::");
+        lcd.locate(0,3);
+        lcd.printf("Tuning String: %i", (6-string_select));
+        lcd.locate(0,5);
+        lcd.printf("%s at %i Hz",key, (int) note);
+        lcd.locate(5,7);
+        if (led_ok) lcd.printf("In Tune!");
+        else if (led_low) lcd.printf("Too Low ");
+        else if (led_high) lcd.printf("Too High");
+        else lcd.printf("~~~~~");
+
+        Counter = 0;
+
+    }
+
+
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Oct 24 23:03:27 2011 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/49a220cc26e0