001 /**
002 \file NiRioEntryPoints.h
003 \author Erik Hons <erik.hons@ni.com>
004 \date 12/14/2004
005
006 \brief Declarations for RIO services client DLL entry points
007
008 Intended to be called from a C client, or the LabVIEW
009 interface.
010
011 � Copyright 2004. National Instruments. All rights reserved.
012 */
013
014 package com.ni.rio;
015
016 import com.sun.cldc.jna.*;
017 import com.sun.cldc.jna.ptr.IntByReference;
018
019 /**
020 * The NiFpga class provides access to the FPGA on the cRIO. This is a wrapper around the accessors
021 * in NiFpga.h
022 */
023 public class NiFpga implements NiRioConstants
024 {
025 // ---------------------------
026 // Fifo Operations:
027
028 private static final Function configFifoFn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_ConfigureFifo");
029
030 /**
031 * Specifies the depth of the host memory part of the DMA FIFO. This method is
032 * optional. In order to see the actual depth configured, use
033 * NiFpga_ConfigureFifo2.
034 *
035 * @param hClient handle to a currently open session
036 * @param channel FIFO to configure
037 * @param fifoDepthInElements requested number of elements in the host memory part of the
038 * DMA FIFO
039 * @param status result of the call
040 */
041 public static void configureFifo(int hClient, int channel, int fifoDepthInElements, NiRioStatus status)
042 {
043 mergeStatus(status,
044 configFifoFn.call3(hClient, channel, fifoDepthInElements));
045 }
046
047 private static final Function startFifoFn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_StartFifo");
048
049 /**
050 * Starts a FIFO. This method is optional.
051 *
052 * @param hClient handle to a currently open session
053 * @param channel FIFO to start
054 * @param status result of the call
055 */
056 public static void startFifo(int hClient, int channel, NiRioStatus status)
057 {
058 mergeStatus(status,
059 startFifoFn.call2(hClient, channel));
060 }
061
062 private static final Function stopFifoFn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_StopFifo");
063
064 /**
065 * Stops a FIFO. This method is optional.
066 *
067 * @param hClient handle to a currently open session
068 * @param channel FIFO to start
069 * @param status result of the call
070 */
071 public static void stopFifo(int hClient, int channel, NiRioStatus status)
072 {
073 mergeStatus(status,
074 stopFifoFn.call2(hClient, channel));
075 }
076
077 private static final Function readFifoU32Fn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_ReadFifoU32");
078
079 /**
080 * Reads from a target-to-host FIFO of unsigned 32-bit integers.
081 *
082 * @param hClient handle to a currently open session
083 * @param channel target-to-host FIFO from which to read
084 * @param buf outputs the data that was read
085 * @param num number of elements to read
086 * @param timeout timeout in milliseconds, or NiFpga_InfiniteTimeout
087 * @param remaining outputs the number of elements
088 * remaining in the host memory part of the DMA FIFO
089 * @param status result of the call
090 */
091 public static void readFifoU32(int hClient, int channel, Pointer buf, int num, int timeout, IntByReference remaining, NiRioStatus status)
092 {
093 mergeStatus(status,
094 readFifoU32Fn.call6(hClient,
095 channel,
096 buf.address().toUWord().toPrimitive(),
097 num,
098 timeout,
099 remaining.getPointer().address().toUWord().toPrimitive()));
100 }
101
102
103 // ---------------------------
104 // I/O:
105
106 /**
107 * Conditionally sets the status to a new value. The previous status is
108 * preserved unless the new status is more of an error, which means that
109 * warnings and errors overwrite successes, and errors overwrite warnings. New
110 * errors do not overwrite older errors, and new warnings do not overwrite
111 * older warnings.
112 *
113 * @param status status to conditionally set
114 * @param newStatus int value new status value that may be set
115 */
116 static void mergeStatus(NiRioStatus statusA, int statusB) {
117 statusA.setStatus(statusB);
118 }
119
120 private static final Function writeU32Fn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_WriteU32");
121
122 /**
123 * Writes an unsigned 32-bit integer value to a given control or indicator.
124 *
125 * @param hClient handle to a currently open session
126 * @param offset control or indicator to which to write
127 * @param value value to write
128 * @param status result of the call
129 */
130 public static void writeU32(int hClient, int offset, int value, NiRioStatus status)
131 {
132 // System.out.print("write offset = 0x");
133 // System.out.println(Long.toString(offset, 16));
134 // System.out.print("value = 0x");
135 // System.out.println(Long.toString(((long)value) & 0xFFFFFFFFL, 16));
136 mergeStatus(status, writeU32Fn.call3(hClient, offset, value));
137 }
138
139 private static IntByReference readValue = new IntByReference(0);
140
141 private static final Function readU32Fn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_ReadU32");
142
143 /**
144 * Reads an unsigned 32-bit integer value from a given offset
145 *
146 * @param hClient handle to a currently open session
147 * @param offset indicator or control from which to read
148 * @param status result of the call
149 * @return outputs the value that was read
150 */
151 public static synchronized int readU32(int hClient, int offset, NiRioStatus status) {
152 // System.out.print("read offset = 0x");
153 // System.out.println(Long.toString(offset, 16));
154 mergeStatus(status,
155 readU32Fn.call3(hClient, offset, readValue.getPointer()));
156 // System.out.print("value = 0x");
157 // System.out.println(Long.toString(((long)value) & 0xFFFFFFFFL, 16));
158 return readValue.getValue();
159 }
160
161 // ---------------------------
162 // IRQs:
163
164 private static final Function reserveIrqContextFn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_ReserveIrqContext");
165
166 /**
167 * IRQ contexts are single-threaded; only one thread can wait with a particular
168 * context at any given time. Clients must reserve as many contexts as the
169 * application requires.
170 *
171 * If a context is successfully reserved (the returned status is not an error),
172 * it must be unreserved later. Otherwise a memory leak will occur.
173 *
174 * @param hClient handle to a currently open session
175 * @param context outputs the IRQ context
176 * @param NiRioStatus result of the call
177 */
178 public static void reserveIrqContext(int hClient, IntByReference context, NiRioStatus status)
179 {
180 mergeStatus(status,
181 reserveIrqContextFn.call2(hClient, context.getPointer().address().toUWord().toPrimitive()));
182 }
183
184 private static final Function unreserveIrqContextFn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_UnreserveIrqContext");
185 /**
186 * Unreserves an IRQ context obtained from reserveIrqContext.
187 *
188 * @param session handle to a currently open session
189 * @param context IRQ context to unreserve
190 * @return result of the call
191 */
192 public static void unreserveIrqContext(int hClient, IntByReference context, NiRioStatus status)
193 {
194 mergeStatus(status,
195 unreserveIrqContextFn.call2(hClient, context.getValue()));
196 }
197
198 private static IntByReference irqsAsserted = new IntByReference(0);
199
200 private static final Function waitOnIrqsFn = NativeLibrary.getDefaultInstance().getFunction("NiFpga_WaitOnIrqs");
201
202 /**
203 * This is a blocking function that stops the calling thread until the FPGA
204 * asserts any IRQ in the irqs parameter, or until the function call times out.
205 * Before calling this function, you must use NiFpga_ReserveIrqContext to
206 * reserve an IRQ context. No other threads can use the same context when this
207 * function is called.
208 *
209 * You can use the irqsAsserted parameter to determine which IRQs were asserted
210 * for each function call.
211 *
212 * @todo If this really blocks, then waitOnIrqsFn should probably be a BlockingFunction
213 *
214 * @param hClient handle to a currently open session
215 * @param context IRQ context with which to wait
216 * @param irqs bitwise OR of NiFpga_Irqs
217 * @param timeout timeout in milliseconds, or NiFpga_InfiniteTimeout
218 * @param irqsAsserted if non-NULL, outputs bitwise OR of IRQs that were
219 * asserted
220 * @param timedOut if non-NULL, outputs whether the timeout expired
221 * @return bitwise OR of IRQs that were asserted
222 */
223 public static synchronized int waitOnIrqs(int hClient, IntByReference context, int irqs, int timeout, NiRioStatus status) {
224 irqsAsserted.setValue(0);
225 mergeStatus(status,
226 waitOnIrqsFn.call6(hClient, context.getValue(), irqs, timeout, irqsAsserted.getPointer().address().toUWord().toPrimitive(), 0));
227 return irqsAsserted.getValue();
228 }
229
230 private NiFpga() {
231 }
232
233 }