void AVRProgrammer::startupTargetMcuProgramming(byte& statusRes) {
  initStatus();
  if (targetMcuProgMode) {
    logError("MCU In PMODE!");
    returnStatus(ERR(0x17));
  }
  
  digitalWrite(pinVccEnable, HIGH);
  digitalWrite(pinAVccEnable, HIGH);
  
  // special case (when we cannot operate with Vcc and Avcc pins of target mcu)
  digitalWrite(pinReset, HIGH);
  delay(3);
  digitalWrite(pinReset, LOW);
  
  delay(30); // minimum 20ms is required by spec
  
  byte byte1 = sendReadByte(0xAC);
  byte byte2 = sendReadByte(0x53);
  byte byte3 = sendReadByte(0x00);
  byte byte4 = sendReadByte(0x00);

  targetMcuProgMode = true;
  targetMcuOutOfSync = (byte3 != 0x53 || byte4 != 0x00);
  if (targetMcuOutOfSync) {
    returnStatus(ERR(0x11));
  }
}
void ProgramFile::findAndOpenNextFileBackupFile(String filePref, byte& statusRes) {
  initStatus();
  // Create file
  if (filePref.length() > 4) {
    logDebug("Wrong file pref used");
    returnStatus(ERR(0x50)); // system error, wrong filePref used
  }
  //char buf[13];
  String fileName;
  boolean isF = false;
  int minAvNo = 10000;
  for (int n = 300; n > 0; n--) {//maximum 300 files allowed, for faster search (possible up to 9999)
    fileName = String(filePref + String(n / 1000) + String(n / 100 % 10) + String(n / 10 % 10) + String(n % 10) + ".BKP");
    logDebugS("checking:", fileName);
    backupFile = SD.open(fileName, FILE_READ);
    if (backupFile) {
      logDebugD("found",n);
      break;
    }
    minAvNo = n;
  }
  if (minAvNo == 10000) {
    returnStatus(ERR(0x53)); // not enough space for backup files
  }
  
  fileName = String(filePref + String(minAvNo / 1000) + String(minAvNo / 100 % 10) + String(minAvNo / 10 % 10) + String(minAvNo % 10) + ".BKP");
  logDebugS("Next free file:", fileName);
  backupFile = SD.open(fileName, FILE_WRITE);
  if (!backupFile) {
    logDebug("!writeFile");
    returnStatus(ERR(0x52)); // cannot open backup file for write
  }
}
示例#3
0
SEXP setMVElement(SEXP Sextptr, SEXP Sindex, SEXP Svalue){
    if(!isInteger(Sindex)) {
    PRINTF("Error: Sindex is not an integer!\n");
	return(returnStatus(false) ) ;
  }
  if(!R_ExternalPtrAddr(Sextptr)) {
    PRINTF("Error: Sextptr is not a valid external pointer\n");
	return(returnStatus(false) ) ;
  }
  int index = INTEGER(Sindex)[0];
  if(index < 1){ 
    PRINTF("Error: index < 1\n");   	
	return(returnStatus(false) ) ;
  }

   NimVecType *typePtr = static_cast< NimVecType* >(R_ExternalPtrAddr(Sextptr));
   nimType vecType = (*typePtr).getNimType();
  int nrowCpp = typePtr->size();
  if(index > nrowCpp){
	PRINTF("Error: index too large\n");
	return(returnStatus(false) ) ;
  }
  cSetMVElementSingle( typePtr, vecType, index, Svalue );
  SEXP SEXP_2_int(SEXP rPtr, SEXP refNum, SEXP rScalar);
  return(returnStatus(true) );
 } 
/**
  addrMsb - 0000 00aa
  addrLsb - aaaa aa00
*/
void AVRProgrammer::writeEEPROMMemoryPage(byte addrMsb, byte addrLsb, byte& statusRes) {
  if (addrMsb & B00000011 > 0) {
    logDebug("addrMsb is wrong");
    returnStatus(ERR(0x10)); // system error, wrong addrMsb
  }
  if (addrLsb & B11111100 > 0) {
    logDebug("addrLsb is wrong");
    returnStatus(ERR(0x10)); // system error, wrong addrLsb
  }
  issueByteWriteCmd(0xC2, addrMsb, addrLsb, 0x00, statusRes);
}
示例#5
0
/* Cliff's new function for adding blank rows to C model values */
SEXP addBlankModelValueRows(SEXP Sextptr, SEXP numAdded){
    if(!isInteger(numAdded)) {
        PRINTF("Error: numAdded is not an integer!\n");
        return(returnStatus(false) );
    }
    
    if(!R_ExternalPtrAddr(Sextptr)) {
        PRINTF("Error: Sextptr is not a valid external pointer\n");
        return(returnStatus(false) );
    }
    NimVecType *typePtr = static_cast< NimVecType* >(R_ExternalPtrAddr(Sextptr));
    nimType vecType = (*typePtr).getNimType();
    if(vecType == DOUBLE){
    	VecNimArrBase<double> *matPtr = static_cast< VecNimArrBase<double>* >(R_ExternalPtrAddr(Sextptr));
    	int nrowCpp = matPtr->size();
	    int new_size = INTEGER(numAdded)[0] + nrowCpp;
    	matPtr->resize(new_size);
    	NimArrBase<double> *thisRow;
    	thisRow = matPtr->getBasePtr(0);
    	int numDims = thisRow->numDims();
	     vector<int> Dims(numDims);
 		for(int i = 0; i < numDims; i++)
      		Dims[i] = thisRow->dimSize(i);
    	for(int i = nrowCpp; i < INTEGER(numAdded)[0] + nrowCpp; i++){
      		thisRow = matPtr->getBasePtr(i); 
      		thisRow->setSize(Dims);
    	}
    return(returnStatus(true) );
    }
    
    else if(vecType == INT){
    	VecNimArrBase<int> *matPtr = static_cast< VecNimArrBase<int>* >(R_ExternalPtrAddr(Sextptr));
    	int nrowCpp = matPtr->size();
    	  int new_size = INTEGER(numAdded)[0] + nrowCpp;
	  	matPtr->resize(new_size);
    	NimArrBase<int> *thisRow;
    	thisRow = matPtr->getBasePtr(0);
    	int numDims = thisRow->numDims();
  	    vector<int> Dims(numDims);
		for(int i = 0; i < numDims; i++)
      		Dims[i] = thisRow->dimSize(i);
    	for(int i = nrowCpp; i < INTEGER(numAdded)[0] + nrowCpp; i++){
      		thisRow = matPtr->getBasePtr(i); 
      		thisRow->setSize(Dims);
    	}
    return(returnStatus(true) );
    }
 	
 	PRINTF("Data type for VecNimArr not currently supported\n");
 	return(returnStatus(false) ) ;
}
示例#6
0
SEXP setNumListRows(SEXP Sextptr, SEXP nRows, SEXP setSize2row1){
    NimVecType *typePtr = static_cast< NimVecType* >(R_ExternalPtrAddr(Sextptr));
    nimType vecType = (*typePtr).getNimType();
    if(vecType == DOUBLE){
    	VecNimArrBase<double> *matPtr = static_cast< VecNimArrBase<double>* >(R_ExternalPtrAddr(Sextptr));
    	int nrowCpp = matPtr->size();
	    int new_size = INTEGER(nRows)[0];
    	matPtr->resize(new_size);
    	if(new_size <= nrowCpp)
    		return(returnStatus(true));
    	if(LOGICAL(setSize2row1)[0]	== TRUE){
		    	NimArrBase<double> *thisRow;
    			thisRow = matPtr->getBasePtr(0);
    			int numDims = thisRow->numDims();
		     	vector<int> Dims(numDims);
 				for(int i = 0; i < numDims; i++)
    	  			Dims[i] = thisRow->dimSize(i);
   		   		for(int i = nrowCpp; i < new_size; i++){
   		   			thisRow = matPtr->getBasePtr(i);
    	  			thisRow->setSize(Dims);
    	  		}
    	return(returnStatus(true) );
    	}
    }
    else if(vecType == INT){
    	VecNimArrBase<int> *matPtr = static_cast< VecNimArrBase<int>* >(R_ExternalPtrAddr(Sextptr));
    	int nrowCpp = matPtr->size();
    	  int new_size = INTEGER(nRows)[0];
	  	matPtr->resize(new_size);
	  	if(new_size <= nrowCpp)
    		return(returnStatus(true));

    	if(LOGICAL(setSize2row1)[0]	== TRUE){
    		NimArrBase<int> *thisRow;
    		thisRow = matPtr->getBasePtr(0);
    		int numDims = thisRow->numDims();
  	    	vector<int> Dims(numDims);
			for(int i = 0; i < numDims; i++)
      			Dims[i] = thisRow->dimSize(i);
      		for(int i = nrowCpp; i < new_size; i++){
      			thisRow = matPtr->getBasePtr(i);
      			thisRow->setSize(Dims);
      		}
      	}
    return(returnStatus(true) );
    }
 	
 	PRINTF("Data type for VecNimArr not currently supported\n");
 	return(returnStatus(false) ) ;
}
/**
  addr - 0..3
*/
void AVRProgrammer::loadEEPROMMemoryPageByte(byte addr, byte b, byte& statusRes) { 
  if (addr > 3) {
    logDebug("loadEEPROMMemoryPageByte, addr > 3");
    returnStatus(ERR(0x10));// system error - addr too high
  }
  issueByteWriteCmd(0xC1, 0x00, addr, b, statusRes); 
}
void AVRProgrammer::loadAndWriteProgramMemoryPage(byte* buf, int bufSize, int pageNo, byte mcuModelId, byte& statusRes) {
  if (pageNo < 0) {
    logErrorD("wrongPageNo:", pageNo);
    returnStatus(ERR(0x10));
  }
  if (mcuModelId < 1 || mcuModelId > MCU_AVR_DATA_LENGTH) {
    logErrorD("wrongMcuModelId:", mcuModelId);
    returnStatus(ERR(0x10));
  }

  byte progMemPageSize   = MCU_AVR_DATA[mcuModelId-1][0];
  byte progMemPagesCount = MCU_AVR_DATA[mcuModelId-1][1];
  byte expectedBufSize = (1 << (progMemPageSize + 1));
  if (bufSize != expectedBufSize) {
    logErrorD("!bufSize:", bufSize);
    logInfoD("expected:", expectedBufSize);
    returnStatus(ERR(0x10));
  }

  /* (should only run when Full erase was performed before!)
  // Check is all FF, then no need to program this buffer
  boolean allFF = true;
  for (int i = 0; i < expectedBufSize; i++) {
    if (buf[i] != 0xFF) { allFF = false; break; }
  }
  if (allFF) return; // nothing to programm, all FF
  */
  
  int addr = pageNo << progMemPageSize;
  byte addrMsb = addr >> 8;
  byte addrLsb = addr & 0xFF;
  //logDebugD("addr:",addr);
  //logDebugD("addrMsb:",addrMsb);
  //logDebugD("addrLsb:",addrLsb);
  
  // load into buffer
  waitForTargetMCU(statusRes); checkStatus();
  for (int i = 0; i < (1 << progMemPageSize); i++) {
    byte addrLow = addrLsb | i;
    //logDebugB("i:", i);
    //logDebugB("addrLow:", addrLow);
    loadProgramMemoryPageByte(false, i, buf[i * 2], statusRes); checkStatus();
    loadProgramMemoryPageByte(true, i, buf[i * 2 + 1], statusRes); checkStatus();
  }
  // programm
  writeProgramMemoryPage(addrMsb, addrLsb, statusRes); checkStatus();
}
示例#9
0
void HEXFile::openFile(File& f, String fileName, int mode, byte& statusRes) {
  initStatus();
  f = SD.open(fileName, FILE_READ);
  if (mode == FILE_WRITE) {
    if (!f) {
      logDebugS("File exists! override protection!:", fileName);
      returnStatus(ERR(0x90));//system error, calling program must check if file exists
    }
    f = SD.open(fileName, FILE_WRITE);
  }
  if (!f) {
    logDebugS("!open:",fileName);
    returnStatus(ERR(0x91)); //Cannot open ProgramFile
  } else {
    logInfoS("Opened file:", fileName);
  }
}
void AVRProgrammer::issueByteWriteCmd(byte b1, byte b2, byte b3, byte b4, byte& statusRes) {
  byte r = issueByteReadCmd4(b1, b2, b3, b4, statusRes);
  if (r != b3) {
    targetMcuOutOfSync = true;
    logErrorB("OutOfSync b4:",b3);// Out of sync on 4th byte
    returnStatus(ERR(0x12));
  }
}
示例#11
0
// returns false if there are no more characters to read, true otherwise
void ConfFile::skipWhiteCharactersExpectNoEolNoEof(byte& statusRes) {// skip all white characters (except EOL), positions on the first non-white character. Expect no EOL or EOF!
  initStatus();
  int skippedChars = 0;
  while (_confFile.available()) {
    char c = _confFile.peek();
    if (c == 0x0A || c == 0x0D) {
      logDebug("unexpected EOL");
      returnStatus(ERR(0x22)); // unexpected EOL
    } else {
      if (!isWhiteChar(c)) {
        return;
      }
    }
    _confFile.read(); skippedChars++;
  }
  logDebug("unexpected EOF");
  returnStatus(ERR(0x22));//unexpected EOF
}
示例#12
0
void HEXFile::readLine(File& f, byte& lineType, byte* buf, byte bufSize, byte& resSize, unsigned int& address, byte& statusRes) {
  byte i;
  crc8Init();
  logDebug("readLine");
  // :LLAAAATTDDDD.....DDCC
  // c[0] - LL - Length of Data
  // c[1-2] - AAAA - Address
  // c[3] - TT - Line Type (0x00 - Data; 0x01 - End Of File; ...)
  if (!UtilsSD::readChar(f,i)) { logDebug("rl0"); returnStatus(ERR(0x9F)); }
  if (i != ':') {
    logDebugB("badStart:",i);
    returnStatus(ERR(0x9F));
  }

  // read data length
  resSize = crc8Append(UtilsSD::readHexByte(f,statusRes)); checkOverrideStatus(ERR(0x9F));
  if (resSize > bufSize) {
    logErrorD("too big line data!", resSize);
    returnStatus(ERR(0x9F));
  }

  // read address
  logDebug("addrH");
  address = crc8Append(UtilsSD::readHexByte(f,statusRes)) << 8; checkOverrideStatus(ERR(0x9F));
  logDebug("addrL");
  address |= crc8Append(UtilsSD::readHexByte(f,statusRes)); checkOverrideStatus(ERR(0x9F));
  logDebugD("addr:", address);

  logDebug("type");
  lineType = crc8Append(UtilsSD::readHexByte(f,statusRes)); checkOverrideStatus(ERR(0x9F));
  if (lineType != LINE_TYPE_DATA && lineType != LINE_TYPE_EOF) {
    logDebugB("bad!:", lineType);
    returnStatus(ERR(0x9F));
  }
  
  logDebug("data");
  for (i = 0; i < resSize; i++) {
    buf[i] = crc8Append(UtilsSD::readHexByte(f,statusRes)); checkOverrideStatus(ERR(0x9F));
  }

  logDebug("crc");
  byte crc = UtilsSD::readHexByte(f,statusRes); checkOverrideStatus(ERR(0x9F));
  byte calcCrc = crc8Close();
  if (crc != calcCrc) {
    logDebug("Wrong CRC!");
    logDebugB("expected:", crc);
    logDebugB("calculated:", calcCrc);
    returnStatus(ERR(0x9F));
  }
  
  UtilsSD::readCharOrEolOrEof(f, i, crc, statusRes); checkOverrideStatus(ERR(0x9F));
  if (crc == UtilsSD::IS_CHAR) {
    logDebugC("c:",i);
    returnStatus(ERR(0x9F));
  }

  returnStatusOK();
}
示例#13
0
SEXP getMVElement(SEXP Sextptr, SEXP Sindex){
	if(!isInteger(Sindex)) {
    	PRINTF("Error: Sindex is not an integer!\n");
    	return(returnStatus(false) ) ;
	}
  	if(!R_ExternalPtrAddr(Sextptr)) {
  	  PRINTF("Error: Sextptr is not a valid external pointer\n");
  	  return(returnStatus(false) ) ;
  	}
	NimVecType *typePtr = static_cast< NimVecType* >(R_ExternalPtrAddr(Sextptr));
	nimType vecType = (*typePtr).getNimType();
	int nrowCpp = typePtr->size();
	int index = INTEGER(Sindex)[0];
	if(index > nrowCpp){
		PRINTF("Error: index too large\n");
		return(returnStatus(false) ) ;
	  }
  	if(index < 1){
		PRINTF("Error: index < 1\n");
		return(returnStatus(false) ) ;
  	}
  return(cGetMVElementOneRow(typePtr, vecType, index) ) ;	
}  	
void AVRProgrammer::readEepromMemoryPage(byte* pageBuffer, byte pageNumber, byte pageSize, byte& statusRes) {
  if (pageSize != AVR_MEM_PAGE_SIZE_4) {
    logDebugD("readEepromMemoryPage:pageSize:", pageSize);
    returnStatus(ERR(0x10));
  }
  byte addrHigh = pageNumber >> (8 - pageSize);
  byte addrLowPage = pageNumber << pageSize;
  byte maxPageAddr = 1 << pageSize;
  for (int i = 0; i < maxPageAddr; i++) {
    byte addrLow = addrLowPage | i;
    pageBuffer[i] = readEepromMemoryByte(addrHigh, addrLow, statusRes);
    checkStatus();
  }
}
示例#15
0
void ProgramFile::uploadMcuDataFromFile_internal(boolean progMode, String fileName, byte targetMcuModelId, byte& statusRes) {
  if (targetMcuModelId < 1 || targetMcuModelId > MCU_AVR_DATA_LENGTH) {
    logDebugD("modelId bad:", targetMcuModelId);
    returnStatus(ERR(0x50));
  }
  byte m = targetMcuModelId - 1;
  byte signBytes[3];
  signBytes[0] = MCU_AVR_DATA[m][4];
  signBytes[1] = MCU_AVR_DATA[m][5];
  signBytes[2] = MCU_AVR_DATA[m][6];
  byte progMemPageSize = MCU_AVR_DATA[m][0], progMemPagesCount = MCU_AVR_DATA[m][1];
  byte eepromMemPageSize = MCU_AVR_DATA[m][2], eepromMemPagesCount = MCU_AVR_DATA[m][3];
  uploadMcuDataFromFile_internal(progMode, fileName, targetMcuModelId, signBytes, 
            progMemPagesCount, progMemPageSize, eepromMemPagesCount, eepromMemPageSize, statusRes);
}
示例#16
0
// returns false if there are no more characters to read, true otherwise
void ConfFile::skipLine(byte& statusRes) {// skips to the next line, positions on first character of next line
  initStatus();
  while (_confFile.available()) {
    byte c = _confFile.read();
    if (c == 0x0A) {
      return;
    }
    if (c == 0x0D) {
      if (_confFile.available()) c = _confFile.read();
      if (c != 0x0A) {
        logDebug("skipLine,eol wrong");
        returnStatus(ERR(0x21)); // corrupted file, eol is wrong
      }
      return;
    }
  }
}
void AVRProgrammer::readProgramMemoryPage(byte* pageBuffer, byte pageNumber, byte pageSize, byte& statusRes) {
  if (pageSize < AVR_MEM_PAGE_SIZE_16 || pageSize > AVR_MEM_PAGE_SIZE_64) {
    logDebugD("readProgramMemoryPage:pageSize:", pageSize);
    returnStatus(ERR(0x10));
  }
  byte addrHigh = pageNumber >> (8 - pageSize);
  byte addrLowPage = pageNumber << pageSize;
  byte maxPageAddr = 1 << pageSize;
  for (int i = 0; i < maxPageAddr; i++) {
    byte addrLow = addrLowPage | i;
    logDebugB("addrHigh:", addrHigh);
    logDebugB("addrLow:", addrLow);
    pageBuffer[i * 2] = readProgramMemoryByte(false, addrHigh, addrLow, statusRes);
    checkStatus();
    pageBuffer[i * 2 + 1] = readProgramMemoryByte(true, addrHigh, addrLow, statusRes);
    checkStatus();
  }
}
示例#18
0
/* This copies the values from SextptrFrom into SextptrTo. It takes values from rowsFrom and copies
into rowsTo */
SEXP copyModelValuesElements(SEXP SextptrFrom, SEXP SextptrTo, SEXP rowsFrom, SEXP rowsTo){
    if(!R_ExternalPtrAddr(SextptrFrom) | !R_ExternalPtrAddr(SextptrFrom)) {
        PRINTF("Error: Sextptr is not a valid external pointer\n");
        return(returnStatus(false));
    }
    if(LENGTH(rowsFrom) != LENGTH(rowsTo) ){
        PRINTF("Error: length of rowsFrom != rowsTo");
        return(returnStatus(false) );
    }
    if(LENGTH(rowsFrom) == 0){
        return(returnStatus(true) );
    }
  
  NimVecType *typePtrFrom = static_cast< NimVecType* >(R_ExternalPtrAddr(SextptrFrom));
  nimType vecTypeFrom = (*typePtrFrom).getNimType();
  NimVecType *typePtrTo = static_cast< NimVecType* >(R_ExternalPtrAddr(SextptrTo));
  nimType vecTypeTo = (*typePtrTo).getNimType();

  if((vecTypeFrom == DOUBLE) & (vecTypeTo == DOUBLE)){
	  VecNimArrBase<double> *matPtrFrom = static_cast< VecNimArrBase<double>* >(typePtrFrom);
	  VecNimArrBase<double> *matPtrTo = static_cast< VecNimArrBase<double>* >(typePtrTo );
	  int k = LENGTH(rowsFrom);
	  int sizeFrom = matPtrFrom->size();
	  int sizeTo = matPtrTo->size();
	  int *indexFrom = INTEGER(rowsFrom);
	  int *indexTo = INTEGER(rowsTo);
	  NimArrBase<double> *thisRowFrom;
	  NimArrBase<double> *thisRowTo;
	  int ncFrom = 0;
	  int ncTo = 0;
    
	  for(int i = 0; i < k; i++){
	  if((indexFrom[i] > sizeFrom) | (indexFrom[i] <= 0))
	    {
	    _nimble_global_output<<"Warning: invalid index to copy from. Index = " << indexFrom[i] << " sizeFrom = " << sizeFrom << "\n";
	    nimble_print_to_R(_nimble_global_output);
	    if(i > 0)
	      PRINTF("Warning: partial copy completed before error discovered!\n");
	    return(returnStatus(false) );
    	}
  	if((indexTo[i] > sizeTo) | (indexTo[i] <=0))
  	  {
	    _nimble_global_output<<"Warning: invalid index to copy from. Index = " << indexTo[i] << " sizeTo = "<< sizeTo << "\n";
	    nimble_print_to_R(_nimble_global_output);
  	  if(i > 0)
  	    PRINTF("Warning: partial copy completed before error discovered!\n");
  	  return(returnStatus(false) );
  	  }
  	thisRowFrom = matPtrFrom->getBasePtr(indexFrom[i] - 1);  
  	thisRowTo = matPtrTo->getBasePtr(indexTo[i] - 1);  
  
  	ncFrom = thisRowFrom->size();
  	ncTo = thisRowTo->size();
  
  	if(ncFrom != ncTo){
  	  PRINTF("Error: ncFrom != ncTo\n");
  	  if(i > 0)
  	    PRINTF("Warning: partial copy completed before error discovered!\n");
  	  return(returnStatus(false) );
  	  }
  	for(int j = 0; j < ncFrom; j++)
  		    (*thisRowTo)[j] = (*thisRowFrom)[j];
  	}
  	return(returnStatus(true) );
  }

  if((vecTypeFrom == INT) & (vecTypeTo == INT)){
	  VecNimArrBase<int> *matPtrFrom = static_cast< VecNimArrBase<int>* >(typePtrFrom);
	  VecNimArrBase<int> *matPtrTo = static_cast< VecNimArrBase<int>* >(typePtrTo );
	  int k = LENGTH(rowsFrom);
	  int sizeFrom = matPtrFrom->size();
	  int sizeTo = matPtrTo->size();
	  int *indexFrom = INTEGER(rowsFrom);
	  int *indexTo = INTEGER(rowsTo);
	  NimArrBase<int> *thisRowFrom;
	  NimArrBase<int> *thisRowTo;
	  int ncFrom = 0;
	  int ncTo = 0;
    
	  for(int i = 0; i < k; i++){
	  if((indexFrom[i] > sizeFrom) | (indexFrom[i] <= 0))
	    {
	    _nimble_global_output<<"Warning: invalid index to copy from. Index = " << indexFrom[i] << " sizeFrom = " << sizeFrom << "\n";
	    nimble_print_to_R(_nimble_global_output);
	    if(i > 0)
	      PRINTF("Warning: partial copy completed before error discovered!\n");
	    return(returnStatus(false) );
    	}
  	if((indexTo[i] > sizeTo) | (indexTo[i] <=0))
  	  {
  	  _nimble_global_output<<"Warning: invalid index to copy from. Index = " << indexTo[i] << " sizeTo = "<< sizeTo << "\n";
	  nimble_print_to_R(_nimble_global_output);
	  if(i > 0)
  	    PRINTF("Warning: partial copy completed before error discovered!\n");
  	  return(returnStatus(false) );
  	  }
  	thisRowFrom = matPtrFrom->getBasePtr(indexFrom[i] - 1);  
  	thisRowTo = matPtrTo->getBasePtr(indexTo[i] - 1);  
  
  	ncFrom = thisRowFrom->size();
  	ncTo = thisRowTo->size();
  
  	if(ncFrom != ncTo){
  	  PRINTF("Error: ncFrom != ncTo\n");
  	  if(i > 0)
  	    PRINTF("Warning: partial copy completed before error discovered!\n");
  	  return(returnStatus(false) );
  	  }
  	for(int j = 0; j < ncFrom; j++)
  		    (*thisRowTo)[j] = (*thisRowFrom)[j];
  	}
  	return(returnStatus(true) );
  }

  PRINTF("Data type not currently supported for VecNimArr. Copy MV elements failed\n");
  return(returnStatus(false) );

}	
示例#19
0
void ProgramFile::readLine(File& f, byte& lineType, byte* buffer, int& resSize, int& pageNo, byte& statusRes) {
  byte c[4];
  logDebug("readLine");
  if (!UtilsSD::readChar(f,c[0])) { logDebug("rl0"); returnStatus(ERR(0x54)); }
  logDebugC("read c[0]:", c[0]);
  if (c[0] == '#') {
    lineType = LINE_TYPE_COMMENT;
    int chars = UtilsSD::readToTheEOL(f,statusRes);
    logDebugS("readToEOL:", String(chars) + "," + String(statusRes,HEX));
    return;
  }
  if (!UtilsSD::readChar(f,c[1])) returnStatus(ERR(0x54));
  logDebugC("read c[1]:", c[1]);
  if (!UtilsSD::readChar(f,c[2])) returnStatus(ERR(0x54));
  logDebugC("read c[2]:", c[2]);
  if (!UtilsSD::readChar(f,c[3])) returnStatus(ERR(0x54));
  logDebugC("read c[3]:", c[3]);
  if (c[3] != ':') returnStatus(ERR(0x54));
  logDebug("read 3 char");
  
  lineType = 0xFF;
  for (byte i = 0; i < 11; i++) {
    boolean matched = true;
    for (byte j = 0; j < 3; j++) {
      if (c[j] != line_types[i][j]) {
        matched = false;
        break;
      }
    }
    if (matched) {
      lineType = line_types[i][3];
      break;
    }
  }
  logDebugB("lineType:", lineType);
  if (lineType == 0xFF) {
    logWarn("Bad line"); // No match of valid line type found!
    returnStatus(ERR(0x54));
  }
  
  if (lineType == LINE_TYPE_TID) {
    UtilsSD::readToTheEOL(f,statusRes);
    return;
  } else if (lineType == LINE_TYPE_TYP) {
    UtilsSD::readToTheEOL(f,statusRes);
    return;
    // TODO Implement verification of string: it should be "AVR" or "PIC" for PICs
  } else if (lineType == LINE_TYPE_MDL) {
    UtilsSD::readToTheEOL(f,statusRes);
    return;
    // TODO Implement verification of string: it should be "AVR" or "PIC" for PICs
  } else if (lineType == LINE_TYPE_SGN) {
    resSize = 3;
    buffer[0] = UtilsSD::readHexByte(f,statusRes); checkStatus();
    logDebugB("byte0:", buffer[0]);

    buffer[1] = UtilsSD::readHexByte(f,statusRes); checkStatus();
    logDebugB("byte1:", buffer[1]);

    buffer[2] = UtilsSD::readHexByte(f,statusRes); checkStatus();
    logDebugB("byte2:", buffer[2]);

  } else if (lineType == LINE_TYPE_LKB || lineType == LINE_TYPE_FSB || 
             lineType == LINE_TYPE_FHB || lineType == LINE_TYPE_EFB || lineType == LINE_TYPE_CLB) {
    resSize = 1;
    buffer[0] = UtilsSD::readHexByte(f,statusRes); checkStatus();

  } else if (lineType == LINE_TYPE_PRM || lineType == LINE_TYPE_ERM) {

    pageNo = UtilsSD::read3DigByte(f,statusRes); checkStatus();
    //logDebugD("pageNo:", pageNo);

    byte cs;
    if (!UtilsSD::readChar(f,cs)) returnStatus(ERR(0x54));
    //logDebugB("read cs:", cs);
    if (cs != ':') returnStatus(ERR(0x54)); // No ':'
  
    resSize = 0;
    do {
      boolean isEOL = false;
      byte b = UtilsSD::readHexByteOrEOL(f,isEOL,statusRes);
      if (statusRes > 0) return;
      if (isEOL) return; // its end of line, we should not continue from this place, otherwise line will get corrupted!
      
      if (resSize == LINE_READ_BUFFER_SIZE) {
        // too long line - buffer cannot hold that amount!
        logDebug("TOO LONG!!!!");
        returnStatus(ERR(0x54));
      }
      buffer[resSize++] = b;
    } while(true);
  }

  int z = UtilsSD::readToTheEOL(f,statusRes); checkStatus();
  if (z != 0) {
    returnStatus(ERR(0x54));
  }
}
示例#20
0
void MainWindow::timer_timeout()
{
    ui->txtLog->setText(sc->log);

    ui->txtVisionSpeed->setText(QString::number(sc->sslvision->FPS()));
    ui->txtVisionSpeed_0->setText(QString::number(sc->sslvision->getFPS(0)));
    ui->txtVisionSpeed_1->setText(QString::number(sc->sslvision->getFPS(1)));
    ui->txtAIfps->setText(QString::number(sc->ai->fps.FPS()));

    bool pause1;
    bool pause2;
    if(ui->rdoRefMain->isChecked())
    {
        pause1 = false;
        pause2 = true;
    }
    if(ui->rdoRefManual->isChecked())
    {
        pause1 = true;
        pause2 = false;
    }

    GameStatePacket refgs;
    GameStatePacket refgs2;
    if(sc->sslrefbox)
    {
        sc->sslrefbox->paused = pause1;
        ui->txtRefreeSpeed->setText("old : " + QString::number(sc->sslrefbox->FPS()));
        refgs = sc->sslrefbox->refgs;
    }
    if(sc->sslrefboxnew)
    {
        sc->sslrefboxnew->paused = pause1;
        ui->txtRefreeSpeed->setText("new : " + QString::number(sc->sslrefboxnew->FPS()));
        refgs = sc->sslrefboxnew->refgs;
    }
    if(sc->sslrefbox2)
    {
        sc->sslrefbox2->paused = pause2;
        ui->txtRefreeSpeed_2->setText("old : " + QString::number(sc->sslrefbox2->FPS()));
        refgs2 = sc->sslrefbox2->refgs;
    }
    if(sc->sslrefboxnew2)
    {
        sc->sslrefboxnew2->paused = pause2;
        ui->txtRefreeSpeed_2->setText("new : " + QString::number(sc->sslrefboxnew2->FPS()));
        refgs2 = sc->sslrefboxnew2->refgs;
    }

    ui->txtTime->setText(QString::number(sc->wm->time));
    ui->txtTimeBall->setText(QString::number(sc->wm->ball.time));

    QString str_refgs = QString("") + refgs.cmd +
            " : " +QString::number(refgs.cmd_counter) +
            " : " + QString::number(refgs.goals_blue) +
            " : " + QString::number(refgs.goals_yellow) +
            " : " + QString::number(refgs.time_remaining);
    ui->txtrefgs->setText(str_refgs);

    QString str_refgs2 = QString("") + refgs2.cmd +
            " : " +QString::number(refgs2.cmd_counter) +
            " : " + QString::number(refgs2.goals_blue) +
            " : " + QString::number(refgs2.goals_yellow) +
            " : " + QString::number(refgs2.time_remaining);
    ui->txtrefgs_2->setText(str_refgs2);

    ui->txtcmgs_1->setText(QString("gameOn : ") + (sc->wm->cmgs.gameOn()?"1":"0"));
    ui->txtcmgs_2->setText(QString("allowedNearBall : ") + (sc->wm->cmgs.allowedNearBall()?"1":"0"));
    ui->txtcmgs_3->setText(QString("canKickBall : ") + (sc->wm->cmgs.canKickBall()?"1":"0"));

    ui->txtcmgs_4->setText(QString("restart : ") + (sc->wm->cmgs.restart()?"1":"0"));
    ui->txtcmgs_5->setText(QString("ourRestart : ") + (sc->wm->cmgs.ourRestart()?"1":"0"));
    ui->txtcmgs_6->setText(QString("theirRestart : ") + (sc->wm->cmgs.theirRestart()?"1":"0"));

    ui->txtcmgs_7->setText(QString("kickoff : ") + (sc->wm->cmgs.kickoff()?"1":"0"));
    ui->txtcmgs_8->setText(QString("Blue Kickoff : ") + (sc->wm->cmgs.blueKickoff()?"1":"0"));
    ui->txtcmgs_9->setText(QString("Yellow Kickoff : ") + (sc->wm->cmgs.yellowKickoff()?"1":"0"));

    ui->txtcmgs_10->setText(QString("penaltyKick : ") + (sc->wm->cmgs.penaltyKick()?"1":"0"));
    ui->txtcmgs_11->setText(QString("Blue PenaltyKick : ") + (sc->wm->cmgs.bluePenaltyKick()?"1":"0"));
    ui->txtcmgs_12->setText(QString("Yellow PenaltyKick : ") + (sc->wm->cmgs.yellowPenaltyKick()?"1":"0"));

    ui->txtcmgs_13->setText(QString("directKick : ") + (sc->wm->cmgs.directKick()?"1":"0"));
    ui->txtcmgs_14->setText(QString("blue DirectKick : ") + (sc->wm->cmgs.blueDirectKick()?"1":"0"));
    ui->txtcmgs_15->setText(QString("yellow DirectKick : ") + (sc->wm->cmgs.yellowDirectKick()?"1":"0"));

    ui->txtcmgs_16->setText(QString("indirectKick : ") + (sc->wm->cmgs.indirectKick()?"1":"0"));
    ui->txtcmgs_17->setText(QString("Blue IndirectKick : ") + (sc->wm->cmgs.blueIndirectKick()?"1":"0"));
    ui->txtcmgs_18->setText(QString("Yellow IndirectKick : ") + (sc->wm->cmgs.yellowIndirectKick()?"1":"0"));

    ui->txtcmgs_19->setText(QString("freeKick : ") + (sc->wm->cmgs.freeKick()?"1":"0"));
    ui->txtcmgs_20->setText(QString("Blue FreeKick : ") + (sc->wm->cmgs.blueFreeKick()?"1":"0"));
    ui->txtcmgs_21->setText(QString("Yellow FreeKick : ") + (sc->wm->cmgs.yellowFreeKick()?"1":"0"));

    ui->txtcmgs_22->setText(QString("canMove : ") + (sc->wm->cmgs.canMove()?"1":"0"));

    QString ball  = QString::number(sc->wm->ball.pos.loc.x,'f',2) + " , " + QString::number(sc->wm->ball.pos.loc.y,'f',2);
    QString ballv = QString::number(sc->wm->ball.vel.loc.x,'f',2) + " , " + QString::number(sc->wm->ball.vel.loc.y,'f',2);
    ball = "( " + ball + " ) , ( " + ballv + " ) ";

    //Rules
    ui->txtState->setText(returnState(sc->wm->gs));

    int counter = 0, numberOfRules = sc->ai->rS->ruleSize();
    if( counter < numberOfRules )
    {
        ui->txtRule0->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus0->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule1->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus1->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule2->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus2->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule3->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus3->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule4->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus4->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule5->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus5->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule6->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus6->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule7->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus7->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule8->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus8->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule9->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus9->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule10->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus10->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    if( counter < numberOfRules )
    {
        ui->txtRule11->setText(sc->ai->rS->getRuleName(counter));
        ui->txtStatus11->setText(returnStatus(sc->ai->rS->getRuleStatus(counter)));
        counter++;
    }

    // WM
    ui->txtWM->setText("");
    ui->txtWM->append("time : " + QString::number(sc->wm->time));
    ui->txtWM->append("ball : " + ball + " [" + QString::number(sc->wm->ball.isValid?1:0) + "] ");

    ui->txtWM->append("");
    for(int i=0; i<PLAYERS_MAX_NUM; ++i)
    {
        QString r = QString::number(sc->wm->blueRobot[i].pos.loc.x,'f',2) + " , " + QString::number(sc->wm->blueRobot[i].pos.loc.y,'f',2) + " : " + QString::number(sc->wm->blueRobot[i].pos.dir,'f',2);
        QString s = QString::number(sc->wm->blueRobot[i].vel.loc.x,'f',2) + " , " + QString::number(sc->wm->blueRobot[i].vel.loc.y,'f',2) + " : " + QString::number(sc->wm->blueRobot[i].vel.dir,'f',2);
        QString id = QString::number(i);
        if(id.length()<2) id = "0" + id;
        ui->txtWM->append("blue[" + id + "]  : ( " + r + " ) , ( " + s + " ) (" + QString::number(sc->wm->blueRobot[i].vel.loc.length(),'f',2) + ") [" + QString::number(sc->wm->blueRobot[i].isValid) + "] ");
    }

    ui->txtWM->append("");
    for(int i=0; i<PLAYERS_MAX_NUM; ++i)
    {
        QString r = QString::number(sc->wm->yellowRobot[i].pos.loc.x,'f',2) + " , " + QString::number(sc->wm->yellowRobot[i].pos.loc.y,'f',2) + " : " + QString::number(sc->wm->yellowRobot[i].pos.dir,'f',2);
        QString s = QString::number(sc->wm->yellowRobot[i].vel.loc.x,'f',2) + " , " + QString::number(sc->wm->yellowRobot[i].vel.loc.y,'f',2) + " : " + QString::number(sc->wm->yellowRobot[i].vel.dir,'f',2);
        QString id = QString::number(i);
        if(id.length()<2) id = "0" + id;
        ui->txtWM->append("yellow[" + id + "] :  ( " + r + " ) , ( " + s + " ) (" + QString::number(sc->wm->yellowRobot[i].vel.loc.length(),'f',2) + ") [" + QString::number(sc->wm->yellowRobot[i].isValid) + "] ");
    }
    ui->txtWM->append("");
    ui->txtWM->append("ref_goalie_our : " + QString::number(sc->wm->ref_goalie_our));
    ui->txtWM->append("ref_goalie_opp : " + QString::number(sc->wm->ref_goalie_opp));
    ui->txtWM->append("");

    //AI
    sc->wm->var[0] = ui->spnvar0->value();
    ui->txtvar0->setText(QString::number(sc->wm->var[0]));
    sc->wm->var[1] = ui->spnvar1->value();
    ui->txtvar1->setText(QString::number(sc->wm->var[1]));
    sc->wm->var[2] = ui->spnvar2->value();
    ui->txtvar2->setText(QString::number(sc->wm->var[2]));
    sc->wm->var[3] = ui->spnvar3->value();
    ui->txtvar3->setText(QString::number(sc->wm->var[3]));
    sc->wm->var[4] = ui->spnvar4->value();
    ui->txtvar4->setText(QString::number(sc->wm->var[4]));
    sc->wm->var[5] = ui->spnvar5->value();
    ui->txtvar5->setText(QString::number(sc->wm->var[5]));
    sc->wm->var[6] = ui->spnvar6->value();
    ui->txtvar6->setText(QString::number(sc->wm->var[6]));
    sc->wm->var[7] = ui->spnvar7->value();
    ui->txtvar7->setText(QString::number(sc->wm->var[7]));
    sc->wm->var[8] = ui->spnvar8->value();
    ui->txtvar8->setText(QString::number(sc->wm->var[8]));
    sc->wm->var[9] = ui->spnvar9->value();
    ui->txtvar9->setText(QString::number(sc->wm->var[9]));

    //---Debuging Tools----------------
    sc->wm->showAstarOut = ui->astar_checkBox->isChecked();
    sc->wm->indexOfAstarRobot = ui->astarIndex_comboBox->currentText().toInt();

    sc->wm->showVoronoi = ui->show_voronoi->isChecked();

    sc->wm->showDebug = ui->showDebugs->isChecked();
    sc->wm->debug_type = ui->debug_output_type->currentText().toInt();

    sc->wm->showDefenderDebug = ui->showDefence->isChecked();
}
示例#21
0
void ConfFile::readRootConfFile(const char* progId, char* mcuModel, char* filePath, byte& statusRes) {
  initStatus();
  mcuModel[0] = '\0';
  filePath[0] = '\0';
  byte pos = 0;
  boolean eol;
  char c;
  byte progIdLength = strLength(progId);
  logDebugD("l:", progIdLength);
  
  boolean matchDetected = false;
  while (!matchDetected && skipToValidData(statusRes)) { // loop for every valid line
    checkStatus(); // for skipToValidData

    logDebug("skipped");
    // read PROG_ID and match it
    pos = 0;
    while(true) {
      if (!_confFile.available()) {
        logDebug("readRootConfFile:unexp EOF");
        returnStatus(ERR(0x22)); // unexpected EOF
      }
      logDebug("avail");
      c = readCharSafe(eol, statusRes); checkStatus();
      logDebugC("readChar",c);
      if (eol) {
        logDebug("readRootConfFile:unexp EOF");
        returnStatus(ERR(0x22)); // unexpected EOL
      }
      if ((pos >= progIdLength) || (progId[pos] != c) || isWhiteChar(c)) {
           // if we are above expected progId length, no need to continue this line, or
           // if char at pos didn't match progId[pos], or
           // if white char
        break;
      }
      pos++;
    }

    logDebugD("step1:",pos);

    if (pos != progIdLength) {
      goto _skipLine;
    } else {
      matchDetected = true;
    }
      
    logDebugD("step2:",pos);
    
    // read MCU_MODEL
    skipWhiteCharactersExpectNoEolNoEof(statusRes); checkStatus();
    pos = 0;
    while (true) {
      if (pos >= UtilsAVR::MCU_MODEL_BUFFER_SIZE) {// too long MCU_MODEL in conf file!
        mcuModel[UtilsAVR::MCU_MODEL_BUFFER_SIZE-1] = '\0';
        returnStatus(ERR(0x23));
      }
      
      if (!_confFile.available()) {
        logDebug("!EOF");
        returnStatus(ERR(0x22)); // unexpected EOF
      }
      mcuModel[pos] = readCharSafe(eol, statusRes); checkStatus();
      if (eol) {
        logDebug("!EOL");
        returnStatus(ERR(0x22)); // unexpected EOL
      }
      if (isWhiteChar(mcuModel[pos])) {
        mcuModel[pos] = '\0';
        break;
      }
      pos++;
    }

    logDebugD("step3:",pos);
    
    // read FILE_PATH
    skipWhiteCharactersExpectNoEolNoEof(statusRes); checkStatus();
    pos = 0;
    while (true) {
      if (pos >= Utils::FILE_PATH_BUFFER_SIZE) {// too long FILE_PATH in conf file!
        filePath[Utils::FILE_PATH_BUFFER_SIZE-1] = '\0';
        returnStatus(ERR(0x24));
      }
      
      if (!_confFile.available()) {
        logDebug("!EOF");
        returnStatus(ERR(0x22)); // unexpected EOF
      }
      filePath[pos] = readCharSafe(eol, statusRes); checkStatus();
      if (eol || isWhiteChar(filePath[pos])) {
        filePath[pos] = '\0';
        break;
      }
      pos++;
    }

    logDebugD("step4:",pos);
    
    // Skip this line and proceed to next line
    _skipLine: skipLine(statusRes); checkStatus(); // skip the line, and continue to next one
  }
}
示例#22
0
// targetMcuSign - byte[3] with sign of MCU e.g. {0x1e,0x95,0x0f}
void ProgramFile::uploadMcuDataFromFile_internal(boolean progMode, String fileName, byte targetMcuModelId, byte* targetMcuSign,
                        byte progMemPagesCount, byte progMemPageSize,
                        byte eepromMemPagesCount, byte eepromMemPageSize, byte& statusRes) {
  File f;
  openFile2(f, fileName, FILE_READ, statusRes);
  checkOverrideStatus(ERR(0x51));

  
  byte lkb,fsb,fhb,efb;
  boolean isSign=false,isLkb=false,isFsb=false,isFhb=false,isEfb=false; // flag represents if any of this value is already loaded from ProgramFile
  
  boolean isSignValid = false; // if true - then signature is loaded from file and matches targetMcuSign provided for this method
  boolean startedProgramming = false; // if programming already started
  
  byte buf[LINE_READ_BUFFER_SIZE];
  byte lineType;
  int resSize, pageNo;
  while(f.available()) {
    resSize = pageNo = 0;
    readLine(f,lineType,buf,resSize,pageNo,statusRes);
    checkOverrideStatus(ERR(0x54)); // FIXME it is supposed to perform "goto f_close;" not return!
    logDebugB("Line type: ", lineType);
    logDebugD("Res size: ", resSize);
    logDebugD("PageNo: ", pageNo);
    logDebugB("buf[0]: ", buf[0]);
    logDebugB("buf[1]: ", buf[1]);
    
    // verify buffer result
    if (lineType == LINE_TYPE_PRM) {
      if (resSize != (1 << (progMemPageSize + 1))) {
        logDebugD("resSize bad:",resSize);
        returnStatus(ERR(0x54));
      }
      if (pageNo >= (1 << progMemPagesCount)) {
        logDebugD("pageNo bad:", pageNo);
        returnStatus(ERR(0x54));
      }
    } else if (lineType == LINE_TYPE_ERM) {
      if (resSize != (1 << eepromMemPageSize)) {
        logDebugD("EEPROM resSize bad:", resSize);
        returnStatus(ERR(0x54));
      }
      if (pageNo >= (1 << eepromMemPagesCount)) {
        logDebugD("EEPROM pageNo bad:", pageNo);
        returnStatus(ERR(0x54));
      }
    }
    
    // TODO Implement lineType: ERS - if is set to true - will Erase whole chip before programming!
    if (lineType == LINE_TYPE_PRM) {
      startedProgramming = true;
      if (!isSignValid) { logDebug("!isSignValid_1"); returnStatus(ERR(0x54)); }
      if (progMode && (pageNo < 5)) {//FIXME something wrong here, it must work for all pages
        logInfoD("PRM Page!",pageNo);
        AVRProgrammer::loadAndWriteProgramMemoryPage(buf, resSize, pageNo, targetMcuModelId, statusRes);
        checkStatus();
      }
    } else if (lineType == LINE_TYPE_ERM) {
      startedProgramming = true;
      if (!isSignValid) { logDebug("!isSignValid_2"); returnStatus(ERR(0x54)); }
      if (progMode) {
        logInfoD("ERM Page!",pageNo);
      }
    } else if (lineType == LINE_TYPE_SGN) {
      if (isSign || startedProgramming) { logDebug("isSign||startedProg"); returnStatus(ERR(0x54)); }
      isSign = true;
      isSignValid = true;
      for (byte i = 0; i < 3; i++) isSignValid = (targetMcuSign[i] == buf[i]) && isSignValid;
    } else if (lineType == LINE_TYPE_LKB) {
      if (isLkb || startedProgramming) { logDebug("isLkb||startedProg"); returnStatus(ERR(0x54)); }
      isLkb = true;
      lkb = buf[0];
    } else if (lineType == LINE_TYPE_FSB) {
      if (isFsb || startedProgramming) { logDebug("isLkb||startedProg"); returnStatus(ERR(0x54)); }
      isFsb = true;
      fsb = buf[0];
    } else if (lineType == LINE_TYPE_FHB) {
      if (isFhb || startedProgramming) { logDebug("isFhb||startedProg"); returnStatus(ERR(0x54)); }
      isFhb = true;
      fhb = buf[0];
    } else if (lineType == LINE_TYPE_EFB) {
      if (isEfb || startedProgramming) { logDebug("isEfb||startedProg"); returnStatus(ERR(0x54)); }
      isEfb = true;
      efb = buf[0];
    }
  }
  
  // now lets programm fuses and lock bits
  if (!isSignValid) { logDebug("!isSignValid_3"); returnStatus(ERR(0x54)); }; // before programming fuses we must check signature
  if (isFsb && progMode) {
    logInfoB("FSB!",fsb);
    // TODO Implement this!
  }
  if (isFhb && progMode) {
    logInfoB("FHB!",fhb);
    // TODO Implement this!
  }
  if (isEfb && progMode) {
    logInfoB("EFB!",efb);
    // TODO Implement this!
  }
  if (isLkb && progMode) { // lock bits should be programmed last!
    logInfoB("LKB!",lkb);
    // TODO Implement this!
  }
  
  AVRProgrammer::waitForTargetMCU(statusRes); // wait for last operation to finish
  
  f_close: f.close(); return;
  //f_error: statusRes = ERR(0x50); goto f_close;
}