Merge remote-tracking branch 'origin/dev' into release-candidate
This commit is contained in:
commit
085c8008db
44
.github/workflows/build.yml
vendored
44
.github/workflows/build.yml
vendored
@ -139,7 +139,7 @@ jobs:
|
||||
|
||||
- name: 'Find Previous Comment'
|
||||
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request }}
|
||||
uses: peter-evans/find-comment@v1
|
||||
uses: peter-evans/find-comment@v2
|
||||
id: fc
|
||||
with:
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
@ -148,7 +148,7 @@ jobs:
|
||||
|
||||
- name: 'Create or update comment'
|
||||
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request}}
|
||||
uses: peter-evans/create-or-update-comment@v1
|
||||
uses: peter-evans/create-or-update-comment@v3
|
||||
with:
|
||||
comment-id: ${{ steps.fc.outputs.comment-id }}
|
||||
issue-number: ${{ github.event.pull_request.number }}
|
||||
@ -162,6 +162,9 @@ jobs:
|
||||
compact:
|
||||
if: ${{ !startsWith(github.ref, 'refs/tags') }}
|
||||
runs-on: [self-hosted,FlipperZeroShell]
|
||||
strategy:
|
||||
matrix:
|
||||
target: [f7, f18]
|
||||
steps:
|
||||
- name: 'Wipe workspace'
|
||||
run: find ./ -mount -maxdepth 1 -exec rm -rf {} \;
|
||||
@ -185,9 +188,40 @@ jobs:
|
||||
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE" || cat "${{ github.event_path }}"
|
||||
|
||||
- name: 'Build the firmware'
|
||||
id: build-fw
|
||||
run: |
|
||||
set -e
|
||||
for TARGET in ${TARGETS}; do
|
||||
TARGET="$(echo "${TARGET}" | sed 's/f//')"; \
|
||||
./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package
|
||||
TARGET="$(echo '${{ matrix.target }}' | sed 's/f//')"; \
|
||||
./fbt TARGET_HW=$TARGET DEBUG=0 COMPACT=1 fap_dist updater_package
|
||||
echo "sdk-file=$(ls dist/${{ matrix.target }}-*/flipper-z-${{ matrix.target }}-sdk-*.zip)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Deploy uFBT with SDK
|
||||
uses: flipperdevices/flipperzero-ufbt-action@v0.1.0
|
||||
with:
|
||||
task: setup
|
||||
sdk-file: ${{ steps.build-fw.outputs.sdk-file }}
|
||||
|
||||
- name: Build test app with SDK
|
||||
run: |
|
||||
mkdir testapp
|
||||
cd testapp
|
||||
ufbt create APPID=testapp
|
||||
ufbt
|
||||
|
||||
- name: Build example & external apps with uFBT
|
||||
run: |
|
||||
for appdir in 'applications/external' 'applications/examples'; do
|
||||
for app in $(find "$appdir" -maxdepth 1 -mindepth 1 -type d); do
|
||||
pushd $app
|
||||
TARGETS_FAM=$(grep "targets" application.fam || echo "${{ matrix.target }}")
|
||||
if ! grep -q "${{ matrix.target }}" <<< $TARGETS_FAM ; then
|
||||
echo Skipping unsupported app: $app
|
||||
popd
|
||||
continue
|
||||
fi
|
||||
echo Building $app
|
||||
ufbt
|
||||
popd
|
||||
done
|
||||
done
|
||||
|
||||
|
||||
34
.github/workflows/lint_and_submodule_check.yml
vendored
34
.github/workflows/lint_and_submodule_check.yml
vendored
@ -40,7 +40,7 @@ jobs:
|
||||
COMMITS_IN_BRANCH="$(git rev-list --count dev)";
|
||||
if [ $COMMITS_IN_BRANCH -lt $SUB_COMMITS_MIN ]; then
|
||||
echo "name=fails::error" >> $GITHUB_OUTPUT;
|
||||
echo "::error::Error: Too low commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)";
|
||||
echo "::error::Error: Too few commits in $SUB_BRANCH of submodule $SUB_PATH: $COMMITS_IN_BRANCH(expected $SUB_COMMITS_MIN+)";
|
||||
exit 1;
|
||||
fi
|
||||
if ! grep -q "/$SUB_BRANCH" <<< "$BRANCHES"; then
|
||||
@ -51,12 +51,36 @@ jobs:
|
||||
|
||||
- name: 'Check Python code formatting'
|
||||
id: syntax_check_py
|
||||
run: ./fbt lint_py 2>&1 >/dev/null || echo "errors=1" >> $GITHUB_OUTPUT
|
||||
|
||||
run: |
|
||||
set +e;
|
||||
./fbt -s lint_py 2>&1 | tee lint-py.log;
|
||||
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
|
||||
# Save multiline output
|
||||
echo "errors=1" >> $GITHUB_OUTPUT;
|
||||
printf "Python Lint errors:\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY;
|
||||
echo "$(cat lint-py.log)" >> $GITHUB_STEP_SUMMARY;
|
||||
printf "\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY;
|
||||
exit 1;
|
||||
else
|
||||
echo "Python Lint: all good ✨" >> $GITHUB_STEP_SUMMARY;
|
||||
fi
|
||||
|
||||
- name: 'Check C++ code formatting'
|
||||
if: always()
|
||||
id: syntax_check_cpp
|
||||
run: ./fbt lint 2>&1 >/dev/null || echo "errors=1" >> $GITHUB_OUTPUT
|
||||
if: always()
|
||||
run: |
|
||||
set +e;
|
||||
./fbt -s lint 2>&1 | tee lint-cpp.log;
|
||||
if [ "${PIPESTATUS[0]}" -ne 0 ]; then
|
||||
# Save multiline output
|
||||
echo "errors=1" >> $GITHUB_OUTPUT;
|
||||
printf "C Lint errors:\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY;
|
||||
echo "$(cat lint-cpp.log)" >> $GITHUB_STEP_SUMMARY;
|
||||
printf "\n\`\`\`\n" >> $GITHUB_STEP_SUMMARY;
|
||||
exit 1;
|
||||
else
|
||||
echo "C Lint: all good ✨" >> $GITHUB_STEP_SUMMARY;
|
||||
fi
|
||||
|
||||
- name: Report code formatting errors
|
||||
if: ( steps.syntax_check_py.outputs.errors || steps.syntax_check_cpp.outputs.errors ) && github.event.pull_request
|
||||
|
||||
@ -84,7 +84,7 @@ static void test_rpc_setup(void) {
|
||||
|
||||
rpc = furi_record_open(RECORD_RPC);
|
||||
for(int i = 0; !(rpc_session[0].session) && (i < 10000); ++i) {
|
||||
rpc_session[0].session = rpc_session_open(rpc);
|
||||
rpc_session[0].session = rpc_session_open(rpc, RpcOwnerUnknown);
|
||||
furi_delay_tick(1);
|
||||
}
|
||||
furi_check(rpc_session[0].session);
|
||||
@ -104,7 +104,7 @@ static void test_rpc_setup_second_session(void) {
|
||||
furi_check(!(rpc_session[1].session));
|
||||
|
||||
for(int i = 0; !(rpc_session[1].session) && (i < 10000); ++i) {
|
||||
rpc_session[1].session = rpc_session_open(rpc);
|
||||
rpc_session[1].session = rpc_session_open(rpc, RpcOwnerUnknown);
|
||||
furi_delay_tick(1);
|
||||
}
|
||||
furi_check(rpc_session[1].session);
|
||||
|
||||
@ -570,7 +570,7 @@ void picopass_worker_elite_dict_attack(PicopassWorker* picopass_worker) {
|
||||
picopass_worker->callback(PicopassWorkerEventFail, picopass_worker->context);
|
||||
break;
|
||||
}
|
||||
picopass_worker->callback(PicopassWorkerEventSuccess, picopass_worker->context);
|
||||
picopass_worker->callback(PicopassWorkerEventAborted, picopass_worker->context);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -596,6 +596,9 @@ int32_t picopass_worker_task(void* context) {
|
||||
picopass_worker_write_key(picopass_worker);
|
||||
} else if(picopass_worker->state == PicopassWorkerStateEliteDictAttack) {
|
||||
picopass_worker_elite_dict_attack(picopass_worker);
|
||||
} else if(picopass_worker->state == PicopassWorkerStateStop) {
|
||||
FURI_LOG_D(TAG, "Worker state stop");
|
||||
// no-op
|
||||
} else {
|
||||
FURI_LOG_W(TAG, "Unknown state %d", picopass_worker->state);
|
||||
}
|
||||
|
||||
@ -116,8 +116,7 @@ bool picopass_scene_elite_dict_attack_on_event(void* context, SceneManagerEvent
|
||||
uint32_t state =
|
||||
scene_manager_get_scene_state(picopass->scene_manager, PicopassSceneEliteDictAttack);
|
||||
if(event.type == SceneManagerEventTypeCustom) {
|
||||
if(event.event == PicopassWorkerEventSuccess ||
|
||||
event.event == PicopassWorkerEventAborted) {
|
||||
if(event.event == PicopassWorkerEventSuccess) {
|
||||
if(state == DictAttackStateUserDictInProgress ||
|
||||
state == DictAttackStateStandardDictInProgress) {
|
||||
picopass_worker_stop(picopass->worker);
|
||||
@ -127,6 +126,9 @@ bool picopass_scene_elite_dict_attack_on_event(void* context, SceneManagerEvent
|
||||
scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess);
|
||||
consumed = true;
|
||||
}
|
||||
} else if(event.event == PicopassWorkerEventAborted) {
|
||||
scene_manager_next_scene(picopass->scene_manager, PicopassSceneReadCardSuccess);
|
||||
consumed = true;
|
||||
} else if(event.event == PicopassWorkerEventCardDetected) {
|
||||
dict_attack_set_card_detected(picopass->dict_attack);
|
||||
consumed = true;
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
#include "fap_loader_app.h"
|
||||
|
||||
#include <furi.h>
|
||||
#include <furi_hal_debug.h>
|
||||
|
||||
#include <assets_icons.h>
|
||||
#include <gui/gui.h>
|
||||
@ -23,8 +24,6 @@ struct FapLoader {
|
||||
Loading* loading;
|
||||
};
|
||||
|
||||
volatile bool fap_loader_debug_active = false;
|
||||
|
||||
bool fap_loader_load_name_and_icon(
|
||||
FuriString* path,
|
||||
Storage* storage,
|
||||
@ -111,7 +110,7 @@ static bool fap_loader_run_selected_app(FapLoader* loader) {
|
||||
FuriThread* thread = flipper_application_spawn(loader->app, NULL);
|
||||
|
||||
/* This flag is set by the debugger - to break on app start */
|
||||
if(fap_loader_debug_active) {
|
||||
if(furi_hal_debug_is_gdb_session_active()) {
|
||||
FURI_LOG_W(TAG, "Triggering BP for debugger");
|
||||
/* After hitting this, you can set breakpoints in your .fap's code
|
||||
* Note that you have to toggle breakpoints that were set before */
|
||||
|
||||
@ -225,7 +225,7 @@ static bool bt_on_gap_event_callback(GapEvent event, void* context) {
|
||||
furi_event_flag_clear(bt->rpc_event, BT_RPC_EVENT_DISCONNECTED);
|
||||
if(bt->profile == BtProfileSerial) {
|
||||
// Open RPC session
|
||||
bt->rpc_session = rpc_session_open(bt->rpc);
|
||||
bt->rpc_session = rpc_session_open(bt->rpc, RpcOwnerBle);
|
||||
if(bt->rpc_session) {
|
||||
FURI_LOG_I(TAG, "Open RPC connection");
|
||||
rpc_session_set_send_bytes_callback(bt->rpc_session, bt_rpc_send_bytes_callback);
|
||||
|
||||
@ -46,6 +46,12 @@ static void desktop_dummy_mode_icon_draw_callback(Canvas* canvas, void* context)
|
||||
canvas_draw_icon(canvas, 0, 0, &I_GameMode_11x8);
|
||||
}
|
||||
|
||||
static void desktop_stealth_mode_icon_draw_callback(Canvas* canvas, void* context) {
|
||||
UNUSED(context);
|
||||
furi_assert(canvas);
|
||||
canvas_draw_icon(canvas, 0, 0, &I_Muted_8x8);
|
||||
}
|
||||
|
||||
static bool desktop_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
Desktop* desktop = (Desktop*)context;
|
||||
@ -153,6 +159,17 @@ void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled) {
|
||||
desktop->in_transition = false;
|
||||
}
|
||||
|
||||
void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled) {
|
||||
desktop->in_transition = true;
|
||||
if(enabled) {
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagStealthMode);
|
||||
} else {
|
||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagStealthMode);
|
||||
}
|
||||
view_port_enabled_set(desktop->stealth_mode_icon_viewport, enabled);
|
||||
desktop->in_transition = false;
|
||||
}
|
||||
|
||||
Desktop* desktop_alloc() {
|
||||
Desktop* desktop = malloc(sizeof(Desktop));
|
||||
|
||||
@ -244,6 +261,18 @@ Desktop* desktop_alloc() {
|
||||
view_port_enabled_set(desktop->dummy_mode_icon_viewport, false);
|
||||
gui_add_view_port(desktop->gui, desktop->dummy_mode_icon_viewport, GuiLayerStatusBarLeft);
|
||||
|
||||
// Stealth mode icon
|
||||
desktop->stealth_mode_icon_viewport = view_port_alloc();
|
||||
view_port_set_width(desktop->stealth_mode_icon_viewport, icon_get_width(&I_Muted_8x8));
|
||||
view_port_draw_callback_set(
|
||||
desktop->stealth_mode_icon_viewport, desktop_stealth_mode_icon_draw_callback, desktop);
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)) {
|
||||
view_port_enabled_set(desktop->stealth_mode_icon_viewport, true);
|
||||
} else {
|
||||
view_port_enabled_set(desktop->stealth_mode_icon_viewport, false);
|
||||
}
|
||||
gui_add_view_port(desktop->gui, desktop->stealth_mode_icon_viewport, GuiLayerStatusBarLeft);
|
||||
|
||||
// Special case: autostart application is already running
|
||||
desktop->loader = furi_record_open(RECORD_LOADER);
|
||||
if(loader_is_locked(desktop->loader) &&
|
||||
|
||||
@ -59,6 +59,7 @@ struct Desktop {
|
||||
|
||||
ViewPort* lock_icon_viewport;
|
||||
ViewPort* dummy_mode_icon_viewport;
|
||||
ViewPort* stealth_mode_icon_viewport;
|
||||
|
||||
AnimationManager* animation_manager;
|
||||
|
||||
@ -79,3 +80,4 @@ void desktop_free(Desktop* desktop);
|
||||
void desktop_lock(Desktop* desktop);
|
||||
void desktop_unlock(Desktop* desktop);
|
||||
void desktop_set_dummy_mode_state(Desktop* desktop, bool enabled);
|
||||
void desktop_set_stealth_mode_state(Desktop* desktop, bool enabled);
|
||||
|
||||
@ -27,6 +27,8 @@ void desktop_scene_lock_menu_on_enter(void* context) {
|
||||
desktop_lock_menu_set_callback(desktop->lock_menu, desktop_scene_lock_menu_callback, desktop);
|
||||
desktop_lock_menu_set_pin_state(desktop->lock_menu, desktop->settings.pin_code.length > 0);
|
||||
desktop_lock_menu_set_dummy_mode_state(desktop->lock_menu, desktop->settings.dummy_mode);
|
||||
desktop_lock_menu_set_stealth_mode_state(
|
||||
desktop->lock_menu, furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode));
|
||||
desktop_lock_menu_set_idx(desktop->lock_menu, 0);
|
||||
|
||||
view_dispatcher_switch_to_view(desktop->view_dispatcher, DesktopViewIdLockMenu);
|
||||
@ -78,6 +80,16 @@ bool desktop_scene_lock_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
desktop->scene_manager, DesktopSceneMain);
|
||||
break;
|
||||
case DesktopLockMenuEventStealthModeOn:
|
||||
desktop_set_stealth_mode_state(desktop, true);
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
desktop->scene_manager, DesktopSceneMain);
|
||||
break;
|
||||
case DesktopLockMenuEventStealthModeOff:
|
||||
desktop_set_stealth_mode_state(desktop, false);
|
||||
scene_manager_search_and_switch_to_previous_scene(
|
||||
desktop->scene_manager, DesktopSceneMain);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@ -34,6 +34,8 @@ typedef enum {
|
||||
DesktopLockMenuEventPinLock,
|
||||
DesktopLockMenuEventDummyModeOn,
|
||||
DesktopLockMenuEventDummyModeOff,
|
||||
DesktopLockMenuEventStealthModeOn,
|
||||
DesktopLockMenuEventStealthModeOff,
|
||||
|
||||
DesktopAnimationEventCheckAnimation,
|
||||
DesktopAnimationEventNewIdleAnimation,
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
typedef enum {
|
||||
DesktopLockMenuIndexLock,
|
||||
DesktopLockMenuIndexPinLock,
|
||||
DesktopLockMenuIndexStealth,
|
||||
DesktopLockMenuIndexDummy,
|
||||
|
||||
DesktopLockMenuIndexTotalCount
|
||||
@ -39,6 +39,14 @@ void desktop_lock_menu_set_dummy_mode_state(DesktopLockMenuView* lock_menu, bool
|
||||
true);
|
||||
}
|
||||
|
||||
void desktop_lock_menu_set_stealth_mode_state(DesktopLockMenuView* lock_menu, bool stealth_mode) {
|
||||
with_view_model(
|
||||
lock_menu->view,
|
||||
DesktopLockMenuViewModel * model,
|
||||
{ model->stealth_mode = stealth_mode; },
|
||||
true);
|
||||
}
|
||||
|
||||
void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx) {
|
||||
furi_assert(idx < DesktopLockMenuIndexTotalCount);
|
||||
with_view_model(
|
||||
@ -58,11 +66,11 @@ void desktop_lock_menu_draw_callback(Canvas* canvas, void* model) {
|
||||
|
||||
if(i == DesktopLockMenuIndexLock) {
|
||||
str = "Lock";
|
||||
} else if(i == DesktopLockMenuIndexPinLock) {
|
||||
if(m->pin_is_set) {
|
||||
str = "Lock with PIN";
|
||||
} else if(i == DesktopLockMenuIndexStealth) {
|
||||
if(m->stealth_mode) {
|
||||
str = "Sound Mode";
|
||||
} else {
|
||||
str = "Set PIN";
|
||||
str = "Stealth Mode";
|
||||
}
|
||||
} else if(i == DesktopLockMenuIndexDummy) { //-V547
|
||||
if(m->dummy_mode) {
|
||||
@ -93,6 +101,8 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) {
|
||||
uint8_t idx = 0;
|
||||
bool consumed = false;
|
||||
bool dummy_mode = false;
|
||||
bool stealth_mode = false;
|
||||
bool pin_is_set = false;
|
||||
bool update = false;
|
||||
|
||||
with_view_model(
|
||||
@ -120,14 +130,24 @@ bool desktop_lock_menu_input_callback(InputEvent* event, void* context) {
|
||||
}
|
||||
idx = model->idx;
|
||||
dummy_mode = model->dummy_mode;
|
||||
stealth_mode = model->stealth_mode;
|
||||
pin_is_set = model->pin_is_set;
|
||||
},
|
||||
update);
|
||||
|
||||
if(event->key == InputKeyOk) {
|
||||
if((idx == DesktopLockMenuIndexLock) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventLock, lock_menu->context);
|
||||
} else if((idx == DesktopLockMenuIndexPinLock) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventPinLock, lock_menu->context);
|
||||
if((idx == DesktopLockMenuIndexLock)) {
|
||||
if((pin_is_set) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventPinLock, lock_menu->context);
|
||||
} else if((pin_is_set == false) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventLock, lock_menu->context);
|
||||
}
|
||||
} else if(idx == DesktopLockMenuIndexStealth) {
|
||||
if((stealth_mode == false) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventStealthModeOn, lock_menu->context);
|
||||
} else if((stealth_mode == true) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventStealthModeOff, lock_menu->context);
|
||||
}
|
||||
} else if(idx == DesktopLockMenuIndexDummy) {
|
||||
if((dummy_mode == false) && (event->type == InputTypeShort)) {
|
||||
lock_menu->callback(DesktopLockMenuEventDummyModeOn, lock_menu->context);
|
||||
|
||||
@ -19,6 +19,7 @@ typedef struct {
|
||||
uint8_t idx;
|
||||
bool pin_is_set;
|
||||
bool dummy_mode;
|
||||
bool stealth_mode;
|
||||
} DesktopLockMenuViewModel;
|
||||
|
||||
void desktop_lock_menu_set_callback(
|
||||
@ -29,6 +30,7 @@ void desktop_lock_menu_set_callback(
|
||||
View* desktop_lock_menu_get_view(DesktopLockMenuView* lock_menu);
|
||||
void desktop_lock_menu_set_pin_state(DesktopLockMenuView* lock_menu, bool pin_is_set);
|
||||
void desktop_lock_menu_set_dummy_mode_state(DesktopLockMenuView* lock_menu, bool dummy_mode);
|
||||
void desktop_lock_menu_set_stealth_mode_state(DesktopLockMenuView* lock_menu, bool stealth_mode);
|
||||
void desktop_lock_menu_set_idx(DesktopLockMenuView* lock_menu, uint8_t idx);
|
||||
DesktopLockMenuView* desktop_lock_menu_alloc();
|
||||
void desktop_lock_menu_free(DesktopLockMenuView* lock_menu);
|
||||
|
||||
@ -20,9 +20,9 @@ static const uint8_t reset_sound_mask = 1 << 4;
|
||||
static const uint8_t reset_display_mask = 1 << 5;
|
||||
static const uint8_t reset_blink_mask = 1 << 6;
|
||||
|
||||
void notification_vibro_on();
|
||||
void notification_vibro_on(bool force);
|
||||
void notification_vibro_off();
|
||||
void notification_sound_on(float freq, float volume);
|
||||
void notification_sound_on(float freq, float volume, bool force);
|
||||
void notification_sound_off();
|
||||
|
||||
uint8_t notification_settings_get_display_brightness(NotificationApp* app, uint8_t value);
|
||||
@ -141,17 +141,21 @@ uint32_t notification_settings_display_off_delay_ticks(NotificationApp* app) {
|
||||
}
|
||||
|
||||
// generics
|
||||
void notification_vibro_on() {
|
||||
furi_hal_vibro_on(true);
|
||||
void notification_vibro_on(bool force) {
|
||||
if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) {
|
||||
furi_hal_vibro_on(true);
|
||||
}
|
||||
}
|
||||
|
||||
void notification_vibro_off() {
|
||||
furi_hal_vibro_on(false);
|
||||
}
|
||||
|
||||
void notification_sound_on(float freq, float volume) {
|
||||
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
||||
furi_hal_speaker_start(freq, volume);
|
||||
void notification_sound_on(float freq, float volume, bool force) {
|
||||
if(!furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode) || force) {
|
||||
if(furi_hal_speaker_is_mine() || furi_hal_speaker_acquire(30)) {
|
||||
furi_hal_speaker_start(freq, volume);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -174,6 +178,8 @@ void notification_process_notification_message(
|
||||
NotificationApp* app,
|
||||
NotificationAppMessage* message) {
|
||||
uint32_t notification_message_index = 0;
|
||||
bool force_volume = false;
|
||||
bool force_vibro = false;
|
||||
const NotificationMessage* notification_message;
|
||||
notification_message = (*message->sequence)[notification_message_index];
|
||||
|
||||
@ -269,7 +275,7 @@ void notification_process_notification_message(
|
||||
break;
|
||||
case NotificationMessageTypeVibro:
|
||||
if(notification_message->data.vibro.on) {
|
||||
if(vibro_setting) notification_vibro_on();
|
||||
if(vibro_setting) notification_vibro_on(force_vibro);
|
||||
} else {
|
||||
notification_vibro_off();
|
||||
}
|
||||
@ -278,7 +284,8 @@ void notification_process_notification_message(
|
||||
case NotificationMessageTypeSoundOn:
|
||||
notification_sound_on(
|
||||
notification_message->data.sound.frequency,
|
||||
notification_message->data.sound.volume * speaker_volume_setting);
|
||||
notification_message->data.sound.volume * speaker_volume_setting,
|
||||
force_volume);
|
||||
reset_mask |= reset_sound_mask;
|
||||
break;
|
||||
case NotificationMessageTypeSoundOff:
|
||||
@ -307,9 +314,11 @@ void notification_process_notification_message(
|
||||
break;
|
||||
case NotificationMessageTypeForceSpeakerVolumeSetting:
|
||||
speaker_volume_setting = notification_message->data.forced_settings.speaker_volume;
|
||||
force_volume = true;
|
||||
break;
|
||||
case NotificationMessageTypeForceVibroSetting:
|
||||
vibro_setting = notification_message->data.forced_settings.vibro;
|
||||
force_vibro = true;
|
||||
break;
|
||||
case NotificationMessageTypeForceDisplayBrightnessSetting:
|
||||
display_brightness_setting =
|
||||
|
||||
@ -76,6 +76,7 @@ struct RpcSession {
|
||||
RpcBufferIsEmptyCallback buffer_is_empty_callback;
|
||||
RpcSessionClosedCallback closed_callback;
|
||||
RpcSessionTerminatedCallback terminated_callback;
|
||||
RpcOwner owner;
|
||||
void* context;
|
||||
};
|
||||
|
||||
@ -83,6 +84,11 @@ struct Rpc {
|
||||
FuriMutex* busy_mutex;
|
||||
};
|
||||
|
||||
RpcOwner rpc_session_get_owner(RpcSession* session) {
|
||||
furi_assert(session);
|
||||
return session->owner;
|
||||
}
|
||||
|
||||
static void rpc_close_session_process(const PB_Main* request, void* context) {
|
||||
furi_assert(request);
|
||||
furi_assert(context);
|
||||
@ -348,7 +354,7 @@ static void rpc_session_free_callback(FuriThreadState thread_state, void* contex
|
||||
}
|
||||
}
|
||||
|
||||
RpcSession* rpc_session_open(Rpc* rpc) {
|
||||
RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner) {
|
||||
furi_assert(rpc);
|
||||
|
||||
RpcSession* session = malloc(sizeof(RpcSession));
|
||||
@ -357,6 +363,7 @@ RpcSession* rpc_session_open(Rpc* rpc) {
|
||||
session->rpc = rpc;
|
||||
session->terminate = false;
|
||||
session->decode_error = false;
|
||||
session->owner = owner;
|
||||
RpcHandlerDict_init(session->handlers);
|
||||
|
||||
session->decoded_message = malloc(sizeof(PB_Main));
|
||||
|
||||
@ -30,6 +30,21 @@ typedef void (*RpcSessionClosedCallback)(void* context);
|
||||
* and all operations were finished */
|
||||
typedef void (*RpcSessionTerminatedCallback)(void* context);
|
||||
|
||||
/** RPC owner */
|
||||
typedef enum {
|
||||
RpcOwnerUnknown = 0,
|
||||
RpcOwnerBle,
|
||||
RpcOwnerUsb,
|
||||
RpcOwnerCount,
|
||||
} RpcOwner;
|
||||
|
||||
/** Get RPC session owner
|
||||
*
|
||||
* @param session pointer to RpcSession descriptor
|
||||
* @return session owner
|
||||
*/
|
||||
RpcOwner rpc_session_get_owner(RpcSession* session);
|
||||
|
||||
/** Open RPC session
|
||||
*
|
||||
* USAGE:
|
||||
@ -44,10 +59,11 @@ typedef void (*RpcSessionTerminatedCallback)(void* context);
|
||||
*
|
||||
*
|
||||
* @param rpc instance
|
||||
* @param owner owner of session
|
||||
* @return pointer to RpcSession descriptor, or
|
||||
* NULL if RPC is busy and can't open session now
|
||||
*/
|
||||
RpcSession* rpc_session_open(Rpc* rpc);
|
||||
RpcSession* rpc_session_open(Rpc* rpc, RpcOwner owner);
|
||||
|
||||
/** Close RPC session
|
||||
* It is guaranteed that no callbacks will be called
|
||||
|
||||
@ -47,7 +47,7 @@ void rpc_cli_command_start_session(Cli* cli, FuriString* args, void* context) {
|
||||
FURI_LOG_D(TAG, "Free memory %lu", mem_before);
|
||||
|
||||
furi_hal_usb_lock();
|
||||
RpcSession* rpc_session = rpc_session_open(rpc);
|
||||
RpcSession* rpc_session = rpc_session_open(rpc, RpcOwnerUsb);
|
||||
if(rpc_session == NULL) {
|
||||
printf("Session start error\r\n");
|
||||
furi_hal_usb_unlock();
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "rpc_i.h"
|
||||
#include "gui.pb.h"
|
||||
#include <gui/gui_i.h>
|
||||
#include <assets_icons.h>
|
||||
|
||||
#define TAG "RpcGui"
|
||||
|
||||
@ -31,6 +32,8 @@ typedef struct {
|
||||
|
||||
uint32_t input_key_counter[InputKeyMAX];
|
||||
uint32_t input_counter;
|
||||
|
||||
ViewPort* rpc_session_active_viewport;
|
||||
} RpcGuiSystem;
|
||||
|
||||
static const PB_Gui_ScreenOrientation rpc_system_gui_screen_orientation_map[] = {
|
||||
@ -352,6 +355,12 @@ static void rpc_system_gui_virtual_display_frame_process(const PB_Main* request,
|
||||
(void)session;
|
||||
}
|
||||
|
||||
static void rpc_active_session_icon_draw_callback(Canvas* canvas, void* context) {
|
||||
UNUSED(context);
|
||||
furi_assert(canvas);
|
||||
canvas_draw_icon(canvas, 0, 0, &I_Rpc_active_7x8);
|
||||
}
|
||||
|
||||
void* rpc_system_gui_alloc(RpcSession* session) {
|
||||
furi_assert(session);
|
||||
|
||||
@ -359,6 +368,18 @@ void* rpc_system_gui_alloc(RpcSession* session) {
|
||||
rpc_gui->gui = furi_record_open(RECORD_GUI);
|
||||
rpc_gui->session = session;
|
||||
|
||||
// Active session icon
|
||||
rpc_gui->rpc_session_active_viewport = view_port_alloc();
|
||||
view_port_set_width(rpc_gui->rpc_session_active_viewport, icon_get_width(&I_Rpc_active_7x8));
|
||||
view_port_draw_callback_set(
|
||||
rpc_gui->rpc_session_active_viewport, rpc_active_session_icon_draw_callback, session);
|
||||
if(rpc_session_get_owner(rpc_gui->session) != RpcOwnerBle) {
|
||||
view_port_enabled_set(rpc_gui->rpc_session_active_viewport, true);
|
||||
} else {
|
||||
view_port_enabled_set(rpc_gui->rpc_session_active_viewport, false);
|
||||
}
|
||||
gui_add_view_port(rpc_gui->gui, rpc_gui->rpc_session_active_viewport, GuiLayerStatusBarLeft);
|
||||
|
||||
RpcHandler rpc_handler = {
|
||||
.message_handler = NULL,
|
||||
.decode_submessage = NULL,
|
||||
@ -399,6 +420,9 @@ void rpc_system_gui_free(void* context) {
|
||||
rpc_gui->virtual_display_not_empty = false;
|
||||
}
|
||||
|
||||
gui_remove_view_port(rpc_gui->gui, rpc_gui->rpc_session_active_viewport);
|
||||
view_port_free(rpc_gui->rpc_session_active_viewport);
|
||||
|
||||
if(rpc_gui->is_streaming) {
|
||||
rpc_gui->is_streaming = false;
|
||||
// Remove GUI framebuffer callback
|
||||
@ -415,4 +439,4 @@ void rpc_system_gui_free(void* context) {
|
||||
}
|
||||
furi_record_close(RECORD_GUI);
|
||||
free(rpc_gui);
|
||||
}
|
||||
}
|
||||
@ -157,18 +157,33 @@ static NotificationAppSettings* alloc_settings() {
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, backlight_text[value_index]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "Volume", VOLUME_COUNT, volume_changed, app);
|
||||
value_index =
|
||||
value_index_float(app->notification->settings.speaker_volume, volume_value, VOLUME_COUNT);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, volume_text[value_index]);
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)) {
|
||||
item = variable_item_list_add(app->variable_item_list, "Volume", 1, NULL, app);
|
||||
value_index = 0;
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, "Stealth");
|
||||
} else {
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "Volume", VOLUME_COUNT, volume_changed, app);
|
||||
value_index = value_index_float(
|
||||
app->notification->settings.speaker_volume, volume_value, VOLUME_COUNT);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, volume_text[value_index]);
|
||||
}
|
||||
|
||||
item =
|
||||
variable_item_list_add(app->variable_item_list, "Vibro", VIBRO_COUNT, vibro_changed, app);
|
||||
value_index = value_index_bool(app->notification->settings.vibro_on, vibro_value, VIBRO_COUNT);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, vibro_text[value_index]);
|
||||
if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagStealthMode)) {
|
||||
item = variable_item_list_add(app->variable_item_list, "Vibro", 1, NULL, app);
|
||||
value_index = 0;
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, "Stealth");
|
||||
} else {
|
||||
item = variable_item_list_add(
|
||||
app->variable_item_list, "Vibro", VIBRO_COUNT, vibro_changed, app);
|
||||
value_index =
|
||||
value_index_bool(app->notification->settings.vibro_on, vibro_value, VIBRO_COUNT);
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, vibro_text[value_index]);
|
||||
}
|
||||
|
||||
app->view_dispatcher = view_dispatcher_alloc();
|
||||
view_dispatcher_enable_queue(app->view_dispatcher);
|
||||
|
||||
@ -4,8 +4,8 @@
|
||||
#include <assets_icons.h>
|
||||
#include <locale/locale.h>
|
||||
|
||||
#define LOW_CHARGE_THRESHOLD 10
|
||||
#define HIGH_DRAIN_CURRENT_THRESHOLD 100
|
||||
#define LOW_CHARGE_THRESHOLD (10)
|
||||
#define HIGH_DRAIN_CURRENT_THRESHOLD (-100)
|
||||
|
||||
struct BatteryInfo {
|
||||
View* view;
|
||||
@ -25,14 +25,13 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
||||
char header[20] = {};
|
||||
char value[20] = {};
|
||||
|
||||
int32_t drain_current = data->gauge_current * (-1000);
|
||||
uint32_t charge_current = data->gauge_current * 1000;
|
||||
int32_t current = 1000.0f * data->gauge_current;
|
||||
|
||||
// Draw battery
|
||||
canvas_draw_icon(canvas, x, y, &I_BatteryBody_52x28);
|
||||
if(charge_current > 0) {
|
||||
if(current > 0) {
|
||||
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceCharging_29x14);
|
||||
} else if(drain_current > HIGH_DRAIN_CURRENT_THRESHOLD) {
|
||||
} else if(current < HIGH_DRAIN_CURRENT_THRESHOLD) {
|
||||
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceConfused_29x14);
|
||||
} else if(data->charge < LOW_CHARGE_THRESHOLD) {
|
||||
canvas_draw_icon(canvas, x + 16, y + 7, &I_FaceNopower_29x14);
|
||||
@ -44,7 +43,7 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
||||
elements_bubble(canvas, 53, 0, 71, 39);
|
||||
|
||||
// Set text
|
||||
if(charge_current > 0) {
|
||||
if(current > 0) {
|
||||
snprintf(emote, sizeof(emote), "%s", "Yummy!");
|
||||
snprintf(header, sizeof(header), "%s", "Charging at");
|
||||
snprintf(
|
||||
@ -53,34 +52,36 @@ static void draw_battery(Canvas* canvas, BatteryInfoModel* data, int x, int y) {
|
||||
"%lu.%luV %lumA",
|
||||
(uint32_t)(data->vbus_voltage),
|
||||
(uint32_t)(data->vbus_voltage * 10) % 10,
|
||||
charge_current);
|
||||
} else if(drain_current > 0) {
|
||||
current);
|
||||
} else if(current < 0) {
|
||||
snprintf(
|
||||
emote,
|
||||
sizeof(emote),
|
||||
"%s",
|
||||
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!");
|
||||
current < HIGH_DRAIN_CURRENT_THRESHOLD ? "Oh no!" : "Om-nom-nom!");
|
||||
snprintf(header, sizeof(header), "%s", "Consumption is");
|
||||
snprintf(
|
||||
value,
|
||||
sizeof(value),
|
||||
"%ld %s",
|
||||
drain_current,
|
||||
drain_current > HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
|
||||
} else if(drain_current != 0) {
|
||||
snprintf(header, 20, "...");
|
||||
} else if(data->charge_voltage_limit < 4.2) {
|
||||
// Non-default battery charging limit, mention it
|
||||
snprintf(emote, sizeof(emote), "Charged!");
|
||||
snprintf(header, sizeof(header), "Limited to");
|
||||
snprintf(
|
||||
value,
|
||||
sizeof(value),
|
||||
"%lu.%luV",
|
||||
(uint32_t)(data->charge_voltage_limit),
|
||||
(uint32_t)(data->charge_voltage_limit * 10) % 10);
|
||||
ABS(current),
|
||||
current < HIGH_DRAIN_CURRENT_THRESHOLD ? "mA!" : "mA");
|
||||
} else if(data->vbus_voltage > 0) {
|
||||
if(data->charge_voltage_limit < 4.2) {
|
||||
// Non-default battery charging limit, mention it
|
||||
snprintf(emote, sizeof(emote), "Charged!");
|
||||
snprintf(header, sizeof(header), "Limited to");
|
||||
snprintf(
|
||||
value,
|
||||
sizeof(value),
|
||||
"%lu.%luV",
|
||||
(uint32_t)(data->charge_voltage_limit),
|
||||
(uint32_t)(data->charge_voltage_limit * 10) % 10);
|
||||
} else {
|
||||
snprintf(header, sizeof(header), "Charged!");
|
||||
}
|
||||
} else {
|
||||
snprintf(header, sizeof(header), "Charged!");
|
||||
snprintf(header, sizeof(header), "Napping...");
|
||||
}
|
||||
|
||||
canvas_draw_str_aligned(canvas, 92, y + 3, AlignCenter, AlignCenter, emote);
|
||||
|
||||
@ -141,6 +141,21 @@ static void hand_orient_changed(VariableItem* item) {
|
||||
loader_update_menu();
|
||||
}
|
||||
|
||||
const char* const sleep_method[] = {
|
||||
"Default",
|
||||
"Legacy",
|
||||
};
|
||||
|
||||
static void sleep_method_changed(VariableItem* item) {
|
||||
uint8_t index = variable_item_get_current_value_index(item);
|
||||
variable_item_set_current_value_text(item, sleep_method[index]);
|
||||
if(index) {
|
||||
furi_hal_rtc_set_flag(FuriHalRtcFlagLegacySleep);
|
||||
} else {
|
||||
furi_hal_rtc_reset_flag(FuriHalRtcFlagLegacySleep);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t system_settings_exit(void* context) {
|
||||
UNUSED(context);
|
||||
return VIEW_NONE;
|
||||
@ -218,6 +233,12 @@ SystemSettings* system_settings_alloc() {
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, heap_trace_mode_text[value_index]);
|
||||
|
||||
item = variable_item_list_add(
|
||||
app->var_item_list, "Sleep Method", COUNT_OF(sleep_method), sleep_method_changed, app);
|
||||
value_index = furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) ? 1 : 0;
|
||||
variable_item_set_current_value_index(item, value_index);
|
||||
variable_item_set_current_value_text(item, sleep_method[value_index]);
|
||||
|
||||
view_set_previous_callback(
|
||||
variable_item_list_get_view(app->var_item_list), system_settings_exit);
|
||||
view_dispatcher_add_view(
|
||||
|
||||
BIN
assets/icons/StatusBar/Muted_8x8.png
Normal file
BIN
assets/icons/StatusBar/Muted_8x8.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
BIN
assets/icons/StatusBar/Rpc_active_7x8.png
Normal file
BIN
assets/icons/StatusBar/Rpc_active_7x8.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.5 KiB |
@ -135,6 +135,7 @@ class FlipperAppStateHelper:
|
||||
self.app_list_ptr = None
|
||||
self.app_list_entry_type = None
|
||||
self._current_apps: list[AppState] = []
|
||||
self.set_debug_mode(True)
|
||||
|
||||
def _walk_app_list(self, list_head):
|
||||
while list_head:
|
||||
@ -195,7 +196,7 @@ class FlipperAppStateHelper:
|
||||
self.set_debug_mode(False)
|
||||
|
||||
def set_debug_mode(self, mode: bool) -> None:
|
||||
gdb.execute(f"set variable fap_loader_debug_active = {int(mode)}")
|
||||
gdb.execute(f"set variable furi_hal_debug_gdb_session_active = {int(mode)}")
|
||||
|
||||
|
||||
# Init additional 'fap-set-debug-elf-root' command and set up hooks
|
||||
|
||||
26
documentation/FuriHalDebuging.md
Normal file
26
documentation/FuriHalDebuging.md
Normal file
@ -0,0 +1,26 @@
|
||||
# Furi HAL Debugging
|
||||
|
||||
Some Furi subsystem got additional debugging features that can be enabled by adding additional defines to firmware compilation.
|
||||
Usually they are used for low level tracing and profiling or signal redirection/duplication.
|
||||
|
||||
|
||||
## FuriHalOs
|
||||
|
||||
`--extra-define=FURI_HAL_OS_DEBUG` enables tick, tick suppression, idle and time flow.
|
||||
|
||||
There are 3 signals that will be exposed to external GPIO pins:
|
||||
|
||||
- `AWAKE` - `PA7` - High when system is busy with computations, low when sleeping. Can be used to track transitions to sleep mode.
|
||||
- `TICK` - `PA6` - Flipped on system tick, only flips when no tick suppression in progress. Can be used to track tick skew and abnormal task scheduling.
|
||||
- `SECOND` - `PA4` - Flipped each second. Can be used for tracing RT issue: time flow disturbance means system doesn't conforms Hard RT.
|
||||
|
||||
|
||||
|
||||
## FuriHalPower
|
||||
|
||||
`--extra-define=FURI_HAL_POWER_DEBUG` enables power subsystem mode transitions tracing.
|
||||
|
||||
There are 2 signals that will be exposed to external GPIO pins:
|
||||
|
||||
- `WFI` - `PB2` - Light sleep (wait for interrupt) used. Basically this is lightest and most non-breaking things power save mode. All function and debug should work correctly in this mode.
|
||||
- `STOP` - `PC3` - STOP mode used. Platform deep sleep mode. Extremely fragile mode where most of the silicon is disabled or in unusable state. Debugging MCU in this mode is nearly impossible.
|
||||
23
documentation/LFRFIDRaw.md
Normal file
23
documentation/LFRFIDRaw.md
Normal file
@ -0,0 +1,23 @@
|
||||
# Reading RAW RFID data
|
||||
|
||||
Flipper Zero has the option to read RAW data from 125 kHz cards that allows you to record the card's data and save it, similar to how a dictaphone records sound.
|
||||
|
||||
To use this function, you need to activate the Debug mode on your Flipper Zero by doing the following:
|
||||
|
||||
1. Go to **Main Menu** → **Settings** → **System**.
|
||||
|
||||
2. Set **Debug** to **ON**.
|
||||
|
||||
Once the Debug mode is activated on your Flipper Zero, you can read RAW data from 125 kHz RFID cards:
|
||||
|
||||
1. Go to **Main Menu** → **125 kHz RFID** → **Extra Actions**.
|
||||
|
||||
2. Select **RAW RFID** data and name the raw file.
|
||||
|
||||
3. Read instructions and press **OK**.
|
||||
|
||||
4. Apply the card to Flipper Zero's back.
|
||||
|
||||
5. Once the reading is finished, press **OK**.
|
||||
|
||||
Two files with data (with ASK and PSK modulations) will be saved in the `lfrfid` folder on the microSD card. Now, you can share it and the card's photo with developers by creating an issue on GitHub.
|
||||
@ -105,6 +105,7 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
|
||||
- `--options optionfile.py` (default value `fbt_options.py`) - load a file with multiple configuration values
|
||||
- `--extra-int-apps=app1,app2,appN` - force listed apps to be built as internal with the `firmware` target
|
||||
- `--extra-ext-apps=app1,app2,appN` - force listed apps to be built as external with the `firmware_extapps` target
|
||||
- `--extra-define=A --extra-define=B=C ` - extra global defines that will be passed to the C/C++ compiler, can be specified multiple times
|
||||
- `--proxy-env=VAR1,VAR2` - additional environment variables to expose to subprocesses spawned by `fbt`. By default, `fbt` sanitizes the execution environment and doesn't forward all inherited environment variables. You can find the list of variables that are always forwarded in the `environ.scons` file.
|
||||
|
||||
## Configuration
|
||||
|
||||
@ -20,7 +20,7 @@ DIST_SUFFIX = "local"
|
||||
COPRO_OB_DATA = "scripts/ob.data"
|
||||
|
||||
# Must match lib/STM32CubeWB version
|
||||
COPRO_CUBE_VERSION = "1.13.3"
|
||||
COPRO_CUBE_VERSION = "1.16.0"
|
||||
|
||||
COPRO_CUBE_DIR = "lib/STM32CubeWB"
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,21.0,,
|
||||
Version,+,23.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@ -176,17 +176,17 @@ Header,+,lib/toolbox/tar/tar_archive.h,,
|
||||
Header,+,lib/toolbox/value_index.h,,
|
||||
Header,+,lib/toolbox/version.h,,
|
||||
Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef*
|
||||
Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, LL_ADC_CommonInitTypeDef*"
|
||||
Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, const LL_ADC_CommonInitTypeDef*"
|
||||
Function,-,LL_ADC_CommonStructInit,void,LL_ADC_CommonInitTypeDef*
|
||||
Function,-,LL_ADC_DeInit,ErrorStatus,ADC_TypeDef*
|
||||
Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_INJ_InitTypeDef*"
|
||||
Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_INJ_InitTypeDef*"
|
||||
Function,-,LL_ADC_INJ_StructInit,void,LL_ADC_INJ_InitTypeDef*
|
||||
Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_InitTypeDef*"
|
||||
Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_REG_InitTypeDef*"
|
||||
Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_InitTypeDef*"
|
||||
Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_REG_InitTypeDef*"
|
||||
Function,-,LL_ADC_REG_StructInit,void,LL_ADC_REG_InitTypeDef*
|
||||
Function,-,LL_ADC_StructInit,void,LL_ADC_InitTypeDef*
|
||||
Function,-,LL_COMP_DeInit,ErrorStatus,COMP_TypeDef*
|
||||
Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, LL_COMP_InitTypeDef*"
|
||||
Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, const LL_COMP_InitTypeDef*"
|
||||
Function,-,LL_COMP_StructInit,void,LL_COMP_InitTypeDef*
|
||||
Function,-,LL_CRC_DeInit,ErrorStatus,CRC_TypeDef*
|
||||
Function,-,LL_CRS_DeInit,ErrorStatus,
|
||||
@ -199,16 +199,16 @@ Function,-,LL_EXTI_StructInit,void,LL_EXTI_InitTypeDef*
|
||||
Function,-,LL_GPIO_DeInit,ErrorStatus,GPIO_TypeDef*
|
||||
Function,+,LL_GPIO_Init,ErrorStatus,"GPIO_TypeDef*, LL_GPIO_InitTypeDef*"
|
||||
Function,-,LL_GPIO_StructInit,void,LL_GPIO_InitTypeDef*
|
||||
Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef*
|
||||
Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*"
|
||||
Function,-,LL_I2C_DeInit,ErrorStatus,const I2C_TypeDef*
|
||||
Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, const LL_I2C_InitTypeDef*"
|
||||
Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef*
|
||||
Function,-,LL_Init1msTick,void,uint32_t
|
||||
Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef*
|
||||
Function,-,LL_LPTIM_Disable,void,LPTIM_TypeDef*
|
||||
Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, LL_LPTIM_InitTypeDef*"
|
||||
Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, const LL_LPTIM_InitTypeDef*"
|
||||
Function,-,LL_LPTIM_StructInit,void,LL_LPTIM_InitTypeDef*
|
||||
Function,-,LL_LPUART_DeInit,ErrorStatus,USART_TypeDef*
|
||||
Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, LL_LPUART_InitTypeDef*"
|
||||
Function,-,LL_LPUART_DeInit,ErrorStatus,const USART_TypeDef*
|
||||
Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, const LL_LPUART_InitTypeDef*"
|
||||
Function,-,LL_LPUART_StructInit,void,LL_LPUART_InitTypeDef*
|
||||
Function,-,LL_PKA_DeInit,ErrorStatus,PKA_TypeDef*
|
||||
Function,-,LL_PKA_Init,ErrorStatus,"PKA_TypeDef*, LL_PKA_InitTypeDef*"
|
||||
@ -253,23 +253,23 @@ Function,+,LL_SPI_Init,ErrorStatus,"SPI_TypeDef*, LL_SPI_InitTypeDef*"
|
||||
Function,-,LL_SPI_StructInit,void,LL_SPI_InitTypeDef*
|
||||
Function,-,LL_SetFlashLatency,ErrorStatus,uint32_t
|
||||
Function,+,LL_SetSystemCoreClock,void,uint32_t
|
||||
Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_BDTR_InitTypeDef*"
|
||||
Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_BDTR_InitTypeDef*"
|
||||
Function,-,LL_TIM_BDTR_StructInit,void,LL_TIM_BDTR_InitTypeDef*
|
||||
Function,+,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef*
|
||||
Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_ENCODER_InitTypeDef*"
|
||||
Function,-,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef*
|
||||
Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_ENCODER_InitTypeDef*"
|
||||
Function,-,LL_TIM_ENCODER_StructInit,void,LL_TIM_ENCODER_InitTypeDef*
|
||||
Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_HALLSENSOR_InitTypeDef*"
|
||||
Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_HALLSENSOR_InitTypeDef*"
|
||||
Function,-,LL_TIM_HALLSENSOR_StructInit,void,LL_TIM_HALLSENSOR_InitTypeDef*
|
||||
Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_IC_InitTypeDef*"
|
||||
Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_IC_InitTypeDef*"
|
||||
Function,-,LL_TIM_IC_StructInit,void,LL_TIM_IC_InitTypeDef*
|
||||
Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_InitTypeDef*"
|
||||
Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_OC_InitTypeDef*"
|
||||
Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_InitTypeDef*"
|
||||
Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_OC_InitTypeDef*"
|
||||
Function,-,LL_TIM_OC_StructInit,void,LL_TIM_OC_InitTypeDef*
|
||||
Function,-,LL_TIM_StructInit,void,LL_TIM_InitTypeDef*
|
||||
Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, LL_USART_ClockInitTypeDef*"
|
||||
Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, const LL_USART_ClockInitTypeDef*"
|
||||
Function,-,LL_USART_ClockStructInit,void,LL_USART_ClockInitTypeDef*
|
||||
Function,-,LL_USART_DeInit,ErrorStatus,USART_TypeDef*
|
||||
Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, LL_USART_InitTypeDef*"
|
||||
Function,-,LL_USART_DeInit,ErrorStatus,const USART_TypeDef*
|
||||
Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, const LL_USART_InitTypeDef*"
|
||||
Function,-,LL_USART_StructInit,void,LL_USART_InitTypeDef*
|
||||
Function,-,LL_mDelay,void,uint32_t
|
||||
Function,-,SystemCoreClockUpdate,void,
|
||||
@ -901,6 +901,7 @@ Function,+,furi_hal_crypto_verify_enclave,_Bool,"uint8_t*, uint8_t*"
|
||||
Function,+,furi_hal_crypto_verify_key,_Bool,uint8_t
|
||||
Function,+,furi_hal_debug_disable,void,
|
||||
Function,+,furi_hal_debug_enable,void,
|
||||
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
||||
Function,-,furi_hal_deinit_early,void,
|
||||
Function,-,furi_hal_flash_erase,void,uint8_t
|
||||
Function,-,furi_hal_flash_get_base,size_t,
|
||||
@ -983,7 +984,6 @@ Function,-,furi_hal_os_init,void,
|
||||
Function,+,furi_hal_os_tick,void,
|
||||
Function,+,furi_hal_power_check_otg_status,void,
|
||||
Function,+,furi_hal_power_debug_get,void,"PropertyValueCallback, void*"
|
||||
Function,+,furi_hal_power_deep_sleep_available,_Bool,
|
||||
Function,+,furi_hal_power_disable_external_3_3v,void,
|
||||
Function,+,furi_hal_power_disable_otg,void,
|
||||
Function,+,furi_hal_power_enable_external_3_3v,void,
|
||||
@ -1059,6 +1059,7 @@ Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits
|
||||
Function,+,furi_hal_rtc_set_log_level,void,uint8_t
|
||||
Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t
|
||||
Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t"
|
||||
Function,+,furi_hal_rtc_sync_shadow,void,
|
||||
Function,+,furi_hal_rtc_validate_datetime,_Bool,FuriHalRtcDateTime*
|
||||
Function,+,furi_hal_speaker_acquire,_Bool,uint32_t
|
||||
Function,-,furi_hal_speaker_deinit,void,
|
||||
@ -1595,7 +1596,8 @@ Function,-,rindex,char*,"const char*, int"
|
||||
Function,+,rpc_session_close,void,RpcSession*
|
||||
Function,+,rpc_session_feed,size_t,"RpcSession*, uint8_t*, size_t, TickType_t"
|
||||
Function,+,rpc_session_get_available_size,size_t,RpcSession*
|
||||
Function,+,rpc_session_open,RpcSession*,Rpc*
|
||||
Function,+,rpc_session_get_owner,RpcOwner,RpcSession*
|
||||
Function,+,rpc_session_open,RpcSession*,"Rpc*, RpcOwner"
|
||||
Function,+,rpc_session_set_buffer_is_empty_callback,void,"RpcSession*, RpcBufferIsEmptyCallback"
|
||||
Function,+,rpc_session_set_close_callback,void,"RpcSession*, RpcSessionClosedCallback"
|
||||
Function,+,rpc_session_set_context,void,"RpcSession*, void*"
|
||||
@ -2149,6 +2151,8 @@ Variable,+,gpio_ext_pd0,const GpioPin,
|
||||
Variable,+,gpio_ext_pe4,const GpioPin,
|
||||
Variable,+,gpio_i2c_power_scl,const GpioPin,
|
||||
Variable,+,gpio_i2c_power_sda,const GpioPin,
|
||||
Variable,+,gpio_ibutton,const GpioPin,
|
||||
Variable,+,gpio_periph_power,const GpioPin,
|
||||
Variable,+,gpio_pins,const GpioPinRecord[],
|
||||
Variable,+,gpio_pins_count,const size_t,
|
||||
Variable,+,gpio_sdcard_cd,const GpioPin,
|
||||
@ -2157,11 +2161,13 @@ Variable,+,gpio_speaker,const GpioPin,
|
||||
Variable,+,gpio_spi_d_miso,const GpioPin,
|
||||
Variable,+,gpio_spi_d_mosi,const GpioPin,
|
||||
Variable,+,gpio_spi_d_sck,const GpioPin,
|
||||
Variable,+,gpio_swclk,const GpioPin,
|
||||
Variable,+,gpio_swdio,const GpioPin,
|
||||
Variable,+,gpio_usart_rx,const GpioPin,
|
||||
Variable,+,gpio_usart_tx,const GpioPin,
|
||||
Variable,+,gpio_usb_dm,const GpioPin,
|
||||
Variable,+,gpio_usb_dp,const GpioPin,
|
||||
Variable,+,gpio_ibutton,const GpioPin,
|
||||
Variable,+,gpio_vibro,const GpioPin,
|
||||
Variable,+,input_pins,const InputPin[],
|
||||
Variable,+,input_pins_count,const size_t,
|
||||
Variable,+,message_blink_set_color_blue,const NotificationMessage,
|
||||
@ -2309,7 +2315,6 @@ Variable,+,message_red_255,const NotificationMessage,
|
||||
Variable,+,message_sound_off,const NotificationMessage,
|
||||
Variable,+,message_vibro_off,const NotificationMessage,
|
||||
Variable,+,message_vibro_on,const NotificationMessage,
|
||||
Variable,+,gpio_periph_power,const GpioPin,
|
||||
Variable,+,sequence_audiovisual_alert,const NotificationSequence,
|
||||
Variable,+,sequence_blink_blue_10,const NotificationSequence,
|
||||
Variable,+,sequence_blink_blue_100,const NotificationSequence,
|
||||
@ -2364,4 +2369,3 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface,
|
||||
Variable,+,usb_hid,FuriHalUsbInterface,
|
||||
Variable,+,usb_hid_u2f,FuriHalUsbInterface,
|
||||
Variable,+,usbd_devfs,const usbd_driver,
|
||||
Variable,+,gpio_vibro,const GpioPin,
|
||||
|
||||
|
@ -6,6 +6,9 @@
|
||||
|
||||
#define TAG "FuriHalResources"
|
||||
|
||||
const GpioPin gpio_swdio = {.port = GPIOA, .pin = LL_GPIO_PIN_13};
|
||||
const GpioPin gpio_swclk = {.port = GPIOA, .pin = LL_GPIO_PIN_14};
|
||||
|
||||
const GpioPin gpio_vibro = {.port = GPIOA, .pin = LL_GPIO_PIN_8};
|
||||
const GpioPin gpio_ibutton = {.port = GPIOB, .pin = LL_GPIO_PIN_14};
|
||||
|
||||
@ -166,8 +169,9 @@ void furi_hal_resources_init() {
|
||||
furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall);
|
||||
|
||||
// Explicit pulls pins
|
||||
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||
furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||
LL_PWR_EnablePUPDCfg();
|
||||
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker
|
||||
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro
|
||||
|
||||
// Display pins
|
||||
furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
@ -50,6 +50,9 @@ extern const size_t input_pins_count;
|
||||
extern const GpioPinRecord gpio_pins[];
|
||||
extern const size_t gpio_pins_count;
|
||||
|
||||
extern const GpioPin gpio_swdio;
|
||||
extern const GpioPin gpio_swclk;
|
||||
|
||||
extern const GpioPin gpio_vibro;
|
||||
extern const GpioPin gpio_ibutton;
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,21.0,,
|
||||
Version,+,23.0,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@ -208,17 +208,17 @@ Header,+,lib/toolbox/tar/tar_archive.h,,
|
||||
Header,+,lib/toolbox/value_index.h,,
|
||||
Header,+,lib/toolbox/version.h,,
|
||||
Function,-,LL_ADC_CommonDeInit,ErrorStatus,ADC_Common_TypeDef*
|
||||
Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, LL_ADC_CommonInitTypeDef*"
|
||||
Function,-,LL_ADC_CommonInit,ErrorStatus,"ADC_Common_TypeDef*, const LL_ADC_CommonInitTypeDef*"
|
||||
Function,-,LL_ADC_CommonStructInit,void,LL_ADC_CommonInitTypeDef*
|
||||
Function,-,LL_ADC_DeInit,ErrorStatus,ADC_TypeDef*
|
||||
Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_INJ_InitTypeDef*"
|
||||
Function,-,LL_ADC_INJ_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_INJ_InitTypeDef*"
|
||||
Function,-,LL_ADC_INJ_StructInit,void,LL_ADC_INJ_InitTypeDef*
|
||||
Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_InitTypeDef*"
|
||||
Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, LL_ADC_REG_InitTypeDef*"
|
||||
Function,-,LL_ADC_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_InitTypeDef*"
|
||||
Function,-,LL_ADC_REG_Init,ErrorStatus,"ADC_TypeDef*, const LL_ADC_REG_InitTypeDef*"
|
||||
Function,-,LL_ADC_REG_StructInit,void,LL_ADC_REG_InitTypeDef*
|
||||
Function,-,LL_ADC_StructInit,void,LL_ADC_InitTypeDef*
|
||||
Function,-,LL_COMP_DeInit,ErrorStatus,COMP_TypeDef*
|
||||
Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, LL_COMP_InitTypeDef*"
|
||||
Function,+,LL_COMP_Init,ErrorStatus,"COMP_TypeDef*, const LL_COMP_InitTypeDef*"
|
||||
Function,-,LL_COMP_StructInit,void,LL_COMP_InitTypeDef*
|
||||
Function,-,LL_CRC_DeInit,ErrorStatus,CRC_TypeDef*
|
||||
Function,-,LL_CRS_DeInit,ErrorStatus,
|
||||
@ -231,16 +231,16 @@ Function,-,LL_EXTI_StructInit,void,LL_EXTI_InitTypeDef*
|
||||
Function,-,LL_GPIO_DeInit,ErrorStatus,GPIO_TypeDef*
|
||||
Function,+,LL_GPIO_Init,ErrorStatus,"GPIO_TypeDef*, LL_GPIO_InitTypeDef*"
|
||||
Function,-,LL_GPIO_StructInit,void,LL_GPIO_InitTypeDef*
|
||||
Function,-,LL_I2C_DeInit,ErrorStatus,I2C_TypeDef*
|
||||
Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, LL_I2C_InitTypeDef*"
|
||||
Function,-,LL_I2C_DeInit,ErrorStatus,const I2C_TypeDef*
|
||||
Function,+,LL_I2C_Init,ErrorStatus,"I2C_TypeDef*, const LL_I2C_InitTypeDef*"
|
||||
Function,-,LL_I2C_StructInit,void,LL_I2C_InitTypeDef*
|
||||
Function,-,LL_Init1msTick,void,uint32_t
|
||||
Function,+,LL_LPTIM_DeInit,ErrorStatus,LPTIM_TypeDef*
|
||||
Function,-,LL_LPTIM_Disable,void,LPTIM_TypeDef*
|
||||
Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, LL_LPTIM_InitTypeDef*"
|
||||
Function,+,LL_LPTIM_Init,ErrorStatus,"LPTIM_TypeDef*, const LL_LPTIM_InitTypeDef*"
|
||||
Function,-,LL_LPTIM_StructInit,void,LL_LPTIM_InitTypeDef*
|
||||
Function,-,LL_LPUART_DeInit,ErrorStatus,USART_TypeDef*
|
||||
Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, LL_LPUART_InitTypeDef*"
|
||||
Function,-,LL_LPUART_DeInit,ErrorStatus,const USART_TypeDef*
|
||||
Function,+,LL_LPUART_Init,ErrorStatus,"USART_TypeDef*, const LL_LPUART_InitTypeDef*"
|
||||
Function,-,LL_LPUART_StructInit,void,LL_LPUART_InitTypeDef*
|
||||
Function,-,LL_PKA_DeInit,ErrorStatus,PKA_TypeDef*
|
||||
Function,-,LL_PKA_Init,ErrorStatus,"PKA_TypeDef*, LL_PKA_InitTypeDef*"
|
||||
@ -285,23 +285,23 @@ Function,+,LL_SPI_Init,ErrorStatus,"SPI_TypeDef*, LL_SPI_InitTypeDef*"
|
||||
Function,-,LL_SPI_StructInit,void,LL_SPI_InitTypeDef*
|
||||
Function,-,LL_SetFlashLatency,ErrorStatus,uint32_t
|
||||
Function,+,LL_SetSystemCoreClock,void,uint32_t
|
||||
Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_BDTR_InitTypeDef*"
|
||||
Function,-,LL_TIM_BDTR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_BDTR_InitTypeDef*"
|
||||
Function,-,LL_TIM_BDTR_StructInit,void,LL_TIM_BDTR_InitTypeDef*
|
||||
Function,+,LL_TIM_DeInit,ErrorStatus,TIM_TypeDef*
|
||||
Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_ENCODER_InitTypeDef*"
|
||||
Function,-,LL_TIM_ENCODER_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_ENCODER_InitTypeDef*"
|
||||
Function,-,LL_TIM_ENCODER_StructInit,void,LL_TIM_ENCODER_InitTypeDef*
|
||||
Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_HALLSENSOR_InitTypeDef*"
|
||||
Function,-,LL_TIM_HALLSENSOR_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_HALLSENSOR_InitTypeDef*"
|
||||
Function,-,LL_TIM_HALLSENSOR_StructInit,void,LL_TIM_HALLSENSOR_InitTypeDef*
|
||||
Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_IC_InitTypeDef*"
|
||||
Function,-,LL_TIM_IC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_IC_InitTypeDef*"
|
||||
Function,-,LL_TIM_IC_StructInit,void,LL_TIM_IC_InitTypeDef*
|
||||
Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, LL_TIM_InitTypeDef*"
|
||||
Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, LL_TIM_OC_InitTypeDef*"
|
||||
Function,+,LL_TIM_Init,ErrorStatus,"TIM_TypeDef*, const LL_TIM_InitTypeDef*"
|
||||
Function,+,LL_TIM_OC_Init,ErrorStatus,"TIM_TypeDef*, uint32_t, const LL_TIM_OC_InitTypeDef*"
|
||||
Function,-,LL_TIM_OC_StructInit,void,LL_TIM_OC_InitTypeDef*
|
||||
Function,-,LL_TIM_StructInit,void,LL_TIM_InitTypeDef*
|
||||
Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, LL_USART_ClockInitTypeDef*"
|
||||
Function,-,LL_USART_ClockInit,ErrorStatus,"USART_TypeDef*, const LL_USART_ClockInitTypeDef*"
|
||||
Function,-,LL_USART_ClockStructInit,void,LL_USART_ClockInitTypeDef*
|
||||
Function,-,LL_USART_DeInit,ErrorStatus,USART_TypeDef*
|
||||
Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, LL_USART_InitTypeDef*"
|
||||
Function,-,LL_USART_DeInit,ErrorStatus,const USART_TypeDef*
|
||||
Function,+,LL_USART_Init,ErrorStatus,"USART_TypeDef*, const LL_USART_InitTypeDef*"
|
||||
Function,-,LL_USART_StructInit,void,LL_USART_InitTypeDef*
|
||||
Function,-,LL_mDelay,void,uint32_t
|
||||
Function,-,SystemCoreClockUpdate,void,
|
||||
@ -1082,6 +1082,7 @@ Function,+,furi_hal_crypto_verify_enclave,_Bool,"uint8_t*, uint8_t*"
|
||||
Function,+,furi_hal_crypto_verify_key,_Bool,uint8_t
|
||||
Function,+,furi_hal_debug_disable,void,
|
||||
Function,+,furi_hal_debug_enable,void,
|
||||
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
||||
Function,-,furi_hal_deinit_early,void,
|
||||
Function,-,furi_hal_flash_erase,void,uint8_t
|
||||
Function,-,furi_hal_flash_get_base,size_t,
|
||||
@ -1212,7 +1213,6 @@ Function,-,furi_hal_os_init,void,
|
||||
Function,+,furi_hal_os_tick,void,
|
||||
Function,+,furi_hal_power_check_otg_status,void,
|
||||
Function,+,furi_hal_power_debug_get,void,"PropertyValueCallback, void*"
|
||||
Function,+,furi_hal_power_deep_sleep_available,_Bool,
|
||||
Function,+,furi_hal_power_disable_external_3_3v,void,
|
||||
Function,+,furi_hal_power_disable_otg,void,
|
||||
Function,+,furi_hal_power_enable_external_3_3v,void,
|
||||
@ -1313,6 +1313,7 @@ Function,+,furi_hal_rtc_set_locale_units,void,FuriHalRtcLocaleUnits
|
||||
Function,+,furi_hal_rtc_set_log_level,void,uint8_t
|
||||
Function,+,furi_hal_rtc_set_pin_fails,void,uint32_t
|
||||
Function,+,furi_hal_rtc_set_register,void,"FuriHalRtcRegister, uint32_t"
|
||||
Function,+,furi_hal_rtc_sync_shadow,void,
|
||||
Function,+,furi_hal_rtc_validate_datetime,_Bool,FuriHalRtcDateTime*
|
||||
Function,+,furi_hal_speaker_acquire,_Bool,uint32_t
|
||||
Function,-,furi_hal_speaker_deinit,void,
|
||||
@ -2372,7 +2373,8 @@ Function,-,roundl,long double,long double
|
||||
Function,+,rpc_session_close,void,RpcSession*
|
||||
Function,+,rpc_session_feed,size_t,"RpcSession*, uint8_t*, size_t, TickType_t"
|
||||
Function,+,rpc_session_get_available_size,size_t,RpcSession*
|
||||
Function,+,rpc_session_open,RpcSession*,Rpc*
|
||||
Function,+,rpc_session_get_owner,RpcOwner,RpcSession*
|
||||
Function,+,rpc_session_open,RpcSession*,"Rpc*, RpcOwner"
|
||||
Function,+,rpc_session_set_buffer_is_empty_callback,void,"RpcSession*, RpcBufferIsEmptyCallback"
|
||||
Function,+,rpc_session_set_close_callback,void,"RpcSession*, RpcSessionClosedCallback"
|
||||
Function,+,rpc_session_set_context,void,"RpcSession*, void*"
|
||||
@ -3076,10 +3078,12 @@ Variable,+,gpio_ext_pc1,const GpioPin,
|
||||
Variable,+,gpio_ext_pc3,const GpioPin,
|
||||
Variable,+,gpio_i2c_power_scl,const GpioPin,
|
||||
Variable,+,gpio_i2c_power_sda,const GpioPin,
|
||||
Variable,+,gpio_ibutton,const GpioPin,
|
||||
Variable,+,gpio_infrared_rx,const GpioPin,
|
||||
Variable,+,gpio_infrared_tx,const GpioPin,
|
||||
Variable,+,gpio_nfc_cs,const GpioPin,
|
||||
Variable,+,gpio_nfc_irq_rfid_pull,const GpioPin,
|
||||
Variable,+,gpio_periph_power,const GpioPin,
|
||||
Variable,+,gpio_pins,const GpioPinRecord[],
|
||||
Variable,+,gpio_pins_count,const size_t,
|
||||
Variable,+,gpio_rf_sw_0,const GpioPin,
|
||||
@ -3096,11 +3100,13 @@ Variable,+,gpio_spi_r_miso,const GpioPin,
|
||||
Variable,+,gpio_spi_r_mosi,const GpioPin,
|
||||
Variable,+,gpio_spi_r_sck,const GpioPin,
|
||||
Variable,+,gpio_subghz_cs,const GpioPin,
|
||||
Variable,+,gpio_swclk,const GpioPin,
|
||||
Variable,+,gpio_swdio,const GpioPin,
|
||||
Variable,+,gpio_usart_rx,const GpioPin,
|
||||
Variable,+,gpio_usart_tx,const GpioPin,
|
||||
Variable,+,gpio_usb_dm,const GpioPin,
|
||||
Variable,+,gpio_usb_dp,const GpioPin,
|
||||
Variable,+,gpio_ibutton,const GpioPin,
|
||||
Variable,+,gpio_vibro,const GpioPin,
|
||||
Variable,+,input_pins,const InputPin[],
|
||||
Variable,+,input_pins_count,const size_t,
|
||||
Variable,+,lfrfid_protocols,const ProtocolBase*[],
|
||||
@ -3249,7 +3255,6 @@ Variable,+,message_red_255,const NotificationMessage,
|
||||
Variable,+,message_sound_off,const NotificationMessage,
|
||||
Variable,+,message_vibro_off,const NotificationMessage,
|
||||
Variable,+,message_vibro_on,const NotificationMessage,
|
||||
Variable,+,gpio_periph_power,const GpioPin,
|
||||
Variable,+,sequence_audiovisual_alert,const NotificationSequence,
|
||||
Variable,+,sequence_blink_blue_10,const NotificationSequence,
|
||||
Variable,+,sequence_blink_blue_100,const NotificationSequence,
|
||||
@ -3307,4 +3312,3 @@ Variable,+,usb_cdc_single,FuriHalUsbInterface,
|
||||
Variable,+,usb_hid,FuriHalUsbInterface,
|
||||
Variable,+,usb_hid_u2f,FuriHalUsbInterface,
|
||||
Variable,+,usbd_devfs,const usbd_driver,
|
||||
Variable,+,gpio_vibro,const GpioPin,
|
||||
|
||||
|
@ -33,6 +33,7 @@ extern "C" {
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <core/common_defines.h>
|
||||
#include <tl.h>
|
||||
|
||||
#include "app_conf.h"
|
||||
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
|
||||
#define CFG_TX_POWER (0x19) /* +0dBm */
|
||||
|
||||
#define CFG_IDENTITY_ADDRESS GAP_PUBLIC_ADDR
|
||||
|
||||
/**
|
||||
* Define Advertising parameters
|
||||
*/
|
||||
|
||||
@ -33,7 +33,8 @@ PLACE_IN_SECTION("MB_MEM2")
|
||||
ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig = {0, 0, 0, 0};
|
||||
PLACE_IN_SECTION("MB_MEM2")
|
||||
ALIGN(4)
|
||||
static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig = {BLE_DTB_CFG, SYS_DBG_CFG1, {0, 0}};
|
||||
static SHCI_C2_DEBUG_GeneralConfig_t APPD_GeneralConfig =
|
||||
{BLE_DTB_CFG, SYS_DBG_CFG1, {0, 0}, 0, 0, 0, 0, 0};
|
||||
|
||||
/**
|
||||
* THE DEBUG ON GPIO FOR CPU2 IS INTENDED TO BE USED ONLY ON REQUEST FROM ST SUPPORT
|
||||
@ -68,7 +69,7 @@ static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] = {
|
||||
{GPIOA, LL_GPIO_PIN_0, 0, 0}, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */
|
||||
{GPIOA, LL_GPIO_PIN_0, 0, 0}, /* TIMER_SERVER_CALLBACK - Toggle on Entry */
|
||||
{GPIOA, LL_GPIO_PIN_4, 1, 0}, /* PES_ACTIVITY - Set on Entry / Reset on Exit */
|
||||
{GPIOB, LL_GPIO_PIN_2, 1, 0}, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */
|
||||
{GPIOC, LL_GPIO_PIN_0, 1, 0}, /* MB_BLE_SEND_EVT - Set on Entry / Reset on Exit */
|
||||
/* From v1.3.0 */
|
||||
{GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_NO_DELAY - Set on Entry / Reset on Exit */
|
||||
{GPIOA, LL_GPIO_PIN_0, 0, 0}, /* BLE_STACK_STORE_NVM_CB - Set on Entry / Reset on Exit */
|
||||
|
||||
@ -18,8 +18,8 @@ PLACE_IN_SECTION("MB_MEM1") ALIGN(4) static TL_CmdPacket_t ble_app_cmd_buffer;
|
||||
PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static uint32_t ble_app_nvm[BLE_NVM_SRAM_SIZE];
|
||||
|
||||
_Static_assert(
|
||||
sizeof(SHCI_C2_Ble_Init_Cmd_Packet_t) == 49,
|
||||
"Ble stack config structure size mismatch");
|
||||
sizeof(SHCI_C2_Ble_Init_Cmd_Packet_t) == 58,
|
||||
"Ble stack config structure size mismatch (check new config options - last updated for v.1.16.0)");
|
||||
|
||||
typedef struct {
|
||||
FuriMutex* hci_mtx;
|
||||
@ -88,6 +88,12 @@ bool ble_app_init() {
|
||||
.min_tx_power = 0,
|
||||
.max_tx_power = 0,
|
||||
.rx_model_config = 1,
|
||||
/* New stack (13.3->16.0)*/
|
||||
.max_adv_set_nbr = 1, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set
|
||||
.max_adv_data_len = 31, // Only used if SHCI_C2_BLE_INIT_OPTIONS_EXT_ADV is set
|
||||
.tx_path_compens = 0, // RF TX Path Compensation, * 0.1 dB
|
||||
.rx_path_compens = 0, // RF RX Path Compensation, * 0.1 dB
|
||||
.ble_core_version = 11, // BLE Core Version: 11(5.2), 12(5.3)
|
||||
}};
|
||||
status = SHCI_C2_BLE_Init(&ble_init_cmd_packet);
|
||||
if(status) {
|
||||
@ -137,38 +143,33 @@ static int32_t ble_app_hci_thread(void* arg) {
|
||||
// Called by WPAN lib
|
||||
void hci_notify_asynch_evt(void* pdata) {
|
||||
UNUSED(pdata);
|
||||
if(ble_app) {
|
||||
FuriThreadId thread_id = furi_thread_get_id(ble_app->thread);
|
||||
furi_assert(thread_id);
|
||||
furi_thread_flags_set(thread_id, BLE_APP_FLAG_HCI_EVENT);
|
||||
}
|
||||
furi_check(ble_app);
|
||||
FuriThreadId thread_id = furi_thread_get_id(ble_app->thread);
|
||||
furi_assert(thread_id);
|
||||
furi_thread_flags_set(thread_id, BLE_APP_FLAG_HCI_EVENT);
|
||||
}
|
||||
|
||||
void hci_cmd_resp_release(uint32_t flag) {
|
||||
UNUSED(flag);
|
||||
if(ble_app) {
|
||||
furi_semaphore_release(ble_app->hci_sem);
|
||||
}
|
||||
furi_check(ble_app);
|
||||
furi_check(furi_semaphore_release(ble_app->hci_sem) == FuriStatusOk);
|
||||
}
|
||||
|
||||
void hci_cmd_resp_wait(uint32_t timeout) {
|
||||
UNUSED(timeout);
|
||||
if(ble_app) {
|
||||
furi_semaphore_acquire(ble_app->hci_sem, FuriWaitForever);
|
||||
}
|
||||
furi_check(ble_app);
|
||||
furi_check(furi_semaphore_acquire(ble_app->hci_sem, timeout) == FuriStatusOk);
|
||||
}
|
||||
|
||||
static void ble_app_hci_event_handler(void* pPayload) {
|
||||
SVCCTL_UserEvtFlowStatus_t svctl_return_status;
|
||||
tHCI_UserEvtRxParam* pParam = (tHCI_UserEvtRxParam*)pPayload;
|
||||
|
||||
if(ble_app) {
|
||||
svctl_return_status = SVCCTL_UserEvtRx((void*)&(pParam->pckt->evtserial));
|
||||
if(svctl_return_status != SVCCTL_UserEvtFlowDisable) {
|
||||
pParam->status = HCI_TL_UserEventFlow_Enable;
|
||||
} else {
|
||||
pParam->status = HCI_TL_UserEventFlow_Disable;
|
||||
}
|
||||
furi_check(ble_app);
|
||||
svctl_return_status = SVCCTL_UserEvtRx((void*)&(pParam->pckt->evtserial));
|
||||
if(svctl_return_status != SVCCTL_UserEvtFlowDisable) {
|
||||
pParam->status = HCI_TL_UserEventFlow_Enable;
|
||||
} else {
|
||||
pParam->status = HCI_TL_UserEventFlow_Disable;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -23,6 +23,7 @@
|
||||
#include <ble/core/ble_std.h>
|
||||
#include <ble/core/ble_defs.h>
|
||||
#include "osal.h"
|
||||
#include "compiler.h"
|
||||
|
||||
/* Default BLE variant */
|
||||
#ifndef BASIC_FEATURES
|
||||
@ -34,6 +35,9 @@
|
||||
#ifndef LL_ONLY
|
||||
#define LL_ONLY 0
|
||||
#endif
|
||||
#ifndef LL_ONLY_BASIC
|
||||
#define LL_ONLY_BASIC 0
|
||||
#endif
|
||||
#ifndef BEACON_ONLY
|
||||
#define BEACON_ONLY 0
|
||||
#endif
|
||||
|
||||
@ -58,12 +58,6 @@ void ble_glue_init() {
|
||||
ble_glue = malloc(sizeof(BleGlue));
|
||||
ble_glue->status = BleGlueStatusStartup;
|
||||
|
||||
// Configure the system Power Mode
|
||||
// Select HSI as system clock source after Wake Up from Stop mode
|
||||
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
|
||||
/* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */
|
||||
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
|
||||
|
||||
#ifdef BLE_GLUE_DEBUG
|
||||
APPD_Init();
|
||||
#endif
|
||||
@ -409,7 +403,9 @@ void shci_cmd_resp_release(uint32_t flag) {
|
||||
void shci_cmd_resp_wait(uint32_t timeout) {
|
||||
UNUSED(timeout);
|
||||
if(ble_glue) {
|
||||
furi_hal_power_insomnia_enter();
|
||||
furi_semaphore_acquire(ble_glue->shci_sem, FuriWaitForever);
|
||||
furi_hal_power_insomnia_exit();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@
|
||||
*****************************************************************************
|
||||
* @attention
|
||||
*
|
||||
* Copyright (c) 2018-2022 STMicroelectronics.
|
||||
* Copyright (c) 2018-2023 STMicroelectronics.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software is licensed under terms that can be found in the LICENSE file
|
||||
@ -18,6 +18,14 @@
|
||||
#ifndef COMPILER_H__
|
||||
#define COMPILER_H__
|
||||
|
||||
#ifndef __PACKED_STRUCT
|
||||
#define __PACKED_STRUCT PACKED(struct)
|
||||
#endif
|
||||
|
||||
#ifndef __PACKED_UNION
|
||||
#define __PACKED_UNION PACKED(union)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief This is the section dedicated to IAR toolchain
|
||||
*/
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include "gap.h"
|
||||
|
||||
#include "app_common.h"
|
||||
#include <ble/ble.h>
|
||||
|
||||
#include <furi_hal.h>
|
||||
@ -85,7 +86,7 @@ static void gap_verify_connection_parameters(Gap* gap) {
|
||||
SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
hci_event_pckt* event_pckt;
|
||||
evt_le_meta_event* meta_evt;
|
||||
evt_blue_aci* blue_evt;
|
||||
evt_blecore_aci* blue_evt;
|
||||
hci_le_phy_update_complete_event_rp0* evt_le_phy_update_complete;
|
||||
uint8_t tx_phy;
|
||||
uint8_t rx_phy;
|
||||
@ -97,7 +98,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
furi_mutex_acquire(gap->state_mutex, FuriWaitForever);
|
||||
}
|
||||
switch(event_pckt->evt) {
|
||||
case EVT_DISCONN_COMPLETE: {
|
||||
case HCI_DISCONNECTION_COMPLETE_EVT_CODE: {
|
||||
hci_disconnection_complete_event_rp0* disconnection_complete_event =
|
||||
(hci_disconnection_complete_event_rp0*)event_pckt->data;
|
||||
if(disconnection_complete_event->Connection_Handle == gap->service.connection_handle) {
|
||||
@ -106,6 +107,8 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
FURI_LOG_I(
|
||||
TAG, "Disconnect from client. Reason: %02X", disconnection_complete_event->Reason);
|
||||
}
|
||||
// Enterprise sleep
|
||||
furi_delay_us(666 + 666);
|
||||
if(gap->enable_adv) {
|
||||
// Restart advertising
|
||||
gap_advertise_start(GapStateAdvFast);
|
||||
@ -114,10 +117,10 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
gap->on_event_cb(event, gap->context);
|
||||
} break;
|
||||
|
||||
case EVT_LE_META_EVENT:
|
||||
case HCI_LE_META_EVT_CODE:
|
||||
meta_evt = (evt_le_meta_event*)event_pckt->data;
|
||||
switch(meta_evt->subevent) {
|
||||
case EVT_LE_CONN_UPDATE_COMPLETE: {
|
||||
case HCI_LE_CONNECTION_UPDATE_COMPLETE_SUBEVT_CODE: {
|
||||
hci_le_connection_update_complete_event_rp0* event =
|
||||
(hci_le_connection_update_complete_event_rp0*)meta_evt->data;
|
||||
gap->connection_params.conn_interval = event->Conn_Interval;
|
||||
@ -128,7 +131,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_LE_PHY_UPDATE_COMPLETE:
|
||||
case HCI_LE_PHY_UPDATE_COMPLETE_SUBEVT_CODE:
|
||||
evt_le_phy_update_complete = (hci_le_phy_update_complete_event_rp0*)meta_evt->data;
|
||||
if(evt_le_phy_update_complete->Status) {
|
||||
FURI_LOG_E(
|
||||
@ -144,7 +147,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
}
|
||||
break;
|
||||
|
||||
case EVT_LE_CONN_COMPLETE: {
|
||||
case HCI_LE_CONNECTION_COMPLETE_SUBEVT_CODE: {
|
||||
hci_le_connection_complete_event_rp0* event =
|
||||
(hci_le_connection_complete_event_rp0*)meta_evt->data;
|
||||
gap->connection_params.conn_interval = event->Conn_Interval;
|
||||
@ -168,16 +171,16 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
}
|
||||
break;
|
||||
|
||||
case EVT_VENDOR:
|
||||
blue_evt = (evt_blue_aci*)event_pckt->data;
|
||||
case HCI_VENDOR_SPECIFIC_DEBUG_EVT_CODE:
|
||||
blue_evt = (evt_blecore_aci*)event_pckt->data;
|
||||
switch(blue_evt->ecode) {
|
||||
aci_gap_pairing_complete_event_rp0* pairing_complete;
|
||||
|
||||
case EVT_BLUE_GAP_LIMITED_DISCOVERABLE:
|
||||
case ACI_GAP_LIMITED_DISCOVERABLE_VSEVT_CODE:
|
||||
FURI_LOG_I(TAG, "Limited discoverable event");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_PASS_KEY_REQUEST: {
|
||||
case ACI_GAP_PASS_KEY_REQ_VSEVT_CODE: {
|
||||
// Generate random PIN code
|
||||
uint32_t pin = rand() % 999999; //-V1064
|
||||
aci_gap_pass_key_resp(gap->service.connection_handle, pin);
|
||||
@ -190,7 +193,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
gap->on_event_cb(event, gap->context);
|
||||
} break;
|
||||
|
||||
case EVT_BLUE_ATT_EXCHANGE_MTU_RESP: {
|
||||
case ACI_ATT_EXCHANGE_MTU_RESP_VSEVT_CODE: {
|
||||
aci_att_exchange_mtu_resp_event_rp0* pr = (void*)blue_evt->data;
|
||||
FURI_LOG_I(TAG, "Rx MTU size: %d", pr->Server_RX_MTU);
|
||||
// Set maximum packet size given header size is 3 bytes
|
||||
@ -199,32 +202,28 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
gap->on_event_cb(event, gap->context);
|
||||
} break;
|
||||
|
||||
case EVT_BLUE_GAP_AUTHORIZATION_REQUEST:
|
||||
case ACI_GAP_AUTHORIZATION_REQ_VSEVT_CODE:
|
||||
FURI_LOG_D(TAG, "Authorization request event");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_SLAVE_SECURITY_INITIATED:
|
||||
case ACI_GAP_SLAVE_SECURITY_INITIATED_VSEVT_CODE:
|
||||
FURI_LOG_D(TAG, "Slave security initiated");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_BOND_LOST:
|
||||
case ACI_GAP_BOND_LOST_VSEVT_CODE:
|
||||
FURI_LOG_D(TAG, "Bond lost event. Start rebonding");
|
||||
aci_gap_allow_rebond(gap->service.connection_handle);
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_DEVICE_FOUND:
|
||||
FURI_LOG_D(TAG, "Device found event");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_ADDR_NOT_RESOLVED:
|
||||
case ACI_GAP_ADDR_NOT_RESOLVED_VSEVT_CODE:
|
||||
FURI_LOG_D(TAG, "Address not resolved event");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_KEYPRESS_NOTIFICATION:
|
||||
case ACI_GAP_KEYPRESS_NOTIFICATION_VSEVT_CODE:
|
||||
FURI_LOG_D(TAG, "Key press notification event");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_NUMERIC_COMPARISON_VALUE: {
|
||||
case ACI_GAP_NUMERIC_COMPARISON_VALUE_VSEVT_CODE: {
|
||||
uint32_t pin =
|
||||
((aci_gap_numeric_comparison_value_event_rp0*)(blue_evt->data))->Numeric_Value;
|
||||
FURI_LOG_I(TAG, "Verify numeric comparison: %06lu", pin);
|
||||
@ -234,7 +233,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
break;
|
||||
}
|
||||
|
||||
case EVT_BLUE_GAP_PAIRING_CMPLT:
|
||||
case ACI_GAP_PAIRING_COMPLETE_VSEVT_CODE:
|
||||
pairing_complete = (aci_gap_pairing_complete_event_rp0*)blue_evt->data;
|
||||
if(pairing_complete->Status) {
|
||||
FURI_LOG_E(
|
||||
@ -249,11 +248,11 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) {
|
||||
}
|
||||
break;
|
||||
|
||||
case EVT_BLUE_GAP_PROCEDURE_COMPLETE:
|
||||
case ACI_L2CAP_CONNECTION_UPDATE_RESP_VSEVT_CODE:
|
||||
FURI_LOG_D(TAG, "Procedure complete event");
|
||||
break;
|
||||
|
||||
case EVT_BLUE_L2CAP_CONNECTION_UPDATE_RESP: {
|
||||
case ACI_L2CAP_CONNECTION_UPDATE_REQ_VSEVT_CODE: {
|
||||
uint16_t result =
|
||||
((aci_l2cap_connection_update_resp_event_rp0*)(blue_evt->data))->Result;
|
||||
if(result == 0) {
|
||||
@ -289,8 +288,6 @@ static void gap_init_svc(Gap* gap) {
|
||||
tBleStatus status;
|
||||
uint32_t srd_bd_addr[2];
|
||||
|
||||
// HCI Reset to synchronise BLE Stack
|
||||
hci_reset();
|
||||
// Configure mac address
|
||||
aci_hal_write_config_data(
|
||||
CONFIG_DATA_PUBADDR_OFFSET, CONFIG_DATA_PUBADDR_LEN, gap->config->mac_address);
|
||||
@ -364,7 +361,7 @@ static void gap_init_svc(Gap* gap) {
|
||||
CFG_ENCRYPTION_KEY_SIZE_MAX,
|
||||
CFG_USED_FIXED_PIN,
|
||||
0,
|
||||
PUBLIC_ADDR);
|
||||
CFG_IDENTITY_ADDRESS);
|
||||
// Configure whitelist
|
||||
aci_gap_configure_whitelist();
|
||||
}
|
||||
@ -399,7 +396,7 @@ static void gap_advertise_start(GapState new_state) {
|
||||
ADV_IND,
|
||||
min_interval,
|
||||
max_interval,
|
||||
PUBLIC_ADDR,
|
||||
CFG_IDENTITY_ADDRESS,
|
||||
0,
|
||||
strlen(gap->service.adv_name),
|
||||
(uint8_t*)gap->service.adv_name,
|
||||
|
||||
@ -63,6 +63,10 @@ void furi_hal_clock_init() {
|
||||
LL_RCC_HSI_Enable();
|
||||
while(!HS_CLOCK_IS_READY())
|
||||
;
|
||||
/* Select HSI as system clock source after Wake Up from Stop mode
|
||||
* Must be set before enabling CSS */
|
||||
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
|
||||
|
||||
LL_RCC_HSE_EnableCSS();
|
||||
|
||||
/* LSE and LSI1 configuration and activation */
|
||||
@ -215,11 +219,14 @@ void furi_hal_clock_switch_to_hsi() {
|
||||
void furi_hal_clock_switch_to_pll() {
|
||||
LL_RCC_HSE_Enable();
|
||||
LL_RCC_PLL_Enable();
|
||||
LL_RCC_PLLSAI1_Enable();
|
||||
|
||||
while(!LL_RCC_HSE_IsReady())
|
||||
;
|
||||
while(!LL_RCC_PLL_IsReady())
|
||||
;
|
||||
while(!LL_RCC_PLLSAI1_IsReady())
|
||||
;
|
||||
|
||||
LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
|
||||
|
||||
@ -296,4 +303,4 @@ void furi_hal_clock_mco_disable() {
|
||||
LL_RCC_MSI_Disable();
|
||||
while(LL_RCC_MSI_IsReady() != 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,12 +3,26 @@
|
||||
#include <stm32wbxx_ll_exti.h>
|
||||
#include <stm32wbxx_ll_system.h>
|
||||
|
||||
#include <furi_hal_gpio.h>
|
||||
#include <furi_hal_resources.h>
|
||||
|
||||
volatile bool furi_hal_debug_gdb_session_active = false;
|
||||
|
||||
void furi_hal_debug_enable() {
|
||||
// Low power mode debug
|
||||
LL_DBGMCU_EnableDBGSleepMode();
|
||||
LL_DBGMCU_EnableDBGStopMode();
|
||||
LL_DBGMCU_EnableDBGStandbyMode();
|
||||
LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48);
|
||||
// SWD GPIO
|
||||
furi_hal_gpio_init_ex(
|
||||
&gpio_swdio,
|
||||
GpioModeAltFunctionPushPull,
|
||||
GpioPullUp,
|
||||
GpioSpeedVeryHigh,
|
||||
GpioAltFn0JTMS_SWDIO);
|
||||
furi_hal_gpio_init_ex(
|
||||
&gpio_swclk, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn0JTCK_SWCLK);
|
||||
}
|
||||
|
||||
void furi_hal_debug_disable() {
|
||||
@ -17,4 +31,11 @@ void furi_hal_debug_disable() {
|
||||
LL_DBGMCU_DisableDBGStopMode();
|
||||
LL_DBGMCU_DisableDBGStandbyMode();
|
||||
LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
|
||||
// SWD GPIO
|
||||
furi_hal_gpio_init_simple(&gpio_swdio, GpioModeAnalog);
|
||||
furi_hal_gpio_init_simple(&gpio_swclk, GpioModeAnalog);
|
||||
}
|
||||
|
||||
bool furi_hal_debug_is_gdb_session_active() {
|
||||
return furi_hal_debug_gdb_session_active;
|
||||
}
|
||||
@ -1,5 +1,6 @@
|
||||
#include <furi_hal_flash.h>
|
||||
#include <furi_hal_bt.h>
|
||||
#include <furi_hal_power.h>
|
||||
#include <furi.h>
|
||||
#include <ble/ble.h>
|
||||
#include <interface/patterns/ble_thread/shci/shci.h>
|
||||
@ -114,6 +115,7 @@ static void furi_hal_flash_lock(void) {
|
||||
}
|
||||
|
||||
static void furi_hal_flash_begin_with_core2(bool erase_flag) {
|
||||
furi_hal_power_insomnia_enter();
|
||||
/* Take flash controller ownership */
|
||||
while(LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID) != 0) {
|
||||
furi_thread_yield();
|
||||
@ -188,6 +190,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) {
|
||||
|
||||
/* Release flash controller ownership */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0);
|
||||
furi_hal_power_insomnia_exit();
|
||||
}
|
||||
|
||||
static void furi_hal_flash_end(bool erase_flag) {
|
||||
|
||||
@ -28,11 +28,24 @@
|
||||
// Arbitrary (but small) number for better tick consistency
|
||||
#define FURI_HAL_OS_EXTRA_CNT 3
|
||||
|
||||
#ifndef FURI_HAL_OS_DEBUG_AWAKE_GPIO
|
||||
#define FURI_HAL_OS_DEBUG_AWAKE_GPIO (&gpio_ext_pa7)
|
||||
#endif
|
||||
|
||||
#ifndef FURI_HAL_OS_DEBUG_TICK_GPIO
|
||||
#define FURI_HAL_OS_DEBUG_TICK_GPIO (&gpio_ext_pa6)
|
||||
#endif
|
||||
|
||||
#ifndef FURI_HAL_OS_DEBUG_SECOND_GPIO
|
||||
#define FURI_HAL_OS_DEBUG_SECOND_GPIO (&gpio_ext_pa4)
|
||||
#endif
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
#include <stm32wbxx_ll_gpio.h>
|
||||
|
||||
void furi_hal_os_timer_callback() {
|
||||
furi_hal_gpio_write(&gpio_ext_pa4, !furi_hal_gpio_read(&gpio_ext_pa4));
|
||||
furi_hal_gpio_write(
|
||||
FURI_HAL_OS_DEBUG_SECOND_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_SECOND_GPIO));
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -44,9 +57,11 @@ void furi_hal_os_init() {
|
||||
furi_hal_idle_timer_init();
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa6, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_AWAKE_GPIO, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_TICK_GPIO, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_SECOND_GPIO, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1);
|
||||
|
||||
FuriTimer* second_timer =
|
||||
furi_timer_alloc(furi_hal_os_timer_callback, FuriTimerTypePeriodic, NULL);
|
||||
furi_timer_start(second_timer, FURI_HAL_OS_TICK_HZ);
|
||||
@ -58,7 +73,8 @@ void furi_hal_os_init() {
|
||||
void furi_hal_os_tick() {
|
||||
if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pa6, !furi_hal_gpio_read(&gpio_ext_pa6));
|
||||
furi_hal_gpio_write(
|
||||
FURI_HAL_OS_DEBUG_TICK_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_TICK_GPIO));
|
||||
#endif
|
||||
xPortSysTickHandler();
|
||||
}
|
||||
@ -121,14 +137,14 @@ static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) {
|
||||
furi_hal_idle_timer_start(FURI_HAL_OS_TICKS_TO_IDLE_CNT(expected_idle_ticks));
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pa7, 0);
|
||||
furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 0);
|
||||
#endif
|
||||
|
||||
// Go to sleep mode
|
||||
furi_hal_power_sleep();
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pa7, 1);
|
||||
furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1);
|
||||
#endif
|
||||
|
||||
// Calculate how much time we spent in the sleep
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
#include <furi_hal_vibro.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_uart.h>
|
||||
#include <furi_hal_rtc.h>
|
||||
#include <furi_hal_debug.h>
|
||||
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_pwr.h>
|
||||
@ -19,15 +21,24 @@
|
||||
|
||||
#define TAG "FuriHalPower"
|
||||
|
||||
#ifdef FURI_HAL_POWER_DEEP_SLEEP_ENABLED
|
||||
#define FURI_HAL_POWER_DEEP_INSOMNIA 0
|
||||
#else
|
||||
#define FURI_HAL_POWER_DEEP_INSOMNIA 1
|
||||
#ifndef FURI_HAL_POWER_DEBUG_WFI_GPIO
|
||||
#define FURI_HAL_POWER_DEBUG_WFI_GPIO (&gpio_ext_pb2)
|
||||
#endif
|
||||
|
||||
#ifndef FURI_HAL_POWER_DEBUG_STOP_GPIO
|
||||
#define FURI_HAL_POWER_DEBUG_STOP_GPIO (&gpio_ext_pc3)
|
||||
#endif
|
||||
|
||||
#ifndef FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO
|
||||
#define FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO (&gpio_ext_pb3)
|
||||
#endif
|
||||
|
||||
#ifndef FURI_HAL_POWER_STOP_MODE
|
||||
#define FURI_HAL_POWER_STOP_MODE (LL_PWR_MODE_STOP2)
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
volatile uint8_t insomnia;
|
||||
volatile uint8_t deep_insomnia;
|
||||
volatile uint8_t suppress_charge;
|
||||
|
||||
uint8_t gauge_initialized;
|
||||
@ -36,7 +47,6 @@ typedef struct {
|
||||
|
||||
static volatile FuriHalPower furi_hal_power = {
|
||||
.insomnia = 0,
|
||||
.deep_insomnia = FURI_HAL_POWER_DEEP_INSOMNIA,
|
||||
.suppress_charge = 0,
|
||||
};
|
||||
|
||||
@ -79,19 +89,25 @@ const ParamCEDV cedv = {
|
||||
};
|
||||
|
||||
void furi_hal_power_init() {
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_WFI_GPIO, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_STOP_GPIO, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0);
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0);
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, 0);
|
||||
#endif
|
||||
|
||||
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
|
||||
LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN);
|
||||
LL_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);
|
||||
LL_C2_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);
|
||||
|
||||
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
|
||||
bq27220_init(&furi_hal_i2c_handle_power, &cedv);
|
||||
bq25896_init(&furi_hal_i2c_handle_power);
|
||||
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pb2, GpioModeOutputPushPull);
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull);
|
||||
#endif
|
||||
|
||||
FURI_LOG_I(TAG, "Init OK");
|
||||
}
|
||||
|
||||
@ -140,11 +156,14 @@ bool furi_hal_power_sleep_available() {
|
||||
return furi_hal_power.insomnia == 0;
|
||||
}
|
||||
|
||||
bool furi_hal_power_deep_sleep_available() {
|
||||
return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0;
|
||||
static inline bool furi_hal_power_deep_sleep_available() {
|
||||
return furi_hal_bt_is_alive() && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) &&
|
||||
!furi_hal_debug_is_gdb_session_active() && !LL_PWR_IsActiveFlag_CRPE() &&
|
||||
!LL_PWR_IsActiveFlag_CRP() && !LL_PWR_IsActiveFlag_BLEA() &&
|
||||
!LL_PWR_IsActiveFlag_BLEWU();
|
||||
}
|
||||
|
||||
void furi_hal_power_light_sleep() {
|
||||
static inline void furi_hal_power_light_sleep() {
|
||||
__WFI();
|
||||
}
|
||||
|
||||
@ -152,17 +171,15 @@ static inline void furi_hal_power_suspend_aux_periphs() {
|
||||
// Disable USART
|
||||
furi_hal_uart_suspend(FuriHalUartIdUSART1);
|
||||
furi_hal_uart_suspend(FuriHalUartIdLPUART1);
|
||||
// TODO: Disable USB
|
||||
}
|
||||
|
||||
static inline void furi_hal_power_resume_aux_periphs() {
|
||||
// Re-enable USART
|
||||
furi_hal_uart_resume(FuriHalUartIdUSART1);
|
||||
furi_hal_uart_resume(FuriHalUartIdLPUART1);
|
||||
// TODO: Re-enable USB
|
||||
}
|
||||
|
||||
void furi_hal_power_deep_sleep() {
|
||||
static inline void furi_hal_power_deep_sleep() {
|
||||
furi_hal_power_suspend_aux_periphs();
|
||||
|
||||
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID))
|
||||
@ -187,8 +204,6 @@ void furi_hal_power_deep_sleep() {
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
|
||||
// Prepare deep sleep
|
||||
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
|
||||
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
|
||||
LL_LPM_EnableDeepSleep();
|
||||
|
||||
#if defined(__CC_ARM)
|
||||
@ -196,17 +211,19 @@ void furi_hal_power_deep_sleep() {
|
||||
__force_stores();
|
||||
#endif
|
||||
|
||||
__WFI();
|
||||
bool should_abort_sleep = LL_PWR_IsActiveFlag_CRPE() || LL_PWR_IsActiveFlag_CRP() ||
|
||||
LL_PWR_IsActiveFlag_BLEA() || LL_PWR_IsActiveFlag_BLEWU();
|
||||
|
||||
if(should_abort_sleep) {
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, 1);
|
||||
#endif
|
||||
} else {
|
||||
__WFI();
|
||||
}
|
||||
|
||||
LL_LPM_EnableSleep();
|
||||
|
||||
// Make sure that values differ to prevent disaster on wfi
|
||||
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0);
|
||||
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN);
|
||||
|
||||
LL_PWR_ClearFlag_C1STOP_C1STB();
|
||||
LL_PWR_ClearFlag_C2STOP_C2STB();
|
||||
|
||||
/* Release ENTRY_STOP_MODE semaphore */
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0);
|
||||
|
||||
@ -220,28 +237,25 @@ void furi_hal_power_deep_sleep() {
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
|
||||
|
||||
furi_hal_power_resume_aux_periphs();
|
||||
furi_hal_rtc_sync_shadow();
|
||||
}
|
||||
|
||||
void furi_hal_power_sleep() {
|
||||
if(furi_hal_power_deep_sleep_available()) {
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pc3, 1);
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 1);
|
||||
#endif
|
||||
|
||||
furi_hal_power_deep_sleep();
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pc3, 0);
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0);
|
||||
#endif
|
||||
} else {
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pb2, 1);
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 1);
|
||||
#endif
|
||||
|
||||
furi_hal_power_light_sleep();
|
||||
|
||||
#ifdef FURI_HAL_OS_DEBUG
|
||||
furi_hal_gpio_write(&gpio_ext_pb2, 0);
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,19 +9,35 @@
|
||||
|
||||
#define TAG "FuriHalRandom"
|
||||
|
||||
static uint32_t furi_hal_random_read_rng() {
|
||||
while(LL_RNG_IsActiveFlag_CECS(RNG) && LL_RNG_IsActiveFlag_SECS(RNG) &&
|
||||
!LL_RNG_IsActiveFlag_DRDY(RNG)) {
|
||||
/* Error handling as described in RM0434, pg. 582-583 */
|
||||
if(LL_RNG_IsActiveFlag_CECS(RNG)) {
|
||||
/* Clock error occurred */
|
||||
LL_RNG_ClearFlag_CEIS(RNG);
|
||||
}
|
||||
|
||||
if(LL_RNG_IsActiveFlag_SECS(RNG)) {
|
||||
/* Noise source error occurred */
|
||||
LL_RNG_ClearFlag_SEIS(RNG);
|
||||
|
||||
for(uint32_t i = 0; i < 12; ++i) {
|
||||
const volatile uint32_t discard = LL_RNG_ReadRandData32(RNG);
|
||||
UNUSED(discard);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LL_RNG_ReadRandData32(RNG);
|
||||
}
|
||||
|
||||
uint32_t furi_hal_random_get() {
|
||||
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID))
|
||||
;
|
||||
LL_RNG_Enable(RNG);
|
||||
|
||||
while(!LL_RNG_IsActiveFlag_DRDY(RNG))
|
||||
;
|
||||
|
||||
if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) {
|
||||
furi_crash("TRNG error");
|
||||
}
|
||||
|
||||
uint32_t random_val = LL_RNG_ReadRandData32(RNG);
|
||||
const uint32_t random_val = furi_hal_random_read_rng();
|
||||
|
||||
LL_RNG_Disable(RNG);
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
|
||||
@ -35,15 +51,7 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) {
|
||||
LL_RNG_Enable(RNG);
|
||||
|
||||
for(uint32_t i = 0; i < len; i += 4) {
|
||||
while(!LL_RNG_IsActiveFlag_DRDY(RNG))
|
||||
;
|
||||
|
||||
if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) {
|
||||
furi_crash("TRNG error");
|
||||
}
|
||||
|
||||
uint32_t random_val = LL_RNG_ReadRandData32(RNG);
|
||||
|
||||
const uint32_t random_val = furi_hal_random_read_rng();
|
||||
uint8_t len_cur = ((i + 4) < len) ? (4) : (len - i);
|
||||
memcpy(&buf[i], &random_val, len_cur);
|
||||
}
|
||||
|
||||
@ -6,6 +6,9 @@
|
||||
|
||||
#define TAG "FuriHalResources"
|
||||
|
||||
const GpioPin gpio_swdio = {.port = GPIOA, .pin = LL_GPIO_PIN_13};
|
||||
const GpioPin gpio_swclk = {.port = GPIOA, .pin = LL_GPIO_PIN_14};
|
||||
|
||||
const GpioPin gpio_vibro = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin};
|
||||
const GpioPin gpio_ibutton = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin};
|
||||
|
||||
@ -153,10 +156,11 @@ void furi_hal_resources_init() {
|
||||
// Button pins
|
||||
furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall);
|
||||
|
||||
// Explicit pulls pins
|
||||
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||
furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||
// Explicit, surviving reset, pulls
|
||||
LL_PWR_EnablePUPDCfg();
|
||||
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_9); // gpio_infrared_tx
|
||||
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker
|
||||
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro
|
||||
|
||||
// Display pins
|
||||
furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||
|
||||
@ -50,6 +50,9 @@ extern const size_t input_pins_count;
|
||||
extern const GpioPinRecord gpio_pins[];
|
||||
extern const size_t gpio_pins_count;
|
||||
|
||||
extern const GpioPin gpio_swdio;
|
||||
extern const GpioPin gpio_swclk;
|
||||
|
||||
extern const GpioPin gpio_vibro;
|
||||
extern const GpioPin gpio_ibutton;
|
||||
|
||||
|
||||
@ -165,6 +165,14 @@ void furi_hal_rtc_init() {
|
||||
FURI_LOG_I(TAG, "Init OK");
|
||||
}
|
||||
|
||||
void furi_hal_rtc_sync_shadow() {
|
||||
if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) {
|
||||
LL_RTC_ClearFlag_RS(RTC);
|
||||
while(!LL_RTC_IsActiveFlag_RS(RTC)) {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t furi_hal_rtc_get_register(FuriHalRtcRegister reg) {
|
||||
return LL_RTC_BAK_GetRegister(RTC, reg);
|
||||
}
|
||||
@ -312,12 +320,7 @@ void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) {
|
||||
/* Exit Initialization mode */
|
||||
LL_RTC_DisableInitMode(RTC);
|
||||
|
||||
/* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
|
||||
if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) {
|
||||
LL_RTC_ClearFlag_RS(RTC);
|
||||
while(!LL_RTC_IsActiveFlag_RS(RTC)) {
|
||||
};
|
||||
}
|
||||
furi_hal_rtc_sync_shadow();
|
||||
|
||||
/* Enable write protection */
|
||||
LL_RTC_EnableWriteProtection(RTC);
|
||||
|
||||
@ -29,6 +29,8 @@ int main() {
|
||||
FuriThread* main_thread = furi_thread_alloc_ex("Init", 4096, init_task, NULL);
|
||||
|
||||
#ifdef FURI_RAM_EXEC
|
||||
// Prevent entering sleep mode when executed from RAM
|
||||
furi_hal_power_insomnia_enter();
|
||||
furi_thread_start(main_thread);
|
||||
#else
|
||||
furi_hal_light_sequence("RGB");
|
||||
@ -44,6 +46,7 @@ int main() {
|
||||
furi_hal_power_reset();
|
||||
} else if(boot_mode == FuriHalRtcBootModeUpdate) {
|
||||
furi_hal_light_sequence("rgb BR");
|
||||
// Do update
|
||||
flipper_boot_update_exec();
|
||||
// if things go nice, we shouldn't reach this point.
|
||||
// But if we do, abandon to avoid bootloops
|
||||
|
||||
@ -18,6 +18,9 @@ void furi_hal_debug_enable();
|
||||
/** Disable MCU debug */
|
||||
void furi_hal_debug_disable();
|
||||
|
||||
/** Check if GDB debug session is active */
|
||||
bool furi_hal_debug_is_gdb_session_active();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -58,12 +58,6 @@ void furi_hal_power_insomnia_exit();
|
||||
*/
|
||||
bool furi_hal_power_sleep_available();
|
||||
|
||||
/** Check if deep sleep availble
|
||||
*
|
||||
* @return true if available
|
||||
*/
|
||||
bool furi_hal_power_deep_sleep_available();
|
||||
|
||||
/** Go to sleep
|
||||
*/
|
||||
void furi_hal_power_sleep();
|
||||
|
||||
@ -30,6 +30,8 @@ typedef enum {
|
||||
FuriHalRtcFlagLock = (1 << 2),
|
||||
FuriHalRtcFlagC2Update = (1 << 3),
|
||||
FuriHalRtcFlagHandOrient = (1 << 4),
|
||||
FuriHalRtcFlagLegacySleep = (1 << 5),
|
||||
FuriHalRtcFlagStealthMode = (1 << 6),
|
||||
} FuriHalRtcFlag;
|
||||
|
||||
typedef enum {
|
||||
@ -85,6 +87,9 @@ void furi_hal_rtc_deinit_early();
|
||||
/** Initialize RTC subsystem */
|
||||
void furi_hal_rtc_init();
|
||||
|
||||
/** Force sync shadow registers */
|
||||
void furi_hal_rtc_sync_shadow();
|
||||
|
||||
/** Get RTC register content
|
||||
*
|
||||
* @param[in] reg The register identifier
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
#include <furi_hal_console.h>
|
||||
#include <furi_hal_power.h>
|
||||
#include <furi_hal_rtc.h>
|
||||
#include <furi_hal_debug.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <FreeRTOS.h>
|
||||
@ -117,6 +118,8 @@ FURI_NORETURN void __furi_crash() {
|
||||
if(debug) {
|
||||
furi_hal_console_puts("\r\nSystem halted. Connect debugger for more info\r\n");
|
||||
furi_hal_console_puts("\033[0m\r\n");
|
||||
furi_hal_debug_enable();
|
||||
|
||||
RESTORE_REGISTERS_AND_HALT_MCU(true);
|
||||
} else {
|
||||
furi_hal_rtc_set_fault_data((uint32_t)__furi_check_message);
|
||||
|
||||
@ -24,6 +24,10 @@ extern "C" {
|
||||
})
|
||||
#endif
|
||||
|
||||
#ifndef ABS
|
||||
#define ABS(a) ({ (a) < 0 ? -(a) : (a); })
|
||||
#endif
|
||||
|
||||
#ifndef ROUND_UP_TO
|
||||
#define ROUND_UP_TO(a, b) \
|
||||
({ \
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit a9e29b431f6dac95b6fc860a717834f35b7f78e5
|
||||
Subproject commit 06b8133fa295474507b55b1a5695d4b8bf804ed6
|
||||
@ -14,7 +14,7 @@ IWDGSTOP:0x1:rw
|
||||
IWDGSW:0x1:rw
|
||||
IPCCDBA:0x0:rw
|
||||
ESE:0x1:r
|
||||
SFSA:0xD7:r
|
||||
SFSA:0xD5:r
|
||||
FSD:0x0:r
|
||||
DDS:0x1:r
|
||||
C2OPT:0x1:r
|
||||
@ -22,7 +22,7 @@ NBRSD:0x0:r
|
||||
SNBRSA:0xD:r
|
||||
BRSD:0x0:r
|
||||
SBRSA:0x12:r
|
||||
SBRV:0x35C00:r
|
||||
SBRV:0x35400:r
|
||||
PCROP1A_STRT:0x1FF:r
|
||||
PCROP1A_END:0x0:r
|
||||
PCROP_RDP:0x1:rw
|
||||
|
||||
@ -1,6 +1,8 @@
|
||||
from SCons.Platform import TempFileMunge
|
||||
from SCons.Node import FS
|
||||
from SCons.Errors import UserError
|
||||
from SCons.Warnings import warn, WarningOnByDefault
|
||||
|
||||
|
||||
import os
|
||||
import multiprocessing
|
||||
@ -246,7 +248,12 @@ known_extapps = [
|
||||
for apptype in apps_to_build_as_faps
|
||||
for app in appenv["APPBUILD"].get_apps_of_type(apptype, True)
|
||||
]
|
||||
incompatible_apps = []
|
||||
for app in known_extapps:
|
||||
if not app.supports_hardware_target(appenv.subst("f${TARGET_HW}")):
|
||||
incompatible_apps.append(app)
|
||||
continue
|
||||
|
||||
app_artifacts = appenv.BuildAppElf(app)
|
||||
app_src_dir = extract_abs_dir(app_artifacts.app._appdir)
|
||||
app_artifacts.installer = [
|
||||
@ -254,6 +261,13 @@ for app in known_extapps:
|
||||
appenv.Install(app_src_dir.Dir("dist").Dir("debug"), app_artifacts.debug),
|
||||
]
|
||||
|
||||
if len(incompatible_apps):
|
||||
print(
|
||||
"WARNING: The following apps are not compatible with the current target hardware and will not be built: {}".format(
|
||||
", ".join([app.name for app in incompatible_apps])
|
||||
)
|
||||
)
|
||||
|
||||
if appenv["FORCE"]:
|
||||
appenv.AlwaysBuild([extapp.compact for extapp in apps_artifacts.values()])
|
||||
|
||||
|
||||
@ -36,6 +36,7 @@ ENV.AppendUnique(
|
||||
],
|
||||
CPPDEFINES=[
|
||||
"_GNU_SOURCE",
|
||||
*GetOption("extra_defines"),
|
||||
],
|
||||
LINKFLAGS=[
|
||||
"-mcpu=cortex-m4",
|
||||
|
||||
@ -26,6 +26,14 @@ AddOption(
|
||||
help="List of applications to add to firmware's built-ins. Also see FIRMWARE_APP_SET and FIRMWARE_APPS",
|
||||
)
|
||||
|
||||
AddOption(
|
||||
"--extra-define",
|
||||
action="append",
|
||||
dest="extra_defines",
|
||||
default=[],
|
||||
help="Extra global define that will be passed to C/C++ compiler, can be specified multiple times",
|
||||
)
|
||||
|
||||
AddOption(
|
||||
"--extra-ext-apps",
|
||||
action="store",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user