2019-07-24 06:07:06 +08:00
|
|
|
// ********************* Includes *********************
|
2017-06-28 10:27:24 +08:00
|
|
|
#include "config.h"
|
2017-07-21 14:45:48 +08:00
|
|
|
|
2019-10-26 07:22:42 +08:00
|
|
|
#include "drivers/pwm.h"
|
2017-07-21 14:45:48 +08:00
|
|
|
#include "drivers/usb.h"
|
2018-08-03 02:13:57 +08:00
|
|
|
#include "drivers/gmlan_alt.h"
|
2020-07-11 05:18:24 +08:00
|
|
|
#include "drivers/kline_init.h"
|
2023-04-05 09:51:35 +08:00
|
|
|
#include "drivers/simple_watchdog.h"
|
2023-11-09 14:54:55 +08:00
|
|
|
#include "drivers/bootkick.h"
|
2017-07-22 02:48:03 +08:00
|
|
|
|
2021-07-03 09:25:35 +08:00
|
|
|
#include "early_init.h"
|
|
|
|
#include "provision.h"
|
2019-07-24 06:07:06 +08:00
|
|
|
|
2019-05-22 23:30:32 +08:00
|
|
|
#include "safety.h"
|
2019-07-24 06:07:06 +08:00
|
|
|
|
2022-09-20 07:11:49 +08:00
|
|
|
#include "health.h"
|
|
|
|
|
2021-07-17 03:22:28 +08:00
|
|
|
#include "drivers/can_common.h"
|
2021-08-03 11:26:15 +08:00
|
|
|
|
|
|
|
#ifdef STM32H7
|
|
|
|
#include "drivers/fdcan.h"
|
|
|
|
#else
|
|
|
|
#include "drivers/bxcan.h"
|
|
|
|
#endif
|
2017-07-30 08:53:39 +08:00
|
|
|
|
2023-06-29 03:33:17 +08:00
|
|
|
#include "power_saving.h"
|
|
|
|
|
2021-07-03 09:25:35 +08:00
|
|
|
#include "obj/gitversion.h"
|
|
|
|
|
2022-12-01 14:12:28 +08:00
|
|
|
#include "can_comms.h"
|
2022-08-03 19:11:52 +08:00
|
|
|
#include "main_comms.h"
|
2019-12-10 02:39:04 +08:00
|
|
|
|
|
|
|
|
2019-07-24 06:07:06 +08:00
|
|
|
// ********************* Serial debugging *********************
|
2017-07-21 04:41:21 +08:00
|
|
|
|
2019-10-23 07:12:18 +08:00
|
|
|
bool check_started(void) {
|
2022-08-12 18:43:36 +08:00
|
|
|
bool started = current_board->check_ignition() || ignition_can;
|
|
|
|
ignition_seen |= started;
|
|
|
|
return started;
|
2019-10-23 06:27:55 +08:00
|
|
|
}
|
|
|
|
|
2017-07-21 04:41:21 +08:00
|
|
|
void debug_ring_callback(uart_ring *ring) {
|
|
|
|
char rcv;
|
|
|
|
while (getc(ring, &rcv)) {
|
2019-07-04 07:01:01 +08:00
|
|
|
(void)putc(ring, rcv); // misra-c2012-17.7: cast to void is ok: debug function
|
2017-07-21 04:41:21 +08:00
|
|
|
|
2019-12-11 00:14:30 +08:00
|
|
|
// only allow bootloader entry on debug builds
|
|
|
|
#ifdef ALLOW_DEBUG
|
|
|
|
// jump to DFU flash
|
|
|
|
if (rcv == 'z') {
|
|
|
|
enter_bootloader_mode = ENTER_BOOTLOADER_MAGIC;
|
|
|
|
NVIC_SystemReset();
|
|
|
|
}
|
|
|
|
#endif
|
2017-07-21 04:41:21 +08:00
|
|
|
|
|
|
|
// normal reset
|
|
|
|
if (rcv == 'x') {
|
|
|
|
NVIC_SystemReset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-07-24 06:07:06 +08:00
|
|
|
// ****************************** safety mode ******************************
|
|
|
|
|
|
|
|
// this is the only way to leave silent mode
|
2022-05-03 04:36:19 +08:00
|
|
|
void set_safety_mode(uint16_t mode, uint16_t param) {
|
2019-11-21 07:13:26 +08:00
|
|
|
uint16_t mode_copy = mode;
|
|
|
|
int err = set_safety_hooks(mode_copy, param);
|
2019-07-24 06:07:06 +08:00
|
|
|
if (err == -1) {
|
2022-11-30 14:55:10 +08:00
|
|
|
print("Error: safety set mode failed. Falling back to SILENT\n");
|
2019-11-21 07:13:26 +08:00
|
|
|
mode_copy = SAFETY_SILENT;
|
2022-04-21 14:25:03 +08:00
|
|
|
err = set_safety_hooks(mode_copy, 0U);
|
2019-11-21 05:36:29 +08:00
|
|
|
if (err == -1) {
|
2022-11-30 14:55:10 +08:00
|
|
|
print("Error: Failed setting SILENT mode. Hanging\n");
|
2019-11-21 05:36:29 +08:00
|
|
|
while (true) {
|
|
|
|
// TERMINAL ERROR: we can't continue if SILENT safety mode isn't succesfully set
|
2019-09-28 08:18:02 +08:00
|
|
|
}
|
2019-11-21 05:36:29 +08:00
|
|
|
}
|
2019-07-24 06:07:06 +08:00
|
|
|
}
|
2022-09-16 04:08:46 +08:00
|
|
|
safety_tx_blocked = 0;
|
|
|
|
safety_rx_invalid = 0;
|
2022-01-28 09:46:24 +08:00
|
|
|
|
2019-11-21 07:13:26 +08:00
|
|
|
switch (mode_copy) {
|
2019-11-21 05:36:29 +08:00
|
|
|
case SAFETY_SILENT:
|
2023-08-02 07:33:34 +08:00
|
|
|
set_intercept_relay(false, false);
|
2021-07-03 09:25:35 +08:00
|
|
|
if (current_board->has_obd) {
|
2019-11-21 05:36:29 +08:00
|
|
|
current_board->set_can_mode(CAN_MODE_NORMAL);
|
|
|
|
}
|
|
|
|
can_silent = ALL_CAN_SILENT;
|
|
|
|
break;
|
|
|
|
case SAFETY_NOOUTPUT:
|
2023-08-02 07:33:34 +08:00
|
|
|
set_intercept_relay(false, false);
|
2021-07-03 09:25:35 +08:00
|
|
|
if (current_board->has_obd) {
|
2019-11-21 05:36:29 +08:00
|
|
|
current_board->set_can_mode(CAN_MODE_NORMAL);
|
|
|
|
}
|
|
|
|
can_silent = ALL_CAN_LIVE;
|
|
|
|
break;
|
|
|
|
case SAFETY_ELM327:
|
2023-08-02 07:33:34 +08:00
|
|
|
set_intercept_relay(false, false);
|
2019-11-21 05:36:29 +08:00
|
|
|
heartbeat_counter = 0U;
|
2021-06-05 13:07:45 +08:00
|
|
|
heartbeat_lost = false;
|
2021-07-03 09:25:35 +08:00
|
|
|
if (current_board->has_obd) {
|
2022-04-21 14:25:03 +08:00
|
|
|
if (param == 0U) {
|
2021-06-24 19:12:17 +08:00
|
|
|
current_board->set_can_mode(CAN_MODE_OBD_CAN2);
|
|
|
|
} else {
|
|
|
|
current_board->set_can_mode(CAN_MODE_NORMAL);
|
|
|
|
}
|
2019-11-21 05:36:29 +08:00
|
|
|
}
|
|
|
|
can_silent = ALL_CAN_LIVE;
|
|
|
|
break;
|
|
|
|
default:
|
2023-08-02 07:33:34 +08:00
|
|
|
set_intercept_relay(true, false);
|
2019-11-21 05:36:29 +08:00
|
|
|
heartbeat_counter = 0U;
|
2021-06-05 13:07:45 +08:00
|
|
|
heartbeat_lost = false;
|
2021-07-03 09:25:35 +08:00
|
|
|
if (current_board->has_obd) {
|
2019-11-21 05:36:29 +08:00
|
|
|
current_board->set_can_mode(CAN_MODE_NORMAL);
|
|
|
|
}
|
|
|
|
can_silent = ALL_CAN_LIVE;
|
|
|
|
break;
|
2019-11-21 06:04:07 +08:00
|
|
|
}
|
2019-11-21 05:36:29 +08:00
|
|
|
can_init_all();
|
2019-07-24 06:07:06 +08:00
|
|
|
}
|
|
|
|
|
2021-07-13 12:53:14 +08:00
|
|
|
bool is_car_safety_mode(uint16_t mode) {
|
|
|
|
return (mode != SAFETY_SILENT) &&
|
|
|
|
(mode != SAFETY_NOOUTPUT) &&
|
2022-08-18 13:42:18 +08:00
|
|
|
(mode != SAFETY_ALLOUTPUT) &&
|
2021-07-13 12:53:14 +08:00
|
|
|
(mode != SAFETY_ELM327);
|
|
|
|
}
|
|
|
|
|
2017-04-07 09:11:36 +08:00
|
|
|
// ***************************** main code *****************************
|
|
|
|
|
2019-07-09 06:13:52 +08:00
|
|
|
// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck
|
2019-06-25 01:25:30 +08:00
|
|
|
void __initialize_hardware_early(void) {
|
2021-07-03 09:25:35 +08:00
|
|
|
early_initialization();
|
2017-04-07 09:11:36 +08:00
|
|
|
}
|
|
|
|
|
2019-06-25 01:25:30 +08:00
|
|
|
void __attribute__ ((noinline)) enable_fpu(void) {
|
2018-04-12 10:52:42 +08:00
|
|
|
// enable the FPU
|
2019-07-04 16:04:58 +08:00
|
|
|
SCB->CPACR |= ((3UL << (10U * 2U)) | (3UL << (11U * 2U)));
|
2018-04-12 10:52:42 +08:00
|
|
|
}
|
|
|
|
|
2021-06-22 04:54:09 +08:00
|
|
|
// go into SILENT when heartbeat isn't received for this amount of seconds.
|
|
|
|
#define HEARTBEAT_IGNITION_CNT_ON 5U
|
|
|
|
#define HEARTBEAT_IGNITION_CNT_OFF 2U
|
2019-05-24 02:58:57 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// called at 8Hz
|
|
|
|
uint8_t loop_counter = 0U;
|
2021-07-03 09:25:35 +08:00
|
|
|
void tick_handler(void) {
|
|
|
|
if (TICK_TIMER->SR != 0) {
|
2020-08-17 21:04:01 +08:00
|
|
|
// siren
|
2021-06-29 22:38:50 +08:00
|
|
|
current_board->set_siren((loop_counter & 1U) && (siren_enabled || (siren_countdown > 0U)));
|
2019-05-24 02:58:57 +08:00
|
|
|
|
2022-09-01 11:46:07 +08:00
|
|
|
// tick drivers at 8Hz
|
2022-08-18 11:43:49 +08:00
|
|
|
fan_tick();
|
2023-04-03 23:13:02 +08:00
|
|
|
usb_tick();
|
2023-08-02 12:31:15 +08:00
|
|
|
harness_tick();
|
2023-04-05 09:51:35 +08:00
|
|
|
simple_watchdog_kick();
|
2022-08-18 11:43:49 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// decimated to 1Hz
|
2021-07-13 12:53:14 +08:00
|
|
|
if (loop_counter == 0U) {
|
2020-08-17 21:04:01 +08:00
|
|
|
can_live = pending_can_live;
|
2019-05-24 02:58:57 +08:00
|
|
|
|
2022-11-30 14:55:10 +08:00
|
|
|
//puth(usart1_dma); print(" "); puth(DMA2_Stream5->M0AR); print(" "); puth(DMA2_Stream5->NDTR); print("\n");
|
2019-05-24 02:58:57 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// reset this every 16th pass
|
|
|
|
if ((uptime_cnt & 0xFU) == 0U) {
|
|
|
|
pending_can_live = 0;
|
|
|
|
}
|
|
|
|
#ifdef DEBUG
|
2022-11-30 14:55:10 +08:00
|
|
|
print("** blink ");
|
|
|
|
print("rx:"); puth4(can_rx_q.r_ptr); print("-"); puth4(can_rx_q.w_ptr); print(" ");
|
|
|
|
print("tx1:"); puth4(can_tx1_q.r_ptr); print("-"); puth4(can_tx1_q.w_ptr); print(" ");
|
|
|
|
print("tx2:"); puth4(can_tx2_q.r_ptr); print("-"); puth4(can_tx2_q.w_ptr); print(" ");
|
|
|
|
print("tx3:"); puth4(can_tx3_q.r_ptr); print("-"); puth4(can_tx3_q.w_ptr); print("\n");
|
2020-08-17 21:04:01 +08:00
|
|
|
#endif
|
2019-10-26 07:22:42 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// set green LED to be controls allowed
|
2023-01-11 07:09:51 +08:00
|
|
|
current_board->set_led(LED_GREEN, controls_allowed | green_led_enabled);
|
2019-07-24 06:07:06 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// turn off the blue LED, turned on by CAN
|
|
|
|
// unless we are in power saving mode
|
|
|
|
current_board->set_led(LED_BLUE, (uptime_cnt & 1U) && (power_save_status == POWER_SAVE_STATUS_ENABLED));
|
2019-07-24 06:07:06 +08:00
|
|
|
|
2022-09-01 11:46:07 +08:00
|
|
|
const bool recent_heartbeat = heartbeat_counter == 0U;
|
2023-07-13 11:34:46 +08:00
|
|
|
|
2023-11-09 14:54:55 +08:00
|
|
|
// tick drivers at 1Hz
|
|
|
|
bootkick_tick(check_started(), recent_heartbeat);
|
2023-07-13 11:34:46 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// increase heartbeat counter and cap it at the uint32 limit
|
|
|
|
if (heartbeat_counter < __UINT32_MAX__) {
|
|
|
|
heartbeat_counter += 1U;
|
2019-11-22 04:53:00 +08:00
|
|
|
}
|
2020-01-31 11:23:19 +08:00
|
|
|
|
2022-08-18 13:42:18 +08:00
|
|
|
// disabling heartbeat not allowed while in safety mode
|
|
|
|
if (is_car_safety_mode(current_safety_mode)) {
|
|
|
|
heartbeat_disabled = false;
|
|
|
|
}
|
|
|
|
|
2021-06-29 22:38:50 +08:00
|
|
|
if (siren_countdown > 0U) {
|
|
|
|
siren_countdown -= 1U;
|
|
|
|
}
|
|
|
|
|
2023-03-22 09:49:58 +08:00
|
|
|
if (controls_allowed || heartbeat_engaged) {
|
2021-09-08 06:19:42 +08:00
|
|
|
controls_allowed_countdown = 30U;
|
|
|
|
} else if (controls_allowed_countdown > 0U) {
|
|
|
|
controls_allowed_countdown -= 1U;
|
|
|
|
} else {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2021-12-16 09:28:57 +08:00
|
|
|
// exit controls allowed if unused by openpilot for a few seconds
|
|
|
|
if (controls_allowed && !heartbeat_engaged) {
|
|
|
|
heartbeat_engaged_mismatches += 1U;
|
|
|
|
if (heartbeat_engaged_mismatches >= 3U) {
|
2023-08-19 04:22:04 +08:00
|
|
|
controls_allowed = false;
|
2021-12-16 09:28:57 +08:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
heartbeat_engaged_mismatches = 0U;
|
|
|
|
}
|
|
|
|
|
2021-06-22 04:54:09 +08:00
|
|
|
if (!heartbeat_disabled) {
|
|
|
|
// if the heartbeat has been gone for a while, go to SILENT safety mode and enter power save
|
|
|
|
if (heartbeat_counter >= (check_started() ? HEARTBEAT_IGNITION_CNT_ON : HEARTBEAT_IGNITION_CNT_OFF)) {
|
2022-11-30 14:55:10 +08:00
|
|
|
print("device hasn't sent a heartbeat for 0x");
|
2021-06-22 04:54:09 +08:00
|
|
|
puth(heartbeat_counter);
|
2022-11-30 14:55:10 +08:00
|
|
|
print(" seconds. Safety is set to SILENT mode.\n");
|
2021-06-29 22:38:50 +08:00
|
|
|
|
2021-09-08 06:19:42 +08:00
|
|
|
if (controls_allowed_countdown > 0U) {
|
2021-06-29 22:38:50 +08:00
|
|
|
siren_countdown = 5U;
|
2021-09-08 06:19:42 +08:00
|
|
|
controls_allowed_countdown = 0U;
|
2021-06-29 22:38:50 +08:00
|
|
|
}
|
|
|
|
|
2021-07-13 12:53:14 +08:00
|
|
|
// set flag to indicate the heartbeat was lost
|
|
|
|
if (is_car_safety_mode(current_safety_mode)) {
|
|
|
|
heartbeat_lost = true;
|
|
|
|
}
|
|
|
|
|
2023-05-08 12:00:05 +08:00
|
|
|
// clear heartbeat engaged state
|
|
|
|
heartbeat_engaged = false;
|
|
|
|
|
2021-06-22 04:54:09 +08:00
|
|
|
if (current_safety_mode != SAFETY_SILENT) {
|
|
|
|
set_safety_mode(SAFETY_SILENT, 0U);
|
|
|
|
}
|
2022-11-18 00:59:11 +08:00
|
|
|
|
2021-06-22 04:54:09 +08:00
|
|
|
if (power_save_status != POWER_SAVE_STATUS_ENABLED) {
|
|
|
|
set_power_save_state(POWER_SAVE_STATUS_ENABLED);
|
|
|
|
}
|
2020-06-12 09:14:41 +08:00
|
|
|
|
2021-06-22 04:54:09 +08:00
|
|
|
// Also disable IR when the heartbeat goes missing
|
|
|
|
current_board->set_ir_power(0U);
|
2020-08-17 21:04:01 +08:00
|
|
|
|
2023-07-02 09:57:53 +08:00
|
|
|
// Run fan when device is up, but not talking to us
|
|
|
|
// * bootloader enables the SOM GPIO on boot
|
|
|
|
// * fallback to USB enumerated where supported
|
|
|
|
bool enabled = usb_enumerated || current_board->read_som_gpio();
|
|
|
|
fan_set_power(enabled ? 50U : 0U);
|
2020-08-17 21:04:01 +08:00
|
|
|
}
|
|
|
|
}
|
2019-05-24 02:58:57 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// check registers
|
|
|
|
check_registers();
|
2019-12-10 02:39:04 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// set ignition_can to false after 2s of no CAN seen
|
|
|
|
if (ignition_can_cnt > 2U) {
|
|
|
|
ignition_can = false;
|
2021-07-13 12:53:14 +08:00
|
|
|
}
|
2019-12-04 08:44:55 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
// on to the next one
|
|
|
|
uptime_cnt += 1U;
|
|
|
|
safety_mode_cnt += 1U;
|
|
|
|
ignition_can_cnt += 1U;
|
|
|
|
|
|
|
|
// synchronous safety check
|
2021-09-04 02:45:17 +08:00
|
|
|
safety_tick(current_rx_checks);
|
2020-08-17 21:04:01 +08:00
|
|
|
}
|
2019-12-21 17:25:54 +08:00
|
|
|
|
2020-08-17 21:04:01 +08:00
|
|
|
loop_counter++;
|
|
|
|
loop_counter %= 8U;
|
2019-05-24 02:58:57 +08:00
|
|
|
}
|
2021-07-03 09:25:35 +08:00
|
|
|
TICK_TIMER->SR = 0;
|
2019-05-24 02:58:57 +08:00
|
|
|
}
|
|
|
|
|
2022-03-08 06:24:04 +08:00
|
|
|
void EXTI_IRQ_Handler(void) {
|
|
|
|
if (check_exti_irq()) {
|
|
|
|
exti_irq_clear();
|
|
|
|
clock_init();
|
|
|
|
|
|
|
|
set_power_save_state(POWER_SAVE_STATUS_DISABLED);
|
2022-08-02 08:25:48 +08:00
|
|
|
deepsleep_allowed = false;
|
2022-03-08 06:24:04 +08:00
|
|
|
heartbeat_counter = 0U;
|
|
|
|
usb_soft_disconnect(false);
|
|
|
|
|
|
|
|
NVIC_EnableIRQ(TICK_TIMER_IRQ);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t rtc_counter = 0;
|
|
|
|
void RTC_WKUP_IRQ_Handler(void) {
|
|
|
|
exti_irq_clear();
|
|
|
|
clock_init();
|
|
|
|
|
|
|
|
rtc_counter++;
|
|
|
|
if ((rtc_counter % 2U) == 0U) {
|
|
|
|
current_board->set_led(LED_BLUE, false);
|
|
|
|
} else {
|
|
|
|
current_board->set_led(LED_BLUE, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rtc_counter == __UINT8_MAX__) {
|
|
|
|
rtc_counter = 1U;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-07-03 09:25:35 +08:00
|
|
|
|
2019-06-25 01:25:30 +08:00
|
|
|
int main(void) {
|
2019-12-06 06:19:29 +08:00
|
|
|
// Init interrupt table
|
2019-11-28 10:11:21 +08:00
|
|
|
init_interrupts(true);
|
2019-12-06 06:19:29 +08:00
|
|
|
|
2017-07-21 14:42:19 +08:00
|
|
|
// shouldn't have interrupts here, but just in case
|
2019-08-29 03:53:51 +08:00
|
|
|
disable_interrupts();
|
2017-07-21 14:14:27 +08:00
|
|
|
|
2017-07-28 06:54:55 +08:00
|
|
|
// init early devices
|
2017-04-07 09:11:36 +08:00
|
|
|
clock_init();
|
2019-07-24 06:07:06 +08:00
|
|
|
peripherals_init();
|
|
|
|
detect_board_type();
|
2023-09-06 04:36:13 +08:00
|
|
|
// red+green leds enabled until succesful USB/SPI init, as a debug indicator
|
|
|
|
current_board->set_led(LED_RED, true);
|
|
|
|
current_board->set_led(LED_GREEN, true);
|
2019-07-24 06:07:06 +08:00
|
|
|
adc_init();
|
2019-09-28 08:18:02 +08:00
|
|
|
|
2017-07-28 06:54:55 +08:00
|
|
|
// print hello
|
2022-11-30 14:55:10 +08:00
|
|
|
print("\n\n\n************************ MAIN START ************************\n");
|
2017-04-18 04:57:34 +08:00
|
|
|
|
2019-07-24 06:07:06 +08:00
|
|
|
// check for non-supported board types
|
|
|
|
if(hw_type == HW_TYPE_UNKNOWN){
|
2022-11-30 14:55:10 +08:00
|
|
|
print("Unsupported board type\n");
|
2019-07-24 06:07:06 +08:00
|
|
|
while (1) { /* hang */ }
|
2019-06-29 04:46:57 +08:00
|
|
|
}
|
2019-05-20 00:12:03 +08:00
|
|
|
|
2022-11-30 14:55:10 +08:00
|
|
|
print("Config:\n");
|
|
|
|
print(" Board type: "); print(current_board->board_type); print("\n");
|
2019-07-24 06:07:06 +08:00
|
|
|
|
|
|
|
// init board
|
|
|
|
current_board->init();
|
2017-04-07 09:11:36 +08:00
|
|
|
|
2018-04-12 10:52:42 +08:00
|
|
|
// panda has an FPU, let's use it!
|
|
|
|
enable_fpu();
|
|
|
|
|
2022-11-18 13:02:37 +08:00
|
|
|
if (current_board->has_lin) {
|
2019-07-24 06:07:06 +08:00
|
|
|
// enable LIN
|
2019-10-05 04:28:56 +08:00
|
|
|
uart_init(&uart_ring_lin1, 10400);
|
2019-07-24 06:07:06 +08:00
|
|
|
UART5->CR2 |= USART_CR2_LINEN;
|
2019-10-05 04:28:56 +08:00
|
|
|
uart_init(&uart_ring_lin2, 10400);
|
2019-07-24 06:07:06 +08:00
|
|
|
USART3->CR2 |= USART_CR2_LINEN;
|
|
|
|
}
|
2017-04-07 09:11:36 +08:00
|
|
|
|
2022-11-18 13:02:37 +08:00
|
|
|
if (current_board->fan_max_rpm > 0U) {
|
2023-04-21 06:44:12 +08:00
|
|
|
fan_init();
|
2022-11-18 13:02:37 +08:00
|
|
|
}
|
|
|
|
|
2021-07-03 09:25:35 +08:00
|
|
|
microsecond_timer_init();
|
2017-10-27 09:44:25 +08:00
|
|
|
|
2019-11-21 03:56:26 +08:00
|
|
|
// init to SILENT and can silent
|
2022-04-21 14:25:03 +08:00
|
|
|
set_safety_mode(SAFETY_SILENT, 0U);
|
2017-05-31 00:46:21 +08:00
|
|
|
|
2019-11-22 05:42:36 +08:00
|
|
|
// enable CAN TXs
|
2020-09-28 22:19:09 +08:00
|
|
|
current_board->enable_can_transceivers(true);
|
2019-11-22 05:42:36 +08:00
|
|
|
|
2023-05-16 05:15:48 +08:00
|
|
|
// init watchdog for heartbeat loop, fed at 8Hz
|
|
|
|
simple_watchdog_init(FAULT_HEARTBEAT_LOOP_WATCHDOG, (3U * 1000000U / 8U));
|
2023-04-05 09:51:35 +08:00
|
|
|
|
2021-07-03 09:25:35 +08:00
|
|
|
// 8Hz timer
|
|
|
|
REGISTER_INTERRUPT(TICK_TIMER_IRQ, tick_handler, 10U, FAULT_INTERRUPT_RATE_TICK)
|
|
|
|
tick_timer_init();
|
2019-05-24 02:58:57 +08:00
|
|
|
|
2019-04-02 13:45:00 +08:00
|
|
|
#ifdef DEBUG
|
2022-11-30 14:55:10 +08:00
|
|
|
print("DEBUG ENABLED\n");
|
2019-04-02 13:45:00 +08:00
|
|
|
#endif
|
2019-07-24 06:07:06 +08:00
|
|
|
// enable USB (right before interrupts or enum can fail!)
|
|
|
|
usb_init();
|
2017-04-07 09:11:36 +08:00
|
|
|
|
2022-11-10 10:46:20 +08:00
|
|
|
#ifdef ENABLE_SPI
|
2022-11-14 11:57:20 +08:00
|
|
|
if (current_board->has_spi) {
|
|
|
|
spi_init();
|
|
|
|
}
|
2022-11-10 10:46:20 +08:00
|
|
|
#endif
|
|
|
|
|
2023-09-06 04:36:13 +08:00
|
|
|
current_board->set_led(LED_RED, false);
|
|
|
|
current_board->set_led(LED_GREEN, false);
|
|
|
|
|
2022-11-30 14:55:10 +08:00
|
|
|
print("**** INTERRUPTS ON ****\n");
|
2019-06-15 04:28:15 +08:00
|
|
|
enable_interrupts();
|
2017-04-07 09:11:36 +08:00
|
|
|
|
|
|
|
// LED should keep on blinking all the time
|
2017-08-22 23:27:00 +08:00
|
|
|
uint64_t cnt = 0;
|
|
|
|
|
2017-04-07 09:11:36 +08:00
|
|
|
for (cnt=0;;cnt++) {
|
2019-05-24 02:58:57 +08:00
|
|
|
if (power_save_status == POWER_SAVE_STATUS_DISABLED) {
|
2019-11-28 10:11:21 +08:00
|
|
|
#ifdef DEBUG_FAULTS
|
2022-09-01 11:46:07 +08:00
|
|
|
if (fault_status == FAULT_STATUS_NONE) {
|
2019-11-28 10:11:21 +08:00
|
|
|
#endif
|
|
|
|
// useful for debugging, fade breaks = panda is overloaded
|
2022-09-01 11:46:07 +08:00
|
|
|
for (uint32_t fade = 0U; fade < MAX_LED_FADE; fade += 1U) {
|
2020-06-03 05:21:41 +08:00
|
|
|
current_board->set_led(LED_RED, true);
|
|
|
|
delay(fade >> 4);
|
|
|
|
current_board->set_led(LED_RED, false);
|
2021-07-03 09:25:35 +08:00
|
|
|
delay((MAX_LED_FADE - fade) >> 4);
|
2019-05-22 00:47:43 +08:00
|
|
|
}
|
2020-06-03 05:21:41 +08:00
|
|
|
|
2022-09-01 11:46:07 +08:00
|
|
|
for (uint32_t fade = MAX_LED_FADE; fade > 0U; fade -= 1U) {
|
2020-06-03 05:21:41 +08:00
|
|
|
current_board->set_led(LED_RED, true);
|
|
|
|
delay(fade >> 4);
|
|
|
|
current_board->set_led(LED_RED, false);
|
2021-07-03 09:25:35 +08:00
|
|
|
delay((MAX_LED_FADE - fade) >> 4);
|
2020-06-03 05:21:41 +08:00
|
|
|
}
|
|
|
|
|
2019-11-28 10:11:21 +08:00
|
|
|
#ifdef DEBUG_FAULTS
|
|
|
|
} else {
|
|
|
|
current_board->set_led(LED_RED, 1);
|
|
|
|
delay(512000U);
|
|
|
|
current_board->set_led(LED_RED, 0);
|
|
|
|
delay(512000U);
|
|
|
|
}
|
|
|
|
#endif
|
2019-05-24 02:58:57 +08:00
|
|
|
} else {
|
2022-08-12 18:43:36 +08:00
|
|
|
if (deepsleep_allowed && !usb_enumerated && !check_started() && ignition_seen && (heartbeat_counter > 20U)) {
|
2022-03-08 06:24:04 +08:00
|
|
|
usb_soft_disconnect(true);
|
2022-08-18 11:43:49 +08:00
|
|
|
fan_set_power(0U);
|
2022-03-08 06:24:04 +08:00
|
|
|
NVIC_DisableIRQ(TICK_TIMER_IRQ);
|
|
|
|
delay(512000U);
|
|
|
|
|
|
|
|
// Init IRQs for CAN transceiver and ignition line
|
|
|
|
exti_irq_init();
|
|
|
|
|
|
|
|
// Init RTC Wakeup event on EXTI22
|
|
|
|
REGISTER_INTERRUPT(RTC_WKUP_IRQn, RTC_WKUP_IRQ_Handler, 10U, FAULT_INTERRUPT_RATE_EXTI)
|
|
|
|
rtc_wakeup_init();
|
|
|
|
|
|
|
|
// STOP mode
|
|
|
|
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
|
|
|
}
|
2019-05-24 02:58:57 +08:00
|
|
|
__WFI();
|
2022-03-08 06:24:04 +08:00
|
|
|
SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk;
|
2017-08-23 00:44:08 +08:00
|
|
|
}
|
2017-04-07 09:11:36 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|