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 }