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; }
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); }
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; }
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); }
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; }