Merge branch 'dev' into astra/3746-mfp-detect

This commit is contained in:
Astra 2024-04-23 10:39:34 +09:00 committed by GitHub
commit 85fc0a2dd3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
1001 changed files with 15407 additions and 6205 deletions

View file

@ -129,7 +129,7 @@ jobs:
- name: 'Find previous comment'
if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET && github.event.pull_request }}
uses: peter-evans/find-comment@v2
uses: peter-evans/find-comment@v3
id: find-comment
with:
issue-number: ${{ github.event.pull_request.number }}
@ -138,7 +138,7 @@ jobs:
- name: 'Create or update comment'
if: ${{ !github.event.pull_request.head.repo.fork && matrix.target == env.DEFAULT_TARGET && github.event.pull_request }}
uses: peter-evans/create-or-update-comment@v3
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
@ -147,6 +147,7 @@ jobs:
- [📦 Update package](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz)
- [📥 DFU file](https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-full-${{steps.names.outputs.suffix}}.dfu)
- [☁️ Web/App updater](https://lab.flipper.net/?url=https://update.flipperzero.one/builds/firmware/${{steps.names.outputs.branch_name}}/flipper-z-${{steps.names.outputs.default_target}}-update-${{steps.names.outputs.suffix}}.tgz&channel=${{steps.names.outputs.branch_name}}&version=${{steps.names.outputs.commit_sha}})
- [📊 Size report](https://fw-reports.flipp.dev/?branch=${{steps.names.outputs.branch_name}})
edit-mode: replace
- name: 'SDK submission to staging catalog'

78
.github/workflows/docs.yml vendored Normal file
View file

@ -0,0 +1,78 @@
name: 'Generate documentation with Doxygen'
on:
push:
branches:
- dev
pull_request:
env:
TARGETS: f7
DEFAULT_TARGET: f7
jobs:
check-secret:
if: ${{ github.event.pull_request.head.repo.fork == false }}
runs-on: ubuntu-latest
outputs:
s3-valid-config: ${{ steps.check.outputs.s3-valid-config }}
steps:
- name: 'Check if S3 key exists'
id: check
run: |
if [[ -z "${{ secrets.FW_DOCS_AWS_ACCESS_KEY }}" || -z "${{ secrets.FW_DOCS_AWS_SECRET_KEY }}" || -z "${{ secrets.FW_DOCS_AWS_BUCKET }}" ]]; then
echo "s3-valid-config=false" >> $GITHUB_OUTPUT;
else
echo "s3-valid-config=true" >> $GITHUB_OUTPUT;
fi
doxygen:
if: ${{ github.event.pull_request.head.repo.fork == false }}
runs-on: ubuntu-latest
needs: check-secret
steps:
- name: 'Wipe workspace'
run: find ./ -mount -maxdepth 1 -exec rm -rf {} \;
- name: 'Checkout code'
uses: actions/checkout@v4
with:
submodules: true
fetch-depth: 1
ref: ${{ github.event.pull_request.head.sha }}
- name: 'Get commit details'
id: names
run: |
if [[ ${{ github.event_name }} == 'pull_request' ]]; then
TYPE="pull"
elif [[ "${{ github.ref }}" == "refs/tags/"* ]]; then
TYPE="tag"
else
TYPE="other"
fi
python3 scripts/get_env.py "--event_file=${{ github.event_path }}" "--type=$TYPE"
- name: 'Generate documentation'
uses: mattnotmitt/doxygen-action@edge
env:
DOXY_SRC_ROOT: "${{ github.workspace }}"
DOXY_CONFIG_DIR: "${{ github.workspace }}/documentation/doxygen"
DOXY_OUTPUT_DIR: "${{ github.workspace }}/documentation/doxygen/build"
with:
working-directory: 'documentation/'
doxyfile-path: './doxygen/Doxyfile-awesome.cfg'
- name: 'Upload documentation'
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/dev' && needs.check-secret.outputs.s3-valid-config == 'true' }}
uses: jakejarvis/s3-sync-action@v0.5.1
env:
AWS_S3_BUCKET: "${{ secrets.FW_DOCS_AWS_BUCKET }}"
AWS_ACCESS_KEY_ID: "${{ secrets.FW_DOCS_AWS_ACCESS_KEY }}"
AWS_SECRET_ACCESS_KEY: "${{ secrets.FW_DOCS_AWS_SECRET_KEY }}"
AWS_REGION: "${{ secrets.FW_DOCS_AWS_REGION }}"
SOURCE_DIR: "./documentation/doxygen/build/html"
DEST_DIR: "${{steps.names.outputs.branch_name}}"
with:
args: "--delete"

View file

@ -48,6 +48,9 @@ jobs:
WARNINGS=0
./fbt COMPACT=1 PVSNOBROWSER=1 firmware_pvs || WARNINGS=1
echo "warnings=${WARNINGS}" >> $GITHUB_OUTPUT
if [[ $WARNINGS -ne 0 ]]; then
echo "report-url=https://pvs.flipp.dev/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/index.html" >> $GITHUB_OUTPUT
fi
- name: 'Upload report'
if: ${{ !github.event.pull_request.head.repo.fork && (steps.pvs-warn.outputs.warnings != 0) }}
@ -62,7 +65,7 @@ jobs:
- name: 'Find Previous Comment'
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request && (steps.pvs-warn.outputs.warnings != 0) }}
uses: peter-evans/find-comment@v2
uses: peter-evans/find-comment@v3
id: fc
with:
issue-number: ${{ github.event.pull_request.number }}
@ -71,18 +74,19 @@ jobs:
- name: 'Create or update comment'
if: ${{ !github.event.pull_request.head.repo.fork && github.event.pull_request && (steps.pvs-warn.outputs.warnings != 0) }}
uses: peter-evans/create-or-update-comment@v1
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.fc.outputs.comment-id }}
issue-number: ${{ github.event.pull_request.number }}
body: |
**PVS-Studio report for commit `${{steps.names.outputs.commit_sha}}`:**
- [Report](https://pvs.flipp.dev/${{steps.names.outputs.branch_name}}/${{steps.names.outputs.default_target}}-${{steps.names.outputs.suffix}}/index.html)
- [Report](${{ steps.pvs-warn.outputs.report-url }})
edit-mode: replace
- name: 'Raise exception'
if: ${{ steps.pvs-warn.outputs.warnings != 0 }}
run: |
echo "Please fix all PVS warnings before merge"
echo "Report: ${{ steps.pvs-warn.outputs.report-url }}"
echo "[PVS report](${{ steps.pvs-warn.outputs.report-url }})" >> $GITHUB_STEP_SUMMARY
exit 1

5
.gitmodules vendored
View file

@ -37,4 +37,7 @@
url = https://github.com/STMicroelectronics/stm32wbxx_hal_driver
[submodule "lib/stm32wb_copro"]
path = lib/stm32wb_copro
url = https://github.com/flipperdevices/stm32wb_copro.git
url = https://github.com/flipperdevices/stm32wb_copro.git
[submodule "documentation/doxygen/doxygen-awesome-css"]
path = documentation/doxygen/doxygen-awesome-css
url = https://github.com/jothepro/doxygen-awesome-css.git

View file

@ -1,10 +1,10 @@
# MLib macros we can't do much about.
//-V:M_LET:1048,1044
//-V:M_EACH:1048,1044
//-V:ARRAY_DEF:760,747,568,776,729,712,654
//-V:LIST_DEF:760,747,568,712,729,654,776
//-V:ARRAY_DEF:760,747,568,776,729,712,654,1103
//-V:LIST_DEF:760,747,568,712,729,654,776,1103
//-V:BPTREE_DEF2:779,1086,557,773,512
//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685
//-V:DICT_DEF2:779,524,776,760,1044,1001,729,590,568,747,685,1103
//-V:ALGO_DEF:1048,747,1044
//-V:TUPLE_DEF2:524,590,1001,760
@ -42,8 +42,5 @@
# Model-related warnings
//-V:with_view_model:1044,1048
# Functions that always return the same error code
//-V:picopass_device_decrypt:1048
# Examples
//V_EXCLUDE_PATH applications/examples/

2
.vscode/ReadMe.md vendored
View file

@ -1,4 +1,4 @@
# Visual Studio Code workspace for Flipper Zero
# Visual Studio Code workspace for Flipper Zero {#vscode}
## Setup

View file

@ -5,27 +5,24 @@
"compilerPath": "${workspaceFolder}/toolchain/x86_64-windows/bin/arm-none-eabi-gcc.exe",
"intelliSenseMode": "gcc-arm",
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
"configurationProvider": "ms-vscode.cpptools",
"cStandard": "gnu17",
"cppStandard": "c++17"
"cStandard": "gnu23",
"cppStandard": "c++20"
},
{
"name": "Linux",
"compilerPath": "${workspaceFolder}/toolchain/x86_64-linux/bin/arm-none-eabi-gcc",
"intelliSenseMode": "gcc-arm",
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
"configurationProvider": "ms-vscode.cpptools",
"cStandard": "gnu17",
"cppStandard": "c++17"
"cStandard": "gnu23",
"cppStandard": "c++20"
},
{
"name": "Mac",
"compilerPath": "${workspaceFolder}/toolchain/x86_64-darwin/bin/arm-none-eabi-gcc",
"intelliSenseMode": "gcc-arm",
"compileCommands": "${workspaceFolder}/build/latest/compile_commands.json",
"configurationProvider": "ms-vscode.cpptools",
"cStandard": "gnu17",
"cppStandard": "c++17"
"cStandard": "gnu23",
"cppStandard": "c++20"
}
],
"version": 4

View file

@ -1,6 +1,6 @@
{
"C_Cpp.default.cStandard": "gnu17",
"C_Cpp.default.cppStandard": "c++17",
"C_Cpp.default.cStandard": "gnu23",
"C_Cpp.default.cppStandard": "c++20",
"python.formatting.provider": "black",
"workbench.tree.indent": 12,
"cortex-debug.enableTelemetry": false,
@ -14,7 +14,7 @@
"*.scons": "python",
"SConscript": "python",
"SConstruct": "python",
"*.fam": "python",
"*.fam": "python"
},
"clangd.arguments": [
// We might be able to tighten this a bit more to only include the correct toolchain.

View file

@ -11,6 +11,7 @@
- [Flipper Zero Official Website](https://flipperzero.one). A simple way to explain to your friends what Flipper Zero can do.
- [Flipper Zero Firmware Update](https://update.flipperzero.one). Improvements for your dolphin: latest firmware releases, upgrade tools for PC and mobile devices.
- [User Documentation](https://docs.flipperzero.one). Learn more about your dolphin: specs, usage guides, and anything you want to ask.
- [Developer Documentation](https://developer.flipper.net/flipperzero/doxygen). Dive into the Flipper Zero Firmware source code: build system, firmware structure, and more.
# Contributing
@ -18,7 +19,7 @@ Our main goal is to build a healthy and sustainable community around Flipper, so
## I need help
The best place to search for answers is our [User Documentation](https://docs.flipperzero.one). If you can't find the answer there, check our [Discord Server](https://flipp.dev/discord) or our [Forum](https://forum.flipperzero.one/).
The best place to search for answers is our [User Documentation](https://docs.flipperzero.one). If you can't find the answer there, check our [Discord Server](https://flipp.dev/discord) or our [Forum](https://forum.flipperzero.one/). If you want to contribute to the firmware development, or modify it for your own needs, you can also check our [Developer Documentation](https://developer.flipper.net/flipperzero/doxygen).
## I want to report an issue
@ -95,7 +96,8 @@ Make sure your Flipper is on, and your firmware is functioning. Connect your Fli
- [Hardware combos and Un-bricking](/documentation/KeyCombo.md) - recovering your Flipper from the most nasty situations
- [Flipper File Formats](/documentation/file_formats) - everything about how Flipper stores your data and how you can work with it
- [Universal Remotes](/documentation/UniversalRemotes.md) - contributing your infrared remote to the universal remote database
- And much more in the [documentation](/documentation) folder
- [Firmware Roadmap](/documentation/RoadMap.md)
- And much more in the [Developer Documentation](https://developer.flipper.net/flipperzero/doxygen)
# Project structure

View file

@ -7,7 +7,7 @@
# construction of certain targets behind command-line options.
import os
from fbt.util import path_as_posix
from fbt.util import open_browser_action
DefaultEnvironment(tools=[])
@ -42,6 +42,7 @@ distenv = coreenv.Clone(
"openocd",
"blackmagic",
"jflash",
"doxygen",
],
ENV=os.environ,
UPDATE_BUNDLE_DIR="dist/${DIST_DIR}/f${TARGET_HW}-update-${DIST_SUFFIX}",
@ -66,6 +67,7 @@ if GetOption("fullenv") or any(
# Target for self-update package
dist_basic_arguments = [
"${ARGS}",
"--bundlever",
"${UPDATE_VERSION_STRING}",
]
@ -182,6 +184,7 @@ fap_deploy = distenv.PhonyTarget(
"send",
"${SOURCE}",
"/ext/apps",
"${ARGS}",
]
]
),
@ -208,7 +211,7 @@ distenv.Alias("jflash", firmware_jflash)
distenv.PhonyTarget(
"gdb_trace_all",
"$GDB $GDBOPTS $SOURCES $GDBFLASH",
[["${GDB}", "${GDBOPTS}", "${SOURCES}", "${GDBFLASH}"]],
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE}",
GDBREMOTE="${OPENOCD_GDB_PIPE}",
@ -227,7 +230,7 @@ firmware_debug = distenv.PhonyTarget(
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE}",
GDBREMOTE="${OPENOCD_GDB_PIPE}",
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
)
distenv.Depends(firmware_debug, firmware_flash)
@ -237,7 +240,7 @@ distenv.PhonyTarget(
source=firmware_env["FW_ELF"],
GDBOPTS="${GDBOPTS_BASE} ${GDBOPTS_BLACKMAGIC}",
GDBREMOTE="${BLACKMAGIC_ADDR}",
FBT_FAP_DEBUG_ELF_ROOT=path_as_posix(firmware_env.subst("$FBT_FAP_DEBUG_ELF_ROOT")),
FBT_FAP_DEBUG_ELF_ROOT=firmware_env["FBT_FAP_DEBUG_ELF_ROOT"],
)
# Debug alien elf
@ -272,19 +275,35 @@ distenv.PhonyTarget(
# Just start OpenOCD
distenv.PhonyTarget(
"openocd",
"${OPENOCDCOM}",
[["${OPENOCDCOM}", "${ARGS}"]],
)
# Linter
distenv.PhonyTarget(
"lint",
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "check", "${LINT_SOURCES}"]],
[
[
"${PYTHON3}",
"${FBT_SCRIPT_DIR}/lint.py",
"check",
"${LINT_SOURCES}",
"${ARGS}",
]
],
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
)
distenv.PhonyTarget(
"format",
[["${PYTHON3}", "${FBT_SCRIPT_DIR}/lint.py", "format", "${LINT_SOURCES}"]],
[
[
"${PYTHON3}",
"${FBT_SCRIPT_DIR}/lint.py",
"format",
"${LINT_SOURCES}",
"${ARGS}",
]
],
LINT_SOURCES=[n.srcnode() for n in firmware_env["LINT_SOURCES"]],
)
@ -307,7 +326,16 @@ firmware_env.Append(
)
black_commandline = "@${PYTHON3} -m black ${PY_BLACK_ARGS} ${PY_LINT_SOURCES}"
black_commandline = [
[
"@${PYTHON3}",
"-m",
"black",
"${PY_BLACK_ARGS}",
"${PY_LINT_SOURCES}",
"${ARGS}",
]
]
black_base_args = [
"--include",
'"(\\.scons|\\.py|SConscript|SConstruct|\\.fam)$"',
@ -333,12 +361,28 @@ distenv.PhonyTarget(
# Start Flipper CLI via PySerial's miniterm
distenv.PhonyTarget(
"cli", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/serial_cli.py", "-p", "${FLIP_PORT}"]]
"cli",
[
[
"${PYTHON3}",
"${FBT_SCRIPT_DIR}/serial_cli.py",
"-p",
"${FLIP_PORT}",
"${ARGS}",
]
],
)
# Update WiFi devboard firmware
# Update WiFi devboard firmware with release channel
distenv.PhonyTarget(
"devboard_flash", [["${PYTHON3}", "${FBT_SCRIPT_DIR}/wifi_board.py"]]
"devboard_flash",
[
[
"${PYTHON3}",
"${FBT_SCRIPT_DIR}/wifi_board.py",
"${ARGS}",
]
],
)
@ -353,7 +397,7 @@ distenv.PhonyTarget(
distenv.PhonyTarget(
"get_stlink",
distenv.Action(
lambda **kw: distenv.GetDevices(),
lambda **_: distenv.GetDevices(),
None,
),
)
@ -376,3 +420,18 @@ distenv.PhonyTarget(
"env",
"@echo $( ${FBT_SCRIPT_DIR.abspath}/toolchain/fbtenv.sh $)",
)
doxy_build = distenv.DoxyBuild(
"documentation/doxygen/build/html/index.html",
"documentation/doxygen/Doxyfile-awesome.cfg",
doxy_env_variables={
"DOXY_SRC_ROOT": Dir(".").abspath,
"DOXY_BUILD_DIR": Dir("documentation/doxygen/build").abspath,
"DOXY_CONFIG_DIR": "documentation/doxygen",
},
)
distenv.Alias("doxygen", doxy_build)
distenv.AlwaysBuild(doxy_build)
# Open generated documentation in browser
distenv.PhonyTarget("doxy", open_browser_action, source=doxy_build)

View file

@ -11,29 +11,29 @@ class AccessorApp {
public:
void run(void);
AccessorApp();
~AccessorApp();
AccessorApp(void);
~AccessorApp(void);
enum class Scene : uint8_t {
Exit,
Start,
};
AccessorAppViewManager* get_view_manager();
AccessorAppViewManager* get_view_manager(void);
void switch_to_next_scene(Scene index);
void search_and_switch_to_previous_scene(std::initializer_list<Scene> scenes_list);
bool switch_to_previous_scene(uint8_t count = 1);
Scene get_previous_scene();
Scene get_previous_scene(void);
void notify_green_blink();
void notify_success();
void notify_green_blink(void);
void notify_success(void);
char* get_text_store();
uint8_t get_text_store_size();
char* get_text_store(void);
uint8_t get_text_store_size(void);
void set_text_store(const char* text...);
WIEGAND* get_wiegand();
OneWireHost* get_one_wire();
WIEGAND* get_wiegand(void);
OneWireHost* get_one_wire(void);
private:
std::list<Scene> previous_scenes_list = {Scene::Exit};

View file

@ -1,6 +1,6 @@
#include "accessor_view_manager.h"
#include "accessor_event.h"
#include <callback-connector.h>
#include "callback_connector.h"
AccessorAppViewManager::AccessorAppViewManager() {
event_queue = furi_message_queue_alloc(10, sizeof(AccessorEvent));

View file

@ -15,16 +15,16 @@ public:
FuriMessageQueue* event_queue;
AccessorAppViewManager();
~AccessorAppViewManager();
AccessorAppViewManager(void);
~AccessorAppViewManager(void);
void switch_to(ViewType type);
void receive_event(AccessorEvent* event);
void send_event(AccessorEvent* event);
Submenu* get_submenu();
Popup* get_popup();
Submenu* get_submenu(void);
Popup* get_popup(void);
private:
ViewDispatcher* view_dispatcher;

View file

@ -1,10 +1,13 @@
#ifndef CALLBACKCONNECTOR_H
#define CALLBACKCONNECTOR_H
#ifdef __cplusplus
#include <functional>
namespace cbc {
namespace Details {
template <std::size_t Tag, typename T, typename Ret, typename... Args> class FuncMemberWrapper {
template <std::size_t Tag, typename T, typename Ret, typename... Args>
class FuncMemberWrapper {
public:
FuncMemberWrapper() = delete;
using member_fun_t = Ret (T::*)(Args...);
@ -43,7 +46,8 @@ template <std::size_t Tag, typename T, typename Ret, typename... Args>
typename FuncMemberWrapper<Tag, T, Ret, Args...>::const_member_fun_t
FuncMemberWrapper<Tag, T, Ret, Args...>::const_member{};
template <typename Functor, typename Ret, typename... Args> struct FunctorWrapper {
template <typename Functor, typename Ret, typename... Args>
struct FunctorWrapper {
public:
static std::function<Ret(Args...)> functor;
static auto instatiate(Functor fn) {
@ -75,7 +79,8 @@ auto const_instantiate(T* t, Ret (T::*ptr)(Args...) const) {
return FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
}
template <std::size_t tag, typename T, typename Func> auto const_instantiate(T* t, Func ptr) {
template <std::size_t tag, typename T, typename Func>
auto const_instantiate(T* t, Func ptr) {
return const_instantiate(t, ptr);
}
@ -91,9 +96,11 @@ auto obtain_connector(T* t, Ret (T::*ptr)(Args...) const) {
return Details::FuncMemberWrapper<tag, T, Ret, Args...>::instantiate(t, ptr);
}
template <typename Functor> auto obtain_connector(Functor functor) {
template <typename Functor>
auto obtain_connector(Functor functor) {
return Details::deducer(std::move(functor), &Functor::operator());
}
} //end of cbc scope
#endif // __cplusplus
#endif // CALLBACKCONNECTOR_H

View file

@ -2,12 +2,12 @@
#include <furi.h>
#include <furi_hal.h>
volatile unsigned long WIEGAND::_cardTempHigh = 0;
volatile unsigned long WIEGAND::_cardTemp = 0;
volatile unsigned long WIEGAND::_lastWiegand = 0;
unsigned long WIEGAND::_cardTempHigh = 0;
unsigned long WIEGAND::_cardTemp = 0;
unsigned long WIEGAND::_lastWiegand = 0;
unsigned long WIEGAND::_code = 0;
unsigned long WIEGAND::_codeHigh = 0;
volatile int WIEGAND::_bitCount = 0;
int WIEGAND::_bitCount = 0;
int WIEGAND::_wiegandType = 0;
constexpr uint32_t clocks_in_ms = 64 * 1000;
@ -98,10 +98,7 @@ void WIEGAND::ReadD1() {
_lastWiegand = DWT->CYCCNT; // Keep track of last wiegand bit received
}
unsigned long WIEGAND::GetCardId(
volatile unsigned long* codehigh,
volatile unsigned long* codelow,
char bitlength) {
unsigned long WIEGAND::GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength) {
if(bitlength == 26) // EM tag
return (*codelow & 0x1FFFFFE) >> 1;

View file

@ -2,28 +2,26 @@
class WIEGAND {
public:
WIEGAND();
void begin();
void end();
bool available();
unsigned long getCode();
unsigned long getCodeHigh();
int getWiegandType();
WIEGAND(void);
void begin(void);
void end(void);
bool available(void);
unsigned long getCode(void);
unsigned long getCodeHigh(void);
int getWiegandType(void);
static void ReadD0();
static void ReadD1();
static void ReadD0(void);
static void ReadD1(void);
private:
static bool DoWiegandConversion();
static unsigned long GetCardId(
volatile unsigned long* codehigh,
volatile unsigned long* codelow,
char bitlength);
static bool DoWiegandConversion(void);
static unsigned long
GetCardId(unsigned long* codehigh, unsigned long* codelow, char bitlength);
static volatile unsigned long _cardTempHigh;
static volatile unsigned long _cardTemp;
static volatile unsigned long _lastWiegand;
static volatile int _bitCount;
static unsigned long _cardTempHigh;
static unsigned long _cardTemp;
static unsigned long _lastWiegand;
static int _bitCount;
static int _wiegandType;
static unsigned long _code;
static unsigned long _codeHigh;

View file

@ -1,7 +1,7 @@
#include "../accessor_app.h"
#include "../accessor_view_manager.h"
#include "../accessor_event.h"
#include <callback-connector.h>
#include "callback_connector.h"
#include "accessor_scene_start.h"
void AccessorSceneStart::on_enter(AccessorApp* app) {

View file

@ -12,7 +12,8 @@ void battery_test_dialog_callback(DialogExResult result, void* context) {
}
}
uint32_t battery_test_exit_confirm_view() {
uint32_t battery_test_exit_confirm_view(void* context) {
UNUSED(context);
return BatteryTestAppViewExitDialog;
}
@ -31,7 +32,7 @@ static void battery_test_battery_info_update_model(void* context) {
notification_message(app->notifications, &sequence_display_backlight_on);
}
BatteryTestApp* battery_test_alloc() {
BatteryTestApp* battery_test_alloc(void) {
BatteryTestApp* app = malloc(sizeof(BatteryTestApp));
// Records

View file

@ -116,7 +116,7 @@ static void battery_info_draw_callback(Canvas* canvas, void* context) {
draw_stat(canvas, 104, 42, &I_Health_16x16, health);
}
BatteryInfo* battery_info_alloc() {
BatteryInfo* battery_info_alloc(void) {
BatteryInfo* battery_info = malloc(sizeof(BatteryInfo));
battery_info->view = view_alloc();
view_set_context(battery_info->view, battery_info);

View file

@ -14,7 +14,7 @@ typedef struct {
uint8_t health;
} BatteryInfoModel;
BatteryInfo* battery_info_alloc();
BatteryInfo* battery_info_alloc(void);
void battery_info_free(BatteryInfo* battery_info);

View file

@ -28,7 +28,7 @@ uint32_t bt_debug_start_view(void* context) {
return BtDebugAppViewSubmenu;
}
BtDebugApp* bt_debug_app_alloc() {
BtDebugApp* bt_debug_app_alloc(void) {
BtDebugApp* app = malloc(sizeof(BtDebugApp));
// Gui

View file

@ -129,7 +129,7 @@ static void bt_test_carrier_timer_callback(void* context) {
}
}
BtCarrierTest* bt_carrier_test_alloc() {
BtCarrierTest* bt_carrier_test_alloc(void) {
BtCarrierTest* bt_carrier_test = malloc(sizeof(BtCarrierTest));
bt_carrier_test->bt_test = bt_test_alloc();
bt_test_set_context(bt_carrier_test->bt_test, bt_carrier_test);

View file

@ -3,7 +3,7 @@
typedef struct BtCarrierTest BtCarrierTest;
BtCarrierTest* bt_carrier_test_alloc();
BtCarrierTest* bt_carrier_test_alloc(void);
void bt_carrier_test_free(BtCarrierTest* bt_carrier_test);

View file

@ -97,7 +97,7 @@ static void bt_test_packet_timer_callback(void* context) {
}
}
BtPacketTest* bt_packet_test_alloc() {
BtPacketTest* bt_packet_test_alloc(void) {
BtPacketTest* bt_packet_test = malloc(sizeof(BtPacketTest));
bt_packet_test->bt_test = bt_test_alloc();
bt_test_set_context(bt_packet_test->bt_test, bt_packet_test);

View file

@ -3,7 +3,7 @@
typedef struct BtPacketTest BtPacketTest;
BtPacketTest* bt_packet_test_alloc();
BtPacketTest* bt_packet_test_alloc(void);
void bt_packet_test_free(BtPacketTest* bt_packet_test);

View file

@ -305,7 +305,7 @@ void bt_test_process_back(BtTest* bt_test) {
}
}
BtTest* bt_test_alloc() {
BtTest* bt_test_alloc(void) {
BtTest* bt_test = malloc(sizeof(BtTest));
bt_test->view = view_alloc();
view_set_context(bt_test->view, bt_test);

View file

@ -12,7 +12,7 @@ typedef void (*BtTestBackCallback)(void* context);
typedef struct BtTestParam BtTestParam;
typedef void (*BtTestParamChangeCallback)(BtTestParam* param);
BtTest* bt_test_alloc();
BtTest* bt_test_alloc(void);
void bt_test_free(BtTest* bt_test);

View file

@ -90,7 +90,7 @@ uint32_t ccid_test_exit(void* context) {
return VIEW_NONE;
}
CcidTestApp* ccid_test_app_alloc() {
CcidTestApp* ccid_test_app_alloc(void) {
CcidTestApp* app = malloc(sizeof(CcidTestApp));
// Gui

View file

@ -50,7 +50,7 @@ static void crash_test_submenu_callback(void* context, uint32_t index) {
furi_halt("Crash test: furi_halt");
break;
default:
furi_crash("Programming error");
furi_crash();
}
}
@ -59,7 +59,7 @@ static uint32_t crash_test_exit_callback(void* context) {
return VIEW_NONE;
}
CrashTest* crash_test_alloc() {
CrashTest* crash_test_alloc(void) {
CrashTest* instance = malloc(sizeof(CrashTest));
View* view = NULL;

View file

@ -26,7 +26,7 @@ static void gui_input_events_callback(const void* value, void* ctx) {
}
}
static DirectDraw* direct_draw_alloc() {
static DirectDraw* direct_draw_alloc(void) {
DirectDraw* instance = malloc(sizeof(DirectDraw));
instance->input = furi_record_open(RECORD_INPUT_EVENTS);

View file

@ -121,7 +121,7 @@ static void display_config_set_contrast(VariableItem* item) {
display_test_reload_config(instance);
}
DisplayTest* display_test_alloc() {
DisplayTest* display_test_alloc(void) {
DisplayTest* instance = malloc(sizeof(DisplayTest));
View* view = NULL;

View file

@ -154,7 +154,7 @@ static void view_display_test_timer_callback(void* context) {
instance->view, ViewDisplayTestModel * model, { model->counter++; }, true);
}
ViewDisplayTest* view_display_test_alloc() {
ViewDisplayTest* view_display_test_alloc(void) {
ViewDisplayTest* instance = malloc(sizeof(ViewDisplayTest));
instance->view = view_alloc();

View file

@ -5,7 +5,7 @@
typedef struct ViewDisplayTest ViewDisplayTest;
ViewDisplayTest* view_display_test_alloc();
ViewDisplayTest* view_display_test_alloc(void);
void view_display_test_free(ViewDisplayTest* instance);

View file

@ -81,7 +81,7 @@ static void expansion_test_app_serial_rx_callback(
}
}
static ExpansionTestApp* expansion_test_app_alloc() {
static ExpansionTestApp* expansion_test_app_alloc(void) {
ExpansionTestApp* instance = malloc(sizeof(ExpansionTestApp));
instance->buf = furi_stream_buffer_alloc(RECEIVE_BUFFER_SIZE, 1);
return instance;

View file

@ -12,7 +12,7 @@ static bool lfrfid_debug_back_event_callback(void* context) {
return scene_manager_handle_back_event(app->scene_manager);
}
static LfRfidDebug* lfrfid_debug_alloc() {
static LfRfidDebug* lfrfid_debug_alloc(void) {
LfRfidDebug* app = malloc(sizeof(LfRfidDebug));
app->view_dispatcher = view_dispatcher_alloc();

View file

@ -170,7 +170,7 @@ static bool lfrfid_debug_view_tune_input_callback(InputEvent* event, void* conte
return consumed;
}
LfRfidTuneView* lfrfid_debug_view_tune_alloc() {
LfRfidTuneView* lfrfid_debug_view_tune_alloc(void) {
LfRfidTuneView* tune_view = malloc(sizeof(LfRfidTuneView));
tune_view->view = view_alloc();
view_set_context(tune_view->view, tune_view);

View file

@ -3,7 +3,7 @@
typedef struct LfRfidTuneView LfRfidTuneView;
LfRfidTuneView* lfrfid_debug_view_tune_alloc();
LfRfidTuneView* lfrfid_debug_view_tune_alloc(void);
void lfrfid_debug_view_tune_free(LfRfidTuneView* tune_view);

View file

@ -53,7 +53,7 @@ static uint32_t locale_test_exit(void* context) {
return VIEW_NONE;
}
static LocaleTestApp* locale_test_alloc() {
static LocaleTestApp* locale_test_alloc(void) {
LocaleTestApp* app = malloc(sizeof(LocaleTestApp));
// Gui

View file

@ -83,7 +83,7 @@ static bool rpc_debug_app_rpc_init_rpc(RpcDebugApp* app, const char* args) {
return ret;
}
static RpcDebugApp* rpc_debug_app_alloc() {
static RpcDebugApp* rpc_debug_app_alloc(void) {
RpcDebugApp* app = malloc(sizeof(RpcDebugApp));
app->gui = furi_record_open(RECORD_GUI);

View file

@ -21,7 +21,7 @@ typedef struct {
Cli* cli;
} SpeakerDebugApp;
static SpeakerDebugApp* speaker_app_alloc() {
static SpeakerDebugApp* speaker_app_alloc(void) {
SpeakerDebugApp* app = (SpeakerDebugApp*)malloc(sizeof(SpeakerDebugApp));
app->music_worker = music_worker_alloc();
app->message_queue = furi_message_queue_alloc(8, sizeof(SpeakerDebugAppMessage));

View file

@ -38,7 +38,7 @@ typedef enum {
PrincetonDecoderStepCheckDuration,
} PrincetonDecoderStep;
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc() {
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void) {
SubGhzEncoderPrinceton* instance = malloc(sizeof(SubGhzEncoderPrinceton));
return instance;
}

View file

@ -15,7 +15,7 @@ typedef void (*SubGhzDecoderPrincetonCallback)(SubGhzDecoderPrinceton* parser, v
* Allocate SubGhzEncoderPrinceton
* @return pointer to SubGhzEncoderPrinceton instance
*/
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc();
SubGhzEncoderPrinceton* subghz_encoder_princeton_for_testing_alloc(void);
/**
* Free SubGhzEncoderPrinceton instance
@ -69,7 +69,7 @@ LevelDuration subghz_encoder_princeton_for_testing_yield(void* context);
* Allocate SubGhzDecoderPrinceton
* @return SubGhzDecoderPrinceton*
*/
SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc();
SubGhzDecoderPrinceton* subghz_decoder_princeton_for_testing_alloc(void);
/**
* Free SubGhzDecoderPrinceton

View file

@ -12,7 +12,7 @@ void subghz_test_scene_show_only_rx_on_enter(void* context) {
// Setup view
Popup* popup = app->popup;
const char* header_text = "Transmission is blocked";
const char* header_text = "Transmission is Blocked";
const char* message_text = "Transmission on\nthis frequency is\nrestricted in\nyour region";
if(!furi_hal_region_is_provisioned()) {
header_text = "Firmware update needed";

View file

@ -21,7 +21,7 @@ static void subghz_test_app_tick_event_callback(void* context) {
scene_manager_handle_tick_event(app->scene_manager);
}
SubGhzTestApp* subghz_test_app_alloc() {
SubGhzTestApp* subghz_test_app_alloc(void) {
SubGhzTestApp* app = malloc(sizeof(SubGhzTestApp));
// GUI

View file

@ -186,7 +186,7 @@ void subghz_test_carrier_rssi_timer_callback(void* context) {
false);
}
SubGhzTestCarrier* subghz_test_carrier_alloc() {
SubGhzTestCarrier* subghz_test_carrier_alloc(void) {
SubGhzTestCarrier* subghz_test_carrier = malloc(sizeof(SubGhzTestCarrier));
// View allocation and configuration

View file

@ -15,7 +15,7 @@ void subghz_test_carrier_set_callback(
SubGhzTestCarrierCallback callback,
void* context);
SubGhzTestCarrier* subghz_test_carrier_alloc();
SubGhzTestCarrier* subghz_test_carrier_alloc(void);
void subghz_test_carrier_free(SubGhzTestCarrier* subghz_test_carrier);

View file

@ -236,7 +236,7 @@ void subghz_test_packet_exit(void* context) {
furi_hal_subghz_sleep();
}
SubGhzTestPacket* subghz_test_packet_alloc() {
SubGhzTestPacket* subghz_test_packet_alloc(void) {
SubGhzTestPacket* instance = malloc(sizeof(SubGhzTestPacket));
// View allocation and configuration

View file

@ -15,7 +15,7 @@ void subghz_test_packet_set_callback(
SubGhzTestPacketCallback callback,
void* context);
SubGhzTestPacket* subghz_test_packet_alloc();
SubGhzTestPacket* subghz_test_packet_alloc(void);
void subghz_test_packet_free(SubGhzTestPacket* subghz_test_packet);

View file

@ -164,7 +164,7 @@ void subghz_test_static_exit(void* context) {
furi_hal_subghz_sleep();
}
SubGhzTestStatic* subghz_test_static_alloc() {
SubGhzTestStatic* subghz_test_static_alloc(void) {
SubGhzTestStatic* instance = malloc(sizeof(SubGhzTestStatic));
// View allocation and configuration

View file

@ -15,7 +15,7 @@ void subghz_test_static_set_callback(
SubGhzTestStaticCallback callback,
void* context);
SubGhzTestStatic* subghz_test_static_alloc();
SubGhzTestStatic* subghz_test_static_alloc(void);
void subghz_test_static_free(SubGhzTestStatic* subghz_static);

View file

@ -734,7 +734,7 @@ MU_TEST_SUITE(test_bit_lib) {
MU_RUN_TEST(test_bit_lib_bytes_to_num_bcd);
}
int run_minunit_test_bit_lib() {
int run_minunit_test_bit_lib(void) {
MU_RUN_SUITE(test_bit_lib);
return MU_EXIT_CODE;
}

View file

@ -17,7 +17,7 @@ typedef struct {
BtTest* bt_test = NULL;
void bt_test_alloc() {
void bt_test_alloc(void) {
bt_test = malloc(sizeof(BtTest));
bt_test->storage = furi_record_open(RECORD_STORAGE);
bt_test->nvm_ram_buff_dut = malloc(BT_TEST_NVM_RAM_BUFF_SIZE);
@ -27,7 +27,7 @@ void bt_test_alloc() {
bt_test->bt_keys_storage, bt_test->nvm_ram_buff_dut, BT_TEST_NVM_RAM_BUFF_SIZE);
}
void bt_test_free() {
void bt_test_free(void) {
furi_check(bt_test);
free(bt_test->nvm_ram_buff_ref);
free(bt_test->nvm_ram_buff_dut);
@ -37,7 +37,7 @@ void bt_test_free() {
bt_test = NULL;
}
static void bt_test_keys_storage_profile() {
static void bt_test_keys_storage_profile(void) {
// Emulate nvm change on initial connection
const int nvm_change_size_on_connection = 88;
for(size_t i = 0; i < nvm_change_size_on_connection; i++) {
@ -82,7 +82,7 @@ static void bt_test_keys_storage_profile() {
"Wrong buffer loaded");
}
static void bt_test_keys_remove_test_file() {
static void bt_test_keys_remove_test_file(void) {
mu_assert(
storage_simply_remove(bt_test->storage, BT_TEST_KEY_STORAGE_FILE_PATH),
"Can't remove test file");
@ -104,7 +104,7 @@ MU_TEST_SUITE(test_bt) {
bt_test_free();
}
int run_minunit_test_bt() {
int run_minunit_test_bt(void) {
MU_RUN_SUITE(test_bt);
return MU_EXIT_CODE;
}

View file

@ -112,7 +112,7 @@ MU_TEST_SUITE(test_datetime_validate_datetime) {
MU_TEST(test_datetime_timestamp_to_datetime_min) {
uint32_t test_value = 0;
DateTime min_datetime_expected = {0, 0, 0, 1, 1, 1970, 0};
DateTime min_datetime_expected = {0, 0, 0, 1, 1, 1970, 4};
DateTime result = {0};
datetime_timestamp_to_datetime(test_value, &result);
@ -122,7 +122,7 @@ MU_TEST(test_datetime_timestamp_to_datetime_min) {
MU_TEST(test_datetime_timestamp_to_datetime_max) {
uint32_t test_value = UINT32_MAX;
DateTime max_datetime_expected = {6, 28, 15, 7, 2, 2106, 0};
DateTime max_datetime_expected = {6, 28, 15, 7, 2, 2106, 7};
DateTime result = {0};
datetime_timestamp_to_datetime(test_value, &result);
@ -141,10 +141,26 @@ MU_TEST(test_datetime_timestamp_to_datetime_to_timestamp) {
mu_assert_int_eq(test_value, result);
}
MU_TEST(test_datetime_timestamp_to_datetime_weekday) {
uint32_t test_value = 1709748421; // Wed Mar 06 18:07:01 2024 UTC
DateTime datetime = {0};
datetime_timestamp_to_datetime(test_value, &datetime);
mu_assert_int_eq(datetime.hour, 18);
mu_assert_int_eq(datetime.minute, 7);
mu_assert_int_eq(datetime.second, 1);
mu_assert_int_eq(datetime.day, 6);
mu_assert_int_eq(datetime.month, 3);
mu_assert_int_eq(datetime.weekday, 3);
mu_assert_int_eq(datetime.year, 2024);
}
MU_TEST_SUITE(test_datetime_timestamp_to_datetime_suite) {
MU_RUN_TEST(test_datetime_timestamp_to_datetime_min);
MU_RUN_TEST(test_datetime_timestamp_to_datetime_max);
MU_RUN_TEST(test_datetime_timestamp_to_datetime_to_timestamp);
MU_RUN_TEST(test_datetime_timestamp_to_datetime_weekday);
}
MU_TEST(test_datetime_datetime_to_timestamp_min) {
@ -166,7 +182,7 @@ MU_TEST_SUITE(test_datetime_datetime_to_timestamp_suite) {
MU_RUN_TEST(test_datetime_datetime_to_timestamp_max);
}
int run_minunit_test_datetime() {
int run_minunit_test_datetime(void) {
MU_RUN_SUITE(test_datetime_timestamp_to_datetime_suite);
MU_RUN_SUITE(test_datetime_datetime_to_timestamp_suite);
MU_RUN_SUITE(test_datetime_validate_datetime);

View file

@ -25,7 +25,7 @@ MU_TEST_SUITE(dialogs_file_browser_options) {
MU_RUN_TEST(test_dialog_file_browser_set_basic_options_should_init_all_fields);
}
int run_minunit_test_dialogs_file_browser_options() {
int run_minunit_test_dialogs_file_browser_options(void) {
MU_RUN_SUITE(dialogs_file_browser_options);
return MU_EXIT_CODE;

View file

@ -194,7 +194,7 @@ MU_TEST_SUITE(test_expansion_suite) {
MU_RUN_TEST(test_expansion_garbage_input);
}
int run_minunit_test_expansion() {
int run_minunit_test_expansion(void) {
MU_RUN_SUITE(test_expansion_suite);
return MU_EXIT_CODE;
}

View file

@ -331,7 +331,7 @@ MU_TEST_SUITE(flipper_format_string_suite) {
MU_RUN_TEST(flipper_format_file_test);
}
int run_minunit_test_flipper_format_string() {
int run_minunit_test_flipper_format_string(void) {
MU_RUN_SUITE(flipper_format_string_suite);
return MU_EXIT_CODE;
}

View file

@ -103,14 +103,14 @@ static bool storage_write_string(const char* path, const char* data) {
return result;
}
static void tests_setup() {
static void tests_setup(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data");
mu_assert(storage_simply_mkdir(storage, TEST_DIR_NAME), "Cannot create dir");
furi_record_close(RECORD_STORAGE);
}
static void tests_teardown() {
static void tests_teardown(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
mu_assert(storage_simply_remove_recursive(storage, TEST_DIR_NAME), "Cannot clean data");
furi_record_close(RECORD_STORAGE);
@ -545,7 +545,7 @@ MU_TEST_SUITE(flipper_format) {
tests_teardown();
}
int run_minunit_test_flipper_format() {
int run_minunit_test_flipper_format(void) {
MU_RUN_SUITE(flipper_format);
return MU_EXIT_CODE;
}

View file

@ -54,7 +54,7 @@ MU_TEST_SUITE(float_tools_suite) {
MU_RUN_TEST(float_tools_equal_test);
}
int run_minunit_test_float_tools() {
int run_minunit_test_float_tools(void) {
MU_RUN_SUITE(float_tools_suite);
return MU_EXIT_CODE;
}

View file

@ -4,7 +4,7 @@
#include <stdbool.h>
#include <stdint.h>
void test_furi_memmgr() {
void test_furi_memmgr(void) {
void* ptr;
// allocate memory case

View file

@ -15,7 +15,7 @@ void test_pubsub_handler(const void* arg, void* ctx) {
pubsub_context_value = *(uint32_t*)ctx;
}
void test_furi_pubsub() {
void test_furi_pubsub(void) {
FuriPubSub* test_pubsub = NULL;
FuriPubSubSubscription* test_pubsub_subscription = NULL;

View file

@ -5,7 +5,7 @@
#define TEST_RECORD_NAME "test/holding"
void test_furi_create_open() {
void test_furi_create_open(void) {
// Test that record does not exist
mu_check(furi_record_exists(TEST_RECORD_NAME) == false);

View file

@ -462,7 +462,7 @@ MU_TEST_SUITE(test_suite) {
MU_RUN_TEST(mu_test_furi_string_utf8);
}
int run_minunit_test_furi_string() {
int run_minunit_test_furi_string(void) {
MU_RUN_SUITE(test_suite);
return MU_EXIT_CODE;

View file

@ -4,11 +4,11 @@
#include "../minunit.h"
// v2 tests
void test_furi_create_open();
void test_furi_concurrent_access();
void test_furi_pubsub();
void test_furi_create_open(void);
void test_furi_concurrent_access(void);
void test_furi_pubsub(void);
void test_furi_memmgr();
void test_furi_memmgr(void);
static int foo = 0;
@ -50,7 +50,7 @@ MU_TEST_SUITE(test_suite) {
MU_RUN_TEST(mu_test_furi_memmgr);
}
int run_minunit_test_furi() {
int run_minunit_test_furi(void) {
MU_RUN_SUITE(test_suite);
return MU_EXIT_CODE;

View file

@ -409,16 +409,16 @@ static const uint8_t tv_gcm_tag_4[16] = {
0x1B,
};
static void furi_hal_crypto_ctr_setup() {
static void furi_hal_crypto_ctr_setup(void) {
}
static void furi_hal_crypto_ctr_teardown() {
static void furi_hal_crypto_ctr_teardown(void) {
}
static void furi_hal_crypto_gcm_setup() {
static void furi_hal_crypto_gcm_setup(void) {
}
static void furi_hal_crypto_gcm_teardown() {
static void furi_hal_crypto_gcm_teardown(void) {
}
MU_TEST(furi_hal_crypto_ctr_1) {
@ -595,7 +595,7 @@ MU_TEST_SUITE(furi_hal_crypto_gcm_test) {
MU_RUN_TEST(furi_hal_crypto_gcm_4);
}
int run_minunit_test_furi_hal_crypto() {
int run_minunit_test_furi_hal_crypto(void) {
MU_RUN_SUITE(furi_hal_crypto_ctr_test);
MU_RUN_SUITE(furi_hal_crypto_gcm_test);
return MU_EXIT_CODE;

View file

@ -14,19 +14,19 @@
#define EEPROM_PAGE_SIZE 16
#define EEPROM_WRITE_DELAY_MS 6
static void furi_hal_i2c_int_setup() {
static void furi_hal_i2c_int_setup(void) {
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
}
static void furi_hal_i2c_int_teardown() {
static void furi_hal_i2c_int_teardown(void) {
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
}
static void furi_hal_i2c_ext_setup() {
static void furi_hal_i2c_ext_setup(void) {
furi_hal_i2c_acquire(&furi_hal_i2c_handle_external);
}
static void furi_hal_i2c_ext_teardown() {
static void furi_hal_i2c_ext_teardown(void) {
furi_hal_i2c_release(&furi_hal_i2c_handle_external);
}
@ -227,7 +227,7 @@ MU_TEST_SUITE(furi_hal_i2c_ext_suite) {
MU_RUN_TEST(furi_hal_i2c_ext_eeprom);
}
int run_minunit_test_furi_hal() {
int run_minunit_test_furi_hal(void) {
MU_RUN_SUITE(furi_hal_i2c_int_suite);
MU_RUN_SUITE(furi_hal_i2c_ext_suite);
return MU_EXIT_CODE;

View file

@ -17,7 +17,7 @@ typedef struct {
static InfraredTest* test;
static void infrared_test_alloc() {
static void infrared_test_alloc(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
test = malloc(sizeof(InfraredTest));
test->decoder_handler = infrared_alloc_decoder();
@ -26,7 +26,7 @@ static void infrared_test_alloc() {
test->file_path = furi_string_alloc();
}
static void infrared_test_free() {
static void infrared_test_free(void) {
furi_check(test);
infrared_free_decoder(test->decoder_handler);
infrared_free_encoder(test->encoder_handler);
@ -426,53 +426,53 @@ MU_TEST(infrared_test_decoder_mixed) {
infrared_test_run_decoder(InfraredProtocolSIRC, 3);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 1);
infrared_test_run_decoder(InfraredProtocolRCA, 1);
infrared_test_run_decoder(InfraredProtocolPioneer, 6);
}
MU_TEST(infrared_test_decoder_nec) {
infrared_test_run_decoder(InfraredProtocolNEC, 1);
infrared_test_run_decoder(InfraredProtocolNEC, 2);
infrared_test_run_decoder(InfraredProtocolNEC, 3);
for(uint32_t i = 1; i <= 3; ++i) {
infrared_test_run_decoder(InfraredProtocolNEC, i);
}
}
MU_TEST(infrared_test_decoder_unexpected_end_in_sequence) {
infrared_test_run_decoder(InfraredProtocolNEC, 1);
infrared_test_run_decoder(InfraredProtocolNEC, 1);
infrared_test_run_decoder(InfraredProtocolNEC, 2);
infrared_test_run_decoder(InfraredProtocolNEC, 2);
for(uint32_t i = 1; i <= 2; ++i) {
infrared_test_run_decoder(InfraredProtocolNEC, i);
infrared_test_run_decoder(InfraredProtocolNEC, i);
}
}
MU_TEST(infrared_test_decoder_necext1) {
infrared_test_run_decoder(InfraredProtocolNECext, 1);
infrared_test_run_decoder(InfraredProtocolNECext, 1);
for(uint32_t i = 0; i < 2; ++i) {
UNUSED(i);
infrared_test_run_decoder(InfraredProtocolNECext, 1);
}
}
MU_TEST(infrared_test_decoder_long_packets_with_nec_start) {
infrared_test_run_decoder(InfraredProtocolNEC42ext, 1);
infrared_test_run_decoder(InfraredProtocolNEC42ext, 2);
for(uint32_t i = 1; i <= 2; ++i) {
infrared_test_run_decoder(InfraredProtocolNEC42ext, i);
}
}
MU_TEST(infrared_test_encoder_sirc) {
infrared_test_run_encoder(InfraredProtocolSIRC, 1);
infrared_test_run_encoder(InfraredProtocolSIRC, 2);
for(uint32_t i = 1; i <= 2; ++i) {
infrared_test_run_encoder(InfraredProtocolSIRC, i);
}
}
MU_TEST(infrared_test_decoder_sirc) {
infrared_test_run_decoder(InfraredProtocolSIRC, 3);
infrared_test_run_decoder(InfraredProtocolSIRC, 1);
infrared_test_run_decoder(InfraredProtocolSIRC, 2);
infrared_test_run_decoder(InfraredProtocolSIRC, 4);
infrared_test_run_decoder(InfraredProtocolSIRC, 5);
for(uint32_t i = 1; i <= 5; ++i) {
infrared_test_run_decoder(InfraredProtocolSIRC, 5);
}
}
MU_TEST(infrared_test_decoder_rc5) {
infrared_test_run_decoder(InfraredProtocolRC5X, 1);
infrared_test_run_decoder(InfraredProtocolRC5, 1);
infrared_test_run_decoder(InfraredProtocolRC5, 2);
infrared_test_run_decoder(InfraredProtocolRC5, 3);
infrared_test_run_decoder(InfraredProtocolRC5, 4);
infrared_test_run_decoder(InfraredProtocolRC5, 5);
infrared_test_run_decoder(InfraredProtocolRC5, 6);
infrared_test_run_decoder(InfraredProtocolRC5, 7);
for(uint32_t i = 1; i <= 7; ++i) {
infrared_test_run_decoder(InfraredProtocolRC5, i);
}
}
MU_TEST(infrared_test_encoder_rc5x) {
@ -492,21 +492,21 @@ MU_TEST(infrared_test_encoder_rc6) {
}
MU_TEST(infrared_test_decoder_kaseikyo) {
infrared_test_run_decoder(InfraredProtocolKaseikyo, 1);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 2);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 3);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 4);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 5);
infrared_test_run_decoder(InfraredProtocolKaseikyo, 6);
for(uint32_t i = 1; i <= 6; ++i) {
infrared_test_run_decoder(InfraredProtocolKaseikyo, i);
}
}
MU_TEST(infrared_test_decoder_rca) {
infrared_test_run_decoder(InfraredProtocolRCA, 1);
infrared_test_run_decoder(InfraredProtocolRCA, 2);
infrared_test_run_decoder(InfraredProtocolRCA, 3);
infrared_test_run_decoder(InfraredProtocolRCA, 4);
infrared_test_run_decoder(InfraredProtocolRCA, 5);
infrared_test_run_decoder(InfraredProtocolRCA, 6);
for(uint32_t i = 1; i <= 6; ++i) {
infrared_test_run_decoder(InfraredProtocolRCA, i);
}
}
MU_TEST(infrared_test_decoder_pioneer) {
for(uint32_t i = 1; i <= 11; ++i) {
infrared_test_run_decoder(InfraredProtocolPioneer, i);
}
}
MU_TEST(infrared_test_encoder_decoder_all) {
@ -520,6 +520,7 @@ MU_TEST(infrared_test_encoder_decoder_all) {
infrared_test_run_encoder_decoder(InfraredProtocolSIRC, 1);
infrared_test_run_encoder_decoder(InfraredProtocolKaseikyo, 1);
infrared_test_run_encoder_decoder(InfraredProtocolRCA, 1);
infrared_test_run_encoder_decoder(InfraredProtocolPioneer, 1);
}
MU_TEST_SUITE(infrared_test) {
@ -539,11 +540,12 @@ MU_TEST_SUITE(infrared_test) {
MU_RUN_TEST(infrared_test_decoder_necext1);
MU_RUN_TEST(infrared_test_decoder_kaseikyo);
MU_RUN_TEST(infrared_test_decoder_rca);
MU_RUN_TEST(infrared_test_decoder_pioneer);
MU_RUN_TEST(infrared_test_decoder_mixed);
MU_RUN_TEST(infrared_test_encoder_decoder_all);
}
int run_minunit_test_infrared() {
int run_minunit_test_infrared(void) {
MU_RUN_SUITE(infrared_test);
return MU_EXIT_CODE;
}

View file

@ -547,7 +547,7 @@ MU_TEST_SUITE(test_lfrfid_protocols_suite) {
MU_RUN_TEST(test_lfrfid_protocol_fdxb_emulate_simple);
}
int run_minunit_test_lfrfid_protocols() {
int run_minunit_test_lfrfid_protocols(void) {
MU_RUN_SUITE(test_lfrfid_protocols_suite);
return MU_EXIT_CODE;
}

View file

@ -69,7 +69,7 @@ MU_TEST_SUITE(manifest_suite) {
MU_RUN_TEST(manifest_iteration_test);
}
int run_minunit_test_manifest() {
int run_minunit_test_manifest(void) {
MU_RUN_SUITE(manifest_suite);
return MU_EXIT_CODE;
}

View file

@ -7,10 +7,13 @@
#include <nfc/nfc_poller.h>
#include <nfc/nfc_listener.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller.h>
#include <nfc/protocols/iso14443_3a/iso14443_3a_poller_sync.h>
#include <nfc/protocols/mf_ultralight/mf_ultralight.h>
#include <nfc/protocols/mf_ultralight/mf_ultralight_poller_sync.h>
#include <nfc/protocols/mf_classic/mf_classic_poller_sync.h>
#include <nfc/protocols/mf_classic/mf_classic_poller.h>
#include <nfc/nfc_poller.h>
#include <toolbox/keys_dict.h>
#include <nfc/nfc.h>
@ -22,18 +25,35 @@
#define NFC_TEST_NFC_DEV_PATH EXT_PATH("unit_tests/nfc/nfc_device_test.nfc")
#define NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH EXT_PATH("unit_tests/mf_dict.nfc")
#define NFC_TEST_FLAG_WORKER_DONE (1)
typedef enum {
NfcTestMfClassicSendFrameTestStateAuth,
NfcTestMfClassicSendFrameTestStateReadBlock,
NfcTestMfClassicSendFrameTestStateFail,
NfcTestMfClassicSendFrameTestStateSuccess,
} NfcTestMfClassicSendFrameTestState;
typedef struct {
NfcTestMfClassicSendFrameTestState state;
BitBuffer* tx_buf;
BitBuffer* rx_buf;
FuriThreadId thread_id;
} NfcTestMfClassicSendFrameTest;
typedef struct {
Storage* storage;
} NfcTest;
static NfcTest* nfc_test = NULL;
static void nfc_test_alloc() {
static void nfc_test_alloc(void) {
nfc_test = malloc(sizeof(NfcTest));
nfc_test->storage = furi_record_open(RECORD_STORAGE);
}
static void nfc_test_free() {
static void nfc_test_free(void) {
furi_check(nfc_test);
furi_record_close(RECORD_STORAGE);
@ -292,7 +312,7 @@ MU_TEST(ntag_213_locked_reader) {
nfc_free(poller);
}
static void mf_ultralight_write() {
static void mf_ultralight_write(void) {
Nfc* poller = nfc_alloc();
Nfc* listener = nfc_alloc();
@ -342,7 +362,7 @@ static void mf_ultralight_write() {
nfc_free(poller);
}
static void mf_classic_reader() {
static void mf_classic_reader(void) {
Nfc* poller = nfc_alloc();
Nfc* listener = nfc_alloc();
@ -368,7 +388,7 @@ static void mf_classic_reader() {
nfc_free(poller);
}
static void mf_classic_write() {
static void mf_classic_write(void) {
Nfc* poller = nfc_alloc();
Nfc* listener = nfc_alloc();
@ -396,7 +416,7 @@ static void mf_classic_write() {
nfc_free(poller);
}
static void mf_classic_value_block() {
static void mf_classic_value_block(void) {
Nfc* poller = nfc_alloc();
Nfc* listener = nfc_alloc();
@ -435,6 +455,109 @@ static void mf_classic_value_block() {
nfc_free(poller);
}
NfcCommand mf_classic_poller_send_frame_callback(NfcGenericEventEx event, void* context) {
furi_check(event.poller);
furi_check(event.parent_event_data);
furi_check(context);
NfcCommand command = NfcCommandContinue;
MfClassicPoller* instance = event.poller;
NfcTestMfClassicSendFrameTest* frame_test = context;
Iso14443_3aPollerEvent* iso3_event = event.parent_event_data;
MfClassicError error = MfClassicErrorNone;
if(iso3_event->type == Iso14443_3aPollerEventTypeReady) {
if(frame_test->state == NfcTestMfClassicSendFrameTestStateAuth) {
MfClassicKey key = {
.data = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff},
};
error = mf_classic_poller_auth(instance, 0, &key, MfClassicKeyTypeA, NULL);
frame_test->state = (error == MfClassicErrorNone) ?
NfcTestMfClassicSendFrameTestStateReadBlock :
NfcTestMfClassicSendFrameTestStateFail;
} else if(frame_test->state == NfcTestMfClassicSendFrameTestStateReadBlock) {
do {
const uint8_t read_block_cmd[] = {
0x30,
0x01,
0x8b,
0xb9,
};
bit_buffer_copy_bytes(frame_test->tx_buf, read_block_cmd, sizeof(read_block_cmd));
error = mf_classic_poller_send_encrypted_frame(
instance, frame_test->tx_buf, frame_test->rx_buf, 200000);
if(error != MfClassicErrorNone) break;
if(bit_buffer_get_size_bytes(frame_test->rx_buf) != 18) {
error = MfClassicErrorProtocol;
break;
}
const uint8_t* rx_data = bit_buffer_get_data(frame_test->rx_buf);
const uint8_t rx_data_ref[16] = {0};
if(memcmp(rx_data, rx_data_ref, sizeof(rx_data_ref)) != 0) {
error = MfClassicErrorProtocol;
break;
}
} while(false);
frame_test->state = (error == MfClassicErrorNone) ?
NfcTestMfClassicSendFrameTestStateSuccess :
NfcTestMfClassicSendFrameTestStateFail;
} else if(frame_test->state == NfcTestMfClassicSendFrameTestStateSuccess) {
command = NfcCommandStop;
} else if(frame_test->state == NfcTestMfClassicSendFrameTestStateFail) {
command = NfcCommandStop;
}
} else {
frame_test->state = NfcTestMfClassicSendFrameTestStateFail;
command = NfcCommandStop;
}
if(command == NfcCommandStop) {
furi_thread_flags_set(frame_test->thread_id, NFC_TEST_FLAG_WORKER_DONE);
}
return command;
}
MU_TEST(mf_classic_send_frame_test) {
Nfc* poller = nfc_alloc();
Nfc* listener = nfc_alloc();
NfcDevice* nfc_device = nfc_device_alloc();
nfc_data_generator_fill_data(NfcDataGeneratorTypeMfClassic4k_7b, nfc_device);
NfcListener* mfc_listener = nfc_listener_alloc(
listener, NfcProtocolMfClassic, nfc_device_get_data(nfc_device, NfcProtocolMfClassic));
nfc_listener_start(mfc_listener, NULL, NULL);
NfcPoller* mfc_poller = nfc_poller_alloc(poller, NfcProtocolMfClassic);
NfcTestMfClassicSendFrameTest context = {
.state = NfcTestMfClassicSendFrameTestStateAuth,
.thread_id = furi_thread_get_current_id(),
.tx_buf = bit_buffer_alloc(32),
.rx_buf = bit_buffer_alloc(32),
};
nfc_poller_start_ex(mfc_poller, mf_classic_poller_send_frame_callback, &context);
uint32_t flag =
furi_thread_flags_wait(NFC_TEST_FLAG_WORKER_DONE, FuriFlagWaitAny, FuriWaitForever);
mu_assert(flag == NFC_TEST_FLAG_WORKER_DONE, "Wrong thread flag");
nfc_poller_stop(mfc_poller);
nfc_poller_free(mfc_poller);
mu_assert(
context.state == NfcTestMfClassicSendFrameTestStateSuccess, "Wrong test state at the end");
bit_buffer_free(context.tx_buf);
bit_buffer_free(context.rx_buf);
nfc_listener_stop(mfc_listener);
nfc_listener_free(mfc_listener);
nfc_device_free(nfc_device);
nfc_free(listener);
nfc_free(poller);
}
MU_TEST(mf_classic_dict_test) {
Storage* storage = furi_record_open(RECORD_STORAGE);
if(storage_common_stat(storage, NFC_APP_MF_CLASSIC_DICT_UNIT_TEST_PATH, NULL) == FSE_OK) {
@ -538,17 +661,17 @@ MU_TEST_SUITE(nfc) {
MU_RUN_TEST(mf_classic_1k_7b_file_test);
MU_RUN_TEST(mf_classic_4k_4b_file_test);
MU_RUN_TEST(mf_classic_4k_7b_file_test);
MU_RUN_TEST(mf_classic_reader);
MU_RUN_TEST(mf_classic_reader);
MU_RUN_TEST(mf_classic_write);
MU_RUN_TEST(mf_classic_value_block);
MU_RUN_TEST(mf_classic_send_frame_test);
MU_RUN_TEST(mf_classic_dict_test);
nfc_test_free();
}
int run_minunit_test_nfc() {
int run_minunit_test_nfc(void) {
MU_RUN_SUITE(nfc);
return MU_EXIT_CODE;
}

View file

@ -115,7 +115,7 @@ static void nfc_prepare_col_res_data(
}
}
Nfc* nfc_alloc() {
Nfc* nfc_alloc(void) {
Nfc* instance = malloc(sizeof(Nfc));
return instance;

View file

@ -63,7 +63,7 @@ MU_TEST_SUITE(test_power_suite) {
power_test_deinit();
}
int run_minunit_test_power() {
int run_minunit_test_power(void) {
MU_RUN_SUITE(test_power_suite);
return MU_EXIT_CODE;
}

View file

@ -18,7 +18,7 @@ typedef struct {
static const uint32_t protocol_0_decoder_result = 0xDEADBEEF;
static void* protocol_0_alloc() {
static void* protocol_0_alloc(void) {
void* data = malloc(sizeof(Protocol0Data));
return data;
}
@ -63,7 +63,7 @@ typedef struct {
static const uint64_t protocol_1_decoder_result = 0x1234567890ABCDEF;
static void* protocol_1_alloc() {
static void* protocol_1_alloc(void) {
void* data = malloc(sizeof(Protocol1Data));
return data;
}
@ -216,7 +216,7 @@ MU_TEST_SUITE(test_protocol_dict_suite) {
MU_RUN_TEST(test_protocol_dict);
}
int run_minunit_test_protocol_dict() {
int run_minunit_test_protocol_dict(void) {
MU_RUN_SUITE(test_protocol_dict_suite);
return MU_EXIT_CODE;
}

View file

@ -0,0 +1,205 @@
Filetype: IR tests file
Version: 1
#
name: decoder_input1
type: raw
data: 25557 8437 4188 571 1538 595 1514 567 1542 570 1539 573 501 565 1544 568 506 571 1539 573 501 565 509 568 508 569 506 571 1538 574 501 565 1543 569 506 571 504 573 1536 566 1544 568 506 592 1517 574 1535 567 507 570 505 572 1537 575 500 566 508 600 1509 572 503 574 501 565 1544 568 1540 593
#
name: decoder_expected1
type: parsed_array
count: 1
#
protocol: Pioneer
address: AF 00 00 00
command: 36 00 00 00
repeat: false
#
name: decoder_input2
type: raw
data: 25609 8444 4152 564 1568 544 1565 547 1561 541 1568 544 530 547 1536 566 510 567 1567 545 529 548 526 540 535 542 508 569 1539 573 527 539 1543 569 506 571 504 573 1561 541 508 569 507 570 1538 564 1545 567 507 570 505 572 1537 565 509 568 1541 571 1538 564 511 566 509 568 1539 573 1537 596
#
name: decoder_expected2
type: parsed_array
count: 1
#
protocol: Pioneer
address: AF 00 00 00
command: 32 00 00 00
repeat: false
#
name: decoder_input3
type: raw
data: 25582 8448 4176 571 1537 565 1544 568 1540 572 1537 575 500 566 1542 570 505 572 1537 575 500 566 508 569 506 571 504 573 1536 565 510 567 1542 570 504 573 1536 566 1543 569 506 571 504 573 1536 566 1543 569 506 571 504 573 502 575 500 566 1542 570 1539 573 502 575 500 566 1542 570 1540 572
#
name: decoder_expected3
type: parsed_array
count: 1
#
protocol: Pioneer
address: AF 00 00 00
command: 33 00 00 00
repeat: false
#
name: decoder_input4
type: raw
data: 25594 8443 4181 568 1542 570 505 572 1538 564 1545 567 508 569 1540 572 504 573 1536 566 510 567 1542 571 505 572 504 573 1562 540 510 567 1543 570 506 571 504 573 503 574 501 565 510 567 509 568 507 570 1539 573 502 565 1545 568 1542 571 1539 573 1536 566 1544 569 1541 572 503 574 1537 565
#
name: decoder_expected4
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 40 00 00 00
repeat: false
#
name: decoder_input5
type: raw
data: 25556 8475 4150 597 1512 600 476 601 1509 603 1506 595 480 597 1512 600 476 601 1508 594 482 595 1515 597 478 599 477 600 1510 602 473 604 1506 595 480 597 1513 599 476 601 475 602 474 603 472 594 482 595 1514 598 477 600 476 601 1508 594 1516 596 1513 599 1510 602 1507 595 480 597 1513 599
#
name: decoder_expected5
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 41 00 00 00
repeat: false
#
name: decoder_input6
type: raw
data: 25567 8471 4155 604 1506 596 480 597 1513 599 1510 603 473 594 1515 597 478 599 1511 602 474 603 1507 595 480 597 479 598 1511 602 474 603 1506 596 480 597 478 599 1511 602 474 603 472 594 481 596 479 598 1512 601 474 603 1506 596 479 598 1511 602 1508 594 1515 598 1512 600 475 602 1507 595
#
name: decoder_expected6
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 42 00 00 00
repeat: false
#
name: decoder_input7
type: raw
data: 25584 8444 4180 569 1541 572 504 573 1536 566 1544 569 507 570 1539 574 501 566 1569 596 455 570 1540 573 502 575 501 565 1544 569 507 570 1565 548 503 574 1535 567 1543 570 506 571 529 548 502 565 511 566 1543 601 475 571 504 573 503 574 1536 566 1543 570 1539 574 1536 566 509 568 1541 572
#
name: decoder_expected7
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 43 00 00 00
repeat: false
#
name: decoder_input8
type: raw
data: 25562 8445 4181 568 1543 570 505 572 1538 575 1535 567 508 569 1539 573 503 595 1514 567 508 600 1509 572 503 595 481 596 1513 568 507 601 1508 573 502 575 501 566 1543 570 506 571 504 573 1536 566 510 567 508 600 475 571 1539 573 502 575 1534 568 1542 571 505 572 1537 575 1534 568 1542 571
#
name: decoder_expected8
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 12 00 00 00
repeat: false
#
name: decoder_input9
type: raw
data: 25558 8470 4152 597 1513 600 476 601 1508 594 1515 598 478 599 1509 593 483 594 1515 598 478 599 1510 603 474 592 482 595 1514 599 477 600 1509 593 483 594 481 596 1513 600 476 601 1508 594 1515 598 478 599 476 601 474 593 1517 596 479 598 1512 601 474 603 472 594 1515 598 1511 602 1508 594
#
name: decoder_expected9
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 1A 00 00 00
repeat: false
#
name: decoder_input10
type: raw
data: 25587 8442 4179 601 1507 595 481 565 1544 600 1509 593 482 595 1513 568 507 570 1539 594 481 565 1544 600 476 570 505 593 1516 597 479 598 1511 591 484 593 481 575 1534 600 476 570 1539 595 480 597 478 599 476 570 505 593 1517 564 511 597 1511 602 474 572 1537 597 1513 600 1509 572 1537 565
#
name: decoder_expected10
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 0A 00 00 00
repeat: false
#
name: decoder_input11
type: raw
data: 25554 8474 4149 600 1510 603 472 594 1515 597 1512 601 475 602 1507 595 480 597 1513 599 475 602 1508 594 481 596 479 598 1512 601 474 603 1506 596 479 598 1512 601 1508 594 481 596 1513 599 476 601 474 603 472 594 481 596 480 597 478 599 1510 603 473 593 1515 597 1512 601 1509 603 1506 596
#
name: decoder_expected11
type: parsed_array
count: 1
#
protocol: Pioneer
address: AD 00 00 00
command: 0B 00 00 00
repeat: false
#
name: encoder_decoder_input1
type: parsed_array
count: 11
#
protocol: Pioneer
address: AF 00 00 00
command: 36 00 00 00
repeat: false
#
protocol: Pioneer
address: AF 00 00 00
command: 32 00 00 00
repeat: false
#
protocol: Pioneer
address: AF 00 00 00
command: 33 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 40 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 41 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 42 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 43 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 12 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 1A 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 0A 00 00 00
repeat: false
#
protocol: Pioneer
address: AD 00 00 00
command: 0B 00 00 00
repeat: false
#

View file

@ -1840,7 +1840,7 @@ MU_TEST_SUITE(test_rpc_session) {
furi_record_close(RECORD_STORAGE);
}
int run_minunit_test_rpc() {
int run_minunit_test_rpc(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
if(storage_sd_status(storage) != FSE_OK) {
FURI_LOG_E(TAG, "SD card not mounted - skip storage tests");

View file

@ -266,7 +266,7 @@ MU_TEST_SUITE(test_dirwalk_suite) {
furi_record_close(RECORD_STORAGE);
}
int run_minunit_test_dirwalk() {
int run_minunit_test_dirwalk(void) {
MU_RUN_SUITE(test_dirwalk_suite);
return MU_EXIT_CODE;
}

View file

@ -36,7 +36,7 @@ static bool storage_file_create(Storage* storage, const char* path, const char*
return result;
}
static void storage_file_open_lock_setup() {
static void storage_file_open_lock_setup(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
File* file = storage_file_alloc(storage);
storage_simply_remove(storage, STORAGE_LOCKED_FILE);
@ -47,7 +47,7 @@ static void storage_file_open_lock_setup() {
furi_record_close(RECORD_STORAGE);
}
static void storage_file_open_lock_teardown() {
static void storage_file_open_lock_teardown(void) {
Storage* storage = furi_record_open(RECORD_STORAGE);
mu_check(storage_simply_remove(storage, STORAGE_LOCKED_FILE));
furi_record_close(RECORD_STORAGE);
@ -702,7 +702,7 @@ MU_TEST_SUITE(test_md5_calc_suite) {
MU_RUN_TEST(test_md5_calc);
}
int run_minunit_test_storage() {
int run_minunit_test_storage(void) {
MU_RUN_SUITE(storage_file);
MU_RUN_SUITE(storage_file_64k);
MU_RUN_SUITE(storage_dir);

View file

@ -526,7 +526,7 @@ MU_TEST_SUITE(stream_suite) {
MU_RUN_TEST(stream_buffered_large_file_test);
}
int run_minunit_test_stream() {
int run_minunit_test_stream(void) {
MU_RUN_SUITE(stream_suite);
return MU_EXIT_CODE;
}

View file

@ -314,7 +314,7 @@ static LevelDuration subghz_hal_async_tx_test_yield(void* context) {
furi_crash("Yield after reset");
}
} else {
furi_crash("Programming error");
furi_crash();
}
}
@ -904,7 +904,7 @@ MU_TEST_SUITE(subghz) {
subghz_test_deinit();
}
int run_minunit_test_subghz() {
int run_minunit_test_subghz(void) {
MU_RUN_SUITE(subghz);
return MU_EXIT_CODE;
}

View file

@ -8,31 +8,31 @@
#define TAG "UnitTests"
int run_minunit_test_furi();
int run_minunit_test_furi_hal();
int run_minunit_test_furi_hal_crypto();
int run_minunit_test_furi_string();
int run_minunit_test_infrared();
int run_minunit_test_rpc();
int run_minunit_test_manifest();
int run_minunit_test_flipper_format();
int run_minunit_test_flipper_format_string();
int run_minunit_test_stream();
int run_minunit_test_storage();
int run_minunit_test_subghz();
int run_minunit_test_dirwalk();
int run_minunit_test_power();
int run_minunit_test_protocol_dict();
int run_minunit_test_lfrfid_protocols();
int run_minunit_test_nfc();
int run_minunit_test_bit_lib();
int run_minunit_test_datetime();
int run_minunit_test_float_tools();
int run_minunit_test_bt();
int run_minunit_test_dialogs_file_browser_options();
int run_minunit_test_expansion();
int run_minunit_test_furi(void);
int run_minunit_test_furi_hal(void);
int run_minunit_test_furi_hal_crypto(void);
int run_minunit_test_furi_string(void);
int run_minunit_test_infrared(void);
int run_minunit_test_rpc(void);
int run_minunit_test_manifest(void);
int run_minunit_test_flipper_format(void);
int run_minunit_test_flipper_format_string(void);
int run_minunit_test_stream(void);
int run_minunit_test_storage(void);
int run_minunit_test_subghz(void);
int run_minunit_test_dirwalk(void);
int run_minunit_test_power(void);
int run_minunit_test_protocol_dict(void);
int run_minunit_test_lfrfid_protocols(void);
int run_minunit_test_nfc(void);
int run_minunit_test_bit_lib(void);
int run_minunit_test_datetime(void);
int run_minunit_test_float_tools(void);
int run_minunit_test_bt(void);
int run_minunit_test_dialogs_file_browser_options(void);
int run_minunit_test_expansion(void);
typedef int (*UnitTestEntry)();
typedef int (*UnitTestEntry)(void);
typedef struct {
const char* name;
@ -66,7 +66,7 @@ const UnitTest unit_tests[] = {
{.name = "expansion", .entry = run_minunit_test_expansion},
};
void minunit_print_progress() {
void minunit_print_progress(void) {
static const char progress[] = {'\\', '|', '/', '-'};
static uint8_t progress_counter = 0;
static uint32_t last_tick = 0;
@ -157,7 +157,7 @@ void unit_tests_cli(Cli* cli, FuriString* args, void* context) {
furi_record_close(RECORD_LOADER);
}
void unit_tests_on_system_start() {
void unit_tests_on_system_start(void) {
#ifdef SRV_CLI
Cli* cli = furi_record_open(RECORD_CLI);

View file

@ -82,7 +82,7 @@ MU_TEST_SUITE(test_varint_suite) {
MU_RUN_TEST(test_varint_rand_i);
}
int run_minunit_test_varint() {
int run_minunit_test_varint(void) {
MU_RUN_SUITE(test_varint_suite);
return MU_EXIT_CODE;
}

View file

@ -55,7 +55,7 @@ uint32_t usb_test_exit(void* context) {
return VIEW_NONE;
}
UsbTestApp* usb_test_app_alloc() {
UsbTestApp* usb_test_app_alloc(void) {
UsbTestApp* app = malloc(sizeof(UsbTestApp));
// Gui

View file

@ -93,7 +93,7 @@ typedef struct {
static SubGhzDeviceCC1101Ext* subghz_device_cc1101_ext = NULL;
static bool subghz_device_cc1101_ext_check_init() {
static bool subghz_device_cc1101_ext_check_init(void) {
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateInit);
subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle;
@ -177,6 +177,14 @@ static bool subghz_device_cc1101_ext_check_init() {
furi_hal_gpio_init(
subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
// Reset GDO2 (!TX/RX) to floating state
cc1101_status = cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance);
if(cc1101_status.CHIP_RDYn != 0) {
//timeout or error
break;
}
// Go to sleep
cc1101_status = cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle);
if(cc1101_status.CHIP_RDYn != 0) {
@ -198,7 +206,7 @@ static bool subghz_device_cc1101_ext_check_init() {
return ret;
}
bool subghz_device_cc1101_ext_alloc() {
bool subghz_device_cc1101_ext_alloc(void) {
furi_assert(subghz_device_cc1101_ext == NULL);
subghz_device_cc1101_ext = malloc(sizeof(SubGhzDeviceCC1101Ext));
subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateInit;
@ -213,7 +221,7 @@ bool subghz_device_cc1101_ext_alloc() {
return subghz_device_cc1101_ext_check_init();
}
void subghz_device_cc1101_ext_free() {
void subghz_device_cc1101_ext_free(void) {
furi_assert(subghz_device_cc1101_ext != NULL);
furi_hal_spi_bus_handle_deinit(subghz_device_cc1101_ext->spi_bus_handle);
free(subghz_device_cc1101_ext);
@ -224,11 +232,11 @@ void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin) {
subghz_device_cc1101_ext->async_mirror_pin = pin;
}
const GpioPin* subghz_device_cc1101_ext_get_data_gpio() {
const GpioPin* subghz_device_cc1101_ext_get_data_gpio(void) {
return subghz_device_cc1101_ext->g0_pin;
}
bool subghz_device_cc1101_ext_is_connect() {
bool subghz_device_cc1101_ext_is_connect(void) {
bool ret = false;
if(subghz_device_cc1101_ext == NULL) { // not initialized
@ -244,7 +252,7 @@ bool subghz_device_cc1101_ext_is_connect() {
return ret;
}
void subghz_device_cc1101_ext_sleep() {
void subghz_device_cc1101_ext_sleep(void) {
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateIdle);
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
@ -259,7 +267,7 @@ void subghz_device_cc1101_ext_sleep() {
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_dump_state() {
void subghz_device_cc1101_ext_dump_state(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
printf(
"[subghz_device_cc1101_ext] cc1101 chip %d, version %d\r\n",
@ -324,19 +332,19 @@ void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size) {
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_flush_rx() {
void subghz_device_cc1101_ext_flush_rx(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_flush_rx(subghz_device_cc1101_ext->spi_bus_handle);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_flush_tx() {
void subghz_device_cc1101_ext_flush_tx(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_flush_tx(subghz_device_cc1101_ext->spi_bus_handle);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
bool subghz_device_cc1101_ext_rx_pipe_not_empty() {
bool subghz_device_cc1101_ext_rx_pipe_not_empty(void) {
CC1101RxBytes status[1];
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_read_reg(
@ -351,7 +359,7 @@ bool subghz_device_cc1101_ext_rx_pipe_not_empty() {
}
}
bool subghz_device_cc1101_ext_is_rx_data_crc_valid() {
bool subghz_device_cc1101_ext_is_rx_data_crc_valid(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
uint8_t data[1];
cc1101_read_reg(
@ -370,14 +378,14 @@ void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size) {
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_shutdown() {
void subghz_device_cc1101_ext_shutdown(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
// Reset and shutdown
cc1101_shutdown(subghz_device_cc1101_ext->spi_bus_handle);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_reset() {
void subghz_device_cc1101_ext_reset(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
furi_hal_gpio_init(subghz_device_cc1101_ext->g0_pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle);
@ -385,39 +393,51 @@ void subghz_device_cc1101_ext_reset() {
// Warning: push pull cc1101 clock output on GD0
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG0, CC1101IocfgHighImpedance);
// Reset GDO2 (!TX/RX) to floating state
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_idle() {
void subghz_device_cc1101_ext_idle(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_switch_to_idle(subghz_device_cc1101_ext->spi_bus_handle);
//waiting for the chip to switch to IDLE mode
furi_check(cc1101_wait_status_state(
subghz_device_cc1101_ext->spi_bus_handle, CC1101StateIDLE, 10000));
// Reset GDO2 (!TX/RX) to floating state
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHighImpedance);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
void subghz_device_cc1101_ext_rx() {
void subghz_device_cc1101_ext_rx(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_switch_to_rx(subghz_device_cc1101_ext->spi_bus_handle);
//waiting for the chip to switch to Rx mode
furi_check(
cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateRX, 10000));
// Go GDO2 (!TX/RX) to high (RX state)
cc1101_write_reg(
subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW | CC1101_IOCFG_INV);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
}
bool subghz_device_cc1101_ext_tx() {
bool subghz_device_cc1101_ext_tx(void) {
if(subghz_device_cc1101_ext->regulation != SubGhzDeviceCC1101ExtRegulationTxRx) return false;
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
cc1101_switch_to_tx(subghz_device_cc1101_ext->spi_bus_handle);
//waiting for the chip to switch to Tx mode
furi_check(
cc1101_wait_status_state(subghz_device_cc1101_ext->spi_bus_handle, CC1101StateTX, 10000));
// Go GDO2 (!TX/RX) to low (TX state)
cc1101_write_reg(subghz_device_cc1101_ext->spi_bus_handle, CC1101_IOCFG2, CC1101IocfgHW);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
return true;
}
float subghz_device_cc1101_ext_get_rssi() {
float subghz_device_cc1101_ext_get_rssi(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
int32_t rssi_dec = cc1101_get_rssi(subghz_device_cc1101_ext->spi_bus_handle);
furi_hal_spi_release(subghz_device_cc1101_ext->spi_bus_handle);
@ -432,7 +452,7 @@ float subghz_device_cc1101_ext_get_rssi() {
return rssi;
}
uint8_t subghz_device_cc1101_ext_get_lqi() {
uint8_t subghz_device_cc1101_ext_get_lqi(void) {
furi_hal_spi_acquire(subghz_device_cc1101_ext->spi_bus_handle);
uint8_t data[1];
cc1101_read_reg(
@ -472,7 +492,7 @@ uint32_t subghz_device_cc1101_ext_set_frequency(uint32_t value) {
return real_frequency;
}
static bool subghz_device_cc1101_ext_start_debug() {
static bool subghz_device_cc1101_ext_start_debug(void) {
bool ret = false;
if(subghz_device_cc1101_ext->async_mirror_pin != NULL) {
furi_hal_gpio_init(
@ -485,7 +505,7 @@ static bool subghz_device_cc1101_ext_start_debug() {
return ret;
}
static bool subghz_device_cc1101_ext_stop_debug() {
static bool subghz_device_cc1101_ext_stop_debug(void) {
bool ret = false;
if(subghz_device_cc1101_ext->async_mirror_pin != NULL) {
furi_hal_gpio_init(
@ -495,7 +515,8 @@ static bool subghz_device_cc1101_ext_stop_debug() {
return ret;
}
static void subghz_device_cc1101_ext_capture_ISR() {
static void subghz_device_cc1101_ext_capture_ISR(void* context) {
UNUSED(context);
if(!furi_hal_gpio_read(subghz_device_cc1101_ext->g0_pin)) {
if(subghz_device_cc1101_ext->async_rx.capture_callback) {
if(subghz_device_cc1101_ext->async_mirror_pin != NULL)
@ -566,7 +587,7 @@ void subghz_device_cc1101_ext_start_async_rx(
subghz_device_cc1101_ext->async_rx.capture_delta_duration = 0;
}
void subghz_device_cc1101_ext_stop_async_rx() {
void subghz_device_cc1101_ext_stop_async_rx(void) {
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncRx);
subghz_device_cc1101_ext->state = SubGhzDeviceCC1101ExtStateIdle;
@ -674,7 +695,8 @@ static void subghz_device_cc1101_ext_async_tx_refill(uint32_t* buffer, size_t sa
}
}
static void subghz_device_cc1101_ext_async_tx_dma_isr() {
static void subghz_device_cc1101_ext_async_tx_dma_isr(void* context) {
UNUSED(context);
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx);
#if SUBGHZ_DEVICE_CC1101_EXT_DMA_CH3_CHANNEL == LL_DMA_CHANNEL_3
@ -803,13 +825,13 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
return true;
}
bool subghz_device_cc1101_ext_is_async_tx_complete() {
bool subghz_device_cc1101_ext_is_async_tx_complete(void) {
return (
(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx) &&
(LL_TIM_GetAutoReload(TIM17) == 0));
}
void subghz_device_cc1101_ext_stop_async_tx() {
void subghz_device_cc1101_ext_stop_async_tx(void) {
furi_assert(subghz_device_cc1101_ext->state == SubGhzDeviceCC1101ExtStateAsyncTx);
// Shutdown radio

View file

@ -1,6 +1,6 @@
/**
* @file furi_hal_subghz.h
* SubGhz HAL API
* @file cc1101_ext.h
* @brief External CC1101 transceiver access API.
*/
#pragma once
@ -28,31 +28,31 @@ void subghz_device_cc1101_ext_set_async_mirror_pin(const GpioPin* pin);
*
* @return pointer to the gpio pin structure
*/
const GpioPin* subghz_device_cc1101_ext_get_data_gpio();
const GpioPin* subghz_device_cc1101_ext_get_data_gpio(void);
/** Initialize device
*
* @return true if success
*/
bool subghz_device_cc1101_ext_alloc();
bool subghz_device_cc1101_ext_alloc(void);
/** Deinitialize device
*/
void subghz_device_cc1101_ext_free();
void subghz_device_cc1101_ext_free(void);
/** Check and switch to power save mode Used by internal API-HAL
* initialization routine Can be used to reinitialize device to safe state and
* send it to sleep
*/
bool subghz_device_cc1101_ext_is_connect();
bool subghz_device_cc1101_ext_is_connect(void);
/** Send device to sleep mode
*/
void subghz_device_cc1101_ext_sleep();
void subghz_device_cc1101_ext_sleep(void);
/** Dump info to stdout
*/
void subghz_device_cc1101_ext_dump_state();
void subghz_device_cc1101_ext_dump_state(void);
/** Load custom registers from preset
*
@ -83,13 +83,13 @@ void subghz_device_cc1101_ext_write_packet(const uint8_t* data, uint8_t size);
*
* @return true if not empty
*/
bool subghz_device_cc1101_ext_rx_pipe_not_empty();
bool subghz_device_cc1101_ext_rx_pipe_not_empty(void);
/** Check if received data crc is valid
*
* @return true if valid
*/
bool subghz_device_cc1101_ext_is_rx_data_crc_valid();
bool subghz_device_cc1101_ext_is_rx_data_crc_valid(void);
/** Read packet from FIFO
*
@ -100,47 +100,47 @@ void subghz_device_cc1101_ext_read_packet(uint8_t* data, uint8_t* size);
/** Flush rx FIFO buffer
*/
void subghz_device_cc1101_ext_flush_rx();
void subghz_device_cc1101_ext_flush_rx(void);
/** Flush tx FIFO buffer
*/
void subghz_device_cc1101_ext_flush_tx();
void subghz_device_cc1101_ext_flush_tx(void);
/** Shutdown Issue SPWD command
* @warning registers content will be lost
*/
void subghz_device_cc1101_ext_shutdown();
void subghz_device_cc1101_ext_shutdown(void);
/** Reset Issue reset command
* @warning registers content will be lost
*/
void subghz_device_cc1101_ext_reset();
void subghz_device_cc1101_ext_reset(void);
/** Switch to Idle
*/
void subghz_device_cc1101_ext_idle();
void subghz_device_cc1101_ext_idle(void);
/** Switch to Receive
*/
void subghz_device_cc1101_ext_rx();
void subghz_device_cc1101_ext_rx(void);
/** Switch to Transmit
*
* @return true if the transfer is allowed by belonging to the region
*/
bool subghz_device_cc1101_ext_tx();
bool subghz_device_cc1101_ext_tx(void);
/** Get RSSI value in dBm
*
* @return RSSI value
*/
float subghz_device_cc1101_ext_get_rssi();
float subghz_device_cc1101_ext_get_rssi(void);
/** Get LQI
*
* @return LQI value
*/
uint8_t subghz_device_cc1101_ext_get_lqi();
uint8_t subghz_device_cc1101_ext_get_lqi(void);
/** Check if frequency is in valid range
*
@ -174,7 +174,7 @@ void subghz_device_cc1101_ext_start_async_rx(
/** Disable signal timings capture Resets GPIO and TIM2
*/
void subghz_device_cc1101_ext_stop_async_rx();
void subghz_device_cc1101_ext_stop_async_rx(void);
/** Async TX callback type
* @param context callback context
@ -195,11 +195,11 @@ bool subghz_device_cc1101_ext_start_async_tx(SubGhzDeviceCC1101ExtCallback callb
*
* @return true if TX complete
*/
bool subghz_device_cc1101_ext_is_async_tx_complete();
bool subghz_device_cc1101_ext_is_async_tx_complete(void);
/** Stop async transmission and cleanup resources Resets GPIO, TIM2, and DMA1
*/
void subghz_device_cc1101_ext_stop_async_tx();
void subghz_device_cc1101_ext_stop_async_tx(void);
#ifdef __cplusplus
}

View file

@ -105,6 +105,6 @@ static const FlipperAppPluginDescriptor subghz_device_cc1101_ext_descriptor = {
.entry_point = &subghz_device_cc1101_ext,
};
const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep() {
const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(void) {
return &subghz_device_cc1101_ext_descriptor;
}

View file

@ -5,4 +5,4 @@
typedef struct SubGhzDeviceCC1101Ext SubGhzDeviceCC1101Ext;
const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep();
const FlipperAppPluginDescriptor* subghz_device_cc1101_ext_ep(void);

View file

@ -0,0 +1,9 @@
App(
appid="example_adc",
name="Example: ADC",
apptype=FlipperAppType.EXTERNAL,
entry_point="example_adc_main",
requires=["gui"],
stack_size=1 * 1024,
fap_category="Examples",
)

View file

@ -0,0 +1,176 @@
/**
* @file example_adc.c
* @brief ADC example.
*/
#include <furi.h>
#include <furi_hal.h>
#include <gui/gui.h>
#include <gui/elements.h>
#include <input/input.h>
const uint8_t font[] =
"`\2\3\2\3\4\1\2\4\5\11\0\376\6\376\7\377\1M\2\263\3\370 \6\315\364\371\6!\12\315"
"\364\201\260\35\312Q\0\42\11\315tJI\316\13\0#\14\315\264\223dP*\203R'\1$\15\315\264"
"\262A\311\266D\251l\71\0%\15\315\264\7%\61)J\42\345 \0&\14\315\264\263$\13\223\266$"
"\7\1'\10\315\364\201\60\347\10(\10\315\364\32[\313\0)\11\315\64\322b[\35\2*\12\315\264\263"
"(\222j\71\15+\11\315\364I\331\226\23\1,\10\315\364\271\205Y\10-\10\315\364\31t\26\0.\10"
"\315\364\71\346(\0/\14\315\364\221\60\13\263\60\13C\0\60\13\315\264\245Jb)E:\12\61\12\315"
"\364\201Ll\333A\0\62\12\315\264\245bV\33r\20\63\13\315\264\245Z\232D\221\216\2\64\14\315\364"
"\201LJ\242!\313v\20\65\14\315t\207$\134\223(\322Q\0\66\13\315\264\245p\252D\221\216\2\67"
"\12\315t\207\60+\326a\0\70\13\315\264\245\222T\211\42\35\5\71\13\315\264\245J\24\215\221\216\2:"
"\11\315\364i\71!G\1;\12\315\364I\71!\314B\0<\11\315\364\341\254Z\7\1=\12\315\364)"
"C<\344$\0>\11\315\364\301\264V\207\1\77\12\315\264\245Z\35\312a\0@\14\315\264\245J\242$"
"J\272\203\0A\15\315\264\245J\224\14I\224D\71\10B\13\315t\247\312T\211\222\35\5C\12\315\264"
"\245JX\212t\24D\15\315t\247J\224DI\224\354(\0E\14\315t\207$\234\302p\310A\0F"
"\12\315t\207$\234\302:\1G\14\315\264\245J\230(Q\244\243\0H\17\315t\243$J\206$J\242"
"$\312A\0I\11\315\264\267\260m\7\1J\12\315\364\221\260%\212t\24K\14\315t\243\244\244iI"
"T\7\1L\11\315t\303\216C\16\2M\17\315t\243dH\206$J\242$\312A\0N\16\315t\243"
"D\251(Q\22%Q\16\2O\15\315\264\245J\224DI\24\351(\0P\12\315t\247J\224LaN"
"Q\15\315\264\245J\224DI\42\251\61\0R\14\315t\247J\224L\225(\7\1S\13\315\264\245\222\232"
"D\221\216\2T\10\315\264\267\260;\12U\16\315t\243$J\242$J\242HG\1V\15\315t\243$"
"J\242$Jj\71\14W\17\315t\243$J\242dH\206$\312A\0X\15\315t\243$\212\64\251\22"
"\345 \0Y\13\315t\243$Jja\35\6Z\12\315t\207\60k\34r\20[\10\315\264\264\260G\31"
"\134\12\315\264\303\64L\303\64\14]\10\315t\304\276\351\0^\11\315\364\201,\311\271\1_\7\315\364y"
"\35\4`\10\315t\322\234'\0a\14\315\364IK\224$R\222\203\0b\13\315t\303p\252D\311\216"
"\2c\12\315\364IR%\335A\0d\14\315\364\221\60Z\242$\212v\20e\12\315\364I\322\220\244;"
"\10f\12\315\364\221,\333\302:\12g\14\315\364IK\224D\321\30I\0h\14\315t\303p\252DI"
"\224\203\0i\12\315\364\201\34\21k;\10j\12\315\364\201\34\21\273e\0k\13\315t\303J\244%Q"
"\35\4l\10\315\264\305n;\10m\14\315\364)CRQ\22\245\216\1n\13\315\364)%\245\224D\71"
"\10o\12\315\364IR%\212t\24p\13\315\364)S%J\246\60\4q\13\315\364IK\224D\321X"
"\1r\11\315\364)%\245\230\23s\12\315\364I\313\232\354(\0t\13\315\364\201\60\333\302\64\7\1u"
"\15\315\364)Q\22%\211\224\344 \0v\13\315\364)Q\22%\265\34\6w\13\315\364)\25%Q\272"
"\203\0x\12\315\364)Q\244Iu\20y\15\315\364)Q\22%Q\64F\22\0z\12\315\364)CV"
"\33r\20{\12\315\364\212\265\64\254&\0|\7\315\264\302~\7}\12\315t\322\260\232\205\265\14~\11"
"\315\364II;\13\0\177\6\315\364\371\6\0\0\0\4\377\377\0";
#define FONT_HEIGHT (8u)
typedef float (*ValueConverter)(FuriHalAdcHandle* handle, uint16_t value);
typedef struct {
const GpioPinRecord* pin;
float value;
ValueConverter converter;
const char* suffix;
} DataItem;
typedef struct {
size_t count;
DataItem* items;
} Data;
const GpioPinRecord item_vref = {.name = "VREF", .channel = FuriHalAdcChannelVREFINT};
const GpioPinRecord item_temp = {.name = "TEMP", .channel = FuriHalAdcChannelTEMPSENSOR};
const GpioPinRecord item_vbat = {.name = "VBAT", .channel = FuriHalAdcChannelVBAT};
static void app_draw_callback(Canvas* canvas, void* ctx) {
furi_assert(ctx);
Data* data = ctx;
canvas_set_custom_u8g2_font(canvas, font);
char buffer[64];
int32_t x = 0, y = FONT_HEIGHT;
for(size_t i = 0; i < data->count; i++) {
if(i == canvas_height(canvas) / FONT_HEIGHT) {
x = 64;
y = FONT_HEIGHT;
}
snprintf(
buffer,
sizeof(buffer),
"%4s: %4.0f%s\n",
data->items[i].pin->name,
(double)data->items[i].value,
data->items[i].suffix);
canvas_draw_str(canvas, x, y, buffer);
y += FONT_HEIGHT;
}
}
static void app_input_callback(InputEvent* input_event, void* ctx) {
furi_assert(ctx);
FuriMessageQueue* event_queue = ctx;
furi_message_queue_put(event_queue, input_event, FuriWaitForever);
}
int32_t example_adc_main(void* p) {
UNUSED(p);
// Data
Data data = {};
for(size_t i = 0; i < gpio_pins_count; i++) {
if(gpio_pins[i].channel != FuriHalAdcChannelNone) {
data.count++;
}
}
data.count += 3; // Special channels
data.items = malloc(data.count * sizeof(DataItem));
size_t item_pos = 0;
for(size_t i = 0; i < gpio_pins_count; i++) {
if(gpio_pins[i].channel != FuriHalAdcChannelNone) {
furi_hal_gpio_init(gpio_pins[i].pin, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
data.items[item_pos].pin = &gpio_pins[i];
data.items[item_pos].converter = furi_hal_adc_convert_to_voltage;
data.items[item_pos].suffix = "mV";
item_pos++;
}
}
data.items[item_pos].pin = &item_vref;
data.items[item_pos].converter = furi_hal_adc_convert_vref;
data.items[item_pos].suffix = "mV";
item_pos++;
data.items[item_pos].pin = &item_temp;
data.items[item_pos].converter = furi_hal_adc_convert_temp;
data.items[item_pos].suffix = "C";
item_pos++;
data.items[item_pos].pin = &item_vbat;
data.items[item_pos].converter = furi_hal_adc_convert_vbat;
data.items[item_pos].suffix = "mV";
item_pos++;
furi_assert(item_pos == data.count);
// Alloc message queue
FuriMessageQueue* event_queue = furi_message_queue_alloc(8, sizeof(InputEvent));
// Configure view port
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, app_draw_callback, &data);
view_port_input_callback_set(view_port, app_input_callback, event_queue);
// Register view port in GUI
Gui* gui = furi_record_open(RECORD_GUI);
gui_add_view_port(gui, view_port, GuiLayerFullscreen);
// Initialize ADC
FuriHalAdcHandle* adc_handle = furi_hal_adc_acquire();
furi_hal_adc_configure(adc_handle);
// Process events
InputEvent event;
bool running = true;
while(running) {
if(furi_message_queue_get(event_queue, &event, 100) == FuriStatusOk) {
if(event.type == InputTypePress && event.key == InputKeyBack) {
running = false;
}
} else {
for(size_t i = 0; i < data.count; i++) {
data.items[i].value = data.items[i].converter(
adc_handle, furi_hal_adc_read(adc_handle, data.items[i].pin->channel));
}
view_port_update(view_port);
}
}
furi_hal_adc_release(adc_handle);
view_port_enabled_set(view_port, false);
gui_remove_view_port(gui, view_port);
view_port_free(view_port);
furi_message_queue_free(event_queue);
furi_record_close(RECORD_GUI);
free(data.items);
return 0;
}

View file

@ -1,7 +1,11 @@
# Apps Assets folder Example
# Apps Assets folder Example {#example_app_assets}
This example shows how to use the Apps Assets folder to store data that is not part of the application itself, but is required for its operation, and that data is provided with the application.
## Source code
Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_apps_assets).
## What is the Apps Assets Folder?
The **Apps Assets** folder is a folder where external applications unpack their assets.

View file

@ -1,3 +1,7 @@
/**
* @file example_apps_assets.c
* @brief Application assets example.
*/
#include <furi.h>
#include <storage/storage.h>
#include <toolbox/stream/stream.h>

View file

@ -1,7 +1,11 @@
# Apps Data folder Example
# Apps Data folder Example {#example_app_data}
This example demonstrates how to utilize the Apps Data folder to store data that is not part of the app itself, such as user data, configuration files, and so forth.
## Source code
Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_apps_data).
## What is the Apps Data Folder?
The **Apps Data** folder is a folder used to store data for external apps that are not part of the main firmware.

View file

@ -1,3 +1,7 @@
/**
* @file example_apps_data.c
* @brief Application data example.
*/
#include <furi.h>
#include <storage/storage.h>

View file

@ -57,7 +57,7 @@ static void ble_beacon_app_restore_beacon_state(BleBeaconApp* app) {
app->beacon_data_len = furi_hal_bt_extra_beacon_get_data(app->beacon_data);
}
static BleBeaconApp* ble_beacon_app_alloc() {
static BleBeaconApp* ble_beacon_app_alloc(void) {
BleBeaconApp* app = malloc(sizeof(BleBeaconApp));
app->gui = furi_record_open(RECORD_GUI);

View file

@ -1,3 +1,7 @@
/**
* @file ble_beacon_app.h
* @brief BLE beacon example.
*/
#pragma once
#include "extra_beacon.h"

View file

@ -1,3 +1,7 @@
/**
* @file example_custom_font.c
* @brief Custom font example.
*/
#include <furi.h>
#include <furi_hal.h>
@ -7,35 +11,62 @@
//This arrays contains the font itself. You can use any u8g2 font you want
/*
Fontname: -Raccoon-Fixed4x6-Medium-R-Normal--6-60-75-75-P-40-ISO10646-1
Copyright:
Glyphs: 95/203
BBX Build Mode: 0
Fontname: -Misc-Fixed-Medium-R-Normal--6-60-75-75-C-40-ISO10646-1
Copyright: Public domain font. Share and enjoy.
Glyphs: 191/919
BBX Build Mode: 0
*/
const uint8_t u8g2_font_tom_thumb_4x6_tr[725] =
"_\0\2\2\2\3\3\4\4\3\6\0\377\5\377\5\0\0\352\1\330\2\270 \5\340\315\0!\6\265\310"
"\254\0\42\6\213\313$\25#\10\227\310\244\241\206\12$\10\227\310\215\70b\2%\10\227\310d\324F\1"
"&\10\227\310(\65R\22'\5\251\313\10(\6\266\310\251\62)\10\226\310\304\224\24\0*\6\217\312\244"
"\16+\7\217\311\245\225\0,\6\212\310)\0-\5\207\312\14.\5\245\310\4/\7\227\310Ve\4\60"
"\7\227\310-k\1\61\6\226\310\255\6\62\10\227\310h\220\312\1\63\11\227\310h\220\62X\0\64\10\227"
"\310$\65b\1\65\10\227\310\214\250\301\2\66\10\227\310\315\221F\0\67\10\227\310\314TF\0\70\10\227"
"\310\214\64\324\10\71\10\227\310\214\64\342\2:\6\255\311\244\0;\7\222\310e\240\0<\10\227\310\246\32"
"d\20=\6\217\311l\60>\11\227\310d\220A*\1\77\10\227\310\314\224a\2@\10\227\310UC\3"
"\1A\10\227\310UC\251\0B\10\227\310\250\264\322\2C\7\227\310\315\32\10D\10\227\310\250d-\0"
"E\10\227\310\214\70\342\0F\10\227\310\214\70b\4G\10\227\310\315\221\222\0H\10\227\310$\65\224\12"
"I\7\227\310\254X\15J\7\227\310\226\252\2K\10\227\310$\265\222\12L\7\227\310\304\346\0M\10\227"
"\310\244\61\224\12N\10\227\310\244q\250\0O\7\227\310UV\5P\10\227\310\250\264b\4Q\10\227\310"
"Uj$\1R\10\227\310\250\64V\1S\10\227\310m\220\301\2T\7\227\310\254\330\2U\7\227\310$"
"W\22V\10\227\310$\253L\0W\10\227\310$\65\206\12X\10\227\310$\325R\1Y\10\227\310$U"
"V\0Z\7\227\310\314T\16[\7\227\310\214X\16\134\10\217\311d\220A\0]\7\227\310\314r\4^"
"\5\213\313\65_\5\207\310\14`\6\212\313\304\0a\7\223\310\310\65\2b\10\227\310D\225\324\2c\7"
"\223\310\315\14\4d\10\227\310\246\245\222\0e\6\223\310\235\2f\10\227\310\246\264b\2g\10\227\307\35"
"\61%\0h\10\227\310D\225\254\0i\6\265\310\244\1j\10\233\307f\30U\5k\10\227\310\304\264T"
"\1l\7\227\310\310\326\0m\7\223\310<R\0n\7\223\310\250d\5o\7\223\310U\252\2p\10\227"
"\307\250\244V\4q\10\227\307-\225d\0r\6\223\310\315\22s\10\223\310\215\70\22\0t\10\227\310\245"
"\25\243\0u\7\223\310$+\11v\10\223\310$\65R\2w\7\223\310\244q\4x\7\223\310\244\62\25"
"y\11\227\307$\225dJ\0z\7\223\310\254\221\6{\10\227\310\251\32D\1|\6\265\310(\1}\11"
"\227\310\310\14RR\0~\6\213\313\215\4\0\0\0\4\377\377\0";
const uint8_t u8g2_font_4x6_t_cyrillic[] =
"\277\0\2\2\3\3\2\4\4\4\6\0\377\5\377\5\377\0\356\1\334\2\301 \5\200\315\0!\6\351\310"
"\254\0\42\6\223\313$\25#\12\254\310\244\64T\32*\1$\11\263\307\245\241\301H\11%\10\253\310d"
"\324F\1&\11\254\310\305\24\253\230\2'\5\321\313\10(\7\362\307\251f\0)\10\262\307\304T)\0"
"*\7\253\310\244j\65+\10\253\310\305\264b\2,\6\222\307)\0-\5\213\312\14.\5\311\310\4/"
"\7\253\310Ve\4\60\10\253\310UCU\0\61\7\253\310%Y\15\62\7\253\310\65S\32\63\10\253\310"
"\314\224\301\2\64\10\253\310$\65b\1\65\10\253\310\214\250\301\2\66\7\253\310M\325\2\67\10\253\310\314"
"TF\0\70\7\253\310\255\326\2\71\7\253\310\265\344\2:\6\341\310\304\0;\7\252\307e\250\0<\10"
"\253\310\246\32d\20=\6\233\311l\60>\11\253\310d\220A*\1\77\11\253\310h\220\62L\0@\7"
"\253\310-\33\10A\10\253\310UC\251\0B\10\253\310\250\264\322\2C\10\253\310U\62U\0D\10\253"
"\310\250d-\0E\10\253\310\214\250\342\0F\10\253\310\214\250b\4G\10\253\310\315\244\222\0H\10\253"
"\310$\65\224\12I\7\253\310\254X\15J\7\253\310\226\252\2K\10\253\310$\265\222\12L\7\253\310\304"
"\346\0M\10\253\310\244\61\224\12N\10\253\310\252\241$\0O\7\253\310UV\5P\10\253\310\250\264b"
"\4Q\10\263\307UV\15\2R\10\253\310\250\264\222\12S\10\253\310m\220\301\2T\7\253\310\254\330\2"
"U\7\253\310$\327\10V\10\253\310$k\244\4W\10\253\310$\65\206\12X\10\253\310$\325R\1Y"
"\10\253\310$UV\0Z\7\253\310\314T\16[\6\352\310\254J\134\11\253\310\304\14\62\210\1]\6\252"
"\310\250j^\5\223\313\65_\5\213\307\14`\6\322\313\304\0a\7\243\310-\225\4b\10\253\310D\225"
"\324\2c\7\243\310\315\14\4d\10\253\310\246\245\222\0e\6\243\310USf\10\253\310\246\264b\2g"
"\10\253\307\255$\27\0h\10\253\310D\225\254\0i\10\253\310e$\323\0j\10\263\307fX.\0k"
"\10\253\310\304\264\222\12l\7\253\310\310\326\0m\10\243\310\244\241T\0n\7\243\310\250d\5o\7\243"
"\310U\252\2p\10\253\307\250\264b\4q\10\253\307-\225d\0r\10\243\310\244\25#\0s\10\243\310"
"\215\14\26\0t\10\253\310\245\25\63\10u\7\243\310$+\11v\7\243\310$\253\2w\10\243\310$\65"
"T\0x\7\243\310\244\62\25y\10\253\307$\225\344\2z\7\243\310\314\224\6{\10\263\307\246$k\20"
"|\6\351\310\14\1}\11\263\307d\20UL\21~\7\224\313%\225\0\0\0\0\4\377\377\4\1\11\253"
"\310\244\261\342\0\4\2\11\253\310\214\250\222\12\4\3\10\253\310\16Y\2\4\4\11\253\310M\225\201\0\4"
"\5\11\253\310m\220\301\2\4\6\10\253\310\254X\15\4\7\11\253\310\244\221b\32\4\10\10\253\310\226\252"
"\2\4\11\11\254\310L\325Z\2\4\12\11\254\310\244\326JK\4\13\11\253\310\250\250\222\12\4\14\10\253"
"\310\312\264\12\4\16\11\263\307\244\32u\2\4\17\11\263\307$\327H\11\4\20\11\253\310UC\251\0\4"
"\21\11\253\310\214\250\322\2\4\22\11\253\310\250\264\322\2\4\23\10\253\310\214\330\4\4\24\11\263\307\254\245"
"\206\12\4\25\11\253\310\214\250\342\0\4\26\12\253\310\244\221\322H\1\4\27\12\253\310h\220\62X\0\4"
"\30\11\253\310\304\64T\14\4\31\11\263\307\315\64T\14\4\32\11\253\310$\265\222\12\4\33\10\253\310-"
"W\0\4\34\11\253\310\244\241\254\0\4\35\11\253\310$\65\224\12\4\36\10\253\310UV\5\4\37\10\253"
"\310\214\344\12\4 \11\253\310\250\264b\4\4!\11\253\310U\62U\0\4\42\10\253\310\254\330\2\4#"
"\11\263\307$\253L\21\4$\12\253\310\245\221FJ\0\4%\11\253\310$\325R\1\4&\10\253\310$"
"\327\10\4'\11\253\310$\225d\1\4(\11\253\310$\65\216\0\4)\12\264\307\244\326#\203\0\4*"
"\13\254\310h\220\201LI\1\4+\12\254\310D\271\324H\1\4,\11\253\310\304\250\322\2\4-\11\253"
"\310h\220\344\2\4.\12\254\310\244\244.\225\0\4/\11\253\310\255\264T\0\4\60\10\243\310-\225\4"
"\4\61\11\253\310\315\221*\0\4\62\11\243\310\14\225\26\0\4\63\10\243\310\214X\2\4\64\11\253\307-"
"\65T\0\4\65\7\243\310US\4\66\11\244\310$S%\1\4\67\11\243\310\254\14\26\0\4\70\11\243"
"\310\244\61T\0\4\71\11\253\310\244\326P\1\4:\10\243\310$\265\12\4;\7\243\310-+\4<\11"
"\243\310\244\241T\0\4=\11\243\310\244\241T\0\4>\10\243\310U\252\2\4\77\10\243\310\214d\5\4"
"@\11\253\307\250\264b\4\4A\10\243\310\315\14\4\4B\10\243\310\254X\1\4C\11\253\307$\225\344"
"\2\4D\12\263\307\305\224T\231\0\4E\10\243\310\244\62\25\4F\11\253\307$k\304\0\4G\11\243"
"\310$\225d\0\4H\10\243\310\244q\4\4I\11\254\307\244\364\310 \4J\12\244\310h SR\0"
"\4K\11\244\310\304\245F\12\4L\11\243\310D\225\26\0\4M\10\243\310H\271\0\4N\12\244\310\244"
"\244\226J\0\4O\10\243\310\255\264\2\4Q\10\253\310\244\326\24\4R\11\263\307D\25U\31\4S\11"
"\253\310\246\64b\4\4T\11\243\310\215\224\201\0\4U\11\243\310\215\14\26\0\4V\11\253\310e$\323"
"\0\4W\11\253\310\244\14d\32\4X\11\263\307fX.\0\4Y\10\244\310\251\326\22\4Z\11\244\310"
"\244\264\322\22\4[\11\253\310D\25U\1\4\134\10\253\310\312\264\12\4^\11\263\307\244\32u\2\4_"
"\11\253\307$k\244\4\4\220\10\253\310\16Y\2\4\221\10\243\310\16\31\1\4\222\11\253\310\251\264b\2"
"\4\223\11\243\310\251\264\22\0\0";
// Screen is 128x64 px
static void app_draw_callback(Canvas* canvas, void* ctx) {
@ -43,10 +74,11 @@ static void app_draw_callback(Canvas* canvas, void* ctx) {
canvas_clear(canvas);
canvas_set_custom_u8g2_font(canvas, u8g2_font_tom_thumb_4x6_tr);
canvas_set_custom_u8g2_font(canvas, u8g2_font_4x6_t_cyrillic);
canvas_draw_str(canvas, 0, 6, "This is a tiny custom font");
canvas_draw_str(canvas, 0, 12, "012345.?! ,:;\"\'@#$%");
canvas_draw_str(canvas, 0, 18, "И немного юникода");
}
static void app_input_callback(InputEvent* input_event, void* ctx) {
@ -62,7 +94,7 @@ int32_t example_custom_font_main(void* p) {
// Configure view port
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, app_draw_callback, view_port);
view_port_draw_callback_set(view_port, app_draw_callback, NULL);
view_port_input_callback_set(view_port, app_input_callback, event_queue);
// Register view port in GUI

View file

@ -1,11 +1,21 @@
# Application icons
# Application icons {#example_app_images}
## Source code
Source code for this example can be found [here](https://github.com/flipperdevices/flipperzero-firmware/tree/dev/applications/examples/example_images).
## General principle
To use icons, do the following:
* add a line to the application manifest: `fap_icon_assets="folder"`, where `folder` points to the folder where your icons are located
* add `#include "application_id_icons.h"` to the application code, where `application_id` is the appid from the manifest
* every icon in the folder will be available as a `I_icon_name` variable, where `icon_name` is the name of the icon file without the extension
* Add a line to the application manifest: `fap_icon_assets="folder"`, where `folder` points to the folder where your icons are located
* Add `#include "application_id_icons.h"` to the application code, where `application_id` is the appid from the manifest
* Every icon in the folder will be available as a `I_icon_name` variable, where `icon_name` is the name of the icon file without the extension
## Example
We have an application with the following manifest:
```
App(
appid="example_images",
@ -17,6 +27,7 @@ App(
So the icons are in the `images` folder and will be available in the generated `example_images_icons.h` file.
The example code is located in `example_images_main.c` and contains the following line:
```
#include "example_images_icons.h"
```

View file

@ -1,3 +1,7 @@
/**
* @file example_images.c
* @brief Custom images example.
*/
#include <furi.h>
#include <furi_hal.h>
@ -9,7 +13,7 @@
#include "example_images_icons.h"
typedef struct {
uint8_t x, y;
int32_t x, y;
} ImagePosition;
static ImagePosition image_position = {.x = 0, .y = 0};
@ -19,7 +23,7 @@ static void app_draw_callback(Canvas* canvas, void* ctx) {
UNUSED(ctx);
canvas_clear(canvas);
canvas_draw_icon(canvas, image_position.x % 128, image_position.y % 64, &I_dolphin_71x25);
canvas_draw_icon(canvas, image_position.x, image_position.y, &I_dolphin_71x25);
}
static void app_input_callback(InputEvent* input_event, void* ctx) {
@ -35,7 +39,7 @@ int32_t example_images_main(void* p) {
// Configure view port
ViewPort* view_port = view_port_alloc();
view_port_draw_callback_set(view_port, app_draw_callback, view_port);
view_port_draw_callback_set(view_port, app_draw_callback, NULL);
view_port_input_callback_set(view_port, app_input_callback, event_queue);
// Register view port in GUI

View file

@ -1,5 +1,7 @@
/*
* An example of a plugin host application.
/**
* @file example_plugins.c
* @brief Plugin host application example.
*
* Loads a single plugin and calls its methods.
*/

View file

@ -1,5 +1,7 @@
/*
* An example of an advanced plugin host application.
/**
* @file example_plugins_multi.c
* @brief Advanced plugin host application example.
*
* It uses PluginManager to load all plugins from a directory
*/

View file

@ -1,10 +1,15 @@
/* A simple plugin implementing example_plugins application's plugin interface */
/**
* @file plugin1.c
* @brief Plugin example 1.
*
* A simple plugin implementing example_plugins application's plugin interface
*/
#include "plugin_interface.h"
#include <flipper_application/flipper_application.h>
static int example_plugin1_method1() {
static int example_plugin1_method1(void) {
return 42;
}
@ -27,6 +32,6 @@ static const FlipperAppPluginDescriptor example_plugin1_descriptor = {
};
/* Plugin entry point - must return a pointer to const descriptor */
const FlipperAppPluginDescriptor* example_plugin1_ep() {
const FlipperAppPluginDescriptor* example_plugin1_ep(void) {
return &example_plugin1_descriptor;
}

View file

@ -1,10 +1,15 @@
/* Second plugin implementing example_plugins application's plugin interface */
/**
* @file plugin2.c
* @brief Plugin example 2.
*
* Second plugin implementing example_plugins application's plugin interface
*/
#include "plugin_interface.h"
#include <flipper_application/flipper_application.h>
static int example_plugin2_method1() {
static int example_plugin2_method1(void) {
return 1337;
}
@ -27,6 +32,6 @@ static const FlipperAppPluginDescriptor example_plugin2_descriptor = {
};
/* Plugin entry point - must return a pointer to const descriptor */
const FlipperAppPluginDescriptor* example_plugin2_ep() {
const FlipperAppPluginDescriptor* example_plugin2_ep(void) {
return &example_plugin2_descriptor;
}

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