From 9b75f957d9fec1bfb68583f90dad6eb264341759 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 17:15:38 +0300 Subject: [PATCH 01/10] update link --- .drone.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.drone.yml b/.drone.yml index 815426784..1e9e7586f 100644 --- a/.drone.yml +++ b/.drone.yml @@ -23,7 +23,7 @@ steps: - ls -laS artifacts-default - ls -laS artifacts-default/f7-update-${DRONE_TAG} - sed -i 's/(version)/'${DRONE_TAG}'/g' CHANGELOG.md - - echo '# [Install via Web Updater](https://my.flipp.dev/?url=https://unleashedflip.com/builds/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=dev-cfw&version='${DRONE_TAG}')' >> CHANGELOG.md + - echo '# [Install via Web Updater](https://lab.flipper.net/?url=https://unleashedflip.com/builds/flipper-z-f7-update-'${DRONE_TAG}'.tgz&channel=dev-cfw&version='${DRONE_TAG}')' >> CHANGELOG.md environment: FBT_TOOLS_CUSTOM_LINK: from_secret: fbt_link @@ -88,7 +88,7 @@ steps: [-How to install firmware-](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/documentation/HowToInstall.md) - [-Install via Web Updater-](https://my.flipp.dev/?url=https://unleashedflip.com/builds/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=dev-cfw&version=${DRONE_TAG})" + [-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/builds/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=dev-cfw&version=${DRONE_TAG})" document: - artifacts-default/flipper-z-f7-update-${DRONE_TAG}.tgz @@ -108,7 +108,7 @@ steps: [[Github]](https://github.com/DarkFlippers/unleashed-firmware/releases/tag/${DRONE_TAG}) - [-Install via Web Updater-](https://my.flipp.dev/?url=https://unleashedflip.com/builds/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=dev-cfw&version=${DRONE_TAG})" + [-Install via Web Updater-](https://lab.flipper.net/?url=https://unleashedflip.com/builds/flipper-z-f7-update-${DRONE_TAG}.tgz&channel=dev-cfw&version=${DRONE_TAG})" trigger: event: From 1e7b45159efe052205990ea3d140b371287189c1 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 17:26:03 +0300 Subject: [PATCH 02/10] again.... --- firmware/targets/f7/api_symbols.csv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 2e96e335e..0967d447c 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -1,5 +1,5 @@ entry,status,name,type,params -Version,+,5.1,, +Version,+,6.1,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, From b39e0dd09e56e8f684ba6946fa23f12af4312c5d Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 18:31:47 +0300 Subject: [PATCH 03/10] cleanup --- firmware/targets/f7/api_symbols.csv | 1 - 1 file changed, 1 deletion(-) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index 0967d447c..dbb0da633 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -4729,7 +4729,6 @@ Variable,-,subghz_protocol_nice_flo_encoder,const SubGhzProtocolEncoder, Variable,-,subghz_protocol_nice_flor_s,const SubGhzProtocol, Variable,-,subghz_protocol_nice_flor_s_decoder,const SubGhzProtocolDecoder, Variable,-,subghz_protocol_nice_flor_s_encoder,const SubGhzProtocolEncoder, -Variable,-,subghz_protocol_oregon2,const SubGhzProtocol, Variable,-,subghz_protocol_phoenix_v2,const SubGhzProtocol, Variable,-,subghz_protocol_phoenix_v2_decoder,const SubGhzProtocolDecoder, Variable,-,subghz_protocol_phoenix_v2_encoder,const SubGhzProtocolEncoder, From 517d4ffb732f9285325b8603ace378909a142e28 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 19:53:59 +0300 Subject: [PATCH 04/10] new plugin, and use clear power in temp sensor --- applications/plugins/hc_sr04/application.fam | 14 + .../plugins/hc_sr04/dist_sensor10px.png | Bin 0 -> 141 bytes applications/plugins/hc_sr04/hc_sr04.c | 251 ++++++++++++++++++ .../temperature_sensor/temperature_sensor.c | 2 + 4 files changed, 267 insertions(+) create mode 100644 applications/plugins/hc_sr04/application.fam create mode 100644 applications/plugins/hc_sr04/dist_sensor10px.png create mode 100644 applications/plugins/hc_sr04/hc_sr04.c diff --git a/applications/plugins/hc_sr04/application.fam b/applications/plugins/hc_sr04/application.fam new file mode 100644 index 000000000..17599b5d1 --- /dev/null +++ b/applications/plugins/hc_sr04/application.fam @@ -0,0 +1,14 @@ +App( + appid="hc_sr04", + name="HC-SR04 Dist. Sensor", + apptype=FlipperAppType.EXTERNAL, + entry_point="hc_sr04_app", + cdefines=["APP_HC_SR04"], + requires=[ + "gui", + ], + stack_size=2 * 1024, + order=20, + fap_icon="dist_sensor10px.png", + fap_category="GPIO", +) \ No newline at end of file diff --git a/applications/plugins/hc_sr04/dist_sensor10px.png b/applications/plugins/hc_sr04/dist_sensor10px.png new file mode 100644 index 0000000000000000000000000000000000000000..af9aa7358ea19072cccd0e462070dab2695cab9f GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^AT}2V8<6ZZI=>f4F%}28J29*~C-V}>arbm_43U`H zJHeCdfB_G)yW;=qVA* oJ^0$FdYZ?lpqVlAH`e}OzR_*?{aKRrL!glip00i_>zopr0MDB=8UO$Q literal 0 HcmV?d00001 diff --git a/applications/plugins/hc_sr04/hc_sr04.c b/applications/plugins/hc_sr04/hc_sr04.c new file mode 100644 index 000000000..3f6d8da78 --- /dev/null +++ b/applications/plugins/hc_sr04/hc_sr04.c @@ -0,0 +1,251 @@ +// insired by +// https://github.com/esphome/esphome/blob/ac0d921413c3884752193fe568fa82853f0f99e9/esphome/components/ultrasonic/ultrasonic_sensor.cpp +// Ported and modified by @xMasterX + +#include +#include +#include +#include +#include +#include +#include +#include + +typedef enum { + EventTypeTick, + EventTypeKey, +} EventType; + +typedef struct { + EventType type; + InputEvent input; +} PluginEvent; + +typedef struct { + NotificationApp* notification; + bool have_5v; + bool measurement_made; + uint32_t echo; // ms + float distance; // meters +} PluginState; + +const NotificationSequence sequence_done = { + &message_display_backlight_on, + &message_green_255, + &message_note_c5, + &message_delay_50, + &message_sound_off, + NULL, +}; + +static void render_callback(Canvas* const canvas, void* ctx) { + const PluginState* plugin_state = acquire_mutex((ValueMutex*)ctx, 25); + if(plugin_state == NULL) { + return; + } + // border around the edge of the screen + // canvas_draw_frame(canvas, 0, 0, 128, 64); + + canvas_set_font(canvas, FontPrimary); + elements_multiline_text_aligned( + canvas, 64, 2, AlignCenter, AlignTop, "HC-SR04 Ultrasonic\nDistance Sensor"); + + canvas_set_font(canvas, FontSecondary); + + if(!plugin_state->have_5v) { + elements_multiline_text_aligned( + canvas, + 4, + 28, + AlignLeft, + AlignTop, + "5V on GPIO must be\nenabled, or USB must\nbe connected."); + } else { + if(!plugin_state->measurement_made) { + elements_multiline_text_aligned( + canvas, 64, 28, AlignCenter, AlignTop, "Press OK button to measure"); + elements_multiline_text_aligned( + canvas, 64, 40, AlignCenter, AlignTop, "13/TX -> Trig\n14/RX -> Echo"); + } else { + elements_multiline_text_aligned(canvas, 4, 28, AlignLeft, AlignTop, "Readout:"); + + FuriString* str_buf; + str_buf = furi_string_alloc(); + furi_string_printf(str_buf, "Echo: %ld ms", plugin_state->echo); + + canvas_draw_str_aligned( + canvas, 8, 38, AlignLeft, AlignTop, furi_string_get_cstr(str_buf)); + furi_string_printf(str_buf, "Distance: %02f m", (double)plugin_state->distance); + canvas_draw_str_aligned( + canvas, 8, 48, AlignLeft, AlignTop, furi_string_get_cstr(str_buf)); + + furi_string_free(str_buf); + } + } + + release_mutex((ValueMutex*)ctx, plugin_state); +} + +static void input_callback(InputEvent* input_event, FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + PluginEvent event = {.type = EventTypeKey, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +static void hc_sr04_state_init(PluginState* const plugin_state) { + plugin_state->echo = -1; + plugin_state->distance = -1; + plugin_state->measurement_made = false; + + furi_hal_power_suppress_charge_enter(); + + plugin_state->have_5v = false; + if(furi_hal_power_is_otg_enabled() || furi_hal_power_is_charging()) { + plugin_state->have_5v = true; + } else { + furi_hal_power_enable_otg(); + plugin_state->have_5v = true; + } +} + +float hc_sr04_ms_to_m(uint32_t ms) { + const float speed_sound_m_per_s = 343.0f; + const float time_s = ms / 1e3f; + const float total_dist = time_s * speed_sound_m_per_s; + return total_dist / 2.0f; +} + +static void hc_sr04_measure(PluginState* const plugin_state) { + //plugin_state->echo = 1; + //return; + + if(!plugin_state->have_5v) { + if(furi_hal_power_is_otg_enabled() || furi_hal_power_is_charging()) { + plugin_state->have_5v = true; + } else { + return; + } + } + + //furi_hal_light_set(LightRed, 0xFF); + notification_message(plugin_state->notification, &sequence_blink_start_yellow); + + const uint32_t timeout_ms = 2000; + // Pin 13 / TX -> Trig + furi_hal_gpio_write(&gpio_usart_tx, false); + furi_hal_gpio_init(&gpio_usart_tx, GpioModeOutputPushPull, GpioPullNo, GpioSpeedVeryHigh); + + // Pin 14 / RX -> Echo + furi_hal_gpio_write(&gpio_usart_rx, false); + furi_hal_gpio_init(&gpio_usart_rx, GpioModeInput, GpioPullNo, GpioSpeedVeryHigh); + + //FURI_CRITICAL_ENTER(); + // 10 ms pulse on TX + furi_hal_gpio_write(&gpio_usart_tx, true); + furi_delay_ms(10); + furi_hal_gpio_write(&gpio_usart_tx, false); + + // TODO change from furi_get_tick(), which returns ms, + // to DWT->CYCCNT, which is a more precise counter with + // us precision (see furi_hal_cortex_delay_us) + + const uint32_t start = furi_get_tick(); + + while(furi_get_tick() - start < timeout_ms && furi_hal_gpio_read(&gpio_usart_rx)) + ; + while(furi_get_tick() - start < timeout_ms && !furi_hal_gpio_read(&gpio_usart_rx)) + ; + + const uint32_t pulse_start = furi_get_tick(); + + while(furi_get_tick() - start < timeout_ms && furi_hal_gpio_read(&gpio_usart_rx)) + ; + + const uint32_t pulse_end = furi_get_tick(); + //FURI_CRITICAL_EXIT(); + + plugin_state->echo = pulse_end - pulse_start; + plugin_state->distance = hc_sr04_ms_to_m(pulse_end - pulse_start); + plugin_state->measurement_made = true; + + //furi_hal_light_set(LightRed, 0x00); + notification_message(plugin_state->notification, &sequence_blink_stop); + notification_message(plugin_state->notification, &sequence_done); +} + +int32_t hc_sr04_app() { + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(PluginEvent)); + + PluginState* plugin_state = malloc(sizeof(PluginState)); + + hc_sr04_state_init(plugin_state); + + ValueMutex state_mutex; + if(!init_mutex(&state_mutex, plugin_state, sizeof(PluginState))) { + FURI_LOG_E("hc_sr04", "cannot create mutex\r\n"); + if(furi_hal_power_is_otg_enabled()) { + furi_hal_power_disable_otg(); + } + furi_hal_power_suppress_charge_exit(); + furi_message_queue_free(event_queue); + free(plugin_state); + return 255; + } + + plugin_state->notification = furi_record_open(RECORD_NOTIFICATION); + + // Set system callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, render_callback, &state_mutex); + view_port_input_callback_set(view_port, input_callback, event_queue); + + // Open GUI and register view_port + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + PluginEvent event; + for(bool processing = true; processing;) { + FuriStatus event_status = furi_message_queue_get(event_queue, &event, 100); + + PluginState* plugin_state = (PluginState*)acquire_mutex_block(&state_mutex); + + if(event_status == FuriStatusOk) { + // press events + if(event.type == EventTypeKey) { + if(event.input.type == InputTypePress) { + switch(event.input.key) { + case InputKeyUp: + case InputKeyDown: + case InputKeyRight: + case InputKeyLeft: + break; + case InputKeyOk: + hc_sr04_measure(plugin_state); + break; + case InputKeyBack: + processing = false; + break; + } + } + } + } + + view_port_update(view_port); + release_mutex(&state_mutex, plugin_state); + } + + if(furi_hal_power_is_otg_enabled()) { + furi_hal_power_disable_otg(); + } + furi_hal_power_suppress_charge_exit(); + view_port_enabled_set(view_port, false); + gui_remove_view_port(gui, view_port); + furi_record_close(RECORD_GUI); + furi_record_close(RECORD_NOTIFICATION); + view_port_free(view_port); + furi_message_queue_free(event_queue); + delete_mutex(&state_mutex); + + return 0; +} \ No newline at end of file diff --git a/applications/plugins/temperature_sensor/temperature_sensor.c b/applications/plugins/temperature_sensor/temperature_sensor.c index 311d10e31..9ffa4719d 100644 --- a/applications/plugins/temperature_sensor/temperature_sensor.c +++ b/applications/plugins/temperature_sensor/temperature_sensor.c @@ -194,6 +194,7 @@ static void temperature_sensor_timer_callback(FuriMessageQueue* event_queue) { int32_t temperature_sensor_app(void* p) { UNUSED(p); + furi_hal_power_suppress_charge_enter(); // Declare our variables TSEvent tsEvent; bool sensorFound = false; @@ -264,6 +265,7 @@ int32_t temperature_sensor_app(void* p) { furi_delay_tick(wait_ticks); } + furi_hal_power_suppress_charge_exit(); // Dobby is freee (free our variables, Flipper will crash if we don't do this!) furi_timer_free(timer); gui_remove_view_port(gui, view_port); From 29ab1088bd3b6c9df8d21d0cc8f00cccebcd5b23 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 21:22:11 +0300 Subject: [PATCH 05/10] WS: add protocol Acurite 592TXR OFW PR 1916 by Skorpionm --- .../helpers/weather_station_types.h | 2 +- .../protocols/acurite_592txr.c | 307 ++++++++++++++++++ .../protocols/acurite_592txr.h | 79 +++++ .../protocols/protocol_items.c | 1 + .../protocols/protocol_items.h | 1 + firmware/targets/f7/api_symbols.csv | 4 + lib/subghz/blocks/math.c | 30 ++ lib/subghz/blocks/math.h | 31 ++ 8 files changed, 454 insertions(+), 1 deletion(-) create mode 100644 applications/plugins/weather_station/protocols/acurite_592txr.c create mode 100644 applications/plugins/weather_station/protocols/acurite_592txr.h diff --git a/applications/plugins/weather_station/helpers/weather_station_types.h b/applications/plugins/weather_station/helpers/weather_station_types.h index 275d23329..479638b98 100644 --- a/applications/plugins/weather_station/helpers/weather_station_types.h +++ b/applications/plugins/weather_station/helpers/weather_station_types.h @@ -3,7 +3,7 @@ #include #include -#define WS_VERSION_APP "0.2" +#define WS_VERSION_APP "0.3" #define WS_DEVELOPED "SkorP" #define WS_GITHUB "https://github.com/flipperdevices/flipperzero-firmware" diff --git a/applications/plugins/weather_station/protocols/acurite_592txr.c b/applications/plugins/weather_station/protocols/acurite_592txr.c new file mode 100644 index 000000000..db05af095 --- /dev/null +++ b/applications/plugins/weather_station/protocols/acurite_592txr.c @@ -0,0 +1,307 @@ +#include "acurite_592txr.h" + +#define TAG "WSProtocolAcurite_592TXR" + +/* + * Help + * https://github.com/merbanan/rtl_433/blob/5bef4e43133ac4c0e2d18d36f87c52b4f9458453/src/devices/acurite.c + * + * Acurite 592TXR Temperature Humidity sensor decoder + * Message Type 0x04, 7 bytes + * | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | + * | --------- | --------- | --------- | --------- | --------- | --------- | --------- | + * | CCII IIII | IIII IIII | pB00 0100 | pHHH HHHH | p??T TTTT | pTTT TTTT | KKKK KKKK | + * - C: Channel 00: C, 10: B, 11: A, (01 is invalid) + * - I: Device ID (14 bits) + * - B: Battery, 1 is battery OK, 0 is battery low + * - M: Message type (6 bits), 0x04 + * - T: Temperature Celsius (11 - 14 bits?), + 1000 * 10 + * - H: Relative Humidity (%) (7 bits) + * - K: Checksum (8 bits) + * - p: Parity bit + * Notes: + * - Temperature + * - Encoded as Celsius + 1000 * 10 + * - only 11 bits needed for specified range -40 C to 70 C (-40 F - 158 F) + * - However 14 bits available for temperature, giving possible range of -100 C to 1538.4 C + * - @todo - check if high 3 bits ever used for anything else + * + */ + +static const SubGhzBlockConst ws_protocol_acurite_592txr_const = { + .te_short = 200, + .te_long = 400, + .te_delta = 90, + .min_count_bit_for_found = 56, +}; + +struct WSProtocolDecoderAcurite_592TXR { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + WSBlockGeneric generic; + + uint16_t header_count; +}; + +struct WSProtocolEncoderAcurite_592TXR { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + WSBlockGeneric generic; +}; + +typedef enum { + Acurite_592TXRDecoderStepReset = 0, + Acurite_592TXRDecoderStepCheckPreambule, + Acurite_592TXRDecoderStepSaveDuration, + Acurite_592TXRDecoderStepCheckDuration, +} Acurite_592TXRDecoderStep; + +const SubGhzProtocolDecoder ws_protocol_acurite_592txr_decoder = { + .alloc = ws_protocol_decoder_acurite_592txr_alloc, + .free = ws_protocol_decoder_acurite_592txr_free, + + .feed = ws_protocol_decoder_acurite_592txr_feed, + .reset = ws_protocol_decoder_acurite_592txr_reset, + + .get_hash_data = ws_protocol_decoder_acurite_592txr_get_hash_data, + .serialize = ws_protocol_decoder_acurite_592txr_serialize, + .deserialize = ws_protocol_decoder_acurite_592txr_deserialize, + .get_string = ws_protocol_decoder_acurite_592txr_get_string, +}; + +const SubGhzProtocolEncoder ws_protocol_acurite_592txr_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol ws_protocol_acurite_592txr = { + .name = WS_PROTOCOL_ACURITE_592TXR_NAME, + .type = SubGhzProtocolWeatherStation, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &ws_protocol_acurite_592txr_decoder, + .encoder = &ws_protocol_acurite_592txr_encoder, +}; + +void* ws_protocol_decoder_acurite_592txr_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + WSProtocolDecoderAcurite_592TXR* instance = malloc(sizeof(WSProtocolDecoderAcurite_592TXR)); + instance->base.protocol = &ws_protocol_acurite_592txr; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void ws_protocol_decoder_acurite_592txr_free(void* context) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + free(instance); +} + +void ws_protocol_decoder_acurite_592txr_reset(void* context) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; +} + +static bool ws_protocol_acurite_592txr_check_crc(WSProtocolDecoderAcurite_592TXR* instance) { + uint8_t msg[] = { + instance->decoder.decode_data >> 48, + instance->decoder.decode_data >> 40, + instance->decoder.decode_data >> 32, + instance->decoder.decode_data >> 24, + instance->decoder.decode_data >> 16, + instance->decoder.decode_data >> 8}; + + if((subghz_protocol_blocks_add_bytes(msg, 6) == + (uint8_t)(instance->decoder.decode_data & 0xFF)) && + (!subghz_protocol_blocks_parity_bytes(&msg[2], 4))) { + return true; + } else { + return false; + } +} + +/** + * Analysis of received data + * @param instance Pointer to a WSBlockGeneric* instance + */ +static void ws_protocol_acurite_592txr_remote_controller(WSBlockGeneric* instance) { + uint8_t channel[] = {3, 0, 2, 1}; + uint8_t channel_raw = ((instance->data >> 54) & 0x03); + instance->channel = channel[channel_raw]; + instance->id = (instance->data >> 40) & 0x3FFF; + instance->battery_low = !((instance->data >> 38) & 1); + instance->humidity = (instance->data >> 24) & 0x7F; + + uint16_t temp_raw = ((instance->data >> 9) & 0xF80) | ((instance->data >> 8) & 0x7F); + instance->temp = ((float)(temp_raw)-1000) / 10.0f; + + instance->btn = WS_NO_BTN; +} + +void ws_protocol_decoder_acurite_592txr_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + + switch(instance->decoder.parser_step) { + case Acurite_592TXRDecoderStepReset: + if((level) && (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short * 3) < + ws_protocol_acurite_592txr_const.te_delta * 2)) { + instance->decoder.parser_step = Acurite_592TXRDecoderStepCheckPreambule; + instance->decoder.te_last = duration; + instance->header_count = 0; + } + break; + + case Acurite_592TXRDecoderStepCheckPreambule: + if(level) { + instance->decoder.te_last = duration; + } else { + if((DURATION_DIFF( + instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_short * 3) < + ws_protocol_acurite_592txr_const.te_delta * 2) && + (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short * 3) < + ws_protocol_acurite_592txr_const.te_delta * 2)) { + //Found preambule + instance->header_count++; + } else if((instance->header_count > 2) && (instance->header_count < 5)) { + if((DURATION_DIFF( + instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_short) < + ws_protocol_acurite_592txr_const.te_delta) && + (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_long) < + ws_protocol_acurite_592txr_const.te_delta)) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_long) < + ws_protocol_acurite_592txr_const.te_delta) && + (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short) < + ws_protocol_acurite_592txr_const.te_delta)) { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; + } else { + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; + } + } else { + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; + } + } + break; + + case Acurite_592TXRDecoderStepSaveDuration: + if(level) { + instance->decoder.te_last = duration; + instance->decoder.parser_step = Acurite_592TXRDecoderStepCheckDuration; + } else { + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; + } + break; + + case Acurite_592TXRDecoderStepCheckDuration: + if(!level) { + if(duration >= ((uint32_t)ws_protocol_acurite_592txr_const.te_short * 5)) { + if((instance->decoder.decode_count_bit == + ws_protocol_acurite_592txr_const.min_count_bit_for_found) && + ws_protocol_acurite_592txr_check_crc(instance)) { + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = instance->decoder.decode_count_bit; + ws_protocol_acurite_592txr_remote_controller(&instance->generic); + if(instance->base.callback) + instance->base.callback(&instance->base, instance->base.context); + } + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; + break; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_short) < + ws_protocol_acurite_592txr_const.te_delta) && + (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_long) < + ws_protocol_acurite_592txr_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 0); + instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; + } else if( + (DURATION_DIFF( + instance->decoder.te_last, ws_protocol_acurite_592txr_const.te_long) < + ws_protocol_acurite_592txr_const.te_delta) && + (DURATION_DIFF(duration, ws_protocol_acurite_592txr_const.te_short) < + ws_protocol_acurite_592txr_const.te_delta)) { + subghz_protocol_blocks_add_bit(&instance->decoder, 1); + instance->decoder.parser_step = Acurite_592TXRDecoderStepSaveDuration; + } else { + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; + } + } else { + instance->decoder.parser_step = Acurite_592TXRDecoderStepReset; + } + break; + } +} + +uint8_t ws_protocol_decoder_acurite_592txr_get_hash_data(void* context) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +bool ws_protocol_decoder_acurite_592txr_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + return ws_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +bool ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + bool ret = false; + do { + if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + ws_protocol_acurite_592txr_const.min_count_bit_for_found) { + FURI_LOG_E(TAG, "Wrong number of bits in key"); + break; + } + ret = true; + } while(false); + return ret; +} + +void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output) { + furi_assert(context); + WSProtocolDecoderAcurite_592TXR* instance = context; + furi_string_printf( + output, + "%s %dbit\r\n" + "Key:0x%lX%08lX\r\n" + "Sn:0x%lX Ch:%d Bat:%d\r\n" + "Temp:%d.%d C Hum:%d%%", + instance->generic.protocol_name, + instance->generic.data_count_bit, + (uint32_t)(instance->generic.data >> 32), + (uint32_t)(instance->generic.data), + instance->generic.id, + instance->generic.channel, + instance->generic.battery_low, + (int16_t)instance->generic.temp, + abs(((int16_t)(instance->generic.temp * 10) - (((int16_t)instance->generic.temp) * 10))), + instance->generic.humidity); +} diff --git a/applications/plugins/weather_station/protocols/acurite_592txr.h b/applications/plugins/weather_station/protocols/acurite_592txr.h new file mode 100644 index 000000000..ac0371d89 --- /dev/null +++ b/applications/plugins/weather_station/protocols/acurite_592txr.h @@ -0,0 +1,79 @@ +#pragma once + +#include + +#include +#include +#include +#include "ws_generic.h" +#include + +#define WS_PROTOCOL_ACURITE_592TXR_NAME "Acurite 592TXR" + +typedef struct WSProtocolDecoderAcurite_592TXR WSProtocolDecoderAcurite_592TXR; +typedef struct WSProtocolEncoderAcurite_592TXR WSProtocolEncoderAcurite_592TXR; + +extern const SubGhzProtocolDecoder ws_protocol_acurite_592txr_decoder; +extern const SubGhzProtocolEncoder ws_protocol_acurite_592txr_encoder; +extern const SubGhzProtocol ws_protocol_acurite_592txr; + +/** + * Allocate WSProtocolDecoderAcurite_592TXR. + * @param environment Pointer to a SubGhzEnvironment instance + * @return WSProtocolDecoderAcurite_592TXR* pointer to a WSProtocolDecoderAcurite_592TXR instance + */ +void* ws_protocol_decoder_acurite_592txr_alloc(SubGhzEnvironment* environment); + +/** + * Free WSProtocolDecoderAcurite_592TXR. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + */ +void ws_protocol_decoder_acurite_592txr_free(void* context); + +/** + * Reset decoder WSProtocolDecoderAcurite_592TXR. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + */ +void ws_protocol_decoder_acurite_592txr_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void ws_protocol_decoder_acurite_592txr_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + * @return hash Hash sum + */ +uint8_t ws_protocol_decoder_acurite_592txr_get_hash_data(void* context); + +/** + * Serialize data WSProtocolDecoderAcurite_592TXR. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + * @param flipper_format Pointer to a FlipperFormat instance + * @param preset The modulation on which the signal was received, SubGhzRadioPreset + * @return true On success + */ +bool ws_protocol_decoder_acurite_592txr_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data WSProtocolDecoderAcurite_592TXR. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool ws_protocol_decoder_acurite_592txr_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a WSProtocolDecoderAcurite_592TXR instance + * @param output Resulting text + */ +void ws_protocol_decoder_acurite_592txr_get_string(void* context, FuriString* output); diff --git a/applications/plugins/weather_station/protocols/protocol_items.c b/applications/plugins/weather_station/protocols/protocol_items.c index 0740691a2..3ec9e995a 100644 --- a/applications/plugins/weather_station/protocols/protocol_items.c +++ b/applications/plugins/weather_station/protocols/protocol_items.c @@ -8,6 +8,7 @@ const SubGhzProtocol* weather_station_protocol_registry_items[] = { &ws_protocol_acurite_606tx, &ws_protocol_lacrosse_tx141thbv2, &ws_protocol_oregon2, + &ws_protocol_acurite_592txr, }; const SubGhzProtocolRegistry weather_station_protocol_registry = { diff --git a/applications/plugins/weather_station/protocols/protocol_items.h b/applications/plugins/weather_station/protocols/protocol_items.h index edc078cd6..8f3eb53d7 100644 --- a/applications/plugins/weather_station/protocols/protocol_items.h +++ b/applications/plugins/weather_station/protocols/protocol_items.h @@ -8,5 +8,6 @@ #include "acurite_606tx.h" #include "lacrosse_tx141thbv2.h" #include "oregon2.h" +#include "acurite_592txr.h" extern const SubGhzProtocolRegistry weather_station_protocol_registry; diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index dbb0da633..2d94626f7 100644 --- a/firmware/targets/f7/api_symbols.csv +++ b/firmware/targets/f7/api_symbols.csv @@ -2323,6 +2323,7 @@ Function,-,subghz_keystore_raw_encrypted_save,_Bool,"const char*, const char*, u Function,-,subghz_keystore_raw_get_data,_Bool,"const char*, size_t, uint8_t*, size_t" Function,-,subghz_keystore_save,_Bool,"SubGhzKeystore*, const char*, uint8_t*" Function,+,subghz_protocol_blocks_add_bit,void,"SubGhzBlockDecoder*, uint8_t" +Function,+,subghz_protocol_blocks_add_bytes,uint8_t,"const uint8_t[], unsigned" Function,+,subghz_protocol_blocks_crc16,uint16_t,"const uint8_t[], unsigned, uint16_t, uint16_t" Function,+,subghz_protocol_blocks_crc16lsb,uint16_t,"const uint8_t[], unsigned, uint16_t, uint16_t" Function,+,subghz_protocol_blocks_crc4,uint8_t,"const uint8_t[], unsigned, uint8_t, uint8_t" @@ -2336,8 +2337,11 @@ Function,+,subghz_protocol_blocks_get_upload,size_t,"uint8_t[], size_t, LevelDur Function,+,subghz_protocol_blocks_lfsr_digest16,uint16_t,"const uint8_t[], unsigned, uint16_t, uint16_t" Function,+,subghz_protocol_blocks_lfsr_digest8,uint8_t,"const uint8_t[], unsigned, uint8_t, uint8_t" Function,+,subghz_protocol_blocks_lfsr_digest8_reflect,uint8_t,"const uint8_t[], int, uint8_t, uint8_t" +Function,+,subghz_protocol_blocks_parity8,int,uint8_t +Function,+,subghz_protocol_blocks_parity_bytes,int,"const uint8_t[], unsigned" Function,+,subghz_protocol_blocks_reverse_key,uint64_t,"uint64_t, uint8_t" Function,+,subghz_protocol_blocks_set_bit_array,void,"_Bool, uint8_t[], size_t, size_t" +Function,+,subghz_protocol_blocks_xor_bytes,uint8_t,"const uint8_t[], unsigned" Function,-,subghz_protocol_decoder_base_deserialize,_Bool,"SubGhzProtocolDecoderBase*, FlipperFormat*" Function,+,subghz_protocol_decoder_base_get_hash_data,uint8_t,SubGhzProtocolDecoderBase* Function,+,subghz_protocol_decoder_base_get_string,_Bool,"SubGhzProtocolDecoderBase*, FuriString*" diff --git a/lib/subghz/blocks/math.c b/lib/subghz/blocks/math.c index 588d4effc..c995f363d 100644 --- a/lib/subghz/blocks/math.c +++ b/lib/subghz/blocks/math.c @@ -216,4 +216,34 @@ uint16_t subghz_protocol_blocks_lfsr_digest16( } } return sum; +} + +uint8_t subghz_protocol_blocks_add_bytes(uint8_t const message[], unsigned num_bytes) { + int result = 0; + for(unsigned i = 0; i < num_bytes; ++i) { + result += message[i]; + } + return (uint8_t)result; +} + +int subghz_protocol_blocks_parity8(uint8_t byte) { + byte ^= byte >> 4; + byte &= 0xf; + return (0x6996 >> byte) & 1; +} + +int subghz_protocol_blocks_parity_bytes(uint8_t const message[], unsigned num_bytes) { + int result = 0; + for(unsigned i = 0; i < num_bytes; ++i) { + result ^= subghz_protocol_blocks_parity8(message[i]); + } + return result; +} + +uint8_t subghz_protocol_blocks_xor_bytes(uint8_t const message[], unsigned num_bytes) { + uint8_t result = 0; + for(unsigned i = 0; i < num_bytes; ++i) { + result ^= message[i]; + } + return result; } \ No newline at end of file diff --git a/lib/subghz/blocks/math.h b/lib/subghz/blocks/math.h index 275889484..c5995e3d5 100644 --- a/lib/subghz/blocks/math.h +++ b/lib/subghz/blocks/math.h @@ -161,6 +161,37 @@ uint16_t subghz_protocol_blocks_lfsr_digest16( uint16_t gen, uint16_t key); +/** + * Compute Addition of a number of bytes. + * @param message bytes of message data + * @param num_bytes number of bytes to sum + * @return summation value + **/ +uint8_t subghz_protocol_blocks_add_bytes(uint8_t const message[], unsigned num_bytes); + +/** + * Compute bit parity of a single byte (8 bits). + * @param byte single byte to check + * @return 1 odd parity, 0 even parity + **/ +int subghz_protocol_blocks_parity8(uint8_t byte); + +/** + * Compute bit parity of a number of bytes. + * @param message bytes of message data + * @param num_bytes number of bytes to sum + * @return 1 odd parity, 0 even parity + **/ +int subghz_protocol_blocks_parity_bytes(uint8_t const message[], unsigned num_bytes); + +/** + * Compute XOR (byte-wide parity) of a number of bytes. + * @param message bytes of message data + * @param num_bytes number of bytes to sum + * @return summation value, per bit-position 1 odd parity, 0 even parity + **/ +uint8_t subghz_protocol_blocks_xor_bytes(uint8_t const message[], unsigned num_bytes); + #ifdef __cplusplus } #endif From 5ed9ca838a0b36c78871a054ca9abc35b8d7a439 Mon Sep 17 00:00:00 2001 From: gornekich Date: Mon, 24 Oct 2022 18:48:09 +0400 Subject: [PATCH 06/10] bt hid: reset cursor for ble tiktok controller --- .../plugins/bt_hid_app/views/bt_hid_tiktok.c | 179 ++++++++++-------- 1 file changed, 101 insertions(+), 78 deletions(-) diff --git a/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c index d39034069..f751c53d2 100644 --- a/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c +++ b/applications/plugins/bt_hid_app/views/bt_hid_tiktok.c @@ -17,6 +17,7 @@ typedef struct { bool down_pressed; bool ok_pressed; bool connected; + bool is_cursor_set; } BtHidTikTokModel; static void bt_hid_tiktok_draw_callback(Canvas* canvas, void* context) { @@ -88,48 +89,48 @@ static void bt_hid_tiktok_draw_callback(Canvas* canvas, void* context) { elements_multiline_text_aligned(canvas, 13, 62, AlignLeft, AlignBottom, "Hold to exit"); } -static void bt_hid_tiktok_process_press(BtHidTikTok* bt_hid_tiktok, InputEvent* event) { - with_view_model( - bt_hid_tiktok->view, - BtHidTikTokModel * model, - { - if(event->key == InputKeyUp) { - model->up_pressed = true; - } else if(event->key == InputKeyDown) { - model->down_pressed = true; - } else if(event->key == InputKeyLeft) { - model->left_pressed = true; - furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_DECREMENT); - } else if(event->key == InputKeyRight) { - model->right_pressed = true; - furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT); - } else if(event->key == InputKeyOk) { - model->ok_pressed = true; - } - }, - true); +static void bt_hid_tiktok_reset_cursor() { + // Set cursor to the phone's left up corner + // Delays to guarantee one packet per connection interval + for(size_t i = 0; i < 8; i++) { + furi_hal_bt_hid_mouse_move(-127, -127); + furi_delay_ms(50); + } + // Move cursor from the corner + furi_hal_bt_hid_mouse_move(20, 120); + furi_delay_ms(50); } -static void bt_hid_tiktok_process_release(BtHidTikTok* bt_hid_tiktok, InputEvent* event) { - with_view_model( - bt_hid_tiktok->view, - BtHidTikTokModel * model, - { - if(event->key == InputKeyUp) { - model->up_pressed = false; - } else if(event->key == InputKeyDown) { - model->down_pressed = false; - } else if(event->key == InputKeyLeft) { - model->left_pressed = false; - furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_DECREMENT); - } else if(event->key == InputKeyRight) { - model->right_pressed = false; - furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT); - } else if(event->key == InputKeyOk) { - model->ok_pressed = false; - } - }, - true); +static void bt_hid_tiktok_process_press(BtHidTikTokModel* model, InputEvent* event) { + if(event->key == InputKeyUp) { + model->up_pressed = true; + } else if(event->key == InputKeyDown) { + model->down_pressed = true; + } else if(event->key == InputKeyLeft) { + model->left_pressed = true; + furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = true; + furi_hal_bt_hid_consumer_key_press(HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = true; + } +} + +static void bt_hid_tiktok_process_release(BtHidTikTokModel* model, InputEvent* event) { + if(event->key == InputKeyUp) { + model->up_pressed = false; + } else if(event->key == InputKeyDown) { + model->down_pressed = false; + } else if(event->key == InputKeyLeft) { + model->left_pressed = false; + furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_DECREMENT); + } else if(event->key == InputKeyRight) { + model->right_pressed = false; + furi_hal_bt_hid_consumer_key_release(HID_CONSUMER_VOLUME_INCREMENT); + } else if(event->key == InputKeyOk) { + model->ok_pressed = false; + } } static bool bt_hid_tiktok_input_callback(InputEvent* event, void* context) { @@ -137,43 +138,59 @@ static bool bt_hid_tiktok_input_callback(InputEvent* event, void* context) { BtHidTikTok* bt_hid_tiktok = context; bool consumed = false; - if(event->type == InputTypePress) { - bt_hid_tiktok_process_press(bt_hid_tiktok, event); - consumed = true; - } else if(event->type == InputTypeRelease) { - bt_hid_tiktok_process_release(bt_hid_tiktok, event); - consumed = true; - } else if(event->type == InputTypeShort) { - if(event->key == InputKeyOk) { - furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); - furi_delay_ms(50); - furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); - furi_delay_ms(50); - furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); - furi_delay_ms(50); - furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); - consumed = true; - } else if(event->key == InputKeyUp) { - // Emulate up swipe - furi_hal_bt_hid_mouse_scroll(-6); - furi_hal_bt_hid_mouse_scroll(-12); - furi_hal_bt_hid_mouse_scroll(-19); - furi_hal_bt_hid_mouse_scroll(-12); - furi_hal_bt_hid_mouse_scroll(-6); - consumed = true; - } else if(event->key == InputKeyDown) { - // Emulate down swipe - furi_hal_bt_hid_mouse_scroll(6); - furi_hal_bt_hid_mouse_scroll(12); - furi_hal_bt_hid_mouse_scroll(19); - furi_hal_bt_hid_mouse_scroll(12); - furi_hal_bt_hid_mouse_scroll(6); - consumed = true; - } else if(event->key == InputKeyBack) { - furi_hal_bt_hid_consumer_key_release_all(); - consumed = true; - } - } + with_view_model( + bt_hid_tiktok->view, + BtHidTikTokModel * model, + { + if(event->type == InputTypePress) { + bt_hid_tiktok_process_press(model, event); + if(model->connected && !model->is_cursor_set) { + bt_hid_tiktok_reset_cursor(); + model->is_cursor_set = true; + } + consumed = true; + } else if(event->type == InputTypeRelease) { + bt_hid_tiktok_process_release(model, event); + consumed = true; + } else if(event->type == InputTypeShort) { + if(event->key == InputKeyOk) { + furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_press(HID_MOUSE_BTN_LEFT); + furi_delay_ms(50); + furi_hal_bt_hid_mouse_release(HID_MOUSE_BTN_LEFT); + consumed = true; + } else if(event->key == InputKeyUp) { + // Emulate up swipe + furi_hal_bt_hid_mouse_scroll(-6); + furi_hal_bt_hid_mouse_scroll(-12); + furi_hal_bt_hid_mouse_scroll(-19); + furi_hal_bt_hid_mouse_scroll(-12); + furi_hal_bt_hid_mouse_scroll(-6); + consumed = true; + } else if(event->key == InputKeyDown) { + // Emulate down swipe + furi_hal_bt_hid_mouse_scroll(6); + furi_hal_bt_hid_mouse_scroll(12); + furi_hal_bt_hid_mouse_scroll(19); + furi_hal_bt_hid_mouse_scroll(12); + furi_hal_bt_hid_mouse_scroll(6); + consumed = true; + } else if(event->key == InputKeyBack) { + furi_hal_bt_hid_consumer_key_release_all(); + consumed = true; + } + } else if(event->type == InputTypeLong) { + if(event->key == InputKeyBack) { + furi_hal_bt_hid_consumer_key_release_all(); + model->is_cursor_set = false; + consumed = false; + } + } + }, + true); return consumed; } @@ -203,5 +220,11 @@ View* bt_hid_tiktok_get_view(BtHidTikTok* bt_hid_tiktok) { void bt_hid_tiktok_set_connected_status(BtHidTikTok* bt_hid_tiktok, bool connected) { furi_assert(bt_hid_tiktok); with_view_model( - bt_hid_tiktok->view, BtHidTikTokModel * model, { model->connected = connected; }, true); + bt_hid_tiktok->view, + BtHidTikTokModel * model, + { + model->connected = connected; + model->is_cursor_set = false; + }, + true); } From c19a8fd6367990dc7edc4a8725ca9b4d10179e6a Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 21:28:04 +0300 Subject: [PATCH 07/10] halloween theme :) --- .../external/L1_Halloween_128x64/frame_0.png | Bin 0 -> 1597 bytes .../external/L1_Halloween_128x64/frame_1.png | Bin 0 -> 1592 bytes .../external/L1_Halloween_128x64/frame_2.png | Bin 0 -> 1605 bytes .../external/L1_Halloween_128x64/frame_3.png | Bin 0 -> 1594 bytes .../external/L1_Halloween_128x64/meta.txt | 14 ++++++++++++++ assets/dolphin/external/manifest.txt | 7 +++++++ assets/icons/StatusBar/Background_128x11.png | Bin 410 -> 447 bytes 7 files changed, 21 insertions(+) create mode 100644 assets/dolphin/external/L1_Halloween_128x64/frame_0.png create mode 100644 assets/dolphin/external/L1_Halloween_128x64/frame_1.png create mode 100644 assets/dolphin/external/L1_Halloween_128x64/frame_2.png create mode 100644 assets/dolphin/external/L1_Halloween_128x64/frame_3.png create mode 100644 assets/dolphin/external/L1_Halloween_128x64/meta.txt diff --git a/assets/dolphin/external/L1_Halloween_128x64/frame_0.png b/assets/dolphin/external/L1_Halloween_128x64/frame_0.png new file mode 100644 index 0000000000000000000000000000000000000000..f69a43f5e75a4efee946984b5f551d2af692bf72 GIT binary patch literal 1597 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 literal 0 HcmV?d00001 diff --git a/assets/dolphin/external/L1_Halloween_128x64/meta.txt b/assets/dolphin/external/L1_Halloween_128x64/meta.txt new file mode 100644 index 000000000..9762d4caa --- /dev/null +++ b/assets/dolphin/external/L1_Halloween_128x64/meta.txt @@ -0,0 +1,14 @@ +Filetype: Flipper Animation +Version: 1 + +Width: 128 +Height: 64 +Passive frames: 4 +Active frames: 0 +Frames order: 0 1 2 3 +Active cycles: 0 +Frame rate: 3 +Duration: 3600 +Active cooldown: 0 + +Bubble slots: 0 diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt index ecf7c1806..60b8fc25f 100644 --- a/assets/dolphin/external/manifest.txt +++ b/assets/dolphin/external/manifest.txt @@ -15,6 +15,13 @@ Min level: 1 Max level: 1 Weight: 3 +Name: L1_Halloween_128x64 +Min butthurt: 0 +Max butthurt: 13 +Min level: 1 +Max level: 3 +Weight: 8 + Name: L1_Sleep_128x64 Min butthurt: 0 Max butthurt: 10 diff --git a/assets/icons/StatusBar/Background_128x11.png b/assets/icons/StatusBar/Background_128x11.png index 78ef029ae737fe82080bd709545aff7ccdae948e..e43b32d16f04675311263d032e5d4018223febb6 100644 GIT binary patch delta 410 zcmbQmyq|f31SbbG0|P_D^wLKY4W;Y#85my0GcZ_9XJ8O7s1e=82$U-d@Ck7R(m?Qk zZE~|A!~g&PzaLpz{ojD0nIUz_YzBsZ|65z8SXn&-DtLbM+?>{yY|UuH=%v|)DNFx% z_uLB(>RGyUX;4tmlqpmGO_?%z%D?~rm;MLp0%8V+T2G*XR#qBJf&Urm|2r`-CLd#H zY5RYV;rN3rbD*7SB|(0{AUg>Ii+aD|RUo1|K zkMC2O<9>dBwdm#Zf9vX|Pt;!> X#+y>O#s3s2bUj_!{9M*KB{Ts53`57q delta 372 zcmdnbJd1gPgd`I)0|Ub;^;~Bl#ggvm>&U>cv7h@-BI`s&>3RbOhF1v;3|2E37{m+a z>_V@sW8a-VcLnJPT1~~E^P~d1jayNa^|HRIFrW60yr@Gu>&}-W^MJYtB zAT+Z6v_R8C*5!_~U#+%~>#RI`?Zh$;{j%1sd-qqd*0%7hJfoBHOSf@SSMj~~6YY;D zq&+w;&G5)<-`RzI`L)@x8onh{n|&LEWVUS8RxPn`a>}_=b*kk#s;cm>5Dd_?7)q0cv3IboFyt=akR{0J)cb{{R30 From c2bf81dd6494db7ec393bc367eb13e8059f5ed72 Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 21:28:39 +0300 Subject: [PATCH 08/10] forgot to add this --- .../dolphin/L1_Halloween_128x64/frame_0.bm | Bin 0 -> 744 bytes .../dolphin/L1_Halloween_128x64/frame_1.bm | Bin 0 -> 742 bytes .../dolphin/L1_Halloween_128x64/frame_2.bm | Bin 0 -> 744 bytes .../dolphin/L1_Halloween_128x64/frame_3.bm | Bin 0 -> 747 bytes .../dolphin/L1_Halloween_128x64/meta.txt | 14 ++++++++++++++ assets/resources/dolphin/manifest.txt | 7 +++++++ 6 files changed, 21 insertions(+) create mode 100644 assets/resources/dolphin/L1_Halloween_128x64/frame_0.bm create mode 100644 assets/resources/dolphin/L1_Halloween_128x64/frame_1.bm create mode 100644 assets/resources/dolphin/L1_Halloween_128x64/frame_2.bm create mode 100644 assets/resources/dolphin/L1_Halloween_128x64/frame_3.bm create mode 100644 assets/resources/dolphin/L1_Halloween_128x64/meta.txt diff --git a/assets/resources/dolphin/L1_Halloween_128x64/frame_0.bm b/assets/resources/dolphin/L1_Halloween_128x64/frame_0.bm new file mode 100644 index 0000000000000000000000000000000000000000..2d7dbac041c3715f2983d534de6123f4fb84bb1a GIT binary patch literal 744 zcmVxc?*Y5BL1KGYAG|0q^=nU=Yvo zoPVGA9Rgzj#YjKhx@bILJ^=uL27wTSV7MRu{Q3cmfkrF{(}WYqZa8=hA_WG(6hr_p zb9jf#_W+1ML8Cf28a#9#-~9dw;J^Zh=?^=M0bVo@V1QAhK)75z5Okq4$3a2u|Ih*9e{t)f)5z@2t(;~T@TzIF<^Ozjsb#%!@RKg1Y{m@ z;CaA&Q91+|3L(MZEkqu0pXIy|Ny7n|z+j)u{0^i9VlyAvf~LgT@GQ9Q=|U zIDthY@PT?mI2iu~g8z8PL=vJ75_rHOn+yH|LGQSONFGS?ibOo{2p|6D4Ip5F3J(P2 zNFZ>)e88agsRR;W4;Vl+XaMmk3$Sm}2uB0=JA_NH6cBjwBjd5P1b811ONYs5=c%t=nCMl5I}jFOT!_>Kve~xR*1Y| z697QQXPAf!l(+#wCyWvqfS>TE;PD;`>|jzuc|f=nALP#j4;VWvq6qPV3Pyo=m~VmO z4<3#JV6PZN3c-LOjR;yX@{w9F9vOrX9&{HN&tD~1z(i;`j}8JMCcwz>6QjuBEkN3SA)+0^!f1q4m1gzKmV9z4S!tH!P#5ct4;S@3yepo>9(4@5p+|DXTk|DfcduhOpv a%lPmR0N^|D*tk5k!SV+m{sF(RNQ3Mz*+C@$ literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Halloween_128x64/frame_1.bm b/assets/resources/dolphin/L1_Halloween_128x64/frame_1.bm new file mode 100644 index 0000000000000000000000000000000000000000..495c3cc8a1be38074df2d0c97a05ffefff8a9cc8 GIT binary patch literal 742 zcmV%6hMr#2gUTGTIO=3xf)5z@2t(;~@IZdx@rwh@Ja7yYCLQHg3}ha0 z;CaA&Q91+|3L(MZEkqu0pXIy|F!bSo%-}Fj=6(kbzoLkoAoQY7r{Bm-e6nEi0+xPB z4xB)ukO)A%A(#vofL8K2Pc||rK_yiCCa|VzwK!pc_ zL?rMyU_M|_enf%^Fb9kv8Z-cSl!e$fsRSc|`<=oi*a`?deG5^6--6};obe^N3r?tB;hFA}I2yxd=+ALFe8AodyL?#6(M? z87O#sSVe(=&^ePc=!3@LFyt~42SES-;slb0Py^z)ECdi9W|A9@dIG2|0<=Zr2$%u~ z!y&~$T&2JY2|Qqrv7g3gn1Ud{*JA>b8_EU1pzx>o0C>UKWe`V<5K=S`V5i773jhEB literal 0 HcmV?d00001 diff --git a/assets/resources/dolphin/L1_Halloween_128x64/frame_2.bm b/assets/resources/dolphin/L1_Halloween_128x64/frame_2.bm new file mode 100644 index 0000000000000000000000000000000000000000..91f2de20ec8b2c2cfe1c9a2a22f64d7874564ffa GIT binary patch literal 744 zcmVuh(Lnl@W0?c<1xSk#}$B}$YL-EXW~Bq z|Nr0=35+8J0QdbOpz(lz>XK=OuA1LC+P5QEAH4PXrvwJPHT$XMzWaBvB&};6U&a z3kCx5F#ZF@iY?KYU_3Mkz&v3S3J|noLAJbqd5d2=9^1$foN!XF?1&;RlN$Z}9dAixKr03YMP aKm&lU`!JaJGDf6^-e zhJPXO5BL59K$yZXQV;iTnhzKcz#t$2phOAd!2kc}&7%CL$LJj0696SaQ0)g-g z=LbiKe7|rAh6ENj6?*7Dzxn(Vz?Lr&ykQLTpnC)Yd>I6CIm9T7F!U52-~9kF0Z73h z5J^BhlcQ+=!oZ{878E!hafs?{7{opxApi~2!2$b&)1clUd0?S1?oGkphT3p+C!d_+j9&2b##>pUnIY9lr#aIKZPspHIJ#ocnOg;sq@H zk{vjKMFnRd9~J`z;E-SM83gE(NC+@k2Lj)KkbBz#3KU5L$`P>tz#xD7m?(fE5-22c zAt!;u0rMP$awHH*fIMLYp#X_=r;rO&f)T*|&fya51cV+wNPGBi$3bq4=ZP)AP(b7I zkATM14=aRvi!9(!z~eDSm7z#n2z?rv;KQqzl$b08AC*nWVpYTdF7yHf1R4wqors9Q zOeKJahsB0i7!3oNGk~B<;V|SX4Ma2#|NaCIC}jXXAY#Bl0p$b)5ZrUaW6&o=UNL|{ zcw{)J4*=jnK_`uZfq;$gxEjC`a^Verr+0P%!OC@nFblm-!3z(iy?PY67)GCTz8AXytw zJYqN?c*G>o9vz12h8u@hzz-Y`hXW9_z+h4DR6oJ5)p$Je4-cOX4;T|TfB#zjR;u$F z2aC`D@Nu9~hUn_`KmkLJFn&Mz2LcITSB+deA@P9xv*7aPK^B7m9*BIu|3Cl7{~^gg dPP`v4 Date: Mon, 24 Oct 2022 21:30:40 +0300 Subject: [PATCH 09/10] fix fap_dist --- .vscode/example/tasks.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.vscode/example/tasks.json b/.vscode/example/tasks.json index 3946d05cc..9baaf97b4 100644 --- a/.vscode/example/tasks.json +++ b/.vscode/example/tasks.json @@ -109,13 +109,13 @@ "label": "[Debug] Build FAPs", "group": "build", "type": "shell", - "command": "./fbt plugin_dist" + "command": "./fbt fap_dist" }, { "label": "[Release] Build FAPs", "group": "build", "type": "shell", - "command": "./fbt COMPACT=1 DEBUG=0 plugin_dist" + "command": "./fbt COMPACT=1 DEBUG=0 fap_dist" }, { "label": "[Debug] Launch App on Flipper", From fd127cee8c2ba5f584ebf75049f093ddbebb6aee Mon Sep 17 00:00:00 2001 From: MX <10697207+xMasterX@users.noreply.github.com> Date: Mon, 24 Oct 2022 22:01:18 +0300 Subject: [PATCH 10/10] update changelog and readme --- CHANGELOG.md | 13 ++++++++++--- ReadMe.md | 1 + 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d11803d41..49ec6eef1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,14 @@ ### New changes -* API version changed to 5.1 due to OFW updates, Extra apps pack update is coming, download it from link below tomorrow or get it from our discord -* OFW: SubGHz: Move Oregon2 protocol to Weather Station plugin -* OFW: Gui: update statusbar attention icon and better crash handling (breaking change, API version increased because of that) +* API version changed to 6.1 due to OFW updates, Extra apps pack update is already done! Download it from link below +* Halloween theme + animation :) (by @Svaarich) (will be disabled on first days of November) +* Plugins: Add new plugin - HC-SR04 Distance sensor [(original by Sanqui)](https://github.com/Sanqui/flipperzero-firmware/tree/hc_sr04) - Ported and modified by @xMasterX - How to connect -> (5V -> VCC) / (GND -> GND) / (13|TX -> Trig) / (14|RX -> Echo) +* Plugins: Snake -> Allow food to spawn anywhere (by @TQMatvey | PR #130) +* Plugins: Use clear power in temp sensor plugin +* Plugins: WS -> add protocol Acurite 592TXR (OFW PR 1916 by Skorpionm) +* Plugins: WS -> fix oregon2 flags, and protocol type +* Fixed wrong fbt arguments in tasks.json in vscode example config -> plugin_dist -> fap_dist +* OFW PR: TikTok: reset cursor after enter and reconnect (OFW PR 1921 by gornekich) +* OFW: Furi: smaller crash routine (breaking change, API version increased because of that) #### [🎲 Download extra apps pack](https://download-directory.github.io/?url=https://github.com/UberGuidoZ/Flipper/tree/main/Applications/Unleashed%20(and%20RogueMaster)) diff --git a/ReadMe.md b/ReadMe.md index 758891bc0..f1b3fbece 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -91,6 +91,7 @@ Also check changelog in releases for latest updates! - GPS [(By ezod)](https://github.com/ezod/flipperzero-gps) works with module `NMEA 0183` via UART (13TX, 14RX, GND pins on Flipper) - i2c Tools [(By NaejEL)](https://github.com/NaejEL/flipperzero-i2ctools) - C0 -> SCL / C1 -> SDA / GND -> GND | 3v3 logic levels only! - Temperature Sensor Plugin - HTU21D / SI7021 [(By Mywk)](https://github.com/Mywk/FlipperTemperatureSensor) - [How to Connect](https://github.com/DarkFlippers/unleashed-firmware/blob/dev/applications/plugins/temperature_sensor/Readme.md) +- HC-SR04 Distance sensor [(original by Sanqui)](https://github.com/Sanqui/flipperzero-firmware/tree/hc_sr04) - Ported and modified by @xMasterX - How to connect -> (5V -> VCC) / (GND -> GND) / (13|TX -> Trig) / (14|RX -> Echo) Games: - DOOM (fixed) [(By p4nic4ttack)](https://github.com/p4nic4ttack/doom-flipper-zero/)