You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
145 lines
4.0 KiB
145 lines
4.0 KiB
/** @file navswitch.c
|
|
@author M.P. Hayes
|
|
@date 28 Aug 2008
|
|
@brief Navswitch driver.
|
|
@note This polls the 5-way navigation switch
|
|
but does not do debouncing.
|
|
*/
|
|
|
|
#include "system.h"
|
|
#include "navswitch.h"
|
|
#include "delay.h"
|
|
#include "pio.h"
|
|
|
|
|
|
/* Navswitch configuration structure. */
|
|
typedef struct
|
|
{
|
|
pio_t pio;
|
|
} navswitch_cfg_t;
|
|
|
|
|
|
/** Navswitch state structure. */
|
|
typedef struct
|
|
{
|
|
bool current;
|
|
bool previous;
|
|
} navswitch_state_t;
|
|
|
|
|
|
/* Define navswitch PIO connections. */
|
|
static const navswitch_cfg_t navswitch_cfg[] =
|
|
{
|
|
{NAVSWITCH_NORTH_PIO},
|
|
{NAVSWITCH_EAST_PIO},
|
|
{NAVSWITCH_SOUTH_PIO},
|
|
{NAVSWITCH_WEST_PIO},
|
|
{NAVSWITCH_PUSH_PIO}
|
|
};
|
|
|
|
#define NAVSWITCH_NUM ARRAY_SIZE (navswitch_cfg)
|
|
|
|
static navswitch_state_t navswitch_state[NAVSWITCH_NUM];
|
|
|
|
|
|
/** Return true if navswitch state changed from up to down since
|
|
last call to navswitch_update
|
|
@param navswitch index of navswitch to select
|
|
@return 1 if navswitch changed from up to down otherwise 0 */
|
|
bool
|
|
navswitch_push_event_p (uint8_t navswitch)
|
|
{
|
|
return navswitch_state[navswitch].current
|
|
&& !navswitch_state[navswitch].previous;
|
|
}
|
|
|
|
|
|
/** Return true if navswitch state changed from down to up since
|
|
last call to navswitch_update
|
|
@param navswitch index of navswitch to select
|
|
@return 1 if navswitch changed from down to up otherwise 0 */
|
|
bool
|
|
navswitch_release_event_p (uint8_t navswitch)
|
|
{
|
|
return !navswitch_state[navswitch].current
|
|
&& navswitch_state[navswitch].previous;
|
|
}
|
|
|
|
|
|
/** Return true if navswitch down (pushed).
|
|
@param navswitch index of navswitch to select
|
|
@return 1 if navswitch down otherwise 0 */
|
|
bool
|
|
navswitch_down_p (uint8_t navswitch)
|
|
{
|
|
return navswitch_state[navswitch].current;
|
|
}
|
|
|
|
|
|
/** Return true if navswitch up (released).
|
|
@param navswitch index of navswitch to select
|
|
@return 1 if navswitch down otherwise 0 */
|
|
bool
|
|
navswitch_up_p (uint8_t navswitch)
|
|
{
|
|
return !navswitch_state[navswitch].current;
|
|
}
|
|
|
|
|
|
/** Poll all the navswitches and update their state. */
|
|
void
|
|
navswitch_update (void)
|
|
{
|
|
uint8_t i;
|
|
|
|
/* The switch is a 5-way navigation switch with push. The common
|
|
connection is connected to ground. The 5 switch outputs share
|
|
the LED matrix display column drive pins so we need to save the
|
|
state of the column outputs, switch them to inputs, read the
|
|
switch states, switch them back to outputs, and restore the
|
|
output state.
|
|
|
|
When a switch is pushed it will pull its associated PIO pin low
|
|
via a 2.2 kohm resistor. When the PIO pin is configured as an
|
|
input with pullup, pushing the switch will also turn on the
|
|
column MOSFET driver. This will cause some ghosting of the
|
|
display. This can be avoided by driving all the LED matrix
|
|
rows low while we read the switches. */
|
|
|
|
for (i = 0; i < NAVSWITCH_NUM; i++)
|
|
{
|
|
pio_config_t config;
|
|
|
|
navswitch_state[i].previous = navswitch_state[i].current;
|
|
|
|
config = pio_config_get (navswitch_cfg[i].pio);
|
|
|
|
/* Momentarily force PIO pin high to charge gate capacitance of
|
|
MOSFET otherwise will always read logic low and think the
|
|
switch is pushed. Alternatively, we need to wait 10 us or
|
|
more so that the gate capacitance of the MOSFET charges via
|
|
the internal pullup resistor. */
|
|
pio_config_set (navswitch_cfg[i].pio, PIO_OUTPUT_HIGH);
|
|
|
|
/* Switch PIO to an input to read switch. */
|
|
pio_config_set (navswitch_cfg[i].pio, PIO_PULLUP);
|
|
|
|
/* Wait long enough for MOSFET gate capacitance to discharge
|
|
through 2.2 kohm resistor when switch is pushed (connected
|
|
to ground). */
|
|
DELAY_US (2.5);
|
|
|
|
navswitch_state[i].current = pio_input_get (navswitch_cfg[i].pio) == 0;
|
|
|
|
/* Restore PIO state. */
|
|
pio_config_set (navswitch_cfg[i].pio, config);
|
|
}
|
|
}
|
|
|
|
|
|
/** Initialise navswitch driver. */
|
|
void navswitch_init (void)
|
|
{
|
|
/* Nothing to do since we configure PIOs when polling the switch. */
|
|
}
|