1
//---------------------------------------------------------------------------
2
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
4
// Permission is hereby granted, free of charge, to any person obtaining a
5
// copy of this software and associated documentation files (the "Software"),
6
// to deal in the Software without restriction, including without limitation
7
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
// and/or sell copies of the Software, and to permit persons to whom the
9
// Software is furnished to do so, subject to the following conditions:
11
// The above copyright notice and this permission notice shall be included
12
// in all copies or substantial portions of the Software.
14
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17
// IN NO EVENT SHALL DALLAS SEMICONDUCTOR BE LIABLE FOR ANY CLAIM, DAMAGES
18
// OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19
// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20
// OTHER DEALINGS IN THE SOFTWARE.
22
// Except as contained in this notice, the name of Dallas Semiconductor
23
// shall not be used except as stated in the Dallas Semiconductor
25
//---------------------------------------------------------------------------
27
// linuxlnk.C - COM functions required by MLANLL.C, MLANTRNU, MLANNETU.C and
28
// MLanFile.C for MLANU to communicate with the DS2480 based
29
// Universal Serial Adapter 'U'. Fill in the platform specific code.
33
// History: 1.00 -> 1.01 Added function msDelay.
35
// 1.01 -> 1.02 Changed to generic OpenCOM/CloseCOM for easier
36
// use with other platforms.
39
//--------------------------------------------------------------------------
40
// Copyright (C) 1998 Andrea Chambers and University of Newcastle upon Tyne,
41
// All Rights Reserved.
42
//--------------------------------------------------------------------------
44
// Permission is hereby granted, free of charge, to any person obtaining a
45
// copy of this software and associated documentation files (the "Software"),
46
// to deal in the Software without restriction, including without limitation
47
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
48
// and/or sell copies of the Software, and to permit persons to whom the
49
// Software is furnished to do so, subject to the following conditions:
51
// The above copyright notice and this permission notice shall be included
52
// in all copies or substantial portions of the Software.
54
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
55
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
56
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
57
// IN NO EVENT SHALL THE UNIVERSITY OF NEWCASTLE UPON TYNE OR ANDREA CHAMBERS
58
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
59
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH
60
// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
61
//---------------------------------------------------------------------------
63
// LinuxLNK.C - COM functions required by MLANLLU.C, MLANTRNU.C, MLANNETU.C
64
// and MLanFile.C for MLANU to communicate with the DS2480 based
65
// Universal Serial Adapter 'U'. Platform specific code.
68
// History: 1.02 -> 1.03 modifications by David Smiczek
69
// Changed to use generic OpenCOM/CloseCOM
70
// Pass port name to OpenCOM instead of hard coded
71
// Changed msDelay to handle long delays
72
// Reformatted to look like 'TODO.C'
73
// Added #include "ds2480.h" to use constants.
74
// Added function SetBaudCOM()
75
// Added function msGettick()
76
// Removed delay from WriteCOM(), used tcdrain()
77
// Added wait for byte available with timeout using
78
// select() in ReadCOM()
80
// 1.03 -> 2.00 Support for multiple ports. Include "ownet.h". Use
81
// 'uchar'. Reorder functions. Provide correct
82
// return values to OpenCOM. Replace 'makeraw' call.
83
// Should now be POSIX.
84
// 2.00 -> 2.01 Added support for owError library.
88
#include <sys/types.h>
91
#include <sys/ioctl.h>
100
/* exportable functions */
101
SMALLINT OpenCOM(int, char*);
102
SMALLINT WriteCOM(int, int, uchar*);
105
int ReadCOM(int, int, uchar*);
107
void SetBaudCOM(int, int);
109
long msGettick(void);
113
struct termios origterm;
115
//---------------------------------------------------------------------------
116
// Attempt to open a com port.
117
// Set the starting baud rate to 9600.
119
// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
120
// be used to indicate the port number desired when calling
121
// all other functions in this library.
123
// 'port_zstr' - zero terminate port name. For this platform
124
// use format COMX where X is the port number.
127
// Returns: TRUE(1) - success, COM port opened
128
// FALSE(0) - failure, could not open specified port
130
SMALLINT OpenCOM(int portnum, char *port_zstr)
132
struct termios t; // see man termios - declared as above
135
fd[portnum] = open(port_zstr, O_RDWR|O_NONBLOCK);
138
OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED);
139
return FALSE; // changed (2.00), used to return fd;
141
rc = tcgetattr (fd[portnum], &t);
148
OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
149
return FALSE; // changed (2.00), used to return rc;
152
cfsetospeed(&t, B9600);
153
cfsetispeed (&t, B9600);
155
// Get terminal parameters. (2.00) removed raw
156
tcgetattr(fd[portnum],&t);
157
// Save original settings.
160
// Set to non-canonical mode, and no RTS/CTS handshaking
161
t.c_iflag &= ~(BRKINT|ICRNL|IGNCR|INLCR|INPCK|ISTRIP|IXON|IXOFF|PARMRK);
162
t.c_iflag |= IGNBRK|IGNPAR;
163
t.c_oflag &= ~(OPOST);
164
t.c_cflag &= ~(CRTSCTS|CSIZE|HUPCL|PARENB);
165
t.c_cflag |= (CLOCAL|CS8|CREAD);
166
t.c_lflag &= ~(ECHO|ECHOE|ECHOK|ECHONL|ICANON|IEXTEN|ISIG);
170
rc = tcsetattr(fd[portnum], TCSAFLUSH, &t);
171
tcflush(fd[portnum],TCIOFLUSH);
179
OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
180
return FALSE; // changed (2.00), used to return rc;
183
return TRUE; // changed (2.00), used to return fd;
187
//---------------------------------------------------------------------------
188
// Closes the connection to the port.
190
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
191
// OpenCOM to indicate the port number.
193
void CloseCOM(int portnum)
195
// restore tty settings
196
tcsetattr(fd[portnum], TCSAFLUSH, &origterm);
202
//--------------------------------------------------------------------------
203
// Write an array of bytes to the COM port, verify that it was
204
// sent out. Assume that baud rate has been set.
206
// 'portnum' - number 0 to MAX_PORTNUM-1. This number provided will
207
// be used to indicate the port number desired when calling
208
// all other functions in this library.
209
// Returns 1 for success and 0 for failure
211
SMALLINT WriteCOM(int portnum, int outlen, uchar *outbuf)
214
int i = write(fd[portnum], outbuf, outlen);
216
tcdrain(fd[portnum]);
221
//--------------------------------------------------------------------------
222
// Read an array of bytes to the COM port, verify that it was
223
// sent out. Assume that baud rate has been set.
225
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
226
// OpenCOM to indicate the port number.
227
// 'outlen' - number of bytes to write to COM port
228
// 'outbuf' - pointer ot an array of bytes to write
230
// Returns: Number of bytes actually read
232
int ReadCOM(int portnum, int inlen, uchar *inbuf)
239
extern int global_msec,
243
// loop to wait until each byte is available and read it
244
for (cnt = 0; cnt < inlen; cnt++)
246
if( msec < global_msec )
249
// set a descriptor to wait for a character available
251
FD_SET(fd[portnum],&filedescr);
252
// set initial timeout to global_msec ms
254
tval.tv_usec = 1000 * msec;
256
// if byte available read or return bytes read
257
sel = select(fd[portnum]+1,&filedescr,NULL,NULL,&tval);
260
if (read(fd[portnum],&inbuf[cnt],1) != 1)
262
/* Received something, return it */
265
} else if( sel == 0 ) {
266
/* We timed out waiting for a character, so increase the limit */
271
fprintf(stderr, "Increasing delay to %ld\n", global_msec * 1000 );
272
#endif /* DEBUG_USERIAL */
274
/* don't go too high, just return an error (0) */
275
if( global_msec > global_msec_max )
282
// success, so return desired length
287
//---------------------------------------------------------------------------
289
// flush the rx and tx buffers
291
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
292
// OpenCOM to indicate the port number.
294
void FlushCOM(int portnum)
296
tcflush(fd[portnum], TCIOFLUSH);
300
//--------------------------------------------------------------------------
302
// Send a break on the com port for at least 2 ms
304
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
305
// OpenCOM to indicate the port number.
307
void BreakCOM(int portnum)
309
int duration = 0; // see man termios break may be
310
tcsendbreak(fd[portnum], duration); // too long
314
//--------------------------------------------------------------------------
315
// Set the baud rate on the com port.
317
// 'portnum' - number 0 to MAX_PORTNUM-1. This number was provided to
318
// OpenCOM to indicate the port number.
319
// 'new_baud' - new baud rate defined as
321
// PARMSET_19200 0x02
322
// PARMSET_57600 0x04
323
// PARMSET_115200 0x06
325
void SetBaudCOM(int portnum, int new_baud)
331
// read the attribute structure
332
rc = tcgetattr(fd[portnum], &t);
339
// convert parameter to linux baud rate
356
// set baud in structure
357
cfsetospeed(&t, baud);
358
cfsetispeed(&t, baud);
360
// change baud on port
361
rc = tcsetattr(fd[portnum], TCSAFLUSH, &t);
367
//--------------------------------------------------------------------------
368
// Get the current millisecond tick count. Does not have to represent
369
// an actual time, it just needs to be an incrementing timer.
373
struct timezone tmzone;
374
struct timeval tmval;
377
gettimeofday(&tmval,&tmzone);
378
ms = (tmval.tv_sec & 0xFFFF) * 1000 + tmval.tv_usec / 1000;
383
//--------------------------------------------------------------------------
385
// Delay for at least 'len' ms
387
void msDelay(int len)
389
struct timespec s; // Set aside memory space on the stack
391
s.tv_sec = len / 1000;
392
s.tv_nsec = (len - (s.tv_sec * 1000)) * 1000000;