/*! * \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; }
/** * 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; }
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); }
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)); } }
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 }
/*! * \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; }