117 lines
3.9 KiB
Python
117 lines
3.9 KiB
Python
import platform.pch as pch
|
||
import asm
|
||
import t, c
|
||
|
||
|
||
|
||
# 串口端口定义
|
||
COM1_PORT: t.CDefine = 0x3F8 # COM1端口地址
|
||
COM2_PORT: t.CDefine = 0x2F8 # COM2端口地址
|
||
|
||
# 8250/16550 UART寄存器偏移
|
||
UART_RBR: t.CDefine = 0 # 接收缓冲区寄存器(读)
|
||
UART_THR: t.CDefine = 0 # 发送保持寄存器(写)
|
||
UART_DLL: t.CDefine = 0 # 除数锁存低位(写,DLAB=1)
|
||
UART_IER: t.CDefine = 1 # 中断使能寄存器
|
||
UART_DLM: t.CDefine = 1 # 除数锁存高位(写,DLAB=1)
|
||
UART_FCR: t.CDefine = 2 # FIFO控制寄存器
|
||
UART_IIR: t.CDefine = 2 # 中断识别寄存器(读)
|
||
UART_LCR: t.CDefine = 3 # 线路控制寄存器
|
||
UART_MCR: t.CDefine = 4 # 调制解调器控制寄存器
|
||
UART_LSR: t.CDefine = 5 # 线路状态寄存器
|
||
UART_MSR: t.CDefine = 6 # 调制解调器状态寄存器
|
||
UART_SCR: t.CDefine = 7 # scratch register
|
||
|
||
|
||
UART_LSR_THRE: t.CDefine = 0x20 # THRE:发送保持寄存器空
|
||
UART_LSR_TEMT: t.CDefine = 0x40 # TEMT:发送移位寄存器空(真正的发送完成)
|
||
|
||
|
||
# 线路控制寄存器位定义
|
||
UART_LCR_DLAB: t.CDefine = 0x80 # 除数锁存访问位
|
||
UART_LCR_8BIT: t.CDefine = 0x03 # 8位数据位
|
||
|
||
# 线路状态寄存器位定义
|
||
UART_LSR_DR: t.CDefine = 0x01 # 数据就绪
|
||
UART_LSR_THRE: t.CDefine = 0x20 # 发送保持寄存器空
|
||
|
||
# 波特率除数(115200 bps)
|
||
BAUD_115200: t.CDefine = 1
|
||
|
||
|
||
# 初始化UART 8250/16550
|
||
def init(port: t.CUInt16T):
|
||
# 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: t.CInt):
|
||
for i in range(count): c.Asm("nop")
|
||
|
||
# 检查发送缓冲区是否为空
|
||
def isTransmitEmpty(port: t.CUInt16T) -> t.CInt:
|
||
return asm.inb(port + UART_LSR) & UART_LSR_THRE
|
||
|
||
def putchar(port: t.CUInt16T, cr: t.CChar):
|
||
# 1. 处理换行符:串口终端需要\r\n才会正确换行,只发\n会错位
|
||
if cr == '\n':
|
||
# 直接发送\r,避免递归调用
|
||
timeout: t.CUInt32T = 1000000
|
||
while ((asm.inb(port + UART_LSR) & UART_LSR_THRE) == 0) and timeout:
|
||
c.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:
|
||
c.Asm("nop")
|
||
timeout -= 1
|
||
# 2. 等待发送缓冲区为空
|
||
timeout: t.CUInt32T = 1000000
|
||
while ((asm.inb(port + UART_LSR) & UART_LSR_THRE) == 0) and timeout:
|
||
c.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:
|
||
c.Asm("nop")
|
||
timeout -= 1
|
||
|
||
# 检查是否有数据可读
|
||
def isDataAvailable(port: t.CUInt16T) -> t.CInt:
|
||
return asm.inb(port + UART_LSR) & UART_LSR_DR
|
||
|
||
# 读取一个字符
|
||
def getchar(port: t.CUInt16T) -> t.CChar:
|
||
# 等待数据可用
|
||
while not isDataAvailable(port): pass
|
||
# 读取字符
|
||
return asm.inb(port + UART_RBR)
|