00001 00036 /* 00037 * $Log: ih_tc0.c,v $ 00038 * 00039 */ 00040 00041 #include <arch/avr32.h> 00042 #include <dev/irqreg.h> 00043 00044 #ifndef NUT_IRQPRI_TC0 00045 #define NUT_IRQPRI_TC0 0 00046 #endif 00047 00048 #define CHANNEL 0 00049 00050 static int TimerCounter0IrqCtl(int cmd, void *param); 00051 00052 IRQ_HANDLER sig_TC0 = { 00053 #ifdef NUT_PERFMON 00054 0, /* Interrupt counter, ir_count. */ 00055 #endif 00056 NULL, /* Passed argument, ir_arg. */ 00057 NULL, /* Handler subroutine, ir_handler. */ 00058 TimerCounter0IrqCtl /* Interrupt control, ir_ctl. */ 00059 }; 00060 00078 static int TimerCounter0IrqCtl(int cmd, void *param) 00079 { 00080 int rc = 0; 00081 unsigned int *ival = (unsigned int *) param; 00082 int_fast8_t enabled = inr(AIC_IMR) & _BV(TC0_ID); 00083 00084 /* Disable interrupt. */ 00085 if (enabled) { 00086 AVR32_TC.channel[CHANNEL].sr; 00087 } 00088 00089 switch (cmd) { 00090 case NUT_IRQCTL_INIT: 00091 // GENERATE SIGNALS: Waveform operating mode. 00092 AVR32_TC.channel[CHANNEL].cmr = AVR32_TC_NONE << AVR32_TC_BSWTRG_OFFSET | 00093 AVR32_TC_NONE << AVR32_TC_BEEVT_OFFSET | 00094 AVR32_TC_NONE << AVR32_TC_BCPC_OFFSET | 00095 AVR32_TC_NONE << AVR32_TC_BCPB_OFFSET | 00096 AVR32_TC_NONE << AVR32_TC_ASWTRG_OFFSET | 00097 AVR32_TC_NONE << AVR32_TC_AEEVT_OFFSET | 00098 AVR32_TC_NONE << AVR32_TC_ACPC_OFFSET | 00099 AVR32_TC_NONE << AVR32_TC_ACPA_OFFSET | 00100 1 << AVR32_TC_WAVE_OFFSET | 00101 AVR32_TC_WAVSEL_UP_AUTO << AVR32_TC_WAVSEL_OFFSET | 00102 0 << AVR32_TC_ENETRG_OFFSET | 00103 0 << AVR32_TC_EEVT_OFFSET | 00104 AVR32_TC_EEVTEDG_NO_EDGE << AVR32_TC_EEVTEDG_OFFSET | 00105 0 << AVR32_TC_CPCDIS_OFFSET | 00106 0 << AVR32_TC_CPCSTOP_OFFSET | 00107 0 << AVR32_TC_BURST_OFFSET | 0 << AVR32_TC_CLKI_OFFSET | AVR32_TC_TCCLKS_TIMER_CLOCK3 << AVR32_TC_TCCLKS_OFFSET; 00108 00109 00110 00111 break; 00112 case NUT_IRQCTL_STATUS: 00113 if (enabled) { 00114 *ival |= 1; 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(TC0_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(TC0_ID), (inr(AIC_SMR(TC0_ID)) & ~AIC_SRCTYPE) | AIC_SRCTYPE_INT_LEVEL_SENSITIVE); 00138 } else if (*ival == NUT_IRQMODE_EDGE) { 00139 outr(AIC_SMR(TC0_ID), (inr(AIC_SMR(TC0_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(TC0_ID)) & AIC_PRIOR; 00146 break; 00147 case NUT_IRQCTL_SETPRIO: 00148 outr(AIC_SMR(TC0_ID), (inr(AIC_SMR(TC0_ID)) & ~AIC_PRIOR) | *ival); 00149 break; 00150 #ifdef NUT_PERFMON 00151 case NUT_IRQCTL_GETCOUNT: 00152 *ival = (unsigned int) sig_TC0.ir_count; 00153 sig_TC0.ir_count = 0; 00154 break; 00155 #endif 00156 default: 00157 rc = -1; 00158 break; 00159 } 00160 00161 /* Enable interrupt. */ 00162 if (enabled) { 00163 outr(AIC_IECR, _BV(TC0_ID)); 00164 } 00165 return rc; 00166 }