Files
simulation_Peripheral/Custom_TLZA_OC_HDC1.cs
dengxingting 73aad61a78 OC
2026-03-23 10:53:21 +08:00

169 lines
6.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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;
}
}