From 6015afe36894d67a74d911671a4deee8f1b64bb3 Mon Sep 17 00:00:00 2001 From: jbohack Date: Fri, 13 Jan 2023 10:02:14 -0500 Subject: [PATCH] updated protoview and fixed array count issue arrays start at 0 and citroen_tpms was trying to read 0-10 meaning 11 full bytes rather than actually 10 (0-9). --- applications/plugins/protoview/README.md | 32 ++++++- applications/plugins/protoview/TODO | 28 +++---- applications/plugins/protoview/app.c | 48 ++++++++--- applications/plugins/protoview/app.h | 23 ++++++ applications/plugins/protoview/app_subghz.c | 78 ++++++++++++++++-- .../plugins/protoview/application.fam | 2 +- .../plugins/protoview/binaries/protoview.fap | Bin 21208 -> 28520 bytes .../plugins/protoview/binaries/update.sh | 4 + applications/plugins/protoview/crc.c | 20 +++++ .../plugins/protoview/custom_presets.h | 62 +++++++++++++- .../protoview/{proto.c => data_feed.c} | 0 .../plugins/protoview/images/protoview_1.jpg | Bin 0 -> 66885 bytes .../plugins/protoview/images/protoview_2.jpg | Bin 0 -> 64574 bytes .../plugins/protoview/protocols/b4b1.c | 2 +- .../protoview/protocols/citroen_tpms.c | 60 ++++++++++++++ .../plugins/protoview/protocols/ford_tpms.c | 64 ++++++++++++++ .../protoview/protocols/renault_tpms.c | 25 +++--- .../protoview/protocols/schrader_tpms.c | 65 +++++++++++++++ .../plugins/protoview/protocols/toyota_tpms.c | 77 +++++++++++++++++ applications/plugins/protoview/signal.c | 72 ++++++++++++---- .../plugins/protoview/view_direct_sampling.c | 35 ++++++-- applications/plugins/protoview/view_info.c | 21 ++--- .../plugins/protoview/view_settings.c | 34 ++++++-- 23 files changed, 663 insertions(+), 89 deletions(-) create mode 100644 applications/plugins/protoview/binaries/update.sh create mode 100644 applications/plugins/protoview/crc.c rename applications/plugins/protoview/{proto.c => data_feed.c} (100%) create mode 100644 applications/plugins/protoview/images/protoview_1.jpg create mode 100644 applications/plugins/protoview/images/protoview_2.jpg create mode 100644 applications/plugins/protoview/protocols/citroen_tpms.c create mode 100644 applications/plugins/protoview/protocols/ford_tpms.c create mode 100644 applications/plugins/protoview/protocols/schrader_tpms.c create mode 100644 applications/plugins/protoview/protocols/toyota_tpms.c diff --git a/applications/plugins/protoview/README.md b/applications/plugins/protoview/README.md index 4b8a3c3a0..8359c073d 100644 --- a/applications/plugins/protoview/README.md +++ b/applications/plugins/protoview/README.md @@ -6,11 +6,24 @@ the car keys), the curious person is left wondering what the device is sending at all. Using ProtoView she or he can visualize the high and low pulses like in the example image below (showing a Volkswagen key in 2FSK): -![ProtoView screenshot](/images/ProtoViewSignal.jpg) +![ProtoView screenshot raw signal](/images/protoview_1.jpg) This is often enough to make an initial idea about the encoding used and if the selected modulation is correct. +Other than that, ProtoView is able to decode a few interesting protocols: + +* TPMS sensors: Renault, Toyota, Schrader, Citroen, Ford. +* Oregon thermometer protocol 2. +* PTxxxx/SCxxxx based remotes. +* ... more will be implemented soon, hopefully. Send PRs :) + +![ProtoView screenshot Renault TPMS data](/images/protoview_2.jpg) + +The app implements a framework that makes adding and experimenting with new +protocols very simple. Check the `protocols` directory to see how the +API works. + The secondary goal of ProtoView is to provide a somewhat-documented application for the Flipper (even if ProtoView is a pretty atypical application: doesn't make use of the standard widgets and other abstractions provded by the framework). Many apps dealing with the *subghz subsystem* (the Flipper @@ -40,7 +53,7 @@ encodings are somewhat self-clocked, so they tend to have just two or three classes of pulse lengths. However often pulses of the same theoretical -length have slightly different lenghts in the case of high and low level +length have slightly different lengths in the case of high and low level (RF on or off), so we classify them separately for robustness. # Usage @@ -55,6 +68,10 @@ Under the detected sequence, you will see a small triangle marking a specific sample. This mark means that the sequence looked coherent up to that point, and starting from there it could be just noise. +If the protocol is decoded, the bottom-left corner of the screen +will show the name of the protocol, and going in the next screen +with the right arrow will show information about the decoded signal. + In the bottom-right corner the application displays an amount of time in microseconds. This is the average length of the shortest pulse length detected among the three classes. Usually the *data rate* of the protocol @@ -67,7 +84,8 @@ Things to investigate: * Many cheap remotes (gate openers, remotes, ...) are on the 433.92Mhz or nearby and use OOK modulation. * Weather stations are often too in the 433.92Mhz OOK. -* For car keys, try 443.92 OOK650 and 868.35 Mhz in OOK or 2FSK. +* For car keys, try 433.92 OOK650 and 868.35 Mhz in OOK or 2FSK. +* For TPMS try 433.92 in TPMS modulation (FSK optimized for these signals). # Installing the app from source @@ -101,3 +119,11 @@ The code is released under the BSD license. # Disclaimer This application is only provided as an educational tool. The author is not liable in case the application is used to reverse engineer protocols protected by IP or for any other illegal purpose. + +# Credits + +A big thank you to the RTL433 author, [Benjamin Larsson](https://github.com/merbanan). I used the code and tools he developed in many ways: +* To capture TPMS data with rtl433 and save to a file, to later play the IQ files and speedup the development. +* As a sourve of documentation for protocols. +* As an awesome way to visualize and understand protocols, via [these great web tools](https://triq.org/). +* To have tons of fun with RTLSDR in general, now and in the past. diff --git a/applications/plugins/protoview/TODO b/applications/plugins/protoview/TODO index 0003ccd38..feb7b0743 100644 --- a/applications/plugins/protoview/TODO +++ b/applications/plugins/protoview/TODO @@ -1,20 +1,14 @@ Core improvements ================= -- Detection of non Manchester and non RZ encoded signals. Not sure if there are any signals that are not self clocked widely used in RF. Note that the current approach already detects encodings using short high + long low and long high + short low to encode 0 and 1. In addition to the current classifier, it is possible to add one that checks for a sequence of pulses that are all multiples of some base length. This should detect, for instance, even NRZ encodings where 1 and 0 are just clocked as they are. - -- Views on-enter on-exit. - -Features -======== - -- Help screen (with press ok for next page). -- Detect the line code used and try to decode the message as hex dump. -- Pressing right/left you browse different modes: - * Current best signal pulse classes. - * Raw square wave display. Central button freezes and resumes (toggle). When frozen we display "paused" (inverted) on the low part of the screen. - -Screens sequence (user can navigate with <- and ->): - - (default) -[settings] <> [freq] <> [pulses view] <> [raw square view] <> [signal info] +- Decoders should declare the short pulse duration range, so that + only matching decoders will be called. This may also be useful for + modulations. If a signal is only OOK, does not make much sense to + call it for samples obtained in FSK. +- More protocols, especially TPMS and other stuff not supported right now + by the Flipper. +- CC1101 synchronous mode with protocol hopping? +- Protocols decoded can register actions, for instance to generate + sub files with modified signal and so forth. +- Optimize memory usage storing raw samples in a bitfield: 15 bits + duration, 1 bit level. diff --git a/applications/plugins/protoview/app.c b/applications/plugins/protoview/app.c index 4e6b2ff3e..ea4e366b8 100644 --- a/applications/plugins/protoview/app.c +++ b/applications/plugins/protoview/app.c @@ -89,6 +89,12 @@ static void app_switch_view(ProtoViewApp *app, SwitchViewDirection dir) { /* Call the enter/exit view callbacks if needed. */ if (old == ViewDirectSampling) view_exit_direct_sampling(app); if (new == ViewDirectSampling) view_enter_direct_sampling(app); + /* The frequency/modulation settings are actually a single view: + * as long as the user stays between the two modes of this view we + * don't need to call the exit-view callback. */ + if ((old == ViewFrequencySettings && new != ViewModulationSettings) || + (old == ViewModulationSettings && new != ViewFrequencySettings)) + view_exit_settings(app); } /* Allocate the application state and initialize a number of stuff. @@ -112,9 +118,11 @@ ProtoViewApp* protoview_app_alloc() { gui_add_view_port(app->gui, app->view_port, GuiLayerFullscreen); app->event_queue = furi_message_queue_alloc(8, sizeof(InputEvent)); app->current_view = ViewRawPulses; + app->direct_sampling_enabled = false; // Signal found and visualization defaults app->signal_bestlen = 0; + app->signal_last_scan_idx = 0; app->signal_decoded = false; app->us_scale = PROTOVIEW_RAW_VIEW_DEFAULT_SCALE; app->signal_offset = 0; @@ -123,20 +131,24 @@ ProtoViewApp* protoview_app_alloc() { app->txrx = malloc(sizeof(ProtoViewTxRx)); /* Setup rx worker and environment. */ + app->txrx->freq_mod_changed = false; + app->txrx->debug_timer_sampling = false; + app->txrx->last_g0_change_time = DWT->CYCCNT; + app->txrx->last_g0_value = false; app->txrx->worker = subghz_worker_alloc(); - #ifdef PROTOVIEW_DISABLE_SUBGHZ_FILTER app->txrx->worker->filter_running = 0; #endif - app->txrx->environment = subghz_environment_alloc(); subghz_environment_set_protocol_registry( app->txrx->environment, (void*)&protoview_protocol_registry); - app->txrx->receiver = subghz_receiver_alloc_init(app->txrx->environment); - - subghz_receiver_set_filter(app->txrx->receiver, SubGhzProtocolFlag_Decodable); + app->txrx->receiver = + subghz_receiver_alloc_init(app->txrx->environment); + subghz_receiver_set_filter(app->txrx->receiver, + SubGhzProtocolFlag_Decodable); subghz_worker_set_overrun_callback( - app->txrx->worker, (SubGhzWorkerOverrunCallback)subghz_receiver_reset); + app->txrx->worker, + (SubGhzWorkerOverrunCallback)subghz_receiver_reset); subghz_worker_set_pair_callback( app->txrx->worker, (SubGhzWorkerPairCallback)subghz_receiver_decode); subghz_worker_set_context(app->txrx->worker, app->txrx->receiver); @@ -171,9 +183,11 @@ void protoview_app_free(ProtoViewApp *app) { subghz_setting_free(app->setting); // Worker stuff. - subghz_receiver_free(app->txrx->receiver); - subghz_environment_free(app->txrx->environment); - subghz_worker_free(app->txrx->worker); + if (!app->txrx->debug_timer_sampling) { + subghz_receiver_free(app->txrx->receiver); + subghz_environment_free(app->txrx->environment); + subghz_worker_free(app->txrx->worker); + } free(app->txrx); // Raw samples buffers. @@ -189,6 +203,20 @@ void protoview_app_free(ProtoViewApp *app) { * function is to scan for signals and set DetectedSamples. */ static void timer_callback(void *ctx) { ProtoViewApp *app = ctx; + uint32_t delta, lastidx = app->signal_last_scan_idx; + + /* scan_for_signal(), called by this function, deals with a + * circular buffer. To never miss anything, even if a signal spawns + * cross-boundaries, it is enough if we scan each time the buffer fills + * for 50% more compared to the last scan. Thanks to this check we + * can avoid scanning too many times to just find the same data. */ + if (lastidx < RawSamples->idx) { + delta = RawSamples->idx - lastidx; + } else { + delta = RawSamples->total - lastidx + RawSamples->idx; + } + if (delta < RawSamples->total/2) return; + app->signal_last_scan_idx = RawSamples->idx; scan_for_signal(app); } @@ -198,7 +226,7 @@ int32_t protoview_app_entry(void* p) { /* Create a timer. We do data analysis in the callback. */ FuriTimer *timer = furi_timer_alloc(timer_callback, FuriTimerTypePeriodic, app); - furi_timer_start(timer, furi_kernel_get_tick_frequency() / 4); + furi_timer_start(timer, furi_kernel_get_tick_frequency() / 8); /* Start listening to signals immediately. */ radio_begin(app); diff --git a/applications/plugins/protoview/app.h b/applications/plugins/protoview/app.h index 4ad0a9196..71b06bf9a 100644 --- a/applications/plugins/protoview/app.h +++ b/applications/plugins/protoview/app.h @@ -65,10 +65,21 @@ extern ProtoViewModulation ProtoViewModulations[]; /* In app_subghz.c */ * It receives data and we get our protocol "feed" callback called * with the level (1 or 0) and duration. */ struct ProtoViewTxRx { + bool freq_mod_changed; /* The user changed frequency and/or modulation + from the interface. There is to restart the + radio with the right parameters. */ SubGhzWorker* worker; /* Our background worker. */ SubGhzEnvironment* environment; SubGhzReceiver* receiver; TxRxState txrx_state; /* Receiving, idle or sleeping? */ + + /* Timer sampling mode state. */ + bool debug_timer_sampling; /* Read data from GDO0 in a busy loop. Only + for testing. */ + uint32_t last_g0_change_time; /* Last high->low (or reverse) switch. */ + bool last_g0_value; /* Current value (high or low): we are + checking the duration in the timer + handler. */ }; typedef struct ProtoViewTxRx ProtoViewTxRx; @@ -85,6 +96,7 @@ typedef struct ProtoViewMsgInfo { char info1[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 1. */ char info2[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 2. */ char info3[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 3. */ + char info4[PROTOVIEW_MSG_STR_LEN]; /* Protocol specific info line 4. */ uint64_t len; /* Bits consumed from the stream. */ } ProtoViewMsgInfo; @@ -103,8 +115,12 @@ struct ProtoViewApp { /* Generic app state. */ int running; /* Once false exists the app. */ uint32_t signal_bestlen; /* Longest coherent signal observed so far. */ + uint32_t signal_last_scan_idx; /* Index of the buffer last time we + performed the scan. */ bool signal_decoded; /* Was the current signal decoded? */ ProtoViewMsgInfo signal_info; /* Decoded message, if signal_decoded true. */ + bool direct_sampling_enabled; /* This special view needs an explicit + acknowledge to work. */ /* Raw view apps state. */ uint32_t us_scale; /* microseconds per pixel. */ @@ -136,6 +152,8 @@ uint32_t radio_rx(ProtoViewApp* app); void radio_idle(ProtoViewApp* app); void radio_rx_end(ProtoViewApp* app); void radio_sleep(ProtoViewApp* app); +void raw_sampling_worker_start(ProtoViewApp *app); +void raw_sampling_worker_stop(ProtoViewApp *app); /* signal.c */ uint32_t duration_delta(uint32_t a, uint32_t b); @@ -148,6 +166,7 @@ void bitmap_invert_bytes_bits(uint8_t *p, uint32_t len); bool bitmap_match_bits(uint8_t *b, uint32_t blen, uint32_t bitpos, const char *bits); uint32_t bitmap_seek_bits(uint8_t *b, uint32_t blen, uint32_t startpos, uint32_t maxbits, const char *bits); uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t offset, const char *zero_pattern, const char *one_pattern); +uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous); /* view_*.c */ void render_view_raw_pulses(Canvas *const canvas, ProtoViewApp *app); @@ -160,6 +179,10 @@ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app); void process_input_direct_sampling(ProtoViewApp *app, InputEvent input); void view_enter_direct_sampling(ProtoViewApp *app); void view_exit_direct_sampling(ProtoViewApp *app); +void view_exit_settings(ProtoViewApp *app); /* ui.c */ void canvas_draw_str_with_border(Canvas* canvas, uint8_t x, uint8_t y, const char* str, Color text_color, Color border_color); + +/* crc.c */ +uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly); diff --git a/applications/plugins/protoview/app_subghz.c b/applications/plugins/protoview/app_subghz.c index 2bb87af7a..30e0c817f 100644 --- a/applications/plugins/protoview/app_subghz.c +++ b/applications/plugins/protoview/app_subghz.c @@ -5,6 +5,12 @@ #include "custom_presets.h" #include +#include +#include +#include + +void raw_sampling_worker_start(ProtoViewApp *app); +void raw_sampling_worker_stop(ProtoViewApp *app); ProtoViewModulation ProtoViewModulations[] = { {"OOK 650Khz", FuriHalSubGhzPresetOok650Async, NULL}, @@ -15,6 +21,7 @@ ProtoViewModulation ProtoViewModulations[] = { {"GFSK", FuriHalSubGhzPresetGFSK9_99KbAsync, NULL}, {"TPMS 1 (FSK)", 0, (uint8_t*)protoview_subghz_tpms1_async_regs}, {"TPMS 2 (FSK)", 0, (uint8_t*)protoview_subghz_tpms2_async_regs}, + {"TPMS 3 (FSK)", 0, (uint8_t*)protoview_subghz_tpms3_async_regs}, {NULL, 0, NULL} /* End of list sentinel. */ }; @@ -53,9 +60,14 @@ uint32_t radio_rx(ProtoViewApp* app) { furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); furi_hal_subghz_flush_rx(); furi_hal_subghz_rx(); + if (!app->txrx->debug_timer_sampling) { - furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, app->txrx->worker); - subghz_worker_start(app->txrx->worker); + furi_hal_subghz_start_async_rx(subghz_worker_rx_callback, + app->txrx->worker); + subghz_worker_start(app->txrx->worker); + } else { + raw_sampling_worker_start(app); + } app->txrx->txrx_state = TxRxStateRx; return value; } @@ -64,9 +76,13 @@ uint32_t radio_rx(ProtoViewApp* app) { void radio_rx_end(ProtoViewApp* app) { furi_assert(app); if (app->txrx->txrx_state == TxRxStateRx) { - if(subghz_worker_is_running(app->txrx->worker)) { - subghz_worker_stop(app->txrx->worker); - furi_hal_subghz_stop_async_rx(); + if (!app->txrx->debug_timer_sampling) { + if(subghz_worker_is_running(app->txrx->worker)) { + subghz_worker_stop(app->txrx->worker); + furi_hal_subghz_stop_async_rx(); + } + } else { + raw_sampling_worker_stop(app); } } furi_hal_subghz_idle(); @@ -84,3 +100,55 @@ void radio_sleep(ProtoViewApp* app) { furi_hal_subghz_sleep(); app->txrx->txrx_state = TxRxStateSleep; } + +/* ============================= Raw sampling mode ============================= + * This is a special mode that uses a high frequency timer to sample the + * CC1101 pin directly. It's useful for debugging purposes when we want + * to get the raw data from the chip and completely bypass the subghz + * Flipper system. + * ===========================================================================*/ + +void protoview_timer_isr(void *ctx) { + ProtoViewApp *app = ctx; + + bool level = furi_hal_gpio_read(&gpio_cc1101_g0); + if (app->txrx->last_g0_value != level) { + uint32_t now = DWT->CYCCNT; + uint32_t dur = now - app->txrx->last_g0_change_time; + dur /= furi_hal_cortex_instructions_per_microsecond(); + if (dur > 15000) dur = 15000; + raw_samples_add(RawSamples, app->txrx->last_g0_value, dur); + app->txrx->last_g0_value = level; + app->txrx->last_g0_change_time = now; + } + LL_TIM_ClearFlag_UPDATE(TIM2); +} + +void raw_sampling_worker_start(ProtoViewApp *app) { + UNUSED(app); + + LL_TIM_InitTypeDef tim_init = { + .Prescaler = 63, /* CPU frequency is ~64Mhz. */ + .CounterMode = LL_TIM_COUNTERMODE_UP, + .Autoreload = 5, /* Sample every 5 us */ + }; + + LL_TIM_Init(TIM2, &tim_init); + LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL); + LL_TIM_DisableCounter(TIM2); + LL_TIM_SetCounter(TIM2, 0); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, protoview_timer_isr, app); + LL_TIM_EnableIT_UPDATE(TIM2); + LL_TIM_EnableCounter(TIM2); + FURI_LOG_E(TAG, "Timer enabled"); +} + +void raw_sampling_worker_stop(ProtoViewApp *app) { + UNUSED(app); + FURI_CRITICAL_ENTER(); + LL_TIM_DisableCounter(TIM2); + LL_TIM_DisableIT_UPDATE(TIM2); + furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); + LL_TIM_DeInit(TIM2); + FURI_CRITICAL_EXIT(); +} diff --git a/applications/plugins/protoview/application.fam b/applications/plugins/protoview/application.fam index df2a77261..6cd31372e 100644 --- a/applications/plugins/protoview/application.fam +++ b/applications/plugins/protoview/application.fam @@ -1,6 +1,6 @@ App( appid="protoview", - name="Protocols visualizer", + name="ProtoView", apptype=FlipperAppType.EXTERNAL, entry_point="protoview_app_entry", cdefines=["APP_PROTOVIEW"], diff --git a/applications/plugins/protoview/binaries/protoview.fap b/applications/plugins/protoview/binaries/protoview.fap index f5a03056e172efab800adfb989d987ce2e3b849e..696dc523ef6e43d610df9cfaf14e5264774c7da2 100644 GIT binary patch literal 28520 zcmbV!4}4U`wg23^yU7xkB#@{90^DR1SV)LV5;P)~%^z+c2_`~pQL)LAUD&Ppvt~C4 zKKfV$pR~m`2vn-@d9>0#-jmvZVxg6nROzd>*x!Qs8VX9R)Wwa`4FtOdTYukk@7&GJ ziq_A&diOhL{+>DK%$d0}6E-ZYlLbLw+9NOJ|tXv#m zy_=$}(tfx;Qf{n|RGM}~Oljuc?ueK+t+z44EO$pl%Z7++#fFG`1&jVESRZL@d~@*b zyN~p?Rao9GtO`a%abv__cqGEuridVD^ewZu^xBV&kFxsuh%l#qIG9}*89zr1IVzlk z4Yo6v|#k9;7dcS-rU<1X|Oa5F;+fk zysJE7670vCB6Su=c{%D4=G%Iyt`AOai?TFhuOKt&;MI+n&An2|Gecty&ksqW<&TzP z^V{N3rsd@!izr;RM02i+LzV%=i2c1U4@njQv~<<-$=TlWh(+jjoS*cgUIDGmth68N zh!~C2=4b!WQkr_!IFxBTjvA$_#wf~Mc0>#;=c@7Y!iWJ}9UrprR1v90C3U83KZYDp z!X4mn({L~&sdwXWaJ*0|+;L}^^qJL58l4#$(YGl?`Zo4Xl+#geTf~qywU^~EiF)3+ z!gSKX7MI(4%V9P4W0_Zi#`(R%mEd^$F_QJd=s(KKhkXJh&g{pi{z*zb)JAsiSXq=C zB0_0W@6w22F4bH<%yR6UB;neBkC~W6&k|VPftgCi+UXul;m%wrpY;sj5AjE>WGxS&@U>>4R_hV7VVx3?>O* zk5r~&L`B~4Q5}kvqnr`tOl0X=Ii(Ewhtc^ZYU9$K5iu3*Tow?njEDvr6~qu`jl%|A_4yG#Sx;Dvdw#$1J)9p4?DU9}V8UFp`l` z8JW<6(UZF{GX92zk#u)`giTKcuX`|dzF$!_^mn5XRwSOf&s-lV7GIp?9yFNLaQ$#F zy?&S#zBnkRb`2U*b9-N$)FnG27RK`?#IN|A_}!lqf0o@HNlMKM)kjR=?8dJ8NYah< zkyi|rk){6n$jcai+1Y(3Nl#->mPeT4fgs_!7sC_>-(1P05$j&?@z0(+JZONI1HTr% zkM|uzfA72#b5!Q%+IIK*3&G3d?~{f}UuH$i3x;q18Br;uz0wWCr9UJ6Z5Yn~8ELmL zOjHtSbMAuSzduKDx#1DJ*f9L-=Rg@Z43GO6EWxy4c<{Li;VH8^PS5@zTK(;wWO<8x zqx=K;mfGzXl3B{Lh7Xb%%M%O7pGA0Zvte1xGM{ZPky&oJTqe(6vcK9S_Y8fyKsYIs z4u%gSR2MoIJF&Mwo>6m`EJ`!(?5S2t8XIF4OJ41+YE#t%Q>`_|C#*GwC&cZq$BaSt zq#>7CllDuCw^SQtgFHlYjSGjIq~Z#`M=>W@+-;Z^bP3 zJ+X;+CrQE+Z2O*AmVH8vlrv^fVB_odRyWOkE!Nk-tgpq6+Xd-Nm`T2BCjB9-EJpCN zUkdTLHK&DKmXn0}yUg%FRR*Mfk3%RPGwb8G#~ftRufls`a~e$1H1nQV zu`l^z_rpgnuKxD9k8XX~c5%kH_ryy24h$8K*%K>mE`i*nW@qz{nkTQd`uD_ULtaJF zp4iRldt!FBCpLFrPwbYxugCK6N(0H?e?6AfXL{1O)6gw$Q>9vHw?eATS-H?P%A)+u zC~r^K(r4SJAl*3RVEe0$L(R!q7t>QFLeH;%z=SNMl*#+6Yvr4iJVE4P->;N26>2Xi zLAno`xd-ppFfXR_Wn~_)5$|$NuK+&&mnWpeN~dazN6?X z-LOE>*H}$on@C?@=lZ%|r>~zvUkA3`%k{Mn`dSWsEr-6+xxUQMmwA69*Vi(xuLZLm zm$n62?sz#F8nY=HGtZw`_1Yn!IBC|ExA(+m*uPWZh;9t-iA`@9WQO4&bde`zRGKfQ z&pUGQ)o)+9$hhwEoA>-J-_8o|IrEdDvN1`~4N0bGm1$nBLDA#nE!K^DVmZ)4F0^2U z7W3GiSiTSS_Mw#l=nrpZpYh2N4NCR`$h$eK06o>0)ifyC^A&wK*b&m8nKYQoHJF1G zhkT^^=nzZG2-V6{m7GB(=U!Gddwgh8?PSDdV#Ep3k}!PXn0?`rxV}>{{yzw3)_w>L zWA!A>$2%{a4PDV=2d==|%xM=eh<7WedpMo|4&cos+Q8T_Fbi)3(RilK5-=Wp)ui`r z@L}WRsqz-C-^ak2k&j1l(AgaodB?au8aUO2r+*PWB{eId%Ux zxj$OZwOml>xb$9dUG3y8KaCaIS^nd(qK2QwYNB1{bhFH6zj>xNo$a_? z{(4Q*V)7t6V37rg|LqxXg$b)cA!-no_tsRrJY*D&SH(-||0xWcxG8_MwIm)9mm)Q_!N5s_#3>J5!SySAuf#fU7q$gLcG+U%7`(OdbAUMXQtA- znU3!%VKrr@V@vq)SfS%l{LXefg5M&?2K?qZ*5fzdu`XR=EZ4619$!{2bVx0em$%s^*jp0(4aKScO!HKel$2&A z1!D-g^XxY&aY4ih(s-InHZkcctS|TJI25k$Lzm@+v0p~i`9i>@vn!Itt{7^GiLv-ii8U7yD9|CnKVD-*(ZtO zu%i>+p9(>Xa=*0%T%!FQM zK`#Y;dt!y~DB0v$`b;~F-G*)A6Et&WL#}JHvXypi(CAD)3(v5V*H2dTlRVUHB5#t( zy-5aAZ1UdfN||Qretub(~(H^8>2? zH^LW8lk2$bYju+U79_u7+afOcMo37!#-1=llMUpTN9*Axt_Kv=d`wV>hAf0ynWh+0>`E2gX$`C?1B51 zq`jVYyuf2^W_kH?I#!sET2{m|5BvhN&4keFF}7D*X)Z-iRWFW}=G+g$4f37ni?K?a z{{q&WEc(4*?UH43ZOu%qv`EW>)v#UMp{_1z1eujJ7OgH9DtUUU)e+P-kZcWN1ey0c zxFxG2$O)b0HT&6_Lo|LWBX4CS&eTH}Ef1GLpRMdX@=W(tMgEX!n@@gDzfRT9w-{Xv zqYL`X?n~-cR$1R4nS)8Aw06zGI%~|3BS~L!Bp2z_julnnDvRQ*GU;{9P_weGB5kH? z9_TUE-=!-WRDTvFF;<9Idm4E-01Wc*evZe1{dmoX$I94EC>G>?j{y0bv8O`iqlY*3 z&`4uB6CwKrRvn2VWp_F$xWa64jbj9hre~ypMB<#q0>|_ zCY1lMv1mfbI6E^W7Tp*!6io{GjxnpD^HNxt89jO9Q6s`1hW%3wogaiHIT^KG044$7 z4;yB`AChDv!so-{?7y9SH>~F!-_*mKeYZn?MtL4=U|wxjv-&#^C7PYLEhe0|h<>GJ zC9XMFzHRYspb48j6f)*IJ(A~EgkaP7irZB^(9H7lJ2%Io4S#m#uiT8aipzRDHf%p0 zi#23RG!scqlW$?5u=YMrrPH*g0A+m5R_}eDDP7aOGePx$vMt`_u^~L&+vAx5j3Q3V z>G$L#Z1v_XUhbi9JALT1XSs(~ky9^YYRn-wz3+2DrdGrVuR_qU_sY@&h*`)E^cQ znvKvKVdJwIA0#nJo(1YeoFaSsb(|tg`|mhq1@&`yguQ(^2wA<8*9!&akWHQjN|LAI zmr2GR-?1q*jpe@*GcJE6W?2qzI3)@CLdw#avhiah z>#3HM`Y?)gPx|4CkJA}>8zasLOw?Yp>Tx7l-=`Ji!dqp+k|D4{YhBVO`QfAnK{_6HZrP1r@c3EyBN{W2+j z*O*ma^{dM%!UI{8*Rk8PdIjt4J^{6wP;0HHq}itQ>DYw}8%Oj*JdIOovUw(u3?M5B zBMvnxew`!+Ic1%SS!|G%jifhoiZsQ{7}~g@c9Lg; z_vtN@DpEqibgOsLzaFYcK3N|PR(3=MagsB3j7`5B9#``<&;8zSPNrGv@U`fr%8z$h zpQ>P|C&^at#D7hOFCd?9^-f)5^)@-rX?B+2r^*h$deA77U!ZqKjLk6&Rto7g;^0QH z+q3o{&4Br?}Iw)40>LbAk1zF{9mtm6GtE=%<7H6R_$Tk9Bx&i4`lzXPT`ZYg8~;o82pm z<&?z+iCTZpQ;E3ukVa^2PO3@57$d7o!idwidmQb)$;Sfu+&S>MAEXipI4~F&p88N6e{`B#m7bZCl;Ef&r%VpCh>(RelPTy4W zOP0?DgnZ&XNgnt7UoMY-tUlUc*mQaPmfp)9-|M|x|2>kbCdu~{iN4oN>m!3inwDf5 z`E3UuLy6ciA^&t(w27h47uk$Ig_ZTrjCaCfkq}z>;$Olvrav6j2aVVC!ws-0gLl$; zVb+)s)u>ucI^^L{tmfYJ_a0sDQEIeZgzT4l6rCYwI834Q*R7Z8r+#bolcyaMqWo9^ zK;l$?Rv-B`dM}NtgUYeP|ArGj>P`Sa(_^@-t$sp;=pV_K`zA=&Lp#J{Pm}(P~s3(>oAv zKKL)#4WbltAEOjJO8nvUgT$p7Jg4_jjU#?QO_vTDF@|Z4MtL%oevRZAsYg0!mW_)O z^Bo|b_(Sz=sSr*(CV>;Y>4%y16=z>8W)I@qTxo^AY0%o=X!X4aQuma^0GQ}Xx$)8J;4IQXccGG<>d&PB*1SQp0Z^9_Zyp_CyZWz3K; zX6%)#{@R6=rwz}J8yYJvmW5sAXw~rVQ*OTP^v|z6+;K}k?e71%e@|>|1L`w~B@_Nj z9NdI`e*4xV_zF7_qS$y`>m2O*7lW7L+GnmMS$hVzrwMNerEiCmu9?@EhXlim*Dild zd{K!<#fq4{Rh+AYO~l#3Fv~SQVR|BOU;=ikHVNgiGK)|m6ihyA7<@#Su%BTbxGQG2 zFx%x2#fWnz9H1EoaoOU`4^A6V=B`*-Hkh)efnbRy zTb3QfH{?~z<@8u;UtPptVL-CVk=Q~WdpYc@MoG&XmGsq3b(v15$1E(XoJ9pjrw(Mp zvp!;3$aZquT(ZDr^%V} z+cBwI9Q>8|e%7H1vHwOH`AUCMG3IowjBfzhA)7E;FxxP`GlT)mly-d`(fUVwgeTsP z&EHGk*QFu)3V)hL=9oHp!a)6Suq9VE4}3KnwqU2zof}{&1#+=`|5R3R`DCU{_LTbc z4;E&fQmtvs;8;P}WkHLErw(1adO771 zE|=M^@o4ulw996hdn*@?56zWdsz^JvOp(KKnPz`xI}>V9zP*f9)XRbJT-hcY68O-@ z8}YJDHgfnrt$C0WOj26x*6vyA0my^1*Ylo}T{d zM`Y|lci)4U`#qJg3~HUucT94B_1?i0Mk$j$tUJ3V3$@`(sQcAwHv3HI{-YCXG7v*w zL}kh@fK5(T^kBx_1@n+YG!HckX6y%=hxQsrc7Q8oON|NTOyKKJ+FA-Sijt2XLz+{c zLY(_#f-b~crHfZ>ELmQFc9ZZs(L?vJc1i6GJQp3 z=P8&gGpk*`6}x{M<=-Ohn)jIs@zj&(VaY-IWd-s{Iu)r5y^6EYcDTNgXrOAaK;vCG5GG=JAQl2Nz!Dytf8bR5MRQv<{U7oIS-{D8l^0rvi zKK3A+K5szCq4VS!wPSKcl$nltrq@nT!h5UpYA5rMwKk83a%yMu5JUc+>Z!H!b5oVp zrVm`j`dYZ1&ANt@>kWlt&t}Ef|3jfmhu#I})VIN~aLa-s%rKBE@ky(D!76NL*yBn? zZFz_r2R=kv`6}O(d%6Af0S73Y!f=SqSQ%dJspH{CdPJPCC$VE#hZ_ro5NfIJMsGJ^ zT^$5|9EM&Ft7|&p@TX4+7mO`#R4&8=%KlIk0Q6&N%Edoc>ie3e+yP4c5jhQPh`u+?E+3P zOOfNP*szaTACFD5Cv7+EcnY^1mJJwwaA$TB)<)Ar(=OG=(JW{9e(FHd)4#0v%IPzc zlePE{Q(miFEo7Z1^{?=<@}SSwkp&K#mU5xKBv2kgBSo>F}J z40cJ*hKx_uR0$&#zd2GPT`VjKqzox~cm*dt(c-2_dR&<-ekhNbL=8b^+} zKT{cT>Rzm7$>OsMa-Gml8q#*cD#jkofaXY}^t~tK;6wrTP8M=UF6sO)I$K(+>4@7R z8>K5_fiWZ&Ows8}EJz6%3Q|MHg5i_QO6y@4euwQJg+mAnB@`1@!?#oTU7Tgn=tvC- z1!*BxaQb8jxr+;KI$fNbQgG_@)03$5@58i5{5zBzw$CX@M%wdNu5NhcR7Mr0LWa2? z<9%PpH+>JQd)DOf3mz5=aznS)rsN9f^(~M?!NZ0EYiKTFWW*G6sTCpboZ35bQxG?s za(VAtf95Eao{C=G8lo>?O*MOROurKx&zJI5n z_KauV_<&inv38&v6q9Sxp)>lnq>xvsVXck%EGI{m$=3zP3P$|L^i`77lcEFl_yw;wg2ziH@i z8NMR%)$Jqi=kVIV1MTyY-(hox!VWL(3Dcg#;fgV*X3EW8+N;CYIL^n?Lc-k3*b6*d zF@QRa_WO>OAAN9YvzNZ_sg6_F_s4$xZCAoV!T&oc%sF`NeFa}G_(wG%{rP!&kr_`iihE9Pt)Uf~$1`gF<<@?%a=&>t%9%muD z%&}DK=!fn>FUPx{M}LBIF*D95GVw}y>G||i_Nnlxz;LY^@F|;P|H5YumH8)m?3C%B z<)KU!r4>qjgp#k*?QC1w>Xw{=c~X9B7wTx}>YFpi4p8bPRLZ#AEgdem zE1tjc=4F*qr@O5q;HEtJ_TuH*OY|K3sQ;7-m%7`XU9ADBv0=%wI1dH>b?q(Es*bL9 z7nK{u2e=^KE4_iv4tKj+j`Ja{^alK#8GSm{q4Du$kn%TrJKfUaDk(8Pr8RWA{r)bb z=NA>Pk{<9mDZjhT=k9a{lxUY!N%@w#eQsw!%6An?6$&D*y@RoJZa?~<|4)^z+|l`k zg1DX>P{#FnLWrlK-Nb$*(!}qV@3YVErTo|Fv)t-j?MIiXz9k)NyzQ%{d_Tf=*pL1t zif9cfe|@KWbw_*gb*%6Su?Q7hf0k=zP_pXG6-2$i>ovN*_cKQn94(AKU`RH<=?d0h6 z7LU8-0e@GU)aLcKIRh=8(e0uS*Xy%Bj`}&$|2c90MR_Rg%gTU^olKs}s9}}h@rvDQ z@kBIstm_CkRq2rTyD#5=zvcn;wy)3kS!s-_=b!df>(fYoNBp&xHoCu`Kknl^N;F~A zIsF02?{0OsVA!#n-D?9k`@2@I_B?#E)9-f&{5Rt#0N>Em<#%_o)m>h;s;d*HCP;(} zT;=q(x?SUx70D8(w_U31=mway)_0QT6q;(k*lCwVsFJ`w%X^RSg%*%Rm&B zlqo5UDRk+rMYnKz$+B8jjXbEHDf8wW$p&&}oGwnFOGfC=le5yVHR@bX^$2)rPg`Is ziTqLzRt?G&Ecu;nK8Oq5B-cMmW>w0Pp%W>PNXG-T(vaGa>&^~IF=v`Ed>wwj7xJdE zYJL~;7fPMZhweZ*Z~Ll_J1{;9wg2x&zB}%?<112?*Y9g}u7k8y4x}!h%Sn#k26IuP zFgKyaEY?cbUP)dmAF9|C+g$2=ND(=D*hPYuHA6&r zNr$Ve)fw=1fUmp#Zb(LQw!0)($3yL8n&_%`)jH&}RV}QzyISc<=P1e4->KLaEqRcQ zEmH@uL?%;+p{|ayxP{-03VC}}J<0sDwy>8f!b5kv>7o0-^q7q*207AQGkWNL5^ zl4oUwijAuAWe6M8AX|hmFV2=D%&TB45a!h|7sB-P;0^F_Kf;@NSQ!MAfj{E7u}S9Q zWMd}F5GNSNZ%@DHhVrbei8oH!mdz$7OV@JKbG}MhKa=kpUm{<+QeUZ3Uod<5t^JUh6JG*;u=vi7~-1H=;VYF_z*(UT1}ClNRR5@lu{XkLhq-b@~AEDMyJ(B zQ0!+97Xtp`OUb`Q(r;sq&H%>eKF^ zYW2Bv`KdlP=pDNHdd6!NsP)-2lJiI3-s+>;&&d5pRUa{3d8+?!pik)P-<+Y9SL=_n z!{uSulF=TDvE#b@WSYMQO)}H;(XUG6HHk9X%KHVbHC*{Fyg^P#$jY@$skfFD0aBQYUoz z3ls8hO-MKMzbU5`2=#~VWvP!^e?vn0FLX5V->0Lge0SVn)%tj4fMlh9%A-CiJu-e( z|MW>h`SgieelC98ax zDZN`qQ~BLGn$lwlv~qt#sZW)+WwJuxN0r}-1e)&qsE?XIn2>%UfgVW6&$6}hYW-Vu zH1T^vM-#twQ%3Srdb5tE^nE&-())BYrC&&(X-%O%s(&ccNbWy+66pQ}S{Z~&oI3tv zy85a8;;C8zRX?{R(DQY)(!T_n?v$vHD&NM0beE2%_F8o`)wf8kugx^yZ!tgBC{YMPQ6KdQY* zI-1f8bu`t#Rl<+*sPf+}aT4Vz|2qjZ%Na?h@?|=j^3T`Nl)hd^Q+iNGQ##Jq_@lO$ zuA?cvTSrs*-8!1m)2+NX=Qm47Q+i$kP3Pq5qw2?&kY1IirK|Fzb6|b`KtlTZd@Wtg zPv`FHquTqCgmfECGRmXok5|X%OYN*wo8L*$4ARv@i| z?oOcbi5Y(={a^4(c+GgnizfD6p!QJu4>bZv^z(Sf!~VAdCx`<3El_(X{f~I37#O=3 zNa^nbX?oV`zk;y#Q2q=E;C0L&I}oP)Beu)=Cjs$?@;?H4587XkFy;UEg!Jb?PsIFN z$J6@~($9guANFMD>3;)F{*UBL{huu2?=hj@eLTGswDwT@^tY`Cp|A4@Q~RqE(z`%! zL;JKuqx3DH?|^?K84%sW^Q-M8v%ZA#|C>O+pFqbF=ubia7;i4Ge=KCLJ;d)U&_^-; zHF?RPCt6k65B^p`+8 zA-^r0egibbt2~tcE@#i;(TC8VzheFN+_m#04k`f<=b zoPHMcuh73TPX9ci{2vqO_d(NqE+IehLua7cqwoV-FQ2l6^jgp#z}_2Bi1@t^H2s@X z2e`aDs66EP4W7Opv>jp1AAA?|9X6~9c=``PYY(-5FoEt%pid>x7eJ3exre#_u7K9J zZ%Ec^SMBX4&~EUrwLdc<{VSmL@2Q0J{{pSIx934` z#CkjkHc6hZgT4*p&Bf_=63Pq22!BXkX3$q)KNf_k{7nhzw}U3zqIbNQ%w*7%gen~B?+|to*|{*n~>fG`p3|B71F4GkAj{%9p7-A{vl|u4StE! zKLfo-8u2H;0Nn=pX7Th0Xzii)u7Tc$`Cj7urep5jn1eMW(x|-|ptXnc&rhIh66lo) z^fwde9SQV*fTns$j3nQmC!~+8CDeR>OGqC#R^v`hmq0t=Pnr=;{LcpcIQ9dMbJ_v= zR-M0U2c3icg;w7GM?h;2@%1B4Yy3Tzkp5NzeKCRl6!bYs^;g7C3Jm>joj!`m@cBdS zEl!}_pnr_~P_fdVtqJLSKnrm0CwTf#64GC!bl77dPyby)`l$r^&!F#s{xy617_@$V z661S)s=RLiEg=7VUjK}Q^mz$%O#XLO{~=WFsS zhjUHJv6pf%rslyZhFd)l^f+6a)Pu{WRjplqPgCbw*3_hARSs^nqkB4q<0o5;=YOc9 z^8vJ{)U~DoH#-*MsIjsW$Bp2SwR9+V5|G@{*3{~4cQ?^Z8rI@$U*q&Qxp30e&smBYja$ALyXA$)z0F zHE9QSy2FXj@ZaPOxN)wC_!byXLWT= zjf4|qn!OXFUo-?B&9?s4Z=1%T5zTrP!7hIDaWLKwg0UhtC7(Q zec)gkcNf&ywl0$Wh(Y4O5*L1&T3R7_*5+<&@vYO0#7{<|SOx5^-QC)>8hVAbJwV0P z1L;KjYJ&ZHnpUDlaPLL0aPaAU*xl6TUk!<^>QJSmh(0cbHnk7`ysrw=BVAXAme)^4 z?Q}a=dYihu#V&1>D$>!ZN6X{tL_=H@(4%v;y9r(Ca#QCtc|#^{FAi3lRC!-7H|H6{ zi=^AcPjGo3wBZ49!HyyCz$iJnIs#xBvG6DURjyUV@ea6L-ZiYHv!#q;TrStDl98mg zu2zjd{a8~OiH}YU0YyxFoOiV=N*v8s=h_h;_L)IXcNw&H;&vAoy55GqtlDq`L$w06 zFnJhX$3u{=zssi_M>n;2oSo2vYV&AIH^34HDEGmNb`^ud9UwRZ!x_Pwr8#88WfBD4S@$ zK$qbeHQVfJh5f4carFLwv_zC%H#I%f>BMx?t_<*1I_INkANOC#ew29#!tM;{GVq%x zieJ(ic0m;2LYW$HMUuun7Y-k#O(e=ueHo?w_<-TIrw&INjU(NSi+S{f&^Bri!l!C2 zb0MnjG{IA^q2a*iGq8nm*G}UIz`Z4Ojl3H8=2~sR9nka?T$M3ZWr?0emyKKi<|TJ$XO~Z1Esz(FYY=*(!K5GRpW_BNN4TZiMx$ZG zgU5~Svoj{C+k-1IO}NOzRm$hU4xhVyRIA+h{qfa^+FnzjqlqpCCkjp1Z)${QN>yK@ zZCsVDa(NA!<1>v?7D9mqDT2e&hzz;KNh>MHiciGq?CorMunP+pM%Qum)^#1jcDYy4 zZRimL*Li}`%Uiwp;tq_)&u0`#i$QX_m`5;!>4rFYG=1;BKnpH-V{KYcvZ<>XRG>$Qze{{z+T0B(=EaZkzJxh#NtVxM76nUVNZ^v|na<;E>6{R*De^>N{k zN?F+ft6MYbo3+Dofj|oMO-d0)&$6Mlgye?ek z8)-|ul}8nL9#$8}^yP8=v9FFSehskGAHUCgoq?oZXDN0~cYZ|d(QPHXM_}EYrn6M> z49+|Wzb3HVJbo|7eT4tR*nUpaStr%g!|??|i=gb$Q9RxKA+!;qokC9AIhJyyzXPOt zX+MVYS8-g#v5pY+HgLL;@Lqu}=kyAW%^Y1EJ%s2F-5H{K(+R;xCa1GFW^$2}61G#=W{z7pZspj`aRhl!j{St_zl6;q;wO&~{Ma~M$kEQRlo0%sae6-CCB___uHv|e5bf4+ zx`7aSYUK2Cjw?7e6M_%AD@A;~KnOmLaQY>VeH@Pyf{#}@eS#2tggE^s$9|4y3Bk_* zr_U3Dp9`G+kYkkNFd_J%yH&)`7DDi|l@Q~yo5%0qxQh_^cN6}evAsNgA0hbK&*=jk zdkDeL3!FYe2!3ATbRS2$izVI!IpRP~T!QgOcsJxoI0@sA@B+@12|vX?C1IJsT!bY8 z^ANs_{YXOegYHs^M#!1)Bb?J=uTngP{anK70?Q_R5AoRJ6wf1`5Qmi6geWI*%p;r! zJ0V29g@h9XX6JM%;jK8YBK$hWr$WO{2;YK#AuPeajZ9d9{t>34e}o_6juK&(z*Z1m zLB9xZM8616;7ptF4uQ22I&scLSR}9jVUxht5)R_rk8rWTf`k{LPr`DXOA`Ja`*=93 zp?hW)!Zd-U6V8NxA{-~MEJE}zoA7P)pK!jw@(2sje?kxZDk0=!C;S+9LOESVn1lWk zLJtnYOo3Gqt`^uL!sCq95uzQs3nnfS*bYK$g6<-`8UBHA0Cq))1KWLs_y?)?6XGAG zK0t`_Jse*kggqW1Y=K=7MsW5<2tHpWME(LV*nvLY^@mPj}J8v#=*Z$cgTri3^}t!f66)CR{Ekch1P( zwh(;{^CDqLy<0~4&+~kAmyGCALX@MsV?^&Dd(=RJhExPMDn zjP?obXrFK;?1~WQbRI$hc14KtKEnH9SA^*QTEe>oww@6Ern_SzCXNpY--jFs=RgiT zJ;w19!ZYX}_SQus{0Jf1?Ix@R|AeS-7suU%$iJ5meC#6xANvV^g>g)XL*X9682lyS zN$8uf68a_tzkP(+0y|EK`d{TpchtlNj5k8?+er8aj61^nARoeCqg_Jqxt|dA9U!bj zyM#&bUxdF!yM({PT`WShLwDH3zv1pEA<9Jw$v${`9roBs-wlMw?;=D#52xu)7|}sa z(;YCfpWQruFOR3YU!>PQLg@84Pk)uC(_JrxAHuIdPdq)!J%o_s3xwd8?pRT| zLPE@2cEaDle-L8cy1>&vza~Vzr5wu$F)z~{D)FlrA2WgAzmX97T~4?RdLTsm zbT^9n{U%{4{3aplJ4=Xq1_;sKc|!09t(-;{VPD-?wLR}k(-LAo;_zMC*Y5;I)NX2Yam)_&q4^MM)8HU%_zPwM@T$Bh6@uhCT*NX zcQMbZcQuILQlg90vwNbec)kXXD>!;M1~>*eZXv|D-OA}5oZiLhy_~k8OX5}a%u##| z?Gs&t`Ht`vv`?6V^#tK6fjJ1R@FRpo6#3V+1)M8^fld`YS_q%(MamIE5rsNClx-^| ztcF(l{j6w})7Rz>I9bu^_AY$)uIyTkt%3)@-IsgdJ{h=RNj!TQFh;`UkD23S;269P zPWOBra|o0M6)NS)z9=t-jY31@Nhpl*Zp2Z25W8ZpRNq{@ z#2>|Ffw=~}n9kylR^J@N==qDGzI5cH`b>B={%%K@>ZSTzx4~cHMK|J)R-Xegx@MGo zcgJ&$q%BU!H;npdOlgl+AJs)N(H`?W^cQPd5=|do%15?OeIVYnXBP}M3*UU&qwzEz R5&C@QHuz926Hv?d{{cGVrR4ws delta 10526 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 +#include + +/* CRC8 with the specified initialization value 'init' and + * polynomial 'poly'. */ +uint8_t crc8(const uint8_t *data, size_t len, uint8_t init, uint8_t poly) +{ + uint8_t crc = init; + size_t i, j; + for (i = 0; i < len; i++) { + crc ^= data[i]; + for (j = 0; j < 8; j++) { + if ((crc & 0x80) != 0) + crc = (uint8_t)((crc << 1) ^ poly); + else + crc <<= 1; + } + } + return crc; +} diff --git a/applications/plugins/protoview/custom_presets.h b/applications/plugins/protoview/custom_presets.h index d34446f48..38fca0e31 100644 --- a/applications/plugins/protoview/custom_presets.h +++ b/applications/plugins/protoview/custom_presets.h @@ -11,7 +11,7 @@ * * ((256+MDMCFG3)*(2^MDMCFG4:0..3bits)) / 2^28 * 26000000. * - * For instance for the default values of MDMCFG3 (34) and MDMCFG4 (12): + * For instance for the default values of MDMCFG3[0..3] (34) and MDMCFG4 (12): * * ((256+34)*(2^12))/(2^28)*26000000 = 115051.2688000000, that is 115KBaud * @@ -38,6 +38,23 @@ * d 82 khz * e 68 khz * f 58 khz + * + * FSK deviation is controlled by the DEVIATION register. In Ruby: + * + * dev = (26000000.0/2**17)*(8+(deviation&7))*(2**(deviation>>4&7)) + * + * deviation&7 (last three bits) is the deviation mantissa, while + * deviation>>4&7 (bits 6,5,4) are the exponent. + * + * Deviations values according to certain configuration of DEVIATION: + * + * 0x04 -> 2.380371 kHz + * 0x24 -> 9.521484 kHz + * 0x34 -> 19.042969 Khz + * 0x40 -> 25.390625 Khz + * 0x43 -> 34.912109 Khz + * 0x45 -> 41.259765 Khz + * 0x47 -> 47.607422 kHz */ /* 20 KBaud, 2FSK, 28.56 kHz deviation, 325 Khz bandwidth filter. */ @@ -130,3 +147,46 @@ static uint8_t protoview_subghz_tpms2_async_regs[][2] = { {0, 0}, }; +/* Parameters that should work well for the TPMS PVM C210 sensor. */ +static uint8_t protoview_subghz_tpms3_async_regs[][2] = { + /* GPIO GD0 */ + {CC1101_IOCFG0, 0x0D}, // GD0 as async serial data output/input + + /* Frequency Synthesizer Control */ + {CC1101_FSCTRL1, 0x06}, // IF = (26*10^6) / (2^10) * 0x06 = 152343.75Hz + + /* Packet engine */ + {CC1101_PKTCTRL0, 0x32}, // Async, continious, no whitening + {CC1101_PKTCTRL1, 0x04}, + + // // Modem Configuration + {CC1101_MDMCFG0, 0x00}, + {CC1101_MDMCFG1, 0x02}, // 2 is the channel spacing exponet: not used + {CC1101_MDMCFG2, 0x10}, // GFSK without any other check + {CC1101_MDMCFG3, 0x93}, // Data rate is 20kBaud + {CC1101_MDMCFG4, 0x59}, // Rx bandwidth filter is 325 kHz + {CC1101_DEVIATN, 0x34}, // Deviation 19.04 Khz, works well with TPMS + + /* Main Radio Control State Machine */ + {CC1101_MCSM0, 0x18}, // Autocalibrate on idle-to-rx/tx, PO_TIMEOUT is 64 cycles(149-155us) + + /* Frequency Offset Compensation Configuration */ + {CC1101_FOCCFG, + 0x16}, // no frequency offset compensation, POST_K same as PRE_K, PRE_K is 4K, GATE is off + + /* Automatic Gain Control */ + {CC1101_AGCCTRL0, 0x80}, + {CC1101_AGCCTRL1, 0x58}, + {CC1101_AGCCTRL2, 0x87}, + + /* Wake on radio and timeouts control */ + {CC1101_WORCTRL, 0xFB}, // WOR_RES is 2^15 periods (0.91 - 0.94 s) 16.5 - 17.2 hours + + /* Frontend configuration */ + {CC1101_FREND0, 0x10}, // Adjusts current TX LO buffer + {CC1101_FREND1, 0x56}, + + /* End */ + {0, 0}, +}; + diff --git a/applications/plugins/protoview/proto.c b/applications/plugins/protoview/data_feed.c similarity index 100% rename from applications/plugins/protoview/proto.c rename to applications/plugins/protoview/data_feed.c diff --git a/applications/plugins/protoview/images/protoview_1.jpg b/applications/plugins/protoview/images/protoview_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..10d9d6ec551f678fb8064ae8310dabd64d69b9c1 GIT binary patch literal 66885 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 a#@^hs?BdY5iuF7vE49l|^XuYYZ~hy2+QilX literal 0 HcmV?d00001 diff --git a/applications/plugins/protoview/images/protoview_2.jpg b/applications/plugins/protoview/images/protoview_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2560297707d0d2a38e5f4e5a4cf64ee4f0ab64ec GIT binary patch literal 64574 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 literal 0 HcmV?d00001 diff --git a/applications/plugins/protoview/protocols/b4b1.c b/applications/plugins/protoview/protocols/b4b1.c index 6977c0eb3..2bed2ac32 100644 --- a/applications/plugins/protoview/protocols/b4b1.c +++ b/applications/plugins/protoview/protocols/b4b1.c @@ -1,7 +1,7 @@ /* PT/SC remotes. Usually 443.92 Mhz OOK. * * This line code is used in many remotes such as Princeton chips - * named PT, Silian Microelectronics SC5262 and others. + * named PT2262, Silian Microelectronics SC5262 and others. * Basically every 4 pulsee represent a bit, where 1000 means 0, and * 1110 means 1. Usually we can read 24 bits of data. * In this specific implementation we check for a prelude that is diff --git a/applications/plugins/protoview/protocols/citroen_tpms.c b/applications/plugins/protoview/protocols/citroen_tpms.c new file mode 100644 index 000000000..14d824e50 --- /dev/null +++ b/applications/plugins/protoview/protocols/citroen_tpms.c @@ -0,0 +1,60 @@ +/* Citroen TPMS. Usually 443.92 Mhz FSK. + * + * Preamble of ~14 high/low 52 us pulses + * Sync of high 100us pulse then 50us low + * Then Manchester bits, 10 bytes total. + * Simple XOR checksum. */ + +#include "../app.h" + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + + /* We consider a preamble of 17 symbols. They are more, but the decoding + * is more likely to happen if we don't pretend to receive from the + * very start of the message. */ + uint32_t sync_len = 17; + const char *sync_pattern = "10101010101010110"; + if (numbits-sync_len < 8*10) return false; /* Expect 10 bytes. */ + + uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + if (off == BITMAP_SEEK_NOT_FOUND) return false; + FURI_LOG_E(TAG, "Renault TPMS preamble+sync found"); + + off += sync_len; /* Skip preamble + sync. */ + + uint8_t raw[10]; + uint32_t decoded = + convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, + "01","10"); /* Manchester. */ + FURI_LOG_E(TAG, "Citroen TPMS decoded bits: %lu", decoded); + + if (decoded < 8*10) return false; /* Require the full 10 bytes. */ + + /* Check the CRC. It's a simple XOR of bytes 1-9, the first byte + * is not included. The meaning of the first byte is unknown and + * we don't display it. */ + uint8_t crc = 0; + for (int j = 1; j < 10; j++) crc ^= raw[j]; + if (crc != 0) return false; /* Require sane checksum. */ + + int repeat = raw[5] & 0xf; + float kpa = (float)raw[6]*1.364; + int temp = raw[7]-50; + int battery = raw[8]; /* This may be the battery. It's not clear. */ + + snprintf(info->name,sizeof(info->name),"%s","Citroen TPMS"); + snprintf(info->raw,sizeof(info->raw), + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7],raw[8],raw[9]); + snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X", + raw[1],raw[2],raw[3],raw[4]); + snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); + snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); + snprintf(info->info4,sizeof(info->info4),"Repeat %d, Bat %d", repeat, battery); + return true; +} + +ProtoViewDecoder CitroenTPMSDecoder = { + "Citroen TPMS", decode +}; diff --git a/applications/plugins/protoview/protocols/ford_tpms.c b/applications/plugins/protoview/protocols/ford_tpms.c new file mode 100644 index 000000000..2cab0ea91 --- /dev/null +++ b/applications/plugins/protoview/protocols/ford_tpms.c @@ -0,0 +1,64 @@ +/* Ford tires TPMS. Usually 443.92 Mhz FSK (in Europe). + * + * 52 us short pules + * Preamble: 0101010101010101010101010101 + * Sync: 0110 (that is 52 us gap + 104 us pulse + 52 us gap) + * Data: 8 bytes Manchester encoded + * 01 = zero + * 10 = one + */ + +#include "../app.h" + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + + const char *sync_pattern = "010101010101" "0110"; + uint8_t sync_len = 12+4; /* We just use 12 preamble symbols + sync. */ + if (numbits-sync_len < 8*8) return false; + + uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + if (off == BITMAP_SEEK_NOT_FOUND) return false; + FURI_LOG_E(TAG, "Fort TPMS preamble+sync found"); + + off += sync_len; /* Skip preamble and sync. */ + + uint8_t raw[8]; + uint32_t decoded = + convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, + "01","10"); /* Manchester. */ + FURI_LOG_E(TAG, "Ford TPMS decoded bits: %lu", decoded); + + if (decoded < 8*8) return false; /* Require the full 8 bytes. */ + + /* CRC is just the sum of the first 7 bytes MOD 256. */ + uint8_t crc = 0; + for (int j = 0; j < 7; j++) crc += raw[j]; + if (crc != raw[7]) return false; /* Require sane CRC. */ + + float psi = 0.25 * (((raw[6]&0x20)<<3)|raw[4]); + + /* Temperature apperas to be valid only if the most significant + * bit of the value is not set. Otherwise its meaning is unknown. + * Likely useful to alternatively send temperature or other info. */ + int temp = raw[5] & 0x80 ? 0 : raw[5]-56; + int flags = raw[5] & 0x7f; + int car_moving = (raw[6] & 0x44) == 0x44; + + snprintf(info->name,sizeof(info->name),"%s","Ford TPMS"); + snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7]); + snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3]); + snprintf(info->info2,sizeof(info->info2),"Pressure %.2f psi", (double)psi); + if (temp) + snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); + else + snprintf(info->info3,sizeof(info->info3),"Flags %d", flags); + snprintf(info->info4,sizeof(info->info4),"Moving %s", car_moving ? "yes" : "no"); + return true; +} + +ProtoViewDecoder FordTPMSDecoder = { + "Ford TPMS", decode +}; diff --git a/applications/plugins/protoview/protocols/renault_tpms.c b/applications/plugins/protoview/protocols/renault_tpms.c index 3022a5d4e..1f8ea0711 100644 --- a/applications/plugins/protoview/protocols/renault_tpms.c +++ b/applications/plugins/protoview/protocols/renault_tpms.c @@ -1,16 +1,16 @@ /* Renault tires TPMS. Usually 443.92 Mhz FSK. * - * Preamble + marshal-encoded bits. 9 Bytes in total if we don't - * count the preamble. */ + * Preamble + sync + Manchester bits. ~48us short pulse. + * 9 Bytes in total not counting the preamble. */ #include "../app.h" #define USE_TEST_VECTOR 0 static const char *test_vector = - "10101010" "10101010" "10101010" "10101001" // Preamble + sync. + "...01010101010101010110" // Preamble + sync - /* The following is marshal encoded, so each two characters are - * actaully one bit. 01 = 1, 10 = 0. */ + /* The following is Marshal encoded, so each two characters are + * actaully one bit. 01 = 0, 10 = 1. */ "010110010110" // Flags. "10011001101010011001" // Pressure, multiply by 0.75 to obtain kpa. // 244 kpa here. @@ -29,22 +29,23 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView numbits = strlen(test_vector); } - if (numbits < 13*8) return false; + if (numbits-12 < 9*8) return false; - const char *sync_pattern = "10101010" "10101010" "10101010" "10101001"; + const char *sync_pattern = "01010101010101010110"; uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); if (off == BITMAP_SEEK_NOT_FOUND) return false; FURI_LOG_E(TAG, "Renault TPMS preamble+sync found"); - off += 32; /* Skip preamble. */ + off += 20; /* Skip preamble. */ uint8_t raw[9]; uint32_t decoded = convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, - "10","01"); /* Manchester. */ + "01","10"); /* Manchester. */ FURI_LOG_E(TAG, "Renault TPMS decoded bits: %lu", decoded); if (decoded < 8*9) return false; /* Require the full 9 bytes. */ + if (crc8(raw,8,0,7) != raw[8]) return false; /* Require sane CRC. */ float kpa = 0.75 *((uint32_t)((raw[0]&3)<<8) | raw[1]); int temp = raw[2]-30; @@ -53,8 +54,10 @@ static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoView snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], raw[6],raw[7],raw[8]); - snprintf(info->info1,sizeof(info->info1),"Pressure %.2f kpa", (double)kpa); - snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp); + snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X", + raw[3],raw[4],raw[5]); + snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); + snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); return true; } diff --git a/applications/plugins/protoview/protocols/schrader_tpms.c b/applications/plugins/protoview/protocols/schrader_tpms.c new file mode 100644 index 000000000..ebf3d6004 --- /dev/null +++ b/applications/plugins/protoview/protocols/schrader_tpms.c @@ -0,0 +1,65 @@ +/* Schrader TPMS. Usually 443.92 Mhz OOK, 120us pulse len. + * + * 500us high pulse + Preamble + Manchester coded bits where: + * 1 = 10 + * 0 = 01 + * + * 60 bits of data total (first 4 nibbles is the preamble, 0xF). + * + * Used in FIAT-Chrysler, Mercedes, ... */ + +#include "../app.h" + +#define USE_TEST_VECTOR 0 +static const char *test_vector = "000000111101010101011010010110010110101001010110100110011001100101010101011010100110100110011010101010101010101010101010101010101010101010101010"; + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + + if (USE_TEST_VECTOR) { /* Test vector to check that decoding works. */ + bitmap_set_pattern(bits,numbytes,test_vector); + numbits = strlen(test_vector); + } + + if (numbits < 64) return false; /* Preamble + data. */ + + const char *sync_pattern = "1111010101" "01011010"; + uint64_t off = bitmap_seek_bits(bits,numbytes,0,numbits,sync_pattern); + if (off == BITMAP_SEEK_NOT_FOUND) return false; + FURI_LOG_E(TAG, "Schrader TPMS gap+preamble found"); + + off += 10; /* Skip just the long pulse and the first 3 bits of sync, so + that we have the first byte of data with the sync nibble + 0011 = 0x3. */ + + uint8_t raw[8]; + uint32_t decoded = + convert_from_line_code(raw,sizeof(raw),bits,numbytes,off, + "01","10"); /* Manchester code. */ + FURI_LOG_E(TAG, "Schrader TPMS decoded bits: %lu", decoded); + + if (decoded < 64) return false; /* Require the full 8 bytes. */ + + raw[0] |= 0xf0; // Fix the preamble nibble for checksum computation. + uint8_t cksum = crc8(raw,sizeof(raw)-1,0xf0,0x7); + if (cksum != raw[7]) { + FURI_LOG_E(TAG, "Schrader TPMS checksum mismatch"); + return false; + } + + float kpa = (float)raw[5]*2.5; + int temp = raw[6]-50; + + snprintf(info->name,sizeof(info->name),"%s","Schrader TPMS"); + snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7]); + snprintf(info->info1,sizeof(info->info1),"Tire ID %01X%02X%02X%02X", + raw[1]&7,raw[2],raw[3],raw[4]); /* Only 28 bits of ID, not 32. */ + snprintf(info->info2,sizeof(info->info2),"Pressure %.2f kpa", (double)kpa); + snprintf(info->info3,sizeof(info->info3),"Temperature %d C", temp); + return true; +} + +ProtoViewDecoder SchraderTPMSDecoder = { + "Schrader TPMS", decode +}; diff --git a/applications/plugins/protoview/protocols/toyota_tpms.c b/applications/plugins/protoview/protocols/toyota_tpms.c new file mode 100644 index 000000000..b870c2f33 --- /dev/null +++ b/applications/plugins/protoview/protocols/toyota_tpms.c @@ -0,0 +1,77 @@ +/* Toyota tires TPMS. Usually 443.92 Mhz FSK (In Europe). + * + * Preamble + sync + 64 bits of data. ~48us short pulse length. + * + * The preamble + sync is something like: + * + * 10101010101 (preamble) + 001111[1] (sync) + * + * Note: the final [1] means that sometimes it is four 1s, sometimes + * five, depending on the short pulse length detection and the exact + * duration of the high long pulse. After the sync, a differential + * Manchester encoded payload follows. However the Flipper's CC1101 + * often can't decode correctly the initial alternating pattern 101010101, + * so what we do is to seek just the sync, that is "001111" or "0011111", + * however we now that it must be followed by one differenitally encoded + * bit, so we can use also the first bit of data to force a more robust + * detection, and look for one of the following: + * + * [001111]00 + * [0011111]00 + * [001111]01 + * [0011111]01 + */ + +#include "../app.h" + +static bool decode(uint8_t *bits, uint32_t numbytes, uint32_t numbits, ProtoViewMsgInfo *info) { + + if (numbits-6 < 64*2) return false; /* Ask for 64 bit of data (each bit + is two symbols in the bitmap). */ + + char *sync[] = { + "00111100", + "001111100", + "00111101", + "001111101", + NULL + }; + + int j; + uint32_t off = 0; + for (j = 0; sync[j]; j++) { + off = bitmap_seek_bits(bits,numbytes,0,numbits,sync[j]); + if (off != BITMAP_SEEK_NOT_FOUND) { + off += strlen(sync[j])-2; + break; + } + } + if (off == BITMAP_SEEK_NOT_FOUND) return false; + + FURI_LOG_E(TAG, "Toyota TPMS sync[%s] found", sync[j]); + + uint8_t raw[9]; + uint32_t decoded = + convert_from_diff_manchester(raw,sizeof(raw),bits,numbytes,off,true); + FURI_LOG_E(TAG, "Toyota TPMS decoded bits: %lu", decoded); + + if (decoded < 8*9) return false; /* Require the full 8 bytes. */ + if (crc8(raw,8,0x80,7) != raw[8]) return false; /* Require sane CRC. */ + + float kpa = (float)((raw[4]&0x7f)<<1 | raw[5]>>7) * 0.25 - 7; + int temp = ((raw[5]&0x7f)<<1 | raw[6]>>7) - 40; + + snprintf(info->name,sizeof(info->name),"%s","Toyota TPMS"); + snprintf(info->raw,sizeof(info->raw),"%02X%02X%02X%02X%02X%02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3],raw[4],raw[5], + raw[6],raw[7],raw[8]); + snprintf(info->info1,sizeof(info->info1),"Tire ID %02X%02X%02X%02X", + raw[0],raw[1],raw[2],raw[3]); + snprintf(info->info1,sizeof(info->info1),"Pressure %.2f psi", (double)kpa); + snprintf(info->info2,sizeof(info->info2),"Temperature %d C", temp); + return true; +} + +ProtoViewDecoder ToyotaTPMSDecoder = { + "Toyota TPMS", decode +}; diff --git a/applications/plugins/protoview/signal.c b/applications/plugins/protoview/signal.c index 2ff632811..5a1c6c99b 100644 --- a/applications/plugins/protoview/signal.c +++ b/applications/plugins/protoview/signal.c @@ -53,6 +53,7 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) { bool level; uint32_t dur; raw_samples_get(s, j, &level, &dur); + if (dur < minlen || dur > maxlen) break; /* return. */ /* Let's see if it matches a class we already have or if we @@ -70,7 +71,7 @@ uint32_t search_coherent_signal(RawSamplesBuffer *s, uint32_t idx) { /* Is the difference in duration between this signal and * the class we are inspecting less than a given percentage? * If so, accept this signal. */ - if (delta < classavg/8) { /* 100%/8 = 12%. */ + if (delta < classavg/5) { /* 100%/5 = 20%. */ /* It is useful to compute the average of the class * we are observing. We know how many samples we got so * far, so we can recompute the average easily. @@ -130,9 +131,9 @@ void scan_for_signal(ProtoViewApp *app) { /* Try to seek on data that looks to have a regular high low high low * pattern. */ - uint32_t minlen = 13; /* Min run of coherent samples. Up to - 12 samples it's very easy to mistake - noise for signal. */ + uint32_t minlen = 18; /* Min run of coherent samples. With less + than a few samples it's very easy to + mistake noise for signal. */ ProtoViewMsgInfo *info = malloc(sizeof(ProtoViewMsgInfo)); uint32_t i = 0; @@ -152,18 +153,25 @@ void scan_for_signal(ProtoViewApp *app) { the signal in the loop. */ /* Accept this signal as the new signal if either it's longer - * than the previous one, or the previous one was unknown and - * this is decoded. */ - if (thislen > app->signal_bestlen || - (app->signal_decoded == false && decoded)) + * than the previous undecoded one, or the previous one was + * unknown and this is decoded. */ + if ((thislen > app->signal_bestlen && app->signal_decoded == false) + || (app->signal_decoded == false && decoded)) { app->signal_info = *info; app->signal_bestlen = thislen; app->signal_decoded = decoded; raw_samples_copy(DetectedSamples,copy); raw_samples_center(DetectedSamples,i); - FURI_LOG_E(TAG, "Displayed sample updated (%d samples %lu us)", + FURI_LOG_E(TAG, "===> Displayed sample updated (%d samples %lu us)", (int)thislen, DetectedSamples->short_pulse_dur); + + /* Adjust raw view scale if the signal has an high + * data rate. */ + if (DetectedSamples->short_pulse_dur < 75) + app->us_scale = 10; + else if (DetectedSamples->short_pulse_dur < 145) + app->us_scale = 30; } } i += thislen ? thislen : 1; @@ -317,11 +325,9 @@ uint32_t convert_signal_to_bits(uint8_t *b, uint32_t blen, RawSamplesBuffer *s, /* This function converts the line code used to the final data representation. * The representation is put inside 'buf', for up to 'buflen' bytes of total - * data. For instance in order to convert manchester I can use "10" and "01" - * as zero and one patterns. It is possible to use "?" inside patterns in - * order to skip certain bits. For instance certain devices encode data twice, - * with each bit encoded in manchester encoding and then in its reversed - * representation. In such a case I could use "10??" and "01??". + * data. For instance in order to convert manchester you can use "10" and "01" + * as zero and one patterns. However this function does not handle differential + * encodings. See below for convert_from_diff_manchester(). * * The function returns the number of bits converted. It will stop as soon * as it finds a pattern that does not match zero or one patterns, or when @@ -350,17 +356,46 @@ uint32_t convert_from_line_code(uint8_t *buf, uint64_t buflen, uint8_t *bits, ui return decoded; } +/* Convert the differential Manchester code to bits. This is similar to + * convert_from_line_code() but specific for Manchester. The user must + * supply the value of the previous symbol before this stream, since + * in differential codings the next bits depend on the previous one. + * + * Parameters and return values are like convert_from_line_code(). */ +uint32_t convert_from_diff_manchester(uint8_t *buf, uint64_t buflen, uint8_t *bits, uint32_t len, uint32_t off, bool previous) +{ + uint32_t decoded = 0; + len *= 8; /* Conver to bits. */ + for (uint32_t j = off; j < len; j += 2) { + bool b0 = bitmap_get(bits,len,j); + bool b1 = bitmap_get(bits,len,j+1); + if (b0 == previous) break; /* Each new bit must switch value. */ + bitmap_set(buf,buflen,decoded++,b0 == b1); + previous = b1; + if (decoded/8 == buflen) break; /* No space left on target buffer. */ + } + return decoded; +} + /* Supported protocols go here, with the relevant implementation inside * protocols/.c */ extern ProtoViewDecoder Oregon2Decoder; extern ProtoViewDecoder B4B1Decoder; extern ProtoViewDecoder RenaultTPMSDecoder; +extern ProtoViewDecoder ToyotaTPMSDecoder; +extern ProtoViewDecoder SchraderTPMSDecoder; +extern ProtoViewDecoder CitroenTPMSDecoder; +extern ProtoViewDecoder FordTPMSDecoder; ProtoViewDecoder *Decoders[] = { &Oregon2Decoder, /* Oregon sensors v2.1 protocol. */ &B4B1Decoder, /* PT, SC, ... 24 bits remotes. */ &RenaultTPMSDecoder, /* Renault TPMS. */ + &ToyotaTPMSDecoder, /* Toyota TPMS. */ + &SchraderTPMSDecoder, /* Schrader TPMS. */ + &CitroenTPMSDecoder, /* Citroen TPMS. */ + &FordTPMSDecoder, /* Ford TPMS. */ NULL }; @@ -378,12 +413,13 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) { uint32_t bitmap_bits_size = 4096*8; uint32_t bitmap_size = bitmap_bits_size/8; - /* We call the decoders with an offset a few bits before the actual + /* We call the decoders with an offset a few samples before the actual * signal detected and for a len of a few bits after its end. */ - uint32_t before_after_bits = 2; + uint32_t before_samples = 20; + uint32_t after_samples = 100; uint8_t *bitmap = malloc(bitmap_size); - uint32_t bits = convert_signal_to_bits(bitmap,bitmap_size,s,-before_after_bits,len+before_after_bits*2,s->short_pulse_dur); + uint32_t bits = convert_signal_to_bits(bitmap,bitmap_size,s,-before_samples,len+before_samples+after_samples,s->short_pulse_dur); if (DEBUG_MSG) { /* Useful for debugging purposes. Don't remove. */ char *str = malloc(1024); @@ -413,7 +449,7 @@ bool decode_signal(RawSamplesBuffer *s, uint64_t len, ProtoViewMsgInfo *info) { if (!decoded) { FURI_LOG_E(TAG, "No decoding possible"); } else { - FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s]", info->name, info->raw, info->info1, info->info2, info->info3); + FURI_LOG_E(TAG, "Decoded %s, raw=%s info=[%s,%s,%s,%s]", info->name, info->raw, info->info1, info->info2, info->info3, info->info4); } free(bitmap); return decoded; diff --git a/applications/plugins/protoview/view_direct_sampling.c b/applications/plugins/protoview/view_direct_sampling.c index a287dc14a..251a289b8 100644 --- a/applications/plugins/protoview/view_direct_sampling.c +++ b/applications/plugins/protoview/view_direct_sampling.c @@ -8,7 +8,18 @@ /* Read directly from the G0 CC1101 pin, and draw a black or white * dot depending on the level. */ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) { - UNUSED(app); + if (!app->direct_sampling_enabled) { + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas,2,9,"Direct sampling is a special"); + canvas_draw_str(canvas,2,18,"mode that displays the signal"); + canvas_draw_str(canvas,2,27,"captured in real time. Like in"); + canvas_draw_str(canvas,2,36,"a old CRT TV. It's very slow."); + canvas_draw_str(canvas,2,45,"Can crash your Flipper."); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas,14,60,"To enable press OK"); + return; + } + for (int y = 0; y < 64; y++) { for (int x = 0; x < 128; x++) { bool level = furi_hal_gpio_read(&gpio_cc1101_g0); @@ -16,31 +27,41 @@ void render_view_direct_sampling(Canvas *const canvas, ProtoViewApp *app) { /* Busy loop: this is a terrible approach as it blocks * everything else, but for now it's the best we can do * to obtain direct data with some spacing. */ - uint32_t x = 500; while(x--); + uint32_t x = 250; while(x--); } } canvas_set_font(canvas, FontSecondary); - canvas_draw_str_with_border(canvas,40,60,"Direct sampling", + canvas_draw_str_with_border(canvas,36,60,"Direct sampling", ColorWhite,ColorBlack); } /* Handle input */ void process_input_direct_sampling(ProtoViewApp *app, InputEvent input) { - UNUSED(app); - UNUSED(input); + if (input.type == InputTypePress && input.key == InputKeyOk) { + app->direct_sampling_enabled = !app->direct_sampling_enabled; + } } /* Enter view. Stop the subghz thread to prevent access as we read * the CC1101 data directly. */ void view_enter_direct_sampling(ProtoViewApp *app) { - if (app->txrx->txrx_state == TxRxStateRx) { + if (app->txrx->txrx_state == TxRxStateRx && + !app->txrx->debug_timer_sampling) + { subghz_worker_stop(app->txrx->worker); + } else { + raw_sampling_worker_stop(app); } } /* Exit view. Restore the subghz thread. */ void view_exit_direct_sampling(ProtoViewApp *app) { - if (app->txrx->txrx_state == TxRxStateRx) { + if (app->txrx->txrx_state == TxRxStateRx && + !app->txrx->debug_timer_sampling) + { subghz_worker_start(app->txrx->worker); + } else { + raw_sampling_worker_start(app); } + app->direct_sampling_enabled = false; } diff --git a/applications/plugins/protoview/view_info.c b/applications/plugins/protoview/view_info.c index fff9c836e..775c8abc2 100644 --- a/applications/plugins/protoview/view_info.c +++ b/applications/plugins/protoview/view_info.c @@ -25,17 +25,18 @@ void render_view_info(Canvas *const canvas, ProtoViewApp *app) { canvas_draw_str(canvas, 0, y, buf); y += lineheight; } - canvas_draw_str(canvas, 0, y, app->signal_info.info1); - y += lineheight; - canvas_draw_str(canvas, 0, y, app->signal_info.info2); - y += lineheight; - canvas_draw_str(canvas, 0, y, app->signal_info.info3); - y += lineheight; + canvas_draw_str(canvas, 0, y, app->signal_info.info1); y += lineheight; + canvas_draw_str(canvas, 0, y, app->signal_info.info2); y += lineheight; + canvas_draw_str(canvas, 0, y, app->signal_info.info3); y += lineheight; + canvas_draw_str(canvas, 0, y, app->signal_info.info4); y += lineheight; } -/* Handle input for the settings view. */ +/* Handle input for the info view. */ void process_input_info(ProtoViewApp *app, InputEvent input) { - UNUSED(app); - UNUSED(input); - return; + if (input.type == InputTypeShort) { + if (input.key == InputKeyOk) { + /* Reset the current sample to capture the next. */ + reset_current_signal(app); + } + } } diff --git a/applications/plugins/protoview/view_settings.c b/applications/plugins/protoview/view_settings.c index 22ac5ef0f..1e2dce226 100644 --- a/applications/plugins/protoview/view_settings.c +++ b/applications/plugins/protoview/view_settings.c @@ -20,6 +20,9 @@ void render_view_settings(Canvas *const canvas, ProtoViewApp *app) { canvas_set_font(canvas, FontSecondary); canvas_draw_str(canvas,10,61,"Use up and down to modify"); + if (app->txrx->debug_timer_sampling) + canvas_draw_str(canvas,3,52,"(DEBUG timer sampling is ON)"); + /* Show frequency. We can use big numbers font since it's just a number. */ if (app->current_view == ViewFrequencySettings) { char buf[16]; @@ -40,6 +43,18 @@ void process_input_settings(ProtoViewApp *app, InputEvent input) { * modulation. */ app->frequency = subghz_setting_get_default_frequency(app->setting); app->modulation = 0; + } else if (0 && input.type == InputTypeLong && input.key == InputKeyDown) { + /* Long pressing to down switches between normal and debug + * timer sampling mode. NOTE: this feature is disabled for users, + * only useful for devs (if useful at all). */ + + /* We have to stop the previous sampling system. */ + radio_rx_end(app); + + /* Then switch mode and start the new one. */ + app->txrx->debug_timer_sampling = !app->txrx->debug_timer_sampling; + radio_begin(app); + radio_rx(app); } else if (input.type == InputTypePress && (input.key != InputKeyDown || input.key != InputKeyUp)) { @@ -85,9 +100,18 @@ void process_input_settings(ProtoViewApp *app, InputEvent input) { return; } - /* Apply changes. */ - FURI_LOG_E(TAG, "Setting view, setting frequency/modulation to %lu %s", app->frequency, ProtoViewModulations[app->modulation].name); - radio_rx_end(app); - radio_begin(app); - radio_rx(app); + /* Apply changes when switching to other views. */ + app->txrx->freq_mod_changed = true; +} + +/* When the user switches to some other view, if they changed the parameters + * we need to restart the radio with the right frequency and modulation. */ +void view_exit_settings(ProtoViewApp *app) { + if (app->txrx->freq_mod_changed) { + FURI_LOG_E(TAG, "Setting view, setting frequency/modulation to %lu %s", app->frequency, ProtoViewModulations[app->modulation].name); + radio_rx_end(app); + radio_begin(app); + radio_rx(app); + app->txrx->freq_mod_changed = false; + } }