/*!
 * \brief Software 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_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 SoftwareIrqCtl(int cmd, void *param)
{
    int rc = 0;
    unsigned int *ival = (unsigned int *)param;
    int_fast8_t enabled = inr(AIC_IMR) & _BV(SWIRQ_ID);

    /* Disable interrupt. */
    if (enabled) {
        outr(AIC_IDCR, _BV(SWIRQ_ID));
    }

    switch(cmd) {
    case NUT_IRQCTL_INIT:
        /* Set the vector. */
        outr(AIC_SVR(SWIRQ_ID), (unsigned int)SoftwareIrqEntry);
        /* Initialize to edge triggered with defined priority. */
        outr(AIC_SMR(SWIRQ_ID), AIC_SRCTYPE_INT_EDGE_TRIGGERED | NUT_IRQPRI_SWIRQ);
        /* Clear interrupt */
        outr(AIC_ICCR, _BV(SWIRQ_ID));
        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_GETPRIO:
        *ival = inr(AIC_SMR(SWIRQ_ID)) & AIC_PRIOR;
        break;
    case NUT_IRQCTL_SETPRIO:
        outr(AIC_SMR(SWIRQ_ID), (inr(AIC_SMR(SWIRQ_ID)) & ~AIC_PRIOR) | *ival);
        break;
#ifdef NUT_PERFMON
    case NUT_IRQCTL_GETCOUNT:
        *ival = (unsigned int)sig_SWIRQ.ir_count;
        sig_SWIRQ.ir_count = 0;
        break;
#endif
    default:
        rc = -1;
        break;
    }

    /* Enable interrupt. */
    if (enabled) {
        outr(AIC_IECR, _BV(SWIRQ_ID));
    }
    return rc;
}
Beispiel #2
0
/**
 * Timer couter setup.
 *
 * This function apply to select timer couter all needed settings.
 * Every settings are stored in stepper_timers[].
 */
void stepper_tc_setup(int index, stepper_isr_t callback, struct Stepper *motor)
{
	ASSERT(index < CONFIG_TC_STEPPER_MAX_NUM);

	motor->timer = &stepper_timers[index];

	//Disable PIO controller and enable TIO function
	TIO_PIO_PDR = BV(motor->timer->tio_pin);
	TIO_PIO_ABSR = BV(motor->timer->tio_pin);

	/*
	 * Sets timer counter in waveform mode.
	 * We set as default:
	 * - Waveform mode 00 (see datasheet for more detail.)
	 * - Master clock prescaler to STEPPER_MCK_PRESCALER
	 * - Set none external event
	 * - Clear pin output on comp_reg
	 * - None effect on reg C compare
	 */
	*motor->timer->chl_mode_reg = BV(TC_WAVE);
	*motor->timer->chl_mode_reg |= motor->timer->ext_event_set;
	*motor->timer->chl_mode_reg &= ~TC_WAVSEL_MASK;
	*motor->timer->chl_mode_reg |= TC_WAVSEL_UP;
	*motor->timer->chl_mode_reg |= STEPPER_MCK_PRESCALER;
	*motor->timer->chl_mode_reg |= motor->timer->comp_effect_clear;
	*motor->timer->chl_mode_reg &= ~motor->timer->comp_effect_c_mask;

	//Reset comp_reg and C compare register
	*motor->timer->comp_reg = 0;
	*motor->timer->comp_c_reg = 0;

	//Register interrupt vector
	cpu_flags_t flags;
	IRQ_SAVE_DISABLE(flags);

	/*
	 * Warning: To guarantee a correct management of interrupt event, we must
	 * trig the interrupt on level sensitive. This becouse, we have only a common
	 * line for interrupt request, and if we have at the same time two interrupt
	 * request could be that the is service normaly but the second will never
	 *  been detected and interrupt will stay active but never serviced.
	 */
	AIC_SVR(motor->timer->timer_id) = motor->timer->isr;
	AIC_SMR(motor->timer->timer_id) = AIC_SRCTYPE_INT_LEVEL_SENSITIVE;
	AIC_IECR = BV(motor->timer->timer_id);

	// Disable interrupt on select timer counter
	stepper_tc_irq_disable(motor->timer);

	IRQ_RESTORE(flags);

	//Register callback
	motor->timer->callback = callback;
	motor->timer->motor = motor;
}
Beispiel #3
0
static void __INIT__ at91_aic_init(void)
{
	int irq;

	for(irq = 0; irq < 32; irq++) {
		at91_aic_writel(AIC_SVR(irq), irq);
		at91_aic_writel(AIC_SMR(irq), (0 << 5) | 0);

		irq_assoc_intctl(irq, &at91sam926x_aic_intctrl);
		irq_set_handler(irq, irq_handle_level, 0);
	}

	//	at91_aic_writel(AIC_SPU, MAX_IRQ_NUM);
	//	at91_aic_writel(AIC_DCR, 0);

	//	at91_aic_writel(AIC_IDCR, ~0UL);
	//	at91_aic_writel(AIC_ICCR, ~0UL);
}
Beispiel #4
0
void aic_atmel_init()
{
  int irqno;

  // Disable all interrupts
  outl(0xFFFFFFFF, AIC_IDCR);
  
  // Clear all interrupts
  outl(0xFFFFFFFF, AIC_ICCR);

  for ( irqno = 0 ; irqno < 32 ; irqno++ ) {
    outl(irqno, AIC_EOICR);
  }
  
  for ( irqno = 0 ; irqno < 32 ; irqno++ ) {
    outl((atmel_irq_prtable[irqno] >> 5) | atmel_irq_type[irqno],
	 AIC_SMR(irqno));
  }

  for ( irqno = 0 ; irqno < 32 ; irqno++ ) {
    outl(0, AIC_SVR(irqno));
  }
}
Beispiel #5
0
int eth_init()
{
	cpu_flags_t flags;

	emac_reset();
	emac_start();

	event_initGeneric(&recv_wait);
	event_initGeneric(&send_wait);

	// Register interrupt vector
	IRQ_SAVE_DISABLE(flags);

	/* Disable all emac interrupts */
	EMAC_IDR = 0xFFFFFFFF;

#if CPU_ARM_AT91
	// TODO: define sysirq_set...
	/* Set the vector. */
	AIC_SVR(EMAC_ID) = emac_irqHandler;
	/* Initialize to edge triggered with defined priority. */
	AIC_SMR(EMAC_ID) = AIC_SRCTYPE_INT_EDGE_TRIGGERED;
	/* Clear pending interrupt */
	AIC_ICCR = BV(EMAC_ID);
	/* Enable the system IRQ */
	AIC_IECR = BV(EMAC_ID);
#else
	sysirq_setHandler(INT_EMAC, emac_irqHandler);
#endif

	/* Enable interrupts */
	EMAC_IER = EMAC_RX_INTS | EMAC_TX_INTS;

	IRQ_RESTORE(flags);

	return 0;
}
/*!
 * \brief Timer/Counter 0 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 TimerCounter0IrqCtl(int cmd, void *param)
{
    int rc = 0;
    unsigned int *ival = (unsigned int *)param;
    int_fast8_t enabled = inr(AIC_IMR) & _BV(TC0_ID);

    /* Disable interrupt. */
    if (enabled) {
        outr(AIC_IDCR, _BV(TC0_ID));
    }

    switch(cmd) {
    case NUT_IRQCTL_INIT:
        /* Set the vector. */
        outr(AIC_SVR(TC0_ID), (unsigned int)TimerCounter0IrqEntry);
        /* Initialize to edge triggered with defined priority. */
        outr(AIC_SMR(TC0_ID), AIC_SRCTYPE_INT_EDGE_TRIGGERED | NUT_IRQPRI_TC0);
        /* Clear interrupt */
        outr(AIC_ICCR, _BV(TC0_ID));
        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:
        {
            unsigned int val = inr(AIC_SMR(TC0_ID)) & AIC_SRCTYPE;
            if (val == AIC_SRCTYPE_INT_LEVEL_SENSITIVE || val == AIC_SRCTYPE_EXT_HIGH_LEVEL) {
                *ival = NUT_IRQMODE_LEVEL;
            } else  {
                *ival = NUT_IRQMODE_EDGE;
            }
        }
        break;
    case NUT_IRQCTL_SETMODE:
        if (*ival == NUT_IRQMODE_LEVEL) {
            outr(AIC_SMR(TC0_ID), (inr(AIC_SMR(TC0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_LEVEL_SENSITIVE);
        } else if (*ival == NUT_IRQMODE_EDGE) {
            outr(AIC_SMR(TC0_ID), (inr(AIC_SMR(TC0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_EDGE_TRIGGERED);
        } else  {
            rc = -1;
        }
        break;
    case NUT_IRQCTL_GETPRIO:
        *ival = inr(AIC_SMR(TC0_ID)) & AIC_PRIOR;
        break;
    case NUT_IRQCTL_SETPRIO:
        outr(AIC_SMR(TC0_ID), (inr(AIC_SMR(TC0_ID)) & ~AIC_PRIOR) | *ival);
        break;
#ifdef NUT_PERFMON
    case NUT_IRQCTL_GETCOUNT:
        *ival = (unsigned int)sig_TC0.ir_count;
        sig_TC0.ir_count = 0;
        break;
#endif
    default:
        rc = -1;
        break;
    }

    /* Enable interrupt. */
    if (enabled) {
        outr(AIC_IECR, _BV(TC0_ID));
    }
    return rc;
}
/*!
 * \brief Initialize system timer.
 *
 * This function is automatically called by Nut/OS
 * during system initialization.
 *
 * Nut/OS uses on-chip timer 0 for its timer services.
 * Applications should not modify any registers of this
 * timer, but make use of the Nut/OS timer API. Timer 1
 * and timer 2 are available to applications.
 */
void NutRegisterTimer(void (*handler) (void *))
{
    os_handler = handler;

#if defined(MCU_AT91R40008)

    /* Disable the Clock Counter */
    outr(TC0_CCR, TC_CLKDIS);
    /* Disable all interrupts */
    outr(TC0_IDR, 0xFFFFFFFF);
    /* Clear the status register. */
    dummy = inr(TC0_SR);
    /* Select divider and compare trigger */
    outr(TC0_CMR, TC_CLKS_MCK32 | TC_CPCTRG);
    /* Enable the Clock counter */
    outr(TC0_CCR, TC_CLKEN);
    /* Validate the RC compare interrupt */
    outr(TC0_IER, TC_CPCS);

    /* Disable timer 0 interrupts. */
    outr(AIC_IDCR, _BV(TC0_ID));
    /* Set the TC0 IRQ handler address */
    outr(AIC_SVR(4), (unsigned int)Timer0Entry);
    /* Set the trigg and priority for timer 0 interrupt */
    /* Level 7 is highest, level 0 lowest. */
    outr(AIC_SMR(4), (AIC_SRCTYPE_INT_LEVEL_SENSITIVE | 0x4));
    /* Clear timer 0 interrupt */
    outr(AIC_ICCR, _BV(TC0_ID));
    /* Enable timer 0 interrupts */
    outr(AIC_IECR, _BV(TC0_ID));

    /* Set compare value for 1 ms. */
    outr(TC0_RC, 0x80F);
    /* Software trigger starts the clock. */
    outr(TC0_CCR, TC_SWTRG);

#elif defined(MCU_S3C4510B)

    INT_DISABLE(IRQ_TIMER);
    CSR_WRITE(TCNT0, 0);
    CSR_WRITE(TDATA0, CLOCK_TICK_RATE);
    CSR_WRITE(TMOD, TMOD_TIMER0_VAL);

    CLEAR_PEND_INT(IRQ_TIMER);

    NutRegisterIrqHandler(
        &InterruptHandlers[IRQ_TIMER], handler, 0);

    INT_ENABLE(IRQ_TIMER);

#elif defined(MCU_GBA)

    /* Disable master interrupt. */
    outw(REG_IME, 0);

    /* Set global interrupt vector. */
    NutRegisterIrqHandler(&sig_TMR3, Timer3Entry, 0);

    /* Enable timer and timer interrupts. */
    outdw(REG_TMR3CNT, TMR_IRQ_ENA | TMR_ENA | 48756);

    /* Enable timer 3 interrupts. */
    outw(REG_IE, inw(REG_IE) | INT_TMR3);

    /* Enable master interrupt. */
    outw(REG_IME, 1);

#else
#warning "MCU not defined"
#endif
}
Beispiel #8
0
/*!
 * \brief External interrupt 0 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_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 Interrupt0Ctl(int cmd, void *param)
{
    int rc = 0;
    unsigned int *ival = (unsigned int *)param;
    int_fast8_t enabled = inr(AIC_IMR) & _BV(IRQ0_ID);

    /* Disable interrupt. */
    if (enabled) {
        outr(AIC_IDCR, _BV(IRQ0_ID));
    }

    switch(cmd) {
    case NUT_IRQCTL_INIT:
        /* Set the vector. */
        outr(AIC_SVR(IRQ0_ID), (unsigned int)Interrupt0Entry);
        /* Initialize to edge triggered with defined priority. */
        outr(AIC_SMR(IRQ0_ID), AIC_SRCTYPE_EXT_NEGATIVE_EDGE | NUT_IRQPRI_IRQ0);
        /* Clear interrupt */
        outr(AIC_ICCR, _BV(IRQ0_ID));
        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:
        {
            unsigned int val = inr(AIC_SMR(IRQ0_ID)) & AIC_SRCTYPE;
            if (val == AIC_SRCTYPE_EXT_LOW_LEVEL) {
                *ival = NUT_IRQMODE_LOWLEVEL;
            } else if (val == AIC_SRCTYPE_EXT_HIGH_LEVEL) {
                *ival = NUT_IRQMODE_HIGHLEVEL;
            } else if (val == AIC_SRCTYPE_EXT_POSITIVE_EDGE) {
                *ival = NUT_IRQMODE_RISINGEDGE;
            } else  {
                *ival = NUT_IRQMODE_FALLINGEDGE;
            }
        }
        break;
    case NUT_IRQCTL_SETMODE:
        if (*ival == NUT_IRQMODE_LOWLEVEL) {
            outr(AIC_SMR(IRQ0_ID), (inr(AIC_SMR(IRQ0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_EXT_LOW_LEVEL);
        } else if (*ival == NUT_IRQMODE_HIGHLEVEL) {
            outr(AIC_SMR(IRQ0_ID), (inr(AIC_SMR(IRQ0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_EXT_HIGH_LEVEL);
        } else if (*ival == NUT_IRQMODE_FALLINGEDGE) {
            outr(AIC_SMR(IRQ0_ID), (inr(AIC_SMR(IRQ0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_EXT_NEGATIVE_EDGE);
        } else  if (*ival == NUT_IRQMODE_RISINGEDGE) {
            outr(AIC_SMR(IRQ0_ID), (inr(AIC_SMR(IRQ0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_EXT_POSITIVE_EDGE);
        } else  {
            rc = -1;
        }
        break;
    case NUT_IRQCTL_GETPRIO:
        *ival = inr(AIC_SMR(IRQ0_ID)) & AIC_PRIOR;
        break;
    case NUT_IRQCTL_SETPRIO:
        outr(AIC_SMR(IRQ0_ID), (inr(AIC_SMR(IRQ0_ID)) & ~AIC_PRIOR) | *ival);
        break;
#ifdef NUT_PERFMON
    case NUT_IRQCTL_GETCOUNT:
        *ival = (unsigned int)sig_INTERRUPT0.ir_count;
        sig_INTERRUPT0.ir_count = 0;
        break;
#endif
    default:
        rc = -1;
        break;
    }

    /* Enable interrupt. */
    if (enabled) {
        outr(AIC_IECR, _BV(IRQ0_ID));
#if defined(PMC_PCER)
        outr(PMC_PCER, _BV(IRQ0_ID));
#endif
    }
    return rc;
}