def open(self, port): if not os.path.exists(self.port): return False self.port = port impl = SPI(self.port, self.baud) if not impl.BBmode(): print "Failed to enter binary mode." return False if not impl.enter_SPI(): print "Failed to enter SPI mode." return False if not impl.cfg_pins(PinCfg.POWER | PinCfg.CS | PinCfg.AUX): print "Failed to set SPI peripherals." return False if not impl.set_speed(SPISpeed._1MHZ): print "Failed to set SPI Speed." return False if not impl.cfg_spi(SPICfg.OUT_TYPE): print "Failed to set SPI configuration." return False impl.timeout(0.2) self.impl = impl return True
class VbusPirate(object): """ """ UART_DEVNAME = "/dev/ttyACM0" UART_SPEED = 115200 SPI_SPEED = SPISpeed._1MHZ #SPICfg.CLK_EDGE | SPI_CFG = SPICfg.OUT_TYPE PINS_CFG = PinCfg.POWER | PinCfg.CS | PinCfg.AUX def __init__(self, devname=UART_DEVNAME, speed=UART_SPEED, datasize=8): self._datasize = datasize self.spi = SPI(devname, speed) if not self.spi.BBmode(): raise VbusPirateError("Can't enter to binmode") if not self.spi.enter_SPI(): raise VbusPirateError("Can't enter raw SPI mode") if not self.spi.set_speed(self.SPI_SPEED): raise VbusPirateError("Can't Configure SPI speed") if not self.spi.cfg_spi(self.SPI_CFG): raise VbusPirateError("Can't Configure SPI configuration") if not self.spi.cfg_pins(self.PINS_CFG): raise VbusPirateError("Can't Configure SPI peripherals") self.spi.timeout(0.2) def sendReceiveFrame(self, raddr, dataValue=0): vbp.spi.CS_Low() resp = vbp.spi.bulk_trans([raddr]) # Wait little bit # Then if (self._datasize == 8): resp = vbp.spi.bulk_trans([dataValue]) else: resp = vbp.spi.bulk_trans([dataValue >> 8, dataValue & 0x00FF]) vbp.spi.CS_High() if type(resp) != bytes and len(resp) != 2: resp = ord(resp[-1]) elif (len(resp) == 2): if (type(resp) == str): resp = (ord(resp[0]) << 8) + ord(resp[1]) else: resp = (resp[0] << 8) + resp[1] else: resp = ord(resp) return resp def writeByte(self, addr, value): self.sendReceiveFrame(0x80 | addr, value) def readByte(self, addr): ret = self.sendReceiveFrame(0x7F & addr) return ret
if not spi.enter_SPI(): print('enter_SPI() failed') sys.exit() # speed = 30kHz # polarity = idle low (default) # output clock edge = active to idle (default) # input sample phase = middle (default) # CS = /CS (default) # output type = normal if not spi.cfg_pins(PinCfg.POWER | PinCfg.CS | PinCfg.AUX): print('cfg_pins() failed') sys.exit() if not spi.set_speed(SPISpeed._30KHZ): #if not spi.set_speed(SPISpeed._2_6MHZ): print('set_speed() failed') sys.exit() if not spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print('cfg_spi() failed') sys.exit() def write_data(data): data = struct.pack('>I', data) data = map(ord, data) print(['%02x' % d for d in data]) spi.CS_Low() spi.bulk_trans(len(data), data)
if not spi.enter_SPI(): print('enter_SPI() failed') sys.exit() # speed = 30kHz # polarity = idle low (default) # output clock edge = active to idle (default) # input sample phase = middle (default) # CS = /CS (default) # output type = normal if not spi.cfg_pins(PinCfg.POWER | PinCfg.CS | PinCfg.AUX): print('cfg_pins() failed') sys.exit() if not spi.set_speed(SPISpeed._30KHZ): #if not spi.set_speed(SPISpeed._2_6MHZ): print('set_speed() failed') sys.exit() if not spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print('cfg_spi() failed') sys.exit() def write_data(data): data = struct.pack('>I', data) data = map(ord, data) print(['%02x' % d for d in data]) spi.CS_Low() spi.bulk_trans(len(data), data) spi.CS_High()
#!/usr/bin/env python # -*- coding: utf-8 -*- # Example of SPI data transfer from pyBusPirateLite.SPI import * from pyBusPirateLite.BBIO_base import PinCfg spi = SPI() spi.connect('COM3') spi.enter_bb() spi.enter_spi() spi.cfg_pins(PinCfg.POWER | PinCfg.CS ) spi.cfg_spi( 0x0c ) spi.set_speed(SPISpeed._1MHZ) # send two bytes and receive answer spi.cs_low() data = spi.transfer( [0x82, 0x00]) spi.cs_high() print(ord(data[2])) spi.reset() spi.port.close()
class bpnrf24lReader: def __init__(self): self.status_byte = PinCfg.POWER | PinCfg.CS self.spi = None # SPI Commands self.SPI_WREN = 0x06 #Set flash write enable,FSR.WEN self.SPI_WRDIS = 0x04 #Reset flash write enable, FSR.WEN self.SPI_RDSR = 0x05 #Read Flash Status Register (FSR) self.SPI_WRSR = 0x01 self.SPI_READ = 0x03 self.SPI_PROGRAM = 0x02 self.SPI_ERASEPAGE = 0x52 self.SPI_ERASEALL = 0x62 self.SPI_RDFPCR = 0x89 self.SPI_RDISIP = 0x84 self.SPI_RDISMB = 0x85 self.SPI_ENDEBUG = 0x86 #FSR Bits self.FSR_RESERVED = 0 self.FSR_RDISIP = 1 self.FSR_RDISMB = 2 self.FSR_INFEN = 3 self.FSR_RDYN = 4 self.FSR_WEN = 5 self.FSR_STP = 6 self.FSR_DBG = 7 def connect(self, usb_port): self.spi = SPI(usb_port, 115200) print "Entering binmode: ", if self.spi.BBmode(): print "OK." else: print "failed." sys.exit() print "Entering raw SPI mode: ", if self.spi.enter_SPI(): print "OK." else: print "failed." sys.exit() print "Configuring SPI." if not self.spi.cfg_pins(self.status_byte): print "Failed to set SPI peripherals." sys.exit() if not self.spi.set_speed(SPISpeed._2_6MHZ): print "Failed to set SPI Speed." sys.exit() if not self.spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print "Failed to set SPI configuration."; sys.exit() self.spi.timeout(0.2) #Bring PROG to High self.status_byte |= PinCfg.AUX if not self.spi.cfg_pins(self.status_byte): print "Failed to set PROG pin to HIGH" sys.exit() def disconnect(self): #Cleanup print "Reset Bus Pirate to user terminal: ", if self.spi.resetBP(): print "OK." else: print "failed." sys.exit() def set_CS(self, status_flip, onfail_exit = False): if status_flip: self.status_byte &= ~PinCfg.CS; else: self.status_byte |= PinCfg.CS; if not self.spi.cfg_pins(self.status_byte): print "send_spi_command : Failed to enable writing." if onfail_exit: sys.exit() def send_spi_command(self, data=[]): return self.spi.bulk_trans(len(data), data) def is_bit_set(self, check, bit): return (check & (1 << bit) != 0) def set_bit(self, check, bit): return check | (1 << bit) def unset_bit(self, check, bit): return check & ~(1 << bit) def get_fsr(self): self.set_CS(True, True) ret = self.send_spi_command([self.SPI_RDSR, 0x00])[1] #print "get_fsr() returned : " + repr(ret) self.set_CS(False, True) return ord(ret) def parse_fsr(self, fsr=None): fsr_string = ["FSR_RESERVED", "FSR_RDISIP", "FSR_RDISMB", "FSR_INFEN", "FSR_RDYN", "FSR_WEN", "FSR_STP", "FSR_DBG"] print "=== Parsing FSR START ===" if not fsr: fsr = self.get_fsr() #print repr(fsr) for i in xrange(8): if self.is_bit_set(fsr, i): print "%s bit is set" % (fsr_string[i]) print "=== Parsing FSR END ===" return fsr def enable_read_infopage(self, disable_infopage = False): fsr = self.get_fsr() if disable_infopage: fsr = self.unset_bit(fsr, self.FSR_INFEN) else: fsr = self.set_bit(fsr, self.FSR_INFEN) self.set_CS(True, True) if not self.send_spi_command([self.SPI_WRSR, fsr]): print "enable_write() failed" sys.exit() self.set_CS(False, True) def enable_write(self): self.set_CS(True, True) if not self.send_spi_command([self.SPI_WREN,]): print "enable_write() failed" sys.exit() self.set_CS(False, True) def erase_chip(self): print "Erasing Mainblock..." #Enable writing of chip self.enable_write() ret = self.get_fsr() if ret != 0x20 and ret != 0x24: print "Incorrect status, 0x%x returned, erase_chip probably failed. Check your connections." % (ret) self.set_CS(True, True) self.send_spi_command([self.SPI_ERASEALL]) self.set_CS(False, True) while True: ret = self.get_fsr() if ret == 0x00 or ret == 0x08: #FSR_INFEN may be flagged break def erase_page(self, page): #Each page is 512 bytes and contain 8 blocks print "Erasing Page : %d" % (page) self.enable_write() ret = self.get_fsr() if ret != 0x20 and ret != 0x28 and ret != 0x2C: print "Incorrect status, 0x%x returned, erase_page probably failed. Check your connections." % (ret) self.set_CS(True, True) self.send_spi_command([self.SPI_ERASEPAGE,] + map(ord, list(struct.pack(">B",page))) ) self.set_CS(False, True) while True: ret = self.get_fsr() if ret == 0x00 or ret == 0x08: #FSR_INFEN may be flagged break def program_data(self, rom_data, start_address = 0): print "=== PROGRAM CHIP START ===" split_length = 4 #pad rom data to be % split_length == 0 if len(rom_data) % split_length != 0: rom_data = rom_data + ("\xFF" * (split_length-len(rom_data) % split_length)) self.enable_write() ret = self.get_fsr() if ret != 0x20 and ret != 0x28: #FSR_INFEN may be flagged print "Incorrect status, 0x%x returned, program_data probably failed. Check your connections." % (ret) rom_data_split = [rom_data[i:i+split_length] for i in range(0, len(rom_data), split_length)] pAddress = start_address for d in rom_data_split: self.enable_write() #Enable writing #Program bytes print "%.4X : %s" % (pAddress, repr(map(ord,list(d)))) self.set_CS(True, True) self.send_spi_command([self.SPI_PROGRAM,] + map(ord, list(struct.pack(">H",pAddress)) + list(d))) self.set_CS(False, True) pAddress += split_length print "=== PROGRAM CHIP END ===" def can_read_infopage(self): fsr = self.get_fsr() if self.is_bit_set(fsr, self.FSR_RDISIP): return False return True def is_chip_protected(self): #This check can be used to see if we can read data from MB and write to IP fsr = self.get_fsr() if self.is_bit_set(fsr, self.FSR_RDISMB): return True return False def dump_rom(self, max_size): return_data = "" for pAddress in xrange(max_size/4): spi_read_cmd = [self.SPI_READ,] + map(ord, list(struct.pack(">H",pAddress*4))) + [0, 0, 0, 0] #print "Sending SPI command: " + repr(spi_read_cmd) self.set_CS(True, True) ret = self.send_spi_command(spi_read_cmd) self.set_CS(False, True) print "%.4X : %s" % (pAddress*4, repr(map(ord,list(ret[3:])))) return_data += "".join(ret[3:]) return return_data def dump_infopage(self): if not self.can_read_infopage(): return None return_data = "" self.enable_read_infopage() return_data = self.dump_rom(512) self.enable_read_infopage(disable_infopage=True) return return_data def dump_mainblock(self, is_16kb = False): if self.is_chip_protected(): return None read_size = 0x8000 if is_16kb: read_size = 0x4000 return_data = "" return_data = self.dump_rom(read_size) return return_data
print "Entering raw SPI mode: ", if spi.enter_SPI(): print "OK." else: print "failed." sys.exit() print "Configuring SPI peripherals: ", if spi.cfg_pins(PinCfg.POWER | PinCfg.CS | PinCfg.AUX): print "OK." else: print "failed." sys.exit() print "Configuring SPI speed: ", if spi.set_speed(SPISpeed._2_6MHZ): print "OK." else: print "failed." sys.exit() print "Configuring SPI configuration: ", if spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print "OK." else: print "failed." sys.exit() spi.timeout(0.2) if opt.command == "read": print "Reading EEPROM." spi.CS_Low()
print "failed." sys.exit() print "Entering raw SPI mode: ", if spi.enter_SPI(): print "OK." else: print "failed." sys.exit() print "Configuring SPI." if not spi.cfg_pins(PinCfg.POWER | PinCfg.CS): print "Failed to set SPI peripherals." sys.exit() if not spi.set_speed(SPISpeed._8MHZ): print "Failed to set SPI Speed." sys.exit() if not spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print "Failed to set SPI configuration."; sys.exit() spi.timeout(0.2) if opt.command == "read": print "Reading EEPROM." spi.CS_Low() spi.bulk_trans(5, [0xB, 0, 0, 0, 0]) for i in range((int(opt.flash_size)/16)): data = spi.bulk_trans(16, read_list_data(16))
class GD25Q128Reader: def __init__(self): self.status_byte = PinCfg.POWER | PinCfg.CS self.spi = None #Chip Size #self.chip_block = 256 #self.chip_sectors = 16 #self.chip_pages = 4096 self.chip_bytes = 0x1000000 #Commands self.CMD_WREN = 0x06 #Write Enable self.CMD_WRDI = 0x04 #Write Disable self.CMD_RDSR1 = 0x05 #Read status register 0-7 self.CMD_RDSR2 = 0x35 #Read status register 8-15 self.CMD_RDSR3 = 0x15 #Read status register 16-23 self.CMD_READ = 0x03 #Read data bytes self.CMD_PP = 0x02 #Page Program #self.CMD_SE = 0x20 #Sector Erase #self.CMD_BE32 = 0x52 #32kb Block Erase #self.CMD_BE64 = 0xD8 #64kb Block Erase self.CMD_CE = 0xC7 #Chip Erase self.CMD_REMS = 0x90 #Read Manufacture ID/Device ID self.CMD_RDID = 0x9F #Read Identification #Status Registers self.SR_HOLD_RST = 7 self.SR_DRV1 = 6 self.SR_DRV0 = 5 self.SR_WPS = 2 self.SR_SUS1 = 7 self.SR_CMP = 6 self.SR_LB3 = 5 self.SR_LB2 = 4 self.SR_LB1 = 3 self.SR_SUS2 = 2 self.SR_QE = 1 self.SR_SRP1 = 0 self.SR_SRP0 = 7 self.SR_BP4 = 6 self.SR_BP3 = 5 self.SR_BP2 = 4 self.SR_BP1 = 3 self.SR_BP0 = 2 self.SR_WEL = 1 self.SR_WIP = 0 def connect(self, usb_port): self.spi = SPI(usb_port, 115200) print "Entering binmode: ", if self.spi.BBmode(): print "OK." else: print "failed." sys.exit() print "Entering raw SPI mode: ", if self.spi.enter_SPI(): print "OK." else: print "failed." sys.exit() print "Configuring SPI." if not self.spi.cfg_pins(self.status_byte): print "Failed to set SPI peripherals." sys.exit() if not self.spi.set_speed(SPISpeed._2_6MHZ): print "Failed to set SPI Speed." sys.exit() if not self.spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print "Failed to set SPI configuration." sys.exit() self.spi.timeout(0.2) #Bring PROG to High self.status_byte |= PinCfg.AUX if not self.spi.cfg_pins(self.status_byte): print "Failed to set PROG pin to HIGH" sys.exit() def disconnect(self): #Cleanup print "Reset Bus Pirate to user terminal: ", if self.spi.resetBP(): print "OK." else: print "failed." sys.exit() def send_single_spi_command(self, data=[]): self.spi.CS_Low() ret = self.spi.bulk_trans(len(data), data) self.spi.CS_High() return ret def send_spi_command(self, data=[]): return self.spi.bulk_trans(len(data), data) def is_bit_set(self, check, bit): return (check & (1 << bit) != 0) def set_bit(self, check, bit): return check | (1 << bit) def unset_bit(self, check, bit): return check & ~(1 << bit) def parse_SR(self): SR1, SR2, SR3 = self.get_SR() print "Parsing STATUS_REGISTERS" SR1_Dict = { "SR_SRP0": self.is_bit_set(SR1, self.SR_SRP0), "SR_BP4": self.is_bit_set(SR1, self.SR_BP4), "SR_BP3": self.is_bit_set(SR1, self.SR_BP3), "SR_BP2": self.is_bit_set(SR1, self.SR_BP2), "SR_BP1": self.is_bit_set(SR1, self.SR_BP1), "SR_BP0": self.is_bit_set(SR1, self.SR_BP0), "SR_WEL": self.is_bit_set(SR1, self.SR_WEL), "SR_WIP": self.is_bit_set(SR1, self.SR_WIP) } SR2_Dict = { "SR_SUS1": self.is_bit_set(SR1, self.SR_SUS1), "SR_CMP": self.is_bit_set(SR1, self.SR_CMP), "SR_LB3": self.is_bit_set(SR1, self.SR_LB3), "SR_LB2": self.is_bit_set(SR1, self.SR_LB2), "SR_LB1": self.is_bit_set(SR1, self.SR_LB1), "SR_SUS2": self.is_bit_set(SR1, self.SR_SUS2), "SR_QE": self.is_bit_set(SR1, self.SR_QE), "SR_SRP1": self.is_bit_set(SR1, self.SR_SRP1) } SR3_Dict = { "SR_HOLD_RST": self.is_bit_set(SR1, self.SR_HOLD_RST), "SR_DRV1": self.is_bit_set(SR1, self.SR_DRV1), "SR_DRV0": self.is_bit_set(SR1, self.SR_DRV0), "SR_WPS": self.is_bit_set(SR1, self.SR_WPS), } for i in [SR1_Dict, SR2_Dict]: for item in i: if i[item]: print "ENABLED: " + repr(item) def get_SR(self, SR_NUM=None): if SR_NUM: dsrnum = {1: self.CMD_RDSR1, 2: self.CMD_RDSR2, 3: self.CMD_RDSR3} ret = ord(self.send_single_spi_command([dsrnum[SR_NUM], 0x00])[1]) return ret ret1 = ord(self.send_single_spi_command([self.CMD_RDSR1, 0x00])[1]) ret2 = ord(self.send_single_spi_command([self.CMD_RDSR2, 0x00])[1]) ret3 = ord(self.send_single_spi_command([self.CMD_RDSR3, 0x00])[1]) return [ret1, ret2, ret3] def read_id(self): ret = self.send_single_spi_command([self.CMD_RDID, 0x00, 0x00, 0x00])[1:] ret2 = self.send_single_spi_command( [self.CMD_REMS, 0x00, 0x00, 0x00, 0x00, 0x00])[1:] print "Manufacturer ID: " + hex(ord(ret[0])) print "Memory Type: " + hex(ord(ret[1])) print "Capacity: " + hex(ord(ret[2])) print "DeviceID: " + hex(ord(ret2[4])) return ret def write_enable(self): #print "Sending Write Enable" self.send_single_spi_command([self.CMD_WREN]) def write_disable(self): #print "Sending Write Disable" self.send_single_spi_command([self.CMD_WRDI]) def dump_rom(self, output_file): read_size = 16 self.spi.CS_Low() self.send_spi_command([self.CMD_READ, 0, 0, 0]) with open(output_file, "wb") as f: for pAddress in xrange(self.chip_bytes / read_size): data = self.spi.bulk_trans(read_size, list([0] * read_size)) f.write("".join(data)) if (pAddress % (0x100 / read_size) == 0): print "%.6X : %s" % (pAddress * read_size, repr(map(ord, list(data)))) self.spi.CS_High() def is_busy(self): SR = self.get_SR(1) if self.is_bit_set(SR, self.SR_WIP): return True return False def chip_erase(self): print "Erasing Entire Chip..." #Enable WREN self.write_enable() #Send chip erase self.send_single_spi_command([self.CMD_CE]) while self.is_busy(): self.spi.timeout(0.1) print "Erase Complete..." def chunk(self, data, chunk_size): return [ data[i:i + chunk_size] for i in xrange(0, len(data), chunk_size) ] def write_rom(self, input_file): write_size = 16 with open(input_file, "rb") as f: input_data = f.read() input_data_len = len(input_data) if input_data_len > self.chip_bytes: print "Input file is bigger than maximum flash size" return if input_data_len % write_size != 0: print "Data is not divisible by %d" % (write_size) return self.chip_erase() print "Writing file to flash..." chunk_size = 256 #Datasheet indicates each transfer is 255 bytes at a time data_chunks = self.chunk(input_data, chunk_size) total_written = 0 for dc in xrange(len(data_chunks)): prog_address = dc << 8 #Enable WREN self.write_enable() self.spi.CS_Low() spi_write_cmd = [ self.CMD_PP, ] + map(ord, list(struct.pack(">L", prog_address)))[1:] self.send_spi_command(spi_write_cmd) to_write_chunks = self.chunk( data_chunks[dc], write_size) #bus pirate can only latch in 16 byes each time for twc in to_write_chunks: conv_arr = map(int, list(ord(i) for i in twc)) self.spi.bulk_trans(write_size, conv_arr) total_written += write_size self.spi.CS_High() if total_written % 4096 == 0: print "Total bytes written: %s of %s" % ("{:,}".format( total_written), "{:,}".format(input_data_len)) print "Total bytes written: %s" % ("{:,}".format(total_written))
class bpnrf24lReader: def __init__(self): self.status_byte = PinCfg.POWER | PinCfg.CS self.spi = None # SPI Commands self.SPI_WREN = 0x06 #Set flash write enable,FSR.WEN self.SPI_WRDIS = 0x04 #Reset flash write enable, FSR.WEN self.SPI_RDSR = 0x05 #Read Flash Status Register (FSR) self.SPI_WRSR = 0x01 self.SPI_READ = 0x03 self.SPI_PROGRAM = 0x02 self.SPI_ERASEPAGE = 0x52 self.SPI_ERASEALL = 0x62 self.SPI_RDFPCR = 0x89 self.SPI_RDISIP = 0x84 self.SPI_RDISMB = 0x85 self.SPI_ENDEBUG = 0x86 #FSR Bits self.FSR_RESERVED = 0 self.FSR_RDISIP = 1 self.FSR_RDISMB = 2 self.FSR_INFEN = 3 self.FSR_RDYN = 4 self.FSR_WEN = 5 self.FSR_STP = 6 self.FSR_DBG = 7 def connect(self, usb_port): self.spi = SPI(usb_port, 115200) print "Entering binmode: ", if self.spi.BBmode(): print "OK." else: print "failed." sys.exit() print "Entering raw SPI mode: ", if self.spi.enter_SPI(): print "OK." else: print "failed." sys.exit() print "Configuring SPI." if not self.spi.cfg_pins(self.status_byte): print "Failed to set SPI peripherals." sys.exit() if not self.spi.set_speed(SPISpeed._2_6MHZ): print "Failed to set SPI Speed." sys.exit() if not self.spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print "Failed to set SPI configuration." sys.exit() self.spi.timeout(0.2) #Bring PROG to High self.status_byte |= PinCfg.AUX if not self.spi.cfg_pins(self.status_byte): print "Failed to set PROG pin to HIGH" sys.exit() def disconnect(self): #Cleanup print "Reset Bus Pirate to user terminal: ", if self.spi.resetBP(): print "OK." else: print "failed." sys.exit() def set_CS(self, status_flip, onfail_exit=False): if status_flip: self.status_byte &= ~PinCfg.CS else: self.status_byte |= PinCfg.CS if not self.spi.cfg_pins(self.status_byte): print "send_spi_command : Failed to enable writing." if onfail_exit: sys.exit() def send_spi_command(self, data=[]): return self.spi.bulk_trans(len(data), data) def is_bit_set(self, check, bit): return (check & (1 << bit) != 0) def set_bit(self, check, bit): return check | (1 << bit) def unset_bit(self, check, bit): return check & ~(1 << bit) def get_fsr(self): self.set_CS(True, True) ret = self.send_spi_command([self.SPI_RDSR, 0x00])[1] #print "get_fsr() returned : " + repr(ret) self.set_CS(False, True) return ord(ret) def parse_fsr(self, fsr=None): fsr_string = [ "FSR_RESERVED", "FSR_RDISIP", "FSR_RDISMB", "FSR_INFEN", "FSR_RDYN", "FSR_WEN", "FSR_STP", "FSR_DBG" ] print "=== Parsing FSR START ===" if not fsr: fsr = self.get_fsr() #print repr(fsr) for i in xrange(8): if self.is_bit_set(fsr, i): print "%s bit is set" % (fsr_string[i]) print "=== Parsing FSR END ===" return fsr def enable_read_infopage(self, disable_infopage=False): fsr = self.get_fsr() if disable_infopage: fsr = self.unset_bit(fsr, self.FSR_INFEN) else: fsr = self.set_bit(fsr, self.FSR_INFEN) self.set_CS(True, True) if not self.send_spi_command([self.SPI_WRSR, fsr]): print "enable_write() failed" sys.exit() self.set_CS(False, True) def enable_write(self): self.set_CS(True, True) if not self.send_spi_command([ self.SPI_WREN, ]): print "enable_write() failed" sys.exit() self.set_CS(False, True) def erase_chip(self): print "Erasing Mainblock..." #Enable writing of chip self.enable_write() ret = self.get_fsr() if ret != 0x20 and ret != 0x24: print "Incorrect status, 0x%x returned, erase_chip probably failed. Check your connections." % ( ret) self.set_CS(True, True) self.send_spi_command([self.SPI_ERASEALL]) self.set_CS(False, True) while True: ret = self.get_fsr() if ret == 0x00 or ret == 0x08: #FSR_INFEN may be flagged break def erase_page(self, page): #Each page is 512 bytes and contain 8 blocks print "Erasing Page : %d" % (page) self.enable_write() ret = self.get_fsr() if ret != 0x20 and ret != 0x28 and ret != 0x2C: print "Incorrect status, 0x%x returned, erase_page probably failed. Check your connections." % ( ret) self.set_CS(True, True) self.send_spi_command([ self.SPI_ERASEPAGE, ] + map(ord, list(struct.pack(">B", page)))) self.set_CS(False, True) while True: ret = self.get_fsr() if ret == 0x00 or ret == 0x08: #FSR_INFEN may be flagged break def program_data(self, rom_data, start_address=0): print "=== PROGRAM CHIP START ===" split_length = 4 #pad rom data to be % split_length == 0 if len(rom_data) % split_length != 0: rom_data = rom_data + ( "\xFF" * (split_length - len(rom_data) % split_length)) self.enable_write() ret = self.get_fsr() if ret != 0x20 and ret != 0x28: #FSR_INFEN may be flagged print "Incorrect status, 0x%x returned, program_data probably failed. Check your connections." % ( ret) rom_data_split = [ rom_data[i:i + split_length] for i in range(0, len(rom_data), split_length) ] pAddress = start_address for d in rom_data_split: self.enable_write() #Enable writing #Program bytes print "%.4X : %s" % (pAddress, repr(map(ord, list(d)))) self.set_CS(True, True) self.send_spi_command([ self.SPI_PROGRAM, ] + map(ord, list(struct.pack(">H", pAddress)) + list(d))) self.set_CS(False, True) pAddress += split_length print "=== PROGRAM CHIP END ===" def can_read_infopage(self): fsr = self.get_fsr() if self.is_bit_set(fsr, self.FSR_RDISIP): return False return True def is_chip_protected(self): #This check can be used to see if we can read data from MB and write to IP fsr = self.get_fsr() if self.is_bit_set(fsr, self.FSR_RDISMB): return True return False def dump_rom(self, max_size): return_data = "" for pAddress in xrange(max_size / 4): spi_read_cmd = [ self.SPI_READ, ] + map(ord, list(struct.pack(">H", pAddress * 4))) + [0, 0, 0, 0] #print "Sending SPI command: " + repr(spi_read_cmd) self.set_CS(True, True) ret = self.send_spi_command(spi_read_cmd) self.set_CS(False, True) print "%.4X : %s" % (pAddress * 4, repr(map(ord, list(ret[3:])))) return_data += "".join(ret[3:]) return return_data def dump_infopage(self): if not self.can_read_infopage(): return None return_data = "" self.enable_read_infopage() return_data = self.dump_rom(512) self.enable_read_infopage(disable_infopage=True) return return_data def dump_mainblock(self, is_16kb=False): if self.is_chip_protected(): return None read_size = 0x8000 if is_16kb: read_size = 0x4000 return_data = "" return_data = self.dump_rom(read_size) return return_data
def buspirate_test(buspirate_dev: str, filename: str): spi = SPI(buspirate_dev, 115200) print("Entering binmode: ") if spi.BBmode(): print("OK.") else: print("failed.") sys.exit() print("Entering raw SPI mode: ") if spi.enter_SPI(): print("OK.") else: print("failed.") sys.exit() print("Configuring SPI peripherals: ") if spi.cfg_pins(PinCfg.POWER | PinCfg.CS): print("OK.") else: print("failed.") sys.exit() sleep(0.5) print("Configuring SPI speed: ") if spi.set_speed(SPISpeed._125KHZ): print("OK.") else: print("failed.") sys.exit() print("Configuring SPI configuration: ") if spi.cfg_spi(SPICfg.CLK_EDGE | SPICfg.OUT_TYPE): print("OK.") else: print("failed.") sys.exit() spi.timeout(0.2) bme280 = BME280(spi) bme280.begin() print("Checking chip ID: ", end='') chipID = bme280.read_reg8(0xD0) if chipID == 0x60: print("OK") else: print(f"ERROR ({chipID} != 0x60") sys.exit() bme280.end() print("Starting conversion") bme280.begin() bme280.write_reg8(0xF2, 0x02) bme280.write_reg8(0xF4, 0b01001010) bme280.end() bme280.begin() print("Waiting for result.", end='') while bme280.read_reg8(0xF3) & 0x80: print('.', end='') sleep(0.01) print("OK") bme280.end() print("Reading results:", end='') bme280.begin() bres = bme280.read_data(0xF7, 8) bme280.end() if len(bres) == 8: print("OK") else: print("ERROR") sys.exit() raw_humidity = (bres[6] << 8) | bres[7] raw_pressure = (bres[0] << 12) | (bres[1] << 4) | (bres[2] >> 4) raw_temp = (bres[3] << 12) | (bres[4] << 4) | (bres[5] >> 4) print( f"Raw Humidity:{raw_humidity} Raw Pressure:{raw_pressure} Raw Temperature:{raw_temp}" ) bme280.begin() bcompA = bme280.read_data(0x88, 26) # 0x88 - 0xA1 bme280.end() bme280.begin() bcompB = bme280.read_data(0xE1, 7) # 0xE1 - 0xE7 bme280.end() if filename is not None: fp = open("bme280.bin", "wb") fp.write(bres) fp.write(bcompA) fp.write(bcompB) fp.close() print("Reset Bus Pirate to user terminal: ", end='') if spi.resetBP(): print("OK") else: print("ERROR") sys.exit() temperature = bme280.calculateTemperature(raw_temp, bcompA) pressure = bme280.calculatePressure(raw_pressure, bcompA) humidity = bme280.calculateHumidity(raw_humidity, bcompA[25:] + bcompB) print("Temperature: {:.2f}C".format(temperature / 100.0)) print("Pressure: {:.2f}hPa".format(pressure / 100.0)) print("RH: {:.2f}%".format(humidity))