refact0red awake-app, standby-packets are now sent continously

This commit is contained in:
tunix 2012-06-17 22:49:06 +02:00
parent 50f14a3a5e
commit ab1870534e
1 changed files with 118 additions and 80 deletions

View File

@ -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;
}