Example #1
0
        public static IntPtr initializeInterrupts(uint interruptIndex, bool watcher,
            ref int status)
        {
            //Check to see if we are already allocated, or if we have already allocated 8.
            if (Interrupts[interruptIndex] != null)
            {
                status = HALErrorConstants.RESOURCE_IS_ALLOCATED;
                return IntPtr.Zero;
            }
            if (interruptIndex >= NumInterrupts)
            {
                status = HALErrorConstants.NO_AVAILABLE_RESOURCES;
                return IntPtr.Zero;
            }

            Interrupt interrupt = new Interrupt
            {
                Callback = null,
                Watcher = watcher,
                Pin = -1,
            };
            status = HALErrorConstants.NiFpga_Status_Success;
            Interrupts[interruptIndex] = interrupt;
            //Returns + 1. See GetInterrupts comments for the reason.
            return (IntPtr)interruptIndex + 1;
        }
Example #2
0
 private static void enableInterruptsDigital(Interrupt interrupt, ref int status)
 {
     interrupt.DictCallback = (k, v) =>
     {
         //Since the NotifyDict will fire even if the state is the same,
         //We ignore if the state is the same.
         if (v == interrupt.PreviousState)
             return;
         //True => false, Falling
         if (interrupt.PreviousState)
         {
             //Set previous state, so next trigger will work.
             interrupt.PreviousState = v;
             //If we dont fire on down, return
             if (!interrupt.FireOnDown)
                 return;
             //Set out timestamps
             interrupt.FallingTimestamp = SimHooks.GetFPGATimestamp();
             interrupt.RisingTimestamp = 0;
         }
         else
         {
             interrupt.PreviousState = v;
             //If we dont fire on up, return
             if (!interrupt.FireOnUp)
                 return;
             interrupt.RisingTimestamp = SimHooks.GetFPGATimestamp();
             interrupt.FallingTimestamp = 0;
         }
         //Call our callback in a new thread. This is what the FPGA does as well.
         new Thread(() =>
         {
             interrupt.Callback((uint)interrupt.Pin, interrupt.Param);
         }).Start();
     };
     //Set our previous state, and register
     interrupt.PreviousState = DIO[interrupt.Pin].Value;
     var dio = DIO[interrupt.Pin];
     dio.Register(nameof(dio.Value), interrupt.DictCallback);
 }
Example #3
0
        private static uint WaitForInterruptAnalog(Interrupt interrupt, double timeout, bool ignorePrevious, ref int status)
        {
            object lockObject = new object();

            AnalogTriggerData trigData = SimData.AnalogTrigger[interrupt.Pin];

            //Store the previous state of the interrupt, so we can check for rising or falling edges
            interrupt.PreviousState = trigData.GetTriggerValue(interrupt.AnalogType, ref status);


            interrupt.DictCallback = (k, val) =>
            {
                //V is new analog value
                int status2 = 0;
                bool v = trigData.GetTriggerValue(interrupt.AnalogType, ref status2);
                //If no change, do nothing
                if (v == interrupt.PreviousState)
                    return;
                //If its a falling change, and we dont fire on falling return
                if (interrupt.PreviousState && !interrupt.FireOnDown)
                    return;
                //If its a rising change, and we dont fire on rising return.
                if (!interrupt.PreviousState && !interrupt.FireOnUp)
                    return;
                //Otherwise pulse the lock.
                lock (lockObject)
                {
                    Monitor.PulseAll(lockObject);
                }
            };

            //Register our interrupt with the NotifyDict
            var aIn = AnalogIn[trigData.AnalogPin];
            aIn.Register(nameof(aIn.Voltage), interrupt.DictCallback);

            WaitResult retVal = WaitResult.Timeout;
            //We are using a lock to wait for the interrupt.
            lock (lockObject)
            {
                bool timedout = !Monitor.Wait(lockObject, TimeSpan.FromSeconds(timeout));
                //Cancel the interrupt, because we don't want it to fire again.
                aIn.Cancel(nameof(aIn.Voltage), interrupt.DictCallback);
                if (timedout)
                {
                    retVal = WaitResult.Timeout;
                }
                else
                {
                    //True => false, Falling
                    if (interrupt.PreviousState)
                    {
                        //Set our return value and our timestamps
                        retVal = WaitResult.FallingEdge;
                        interrupt.FallingTimestamp = SimHooks.GetFPGATimestamp();
                        interrupt.RisingTimestamp = 0;
                    }
                    else
                    {
                        retVal = WaitResult.RisingEdge;
                        interrupt.RisingTimestamp = SimHooks.GetFPGATimestamp();
                        interrupt.FallingTimestamp = 0;
                    }
                }
            }

            return (uint)retVal;
        }
Example #4
0
        private static void enableInterruptsAnalog(Interrupt interrupt, ref int status)
        {
            AnalogTriggerData trigData = SimData.AnalogTrigger[interrupt.Pin];

            interrupt.DictCallback = (k, val) =>
            {

                int status2 = 0;
                bool v = trigData.GetTriggerValue(interrupt.AnalogType, ref status2);
                //Since the NotifyDict will fire even if the state is the same,
                //We ignore if the state is the same.
                if (v == interrupt.PreviousState)
                    return;
                //True => false, Falling
                if (interrupt.PreviousState)
                {
                    //Set previous state, so next trigger will work.
                    interrupt.PreviousState = v;
                    //If we dont fire on down, return
                    if (!interrupt.FireOnDown)
                        return;
                    //Set out timestamps
                    interrupt.FallingTimestamp = SimHooks.GetFPGATimestamp();
                    interrupt.RisingTimestamp = 0;
                }
                else
                {
                    interrupt.PreviousState = v;
                    //If we dont fire on up, return
                    if (!interrupt.FireOnUp)
                        return;
                    interrupt.RisingTimestamp = SimHooks.GetFPGATimestamp();
                    interrupt.FallingTimestamp = 0;
                }
                //Call our callback in a new thread. This is what the FPGA does as well.
                new Thread(() =>
                {
                    interrupt.Callback((uint)interrupt.Pin, interrupt.Param);
                }).Start();
            };
            //Set our previous state, and register
            interrupt.PreviousState = trigData.GetTriggerValue(interrupt.AnalogType, ref status);
            var aIn = AnalogIn[trigData.AnalogPin];
            aIn.Register(nameof(aIn.Voltage), interrupt.DictCallback);
        }
Example #5
0
        private static uint WaitForInterruptDigital(Interrupt interrupt, double timeout, bool ignorePrevious)
        {
            object lockObject = new object();

            //Store the previous state of the interrupt, so we can check for rising or falling edges
            interrupt.PreviousState = DIO[interrupt.Pin].Value;

            interrupt.DictCallback = (k, v) =>
            {
                //If no change, do nothing
                if (v == interrupt.PreviousState)
                    return;
                //If its a falling change, and we dont fire on falling return
                if (interrupt.PreviousState && !interrupt.FireOnDown)
                    return;
                //If its a rising change, and we dont fire on rising return.
                if (!interrupt.PreviousState && !interrupt.FireOnUp)
                    return;
                //Otherwise pulse the lock.
                lock (lockObject)
                {
                    Monitor.PulseAll(lockObject);
                }
            };

            //Register our interrupt with the NotifyDict
            var dio = DIO[interrupt.Pin];
            dio.Register(nameof(dio.Value), interrupt.DictCallback);

            WaitResult retVal = WaitResult.Timeout;
            //We are using a lock to wait for the interrupt.
            lock (lockObject)
            {
                bool timedout = !Monitor.Wait(lockObject, TimeSpan.FromSeconds(timeout));
                //Cancel the interrupt, because we don't want it to fire again.
                dio.Cancel(nameof(dio.Value), interrupt.DictCallback);
                if (timedout)
                {
                    retVal = WaitResult.Timeout;
                }
                else
                {
                    //True => false, Falling
                    if (interrupt.PreviousState)
                    {
                        //Set our return value and our timestamps
                        retVal = WaitResult.FallingEdge;
                        interrupt.FallingTimestamp = SimHooks.GetFPGATimestamp();
                        interrupt.RisingTimestamp = 0;
                    }
                    else
                    {
                        retVal = WaitResult.RisingEdge;
                        interrupt.RisingTimestamp = SimHooks.GetFPGATimestamp();
                        interrupt.FallingTimestamp = 0;
                    }
                }
            }

            return (uint)retVal;
        }