From 656f99b080b27baa8dae623a773ce107c39116a6 Mon Sep 17 00:00:00 2001 From: robbederks Date: Wed, 27 Nov 2019 18:11:21 -0800 Subject: [PATCH] Interrupt refactor (NVIC_SM_1: #334) and Fault handling (#377) (PR #373) --- board/boards/common.h | 2 +- board/bootstub.c | 4 + board/config.h | 4 + board/drivers/can.h | 52 ++++++---- board/drivers/fan.h | 29 +++--- board/drivers/gmlan_alt.h | 4 +- board/drivers/interrupts.h | 190 +++++++++++++++++++++++++++++++++++++ board/drivers/spi.h | 58 +++++------ board/drivers/uart.h | 17 +++- board/drivers/usb.h | 145 ++++++++++++++-------------- board/faults.h | 48 ++++++++++ board/inc/stm32f413xx.h | 1 + board/libc.h | 25 ----- board/main.c | 49 ++++++---- board/pedal/main.c | 22 +++-- board/spi_flasher.h | 12 ++- tests/misra/.gitignore | 1 + 17 files changed, 473 insertions(+), 190 deletions(-) create mode 100644 board/drivers/interrupts.h create mode 100644 board/faults.h create mode 100644 tests/misra/.gitignore diff --git a/board/boards/common.h b/board/boards/common.h index e33b2a2f0426c4..d0a49087632ee6 100644 --- a/board/boards/common.h +++ b/board/boards/common.h @@ -61,7 +61,7 @@ void peripherals_init(void){ RCC->APB1ENR |= RCC_APB1ENR_TIM3EN; // pedal and fan PWM RCC->APB1ENR |= RCC_APB1ENR_TIM4EN; // gmlan_alt and IR PWM //RCC->APB1ENR |= RCC_APB1ENR_TIM5EN; - //RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; + RCC->APB1ENR |= RCC_APB1ENR_TIM6EN; // interrupt timer RCC->APB1ENR |= RCC_APB1ENR_PWREN; // for RTC config RCC->APB2ENR |= RCC_APB2ENR_USART1EN; RCC->AHB2ENR |= RCC_AHB2ENR_OTGFSEN; diff --git a/board/bootstub.c b/board/bootstub.c index 8ada20c7383224..78376d91584189 100644 --- a/board/bootstub.c +++ b/board/bootstub.c @@ -29,7 +29,9 @@ const board *current_board; // ********************* Includes ********************* #include "libc.h" #include "provision.h" +#include "faults.h" +#include "drivers/interrupts.h" #include "drivers/clock.h" #include "drivers/llgpio.h" #include "drivers/adc.h" @@ -65,6 +67,8 @@ extern void *_app_start[]; // BOUNTY: $200 coupon on shop.comma.ai or $100 check. int main(void) { + init_interrupts(false); + disable_interrupts(); clock_init(); detect_configuration(); diff --git a/board/config.h b/board/config.h index c2eb412e960903..15096b69fa809b 100644 --- a/board/config.h +++ b/board/config.h @@ -5,6 +5,7 @@ //#define DEBUG_UART //#define DEBUG_USB //#define DEBUG_SPI +//#define DEBUG_FAULTS #ifdef STM32F4 #define PANDA @@ -37,5 +38,8 @@ #define MAX_RESP_LEN 0x40U +// Around (1Mbps / 8 bits/byte / 12 bytes per message) +#define CAN_INTERRUPT_RATE 12000U + #endif diff --git a/board/drivers/can.h b/board/drivers/can.h index 5e6fd95b8c12b1..504056f0c3484d 100644 --- a/board/drivers/can.h +++ b/board/drivers/can.h @@ -148,18 +148,6 @@ void can_set_speed(uint8_t can_number) { } } -void can_init(uint8_t can_number) { - if (can_number != 0xffU) { - CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); - can_set_speed(can_number); - - llcan_init(CAN); - - // in case there are queued up messages - process_can(can_number); - } -} - void can_init_all(void) { for (uint8_t i=0U; i < CAN_MAX; i++) { can_init(i); @@ -407,17 +395,17 @@ void can_rx(uint8_t can_number) { } } -void CAN1_TX_IRQHandler(void) { process_can(0); } -void CAN1_RX0_IRQHandler(void) { can_rx(0); } -void CAN1_SCE_IRQHandler(void) { can_sce(CAN1); } +void CAN1_TX_IRQ_Handler(void) { process_can(0); } +void CAN1_RX0_IRQ_Handler(void) { can_rx(0); } +void CAN1_SCE_IRQ_Handler(void) { can_sce(CAN1); } -void CAN2_TX_IRQHandler(void) { process_can(1); } -void CAN2_RX0_IRQHandler(void) { can_rx(1); } -void CAN2_SCE_IRQHandler(void) { can_sce(CAN2); } +void CAN2_TX_IRQ_Handler(void) { process_can(1); } +void CAN2_RX0_IRQ_Handler(void) { can_rx(1); } +void CAN2_SCE_IRQ_Handler(void) { can_sce(CAN2); } -void CAN3_TX_IRQHandler(void) { process_can(2); } -void CAN3_RX0_IRQHandler(void) { can_rx(2); } -void CAN3_SCE_IRQHandler(void) { can_sce(CAN3); } +void CAN3_TX_IRQ_Handler(void) { process_can(2); } +void CAN3_RX0_IRQ_Handler(void) { can_rx(2); } +void CAN3_SCE_IRQ_Handler(void) { can_sce(CAN3); } void can_send(CAN_FIFOMailBox_TypeDef *to_push, uint8_t bus_number, bool skip_tx_hook) { if (skip_tx_hook || safety_tx_hook(to_push) != 0) { @@ -439,3 +427,25 @@ void can_set_forwarding(int from, int to) { can_forwarding[from] = to; } +void can_init(uint8_t can_number) { + REGISTER_INTERRUPT(CAN1_TX_IRQn, CAN1_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN1_RX0_IRQn, CAN1_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN1_SCE_IRQn, CAN1_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN2_TX_IRQn, CAN2_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_2) + REGISTER_INTERRUPT(CAN2_RX0_IRQn, CAN2_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_2) + REGISTER_INTERRUPT(CAN2_SCE_IRQn, CAN2_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_2) + REGISTER_INTERRUPT(CAN3_TX_IRQn, CAN3_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_3) + REGISTER_INTERRUPT(CAN3_RX0_IRQn, CAN3_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_3) + REGISTER_INTERRUPT(CAN3_SCE_IRQn, CAN3_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_3) + + if (can_number != 0xffU) { + CAN_TypeDef *CAN = CANIF_FROM_CAN_NUM(can_number); + can_set_speed(can_number); + + llcan_init(CAN); + + // in case there are queued up messages + process_can(can_number); + } +} + diff --git a/board/drivers/fan.h b/board/drivers/fan.h index d7326ec0b33d59..89b4bd34314e59 100644 --- a/board/drivers/fan.h +++ b/board/drivers/fan.h @@ -1,15 +1,3 @@ -void fan_init(void){ - // Init PWM speed control - pwm_init(TIM3, 3); - - // Init TACH interrupt - SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI2_PD; - EXTI->IMR |= (1U << 2); - EXTI->RTSR |= (1U << 2); - EXTI->FTSR |= (1U << 2); - NVIC_EnableIRQ(EXTI2_IRQn); -} - void fan_set_power(uint8_t percentage){ pwm_set(TIM3, 3, percentage); } @@ -27,10 +15,25 @@ void fan_tick(void){ } // TACH interrupt handler -void EXTI2_IRQHandler(void) { +void EXTI2_IRQ_Handler(void) { volatile unsigned int pr = EXTI->PR & (1U << 2); if ((pr & (1U << 2)) != 0U) { fan_tach_counter++; } EXTI->PR = (1U << 2); +} + +void fan_init(void){ + // 5000RPM * 4 tach edges / 60 seconds + REGISTER_INTERRUPT(EXTI2_IRQn, EXTI2_IRQ_Handler, 700U, FAULT_INTERRUPT_RATE_TACH) + + // Init PWM speed control + pwm_init(TIM3, 3); + + // Init TACH interrupt + SYSCFG->EXTICR[0] = SYSCFG_EXTICR1_EXTI2_PD; + EXTI->IMR |= (1U << 2); + EXTI->RTSR |= (1U << 2); + EXTI->FTSR |= (1U << 2); + NVIC_EnableIRQ(EXTI2_IRQn); } \ No newline at end of file diff --git a/board/drivers/gmlan_alt.h b/board/drivers/gmlan_alt.h index c697a21b41ef9c..8fd32476f62002 100644 --- a/board/drivers/gmlan_alt.h +++ b/board/drivers/gmlan_alt.h @@ -187,7 +187,7 @@ int gmlan_fail_count = 0; #define REQUIRED_SILENT_TIME 10 #define MAX_FAIL_COUNT 10 -void TIM4_IRQHandler(void) { +void TIM4_IRQ_Handler(void) { if (gmlan_alt_mode == BITBANG) { if ((TIM4->SR & TIM_SR_UIF) && (gmlan_sendmax != -1)) { int read = get_gpio_input(GPIOB, 12); @@ -279,6 +279,8 @@ bool bitbang_gmlan(CAN_FIFOMailBox_TypeDef *to_bang) { set_bitbanged_gmlan(1); // recessive set_gpio_mode(GPIOB, 13, MODE_OUTPUT); + // 33kbps + REGISTER_INTERRUPT(TIM4_IRQn, TIM4_IRQ_Handler, 40000U, FAULT_INTERRUPT_RATE_GMLAN) setup_timer4(); } return gmlan_send_ok; diff --git a/board/drivers/interrupts.h b/board/drivers/interrupts.h new file mode 100644 index 00000000000000..d0a138edb5e0ba --- /dev/null +++ b/board/drivers/interrupts.h @@ -0,0 +1,190 @@ +// ********************* Interrupt helpers ********************* +volatile bool interrupts_enabled = false; + +void enable_interrupts(void) { + interrupts_enabled = true; + __enable_irq(); +} + +void disable_interrupts(void) { + interrupts_enabled = false; + __disable_irq(); +} + +uint8_t global_critical_depth = 0U; +#define ENTER_CRITICAL() \ + __disable_irq(); \ + global_critical_depth += 1U; + +#define EXIT_CRITICAL() \ + global_critical_depth -= 1U; \ + if ((global_critical_depth == 0U) && interrupts_enabled) { \ + __enable_irq(); \ + } + +// ********************* Interrupt handling ********************* + +typedef struct interrupt { + IRQn_Type irq_type; + void (*handler)(void); + uint32_t call_counter; + uint32_t max_call_rate; // Call rate is defined as the amount of calls each second + uint32_t call_rate_fault; +} interrupt; + +void unused_interrupt_handler(void) { + // Something is wrong if this handler is called! + puts("Unused interrupt handler called!\n"); + fault_occurred(FAULT_UNUSED_INTERRUPT_HANDLED); +} + +#define NUM_INTERRUPTS 102U // There are 102 external interrupt sources (see stm32f413.h) +interrupt interrupts[NUM_INTERRUPTS]; + +#define REGISTER_INTERRUPT(irq_num, func_ptr, call_rate, rate_fault) \ + interrupts[irq_num].irq_type = irq_num; \ + interrupts[irq_num].handler = func_ptr; \ + interrupts[irq_num].call_counter = 0U; \ + interrupts[irq_num].max_call_rate = call_rate; \ + interrupts[irq_num].call_rate_fault = rate_fault; + +bool check_interrupt_rate = false; + +void handle_interrupt(IRQn_Type irq_type){ + interrupts[irq_type].call_counter++; + interrupts[irq_type].handler(); + + // Check that the interrupts don't fire too often + if(check_interrupt_rate && (interrupts[irq_type].call_counter > interrupts[irq_type].max_call_rate)){ + puts("Interrupt 0x"); puth(irq_type); puts(" fired too often (0x"); puth(interrupts[irq_type].call_counter); puts("/s)!\n"); + fault_occurred(interrupts[irq_type].call_rate_fault); + } +} + +// Reset interrupt counter every second +void TIM6_DAC_IRQ_Handler(void) { + if (TIM6->SR != 0) { + for(uint16_t i=0U; iSR = 0; +} + +void init_interrupts(bool check_rate_limit){ + check_interrupt_rate = check_rate_limit; + + for(uint16_t i=0U; iAPB1ENR |= RCC_APB1ENR_TIM6EN; // enable interrupt timer peripheral + REGISTER_INTERRUPT(TIM6_DAC_IRQn, TIM6_DAC_IRQ_Handler, 1, FAULT_INTERRUPT_RATE_INTERRUPTS) + TIM6->PSC = 732-1; + TIM6->DIER = TIM_DIER_UIE; + TIM6->CR1 = TIM_CR1_CEN; + TIM6->SR = 0; + NVIC_EnableIRQ(TIM6_DAC_IRQn); +} + +// ********************* Bare interrupt handlers ********************* +// Only implemented the STM32F413 interrupts for now, the STM32F203 specific ones do not fall into the scope of SIL2 + +void WWDG_IRQHandler(void) {handle_interrupt(WWDG_IRQn);} +void PVD_IRQHandler(void) {handle_interrupt(PVD_IRQn);} +void TAMP_STAMP_IRQHandler(void) {handle_interrupt(TAMP_STAMP_IRQn);} +void RTC_WKUP_IRQHandler(void) {handle_interrupt(RTC_WKUP_IRQn);} +void FLASH_IRQHandler(void) {handle_interrupt(FLASH_IRQn);} +void RCC_IRQHandler(void) {handle_interrupt(RCC_IRQn);} +void EXTI0_IRQHandler(void) {handle_interrupt(EXTI0_IRQn);} +void EXTI1_IRQHandler(void) {handle_interrupt(EXTI1_IRQn);} +void EXTI2_IRQHandler(void) {handle_interrupt(EXTI2_IRQn);} +void EXTI3_IRQHandler(void) {handle_interrupt(EXTI3_IRQn);} +void EXTI4_IRQHandler(void) {handle_interrupt(EXTI4_IRQn);} +void DMA1_Stream0_IRQHandler(void) {handle_interrupt(DMA1_Stream0_IRQn);} +void DMA1_Stream1_IRQHandler(void) {handle_interrupt(DMA1_Stream1_IRQn);} +void DMA1_Stream2_IRQHandler(void) {handle_interrupt(DMA1_Stream2_IRQn);} +void DMA1_Stream3_IRQHandler(void) {handle_interrupt(DMA1_Stream3_IRQn);} +void DMA1_Stream4_IRQHandler(void) {handle_interrupt(DMA1_Stream4_IRQn);} +void DMA1_Stream5_IRQHandler(void) {handle_interrupt(DMA1_Stream5_IRQn);} +void DMA1_Stream6_IRQHandler(void) {handle_interrupt(DMA1_Stream6_IRQn);} +void ADC_IRQHandler(void) {handle_interrupt(ADC_IRQn);} +void CAN1_TX_IRQHandler(void) {handle_interrupt(CAN1_TX_IRQn);} +void CAN1_RX0_IRQHandler(void) {handle_interrupt(CAN1_RX0_IRQn);} +void CAN1_RX1_IRQHandler(void) {handle_interrupt(CAN1_RX1_IRQn);} +void CAN1_SCE_IRQHandler(void) {handle_interrupt(CAN1_SCE_IRQn);} +void EXTI9_5_IRQHandler(void) {handle_interrupt(EXTI9_5_IRQn);} +void TIM1_BRK_TIM9_IRQHandler(void) {handle_interrupt(TIM1_BRK_TIM9_IRQn);} +void TIM1_UP_TIM10_IRQHandler(void) {handle_interrupt(TIM1_UP_TIM10_IRQn);} +void TIM1_TRG_COM_TIM11_IRQHandler(void) {handle_interrupt(TIM1_TRG_COM_TIM11_IRQn);} +void TIM1_CC_IRQHandler(void) {handle_interrupt(TIM1_CC_IRQn);} +void TIM2_IRQHandler(void) {handle_interrupt(TIM2_IRQn);} +void TIM3_IRQHandler(void) {handle_interrupt(TIM3_IRQn);} +void TIM4_IRQHandler(void) {handle_interrupt(TIM4_IRQn);} +void I2C1_EV_IRQHandler(void) {handle_interrupt(I2C1_EV_IRQn);} +void I2C1_ER_IRQHandler(void) {handle_interrupt(I2C1_ER_IRQn);} +void I2C2_EV_IRQHandler(void) {handle_interrupt(I2C2_EV_IRQn);} +void I2C2_ER_IRQHandler(void) {handle_interrupt(I2C2_ER_IRQn);} +void SPI1_IRQHandler(void) {handle_interrupt(SPI1_IRQn);} +void SPI2_IRQHandler(void) {handle_interrupt(SPI2_IRQn);} +void USART1_IRQHandler(void) {handle_interrupt(USART1_IRQn);} +void USART2_IRQHandler(void) {handle_interrupt(USART2_IRQn);} +void USART3_IRQHandler(void) {handle_interrupt(USART3_IRQn);} +void EXTI15_10_IRQHandler(void) {handle_interrupt(EXTI15_10_IRQn);} +void RTC_Alarm_IRQHandler(void) {handle_interrupt(RTC_Alarm_IRQn);} +void OTG_FS_WKUP_IRQHandler(void) {handle_interrupt(OTG_FS_WKUP_IRQn);} +void TIM8_BRK_TIM12_IRQHandler(void) {handle_interrupt(TIM8_BRK_TIM12_IRQn);} +void TIM8_UP_TIM13_IRQHandler(void) {handle_interrupt(TIM8_UP_TIM13_IRQn);} +void TIM8_TRG_COM_TIM14_IRQHandler(void) {handle_interrupt(TIM8_TRG_COM_TIM14_IRQn);} +void TIM8_CC_IRQHandler(void) {handle_interrupt(TIM8_CC_IRQn);} +void DMA1_Stream7_IRQHandler(void) {handle_interrupt(DMA1_Stream7_IRQn);} +void FSMC_IRQHandler(void) {handle_interrupt(FSMC_IRQn);} +void SDIO_IRQHandler(void) {handle_interrupt(SDIO_IRQn);} +void TIM5_IRQHandler(void) {handle_interrupt(TIM5_IRQn);} +void SPI3_IRQHandler(void) {handle_interrupt(SPI3_IRQn);} +void UART4_IRQHandler(void) {handle_interrupt(UART4_IRQn);} +void UART5_IRQHandler(void) {handle_interrupt(UART5_IRQn);} +void TIM6_DAC_IRQHandler(void) {handle_interrupt(TIM6_DAC_IRQn);} +void TIM7_IRQHandler(void) {handle_interrupt(TIM7_IRQn);} +void DMA2_Stream0_IRQHandler(void) {handle_interrupt(DMA2_Stream0_IRQn);} +void DMA2_Stream1_IRQHandler(void) {handle_interrupt(DMA2_Stream1_IRQn);} +void DMA2_Stream2_IRQHandler(void) {handle_interrupt(DMA2_Stream2_IRQn);} +void DMA2_Stream3_IRQHandler(void) {handle_interrupt(DMA2_Stream3_IRQn);} +void DMA2_Stream4_IRQHandler(void) {handle_interrupt(DMA2_Stream4_IRQn);} +void CAN2_TX_IRQHandler(void) {handle_interrupt(CAN2_TX_IRQn);} +void CAN2_RX0_IRQHandler(void) {handle_interrupt(CAN2_RX0_IRQn);} +void CAN2_RX1_IRQHandler(void) {handle_interrupt(CAN2_RX1_IRQn);} +void CAN2_SCE_IRQHandler(void) {handle_interrupt(CAN2_SCE_IRQn);} +void OTG_FS_IRQHandler(void) {handle_interrupt(OTG_FS_IRQn);} +void DMA2_Stream5_IRQHandler(void) {handle_interrupt(DMA2_Stream5_IRQn);} +void DMA2_Stream6_IRQHandler(void) {handle_interrupt(DMA2_Stream6_IRQn);} +void DMA2_Stream7_IRQHandler(void) {handle_interrupt(DMA2_Stream7_IRQn);} +void USART6_IRQHandler(void) {handle_interrupt(USART6_IRQn);} +void I2C3_EV_IRQHandler(void) {handle_interrupt(I2C3_EV_IRQn);} +void I2C3_ER_IRQHandler(void) {handle_interrupt(I2C3_ER_IRQn);} +#ifdef STM32F4 + void DFSDM1_FLT0_IRQHandler(void) {handle_interrupt(DFSDM1_FLT0_IRQn);} + void DFSDM1_FLT1_IRQHandler(void) {handle_interrupt(DFSDM1_FLT1_IRQn);} + void CAN3_TX_IRQHandler(void) {handle_interrupt(CAN3_TX_IRQn);} + void CAN3_RX0_IRQHandler(void) {handle_interrupt(CAN3_RX0_IRQn);} + void CAN3_RX1_IRQHandler(void) {handle_interrupt(CAN3_RX1_IRQn);} + void CAN3_SCE_IRQHandler(void) {handle_interrupt(CAN3_SCE_IRQn);} + void RNG_IRQHandler(void) {handle_interrupt(RNG_IRQn);} + void FPU_IRQHandler(void) {handle_interrupt(FPU_IRQn);} + void UART7_IRQHandler(void) {handle_interrupt(UART7_IRQn);} + void UART8_IRQHandler(void) {handle_interrupt(UART8_IRQn);} + void SPI4_IRQHandler(void) {handle_interrupt(SPI4_IRQn);} + void SPI5_IRQHandler(void) {handle_interrupt(SPI5_IRQn);} + void SAI1_IRQHandler(void) {handle_interrupt(SAI1_IRQn);} + void UART9_IRQHandler(void) {handle_interrupt(UART9_IRQn);} + void UART10_IRQHandler(void) {handle_interrupt(UART10_IRQn);} + void QUADSPI_IRQHandler(void) {handle_interrupt(QUADSPI_IRQn);} + void FMPI2C1_EV_IRQHandler(void) {handle_interrupt(FMPI2C1_EV_IRQn);} + void FMPI2C1_ER_IRQHandler(void) {handle_interrupt(FMPI2C1_ER_IRQn);} + void LPTIM1_IRQHandler(void) {handle_interrupt(LPTIM1_IRQn);} + void DFSDM2_FLT0_IRQHandler(void) {handle_interrupt(DFSDM2_FLT0_IRQn);} + void DFSDM2_FLT1_IRQHandler(void) {handle_interrupt(DFSDM2_FLT1_IRQn);} + void DFSDM2_FLT2_IRQHandler(void) {handle_interrupt(DFSDM2_FLT2_IRQn);} + void DFSDM2_FLT3_IRQHandler(void) {handle_interrupt(DFSDM2_FLT3_IRQn);} +#endif \ No newline at end of file diff --git a/board/drivers/spi.h b/board/drivers/spi.h index 26690984de7bb8..86e795805a2d4c 100644 --- a/board/drivers/spi.h +++ b/board/drivers/spi.h @@ -10,29 +10,6 @@ uint8_t spi_buf[SPI_BUF_SIZE]; int spi_buf_count = 0; int spi_total_count = 0; -void spi_init(void) { - //puts("SPI init\n"); - SPI1->CR1 = SPI_CR1_SPE; - - // enable SPI interrupts - //SPI1->CR2 = SPI_CR2_RXNEIE | SPI_CR2_ERRIE | SPI_CR2_TXEIE; - SPI1->CR2 = SPI_CR2_RXNEIE; - - NVIC_EnableIRQ(DMA2_Stream2_IRQn); - NVIC_EnableIRQ(DMA2_Stream3_IRQn); - //NVIC_EnableIRQ(SPI1_IRQn); - - // reset handshake back to pull up - set_gpio_mode(GPIOB, 0, MODE_INPUT); - set_gpio_pullup(GPIOB, 0, PULL_UP); - - // setup interrupt on falling edge of SPI enable (on PA4) - SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA; - EXTI->IMR |= (1U << 4); - EXTI->FTSR |= (1U << 4); - NVIC_EnableIRQ(EXTI4_IRQn); -} - void spi_tx_dma(void *addr, int len) { // disable DMA SPI1->CR2 &= ~SPI_CR2_TXDMAEN; @@ -78,12 +55,11 @@ void spi_rx_dma(void *addr, int len) { } // ***************************** SPI IRQs ***************************** - // can't go on the stack cause it's DMAed uint8_t spi_tx_buf[0x44]; // SPI RX -void DMA2_Stream2_IRQHandler(void) { +void DMA2_Stream2_IRQ_Handler(void) { int *resp_len = (int*)spi_tx_buf; (void)memset(spi_tx_buf, 0xaa, 0x44); *resp_len = spi_cb_rx(spi_buf, 0x14, spi_tx_buf+4); @@ -99,7 +75,7 @@ void DMA2_Stream2_IRQHandler(void) { } // SPI TX -void DMA2_Stream3_IRQHandler(void) { +void DMA2_Stream3_IRQ_Handler(void) { #ifdef DEBUG_SPI puts("SPI handshake\n"); #endif @@ -112,7 +88,7 @@ void DMA2_Stream3_IRQHandler(void) { DMA2->LIFCR = DMA_LIFCR_CTCIF3; } -void EXTI4_IRQHandler(void) { +void EXTI4_IRQ_Handler(void) { volatile unsigned int pr = EXTI->PR & (1U << 4); #ifdef DEBUG_SPI puts("exti4\n"); @@ -125,3 +101,31 @@ void EXTI4_IRQHandler(void) { EXTI->PR = pr; } +// ***************************** SPI init ***************************** +void spi_init(void) { + // Max SPI clock the ESP can produce is 80MHz. At buffer size of 256 bytes, that's a max of about 40k buffers per second + REGISTER_INTERRUPT(DMA2_Stream2_IRQn, DMA2_Stream2_IRQ_Handler, 50000U, FAULT_INTERRUPT_RATE_SPI_DMA) + REGISTER_INTERRUPT(DMA2_Stream3_IRQn, DMA2_Stream3_IRQ_Handler, 50000U, FAULT_INTERRUPT_RATE_SPI_DMA) + REGISTER_INTERRUPT(EXTI4_IRQn, EXTI4_IRQ_Handler, 50000U, FAULT_INTERRUPT_RATE_SPI_CS) // TODO: Figure out if this is a reasonable limit + + //puts("SPI init\n"); + SPI1->CR1 = SPI_CR1_SPE; + + // enable SPI interrupts + //SPI1->CR2 = SPI_CR2_RXNEIE | SPI_CR2_ERRIE | SPI_CR2_TXEIE; + SPI1->CR2 = SPI_CR2_RXNEIE; + + NVIC_EnableIRQ(DMA2_Stream2_IRQn); + NVIC_EnableIRQ(DMA2_Stream3_IRQn); + //NVIC_EnableIRQ(SPI1_IRQn); + + // reset handshake back to pull up + set_gpio_mode(GPIOB, 0, MODE_INPUT); + set_gpio_pullup(GPIOB, 0, PULL_UP); + + // setup interrupt on falling edge of SPI enable (on PA4) + SYSCFG->EXTICR[2] = SYSCFG_EXTICR2_EXTI4_PA; + EXTI->IMR |= (1U << 4); + EXTI->FTSR |= (1U << 4); + NVIC_EnableIRQ(EXTI4_IRQn); +} \ No newline at end of file diff --git a/board/drivers/uart.h b/board/drivers/uart.h index 3a095f67261d8e..da45803001f84f 100644 --- a/board/drivers/uart.h +++ b/board/drivers/uart.h @@ -197,12 +197,12 @@ void uart_interrupt_handler(uart_ring *q) { EXIT_CRITICAL(); } -void USART1_IRQHandler(void) { uart_interrupt_handler(&uart_ring_esp_gps); } -void USART2_IRQHandler(void) { uart_interrupt_handler(&uart_ring_debug); } -void USART3_IRQHandler(void) { uart_interrupt_handler(&uart_ring_lin2); } -void UART5_IRQHandler(void) { uart_interrupt_handler(&uart_ring_lin1); } +void USART1_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_esp_gps); } +void USART2_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_debug); } +void USART3_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin2); } +void UART5_IRQ_Handler(void) { uart_interrupt_handler(&uart_ring_lin1); } -void DMA2_Stream5_IRQHandler(void) { +void DMA2_Stream5_IRQ_Handler(void) { ENTER_CRITICAL(); // Handle errors @@ -272,6 +272,13 @@ void uart_set_baud(USART_TypeDef *u, unsigned int baud) { } void uart_init(uart_ring *q, int baud) { + // Register interrupts (max data rate: 115200 baud) + REGISTER_INTERRUPT(USART1_IRQn, USART1_IRQ_Handler, 150000U, FAULT_INTERRUPT_RATE_UART_1) + REGISTER_INTERRUPT(USART2_IRQn, USART2_IRQ_Handler, 150000U, FAULT_INTERRUPT_RATE_UART_2) + REGISTER_INTERRUPT(USART3_IRQn, USART3_IRQ_Handler, 150000U, FAULT_INTERRUPT_RATE_UART_3) + REGISTER_INTERRUPT(UART5_IRQn, UART5_IRQ_Handler, 150000U, FAULT_INTERRUPT_RATE_UART_5) + REGISTER_INTERRUPT(DMA2_Stream5_IRQn, DMA2_Stream5_IRQ_Handler, 100U, FAULT_INTERRUPT_RATE_UART_DMA) // Called twice per buffer + // Set baud and enable peripheral with TX and RX mode uart_set_baud(q->uart, baud); q->uart->CR1 = USART_CR1_UE | USART_CR1_TE | USART_CR1_RE; diff --git a/board/drivers/usb.h b/board/drivers/usb.h index 72d1b9c6f90909..a970194ffd284e 100644 --- a/board/drivers/usb.h +++ b/board/drivers/usb.h @@ -660,76 +660,7 @@ void usb_setup(void) { } } -void usb_init(void) { - // full speed PHY, do reset and remove power down - /*puth(USBx->GRSTCTL); - puts(" resetting PHY\n");*/ - while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); - //puts("AHB idle\n"); - - // reset PHY here - USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; - while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); - //puts("reset done\n"); - - // internal PHY, force device mode - USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_FDMOD; - - // slowest timings - USBx->GUSBCFG |= ((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); - - // power up the PHY -#ifdef STM32F4 - USBx->GCCFG = USB_OTG_GCCFG_PWRDWN; - - //USBx->GCCFG |= USB_OTG_GCCFG_VBDEN | USB_OTG_GCCFG_SDEN |USB_OTG_GCCFG_PDEN | USB_OTG_GCCFG_DCDEN; - - /* B-peripheral session valid override enable*/ - USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; - USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; -#else - USBx->GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS; -#endif - - // be a device, slowest timings - //USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL; - //USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); - //USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL; - // **** for debugging, doesn't seem to work **** - //USBx->GUSBCFG |= USB_OTG_GUSBCFG_CTXPKT; - - // reset PHY clock - USBx_PCGCCTL = 0; - - // enable the fancy OTG things - // DCFG_FRAME_INTERVAL_80 is 0 - //USBx->GUSBCFG |= USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP; - USBx_DEVICE->DCFG |= USB_OTG_SPEED_FULL | USB_OTG_DCFG_NZLSOHSK; - - //USBx_DEVICE->DCFG = USB_OTG_DCFG_NZLSOHSK | USB_OTG_DCFG_DSPD; - //USBx_DEVICE->DCFG = USB_OTG_DCFG_DSPD; - - // clear pending interrupts - USBx->GINTSTS = 0xBFFFFFFFU; - - // setup USB interrupts - // all interrupts except TXFIFO EMPTY - //USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF); - //USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM); - USBx->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_OTGINT | - USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_GONAKEFFM | USB_OTG_GINTMSK_GINAKEFFM | - USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_USBSUSPM | - USB_OTG_GINTMSK_CIDSCHGM | USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_MMISM; - - USBx->GAHBCFG = USB_OTG_GAHBCFG_GINT; - - // DCTL startup value is 2 on new chip, 0 on old chip - USBx_DEVICE->DCTL = 0; - - // enable the IRQ - NVIC_EnableIRQ(OTG_FS_IRQn); -} // ***************************** USB port ***************************** @@ -1001,7 +932,7 @@ void usb_irqhandler(void) { //USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF); } -void OTG_FS_IRQHandler(void) { +void OTG_FS_IRQ_Handler(void) { NVIC_DisableIRQ(OTG_FS_IRQn); //__disable_irq(); usb_irqhandler(); @@ -1009,3 +940,77 @@ void OTG_FS_IRQHandler(void) { NVIC_EnableIRQ(OTG_FS_IRQn); } +// ***************************** USB init ***************************** + +void usb_init(void) { + REGISTER_INTERRUPT(OTG_FS_IRQn, OTG_FS_IRQ_Handler, 1500000U, FAULT_INTERRUPT_RATE_USB) //TODO: Find out a better rate limit for USB. Now it's the 1.5MB/s rate + + // full speed PHY, do reset and remove power down + /*puth(USBx->GRSTCTL); + puts(" resetting PHY\n");*/ + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0); + //puts("AHB idle\n"); + + // reset PHY here + USBx->GRSTCTL |= USB_OTG_GRSTCTL_CSRST; + while ((USBx->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST); + //puts("reset done\n"); + + // internal PHY, force device mode + USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_FDMOD; + + // slowest timings + USBx->GUSBCFG |= ((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); + + // power up the PHY +#ifdef STM32F4 + USBx->GCCFG = USB_OTG_GCCFG_PWRDWN; + + //USBx->GCCFG |= USB_OTG_GCCFG_VBDEN | USB_OTG_GCCFG_SDEN |USB_OTG_GCCFG_PDEN | USB_OTG_GCCFG_DCDEN; + + /* B-peripheral session valid override enable*/ + USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOVAL; + USBx->GOTGCTL |= USB_OTG_GOTGCTL_BVALOEN; +#else + USBx->GCCFG = USB_OTG_GCCFG_PWRDWN | USB_OTG_GCCFG_NOVBUSSENS; +#endif + + // be a device, slowest timings + //USBx->GUSBCFG = USB_OTG_GUSBCFG_FDMOD | USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL; + //USBx->GUSBCFG |= (uint32_t)((USBD_FS_TRDT_VALUE << 10) & USB_OTG_GUSBCFG_TRDT); + //USBx->GUSBCFG = USB_OTG_GUSBCFG_PHYSEL | USB_OTG_GUSBCFG_TRDT | USB_OTG_GUSBCFG_TOCAL; + + // **** for debugging, doesn't seem to work **** + //USBx->GUSBCFG |= USB_OTG_GUSBCFG_CTXPKT; + + // reset PHY clock + USBx_PCGCCTL = 0; + + // enable the fancy OTG things + // DCFG_FRAME_INTERVAL_80 is 0 + //USBx->GUSBCFG |= USB_OTG_GUSBCFG_HNPCAP | USB_OTG_GUSBCFG_SRPCAP; + USBx_DEVICE->DCFG |= USB_OTG_SPEED_FULL | USB_OTG_DCFG_NZLSOHSK; + + //USBx_DEVICE->DCFG = USB_OTG_DCFG_NZLSOHSK | USB_OTG_DCFG_DSPD; + //USBx_DEVICE->DCFG = USB_OTG_DCFG_DSPD; + + // clear pending interrupts + USBx->GINTSTS = 0xBFFFFFFFU; + + // setup USB interrupts + // all interrupts except TXFIFO EMPTY + //USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM | USB_OTG_GINTSTS_SOF | USB_OTG_GINTSTS_EOPF); + //USBx->GINTMSK = 0xFFFFFFFF & ~(USB_OTG_GINTMSK_NPTXFEM | USB_OTG_GINTMSK_PTXFEM); + USBx->GINTMSK = USB_OTG_GINTMSK_USBRST | USB_OTG_GINTMSK_ENUMDNEM | USB_OTG_GINTMSK_OTGINT | + USB_OTG_GINTMSK_RXFLVLM | USB_OTG_GINTMSK_GONAKEFFM | USB_OTG_GINTMSK_GINAKEFFM | + USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT | USB_OTG_GINTMSK_USBSUSPM | + USB_OTG_GINTMSK_CIDSCHGM | USB_OTG_GINTMSK_SRQIM | USB_OTG_GINTMSK_MMISM; + + USBx->GAHBCFG = USB_OTG_GAHBCFG_GINT; + + // DCTL startup value is 2 on new chip, 0 on old chip + USBx_DEVICE->DCTL = 0; + + // enable the IRQ + NVIC_EnableIRQ(OTG_FS_IRQn); +} \ No newline at end of file diff --git a/board/faults.h b/board/faults.h new file mode 100644 index 00000000000000..9acba95f85214c --- /dev/null +++ b/board/faults.h @@ -0,0 +1,48 @@ +#define FAULT_STATUS_NONE 0U +#define FAULT_STATUS_TEMPORARY 1U +#define FAULT_STATUS_PERMANENT 2U + +// Fault types +#define FAULT_RELAY_MALFUNCTION (1U << 0) +#define FAULT_UNUSED_INTERRUPT_HANDLED (1U << 1) +#define FAULT_INTERRUPT_RATE_CAN_1 (1U << 2) +#define FAULT_INTERRUPT_RATE_CAN_2 (1U << 3) +#define FAULT_INTERRUPT_RATE_CAN_3 (1U << 4) +#define FAULT_INTERRUPT_RATE_TACH (1U << 5) +#define FAULT_INTERRUPT_RATE_GMLAN (1U << 6) +#define FAULT_INTERRUPT_RATE_INTERRUPTS (1U << 7) +#define FAULT_INTERRUPT_RATE_SPI_DMA (1U << 8) +#define FAULT_INTERRUPT_RATE_SPI_CS (1U << 9) +#define FAULT_INTERRUPT_RATE_UART_1 (1U << 10) +#define FAULT_INTERRUPT_RATE_UART_2 (1U << 11) +#define FAULT_INTERRUPT_RATE_UART_3 (1U << 12) +#define FAULT_INTERRUPT_RATE_UART_5 (1U << 13) +#define FAULT_INTERRUPT_RATE_UART_DMA (1U << 14) +#define FAULT_INTERRUPT_RATE_USB (1U << 15) +#define FAULT_INTERRUPT_RATE_TIM1 (1U << 16) +#define FAULT_INTERRUPT_RATE_TIM3 (1U << 17) + +// Permanent faults +#define PERMANENT_FAULTS 0U + +uint8_t fault_status = FAULT_STATUS_NONE; +uint32_t faults = 0U; + +void fault_occurred(uint32_t fault) { + faults |= fault; + if((PERMANENT_FAULTS & fault) != 0U){ + puts("Permanent fault occurred: 0x"); puth(fault); puts("\n"); + fault_status = FAULT_STATUS_PERMANENT; + } else { + puts("Temporary fault occurred: 0x"); puth(fault); puts("\n"); + fault_status = FAULT_STATUS_TEMPORARY; + } +} + +void fault_recovered(uint32_t fault) { + if((PERMANENT_FAULTS & fault) == 0U){ + faults &= ~fault; + } else { + puts("Cannot recover from a permanent fault!\n"); + } +} \ No newline at end of file diff --git a/board/inc/stm32f413xx.h b/board/inc/stm32f413xx.h index 0fd9f4c387d405..0962a8def1a3a6 100644 --- a/board/inc/stm32f413xx.h +++ b/board/inc/stm32f413xx.h @@ -141,6 +141,7 @@ typedef enum TIM8_TRG_COM_TIM14_IRQn = 45, /*!< TIM8 Trigger and Commutation Interrupt and TIM14 global interrupt */ TIM8_CC_IRQn = 46, /*!< TIM8 Capture Compare global interrupt */ DMA1_Stream7_IRQn = 47, /*!< DMA1 Stream7 Interrupt */ + FSMC_IRQn = 48, /*!< FSMC global Interrupt */ SDIO_IRQn = 49, /*!< SDIO global Interrupt */ TIM5_IRQn = 50, /*!< TIM5 global Interrupt */ SPI3_IRQn = 51, /*!< SPI3 global Interrupt */ diff --git a/board/libc.h b/board/libc.h index f8d9dbce2acdda..67411fbb313391 100644 --- a/board/libc.h +++ b/board/libc.h @@ -40,28 +40,3 @@ int memcmp(const void * ptr1, const void * ptr2, unsigned int num) { return ret; } -// ********************* IRQ helpers ********************* - -volatile bool interrupts_enabled = false; - -void enable_interrupts(void) { - interrupts_enabled = true; - __enable_irq(); -} - -void disable_interrupts(void) { - interrupts_enabled = false; - __disable_irq(); -} - -uint8_t global_critical_depth = 0U; -#define ENTER_CRITICAL() \ - __disable_irq(); \ - global_critical_depth += 1U; - -#define EXIT_CRITICAL() \ - global_critical_depth -= 1U; \ - if ((global_critical_depth == 0U) && interrupts_enabled) { \ - __enable_irq(); \ - } - diff --git a/board/main.c b/board/main.c index 23aeb2d864dbd7..aa011c3714e212 100644 --- a/board/main.c +++ b/board/main.c @@ -5,10 +5,13 @@ #include "config.h" #include "obj/gitversion.h" +#include "main_declarations.h" + #include "libc.h" #include "provision.h" +#include "faults.h" -#include "main_declarations.h" +#include "drivers/interrupts.h" #include "drivers/llcan.h" #include "drivers/llgpio.h" @@ -164,8 +167,8 @@ int get_health_pkt(void *dat) { health->safety_mode_pkt = (uint8_t)(current_safety_mode); health->power_save_enabled_pkt = (uint8_t)(power_save_status == POWER_SAVE_STATUS_ENABLED); - health->fault_status_pkt = 0U; // TODO: populate this field - health->faults_pkt = 0U; // TODO: populate this field + health->fault_status_pkt = fault_status; + health->faults_pkt = faults; return sizeof(*health); } @@ -640,8 +643,7 @@ void __attribute__ ((noinline)) enable_fpu(void) { #define EON_HEARTBEAT_IGNITION_CNT_OFF 2U // called once per second -// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck -void TIM1_BRK_TIM9_IRQHandler(void) { +void TIM1_BRK_TIM9_IRQ_Handler(void) { if (TIM9->SR != 0) { can_live = pending_can_live; @@ -705,6 +707,10 @@ void TIM1_BRK_TIM9_IRQHandler(void) { } int main(void) { + init_interrupts(true); + // 1s timer + REGISTER_INTERRUPT(TIM1_BRK_TIM9_IRQn, TIM1_BRK_TIM9_IRQ_Handler, 2U, FAULT_INTERRUPT_RATE_TIM1) + // shouldn't have interrupts here, but just in case disable_interrupts(); @@ -793,19 +799,30 @@ int main(void) { for (cnt=0;;cnt++) { if (power_save_status == POWER_SAVE_STATUS_DISABLED) { - int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1); - - // useful for debugging, fade breaks = panda is overloaded - for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) { - for (int fade = 0; fade < 1024; fade += 8) { - for (int i = 0; i < (128/div_mode); i++) { - current_board->set_led(LED_RED, 1); - if (fade < 512) { delay(fade); } else { delay(1024-fade); } - current_board->set_led(LED_RED, 0); - if (fade < 512) { delay(512-fade); } else { delay(fade-512); } + #ifdef DEBUG_FAULTS + if(fault_status == FAULT_STATUS_NONE){ + #endif + int div_mode = ((usb_power_mode == USB_POWER_DCP) ? 4 : 1); + + // useful for debugging, fade breaks = panda is overloaded + for (int div_mode_loop = 0; div_mode_loop < div_mode; div_mode_loop++) { + for (int fade = 0; fade < 1024; fade += 8) { + for (int i = 0; i < (128/div_mode); i++) { + current_board->set_led(LED_RED, 1); + if (fade < 512) { delay(fade); } else { delay(1024-fade); } + current_board->set_led(LED_RED, 0); + if (fade < 512) { delay(512-fade); } else { delay(fade-512); } + } } } - } + #ifdef DEBUG_FAULTS + } else { + current_board->set_led(LED_RED, 1); + delay(512000U); + current_board->set_led(LED_RED, 0); + delay(512000U); + } + #endif } else { __WFI(); } diff --git a/board/pedal/main.c b/board/pedal/main.c index e7642f0c005635..13becced96957a 100644 --- a/board/pedal/main.c +++ b/board/pedal/main.c @@ -3,7 +3,9 @@ #include "libc.h" #include "main_declarations.h" +#include "faults.h" +#include "drivers/interrupts.h" #include "drivers/llcan.h" #include "drivers/llgpio.h" #include "drivers/adc.h" @@ -129,8 +131,7 @@ uint8_t pedal_checksum(uint8_t *dat, int len) { #define CAN_GAS_SIZE 6 #define COUNTER_CYCLE 0xFU -// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck -void CAN1_TX_IRQHandler(void) { +void CAN1_TX_IRQ_Handler(void) { // clear interrupt CAN->TSR |= CAN_TSR_RQCP0; } @@ -152,8 +153,7 @@ uint32_t current_index = 0; #define FAULT_INVALID 6U uint8_t state = FAULT_STARTUP; -// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck -void CAN1_RX0_IRQHandler(void) { +void CAN1_RX0_IRQ_Handler(void) { while ((CAN->RF0R & CAN_RF0R_FMP0) != 0) { #ifdef DEBUG puts("CAN RX\n"); @@ -216,8 +216,7 @@ void CAN1_RX0_IRQHandler(void) { } } -// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck -void CAN1_SCE_IRQHandler(void) { +void CAN1_SCE_IRQ_Handler(void) { state = FAULT_SCE; llcan_clear_send(CAN); } @@ -228,8 +227,7 @@ unsigned int pkt_idx = 0; int led_value = 0; -// cppcheck-suppress unusedFunction ; used in headers not included in cppcheck -void TIM3_IRQHandler(void) { +void TIM3_IRQ_Handler(void) { #ifdef DEBUG puth(TIM3->CNT); puts(" "); @@ -296,6 +294,14 @@ void pedal(void) { } int main(void) { + init_interrupts(true); + REGISTER_INTERRUPT(CAN1_TX_IRQn, CAN1_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN1_RX0_IRQn, CAN1_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN1_SCE_IRQn, CAN1_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + + // Should run at around 732Hz (see init below) + REGISTER_INTERRUPT(TIM3_IRQn, TIM3_IRQ_Handler, 1000U, FAULT_INTERRUPT_RATE_TIM3) + disable_interrupts(); // init devices diff --git a/board/spi_flasher.h b/board/spi_flasher.h index b1bba71d4623c4..3fe15961c8cf9f 100644 --- a/board/spi_flasher.h +++ b/board/spi_flasher.h @@ -151,7 +151,7 @@ int spi_cb_rx(uint8_t *data, int len, uint8_t *data_out) { #define CAN_BL_INPUT 0x1 #define CAN_BL_OUTPUT 0x2 -void CAN1_TX_IRQHandler(void) { +void CAN1_TX_IRQ_Handler(void) { // clear interrupt CAN->TSR |= CAN_TSR_RQCP0; } @@ -178,7 +178,7 @@ void bl_can_send(uint8_t *odat) { CAN->sTxMailBox[0].TIR = (CAN_BL_OUTPUT << 21) | 1; } -void CAN1_RX0_IRQHandler(void) { +void CAN1_RX0_IRQ_Handler(void) { while (CAN->RF0R & CAN_RF0R_FMP0) { if ((CAN->sFIFOMailBox[0].RIR>>21) == CAN_BL_INPUT) { uint8_t dat[8]; @@ -253,13 +253,19 @@ void CAN1_RX0_IRQHandler(void) { } } -void CAN1_SCE_IRQHandler(void) { +void CAN1_SCE_IRQ_Handler(void) { llcan_clear_send(CAN); } #endif void soft_flasher_start(void) { + #ifdef PEDAL + REGISTER_INTERRUPT(CAN1_TX_IRQn, CAN1_TX_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN1_RX0_IRQn, CAN1_RX0_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + REGISTER_INTERRUPT(CAN1_SCE_IRQn, CAN1_SCE_IRQ_Handler, CAN_INTERRUPT_RATE, FAULT_INTERRUPT_RATE_CAN_1) + #endif + puts("\n\n\n************************ FLASHER START ************************\n"); enter_bootloader_mode = 0; diff --git a/tests/misra/.gitignore b/tests/misra/.gitignore new file mode 100644 index 00000000000000..fa3aeaa30613ce --- /dev/null +++ b/tests/misra/.gitignore @@ -0,0 +1 @@ +cppcheck/