Go to the documentation of this file.00001
00036
00037
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 static int InterruptNMICtl(int cmd, void *param);
00051
00052 IRQ_HANDLER sig_INTERRUPTNMI = {
00053 #ifdef NUT_PERFMON
00054 0,
00055 #endif
00056 NULL,
00057 NULL,
00058 InterruptNMICtl
00059 };
00060
00064 SIGNAL(InterruptNMIEntry)
00065 {
00066
00067
00068
00069
00070
00071
00072 __asm__ __volatile__("pushm r0-r12, lr");
00073
00074 #ifdef NUT_PERFMON
00075 sig_INTERRUPTNMI.ir_count++;
00076 #endif
00077 if (sig_INTERRUPTNMI.ir_handler) {
00078 (sig_INTERRUPTNMI.ir_handler) (sig_INTERRUPTNMI.ir_arg);
00079 }
00080
00081
00082 AVR32_EIC.icr = AVR32_EIC_ICR_NMI_MASK;
00083 AVR32_EIC.isr;
00084
00085 __asm__ __volatile__("popm r0-r12,lr");
00086 }
00087
00101 static int InterruptNMICtl(int cmd, void *param)
00102 {
00103 int rc = 0;
00104 unsigned int *ival = (unsigned int *) param;
00105 int_fast8_t enabled = AVR32_EIC.imr & AVR32_EIC_IMR_NMI_MASK;
00106
00107
00108 if (enabled) {
00109 AVR32_EIC.idr = AVR32_EIC_IDR_NMI_MASK;
00110 AVR32_EIC.imr;
00111 }
00112
00113 switch (cmd) {
00114 case NUT_IRQCTL_INIT:
00115
00116 gpio_enable_module_pin(AVR32_EIC_EXTINT_8_PIN, AVR32_EIC_EXTINT_8_FUNCTION);
00117
00118
00119 AVR32_EIC.mode &= ~AVR32_EIC_MODE_NMI_MASK;
00120
00121
00122 AVR32_EIC.icr = AVR32_EIC_ICR_NMI_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_NMI_MASK) {
00140 if (AVR32_EIC.level & AVR32_EIC_LEVEL_NMI_MASK)
00141 *ival = NUT_IRQMODE_HIGHLEVEL;
00142 else
00143 *ival = NUT_IRQMODE_LOWLEVEL;
00144 } else {
00145 if (AVR32_EIC.edge & AVR32_EIC_EDGE_NMI_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_NMI_MASK;
00155 AVR32_EIC.level &= ~AVR32_EIC_LEVEL_NMI_MASK;
00156 } else if (*ival == NUT_IRQMODE_HIGHLEVEL) {
00157 AVR32_EIC.mode |= AVR32_EIC_MODE_NMI_MASK;
00158 AVR32_EIC.level |= ~AVR32_EIC_LEVEL_NMI_MASK;
00159 } else if (*ival == NUT_IRQMODE_FALLINGEDGE) {
00160 AVR32_EIC.mode &= ~AVR32_EIC_MODE_NMI_MASK;
00161 AVR32_EIC.edge &= ~AVR32_EIC_EDGE_NMI_MASK;
00162 } else if (*ival == NUT_IRQMODE_RISINGEDGE) {
00163 AVR32_EIC.mode &= ~AVR32_EIC_MODE_NMI_MASK;
00164 AVR32_EIC.edge |= ~AVR32_EIC_EDGE_NMI_MASK;
00165 } else {
00166 rc = -1;
00167 }
00168 break;
00169 #ifdef NUT_PERFMON
00170 case NUT_IRQCTL_GETCOUNT:
00171 *ival = (unsigned int) sig_INTERRUPTNMI.ir_count;
00172 sig_INTERRUPTNMI.ir_count = 0;
00173 break;
00174 #endif
00175 default:
00176 rc = -1;
00177 break;
00178 }
00179
00180
00181 if (enabled) {
00182 AVR32_EIC.ier = AVR32_EIC_IER_NMI_MASK;
00183 AVR32_EIC.imr;
00184 AVR32_EIC.en |= AVR32_EIC_EN_NMI_MASK;
00185 }
00186 return rc;
00187 }