Browse Source

cmSerialPort.h/c : Initial commit.

master
kevin.larke 4 years ago
parent
commit
575db4382d
2 changed files with 652 additions and 0 deletions
  1. 562
    0
      cmSerialPort.c
  2. 90
    0
      cmSerialPort.h

+ 562
- 0
cmSerialPort.c View File

1
+#include "cmPrefix.h"
2
+#include "cmGlobal.h"
3
+#include "cmRpt.h"
4
+#include "cmErr.h"
5
+#include "cmCtx.h"
6
+#include "cmMem.h"
7
+#include "cmMallocDebug.h"
8
+#include "cmSerialPort.h"
9
+#include "cmThread.h"
10
+
11
+#include <poll.h>
12
+#include <termios.h>
13
+#include <unistd.h>    // close()
14
+#include <fcntl.h>     // O_RDWR
15
+#include <sys/ioctl.h> // TIOCEXCL
16
+
17
+typedef struct cmSerialPort_str
18
+{
19
+  cmErr_t               _err;
20
+  cmThreadH_t           _thH; 
21
+  const char*           _deviceStr;
22
+  int                   _deviceH;
23
+  unsigned              _baudRate;
24
+  unsigned              _cfgFlags;
25
+  cmSeCallbackFunc_t    _cbFunc;
26
+  void*                 _cbArg;
27
+  struct termios        _ttyAttrs;
28
+  struct pollfd         _pollfd;
29
+  unsigned              _pollPeriodMs;
30
+} cmSerialPort_t;
31
+
32
+cmSerialPort_t* _cmSePtrFromHandle( cmSeH_t h )
33
+{
34
+  cmSerialPort_t* p = (cmSerialPort_t*)h.h;
35
+  assert(p!=NULL);
36
+  return p;
37
+}
38
+
39
+void   _cmSeSetClosedState( cmSerialPort_t* p )
40
+{
41
+  if( p->_deviceStr != NULL )
42
+    cmMemFree((char*)(p->_deviceStr));
43
+     
44
+  p->_deviceH = -1;
45
+  p->_deviceStr = NULL;
46
+  p->_baudRate  = 0;
47
+  p->_cfgFlags  = 0;
48
+  p->_cbFunc    = NULL;
49
+  p->_cbArg     = NULL;
50
+      
51
+}
52
+    
53
+cmSeRC_t _cmSeGetAttributes( cmSerialPort_t* p, struct termios* attr ) 
54
+{
55
+  if( tcgetattr(p->_deviceH, attr) == -1 )
56
+    return cmErrSysMsg(&p->_err,kGetAttrFailSeRC,errno,"Error getting tty attributes from %s.",p->_deviceStr);
57
+
58
+  return kOkSeRC;
59
+}
60
+    
61
+cmSeRC_t _cmSePoll( cmSerialPort_t* p, unsigned timeOutMs )
62
+{
63
+  cmSeRC_t rc = kOkSeRC;
64
+  int sysRC;
65
+
66
+  if((sysRC = poll(&p->_pollfd,1,timeOutMs)) == 0)
67
+    rc = kTimeOutSeRC;
68
+  else
69
+  {
70
+    if( sysRC < 0 )
71
+      rc = cmErrSysMsg(&p->_err,kReadFailSeRC,errno,"Poll failed on serial port.");
72
+  }
73
+  
74
+  return rc;
75
+      
76
+}
77
+
78
+bool _cmSeThreadFunc(void* param)
79
+{
80
+  cmSerialPort_t* p = (cmSerialPort_t*)param;
81
+  cmSeH_t h;
82
+  h.h = p;
83
+  unsigned readN;
84
+  if( cmSeIsOpen(h) )
85
+    cmSeReceiveCbTimeOut(h,p->_pollPeriodMs,&readN);
86
+  
87
+      
88
+  
89
+  return true;
90
+}
91
+
92
+    
93
+cmSeRC_t _cmSeDestroy( cmSerialPort_t* p )
94
+{
95
+  cmSeRC_t rc = kOkSeRC;
96
+
97
+
98
+  // stop the thread first
99
+  if( cmThreadDestroy(&p->_thH) != kOkThRC )
100
+  {
101
+    rc = cmErrMsg(&p->_err,kThreadErrSeRC,"Thread destroy failed.");
102
+    goto errLabel;
103
+  }
104
+  
105
+  // Block until all written output has been sent from the device.
106
+  // Note that this call is simply passed on to the serial device driver.
107
+  // See tcsendbreak(3) ("man 3 tcsendbreak") for details.
108
+  if (tcdrain(p->_deviceH) == -1)
109
+  {
110
+    rc = cmErrSysMsg(&p->_err,kFlushFailSeRC,errno,"Error waiting for serial device '%s' to drain.", p->_deviceStr );
111
+    goto errLabel;
112
+  }
113
+
114
+  // It is good practice to reset a serial port back to the state in
115
+  // which you found it. This is why we saved the original termios struct
116
+  // The constant TCSANOW (defined in termios.h) indicates that
117
+  // the change should take effect immediately.
118
+
119
+  if (tcsetattr(p->_deviceH, TCSANOW, &p->_ttyAttrs) ==  -1)
120
+  {
121
+    rc = cmErrSysMsg(&p->_err,kSetAttrFailSeRC,errno,"Error resetting tty attributes on serial device '%s'.",p->_deviceStr);
122
+    goto errLabel;
123
+  }
124
+	
125
+  if( p->_deviceH != -1 )
126
+  {
127
+    if( close(p->_deviceH ) != 0 )
128
+    {
129
+      rc = cmErrSysMsg(&p->_err,kCloseFailSeRC,errno,"Port close failed on serial dvice '%s'.", p->_deviceStr);
130
+      goto errLabel;
131
+    }
132
+		
133
+    _cmSeSetClosedState(p);
134
+  }
135
+
136
+  cmMemPtrFree(&p);
137
+
138
+ errLabel:
139
+  return rc;      
140
+}
141
+    
142
+
143
+cmSeH_t cmSeCreate( cmCtx_t* ctx, cmSeH_t* hp, const char* deviceStr, unsigned baudRate, unsigned cfgFlags, cmSeCallbackFunc_t cbFunc, void* cbArg, unsigned pollPeriodMs )
144
+{
145
+  cmSeRC_t       rc = kOkSeRC;
146
+  struct termios options;
147
+  cmSeH_t h;
148
+  
149
+  // if the port is already open then close it
150
+  if((rc = cmSeDestroy(hp)) != kOkSeRC )
151
+    return *hp;
152
+
153
+  cmSerialPort_t* p = cmMemAllocZ(cmSerialPort_t,1);
154
+  
155
+  cmErrSetup(&p->_err,&ctx->rpt,"Serial Port");
156
+
157
+  p->_deviceH = -1;
158
+    
159
+	// open the port		
160
+	if( (p->_deviceH = open(deviceStr, O_RDWR | O_NOCTTY | O_NONBLOCK)) == -1 )
161
+	{
162
+		rc = cmErrSysMsg(&p->_err,kOpenFailSeRC,errno,"Error opening serial '%s'",cmStringNullGuard(deviceStr));
163
+		goto errLabel;;
164
+	}
165
+
166
+  // Note that open() follows POSIX semantics: multiple open() calls to 
167
+  // the same file will succeed unless the TIOCEXCL ioctl is issued.
168
+  // This will prevent additional opens except by root-owned processes.
169
+  // See tty(4) ("man 4 tty") and ioctl(2) ("man 2 ioctl") for details.
170
+  
171
+  if( ioctl(p->_deviceH, TIOCEXCL) == -1 )
172
+  {
173
+    rc = cmErrSysMsg(&p->_err,kResourceNotAvailableSeRC,errno,"The serial device '%s' is already in use.", cmStringNullGuard(deviceStr));
174
+    goto errLabel;
175
+  }
176
+
177
+
178
+  // Now that the device is open, clear the O_NONBLOCK flag so 
179
+  // subsequent I/O will block.
180
+  // See fcntl(2) ("man 2 fcntl") for details.
181
+ 	/*
182
+    if (fcntl(_deviceH, F_SETFL, 0) == -1)
183
+
184
+    {
185
+    _error("Error clearing O_NONBLOCK %s - %s(%d).", pr.devFilePath.c_str(), strerror(errno), errno);
186
+    goto errLabel;
187
+    }
188
+	*/
189
+	
190
+  // Get the current options and save them so we can restore the 
191
+  // default settings later.
192
+  if (tcgetattr(p->_deviceH, &p->_ttyAttrs) == -1)
193
+  {
194
+    rc = cmErrSysMsg(&p->_err,kGetAttrFailSeRC,errno,"Error getting tty attributes from the device '%s'.",deviceStr);
195
+    goto errLabel;
196
+  }
197
+
198
+
199
+  // The serial port attributes such as timeouts and baud rate are set by 
200
+  // modifying the termios structure and then calling tcsetattr to
201
+  // cause the changes to take effect. Note that the
202
+  // changes will not take effect without the tcsetattr() call.
203
+  // See tcsetattr(4) ("man 4 tcsetattr") for details.
204
+  options = p->_ttyAttrs;
205
+
206
+
207
+  // Set raw input (non-canonical) mode, with reads blocking until either 
208
+  // a single character has been received or a 100ms timeout expires.
209
+  // See tcsetattr(4) ("man 4 tcsetattr") and termios(4) ("man 4 termios") 
210
+  // for details.
211
+  cfmakeraw(&options);
212
+  options.c_cc[VMIN] = 1;
213
+  options.c_cc[VTIME] = 1;
214
+
215
+
216
+  // The baud rate, word length, and handshake options can be set as follows:
217
+
218
+ 
219
+	// set baud rate
220
+  cfsetspeed(&options, baudRate);
221
+  
222
+  options.c_cflag |=  CREAD | CLOCAL; // ignore modem controls
223
+
224
+  // set data word size
225
+  cmClrBits(options.c_cflag, CSIZE); // clear the word size bits
226
+  cmEnaBits(options.c_cflag,	CS5,			cmIsFlag(cfgFlags, kDataBits5SeFl));
227
+  cmEnaBits(options.c_cflag,	CS6,			cmIsFlag(cfgFlags, kDataBits6SeFl));
228
+  cmEnaBits(options.c_cflag,	CS7,			cmIsFlag(cfgFlags, kDataBits7SeFl));
229
+  cmEnaBits(options.c_cflag,	CS8,			cmIsFlag(cfgFlags, kDataBits8SeFl));
230
+
231
+  cmClrBits(options.c_cflag, PARENB); // assume no-parity
232
+
233
+  // if the odd or even parity flag is set
234
+  if( cmIsFlag( cfgFlags, kEvenParitySeFl) || cmIsFlag( cfgFlags, kOddParitySeFl ) )
235
+  {
236
+    cmSetBits(options.c_cflag,	PARENB);
237
+    	
238
+    if( cmIsFlag(cfgFlags, kOddParitySeFl ) )
239
+      cmSetBits( options.c_cflag,	PARODD);
240
+  }
241
+
242
+	// set two stop bits    
243
+  cmEnaBits( options.c_cflag, CSTOPB, cmIsFlag(cfgFlags, k2StopBitSeFl));
244
+    
245
+    		    
246
+  // set hardware flow control
247
+  //cmEnaBits(options.c_cflag,		CCTS_OFLOW, 	cmIsFlag(cfgFlags, kCTS_OutFlowCtlFl)); 
248
+	//cmEnaBits(options.c_cflag, 	CRTS_IFLOW, 	cmIsFlag(cfgFlags, kRTS_InFlowCtlFl));
249
+	//cmEnaBits(options.c_cflag, 	CDTR_IFLOW, 	cmIsFlag(cfgFlags, kDTR_InFlowCtlFl));
250
+	//cmEnaBits(options.c_cflag, 	CDSR_OFLOW, 	cmIsFlag(cfgFlags, kDSR_OutFlowCtlFl));
251
+	//cmEnaBits(options.c_cflag, 	CCAR_OFLOW, 	cmIsFlag(cfgFlags, kDCD_OutFlowCtlFl));
252
+    
253
+	cmClrBits(options.c_cflag,CRTSCTS); // turn-off hardware flow control
254
+
255
+	// 7 bit words, enable even parity, CTS out ctl flow, RTS in ctl flow
256
+	// note: set PARODD and PARENB to enable odd parity)
257
+	//options.c_cflag |= (CS7 | PARENB | CCTS_OFLOW | CRTS_IFLOW );
258
+
259
+  // Cause the new options to take effect immediately.
260
+  if (tcsetattr(p->_deviceH, TCSANOW, &options) == -1)
261
+  {
262
+
263
+    rc = cmErrSysMsg(&p->_err,kSetAttrFailSeRC,errno,"Error setting tty attributes on serial device %.", deviceStr);
264
+    goto errLabel;
265
+  }
266
+  
267
+  memset(&p->_pollfd,0,sizeof(p->_pollfd));
268
+  p->_pollfd.fd     = p->_deviceH;
269
+  p->_pollfd.events = POLLIN;
270
+  
271
+  p->_deviceStr    = cmMemAllocStr( deviceStr );
272
+  p->_baudRate     = baudRate;
273
+	p->_cfgFlags     = cfgFlags;
274
+  p->_cbFunc       = cbFunc;
275
+  p->_cbArg        = cbArg;
276
+  p->_pollPeriodMs = pollPeriodMs;
277
+
278
+  // create the listening thread
279
+  if( cmThreadCreate( &p->_thH, _cmSeThreadFunc, p, &ctx->rpt) != kOkThRC )
280
+  {
281
+    rc = cmErrMsg(&p->_err,kThreadErrSeRC,"Thread initialization failed.");
282
+    goto errLabel;
283
+  }
284
+
285
+  if( cmThreadPause(p->_thH,0) != kOkThRC )
286
+  {
287
+    rc = cmErrMsg(&p->_err,kThreadErrSeRC,0,"Thread start failed.");
288
+    goto errLabel;
289
+  }
290
+  
291
+  if( hp != NULL )
292
+    hp->h = p;
293
+  else
294
+    h.h = p;
295
+  
296
+ errLabel:
297
+  if( rc != kOkSeRC )
298
+  {
299
+    _cmSeDestroy(p);
300
+    h.h = NULL;
301
+	}
302
+  
303
+  return hp != NULL ? *hp : h;
304
+  
305
+}
306
+
307
+cmSeRC_t cmSeDestroy(cmSeH_t* hp )
308
+{
309
+  cmSeRC_t rc = kOkSeRC; 
310
+  
311
+  if( hp==NULL || !cmSeIsOpen(*hp) )
312
+    return kOkSeRC;
313
+
314
+  cmSerialPort_t* p = _cmSePtrFromHandle(*hp);
315
+
316
+  if((rc = _cmSeDestroy(p)) != kOkSeRC )
317
+    return rc;
318
+
319
+  hp->h = NULL;
320
+  
321
+  return rc;
322
+}
323
+
324
+bool cmSeIsOpen( cmSeH_t h)
325
+{
326
+  if( h.h == NULL )
327
+    return false;
328
+  
329
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
330
+  return p->_deviceH != -1;
331
+}
332
+
333
+cmSeRC_t cmSeSend( cmSeH_t h, const void* byteA, unsigned byteN )
334
+{
335
+  cmSeRC_t        rc = kOkSeRC;
336
+  cmSerialPort_t* p  = _cmSePtrFromHandle(h);
337
+      
338
+  if( !cmSeIsOpen(h)  )
339
+    return cmErrWarnMsg( &p->_err, kResourceNotAvailableSeRC, "An attempt was made to transmit from a closed serial port.");
340
+        
341
+  if( byteN == 0 )
342
+    return rc;
343
+        
344
+  // implement a non blocking write - if less than all the bytes were written then iterate
345
+  unsigned i = 0;
346
+  do
347
+  {
348
+    int n = 0;
349
+    if((n = write( p->_deviceH, ((char*)byteA)+i, byteN-i )) == -1 )
350
+    {
351
+      rc = cmErrSysMsg(&p->_err,kWriteFailSeRC,errno,"Write failed on serial port '%s'.", p->_deviceStr );
352
+      break;
353
+    }
354
+
355
+    i += n;
356
+
357
+      
358
+  }while( i<byteN );
359
+
360
+  return rc;
361
+  
362
+}
363
+
364
+
365
+cmSeRC_t cmSeReceiveCbNb( cmSeH_t h, unsigned* readN_Ref)
366
+{
367
+  cmSeRC_t        rc   = kOkSeRC;
368
+  cmSerialPort_t* p    = _cmSePtrFromHandle(h);
369
+  const unsigned  bufN = 512;
370
+  char            buf[ bufN ];
371
+
372
+  if( readN_Ref != NULL)
373
+    *readN_Ref = 0;
374
+
375
+  if((rc = cmSeReceiveNb(h,buf,bufN,readN_Ref)) == kOkSeRC )
376
+    if( readN_Ref > 0 && p->_cbFunc != NULL )
377
+      p->_cbFunc( p->_cbArg, buf, *readN_Ref );
378
+
379
+  return rc;
380
+  
381
+}
382
+  
383
+cmSeRC_t cmSeReceiveCbTimeOut( cmSeH_t h, unsigned timeOutMs, unsigned* readN_Ref)
384
+{
385
+  cmSeRC_t        rc;
386
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
387
+
388
+  if((rc = _cmSePoll(p,timeOutMs)) == kOkSeRC )
389
+    rc = cmSeReceiveCbNb(h,readN_Ref);
390
+  return rc;
391
+  
392
+}
393
+
394
+cmSeRC_t cmSeReceiveNb( cmSeH_t h, void* buf, unsigned bufN, unsigned* readN_Ref)
395
+{
396
+  cmSeRC_t        rc = kOkSeRC;
397
+  cmSerialPort_t* p  = _cmSePtrFromHandle(h);
398
+
399
+  if( readN_Ref != NULL )
400
+    *readN_Ref = 0;
401
+  
402
+  if( !cmSeIsOpen(h)  )
403
+    return cmErrWarnMsg(&p->_err, kResourceNotAvailableSeRC, "An attempt was made to read from a closed serial port.");
404
+  
405
+  int       n    = 0;
406
+  
407
+  // if attempt to read the port succeeded ...
408
+  if((n =read( p->_deviceH, buf, bufN )) != -1 )
409
+    *readN_Ref = n;
410
+  else
411
+  {
412
+    // ... or failed and it wasn't because the port was empty
413
+    if( errno != EAGAIN)
414
+      rc = cmErrSysMsg(&p->_err,kReadFailSeRC,errno,"An attempt to read the serial port '%s' failed.", p->_deviceStr );
415
+  }
416
+    
417
+  return rc;
418
+}
419
+    
420
+cmSeRC_t cmSeReceive( cmSeH_t h, void* buf, unsigned bufByteN, unsigned timeOutMs, unsigned* readN_Ref )
421
+{
422
+  cmSeRC_t        rc = kOkSeRC;
423
+  cmSerialPort_t* p  = _cmSePtrFromHandle(h);
424
+  
425
+  if((rc = _cmSePoll(p,timeOutMs)) == kOkSeRC )
426
+    rc = cmSeReceiveNb(h,buf,bufByteN,readN_Ref);
427
+  
428
+  return rc;  
429
+}
430
+
431
+const char* cmSeDevice( cmSeH_t h)
432
+{
433
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
434
+  return p->_deviceStr;
435
+}
436
+    
437
+unsigned    cmSeBaudRate( cmSeH_t h)
438
+{
439
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
440
+  return p->_baudRate;
441
+}
442
+
443
+unsigned    cmSeCfgFlags( cmSeH_t h)
444
+{
445
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
446
+  return p->_cfgFlags;
447
+}
448
+
449
+unsigned cmSeReadInBaudRate( cmSeH_t h )
450
+{
451
+	struct termios attr;
452
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
453
+	
454
+	if((_cmSeGetAttributes(p,&attr)) != kOkSeRC )
455
+		return 0;
456
+
457
+	return cfgetispeed(&attr);	
458
+  
459
+}
460
+
461
+unsigned cmSeReadOutBaudRate( cmSeH_t h)
462
+{
463
+	struct termios attr;
464
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
465
+	
466
+	if((_cmSeGetAttributes(p,&attr)) != kOkSeRC )
467
+		return 0;
468
+		
469
+	return cfgetospeed(&attr);	
470
+  
471
+}
472
+
473
+unsigned cmSeReadCfgFlags( cmSeH_t h)
474
+{
475
+	struct termios attr;	
476
+	unsigned result = 0;
477
+  cmSerialPort_t* p = _cmSePtrFromHandle(h);
478
+
479
+	if((_cmSeGetAttributes(p,&attr)) == false )
480
+		return 0;
481
+
482
+	switch( attr.c_cflag & CSIZE )
483
+	{
484
+		case CS5:
485
+			cmSetBits( result, kDataBits5SeFl);
486
+			break;
487
+			
488
+		case CS6:
489
+			cmSetBits( result, kDataBits6SeFl );
490
+			break;
491
+			
492
+		case CS7:
493
+			cmSetBits( result, kDataBits7SeFl);
494
+			break;
495
+			
496
+		case CS8:
497
+			cmSetBits( result, kDataBits8SeFl);
498
+			break;
499
+	}
500
+	
501
+	cmEnaBits( result, k2StopBitSeFl, cmIsFlag(  attr.c_cflag, CSTOPB ));
502
+	cmEnaBits( result, k1StopBitSeFl, !cmIsFlag( attr.c_cflag, CSTOPB ));
503
+
504
+	if( cmIsFlag( attr.c_cflag, PARENB ) )
505
+	{
506
+		cmEnaBits( result, kOddParitySeFl, 	cmIsFlag( attr.c_cflag, PARODD ));
507
+		cmEnaBits( result, kEvenParitySeFl, 	!cmIsFlag( attr.c_cflag, PARODD ));
508
+	}		
509
+	
510
+	return result;
511
+  
512
+}
513
+
514
+
515
+//====================================================================================================
516
+//
517
+//
518
+
519
+
520
+void _cmSePortTestCb( void* arg, const void* byteA, unsigned byteN )
521
+{
522
+  const char* text = (const char*)byteA;
523
+      
524
+  for(unsigned i=0; i<byteN; ++i)
525
+    printf("%c:%i ",text[i],(int)text[i]);
526
+
527
+  if( byteN )
528
+    fflush(stdout);      
529
+}
530
+
531
+cmSeRC_t cmSePortTest(cmCtx_t* ctx)
532
+{
533
+  // Use this test an Arduino running study/serial/arduino_xmt_rcv/main.c  
534
+  cmSeRC_t                  rc             = kOkSeRC;
535
+  const char*               device         = "/dev/ttyACM0";
536
+  unsigned                  baud           = 38400;
537
+  unsigned                  serialCfgFlags = kDefaultCfgSeFlags;
538
+  unsigned                  pollPeriodMs   = 50;
539
+  cmSeH_t                   h;
540
+
541
+  h.h = NULL;
542
+  
543
+  h = cmSeCreate(ctx,&h,device,baud,serialCfgFlags,_cmSePortTestCb,NULL,pollPeriodMs);
544
+
545
+  bool quitFl = false;
546
+  printf("q=quit\n");
547
+  while(!quitFl)
548
+  {
549
+    char c = getchar();
550
+    
551
+    if( c == 'q')
552
+      quitFl = true;
553
+    else
554
+      if( '0' <= c && c <= 'z' )
555
+        cmSeSend(h,&c,1);
556
+      
557
+    
558
+  }
559
+
560
+  cmSeDestroy(&h);
561
+  return rc;
562
+}

+ 90
- 0
cmSerialPort.h View File

1
+#ifndef cmSerialPort_h
2
+#define cmSerialPort_h
3
+
4
+#ifdef __cplusplus
5
+extern "C" {
6
+#endif
7
+
8
+  typedef unsigned cmSeRC_t;
9
+
10
+  enum
11
+  {
12
+   kOkSeRC = cmOkRC,
13
+   kFlushFailSeRC,
14
+   kSetAttrFailSeRC,
15
+   kCloseFailSeRC,
16
+   kOpenFailSeRC,
17
+   kResourceNotAvailableSeRC,
18
+   kGetAttrFailSeRC,
19
+   kWriteFailSeRC,
20
+   kReadFailSeRC,
21
+   kTimeOutSeRC,
22
+   kThreadErrSeRC
23
+  };
24
+
25
+
26
+  enum
27
+  {
28
+   kDataBits5SeFl 	= 0x0001,
29
+   kDataBits6SeFl 	= 0x0002,
30
+   kDataBits7SeFl 	= 0x0004,
31
+   kDataBits8SeFl 	= 0x0008,
32
+   kDataBitsSeMask	= 0x000f,
33
+   
34
+   k1StopBitSeFl		= 0x0010,
35
+   k2StopBitSeFl 	  = 0x0020,
36
+   
37
+   kEvenParitySeFl	= 0x0040,
38
+   kOddParitySeFl	  = 0x0080,
39
+   kNoParitySeFl		= 0x0000,
40
+
41
+   kDefaultCfgSeFlags = kDataBits8SeFl | k1StopBitSeFl | kNoParitySeFl
42
+  };
43
+
44
+
45
+
46
+  
47
+  typedef void (*cmSeCallbackFunc_t)( void* cbArg, const void* byteA, unsigned byteN );
48
+
49
+  typedef cmHandle_t cmSeH_t;
50
+    
51
+  cmSeH_t cmSeCreate( cmCtx_t* ctx, cmSeH_t* hp, const char* device, unsigned baudRate, unsigned cfgFlags, cmSeCallbackFunc_t cbFunc, void* cbArg, unsigned pollPeriodMs );
52
+  cmSeRC_t    cmSeDestroy(cmSeH_t* hp );
53
+
54
+  bool cmSeIsOpen( cmSeH_t h);
55
+    
56
+  cmSeRC_t cmSeSend( cmSeH_t h, const void* byteA, unsigned byteN );
57
+
58
+
59
+  // Make callback to listener with result of read - Non-blocking
60
+  cmSeRC_t cmSeReceiveCbNb( cmSeH_t h, unsigned* readN_Ref);
61
+  
62
+  // Make callback to listener with result of read - Block for up to timeOutMs.
63
+  cmSeRC_t cmSeReceiveCbTimeOut( cmSeH_t h, unsigned timeOutMs, unsigned* readN_Ref); 
64
+
65
+  // Return result of read in buf[bufByteN] - Non-blocking.
66
+  cmSeRC_t cmSeReceiveNb( cmSeH_t h, void* buf, unsigned bufByteN, unsigned* readN_Ref);
67
+    
68
+  // Return result of read in buf[bufByteN] - Block for up to timeOutMs.
69
+  cmSeRC_t cmSeReceive( cmSeH_t h, void* buf, unsigned bufByteN, unsigned timeOutMs, unsigned* readN_Ref );
70
+
71
+  const char* cmSeDevice( cmSeH_t h);
72
+    
73
+  // Get the baud rate and cfgFlags used to initialize the port
74
+  unsigned    cmSeBaudRate( cmSeH_t h);
75
+  unsigned    cmSeCfgFlags( cmSeH_t h);
76
+
77
+  // Get the baud rate and cfg flags by reading the device.
78
+  // Note the the returned buad rate is a system id rather than the actual baud rate,
79
+  // however the cfgFlags are converted to the same kXXXFl defined in this class.
80
+  unsigned cmSeReadInBaudRate( cmSeH_t h );
81
+  unsigned cmSeReadOutBaudRate( cmSeH_t h);
82
+  unsigned cmSeReadCfgFlags( cmSeH_t h);
83
+
84
+  cmSeRC_t cmSePortTest(cmCtx_t* ctx);
85
+
86
+#ifdef __cplusplus
87
+}
88
+#endif
89
+
90
+#endif

Loading…
Cancel
Save