Set CAN1 to 500K and CAN2 to 250K with matching DBCs and PDF
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
VERSION "AMI-2.0-2026-10-03"
|
||||
VERSION "AMI-2.1-2026-10-03"
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
@@ -65,7 +65,7 @@ BO_ 2556444915 BMS_Status_Extended: 8 BMS
|
||||
BO_ 2556510451 BMS_Extremes_Extended: 8 BMS
|
||||
SG_ Maximum_Cell_Temperature : 39|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
|
||||
CM_ "AMI CAN interface v2.0. Classic CAN at 500000 bit/s. CAN1 and CAN2 use identical IDs and parsing. SDC fields follow SDC_ACQ_DAC.dbc VERSION 1.1. BMS consumed fields follow BmsMonitor-CANTest commit e65c95203d1689df05343775982d7e85bd782646. Omitted bytes/signals are not interpreted by the AMI firmware. No motor temperature, calibrated vehicle speed, torque, task execution feedback or AMI heartbeat frame is defined.";
|
||||
CM_ "AMI CAN interface v2.1. CAN1: 500000 bit/s; CAN2: 250000 bit/s. Both use Classic CAN, identical IDs, parsing and task request capability. This file is CAN1; use AMI_CAN2_250k.dbc for CAN2. Frames are not bridged between buses. SDC fields follow SDC_ACQ_DAC.dbc VERSION 1.1. BMS consumed fields follow BmsMonitor-CANTest commit e65c95203d1689df05343775982d7e85bd782646. Omitted bytes/signals are not interpreted by the AMI firmware. No motor temperature, calibrated vehicle speed, torque, task execution feedback or AMI heartbeat frame is defined.";
|
||||
CM_ BU_ AMI "Instrument MCU. UART HMI task confirmation produces AMI_TaskRequest. Display values are received from SDC and BMS.";
|
||||
CM_ BU_ VCU "Logical receiver of task selection requests; execution and safety interlocks are outside this AMI interface.";
|
||||
CM_ BU_ SDC_ACQ_DAC "Source of ADC, capture frequencies and raw PD0-PD14 states; both SDC CAN ports carry the same protocol.";
|
||||
@@ -121,12 +121,15 @@ VAL_ 2556510451 Maximum_Cell_Temperature 255 "Invalid";
|
||||
|
||||
BA_DEF_ "BusType" STRING;
|
||||
BA_DEF_ "Baudrate" INT 0 1000000;
|
||||
BA_DEF_ "AMIPort" STRING;
|
||||
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 2147483647;
|
||||
BA_DEF_DEF_ "BusType" "CAN";
|
||||
BA_DEF_DEF_ "Baudrate" 500000;
|
||||
BA_DEF_DEF_ "AMIPort" "CAN1";
|
||||
BA_DEF_DEF_ "GenMsgCycleTime" 0;
|
||||
BA_ "BusType" "CAN";
|
||||
BA_ "Baudrate" 500000;
|
||||
BA_ "AMIPort" "CAN1";
|
||||
BA_ "GenMsgCycleTime" BO_ 1696 100;
|
||||
BA_ "GenMsgCycleTime" BO_ 1697 500;
|
||||
BA_ "GenMsgCycleTime" BO_ 1698 20;
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
VERSION "AMI-2.1-2026-10-03"
|
||||
|
||||
NS_ :
|
||||
NS_DESC_
|
||||
CM_
|
||||
BA_DEF_
|
||||
BA_
|
||||
VAL_
|
||||
BA_DEF_DEF_
|
||||
|
||||
BS_:
|
||||
|
||||
BU_: AMI VCU SDC_ACQ_DAC BMS
|
||||
|
||||
BO_ 768 AMI_TaskRequest: 8 AMI
|
||||
SG_ Protocol_Version : 0|8@1+ (1,0) [1|1] "" VCU
|
||||
SG_ Task_ID : 8|8@1+ (1,0) [1|6] "" VCU
|
||||
SG_ Request_Sequence : 16|8@1+ (1,0) [0|255] "" VCU
|
||||
SG_ Request_Source : 24|8@1+ (1,0) [1|1] "" VCU
|
||||
SG_ MCU_Uptime : 32|32@1+ (1,0) [0|4294967295] "ms" VCU
|
||||
|
||||
BO_ 1696 SDC_Heartbeat: 8 SDC_ACQ_DAC
|
||||
SG_ Board_Identifier : 0|8@1+ (1,0) [0|255] "" AMI
|
||||
SG_ Protocol_Version : 8|8@1+ (1,0) [0|255] "" AMI
|
||||
SG_ Heartbeat_Sequence : 16|16@1+ (1,0) [0|65535] "" AMI
|
||||
SG_ Uptime : 32|32@1+ (0.001,0) [0|4294967.295] "s" AMI
|
||||
|
||||
BO_ 1697 SDC_ADC_InputVoltage: 2 SDC_ACQ_DAC
|
||||
SG_ Input_Voltage : 0|16@1+ (0.001,0) [0|65.535] "V" AMI
|
||||
|
||||
BO_ 1698 SDC_InputFrequencies: 8 SDC_ACQ_DAC
|
||||
SG_ Frequency_LeftFront_PA0 : 0|16@1+ (1,0) [0|65535] "Hz" AMI
|
||||
SG_ Frequency_PA2 : 16|16@1+ (1,0) [0|65535] "Hz" AMI
|
||||
SG_ Frequency_RightFront_PA6 : 32|16@1+ (1,0) [0|65535] "Hz" AMI
|
||||
SG_ Frequency_PB14 : 48|16@1+ (1,0) [0|65535] "Hz" AMI
|
||||
|
||||
BO_ 1700 SDC_DAC_Ack: 4 SDC_ACQ_DAC
|
||||
SG_ DAC_Set_Result : 0|8@1+ (1,0) [0|1] "" AMI
|
||||
SG_ DAC_Select : 8|8@1+ (1,0) [1|2] "" AMI
|
||||
SG_ DAC_Output_Voltage : 16|16@1+ (0.001,0) [0|5] "V" AMI
|
||||
|
||||
BO_ 1702 SDC_GPIO_Status: 8 SDC_ACQ_DAC
|
||||
SG_ SDC_Input_State : 0|15@1+ (1,0) [0|32767] "" AMI
|
||||
SG_ SDC_Changed_Mask : 16|15@1+ (1,0) [0|32767] "" AMI
|
||||
SG_ Timestamp : 32|32@1+ (0.001,0) [0|4294967.295] "s" AMI
|
||||
|
||||
BO_ 320 BMS_Status: 8 BMS
|
||||
SG_ Pack_Voltage : 7|16@0+ (0.1,0) [0|6553.5] "V" AMI
|
||||
SG_ Pack_Current : 23|16@0+ (0.1,-500) [-500|6053.5] "A" AMI
|
||||
|
||||
BO_ 342 BMS_Temperatures: 8 BMS
|
||||
SG_ Temperature_1 : 7|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_2 : 15|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_3 : 23|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_4 : 31|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_5 : 39|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_6 : 47|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_7 : 55|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
SG_ Temperature_8 : 63|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
|
||||
BO_ 2556444915 BMS_Status_Extended: 8 BMS
|
||||
SG_ Pack_Voltage : 7|16@0+ (0.1,0) [0|6553.5] "V" AMI
|
||||
SG_ Pack_Current : 23|16@0+ (0.1,-500) [-500|6053.5] "A" AMI
|
||||
|
||||
BO_ 2556510451 BMS_Extremes_Extended: 8 BMS
|
||||
SG_ Maximum_Cell_Temperature : 39|8@0+ (1,-40) [-40|215] "degC" AMI
|
||||
|
||||
CM_ "AMI CAN interface v2.1. CAN1: 500000 bit/s; CAN2: 250000 bit/s. Both use Classic CAN, identical IDs, parsing and task request capability. This file is CAN2; use AMI.dbc for CAN1. Frames are not bridged between buses. SDC fields follow SDC_ACQ_DAC.dbc VERSION 1.1. BMS consumed fields follow BmsMonitor-CANTest commit e65c95203d1689df05343775982d7e85bd782646. Omitted bytes/signals are not interpreted by the AMI firmware. No motor temperature, calibrated vehicle speed, torque, task execution feedback or AMI heartbeat frame is defined.";
|
||||
CM_ BU_ AMI "Instrument MCU. UART HMI task confirmation produces AMI_TaskRequest. Display values are received from SDC and BMS.";
|
||||
CM_ BU_ VCU "Logical receiver of task selection requests; execution and safety interlocks are outside this AMI interface.";
|
||||
CM_ BU_ SDC_ACQ_DAC "Source of ADC, capture frequencies and raw PD0-PD14 states; both SDC CAN ports carry the same protocol.";
|
||||
CM_ BU_ BMS "Logical BMS source. Source frame periods are not specified here; do not infer them from test traffic.";
|
||||
|
||||
CM_ BO_ 768 "Standard ID 0x300, DLC 8. Event-driven: one request on valid HMI task confirmation, none on cancel. Counter wraps at 255. Request is not proof of execution and is not SDC ASSI_Lamp_Set (0x6A5). No CAN application-level acknowledgement is defined. Route to ports with valid RX within 500 ms; if none, attempt both.";
|
||||
CM_ SG_ 768 Protocol_Version "Fixed 1.";
|
||||
CM_ SG_ 768 Task_ID "Valid task values are 1 through 6.";
|
||||
CM_ SG_ 768 Request_Sequence "Zero at MCU boot; increments after the request is queued on all target ports, modulo 256.";
|
||||
CM_ SG_ 768 Request_Source "Fixed 1 = AMI HMI.";
|
||||
CM_ SG_ 768 MCU_Uptime "Unsigned MCU HAL_GetTick milliseconds, little-endian. Natural uint32 wrap.";
|
||||
|
||||
CM_ BO_ 1696 "Standard ID 0x6A0, DLC 8, 100 ms. AMI accepts board identifier 0xA1 and protocol version 1.";
|
||||
CM_ BO_ 1697 "Standard ID 0x6A1, DLC exactly 2, 500 ms. Calibrated input voltage before the SDC divider. AMI uses it exclusively as low-voltage battery voltage. Do not apply the divider again.";
|
||||
CM_ SG_ 1697 Input_Voltage "On-wire uint16 mV, decoded in V. dash.lvbat uses 0.01 V integer display units: (raw_mV + 5) / 10. Source expires after 1500 ms.";
|
||||
CM_ BO_ 1698 "Standard ID 0x6A2, DLC 8, 20 ms. Preserve Hz; wheel circumference and pulses per revolution are undefined, so AMI does not convert to km/h.";
|
||||
CM_ BO_ 1700 "Standard ID 0x6A4, DLC 4. Response to a DAC command. AMI recognizes the frame but does not update a display value from it.";
|
||||
CM_ BO_ 1702 "Standard ID 0x6A6, DLC 8. Sent at startup and on PD0-PD14 changes, not periodically. AMI stores raw state, change mask and timestamp. No mapping to named d0-d15 safety signals or normal polarity is defined.";
|
||||
CM_ SG_ 1702 SDC_Input_State "Bit n maps directly to PDn for n=0..14. Bits 15 and 31 in the payload are unused.";
|
||||
CM_ SG_ 1702 SDC_Changed_Mask "Bit n indicates PDn changed since the preceding GPIO status frame.";
|
||||
|
||||
CM_ BO_ 320 "Standard ID 0x140, DLC 8. AMI consumes only bytes 0..3: big-endian unsigned voltage and offset unsigned current. Other payload bytes are outside this DBC subset. Display rounds voltage/current to whole V/A; source expires after 2000 ms.";
|
||||
CM_ SG_ 320 Pack_Current "Current = raw_uint16 * 0.1 - 500 A; raw 5000 is zero current. This is not a signed int16 field.";
|
||||
CM_ BO_ 342 "Standard ID 0x156, DLC 8. Eight actual temperature channels. Raw 0xFF is invalid, not 215 degC. AMI takes the maximum of valid channels only; all invalid clears validity. Maximum is derived, not another on-wire signal. Source expires after 2000 ms.";
|
||||
CM_ SG_ 342 Temperature_1 "Raw byte 0xFF is invalid. Numeric decoders with choices disabled may return 215; check the raw sentinel before aggregation.";
|
||||
CM_ SG_ 342 Temperature_2 "Raw byte 0xFF is invalid.";
|
||||
CM_ SG_ 342 Temperature_3 "Raw byte 0xFF is invalid.";
|
||||
CM_ SG_ 342 Temperature_4 "Raw byte 0xFF is invalid.";
|
||||
CM_ SG_ 342 Temperature_5 "Raw byte 0xFF is invalid.";
|
||||
CM_ SG_ 342 Temperature_6 "Raw byte 0xFF is invalid.";
|
||||
CM_ SG_ 342 Temperature_7 "Raw byte 0xFF is invalid.";
|
||||
CM_ SG_ 342 Temperature_8 "Raw byte 0xFF is invalid. Synthetic channels 9/10 from the reference UI are not on-wire channels.";
|
||||
CM_ BO_ 2556444915 "Extended arbitration ID 0x186040F3, DLC 8. Same consumed voltage/current layout as standard 0x140. DBC BO_ numeric ID includes the extended-frame flag 0x80000000.";
|
||||
CM_ SG_ 2556444915 Pack_Current "Current = raw_uint16 * 0.1 - 500 A.";
|
||||
CM_ BO_ 2556510451 "Extended arbitration ID 0x186140F3, DLC 8. AMI consumes byte 4 as maximum cell temperature. Raw 0xFF is invalid. Other bytes, including BMS low-voltage bytes 6..7, are not used and cannot override SDC ADC. DBC BO_ numeric ID includes 0x80000000.";
|
||||
|
||||
VAL_ 768 Protocol_Version 1 "Version_1";
|
||||
VAL_ 768 Task_ID 1 "Skidpad" 2 "Acceleration" 3 "Autocross" 4 "Inspection_Test" 5 "EBS_Test" 6 "Manual_Driving";
|
||||
VAL_ 768 Request_Source 1 "AMI_HMI";
|
||||
VAL_ 1696 Board_Identifier 161 "A11_F407";
|
||||
VAL_ 1696 Protocol_Version 1 "Version_1";
|
||||
VAL_ 1700 DAC_Set_Result 0 "Failed" 1 "OK";
|
||||
VAL_ 1700 DAC_Select 1 "DAC1" 2 "DAC2";
|
||||
VAL_ 342 Temperature_1 255 "Invalid";
|
||||
VAL_ 342 Temperature_2 255 "Invalid";
|
||||
VAL_ 342 Temperature_3 255 "Invalid";
|
||||
VAL_ 342 Temperature_4 255 "Invalid";
|
||||
VAL_ 342 Temperature_5 255 "Invalid";
|
||||
VAL_ 342 Temperature_6 255 "Invalid";
|
||||
VAL_ 342 Temperature_7 255 "Invalid";
|
||||
VAL_ 342 Temperature_8 255 "Invalid";
|
||||
VAL_ 2556510451 Maximum_Cell_Temperature 255 "Invalid";
|
||||
|
||||
BA_DEF_ "BusType" STRING;
|
||||
BA_DEF_ "Baudrate" INT 0 1000000;
|
||||
BA_DEF_ "AMIPort" STRING;
|
||||
BA_DEF_ BO_ "GenMsgCycleTime" INT 0 2147483647;
|
||||
BA_DEF_DEF_ "BusType" "CAN";
|
||||
BA_DEF_DEF_ "Baudrate" 250000;
|
||||
BA_DEF_DEF_ "AMIPort" "CAN2";
|
||||
BA_DEF_DEF_ "GenMsgCycleTime" 0;
|
||||
BA_ "BusType" "CAN";
|
||||
BA_ "Baudrate" 250000;
|
||||
BA_ "AMIPort" "CAN2";
|
||||
BA_ "GenMsgCycleTime" BO_ 1696 100;
|
||||
BA_ "GenMsgCycleTime" BO_ 1697 500;
|
||||
BA_ "GenMsgCycleTime" BO_ 1698 20;
|
||||
@@ -2,17 +2,19 @@
|
||||
|
||||
YMR A11 仪表,使用淘晶驰 TJC4827X543_011 串口屏,分辨率 480 × 272。
|
||||
|
||||
当前 MCU CAN 输入为 **v2.0(SDC DBC / BMS 适配,2026-10-03)**,屏幕沿用 debug 数字状态接口;工程使用 USART HMI 1.68.1.3037 编辑、编译。
|
||||
当前 MCU CAN 输入为 **v2.1(CAN1 500 kbit/s、CAN2 250 kbit/s,2026-10-03)**,两路保留相同的 SDC / BMS 解码和任务收发功能;屏幕沿用 debug 数字状态接口。工程使用 USART HMI 1.68.1.3037 编辑、编译。
|
||||
|
||||
dash 顶部已加入低压电池电压 `lvbat`(两位小数),来源是 SDC `0x6A1` ADC mV。高压电压、电流来自 BMS `0x140` / 扩展 `0x186040F3`,现有控件显示整数单位;最高单体温度取 `0x156` 的有效实际温度最大值,或扩展 `0x186140F3`。旧 `0x180 / 0x181 / 0x280` 输入不再使用。
|
||||
|
||||
## 工程与交接资料
|
||||
|
||||
- [AMI.dbc](AMI.dbc):当前 AMI CAN 接口,10 条报文、33 个信号,含标准/扩展帧。
|
||||
- [CAN1 DBC](AMI.dbc):500 kbit/s,10 条报文、33 个信号,含标准/扩展帧。
|
||||
- [CAN2 DBC](AMI_CAN2_250k.dbc):250 kbit/s,报文布局与 CAN1 相同。
|
||||
- [DBC 对应说明](docs/AMI_CAN_DBC说明.md):信号布局、枚举、字节序、样例与复现检查。
|
||||
- [CAN 报文说明 PDF](output/pdf/AMI_CAN报文说明.pdf):当前 v2.0 协议的中文打印版,包含全部 10 条报文。
|
||||
- [CAN 报文说明 PDF](output/pdf/AMI_CAN报文说明.pdf):当前 v2.1 协议的中文打印版,包含两路速率和全部 10 条报文。
|
||||
- [联调报告](docs/SDC_BMS联调报告.md):真实 CAN1 / MCU / COM4 到 HMI 调试器的证据。
|
||||
- [已联调固件 BIN](output/firmware/AMI_Controller.bin):STM32G0B1CBT6,配套源码在 firmware。
|
||||
- [当前固件 BIN](output/firmware/AMI_Controller.bin):STM32G0B1CBT6,CAN1 500K / CAN2 250K,已编译、尚未烧录;配套源码在 firmware。
|
||||
- [此前已联调的 v2.0 BIN](output/firmware/AMI_Controller_v2.0_500k.bin):两路均为 500K,保留历史测试版本。
|
||||
- [AMI.HMI](AMI.HMI):最新版屏幕工程,打开后编译并下载到对应型号屏幕。
|
||||
- [通讯交接文档](docs/通讯交接文档.md):可编辑协议说明,包含全部状态编号、任务帧、主页面属性及联调步骤。
|
||||
- [历史屏幕接口 PDF](docs/AMI仪表通讯交接文档.pdf):保留的 v1.2 屏幕接口资料;当前 CAN 与有效性定义以 DBC 对应说明和 Markdown 交接文档为准。
|
||||
@@ -52,6 +54,8 @@ dash.lvbat.val=1260
|
||||
|
||||
2026-10-03 已验证 CAN 盒 → 实物 AMI CAN1 / MCU → USART2 / COM4 → 官方 HMI 调试器的数据更新、失效与恢复。固件编译及烧录校验通过;物理串口屏和 CAN2 尚未接线实测。旧 C 示例仍是屏幕 debug 接口示例。
|
||||
|
||||
上述实物证据对应 v2.0。v2.1 将 CAN2 改为 250 kbit/s,源码、CubeMX、两份 DBC 与位时序校验及 Release 编译已通过;新 BIN 尚未烧录,CAN2 250K 尚未实测。两路均不转发原始 CAN 帧,CAN 盒需分别设置正确速率。
|
||||
|
||||
灰色数值表示未知或失效。现有资料缺少电机/逆变器温度协议、Hz 到 km/h 标定参数、SDC PD0..PD14 到具名安全信号的映射,对应显示保持无效/未知。VCU 任务裁决、执行反馈和 EBS 安全输出仍需车辆控制协议,画面 EBS 文案不能作为安全状态证明。
|
||||
|
||||
许可证沿用仓库中的 [AGPL-3.0](LICENSE)。
|
||||
|
||||
+13
-4
@@ -1,10 +1,19 @@
|
||||
# AMI CAN DBC 说明
|
||||
|
||||
版本:`AMI-2.0-2026-10-03`。由 [AMI.dbc](../AMI.dbc) 自动生成,10 条报文、33 个信号。
|
||||
版本:`AMI-2.1-2026-10-03`。由 [AMI.dbc](../AMI.dbc) 自动生成,10 条报文、33 个信号。
|
||||
|
||||
## 使用范围
|
||||
|
||||
CAN1 / CAN2 功能相同,均为 500 kbit/s、Classic CAN、87.5% 采样点。节点 AMI 为仪表 MCU,VCU 为任务请求的逻辑接收者,SDC_ACQ_DAC 和 BMS 为数据源。
|
||||
CAN1 为 500 kbit/s,CAN2 为 250 kbit/s,均为 Classic CAN、87.5% 采样点。两路保留相同的接收 ID、解码与任务发送功能,MCU 不在两路之间转发原始报文。节点 AMI 为仪表 MCU,VCU 为任务请求的逻辑接收者,SDC_ACQ_DAC 和 BMS 为数据源。
|
||||
|
||||
| 端口 | 速率 | RX / TX 引脚 | DBC 文件 |
|
||||
| --- | --- | --- | --- |
|
||||
| CAN1 | 500 kbit/s | PA11 / PA12 | [AMI.dbc](../AMI.dbc) |
|
||||
| CAN2 | 250 kbit/s | PB0 / PB1 | [AMI_CAN2_250k.dbc](../AMI_CAN2_250k.dbc) |
|
||||
|
||||
DBC 的 `Baudrate` / `AMIPort` 分别标注所属总线。每份 DBC 均含 10 条报文、33 个信号;同一份报文表适用于两路。CAN 工具必须按接入端口设置速率,导入 DBC 不一定自动改硬件速率。例如 SDC 板保持 500 kbit/s 时接 CAN1;BMS 节点配置为 250 kbit/s 时接 CAN2。
|
||||
|
||||
FDCAN 时钟 64 MHz,时钟分频为 1;NominalPrescaler 为 CAN1=8、CAN2=16,两路均使用 Sync=1、TimeSeg1=13、TimeSeg2=2、SJW=1。速率 = 64 MHz / Prescaler / (1+13+2);采样点 = (1+13)/16 = 87.5%。
|
||||
|
||||
本 DBC 包含 AMI 唯一发送的 `0x300` 任务请求,以及 AMI 当前识别的 SDC / BMS 输入。SDC `0x6A3` DAC 控制、`0x6A5` ASSI 控制、BMS 其他电芯/故障字段不属于此接口子集。没有定义电机温度、逆变器温度、扭矩、标定后的车速、AMI 周期心跳或 VCU 执行反馈。旧 `0x180 / 0x181 / 0x280` 输入已停用。
|
||||
|
||||
@@ -184,6 +193,6 @@ python scripts/verify_dbc.py --sdc-dbc ../SDC_ACQ_DAC/SDC_ACQ_DAC.dbc
|
||||
|
||||
校验覆盖严格 DBC 解析(长度、信号越界与重叠)、10 个 ID 与固件宏对应、标准/扩展格式、33 个信号、发送/接收节点、SDC 周期、24 个已知报文解码、六个任务号与计数边界编码、大端偏置电流、无效温度枚举、全负温度和截短 DLC。已安装并验证 cantools 44.1.0,接口参考 [cantools 官方文档](https://cantools.readthedocs.io/en/latest/)。
|
||||
|
||||
上述是静态及软件编解码验证。之前 CAN 盒 -> 实物 AMI CAN1 / MCU -> USART2 -> COM4 -> 官方 HMI 调试器的实际更新和六个任务回传见 [联调报告](SDC_BMS联调报告.md)。物理串口屏、CAN2 接线、真实 SDC/BMS 节点和车辆执行动作尚未实测;文档生成和 DBC 解析不替代这些测试。
|
||||
上述是静态及软件编解码验证,另校验两份 DBC 的速率、相同信号布局及源码 / CubeMX 位时序一致。v2.1 的 CAN2 250 kbit/s 固件已编译,尚未烧录或实物验证。之前 v2.0 的 CAN 盒 -> 实物 AMI CAN1 / MCU -> USART2 -> COM4 -> 官方 HMI 调试器的实际更新和六个任务回传见 [联调报告](SDC_BMS联调报告.md)。物理串口屏、CAN2 接线、真实 SDC/BMS 节点和车辆执行动作尚未实测;文档生成和 DBC 解析不替代这些测试。
|
||||
|
||||
修改 AMI.dbc 后运行 `python scripts/export_dbc_docs.py` 更新本文;固件字节布局、DBC 与此文档需同时保持一致。
|
||||
修改 AMI.dbc 后运行 `python scripts/export_dbc_docs.py` 更新 CAN2 DBC 和本文;固件字节布局、DBC 与此文档需同时保持一致。
|
||||
|
||||
+3
-1
@@ -1,6 +1,8 @@
|
||||
# AMI 接入 SDC / BMS 协议
|
||||
|
||||
版本 2.0,2026-10-03。CAN1 / CAN2 配置相同:500 kbit/s、Classic CAN、87.5% 采样点。当前固件不再接收旧 `0x180 / 0x181 / 0x280` 数据接口。
|
||||
版本 2.1,2026-10-03。CAN1 为 500 kbit/s,CAN2 为 250 kbit/s;两路均为 Classic CAN、87.5% 采样点,接收 ID、解码和任务发送功能相同,不转发原始帧。CAN1 使用 [AMI.dbc](../AMI.dbc),CAN2 使用 [AMI_CAN2_250k.dbc](../AMI_CAN2_250k.dbc)。当前固件不再接收旧 `0x180 / 0x181 / 0x280` 数据接口。
|
||||
|
||||
v2.1 已通过源码 / CubeMX 位时序一致性检查及 Release 编译,尚未烧录或验证 CAN2 250K。本文后面的实物联调证据属于两路均为 500K 的 v2.0。
|
||||
|
||||
来源:`SDC_ACQ_DAC/SDC_ACQ_DAC.dbc` VERSION 1.1;[BmsMonitor-CANTest](https://git.acetaffy.ltd/acetaffy/BmsMonitor-CANTest) 的 `BmsMonitor.App/Protocol/BmsProtocolParser.cs`,核对提交 `e65c95203d1689df05343775982d7e85bd782646`,本机核对副本保存在 `tmp/BmsMonitor-CANTest`(不提交);远端来源使用上述仓库及提交号定位。
|
||||
|
||||
|
||||
+3
-1
@@ -2,6 +2,8 @@
|
||||
|
||||
2026-10-03,测试链路:PCAN-USB(500 kbit/s)→ 实物 AMI CAN1 → STM32G0B1 MCU → USART2 PA2/PA3 → CH340 COM4(9600 8N1)→ USART HMI 官方调试器。使用 CAN 盒模拟 SDC / BMS 报文,未接真实 SDC / BMS 节点或物理串口屏。
|
||||
|
||||
本文记录 v2.0 的实物测试。后续 v2.1 将 CAN2 改为 250K;新版本尚未烧录,本文不作为 CAN2 250K 验证依据。
|
||||
|
||||
## 实际发送与显示
|
||||
|
||||
| ID / 格式 / DLC | CAN 数据(十六进制) | 含义 | HMI 实测 |
|
||||
@@ -36,7 +38,7 @@
|
||||
|
||||
- [当前协议](SDC_BMS协议.md)
|
||||
- [HMI 工程](../AMI.HMI),SHA256 `8A37E4961F90671F04E55BA94C173AE8FBFC5E30C2A3E74A2C37148157C3D16D`
|
||||
- [固件 BIN](../output/firmware/AMI_Controller.bin),SHA256 `F0DA6EC9C5C8A4F803E4CDD28BB73C6458E010B15F32D3EAEF5C3A1B60D8827B`
|
||||
- [测试所用 v2.0 固件 BIN](../output/firmware/AMI_Controller_v2.0_500k.bin),SHA256 `F0DA6EC9C5C8A4F803E4CDD28BB73C6458E010B15F32D3EAEF5C3A1B60D8827B`
|
||||
- [全部 CAN 发送记录](evidence/2026-10-03/sdc-bms/sdc_bms_visual_results.json)
|
||||
- [MCU 快照自动核对](evidence/2026-10-03/sdc-bms/sdc_bms_verified.json)
|
||||
- [任务回归](evidence/2026-10-03/sdc-bms/sdc_bms_function_task_results.json)
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"result": "passed",
|
||||
"messages": 10,
|
||||
"signals": 33,
|
||||
"known_payload_checks": 24,
|
||||
"all_task_ids_and_counter_edges": true,
|
||||
"ports_bitrate": {
|
||||
"CAN1": 500000,
|
||||
"CAN2": 250000
|
||||
},
|
||||
"both_dbc_layouts_and_payloads_match": true,
|
||||
"firmware_and_ioc_bit_timing_match": true,
|
||||
"firmware_ids_match": true,
|
||||
"sdc_source_layout_match": true,
|
||||
"cantools_version": "44.1.0",
|
||||
"version": "AMI-2.1-2026-10-03",
|
||||
"release_build": {
|
||||
"result": "passed",
|
||||
"flash_bytes": 15612,
|
||||
"ram_bytes": 2632
|
||||
},
|
||||
"hardware_flash": "not performed for v2.1",
|
||||
"can2_250k_physical_test": "not performed",
|
||||
"pdf_visual_review": {
|
||||
"pages": 10,
|
||||
"result": "passed"
|
||||
},
|
||||
"sha256": {
|
||||
"AMI.dbc": "4f56ff454563826701a85749f981dc65d6cd74e17b49a62ea030a957a8cf64f5",
|
||||
"AMI_CAN2_250k.dbc": "fb9aa42f3cb2025e86b1b8227c1318c7dc3edc7a98ea525e57b41e53cce46273",
|
||||
"firmware/Core/Src/fdcan.c": "3640e809c169a1593249a38e009c0837070a73330cd7af1be236bb7a854e4fdb",
|
||||
"firmware/AMI_Controller.ioc": "b639e05cec85bed890c45a64bf624098e1b28458c780e7a94e8a42f84f1c7666",
|
||||
"output/firmware/AMI_Controller.bin": "143bb0cf190a17dd3f8a251bd49fef2af19699d873951c58cb790b35764e3212",
|
||||
"output/firmware/AMI_Controller_v2.0_500k.bin": "f0da6ec9c5c8a4f803e4cdd28bb73c6458e010b15f32d3eaef5c3a1b60d8827b",
|
||||
"output/pdf/AMI_CAN报文说明.pdf": "3ba73849d3375ab2248d59038c273c81129c007ab77281c4c80ec1d22eb6bf11"
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -1,7 +1,9 @@
|
||||
2026-10-03:屏幕数字接口1.2,MCU CAN输入2.0(SDC/BMS)。
|
||||
AMI.dbc包含10条Classic CAN报文和33个信号,CAN1/CAN2为500 kbit/s。
|
||||
2026-10-03:屏幕数字接口1.2,MCU CAN输入2.1(SDC/BMS)。
|
||||
CAN1为500 kbit/s,使用AMI.dbc;CAN2为250 kbit/s,使用AMI_CAN2_250k.dbc。每份包含10条Classic CAN报文和33个信号,报文布局相同。
|
||||
v2.1源码/CubeMX/DBC位时序一致性校验及Release编译通过;新BIN尚未烧录,CAN2 250K尚未实测。
|
||||
cantools 44.1.0严格解析、24个已知报文、六个任务号及计数边界、标准/扩展ID、偏置电流、无效温度和SDC布局一致性检查通过;具体复现命令见docs/AMI_CAN_DBC说明.md。
|
||||
HMI编译0错误0警告;固件Release编译、SWD烧录校验通过。
|
||||
下述历史实物证据对应v2.0,两路均为500K;原BIN保留在output/firmware/AMI_Controller_v2.0_500k.bin。
|
||||
HMI编译0错误0警告;v2.0固件Release编译、SWD烧录校验通过。
|
||||
已实测CAN盒->实物AMI CAN1/MCU->USART2->COM4->官方HMI调试器:低压电压、高压电压/电流、最高有效温度、无效数据、超时/恢复、跨页更新、HMI重连。
|
||||
六个任务确认均收到正确0x300请求,六个取消均未发送;该测试条件为CAN1持续有有效输入。
|
||||
证据在docs/evidence/2026-10-03/sdc-bms;联调报告见docs/SDC_BMS联调报告.md。
|
||||
|
||||
@@ -53,14 +53,14 @@ FDCAN1.NominalTimeSeg2=2
|
||||
FDCAN1.StdFiltersNbr=3
|
||||
FDCAN1.ExtFiltersNbr=1
|
||||
FDCAN2.AutoRetransmission=ENABLE
|
||||
FDCAN2.CalculateBaudRateNominal=500000
|
||||
FDCAN2.CalculateTimeBitNominal=2000
|
||||
FDCAN2.CalculateTimeQuantumNominal=125.0
|
||||
FDCAN2.DataPrescaler=8
|
||||
FDCAN2.CalculateBaudRateNominal=250000
|
||||
FDCAN2.CalculateTimeBitNominal=4000
|
||||
FDCAN2.CalculateTimeQuantumNominal=250.0
|
||||
FDCAN2.DataPrescaler=16
|
||||
FDCAN2.DataTimeSeg1=13
|
||||
FDCAN2.DataTimeSeg2=2
|
||||
FDCAN2.IPParameters=AutoRetransmission,CalculateTimeQuantumNominal,CalculateTimeBitNominal,CalculateBaudRateNominal,DataPrescaler,DataTimeSeg1,DataTimeSeg2,StdFiltersNbr,NominalPrescaler,NominalTimeSeg1,NominalTimeSeg2,ExtFiltersNbr
|
||||
FDCAN2.NominalPrescaler=8
|
||||
FDCAN2.NominalPrescaler=16
|
||||
FDCAN2.NominalTimeSeg1=13
|
||||
FDCAN2.NominalTimeSeg2=2
|
||||
FDCAN2.StdFiltersNbr=3
|
||||
|
||||
@@ -83,11 +83,11 @@ void MX_FDCAN2_Init(void)
|
||||
hfdcan2.Init.AutoRetransmission = ENABLE;
|
||||
hfdcan2.Init.TransmitPause = DISABLE;
|
||||
hfdcan2.Init.ProtocolException = DISABLE;
|
||||
hfdcan2.Init.NominalPrescaler = 8;
|
||||
hfdcan2.Init.NominalPrescaler = 16;
|
||||
hfdcan2.Init.NominalSyncJumpWidth = 1;
|
||||
hfdcan2.Init.NominalTimeSeg1 = 13;
|
||||
hfdcan2.Init.NominalTimeSeg2 = 2;
|
||||
hfdcan2.Init.DataPrescaler = 8;
|
||||
hfdcan2.Init.DataPrescaler = 16;
|
||||
hfdcan2.Init.DataSyncJumpWidth = 1;
|
||||
hfdcan2.Init.DataTimeSeg1 = 13;
|
||||
hfdcan2.Init.DataTimeSeg2 = 2;
|
||||
|
||||
+7
-3
@@ -10,13 +10,15 @@
|
||||
| 12 | PA1 | STATUS_LED2,仪表/SDC 状态活动超时提示;两路择有效输入 |
|
||||
| 13 | PA2 | USART2_TX → 屏幕 RX,9600 8N1 |
|
||||
| 14 | PA3 | USART2_RX ← 屏幕 TX,9600 8N1 |
|
||||
| 19 | PB0 | FDCAN2_RX,500 kbit/s,与 CAN1 功能相同 |
|
||||
| 20 | PB1 | FDCAN2_TX,500 kbit/s,与 CAN1 功能相同 |
|
||||
| 19 | PB0 | FDCAN2_RX,250 kbit/s,与 CAN1 解码功能相同 |
|
||||
| 20 | PB1 | FDCAN2_TX,250 kbit/s,与 CAN1 任务发送功能相同 |
|
||||
| 33 | PA11 | FDCAN1_RX,默认 500 kbit/s |
|
||||
| 34 | PA12 | FDCAN1_TX,默认 500 kbit/s |
|
||||
|
||||
LED 默认按高电平点亮。如果硬件是低电平点亮,将 `Core/Inc/ami_app.h` 中 `AMI_LED_ACTIVE_LEVEL` 改为 `GPIO_PIN_RESET`。
|
||||
|
||||
CAN1 为 500 kbit/s、CAN2 为 250 kbit/s。FDCAN 时钟为 64 MHz,两路 ClockDivider=1,NominalPrescaler 分别为 8 / 16;TimeSeg1=13、TimeSeg2=2、SJW=1,采样点均为 87.5%。CAN1 使用根目录 `AMI.dbc`,CAN2 使用 `AMI_CAN2_250k.dbc`。MCU 不在两路之间转发原始 CAN 报文。
|
||||
|
||||
## 数据路径
|
||||
|
||||
- FDCAN1、FDCAN2 使用相同的三条标准过滤器和一条扩展过滤器,接收 SDC 0x6A0..0x6A6 与 BMS 0x140 / 0x156 / 0x186040F3 / 0x186140F3。
|
||||
@@ -50,7 +52,9 @@ CubeMX 配置源为 `AMI_Controller.ioc`。重新生成时保留 USER CODE 区
|
||||
## 实物联调前确认
|
||||
|
||||
1. 核对芯片完整丝印,确认是 CB/CC/CE 中的哪一个。
|
||||
2. 确认 CAN1/CAN2 收发器、终端电阻及 500 kbit/s 总线速率。
|
||||
2. 确认 CAN1/CAN2 收发器、终端电阻;CAN1 总线 500 kbit/s、CAN2 总线 250 kbit/s。
|
||||
3. 确认屏幕是 TTL 电平并与主控共地,主控 TX 接屏 RX、主控 RX 接屏 TX。
|
||||
4. 下载 `AMI.HMI` 后逐条验证仪表数值、16 路 debug 状态及 6 个任务按钮。
|
||||
5. 2026-10-03 已完成 CAN1 / MCU / USART2 到 COM4 官方 HMI 调试器联调;物理屏幕、CAN2 和 LED 极性尚未实测。证据位于 [发布的 CAN 记录](../docs/evidence/2026-10-03/sdc-bms/sdc_bms_visual_results.json)。
|
||||
|
||||
此前实物证据对应两路均为 500K 的 v2.0。当前 v2.1 的 CAN2 250K BIN 已编译,尚未烧录或实物测试。
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -28,7 +28,7 @@ def inline(text):
|
||||
def link(match):
|
||||
label, target = match.groups()
|
||||
if not target.startswith(('http://', 'https://')):
|
||||
target = REMOTE + ('AMI.dbc' if target == '../AMI.dbc' else 'docs/' + target)
|
||||
target = REMOTE + (target[3:] if target.startswith('../') else 'docs/' + target)
|
||||
return f'<link href="{target}" color="#155E75">{label}</link>'
|
||||
|
||||
return re.sub(r'\[([^\]]+)\]\(([^)]+)\)', link, text)
|
||||
@@ -78,6 +78,7 @@ def export(font_path):
|
||||
proportions = {
|
||||
2: [0.15, 0.85],
|
||||
3: [0.17, 0.40, 0.43],
|
||||
4: [0.12, 0.15, 0.20, 0.53],
|
||||
6: [0.11, 0.055, 0.04, 0.28, 0.365, 0.15],
|
||||
8: [0.32, 0.055, 0.055, 0.10, 0.09, 0.08, 0.06, 0.24],
|
||||
}[count]
|
||||
@@ -126,7 +127,7 @@ def export(font_path):
|
||||
canvas.line(40, 31, page_width-40, 31)
|
||||
canvas.setFont('AMIChinese', 8)
|
||||
canvas.setFillColor(colors.HexColor('#506775'))
|
||||
canvas.drawString(40, 19, 'AMI-2.0 | 2026-10-03 | CAN 接口说明')
|
||||
canvas.drawString(40, 19, 'AMI-2.1 | 2026-10-03 | CAN1 500K / CAN2 250K')
|
||||
canvas.drawRightString(page_width-40, 19, f'{doc.page}')
|
||||
canvas.restoreState()
|
||||
|
||||
@@ -135,7 +136,7 @@ def export(font_path):
|
||||
leftMargin=40, rightMargin=40,
|
||||
topMargin=36, bottomMargin=44,
|
||||
title='AMI CAN 报文说明', author='AMI / YMR',
|
||||
subject='AMI CAN DBC v2.0: SDC, BMS and task requests')
|
||||
subject='AMI CAN DBC v2.1: CAN1 500K / CAN2 250K')
|
||||
document.build(story, onFirstPage=footer, onLaterPages=footer)
|
||||
print(OUTPUT)
|
||||
|
||||
|
||||
@@ -6,6 +6,21 @@ import cantools
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
OUTPUT = ROOT / 'docs/AMI_CAN_DBC说明.md'
|
||||
CAN2_OUTPUT = ROOT / 'AMI_CAN2_250k.dbc'
|
||||
|
||||
|
||||
def can2_dbc_text():
|
||||
text = (ROOT / 'AMI.dbc').read_text(encoding='ascii')
|
||||
for old, new in [
|
||||
('BA_DEF_DEF_ "Baudrate" 500000;', 'BA_DEF_DEF_ "Baudrate" 250000;'),
|
||||
('BA_ "Baudrate" 500000;', 'BA_ "Baudrate" 250000;'),
|
||||
('"AMIPort" "CAN1";', '"AMIPort" "CAN2";'),
|
||||
('This file is CAN1; use AMI_CAN2_250k.dbc for CAN2.',
|
||||
'This file is CAN2; use AMI.dbc for CAN1.'),
|
||||
]:
|
||||
assert old in text, old
|
||||
text = text.replace(old, new)
|
||||
return text
|
||||
|
||||
PURPOSE = {
|
||||
0x300: 'AMI -> VCU:用户确认后的任务选择请求',
|
||||
@@ -27,8 +42,19 @@ def render():
|
||||
'# AMI CAN DBC 说明', '',
|
||||
f'版本:`{db.version}`。由 [AMI.dbc](../AMI.dbc) 自动生成,10 条报文、33 个信号。', '',
|
||||
'## 使用范围', '',
|
||||
'CAN1 / CAN2 功能相同,均为 500 kbit/s、Classic CAN、87.5% 采样点。'
|
||||
'CAN1 为 500 kbit/s,CAN2 为 250 kbit/s,均为 Classic CAN、87.5% 采样点。'
|
||||
'两路保留相同的接收 ID、解码与任务发送功能,MCU 不在两路之间转发原始报文。'
|
||||
'节点 AMI 为仪表 MCU,VCU 为任务请求的逻辑接收者,SDC_ACQ_DAC 和 BMS 为数据源。', '',
|
||||
'| 端口 | 速率 | RX / TX 引脚 | DBC 文件 |',
|
||||
'| --- | --- | --- | --- |',
|
||||
'| CAN1 | 500 kbit/s | PA11 / PA12 | [AMI.dbc](../AMI.dbc) |',
|
||||
'| CAN2 | 250 kbit/s | PB0 / PB1 | [AMI_CAN2_250k.dbc](../AMI_CAN2_250k.dbc) |', '',
|
||||
'DBC 的 `Baudrate` / `AMIPort` 分别标注所属总线。每份 DBC 均含 10 条报文、33 个信号;'
|
||||
'同一份报文表适用于两路。CAN 工具必须按接入端口设置速率,导入 DBC 不一定自动改硬件速率。'
|
||||
'例如 SDC 板保持 500 kbit/s 时接 CAN1;BMS 节点配置为 250 kbit/s 时接 CAN2。', '',
|
||||
'FDCAN 时钟 64 MHz,时钟分频为 1;NominalPrescaler 为 CAN1=8、CAN2=16,'
|
||||
'两路均使用 Sync=1、TimeSeg1=13、TimeSeg2=2、SJW=1。'
|
||||
'速率 = 64 MHz / Prescaler / (1+13+2);采样点 = (1+13)/16 = 87.5%。', '',
|
||||
'本 DBC 包含 AMI 唯一发送的 `0x300` 任务请求,以及 AMI 当前识别的 SDC / BMS 输入。'
|
||||
'SDC `0x6A3` DAC 控制、`0x6A5` ASSI 控制、BMS 其他电芯/故障字段不属于此接口子集。'
|
||||
'没有定义电机温度、逆变器温度、扭矩、标定后的车速、AMI 周期心跳或 VCU 执行反馈。'
|
||||
@@ -123,11 +149,13 @@ def render():
|
||||
'标准/扩展格式、33 个信号、发送/接收节点、SDC 周期、24 个已知报文解码、'
|
||||
'六个任务号与计数边界编码、大端偏置电流、无效温度枚举、全负温度和截短 DLC。'
|
||||
'已安装并验证 cantools 44.1.0,接口参考 [cantools 官方文档](https://cantools.readthedocs.io/en/latest/)。', '',
|
||||
'上述是静态及软件编解码验证。之前 CAN 盒 -> 实物 AMI CAN1 / MCU -> USART2 -> COM4 '
|
||||
'上述是静态及软件编解码验证,另校验两份 DBC 的速率、相同信号布局及源码 / CubeMX 位时序一致。'
|
||||
'v2.1 的 CAN2 250 kbit/s 固件已编译,尚未烧录或实物验证。'
|
||||
'之前 v2.0 的 CAN 盒 -> 实物 AMI CAN1 / MCU -> USART2 -> COM4 '
|
||||
'-> 官方 HMI 调试器的实际更新和六个任务回传见 [联调报告](SDC_BMS联调报告.md)。'
|
||||
'物理串口屏、CAN2 接线、真实 SDC/BMS 节点和车辆执行动作尚未实测;'
|
||||
'文档生成和 DBC 解析不替代这些测试。', '',
|
||||
'修改 AMI.dbc 后运行 `python scripts/export_dbc_docs.py` 更新本文;'
|
||||
'修改 AMI.dbc 后运行 `python scripts/export_dbc_docs.py` 更新 CAN2 DBC 和本文;'
|
||||
'固件字节布局、DBC 与此文档需同时保持一致。', '',
|
||||
]
|
||||
return '\n'.join(lines)
|
||||
@@ -140,10 +168,12 @@ def main():
|
||||
text = render()
|
||||
if args.check:
|
||||
assert OUTPUT.read_text(encoding='utf-8') == text, 'DBC document is stale; run export_dbc_docs.py'
|
||||
print('DBC documentation matches AMI.dbc')
|
||||
assert CAN2_OUTPUT.read_text(encoding='ascii') == can2_dbc_text(), 'CAN2 DBC is stale'
|
||||
print('DBC documentation and CAN2 DBC match AMI.dbc')
|
||||
else:
|
||||
CAN2_OUTPUT.write_text(can2_dbc_text(), encoding='ascii', newline='\n')
|
||||
OUTPUT.write_text(text, encoding='utf-8', newline='\n')
|
||||
print('Generated docs/AMI_CAN_DBC说明.md')
|
||||
print('Generated CAN2 DBC and docs/AMI_CAN_DBC说明.md')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
@@ -10,11 +10,48 @@ from pathlib import Path
|
||||
import re
|
||||
|
||||
import cantools
|
||||
from export_dbc_docs import can2_dbc_text
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
|
||||
|
||||
def verify_bit_timing():
|
||||
ioc = dict(line.split('=', 1) for line in
|
||||
(ROOT / 'firmware/AMI_Controller.ioc').read_text().splitlines() if '=' in line)
|
||||
source = (ROOT / 'firmware/Core/Src/fdcan.c').read_text()
|
||||
clock_source = (ROOT / 'firmware/Core/Src/main.c').read_text()
|
||||
for setting in ('RCC_HSI_DIV1', 'RCC_PLLM_DIV1', 'RCC_PLLR_DIV4', 'RCC_HCLK_DIV1'):
|
||||
assert setting in clock_source
|
||||
assert re.search(r'PLL\.PLLN\s*=\s*16;', clock_source)
|
||||
assert 'RCC_FDCANCLKSOURCE_PCLK1' in source
|
||||
clock = int(ioc['RCC.FDCANFreq_Value'])
|
||||
assert clock == 16000000 * 16 // 4 == int(ioc['RCC.APBFreq_Value'])
|
||||
result = {}
|
||||
for port, expected_rate, expected_prescaler in ((1, 500000, 8), (2, 250000, 16)):
|
||||
def value(field):
|
||||
found = re.search(rf'hfdcan{port}\.Init\.{field}\s*=\s*(\w+);', source)
|
||||
assert found, field
|
||||
return found.group(1)
|
||||
|
||||
assert value('ClockDivider') == 'FDCAN_CLOCK_DIV1'
|
||||
assert value('FrameFormat') == 'FDCAN_FRAME_CLASSIC'
|
||||
prescaler, seg1, seg2, sjw = (int(value(field)) for field in
|
||||
('NominalPrescaler', 'NominalTimeSeg1',
|
||||
'NominalTimeSeg2', 'NominalSyncJumpWidth'))
|
||||
assert (prescaler, seg1, seg2, sjw) == (expected_prescaler, 13, 2, 1)
|
||||
rate = clock // prescaler // (1 + seg1 + seg2)
|
||||
near((1 + seg1) / (1 + seg1 + seg2), 0.875)
|
||||
assert rate == expected_rate == int(ioc[f'FDCAN{port}.CalculateBaudRateNominal'])
|
||||
for field in ('NominalPrescaler', 'NominalTimeSeg1', 'NominalTimeSeg2',
|
||||
'DataPrescaler', 'DataTimeSeg1', 'DataTimeSeg2'):
|
||||
assert int(value(field)) == int(ioc[f'FDCAN{port}.{field}'])
|
||||
near(float(ioc[f'FDCAN{port}.CalculateTimeBitNominal']), 1e9 / rate)
|
||||
near(float(ioc[f'FDCAN{port}.CalculateTimeQuantumNominal']), 1e9 * prescaler / clock)
|
||||
result[f'CAN{port}'] = rate
|
||||
return result
|
||||
|
||||
|
||||
def near(actual, expected):
|
||||
assert math.isclose(actual, expected, rel_tol=0, abs_tol=1e-8), (actual, expected)
|
||||
|
||||
@@ -24,6 +61,12 @@ def main():
|
||||
parser.add_argument('--sdc-dbc', type=Path)
|
||||
args = parser.parse_args()
|
||||
db = cantools.database.load_file(ROOT / 'AMI.dbc', strict=True)
|
||||
db2 = cantools.database.load_file(ROOT / 'AMI_CAN2_250k.dbc', strict=True)
|
||||
assert (ROOT / 'AMI_CAN2_250k.dbc').read_text(encoding='ascii') == can2_dbc_text()
|
||||
assert db2.dbc.attributes['Baudrate'].value == 250000
|
||||
assert db.dbc.attributes['AMIPort'].value == 'CAN1'
|
||||
assert db2.dbc.attributes['AMIPort'].value == 'CAN2'
|
||||
bitrates = verify_bit_timing()
|
||||
header = (ROOT / 'firmware/Core/Inc/ami_protocol.h').read_text(encoding='utf-8')
|
||||
identifiers = {int(value, 16) for value in re.findall(
|
||||
r'^#define\s+AMI_CAN_ID_\w+\s+(0x[\dA-Fa-f]+)', header, re.MULTILINE)}
|
||||
@@ -58,6 +101,7 @@ def main():
|
||||
assert task == {'Protocol_Version':1,'Task_ID':2,'Request_Sequence':0,
|
||||
'Request_Source':1,'MCU_Uptime':1000}
|
||||
request = db.get_message_by_frame_id(0x300)
|
||||
request2 = db2.get_message_by_frame_id(0x300)
|
||||
assert request.encode(task) == bytes.fromhex('01 02 00 01 E8 03 00 00')
|
||||
for task_id in range(1,7):
|
||||
for seq in (0,255):
|
||||
@@ -65,6 +109,8 @@ def main():
|
||||
payload=request.encode(data)
|
||||
assert payload == bytes([1,task_id,seq,1,255,255,255,255])
|
||||
assert request.decode(payload,decode_choices=False) == data
|
||||
assert request2.encode(data) == payload
|
||||
assert request2.decode(payload,decode_choices=False) == data
|
||||
assert set(request.get_signal_by_name('Task_ID').choices) == set(range(1,7))
|
||||
|
||||
for raw, volts in [('08 20',8.2),('0C 30',12.3),('88 31',12.68),('A4 38',14.5),('FF FF',65.535)]:
|
||||
@@ -137,8 +183,16 @@ def main():
|
||||
assert all(getattr(a,key)==getattr(b,key) for key in fields),(ident,a,b)
|
||||
source_check=True
|
||||
|
||||
for check in checks:
|
||||
ident = int(check['id'], 16)
|
||||
payload = bytes.fromhex(check['data'])
|
||||
for decode_choices in (False, True):
|
||||
assert db.decode_message(ident, payload, decode_choices=decode_choices) == \
|
||||
db2.decode_message(ident, payload, decode_choices=decode_choices)
|
||||
print(json.dumps({'result':'passed','messages':len(db.messages),'signals':33,
|
||||
'known_payload_checks':len(checks),'all_task_ids_and_counter_edges':True,
|
||||
'ports_bitrate':bitrates,'both_dbc_layouts_and_payloads_match':True,
|
||||
'firmware_and_ioc_bit_timing_match':True,
|
||||
'firmware_ids_match':True,'sdc_source_layout_match':source_check,
|
||||
'cantools_version':cantools.__version__},indent=2))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user