class CrazyloadThread(QThread): # Input signals declaration (not sure it should be used like that...) program = pyqtSignal(str, bool) verify = pyqtSignal() initiateColdBootSignal = pyqtSignal(str) resetCopterSignal = pyqtSignal() writeConfigSignal = pyqtSignal(int, int, float, float) # Output signals declaration programmed = pyqtSignal() verified = pyqtSignal() statusChanged = pyqtSignal(str, int) connectedSignal = pyqtSignal() connectingSignal = pyqtSignal() failed_signal = pyqtSignal(str) disconnectedSignal = pyqtSignal() updateConfigSignal = pyqtSignal(int, int, float, float) updateCpuIdSignal = pyqtSignal(str) radioSpeedPos = 2 def __init__(self): super(CrazyloadThread, self).__init__() # Make sure that the signals are handled by this thread event loop self.moveToThread(self) self.program.connect(self.programAction) self.writeConfigSignal.connect(self.writeConfigAction) self.initiateColdBootSignal.connect(self.initiateColdBoot) self.resetCopterSignal.connect(self.resetCopter) self.loader = None self.link = None def __del__(self): self.quit() self.wait() def initiateColdBoot(self, linkURI): self.connectingSignal.emit() try: self.link = cflib.crtp.get_link_driver("radio://0/110") except Exception as e: self.failed_signal.emit(str(e)) if (self.link): self.loader = Cloader(self.link, "radio://0/110") if self.loader.coldboot(): logger.info("Connected in coldboot mode ok") self.updateCpuIdSignal.emit(self.loader.cpuid) self.readConfigAction() self.connectedSignal.emit() else: self.failed_signal.emit("Connection timeout") logger.info("Connected in coldboot mode failed") self.link.close() def programAction(self, filename, verify): logger.info("Flashing file [%s]", filename) f = open(filename, "rb") if not f: logger.warning("Cannot open file [%s]", filename) self.link.close() return image = f.read() f.close() self.loadAndFlash(image, verify) def checksum256(self, st): return reduce(lambda x, y: x + y, map(ord, st)) % 256 def writeConfigAction(self, channel, speed, rollTrim, pitchTrim): data = (0x00, channel, speed, pitchTrim, rollTrim) image = struct.pack("<BBBff", *data) # Adding some magic: image = "0xBC" + image image += struct.pack("B", 256 - self.checksum256(image)) self.loadAndFlash(image, True, 117) def readConfigAction(self): self.statusChanged.emit("Reading config block...", 0) data = self.loader.read_flash(self.loader.start_page + 117) if (data is not None): self.statusChanged.emit("Reading config block...done!", 100) if data[0:4] == "0xBC": # Skip 0xBC and version at the beginning [channel, speed, pitchTrim, rollTrim] = struct.unpack("<BBff", data[5:15]) else: channel = GuiConfig().get("default_cf_channel") speed = GuiConfig().get("default_cf_speed") pitchTrim = GuiConfig().get("default_cf_trim") rollTrim = GuiConfig().get("default_cf_trim") self.updateConfigSignal.emit(channel, speed, pitchTrim, rollTrim) else: self.statusChanged.emit("Reading config block failed!", 0) def loadAndFlash(self, image, verify=False, startpage=0): factor = ((100.0 * self.loader.page_size) / len(image)) if (verify == True): factor /= 2 progress = 0 # For each page ctr = 0 # Buffer counter for i in range(0, int((len(image) - 1) / self.loader.page_size) + 1): # Load the buffer if ((i + 1) * self.loader.page_size) > len(image): self.loader.upload_buffer(ctr, 0, image[i * self.loader.page_size:]) else: self.loader.upload_buffer(ctr, 0, image[i * self.loader.page_size:(i + 1) * self.loader.page_size]) ctr += 1 progress += factor self.statusChanged.emit("Uploading buffer...", int(progress)) # Flash when the complete buffers are full if ctr >= self.loader.buffer_pages: self.statusChanged.emit("Writing buffer...", int(progress)) firstFlashPage = (self.loader.start_page + startpage + i - (ctr - 1)) if not self.loader.write_flash(0, firstFlashPage, ctr): self.disconnectedSignal.emit() self.statusChanged.emit("Error during flash operation " "(err code %d)" % self.loader.error_code, int(progress)) self.link.close() return if (verify == True): for p in range(firstFlashPage, firstFlashPage + ctr): test = self.loader.read_flash(p) buffStart = ((p - self.loader.start_page) * self.loader.page_size) ver = image[buffStart:buffStart + self.loader.page_size] if (test != ver): self.statusChanged.emit("Verification failed!", int(progress)) return progress += factor self.statusChanged.emit("Verifying flashed data...", int(progress)) ctr = 0 if ctr > 0: self.statusChanged.emit("Writing buffer...", int(progress)) firstFlashPage = (self.loader.start_page + startpage + (int((len(image) - 1) / self.loader.page_size)) - (ctr - 1)) if not self.loader.write_flash(0, firstFlashPage, ctr): self.statusChanged.emit("Error during flash operation " "(err code %d)" % self.loader.error_code, int(progress)) self.disconnectedSignal.emit() self.link.close() return if (verify == True): for p in range(firstFlashPage, firstFlashPage + ctr): buffStart = ((p - self.loader.start_page) * self.loader.page_size) ver = image[buffStart:buffStart + self.loader.page_size] # We read back more than we should compare. test = self.loader.read_flash(p)[0:len(ver)] if (test != ver): self.statusChanged.emit("Verification failed!", int(progress)) return progress += factor self.statusChanged.emit("Verifying flashed data...", int(progress)) self.statusChanged.emit("Flashing...done!", 100) def resetCopter(self): self.disconnectedSignal.emit() if self.loader: self.loader.reset_to_firmware(self.loader.decode_cpu_id( "32:00:6e:06:58:37:35:32:60:58:01:43")) if self.link: self.link.close()
class CrazyloadThread(QThread): # Input signals declaration (not sure it should be used like that...) program = pyqtSignal(str, bool) verify = pyqtSignal() initiateColdBootSignal = pyqtSignal(str) resetCopterSignal = pyqtSignal() writeConfigSignal = pyqtSignal(int, int, float, float) # Output signals declaration programmed = pyqtSignal() verified = pyqtSignal() statusChanged = pyqtSignal(str, int) connectedSignal = pyqtSignal() connectingSignal = pyqtSignal() failed_signal = pyqtSignal(str) disconnectedSignal = pyqtSignal() updateConfigSignal = pyqtSignal(int, int, float, float) updateCpuIdSignal = pyqtSignal(str) radioSpeedPos = 2 def __init__(self): super(CrazyloadThread, self).__init__() # Make sure that the signals are handled by this thread event loop self.moveToThread(self) self.program.connect(self.programAction) self.writeConfigSignal.connect(self.writeConfigAction) self.initiateColdBootSignal.connect(self.initiateColdBoot) self.resetCopterSignal.connect(self.resetCopter) self.loader = None self.link = None def __del__(self): self.quit() self.wait() def initiateColdBoot(self, linkURI): self.connectingSignal.emit() try: self.link = cflib.crtp.get_link_driver("radio://0/110") except Exception as e: self.failed_signal.emit(str(e)) if (self.link): self.loader = Cloader(self.link, "radio://0/110") if self.loader.coldboot(): logger.info("Connected in coldboot mode ok") self.updateCpuIdSignal.emit(self.loader.cpuid) self.readConfigAction() self.connectedSignal.emit() else: self.failed_signal.emit("Connection timeout") logger.info("Connected in coldboot mode failed") self.link.close() def programAction(self, filename, verify): logger.info("Flashing file [%s]", filename) f = open(filename, "rb") if not f: logger.warning("Cannot open file [%s]", filename) self.link.close() return image = f.read() f.close() self.loadAndFlash(image, verify) def checksum256(self, st): return reduce(lambda x, y: x + y, map(ord, st)) % 256 def writeConfigAction(self, channel, speed, rollTrim, pitchTrim): data = (0x00, channel, speed, pitchTrim, rollTrim) image = struct.pack("<BBBff", *data) # Adding some magic: image = "0xBC" + image image += struct.pack("B", 256 - self.checksum256(image)) self.loadAndFlash(image, True, 117) def readConfigAction(self): self.statusChanged.emit("Reading config block...", 0) data = self.loader.read_flash(self.loader.start_page + 117) if (data is not None): self.statusChanged.emit("Reading config block...done!", 100) if data[0:4] == "0xBC": # Skip 0xBC and version at the beginning [channel, speed, pitchTrim, rollTrim] = struct.unpack("<BBff", data[5:15]) else: channel = Config().get("default_cf_channel") speed = Config().get("default_cf_speed") pitchTrim = Config().get("default_cf_trim") rollTrim = Config().get("default_cf_trim") self.updateConfigSignal.emit(channel, speed, pitchTrim, rollTrim) else: self.statusChanged.emit("Reading config block failed!", 0) def loadAndFlash(self, image, verify=False, startpage=0): factor = ((100.0 * self.loader.page_size) / len(image)) if (verify == True): factor /= 2 progress = 0 # For each page ctr = 0 # Buffer counter for i in range(0, int((len(image) - 1) / self.loader.page_size) + 1): # Load the buffer if ((i + 1) * self.loader.page_size) > len(image): self.loader.upload_buffer(ctr, 0, image[i * self.loader.page_size:]) else: self.loader.upload_buffer(ctr, 0, image[i * self.loader.page_size:(i + 1) * self.loader.page_size]) ctr += 1 progress += factor self.statusChanged.emit("Uploading buffer...", int(progress)) # Flash when the complete buffers are full if ctr >= self.loader.buffer_pages: self.statusChanged.emit("Writing buffer...", int(progress)) firstFlashPage = (self.loader.start_page + startpage + i - (ctr - 1)) if not self.loader.write_flash(0, firstFlashPage, ctr): self.disconnectedSignal.emit() self.statusChanged.emit("Error during flash operation " "(err code %d)" % self.loader.error_code, int(progress)) self.link.close() return if (verify == True): for p in range(firstFlashPage, firstFlashPage + ctr): test = self.loader.read_flash(p) buffStart = ((p - self.loader.start_page) * self.loader.page_size) ver = image[buffStart:buffStart + self.loader.page_size] if (test != ver): self.statusChanged.emit("Verification failed!", int(progress)) return progress += factor self.statusChanged.emit("Verifying flashed data...", int(progress)) ctr = 0 if ctr > 0: self.statusChanged.emit("Writing buffer...", int(progress)) firstFlashPage = (self.loader.start_page + startpage + (int((len(image) - 1) / self.loader.page_size)) - (ctr - 1)) if not self.loader.write_flash(0, firstFlashPage, ctr): self.statusChanged.emit("Error during flash operation " "(err code %d)" % self.loader.error_code, int(progress)) self.disconnectedSignal.emit() self.link.close() return if (verify == True): for p in range(firstFlashPage, firstFlashPage + ctr): buffStart = ((p - self.loader.start_page) * self.loader.page_size) ver = image[buffStart:buffStart + self.loader.page_size] # We read back more than we should compare. test = self.loader.read_flash(p)[0:len(ver)] if (test != ver): self.statusChanged.emit("Verification failed!", int(progress)) return progress += factor self.statusChanged.emit("Verifying flashed data...", int(progress)) self.statusChanged.emit("Flashing...done!", 100) def resetCopter(self): self.disconnectedSignal.emit() if self.loader: self.loader.reset_to_firmware(self.loader.decode_cpu_id( "32:00:6e:06:58:37:35:32:60:58:01:43")) if self.link: self.link.close()
if len(image) > ((cload.flash_pages - cload.start_page) * cload.page_size): print "Error: Not enough space to flash the image file." raise Exception() sys.stdout.write(("Flashing %d bytes (%d pages) " % ((len(image) - 1), int(len(image) / cload.page_size) + 1))) sys.stdout.flush() #For each page ctr = 0 # Buffer counter for i in range(0, int((len(image) - 1) / cload.page_size) + 1): #Load the buffer if ((i + 1) * cload.page_size) > len(image): cload.upload_buffer(ctr, 0, image[i * cload.page_size:]) else: cload.upload_buffer(ctr, 0, image[i * cload.page_size: (i + 1) * cload.page_size]) ctr += 1 sys.stdout.write(".") sys.stdout.flush() #Flash when the complete buffers are full if ctr >= cload.buffer_pages: sys.stdout.write("%d" % ctr) sys.stdout.flush() if not cload.write_flash(0, cload.start_page + i - (ctr - 1),