feat: add AS status feedback for both HMI sizes with verified v2.7 release
This commit is contained in:
+41
-22
@@ -38,18 +38,22 @@ static volatile AmiDisplayState display_state;
|
||||
static volatile uint32_t display_dirty;
|
||||
static volatile uint32_t dash_last_rx_ms;
|
||||
static volatile uint32_t debug_last_rx_ms;
|
||||
static volatile uint32_t wheel_speed_last_rx_ms;
|
||||
static volatile bool wheel_speed_received;
|
||||
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;
|
||||
static volatile uint32_t vcu_status_last_rx_ms;
|
||||
/* Task 7 = unknown; lock/EBS 0 = unknown, 1 = green, 2 = red. */
|
||||
static volatile uint8_t vcu_display_state[3] = {7U, 0U, 0U};
|
||||
/* AS 0..5 = OFF/Ready/Driving/Finished/Emergency/Manual; 6 = unknown. */
|
||||
static volatile uint8_t vcu_display_state[4] = {7U, 0U, 0U, 6U};
|
||||
static volatile uint8_t vcu_display_dirty;
|
||||
static volatile bool vcu_status_received;
|
||||
/* 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];
|
||||
/* SDC 7bc2d9f: left-front PA0 and right-front PA6, already calibrated mm/s. */
|
||||
static volatile uint16_t sdc_wheel_speed_mm_s[2];
|
||||
static volatile uint16_t sdc_gpio_state;
|
||||
static volatile uint16_t sdc_gpio_changed;
|
||||
static volatile uint32_t sdc_gpio_timestamp_ms;
|
||||
@@ -281,18 +285,20 @@ static bool DecodeCan(uint32_t identifier, uint32_t id_type,
|
||||
if (identifier == AMI_CAN_ID_VCU_STATUS)
|
||||
{
|
||||
/* Custom VCU feedback; requests never update these actual states. */
|
||||
if ((length != 8U) || (data[7] != 1U) || (data[0] > 6U) ||
|
||||
(data[1] > 1U) || (data[2] > 1U) || ((data[3] & 0xF8U) != 0U) ||
|
||||
(data[5] != 0U) || (data[6] != 0U))
|
||||
if ((length != 8U) || (data[0] > 6U) ||
|
||||
(data[1] > 1U) || (data[2] > 1U) || (data[6] != 0U) ||
|
||||
!(((data[7] == 1U) && ((data[3] & 0xF8U) == 0U) && (data[5] == 0U)) ||
|
||||
((data[7] == 2U) && ((data[3] & 0xF0U) == 0U) && (data[5] <= 5U))))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
uint8_t states[3] = {
|
||||
uint8_t states[4] = {
|
||||
(data[3] & 1U) ? data[0] : 7U,
|
||||
(data[3] & 2U) ? (data[1] ? 1U : 2U) : 0U,
|
||||
(data[3] & 4U) ? (data[2] ? 1U : 2U) : 0U
|
||||
(data[3] & 4U) ? (data[2] ? 1U : 2U) : 0U,
|
||||
((data[7] == 2U) && (data[3] & 8U)) ? data[5] : 6U
|
||||
};
|
||||
for (uint32_t i = 0U; i < 3U; ++i)
|
||||
for (uint32_t i = 0U; i < 4U; ++i)
|
||||
{
|
||||
if (vcu_display_state[i] != states[i])
|
||||
{
|
||||
@@ -340,13 +346,19 @@ static bool DecodeCan(uint32_t identifier, uint32_t id_type,
|
||||
debug_last_rx_ms = now;
|
||||
return true;
|
||||
}
|
||||
if ((identifier == AMI_CAN_ID_SDC_FREQUENCY) && (length == 8U))
|
||||
if ((identifier == AMI_CAN_ID_SDC_WHEEL_SPEED) && (length == 4U))
|
||||
{
|
||||
for (uint32_t i = 0U; i < 4U; ++i)
|
||||
{
|
||||
sdc_frequency_hz[i] = (uint16_t)ReadLeU16(&data[i * 2U]);
|
||||
}
|
||||
/* Hz is not km/h; wheel circumference and pulses/rev are undefined. */
|
||||
uint32_t left = ReadLeU16(data);
|
||||
uint32_t right = ReadLeU16(&data[2]);
|
||||
sdc_wheel_speed_mm_s[0] = (uint16_t)left;
|
||||
sdc_wheel_speed_mm_s[1] = (uint16_t)right;
|
||||
/* Mean front-wheel mm/s * 0.0036 -> whole km/h, rounded once.
|
||||
SDC already applies 49 pulses/rev and 1414 mm circumference.
|
||||
Zero and 0xFFFF are valid values; the source defines no sentinel. */
|
||||
SetDashValue(0U, (int32_t)(((left + right) * 9U + 2500U) / 5000U));
|
||||
wheel_speed_last_rx_ms = now;
|
||||
wheel_speed_received = true;
|
||||
dash_last_rx_ms = now;
|
||||
return true;
|
||||
}
|
||||
if ((identifier == AMI_CAN_ID_SDC_GPIO) && (length == 8U))
|
||||
@@ -602,13 +614,20 @@ static void UpdateTimeoutsAndLeds(void)
|
||||
__disable_irq();
|
||||
/* Sample time after excluding RX IRQs: a newer timestamp must not underflow. */
|
||||
now = HAL_GetTick();
|
||||
if (wheel_speed_received &&
|
||||
((now - wheel_speed_last_rx_ms) > AMI_WHEEL_SPEED_TIMEOUT_MS))
|
||||
{
|
||||
SetDashValid(0U, false);
|
||||
wheel_speed_received = false;
|
||||
}
|
||||
if (vcu_status_received &&
|
||||
((now - vcu_status_last_rx_ms) > AMI_VCU_STATUS_TIMEOUT_MS))
|
||||
{
|
||||
vcu_display_state[0] = 7U;
|
||||
vcu_display_state[1] = 0U;
|
||||
vcu_display_state[2] = 0U;
|
||||
vcu_display_dirty |= 7U;
|
||||
vcu_display_state[3] = 6U;
|
||||
vcu_display_dirty |= 15U;
|
||||
vcu_status_received = false;
|
||||
}
|
||||
if ((adc_last_rx_ms == 0U) || ((now - adc_last_rx_ms) > AMI_ADC_TIMEOUT_MS))
|
||||
@@ -654,8 +673,8 @@ static void UpdateTimeoutsAndLeds(void)
|
||||
|
||||
static void SendNextDirtyValue(void)
|
||||
{
|
||||
static const char *const vcu_prefix[3] = {
|
||||
"current_task=", "lock_state=", "ebs_state="
|
||||
static const char *const vcu_prefix[4] = {
|
||||
"current_task=", "lock_state=", "ebs_state=", "as_state="
|
||||
};
|
||||
static const char *const dash_prefix[8] = {
|
||||
"dash.speed.val=", "dash.ts.val=", "dash.mct.val=", "dash.dl.val=",
|
||||
@@ -689,14 +708,14 @@ static void SendNextDirtyValue(void)
|
||||
}
|
||||
|
||||
/* Fair rotation prevents rapid source updates from starving other fields. */
|
||||
for (uint32_t offset = 0U; offset < 35U; ++offset)
|
||||
for (uint32_t offset = 0U; offset < 36U; ++offset)
|
||||
{
|
||||
index = (cursor + offset) % 35U;
|
||||
index = (cursor + offset) % 36U;
|
||||
if ((index < 32U) ? ((dirty & (1UL << index)) != 0U)
|
||||
: ((vcu_dirty & (1U << (index - 32U))) != 0U)) { break; }
|
||||
}
|
||||
bit = 1UL << ((index < 32U) ? index : index - 32U);
|
||||
cursor = (index + 1U) % 35U;
|
||||
cursor = (index + 1U) % 36U;
|
||||
|
||||
__disable_irq();
|
||||
if (index >= 32U)
|
||||
@@ -750,7 +769,7 @@ void AMI_App_Init(void)
|
||||
HAL_GPIO_WritePin(STATUS_LED1_GPIO_Port, STATUS_LED1_Pin, LedInactiveLevel());
|
||||
HAL_GPIO_WritePin(STATUS_LED2_GPIO_Port, STATUS_LED2_Pin, AMI_LED_ACTIVE_LEVEL);
|
||||
display_dirty = DIRTY_DASH_ALL | DIRTY_DEBUG_ALL | DIRTY_COLOR_ALL;
|
||||
vcu_display_dirty = 7U;
|
||||
vcu_display_dirty = 15U;
|
||||
ConfigureCan();
|
||||
RestartScreenRx();
|
||||
}
|
||||
@@ -768,7 +787,7 @@ void AMI_App_Service(void)
|
||||
{
|
||||
__disable_irq();
|
||||
display_dirty |= DIRTY_DASH_ALL | DIRTY_DEBUG_ALL | DIRTY_COLOR_ALL;
|
||||
vcu_display_dirty |= 7U;
|
||||
vcu_display_dirty |= 15U;
|
||||
__enable_irq();
|
||||
last_screen_sync_ms = now;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user