Page 1 of 2

I/O pin interrupt

Posted: Mon Jun 22, 2015 7:20 am
by davecove
Can someone point me to an example of using an I/O pin to trigger an interrupt on a SBL2E please?

I looked at the titles of the examples that came with the NNDK and nothing seemed to cover that topic.

Dave

Re: I/O pin interrupt

Posted: Mon Jun 22, 2015 1:21 pm
by pbreed
I don't believe that any of the SBL2E module pins can be set up to generate an interrupt.

The SBL2E chip, or BOB can use the interrupt pins.

It might be possible to mess with the serial interrupts to detect a change on the UART1 CTS pin.
Its also possible to set the A/D converter in continuous operation mode and set limits that trigger interrupts.

How fast do you need the interrupt response?

Re: I/O pin interrupt

Posted: Mon Jun 22, 2015 2:03 pm
by davecove
Interrupt response doesn't need to be immediate... 50ms max I guess.

"Its also possible to set the A/D converter in continuous operation mode and set limits that trigger interrupts."

That's sounds like the ticket; any examples of that?

Dave

Re: I/O pin interrupt

Posted: Mon Jun 22, 2015 4:04 pm
by pbreed
Examples of that.. short answer is no...

I might get some time to prototype that late this week early next...

Paul

Re: I/O pin interrupt

Posted: Tue Jun 23, 2015 7:39 am
by davecove
I think I shot too high in my first post; going with an interrupt.

All I really want to do is sense when Pin 12 (UART1_RX) goes low (button push). I can do that in the main loop too, so how about an example of pin 12 being put into GPIO mode and then read as a digital input?

Dave

Re: I/O pin interrupt

Posted: Tue Jun 23, 2015 2:32 pm
by dciliske
Assuming you're not the person who called yesterday asking about this exact topic... You could use the PIT timer to post to a semaphore that a high priority task is pending on. You can then poll the state of the pin in this high priority task.

The PitTimer example for the SBL2e is almost this exact setup. Just set the frequency you want to poll at.

-Dan

Re: I/O pin interrupt

Posted: Tue Jun 23, 2015 3:32 pm
by davecove
Nope, not the person that called.

What example shows reading a pin for a button push? (with de-bounce? )

Dave

Re: I/O pin interrupt

Posted: Tue Jun 23, 2015 4:13 pm
by dciliske
Uh... you can use the PinIO class to interface with the header pins and read it that way. As for debouncing, you can use the afore mentioned PIT timer to set a semaphore in the ~1KHz range and do a threshold count debounce, where you require it to not change states for some period of time to be considered a valid transition (you can also do this in the interrupt itself, but this is probably more complex to write robustly).

-Dan

Re: I/O pin interrupt

Posted: Tue Jun 23, 2015 8:29 pm
by davecove
Where can I find an example of PinIO usage? I searched the NNDKProMan.pgf and didn't get any hits...

Dave

Re: I/O pin interrupt

Posted: Wed Jun 24, 2015 12:56 pm
by dciliske
Yea... it doesn't appear to be in the SBL2e manual. Or in the RuntimeLibraries manual, explicitly.

So, let's say you want to use Pin 7 as your button input. Here's what you would probably do for debouncing it. We'll assume that the pin is normally low and goes high when the button is pressed. Note, this is using the PitTimer example's pit sem code.

Code: Select all

/*------------------------------------------------------------------------------
 SBL2e Periodic Interrupt Timer (PIT) example
 This example will initialize a PIT timer to post a semaphonre every 50ms. The
 number of posts will then be counted to time an event such as 1600ms.
 *----------------------------------------------------------------------------*/


#include "predef.h"
#include <stdio.h>
#include <ctype.h>
#include <basictypes.h>
#include <serialirq.h>
#include <system.h>
#include <constants.h>
#include <ucos.h>
#include <netif.h>
#include <autoupdate.h>
#include <smarttrap.h>
#include <pins.h>
#include <pinconstant.h>
#include "pit1_sem.h"


#define DEBOUNCE_MIN    50
#define INPUT_PIN       7

extern "C" {
    void UserMain(void * pd);
}

const char * AppName = "SBL2e PIT Timer Ex";

/*-------------------------------------------------------------------
 * UserMain
 *------------------------------------------------------------------*/
void UserMain(void * pd)
{
    SimpleUart(0, SystemBaud);
    assign_stdio(0);
    InitializeStack();
    OSChangePrio(MAIN_PRIO);
    EnableAutoUpdate();

#ifndef _DEBUG
    EnableSmartTraps();
#endif

    iprintf("Application started\n");

    OS_SEM MyPit1Sem;
    OSSemInit( &MyPit1Sem, 0 );

    // Create a timer to trigger every 50ms. Then determine the number of
	// "ticks" it will take to reach 1600ms.
	// 20 ticks per second = one tick every 50ms. 1600ms/50ms = 32 ticks.
    const int Pit1TicksPerSec = 1000;

    // level 6, prio 3
    InitPit1Semaphore( &MyPit1Sem, Pit1TicksPerSec, 6, 3 );

    Pins[7].function(PINX_GPIO);
    int stableState = Pins[INPUT_PIN];
    int lastRead = stableState;
    int thisRead;
    int debounceCount = 0;

    while (1)
    {
        OSSemPend( &MyPit1Sem, TICKS_PER_SECOND * 10 );

        thisRead = Pins[INPUT_PIN];

        if (thisRead == lastRead) {
            debounceCount++;
            if (debounceCount == DEBOUNCE_MIN) {
                stableState = thisRead;
                iprintf("Button Pressed -- New State: %d", stableState);
            }
        }
        else {
            debounceCount = 1;
        }

        lastRead = thisRead;
    }
}
I haven't actually tested this specific iteration, but this should get you going.