You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
			
				
					164 lines
				
				8.5 KiB
			
		
		
			
		
	
	
					164 lines
				
				8.5 KiB
			| 
								 
											6 years ago
										 
									 | 
							
								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
							 | 
						||
| 
								 | 
							
								  register_set_bits(&(RCC->APB1ENR), RCC_APB1ENR_TIM6EN);  // Enable interrupt timer peripheral
							 | 
						||
| 
								 | 
							
								  REGISTER_INTERRUPT(TIM6_DAC_IRQn, TIM6_DAC_IRQ_Handler, 1, FAULT_INTERRUPT_RATE_INTERRUPTS)
							 | 
						||
| 
								 | 
							
								  register_set(&(TIM6->PSC), (732-1), 0xFFFFU);
							 | 
						||
| 
								 | 
							
								  register_set(&(TIM6->DIER), TIM_DIER_UIE, 0x5F5FU);
							 | 
						||
| 
								 | 
							
								  register_set(&(TIM6->CR1), TIM_CR1_CEN, 0x3FU);
							 | 
						||
| 
								 | 
							
								  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
							 |