Просмотр исходного кода

Duration filter now changes according to preset data rate.

After this change, 30us signals generated with "sendook"
of rpitx are detected correctly, using the OOK 40kBaud modulation.
antirez 3 лет назад
Родитель
Сommit
e7a81d178e
5 измененных файлов с 35 добавлено и 21 удалено
  1. 2 1
      app.c
  2. 6 3
      app.h
  3. 15 10
      app_subghz.c
  4. 11 6
      signal.c
  5. 1 1
      view_build.c

+ 2 - 1
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

+ 6 - 3
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);

+ 15 - 10
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

+ 11 - 6
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) {

+ 1 - 1
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);
         }