queue_plus: allows for incremental queue stuff (nrf receive mostly)

This commit is contained in:
Stefan `Sec` Zehl 2011-08-04 19:10:22 +02:00
parent 009897df88
commit a41ca4d93d
6 changed files with 126 additions and 29 deletions

View File

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

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

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

View File

@ -78,3 +78,4 @@ nickfont
setExtFont
getFontHeight
menuflags
delayms_queue_plus

View File

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