diff --git a/UART_kx12A6_event.cs b/UART_kx12A6_event.cs
index b2ca13d..f2aadbc 100644
--- a/UART_kx12A6_event.cs
+++ b/UART_kx12A6_event.cs
@@ -1,502 +1,501 @@
-//
-// 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;
-// using Antmicro.Migrant;
-
-namespace Antmicro.Renode.Peripherals.CustomPeripherals
-{
- ///
- /// UART_771_RUHW_2CFG 控制器:同步串口、遥测、有中断
- /// 接收缓存0B,发送缓存2048B,输入时钟24MHz
- ///
- public class UART_771_RUHW_2CFG6 : IDoubleWordPeripheral, IKnownSize
- {
- private readonly IMachine machine;
- private readonly object txFifoLock = new object();
- private readonly object rxFifoLock = new object();
-
- public UART_771_RUHW_2CFG6(IMachine machine)
- {
- this.clockFrequency = 24000000;
- this.machine = machine;
- transmissionGeneration = 0;
-
- // 创建 FIFO
- txFifo = new Queue();
- rxFifo = new Queue();
-
- // 创建中断线
- IRQ = new GPIO();
-
- // 初始化寄存器
- DefineRegisters();
- Reset();
-
- this.Log(LogLevel.Info, "771 UART initialized, clock: {0} Hz", clockFrequency);
- }
-
- public void Reset()
- {
- lock(txFifoLock)
- {
- txFifo.Clear();
- }
- lock(rxFifoLock)
- {
- rxFifo.Clear();
- }
-
- fsta = FSTA_TEMP; // FIFO状态寄存器
- frm_cnt = 0; // 帧计数
- byte_cnt = 0;
- tbr = 0; // 发送FIFO剩余字节数
- currentBaudRate = 16384; // 时钟配置缺省为16384Hz
- clk_set = (ushort)(clockFrequency / (2 * currentBaudRate) - 1);
- scramble_ctrl = 0x00; // 加解扰使能禁止
- rstr = 0x00; // 复位/使能寄存器
-
- RxfifoEnabled = true;
- TxfifoEnabled = true; //发送fifo使能
-
- transmissionScheduled = false;
- transmissionGeneration++;
- InterruptTriggerCondition = false; //重置后不满足条件
-
- IRQ.Set(false);
- UpdateInterrupts();
-
- this.Log(LogLevel.Info, "TX_FIFO_SIZE reset");
- }
-
-
- 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.FSTA: // FIFO状态寄存器
- lock(txFifoLock)
- {
- value = (byte)(fsta & 0xFF);
- }
- this.Log(LogLevel.Info, "Read FSTA: 0x{0:X2}", value);
- break;
-
- case (long)Registers.FRM_CNT: //帧计数,待定
- lock(txFifoLock)
- {
- value = (uint)frm_cnt;
- }
- this.Log(LogLevel.Info, "Read FRM_CNT: {0}", value);
- break;
-
- case (long)Registers.TBR_FreeBytes: //发送FIFO剩余字节数
- lock(txFifoLock)
- {
- tbr = (ushort)txFifo.Count;
- }
- value = (uint)tbr;
- this.Log(LogLevel.Info, "Read TBR_FreeBytes: {0}", value);
- break;
-
- case (long)Registers.CLK_SET: //时钟配置,暂无读操作
- value = (uint)clk_set;
- this.Log(LogLevel.Info, "Read CLK_SET: {0}", value);
- break;
-
- case (long)Registers.SCRAMBLE_CTRL: //加解扰使能禁止,暂无读操作
- value = (uint)(scramble_ctrl & 0xFF);
- this.Log(LogLevel.Info, "Read SCRAMBLE_CTRL: 0x{0}", value);
- break;
-
- case (long)Registers.RSTR: // 复位/使能,暂无读操作
- value = (uint)(rstr & 0xFF);
- this.Log(LogLevel.Info, "Read RSTR: 0x{0}", value);
- break;
-
- default:
- this.Log(LogLevel.Warning, "Read to unknown offset: 0x{0:X} = 0x{1:X2}", offset, value);
- break;
- }
-
- return value;
- }
-
-
- public void WriteRegisters(long offset, uint value)
- {
-
- switch (offset)
- {
-
- case (long)Registers.TBR_RBR: // 发送FIFO
- WriteTBR(value);
- //this.Log(LogLevel.Info, "Write TBR_RBR: {0}", value);
- break;
-
- case (long)Registers.CLK_SET: // 时钟配置
- clk_set = (ushort)value;
- currentBaudRate = (ushort)(clockFrequency / 2 / (1 + value));
- this.Log(LogLevel.Info, "Write CLK_SET: {0}, currentBaudRate: {1}", value, currentBaudRate);
- // 计算传输速率
- ComputeTransRate();
- break;
-
- case (long)Registers.SCRAMBLE_CTRL: // 加解扰使能禁止
- scramble_ctrl = (byte)(value & 0xFF);
- this.Log(LogLevel.Info, "Write SCRAMBLE_CTRL: 0x{0:X2}", value);
- break;
-
- case (long)Registers.RSTR: // 复位/使能
- rstr = (byte)(value & 0xFF);
- this.Log(LogLevel.Info, "Write RSTR: 0x{0:X2}", rstr);
- if ((rstr & 0XFF) == RSTR_RES)
- {
- Reset();
- }
- break;
-
- default:
- this.Log(LogLevel.Warning, "Write to unknown offset: 0x{0:X} = 0x{1:X2}", offset, value);
- break;
- }
- }
-
-
- // ========================================
- // 按波特率计算传输速率,同步串口无起始位、停止位、奇偶校验位
- // ========================================
- public void ComputeTransRate()
- {
- // 计算传输时间
- int bitsPerByte = 8; // 数据位
-
- // 计算传输时间(秒),16384hz->488.24us
- if(currentBaudRate == 0)
- {
- return;
- }
- double secondsPerByte = (double)bitsPerByte / currentBaudRate;
- microsecondsPerByte = (ulong)(secondsPerByte * 1000000);
-
- this.Log(LogLevel.Debug,
- "Scheduling byte transmission: {0} bits @ {1} bps = {2}μs",
- bitsPerByte, currentBaudRate, microsecondsPerByte);
- }
-
- private void UpdateInterrupts()
- {
- if(InterruptTriggerCondition == false)
- {
- // FIFO空 → 必须先写满>64,期间绝对不触发中断
- IRQ.Set(false);
- return;
- }
-
- lock(txFifoLock)
- {
- // <64 中断,>96 清除,中间保持
- if (txFifo.Count < IRQ_MINBYTES)
- {
- IRQ.Set(true);
- this.Log(LogLevel.Info, "Interrupt asserted");
- }
- else if (txFifo.Count > IRQ_MAXBYTES)
- {
- IRQ.Set(false);
- }
- }
-
- }
-
-
- public void WriteTBR(uint value)
- {
- // 从星务接收数据 ,操作txFifo
- // value 低16位有效
- this.Log(LogLevel.Info, "Write TBR: 0x{0:X2}", value);
-
- lock(txFifoLock)
- {
- if (TxfifoEnabled)
- {
- if ((txFifo.Count + 2) <= TX_FIFO_SIZE)
- {
- bool wasEmpty = (txFifo.Count == 0);
-
- byte tmp = (byte)(value >> 8);
- txFifo.Enqueue(tmp);
- tmp = (byte)value;
- txFifo.Enqueue(tmp);
- fsta = (byte)(fsta & (~FSTA_TEMP)); // 发送缓冲区不为空,D0置0
-
- // 更新帧计数
- byte_cnt += 2;
- frm_cnt = (ushort)(byte_cnt / FRAME_LONG); // 遥测帧固定1024字节
-
- // FIFO从空变为非空
- if(wasEmpty)
- {
- this.Log(LogLevel.Info, "FIFO: Empty->NonEmpty");
- // 启动传输调度(事件驱动)
- ScheduleNextByteTransmit();
- }
-
- if (txFifo.Count >= (TX_FIFO_SIZE / 2))
- {
- // 置半满标志
- fsta = (byte)(fsta | FSTA_TLHF); // 发送FIFO半满,D2置1
- }
-
- if((InterruptTriggerCondition == false) && (txFifo.Count > IRQ_MINBYTES))
- {
- InterruptTriggerCondition = true;
- UpdateInterrupts();
- }
- }
- else
- {
- fsta = (byte)(fsta | FSTA_TFUL); // 发送FIFO满
- this.Log(LogLevel.Warning, "TX FIFO overflow");
- }
- }
- else
- {
- // 非 FIFO 模式,待定
- txFifo.Clear();
- txFifo.Enqueue((byte)value);
- fsta = (byte)(fsta & (~FSTA_TEMP)); // 发送缓冲区不为空,D0置0
- }
- }
-
- }
-
-
- // ========================================
- // 核心:按波特率调度发送(事件驱动)
- // ========================================
- private void ScheduleNextByteTransmit()
- {
- lock(txFifoLock)
- {
- // 防止重复调度
- if (transmissionScheduled)
- {
- return;
- }
-
- if (txFifo.Count == 0)
- {
- // FIFO空
- fsta = (byte)((fsta & 0xF0) | FSTA_TEMP);
- fsta |= FSTA_THHF; //空闲置1
- this.Log(LogLevel.Info, "TX FIFO empty");
- InterruptTriggerCondition = false;
- return;
- }
-
- if (txFifo.Count < (TX_FIFO_SIZE / 2))
- {
- // 清半满标志
- fsta = (byte)(fsta & (~FSTA_TLHF)); // 发送FIFO非半满,D2清0
- }
-
- transmissionScheduled = true;
- fsta = (byte)(fsta & (~FSTA_THHF)); //正在发送,置0
- var currentGeneration = transmissionGeneration;
-
- // 使用Renode虚拟时间调度
- machine.ScheduleAction(
- TimeInterval.FromMicroseconds(microsecondsPerByte),
- _ => TransmitOneByte(currentGeneration)
- );
- }
- }
-
- private void TransmitOneByte(ulong generation)
- {
- lock(txFifoLock)
- {
- transmissionScheduled = false;
-
- // 检查是否被Reset取消
- if (generation != transmissionGeneration)
- {
- this.Log(LogLevel.Debug, "Transmission cancelled (reset)");
- return;
- }
-
- if (txFifo.Count > 0)
- {
- byte data = txFifo.Dequeue();
-
- // 触发CharReceived事件(外部Backend可订阅 网络中间层改为订阅这个事件的方式)
- TransmitCharacter(data);
-
- this.Log(LogLevel.Info,
- "Transmitted: 0x{0:X2} ('{1}'), Remaining: {2}",
- data,
- (data >= 32 && data < 127) ? (char)data : '.',
- txFifo.Count);
-
- // 继续调度下一个字节
- UpdateInterrupts();
- ScheduleNextByteTransmit();
- }
- }
- }
-
-
-
-
- public string GetTXFIFODataString()
- {
- string data = "0x";
- byte tmp;
-
- // 从 TX FIFO 发送数据,中间层获取txfifo接口
-
- if(txFifo.Count == 0)
- {
- this.Log(LogLevel.Info, "TXFIFO Null");
- return "0x00";
- }
-
- while (txFifo.Count > 0)
- {
- tmp = txFifo.Dequeue();
- data += tmp.ToString("X2"); // 转换为16进制字符串
- }
-
- this.Log(LogLevel.Info, "Transmitted: 0x{0}, TXFIFO Null", data);
-
-
- UpdateInterrupts();
-
- return data;
- }
-
- // ========================================
- // 同步串口属性
- // ========================================
- public uint BaudRate => 0;
- public enum Bits { None }
- public Bits StopBits => Bits.None;
- public enum Parity { None }
- public Parity ParityBit => Parity.None;
-
- public uint GetFSTA() => fsta;
- public uint GetByteCount() => byte_cnt;
- public ushort GetFrameCount() => frm_cnt;
-
- private void TransmitCharacter(byte data) { }
-
-
- public long Size => 0x80; //uart地址长度总空间
-
- public GPIO IRQ { get; }
-
- // ========================================
- // 寄存器定义
- // ========================================
-
- private enum Registers : long
- {
- TBR_RBR = 0x00, // TBR发送FIFO
- FSTA = 0x04, // FIFO状态寄存器
- FRM_CNT = 0x08, // 帧计数
- TBR_FreeBytes = 0x0C, // 发送FIFO剩余字节数
- CLK_SET = 0x10, // 时钟配置
- SCRAMBLE_CTRL = 0x14, // 加解扰使能禁止
- RSTR = 0x7C // 复位/使能 x55复位;其他使能
- }
-
-
- // FSTA FIFO状态寄存器
- private const byte FSTA_TEMP = 0x01; // 发送FIFO空
- private const byte FSTA_TLHF= 0x02; // 发送FIFO半满
- private const byte FSTA_TFUL = 0x04; // 发送FIFO满
- private const byte FSTA_THHF = 0x08; // 1为空闲;0为正在发送
-
-
- // RSTR 复位/使能寄存器
- private const byte RSTR_RES = 0x55; // 0x55复位,其他使能
-
- private const byte SCRAMBLE_CTRL_ENABLE = 0x55; // 0x55加解扰使能,其他禁止
-
- // 常量
- private const int RX_FIFO_SIZE = 0; // 接收FIFO_SIZE
- private const int TX_FIFO_SIZE = 2048; // 发送FIFO_SIZE
- private const int FRAME_LONG = 1024; // 帧长固定为1024B
- private const int IRQ_MINBYTES = 64; // FIFO中的字节数小于64字节时会产生中断
- private const int IRQ_MAXBYTES = 96; // FIFO中的字节数大于96字节时会清中断
-
-
-
- // ========================================
- // 私有字段
- // ========================================
-
- private readonly uint clockFrequency;
- private uint currentBaudRate;
- private uint byte_cnt; // 字节计数,计算帧计数
-
- // 寄存器
- private byte fsta; // FIFO状态寄存器
- private ushort frm_cnt; // 帧计数
- private ushort tbr; // 发送FIFO剩余字节数
- private ushort clk_set; // 时钟配置
- private byte scramble_ctrl; // 加解扰使能禁止
- private byte rstr; // 复位/使能
-
-
- // FIFO
- private readonly Queue rxFifo;
- private readonly Queue txFifo;
- private bool RxfifoEnabled;
- private bool TxfifoEnabled;
- private bool transmissionScheduled;
- private ulong transmissionGeneration;
- private ulong microsecondsPerByte;
- private bool InterruptTriggerCondition; //FIFO为空后写入64字节才允许触发中断
-
-
-
- }
-}
+//
+// 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;
+using Antmicro.Migrant;
+
+namespace Antmicro.Renode.Peripherals.CustomPeripherals
+{
+ ///
+ /// UART_771_RUHW_2CFG 控制器:同步串口、遥测、有中断
+ /// 接收缓存0B,发送缓存2048B,输入时钟24MHz
+ ///
+ public class UART_771_RUHW_2CFG6 : IDoubleWordPeripheral, IKnownSize
+ {
+ private readonly IMachine machine;
+ private readonly object txFifoLock = new object();
+ private readonly object rxFifoLock = new object();
+
+ public UART_771_RUHW_2CFG6(IMachine machine)
+ {
+ this.clockFrequency = 24000000;
+ this.machine = machine;
+ transmissionGeneration = 0;
+
+ // 创建 FIFO
+ txFifo = new Queue();
+ rxFifo = new Queue();
+
+ // 创建中断线
+ IRQ = new GPIO();
+
+ // 初始化寄存器
+ DefineRegisters();
+ Reset();
+
+ this.Log(LogLevel.Info, "771 UART initialized, clock: {0} Hz", clockFrequency);
+ }
+
+ public void Reset()
+ {
+ lock(txFifoLock)
+ {
+ txFifo.Clear();
+ }
+ lock(rxFifoLock)
+ {
+ rxFifo.Clear();
+ }
+
+ fsta = FSTA_TEMP; // FIFO状态寄存器
+ frm_cnt = 0; // 帧计数
+ byte_cnt = 0;
+ tbr = 0; // 发送FIFO剩余字节数
+ currentBaudRate = 16384; // 时钟配置缺省为16384Hz
+ clk_set = (ushort)(clockFrequency / (2 * currentBaudRate) - 1);
+ scramble_ctrl = 0x00; // 加解扰使能禁止
+ rstr = 0x00; // 复位/使能寄存器
+
+ RxfifoEnabled = true;
+ TxfifoEnabled = true; //发送fifo使能
+
+ transmissionScheduled = false;
+ transmissionGeneration++;
+ InterruptTriggerCondition = false; //重置后不满足条件
+
+ IRQ.Set(false);
+ UpdateInterrupts();
+
+ this.Log(LogLevel.Info, "TX_FIFO_SIZE reset");
+ }
+
+
+ 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.FSTA: // FIFO状态寄存器
+ value = (byte)(fsta & 0xFF);
+ this.Log(LogLevel.Info, "Read FSTA: 0x{0:X2}", value);
+ break;
+
+ case (long)Registers.FRM_CNT: //帧计数,待定
+ value = (uint)frm_cnt;
+ this.Log(LogLevel.Info, "Read TBR_FreeBytes: {0}", value);
+ break;
+
+ case (long)Registers.TBR_FreeBytes: //发送FIFO剩余字节数
+ lock(txFifoLock)
+ {
+ tbr = (ushort)txFifo.Count;
+ }
+ value = (uint)tbr;
+ this.Log(LogLevel.Info, "Read TBR_FreeBytes: {0}", value);
+ break;
+
+ case (long)Registers.CLK_SET: //时钟配置,暂无读操作
+ value = (uint)clk_set;
+ this.Log(LogLevel.Info, "Read CLK_SET: {0}", value);
+ break;
+
+ case (long)Registers.SCRAMBLE_CTRL: //加解扰使能禁止,暂无读操作
+ value = (uint)(scramble_ctrl & 0xFF);
+ this.Log(LogLevel.Info, "Read SCRAMBLE_CTRL: 0x{0}", value);
+ break;
+
+ case (long)Registers.RSTR: // 复位/使能,暂无读操作
+ value = (uint)(rstr & 0xFF);
+ this.Log(LogLevel.Info, "Read RSTR: 0x{0}", value);
+ break;
+
+ default:
+ this.Log(LogLevel.Warning, "Read to unknown offset: 0x{0:X} = 0x{1:X2}", offset, value);
+ break;
+ }
+
+ return value;
+ }
+
+
+ public void WriteRegisters(long offset, uint value)
+ {
+
+ switch (offset)
+ {
+
+ case (long)Registers.TBR_RBR: // 发送FIFO
+ WriteTBR(value);
+ //this.Log(LogLevel.Info, "Write TBR_RBR: {0}", value);
+ break;
+
+ case (long)Registers.CLK_SET: // 时钟配置
+ clk_set = (ushort)value;
+ currentBaudRate = (ushort)(clockFrequency / 2 / (1 + value));
+ this.Log(LogLevel.Info, "Write CLK_SET: {0}, currentBaudRate: {1}", value, currentBaudRate);
+ // 计算传输速率
+ ComputeTransRate();
+ break;
+
+ case (long)Registers.SCRAMBLE_CTRL: // 加解扰使能禁止
+ scramble_ctrl = (byte)(value & 0xFF);
+ this.Log(LogLevel.Info, "Write SCRAMBLE_CTRL: 0x{0:X2}", value);
+ break;
+
+ case (long)Registers.RSTR: // 复位/使能
+ rstr = (byte)(value & 0xFF);
+ this.Log(LogLevel.Info, "Write RSTR: 0x{0:X2}", rstr);
+ if ((rstr & 0XFF) == RSTR_RES)
+ {
+ Reset();
+ }
+ break;
+
+ default:
+ this.Log(LogLevel.Warning, "Write to unknown offset: 0x{0:X} = 0x{1:X2}", offset, value);
+ break;
+ }
+ }
+
+
+ // ========================================
+ // 按波特率计算传输速率,同步串口无起始位、停止位、奇偶校验位
+ // ========================================
+ public void ComputeTransRate()
+ {
+ // 计算传输时间
+ int bitsPerByte = 8; // 数据位
+
+ // 计算传输时间(秒),16384hz->488.24us
+ if(currentBaudRate == 0)
+ {
+ return;
+ }
+ double secondsPerByte = (double)bitsPerByte / currentBaudRate;
+ microsecondsPerByte = (ulong)(secondsPerByte * 1000000);
+
+ this.Log(LogLevel.Debug,
+ "Scheduling byte transmission: {0} bits @ {1} bps = {2}μs",
+ bitsPerByte, currentBaudRate, microsecondsPerByte);
+ }
+
+ private void UpdateInterrupts()
+ {
+ if(InterruptTriggerCondition == false)
+ {
+ // FIFO空 → 必须先写满>64,期间绝对不触发中断
+ IRQ.Set(false);
+ return;
+ }
+
+ lock(txFifoLock)
+ {
+ // <64 中断,>96 清除,中间保持
+ if (txFifo.Count < IRQ_MINBYTES)
+ {
+ IRQ.Set(true);
+ this.Log(LogLevel.Info, "Interrupt asserted");
+ }
+ else if (txFifo.Count > IRQ_MAXBYTES)
+ {
+ IRQ.Set(false);
+ }
+ }
+
+ }
+
+
+ public void WriteTBR(uint value)
+ {
+ // 从星务接收数据 ,操作txFifo
+ // value 低16位有效
+ this.Log(LogLevel.Info, "Write TBR: 0x{0:X2}", value);
+
+ lock(txFifoLock)
+ {
+ if (TxfifoEnabled)
+ {
+ if ((txFifo.Count + 2) <= TX_FIFO_SIZE)
+ {
+ bool wasEmpty = (txFifo.Count == 0);
+
+ byte tmp = (byte)(value >> 8);
+ txFifo.Enqueue(tmp);
+ tmp = (byte)value;
+ txFifo.Enqueue(tmp);
+ fsta = (byte)(fsta & (~FSTA_TEMP)); // 发送缓冲区不为空,D0置0
+
+ // 更新帧计数
+ byte_cnt += 2;
+ frm_cnt = (ushort)(byte_cnt / FRAME_LONG); // 遥测帧固定1024字节
+
+ // FIFO从空变为非空
+ if(wasEmpty)
+ {
+ this.Log(LogLevel.Info, "FIFO: Empty->NonEmpty");
+ // 启动传输调度(事件驱动)
+ ScheduleNextByteTransmit();
+ }
+
+ if (txFifo.Count >= (TX_FIFO_SIZE / 2))
+ {
+ // 置半满标志
+ fsta = (byte)(fsta | FSTA_TLHF); // 发送FIFO半满,D2置1
+ }
+
+ if((InterruptTriggerCondition == false) && (txFifo.Count > IRQ_MINBYTES))
+ {
+ InterruptTriggerCondition = true;
+ UpdateInterrupts();
+ }
+ }
+ else
+ {
+ fsta = (byte)(fsta | FSTA_TFUL); // 发送FIFO满
+ this.Log(LogLevel.Warning, "TX FIFO overflow");
+ }
+ }
+ else
+ {
+ // 非 FIFO 模式,待定
+ txFifo.Clear();
+ txFifo.Enqueue((byte)value);
+ fsta = (byte)(fsta & (~FSTA_TEMP)); // 发送缓冲区不为空,D0置0
+ }
+ }
+
+ }
+
+
+ // ========================================
+ // 核心:按波特率调度发送(事件驱动)
+ // ========================================
+ private void ScheduleNextByteTransmit()
+ {
+ lock(txFifoLock)
+ {
+ // 防止重复调度
+ if (transmissionScheduled)
+ {
+ return;
+ }
+
+ if (txFifo.Count == 0)
+ {
+ // FIFO空
+ fsta = (byte)((fsta & 0xF0) | FSTA_TEMP);
+ fsta |= FSTA_THHF; //空闲置1
+ this.Log(LogLevel.Info, "TX FIFO empty");
+ InterruptTriggerCondition = false;
+ return;
+ }
+
+ if (txFifo.Count < (TX_FIFO_SIZE / 2))
+ {
+ // 清半满标志
+ fsta = (byte)(fsta & (~FSTA_TLHF)); // 发送FIFO非半满,D2清0
+ }
+
+ transmissionScheduled = true;
+ fsta = (byte)(fsta & (~FSTA_THHF)); //正在发送,置0
+ var currentGeneration = transmissionGeneration;
+
+ // 使用Renode虚拟时间调度
+ machine.ScheduleAction(
+ TimeInterval.FromMicroseconds(microsecondsPerByte),
+ _ => TransmitOneByte(currentGeneration)
+ );
+ }
+ }
+
+ private void TransmitOneByte(ulong generation)
+ {
+ lock(txFifoLock)
+ {
+ transmissionScheduled = false;
+
+ // 检查是否被Reset取消
+ if (generation != transmissionGeneration)
+ {
+ this.Log(LogLevel.Debug, "Transmission cancelled (reset)");
+ return;
+ }
+
+ if (txFifo.Count > 0)
+ {
+ byte data = txFifo.Dequeue();
+
+ // 触发CharReceived事件(外部Backend可订阅 网络中间层改为订阅这个事件的方式)
+ TransmitCharacter(data);
+
+ this.Log(LogLevel.Info,
+ "Transmitted: 0x{0:X2} ('{1}'), Remaining: {2}",
+ data,
+ (data >= 32 && data < 127) ? (char)data : '.',
+ txFifo.Count);
+
+ // 继续调度下一个字节
+ UpdateInterrupts();
+ ScheduleNextByteTransmit();
+ }
+ }
+ }
+
+
+
+
+ public string GetTXFIFODataString()
+ {
+ string data = "0x";
+ byte tmp;
+
+ // 从 TX FIFO 发送数据,中间层获取txfifo接口
+
+ if(txFifo.Count == 0)
+ {
+ this.Log(LogLevel.Info, "TXFIFO Null");
+ return "0x00";
+ }
+
+ while (txFifo.Count > 0)
+ {
+ tmp = txFifo.Dequeue();
+ data += tmp.ToString("X2"); // 转换为16进制字符串
+ }
+
+ this.Log(LogLevel.Info, "Transmitted: 0x{0}, TXFIFO Null", data);
+
+
+ UpdateInterrupts();
+
+ return data;
+ }
+
+ // ========================================
+ // 同步串口属性
+ // ========================================
+ public uint BaudRate => 0;
+ public enum Bits { None }
+ public Bits StopBits => Bits.None;
+ public enum Parity { None }
+ public Parity ParityBit => Parity.None;
+
+ public uint GetFSTA() => fsta;
+ public uint GetByteCount() => byte_cnt;
+ public ushort GetFrameCount() => frm_cnt;
+
+ public event Action CharReceived;
+
+ private void TransmitCharacter(byte data)
+ {
+ CharReceived?.Invoke(data);
+ }
+
+
+ public long Size => 0x80; //uart地址长度总空间
+
+ public GPIO IRQ { get; }
+
+ // ========================================
+ // 寄存器定义
+ // ========================================
+
+ private enum Registers : long
+ {
+ TBR_RBR = 0x00, // TBR发送FIFO
+ FSTA = 0x04, // FIFO状态寄存器
+ FRM_CNT = 0x08, // 帧计数
+ TBR_FreeBytes = 0x0C, // 发送FIFO剩余字节数
+ CLK_SET = 0x10, // 时钟配置
+ SCRAMBLE_CTRL = 0x14, // 加解扰使能禁止
+ RSTR = 0x7C // 复位/使能 x55复位;其他使能
+ }
+
+
+ // FSTA FIFO状态寄存器
+ private const byte FSTA_TEMP = 0x01; // 发送FIFO空
+ private const byte FSTA_TLHF= 0x02; // 发送FIFO半满
+ private const byte FSTA_TFUL = 0x04; // 发送FIFO满
+ private const byte FSTA_THHF = 0x08; // 1为空闲;0为正在发送
+
+
+ // RSTR 复位/使能寄存器
+ private const byte RSTR_RES = 0x55; // 0x55复位,其他使能
+
+ private const byte SCRAMBLE_CTRL_ENABLE = 0x55; // 0x55加解扰使能,其他禁止
+
+ // 常量
+ private const int RX_FIFO_SIZE = 0; // 接收FIFO_SIZE
+ private const int TX_FIFO_SIZE = 2048; // 发送FIFO_SIZE
+ private const int FRAME_LONG = 1024; // 帧长固定为1024B
+ private const int IRQ_MINBYTES = 64; // FIFO中的字节数小于64字节时会产生中断
+ private const int IRQ_MAXBYTES = 96; // FIFO中的字节数大于96字节时会清中断
+
+
+
+ // ========================================
+ // 私有字段
+ // ========================================
+
+ private readonly uint clockFrequency;
+ private uint currentBaudRate;
+ private uint byte_cnt; // 字节计数,计算帧计数
+
+ // 寄存器
+ private byte fsta; // FIFO状态寄存器
+ private ushort frm_cnt; // 帧计数
+ private ushort tbr; // 发送FIFO剩余字节数
+ private ushort clk_set; // 时钟配置
+ private byte scramble_ctrl; // 加解扰使能禁止
+ private byte rstr; // 复位/使能
+
+
+ // FIFO
+ private readonly Queue rxFifo;
+ private readonly Queue txFifo;
+ private bool RxfifoEnabled;
+ private bool TxfifoEnabled;
+ private bool transmissionScheduled;
+ private ulong transmissionGeneration;
+ private ulong microsecondsPerByte;
+ private bool InterruptTriggerCondition; //FIFO为空后写入64字节才允许触发中断
+
+
+
+ }
+}