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