~ubuntu-branches/debian/jessie/digitemp/jessie

« back to all changes in this revision

Viewing changes to userial/ds9097u/linuxlnk.c

  • Committer: Bazaar Package Importer
  • Author(s): Jesus Roncero
  • Date: 2004-09-01 01:34:37 UTC
  • Revision ID: james.westby@ubuntu.com-20040901013437-eicsrrd40dr371u0
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//---------------------------------------------------------------------------
 
2
// Copyright (C) 2000 Dallas Semiconductor Corporation, All Rights Reserved.
 
3
//
 
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:
 
10
//
 
11
// The above copyright notice and this permission notice shall be included
 
12
// in all copies or substantial portions of the Software.
 
13
//
 
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.
 
21
//
 
22
// Except as contained in this notice, the name of Dallas Semiconductor
 
23
// shall not be used except as stated in the Dallas Semiconductor
 
24
// Branding Policy.
 
25
//---------------------------------------------------------------------------
 
26
//
 
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.
 
30
//
 
31
//  Version: 1.02
 
32
//
 
33
//  History: 1.00 -> 1.01  Added function msDelay.
 
34
//
 
35
//           1.01 -> 1.02  Changed to generic OpenCOM/CloseCOM for easier
 
36
//                         use with other platforms.
 
37
//
 
38
 
 
39
//--------------------------------------------------------------------------
 
40
// Copyright (C) 1998 Andrea Chambers and University of Newcastle upon Tyne,
 
41
// All Rights Reserved.
 
42
//--------------------------------------------------------------------------
 
43
//
 
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:
 
50
//
 
51
// The above copyright notice and this permission notice shall be included
 
52
// in all copies or substantial portions of the Software.
 
53
//
 
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
//---------------------------------------------------------------------------
 
62
//
 
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.
 
66
//
 
67
//  Version: 2.01
 
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()
 
79
//
 
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.
 
85
//
 
86
 
 
87
#include <unistd.h>
 
88
#include <sys/types.h>
 
89
#include <sys/stat.h>
 
90
#include <fcntl.h>
 
91
#include <sys/ioctl.h>
 
92
#include <time.h>
 
93
#include <termios.h>
 
94
#include <errno.h>
 
95
#include <sys/time.h>
 
96
 
 
97
#include "ds2480.h"
 
98
#include "ownet.h"
 
99
 
 
100
/* exportable functions */
 
101
SMALLINT  OpenCOM(int, char*);
 
102
SMALLINT  WriteCOM(int, int, uchar*);
 
103
void      CloseCOM(int);
 
104
void      FlushCOM(int);
 
105
int       ReadCOM(int, int, uchar*);
 
106
void      BreakCOM(int);
 
107
void      SetBaudCOM(int, int);
 
108
void      msDelay(int);
 
109
long      msGettick(void);
 
110
 
 
111
// LinuxLNK global
 
112
int fd[MAX_PORTNUM];
 
113
struct termios origterm;
 
114
 
 
115
//---------------------------------------------------------------------------
 
116
// Attempt to open a com port.
 
117
// Set the starting baud rate to 9600.
 
118
//
 
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.
 
122
//
 
123
// 'port_zstr' - zero terminate port name.  For this platform
 
124
//               use format COMX where X is the port number.
 
125
//
 
126
//
 
127
// Returns: TRUE(1)  - success, COM port opened
 
128
//          FALSE(0) - failure, could not open specified port
 
129
//
 
130
SMALLINT OpenCOM(int portnum, char *port_zstr)
 
131
{
 
132
   struct termios t;               // see man termios - declared as above
 
133
   int rc;
 
134
 
 
135
   fd[portnum] = open(port_zstr, O_RDWR|O_NONBLOCK);
 
136
   if (fd[portnum]<0)
 
137
   {
 
138
      OWERROR(OWERROR_GET_SYSTEM_RESOURCE_FAILED);
 
139
      return FALSE;  // changed (2.00), used to return fd;
 
140
   }
 
141
   rc = tcgetattr (fd[portnum], &t);
 
142
   if (rc < 0)
 
143
   {
 
144
      int tmp;
 
145
      tmp = errno;
 
146
      close(fd[portnum]);
 
147
      errno = tmp;
 
148
      OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 
149
      return FALSE; // changed (2.00), used to return rc;
 
150
   }
 
151
 
 
152
   cfsetospeed(&t, B9600);
 
153
   cfsetispeed (&t, B9600);
 
154
 
 
155
   // Get terminal parameters. (2.00) removed raw
 
156
   tcgetattr(fd[portnum],&t);
 
157
   // Save original settings.
 
158
   origterm = t;
 
159
 
 
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);
 
167
   t.c_cc[VMIN] = 0;
 
168
   t.c_cc[VTIME] = 3;
 
169
 
 
170
   rc = tcsetattr(fd[portnum], TCSAFLUSH, &t);
 
171
   tcflush(fd[portnum],TCIOFLUSH);
 
172
 
 
173
   if (rc < 0)
 
174
   {
 
175
      int tmp;
 
176
      tmp = errno;
 
177
      close(fd[portnum]);
 
178
      errno = tmp;
 
179
      OWERROR(OWERROR_SYSTEM_RESOURCE_INIT_FAILED);
 
180
      return FALSE; // changed (2.00), used to return rc;
 
181
   }
 
182
 
 
183
   return TRUE; // changed (2.00), used to return fd;
 
184
}
 
185
 
 
186
 
 
187
//---------------------------------------------------------------------------
 
188
// Closes the connection to the port.
 
189
//
 
190
// 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
 
191
//              OpenCOM to indicate the port number.
 
192
//
 
193
void CloseCOM(int portnum)
 
194
{
 
195
   // restore tty settings
 
196
   tcsetattr(fd[portnum], TCSAFLUSH, &origterm);
 
197
   FlushCOM(portnum);
 
198
   close(fd[portnum]);
 
199
}
 
200
 
 
201
 
 
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.
 
205
//
 
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
 
210
//
 
211
SMALLINT WriteCOM(int portnum, int outlen, uchar *outbuf)
 
212
{
 
213
   long count = outlen;
 
214
   int i = write(fd[portnum], outbuf, outlen);
 
215
 
 
216
   tcdrain(fd[portnum]);
 
217
   return (i == count);
 
218
}
 
219
 
 
220
 
 
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.
 
224
//
 
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
 
229
//
 
230
// Returns:  Number of bytes actually read
 
231
//
 
232
int ReadCOM(int portnum, int inlen, uchar *inbuf)
 
233
{
 
234
   fd_set         filedescr;
 
235
   struct timeval tval;
 
236
   int            cnt;
 
237
   int            sel;
 
238
   int            msec = 0;
 
239
   extern int     global_msec,
 
240
                  global_msec_max;
 
241
 
 
242
 
 
243
   // loop to wait until each byte is available and read it
 
244
   for (cnt = 0; cnt < inlen; cnt++)
 
245
   {
 
246
      if( msec < global_msec )
 
247
         msec = global_msec;
 
248
 
 
249
      // set a descriptor to wait for a character available
 
250
      FD_ZERO(&filedescr);
 
251
      FD_SET(fd[portnum],&filedescr);
 
252
      // set initial timeout to global_msec ms
 
253
      tval.tv_sec = 1;
 
254
      tval.tv_usec = 1000 * msec;
 
255
 
 
256
      // if byte available read or return bytes read
 
257
      sel = select(fd[portnum]+1,&filedescr,NULL,NULL,&tval);
 
258
      if ( sel > 0 )
 
259
      {
 
260
         if (read(fd[portnum],&inbuf[cnt],1) != 1)
 
261
         {
 
262
            /* Received something, return it */
 
263
            return cnt;
 
264
         }
 
265
      } else if( sel == 0 ) {
 
266
         /* We timed out waiting for a character, so increase the limit */
 
267
         global_msec++;
 
268
         cnt = -1;
 
269
 
 
270
#ifdef DEBUG_USERIAL
 
271
         fprintf(stderr, "Increasing delay to %ld\n", global_msec * 1000 );
 
272
#endif /* DEBUG_USERIAL */
 
273
 
 
274
         /* don't go too high, just return an error (0) */
 
275
         if( global_msec > global_msec_max )
 
276
           return 0;
 
277
      } else {
 
278
         return cnt;
 
279
      } /* select if */
 
280
   } /* count loop */
 
281
 
 
282
   // success, so return desired length
 
283
   return inlen;
 
284
}
 
285
 
 
286
 
 
287
//---------------------------------------------------------------------------
 
288
//  Description:
 
289
//     flush the rx and tx buffers
 
290
//
 
291
// 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
 
292
//              OpenCOM to indicate the port number.
 
293
//
 
294
void FlushCOM(int portnum)
 
295
{
 
296
   tcflush(fd[portnum], TCIOFLUSH);
 
297
}
 
298
 
 
299
 
 
300
//--------------------------------------------------------------------------
 
301
//  Description:
 
302
//     Send a break on the com port for at least 2 ms
 
303
//
 
304
// 'portnum'  - number 0 to MAX_PORTNUM-1.  This number was provided to
 
305
//              OpenCOM to indicate the port number.
 
306
//
 
307
void BreakCOM(int portnum)
 
308
{
 
309
   int duration = 0;                       // see man termios break may be
 
310
   tcsendbreak(fd[portnum], duration);     // too long
 
311
}
 
312
 
 
313
 
 
314
//--------------------------------------------------------------------------
 
315
// Set the baud rate on the com port.
 
316
//
 
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
 
320
// PARMSET_9600     0x00
 
321
// PARMSET_19200    0x02
 
322
// PARMSET_57600    0x04
 
323
// PARMSET_115200   0x06
 
324
//
 
325
void SetBaudCOM(int portnum, int new_baud)
 
326
{
 
327
   struct termios t;
 
328
   int rc;
 
329
   speed_t baud=B9600;
 
330
 
 
331
   // read the attribute structure
 
332
   rc = tcgetattr(fd[portnum], &t);
 
333
   if (rc < 0)
 
334
   {
 
335
      close(fd[portnum]);
 
336
      return;
 
337
   }
 
338
 
 
339
   // convert parameter to linux baud rate
 
340
   switch(new_baud)
 
341
   {
 
342
      case PARMSET_9600:
 
343
         baud = B9600;
 
344
         break;
 
345
      case PARMSET_19200:
 
346
         baud = B19200;
 
347
         break;
 
348
      case PARMSET_57600:
 
349
         baud = B57600;
 
350
         break;
 
351
      case PARMSET_115200:
 
352
         baud = B115200;
 
353
         break;
 
354
   }
 
355
 
 
356
   // set baud in structure
 
357
   cfsetospeed(&t, baud);
 
358
   cfsetispeed(&t, baud);
 
359
 
 
360
   // change baud on port
 
361
   rc = tcsetattr(fd[portnum], TCSAFLUSH, &t);
 
362
   if (rc < 0)
 
363
      close(fd[portnum]);
 
364
}
 
365
 
 
366
 
 
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.
 
370
//
 
371
long msGettick(void)
 
372
{
 
373
   struct timezone tmzone;
 
374
   struct timeval  tmval;
 
375
   long ms;
 
376
 
 
377
   gettimeofday(&tmval,&tmzone);
 
378
   ms = (tmval.tv_sec & 0xFFFF) * 1000 + tmval.tv_usec / 1000;
 
379
   return ms;
 
380
}
 
381
 
 
382
 
 
383
//--------------------------------------------------------------------------
 
384
//  Description:
 
385
//     Delay for at least 'len' ms
 
386
//
 
387
void msDelay(int len)
 
388
{
 
389
   struct timespec s;              // Set aside memory space on the stack
 
390
 
 
391
   s.tv_sec = len / 1000;
 
392
   s.tv_nsec = (len - (s.tv_sec * 1000)) * 1000000;
 
393
   nanosleep(&s, NULL);
 
394
}
 
395