diff --git a/tools/esptool.py b/tools/esptool.py index 130e80f0..88a4b4ed 100755 --- a/tools/esptool.py +++ b/tools/esptool.py @@ -41,7 +41,7 @@ class ESPROM: # Maximum block sized for RAM and Flash writes, respectively. ESP_RAM_BLOCK = 0x1800 - ESP_FLASH_BLOCK = 0x100 + ESP_FLASH_BLOCK = 0x400 # Default baudrate. The ROM auto-bauds, so we can use more or less whatever we want. ESP_ROM_BAUD = 115200 @@ -56,6 +56,12 @@ class ESPROM: ESP_OTP_MAC0 = 0x3ff00050 ESP_OTP_MAC1 = 0x3ff00054 + # Sflash stub: an assembly routine to read from spi flash and send to host + SFLASH_STUB = "\x80\x3c\x00\x40\x1c\x4b\x00\x40\x21\x11\x00\x40\x00\x80" \ + "\xfe\x3f\xc1\xfb\xff\xd1\xf8\xff\x2d\x0d\x31\xfd\xff\x41\xf7\xff\x4a" \ + "\xdd\x51\xf9\xff\xc0\x05\x00\x21\xf9\xff\x31\xf3\xff\x41\xf5\xff\xc0" \ + "\x04\x00\x0b\xcc\x56\xec\xfd\x06\xff\xff\x00\x00" + def __init__(self, port = 0, baud = ESP_ROM_BAUD): self._port = serial.Serial(port, baud) @@ -78,15 +84,7 @@ class ESPROM: """ Write bytes to the serial port while performing SLIP escaping """ def write(self, packet): - buf = '\xc0' - for b in packet: - if b == '\xc0': - buf += '\xdb\xdc' - elif b == '\xdb': - buf += '\xdb\xdd' - else: - buf += b - buf += '\xc0' + buf = '\xc0'+(packet.replace('\xdb','\xdb\xdd').replace('\xc0','\xdb\xdc'))+'\xc0' self._port.write(buf) """ Calculate checksum of a blob, as it is defined by the ROM """ @@ -132,11 +130,25 @@ class ESPROM: # RTS = CH_PD (i.e reset) # DTR = GPIO0 + # self._port.setRTS(True) + # self._port.setDTR(True) + # self._port.setRTS(False) + # time.sleep(0.1) + # self._port.setDTR(False) + + # NodeMCU devkit self._port.setRTS(True) self._port.setDTR(True) - self._port.setRTS(False) time.sleep(0.1) + self._port.setRTS(False) self._port.setDTR(False) + time.sleep(0.1) + self._port.setRTS(True) + time.sleep(0.1) + self._port.setDTR(True) + self._port.setRTS(False) + time.sleep(0.3) + self._port.setDTR(True) self._port.timeout = 0.5 for i in xrange(10): @@ -209,16 +221,78 @@ class ESPROM: self.flash_begin(0, 0) self.flash_finish(reboot) + """ Read MAC from OTP ROM """ + def read_mac(self): + mac0 = esp.read_reg(esp.ESP_OTP_MAC0) + mac1 = esp.read_reg(esp.ESP_OTP_MAC1) + if ((mac1 >> 16) & 0xff) == 0: + oui = (0x18, 0xfe, 0x34) + elif ((mac1 >> 16) & 0xff) == 1: + oui = (0xac, 0xd0, 0x74) + else: + raise Exception("Unknown OUI") + return oui + ((mac1 >> 8) & 0xff, mac1 & 0xff, (mac0 >> 24) & 0xff) + + """ Read SPI flash manufacturer and device id """ + def flash_id(self): + self.flash_begin(0, 0) + self.write_reg(0x60000240, 0x0, 0xffffffff) + self.write_reg(0x60000200, 0x10000000, 0xffffffff) + flash_id = esp.read_reg(0x60000240) + self.flash_finish(False) + return flash_id + + """ Read SPI flash """ + def flash_read(self, offset, size, count = 1): + # Create a custom stub + stub = struct.pack(' 16: @@ -246,7 +320,8 @@ class ESPFirmwareImage: def save(self, filename): f = file(filename, 'wb') - f.write(struct.pack('> 8) & 0xff, mac1 & 0xff, (mac0 >> 24) & 0xff) + mac = esp.read_mac() + print 'MAC: %s' % ':'.join(map(lambda x: '%02x'%x, mac)) + + elif args.operation == 'flash_id': + flash_id = esp.flash_id() + print 'Manufacturer: %02x' % (flash_id & 0xff) + print 'Device: %02x%02x' % ((flash_id >> 8) & 0xff, (flash_id >> 16) & 0xff) + + elif args.operation == 'read_flash': + print 'Please wait...' + file(args.filename, 'wb').write(esp.flash_read(args.address, 1024, int(math.ceil(args.size / 1024.)))[:args.size]) + + elif args.operation == 'erase_flash': + esp.flash_erase()