From 51637a2ee4548384a3fb559c9c1b69c7798be639 Mon Sep 17 00:00:00 2001 From: recallmenot <edmund.raile@proton.me> Date: Sun, 4 Jun 2023 06:58:51 +0200 Subject: [PATCH] ch32v003fun.c and .h added interrupt suspension functions --- ch32v003fun/ch32v003fun.c | 45 +++++++++++++++++++++++++++++++++++++++ ch32v003fun/ch32v003fun.h | 5 +++++ 2 files changed, 50 insertions(+) diff --git a/ch32v003fun/ch32v003fun.c b/ch32v003fun/ch32v003fun.c index 3db230e..671f081 100644 --- a/ch32v003fun/ch32v003fun.c +++ b/ch32v003fun/ch32v003fun.c @@ -765,6 +765,51 @@ void InterruptVectorDefault() .option pop;\n"); } + + +/* +SUSPEND ALL INTERRUPTS EXCEPT +The following 3 functions serve to suspend all interrupts, except for the one you momentarily need. +The purpose of this is to not disturb the one interrupt of interest and let it run unimpeded. +procedure: +1. save the enabled IRQs: uint32_t IRQ_backup = NVIC_get_enabled_IRQs(); +2. disable all IRQs: NVIC_clear_all_IRQs_except(IRQ_of_interest); +3. restore the previously enabled IRQs: NVIC_restore_IRQs(IRQ_backup); + +bit layout of the IRQ backup +bit 0 | 1 | 2 | 3 | 4 | 5 | 6 .. 22 | 23 .. 28 +IRQn 2 | 3 | 12 | res | 14 | res | 16 .. 31 | 32 .. 38 +IRQn 2 and 3 aren't actually user-settable (see RM). + +Specifying an invalid IRQn_to_keep like 0 will disable all interrupts. +*/ + +RV_STATIC_INLINE uint32_t NVIC_get_enabled_IRQs() +{ + return ( ((NVIC->ISR[0] >> 2) & 0b11) | ((NVIC->ISR[0] >> 12) << 2) | ((NVIC->ISR[1] & 0b1111111) << 23) ); +} + +RV_STATIC_INLINE void NVIC_clear_all_IRQs_except(uint8_t IRQn_to_keep) +{ + if (!(IRQn_to_keep >> 5)) { // IRQn_to_keep < 32 + NVIC->IRER[0] = (~0) & (~(1 << IRQn_to_keep)); + NVIC->IRER[1] = (~0); + } + else { + IRQn_to_keep = IRQn_to_keep >> 5; + NVIC->IRER[0] = (~0); + NVIC->IRER[1] = (~0) & (~(1 << IRQn_to_keep)); + } +} + +RV_STATIC_INLINE void NVIC_restore_IRQs(uint32_t old_state) +{ + NVIC->IENR[0] = (old_state >> 2) << 12; + NVIC->IENR[1] = old_state >> 23; +} + + + void handle_reset() { asm volatile( "\n\ diff --git a/ch32v003fun/ch32v003fun.h b/ch32v003fun/ch32v003fun.h index 10d5fc2..cc62930 100644 --- a/ch32v003fun/ch32v003fun.h +++ b/ch32v003fun/ch32v003fun.h @@ -5024,6 +5024,11 @@ void SystemInit24HSI( void ); // No PLL, just raw internal RC oscillator. void SystemInitHSE( int HSEBYP ); void SystemInitHSEPLL( int HSEBYP ); +// SUSPEND ALL INTERRUPTS EXCEPT +RV_STATIC_INLINE uint32_t NVIC_get_enabled_IRQs(); +RV_STATIC_INLINE void NVIC_clear_all_IRQs_except(uint8_t IRQn_to_keep); +RV_STATIC_INLINE void NVIC_restore_IRQs(uint32_t old_state); + #define UART_BAUD_RATE 115200 #define OVER8DIV 4 #define INTEGER_DIVIDER (((25 * (APB_CLOCK)) / ((OVER8DIV) * (UART_BAUD_RATE)))) -- GitLab