- raw serial receive support for win32 added. It is disabled for now because it
doesn't work properly (lost data at 300 baud).
This commit is contained in:
parent
4eea772270
commit
a2d6bfc786
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: serial_raw.cc,v 1.14 2004-03-28 12:41:12 vruppert Exp $
|
||||
// $Id: serial_raw.cc,v 1.15 2004-05-13 16:23:14 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2004 MandrakeSoft S.A.
|
||||
@ -36,10 +36,15 @@
|
||||
|
||||
#define LOG_THIS
|
||||
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
DWORD WINAPI RawSerialThread(VOID *this_ptr);
|
||||
#endif
|
||||
|
||||
serial_raw::serial_raw (char *devname)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char portstr[MAX_PATH];
|
||||
DWORD threadID;
|
||||
#endif
|
||||
|
||||
put ("SERR");
|
||||
@ -50,6 +55,10 @@ serial_raw::serial_raw (char *devname)
|
||||
dcb.fBinary = 1;
|
||||
dcb.fDtrControl = DTR_CONTROL_ENABLE;
|
||||
dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
||||
dcb.Parity = NOPARITY;
|
||||
dcb.ByteSize = 8;
|
||||
dcb.StopBits = ONESTOPBIT;
|
||||
dcb.BaudRate = CBR_115200;
|
||||
DCBchanged = FALSE;
|
||||
if (lstrlen(devname) > 0) {
|
||||
wsprintf(portstr, "\\\\.\\%s", devname);
|
||||
@ -57,6 +66,16 @@ serial_raw::serial_raw (char *devname)
|
||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
|
||||
if (hCOM != INVALID_HANDLE_VALUE) {
|
||||
present = 1;
|
||||
GetCommModemStatus(hCOM, &MSR_value);
|
||||
SetupComm(hCOM, 8192, 2048);
|
||||
PurgeComm(hCOM, PURGE_TXABORT | PURGE_RXABORT |
|
||||
PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
SetCommMask(hCOM, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR);
|
||||
memset(&rx_ovl, 0, sizeof(OVERLAPPED));
|
||||
rx_ovl.hEvent = CreateEvent(NULL,TRUE,FALSE,"receive");
|
||||
hRawSerialThread = CreateThread(NULL, 0, RawSerialThread, this, 0, &threadID);
|
||||
#endif
|
||||
} else {
|
||||
present = 0;
|
||||
BX_ERROR(("Raw device '%s' not present", devname));
|
||||
@ -76,6 +95,14 @@ serial_raw::~serial_raw (void)
|
||||
{
|
||||
if (present) {
|
||||
#ifdef WIN32
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
thread_quit = TRUE;
|
||||
SetCommMask(hCOM, 0);
|
||||
while (thread_active) Sleep(10);
|
||||
CloseHandle(thread_ovl.hEvent);
|
||||
CloseHandle(rx_ovl.hEvent);
|
||||
CloseHandle(hRawSerialThread);
|
||||
#endif
|
||||
CloseHandle(hCOM);
|
||||
#endif
|
||||
}
|
||||
@ -187,14 +214,10 @@ serial_raw::set_modem_control (int ctrl)
|
||||
int
|
||||
serial_raw::get_modem_status ()
|
||||
{
|
||||
#ifdef WIN32
|
||||
DWORD mstat;
|
||||
#endif
|
||||
int status = 0;
|
||||
|
||||
#ifdef WIN32
|
||||
GetCommModemStatus(hCOM, &mstat);
|
||||
status = mstat & 0xf0;
|
||||
status = MSR_value;
|
||||
#endif
|
||||
BX_DEBUG (("get modem status returns 0x%02x", status));
|
||||
return status;
|
||||
@ -208,13 +231,15 @@ serial_raw::setup_port ()
|
||||
COMMTIMEOUTS ctmo;
|
||||
|
||||
ClearCommError(hCOM, &DErr, NULL);
|
||||
SetupComm(hCOM, 2048, 2048);
|
||||
PurgeComm(hCOM, PURGE_TXABORT | PURGE_RXABORT |
|
||||
PURGE_TXCLEAR | PURGE_RXCLEAR);
|
||||
memset(&ctmo, 0, sizeof(ctmo));
|
||||
SetCommTimeouts(hCOM, &ctmo);
|
||||
SetCommState(hCOM, &dcb);
|
||||
SetCommMask(hCOM, 0);
|
||||
rxdata_count = 0;
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
thread_rxdata_count = 0;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -260,6 +285,12 @@ serial_raw::ready_transmit ()
|
||||
bx_bool
|
||||
serial_raw::ready_receive ()
|
||||
{
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
if ((rxdata_count == 0) && (thread_rxdata_count > 0)) {
|
||||
SetEvent(thread_ovl.hEvent);
|
||||
SetEvent(rx_ovl.hEvent);
|
||||
}
|
||||
#endif
|
||||
BX_DEBUG (("ready_receive returning %d", (rxdata_count > 0)));
|
||||
return (rxdata_count > 0);
|
||||
}
|
||||
@ -267,17 +298,197 @@ serial_raw::ready_receive ()
|
||||
int
|
||||
serial_raw::receive ()
|
||||
{
|
||||
BX_DEBUG (("receive returning 'A'"));
|
||||
#ifdef WIN32
|
||||
int data;
|
||||
#endif
|
||||
|
||||
if (present) {
|
||||
#ifdef WIN32
|
||||
if (DCBchanged) {
|
||||
setup_port();
|
||||
}
|
||||
#endif
|
||||
data = rxdata_buffer[0];
|
||||
if (rxdata_count > 0) {
|
||||
memcpy(&rxdata_buffer[0], &rxdata_buffer[1], sizeof(Bit16s)*(RX_BUFSIZE-1));
|
||||
rxdata_count--;
|
||||
}
|
||||
if (data < 0) {
|
||||
switch (data) {
|
||||
case RAW_EVENT_CTS_ON:
|
||||
MSR_value |= 0x10;
|
||||
break;
|
||||
case RAW_EVENT_CTS_OFF:
|
||||
MSR_value &= ~0x10;
|
||||
break;
|
||||
case RAW_EVENT_DSR_ON:
|
||||
MSR_value |= 0x20;
|
||||
break;
|
||||
case RAW_EVENT_DSR_OFF:
|
||||
MSR_value &= ~0x20;
|
||||
break;
|
||||
case RAW_EVENT_RING_ON:
|
||||
MSR_value |= 0x40;
|
||||
break;
|
||||
case RAW_EVENT_RING_OFF:
|
||||
MSR_value &= ~0x40;
|
||||
break;
|
||||
case RAW_EVENT_RLSD_ON:
|
||||
MSR_value |= 0x80;
|
||||
break;
|
||||
case RAW_EVENT_RLSD_OFF:
|
||||
MSR_value &= ~0x80;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return data;
|
||||
#else
|
||||
BX_DEBUG (("receive returning 'A'"));
|
||||
return (int)'A';
|
||||
#endif
|
||||
} else {
|
||||
BX_DEBUG (("receive returning 'A'"));
|
||||
return (int)'A';
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
|
||||
DWORD WINAPI RawSerialThread(VOID *this_ptr)
|
||||
{
|
||||
serial_raw *class_ptr = (serial_raw *) this_ptr;
|
||||
class_ptr->serial_thread();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
serial_raw::serial_thread ()
|
||||
{
|
||||
DWORD DErr, Len2;
|
||||
DWORD EvtMask, MSR, Temp;
|
||||
char s1[2];
|
||||
|
||||
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE);
|
||||
thread_active = TRUE;
|
||||
thread_quit = FALSE;
|
||||
memset(&thread_ovl, 0, sizeof(OVERLAPPED));
|
||||
thread_ovl.hEvent = CreateEvent(NULL,TRUE,TRUE,"thread");
|
||||
thread_rxdata_count = 0;
|
||||
while (!thread_quit) {
|
||||
if ((rxdata_count == 0) && (thread_rxdata_count > 0)) {
|
||||
if (thread_rxdata_count > RX_BUFSIZE) {
|
||||
memcpy(&rxdata_buffer[0], &thread_rxdata_buffer[0], sizeof(Bit16s)*RX_BUFSIZE);
|
||||
memcpy(&thread_rxdata_buffer[0], &thread_rxdata_buffer[RX_BUFSIZE], sizeof(Bit16s)*(thread_rxdata_count-RX_BUFSIZE));
|
||||
rxdata_count = RX_BUFSIZE;
|
||||
thread_rxdata_count -= RX_BUFSIZE;
|
||||
} else {
|
||||
memcpy(&rxdata_buffer[0], &thread_rxdata_buffer[0], sizeof(Bit16s)*thread_rxdata_count);
|
||||
rxdata_count = thread_rxdata_count;
|
||||
thread_rxdata_count = 0;
|
||||
}
|
||||
}
|
||||
ClearCommError(hCOM, &DErr, NULL);
|
||||
EvtMask = 0;
|
||||
if (!WaitCommEvent(hCOM, &EvtMask, &thread_ovl)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
if (WaitForSingleObject(thread_ovl.hEvent, INFINITE) == WAIT_OBJECT_0) {
|
||||
GetOverlappedResult(hCOM, &thread_ovl, &Temp, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (EvtMask & EV_RXCHAR) {
|
||||
if (thread_rxdata_count < THREAD_RX_BUFSIZE) {
|
||||
do {
|
||||
ClearCommError(hCOM, &DErr, NULL);
|
||||
if (!ReadFile(hCOM, s1, 1, &Len2, &rx_ovl)) {
|
||||
if (GetLastError() == ERROR_IO_PENDING) {
|
||||
if (WaitForSingleObject(rx_ovl.hEvent, INFINITE) != WAIT_OBJECT_0) {
|
||||
Len2 = 0;
|
||||
} else {
|
||||
GetOverlappedResult(hCOM, &rx_ovl, &Len2, FALSE);
|
||||
}
|
||||
} else {
|
||||
Len2 = 0;
|
||||
}
|
||||
}
|
||||
if (Len2 > 0) {
|
||||
enq_event(s1[0]);
|
||||
}
|
||||
if ((rxdata_count == 0) && (thread_rxdata_count > 0)) {
|
||||
if (thread_rxdata_count > RX_BUFSIZE) {
|
||||
memcpy(&rxdata_buffer[0], &thread_rxdata_buffer[0], sizeof(Bit16s)*RX_BUFSIZE);
|
||||
memcpy(&thread_rxdata_buffer[0], &thread_rxdata_buffer[RX_BUFSIZE], sizeof(Bit16s)*(thread_rxdata_count-RX_BUFSIZE));
|
||||
rxdata_count = RX_BUFSIZE;
|
||||
thread_rxdata_count -= RX_BUFSIZE;
|
||||
} else {
|
||||
memcpy(&rxdata_buffer[0], &thread_rxdata_buffer[0], sizeof(Bit16s)*thread_rxdata_count);
|
||||
rxdata_count = thread_rxdata_count;
|
||||
thread_rxdata_count = 0;
|
||||
}
|
||||
}
|
||||
} while ((Len2 != 0) && (thread_rxdata_count < THREAD_RX_BUFSIZE));
|
||||
ClearCommError(hCOM, &DErr, NULL);
|
||||
}
|
||||
}
|
||||
if (EvtMask & EV_BREAK) {
|
||||
enq_event(RAW_EVENT_BREAK);
|
||||
}
|
||||
if (EvtMask & EV_ERR) {
|
||||
ClearCommError(hCOM, &DErr, NULL);
|
||||
if (DErr & CE_FRAME) {
|
||||
enq_event(RAW_EVENT_FRAME);
|
||||
}
|
||||
if (DErr & CE_OVERRUN) {
|
||||
enq_event(RAW_EVENT_OVERRUN);
|
||||
}
|
||||
if (DErr & CE_RXPARITY) {
|
||||
enq_event(RAW_EVENT_PARITY);
|
||||
}
|
||||
}
|
||||
if (EvtMask & (EV_CTS | EV_DSR | EV_RING | EV_RLSD)) {
|
||||
GetCommModemStatus(hCOM, &MSR);
|
||||
}
|
||||
if (EvtMask & EV_CTS) {
|
||||
if (MSR & MS_CTS_ON) {
|
||||
enq_event(RAW_EVENT_CTS_ON);
|
||||
} else {
|
||||
enq_event(RAW_EVENT_CTS_OFF);
|
||||
}
|
||||
}
|
||||
if (EvtMask & EV_DSR) {
|
||||
if (MSR & MS_DSR_ON) {
|
||||
enq_event(RAW_EVENT_DSR_ON);
|
||||
} else {
|
||||
enq_event(RAW_EVENT_DSR_OFF);
|
||||
}
|
||||
}
|
||||
if (EvtMask & EV_RING) {
|
||||
if (MSR & MS_RING_ON) {
|
||||
enq_event(RAW_EVENT_RING_ON);
|
||||
} else {
|
||||
enq_event(RAW_EVENT_RING_OFF);
|
||||
}
|
||||
}
|
||||
if (EvtMask & EV_RLSD) {
|
||||
if (MSR & MS_RLSD_ON) {
|
||||
enq_event(RAW_EVENT_RLSD_ON);
|
||||
} else {
|
||||
enq_event(RAW_EVENT_RLSD_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
CloseHandle(thread_ovl.hEvent);
|
||||
thread_active = FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
serial_raw::enq_event (Bit16s event)
|
||||
{
|
||||
if (thread_rxdata_count < THREAD_RX_BUFSIZE) {
|
||||
thread_rxdata_buffer[thread_rxdata_count++] = event;
|
||||
} else {
|
||||
fprintf(stderr, "receive buffer overflow\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
@ -1,5 +1,5 @@
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// $Id: serial_raw.h,v 1.10 2004-03-28 12:41:12 vruppert Exp $
|
||||
// $Id: serial_raw.h,v 1.11 2004-05-13 16:23:15 vruppert Exp $
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
@ -9,6 +9,11 @@
|
||||
#include <linux/serial.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
// experimental raw serial receive support on win32
|
||||
//#define WIN32_RECEIVE_RAW
|
||||
#endif
|
||||
|
||||
#define P_NONE 0
|
||||
#define P_ODD 1
|
||||
#define P_EVEN 2
|
||||
@ -28,6 +33,9 @@
|
||||
#define RAW_EVENT_OVERRUN -11
|
||||
#define RAW_EVENT_PARITY -12
|
||||
|
||||
#define THREAD_RX_BUFSIZE 8192
|
||||
#define RX_BUFSIZE 256
|
||||
|
||||
class serial_raw : public logfunctions {
|
||||
public:
|
||||
serial_raw (char *devname);
|
||||
@ -43,15 +51,32 @@ class serial_raw : public logfunctions {
|
||||
bx_bool ready_transmit ();
|
||||
bx_bool ready_receive ();
|
||||
int receive ();
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
void serial_thread ();
|
||||
#endif
|
||||
|
||||
private:
|
||||
void setup_port ();
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
void enq_event (Bit16s event);
|
||||
#endif
|
||||
bx_bool present;
|
||||
Bit8u rxdata_count;
|
||||
unsigned rxdata_count;
|
||||
#ifdef WIN32
|
||||
HANDLE hCOM;
|
||||
DCB dcb;
|
||||
BOOL DCBchanged;
|
||||
DWORD MSR_value;
|
||||
Bit16s rxdata_buffer[RX_BUFSIZE];
|
||||
#ifdef WIN32_RECEIVE_RAW
|
||||
HANDLE hRawSerialThread;
|
||||
BOOL thread_active;
|
||||
BOOL thread_quit;
|
||||
OVERLAPPED rx_ovl;
|
||||
OVERLAPPED thread_ovl;
|
||||
unsigned thread_rxdata_count;
|
||||
Bit16s thread_rxdata_buffer[THREAD_RX_BUFSIZE];
|
||||
#endif
|
||||
#endif
|
||||
};
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user