BSP430  20141115
Board Support Package for MSP430 microcontrollers
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
bootstrap/button/main.c
#include <bsp430/clock.h>
#if ! (BSP430_PLATFORM_BUTTON0 - 0)
#error No button available on this platform
#endif /* BSP430_PLATFORM_BUTTON0 */
typedef struct sButtonState {
sBSP430halISRIndexedChainNode button_cb; /* Callback structure */
const unsigned char bit; /* Bit for button */
volatile unsigned int in_mask; /* Bit set if button is pressed */
volatile unsigned int count; /* Number of interrupts occured */
} sButtonState;
static int
button_isr_ni (const struct sBSP430halISRIndexedChainNode * cb,
void * context,
int idx)
{
sButtonState * sp = (sButtonState *)cb;
++sp->count;
/* Record whether the button is currently pressed based on the edge
* type we captured (1 means transition to 0 = released, 0 means
* transition to 1 = pressed). Configure to detect a state change
* opposite of the one we just captured, regardless of what that
* state might be. This algorithm coupled with interrupts being
* disabled outside of LPM helps ensure we interleave
* pressed/released notifications even in the presence of
* bounces. */
sp->in_mask = (hpl->ies & sp->bit) ^ sp->bit;
hpl->ies ^= sp->bit;
vBSP430ledSet(0, -1);
/* Wakeup. Whether this clears #GIE depends on
* #configBSP430_CORE_LPM_EXIT_CLEAR_GIE */
}
static sButtonState button_state = {
.button_cb = { .callback_ni = button_isr_ni },
};
void main ()
{
volatile sBSP430hplPORTIE * b0hpl;
cprintf("\nbutton " __DATE__ " " __TIME__ "\n");
cprintf("There's supposed to be a button at %s.%u\n",
b0pin);
if (! b0hal) {
cprintf("Whoops, guess it's not really there\n");
return;
}
button_state.button_cb.next_ni = b0hal->pin_cbchain_ni[b0pin];
b0hal->pin_cbchain_ni[b0pin] = &button_state.button_cb;
#if (BSP430_PORT_SUPPORTS_REN - 0)
#endif /* BSP430_PORT_SUPPORTS_REN */
button_state.in_mask = BSP430_PLATFORM_BUTTON0_PORT_BIT;
} else {
button_state.in_mask = 0;
}
cprintf("Button is configured. Try pressing it. No debouncing is done.\n");
#if ! (configBSP430_CORE_LPM_EXIT_CLEAR_GIE - 0)
cprintf("WARNING: Interrupts remain enabled after wakeup\n");
#endif /* configBSP430_CORE_LPM_EXIT_CLEAR_GIE */
while (1) {
static const char * state_str[] = { "released", "pressed" };
cprintf("Count %u, in mask 0x%02x: %s\n", button_state.count, button_state.in_mask, state_str[!button_state.in_mask]);
/* Note that we've never turned interrupts on, but
* BSP430_CORE_LPM_ENTER_NI() does so internally so the ISR can be
* executed. Whether they are cleared before returning to this
* loop depends on #configBSP430_CORE_LPM_EXIT_CLEAR_GIE. */
#if ! (configBSP430_CORE_LPM_EXIT_CLEAR_GIE - 0)
/* Infrastructure didn't clear this, so we should */
#endif /* configBSP430_CORE_LPM_EXIT_CLEAR_GIE */
}
}