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
00060 #include <cfg/os.h>
00061 #include <cfg/clock.h>
00062 #include <arch/arm.h>
00063 #include <dev/irqreg.h>
00064
00065 #include <sys/event.h>
00066 #include <sys/timer.h>
00067
00068 #include "buttons.h"
00069
00106 #if defined(AT91SAM7X_EK)
00107
00108 #define BTN_TC_ID TC1_ID
00109 #define BTN_PIO_ID PIOB_ID
00110 #define BTN_DOWN_BIT 27
00111
00112 #define BTN_UP_BIT 29
00113
00114 #elif defined(AT91SAM9260_EK)
00115
00116 #define BTN_TC_ID TC1_ID
00117 #define BTN_PIO_ID PIOB_ID
00118 #define BTN_DOWN_BIT 8
00119 #define BTN_SELECT_BIT 9
00120 #define BTN_UP_BIT 10
00121
00122 #elif defined(ELEKTOR_IR1)
00123
00124 #define BTN_TC_ID TC1_ID
00125 #define BTN_PIO_ID PIOB_ID
00126 #define BTN_DOWN_BIT 24
00127 #define BTN_SELECT_BIT 25
00128 #define BTN_UP_BIT 26
00129 #endif
00130
00131 #ifndef BTN_SCAN_FREQ
00132
00135 #define BTN_SCAN_FREQ 128UL
00136 #endif
00137
00138 #ifndef BTN_REPEAT_FIRST
00139
00142 #define BTN_REPEAT_FIRST 100
00143 #endif
00144
00145 #ifndef BTN_REPEAT_NEXT
00146
00149 #define BTN_REPEAT_NEXT 25
00150 #endif
00151
00173 #if BTN_PIO_ID == PIOB_ID
00174 #define BTN_PIO_PE_REG PIOB_PER
00175 #define BTN_PIO_OD_REG PIOB_ODR
00176 #define BTN_PIO_PDS_REG PIOB_PDSR
00177 #define BTN_PIO_PUE_REG PIOB_PUER
00178 #elif BTN_PIO_ID == PIOA_ID
00179 #define BTN_PIO_PE_REG PIOA_PER
00180 #define BTN_PIO_OD_REG PIOA_ODR
00181 #define BTN_PIO_PDS_REG PIOA_PDSR
00182 #define BTN_PIO_PUE_REG PIOA_PUER
00183 #elif BTN_PIO_ID == PIOC_ID
00184 #define BTN_PIO_PE_REG PIOC_PER
00185 #define BTN_PIO_OD_REG PIOC_ODR
00186 #define BTN_PIO_PDS_REG PIOC_PDSR
00187 #define BTN_PIO_PUE_REG PIOC_PUER
00188 #else
00189 #define BTN_PIO_PE_REG PIO_PER
00190 #define BTN_PIO_OD_REG PIO_ODR
00191 #define BTN_PIO_PDS_REG PIO_PDSR
00192 #define BTN_PIO_PUE_REG PIO_PUER
00193 #endif
00194
00196 #ifdef BTN_SELECT_BIT
00197 #define BTN_SELECT _BV(BTN_SELECT_BIT)
00198 #else
00199 #define BTN_SELECT 0
00200 #endif
00201
00203 #ifdef BTN_UP_BIT
00204 #define BTN_UP _BV(BTN_UP_BIT)
00205 #else
00206 #define BTN_UP 0
00207 #endif
00208
00210 #ifdef BTN_DOWN_BIT
00211 #define BTN_DOWN _BV(BTN_DOWN_BIT)
00212 #else
00213 #define BTN_DOWN 0
00214 #endif
00215
00253 #if BTN_TC_ID == TC1_ID
00254 #define sig_BTN_TC sig_TC1
00255 #define BTN_TC_CC_REG TC1_CCR
00256 #define BTN_TC_CM_REG TC1_CMR
00257 #define BTN_TC_IE_REG TC1_IER
00258 #define BTN_TC_ID_REG TC1_IDR
00259 #define BTN_TC_S_REG TC1_SR
00260 #define BTN_TC_RC_REG TC1_RC
00261 #elif BTN_TC_ID == TC2_ID
00262 #define sig_BTN_TC sig_TC2
00263 #define BTN_TC_CC_REG TC2_CCR
00264 #define BTN_TC_CM_REG TC2_CMR
00265 #define BTN_TC_IE_REG TC2_IER
00266 #define BTN_TC_ID_REG TC2_IDR
00267 #define BTN_TC_S_REG TC2_SR
00268 #define BTN_TC_RC_REG TC2_RC
00269 #endif
00270
00278 static HANDLE btn_que;
00279
00286 static volatile u_int btn_pressed;
00287
00288 #if USE_BUTTONS
00289
00292 static void ScanTimerInterrupt(void *arg)
00293 {
00294 static u_int btn_prev;
00295 static u_int btn_repeat;
00296 u_int btn_code;
00297
00298
00299 btn_code = ~inr(BTN_PIO_PDS_REG) & (BTN_DOWN | BTN_SELECT | BTN_UP);
00300 if (btn_code) {
00301
00302 if (btn_code != btn_prev) {
00303
00304 btn_pressed = btn_code;
00305 NutEventPostFromIrq(&btn_que);
00306
00307 btn_repeat = BTN_REPEAT_FIRST;
00308 }
00309 else if (btn_repeat == 0) {
00310
00311
00312 NutEventPostFromIrq(&btn_que);
00313
00314 btn_repeat = BTN_REPEAT_NEXT;
00315 }
00316 else {
00317
00318 btn_repeat--;
00319 }
00320 }
00321
00322
00323 btn_prev = btn_code;
00324 }
00325 #endif
00326
00336 void ButtonInit(void)
00337 {
00338 #if USE_BUTTONS
00339 int dummy;
00340
00341
00342 outr(PMC_PCER, _BV(BTN_TC_ID) | _BV(BTN_PIO_ID));
00343
00344 outr(BTN_TC_CC_REG, TC_CLKDIS);
00345
00346 outr(BTN_TC_ID_REG, 0xFFFFFFFF);
00347
00348 dummy = inr(BTN_TC_S_REG);
00349
00350 outr(BTN_TC_CM_REG, TC_CLKS_MCK32 | TC_CPCTRG);
00351
00352 outr(BTN_TC_CC_REG, TC_CLKEN);
00353
00354 outr(BTN_TC_IE_REG, TC_CPCS);
00355
00356
00357 NutRegisterIrqHandler(&sig_BTN_TC, ScanTimerInterrupt, 0);
00358
00359 NutIrqSetPriority(&sig_BTN_TC, 0);
00360
00361
00362 NutIrqEnable(&sig_BTN_TC);
00363
00364
00365 #if defined(AT91_PLL_MAINCK)
00366 outr(BTN_TC_RC_REG, At91GetMasterClock() / (32 * BTN_SCAN_FREQ));
00367 #else
00368 outr(BTN_TC_RC_REG, NutGetCpuClock() / (32 * BTN_SCAN_FREQ));
00369 #endif
00370
00371
00372 outr(BTN_PIO_PE_REG, BTN_SELECT | BTN_UP | BTN_DOWN);
00373 outr(BTN_PIO_OD_REG, BTN_SELECT | BTN_UP | BTN_DOWN);
00374 outr(BTN_PIO_PUE_REG, BTN_SELECT | BTN_UP | BTN_DOWN);
00375
00376
00377 outr(BTN_TC_CC_REG, TC_SWTRG);
00378 #endif
00379 }
00380
00394 char ButtonRead(u_long tmo)
00395 {
00396
00397 if (NutEventWait(&btn_que, tmo) == 0) {
00398
00399 u_int pressed = btn_pressed;
00400
00401 if (pressed & BTN_SELECT) {
00402 return KEYCODE_SELECT;
00403 }
00404 if (pressed & BTN_DOWN) {
00405 return KEYCODE_DOWN;
00406 }
00407 if (pressed & BTN_UP) {
00408 return KEYCODE_UP;
00409 }
00410 }
00411 return 0;
00412 }