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

Last change on this file since 233 was 233, checked in by gregli@…, 12 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.