-
Notifications
You must be signed in to change notification settings - Fork 9.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
- Loading branch information
1 parent
000282e
commit 656f99b
Showing
17 changed files
with
473 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; i<NUM_INTERRUPTS; i++){ | ||
interrupts[i].call_counter = 0U; | ||
} | ||
} | ||
TIM6->SR = 0; | ||
} | ||
|
||
void init_interrupts(bool check_rate_limit){ | ||
check_interrupt_rate = check_rate_limit; | ||
|
||
for(uint16_t i=0U; i<NUM_INTERRUPTS; i++){ | ||
interrupts[i].handler = unused_interrupt_handler; | ||
} | ||
|
||
// Init timer 10 for a 1s interval | ||
RCC->APB1ENR |= 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 |
Oops, something went wrong.