// // Copyright (c) 2010-2023 Antmicro // Copyright (c) 2011-2015 Realtime Embedded // // This file is licensed under the MIT License. // Full license text is available in 'licenses/MIT.txt'. // using System; using Antmicro.Renode.Peripherals.Bus; using Antmicro.Renode.Core; using Antmicro.Renode.Peripherals; using Antmicro.Renode.Utilities; using Antmicro.Renode.Logging; using System.Collections.Generic; using Antmicro.Renode.Core.Structure.Registers; namespace Antmicro.Renode.Peripherals.Miscellaneous { public class ESP32S3_RTC_CNTL : IBytePeripheral, IDoubleWordPeripheral, IKnownSize { public ESP32S3_RTC_CNTL(Machine machine) { var registersMap = new Dictionary { {(long)Registers.OPTIONS0, new DoubleWordRegister(this) .WithValueField(0, 2, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => 0, name: "SW_STALL_APPCPU_C0") // {reg_sw_stall_appcpu_c1[5:0], reg_sw_stall_appcpu_c0[1:0]} == 0x86 will stall APP CPU .WithValueField(2, 2, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => 0, name: "SW_STALL_PROCPU_C0") // {reg_sw_stall_procpu_c1[5:0], reg_sw_stall_procpu_c0[1:0]} == 0x86 will stall PRO CPU .WithFlag(4, FieldMode.Read | FieldMode.Write, name: "SW_APPCPU_RST") // APP CPU SW reset .WithFlag(5, FieldMode.Read | FieldMode.Write, name: "SW_PROCPU_RST") // PRO CPU SW reset .WithFlag(6, FieldMode.Read | FieldMode.Write, name: "BB_I2C_FORCE_PD") // BB_I2C force power down .WithFlag(7, FieldMode.Read | FieldMode.Write, name: "BB_I2C_FORCE_PU") // BB_I2C force power up .WithFlag(8, FieldMode.Read | FieldMode.Write, name: "BBPLL_I2C_FORCE_PD") // BB_PLL _I2C force power down .WithFlag(9, FieldMode.Read | FieldMode.Write, name: "BBPLL_I2C_FORCE_PU") // BB_PLL_I2C force power up .WithFlag(10, FieldMode.Read | FieldMode.Write, name: "BBPLL_FORCE_PD") // BB_PLL force power down .WithFlag(11, FieldMode.Read | FieldMode.Write, name: "BBPLL_FORCE_PU") // BB_PLL force power up .WithFlag(12, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_PD") // crystall force power down .WithFlag(13, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_PU") // crystall force power up .WithValueField(14, 4, FieldMode.Read | FieldMode.Write, name: "XTL_EN_WAIT") // wait bias_sleep and current source wakeup .WithFlag(23, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_ISO") // No public .WithFlag(24, FieldMode.Read | FieldMode.Write, name: "PLL_FORCE_ISO") // No public .WithFlag(25, FieldMode.Read | FieldMode.Write, name: "ANALOG_FORCE_ISO") // No public .WithFlag(26, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_NOISO") // No public .WithFlag(27, FieldMode.Read | FieldMode.Write, name: "PLL_FORCE_NOISO") // No public .WithFlag(28, FieldMode.Read | FieldMode.Write, name: "ANALOG_FORCE_NOISO") // No public .WithFlag(29, FieldMode.Read | FieldMode.Write, name: "DG_WRAP_FORCE_RST") // digital wrap force reset in deep sleep .WithFlag(30, FieldMode.Read | FieldMode.Write, name: "DG_WRAP_FORCE_NORST") // digital core force no reset in deep sleep .WithFlag(31, FieldMode.Write, name: "SW_SYS_RST") // SW system reset }, {(long)Registers.RESET_STATE, new DoubleWordRegister(this) .WithValueField(0, 6, FieldMode.Read, valueProviderCallback: (_) => (ulong)ResetReason.POWERON, name: "RESET_CAUSE_PROCPU") .WithValueField(6, 6, FieldMode.Read, valueProviderCallback: (_) => 1, name: "RESET_CAUSE_APPCPU") .WithFlag(12, FieldMode.Read | FieldMode.Write, name: "APPCPU_STAT_VECTOR_SEL") .WithFlag(13, FieldMode.Read | FieldMode.Write, name: "PROCPU_STAT_VECTOR_SEL") .WithFlag(14, FieldMode.Read, valueProviderCallback: (_) => true, name: "RESET_FLAG_PROCPU") .WithFlag(15, FieldMode.Read, valueProviderCallback: (_) => true, name: "RESET_FLAG_APPCPU") .WithFlag(16, FieldMode.Write, name: "RESET_FLAG_PROCPU_CLR") .WithFlag(17, FieldMode.Write, name: "RESET_FLAG_APPCPU_CLR") .WithFlag(18, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => true, name: "PROCPU_OCD_HALT_ON_RESET") .WithFlag(19, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => true, name: "RESET_FLAG_APPCPU") .WithFlag(20, FieldMode.Read, valueProviderCallback: (_) => true, name: "RESET_FLAG_JTAG_PROCPU") .WithFlag(21, FieldMode.Read, valueProviderCallback: (_) => true, name: "RESET_FLAG_JTAG_APPCPU") .WithFlag(22, FieldMode.Write, name: "RESET_FLAG_JTAG_PROCPU_CLR") .WithFlag(23, FieldMode.Write, name: "RESET_FLAG_JTAG_APPCPU_CLR") .WithFlag(24, FieldMode.Read | FieldMode.Write, name: "APP_DRESET_MASK") .WithFlag(25, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => true, name: "PRO_DRESET_MASK") }, {(long)Registers.PWC, new DoubleWordRegister(this) .WithValueField(0, 32) }, {(long)Registers.DIG_ISO, new DoubleWordRegister(this) .WithValueField(0, 32) }, {(long)Registers.SWD_CONF, new DoubleWordRegister(this) .WithValueField(0, 32) }, {(long)Registers.STORE4, new DoubleWordRegister(this) .WithValueField(0, 32, name: "SCRATCH4") }, {(long)Registers.DIG_PAD_HOLD, new DoubleWordRegister(this) .WithValueField(0, 32) }, // {(long)Registers.STATUS, new DoubleWordRegister(this) // .WithValueField(0, 10, FieldMode.Read, name: "RXFIFO_CNT") // .WithFlag(13, FieldMode.Read, name: "UART_DSRN") // .WithFlag(14, FieldMode.Read, valueProviderCallback: (_) => true, name: "UART_CTSN") // .WithFlag(15, FieldMode.Read, valueProviderCallback: (_) => true, name: "UART_RXD") // .WithValueField(16, 10, FieldMode.Read, name: "TXFIFO_CNT") // .WithFlag(29, FieldMode.Read, valueProviderCallback: (_) => true, name: "UART_DTRN") // .WithFlag(30, FieldMode.Read, valueProviderCallback: (_) => true, name: "UART_RTSN") // .WithFlag(31, FieldMode.Read, valueProviderCallback: (_) => true, name: "UART_TXD") // }, // {(long)Registers.TxFull, new DoubleWordRegister(this) // .WithFlag(0, FieldMode.Read) //tx is never full // }, // {(long)Registers.RxEmpty, new DoubleWordRegister(this) // .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => Count == 0) // }, // {(long)Registers.EventPending, new DoubleWordRegister(this) // // `txEventPending` implements `WriteOneToClear` semantics to avoid fake warnings // // `txEventPending` is generated on the falling edge of TxFull; in our case it means never // .WithFlag(0, FieldMode.Read | FieldMode.WriteOneToClear, valueProviderCallback: _ => false, name: "txEventPending") // .WithFlag(1, out rxEventPending, FieldMode.Read | FieldMode.WriteOneToClear, name: "rxEventPending") // .WithWriteCallback((_, __) => UpdateInterrupts()) // }, // {(long)Registers.EventEnable, new DoubleWordRegister(this) // .WithFlag(0, name: "txEventEnabled") // .WithFlag(1, out rxEventEnabled) // .WithWriteCallback((_, __) => UpdateInterrupts()) // }, }; registers = new DoubleWordRegisterCollection(this, registersMap); } public uint ReadDoubleWord(long offset) { return registers.Read(offset); } public byte ReadByte(long offset) { if (offset % 4 != 0) { // in the current configuration, only the lowest byte // contains a meaningful data return 0; } return (byte)ReadDoubleWord(offset); } public void Reset() { // base.Reset(); registers.Reset(); // UpdateInterrupts(); } public void WriteDoubleWord(long offset, uint value) { registers.Write(offset, value); } public void WriteByte(long offset, byte value) { if (offset % 4 != 0) { // in the current configuration, only the lowest byte // contains a meaningful data return; } WriteDoubleWord(offset, value); } public long Size => 0x15C; private readonly DoubleWordRegisterCollection registers; private enum Registers : long { OPTIONS0 = 0x00, // RTC common configure register RESET_STATE = 0x38, // get reset state PWC = 0x88, // configure rtc power DIG_ISO = 0x94, // congigure digital power isolation SWD_CONF = 0xB4, // congfigure super watch dog STORE4 = 0xC0, // reserved register DIG_PAD_HOLD = 0xDC, // configure digtal pad hold } private enum ResetReason : long { POWERON = 0x01, JTAG = 0x02, RTC_SW_SYS_RST = 0x03, DSLEEP = 0x05, TG0WDT_SYS_RST = 0x07, TG1WDT_SYS_RST = 0x08, RTCWDT_SYS_RST = 0x09, INTRUSION_RST = 0x0A, TG0WDT_CPU_RST = 0x0B, RTC_SW_CPU_RST = 0x0C, RTCWDT_CPU_RST = 0x0D, BROWNOUT_RST = 0x0F, RTCWDT_RTC_RST = 0x10, TG01DT_CPU_RST = 0x11, SUPER_WDT_RST = 0x12, GLITCH_RTC_RST = 0x13, EFUSE_RST = 0x14, USB_UART_CHIP_RESET = 0x15, USB_JTAG_CHIP_RESET = 0x16, POWER_GLITCH_RESET = 0x17, } } }