Annotation of embedaddon/ntp/libntp/icom.c, revision 1.1.1.1
1.1 misho 1: /*
2: * Program to control ICOM radios
3: *
4: * This is a ripoff of the utility routines in the ICOM software
5: * distribution. The only function provided is to load the radio
6: * frequency. All other parameters must be manually set before use.
7: */
8: #include <config.h>
9: #include "icom.h"
10: #include <unistd.h>
11: #include <stdio.h>
12: #include <fcntl.h>
13: #include <errno.h>
14:
15: #include "ntp_tty.h"
16: #include "l_stdlib.h"
17:
18: #ifdef SYS_WINNT
19: #undef write /* ports/winnt/include/config.h: #define write _write */
20: extern int async_write(int, const void *, unsigned int);
21: #define write(fd, data, octets) async_write(fd, data, octets)
22: #endif
23:
24: /*
25: * Packet routines
26: *
27: * These routines send a packet and receive the response. If an error
28: * (collision) occurs on transmit, the packet is resent. If an error
29: * occurs on receive (timeout), all input to the terminating FI is
30: * discarded and the packet is resent. If the maximum number of retries
31: * is not exceeded, the program returns the number of octets in the user
32: * buffer; otherwise, it returns zero.
33: *
34: * ICOM frame format
35: *
36: * Frames begin with a two-octet preamble PR-PR followyd by the
37: * transceiver address RE, controller address TX, control code CN, zero
38: * or more data octets DA (depending on command), and terminator FI.
39: * Since the bus is bidirectional, every octet output is echoed on
40: * input. Every valid frame sent is answered with a frame in the same
41: * format, but with the RE and TX fields interchanged. The CN field is
42: * set to NAK if an error has occurred. Otherwise, the data are returned
43: * in this and following DA octets. If no data are returned, the CN
44: * octet is set to ACK.
45: *
46: * +------+------+------+------+------+--//--+------+
47: * | PR | PR | RE | TX | CN | DA | FI |
48: * +------+------+------+------+------+--//--+------+
49: */
50: /*
51: * Scraps
52: */
53: #define DICOM /dev/icom/ /* ICOM port link */
54:
55: /*
56: * Local function prototypes
57: */
58: static void doublefreq (double, u_char *, int);
59:
60:
61: /*
62: * icom_freq(fd, ident, freq) - load radio frequency
63: */
64: int
65: icom_freq( /* returns 0 (ok), EIO (error) */
66: int fd, /* file descriptor */
67: int ident, /* ICOM radio identifier */
68: double freq /* frequency (MHz) */
69: )
70: {
71: u_char cmd[] = {PAD, PR, PR, 0, TX, V_SFREQ, 0, 0, 0, 0, FI,
72: FI};
73: int temp;
74:
75: cmd[3] = (char)ident;
76: if (ident == IC735)
77: temp = 4;
78: else
79: temp = 5;
80: doublefreq(freq * 1e6, &cmd[6], temp);
81: temp = write(fd, cmd, temp + 7);
82:
83: return (0);
84: }
85:
86:
87: /*
88: * doublefreq(freq, y, len) - double to ICOM frequency with padding
89: */
90: static void
91: doublefreq( /* returns void */
92: double freq, /* frequency */
93: u_char *x, /* radio frequency */
94: int len /* length (octets) */
95: )
96: {
97: int i;
98: char s1[16];
99: char *y;
100:
101: snprintf(s1, sizeof(s1), " %10.0f", freq);
102: y = s1 + 10;
103: i = 0;
104: while (*y != ' ') {
105: x[i] = *y-- & 0x0f;
106: x[i] = x[i] | ((*y-- & 0x0f) << 4);
107: i++;
108: }
109: for ( ; i < len; i++)
110: x[i] = 0;
111: x[i] = FI;
112: }
113:
114: /*
115: * icom_init() - open and initialize serial interface
116: *
117: * This routine opens the serial interface for raw transmission; that
118: * is, character-at-a-time, no stripping, checking or monkeying with the
119: * bits. For Unix, an input operation ends either with the receipt of a
120: * character or a 0.5-s timeout.
121: */
122: int
123: icom_init(
124: char *device, /* device name/link */
125: int speed, /* line speed */
126: int trace /* trace flags */ )
127: {
128: TTY ttyb;
129: int fd;
130: int flags;
131: int rc;
132: int saved_errno;
133:
134: flags = trace;
135: fd = tty_open(device, O_RDWR, 0777);
136: if (fd < 0)
137: return -1;
138:
139: rc = tcgetattr(fd, &ttyb);
140: if (rc < 0) {
141: saved_errno = errno;
142: close(fd);
143: errno = saved_errno;
144: return -1;
145: }
146: ttyb.c_iflag = 0; /* input modes */
147: ttyb.c_oflag = 0; /* output modes */
148: ttyb.c_cflag = IBAUD|CS8|CLOCAL; /* control modes (no read) */
149: ttyb.c_lflag = 0; /* local modes */
150: ttyb.c_cc[VMIN] = 0; /* min chars */
151: ttyb.c_cc[VTIME] = 5; /* receive timeout */
152: cfsetispeed(&ttyb, (u_int)speed);
153: cfsetospeed(&ttyb, (u_int)speed);
154: rc = tcsetattr(fd, TCSANOW, &ttyb);
155: if (rc < 0) {
156: saved_errno = errno;
157: close(fd);
158: errno = saved_errno;
159: return -1;
160: }
161: return (fd);
162: }
163:
164: /* end program */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>