UpdatePTUDevCtrl/DCPlugin/src/dcBL.cpp

1462 lines
41 KiB
C++

//#include <stdint.h>
#include "dcBL.h"
#include <QDebug>
//#include "tabFw.h"
#include "sendWRcmd.h"
// File sits "behind" the HWapi and in front of "PI", so all necessary Bootloader functions can be called from HWapi
uint16_t ucharTOuint(uint8_t Highbyte, uint8_t Lowbyte)
{
uint16_t uitmp;
uitmp=0;
uitmp |= uint8_t(Highbyte);
uitmp<<=8;
uitmp |= uint8_t(Lowbyte);
return uitmp;
}
#define GETLOWBYTE 0
#define GETHIGHBYTE 1
uint8_t uintTOuchar(uint16_t uival, uint8_t getHighB)
{
// getHighB: low=GetLowByte
uint16_t uitmp=uival;
if (getHighB==0)
return uint8_t(uitmp);
uitmp>>=8;
return uint8_t(uitmp);
}
//#define GETLOWBYTE 0
//#define GETHIGHBYTE 1
#define GETMIDLOWBYTE 2
#define GETMIDHIGHBYTE 3
uint8_t ulongTOuchar(uint32_t ulval, uint8_t whichByte)
{
uint32_t ultmp=ulval;
if (whichByte==GETLOWBYTE)
return uint8_t(ultmp);
ultmp>>=8;
if (whichByte==GETMIDLOWBYTE)
return uint8_t(ultmp);
ultmp>>=8;
if (whichByte==GETMIDHIGHBYTE)
return uint8_t(ultmp);
ultmp>>=8;
if (whichByte==GETHIGHBYTE)
return uint8_t(ultmp);
return 0;
}
void strclr(uint8_t *buf, uint8_t clrsign, uint8_t len)
{
uint16_t nn;
for (nn=0; nn<len; nn++)
buf[nn]=clrsign;
}
// -----------------------------------------------------------------------------------------------
// communication with this particular DeviceController's Bootloader ---------------------------------
// -----------------------------------------------------------------------------------------------
uint16_t dcBL_calcCrcCcitt(uint32_t BufLength, uint8_t *buf)
{
// CRC16 / CCITT-FALSE
uint8_t nn, B15H, element;
uint16_t crc = 0x84cf;
while (BufLength--)
{
element = *buf++;
for (nn = 0; nn < 8; nn++)
{
B15H = 0;
if(crc & 0x8000)
B15H = 1;
crc = (crc << 1) | ((element >> (7 - nn)) & 0x01);
if (B15H)
{
crc ^= 0x1021;
}
}
}
for (nn = 0; nn < 16; nn++)
{
B15H = 0;
if(crc & 0x8000)
B15H = 1;
crc = (crc << 1) | 0x00;
if (B15H)
{
crc ^= 0x1021;
}
}
return crc;
}
#define SEND_STX 2
#define SEND_ETX 3
#define SEND_ESC 0x1B
static uint8_t dcBL_LastBLcmd; // stored the last sent cmd in order to analys response
// cmd echo'ed: error cmd or'ed with 0x80: OK
uint8_t dcBL_prepareDC_BLcmd(uint8_t Cmd, uint8_t SendDataLength, uint8_t *sendData, uint8_t *outBuf)
{
// make BL protocol, retval = outbuf length (5...133)
// bring data in correct form: start always with 0x02 finish with 0x03 and append checksum
// 0x02 Cmd < ...sendData ..> CRC CRC 0x03
// Data length = 0...64
// special conversion: if data contain 2 or 3 (STX, ETX) then write two bytes: 0x1B (=ESC) and data|0x80
// so maxlength = 5 + 2 x 64 (if all data are 2 or 3) without 2,3: maxlength = 5 + 64
// 26.01.2021: noch einen Fehler gefunden: die "special conversion" fehlt bei der angehaengten Checksumme!!!
uint8_t myBuf[140], pp=0, HB, LB;
uint8_t crcBuf[140], mm=0;
uint8_t nn, uctmp, currLen=0;
uint16_t calcCrc;
strclr(myBuf, 0, 140);
strclr(crcBuf, 0, 140); // extra Puffer because STX must not be caculated
myBuf[pp++]=SEND_STX;
myBuf[pp++]=Cmd;
crcBuf[mm++]=Cmd;
dcBL_LastBLcmd=Cmd;
// append data:
for (nn=0; nn<SendDataLength; nn++)
{
uctmp=sendData[nn];
if (uctmp==SEND_STX || uctmp==SEND_ETX || uctmp==SEND_ESC) // ESC, STX or ETX in payload
{
myBuf[pp++]=SEND_ESC;
//crcBuf[mm++]=SEND_ESC; // so wäre die Berechnung NACH der Umwandlung, ist aber falsch
myBuf[pp++]=uctmp | 0x80;
//crcBuf[mm++]=uctmp | 0x80; // so wäre die Berechnung NACH der Umwandlung, ist aber falsch
crcBuf[mm++]=uctmp; // crc VOR umwandlung berechnen!
} else
{
myBuf[pp++]=uctmp;
crcBuf[mm++]=uctmp;
}
}
currLen=mm;
// calc crc: (over cmd and data, without STX)
//qDebug() << "calc crc: anzahl " <<mm;
//qDebug() << crcBuf;
calcCrc=dcBL_calcCrcCcitt(uint32_t(currLen), crcBuf);
//qDebug() << calcCrc;
// myBuf[pp++]=uintTOuchar(calcCrc, GETHIGHBYTE);
// myBuf[pp++]=uintTOuchar(calcCrc, GETLOWBYTE);
// myBuf[pp++]=SEND_ETX;
// 26.01.2021: die "special conversion" auch für die angehaengte Checksumme:
HB=uintTOuchar(calcCrc, GETHIGHBYTE);
LB=uintTOuchar(calcCrc, GETLOWBYTE);
uctmp=HB;
if (uctmp==SEND_STX || uctmp==SEND_ETX || uctmp==SEND_ESC) // ESC, STX or ETX in payload
{
myBuf[pp++]=SEND_ESC;
myBuf[pp++]=uctmp | 0x80;
crcBuf[mm++]=uctmp;
} else
{
myBuf[pp++]=uctmp;
crcBuf[mm++]=uctmp;
}
uctmp=LB;
if (uctmp==SEND_STX || uctmp==SEND_ETX || uctmp==SEND_ESC) // ESC, STX or ETX in payload
{
myBuf[pp++]=SEND_ESC;
myBuf[pp++]=uctmp | 0x80;
crcBuf[mm++]=uctmp;
} else
{
myBuf[pp++]=uctmp;
crcBuf[mm++]=uctmp;
}
myBuf[pp++]=SEND_ETX;
currLen=pp;
for (nn=0; nn<currLen; nn++)
outBuf[nn]=myBuf[nn];
if (outBuf[currLen-1] !=3)
{
qDebug()<<"protocol error no ETX, len="<< currLen << " data: " << myBuf;
}
return currLen;
}
// some special commands (right out of bootloader manual)
uint8_t dcBL_readBLversion(uint8_t *sendData)
{
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
strclr(myBuf, 0, 2);
return dcBL_prepareDC_BLcmd(0x11, 0, myBuf, sendData);
}
uint8_t dcBL_readFWversion(uint8_t *sendData)
{
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
strclr(myBuf, 0, 2);
return dcBL_prepareDC_BLcmd(0x12, 0, myBuf, sendData);
}
uint8_t dcBL_exitBL(uint8_t *sendData)
{
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
strclr(myBuf, 0, 2);
return dcBL_prepareDC_BLcmd(0x18, 0, myBuf, sendData);
}
uint8_t dcBL_sendFlashStartAddr2BL(uint32_t startAddr, uint8_t *sendData)
{
// minimum size of sendData-buffer: 13byte retval: length (9...13)
uint8_t myBuf[5];
myBuf[0]=ulongTOuchar(startAddr, GETHIGHBYTE);
myBuf[1]=ulongTOuchar(startAddr, GETMIDHIGHBYTE);
myBuf[2]=ulongTOuchar(startAddr, GETMIDLOWBYTE);
myBuf[3]=ulongTOuchar(startAddr, GETLOWBYTE);
myBuf[4]=0;
return dcBL_prepareDC_BLcmd(0x21, 4, myBuf, sendData);
}
uint8_t dcBL_writeLastPage(uint8_t *sendData)
{
// return the necessary command to tell the BL "finish writing" =write last page even if not full
// minimum size of sendData-buffer: 5byte retval: length
uint8_t myBuf[2];
strclr(myBuf, 0, 2);
return dcBL_prepareDC_BLcmd(0x22, 0, myBuf, sendData);
}
uint8_t dcBL_restartDC(uint8_t *sendData)
{
// minimum size of sendData-buffer: 20 byte retval: length
// send this data block in decimal: 2 81 67 34 85 91 45 52 66 77 88 210 211 3
uint8_t nn=0;
sendData[nn++]=2;
sendData[nn++]=81;
sendData[nn++]=67;
sendData[nn++]=34;
sendData[nn++]=85;
sendData[nn++]=91;
sendData[nn++]=45;
sendData[nn++]=52;
sendData[nn++]=66;
sendData[nn++]=77;
sendData[nn++]=88;
sendData[nn++]=210;
sendData[nn++]=211;
sendData[nn++]=3;
sendData[nn++]=0;
sendData[nn++]=0;
return nn;
}
uint8_t dcBL_activatBootloader(uint8_t *sendData)
{
// minimum size of sendData-buffer: 20 byte retval: length
uint8_t nn=0;
//sendData[nn++]='U'; nötig??
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]=2;
sendData[nn++]='c';
sendData[nn++]='4';
sendData[nn++]='5';
sendData[nn++]='b';
sendData[nn++]='3';
sendData[nn++]=3;
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]='U';
sendData[nn++]=0;
return nn;
}
// -----------------------------------------------------------------------------------------------
uint8_t dcBL_getResponse(uint8_t *respBuff, bool display)
{
// retval: nr of received bytes
uint8_t recLen=epi_getRawRecLength();
if (recLen>0 && recLen<150)
{
epi_getRawReceivedData(respBuff);
epi_clrRawReceivedString();
dcBL_writeText("dcBL gotResponse");
if (display)
{
/*
// Antwort ins Fenster schreiben:
QString tmpStr="", myStr="~~> ";
tmpStr.setNum(recLen);
myStr.append(tmpStr);
myStr.append(" bytes received: ");
for (int nn=0; nn<recLen; nn++)
{
tmpStr.clear();
tmpStr.setNum(respBuff[nn]);
myStr.append(tmpStr);
myStr.append(" ");
}
dcBL_writeText(myStr);
*/
}
}
return recLen;
}
#define noReceive 0
#define ISWRONG 1
#define ISOK 10
uint8_t dcBL_ChkResponse()
{
// retval: 0: no response (by now)
// 1...5: Error, repeat
// 10: OK, next...
uint8_t buf[152], recLen;
//uint8_t exactError;
//QString tmpStr="";
//exactError=0;
recLen=dcBL_getResponse(buf,0);
if (recLen==0)
return 0; // no response by now
//qDebug()<<" DCBL_chkResp got answer " << recLen ;
//dcBL_writeText("DCBL_chkResp got answer");
if (buf[0]==2 && buf[1]==(dcBL_LastBLcmd | 0x80) )
return 10; // OK
// 27.01.21: Problem aufgetaucht: Fehler nur bei CRC melden
// -> block wiederholen. In den anderen Fällen NICHT wiederholen
// sonst ist der block doppelt im Flash!!!!!!!!
if (recLen>0 && recLen<5)
{
dcBL_writeText("error wrong length");
//exactError=1;
qDebug()<<" DCBL_chkResp wrong length ";
return 10; // OK
}
if (buf[0] !=2)
{
dcBL_writeText("error wrong start");
//exactError=2;
qDebug()<<" DCBL_chkResp wrong start ";
return 10; // OK
}
if (buf[0]==2 && buf[1]=='e' && buf[2]=='0' )
{
dcBL_writeText("error wrong crc");
//exactError=3; // DC reports wrong crc
qDebug()<<" DCBL_chkResp wrong crc";
return 1; // error
}
if (buf[0]==2 && buf[1]==dcBL_LastBLcmd )
{
dcBL_writeText("error wrong cmd");
//exactError=4; // wrong cmd
qDebug()<<" DCBL_chkResp wrong cmd";
return 10; // OK
}
//tmpStr.clear();
//tmpStr.setNum(exactError);
//dcBL_writeText(tmpStr);
return 1; // error
}
uint8_t dcBL_sendSuccess(uint8_t lastCommand)
{
// return val: 0: no response by now 1:error 10: OK
uint8_t buf[152], recLen;
recLen=dcBL_getResponse(buf,0);
if (recLen==0)
return 0; // no response by now
if (buf[0]==2 && buf[1]==(lastCommand | 0x80) )
return 10; // OK
return 1;
}
// -----------------------------------------------------------------------------------------------
// --- ATB Bin-File Handling ---------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
/* example read file from HDD:
uint8_t uit8tmp;
QString stemp=" ";
QFile file("/own/H2B/dc2.bin");
//QFile file("/own/H2B/dc2.hex"); // laesst sich genauso oeffnen
// TODO: use File-Open-Dialog-Box
if (!file.exists())
{
qDebug()<<"file not exists";
} else
{
if (!file.open(QIODevice::ReadOnly) )
{
qDebug()<<"cannot open";
} else
{
qDebug()<<"loading....";
qDebug()<<"size: " << file.size() <<"\n";
QByteArray myBin = file.readAll();
// Kontrolle:
int ii=0;
do
{
uit8tmp=(uint8_t)myBin[ii++];
//qDebug() << uit8tmp << " "; // Anzeige in dez
stemp.setNum(uit8tmp,16);
qDebug() << stemp << " "; // Anzeige in hex
} while (ii<100);
}
}
*/
// -------------------------------------------------------------------------
char dcBL_loadBinary(char withDisplay)
{
// same function as in "tabFw"
//uint8_t uit8tmp;
uint32_t ultmp, fileLen;
QString tmpStr="", s2tmp="";
qDebug()<<"dcBL loading DC2c binary...";
QFile file("../dc2c4.bin");
if (!file.exists())
{
//qDebug()<<"file _own_H2B_dc2.bin does not exist";
dcBL_writeText("file _own_H2B_dc2.bin does not exist");
return 1;
}
if (!file.open(QIODevice::ReadOnly) )
{
//qDebug()<<"cannot open";
dcBL_writeText("cannot open");
return 1;
}
//qDebug()<<"loading....";
//qDebug()<<"size: " << file.size() <<"\n";
if (withDisplay)
{
s2tmp="loading file with ";
tmpStr.setNum(file.size());
s2tmp.append(tmpStr);
s2tmp.append(" bytes");
dcBL_writeText(s2tmp);
}
QByteArray myBin = file.readAll();
fileLen=uint32_t(file.size());
// Rest des Blockes mit 0xFF füllen
for (ultmp=fileLen; ultmp<(fileLen+70); ultmp++)
myBin[ultmp]=char(0xFF);
/* // Kontrolle:
qDebug()<<"dcBL_loadBinary: ";
int ii=59500;
do
{
uit8tmp=uint8_t(myBin[ii++]);
s2tmp.clear();
//qDebug() << uit8tmp << " "; // Anzeige in dez
s2tmp.setNum(uit8tmp,16);
qDebug() << s2tmp << " "; // Anzeige in hex
} while (ii<60100);
*/
dcBL_importBinFile(myBin, fileLen, withDisplay);
return 0;
}
static QByteArray dcBL_AtbBinFile;
static uint32_t dcBL_fileSize;
static uint16_t dcBL_nrOfBlocks;
static uint16_t dcBL_fileCrc;
//static uint8_t dcBL_myBuf[2570000]; // same content like "dcBL_AtbBinFile" but bytewise
static uint8_t dcBL_myBuf[300000]; // same content like "dcBL_AtbBinFile" but bytewise
bool dcBL_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl)
{
uint16_t uitmp;
uint32_t ultmp;
uint32_t LL;
QString tmpStr="", s2tmp="";
dcBL_AtbBinFile=readBinFile;
dcBL_fileSize=fileSize;
//if (dcBL_fileSize>258048) // 27.3.23TS woher kommt die Zahl???
// das hex file hat 278kB
// hex file nicht erlaubt???
if (dcBL_fileSize>=300000)
return false; // keep last file
ultmp=dcBL_fileSize;
ultmp %=64;
uitmp=uint16_t(ultmp);
ultmp=dcBL_fileSize;
ultmp /=64;
dcBL_nrOfBlocks=uint16_t(ultmp);
if (uitmp>0)
dcBL_nrOfBlocks++; // letzter Block hat !=64 byte
// type conversion for crc calc
for (LL=0; LL<dcBL_fileSize; LL++)
dcBL_myBuf[LL]=uint8_t(dcBL_AtbBinFile[LL]);
dcBL_fileCrc=dcBL_calcCrcCcitt(LL, dcBL_myBuf);
// dcBL_writeText("file crc calculated successful");
if (withDispl)
{
s2tmp="crc: ";
tmpStr.setNum(dcBL_fileCrc,16);
s2tmp.append(tmpStr);
dcBL_writeText(s2tmp);
tmpStr.clear();
s2tmp="blocks: ";
tmpStr.setNum(dcBL_nrOfBlocks,10);
s2tmp.append(tmpStr);
dcBL_writeText(s2tmp);
tmpStr.clear();
s2tmp="last block size: ";
tmpStr.setNum(uitmp,10);
s2tmp.append(tmpStr);
dcBL_writeText(s2tmp);
}
return true;
// erstmal nicht wie bisher um 14 Bytes nach oben schieben und Laenge/crc anhaengen,
// weil man sonst den BL und das Win-tool auch aendern muesste
}
char dcBL_loadBinSafe(void)
{
// retval: true: file = OK
// Problem: nach der BL Programmierung ist das flash sehr oft defekt (ganze Bereiche sind falsch)
// die Übertragung ist CRC geschüzt, also bleibt die Vermutung das es am Einlesen des binfiles liegt.
// --->also sicherstellen dass das Laden des Binfiles 100%ig in Ordnung ist.
QByteArray BINFILECOPY1, BINFILECOPY2, BINFILECOPY3;
uint32_t BinFileCpyLen1, BinFileCpyLen2, BinFileCpyLen3, LL;
uint8_t repeat=0, nn=0, stopp=0;
//char cc;
do
{
//dcBL_writeText("loading 1st time:");
//qDebug() <<"loading 1st time:";
dcBL_loadBinary(0);
// file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize"
BINFILECOPY1=dcBL_AtbBinFile;
BinFileCpyLen1=dcBL_fileSize;
//dcBL_writeText("loading 2nd time:");
//qDebug() <<"loading 2. time:";
dcBL_loadBinary(0);
// file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize"
BINFILECOPY2=dcBL_AtbBinFile;
BinFileCpyLen2=dcBL_fileSize;
//dcBL_writeText("loading 3rd time:");
//qDebug() <<"loading 3. time:";
dcBL_loadBinary(0);
// file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize"
BINFILECOPY3=dcBL_AtbBinFile;
BinFileCpyLen3=dcBL_fileSize;
//cc=BINFILECOPY2[100];
//if (cc>0)
// BINFILECOPY2[100]=0;
//else
// BINFILECOPY2[100]=1;
repeat=0;
if (BinFileCpyLen1 !=BinFileCpyLen2 || BinFileCpyLen1 !=BinFileCpyLen3)
{
dcBL_writeText("file length wrong");
qDebug() <<"length error";
repeat=1; // load both again....
}
if (repeat==0)
{
LL=0; stopp=0;
//qDebug() <<"1. loop";
do
{
if (dcBL_AtbBinFile[LL] != BINFILECOPY1[LL])
stopp=1;
} while((++LL < dcBL_fileSize) && !stopp);
if (stopp)
{
dcBL_writeText("file compare1 wrong ");
repeat=1; // load both again....
}
}
if (repeat==0)
{
LL=0; stopp=0;
//qDebug() <<"2. loop";
do
{
if (dcBL_AtbBinFile[LL] != BINFILECOPY2[LL])
stopp=1;
} while((++LL < dcBL_fileSize) && !stopp);
if (stopp)
{
dcBL_writeText("file compare2 wrong ");
repeat=1; // load both again....
} else
dcBL_writeText("file OK");
}
} while (++nn<3 && repeat); // 3 trials
qDebug() << "compare finito " << nn << " " << repeat;
if (repeat==0)
return true; // file OK
return false; // error, could not load correctly
}
uint8_t dcBL_getAtbFileHeader(uint8_t *buf)
{
// this header is prepended by the pc-direct-loader-tool
// (so the uC-BL expects this!) here it is sent seperately:
uint8_t myBuf[30], pp=0, len;
myBuf[pp++]='A';
myBuf[pp++]='T';
myBuf[pp++]='B';
myBuf[pp++]='-';
myBuf[pp++]='D';
myBuf[pp++]='C';
myBuf[pp++]='2';
myBuf[pp++]='-';
myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETHIGHBYTE);
myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETMIDHIGHBYTE);
myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETMIDLOWBYTE);
myBuf[pp++]=ulongTOuchar(dcBL_fileSize, GETLOWBYTE);
myBuf[pp++]='-';
myBuf[pp++]=uintTOuchar(dcBL_fileCrc, GETHIGHBYTE);
myBuf[pp++]=uintTOuchar(dcBL_fileCrc, GETLOWBYTE);
myBuf[pp++]='-';
len=pp;
//tslib_strcpy(myBuf, buf, (len+3));
len=dcBL_prepareDC_BLcmd(0x32, len, myBuf, buf);
return len;
}
uint8_t dcBL_getFileBlock(uint16_t blockPointer, uint8_t *buf)
{
// blockPointer=0....4095
uint32_t addr, LL; //, BL;
//uint8_t uit8tmp;
//QString stemp=" ";
addr=uint32_t(blockPointer);
addr<<=6; // *64 =Start address
/*
if ( (addr+63)>dcBL_fileSize)
{
BL=dcBL_fileSize-addr+1; // Block Length
for (LL=0; LL<64; LL++)
buf[LL]=0;
if (BL>64) BL=64; // security limitation
// only BL bytes are left to give
for (LL=0; LL<BL; LL++)
{
buf[LL]=uint8_t(dcBL_AtbBinFile[LL+addr]);
// buf[LL]=dcBL_myBuf[LL+addr];
}
return uint8_t(BL);
} else
*/
{
// all 64bytes can be read:
for (LL=0; LL<64; LL++)
{
buf[LL]=uint8_t(dcBL_AtbBinFile[LL+addr]);
//buf[LL]=dcBL_myBuf[LL+addr];
}
/*
// Kontrolle:
qDebug()<<"dcBL getFileBlock myBuf: ";
int ii=0;
do
{
uit8tmp=(uint8_t)dcBL_myBuf[ii++];
//qDebug() << uit8tmp << " "; // Anzeige in dez
stemp.setNum(uit8tmp,16);
qDebug() << stemp << " "; // Anzeige in hex
} while (ii<64);
qDebug()<<"dcBL getFileBlock myBuf: ";
ii=0;
do
{
uit8tmp=(uint8_t)buf[ii++];
//qDebug() << uit8tmp << " "; // Anzeige in dez
stemp.setNum(uit8tmp,16);
qDebug() << stemp << " "; // Anzeige in hex
} while (ii<64);
*/
return 64;
}
//return 0;
}
// -----------------------------------------------------------------------------------------------
// -- fully automatic programmimg chain ------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
// use modules above and this functions from PI:
// sendWRcmd_setSendBlock160(len, buf);
// epi_getRawRecLength();
// epi_getRawReceivedData(receivedData);
// this lines shall be displayed in tabFW / FW_responseWindow
// they are read every 100ms. Make batch for 10 lines
#define SIZEBLRESP 50
static QString BlResp[SIZEBLRESP];
static int pBlResp;
bool dcBL_isTextMemFree(void)
{
if (pBlResp<0) pBlResp=0; // just for security
if (pBlResp<(SIZEBLRESP-1))
return true;
return false;
}
void dcBL_writeText(QString newTxt)
{
// write text her in this file from memory 1....9, mem 0 is always free
if (dcBL_isTextMemFree())
BlResp[++pBlResp]=newTxt;
}
bool dcBL_checkForText(void)
{
// if pointer at 0 then no more content
if (pBlResp>0)
return true;
return false;
}
QString dcBL_readText(void)
{
// read from 0...9 (oldest first)
if (pBlResp<=0) // should never be <0
return "";
QString locStr=BlResp[1]; // store memory[1]
// move memories down by one: 2->1 3->2 4>3....9->8. Place 1 is free now
// example: if pBlResp==3 then we have still text 2 and 3 to display. 1 will be transfered now with this call
int nn;
for (nn=1; nn<pBlResp; nn++)
BlResp[nn]=BlResp[nn+1];
if (pBlResp>0) pBlResp--;
return locStr;
}
// -------------------------------------------------------------------------
static uint8_t dcBL_step, dcBL_state;
static uint16_t dcBL_BlkCtr, dcBL_cyclCtr, repeatCtr;
void dcBL_iniChain(void)
{
int nn;
dcBL_step=0;
dcBL_cyclCtr=0;
dcBL_state=0;
dcBL_BlkCtr=0;
repeatCtr=0;
// delete output window:
pBlResp=0;
for (nn=0;nn<SIZEBLRESP; nn++)
BlResp[nn]="";
//dcBL_writeText("**CLEAR**");
dcBL_writeText("bl chain ini");
}
uint8_t dcBL_startChain(void)
{
if (dcBL_step==0 || dcBL_step>17)
{
dcBL_iniChain();
dcBL_step=1;
//epi_clrRawReceivedString();
qDebug()<<"starting chain...";
//qDebug()<<pBlResp;
dcBL_writeText("bl chain start");
}
return 0;
}
uint8_t dcBL_runChain(void)
{
// starting BL
// request BL-version (to be sure it's working)
// send start address
// send bin-file
// check all responses
// display result
// close BL
// sequencer, triggered by 100ms timer from mainwindow over TabFw::updateGui
QString tmpStr="";
uint8_t buf[70], sendBuf[160], len, sendLen, gotResp, ii, uit8tmp;
//static uint8_t lastBlkLength;
QString stemp=" ";
uint32_t ultmp;
bool ret;
//uint8_t recLen, recBuff[160], ;
gotResp=dcBL_ChkResponse(); //zum test hier raus, unten gehts nicht, darf nur 1x
switch (dcBL_step)
{
case 1: // tell DC-app to restart
dcBL_writeText("loading binary..");
ret=dcBL_loadBinSafe();
if (ret)
dcBL_step++;
else
{
dcBL_writeText("cancel, cannot load binary!");
dcBL_step=0;
}
break;
case 2:
dcBL_writeText("sending restart...");
len=dcBL_restartDC(buf);
sendWRcmd_setSendBlock160(len, buf);
dcBL_step++;
break;
case 3: // wait 100ms more
dcBL_step++;
break;
case 4: // start BL
dcBL_writeText("sending BL start...");
len=dcBL_activatBootloader(buf);
sendWRcmd_setSendBlock160(5, buf);
dcBL_step++;
dcBL_cyclCtr=0;
break;
case 5: // wait for answer: 2 99 52 53 98 51 3
// Problem: kommt von app, nicht vom BL. Also wenn BL schon aktiv ist dann gehts nicht
/*
dcBL_cyclCtr++;
if (recLen>6 && recBuff[0]==2 && recBuff[1]==99 && recBuff[2]==52)
// && recBuff[3]==53 && recBuff[4]==98 && recBuff[5]==51 && recBuff[6]==3 )
{
dcBL_writeText("BL started");
dcBL_cyclCtr=0;
dcBL_step++;
return 0;
}
//qDebug()<<dcBL_cyclCtr;
if (dcBL_cyclCtr>10) // 50 gibt 6,2s
{
// cancel, report error
dcBL_writeText("cannot start BL, cancel");
dcBL_state=3;
dcBL_step=0; // stop chain
return 0;
} */
dcBL_step++;
repeatCtr=0;
break;
case 6: // request Version number
len=dcBL_readFWversion(buf);
sendWRcmd_setSendBlock160(len, buf);
dcBL_writeText("request version nr...");
dcBL_cyclCtr=0;
dcBL_step++;
break;
case 7: // wait for answer 2 146 45 45 95 176 3
if (gotResp==ISOK)
{
dcBL_state=1; // BL started
dcBL_step++;
repeatCtr=0;
return 0;
} else
if (gotResp==ISWRONG)
{
if (++repeatCtr<3)
{
dcBL_step--;
}else
{
dcBL_step=0; // stop chain
}
}
if (++dcBL_cyclCtr>10)
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
case 8: // send start address
if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096)
{
ultmp=uint32_t(dcBL_BlkCtr);
ultmp*=64;
len=dcBL_sendFlashStartAddr2BL(ultmp, buf);
sendWRcmd_setSendBlock160(len, buf);
dcBL_writeText("sending start address");
dcBL_cyclCtr=0;
dcBL_step++;
return 0;
} else
dcBL_step=12;
break;
case 9: // wait for answer 2 161 68 59 3
if (gotResp==ISOK)
{
dcBL_step=12; // Header nicht senden, unnötig
dcBL_BlkCtr=0; // 0
repeatCtr=0;
return 0;
} else
if (gotResp==ISWRONG)
{
if (++repeatCtr<3)
{
dcBL_step--;
} else
{
dcBL_step=0; // stop chain
}
}
if (++dcBL_cyclCtr>10)
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
case 12: // send binary 64 byte wise
len=dcBL_getFileBlock(dcBL_BlkCtr, buf); // read from file, len = 0...64
//lastBlkLength=len; // recognize last block or end
sendLen=dcBL_prepareDC_BLcmd(0x22, len, buf, sendBuf); // pack into protocol frame
// Kontrolle:
qDebug()<<"dcBL sending: ";
ii=0;
do
{
uit8tmp=(uint8_t)sendBuf[ii++];
//qDebug() << uit8tmp << " "; // Anzeige in dez
stemp.setNum(uit8tmp,16);
qDebug() << stemp << " "; // Anzeige in hex
} while (ii<100);
sendWRcmd_setSendBlock160(sendLen, sendBuf); // send 140 bytes
delay(100);
//dcBL_writeText("blk nr: ");
tmpStr.setNum(dcBL_BlkCtr);
dcBL_writeText(tmpStr);
delay(100);
//qDebug()<<"sending: " << buf;
dcBL_cyclCtr=0;
dcBL_BlkCtr++;
dcBL_step++;
break;
case 13: // wait for answer 2 162 116 88 3
if (gotResp==ISOK)
{
// check if next address is needed (every 1024Blocks = 65536bytes)
if (dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096)
{
dcBL_step=8;
return 0;
}
// check for EOF:
if (dcBL_BlkCtr >= dcBL_nrOfBlocks)
{
dcBL_writeText("last block successful sent...");
dcBL_step++; // stop chain
dcBL_state=3; // transmission SUCCESSFUL
return 0;
}
dcBL_state=2; // transmission started
dcBL_step--; // send next data block
repeatCtr=0;
return 0;
}
if (gotResp==ISWRONG)
{
if (++repeatCtr<3)
{
dcBL_writeText("error");
dcBL_BlkCtr--;
dcBL_step--; // send same block again
} else
{
dcBL_step=0; // stop chain
}
}
if (++dcBL_cyclCtr>30) // longer TO due to flashing
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
case 14: //
dcBL_writeText("finish writing flash");
len=dcBL_writeLastPage(buf); // nur zur Sicherheit
sendWRcmd_setSendBlock160(len, buf);
dcBL_step++;
break;
case 15: // wait for answer
if (gotResp==ISOK)
{
dcBL_step++;
repeatCtr=0;
return 0;
} else
if (gotResp==ISWRONG)
{
if (++repeatCtr>3)
{
dcBL_step--;
}
}
if (++dcBL_cyclCtr>10)
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
case 16: //
dcBL_writeText("exit BL, bye");
len=dcBL_exitBL(buf);
sendWRcmd_setSendBlock160(len, buf);
dcBL_step++;
break;
case 17: // wait for answer, not sure if it comes!
if (gotResp==ISOK)
{
dcBL_step++;
repeatCtr=0;
return 0;
} else
if (gotResp==ISWRONG)
{
if (++repeatCtr>10)
{
dcBL_step--;
}
}
if (++dcBL_cyclCtr>30)
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
case 18:
dcBL_step=0;
break;
}
return 0;
}
void dcBL_iniLoading(void)
{
dcBL_iniChain();
}
// nicht verwendet
void dcBL_startLoading(void)
{
if (dcBL_step==0 || dcBL_step>17)
{
//dcBL_iniChain();
dcBL_step=1;
//epi_clrRawReceivedString();
qDebug()<<"DCBL start sending hexfile...";
dcBL_writeText("DCBL start sending hexfile...");
dcBL_BlkCtr=0;
dcBL_cyclCtr=0;
}
}
// nicht verwendet
uint8_t dcBL_sendHexfile(void)
{
QString tmpStr="";
uint8_t buf[70], sendBuf[160], len, sendLen, gotResp; //, recLen; recBuff[160], ii,
QString stemp=" ";
uint32_t ultmp;
//uint8_t uit8tmp, ii;
gotResp=dcBL_ChkResponse();
switch (dcBL_step)
{
case 1: // send start address
if (dcBL_BlkCtr==0 || dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096)
{
ultmp=uint32_t(dcBL_BlkCtr);
ultmp*=64;
len=dcBL_sendFlashStartAddr2BL(ultmp, buf);
sendWRcmd_setSendBlock160(len, buf);
qDebug()<<" DCBL_CYCL_sending HexFile address ";
dcBL_writeText("sending addr");
dcBL_step++;
return 0;
} else
dcBL_step=12;
break;
case 2: // wait for answer 2 161 68 59 3
if (gotResp==ISOK)
{
dcBL_step=12; // Header nicht senden, unnötig
dcBL_BlkCtr=0; // 0
repeatCtr=0;
return 0;
} else
if (gotResp==ISWRONG)
{
if (++repeatCtr<3)
{
dcBL_step--;
} else
{
dcBL_step=0; // stop chain
qDebug()<<" DCBL_CYCL_got wrong resp to addr";
dcBL_writeText("wrong resp");
}
}
if (++dcBL_cyclCtr>100)
{
dcBL_writeText("cancel");
qDebug()<<" DCBL_CYCL_step 2 got NO resp to addr";
dcBL_step=0; // stop chain
}
break;
case 12: // send binary 64 byte wise
len=dcBL_getFileBlock(dcBL_BlkCtr, buf); // read from file, len = 0...64
//lastBlkLength=len; // recognize last block or end
sendLen=dcBL_prepareDC_BLcmd(0x22, len, buf, sendBuf); // pack into protocol frame
/*
// Kontrolle:
qDebug()<<"dcBL sending: ";
ii=0;
do
{
uit8tmp=(uint8_t)sendBuf[ii++];
//qDebug() << uit8tmp << " "; // Anzeige in dez
stemp.setNum(uit8tmp,16);
qDebug() << stemp << " "; // Anzeige in hex
} while (ii<100);
*/
sendWRcmd_setSendBlock160(sendLen, sendBuf); // send 140 bytes
delay(100);
dcBL_writeText("blk nr: ");
tmpStr.setNum(dcBL_BlkCtr);
dcBL_writeText(tmpStr);
delay(100);
qDebug()<<"DCBL sending blk nr: " << dcBL_BlkCtr;
dcBL_cyclCtr=0;
dcBL_BlkCtr++;
dcBL_step++;
break;
case 13: // wait for answer 2 162 116 88 3
if (gotResp==ISOK)
{
// check if next address is needed (every 1024Blocks = 65536bytes)
if (dcBL_BlkCtr==1024 || dcBL_BlkCtr==2048 || dcBL_BlkCtr==3072 || dcBL_BlkCtr==4096)
{
dcBL_step=8;
return 0;
}
// check for EOF:
if (dcBL_BlkCtr >= dcBL_nrOfBlocks)
{
dcBL_writeText("last block successful sent...");
dcBL_step++; // stop chain
dcBL_state=3; // transmission SUCCESSFUL
return 0;
}
dcBL_state=2; // transmission started
dcBL_step--; // send next data block
repeatCtr=0;
return 0;
}
if (gotResp==ISWRONG)
{
if (++repeatCtr<3)
{
dcBL_writeText("error");
dcBL_BlkCtr--;
dcBL_step--; // send same block again
} else
{
dcBL_step=0; // stop chain
}
}
if (++dcBL_cyclCtr>30) // longer TO due to flashing
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
case 14: //
dcBL_writeText("finish writing flash");
len=dcBL_writeLastPage(buf); // nur zur Sicherheit
sendWRcmd_setSendBlock160(len, buf);
dcBL_step++;
break;
case 15: // wait for answer
if (gotResp==ISOK)
{
dcBL_step++;
repeatCtr=0;
return 0;
} else
if (gotResp==ISWRONG)
{
if (++repeatCtr>3)
{
dcBL_step--;
}
}
if (++dcBL_cyclCtr>10)
{
dcBL_writeText("cancel");
dcBL_step=0; // stop chain
}
break;
}
return 0;
}
uint8_t dcBL_getResult(void)
{
// call after every step to what's going on....
// 1: connected to BL
// 2: transmission started
// 3: transmission successful
return dcBL_state;
}
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
static uint8_t Sdata_rawData[RAW_BL_DATALEN];
static uint8_t Sdata_LengthRawData;
void gpi_storeRawReceivedData(uint8_t RdDlen, uint8_t *receivedData)
{
uint8_t nn;
Sdata_LengthRawData=RdDlen;
if (Sdata_LengthRawData>RAW_BL_DATALEN)
Sdata_LengthRawData=RAW_BL_DATALEN;
for (nn=0; nn<Sdata_LengthRawData; nn++)
Sdata_rawData[nn]=receivedData[nn];
//qDebug()<<"dcBL got data"<< Sdata_LengthRawData << "bytes :)";
}
uint8_t epi_getRawReceivedData(uint8_t *receivedData)
{
// retval=length, will be zeroed after first reading
uint8_t nn, ret;
for (nn=0; nn<Sdata_LengthRawData; nn++)
receivedData[nn]=Sdata_rawData[nn];
ret=Sdata_LengthRawData;
//Sdata_LengthRawData=0;
return ret;
}
uint8_t epi_getRawRecLength(void)
{
// retval=length
return Sdata_LengthRawData;
}
QString epi_getRawReceivedString()
{
uint8_t nn; //, ret;
QString myString=nullptr, tmpStr=nullptr;
myString.clear();
if (Sdata_LengthRawData==0)
return myString;
for (nn=0; nn<Sdata_LengthRawData; nn++)
{
tmpStr.clear();
tmpStr.setNum(Sdata_rawData[nn],16); // problem: wenn >0x80 dann wird EIN Byte 16 stellig angezeigt
int ll=tmpStr.length();
if (ll>2)
{
myString.append(tmpStr[ll-2]);
myString.append(tmpStr[ll-1]);
} else
{
myString.append(tmpStr);
}
myString.append(" ");
}
//ret=Sdata_LengthRawData;
//Sdata_LengthRawData=0;
return myString;
}
void epi_clrRawReceivedString()
{
Sdata_LengthRawData=0;
}