1use std::{fmt::Debug, time::Duration};
4
5use crate::{error::FPGAError, nifpga_sys::*, session::Session, types::FpgaBool};
6
7pub use crate::types::IrqSelection;
9
10pub const IRQ0: IrqSelection = IrqSelection::new(0);
11pub const IRQ1: IrqSelection = IrqSelection::new(1);
12pub const IRQ2: IrqSelection = IrqSelection::new(2);
13pub const IRQ3: IrqSelection = IrqSelection::new(3);
14pub const IRQ4: IrqSelection = IrqSelection::new(4);
15pub const IRQ5: IrqSelection = IrqSelection::new(5);
16pub const IRQ6: IrqSelection = IrqSelection::new(6);
17pub const IRQ7: IrqSelection = IrqSelection::new(7);
18pub const IRQ8: IrqSelection = IrqSelection::new(8);
19pub const IRQ9: IrqSelection = IrqSelection::new(9);
20pub const IRQ10: IrqSelection = IrqSelection::new(10);
21pub const IRQ11: IrqSelection = IrqSelection::new(11);
22pub const IRQ12: IrqSelection = IrqSelection::new(12);
23pub const IRQ13: IrqSelection = IrqSelection::new(13);
24pub const IRQ14: IrqSelection = IrqSelection::new(14);
25pub const IRQ15: IrqSelection = IrqSelection::new(15);
26pub const IRQ16: IrqSelection = IrqSelection::new(16);
27pub const IRQ17: IrqSelection = IrqSelection::new(17);
28pub const IRQ18: IrqSelection = IrqSelection::new(18);
29pub const IRQ19: IrqSelection = IrqSelection::new(19);
30pub const IRQ20: IrqSelection = IrqSelection::new(20);
31pub const IRQ21: IrqSelection = IrqSelection::new(21);
32pub const IRQ22: IrqSelection = IrqSelection::new(22);
33pub const IRQ23: IrqSelection = IrqSelection::new(23);
34pub const IRQ24: IrqSelection = IrqSelection::new(24);
35pub const IRQ25: IrqSelection = IrqSelection::new(25);
36pub const IRQ26: IrqSelection = IrqSelection::new(26);
37pub const IRQ27: IrqSelection = IrqSelection::new(27);
38pub const IRQ28: IrqSelection = IrqSelection::new(28);
39pub const IRQ29: IrqSelection = IrqSelection::new(29);
40pub const IRQ30: IrqSelection = IrqSelection::new(30);
41pub const IRQ31: IrqSelection = IrqSelection::new(31);
42
43pub struct IrqContext<'session> {
50 handle: IrqContextHandle,
51 session: &'session SessionHandle,
52}
53
54#[derive(Debug, PartialEq, Eq, Clone, Copy)]
56pub enum IrqWaitResult {
57 TimedOut,
59 IrqsAsserted(IrqSelection),
61}
62
63impl<'session> IrqContext<'session> {
64 pub fn wait_on_irq(
68 &mut self,
69 irq: IrqSelection,
70 timeout: Duration,
71 ) -> Result<IrqWaitResult, FPGAError> {
72 let mut irqs_asserted: IrqSelection = IrqSelection::NONE;
73 let mut timed_out: FpgaBool = FpgaBool::FALSE;
74
75 unsafe {
76 let status = NiFpga_WaitOnIrqs(
77 *self.session,
78 self.handle,
79 irq,
80 timeout.as_millis() as u32,
81 &mut irqs_asserted,
82 &mut timed_out,
83 );
84
85 if status.is_error() {
86 return Err(status.into());
87 }
88 }
89
90 if timed_out == FpgaBool::TRUE {
91 Ok(IrqWaitResult::TimedOut)
92 } else {
93 Ok(IrqWaitResult::IrqsAsserted(irqs_asserted))
94 }
95 }
96}
97
98impl Drop for IrqContext<'_> {
99 fn drop(&mut self) {
100 unsafe {
101 NiFpga_UnreserveIrqContext(*self.session, self.handle);
102 }
103 }
104}
105
106impl Session {
107 pub fn create_irq_context(&self) -> Result<IrqContext, FPGAError> {
115 let mut handle: IrqContextHandle = std::ptr::null();
116 unsafe {
117 let status = NiFpga_ReserveIrqContext(self.handle, &mut handle);
118
119 if status.is_error() {
120 return Err(status.into());
121 }
122 }
123 Ok(IrqContext {
124 handle,
125 session: &self.handle,
126 })
127 }
128
129 pub fn acknowledge_irqs(&self, irqs: IrqSelection) -> Result<(), FPGAError> {
131 unsafe {
132 let status = NiFpga_AcknowledgeIrqs(self.handle, irqs);
133
134 if status.is_error() {
135 return Err(status.into());
136 }
137 }
138 Ok(())
139 }
140}