210 lines
6.4 KiB
C++
210 lines
6.4 KiB
C++
#include <m68hc11/commctrl.hpp>
|
|
#include <m68hc11/m68hc11.hpp>
|
|
#include <m68hc11/fmtlines.hpp>
|
|
|
|
void CommControl::portToString(CommControl::Port port,String &strPort)
|
|
{
|
|
if(port==CommControl::PortCOM1)strPort=String(STRING_COM1);
|
|
else if(port==CommControl::PortCOM2)strPort=String(STRING_COM2);
|
|
else if(port==CommControl::PortCOM3)strPort=String(STRING_COM3);
|
|
else strPort=String(STRING_COM4);
|
|
}
|
|
|
|
CommControl::Port CommControl::stringToPort(const String &strPort)
|
|
{
|
|
if(strPort==String(STRING_COM1))return CommControl::PortCOM1;
|
|
else if(strPort==String(STRING_COM2))return CommControl::PortCOM2;
|
|
else if(strPort==String(STRING_COM3))return CommControl::PortCOM3;
|
|
else return CommControl::PortCOM4;
|
|
}
|
|
|
|
bool CommControl::readFully(GlobalData<BYTE> &dataBytes)
|
|
{
|
|
CommStatus commStatus;
|
|
DWORD bytesRead=0;
|
|
DWORD byteCount;
|
|
DWORD bytesToRead;
|
|
|
|
if(!isOkay())return false;
|
|
clearError(commStatus);
|
|
byteCount=dataBytes.size();
|
|
if(!byteCount&&!commStatus.bytesInReceiveQueue())return false;
|
|
if(!byteCount){byteCount=commStatus.bytesInReceiveQueue();dataBytes.size(byteCount);}
|
|
return readFully(&dataBytes[0],dataBytes.size());
|
|
}
|
|
|
|
bool CommControl::readFully(BYTE *pBuffer,DWORD byteCount)
|
|
{
|
|
CommStatus commStatus;
|
|
DWORD bytesRead=0;
|
|
DWORD bytesToRead;
|
|
|
|
if(!isOkay())return false;
|
|
clearError(commStatus);
|
|
if(!byteCount||!pBuffer)return false;
|
|
while(bytesRead<byteCount)
|
|
{
|
|
if(commStatus.bytesInReceiveQueue())
|
|
{
|
|
bytesToRead=bytesRead+commStatus.bytesInReceiveQueue()>byteCount?byteCount-bytesRead:commStatus.bytesInReceiveQueue();
|
|
read(&pBuffer[bytesRead],bytesToRead);
|
|
bytesRead+=bytesToRead;
|
|
}
|
|
if(bytesRead==byteCount)break;
|
|
::Sleep(25);
|
|
clearError(commStatus);
|
|
}
|
|
showBytes(pBuffer,byteCount);
|
|
return true;
|
|
}
|
|
|
|
bool CommControl::hasData(void)
|
|
{
|
|
CommStatus commStatus;
|
|
clearError(commStatus);
|
|
return commStatus.bytesInReceiveQueue()?true:false;
|
|
}
|
|
|
|
bool CommControl::clearReceiveQueue(void)
|
|
{
|
|
GlobalData<BYTE> rcvBytes;
|
|
CommStatus commStatus;
|
|
|
|
if(!isOkay())return false;
|
|
::Sleep(1000);
|
|
clearError(commStatus);
|
|
if(!commStatus.bytesInReceiveQueue())return true;
|
|
::OutputDebugString(String(String("Clearing ")+String().fromInt(commStatus.bytesInReceiveQueue())+String(" bytes from receive queue.\n")).str());
|
|
rcvBytes.size(commStatus.bytesInReceiveQueue());
|
|
read(&rcvBytes[0],rcvBytes.size());
|
|
showBytes(rcvBytes);
|
|
return true;
|
|
}
|
|
|
|
bool CommControl::waitEvent(DWORD &eventMask,DWORD timeout)
|
|
{
|
|
BOOL result;
|
|
DWORD lastError;
|
|
|
|
eventMask=0;
|
|
if(!isOkay())return false;
|
|
mIOEvent.resetEvent();
|
|
result=::WaitCommEvent((HANDLE)mCommDevice,&eventMask,&mOverlapped.getOverlapped());
|
|
if(result)return true;
|
|
lastError=::GetLastError();
|
|
if(lastError!=ERROR_IO_PENDING)return false;
|
|
mIOEvent.waitEvent(timeout);
|
|
if(!mCommDevice.getOverlappedResult(mOverlapped,false))return false;
|
|
return true;
|
|
}
|
|
|
|
DWORD CommControl::enumerateDevices(Block<Port> &deviceList)
|
|
{
|
|
|
|
deviceList.remove();
|
|
if(isOkay())return 0;
|
|
for(Port port=PortCOM1;port<=PortCOM4;((int&)port)++)
|
|
{
|
|
if(mCommDevice.open(mStrPorts[port]))
|
|
{
|
|
mCommDevice.close();
|
|
deviceList.insert(&port);
|
|
}
|
|
}
|
|
return deviceList.size();
|
|
}
|
|
|
|
DWORD CommControl::enumerateDevices(Block<String> &deviceList)
|
|
{
|
|
deviceList.remove();
|
|
if(isOkay())return 0;
|
|
for(Port port=PortCOM1;port<=PortCOM4;((int&)port)++)
|
|
{
|
|
if(mCommDevice.open(mStrPorts[port]))
|
|
{
|
|
mCommDevice.close();
|
|
if(PortCOM1==port)deviceList.insert(&String("COM1"));
|
|
else if(PortCOM2==port)deviceList.insert(&String("COM2"));
|
|
else if(PortCOM3==port)deviceList.insert(&String("COM3"));
|
|
else if(PortCOM4==port)deviceList.insert(&String("COM4"));
|
|
}
|
|
}
|
|
return deviceList.size();
|
|
}
|
|
|
|
DWORD CommControl::read(void *pBuffer,int length,DWORD timeout)
|
|
{
|
|
BOOL result;
|
|
DWORD lastError;
|
|
|
|
if(!isOkay())return FALSE;
|
|
mIOEvent.resetEvent();
|
|
result=mCommDevice.read((BYTE*)pBuffer,length,mOverlapped);
|
|
if(result)return TRUE;
|
|
lastError=::GetLastError();
|
|
if(lastError!=ERROR_IO_PENDING)return FALSE;
|
|
mIOEvent.waitEvent(TimeOut);
|
|
if(!mCommDevice.getOverlappedResult(mOverlapped,FALSE))return FALSE;
|
|
return TRUE;
|
|
}
|
|
|
|
bool CommControl::isOkay(void)const
|
|
{
|
|
return mCommDevice.isOkay();
|
|
}
|
|
|
|
bool CommControl::clearError(CommStatus &commStatus)const
|
|
{
|
|
DWORD errorMask(0);
|
|
bool returnCode(false);
|
|
|
|
if(!isOkay())return returnCode;
|
|
returnCode=::ClearCommError((HANDLE)mCommDevice,&errorMask,&commStatus.getCOMSTAT());
|
|
showError(errorMask);
|
|
return returnCode;
|
|
}
|
|
|
|
bool CommControl::clearError(void)const
|
|
{
|
|
DWORD errorMask(0);
|
|
bool returnCode(false);
|
|
|
|
if(!isOkay())return false;
|
|
returnCode=::ClearCommError((HANDLE)mCommDevice,&errorMask,0);
|
|
showError(errorMask);
|
|
return returnCode;
|
|
}
|
|
|
|
void CommControl::showError(DWORD errorMask)const
|
|
{
|
|
if(errorMask&CE_BREAK)::OutputDebugString("The hardware detected a break condition.\n");
|
|
if(errorMask&CE_DNS)::OutputDebugString("Windows 95 and Windows 98: A parallel device is not selected.\n");
|
|
if(errorMask&CE_FRAME)::OutputDebugString("The hardware detected a framing error.\n");
|
|
if(errorMask&CE_IOE)::OutputDebugString("An I/O error occurred during communications with the device.\n");
|
|
if(errorMask&CE_MODE)::OutputDebugString("The requested mode is not supported, or the hFile parameter is invalid. If this value is specified, it is the only valid error.\n");
|
|
if(errorMask&CE_OOP)::OutputDebugString("Windows 95 and Windows 98: A parallel device signaled that it is out of paper.\n");
|
|
if(errorMask&CE_OVERRUN)::OutputDebugString("A character-buffer overrun has occurred. The next character is lost.\n");
|
|
if(errorMask&CE_PTO)::OutputDebugString("Windows 95 and Windows 98: A time-out occurred on a parallel device.\n");
|
|
if(errorMask&CE_RXOVER)::OutputDebugString("An input buffer overflow has occurred. There is either no room in the input buffer, or a character was received after the end-of-file (EOF) character.\n");
|
|
if(errorMask&CE_RXPARITY)::OutputDebugString("The hardware detected a parity error.\n");
|
|
if(errorMask&CE_TXFULL)::OutputDebugString("The application tried to transmit a character, but the output buffer was full.\n");
|
|
}
|
|
|
|
void CommControl::showBytes(BYTE *pBuffer,DWORD byteCount)
|
|
{
|
|
Block<String> strLines;
|
|
|
|
::OutputDebugString("\n");
|
|
FormatLines::hexasciiLines(strLines,pBuffer,byteCount);
|
|
for(int index=0;index<strLines.size();index++)
|
|
{
|
|
::OutputDebugString(strLines[index].str());
|
|
::OutputDebugString("\n");
|
|
}
|
|
}
|
|
|
|
void CommControl::showBytes(GlobalData<BYTE> rcvBytes)
|
|
{
|
|
showBytes(&rcvBytes[0],rcvBytes.size());
|
|
}
|