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; } }