Files

163 lines
4.9 KiB
C#
Raw Permalink Normal View History

//
// UART 外设实现
// 基于 UART 规格,包含完整的 FIFO、中断和调制解调器控制功能
//
using System;
using System.Collections.Generic;
using Antmicro.Renode.Core;
using Antmicro.Renode.Logging;
using Antmicro.Renode.Peripherals.Bus;
using Antmicro.Renode.Peripherals.UART;
using Antmicro.Renode.Utilities;
using Antmicro.Renode.Time;
namespace Antmicro.Renode.Peripherals.CustomPeripherals
{
/// <summary>
/// 毫秒计数器
/// </summary>
public class Custom_MS : IDoubleWordPeripheral, IKnownSize
{
private readonly IMachine machine;
public Custom_MS(IMachine machine)
{
this.machine = machine;
// 初始化寄存器
DefineRegisters();
Reset();
this.Log(LogLevel.Info, "Custom_MS initialized");
// 启动后台计时任务
// StartCountingTask();
}
public void Reset()
{
ms_cnt = 0; // 毫秒计数
rstr = 0x00; // 复位/使能寄存器
startTime = machine.ElapsedVirtualTime; //记录启动时间
this.Log(LogLevel.Info, "Custom_MS reset, startTime={0}", startTime.TimeElapsed);
}
void get_msCnt()
{
TimeStamp currentTime = machine.ElapsedVirtualTime;
TimeInterval timeDifference = currentTime.TimeElapsed - startTime.TimeElapsed;
double timeDiffMs = timeDifference.TotalMilliseconds;
// ms_cnt = (ushort)(timeDiffMs % 1000);
ms_cnt = (ushort)timeDiffMs;
this.Log(LogLevel.Info, "Custom_MS currentTime={0}", currentTime.TimeElapsed);
this.Log(LogLevel.Info, "Custom_MS timeDiffMs={0}", timeDiffMs);
}
private void DefineRegisters()
{
// 寄存器访问通过 ReadDoubleWord/WriteDoubleWord 实现
}
// ========================================
// IBusPeripheral 接口实现
// ========================================
public uint ReadDoubleWord(long offset)
{
return ReadRegisters(offset);
}
public void WriteDoubleWord(long offset, uint value)
{
WriteRegisters(offset, value);
}
// ========================================
// 自定义
// ========================================
public uint ReadRegisters(long offset)
{
uint value = 0;
switch (offset)
{
case (long)Registers.CNT_REG: // 毫秒延迟计时
get_msCnt();
value = (uint)ms_cnt;
this.Log(LogLevel.Info, "Read CNT_REG: {0}", value);
break;
case (long)Registers.RSTR_REG: // 复位/使能,暂无读操作
value = (uint)(rstr & 0xFF);
this.Log(LogLevel.Info, "Read RSTR_REG: 0x{0}", value);
break;
default:
this.Log(LogLevel.Warning, "Read to unknown offset: 0x{0:X}", offset);
break;
}
return value;
}
public void WriteRegisters(long offset, uint value)
{
switch (offset)
{
case (long)Registers.RSTR_REG: // 复位/使能,暂无读操作
rstr = (byte)(value & 0xFF);
this.Log(LogLevel.Info, "Write RSTR_REG: 0x{0:X2}", rstr);
if ((rstr & 0XFF) == RSTR_RES)
{
Reset();
}
break;
default:
this.Log(LogLevel.Warning, "Write to unknown offset: 0x{0:X}", offset);
break;
}
}
public long Size => 0x80; //uart地址长度总空间
// ========================================
// 寄存器定义
// ========================================
private enum Registers : long
{
CNT_REG = 0x00, // 毫秒延迟计时
RSTR_REG = 0x7C // 复位/使能 0x55复位清零其他使能
}
// RSTR 复位/使能寄存器
private const byte RSTR_RES = 0x55; // 0x55复位清零其他使能
// ========================================
// 私有字段
// ========================================
private TimeStamp startTime; // 记录累加器启动时间
// 寄存器
private ushort ms_cnt; // FIFO状态寄存器
private byte rstr; // 复位/使能
}
}