diff --git a/app.c b/app.c index a39f32d1892..358ace58967 100644 --- a/app.c +++ b/app.c @@ -215,7 +215,8 @@ static void timer_callback(void *ctx) { } if (delta < RawSamples->total/2) return; app->signal_last_scan_idx = RawSamples->idx; - scan_for_signal(app,RawSamples); + scan_for_signal(app,RawSamples, + ProtoViewModulations[app->modulation].duration_filter); } /* This is the navigation callback we use in the view dispatcher used diff --git a/app.h b/app.h index 2621f1f43c6..a579df5111b 100644 --- a/app.h +++ b/app.h @@ -66,8 +66,11 @@ typedef struct { const char *name; // Name to show to the user. const char *id; // Identifier in the Flipper API/file. FuriHalSubGhzPreset preset; // The preset ID. - uint8_t *custom; // If not null, a set of registers for - // the CC1101, specifying a custom preset. + uint8_t *custom; /* If not null, a set of registers for + the CC1101, specifying a custom preset.*/ + uint32_t duration_filter; /* Ignore pulses and gaps that are less + than the specified microseconds. This + depends on the data rate. */ } ProtoViewModulation; extern ProtoViewModulation ProtoViewModulations[]; /* In app_subghz.c */ @@ -250,7 +253,7 @@ void protoview_rx_callback(bool level, uint32_t duration, void* context); /* signal.c */ uint32_t duration_delta(uint32_t a, uint32_t b); void reset_current_signal(ProtoViewApp *app); -void scan_for_signal(ProtoViewApp *app,RawSamplesBuffer *source); +void scan_for_signal(ProtoViewApp *app,RawSamplesBuffer *source,uint32_t min_duration); bool bitmap_get(uint8_t *b, uint32_t blen, uint32_t bitpos); void bitmap_set(uint8_t *b, uint32_t blen, uint32_t bitpos, bool val); void bitmap_copy(uint8_t *d, uint32_t dlen, uint32_t doff, uint8_t *s, uint32_t slen, uint32_t soff, uint32_t count); diff --git a/app_subghz.c b/app_subghz.c index 4155d278b96..b17d36f18cd 100644 --- a/app_subghz.c +++ b/app_subghz.c @@ -14,19 +14,24 @@ void raw_sampling_timer_stop(ProtoViewApp *app); ProtoViewModulation ProtoViewModulations[] = { {"OOK 650Khz", "FuriHalSubGhzPresetOok650Async", - FuriHalSubGhzPresetOok650Async, NULL}, + FuriHalSubGhzPresetOok650Async, NULL, 30}, {"OOK 270Khz", "FuriHalSubGhzPresetOok270Async", - FuriHalSubGhzPresetOok270Async, NULL}, + FuriHalSubGhzPresetOok270Async, NULL, 30}, {"2FSK 2.38Khz", "FuriHalSubGhzPreset2FSKDev238Async", - FuriHalSubGhzPreset2FSKDev238Async, NULL}, + FuriHalSubGhzPreset2FSKDev238Async, NULL, 30}, {"2FSK 47.6Khz", "FuriHalSubGhzPreset2FSKDev476Async", - FuriHalSubGhzPreset2FSKDev476Async, NULL}, - {"TPMS 1 (FSK)", NULL, 0, (uint8_t*)protoview_subghz_tpms1_fsk_async_regs}, - {"TPMS 2 (OOK)", NULL, 0, (uint8_t*)protoview_subghz_tpms2_ook_async_regs}, - {"TPMS 3 (GFSK)", NULL, 0, (uint8_t*)protoview_subghz_tpms3_gfsk_async_regs}, - {"OOK 40kBaud", NULL, 0, (uint8_t*)protoview_subghz_40k_ook_async_regs}, - {"FSK 40kBaud", NULL, 0, (uint8_t*)protoview_subghz_40k_fsk_async_regs}, - {NULL, NULL, 0, NULL} /* End of list sentinel. */ + FuriHalSubGhzPreset2FSKDev476Async, NULL, 30}, + {"TPMS 1 (FSK)", NULL, + 0, (uint8_t*)protoview_subghz_tpms1_fsk_async_regs, 30}, + {"TPMS 2 (OOK)", NULL, + 0, (uint8_t*)protoview_subghz_tpms2_ook_async_regs, 30}, + {"TPMS 3 (GFSK)", NULL, + 0, (uint8_t*)protoview_subghz_tpms3_gfsk_async_regs, 30}, + {"OOK 40kBaud", NULL, + 0, (uint8_t*)protoview_subghz_40k_ook_async_regs, 15}, + {"FSK 40kBaud", NULL, + 0, (uint8_t*)protoview_subghz_40k_fsk_async_regs, 15}, + {NULL, NULL, 0, NULL, 0} /* End of list sentinel. */ }; /* Called after the application initialization in order to setup the diff --git a/signal.c b/signal.c index f4c5ebedf35..fa7f86d6df0 100644 --- a/signal.c +++ b/signal.c @@ -39,15 +39,20 @@ void reset_current_signal(ProtoViewApp *app) { * For instance Oregon2 sensors, in the case of protocol 2.1 will send * pulses of ~400us (RF on) VS ~580us (RF off). */ #define SEARCH_CLASSES 3 -uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) { +uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx, uint32_t min_duration) { struct { uint32_t dur[2]; /* dur[0] = low, dur[1] = high */ uint32_t count[2]; /* Associated observed frequency. */ } classes[SEARCH_CLASSES]; memset(classes,0,sizeof(classes)); - uint32_t minlen = 30, maxlen = 4000; /* Depends on data rate, here we - allow for high and low. */ + + // Set a min/max duration limit for samples to be considered part of a + // coherent signal. The maximum length is fixed while the minimum + // is passed as argument, as depends on the data rate and in general + // on the signal to analyze. + uint32_t max_duration = 4000; + uint32_t len = 0; /* Observed len of coherent samples. */ s->short_pulse_dur = 0; for (uint32_t j = idx; j < idx+500; j++) { @@ -55,7 +60,7 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) { uint32_t dur; raw_samples_get(s, j, &level, &dur); - if (dur < minlen || dur > maxlen) break; /* return. */ + if (dur < min_duration || dur > max_duration) break; /* return. */ /* Let's see if it matches a class we already have or if we * can populate a new (yet empty) class. */ @@ -149,7 +154,7 @@ void notify_signal_detected(ProtoViewApp *app, bool decoded) { * in order to find a coherent signal. If a signal that does not appear to * be just noise is found, it is set in DetectedSamples global signal * buffer, that is what is rendered on the screen. */ -void scan_for_signal(ProtoViewApp *app, RawSamplesBuffer *source) { +void scan_for_signal(ProtoViewApp *app, RawSamplesBuffer *source, uint32_t min_duration) { /* We need to work on a copy: the source buffer may be populated * by the background thread receiving data. */ RawSamplesBuffer *copy = raw_samples_alloc(); @@ -164,7 +169,7 @@ void scan_for_signal(ProtoViewApp *app, RawSamplesBuffer *source) { uint32_t i = 0; while (i < copy->total-1) { - uint32_t thislen = search_coherent_signal(copy,i); + uint32_t thislen = search_coherent_signal(copy,i,min_duration); /* For messages that are long enough, attempt decoding. */ if (thislen > minlen) { diff --git a/view_build.c b/view_build.c index fd276b61d6c..b47c2c9c232 100644 --- a/view_build.c +++ b/view_build.c @@ -207,7 +207,7 @@ static void process_input_set_fields(ProtoViewApp *app, InputEvent input) { privdata->decoder->build_message(rs,privdata->fieldset); app->signal_decoded = false; // So that the new signal will be // accepted as the current signal. - scan_for_signal(app,rs); + scan_for_signal(app,rs,5); raw_samples_free(rs); ui_show_alert(app,"Done: press back key",3000); }