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    }