DCLibraries/src/dcBL.cpp

1529 lines
43 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;
qDebug()<<"dcBL_sendFlashStartAddr2BL "<<myBuf[0]<<" "<<myBuf[1]<<" "<<myBuf[2]<<" "<<myBuf[3];
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],ret;
strclr(myBuf, 0, 2);
ret=dcBL_prepareDC_BLcmd(0x22, 0, myBuf, sendData);
qDebug()<<"dcBL just sending last block command, ret: "<<ret<<" "<<sendData[0]
<<" "<<sendData[1]<<" "<<sendData[2]<<" "<<sendData[3]<<" "<<sendData[4]
<<" "<<sendData[5]<<" "<<sendData[6]<<" "<<sendData[7];
return ret;
}
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)
{
// retval: nr of received bytes
uint8_t recLen=epi_getRawRecLength();
if (recLen>0 && recLen<150)
{
epi_getRawReceivedData(respBuff);
epi_clrRawReceivedString();
//dcBL_writeText("dcBL gotResponse");
}
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;
memset(buf,0,152);
recLen=dcBL_getResponse(buf);
if (recLen==0)
return 0; // no response by now
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
}
return 1; // error
}
uint8_t dcBL_sendSuccess(uint8_t lastCommand)
{
// return val: 0: no response by now 1:error 10: OK
uint8_t Indata[152], recLen;
memset(Indata,0,152);
recLen=dcBL_getResponse(Indata);
if (recLen==0)
return 0; // no response by now
// qDebug()<<"dcBL_sendSuccess: got BL data"<< recLen <<
// Indata[0]<< Indata[1]<< Indata[2]<< Indata[3] << Indata[4]<< Indata[5]<< Indata[6]<< Indata[7];
if (Indata[0]==2 && Indata[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);
}
}
*/
// -------------------------------------------------------------------------
static QByteArray dcBL_AtbBinFile;
static uint32_t dcBL_fileSize;
static uint16_t dcBL_nrOfBlocks; // incl. last block
static uint16_t dcBL_fileCrc;
static uint8_t dcBL_myBuf[265000]; // same content like "dcBL_AtbBinFile" but bytewise
static uint8_t dcBL_sizeLastBlk;
bool dcBL_importBinFile(QByteArray readBinFile, uint32_t fileSize, char withDispl)
{
// copy file from QByteArray into local buffer for sending to DC
// calculate size, nr_of_blocks and crc
uint16_t uitmp;
uint32_t ultmp;
uint32_t LL;
dcBL_AtbBinFile=readBinFile;
dcBL_fileSize=fileSize;
if (dcBL_fileSize>=265000) // max bin file size for atmega
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);
ultmp=dcBL_fileSize % 64;
dcBL_sizeLastBlk = uint8_t(ultmp);
qDebug()<<" got file with "<<dcBL_nrOfBlocks<<" blocks (64byte) and crc: "<<dcBL_fileCrc;
return true;
if (withDispl)
{
}
// hier nicht wie bisher bei der VMC um 14 Bytes nach oben schieben und Laenge/crc anhaengen,
// weil man sonst den BL und das Win-tool auch aendern muesste
}
char dcBL_loadBinary(QString fileName)
{
uint32_t fileLen;
QFile file(fileName);
if (!file.exists())
{
qDebug()<<"file dc2c4.bin does not exist";
return 1;
}
if (!file.open(QIODevice::ReadOnly) )
{
qDebug()<<"cannot open";
return 1;
}
QByteArray myBin;
myBin.clear();
myBin = file.readAll();
fileLen=uint32_t(file.size());
qDebug()<<"loading dc2c4.bin binary with " << fileLen <<"bytes \n";
dcBL_importBinFile(myBin, fileLen, 0); //withDisplay);
return 0;
}
char dcBL_loadBinSafe(QString fileName)
{
// 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;
uint32_t BinFileCpyLen1, BinFileCpyLen2, LL;
uint8_t repeat=0, nn=0, stopp=0;
do
{
//dcBL_writeText("loading 1st time:");
//qDebug() <<"loading 1st time:";
dcBL_loadBinary(fileName);
// 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(fileName);
// 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(fileName);
// file jetzt in: "QByteArray dcBL_AtbBinFile" mit Laenge "uint32_t dcBL_fileSize"
repeat=0;
if (dcBL_fileSize !=BinFileCpyLen1 || dcBL_fileSize !=BinFileCpyLen2)
{
//dcBL_writeText("file length wrong");
qDebug() <<"length error";
repeat=1; // load both again....
}
if (repeat==0)
{
LL=0; stopp=0;
do
{
if (dcBL_AtbBinFile.at(LL) != BINFILECOPY1.at(LL))
stopp=1;
} while((++LL < dcBL_fileSize) && !stopp);
if (stopp)
{
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)
{
repeat=1; // load both again....
}
}
} while (++nn<3 && repeat); // 3 trials
if (repeat==0)
{
qDebug() << "read file successful after " << nn << " loops";
return true; // file OK
}
qDebug() << "read file with errors after " << nn << " loops";
return false; // error, could not load correctly
}
// -----------------------------------------------------------------------------------------------
// --- Send Bin-File to DC ---------------------------------------------------------------------
// -----------------------------------------------------------------------------------------------
//static uint32_t dcBL_fileSize;
//static uint16_t dcBL_nrOfBlocks;
//static uint16_t dcBL_fileCrc;
uint16_t dcBL_getNrOfBlocks(void)
{
// size of the loaded bin file in 64byte blocks
return dcBL_nrOfBlocks;
}
uint16_t dcBL_getFileCrc(void)
{
// checksum of the loaded bin file
return dcBL_fileCrc;
}
uint32_t dcBL_getFileSize(void)
{
// length of the loaded bin file in byte
return dcBL_fileSize;
}
uint8_t dcBL_getSizeOfLastBlock(void)
{
uint32_t ultmp;
ultmp=dcBL_fileSize % 64;
return uint8_t(ultmp);
}
void dcBL_sendAddress(uint16_t blockNumber)
{
// send start address, nr of 64byte-block, start with 0
// will be sent only for folling block-numbers:
// 0, 1024, 2048, 3072 and 4096, so basically every 64kByte
uint32_t dcBL_BlkCtr=(uint32_t)blockNumber;
uint8_t len, buf[20];
tslib_strclr(buf, 0, 20);
if (blockNumber==0 || blockNumber==1024 || blockNumber==2048 || blockNumber==3072 || blockNumber==4096)
{
dcBL_BlkCtr*=64;
len=dcBL_sendFlashStartAddr2BL(dcBL_BlkCtr, buf); // make command string
//qDebug()<<"dcBL_bl_sendAddress "<<buf[0]<<" "<<buf[1]<<" "<<buf[2]<<" "<<buf[3]<<" "
// <<buf[4]<<" "<<buf[5]<<" "<<buf[6]<<" ";
sendWRcmd_setSendBlock160(len, buf); // send command to BL
}
}
uint8_t dcBL_getFileBlock(uint16_t blockPointer, uint8_t *buf)
{
// blockPointer=0....4095
uint32_t addr, LL, lang; //, BL;
uint8_t val;
addr=uint32_t(blockPointer);
addr<<=6; // *64 =Start address
lang=dcBL_AtbBinFile.length();
for (LL=0; LL<64; LL++)
{
if (addr<lang)
val=uint8_t(dcBL_AtbBinFile.at(addr));
else
val=0xFF;
addr++;
buf[LL]=val;
}
return 64;
}
static uint16_t block2beSentNow, blTimeOutCounter;
static uint8_t blChainStep, blChainResult, blRepeatCounter;
bool dcBL_sendOneBlockCpl(uint16_t blockNumber)
{
// call in loop from block number 0 upto < "dcBL_getNrOfBlocks()"
// but after every call WAIT (!) for response "dcBL_getBlockResult()" !!!!
// data will be sent to DC, if neccesary addr will be sent additionally
// if neccesary sending will automatically repeat up to 3times
if (blockNumber>4095)
return false;
block2beSentNow=blockNumber;
blChainStep=1;
blChainResult=0;
blTimeOutCounter=0;
blRepeatCounter=0;
return true;
}
int8_t dcBL_getBlockResult(void)
{
// after every "dcBL_sendOneBlock()" call this until response
// retval 0: wait 1: OK, blk was sent 2: OK, transfer complete
// 3: error despite repeating, cancel. probably bin file corrupted
// Max duration: 3x no response (BL not OK) = 900ms
return blChainResult;
}
char dcBL_cycle(void)
{
// to be called cyclic every 100ms
uint8_t buf[70], sendBuf[160], ret, sendLen;
if (blChainStep==1)
{
// start, check if addr necessary
if (block2beSentNow==0 || block2beSentNow==1024 || block2beSentNow==2048
|| block2beSentNow==3072 || block2beSentNow==4096 )
{
dcBL_sendAddress(block2beSentNow);
blChainStep++;
//qDebug()<<"dcBL_cycle sending address and wait for response";
return 0; // continue in 100ms
} else
blChainStep=10; // continue immed. with sending data
}
if (blChainStep==2)
{
// address was send, wait for response
ret= dcBL_sendSuccess(0x21);
// return val: 0: no response by now 1:error 10: OK
if (ret==10)
{
//qDebug()<<"dcBL_cycle got resp OK";
blChainStep=10; // OK, continue with data
blTimeOutCounter=0;
return 0; // continue in 100ms
}
if (ret==1)
{
//qDebug()<<"dcBL_cycle got resp error";
// we got response but BL reports an error
blTimeOutCounter=0;
blRepeatCounter++;
if (blRepeatCounter<3)
blChainStep=1; // repeat
else
{
blChainResult=3; // error timeout, no response from DC-BL
blChainStep=99;
return 0;
}
return 0; // continue in 100ms
}
blTimeOutCounter++;
if (blTimeOutCounter>=3) // wait 3 cycles (3x100ms) for response
{
//qDebug()<<"dcBL_cycle TO";
blChainResult=3; // error timeout, no response from DC-BL
blChainStep=99;
return 0;
} else
{
// ein oder zweimal keine Antwort
blChainStep=1; // repeat
//qDebug()<<"dcBL_cycle no response";
return 0; // continue in 100ms
}
}
// kein else!
if (blChainStep==10)
{
// send data block or conclusion
if (block2beSentNow == dcBL_nrOfBlocks)
{
// very last blocknumber, send conclusion
sendLen=dcBL_writeLastPage(sendBuf);
sendWRcmd_setSendBlock160(sendLen, sendBuf);
} else
{
// send data...
dcBL_getFileBlock(block2beSentNow, buf);
//qDebug()<<"dcBL sending data block"<<block2beSentNow;
sendLen=dcBL_prepareDC_BLcmd(0x22, 64, buf, sendBuf); // pack into protocol frame
sendWRcmd_setSendBlock160(sendLen, sendBuf); // send up to 140 bytes
}
blChainStep++;
} else
if (blChainStep==11)
{
// data or conclusion was send, wait for response
ret=dcBL_sendSuccess(0x22);
// return val: 0: no response by now 1:error 10: OK
if (ret==10)
{
blChainStep=99; // OK, done
blChainResult=1; // block sent succesful
if (block2beSentNow == dcBL_nrOfBlocks)
blChainResult=2; // transfer complete
blTimeOutCounter=0;
return 0; // continue in 100ms
}
if (ret==1)
{
// we got response but BL reports an error
blTimeOutCounter=0;
blRepeatCounter++;
if (blRepeatCounter<3)
blChainStep=10; // repeat
else
{
blChainResult=3; // error timeout, no response from DC-BL
blChainStep=99;
return 0;
}
return 0; // continue in 100ms
}
blTimeOutCounter++;
if (blTimeOutCounter>=3) // wait 3 cycles (3x100ms) for response
{
blChainResult=3; // error timeout, no response from DC-BL
blChainStep=99;
return 0;
} else
{
// ein oder zweimal keine Antwort
blChainStep=10; // repeat
return 0; // continue in 100ms
}
}
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 here 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_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
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;
}
*/
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// -------------------------------------------------------------------------
// move to storeINdata and use shared mem as ptu-updater uses CAslave Lib 6.9.23TS
/*
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;
}
*/