diff --git a/firmware/basic/basic.h b/firmware/basic/basic.h index 008baef..8d0bcc1 100644 --- a/firmware/basic/basic.h +++ b/firmware/basic/basic.h @@ -205,5 +205,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/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/funk/mesh.c b/firmware/funk/mesh.c index 2b73995..6ff2c27 100644 --- a/firmware/funk/mesh.c +++ b/firmware/funk/mesh.c @@ -84,7 +84,7 @@ void mesh_sendloop(void){ // Update [T]ime packet MO_TIME_set(meshbuffer[0].pkt,getSeconds()); MO_GEN_set(meshbuffer[0].pkt,meshgen); - if(GLOBAL(provacy)==0) + if(GLOBAL(privacy)==0) uint32touint8p(GetUUID32(),MO_BODY(meshbuffer[0].pkt)); else uint32touint8p(0,MO_BODY(meshbuffer[0].pkt)); @@ -152,12 +152,12 @@ uint8_t mesh_recvqloop_work(void){ // Skip locked packet if(mpkt->flags&MF_LOCK) - return 1; + return 2; // only accept newer/better packets if(mpkt->flags==MF_USED) if(MO_TIME(buf)<=MO_TIME(mpkt->pkt)) - return 1; + return 2; if((MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C') || (MO_TYPE(buf)>='A' && MO_TYPE(buf)<='C')) @@ -165,6 +165,7 @@ uint8_t mesh_recvqloop_work(void){ memcpy(mpkt->pkt,buf,MESHPKTSIZE); mpkt->flags=MF_USED; + return 1; }; void mesh_recvqloop_end(void){ @@ -187,12 +188,39 @@ void mesh_recvloop(void){ mesh_recvqloop_end(); }; +uint8_t mesh_recvloop_plus(uint8_t state){ + static int recvend=0; + static int pktctr=0; + + 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; + }; + + return state; +}; + void mesh_systick(void){ static int rcvctr=0; 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); }; diff --git a/firmware/l0dable/EXPORTS b/firmware/l0dable/EXPORTS index b0d95e9..7242605 100644 --- a/firmware/l0dable/EXPORTS +++ b/firmware/l0dable/EXPORTS @@ -78,3 +78,4 @@ nickfont setExtFont getFontHeight menuflags +delayms_queue_plus diff --git a/firmware/l0dable/nick_plain.c b/firmware/l0dable/nick_plain.c index 47821e2..5a24671 100644 --- a/firmware/l0dable/nick_plain.c +++ b/firmware/l0dable/nick_plain.c @@ -22,11 +22,12 @@ void ram(void) { dy=(RESY-getFontHeight())/2; lcdClear(); + lcdSetPixel(1,1,1); DoString(dx,dy,GLOBAL(nickname)); lcdRefresh(); while(getInputRaw()==BTN_NONE){ - work_queue(); + delayms_queue_plus(10,0); }; return; }