293 lines
7.6 KiB
C++
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;
|
|
|
|
|
|
}
|