diff --git a/Custom_TLZA_ADU.cs b/Custom_TLZA_ADU.cs new file mode 100644 index 0000000..985115d --- /dev/null +++ b/Custom_TLZA_ADU.cs @@ -0,0 +1,238 @@ +using System; +using System.Collections.Generic; +using Antmicro.Renode.Core; +using Antmicro.Renode.Peripherals.Bus; +using Antmicro.Renode.Logging; + +namespace Antmicro.Renode.Peripherals.ADUADC0 +{ + public class ADU0 : IDoubleWordPeripheral, IKnownSize + { + // 通道组内部偏移(来自表格,未左移) + private const uint GROUP1_START = 0x122; // 通道 1-14 + private const uint GROUP2_START = 0x142; // 通道 15-28 + private const uint GROUP3_START = 0x162; // 通道 29-42 + private const uint GROUP4_START = 0x182; // 通道 43-56 + private const uint GROUP5_START = 0x1A2; // 通道 57-64 + + // 寄存器存储 + private readonly Dictionary registerMap; + private readonly object lockObject = new object(); + private readonly uint baseAddress; + + public ADU0(IMachine machine) + { + // ADC0基地址 + baseAddress = 0x21800000; + registerMap = new Dictionary(); + InitializeRegisters(); + LogInitializationInfo(); + } + + private void InitializeRegisters() + { + lock (lockObject) + { + // ========== 第一组: 通道 1-14 (ADC0通道1-14) ========== + // 通道 1-2 + registerMap[GROUP1_START << 2] = 1; + registerMap[(GROUP1_START << 2) + 4] = 2; + + // 通道 3-4 + registerMap[(GROUP1_START + 4) << 2] = 3; + registerMap[((GROUP1_START + 4) << 2) + 4] = 4; + + // 通道 5-6 + registerMap[(GROUP1_START + 8) << 2] = 5; + registerMap[((GROUP1_START + 8) << 2) + 4] = 6; + + // 通道 7-8 + registerMap[(GROUP1_START + 12) << 2] = 7; + registerMap[((GROUP1_START + 12) << 2) + 4] = 8; + + // 通道 9-10 + registerMap[(GROUP1_START + 16) << 2] = 9; + registerMap[((GROUP1_START + 16) << 2) + 4] = 10; + + // 通道 11-12 + registerMap[(GROUP1_START + 20) << 2] = 11; + registerMap[((GROUP1_START + 20) << 2) + 4] = 12; + + // 通道 13-14 + registerMap[(GROUP1_START + 24) << 2] = 13; + registerMap[((GROUP1_START + 24) << 2) + 4] = 14; + + // ========== 第二组: 通道 15-28 (ADC0通道15-28) ========== + // 通道 15-16 + registerMap[GROUP2_START << 2] = 15; + registerMap[(GROUP2_START << 2) + 4] = 16; + + // 通道 17-18 + registerMap[(GROUP2_START + 4) << 2] = 17; + registerMap[((GROUP2_START + 4) << 2) + 4] = 18; + + // 通道 19-20 + registerMap[(GROUP2_START + 8) << 2] = 19; + registerMap[((GROUP2_START + 8) << 2) + 4] = 20; + + // 通道 21-22 + registerMap[(GROUP2_START + 12) << 2] = 21; + registerMap[((GROUP2_START + 12) << 2) + 4] = 22; + + // 通道 23-24 + registerMap[(GROUP2_START + 16) << 2] = 23; + registerMap[((GROUP2_START + 16) << 2) + 4] = 24; + + // 通道 25-26 + registerMap[(GROUP2_START + 20) << 2] = 25; + registerMap[((GROUP2_START + 20) << 2) + 4] = 26; + + // 通道 27-28 + registerMap[(GROUP2_START + 24) << 2] = 27; + registerMap[((GROUP2_START + 24) << 2) + 4] = 28; + + // ========== 第三组: 通道 29-42 (ADC0通道29-42) ========== + // 通道 29-30 + registerMap[GROUP3_START << 2] = 29; + registerMap[(GROUP3_START << 2) + 4] = 30; + + // 通道 31-32 + registerMap[(GROUP3_START + 4) << 2] = 31; + registerMap[((GROUP3_START + 4) << 2) + 4] = 32; + + // 通道 33-34 + registerMap[(GROUP3_START + 8) << 2] = 33; + registerMap[((GROUP3_START + 8) << 2) + 4] = 34; + + // 通道 35-36 + registerMap[(GROUP3_START + 12) << 2] = 35; + registerMap[((GROUP3_START + 12) << 2) + 4] = 36; + + // 通道 37-38 + registerMap[(GROUP3_START + 16) << 2] = 37; + registerMap[((GROUP3_START + 16) << 2) + 4] = 38; + + // 通道 39-40 + registerMap[(GROUP3_START + 20) << 2] = 39; + registerMap[((GROUP3_START + 20) << 2) + 4] = 40; + + // 通道 41-42 + registerMap[(GROUP3_START + 24) << 2] = 41; + registerMap[((GROUP3_START + 24) << 2) + 4] = 42; + + // ========== 第四组: 通道 43-56 (ADC0通道43-56) ========== + // 通道 43-44 + registerMap[GROUP4_START << 2] = 43; + registerMap[(GROUP4_START << 2) + 4] = 44; + + // 通道 45-46 + registerMap[(GROUP4_START + 4) << 2] = 45; + registerMap[((GROUP4_START + 4) << 2) + 4] = 46; + + // 通道 47-48 + registerMap[(GROUP4_START + 8) << 2] = 47; + registerMap[((GROUP4_START + 8) << 2) + 4] = 48; + + // 通道 49-50 + registerMap[(GROUP4_START + 12) << 2] = 49; + registerMap[((GROUP4_START + 12) << 2) + 4] = 50; + + // 通道 51-52 + registerMap[(GROUP4_START + 16) << 2] = 51; + registerMap[((GROUP4_START + 16) << 2) + 4] = 52; + + // 通道 53-54 + registerMap[(GROUP4_START + 20) << 2] = 53; + registerMap[((GROUP4_START + 20) << 2) + 4] = 54; + + // 通道 55-56 + registerMap[(GROUP4_START + 24) << 2] = 55; + registerMap[((GROUP4_START + 24) << 2) + 4] = 56; + + // ========== 第五组: 通道 57-64 (ADC0通道57-64) ========== + // 通道 57-58 + registerMap[GROUP5_START << 2] = 57; + registerMap[(GROUP5_START << 2) + 4] = 58; + + // 通道 59-60 + registerMap[(GROUP5_START + 4) << 2] = 59; + registerMap[((GROUP5_START + 4) << 2) + 4] = 60; + + // 通道 61-62 + registerMap[(GROUP5_START + 8) << 2] = 61; + registerMap[((GROUP5_START + 8) << 2) + 4] = 62; + + // 通道 63-64 + registerMap[(GROUP5_START + 12) << 2] = 63; + registerMap[((GROUP5_START + 12) << 2) + 4] = 64; + } + } + + private void LogInitializationInfo() + { + this.Log(LogLevel.Info, "=========================================="); + this.Log(LogLevel.Info, "ADU0初始化完成"); + this.Log(LogLevel.Info, "ADC0基地址: 0x{0:X8}", baseAddress); + this.Log(LogLevel.Info, "64个通道寄存器,低16位有效,初始值=通道号"); + this.Log(LogLevel.Info, "通道1-64 (ADC0内部通道1-64)"); + this.Log(LogLevel.Info, ""); + this.Log(LogLevel.Info, "重要地址映射:"); + this.Log(LogLevel.Info, " 通道1 地址: 0x{0:X8}", baseAddress + (GROUP1_START << 2)); + this.Log(LogLevel.Info, " 通道2 地址: 0x{0:X8}", baseAddress + (GROUP1_START << 2) + 4); + this.Log(LogLevel.Info, " 通道64 地址: 0x{0:X8}", baseAddress + ((GROUP5_START + 12) << 2) + 4); + this.Log(LogLevel.Info, "=========================================="); + } + + public uint ReadDoubleWord(long offset) + { + lock (lockObject) + { + uint fullAddress = baseAddress + (uint)offset; + + if (registerMap.TryGetValue(offset, out ushort value)) + { + this.Log(LogLevel.Debug, "ADC0读取: 地址0x{0:X8} (偏移0x{1:X8}), 值0x{2:X4} (通道{3})", + fullAddress, offset, value, value); + return value; + } + + this.Log(LogLevel.Warning, "ADC0读取未定义地址: 0x{0:X8} (偏移0x{1:X8})", fullAddress, offset); + return 0; + } + } + + public void WriteDoubleWord(long offset, uint value) + { + lock (lockObject) + { + uint fullAddress = baseAddress + (uint)offset; + + if (registerMap.ContainsKey(offset)) + { + ushort writeValue = (ushort)(value & 0xFFFF); + registerMap[offset] = writeValue; + + this.Log(LogLevel.Info, "ADC0写入: 地址0x{0:X8} (偏移0x{1:X8}), 值0x{2:X4} (通道{3})", + fullAddress, offset, writeValue, writeValue); + } + else + { + this.Log(LogLevel.Warning, "ADC0尝试写入未定义地址: 0x{0:X8} (偏移0x{1:X8}), 值0x{2:X8}", + fullAddress, offset, value); + } + } + } + + public void Reset() + { + lock (lockObject) + { + registerMap.Clear(); + InitializeRegisters(); + } + this.Log(LogLevel.Info, "ADC0 (基地址0x{0:X8}) 已复位", baseAddress); + } + + public long Size => 0x0700; + } +} \ No newline at end of file