/** * @brief This function handles EXTI Lines 15 to 10 interrupts requests. * @param None * @retval None */ void EXTI15_10_IRQHandler(void) { if(EXTI_GetITStatus(TAMPER_BUTTON_EXTI_LINE) != RESET) { if(uwIndex == 0) { /* Configure the BASEPRI register to 0x40 (Preemption priority = 1). Only IRQ with higher preemption priority than 1 are permitted. This will mask TIM3 and TIM4 IRQ from generation. */ __set_BASEPRI(0x40); uwIndex++; } else { /* Configure the BASEPRI register to 0x00 (Preemption priority = 0). When this BASEPRI register is set to 0, it has no effect on the current priority. TIM2, TIM3 and TIM4 generation is controlled by NVIC priority registers. */ __set_BASEPRI(0x00); uwIndex = 0; } /* Clears the TAMPER Button EXTI line pending bit */ EXTI_ClearITPendingBit(TAMPER_BUTTON_EXTI_LINE); } }
void nOS_SwitchContext (void) { #if (NOS_CONFIG_MAX_UNSAFE_ISR_PRIO > 0) nOS_StatusReg sr = __get_BASEPRI(); #endif /* Request context switch */ *(volatile uint32_t *)0xE000ED04UL = 0x10000000UL; /* Leave critical section */ #if (NOS_CONFIG_MAX_UNSAFE_ISR_PRIO > 0) __set_BASEPRI(0); #else __enable_interrupt(); #endif __DSB(); __ISB(); __no_operation(); /* Enter critical section */ #if (NOS_CONFIG_MAX_UNSAFE_ISR_PRIO > 0) __set_BASEPRI(sr); #else __disable_interrupt(); #endif __DSB(); __ISB(); }
void arch_early_init(void) { arch_disable_ints(); #if (__CORTEX_M >= 0x03) || (CORTEX_SC >= 300) uint i; /* set the vector table base */ SCB->VTOR = (uint32_t)&vectab; #if ARM_CM_DYNAMIC_PRIORITY_SIZE /* number of priorities */ for (i=0; i < 7; i++) { __set_BASEPRI(1 << i); if (__get_BASEPRI() != 0) break; } arm_cm_num_irq_pri_bits = 8 - i; arm_cm_irq_pri_mask = ~((1 << i) - 1) & 0xff; #endif /* clear any pending interrupts and set all the vectors to medium priority */ uint groups = (SCnSCB->ICTR & 0xf) + 1; for (i = 0; i < groups; i++) { NVIC->ICER[i] = 0xffffffff; NVIC->ICPR[i] = 0xffffffff; for (uint j = 0; j < 32; j++) { NVIC_SetPriority(i*32 + j, arm_cm_medium_priority()); } } /* leave BASEPRI at 0 */ __set_BASEPRI(0); /* set priority grouping to 0 */ NVIC_SetPriorityGrouping(0); /* enable certain faults */ SCB->SHCSR |= (SCB_SHCSR_USGFAULTENA_Msk | SCB_SHCSR_BUSFAULTENA_Msk | SCB_SHCSR_MEMFAULTENA_Msk); /* set the svc and pendsv priority level to pretty low */ #endif NVIC_SetPriority(SVCall_IRQn, arm_cm_lowest_priority()); NVIC_SetPriority(PendSV_IRQn, arm_cm_lowest_priority()); /* set systick and debugmonitor to medium priority */ NVIC_SetPriority(SysTick_IRQn, arm_cm_medium_priority()); #if (__CORTEX_M >= 0x03) NVIC_SetPriority(DebugMonitor_IRQn, arm_cm_medium_priority()); #endif #if ARM_WITH_CACHE arch_enable_cache(UCACHE); #endif }
int HAL_disable_irq() { // We are blocking any interrupts with priorities >= 2, without // affecting SoftDevice interrupts which run with priorities 0 and 1. int st = __get_BASEPRI(); __set_BASEPRI(APP_IRQ_PRIORITY_HIGHEST << (8 - __NVIC_PRIO_BITS)); return st; }
/* If FreeRTOS is not running, then we rely on RIT service to call this function, * otherwise we rely on FreeRTOS tick hook to provide system timer */ static void hl_periodic_service(void) { sys_watchdog_feed(); /* If FreeRTOS is running, user should use a dedicated task to call mesh service, * so we will not call it if freertos is running */ if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) { g_system_uptime_ms += MS_PER_TICK(); /* We don't need RIT if FreeRTOS is running */ if (sys_rit_running()) { sys_rit_disable(); /* The timer value so far may be an odd number, and if MS_PER_TICK() is not 1 * then we may increment it like 12, 22, 32, etc. so round this number once. */ g_system_uptime_ms = (g_system_uptime_ms / 10) * 10; } } else { g_system_uptime_ms += g_time_per_rit_isr_ms; wireless_service(); /** * Small hack to support interrupts if FreeRTOS is not running : * FreeRTOS API resets our base priority register, then all * interrupts higher priority than IP_SYSCALL will not get locked out. * @see more notes at isr_priorities.h. @see IP_SYSCALL */ __set_BASEPRI(0); } }
/** \brief Test case: TC_CoreFunc_BASEPRI \details - Check if __get_BASEPRI and __set_BASEPRI intrinsic can be used to manipulate BASEPRI. - Check if __set_BASEPRI_MAX intrinsic can be used to manipulate BASEPRI. */ void TC_CoreFunc_BASEPRI(void) { uint32_t orig = __get_BASEPRI(); uint32_t basepri = ~orig & 0x80U; __set_BASEPRI(basepri); uint32_t result = __get_BASEPRI(); ASSERT_TRUE(result == basepri); __set_BASEPRI(orig); __set_BASEPRI_MAX(basepri); result = __get_BASEPRI(); ASSERT_TRUE(result == basepri); }
void _arm_cm_set_irqpri(uint32_t pri) { if (pri == 0) { __disable_irq(); // cpsid i __set_BASEPRI(0); } else if (pri >= 256) { __set_BASEPRI(0); __enable_irq(); } else { uint32_t _pri = pri & arm_cm_irq_pri_mask; if (_pri == 0) __set_BASEPRI(1 << (8 - arm_cm_num_irq_pri_bits)); else __set_BASEPRI(_pri); __enable_irq(); // cpsie i } }
/** * @brief Outgoing packets handler. * * @param[in] usbp pointer to the @p USBDriver object * @param[in] ep endpoint number * * @notapi */ static bool_t otg_txfifo_handler(USBDriver *usbp, usbep_t ep) { /* The TXFIFO is filled until there is space and data to be transmitted.*/ while (TRUE) { uint32_t n; /* Transaction end condition.*/ if (usbp->epc[ep]->in_state->txcnt >= usbp->epc[ep]->in_state->txsize) return TRUE; /* Number of bytes remaining in current transaction.*/ n = usbp->epc[ep]->in_state->txsize - usbp->epc[ep]->in_state->txcnt; if (n > usbp->epc[ep]->in_maxsize) n = usbp->epc[ep]->in_maxsize; /* Checks if in the TXFIFO there is enough space to accommodate the next packet.*/ if (((usbp->otg->ie[ep].DTXFSTS & DTXFSTS_INEPTFSAV_MASK) * 4) < n) return FALSE; #if STM32_USB_OTGFIFO_FILL_BASEPRI __set_BASEPRI(CORTEX_PRIORITY_MASK(STM32_USB_OTGFIFO_FILL_BASEPRI)); #endif /* Handles the two cases: linear buffer or queue.*/ if (usbp->epc[ep]->in_state->txqueued) { /* Queue associated.*/ otg_fifo_write_from_queue(usbp->otg->FIFO[ep], usbp->epc[ep]->in_state->mode.queue.txqueue, n); } else { /* Linear buffer associated.*/ otg_fifo_write_from_buffer(usbp->otg->FIFO[ep], usbp->epc[ep]->in_state->mode.linear.txbuf, n); usbp->epc[ep]->in_state->mode.linear.txbuf += n; } usbp->epc[ep]->in_state->txcnt += n; } #if STM32_USB_OTGFIFO_FILL_BASEPRI __set_BASEPRI(0); #endif }
void nOS_SwitchContext (void) { nOS_StatusReg sr = __get_BASEPRI(); /* Request context switch */ *(volatile uint32_t *)0xE000ED04UL = 0x10000000UL; /* Leave critical section */ __set_BASEPRI(0); __DSB(); __ISB(); __no_operation(); /* Enter critical section */ __set_BASEPRI(sr); __DSB(); __ISB(); }
void lock_interrupts(void) { #if defined(CONFIG_ARMV6_M_ARMV8_M_BASELINE) __disable_irq(); #elif defined(CONFIG_ARMV7_M_ARMV8_M_MAINLINE) __set_BASEPRI(_EXC_IRQ_DEFAULT_PRIO); #else #error Unknown ARM architecture #endif /* CONFIG_ARMV6_M_ARMV8_M_BASELINE */ }
void board_init(void) { /* Set the Vector Table base location at 0x08000000 */ NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); /* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for subpriority */ NVIC_SetPriorityGrouping(NVIC_PriorityGroup_0); /* Set Base Priority Mask Register */ __set_BASEPRI(0x00UL); }
void restoreInterruptMasking(const InterruptMask interruptMask) { #if CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI != 0 __set_BASEPRI(interruptMask); #else // CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0 __set_PRIMASK(interruptMask); #endif // CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0 }
InterruptMask disableInterruptMasking() { #if CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI != 0 const auto interruptMask = __get_BASEPRI(); __set_BASEPRI(0); return interruptMask; #else // CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0 const auto interruptMask = __get_PRIMASK(); __enable_irq(); return interruptMask; #endif // CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0 }
/***************************************************************************//** * @brief * Configure the address of vector table * * @details * * @note * ******************************************************************************/ static void NVIC_Configuration(void) { #ifdef VECT_TAB_RAM /* Set the Vector Table base location at 0x20000000 */ NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0); #else /* VECT_TAB_FLASH */ /* Set the Vector Table base location at 0x08003000 */ NVIC_SetVectorTable(0x08000000, 0x0); #endif /* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for subpriority */ NVIC_SetPriorityGrouping(NVIC_PriorityGroup_0); /* Set Base Priority Mask Register */ __set_BASEPRI(BSP_BASE_PRI_DEFAULT); }
/***************************************************************************//** * @brief * Configure the address of vector table * * @details * * @note * ******************************************************************************/ static void NVIC_Configuration(void) { #ifdef VECT_TAB_RAM /* Set the vector table allocated at 0x20000000 */ NVIC_SetVectorTable(RAM_MEM_BASE, 0x0); #else /* VECT_TAB_FLASH */ /* Set the vector table allocated at 0x00000000 */ NVIC_SetVectorTable(FLASH_MEM_BASE, 0x0); #endif /* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for subpriority */ NVIC_SetPriorityGrouping(0x7UL); /* Set Base Priority Mask Register */ __set_BASEPRI(EFM32_BASE_PRI_DEFAULT); }
/* Handle SOC specific activity after Low Power Mode Exit */ void _sys_soc_power_state_post_ops(enum power_states state) { switch (state) { case SYS_POWER_STATE_CPU_LPS: case SYS_POWER_STATE_CPU_LPS_1: /* Enable interrupts */ __set_BASEPRI(0); break; #if defined(CONFIG_SYS_POWER_DEEP_SLEEP) case SYS_POWER_STATE_DEEP_SLEEP: break; #endif default: /* Unsupported State */ SYS_LOG_ERR("Unsupported State\n"); break; } }
InterruptMask enableInterruptMasking() { #if CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI != 0 const auto interruptMask = __get_BASEPRI(); constexpr auto basepriValue = CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI << (8 - __NVIC_PRIO_BITS); static_assert(basepriValue > 0 && basepriValue <= UINT8_MAX, "Invalid CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI value!"); __set_BASEPRI(basepriValue); return interruptMask; #else // CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0 const auto interruptMask = __get_PRIMASK(); __disable_irq(); return interruptMask; #endif // CONFIG_ARCHITECTURE_ARMV7_M_KERNEL_BASEPRI == 0 }
/* If FreeRTOS is not running, then we rely on rit service to call this function, * otherwise we rely on FreeRTOS tick hook to provide system timer */ static void hl_periodic_service(void) { const uint32_t timer_ms = sys_get_uptime_ms(); /* If FreeRTOS is running, user should use a dedicated task to call mesh service, * so we will not call it if freertos is running */ if (taskSCHEDULER_RUNNING == xTaskGetSchedulerState()) { m_system_uptime_ms += MS_PER_TICK(); /* We don't need RIT if FreeRTOS is running */ if (sys_rit_running()) { sys_rit_disable(); /* Round up uptime_ms because if ms per tick is 10, then we don't want to * increment this timer by 10 from an odd number because % 10 won't work. */ m_system_uptime_ms = (m_system_uptime_ms / 10) * 10; } } else { m_system_uptime_ms += m_time_per_rit_isr_ms; wireless_service(); /** * Small hack to support interrupts if FreeRTOS is not running : * FreeRTOS API resets our base priority register, then all * interrupts higher priority than IP_SYSCALL will not get locked out. * @see more notes at isr_priorities.h. @see IP_SYSCALL */ __set_BASEPRI(0); } /** * Call SD timer function at 100Hz. * Feed the watchdog too while we're at it. */ if (0 == (timer_ms % 10)) { sd_timerproc(); sys_watchdog_feed(); } }
/** * Initializes the minimal system including CPU Clock, UART, and Flash accelerator * Be careful of the order of the operations!!! */ void low_level_init(void) { rtc_init(); g_rtc_boot_time = rtc_gettime(); /* Configure System Clock based on desired clock rate @ sys_config.h */ sys_clock_configure(); configure_flash_acceleration(sys_get_cpu_clock()); /* Setup default interrupt priorities that will work with FreeRTOS */ configure_interrupt_priorities(); /* These methods shouldn't be needed but doing it anyway to be safe */ NVIC_SetPriorityGrouping(0); __set_BASEPRI(0); __enable_fault_irq(); __enable_irq(); /* Setup UART with minimal I/O functions */ uart0_init(SYS_CFG_UART0_BPS); sys_set_outchar_func(uart0_putchar); sys_set_inchar_func(uart0_getchar); /** * Turn off I/O buffering otherwise sometimes printf/scanf doesn't behave * correctly due to strange buffering and/or flushing effects. */ setvbuf(stdout, 0, _IONBF, 0); setvbuf(stdin, 0, _IONBF, 0); /* Initialize newlib fopen() fread() calls support */ syscalls_init(); /* Enable the watchdog to allow us to recover in an event of system crash */ sys_watchdog_enable(); /* Uart and printf() are initialized, so print our boot-up message */ print_boot_info(); }
/* Note: On ARMv7-M the return_handler is executed in NP mode. */ void debug_deprivilege_and_return(void * debug_handler, void * return_handler, uint32_t a0, uint32_t a1, uint32_t a2, uint32_t a3) { /* Source box: Get the current stack pointer. */ /* Note: The source stack pointer is only used to assess the stack * alignment and to read the xpsr. */ uint32_t src_sp = context_validate_exc_sf(__get_PSP()); /* Destination box: The debug box. */ uint8_t dst_id = g_debug_box.box_id; /* Copy the xPSR from the source exception stack frame. */ uint32_t xpsr = vmpu_unpriv_uint32_read((uint32_t) &((uint32_t *) src_sp)[7]); /* Destination box: Forge the destination stack frame. */ /* Note: We manually have to set the 4 parameters on the destination stack, * so we will set the API to have nargs=0. */ uint32_t dst_sp = context_forge_exc_sf(src_sp, dst_id, (uint32_t) debug_handler, (uint32_t) return_handler, xpsr, 0); ((uint32_t *) dst_sp)[0] = a0; ((uint32_t *) dst_sp)[1] = a1; ((uint32_t *) dst_sp)[2] = a2; ((uint32_t *) dst_sp)[3] = a3; /* Suspend the OS. */ g_priv_sys_hooks.priv_os_suspend(); /* Stop all lower-than-SVC-priority interrupts. FIXME Enable debug box to * do things that require interrupts. One idea would be to provide an SVC * to re-enable interrupts that can only be called by the debug box during * debug handling. */ __set_BASEPRI(__UVISOR_NVIC_MIN_PRIORITY << (8U - __NVIC_PRIO_BITS)); context_switch_in(CONTEXT_SWITCH_FUNCTION_DEBUG, dst_id, src_sp, dst_sp); /* Upon execution return debug_handler will be executed. Upon return from * debug_handler, return_handler will be executed. */ return; }
void HAL_enable_irq(int is) { __set_BASEPRI(is); }
InterruptMask disableInterruptMasking() { const auto interruptMask = __get_BASEPRI(); __set_BASEPRI(0); return interruptMask; }
/*-------------------------------------------------------------------------* * Function: CPUDisableInterrupts *-------------------------------------------------------------------------* * Description: * Disables all standard CPU interrupts (IRQ). *-------------------------------------------------------------------------*/ void CPUDisableInterrupts(void) { __set_BASEPRI(16UL << (8 - 5)); }
byte Synth::play() { static const byte sineQuadrant[128] = { 129, 130, 132, 133, 135, 137, 138, 140, 141, 143, 144, 146, 147, 149, 150, 152, 154, 155, 157, 158, 160, 161, 163, 164, 166, 167, 169, 170, 172, 173, 174, 176, 177, 179, 180, 182, 183, 184, 186, 187, 189, 190, 191, 193, 194, 195, 197, 198, 199, 200, 202, 203, 204, 206, 207, 208, 209, 210, 212, 213, 214, 215, 216, 217, 218, 219, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 230, 231, 232, 233, 234, 235, 236, 237, 237, 238, 239, 240, 240, 241, 242, 242, 243, 244, 244, 245, 246, 246, 247, 247, 248, 248, 249, 249, 250, 250, 251, 251, 251, 252, 252, 252, 253, 253, 253, 254, 254, 254, 254, 254, 254, 255, 255, 255, 255, 255, 255, 255 }; //ensure is off ------------------- TIM_DeInit(TIM2); //some checks --------------------- if( ! warnings) { if(putFrame > theFrames && putFrame[-1].nPulses != 0) { warnings |= MISSING_END_FRAME_WARNING; } if(putFrame < &theFrames[2]) { warnings |= NO_FRAMES_TO_PLAY_WARNING; } } if(warnings) { return warnings; // don't attempt to play dodgy sequences } //start --------------------------- SynthFrame *playFrame; uint16_t pulsesRemaining; U32 amplitude; uint32_t phaseStep; U32 phase; playFrame = theFrames; pulsesRemaining = playFrame->nPulses; amplitude.w[0] = 0; amplitude.w[1] = playFrame->amplitude + 1; phase.u = 384UL << 16; // sine sample is at lowest point (zero) at start of fourth quadrant phaseStep = playFrame->phaseStep; // save interrupt state & turn off all but highest level user interrupts (level 0) // Could alternatively use PRIMASK uint32_t savedInterruptBasePriority = __get_BASEPRI(); __set_BASEPRI(1 << (8 - __NVIC_PRIO_BITS)); // initialise timer // We output on TIM2 channel 1 which uses PA0 const int16_t TOP = 128; RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); pinMode(A0, AF_OUTPUT_PUSHPULL); TIM_TimeBaseInitTypeDef timerInit; timerInit.TIM_Prescaler = 0; // no prescaling run clock at 72MHz. Sets TIM2_PSC register to 0 timerInit.TIM_CounterMode = TIM_CounterMode_CenterAligned1; // count from 0 to Auto Reload Reg. Sets TIM2_CR1 CMS bits to 01 timerInit.TIM_Period = TOP; // Counter re-zeroes at 128 (for period 256): 281,250 Hz. Sets TIM2_ARR to become 128 on update timerInit.TIM_ClockDivision = 0; // not really relevant TIM_TimeBaseInit(TIM2, &timerInit); TIM_OCInitTypeDef outputChannelInit; outputChannelInit.TIM_OCMode = TIM_OCMode_PWM2; // we want PWM, active when count is high (## how is this different from polarity?) outputChannelInit.TIM_OCPolarity = TIM_OCNPolarity_High; // Output is active (high) while counter is high (at (on up) or above TIM2_CCR1) outputChannelInit.TIM_OutputState = TIM_OutputState_Enable; outputChannelInit.TIM_Pulse = 0; //TOP - 0; // Set initial duty cycle. First pulse is 0% to start quietly. TIM2_CCR1 = 128 TIM_OC1Init(TIM2, &outputChannelInit); // init output channel 1 TIM_OC1PreloadConfig(TIM2, TIM_OCPreload_Enable); // TIM2_CCR1 to be buffered so changes take effect at update event (counter reset) //TIM_ARRPreloadConfig(TIM2, ENABLE); // commented as we never change TIM2_ARR from now on // Note URS & UDIS bits in TIM2_CR1 by default allow update events to set TIM_IT_Update flag in TIM2_SR // start timer TIM_Cmd(TIM2, ENABLE); // ensure update flag is clear on entry TIM2->SR = (uint16_t) ~TIM_IT_Update; //loop --------------------------- while(true) { // We want to wait for the TIM_IT_Update bit in TIM2_SR to signal an update event // With up/down counting for centered PWM we get update events at both top and bottom // if its already set then we're late here so store a warning if(TIM2->SR & TIM_IT_Update) { warnings |= LATE_SAMPLE_PULSE_WARNING; } else { // wait for timer to set its update flag when counter next reaches top while((TIM2->SR & TIM_IT_Update) == 0) { } } // now clear the flag; TIM->SR are only cleared on write; they can't be set on write TIM2->SR = (uint16_t) ~TIM_IT_Update; if(TIM2->CR1 & TIM_CR1_DIR) { // only supply next sample when we're counting down (so update occurs at bottom) // One quarter period of sine wave is stored; symmetry is used to obtain other quadrant data byte p = phase.b[2]; byte sample = sineQuadrant[p & 0x80 ? 255 - p : p]; // read table forwards or backwards if(phase.b[3] & 1) { // invert if in second half of wave period sample = 255 - sample; } // if amplitude not maximum (amplitude.w[1] == 256) then reduce sample if(amplitude.b[3] == 0) { sample = (sample * amplitude.b[2]) >> 8; } // set the output compare register which sets the number of clock cycles the output pin will be on for // TIM2_CCR1 is buffered so the actual change occurs at the *next* timer overflow // for TOP = 128, sample range 0..255 must be halved (period is doubled again by symmetry) TIM2->CCR1 = TOP - (sample >> 1); }
/*-------------------------------------------------------------------------* * Function: CPUEnableInterrupts *-------------------------------------------------------------------------* * Description: * Enables all standard CPU interrupts (IRQ). *-------------------------------------------------------------------------*/ void CPUEnableInterrupts(void) { __set_BASEPRI(0UL); }