Swadge 2024 2.0.0
APIs to develop games for the Magfest Swadge
Loading...
Searching...
No Matches
hdw-btn.h File Reference

Detailed Description

Design Philosophy

This component handles both push-buttons and touch-pads. Push-buttons are physical, tactile buttons while touch-pads are touch-sensitive areas on the PCB. Events from push-buttons and touch-pads are processed different ways.

The Swadge mode needs to call checkButtonQueueWrapper(), which calls checkButtonQueue() to receive queued button events. The reason for checkButtonQueueWrapper() is so that the main loop can monitor the button which can be held down to return to the main menu. The event contains which button caused the event, whether it was pressed or released, and the current state of all buttons. This way the Swadge mode is not responsible for high frequency button polling, and can still receive all button inputs.

The individual touch-pads are only represented as a single, larger, circular analog touchpad which reports touches in polar coordinates.

Pushbutton Design Philosophy

The push-buttons are polled continuously at 1ms intervals in an interrupt, but these readings are not reported to the Swadge modes. The interrupt saves the prior DEBOUNCE_HIST_LEN polled button states and the last reported button state. When all DEBOUNCE_HIST_LEN button states are identical, the interrupt accepts the current state and checks if it different than the last reported state. If there is a difference, the button event is queued in the interrupt to be received by the Swadge mode.

The push-button GPIOs are all read at the same time using Dedicated GPIO.

Originally the push-buttons would trigger an interrupt, but we found that to have less reliable results with more glitches than polling.

Button events used to be delivered to the Swadge mode via a callback. This led to cases where multiple callbacks would occur between a single invocation of that mode's main function. Because the Swadge mode didn't have a separate queue for button events, this caused events to be dropped. Instead of forcing each mode to queue button events, now each mode must dequeue them rather than having a callback called.

Touch-pad Design Philosophy

Unlike push-buttons, the touch-pads are treated as a single circular area (not discrete touch areas) and are not polled. Events like touches are not queued to be processed later. The individual Swadge mode must poll the current touch state with getTouchJoystick(). The touch state reports the polar coordinates of the touch (angle and radius) as well as the intensity of the touch.

Touch-pad areas are set up and read with Touch Sensor.

Usage

You don't need to call initButtons() or deinitButtons(). The system does at the appropriate times.

You do need to call checkButtonQueueWrapper() and should do so in a while-loop to receive all events since the last check. This should be done in the Swadge mode's main function.

You may call getTouchJoystick() to get the analog touch position. This is independent of checkButtonQueueWrapper(). Three utility functions are provided to interpret touch data different ways.

  • getTouchJoystickZones() is available to translate the analog touches into a four, five, eight, or nine-way virtual directional pad.
  • getTouchSpins() is available to count the number of times the touch joystick was circled around.
  • getTouchCartesian() is available to translate the polar coordinates of the touch into the Cartesian X-Y plane

Example

// Check all queued button events
{
// Print the current event
printf("state: %04X, button: %d, down: %s\n",
evt.state, evt.button, evt.down ? "down" : "up");
}
// Check if the touch area is touched, and print values if it is
int32_t phi, r, intensity;
if (getTouchJoystick(&phi, &r, &intensity))
{
printf("touch center: %" PRIu32 ", intensity: %" PRIu32 ", intensity %" PRIu32 "\n", phi, r, intensity);
}
else
{
printf("no touch\n");
}
int getTouchJoystick(int32_t *phi, int32_t *r, int32_t *intensity)
Get high-level touch input, an analog input. NOTE: You must have touch callbacks enabled to use this.
Definition hdw-btn.c:464
buttonBit_t button
The button that caused this event.
Definition hdw-btn.h:119
bool down
True if the button was pressed, false if it was released.
Definition hdw-btn.h:120
uint16_t state
A bitmask for the state of all buttons.
Definition hdw-btn.h:118
A button event containing the button that triggered the event, whether it was pressed or released,...
Definition hdw-btn.h:117
bool checkButtonQueueWrapper(buttonEvt_t *evt)
Service the queue of button events that caused interrupts This only returns a single event,...
Definition swadge2024.c:740

Go to the source code of this file.

Data Structures

struct  buttonEvt_t
 A button event containing the button that triggered the event, whether it was pressed or released, and the whole button state. More...
 

Enumerations

enum  buttonBit_t {
  PB_UP = 0x0001 , PB_DOWN = 0x0002 , PB_LEFT = 0x0004 , PB_RIGHT = 0x0008 ,
  PB_A = 0x0010 , PB_B = 0x0020 , PB_START = 0x0040 , PB_SELECT = 0x0080
}
 Bitmask values for all the different buttons. More...
 

Functions

void initButtons (gpio_num_t *pushButtons, uint8_t numPushButtons, touch_pad_t *touchPads, uint8_t numTouchPads)
 Initialize both pushbuttons and touch buttons.
 
void deinitButtons (void)
 Free memory used by the buttons.
 
bool checkButtonQueue (buttonEvt_t *)
 Service the queue of button events that caused interrupts This only returns a single event, even if there are multiple in the queue This function may be called multiple times in a row to completely empty the queue.
 
int getTouchJoystick (int32_t *phi, int32_t *r, int32_t *intensity)
 Get high-level touch input, an analog input. NOTE: You must have touch callbacks enabled to use this.
 

Data Structure Documentation

◆ buttonEvt_t

struct buttonEvt_t
Data Fields
uint16_t state A bitmask for the state of all buttons.
buttonBit_t button The button that caused this event.
bool down True if the button was pressed, false if it was released.

Enumeration Type Documentation

◆ buttonBit_t

Bitmask values for all the different buttons.

Enumerator
PB_UP 

The up button's bit.

PB_DOWN 

The down button's bit.

PB_LEFT 

The left button's bit.

PB_RIGHT 

The right button's bit.

PB_A 

The A button's bit.

PB_B 

The B button's bit.

PB_START 

The start button's bit.

PB_SELECT 

The select button's bit.

Function Documentation

◆ initButtons()

void initButtons ( gpio_num_t * pushButtons,
uint8_t numPushButtons,
touch_pad_t * touchPads,
uint8_t numTouchPads )

Initialize both pushbuttons and touch buttons.

Parameters
pushButtonsA list of GPIOs with pushbuttons to initialize. The list should be in the same order as buttonBit_t, starting at PB_UP
numPushButtonsThe number of pushbuttons to initialize
touchPadsA list of touch areas that make up a touchpad to initialize.
numTouchPadsThe number of touch buttons to initialize

◆ deinitButtons()

void deinitButtons ( void )

Free memory used by the buttons.

◆ checkButtonQueue()

bool checkButtonQueue ( buttonEvt_t * evt)

Service the queue of button events that caused interrupts This only returns a single event, even if there are multiple in the queue This function may be called multiple times in a row to completely empty the queue.

Parameters
evtIf an event occurred, return it through this argument
Returns
true if an event occurred, false if nothing happened

◆ getTouchJoystick()

int getTouchJoystick ( int32_t * phi,
int32_t * r,
int32_t * intensity )

Get high-level touch input, an analog input. NOTE: You must have touch callbacks enabled to use this.

Parameters
[out]phithe angle of the touch. Where 0 is right, 320 is up, 640 is left and 960 is down.
[out]ris how far from center you are. 511 is on the outside edge, 0 is on the inside.
[out]intensityis how hard the user is pressing.
Returns
true if touched (joystick), false if not touched (no centroid)