Files
Work/m68hc11/MCUTHRD.CPP
2024-08-07 09:16:27 -04:00

239 lines
6.2 KiB
C++

#include <m68hc11/mcuthrd.hpp>
#include <m68hc11/commctrl.hpp>
#include <m68hc11/m68hc11.hpp>
#include <m68hc11/m68reg.hpp>
#include <common/openfile.hpp>
#include <common/gdata.hpp>
MCUThread::MCUThread(void)
: mIsInEvents(false)
{
mThreadHandler.setCallback(this,&MCUThread::threadHandler);
insertHandler(&mThreadHandler);
}
MCUThread::MCUThread(const MCUThread &someMCUThread)
: mIsInEvents(false)
{ // private implementation
*this=someMCUThread;
}
MCUThread::~MCUThread()
{
removeHandler(&mThreadHandler);
}
MCUThread &MCUThread::operator=(const MCUThread &someMCUThread)
{ // private implementation
return *this;
}
void MCUThread::listen(const String &strPathBinary)
{
String *pString=::new String(strPathBinary);
ThreadMessage threadMessage(ThreadMessage::TM_USER,ThMsgListen,int(pString));
postMessage(threadMessage);
return;
}
DWORD MCUThread::threadHandler(ThreadMessage &someThreadMessage)
{
switch(someThreadMessage.message())
{
case ThreadMessage::TM_CREATE :
break;
case ThreadMessage::TM_DESTROY :
break;
case ThreadMessage::TM_USER :
if(ThMsgListen==someThreadMessage.userDataOne())
{
String *pString=(String*)someThreadMessage.userDataTwo();
thListen(*pString);
::delete pString;
}
break;
}
return FALSE;
}
void MCUThread::thListen(const String &strPathBinary)
{
CommControl commControl;
sendMessage("Initializing device...");
if(!openDevice(commControl))return;
sendMessage("Loading code...");
if(!codeLoad(commControl,strPathBinary))return;
sendMessage("Processing events...");
processEvents(commControl);
return;
}
BOOL MCUThread::openDevice(CommControl &commControl,bool useOverlappedIO)
{
M68Reg mcuReg;
if(!commControl.open(CommControl::stringToPort(mcuReg.getPort()),useOverlappedIO))
{
mErrorEventHandler.callback(CallbackData(ErrorPortOpen,0L));
return FALSE;
}
if(!commControl.setDeviceControlBlock(mcuReg.getSerialSettings()))
{
mErrorEventHandler.callback(CallbackData(ErrorPortSettings,0L));
return FALSE;
}
commControl.setEventMask(CommControl::EventBreak);
if(!commControl.waitEvent())
{
mErrorEventHandler.callback(CallbackData(ErrorTimeout,0L));
return FALSE;
}
return TRUE;
}
BOOL MCUThread::codeLoad(CommControl &commControl,const String &strPathBinary)
{
FileHandle inFile;
BYTE sndBuffer[256];
// BYTE rcvBuffer[256];
GlobalData<BYTE> rcvBuffer;
WORD codeLength(0);
BYTE prefix(0xFF);
BYTE *ptrByte;
if(!inFile.open(strPathBinary))
{
mErrorEventHandler.callback(CallbackData(ErrorFileOpen,int(&(String&)strPathBinary)));
return FALSE;
}
::memset(sndBuffer,1,sizeof(sndBuffer));
// ::memset(&rcvBuffer,0,sizeof(rcvBuffer));
ptrByte=sndBuffer;
while(inFile.read(*ptrByte)&&codeLength<=256){codeLength++;ptrByte++;}
commControl.write(&prefix,sizeof(prefix));
commControl.clearReceiveQueue();
commControl.write(sndBuffer,sizeof(sndBuffer));
if(!commControl.waitForData())
{
mErrorEventHandler.callback(CallbackData(ErrorTalkBackFailure,0L));
return false;
}
rcvBuffer.size(sizeof(sndBuffer));
rcvBuffer.setZero();
commControl.readFully(rcvBuffer);
// commControl.readFully(rcvBuffer,sizeof(rcvBuffer));
if(::memcmp(&rcvBuffer[0],sndBuffer,sizeof(sndBuffer)))
{
mErrorEventHandler.callback(CallbackData(ErrorTalkBackData,0L));
return false;
}
return true;
}
// event types
// 0x00 - character
// 0x01 - WORD
// 0x02 - DWORD
// 0x03 - varchar : [WORD:count,countcharacters]
// 0xFF - end
BOOL MCUThread::processEvents(CommControl &commControl)
{
GlobalData<BYTE> byteData;
String strString;
BYTE event(0x00);
BYTE ack(0x00);
WORD wordData;
DWORD dwordData;
char charData;
int index;
int map(0x1000);
::OutputDebugString("MCUThread::processEvents[Thread is starting]");
isInEvents(true);
while(isInEvents())
{
if(!commControl.hasData())continue;
commControl.read(&event,sizeof(event));
switch(MCUEvent(event))
{
case EventString :
{
String str;
sendMessage(STRING_EVENTSTRING);
while(true)
{
commControl.read(&charData,sizeof(charData));
if(!charData)break;
str+=charData;
}
mMCUEventHandler.callback(CallbackData(EventString,int(&str)));
commControl.write(&ack,sizeof(ack));
}
break;
case EventSingleByte :
sendMessage(STRING_EVENTSINGLEBYTE);
commControl.read(&charData,sizeof(charData));
mMCUEventHandler.callback(CallbackData(EventSingleByte,int(&charData)));
commControl.write(&ack,sizeof(ack));
break;
case EventDoubleByte :
sendMessage(STRING_EVENTDOUBLEBYTE);
commControl.read(&wordData,sizeof(wordData));
mMCUEventHandler.callback(CallbackData(EventDoubleByte,int(&wordData)));
commControl.write(&ack,sizeof(ack));
break;
case EventQuadByte :
sendMessage(STRING_EVENTQUADBYTE);
commControl.read(&dwordData,sizeof(dwordData));
mMCUEventHandler.callback(CallbackData(EventQuadByte,(int)&dwordData));
commControl.write(&ack,sizeof(ack));
break;
case EventVarByte :
sendMessage(STRING_EVENTVARBYTE);
commControl.read(&wordData,sizeof(wordData));
byteData.size(wordData);
for(index=0;index<byteData.size();index++)
{
commControl.read(&charData,sizeof(charData));
byteData[index]=charData;
}
mMCUEventHandler.callback(CallbackData(EventVarByte,int(&byteData)));
commControl.write(&ack,sizeof(ack));
break;
case EventRegs :
map=0x1000;
byteData.size(64);
sendMessage(STRING_EVENTREGDATASTART);
for(index=0;index<byteData.size();index++)
{
commControl.read(&charData,sizeof(charData));
byteData[index]=charData;
}
sendMessage(STRING_EVENTREGDATACOMPLETE);
mMCUEventHandler.callback(CallbackData(EventRegs,int(&byteData)));
commControl.write(&ack,sizeof(ack));
break;
case EventEnd :
sendMessage(STRING_EVENTCODECOMPLETE);
mMCUEventHandler.callback(CallbackData(EventEnd,0L));
isInEvents(false);
break;
default :
{
String str;
::sprintf(str,"unexpected character : 0x%04lx\n",(int)event);
::OutputDebugString(str);
}
}
}
::OutputDebugString("MCUThread::processEvents[Thread is ending normally]");
return TRUE;
}
void MCUThread::sendMessage(const String &strMessage)
{
mMessageHandler.callback(CallbackData(0,int(&(String&)strMessage)));
}