nidas v1.2.3
emerald.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 ** 2006, 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 module for Diamond Systems Emerald 8 port serial card.
29
30 This driver can get/set the irq and ioport values for each of the
31 8 serial ports on a card. Once this driver sets the irq and ioport
32 values for each port in the card registers, and enables it, then the
33 serial port can be configured with the Linux setserial command and
34 accessed as a normal serial port by the Linux tty serial port driver.
35
36 An Emerald also has 8 digital I/O pins. This driver supports the
37 get/set of those 8 pins via ioctl calls.
38
39 This module can control up to EMERALD_MAX_NR_DEVS boards, which
40 is typically defined in this header to be 4. A unique ioport address
41 of each board must be chosen and jumpered on the board. These ioport
42 address values must then be passed to this driver module as the "ioports"
43 parameter when it is loaded.
44 A typical setting in /etc/modprobe.d/diamond is as follows:
45 options emerald ioports=0x200,0x240,0x2c0,0x300
46 This driver will check if a board responds at each address, so the
47 above array of ioports will work if there are less than 4 boards
48 installed in the system, assuming there is not a conflict with another
49 PC104 board at those addresses. Each Emerald uses 7 bytes of ioport
50 address space.
51
52 The usual device configuration is as follows, where /dev/emerald[0-3]
53 are the device files that can be used to address each emerald board
54 in the system. The major number is allocated dynamically when the
55 driver module is loaded, and can then be queried with
56 "grep emerald /proc/devices".
57
58 name device minor number
59 /dev/emerald0 0
60 /dev/emerald1 8
61 /dev/emerald2 16
62 /dev/emerald3 24
63
64 The digital I/O devices can be named in a similar way to the serial ports
65 on the board. In this example, serial ports ttyS[5-12] are the 8 serial ports
66 on the first board, and so the digital I/O devices are named starting at ttyD5:
67
68 /dev/ttyD5 0
69 ...
70 /dev/ttyD12 7
71
72 Serial ports on second board:
73 /dev/ttyD13 8
74 ...
75 /dev/ttyD20 15
76
77 Third board, etc:
78 /dev/ttyD21 16
79 ...
80 /dev/ttyD28 23
81
82 Notice that /dev/emerald0 and /dev/ttyD5 have the same major and minor numbers,
83 and so are synomyms for the same device. Likewise for /dev/emerald1 and /dev/ttyD13.
84
85 The Linux tty driver expects 8 bytes of ioport address space for each serial port.
86 An IRQ must also be allocated for each port. A typical configuration of the
87 serial ports is as follows:
88 port device ioport IRQ
89 0 /dev/ttyS5 0x100 3
90 1 /dev/ttyS6 0x108 3
91 2 /dev/ttyS7 0x110 3
92 3 /dev/ttyS8 0x118 3
93 4 /dev/ttyS9 0x120 3
94 5 /dev/ttyS10 0x128 3
95 6 /dev/ttyS11 0x130 3
96 7 /dev/ttyS12 0x138 3
97 8 /dev/ttyS13 0x140 3
98 ...
99
100 Note that these ioport values are for the individual serial ports on the board,
101 and are distinct from the ioport values that are used to address the board
102 itself.
103
104 The above iport and IRQ values can be set on the Emerald card for each port
105 via the EMERALD_IOCSPORTCONFIG ioctl. The set_emerald application can be
106 used to invoke the necessary ioctls on this driver.
107
108 To set the ioport and IRQ values for each board and enable the ports:
109 set_emerald /dev/emerald0 0x100 3
110 set_emerald /dev/emerald1 0x140 3
111 ...
112
113 To set the ioport and IRQ values in EEPROM via the EMERALD_IOCSEEPORTCONFIG
114 ioctl, and enable the ports:
115 set_emerald /dev/emerald0 0x100 3
116 set_emerald /dev/emerald1 0x140 3
117
118 To query the values:
119 set_emerald /dev/emerald0
120
121 To enable (up) the ports, assuming the existing values are OK
122 set_emerald -u /dev/emerald0
123
124 After configuring the emerald card as above, the tty driver can
125 be configured to access those ports, using the Linux setserial command.
126 In this example, minor number 64-68 were used for serial ports /dev/ttyS0-4
127 on the CPU board, and so minor numbers 69 and above are for the Emerald ports.
128
129 mknod /dev/ttyS5 c 4 69
130 mknod /dev/ttyS6 c 4 70
131 ...
132
133 setserial -zvb /dev/ttyS5 port 0x100 irq 3 baud_base 460800 autoconfig
134 setserial -zvb /dev/ttyS6 port 0x108 irq 3 baud_base 460800 autoconfig
135 ...
136
137 At this point the serial ports should be accessible.
138
139 This module can also set the RS232/422/485 mode for each serial port on an EMM-8P.
140
141*/
142#ifndef NIDAS_LINUX_EMERALD_H
143#define NIDAS_LINUX_EMERALD_H
144
145// #define EMERALD_DEBUG
146
147/* Debugging printk macros from Linux Device Drivers book.
148 * Not used, kept for reference */
149#undef PDEBUG /* undef it, just in case */
150#ifdef EMERALD_DEBUG
151# ifdef __KERNEL__
152 /* This one if debugging is on, and kernel space */
153# define PDEBUG(fmt, args...) printk( KERN_DEBUG "emerald: " fmt, ## args)
154# else
155 /* This one for user space */
156# define PDEBUG(fmt, args...) fprintf(stderr, fmt, ## args)
157# endif
158#else
159# define PDEBUG(fmt, args...) /* not debugging: nothing */
160#endif
161#undef PDEBUGG
162#define PDEBUGG(fmt, args...) /* nothing: it's a placeholder */
163
164#define EMERALD_NR_PORTS 8 /* number of serial ports on an emerald-mm-8 */
165
166#ifdef __KERNEL__
167
168#include <linux/cdev.h>
169#include <linux/device.h>
170#include <linux/ioctl.h> /* needed for the _IOW etc stuff used later */
171
172#define EMERALD_MAX_NR_DEVS 4 /* maximum number of emerald cards in sys */
173#define EMERALD_IO_REGION_SIZE 7 /* number of 1-byte registers per card */
174
175/* registers on the emerald starting at the ioport address */
176#define EMERALD_APER 0x0 /* address ptr/enable reg (read,write)*/
177#define EMERALD_AIDR 0x1 /* address/IRQ data reg (write) */
178#define EMERALD_ARR 0x1 /* address register readback (read) */
179#define EMERALD_DDR 0x2 /* digital I/O direction reg (write) */
180#define EMERALD_ISR 0x2 /* interrupt status reg (read) */
181#define EMERALD_DOR 0x3 /* digital output reg (write) */
182#define EMERALD_DIR 0x3 /* digital input reg (read) */
183#define EMERALD_ECAR 0x4 /* EEPROM cmd and addr reg (write) */
184#define EMERALD_EBR 0x4 /* EEPROM busy reg (read) */
185#define EMERALD_EDR 0x5 /* EEPROM data reg (read/write) */
186#define EMERALD_CRR 0x6 /* Configuration register reload (write) */
187
188#endif /* __KERNEL__ */
189
190typedef struct emerald_serial_port {
191 unsigned int ioport; /* ISA ioport of a serial port, e.g. 0x100 */
192 unsigned int irq; /* ISA IRQ of serial port */
194
198
199/*
200 * Enumeration of software-setable serial modes for ports on Emm-8P card.
201 */
208
209/*
210 * Module attempts to determine which model of card.
211 */
217
218typedef struct emerald_mode {
219 enum EMERALD_MODE mode; /* desired mode of a port */
221
222#ifdef __KERNEL__
223
224/*
225 * An emerald board. May be more than one on a system.
226 */
227typedef struct emerald_board {
228 unsigned int ioport; /* ioport address of emerald */
229 unsigned long addr; /* ioport plus system ISA base address */
230 emerald_config config; /* ioport and irq of 8 serial ports */
231 enum EMERALD_MODEL model; /* model of card */
232 char deviceName[32];
233#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
234 struct mutex brd_mutex; // exclusion lock for accessing board registers
235#else
236 struct semaphore brd_mutex; // exclusion lock for accessing board registers
237#endif
238 int digioval; /* current digital I/O value */
239 int digioout; /* bit=1, dig I/O direction = out */
240
241 struct cdev cdev;
242 struct device* device;
243
244} emerald_board;
245
246/*
247 * struct for each of the emerald ports, 8 per board. User can
248 * control the digital I/O pin on each port.
249 */
250typedef struct emerald_port {
251 emerald_board* board;
252 struct cdev cdev;
253 int portNum; /* serial port number on this board, 0-7 */
254 struct device* device;
255} emerald_port;
256
257
258# endif /* __KERNEL__ */
259
260/* Look in Documentation/ioctl-number.txt */
261#define EMERALD_IOC_MAGIC 0xd0
262
263/* set port config in RAM */
264#define EMERALD_IOCSPORTCONFIG _IOW(EMERALD_IOC_MAGIC, 0, emerald_config)
265
266/* get port config from RAM */
267#define EMERALD_IOCGPORTCONFIG _IOR(EMERALD_IOC_MAGIC, 1, emerald_config)
268
269/* set config in EEPROM */
270#define EMERALD_IOCSEEPORTCONFIG _IOW(EMERALD_IOC_MAGIC, 2, emerald_config)
271
272/* get config from EEPROM */
273#define EMERALD_IOCGEEPORTCONFIG _IOR(EMERALD_IOC_MAGIC, 3, emerald_config)
274
275/* load config from EEPROM to RAM */
276#define EMERALD_IOCEECONFIGLOAD _IO(EMERALD_IOC_MAGIC, 4)
277
278/* enable the UARTs */
279#define EMERALD_IOCPORTENABLE _IO(EMERALD_IOC_MAGIC, 5)
280
281/* how many boards are responding at the given ioport addresses */
282#define EMERALD_IOCGNBOARD _IOR(EMERALD_IOC_MAGIC, 6, int)
283
284/* what is the base ISA address on this system */
285#define EMERALD_IOCGISABASE _IOR(EMERALD_IOC_MAGIC,7,unsigned long)
286
287/* Get direction of digital I/O line for a port, 1=out, 0=in */
288#define EMERALD_IOCGDIOOUT _IOR(EMERALD_IOC_MAGIC,8,int)
289
290/* Set direction of digital I/O line for a port, 1=out, 0=in */
291#define EMERALD_IOCSDIOOUT _IOW(EMERALD_IOC_MAGIC,9,int)
292
293/* Get value of digital I/O line for a port */
294#define EMERALD_IOCGDIO _IOR(EMERALD_IOC_MAGIC,10,int)
295
296/* Set value of digital I/O line for a port */
297#define EMERALD_IOCSDIO _IOW(EMERALD_IOC_MAGIC,11,int)
298
299/* Get value of mode for a port */
300#define EMERALD_IOCG_MODE _IOWR(EMERALD_IOC_MAGIC,12,emerald_mode)
301
302/* Set value of mode for a port */
303#define EMERALD_IOCS_MODE _IOW(EMERALD_IOC_MAGIC,13,emerald_mode)
304
305/* Get value of mode for a port from eeprom */
306#define EMERALD_IOCG_EEMODE _IOWR(EMERALD_IOC_MAGIC,14,emerald_mode)
307
308/* Set value of mode for a port into eeprom */
309#define EMERALD_IOCS_EEMODE _IOW(EMERALD_IOC_MAGIC,15,emerald_mode)
310
311#define EMERALD_IOC_MAXNR 15
312
313#endif /* _EMERALD_H */
314
static struct DMMAT * board
Definition dmd_mmat.c:124
struct emerald_mode emerald_mode
struct emerald_config emerald_config
EMERALD_MODEL
Definition emerald.h:212
@ EMERALD_MM_8P
Definition emerald.h:215
@ EMERALD_UNKNOWN
Definition emerald.h:213
@ EMERALD_MM_8
Definition emerald.h:214
#define EMERALD_NR_PORTS
Definition emerald.h:164
EMERALD_MODE
Definition emerald.h:202
@ EMERALD_RS485_NOECHO
Definition emerald.h:206
@ EMERALD_RS232
Definition emerald.h:203
@ EMERALD_RS485_ECHO
Definition emerald.h:205
@ EMERALD_RS422
Definition emerald.h:204
struct emerald_serial_port emerald_serial_port
static unsigned int ioport[MESA_4I34_MAX_NR_DEVS]
Definition mesa.c:72
static string device
Definition sing.cc:60
Definition emerald.h:195
emerald_serial_port ports[EMERALD_NR_PORTS]
Definition emerald.h:196
Definition emerald.h:218
enum EMERALD_MODE mode
Definition emerald.h:219
Definition emerald.h:190
unsigned int ioport
Definition emerald.h:191
unsigned int irq
Definition emerald.h:192