def upload(self, filePath):

        flashPageSize = 128
        self.resolve_target()


        reader = HexFileFormat(filePath)
        lines = reader.get_bytes()

        startAddress, foo = lines[0]
        toWrite = bytearray()

        for (address, data) in lines:
            toWrite += data
        length = len(toWrite)

        programmer = AvrIspFlow(self.xbee)

        print("configuring target addresses")

        self.configure_target()

        try:
            print("resetting target")
            self.reset_target()
            programmer.getTargetParameters()
            print("beginning programming sequence")
            programmer.enterProgMode()
            print("ready for upload")

            pagesToWrite = length / flashPageSize
            if pagesToWrite > int(pagesToWrite):
                pagesToWrite = int(pagesToWrite) + 1        
            for pageNo in range(0, int(pagesToWrite)):
                startByte = pageNo*flashPageSize
                page = toWrite[startByte:startByte+flashPageSize]
                if len(page) < flashPageSize:
                    for i in range(flashPageSize - len(page)):
                        page += b'\xFF'
                programmer.writeRomPage(startAddress + startByte, page)

            programmer.leaveProgMode()

            print("Verifying %d bytes beginning with start address 0x%x" % (length, startAddress))
            readPages = bytearray()
            readPageSize = 128
            readPageNo = length / readPageSize
            readPageWholeNo = int(readPageNo) +1
            for i in range(0, readPageWholeNo):
                readPages += programmer.readRomPage(startAddress + i*readPageSize, readPageSize)

            readPages = readPages[:length]

            if readPages != toWrite:
                raise Exception("Failed validation")

        finally:
            self.restore_target()

        pass
    def download(self, startAddress, length, filePath):
        pageSize = min(248, length)
        data = bytearray()
        address = startAddress
        pages = int(length / pageSize)

        programmer = AvrIspFlow(self.xbee)
        
        self.resolve_target()
        self.reset_target()
        programmer.getTargetParameters()

        for i in range(0, pages):
            dataPage = programmer.readRomPage(address, pageSize)
            if len(dataPage) < pageSize:
                raise Exception("Read less bytes than the expected page size")
            data += dataPage
            address += pageSize

        if pages * pageSize < length:
            remainder = length - pages * pageSize
            print("reading remainder " + str(remainder))
            data += programmer.readRomPage(address, remainder)

        self.restore_target()

        writer = HexFileFormat(filePath)
        writer.save_bytes(data, startAddress)