1# SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 2# 3# SPDX-License-Identifier: GPL-2.0-or-later 4 5import struct 6import time 7from typing import Dict 8 9from .esp32c6 import ESP32C6ROM 10from ..loader import ESPLoader 11 12 13class ESP32C5BETA3ROM(ESP32C6ROM): 14 CHIP_NAME = "ESP32-C5(beta3)" 15 IMAGE_CHIP_ID = 17 16 17 IROM_MAP_START = 0x41000000 18 IROM_MAP_END = 0x41800000 19 DROM_MAP_START = 0x41000000 20 DROM_MAP_END = 0x41800000 21 22 # Magic value for ESP32C5(beta3) 23 CHIP_DETECT_MAGIC_VALUE = [0xE10D8082] 24 25 FLASH_FREQUENCY = { 26 "80m": 0xF, 27 "40m": 0x0, 28 "20m": 0x2, 29 } 30 31 MEMORY_MAP = [ 32 [0x00000000, 0x00010000, "PADDING"], 33 [0x41800000, 0x42000000, "DROM"], 34 [0x40800000, 0x40880000, "DRAM"], 35 [0x40800000, 0x40880000, "BYTE_ACCESSIBLE"], 36 [0x4004A000, 0x40050000, "DROM_MASK"], 37 [0x40000000, 0x4004A000, "IROM_MASK"], 38 [0x41000000, 0x41800000, "IROM"], 39 [0x40800000, 0x40880000, "IRAM"], 40 [0x50000000, 0x50004000, "RTC_IRAM"], 41 [0x50000000, 0x50004000, "RTC_DRAM"], 42 [0x600FE000, 0x60100000, "MEM_INTERNAL2"], 43 ] 44 45 EFUSE_MAX_KEY = 5 46 KEY_PURPOSES: Dict[int, str] = { 47 0: "USER/EMPTY", 48 1: "ECDSA_KEY", 49 2: "XTS_AES_256_KEY_1", 50 3: "XTS_AES_256_KEY_2", 51 4: "XTS_AES_128_KEY", 52 5: "HMAC_DOWN_ALL", 53 6: "HMAC_DOWN_JTAG", 54 7: "HMAC_DOWN_DIGITAL_SIGNATURE", 55 8: "HMAC_UP", 56 9: "SECURE_BOOT_DIGEST0", 57 10: "SECURE_BOOT_DIGEST1", 58 11: "SECURE_BOOT_DIGEST2", 59 12: "KM_INIT_KEY", 60 } 61 62 def get_pkg_version(self): 63 num_word = 2 64 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 26) & 0x07 65 66 def get_minor_chip_version(self): 67 num_word = 2 68 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 0) & 0x0F 69 70 def get_major_chip_version(self): 71 num_word = 2 72 return (self.read_reg(self.EFUSE_BLOCK1_ADDR + (4 * num_word)) >> 4) & 0x03 73 74 def get_chip_description(self): 75 chip_name = { 76 0: "ESP32-C5 beta3 (QFN40)", 77 }.get(self.get_pkg_version(), "unknown ESP32-C5 beta3") 78 major_rev = self.get_major_chip_version() 79 minor_rev = self.get_minor_chip_version() 80 return f"{chip_name} (revision v{major_rev}.{minor_rev})" 81 82 def get_crystal_freq(self): 83 # The crystal detection algorithm of ESP32/ESP8266 84 # works for ESP32-C5 beta3 as well. 85 return ESPLoader.get_crystal_freq(self) 86 87 def change_baud(self, baud): 88 rom_with_48M_XTAL = not self.IS_STUB and self.get_crystal_freq() == 48 89 if rom_with_48M_XTAL: 90 # The code is copied over from ESPLoader.change_baud(). 91 # Probably this is just a temporary solution until the next chip revision. 92 93 # The ROM code thinks it uses a 40 MHz XTAL. Recompute the baud rate 94 # in order to trick the ROM code to set the correct baud rate for 95 # a 48 MHz XTAL. 96 false_rom_baud = baud * 40 // 48 97 98 print(f"Changing baud rate to {baud}") 99 self.command( 100 self.ESP_CHANGE_BAUDRATE, struct.pack("<II", false_rom_baud, 0) 101 ) 102 print("Changed.") 103 self._set_port_baudrate(baud) 104 time.sleep(0.05) # get rid of garbage sent during baud rate change 105 self.flush_input() 106 else: 107 ESPLoader.change_baud(self, baud) 108 109 110class ESP32C5BETA3StubLoader(ESP32C5BETA3ROM): 111 """Access class for ESP32C5BETA3 stub loader, runs on top of ROM. 112 113 (Basically the same as ESP32StubLoader, but different base class. 114 Can possibly be made into a mixin.) 115 """ 116 117 FLASH_WRITE_SIZE = 0x4000 # matches MAX_WRITE_BLOCK in stub_loader.c 118 STATUS_BYTES_LENGTH = 2 # same as ESP8266, different to ESP32 ROM 119 IS_STUB = True 120 121 def __init__(self, rom_loader): 122 self.secure_download_mode = rom_loader.secure_download_mode 123 self._port = rom_loader._port 124 self._trace_enabled = rom_loader._trace_enabled 125 self.cache = rom_loader.cache 126 self.flush_input() # resets _slip_reader 127 128 129ESP32C5BETA3ROM.STUB_CLASS = ESP32C5BETA3StubLoader 130