Files
2026-06-16 15:40:19 +08:00

69 lines
3.4 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'''
4. UART 协议模块midware/protocol/uart_protocol.py
实现 UART 协议核心逻辑寄存器配置、FIFO 缓冲区写入 / 读取、校验和检测、日志记录,严格遵循需求中的字节操作规则:
'''
import struct
from loguru import logger
from midware.config.base_config import BUS_CONFIG, UART_CHIP_CONFIG, DEVICE_CONFIG_DICT
from midware.bus.cache_handler import CacheHandler
from midware.core.error_check import check_checksum
class UARTProtocol:
def __init__(self):
self.cache_handler = CacheHandler() # 缓存交互实例
self.write_byte = BUS_CONFIG["WRITE_BYTE_UART"] # 每次写入2字节
self.read_byte = BUS_CONFIG["WRITE_BYTE_UART"] # 每次读取2字节
def write_uart_fifo(self, device_name, raw_data):
"""将原始数据写入虚拟芯片FIFO缓冲区按UART协议每次2字节"""
if device_name not in DEVICE_CONFIG_DICT:
logger.error(f"UART外设不存在{device_name}")
return False
# 获取外设基地址、偏移地址
base_addr = DEVICE_CONFIG_DICT[device_name]["base_addr"]
offset_addr = DEVICE_CONFIG_DICT[device_name]["offset_addr"]
# 校验和检测
if not check_checksum(raw_data, "UART", device_name):
return False
# 不定长数据分块每次2字节写入
data_len = len(raw_data)
for i in range(0, data_len, self.write_byte):
# 截取2字节不足补0
chunk = raw_data[i:i+self.write_byte]
if len(chunk) < self.write_byte:
chunk += b'\x00' * (self.write_byte - len(chunk))
# 计算内存地址:基地址+偏移地址
mem_addr = base_addr + offset_addr + UART_CHIP_CONFIG["TBR"]
# 写入共享缓存sysbus WriteDoubleWord
self.cache_handler.write_double_word(mem_addr, struct.unpack(">H", chunk)[0])
logger.debug(f"UART外设{device_name}写入FIFO完成数据长度{data_len}")
return True
def read_uart_fifo(self, device_name):
"""从虚拟芯片FIFO缓冲区读取数据按UART协议每次2字节组成完整帧"""
if device_name not in DEVICE_CONFIG_DICT:
logger.error(f"UART外设不存在{device_name}")
return b""
# 获取外设基地址、偏移地址
base_addr = DEVICE_CONFIG_DICT[device_name]["base_addr"]
offset_addr = DEVICE_CONFIG_DICT[device_name]["offset_addr"]
# 读取FIFO剩余字节数
remain_addr = base_addr + offset_addr + UART_CHIP_CONFIG["FIFO_REMAIN"]
remain_bytes = self.cache_handler.read_double_word(remain_addr)
if remain_bytes == 0:
logger.debug(f"UART外设{device_name}FIFO缓冲区无数据")
return b""
# 分块读取每次2字节
raw_data = b""
for _ in range(0, remain_bytes, self.read_byte):
mem_addr = base_addr + offset_addr + UART_CHIP_CONFIG["TBR"]
# 从共享缓存读取sysbus ReadDoubleWord
data = self.cache_handler.read_double_word(mem_addr)
raw_data += struct.pack(">H", data)
# 去除补0的空字节得到完整帧
raw_data = raw_data.rstrip(b'\x00')
logger.debug(f"UART外设{device_name}读取FIFO完成数据长度{len(raw_data)}")
return raw_data
# 全局UART协议实例
uart_protocol = UARTProtocol()