diff --git a/firmware/applications/default.c b/firmware/applications/default.c index 6b0c843..db93123 100644 --- a/firmware/applications/default.c +++ b/firmware/applications/default.c @@ -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; }; diff --git a/firmware/applications/final.c b/firmware/applications/final.c index cce4e3b..b46a770 100644 --- a/firmware/applications/final.c +++ b/firmware/applications/final.c @@ -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; diff --git a/firmware/applications/final/config.c b/firmware/applications/final/config.c index 3761494..a3a0921 100644 --- a/firmware/applications/final/config.c +++ b/firmware/applications/final/config.c @@ -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"); }; + lcdRefresh(); } lcdRefresh(); - j=menuselection; - int t=0; - while(j){ - if(!the_config[t].disabled) - j--; - t++; - } - switch (getInputWaitRepeat()) { case BTN_UP: menuselection--; diff --git a/firmware/applications/final/mesh.c b/firmware/applications/final/mesh.c index ef3fa22..20593fd 100644 --- a/firmware/applications/final/mesh.c +++ b/firmware/applications/final/mesh.c @@ -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; + }; }; diff --git a/firmware/applications/final/nickname.c b/firmware/applications/final/nickname.c index 11cf4ed..2882293 100644 --- a/firmware/applications/final/nickname.c +++ b/firmware/applications/final/nickname.c @@ -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(); +}; diff --git a/firmware/basic/basic.c b/firmware/basic/basic.c index 749547b..f0deb7d 100644 --- a/firmware/basic/basic.c +++ b/firmware/basic/basic.c @@ -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) { } diff --git a/firmware/basic/basic.h b/firmware/basic/basic.h index 0493eaa..ac0734a 100644 --- a/firmware/basic/basic.h +++ b/firmware/basic/basic.h @@ -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 diff --git a/firmware/basic/config.c b/firmware/basic/config.c index 2533e06..351015f 100644 --- a/firmware/basic/config.c +++ b/firmware/basic/config.c @@ -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)); diff --git a/firmware/basic/config.h b/firmware/basic/config.h index 9654b38..f018fc2 100644 --- a/firmware/basic/config.h +++ b/firmware/basic/config.h @@ -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 diff --git a/firmware/basic/idle.c b/firmware/basic/idle.c index 623154b..9682675 100644 --- a/firmware/basic/idle.c +++ b/firmware/basic/idle.c @@ -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; diff --git a/firmware/basic/idle.h b/firmware/basic/idle.h index 8e406a8..5d73dac 100644 --- a/firmware/basic/idle.h +++ b/firmware/basic/idle.h @@ -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. diff --git a/firmware/basic/menu.c b/firmware/basic/menu.c index 97b0b60..b4824f0 100644 --- a/firmware/basic/menu.c +++ b/firmware/basic/menu.c @@ -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; diff --git a/firmware/filesystem/execute.c b/firmware/filesystem/execute.c index 3ae2a86..c50426c 100644 --- a/firmware/filesystem/execute.c +++ b/firmware/filesystem/execute.c @@ -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; }; diff --git a/firmware/filesystem/execute.h b/firmware/filesystem/execute.h index 8c52cae..4e2c654 100644 --- a/firmware/filesystem/execute.h +++ b/firmware/filesystem/execute.h @@ -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 diff --git a/firmware/funk/mesh.c b/firmware/funk/mesh.c index e15656d..6ff2c27 100644 --- a/firmware/funk/mesh.c +++ b/firmware/funk/mesh.c @@ -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;imeshgen){ 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)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()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()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;irecvend || 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); }; }; + diff --git a/firmware/funk/mesh.h b/firmware/funk/mesh.h index 2ff8f35..1fe069d 100644 --- a/firmware/funk/mesh.h +++ b/firmware/funk/mesh.h @@ -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); diff --git a/firmware/l0dable/1boot.c b/firmware/l0dable/1boot.c new file mode 100644 index 0000000..3b57a42 --- /dev/null +++ b/firmware/l0dable/1boot.c @@ -0,0 +1,92 @@ +#include + +#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; +} + diff --git a/firmware/l0dable/EXPORTS b/firmware/l0dable/EXPORTS index c8ddcd5..b3a3e8d 100644 --- a/firmware/l0dable/EXPORTS +++ b/firmware/l0dable/EXPORTS @@ -72,3 +72,15 @@ nrf_check_reset sspSend sspReceive sspSendReceive +getInputWait +lcdGetPixel +nickfont +setExtFont +getFontHeight +menuflags +delayms_queue_plus +getInputWaitTimeout +readFile +writeFile +input +saveConfig diff --git a/firmware/l0dable/Makefile b/firmware/l0dable/Makefile index 8da03dc..c97d8de 100644 --- a/firmware/l0dable/Makefile +++ b/firmware/l0dable/Makefile @@ -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: diff --git a/firmware/l0dable/invaders.c b/firmware/l0dable/invaders.c index 8fef54c..c2f6062 100644 --- a/firmware/l0dable/invaders.c +++ b/firmware/l0dable/invaders.c @@ -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; rowBUNKER_X[BUNKERS-1-b] && xpos 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 + +#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<bits[base]&=~(one<bits[base]^=(one<bits[base]&(one<>24) + +#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; +} diff --git a/firmware/l0dable/pwgen.c b/firmware/l0dable/pwgen.c new file mode 100644 index 0000000..329f6c5 --- /dev/null +++ b/firmware/l0dable/pwgen.c @@ -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;i0x7a)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; +} + diff --git a/firmware/lcd/Makefile b/firmware/lcd/Makefile index fe639a3..e9b8d76 100644 --- a/firmware/lcd/Makefile +++ b/firmware/lcd/Makefile @@ -9,6 +9,7 @@ OBJS += render.o OBJS += decoder.o OBJS += backlight.o OBJS += print.o +OBJS += image.o FONTS = $(basename $(wildcard fonts/*.c)) diff --git a/firmware/lcd/image.c b/firmware/lcd/image.c new file mode 100644 index 0000000..6d6b90a --- /dev/null +++ b/firmware/lcd/image.c @@ -0,0 +1,46 @@ +#include + +#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 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 <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); diff --git a/tools/image/lcd/i42.lcd b/tools/image/lcd/i42.lcd new file mode 100644 index 0000000..f8b96a3 Binary files /dev/null and b/tools/image/lcd/i42.lcd differ diff --git a/tools/image/lcd/r0ket.lcd b/tools/image/lcd/r0ket.lcd new file mode 100644 index 0000000..cbe462a Binary files /dev/null and b/tools/image/lcd/r0ket.lcd differ diff --git a/tools/image/src/i42.gif b/tools/image/src/i42.gif new file mode 100755 index 0000000..acd34ee Binary files /dev/null and b/tools/image/src/i42.gif differ diff --git a/tools/image/src/r0ket.gif b/tools/image/src/r0ket.gif new file mode 100644 index 0000000..0b043a9 Binary files /dev/null and b/tools/image/src/r0ket.gif differ