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
00051 #include <cfg/os.h>
00052 #include <cfg/clock.h>
00053 #include <arch/arm.h>
00054 #include <dev/irqreg.h>
00055
00056 #include <sys/event.h>
00057 #include <sys/timer.h>
00058
00059 #include "buttons.h"
00060
00097 #if defined(AT91SAM7X_EK)
00098 #define BTN_TC_ID TC1_ID
00099 #define BTN_PIO_ID PIOB_ID
00100 #define BTN_DOWN_BIT 27
00101
00102 #define BTN_UP_BIT 29
00103 #elif defined(AT91SAM9260_EK)
00104 #define BTN_TC_ID TC1_ID
00105 #define BTN_PIO_ID PIOB_ID
00106 #define BTN_DOWN_BIT 8
00107 #define BTN_SELECT_BIT 9
00108 #define BTN_UP_BIT 10
00109 #endif
00110
00111 #ifndef BTN_SCAN_FREQ
00112
00115 #define BTN_SCAN_FREQ 128UL
00116 #endif
00117
00118 #ifndef BTN_REPEAT_FIRST
00119
00122 #define BTN_REPEAT_FIRST 100
00123 #endif
00124
00125 #ifndef BTN_REPEAT_NEXT
00126
00129 #define BTN_REPEAT_NEXT 25
00130 #endif
00131
00153 #if BTN_PIO_ID == PIOB_ID
00154 #define BTN_PIO_PE_REG PIOB_PER
00155 #define BTN_PIO_OD_REG PIOB_ODR
00156 #define BTN_PIO_PDS_REG PIOB_PDSR
00157 #define BTN_PIO_PUE_REG PIOB_PUER
00158 #elif BTN_PIO_ID == PIOA_ID
00159 #define BTN_PIO_PE_REG PIOA_PER
00160 #define BTN_PIO_OD_REG PIOA_ODR
00161 #define BTN_PIO_PDS_REG PIOA_PDSR
00162 #define BTN_PIO_PUE_REG PIOA_PUER
00163 #elif BTN_PIO_ID == PIOC_ID
00164 #define BTN_PIO_PE_REG PIOC_PER
00165 #define BTN_PIO_OD_REG PIOC_ODR
00166 #define BTN_PIO_PDS_REG PIOC_PDSR
00167 #define BTN_PIO_PUE_REG PIOC_PUER
00168 #else
00169 #define BTN_PIO_PE_REG PIO_PER
00170 #define BTN_PIO_OD_REG PIO_ODR
00171 #define BTN_PIO_PDS_REG PIO_PDSR
00172 #define BTN_PIO_PUE_REG PIO_PUER
00173 #endif
00174
00176 #ifdef BTN_SELECT_BIT
00177 #define BTN_SELECT _BV(BTN_SELECT_BIT)
00178 #else
00179 #define BTN_SELECT 0
00180 #endif
00181
00183 #ifdef BTN_UP_BIT
00184 #define BTN_UP _BV(BTN_UP_BIT)
00185 #else
00186 #define BTN_UP 0
00187 #endif
00188
00190 #ifdef BTN_DOWN_BIT
00191 #define BTN_DOWN _BV(BTN_DOWN_BIT)
00192 #else
00193 #define BTN_DOWN 0
00194 #endif
00195
00233 #if BTN_TC_ID == TC1_ID
00234 #define sig_BTN_TC sig_TC1
00235 #define BTN_TC_CC_REG TC1_CCR
00236 #define BTN_TC_CM_REG TC1_CMR
00237 #define BTN_TC_IE_REG TC1_IER
00238 #define BTN_TC_ID_REG TC1_IDR
00239 #define BTN_TC_S_REG TC1_SR
00240 #define BTN_TC_RC_REG TC1_RC
00241 #elif BTN_TC_ID == TC2_ID
00242 #define sig_BTN_TC sig_TC2
00243 #define BTN_TC_CC_REG TC2_CCR
00244 #define BTN_TC_CM_REG TC2_CMR
00245 #define BTN_TC_IE_REG TC2_IER
00246 #define BTN_TC_ID_REG TC2_IDR
00247 #define BTN_TC_S_REG TC2_SR
00248 #define BTN_TC_RC_REG TC2_RC
00249 #endif
00250
00258 static HANDLE btn_que;
00259
00266 static volatile u_int btn_pressed;
00267
00271 static void ScanTimerInterrupt(void *arg)
00272 {
00273 static u_int btn_prev;
00274 static u_int btn_repeat;
00275 u_int btn_code;
00276
00277
00278 btn_code = ~inr(BTN_PIO_PDS_REG) & (BTN_DOWN | BTN_SELECT | BTN_UP);
00279 if (btn_code) {
00280
00281 if (btn_code != btn_prev) {
00282
00283 btn_pressed = btn_code;
00284 NutEventPostFromIrq(&btn_que);
00285
00286 btn_repeat = BTN_REPEAT_FIRST;
00287 }
00288 else if (btn_repeat == 0) {
00289
00290
00291 NutEventPostFromIrq(&btn_que);
00292
00293 btn_repeat = BTN_REPEAT_NEXT;
00294 }
00295 else {
00296
00297 btn_repeat--;
00298 }
00299 }
00300
00301
00302 btn_prev = btn_code;
00303 }
00304
00314 void ButtonInit(void)
00315 {
00316 int dummy;
00317
00318
00319 outr(PMC_PCER, _BV(BTN_TC_ID) | _BV(BTN_PIO_ID));
00320
00321 outr(BTN_TC_CC_REG, TC_CLKDIS);
00322
00323 outr(BTN_TC_ID_REG, 0xFFFFFFFF);
00324
00325 dummy = inr(BTN_TC_S_REG);
00326
00327 outr(BTN_TC_CM_REG, TC_CLKS_MCK32 | TC_CPCTRG);
00328
00329 outr(BTN_TC_CC_REG, TC_CLKEN);
00330
00331 outr(BTN_TC_IE_REG, TC_CPCS);
00332
00333
00334 NutRegisterIrqHandler(&sig_BTN_TC, ScanTimerInterrupt, 0);
00335
00336 NutIrqSetPriority(&sig_BTN_TC, 0);
00337
00338
00339 NutIrqEnable(&sig_BTN_TC);
00340
00341
00342 #if defined(AT91_PLL_MAINCK)
00343 outr(BTN_TC_RC_REG, At91GetMasterClock() / (32 * BTN_SCAN_FREQ));
00344 #else
00345 outr(BTN_TC_RC_REG, NutGetCpuClock() / (32 * BTN_SCAN_FREQ));
00346 #endif
00347
00348
00349 outr(BTN_PIO_PE_REG, BTN_SELECT | BTN_UP | BTN_DOWN);
00350 outr(BTN_PIO_OD_REG, BTN_SELECT | BTN_UP | BTN_DOWN);
00351 outr(BTN_PIO_PUE_REG, BTN_SELECT | BTN_UP | BTN_DOWN);
00352
00353
00354 outr(BTN_TC_CC_REG, TC_SWTRG);
00355 }
00356
00370 char ButtonRead(u_long tmo)
00371 {
00372
00373 if (NutEventWait(&btn_que, tmo) == 0) {
00374
00375 u_int pressed = btn_pressed;
00376
00377 if (pressed & BTN_SELECT) {
00378 return KEYCODE_SELECT;
00379 }
00380 if (pressed & BTN_DOWN) {
00381 return KEYCODE_DOWN;
00382 }
00383 if (pressed & BTN_UP) {
00384 return KEYCODE_UP;
00385 }
00386 }
00387 return 0;
00388 }