|
|
|
/* USER CODE BEGIN Header */
|
|
|
|
/**
|
|
|
|
******************************************************************************
|
|
|
|
* @file stm32f1xx_it.c
|
|
|
|
* @brief Interrupt Service Routines.
|
|
|
|
******************************************************************************
|
|
|
|
* @attention
|
|
|
|
*
|
|
|
|
* Copyright (c) 2023 STMicroelectronics.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This software is licensed under terms that can be found in the LICENSE file
|
|
|
|
* in the root directory of this software component.
|
|
|
|
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
|
|
*
|
|
|
|
******************************************************************************
|
|
|
|
*/
|
|
|
|
/* USER CODE END Header */
|
|
|
|
|
|
|
|
/* Includes ------------------------------------------------------------------*/
|
|
|
|
#include "main.h"
|
|
|
|
#include "stm32f1xx_it.h"
|
|
|
|
#include "FreeRTOS.h"
|
|
|
|
#include "task.h"
|
|
|
|
/* Private includes ----------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN Includes */
|
|
|
|
#include "app_temp.h"
|
|
|
|
#include "app_knob.h"
|
|
|
|
#include "app_heater.h"
|
|
|
|
#include <inttypes.h>
|
|
|
|
/* USER CODE END Includes */
|
|
|
|
|
|
|
|
/* Private typedef -----------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN TD */
|
|
|
|
|
|
|
|
/* USER CODE END TD */
|
|
|
|
|
|
|
|
/* Private define ------------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PD */
|
|
|
|
|
|
|
|
/* USER CODE END PD */
|
|
|
|
|
|
|
|
/* Private macro -------------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PM */
|
|
|
|
|
|
|
|
/* USER CODE END PM */
|
|
|
|
|
|
|
|
/* Private variables ---------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PV */
|
|
|
|
|
|
|
|
/* USER CODE END PV */
|
|
|
|
|
|
|
|
/* Private function prototypes -----------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN PFP */
|
|
|
|
|
|
|
|
/* USER CODE END PFP */
|
|
|
|
|
|
|
|
/* Private user code ---------------------------------------------------------*/
|
|
|
|
/* USER CODE BEGIN 0 */
|
|
|
|
|
|
|
|
/* USER CODE END 0 */
|
|
|
|
|
|
|
|
/* External variables --------------------------------------------------------*/
|
|
|
|
|
|
|
|
/* USER CODE BEGIN EV */
|
|
|
|
|
|
|
|
bool EE_NMI_Callback();
|
|
|
|
|
|
|
|
/* USER CODE END EV */
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* Cortex-M3 Processor Interruption and Exception Handlers */
|
|
|
|
/******************************************************************************/
|
|
|
|
/**
|
|
|
|
* @brief This function handles Non maskable interrupt.
|
|
|
|
*/
|
|
|
|
void NMI_Handler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
|
|
|
|
|
|
|
|
if (EE_NMI_Callback()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
app_emergency_stop();
|
|
|
|
|
|
|
|
/* USER CODE END NonMaskableInt_IRQn 0 */
|
|
|
|
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
|
|
|
|
while (1) {
|
|
|
|
}
|
|
|
|
/* USER CODE END NonMaskableInt_IRQn 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#define VERBOSE_HARDFAULT 1
|
|
|
|
|
|
|
|
|
|
|
|
#if VERBOSE_HARDFAULT
|
|
|
|
void __attribute__((used)) HardFault_DumpRegisters(const uint32_t *origStack, uint32_t lr_value)
|
|
|
|
{
|
|
|
|
/* These are volatile to try and prevent the compiler/linker optimising them
|
|
|
|
away as the variables never actually get used. If the debugger won't show the
|
|
|
|
values of the variables, make them global my moving their declaration outside
|
|
|
|
of this function. */
|
|
|
|
volatile uint32_t stacked_r0;
|
|
|
|
volatile uint32_t stacked_r1;
|
|
|
|
volatile uint32_t stacked_r2;
|
|
|
|
volatile uint32_t stacked_r3;
|
|
|
|
volatile uint32_t stacked_r12;
|
|
|
|
volatile uint32_t stacked_lr; /* Link register. */
|
|
|
|
volatile uint32_t stacked_pc; /* Program counter. */
|
|
|
|
volatile uint32_t stacked_psr;/* Program status register. */
|
|
|
|
|
|
|
|
#if (__CORTEX_M >= 3)
|
|
|
|
uint32_t cfsr, hfsr, dfsr;
|
|
|
|
|
|
|
|
uint32_t bus_fault_address;
|
|
|
|
uint32_t memmanage_fault_address;
|
|
|
|
|
|
|
|
bus_fault_address = SCB->BFAR;
|
|
|
|
memmanage_fault_address = SCB->MMFAR;
|
|
|
|
cfsr = SCB->CFSR;
|
|
|
|
hfsr = SCB->HFSR;
|
|
|
|
dfsr = SCB->DFSR;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
stacked_r0 = origStack[0];
|
|
|
|
stacked_r1 = origStack[1];
|
|
|
|
stacked_r2 = origStack[2];
|
|
|
|
stacked_r3 = origStack[3];
|
|
|
|
stacked_r12 = origStack[4];
|
|
|
|
stacked_lr = origStack[5];
|
|
|
|
stacked_pc = origStack[6];
|
|
|
|
stacked_psr = origStack[7];
|
|
|
|
|
|
|
|
app_heater_emergency_shutdown();
|
|
|
|
|
|
|
|
#define BS(reg, pos, str) (((reg)&(1<<(pos)))?(str" "):"")
|
|
|
|
#define REDPTR(val) (((val)&0xFF000000) != 0x08000000?"\033[31m":"\033[32m")
|
|
|
|
|
|
|
|
PRINTF("\r\n*** HARD FAULT ***\r\n\r\n");
|
|
|
|
PRINTF("- Stack frame:\r\n");
|
|
|
|
PRINTF(" R0 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r0);
|
|
|
|
PRINTF(" R1 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r1);
|
|
|
|
PRINTF(" R2 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r2);
|
|
|
|
PRINTF(" R3 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r3);
|
|
|
|
PRINTF(" R12 = \033[35m0x%"PRIX32"\033[m\r\n", stacked_r12);
|
|
|
|
PRINTF(" LR = %s0x%08"PRIX32"\033[m\r\n", REDPTR(stacked_lr), stacked_lr);
|
|
|
|
PRINTF(" PC = %s0x%08"PRIX32"\033[m\r\n", REDPTR(stacked_pc), stacked_pc);
|
|
|
|
PRINTF(" PSR = \033[36m0x%08"PRIX32"\033[m", stacked_psr);
|
|
|
|
uint32_t exc = stacked_psr & 0x3F;
|
|
|
|
PRINTF(" [ %s%s%s%s%s ]\r\n",
|
|
|
|
BS(stacked_psr, 31, "N"),
|
|
|
|
BS(stacked_psr, 30, "Z"),
|
|
|
|
BS(stacked_psr, 29, "C"),
|
|
|
|
BS(stacked_psr, 28, "V"),
|
|
|
|
//BS(stacked_psr, 24, "T"), - thumb, always ON
|
|
|
|
|
|
|
|
(exc==0)?"Thread":
|
|
|
|
(exc==2)?"NMI":
|
|
|
|
(exc==3)?"HardFault":
|
|
|
|
(exc==11)?"SVCall":
|
|
|
|
(exc==14)?"PendSV":
|
|
|
|
(exc==15)?"SysTick":
|
|
|
|
(exc>=16)?"IRQ":"Unknown"
|
|
|
|
);
|
|
|
|
|
|
|
|
#if (__CORTEX_M >= 3)
|
|
|
|
PRINTF("\r\n- FSR/FAR:\r\n");
|
|
|
|
PRINTF(" CFSR = \033[36m0x%08"PRIX32"\033[m\r\n", cfsr);
|
|
|
|
PRINTF(" UsageFault: \033[31;1m%s%s%s%s%s%s%s\033[m\r\n"
|
|
|
|
" BusFault: \033[31;1m%s%s%s%s%s%s%s%s\033[m\r\n"
|
|
|
|
" MemFault: \033[31;1m%s%s%s%s%s%s%s\033[m\r\n",
|
|
|
|
BS(cfsr, 0, "IAccViol"),
|
|
|
|
BS(cfsr, 1, "DAccViol"),
|
|
|
|
BS(cfsr, 3, "MUnstkErr"),
|
|
|
|
BS(cfsr, 4, "MStkErr"),
|
|
|
|
BS(cfsr, 5, "MLSPErr(FPU)"),
|
|
|
|
BS(cfsr, 7, "MMArValid"),
|
|
|
|
((cfsr&0xFF)?"":"\033[m- "),
|
|
|
|
|
|
|
|
BS(cfsr, 8, "IBusErr"),
|
|
|
|
BS(cfsr, 9, "PreciseErr"),
|
|
|
|
BS(cfsr, 10, "ImpreciseErr"),
|
|
|
|
BS(cfsr, 11, "UnstkErr"),
|
|
|
|
BS(cfsr, 12, "StkErr"),
|
|
|
|
BS(cfsr, 13, "LSPErr"),
|
|
|
|
BS(cfsr, 15, "BFArValid"),
|
|
|
|
((cfsr&0xFF00)?"":"\033[m- "),
|
|
|
|
|
|
|
|
BS(cfsr, 16, "UndefInstr"),
|
|
|
|
BS(cfsr, 17, "InvState"),
|
|
|
|
BS(cfsr, 18, "InvPC"),
|
|
|
|
BS(cfsr, 19, "NoCP"),
|
|
|
|
BS(cfsr, 24, "Unaligned"),
|
|
|
|
BS(cfsr, 25, "Div0"),
|
|
|
|
((cfsr&0xFFFF0000)?"":"\033[m- ")
|
|
|
|
);
|
|
|
|
|
|
|
|
PRINTF(" HFSR = \033[36m0x%08"PRIX32"\033[m", hfsr);
|
|
|
|
PRINTF(" [ %s%s%s]\r\n",
|
|
|
|
BS(hfsr, 31, "DebugEvt"),
|
|
|
|
BS(hfsr, 30, "Forced"),
|
|
|
|
BS(hfsr, 1, "VectTbl")
|
|
|
|
);
|
|
|
|
|
|
|
|
PRINTF(" DFSR = \033[36m0x%08"PRIX32"\033[m", dfsr);
|
|
|
|
PRINTF(" [ %s%s%s%s%s]\r\n",
|
|
|
|
BS(dfsr, 0, "Halted"),
|
|
|
|
BS(dfsr, 1, "Bkpt"),
|
|
|
|
BS(dfsr, 2, "DWtTrap"),
|
|
|
|
BS(dfsr, 3, "VCatch"),
|
|
|
|
BS(dfsr, 4, "External")
|
|
|
|
);
|
|
|
|
|
|
|
|
if (cfsr & 0x0080) PRINTF(" MMFAR = \033[33m0x%08"PRIX32"\033[m\r\n", memmanage_fault_address);
|
|
|
|
if (cfsr & 0x8000) PRINTF(" BFAR = \033[33m0x%08"PRIX32"\033[m\r\n", bus_fault_address);
|
|
|
|
PRINTF("\r\n- Misc\r\n");
|
|
|
|
PRINTF(" LR/EXC_RETURN= %s0x%08"PRIX32"\033[m\n", REDPTR(lr_value), lr_value);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
while (1);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles Hard fault interrupt.
|
|
|
|
*/
|
|
|
|
void __attribute__((naked)) HardFault_Handler(void)
|
|
|
|
{
|
|
|
|
#if VERBOSE_HARDFAULT
|
|
|
|
// __asm volatile
|
|
|
|
// (
|
|
|
|
// " tst lr, #4 \n"
|
|
|
|
// " ite eq \n"
|
|
|
|
// " mrseq r0, msp \n"
|
|
|
|
// " mrsne r0, psp \n"
|
|
|
|
// " ldr r1, [r0, #24] \n"
|
|
|
|
// " mov r2, lr \n"
|
|
|
|
// " ldr r3, handler2_address_const \n"
|
|
|
|
// " bx r3 \n"
|
|
|
|
// " handler2_address_const: .word HardFault_DumpRegisters \n"
|
|
|
|
// );
|
|
|
|
//
|
|
|
|
__asm volatile( ".syntax unified\n"
|
|
|
|
"MOVS R0, #4 \n"
|
|
|
|
"MOV R1, LR \n"
|
|
|
|
"TST R0, R1 \n"
|
|
|
|
"BEQ _MSP \n"
|
|
|
|
"MRS R0, PSP \n"
|
|
|
|
"B HardFault_DumpRegisters \n"
|
|
|
|
"_MSP: \n"
|
|
|
|
"MRS R0, MSP \n"
|
|
|
|
"B HardFault_DumpRegisters \n"
|
|
|
|
".syntax divided\n") ;
|
|
|
|
|
|
|
|
#else
|
|
|
|
app_emergency_stop();
|
|
|
|
PRINTF("*** HARD FAULT ***\r\n\r\n");
|
|
|
|
while (1);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles Memory management fault.
|
|
|
|
*/
|
|
|
|
void MemManage_Handler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
|
|
|
|
PUTS("MemManage_Handler\r\n");
|
|
|
|
app_emergency_stop();
|
|
|
|
|
|
|
|
/* USER CODE END MemoryManagement_IRQn 0 */
|
|
|
|
while (1) {
|
|
|
|
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
|
|
|
|
/* USER CODE END W1_MemoryManagement_IRQn 0 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles Prefetch fault, memory access fault.
|
|
|
|
*/
|
|
|
|
void BusFault_Handler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN BusFault_IRQn 0 */
|
|
|
|
PUTS("BusFault_Handler\r\n");
|
|
|
|
app_emergency_stop();
|
|
|
|
/* USER CODE END BusFault_IRQn 0 */
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
|
|
|
|
/* USER CODE END W1_BusFault_IRQn 0 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles Undefined instruction or illegal state.
|
|
|
|
*/
|
|
|
|
void UsageFault_Handler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN UsageFault_IRQn 0 */
|
|
|
|
PUTS("UsageFault_Handler\r\n");
|
|
|
|
app_emergency_stop();
|
|
|
|
/* USER CODE END UsageFault_IRQn 0 */
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
|
|
|
|
/* USER CODE END W1_UsageFault_IRQn 0 */
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles Debug monitor.
|
|
|
|
*/
|
|
|
|
void DebugMon_Handler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
|
|
|
|
|
|
|
|
/* USER CODE END DebugMonitor_IRQn 0 */
|
|
|
|
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
|
|
|
|
|
|
|
|
/* USER CODE END DebugMonitor_IRQn 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles System tick timer.
|
|
|
|
*/
|
|
|
|
void SysTick_Handler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN SysTick_IRQn 0 */
|
|
|
|
|
|
|
|
/* USER CODE END SysTick_IRQn 0 */
|
|
|
|
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
|
|
|
if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
|
|
|
#endif /* INCLUDE_xTaskGetSchedulerState */
|
|
|
|
xPortSysTickHandler();
|
|
|
|
#if (INCLUDE_xTaskGetSchedulerState == 1)
|
|
|
|
}
|
|
|
|
#endif /* INCLUDE_xTaskGetSchedulerState */
|
|
|
|
/* USER CODE BEGIN SysTick_IRQn 1 */
|
|
|
|
|
|
|
|
/* USER CODE END SysTick_IRQn 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
/* STM32F1xx Peripheral Interrupt Handlers */
|
|
|
|
/* Add here the Interrupt Handlers for the used peripherals. */
|
|
|
|
/* For the available peripheral interrupt handler names, */
|
|
|
|
/* please refer to the startup file (startup_stm32f1xx.s). */
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles DMA1 channel1 global interrupt.
|
|
|
|
*/
|
|
|
|
void DMA1_Channel1_IRQHandler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN DMA1_Channel1_IRQn 0 */
|
|
|
|
|
|
|
|
if (LL_DMA_IsActiveFlag_TC1(DMA1)) {
|
|
|
|
app_temp_adc_eos();
|
|
|
|
LL_DMA_ClearFlag_TC1(DMA1);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* USER CODE END DMA1_Channel1_IRQn 0 */
|
|
|
|
|
|
|
|
/* USER CODE BEGIN DMA1_Channel1_IRQn 1 */
|
|
|
|
|
|
|
|
/* USER CODE END DMA1_Channel1_IRQn 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles EXTI line[9:5] interrupts.
|
|
|
|
*/
|
|
|
|
void EXTI9_5_IRQHandler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
|
|
|
|
bool state = LL_GPIO_IsInputPinSet(KNOB_PUSH_GPIO_Port, KNOB_PUSH_Pin);
|
|
|
|
|
|
|
|
/* USER CODE END EXTI9_5_IRQn 0 */
|
|
|
|
if (LL_EXTI_IsActiveFlag_0_31(LL_EXTI_LINE_8) != RESET) {
|
|
|
|
LL_EXTI_ClearFlag_0_31(LL_EXTI_LINE_8);
|
|
|
|
/* USER CODE BEGIN LL_EXTI_LINE_8 */
|
|
|
|
|
|
|
|
app_knob_push_isr(0 == state);
|
|
|
|
|
|
|
|
/* USER CODE END LL_EXTI_LINE_8 */
|
|
|
|
}
|
|
|
|
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
|
|
|
|
|
|
|
|
/* USER CODE END EXTI9_5_IRQn 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief This function handles TIM4 global interrupt.
|
|
|
|
*/
|
|
|
|
void TIM4_IRQHandler(void)
|
|
|
|
{
|
|
|
|
/* USER CODE BEGIN TIM4_IRQn 0 */
|
|
|
|
|
|
|
|
if (LL_TIM_IsActiveFlag_CC1(TIM4) || LL_TIM_IsActiveFlag_CC2(TIM4)) {
|
|
|
|
LL_TIM_ClearFlag_CC1(TIM4);
|
|
|
|
LL_TIM_ClearFlag_CC2(TIM4);
|
|
|
|
app_knob_turn_isr();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* USER CODE END TIM4_IRQn 0 */
|
|
|
|
/* USER CODE BEGIN TIM4_IRQn 1 */
|
|
|
|
|
|
|
|
/* USER CODE END TIM4_IRQn 1 */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* USER CODE BEGIN 1 */
|
|
|
|
|
|
|
|
/* USER CODE END 1 */
|