917 lines
36 KiB
C++
917 lines
36 KiB
C++
#include "PICUploader.h"
|
|
#include "GlobalDefine.h"
|
|
#include <QHostAddress>
|
|
#include <QtEndian>
|
|
|
|
|
|
CPICUploader::CPICUploader(CPICUploaderGui *Gui)
|
|
{
|
|
mPICUploaderGui = Gui;
|
|
mPICUploaderGui->mProgramHandle = this;
|
|
|
|
connect(&mBootloaderSocket,SIGNAL(connected()),this,SLOT(BootloaderSocketConnected()));
|
|
connect(&mBootloaderSocket,SIGNAL(disconnected()),this,SLOT(BootloaderSocketDisconnected()));
|
|
connect(&mBootloaderSocket,SIGNAL(readyRead()),this,SLOT(BootloaderDataAvailable()));
|
|
connect(&mBootloaderSocket,SIGNAL(error(QAbstractSocket::SocketError)),this,SLOT(BootloaderSocketError(QAbstractSocket::SocketError)));
|
|
|
|
mBootloaderProtocol.mProgramHandle = this;
|
|
}
|
|
|
|
|
|
int CPICUploader::Start()
|
|
{
|
|
mBootloaderProtocol.BootloaderProtocolInit();
|
|
ResetBooloaderInterfaceStateMachine();
|
|
return RET_OK;
|
|
}
|
|
|
|
|
|
int CPICUploader::OpenHexFileRequest(QString FilePath)
|
|
{
|
|
if(mHexFile.HexFileLoaded() == true)
|
|
{
|
|
mHexFile.CloseOpenedHexFile();
|
|
}
|
|
|
|
int ret = mHexFile.OpenDataFile(FilePath);
|
|
|
|
if(ret == 0)
|
|
return 0;
|
|
|
|
QString HexFileStats = QString("HexFileSize: %1\nFirmware Size: %4\nNb analyzed Records: %2\nNb Big Records: %3\nData CRC32: 0x%5").arg(mHexFile.GetFileSize()).arg(mHexFile.GetTotalParsedRecords()).arg(mHexFile.GetNBRecords()).arg(mHexFile.GetFirmwareSize()).arg(mHexFile.GetDataCRC32(),0,16);
|
|
|
|
mPICUploaderGui->SetHexFileStats(HexFileStats);
|
|
|
|
|
|
//HexFileStats << "HexFileSize: " << mHexFile.GetFileSize() << "\n";
|
|
// HexFileStats <<
|
|
}
|
|
|
|
int CPICUploader::ShowHexFileInfoRequest()
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(mHexFile.GetHexFileInfoString());
|
|
}
|
|
|
|
int CPICUploader::ConnectToBootloader(QString IP)
|
|
{
|
|
|
|
mBootloaderSocket.connectToHost(IP,99);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CPICUploader::DisconnectFromBootloader()
|
|
{
|
|
mBootloaderSocket.disconnectFromHost();
|
|
return true;
|
|
}
|
|
|
|
void CPICUploader::BootloaderSocketConnected()
|
|
{
|
|
mPICUploaderGui->UploaderSocketConnected();
|
|
mPICUploaderGui->AddTextToLogScreen("Socket Connected");
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_BOOTLOADER_CONNECTED_CMD);
|
|
}
|
|
|
|
void CPICUploader::BootloaderSocketDisconnected()
|
|
{
|
|
mPICUploaderGui->UploaderSocketDisconnected();
|
|
mPICUploaderGui->AddTextToLogScreen("Socket Disconnected");
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_BOOTLOADER_DISCONNECTED_CMD);
|
|
}
|
|
|
|
void CPICUploader::BootloaderDataAvailable()
|
|
{
|
|
|
|
QByteArray Data = mBootloaderSocket.readAll();
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Recevied %1 bytes from bootloader").arg(Data.size()));
|
|
mBootloaderProtocol.BooloaderProtocolRxFrame(Data);
|
|
|
|
}
|
|
|
|
void CPICUploader::BootloaderSocketError(QAbstractSocket::SocketError Error)
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Socket error %1 in PICUploader").arg(Error));
|
|
}
|
|
|
|
int CPICUploader::SendSingleCmdRequest(int CmdID)
|
|
{
|
|
QByteArray Frame = mBootloaderProtocol.BootloaderProtocolGetFrame(CmdID,QByteArray());
|
|
mBootloaderSocket.write(Frame);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CPICUploader::SendCmdRequest(int CmdID, QByteArray Data)
|
|
{
|
|
QByteArray Frame = mBootloaderProtocol.BootloaderProtocolGetFrame(CmdID,Data);
|
|
mBootloaderSocket.write(Frame);
|
|
return RET_OK;
|
|
}
|
|
|
|
int CPICUploader::GuiEvent(int EventID, void *Data)
|
|
{
|
|
switch(EventID)
|
|
{
|
|
case CPICUploaderGui::UPLOADER_GUI_HEARTBEAT_BTN_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_HEARTBEAT_REQUEST);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_FLASH_ERASE_BTN_CLICK_EVENT:
|
|
{
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_ERASE_FLASH_GUI_CMD);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_INIT_UPLOAD_BTN_CLICK_EVENT:
|
|
{
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_START_UPLOAD_GUI_CMD);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_SEND_DATA_CHUNK_BTN_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_SEND_DATA_CHUNK_REQUEST);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_UPLOAD_FINISHED_BTN_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_UPLOAD_FINISHED_REQUEST);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_EXECUTE_UPGRADE_BTN_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_EXECUTE_UPGRAGE_REQUEST);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_ABORT_BTN_CLICK_EVENT:
|
|
{
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_ABORT_GUI_CMD);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_AUTOMATIC_UPDATE_START_BTN_CLICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_GET_STATE_BTN_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_GET_STATE_REQUEST);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_CHECK_FLASH_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_REQUEST);
|
|
break;
|
|
}
|
|
case CPICUploaderGui::UPLOADER_GUI_GET_STORED_FIRMWARE_INFO_CLICK_EVENT:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_GET_STORED_FIRMWARE_INFO_REQUEST);
|
|
break;
|
|
}
|
|
}
|
|
return RET_OK;
|
|
}
|
|
|
|
int CPICUploader::BootloaderRxCmd(int CmdID, QByteArray Data)
|
|
{
|
|
switch(CmdID)
|
|
{
|
|
case BOOTLOADER_HEARTBEAT_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Heartbeat device response: %1").arg((int)Data.at(0)));
|
|
break;
|
|
}
|
|
case BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Erase flash device response: %1").arg((int)Data.at(0)));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_ERASE_BOOTLOADER_FLASH_ACK_HOST_CMD,Data.at(0));
|
|
break;
|
|
}
|
|
case BOOTLOADER_ERASE_BOOTLOADER_FLASH_RESULT_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Erase flash result device response: %1").arg((int)Data.at(0)));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_ERASE_BOOTLOADER_FLASH_RESULT_HOST_CMD,Data.at(0));
|
|
break;
|
|
}
|
|
case BOOTLOADER_INIT_UPLOAD_RESPONSE:
|
|
{
|
|
int ChunkSize;
|
|
quint32 temp = *(int*)Data.mid(1,4).data();
|
|
qToBigEndian(temp,&ChunkSize);
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Init Upload device response: %1, Chunk Size: %2").arg((int)Data.at(0)).arg(ChunkSize));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_INIT_UPLOAD_HOST_CMD,(int)Data.at(0),(void*)&ChunkSize);
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_GET_STATE_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Get State device Response: %1").arg((int)Data.at(0)));
|
|
break;
|
|
}
|
|
case BOOTLOADER_READY_FOR_DATA_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Ready for data device response: %1").arg((int)Data.at(0)));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_READY_FOR_DATA_HOST_CMD,(int)Data.at(0));
|
|
break;
|
|
}
|
|
case BOOTLOADER_SEND_DATA_CHUNK_RESPONSE:
|
|
{
|
|
quint32 temp = *(int*)Data.mid(1,4).data();
|
|
int Index;
|
|
qToBigEndian(temp,&Index);
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Send Chunk device response: %1, Index: %2").arg((int)Data.at(0)).arg(Index));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_SEND_DATA_CHUNK_HOST_CMD,(int)Data.at(0),(void*)&Index);
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_FINISHED_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload finished device response: %1").arg((int)Data.at(0)));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_UPLOAD_FINISHED_HOST_CMD,(int)Data.at(0));
|
|
break;
|
|
}
|
|
case BOOTLOADER_EXECUTE_UPGRADE_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Execute upgrade device response: %1").arg((int)Data.at(0)));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_EXECUTE_UPGRADE_HOST_CMD,(int)Data.at(0));
|
|
break;
|
|
}
|
|
case BOOTLOADER_ABORT_OPERATION_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Abort Operation device response: %1").arg((int)Data.at(0)));
|
|
BootloaderInterfaceStateMachine(BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT,BOOTLOADER_UPLOAD_ABORT_OPERATION_HOST_CMD,(int)Data.at(0));
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHECK_FLASH_FIRMW_INTEGRITY_RESPONSE:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Flash integrity check response: %1").arg((int)Data.at(0)));
|
|
break;
|
|
}
|
|
case BOOTLOADER_GET_STORED_FIRMWARE_INFO_RESPONSE:
|
|
{
|
|
QString FirmwareInfo;
|
|
FirmwareInfo.clear();
|
|
|
|
if(Data.at(0) == 0)
|
|
{
|
|
FirmwareInfo = "--------------------------------\nNo firmware stored in SPI flash\n--------------------------------";
|
|
}
|
|
else
|
|
{
|
|
quint32 FirmwareFlags, NbRecords, FirmwareSize, VersionCode, DataCRC32;
|
|
|
|
quint32 temp = *(int*)Data.mid(1,4).data();
|
|
qToBigEndian(temp,&FirmwareFlags);
|
|
|
|
temp = *(int*)Data.mid(5,4).data();
|
|
qToBigEndian(temp,&NbRecords);
|
|
|
|
temp = *(int*)Data.mid(9,4).data();
|
|
qToBigEndian(temp,&FirmwareSize);
|
|
|
|
temp = *(int*)Data.mid(13,4).data();
|
|
qToBigEndian(temp,&VersionCode);
|
|
|
|
temp = *(int*)Data.mid(17,4).data();
|
|
qToBigEndian(temp,&DataCRC32);
|
|
|
|
FirmwareInfo = QString("\n----------------------------------\nStored firmware info:\nFirmware flags: 0x%1\nNb Records: %2\nFirmware Size: %3\nVersion: %4\nData CRC32: 0x%5\n----------------------------------\n")\
|
|
.arg(FirmwareFlags,0,16).arg(NbRecords).arg(FirmwareSize).arg(VersionCode).arg(DataCRC32,0,16);
|
|
|
|
}
|
|
|
|
mPICUploaderGui->AddTextToLogScreen(FirmwareInfo);
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int CPICUploader::BootloaderInterfaceStateMachine(int Event, int Cmd, int CmdParam, void* Data)
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_BOOTLOADER_DISCONNECTED_CMD:
|
|
{
|
|
ResetBooloaderInterfaceStateMachine();
|
|
return RET_OK;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
// State machine implementation starts here...
|
|
|
|
switch (mBootloaderInterfaceSMState)
|
|
{
|
|
case BOOTLOADER_INTERFACE_SM_STANDBY_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_BOOTLOADER_CONNECTED_CMD:
|
|
{
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_BOOTLDR_CONNECTED_STATE;
|
|
mPICUploaderGui->AddTextToLogScreen("[BootloaderSM] Going into CONNECTED state\n");
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_INTERFACE_SM_BOOTLDR_CONNECTED_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_ERASE_FLASH_GUI_CMD:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_ERASE_BOOTLOADER_FLASH_REQUEST);
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_ERASE_FLASH_STATE;
|
|
mPICUploaderGui->AddTextToLogScreen("[BootloaderSM] Going into ERASE_FLASH state\n");
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_START_FULL_UPDATE_GUI_CMD:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_START_UPLOAD_GUI_CMD:
|
|
{
|
|
SendSingleCmdRequest(BOOTLOADER_INIT_UPLOAD_REQUEST);
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_INIT_UPLOAD_STATE;
|
|
mPICUploaderGui->AddTextToLogScreen("[BootloaderSM] Going into INIT_UPLOAD state\n");
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case BOOTLOADER_INTERFACE_SM_ERASE_FLASH_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_ERASE_BOOTLOADER_FLASH_ACK_HOST_CMD:
|
|
{
|
|
if(CmdParam != BOOTLOADER_FLASH_ERASE_OK)
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen("Flash erase refused from host. Going back to CONNECTED state\n");
|
|
}
|
|
else
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen("Device confirmed erasing flash in progress... \n");
|
|
}
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_ERASE_BOOTLOADER_FLASH_RESULT_HOST_CMD:
|
|
{
|
|
if(CmdParam != BOOTLOADER_FLASH_ERASE_OK)
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen("Flash erase failed. Going back to CONNECTED state\n");
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_BOOTLDR_CONNECTED_STATE;
|
|
}
|
|
else
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen("Flash erase success. \n");
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_BOOTLDR_CONNECTED_STATE;
|
|
mPICUploaderGui->AddTextToLogScreen("[BootloaderSM] Going into CONNECTED state\n");
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case BOOTLOADER_INTERFACE_SM_INIT_UPLOAD_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_INIT_UPLOAD_HOST_CMD:
|
|
{
|
|
if(CmdParam == BOOTLOADER_INIT_UPLOAD_SUCCESS)
|
|
{
|
|
//Host is in update mode. Load the buffer size and wait for "Ready for data" CMD (stay in the same state)
|
|
mFirmwareUploadBufferSize = *(int*)Data;
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Init upload accepted by host. Frame size: %1\n").arg(mFirmwareUploadBufferSize));
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_WAIT_READY_FOR_DATA_FROM_HOST_STATE;
|
|
mPICUploaderGui->AddTextToLogScreen("[BootloaderSM] Going into READY_FOR_DATA state\n");
|
|
}
|
|
else
|
|
{
|
|
//Something's wrong with the host. Abort upload...
|
|
//TODO: Make the GUI aware of this.
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Init upload refused. Error code: %1. Going back to STANDBY state\n").arg(CmdParam));
|
|
ResetBooloaderInterfaceStateMachine();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case BOOTLOADER_INTERFACE_SM_WAIT_READY_FOR_DATA_FROM_HOST_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_READY_FOR_DATA_HOST_CMD:
|
|
{
|
|
//Host is ready for data. Start the upload state machine
|
|
mPICUploaderGui->AddTextToLogScreen("Host ready for data. Starting upload\n");
|
|
BootloaderFirmwareUploadStateMachine(BOOTLOADER_FIRM_UPLD_CMD_EVENT,BOOTLOADER_FIRM_UPLD_INIT_UPLOAD_CMD);
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_SEND_DATA_STATE;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Invalid response from host received int <WAIT READY FOR DATA> state. Response Cmd received: %1. Going back to STANDBY state\n").arg(Cmd));
|
|
ResetBooloaderInterfaceStateMachine();
|
|
break;
|
|
}
|
|
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_INTERFACE_SM_SEND_DATA_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SEND_DATA_CHUNK_HOST_CMD:
|
|
{
|
|
int Res = BootloaderFirmwareUploadStateMachine(BOOTLOADER_FIRM_UPLD_CMD_EVENT,BOOTLOADER_FIRM_UPLD_CHUNK_RX_RESPONSE_CMD,CmdParam,*(int*)Data);
|
|
switch(Res)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_SENDING_RES:
|
|
{
|
|
//All is going well.
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_FINISHED_RES:
|
|
{
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_DATA_FINISHED_STATE;
|
|
mPICUploaderGui->AddTextToLogScreen("Bootloader upload state machine uploaded all firmware\n");
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_ERROR_RES:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_TIMEOUT_RES:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_ABORT_RES:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_OK_RES:
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case BOOTLOADER_INTERFACE_SM_DATA_FINISHED_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_UPLOAD_SM_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_SM_NEW_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_UPLOAD_BOOTLOADER_CONNECTED_CMD:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_UPLOAD_UPLOAD_FINISHED_HOST_CMD:
|
|
{
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_BOOTLDR_CONNECTED_STATE;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
|
|
return RET_OK;
|
|
}
|
|
|
|
//State machine managing firmware packets upload and errors
|
|
int CPICUploader::BootloaderFirmwareUploadStateMachine(int Event, int Cmd, int CmdResult, int CmdParam)
|
|
{
|
|
switch(mBootloaderFirmwareUpldState)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_STANDBY_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_INIT_UPLOAD_CMD:
|
|
{
|
|
//TODO: Send First chunk
|
|
bool Finished;
|
|
mFirmwareData = mHexFile.GetRawData();
|
|
SendCmdRequest(BOOTLOADER_SEND_DATA_CHUNK_REQUEST, GetCurDataChunk(Finished));
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload SM: Sending first frame (%1)\n").arg(mFirmwareUploadCurFrame));
|
|
int NbChunks = mFirmwareData.size() / mFirmwareUploadBufferSize;
|
|
mPICUploaderGui->SetUploadProgressSettings(NbChunks);
|
|
mPICUploaderGui->ResetProgressBar();
|
|
if(Finished)
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("That was the last chunk. Going into UPLOAD_FINISHED state\n"));
|
|
mBootloaderFirmwareUpldState = BOOTLOADER_FIRM_UPLD_FINISHED_STATE;
|
|
}
|
|
else
|
|
{
|
|
mBootloaderFirmwareUpldState = BOOTLOADER_FIRM_UPLD_SEND_CHUNK_STATE;
|
|
}
|
|
return BOOTLOADER_FIRM_UPLD_SENDING_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_ABORT_UPLOAD_CMD:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ABORT_RES;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
//TODO: Find out what to do with that...
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
// case BOOTLOADER_FIRM_UPLD_WAIT_FOR_HOST_READY_STATE:
|
|
// {
|
|
// switch(Event)
|
|
// {
|
|
// case BOOTLOADER_FIRM_UPLD_TICK_EVENT:
|
|
// {
|
|
// return BOOTLOADER_FIRM_UPLD_WAITING_FOR_HOST_RES;
|
|
// break;
|
|
// }
|
|
// case BOOTLOADER_FIRM_UPLD_CMD_EVENT:
|
|
// {
|
|
// switch(Cmd)
|
|
// {
|
|
// case BOOTLOADER_FIRM_UPLD_INIT_UPLOAD_ACK_CMD:
|
|
// {
|
|
// if(CmdResult == BOOTLOADER_INIT_UPLOAD_SUCCESS)
|
|
// {
|
|
// //Host is in update mode. Load the buffer size and wait for "Ready for data" CMD (stay in the same state)
|
|
// mFirmwareUploadBufferSize = CmdParam;
|
|
// return BOOTLOADER_FIRM_UPLD_WAITING_FOR_HOST_RES;
|
|
// }
|
|
// else
|
|
// {
|
|
// ResetFirmwareUploadStateMachine();
|
|
// return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
// }
|
|
// break;
|
|
// }
|
|
// case BOOTLOADER_FIRM_UPLD_HOST_READY_FOR_DATA_CMD:
|
|
// {
|
|
// //Host is ready for data. Send the first chunk and go into next state (send chunk)
|
|
// //TODO: Send first data chunk
|
|
// mBootloaderFirmwareUpldState = BOOTLOADER_FIRM_UPLD_SEND_CHUNK_STATE;
|
|
// return BOOTLOADER_FIRM_UPLD_SENDING_RES;
|
|
// break;
|
|
// }
|
|
// default:
|
|
// {
|
|
// return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
// break;
|
|
// }
|
|
// }
|
|
|
|
// break;
|
|
// }
|
|
|
|
// }
|
|
// break;
|
|
// }
|
|
case BOOTLOADER_FIRM_UPLD_SEND_CHUNK_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_CHUNK_RX_RESPONSE_CMD:
|
|
{
|
|
switch(CmdResult)
|
|
{
|
|
case BOOTLOADER_CHUNK_TRANSFER_SUCCESS:
|
|
{
|
|
if(mFirmwareUploadCurFrame == 700 || mFirmwareUploadCurFrame == 800 || mFirmwareUploadCurFrame == 900)
|
|
{
|
|
int toto = 5;
|
|
}
|
|
bool Finished = false;
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload SM: Sending frame Nb: %1\n").arg(mFirmwareUploadCurFrame));
|
|
mFirmwareUploadCurFrame++;
|
|
SendCmdRequest(BOOTLOADER_SEND_DATA_CHUNK_REQUEST, GetCurDataChunk(Finished));
|
|
mPICUploaderGui->TickProgressBar();
|
|
if(Finished)
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("That was the last chunk. Going into UPLOAD_FINISHED state\n"));
|
|
mBootloaderFirmwareUpldState = BOOTLOADER_FIRM_UPLD_FINISHED_STATE;
|
|
}
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_RESEND:
|
|
{
|
|
//TODO: Resend current frame
|
|
if(mFirmwareUploadCurFrame != CmdParam)
|
|
{
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload of frame %1 failed. and frame index desynchronized (Curframe = %2). Aborting and going to STANDBY mode\n").arg(CmdParam).arg(mFirmwareUploadCurFrame));
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
}
|
|
bool Finished;
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload of frame %1 failed. Trying to resend\n").arg(CmdParam));
|
|
SendCmdRequest(BOOTLOADER_SEND_DATA_CHUNK_REQUEST, GetCurDataChunk(Finished));
|
|
//TODO: Manage the number of failed attempts.
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_FAILURE:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_INVALID_CHUNK_INDEX:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_ERROR:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return BOOTLOADER_FIRM_UPLD_SENDING_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_ABORT_UPLOAD_CMD:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ABORT_RES;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_FINISHED_STATE:
|
|
{
|
|
switch(Event)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_TICK_EVENT:
|
|
{
|
|
break;
|
|
}
|
|
case BOOTLOADER_FIRM_UPLD_CMD_EVENT:
|
|
{
|
|
switch(Cmd)
|
|
{
|
|
case BOOTLOADER_FIRM_UPLD_CHUNK_RX_RESPONSE_CMD:
|
|
{switch(CmdResult)
|
|
{
|
|
case BOOTLOADER_CHUNK_TRANSFER_SUCCESS:
|
|
{
|
|
//TODO: Send upload finished CMD to host
|
|
|
|
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload of last frame success. Frame Nb %1\n").arg(CmdParam));
|
|
mPICUploaderGui->TickProgressBar();
|
|
|
|
return BOOTLOADER_FIRM_UPLD_FINISHED_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_RESEND:
|
|
{
|
|
//TODO: Resend current frame
|
|
if(mFirmwareUploadCurFrame != CmdParam)
|
|
{
|
|
//TODO: Manage this error... (Abort)
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
}
|
|
bool Finished;
|
|
mPICUploaderGui->AddTextToLogScreen(QString("Upload of frame %1 failed. Trying to resend\n").arg(CmdParam));
|
|
SendCmdRequest(BOOTLOADER_SEND_DATA_CHUNK_REQUEST, GetCurDataChunk(Finished));
|
|
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_FAILURE:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_INVALID_CHUNK_INDEX:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
case BOOTLOADER_CHUNK_TRANSFER_ERROR_FLASH_ERROR:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
return BOOTLOADER_FIRM_UPLD_ERROR_RES;
|
|
break;
|
|
}
|
|
}
|
|
ResetFirmwareUploadStateMachine();
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
ResetFirmwareUploadStateMachine();
|
|
break;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
return BOOTLOADER_FIRM_UPLD_OK_RES;
|
|
|
|
}
|
|
|
|
int CPICUploader::ResetBooloaderInterfaceStateMachine()
|
|
{
|
|
mBootloaderInterfaceSMState = BOOTLOADER_INTERFACE_SM_STANDBY_STATE;
|
|
mFirmwareUploadBufferSize = 0;
|
|
mFirmwareUploadCurFrame = 0;
|
|
ResetFirmwareUploadStateMachine();
|
|
return RET_OK;
|
|
}
|
|
|
|
int CPICUploader::ResetFirmwareUploadStateMachine()
|
|
{
|
|
mBootloaderFirmwareUpldState = BOOTLOADER_FIRM_UPLD_STANDBY_STATE;
|
|
mFirmwareData.clear();
|
|
return RET_OK;
|
|
}
|
|
|
|
//Sends current data chunk based on mFirmwareUploadCurFrame and mFirmwareUploadBufferSize.
|
|
QByteArray CPICUploader::GetCurDataChunk(bool &IsLastChunk)
|
|
{
|
|
QByteArray Chunk;
|
|
QByteArray Payload;
|
|
Chunk.clear();
|
|
|
|
unsigned int index = mFirmwareUploadCurFrame * mFirmwareUploadBufferSize;
|
|
if((index + mFirmwareUploadBufferSize) >= mFirmwareData.size())
|
|
{
|
|
IsLastChunk = true;
|
|
}
|
|
|
|
Payload = mFirmwareData.mid(index,mFirmwareUploadBufferSize);
|
|
|
|
Chunk.append(IntToByteArray(mFirmwareUploadCurFrame));
|
|
Chunk.append(IntToByteArray(Payload.size()));
|
|
Chunk.append(Payload);
|
|
|
|
return Chunk;
|
|
}
|
|
|
|
|
|
QByteArray CPICUploader::IntToByteArray(int data)
|
|
{
|
|
QByteArray Array;
|
|
unsigned char nibble = (char)((data >> 24) &0x000000FF);
|
|
Array.append(nibble);
|
|
|
|
nibble = (char)((data >> 16) &0x000000FF);
|
|
Array.append(nibble);
|
|
|
|
nibble = (char)((data >> 8) &0x000000FF);
|
|
Array.append(nibble);
|
|
|
|
nibble = (char)(data &0x000000FF);
|
|
Array.append(nibble);
|
|
|
|
return Array;
|
|
}
|