Go to the documentation of this file.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
00034
00035
00036
00037
00038 #include <arch/arm.h>
00039 #include <dev/irqreg.h>
00040
00041 #if defined(PIOA_ID)
00042
00043 #ifndef NUT_IRQPRI_PIOA
00044 #define NUT_IRQPRI_PIOA 4
00045 #endif
00046
00047 static int PortIoIrqCtl(int cmd, void *param);
00048
00049 IRQ_HANDLER sig_PIOA = {
00050 #ifdef NUT_PERFMON
00051 0,
00052 #endif
00053 NULL,
00054 NULL,
00055 PortIoIrqCtl
00056 };
00057
00061 static void PortIoIrqEntry(void) __attribute__ ((naked));
00062 void PortIoIrqEntry(void)
00063 {
00064 IRQ_ENTRY();
00065 #ifdef NUT_PERFMON
00066 sig_PIOA.ir_count++;
00067 #endif
00068 if (sig_PIOA.ir_handler) {
00069 (sig_PIOA.ir_handler) (sig_PIOA.ir_arg);
00070 }
00071 IRQ_EXIT();
00072 }
00073
00091 static int PortIoIrqCtl(int cmd, void *param)
00092 {
00093 int rc = 0;
00094 unsigned int *ival = (unsigned int *)param;
00095 int_fast8_t enabled = inr(AIC_IMR) & _BV(PIOA_ID);
00096
00097
00098 if (enabled) {
00099 outr(AIC_IDCR, _BV(PIOA_ID));
00100 }
00101
00102 switch(cmd) {
00103 case NUT_IRQCTL_INIT:
00104
00105 outr(AIC_SVR(PIOA_ID), (unsigned int)PortIoIrqEntry);
00106
00107 outr(AIC_SMR(PIOA_ID), AIC_SRCTYPE_INT_EDGE_TRIGGERED | NUT_IRQPRI_PIOA);
00108
00109 outr(AIC_ICCR, _BV(PIOA_ID));
00110 break;
00111 case NUT_IRQCTL_STATUS:
00112 if (enabled) {
00113 *ival |= 1;
00114 }
00115 else {
00116 *ival &= ~1;
00117 }
00118 break;
00119 case NUT_IRQCTL_ENABLE:
00120 enabled = 1;
00121 break;
00122 case NUT_IRQCTL_DISABLE:
00123 enabled = 0;
00124 break;
00125 case NUT_IRQCTL_GETMODE:
00126 {
00127 unsigned int val = inr(AIC_SMR(PIOA_ID)) & AIC_SRCTYPE;
00128 if (val == AIC_SRCTYPE_INT_LEVEL_SENSITIVE || val == AIC_SRCTYPE_EXT_HIGH_LEVEL) {
00129 *ival = NUT_IRQMODE_LEVEL;
00130 } else {
00131 *ival = NUT_IRQMODE_EDGE;
00132 }
00133 }
00134 break;
00135 case NUT_IRQCTL_SETMODE:
00136 if (*ival == NUT_IRQMODE_LEVEL) {
00137 outr(AIC_SMR(PIOA_ID), (inr(AIC_SMR(PIOA_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_LEVEL_SENSITIVE);
00138 } else if (*ival == NUT_IRQMODE_EDGE) {
00139 outr(AIC_SMR(PIOA_ID), (inr(AIC_SMR(PIOA_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_EDGE_TRIGGERED);
00140 } else {
00141 rc = -1;
00142 }
00143 break;
00144 case NUT_IRQCTL_GETPRIO:
00145 *ival = inr(AIC_SMR(PIOA_ID)) & AIC_PRIOR;
00146 break;
00147 case NUT_IRQCTL_SETPRIO:
00148 outr(AIC_SMR(PIOA_ID), (inr(AIC_SMR(PIOA_ID)) & ~AIC_PRIOR) | *ival);
00149 break;
00150 #ifdef NUT_PERFMON
00151 case NUT_IRQCTL_GETCOUNT:
00152 *ival = (unsigned int)sig_PIOA.ir_count;
00153 sig_PIOA.ir_count = 0;
00154 break;
00155 #endif
00156 default:
00157 rc = -1;
00158 break;
00159 }
00160
00161
00162 if (enabled) {
00163 outr(AIC_IECR, _BV(PIOA_ID));
00164 }
00165 return rc;
00166 }
00167
00168 #endif