- 去掉不再需要的 import t, c - class → struct(纯数据聚合) - t.CArray[T, N] → [N]T - static 修饰符移到类型前 - @__attribute(packed) → @__attribute__(packed) - UHCI 中断回调参数改用 callable[[], int] - 同步 CPUID 注释中的旧类型名
115 lines
3.7 KiB
Plaintext
115 lines
3.7 KiB
Plaintext
import asm
|
||
|
||
|
||
|
||
# 串口端口定义
|
||
define COM1_PORT = 0x3F8 # COM1端口地址
|
||
define COM2_PORT = 0x2F8 # COM2端口地址
|
||
|
||
# 8250/16550 UART寄存器偏移
|
||
define UART_RBR = 0 # 接收缓冲区寄存器(读)
|
||
define UART_THR = 0 # 发送保持寄存器(写)
|
||
define UART_DLL = 0 # 除数锁存低位(写,DLAB=1)
|
||
define UART_IER = 1 # 中断使能寄存器
|
||
define UART_DLM = 1 # 除数锁存高位(写,DLAB=1)
|
||
define UART_FCR = 2 # FIFO控制寄存器
|
||
define UART_IIR = 2 # 中断识别寄存器(读)
|
||
define UART_LCR = 3 # 线路控制寄存器
|
||
define UART_MCR = 4 # 调制解调器控制寄存器
|
||
define UART_LSR = 5 # 线路状态寄存器
|
||
define UART_MSR = 6 # 调制解调器状态寄存器
|
||
define UART_SCR = 7 # scratch register
|
||
|
||
|
||
define UART_LSR_THRE = 0x20 # THRE:发送保持寄存器空
|
||
define UART_LSR_TEMT = 0x40 # TEMT:发送移位寄存器空(真正的发送完成)
|
||
|
||
|
||
# 线路控制寄存器位定义
|
||
define UART_LCR_DLAB = 0x80 # 除数锁存访问位
|
||
define UART_LCR_8BIT = 0x03 # 8位数据位
|
||
|
||
# 线路状态寄存器位定义
|
||
define UART_LSR_DR = 0x01 # 数据就绪
|
||
define UART_LSR_THRE = 0x20 # 发送保持寄存器空
|
||
|
||
# 波特率除数(115200 bps)
|
||
define BAUD_115200 = 1
|
||
|
||
|
||
# 初始化UART 8250/16550
|
||
def init(port: uint16):
|
||
# 1. 禁用中断
|
||
asm.outb(port + UART_IER, 0x00)
|
||
delay(1000)
|
||
# 2. 设置波特率除数(115200 bps)
|
||
asm.outb(port + UART_LCR, UART_LCR_DLAB) # 设置DLAB位
|
||
delay(1000)
|
||
asm.outb(port + UART_DLL, 0x01) # 除数低位 (115200 bps)
|
||
delay(1000)
|
||
asm.outb(port + UART_DLM, 0x00) # 除数高位
|
||
delay(1000)
|
||
# 3. 设置线路控制:8位数据位,1位停止位,无校验
|
||
asm.outb(port + UART_LCR, UART_LCR_8BIT)
|
||
delay(1000)
|
||
# 4. 初始化FIFO
|
||
asm.outb(port + UART_FCR, 0x07) # 启用FIFO,清除接收和发送FIFO
|
||
delay(1000)
|
||
# 5. 设置调制解调器控制
|
||
asm.outb(port + UART_MCR, 0x03) # 启用DTR、RTS
|
||
delay(1000)
|
||
# 6. 清除任何待处理的中断
|
||
asm.inb(port + UART_IIR)
|
||
delay(1000)
|
||
asm.inb(port + UART_RBR)
|
||
delay(1000)
|
||
# 7. 等待一段时间让设备稳定
|
||
delay(10000)
|
||
|
||
# 延迟函数
|
||
def delay(count: int):
|
||
for _ in range(count): asm.nop()
|
||
|
||
# 检查发送缓冲区是否为空
|
||
def isTransmitEmpty(port: uint16) -> int:
|
||
return asm.inb(port + UART_LSR) & UART_LSR_THRE
|
||
|
||
def putchar(port: uint16, cr: char):
|
||
# 1. 处理换行符:串口终端需要\r\n才会正确换行,只发\n会错位
|
||
if cr == '\n':
|
||
# 直接发送\r,避免递归调用
|
||
timeout: uint32 = 1000000
|
||
while ((asm.inb(port + UART_LSR) & UART_LSR_THRE) == 0) and timeout:
|
||
asm.nop()
|
||
timeout -= 1
|
||
if timeout == 0: return
|
||
asm.outb(port + UART_THR, '\r')
|
||
timeout = 1000000
|
||
while ((asm.inb(port + UART_LSR) & UART_LSR_TEMT) == 0) and timeout:
|
||
asm.nop()
|
||
timeout -= 1
|
||
# 2. 等待发送缓冲区为空
|
||
timeout: uint32 = 1000000
|
||
while ((asm.inb(port + UART_LSR) & UART_LSR_THRE) == 0) and timeout:
|
||
asm.nop()
|
||
timeout -= 1
|
||
if timeout == 0: return
|
||
# 3. 发送字符
|
||
asm.outb(port + UART_THR, cr)
|
||
# 4. 等待发送完成
|
||
timeout = 1000000
|
||
while ((asm.inb(port + UART_LSR) & UART_LSR_TEMT) == 0) and timeout:
|
||
asm.nop()
|
||
timeout -= 1
|
||
|
||
# 检查是否有数据可读
|
||
def isDataAvailable(port: uint16) -> int:
|
||
return asm.inb(port + UART_LSR) & UART_LSR_DR
|
||
|
||
# 读取一个字符
|
||
def getchar(port: uint16) -> char:
|
||
# 等待数据可用
|
||
while not isDataAvailable(port): pass
|
||
# 读取字符
|
||
return asm.inb(port + UART_RBR)
|