feat: add CAN board test tool and timing safeguards

This commit is contained in:
shenlefengnai-rgb
2026-10-01 17:43:28 +08:00
parent be4f167b83
commit 34627fa6a0
14 changed files with 607 additions and 44 deletions
+57 -20
View File
@@ -62,8 +62,10 @@ typedef struct
#define GPIO_INPUT_MASK 0x7FFFU
#define UART_LINE_SIZE 32U
#define REPORT_PERIOD_MS 500U
#define CAN_HEARTBEAT_PERIOD_MS 1000U
#define ADC_REPORT_PERIOD_MS 500U
#define PWM_REPORT_PERIOD_MS 20U
#define CAN_HEARTBEAT_PERIOD_MS 100U
#define DAC_CAN_TIMEOUT_MS 100U
#define PWM_TIMEOUT_MS 1000U
#define CAN_HEARTBEAT_STD_ID 0x6A0U
@@ -109,9 +111,12 @@ static uint16_t gpio_last_state;
static volatile uint16_t gpio_shadow_state;
static volatile uint16_t gpio_report_state;
static volatile uint16_t gpio_pending_changed_mask;
static uint32_t last_report_ms;
static uint32_t last_heartbeat_ms;
static uint32_t last_can_heartbeat_ms;
static uint32_t last_adc_report_ms;
static uint32_t last_pwm_report_ms;
static uint32_t last_heartbeat_ms;
static uint32_t last_can_heartbeat_ms;
static uint32_t dac_can_last_command_ms[2];
static bool dac_can_watchdog_active[2];
static uint16_t can_heartbeat_sequence;
static uint32_t adc_filter_history[ADC_FILTER_WINDOW];
static uint32_t adc_filter_sum;
@@ -144,6 +149,7 @@ static void PollGpioChanges(void);
static void SendPeriodicReport(void);
static void ServiceHeartbeat(void);
static void ServiceAssiLamp(void);
static void ServiceDacCanWatchdog(void);
static void SendCanHeartbeat(void);
static void HandleAssiLampSetRequest(const char *source, uint8_t state);
static void HandleTextCommand(const char *source, const char *line);
@@ -234,6 +240,7 @@ int main(void)
PollUart();
PollCanBus(&hcan1, "CAN1");
PollCanBus(&hcan2, "CAN2");
ServiceDacCanWatchdog();
ServiceAssiLamp();
PollCaptureChannels();
PollGpioChanges();
@@ -758,9 +765,14 @@ static void AppInit(void)
gpio_shadow_state = gpio_last_state;
gpio_report_state = gpio_last_state;
gpio_pending_changed_mask = 0U;
last_report_ms = HAL_GetTick();
last_heartbeat_ms = last_report_ms;
last_can_heartbeat_ms = last_report_ms;
last_adc_report_ms = HAL_GetTick();
last_pwm_report_ms = last_adc_report_ms;
last_heartbeat_ms = last_adc_report_ms;
last_can_heartbeat_ms = last_adc_report_ms;
dac_can_last_command_ms[0] = 0U;
dac_can_last_command_ms[1] = 0U;
dac_can_watchdog_active[0] = false;
dac_can_watchdog_active[1] = false;
can_heartbeat_sequence = 0U;
adc_filter_sum = 0U;
adc_filter_count = 0U;
@@ -826,10 +838,12 @@ static void PollCanBus(CAN_HandleTypeDef *hcan, const char *name)
if (rx_header.StdId == CAN_DAC_CMD_STD_ID)
{
if ((rx_header.DLC >= 3U) && (rx_data[0] >= 1U) && (rx_data[0] <= 2U))
{
uint16_t millivolts = (uint16_t)rx_data[1] | ((uint16_t)rx_data[2] << 8);
HandleDacSetRequest(name, rx_data[0], millivolts);
if ((rx_header.DLC >= 3U) && (rx_data[0] >= 1U) && (rx_data[0] <= 2U))
{
uint16_t millivolts = (uint16_t)rx_data[1] | ((uint16_t)rx_data[2] << 8);
HandleDacSetRequest(name, rx_data[0], millivolts);
dac_can_last_command_ms[rx_data[0] - 1U] = HAL_GetTick();
dac_can_watchdog_active[rx_data[0] - 1U] = true;
}
else
{
@@ -918,12 +932,12 @@ static void SendPeriodicReport(void)
{
uint32_t now = HAL_GetTick();
if ((now - last_report_ms) >= REPORT_PERIOD_MS)
{
if ((now - last_adc_report_ms) >= ADC_REPORT_PERIOD_MS)
{
uint32_t adc_mv = ReadAdcInputMillivolts();
char line[160];
last_report_ms = now;
last_adc_report_ms = now;
snprintf(line,
sizeof(line),
@@ -933,11 +947,16 @@ static void SendPeriodicReport(void)
(unsigned long)capture_channels[1].frequency_hz,
(unsigned long)capture_channels[2].frequency_hz,
(unsigned long)capture_channels[3].frequency_hz);
UartWrite(line);
BroadcastAdcReport(adc_mv);
BroadcastPwmReport();
}
}
UartWrite(line);
BroadcastAdcReport(adc_mv);
}
if ((now - last_pwm_report_ms) >= PWM_REPORT_PERIOD_MS)
{
last_pwm_report_ms = now;
BroadcastPwmReport();
}
}
static void ServiceHeartbeat(void)
{
@@ -987,6 +1006,24 @@ static void ServiceAssiLamp(void)
HAL_GPIO_WritePin(GPIOE, GPIO_PIN_11, blue);
}
static void ServiceDacCanWatchdog(void)
{
uint32_t now = HAL_GetTick();
uint8_t dac_id;
for (dac_id = 1U; dac_id <= 2U; dac_id++)
{
uint8_t index = dac_id - 1U;
if (dac_can_watchdog_active[index] &&
((now - dac_can_last_command_ms[index]) >= DAC_CAN_TIMEOUT_MS))
{
(void)DacSetMillivolts(dac_id, 0U);
dac_can_watchdog_active[index] = false;
}
}
}
static void HandleAssiLampSetRequest(const char *source, uint8_t state)
{
char reply[64];