Nut/OS  4.10.3
API Reference
ih_irq0.c
Go to the documentation of this file.
00001 
00035 /*
00036  * $Log: ih_irq0.c,v $
00037  *
00038  */
00039 
00040 #include <arch/avr32.h>
00041 #include <dev/irqreg.h>
00042 #include <dev/gpio.h>
00043 
00044 #include <arch/avr32/gpio.h>
00045 #include <arch/avr32/ihndlr.h>
00046 
00047 #include <avr32/io.h>
00048 
00049 #ifdef AVR32_EIC_IRQ_0
00050 
00051 #ifndef NUT_IRQPRI_IRQ0
00052 #define NUT_IRQPRI_IRQ0  AVR32_INTC_INT3
00053 #endif
00054 
00055 static int Interrupt0Ctl(int cmd, void *param);
00056 
00057 IRQ_HANDLER sig_INTERRUPT0 = {
00058 #ifdef NUT_PERFMON
00059     0,                          /* Interrupt counter, ir_count. */
00060 #endif
00061     NULL,                       /* Passed argument, ir_arg. */
00062     NULL,                       /* Handler subroutine, ir_handler. */
00063     Interrupt0Ctl               /* Interrupt control, ir_ctl. */
00064 };
00065 
00069 static SIGNAL(Interrupt0Entry)
00070 {
00071     IRQ_ENTRY();
00072 #ifdef NUT_PERFMON
00073     sig_INTERRUPT0.ir_count++;
00074 #endif
00075     if (sig_INTERRUPT0.ir_handler) {
00076         (sig_INTERRUPT0.ir_handler) (sig_INTERRUPT0.ir_arg);
00077     }
00078     /* Clear interrupt */
00079     AVR32_EIC.icr = AVR32_EIC_ICR_INT0_MASK;
00080     AVR32_EIC.isr;
00081 
00082     IRQ_EXIT();
00083 }
00084 
00099 static int Interrupt0Ctl(int cmd, void *param)
00100 {
00101     int rc = 0;
00102     unsigned int *ival = (unsigned int *) param;
00103     int_fast8_t enabled = AVR32_EIC.imr & AVR32_EIC_IMR_INT0_MASK;
00104 
00105     /* Disable interrupt. */
00106     if (enabled) {
00107         AVR32_EIC.idr = AVR32_EIC_IDR_INT0_MASK;
00108         AVR32_EIC.imr;
00109     }
00110 
00111     switch (cmd) {
00112     case NUT_IRQCTL_INIT:
00113 #if defined(AVR32_EIC_EXTINT_0_PIN)
00114         /* Setup Peripheral mux for interrupt line */
00115         gpio_enable_module_pin(AVR32_EIC_EXTINT_0_PIN, AVR32_EIC_EXTINT_0_FUNCTION);
00116 #endif
00117         /* Set the vector. */
00118         register_interrupt(Interrupt0Entry, AVR32_EIC_IRQ_0, NUT_IRQPRI_IRQ0);
00119         /* Initialize to edge triggered with defined priority. */
00120         AVR32_EIC.mode &= ~AVR32_EIC_MODE_INT0_MASK;
00121         /* Clear interrupt */
00122         AVR32_EIC.icr = AVR32_EIC_ICR_INT0_MASK;
00123         break;
00124     case NUT_IRQCTL_STATUS:
00125         if (enabled) {
00126             *ival |= 1;
00127         } else {
00128             *ival &= ~1;
00129         }
00130         break;
00131     case NUT_IRQCTL_ENABLE:
00132         enabled = 1;
00133         break;
00134     case NUT_IRQCTL_DISABLE:
00135         enabled = 0;
00136         break;
00137     case NUT_IRQCTL_GETMODE:
00138         {
00139             if (AVR32_EIC.mode & AVR32_EIC_MODE_INT0_MASK) {
00140                 if (AVR32_EIC.level & AVR32_EIC_LEVEL_INT0_MASK)
00141                     *ival = NUT_IRQMODE_HIGHLEVEL;
00142                 else
00143                     *ival = NUT_IRQMODE_LOWLEVEL;
00144             } else {
00145                 if (AVR32_EIC.edge & AVR32_EIC_EDGE_INT0_MASK)
00146                     *ival = NUT_IRQMODE_RISINGEDGE;
00147                 else
00148                     *ival = NUT_IRQMODE_FALLINGEDGE;
00149             }
00150         }
00151         break;
00152     case NUT_IRQCTL_SETMODE:
00153         if (*ival == NUT_IRQMODE_LOWLEVEL) {
00154             AVR32_EIC.mode |= AVR32_EIC_MODE_INT0_MASK;
00155             AVR32_EIC.level &= ~AVR32_EIC_LEVEL_INT0_MASK;
00156         } else if (*ival == NUT_IRQMODE_HIGHLEVEL) {
00157             AVR32_EIC.mode |= AVR32_EIC_MODE_INT0_MASK;
00158             AVR32_EIC.level |= ~AVR32_EIC_LEVEL_INT0_MASK;
00159         } else if (*ival == NUT_IRQMODE_FALLINGEDGE) {
00160             AVR32_EIC.mode &= ~AVR32_EIC_MODE_INT0_MASK;
00161             AVR32_EIC.edge &= ~AVR32_EIC_EDGE_INT0_MASK;
00162         } else if (*ival == NUT_IRQMODE_RISINGEDGE) {
00163             AVR32_EIC.mode &= ~AVR32_EIC_MODE_INT0_MASK;
00164             AVR32_EIC.edge |= ~AVR32_EIC_EDGE_INT0_MASK;
00165         } else {
00166             rc = -1;
00167         }
00168         break;
00169     case NUT_IRQCTL_GETPRIO:
00170         *ival = NUT_IRQPRI_IRQ0;
00171         break;
00172 #ifdef NUT_PERFMON
00173     case NUT_IRQCTL_GETCOUNT:
00174         *ival = (unsigned int) sig_INTERRUPT0.ir_count;
00175         sig_INTERRUPT0.ir_count = 0;
00176         break;
00177 #endif
00178     default:
00179         rc = -1;
00180         break;
00181     }
00182 
00183     /* Enable interrupt. */
00184     if (enabled) {
00185         AVR32_EIC.ier = AVR32_EIC_IER_INT0_MASK;
00186         AVR32_EIC.imr;
00187 #if !defined( __AVR32_AP7000__ )
00188         AVR32_EIC.en |= AVR32_EIC_EN_INT0_MASK;
00189 #endif
00190     }
00191     return rc;
00192 }
00193 
00194 #endif // AVR32_EIC_IRQ_1