This commit is contained in:
Willy-JL
2024-03-21 01:22:13 +00:00
107 changed files with 1396 additions and 1008 deletions

View File

@@ -4,6 +4,7 @@ on:
push:
branches:
- dev
pull_request:
env:
TARGETS: f7
@@ -37,12 +38,17 @@ jobs:
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
- name: "Generate documentation"
uses: mattnotmitt/doxygen-action@v1.9.8
uses: mattnotmitt/doxygen-action@edge
env:
DOXY_SRC_ROOT: "${{ github.workspace }}"
DOXY_CONFIG_DIR: "${{ github.workspace }}/documentation/doxygen"
DOXY_OUTPUT_DIR: "${{ github.workspace }}/documentation/doxygen/build"
with:
working-directory: "documentation/"
doxyfile-path: "./doxygen/Doxyfile-awesome.cfg"
- name: "Upload documentation"
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' }}
uses: jakejarvis/s3-sync-action@v0.5.1
env:
AWS_S3_BUCKET: "${{ secrets.FW_DOCS_AWS_BUCKET }}"

View File

@@ -7,7 +7,7 @@
# construction of certain targets behind command-line options.
import os
from fbt.util import path_as_posix
from fbt.util import path_as_posix, open_browser_action
DefaultEnvironment(tools=[])
@@ -42,6 +42,7 @@ distenv = coreenv.Clone(
"openocd",
"blackmagic",
"jflash",
"doxygen",
],
ENV=os.environ,
UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
@@ -229,7 +230,6 @@ firmware_debug = distenv.PhonyTarget(
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE}",
GDBREMOTE="${OPENOCD_GDB_PIPE}",
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
)
distenv.Depends(firmware_debug, firmware_flash)
@@ -239,7 +239,6 @@ distenv.PhonyTarget(
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="${BLACKMAGIC_ADDR}",
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
)
# Debug alien elf
@@ -419,3 +418,18 @@ distenv.PhonyTarget(
"env",
"@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)",
)
doxy_build = distenv.DoxyBuild(
"documentation/doxygen/build/html/index.html",
"documentation/doxygen/Doxyfile-awesome.cfg",
doxy_env_variables={
"DOXY_SRC_ROOT": Dir(".").abspath,
"DOXY_BUILD_DIR": Dir("documentation/doxygen/build").abspath,
"DOXY_CONFIG_DIR": "documentation/doxygen",
},
)
distenv.Alias("doxygen", doxy_build)
distenv.AlwaysBuild(doxy_build)
# Open generated documentation in browser
distenv.PhonyTarget("doxy", open_browser_action, source=doxy_build)

View File

@@ -576,6 +576,7 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->st.line_cur = 0;
bad_kb->defdelay = 0;
bad_kb->stringdelay = 0;
bad_kb->defstringdelay = 0;
bad_kb->repeat_cnt = 0;
bad_kb->key_hold_nb = 0;
bad_kb->file_end = false;
@@ -605,6 +606,7 @@ static int32_t bad_kb_worker(void* context) {
bad_kb->st.line_cur = 0;
bad_kb->defdelay = 0;
bad_kb->stringdelay = 0;
bad_kb->defstringdelay = 0;
bad_kb->repeat_cnt = 0;
bad_kb->file_end = false;
storage_file_seek(script_file, 0, true);
@@ -780,10 +782,12 @@ static int32_t bad_kb_worker(void* context) {
}
} else if(worker_state == BadKbStateStringDelay) { // State: print string with delays
FURI_LOG_D(WORKER_TAG, "delay wait");
uint32_t delay = (bad_kb->stringdelay == 0) ? bad_kb->defstringdelay :
bad_kb->stringdelay;
uint32_t flags = bad_kb_flags_get(
WorkerEvtEnd | WorkerEvtStartStop | WorkerEvtPauseResume | WorkerEvtConnect |
WorkerEvtDisconnect,
bad_kb->stringdelay);
delay);
FURI_LOG_D(WORKER_TAG, "delay flags: %lu", flags);
if(!(flags & FuriFlagError)) {

View File

@@ -48,6 +48,17 @@ static int32_t ducky_fnc_strdelay(BadKbScript* bad_kb, const char* line, int32_t
return 0;
}
static int32_t ducky_fnc_defstrdelay(BadKbScript* bad_kb, const char* line, int32_t param) {
UNUSED(param);
line = &line[ducky_get_command_len(line) + 1];
bool state = ducky_get_number(line, &bad_kb->defstringdelay);
if(!state) {
return ducky_error(bad_kb, "Invalid number %s", line);
}
return 0;
}
static int32_t ducky_fnc_string(BadKbScript* bad_kb, const char* line, int32_t param) {
line = &line[ducky_get_command_len(line) + 1];
furi_string_set_str(bad_kb->string_print, line);
@@ -55,7 +66,8 @@ static int32_t ducky_fnc_string(BadKbScript* bad_kb, const char* line, int32_t p
furi_string_cat(bad_kb->string_print, "\n");
}
if(bad_kb->stringdelay == 0) { // stringdelay not set - run command immediately
if(bad_kb->stringdelay == 0 &&
bad_kb->defstringdelay == 0) { // stringdelay not set - run command immediately
bool state = ducky_string(bad_kb, furi_string_get_cstr(bad_kb->string_print));
if(!state) {
return ducky_error(bad_kb, "Invalid string %s", line);
@@ -180,6 +192,8 @@ static const DuckyCmd ducky_commands[] = {
{"DEFAULTDELAY", ducky_fnc_defdelay, -1},
{"STRINGDELAY", ducky_fnc_strdelay, -1},
{"STRING_DELAY", ducky_fnc_strdelay, -1},
{"DEFAULT_STRING_DELAY", ducky_fnc_defstrdelay, -1},
{"DEFAULTSTRINGDELAY", ducky_fnc_defstrdelay, -1},
{"REPEAT", ducky_fnc_repeat, -1},
{"SYSRQ", ducky_fnc_sysrq, -1},
{"ALTCHAR", ducky_fnc_altchar, -1},

View File

@@ -30,6 +30,7 @@ struct BadKbScript {
uint32_t defdelay;
uint32_t stringdelay;
uint32_t defstringdelay;
uint16_t layout[128];
FuriString* line;

View File

@@ -64,6 +64,18 @@ static const DuckyKey ducky_keys[] = {
{"F10", HID_KEYBOARD_F10},
{"F11", HID_KEYBOARD_F11},
{"F12", HID_KEYBOARD_F12},
{"F13", HID_KEYBOARD_F13},
{"F14", HID_KEYBOARD_F14},
{"F15", HID_KEYBOARD_F15},
{"F16", HID_KEYBOARD_F16},
{"F17", HID_KEYBOARD_F17},
{"F18", HID_KEYBOARD_F18},
{"F19", HID_KEYBOARD_F19},
{"F20", HID_KEYBOARD_F20},
{"F21", HID_KEYBOARD_F21},
{"F22", HID_KEYBOARD_F22},
{"F23", HID_KEYBOARD_F23},
{"F24", HID_KEYBOARD_F24},
};
uint16_t ducky_get_keycode_by_name(const char* param) {

View File

@@ -169,7 +169,7 @@ static void nfc_scene_read_setup_view(NfcApp* instance) {
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop);
popup_set_text(
instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop);
instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
} else {
popup_set_header(instance->popup, "Don't move", 85, 27, AlignCenter, AlignTop);
popup_set_icon(instance->popup, 12, 20, &A_Loading_24);

View File

@@ -11,7 +11,11 @@ static void nfc_render_mf_ultralight_pages_count(const MfUltralightData* data, F
void nfc_render_mf_ultralight_pwd_pack(const MfUltralightData* data, FuriString* str) {
bool all_pages = mf_ultralight_is_all_data_read(data);
furi_string_cat_printf(str, "\e#%s pages unlocked!", all_pages ? "All" : "Not all");
if(all_pages) {
furi_string_cat_printf(str, "\e#All Pages Are Unlocked!");
} else {
furi_string_cat_printf(str, "\e#Some Pages Are Locked!");
}
MfUltralightConfigPages* config;
mf_ultralight_get_config_page(data, &config);

View File

@@ -73,7 +73,7 @@ static bool myki_parse(const NfcDevice* device, FuriString* parsed_data) {
// Stored card number doesn't include check digit
card_number += myki_calculate_luhn(card_number);
furi_string_set(parsed_data, "\e#myki\n");
furi_string_set(parsed_data, "\e#myki\nNo.: ");
// Stylise card number according to the physical card
char card_string[20];

View File

@@ -170,7 +170,7 @@ static bool opal_parse(const NfcDevice* device, FuriString* parsed_data) {
furi_string_printf(
parsed_data,
"\e#Opal: $%s%ld.%02hu\n3085 22%02hhu %04hu %03hu%01hhu\n%s, %s\n",
"\e#Opal: $%s%ld.%02hu\nNo.: 3085 22%02hhu %04hu %03hu%01hhu\n%s, %s\n",
sign,
balance_dollars,
balance_cents,

View File

@@ -191,7 +191,7 @@ static bool plantain_parse(const NfcDevice* device, FuriString* parsed_data) {
}
furi_string_printf(
parsed_data, "\e#Plantain\nN:%llu-\nBalance:%lu\n", card_number, balance);
parsed_data, "\e#Plantain\nNo.: %llu?\nBalance:%lu\n", card_number, balance);
parsed = true;
} while(false);

View File

@@ -157,7 +157,7 @@ static bool two_cities_parse(const NfcDevice* device, FuriString* parsed_data) {
furi_string_printf(
parsed_data,
"\e#Troika+Plantain\nPN: %llu-\nPB: %lu rur.\nTN: %lu\nTB: %u rur.\n",
"\e#Troika+Plantain\nPN: %llu?\nPB: %lu rur.\nTN: %lu\nTB: %u rur.\n",
card_number,
balance,
troika_number,

View File

@@ -45,10 +45,11 @@ ADD_SCENE(nfc, mf_classic_mfkey_nonces_info, MfClassicMfkeyNoncesInfo)
ADD_SCENE(nfc, mf_classic_mfkey_complete, MfClassicMfkeyComplete)
ADD_SCENE(nfc, mf_classic_update_initial, MfClassicUpdateInitial)
ADD_SCENE(nfc, mf_classic_update_initial_success, MfClassicUpdateInitialSuccess)
ADD_SCENE(nfc, mf_classic_update_initial_wrong_card, MfClassicUpdateInitialWrongCard)
ADD_SCENE(nfc, mf_classic_write_initial, MfClassicWriteInitial)
ADD_SCENE(nfc, mf_classic_write_initial_success, MfClassicWriteInitialSuccess)
ADD_SCENE(nfc, mf_classic_write_initial_fail, MfClassicWriteInitialFail)
ADD_SCENE(nfc, mf_classic_wrong_card, MfClassicWrongCard)
ADD_SCENE(nfc, mf_classic_write_initial_wrong_card, MfClassicWriteInitialWrongCard)
ADD_SCENE(nfc, mf_classic_keys, MfClassicKeys)
ADD_SCENE(nfc, mf_classic_keys_list, MfClassicKeysList)

View File

@@ -19,7 +19,7 @@ void nfc_scene_detect_on_enter(void* context) {
popup_reset(instance->popup);
popup_set_header(instance->popup, "Reading", 97, 15, AlignCenter, AlignTop);
popup_set_text(
instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop);
instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);

View File

@@ -12,7 +12,7 @@ void nfc_scene_mf_classic_keys_warn_duplicate_on_enter(void* context) {
// Setup view
Popup* popup = instance->popup;
popup_set_icon(popup, 83, 22, &I_WarningDolphinFlip_45x42);
popup_set_header(popup, "Key already exists!", 64, 3, AlignCenter, AlignTop);
popup_set_header(popup, "Key Already Exists!", 64, 3, AlignCenter, AlignTop);
popup_set_text(
popup,
"Please enter a\n"

View File

@@ -14,7 +14,7 @@ void nfc_scene_mf_classic_mfkey_complete_on_enter(void* context) {
NfcApp* instance = context;
widget_add_string_element(
instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Complete!");
instance->widget, 64, 0, AlignCenter, AlignTop, FontPrimary, "Completed!");
widget_add_string_multiline_element(
instance->widget,
64,

View File

@@ -61,7 +61,7 @@ static void nfc_scene_mf_classic_update_initial_setup_view(NfcApp* instance) {
if(state == NfcSceneMfClassicUpdateInitialStateCardSearch) {
popup_set_text(
instance->popup, "Apply the initial\ncard only", 128, 32, AlignRight, AlignCenter);
instance->popup, "Use the source\ncard only", 128, 32, AlignRight, AlignCenter);
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
} else {
popup_set_header(popup, "Updating\nDon't move...", 52, 32, AlignLeft, AlignCenter);
@@ -111,14 +111,16 @@ bool nfc_scene_mf_classic_update_initial_on_event(void* context, SceneManagerEve
nfc_scene_mf_classic_update_initial_setup_view(instance);
consumed = true;
} else if(event.event == NfcCustomEventWrongCard) {
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWrongCard);
scene_manager_next_scene(
instance->scene_manager, NfcSceneMfClassicUpdateInitialWrongCard);
consumed = true;
} else if(event.event == NfcCustomEventWorkerExit) {
if(nfc_save_shadow_file(instance)) {
scene_manager_next_scene(
instance->scene_manager, NfcSceneMfClassicUpdateInitialSuccess);
} else {
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWrongCard);
scene_manager_next_scene(
instance->scene_manager, NfcSceneMfClassicUpdateInitialWrongCard);
consumed = true;
}
}

View File

@@ -0,0 +1,58 @@
#include "../nfc_app_i.h"
void nfc_scene_mf_classic_update_initial_wrong_card_widget_callback(
GuiButtonType result,
InputType type,
void* context) {
NfcApp* instance = context;
if(type == InputTypeShort) {
view_dispatcher_send_custom_event(instance->view_dispatcher, result);
}
}
void nfc_scene_mf_classic_update_initial_wrong_card_on_enter(void* context) {
NfcApp* instance = context;
Widget* widget = instance->widget;
notification_message(instance->notifications, &sequence_error);
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
widget_add_string_element(widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Wrong Card!");
widget_add_string_multiline_element(
widget,
4,
17,
AlignLeft,
AlignTop,
FontSecondary,
"Data management\nis only possible\nwith source card");
widget_add_button_element(
widget,
GuiButtonTypeLeft,
"Retry",
nfc_scene_mf_classic_update_initial_wrong_card_widget_callback,
instance);
// Setup and start worker
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_mf_classic_update_initial_wrong_card_on_event(
void* context,
SceneManagerEvent event) {
NfcApp* instance = context;
bool consumed = false;
if(event.type == SceneManagerEventTypeCustom) {
if(event.event == GuiButtonTypeLeft) {
consumed = scene_manager_previous_scene(instance->scene_manager);
}
}
return consumed;
}
void nfc_scene_mf_classic_update_initial_wrong_card_on_exit(void* context) {
NfcApp* instance = context;
widget_reset(instance->widget);
}

View File

@@ -67,7 +67,7 @@ static void nfc_scene_mf_classic_write_initial_setup_view(NfcApp* instance) {
if(state == NfcSceneMfClassicWriteInitialStateCardSearch) {
popup_set_header(instance->popup, "Writing", 95, 20, AlignCenter, AlignCenter);
popup_set_text(
instance->popup, "Apply the initial\ncard only", 95, 38, AlignCenter, AlignCenter);
instance->popup, "Use the source\ncard only", 95, 38, AlignCenter, AlignCenter);
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
} else {
popup_set_header(popup, "Writing\nDon't move...", 52, 32, AlignLeft, AlignCenter);
@@ -115,7 +115,8 @@ bool nfc_scene_mf_classic_write_initial_on_event(void* context, SceneManagerEven
nfc_scene_mf_classic_write_initial_setup_view(instance);
consumed = true;
} else if(event.event == NfcCustomEventWrongCard) {
scene_manager_next_scene(instance->scene_manager, NfcSceneMfClassicWrongCard);
scene_manager_next_scene(
instance->scene_manager, NfcSceneMfClassicWriteInitialWrongCard);
consumed = true;
} else if(event.event == NfcCustomEventPollerSuccess) {
scene_manager_next_scene(

View File

@@ -1,6 +1,6 @@
#include "../nfc_app_i.h"
void nfc_scene_mf_classic_wrong_card_widget_callback(
void nfc_scene_mf_classic_write_initial_wrong_card_widget_callback(
GuiButtonType result,
InputType type,
void* context) {
@@ -10,7 +10,7 @@ void nfc_scene_mf_classic_wrong_card_widget_callback(
}
}
void nfc_scene_mf_classic_wrong_card_on_enter(void* context) {
void nfc_scene_mf_classic_write_initial_wrong_card_on_enter(void* context) {
NfcApp* instance = context;
Widget* widget = instance->widget;
@@ -18,7 +18,7 @@ void nfc_scene_mf_classic_wrong_card_on_enter(void* context) {
widget_add_icon_element(widget, 83, 22, &I_WarningDolphinFlip_45x42);
widget_add_string_element(
widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "This is wrong card");
widget, 3, 4, AlignLeft, AlignTop, FontPrimary, "Use The Source Card!");
widget_add_string_multiline_element(
widget,
4,
@@ -26,19 +26,19 @@ void nfc_scene_mf_classic_wrong_card_on_enter(void* context) {
AlignLeft,
AlignTop,
FontSecondary,
"Data management\nis only possible\nwith initial card");
"Go to NFC Magic\napp if you want to\nwrite blanks");
widget_add_button_element(
widget,
GuiButtonTypeLeft,
"Retry",
nfc_scene_mf_classic_wrong_card_widget_callback,
nfc_scene_mf_classic_write_initial_wrong_card_widget_callback,
instance);
// Setup and start worker
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewWidget);
}
bool nfc_scene_mf_classic_wrong_card_on_event(void* context, SceneManagerEvent event) {
bool nfc_scene_mf_classic_write_initial_wrong_card_on_event(void* context, SceneManagerEvent event) {
NfcApp* instance = context;
bool consumed = false;
@@ -50,7 +50,7 @@ bool nfc_scene_mf_classic_wrong_card_on_event(void* context, SceneManagerEvent e
return consumed;
}
void nfc_scene_mf_classic_wrong_card_on_exit(void* context) {
void nfc_scene_mf_classic_write_initial_wrong_card_on_exit(void* context) {
NfcApp* instance = context;
widget_reset(instance->widget);

View File

@@ -22,14 +22,14 @@ void nfc_scene_mf_ultralight_unlock_warn_on_enter(void* context) {
for(size_t i = 0; i < sizeof(nfc->mf_ul_auth->password.data); i++) {
furi_string_cat_printf(password_str, "%02X ", nfc->mf_ul_auth->password.data[i]);
}
furi_string_cat_str(password_str, "?\nCaution, a wrong password\ncan block the card!");
furi_string_cat_str(password_str, "\nWarning: incorrect password\nwill block the card!");
nfc_text_store_set(nfc, furi_string_get_cstr(password_str));
furi_string_free(password_str);
const char* message = (type == MfUltralightAuthTypeReader) ? "Password captured!" :
"Risky function!";
const char* message = (type == MfUltralightAuthTypeReader) ? "Password Captured!" :
"Risky Action!";
dialog_ex_set_header(dialog_ex, message, 64, 0, AlignCenter, AlignTop);
dialog_ex_set_text(dialog_ex, nfc->text_store, 64, 12, AlignCenter, AlignTop);
dialog_ex_set_text(dialog_ex, nfc->text_store, 64, 10, AlignCenter, AlignTop);
dialog_ex_set_left_button_text(dialog_ex, "Cancel");
dialog_ex_set_right_button_text(dialog_ex, "Continue");
@@ -37,7 +37,7 @@ void nfc_scene_mf_ultralight_unlock_warn_on_enter(void* context) {
notification_message(nfc->notifications, &sequence_set_green_255);
}
} else {
dialog_ex_set_header(dialog_ex, "Risky function!", 64, 4, AlignCenter, AlignTop);
dialog_ex_set_header(dialog_ex, "Risky action!", 64, 4, AlignCenter, AlignTop);
dialog_ex_set_text(
dialog_ex, "Wrong password\ncan block your\ncard.", 4, 18, AlignLeft, AlignTop);
dialog_ex_set_icon(dialog_ex, 83, 22, &I_WarningDolphinFlip_45x42);

View File

@@ -32,7 +32,7 @@ void nfc_scene_slix_unlock_on_enter(void* context) {
popup_set_icon(instance->popup, 0, 8, &I_NFC_manual_60x50);
popup_set_header(instance->popup, "Unlocking", 97, 15, AlignCenter, AlignTop);
popup_set_text(
instance->popup, "Apply card to\nFlipper's back", 97, 27, AlignCenter, AlignTop);
instance->popup, "Hold card next\nto Flipper's back", 94, 27, AlignCenter, AlignTop);
view_dispatcher_switch_to_view(instance->view_dispatcher, NfcViewPopup);
instance->poller = nfc_poller_alloc(instance->nfc, NfcProtocolSlix);

View File

@@ -94,8 +94,9 @@ void view_holder_start(ViewHolder* view_holder);
void view_holder_stop(ViewHolder* view_holder);
/** View Update Handler
* @param view, View Instance
* @param context, ViewHolder instance
*
* @param view View Instance
* @param context ViewHolder instance
*/
void view_holder_update(View* view, void* context);

View File

@@ -52,6 +52,18 @@ static const struct {
{"F10", HID_KEYBOARD_F10},
{"F11", HID_KEYBOARD_F11},
{"F12", HID_KEYBOARD_F12},
{"F13", HID_KEYBOARD_F13},
{"F14", HID_KEYBOARD_F14},
{"F15", HID_KEYBOARD_F15},
{"F16", HID_KEYBOARD_F16},
{"F17", HID_KEYBOARD_F17},
{"F18", HID_KEYBOARD_F18},
{"F19", HID_KEYBOARD_F19},
{"F20", HID_KEYBOARD_F20},
{"F21", HID_KEYBOARD_F21},
{"F22", HID_KEYBOARD_F22},
{"F23", HID_KEYBOARD_F23},
{"F24", HID_KEYBOARD_F24},
{"NUM0", HID_KEYPAD_0},
{"NUM1", HID_KEYPAD_1},

View File

@@ -8,7 +8,7 @@ Active frames: 51
Frames order: 0 1 2 3 4 5 6 0 1 2 7 8 9 10 11 12 7 8 9 13 14 15 14 13 14 15 7 8 9 16 17 18 13 14 19 20 21 22 23 24 21 25 26 27 28 29 30 31 32 33 32 34 35 36 35 34 37 38 39 40 41 42 43 44 45 46 17 47 48 7
Active cycles: 1
Frame rate: 2
Duration: 3600
Duration: 360
Active cooldown: 7
Bubble slots: 1

View File

@@ -8,7 +8,7 @@ Active frames: 55
Frames order: 0 1 2 3 4 5 0 1 6 7 8 5 9 10 11 12 13 14 15 0 1 2 3 4 5 0 1 6 7 8 5 9 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 53 54 53 55 56 57 58 59 60 61 62 4 5
Active cycles: 1
Frame rate: 2
Duration: 3600
Duration: 360
Active cooldown: 6
Bubble slots: 4

View File

@@ -8,7 +8,7 @@ Active frames: 44
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 17 19 20 21 22 23 24 24 25 26 27 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
Active cycles: 1
Frame rate: 2
Duration: 3600
Duration: 360
Active cooldown: 7
Bubble slots: 1

View File

@@ -8,7 +8,7 @@ Active frames: 24
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
Active cycles: 1
Frame rate: 2
Duration: 3600
Duration: 360
Active cooldown: 7
Bubble slots: 0

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1,23 @@
Filetype: Flipper Animation
Version: 1
Width: 128
Height: 64
Passive frames: 20
Active frames: 38
Frames order: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 12 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
Active cycles: 1
Frame rate: 2
Duration: 360
Active cooldown: 7
Bubble slots: 1
Slot: 0
X: 52
Y: 46
Text: Thanks, man!
AlignH: Left
AlignV: Top
StartFrame: 37
EndFrame: 40

View File

@@ -104,7 +104,7 @@ Min butthurt: 0
Max butthurt: 14
Min level: 17
Max level: 30
Weight: 4
Weight: 3
Name: L2_Wake_up_128x64
Min butthurt: 0
@@ -139,7 +139,7 @@ Min butthurt: 0
Max butthurt: 14
Min level: 21
Max level: 30
Weight: 4
Weight: 3
Name: L3_Furippa3_128x64
Min butthurt: 0
@@ -167,18 +167,25 @@ Min butthurt: 11
Max butthurt: 14
Min level: 14
Max level: 30
Weight: 4
Weight: 3
Name: L2_Coding_in_the_shell_128x64
Min butthurt: 0
Max butthurt: 14
Min level: 22
Max level: 30
Weight: 4
Weight: 3
Name: L2_Secret_door_128x64
Min butthurt: 0
Max butthurt: 14
Min level: 26
Max level: 30
Weight: 4
Weight: 3
Name: L3_Freedom_2_dolphins_128x64
Min butthurt: 0
Max butthurt: 14
Min level: 16
Max level: 30
Weight: 5

View File

@@ -1,77 +1,30 @@
# Firmware update on Developer Board {#dev_board_fw_update}
It's important to regularly update your Developer Board to keep it up to date. This tutorial will guide you through the necessary steps to successfully update the firmware of your Developer Board.
It's important to regularly update your Developer Board to ensure that you have access to the latest features and bug fixes. This tutorial will guide you through the necessary steps to update the firmware of your Developer Board.
This tutorial assumes that you're familiar with the basics of the command line. If youre unfamiliar with the command line, please refer to the [Windows](https://www.digitalcitizen.life/command-prompt-how-use-basic-commands/) or [MacOS/Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) command line tutorials.
This tutorial assumes that you're familiar with the basics of the command line. If youre not, please refer to the [Windows](https://www.digitalcitizen.life/command-prompt-how-use-basic-commands/) or [MacOS/Linux](https://ubuntu.com/tutorials/command-line-for-beginners#1-overview) command line tutorials.
***
## Downloading the latest firmware
## Installing the micro Flipper Build Tool
The first thing you need to do is to download the latest Developer Board firmware.
Micro Flipper Build Tool (uFBT) is a cross-platform tool that enables basic development tasks for Flipper Zero, such as building and debugging applications, flashing firmware, and creating VS Code development configurations.
To get the latest pre-built firmware, do the following:
Install uFBT on your computer by running the following command in the Terminal:
1. Go to the [Update Server page](https://update.flipperzero.one/builds/blackmagic-firmware).
![The Update Server page hosts different versions of the Developer Board firmware](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/gIXVO9VrE4LK05CmcMSSD_monosnap-miro-2023-07-19-17-36-23.jpg)
There, you can find the following version of the Developer Board firmware:
* **Release:** The most stable version of the firmware, which went through rigorous testing. The Release firmware version has the following format: **X.Y.Z/**, where X, Y, and Z are the build numbers. We recommend installing this version of the firmware.
* **Release-candidate:** The firmware version that hasn't been tested yet and may contain bugs. The Release-candidate firmware version has the following format: **X.Y.Z-rc/**, where X, Y, and Z are the build numbers.
* **Development:** The firmware version which builds every day and contains the latest features but might be unstable.
2. Open the folder with the latest Release firmware and download the `blackmagic-firmware-s2-full-X.Y.Z.tgz` file.
***
## Extracting the firmware
After downloading the firmware archive, extract it into a folder:
* On Windows, you can use any archive manager for this, for example, [7-Zip](https://www.7-zip.org/).
* On MacOS and Linux, you can use the `tar` command:
```text
tar -xzf blackmagic-firmware-s2-full-X.Y.Z.tgz -C <destination_directory>
```
Don't forget to replace `X.Y.Z` with the actual version number and set the destination directory!
***
## Installing the prerequisites for flashing
Install the tools below if you haven't already.
### Python
Download and install [Python3](https://www.python.org/downloads/). Make sure to check the “Add Python to PATH” option during installation.
### pip
To install the pip package manager, run the following command in the Terminal:
**For Linux & macOS:**
```text
python3 -m ensurepip --upgrade
python3 -m pip install --upgrade ufbt
```
If this command fails, please refer to the [official pip documentation](https://pip.pypa.io/en/stable/installation/) for alternative installation methods.
### esptool
esptool is a command-line utility for flashing ESP8266 and ESP32 microcontrollers, including the ESP32-S2 in your Developer Board.
To install esptool, run the following command in the Terminal:
**For Windows:**
```text
pip3 install esptool
py -m pip install --upgrade ufbt
```
If this command fails, try using **pip** instead of **pip3**. If this didnt help, please refer to the [official esptool installation manual](https://docs.espressif.com/projects/esptool/en/latest/esp32/installation.html).
If you want to learn more about uFBT, visit [the project's page](https://pypi.org/project/ufbt/).
***
@@ -79,21 +32,21 @@ If this command fails, try using **pip** instead of **pip3**. If this didnt h
1. List all of the serial devices on your computer.
* ***Windows***
**Windows**
On Windows, go to Device Manager and expand the Ports (COM & LPT) section.
* ***macOS***
**macOS**
On macOS, you can run the following command in the Terminal:
On macOS, you can run the following command in the Terminal:
```text
ls /dev/cu.*
```
* ***Linux***
**Linux**
On Linux, you can run the following command in the Terminal:
On Linux, you can run the following command in the Terminal:
```text
ls /dev/tty*
@@ -101,7 +54,7 @@ If this command fails, try using **pip** instead of **pip3**. If this didnt h
View the devices in the list.
2. Connect the Developer Board to your computer using a USB-C cable.\
2. Connect the Developer Board to your computer using a USB-C cable.
![The Developer Board in Wired mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/Aq7gfMI-m_5H6sGGjwb4I_monosnap-miro-2023-07-19-19-47-39.jpg)
3. Switch your Developer Board to Bootloader mode:
@@ -110,7 +63,7 @@ If this command fails, try using **pip** instead of **pip3**. If this didnt h
3.2. Press the **RESET** button while holding the **BOOT** button.
3.3. Release the **BOOT** button.
3.3. Release the **BOOT** button.\
![You can easily switch the Dev Board to Bootloader mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/KynP9iT6sJ3mXLaLyI82__image.png)
4. Repeat Step 1 and view the name of your Developer Board that appeared in the list.
@@ -125,103 +78,23 @@ If this command fails, try using **pip** instead of **pip3**. If this didnt h
## Flashing the firmware
### Getting the flash command
To flash the firmware onto your Developer Board, run the following command in the terminal:
1. Run the Terminal and navigate to the folder with the extracted firmware.
```text
python3 -m ufbt devboard_flash
```
2. Run the following command to read the file with the flash command:
You should see the following message: `WiFi board flashed successfully`.
```text
cat flash.command
```
## If flashing failed
If you see a similar output, you can proceed to the Flashing step:
```text
esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32s2 write_flash --flash_mode dio --flash_freq 80m --flash_size 4MB 0x1000 bootloader.bin 0x10000 blackmagic.bin 0x8000 partition-table.bin
```
Don't use the exact command above for your Developer Board in the next step since it's just an example and may not match your firmware version!
If you get an error, ensure youre in the correct directory and extracted the firmware archive correctly.
***
### Flashing
1. Copy the command you got from the previous step and replace the `(PORT)` part with the name of the serial device you learned earlier.
For Windows, replace `(PORT)` with the COM port number—for example, `COM3`.
2. Run the command in the Terminal.
Your command should look similar to this:
```text
esptool.py -p /dev/cu.usbmodem01 -b 460800 --before default_reset --after hard_reset --chip esp32s2 write_flash --flash_mode dio --flash_freq 80m --flash_size 4MB 0x1000 bootloader.bin 0x10000 blackmagic.bin 0x8000 partition-table.bin
```
If you get an error, ensure that youve entered the correct serial device name and that the Developer Board is in Bootloader mode.
3. Wait till the firmware flashing is over. The flashing process takes about 30 seconds.
The Terminal output should look similar to this:
```text
esptool.py v4.6.1
Serial port /dev/cu.usbmodem01
Connecting...
Chip is ESP32-S2 (revision v0.0)
Features: WiFi, No Embedded Flash, No Embedded PSRAM, ADC and temperature sensor
calibration in BLK2 of efuse V2
Crystal is 40MHz
MAC: 00:11:22:33:44:55
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00004fff...
Flash will be erased from 0x00010000 to 0x000ecfff...
Flash will be erased from 0x00008000 to 0x00008fff...
Compressed 13248 bytes to 9298...
Wrote 13248 bytes (9298 compressed) at 0x00001000 in 0.3 seconds (effective 402.7 kbit/s)...
Hash of data verified.
Compressed 904288 bytes to 562550...
Wrote 904288 bytes (562550 compressed) at 0x00010000 in 6.7 seconds (effective 1076.5 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 124...
Wrote 3072 bytes (124 compressed) at 0x00008000 in 0.1 seconds (effective 360.8 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
```
If the Terminal output has these two lines at the end, your Developer Board has been successfully updated:
```text
Leaving...
Hard resetting via RTS pin...
```
If you get this warning, you can safely ignore it:
```text
WARNING: ESP32-S2 (revision v0.0) chip was placed into download mode using GPIO0.
esptool.py can not exit the download mode over USB. To run the app, reset the chip manually.
To suppress this note, set --after option to 'no_reset
```
#### If flashing failed
If you get an error message during the flashing process, such as:
If you get an error message during the flashing process, such as this:
```text
A fatal error occurred: Serial data stream stopped: Possible serial noise or corruption.
```
or
Or this:
```text
FileNotFoundError: [Errno 2] No such file or directory: '/dev/cu.usbmodem01'
@@ -239,8 +112,11 @@ Try doing the following:
## Finishing the installation
After flashing the firmware, you can reboot the Developer Board by pressing the **RESET** button.
After flashing the firmware:
1. Reboot the Developer Board by pressing the **RESET** button.
![Reset the Developer Board](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/rcQeKARgrVwa51tLoo-qY_monosnap-miro-2023-07-20-18-29-33.jpg)
2. Disconnect and reconnect the USB-C cable.
The Developer Board should appear as a serial device on your computer. Now, you can use it with the Black Magic Debug client of your choice.

View File

@@ -14,7 +14,7 @@ Update the firmware of your Developer Board before using it. For more informatio
## Installing Git
Youll need Git installed on your computer to clone the firmware repository. If you dont have Git, install it by doing the following:
You'll need Git installed on your computer to clone the firmware repository. If you don't have Git, install it by doing the following:
* **MacOS**
@@ -57,7 +57,9 @@ Then, run the **Flipper Build Tool** (FBT) to build the firmware:
The Developer Board can work in the **Wired** mode and two **Wireless** modes: **Wi-Fi access point (AP)** mode and **Wi-Fi client (STA)** mode. The Wired mode is the simplest to set up, but requires a USB Type-C cable. The Wireless modes are more complex to set up, but they allow you to debug your Flipper Zero wirelessly.
> **NOTE:** Use the following credentials when connecting to the Developer Board in **Wi-Fi access point** mode: Name: **blackmagic**, Password: **iamwitcher**
> **NOTE:** Use the following credentials when connecting to the Developer Board in **Wi-Fi access point** mode:\n
Name: **blackmagic**\n
Password: **iamwitcher**
## Wired
@@ -87,9 +89,9 @@ To connect the Developer Board in **Wired** mode, do the following:
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
> **NOTE:** If the Developer Board doesnt appear in the list of devices, try using a different cable, USB port, or computer.
>
> **NOTE:** Flipper Zero logs can only be viewed when the Developer Board is connected via USB. The option to view logs over Wi-Fi will be added in future updates. For more information, visit [Reading logs via the Dev Board](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/reading-logs).
> **NOTE:** If the Developer Board doesn't appear in the list of devices, try using a different cable, USB port, or computer.
>
> **NOTE:** Flipper Zero logs can only be viewed when the Developer Board is connected via USB. The option to view logs over Wi-Fi will be added in future updates. For more information, visit [Reading logs via the Dev Board](https://docs.flipperzero.one/development/hardware/wifi-debugger-module/reading-logs).
## Wireless
@@ -97,7 +99,7 @@ To connect the Developer Board in **Wired** mode, do the following:
![The Developer Board in Wi-Fi access point mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/tKRTMHAuruiLSEce2a8Ve_monosnap-miro-2023-06-22-16-39-17.jpg)
Out of the box, the Developer Board is configured to work as a **Wi-Fi access point**. This means it will create its own Wi-Fi network to which you can connect. If your Developer Board doesnt create a Wi-Fi network, it is probably configured to work in **Wi-Fi client** mode. To reset your Developer Board back to **Wi-Fi access point** mode, press and hold the **BOOT** button for 10 seconds, then wait for the module to reboot.
Out of the box, the Developer Board is configured to work as a **Wi-Fi access point**. This means it'll create its own Wi-Fi network to which you can connect. If your Developer Board doesn't create a Wi-Fi network, it is probably configured to work in **Wi-Fi client** mode. To reset your Developer Board back to **Wi-Fi access point** mode, press and hold the **BOOT** button for 10 seconds, then wait for the module to reboot.
![You can reconfigure the Developer Board mode by pressing and holding the BOOT button](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/57eELJsAwMxeZCEA1NMJw_monosnap-miro-2023-06-22-20-33-27.jpg)
@@ -110,11 +112,12 @@ To connect the Developer Board in **Wi-Fi access point** mode, do the following:
3. Connect to the network:
* Name: **blackmagic**
* Password: **iamwitcher**
4. To configure the Developer Board, open a browser and go to `http://192.168.4.1`.
#### Wi-Fi client (STA) mode
### Wi-Fi client (STA) mode
![The Developer Board in Wi-Fi client mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/xLQpFyYPfUS5Cx0uQhrNd_monosnap-miro-2023-06-23-12-34-36.jpg)
@@ -126,15 +129,15 @@ To connect the Developer Board in **Wi-Fi client** mode, you need to configure i
3. In a browser, go to the configuration page on `http://192.168.4.1`.
4. Select the **STA** mode and enter your networks **SSID** (name) and **password**. For convenience, you can click the **+** button to see the list of nearby networks.
4. Select the **STA** mode and enter your network's **SSID** (name) and **password**. For convenience, you can click the **+** button to see the list of nearby networks.
5. Save the configuration and reboot the Developer Board.
![In the Wi-Fi tab, you can set the Developer Board mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/klbLVj8lz2bEvm7j4wRaj_monosnap-miro-2023-06-23-13-06-32.jpg)
After rebooting, the Developer Board connects to your Wi-Fi network. You can connect to the device using the mDNS name [blackmagic.local](http://blackmagic.local) or the IP address it got from your router (youll have to figure this out yourself, every router is different).
After rebooting, the Developer Board connects to your Wi-Fi network. You can connect to the device using the mDNS name **blackmagic.local** or the IP address it got from your router (you'll have to figure this out yourself, every router is different).
After connecting to your debugger via [blackmagic.local](http://blackmagic.local), you can find its IP address in the **SYS** tab. You can also change the debuggers mode to **AP** or **STA** there.
After connecting to your debugger via <http://blackmagic.local>, you can find its IP address in the **SYS** tab. You can also change the debugger's mode to **AP** or **STA** there.
![In the SYS tab, you can view the IP address of your Developer Board](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/5XbUptlfqzlV0p6hRUqiG_monosnap-miro-2023-06-22-18-11-30.jpg)
@@ -145,10 +148,10 @@ After connecting to your debugger via [blackmagic.local](http://blackmagic.local
Open the **Terminal** in the **flipperzero-firmware** directory that you cloned earlier and run the following command:
```text
./fbt flash_blackmagic
./fbt flash
```
This will upload the firmware youve just built to your Flipper Zero via the Developer Board. After that, you can start debugging the firmware using the [GDB](https://www.gnu.org/software/gdb/) debugger. We recommend using **VSCode** with the recommended extensions, and we have pre-made configurations for it.
This will upload the firmware you've just built to your Flipper Zero via the Developer Board. After that, you can start debugging the firmware using the [GDB](https://www.gnu.org/software/gdb/) debugger. We recommend using **VSCode** with the recommended extensions, and we have pre-made configurations for it.
To debug in **VSCode**, do the following:
@@ -162,9 +165,9 @@ To debug in **VSCode**, do the following:
4. In VSCode, open the **Run and Debug** tab and select **Attach FW (blackmagic)** from the dropdown menu.
5. If needed, flash your Flipper Zero with the `./fbt flash_blackmagic` command, then click the **Play** button in the debug sidebar to start the debugging session.
5. If needed, flash your Flipper Zero with the `./fbt flash` command, then click the **Play** button in the debug sidebar to start the debugging session.
6. Note that starting a debug session halts the execution of the firmware, so youll need to click the **Continue** button on the toolbar at the top of your VSCode window to continue execution.
6. Note that starting a debug session halts the execution of the firmware, so you'll need to click the **Continue** button on the toolbar at the top of your VSCode window to continue execution.
![Click Continue in the toolbar to continue execution of the firmware](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/lp8ygGaZ3DvWD3OSI9yGO_monosnap-miro-2023-06-23-17-58-09.jpg)

View File

@@ -4,9 +4,11 @@ The Developer Board allows you to read Flipper Zero logs via UART. Unlike readin
> **NOTE:** Flipper Zero logs can only be viewed when the developer board is connected via USB. The option to view logs over Wi-Fi will be added in future updates.
***
## Setting the log level
Depending on your needs, you can set the log level by going to Main Menu -> Settings -> Log Level. To learn more about logging levels, visit [Settings](https://docs.flipperzero.one/basics/settings#d5TAt).
Depending on your needs, you can set the log level by going to **Main Menu -> Settings -> Log Level**. To learn more about logging levels, visit [Settings](https://docs.flipperzero.one/basics/settings#d5TAt).
![You can manually set the preferred log level](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/INzQMw8QUsG9PXi30WFS0_monosnap-miro-2023-07-11-13-29-47.jpg)
@@ -20,7 +22,7 @@ Depending on your operating system, you need to install an additional applicatio
On MacOS, you need to install the **minicom** communication program by doing the following:
1. [Install Homebrew](https://brew.sh/) by running in the Terminal the following command:
1. [Install Homebrew](https://brew.sh/) by running the following command in the Terminal:
```text
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
@@ -44,13 +46,16 @@ After installation of minicom on your macOS computer, you can connect to the Dev
Note the list of devices.
3. Connect the developer board to your computer using a USB Type-C cable.\
![The Developer Board in Wired mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/iPpsMt2-is4aIjiVeFu5t_hjxs2i1oovrnps74v5jgsimage.png)
3. Connect the developer board to your computer using a USB Type-C cable.
![Connect the developer board with a USB-C cable](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/iPpsMt2-is4aIjiVeFu5t_hjxs2i1oovrnps74v5jgsimage.png)
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
```text
/dev/cu.usbmodemblackmagic1
```
```text
/dev/cu.usbmodemblackmagic3
```
@@ -79,8 +84,8 @@ After installation of minicom on your macOS computer, you can connect to the Dev
On Linux, you need to install the **minicom** communication program. For example, on Ubuntu, run in the Terminal the following command:
```text
sudo apt install minicom
```
sudo apt install minicom
```
After installation of minicom on your Linux computer, you can connect to the Developer Board to read Flipper Zero logs by doing the following:
@@ -95,12 +100,15 @@ After installation of minicom on your Linux computer, you can connect to the Dev
Note the list of devices.
3. Connect the developer board to your computer using a USB Type-C cable.
![The Developer Board in Wired mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/iPpsMt2-is4aIjiVeFu5t_hjxs2i1oovrnps74v5jgsimage.png)
![Connect the developer board with a USB-C cable](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/iPpsMt2-is4aIjiVeFu5t_hjxs2i1oovrnps74v5jgsimage.png)
4. Rerun the command. Two new devices have to appear: this is the Developer Board.
```text
/dev/ttyACM0
```
```text
/dev/ttyACM1
```
@@ -109,7 +117,7 @@ After installation of minicom on your Linux computer, you can connect to the Dev
5. Run the following command:
```text
minicom -D /dev/<port> \-b 230400
minicom -D /dev/<port> -b 230400
```
Where `<port>` is the name of your device with a bigger number.
@@ -117,12 +125,12 @@ After installation of minicom on your Linux computer, you can connect to the Dev
Example:
```text
minicom -D /dev/ttyACM1 \-b 230400
minicom -D /dev/cu.usbmodemblackmagic3 -b 230400
```
6. View logs of your Flipper Zero in the Terminal.
> **NOTE:** If no logs are shown in the Terminal, try running the command from Step 5 with another device name.
**NOTE:** If no logs are shown in the Terminal, try running the command from Step 5 with another device name.
7. To quit, close the minicom window or quit via the minicom menu.
@@ -135,17 +143,17 @@ On Windows, do the following:
2. Cold-plug the Developer Board into your Flipper Zero by turning off the Flipper Zero, connecting the developer board, and then turning it back on.
3. Connect the developer board to your computer using a USB Type-C cable.
![The Developer Board in Wired mode](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/iPpsMt2-is4aIjiVeFu5t_hjxs2i1oovrnps74v5jgsimage.png)
![Connect the developer board with a USB-C cable](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/iPpsMt2-is4aIjiVeFu5t_hjxs2i1oovrnps74v5jgsimage.png)
4. Find the serial port that the developer board is connected to by going to **Device Manager -> Ports (COM & LPT)** and looking for a new port that appears when you connect the Wi-Fi developer board.
![Go to Device Manager -> Ports (COM & LPT)](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/KKLQJK1lvqmI5iab3d__C_image.png)
![Find the serial port in your Device Manager](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/KKLQJK1lvqmI5iab3d__C_image.png)
5. Run the PuTTY application and select **Serial** as the connection type.
6. Enter the port number you found in the previous step into the **Serial line** field.
7. Set the **Speed** parameter to **230400** and click **Open**.
![Set the required parameters](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/ROBSJyfQ_CXiy4GUZcPbs_monosnap-miro-2023-07-12-13-56-47.jpg)
![Set speed to 230400](https://archbee-image-uploads.s3.amazonaws.com/3StCFqarJkJQZV-7N79yY/ROBSJyfQ_CXiy4GUZcPbs_monosnap-miro-2023-07-12-13-56-47.jpg)
8. View logs of your Flipper Zero in the PuTTY terminal window.

View File

@@ -1,11 +1,10 @@
@INCLUDE = doxygen/Doxyfile.cfg
@INCLUDE = $(DOXY_CONFIG_DIR)/Doxyfile.cfg
GENERATE_TREEVIEW = YES # required!
DISABLE_INDEX = NO
FULL_SIDEBAR = NO
HTML_EXTRA_STYLESHEET = doxygen/doxygen-awesome-css/doxygen-awesome.css \
doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only.css \
doxygen/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css
HTML_EXTRA_STYLESHEET = $(DOXY_CONFIG_DIR)/doxygen-awesome-css/doxygen-awesome.css \
$(DOXY_CONFIG_DIR)/doxygen-awesome-css/doxygen-awesome-sidebar-only.css \
$(DOXY_CONFIG_DIR)/doxygen-awesome-css/doxygen-awesome-sidebar-only-darkmode-toggle.css
HTML_COLORSTYLE = LIGHT # required with Doxygen >= 1.9.5
HTML_HEADER = doxygen/header.html
HTML_EXTRA_FILES = doxygen/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js
HTML_HEADER = $(DOXY_CONFIG_DIR)/header.html
HTML_EXTRA_FILES = $(DOXY_CONFIG_DIR)/doxygen-awesome-css/doxygen-awesome-darkmode-toggle.js

View File

@@ -1,4 +1,4 @@
# Doxyfile 1.9.2
# Doxyfile 1.10.0
# This file describes the settings to be used by the documentation system
# doxygen (www.doxygen.org) for a project.
@@ -12,6 +12,16 @@
# For lists, items can also be appended using:
# TAG += value [value, ...]
# Values that contain spaces should be placed between quotes (\" \").
#
# Note:
#
# Use doxygen to compare the used configuration file with the template
# configuration file:
# doxygen -x [configFile]
# Use doxygen to compare the used configuration file with the template
# configuration file without replacing the environment variables or CMake type
# replacement variables:
# doxygen -x_noenv [configFile]
#---------------------------------------------------------------------------
# Project related configuration options
@@ -51,30 +61,43 @@ PROJECT_BRIEF =
# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy
# the logo to the output directory.
PROJECT_LOGO = doxygen/logo.png
PROJECT_LOGO = $(DOXY_CONFIG_DIR)/logo.png
# With the PROJECT_ICON tag one can specify an icon that is included in the tabs
# when the HTML document is shown. Doxygen will copy the logo to the output directory.
# when the HTML document is shown. Doxygen will copy the logo to the output
# directory.
PROJECT_ICON = doxygen/favicon.ico
PROJECT_ICON = $(DOXY_CONFIG_DIR)/favicon.ico
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
# into which the generated documentation will be written. If a relative path is
# entered, it will be relative to the location where doxygen was started. If
# left blank the current directory will be used.
OUTPUT_DIRECTORY = doxygen/build
OUTPUT_DIRECTORY = $(DOXY_CONFIG_DIR)/build
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub-
# directories (in 2 levels) under the output directory of each output format and
# will distribute the generated files over these directories. Enabling this
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create up to 4096
# sub-directories (in 2 levels) under the output directory of each output format
# and will distribute the generated files over these directories. Enabling this
# option can be useful when feeding doxygen a huge amount of source files, where
# putting all generated files in the same directory would otherwise causes
# performance problems for the file system.
# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to
# control the number of sub-directories.
# The default value is: NO.
CREATE_SUBDIRS = NO
# Controls the number of sub-directories that will be created when
# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every
# level increment doubles the number of directories, resulting in 4096
# directories at level 8 which is the default and also the maximum value. The
# sub-directories are organized in 2 levels, the first level always has a fixed
# number of 16 directories.
# Minimum value: 0, maximum value: 8, default value: 8.
# This tag requires that the tag CREATE_SUBDIRS is set to YES.
CREATE_SUBDIRS_LEVEL = 8
# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
# characters to appear in the names of generated files. If set to NO, non-ASCII
# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
@@ -86,14 +109,14 @@ ALLOW_UNICODE_NAMES = NO
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
# documentation generated by doxygen is written. Doxygen will use this
# information to generate all constant output in the proper language.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
# Ukrainian and Vietnamese.
# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian,
# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English
# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek,
# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with
# English messages), Korean, Korean-en (Korean with English messages), Latvian,
# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese,
# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish,
# Swedish, Turkish, Ukrainian and Vietnamese.
# The default value is: English.
OUTPUT_LANGUAGE = English
@@ -346,6 +369,17 @@ MARKDOWN_SUPPORT = YES
TOC_INCLUDE_HEADINGS = 5
# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to
# generate identifiers for the Markdown headings. Note: Every identifier is
# unique.
# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a
# sequence number starting at 0 and GITHUB use the lower case version of title
# with any whitespace replaced by '-' and punctuation characters removed.
# The default value is: DOXYGEN.
# This tag requires that the tag MARKDOWN_SUPPORT is set to YES.
MARKDOWN_ID_STYLE = DOXYGEN
# When enabled doxygen tries to link words that correspond to documented
# classes, or namespaces to their corresponding documentation. Such a link can
# be prevented in individual cases by putting a % sign in front of the word or
@@ -457,7 +491,7 @@ TYPEDEF_HIDES_STRUCT = NO
LOOKUP_CACHE_SIZE = 0
# The NUM_PROC_THREADS specifies the number threads doxygen is allowed to use
# The NUM_PROC_THREADS specifies the number of threads doxygen is allowed to use
# during processing. When set to 0 doxygen will based this on the number of
# cores available in the system. You can set it explicitly to a value larger
# than 0 to get more control over the balance between CPU load and processing
@@ -470,6 +504,14 @@ LOOKUP_CACHE_SIZE = 0
NUM_PROC_THREADS = 4
# If the TIMESTAMP tag is set different from NO then each generated page will
# contain the date or date and time when the page was generated. Setting this to
# NO can help when comparing the output of multiple runs.
# Possible values are: YES, NO, DATETIME and DATE.
# The default value is: NO.
TIMESTAMP = NO
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
@@ -551,7 +593,8 @@ HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy. If set
# to NO, these classes will be included in the various overviews. This option
# has no effect if EXTRACT_ALL is enabled.
# will also hide undocumented C++ concepts if enabled. This option has no effect
# if EXTRACT_ALL is enabled.
# The default value is: NO.
HIDE_UNDOC_CLASSES = NO
@@ -582,14 +625,15 @@ INTERNAL_DOCS = NO
# filesystem is case sensitive (i.e. it supports files in the same directory
# whose names only differ in casing), the option must be set to YES to properly
# deal with such files in case they appear in the input. For filesystems that
# are not case sensitive the option should be be set to NO to properly deal with
# are not case sensitive the option should be set to NO to properly deal with
# output files written for symbols that only differ in casing, such as for two
# classes, one named CLASS and the other named Class, and to also support
# references to files without having to specify the exact matching casing. On
# Windows (including Cygwin) and MacOS, users should typically set this option
# to NO, whereas on Linux or other Unix flavors it should typically be set to
# YES.
# The default value is: system dependent.
# Possible values are: SYSTEM, NO and YES.
# The default value is: SYSTEM.
CASE_SENSE_NAMES = NO
@@ -798,7 +842,7 @@ CITE_BIB_FILES =
# messages are off.
# The default value is: NO.
QUIET = NO
QUIET = YES
# The WARNINGS tag can be used to turn on/off the warning messages that are
# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES
@@ -814,7 +858,7 @@ WARNINGS = YES
# will automatically be disabled.
# The default value is: YES.
WARN_IF_UNDOCUMENTED = YES
WARN_IF_UNDOCUMENTED = NO
# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
# potential errors in the documentation, such as documenting some parameters in
@@ -839,16 +883,31 @@ WARN_IF_INCOMPLETE_DOC = YES
# WARN_IF_INCOMPLETE_DOC
# The default value is: NO.
WARN_NO_PARAMDOC = NO
WARN_NO_PARAMDOC = YES
# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, doxygen will warn about
# undocumented enumeration values. If set to NO, doxygen will accept
# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag
# will automatically be disabled.
# The default value is: NO.
WARN_IF_UNDOC_ENUM_VAL = NO
# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when
# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS
# then doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but
# at the end of the doxygen process doxygen will return with a non-zero status.
# Possible values are: NO, YES and FAIL_ON_WARNINGS.
# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then doxygen behaves
# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined doxygen will not
# write the warning messages in between other messages but write them at the end
# of a run, in case a WARN_LOGFILE is defined the warning messages will be
# besides being in the defined file also be shown at the end of a run, unless
# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case
# the behavior will remain as with the setting FAIL_ON_WARNINGS.
# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT.
# The default value is: NO.
WARN_AS_ERROR = NO
WARN_AS_ERROR = FAIL_ON_WARNINGS
# The WARN_FORMAT tag determines the format of the warning messages that doxygen
# can produce. The string should contain the $file, $line, and $text tags, which
@@ -856,13 +915,27 @@ WARN_AS_ERROR = NO
# and the warning text. Optionally the format may contain $version, which will
# be replaced by the version of the file (if it could be obtained via
# FILE_VERSION_FILTER)
# See also: WARN_LINE_FORMAT
# The default value is: $file:$line: $text.
WARN_FORMAT = "$file:$line: $text"
# In the $text part of the WARN_FORMAT command it is possible that a reference
# to a more specific place is given. To make it easier to jump to this place
# (outside of doxygen) the user can define a custom "cut" / "paste" string.
# Example:
# WARN_LINE_FORMAT = "'vi $file +$line'"
# See also: WARN_FORMAT
# The default value is: at line $line of file $file.
WARN_LINE_FORMAT = "at line $line of file $file"
# The WARN_LOGFILE tag can be used to specify a file to which warning and error
# messages should be written. If left blank the output is written to standard
# error (stderr).
# error (stderr). In case the file specified cannot be opened for writing the
# warning and error messages are written to standard error. When as file - is
# specified the warning and error messages are written to standard output
# (stdout).
WARN_LOGFILE =
@@ -876,23 +949,34 @@ WARN_LOGFILE =
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING
# Note: If this tag is empty the current directory is searched.
INPUT = ../applications \
../documentation \
../targets \
../assets \
../lib \
../furi \
../.vscode \
INPUT = $(DOXY_SRC_ROOT)/applications \
$(DOXY_SRC_ROOT)/documentation \
$(DOXY_SRC_ROOT)/targets \
$(DOXY_SRC_ROOT)/assets \
$(DOXY_SRC_ROOT)/lib \
$(DOXY_SRC_ROOT)/furi \
$(DOXY_SRC_ROOT)/.vscode
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
# documentation (see:
# https://www.gnu.org/software/libiconv/) for the list of possible encodings.
# See also: INPUT_FILE_ENCODING
# The default value is: UTF-8.
INPUT_ENCODING = UTF-8
# This tag can be used to specify the character encoding of the source files
# that doxygen parses The INPUT_FILE_ENCODING tag can be used to specify
# character encoding on a per file pattern basis. Doxygen will compare the file
# name with each pattern and apply the encoding instead of the default
# INPUT_ENCODING) if there is a match. The character encodings are a list of the
# form: pattern=encoding (like *.php=ISO-8859-1). See cfg_input_encoding
# "INPUT_ENCODING" for further information on supported encodings.
INPUT_FILE_ENCODING =
# If the value of the INPUT tag contains directories, you can use the
# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
# *.h) to filter out the source-files in the directories.
@@ -904,12 +988,12 @@ INPUT_ENCODING = UTF-8
# Note the list of default checked file patterns might differ from the list of
# default file extension mappings.
#
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp,
# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h,
# *.hh, *.hxx, *.hpp, *.h++, *.l, *.cs, *.d, *.php, *.php4, *.php5, *.phtml,
# *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to be provided as doxygen C
# comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, *.f18, *.f, *.for, *.vhd,
# *.vhdl, *.ucf, *.qsf and *.ice.
# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm,
# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl,
# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d,
# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to
# be provided as doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08,
# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice.
FILE_PATTERNS = *.c \
*.cc \
@@ -937,47 +1021,45 @@ RECURSIVE = YES
# Note that relative paths are relative to the directory from which doxygen is
# run.
EXCLUDE = \
../lib/mlib \
../lib/STM32CubeWB \
../lib/littlefs \
../lib/nanopb \
../assets/protobuf \
../lib/libusb_stm32 \
../lib/FreeRTOS-Kernel \
../lib/microtar \
../lib/mbedtls \
../lib/cxxheaderparser \
../lib/ST25RFAL002 \
../lib/fatfs \
../lib/mlib \
../lib/stm32wb_cmsis \
../lib/stm32wb_copro \
../lib/stm32wb_hal_driver \
../lib/stm32wb_hal \
../lib/cmsis_core \
../targets/f7/fatfs/ \
../applications/plugins/dap_link/lib/free-dap \
../applications/debug \
../applications/main \
../applications/settings \
../lib/micro-ecc \
../lib/ReadMe.md \
../lib/callback-connector \
../lib/app-scened-template \
../applications/ReadMe.md \
../targets/ReadMe.md \
../web \
../assets/protobuf \
../lib/libusb_stm32 \
../lib/FreeRTOS-Kernel \
../lib/microtar \
../lib/mbedtls \
../lib/cxxheaderparser \
../applications/external/dap_link/lib/free-dap \
../lib/heatshrink \
./doxygen/doxygen-awesome-css
EXCLUDE = $(DOXY_SRC_ROOT)/lib/mlib \
$(DOXY_SRC_ROOT)/lib/STM32CubeWB \
$(DOXY_SRC_ROOT)/lib/littlefs \
$(DOXY_SRC_ROOT)/lib/nanopb \
$(DOXY_SRC_ROOT)/assets/protobuf \
$(DOXY_SRC_ROOT)/lib/libusb_stm32 \
$(DOXY_SRC_ROOT)/lib/FreeRTOS-Kernel \
$(DOXY_SRC_ROOT)/lib/microtar \
$(DOXY_SRC_ROOT)/lib/mbedtls \
$(DOXY_SRC_ROOT)/lib/cxxheaderparser \
$(DOXY_SRC_ROOT)/lib/ST25RFAL002 \
$(DOXY_SRC_ROOT)/lib/fatfs \
$(DOXY_SRC_ROOT)/lib/mlib \
$(DOXY_SRC_ROOT)/lib/stm32wb_cmsis \
$(DOXY_SRC_ROOT)/lib/stm32wb_copro \
$(DOXY_SRC_ROOT)/lib/stm32wb_hal_driver \
$(DOXY_SRC_ROOT)/lib/stm32wb_hal \
$(DOXY_SRC_ROOT)/lib/cmsis_core \
$(DOXY_SRC_ROOT)/targets/f7/fatfs/ \
$(DOXY_SRC_ROOT)/applications/plugins/dap_link/lib/free-dap \
$(DOXY_SRC_ROOT)/applications/debug \
$(DOXY_SRC_ROOT)/applications/main \
$(DOXY_SRC_ROOT)/applications/settings \
$(DOXY_SRC_ROOT)/lib/micro-ecc \
$(DOXY_SRC_ROOT)/lib/ReadMe.md \
$(DOXY_SRC_ROOT)/lib/callback-connector \
$(DOXY_SRC_ROOT)/lib/app-scened-template \
$(DOXY_SRC_ROOT)/applications/ReadMe.md \
$(DOXY_SRC_ROOT)/targets/ReadMe.md \
$(DOXY_SRC_ROOT)/web \
$(DOXY_SRC_ROOT)/assets/protobuf \
$(DOXY_SRC_ROOT)/lib/libusb_stm32 \
$(DOXY_SRC_ROOT)/lib/FreeRTOS-Kernel \
$(DOXY_SRC_ROOT)/lib/microtar \
$(DOXY_SRC_ROOT)/lib/mbedtls \
$(DOXY_SRC_ROOT)/lib/cxxheaderparser \
$(DOXY_SRC_ROOT)/applications/external/dap_link/lib/free-dap \
$(DOXY_SRC_ROOT)/lib/heatshrink \
$(DOXY_CONFIG_DIR)/doxygen-awesome-css
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
# directories that are symbolic links (a Unix file system feature) are excluded
@@ -999,10 +1081,7 @@ EXCLUDE_PATTERNS =
# (namespaces, classes, functions, etc.) that should be excluded from the
# output. The symbol name can be a fully qualified name, a word, or if the
# wildcard * is used, a substring. Examples: ANamespace, AClass,
# AClass::ANamespace, ANamespace::*Test
#
# Note that the wildcards are matched against the file with absolute path, so to
# exclude all test directories use the pattern */test/*
# ANamespace::AClass, ANamespace::*Test
EXCLUDE_SYMBOLS =
@@ -1047,6 +1126,11 @@ IMAGE_PATH =
# code is scanned, but not when the output code is generated. If lines are added
# or removed, the anchors will not be placed correctly.
#
# Note that doxygen will use the data processed and written to standard output
# for further processing, therefore nothing else, like debug statements or used
# commands (so in case of a Windows batch file always use @echo OFF), should be
# written to standard output.
#
# Note that for custom extensions or not directly supported extensions you also
# need to set EXTENSION_MAPPING for the extension otherwise the files are not
# properly processed by doxygen.
@@ -1088,6 +1172,15 @@ FILTER_SOURCE_PATTERNS =
USE_MDFILE_AS_MAINPAGE =
# The Fortran standard specifies that for fixed formatted Fortran code all
# characters from position 72 are to be considered as comment. A common
# extension is to allow longer lines before the automatic comment starts. The
# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can
# be processed before the automatic comment starts.
# Minimum value: 7, maximum value: 10000, default value: 72.
FORTRAN_COMMENT_AFTER = 72
#---------------------------------------------------------------------------
# Configuration options related to source browsing
#---------------------------------------------------------------------------
@@ -1102,7 +1195,8 @@ USE_MDFILE_AS_MAINPAGE =
SOURCE_BROWSER = NO
# Setting the INLINE_SOURCES tag to YES will include the body of functions,
# classes and enums directly into the documentation.
# multi-line macros, enums or list initialized variables directly into the
# documentation.
# The default value is: NO.
INLINE_SOURCES = NO
@@ -1185,10 +1279,11 @@ VERBATIM_HEADERS = YES
ALPHABETICAL_INDEX = YES
# In case all classes in a project start with a common prefix, all classes will
# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
# can be used to specify a prefix (or a list of prefixes) that should be ignored
# while generating the index headers.
# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes)
# that should be ignored while generating the index headers. The IGNORE_PREFIX
# tag works for classes, function and member names. The entity will be placed in
# the alphabetical list under the first letter of the entity name that remains
# after removing the prefix.
# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
IGNORE_PREFIX =
@@ -1267,7 +1362,12 @@ HTML_STYLESHEET =
# Doxygen will copy the style sheet files to the output directory.
# Note: The order of the extra style sheet files is of importance (e.g. the last
# style sheet in the list overrules the setting of the previous ones in the
# list). For an example see the documentation.
# list).
# Note: Since the styling of scrollbars can currently not be overruled in
# Webkit/Chromium, the styling will be left out of the default doxygen.css if
# one or more extra stylesheets have been specified. So if scrollbar
# customization is desired it has to be added explicitly. For an example see the
# documentation.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_EXTRA_STYLESHEET =
@@ -1282,6 +1382,19 @@ HTML_EXTRA_STYLESHEET =
HTML_EXTRA_FILES =
# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output
# should be rendered with a dark or light theme.
# Possible values are: LIGHT always generate light mode output, DARK always
# generate dark mode output, AUTO_LIGHT automatically set the mode according to
# the user preference, use light mode if no preference is set (the default),
# AUTO_DARK automatically set the mode according to the user preference, use
# dark mode if no preference is set and TOGGLE allow to user to switch between
# light and dark mode via a button.
# The default value is: AUTO_LIGHT.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COLORSTYLE = AUTO_LIGHT
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
# will adjust the colors in the style sheet and background images according to
# this color. Hue is specified as an angle on a color-wheel, see
@@ -1312,15 +1425,6 @@ HTML_COLORSTYLE_SAT = 100
HTML_COLORSTYLE_GAMMA = 80
# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
# page will contain the date and time when the page was generated. Setting this
# to YES can help to show when doxygen was last run and thus if the
# documentation is up to date.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_TIMESTAMP = NO
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML
# documentation will contain a main index with vertical navigation menus that
# are dynamically created via JavaScript. If disabled, the navigation index will
@@ -1340,6 +1444,33 @@ HTML_DYNAMIC_MENUS = YES
HTML_DYNAMIC_SECTIONS = NO
# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be
# dynamically folded and expanded in the generated HTML source code.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_CODE_FOLDING = YES
# If the HTML_COPY_CLIPBOARD tag is set to YES then doxygen will show an icon in
# the top right corner of code and text fragments that allows the user to copy
# its content to the clipboard. Note this only works if supported by the browser
# and the web page is served via a secure context (see:
# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file:
# protocol.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_COPY_CLIPBOARD = YES
# Doxygen stores a couple of settings persistently in the browser (via e.g.
# cookies). By default these settings apply to all HTML pages generated by
# doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store
# the settings under a project specific key, such that the user preferences will
# be stored separately.
# This tag requires that the tag GENERATE_HTML is set to YES.
HTML_PROJECT_COOKIE =
# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
# shown in the various tree structured indices initially; the user can expand
# and collapse entries dynamically later on. Doxygen will expand the tree to
@@ -1376,6 +1507,13 @@ GENERATE_DOCSET = NO
DOCSET_FEEDNAME = "Doxygen generated docs"
# This tag determines the URL of the docset feed. A documentation feed provides
# an umbrella under which multiple documentation sets from a single provider
# (such as a company or product suite) can be grouped.
# This tag requires that the tag GENERATE_DOCSET is set to YES.
DOCSET_FEEDURL =
# This tag specifies a string that should uniquely identify the documentation
# set bundle. This should be a reverse domain-name style string, e.g.
# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
@@ -1463,6 +1601,16 @@ BINARY_TOC = NO
TOC_EXPAND = NO
# The SITEMAP_URL tag is used to specify the full URL of the place where the
# generated documentation will be placed on the server by the user during the
# deployment of the documentation. The generated sitemap is called sitemap.xml
# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL
# is specified no sitemap is generated. For information about the sitemap
# protocol see https://www.sitemaps.org
# This tag requires that the tag GENERATE_HTML is set to YES.
SITEMAP_URL =
# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
@@ -1580,7 +1728,7 @@ GENERATE_TREEVIEW = NO
# area (value NO) or if it should extend to the full height of the window (value
# YES). Setting this to YES gives a layout similar to
# https://docs.readthedocs.io with more room for contents, but less room for the
# project logo, title, and description. If either GENERATOR_TREEVIEW or
# project logo, title, and description. If either GENERATE_TREEVIEW or
# DISABLE_INDEX is set to NO, this option has no effect.
# The default value is: NO.
# This tag requires that the tag GENERATE_HTML is set to YES.
@@ -1611,6 +1759,13 @@ TREEVIEW_WIDTH = 250
EXT_LINKS_IN_WINDOW = NO
# If the OBFUSCATE_EMAILS tag is set to YES, doxygen will obfuscate email
# addresses.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
OBFUSCATE_EMAILS = YES
# If the HTML_FORMULA_FORMAT option is set to svg, doxygen will use the pdf2svg
# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see
# https://inkscape.org) to generate formulas as SVG images instead of PNGs for
@@ -1631,17 +1786,6 @@ HTML_FORMULA_FORMAT = png
FORMULA_FONTSIZE = 10
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images
# generated for formulas are transparent PNGs. Transparent PNGs are not
# supported properly for IE 6.0, but are supported on all modern browsers.
#
# Note that when changing this option you need to delete any form_*.png files in
# the HTML output directory before the changes have effect.
# The default value is: YES.
# This tag requires that the tag GENERATE_HTML is set to YES.
FORMULA_TRANSPARENT = YES
# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands
# to create new LaTeX commands to be used in formulas as building blocks. See
# the section "Including formulas" for details.
@@ -1703,8 +1847,8 @@ MATHJAX_RELPATH =
# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
# extension names that should be enabled during MathJax rendering. For example
# for MathJax version 2 (see https://docs.mathjax.org/en/v2.7-latest/tex.html
# #tex-and-latex-extensions):
# for MathJax version 2 (see
# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions):
# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
# For example for MathJax version 3 (see
# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html):
@@ -1955,9 +2099,16 @@ PDF_HYPERLINKS = YES
USE_PDFLATEX = YES
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
# command to the generated LaTeX files. This will instruct LaTeX to keep running
# if errors occur, instead of asking the user for help.
# The LATEX_BATCHMODE tag signals the behavior of LaTeX in case of an error.
# Possible values are: NO same as ERROR_STOP, YES same as BATCH, BATCH In batch
# mode nothing is printed on the terminal, errors are scrolled as if <return> is
# hit at every error; missing files that TeX tries to input or request from
# keyboard input (\read on a not open input stream) cause the job to abort,
# NON_STOP In nonstop mode the diagnostic message will appear on the terminal,
# but there is no possibility of user interaction just like in batch mode,
# SCROLL In scroll mode, TeX will stop only for missing files to input or if
# keyboard input is necessary and ERROR_STOP In errorstop mode, TeX will stop at
# each error, asking for user intervention.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
@@ -1978,14 +2129,6 @@ LATEX_HIDE_INDICES = NO
LATEX_BIB_STYLE = plain
# If the LATEX_TIMESTAMP tag is set to YES then the footer of each generated
# page will contain the date and time when the page was generated. Setting this
# to NO can help when comparing the output of multiple runs.
# The default value is: NO.
# This tag requires that the tag GENERATE_LATEX is set to YES.
LATEX_TIMESTAMP = NO
# The LATEX_EMOJI_DIRECTORY tag is used to specify the (relative or absolute)
# path from which the emoji images will be read. If a relative path is entered,
# it will be relative to the LATEX_OUTPUT directory. If left blank the
@@ -2151,13 +2294,39 @@ DOCBOOK_OUTPUT = docbook
#---------------------------------------------------------------------------
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures
# AutoGen Definitions (see https://autogen.sourceforge.net/) file that captures
# the structure of the code including all documentation. Note that this feature
# is still experimental and incomplete at the moment.
# The default value is: NO.
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# Configuration options related to Sqlite3 output
#---------------------------------------------------------------------------
# If the GENERATE_SQLITE3 tag is set to YES doxygen will generate a Sqlite3
# database with symbols found by doxygen stored in tables.
# The default value is: NO.
GENERATE_SQLITE3 = NO
# The SQLITE3_OUTPUT tag is used to specify where the Sqlite3 database will be
# put. If a relative path is entered the value of OUTPUT_DIRECTORY will be put
# in front of it.
# The default directory is: sqlite3.
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
SQLITE3_OUTPUT = sqlite3
# The SQLITE3_RECREATE_DB tag is set to YES, the existing doxygen_sqlite3.db
# database file will be recreated with each doxygen run. If set to NO, doxygen
# will warn if a database file is already found and not modify it.
# The default value is: YES.
# This tag requires that the tag GENERATE_SQLITE3 is set to YES.
SQLITE3_RECREATE_DB = YES
#---------------------------------------------------------------------------
# Configuration options related to the Perl module output
#---------------------------------------------------------------------------
@@ -2232,7 +2401,8 @@ SEARCH_INCLUDES = YES
# The INCLUDE_PATH tag can be used to specify one or more directories that
# contain include files that are not input files but should be processed by the
# preprocessor.
# preprocessor. Note that the INCLUDE_PATH is not recursive, so the setting of
# RECURSIVE has no effect here.
# This tag requires that the tag SEARCH_INCLUDES is set to YES.
INCLUDE_PATH =
@@ -2299,15 +2469,15 @@ TAGFILES =
GENERATE_TAGFILE =
# If the ALLEXTERNALS tag is set to YES, all external class will be listed in
# the class index. If set to NO, only the inherited external classes will be
# listed.
# If the ALLEXTERNALS tag is set to YES, all external classes and namespaces
# will be listed in the class and namespace index. If set to NO, only the
# inherited external classes will be listed.
# The default value is: NO.
ALLEXTERNALS = NO
# If the EXTERNAL_GROUPS tag is set to YES, all external groups will be listed
# in the modules index. If set to NO, only the current project's groups will be
# in the topic index. If set to NO, only the current project's groups will be
# listed.
# The default value is: YES.
@@ -2321,25 +2491,9 @@ EXTERNAL_GROUPS = YES
EXTERNAL_PAGES = YES
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
# Configuration options related to diagram generator tools
#---------------------------------------------------------------------------
# If the CLASS_DIAGRAMS tag is set to YES, doxygen will generate a class diagram
# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
# NO turns the diagrams off. Note that this option also works with HAVE_DOT
# disabled, but it is recommended to install and use dot, since it yields more
# powerful graphs.
# The default value is: YES.
CLASS_DIAGRAMS = YES
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path.
DIA_PATH =
# If set to YES the inheritance and collaboration graphs will hide inheritance
# and usage relations if the target is undocumented or is not a class.
# The default value is: YES.
@@ -2348,7 +2502,7 @@ HIDE_UNDOC_RELATIONS = YES
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
# available from the path. This tool is part of Graphviz (see:
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# https://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
# Bell Labs. The other options in this section have no effect if this option is
# set to NO
# The default value is: NO.
@@ -2365,49 +2519,77 @@ HAVE_DOT = NO
DOT_NUM_THREADS = 0
# When you want a differently looking font in the dot files that doxygen
# generates you can specify the font name using DOT_FONTNAME. You need to make
# sure dot is able to find the font, which can be done by putting it in a
# standard location or by setting the DOTFONTPATH environment variable or by
# setting DOT_FONTPATH to the directory containing the font.
# The default value is: Helvetica.
# DOT_COMMON_ATTR is common attributes for nodes, edges and labels of
# subgraphs. When you want a differently looking font in the dot files that
# doxygen generates you can specify fontname, fontcolor and fontsize attributes.
# For details please see <a href=https://graphviz.org/doc/info/attrs.html>Node,
# Edge and Graph Attributes specification</a> You need to make sure dot is able
# to find the font, which can be done by putting it in a standard location or by
# setting the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the
# directory containing the font. Default graphviz fontsize is 14.
# The default value is: fontname=Helvetica,fontsize=10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTNAME = Helvetica
DOT_COMMON_ATTR = "fontname=Helvetica,fontsize=10"
# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
# dot graphs.
# Minimum value: 4, maximum value: 24, default value: 10.
# DOT_EDGE_ATTR is concatenated with DOT_COMMON_ATTR. For elegant style you can
# add 'arrowhead=open, arrowtail=open, arrowsize=0.5'. <a
# href=https://graphviz.org/doc/info/arrows.html>Complete documentation about
# arrows shapes.</a>
# The default value is: labelfontname=Helvetica,labelfontsize=10.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTSIZE = 10
DOT_EDGE_ATTR = "labelfontname=Helvetica,labelfontsize=10"
# By default doxygen will tell dot to use the default font as specified with
# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
# the path where dot can find it using this tag.
# DOT_NODE_ATTR is concatenated with DOT_COMMON_ATTR. For view without boxes
# around nodes set 'shape=plain' or 'shape=plaintext' <a
# href=https://www.graphviz.org/doc/info/shapes.html>Shapes specification</a>
# The default value is: shape=box,height=0.2,width=0.4.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_NODE_ATTR = "shape=box,height=0.2,width=0.4"
# You can set the path where dot can find font specified with fontname in
# DOT_COMMON_ATTR and others dot attributes.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_FONTPATH =
# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
# each documented class showing the direct and indirect inheritance relations.
# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
# If the CLASS_GRAPH tag is set to YES or GRAPH or BUILTIN then doxygen will
# generate a graph for each documented class showing the direct and indirect
# inheritance relations. In case the CLASS_GRAPH tag is set to YES or GRAPH and
# HAVE_DOT is enabled as well, then dot will be used to draw the graph. In case
# the CLASS_GRAPH tag is set to YES and HAVE_DOT is disabled or if the
# CLASS_GRAPH tag is set to BUILTIN, then the built-in generator will be used.
# If the CLASS_GRAPH tag is set to TEXT the direct and indirect inheritance
# relations will be shown as texts / links. Explicit enabling an inheritance
# graph or choosing a different representation for an inheritance graph of a
# specific class, can be accomplished by means of the command \inheritancegraph.
# Disabling an inheritance graph can be accomplished by means of the command
# \hideinheritancegraph.
# Possible values are: NO, YES, TEXT, GRAPH and BUILTIN.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
CLASS_GRAPH = YES
# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
# graph for each documented class showing the direct and indirect implementation
# dependencies (inheritance, containment, and class references variables) of the
# class with other documented classes.
# class with other documented classes. Explicit enabling a collaboration graph,
# when COLLABORATION_GRAPH is set to NO, can be accomplished by means of the
# command \collaborationgraph. Disabling a collaboration graph can be
# accomplished by means of the command \hidecollaborationgraph.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
COLLABORATION_GRAPH = YES
# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
# groups, showing the direct groups dependencies.
# groups, showing the direct groups dependencies. Explicit enabling a group
# dependency graph, when GROUP_GRAPHS is set to NO, can be accomplished by means
# of the command \groupgraph. Disabling a directory graph can be accomplished by
# means of the command \hidegroupgraph. See also the chapter Grouping in the
# manual.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2449,8 +2631,8 @@ DOT_UML_DETAILS = NO
# The DOT_WRAP_THRESHOLD tag can be used to set the maximum number of characters
# to display on a single line. If the actual line length exceeds this threshold
# significantly it will wrapped across multiple lines. Some heuristics are apply
# to avoid ugly line breaks.
# significantly it will be wrapped across multiple lines. Some heuristics are
# applied to avoid ugly line breaks.
# Minimum value: 0, maximum value: 1000, default value: 17.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2467,7 +2649,9 @@ TEMPLATE_RELATIONS = NO
# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
# YES then doxygen will generate a graph for each documented file showing the
# direct and indirect include dependencies of the file with other documented
# files.
# files. Explicit enabling an include graph, when INCLUDE_GRAPH is is set to NO,
# can be accomplished by means of the command \includegraph. Disabling an
# include graph can be accomplished by means of the command \hideincludegraph.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2476,7 +2660,10 @@ INCLUDE_GRAPH = YES
# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
# set to YES then doxygen will generate a graph for each documented file showing
# the direct and indirect include dependencies of the file with other documented
# files.
# files. Explicit enabling an included by graph, when INCLUDED_BY_GRAPH is set
# to NO, can be accomplished by means of the command \includedbygraph. Disabling
# an included by graph can be accomplished by means of the command
# \hideincludedbygraph.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2516,16 +2703,26 @@ GRAPHICAL_HIERARCHY = YES
# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
# dependencies a directory has on other directories in a graphical way. The
# dependency relations are determined by the #include relations between the
# files in the directories.
# files in the directories. Explicit enabling a directory graph, when
# DIRECTORY_GRAPH is set to NO, can be accomplished by means of the command
# \directorygraph. Disabling a directory graph can be accomplished by means of
# the command \hidedirectorygraph.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
DIRECTORY_GRAPH = YES
# The DIR_GRAPH_MAX_DEPTH tag can be used to limit the maximum number of levels
# of child directories generated in directory dependency graphs by dot.
# Minimum value: 1, maximum value: 25, default value: 1.
# This tag requires that the tag DIRECTORY_GRAPH is set to YES.
DIR_GRAPH_MAX_DEPTH = 1
# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
# generated by dot. For an explanation of the image formats see the section
# output formats in the documentation of the dot tool (Graphviz (see:
# http://www.graphviz.org/)).
# https://www.graphviz.org/)).
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
# to make the SVG files visible in IE 9+ (other browsers do not have this
# requirement).
@@ -2562,11 +2759,12 @@ DOT_PATH =
DOTFILE_DIRS =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
# command).
# You can include diagrams made with dia in doxygen documentation. Doxygen will
# then run dia to produce the diagram and insert it in the documentation. The
# DIA_PATH tag allows you to specify the directory where the dia binary resides.
# If left empty dia is assumed to be found in the default search path.
MSCFILE_DIRS =
DIA_PATH =
# The DIAFILE_DIRS tag can be used to specify one or more directories that
# contain dia files that are included in the documentation (see the \diafile
@@ -2575,10 +2773,10 @@ MSCFILE_DIRS =
DIAFILE_DIRS =
# When using plantuml, the PLANTUML_JAR_PATH tag should be used to specify the
# path where java can find the plantuml.jar file. If left blank, it is assumed
# PlantUML is not used or called during a preprocessing step. Doxygen will
# generate a warning when it encounters a \startuml command in this case and
# will not generate output for the diagram.
# path where java can find the plantuml.jar file or to the filename of jar file
# to be used. If left blank, it is assumed PlantUML is not used or called during
# a preprocessing step. Doxygen will generate a warning when it encounters a
# \startuml command in this case and will not generate output for the diagram.
PLANTUML_JAR_PATH =
@@ -2616,18 +2814,6 @@ DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
# background. This is disabled by default, because dot on Windows does not seem
# to support this out of the box.
#
# Warning: Depending on the platform used, enabling this option may lead to
# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
# read).
# The default value is: NO.
# This tag requires that the tag HAVE_DOT is set to YES.
DOT_TRANSPARENT = NO
# Set the DOT_MULTI_TARGETS tag to YES to allow dot to generate multiple output
# files in one run (i.e. multiple -o and -T options on the command line). This
# makes dot run faster, but since only newer versions of dot (>1.8.10) support
@@ -2640,6 +2826,8 @@ DOT_MULTI_TARGETS = NO
# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
# explaining the meaning of the various boxes and arrows in the dot generated
# graphs.
# Note: This tag requires that UML_LOOK isn't set, i.e. the doxygen internal
# graphical representation for inheritance and collaboration diagrams is used.
# The default value is: YES.
# This tag requires that the tag HAVE_DOT is set to YES.
@@ -2653,3 +2841,19 @@ GENERATE_LEGEND = YES
# The default value is: YES.
DOT_CLEANUP = YES
# You can define message sequence charts within doxygen comments using the \msc
# command. If the MSCGEN_TOOL tag is left empty (the default), then doxygen will
# use a built-in version of mscgen tool to produce the charts. Alternatively,
# the MSCGEN_TOOL tag can also specify the name an external tool. For instance,
# specifying prog as the value, doxygen will call the tool as prog -T
# <outfile_format> -o <outputfile> <inputfile>. The external tool should support
# output file formats "png", "eps", "svg", and "ismap".
MSCGEN_TOOL =
# The MSCFILE_DIRS tag can be used to specify one or more directories that
# contain msc files that are included in the documentation (see the \mscfile
# command).
MSCFILE_DIRS =

View File

@@ -79,6 +79,7 @@ To use language servers other than the default VS Code C/C++ language server, us
- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs. Supports `ARGS="..."` to pass extra arguments to clang-format.
- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests. Supports `ARGS="..."` to pass extra arguments to black.
- `firmware_pvs` - generate a PVS Studio report for the firmware. Requires PVS Studio to be available on your system's `PATH`.
- `doxygen` - generate Doxygen documentation for the firmware. `doxy` target also opens web browser to view the generated documentation.
- `cli` - start a Flipper CLI session over USB.
### Firmware targets

View File

@@ -98,9 +98,11 @@ Will wait indefinitely for a button to be pressed
Delay between keypresses.
| Command | Parameters | Notes |
| ------------ | ----------------- | --------------------------------------------- |
| -------------------- | ----------------- | --------------------------------------------- |
| STRING_DELAY | Delay value in ms | Applied once to next appearing STRING command |
| STRINGDELAY | Delay value in ms | Same as STRING_DELAY |
| DEFAULT_STRING_DELAY | Delay value in ms | Apply to every appearing STRING command |
| DEFAULTSTRINGDELAY | Delay value in ms | Same as DEFAULT_STRING_DELAY |
### Repeat

View File

@@ -33,15 +33,13 @@ typedef enum {
FlipperApplicationLoadStatusMissingImports,
} FlipperApplicationLoadStatus;
/**
* @brief Get text description of preload status
/** Get text description of preload status
* @param status Status code
* @return String pointer to description
*/
const char* flipper_application_preload_status_to_string(FlipperApplicationPreloadStatus status);
/**
* @brief Get text description of load status
/** Get text description of load status
* @param status Status code
* @return String pointer to description
*/
@@ -61,8 +59,7 @@ typedef struct {
uint8_t* debug_link;
} FlipperApplicationState;
/**
* @brief Initialize FlipperApplication object
/** Initialize FlipperApplication object
* @param storage Storage instance
* @param api_interface ELF API interface to use for pre-loading and symbol resolving
* @return Application instance
@@ -70,44 +67,44 @@ typedef struct {
FlipperApplication*
flipper_application_alloc(Storage* storage, const ElfApiInterface* api_interface);
/**
* @brief Destroy FlipperApplication object
/** Destroy FlipperApplication object
* @param app Application pointer
*/
void flipper_application_free(FlipperApplication* app);
/**
* @brief Validate elf file and load application metadata
/** Validate elf file and load application metadata
*
* @param app Application pointer
* @param[in] path The path to fap file
*
* @return Preload result code
*/
FlipperApplicationPreloadStatus
flipper_application_preload(FlipperApplication* app, const char* path);
/**
* @brief Validate elf file and load application manifest
/** Validate elf file and load application manifest
*
* @param app Application pointer
* @param[in] path The path to fap file
*
* @return Preload result code
*/
FlipperApplicationPreloadStatus
flipper_application_preload_manifest(FlipperApplication* app, const char* path);
/**
* @brief Get pointer to application manifest for preloaded application
/** Get pointer to application manifest for preloaded application
* @param app Application pointer
* @return Pointer to application manifest
*/
const FlipperApplicationManifest* flipper_application_get_manifest(FlipperApplication* app);
/**
* @brief Load sections and process relocations for already pre-loaded application
/** Load sections and process relocations for already pre-loaded application
* @param app Application pointer
* @return Load result code
*/
FlipperApplicationLoadStatus flipper_application_map_to_memory(FlipperApplication* app);
/**
* @brief Allocate application thread at entry point address, using app name and
/** Allocate application thread at entry point address, using app name and
* stack size from metadata. Returned thread isn't started yet.
* Can be only called once for application instance.
* @param app Applicaiton pointer
@@ -116,20 +113,17 @@ FlipperApplicationLoadStatus flipper_application_map_to_memory(FlipperApplicatio
*/
FuriThread* flipper_application_alloc_thread(FlipperApplication* app, const char* args);
/**
* @brief Check if application is a plugin (not a runnable standalone app)
/** Check if application is a plugin (not a runnable standalone app)
* @param app Application pointer
* @return true if application is a plugin, false otherwise
*/
bool flipper_application_is_plugin(FlipperApplication* app);
/**
* @brief Entry point prototype for standalone applications
/** Entry point prototype for standalone applications
*/
typedef int32_t (*FlipperApplicationEntryPoint)(void*);
/**
* @brief An object that describes a plugin - must be returned by plugin's entry point
/** An object that describes a plugin - must be returned by plugin's entry point
*/
typedef struct {
const char* appid;
@@ -137,21 +131,18 @@ typedef struct {
const void* entry_point;
} FlipperAppPluginDescriptor;
/**
* @brief Entry point prototype for plugins
/** Entry point prototype for plugins
*/
typedef const FlipperAppPluginDescriptor* (*FlipperApplicationPluginEntryPoint)(void);
/**
* @brief Get plugin descriptor for preloaded plugin
/** Get plugin descriptor for preloaded plugin
* @param app Application pointer
* @return Pointer to plugin descriptor
*/
const FlipperAppPluginDescriptor*
flipper_application_plugin_get_descriptor(FlipperApplication* app);
/**
* @brief Load name and icon from FAP file.
/** Load name and icon from FAP file.
*
* @param path Path to FAP file.
* @param storage Storage instance.

View File

@@ -1,6 +1,4 @@
/**
* @file flipper_format.h
* Flipper File Format helper library.
/** @file flipper_format.h Flipper File Format helper library.
*
* Flipper File Format is a fairly simple format for storing data in a file.
*
@@ -11,7 +9,9 @@
* Field name: field value
* ~~~~~~~~~~~~~~~~~~~~~
*
* Lines starting with the # character are ignored (considered as comments). The separator between the name of the value and the value itself is the string ": ".
* Lines starting with the # character are ignored (considered as comments). The
* separator between the name of the value and the value itself is the string
* ": ".
*
* Currently supported types:
*
@@ -25,7 +25,9 @@
*
* End of line is LF when writing, but CR is supported when reading.
*
* The library is designed in such a way that comments and field values are completely ignored when searching for keys, that is, they do not consume memory.
* The library is designed in such a way that comments and field values are
* completely ignored when searching for keys, that is, they do not consume
* memory.
*
* File example:
*
@@ -43,22 +45,19 @@
* ~~~~~~~~~~~~~~~~~~~~~
* FlipperFormat* format = flipper_format_file_alloc(storage);
*
* do {
* const uint32_t version = 1;
* const char* string_value = "String value";
* const uint32_t uint32_value = 1234;
* const uint16_t array_size = 4;
* const uint8_t* array[array_size] = {0x00, 0x01, 0xFF, 0xA3};
* do { const uint32_t version = 1; const char* string_value = "String value";
* const uint32_t uint32_value = 1234; const uint16_t array_size = 4; const
* uint8_t* array[array_size] = {0x00, 0x01, 0xFF, 0xA3};
*
* if(!flipper_format_file_open_new(format, EXT_PATH("flipper_format_test"))) break;
* if(!flipper_format_write_header_cstr(format, "Flipper Test File", version)) break;
* if(!flipper_format_write_comment_cstr(format, "Just test file")) break;
* if(!flipper_format_write_string_cstr(format, "String", string_value)) break;
* if(!flipper_format_write_uint32(format, "UINT", &uint32_value, 1)) break;
* if(!flipper_format_write_hex(format, "Hex Array", array, array_size)) break;
* if(!flipper_format_file_open_new(format, EXT_PATH("flipper_format_test")))
* break; if(!flipper_format_write_header_cstr(format, "Flipper Test File",
* version)) break; if(!flipper_format_write_comment_cstr(format,
* "Just test file")) break; if(!flipper_format_write_string_cstr(format,
* "String", string_value)) break; if(!flipper_format_write_uint32(format,
* "UINT", &uint32_value, 1)) break; if(!flipper_format_write_hex(format,
* "Hex Array", array, array_size)) break;
*
* // signal that the file was written successfully
* } while(0);
* // signal that the file was written successfully } while(0);
*
* flipper_format_free(file);
* ~~~~~~~~~~~~~~~~~~~~~
@@ -68,28 +67,21 @@
* ~~~~~~~~~~~~~~~~~~~~~
* FlipperFormat* file = flipper_format_file_alloc(storage);
*
* do {
* uint32_t version = 1;
* FuriString* file_type;
* FuriString* string_value;
* uint32_t uint32_value = 1;
* uint16_t array_size = 4;
* uint8_t* array[array_size] = {0};
* file_type = furi_string_alloc();
* string_value = furi_string_alloc();
* do { uint32_t version = 1; FuriString* file_type; FuriString* string_value;
* uint32_t uint32_value = 1; uint16_t array_size = 4; uint8_t*
* array[array_size] = {0}; file_type = furi_string_alloc(); string_value =
* furi_string_alloc();
*
* if(!flipper_format_file_open_existing(file, EXT_PATH("flipper_format_test"))) break;
* if(!flipper_format_read_header(file, file_type, &version)) break;
* if(!flipper_format_file_open_existing(file, EXT_PATH("flipper_format_test")))
* break; if(!flipper_format_read_header(file, file_type, &version)) break;
* if(!flipper_format_read_string(file, "String", string_value)) break;
* if(!flipper_format_read_uint32(file, "UINT", &uint32_value, 1)) break;
* if(!flipper_format_read_hex(file, "Hex Array", array, array_size)) break;
*
* // signal that the file was read successfully
* } while(0);
* // signal that the file was read successfully } while(0);
*
* flipper_format_free(file);
* ~~~~~~~~~~~~~~~~~~~~~
*
*/
#pragma once
@@ -102,135 +94,153 @@ extern "C" {
typedef struct FlipperFormat FlipperFormat;
/**
* Allocate FlipperFormat as string.
/** Allocate FlipperFormat as string.
*
* @return FlipperFormat* pointer to a FlipperFormat instance
*/
FlipperFormat* flipper_format_string_alloc(void);
/**
* Allocate FlipperFormat as file.
/** Allocate FlipperFormat as file.
*
* @param storage The storage
*
* @return FlipperFormat* pointer to a FlipperFormat instance
*/
FlipperFormat* flipper_format_file_alloc(Storage* storage);
/**
* Allocate FlipperFormat as file, buffered mode.
/** Allocate FlipperFormat as file, buffered mode.
*
* @param storage The storage
*
* @return FlipperFormat* pointer to a FlipperFormat instance
*/
FlipperFormat* flipper_format_buffered_file_alloc(Storage* storage);
/**
* Open existing file.
* Use only if FlipperFormat allocated as a file.
/** Open existing file. Use only if FlipperFormat allocated as a file.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param path File path
*
* @return True on success
*/
bool flipper_format_file_open_existing(FlipperFormat* flipper_format, const char* path);
/**
* Open existing file, buffered mode.
* Use only if FlipperFormat allocated as a buffered file.
/** Open existing file, buffered mode. Use only if FlipperFormat allocated as a
* buffered file.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param path File path
*
* @return True on success
*/
bool flipper_format_buffered_file_open_existing(FlipperFormat* flipper_format, const char* path);
/**
* Open existing file for writing and add values to the end of file.
* Use only if FlipperFormat allocated as a file.
/** Open existing file for writing and add values to the end of file. Use only if
* FlipperFormat allocated as a file.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param path File path
*
* @return True on success
*/
bool flipper_format_file_open_append(FlipperFormat* flipper_format, const char* path);
/**
* Open file. Creates a new file, or deletes the contents of the file if it already exists.
* Use only if FlipperFormat allocated as a file.
/** Open file. Creates a new file, or deletes the contents of the file if it
* already exists. Use only if FlipperFormat allocated as a file.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param path File path
*
* @return True on success
*/
bool flipper_format_file_open_always(FlipperFormat* flipper_format, const char* path);
/**
* Open file. Creates a new file, or deletes the contents of the file if it already exists, buffered mode.
* Use only if FlipperFormat allocated as a buffered file.
/** Open file. Creates a new file, or deletes the contents of the file if it
* already exists, buffered mode. Use only if FlipperFormat allocated as a
* buffered file.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param path File path
*
* @return True on success
*/
bool flipper_format_buffered_file_open_always(FlipperFormat* flipper_format, const char* path);
/**
* Open file. Creates a new file, fails if file already exists.
* Use only if FlipperFormat allocated as a file.
/** Open file. Creates a new file, fails if file already exists. Use only if
* FlipperFormat allocated as a file.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param path File path
*
* @return True on success
*/
bool flipper_format_file_open_new(FlipperFormat* flipper_format, const char* path);
/**
* Closes the file, use only if FlipperFormat allocated as a file.
* @param flipper_format
/** Closes the file, use only if FlipperFormat allocated as a file.
*
* @param flipper_format The flipper format
*
* @return true
* @return false
*/
bool flipper_format_file_close(FlipperFormat* flipper_format);
/**
* Closes the file, use only if FlipperFormat allocated as a buffered file.
* @param flipper_format
/** Closes the file, use only if FlipperFormat allocated as a buffered file.
*
* @param flipper_format The flipper format
*
* @return true
* @return false
*/
bool flipper_format_buffered_file_close(FlipperFormat* flipper_format);
/**
* Free FlipperFormat.
/** Free FlipperFormat.
*
* @param flipper_format Pointer to a FlipperFormat instance
*/
void flipper_format_free(FlipperFormat* flipper_format);
/**
* Set FlipperFormat mode.
/** Set FlipperFormat mode.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param strict_mode True obligates not to skip valid fields. False by default.
* @param strict_mode True obligates not to skip valid fields. False by
* default.
*/
void flipper_format_set_strict_mode(FlipperFormat* flipper_format, bool strict_mode);
/**
* Rewind the RW pointer.
/** Rewind the RW pointer.
*
* @param flipper_format Pointer to a FlipperFormat instance
*
* @return True on success
*/
bool flipper_format_rewind(FlipperFormat* flipper_format);
/**
* Move the RW pointer at the end. Can be useful if you want to add some data after reading.
/** Move the RW pointer at the end. Can be useful if you want to add some data
* after reading.
*
* @param flipper_format Pointer to a FlipperFormat instance
*
* @return True on success
*/
bool flipper_format_seek_to_end(FlipperFormat* flipper_format);
/**
* Check if the key exists.
/** Check if the key exists.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
*
* @return true key exists
* @return false key is not exists
*/
bool flipper_format_key_exist(FlipperFormat* flipper_format, const char* key);
/**
* Read the header (file type and version).
/** Read the header (file type and version).
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param filetype File type string
* @param version Version Value
*
* @return True on success
*/
bool flipper_format_read_header(
@@ -238,11 +248,12 @@ bool flipper_format_read_header(
FuriString* filetype,
uint32_t* version);
/**
* Write the header (file type and version).
/** Write the header (file type and version).
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param filetype File type string
* @param version Version Value
*
* @return True on success
*/
bool flipper_format_write_header(
@@ -250,11 +261,12 @@ bool flipper_format_write_header(
FuriString* filetype,
const uint32_t version);
/**
* Write the header (file type and version). Plain C string version.
/** Write the header (file type and version). Plain C string version.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param filetype File type string
* @param version Version Value
*
* @return True on success
*/
bool flipper_format_write_header_cstr(
@@ -262,11 +274,12 @@ bool flipper_format_write_header_cstr(
const char* filetype,
const uint32_t version);
/**
* Get the count of values by key
/** Get the count of values by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key
* @param count
* @param key The key
* @param count The count
*
* @return bool
*/
bool flipper_format_get_value_count(
@@ -274,29 +287,32 @@ bool flipper_format_get_value_count(
const char* key,
uint32_t* count);
/**
* Read a string by key
/** Read a string by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_read_string(FlipperFormat* flipper_format, const char* key, FuriString* data);
/**
* Write key and string
/** Write key and string
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_write_string(FlipperFormat* flipper_format, const char* key, FuriString* data);
/**
* Write key and string. Plain C string version.
/** Write key and string. Plain C string version.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_write_string_cstr(
@@ -304,12 +320,13 @@ bool flipper_format_write_string_cstr(
const char* key,
const char* data);
/**
* Read array of uint64 in hex format by key
/** Read array of uint64 in hex format by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_read_hex_uint64(
@@ -318,12 +335,13 @@ bool flipper_format_read_hex_uint64(
uint64_t* data,
const uint16_t data_size);
/**
* Write key and array of uint64 in hex format
/** Write key and array of uint64 in hex format
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_write_hex_uint64(
@@ -332,12 +350,13 @@ bool flipper_format_write_hex_uint64(
const uint64_t* data,
const uint16_t data_size);
/**
* Read array of uint32 by key
/** Read array of uint32 by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_read_uint32(
@@ -346,12 +365,13 @@ bool flipper_format_read_uint32(
uint32_t* data,
const uint16_t data_size);
/**
* Write key and array of uint32
/** Write key and array of uint32
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_write_uint32(
@@ -360,12 +380,13 @@ bool flipper_format_write_uint32(
const uint32_t* data,
const uint16_t data_size);
/**
* Read array of int32 by key
/** Read array of int32 by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_read_int32(
@@ -374,12 +395,13 @@ bool flipper_format_read_int32(
int32_t* data,
const uint16_t data_size);
/**
* Write key and array of int32
/** Write key and array of int32
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_write_int32(
@@ -388,12 +410,13 @@ bool flipper_format_write_int32(
const int32_t* data,
const uint16_t data_size);
/**
* Read array of bool by key
/** Read array of bool by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_read_bool(
@@ -402,12 +425,13 @@ bool flipper_format_read_bool(
bool* data,
const uint16_t data_size);
/**
* Write key and array of bool
/** Write key and array of bool
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_write_bool(
@@ -416,12 +440,13 @@ bool flipper_format_write_bool(
const bool* data,
const uint16_t data_size);
/**
* Read array of float by key
/** Read array of float by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_read_float(
@@ -430,12 +455,13 @@ bool flipper_format_read_float(
float* data,
const uint16_t data_size);
/**
* Write key and array of float
/** Write key and array of float
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_write_float(
@@ -444,12 +470,13 @@ bool flipper_format_write_float(
const float* data,
const uint16_t data_size);
/**
* Read array of hex-formatted bytes by key
/** Read array of hex-formatted bytes by key
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_read_hex(
@@ -458,12 +485,13 @@ bool flipper_format_read_hex(
uint8_t* data,
const uint16_t data_size);
/**
* Write key and array of hex-formatted bytes
/** Write key and array of hex-formatted bytes
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param data_size Values count
*
* @return True on success
*/
bool flipper_format_write_hex(
@@ -472,44 +500,52 @@ bool flipper_format_write_hex(
const uint8_t* data,
const uint16_t data_size);
/**
* Write comment
/** Write comment
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param data Comment text
*
* @return True on success
*/
bool flipper_format_write_comment(FlipperFormat* flipper_format, FuriString* data);
/**
* Write comment. Plain C string version.
/** Write comment. Plain C string version.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param data Comment text
*
* @return True on success
*/
bool flipper_format_write_comment_cstr(FlipperFormat* flipper_format, const char* data);
/**
* Removes the first matching key and its value. Sets the RW pointer to a position of deleted data.
/** Removes the first matching key and its value. Sets the RW pointer to a
* position of deleted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
*
* @return True on success
*/
bool flipper_format_delete_key(FlipperFormat* flipper_format, const char* key);
/**
* Updates the value of the first matching key to a string value. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a string value. Sets the RW
* pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_update_string(FlipperFormat* flipper_format, const char* key, FuriString* data);
/**
* Updates the value of the first matching key to a string value. Plain C version. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a string value. Plain C
* version. Sets the RW pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_update_string_cstr(
@@ -517,11 +553,14 @@ bool flipper_format_update_string_cstr(
const char* key,
const char* data);
/**
* Updates the value of the first matching key to a uint32 array value. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a uint32 array value. Sets the
* RW pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_update_uint32(
@@ -530,11 +569,14 @@ bool flipper_format_update_uint32(
const uint32_t* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a int32 array value. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a int32 array value. Sets the
* RW pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_update_int32(
@@ -543,11 +585,14 @@ bool flipper_format_update_int32(
const int32_t* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a bool array value. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a bool array value. Sets the
* RW pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_update_bool(
@@ -556,11 +601,14 @@ bool flipper_format_update_bool(
const bool* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a float array value. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a float array value. Sets the
* RW pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_update_float(
@@ -569,11 +617,14 @@ bool flipper_format_update_float(
const float* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to an array of hex-formatted bytes. Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to an array of hex-formatted
* bytes. Sets the RW pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_update_hex(
@@ -582,12 +633,14 @@ bool flipper_format_update_hex(
const uint8_t* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a string value, or adds the key and value if the key did not exist.
* Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a string value, or adds the
* key and value if the key did not exist. Sets the RW pointer to a position at
* the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_insert_or_update_string(
@@ -595,13 +648,14 @@ bool flipper_format_insert_or_update_string(
const char* key,
FuriString* data);
/**
* Updates the value of the first matching key to a string value, or adds the key and value if the key did not exist.
* Plain C version.
* Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a string value, or adds the
* key and value if the key did not exist. Plain C version. Sets the RW pointer
* to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
*
* @return True on success
*/
bool flipper_format_insert_or_update_string_cstr(
@@ -609,12 +663,15 @@ bool flipper_format_insert_or_update_string_cstr(
const char* key,
const char* data);
/**
* Updates the value of the first matching key to a uint32 array value, or adds the key and value if the key did not exist.
* Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a uint32 array value, or adds
* the key and value if the key did not exist. Sets the RW pointer to a position
* at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_insert_or_update_uint32(
@@ -623,12 +680,15 @@ bool flipper_format_insert_or_update_uint32(
const uint32_t* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a int32 array value, or adds the key and value if the key did not exist.
* Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a int32 array value, or adds
* the key and value if the key did not exist. Sets the RW pointer to a position
* at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_insert_or_update_int32(
@@ -637,12 +697,15 @@ bool flipper_format_insert_or_update_int32(
const int32_t* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a bool array value, or adds the key and value if the key did not exist.
* Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a bool array value, or adds
* the key and value if the key did not exist. Sets the RW pointer to a position
* at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_insert_or_update_bool(
@@ -651,12 +714,15 @@ bool flipper_format_insert_or_update_bool(
const bool* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to a float array value, or adds the key and value if the key did not exist.
* Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to a float array value, or adds
* the key and value if the key did not exist. Sets the RW pointer to a position
* at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_insert_or_update_float(
@@ -665,12 +731,15 @@ bool flipper_format_insert_or_update_float(
const float* data,
const uint16_t data_size);
/**
* Updates the value of the first matching key to an array of hex-formatted bytes, or adds the key and value if the key did not exist.
*Sets the RW pointer to a position at the end of inserted data.
/** Updates the value of the first matching key to an array of hex-formatted
* bytes, or adds the key and value if the key did not exist. Sets the RW
* pointer to a position at the end of inserted data.
*
* @param flipper_format Pointer to a FlipperFormat instance
* @param key Key
* @param data Value
* @param[in] data_size The data size
*
* @return True on success
*/
bool flipper_format_insert_or_update_hex(

View File

@@ -1,5 +1,4 @@
/**
* @file lfrfid_worker.h
/** @file lfrfid_worker.h
*
* LFRFID worker
*/
@@ -54,37 +53,35 @@ typedef void (*LFRFIDWorkerEmulateRawCallback)(LFRFIDWorkerEmulateRawResult resu
typedef struct LFRFIDWorker LFRFIDWorker;
/**
* Allocate LF-RFID worker
/** Allocate LF-RFID worker
* @return LFRFIDWorker*
*/
LFRFIDWorker* lfrfid_worker_alloc(ProtocolDict* dict);
/**
* Free LF-RFID worker
* @param worker
/** Free LF-RFID worker
*
* @param worker The worker
*/
void lfrfid_worker_free(LFRFIDWorker* worker);
/**
* Start LF-RFID worker thread
* @param worker
/** Start LF-RFID worker thread
*
* @param worker The worker
*/
void lfrfid_worker_start_thread(LFRFIDWorker* worker);
/**
* Stop LF-RFID worker thread
* @param worker
/** Stop LF-RFID worker thread
*
* @param worker The worker
*/
void lfrfid_worker_stop_thread(LFRFIDWorker* worker);
/**
* @brief Start read mode
/** Start read mode
*
* @param worker
* @param type
* @param callback
* @param context
* @param worker The worker
* @param type The type
* @param callback The callback
* @param context The context
*/
void lfrfid_worker_read_start(
LFRFIDWorker* worker,
@@ -92,13 +89,12 @@ void lfrfid_worker_read_start(
LFRFIDWorkerReadCallback callback,
void* context);
/**
* @brief Start write mode
/** Start write mode
*
* @param worker
* @param protocol
* @param callback
* @param context
* @param worker The worker
* @param protocol The protocol
* @param callback The callback
* @param context The context
*/
void lfrfid_worker_write_start(
LFRFIDWorker* worker,
@@ -120,20 +116,20 @@ void lfrfid_worker_write_and_set_pass_start(
LFRFIDWorkerWriteCallback callback,
void* context);
/**
* Start emulate mode
* @param worker
/** Start emulate mode
*
* @param worker The worker
* @param[in] protocol The protocol
*/
void lfrfid_worker_emulate_start(LFRFIDWorker* worker, LFRFIDProtocol protocol);
/**
* @brief Start raw read mode
/** Start raw read mode
*
* @param worker
* @param filename
* @param type
* @param callback
* @param context
* @param worker The worker
* @param filename The filename
* @param type The type
* @param callback The callback
* @param context The context
*/
void lfrfid_worker_read_raw_start(
LFRFIDWorker* worker,
@@ -142,12 +138,12 @@ void lfrfid_worker_read_raw_start(
LFRFIDWorkerReadRawCallback callback,
void* context);
/**
* Emulate raw read mode
* @param worker
* @param filename
* @param callback
* @param context
/** Emulate raw read mode
*
* @param worker The worker
* @param filename The filename
* @param callback The callback
* @param context The context
*/
void lfrfid_worker_emulate_raw_start(
LFRFIDWorker* worker,
@@ -155,9 +151,9 @@ void lfrfid_worker_emulate_raw_start(
LFRFIDWorkerEmulateRawCallback callback,
void* context);
/**
* Stop all modes
* @param worker
/** Stop all modes
*
* @param worker The worker
*/
void lfrfid_worker_stop(LFRFIDWorker* worker);

View File

@@ -158,6 +158,8 @@ static inline bool onewire_slave_receive_and_process_command(OneWireSlave* bus)
static inline bool onewire_slave_bus_start(OneWireSlave* bus) {
FURI_CRITICAL_ENTER();
furi_hal_gpio_disable_int_callback(bus->gpio_pin);
furi_hal_gpio_init(bus->gpio_pin, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
while(onewire_slave_receive_and_process_command(bus))
@@ -166,6 +168,8 @@ static inline bool onewire_slave_bus_start(OneWireSlave* bus) {
const bool result = (bus->error == OneWireSlaveErrorNone);
furi_hal_gpio_init(bus->gpio_pin, GpioModeInterruptRiseFall, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_enable_int_callback(bus->gpio_pin);
FURI_CRITICAL_EXIT();
return result;

View File

@@ -43,7 +43,8 @@ typedef struct Compress Compress;
/** Allocate encoder and decoder
*
* @param compress_buff_size size of decoder and encoder buffer to allocate
* @param compress_buff_size size of decoder and encoder buffer to
* allocate
*
* @return Compress instance
*/
@@ -61,6 +62,7 @@ void compress_free(Compress* compress);
* @param data_in pointer to input data
* @param data_in_size size of input data
* @param data_out maximum size of output data
* @param[in] data_out_size The data out size
* @param data_res_size pointer to result output data size
*
* @return true on success
@@ -79,6 +81,7 @@ bool compress_encode(
* @param data_in pointer to input data
* @param data_in_size size of input data
* @param data_out maximum size of output data
* @param[in] data_out_size The data out size
* @param data_res_size pointer to result output data size
*
* @return true on success

View File

@@ -1,5 +1,9 @@
import os
import re
import subprocess
import sys
import webbrowser
from pathlib import Path, PurePosixPath
import SCons
from SCons.Errors import StopError
@@ -79,7 +83,35 @@ def resolve_real_dir_node(node):
raise StopError(f"Can't find absolute path for {node.name} ({node})")
class PosixPathWrapper:
def __init__(self, pathobj):
self.pathobj = pathobj
@staticmethod
def fixup_separators(path):
if SCons.Platform.platform_default() == "win32":
return path.replace(os.path.sep, os.path.altsep)
return path
@staticmethod
def fix_path(path):
return str(PurePosixPath(Path(path).as_posix()))
def __call__(self, target, source, env, for_signature):
if for_signature:
return self.pathobj
return self.fix_path(env.subst(self.pathobj))
def path_as_posix(path):
if SCons.Platform.platform_default() == "win32":
return path.replace(os.path.sep, os.path.altsep)
return path
def open_browser_action(target, source, env):
if sys.platform == "darwin":
subprocess.run(["open", source[0].abspath])
else:
webbrowser.open(source[0].abspath)

Some files were not shown because too many files have changed in this diff Show More