/*! * \brief RTC interrupt control. * * \param cmd Control command. * - NUT_IRQCTL_INIT Initialize and disable interrupt. * - NUT_IRQCTL_STATUS Query interrupt status. * - NUT_IRQCTL_ENABLE Enable interrupt. * - NUT_IRQCTL_DISABLE Disable interrupt. * - NUT_IRQCTL_GETMODE Query interrupt mode. * - NUT_IRQCTL_SETMODE Set interrupt mode (NUT_IRQMODE_LEVEL or NUT_IRQMODE_EDGE). * - NUT_IRQCTL_GETPRIO Query interrupt priority. * - NUT_IRQCTL_SETPRIO Set interrupt priority. * - NUT_IRQCTL_GETCOUNT Query and clear interrupt counter. * \param param Pointer to optional parameter. * * \return 0 on success, -1 otherwise. */ static int RtcIrqCtl(int cmd, void *param) { int rc = 0; uint32_t *ival = (uint32_t *)param; int enabled = NVIC_GetEnableIRQ(RTC_IRQn); /* Disable interrupt. */ if (enabled) { NVIC_DisableIRQ(RTC_IRQn); } switch(cmd) { case NUT_IRQCTL_INIT: /* Set the vector. */ Cortex_RegisterInt(RTC_IRQn, RtcIrqEntry); /* Initialize with defined priority. */ NVIC_SetPriority(RTC_IRQn, NUT_IRQPRI_RTC); /* Clear interrupt */ NVIC_ClearPendingIRQ(RTC_IRQn); break; case NUT_IRQCTL_STATUS: if (enabled) { *ival |= 1; } else { *ival &= ~1; } break; case NUT_IRQCTL_ENABLE: enabled = 1; break; case NUT_IRQCTL_DISABLE: enabled = 0; break; case NUT_IRQCTL_GETMODE: *ival = NUT_IRQMODE_EDGE; break; case NUT_IRQCTL_SETMODE: rc = -1; break; case NUT_IRQCTL_GETPRIO: *ival = NVIC_GetPriority(RTC_IRQn); break; case NUT_IRQCTL_SETPRIO: NVIC_SetPriority(RTC_IRQn, *ival); break; #ifdef NUT_PERFMON case NUT_IRQCTL_GETCOUNT: *ival = (uint32_t)sig_RTC.ir_count; sig_RTC.ir_count = 0; break; #endif default: rc = -1; break; } /* Enable interrupt. */ if (enabled) { NVIC_EnableIRQ(RTC_IRQn); } return rc; }
/** \brief Test case: TC_CoreFunc_EnDisIRQ \details Check expected behavior of interrupt related control functions: - __disable_irq() and __enable_irq() - NVIC_EnableIRQ, NVIC_DisableIRQ, and NVIC_GetEnableIRQ - NVIC_SetPendingIRQ, NVIC_ClearPendingIRQ, and NVIC_GetPendingIRQ - NVIC_GetActive (not on Cortex-M0/M0+) */ void TC_CoreFunc_EnDisIRQ (void) { // Globally disable all interrupt servicing __disable_irq(); // Enable the interrupt NVIC_EnableIRQ(WDT_IRQn); ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) != 0U); // Clear its pending state NVIC_ClearPendingIRQ(WDT_IRQn); ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U); // Register test interrupt handler. TST_IRQHandler = TC_CoreFunc_EnDisIRQIRQHandler; irqTaken = 0U; #if defined(__CORTEX_M) && (__CORTEX_M > 0) irqActive = UINT32_MAX; #endif // Set the interrupt pending state NVIC_SetPendingIRQ(WDT_IRQn); for(uint32_t i = 10U; i > 0U; --i) {} // Interrupt is not taken ASSERT_TRUE(irqTaken == 0U); ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U); #if defined(__CORTEX_M) && (__CORTEX_M > 0) ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U); #endif // Globally enable interrupt servicing __enable_irq(); for(uint32_t i = 10U; i > 0U; --i) {} // Interrupt was taken ASSERT_TRUE(irqTaken == 1U); #if defined(__CORTEX_M) && (__CORTEX_M > 0) ASSERT_TRUE(irqActive != 0U); ASSERT_TRUE(NVIC_GetActive(WDT_IRQn) == 0U); #endif // Interrupt it not pending anymore. ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U); // Disable interrupt NVIC_DisableIRQ(WDT_IRQn); ASSERT_TRUE(NVIC_GetEnableIRQ(WDT_IRQn) == 0U); // Set interrupt pending NVIC_SetPendingIRQ(WDT_IRQn); for(uint32_t i = 10U; i > 0U; --i) {} // Interrupt is not taken again ASSERT_TRUE(irqTaken == 1U); ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) != 0U); // Clear interrupt pending NVIC_ClearPendingIRQ(WDT_IRQn); for(uint32_t i = 10U; i > 0U; --i) {} // Interrupt it not pending anymore. ASSERT_TRUE(NVIC_GetPendingIRQ(WDT_IRQn) == 0U); // Globally disable interrupt servicing __disable_irq(); }
static int TwoWireIrqCtl(IRQn_Type IRQn, void(*ifunc)(void*), int cmd, void *param) #endif { int rc = 0; unsigned int *ival = (unsigned int *)param; uint_fast8_t enabled = NVIC_GetEnableIRQ(IRQn); /* Disable interrupt. */ if (enabled) { NVIC_DisableIRQ(IRQn); } switch(cmd) { case NUT_IRQCTL_INIT: /* Set the vector. */ Cortex_RegisterInt(IRQn, ifunc); /* Initialize Event IRQ with defined priority. */ NVIC_SetPriority(IRQn, NUT_IRQPRI_TWI); /* Clear interrupt */ NVIC_ClearPendingIRQ(IRQn); break; case NUT_IRQCTL_STATUS: if (enabled) { *ival |= 1; } else { *ival &= ~1; } break; case NUT_IRQCTL_ENABLE: enabled = 1; break; case NUT_IRQCTL_DISABLE: enabled = 0; break; case NUT_IRQCTL_GETMODE: *ival = NUT_IRQMODE_LEVEL; break; case NUT_IRQCTL_SETMODE: break; case NUT_IRQCTL_GETPRIO: *ival = NVIC_GetPriority(IRQn); break; case NUT_IRQCTL_SETPRIO: NVIC_SetPriority(IRQn, *ival); break; #ifdef NUT_PERFMON case NUT_IRQCTL_GETCOUNT: *ival = (unsigned int)ih->ir_count; ih->ir_count = 0; break; #endif default: rc = -1; break; } /* Enable interrupt. */ if (enabled) { NVIC_EnableIRQ(IRQn); } return rc; }