source: xtideuniversalbios/trunk/Serial_Server/win32/Win32Serial.h@ 253

Last change on this file since 253 was 233, checked in by gregli@…, 13 years ago

Serial Port: split single byte port and baud into two bytes, taking advantage of the two bytes in DPT_SERIAL, which supports more serial baud rates and in particular fixed a bug where a 4x client machine couldn't talk to a 115.2K server machine. This is a wide change, touching lots of files, but most are shallow changes. DetectPrint.asm took the most significant changes, now it calculates the baud rate to display instead of using characters provided by the Configurator. The Configurator now has a new menu flag, FLG_MENUITEM_CHOICESTRINGS, for specifying that values are not linear and they should be lookedup rather than indexed. Finally, another important bug fixed here is that in some error cases, the serial port code could get into an infinite loop waiting ont the hardware; now it has a timeout.

File size: 3.7 KB
Line 
1//======================================================================
2//
3// Project: XTIDE Universal BIOS, Serial Port Server
4//
5// File: Win32Serial.h - Microsoft Windows serial code
6//
7
8#include <stdio.h>
9#include "windows.h"
10#include "../library/library.h"
11
12#define PIPENAME "\\\\.\\pipe\\xtide"
13
14class SerialAccess
15{
16public:
17 void Connect( char *name, struct baudRate *p_baudRate )
18 {
19 char buff1[20], buff2[1024];
20
21 baudRate = p_baudRate;
22
23 pipe = NULL;
24
25 if( !name )
26 {
27 for( int t = 1; t <= 30 && !name; t++ )
28 {
29 sprintf( buff1, "COM%d", t );
30 if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
31 name = buff1;
32 }
33 if( !name )
34 log( -1, "No physical COM ports found" );
35 }
36
37 if( !strcmp( name, "PIPE" ) )
38 {
39 log( 0, "Opening named pipe %s (simulating %s baud)", PIPENAME, baudRate->display );
40
41 pipe = CreateNamedPipeA( PIPENAME, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE|PIPE_REJECT_REMOTE_CLIENTS, 2, 1024, 1024, 0, NULL );
42 if( pipe == INVALID_HANDLE_VALUE )
43 log( -1, "Could not CreateNamedPipe " PIPENAME );
44
45 if( !ConnectNamedPipe( pipe, NULL ) )
46 log( -1, "Could not ConnectNamedPipe" );
47
48 if( baudRate->divisor > 3 )
49 log( -1, "Cannot simulate baud rates with hardware multipliers" );
50
51 speedEmulation = 1;
52 resetConnection = 1;
53 }
54 else
55 {
56 if( QueryDosDeviceA( name, buff2, sizeof(buff2) ) )
57 {
58 COMMTIMEOUTS timeouts;
59 DCB dcb;
60
61 log( 0, "Opening %s (%lu baud)", name, baudRate->rate );
62
63 pipe = CreateFileA( name, GENERIC_READ|GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0 );
64 if( pipe == INVALID_HANDLE_VALUE )
65 log( -1, "Could not Open \"%s\"", name );
66
67 FillMemory(&dcb, sizeof(dcb), 0);
68 FillMemory(&timeouts, sizeof(timeouts), 0);
69
70 dcb.DCBlength = sizeof(dcb);
71 dcb.BaudRate = baudRate->rate;
72 dcb.ByteSize = 8;
73 dcb.StopBits = ONESTOPBIT;
74 dcb.Parity = NOPARITY;
75 if( !SetCommState( pipe, &dcb ) )
76 log( -1, "Could not SetCommState" );
77
78 if( !SetCommTimeouts( pipe, &timeouts ) )
79 log( -1, "Could not SetCommTimeouts" );
80 }
81 else
82 {
83 char logbuff[ 1024 ];
84 int found = 0;
85
86 sprintf( logbuff, "serial port '%s' not found, detected COM ports:", name );
87
88 for( int t = 1; t <= 40; t++ )
89 {
90 sprintf( buff1, "COM%d", t );
91 if( QueryDosDeviceA( buff1, buff2, sizeof(buff2) ) )
92 {
93 strcat( logbuff, "\n " );
94 strcat( logbuff, buff1 );
95 found = 1;
96 }
97 }
98 if( !found )
99 strcat( logbuff, "\n (none)" );
100
101 log( -1, logbuff );
102 }
103 }
104 }
105
106 void Disconnect()
107 {
108 if( pipe )
109 {
110 CloseHandle( pipe );
111 pipe = NULL;
112 }
113 }
114
115 unsigned long readCharacters( void *buff, unsigned long len )
116 {
117 unsigned long readLen;
118 int ret;
119
120 ret = ReadFile( pipe, buff, len, &readLen, NULL );
121
122 if( !ret || readLen == 0 )
123 {
124 if( GetLastError() == ERROR_BROKEN_PIPE )
125 return( 0 );
126 else
127 log( -1, "read serial failed (error code %d)", GetLastError() );
128 }
129
130 return( readLen );
131 }
132
133 int writeCharacters( void *buff, unsigned long len )
134 {
135 unsigned long writeLen;
136 int ret;
137
138 ret = WriteFile( pipe, buff, len, &writeLen, NULL );
139
140 if( !ret || len != writeLen )
141 {
142 if( GetLastError() == ERROR_BROKEN_PIPE )
143 return( 0 );
144 else
145 log( -1, "write serial failed (error code %d)", GetLastError() );
146 }
147
148 return( 1 );
149 }
150
151 SerialAccess()
152 {
153 pipe = NULL;
154 speedEmulation = 0;
155 resetConnection = 0;
156 baudRate = NULL;
157 }
158
159 ~SerialAccess()
160 {
161 Disconnect();
162 }
163
164 int speedEmulation;
165 int resetConnection;
166
167 struct baudRate *baudRate;
168
169private:
170 HANDLE pipe;
171};
172
Note: See TracBrowser for help on using the repository browser.