Making a general OnInterrupt handler

The standard OnInterrupt handler is passed the parameters (uint port, uint state, DateTime time). It looks like the port is “defined” for a particular board eg Di13 = 42, Di1 = 18, Di-0= 20.
If so is it possible to have a single general OnInterrupt handler with a switch on port number?

Will Domino Di13 always be port 42 on a Domino?

The reason I’m asking is I’m making a pseudo Finite State Machine where the real world inputs are responsible for initiating state changes. It would be quite neat to wrap it all up in a single general handler.

Mike

Yes, this is is completely okay and not bad practice at all.

It may not be bad practice, but is it good practice?

Now I’m light on C# experience. I have looked on MS .NETFM and couldn’t drop on an answer but…
I understand how to make a port an interrupt pin. I tried a couple of hacks to add a second pin to an existing interrupt handler. But I just generated errors along the lines of there’s already a handler.

What syntax should I be using?

Yes it is a good practice, keeping in mind that the one handler will take care of more than one pin so there is a slight overhead to figure out which pin is the interrupt source. In most cases, this is okay.

Here is a sample, I have not looked at the glitch (debounce) handling for this. So the same event may fire multiple times. This is on the Cobra, you may want to use some other routine in the absence of a display (blink RED, blink GREEN).


using System.Threading;
using Microsoft.SPOT;
using System;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Media;
using GHIElectronics.NETMF.FEZ;
using Microsoft.SPOT.Hardware;
using CobraLCD;

namespace MFConsoleApplication1
{
    public class Program
    {
        static Bitmap LCD;
        static Font MyFont;

        public static void Main()
        {
            MyFont = Resources.GetFont(Resources.FontResources.small);

            LCD = new Bitmap(SystemMetrics.ScreenWidth, SystemMetrics.ScreenHeight);
            LCD.Clear();
            LCD.DrawText("Interrupt Mon", MyFont, Colors.Red, 10, 10);
            LCD.Flush();

            InterruptPort Port1 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO19, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);
            InterruptPort Port2 = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.IO18, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeBoth);

            //Event handler is the same for both ports
            Port1.OnInterrupt += new NativeEventHandler(Portx_OnInterrupt);
            Port2.OnInterrupt += new NativeEventHandler(Portx_OnInterrupt);
            Thread.Sleep(Timeout.Infinite);
        }

        static void Portx_OnInterrupt(uint port, uint state, DateTime time)
        {
            //figure out the port
            switch (port)
            {
                case  19 :
                    Display(port);
                    break;
                case 18:
                    Display(port);
                    break;
                default:
                    Display(0);
                    break;
            }
                
          
        }

        static void Display(uint port)
        {
            LCD.Clear();
            LCD.DrawText("Interrupt source is Port : " + port, MyFont, Colors.Red, 10, 10);
            LCD.Flush();
        }
    }
}


HTH.

-Rajesh

Rajesh,

Thanks for the code kick start. I’ll try it tonight after work.

Mike

I’m sure the information is in the documentation but I though I would leave a breadcrumb trail.

Of the Domino Interrupt ports Port returns the following values:

An0 28
An1 26
An2 24
An3 22
Di0 20
Di1 18
Di2 33
Di3 31
Di4 19
Di5 2
Di6 7
Di11 41
Di12 40
Di13 42

Ive not tested the remaining Interrupt enabled ports (LDR, LED, UEXT{10, 3, 4, 5, 6, 7, 8, 9}).

Mike

I didn’t think the LED pin was exposed, is it? LDR and UEXT obviously are.

Just a thought here - since I’m searching on this topic right now, and if I am someone else might also do so…

in the CASE statements, why hardcode these values?


switch ((Cpu.Pin)port)
{
case (Cpu.Pin)FEZ_Pin.Digital.Di0:
..... etc

works fine.

(did anyone else say “I hate magic numbers”? Well I do :slight_smile: )