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; // 复位/使能
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
}
|