Merge git://github.com/r0ket/r0ket

This commit is contained in:
bernd 2011-08-05 00:30:17 +02:00
commit 5d83884d4d
32 changed files with 926 additions and 180 deletions

View File

@ -8,6 +8,7 @@
#include "filesystem/ff.h"
#include "usb/usbmsc.h"
#include "basic/random.h"
#include "funk/nrf24l01p.h"
/**************************************************************************/
@ -18,6 +19,9 @@ void main_default(void) {
case BTN_ENTER:
ISPandReset();
break;
case BTN_UP: // Reset config
f_unlink("r0ket.cfg");
break;
case BTN_DOWN:
usbMSCInit();
while(1)
@ -84,7 +88,7 @@ void tick_default(void) {
};
EVERY(4096,17){
nrf_check_reset();
push_queue(nrf_check_reset);
};
return;
};

View File

@ -8,6 +8,8 @@
#include "basic/ecc.h"
#include "basic/config.h"
/**************************************************************************/
#include "final.gen"
@ -16,6 +18,20 @@ void init_nick();
void fancyNickname();
void main_final(void) {
if(GLOBAL(privacy)>2){ //firstboot
if(execute_file("1boot.int",0,0)){
lcdPrintln("Badge SETUP");
lcdPrintln("error.");
lcdPrintln("Features may");
lcdPrintln("be broken.");
lcdRefresh();
getInputWait();
getInputWaitRelease();
GLOBAL(privacy)=0;
}else{
saveConfig();
};
};
//checkFirstBoot();
init_final();
menuflags|=MENU_TIMEOUT;

View File

@ -13,18 +13,6 @@
/**************************************************************************/
void readcfg(void) {
readConfig();
};
void savecfg(void){
saveConfig();
};
void applycfg(void){
applyConfig();
};
//# MENU config
void changer(void){
uint8_t numentries = 0;
@ -55,41 +43,37 @@ void changer(void){
lcdNl();
uint8_t j=0;
for (uint8_t i=0;i<current_offset;i++,j++)
if(the_config[j].disabled)
j++;
for (uint8_t i=0;i<current_offset;i++)
while (the_config[++j].disabled);
uint8_t t=0;
for (uint8_t i=0;i<menuselection;i++)
while (the_config[++t].disabled);
for (uint8_t i = current_offset; i < (visible_lines + current_offset) && i < numentries; i++,j++) {
while(the_config[j].disabled)j++;
if(i==0){
lcdPrintln("Save changes:");
if (i == menuselection)
if (i == t)
lcdPrint("*");
lcdSetCrsrX(14);
if (i == menuselection)
if (i == t)
lcdPrintln("YES");
else
lcdPrintln("no");
}else{
lcdPrintln(the_config[j].name);
if (j == menuselection)
if (j == t)
lcdPrint("*");
lcdSetCrsrX(14);
lcdPrint("<");
lcdPrint(IntToStr(the_config[j].value,3,F_LONG));
lcdPrintln(">");
};
lcdRefresh();
}
lcdRefresh();
j=menuselection;
int t=0;
while(j){
if(!the_config[t].disabled)
j--;
t++;
}
switch (getInputWaitRepeat()) {
case BTN_UP:
menuselection--;

View File

@ -128,6 +128,9 @@ void m_choose(){
char list[99];
int i=0;
meshmsg=0;
gpioSetValue (RB_LED1, 0);
while(1){
char *p=list;
strcpy(p,"Note");
@ -207,6 +210,7 @@ void m_choose(){
lcdPrint(".");
lcdPrint(IntToStr(tm->tm_year+YEAR0,4,F_LONG|F_ZEROS));
lcdNl();
MO_BODY(meshbuffer[j].pkt)[0]=0;
};
};
char *foo=(char *)MO_BODY(meshbuffer[j].pkt);
@ -231,5 +235,10 @@ void m_choose(){
void tick_mesh(void){
if(GLOBAL(privacy)<2)
mesh_systick();
if(_timectr%64)
if(meshmsg){
gpioSetValue (RB_LED1, 1);
meshmsg=0;
};
};

View File

@ -16,7 +16,20 @@
/**************************************************************************/
void simpleNickname(void);
void fancyNickname(void) {
if(GLOBAL(l0nick)){
if(execute_file(GLOBAL(nickl0),0,0))
GLOBAL(l0nick)=0;
}
if(!GLOBAL(l0nick))
simpleNickname();
return;
}
void simpleNickname(void) {
int dx=0;
int dy=0;
static uint32_t ctr=0;
@ -44,6 +57,7 @@ void fancyNickname(void) {
void init_nick(void){
readFile("nick.cfg",GLOBAL(nickname),MAXNICK);
readFile("font.cfg",GLOBAL(nickfont),FILENAMELEN);
readFile("l0nick.cfg",GLOBAL(nickl0),FILENAMELEN);
};
//# MENU nick editNick
@ -71,3 +85,16 @@ void doFont(void){
setIntFont(&Font_7x8);
while(!getInputRaw())delayms(10);
};
//# MENU nick chooseAnim
void doAnim(void){
getInputWaitRelease();
if( selectFile(GLOBAL(nickl0),"NIK") != 0){
lcdPrintln("No file selected.");
GLOBAL(l0nick)=0;
return;
};
writeFile("l0nick.cfg",GLOBAL(nickl0),strlen(GLOBAL(nickl0)));
GLOBAL(l0nick)=1;
getInputWaitRelease();
};

View File

@ -43,27 +43,20 @@ void rbInit() {
IOCON_JTAG_TDI_PIO0_11 |= IOCON_JTAG_TDI_PIO0_11_FUNC_GPIO;
gpioSetDir(RB_LED0, gpioDirection_Output);
gpioSetValue (RB_LED0, 1);
gpioSetValue (RB_LED0, 0);
gpioSetDir(RB_LED1, gpioDirection_Output);
gpioSetValue (RB_LED1, 1);
gpioSetValue (RB_LED1, 0);
gpioSetDir(RB_LED2, gpioDirection_Output);
gpioSetValue (RB_LED2, 1);
gpioSetValue (RB_LED2, 0);
gpioSetDir(RB_LED3, gpioDirection_Output);
gpioSetValue (RB_LED3, 1);
gpioSetValue (RB_LED3, 0);
// Set LED3 to ?
IOCON_PIO1_11 = 0x41;
// prepare IR
//gpioSetDir(RB_IROUT, gpioDirection_Output);
//gpioSetValue (RB_IROUT, 1);
//gpioSetDir(RB_IRIN, gpioDirection_Input);
//gpioSetPullup (&RB_IRIN_IO, gpioPullupMode_PullUp);
// prepare lcd
// TODO FIXME more init needed ?
gpioSetDir(RB_LCD_BL, gpioDirection_Output);
@ -127,16 +120,13 @@ void rbInit() {
gpioSetPullup (&RB_BUSINT_IO, gpioPullupMode_PullUp);
gpioSetInterrupt(RB_BUSINT, gpioInterruptSense_Edge, gpioInterruptEdge_Single, gpioInterruptEvent_ActiveLow);
gpioIntEnable(RB_BUSINT);
// add this to catch interrupt:
/*
*/
//nrf_init();
backlightInit();
font=&Font_7x8;
ECIES_setup();
}
#define WEAK_ALIAS(f) __attribute__ ((weak, alias (#f)));
void interrupt_undefined(void) {
}

View File

@ -179,7 +179,9 @@ struct MENU {
struct MENU_DEF entries[];
};
#define MENU_TIMEOUT (1<<0)
#define MENU_TIMEOUT (1<<0)
#define MENU_JUSTONCE (1<<1)
#define MENU_BIG (1<<2)
extern uint8_t menuflags;
@ -204,5 +206,12 @@ const char* IntToStr(int num, unsigned int mxlen, char flag);
// global
#define SYSTICKSPEED 10
#ifdef __arm__
#define WFI __asm volatile ("WFI")
#else
#define WFI delayms(SYSTICKSPEED)
#endif
#endif

View File

@ -7,7 +7,7 @@
#include "basic/random.h"
#include "basic/config.h"
#define CFGVER 1
#define CFGVER 3
struct CDESC the_config[]= {
{"version", CFGVER, CFGVER, CFGVER, 0, 0},
@ -20,17 +20,20 @@ struct CDESC the_config[]= {
{"lcdmirror", 0, 0, 1 , 0, 0},
{"lcdinvert", 0, 0, 1 , 0, 0},
{"lcdcontrast", 14, 0, 31 , 0, 0},
{"alivechk", 0, 0, 2 , 0, 0},
{"alivechk", 0, 0, 2 , 1, CFG_TYPE_DEVEL},
{"develmode", 0, 0, 1 , 1, CFG_TYPE_DEVEL},
{"flamemax", 255, 0, 255, 1, CFG_TYPE_FLAME},
{"flamemin", 0, 0, 255, 1, CFG_TYPE_FLAME},
{"flamespeed", 1, 1, 100, 1, CFG_TYPE_FLAME},
{"flamemaxw", 255, 1, 255, 1, CFG_TYPE_FLAME},
{"flameminw", 0x8f, 1, 255, 1, CFG_TYPE_FLAME},
{"l0nick", 0, 0, 1 , 0, 0},
{ NULL, 0, 0, 0 , 0, 0},
};
char nickname[MAXNICK]="anonymous";
char nickfont[FILENAMELEN];
char nickl0[FILENAMELEN];
#define CONFFILE "r0ket.cfg"
#define CONF_ITER for(int i=0;the_config[i].name!=NULL;i++)
@ -40,7 +43,7 @@ char nickfont[FILENAMELEN];
void applyConfig(){
if(GLOBAL(lcdcontrast)>0)
lcdSetContrast(GLOBAL(lcdcontrast));
return;
enableConfig(CFG_TYPE_DEVEL,GLOBAL(develmode));
};
int saveConfig(void){
@ -49,6 +52,8 @@ int saveConfig(void){
UINT allwrite=0;
int res;
lcdClear();
res=f_open(&file, CONFFILE, FA_OPEN_ALWAYS|FA_WRITE);
lcdPrint("create:");
lcdPrintln(f_get_rc_string(res));

View File

@ -21,8 +21,9 @@ struct CDESC {
#define MAXNICK 20
extern struct CDESC the_config[];
extern char nickname[MAXNICK];
extern char nickname[];
extern char nickfont[];
extern char nickl0[];
#define GLOBALversion (the_config[ 0].value)
#define GLOBALprivacy (the_config[ 1].value)
@ -34,13 +35,16 @@ extern char nickfont[];
#define GLOBALlcdinvert (the_config[ 7].value)
#define GLOBALlcdcontrast (the_config[ 8].value)
#define GLOBALalivechk (the_config[ 9].value)
#define GLOBALflamemax (the_config[10].value)
#define GLOBALflamemin (the_config[11].value)
#define GLOBALflamespeed (the_config[12].value)
#define GLOBALflamemaxw (the_config[13].value)
#define GLOBALflameminw (the_config[14].value)
#define GLOBALdevelmode (the_config[10].value)
#define GLOBALflamemax (the_config[11].value)
#define GLOBALflamemin (the_config[12].value)
#define GLOBALflamespeed (the_config[13].value)
#define GLOBALflamemaxw (the_config[14].value)
#define GLOBALflameminw (the_config[15].value)
#define GLOBALl0nick (the_config[16].value)
#define GLOBALnickname (nickname)
#define GLOBALnickfont (nickfont)
#define GLOBALnickl0 (nickl0)
#define GLOBAL(x) GLOBAL ## x

View File

@ -13,36 +13,70 @@ extern uint32_t simTimeCounter();
/**************************************************************************/
void work_queue(void){
void (*elem)(void);
uint8_t work_queue_minimal(void){
int start;
if (the_queue.qstart == the_queue.qend){
#ifdef __arm__
__asm volatile ("WFI");
#else
delayms(SYSTICKSPEED);
#endif
return;
return 0;
};
start=the_queue.qstart;
start=(start+1)%MAXQENTRIES;
elem=the_queue.queue[start].callback;
the_queue.qstart=start;
if(the_queue.queue[start].type == QT_NORMAL){
void (*elem)(void);
elem=the_queue.queue[start].u.callback;
the_queue.qstart=start;
elem();
return 0;
}else if(the_queue.queue[start].type == QT_PLUS){
uint8_t (*elem)(uint8_t);
uint8_t state=the_queue.queue[start].state;
elem=the_queue.queue[start].u.callbackplus;
state=elem(state);
if(state==QS_END){
the_queue.qstart=start;
return 0;
}else{
the_queue.queue[start].state=state;
return 1;
};
};
};
elem();
void work_queue(void){
int start;
if (the_queue.qstart == the_queue.qend){
WFI;
return;
};
while(work_queue_minimal());
};
uint8_t delayms_queue_plus(uint32_t ms, uint8_t final){
int ret;
int end=_timectr+ms/SYSTICKSPEED;
do {
if (the_queue.qstart == the_queue.qend){
WFI;
}else{
ret=work_queue_minimal();
};
} while (end >_timectr);
if(ret && final){
while(work_queue_minimal());
};
return ret;
};
void delayms_queue(uint32_t ms){
int end=_timectr+ms/SYSTICKSPEED;
do {
if (the_queue.qstart == the_queue.qend){
#ifdef __arm__
__asm volatile ("WFI");
#else
delayms(SYSTICKSPEED);
#endif
WFI;
}else{
work_queue();
};
@ -53,11 +87,7 @@ void delayms_power(uint32_t ms){
ms/=SYSTICKSPEED;
ms+=_timectr;
do {
#ifdef __arm__
__asm volatile ("WFI");
#else
delayms(SYSTICKSPEED);
#endif
WFI;
} while (ms >_timectr);
};
@ -70,7 +100,25 @@ int push_queue(void (*new)(void)){
if(end == the_queue.qstart) // Queue full
return -1;
the_queue.queue[end].callback=new;
the_queue.queue[end].u.callback=new;
the_queue.queue[end].type=QT_NORMAL;
the_queue.qend=end;
return 0;
};
int push_queue_plus(uint8_t (*new)(uint8_t)){
int end;
end=the_queue.qend;
end=(end+1)%MAXQENTRIES;
if(end == the_queue.qstart) // Queue full
return -1;
the_queue.queue[end].u.callbackplus=new;
the_queue.queue[end].type=QT_PLUS;
the_queue.queue[end].state=QS_START;
the_queue.qend=end;
return 0;

View File

@ -3,8 +3,18 @@
#define MAXQENTRIES 8
#define QT_NORMAL 0
#define QT_PLUS 1
#define QS_START 0x0
#define QS_END 0x7f
typedef struct {
void (*callback)(void);
union {
void (*callback)(void);
uint8_t (*callbackplus)(uint8_t);
} u;
unsigned type :1;
unsigned state :7;
} QENTRY;
typedef struct {
@ -17,10 +27,12 @@ extern QUEUE the_queue;
extern volatile uint32_t _timectr;
void work_queue(void);
uint8_t work_queue_minimal(void);
void delayms_queue(uint32_t);
uint8_t delayms_queue_plus(uint32_t, uint8_t);
void delayms_power(uint32_t);
int push_queue(void (*qnew)(void));
int magic(void *qnew);
int push_queue_plus(uint8_t (*qnew)(uint8_t));
// Note:
// Our time implementation will fail after 497 days of continous uptime.

View File

@ -22,6 +22,10 @@ void handleMenu(const struct MENU *the_menu) {
for (numentries = 0; the_menu->entries[numentries].text != NULL ; numentries++);
visible_lines = lcdGetVisibleLines()-1; // subtract title line
if(menuflags&MENU_BIG)
visible_lines/=2;
#ifdef SAFETY
if (visible_lines < 2) return;
#endif
@ -32,6 +36,8 @@ void handleMenu(const struct MENU *the_menu) {
lcdPrintln(the_menu->title);
for (uint8_t i = current_offset; i < (visible_lines + current_offset) && i < numentries; i++) {
if(menuflags&MENU_BIG)
lcdNl();
if (i == menuselection) {
lcdPrint("*");
}
@ -68,6 +74,10 @@ void handleMenu(const struct MENU *the_menu) {
case BTN_RIGHT:
if (the_menu->entries[menuselection].callback!=NULL)
the_menu->entries[menuselection].callback();
if (menuflags&MENU_JUSTONCE)
return;
break;
case BTN_ENTER:
lcdClear();
@ -77,6 +87,10 @@ void handleMenu(const struct MENU *the_menu) {
if (the_menu->entries[menuselection].callback!=NULL)
the_menu->entries[menuselection].callback();
lcdRefresh();
if (menuflags&MENU_JUSTONCE)
return;
getInputWait();
break;

View File

@ -20,7 +20,7 @@ extern void * sram_top;
/**************************************************************************/
void execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
uint8_t execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
FRESULT res;
FIL file;
UINT readbytes;
@ -38,7 +38,7 @@ void execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
//lcdPrintln(f_get_rc_string(res));
//lcdRefresh();
if(res){
return;
return -1;
};
res = f_read(&file, (char *)dst, RAMCODE, &readbytes);
@ -46,7 +46,7 @@ void execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
//lcdPrintln(f_get_rc_string(res));
//lcdRefresh();
if(res){
return;
return -1;
};
if( decode || checksignature )
//only accept files with fixed length
@ -55,7 +55,7 @@ void execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
lcdPrint("readbytes&3");
lcdRefresh();
while(1);
return;
return -1;
}
if( checksignature ){
uint32_t mac[4];
@ -72,7 +72,7 @@ void execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
lcdPrintIntHex(mac[3]); lcdNl();
lcdRefresh();
while(1);
return;
return -1;
}
//lcdPrint("macok");
//lcdRefresh();
@ -90,6 +90,7 @@ void execute_file (const char * fname, uint8_t checksignature, uint8_t decode){
dst=(void (*)(void)) ((uint32_t)(dst) | 1); // Enable Thumb mode!
dst();
return 0;
};

View File

@ -1,7 +1,7 @@
#ifndef _EXECUTE_H_
#define _EXECUTE_H_
void execute_file (const char * fname, uint8_t checksignature, uint8_t decode);
uint8_t execute_file (const char * fname, uint8_t checksignature, uint8_t decode);
void executeSelect(char *ext);
#endif

View File

@ -6,9 +6,11 @@
#include "funk/nrf24l01p.h"
#include "basic/byteorder.h"
#include "basic/random.h"
#include "basic/config.h"
char meshgen=0; // Generation
char meshincctr=0;
char meshmsg=0;
MPKT meshbuffer[MESHBUFSIZE];
uint32_t const meshkey[4] = {
@ -70,11 +72,38 @@ void mesh_cleanup(void){
};
};
void mesh_recvloop(void){
void mesh_sendloop(void){
int ctr=0;
__attribute__ ((aligned (4))) uint8_t buf[32];
int len;
int recvend=M_RECVTIM/SYSTICKSPEED+getTimer();
int pktctr=0;
int status;
nrf_config_get(&oldconfig);
nrf_set_channel(MESH_CHANNEL);
nrf_set_tx_mac(strlen(MESH_MAC),(uint8_t*)MESH_MAC);
// Update [T]ime packet
MO_TIME_set(meshbuffer[0].pkt,getSeconds());
MO_GEN_set(meshbuffer[0].pkt,meshgen);
if(GLOBAL(privacy)==0)
uint32touint8p(GetUUID32(),MO_BODY(meshbuffer[0].pkt));
else
uint32touint8p(0,MO_BODY(meshbuffer[0].pkt));
for (int i=0;i<MESHBUFSIZE;i++){
if(!meshbuffer[i].flags&MF_USED)
continue;
if(meshbuffer[i].flags&MF_LOCK)
continue;
ctr++;
memcpy(buf,meshbuffer[i].pkt,MESHPKTSIZE);
status=nrf_snd_pkt_crc_encr(MESHPKTSIZE,buf,meshkey);
//Check status? But what would we do...
};
nrf_config_set(&oldconfig);
};
void mesh_recvqloop_setup(void){
nrf_config_get(&oldconfig);
@ -84,15 +113,18 @@ void mesh_recvloop(void){
mesh_cleanup();
nrf_rcv_pkt_start();
do{
};
uint8_t mesh_recvqloop_work(void){
__attribute__ ((aligned (4))) uint8_t buf[32];
int len;
len=nrf_rcv_pkt_poll_dec(sizeof(buf),buf,meshkey);
// Receive
if(len<=0){
delayms_power(10);
continue;
return 0;
};
pktctr++;
if(MO_GEN(buf)>meshgen){
if(meshgen)
@ -109,7 +141,7 @@ void mesh_recvloop(void){
_timet = toff;
meshincctr++;
};
continue;
return 1;
};
// Safety: Truncate ascii packets by 0-ing the CRC
@ -120,47 +152,67 @@ void mesh_recvloop(void){
// Skip locked packet
if(mpkt->flags&MF_LOCK)
continue;
return 2;
// only accept newer/better packets
if(mpkt->flags==MF_USED)
if(MO_TIME(buf)<MO_TIME(mpkt->pkt))
continue;
if(MO_TIME(buf)<=MO_TIME(mpkt->pkt))
return 2;
if((MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C') ||
(MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C'))
meshmsg=1;
memcpy(mpkt->pkt,buf,MESHPKTSIZE);
mpkt->flags=MF_USED;
return 1;
};
}while(getTimer()<recvend || pktctr>MESHBUFSIZE);
void mesh_recvqloop_end(void){
nrf_rcv_pkt_end();
nrf_config_set(&oldconfig);
}
void mesh_sendloop(void){
int ctr=0;
__attribute__ ((aligned (4))) uint8_t buf[32];
int status;
void mesh_recvloop(void){
int recvend=M_RECVTIM/SYSTICKSPEED+getTimer();
int pktctr=0;
nrf_config_get(&oldconfig);
nrf_set_channel(MESH_CHANNEL);
nrf_set_tx_mac(strlen(MESH_MAC),(uint8_t*)MESH_MAC);
mesh_recvqloop_setup();
do{
if( mesh_recvqloop_work() ){
pktctr++;
}else{
delayms_power(10);
};
}while(getTimer()<recvend || pktctr>MESHBUFSIZE);
mesh_recvqloop_end();
};
// Update [T]ime packet
MO_TIME_set(meshbuffer[0].pkt,getSeconds());
MO_GEN_set(meshbuffer[0].pkt,meshgen);
uint8_t mesh_recvloop_plus(uint8_t state){
static int recvend=0;
static int pktctr=0;
for (int i=0;i<MESHBUFSIZE;i++){
if(!meshbuffer[i].flags&MF_USED)
continue;
if(meshbuffer[i].flags&MF_LOCK)
continue;
ctr++;
memcpy(buf,meshbuffer[i].pkt,MESHPKTSIZE);
status=nrf_snd_pkt_crc_encr(MESHPKTSIZE,buf,meshkey);
//Check status? But what would we do...
if (state==0){
recvend=M_RECVTIM/SYSTICKSPEED+getTimer();
pktctr=0;
mesh_recvqloop_setup();
state=1;
};
if(state==1){
if( mesh_recvqloop_work() ){
pktctr++;
}else{
delayms_power(10);
};
if(getTimer()>recvend || pktctr>MESHBUFSIZE)
state=0xff;
};
if(state==0xff){
return 0xff;
};
nrf_config_set(&oldconfig);
return state;
};
void mesh_systick(void){
@ -168,7 +220,7 @@ void mesh_systick(void){
static int sendctr=0;
if(rcvctr--<0){
push_queue(&mesh_recvloop);
push_queue_plus(&mesh_recvloop_plus);
rcvctr=M_RECVINT/SYSTICKSPEED/2;
rcvctr+=getRandom()%(rcvctr*2);
};
@ -179,3 +231,4 @@ void mesh_systick(void){
sendctr+=getRandom()%(sendctr*2);
};
};

View File

@ -30,6 +30,7 @@ typedef struct {
extern char meshgen; // Generation
extern char meshincctr; // Time checker
extern char meshmsg; // Is there something interesting?
extern MPKT meshbuffer[MESHBUFSIZE];
void initMesh(void);

92
firmware/l0dable/1boot.c Normal file
View File

@ -0,0 +1,92 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "basic/config.h"
#include "lcd/print.h"
#include "usetable.h"
static void screen_intro();
static void set_privacy(int level);
static void privacy0();
static void privacy1();
static void privacy2();
static bool screen_overview();
static const char levels[][12] = {"0-trackable","1-mesh only","2-RF OFF"};
bool privacy_set;
static const struct MENU submenu_privacy={ "Privacy?", {
{ levels[0], &privacy0},
{ levels[1], &privacy1},
{ levels[2], &privacy2},
{NULL,NULL}
}};
void ram(void){
bool again = true;
menuflags|=(MENU_JUSTONCE|MENU_BIG);
screen_intro();
while (again) {
privacy_set = false;
while (!privacy_set) {
handleMenu(&submenu_privacy);
}
input("Nickname:", GLOBAL(nickname), 32, 127, MAXNICK-1);
getInputWaitRelease();
again = screen_overview();
}
menuflags&= (~(MENU_JUSTONCE|MENU_BIG));
writeFile("nick.cfg",GLOBAL(nickname),strlen(GLOBAL(nickname)));
saveConfig();
};
static void privacy0() {
set_privacy(0);
}
static void privacy1() {
set_privacy(1);
}
static void privacy2() {
set_privacy(2);
}
static void set_privacy(int level) {
GLOBAL(privacy) = level;
privacy_set = true;
}
static void screen_intro() {
lcdClear();
lcdPrintln("Welcome to");
lcdPrintln("r0ket");
lcdRefresh();
getInputWait();
getInputWaitRelease();
}
static bool screen_overview() {
char key = 0;
while (key != BTN_ENTER) {
lcdClear();
lcdPrintln("Privacy:");
lcdPrintln(levels[GLOBAL(privacy)]);
lcdPrintln("");
lcdPrintln("Nickname:");
lcdPrintln(GLOBAL(nickname));
lcdPrintln("");
lcdPrintln("LEFT: cancel");
lcdPrintln("ENTER: OK");
lcdRefresh();
key = getInputWait();
if (key == BTN_LEFT) {
//getInputWaitRelease();
return true;
}
}
return false;
}

View File

@ -72,3 +72,15 @@ nrf_check_reset
sspSend
sspReceive
sspSendReceive
getInputWait
lcdGetPixel
nickfont
setExtFont
getFontHeight
menuflags
delayms_queue_plus
getInputWaitTimeout
readFile
writeFile
input
saveConfig

View File

@ -44,10 +44,6 @@ $(LDFILE):
clean:
rm -f *.o *.elf *.bin usetable.h
IDIR=/cygdrive/f
install:
for a in $(BINS) ; do f=$${a#*/};cp $$a $(IDIR)/$${f%.bin}.c0d ; done
$(OBJS): usetable.h
usetable.h:

View File

@ -52,33 +52,33 @@ struct gamestate {
uint8_t bunker[BUNKERS][BUNKER_WIDTH];
} game;
char key;
bool highscore_set(uint32_t score, char nick[]);
uint32_t highscore_get(char nick[]);
void init_game();
void init_enemy();
void check_end();
void move_ufo();
void move_shot();
void move_shots();
void move_player();
void move_enemy();
void draw_score();
void draw_bunker();
void draw_player();
void draw_enemy();
void draw_shots();
void draw_sprite(char type, char x, char y);
void draw_ufo();
void screen_intro();
void screen_gameover();
void screen_level();
bool check_bunker(char xpos, char ypos, int8_t shift);
static bool highscore_set(uint32_t score, char nick[]);
static uint32_t highscore_get(char nick[]);
static void init_game();
static void init_enemy();
static void check_end();
static void move_ufo();
static void move_shot();
static void move_shots();
static void move_player();
static void move_enemy();
static void draw_score();
static void draw_bunker();
static void draw_player();
static void draw_enemy();
static void draw_shots();
static void draw_sprite(char type, char x, char y);
static void draw_ufo();
static bool screen_intro();
static bool screen_gameover();
static void screen_level();
static bool check_bunker(char xpos, char ypos, int8_t shift);
void ram(void) {
//gpioSetValue (RB_LED1, CFG_LED_OFF);
//backlightInit();
while(1) {
while(1) {
if (!screen_intro())
return;
screen_intro();
game.rokets = 3;
game.level = 1;
@ -104,19 +104,20 @@ void ram(void) {
lcdDisplay();
delayms(12);
}
screen_gameover();
if (!screen_gameover())
return;
}
return;
}
void screen_intro() {
static bool screen_intro() {
uint32_t highscore;
char highnick[20];
char key=0;
bool step = false;
while(key==0) {
lcdFill(0);
font = &Font_Invaders;
DoString(28,25,"ABC");
DoString(28,25,step?"ABC":"abc");
font = &Font_7x8;
DoString (28,40,"SPACE");
DoString (18,50,"INVADERS");
@ -125,49 +126,48 @@ void screen_intro() {
DoInt(0, 0, highscore);
DoString (0, 9, highnick);
lcdDisplay();
delayms_queue(50);
key=getInput();
step = !step;
key=getInputWaitTimeout(1);
}
return !(key==BTN_LEFT);
}
void screen_gameover() {
static bool screen_gameover() {
char key =0;
while(key==0) {
lcdFill(0);
font = &Font_7x8;
DoString (12,32, "GAME OVER");
DoString (14,32, "GAME OVER");
DoInt (0,0, game.score);
if (highscore_set(game.score, GLOBAL(nickname)))
DoString (0,9,"HIGHSCORE!");
lcdDisplay();
delayms_queue(50);
key=getInput();
key=getInputWaitTimeout(5);
}
return !(key==BTN_LEFT);
}
void screen_level() {
static void screen_level() {
lcdFill(0);
draw_score();
font = &Font_7x8;
int dx = DoString(20,32, "Level ");
DoInt(dx,32,game.level);
lcdDisplay();
delayms(500);
delayms_queue(500);
}
bool highscore_set(uint32_t score, char nick[]) {
static bool highscore_set(uint32_t score, char nick[]) {
MPKT * mpkt= meshGetMessage('i');
if(MO_TIME(mpkt->pkt)>score)
return false;
MO_TIME_set(mpkt->pkt,score);
strcpy((char*)MO_BODY(mpkt->pkt),nick);
return true;
}
uint32_t highscore_get(char nick[]){
static uint32_t highscore_get(char nick[]){
MPKT * mpkt= meshGetMessage('i');
strcpy(nick,(char*)MO_BODY(mpkt->pkt));
@ -175,7 +175,7 @@ uint32_t highscore_get(char nick[]){
return MO_TIME(mpkt->pkt);
}
void init_game(void) {
static void init_game(void) {
game.player = POS_PLAYER_X;
game.shot_x = DISABLED;
game.shot_y = 0;
@ -214,7 +214,7 @@ void init_game(void) {
}
}
void init_enemy() {
static void init_enemy() {
for (int row = 0; row<ENEMY_ROWS; row++) {
game.enemy_row_y[row] = 10 + (40/ENEMY_ROWS)*row;
for (int col = 0; col<ENEMY_COLUMNS; col++) {
@ -223,7 +223,7 @@ void init_enemy() {
}
}
bool check_bunker(char xpos, char ypos, int8_t shift){
static bool check_bunker(char xpos, char ypos, int8_t shift){
for (int b=0; b<BUNKERS; b++) {
if (xpos>BUNKER_X[BUNKERS-1-b] &&
xpos<BUNKER_X[BUNKERS-1-b]+BUNKER_WIDTH &&
@ -242,7 +242,7 @@ bool check_bunker(char xpos, char ypos, int8_t shift){
return false;
}
void move_shot() {
static void move_shot() {
//No shot, do nothing
if(game.shot_x == DISABLED) {
return;
@ -288,7 +288,7 @@ void move_shot() {
void move_shots() {
static void move_shots() {
for (int col = 0; col<ENEMY_COLUMNS; col++){
//No shot, maybe generate
if (game.shots_x[col] == DISABLED) {
@ -325,7 +325,7 @@ void move_shots() {
}
}
void move_ufo() {
static void move_ufo() {
if (game.ufo == DISABLED) {
if ((getRandom()%UFO_PROB)==0) {
game.ufo = 0;
@ -339,7 +339,7 @@ void move_ufo() {
game.ufo++;
}
void move_player() {
static void move_player() {
if(gpioGetValue(RB_BTN0)==0 && game.player > 0 ){
game.player-=1;
}
@ -354,7 +354,7 @@ void move_player() {
}
}
void move_enemy() {
static void move_enemy() {
if(game.move > 0){
game.move-=game.level/5+1;
return;
@ -392,16 +392,16 @@ void move_enemy() {
game.move = game.alive*2-1;
}
void draw_player() {
static void draw_player() {
draw_sprite(TYPE_PLAYER, game.player, POS_PLAYER_Y);
}
void draw_ufo() {
static void draw_ufo() {
if (game.ufo!=DISABLED)
draw_sprite(TYPE_UFO, game.ufo, POS_UFO_Y);
}
void draw_enemy() {
static void draw_enemy() {
for (int row = 0; row<ENEMY_ROWS; row++) {
for (int col = 0; col<ENEMY_COLUMNS; col++) {
if (game.enemy_x[row][col] != DISABLED) {
@ -411,13 +411,13 @@ void draw_enemy() {
}
}
void draw_bunker() {
static void draw_bunker() {
for (int b=0; b<BUNKERS; b++) {
memcpy(lcdBuffer+(RESX*1+BUNKER_X[b]),game.bunker+b,BUNKER_WIDTH);
}
}
void draw_shots() {
static void draw_shots() {
if (game.shot_x != 255) {
for (int length=0; length<=5; length++) {
lcdSetPixel(game.shot_x, game.shot_y+length, true);
@ -434,13 +434,13 @@ void draw_shots() {
}
void draw_status() {
static void draw_status() {
for (int p = 0; p<game.alive; p++){
lcdSetPixel(p+1,1,true);
}
}
void draw_sprite(char type, char x, char y) {
static void draw_sprite(char type, char x, char y) {
font = &Font_Invaders;
switch(type) {
case TYPE_PLAYER:
@ -461,7 +461,7 @@ void draw_sprite(char type, char x, char y) {
}
}
void draw_score() {
static void draw_score() {
font = &Font_7x8;
DoInt(0,0,game.score);
@ -471,10 +471,10 @@ void draw_score() {
}
void check_end() {
static void check_end() {
if (game.killed) {
game.rokets--;
delayms(500);
delayms_queue(500);
game.player = POS_PLAYER_X;
for(int col=0; col<ENEMY_COLUMNS; col++) {

View File

@ -0,0 +1,246 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "lcd/render.h"
#include "lcd/display.h"
#include "basic/config.h"
#include "usetable.h"
#define BITSET_X (RESX+2)
#define BITSET_Y (RESY+2)
#define BITSET_SIZE (BITSET_X*BITSET_Y)
#define BITSETCHUNKSIZE 32
#define one ((uint32_t)1)
struct bitset {
uint16_t size;
uint32_t bits[BITSET_SIZE/BITSETCHUNKSIZE+1];
};
typedef uint8_t uchar;
int pattern=0;
#define PATTERNCOUNT 3
uchar stepmode=0;
uchar randdensity=0;
//uint8_t bl=0;
struct bitset _buf1,*buf1=&_buf1;
struct bitset _buf2,*buf2=&_buf2;
struct bitset *life =&_buf1;
struct bitset *new =&_buf2;
static void draw_area();
static void calc_area();
static void random_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value);
static void reset_area();
static void nextledcycle();
void ram(void) {
getInputWaitRelease();
reset_area();
random_area(life,1,1,RESX,RESY,40);
lcdClear();
setExtFont(GLOBAL(nickfont));
DoString(20,20,GLOBAL(nickname));
#if 0
gpioSetValue (RB_LED0, CFG_LED_ON);
gpioSetValue (RB_LED1, CFG_LED_ON);
gpioSetValue (RB_LED2, CFG_LED_ON);
gpioSetValue (RB_LED3, CFG_LED_ON);
#endif
while (1) {
draw_area(); // xor life pattern over display content
lcdDisplay();
draw_area(); // xor life pattern again to restore original display content
lcdShift(1,-2,1);
if(getInputRaw())
return;
delayms_queue_plus(10,0);
calc_area();
}
return;
}
static inline void bitset_set(struct bitset *bs,uint16_t index, uint8_t value) {
uint16_t base=index/BITSETCHUNKSIZE;
uint16_t offset=index%BITSETCHUNKSIZE;
if(value) {
bs->bits[base]|=(one<<offset);
} else {
bs->bits[base]&=~(one<<offset);
}
}
static inline void bitset_xor(struct bitset *bs,uint16_t index, uint8_t value) {
uint16_t base=index/BITSETCHUNKSIZE;
uint16_t offset=index%BITSETCHUNKSIZE;
if(value) {
bs->bits[base]^=(one<<offset);
}
}
static inline uint8_t bitset_get(struct bitset *bs,uint16_t index) {
uint16_t base=index/BITSETCHUNKSIZE;
uint16_t offset=index%BITSETCHUNKSIZE;
return (bs->bits[base]&(one<<offset))==(one<<offset);;
}
static inline uint16_t bitset_offset2(uint8_t x, uint8_t y) {
return ((uint16_t)x)+((uint16_t)y)*BITSET_X;
}
static inline void bitset_set2(struct bitset *bs, uint8_t x, uint8_t y, uint8_t value) {
bitset_set(bs,bitset_offset2(x,y),value);
}
static inline void bitset_xor2(struct bitset *bs, uint8_t x, uint8_t y, uint8_t value) {
bitset_xor(bs,bitset_offset2(x,y),value);
}
static inline uint8_t bitset_get2(struct bitset *bs,uint8_t x,uint8_t y) {
return bitset_get(bs,bitset_offset2(x,y));
}
static void draw_rect(char x0, char y0, char x1, char y1) {
for(char x=x0; x<=x1; ++x) {
lcdSetPixel(x,y0,true);
lcdSetPixel(x,y1,true);
}
for(char y=y0+1; y<y1; ++y) {
lcdSetPixel(x0,y,true);
lcdSetPixel(x1,y,true);
}
}
static void fill_rect(char x0, char y0, char x1, char y1) {
for(char x=x0; x<=x1; ++x) {
for(char y=y0; y<=y1; ++y) {
lcdSetPixel(x,y,true);
}
}
}
#define STARTVALUE 10
static void swap_areas() {
struct bitset *tmp=life;
life=new;
new=tmp;
}
static void fill_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) {
for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) {
bitset_set2(area,x,y,value);
}
}
}
static bool find_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) {
for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) {
if(bitset_get2(area,x,y)==value) return true;
}
}
return false;
}
static uint32_t sum_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1) {
uint32_t sum=0;
for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) {
sum+=bitset_get2(area,x,y);
}
}
return sum;
}
static void draw_area() {
for(uchar x=0; x<RESX; ++x) {
for(uchar y=0; y<RESY; ++y) {
lcdSetPixel(x,y,lcdGetPixel(x,y)^bitset_get2(life,x+1,y+1));
}
}
}
static void calc_area() {
#ifdef SIMULATOR
static unsigned long iter=0;
fprintf(stderr,"Iteration %d \n",++iter);
#endif
for(uchar x=1; x<=RESX; ++x) {
for(uchar y=1; y<=RESY; ++y) {
uchar sum=sum_area(life,x-1,y-1,x+1,y+1)-bitset_get2(life,x,y);
bitset_set2(new,x,y,sum==3||(sum==2&&bitset_get2(life,x,y)));
}
}
swap_areas();
}
static void reset_area() {
fill_area(life,0,0,RESX+1,RESY+1,0);
fill_area(new,0,0,RESX+1,RESY+1,0);
switch(pattern) {
case 0:
bitset_set2(life,41,40,1);
bitset_set2(life,42,40,1);
bitset_set2(life,41,41,1);
bitset_set2(life,40,41,1);
bitset_set2(life,41,42,1);
break;
#if 0
case 1:
for(int i=0; i<RESX/2; ++i) bitset_set2(life,i,0,1);
bitset_set2(life,40,40,1);
bitset_set2(life,41,40,1);
bitset_set2(life,41,41,1);
break;
case 2:
bitset_set2(life,40,40,1);
bitset_set2(life,41,40,1);
bitset_set2(life,42,40,1);
bitset_set2(life,42,41,1);
bitset_set2(life,42,42,1);
bitset_set2(life,40,41,1);
bitset_set2(life,40,42,1);
break;
#endif
}
}
static void random_area(struct bitset *area, uchar x0, uchar y0, uchar x1, uchar y1,uchar value) {
for(uchar x=x0; x<=x1; ++x) {
for(uchar y=y0; y<=y1; ++y) {
bitset_set2(area,x,y,(getRandom()>>24)<value);
}
}
}
#define LEDINTERVAL 1
static void nextledcycle() {
static uint8_t ledcycle=3;
ledcycle=(ledcycle+1)%(8*LEDINTERVAL);
uint8_t a=ledcycle/LEDINTERVAL;
switch(a) {
case 0: gpioSetValue (RB_LED0, CFG_LED_ON); break;
case 4: gpioSetValue (RB_LED0, CFG_LED_OFF); break;
case 1: gpioSetValue (RB_LED1, CFG_LED_ON); break;
case 5: gpioSetValue (RB_LED1, CFG_LED_OFF); break;
case 2: gpioSetValue (RB_LED2, CFG_LED_ON); break;
case 6: gpioSetValue (RB_LED2, CFG_LED_OFF); break;
case 3: gpioSetValue (RB_LED3, CFG_LED_ON); break;
case 7: gpioSetValue (RB_LED3, CFG_LED_OFF); break;
}
}

View File

@ -0,0 +1,33 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "basic/config.h"
#include "lcd/lcd.h"
#include "lcd/print.h"
#include "usetable.h"
void ram(void) {
int dx=0;
int dy=0;
static uint32_t ctr=0;
ctr++;
setExtFont(GLOBAL(nickfont));
dx=DoString(0,0,GLOBAL(nickname));
dx=(RESX-dx)/2;
if(dx<0)
dx=0;
dy=(RESY-getFontHeight())/2;
lcdClear();
lcdSetPixel(1,1,1);
DoString(dx,dy,GLOBAL(nickname));
lcdRefresh();
while(getInputRaw()==BTN_NONE){
delayms_queue_plus(10,0);
};
return;
}

58
firmware/l0dable/pwgen.c Normal file
View File

@ -0,0 +1,58 @@
#include "basic/basic.h"
#include "usetable.h"
#define PW_LEN 8
void pw_cleanup(char * pw);
void pw_set(char * pw, uint16_t * k);
void ram(void)
{
char pw[PW_LEN+1];
uint16_t k[8];
int button;
memset(k, 0, 16);
while(1){
lcdClear();
lcdNl();
lcdPrintln(" password");
lcdPrintln(" generator");
lcdNl();
lcdNl();
pw_set(pw,k);
pw_cleanup(pw);
lcdPrint(" ");
lcdPrintln(pw);
lcdRefresh();
delayms(23);
while((button=getInputRaw())==BTN_NONE)
delayms(23);
if(button==BTN_LEFT) return;
}
}
void pw_cleanup(char * pw)
{
int i;
for(i=0;i<PW_LEN;i++)
{
/* strip unwanted ascii chars */
pw[i]&=0x7f;
if(pw[i]<0x30)pw[i]+=0x30;
if(pw[i]>0x7a)pw[i]-=0x10;
if((pw[i]>'Z')&&(pw[i]<'a'))
pw[i]-=0x10;
}
}
void pw_set(char * pw, uint16_t * k)
{
int i;
memset(pw,0,PW_LEN); /* wipe old PW */
for(i=0;i<4;i++)
k[1]=getRandom();
xxtea_encode_words(pw,PW_LEN/4,k);
pw[PW_LEN]=0;
}

View File

@ -9,6 +9,7 @@ OBJS += render.o
OBJS += decoder.o
OBJS += backlight.o
OBJS += print.o
OBJS += image.o
FONTS = $(basename $(wildcard fonts/*.c))

46
firmware/lcd/image.c Normal file
View File

@ -0,0 +1,46 @@
#include <sysinit.h>
#include "basic/basic.h"
#include "lcd/lcd.h"
#include "lcd/display.h"
#include "filesystem/ff.h"
int lcdLoadImage(char *file) {
return readFile(file,(char *)lcdBuffer,RESX*RESY_B);
}
int lcdSaveImage(char *file) {
return writeFile(file,(char *)lcdBuffer,RESX*RESY_B);
}
uint8_t lcdShowAnim(char *fname, uint32_t framems) {
FIL file; /* File object */
int res;
UINT readbytes;
uint8_t state=0;
res=f_open(&file, fname, FA_OPEN_EXISTING|FA_READ);
if(res)
return 1;
getInputWaitRelease();
while(!getInputRaw()){
lcdFill(0x55);
res = f_read(&file, (char *)lcdBuffer, RESX*RESY_B, &readbytes);
if(res)
return -1;
if(readbytes<RESX*RESY_B){
f_lseek(&file,0);
continue;
};
lcdDisplay();
state=delayms_queue_plus(framems,0);
}
if(state)
work_queue();
return 0;
};

8
firmware/lcd/image.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef __DISPLAYIMG_H_
#define __DISPLAYIMG_H_
void lcdLoadImage(char *file);
void lcdSaveImage(char *file);
uint8_t lcdShowAnim(char *file, uint32_t framems);
#endif

BIN
tools/font/ttf/SOVIET4.TTF Executable file

Binary file not shown.

77
tools/image/img2lcd.pl Executable file
View File

@ -0,0 +1,77 @@
#!/usr/bin/perl
# img2lcd.pl - by <sec@42.org> 05/2011, BSD Licence
#
# This script converts an image to .lcd format for the r0ket
use strict;
use warnings;
use Getopt::Long;
use Module::Load;
$|=1;
###
### Runtime Options
###
my ($verbose);
GetOptions (
"verbose" => \$verbose, # flag
"help" => sub {
print <<HELP;
Uasge: img2lcd.pl [-v]
Options:
--verbose Be verbose.
HELP
exit(-1);}
);
###
### Code starts here.
###
my $in=shift || "i42.gif";
my $out=$in;
$out=~s/\..*/.lcd/;
load GD;
my $image = GD::Image->new($in);
my $w=$image->width;
my $h=$image->height;
if($verbose){
print STDERR "$in: ${w}x$h\n\n";
};
my @img;
for my $y (0..$h-1){
for my $x (0..$w-1){
my $px= $image->getPixel($x,$y);
$img[$x][($y+4)/8]|=$px<<(7-($y+4)%8);
if($verbose){
$px=~y/01/ */; print STDERR $px;
};
};
if ($verbose){
print STDERR "<\n";
};
};
open(F,">",$out)||die "open: $!";
$|=1;
my $hb=int(($h-1)/8);
for my $y (0..$hb){
for my $x (0..$w-1){
printf F "%c",$img[$w-$x-1][$hb-$y];
};
};
close(F);

BIN
tools/image/lcd/i42.lcd Normal file

Binary file not shown.

BIN
tools/image/lcd/r0ket.lcd Normal file

Binary file not shown.

BIN
tools/image/src/i42.gif Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 340 B

BIN
tools/image/src/r0ket.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 362 B