forked from liuwenbo/simulation_Peripheral
OC
This commit is contained in:
169
Custom_TLZA_OC_HDC1.cs
Normal file
169
Custom_TLZA_OC_HDC1.cs
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user