Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

buttons.c File Reference


Detailed Description

Simple button interface.

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.


Define Documentation

#define BTN_TC_ID   TC1_ID
 

Button scan timer ID.

Specifies the timer/counter that will be used to generate periodical interrupts for scanning the buttons.

Definition at line 103 of file buttons.c.

#define BTN_PIO_ID   PIOB_ID
 

PIO ID of the button interface.

All buttons must be connected to the same PIO port.

Definition at line 104 of file buttons.c.

#define BTN_DOWN_BIT   8
 

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.

Definition at line 105 of file buttons.c.

#define BTN_SELECT_BIT   9
 

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.

Definition at line 106 of file buttons.c.

#define BTN_UP_BIT   10
 

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.

Definition at line 107 of file buttons.c.

#define BTN_SCAN_FREQ   128UL
 

Number of button scans per second.

Definition at line 114 of file buttons.c.

#define BTN_REPEAT_FIRST   100
 

Number of scans until the first repeat is triggered.

Definition at line 121 of file buttons.c.

#define BTN_REPEAT_NEXT   25
 

Number of scans until all following repeats are triggered.

Definition at line 128 of file buttons.c.

#define BTN_PIO_PE_REG   PIOB_PER
 

PIO enable register of the button interface.

The compiler evaluates BTN_PIO_ID to determine this register.

Definition at line 153 of file buttons.c.

#define BTN_PIO_OD_REG   PIOB_ODR
 

PIO output disable register of the button interface.

The compiler evaluates BTN_PIO_ID to determine this register.

Definition at line 154 of file buttons.c.

#define BTN_PIO_PDS_REG   PIOB_PDSR
 

Pin data status register of the button interface.

The compiler evaluates BTN_PIO_ID to determine this register.

Definition at line 155 of file buttons.c.

#define BTN_PIO_PUE_REG   PIOB_PUER
 

Pull-up enable register of the button interface.

The compiler evaluates BTN_PIO_ID to determine this register.

Definition at line 156 of file buttons.c.

#define BTN_SELECT   _BV(BTN_SELECT_BIT)
 

PIO bit mask of the SELECT button.

Definition at line 176 of file buttons.c.

#define BTN_UP   _BV(BTN_UP_BIT)
 

PIO bit mask of the UP button.

Definition at line 183 of file buttons.c.

#define BTN_DOWN   _BV(BTN_DOWN_BIT)
 

PIO bit mask of the DOWN button.

Definition at line 190 of file buttons.c.

#define sig_BTN_TC   sig_TC1
 

Interrupt signal of the button scan timer.

The compiler evaluates BTN_TC_ID to determine the Nut/OS interrupt signal.

Definition at line 233 of file buttons.c.

#define BTN_TC_CC_REG   TC1_CCR
 

Channel control register of the button scan timer.

The compiler evaluates BTN_TC_ID to determine this register.

Definition at line 234 of file buttons.c.

#define BTN_TC_CM_REG   TC1_CMR
 

Channel mode register of the button scan timer.

The compiler evaluates BTN_TC_ID to determine this register.

Definition at line 235 of file buttons.c.

#define BTN_TC_IE_REG   TC1_IER
 

Interrupt enable register of the button scan timer.

The compiler evaluates BTN_TC_ID to determine this register.

Definition at line 236 of file buttons.c.

#define BTN_TC_ID_REG   TC1_IDR
 

Interrupt disable register of the button scan timer.

The compiler evaluates BTN_TC_ID to determine this register.

Definition at line 237 of file buttons.c.

#define BTN_TC_S_REG   TC1_SR
 

Status register of the button scan timer.

The compiler evaluates BTN_TC_ID to determine this register.

Definition at line 238 of file buttons.c.

#define BTN_TC_RC_REG   TC1_RC
 

Register C of the button scan timer.

The compiler evaluates BTN_TC_ID to determine this register.

Definition at line 239 of file buttons.c.


Function Documentation

static void ScanTimerInterrupt void *  arg  )  [static]
 

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;

void ButtonInit void   ) 
 

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);

char ButtonRead u_long  tmo  ) 
 

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.

Parameters:
tmo Maximum number of milliseconds to wait.
Returns:
Key code of the button, either KEYCODE_SELECT, KEYCODE_DOWN or KEYCODE_UP. If no button had been pressed within the given time, then zero is returned.

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;


Variable Documentation

HANDLE btn_que [static]
 

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.

Definition at line 257 of file buttons.c.

volatile u_int btn_pressed [static]
 

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.

Definition at line 265 of file buttons.c.


Generated on Fri Feb 23 17:28:49 2007 for SAM Internet Radio by  doxygen 1.4.4