00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00073 #include <dev/irqreg.h>
00074
00079
00080 static int AvrInterrupt3Ctl(int cmd, void *param);
00081
00082 IRQ_HANDLER sig_INTERRUPT3 = {
00083 #ifdef NUT_PERFMON
00084 0,
00085 #endif
00086 NULL,
00087 NULL,
00088 AvrInterrupt3Ctl
00089 };
00090
00108 static int AvrInterrupt3Ctl(int cmd, void *param)
00109 {
00110 int rc = 0;
00111 u_int *ival = (u_int *) param;
00112 int enabled = bit_is_set(EIMSK, INT3);
00113
00114
00115 cbi(EIMSK, INT3);
00116
00117 switch (cmd) {
00118 case NUT_IRQCTL_INIT:
00119 #ifdef __AVR_ENHANCED__
00120
00121 cbi(EICRA, ISC30);
00122 cbi(EICRA, ISC31);
00123 #endif
00124 case NUT_IRQCTL_CLEAR:
00125 #ifdef __AVR_ENHANCED__
00126
00127 outb(EIFR, _BV(INTF3));
00128 #endif
00129 break;
00130 case NUT_IRQCTL_STATUS:
00131 #ifdef __AVR_ENHANCED__
00132 if (bit_is_set(EIFR, INTF3)) {
00133 *ival = 1;
00134 } else {
00135 *ival = 0;
00136 }
00137 #else
00138 *ival = 0;
00139 #endif
00140 if (enabled) {
00141 *ival |= 0x80;
00142 }
00143 break;
00144 case NUT_IRQCTL_ENABLE:
00145 enabled = 1;
00146 break;
00147 case NUT_IRQCTL_DISABLE:
00148 enabled = 0;
00149 break;
00150 case NUT_IRQCTL_GETMODE:
00151 #ifdef __AVR_ENHANCED__
00152 {
00153 u_char bval = inb(EICRA) & (_BV(ISC31) | _BV(ISC30));
00154 if (bval == _BV(ISC31)) {
00155 *ival = NUT_IRQMODE_FALLINGEDGE;
00156 } else if (bval == _BV(ISC31 | ISC30)) {
00157 *ival = NUT_IRQMODE_RISINGEDGE;
00158 } else {
00159 *ival = NUT_IRQMODE_LOWLEVEL;
00160 }
00161 }
00162 #else
00163 *ival = NUT_IRQMODE_LOWLEVEL;
00164 #endif
00165 break;
00166 case NUT_IRQCTL_SETMODE:
00167 #ifdef __AVR_ENHANCED__
00168 if (*ival == NUT_IRQMODE_LOWLEVEL) {
00169 cbi(EICRA, ISC30);
00170 cbi(EICRA, ISC31);
00171 } else if (*ival == NUT_IRQMODE_FALLINGEDGE) {
00172 cbi(EICRA, ISC30);
00173 sbi(EICRA, ISC31);
00174 } else if (*ival == NUT_IRQMODE_RISINGEDGE) {
00175 sbi(EICRA, ISC30);
00176 sbi(EICRA, ISC31);
00177 } else {
00178 rc = -1;
00179 }
00180 #else
00181 if (*ival != NUT_IRQMODE_LOWLEVEL) {
00182 rc = -1;
00183 }
00184 #endif
00185 break;
00186 case NUT_IRQCTL_GETPRIO:
00187 *ival = 3;
00188 break;
00189 #ifdef NUT_PERFMON
00190 case NUT_IRQCTL_GETCOUNT:
00191 *ival = (u_int) sig_INTERRUPT3.ir_count;
00192 sig_INTERRUPT3.ir_count = 0;
00193 break;
00194 #endif
00195 default:
00196 rc = -1;
00197 break;
00198 }
00199
00200
00201 if (enabled) {
00202 sbi(EIMSK, INT3);
00203 }
00204 return rc;
00205 }
00206
00210 #ifdef __IMAGECRAFT__
00211 #pragma interrupt_handler SIG_INTERRUPT3:iv_INT3
00212 #endif
00213 NUTSIGNAL(SIG_INTERRUPT3, sig_INTERRUPT3)
00214
00215