Test for PinDetect library. Use constant "#define DIRECTINT" to compile two different versions of the program comparing the status registers related to the interrupt states when using the PinDetect Libraries vs the InterruptIn library.

Dependencies:   C12832_lcd PinDetect mbed

Fork of Bootcamp-Pushbutton_Debounce_Interrupt by avnish aggarwal

main.cpp

Committer:
nleoni
Date:
2014-02-17
Revision:
2:aca93337a0e1
Parent:
1:d5bb7a2e46c2

File content as of revision 2:aca93337a0e1:

#include "mbed.h"
#include "PinDetect.h"
#include "C12832_lcd.h"

//Napoleon Leoni
//***************************************************************************//
//Test program for debounce on interrupt. Here I test the PinDetect Library  //
//To check whether indeed the library is attaching the debounced pin to an   //
//interrupt. The conclusion as shown below is that it is NOT!, the PinDetect //
//has some nice features like key_pressed or key_pressedheld detection       //
//but they are all working on polling the specified debounced pin on a Timer //
//interrupt, which by default is set every 20 ms. This is not the same as    //
//trigering an Interrupt on a leading or trailing edge of GPIO pin           //
//
//
//                  TESTS RUN                                               //
// I print to the LCD three important LPC1768 registers: 
// ISER0..Interrupt set Enable register(address 0xE000E100), for this program 
// the important bits are #4..Timer 3 interrupt and #21 External interrupt 3. 
// Note that all GPIO interrupts are attached to the External Interrupt 3 
// hardware EINT3. contents of ISER0 are accesible via: *(NVIC->ISER)
//
// IntEnR..GPIO interrupt enable on rising, shows which pins are attached to EINT3 
// on their rising edge (these are only for mbed pins mapped to LPC pins on Port 0)
// its contents are available using th macro LPC_GPIOINT->IO0IntEnR
// IntEnF..GPIO interrupt enable on falling, shows which pins are attached to EINT3 
// on their falling edge (these are only for mbed pins mapped to LPC pins on Port 0)
// its contents are available using th macro LPC_GPIOINT->IO0IntEnF
// 
// Note the mapping below of MBED pins to the IntEnR/IntEnF bits:
// IntEnR/IntEnF bit    LPC GPIO       MBED GPIO PIN   
// 0                    P[0].0          p9                              
// 1                    P[0].1          p10
// 4                    P[0].4          p30
// 5                    P[0].5          p29
// 6                    P[0].6          p8
// 7                    P[0].7          p7
// 8                    P[0].8          p6
// 9                    P[0].9          p5
// 10                   P[0].10         p28
// 11                   P[0].11         p27
// 12                   P[0].12         p27
// 15                   P[0].15         p13
// 16                   P[0].16         p14
// 17                   P[0].17         p12
// 18                   P[0].18         p11
// 23                   P[0].23         p15
// 24                   P[0].24         p16
// 25                   P[0].25         p17
// 26                   P[0].26         p18
// 30                   P[0].30         p19
// 31                   P[0].31         p20
//***********************************************************************************
//   Test description                 Resulting Register Values                 Analysis
// 1 DIRECTINT not defined            ISER0       0x0000 0010                   No GPIO interrupts enabled nor attached
//   so only pinDetect(14)            IO0IntEnR   0x0000 0000                   only TIMER 3 Interrupt enabled so the pinDetect
//   is used                          IO0IntEnF   0x0000 0000                   libary is simply polling the pin on a timer interrupt and 
//                                                                              debouncing it. 
//
// 2 DIRECTINT defined                ISER0       0x0020 0010(when enabled)     GPIO interrupt is enabled and disabled periodically     
//                                                0x0000 0010(when disabled)    when disabled the joystick up/down motion does not trigger
//   so we define InterruptIn         IO0IntEnR   0x0080 0000                   LED1 as expected, however the pindetect functionality continues
//   on pins 12 and 15                IO0IntEnF   0x0002 0000                   to work a further confirmation that the library is not working with
//                                                                              an interrupt on the GPIO specified pin. Note that p15 is attached to 
//                                                                              a rising edge GPIO interrupt and p12 to a falling edge interrupt.
//***********************************************************************************

#define DIRECTINT //constant to compare interrupt registers when using pindetect vs. using InterrupIn library

DigitalOut myled(LED1);
DigitalOut myled2(LED2);
DigitalOut myled3(LED3);
DigitalOut myled4(LED4);
C12832_LCD lcd;

#ifdef DIRECTINT
InterruptIn down(p12);  // DOWN of joystickn note that mbed p12 corresponds to lpc P0[17], should appear as 0x0002 0000 in register LPC_GPIOINT->IO0IntEnR/F
InterruptIn fire(p15);  // up of joystickn note that mbed p15 corresponds to lpc P0[23], should appear as 0x0080 0000 in register LPC_GPIOINT->IO0IntEnR/F
#endif


PinDetect pb(p14);      // center of joystickn note that mbed p14 corresponds to lpc P0[16] should appear as 0x0001 0000 in register LPC_GPIOINT->IO0IntEnR/F

void ISR1() {           //interrupt service routine used to turn on LED 1 on rising edge of joystick up
    myled = 1;
}

void ISR2() {          //interrupt service routing used to turn off LED 1 on falling
    myled = 0;
}

// SPST Pushbutton debounced count demo using interrupts and callback
// no external PullUp resistor needed
// Pushbutton from P8 to GND.
// A pb hit generates an interrupt and activates the callback function
// after the switch is debounced

// Global count variable
int volatile count=0;

// Callback routine is interrupt activated by a debounced pb hit
void pb_hit_callback (void) {
    count++;
    myled4 = count & 0x01;
    myled3 = (count & 0x02)>>1;
    myled2 = (count & 0x04)>>2;
}

int main()
{
#ifdef DIRECTINT
   fire.rise(&ISR1);
   down.fall(&ISR2);
#endif    
    // Use internal pullup for pushbutton
    //pb.mode(PullUp);                              // don't do this for app board
    // Delay for initial pullup to take effect
    wait(.01);
    // Setup Interrupt callback function for a pb hit
    pb.attach_deasserted(&pb_hit_callback);
    // Start sampling pb input using interrupts
    pb.setSampleFrequency();

    //Blink myled in main routine forever while responding to pb changes
    // via interrupts that activate the callback counter function
    bool disableInterrupt=false;
    int counter=0,tdelay=10;
    while (1) {
        wait(1);
        lcd.cls();
        lcd.locate(0,1);
        lcd.printf("ISER0=%#010X",*(NVIC->ISER)); //NVIC->ISER holds the address of the ISER0 register
        lcd.locate(0,10);
        lcd.printf("IO0 INTEN R=%#010X",LPC_GPIOINT->IO0IntEnR); //This address holds GPIO interrupt attach on rise edge state.
        lcd.locate(0,20);
        lcd.printf("IO0 INTEN F=%#010X",LPC_GPIOINT->IO0IntEnF ); //This address holds GPIO interrupt attach on falling edge state

#ifdef DIRECTINT
        //This section of coe periodically (every 10 seconds) toggles the external interrupt 3 EINT3
        //state between enabled and disabled. This is the hardware interrupt used for th GPIO pins
        counter++;
        if(counter>=tdelay){
            disableInterrupt=!disableInterrupt;
            if(disableInterrupt)  NVIC_DisableIRQ(EINT3_IRQn);            //disable EINT3
            if(!disableInterrupt) NVIC_EnableIRQ(EINT3_IRQn);             //re-enable EINT3 
            counter=0;
        }
#endif        
    }

}