Compare commits

...

2 Commits

Author SHA1 Message Date
dengxingting
73aad61a78 OC 2026-03-23 10:53:21 +08:00
dengxingting
71a97fd10d ADC代码(ADC0) 2026-03-23 10:49:49 +08:00
2 changed files with 407 additions and 0 deletions

238
Custom_TLZA_ADU.cs Normal file
View File

@@ -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<long, ushort> registerMap;
private readonly object lockObject = new object();
private readonly uint baseAddress;
public ADU0(IMachine machine)
{
// ADC0基地址
baseAddress = 0x21800000;
registerMap = new Dictionary<long, ushort>();
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;
}
}

169
Custom_TLZA_OC_HDC1.cs Normal file
View File

@@ -0,0 +1,169 @@
using System;
using System.Collections.Generic;
using Antmicro.Renode.Core;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Logging;
namespace Antmicro.Renode.Peripherals.ThermalOC
{
public class ThermalOC1 : IDoubleWordPeripheral, IKnownSize
{
private readonly Dictionary<long, byte> registerMap;
private readonly object lockObject = new object();
private readonly uint baseAddress;
private const uint REG_HEAT_1_8 = 0x20; // 1-8路加热输出
private const uint REG_HEAT_9_16 = 0x24; // 9-16路加热输出
private const uint REG_HEAT_17_24 = 0x28; // 17-24路加热输出
private const uint REG_HEAT_25_32 = 0x2C; // 25-32路加热输出
private const uint REG_HEAT_33_40 = 0x30; // 33-40路加热输出
private const uint REG_HEAT_41_48 = 0x34; // 41-48路加热输出
private const uint REG_HEAT_49_56 = 0x38; // 49-56路加热输出
private const uint REG_HEAT_57_64 = 0x3C; // 57-64路加热输出
private readonly (uint offset, int start, int end)[] registers = new[]
{
(REG_HEAT_1_8, 1, 8),
(REG_HEAT_9_16, 9, 16),
(REG_HEAT_17_24, 17, 24),
(REG_HEAT_25_32, 25, 32),
(REG_HEAT_33_40, 33, 40),
(REG_HEAT_41_48, 41, 48),
(REG_HEAT_49_56, 49, 56),
(REG_HEAT_57_64, 57, 64)
};
public ThermalOC1(IMachine machine)
{
baseAddress = 0x22000000;
registerMap = new Dictionary<long, byte>();
InitializeRegisters();
LogInitializationInfo();
}
private void InitializeRegisters()
{
lock (lockObject)
{
foreach (var reg in registers)
{
registerMap[reg.offset] = 0x00;
}
}
}
private void LogInitializationInfo()
{
this.Log(LogLevel.Info, "==========================================");
this.Log(LogLevel.Info, "热控OC1初始化完成");
this.Log(LogLevel.Info, "基地址: 0x{0:X8}", baseAddress);
this.Log(LogLevel.Info, "每个寄存器控制8路加热输出");
this.Log(LogLevel.Info, "共64路加热输出通道 (通道1-64)");
this.Log(LogLevel.Info, "寄存器定义: 低8位有效1表示输出0表示关闭");
this.Log(LogLevel.Info, "位对应关系: D0=通道起始, D7=通道起始+7");
this.Log(LogLevel.Info, "所有通道初始状态: 关闭");
this.Log(LogLevel.Info, "");
this.Log(LogLevel.Info, "寄存器地址映射:");
foreach (var reg in registers)
{
uint fullAddress = baseAddress + reg.offset;
this.Log(LogLevel.Info, " 地址0x{0:X8} (偏移0x{1:X2}), 控制通道{2}-{3}",
fullAddress, reg.offset, reg.start, reg.end);
}
this.Log(LogLevel.Info, "==========================================");
}
private string GetBinaryString(byte value)
{
return Convert.ToString(value, 2).PadLeft(8, '0');
}
private string GetChannelStatus(byte value, int start)
{
List<string> active = new List<string>();
for (int i = 0; i < 8; i++)
{
if ((value & (1 << i)) != 0)
{
active.Add($"通道{start + i}");
}
}
return active.Count > 0 ? string.Join(", ", active) : "无";
}
public uint ReadDoubleWord(long offset)
{
lock (lockObject)
{
uint fullAddress = baseAddress + (uint)offset;
foreach (var reg in registers)
{
if (offset == reg.offset)
{
if (registerMap.TryGetValue(offset, out byte value))
{
string binary = GetBinaryString(value);
string channels = GetChannelStatus(value, reg.start);
this.Log(LogLevel.Info, "热控OC1读取: 地址0x{0:X8} (偏移0x{1:X2})", fullAddress, offset);
this.Log(LogLevel.Info, " 十六进制: 0x{0:X2}", value);
this.Log(LogLevel.Info, " 二进制: {0} (D7-D0)", binary);
this.Log(LogLevel.Info, " 开启通道: {0}", channels);
return value;
}
break;
}
}
this.Log(LogLevel.Warning, "热控OC1读取未定义地址: 0x{0:X8}", fullAddress);
return 0;
}
}
public void WriteDoubleWord(long offset, uint value)
{
lock (lockObject)
{
uint fullAddress = baseAddress + (uint)offset;
byte writeValue = (byte)(value & 0xFF);
foreach (var reg in registers)
{
if (offset == reg.offset)
{
byte oldValue = registerMap.ContainsKey(offset) ? registerMap[offset] : (byte)0;
registerMap[offset] = writeValue;
string oldBinary = GetBinaryString(oldValue);
string newBinary = GetBinaryString(writeValue);
string newChannels = GetChannelStatus(writeValue, reg.start);
this.Log(LogLevel.Info, "热控OC1写入: 地址0x{0:X8} (偏移0x{1:X2})", fullAddress, offset);
this.Log(LogLevel.Info, " 写入值: 0x{0:X2} (二进制: {1})", writeValue, newBinary);
this.Log(LogLevel.Info, " 原值: 0x{0:X2} (二进制: {1})", oldValue, oldBinary);
this.Log(LogLevel.Info, " 开启通道: {0}", newChannels);
return;
}
}
this.Log(LogLevel.Warning, "热控OC1尝试写入未定义地址: 0x{0:X8}, 值0x{1:X2}", fullAddress, writeValue);
}
}
public void Reset()
{
lock (lockObject)
{
registerMap.Clear();
InitializeRegisters();
}
this.Log(LogLevel.Info, "热控OC1 (基地址0x{0:X8}) 已复位", baseAddress);
}
public long Size => 0x40;
}
}