1# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, 2# Espressif Systems (Shanghai) CO LTD, other contributors as noted. 3# 4# SPDX-License-Identifier: GPL-2.0-or-later 5 6from ..loader import ESPLoader 7from ..util import FatalError, NotSupportedError 8 9 10class ESP8266ROM(ESPLoader): 11 """Access class for ESP8266 ROM bootloader""" 12 13 CHIP_NAME = "ESP8266" 14 IS_STUB = False 15 16 CHIP_DETECT_MAGIC_VALUE = [0xFFF0C101] 17 18 # OTP ROM addresses 19 ESP_OTP_MAC0 = 0x3FF00050 20 ESP_OTP_MAC1 = 0x3FF00054 21 ESP_OTP_MAC3 = 0x3FF0005C 22 23 SPI_REG_BASE = 0x60000200 24 SPI_USR_OFFS = 0x1C 25 SPI_USR1_OFFS = 0x20 26 SPI_USR2_OFFS = 0x24 27 SPI_MOSI_DLEN_OFFS = None 28 SPI_MISO_DLEN_OFFS = None 29 SPI_W0_OFFS = 0x40 30 31 UART_CLKDIV_REG = 0x60000014 32 33 XTAL_CLK_DIVIDER = 2 34 35 FLASH_SIZES = { 36 "512KB": 0x00, 37 "256KB": 0x10, 38 "1MB": 0x20, 39 "2MB": 0x30, 40 "4MB": 0x40, 41 "2MB-c1": 0x50, 42 "4MB-c1": 0x60, 43 "8MB": 0x80, 44 "16MB": 0x90, 45 } 46 47 FLASH_FREQUENCY = { 48 "80m": 0xF, 49 "40m": 0x0, 50 "26m": 0x1, 51 "20m": 0x2, 52 } 53 54 BOOTLOADER_FLASH_OFFSET = 0 55 56 MEMORY_MAP = [ 57 [0x3FF00000, 0x3FF00010, "DPORT"], 58 [0x3FFE8000, 0x40000000, "DRAM"], 59 [0x40100000, 0x40108000, "IRAM"], 60 [0x40201010, 0x402E1010, "IROM"], 61 ] 62 63 UF2_FAMILY_ID = 0x7EAB61ED 64 65 def get_efuses(self): 66 # Return the 128 bits of ESP8266 efuse as a single Python integer 67 result = self.read_reg(0x3FF0005C) << 96 68 result |= self.read_reg(0x3FF00058) << 64 69 result |= self.read_reg(0x3FF00054) << 32 70 result |= self.read_reg(0x3FF00050) 71 return result 72 73 def _get_flash_size(self, efuses): 74 # rX_Y = EFUSE_DATA_OUTX[Y] 75 r0_4 = (efuses & (1 << 4)) != 0 76 r3_25 = (efuses & (1 << 121)) != 0 77 r3_26 = (efuses & (1 << 122)) != 0 78 r3_27 = (efuses & (1 << 123)) != 0 79 80 if r0_4 and not r3_25: 81 if not r3_27 and not r3_26: 82 return 1 83 elif not r3_27 and r3_26: 84 return 2 85 if not r0_4 and r3_25: 86 if not r3_27 and not r3_26: 87 return 2 88 elif not r3_27 and r3_26: 89 return 4 90 return -1 91 92 def get_chip_description(self): 93 efuses = self.get_efuses() 94 is_8285 = ( 95 efuses & ((1 << 4) | 1 << 80) 96 ) != 0 # One or the other efuse bit is set for ESP8285 97 if is_8285: 98 flash_size = self._get_flash_size(efuses) 99 max_temp = ( 100 efuses & (1 << 5) 101 ) != 0 # This efuse bit identifies the max flash temperature 102 chip_name = { 103 1: "ESP8285H08" if max_temp else "ESP8285N08", 104 2: "ESP8285H16" if max_temp else "ESP8285N16", 105 }.get(flash_size, "ESP8285") 106 return chip_name 107 return "ESP8266EX" 108 109 def get_chip_features(self): 110 features = ["WiFi"] 111 if "ESP8285" in self.get_chip_description(): 112 features += ["Embedded Flash"] 113 return features 114 115 def flash_spi_attach(self, hspi_arg): 116 if self.IS_STUB: 117 super(ESP8266ROM, self).flash_spi_attach(hspi_arg) 118 else: 119 # ESP8266 ROM has no flash_spi_attach command in serial protocol, 120 # but flash_begin will do it 121 self.flash_begin(0, 0) 122 123 def flash_set_parameters(self, size): 124 # not implemented in ROM, but OK to silently skip for ROM 125 if self.IS_STUB: 126 super(ESP8266ROM, self).flash_set_parameters(size) 127 128 def chip_id(self): 129 """ 130 Read Chip ID from efuse - the equivalent of the SDK system_get_chip_id() func 131 """ 132 id0 = self.read_reg(self.ESP_OTP_MAC0) 133 id1 = self.read_reg(self.ESP_OTP_MAC1) 134 return (id0 >> 24) | ((id1 & 0xFFFFFF) << 8) 135 136 def read_mac(self, mac_type="BASE_MAC"): 137 """Read MAC from OTP ROM""" 138 if mac_type != "BASE_MAC": 139 return None 140 mac0 = self.read_reg(self.ESP_OTP_MAC0) 141 mac1 = self.read_reg(self.ESP_OTP_MAC1) 142 mac3 = self.read_reg(self.ESP_OTP_MAC3) 143 if mac3 != 0: 144 oui = ((mac3 >> 16) & 0xFF, (mac3 >> 8) & 0xFF, mac3 & 0xFF) 145 elif ((mac1 >> 16) & 0xFF) == 0: 146 oui = (0x18, 0xFE, 0x34) 147 elif ((mac1 >> 16) & 0xFF) == 1: 148 oui = (0xAC, 0xD0, 0x74) 149 else: 150 raise FatalError("Unknown OUI") 151 return oui + ((mac1 >> 8) & 0xFF, mac1 & 0xFF, (mac0 >> 24) & 0xFF) 152 153 def get_erase_size(self, offset, size): 154 """Calculate an erase size given a specific size in bytes. 155 156 Provides a workaround for the bootloader erase bug.""" 157 158 sectors_per_block = 16 159 sector_size = self.FLASH_SECTOR_SIZE 160 num_sectors = (size + sector_size - 1) // sector_size 161 start_sector = offset // sector_size 162 163 head_sectors = sectors_per_block - (start_sector % sectors_per_block) 164 if num_sectors < head_sectors: 165 head_sectors = num_sectors 166 167 if num_sectors < 2 * head_sectors: 168 return (num_sectors + 1) // 2 * sector_size 169 else: 170 return (num_sectors - head_sectors) * sector_size 171 172 def get_flash_voltage(self): 173 pass # not supported on ESP8266 174 175 def override_vddsdio(self, new_voltage): 176 raise NotSupportedError(self, "Overriding VDDSDIO") 177 178 def check_spi_connection(self, spi_connection): 179 raise NotSupportedError(self, "Setting --spi-connection") 180 181 def get_secure_boot_enabled(self): 182 return False # ESP8266 doesn't have security features 183 184 185class ESP8266StubLoader(ESP8266ROM): 186 """Access class for ESP8266 stub loader, runs on top of ROM.""" 187 188 FLASH_WRITE_SIZE = 0x4000 # matches MAX_WRITE_BLOCK in stub_loader.c 189 IS_STUB = True 190 191 def __init__(self, rom_loader): 192 self.secure_download_mode = rom_loader.secure_download_mode 193 self._port = rom_loader._port 194 self._trace_enabled = rom_loader._trace_enabled 195 self.cache = rom_loader.cache 196 self.flush_input() # resets _slip_reader 197 198 def get_erase_size(self, offset, size): 199 return size # stub doesn't have same size bug as ROM loader 200 201 202ESP8266ROM.STUB_CLASS = ESP8266StubLoader 203