Handles 3 toggle switches connected to 3 dedicated GPIO lines. It is expected, that the port pin is driven low when the related button is pressed.
Auto repeat is supported.
* * $Log$ * *
Definition in file buttons.c.
#include <cfg/os.h>
#include <cfg/clock.h>
#include <arch/arm.h>
#include <dev/irqreg.h>
#include <sys/event.h>
#include <sys/timer.h>
#include "buttons.h"
Include dependency graph for buttons.c:
Go to the source code of this file.
Defines | |
#define | BTN_TC_ID TC1_ID |
Button scan timer ID. | |
#define | BTN_PIO_ID PIOB_ID |
PIO ID of the button interface. | |
#define | BTN_DOWN_BIT 8 |
PIO bit number of the button labeled DOWN. | |
#define | BTN_SELECT_BIT 9 |
PIO bit number of the button labeled SELECT. | |
#define | BTN_UP_BIT 10 |
PIO bit number of the button labeled UP. | |
#define | BTN_SCAN_FREQ 128UL |
Number of button scans per second. | |
#define | BTN_REPEAT_FIRST 100 |
Number of scans until the first repeat is triggered. | |
#define | BTN_REPEAT_NEXT 25 |
Number of scans until all following repeats are triggered. | |
#define | BTN_PIO_PE_REG PIOB_PER |
PIO enable register of the button interface. | |
#define | BTN_PIO_OD_REG PIOB_ODR |
PIO output disable register of the button interface. | |
#define | BTN_PIO_PDS_REG PIOB_PDSR |
Pin data status register of the button interface. | |
#define | BTN_PIO_PUE_REG PIOB_PUER |
Pull-up enable register of the button interface. | |
#define | BTN_SELECT _BV(BTN_SELECT_BIT) |
PIO bit mask of the SELECT button. | |
#define | BTN_UP _BV(BTN_UP_BIT) |
PIO bit mask of the UP button. | |
#define | BTN_DOWN _BV(BTN_DOWN_BIT) |
PIO bit mask of the DOWN button. | |
#define | sig_BTN_TC sig_TC1 |
Interrupt signal of the button scan timer. | |
#define | BTN_TC_CC_REG TC1_CCR |
Channel control register of the button scan timer. | |
#define | BTN_TC_CM_REG TC1_CMR |
Channel mode register of the button scan timer. | |
#define | BTN_TC_IE_REG TC1_IER |
Interrupt enable register of the button scan timer. | |
#define | BTN_TC_ID_REG TC1_IDR |
Interrupt disable register of the button scan timer. | |
#define | BTN_TC_S_REG TC1_SR |
Status register of the button scan timer. | |
#define | BTN_TC_RC_REG TC1_RC |
Register C of the button scan timer. | |
Functions | |
static void | ScanTimerInterrupt (void *arg) |
Button scan timer interrupt handler. | |
void | ButtonInit (void) |
Initialize the button interface. | |
char | ButtonRead (u_long tmo) |
Wait until the user pressed a button. | |
Variables | |
static HANDLE | btn_que |
Button event queue. | |
static volatile u_int | btn_pressed |
Last button code. |
|
Button scan timer ID. Specifies the timer/counter that will be used to generate periodical interrupts for scanning the buttons. |
|
PIO ID of the button interface. All buttons must be connected to the same PIO port. |
|
PIO bit number of the button labeled DOWN. This button is used to reduce the volume or move to the previous menu item. If not specified, this button will not be available. |
|
PIO bit number of the button labeled SELECT. This button is used to enter menu mode or to select the currently displayed menu item. If not specified, this button will not be available. |
|
PIO bit number of the button labeled UP. This button is used to increase the volume or move to the next menu item. If not specified, this button will not be available. |
|
Number of button scans per second.
|
|
Number of scans until the first repeat is triggered.
|
|
Number of scans until all following repeats are triggered.
|
|
PIO enable register of the button interface. The compiler evaluates BTN_PIO_ID to determine this register. |
|
PIO output disable register of the button interface. The compiler evaluates BTN_PIO_ID to determine this register. |
|
Pin data status register of the button interface. The compiler evaluates BTN_PIO_ID to determine this register. |
|
Pull-up enable register of the button interface. The compiler evaluates BTN_PIO_ID to determine this register. |
|
PIO bit mask of the SELECT button.
|
|
PIO bit mask of the UP button.
|
|
PIO bit mask of the DOWN button.
|
|
Interrupt signal of the button scan timer. The compiler evaluates BTN_TC_ID to determine the Nut/OS interrupt signal. |
|
Channel control register of the button scan timer. The compiler evaluates BTN_TC_ID to determine this register. |
|
Channel mode register of the button scan timer. The compiler evaluates BTN_TC_ID to determine this register. |
|
Interrupt enable register of the button scan timer. The compiler evaluates BTN_TC_ID to determine this register. |
|
Interrupt disable register of the button scan timer. The compiler evaluates BTN_TC_ID to determine this register. |
|
Status register of the button scan timer. The compiler evaluates BTN_TC_ID to determine this register. |
|
Register C of the button scan timer. The compiler evaluates BTN_TC_ID to determine this register. |
|
Button scan timer interrupt handler.
Definition at line 270 of file buttons.c. 00272 { 00273 static u_int btn_prev; 00274 static u_int btn_repeat; 00275 u_int btn_code; 00276 00277 /* Read the negated GPIO line status. Pressing a button drives the pin low. */ 00278 btn_code = ~inr(BTN_PIO_PDS_REG) & (BTN_DOWN | BTN_SELECT | BTN_UP); 00279 if (btn_code) { 00280 /* A button has been or still is pressed. */ 00281 if (btn_code != btn_prev) { 00282 /* This is a new button. Immediately post an event. */ 00283 btn_pressed = btn_code; 00284 NutEventPostFromIrq(&btn_que); 00285 /* Initialize the repeat rate. */ 00286 btn_repeat = BTN_REPEAT_FIRST; 00287 } 00288 else if (btn_repeat == 0) { 00289 /* Button is still pressed and the repeat time elapsed. 00290 Post a new event. */ 00291 NutEventPostFromIrq(&btn_que); 00292 /* Re-initialize the repeat rate. */ 00293 btn_repeat = BTN_REPEAT_NEXT; 00294 } 00295 else { 00296 /* Button is still pressed. Wait until repeat time elapses. */ 00297 btn_repeat--; 00298 } 00299 } 00300 /* Keep the last code, so we are able to distinguish whether the user 00301 is still pressing the same or selected a new button. */ 00302 btn_prev = btn_code;
|
|
Initialize the button interface. Configures and starts a continously running timer interrupt, which scans three GPIO lines. A low level on any line indicates, that the related button has been pressed by the user. The application must call ButtonRead() to read the code of a pressed button. Definition at line 313 of file buttons.c. 00315 { 00316 int dummy; 00317 00318 /* Enable scan timer clock. */ 00319 outr(PMC_PCER, _BV(BTN_TC_ID) | _BV(BTN_PIO_ID)); 00320 /* Disable the Clock Counter */ 00321 outr(BTN_TC_CC_REG, TC_CLKDIS); 00322 /* Disable all interrupts */ 00323 outr(BTN_TC_ID_REG, 0xFFFFFFFF); 00324 /* Clear the status register. */ 00325 dummy = inr(BTN_TC_S_REG); 00326 /* Select divider and compare trigger */ 00327 outr(BTN_TC_CM_REG, TC_CLKS_MCK32 | TC_CPCTRG); 00328 /* Enable the Clock counter */ 00329 outr(BTN_TC_CC_REG, TC_CLKEN); 00330 /* Validate the RC compare interrupt */ 00331 outr(BTN_TC_IE_REG, TC_CPCS); 00332 00333 /* Register timer interrupt handler. */ 00334 NutRegisterIrqHandler(&sig_BTN_TC, ScanTimerInterrupt, 0); 00335 /* Set to lowest priority. */ 00336 NutIrqSetPriority(&sig_BTN_TC, 0); 00337 00338 /* Enable timer interrupts */ 00339 NutIrqEnable(&sig_BTN_TC); 00340 00341 /* Set compare value for specified scan frequency. */ 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 /* Initialize GPIO lines for buttons. */ 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 /* Software trigger starts the scan timer. */ 00354 outr(BTN_TC_CC_REG, TC_SWTRG);
|
|
Wait until the user pressed a button. This routine will not handle concurrently pressed buttons, but return the button with the highest priority. SELECT has the highest and UP has the lowest priority.
Definition at line 369 of file buttons.c. 00371 { 00372 /* Wait for a button event from the interrupt handler. */ 00373 if (NutEventWait(&btn_que, tmo) == 0) { 00374 /* Copy the volatile value to a local variable. */ 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;
|
|
Button event queue. The button scan timer interrupt handler will post an event to this queue whenever a new button had been pressed or the repeat timer elapses with a button still pressed. |
|
Last button code. For each button that had been pressed during the last scan interrupt, the related bit BTN_SELECT, BTN_DOWN or BTN_UP is set. |