예제 #1
0
void JobInfo::doDeviceDependent( AVRProgrammer * prog, AVRDevice * avr )
{
	HEXFile * hex;
	HEXFile * hex_v; // Used for verifying memory contents.
	long pos; // Used when comparing data.
	long bits; // Used for lock and fuse bits.

	/* Set programmer pagesize */
	prog->setPagesize( avr->getPageSize() );

	/* Check if specified address limits are within device range */
	if( flashEndAddress != -1 )
	{
		if( flashEndAddress >= avr->getFlashSize() )
			throw new ErrorMsg( "Specified Flash address range is outside device address space!" );
	} else
	{
		flashStartAddress = 0;
		flashEndAddress = avr->getFlashSize() - 1;
	}

	if( eepromEndAddress != -1 )
	{
		if( eepromEndAddress >= avr->getEEPROMSize() )
			throw new ErrorMsg( "Specified EEPROM address range is outside device address space!" );
	} else
	{
		eepromStartAddress = 0;
		eepromEndAddress = avr->getEEPROMSize() - 1;
	}


	/* Read out Flash contents? */
	if( readFlash )
	{
		/* Check that filename has been specified */
		if( outputFileFlash.size() == 0 )
			throw new ErrorMsg( "Cannot read Flash without output file specified!" );

		/* Prepare the file */
		hex = new HEXFile( avr->getFlashSize() );
		hex->setUsedRange( flashStartAddress, flashEndAddress );

		/* Read data and save file */
		Util.log( "Reading Flash contents...\r\n" );
		if( !prog->readFlash( hex ) )
			throw new ErrorMsg( "Flash readout is not supported by this programmer!" );
		Util.log( "Writing HEX output file...\r\n" );
		hex->writeFile( outputFileFlash );

		delete hex;
	}


	/* Read out EEPROM contents? */
	if( readEEPROM )
	{
		/* Check that filename has been specified */
		if( outputFileEEPROM.size() == 0 )
			throw new ErrorMsg( "Cannot read EEPROM without output file specified!" );

		/* Prepare the file */
		hex = new HEXFile( avr->getEEPROMSize() );
		hex->setUsedRange( eepromStartAddress, eepromEndAddress );

		/* Read data and save file */
		Util.log( "Reading EEPROM contents...\r\n" );
		if( !prog->readEEPROM( hex ) )
			throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" );
		Util.log( "Writing HEX output file...\r\n" );
		hex->writeFile( outputFileEEPROM );

		delete hex;
	}


	/* Read lock bits? */
	if( readLockBits )
	{
		Util.log( "Reading lock bits...\r\n" );
		if( !prog->readLockBits( &bits ) )
			throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" );
		cout << "0x" << std::hex << setw(2) << bits << endl;
	}


	/* Read fuse bits (both ordinary and extended)? */
	if( readFuseBits )
	{
		if( !avr->getFuseStatus() )
			throw new ErrorMsg( "Selected device has no fuse bits!" );

		Util.log( "Reading fuse bits...\r\n" );
		if( !prog->readFuseBits( &bits ) )
			throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" );
		cout << "0x" << std::hex << setw(4) << bits << endl;

		if( avr->getXFuseStatus() )
		{
			if( !prog->readExtendedFuseBits( &bits ) )
				throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" );
			cout << "0x" << std::hex << setw(2) << bits << endl;
		}
	}


	/* Erase chip before programming anything? */
	if( chipErase )
	{
		Util.log( "Erasing chip contents...\r\n" );
		if( !prog->chipErase() )
			throw new ErrorMsg( "Chip erase is not supported by this programmer!" );
	}


	/* Prepare input hex file for flash */
	if( programFlash || verifyFlash )
	{
		/* Check that filename has been specified */
		if( inputFileFlash.size() == 0 )
			throw new ErrorMsg( "Cannot program or verify Flash without input file specified!" );

		/* Prepare the file */
		hex = new HEXFile( avr->getFlashSize() );

		/* Fill if wanted */
		if( memoryFillPattern != -1 )
			hex->clearAll( memoryFillPattern );

		/* Read file */
		Util.log( "Reading HEX input file for flash operations...\r\n" );
		hex->readFile( inputFileFlash );

		/* Check limits */
		if( hex->getRangeStart() > flashEndAddress ||
				hex->getRangeEnd() < flashStartAddress )
			throw new ErrorMsg( "HEX file defines data outside specified range!" );

		if( memoryFillPattern == -1 )
		{
			if( hex->getRangeStart() > flashStartAddress )
				flashStartAddress = hex->getRangeStart();

			if( hex->getRangeEnd() < flashEndAddress )
				flashEndAddress = hex->getRangeEnd();
		}

		hex->setUsedRange( flashStartAddress, flashEndAddress );
	}


	/* Program new Flash contents? */
	if( programFlash )
	{
		/* Program data */
		Util.log( "Programming Flash contents...\r\n" );
		if( !prog->writeFlash( hex ) )
			throw new ErrorMsg( "Flash programming is not supported by this programmer!" );
	}


	/* Verify Flash contents? */
	if( verifyFlash )
	{
		/* Prepare HEX file for comparision */
		hex_v = new HEXFile( avr->getFlashSize() );

		/* Compare to Flash */
		Util.log( "Reading Flash contents...\r\n" );
		hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() );
		if( !prog->readFlash( hex_v ) )
			throw new ErrorMsg( "Flash readout is not supported by this programmer!" );

		/* Compare data */
		Util.log( "Comparing Flash data...\r\n" );

		for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ )
		{
			if( hex->getData( pos ) != hex_v->getData( pos ) )
			{
				cout << "Unequal at address 0x" << std::hex << pos << "!" << endl;
				break;
			}
		}

		if( pos > hex->getRangeEnd() ) // All equal?
		{
			cout << "Equal!" << endl;
		}

		delete hex_v;
	}

	if( programFlash || verifyFlash )
		delete hex;


	/* Prepare input hex file for EEPROM */
	if( programEEPROM || verifyEEPROM )
	{
		/* Check that filename has been specified */
		if( inputFileEEPROM.size() == 0 )
			throw new ErrorMsg( "Cannot program or verify EEPROM without input file specified!" );

		/* Prepare the file */
		hex = new HEXFile( avr->getEEPROMSize() );

		/* Fill if wanted */
		if( memoryFillPattern != -1 )
			hex->clearAll( memoryFillPattern );

		/* Read file and program contents */
		Util.log( "Reading HEX input file for EEPROM operations...\r\n" );
		hex->readFile( inputFileEEPROM );

		/* Check limits */
		if( hex->getRangeStart() > eepromEndAddress ||
				hex->getRangeEnd() < eepromStartAddress )
			throw new ErrorMsg( "HEX file defines data outside specified range!" );

		if( memoryFillPattern == -1 )
		{
			if( hex->getRangeStart() > eepromStartAddress )
				eepromStartAddress = hex->getRangeStart();

			if( hex->getRangeEnd() < eepromEndAddress )
				eepromEndAddress = hex->getRangeEnd();
		}

		hex->setUsedRange( eepromStartAddress, eepromEndAddress );
	}


	/* Program new EEPROM contents? */
	if( programEEPROM )
	{
		/* Program data */
		Util.log( "Programming EEPROM contents...\r\n" );
		if( !prog->writeEEPROM( hex ) )
			throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" );
	}

	/* Verify EEPROM contents? */
	if( verifyEEPROM )
	{
		/* Prepare HEX file for comparision */
		hex_v = new HEXFile( avr->getEEPROMSize() );

		/* Compare to EEPROM */
		Util.log( "Reading EEPROM contents...\r\n" );
		hex_v->setUsedRange( hex->getRangeStart(), hex->getRangeEnd() );
		if( !prog->readEEPROM( hex_v ) )
			throw new ErrorMsg( "EEPROM readout is not supported by this programmer!" );

		/* Compare data */
		Util.log( "Comparing EEPROM data...\r\n" );
		for( pos = hex->getRangeStart(); pos <= hex->getRangeEnd(); pos++ )
		{
			if( hex->getData( pos ) != hex_v->getData( pos ) )
			{
				cout << "Unequal at address 0x" << std::hex << pos << "!" << endl;
				break;
			}
		}

		if( pos > hex->getRangeEnd() ) // All equal?
		{
			cout << "Equal!" << endl;
		}

		delete hex_v;
	}

	if( programEEPROM || verifyEEPROM )
		delete hex;


	/* Program lock bits */
	if( programLockBits != -1 )
	{
		Util.log( "Programming lock bits...\r\n" );
		if( !prog->writeLockBits( programLockBits ) )
			throw new ErrorMsg( "Lock bit programming is not supported by this programmer!" );
	}


	/* Program fuse bits */
	if( programFuseBits != -1 )
	{
		if( !avr->getFuseStatus() )
			throw new ErrorMsg( "Selected device has no fuse bits!" );

		Util.log( "Programming fuse bits...\r\n" );
		if( !prog->writeFuseBits( programFuseBits ) )
			throw new ErrorMsg( "Fuse bit programming is not supported by this programmer!" );
	}


	/* Program extended fuse bits */
	if( programExtendedFuseBits != -1 )
	{
		if( !avr->getXFuseStatus() )
			throw new ErrorMsg( "Selected device has no extended fuse bits!" );

		Util.log( "Programming extended fuse bits...\r\n" );
		if( !prog->writeExtendedFuseBits( programExtendedFuseBits ) )
			throw new ErrorMsg( "Extended fuse bit programming is not supported by this programmer!" );
	}


	/* Verify lock bits */
	if( verifyLockBits != -1 )
	{
		Util.log( "Verifying lock bits...\r\n" );
		if( !prog->readLockBits( &bits ) )
			throw new ErrorMsg( "Lock bit readout is not supported by this programmer!" );
		if( bits == verifyLockBits )
			cout << "Equal!" << endl;
		else
			cout << "Unequal!" << endl;
	}


	/* Verify fuse bits */
	if( verifyFuseBits != -1 )
	{
		if( !avr->getFuseStatus() )
			throw new ErrorMsg( "Selected device has no fuse bits!" );

		Util.log( "Verifying fuse bits...\r\n" );
		if( !prog->readFuseBits( &bits ) )
			throw new ErrorMsg( "Fuse bit readout is not supported by this programmer!" );
		if( bits == verifyFuseBits )
			cout << "Equal!" << endl;
		else
			cout << "Unequal!" << endl;
	}


	/* Verify extended fuse bits */
	if( verifyExtendedFuseBits != -1 )
	{
		if( !avr->getXFuseStatus() )
			throw new ErrorMsg( "Selected device has no extended fuse bits!" );

		Util.log( "Verifying extended fuse bits...\r\n" );
		if( !prog->readExtendedFuseBits( &bits ) )
			throw new ErrorMsg( "Extended fuse bit readout is not supported by this programmer!" );
		if( bits == verifyExtendedFuseBits )
			cout << "Equal!" << endl;
		else
			cout << "Unequal!" << endl;
	}


	/* Read osccal value? */
	if( OSCCAL_Parameter != -1 )
	{
		/* Output to log if read from device */
		if( readOSCCAL )
		{
			Util.log( "Reading OSCCAL from device...\r\n" );
			pos = OSCCAL_Parameter;
			if( !prog->readOSCCAL( pos, &OSCCAL_Parameter ) )
				throw new ErrorMsg( "OSCCAL parameter readout is not supported by this programmer!" );
			cout << "0x" << std::hex << setw(2) << OSCCAL_Parameter << endl;
		}
	}


	/* Write OSCCAL to Flash? */
	if( OSCCAL_FlashAddress != -1 )
	{
		if( OSCCAL_Parameter == -1 )
			throw new ErrorMsg( "OSCCAL value not specified!" );

		Util.log( "Programming OSCCAL value to Flash...\r\n" );
		if( !prog->writeFlashByte( OSCCAL_FlashAddress, OSCCAL_Parameter ) )
			throw new ErrorMsg( "Flash programming is not supported by this programmer!" );
	}


	/* Write OSCCAL to EEPROM? */
	if( OSCCAL_EEPROMAddress != -1 )
	{
		if( OSCCAL_Parameter == -1 )
			throw new ErrorMsg( "OSCCAL value not specified!" );

		Util.log( "Programming OSCCAL value to EEPROM...\r\n" );
		if( !prog->writeEEPROMByte( OSCCAL_EEPROMAddress, OSCCAL_Parameter ) )
			throw new ErrorMsg( "EEPROM programming is not supported by this programmer!" );
	}

}
예제 #2
0
void TKN_NodeBox::hexUpload()
{
    int page=0;
    int word=0;
    int byteCount=0;
    long start, end, addr;
    TKN_Data recData;
    BYTE sendData[TKN_DATA_SIZE];
    BYTE byteForEmpty = 0xff;
    QString recString;

    HEXFile *h;

    try {
        h = new HEXFile(1024*1024, byteForEmpty);
        h->readFile(ui->lineEditHexFilePath->text().toStdString());
    } catch(ErrorMsg *err) {
        emit consoleOut(QString::fromStdString(err->What()));
        return;
    }

    start = h->getRangeStart();
    end   = h->getRangeEnd();

    for (addr=start; addr<= end; ) {
        /* Initiate a boot procedure */
        memset(sendData, 0, TKN_DATA_SIZE);
        strcpy ((char*)sendData, "B:");
        sendData[3] = addr/(PAGESIZE*2);

        /* Flush any data from receive queue */
        flushRecDataQueue();

        while (TKN_PushData ((TKN_Data *) sendData, NODE_ID));

        /* Wait MCU */
        do {
            if ( !dataDeque(&recData, 1500)) {
                emit consoleOut("MCU Busy, aborting.");
                return;
            }
            recString = QString(QByteArray((char*)&recData, sizeof(TKN_Data)));
        } while ( QString::compare(QString("-MCU-READY------"), recString));

        emit consoleOut(QString("Sending Page: ") + QString ('0'+sendData[3]));

        /* Send a complete page */
        do {
            /* Fill a TKN Packet */
            for (int i=0; i<sizeof(TKN_Data); i++){
                sendData[i] = addr<=end? ((BYTE) h->getData(addr)): byteForEmpty;
                byteCount++;
                addr++;
            }

            /* Send it to tha MCU */
            while (TKN_PushData ((TKN_Data *) sendData, NODE_ID));

        } while ((addr % (PAGESIZE*2)!=0) );

    }

    QString msg = QString("Hex upload complete. Sent ") + QString::number(byteCount) + QString(" bytes.");
    emit consoleOut(msg);
}