/** \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 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(); }
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; }
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 }
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 }
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 }
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(); }
//packet received from DSC complete interrupt -> send new packet to DSC void DMA1_Stream5_IRQHandler() { //check if this is correct interrupt if (DMA_GetITStatus( DMA1_Stream5, DMA_IT_TCIF5 ) == SET) { volatile int a,b; a=__get_BASEPRI(); b=__get_PRIMASK(); //clear interrupt flag to avoid repeating interrupts DMA_ClearITPendingBit( DMA1_Stream5, DMA_IT_TCIF5 ); portBASE_TYPE xYieldRequired = pdFALSE; /* Unblock the task by releasing the semaphore. */ xSemaphoreGiveFromISR( MCCommTaskSemaphore, &xYieldRequired ); //must be called because we're at ISR portEND_SWITCHING_ISR( xYieldRequired ); } }
InterruptMask disableInterruptMasking() { const auto interruptMask = __get_BASEPRI(); __set_BASEPRI(0); return interruptMask; }
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); }