Add CAN inputs for drivetrain display values with DBC and bench evidence

This commit is contained in:
shenlefengnai-rgb
2026-10-03 18:53:17 +08:00
parent ceb88a90a5
commit dade0e5d3a
51 changed files with 7084 additions and 51 deletions
+3 -1
View File
@@ -1,7 +1,8 @@
#ifndef AMI_PROTOCOL_H
#define AMI_PROTOCOL_H
/* Both CAN ports use the same 500 kbit/s protocol and the same IDs. */
/* CAN1 is 500 kbit/s; CAN2 is 250 kbit/s. Both share IDs and parsing. */
#define AMI_CAN_ID_DRIVETRAIN_DISPLAY 0x182U
#define AMI_CAN_ID_SDC_HEARTBEAT 0x6A0U
#define AMI_CAN_ID_SDC_ADC 0x6A1U
#define AMI_CAN_ID_SDC_FREQUENCY 0x6A2U
@@ -17,6 +18,7 @@
#define AMI_CAN_DATA_TIMEOUT_MS 500U
#define AMI_ADC_TIMEOUT_MS 1500U
#define AMI_BMS_TIMEOUT_MS 2000U
#define AMI_DRIVETRAIN_TIMEOUT_MS 2000U
#define AMI_SCREEN_BOOT_DELAY_MS 800U
#define AMI_SCREEN_RESYNC_MS 5000U
+39
View File
@@ -41,6 +41,7 @@ static volatile uint32_t debug_last_rx_ms;
static volatile uint32_t adc_last_rx_ms;
static volatile uint32_t bms_status_last_rx_ms;
static volatile uint32_t bms_temperature_last_rx_ms;
static volatile uint32_t drivetrain_last_rx_ms;
/* Preserve the exact source units even where the HMI has integer controls. */
static volatile uint16_t sdc_adc_mv;
static volatile uint16_t sdc_frequency_hz[4];
@@ -88,6 +89,12 @@ static int32_t RoundTenths(int32_t value)
return (value >= 0) ? ((value + 5) / 10) : ((value - 5) / 10);
}
static int32_t ReadLeS16(const uint8_t *data)
{
uint32_t raw = ReadLeU16(data);
return (raw & 0x8000U) ? ((int32_t)raw - 65536) : (int32_t)raw;
}
static size_t AppendUnsigned(char *dst, uint32_t value)
{
char reversed[10];
@@ -245,6 +252,27 @@ static bool DecodeCan(uint32_t identifier, uint32_t id_type,
uint32_t now = HAL_GetTick();
if (id_type == FDCAN_STANDARD_ID)
{
if (identifier == AMI_CAN_ID_DRIVETRAIN_DISPLAY)
{
/* Version 1 display input only; no motor actuation is performed. */
if ((length != 8U) || (data[7] != 1U) || ((data[6] & 0xF8U) != 0U))
{
return false;
}
int32_t torque = ReadLeS16(data);
if ((data[6] & 1U) && (torque >= -1000) && (torque <= 1000))
{
SetDashValue(2U, torque);
}
else { SetDashValid(2U, false); }
if (data[6] & 2U) { SetDashValue(4U, RoundTenths(ReadLeS16(&data[2]))); }
else { SetDashValid(4U, false); }
if (data[6] & 4U) { SetDashValue(5U, RoundTenths(ReadLeS16(&data[4]))); }
else { SetDashValid(5U, false); }
drivetrain_last_rx_ms = now;
dash_last_rx_ms = now;
return true;
}
if ((identifier == AMI_CAN_ID_SDC_ADC) && (length == 2U))
{
sdc_adc_mv = (uint16_t)ReadLeU16(data);
@@ -350,6 +378,10 @@ static void ConfigureCanPort(FDCAN_HandleTypeDef *hfdcan)
filter.FilterID1 = AMI_CAN_ID_BMS_TEMPERATURE;
if (HAL_FDCAN_ConfigFilter(hfdcan, &filter) != HAL_OK) { Error_Handler(); }
filter.FilterIndex = 3U;
filter.FilterID1 = AMI_CAN_ID_DRIVETRAIN_DISPLAY;
if (HAL_FDCAN_ConfigFilter(hfdcan, &filter) != HAL_OK) { Error_Handler(); }
filter.IdType = FDCAN_EXTENDED_ID;
filter.FilterIndex = 0U;
filter.FilterType = FDCAN_FILTER_DUAL;
@@ -489,6 +521,13 @@ static void UpdateTimeoutsAndLeds(void)
{
SetDashValid(6U, false);
}
if ((drivetrain_last_rx_ms == 0U) ||
((now - drivetrain_last_rx_ms) > AMI_DRIVETRAIN_TIMEOUT_MS))
{
SetDashValid(2U, false);
SetDashValid(4U, false);
SetDashValid(5U, false);
}
__enable_irq();
if (debug_timeout && !debug_timeout_applied)
+2 -2
View File
@@ -53,7 +53,7 @@ void MX_FDCAN1_Init(void)
hfdcan1.Init.DataSyncJumpWidth = 1;
hfdcan1.Init.DataTimeSeg1 = 13;
hfdcan1.Init.DataTimeSeg2 = 2;
hfdcan1.Init.StdFiltersNbr = 3;
hfdcan1.Init.StdFiltersNbr = 4;
hfdcan1.Init.ExtFiltersNbr = 1;
hfdcan1.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan1) != HAL_OK)
@@ -91,7 +91,7 @@ void MX_FDCAN2_Init(void)
hfdcan2.Init.DataSyncJumpWidth = 1;
hfdcan2.Init.DataTimeSeg1 = 13;
hfdcan2.Init.DataTimeSeg2 = 2;
hfdcan2.Init.StdFiltersNbr = 3;
hfdcan2.Init.StdFiltersNbr = 4;
hfdcan2.Init.ExtFiltersNbr = 1;
hfdcan2.Init.TxFifoQueueMode = FDCAN_TX_FIFO_OPERATION;
if (HAL_FDCAN_Init(&hfdcan2) != HAL_OK)