Metadata-Version: 2.4
Name: can-autosync
Version: 0.1.0
Summary: python-can backend for AutoSync USB CAN driver
Author: jiangjg
License: LGPL-2.1-only
Project-URL: Homepage, https://github.com/your-org/autosync_winusb
Classifier: Development Status :: 3 - Alpha
Classifier: License :: OSI Approved :: GNU Lesser General Public License v2 (LGPLv2)
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: Microsoft :: Windows
Requires-Python: >=3.10
Description-Content-Type: text/markdown
Requires-Dist: python-can>=4.6
Dynamic: requires-python

# python-can AutoSync Backend

AutoSync USB CAN 驱动的 python-can 后端，通过 ctypes 调用 `autosync.dll` 实现与 AutoSync USB CAN 设备的通信。

## 前置条件

- Windows 10/11
- Python 3.10+
- 已编译的 `autosync.dll`（见项目根目录 `CLAUDE.md` 中的构建说明）
- AutoSync USB CAN 设备已连接到电脑

## 安装

```bash
cd python_can_autosync
pip install -e .
```

`-e` 开发模式安装，代码修改后无需重新安装。安装完成后，python-can 会自动通过 entry_points 机制发现 `autosync` 接口。

验证安装：
```bash
python -c "import can_autosync; print('OK')"
```

## 注册到 python-can

安装后无需额外配置 — `setup.py` 中的 entry_points 已声明：

```python
entry_points={
    "can.interface": [
        "autosync = can_autosync:AutoSyncBus",
    ]
}
```

python-can 通过 `bustype="autosync"` 即可找到并使用该后端。

验证注册是否成功：
```python
import can
print(can.AvailableConfig)  # 列表中应包含 interface="autosync" 的条目
```

## 使用方式

### 基本使用

```python
import can

bus = can.Bus(
    channel=0,
    bustype="autosync",
    bitrate=500000,
    dll_path="C:/path/to/autosync.dll",
)

# 发送消息
msg = can.Message(arbitration_id=0x123, data=[0x01, 0x02, 0x03], is_extended_id=False)
bus.send(msg)

# 接收消息
received = bus.recv(timeout=1.0)
if received:
    print(f"ID: 0x{received.arbitration_id:X}, Data: {received.data.hex()}")

bus.shutdown()
```

### 环境变量方式指定 DLL

设置 `AUTOSYNC_DLL` 环境变量后，可省略 `dll_path` 参数：

```bash
set AUTOSYNC_DLL=C:\path\to\autosync.dll
```

```python
import can

bus = can.Bus(channel=0, bustype="autosync", bitrate=500000)
```

### CAN-FD 模式

```python
bus = can.Bus(
    channel=0,
    bustype="autosync",
    bitrate=500000,       # 名义位速率
    fd=True,              # 启用 CAN-FD
    data_bitrate=2000000, # 数据相位位速率
    fd_iso_mode=True,     # ISO CAN-FD 模式
    dll_path="C:/path/to/autosync.dll",
)

# 发送 FD 帧（最多 64 字节数据）
msg = can.Message(
    arbitration_id=0x400,
    data=[0x00] * 64,
    is_extended_id=True,
    is_fd=True,
    bitrate_switch=True,
)
bus.send(msg)
```

### 远程帧（RTR）

```python
msg = can.Message(
    arbitration_id=0x200,
    is_remote_frame=True,
    is_extended_id=False,
)
bus.send(msg)
```

### 硬件过滤器

设置单条硬件过滤器（仅接收指定 ID 的消息）：

```python
bus = can.Bus(
    channel=0,
    bustype="autosync",
    bitrate=500000,
    dll_path="C:/path/to/autosync.dll",
)

# can_id = 0x123, can_mask = 0x7FF → 精确匹配 0x123
bus.apply_filters([{"can_id": 0x123, "can_mask": 0x7FF}])
```

> **注意**：硬件仅支持单条过滤器。传入多条过滤器时会自动回退到软件过滤。

### 轮询接收（多通道）

```python
bus1 = can.Bus(channel=0, bustype="autosync", bitrate=500000, dll_path=dll)
bus2 = can.Bus(channel=1, bustype="autosync", bitrate=500000, dll_path=dll)

from can.notifier import Notifier

notifier = Notifier(
    [bus1, bus2],
    [MyListener()],
    stop_timingout=False,
)
notifier.start()
```

### 获取硬件统计信息

```python
stats = bus.get_stats()
print(f"RX: {stats['rx_count']}, TX: {stats['tx_count']}")
```

### 检测可用通道

```python
configs = can.AutoSyncBus._detect_available_configs()
for cfg in configs:
    print(f"Channel {cfg['channel']} available")
```

## 完整参数列表

| 参数 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `channel` | `int` | `0` | 通道索引（每台设备最多 6 个通道，最多 16 台设备） |
| `bitrate` / `can_baudrate` | `int` | `500000` | 名义位速率（bps），`can_baudrate` 优先级更高 |
| `fd` | `bool` | `False` | 是否启用 CAN-FD 模式 |
| `data_bitrate` / `canfd_baudrate` | `int` | `2000000` | FD 数据相位位速率 |
| `sample_point` / `can_sample_point` | `int` | `800` | 名义采样点（单位 ‰，800 = 80%） |
| `fd_sample_point` / `canfd_sample_point` | `int` | `800` | FD 数据相位采样点 |
| `fd_iso_mode` | `bool` | `True` | ISO CAN-FD 模式 |
| `dll_path` | `str` | 环境变量 `AUTOSYNC_DLL` | autosync.dll 的完整路径 |
| `echo_messages` | `bool` | `True` | 是否接收发送回显消息 |

## 与 canplayer / cansniffer 配合使用

```bash
# 抓包（需要设置环境变量 AUTOSYNC_DLL）
cansniffer -i autosync -c 0 -b 500000

# 回放（需配合 canlogconverter 或自定义脚本设置 dll_path）
# canplayer 不直接支持 dll_path 参数，建议编写简短 Python 脚本来回放
```

## 故障排查

| 问题 | 解决方案 |
|------|----------|
| `FileNotFoundError: autosync.dll not found` | 检查 `dll_path` 路径是否正确，或设置 `AUTOSYNC_DLL` 环境变量 |
| `AUTOSYNC_Initialize failed` | 确认设备已插入 USB，驱动正常工作 |
| `AUTOSYNC_CanOpen failed` | 检查通道号是否正确（0-based），设备是否被其他程序占用 |
| `AUTOSYNC_CanRead: queue empty` 且无超时返回 | 这是正常轮询行为，设置 `timeout` 参数即可 |
| 接收不到消息 | 检查硬件过滤器设置，或调用 `bus.apply_filters([])` 清除过滤器 |
