summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien.p.george@gmail.com>2018-05-02 14:41:02 +1000
committerDamien George <damien.p.george@gmail.com>2018-05-02 14:41:02 +1000
commita03e6c1e05203bb71ebee50af2a41de404b05078 (patch)
tree8c4e9484ed1ac23a9c6ecc7ce1b52bf856e250de
parent266446624fc055e988782577286fe91efbda438e (diff)
stm32/irq: Define IRQ priorities directly as encoded hardware values.
For a given IRQn (eg UART) there's no need to carry around both a PRI and SUBPRI value (eg IRQ_PRI_UART, IRQ_SUBPRI_UART). Instead, the IRQ_PRI_UART value has been changed in this patch to be the encoded hardware value, using NVIC_EncodePriority. This way the NVIC_SetPriority function can be used directly, instead of going through HAL_NVIC_SetPriority which must do extra processing to encode the PRI+SUBPRI. For a priority grouping of 4 (4 bits for preempt priority, 0 bits for the sub-priority), which is used in the stm32 port, the IRQ_PRI_xxx constants remain unchanged in their value. This patch also "fixes" the use of raise_irq_pri() which should be passed the encoded value (but as mentioned above the unencoded value is the same as the encoded value for priority grouping 4, so there was no bug from this error).
-rw-r--r--ports/stm32/can.c4
-rw-r--r--ports/stm32/dma.c4
-rw-r--r--ports/stm32/extint.c4
-rw-r--r--ports/stm32/irq.h48
-rw-r--r--ports/stm32/pendsv.c2
-rw-r--r--ports/stm32/rtc.c2
-rw-r--r--ports/stm32/sdcard.c2
-rw-r--r--ports/stm32/storage.c2
-rw-r--r--ports/stm32/system_stm32.c2
-rw-r--r--ports/stm32/timer.c8
-rw-r--r--ports/stm32/uart.c2
-rw-r--r--ports/stm32/usbd_conf.c4
12 files changed, 35 insertions, 49 deletions
diff --git a/ports/stm32/can.c b/ports/stm32/can.c
index ae8e8e27e..22ac5509c 100644
--- a/ports/stm32/can.c
+++ b/ports/stm32/can.c
@@ -153,7 +153,7 @@ STATIC bool can_init(pyb_can_obj_t *can_obj) {
__HAL_CAN_ENABLE_IT(&can_obj->can, CAN_IT_ERR | CAN_IT_BOF | CAN_IT_EPV | CAN_IT_EWG);
- HAL_NVIC_SetPriority(sce_irq, IRQ_PRI_CAN, IRQ_SUBPRI_CAN);
+ NVIC_SetPriority(sce_irq, IRQ_PRI_CAN);
HAL_NVIC_EnableIRQ(sce_irq);
return true;
@@ -934,7 +934,7 @@ STATIC mp_obj_t pyb_can_rxcallback(mp_obj_t self_in, mp_obj_t fifo_in, mp_obj_t
irq = (fifo == 0) ? CAN2_RX0_IRQn : CAN2_RX1_IRQn;
#endif
}
- HAL_NVIC_SetPriority(irq, IRQ_PRI_CAN, IRQ_SUBPRI_CAN);
+ NVIC_SetPriority(irq, IRQ_PRI_CAN);
HAL_NVIC_EnableIRQ(irq);
__HAL_CAN_ENABLE_IT(&self->can, (fifo == 0) ? CAN_IT_FMP0 : CAN_IT_FMP1);
__HAL_CAN_ENABLE_IT(&self->can, (fifo == 0) ? CAN_IT_FF0 : CAN_IT_FF1);
diff --git a/ports/stm32/dma.c b/ports/stm32/dma.c
index 35cfba162..fde8d678b 100644
--- a/ports/stm32/dma.c
+++ b/ports/stm32/dma.c
@@ -504,7 +504,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
// TODO: understand how L4 DMA works so this is not needed
HAL_DMA_DeInit(dma);
HAL_DMA_Init(dma);
- HAL_NVIC_SetPriority(dma_irqn[dma_id], IRQ_PRI_DMA, IRQ_SUBPRI_DMA);
+ NVIC_SetPriority(IRQn_NONNEG(dma_irqn[dma_id]), IRQ_PRI_DMA);
#else
// if this stream was previously configured for this channel/request then we
// can skip most of the initialisation
@@ -516,7 +516,7 @@ void dma_init(DMA_HandleTypeDef *dma, const dma_descr_t *dma_descr, void *data){
// (dma->State is set to HAL_DMA_STATE_RESET by memset above)
HAL_DMA_DeInit(dma);
HAL_DMA_Init(dma);
- HAL_NVIC_SetPriority(dma_irqn[dma_id], IRQ_PRI_DMA, IRQ_SUBPRI_DMA);
+ NVIC_SetPriority(IRQn_NONNEG(dma_irqn[dma_id]), IRQ_PRI_DMA);
} else {
// only necessary initialization
dma->State = HAL_DMA_STATE_READY;
diff --git a/ports/stm32/extint.c b/ports/stm32/extint.c
index 9fe53a1a3..7c33b317b 100644
--- a/ports/stm32/extint.c
+++ b/ports/stm32/extint.c
@@ -214,7 +214,7 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca
// Calling HAL_GPIO_Init does an implicit extint_enable
/* Enable and set NVIC Interrupt to the lowest priority */
- HAL_NVIC_SetPriority(nvic_irq_channel[v_line], IRQ_PRI_EXTINT, IRQ_SUBPRI_EXTINT);
+ NVIC_SetPriority(IRQn_NONNEG(nvic_irq_channel[v_line]), IRQ_PRI_EXTINT);
HAL_NVIC_EnableIRQ(nvic_irq_channel[v_line]);
}
return v_line;
@@ -270,7 +270,7 @@ void extint_register_pin(const pin_obj_t *pin, uint32_t mode, bool hard_irq, mp_
}
// Configure the NVIC
- HAL_NVIC_SetPriority(nvic_irq_channel[line], IRQ_PRI_EXTINT, IRQ_SUBPRI_EXTINT);
+ NVIC_SetPriority(IRQn_NONNEG(nvic_irq_channel[line]), IRQ_PRI_EXTINT);
HAL_NVIC_EnableIRQ(nvic_irq_channel[line]);
// Enable the interrupt
diff --git a/ports/stm32/irq.h b/ports/stm32/irq.h
index d0bb49c52..1b68a5488 100644
--- a/ports/stm32/irq.h
+++ b/ports/stm32/irq.h
@@ -26,6 +26,10 @@
#ifndef MICROPY_INCLUDED_STM32_IRQ_H
#define MICROPY_INCLUDED_STM32_IRQ_H
+// Use this macro together with NVIC_SetPriority to indicate that an IRQn is non-negative,
+// which helps the compiler optimise the resulting inline function.
+#define IRQn_NONNEG(pri) ((pri) & 0x7f)
+
// these states correspond to values from query_irq, enable_irq and disable_irq
#define IRQ_STATE_DISABLED (0x00000001)
#define IRQ_STATE_ENABLED (0x00000000)
@@ -98,55 +102,37 @@ MP_DECLARE_CONST_FUN_OBJ_0(pyb_irq_stats_obj);
// The following interrupts are arranged from highest priority to lowest
// priority to make it a bit easier to figure out.
-// Priority Sub-Priority
-// -------- ------------
-//#def IRQ_PRI_SYSTICK 0
-//#def IRQ_SUBPRI_SYSTICK 0
+//#def IRQ_PRI_SYSTICK NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 0, 0)
// The UARTs have no FIFOs, so if they don't get serviced quickly then characters
// get dropped. The handling for each character only consumes about 0.5 usec
-#define IRQ_PRI_UART 1
-#define IRQ_SUBPRI_UART 0
+#define IRQ_PRI_UART NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 1, 0)
// Flash IRQ must be higher priority than interrupts of all those components
// that rely on the flash storage.
-#define IRQ_PRI_FLASH 2
-#define IRQ_SUBPRI_FLASH 0
+#define IRQ_PRI_FLASH NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 2, 0)
// SDIO must be higher priority than DMA for SDIO DMA transfers to work.
-#define IRQ_PRI_SDIO 4
-#define IRQ_SUBPRI_SDIO 0
+#define IRQ_PRI_SDIO NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 4, 0)
// DMA should be higher priority than USB, since USB Mass Storage calls
// into the sdcard driver which waits for the DMA to complete.
-#define IRQ_PRI_DMA 5
-#define IRQ_SUBPRI_DMA 0
-
-#define IRQ_PRI_OTG_FS 6
-#define IRQ_SUBPRI_OTG_FS 0
+#define IRQ_PRI_DMA NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 5, 0)
-#define IRQ_PRI_OTG_HS 6
-#define IRQ_SUBPRI_OTG_HS 0
+#define IRQ_PRI_OTG_FS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
+#define IRQ_PRI_OTG_HS NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
+#define IRQ_PRI_TIM5 NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 6, 0)
-#define IRQ_PRI_TIM5 6
-#define IRQ_SUBPRI_TIM5 0
-
-#define IRQ_PRI_CAN 7
-#define IRQ_SUBPRI_CAN 0
+#define IRQ_PRI_CAN NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 7, 0)
// Interrupt priority for non-special timers.
-#define IRQ_PRI_TIMX 13
-#define IRQ_SUBPRI_TIMX 0
+#define IRQ_PRI_TIMX NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 13, 0)
-#define IRQ_PRI_EXTINT 14
-#define IRQ_SUBPRI_EXTINT 0
+#define IRQ_PRI_EXTINT NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 14, 0)
// PENDSV should be at the lowst priority so that other interrupts complete
// before exception is raised.
-#define IRQ_PRI_PENDSV 15
-#define IRQ_SUBPRI_PENDSV 0
-
-#define IRQ_PRI_RTC_WKUP 15
-#define IRQ_SUBPRI_RTC_WKUP 0
+#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
+#define IRQ_PRI_RTC_WKUP NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, 15, 0)
#endif // MICROPY_INCLUDED_STM32_IRQ_H
diff --git a/ports/stm32/pendsv.c b/ports/stm32/pendsv.c
index 0aeb1a6dc..b5fe42f70 100644
--- a/ports/stm32/pendsv.c
+++ b/ports/stm32/pendsv.c
@@ -40,7 +40,7 @@ void *pendsv_object;
void pendsv_init(void) {
// set PendSV interrupt at lowest priority
- HAL_NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV, IRQ_SUBPRI_PENDSV);
+ NVIC_SetPriority(PendSV_IRQn, IRQ_PRI_PENDSV);
}
// Call this function to raise a pending exception during an interrupt.
diff --git a/ports/stm32/rtc.c b/ports/stm32/rtc.c
index 8fb6ae29f..744fbe8b9 100644
--- a/ports/stm32/rtc.c
+++ b/ports/stm32/rtc.c
@@ -656,7 +656,7 @@ mp_obj_t pyb_rtc_wakeup(size_t n_args, const mp_obj_t *args) {
EXTI->PR = 1 << 22;
#endif
- HAL_NVIC_SetPriority(RTC_WKUP_IRQn, IRQ_PRI_RTC_WKUP, IRQ_SUBPRI_RTC_WKUP);
+ NVIC_SetPriority(RTC_WKUP_IRQn, IRQ_PRI_RTC_WKUP);
HAL_NVIC_EnableIRQ(RTC_WKUP_IRQn);
//printf("wut=%d wucksel=%d\n", wut, wucksel);
diff --git a/ports/stm32/sdcard.c b/ports/stm32/sdcard.c
index 4eb9fce6c..27e7a34b2 100644
--- a/ports/stm32/sdcard.c
+++ b/ports/stm32/sdcard.c
@@ -173,7 +173,7 @@ void HAL_SD_MspInit(SD_HandleTypeDef *hsd) {
#endif
// NVIC configuration for SDIO interrupts
- HAL_NVIC_SetPriority(SDMMC_IRQn, IRQ_PRI_SDIO, IRQ_SUBPRI_SDIO);
+ NVIC_SetPriority(SDMMC_IRQn, IRQ_PRI_SDIO);
HAL_NVIC_EnableIRQ(SDMMC_IRQn);
// GPIO have already been initialised by sdcard_init
diff --git a/ports/stm32/storage.c b/ports/stm32/storage.c
index 1450f2156..2ac54a401 100644
--- a/ports/stm32/storage.c
+++ b/ports/stm32/storage.c
@@ -55,7 +55,7 @@ void storage_init(void) {
// Enable the flash IRQ, which is used to also call our storage IRQ handler
// It needs to go at a higher priority than all those components that rely on
// the flash storage (eg higher than USB MSC).
- HAL_NVIC_SetPriority(FLASH_IRQn, IRQ_PRI_FLASH, IRQ_SUBPRI_FLASH);
+ NVIC_SetPriority(FLASH_IRQn, IRQ_PRI_FLASH);
HAL_NVIC_EnableIRQ(FLASH_IRQn);
}
}
diff --git a/ports/stm32/system_stm32.c b/ports/stm32/system_stm32.c
index 6bf9817cc..2d9f7a15d 100644
--- a/ports/stm32/system_stm32.c
+++ b/ports/stm32/system_stm32.c
@@ -599,7 +599,7 @@ void SystemClock_Config(void)
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
- HAL_NVIC_SetPriority(SysTick_IRQn, TICK_INT_PRIORITY, 0);
+ NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, TICK_INT_PRIORITY, 0));
#endif
}
diff --git a/ports/stm32/timer.c b/ports/stm32/timer.c
index 18661da9c..c662303c5 100644
--- a/ports/stm32/timer.c
+++ b/ports/stm32/timer.c
@@ -170,7 +170,7 @@ void timer_tim5_init(void) {
__HAL_RCC_TIM5_CLK_ENABLE();
// set up and enable interrupt
- HAL_NVIC_SetPriority(TIM5_IRQn, IRQ_PRI_TIM5, IRQ_SUBPRI_TIM5);
+ NVIC_SetPriority(TIM5_IRQn, IRQ_PRI_TIM5);
HAL_NVIC_EnableIRQ(TIM5_IRQn);
// PWM clock configuration
@@ -611,12 +611,12 @@ STATIC mp_obj_t pyb_timer_init_helper(pyb_timer_obj_t *self, size_t n_args, cons
// set IRQ priority (if not a special timer)
if (self->tim_id != 5) {
- HAL_NVIC_SetPriority(self->irqn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX);
+ NVIC_SetPriority(IRQn_NONNEG(self->irqn), IRQ_PRI_TIMX);
if (self->tim_id == 1) {
- HAL_NVIC_SetPriority(TIM1_CC_IRQn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX);
+ NVIC_SetPriority(TIM1_CC_IRQn, IRQ_PRI_TIMX);
#if defined(TIM8)
} else if (self->tim_id == 8) {
- HAL_NVIC_SetPriority(TIM8_CC_IRQn, IRQ_PRI_TIMX, IRQ_SUBPRI_TIMX);
+ NVIC_SetPriority(TIM8_CC_IRQn, IRQ_PRI_TIMX);
#endif
}
}
diff --git a/ports/stm32/uart.c b/ports/stm32/uart.c
index 677606940..54dcc0572 100644
--- a/ports/stm32/uart.c
+++ b/ports/stm32/uart.c
@@ -691,7 +691,7 @@ STATIC mp_obj_t pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const
self->read_buf_len = args.read_buf_len.u_int + 1; // +1 to adjust for usable length of buffer
self->read_buf = m_new(byte, self->read_buf_len << self->char_width);
__HAL_UART_ENABLE_IT(&self->uart, UART_IT_RXNE);
- HAL_NVIC_SetPriority(self->irqn, IRQ_PRI_UART, IRQ_SUBPRI_UART);
+ NVIC_SetPriority(IRQn_NONNEG(self->irqn), IRQ_PRI_UART);
HAL_NVIC_EnableIRQ(self->irqn);
}
diff --git a/ports/stm32/usbd_conf.c b/ports/stm32/usbd_conf.c
index d53d369a6..4902da997 100644
--- a/ports/stm32/usbd_conf.c
+++ b/ports/stm32/usbd_conf.c
@@ -107,7 +107,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
#endif
/* Set USBFS Interrupt priority */
- HAL_NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS, IRQ_SUBPRI_OTG_FS);
+ NVIC_SetPriority(OTG_FS_IRQn, IRQ_PRI_OTG_FS);
/* Enable USBFS Interrupt */
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
@@ -211,7 +211,7 @@ void HAL_PCD_MspInit(PCD_HandleTypeDef *hpcd)
#endif // !MICROPY_HW_USB_HS_IN_FS
/* Set USBHS Interrupt to the lowest priority */
- HAL_NVIC_SetPriority(OTG_HS_IRQn, IRQ_PRI_OTG_HS, IRQ_SUBPRI_OTG_HS);
+ NVIC_SetPriority(OTG_HS_IRQn, IRQ_PRI_OTG_HS);
/* Enable USBHS Interrupt */
HAL_NVIC_EnableIRQ(OTG_HS_IRQn);