refact0red awake-app, standby-packets are now sent continously
This commit is contained in:
parent
50f14a3a5e
commit
ab1870534e
|
@ -10,21 +10,29 @@
|
|||
#define AWAKE_PACKET_RETRIES 20
|
||||
#define AWAKE_MIN_WINNERS 3
|
||||
#define AWAKE_FONT_HEIGHT 8
|
||||
#define BTN_HBUS (1 << 7)
|
||||
|
||||
|
||||
typedef enum packet_type_e {
|
||||
PCKT_WINNER0,
|
||||
PCKT_WINNER1,
|
||||
PCKT_WINNER2,
|
||||
PCKT_WINNER3,
|
||||
PCKT_WINNER4,
|
||||
PCKT_WINNER5,
|
||||
PCKT_WINNER6,
|
||||
PCKT_WINNER7,
|
||||
PCKT_WAKEUP,
|
||||
PCKT_STANDBY,
|
||||
PCKT_NONE
|
||||
} packet_type_t;
|
||||
typedef enum awake_state_e {
|
||||
AWAKE_STATE_STANDBY,
|
||||
AWAKE_STATE_PLAYING,
|
||||
AWAKE_STATE_WON
|
||||
} awake_state_t;
|
||||
|
||||
|
||||
typedef enum awake_packet_e {
|
||||
AWAKE_PCKT_WINNER0,
|
||||
AWAKE_PCKT_WINNER1,
|
||||
AWAKE_PCKT_WINNER2,
|
||||
AWAKE_PCKT_WINNER3,
|
||||
AWAKE_PCKT_WINNER4,
|
||||
AWAKE_PCKT_WINNER5,
|
||||
AWAKE_PCKT_WINNER6,
|
||||
AWAKE_PCKT_WINNER7,
|
||||
AWAKE_PCKT_WAKEUP,
|
||||
AWAKE_PCKT_STANDBY,
|
||||
AWAKE_PCKT_NONE
|
||||
} awake_packet_t;
|
||||
|
||||
|
||||
static char const *const awake_gPackets[] = {
|
||||
|
@ -61,10 +69,10 @@ static void awake_initNrf(void) {
|
|||
/**
|
||||
* Polls for a special packet which indicates the success of a player.
|
||||
*/
|
||||
static packet_type_t awake_waitForPacket(void) {
|
||||
static awake_packet_t awake_waitForPacket(void) {
|
||||
uint8_t buffer[32];
|
||||
if (nrf_rcv_pkt_time(100, 32, buffer) == 32) {
|
||||
for (packet_type_t p = PCKT_WINNER0; p < PCKT_NONE; ++p) {
|
||||
for (awake_packet_t p = AWAKE_PCKT_WINNER0; p < AWAKE_PCKT_NONE; ++p) {
|
||||
unsigned int bEqual = 1;
|
||||
for (unsigned int i = 0; i < 8; ++i) {
|
||||
if (buffer[i] != awake_gPackets[p][i]) {
|
||||
|
@ -77,45 +85,49 @@ static packet_type_t awake_waitForPacket(void) {
|
|||
}
|
||||
}
|
||||
}
|
||||
return PCKT_NONE;
|
||||
return AWAKE_PCKT_NONE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Waits for either pushed buttons or a signal on the hacker bus.
|
||||
* Checks for pushed buttons and signals on RB_HB0.
|
||||
*/
|
||||
static void awake_waitForKeyPressOrHackerbus(void) {
|
||||
gpioSetDir(RB_HB0, gpioDirection_Input);
|
||||
// watch out for pushed buttons and/or hacker bus activity
|
||||
while (gpioGetValue(RB_HB0) != 0) {
|
||||
if (getInput() != BTN_NONE) {
|
||||
static uint8_t awake_getInputNonBlocking(void) {
|
||||
volatile uint32_t rb_hb0 = gpioGetValue(RB_HB0);
|
||||
if (rb_hb0 == 0) {
|
||||
while (gpioGetValue(RB_HB0) == 0);
|
||||
return BTN_HBUS;
|
||||
} else {
|
||||
uint8_t input = getInput();
|
||||
if (input != BTN_NONE) {
|
||||
getInputWaitRelease();
|
||||
break;
|
||||
}
|
||||
return input;
|
||||
}
|
||||
while (gpioGetValue(RB_HB0) == 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The greeter!
|
||||
*/
|
||||
static void awake_promptUserBegin(void) {
|
||||
gpioSetDir(RB_HB0, gpioDirection_Input);
|
||||
|
||||
static void awake_promptBegin(void) {
|
||||
lcdFill(0);
|
||||
DoString(0, 0, "Eine Taste");
|
||||
DoString(0, 8, "druecken um");
|
||||
DoString(0,16, "das Spiel");
|
||||
DoString(0,24, "zu starten!");
|
||||
DoString(0, 0, "Standby-Modus");
|
||||
DoString(0,16, "Override mit");
|
||||
DoString(0,24, "Tastendruck.");
|
||||
lcdDisplay();
|
||||
}
|
||||
|
||||
awake_waitForKeyPressOrHackerbus();
|
||||
|
||||
/**
|
||||
* You don't say?
|
||||
*/
|
||||
static void awake_promptGameRunning(void) {
|
||||
lcdFill(0);
|
||||
DoString(0, 0, "Spiel laeuft!");
|
||||
DoString(0, 16, "FEUERTASTE");
|
||||
DoString(0, 24, "fuer Standby");
|
||||
DoInt(0, 32, 0);
|
||||
lcdDisplay();
|
||||
}
|
||||
|
||||
|
@ -129,8 +141,30 @@ static void awake_promptUserEnd(void){
|
|||
DoString(0, 8, "nug Gewinner ");
|
||||
DoString(0, 16, "ermittelt! ");
|
||||
lcdDisplay();
|
||||
}
|
||||
|
||||
// toggle RB_HB1 pin from 0V to 3,3 for 200ms
|
||||
|
||||
/**
|
||||
* Prepare hacker bus for our evil plans.
|
||||
*/
|
||||
static void awake_initHackerBus(void) {
|
||||
// set RB_HB0 to input mode
|
||||
gpioSetDir(RB_HB0, gpioDirection_Input);
|
||||
|
||||
// set RB_HB1 to GPIO mode...
|
||||
#define IOCON_PIO0_10 (*((REG32*) (0x40044068)))
|
||||
IOCON_PIO0_10 &= ~(00000007);
|
||||
IOCON_PIO0_10 |= 0x00000001;
|
||||
// ...and to output low
|
||||
GPIO_GPIO0DIR |= (1 << 10);
|
||||
GPIO_GPIO0DATA &= ~(1 << 10);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Toggle RB_HB1 pin from 0V to 3,3 for 200ms.
|
||||
*/
|
||||
static void awake_toggleRbHb1(void) {
|
||||
GPIO_GPIO0DATA |= (1u << 10);
|
||||
delayms_queue(200);
|
||||
GPIO_GPIO0DATA &= ~(1u << 10);
|
||||
|
@ -139,72 +173,76 @@ static void awake_promptUserEnd(void){
|
|||
|
||||
|
||||
/**
|
||||
* Explains a brief moment of unresponsiveness.
|
||||
* Sends the specified packet.
|
||||
* @param packet_type The kind of packet to be sent.
|
||||
*/
|
||||
static void awake_promptStandby(void){
|
||||
lcdFill(0);
|
||||
DoString(0, 0, "Bitte warten!");
|
||||
DoString(0, 8, "Sende Standby");
|
||||
DoString(0, 16, "Pakete... ");
|
||||
lcdDisplay();
|
||||
static void awake_sendPacket(awake_packet_t packet_type) {
|
||||
uint8_t packet[32];
|
||||
memcpy(packet, awake_gPackets[packet_type], 32);
|
||||
nrf_snd_pkt_crc(32, packet);
|
||||
delayms(10);
|
||||
}
|
||||
|
||||
|
||||
void awake_initHackerBus() {
|
||||
// set RB_HB1 to GPIO mode (output)
|
||||
#define IOCON_PIO0_10 (*((REG32*) (0x40044068)))
|
||||
IOCON_PIO0_10 &= ~(00000007);
|
||||
IOCON_PIO0_10 |= 0x00000001;
|
||||
GPIO_GPIO0DIR |= (1 << 10);
|
||||
GPIO_GPIO0DATA &= ~(1 << 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function of the l0dable.
|
||||
*/
|
||||
void main_awake(void) {
|
||||
awake_initNrf();
|
||||
awake_initHackerBus();
|
||||
unsigned int nWinnerFlags = 0, nWinnerCount = 0;
|
||||
|
||||
awake_state_t state = AWAKE_STATE_STANDBY;
|
||||
while (1) {
|
||||
awake_promptUserBegin();
|
||||
uint8_t joyinput = BTN_NONE;
|
||||
unsigned int nWinnerFlags = 0, nWinnerCount = 0;
|
||||
while ((joyinput != BTN_ENTER) && (nWinnerCount < AWAKE_MIN_WINNERS)) {
|
||||
if ((joyinput = getInput()) != BTN_NONE) {
|
||||
getInputWaitRelease();
|
||||
switch (state) {
|
||||
case AWAKE_STATE_STANDBY:
|
||||
awake_promptBegin();
|
||||
// wait for key press or hacker bus signal
|
||||
while (awake_getInputNonBlocking() == BTN_NONE) {
|
||||
awake_sendPacket(AWAKE_PCKT_STANDBY);
|
||||
delayms(50);
|
||||
}
|
||||
state = AWAKE_STATE_PLAYING;
|
||||
break;
|
||||
|
||||
// send a "wake up" packet every loop cycle so that in case a r0ket
|
||||
// is rebooted, the player can continue the game
|
||||
uint8_t packet[32];
|
||||
memcpy(packet, awake_gPackets[PCKT_WAKEUP], 32);
|
||||
delayms(10);
|
||||
nrf_snd_pkt_crc(32, packet);
|
||||
case AWAKE_STATE_PLAYING:
|
||||
nWinnerFlags = 0;
|
||||
nWinnerCount = 0;
|
||||
awake_promptGameRunning();
|
||||
while (state == AWAKE_STATE_PLAYING) {
|
||||
// check for manual override
|
||||
if (awake_getInputNonBlocking() != BTN_NONE) {
|
||||
// manual override -> back to standby mode
|
||||
state = AWAKE_STATE_STANDBY;
|
||||
} else {
|
||||
// send a wake up packet
|
||||
awake_sendPacket(AWAKE_PCKT_WAKEUP);
|
||||
|
||||
// watch out for winners!
|
||||
packet_type_t const ePacket = awake_waitForPacket();
|
||||
unsigned int const nWinnerMask = (1 << ePacket) & 0xFF;
|
||||
if ((ePacket <= PCKT_WINNER7) && !(nWinnerFlags & nWinnerMask)) {
|
||||
nWinnerFlags |= nWinnerMask;
|
||||
++nWinnerCount;
|
||||
DoInt(0, 32, nWinnerCount);
|
||||
lcdDisplay();
|
||||
// watch out for winners!
|
||||
const awake_packet_t ePacket = awake_waitForPacket();
|
||||
const unsigned int nWinnerMask = (1 << ePacket) & 0xFF;
|
||||
if ((ePacket <= AWAKE_PCKT_WINNER7) &&
|
||||
!(nWinnerFlags & nWinnerMask)) {
|
||||
nWinnerFlags |= nWinnerMask;
|
||||
DoInt(0, 32, nWinnerCount);
|
||||
lcdDisplay();
|
||||
if (++nWinnerCount >= AWAKE_MIN_WINNERS) {
|
||||
state = AWAKE_STATE_WON;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
if (nWinnerCount >= AWAKE_MIN_WINNERS) {
|
||||
case AWAKE_STATE_WON:
|
||||
awake_promptUserEnd();
|
||||
}
|
||||
awake_toggleRbHb1();
|
||||
state = AWAKE_STATE_STANDBY;
|
||||
break;
|
||||
|
||||
awake_promptStandby();
|
||||
uint8_t packet[32];
|
||||
for (int i = 0; i < AWAKE_PACKET_RETRIES; ++i) {
|
||||
delayms_queue(50);
|
||||
memcpy(packet, awake_gPackets[PCKT_STANDBY], 32);
|
||||
nrf_snd_pkt_crc(32, packet);
|
||||
default:
|
||||
state = AWAKE_STATE_STANDBY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue