feat(set-protocol): добавь порт F407 для DevBoard_V1
This commit is contained in:
60
python/protocan/devboard_v1.py
Normal file
60
python/protocan/devboard_v1.py
Normal file
@@ -0,0 +1,60 @@
|
||||
"""CAN485 DevBoard_V1 USB command and frame helpers (no GUI/serial dependency)."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
FRAME_RE = re.compile(
|
||||
r"^\[\s*(\d+)\.(\d{3})\]\s+(?:(RS485)\s+)?"
|
||||
r"(EXT|STD)\s+0x([0-9A-Fa-f]+)\s+"
|
||||
r"(RTR\s+)?DLC=(\d)(?:\s+DATA=([0-9A-Fa-f ]*))?"
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class BoardFrame:
|
||||
timestamp: float
|
||||
extended: bool
|
||||
can_id: int
|
||||
data: bytes
|
||||
rtr: bool = False
|
||||
source: str = "CAN"
|
||||
|
||||
|
||||
def parse_frame_line(line: str) -> BoardFrame | None:
|
||||
match = FRAME_RE.match(line.strip())
|
||||
if match is None:
|
||||
return None
|
||||
seconds, millis, source, frame_type, raw_id, raw_rtr, raw_dlc, raw_data = match.groups()
|
||||
dlc = int(raw_dlc)
|
||||
data = bytes.fromhex(raw_data or "")
|
||||
rtr = bool(raw_rtr)
|
||||
if (not rtr and len(data) != dlc) or (rtr and data):
|
||||
return None
|
||||
extended = frame_type == "EXT"
|
||||
can_id = int(raw_id, 16)
|
||||
if can_id > (0x1FFFFFFF if extended else 0x7FF):
|
||||
return None
|
||||
return BoardFrame(int(seconds) + int(millis) / 1000.0, extended, can_id,
|
||||
data, rtr, source or "CAN")
|
||||
|
||||
|
||||
def command_transmit(frame: BoardFrame) -> bytes:
|
||||
if len(frame.data) > 8:
|
||||
raise ValueError("DLC cannot exceed 8")
|
||||
kind = "E" if frame.extended else "S"
|
||||
return f"T,{kind},{frame.can_id:X},{len(frame.data)},{frame.data.hex().upper()}\n".encode("ascii")
|
||||
|
||||
|
||||
def command_setup(*, can_bitrate: int = 500, rs485_baud: int = 512000,
|
||||
route: int = 3) -> tuple[bytes, ...]:
|
||||
if can_bitrate not in (25, 50, 100, 125, 250, 500, 800, 1000):
|
||||
raise ValueError("unsupported CAN bitrate")
|
||||
if not 1200 <= rs485_baud <= 4_000_000:
|
||||
raise ValueError("unsupported RS485 baud")
|
||||
if route not in range(4):
|
||||
raise ValueError("route must be 0..3")
|
||||
return (f"S{can_bitrate}\n".encode("ascii"), b"M0\n",
|
||||
f"B{rs485_baud}\n".encode("ascii"), f"Q{route}\n".encode("ascii"))
|
||||
Reference in New Issue
Block a user