SystemGui/Sources/PICUploader/BootloaderProtocol.cpp

293 lines
7.6 KiB
C++

#include "BootloaderProtocol.h"
#include "PICUploader.h"
CBootloaderProtocol::CBootloaderProtocol(QObject *parent) : QObject(parent)
{
mCRCEngine.InitTable();
}
CBootloaderProtocol::~CBootloaderProtocol()
{
}
int CBootloaderProtocol::BootloaderProtocolInit()
{
BootloaderProtocolResetStateMachine();
}
int CBootloaderProtocol::BootloaderProtocolResetStateMachine()
{
mBootloaderDataSize = 0;
mBootloaderHeader = 0;
mBootloaderBufPtr = 0;
mBootloaderDataBuffer.clear();
mBootloaderCommand = 0;
mBootloaderCRC = 0;
mBootloaderComputedCRC = CRC_START_32;
mBootloaderState = RxHeader1;
mBootloaderDataCtr = 0;
}
int CBootloaderProtocol::BooloaderProtocolRxFrame(QByteArray Frame)
{
for(int i = 0; i < Frame.size(); i++)
{
BootloaderProtocolStateMachine(Frame.at(i));
}
}
void CBootloaderProtocol::BootloaderProtocolStateMachine(unsigned char Data)
{
switch(mBootloaderState)
{
case Initialization: //Reset all pointers and data...
{
mBootloaderDataSize = 0;
mBootloaderBufPtr = 0;
mBootloaderDataBuffer.clear();
mBootloaderCommand = 0;
mBootloaderCRC = 0;
mBootloaderComputedCRC = CRC_START_32;
mBootloaderState = RxHeader1;
break;
}
case RxHeader1: //Wait for data header...
{
mBootloaderHeader += Data; //0xDE
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
if(Data == BOOTLOADER_FRAME_HEADER_1)
{
mBootloaderState = RxHeader2;
}
else
{
BootloaderProtocolResetStateMachine();
}
break;
}
case RxHeader2: //Wait for data header...
{
mBootloaderHeader <<= 8;
mBootloaderHeader += Data; //0xAD
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
if(Data == BOOTLOADER_FRAME_HEADER_2)
{
mBootloaderState = RxHeader3;
}
else
{
BootloaderProtocolResetStateMachine();
}
break;
}
case RxHeader3: //Wait for data header...
{
mBootloaderHeader <<= 8;
mBootloaderHeader += Data; //0xBE
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
if(Data == BOOTLOADER_FRAME_HEADER_3)
{
mBootloaderState = RxHeader4;
}
else
{
BootloaderProtocolResetStateMachine();
}
break;
}
case RxHeader4: //Wait for data header...
{
mBootloaderHeader <<= 8;
mBootloaderHeader += Data; //0xEF
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
if(mBootloaderHeader != BOOTLOADER_FRAME_HEADER)
{
//TODO, send NACK?
BootloaderProtocolResetStateMachine();
break;
}
else
{
mBootloaderState = RxCmd;
}
break;
}
case RxCmd:
{
mBootloaderCommand = Data;
mBootloaderState = RxPayloadSize1;
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
break;
}
case RxPayloadSize1:
{
mBootloaderDataSize = Data;
mBootloaderState = RxPayloadSize2;
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
break;
}
case RxPayloadSize2:
{
mBootloaderDataSize <<= 8;
mBootloaderDataSize += Data;
mBootloaderState = RxPayloadSize3;
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
break;
}
case RxPayloadSize3:
{
mBootloaderDataSize <<= 8;
mBootloaderDataSize += Data;
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
mBootloaderState = RxPayloadSize4;
break;
}
case RxPayloadSize4:
{
mBootloaderDataSize <<= 8;
mBootloaderDataSize += Data;
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
if(mBootloaderDataSize > MAX_BOOTLOADER_PAYLOAD_SIZE)
{
//TODO, send NACK?
BootloaderProtocolResetStateMachine();
break;
}
mBootloaderState = RxPayload;
break;
}
case RxPayload: //Data size
{
mBootloaderDataBuffer.append(Data);
mBootloaderDataCtr++;
mBootloaderComputedCRC = mCRCEngine.UpdateCRC32(mBootloaderComputedCRC,Data);
if(mBootloaderDataCtr == mBootloaderDataSize)
{
mBootloaderState = RxCRC1;
break;
}
break;
}
case RxCRC1: //Data size
{
mBootloaderCRC = Data;
mBootloaderState = RxCRC2;
break;
}
case RxCRC2: //Data size
{
mBootloaderCRC <<= 8;
mBootloaderCRC += Data;
mBootloaderState = RxCRC3;
break;
}
case RxCRC3: //Data size
{
mBootloaderCRC <<= 8;
mBootloaderCRC += Data;
mBootloaderState = RxCRC4;
break;
}
case RxCRC4: //Data size
{
mBootloaderCRC <<= 8;
mBootloaderCRC += Data;
mBootloaderComputedCRC ^= 0xffffffffL;
//if(mBootloaderCRC == 0xBAADCAFE)
if(mBootloaderCRC == mBootloaderComputedCRC)
{
mProgramHandle->BootloaderRxCmd(mBootloaderCommand,mBootloaderDataBuffer);
}
else
{
qDebug("Bootloader Protocol bad CRC...");
}
BootloaderProtocolResetStateMachine();
break;
}
default:
{
BootloaderProtocolResetStateMachine();
break;
}
}
}
QByteArray CBootloaderProtocol::BootloaderProtocolGetFrame(char Cmd, QByteArray Data)
{
QByteArray Frame;
Frame.clear();
// Header
Frame.append(BOOTLOADER_FRAME_HEADER_1);
Frame.append(BOOTLOADER_FRAME_HEADER_2);
Frame.append(BOOTLOADER_FRAME_HEADER_3);
Frame.append(BOOTLOADER_FRAME_HEADER_4);
//Cmd
Frame.append(Cmd);
//Size
unsigned int Size = Data.size();
char nibble = (char)((Size >> 24) &0x000000FF);
Frame.append(nibble);
nibble = (char)((Size >> 16) &0x000000FF);
Frame.append(nibble);
nibble = (char)((Size >> 8) &0x000000FF);
Frame.append(nibble);
nibble = (char)(Size &0x000000FF);
Frame.append(nibble);
//Payload
Frame.append(Data);
//CRC
unsigned int CRC = mCRCEngine.ComputeCRC32(Frame);
nibble = (char)((CRC >> 24) &0x000000FF);
Frame.append(nibble);
nibble = (char)((CRC >> 16) &0x000000FF);
Frame.append(nibble);
nibble = (char)((CRC >> 8) &0x000000FF);
Frame.append(nibble);
nibble = (char)(CRC &0x000000FF);
Frame.append(nibble);
/* Frame.append(0xBA);
Frame.append(0xAD);
Frame.append(0xCA);
Frame.append(0xFE);*/
//Send
return Frame;
}