Skip to content

Commit

Permalink
Duration filter now changes according to preset data rate.
Browse files Browse the repository at this point in the history
After this change, 30us signals generated with "sendook"
of rpitx are detected correctly, using the OOK 40kBaud modulation.
  • Loading branch information
antirez committed Jan 24, 2023
1 parent 6a9baf2 commit e7a81d1
Show file tree
Hide file tree
Showing 5 changed files with 35 additions and 21 deletions.
3 changes: 2 additions & 1 deletion app.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 6 additions & 3 deletions app.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -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);
Expand Down
25 changes: 15 additions & 10 deletions app_subghz.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
17 changes: 11 additions & 6 deletions signal.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,28 @@ 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++) {
bool level;
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. */
Expand Down Expand Up @@ -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();
Expand All @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion view_build.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit e7a81d1

Please sign in to comment.