diff --git a/CHANGELOG.md b/CHANGELOG.md index a17ac609a..957258907 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ ### New changes -* Fix crash when furi_halt is called (was found when you try to power off flipper with usb cable connected) -* Fix bug when NFC keys was removed during scan +* Plugins: New AM2320 Sensor plugin (@xMasterX) +* Plugins -> PR: Added DHT Temperature sensor Monitor (by @quen0n | PR #147) [(plugin repo)](https://github.com/quen0n/FipperZero-DHT-Monitor) +* Plugins -> PR: USB Keyboard - added additional row for function keys (by @huuck | PR #145) +* Plugins -> PR: Added Morse Code plugin (by @wh00hw | PR #144) [(plugin repo)](https://github.com/wh00hw/MorseCodeFAP) +* Plugins -> PR: FlappyBird - Fix animation (by @msvsergey | PR #148) +* Plugins: Added Game15 [(by x27)](https://github.com/x27/flipperzero-game15) +* Plugins: Update and fix TOTP +* Plugins: Update Wifi Marauder +* Plugins: fix proper deinit of gpio and spi bus in NRF24 driver +* Snake game: Fix food spawn bug +* Replaced furi check hotfix with proper fix from OFW +* Disable halloween theme +* SubGHz: BFT Mitto fix, other small fixes +* OFW: WS -> add protocol Ambient_Weather +* OFW: Handle storage full error +* OFW: fbt fixes for mfbt pt2 +* OFW: Gui: refactor buttons remapping +* OFW: Furi: raise bkpt only if debug session initiated, add debug support for release builds +* OFW PR: BadUSB scrolllock typo fix (OFW PR 1968 by nminaylov) #### [🎲 Download latest extra apps pack](https://download-directory.github.io/?url=https://github.com/xMasterX/unleashed-extra-pack/tree/main/apps) diff --git a/SConstruct b/SConstruct index 448df9715..13a698c81 100644 --- a/SConstruct +++ b/SConstruct @@ -33,10 +33,6 @@ coreenv = SConscript( ) SConscript("site_scons/cc.scons", exports={"ENV": coreenv}) -# Store root dir in environment for certain tools -coreenv["ROOT_DIR"] = Dir(".") - - # Create a separate "dist" environment and add construction envs to it distenv = coreenv.Clone( tools=[ @@ -233,13 +229,13 @@ distenv.PhonyTarget( # Linter distenv.PhonyTarget( "lint", - "${PYTHON3} scripts/lint.py check ${LINT_SOURCES}", + "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py check ${LINT_SOURCES}", LINT_SOURCES=firmware_env["LINT_SOURCES"], ) distenv.PhonyTarget( "format", - "${PYTHON3} scripts/lint.py format ${LINT_SOURCES}", + "${PYTHON3} ${FBT_SCRIPT_DIR}/lint.py format ${LINT_SOURCES}", LINT_SOURCES=firmware_env["LINT_SOURCES"], ) @@ -280,7 +276,7 @@ distenv.PhonyTarget( ) # Start Flipper CLI via PySerial's miniterm -distenv.PhonyTarget("cli", "${PYTHON3} scripts/serial_cli.py") +distenv.PhonyTarget("cli", "${PYTHON3} ${FBT_SCRIPT_DIR}/serial_cli.py") # Find blackmagic probe diff --git a/applications/main/bad_usb/bad_usb_script.c b/applications/main/bad_usb/bad_usb_script.c index 93b4026f5..f94b42ed5 100644 --- a/applications/main/bad_usb/bad_usb_script.c +++ b/applications/main/bad_usb/bad_usb_script.c @@ -86,7 +86,7 @@ static const DuckyKey ducky_keys[] = { {"PAGEUP", HID_KEYBOARD_PAGE_UP}, {"PAGEDOWN", HID_KEYBOARD_PAGE_DOWN}, {"PRINTSCREEN", HID_KEYBOARD_PRINT_SCREEN}, - {"SCROLLOCK", HID_KEYBOARD_SCROLL_LOCK}, + {"SCROLLLOCK", HID_KEYBOARD_SCROLL_LOCK}, {"SPACE", HID_KEYBOARD_SPACEBAR}, {"TAB", HID_KEYBOARD_TAB}, {"MENU", HID_KEYBOARD_APPLICATION}, diff --git a/applications/main/subghz/scenes/subghz_scene_set_seed_bft.c b/applications/main/subghz/scenes/subghz_scene_set_seed_bft.c index dcb7e6850..1d6f9d70b 100644 --- a/applications/main/subghz/scenes/subghz_scene_set_seed_bft.c +++ b/applications/main/subghz/scenes/subghz_scene_set_seed_bft.c @@ -67,6 +67,8 @@ bool subghz_scene_set_seed_bft_on_event(void* context, SceneManagerEvent event) flipper_format_write_hex( subghz->txrx->fff_data, "Seed", seed_data, sizeof(uint32_t)); + flipper_format_write_string_cstr(subghz->txrx->fff_data, "Manufacture", "BFT"); + generated_protocol = true; } else { generated_protocol = false; diff --git a/applications/plugins/am2320_temp_sensor/application.fam b/applications/plugins/am2320_temp_sensor/application.fam new file mode 100644 index 000000000..9a17539dd --- /dev/null +++ b/applications/plugins/am2320_temp_sensor/application.fam @@ -0,0 +1,14 @@ +App( + appid="am2320_temp_sensor", + name="[AM2320] Temp. Sensor", + apptype=FlipperAppType.EXTERNAL, + entry_point="am_temperature_sensor_app", + cdefines=["APP_AM_TEMPERATURE_SENSOR"], + requires=[ + "gui", + ], + stack_size=2 * 1024, + order=90, + fap_icon="temperature_sensor.png", + fap_category="GPIO", +) diff --git a/applications/plugins/am2320_temp_sensor/temperature_sensor.c b/applications/plugins/am2320_temp_sensor/temperature_sensor.c new file mode 100644 index 000000000..212014e22 --- /dev/null +++ b/applications/plugins/am2320_temp_sensor/temperature_sensor.c @@ -0,0 +1,336 @@ +/* Flipper Plugin to read the values from a AM2320/AM2321 Sensor */ +/* Created by @xMasterX, original app (was used as template) by Mywk - https://github.com/Mywk */ +/* Lib used as reference: https://github.com/Gozem/am2320/blob/master/am2321.c*/ +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#define TS_DEFAULT_VALUE 0xFFFF + +#define AM2320_ADDRESS (0x5C << 1) + +#define DATA_BUFFER_SIZE 8 + +// External I2C BUS +#define I2C_BUS &furi_hal_i2c_handle_external + +typedef enum { + TSSInitializing, + TSSNoSensor, + TSSPendingUpdate, +} TSStatus; + +typedef enum { + TSEventTypeTick, + TSEventTypeInput, +} TSEventType; + +typedef struct { + TSEventType type; + InputEvent input; +} TSEvent; + +extern const NotificationSequence sequence_blink_red_100; +extern const NotificationSequence sequence_blink_blue_100; + +static TSStatus temperature_sensor_current_status = TSSInitializing; + +// Temperature and Humidity data buffers, ready to print +char ts_data_buffer_temperature_c[DATA_BUFFER_SIZE]; +char ts_data_buffer_temperature_f[DATA_BUFFER_SIZE]; +char ts_data_buffer_relative_humidity[DATA_BUFFER_SIZE]; +char ts_data_buffer_absolute_humidity[DATA_BUFFER_SIZE]; + +// CRC16 calculation +static uint16_t get_crc16(const uint8_t* buf, size_t len) { + uint16_t crc = 0xFFFF; + + while(len--) { + crc ^= (uint16_t)*buf++; + for(unsigned i = 0; i < 8; i++) { + if(crc & 0x0001) { + crc >>= 1; + crc ^= 0xA001; + } else { + crc >>= 1; + } + } + } + + return crc; +} +// Combine bytes +static uint16_t combine_bytes(uint8_t msb, uint8_t lsb) { + return ((uint16_t)msb << 8) | (uint16_t)lsb; +} + +// Executes an I2C wake up, sends command and reads result +// true if fetch was successful, false otherwise +static bool temperature_sensor_get_data(uint8_t* buffer, uint8_t size) { + uint32_t timeout = furi_ms_to_ticks(100); + uint8_t cmdbuffer[3] = {0, 0, 0}; + bool ret = false; + + // Aquire I2C bus + furi_hal_i2c_acquire(I2C_BUS); + + // Wake UP AM2320 (sensor goes to sleep to not warm up and affect the humidity sensor) + furi_hal_i2c_is_device_ready(I2C_BUS, (uint8_t)AM2320_ADDRESS, timeout); + // Check if device woken up then we do next stuff + if(furi_hal_i2c_is_device_ready(I2C_BUS, (uint8_t)AM2320_ADDRESS, timeout)) { + // Wait a bit + furi_delay_us(1000); + + // Prepare command: Addr 0x03, start register = 0x00, number of registers to read = 0x04 + cmdbuffer[0] = 0x03; + cmdbuffer[1] = 0x00; + cmdbuffer[2] = 0x04; + + // Transmit command to read registers + ret = furi_hal_i2c_tx(I2C_BUS, (uint8_t)AM2320_ADDRESS, cmdbuffer, 3, timeout); + + // Wait a bit + furi_delay_us(1600); + if(ret) { + /* + * Read out 8 bytes of data + * Byte 0: Should be Modbus function code 0x03 + * Byte 1: Should be number of registers to read (0x04) + * Byte 2: Humidity msb + * Byte 3: Humidity lsb + * Byte 4: Temperature msb + * Byte 5: Temperature lsb + * Byte 6: CRC lsb byte + * Byte 7: CRC msb byte + */ + ret = furi_hal_i2c_rx(I2C_BUS, (uint8_t)AM2320_ADDRESS, buffer, size, timeout); + } + } + // Release i2c bus + furi_hal_i2c_release(I2C_BUS); + + return ret; +} + +// Fetches temperature and humidity from sensor +// Temperature and humidity must be preallocated +// true if fetch was successful, false otherwise +static bool temperature_sensor_fetch_info(double* temperature, double* humidity) { + *humidity = (float)0; + bool ret = false; + + uint8_t buffer[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + + // Fetch data from sensor + ret = temperature_sensor_get_data(buffer, 8); + + // If we got no result + if(!ret) return false; + + if(buffer[0] != 0x03) return false; // must be 0x03 modbus reply + if(buffer[1] != 0x04) return false; // must be 0x04 number of registers reply + + // Check CRC16 sum, if not correct - return false + uint16_t crcdata = get_crc16(buffer, 6); + uint16_t crcread = combine_bytes(buffer[7], buffer[6]); + if(crcdata != crcread) return false; + + // Combine bytes for temp and humidity + uint16_t temp16 = combine_bytes(buffer[4], buffer[5]); + uint16_t humi16 = combine_bytes(buffer[2], buffer[3]); + + /* Temperature resolution is 16Bit, + * temperature highest bit (Bit15) is equal to 1 indicates a + * negative temperature, the temperature highest bit (Bit15) + * is equal to 0 indicates a positive temperature; + * temperature in addition to the most significant bit (Bit14 ~ Bit0) + * indicates the temperature sensor string value. + * Temperature sensor value is a string of 10 times the + * actual temperature value. + */ + if(temp16 & 0x8000) { + temp16 = -(temp16 & 0x7FFF); + } + + // Prepare output data + *temperature = (float)temp16 / 10.0; + *humidity = (float)humi16 / 10.0; + + return true; +} + +// Draw callback + +static void temperature_sensor_draw_callback(Canvas* canvas, void* ctx) { + UNUSED(ctx); + + canvas_clear(canvas); + canvas_set_font(canvas, FontPrimary); + canvas_draw_str(canvas, 2, 10, "AM2320/AM2321 Sensor"); + + canvas_set_font(canvas, FontSecondary); + canvas_draw_str(canvas, 2, 62, "Press back to exit."); + + switch(temperature_sensor_current_status) { + case TSSInitializing: + canvas_draw_str(canvas, 2, 30, "Initializing.."); + break; + case TSSNoSensor: + canvas_draw_str(canvas, 2, 30, "No sensor found!"); + break; + case TSSPendingUpdate: { + canvas_draw_str(canvas, 3, 24, "Temperature"); + canvas_draw_str(canvas, 68, 24, "Humidity"); + + // Draw vertical lines + canvas_draw_line(canvas, 61, 16, 61, 50); + canvas_draw_line(canvas, 62, 16, 62, 50); + + // Draw horizontal line + canvas_draw_line(canvas, 2, 27, 122, 27); + + // Draw temperature and humidity values + canvas_draw_str(canvas, 8, 38, ts_data_buffer_temperature_c); + canvas_draw_str(canvas, 42, 38, "C"); + canvas_draw_str(canvas, 8, 48, ts_data_buffer_temperature_f); + canvas_draw_str(canvas, 42, 48, "F"); + canvas_draw_str(canvas, 68, 38, ts_data_buffer_relative_humidity); + canvas_draw_str(canvas, 100, 38, "%"); + canvas_draw_str(canvas, 68, 48, ts_data_buffer_absolute_humidity); + canvas_draw_str(canvas, 100, 48, "g/m3"); + + } break; + default: + break; + } +} + +// Input callback + +static void temperature_sensor_input_callback(InputEvent* input_event, void* ctx) { + furi_assert(ctx); + FuriMessageQueue* event_queue = ctx; + + TSEvent event = {.type = TSEventTypeInput, .input = *input_event}; + furi_message_queue_put(event_queue, &event, FuriWaitForever); +} + +// Timer callback + +static void temperature_sensor_timer_callback(FuriMessageQueue* event_queue) { + furi_assert(event_queue); + + TSEvent event = {.type = TSEventTypeTick}; + furi_message_queue_put(event_queue, &event, 0); +} + +// App entry point + +int32_t am_temperature_sensor_app(void* p) { + UNUSED(p); + + furi_hal_power_suppress_charge_enter(); + // Declare our variables and assign variables a default value + TSEvent tsEvent; + bool sensorFound = false; + double celsius, fahrenheit, rel_humidity, abs_humidity = TS_DEFAULT_VALUE; + + // Used for absolute humidity calculation + double vapour_pressure = 0; + + FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(TSEvent)); + + // Register callbacks + ViewPort* view_port = view_port_alloc(); + view_port_draw_callback_set(view_port, temperature_sensor_draw_callback, NULL); + view_port_input_callback_set(view_port, temperature_sensor_input_callback, event_queue); + + // Create timer and register its callback + FuriTimer* timer = + furi_timer_alloc(temperature_sensor_timer_callback, FuriTimerTypePeriodic, event_queue); + furi_timer_start(timer, furi_kernel_get_tick_frequency()); + + // Register viewport + Gui* gui = furi_record_open(RECORD_GUI); + gui_add_view_port(gui, view_port, GuiLayerFullscreen); + + // Used to notify the user by blinking red (error) or blue (fetch successful) + NotificationApp* notifications = furi_record_open(RECORD_NOTIFICATION); + + while(1) { + furi_check(furi_message_queue_get(event_queue, &tsEvent, FuriWaitForever) == FuriStatusOk); + + // Handle events + if(tsEvent.type == TSEventTypeInput) { + // Exit on back key + if(tsEvent.input.key == + InputKeyBack) // We dont check for type here, we can check the type of keypress like: (event.input.type == InputTypeShort) + break; + + } else if(tsEvent.type == TSEventTypeTick) { + // Update sensor data + // Fetch data and set the sensor current status accordingly + sensorFound = temperature_sensor_fetch_info(&celsius, &rel_humidity); + temperature_sensor_current_status = (sensorFound ? TSSPendingUpdate : TSSNoSensor); + + if(sensorFound) { + // Blink blue + notification_message(notifications, &sequence_blink_blue_100); + + if(celsius != TS_DEFAULT_VALUE && rel_humidity != TS_DEFAULT_VALUE) { + // Convert celsius to fahrenheit + fahrenheit = (celsius * 9 / 5) + 32; + + // Calculate absolute humidity - For more info refer to https://github.com/Mywk/FlipperTemperatureSensor/issues/1 + // Calculate saturation vapour pressure first + vapour_pressure = + (double)6.11 * + pow(10, (double)(((double)7.5 * celsius) / ((double)237.3 + celsius))); + // Then the vapour pressure in Pa + vapour_pressure = vapour_pressure * rel_humidity; + // Calculate absolute humidity + abs_humidity = + (double)2.16679 * (double)(vapour_pressure / ((double)273.15 + celsius)); + + // Fill our buffers here, not on the canvas draw callback + snprintf(ts_data_buffer_temperature_c, DATA_BUFFER_SIZE, "%.2f", celsius); + snprintf(ts_data_buffer_temperature_f, DATA_BUFFER_SIZE, "%.2f", fahrenheit); + snprintf( + ts_data_buffer_relative_humidity, DATA_BUFFER_SIZE, "%.2f", rel_humidity); + snprintf( + ts_data_buffer_absolute_humidity, DATA_BUFFER_SIZE, "%.2f", abs_humidity); + } + + } else { + // Reset our variables to their default values + celsius = fahrenheit = rel_humidity = abs_humidity = TS_DEFAULT_VALUE; + + // Blink red + notification_message(notifications, &sequence_blink_red_100); + } + } + + uint32_t wait_ticks = furi_ms_to_ticks(!sensorFound ? 100 : 500); + 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); + view_port_free(view_port); + furi_message_queue_free(event_queue); + + furi_record_close(RECORD_NOTIFICATION); + furi_record_close(RECORD_GUI); + + return 0; +} diff --git a/applications/plugins/temperature_sensor/temperature_sensor.png b/applications/plugins/am2320_temp_sensor/temperature_sensor.png similarity index 100% rename from applications/plugins/temperature_sensor/temperature_sensor.png rename to applications/plugins/am2320_temp_sensor/temperature_sensor.png diff --git a/applications/plugins/arkanoid/arkanoid_game.c b/applications/plugins/arkanoid/arkanoid_game.c index 91ae8e736..d0026e226 100644 --- a/applications/plugins/arkanoid/arkanoid_game.c +++ b/applications/plugins/arkanoid/arkanoid_game.c @@ -448,14 +448,13 @@ int32_t arkanoid_game_app(void* p) { arkanoid_state->ball_state.dy = -1; //start the game flag arkanoid_state->gameStarted = true; - break; } + break; + default: + break; } } } - } else { - // Event timeout - FURI_LOG_D(TAG, "furi_message_queue: Event timeout"); } view_port_update(view_port); diff --git a/applications/plugins/barcode_generator/barcode_generator.c b/applications/plugins/barcode_generator/barcode_generator.c index d03d45495..0418d672c 100644 --- a/applications/plugins/barcode_generator/barcode_generator.c +++ b/applications/plugins/barcode_generator/barcode_generator.c @@ -523,12 +523,11 @@ int32_t barcode_UPCA_generator_app(void* p) { plugin_state->modeIndex = 0; } break; + default: + break; } } } - } else { - FURI_LOG_D("barcode_UPCA_generator", "osMessageQueue: event timeout"); - // event timeout } view_port_update(view_port); diff --git a/applications/plugins/dht_temp_sensor/quenon_dht_mon.c b/applications/plugins/dht_temp_sensor/quenon_dht_mon.c index bbb91ec3d..4084a351c 100644 --- a/applications/plugins/dht_temp_sensor/quenon_dht_mon.c +++ b/applications/plugins/dht_temp_sensor/quenon_dht_mon.c @@ -442,6 +442,8 @@ int32_t quenon_dht_mon_app() { case InputKeyBack: processing = false; break; + default: + break; } } } diff --git a/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c b/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c index b9c5a1134..c44fc2528 100644 --- a/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c +++ b/applications/plugins/dht_temp_sensor/scenes/DHTMon_sensorEdit_scene.c @@ -93,6 +93,9 @@ void sensorEdit_scene(PluginData* app) { app->item, DHTMon_GPIO_getName(app->currentSensorEdit->GPIO)); variable_item_list_add(variable_item_list, "Save", 1, NULL, app); + //Сброс выбранного пункта в ноль + variable_item_list_set_selected_item(variable_item_list, 0); + view_dispatcher_switch_to_view(app->view_dispatcher, ADDSENSOR_MENU_VIEW); } void sensorEdit_sceneRemove(void) { diff --git a/applications/plugins/flappy_bird/flappy_bird.c b/applications/plugins/flappy_bird/flappy_bird.c index 4ee3767f6..9f435cf69 100644 --- a/applications/plugins/flappy_bird/flappy_bird.c +++ b/applications/plugins/flappy_bird/flappy_bird.c @@ -350,14 +350,13 @@ int32_t flappy_game_app(void* p) { case InputKeyBack: processing = false; break; + default: + break; } } } else if(event.type == EventTypeTick) { flappy_game_tick(game_state); } - } else { - // FURI_LOG_D(TAG, "osMessageQueue: event timeout"); - // event timeout } view_port_update(view_port); diff --git a/applications/plugins/flipfrid/scene/flipfrid_scene_entrypoint.c b/applications/plugins/flipfrid/scene/flipfrid_scene_entrypoint.c index 3a1ce4951..1ac91625f 100644 --- a/applications/plugins/flipfrid/scene/flipfrid_scene_entrypoint.c +++ b/applications/plugins/flipfrid/scene/flipfrid_scene_entrypoint.c @@ -134,6 +134,8 @@ void flipfrid_scene_entrypoint_on_event(FlipFridEvent event, FlipFridState* cont case InputKeyBack: context->is_running = false; break; + default: + break; } } } diff --git a/applications/plugins/flipfrid/scene/flipfrid_scene_load_custom_uids.c b/applications/plugins/flipfrid/scene/flipfrid_scene_load_custom_uids.c index 24f579ef1..7bf7f5eaa 100644 --- a/applications/plugins/flipfrid/scene/flipfrid_scene_load_custom_uids.c +++ b/applications/plugins/flipfrid/scene/flipfrid_scene_load_custom_uids.c @@ -72,6 +72,8 @@ void flipfrid_scene_load_custom_uids_on_event(FlipFridEvent event, FlipFridState case InputKeyBack: context->current_scene = SceneEntryPoint; break; + default: + break; } } } diff --git a/applications/plugins/flipfrid/scene/flipfrid_scene_load_file.c b/applications/plugins/flipfrid/scene/flipfrid_scene_load_file.c index 402bb51d7..d41549d73 100644 --- a/applications/plugins/flipfrid/scene/flipfrid_scene_load_file.c +++ b/applications/plugins/flipfrid/scene/flipfrid_scene_load_file.c @@ -159,6 +159,8 @@ void flipfrid_scene_load_file_on_event(FlipFridEvent event, FlipFridState* conte case InputKeyBack: context->current_scene = SceneEntryPoint; break; + default: + break; } } } diff --git a/applications/plugins/flipfrid/scene/flipfrid_scene_run_attack.c b/applications/plugins/flipfrid/scene/flipfrid_scene_run_attack.c index 3baa4ea49..c2f1a77ca 100644 --- a/applications/plugins/flipfrid/scene/flipfrid_scene_run_attack.c +++ b/applications/plugins/flipfrid/scene/flipfrid_scene_run_attack.c @@ -546,6 +546,8 @@ void flipfrid_scene_run_attack_on_event(FlipFridEvent event, FlipFridState* cont notification_message(context->notify, &sequence_blink_stop); context->current_scene = SceneEntryPoint; break; + default: + break; } } } diff --git a/applications/plugins/flipfrid/scene/flipfrid_scene_select_field.c b/applications/plugins/flipfrid/scene/flipfrid_scene_select_field.c index 79416d616..ccb49e910 100644 --- a/applications/plugins/flipfrid/scene/flipfrid_scene_select_field.c +++ b/applications/plugins/flipfrid/scene/flipfrid_scene_select_field.c @@ -129,6 +129,8 @@ void flipfrid_scene_select_field_on_event(FlipFridEvent event, FlipFridState* co furi_string_reset(context->notification_msg); context->current_scene = SceneSelectFile; break; + default: + break; } FURI_LOG_D(TAG, "Position: %d/%d", context->key_index, nb_bytes); } diff --git a/applications/plugins/game15/README.md b/applications/plugins/game15/README.md index 493983180..b1710c919 100644 --- a/applications/plugins/game15/README.md +++ b/applications/plugins/game15/README.md @@ -1,6 +1,8 @@ # Game "15" for Flipper Zero +[Original link](https://github.com/x27/flipperzero-game15) + Logic game [Wikipedia](https://en.wikipedia.org/wiki/15_puzzle) ![Game screen](images/Game15.png) @@ -9,4 +11,3 @@ Logic game [Wikipedia](https://en.wikipedia.org/wiki/15_puzzle) ![Popoup](images/Game15Popup.png) -FAP file for firmware 0.69.1 diff --git a/applications/plugins/game15/game15.c b/applications/plugins/game15/game15.c index f89b7c5c0..aad5f1330 100644 --- a/applications/plugins/game15/game15.c +++ b/applications/plugins/game15/game15.c @@ -426,6 +426,8 @@ static void game_event_handler(GameEvent const event) { sandbox_loop_exit(); } break; + default: + break; } } } else if(event.type == EventTypeTick) { diff --git a/applications/plugins/gps_nmea_uart/README.md b/applications/plugins/gps_nmea_uart/README.md index ffeb6ee99..3f7a5ef3d 100644 --- a/applications/plugins/gps_nmea_uart/README.md +++ b/applications/plugins/gps_nmea_uart/README.md @@ -1,6 +1,8 @@ # GPS for Flipper Zero A simple Flipper Zero application for NMEA 0183 serial GPS modules, such as the + +[Original link](https://github.com/ezod/flipperzero-gps) [Adafruit Ultimate GPS Breakout]. [Original link](https://github.com/ezod/flipperzero-gps) diff --git a/applications/plugins/gps_nmea_uart/gps.c b/applications/plugins/gps_nmea_uart/gps.c index 1df4882b5..62053cede 100644 --- a/applications/plugins/gps_nmea_uart/gps.c +++ b/applications/plugins/gps_nmea_uart/gps.c @@ -110,11 +110,11 @@ int32_t gps_app(void* p) { case InputKeyBack: processing = false; break; + default: + break; } } } - } else { - FURI_LOG_D("GPS", "FuriMessageQueue: event timeout"); } view_port_update(view_port); diff --git a/applications/plugins/hc_sr04/hc_sr04.c b/applications/plugins/hc_sr04/hc_sr04.c index 911e92dc6..dbbf4f3ec 100644 --- a/applications/plugins/hc_sr04/hc_sr04.c +++ b/applications/plugins/hc_sr04/hc_sr04.c @@ -230,6 +230,8 @@ int32_t hc_sr04_app() { case InputKeyBack: processing = false; break; + default: + break; } } } diff --git a/applications/plugins/temperature_sensor/Readme.md b/applications/plugins/htu21d_temp_sensor/Readme.md similarity index 100% rename from applications/plugins/temperature_sensor/Readme.md rename to applications/plugins/htu21d_temp_sensor/Readme.md diff --git a/applications/plugins/temperature_sensor/application.fam b/applications/plugins/htu21d_temp_sensor/application.fam similarity index 100% rename from applications/plugins/temperature_sensor/application.fam rename to applications/plugins/htu21d_temp_sensor/application.fam diff --git a/applications/plugins/temperature_sensor/docs/App.png b/applications/plugins/htu21d_temp_sensor/docs/App.png similarity index 100% rename from applications/plugins/temperature_sensor/docs/App.png rename to applications/plugins/htu21d_temp_sensor/docs/App.png diff --git a/applications/plugins/temperature_sensor/docs/Connection.png b/applications/plugins/htu21d_temp_sensor/docs/Connection.png similarity index 100% rename from applications/plugins/temperature_sensor/docs/Connection.png rename to applications/plugins/htu21d_temp_sensor/docs/Connection.png diff --git a/applications/plugins/temperature_sensor/docs/Flipper.png b/applications/plugins/htu21d_temp_sensor/docs/Flipper.png similarity index 100% rename from applications/plugins/temperature_sensor/docs/Flipper.png rename to applications/plugins/htu21d_temp_sensor/docs/Flipper.png diff --git a/applications/plugins/temperature_sensor/temperature_sensor.c b/applications/plugins/htu21d_temp_sensor/temperature_sensor.c similarity index 100% rename from applications/plugins/temperature_sensor/temperature_sensor.c rename to applications/plugins/htu21d_temp_sensor/temperature_sensor.c diff --git a/applications/plugins/htu21d_temp_sensor/temperature_sensor.png b/applications/plugins/htu21d_temp_sensor/temperature_sensor.png new file mode 100644 index 000000000..b6fe6d7fe Binary files /dev/null and b/applications/plugins/htu21d_temp_sensor/temperature_sensor.png differ diff --git a/applications/plugins/metronome/metronome.c b/applications/plugins/metronome/metronome.c index 76cb62a8a..2433ef86c 100644 --- a/applications/plugins/metronome/metronome.c +++ b/applications/plugins/metronome/metronome.c @@ -320,6 +320,8 @@ int32_t metronome_app() { case InputKeyBack: processing = false; break; + default: + break; } } else if(event.input.type == InputTypeLong) { // hold events @@ -340,6 +342,8 @@ int32_t metronome_app() { case InputKeyBack: processing = false; break; + default: + break; } } else if(event.input.type == InputTypeRepeat) { // repeat events @@ -359,6 +363,8 @@ int32_t metronome_app() { case InputKeyBack: processing = false; break; + default: + break; } } } diff --git a/applications/plugins/minesweeper/minesweeper.c b/applications/plugins/minesweeper/minesweeper.c index 95044c04c..fa9fdcc78 100644 --- a/applications/plugins/minesweeper/minesweeper.c +++ b/applications/plugins/minesweeper/minesweeper.c @@ -476,6 +476,8 @@ int32_t minesweeper_app(void* p) { // Exit the plugin processing = false; break; + default: + break; } } else if(event.input.type == InputTypeLong) { // hold events @@ -493,6 +495,8 @@ int32_t minesweeper_app(void* p) { case InputKeyBack: processing = false; break; + default: + break; } } } diff --git a/applications/plugins/morse_code/morse_code.c b/applications/plugins/morse_code/morse_code.c index 0b4790721..a29454371 100644 --- a/applications/plugins/morse_code/morse_code.c +++ b/applications/plugins/morse_code/morse_code.c @@ -27,7 +27,6 @@ typedef struct { MorseCodeWorker* worker; } MorseCode; - static void render_callback(Canvas* const canvas, void* ctx) { MorseCode* morse_code = ctx; furi_check(furi_mutex_acquire(morse_code->model_mutex, FuriWaitForever) == FuriStatusOk); @@ -35,20 +34,26 @@ static void render_callback(Canvas* const canvas, void* ctx) { canvas_set_font(canvas, FontPrimary); //write words - elements_multiline_text_aligned(canvas, 64, 30, AlignCenter, AlignCenter, furi_string_get_cstr(morse_code->model->words)); - - // volume view_port + elements_multiline_text_aligned( + canvas, 64, 30, AlignCenter, AlignCenter, furi_string_get_cstr(morse_code->model->words)); + + // volume view_port uint8_t vol_bar_x_pos = 124; uint8_t vol_bar_y_pos = 0; - const uint8_t volume_h = - (64 / (COUNT_OF(MORSE_CODE_VOLUMES) - 1)) * morse_code->model->volume; + const uint8_t volume_h = (64 / (COUNT_OF(MORSE_CODE_VOLUMES) - 1)) * morse_code->model->volume; canvas_draw_frame(canvas, vol_bar_x_pos, vol_bar_y_pos, 4, 64); canvas_draw_box(canvas, vol_bar_x_pos, vol_bar_y_pos + (64 - volume_h), 4, volume_h); //dit bpm canvas_draw_str_aligned( - canvas, 0, 10, AlignLeft, AlignCenter, furi_string_get_cstr(furi_string_alloc_printf("Dit: %ld ms", morse_code->model->dit_delta))); - + canvas, + 0, + 10, + AlignLeft, + AlignCenter, + furi_string_get_cstr( + furi_string_alloc_printf("Dit: %ld ms", morse_code->model->dit_delta))); + //button info elements_button_center(canvas, "Press/Hold"); furi_mutex_release(morse_code->model_mutex); @@ -59,9 +64,7 @@ static void input_callback(InputEvent* input_event, void* ctx) { furi_message_queue_put(morse_code->input_queue, input_event, FuriWaitForever); } -static void morse_code_worker_callback( - FuriString* words, - void* context) { +static void morse_code_worker_callback(FuriString* words, void* context) { MorseCode* morse_code = context; furi_check(furi_mutex_acquire(morse_code->model_mutex, FuriWaitForever) == FuriStatusOk); morse_code->model->words = words; @@ -115,45 +118,45 @@ int32_t morse_code_app() { InputEvent input; morse_code_worker_start(morse_code->worker); morse_code_worker_set_volume( - morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); - morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); - while(furi_message_queue_get(morse_code->input_queue, &input, FuriWaitForever) == FuriStatusOk){ + morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); + morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); + while(furi_message_queue_get(morse_code->input_queue, &input, FuriWaitForever) == + FuriStatusOk) { furi_check(furi_mutex_acquire(morse_code->model_mutex, FuriWaitForever) == FuriStatusOk); if(input.key == InputKeyBack) { - furi_mutex_release(morse_code->model_mutex); - break; - }else if(input.key == InputKeyOk){ - if(input.type == InputTypePress) - morse_code_worker_play(morse_code->worker, true); - else if(input.type == InputTypeRelease) - morse_code_worker_play(morse_code->worker, false); - }else if(input.key == InputKeyUp && input.type == InputTypePress){ - if(morse_code->model->volume < COUNT_OF(MORSE_CODE_VOLUMES) - 1) - morse_code->model->volume++; - morse_code_worker_set_volume( - morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); - }else if(input.key == InputKeyDown && input.type == InputTypePress){ - if(morse_code->model->volume > 0) - morse_code->model->volume--; - morse_code_worker_set_volume( - morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); - }else if(input.key == InputKeyLeft && input.type == InputTypePress){ - if(morse_code->model->dit_delta > 10) - morse_code->model->dit_delta-=10; - morse_code_worker_set_dit_delta( - morse_code->worker, morse_code->model->dit_delta); - } - else if(input.key == InputKeyRight && input.type == InputTypePress){ - if(morse_code->model->dit_delta >= 10) - morse_code->model->dit_delta+=10; - morse_code_worker_set_dit_delta( - morse_code->worker, morse_code->model->dit_delta); - } - - FURI_LOG_D("Input", "%s %s %ld", input_get_key_name(input.key), input_get_type_name(input.type), input.sequence); - + furi_mutex_release(morse_code->model_mutex); + break; + } else if(input.key == InputKeyOk) { + if(input.type == InputTypePress) + morse_code_worker_play(morse_code->worker, true); + else if(input.type == InputTypeRelease) + morse_code_worker_play(morse_code->worker, false); + } else if(input.key == InputKeyUp && input.type == InputTypePress) { + if(morse_code->model->volume < COUNT_OF(MORSE_CODE_VOLUMES) - 1) + morse_code->model->volume++; + morse_code_worker_set_volume( + morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); + } else if(input.key == InputKeyDown && input.type == InputTypePress) { + if(morse_code->model->volume > 0) morse_code->model->volume--; + morse_code_worker_set_volume( + morse_code->worker, MORSE_CODE_VOLUMES[morse_code->model->volume]); + } else if(input.key == InputKeyLeft && input.type == InputTypePress) { + if(morse_code->model->dit_delta > 10) morse_code->model->dit_delta -= 10; + morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); + } else if(input.key == InputKeyRight && input.type == InputTypePress) { + if(morse_code->model->dit_delta >= 10) morse_code->model->dit_delta += 10; + morse_code_worker_set_dit_delta(morse_code->worker, morse_code->model->dit_delta); + } + + FURI_LOG_D( + "Input", + "%s %s %ld", + input_get_key_name(input.key), + input_get_type_name(input.type), + input.sequence); + furi_mutex_release(morse_code->model_mutex); - view_port_update(morse_code->view_port); + view_port_update(morse_code->view_port); } morse_code_worker_stop(morse_code->worker); morse_code_free(morse_code); diff --git a/applications/plugins/morse_code/morse_code_worker.c b/applications/plugins/morse_code/morse_code_worker.c index 54ee747c5..b465abc5b 100644 --- a/applications/plugins/morse_code/morse_code_worker.c +++ b/applications/plugins/morse_code/morse_code_worker.c @@ -2,19 +2,20 @@ #include #include - #define TAG "MorseCodeWorker" #define MORSE_CODE_VERSION 0 //A-Z0-1 -const char morse_array[36][6] ={ - ".-", "-...", "-.-.", "-..", ".", "..-.", "--.", "....", "..", ".---", "-.-", ".-..", "--", "-.", "---", ".--.", - "--.-", ".-.", "...", "-", "..-", "...-", ".--", "-..-", "-.--", "--..", ".----", "..---", "...--", "....-", ".....", - "-....", "--...", "---..", "----.", "-----" - }; -const char symbol_array[36] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', - 'U', 'V', 'W', 'X', 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; +const char morse_array[36][6] = {".-", "-...", "-.-.", "-..", ".", "..-.", + "--.", "....", "..", ".---", "-.-", ".-..", + "--", "-.", "---", ".--.", "--.-", ".-.", + "...", "-", "..-", "...-", ".--", "-..-", + "-.--", "--..", ".----", "..---", "...--", "....-", + ".....", "-....", "--...", "---..", "----.", "-----"}; +const char symbol_array[36] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', + 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', + 'Y', 'Z', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'}; struct MorseCodeWorker { FuriThread* thread; @@ -28,31 +29,28 @@ struct MorseCodeWorker { FuriString* words; }; -void morse_code_worker_fill_buffer(MorseCodeWorker* instance, uint32_t duration){ +void morse_code_worker_fill_buffer(MorseCodeWorker* instance, uint32_t duration) { FURI_LOG_D("MorseCode: Duration", "%ld", duration); - if( duration <= instance->dit_delta) + if(duration <= instance->dit_delta) furi_string_push_back(instance->buffer, *DOT); else if(duration <= (instance->dit_delta * 3)) furi_string_push_back(instance->buffer, *LINE); - if(furi_string_size(instance->buffer) > 5) - furi_string_reset(instance->buffer); + if(furi_string_size(instance->buffer) > 5) furi_string_reset(instance->buffer); FURI_LOG_D("MorseCode: Buffer", "%s", furi_string_get_cstr(instance->buffer)); } -void morse_code_worker_fill_letter(MorseCodeWorker* instance){ - if(furi_string_size(instance->words) > 63) - furi_string_reset(instance->words); - for (size_t i = 0; i < sizeof(morse_array); i++){ - if(furi_string_cmp_str(instance->buffer, morse_array[i]) == 0){ - furi_string_push_back(instance->words, symbol_array[i]); - furi_string_reset(instance->buffer); - break; - } +void morse_code_worker_fill_letter(MorseCodeWorker* instance) { + if(furi_string_size(instance->words) > 63) furi_string_reset(instance->words); + for(size_t i = 0; i < sizeof(morse_array); i++) { + if(furi_string_cmp_str(instance->buffer, morse_array[i]) == 0) { + furi_string_push_back(instance->words, symbol_array[i]); + furi_string_reset(instance->buffer); + break; } + } FURI_LOG_D("MorseCode: Words", "%s", furi_string_get_cstr(instance->words)); } - static int32_t morse_code_worker_thread_callback(void* context) { furi_assert(context); MorseCodeWorker* instance = context; @@ -61,16 +59,16 @@ static int32_t morse_code_worker_thread_callback(void* context) { uint32_t end_tick = 0; bool pushed = true; bool spaced = true; - while(instance->is_running){ + while(instance->is_running) { furi_delay_ms(SLEEP); - if(instance->play){ - if(!was_playing){ + if(instance->play) { + if(!was_playing) { start_tick = furi_get_tick(); furi_hal_speaker_start(FREQUENCY, instance->volume); was_playing = true; } - }else{ - if(was_playing){ + } else { + if(was_playing) { pushed = false; spaced = false; furi_hal_speaker_stop(); @@ -80,21 +78,21 @@ static int32_t morse_code_worker_thread_callback(void* context) { start_tick = 0; } } - if(!pushed){ - if(end_tick + (instance->dit_delta * 3) < furi_get_tick()){ + if(!pushed) { + if(end_tick + (instance->dit_delta * 3) < furi_get_tick()) { //NEW LETTER morse_code_worker_fill_letter(instance); if(instance->callback) - instance->callback(instance->words, instance->callback_context); + instance->callback(instance->words, instance->callback_context); pushed = true; } } - if(!spaced){ - if(end_tick + (instance->dit_delta * 7) < furi_get_tick()){ + if(!spaced) { + if(end_tick + (instance->dit_delta * 7) < furi_get_tick()) { //NEW WORD furi_string_push_back(instance->words, *SPACE); if(instance->callback) - instance->callback(instance->words, instance->callback_context); + instance->callback(instance->words, instance->callback_context); spaced = true; } } @@ -132,17 +130,17 @@ void morse_code_worker_set_callback( instance->callback_context = context; } -void morse_code_worker_play(MorseCodeWorker* instance, bool play){ +void morse_code_worker_play(MorseCodeWorker* instance, bool play) { furi_assert(instance); instance->play = play; } -void morse_code_worker_set_volume(MorseCodeWorker* instance, float level){ +void morse_code_worker_set_volume(MorseCodeWorker* instance, float level) { furi_assert(instance); instance->volume = level; } -void morse_code_worker_set_dit_delta(MorseCodeWorker* instance, uint32_t delta){ +void morse_code_worker_set_dit_delta(MorseCodeWorker* instance, uint32_t delta) { furi_assert(instance); instance->dit_delta = delta; } diff --git a/applications/plugins/morse_code/morse_code_worker.h b/applications/plugins/morse_code/morse_code_worker.h index cc84a2674..524876476 100644 --- a/applications/plugins/morse_code/morse_code_worker.h +++ b/applications/plugins/morse_code/morse_code_worker.h @@ -10,9 +10,7 @@ #define LINE "-" #define SPACE " " -typedef void (*MorseCodeWorkerCallback)( - FuriString* buffer, - void* context); +typedef void (*MorseCodeWorkerCallback)(FuriString* buffer, void* context); typedef struct MorseCodeWorker MorseCodeWorker; @@ -34,9 +32,3 @@ void morse_code_worker_play(MorseCodeWorker* instance, bool play); void morse_code_worker_set_volume(MorseCodeWorker* instance, float level); void morse_code_worker_set_dit_delta(MorseCodeWorker* instance, uint32_t delta); - - - - - - diff --git a/applications/plugins/mousejacker/mousejacker.c b/applications/plugins/mousejacker/mousejacker.c index eaf8cfaa3..c45b0e502 100644 --- a/applications/plugins/mousejacker/mousejacker.c +++ b/applications/plugins/mousejacker/mousejacker.c @@ -374,6 +374,8 @@ int32_t mousejacker_app(void* p) { plugin_state->close_thread_please = false; processing = false; break; + default: + break; } } } @@ -384,7 +386,7 @@ int32_t mousejacker_app(void* p) { } furi_thread_free(plugin_state->mjthread); - furi_hal_spi_release(nrf24_HANDLE); + nrf24_deinit(); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close(RECORD_GUI); diff --git a/applications/plugins/nrfsniff/nrfsniff.c b/applications/plugins/nrfsniff/nrfsniff.c index 2ad9287b9..ce2836152 100644 --- a/applications/plugins/nrfsniff/nrfsniff.c +++ b/applications/plugins/nrfsniff/nrfsniff.c @@ -400,6 +400,8 @@ int32_t nrfsniff_app(void* p) { case InputKeyBack: if(event.input.type == InputTypeLong) processing = false; break; + default: + break; } } } @@ -444,7 +446,7 @@ int32_t nrfsniff_app(void* p) { sample_time = DEFAULT_SAMPLE_TIME; target_rate = 8; // rate can be either 8 (2Mbps) or 0 (1Mbps) sniffing_state = false; - furi_hal_spi_release(nrf24_HANDLE); + nrf24_deinit(); view_port_enabled_set(view_port, false); gui_remove_view_port(gui, view_port); furi_record_close(RECORD_GUI); diff --git a/applications/plugins/picopass/125_10px.png b/applications/plugins/picopass/125_10px.png new file mode 100644 index 000000000..ce01284a2 Binary files /dev/null and b/applications/plugins/picopass/125_10px.png differ diff --git a/applications/plugins/picopass/application.fam b/applications/plugins/picopass/application.fam index b1b181055..0bf7e02b3 100644 --- a/applications/plugins/picopass/application.fam +++ b/applications/plugins/picopass/application.fam @@ -9,7 +9,8 @@ App( ], stack_size=4 * 1024, order=175, - fap_icon="../../../assets/icons/Archive/125_10px.png", + order=30, + fap_icon="125_10px.png", fap_category="Tools", fap_libs=["mbedtls"], fap_private_libs=[ diff --git a/applications/plugins/picopass/picopass_worker_i.h b/applications/plugins/picopass/picopass_worker_i.h index 101d4d8f2..ded40e6c6 100644 --- a/applications/plugins/picopass/picopass_worker_i.h +++ b/applications/plugins/picopass/picopass_worker_i.h @@ -9,8 +9,6 @@ #include #include -#include -#include #include #include diff --git a/applications/plugins/picopass/rfal_picopass.c b/applications/plugins/picopass/rfal_picopass.c index 50cd4e95d..ac66cb92d 100644 --- a/applications/plugins/picopass/rfal_picopass.c +++ b/applications/plugins/picopass/rfal_picopass.c @@ -1,5 +1,4 @@ #include "rfal_picopass.h" -#include "utils.h" #define RFAL_PICOPASS_TXRX_FLAGS \ (FURI_HAL_NFC_LL_TXRX_FLAGS_CRC_TX_MANUAL | FURI_HAL_NFC_LL_TXRX_FLAGS_AGC_ON | \ @@ -97,7 +96,7 @@ FuriHalNfcReturn rfalPicoPassPollerSelect(uint8_t* csn, rfalPicoPassSelectRes* s rfalPicoPassSelectReq selReq; selReq.CMD = RFAL_PICOPASS_CMD_SELECT; - ST_MEMCPY(selReq.CSN, csn, RFAL_PICOPASS_UID_LEN); + memcpy(selReq.CSN, csn, RFAL_PICOPASS_UID_LEN); uint16_t recvLen = 0; uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); @@ -146,8 +145,8 @@ FuriHalNfcReturn rfalPicoPassPollerCheck(uint8_t* mac, rfalPicoPassCheckRes* chk FuriHalNfcReturn ret; rfalPicoPassCheckReq chkReq; chkReq.CMD = RFAL_PICOPASS_CMD_CHECK; - ST_MEMCPY(chkReq.mac, mac, 4); - ST_MEMSET(chkReq.null, 0, 4); + memcpy(chkReq.mac, mac, 4); + memset(chkReq.null, 0, 4); uint16_t recvLen = 0; uint32_t flags = RFAL_PICOPASS_TXRX_FLAGS; uint32_t fwt = furi_hal_nfc_ll_ms2fc(20); diff --git a/applications/plugins/sentry_safe/sentry_safe.c b/applications/plugins/sentry_safe/sentry_safe.c index f88661beb..4d9c12fc7 100644 --- a/applications/plugins/sentry_safe/sentry_safe.c +++ b/applications/plugins/sentry_safe/sentry_safe.c @@ -143,6 +143,8 @@ int32_t sentry_safe_app(void* p) { case InputKeyBack: processing = false; break; + default: + break; } } } diff --git a/applications/plugins/snake_game/snake_game.c b/applications/plugins/snake_game/snake_game.c index c15475169..cfc92e443 100644 --- a/applications/plugins/snake_game/snake_game.c +++ b/applications/plugins/snake_game/snake_game.c @@ -167,8 +167,8 @@ static Point snake_game_get_new_fruit(SnakeState const* const snake_state) { if((buffer[y] & mask) == 0) { if(newFruit == 0) { Point p = { - .x = x, - .y = y, + .x = x * 2, + .y = y * 2, }; return p; } @@ -361,6 +361,8 @@ int32_t snake_game_app(void* p) { snake_game_save_game_to_file(snake_state); processing = false; break; + default: + break; } } } else if(event.type == EventTypeTick) { diff --git a/applications/plugins/spectrum_analyzer/spectrum_analyzer.c b/applications/plugins/spectrum_analyzer/spectrum_analyzer.c index d94739bc1..8d68c5a1a 100644 --- a/applications/plugins/spectrum_analyzer/spectrum_analyzer.c +++ b/applications/plugins/spectrum_analyzer/spectrum_analyzer.c @@ -496,6 +496,8 @@ int32_t spectrum_analyzer_app(void* p) { case InputKeyBack: exit_loop = true; break; + default: + break; } furi_mutex_release(spectrum_analyzer->model_mutex); diff --git a/applications/plugins/tetris_game/tetris_game.c b/applications/plugins/tetris_game/tetris_game.c index 273081126..7c3757ef1 100644 --- a/applications/plugins/tetris_game/tetris_game.c +++ b/applications/plugins/tetris_game/tetris_game.c @@ -442,6 +442,8 @@ int32_t tetris_game_app() { case InputKeyBack: processing = false; break; + default: + break; } } } else if(event.type == EventTypeTick) { diff --git a/applications/plugins/tictactoe_game/tictactoe_game.c b/applications/plugins/tictactoe_game/tictactoe_game.c index b3a0d5c84..fe57d7c62 100644 --- a/applications/plugins/tictactoe_game/tictactoe_game.c +++ b/applications/plugins/tictactoe_game/tictactoe_game.c @@ -358,12 +358,11 @@ int32_t tictactoe_game_app(void* p) { case InputKeyOk: tictactoe_state->button_state = true; break; + default: + break; } } } - } else { - // Event timeout - FURI_LOG_D(TAG, "furi_message_queue: Event timeout"); } view_port_update(view_port); diff --git a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c b/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c index fc39b66cd..04b73595b 100644 --- a/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c +++ b/applications/plugins/totp/scenes/add_new_token/totp_scene_add_new_token.c @@ -282,6 +282,8 @@ bool totp_scene_add_new_token_handle_event(PluginEvent* const event, PluginState totp_scene_director_activate_scene(plugin_state, TotpSceneGenerateToken, NULL); } break; + default: + break; } } } diff --git a/applications/plugins/totp/scenes/app_settings/totp_app_settings.c b/applications/plugins/totp/scenes/app_settings/totp_app_settings.c index cdb775a8d..b3e6ab847 100644 --- a/applications/plugins/totp/scenes/app_settings/totp_app_settings.c +++ b/applications/plugins/totp/scenes/app_settings/totp_app_settings.c @@ -158,6 +158,8 @@ bool totp_scene_app_settings_handle_event(PluginEvent* const event, PluginState* } break; } + default: + break; } } } diff --git a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c index 4ed79accd..cdb77f5e2 100644 --- a/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c +++ b/applications/plugins/totp/scenes/authenticate/totp_scene_authenticate.c @@ -143,6 +143,8 @@ bool totp_scene_authenticate_handle_event(PluginEvent* const event, PluginState* scene_state->code_length--; } break; + default: + break; } } } diff --git a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c index 674bcd41e..c9547a1ab 100644 --- a/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c +++ b/applications/plugins/totp/scenes/generate_token/totp_scene_generate_token.c @@ -303,6 +303,8 @@ bool totp_scene_generate_token_handle_event(PluginEvent* const event, PluginStat break; case InputKeyBack: break; + default: + break; } } } diff --git a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c index 22c37dc2c..717cb64bc 100644 --- a/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c +++ b/applications/plugins/totp/scenes/token_menu/totp_scene_token_menu.c @@ -179,6 +179,8 @@ bool totp_scene_token_menu_handle_event(PluginEvent* const event, PluginState* p } break; } + default: + break; } } } diff --git a/applications/plugins/unirfremix/unirfremix_app.c b/applications/plugins/unirfremix/unirfremix_app.c index 7bccf56ab..0ce7e036a 100644 --- a/applications/plugins/unirfremix/unirfremix_app.c +++ b/applications/plugins/unirfremix/unirfremix_app.c @@ -1064,6 +1064,8 @@ int32_t unirfremix_app(void* p) { unirfremix_tx_stop(app); exit_loop = true; break; + default: + break; } if(app->processing == 0) { @@ -1135,6 +1137,8 @@ int32_t unirfremix_app(void* p) { case InputKeyBack: exit_loop = true; break; + default: + break; } if(exit_loop == true) { diff --git a/applications/plugins/weather_station/helpers/weather_station_types.h b/applications/plugins/weather_station/helpers/weather_station_types.h index 2976cbce8..5a66dd0ce 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.3.1" +#define WS_VERSION_APP "0.4" #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 index db05af095..4d7f59544 100644 --- a/applications/plugins/weather_station/protocols/acurite_592txr.c +++ b/applications/plugins/weather_station/protocols/acurite_592txr.c @@ -4,7 +4,7 @@ /* * Help - * https://github.com/merbanan/rtl_433/blob/5bef4e43133ac4c0e2d18d36f87c52b4f9458453/src/devices/acurite.c + * https://github.com/merbanan/rtl_433/blob/master/src/devices/acurite.c * * Acurite 592TXR Temperature Humidity sensor decoder * Message Type 0x04, 7 bytes diff --git a/applications/plugins/weather_station/protocols/ambient_weather.c b/applications/plugins/weather_station/protocols/ambient_weather.c new file mode 100644 index 000000000..07f5330fc --- /dev/null +++ b/applications/plugins/weather_station/protocols/ambient_weather.c @@ -0,0 +1,278 @@ +#include "ambient_weather.h" +#include + +#define TAG "WSProtocolAmbient_Weather" + +/* + * Help + * https://github.com/merbanan/rtl_433/blob/master/src/devices/ambient_weather.c + * + * Decode Ambient Weather F007TH, F012TH, TF 30.3208.02, SwitchDoc F016TH. + * Devices supported: + * - Ambient Weather F007TH Thermo-Hygrometer. + * - Ambient Weather F012TH Indoor/Display Thermo-Hygrometer. + * - TFA senders 30.3208.02 from the TFA "Klima-Monitor" 30.3054, + * - SwitchDoc Labs F016TH. + * This decoder handles the 433mhz/868mhz thermo-hygrometers. + * The 915mhz (WH*) family of devices use different modulation/encoding. + * Byte 0 Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 + * xxxxMMMM IIIIIIII BCCCTTTT TTTTTTTT HHHHHHHH MMMMMMMM + * - x: Unknown 0x04 on F007TH/F012TH + * - M: Model Number?, 0x05 on F007TH/F012TH/SwitchDocLabs F016TH + * - I: ID byte (8 bits), volatie, changes at power up, + * - B: Battery Low + * - C: Channel (3 bits 1-8) - F007TH set by Dip switch, F012TH soft setting + * - T: Temperature 12 bits - Fahrenheit * 10 + 400 + * - H: Humidity (8 bits) + * - M: Message integrity check LFSR Digest-8, gen 0x98, key 0x3e, init 0x64 + * + * three repeats without gap + * full preamble is 0x00145 (the last bits might not be fixed, e.g. 0x00146) + * and on decoding also 0xffd45 + */ + +#define AMBIENT_WEATHER_PACKET_HEADER_1 0xFFD440000000000 //0xffd45 .. 0xffd46 +#define AMBIENT_WEATHER_PACKET_HEADER_2 0x001440000000000 //0x00145 .. 0x00146 +#define AMBIENT_WEATHER_PACKET_HEADER_MASK 0xFFFFC0000000000 + +static const SubGhzBlockConst ws_protocol_ambient_weather_const = { + .te_short = 500, + .te_long = 1000, + .te_delta = 120, + .min_count_bit_for_found = 48, +}; + +struct WSProtocolDecoderAmbient_Weather { + SubGhzProtocolDecoderBase base; + + SubGhzBlockDecoder decoder; + WSBlockGeneric generic; + ManchesterState manchester_saved_state; + uint16_t header_count; +}; + +struct WSProtocolEncoderAmbient_Weather { + SubGhzProtocolEncoderBase base; + + SubGhzProtocolBlockEncoder encoder; + WSBlockGeneric generic; +}; + +const SubGhzProtocolDecoder ws_protocol_ambient_weather_decoder = { + .alloc = ws_protocol_decoder_ambient_weather_alloc, + .free = ws_protocol_decoder_ambient_weather_free, + + .feed = ws_protocol_decoder_ambient_weather_feed, + .reset = ws_protocol_decoder_ambient_weather_reset, + + .get_hash_data = ws_protocol_decoder_ambient_weather_get_hash_data, + .serialize = ws_protocol_decoder_ambient_weather_serialize, + .deserialize = ws_protocol_decoder_ambient_weather_deserialize, + .get_string = ws_protocol_decoder_ambient_weather_get_string, +}; + +const SubGhzProtocolEncoder ws_protocol_ambient_weather_encoder = { + .alloc = NULL, + .free = NULL, + + .deserialize = NULL, + .stop = NULL, + .yield = NULL, +}; + +const SubGhzProtocol ws_protocol_ambient_weather = { + .name = WS_PROTOCOL_AMBIENT_WEATHER_NAME, + .type = SubGhzProtocolWeatherStation, + .flag = SubGhzProtocolFlag_433 | SubGhzProtocolFlag_315 | SubGhzProtocolFlag_868 | + SubGhzProtocolFlag_AM | SubGhzProtocolFlag_Decodable, + + .decoder = &ws_protocol_ambient_weather_decoder, + .encoder = &ws_protocol_ambient_weather_encoder, +}; + +void* ws_protocol_decoder_ambient_weather_alloc(SubGhzEnvironment* environment) { + UNUSED(environment); + WSProtocolDecoderAmbient_Weather* instance = malloc(sizeof(WSProtocolDecoderAmbient_Weather)); + instance->base.protocol = &ws_protocol_ambient_weather; + instance->generic.protocol_name = instance->base.protocol->name; + return instance; +} + +void ws_protocol_decoder_ambient_weather_free(void* context) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* instance = context; + free(instance); +} + +void ws_protocol_decoder_ambient_weather_reset(void* context) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* instance = context; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); +} + +static bool ws_protocol_ambient_weather_check_crc(WSProtocolDecoderAmbient_Weather* instance) { + uint8_t msg[] = { + 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}; + + uint8_t crc = subghz_protocol_blocks_lfsr_digest8(msg, 5, 0x98, 0x3e) ^ 0x64; + return (crc == (uint8_t)(instance->decoder.decode_data & 0xFF)); +} + +/** + * Analysis of received data + * @param instance Pointer to a WSBlockGeneric* instance + */ +static void ws_protocol_ambient_weather_remote_controller(WSBlockGeneric* instance) { + instance->id = (instance->data >> 32) & 0xFF; + instance->battery_low = (instance->data >> 31) & 1; + instance->channel = ((instance->data >> 28) & 0x07) + 1; + instance->temp = ws_block_generic_fahrenheit_to_celsius( + ((float)((instance->data >> 16) & 0x0FFF) - 400.0f) / 10.0f); + instance->humidity = (instance->data >> 8) & 0xFF; + instance->btn = WS_NO_BTN; + + // ToDo maybe it won't be needed + /* + Sanity checks to reduce false positives and other bad data + Packets with Bad data often pass the MIC check. + - humidity > 100 (such as 255) and + - temperatures > 140 F (such as 369.5 F and 348.8 F + Specs in the F007TH and F012TH manuals state the range is: + - Temperature: -40 to 140 F + - Humidity: 10 to 99% + @todo - sanity check b[0] "model number" + - 0x45 - F007TH and F012TH + - 0x?5 - SwitchDocLabs F016TH temperature sensor (based on comment b[0] & 0x0f == 5) + - ? - TFA 30.3208.02 + if (instance->humidity < 0 || instance->humidity > 100) { + ERROR; + } + + if (instance->temp < -40.0 || instance->temp > 140.0) { + ERROR; + } + */ +} + +void ws_protocol_decoder_ambient_weather_feed(void* context, bool level, uint32_t duration) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* instance = context; + + ManchesterEvent event = ManchesterEventReset; + if(!level) { + if(DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_short) < + ws_protocol_ambient_weather_const.te_delta) { + event = ManchesterEventShortLow; + } else if( + DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_long) < + ws_protocol_ambient_weather_const.te_delta * 2) { + event = ManchesterEventLongLow; + } + } else { + if(DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_short) < + ws_protocol_ambient_weather_const.te_delta) { + event = ManchesterEventShortHigh; + } else if( + DURATION_DIFF(duration, ws_protocol_ambient_weather_const.te_long) < + ws_protocol_ambient_weather_const.te_delta * 2) { + event = ManchesterEventLongHigh; + } + } + if(event != ManchesterEventReset) { + bool data; + bool data_ok = manchester_advance( + instance->manchester_saved_state, event, &instance->manchester_saved_state, &data); + + if(data_ok) { + instance->decoder.decode_data = (instance->decoder.decode_data << 1) | !data; + } + + if(((instance->decoder.decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == + AMBIENT_WEATHER_PACKET_HEADER_1) || + ((instance->decoder.decode_data & AMBIENT_WEATHER_PACKET_HEADER_MASK) == + AMBIENT_WEATHER_PACKET_HEADER_2)) { + if(ws_protocol_ambient_weather_check_crc(instance)) { + instance->decoder.decode_data = instance->decoder.decode_data; + instance->generic.data = instance->decoder.decode_data; + instance->generic.data_count_bit = + ws_protocol_ambient_weather_const.min_count_bit_for_found; + ws_protocol_ambient_weather_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; + } + } + } else { + instance->decoder.decode_data = 0; + instance->decoder.decode_count_bit = 0; + manchester_advance( + instance->manchester_saved_state, + ManchesterEventReset, + &instance->manchester_saved_state, + NULL); + } +} + +uint8_t ws_protocol_decoder_ambient_weather_get_hash_data(void* context) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* instance = context; + return subghz_protocol_blocks_get_hash_data( + &instance->decoder, (instance->decoder.decode_count_bit / 8) + 1); +} + +bool ws_protocol_decoder_ambient_weather_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* instance = context; + return ws_block_generic_serialize(&instance->generic, flipper_format, preset); +} + +bool ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* instance = context; + bool ret = false; + do { + if(!ws_block_generic_deserialize(&instance->generic, flipper_format)) { + break; + } + if(instance->generic.data_count_bit != + ws_protocol_ambient_weather_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_ambient_weather_get_string(void* context, FuriString* output) { + furi_assert(context); + WSProtocolDecoderAmbient_Weather* 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/ambient_weather.h b/applications/plugins/weather_station/protocols/ambient_weather.h new file mode 100644 index 000000000..04cc5819c --- /dev/null +++ b/applications/plugins/weather_station/protocols/ambient_weather.h @@ -0,0 +1,79 @@ +#pragma once + +#include + +#include +#include +#include +#include "ws_generic.h" +#include + +#define WS_PROTOCOL_AMBIENT_WEATHER_NAME "Ambient_Weather" + +typedef struct WSProtocolDecoderAmbient_Weather WSProtocolDecoderAmbient_Weather; +typedef struct WSProtocolEncoderAmbient_Weather WSProtocolEncoderAmbient_Weather; + +extern const SubGhzProtocolDecoder ws_protocol_ambient_weather_decoder; +extern const SubGhzProtocolEncoder ws_protocol_ambient_weather_encoder; +extern const SubGhzProtocol ws_protocol_ambient_weather; + +/** + * Allocate WSProtocolDecoderAmbient_Weather. + * @param environment Pointer to a SubGhzEnvironment instance + * @return WSProtocolDecoderAmbient_Weather* pointer to a WSProtocolDecoderAmbient_Weather instance + */ +void* ws_protocol_decoder_ambient_weather_alloc(SubGhzEnvironment* environment); + +/** + * Free WSProtocolDecoderAmbient_Weather. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance + */ +void ws_protocol_decoder_ambient_weather_free(void* context); + +/** + * Reset decoder WSProtocolDecoderAmbient_Weather. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance + */ +void ws_protocol_decoder_ambient_weather_reset(void* context); + +/** + * Parse a raw sequence of levels and durations received from the air. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance + * @param level Signal level true-high false-low + * @param duration Duration of this level in, us + */ +void ws_protocol_decoder_ambient_weather_feed(void* context, bool level, uint32_t duration); + +/** + * Getting the hash sum of the last randomly received parcel. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance + * @return hash Hash sum + */ +uint8_t ws_protocol_decoder_ambient_weather_get_hash_data(void* context); + +/** + * Serialize data WSProtocolDecoderAmbient_Weather. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather 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_ambient_weather_serialize( + void* context, + FlipperFormat* flipper_format, + SubGhzRadioPreset* preset); + +/** + * Deserialize data WSProtocolDecoderAmbient_Weather. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance + * @param flipper_format Pointer to a FlipperFormat instance + * @return true On success + */ +bool ws_protocol_decoder_ambient_weather_deserialize(void* context, FlipperFormat* flipper_format); + +/** + * Getting a textual representation of the received data. + * @param context Pointer to a WSProtocolDecoderAmbient_Weather instance + * @param output Resulting text + */ +void ws_protocol_decoder_ambient_weather_get_string(void* context, FuriString* output); diff --git a/applications/plugins/weather_station/protocols/gt_wt_03.c b/applications/plugins/weather_station/protocols/gt_wt_03.c index 1492374c9..04bca9ac1 100644 --- a/applications/plugins/weather_station/protocols/gt_wt_03.c +++ b/applications/plugins/weather_station/protocols/gt_wt_03.c @@ -4,7 +4,7 @@ /* * Help - * https://github.com/merbanan/rtl_433/blob/5f0ff6db624270a4598958ab9dd79bb385ced3ef/src/devices/gt_wt_03.c + * https://github.com/merbanan/rtl_433/blob/master/src/devices/gt_wt_03.c * * * Globaltronics GT-WT-03 sensor on 433.92MHz. diff --git a/applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.c b/applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.c index 828d49be7..d4b89be87 100644 --- a/applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.c +++ b/applications/plugins/weather_station/protocols/lacrosse_tx141thbv2.c @@ -4,7 +4,7 @@ /* * Help - * https://github.com/merbanan/rtl_433/blob/7e83cfd27d14247b6c3c81732bfe4a4f9a974d30/src/devices/lacrosse_tx141x.c + * https://github.com/merbanan/rtl_433/blob/master/src/devices/lacrosse_tx141x.c * * iiii iiii | bkcc tttt | tttt tttt | hhhh hhhh | cccc cccc | u * - i: identification; changes on battery switch diff --git a/applications/plugins/weather_station/protocols/nexus_th.c b/applications/plugins/weather_station/protocols/nexus_th.c index a2ab0f412..c3d823eda 100644 --- a/applications/plugins/weather_station/protocols/nexus_th.c +++ b/applications/plugins/weather_station/protocols/nexus_th.c @@ -4,7 +4,7 @@ /* * Help - * https://github.com/merbanan/rtl_433/blob/ef2d37cf51e3264d11cde9149ef87de2f0a4d37a/src/devices/nexus.c + * https://github.com/merbanan/rtl_433/blob/master/src/devices/nexus.c * * Nexus sensor protocol with ID, temperature and optional humidity * also FreeTec (Pearl) NC-7345 sensors for FreeTec Weatherstation NC-7344, diff --git a/applications/plugins/weather_station/protocols/protocol_items.c b/applications/plugins/weather_station/protocols/protocol_items.c index 3ec9e995a..d7f6458ab 100644 --- a/applications/plugins/weather_station/protocols/protocol_items.c +++ b/applications/plugins/weather_station/protocols/protocol_items.c @@ -9,6 +9,7 @@ const SubGhzProtocol* weather_station_protocol_registry_items[] = { &ws_protocol_lacrosse_tx141thbv2, &ws_protocol_oregon2, &ws_protocol_acurite_592txr, + &ws_protocol_ambient_weather, }; 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 8f3eb53d7..76c085ab4 100644 --- a/applications/plugins/weather_station/protocols/protocol_items.h +++ b/applications/plugins/weather_station/protocols/protocol_items.h @@ -9,5 +9,6 @@ #include "lacrosse_tx141thbv2.h" #include "oregon2.h" #include "acurite_592txr.h" +#include "ambient_weather.h" extern const SubGhzProtocolRegistry weather_station_protocol_registry; diff --git a/applications/services/gui/application.fam b/applications/services/gui/application.fam index 76ace7fab..193b9dfd3 100644 --- a/applications/services/gui/application.fam +++ b/applications/services/gui/application.fam @@ -12,6 +12,7 @@ App( order=70, sdk_headers=[ "gui.h", + "icon_i.h", "elements.h", "canvas_i.h", "view_dispatcher.h", diff --git a/applications/services/gui/view_port.c b/applications/services/gui/view_port.c index baa8f7bd2..ffd01450b 100644 --- a/applications/services/gui/view_port.c +++ b/applications/services/gui/view_port.c @@ -7,61 +7,51 @@ // TODO add mutex to view_port ops -static void view_port_remap_buttons_vertical(InputEvent* event) { - switch(event->key) { - case InputKeyUp: - event->key = InputKeyRight; - break; - case InputKeyDown: - event->key = InputKeyLeft; - break; - case InputKeyRight: - event->key = InputKeyDown; - break; - case InputKeyLeft: - event->key = InputKeyUp; - break; - default: - break; - } -} +_Static_assert(ViewPortOrientationMAX == 4, "Incorrect ViewPortOrientation count"); +_Static_assert( + (ViewPortOrientationHorizontal == 0 && ViewPortOrientationHorizontalFlip == 1 && + ViewPortOrientationVertical == 2 && ViewPortOrientationVerticalFlip == 3), + "Incorrect ViewPortOrientation order"); +_Static_assert(InputKeyMAX == 6, "Incorrect InputKey count"); +_Static_assert( + (InputKeyUp == 0 && InputKeyDown == 1 && InputKeyRight == 2 && InputKeyLeft == 3 && + InputKeyOk == 4 && InputKeyBack == 5), + "Incorrect InputKey order"); -static void view_port_remap_buttons_vertical_flip(InputEvent* event) { - switch(event->key) { - case InputKeyUp: - event->key = InputKeyLeft; - break; - case InputKeyDown: - event->key = InputKeyRight; - break; - case InputKeyRight: - event->key = InputKeyUp; - break; - case InputKeyLeft: - event->key = InputKeyDown; - break; - default: - break; - } -} +/** InputKey directional keys mappings for different screen orientations +* +*/ +static const InputKey view_port_input_mapping[ViewPortOrientationMAX][InputKeyMAX] = { + {InputKeyUp, + InputKeyDown, + InputKeyRight, + InputKeyLeft, + InputKeyOk, + InputKeyBack}, //ViewPortOrientationHorizontal + {InputKeyDown, + InputKeyUp, + InputKeyLeft, + InputKeyRight, + InputKeyOk, + InputKeyBack}, //ViewPortOrientationHorizontalFlip + {InputKeyRight, + InputKeyLeft, + InputKeyDown, + InputKeyUp, + InputKeyOk, + InputKeyBack}, //ViewPortOrientationVertical + {InputKeyLeft, + InputKeyRight, + InputKeyUp, + InputKeyDown, + InputKeyOk, + InputKeyBack}, //ViewPortOrientationVerticalFlip +}; -static void view_port_remap_buttons_horizontal_flip(InputEvent* event) { - switch(event->key) { - case InputKeyUp: - event->key = InputKeyDown; - break; - case InputKeyDown: - event->key = InputKeyUp; - break; - case InputKeyRight: - event->key = InputKeyLeft; - break; - case InputKeyLeft: - event->key = InputKeyRight; - break; - default: - break; - } +// Remaps directional pad buttons on Flipper based on ViewPort orientation +static void view_port_map_input(InputEvent* event, ViewPortOrientation orientation) { + furi_assert(orientation < ViewPortOrientationMAX && event->key < InputKeyMAX); + event->key = view_port_input_mapping[orientation][event->key]; } static void view_port_setup_canvas_orientation(const ViewPort* view_port, Canvas* canvas) { @@ -170,19 +160,7 @@ void view_port_input(ViewPort* view_port, InputEvent* event) { if(view_port->input_callback) { ViewPortOrientation orientation = view_port_get_orientation(view_port); - switch(orientation) { - case ViewPortOrientationHorizontalFlip: - view_port_remap_buttons_horizontal_flip(event); - break; - case ViewPortOrientationVertical: - view_port_remap_buttons_vertical(event); - break; - case ViewPortOrientationVerticalFlip: - view_port_remap_buttons_vertical_flip(event); - break; - default: - break; - } + view_port_map_input(event, orientation); view_port->input_callback(event, view_port->input_callback_context); } } diff --git a/applications/services/gui/view_port.h b/applications/services/gui/view_port.h index 169681ac0..703e99248 100644 --- a/applications/services/gui/view_port.h +++ b/applications/services/gui/view_port.h @@ -19,6 +19,7 @@ typedef enum { ViewPortOrientationHorizontalFlip, ViewPortOrientationVertical, ViewPortOrientationVerticalFlip, + ViewPortOrientationMAX, /**< Special value, don't use it */ } ViewPortOrientation; /** ViewPort Draw callback diff --git a/applications/services/input/input.c b/applications/services/input/input.c index 7b8433aef..d1aef9e8a 100644 --- a/applications/services/input/input.c +++ b/applications/services/input/input.c @@ -60,8 +60,9 @@ const char* input_get_type_name(InputType type) { return "Long"; case InputTypeRepeat: return "Repeat"; + default: + return "Unknown"; } - return "Unknown"; } int32_t input_srv(void* p) { diff --git a/applications/services/input/input.h b/applications/services/input/input.h index bd0ba3902..172b16361 100644 --- a/applications/services/input/input.h +++ b/applications/services/input/input.h @@ -22,6 +22,7 @@ typedef enum { InputTypeShort, /**< Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */ InputTypeLong, /**< Long event, emmited after INPUT_LONG_PRESS interval, asynchronouse to InputTypeRelease */ InputTypeRepeat, /**< Repeat event, emmited with INPUT_REPEATE_PRESS period after InputTypeLong event */ + InputTypeMAX, /**< Special value for exceptional */ } InputType; /** Input Event, dispatches with FuriPubSub */ diff --git a/applications/services/rpc/rpc_storage.c b/applications/services/rpc/rpc_storage.c index 1b545b414..e28998e13 100644 --- a/applications/services/rpc/rpc_storage.c +++ b/applications/services/rpc/rpc_storage.c @@ -405,6 +405,10 @@ static void rpc_system_storage_write_process(const PB_Main* request, void* conte if(!fs_operation_success) { send_response = true; command_status = rpc_system_storage_get_file_error(file); + if(command_status == PB_CommandStatus_OK) { + // Report errors not handled by underlying APIs + command_status = PB_CommandStatus_ERROR_STORAGE_INTERNAL; + } } if(send_response) { diff --git a/assets/dolphin/external/manifest.txt b/assets/dolphin/external/manifest.txt index 71dc735ac..7be04dc86 100644 --- a/assets/dolphin/external/manifest.txt +++ b/assets/dolphin/external/manifest.txt @@ -55,7 +55,7 @@ Min butthurt: 0 Max butthurt: 14 Min level: 1 Max level: 30 -Weight: 14 +Weight: 3 Name: L1_Painting_128x64 Min butthurt: 0 diff --git a/assets/icons/StatusBar/Background_128x11.png b/assets/icons/StatusBar/Background_128x11.png index e43b32d16..78ef029ae 100644 Binary files a/assets/icons/StatusBar/Background_128x11.png and b/assets/icons/StatusBar/Background_128x11.png differ diff --git a/firmware.scons b/firmware.scons index 63a1aa3f7..a0c1ab339 100644 --- a/firmware.scons +++ b/firmware.scons @@ -1,6 +1,7 @@ Import("ENV", "fw_build_meta") from SCons.Errors import UserError +from SCons.Node import FS import itertools from fbt_extra.util import ( @@ -14,7 +15,6 @@ env = ENV.Clone( ("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}), "fwbin", "fbt_apps", - "fbt_sdk", ], COMPILATIONDB_USE_ABSPATH=False, BUILD_DIR=fw_build_meta["build_dir"], @@ -112,7 +112,9 @@ lib_targets = env.BuildModules( # Now, env is fully set up with everything to build apps -fwenv = env.Clone() +fwenv = env.Clone(FW_ARTIFACTS=[]) + +fw_artifacts = fwenv["FW_ARTIFACTS"] # Set up additional app-specific build flags SConscript("site_scons/firmwareopts.scons", exports={"ENV": fwenv}) @@ -130,7 +132,14 @@ if extra_int_apps := GetOption("extra_int_apps"): if fwenv["FAP_EXAMPLES"]: fwenv.Append(APPDIRS=[("applications/examples", False)]) -fwenv.LoadApplicationManifests() +for app_dir, _ in env["APPDIRS"]: + app_dir_node = env.Dir("#").Dir(app_dir) + + for entry in app_dir_node.glob("*"): + if isinstance(entry, FS.Dir) and not str(entry).startswith("."): + fwenv.LoadAppManifest(entry) + + fwenv.PrepareApplicationsBuild() # Build external apps @@ -138,6 +147,7 @@ if env["IS_BASE_FIRMWARE"]: extapps = fwenv["FW_EXTAPPS"] = SConscript( "site_scons/extapps.scons", exports={"ENV": fwenv} ) + fw_artifacts.append(extapps["sdk_tree"]) # Add preprocessor definitions for current set of apps @@ -220,7 +230,10 @@ Depends(fwelf, lib_targets) AddPostAction(fwelf, fwenv["APPBUILD_DUMP"]) AddPostAction( fwelf, - Action('${PYTHON3} "${ROOT_DIR}/scripts/fwsize.py" elf ${TARGET}', "Firmware size"), + Action( + '${PYTHON3} "${BIN_SIZE_SCRIPT}" elf ${TARGET}', + "Firmware size", + ), ) # Produce extra firmware files @@ -228,7 +241,7 @@ fwhex = fwenv["FW_HEX"] = fwenv.HEXBuilder("${FIRMWARE_BUILD_CFG}") fwbin = fwenv["FW_BIN"] = fwenv.BINBuilder("${FIRMWARE_BUILD_CFG}") AddPostAction( fwbin, - Action('@${PYTHON3} "${ROOT_DIR}/scripts/fwsize.py" bin ${TARGET}'), + Action('@${PYTHON3} "${BIN_SIZE_SCRIPT}" bin ${TARGET}'), ) fwdfu = fwenv["FW_DFU"] = fwenv.DFUBuilder("${FIRMWARE_BUILD_CFG}") @@ -238,12 +251,14 @@ fwdump = fwenv.ObjDump("${FIRMWARE_BUILD_CFG}") Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_list", fwdump) -fw_artifacts = fwenv["FW_ARTIFACTS"] = [ - fwhex, - fwbin, - fwdfu, - fwenv["FW_VERSION_JSON"], -] +fw_artifacts.extend( + [ + fwhex, + fwbin, + fwdfu, + fwenv["FW_VERSION_JSON"], + ] +) fwcdb = fwenv.CompilationDatabase() @@ -272,34 +287,5 @@ if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS): Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_all", fw_artifacts) -if fwenv["IS_BASE_FIRMWARE"]: - sdk_source = fwenv.SDKPrebuilder( - "sdk_origin", - # Deps on root SDK headers and generated files - (fwenv["SDK_HEADERS"], fwenv["FW_ASSETS_HEADERS"]), - ) - # Extra deps on headers included in deeper levels - Depends(sdk_source, fwenv.ProcessSdkDepends("sdk_origin.d")) - - fwenv["SDK_DIR"] = fwenv.Dir("sdk") - sdk_tree = fwenv.SDKTree(fwenv["SDK_DIR"], "sdk_origin") - fw_artifacts.append(sdk_tree) - # AlwaysBuild(sdk_tree) - Alias("sdk_tree", sdk_tree) - - sdk_apicheck = fwenv.SDKSymUpdater(fwenv["SDK_DEFINITION"], "sdk_origin") - Precious(sdk_apicheck) - NoClean(sdk_apicheck) - AlwaysBuild(sdk_apicheck) - Alias("sdk_check", sdk_apicheck) - - sdk_apisyms = fwenv.SDKSymGenerator( - "assets/compiled/symbols.h", fwenv["SDK_DEFINITION"] - ) - Alias("api_syms", sdk_apisyms) - - if fwenv["FORCE"]: - fwenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms) - Return("fwenv") diff --git a/firmware/SConscript b/firmware/SConscript index d6715f124..23fbcc661 100644 --- a/firmware/SConscript +++ b/firmware/SConscript @@ -2,11 +2,10 @@ Import("env") env.Append( LINT_SOURCES=["firmware"], - # SDK_HEADERS=[env.File("#/firmware/targets/furi_hal_include/furi_hal.h")], SDK_HEADERS=[ - *env.GlobRecursive("*.h", "#/firmware/targets/furi_hal_include", "*_i.h"), - *env.GlobRecursive("*.h", "#/firmware/targets/f${TARGET_HW}/furi_hal", "*_i.h"), - File("#/firmware/targets/f7/platform_specific/intrinsic_export.h"), + *env.GlobRecursive("*.h", "targets/furi_hal_include", "*_i.h"), + *env.GlobRecursive("*.h", "targets/f${TARGET_HW}/furi_hal", "*_i.h"), + File("targets/f7/platform_specific/intrinsic_export.h"), File("#/firmware/targets/furi_hal_include/furi_hal_subghz.h"), ], ) diff --git a/firmware/targets/f7/api_symbols.csv b/firmware/targets/f7/api_symbols.csv index a3e92db7b..3c539b773 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,+,8.2,, +Version,+,8.4,, Header,+,applications/services/bt/bt_service/bt.h,, Header,+,applications/services/cli/cli.h,, Header,+,applications/services/cli/cli_vcp.h,, @@ -8,6 +8,7 @@ Header,+,applications/services/dolphin/dolphin.h,, Header,+,applications/services/gui/canvas_i.h,, Header,+,applications/services/gui/elements.h,, Header,+,applications/services/gui/gui.h,, +Header,+,applications/services/gui/icon_i.h,, Header,+,applications/services/gui/modules/button_menu.h,, Header,+,applications/services/gui/modules/button_panel.h,, Header,+,applications/services/gui/modules/byte_input.h,, @@ -123,6 +124,33 @@ Header,+,lib/lfrfid/lfrfid_raw_worker.h,, Header,+,lib/lfrfid/lfrfid_worker.h,, Header,+,lib/lfrfid/protocols/lfrfid_protocols.h,, Header,+,lib/lfrfid/tools/bit_lib.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_button.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_consumer.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_desktop.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_device.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_game.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_keyboard.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_led.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_ordinal.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_power.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_simulation.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_sport.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_telephony.h,, +Header,+,lib/libusb_stm32/inc/hid_usage_vr.h,, +Header,+,lib/libusb_stm32/inc/usb.h,, +Header,+,lib/libusb_stm32/inc/usb_cdc.h,, +Header,+,lib/libusb_stm32/inc/usb_cdca.h,, +Header,+,lib/libusb_stm32/inc/usb_cdce.h,, +Header,+,lib/libusb_stm32/inc/usb_cdci.h,, +Header,+,lib/libusb_stm32/inc/usb_cdcp.h,, +Header,+,lib/libusb_stm32/inc/usb_cdcw.h,, +Header,+,lib/libusb_stm32/inc/usb_dfu.h,, +Header,+,lib/libusb_stm32/inc/usb_hid.h,, +Header,+,lib/libusb_stm32/inc/usb_std.h,, +Header,+,lib/libusb_stm32/inc/usb_tmc.h,, +Header,+,lib/libusb_stm32/inc/usbd_core.h,, +Header,+,lib/mbedtls/include/mbedtls/des.h,, +Header,+,lib/mbedtls/include/mbedtls/sha1.h,, Header,+,lib/micro-ecc/uECC.h,, Header,+,lib/one_wire/ibutton/ibutton_worker.h,, Header,+,lib/one_wire/maxim_crc.h,, @@ -417,6 +445,7 @@ Function,-,_system_r,int,"_reent*, const char*" Function,-,_tempnam_r,char*,"_reent*, const char*, const char*" Function,-,_tmpfile_r,FILE*,_reent* Function,-,_tmpnam_r,char*,"_reent*, char*" +Function,-,_tzset_r,void,_reent* Function,-,_ungetc_r,int,"_reent*, int, FILE*" Function,-,_unsetenv_r,int,"_reent*, const char*" Function,-,_vasiprintf_r,int,"_reent*, char**, const char*, __gnuc_va_list" @@ -464,6 +493,8 @@ Function,+,args_read_hex_bytes,_Bool,"FuriString*, uint8_t*, size_t" Function,+,args_read_int_and_trim,_Bool,"FuriString*, int*" Function,+,args_read_probably_quoted_string_and_trim,_Bool,"FuriString*, FuriString*" Function,+,args_read_string_and_trim,_Bool,"FuriString*, FuriString*" +Function,-,asctime,char*,const tm* +Function,-,asctime_r,char*,"const tm*, char*" Function,-,asin,double,double Function,-,asinf,float,float Function,-,asinh,double,double @@ -645,6 +676,7 @@ Function,+,cli_read_timeout,size_t,"Cli*, uint8_t*, size_t, uint32_t" Function,+,cli_session_close,void,Cli* Function,+,cli_session_open,void,"Cli*, void*" Function,+,cli_write,void,"Cli*, const uint8_t*, size_t" +Function,-,clock,clock_t, Function,-,copysign,double,"double, double" Function,-,copysignf,float,"float, float" Function,-,copysignl,long double,"long double, long double" @@ -657,6 +689,8 @@ Function,-,cosl,long double,long double Function,+,crc32_calc_buffer,uint32_t,"uint32_t, const void*, size_t" Function,+,crc32_calc_file,uint32_t,"File*, const FileCrcProgressCb, void*" Function,-,ctermid,char*,char* +Function,-,ctime,char*,const time_t* +Function,-,ctime_r,char*,"const time_t*, char*" Function,-,cuserid,char*,char* Function,+,delete_mutex,_Bool,ValueMutex* Function,+,dialog_ex_alloc,DialogEx*, @@ -683,6 +717,7 @@ Function,+,dialog_message_set_icon,void,"DialogMessage*, const Icon*, uint8_t, u Function,+,dialog_message_set_text,void,"DialogMessage*, const char*, uint8_t, uint8_t, Align, Align" Function,+,dialog_message_show,DialogMessageButton,"DialogsApp*, const DialogMessage*" Function,+,dialog_message_show_storage_error,void,"DialogsApp*, const char*" +Function,-,difftime,double,"time_t, time_t" Function,-,digital_signal_alloc,DigitalSignal*,uint32_t Function,-,digital_signal_append,_Bool,"DigitalSignal*, DigitalSignal*" Function,-,digital_signal_free,void,DigitalSignal* @@ -1502,6 +1537,8 @@ Function,-,getenv,char*,const char* Function,-,gets,char*,char* Function,-,getsubopt,int,"char**, char**, char**" Function,-,getw,int,FILE* +Function,-,gmtime,tm*,const time_t* +Function,-,gmtime_r,tm*,"const time_t*, tm*" Function,+,gui_add_framebuffer_callback,void,"Gui*, GuiCanvasCommitCallback, void*" Function,+,gui_add_view_port,void,"Gui*, ViewPort*, GuiLayer" Function,+,gui_get_framebuffer_size,size_t,Gui* @@ -1701,6 +1738,8 @@ Function,+,loader_update_menu,void, Function,+,loading_alloc,Loading*, Function,+,loading_free,void,Loading* Function,+,loading_get_view,View*,Loading* +Function,-,localtime,tm*,const time_t* +Function,-,localtime_r,tm*,"const time_t*, tm*" Function,-,log,double,double Function,-,log10,double,double Function,-,log10f,float,float @@ -1729,6 +1768,36 @@ Function,+,manchester_encoder_advance,_Bool,"ManchesterEncoderState*, const _Boo Function,+,manchester_encoder_finish,ManchesterEncoderResult,ManchesterEncoderState* Function,+,manchester_encoder_reset,void,ManchesterEncoderState* Function,+,maxim_crc8,uint8_t,"const uint8_t*, const uint8_t, const uint8_t" +Function,-,mbedtls_des3_crypt_cbc,int,"mbedtls_des3_context*, int, size_t, unsigned char[8], const unsigned char*, unsigned char*" +Function,-,mbedtls_des3_crypt_ecb,int,"mbedtls_des3_context*, const unsigned char[8], unsigned char[8]" +Function,-,mbedtls_des3_free,void,mbedtls_des3_context* +Function,-,mbedtls_des3_init,void,mbedtls_des3_context* +Function,-,mbedtls_des3_set2key_dec,int,"mbedtls_des3_context*, const unsigned char[8 * 2]" +Function,-,mbedtls_des3_set2key_enc,int,"mbedtls_des3_context*, const unsigned char[8 * 2]" +Function,-,mbedtls_des3_set3key_dec,int,"mbedtls_des3_context*, const unsigned char[8 * 3]" +Function,-,mbedtls_des3_set3key_enc,int,"mbedtls_des3_context*, const unsigned char[8 * 3]" +Function,-,mbedtls_des_crypt_cbc,int,"mbedtls_des_context*, int, size_t, unsigned char[8], const unsigned char*, unsigned char*" +Function,-,mbedtls_des_crypt_ecb,int,"mbedtls_des_context*, const unsigned char[8], unsigned char[8]" +Function,-,mbedtls_des_free,void,mbedtls_des_context* +Function,-,mbedtls_des_init,void,mbedtls_des_context* +Function,-,mbedtls_des_key_check_key_parity,int,const unsigned char[8] +Function,-,mbedtls_des_key_check_weak,int,const unsigned char[8] +Function,-,mbedtls_des_key_set_parity,void,unsigned char[8] +Function,-,mbedtls_des_self_test,int,int +Function,-,mbedtls_des_setkey,void,"uint32_t[32], const unsigned char[8]" +Function,-,mbedtls_des_setkey_dec,int,"mbedtls_des_context*, const unsigned char[8]" +Function,-,mbedtls_des_setkey_enc,int,"mbedtls_des_context*, const unsigned char[8]" +Function,-,mbedtls_internal_sha1_process,int,"mbedtls_sha1_context*, const unsigned char[64]" +Function,-,mbedtls_platform_gmtime_r,tm*,"const mbedtls_time_t*, tm*" +Function,-,mbedtls_platform_zeroize,void,"void*, size_t" +Function,-,mbedtls_sha1,int,"const unsigned char*, size_t, unsigned char[20]" +Function,-,mbedtls_sha1_clone,void,"mbedtls_sha1_context*, const mbedtls_sha1_context*" +Function,-,mbedtls_sha1_finish,int,"mbedtls_sha1_context*, unsigned char[20]" +Function,-,mbedtls_sha1_free,void,mbedtls_sha1_context* +Function,-,mbedtls_sha1_init,void,mbedtls_sha1_context* +Function,-,mbedtls_sha1_self_test,int,int +Function,-,mbedtls_sha1_starts,int,mbedtls_sha1_context* +Function,-,mbedtls_sha1_update,int,"mbedtls_sha1_context*, const unsigned char*, size_t" Function,-,mblen,int,"const char*, size_t" Function,-,mbstowcs,size_t,"wchar_t*, const char*, size_t" Function,-,mbtowc,int,"wchar_t*, const char*, size_t" @@ -1769,6 +1838,7 @@ Function,-,mkostemps,int,"char*, int, int" Function,-,mkstemp,int,char* Function,-,mkstemps,int,"char*, int" Function,-,mktemp,char*,char* +Function,-,mktime,time_t,tm* Function,-,modf,double,"double, double*" Function,-,modff,float,"float, float*" Function,-,modfl,long double,"long double, long double*" @@ -1797,6 +1867,7 @@ Function,+,notification_message,void,"NotificationApp*, const NotificationSequen Function,+,notification_message_block,void,"NotificationApp*, const NotificationSequence*" Function,-,nrand48,long,unsigned short[3] Function,-,nrf24_configure,void,"FuriHalSpiBusHandle*, uint8_t, uint8_t*, uint8_t*, uint8_t, uint8_t, _Bool, _Bool" +Function,+,nrf24_deinit,void, Function,+,nrf24_find_channel,uint8_t,"FuriHalSpiBusHandle*, uint8_t*, uint8_t*, uint8_t, uint8_t, uint8_t, uint8_t, _Bool" Function,-,nrf24_flush_rx,uint8_t,FuriHalSpiBusHandle* Function,-,nrf24_flush_tx,uint8_t,FuriHalSpiBusHandle* @@ -2309,6 +2380,8 @@ Function,+,stream_write_vaformat,size_t,"Stream*, const char*, va_list" Function,-,strerror,char*,int Function,-,strerror_l,char*,"int, locale_t" Function,-,strerror_r,char*,"int, char*, size_t" +Function,-,strftime,size_t,"char*, size_t, const char*, const tm*" +Function,-,strftime_l,size_t,"char*, size_t, const char*, const tm*, locale_t" Function,+,string_stream_alloc,Stream*, Function,-,strlcat,size_t,"char*, const char*, size_t" Function,+,strlcpy,size_t,"char*, const char*, size_t" @@ -2323,6 +2396,8 @@ Function,-,strndup,char*,"const char*, size_t" Function,-,strnlen,size_t,"const char*, size_t" Function,-,strnstr,char*,"const char*, const char*, size_t" Function,-,strpbrk,char*,"const char*, const char*" +Function,-,strptime,char*,"const char*, const char*, tm*" +Function,-,strptime_l,char*,"const char*, const char*, tm*, locale_t" Function,+,strrchr,char*,"const char*, int" Function,-,strsep,char*,"char**, const char*" Function,-,strsignal,char*,int @@ -2933,6 +3008,7 @@ Function,-,tga_save,void,const char* Function,-,tgamma,double,double Function,-,tgammaf,float,float Function,-,tgammal,long double,long double +Function,-,time,time_t,time_t* Function,+,timerCalculateTimer,uint32_t,uint16_t Function,-,timerDelay,void,uint16_t Function,+,timerIsExpired,_Bool,uint32_t @@ -4005,6 +4081,7 @@ Function,-,u8x8_upscale_byte,uint16_t,uint8_t Function,-,u8x8_utf8_init,void,u8x8_t* Function,-,u8x8_utf8_next,uint16_t,"u8x8_t*, uint8_t" Function,-,u8x8_utoa,const char*,uint16_t +Function,-,tzset,void, Function,-,uECC_compress,void,"const uint8_t*, uint8_t*, uECC_Curve" Function,+,uECC_compute_public_key,int,"const uint8_t*, uint8_t*, uECC_Curve" Function,-,uECC_curve_private_key_size,int,uECC_Curve @@ -4263,10 +4340,13 @@ Variable,-,MSIRangeTable,const uint32_t[16], Variable,-,SmpsPrescalerTable,const uint32_t[4][6], Variable,+,SystemCoreClock,uint32_t, Variable,+,_ctype_,const char[], +Variable,-,_daylight,int, Variable,+,_global_impure_ptr,_reent*, Variable,+,_impure_ptr,_reent*, Variable,-,_sys_errlist,const char*[], Variable,-,_sys_nerr,int, +Variable,-,_timezone,long, +Variable,-,_tzname,char*[2], Variable,+,cli_vcp,CliSession, Variable,+,furi_hal_i2c_bus_external,FuriHalI2cBus, Variable,+,furi_hal_i2c_bus_power,FuriHalI2cBus, diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index d16c567e6..8d53ec48a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -20,6 +20,7 @@ typedef enum { InputKeyLeft, InputKeyOk, InputKeyBack, + InputKeyMAX, /**< Special value */ } InputKey; /* Light */ diff --git a/furi/core/check.c b/furi/core/check.c index cf1b790e8..1c2a005f3 100644 --- a/furi/core/check.c +++ b/furi/core/check.c @@ -1,6 +1,7 @@ #include "check.h" #include "common_defines.h" +#include #include #include #include @@ -24,30 +25,31 @@ PLACE_IN_SECTION("MB_MEM2") uint32_t __furi_check_registers[12] = {0}; : \ : "memory"); -#ifdef FURI_DEBUG -// Restore registers and halt MCU with bkpt mcu debug state -#define RESTORE_REGISTERS_AND_HALT_MCU() \ - asm volatile("ldr r12, =__furi_check_registers \n" \ - "ldm r12, {r0-r11} \n" \ - "loop%=: \n" \ - "bkpt 0x00 \n" \ - "wfi \n" \ - "b loop%= \n" \ - : \ - : \ - : "memory"); -#else -// Restore registers and halt MCU for release builds without bkpt instruction -#define RESTORE_REGISTERS_AND_HALT_MCU() \ - asm volatile("ldr r12, =__furi_check_registers \n" \ - "ldm r12, {r0-r11} \n" \ +/** Restore registers and halt MCU + * + * - Always use it with GET_MESSAGE_AND_STORE_REGISTERS + * - If debugger is(was) connected this routine will raise bkpt + * - If debugger is not connected then endless loop + * + */ +#define RESTORE_REGISTERS_AND_HALT_MCU(debug) \ + register const bool r0 asm("r0") = debug; \ + asm volatile("cbnz r0, with_debugger%= \n" \ + "ldr r12, =__furi_check_registers\n" \ + "ldm r12, {r0-r11} \n" \ "loop%=: \n" \ "wfi \n" \ - "b loop%= \n" \ - : \ + "b loop%= \n" \ + "with_debugger%=: \n" \ + "ldr r12, =__furi_check_registers\n" \ + "ldm r12, {r0-r11} \n" \ + "debug_loop%=: \n" \ + "bkpt 0x00 \n" \ + "wfi \n" \ + "b debug_loop%= \n" \ : \ + : "r"(r0) \ : "memory"); -#endif extern size_t xPortGetTotalHeapSize(void); extern size_t xPortGetFreeHeapSize(void); @@ -109,16 +111,19 @@ FURI_NORETURN void __furi_crash() { } __furi_print_heap_info(); -#ifdef FURI_DEBUG - furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); - furi_hal_console_puts("\033[0m\r\n"); - RESTORE_REGISTERS_AND_HALT_MCU(); -#else - furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message); - furi_hal_console_puts("\r\nRebooting system.\r\n"); - furi_hal_console_puts("\033[0m\r\n"); - furi_hal_power_reset(); -#endif + // Check if debug enabled by DAP + // https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture/ARMv7-M-Debug/Debug-register-support-in-the-SCS/Debug-Halting-Control-and-Status-Register--DHCSR?lang=en + bool debug = CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; + if(debug) { + furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n"); + furi_hal_console_puts("\033[0m\r\n"); + RESTORE_REGISTERS_AND_HALT_MCU(debug); + } else { + furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message); + furi_hal_console_puts("\r\nRebooting system.\r\n"); + furi_hal_console_puts("\033[0m\r\n"); + furi_hal_power_reset(); + } __builtin_unreachable(); } @@ -137,6 +142,11 @@ FURI_NORETURN void __furi_halt() { furi_hal_console_puts(__furi_check_message); furi_hal_console_puts("\r\nSystem halted. Bye-bye!\r\n"); furi_hal_console_puts("\033[0m\r\n"); - RESTORE_REGISTERS_AND_HALT_MCU(); + + // Check if debug enabled by DAP + // https://developer.arm.com/documentation/ddi0403/d/Debug-Architecture/ARMv7-M-Debug/Debug-register-support-in-the-SCS/Debug-Halting-Control-and-Status-Register--DHCSR?lang=en + bool debug = CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk; + RESTORE_REGISTERS_AND_HALT_MCU(debug); + __builtin_unreachable(); } diff --git a/lib/SConscript b/lib/SConscript index 0b1800a02..57cfb3f3a 100644 --- a/lib/SConscript +++ b/lib/SConscript @@ -17,13 +17,13 @@ env.Append( "lib/print", ], SDK_HEADERS=[ - File("#/lib/one_wire/one_wire_host_timing.h"), - File("#/lib/one_wire/one_wire_host.h"), - File("#/lib/one_wire/one_wire_slave.h"), - File("#/lib/one_wire/one_wire_device.h"), - File("#/lib/one_wire/ibutton/ibutton_worker.h"), - File("#/lib/one_wire/maxim_crc.h"), - File("#/lib/u8g2/u8g2.h"), + File("one_wire/one_wire_host_timing.h"), + File("one_wire/one_wire_host.h"), + File("one_wire/one_wire_slave.h"), + File("one_wire/one_wire_device.h"), + File("one_wire/ibutton/ibutton_worker.h"), + File("one_wire/maxim_crc.h"), + File("u8g2/u8g2.h"), ], ) diff --git a/lib/STM32CubeWB.scons b/lib/STM32CubeWB.scons index a00b07d98..cbdde9814 100644 --- a/lib/STM32CubeWB.scons +++ b/lib/STM32CubeWB.scons @@ -15,8 +15,8 @@ env.Append( ], SDK_HEADERS=[ *env.GlobRecursive("*_ll_*.h", "#/lib/STM32CubeWB/Drivers/STM32WBxx_HAL_Driver/Inc/", exclude="*usb.h"), - File("#/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h"), - File("#/lib/STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h"), + File("STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include/FreeRTOS.h"), + File("STM32CubeWB/Middlewares/Third_Party/FreeRTOS/Source/include/stream_buffer.h"), ], ) diff --git a/lib/drivers/SConscript b/lib/drivers/SConscript index 1ca613289..d82f09f1d 100644 --- a/lib/drivers/SConscript +++ b/lib/drivers/SConscript @@ -5,7 +5,7 @@ env.Append( "#/lib/drivers", ], SDK_HEADERS=[ - File("#/lib/drivers/nrf24.h"), + File("nrf24.h"), ], ) diff --git a/lib/drivers/nrf24.c b/lib/drivers/nrf24.c index 2905072d3..8b3776445 100644 --- a/lib/drivers/nrf24.c +++ b/lib/drivers/nrf24.c @@ -12,6 +12,13 @@ void nrf24_init() { furi_hal_gpio_write(nrf24_CE_PIN, false); } +void nrf24_deinit() { + furi_hal_spi_release(nrf24_HANDLE); + furi_hal_spi_bus_handle_deinit(nrf24_HANDLE); + furi_hal_gpio_write(nrf24_CE_PIN, false); + furi_hal_gpio_init(nrf24_CE_PIN, GpioModeAnalog, GpioPullNo, GpioSpeedLow); +} + void nrf24_spi_trx( FuriHalSpiBusHandle* handle, uint8_t* tx, diff --git a/lib/drivers/nrf24.h b/lib/drivers/nrf24.h index 584eaaea7..3cfcfe089 100644 --- a/lib/drivers/nrf24.h +++ b/lib/drivers/nrf24.h @@ -116,6 +116,11 @@ uint8_t nrf24_set_tx_mode(FuriHalSpiBusHandle* handle); */ void nrf24_init(); +/** Must call this when we end using nrf24 device + * + */ +void nrf24_deinit(); + /** Send flush rx command * * @param handle - pointer to FuriHalSpiHandle diff --git a/lib/flipper_application/SConscript b/lib/flipper_application/SConscript index 3a5e7f4db..9fbbf95d1 100644 --- a/lib/flipper_application/SConscript +++ b/lib/flipper_application/SConscript @@ -5,7 +5,7 @@ env.Append( "#/lib/flipper_application", ], SDK_HEADERS=[ - File("#/lib/flipper_application/flipper_application.h"), + File("flipper_application.h"), ], ) diff --git a/lib/flipper_format/SConscript b/lib/flipper_format/SConscript index 5e185678b..353da8035 100644 --- a/lib/flipper_format/SConscript +++ b/lib/flipper_format/SConscript @@ -5,8 +5,8 @@ env.Append( "#/lib/flipper_format", ], SDK_HEADERS=[ - File("#/lib/flipper_format/flipper_format.h"), - File("#/lib/flipper_format/flipper_format_i.h"), + File("flipper_format.h"), + File("flipper_format_i.h"), ], ) diff --git a/lib/infrared/SConscript b/lib/infrared/SConscript index 36baca34e..9a1543f00 100644 --- a/lib/infrared/SConscript +++ b/lib/infrared/SConscript @@ -6,9 +6,9 @@ env.Append( "#/lib/infrared/worker", ], SDK_HEADERS=[ - File("#/lib/infrared/worker/infrared_transmit.h"), - File("#/lib/infrared/worker/infrared_worker.h"), - File("#/lib/infrared/encoder_decoder/infrared.h"), + File("encoder_decoder/infrared.h"), + File("worker/infrared_worker.h"), + File("worker/infrared_transmit.h"), ], ) diff --git a/lib/lfrfid/SConscript b/lib/lfrfid/SConscript index 6177a9a50..69ea9d3c1 100644 --- a/lib/lfrfid/SConscript +++ b/lib/lfrfid/SConscript @@ -8,12 +8,12 @@ env.Append( "#/lib/lfrfid", ], SDK_HEADERS=[ - File("#/lib/lfrfid/lfrfid_worker.h"), - File("#/lib/lfrfid/lfrfid_raw_worker.h"), - File("#/lib/lfrfid/lfrfid_raw_file.h"), - File("#/lib/lfrfid/lfrfid_dict_file.h"), - File("#/lib/lfrfid/tools/bit_lib.h"), - File("#/lib/lfrfid/protocols/lfrfid_protocols.h"), + File("lfrfid_worker.h"), + File("lfrfid_raw_worker.h"), + File("lfrfid_raw_file.h"), + File("lfrfid_dict_file.h"), + File("tools/bit_lib.h"), + File("protocols/lfrfid_protocols.h"), ], ) diff --git a/lib/libusb_stm32.scons b/lib/libusb_stm32.scons index cb867fdbc..4838b7c50 100644 --- a/lib/libusb_stm32.scons +++ b/lib/libusb_stm32.scons @@ -7,6 +7,10 @@ env.Append( CPPDEFINES=[ ("USB_PMASIZE", "0x400"), ], + SDK_HEADERS=env.GlobRecursive( + "*.h", + Dir("libusb_stm32/inc"), + ), ) diff --git a/lib/mbedtls.scons b/lib/mbedtls.scons index b57221a49..79a4a2520 100644 --- a/lib/mbedtls.scons +++ b/lib/mbedtls.scons @@ -5,6 +5,10 @@ env.Append( "#/lib/mbedtls", "#/lib/mbedtls/include", ], + SDK_HEADERS=[ + File("mbedtls/include/mbedtls/des.h"), + File("mbedtls/include/mbedtls/sha1.h"), + ], ) diff --git a/lib/misc.scons b/lib/misc.scons index b7d8554b5..91ad276a0 100644 --- a/lib/misc.scons +++ b/lib/misc.scons @@ -13,7 +13,7 @@ env.Append( "PB_ENABLE_MALLOC", ], SDK_HEADERS=[ - File("#/lib/micro-ecc/uECC.h"), + File("micro-ecc/uECC.h"), ], ) diff --git a/lib/print/SConscript b/lib/print/SConscript index d4a55ab84..f34c8152f 100644 --- a/lib/print/SConscript +++ b/lib/print/SConscript @@ -98,7 +98,7 @@ for wrapped_fn in wrapped_fn_list: env.Append( SDK_HEADERS=[ - File("#/lib/print/wrappers.h"), + File("wrappers.h"), ], ) diff --git a/lib/subghz/SConscript b/lib/subghz/SConscript index 39c04969b..8fbec94ad 100644 --- a/lib/subghz/SConscript +++ b/lib/subghz/SConscript @@ -5,20 +5,20 @@ env.Append( "#/lib/subghz", ], SDK_HEADERS=[ - File("#/lib/subghz/environment.h"), - File("#/lib/subghz/receiver.h"), - File("#/lib/subghz/subghz_worker.h"), - File("#/lib/subghz/subghz_tx_rx_worker.h"), - File("#/lib/subghz/transmitter.h"), - File("#/lib/subghz/registry.h"), - File("#/lib/subghz/protocols/protocol_items.h"), - File("#/lib/subghz/protocols/raw.h"), - File("#/lib/subghz/blocks/const.h"), - File("#/lib/subghz/blocks/decoder.h"), - File("#/lib/subghz/blocks/encoder.h"), - File("#/lib/subghz/blocks/generic.h"), - File("#/lib/subghz/blocks/math.h"), - File("#/lib/subghz/subghz_setting.h"), + File("environment.h"), + File("receiver.h"), + File("subghz_worker.h"), + File("subghz_tx_rx_worker.h"), + File("transmitter.h"), + File("registry.h"), + File("protocols/protocol_items.h"), + File("protocols/raw.h"), + File("blocks/const.h"), + File("blocks/decoder.h"), + File("blocks/encoder.h"), + File("blocks/generic.h"), + File("blocks/math.h"), + File("subghz_setting.h"), ], ) diff --git a/lib/subghz/protocols/faac_slh.c b/lib/subghz/protocols/faac_slh.c index 0533172c3..7572bd8ab 100644 --- a/lib/subghz/protocols/faac_slh.c +++ b/lib/subghz/protocols/faac_slh.c @@ -462,10 +462,7 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* FURI_LOG_E(TAG, "Wrong number of bits in key"); break; } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } + uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; @@ -476,6 +473,11 @@ bool subghz_protocol_decoder_faac_slh_deserialize(void* context, FlipperFormat* } instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } res = true; } while(false); diff --git a/lib/subghz/protocols/keeloq.c b/lib/subghz/protocols/keeloq.c index 6887218d7..10993d706 100644 --- a/lib/subghz/protocols/keeloq.c +++ b/lib/subghz/protocols/keeloq.c @@ -371,15 +371,6 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl break; } - // Read manufacturer from file - if(flipper_format_read_string( - flipper_format, "Manufacture", instance->manufacture_from_file)) { - instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); - } else { - FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); - } - uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; @@ -390,6 +381,20 @@ bool subghz_protocol_encoder_keeloq_deserialize(void* context, FlipperFormat* fl instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "ENCODER: Missing Manufacture"); + } + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + subghz_protocol_keeloq_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); @@ -979,9 +984,22 @@ bool subghz_protocol_decoder_keeloq_serialize( subghz_protocol_keeloq_check_remote_controller( &instance->generic, instance->keystore, &instance->manufacture_name); + if(strcmp(instance->manufacture_name, "BFT") == 0) { + uint8_t seed_data[sizeof(uint32_t)] = {0}; + for(size_t i = 0; i < sizeof(uint32_t); i++) { + seed_data[sizeof(uint32_t) - i - 1] = (instance->generic.seed >> i * 8) & 0xFF; + } + if(res && !flipper_format_write_hex(flipper_format, "Seed", seed_data, sizeof(uint32_t))) { + FURI_LOG_E(TAG, "DECODER Serialize: Unable to add Seed"); + res = false; + } + instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | + seed_data[3]; + } + if(res && !flipper_format_write_string_cstr( flipper_format, "Manufacture", instance->manufacture_name)) { - FURI_LOG_E(TAG, "Unable to add manufacture name"); + FURI_LOG_E(TAG, "DECODER Serialize: Unable to add manufacture name"); res = false; } return res; @@ -1001,19 +1019,6 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl FURI_LOG_E(TAG, "Wrong number of bits in key"); break; } - if(!flipper_format_rewind(flipper_format)) { - FURI_LOG_E(TAG, "Rewind error"); - break; - } - - // Read manufacturer from file - if(flipper_format_read_string( - flipper_format, "Manufacture", instance->manufacture_from_file)) { - instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); - mfname = furi_string_get_cstr(instance->manufacture_from_file); - } else { - FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); - } uint8_t seed_data[sizeof(uint32_t)] = {0}; for(size_t i = 0; i < sizeof(uint32_t); i++) { @@ -1024,6 +1029,21 @@ bool subghz_protocol_decoder_keeloq_deserialize(void* context, FlipperFormat* fl } instance->generic.seed = seed_data[0] << 24 | seed_data[1] << 16 | seed_data[2] << 8 | seed_data[3]; + + // Read manufacturer from file + if(flipper_format_read_string( + flipper_format, "Manufacture", instance->manufacture_from_file)) { + instance->manufacture_name = furi_string_get_cstr(instance->manufacture_from_file); + mfname = furi_string_get_cstr(instance->manufacture_from_file); + } else { + FURI_LOG_D(TAG, "DECODER: Missing Manufacture"); + } + + if(!flipper_format_rewind(flipper_format)) { + FURI_LOG_E(TAG, "Rewind error"); + break; + } + res = true; } while(false); diff --git a/lib/subghz/protocols/nice_flor_s.c b/lib/subghz/protocols/nice_flor_s.c index c6bb8e040..bcc5c7466 100644 --- a/lib/subghz/protocols/nice_flor_s.c +++ b/lib/subghz/protocols/nice_flor_s.c @@ -92,7 +92,7 @@ void* subghz_protocol_encoder_nice_flor_s_alloc(SubGhzEnvironment* environment) instance->nice_flor_s_rainbow_table_file_name = subghz_environment_get_nice_flor_s_rainbow_table_file_name(environment); if(instance->nice_flor_s_rainbow_table_file_name) { - FURI_LOG_I( + FURI_LOG_D( TAG, "Loading rainbow table from %s", instance->nice_flor_s_rainbow_table_file_name); } instance->encoder.repeat = 10; @@ -343,7 +343,7 @@ void* subghz_protocol_decoder_nice_flor_s_alloc(SubGhzEnvironment* environment) instance->nice_flor_s_rainbow_table_file_name = subghz_environment_get_nice_flor_s_rainbow_table_file_name(environment); if(instance->nice_flor_s_rainbow_table_file_name) { - FURI_LOG_I( + FURI_LOG_D( TAG, "Loading rainbow table from %s", instance->nice_flor_s_rainbow_table_file_name); } return instance; diff --git a/lib/toolbox/SConscript b/lib/toolbox/SConscript index d631431ee..015a8ed18 100644 --- a/lib/toolbox/SConscript +++ b/lib/toolbox/SConscript @@ -8,23 +8,23 @@ env.Append( "#/lib/toolbox", ], SDK_HEADERS=[ - File("#/lib/toolbox/manchester_decoder.h"), - File("#/lib/toolbox/manchester_encoder.h"), - File("#/lib/toolbox/path.h"), - File("#/lib/toolbox/random_name.h"), - File("#/lib/toolbox/hmac_sha256.h"), - File("#/lib/toolbox/crc32_calc.h"), - File("#/lib/toolbox/dir_walk.h"), - File("#/lib/toolbox/md5.h"), - File("#/lib/toolbox/args.h"), - File("#/lib/toolbox/saved_struct.h"), - File("#/lib/toolbox/version.h"), - File("#/lib/toolbox/tar/tar_archive.h"), - File("#/lib/toolbox/stream/stream.h"), - File("#/lib/toolbox/stream/file_stream.h"), - File("#/lib/toolbox/stream/string_stream.h"), - File("#/lib/toolbox/stream/buffered_file_stream.h"), - File("#/lib/toolbox/protocols/protocol_dict.h"), + File("manchester_decoder.h"), + File("manchester_encoder.h"), + File("path.h"), + File("random_name.h"), + File("hmac_sha256.h"), + File("crc32_calc.h"), + File("dir_walk.h"), + File("md5.h"), + File("args.h"), + File("saved_struct.h"), + File("version.h"), + File("tar/tar_archive.h"), + File("stream/stream.h"), + File("stream/file_stream.h"), + File("stream/string_stream.h"), + File("stream/buffered_file_stream.h"), + File("protocols/protocol_dict.h"), ], ) diff --git a/scripts/fbt/util.py b/scripts/fbt/util.py index baa4ddfee..f5404458e 100644 --- a/scripts/fbt/util.py +++ b/scripts/fbt/util.py @@ -1,11 +1,11 @@ import SCons from SCons.Subst import quote_spaces from SCons.Errors import StopError +from SCons.Node.FS import _my_normcase import re import os -import random -import string + WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)") @@ -41,3 +41,14 @@ def link_dir(target_path, source_path, is_windows): def single_quote(arg_list): return " ".join(f"'{arg}'" if " " in arg else str(arg) for arg in arg_list) + + +def extract_abs_dir_path(node): + if isinstance(node, SCons.Node.FS.EntryProxy): + node = node.get() + + for repo_dir in node.get_all_rdirs(): + if os.path.exists(repo_dir.abspath): + return repo_dir.abspath + + raise StopError(f"Can't find absolute path for {node.name}") diff --git a/scripts/fbt_tools/crosscc.py b/scripts/fbt_tools/crosscc.py index aacda58c6..dd5cd5319 100644 --- a/scripts/fbt_tools/crosscc.py +++ b/scripts/fbt_tools/crosscc.py @@ -37,6 +37,21 @@ def _get_tool_version(env, tool): def generate(env, **kw): + if not env.get("VERBOSE", False): + env.SetDefault( + CCCOMSTR="\tCC\t${SOURCE}", + CXXCOMSTR="\tCPP\t${SOURCE}", + ASCOMSTR="\tASM\t${SOURCE}", + ARCOMSTR="\tAR\t${TARGET}", + RANLIBCOMSTR="\tRANLIB\t${TARGET}", + LINKCOMSTR="\tLINK\t${TARGET}", + INSTALLSTR="\tINSTALL\t${TARGET}", + APPSCOMSTR="\tAPPS\t${TARGET}", + VERSIONCOMSTR="\tVERSION\t${TARGET}", + STRIPCOMSTR="\tSTRIP\t${TARGET}", + OBJDUMPCOMSTR="\tOBJDUMP\t${TARGET}", + ) + for orig_tool in (asm, gcc, gxx, ar, gnulink, strip, gdb, objdump): orig_tool.generate(env) env.SetDefault( diff --git a/scripts/fbt_tools/fbt_apps.py b/scripts/fbt_tools/fbt_apps.py index ef5e9b9d9..55e282017 100644 --- a/scripts/fbt_tools/fbt_apps.py +++ b/scripts/fbt_tools/fbt_apps.py @@ -2,7 +2,7 @@ from SCons.Builder import Builder from SCons.Action import Action from SCons.Warnings import warn, WarningOnByDefault import SCons -import os.path +from ansi.color import fg from fbt.appmanifest import ( FlipperAppType, @@ -16,21 +16,20 @@ from fbt.appmanifest import ( # AppBuildset env["APPBUILD"] - contains subset of apps, filtered for current config -def LoadApplicationManifests(env): - appmgr = env["APPMGR"] = AppManager() - for app_dir, _ in env["APPDIRS"]: - app_dir_node = env.Dir("#").Dir(app_dir) +def LoadAppManifest(env, entry): + try: + APP_MANIFEST_NAME = "application.fam" + manifest_glob = entry.glob(APP_MANIFEST_NAME) + if len(manifest_glob) == 0: + raise FlipperManifestException( + f"Folder {entry}: manifest {APP_MANIFEST_NAME} is missing" + ) - for entry in app_dir_node.glob("*", ondisk=True, source=True): - if isinstance(entry, SCons.Node.FS.Dir) and not str(entry).startswith("."): - try: - app_manifest_file_path = os.path.join( - entry.abspath, "application.fam" - ) - appmgr.load_manifest(app_manifest_file_path, entry) - env.Append(PY_LINT_SOURCES=[app_manifest_file_path]) - except FlipperManifestException as e: - warn(WarningOnByDefault, str(e)) + app_manifest_file_path = manifest_glob[0].rfile().abspath + env["APPMGR"].load_manifest(app_manifest_file_path, entry) + env.Append(PY_LINT_SOURCES=[app_manifest_file_path]) + except FlipperManifestException as e: + warn(WarningOnByDefault, str(e)) def PrepareApplicationsBuild(env): @@ -46,12 +45,12 @@ def PrepareApplicationsBuild(env): def DumpApplicationConfig(target, source, env): print(f"Loaded {len(env['APPMGR'].known_apps)} app definitions.") - print("Firmware modules configuration:") + print(fg.boldgreen("Firmware modules configuration:")) for apptype in FlipperAppType: app_sublist = env["APPBUILD"].get_apps_of_type(apptype) if app_sublist: print( - f"{apptype.value}:\n\t", + fg.green(f"{apptype.value}:\n\t"), ", ".join(app.appid for app in app_sublist), ) @@ -65,8 +64,11 @@ def build_apps_c(target, source, env): def generate(env): - env.AddMethod(LoadApplicationManifests) + env.AddMethod(LoadAppManifest) env.AddMethod(PrepareApplicationsBuild) + env.SetDefault( + APPMGR=AppManager(), + ) env.Append( BUILDERS={ diff --git a/scripts/fbt_tools/fbt_assets.py b/scripts/fbt_tools/fbt_assets.py index 4fa5353d0..521c37e90 100644 --- a/scripts/fbt_tools/fbt_assets.py +++ b/scripts/fbt_tools/fbt_assets.py @@ -1,11 +1,10 @@ -import SCons - from SCons.Builder import Builder from SCons.Action import Action -from SCons.Node.FS import File +from SCons.Errors import SConsEnvironmentError import os import subprocess +from ansi.color import fg def icons_emitter(target, source, env): @@ -13,7 +12,6 @@ def icons_emitter(target, source, env): target[0].File(env.subst("${ICON_FILE_NAME}.c")), target[0].File(env.subst("${ICON_FILE_NAME}.h")), ] - source = env.GlobRecursive("*.*", env["ICON_SRC_DIR"]) return target, source @@ -86,7 +84,7 @@ def proto_ver_generator(target, source, env): ) except (subprocess.CalledProcessError, EnvironmentError) as e: # Not great, not terrible - print("Git: fetch failed") + print(fg.boldred("Git: fetch failed")) try: git_describe = _invoke_git( @@ -94,10 +92,8 @@ def proto_ver_generator(target, source, env): source_dir=src_dir, ) except (subprocess.CalledProcessError, EnvironmentError) as e: - print("Git: describe failed") - Exit("git error") + raise SConsEnvironmentError("Git: describe failed") - # print("describe=", git_describe) git_major, git_minor = git_describe.split(".") version_file_data = ( "#pragma once", @@ -116,7 +112,7 @@ def CompileIcons(env, target_dir, source_dir, *, icon_bundle_name="assets_icons" icons = env.IconBuilder( target_dir, - ICON_SRC_DIR=source_dir, + source_dir, ICON_FILE_NAME=icon_bundle_name, ) env.Depends(icons, icons_src) @@ -125,8 +121,8 @@ def CompileIcons(env, target_dir, source_dir, *, icon_bundle_name="assets_icons" def generate(env): env.SetDefault( - ASSETS_COMPILER="${ROOT_DIR.abspath}/scripts/assets.py", - NANOPB_COMPILER="${ROOT_DIR.abspath}/lib/nanopb/generator/nanopb_generator.py", + ASSETS_COMPILER="${FBT_SCRIPT_DIR}/assets.py", + NANOPB_COMPILER="${ROOT_DIR}/lib/nanopb/generator/nanopb_generator.py", ) env.AddMethod(CompileIcons) @@ -143,7 +139,7 @@ def generate(env): BUILDERS={ "IconBuilder": Builder( action=Action( - '${PYTHON3} "${ASSETS_COMPILER}" icons ${ICON_SRC_DIR} ${TARGET.dir} --filename ${ICON_FILE_NAME}', + '${PYTHON3} "${ASSETS_COMPILER}" icons ${ABSPATHGETTERFUNC(SOURCE)} ${TARGET.dir} --filename ${ICON_FILE_NAME}', "${ICONSCOMSTR}", ), emitter=icons_emitter, diff --git a/scripts/fbt_tools/fbt_dist.py b/scripts/fbt_tools/fbt_dist.py index 853013e9f..fb59e5b95 100644 --- a/scripts/fbt_tools/fbt_dist.py +++ b/scripts/fbt_tools/fbt_dist.py @@ -103,7 +103,7 @@ def DistCommand(env, name, source, **kw): command = env.Command( target, source, - '@${PYTHON3} "${ROOT_DIR.abspath}/scripts/sconsdist.py" copy -p ${DIST_PROJECTS} -s "${DIST_SUFFIX}" ${DIST_EXTRA}', + '@${PYTHON3} "${DIST_SCRIPT}" copy -p ${DIST_PROJECTS} -s "${DIST_SUFFIX}" ${DIST_EXTRA}', **kw, ) env.Pseudo(target) @@ -121,6 +121,9 @@ def generate(env): env.SetDefault( COPRO_MCU_FAMILY="STM32WB5x", + SELFUPDATE_SCRIPT="${FBT_SCRIPT_DIR}/selfupdate.py", + DIST_SCRIPT="${FBT_SCRIPT_DIR}/sconsdist.py", + COPRO_ASSETS_SCRIPT="${FBT_SCRIPT_DIR}/assets.py", ) env.Append( @@ -128,7 +131,7 @@ def generate(env): "UsbInstall": Builder( action=[ Action( - '${PYTHON3} "${ROOT_DIR.abspath}/scripts/selfupdate.py" dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}/update.fuf' + '${PYTHON3} "${SELFUPDATE_SCRIPT}" dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}/update.fuf' ), Touch("${TARGET}"), ] @@ -136,7 +139,7 @@ def generate(env): "CoproBuilder": Builder( action=Action( [ - '${PYTHON3} "${ROOT_DIR.abspath}/scripts/assets.py" ' + '${PYTHON3} "${COPRO_ASSETS_SCRIPT}" ' "copro ${COPRO_CUBE_DIR} " "${TARGET} ${COPRO_MCU_FAMILY} " "--cube_ver=${COPRO_CUBE_VERSION} " diff --git a/scripts/fbt_tools/fbt_extapps.py b/scripts/fbt_tools/fbt_extapps.py index 38c943cc5..fb4dc2f16 100644 --- a/scripts/fbt_tools/fbt_extapps.py +++ b/scripts/fbt_tools/fbt_extapps.py @@ -1,15 +1,18 @@ -import shutil from SCons.Builder import Builder from SCons.Action import Action from SCons.Errors import UserError import SCons.Warnings -import os -import pathlib from fbt.elfmanifest import assemble_manifest_data from fbt.appmanifest import FlipperApplication, FlipperManifestException from fbt.sdk.cache import SdkCache +from fbt.util import extract_abs_dir_path + +import os +import pathlib import itertools +import shutil + from ansi.color import fg @@ -62,7 +65,7 @@ def BuildAppElf(env, app): lib_src_root_path = os.path.join(app_work_dir, "lib", lib_def.name) app_env.AppendUnique( CPPPATH=list( - app_env.Dir(lib_src_root_path).Dir(incpath).srcnode() + app_env.Dir(lib_src_root_path).Dir(incpath).srcnode().rfile().abspath for incpath in lib_def.fap_include_paths ), ) @@ -82,7 +85,12 @@ def BuildAppElf(env, app): *lib_def.cflags, ], CPPDEFINES=lib_def.cdefines, - CPPPATH=list(map(app._appdir.Dir, lib_def.cincludes)), + CPPPATH=list( + map( + lambda cpath: extract_abs_dir_path(app._appdir.Dir(cpath)), + lib_def.cincludes, + ) + ), ) lib = private_lib_env.StaticLibrary( @@ -157,7 +165,6 @@ def prepare_app_metadata(target, source, env): app = env["APP"] meta_file_name = source[0].path + ".meta" with open(meta_file_name, "wb") as f: - # f.write(f"hello this is {app}") f.write( assemble_manifest_data( app_manifest=app, @@ -236,7 +243,10 @@ def fap_dist_action(target, source, env): def generate(env, **kw): - env.SetDefault(EXT_APPS_WORK_DIR=kw.get("EXT_APPS_WORK_DIR")) + env.SetDefault( + EXT_APPS_WORK_DIR=kw.get("EXT_APPS_WORK_DIR"), + APP_RUN_SCRIPT="${FBT_SCRIPT_DIR}/runfap.py", + ) if not env["VERBOSE"]: env.SetDefault( diff --git a/scripts/fbt_tools/fbt_sdk.py b/scripts/fbt_tools/fbt_sdk.py index f1f55bdb8..c46346b65 100644 --- a/scripts/fbt_tools/fbt_sdk.py +++ b/scripts/fbt_tools/fbt_sdk.py @@ -46,7 +46,9 @@ def prebuild_sdk_emitter(target, source, env): def prebuild_sdk_create_origin_file(target, source, env): mega_file = env.subst("${TARGET}.c", target=target[0]) with open(mega_file, "wt") as sdk_c: - sdk_c.write("\n".join(f"#include <{h.path}>" for h in env["SDK_HEADERS"])) + sdk_c.write( + "\n".join(f"#include <{h.srcnode().path}>" for h in env["SDK_HEADERS"]) + ) class SdkMeta: @@ -62,18 +64,25 @@ class SdkMeta: "cc_args": self._wrap_scons_vars("$CCFLAGS $_CCCOMCOM"), "cpp_args": self._wrap_scons_vars("$CXXFLAGS $CCFLAGS $_CCCOMCOM"), "linker_args": self._wrap_scons_vars("$LINKFLAGS"), - "linker_script": self.env.subst("${LINKER_SCRIPT_PATH}"), + "linker_libs": self.env.subst("${LIBS}"), + "app_ep_subst": self.env.subst("${APP_ENTRY}"), + "sdk_path_subst": self.env.subst("${SDK_DIR_SUBST}"), + "hardware": self.env.subst("${TARGET_HW}"), } with open(json_manifest_path, "wt") as f: json.dump(meta_contents, f, indent=4) def _wrap_scons_vars(self, vars: str): - expanded_vars = self.env.subst(vars, target=Entry("dummy")) + expanded_vars = self.env.subst( + vars, + target=Entry("dummy"), + ) return expanded_vars.replace("\\", "/") class SdkTreeBuilder: SDK_DIR_SUBST = "SDK_ROOT_DIR" + SDK_APP_EP_SUBST = "SDK_APP_EP_SUBST" def __init__(self, env, target, source) -> None: self.env = env @@ -87,6 +96,11 @@ class SdkTreeBuilder: self.sdk_root_dir = target[0].Dir(".") self.sdk_deploy_dir = self.sdk_root_dir.Dir(self.target_sdk_dir_name) + self.sdk_env = self.env.Clone( + APP_ENTRY=self.SDK_APP_EP_SUBST, + SDK_DIR_SUBST=self.SDK_DIR_SUBST, + ) + def _parse_sdk_depends(self): deps_file = self.source[0] with open(deps_file.path, "rt") as deps_f: @@ -95,38 +109,36 @@ class SdkTreeBuilder: self.header_depends = list( filter(lambda fname: fname.endswith(".h"), depends.split()), ) - self.header_depends.append(self.env.subst("${LINKER_SCRIPT_PATH}")) - self.header_depends.append(self.env.subst("${SDK_DEFINITION}")) + self.header_depends.append(self.sdk_env.subst("${LINKER_SCRIPT_PATH}")) + self.header_depends.append(self.sdk_env.subst("${SDK_DEFINITION}")) self.header_dirs = sorted( set(map(os.path.normpath, map(os.path.dirname, self.header_depends))) ) def _generate_sdk_meta(self): - filtered_paths = [self.target_sdk_dir_name] + filtered_paths = ["."] full_fw_paths = list( map( os.path.normpath, - (self.env.Dir(inc_dir).relpath for inc_dir in self.env["CPPPATH"]), + ( + self.sdk_env.Dir(inc_dir).relpath + for inc_dir in self.sdk_env["CPPPATH"] + ), ) ) sdk_dirs = ", ".join(f"'{dir}'" for dir in self.header_dirs) filtered_paths.extend( - map( - self.build_sdk_file_path, - filter(lambda path: path in sdk_dirs, full_fw_paths), - ) + filter(lambda path: path in sdk_dirs, full_fw_paths), ) + filtered_paths = list(map(self.build_sdk_file_path, filtered_paths)) - sdk_env = self.env.Clone() - sdk_env.Replace( + self.sdk_env.Replace( CPPPATH=filtered_paths, - LINKER_SCRIPT=self.env.subst("${APP_LINKER_SCRIPT}"), ORIG_LINKER_SCRIPT_PATH=self.env["LINKER_SCRIPT_PATH"], LINKER_SCRIPT_PATH=self.build_sdk_file_path("${ORIG_LINKER_SCRIPT_PATH}"), ) - - meta = SdkMeta(sdk_env, self) + meta = SdkMeta(self.sdk_env, self) meta.save_to(self.target[0].path) def build_sdk_file_path(self, orig_path: str) -> str: @@ -211,7 +223,7 @@ def validate_sdk_cache(source, target, env): current_sdk = SdkCollector() current_sdk.process_source_file_for_sdk(source[0].path) for h in env["SDK_HEADERS"]: - current_sdk.add_header_to_sdk(pathlib.Path(h.path).as_posix()) + current_sdk.add_header_to_sdk(pathlib.Path(h.srcnode().path).as_posix()) sdk_cache = SdkCache(target[0].path) sdk_cache.validate_api(current_sdk.get_api()) diff --git a/scripts/fbt_tools/fbt_version.py b/scripts/fbt_tools/fbt_version.py index 909eea4f3..87497ca5f 100644 --- a/scripts/fbt_tools/fbt_version.py +++ b/scripts/fbt_tools/fbt_version.py @@ -12,11 +12,14 @@ def version_emitter(target, source, env): def generate(env): + env.SetDefault( + VERSION_SCRIPT="${FBT_SCRIPT_DIR}/version.py", + ) env.Append( BUILDERS={ "VersionBuilder": Builder( action=Action( - '${PYTHON3} "${ROOT_DIR.abspath}/scripts/version.py" generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir "${ROOT_DIR}"', + '${PYTHON3} "${VERSION_SCRIPT}" generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir "${ROOT_DIR}"', "${VERSIONCOMSTR}", ), emitter=version_emitter, diff --git a/scripts/fbt_tools/fwbin.py b/scripts/fbt_tools/fwbin.py index 67e0d6450..f510c2a60 100644 --- a/scripts/fbt_tools/fwbin.py +++ b/scripts/fbt_tools/fwbin.py @@ -8,7 +8,8 @@ __NM_ARM_BIN = "arm-none-eabi-nm" def generate(env): env.SetDefault( - BIN2DFU="${ROOT_DIR.abspath}/scripts/bin2dfu.py", + BIN2DFU="${FBT_SCRIPT_DIR}/bin2dfu.py", + BIN_SIZE_SCRIPT="${FBT_SCRIPT_DIR}/fwsize.py", OBJCOPY=__OBJCOPY_ARM_BIN, # FIXME NM=__NM_ARM_BIN, # FIXME ) diff --git a/scripts/flipper/app.py b/scripts/flipper/app.py index 958356021..30630a5f9 100644 --- a/scripts/flipper/app.py +++ b/scripts/flipper/app.py @@ -1,6 +1,7 @@ import logging import argparse import sys +import colorlog class App: @@ -10,7 +11,7 @@ class App: self.parser = argparse.ArgumentParser() self.parser.add_argument("-d", "--debug", action="store_true", help="Debug") # Logging - self.logger = logging.getLogger() + self.logger = colorlog.getLogger() # Application specific initialization self.init() @@ -21,10 +22,17 @@ class App: self.log_level = logging.DEBUG if self.args.debug else logging.INFO self.logger.setLevel(self.log_level) if not self.logger.hasHandlers(): - self.handler = logging.StreamHandler(sys.stdout) + self.handler = colorlog.StreamHandler(sys.stdout) self.handler.setLevel(self.log_level) - self.formatter = logging.Formatter( - "%(asctime)s [%(levelname)s] %(message)s" + self.formatter = colorlog.ColoredFormatter( + "%(log_color)s%(asctime)s [%(levelname)s] %(message)s", + log_colors={ + "DEBUG": "cyan", + # "INFO": "white", + "WARNING": "yellow", + "ERROR": "red", + "CRITICAL": "red,bg_white", + }, ) self.handler.setFormatter(self.formatter) self.logger.addHandler(self.handler) diff --git a/scripts/sconsdist.py b/scripts/sconsdist.py index 4cbea7bd9..0fa120d87 100644 --- a/scripts/sconsdist.py +++ b/scripts/sconsdist.py @@ -131,7 +131,9 @@ class Main(App): self.copy_single_project(project) self.logger.info( - fg.green(f"Firmware binaries can be found at:\n\t{self.output_dir_path}") + fg.boldgreen( + f"Firmware binaries can be found at:\n\t{self.output_dir_path}" + ) ) if self.args.version: @@ -175,7 +177,7 @@ class Main(App): if (bundle_result := UpdateMain(no_exit=True)(bundle_args)) == 0: self.logger.info( - fg.green( + fg.boldgreen( f"Use this directory to self-update your Flipper:\n\t{bundle_dir}" ) ) diff --git a/scripts/testing/await_flipper.py b/scripts/testing/await_flipper.py old mode 100644 new mode 100755 diff --git a/scripts/testing/units.py b/scripts/testing/units.py old mode 100644 new mode 100755 diff --git a/scripts/toolchain/fbtenv.cmd b/scripts/toolchain/fbtenv.cmd index a11a3ccd5..6e87bf95a 100644 --- a/scripts/toolchain/fbtenv.cmd +++ b/scripts/toolchain/fbtenv.cmd @@ -13,19 +13,22 @@ if not [%FBT_NOENV%] == [] ( exit /b 0 ) -set "FLIPPER_TOOLCHAIN_VERSION=16" -set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\x86_64-windows" +set "FLIPPER_TOOLCHAIN_VERSION=17" +if [%FBT_TOOLCHAIN_ROOT%] == [] ( + set "FBT_TOOLCHAIN_ROOT=%FBT_ROOT%\toolchain\x86_64-windows" +) if not exist "%FBT_TOOLCHAIN_ROOT%" ( - powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" "%FBT_TOOLCHAIN_ROOT%" ) if not exist "%FBT_TOOLCHAIN_ROOT%\VERSION" ( - powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" "%FBT_TOOLCHAIN_ROOT%" ) + set /p REAL_TOOLCHAIN_VERSION=<"%FBT_TOOLCHAIN_ROOT%\VERSION" if not "%REAL_TOOLCHAIN_VERSION%" == "%FLIPPER_TOOLCHAIN_VERSION%" ( - powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" + powershell -ExecutionPolicy Bypass -File "%FBT_ROOT%\scripts\toolchain\windows-toolchain-download.ps1" "%flipper_toolchain_version%" "%FBT_TOOLCHAIN_ROOT%" ) diff --git a/scripts/toolchain/fbtenv.sh b/scripts/toolchain/fbtenv.sh index a2b292c65..ba709a8b5 100755 --- a/scripts/toolchain/fbtenv.sh +++ b/scripts/toolchain/fbtenv.sh @@ -5,7 +5,7 @@ # public variables DEFAULT_SCRIPT_PATH="$(pwd -P)"; SCRIPT_PATH="${SCRIPT_PATH:-$DEFAULT_SCRIPT_PATH}"; -FBT_TOOLCHAIN_VERSION="${FBT_TOOLCHAIN_VERSION:-"16"}"; +FBT_TOOLCHAIN_VERSION="${FBT_TOOLCHAIN_VERSION:-"17"}"; FBT_TOOLCHAIN_PATH="${FBT_TOOLCHAIN_PATH:-$SCRIPT_PATH}"; fbtenv_show_usage() @@ -62,7 +62,7 @@ fbtenv_check_sourced() fbtenv_show_usage; return 1; fi - case ${0##*/} in dash|-dash|bash|-bash|ksh|-ksh|sh|-sh|*.sh|fbt) + case ${0##*/} in dash|-dash|bash|-bash|ksh|-ksh|sh|-sh|*.sh|fbt|ufbt) return 0;; esac fbtenv_show_usage; @@ -76,8 +76,8 @@ fbtenv_chck_many_source() return 0; fi fi - echo "Warning! FBT environment script sourced more than once!"; - echo "This may signal that you are making mistakes, please open a new shell!"; + echo "Warning! FBT environment script was sourced more than once!"; + echo "You might be doing things wrong, please open a new shell!"; return 1; } @@ -93,8 +93,8 @@ fbtenv_set_shell_prompt() fbtenv_check_script_path() { - if [ ! -x "$SCRIPT_PATH/fbt" ]; then - echo "Please source this script being into flipperzero-firmware root directory, or specify 'SCRIPT_PATH' manually"; + if [ ! -x "$SCRIPT_PATH/fbt" ] && [ ! -x "$SCRIPT_PATH/ufbt" ] ; then + echo "Please source this script from [u]fbt root directory, or specify 'SCRIPT_PATH' variable manually"; echo "Example:"; printf "\tSCRIPT_PATH=lang/c/flipperzero-firmware source lang/c/flipperzero-firmware/scripts/fbtenv.sh\n"; echo "If current directory is right, type 'unset SCRIPT_PATH' and try again" @@ -108,7 +108,7 @@ fbtenv_get_kernel_type() SYS_TYPE="$(uname -s)"; ARCH_TYPE="$(uname -m)"; if [ "$ARCH_TYPE" != "x86_64" ] && [ "$SYS_TYPE" != "Darwin" ]; then - echo "Now we provide toolchain only for x86_64 arhitecture, sorry.."; + echo "We only provide toolchain for x86_64 CPUs, sorry.."; return 1; fi if [ "$SYS_TYPE" = "Darwin" ]; then @@ -129,10 +129,10 @@ fbtenv_get_kernel_type() TOOLCHAIN_URL=$FBT_TOOLS_CUSTOM_LINK; fi elif echo "$SYS_TYPE" | grep -q "MINGW"; then - echo "In MinGW shell use \"fbt.cmd\" instead of \"fbt\""; + echo "In MinGW shell use \"[u]fbt.cmd\" instead of \"[u]fbt\""; return 1; else - echo "Your system is not recognized. Sorry.. Please report us your configuration."; + echo "Your system configuration is not supported. Sorry.. Please report us your configuration."; return 1; fi return 0; @@ -152,7 +152,7 @@ fbtenv_check_rosetta() fbtenv_check_tar() { - printf "Checking tar.."; + printf "Checking for tar.."; if ! tar --version > /dev/null 2>&1; then echo "no"; return 1; @@ -163,7 +163,7 @@ fbtenv_check_tar() fbtenv_check_downloaded_toolchain() { - printf "Checking downloaded toolchain tgz.."; + printf "Checking if downloaded toolchain tgz exists.."; if [ ! -f "$FBT_TOOLCHAIN_PATH/toolchain/$TOOLCHAIN_TAR" ]; then echo "no"; return 1; @@ -214,7 +214,7 @@ fbtenv_unpack_toolchain() fbtenv_clearing() { - printf "Clearing.."; + printf "Cleaning up.."; if [ -n "${FBT_TOOLCHAIN_PATH:-""}" ]; then rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.tar.gz; rm -rf "${FBT_TOOLCHAIN_PATH:?}/toolchain/"*.part; diff --git a/scripts/toolchain/windows-toolchain-download.ps1 b/scripts/toolchain/windows-toolchain-download.ps1 index aaed89856..c96bb119c 100644 --- a/scripts/toolchain/windows-toolchain-download.ps1 +++ b/scripts/toolchain/windows-toolchain-download.ps1 @@ -1,34 +1,46 @@ Set-StrictMode -Version 2.0 $ErrorActionPreference = "Stop" [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11, tls" -$repo_root = (Get-Item "$PSScriptRoot\..\..").FullName +# TODO: fix +$download_dir = (Get-Item "$PSScriptRoot\..\..").FullName $toolchain_version = $args[0] -$toolchain_url = "https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-x86_64-windows-flipper-$toolchain_version.zip" -$toolchain_zip = "gcc-arm-none-eabi-10.3-x86_64-windows-flipper-$toolchain_version.zip" -$toolchain_dir = "gcc-arm-none-eabi-10.3-x86_64-windows-flipper" +$toolchain_target_path = $args[1] -if (Test-Path -LiteralPath "$repo_root\toolchain\x86_64-windows") { +$toolchain_url = "https://update.flipperzero.one/builds/toolchain/gcc-arm-none-eabi-10.3-x86_64-windows-flipper-$toolchain_version.zip" +$toolchain_dist_folder = "gcc-arm-none-eabi-10.3-x86_64-windows-flipper" +$toolchain_zip = "$toolchain_dist_folder-$toolchain_version.zip" + +$toolchain_zip_temp_path = "$download_dir\$toolchain_zip" +$toolchain_dist_temp_path = "$download_dir\$toolchain_dist_folder" + +if (Test-Path -LiteralPath "$toolchain_target_path") { Write-Host -NoNewline "Removing old Windows toolchain.." - Remove-Item -LiteralPath "$repo_root\toolchain\x86_64-windows" -Force -Recurse + Remove-Item -LiteralPath "$toolchain_target_path" -Force -Recurse Write-Host "done!" } -if (!(Test-Path -Path "$repo_root\$toolchain_zip" -PathType Leaf)) { +if (!(Test-Path -Path "$toolchain_zip_temp_path" -PathType Leaf)) { Write-Host -NoNewline "Downloading Windows toolchain.." $wc = New-Object net.webclient - $wc.Downloadfile("$toolchain_url", "$repo_root\$toolchain_zip") + $wc.Downloadfile("$toolchain_url", "$toolchain_zip_temp_path") Write-Host "done!" } -if (!(Test-Path -LiteralPath "$repo_root\toolchain")) { - New-Item "$repo_root\toolchain" -ItemType Directory +if (!(Test-Path -LiteralPath "$toolchain_target_path\..")) { + New-Item "$toolchain_target_path\.." -ItemType Directory -Force } Write-Host -NoNewline "Extracting Windows toolchain.." +# This is faster than Expand-Archive Add-Type -Assembly "System.IO.Compression.Filesystem" -[System.IO.Compression.ZipFile]::ExtractToDirectory("$repo_root\$toolchain_zip", "$repo_root\") -Move-Item -Path "$repo_root\$toolchain_dir" -Destination "$repo_root\toolchain\x86_64-windows" +[System.IO.Compression.ZipFile]::ExtractToDirectory("$toolchain_zip_temp_path", "$download_dir") +# Expand-Archive -LiteralPath "$toolchain_zip_temp_path" -DestinationPath "$download_dir" + +Write-Host -NoNewline "moving.." +Move-Item -LiteralPath "$toolchain_dist_temp_path" -Destination "$toolchain_target_path" Write-Host "done!" Write-Host -NoNewline "Cleaning up temporary files.." -Remove-Item -LiteralPath "$repo_root\$toolchain_zip" -Force +Remove-Item -LiteralPath "$toolchain_zip_temp_path" -Force Write-Host "done!" + +# dasdasd \ No newline at end of file diff --git a/site_scons/cc.scons b/site_scons/cc.scons index 507ec04a4..5c7df2575 100644 --- a/site_scons/cc.scons +++ b/site_scons/cc.scons @@ -33,7 +33,8 @@ ENV.AppendUnique( "-ffunction-sections", "-fsingle-precision-constant", "-fno-math-errno", - "-fstack-usage", + # Generates .su files with stack usage information + # "-fstack-usage", "-g", "-Wno-unused-parameter", "-Wno-type-limits", diff --git a/site_scons/environ.scons b/site_scons/environ.scons index 5074716da..74819672c 100644 --- a/site_scons/environ.scons +++ b/site_scons/environ.scons @@ -1,5 +1,10 @@ from SCons.Platform import TempFileMunge -from fbt.util import tempfile_arg_esc_func, single_quote, wrap_tempfile +from fbt.util import ( + tempfile_arg_esc_func, + single_quote, + wrap_tempfile, + extract_abs_dir_path, +) import os import multiprocessing @@ -53,6 +58,12 @@ coreenv = VAR_ENV.Clone( MAXLINELENGTH=2048, PROGSUFFIX=".elf", ENV=forward_os_env, + SINGLEQUOTEFUNC=single_quote, + ABSPATHGETTERFUNC=extract_abs_dir_path, + # Setting up temp file parameters - to overcome command line length limits + TEMPFILEARGESCFUNC=tempfile_arg_esc_func, + FBT_SCRIPT_DIR=Dir("#/scripts"), + ROOT_DIR=Dir("#"), ) # If DIST_SUFFIX is set in environment, is has precedence (set by CI) @@ -61,24 +72,6 @@ if os_suffix := os.environ.get("DIST_SUFFIX", None): DIST_SUFFIX=os_suffix, ) -# print(coreenv.Dump()) -if not coreenv["VERBOSE"]: - coreenv.SetDefault( - CCCOMSTR="\tCC\t${SOURCE}", - CXXCOMSTR="\tCPP\t${SOURCE}", - ASCOMSTR="\tASM\t${SOURCE}", - ARCOMSTR="\tAR\t${TARGET}", - RANLIBCOMSTR="\tRANLIB\t${TARGET}", - LINKCOMSTR="\tLINK\t${TARGET}", - INSTALLSTR="\tINSTALL\t${TARGET}", - APPSCOMSTR="\tAPPS\t${TARGET}", - VERSIONCOMSTR="\tVERSION\t${TARGET}", - STRIPCOMSTR="\tSTRIP\t${TARGET}", - OBJDUMPCOMSTR="\tOBJDUMP\t${TARGET}", - # GDBCOMSTR="\tGDB\t${SOURCE}", - # GDBPYCOMSTR="\tGDB-PY\t${SOURCE}", - ) - # Default value for commandline options SetOption("num_jobs", multiprocessing.cpu_count()) @@ -91,12 +84,7 @@ SetOption("max_drift", 1) # Random task queue - to discover isses with build logic faster # SetOption("random", 1) - -# Setting up temp file parameters - to overcome command line length limits -coreenv["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func wrap_tempfile(coreenv, "LINKCOM") wrap_tempfile(coreenv, "ARCOM") -coreenv["SINGLEQUOTEFUNC"] = single_quote - Return("coreenv") diff --git a/site_scons/extapps.scons b/site_scons/extapps.scons index 90d228e58..bb1d65ffc 100644 --- a/site_scons/extapps.scons +++ b/site_scons/extapps.scons @@ -3,10 +3,9 @@ from SCons.Errors import UserError Import("ENV") - from fbt.appmanifest import FlipperAppType -appenv = ENV.Clone( +appenv = ENV["APPENV"] = ENV.Clone( tools=[ ( "fbt_extapps", @@ -17,6 +16,7 @@ appenv = ENV.Clone( }, ), "fbt_assets", + "fbt_sdk", ] ) @@ -66,6 +66,7 @@ extapps = appenv["_extapps"] = { "validators": {}, "dist": {}, "resources_dist": None, + "sdk_tree": None, } @@ -115,10 +116,41 @@ if appsrc := appenv.subst("$APPSRC"): app_manifest, fap_file, app_validator = appenv.GetExtAppFromPath(appsrc) appenv.PhonyTarget( "launch_app", - '${PYTHON3} scripts/runfap.py ${SOURCE} --fap_dst_dir "/ext/apps/${FAP_CATEGORY}"', + '${PYTHON3} "${APP_RUN_SCRIPT}" ${SOURCE} --fap_dst_dir "/ext/apps/${FAP_CATEGORY}"', source=fap_file, FAP_CATEGORY=app_manifest.fap_category, ) appenv.Alias("launch_app", app_validator) +# SDK management + +sdk_origin_path = "${BUILD_DIR}/sdk_origin" +sdk_source = appenv.SDKPrebuilder( + sdk_origin_path, + # Deps on root SDK headers and generated files + (appenv["SDK_HEADERS"], appenv["FW_ASSETS_HEADERS"]), +) +# Extra deps on headers included in deeper levels +Depends(sdk_source, appenv.ProcessSdkDepends(f"{sdk_origin_path}.d")) + +appenv["SDK_DIR"] = appenv.Dir("${BUILD_DIR}/sdk") +sdk_tree = extapps["sdk_tree"] = appenv.SDKTree(appenv["SDK_DIR"], sdk_origin_path) +# AlwaysBuild(sdk_tree) +Alias("sdk_tree", sdk_tree) + +sdk_apicheck = appenv.SDKSymUpdater(appenv["SDK_DEFINITION"], sdk_origin_path) +Precious(sdk_apicheck) +NoClean(sdk_apicheck) +AlwaysBuild(sdk_apicheck) +Alias("sdk_check", sdk_apicheck) + +sdk_apisyms = appenv.SDKSymGenerator( + "${BUILD_DIR}/assets/compiled/symbols.h", appenv["SDK_DEFINITION"] +) +Alias("api_syms", sdk_apisyms) + +if appenv["FORCE"]: + appenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms) + + Return("extapps")