示例#1
0
    def read_eeprom_block(self, hex_file):

        # Get block size assuming the 'b' command was just ack'ed with a 'Y'
        block_size = (ord(self.__port.read(1)) << 8) | ord(self.__port.read(1))

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        address = start
        while address <= end:
            byte_count = block_size
            if (address + byte_count - 1) > end:
                byte_count = end - address + 1

            self.set_address(address)

            self.__port.write('g')
            self.__port.write(chr((byte_count >> 8) & 0xff))
            self.__port.write(chr(byte_count & 0xff))
            self.__port.write('E')

            while byte_count > 0:
                hex_file.set_data(address, self.__port.read(1))

                address += 1
                byte_count -= 1

            avrlog.progress('.')

        avrlog.progress('\n')

        return True
示例#2
0
    def write_file(self, file_name):

        fp = open(file_name, 'w')

        rec = EncryptedHexRecord()
        rec.set_length(2)
        rec.set_offset(0)
        rec.set_type(0x02)
        rec._data[1] = 0x00
        rec._data[0] = self.__base_address >> 12
        self._write_record(fp, rec)

        for rec_oset in self.__keys():
            rec = self.__records[rec_oset]
            self._write_record(fp, rec)

            if data_pos % 256 == 0:
                avrlog.progress('.')

        # write EOF record
        rec.set_length(0)
        rec.set_offset(0)
        rec.set_type(0x01)

        self._write_record(fp, rec)

        fp.close()
        avrlog.progress('\n')
示例#3
0
	def read_eeprom_block(self, hex_file):

		# Get block size assuming the 'b' command was just ack'ed with a 'Y'
		block_size = (ord(self.__port.read(1)) << 8) | ord(self.__port.read(1))

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		address = start
		while address <= end:
			byte_count = block_size
			if (address + byte_count - 1) > end:
				byte_count = end - address + 1

			self.set_address(address)

			self.__port.write('g')
			self.__port.write(chr((byte_count >> 8) & 0xff))
			self.__port.write(chr(byte_count & 0xff))
			self.__port.write('E')

			while byte_count > 0:
				hex_file.set_data(address, self.__port.read(1))

				address += 1
				byte_count -= 1

			avrlog.progress('.')

		avrlog.progress('\n')

		return True
示例#4
0
    def write_flash(self, hex_file):

        if self.__page_size == -1:
            raise RuntimeError('Programmer page size not set!')

        self.__port.write('b')
        self.__port.flush()

        if self.__port.read(1) == 'Y':
            avrlog.avrlog(avrlog.LOG_DEBUG, 'Using block mode...')
            return self.write_flash_block(hex_file)

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        # check autoincrement support
        self.__port.write('a')
        self.__port.flush()

        autoincrement = False
        if self.__port.read(1) == 'Y':
            autoincrement = true

        self.set_address(start >> 1)  # flash operations use word addresses

        address = start
        if address & 1:
            self.write_flash_low_byte(0xff)
            self.write_flash_high_byte(hex_file.get_data(address))
            address += 1
            if address % self.__page_size == 0 or address > end:
                self.set_address((address - 2) >> 1)
                self.write_flash_page()
                self.set_address(address >> 1)

        while (end - address + 1) >= 2:
            if not autoincrement:
                self.set_address(address >> 1)
            self.write_flash_low_byte(hex_file.get_data(address))
            self.write_flash_high_byte(hex_file.get_data(address + 1))
            address += 2

            if address % 256 == 0:
                avrlog.progress('.')

            if address % self.__page_size == 0 or address > end:
                self.set_address((address - 2) >> 1)
                self.write_flash_page()
                self.set_address(address >> 1)

        if address == end:
            self.write_flash_low_byte(hex_file.get_data(address))
            self.write_flash_high_byte(0xff)
            address += 2
            self.set_address((address - 2) >> 1)
            self.write_flash_page()

        avrlog.progress('\n')
        return True
示例#5
0
	def write_flash(self, hex_file):

		if self.__page_size == -1:
			raise RuntimeError('Programmer page size not set!')

		self.__port.write('b')
		self.__port.flush()

		if self.__port.read(1) == 'Y':
			avrlog.avrlog(avrlog.LOG_DEBUG, 'Using block mode...')
			return self.write_flash_block(hex_file)

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		# check autoincrement support
		self.__port.write('a')
		self.__port.flush()

		autoincrement = False
		if self.__port.read(1) == 'Y':
			autoincrement = true

		self.set_address(start >> 1)	# flash operations use word addresses

		address = start
		if address & 1:
			self.write_flash_low_byte(0xff)
			self.write_flash_high_byte(hex_file.get_data(address))
			address += 1
			if address % self.__page_size == 0 or address > end:
				self.set_address((address - 2) >> 1)
				self.write_flash_page()
				self.set_address(address >> 1)

		while (end - address + 1) >= 2:
			if not autoincrement:
				self.set_address(address >> 1)
			self.write_flash_low_byte(hex_file.get_data(address))
			self.write_flash_high_byte(hex_file.get_data(address + 1))
			address += 2

			if address % 256 == 0:
				avrlog.progress('.')

			if address % self.__page_size == 0 or address > end:
				self.set_address((address - 2) >> 1)
				self.write_flash_page()
				self.set_address(address >> 1)

		if address == end:
			self.write_flash_low_byte(hex_file.get_data(address))
			self.write_flash_high_byte(0xff)
			address += 2
			self.set_address((address - 2) >> 1)
			self.write_flash_page()

		avrlog.progress('\n')
		return True
示例#6
0
	def read_flash(self, hex_file):

		if self.__page_size == -1:
			raise RuntimeError('Programmer page size is not set.')

		self.__port.write('b')
		self.__port.flush()

		if self.__port.read(1) == 'Y':
			avrlog.avrlog(avrlog.LOG_DEBUG, 'Read flash: using block mode...')
			return self.read_flash_block(hex_file)

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		self.__port.write('a')
		self.__port.flush()

		auto_increment = False
		if self.__port.read(1) == 'Y':
			auto_increment = True

		self.set_address(start >> 1)

		address = start
		if address & 1:
			self.__port.write('R')
			self.__port.flush()

			hex_file.set_data(address, self.__port.read(1))		# High byte
			self.__port.read(1)									# Don't use low byte
			address += 1

		while (end - address + 1) >= 2:
			if not auto_increment:
				self.set_address(address >> 1)

			self.__port.write('R')
			self.__port.flush()

			hex_file.set_data(address + 1, self.__port.read(1))
			hex_file.set_data(address, self.__port.read(1))
			address += 2
			
			if address % 256 == 0:
				avrlog.progress('.')

		if address == end:
			self.__port.write('R')
			self.__port.flush()

			self.__port.read(1)
			hex_file.set_data(address, self.__port.read(1))

		avrlog.progress('\n')
示例#7
0
    def read_flash(self, hex_file):

        if self.__page_size == -1:
            raise RuntimeError('Programmer page size is not set.')

        self.__port.write('b')
        self.__port.flush()

        if self.__port.read(1) == 'Y':
            avrlog.avrlog(avrlog.LOG_DEBUG, 'Read flash: using block mode...')
            return self.read_flash_block(hex_file)

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        self.__port.write('a')
        self.__port.flush()

        auto_increment = False
        if self.__port.read(1) == 'Y':
            auto_increment = True

        self.set_address(start >> 1)

        address = start
        if address & 1:
            self.__port.write('R')
            self.__port.flush()

            hex_file.set_data(address, self.__port.read(1))  # High byte
            self.__port.read(1)  # Don't use low byte
            address += 1

        while (end - address + 1) >= 2:
            if not auto_increment:
                self.set_address(address >> 1)

            self.__port.write('R')
            self.__port.flush()

            hex_file.set_data(address + 1, self.__port.read(1))
            hex_file.set_data(address, self.__port.read(1))
            address += 2

            if address % 256 == 0:
                avrlog.progress('.')

        if address == end:
            self.__port.write('R')
            self.__port.flush()

            self.__port.read(1)
            hex_file.set_data(address, self.__port.read(1))

        avrlog.progress('\n')
示例#8
0
    def read_file(self, file_name):

        fp = open(file_name, 'r')
        base_address = 0
        self.__start = self.__size
        self.__end = 0
        lines = fp.readlines()
        for line in lines:

            avrlog.progress('.')

            rec = self._parse_record(line.strip())
            if rec.get_type() == 0x00:
                if (base_address + rec.get_offset() +
                        rec.get_length()) > self.__size:
                    raise RuntimeError(
                        'Hex file defines data outside buffer limits.')

                for data_pos in range(0, rec.get_length()):
                    self.__data[base_address + rec.get_offset() +
                                data_pos] = rec._data[data_pos]

                if base_address + rec.get_offset() < self.__start:
                    self.__start = base_address + rec.get_offset()

                if base_address + rec.get_offset() + rec.get_length(
                ) > self.__end:
                    self.__end = base_address + rec.get_offset(
                    ) + rec.get_length() - 1

            elif rec.get_type() == 0x01:
                fp.close()
                avrlog.progress('\n')
                return
            elif rec.get_type() == 0x02:
                base_address = (rec._data[0] << 8) | rec._data[1]
                base_address <<= 4
            elif rec.get_type() == 0x03:
                pass
            elif rec.get_type() == 0x04:
                base_address = (rec._data[0] << 8) | rec._data[1]
                base_address <<= 16
            elif rec.get_type() == 0x05:
                pass
            else:
                raise RuntimeError(
                    'Incorrect Hex file format, unsupported format. ' +
                    'Line from file (%s)' % (hex_line))

        raise RuntimeError('Premature EOF encountered. ' +
                           'Make sure file contains an EOF record.')
示例#9
0
	def write_eeprom(self, hex_file):

		self.__port.write('b')
		self.__port.flush()

		if self.__port.read(1) == 'Y':
			avrlog.avrlog(avrlog.LOG_DEBUG, 'Write EEPROM using block mode...')

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		self.__port.write('a')
		self.__port.flush()

		auto_increment = False
		if self.__port.read(1) == 'Y':
			auto_increment = True

		self.set_address(start)

		address = start
		while address <= end:

			if not auto_increment:
				self.set_address(address)

			self.__port.write('D')
			self.__port.write(hex_file.get_data(address))
			self.__port.flush()

			if self.__port.read(1) != '\r':
				raise RuntimeError('Writing byte to EEPROM failed! ' +
				                   'Programmer did not ack command.')
			if address % 256 == 0:
				avrlog.progress('.')

			address += 1

		avrlog.progress('\n')

		return True
示例#10
0
    def write_eeprom(self, hex_file):

        self.__port.write('b')
        self.__port.flush()

        if self.__port.read(1) == 'Y':
            avrlog.avrlog(avrlog.LOG_DEBUG, 'Write EEPROM using block mode...')

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        self.__port.write('a')
        self.__port.flush()

        auto_increment = False
        if self.__port.read(1) == 'Y':
            auto_increment = True

        self.set_address(start)

        address = start
        while address <= end:

            if not auto_increment:
                self.set_address(address)

            self.__port.write('D')
            self.__port.write(hex_file.get_data(address))
            self.__port.flush()

            if self.__port.read(1) != '\r':
                raise RuntimeError('Writing byte to EEPROM failed! ' +
                                   'Programmer did not ack command.')
            if address % 256 == 0:
                avrlog.progress('.')

            address += 1

        avrlog.progress('\n')

        return True
示例#11
0
	def read_eeprom(self, hex_file):

		self.__port.write('b')
		self.__port.flush()

		if self.__port.read(1) == 'Y':
			avrlog.avrlog(avrlog.LOG_DEBUG, 'Read EEPROM: using block mode...')
			return self.read_eeprom_block(hex_file)

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		self.__port.write('a')
		self.__port.flush()

		auto_increment = False
		if self.__port.read(1) == 'Y':
			auto_increment = True

		self.set_address(start)

		address = start
		while address <= end:
			if not auto_increment:
				self.set_address(address)

			self.__port.write('d')
			self.__port.flush()

			hex_file.set_data(address, self.__port.read(1))

			if address % 256 == 0:
				avrlog.progress('.')

			address += 1

		avrlog.progress('\n')

		return True
示例#12
0
    def read_eeprom(self, hex_file):

        self.__port.write('b')
        self.__port.flush()

        if self.__port.read(1) == 'Y':
            avrlog.avrlog(avrlog.LOG_DEBUG, 'Read EEPROM: using block mode...')
            return self.read_eeprom_block(hex_file)

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        self.__port.write('a')
        self.__port.flush()

        auto_increment = False
        if self.__port.read(1) == 'Y':
            auto_increment = True

        self.set_address(start)

        address = start
        while address <= end:
            if not auto_increment:
                self.set_address(address)

            self.__port.write('d')
            self.__port.flush()

            hex_file.set_data(address, self.__port.read(1))

            if address % 256 == 0:
                avrlog.progress('.')

            address += 1

        avrlog.progress('\n')

        return True
示例#13
0
	def write_eeprom_block(self, hex_file):

		# Get block size assuming the 'b' command was just ack'ed with a 'Y'
		block_size = (self.__port.read(1) << 8) | self.__port.read(1)

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		address = start
		while address <= end:
			byte_count = block_size
			if (address + byte_count - 1) > end:
				byte_count = end - address + 1

			self.set_address(address)

			self.__port.write('B')
			self.__port.write(chr((byte_count >> 8) & 0xff))
			self.__port.write(chr(byte_count & 0xff))
			self.__port.write('E')

			while byte_count > 0:
				self.__port.write(hex_file.get_data(address))
				self.__port.flush()

				address += 1
				byte_count -= 1

			if self.__port.read(1) != '\r':
				raise RuntimeError('Writing EEPROM block failed! ' +
				                   'Programmer did not ack B..E command.')

			avrlog.progress('.')

		avrlog.progress('\n')

		return True
示例#14
0
    def write_eeprom_block(self, hex_file):

        # Get block size assuming the 'b' command was just ack'ed with a 'Y'
        block_size = (self.__port.read(1) << 8) | self.__port.read(1)

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        address = start
        while address <= end:
            byte_count = block_size
            if (address + byte_count - 1) > end:
                byte_count = end - address + 1

            self.set_address(address)

            self.__port.write('B')
            self.__port.write(chr((byte_count >> 8) & 0xff))
            self.__port.write(chr(byte_count & 0xff))
            self.__port.write('E')

            while byte_count > 0:
                self.__port.write(hex_file.get_data(address))
                self.__port.flush()

                address += 1
                byte_count -= 1

            if self.__port.read(1) != '\r':
                raise RuntimeError('Writing EEPROM block failed! ' +
                                   'Programmer did not ack B..E command.')

            avrlog.progress('.')

        avrlog.progress('\n')

        return True
示例#15
0
    def write_file(self, file_name):

        fp = open(file_name, 'w')

        base_address = self.__start & ~0xffff
        self._offset = self.__start & 0xffff

        rec = HexRecord()
        rec.set_length(2)
        rec.set_offset(0)
        rec.set_type(0x02)
        rec._data[1] = 0x00
        rec._data[0] = base_address >> 12
        self._write_record(fp, rec)

        rec = HexRecord()
        rec.set_length(self.__size)
        data_pos = 0
        while base_address + self._offset + data_pos <= self.__end:
            rec._data[data_pos] = self.__data[base_address + self._offset +
                                              data_pos]
            data_pos += 1

            # check if we need to write out the current data record
            #	reached 64k boundary or
            #	data record full or
            #	end of used range reached
            if self._offset + data_pos >= 0x10000 or \
               data_pos >= 16 or \
               base_address + self._offset + data_pos > self.__end:
                rec.set_length(data_pos)
                rec.set_offset(self._offset)
                rec.set_type(0x00)

                if data_pos % 256 == 0:
                    avrlog.progress('.')

                self._write_record(fp, rec)

                self._offset += data_pos
                data_pos = 0

            # check if we have passed a 64k boundary
            if self._offset + data_pos >= 0x10000:
                # update address pointers
                self._offset -= 0x10000
                base_address += 0x10000

                # write new base address record to hex file
                rec.set_length(2)
                rec.set_offset(0)
                rec.set_type(0x02)
                # give 4k page index
                rec._data[0] = base_address >> 12
                rec._data[1] = 0x00

                self._write_record(fp, rec)

        # write EOF record
        rec.set_length(0)
        rec.set_offset(0)
        rec.set_type(0x01)

        self._write_record(fp, rec)

        fp.close()
        avrlog.progress('\n')
示例#16
0
	def read_flash_block(self, hex_file):

		# Get block size assuming the 'b' command was just ack'ed with a 'Y'
		block_size = (ord(self.__port.read(1)) << 8) | ord(self.__port.read(1))

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		address = start
		if address & 1:
			self.set_address(address >> 1)		# Flash operations use word addresses

			self.__port.write('R')
			self.__port.flush()

			hex_file.set_data(address, self.__port.read(1))		# Save high byte
			self.__port.read(1)									# Skip low byte
			address += 1

		if (address % block_size) > 0:
			byte_count = block_size - (address % block_size)

			if (address + byte_count - 1) > end:
				byte_count = end - address + 1
				byte_count &= ~0x01

			if byte_count > 0:
				self.set_address(address >> 1)

				# Start Flash block read
				self.__port.write('g')
				self.__port.write(chr((byte_count >> 8) & 0xff))
				self.__port.write(chr(byte_count & 0xff))
				self.__port.write('F')

				while byte_count > 0:
					hex_file.set_data(address, self.__port.read(1))
					address += 1
					byte_count -= 1

				avrlog.progress('.')

		while (end - address + 1) >= block_size:
			byte_count = block_size

			self.set_address(address >> 1)

			# Start Flash block read
			self.__port.write('g')
			self.__port.write(chr((byte_count >> 8) & 0xff))
			self.__port.write(chr(byte_count & 0xff))
			self.__port.write('F')

			while byte_count > 0:
				hex_file.set_data(address, self.__port.read(1))
				address += 1
				byte_count -= 1

			avrlog.progress('.')

		if (end - address + 1) >= 1:
			byte_count = (end - address + 1)
			if byte_count & 1:
				byte_count += 1

			self.set_address(address >> 1)

			# Start Flash block read
			self.__port.write('g')
			self.__port.write(chr((byte_count >> 8) & 0xff))
			self.__port.write(chr(byte_count & 0xff))
			self.__port.write('F')

			while byte_count > 0:
				if address > end:
					self.__port.read(1)
				else:
					hex_file.set_data(address, self.__port.read(1))

				address += 1
				byte_count -= 1

			avrlog.progress('.')

		avrlog.progress('\n')

		return True
示例#17
0
	def write_flash_block(self, hex_file):

		# Get block size assuming the 'b' command was just ack'ed with a 'Y'
		block_size = (ord(self.__port.read(1)) << 8) | ord(self.__port.read(1))

		start = hex_file.get_range_start()
		end = hex_file.get_range_end()

		address = start
		if address & 1:
			self.set_address(address >> 1)		# Flash operations use word addresses

			# Use only high byte
			self.write_flash_low_byte(0xff)
			self.write_flash_high_byte(hex_file.get_data(address))
			address += 1

			if address % self.__page_size == 0 or address > end:
				self.set_address((address - 2) >> 1)
				self.write_flash_page()
				self.set_address(address >> 1)

		if (address % block_size) > 0:
			byte_count = block_size - (address & block_size)

			if (address + byte_count - 1) > end:
				byte_count = end - address + 1
				byte_count &= ~0x01				# Adjust to word count

			if byte_count > 0:
				self.set_address(address >> 1)

				self.__port.write('B')
				self.__port.write(chr((byte_count >> 8) & 0xff))
				self.__port.write(chr(byte_count & 0xff))
				self.__port.write('F')

				while byte_count > 0:
					self.__port.write(hex_file.get_data(address))
					address += 1
					byte_count -= 1

				if self.__port.read(1) != '\r':
					raise RuntimeError('Writing Flash block failed! ' +
					                   'Programmer did not return CR after B..F command')
				avrlog.progress('.')

		while (end - address + 1) >= block_size:

			byte_count = block_size

			self.set_address(address >> 1)

			self.__port.write('B')
			self.__port.write(chr((byte_count >> 8) & 0xff))
			self.__port.write(chr(byte_count & 0xff))
			self.__port.write('F')

			while byte_count > 0:
				self.__port.write(chr(hex_file.get_data(address)))
				address += 1
				byte_count -= 1

			if self.__port.read(1) != '\r':
				raise RuntimeError('Writing Flash block failed! ' +
				                   'Programmer did not return CR after B..F command')
			avrlog.progress('.')

		if (end - address + 1) >= 1:

			byte_count = (end - address + 1)
			if byte_count & 1:
				byte_count += 1

			self.set_address(address >> 1)

			self.__port.write('B')
			self.__port.write(chr((byte_count >> 8) & 0xff))
			self.__port.write(chr(byte_count & 0xff))
			self.__port.write('F')

			while byte_count > 0:
				if address > end:
					self.__port.write(chr(0xff))
				else:
					self.__port.write(chr(hex_file.get_data(address)))
				address += 1
				byte_count -= 1

			if self.__port.read(1) != '\r':
				raise RuntimeError('Writing Flash block failed! ' +
				                   'Programmer did not return CR after B..F command')
			avrlog.progress('.')

		avrlog.progress('\n')

		return True
示例#18
0
    def write_flash_block(self, hex_file):

        # Get block size assuming the 'b' command was just ack'ed with a 'Y'
        block_size = (ord(self.__port.read(1)) << 8) | ord(self.__port.read(1))

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        address = start
        if address & 1:
            self.set_address(
                address >> 1)  # Flash operations use word addresses

            # Use only high byte
            self.write_flash_low_byte(0xff)
            self.write_flash_high_byte(hex_file.get_data(address))
            address += 1

            if address % self.__page_size == 0 or address > end:
                self.set_address((address - 2) >> 1)
                self.write_flash_page()
                self.set_address(address >> 1)

        if (address % block_size) > 0:
            byte_count = block_size - (address & block_size)

            if (address + byte_count - 1) > end:
                byte_count = end - address + 1
                byte_count &= ~0x01  # Adjust to word count

            if byte_count > 0:
                self.set_address(address >> 1)

                self.__port.write('B')
                self.__port.write(chr((byte_count >> 8) & 0xff))
                self.__port.write(chr(byte_count & 0xff))
                self.__port.write('F')

                while byte_count > 0:
                    self.__port.write(hex_file.get_data(address))
                    address += 1
                    byte_count -= 1

                if self.__port.read(1) != '\r':
                    raise RuntimeError(
                        'Writing Flash block failed! ' +
                        'Programmer did not return CR after B..F command')
                avrlog.progress('.')

        while (end - address + 1) >= block_size:

            byte_count = block_size

            self.set_address(address >> 1)

            self.__port.write('B')
            self.__port.write(chr((byte_count >> 8) & 0xff))
            self.__port.write(chr(byte_count & 0xff))
            self.__port.write('F')

            while byte_count > 0:
                self.__port.write(chr(hex_file.get_data(address)))
                address += 1
                byte_count -= 1

            if self.__port.read(1) != '\r':
                raise RuntimeError(
                    'Writing Flash block failed! ' +
                    'Programmer did not return CR after B..F command')
            avrlog.progress('.')

        if (end - address + 1) >= 1:

            byte_count = (end - address + 1)
            if byte_count & 1:
                byte_count += 1

            self.set_address(address >> 1)

            self.__port.write('B')
            self.__port.write(chr((byte_count >> 8) & 0xff))
            self.__port.write(chr(byte_count & 0xff))
            self.__port.write('F')

            while byte_count > 0:
                if address > end:
                    self.__port.write(chr(0xff))
                else:
                    self.__port.write(chr(hex_file.get_data(address)))
                address += 1
                byte_count -= 1

            if self.__port.read(1) != '\r':
                raise RuntimeError(
                    'Writing Flash block failed! ' +
                    'Programmer did not return CR after B..F command')
            avrlog.progress('.')

        avrlog.progress('\n')

        return True
示例#19
0
    def read_flash_block(self, hex_file):

        # Get block size assuming the 'b' command was just ack'ed with a 'Y'
        block_size = (ord(self.__port.read(1)) << 8) | ord(self.__port.read(1))

        start = hex_file.get_range_start()
        end = hex_file.get_range_end()

        address = start
        if address & 1:
            self.set_address(
                address >> 1)  # Flash operations use word addresses

            self.__port.write('R')
            self.__port.flush()

            hex_file.set_data(address, self.__port.read(1))  # Save high byte
            self.__port.read(1)  # Skip low byte
            address += 1

        if (address % block_size) > 0:
            byte_count = block_size - (address % block_size)

            if (address + byte_count - 1) > end:
                byte_count = end - address + 1
                byte_count &= ~0x01

            if byte_count > 0:
                self.set_address(address >> 1)

                # Start Flash block read
                self.__port.write('g')
                self.__port.write(chr((byte_count >> 8) & 0xff))
                self.__port.write(chr(byte_count & 0xff))
                self.__port.write('F')

                while byte_count > 0:
                    hex_file.set_data(address, self.__port.read(1))
                    address += 1
                    byte_count -= 1

                avrlog.progress('.')

        while (end - address + 1) >= block_size:
            byte_count = block_size

            self.set_address(address >> 1)

            # Start Flash block read
            self.__port.write('g')
            self.__port.write(chr((byte_count >> 8) & 0xff))
            self.__port.write(chr(byte_count & 0xff))
            self.__port.write('F')

            while byte_count > 0:
                hex_file.set_data(address, self.__port.read(1))
                address += 1
                byte_count -= 1

            avrlog.progress('.')

        if (end - address + 1) >= 1:
            byte_count = (end - address + 1)
            if byte_count & 1:
                byte_count += 1

            self.set_address(address >> 1)

            # Start Flash block read
            self.__port.write('g')
            self.__port.write(chr((byte_count >> 8) & 0xff))
            self.__port.write(chr(byte_count & 0xff))
            self.__port.write('F')

            while byte_count > 0:
                if address > end:
                    self.__port.read(1)
                else:
                    hex_file.set_data(address, self.__port.read(1))

                address += 1
                byte_count -= 1

            avrlog.progress('.')

        avrlog.progress('\n')

        return True