From 5b5e322356a23b6f107a50a84dd0fc65a0a388af Mon Sep 17 00:00:00 2001 From: "J.C. Nelson" <32139633+xC0000005@users.noreply.github.com> Date: Wed, 25 Apr 2018 22:21:16 -0700 Subject: [PATCH] Set Interrupt Priorities and Grouping for STM32F103. (#10517) --- Marlin/src/HAL/HAL_STM32F1/HAL.cpp | 63 +++++++++++++++++-- Marlin/src/HAL/HAL_STM32F1/HAL.h | 4 ++ .../HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp | 38 ++++++----- Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h | 2 +- 4 files changed, 84 insertions(+), 23 deletions(-) diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL.cpp index e900f4a32..f75a071bc 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL.cpp @@ -34,24 +34,60 @@ #include "HAL.h" #include -//#include - // -------------------------------------------------------------------------- // Externals // -------------------------------------------------------------------------- -// -------------------------------------------------------------------------- -// Local defines -// -------------------------------------------------------------------------- - // -------------------------------------------------------------------------- // Types // -------------------------------------------------------------------------- +#define __I +#define __IO + typedef struct + { + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control Register */ + } SCB_Type; + // -------------------------------------------------------------------------- // Variables // -------------------------------------------------------------------------- +// -------------------------------------------------------------------------- +// Local defines +// -------------------------------------------------------------------------- +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP Mask */ + // -------------------------------------------------------------------------- // Public Variables // -------------------------------------------------------------------------- @@ -123,11 +159,26 @@ uint16_t HAL_adc_results[ADC_PIN_COUNT]; // -------------------------------------------------------------------------- // Private functions // -------------------------------------------------------------------------- +static void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) { + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} // -------------------------------------------------------------------------- // Public functions // -------------------------------------------------------------------------- +void HAL_init(void) { + NVIC_SetPriorityGrouping(0x3); +} + /* VGPV Done with defines // disable interrupts void cli(void) { noInterrupts(); } diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL.h b/Marlin/src/HAL/HAL_STM32F1/HAL.h index 3474ae5e1..9e031abb9 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL.h +++ b/Marlin/src/HAL/HAL_STM32F1/HAL.h @@ -108,6 +108,10 @@ extern USBSerial SerialUSB; #define NUM_SERIAL 1 #endif +// Use HAL_init() to set interrupt grouping. +#define HAL_INIT +void HAL_init(); + /** * TODO: review this to return 1 for pins that are not analog input */ diff --git a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp index d3de91ac1..21a648269 100644 --- a/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp +++ b/Marlin/src/HAL/HAL_STM32F1/HAL_timers_Stm32f1.cpp @@ -109,7 +109,11 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { */ break; } - nvic_irq_set_priority(irq_num, 0xF); // this is the lowest settable priority, but should still be over USB + + /** + * Give the Stepper ISR a higher priority (lower number) + * so it automatically preempts the Temperature ISR. + */ switch (timer_num) { case STEP_TIMER_NUM: @@ -119,6 +123,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { timer_set_reload(STEP_TIMER_DEV, 0xFFFF); timer_set_compare(STEP_TIMER_DEV, STEP_TIMER_CHAN, min(HAL_TIMER_TYPE_MAX, (HAL_STEPPER_TIMER_RATE / frequency))); timer_attach_interrupt(STEP_TIMER_DEV, STEP_TIMER_CHAN, stepTC_Handler); + nvic_irq_set_priority(irq_num, 1); timer_generate_update(STEP_TIMER_DEV); timer_resume(STEP_TIMER_DEV); break; @@ -129,6 +134,7 @@ void HAL_timer_start(const uint8_t timer_num, const uint32_t frequency) { timer_set_reload(TEMP_TIMER_DEV, 0xFFFF); timer_set_compare(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, min(HAL_TIMER_TYPE_MAX, ((F_CPU / TEMP_TIMER_PRESCALE) / frequency))); timer_attach_interrupt(TEMP_TIMER_DEV, TEMP_TIMER_CHAN, tempTC_Handler); + nvic_irq_set_priority(irq_num, 2); timer_generate_update(TEMP_TIMER_DEV); timer_resume(TEMP_TIMER_DEV); break; @@ -166,48 +172,48 @@ bool HAL_timer_interrupt_enabled(const uint8_t timer_num) { timer_dev* get_timer_dev(int number) { switch (number) { #if STM32_HAVE_TIMER(1) - case 1: return &timer1; + case 1: return &timer1; #endif #if STM32_HAVE_TIMER(2) - case 2: return &timer2; + case 2: return &timer2; #endif #if STM32_HAVE_TIMER(3) - case 3: return &timer3; + case 3: return &timer3; #endif #if STM32_HAVE_TIMER(4) - case 4: return &timer4; + case 4: return &timer4; #endif #if STM32_HAVE_TIMER(5) - case 5: return &timer5; + case 5: return &timer5; #endif #if STM32_HAVE_TIMER(6) - case 6: return &timer6; + case 6: return &timer6; #endif #if STM32_HAVE_TIMER(7) - case 7: return &timer7; + case 7: return &timer7; #endif #if STM32_HAVE_TIMER(8) - case 8: return &timer8; + case 8: return &timer8; #endif #if STM32_HAVE_TIMER(9) - case 9: return &timer9; + case 9: return &timer9; #endif #if STM32_HAVE_TIMER(10) - case 10: return &timer10; + case 10: return &timer10; #endif #if STM32_HAVE_TIMER(11) - case 11: return &timer11; + case 11: return &timer11; #endif #if STM32_HAVE_TIMER(12) - case 12: return &timer12; + case 12: return &timer12; #endif #if STM32_HAVE_TIMER(13) - case 13: return &timer14; + case 13: return &timer14; #endif #if STM32_HAVE_TIMER(14) - case 14: return &timer14; + case 14: return &timer14; #endif - } + } } #endif // __STM32F1__ diff --git a/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h b/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h index 3674856fe..a854c8dff 100644 --- a/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h +++ b/Marlin/src/HAL/HAL_STM32F1/fastio_Stm32f1.h @@ -32,7 +32,7 @@ #include #define READ(IO) (PIN_MAP[IO].gpio_device->regs->IDR & (1U << PIN_MAP[IO].gpio_bit) ? HIGH : LOW) -#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)v)) +#define WRITE(IO,V) (PIN_MAP[IO].gpio_device->regs->BSRR = (1U << PIN_MAP[IO].gpio_bit) << (16 * !(bool)V)) #define TOGGLE(IO) (PIN_MAP[IO].gpio_device->regs->ODR = PIN_MAP[IO].gpio_device->regs->ODR ^ (1U << PIN_MAP[IO].gpio_bit)) #define WRITE_VAR(IO,V) WRITE(io,V)