nidas v1.2.3
usbtwod.h
Go to the documentation of this file.
1/* -*- mode: C; indent-tabs-mode: nil; c-basic-offset: 8; tab-width: 8; -*- */
2/* vim: set shiftwidth=8 softtabstop=8 expandtab: */
3/*
4 ********************************************************************
5 ** NIDAS: NCAR In-situ Data Acquistion Software
6 **
7 ** 2007, Copyright University Corporation for Atmospheric Research
8 **
9 ** This program is free software; you can redistribute it and/or modify
10 ** it under the terms of the GNU General Public License as published by
11 ** the Free Software Foundation; either version 2 of the License, or
12 ** (at your option) any later version.
13 **
14 ** This program is distributed in the hope that it will be useful,
15 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
16 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 ** GNU General Public License for more details.
18 **
19 ** The LICENSE.txt file accompanying this software contains
20 ** a copy of the GNU General Public License. If it is not found,
21 ** write to the Free Software Foundation, Inc.,
22 ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 **
24 ********************************************************************
25*/
26
27#ifndef _nidas_usbtwod_h_
28#define _nidas_usbtwod_h_
29
30#include <nidas/linux/types.h>
31
32#ifndef __KERNEL__
33/* User programs need this for the _IO macros, but kernel
34 * modules get their's elsewhere.
35 */
36#include <sys/ioctl.h>
37#include <sys/types.h>
38#include <errno.h>
39#endif
40
41#include <nidas/linux/util.h>
42
43#define SOR_DEBUG
44
50{
52 unsigned int numImages;
53 unsigned int lostImages;
55 unsigned int numSORs;
56 unsigned int lostSORs;
57 unsigned int lostTASs;
58 unsigned int urbErrors;
59 unsigned int shutdowns; /* number of detected indications of USB shutdown */
60 unsigned int urbTimeouts;
61};
62
72typedef struct _Tap2D_v1
73{
75 unsigned char ntap;
77 unsigned char div10;
79 unsigned char cntr;
80 unsigned char dummy;
82
87typedef struct _Tap2D_v2
88{
90 unsigned short ntap;
92 unsigned char div10;
93
95 unsigned char cntr;
97
98/*
99 * Believe this struct is unnecessary
100 */
101typedef struct _Tap2D_v3
102{
104 unsigned short tas;
106 unsigned short probeResolution;
108
109/* Pick a character as the magic number of your driver.
110 * It isn't strictly necessary that it be distinct between
111 * all modules on the system, but is a good idea. With
112 * distinct magic numbers one can catch a user sending
113 * an ioctl to the wrong device.
114 */
115#define USB2D_IOC_MAGIC 0x2d
116
117#define USB2D_SET_TAS _IOW(USB2D_IOC_MAGIC,0,Tap2D)
118#define USB2D_SET_SOR_RATE _IOW(USB2D_IOC_MAGIC,1,int)
119#define USB2D_GET_STATUS _IOR(USB2D_IOC_MAGIC,2,struct usb_twod_stats)
120
121/*
122 * Both image and shadow-OR samples are read from this device.
123 * We place the following 4-byte type values at the beginning of
124 * each data sample in big-endian form, so user code can
125 * figure out which is which.
126 */
127#define TWOD_IMG_TYPE 0
128#define TWOD_SOR_TYPE 1
129#define TWOD_SORv3_TYPE 0x534f522c /* "SOR," (actually ",ROS" on little endian) */
130#define TWOD_IMGv2_TYPE 2
131#define TWOD_IMGv3_TYPE 3
132
133#ifdef __KERNEL__
134#include <linux/module.h>
135#include <linux/spinlock.h>
136#include <linux/kref.h>
137
138/* 64 bit probes will have minor numbers starting at 192,
139 * 32 bit probes will have minor numbers starting at 196.
140 * On the vulcan, running 2.6.11 kernel without a udev daemon,
141 * you have to mknod the devices by hand:
142 * mknod /dev/usbtwod_64_0 c 180 192
143 * mknod /dev/usbtwod_64_1 c 180 193
144 * mknod /dev/usbtwod_64_2 c 180 194
145 * mknod /dev/usbtwod_64_3 c 180 195
146 * mknod /dev/usbtwod_32_0 c 180 196
147 * etc...
148 * On systems with a udev daemon, these device files are created
149 * automatically when the device is connected, using the
150 * name member of the struct usb_class_driver, which
151 * is passed to usb_register_dev() in the probe method.
152 */
153#define USB_TWOD_64_V3_MINOR_BASE 192
154#define USB_TWOD_64_MINOR_BASE 192
155#define USB_TWOD_32_MINOR_BASE 196
156
157#define TWOD_IMG_BUFF_SIZE 4096 /* Optimal that it's PAGE_SIZE */
158#define TWOD_SOR_BUFF_SIZE 128 /* PRS doc has 70 as max possible size of housekeeping*/
159#define TWOD_TAS_BUFF_SIZE 4
160
161/*
162 * SAMPLE_QUEUE_SIZE is the number of image and SOR samples
163 * that can be queued for user reads.
164 *
165 * SAMPLE_QUEUE_SIZE must be a power of 2 (required by circ_buf).
166 * In order for a circ_buf to tell the difference between empty
167 * and full, a full circ_buf contains (size-1) elements.
168 *
169 * An entry in the queue is sizeof(struct twod_urb_sample), either
170 * 24 or 32 bytes (if 64 bit pointers), so it's not big.
171 *
172 * To handle the situation where the user reads might get far behind,
173 * make it at least the minimum power of two greater than
174 * IMG_URBS_IN_FLIGHT + SOR_URBS_IN_FLIGHT, but
175 * there isn't an advantage to make it more than that.
176 */
177/*
178 * Throughput tests on both an Intel core laptop PC and an Arcom Vulcan
179 * showed no difference in throughput with the following values
180 * for the sample queue sizes and number of urbs in flight:
181 * SAMPLE_QUEUE_SIZE IMG_URB_QUEUE_SIZE IMG_URBS_IN_FLIGHT
182 * 16 8 7
183 * 8 4 3
184 * 4 2 1
185 */
186#define SAMPLE_QUEUE_SIZE 32 /* power of two */
187
188/*
189 * Size of queue used by throttle rate function.
190 * A power of two that is also greater than IMG_URBS_IN_FLIGHT.
191 */
192#define IMG_URB_QUEUE_SIZE 32
193
194/*
195 * A TWOD_IMG_BUFF_SIZE buffer is pre-allocated for every image
196 * URB in flight, so don't make it too big.
197 *
198 * It should not be greater than (IMG_URB_QUEUE_SIZE-1), but
199 * can be less than that, for example IMG_URB_QUEUE_SIZE=32 and
200 * IMG_URBS_IN_FLIGHT=20.
201 */
202#define IMG_URBS_IN_FLIGHT 20
203
204/*
205 * Maximum invocation rate of the throttle function.
206 * Should divide evenly into HZ.
207 * HZ is 250 on Vortex, 100 on old systems, 1000 on new X86.
208 * grep 'CONFIG_HZ=' /boot/config-$(uname -r)
209 * For a requested throttle rate, the function will
210 * submit a number of urbs (up to IMG_URBS_IN_FLIGHT)
211 * to achieve the requested rate.
212 */
213#define MAX_THROTTLE_FUNC_RATE 10
214
215/*
216 * This is the maximun throttle rate supported, which is limited
217 * by MAX_THROTTLE_FUNC_RATE * IMG_URBS_IN_FLIGHT.
218 * To achieve higher rates you need to increase MAX_THROTTLE_FUNC_RATE
219 * (consuming more CPU) or IMG_URBS_QUEUE_SIZE (consuming more memory).
220 */
221#define MAX_THROTTLE_RATE (MAX_THROTTLE_FUNC_RATE * IMG_URBS_IN_FLIGHT)
222
223#define SOR_URBS_IN_FLIGHT 4
224
225#define TAS_URB_QUEUE_SIZE 4 /* power of two */
226
227struct twod_urb_sample
228{
229 dsm_sample_time_t timetag; /* timetag of sample */
230 dsm_sample_length_t length; /* number of bytes in data */
231 unsigned int stype; /* sample type, 0=image, 1=SOR */
232 unsigned int data; /* True Airspeed for image sample */
233 int pre_urb_len; /* size of sample without urb contents */
234 struct urb *urb;
235};
236struct twod_house_urb_sample
237{
238 int serialNum;
239 dsm_sample_time_t timetag;
240 unsigned int stype; //sor
241 unsigned int data; //dof or
242 int temperature;
243 double levelD1;
244 double levelD32;
245 double levelD64;
246};
247
248struct sample_circ_buf
249{
250 struct twod_urb_sample **buf;
251 int head;
252 int tail;
253};
254
255struct urb_circ_buf
256{
257 struct urb **buf;
258 int head;
259 int tail;
260};
261
262
263/* reading status keeper */
264struct read_state
265{
266 char *dataPtr; /* pointer into data of what is left to copy to user */
267 size_t bytesLeft; /* How much is left to copy to user buffer of sample_ptr */
268 struct twod_urb_sample *pendingSample; /* sample partly copied to user space */
269};
270
271enum twod_probe_type { TWOD_64_V3, TWOD_64, TWOD_32 };
272
273/* Structure to hold all of our device specific stuff */
274struct usb_twod
275{
276 struct usb_device *udev; /* the usb device for this device */
277 struct usb_interface *interface; /* the interface for this device */
278 struct kref kref; /* reference counter for this structure */
279 rwlock_t usb_iface_lock; /* for detection of whether disconnect has been called */
280
281 char dev_name[64]; /* device name for log messages */
282
283 __u8 img_in_endpointAddr; /* the address of the image in endpoint */
284 __u8 tas_out_endpointAddr; /* the address of the TAS out endpoint */
285 __u8 sor_in_endpointAddr; /* the address of the SOR in endpoint */
286 int is_open; /* don't allow multiple opens. */
287
288 enum twod_probe_type ptype;
289
290 struct urb *img_urbs[IMG_URBS_IN_FLIGHT]; /* All data read urbs */
291 struct urb_circ_buf img_urb_q;
292
293 struct urb *sor_urbs[SOR_URBS_IN_FLIGHT]; /* All sor read urbs */
294
295 struct sample_circ_buf sampleq; /* samples that are ready for reading from user side */
296 spinlock_t sampqlock; /* control sample producer threads */
297
298 struct urb_circ_buf tas_urb_q; /* queue of TAS samples for writing */
299
300 wait_queue_head_t read_wait; /* Zzzzz ... */
301
302 struct usb_twod_stats stats; /* various I/O counter for info */
303
304 struct read_state readstate; /* leftovers from past read */
305
306 int errorStatus; /* current error value */
307
308 struct timer_list urbThrottle;
309
310 int throttleJiffies; /* if throttling jiffie wait between
311 timer events */
312
313 int nurbPerTimer; /* if throttling, how many urbs to submit on
314 every timer event */
315
316 int latencyJiffies; /* maximum time user wants to wait
317 * between reads */
318
319 unsigned long lastWakeup; /* time of last read queue wakeup */
320
321 struct timer_list sendTASTimer; /* kernel timer for sending true airspeed */
322 int sendTASJiffies; /* when to send the next TAS */
323
324 spinlock_t taslock; /* control access to TAS value */
325
326 Tap2D tasValue; /* TAS value to send to probe (from user ioctl) */
327
328 int consecTimeouts;
329#ifdef SOR_DEBUG
330 int SORdebugmessages;
331#endif
332};
333#endif // ifdef __KERNEL__
334#endif
Struct to adjust probe slice rate for true airspeed.
Definition usbtwod.h:73
unsigned char div10
boolean toggle for frequency divide by 10
Definition usbtwod.h:77
unsigned char ntap
which tap in the variable resistor (0-255)
Definition usbtwod.h:75
unsigned char dummy
Definition usbtwod.h:80
unsigned char cntr
counter from 1 to 10
Definition usbtwod.h:79
This version is for rev2 of Spowarts USB board.
Definition usbtwod.h:88
unsigned short ntap
which tap in the variable resistor (0-255)
Definition usbtwod.h:90
unsigned char cntr
counter from 1 to 10
Definition usbtwod.h:95
unsigned char div10
boolean toggle for frequency divide by 10
Definition usbtwod.h:92
Definition usbtwod.h:102
unsigned short probeResolution
which probe resolution
Definition usbtwod.h:106
unsigned short tas
sending tas*10, ntap calculation happens on probe
Definition usbtwod.h:104
Statistics gathered by the PMS2D USB driver.
Definition usbtwod.h:50
unsigned int shutdowns
Definition usbtwod.h:59
unsigned int numSORs
Number of Shadow-ORs transfered from probe.
Definition usbtwod.h:55
unsigned int lostTASs
Definition usbtwod.h:57
unsigned int lostSORs
Definition usbtwod.h:56
unsigned int urbErrors
Definition usbtwod.h:58
unsigned int numImages
Number of 4K buffers transfered from probe.
Definition usbtwod.h:52
unsigned int urbTimeouts
Definition usbtwod.h:60
unsigned int lostImages
Definition usbtwod.h:53
unsigned int dsm_sample_length_t
length of data portion of sample.
Definition types.h:51
int dsm_sample_time_t
Depending on the module, either tenths of milliseconds, or milliseconds since 00:00 UTC today.
Definition types.h:48
struct _Tap2D_v1 Tap2Dv1
Struct to adjust probe slice rate for true airspeed.
struct _Tap2D_v3 Tap2D_v3
struct _Tap2D_v2 Tap2D
This version is for rev2 of Spowarts USB board.