Files
TermiNexus 3583f78efc refactor(kernel): 适配 ViperC 新语法
- 去掉不再需要的 import t, c
- class → struct(纯数据聚合)
- t.CArray[T, N] → [N]T
- static 修饰符移到类型前
- @__attribute(packed) → @__attribute__(packed)
- UHCI 中断回调参数改用 callable[[], int]
- 同步 CPUID 注释中的旧类型名
2026-10-26 22:39:56 +08:00

87 lines
3.2 KiB
Plaintext
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.
import drivers.usb.usb as usb
import drivers.usb.hid.hid as hid
import drivers.usb.uhci as uhci
import drivers.serial.uart.serial as serial
define MOUSE_BUF_SIZE = 1024
struct usb_mouse_packet:
buttons: uint8
dx: int16
dy: int16
wheel: int8
mse_buf: [MOUSE_BUF_SIZE]usb_mouse_packet
mse_buf_head: int = 0
mse_buf_tail: int = 0
mse_buf_count: int = 0
mse_dev: usb.usb_device* = None
mse_report: hid.hid_mouse_report
mse_initialized: int = 0
mse_slot_id: int = -1
def init() -> int:
global mse_dev, mse_initialized, mse_slot_id
dev: usb.usb_device* = usb.find_hid_device(0x02)
if dev is None:
serial.puts("[usb_mse] no USB mouse found\n")
return -1
mse_dev = dev
if hid.init_mouse(dev) != 0:
serial.puts("[usb_mse] init failed\n")
return -2
mse_initialized = 1
serial.puts("[usb_mse] initialized\n")
mse_slot_id = uhci.register_int_callback(_on_int_complete)
if mse_slot_id < 0:
serial.puts("[usb_mse] register callback failed\n")
mse_initialized = 0
return -3
# 中断传输长度不得超过 mse_report(4 字节),否则 DMA 越界写全局
mse_pkt_len: uint8 = 4
if dev.ep_in_max < 4: mse_pkt_len = uint8(dev.ep_in_max)
uhci.schedule_int_transfer(mse_slot_id, dev.addr, dev.ep_in, dev.ls, mse_pkt_len, dev.ep_in_toggle, &mse_report)
return 0
def _on_int_complete() -> int:
global mse_buf_head, mse_buf_tail, mse_buf_count
if mse_initialized == 0: return 0
if mse_report.dx != 0 or mse_report.dy != 0 or mse_report.buttons != 0:
if mse_buf_count < MOUSE_BUF_SIZE:
mse_buf[mse_buf_tail].buttons = mse_report.buttons
mse_buf[mse_buf_tail].dx = int16(mse_report.dx)
mse_buf[mse_buf_tail].dy = int16(mse_report.dy)
mse_buf[mse_buf_tail].wheel = mse_report.wheel
mse_buf_tail = mse_buf_tail + 1
if mse_buf_tail >= MOUSE_BUF_SIZE:
mse_buf_tail = 0
mse_buf_count += 1
dev: usb.usb_device* = mse_dev
if dev is not None and mse_slot_id >= 0:
mse_pkt_len2: uint8 = 4
if dev.ep_in_max < 4: mse_pkt_len2 = uint8(dev.ep_in_max)
# 推进 DATA0/DATA1 翻转位:本回调表示上一次中断 IN 事务已结束(IRQ 中 TD 不再
# ACTIVE),翻转后本次重排使用另一 PID。全仓仅此处推进 ep_in_toggle;不推进
# 则 TD token 的 toggle 位恒为 DATA0,DATA toggle 永不交替。
dev.ep_in_toggle = uint8(dev.ep_in_toggle ^ 1)
uhci.schedule_int_transfer(mse_slot_id, dev.addr, dev.ep_in, dev.ls, mse_pkt_len2, dev.ep_in_toggle, &mse_report)
return 0
def has_data() -> int:
if mse_buf_count > 0: return 1
return 0
def read_packet(out: usb_mouse_packet*) -> int:
global mse_buf_head, mse_buf_count
if mse_buf_count == 0: return -1
out.buttons = mse_buf[mse_buf_head].buttons
out.dx = mse_buf[mse_buf_head].dx
out.dy = mse_buf[mse_buf_head].dy
out.wheel = mse_buf[mse_buf_head].wheel
mse_buf_head = mse_buf_head + 1
if mse_buf_head >= MOUSE_BUF_SIZE:
mse_buf_head = 0
mse_buf_count -= 1
return 0