nidas v1.2.3
gpio_mm.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 ** 2008, 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
28 Driver for Diamond Systems Corp GPIO-MM series of Counter/Timer
29 Digital I/O Cards.
30
31 Original Author: Gordon Maclean
32
33*/
34
35/*
36 * Each board has 10 16-bit counters and gobs of digital I/O pins.
37 *
38 * The implementation of a frequency counter uses 3 counters.
39 * One counter on a board is used as a general timer clock.
40 * Other driver modules can register with this clock to be
41 * called back at periodic times.
42 *
43 * Therefore each board supports up to 3 frequency input
44 * devices, or 9 pulse counters.
45 *
46 * Eventually the driver could also support a digital device,
47 * for controlling all the I/O pins. Dig I/O interrupt
48 * support is also available.
49 *
50 * So the following devices can be opened concurrently on a board:
51 * 3 frequency counters, 1 dio
52 * 2 frequency counters, 3 pulse counters, 1 dio
53 * 1 frequency counters, 6 pulse counters, 1 dio
54 * 0 frequency counters, 9 pulse counters, 1 dio
55 *
56 * Support for the pulse counters, dio and events has not been added yet....
57 *
58 * Board #0: Device table:
59 * device devname minor number
60 * freq cntr 0: /dev/gpiomm_fcntr0 0
61 * freq cntr 1: /dev/gpiomm_fcntr1 1
62 * freq cntr 2: /dev/gpiomm_fcntr2 2
63 * digital i/O: /dev/gpiomm_dio0 3
64 * pulse cntr 0: /dev/gpiomm_cntr0 4
65 * pulse cntr 1: /dev/gpiomm_cntr1 5
66 * pulse cntr 2: /dev/gpiomm_cntr2 6
67 * pulse cntr 3: /dev/gpiomm_cntr3 7
68 * pulse cntr 4: /dev/gpiomm_cntr4 8
69 * pulse cntr 5: /dev/gpiomm_cntr5 9
70 * pulse cntr 6: /dev/gpiomm_cntr6 10
71 * pulse cntr 7: /dev/gpiomm_cntr7 11
72 * pulse cntr 8: /dev/gpiomm_cntr8 12
73 * event 0: /dev/gpiomm_event0 13
74 *
75 * Board #1: Device table:
76 * device devname minor number (board0 + 14)
77 * freq cntr 0: /dev/gpiomm_fcntr3 14
78 * freq cntr 1: /dev/gpiomm_fcntr4 15
79 * freq cntr 2: /dev/gpiomm_fcntr5 16
80 * digital i/O: /dev/gpiomm_dio1 17
81 * pulse cntr 0: /dev/gpiomm_cntr9 18
82 * pulse cntr 1: /dev/gpiomm_cntr10 19
83 * pulse cntr 2: /dev/gpiomm_cntr11 10
84 * pulse cntr 3: /dev/gpiomm_cntr12 21
85 * pulse cntr 4: /dev/gpiomm_cntr13 22
86 * pulse cntr 5: /dev/gpiomm_cntr14 23
87 * pulse cntr 6: /dev/gpiomm_cntr15 24
88 * pulse cntr 7: /dev/gpiomm_cntr16 25
89 * pulse cntr 8: /dev/gpiomm_cntr17 26
90 * event 0: /dev/gpiomm_event1 27
91 */
92
93#ifndef NIDAS_DIAMOND_GPIO_MM_H
94#define NIDAS_DIAMOND_GPIO_MM_H
95
96#ifndef __KERNEL__
97/* User programs need this for the _IO macros, but kernel
98 * modules get their's elsewhere.
99 */
100#include <sys/ioctl.h>
101#include <sys/types.h>
102#endif
103
104/* This header is also included from user-side code that
105 * wants to get the values of the ioctl commands, and
106 * the definition of the structures.
107 */
108
110{
111 int outputPeriodUsec; // how often to report
112 int numPulses; // how many pulses to time
114};
115
117{
118 unsigned int lostSamples;
119 unsigned int pulseUnderflow;
120 unsigned int badGateWarning;
121 unsigned int badStatusWarning;
122};
123
128
130{
131 unsigned int nevents;
132 unsigned int lostSamples;
133};
134
135/* Pick a character as the magic number of your driver.
136 * It isn't strictly necessary that it be distinct between
137 * all modules on the system, but is a good idea. With
138 * distinct magic numbers one can catch a user sending
139 * an ioctl to the wrong device.
140 */
141#define GPIO_MM_IOC_MAGIC 'g'
142
143/*
144 * The enumeration of IOCTLs that this driver supports.
145 * See pages 130-132 of Linux Device Driver's Manual
146 */
147
149#define GPIO_MM_FCNTR_START \
150 _IOW(GPIO_MM_IOC_MAGIC,0,struct GPIO_MM_fcntr_config)
151#define GPIO_MM_FCNTR_GET_STATUS \
152 _IOR(GPIO_MM_IOC_MAGIC,1,struct GPIO_MM_fcntr_status)
154#define GPIO_MM_EVENT_START \
155 _IOW(GPIO_MM_IOC_MAGIC,2,struct GPIO_MM_event_config)
156#define GPIO_MM_EVENT_GET_STATUS \
157 _IOR(GPIO_MM_IOC_MAGIC,3,struct GPIO_MM_event_status)
158
159/* Maximum IOCTL number in above values */
160#define GPIO_MM_IOC_MAXNR 3
161
162#define GPIO_MM_CT_CLOCK_HZ 20000000
163
164#ifdef __KERNEL__
165/******** Start of definitions used by driver modules only **********/
166
167#include <linux/cdev.h>
168#include <linux/device.h>
169#include <nidas/linux/util.h>
170#include "gpio_mm_regs.h"
171
172typedef void (*gpio_timer_callback_func_t) (void* privateData);
173
179struct gpio_timer_callback
180{
181 struct list_head list;
182 gpio_timer_callback_func_t callbackFunc;
183 void* privateData;
184 unsigned int usecs;
185 unsigned int tickModulus;
186};
187
202extern struct gpio_timer_callback *register_gpio_timer_callback(
203 gpio_timer_callback_func_t callback,unsigned int usecs,
204 void *privateData, int *errp);
205
232extern long unregister_gpio_timer_callback(struct gpio_timer_callback *cb,
233 int wait);
234
235/* Size of ISA I/O space */
236#define GPIO_MM_DIO_IOPORT_WIDTH 8
237#define GPIO_MM_CT_IOPORT_WIDTH 16
238
239#define MAX_GPIO_MM_BOARDS 5 // number of boards supported by driver
240
241/* See device table in above comments */
242#define GPIO_MM_MINORS_PER_BOARD 14
243
244/* Use 3 counter timers to implement one frequency counter */
245#define GPIO_MM_CNTR_PER_FCNTR 3
246
247/* This will be 10/3=3 for GPIO-MM */
248#define GPIO_MM_FCNTR_PER_BOARD (GPIO_MM_CNTR_PER_BOARD/GPIO_MM_CNTR_PER_FCNTR)
249
250#define GPIO_MM_FCNTR_SAMPLE_QUEUE_SIZE 16
251
252#define GPIO_MM_EVENT_SAMPLE_QUEUE_SIZE 16
253
254/* Which counter 0-9 to use for a general purpose timer */
255#define GPIO_MM_TIMER_COUNTER 9
256
257#define CALLBACK_POOL_SIZE 64 /* number of timer callbacks we can support */
258
263struct freq_sample
264{
265 dsm_sample_time_t timetag; // timetag of sample
266 dsm_sample_length_t length; // number of bytes in data (8)
267 int pulses;
268 int ticks;
269};
270
274struct event_sample
275{
276 dsm_sample_time_t timetag; // timetag of sample
277 dsm_sample_length_t length; // number of bytes in data (0)
278 unsigned int nevents;
279};
280
281struct GPIO_MM;
282
286struct GPIO_MM_fcntr
287{
288 struct GPIO_MM* brd;
289
290 struct device* device;
291
292 int num; // which freq counter on board
293
294 struct GPIO_MM_fcntr_status status;
295
296 char deviceName[32];
297
298 struct cdev cdev;
299
303 int numPulses;
304
308 int outputPeriodUsec;
309
310 atomic_t num_opened; // number of times opened
311
312 struct gpio_timer_callback* timer_callback;
313
314 struct dsm_sample_circ_buf samples; // samples out of b.h.
315
319 wait_queue_head_t rwaitq;
320
321 struct sample_read_state read_state;
322
326 long latencyJiffies;
327
331 unsigned long lastWakeup;
332
333};
334
338struct GPIO_MM_event
339{
340 struct GPIO_MM* brd;
341
342 struct device* device;
343
344 struct GPIO_MM_event_status status;
345
346 char deviceName[32];
347
348 struct cdev cdev;
349
350 atomic_t num_opened; // number of times opened
351
352 struct dsm_sample_circ_buf samples; // event samples
353
357 wait_queue_head_t rwaitq;
358
359 struct sample_read_state read_state;
360
364 long latencyJiffies;
365
369 unsigned long lastWakeup;
370
371};
372
373/*
374 * The GPIO timer.
375 */
376struct GPIO_MM_timer
377{
378 struct GPIO_MM* brd;
379
383 struct list_head callbackList;
384
388 struct list_head callbackPool;
389
393 struct list_head pendingAdds;
394
398 struct gpio_timer_callback *pendingRemoves[CALLBACK_POOL_SIZE];
399
400 int nPendingRemoves;
401
406 spinlock_t callbackLock;
407
413 unsigned int usecs;
414
415 unsigned int irqsReceived;
416
420 unsigned int tick;
421
425 unsigned int tickLimit;
426
427 int scaler;
428
432 struct tasklet_struct tasklet;
433
438 int callbacksChanged;
439
444 wait_queue_head_t callbackWaitQ;
445
446};
447
451struct GPIO_MM
452{
453 int num; // which board in system, from 0
454 unsigned int ioport_dio; // ioport address of DIO regs
455 unsigned long dio_addr; // Base address of 8255 DIO regs
456
457 unsigned int ioport_ct; // ioport address of cntr/timer
458 unsigned long ct_addr; // Base address of 9513 cntr/timer regs
459 int irqs[2]; // values of ISA irq A and B
460 int reqirqs[2]; // requested system irqs A and B
461 int cntr_used[GPIO_MM_CNTR_PER_BOARD]; // 0=unused, 1=used
462
463 int boardID;
464
468 unsigned char mmode_lsb[2];
469 unsigned char mmode_msb[2];
470
471 struct GPIO_MM_timer* timer;
472
476 struct GPIO_MM_fcntr* fcntrs;
477
481 struct GPIO_MM_event* event;
482
487 spinlock_t reglock;
488
489#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
490 struct mutex brd_mutex; // lock for non-interrupt board ops
491#else
492 struct semaphore brd_mutex; // lock for non-interrupt board ops
493#endif
494};
495
496#endif
497
498#endif
static int irqs[MAX_DMMAT_BOARDS]
Definition dmd_mmat.c:73
struct gpio_timer_callback * register_gpio_timer_callback(gpio_timer_callback_func_t callback, unsigned int usecs, void *privateData, int *errp)
Definition gpio_mm.c:2000
long unregister_gpio_timer_callback(struct gpio_timer_callback *cb, int wait)
Definition gpio_mm.c:2010
#define GPIO_MM_CNTR_PER_BOARD
Definition gpio_mm_regs.h:39
#define CALLBACK_POOL_SIZE
Definition pc104sg.c:190
static string device
Definition sing.cc:60
Definition gpio_mm.h:125
int latencyUsecs
Definition gpio_mm.h:126
Definition gpio_mm.h:130
unsigned int nevents
Definition gpio_mm.h:131
unsigned int lostSamples
Definition gpio_mm.h:132
Definition gpio_mm.h:110
int latencyUsecs
Definition gpio_mm.h:113
int numPulses
Definition gpio_mm.h:112
int outputPeriodUsec
Definition gpio_mm.h:111
Definition gpio_mm.h:117
unsigned int pulseUnderflow
Definition gpio_mm.h:119
unsigned int badStatusWarning
Definition gpio_mm.h:121
unsigned int lostSamples
Definition gpio_mm.h:118
unsigned int badGateWarning
Definition gpio_mm.h:120
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