2012-06-08 00:00:33 +00:00
|
|
|
#include <sysinit.h>
|
|
|
|
#include <stdint.h>
|
2012-06-08 01:11:26 +00:00
|
|
|
#include <string.h>
|
2012-06-08 00:00:33 +00:00
|
|
|
#include "basic/basic.h"
|
|
|
|
#include "funk/nrf24l01p.h"
|
2012-06-08 01:11:26 +00:00
|
|
|
#include "lcd/lcd.h"
|
2012-06-08 00:00:33 +00:00
|
|
|
//#include "usetable.h"
|
|
|
|
|
|
|
|
|
|
|
|
#define AWAKE_PACKET_RETRIES 20
|
|
|
|
#define AWAKE_MIN_WINNERS 3
|
|
|
|
#define AWAKE_FONT_HEIGHT 8
|
2012-06-17 20:49:06 +00:00
|
|
|
#define BTN_HBUS (1 << 7)
|
2012-06-08 00:00:33 +00:00
|
|
|
|
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
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;
|
2012-06-08 00:00:33 +00:00
|
|
|
|
|
|
|
|
|
|
|
static char const *const awake_gPackets[] = {
|
|
|
|
"winner0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner3\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner6\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"winner7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"wake up\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0",
|
|
|
|
"standby\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initializes wireless stuff.
|
|
|
|
*/
|
|
|
|
static void awake_initNrf(void) {
|
|
|
|
nrf_init();
|
|
|
|
static struct NRF_CFG config = {
|
|
|
|
.channel = 81,
|
|
|
|
.txmac = "\x1\x2\x3\x2\x1",
|
|
|
|
.nrmacs = 1,
|
|
|
|
.mac0 = "\x1\x2\x3\x2\x1",
|
|
|
|
.maclen = "\x20"
|
|
|
|
};
|
|
|
|
nrf_config_set(&config);
|
|
|
|
nrf_set_strength(3);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Polls for a special packet which indicates the success of a player.
|
|
|
|
*/
|
2012-06-17 20:49:06 +00:00
|
|
|
static awake_packet_t awake_waitForPacket(void) {
|
2012-06-08 00:00:33 +00:00
|
|
|
uint8_t buffer[32];
|
|
|
|
if (nrf_rcv_pkt_time(100, 32, buffer) == 32) {
|
2012-06-17 20:49:06 +00:00
|
|
|
for (awake_packet_t p = AWAKE_PCKT_WINNER0; p < AWAKE_PCKT_NONE; ++p) {
|
2012-06-08 00:00:33 +00:00
|
|
|
unsigned int bEqual = 1;
|
|
|
|
for (unsigned int i = 0; i < 8; ++i) {
|
|
|
|
if (buffer[i] != awake_gPackets[p][i]) {
|
|
|
|
bEqual = 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (bEqual) {
|
|
|
|
return p;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-17 20:49:06 +00:00
|
|
|
return AWAKE_PCKT_NONE;
|
2012-06-08 00:00:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2012-06-17 20:49:06 +00:00
|
|
|
* Checks for pushed buttons and signals on RB_HB0.
|
2012-06-08 00:00:33 +00:00
|
|
|
*/
|
2012-06-17 20:49:06 +00:00
|
|
|
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) {
|
2012-06-08 00:00:33 +00:00
|
|
|
getInputWaitRelease();
|
|
|
|
}
|
2012-06-17 20:49:06 +00:00
|
|
|
return input;
|
2012-06-08 00:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* The greeter!
|
|
|
|
*/
|
2012-06-17 20:49:06 +00:00
|
|
|
static void awake_promptBegin(void) {
|
2012-06-08 00:00:33 +00:00
|
|
|
lcdFill(0);
|
2012-06-17 20:49:06 +00:00
|
|
|
DoString(0, 0, "Standby-Modus");
|
|
|
|
DoString(0,16, "Override mit");
|
|
|
|
DoString(0,24, "Tastendruck.");
|
2012-06-08 00:00:33 +00:00
|
|
|
lcdDisplay();
|
2012-06-17 20:49:06 +00:00
|
|
|
}
|
2012-06-08 00:00:33 +00:00
|
|
|
|
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
/**
|
|
|
|
* You don't say?
|
|
|
|
*/
|
|
|
|
static void awake_promptGameRunning(void) {
|
2012-06-08 00:00:33 +00:00
|
|
|
lcdFill(0);
|
|
|
|
DoString(0, 0, "Spiel laeuft!");
|
|
|
|
DoString(0, 16, "FEUERTASTE");
|
|
|
|
DoString(0, 24, "fuer Standby");
|
2012-06-17 20:49:06 +00:00
|
|
|
DoInt(0, 32, 0);
|
2012-06-08 00:00:33 +00:00
|
|
|
lcdDisplay();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Informs about the happy end!
|
|
|
|
*/
|
|
|
|
static void awake_promptUserEnd(void){
|
|
|
|
lcdFill(0);
|
|
|
|
DoString(0, 0, "Es wurden ge-");
|
|
|
|
DoString(0, 8, "nug Gewinner ");
|
|
|
|
DoString(0, 16, "ermittelt! ");
|
|
|
|
lcdDisplay();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2012-06-17 20:49:06 +00:00
|
|
|
* Prepare hacker bus for our evil plans.
|
2012-06-08 00:00:33 +00:00
|
|
|
*/
|
2012-06-17 20:49:06 +00:00
|
|
|
static void awake_initHackerBus(void) {
|
|
|
|
// set RB_HB0 to input mode
|
|
|
|
gpioSetDir(RB_HB0, gpioDirection_Input);
|
2012-06-08 00:00:33 +00:00
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
// set RB_HB1 to GPIO mode...
|
2012-06-08 00:00:33 +00:00
|
|
|
#define IOCON_PIO0_10 (*((REG32*) (0x40044068)))
|
|
|
|
IOCON_PIO0_10 &= ~(00000007);
|
|
|
|
IOCON_PIO0_10 |= 0x00000001;
|
2012-06-17 20:49:06 +00:00
|
|
|
// ...and to output low
|
2012-06-08 00:00:33 +00:00
|
|
|
GPIO_GPIO0DIR |= (1 << 10);
|
|
|
|
GPIO_GPIO0DATA &= ~(1 << 10);
|
|
|
|
}
|
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* 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);
|
|
|
|
delayms_queue(200);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sends the specified packet.
|
|
|
|
* @param packet_type The kind of packet to be sent.
|
|
|
|
*/
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-06-08 00:00:33 +00:00
|
|
|
/**
|
|
|
|
* Main function of the l0dable.
|
|
|
|
*/
|
|
|
|
void main_awake(void) {
|
|
|
|
awake_initNrf();
|
|
|
|
awake_initHackerBus();
|
2012-06-17 20:49:06 +00:00
|
|
|
unsigned int nWinnerFlags = 0, nWinnerCount = 0;
|
2012-06-08 00:00:33 +00:00
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
awake_state_t state = AWAKE_STATE_STANDBY;
|
2012-06-08 00:00:33 +00:00
|
|
|
while (1) {
|
2012-06-17 20:49:06 +00:00
|
|
|
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);
|
2012-06-08 00:00:33 +00:00
|
|
|
}
|
2012-06-17 20:49:06 +00:00
|
|
|
state = AWAKE_STATE_PLAYING;
|
|
|
|
break;
|
2012-06-08 00:00:33 +00:00
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
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!
|
|
|
|
const awake_packet_t ePacket = awake_waitForPacket();
|
|
|
|
const unsigned int nWinnerMask = (1 << ePacket) & 0xFF;
|
|
|
|
if ((ePacket <= AWAKE_PCKT_WINNER7) &&
|
|
|
|
!(nWinnerFlags & nWinnerMask)) {
|
|
|
|
nWinnerFlags |= nWinnerMask;
|
2012-06-19 21:47:30 +00:00
|
|
|
DoInt(0, 32, ++nWinnerCount);
|
2012-06-17 20:49:06 +00:00
|
|
|
lcdDisplay();
|
2012-06-19 21:47:30 +00:00
|
|
|
if (nWinnerCount >= AWAKE_MIN_WINNERS) {
|
2012-06-17 20:49:06 +00:00
|
|
|
state = AWAKE_STATE_WON;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2012-06-08 00:00:33 +00:00
|
|
|
}
|
2012-06-17 20:49:06 +00:00
|
|
|
break;
|
2012-06-08 00:00:33 +00:00
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
case AWAKE_STATE_WON:
|
2012-06-08 00:00:33 +00:00
|
|
|
awake_promptUserEnd();
|
2012-06-17 20:49:06 +00:00
|
|
|
awake_toggleRbHb1();
|
|
|
|
state = AWAKE_STATE_STANDBY;
|
|
|
|
break;
|
2012-06-08 00:00:33 +00:00
|
|
|
|
2012-06-17 20:49:06 +00:00
|
|
|
default:
|
|
|
|
state = AWAKE_STATE_STANDBY;
|
|
|
|
break;
|
2012-06-08 00:00:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|