163 lines
4.9 KiB
C#
163 lines
4.9 KiB
C#
//
|
||
// 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; // 复位/使能
|
||
|
||
}
|
||
} |