comparison src/gpf/tst/drv/usart.c @ 0:4e78acac3d88

src/{condat,cs,gpf,nucleus}: import from Selenite
author Mychaela Falconia <falcon@freecalypso.org>
date Fri, 16 Oct 2020 06:23:26 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4e78acac3d88
1 /*
2 +------------------------------------------------------------------------------
3 | File: usart.c
4 +------------------------------------------------------------------------------
5 | Copyright 2002 Texas Instruments Berlin, AG
6 | All rights reserved.
7 |
8 | This file is confidential and a trade secret of Texas
9 | Instruments Berlin, AG
10 | The receipt of or possession of this file does not convey
11 | any rights to reproduce or disclose its contents or to
12 | manufacture, use, or sell anything it may describe, in
13 | whole, or in part, without the specific written consent of
14 | Texas Instruments Berlin, AG.
15 +-----------------------------------------------------------------------------
16 | Purpose : This Modul defines functions for actual or simulated
17 | USART comunication between two PS-Frames.
18 | Use US_set_mode() to select actual USART under windows95 or
19 | under windowsNT, or to select simulated USART under win95/NT
20 +-----------------------------------------------------------------------------
21 */
22
23
24
25 #ifndef __USART_C__
26 #define __USART_C__
27 #endif
28
29 /*==== INCLUDES ===================================================*/
30
31 #include <windows.h>
32 #ifndef _VXWORKS_
33 #include <stdarg.h>
34 #endif
35 #include <stdio.h>
36 #include "typedefs.h"
37 #include "usart.h"
38 #include "printtofile.h"
39
40 /*==== CONSTANTS ==================================================*/
41
42 #define COM_ERROR (CE_FRAME | CE_IOE | CE_OVERRUN)
43 #define XON 0x11
44 #define XOFF 0x13
45
46 #define READER_THREAD_EXIT_CODE 4711
47 #define USART_BUFFER_SIZE 0x10000 /* 65536 */
48 #define FILE_MAX_CHUNK 0x0ffff
49 #define FILE_SLOW_DOWN 0x01
50
51 #ifdef _TOOLS_
52 #define USART_SEND_TIMEOUT 60000
53 #define USART_RCV_TIMEOUT 120000
54 #else /* _TOOLS_ */
55 #define USART_SEND_TIMEOUT INFINITE
56 #define USART_RCV_TIMEOUT INFINITE
57 #endif /* _TOOLS_ */
58
59 /*==== TYPES ======================================================*/
60 typedef struct
61 {
62 UBYTE Connects;
63 UBYTE Type;
64 USHORT CH1_numOfBytes;
65 USHORT CH2_numOfBytes;
66 UBYTE CH1_CTS;
67 UBYTE CH2_CTS;
68 UBYTE CH1_data[USART_BUFFER_SIZE];
69 UBYTE CH2_data[USART_BUFFER_SIZE];
70 } T_USARTStream;
71
72 /*==== EXPORT =====================================================*/
73 /*==== PRIVATE ====================================================*/
74 /*==== VARIABLES ==================================================*/
75
76 static int m_mode=UT_MODE_NT;
77 static long int m_send_timeout=(long int)USART_SEND_TIMEOUT;
78 static long int m_rcv_timeout =(long int)USART_RCV_TIMEOUT;
79 static int first_ut_init = 1;
80 static FILE* m_file=NULL;
81
82 static OVERLAPPED gWriteOverLap;
83 static OVERLAPPED gReadOverLap;
84
85 static int ReaderThreadExitRequest = FALSE;
86
87
88 LOCAL void (*ReceiveCallback)(void) = NULL;
89 static int initialized = FALSE;
90
91 #ifdef COM_AUTOSEARCH
92 static int P = 0;
93 #endif
94
95 #ifdef DEBUG_USART
96 static int usart_in, usart_out;
97 #endif
98
99 T_USARTStream *Stream;
100
101 HANDLE SemCH1_full;
102 HANDLE SemCH2_full;
103 HANDLE SemCH1_empty;
104 HANDLE SemCH2_empty;
105 HANDLE USARTMemHandle;
106 HANDLE *semRCVFull=0, *semRCVEmpty=0;
107 HANDLE *semSNDFull=0, *semSNDEmpty=0;
108 HANDLE ut_sema_handle;
109
110 UBYTE *InBuffer, *OutBuffer, *readPointer;
111 USHORT *InCounter, *OutCounter;
112 UBYTE *CTS = NULL;
113
114
115 static HANDLE hComDev = INVALID_HANDLE_VALUE;
116 static HANDLE hThread = INVALID_HANDLE_VALUE;
117 static int mem_closed = TRUE;
118 static int cls_cnt = 0;
119 static int snd_cnt = 0;
120
121 /*==== FUNCTIONS ==================================================*/
122
123 /*
124 +--------------------------------------------------------------------+
125 | PROJECT : GSM-PS (6147) MODULE : USART |
126 | STATE : code ROUTINE : US_set_mode |
127 +--------------------------------------------------------------------+
128
129 PURPOSE : With this function you can select the UART mode
130 #define US_MODE_95 1
131 #define US_MODE_NT 2
132 #define US_MODE_SIM 3
133 #define US_MODE_FILE 4
134
135 */
136 void US_set_mode(int mode)
137 {
138 m_mode=mode;
139 }
140
141 /*
142 +--------------------------------------------------------------------+
143 | PROJECT : GSM-PS (6147) MODULE : USART |
144 | STATE : code ROUTINE : US_set_mode |
145 +--------------------------------------------------------------------+
146
147 PURPOSE : With this function get the seleced UART mode
148 #define US_MODE_95 1
149 #define US_MODE_NT 2
150 #define US_MODE_SIM 3
151 #define US_MODE_FILE 4
152 */
153 int US_get_mode()
154 {
155 return m_mode;
156 }
157
158 /*
159 +--------------------------------------------------------------------+
160 | PROJECT : GSM-PS (6147) MODULE : USARTSIM |
161 | STATE : code ROUTINE : unlockUSARTMemory |
162 +--------------------------------------------------------------------+
163
164 PURPOSE : unlocks the previously locked shared memory area.
165
166 */
167 LOCAL void markRCVBufferEmpty (void)
168 {
169 ReleaseSemaphore (*semRCVEmpty,
170 1,
171 NULL);
172 }
173
174 LOCAL void markSNDBufferFull (void)
175 {
176 ReleaseSemaphore (*semSNDFull,
177 1,
178 NULL);
179 }
180
181 /*
182 +--------------------------------------------------------------------+
183 | PROJECT : GSM-PS (6147) MODULE : USARTSIM |
184 | STATE : code ROUTINE : waitForSNDBufferEmpty |
185 +--------------------------------------------------------------------+
186
187 PURPOSE : waits for send buffer becoming empty
188
189 RETURNS : 0 .. send buffer is empty
190 -1 .. given up
191
192 */
193 LOCAL int waitForSNDBufferEmpty (void)
194 {
195 if (WaitForSingleObject (*semSNDEmpty, m_send_timeout) NEQ WAIT_OBJECT_0)
196 {
197 int err = GetLastError();
198 PrintToFile("USART: error code %d\n", err);
199 PrintToFile("USART: giving up sending with %d ms timeout :-(\n", m_send_timeout);
200 return -1; /* give up */
201 }
202 return 0;
203 }
204
205
206 /*
207 +--------------------------------------------------------------------+
208 | PROJECT : GSM-PS (6147) MODULE : USARTSIM |
209 | STATE : code ROUTINE : createUSARTMemory |
210 +--------------------------------------------------------------------+
211
212 PURPOSE : Create two pipes for byte oriented data exchange
213 between two win32 processes
214
215 */
216
217 LOCAL void *createUSARTMemory (char *name, ULONG size)
218 {
219 char newname[40];
220
221 /*
222 * create two Semaphores pairs to protect the send data to be
223 * overwritten before they have read by the receiver
224 */
225
226 sprintf (newname, "%s_CH1empty", name);
227
228 SemCH1_empty = CreateSemaphore (NULL,
229 1,
230 1,
231 newname);
232
233 if (SemCH1_empty EQ NULL)
234 return NULL;
235
236 sprintf (newname, "%s_CH1full", name);
237
238 SemCH1_full = CreateSemaphore (NULL,
239 0,
240 1,
241 newname);
242
243 if (SemCH1_full EQ NULL)
244 return NULL;
245
246 sprintf (newname, "%s_CH2empty", name);
247
248 SemCH2_empty = CreateSemaphore (NULL,
249 1,
250 1,
251 newname);
252
253 if (SemCH2_empty EQ NULL)
254 return NULL;
255
256 sprintf (newname, "%s_CH2full", name);
257
258 SemCH2_full = CreateSemaphore (NULL,
259 0,
260 1,
261 newname);
262
263 if (SemCH2_full EQ NULL)
264 return NULL;
265
266 /*
267 * create a shared memory area
268 */
269 sprintf (newname, "UT_Mem_%s", name);
270
271 USARTMemHandle
272 = CreateFileMapping (
273 (HANDLE) 0xffffffff, /* memory-mapped */
274 NULL, /* no security */
275 PAGE_READWRITE, /* read/write access */
276 (DWORD) 0,
277 /* memory size */ (DWORD) size,
278 newname /* name of sh. mem */
279 );
280
281 if (USARTMemHandle EQ NULL)
282 return NULL;
283
284 /*
285 * map the shared memory area into the address space of the process
286 * and return the startaddress.
287 */
288
289 return MapViewOfFile (USARTMemHandle,
290 FILE_MAP_WRITE,
291 0,
292 0,
293 0);
294 }
295
296
297 /*
298 +--------------------------------------------------------------------+
299 | PROJECT : GSM-PS (6147) MODULE : USARTSIM |
300 | STATE : code ROUTINE : openUSARTMemory |
301 +--------------------------------------------------------------------+
302
303 PURPOSE : open a shared memory area for character exchange
304 between two WIN32 processes
305
306 */
307
308 LOCAL void *openUSARTMemory (char *name, ULONG size)
309 {
310 char newname[30];
311
312 /*
313 * open the Semaphores
314 */
315
316 sprintf (newname, "%s_CH1empty", name);
317
318 SemCH1_empty = OpenSemaphore (SEMAPHORE_MODIFY_STATE
319 | SYNCHRONIZE,
320 FALSE,
321 newname);
322
323 if (SemCH1_empty EQ NULL)
324 return NULL;
325
326 sprintf (newname, "%s_CH1full", name);
327
328 SemCH1_full = OpenSemaphore (SEMAPHORE_MODIFY_STATE
329 | SYNCHRONIZE,
330 FALSE,
331 newname);
332
333 if (SemCH1_full EQ NULL)
334 return NULL;
335
336 sprintf (newname, "%s_CH2empty", name);
337
338 SemCH2_empty = OpenSemaphore (SEMAPHORE_MODIFY_STATE
339 | SYNCHRONIZE,
340 FALSE,
341 newname);
342
343 if (SemCH2_empty EQ NULL)
344 return NULL;
345
346 sprintf (newname, "%s_CH2full", name);
347
348 SemCH2_full = OpenSemaphore (SEMAPHORE_MODIFY_STATE
349 | SYNCHRONIZE,
350 FALSE,
351 newname);
352
353 if (SemCH2_full EQ NULL)
354 return NULL;
355
356 /*
357 * open the shared memory area
358 */
359
360 sprintf (newname, "UT_Mem_%s", name);
361
362 USARTMemHandle =
363 OpenFileMapping (FILE_MAP_WRITE,
364 FALSE,
365 newname); /* name of sh. mem */
366
367
368 if (USARTMemHandle EQ NULL)
369 return NULL;
370
371 /*
372 * map the shared memory area into the address space of the process
373 * and return the startaddress.
374 */
375
376 return MapViewOfFile (USARTMemHandle,
377 FILE_MAP_WRITE,
378 0,
379 0,
380 0);
381 }
382
383
384 /*
385 +--------------------------------------------------------------------+
386 | PROJECT : GSM-PS (6147) MODULE : USART |
387 | STATE : code ROUTINE : waitForRCVBufferFull |
388 +--------------------------------------------------------------------+
389
390 PURPOSE : This function waits until an incoming character
391 is signaled with the EV_RXCHAR Event
392
393 */
394
395 LOCAL void waitForRCVBufferFull (void)
396 {
397 switch (m_mode) {
398 case US_MODE_95: {
399 static COMSTAT stComStat;
400 static DWORD dwErrors;
401 static DWORD EvtMask = 0;
402 BOOL validReceive = FALSE;
403
404 do
405 {
406 SetCommMask (hComDev, EV_RXCHAR) ;
407 WaitCommEvent (hComDev, &EvtMask, NULL);
408 ClearCommError (hComDev, &dwErrors, &stComStat);
409
410 if (dwErrors & COM_ERROR)
411 PurgeComm (hComDev, PURGE_RXCLEAR|PURGE_RXABORT);
412 else
413 validReceive = TRUE;
414
415 } while (!validReceive);
416 break;
417 }
418 case US_MODE_NT: {
419 static COMSTAT stComStat;
420 static DWORD dwErrors;
421 static DWORD EvtMask = 0;
422 BOOL validReceive = FALSE;
423
424 do
425 {
426 SetCommMask (hComDev, EV_RXCHAR) ;
427 WaitCommEvent (hComDev, &EvtMask, NULL);
428 ClearCommError (hComDev, &dwErrors, &stComStat);
429
430 if (dwErrors & COM_ERROR)
431 PurgeComm (hComDev, PURGE_RXCLEAR|PURGE_RXABORT);
432 else
433 validReceive = TRUE;
434
435 } while (!validReceive && !ReaderThreadExitRequest);
436 break;
437 }
438 case US_MODE_SIM: {
439 if (WaitForSingleObject (*semRCVFull, m_rcv_timeout) NEQ WAIT_OBJECT_0)
440 {
441 PrintToFile("USART: no stack connected\n");
442 }
443 break;
444 }
445 default:
446 break;
447 }
448 }
449
450
451 /*
452 +--------------------------------------------------------------------+
453 | PROJECT : GSM-PS (6147) MODULE : USART |
454 | STATE : code ROUTINE : _readerThread |
455 +--------------------------------------------------------------------+
456
457 PURPOSE : This function is the central signal handling function. It is
458 installed as a thread and waits for the occurance of an
459 event and then calls the installed callback function
460 of the application.
461
462 */
463
464 LOCAL void _readerThread (void)
465 {
466 while (ReaderThreadExitRequest == FALSE)
467 {
468 waitForRCVBufferFull ();
469 ReceiveCallback ();
470 }
471 ReaderThreadExitRequest = FALSE;
472 ExitThread(READER_THREAD_EXIT_CODE);
473 }
474
475 /*
476 +--------------------------------------------------------------------+
477 | PROJECT : GSM-PS (6147) MODULE : USART |
478 | STATE : code ROUTINE : convertBaudrate |
479 +--------------------------------------------------------------------+
480
481 PURPOSE : This function convert the constants for the baudrates in
482 usart.h into the equvalent constants for WIN32 comm.
483
484 */
485 LOCAL DWORD convertBaudrate (DWORD br)
486 {
487 switch (br)
488 {
489 case US_BAUD_256000:
490 return CBR_256000;
491
492 case US_BAUD_128000:
493 return CBR_128000;
494
495 case US_BAUD_115200:
496 return CBR_115200;
497
498 case US_BAUD_57600:
499 return CBR_57600;
500
501 case US_BAUD_38400:
502 return CBR_38400;
503
504 case US_BAUD_19200:
505 return CBR_19200;
506
507 case US_BAUD_14400:
508 return CBR_14400;
509
510 case US_BAUD_9600:
511 return CBR_9600;
512
513 case US_BAUD_4800:
514 return CBR_4800;
515
516 case US_BAUD_2400:
517 return CBR_2400;
518
519 case US_BAUD_1200:
520 return CBR_1200;
521
522 case US_BAUD_600:
523 return CBR_600;
524
525 case US_BAUD_300:
526 return CBR_300;
527
528 default:
529 /* no CBR_xxx constant found -> return value itsself */
530 return br;
531 }
532 }
533
534 /*
535 +--------------------------------------------------------------------+
536 | PROJECT : GSM-PS (6147) MODULE : USART |
537 | STATE : code ROUTINE : sioInit |
538 +--------------------------------------------------------------------+
539
540 PURPOSE : This function opens the given comm port and initiializes
541 the DCB with baudrate and flowcontrol parameters.
542
543 */
544
545 LOCAL BOOL sioInit (int portNr,
546 unsigned int baudrate,
547 unsigned int bufSize,
548 char flowCtrl)
549 {
550 char szPort[10];
551 DCB stDCB;
552 COMMTIMEOUTS stTimeout ;
553 DWORD dwErrorFlags;
554 COMSTAT stComStat;
555
556 sprintf (szPort, "\\\\.\\COM%d", portNr) ;
557
558 // ------------------------------------
559 // open the communication device
560 // ------------------------------------
561 if (m_mode==UT_MODE_NT) {
562 hComDev = CreateFile
563 (
564 szPort,
565 GENERIC_READ | GENERIC_WRITE,
566 0, /* exclusive access */
567 NULL, /* no security attrs */
568 OPEN_EXISTING,
569 FILE_FLAG_OVERLAPPED,
570 NULL
571 );
572 } else {
573 hComDev = CreateFile
574 (
575 szPort,
576 GENERIC_READ | GENERIC_WRITE,
577 0, // exclusive access
578 NULL, // no security attrs
579 OPEN_EXISTING,
580 0,
581 NULL
582 );
583 }
584
585 if (hComDev EQ INVALID_HANDLE_VALUE)
586 return FALSE; // device not available
587
588 if (m_mode==UT_MODE_NT) {
589 gReadOverLap.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
590 if (!gReadOverLap.hEvent)
591 return ( FALSE );
592
593 gReadOverLap.Offset = 0;
594 gReadOverLap.OffsetHigh = 0;
595
596 gWriteOverLap.hEvent = CreateEvent (NULL, TRUE, FALSE, NULL);
597 if (!(gWriteOverLap.hEvent))
598 return ( FALSE );
599
600 gWriteOverLap.Offset = 0;
601 gWriteOverLap.OffsetHigh = 0;
602 }
603
604 // ------------------------------------
605 // get any early notifications
606 // ------------------------------------
607 SetCommMask (hComDev, EV_RXCHAR);
608
609 // ------------------------------------
610 // setup device buffers
611 // ------------------------------------
612 SetupComm (hComDev,
613 bufSize,
614 bufSize
615 );
616
617 // ------------------------------------
618 // purge any information in the buffer
619 // ------------------------------------
620 PurgeComm (hComDev,
621 PURGE_TXABORT | PURGE_RXABORT |
622 PURGE_TXCLEAR | PURGE_RXCLEAR
623 );
624
625 // ------------------------------------
626 // setup up and enable communication
627 // device. If not possible close
628 // communication and abort function.
629 // ------------------------------------
630 if (!GetCommState (hComDev, &stDCB))
631 {
632 SetCommMask (hComDev, 0);
633 CloseHandle (hComDev);
634 return FALSE;
635 }
636
637 stDCB.DCBlength = sizeof (stDCB); // sizeof(DCB)
638
639 switch (flowCtrl)
640 {
641 case 'N':
642 stDCB.fOutxCtsFlow = FALSE;
643 stDCB.fOutxDsrFlow = FALSE;
644 stDCB.fDtrControl = DTR_CONTROL_DISABLE;
645 stDCB.fRtsControl = RTS_CONTROL_DISABLE;
646 break;
647 case 'D':
648 stDCB.fOutxCtsFlow = FALSE;
649 stDCB.fOutxDsrFlow = TRUE;
650 stDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;
651 stDCB.fRtsControl = RTS_CONTROL_DISABLE;
652 stDCB.XonLim = 0;
653 stDCB.XoffLim = 50;
654 break;
655 case 'R':
656 stDCB.fOutxCtsFlow = TRUE;
657 stDCB.fOutxDsrFlow = FALSE;
658 stDCB.fDtrControl = DTR_CONTROL_DISABLE;
659 stDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
660 stDCB.XonLim = 0;
661 stDCB.XoffLim = 50;
662 break;
663 case 'P':
664 stDCB.fOutxCtsFlow = FALSE;
665 stDCB.fOutxDsrFlow = FALSE;
666 stDCB.fDtrControl = DTR_CONTROL_ENABLE;
667 stDCB.fRtsControl = RTS_CONTROL_DISABLE;
668 break;
669 case 'V':
670 if (m_mode==US_MODE_NT) {
671 stDCB.fOutxCtsFlow = FALSE;
672 stDCB.fOutxDsrFlow = FALSE;
673 stDCB.fDtrControl = DTR_CONTROL_ENABLE;
674 stDCB.fRtsControl = RTS_CONTROL_ENABLE;
675 break;
676 }
677 /*lint -fallthrough*/
678 /* go on if not US_MODE_NT */
679 default:
680 return FALSE;
681 }
682 fprintf (stdout,"flow control: %c ...", flowCtrl);
683
684 stDCB.BaudRate = baudrate; // current baud rate
685 stDCB.fBinary = TRUE; // binary mode, no EOF check
686 stDCB.fParity = FALSE; // enable parity checking
687 stDCB.fDsrSensitivity = FALSE; // DSR sensitivity
688 stDCB.fTXContinueOnXoff = FALSE; // XOFF continues Tx
689 stDCB.fOutX = FALSE; // XON/XOFF out flow control
690 stDCB.fInX = FALSE; // XON/XOFF in flow control
691 stDCB.fErrorChar = FALSE; // enable error replacement
692 stDCB.fNull = FALSE; // enable null stripping
693 stDCB.fAbortOnError = FALSE; // abort reads/writes on error
694 stDCB.ByteSize = 8; // number of bits/byte, 4-8
695 stDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
696 stDCB.StopBits = ONESTOPBIT;// 0,1,2 = 1, 1.5, 2
697 stDCB.XonChar = 0; // Tx and Rx XON character
698 stDCB.XoffChar = 0; // Tx and Rx XOFF character
699 stDCB.ErrorChar = 0; // error replacement character
700 stDCB.EofChar = 0; // end of input character
701 stDCB.EvtChar = 0; // received event character
702
703 if (!SetCommState (hComDev, &stDCB))
704 {
705 SetCommMask (hComDev, 0);
706 CloseHandle (hComDev);
707 return FALSE;
708 }
709
710 if (!GetCommTimeouts (hComDev, &stTimeout))
711 return FALSE;
712
713 stTimeout.WriteTotalTimeoutConstant = 0xffff;
714 stTimeout.WriteTotalTimeoutMultiplier = 0xffff;
715 stTimeout.ReadTotalTimeoutConstant = 0xffff;
716 stTimeout.ReadIntervalTimeout = 0;
717 stTimeout.ReadTotalTimeoutMultiplier = 0xffff;
718
719 if (!SetCommTimeouts (hComDev, &stTimeout))
720 return FALSE;
721
722 PurgeComm (hComDev, PURGE_RXCLEAR
723 |PURGE_TXCLEAR
724 |PURGE_TXABORT
725 |PURGE_RXABORT);
726
727 ClearCommError (hComDev, &dwErrorFlags, &stComStat);
728
729 return TRUE;
730 }
731
732 /*
733 +--------------------------------------------------------------------+
734 | PROJECT : GSM-PS (6147) MODULE : USART |
735 | STATE : code ROUTINE : sioRead |
736 +--------------------------------------------------------------------+
737
738 PURPOSE :
739
740 */
741
742 LOCAL BOOL sioRead (BYTE *bpRXBuffer, // RX Buffer
743 DWORD *pdwLength) // IN: Bytes to read
744 {
745 DWORD dwBytesToRead = *pdwLength ;
746 DWORD dwErrorFlags;
747 COMSTAT stComStat;
748
749 if (hComDev == INVALID_HANDLE_VALUE
750 OR *pdwLength == 0)
751 return FALSE; // device not available
752
753 if (m_mode==US_MODE_NT) {
754 if (!ReadFile (hComDev,
755 bpRXBuffer,
756 dwBytesToRead,
757 pdwLength,
758 &gReadOverLap))
759 {
760 // if there was a problem
761 if (GetLastError() == ERROR_IO_PENDING)
762 {
763 /* asynchronous i/o is still in progress */
764
765 /* do something else for a while */
766 /* check on the results of the asynchronous read */
767 if (GetOverlappedResult(gReadOverLap.hEvent, &gReadOverLap,
768 pdwLength, TRUE))
769 return TRUE;
770 }
771
772 ClearCommError(hComDev, &dwErrorFlags, &stComStat);
773 return FALSE;
774 } else {
775 ClearCommError(hComDev, &dwErrorFlags, &stComStat);
776 }
777 } else {
778 if (!ReadFile (hComDev,
779 bpRXBuffer,
780 dwBytesToRead,
781 pdwLength,
782 NULL))
783 {
784 // if there was a problem
785 ClearCommError(hComDev, &dwErrorFlags, &stComStat);
786 return FALSE;
787 }
788 }
789 #ifdef DEBUG_USART
790 {
791 char traceBuf[255];
792 unsigned int i;
793
794 traceBuf[0] = '\0';
795
796 if (bpRXBuffer[0] EQ 0xff)
797 {
798 Sleep(1);
799 }
800
801 for (i=0; i<*pdwLength; i++)
802 {
803 if (!isprint (bpRXBuffer[i]))
804 {
805 sprintf (traceBuf+strlen(traceBuf),
806 "[%02x]%c",
807 (USHORT) bpRXBuffer[i],
808 ((bpRXBuffer[i] EQ '\n') ? '\n' : ' ')
809 );
810 }
811 else
812 sprintf (traceBuf+strlen(traceBuf),
813 "%c",
814 bpRXBuffer[i]);
815 if (strlen (traceBuf) > 200)
816 {
817 write (usart_in, traceBuf, strlen (traceBuf));
818 traceBuf[0] = '\0';
819 }
820 }
821 /*
822 * write the string to the tracefile
823 */
824 write (usart_in, traceBuf, strlen (traceBuf));
825 }
826 #endif
827 return TRUE;
828 }
829
830 /*
831 +--------------------------------------------------------------------+
832 | PROJECT : GSM-PS (6147) MODULE : USART |
833 | STATE : code ROUTINE : sioWrite |
834 +--------------------------------------------------------------------+
835
836 PURPOSE :
837
838 */
839
840 LOCAL BOOL sioWrite (BYTE *bpTXBuffer, // TX Buffer
841 DWORD *pdwLength) // IN: Bytes to read
842 {
843 DWORD dwBytesToSend = *pdwLength, toSend, realySend;
844 int ret;
845 DWORD dwErrorFlags;
846 COMSTAT stComStat;
847 DWORD dwNumberOfBytesTransferred; /* Windows 95: */
848 /* The number of transferred bytes returned by the */
849 /* GetOverlappedResult function is always zero, also */
850 /* if there are bytes received by the communication */
851 /* partner via the serial line. */
852
853 if (hComDev EQ INVALID_HANDLE_VALUE
854 OR !bpTXBuffer
855 OR *pdwLength ==0)
856 return FALSE; // device not available
857
858 realySend = 0;
859 toSend = dwBytesToSend;
860
861 while (toSend > 0)
862 {
863 if (m_mode==US_MODE_NT) {
864 if (toSend > 20) {
865 ret = WriteFile (hComDev,
866 bpTXBuffer+realySend,
867 20,
868 pdwLength,
869 &gWriteOverLap);
870 dwNumberOfBytesTransferred = 20;
871 } else {
872 ret = WriteFile (hComDev,
873 bpTXBuffer+realySend,
874 toSend,
875 pdwLength,
876 &gWriteOverLap);
877 dwNumberOfBytesTransferred = toSend;
878 }
879 /* if there was a problem, or the async. operation's still pending ... */
880 if (!ret)
881 {
882 /* deal with the error code */
883 if (GetLastError() == ERROR_IO_PENDING)
884 {
885 /* asynchronous i/o is still in progress */
886
887 /* do something else for a while */
888 /* check on the results of the asynchronous read */
889 while (!GetOverlappedResult(gWriteOverLap.hEvent, &gWriteOverLap, pdwLength, TRUE))
890 {
891 if(GetLastError() == ERROR_IO_INCOMPLETE) {
892 continue;
893 } else {
894 break ;
895 }
896 }
897 } else {
898 ClearCommError(hComDev, &dwErrorFlags, &stComStat);
899 return FALSE;
900 }
901 }
902 } else {
903 if (toSend > 20) {
904 ret = WriteFile (hComDev,
905 bpTXBuffer+realySend,
906 20,
907 pdwLength,
908 NULL);
909 dwNumberOfBytesTransferred = 20; /* US_MODE_NT */
910 } else {
911 ret = WriteFile (hComDev,
912 bpTXBuffer+realySend,
913 toSend,
914 pdwLength,
915 NULL);
916 dwNumberOfBytesTransferred = toSend; /* US_MODE_NT */
917 }
918 }
919
920 #ifdef DEBUG_USART
921 {
922 char traceBuf[255];
923 unsigned int i;
924
925 traceBuf[0] = '\0';
926
927 for (i=0; i<*pdwLength; i++)
928 {
929 if (!isprint (bpTXBuffer[realySend+i]))
930 {
931 sprintf (traceBuf+strlen(traceBuf),
932 "[%02x]%c",
933 (USHORT) bpTXBuffer[realySend+i],
934 ((bpTXBuffer[realySend+i] EQ '\n') ? '\n': ' ')
935 );
936 }
937 else
938 sprintf (traceBuf+strlen(traceBuf),
939 "%c",
940 bpTXBuffer[realySend+i]);
941 if (strlen (traceBuf) > 200)
942 {
943 write (usart_out, traceBuf, strlen (traceBuf));
944 traceBuf[0] = '\0';
945 }
946 }
947 /*
948 * write the string to the tracefile
949 */
950 write (usart_out, traceBuf, strlen (traceBuf));
951 }
952 #endif
953
954 switch (m_mode) {
955 case US_MODE_NT:
956 realySend += dwNumberOfBytesTransferred;
957 toSend -= dwNumberOfBytesTransferred;
958 break;
959 case US_MODE_95:
960 realySend += *pdwLength;
961 toSend -= *pdwLength;
962 break;
963 default:
964 break;
965 }
966 }
967
968 *pdwLength = dwBytesToSend;
969
970 return TRUE;
971 }
972
973 /*
974 +--------------------------------------------------------------------+
975 | PROJECT : GSM-PS (6147) MODULE : USART |
976 | STATE : code ROUTINE : UT_Init |
977 +--------------------------------------------------------------------+
978
979 PURPOSE : initializes the USART driver
980
981 RETURNS : 0 ... initialization succeeded
982 -1 ... error
983
984 */
985
986
987 int UT_Init (unsigned int baudRate, int fifoSize, char flow_ctrl, void (func(void)), const char* fname )
988 {
989 if (initialized == TRUE)
990 {
991 return 0;
992 }
993
994 switch (m_mode)
995 {
996 case US_MODE_FILE:
997 if (!fname || !strlen(fname) || (m_file=fopen(fname,"rb"))==NULL)
998 {
999 fprintf (stdout, "USART: failed to open %s :-(\n",fname);
1000 return -1;
1001 }
1002 fprintf (stdout, "USART: \"%s\" opened\n",fname);
1003 break;
1004 case US_MODE_95:
1005 case US_MODE_NT: {
1006 BOOL ret;
1007 DWORD dwThreadID;
1008 #ifdef COM_AUTOSEARCH
1009 int from, to;
1010 int portNr;
1011 #else
1012 EXTERN int extPort;
1013 #endif
1014
1015 ReceiveCallback = func;
1016
1017 #ifdef COM_AUTOSEARCH
1018 if (P NEQ 0) {
1019 from = to = P;
1020 } else {
1021 from = 1;
1022 to = 4;
1023 }
1024
1025 /*
1026 * try COMn: to COMm: where n is from and m is to
1027 */
1028 for (portNr = from; portNr <= to; portNr++)
1029 {
1030 fprintf (stdout,"USART: Trying COM%d ... ", portNr);
1031
1032 if ((ret = sioInit (portNr,
1033 convertBaudrate (baudRate),
1034 10000 /*fifoSize*/,
1035 flow_ctrl)) EQ FALSE) {
1036 fprintf (stdout, "fail\n");
1037 } else {
1038 fprintf (stdout, "success!\n");
1039 break;
1040 }
1041 }
1042
1043 #else
1044 fprintf (stdout, "USART: Trying COM%d ... ", extPort);
1045
1046 if ((ret = sioInit (extPort,
1047 convertBaudrate (baudRate),
1048 10000 /*fifoSize*/,
1049 flow_ctrl)) EQ FALSE) {
1050 fprintf (stdout, "fail\n");
1051 }
1052 #endif
1053
1054 if (ret)
1055 {
1056 fprintf (stdout, "success!\n");
1057
1058 if (ReceiveCallback NEQ NULL)
1059 {
1060 hThread = CreateThread ((LPSECURITY_ATTRIBUTES) NULL,
1061 0,
1062 (LPTHREAD_START_ROUTINE) _readerThread,
1063 (LPVOID) NULL,
1064 0,
1065 &dwThreadID
1066 );
1067 }
1068 initialized = TRUE;
1069 }
1070 else {
1071 fprintf (stdout, "USART: COM-port not free or baudrate not supported !\n");
1072 return -1;
1073 }
1074 break;
1075 }
1076
1077 case US_MODE_SIM: {
1078 int i;
1079
1080 if ( first_ut_init )
1081 {
1082 if ( (ut_sema_handle = OpenSemaphore (SEMAPHORE_MODIFY_STATE | SYNCHRONIZE, FALSE, "UT_SIM_SEMA")) == NULL )
1083 {
1084 ut_sema_handle = CreateSemaphore (NULL, 1, 1, "UT_SIM_SEMA");
1085 }
1086 first_ut_init = 0;
1087 }
1088
1089 WaitForSingleObject (ut_sema_handle, INFINITE);
1090
1091 if ((Stream = (T_USARTStream *) openUSARTMemory
1092 (
1093 (char*)"GSM",
1094 sizeof (T_USARTStream)
1095 )) EQ NULL)
1096 {
1097 if ((Stream = (T_USARTStream *) createUSARTMemory
1098 (
1099 (char*)"GSM",
1100 sizeof (T_USARTStream)
1101 )) EQ NULL)
1102 {
1103 PrintToFile ("USART: simulation could not create a shared memory area\n");
1104 return -1;
1105 }
1106 PrintToFile ("USART: shared memory area created\n");
1107
1108 Stream->CH1_numOfBytes = 0;
1109 Stream->CH2_numOfBytes = 0;
1110
1111 Stream->CH1_CTS = 0;
1112 Stream->CH2_CTS = 0;
1113
1114 for (i=0; i<USART_BUFFER_SIZE; i++)
1115 {
1116 Stream->CH1_data[i] = 0;
1117 Stream->CH2_data[i] = 0;
1118 }
1119
1120 Stream->Connects = 0; /* init connection counter (!! CURRENTLY NOT USED !!) */
1121 Stream->Type=1; /* signaling new type */
1122 }
1123 else
1124 {
1125 PrintToFile ("USART: shared memory area opened\n");
1126 }
1127
1128 /* set pointers to semaphores and data buffers */
1129 #ifdef _TOOLS_
1130 if (Stream->Type==0) // shared mem created by old stack
1131 {
1132 PrintToFile ("USART: connecting to old stack !\n");
1133
1134 Stream->CH1_CTS = 1; // (baudRate NEQ -1); removed because baudrate never negative
1135
1136 InBuffer = Stream->CH1_data;
1137 OutBuffer = Stream->CH2_data;
1138 InCounter = &Stream->CH1_numOfBytes;
1139 OutCounter = &Stream->CH2_numOfBytes;
1140 semRCVFull = &SemCH1_full;
1141 semRCVEmpty = &SemCH1_empty;
1142 semSNDFull = &SemCH2_full;
1143 semSNDEmpty = &SemCH2_empty;
1144 CTS = &Stream->CH2_CTS;
1145 }
1146 else // shared mem created by us or new stack
1147 {
1148 Stream->CH2_CTS = 1; // (baudRate NEQ -1); removed because baudrate never negative
1149
1150 InBuffer = Stream->CH2_data;
1151 OutBuffer = Stream->CH1_data;
1152 InCounter = &Stream->CH2_numOfBytes;
1153 OutCounter = &Stream->CH1_numOfBytes;
1154 semRCVFull = &SemCH2_full;
1155 semRCVEmpty = &SemCH2_empty;
1156 semSNDFull = &SemCH1_full;
1157 semSNDEmpty = &SemCH1_empty;
1158 CTS = &Stream->CH1_CTS;
1159 }
1160 #else /* _TOOLS_ */
1161 Stream->CH1_CTS = 1; // (baudRate NEQ -1); removed because baudrate never negative
1162
1163 InBuffer = Stream->CH1_data;
1164 OutBuffer = Stream->CH2_data;
1165 InCounter = &Stream->CH1_numOfBytes;
1166 OutCounter = &Stream->CH2_numOfBytes;
1167 semRCVFull = &SemCH1_full;
1168 semRCVEmpty = &SemCH1_empty;
1169 semSNDFull = &SemCH2_full;
1170 semSNDEmpty = &SemCH2_empty;
1171 CTS = &Stream->CH2_CTS;
1172 #endif /* _TOOLS_ */
1173
1174 readPointer = InBuffer;
1175
1176 ReceiveCallback = func;
1177
1178 Stream->Connects++; /* mark connection (!! CURRENTLY NOT USED !!) */
1179 }
1180
1181 ReleaseSemaphore (ut_sema_handle, 1, NULL);
1182
1183 break;
1184 default:
1185 break;
1186 }
1187 initialized = TRUE;
1188 mem_closed = FALSE;
1189
1190 #ifdef DEBUG_USART
1191 /*
1192 * Open protocol file and initialize
1193 */
1194
1195 usart_in = open ("USART.IN", O_WRONLY| O_TEXT| O_TRUNC| O_CREAT, 0666);
1196 usart_out = open ("USART.OUT", O_WRONLY| O_TEXT| O_TRUNC| O_CREAT, 0666);
1197 #endif
1198
1199 return 0;
1200 }
1201
1202
1203 /*
1204 +--------------------------------------------------------------------+
1205 | PROJECT : GSM-PS (6147) MODULE : USARTSIM |
1206 | STATE : code ROUTINE : UT_Close |
1207 +--------------------------------------------------------------------+
1208
1209 PURPOSE :
1210
1211 */
1212
1213 GLOBAL BOOL UT_Close(void)
1214 {
1215
1216 if (initialized == FALSE)
1217 return FALSE;
1218
1219 switch (m_mode) {
1220 case US_MODE_FILE:
1221 if (m_file)
1222 {
1223 fclose(m_file);
1224 m_file=NULL;
1225 }
1226 break;
1227 case US_MODE_95:
1228 case US_MODE_NT: {
1229 DWORD ExitCode;
1230
1231 if (ReceiveCallback != NULL) {
1232 /* Initialize stop _readerThread */
1233 ReaderThreadExitRequest = TRUE;
1234 while (ReaderThreadExitRequest == TRUE)
1235 SetCommMask (hComDev, 0);
1236 }
1237
1238 /* Close Communication port. */
1239 PurgeComm (hComDev,
1240 PURGE_TXABORT | PURGE_RXABORT |
1241 PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
1242 if (m_mode==UT_MODE_NT) {
1243 CloseHandle (gReadOverLap.hEvent);
1244 gReadOverLap.hEvent = INVALID_HANDLE_VALUE ;
1245 CloseHandle (gWriteOverLap.hEvent);
1246 gWriteOverLap.hEvent = INVALID_HANDLE_VALUE ;
1247 }
1248 CloseHandle (hComDev);
1249 hComDev = INVALID_HANDLE_VALUE;
1250
1251 if (ReceiveCallback != NULL) {
1252 /* Stop _readerThread */
1253 do {
1254 GetExitCodeThread(hThread, (LPDWORD) &ExitCode);
1255 }
1256 while (ExitCode == STILL_ACTIVE);
1257 CloseHandle (hThread);
1258 hThread = INVALID_HANDLE_VALUE;
1259 }
1260
1261 break;
1262 }
1263 case US_MODE_SIM: {
1264 PrintToFile("USART: shared memory closed (%d)\n",cls_cnt);
1265 mem_closed = TRUE;
1266 /* mark disconnection */
1267 Stream->Connects=(Stream->Connects>1) ? 1 : 0; /* (!! CURRENTLY NOT USED !!) */
1268
1269 #ifdef _TOOLS_
1270 if (Stream->Type==0) /* shared mem created by old stack */
1271 {
1272 fprintf (stdout, "USART: disconnecting from old stack !\n");
1273 Stream->CH1_CTS = 0;
1274 }
1275 else /* shared mem created by us or new stack */
1276 {
1277 Stream->CH2_CTS = 0;
1278 }
1279 #else /* _TOOLS_ */
1280 Stream->CH1_CTS = 0;
1281 #endif /* _TOOLS_ */
1282
1283 CTS = NULL;
1284 /* close all handles */
1285 UnmapViewOfFile((void*)Stream);
1286 CloseHandle(USARTMemHandle);
1287 CloseHandle(SemCH1_full);
1288 CloseHandle(SemCH2_full);
1289 CloseHandle(SemCH1_empty);
1290 CloseHandle(SemCH2_empty);
1291 cls_cnt++;
1292 break;
1293 default:
1294 break;
1295 }
1296 }
1297
1298 #ifdef DEBUG_USART
1299 /* close tracefiles for usart-in and out */
1300 close(usart_in);
1301 close(usart_out);
1302 #endif
1303
1304 /* Deinitialize */
1305 ReceiveCallback = NULL;
1306 initialized = FALSE;
1307
1308 return TRUE;
1309 }
1310
1311
1312 /*
1313 +--------------------------------------------------------------------+
1314 | PROJECT : GSM-PS (6147) MODULE : USART |
1315 | STATE : code ROUTINE : UT_InitBlk |
1316 +--------------------------------------------------------------------+
1317
1318 PURPOSE : Initialize the USART for reading blocks
1319
1320 */
1321
1322 int UT_InitBlk ( unsigned int baudRate, int fifoSize, char flow_ctrl, void *hP)
1323 {
1324 return UT_Init (baudRate, fifoSize, flow_ctrl, NULL, NULL);
1325 }
1326
1327 /*
1328 +--------------------------------------------------------------------+
1329 | PROJECT : GSM-PS (6147) MODULE : USART |
1330 | STATE : code ROUTINE : UT_IsChar |
1331 +--------------------------------------------------------------------+
1332
1333 PURPOSE :
1334
1335 */
1336
1337 GLOBAL int UT_IsChar (void)
1338 {
1339 int ret;
1340
1341 switch (m_mode) {
1342 case US_MODE_FILE:
1343 Sleep(FILE_SLOW_DOWN);
1344 while (feof(m_file))
1345 {
1346 Sleep(1000);
1347 fseek(m_file,0,SEEK_CUR);
1348 }
1349 ret=1;
1350 break;
1351 case US_MODE_95:
1352 case US_MODE_NT: {
1353 static COMSTAT stComStat;
1354 static DWORD dwErrors;
1355
1356 if (!initialized)
1357 return FALSE;
1358
1359 waitForRCVBufferFull ();
1360
1361 ClearCommError (hComDev, &dwErrors, &stComStat);
1362
1363 ret= (stComStat.cbInQue > 0);
1364 break;
1365 }
1366
1367 case US_MODE_SIM: {
1368 waitForRCVBufferFull ();
1369 ret = (*InCounter NEQ 0);
1370
1371 if (ret EQ 0)
1372 readPointer = InBuffer;
1373 break;
1374 default:
1375 ret = 0;
1376 break;
1377 }
1378 }
1379
1380 return ret;
1381 }
1382
1383 /*
1384 +--------------------------------------------------------------------+
1385 | PROJECT : GSM-PS (6147) MODULE : USART |
1386 | STATE : code ROUTINE : UT_ReadChar |
1387 +--------------------------------------------------------------------+
1388
1389 PURPOSE :
1390
1391 */
1392
1393 GLOBAL BYTE UT_ReadChar (void)
1394 {
1395 BYTE ret=0;
1396
1397 switch (m_mode) {
1398 case US_MODE_95:
1399 case US_MODE_NT: {
1400
1401 BYTE buffer[1];
1402 ULONG bytesRead;
1403
1404 if (!initialized)
1405 return 0;
1406
1407 sioRead (buffer, &bytesRead);
1408
1409 if (!bytesRead)
1410 buffer[0] = 0xff;
1411
1412 ret=buffer[0];
1413 break;
1414 }
1415
1416 case US_MODE_SIM: {
1417 if (*InCounter NEQ 0)
1418 {
1419 ret = *readPointer++;
1420
1421 #ifdef DEBUG_USART
1422 {
1423 BYTE buf[20];
1424 sprintf (buf, "R[1 of %d]: ", *InCounter);
1425 write (usart_in,
1426 buf,
1427 strlen (buf));
1428 if (isprint (ret))
1429 {
1430 sprintf (buf, "%c\n", ret);
1431 }
1432 else
1433 {
1434 sprintf (buf, "(%02X)\n", ret);
1435 }
1436 write (usart_in,
1437 buf,
1438 strlen (buf));
1439 }
1440 #endif
1441
1442 (*InCounter)--;
1443
1444 if (*InCounter EQ 0)
1445 {
1446 readPointer = InBuffer;
1447 markRCVBufferEmpty ();
1448 }
1449 }
1450 break;
1451 default:
1452 break;
1453 }
1454 }
1455 return ret;
1456 }
1457
1458 /*
1459 +--------------------------------------------------------------------+
1460 | PROJECT : GSM-PS (6147) MODULE : USART |
1461 | STATE : code ROUTINE : UT_ReadNChars |
1462 +--------------------------------------------------------------------+
1463
1464 PURPOSE : Called from the HISR - Reads a block of characters
1465 Parameters : buffer for holding received characters,
1466 max. size of buffer
1467 Returns the number of characters read
1468
1469 */
1470
1471 GLOBAL ULONG UT_ReadNChars (int usart_id, BYTE *buffer, ULONG bufferSize)
1472 {
1473 ULONG bytes;
1474
1475 switch (m_mode) {
1476 case US_MODE_FILE:
1477 if (bufferSize>FILE_MAX_CHUNK)
1478 {
1479 bufferSize=FILE_MAX_CHUNK;
1480 }
1481 bytes=fread(buffer,1,bufferSize,m_file);
1482 break;
1483 case US_MODE_95:
1484 case US_MODE_NT: {
1485
1486 COMSTAT stComStat;
1487 DWORD dwErrors;
1488
1489 if (!initialized)
1490 return 0L;
1491
1492 ClearCommError (hComDev, &dwErrors, &stComStat);
1493
1494 bytes = MINIMUM (stComStat.cbInQue, bufferSize);
1495
1496 if (bytes EQ 0)
1497 return 0L;
1498
1499 sioRead (buffer, &bytes);
1500 break;
1501 }
1502
1503 case US_MODE_SIM: {
1504 if ((bytes = MINIMUM (*InCounter, bufferSize)) NEQ 0)
1505 {
1506 #ifdef DEBUG_USART
1507 unsigned int i;
1508 char buf[50];
1509 #endif
1510
1511 memcpy (buffer, readPointer, bytes);
1512
1513 #ifdef DEBUG_USART
1514 sprintf (buf, "R[%d of %d]: ", bytes, *InCounter);
1515 write (usart_in, buf, strlen (buf));
1516
1517 for (i=0; i<bytes; i++)
1518 {
1519 if (isprint (buffer[i]))
1520 sprintf (buf, "%c", buffer[i]);
1521 else
1522 sprintf (buf, "(%02X)", buffer[i]);
1523 write (usart_in,
1524 buf,
1525 strlen (buf));
1526 }
1527 write (usart_in, "\n", 1);
1528 #endif
1529
1530 (*InCounter) -= (USHORT)bytes;
1531
1532 if (*InCounter EQ 0)
1533 {
1534 readPointer = InBuffer;
1535 markRCVBufferEmpty ();
1536 }
1537 else {
1538 readPointer += bytes;
1539 }
1540 }
1541 else {
1542 markRCVBufferEmpty ();
1543 }
1544 break;
1545 default: bytes = 0;
1546 break;
1547 }
1548 }
1549
1550 return bytes;
1551 }
1552
1553 /*
1554 +--------------------------------------------------------------------+
1555 | PROJECT : GSM-PS (6147) MODULE : USART |
1556 | STATE : code ROUTINE : UT_WriteChar |
1557 +--------------------------------------------------------------------+
1558
1559 PURPOSE :
1560
1561 */
1562
1563 GLOBAL void UT_WriteChar (int usart_id, char ch)
1564 {
1565 switch (m_mode) {
1566 case US_MODE_95:
1567 case US_MODE_NT: {
1568 BYTE buffer[1];
1569 ULONG bytesWritten = 1;
1570
1571 if (!initialized)
1572 return;
1573
1574 buffer[0] = (BYTE)ch;
1575
1576 sioWrite (buffer, &bytesWritten);
1577 break;
1578 }
1579
1580 case US_MODE_SIM: {
1581 #ifdef DEBUG_USART
1582 char buf[50];
1583 #endif
1584
1585 if ( CTS == NULL || !*CTS) /* no testtools connected */
1586 {
1587 return;
1588 }
1589
1590 if (waitForSNDBufferEmpty () != 0)
1591 {
1592 markSNDBufferFull ();
1593 return; /* we gave up sending to avoid dead lock */
1594 }
1595
1596 #ifdef DEBUG_USART
1597 sprintf (buf, "W[1]: %02X", ch);
1598 write (usart_out, buf, strlen (buf));
1599 #endif
1600
1601 *OutBuffer = (UBYTE)ch;
1602 *OutCounter = 1;
1603
1604 markSNDBufferFull ();
1605 break;
1606 default:
1607 break;
1608 }
1609 }
1610 }
1611
1612 /*
1613 +--------------------------------------------------------------------+
1614 | PROJECT : GSM-PS (6147) MODULE : USART |
1615 | STATE : code ROUTINE : UT_WriteString |
1616 +--------------------------------------------------------------------+
1617
1618 PURPOSE :
1619
1620 */
1621
1622 GLOBAL void UT_WriteString (int usart_id, char *s)
1623 {
1624 switch (m_mode) {
1625 case US_MODE_95:
1626 case US_MODE_NT: {
1627 ULONG bytesWritten = strlen (s);
1628
1629 if (!initialized)
1630 return;
1631
1632 sioWrite ((BYTE *) s, &bytesWritten);
1633 break;
1634 }
1635
1636 case US_MODE_SIM: {
1637 unsigned int numOfChars;
1638 #ifdef DEBUG_USART
1639 int i;
1640 char buf[50];
1641 #endif
1642
1643 if ( CTS == NULL || !*CTS) /* no testtools connected */
1644 {
1645 return;
1646 }
1647
1648 if (waitForSNDBufferEmpty () != 0)
1649 {
1650 markSNDBufferFull ();
1651 return; /* we gave up sending to avoid dead lock */
1652 }
1653
1654 numOfChars = strlen (s);
1655
1656 memcpy (OutBuffer, s, numOfChars);
1657 *OutCounter = numOfChars;
1658
1659 #ifdef DEBUG_USART
1660 sprintf (buf, "W[%d]:", numOfChars);
1661 write (usart_out, buf, strlen (buf));
1662
1663 for (i=0; i<numOfChars; i++)
1664 {
1665 if (isprint (OutBuffer[i]))
1666 sprintf (buf, "%c", OutBuffer[i]);
1667 else
1668 sprintf (buf, "(%02X)", OutBuffer[i]);
1669 write (usart_out,
1670 buf,
1671 strlen (buf));
1672
1673 }
1674 write (usart_out,"\n", 1);
1675 #endif
1676
1677 markSNDBufferFull ();
1678 break;
1679 default:
1680 break;
1681 }
1682 }
1683 }
1684
1685
1686 /*
1687 +--------------------------------------------------------------------+
1688 | PROJECT : GSM-PS (6147) MODULE : USART |
1689 | STATE : code ROUTINE : UT_WriteNChars |
1690 +--------------------------------------------------------------------+
1691
1692 PURPOSE :
1693
1694 */
1695
1696 GLOBAL void UT_WriteNChars (int usart_id, BYTE *s, unsigned int n)
1697 {
1698 switch (m_mode) {
1699 case US_MODE_95:
1700 case US_MODE_NT: {
1701 ULONG bytesWritten = (ULONG) n;
1702
1703 if (!initialized)
1704 return;
1705
1706 if (!sioWrite ((BYTE *) s, &bytesWritten))
1707 fprintf (stderr, "USART: Error1\n");
1708 if (bytesWritten NEQ (ULONG) n)
1709 fprintf (stderr, "USART: Error2\n");
1710 break;
1711 }
1712
1713 case US_MODE_SIM: {
1714 #ifdef DEBUG_USART
1715 int i;
1716 char buf[50];
1717 #endif
1718
1719 if ( CTS == NULL || !*CTS) /* no testtools connected */
1720 {
1721 #ifdef DEBUG_USART
1722 printf("-");
1723 #endif
1724 snd_cnt++;
1725 return;
1726 }
1727
1728 if ( mem_closed == TRUE )
1729 {
1730 PrintToFile("USART:tried to write on closed memory (%d)\n",snd_cnt);
1731 return;
1732 }
1733 if (waitForSNDBufferEmpty () != 0)
1734 {
1735 markSNDBufferFull ();
1736 PrintToFile("USART: gave up sending\n");
1737 snd_cnt++;
1738 return; /* we gave up sending to avoid dead lock */
1739 }
1740 memcpy (OutBuffer, s, n);
1741 *OutCounter = n;
1742
1743 #ifdef DEBUG_USART
1744 sprintf (buf, "W[%d]:", n);
1745 write (usart_out, buf, strlen (buf));
1746
1747 for (i=0; i<n; i++)
1748 {
1749 if (isprint (OutBuffer[i]))
1750 sprintf (buf, "%c", OutBuffer[i]);
1751 else
1752 sprintf (buf, "(%02X)", OutBuffer[i]);
1753 write (usart_out,
1754 buf,
1755 strlen (buf));
1756 }
1757 write (usart_out,"\n", 1);
1758 #endif
1759
1760 if ( mem_closed == TRUE )
1761 {
1762 PrintToFile("USART: written on closed memory (%d)\n",snd_cnt);
1763 snd_cnt++;
1764 return;
1765 }
1766 #ifdef DEBUG_USART
1767 printf("+");
1768 #endif
1769 markSNDBufferFull ();
1770 snd_cnt++;
1771 break;
1772 default:
1773 break;
1774 }
1775 }
1776 }
1777
1778 /*
1779 +--------------------------------------------------------------------+
1780 | PROJECT : GSM-PS (6147) MODULE : USART |
1781 | STATE : code ROUTINE : UT_SetFlowCtrl |
1782 +--------------------------------------------------------------------+
1783
1784 PURPOSE :
1785
1786 */
1787
1788 GLOBAL void UT_SetFlowCtrl (char flowCtrl)
1789 {
1790 switch (m_mode) {
1791 case US_MODE_95:
1792 case US_MODE_NT: {
1793 DCB stDCB;
1794
1795 if (!GetCommState (hComDev, &stDCB))
1796 return;
1797
1798 stDCB.DCBlength = sizeof (stDCB); // sizeof(DCB)
1799
1800 switch (flowCtrl)
1801 {
1802 case 'N':
1803 stDCB.fOutxCtsFlow = FALSE;
1804 stDCB.fOutxDsrFlow = FALSE;
1805 stDCB.fDtrControl = DTR_CONTROL_DISABLE;
1806 stDCB.fRtsControl = RTS_CONTROL_DISABLE;
1807 break;
1808 case 'D':
1809 stDCB.fOutxCtsFlow = FALSE;
1810 stDCB.fOutxDsrFlow = TRUE;
1811 stDCB.fDtrControl = DTR_CONTROL_HANDSHAKE;
1812 stDCB.fRtsControl = RTS_CONTROL_DISABLE;
1813 stDCB.XonLim = 0;
1814 stDCB.XoffLim = 50;
1815 break;
1816 case 'R':
1817 stDCB.fOutxCtsFlow = TRUE;
1818 stDCB.fOutxDsrFlow = FALSE;
1819 stDCB.fDtrControl = DTR_CONTROL_DISABLE;
1820 stDCB.fRtsControl = RTS_CONTROL_HANDSHAKE;
1821 stDCB.XonLim = 0;
1822 stDCB.XoffLim = 50;
1823 break;
1824 case 'P':
1825 stDCB.fOutxCtsFlow = FALSE;
1826 stDCB.fOutxDsrFlow = FALSE;
1827 stDCB.fDtrControl = DTR_CONTROL_ENABLE;
1828 stDCB.fRtsControl = RTS_CONTROL_DISABLE;
1829 break;
1830 default:
1831 break;
1832 }
1833
1834 SetCommState (hComDev, &stDCB);
1835 break;
1836 }
1837
1838 case US_MODE_SIM:
1839 break;
1840 default:
1841 break;
1842 }
1843 }