#ifndef SET_LOGIC_STREAM_H #define SET_LOGIC_STREAM_H #include "logic_scope.h" typedef struct { uint8_t pending[LOGIC_SCOPE_MAX]; unsigned filled,target,previous,have_previous,triggered,sequence; } LogicStream; static inline unsigned logic_stream_divider(double span,unsigned rate) { static const unsigned fixed[]={0,1000,100,20,10}; if(rate>0&&rate<5)return fixed[rate]; double value=ceil(span*100000000.0/LOGIC_SCOPE_MAX); return !isfinite(value)||value<10?10:value>65535?65535:(unsigned)value; } static inline void logic_stream_reset(LogicStream *state,unsigned target) { memset(state,0,sizeof(*state));state->target=target<1?1:target>LOGIC_SCOPE_MAX?LOGIC_SCOPE_MAX:target; } static inline int logic_stream_match(unsigned mode,unsigned previous,unsigned current,unsigned valid,unsigned channel) { unsigned mask=1u<<(channel&7),a=previous&mask,b=current&mask; return !mode || (mode==1&&valid&&!a&&b)||(mode==2&&valid&&a&&!b)||(mode==3&&b)||(mode==4&&!b); } /* Sequence continuity is checked before touching the displayed frame. */ static inline int logic_stream_feed(LogicStream *state,LogicScope *scope,unsigned sequence,const uint8_t *bytes,unsigned count) { if(sequence!=state->sequence)return -1; ++state->sequence;scope->stream_samples+=count;int updated=0; unsigned i=0; while(itriggered&&itriggered=logic_stream_match(scope->trigger_mode,state->previous,current,state->have_previous,scope->trigger_channel); if(!state->triggered){state->previous=current;state->have_previous=1;++i;} } if(i==count)break; unsigned take=state->target-state->filled;if(take>count-i)take=count-i; memcpy(state->pending+state->filled,bytes+i,take);state->filled+=take;i+=take; state->previous=bytes[i-1];state->have_previous=1; if(state->filled==state->target){memcpy(scope->samples,state->pending,state->target);scope->count=state->target;scope->origin_s=0;++scope->generation;updated=1;state->filled=0;state->triggered=0; if(scope->single){scope->single=scope->running=0;break;} } }return updated; } #endif