Skip to content

Instantly share code, notes, and snippets.

@Pharap
Created June 24, 2018 22:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Pharap/53a3d6cca784d8909f6bea235ab6ed92 to your computer and use it in GitHub Desktop.
Save Pharap/53a3d6cca784d8909f6bea235ab6ed92 to your computer and use it in GitHub Desktop.
Draft version of PokittoLib2 Buttons API
#pragma once
#include "Buttons.h"
#include <cstddef>
#include <bitset>
namespace Pokitto
{
class BitsetButtons
{
public:
using State = std::bitset<ButtonCount>;
private:
State currentState;
State previousState;
State justPressedState;
State justReleasedState;
private:
static constexpr std::size_t getIndex(Button button)
{
return static_cast<std::size_t>(button);
}
static State getNewState(void);
public:
void update(void)
{
this->previousState = currentState;
this->currentState = getNewState();
const State difference = this->previousState ^ this->currentState;
this->justPressedState = difference & this->currentState;
this->justReleasedState = difference & this->previousState;
}
bool isPressed(Button button) const
{
return this->currentState[getIndex(button)];
}
bool isReleased(Button button) const
{
return !this->currentState[getIndex(button)];
}
bool justPressed(Button button) const
{
//return this->currentState[getIndex(button)] && !this->previousState[getIndex(button)];
return this->justPressedState[getIndex(button)];
}
bool justReleased(Button button) const
{
//return !this->currentState[getIndex(button)] && this->previousState[getIndex(button)];
return this->justReleasedState[getIndex(button)];
}
};
}
#include "BitsetButtons.h"
#include "Pins.h"
using mbed::InterruptIn;
InterruptIn ButtonAInterrupt(Pokitto::Pins::ButtonAPin);
InterruptIn ButtonBInterrupt(Pokitto::Pins::ButtonBPin);
InterruptIn ButtonCInterrupt(Pokitto::Pins::ButtonCPin);
InterruptIn ButtonUpInterrupt(Pokitto::Pins::ButtonUpPin);
InterruptIn ButtonDownInterrupt(Pokitto::Pins::ButtonDownPin);
InterruptIn ButtonLeftInterrupt(Pokitto::Pins::ButtonLeftPin);
InterruptIn ButtonRightInterrupt(Pokitto::Pins::ButtonRightPin);
using Pokitto::BitsetButtons;
using State = typename BitsetButtons::State;
State stateBuffer;
State BitsetButtons::getNewState(void)
{
return stateBuffer;
}
constexpr std::size_t getIndex(Button button)
{
return static_cast<std::size_t>(button);
}
#define DEFINE_ACTIONS(button) \
void On##button##Pressed(void) \
{ \
stateBuffer[getIndex(Button::##button)] = true; \
} \
\
void On##button##Released(void) \
{ \
stateBuffer[getIndex(Button::##button)] = false; \
}
DEFINE_ACTIONS(A)
DEFINE_ACTIONS(B)
DEFINE_ACTIONS(C)
DEFINE_ACTIONS(Up)
DEFINE_ACTIONS(Down)
DEFINE_ACTIONS(Left)
DEFINE_ACTIONS(Right)
/*void OnRightPressed(void)
{
if(stateBuffer[getIndex(Button::C)])
Pokitto::Sound::volumeUp();
else
stateBuffer[getIndex(Button::Right)] = true;
}
void OnRightReleased(void)
{
stateBuffer[getIndex(Button::Right)] = false;
}
void OnLeftPressed(void)
{
if(stateBuffer[getIndex(Button::C)])
Pokitto::Sound::volumeDown();
else
stateBuffer[getIndex(Button::Left)] = true;
}*/
void OnLeftReleased(void)
{
stateBuffer[getIndex(Button::Left)] = false;
}
#define DEFINE_INTERRUPT_HANDLER(number, button) \
void PinInterruptHandler##number(void) \
{ \
stateBuffer[getIndex(Button::##button)] = (Button##button##Interrupt.read() != 0); \
ClearPinInt(reinterpret_cast<LPC_PIN_INT_T *>(LPC_PININT, PININTCH(number)); \
}
DEFINE_INTERRUPT_HANDLER(0, A);
DEFINE_INTERRUPT_HANDLER(1, B);
DEFINE_INTERRUPT_HANDLER(2, C);
DEFINE_INTERRUPT_HANDLER(3, Up);
DEFINE_INTERRUPT_HANDLER(4, Down);
DEFINE_INTERRUPT_HANDLER(5, Left);
DEFINE_INTERRUPT_HANDLER(6, Right);
/*void PinInterruptHandler5(void)
{
stateBuffer[getIndex(Button::C)] = (ButtonCInterrupt.read() != 0);
stateBuffer[getIndex(Button::Left)] = (ButtonCInterrupt.read() != 0);
if(stateBuffer[getIndex(Button::C)] && stateBuffer[getIndex(Button::Left)])
{
if(!volumeControlClicked)
Pokitto::Sound::volumeDown();
stateBuffer[getIndex(Button::Left)] = false;
volumeControlClicked = true;
}
else
volumeControlClicked = false;
ClearPinInt(reinterpret_cast<LPC_PIN_INT_T *>(LPC_PININT, PININTCH(5)));
}*/
/*void PinInterruptHandler6(void)
{
stateBuffer[getIndex(Button::C)] = (ButtonCInterrupt.read() != 0);
stateBuffer[getIndex(Button::Right)] = (ButtonCInterrupt.read() != 0);
if(stateBuffer[getIndex(Button::C)] && stateBuffer[getIndex(Button::Right)])
{
if(!volumeControlClicked)
Pokitto::Sound::volumeDown();
stateBuffer[getIndex(Button::Right)] = false;
volumeControlClicked = true;
}
else
volumeControlClicked = false;
ClearPinInt(reinterpret_cast<LPC_PIN_INT_T *>(LPC_PININT, PININTCH(6)));
}*/
#define SET_VECTOR(number) NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT##number##_IRQn), static_cast<uint32_t>(&PinInterruptHandler##number));
void Pokitto::Buttons::initialise(void)
{
ButtonAInterrupt.rise(OnAPressed);
ButtonAInterrupt.fall(OnAReleased);
ButtonBInterrupt.rise(OnBPressed);
ButtonBInterrupt.fall(OnBReleased);
ButtonCInterrupt.rise(OnCPressed);
ButtonCInterrupt.fall(OnCReleased);
ButtonUpInterrupt.rise(OnUpPressed);
ButtonUpInterrupt.fall(OnUpReleased);
ButtonDownInterrupt.rise(OnDownPressed);
ButtonDownInterrupt.fall(OnDownReleased);
ButtonRightInterrupt.rise(OnRightPressed);
ButtonRightInterrupt.fall(OnRightReleased);
ButtonLeftInterrupt.rise(OnLeftPressed);
ButtonLeftInterrupt.fall(OnLeftReleased);
SET_VECTOR(0);
SET_VECTOR(1);
SET_VECTOR(2);
SET_VECTOR(3);
SET_VECTOR(4);
SET_VECTOR(5);
SET_VECTOR(6);
/*NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT0_IRQn), static_cast<uint32_t>(&PinInterruptHandler0));
NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT1_IRQn), static_cast<uint32_t>(&PinInterruptHandler1));
NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT2_IRQn), static_cast<uint32_t>(&PinInterruptHandler2));
NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT3_IRQn), static_cast<uint32_t>(&PinInterruptHandler3));
NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT4_IRQn), static_cast<uint32_t>(&PinInterruptHandler4));
NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT5_IRQn), static_cast<uint32_t>(&PinInterruptHandler5));
NVIC_SetVector(static_cast<IRQn_Type>(PIN_INT6_IRQn), static_cast<uint32_t>(&PinInterruptHandler6));*/
}
#pragma once
#include <cstdint>
namespace Pokitto
{
enum class Button
{
Left = 0,
Up = 1,
Right = 2,
Down = 3,
A = 4,
B = 5,
C = 6,
};
constexpr uint32_t ButtonCount = 7;
static constexpr std::size_t asIndex(Button button)
{
return static_cast<std::size_t>(button);
}
/*enum class ButtonMode
{
Polling = 0x00,
Interrupt = 0x01,
};*/
class Buttons
{
public:
Buttons(void) = delete;
static void initialise(ButtonMode mode);
static void update(void);
static bool isPressed(Button button);
static bool isReleased(Button button);
static bool justPressed(Button button);
static bool justReleased(Button button);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment