165 lines
5.3 KiB
C
165 lines
5.3 KiB
C
/**
|
|
* @brief CAN调试工具 - 用于诊断CAN发送问题
|
|
* 使用示例:
|
|
*
|
|
* BSP_CAN_StateInfo_t state;
|
|
* if (BSP_CAN_GetStateInfo(BSP_CAN_1, &state) == BSP_OK) {
|
|
* // 打印状态信息
|
|
* printf("CAN State: %d\n", state.can_state);
|
|
* printf("Error Code: 0x%08X\n", state.error_code);
|
|
* printf("Free Mailboxes: %d\n", state.free_mailboxes);
|
|
* printf("MSR: 0x%08X\n", state.can_msr);
|
|
* printf("ESR: 0x%08X\n", state.can_esr);
|
|
* }
|
|
*/
|
|
|
|
#include "bsp/can.h"
|
|
#include <stdio.h>
|
|
|
|
void BSP_CAN_Debug_PrintState(BSP_CAN_t can) {
|
|
BSP_CAN_StateInfo_t state;
|
|
if (BSP_CAN_GetStateInfo(can, &state) != BSP_OK) {
|
|
printf("Failed to get CAN%d state\n", can + 1);
|
|
return;
|
|
}
|
|
|
|
printf("=== CAN%d State Info ===\n", can + 1);
|
|
|
|
// CAN状态
|
|
switch (state.can_state) {
|
|
case HAL_CAN_STATE_RESET:
|
|
printf("State: RESET\n");
|
|
break;
|
|
case HAL_CAN_STATE_READY:
|
|
printf("State: READY\n");
|
|
break;
|
|
case HAL_CAN_STATE_LISTENING:
|
|
printf("State: LISTENING\n");
|
|
break;
|
|
case HAL_CAN_STATE_SLEEP_PENDING:
|
|
printf("State: SLEEP_PENDING\n");
|
|
break;
|
|
case HAL_CAN_STATE_SLEEP_ACTIVE:
|
|
printf("State: SLEEP_ACTIVE\n");
|
|
break;
|
|
case HAL_CAN_STATE_ERROR:
|
|
printf("State: ERROR\n");
|
|
break;
|
|
default:
|
|
printf("State: UNKNOWN(%d)\n", state.can_state);
|
|
break;
|
|
}
|
|
|
|
// 错误状态
|
|
printf("Error Code: 0x%08X", state.error_code);
|
|
if (state.error_code != HAL_CAN_ERROR_NONE) {
|
|
printf(" (");
|
|
if (state.error_code & HAL_CAN_ERROR_EWG) printf("EWG ");
|
|
if (state.error_code & HAL_CAN_ERROR_EPV) printf("EPV ");
|
|
if (state.error_code & HAL_CAN_ERROR_BOF) printf("BOF ");
|
|
if (state.error_code & HAL_CAN_ERROR_STF) printf("STF ");
|
|
if (state.error_code & HAL_CAN_ERROR_FOR) printf("FOR ");
|
|
if (state.error_code & HAL_CAN_ERROR_ACK) printf("ACK ");
|
|
if (state.error_code & HAL_CAN_ERROR_BR) printf("BR ");
|
|
if (state.error_code & HAL_CAN_ERROR_BD) printf("BD ");
|
|
if (state.error_code & HAL_CAN_ERROR_CRC) printf("CRC ");
|
|
printf(")");
|
|
}
|
|
printf("\n");
|
|
|
|
// 邮箱和FIFO状态
|
|
printf("Free Mailboxes: %d/3\n", state.free_mailboxes);
|
|
printf("RX FIFO0 Level: %d\n", state.rx_fifo0_level);
|
|
printf("RX FIFO1 Level: %d\n", state.rx_fifo1_level);
|
|
|
|
// 寄存器状态
|
|
printf("MSR: 0x%08X\n", state.can_msr);
|
|
printf("ESR: 0x%08X", state.can_esr);
|
|
|
|
// 解析ESR寄存器
|
|
uint8_t lec = (state.can_esr >> 4) & 0x07;
|
|
uint8_t tec = (state.can_esr >> 16) & 0xFF;
|
|
uint8_t rec = (state.can_esr >> 24) & 0xFF;
|
|
|
|
printf(" (LEC:%d TEC:%d REC:%d)\n", lec, tec, rec);
|
|
|
|
// 错误计数器分析
|
|
if (tec > 96 || rec > 96) {
|
|
printf("WARNING: High error count detected!\n");
|
|
}
|
|
if (state.can_esr & (1 << 2)) { // BOFF bit
|
|
printf("WARNING: CAN is in Bus-Off state!\n");
|
|
}
|
|
if (state.can_esr & (1 << 1)) { // EPVF bit
|
|
printf("WARNING: Error Passive Flag set!\n");
|
|
}
|
|
if (state.can_esr & (1 << 0)) { // EWGF bit
|
|
printf("WARNING: Error Warning Flag set!\n");
|
|
}
|
|
|
|
printf("========================\n");
|
|
}
|
|
|
|
// 诊断发送失败的可能原因
|
|
void BSP_CAN_Debug_DiagnoseTxFailure(BSP_CAN_t can) {
|
|
BSP_CAN_StateInfo_t state;
|
|
if (BSP_CAN_GetStateInfo(can, &state) != BSP_OK) {
|
|
printf("Failed to get CAN%d state for diagnosis\n", can + 1);
|
|
return;
|
|
}
|
|
|
|
printf("=== CAN%d TX Failure Diagnosis ===\n", can + 1);
|
|
|
|
// 检查各种可能的问题
|
|
bool found_issue = false;
|
|
|
|
if (state.can_state != HAL_CAN_STATE_LISTENING && state.can_state != HAL_CAN_STATE_READY) {
|
|
printf("ISSUE: CAN not in operational state (current: %d)\n", state.can_state);
|
|
found_issue = true;
|
|
}
|
|
|
|
if (state.free_mailboxes == 0) {
|
|
printf("ISSUE: No free TX mailboxes available\n");
|
|
found_issue = true;
|
|
}
|
|
|
|
if (state.error_code != HAL_CAN_ERROR_NONE) {
|
|
printf("ISSUE: CAN has error flags (0x%08X)\n", state.error_code);
|
|
found_issue = true;
|
|
}
|
|
|
|
if (state.can_esr & (1 << 2)) { // BOFF bit
|
|
printf("ISSUE: CAN is in Bus-Off state - need restart\n");
|
|
found_issue = true;
|
|
}
|
|
|
|
uint8_t tec = (state.can_esr >> 16) & 0xFF;
|
|
uint8_t rec = (state.can_esr >> 24) & 0xFF;
|
|
|
|
if (tec > 127) {
|
|
printf("ISSUE: TX Error Counter too high (%d) - bus issues?\n", tec);
|
|
found_issue = true;
|
|
}
|
|
|
|
if (rec > 127) {
|
|
printf("ISSUE: RX Error Counter too high (%d) - bus issues?\n", rec);
|
|
found_issue = true;
|
|
}
|
|
|
|
// 检查MSR寄存器
|
|
if (!(state.can_msr & (1 << 1))) { // INAK bit - should be 0 in normal mode
|
|
printf("ISSUE: CAN may not be properly initialized\n");
|
|
found_issue = true;
|
|
}
|
|
|
|
if (!found_issue) {
|
|
printf("No obvious hardware issues found.\n");
|
|
printf("Possible causes:\n");
|
|
printf("- CAN bus not connected or terminated properly\n");
|
|
printf("- Wrong bit rate configuration\n");
|
|
printf("- Other node not acknowledging\n");
|
|
printf("- Message ID conflicts or filtering issues\n");
|
|
}
|
|
|
|
printf("===================================\n");
|
|
} |