#include "hexfilereader.h"
#include <QDebug>
#include <QThread>
HexFileReader::HexFileReader(QObject *parent) : QObject(parent)
{
QThread *thread = new QThread();
this->moveToThread(thread);
thread->start();
}
int HexFileReader::burnProgram(QString comName, QString fileName)
{
int ret = -1;
ret = readFile(fileName);
if(ret != 0)
{
return -1;
}
QSerialPort serialPort;
serialPort.setPortName(comName);
serialPort.setBaudRate(115200);
serialPort.setDataBits(QSerialPort::Data8);
serialPort.setParity(QSerialPort::EvenParity);
serialPort.setStopBits(QSerialPort::OneStop);
if(serialPort.open(QSerialPort::ReadWrite) == false)
{
return -2;
}
enterBootLoader(&serialPort);
QThread::msleep(100);
uchar data[2] = {0x7f};
serialPort.write((char*)data, 1);
serialPort.waitForReadyRead();
QByteArray response = serialPort.readAll();
qDebug() << "response:" << response.toHex();
if(((uchar)response[0]) == NACK)
{
return -3;
}
eraseAll(&serialPort);
for(int i = 0; i < mDataList.length(); i++)
{
DataFrame df = mDataList[i];
int ret = writeData(&serialPort, df.addr, df.data);
qDebug() << "burn data:" << QString::number(df.addr, 16) << ret;
if(ret != 0)
{
return -4;
}
emit progressChanged(mDataList.length(), i + 1);
}
QThread::msleep(1000);
qDebug() << "进入正常模式";
enterFlash(&serialPort);
return 0;
}
int HexFileReader::readFile(QString filePath)
{
qDebug() << filePath;
mDataList.clear();
QFile file(filePath);
if(file.open(QFile::ReadOnly))
{
quint16 addrBase = 0x0000;
while (file.atEnd() == false) {
QString str = file.readLine().trimmed();
if(str == "")
{
continue;
}
DataFrame df;
int ret = decodeData(str, df);
if(ret != 0)
{
return ret;
}
if(df.type == 4)
{
addrBase = hexToUInt(df.data) & 0xffff;
continue;
}
if(df.type == 5)
{
addrBase = df.addr;
continue;
}
else if(df.type == 0)
{
df.addr += (((addrBase << 16) & 0xffffffff));
}
else if(df.type == 1)
{
continue;
}
mDataList.push_back(df);
}
}
return 0;
}
int HexFileReader::writeData(QSerialPort *port, quint32 addr, QByteArray data)
{
uchar header[] = {0x31, 0xce};
port->write((char*)header, 2);
port->waitForReadyRead();
QByteArray ret = port->readAll();
if(((uchar)ret[0]) == NACK)
{
return -1;
}
uchar addrArray[] = {(uchar)((addr >> 24) & 0xff),
(uchar)((addr >> 16) & 0xff),
(uchar)((addr >> 8) & 0xff),
(uchar)((addr >> 0) & 0xff)
};
QByteArray cmd((char*)addrArray, 4);
uchar checkSum = getXorSum(cmd);
cmd.append(checkSum);
port->write(cmd);
port->waitForReadyRead();
ret = port->readAll();
if(((uchar)ret[0]) == NACK)
{
return -2;
}
cmd.clear();
cmd.append(data.length() - 1);
cmd.append(data);
checkSum = getXorSum(cmd);
cmd.append(checkSum);
port->write(cmd);
port->waitForReadyRead();
ret = port->readAll();
if(((uchar)ret[0]) == NACK)
{
return -3;
}
return 0;
}
int HexFileReader::eraseAll(QSerialPort *port)
{
uchar header[] = {0x43, 0xbc};
port->write((char*)header, 2);
port->waitForReadyRead();
QByteArray ret = port->readAll();
if(((uchar)ret[0]) == NACK)
{
return -1;
}
uchar data[] = {0xff, 0x00};
port->write((char*)data, 2);
port->waitForReadyRead();
ret = port->readAll();
if(((uchar)ret[0]) == NACK)
{
return -2;
}
return 0;
}
void HexFileReader::enterBootLoader(QSerialPort *port)
{
port->setRequestToSend(true);
port->setDataTerminalReady(false);
QThread::msleep(100);
port->setDataTerminalReady(true);
}
void HexFileReader::enterFlash(QSerialPort *port)
{
port->setRequestToSend(true);
port->setDataTerminalReady(false);
port->setRequestToSend(false);
}
QList<DataFrame> &HexFileReader::dataList()
{
return mDataList;
}
quint16 HexFileReader::hexToUInt(QByteArray data)
{
return (uchar)data[0] << 8 | (uchar)data[1];
}
quint8 HexFileReader::getCheckSum(QByteArray data)
{
quint8 sum = data[0];
for(int i = 1; i < data.length(); i++)
{
sum += data[i];
}
sum = 0x100 - sum;
return sum;
}
quint8 HexFileReader::getXorSum(QByteArray data)
{
uchar checkSum = 0x00;
for(int i = 0; i < data.length(); i++)
{
checkSum ^= data[i];
}
return checkSum;
}
int HexFileReader::decodeData(QString dataStr, DataFrame &df)
{
dataStr = dataStr.replace(":", "");
auto hexData = QByteArray::fromHex(dataStr.toLatin1());
df.length = hexData[0];
if(hexData.length() != df.length + 5)
{
return -1;
}
df.addr = hexToUInt(hexData.mid(1, 2));
df.type = hexData[3];
df.data = hexData.mid(4, df.length);
df.checkSum = hexData[hexData.length() - 1];
if(df.checkSum != getCheckSum(hexData.left(hexData.length() - 1)))
{
return -2;
}
return 0;
}