Files
templates/c/logic-scope/include/scope_decoders.h
T

76 lines
5.6 KiB
C

#ifndef SCOPE_DECODERS_H
#define SCOPE_DECODERS_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#define SD_ITEMS 256
#define SD_FIELDS 2048
#define SD_RESULTS 4096
typedef struct { char id[64],name[96],inputs[128],outputs[128]; int unavailable; } ScopeDecoder;
typedef struct { int owner,channel,mandatory; char id[64],name[128],value[128],choices[512]; } ScopeDecoderField;
typedef struct { uint64_t start,end; char decoder[64],row[96],text[256]; } ScopeAnnotation;
typedef struct {
ScopeDecoder items[SD_ITEMS]; ScopeDecoderField fields[SD_FIELDS]; ScopeAnnotation results[SD_RESULTS];
unsigned order[SD_ITEMS],count,field_count,result_count; int open,view,page,selected,edit,request,busy;
unsigned chain[8],chain_count,visible_fields[128],visible_count; double rate;
char status[160],edit_text[128];
} ScopeDecoders;
static inline void sd_copy(char *to,size_t size,const char *from) { size_t n=strlen(from); if(n>=size)n=size-1; memcpy(to,from,n);to[n]=0; }
static inline unsigned sd_split(char *line,char **out,unsigned cap) {
unsigned n=0; char *p=line; while(n<cap) { out[n++]=p; char *end=strchr(p,'\t'); if(!end)break;*end=0;p=end+1; }
if(n)out[n-1][strcspn(out[n-1],"\r\n")]=0; return n;
}
static inline int sd_find(const ScopeDecoders *s,const char *id) { for(unsigned i=0;i<s->count;++i)if(!strcmp(s->items[i].id,id))return (int)i;return -1; }
static inline int sd_has(const char *list,const char *token) {
size_t n=strlen(token);for(const char *p=list;*p;) {const char *e=strchr(p,'|');size_t k=e?(size_t)(e-p):strlen(p);if(k==n&&!strncmp(p,token,n))return 1;if(!e)break;p=e+1;}return 0;
}
static inline int sd_catalog(ScopeDecoders *s,const char *path) {
FILE *f=fopen(path,"r");if(!f)return 0;s->count=s->field_count=0;char line[4096];
while(fgets(line,sizeof(line),f)) {char *v[8];unsigned n=sd_split(line,v,8);
if((!strcmp(v[0],"D")||!strcmp(v[0],"E"))&&n>=3&&s->count<SD_ITEMS) {
ScopeDecoder *d=&s->items[s->count++];memset(d,0,sizeof(*d));sd_copy(d->id,sizeof(d->id),v[1]);sd_copy(d->name,sizeof(d->name),v[2]);d->unavailable=v[0][0]=='E';
if(n>=5){sd_copy(d->inputs,sizeof(d->inputs),v[3]);sd_copy(d->outputs,sizeof(d->outputs),v[4]);}
} else if((v[0][0]=='C'||v[0][0]=='O')&&n>=5&&s->field_count<SD_FIELDS) {
int owner=sd_find(s,v[1]);if(owner<0)continue;ScopeDecoderField *d=&s->fields[s->field_count++];memset(d,0,sizeof(*d));d->owner=owner;d->channel=v[0][0]=='C';
sd_copy(d->id,sizeof(d->id),v[2]);sd_copy(d->name,sizeof(d->name),v[3]);d->mandatory=d->channel&&atoi(v[4]);
sd_copy(d->value,sizeof(d->value),d->channel?"-1":n>5?v[5]:"");if(n>6)sd_copy(d->choices,sizeof(d->choices),v[6]);
}
}fclose(f);for(unsigned i=0;i<s->count;++i){unsigned j=i;s->order[i]=i;while(j>0&&strcmp(s->items[s->order[j-1]].id,s->items[i].id)>0){s->order[j]=s->order[j-1];--j;}s->order[j]=i;}snprintf(s->status,sizeof(s->status),"%u DSView decoders / D0-D7 inputs",s->count);return s->count!=0;
}
static inline int sd_resolve(ScopeDecoders *s,unsigned id,unsigned depth) {
if(depth>=8||id>=s->count||s->items[id].unavailable)return 0;
ScopeDecoder *d=&s->items[id];if(sd_has(d->inputs,"logic")){s->chain[s->chain_count++]=id;return 1;}
char inputs[128];sd_copy(inputs,sizeof(inputs),d->inputs);char *p=inputs;
while(*p) {char *end=strchr(p,'|');if(end)*end=0;int base=sd_find(s,p);
if(base>=0&&(unsigned)base!=id&&sd_resolve(s,(unsigned)base,depth+1)){s->chain[s->chain_count++]=id;return 1;}
for(int direct=1;direct>=0;--direct)for(unsigned i=0;i<s->count;++i)if(i!=id&&sd_has(s->items[i].inputs,"logic")==direct&&sd_has(s->items[i].outputs,p)&&sd_resolve(s,i,depth+1)){s->chain[s->chain_count++]=id;return 1;}
if(!end)break;p=end+1;
}return 0;
}
static inline void sd_select(ScopeDecoders *s,unsigned id) {
s->selected=(int)id;s->page=0;s->view=1;s->edit=-1;s->chain_count=s->visible_count=0;
if(!sd_resolve(s,id,0)){sd_copy(s->status,sizeof(s->status),"No supported logic input stack / import failed");return;}
unsigned next=0;
for(unsigned c=0;c<s->chain_count;++c)for(unsigned f=0;f<s->field_count;++f)if(s->fields[f].owner==(int)s->chain[c]&&s->visible_count<128){
s->visible_fields[s->visible_count++]=f;ScopeDecoderField *field=&s->fields[f];
if(field->channel&&field->mandatory&&atoi(field->value)<0&&next<8)snprintf(field->value,sizeof(field->value),"%u",next++);
}
sd_copy(s->status,sizeof(s->status),"Tap a field to change. DECODE uses the last digital snapshot.");
}
static inline int sd_config(const ScopeDecoders *s,const char *path) {
FILE *f=fopen(path,"w");if(!f)return 0;
for(unsigned c=0;c<s->chain_count;++c){unsigned id=s->chain[c];fprintf(f,"[%s]\n",s->items[id].id);
for(unsigned i=0;i<s->field_count;++i){const ScopeDecoderField *d=&s->fields[i];if(d->owner==(int)id)fprintf(f,"%s.%s=%s\n",d->channel?"ch":"opt",d->id,d->value);}}
int error=ferror(f);return fclose(f)==0&&!error;
}
static inline int sd_results(ScopeDecoders *s,const char *path) {
FILE *f=fopen(path,"r");if(!f)return 0;char line[2048];s->result_count=0;sd_copy(s->status,sizeof(s->status),"No annotations / check channel mapping and sample rate");
while(fgets(line,sizeof(line),f)){char *v[7];unsigned n=sd_split(line,v,7);
if(n>=6&&!strcmp(v[0],"A")&&s->result_count<SD_RESULTS){ScopeAnnotation *a=&s->results[s->result_count++];a->start=strtoull(v[1],NULL,10);a->end=strtoull(v[2],NULL,10);sd_copy(a->decoder,sizeof(a->decoder),v[3]);sd_copy(a->row,sizeof(a->row),v[4]);sd_copy(a->text,sizeof(a->text),v[5]);}
else if(n>=2&&!strcmp(v[0],"ERROR"))sd_copy(s->status,sizeof(s->status),v[1]);
else if(n>=3&&!strcmp(v[0],"DONE")&&s->result_count)snprintf(s->status,sizeof(s->status),"%u annotations / %s",s->result_count,v[2]);
}fclose(f);s->view=2;s->page=0;return 1;
}
#endif