Пример #1
0
/*!
 * \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;
}
Пример #2
0
/**
\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();
}
Пример #3
0
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;
}