//#include #include "dcBL.h" #include //#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> (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; nn0 && 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; LLalso 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 "<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"<=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; nn0) 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;nn17) { dcBL_iniChain(); dcBL_step=1; //epi_clrRawReceivedString(); qDebug()<<"starting chain..."; //qDebug()<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; nn0x80 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; } */