digitalinout and interrupts

14 Oct 2010 . Edited: 16 Oct 2010

Hey guys, I have deleted the post that I had here as I have narrowed down my problem somewhat.

I am going to deal with just one problem for the minute.

Essentially, the problem I am having is I am getting an interrupt when I shouldnt be.

In the code below, I am using a digitalinout pin and outputting a small sequence at which point I change the pin to an input and enable the interrupts.

Now, physically i have this pin connected to ground through a resistor and I also have the pin internally set to PullDown mode. But I get a rising edge interrupt somehow when I shouldnt be getting any. As the code below executes, I only appear to be getting rising edge interrupts as only led3 is toggling and not led4. I'd say falling edge triggers are still occurring but they are happening when the interrupts are set to NULL. Any ideas as to what the cause could be?

Thanks.

 

#include "mbed.h"
#pragma once
#define PINGPIN p22

DigitalInOut PingPin(PINGPIN);
InterruptIn Pinterrupt(PINGPIN);
DigitalOut led3(LED3); //these LEDs are used to indicate when an interrupt occurs.
DigitalOut led4(LED4);

void start_timing();
void set_time();
void set_interrupts()
    {
         Pinterrupt.fall(start_timing);
         Pinterrupt.rise(set_time);
    }
void disable_interrupts()
    {
         Pinterrupt.fall(NULL);
         Pinterrupt.rise(NULL);
    
    } 


    
void start_timing()
 {
   led3 = !led3;

 }

void set_time() 
{
    led4 = !led4;

}

int main() {
   led3 = led4 = 0;
   for(;;)
   {
    wait(1);
    
    disable_interrupts();
    PingPin.mode(PullDown);
    Pinterrupt.mode(PullDown);
    PingPin.output(); //set pingpin as output
    PingPin = 0;
        
    PingPin = 0; //output initiation sequence of 0 1 0 to the rangefinder
    wait_us(2);
    PingPin = 1;
    wait_us(5);
    PingPin = 0;
   
    //PingPin.input(); //set as input
    set_interrupts();
   }  
}
16 Oct 2010

Ok I have resolved my problems with my program by working around the above issue. If anyone else has a program in which they need to slectively enable or disable the interrupts, I had success by doing this with a flag. I.e. keep your interrupt functions enabled but selectively control their functionality with your own binary flag.

 

Regards,

Greg

16 Oct 2010

Greg,

It sounds like you found a solution to your problem already but this might help. The interrupts for Pinterrupt are still active even when the pin is in output mode, meaning every time you toggle the pin high you will get a rising edge interrupt, same for falling.

The easiest way to ignore the interrupts during your initial output would be to use a flag to indicate when you want to pay attention to the events, and set this after you finish the start sequence. You would clear it after detecting the falling edge.

Another way would be to control the interrupt enable bit for the pin directly, be sure to clear the interrupt status bit before setting the interrupt enable or you will get an immediate interrupt if the status is set. See the LPC1768 users manual chapter 9 for more details.

Cheers,

Don

16 Oct 2010

Hi Don, thanks for the reply, Yeah I am doing exactly as you suggested in the first part of your reply. That was the solution that I was using. I believe that you are right in relation to my problem. I wasnt aware that the interrupt status had to be cleared. Thanks for the heads up.

18 Oct 2010

Hi, Don, I am working on attaching another peripheral to the mbed which outputs a PWM modulated signal. In relation to what you mentioned before, how do I go about clearing the status bit? Is there an "mbed" way to do this?

 

Thanks,

Greg

18 Oct 2010

Greg (or is it Jason?), The structure you will most likely be wanting is LPC_GPIOINT and either the IO0IntClr or IO2IntClr register. Format would be LPC_GPIOINT->IO2IntClr = 1<<YOUR_BIT_NUMBER_HERE. Before you can determine the right register or bit you will have to look them up in the schematic for the MBED to determine the actual LPC port number an bit the pin is on.

Simon has responded a number of times on the subject of register manipulation in the past, try searching for "poking registers" to find some good examples.

For a quick start, check out the user manual for the LPC1768, chapter 9, section 9.5.6.10. I would go ahead and read all of chapter 9 for some good background. Then check out http://mbed.org/projects/libraries/svn/mbed/trunk/LPC1768/LPC17xx.h#L178 for a description of all the defined structures and register names. Skip down to the end to see where they are actually defined.

Hope this is what you were looking for,

Don

18 Oct 2010

Will do thanks alot, I think my difficulty in sourcing the interrupt info was that I was looking at the wrong document!

My lecturer who owns the mbed has it registered in his name, I'm Greg, the student who is using it for my project.

18 Oct 2010

You're welcome, it took me a while to find the right manual as well, kept looking in the "DataSheet" which is where I expected it to be. The User Manual was right there the whole time, just didn't think it was what I wanted.

Don

19 Oct 2010

Greg,

Take a look in gpio.c and gpioirq.c :-

http://mbed.org/users/AjK/programs/SOWB/lg489e/docs/files.html