Re: RS232 RxBufferSize WinCE
From: aba (aba_ru_at_mail.ru)
Date: 02/05/04
- Next message: obelix: "Re: sockets eVC++ 4.0 accept(..) problems..........!!!!!!!!!!!!!!!"
- Previous message: caprice: "Resident mode for application"
- In reply to: Steve Maillet \(eMVP\): "Re: RS232 RxBufferSize WinCE"
- Next in thread: David Liao: "Re: RS232 RxBufferSize WinCE"
- Reply: David Liao: "Re: RS232 RxBufferSize WinCE"
- Messages sorted by: [ date ] [ thread ]
Date: 5 Feb 2004 01:20:39 -0800
"Steve Maillet \(eMVP\)" <nospam1@EntelechyConsulting.com> wrote in message news:<uZ9l7pm6DHA.1948@TK2MSFTNGP12.phx.gbl>...
> Ignore the size info - it's an error. Just call read file with as big a
> buffer as you want. The driver will use your buffer directly.
Thanks.
But I cann't understand why just after opening the port there is an
error CE_RXOVER, that I can not clear?! What am I doing wrong? Here's
my code (Initialization, and 2 functions for the reading thread, that
wrapped in CISerial class):
[code]
DWORD CISerial::PortInitialize(LPCTSTR lpPort, DWORD dwBaudRate, HWND
hWndOnMsg)
{
COMMPROP commProp;
CString str;
COMSTAT Stat;
DWORD dwErrors;
// Attempt to open the serial port (COM1)
PortClose();
m_bPortOpened = FALSE;
m_hSerialPort = CreateFile (_T("COM1:"), // Pointer to the name of
the port
GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode
0, // Share mode
NULL, // Pointer to the security attribute
OPEN_EXISTING,// How to open the serial port
0, // Port attributes
NULL); // Handle to port with attribute
// to copy
if (m_hSerialPort == INVALID_HANDLE_VALUE){
#ifdef DEBUG_MSGS_ON
MessageBox(_T("Unable to open serial port"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
// Set the size of the input and output buffer
if (!SetupComm(m_hSerialPort, 1024, 0)) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to set the buffer-size parameters"),
_T("Error"), MB_OK);
#endif
return GetLastError()?GetLastError():-1;
}
// Terminates all outstanding read and write operations and clear
the buffers
VERIFY(PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR));
// Initialize the DCBlength member.
DCB PortDCB;
FillMemory(&PortDCB, sizeof(PortDCB), 0);
PortDCB.DCBlength = sizeof (DCB);
// Get the default port setting information.
GetCommState (m_hSerialPort, &PortDCB);
// Change the DCB structure settings.
PortDCB.BaudRate = dwBaudRate; //16384; // Current baud
PortDCB.fBinary = TRUE; // Binary mode; no EOF check
PortDCB.fParity = TRUE; // Enable parity checking
PortDCB.fOutxCtsFlow = FALSE; // No CTS output flow control
PortDCB.fOutxDsrFlow = FALSE; // No DSR output flow control
PortDCB.fDtrControl = DTR_CONTROL_ENABLE; //DTR_CONTROL_DISABLE;
// DTR flow control type
PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity
PortDCB.fTXContinueOnXoff = FALSE; // XOFF continues Tx
PortDCB.fOutX = FALSE; // No XON/XOFF out flow control
PortDCB.fInX = FALSE; // No XON/XOFF in flow control
PortDCB.fErrorChar = FALSE; // Disable error replacement
PortDCB.fNull = FALSE; // Disable null stripping
PortDCB.fRtsControl = RTS_CONTROL_DISABLE;
// RTS flow control
PortDCB.fAbortOnError = FALSE; // Do not abort reads/writes on
// error
PortDCB.ByteSize = 8; // Number of bits/byte, 4-8
PortDCB.Parity = NOPARITY; // 0-4=no,odd,even,mark,space
PortDCB.StopBits = ONESTOPBIT; // 0,1,2 = 1, 1.5, 2
// Configure the port according to the specifications of the DCB
// structure.
if (!SetCommState (m_hSerialPort, &PortDCB))
{
// Could not create the read thread.
#ifdef DEBUG_MSGS_ON
MessageBox(_T("Unable to configure the serial port"), _T("Error"),
MB_OK);
#endif
return GetLastError();
}
// Retrieve the time-out parameters for all read and write operations
// on the port.
COMMTIMEOUTS CommTimeouts;
GetCommTimeouts (m_hSerialPort, &CommTimeouts);
// Change the COMMTIMEOUTS structure settings.
CommTimeouts.ReadIntervalTimeout = MAXDWORD;
CommTimeouts.ReadTotalTimeoutMultiplier = 0;
CommTimeouts.ReadTotalTimeoutConstant = 0; //5
CommTimeouts.WriteTotalTimeoutMultiplier = 0;
CommTimeouts.WriteTotalTimeoutConstant = 10;
// Set the time-out parameters for all read and write operations
// on the port.
if (!SetCommTimeouts (m_hSerialPort, &CommTimeouts))
{
// Could not create the read thread.
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to set the time-out parameters"),
_T("Error"), MB_OK);
#endif
return GetLastError();
}
if (!ClearCommBreak(m_hSerialPort)) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to restore character transmission
(unBREAK)"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
/* if (!SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR |
EV_RING)) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to specify a set of events to be monitored
for a communications device"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
*/
if (!EscapeCommFunction(m_hSerialPort, SETDTR)){
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to set DTR line"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
if (!EscapeCommFunction(m_hSerialPort, CLRRTS)){
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to clear RTS line"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
// ::Sleep(10);
#ifdef DEBUG_MSGS_ON
if (GetCommProperties(m_hSerialPort, &commProp)) {
str.Format(_T("Comm properties: %X(dwMaxTxQueue), %X(dwMaxRxQueue),
%X(dwMaxBaud), %X(dwProvSubType), %X(dwProvCapabilities),
%X(dwSettableParams), %X(dwSettableBaud), %X(wSettableData),
%X(wSettableStopParity), %X(dwCurrentTxQueue), %X(dwCurrentRxQueue)"),
commProp.dwMaxTxQueue, commProp.dwMaxRxQueue, commProp.dwMaxBaud,
commProp.dwProvSubType, commProp.dwProvCapabilities,
commProp.dwSettableParams, commProp.dwSettableBaud,
commProp.wSettableData, commProp.wSettableStopParity,
commProp.dwCurrentTxQueue, commProp.dwCurrentRxQueue);
MessageBox (str, _T("SerialPort"), MB_OK);
}
#endif
dwErrors = 0;
if (ClearCommError (m_hSerialPort, &dwErrors, &Stat)) {
#ifdef DEBUG_MSGS_ON
str.Format(_T("Possible errors: CE_BREAK(%d), CE_FRAME(%d),
CE_IOE(%d), CE_MODE(%d), CE_OVERRUN(%d), CE_RXOVER(%d),
CE_RXPARITY(%d), CE_TXFULL(%d)\nCOMM Status information: fCtsHold(%d),
fDsrHold(%d), fRlsdHold(%d), fXoffHold(%d), fXoffSent(%d), fEof(%d),
fTxim(%d), cbInQue(%d), cbOutQue(%d)"), dwErrors&CE_BREAK,
dwErrors&CE_FRAME, dwErrors&CE_IOE, dwErrors&CE_MODE,
dwErrors&CE_OVERRUN, dwErrors&CE_RXOVER, dwErrors&CE_RXPARITY,
dwErrors&CE_TXFULL, Stat.fCtsHold, Stat.fDsrHold, Stat.fRlsdHold,
Stat.fXoffHold, Stat.fXoffSent, Stat.fEof, Stat.fTxim, Stat.cbInQue,
Stat.cbOutQue);
MessageBox (str, _T("SerialPort"), MB_OK);
#endif
}
//GetCommState (m_hSerialPort, &PortDCB);
//str.Format(_T("Actual BaudRate is %d"), PortDCB.BaudRate);
//MessageBox (str, _T("OpeningPort"), MB_OK);
m_BaudRate = dwBaudRate;
m_lpPortName = lpPort;
m_bPortOpened = TRUE;
//Starting working thread for reading & processing inData
THREADPARMS* ptp = new THREADPARMS;
ptp->pClass = this;
ptp->hWndOnMsg = hWndOnMsg;
//pReadThread = AfxBeginThread(PortReadThreadProcT, ptp,
THREAD_PRIORITY_HIGHEST); //LPVOID(this));
pReadThread = ::CreateThread(NULL, 0, PortReadThreadProcT, ptp, 0,
NULL); //LPVOID(this));
if (pReadThread == NULL) {
#ifdef DEBUG_MSGS_ON
MessageBox (_T("Unable to run ReadThread"), _T("Error"), MB_OK);
#endif
return GetLastError();
}
VERIFY(SetThreadPriority(pReadThread, THREAD_PRIORITY_HIGHEST));
return 0;
}
DWORD WINAPI CISerial::PortReadThreadProcT(LPVOID pParam)
{
// Route the method to the actual object
THREADPARMS* ptp = (THREADPARMS*) pParam;
CISerial* pThis = reinterpret_cast<CISerial*>(ptp->pClass);
HWND hWnd = ptp->hWndOnMsg;
delete ptp;
return pThis->PortReadThreadProc(hWnd);
}
UINT CISerial::PortReadThreadProc(HWND hWnd)
{
DWORD inDataCount =
sizeof(m_InDataPacketCur)/sizeof(m_InDataPacketCur[0]);
DWORD dwBytesTransferred, dwTotalBytesTransferred = 0;
BOOL bErr;
DWORD dwCommModemStatus;
int dCheckErrCount = NUM_CHECKSUM_TRY;
COMSTAT Stat;
DWORD dwErrors;
BYTE readBuf[RxBufferSize];
// int pReadBuf = 0; //pointer to current position in readBuf
CString str;
::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_WAITING,
(WPARAM) 0, 0);
VERIFY(PurgeComm(m_hSerialPort, PURGE_TXABORT | PURGE_RXABORT |
PURGE_TXCLEAR | PURGE_RXCLEAR));
VERIFY(SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR |
EV_RING | EV_BREAK | EV_ERR));
dwErrors = 0;
if (ClearCommError (m_hSerialPort, &dwErrors, &Stat)) {
#ifdef DEBUG_MSGS_ON
str.Format(_T("Possible errors: CE_BREAK(%d), CE_FRAME(%d),
CE_IOE(%d), CE_MODE(%d), CE_OVERRUN(%d), CE_RXOVER(%d),
CE_RXPARITY(%d), CE_TXFULL(%d)\nCOMM Status information: fCtsHold(%d),
fDsrHold(%d), fRlsdHold(%d), fXoffHold(%d), fXoffSent(%d), fEof(%d),
fTxim(%d), cbInQue(%d), cbOutQue(%d)"), dwErrors&CE_BREAK,
dwErrors&CE_FRAME, dwErrors&CE_IOE, dwErrors&CE_MODE,
dwErrors&CE_OVERRUN, dwErrors&CE_RXOVER, dwErrors&CE_RXPARITY,
dwErrors&CE_TXFULL, Stat.fCtsHold, Stat.fDsrHold, Stat.fRlsdHold,
Stat.fXoffHold, Stat.fXoffSent, Stat.fEof, Stat.fTxim, Stat.cbInQue,
Stat.cbOutQue);
MessageBox (str, _T("SerialPort"), MB_OK);
#endif
}
while (m_hSerialPort != INVALID_HANDLE_VALUE) {//
// Wait for an event to occur for the port.
WaitCommEvent (m_hSerialPort, &dwCommModemStatus, NULL);
// Re-specify the set of events to be monitored for the port.
SetCommMask (m_hSerialPort, EV_RXCHAR | EV_CTS | EV_DSR | EV_RING |
EV_BREAK | EV_ERR);
//check the event for errors
if (dwCommModemStatus & EV_ERR)
{
dwErrors = 0;
if (ClearCommError(m_hSerialPort, &dwErrors, &Stat)) {
#ifdef DEBUG_MSGS_ON
str.Format(_T("Possible errors: CE_BREAK(%d), CE_FRAME(%d),
CE_IOE(%d), CE_MODE(%d), CE_OVERRUN(%d), CE_RXOVER(%d),
CE_RXPARITY(%d), CE_TXFULL(%d)\nCOMM Status information: fCtsHold(%d),
fDsrHold(%d), fRlsdHold(%d), fXoffHold(%d), fXoffSent(%d), fEof(%d),
fTxim(%d), cbInQue(%d), cbOutQue(%d)"), dwErrors&CE_BREAK,
dwErrors&CE_FRAME, dwErrors&CE_IOE, dwErrors&CE_MODE,
dwErrors&CE_OVERRUN, dwErrors&CE_RXOVER, dwErrors&CE_RXPARITY,
dwErrors&CE_TXFULL, Stat.fCtsHold, Stat.fDsrHold, Stat.fRlsdHold,
Stat.fXoffHold, Stat.fXoffSent, Stat.fEof, Stat.fTxim, Stat.cbInQue,
Stat.cbOutQue);
MessageBox (str, _T("SerialPort"), MB_OK);
#endif
}
} //if (dwCommModemStatus & EV_ERR)
//check for RXCHAR
if (dwCommModemStatus & EV_RXCHAR)
{
// Loop for waiting for the data.
do
{
bErr = ReadFile(m_hSerialPort, &readBuf[0],
(inDataCount>dwTotalBytesTransferred)?(inDataCount-dwTotalBytesTransferred):0,
&dwBytesTransferred, NULL);
if (!bErr) {
return GetLastError();
}
if (dwBytesTransferred > 0){
m_mutexSerPortRxBufferBusy.Lock();
//copying inData from readBuf to m_InDataPacketCur
memcpy(&m_InDataPacketCur[dwTotalBytesTransferred], &readBuf[0],
dwBytesTransferred);
m_mutexSerPortRxBufferBusy.Unlock();
dwTotalBytesTransferred += dwBytesTransferred;
if (dwTotalBytesTransferred < inDataCount)
::PostMessage (hWnd, WM_USER_SERIAL_PORT_READING_THREAD_WAITING,
(WPARAM) 0, 0);
//return 2 ;
else {
// if (dwTotalBytesTransferred >= inDataCount) {
if (!CISerial::ProcessInData()) {
//Error in checksum => try to receive extra data
::PostMessage (hWnd,
WM_USER_SERIAL_PORT_READING_THREAD_SUMCHECK_ERR, (WPARAM)
(NUM_CHECKSUM_TRY-dCheckErrCount), 0);
if (dCheckErrCount--) {
m_mutexSerPortRxBufferBusy.Lock();
memmove(&m_InDataPacketCur[0], &m_InDataPacketCur[1],
inDataCount-1);
m_mutexSerPortRxBufferBusy.Unlock();
dwTotalBytesTransferred--;
}
else {
dwTotalBytesTransferred = 0;
::PostMessage (hWnd,
WM_USER_SERIAL_PORT_READING_THREAD_CANCELED, (WPARAM) 0, 0);
return 1;
}
}
else {
dwTotalBytesTransferred = 0;
dCheckErrCount = NUM_CHECKSUM_TRY;
::PostMessage (hWnd,
WM_USER_SERIAL_PORT_READING_THREAD_FINISHED, (WPARAM) 0, 0);
}
} //if (dwTotalBytesTransferred >= inDataCount)
} //if (dwBytesTransferred > 0)
} while ((dwBytesTransferred > 0));//&&(dwTotalBytesTransferred <
inDataCount));
}
if (WaitForSingleObject(m_eventSerPortReadKill, 0) ==
WAIT_OBJECT_0){
break;
}
} //while (m_hSerialPort != INVALID_HANDLE_VALUE)
return 0;
}
[/code]
- Next message: obelix: "Re: sockets eVC++ 4.0 accept(..) problems..........!!!!!!!!!!!!!!!"
- Previous message: caprice: "Resident mode for application"
- In reply to: Steve Maillet \(eMVP\): "Re: RS232 RxBufferSize WinCE"
- Next in thread: David Liao: "Re: RS232 RxBufferSize WinCE"
- Reply: David Liao: "Re: RS232 RxBufferSize WinCE"
- Messages sorted by: [ date ] [ thread ]
Relevant Pages
|