sunnypilot v2026.002.000
version: sunnypilot v2026.002.000 (staging) date: 2026-07-21T07:44:02 master commit: 2c334ede443d7391d27575af8c854a095ba702a8
This commit is contained in:
commit
de77c89cf6
3995 files changed
+1260688
No files matched your search
@@ -0,0 +1,16 @@
|
||||
#include "board/sys/sys.h"
|
||||
|
||||
// ********************* Critical section helpers *********************
|
||||
uint8_t global_critical_depth = 0U;
|
||||
|
||||
static volatile bool interrupts_enabled = false;
|
||||
|
||||
void enable_interrupts(void) {
|
||||
interrupts_enabled = true;
|
||||
__enable_irq();
|
||||
}
|
||||
|
||||
void disable_interrupts(void) {
|
||||
interrupts_enabled = false;
|
||||
__disable_irq();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "board/sys/sys.h"
|
||||
|
||||
uint8_t fault_status = FAULT_STATUS_NONE;
|
||||
uint32_t faults = 0U;
|
||||
|
||||
void fault_occurred(uint32_t fault) {
|
||||
if ((faults & fault) == 0U) {
|
||||
if ((PERMANENT_FAULTS & fault) != 0U) {
|
||||
print("Permanent fault occurred: 0x"); puth(fault); print("\n");
|
||||
fault_status = FAULT_STATUS_PERMANENT;
|
||||
} else {
|
||||
print("Temporary fault occurred: 0x"); puth(fault); print("\n");
|
||||
fault_status = FAULT_STATUS_TEMPORARY;
|
||||
}
|
||||
}
|
||||
faults |= fault;
|
||||
}
|
||||
|
||||
void fault_recovered(uint32_t fault) {
|
||||
if ((PERMANENT_FAULTS & fault) == 0U) {
|
||||
faults &= ~fault;
|
||||
} else {
|
||||
print("Cannot recover from a permanent fault!\n");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
#include "board/sys/sys.h"
|
||||
|
||||
// WARNING: To stay in compliance with the SIL2 rules laid out in STM UM2331, we should never use any of the available hardware low power modes during safety function execution.
|
||||
// See rule: CoU_3
|
||||
|
||||
// Low power state "stop mode" is only entered from SAFETY_SILENT when no safety function is active and exited via reset which is a safe state.
|
||||
|
||||
bool power_save_enabled = false;
|
||||
#ifdef ALLOW_DEBUG
|
||||
volatile bool stop_mode_requested = false;
|
||||
#endif
|
||||
|
||||
void enable_can_transceivers(bool enabled) {
|
||||
// Leave main CAN always on for CAN-based ignition detection
|
||||
uint8_t main_bus = (harness.status == HARNESS_STATUS_FLIPPED) ? 3U : 1U;
|
||||
for(uint8_t i=1U; i<=4U; i++){
|
||||
current_board->enable_can_transceiver(i, (i == main_bus) || enabled);
|
||||
}
|
||||
}
|
||||
|
||||
void set_power_save_state(bool enable) {
|
||||
if (enable != power_save_enabled) {
|
||||
if (enable) {
|
||||
print("enable power savings\n");
|
||||
|
||||
// Disable CAN interrupts
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
llcan_irq_disable(cans[0]);
|
||||
} else {
|
||||
llcan_irq_disable(cans[2]);
|
||||
}
|
||||
llcan_irq_disable(cans[1]);
|
||||
} else {
|
||||
print("disable power savings\n");
|
||||
|
||||
if (harness.status == HARNESS_STATUS_FLIPPED) {
|
||||
llcan_irq_enable(cans[0]);
|
||||
} else {
|
||||
llcan_irq_enable(cans[2]);
|
||||
}
|
||||
llcan_irq_enable(cans[1]);
|
||||
}
|
||||
|
||||
enable_can_transceivers(!enable);
|
||||
|
||||
// Switch off IR when in power saving
|
||||
if(enable){
|
||||
current_board->set_ir_power(0U);
|
||||
}
|
||||
|
||||
power_save_enabled = enable;
|
||||
}
|
||||
}
|
||||
|
||||
static void enter_stop_mode(void) {
|
||||
// set all GPIO to analog mode to reduce power, analog mode also disables pull resistors
|
||||
register_set(&(GPIOA->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
register_set(&(GPIOB->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
register_set(&(GPIOC->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
register_set(&(GPIOD->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
register_set(&(GPIOE->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
register_set(&(GPIOF->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
register_set(&(GPIOG->MODER), 0xFFFFFFFFU, 0xFFFFFFFFU);
|
||||
|
||||
// init GPIO to lowest power state
|
||||
current_board->set_bootkick(BOOT_STANDBY);
|
||||
current_board->set_amp_enabled(false);
|
||||
for (uint8_t i = 1U; i <= 4U; i++) {
|
||||
current_board->enable_can_transceiver(i, false);
|
||||
}
|
||||
|
||||
// disable ADCs
|
||||
ADC1->CR &= ~(ADC_CR_ADEN);
|
||||
ADC1->CR |= ADC_CR_DEEPPWD;
|
||||
ADC2->CR &= ~(ADC_CR_ADEN);
|
||||
ADC2->CR |= ADC_CR_DEEPPWD;
|
||||
|
||||
// disable HSI48: 48 MHz USB clock
|
||||
register_clear_bits(&(RCC->CR), RCC_CR_HSI48ON);
|
||||
// disable SRAM retention in stop mode
|
||||
register_clear_bits(&(RCC->AHB2LPENR), RCC_AHB2LPENR_SRAM1LPEN | RCC_AHB2LPENR_SRAM2LPEN);
|
||||
register_clear_bits(&(RCC->AHB4LPENR), RCC_AHB4LPENR_SRAM4LPEN);
|
||||
register_clear_bits(&(RCC->AHB3LPENR), RCC_AHB3LPENR_AXISRAMLPEN);
|
||||
|
||||
// SBU pins to input for EXTI wakeup
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU1,
|
||||
current_board->harness_config->pin_SBU1, MODE_INPUT);
|
||||
set_gpio_mode(current_board->harness_config->GPIO_SBU2,
|
||||
current_board->harness_config->pin_SBU2, MODE_INPUT);
|
||||
|
||||
// EXTI1: SBU2 (PA1)
|
||||
// EXTI4: SBU1 (PC4)
|
||||
register_set(&(SYSCFG->EXTICR[0]), SYSCFG_EXTICR1_EXTI1_PA, 0xF0U);
|
||||
register_set(&(SYSCFG->EXTICR[1]), SYSCFG_EXTICR2_EXTI4_PC, 0xFU);
|
||||
register_set_bits(&(EXTI->IMR1), (1U << 1) | (1U << 4));
|
||||
register_set_bits(&(EXTI->RTSR1), (1U << 1) | (1U << 4));
|
||||
register_set_bits(&(EXTI->FTSR1), (1U << 1) | (1U << 4));
|
||||
|
||||
// EXTI for CAN wakeup
|
||||
// EXTI8: FDCAN1 RX (PB8)
|
||||
// EXTI5: FDCAN2 RX (PB5)
|
||||
// EXTI12: FDCAN3 RX (PD12)
|
||||
set_gpio_mode(GPIOB, 8, MODE_INPUT);
|
||||
register_set(&(SYSCFG->EXTICR[2]), SYSCFG_EXTICR3_EXTI8_PB, 0xFU);
|
||||
set_gpio_mode(GPIOB, 5, MODE_INPUT);
|
||||
register_set(&(SYSCFG->EXTICR[1]), SYSCFG_EXTICR2_EXTI5_PB, 0xF0U);
|
||||
set_gpio_mode(GPIOD, 12, MODE_INPUT);
|
||||
register_set(&(SYSCFG->EXTICR[3]), SYSCFG_EXTICR4_EXTI12_PD, 0xFU);
|
||||
uint32_t can_exti_line = (1UL << 8) | (1UL << 5) | (1UL << 12);
|
||||
register_set_bits(&(EXTI->IMR1), can_exti_line);
|
||||
register_set_bits(&(EXTI->FTSR1), can_exti_line);
|
||||
|
||||
// clear pending EXTI
|
||||
EXTI->PR1 = (1U << 1) | (1U << 4) | can_exti_line;
|
||||
|
||||
// reset if ignition just came on before going to sleep
|
||||
if (harness_check_ignition()) {
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
|
||||
// stop mode
|
||||
register_clear_bits(&(PWR->CPUCR), PWR_CPUCR_PDDS_D1 | PWR_CPUCR_PDDS_D2 | PWR_CPUCR_PDDS_D3);
|
||||
|
||||
// set SVOS5 voltage scaling, flash low-power
|
||||
register_set(&(PWR->CR1), PWR_CR1_SVOS_0 | PWR_CR1_FLPS, PWR_CR1_SVOS | PWR_CR1_FLPS);
|
||||
|
||||
// enter stop mode on WFI
|
||||
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
|
||||
|
||||
__disable_irq();
|
||||
|
||||
// disable all NVIC interrupts and clear pending
|
||||
for (uint32_t i = 0U; i < 8U; i++) {
|
||||
NVIC->ICER[i] = 0xFFFFFFFFU;
|
||||
NVIC->ICPR[i] = 0xFFFFFFFFU;
|
||||
}
|
||||
// enable only wakeup EXTI interrupts
|
||||
NVIC_EnableIRQ(EXTI1_IRQn); // SBU2 (PA1)
|
||||
NVIC_EnableIRQ(EXTI4_IRQn); // SBU1 (PC4)
|
||||
NVIC_EnableIRQ(EXTI9_5_IRQn); // FDCAN1 RX (PB8), FDCAN2 RX (PB5)
|
||||
NVIC_EnableIRQ(EXTI15_10_IRQn); // FDCAN3 RX (PD12)
|
||||
|
||||
__DSB();
|
||||
__ISB();
|
||||
// cppcheck-suppress misra-c2012-17.3 ; CMSIS __WFI macro expands to inline asm
|
||||
__WFI();
|
||||
|
||||
NVIC_SystemReset();
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#pragma once
|
||||
|
||||
// ******************** critical ********************
|
||||
|
||||
void enable_interrupts(void);
|
||||
void disable_interrupts(void);
|
||||
|
||||
extern uint8_t global_critical_depth;
|
||||
|
||||
#ifndef ENTER_CRITICAL
|
||||
#define ENTER_CRITICAL() \
|
||||
__disable_irq(); \
|
||||
global_critical_depth += 1U;
|
||||
#endif
|
||||
|
||||
#ifndef EXIT_CRITICAL
|
||||
#define EXIT_CRITICAL() \
|
||||
global_critical_depth -= 1U; \
|
||||
if ((global_critical_depth == 0U) && interrupts_enabled) { \
|
||||
__enable_irq(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
// ******************** faults ********************
|
||||
|
||||
#define FAULT_STATUS_NONE 0U
|
||||
#define FAULT_STATUS_TEMPORARY 1U
|
||||
#define FAULT_STATUS_PERMANENT 2U
|
||||
|
||||
// Fault types, matches cereal.log.PandaState.FaultType
|
||||
#define FAULT_RELAY_MALFUNCTION (1UL << 0)
|
||||
#define FAULT_UNUSED_INTERRUPT_HANDLED (1UL << 1)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_1 (1UL << 2)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_2 (1UL << 3)
|
||||
#define FAULT_INTERRUPT_RATE_CAN_3 (1UL << 4)
|
||||
#define FAULT_INTERRUPT_RATE_TACH (1UL << 5)
|
||||
#define FAULT_INTERRUPT_RATE_INTERRUPTS (1UL << 7)
|
||||
#define FAULT_INTERRUPT_RATE_SPI_DMA (1UL << 8)
|
||||
#define FAULT_INTERRUPT_RATE_USB (1UL << 15)
|
||||
#define FAULT_REGISTER_DIVERGENT (1UL << 18)
|
||||
#define FAULT_INTERRUPT_RATE_CLOCK_SOURCE (1UL << 20)
|
||||
#define FAULT_INTERRUPT_RATE_TICK (1UL << 21)
|
||||
#define FAULT_INTERRUPT_RATE_EXTI (1UL << 22)
|
||||
#define FAULT_INTERRUPT_RATE_SPI (1UL << 23)
|
||||
#define FAULT_INTERRUPT_RATE_UART_7 (1UL << 24)
|
||||
#define FAULT_SIREN_MALFUNCTION (1UL << 25)
|
||||
#define FAULT_HEARTBEAT_LOOP_WATCHDOG (1UL << 26)
|
||||
#define FAULT_INTERRUPT_RATE_SOUND_DMA (1UL << 27)
|
||||
|
||||
// Permanent faults
|
||||
#define PERMANENT_FAULTS 0U
|
||||
|
||||
extern uint8_t fault_status;
|
||||
extern uint32_t faults;
|
||||
|
||||
void fault_occurred(uint32_t fault);
|
||||
void fault_recovered(uint32_t fault);
|
||||
|
||||
// ******************** power_saving ********************
|
||||
|
||||
extern bool power_save_enabled;
|
||||
|
||||
void set_power_save_state(bool enable);
|
||||
Reference in new issue
Block a user