def defineMemChecksFromHexlines(self, lines, MLM=MEMCHECKMAXSIZE): memCheckAddresses = dict() # first chop very long data chuncks in smaller parts for line in lines: length = len(line[9:-3]) / 4 # in words checkaddress = h2i(line[3:7]) while (length > 0): if (length > MLM): memCheckAddresses[i2h(checkaddress)] = MLM checkaddress += 2 * MLM # MLM is in words, address is in bytes else: # do some math magic to ceil to the nearest factor of 2 (crc must be factor of 2) memCheckAddresses[i2h(checkaddress)] = max( int(pow(2, ceil(log(length, 2)))), 16) length -= MLM self.mcas = memCheckAddresses logger.debug("new memchecks based upon hexlines: {}".format( pprint.pformat(self.mcas))) # get a list of expected CRC results per small chunck of data self.memChecks = dict() # do not redefine self.memIsGood = dict() # do redefine the memIsBad self.memIsBad = dict() for mca in self.mcas: # check CRC of this block in 4 subparts self.memChecks[mca] = { "crcs": self.crcString(address=h2i(mca), nr_of_words=self.mcas[mca]), "length": self.mcas[mca], }
def checkCRC(self, addr, crcs): if (addr in self.memChecks): this = self.memChecks[addr] logger.info("{} ?= {}".format(this["crcs"], crcs)) crcsize_words = max(this["length"] / self.sf, self.MEMCHECKMINSIZE) addr_offset = 2 * crcsize_words # "*2" because addr is in bytes and the rest is in words, length/4 because we ack one/fourth of the total message for x in range(len(crcs) / 4 - 1, -1, -1): if (this["crcs"][x * 4:x * 4 + 4] == crcs[x * 4:x * 4 + 4] ): # each CRC is 4 characters long # good :) wisp has good data in this part self.memcheck_widget.ack( h2i(addr) + x * addr_offset, crcsize_words) self.memIsGood[i2h( h2i(addr) + x * addr_offset)] = crcsize_words # store the good stuff logger.debug(i2h(h2i(addr) + x * addr_offset) + " = good") else: # do something with a bad crc: self.badCRC(address=h2i(addr) + addr_offset * x, length=crcsize_words) if (addr in self.memIsBad or addr in self.memIsGood): del self.memChecks[addr] return True return False
def defineMemChecks(self, MLM=MEMCHECKMAXSIZE): memCheckAddresses = dict() # first chop very long data chuncks in smaller parts for addr in self.startAddresses: length = self.startAddresses[addr] checkaddress = h2i(addr) while (length > 0): if (length > MLM): memCheckAddresses[i2h(checkaddress)] = MLM checkaddress += 2 * MLM # MLM is in words, address is in bytes else: # do some math magic to ceil to the nearest factor of 2 (crc must be factor of 2) memCheckAddresses[i2h(checkaddress)] = max( int(pow(2, ceil(log(length, 2)))), 16) length -= MLM self.mcas = memCheckAddresses logger.debug("{}".format(pprint.pformat(self.mcas))) # get a list of expected CRC results per small chunck of data self.memChecks = dict() self.memIsGood = dict() self.memIsBad = dict() for mca in self.mcas: # check CRC of this block in 4 subparts self.memChecks[mca] = {"crcs": #"{:04x}{:04x}{:04x}{:04x}".format(self.getCRC(address = h2i(mca), nr_of_words = self.mcas[mca]/4), # self.getCRC(address = h2i(mca)+self.mcas[mca]/2 , nr_of_words = self.mcas[mca]/4), # self.getCRC(address = h2i(mca)+self.mcas[mca]/2 *2, nr_of_words = self.mcas[mca]/4), # self.getCRC(address = h2i(mca)+self.mcas[mca]/2 *3, nr_of_words = self.mcas[mca]/4) ) self.crcString(address = h2i(mca),nr_of_words = self.mcas[mca]), "length": self.mcas[mca],}
def crcByte(self, crc, data): crc ^= 0xffff # invert initial crc for the crc module data = h2i(data) # convert hex-string to integer x = (crc >> 8) ^ data # do some magic x ^= x >> 4 # do some magic crc = (crc << 8) ^ (x << 12) ^ (x << 5) ^ (x) # do some magic return (crc & 0xffff) ^ 0xFFFF # invert it back to leave the crc module
def nextRound(self): counter = 0 for addr in self.memChecks: this = self.memChecks[addr] resultpos = log( max(this["length"] / self.sf, self.MEMCHECKMINSIZE) / 2, 2 ) # 16 should be 1 (if wisp receives 1 then it will translate to X blocks of 2<<1 =4), # 32 should be 2 (if wisp receives 2 then it will translate to X blocks of 2<<2 =8), etc if (resultpos.is_integer()): resultpos = int(resultpos) else: raise NameError("trying to do a CRC with strange number " + str(this["length"]) + " = not 16*2^x for integer x > -1") checksum = i2h((h2i(addr[0:2]) + h2i(addr[2:4])) % 256, 2) # calc checksum message = i2h(resultpos * 32, 2) + checksum + addr # *32 == shift by 5 logger.info(self.ID + ": sending memcheck [" + message + "], expecting CRCs = " + this["crcs"]) self.memcheck_widget.send(address=h2i(addr), size_in_words=this["length"]) self.send_util.addOpspec(OpSpecCreator.getBlockWrite(message)) nr_to_read = 1 + min(self.sf, this["length"] / self.MEMCHECKMINSIZE) self.send_util.addOpspec( OpSpecCreator.getRead(mb=3, address=0, nr_of_words=nr_to_read)) counter += 1 if counter == 4: break if (len(self.send_util.opspecs)): self.send_util.sendOpspecs(OCV=1, nack=self.timeout) else: logger.info(self.ID + ": memcheck finished") logger.info(self.ID + ": " + str(len(self.memIsGood)) + " good and " + str(len(self.memIsBad)) + " bad memblocks") self.iAmFinished()
def getLongHexLinesFromBadCRCs(self): lines = [] addresses = self.memIsBad.keys() addresses.sort( ) # sort the lines such that they are in increasing order, such that hexlinewrapping is possible # [warning:] sort function does sorting based upon characters, fortunately hex is also sorted as 0123456789ABCDEFabcdef for addr in addresses: mem = self.getMem(address=h2i(addr), length_in_words=self.memIsBad[addr]) lines.append(":" + i2h(len(mem) / 2, 2) + addr + "00" + mem + "FF\n") logger.debug(self.ID + ": hexline made from bad CRCcheck: " + i2h(len(mem) / 2, 2) + " " + addr + "[00]" + mem + "[FF]") lines.append(":00000001FF\n") # add the end of file line return wrapHexLines(lines)
def memInit(self, memlines): self.memory = "FF" * ( self.MAXMEM - self.MINMEM ) # init with all "ff", all ones, just as untouched wisp memory # insert all known memory parts: for line in memlines: if ( line[7:9] == "00" ): # check if this line is a normal memory line (instead of: an end-of-file-line) # decompose hexline in parts am = self.convertAddr2myMem(h2i( line[3:7])) # address of memory dm = line[9:-3] # data of memory lm = len(dm) # lenght of data of memory memleft = self.memory[:am] memright = self.memory[am + lm:] self.memory = memleft + dm + memright
def __init__(self, wispRam, title="", destroy_callback=None): super(MemCheckWidget, self).__init__() memchecks = wispRam.memChecks self.setMemCheckTarget( [memchecks[x]["length"] for x in sorted(memchecks)]) self.addresses = [h2i(x) for x in sorted(memchecks)] self.root = Tk() self.root.protocol("WM_DELETE_WINDOW", self.destroyedByUser) self.destroy_callback = destroy_callback # self.root.focus() self.root.title(wispRam.ID + ": " + title) self.root.geometry('+%d-%d' % (20, 20)) text_w = min(max(self.plot_y_target), 250) + 5 text_h = sum( len([y for y in self.plot_y_target if y > i * 220]) for i in range(10)) + 2 self.txt = Text(self.root, width=text_w, height=text_h) self.txt.pack(fill=BOTH, expand=True) for x in range(len(self.plot_y_target)): self.txt.insert( INSERT, i2h(self.addresses[x]) + " " + "?" * self.plot_y_target[x] + "\n")