mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2025-12-12 20:49:49 +04:00
adaptation to the new build system + fixes
This commit is contained in:
15
.drone.yml
15
.drone.yml
@@ -11,23 +11,15 @@ steps:
|
|||||||
- git submodule foreach git config --local gc.auto 0
|
- git submodule foreach git config --local gc.auto 0
|
||||||
- git log -1 --format='%H'
|
- git log -1 --format='%H'
|
||||||
|
|
||||||
- name: 'Rebuild Assets'
|
|
||||||
image: hfdj/fztools
|
|
||||||
pull: never
|
|
||||||
commands:
|
|
||||||
- export DIST_SUFFIX=${DRONE_TAG}
|
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=${DRONE_TAG}
|
|
||||||
- make assets_rebuild assets_manifest
|
|
||||||
|
|
||||||
- name: 'Build default fw'
|
- name: 'Build default fw'
|
||||||
image: hfdj/fztools
|
image: hfdj/fztools
|
||||||
pull: never
|
pull: never
|
||||||
commands:
|
commands:
|
||||||
- export DIST_SUFFIX=${DRONE_TAG}
|
- export DIST_SUFFIX=${DRONE_TAG}
|
||||||
- export WORKFLOW_BRANCH_OR_TAG=${DRONE_TAG}
|
- export WORKFLOW_BRANCH_OR_TAG=dev-cfw
|
||||||
- make updater_package TARGET=f7 DEBUG=0 COMPACT=1
|
- ./fbt --with-updater COMPACT=1 DEBUG=0 updater_package
|
||||||
- mkdir artifacts-default
|
- mkdir artifacts-default
|
||||||
- mv dist/f7/* artifacts-default/
|
- mv dist/f7-C/* artifacts-default/
|
||||||
- ls -laS artifacts-default
|
- ls -laS artifacts-default
|
||||||
- ls -laS artifacts-default/f7-update-${DRONE_TAG}
|
- ls -laS artifacts-default/f7-update-${DRONE_TAG}
|
||||||
|
|
||||||
@@ -36,7 +28,6 @@ steps:
|
|||||||
commands:
|
commands:
|
||||||
- tar czpf artifacts-default/flipper-z-any-resources-${DRONE_TAG}.tgz -C assets resources
|
- tar czpf artifacts-default/flipper-z-any-resources-${DRONE_TAG}.tgz -C assets resources
|
||||||
- mkdir sd-card
|
- mkdir sd-card
|
||||||
- mkdir -p sd-card/wav_player
|
|
||||||
- mkdir -p sd-card/subghz/assets
|
- mkdir -p sd-card/subghz/assets
|
||||||
- mkdir -p sd-card/nfc/assets
|
- mkdir -p sd-card/nfc/assets
|
||||||
- cp assets/resources/subghz/assets/universal_rf_map sd-card/subghz/assets/universal_rf_map
|
- cp assets/resources/subghz/assets/universal_rf_map sd-card/subghz/assets/universal_rf_map
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
### New Update
|
### New Update
|
||||||
|
* Merged latest ofw changes - scons build system
|
||||||
|
* Removed WAV Player - it's not bad as a concept but has a lot of problems
|
||||||
|
* Some small fixes
|
||||||
|
#### Previous changes
|
||||||
* Spectrum Analyzer - show current mode on screen when changing modes
|
* Spectrum Analyzer - show current mode on screen when changing modes
|
||||||
* Spectrum Analyzer - Ultra Narrow mode
|
* Spectrum Analyzer - Ultra Narrow mode
|
||||||
* Desktop autolock more time options
|
* Desktop autolock more time options
|
||||||
* Merged latest ofw dev changes:
|
* Merged latest ofw dev changes:
|
||||||
SubGhz: PowerSmart protocol, Infrared app fixes
|
SubGhz: PowerSmart protocol, Infrared app fixes
|
||||||
#### Previous changes
|
|
||||||
* Merged latest ofw dev changes:
|
* Merged latest ofw dev changes:
|
||||||
Infrared app C port, nfc: NTAG21x complete emulation, nfc: DESFire fixes
|
Infrared app C port, nfc: NTAG21x complete emulation, nfc: DESFire fixes
|
||||||
SubGhz: frequency analyzer combined frequency detection method, etc...
|
SubGhz: frequency analyzer combined frequency detection method, etc...
|
||||||
|
|||||||
21
ReadMe.md
21
ReadMe.md
@@ -67,7 +67,7 @@ then select **`flipper-z-f7-full-(CURRENT VERSION).dfu`**
|
|||||||
|
|
||||||
- And wait, if all flashed successfully - you can manually upload IR libs and other stuff to sd card
|
- And wait, if all flashed successfully - you can manually upload IR libs and other stuff to sd card
|
||||||
|
|
||||||
- If you doing install for first time or migrating from official fw, unpack 3 folders from archive `sd-card-(CURRENT VERSION).zip` onto your microSD card
|
- If you doing install for first time or migrating from official fw, unpack 2 folders from archive `sd-card-(CURRENT VERSION).zip` onto your microSD card
|
||||||
|
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
@@ -85,13 +85,13 @@ then select **`flipper-z-f7-full-(CURRENT VERSION).dfu`**
|
|||||||
### **Replace (CURRENT VERSION) with version that you downloaded from releases**
|
### **Replace (CURRENT VERSION) with version that you downloaded from releases**
|
||||||
3. Run `dfu-util -D flipper-z-f7-full-(CURRENT VERSION).dfu -a 0`
|
3. Run `dfu-util -D flipper-z-f7-full-(CURRENT VERSION).dfu -a 0`
|
||||||
|
|
||||||
4. If you doing install for first time or migrating from official fw, unpack 3 folders from archive `sd-card-(CURRENT VERSION).zip` to your microSD card
|
4. If you doing install for first time or migrating from official fw, unpack 2 folders from archive `sd-card-(CURRENT VERSION).zip` to your microSD card
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
# After install:
|
# After install:
|
||||||
- ### If you installed using .dfu - unpack 3 folders from archive `sd-card-(CURRENT VERSION).zip` to your microSD card
|
- ### If you installed using .dfu - unpack 2 folders from archive `sd-card-(CURRENT VERSION).zip` to your microSD card
|
||||||
<br>
|
<br>
|
||||||
|
|
||||||
- ## [How To: Configure UniversalRF Remix App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/UniRFRemix.md)
|
- ## [How To: Configure UniversalRF Remix App](https://github.com/Eng1n33r/flipperzero-firmware/blob/dev/documentation/UniRFRemix.md)
|
||||||
@@ -128,13 +128,13 @@ $ git clone --recursive https://github.com/Eng1n33r/flipperzero-firmware.git
|
|||||||
### Compile everything for development
|
### Compile everything for development
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker-compose exec dev make
|
docker-compose exec dev ./fbt
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compile everything for release + get updater package to update from microSD card
|
### Compile everything for release + get updater package to update from microSD card
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
docker-compose exec dev make updater_package TARGET=f7 DEBUG=0 COMPACT=1
|
docker-compose exec dev ./fbt --with-updater COMPACT=1 DEBUG=0 updater_package
|
||||||
```
|
```
|
||||||
|
|
||||||
Check `dist/` for build outputs.
|
Check `dist/` for build outputs.
|
||||||
@@ -145,6 +145,8 @@ If compilation fails, make sure all submodules are all initialized. Either clone
|
|||||||
|
|
||||||
# Build on macOS
|
# Build on macOS
|
||||||
|
|
||||||
|
Check out `documentation/fbt.md` for details on building and flashing firmware.
|
||||||
|
|
||||||
## macOS Prerequisites
|
## macOS Prerequisites
|
||||||
|
|
||||||
Make sure you have [brew](https://brew.sh) and install all the dependencies:
|
Make sure you have [brew](https://brew.sh) and install all the dependencies:
|
||||||
@@ -152,18 +154,18 @@ Make sure you have [brew](https://brew.sh) and install all the dependencies:
|
|||||||
brew bundle --verbose
|
brew bundle --verbose
|
||||||
```
|
```
|
||||||
|
|
||||||
**P.S. Brewfile has been fixed, so build works now**
|
Install Python packages required by assets build scripts: `pip3 install -r scripts/requirements.txt`
|
||||||
|
|
||||||
### Compile everything for development
|
### Compile everything for development
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make
|
./fbt
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compile everything for release + get updater package to update from microSD card
|
### Compile everything for release + get updater package to update from microSD card
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
make updater_package TARGET=f7 DEBUG=0 COMPACT=1
|
./fbt --with-updater COMPACT=1 DEBUG=0 updater_package
|
||||||
```
|
```
|
||||||
|
|
||||||
Check `dist/` for build outputs.
|
Check `dist/` for build outputs.
|
||||||
@@ -174,7 +176,6 @@ Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
|
|||||||
|
|
||||||
- [Clock/Stopwatch (By CompaqDisc, Stopwatch & Sound Alert By RogueMaster)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/blob/unleashed/applications/clock_app/clock_app.c)
|
- [Clock/Stopwatch (By CompaqDisc, Stopwatch & Sound Alert By RogueMaster)](https://github.com/RogueMaster/flipperzero-firmware-wPlugins/blob/unleashed/applications/clock_app/clock_app.c)
|
||||||
- [UniversalRF Remix (By ESurge)(Original UniversalRF By jimilinuxguy)](https://github.com/ESurge/flipperzero-firmware-unirfremix)
|
- [UniversalRF Remix (By ESurge)(Original UniversalRF By jimilinuxguy)](https://github.com/ESurge/flipperzero-firmware-unirfremix)
|
||||||
- [WAV Player (By DrZlo13)](https://github.com/flipperdevices/flipperzero-firmware/tree/zlo/wav-player) With Fix From [Atmanos](https://github.com/at-manos)
|
|
||||||
- [Tetris (By jeffplang)](https://github.com/jeffplang/flipperzero-firmware/tree/tetris_game/applications/tetris_game)
|
- [Tetris (By jeffplang)](https://github.com/jeffplang/flipperzero-firmware/tree/tetris_game/applications/tetris_game)
|
||||||
- [Spectrum Analyzer (By jolcese)](https://github.com/jolcese/flipperzero-firmware/tree/spectrum/applications/spectrum_analyzer) - [Ultra Narrow mode & scan channels non-consecutively](https://github.com/theY4Kman/flipperzero-firmware/commits?author=theY4Kman)
|
- [Spectrum Analyzer (By jolcese)](https://github.com/jolcese/flipperzero-firmware/tree/spectrum/applications/spectrum_analyzer) - [Ultra Narrow mode & scan channels non-consecutively](https://github.com/theY4Kman/flipperzero-firmware/commits?author=theY4Kman)
|
||||||
- [Arkanoid (By gotnull)](https://github.com/gotnull/flipperzero-firmware-wPlugins)
|
- [Arkanoid (By gotnull)](https://github.com/gotnull/flipperzero-firmware-wPlugins)
|
||||||
@@ -198,7 +199,7 @@ Use **`flipper-z-{target}-full-{suffix}.dfu`** to flash your device.
|
|||||||
- `documentation` - Documentation generation system configs and input files
|
- `documentation` - Documentation generation system configs and input files
|
||||||
- `firmware` - Firmware source code
|
- `firmware` - Firmware source code
|
||||||
- `lib` - Our and 3rd party libraries, drivers and etc...
|
- `lib` - Our and 3rd party libraries, drivers and etc...
|
||||||
- `make` - Make helpers
|
- `site_scons` - Build helpers
|
||||||
- `scripts` - Supplementary scripts and python libraries home
|
- `scripts` - Supplementary scripts and python libraries home
|
||||||
|
|
||||||
Also pay attention to `ReadMe.md` files inside of those directories.
|
Also pay attention to `ReadMe.md` files inside of those directories.
|
||||||
|
|||||||
10
applications/arkanoid/application.fam
Normal file
10
applications/arkanoid/application.fam
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
App(
|
||||||
|
appid="arkanoid_game",
|
||||||
|
name="Arkanoid",
|
||||||
|
apptype=FlipperAppType.GAME,
|
||||||
|
entry_point="arkanoid_game_app",
|
||||||
|
cdefines=["APP_ARKANOID_GAME"],
|
||||||
|
requires=["gui"],
|
||||||
|
stack_size=1 * 1024,
|
||||||
|
order=30,
|
||||||
|
)
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <input/input.h>
|
#include <input/input.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <notification/notification_messages.h>
|
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
|
||||||
#define TAG "Arkanoid"
|
#define TAG "Arkanoid"
|
||||||
@@ -154,8 +153,8 @@ void move_ball(Canvas* canvas) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Bounce off Bricks
|
//Bounce off Bricks
|
||||||
for(int row = 0; row < ROWS; row++) {
|
for(unsigned int row = 0; row < ROWS; row++) {
|
||||||
for(int column = 0; column < COLUMNS; column++) {
|
for(unsigned int column = 0; column < COLUMNS; column++) {
|
||||||
if(!isHit[row][column]) {
|
if(!isHit[row][column]) {
|
||||||
//Sets Brick bounds
|
//Sets Brick bounds
|
||||||
leftBrick = 10 * column;
|
leftBrick = 10 * column;
|
||||||
@@ -244,8 +243,8 @@ void reset_level(Canvas* canvas) {
|
|||||||
released = false;
|
released = false;
|
||||||
|
|
||||||
// Reset all brick hit states
|
// Reset all brick hit states
|
||||||
for(int row = 0; row < ROWS; row++) {
|
for(unsigned int row = 0; row < ROWS; row++) {
|
||||||
for(int column = 0; column < COLUMNS; column++) {
|
for(unsigned int column = 0; column < COLUMNS; column++) {
|
||||||
isHit[row][column] = false;
|
isHit[row][column] = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -277,8 +276,8 @@ static void arkanoid_draw_callback(Canvas* const canvas, void* ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Draws new bricks and resets their values
|
//Draws new bricks and resets their values
|
||||||
for(int row = 0; row < ROWS; row++) {
|
for(unsigned int row = 0; row < ROWS; row++) {
|
||||||
for(int column = 0; column < COLUMNS; column++) {
|
for(unsigned int column = 0; column < COLUMNS; column++) {
|
||||||
if(!isHit[row][column]) {
|
if(!isHit[row][column]) {
|
||||||
canvas_draw_frame(canvas, 10 * column, 2 + 6 * row, 8, 4);
|
canvas_draw_frame(canvas, 10 * column, 2 + 6 * row, 8, 4);
|
||||||
}
|
}
|
||||||
@@ -320,6 +319,10 @@ static void arkanoid_update_timer_callback(osMessageQueueId_t event_queue) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t arkanoid_game_app(void* p) {
|
int32_t arkanoid_game_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
|
// Set random seed from interrupts
|
||||||
|
srand(DWT->CYCCNT);
|
||||||
|
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(GameEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(GameEvent), NULL);
|
||||||
|
|
||||||
ArkanoidState* arkanoid_state = malloc(sizeof(ArkanoidState));
|
ArkanoidState* arkanoid_state = malloc(sizeof(ArkanoidState));
|
||||||
@@ -404,7 +407,6 @@ int32_t arkanoid_game_app(void* p) {
|
|||||||
furi_record_close("gui");
|
furi_record_close("gui");
|
||||||
view_port_free(view_port);
|
view_port_free(view_port);
|
||||||
osMessageQueueDelete(event_queue);
|
osMessageQueueDelete(event_queue);
|
||||||
furi_record_close("notification");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
11
applications/clock_app/application.fam
Normal file
11
applications/clock_app/application.fam
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
App(
|
||||||
|
appid="clock",
|
||||||
|
name="Clock",
|
||||||
|
apptype=FlipperAppType.APP,
|
||||||
|
entry_point="clock_app",
|
||||||
|
cdefines=["APP_CLOCK"],
|
||||||
|
requires=["gui"],
|
||||||
|
icon="A_Clock_14",
|
||||||
|
stack_size=2 * 1024,
|
||||||
|
order=9,
|
||||||
|
)
|
||||||
@@ -35,7 +35,29 @@ App(
|
|||||||
apptype=FlipperAppType.METAPACKAGE,
|
apptype=FlipperAppType.METAPACKAGE,
|
||||||
provides=[
|
provides=[
|
||||||
"music_player",
|
"music_player",
|
||||||
"snake_game",
|
|
||||||
"bt_hid",
|
"bt_hid",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
App(
|
||||||
|
appid="custom_games",
|
||||||
|
name="Custom applications for games menu",
|
||||||
|
apptype=FlipperAppType.METAPACKAGE,
|
||||||
|
provides=[
|
||||||
|
"snake_game",
|
||||||
|
"tetris_game",
|
||||||
|
"arkanoid_game",
|
||||||
|
"tictactoe_game",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
App(
|
||||||
|
appid="custom_apps",
|
||||||
|
name="Custom applications for main menu",
|
||||||
|
apptype=FlipperAppType.METAPACKAGE,
|
||||||
|
provides=[
|
||||||
|
"clock",
|
||||||
|
"spectrum_analyzer",
|
||||||
|
"unirfremix",
|
||||||
|
],
|
||||||
|
)
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
App(
|
App(
|
||||||
appid="snake_game",
|
appid="snake_game",
|
||||||
name="Snake Game",
|
name="Snake Game",
|
||||||
apptype=FlipperAppType.PLUGIN,
|
apptype=FlipperAppType.GAME,
|
||||||
entry_point="snake_game_app",
|
entry_point="snake_game_app",
|
||||||
cdefines=["APP_SNAKE_GAME"],
|
cdefines=["APP_SNAKE_GAME"],
|
||||||
requires=["gui"],
|
requires=["gui"],
|
||||||
stack_size=1 * 1024,
|
stack_size=1 * 1024,
|
||||||
icon="A_Plugins_14",
|
order=10,
|
||||||
order=30,
|
|
||||||
)
|
)
|
||||||
|
|||||||
11
applications/spectrum_analyzer/application.fam
Normal file
11
applications/spectrum_analyzer/application.fam
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
App(
|
||||||
|
appid="spectrum_analyzer",
|
||||||
|
name="Spectrum Analyzer",
|
||||||
|
apptype=FlipperAppType.APP,
|
||||||
|
entry_point="spectrum_analyzer_app",
|
||||||
|
cdefines=["APP_SPECTRUM_ANALYZER"],
|
||||||
|
requires=["gui"],
|
||||||
|
icon="A_SpectrumAnalyzer_14",
|
||||||
|
stack_size=1 * 1024,
|
||||||
|
order=12,
|
||||||
|
)
|
||||||
@@ -17,35 +17,26 @@
|
|||||||
static const uint32_t subghz_frequency_list[] = {
|
static const uint32_t subghz_frequency_list[] = {
|
||||||
/* 300 - 348 */
|
/* 300 - 348 */
|
||||||
300000000,
|
300000000,
|
||||||
302757000, /* FCC ID N6U303NTX */
|
|
||||||
303875000,
|
303875000,
|
||||||
304250000, /* Ceiling Fan - Harbor Breeze*/
|
304250000,
|
||||||
310000000,
|
310000000,
|
||||||
313850000, /* 2007 Honda Key */
|
|
||||||
315000000,
|
315000000,
|
||||||
318000000,
|
318000000,
|
||||||
348000000,
|
|
||||||
387000000,
|
|
||||||
|
|
||||||
/* 387 - 464 */
|
/* 387 - 464 */
|
||||||
390000000,
|
390000000,
|
||||||
418000000,
|
418000000,
|
||||||
433075000, /* LPD433 first */
|
433075000, /* LPD433 first */
|
||||||
433220000, /* 2016-2020 Honda */
|
|
||||||
433420000,
|
433420000,
|
||||||
433889000, /* ROGUE? */
|
|
||||||
433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
|
433920000 | FREQUENCY_FLAG_DEFAULT, /* LPD433 mid */
|
||||||
434420000,
|
434420000,
|
||||||
434775000, /* LPD433 last channels */
|
434775000, /* LPD433 last channels */
|
||||||
438900000,
|
438900000,
|
||||||
464000000,
|
|
||||||
|
|
||||||
/* 779 - 928 */
|
/* 779 - 928 */
|
||||||
779000000,
|
|
||||||
868350000,
|
868350000,
|
||||||
915000000,
|
915000000,
|
||||||
925000000,
|
925000000,
|
||||||
928000000,
|
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
10
applications/tetris_game/application.fam
Normal file
10
applications/tetris_game/application.fam
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
App(
|
||||||
|
appid="tetris_game",
|
||||||
|
name="Tetris",
|
||||||
|
apptype=FlipperAppType.GAME,
|
||||||
|
entry_point="tetris_game_app",
|
||||||
|
cdefines=["APP_TETRIS_GAME"],
|
||||||
|
requires=["gui"],
|
||||||
|
stack_size=1 * 1024,
|
||||||
|
order=20,
|
||||||
|
)
|
||||||
10
applications/tictactoe_game/application.fam
Normal file
10
applications/tictactoe_game/application.fam
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
App(
|
||||||
|
appid="tictactoe_game",
|
||||||
|
name="Tic Tac Toe",
|
||||||
|
apptype=FlipperAppType.GAME,
|
||||||
|
entry_point="tictactoe_game_app",
|
||||||
|
cdefines=["APP_TICTACTOE_GAME"],
|
||||||
|
requires=["gui"],
|
||||||
|
stack_size=1 * 1024,
|
||||||
|
order=40,
|
||||||
|
)
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#include <gui/gui.h>
|
#include <gui/gui.h>
|
||||||
#include <input/input.h>
|
#include <input/input.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <notification/notification_messages.h>
|
|
||||||
#include <gui/view.h>
|
#include <gui/view.h>
|
||||||
|
|
||||||
#define TAG "TicTacToe"
|
#define TAG "TicTacToe"
|
||||||
@@ -269,6 +268,7 @@ static void tictactoe_update_timer_callback(osMessageQueueId_t event_queue) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int32_t tictactoe_game_app(void* p) {
|
int32_t tictactoe_game_app(void* p) {
|
||||||
|
UNUSED(p);
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(GameEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(8, sizeof(GameEvent), NULL);
|
||||||
|
|
||||||
TicTacToeState* tictactoe_state = malloc(sizeof(TicTacToeState));
|
TicTacToeState* tictactoe_state = malloc(sizeof(TicTacToeState));
|
||||||
@@ -277,6 +277,7 @@ int32_t tictactoe_game_app(void* p) {
|
|||||||
if(!init_mutex(&state_mutex, tictactoe_state, sizeof(TicTacToeState))) {
|
if(!init_mutex(&state_mutex, tictactoe_state, sizeof(TicTacToeState))) {
|
||||||
FURI_LOG_E(TAG, "Cannot create mutex\r\n");
|
FURI_LOG_E(TAG, "Cannot create mutex\r\n");
|
||||||
free(tictactoe_state);
|
free(tictactoe_state);
|
||||||
|
osMessageQueueDelete(event_queue);
|
||||||
return 255;
|
return 255;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -341,7 +342,6 @@ int32_t tictactoe_game_app(void* p) {
|
|||||||
furi_record_close("gui");
|
furi_record_close("gui");
|
||||||
view_port_free(view_port);
|
view_port_free(view_port);
|
||||||
osMessageQueueDelete(event_queue);
|
osMessageQueueDelete(event_queue);
|
||||||
furi_record_close("notification");
|
|
||||||
delete_mutex(&state_mutex);
|
delete_mutex(&state_mutex);
|
||||||
free(tictactoe_state);
|
free(tictactoe_state);
|
||||||
|
|
||||||
|
|||||||
11
applications/unirfremix/application.fam
Normal file
11
applications/unirfremix/application.fam
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
App(
|
||||||
|
appid="unirfremix",
|
||||||
|
name="UniRF Remix",
|
||||||
|
apptype=FlipperAppType.APP,
|
||||||
|
entry_point="unirfremix_app",
|
||||||
|
cdefines=["APP_UNIRFREMIX"],
|
||||||
|
requires=["gui"],
|
||||||
|
icon="A_UniRFRemix_14",
|
||||||
|
stack_size=2 * 1024,
|
||||||
|
order=11,
|
||||||
|
)
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
#include "wav_parser.h"
|
|
||||||
|
|
||||||
#define TAG "WavParser"
|
|
||||||
|
|
||||||
const char* format_text(FormatTag tag) {
|
|
||||||
switch(tag) {
|
|
||||||
case FormatTagPCM:
|
|
||||||
return "PCM";
|
|
||||||
case FormatTagIEEE_FLOAT:
|
|
||||||
return "IEEE FLOAT";
|
|
||||||
default:
|
|
||||||
return "Unknown";
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct WavParser {
|
|
||||||
WavHeaderChunk header;
|
|
||||||
WavFormatChunk format;
|
|
||||||
WavDataChunk data;
|
|
||||||
size_t wav_data_start;
|
|
||||||
size_t wav_data_end;
|
|
||||||
};
|
|
||||||
|
|
||||||
WavParser* wav_parser_alloc() {
|
|
||||||
return malloc(sizeof(WavParser));
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_parser_free(WavParser* parser) {
|
|
||||||
free(parser);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wav_parser_parse(WavParser* parser, Stream* stream) {
|
|
||||||
stream_read(stream, (uint8_t*)&parser->header, sizeof(WavHeaderChunk));
|
|
||||||
stream_read(stream, (uint8_t*)&parser->format, sizeof(WavFormatChunk));
|
|
||||||
stream_read(stream, (uint8_t*)&parser->data, sizeof(WavDataChunk));
|
|
||||||
|
|
||||||
if(memcmp(parser->header.riff, "RIFF", 4) != 0 ||
|
|
||||||
memcmp(parser->header.wave, "WAVE", 4) != 0) {
|
|
||||||
FURI_LOG_E(TAG, "WAV: wrong header");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(memcmp(parser->format.fmt, "fmt ", 4) != 0) {
|
|
||||||
FURI_LOG_E(TAG, "WAV: wrong format");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(parser->format.tag != FormatTagPCM || memcmp(parser->data.data, "data", 4) != 0) {
|
|
||||||
FURI_LOG_E(
|
|
||||||
TAG,
|
|
||||||
"WAV: non-PCM format %u, next '%lu'",
|
|
||||||
parser->format.tag,
|
|
||||||
(uint32_t)parser->data.data);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
FURI_LOG_I(
|
|
||||||
TAG,
|
|
||||||
"Format tag: %s, ch: %u, smplrate: %lu, bps: %lu, bits: %u",
|
|
||||||
format_text(parser->format.tag),
|
|
||||||
parser->format.channels,
|
|
||||||
parser->format.sample_rate,
|
|
||||||
parser->format.byte_per_sec,
|
|
||||||
parser->format.bits_per_sample);
|
|
||||||
|
|
||||||
parser->wav_data_start = stream_tell(stream);
|
|
||||||
parser->wav_data_end = parser->wav_data_start + parser->data.size;
|
|
||||||
|
|
||||||
FURI_LOG_I(TAG, "data: %u - %u", parser->wav_data_start, parser->wav_data_end);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t wav_parser_get_data_start(WavParser* parser) {
|
|
||||||
return parser->wav_data_start;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t wav_parser_get_data_end(WavParser* parser) {
|
|
||||||
return parser->wav_data_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t wav_parser_get_data_len(WavParser* parser) {
|
|
||||||
return parser->wav_data_end - parser->wav_data_start;
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <toolbox/stream/stream.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FormatTagPCM = 0x0001,
|
|
||||||
FormatTagIEEE_FLOAT = 0x0003,
|
|
||||||
} FormatTag;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t riff[4];
|
|
||||||
uint32_t size;
|
|
||||||
uint8_t wave[4];
|
|
||||||
} WavHeaderChunk;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t fmt[4];
|
|
||||||
uint32_t size;
|
|
||||||
uint16_t tag;
|
|
||||||
uint16_t channels;
|
|
||||||
uint32_t sample_rate;
|
|
||||||
uint32_t byte_per_sec;
|
|
||||||
uint16_t block_align;
|
|
||||||
uint16_t bits_per_sample;
|
|
||||||
} WavFormatChunk;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t data[4];
|
|
||||||
uint32_t size;
|
|
||||||
} WavDataChunk;
|
|
||||||
|
|
||||||
typedef struct WavParser WavParser;
|
|
||||||
|
|
||||||
WavParser* wav_parser_alloc();
|
|
||||||
|
|
||||||
void wav_parser_free(WavParser* parser);
|
|
||||||
|
|
||||||
bool wav_parser_parse(WavParser* parser, Stream* stream);
|
|
||||||
|
|
||||||
size_t wav_parser_get_data_start(WavParser* parser);
|
|
||||||
|
|
||||||
size_t wav_parser_get_data_end(WavParser* parser);
|
|
||||||
|
|
||||||
size_t wav_parser_get_data_len(WavParser* parser);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,297 +0,0 @@
|
|||||||
#include <furi.h>
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <cli/cli.h>
|
|
||||||
#include <gui/gui.h>
|
|
||||||
#include <stm32wbxx_ll_dma.h>
|
|
||||||
#include <dialogs/dialogs.h>
|
|
||||||
#include <notification/notification_messages.h>
|
|
||||||
#include <gui/view_dispatcher.h>
|
|
||||||
#include <toolbox/stream/file_stream.h>
|
|
||||||
#include "wav_player_hal.h"
|
|
||||||
#include "wav_parser.h"
|
|
||||||
#include "wav_player_view.h"
|
|
||||||
|
|
||||||
#define TAG "WavPlayer"
|
|
||||||
|
|
||||||
static bool open_wav_stream(Storage* storage, Stream* stream) {
|
|
||||||
DialogsApp* dialogs = furi_record_open("dialogs");
|
|
||||||
bool result = false;
|
|
||||||
string_t path;
|
|
||||||
string_init(path);
|
|
||||||
string_set_str(path, "/ext/wav_player");
|
|
||||||
bool ret = dialog_file_browser_show(dialogs, path, path, ".wav", true, &I_music_10px, false);
|
|
||||||
|
|
||||||
furi_record_close("dialogs");
|
|
||||||
if(ret) {
|
|
||||||
if(!file_stream_open(stream, string_get_cstr(path), FSAM_READ, FSOM_OPEN_EXISTING)) {
|
|
||||||
FURI_LOG_E(TAG, "Cannot open file \"%s\"", string_get_cstr(path));
|
|
||||||
} else {
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
string_clear(path);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WavPlayerEventHalfTransfer,
|
|
||||||
WavPlayerEventFullTransfer,
|
|
||||||
WavPlayerEventCtrlVolUp,
|
|
||||||
WavPlayerEventCtrlVolDn,
|
|
||||||
WavPlayerEventCtrlMoveL,
|
|
||||||
WavPlayerEventCtrlMoveR,
|
|
||||||
WavPlayerEventCtrlOk,
|
|
||||||
WavPlayerEventCtrlBack,
|
|
||||||
} WavPlayerEventType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
WavPlayerEventType type;
|
|
||||||
} WavPlayerEvent;
|
|
||||||
|
|
||||||
static void wav_player_dma_isr(void* ctx) {
|
|
||||||
osMessageQueueId_t event_queue = ctx;
|
|
||||||
|
|
||||||
// half of transfer
|
|
||||||
if(LL_DMA_IsActiveFlag_HT1(DMA1)) {
|
|
||||||
LL_DMA_ClearFlag_HT1(DMA1);
|
|
||||||
// fill first half of buffer
|
|
||||||
WavPlayerEvent event = {.type = WavPlayerEventHalfTransfer};
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// transfer complete
|
|
||||||
if(LL_DMA_IsActiveFlag_TC1(DMA1)) {
|
|
||||||
LL_DMA_ClearFlag_TC1(DMA1);
|
|
||||||
// fill second half of buffer
|
|
||||||
WavPlayerEvent event = {.type = WavPlayerEventFullTransfer};
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Storage* storage;
|
|
||||||
Stream* stream;
|
|
||||||
WavParser* parser;
|
|
||||||
uint16_t* sample_buffer;
|
|
||||||
uint8_t* tmp_buffer;
|
|
||||||
|
|
||||||
size_t samples_count_half;
|
|
||||||
size_t samples_count;
|
|
||||||
|
|
||||||
osMessageQueueId_t queue;
|
|
||||||
|
|
||||||
float volume;
|
|
||||||
bool play;
|
|
||||||
|
|
||||||
WavPlayerView* view;
|
|
||||||
ViewDispatcher* view_dispatcher;
|
|
||||||
Gui* gui;
|
|
||||||
NotificationApp* notification;
|
|
||||||
} WavPlayerApp;
|
|
||||||
|
|
||||||
static WavPlayerApp* app_alloc() {
|
|
||||||
WavPlayerApp* app = malloc(sizeof(WavPlayerApp));
|
|
||||||
app->samples_count_half = 1024 * 4;
|
|
||||||
app->samples_count = app->samples_count_half * 2;
|
|
||||||
app->storage = furi_record_open("storage");
|
|
||||||
app->stream = file_stream_alloc(app->storage);
|
|
||||||
app->parser = wav_parser_alloc();
|
|
||||||
app->sample_buffer = malloc(sizeof(uint16_t) * app->samples_count);
|
|
||||||
app->tmp_buffer = malloc(sizeof(uint8_t) * app->samples_count);
|
|
||||||
app->queue = osMessageQueueNew(10, sizeof(WavPlayerEvent), NULL);
|
|
||||||
|
|
||||||
app->volume = 10.0f;
|
|
||||||
app->play = true;
|
|
||||||
|
|
||||||
app->gui = furi_record_open("gui");
|
|
||||||
app->view_dispatcher = view_dispatcher_alloc();
|
|
||||||
app->view = wav_player_view_alloc();
|
|
||||||
|
|
||||||
view_dispatcher_add_view(app->view_dispatcher, 0, wav_player_view_get_view(app->view));
|
|
||||||
view_dispatcher_attach_to_gui(app->view_dispatcher, app->gui, ViewDispatcherTypeFullscreen);
|
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, 0);
|
|
||||||
|
|
||||||
app->notification = furi_record_open("notification");
|
|
||||||
notification_message(app->notification, &sequence_display_backlight_enforce_on);
|
|
||||||
|
|
||||||
return app;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void app_free(WavPlayerApp* app) {
|
|
||||||
view_dispatcher_remove_view(app->view_dispatcher, 0);
|
|
||||||
view_dispatcher_free(app->view_dispatcher);
|
|
||||||
wav_player_view_free(app->view);
|
|
||||||
furi_record_close("gui");
|
|
||||||
|
|
||||||
osMessageQueueDelete(app->queue);
|
|
||||||
free(app->tmp_buffer);
|
|
||||||
free(app->sample_buffer);
|
|
||||||
wav_parser_free(app->parser);
|
|
||||||
stream_free(app->stream);
|
|
||||||
furi_record_close("storage");
|
|
||||||
|
|
||||||
notification_message(app->notification, &sequence_display_backlight_enforce_auto);
|
|
||||||
furi_record_close("notification");
|
|
||||||
free(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: that works only with 8-bit 2ch audio
|
|
||||||
static bool fill_data(WavPlayerApp* app, size_t index) {
|
|
||||||
uint16_t* sample_buffer_start = &app->sample_buffer[index];
|
|
||||||
size_t count = stream_read(app->stream, app->tmp_buffer, app->samples_count);
|
|
||||||
|
|
||||||
for(size_t i = count; i < app->samples_count; i++) {
|
|
||||||
app->tmp_buffer[i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(size_t i = 0; i < app->samples_count; i += 2) {
|
|
||||||
float data = app->tmp_buffer[i];
|
|
||||||
data -= UINT8_MAX / 2; // to signed
|
|
||||||
data /= UINT8_MAX / 2; // scale -1..1
|
|
||||||
|
|
||||||
data *= app->volume; // volume
|
|
||||||
data = tanhf(data); // hyperbolic tangent limiter
|
|
||||||
|
|
||||||
data *= UINT8_MAX / 2; // scale -128..127
|
|
||||||
data += UINT8_MAX / 2; // to unsigned
|
|
||||||
|
|
||||||
if(data < 0) {
|
|
||||||
data = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data > 255) {
|
|
||||||
data = 255;
|
|
||||||
}
|
|
||||||
|
|
||||||
sample_buffer_start[i / 2] = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
wav_player_view_set_data(app->view, sample_buffer_start, app->samples_count_half);
|
|
||||||
|
|
||||||
return count != app->samples_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ctrl_callback(WavPlayerCtrl ctrl, void* ctx) {
|
|
||||||
osMessageQueueId_t event_queue = ctx;
|
|
||||||
WavPlayerEvent event;
|
|
||||||
|
|
||||||
switch(ctrl) {
|
|
||||||
case WavPlayerCtrlVolUp:
|
|
||||||
event.type = WavPlayerEventCtrlVolUp;
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
break;
|
|
||||||
case WavPlayerCtrlVolDn:
|
|
||||||
event.type = WavPlayerEventCtrlVolDn;
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
break;
|
|
||||||
case WavPlayerCtrlMoveL:
|
|
||||||
event.type = WavPlayerEventCtrlMoveL;
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
break;
|
|
||||||
case WavPlayerCtrlMoveR:
|
|
||||||
event.type = WavPlayerEventCtrlMoveR;
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
break;
|
|
||||||
case WavPlayerCtrlOk:
|
|
||||||
event.type = WavPlayerEventCtrlOk;
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
break;
|
|
||||||
case WavPlayerCtrlBack:
|
|
||||||
event.type = WavPlayerEventCtrlBack;
|
|
||||||
osMessageQueuePut(event_queue, &event, 0, 0);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void app_run(WavPlayerApp* app) {
|
|
||||||
if(!open_wav_stream(app->storage, app->stream)) return;
|
|
||||||
if(!wav_parser_parse(app->parser, app->stream)) return;
|
|
||||||
|
|
||||||
wav_player_view_set_volume(app->view, app->volume);
|
|
||||||
wav_player_view_set_start(app->view, wav_parser_get_data_start(app->parser));
|
|
||||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
|
||||||
wav_player_view_set_end(app->view, wav_parser_get_data_end(app->parser));
|
|
||||||
wav_player_view_set_play(app->view, app->play);
|
|
||||||
|
|
||||||
wav_player_view_set_context(app->view, app->queue);
|
|
||||||
wav_player_view_set_ctrl_callback(app->view, ctrl_callback);
|
|
||||||
|
|
||||||
bool eof = fill_data(app, 0);
|
|
||||||
eof = fill_data(app, app->samples_count_half);
|
|
||||||
|
|
||||||
wav_player_speaker_init();
|
|
||||||
wav_player_dma_init((uint32_t)app->sample_buffer, app->samples_count);
|
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, wav_player_dma_isr, app->queue);
|
|
||||||
|
|
||||||
wav_player_dma_start();
|
|
||||||
wav_player_speaker_start();
|
|
||||||
|
|
||||||
WavPlayerEvent event;
|
|
||||||
|
|
||||||
while(1) {
|
|
||||||
if(osMessageQueueGet(app->queue, &event, NULL, osWaitForever) == osOK) {
|
|
||||||
if(event.type == WavPlayerEventHalfTransfer) {
|
|
||||||
eof = fill_data(app, 0);
|
|
||||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
|
||||||
if(eof) {
|
|
||||||
stream_seek(
|
|
||||||
app->stream,
|
|
||||||
wav_parser_get_data_start(app->parser),
|
|
||||||
StreamOffsetFromStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else if(event.type == WavPlayerEventFullTransfer) {
|
|
||||||
eof = fill_data(app, app->samples_count_half);
|
|
||||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
|
||||||
if(eof) {
|
|
||||||
stream_seek(
|
|
||||||
app->stream,
|
|
||||||
wav_parser_get_data_start(app->parser),
|
|
||||||
StreamOffsetFromStart);
|
|
||||||
}
|
|
||||||
} else if(event.type == WavPlayerEventCtrlVolUp) {
|
|
||||||
if(app->volume < 9.9) app->volume += 0.2;
|
|
||||||
wav_player_view_set_volume(app->view, app->volume);
|
|
||||||
} else if(event.type == WavPlayerEventCtrlVolDn) {
|
|
||||||
if(app->volume > 0.01) app->volume -= 0.2;
|
|
||||||
wav_player_view_set_volume(app->view, app->volume);
|
|
||||||
} else if(event.type == WavPlayerEventCtrlMoveL) {
|
|
||||||
int32_t seek = stream_tell(app->stream) - wav_parser_get_data_start(app->parser);
|
|
||||||
seek = MIN(seek, wav_parser_get_data_len(app->parser) / 100);
|
|
||||||
stream_seek(app->stream, -seek, StreamOffsetFromCurrent);
|
|
||||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
|
||||||
} else if(event.type == WavPlayerEventCtrlMoveR) {
|
|
||||||
int32_t seek = wav_parser_get_data_end(app->parser) - stream_tell(app->stream);
|
|
||||||
seek = MIN(seek, wav_parser_get_data_len(app->parser) / 100);
|
|
||||||
stream_seek(app->stream, seek, StreamOffsetFromCurrent);
|
|
||||||
wav_player_view_set_current(app->view, stream_tell(app->stream));
|
|
||||||
} else if(event.type == WavPlayerEventCtrlOk) {
|
|
||||||
app->play = !app->play;
|
|
||||||
wav_player_view_set_play(app->view, app->play);
|
|
||||||
|
|
||||||
if(!app->play) {
|
|
||||||
wav_player_speaker_stop();
|
|
||||||
} else {
|
|
||||||
wav_player_speaker_start();
|
|
||||||
}
|
|
||||||
} else if(event.type == WavPlayerEventCtrlBack) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
wav_player_speaker_stop();
|
|
||||||
wav_player_dma_stop();
|
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t wav_player_app(void* p) {
|
|
||||||
WavPlayerApp* app = app_alloc();
|
|
||||||
app_run(app);
|
|
||||||
app_free(app);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#include "wav_player_hal.h"
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
|
||||||
#include <stm32wbxx_ll_dma.h>
|
|
||||||
|
|
||||||
#define FURI_HAL_SPEAKER_TIMER TIM16
|
|
||||||
#define FURI_HAL_SPEAKER_CHANNEL LL_TIM_CHANNEL_CH1
|
|
||||||
#define DMA_INSTANCE DMA1, LL_DMA_CHANNEL_1
|
|
||||||
|
|
||||||
void wav_player_speaker_init() {
|
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
|
||||||
TIM_InitStruct.Prescaler = 4;
|
|
||||||
TIM_InitStruct.Autoreload = 255;
|
|
||||||
LL_TIM_Init(FURI_HAL_SPEAKER_TIMER, &TIM_InitStruct);
|
|
||||||
|
|
||||||
LL_TIM_OC_InitTypeDef TIM_OC_InitStruct = {0};
|
|
||||||
TIM_OC_InitStruct.OCMode = LL_TIM_OCMODE_PWM1;
|
|
||||||
TIM_OC_InitStruct.OCState = LL_TIM_OCSTATE_ENABLE;
|
|
||||||
TIM_OC_InitStruct.CompareValue = 127;
|
|
||||||
LL_TIM_OC_Init(FURI_HAL_SPEAKER_TIMER, FURI_HAL_SPEAKER_CHANNEL, &TIM_OC_InitStruct);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_speaker_start() {
|
|
||||||
LL_TIM_EnableAllOutputs(FURI_HAL_SPEAKER_TIMER);
|
|
||||||
LL_TIM_EnableCounter(FURI_HAL_SPEAKER_TIMER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_speaker_stop() {
|
|
||||||
LL_TIM_DisableAllOutputs(FURI_HAL_SPEAKER_TIMER);
|
|
||||||
LL_TIM_DisableCounter(FURI_HAL_SPEAKER_TIMER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_dma_init(uint32_t address, size_t size) {
|
|
||||||
uint32_t dma_dst = (uint32_t) & (FURI_HAL_SPEAKER_TIMER->CCR1);
|
|
||||||
|
|
||||||
LL_DMA_ConfigAddresses(DMA_INSTANCE, address, dma_dst, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
|
|
||||||
LL_DMA_SetDataLength(DMA_INSTANCE, size);
|
|
||||||
|
|
||||||
LL_DMA_SetPeriphRequest(DMA_INSTANCE, LL_DMAMUX_REQ_TIM16_UP);
|
|
||||||
LL_DMA_SetDataTransferDirection(DMA_INSTANCE, LL_DMA_DIRECTION_MEMORY_TO_PERIPH);
|
|
||||||
LL_DMA_SetChannelPriorityLevel(DMA_INSTANCE, LL_DMA_PRIORITY_VERYHIGH);
|
|
||||||
LL_DMA_SetMode(DMA_INSTANCE, LL_DMA_MODE_CIRCULAR);
|
|
||||||
LL_DMA_SetPeriphIncMode(DMA_INSTANCE, LL_DMA_PERIPH_NOINCREMENT);
|
|
||||||
LL_DMA_SetMemoryIncMode(DMA_INSTANCE, LL_DMA_MEMORY_INCREMENT);
|
|
||||||
LL_DMA_SetPeriphSize(DMA_INSTANCE, LL_DMA_PDATAALIGN_HALFWORD);
|
|
||||||
LL_DMA_SetMemorySize(DMA_INSTANCE, LL_DMA_MDATAALIGN_HALFWORD);
|
|
||||||
|
|
||||||
LL_DMA_EnableIT_TC(DMA_INSTANCE);
|
|
||||||
LL_DMA_EnableIT_HT(DMA_INSTANCE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_dma_start() {
|
|
||||||
LL_DMA_EnableChannel(DMA_INSTANCE);
|
|
||||||
LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_SPEAKER_TIMER);
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_dma_stop() {
|
|
||||||
LL_DMA_DisableChannel(DMA_INSTANCE);
|
|
||||||
}
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wav_player_speaker_init();
|
|
||||||
|
|
||||||
void wav_player_speaker_start();
|
|
||||||
|
|
||||||
void wav_player_speaker_stop();
|
|
||||||
|
|
||||||
void wav_player_dma_init(uint32_t address, size_t size);
|
|
||||||
|
|
||||||
void wav_player_dma_start();
|
|
||||||
|
|
||||||
void wav_player_dma_stop();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,214 +0,0 @@
|
|||||||
#include "wav_player_view.h"
|
|
||||||
|
|
||||||
#define DATA_COUNT 116
|
|
||||||
|
|
||||||
struct WavPlayerView {
|
|
||||||
View* view;
|
|
||||||
WavPlayerCtrlCallback callback;
|
|
||||||
void* context;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool play;
|
|
||||||
float volume;
|
|
||||||
size_t start;
|
|
||||||
size_t end;
|
|
||||||
size_t current;
|
|
||||||
uint8_t data[DATA_COUNT];
|
|
||||||
} WavPlayerViewModel;
|
|
||||||
|
|
||||||
float map(float x, float in_min, float in_max, float out_min, float out_max) {
|
|
||||||
return (x - in_min) * (out_max - out_min + 1) / (in_max - in_min + 1) + out_min;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void wav_player_view_draw_callback(Canvas* canvas, void* _model) {
|
|
||||||
WavPlayerViewModel* model = _model;
|
|
||||||
|
|
||||||
canvas_clear(canvas);
|
|
||||||
canvas_set_color(canvas, ColorBlack);
|
|
||||||
uint8_t x_pos = 0;
|
|
||||||
uint8_t y_pos = 0;
|
|
||||||
|
|
||||||
// volume
|
|
||||||
x_pos = 124;
|
|
||||||
y_pos = 0;
|
|
||||||
const float volume = (64 / 10.0f) * model->volume;
|
|
||||||
canvas_draw_frame(canvas, x_pos, y_pos, 4, 64);
|
|
||||||
canvas_draw_box(canvas, x_pos, y_pos + (64 - volume), 4, volume);
|
|
||||||
|
|
||||||
// play / pause
|
|
||||||
x_pos = 58;
|
|
||||||
y_pos = 55;
|
|
||||||
if(model->play) {
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos, x_pos + 8, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos + 8, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos);
|
|
||||||
} else {
|
|
||||||
canvas_draw_box(canvas, x_pos, y_pos, 3, 9);
|
|
||||||
canvas_draw_box(canvas, x_pos + 4, y_pos, 3, 9);
|
|
||||||
}
|
|
||||||
|
|
||||||
x_pos = 78;
|
|
||||||
y_pos = 55;
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos, x_pos + 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos + 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos);
|
|
||||||
|
|
||||||
x_pos = 82;
|
|
||||||
y_pos = 55;
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos, x_pos + 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos + 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos);
|
|
||||||
|
|
||||||
x_pos = 40;
|
|
||||||
y_pos = 55;
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos, x_pos - 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos - 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos);
|
|
||||||
|
|
||||||
x_pos = 44;
|
|
||||||
y_pos = 55;
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos, x_pos - 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos - 4, y_pos + 4);
|
|
||||||
canvas_draw_line(canvas, x_pos, y_pos + 8, x_pos, y_pos);
|
|
||||||
|
|
||||||
// len
|
|
||||||
x_pos = 4;
|
|
||||||
y_pos = 47;
|
|
||||||
const uint8_t play_len = 116;
|
|
||||||
uint8_t play_pos = map(model->current, model->start, model->end, 0, play_len - 4);
|
|
||||||
|
|
||||||
canvas_draw_frame(canvas, x_pos, y_pos, play_len, 4);
|
|
||||||
canvas_draw_box(canvas, x_pos + play_pos, y_pos - 2, 4, 8);
|
|
||||||
canvas_draw_box(canvas, x_pos, y_pos, play_pos, 4);
|
|
||||||
|
|
||||||
// osc
|
|
||||||
x_pos = 4;
|
|
||||||
y_pos = 0;
|
|
||||||
for(size_t i = 1; i < DATA_COUNT; i++) {
|
|
||||||
canvas_draw_line(canvas, x_pos + i - 1, model->data[i - 1], x_pos + i, model->data[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool wav_player_view_input_callback(InputEvent* event, void* context) {
|
|
||||||
WavPlayerView* wav_player_view = context;
|
|
||||||
bool consumed = false;
|
|
||||||
|
|
||||||
if(wav_player_view->callback) {
|
|
||||||
if(event->type == InputTypeShort || event->type == InputTypeRepeat) {
|
|
||||||
if(event->key == InputKeyUp) {
|
|
||||||
wav_player_view->callback(WavPlayerCtrlVolUp, wav_player_view->context);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event->key == InputKeyDown) {
|
|
||||||
wav_player_view->callback(WavPlayerCtrlVolDn, wav_player_view->context);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event->key == InputKeyLeft) {
|
|
||||||
wav_player_view->callback(WavPlayerCtrlMoveL, wav_player_view->context);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event->key == InputKeyRight) {
|
|
||||||
wav_player_view->callback(WavPlayerCtrlMoveR, wav_player_view->context);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event->key == InputKeyOk) {
|
|
||||||
wav_player_view->callback(WavPlayerCtrlOk, wav_player_view->context);
|
|
||||||
consumed = true;
|
|
||||||
} else if(event->key == InputKeyBack) {
|
|
||||||
wav_player_view->callback(WavPlayerCtrlBack, wav_player_view->context);
|
|
||||||
consumed = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return consumed;
|
|
||||||
}
|
|
||||||
|
|
||||||
WavPlayerView* wav_player_view_alloc() {
|
|
||||||
WavPlayerView* wav_view = malloc(sizeof(WavPlayerView));
|
|
||||||
wav_view->view = view_alloc();
|
|
||||||
view_set_context(wav_view->view, wav_view);
|
|
||||||
view_allocate_model(wav_view->view, ViewModelTypeLocking, sizeof(WavPlayerViewModel));
|
|
||||||
view_set_draw_callback(wav_view->view, wav_player_view_draw_callback);
|
|
||||||
view_set_input_callback(wav_view->view, wav_player_view_input_callback);
|
|
||||||
|
|
||||||
return wav_view;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_free(WavPlayerView* wav_view) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
view_free(wav_view->view);
|
|
||||||
free(wav_view);
|
|
||||||
}
|
|
||||||
|
|
||||||
View* wav_player_view_get_view(WavPlayerView* wav_view) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
return wav_view->view;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_volume(WavPlayerView* wav_view, float volume) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
with_view_model(
|
|
||||||
wav_view->view, (WavPlayerViewModel * model) {
|
|
||||||
model->volume = volume;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_start(WavPlayerView* wav_view, size_t start) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
with_view_model(
|
|
||||||
wav_view->view, (WavPlayerViewModel * model) {
|
|
||||||
model->start = start;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_end(WavPlayerView* wav_view, size_t end) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
with_view_model(
|
|
||||||
wav_view->view, (WavPlayerViewModel * model) {
|
|
||||||
model->end = end;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_current(WavPlayerView* wav_view, size_t current) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
with_view_model(
|
|
||||||
wav_view->view, (WavPlayerViewModel * model) {
|
|
||||||
model->current = current;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_play(WavPlayerView* wav_view, bool play) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
with_view_model(
|
|
||||||
wav_view->view, (WavPlayerViewModel * model) {
|
|
||||||
model->play = play;
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_data(WavPlayerView* wav_view, uint16_t* data, size_t data_count) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
with_view_model(
|
|
||||||
wav_view->view, (WavPlayerViewModel * model) {
|
|
||||||
size_t inc = (data_count / DATA_COUNT) - 1;
|
|
||||||
|
|
||||||
for(size_t i = 0; i < DATA_COUNT; i++) {
|
|
||||||
model->data[i] = *data / 6;
|
|
||||||
if(model->data[i] > 42) model->data[i] = 42;
|
|
||||||
data += inc;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_ctrl_callback(WavPlayerView* wav_view, WavPlayerCtrlCallback callback) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
wav_view->callback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
void wav_player_view_set_context(WavPlayerView* wav_view, void* context) {
|
|
||||||
furi_assert(wav_view);
|
|
||||||
wav_view->context = context;
|
|
||||||
}
|
|
||||||
@@ -1,45 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <gui/view.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct WavPlayerView WavPlayerView;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WavPlayerCtrlVolUp,
|
|
||||||
WavPlayerCtrlVolDn,
|
|
||||||
WavPlayerCtrlMoveL,
|
|
||||||
WavPlayerCtrlMoveR,
|
|
||||||
WavPlayerCtrlOk,
|
|
||||||
WavPlayerCtrlBack,
|
|
||||||
} WavPlayerCtrl;
|
|
||||||
|
|
||||||
typedef void (*WavPlayerCtrlCallback)(WavPlayerCtrl ctrl, void* context);
|
|
||||||
|
|
||||||
WavPlayerView* wav_player_view_alloc();
|
|
||||||
|
|
||||||
void wav_player_view_free(WavPlayerView* wav_view);
|
|
||||||
|
|
||||||
View* wav_player_view_get_view(WavPlayerView* wav_view);
|
|
||||||
|
|
||||||
void wav_player_view_set_volume(WavPlayerView* wav_view, float volume);
|
|
||||||
|
|
||||||
void wav_player_view_set_start(WavPlayerView* wav_view, size_t start);
|
|
||||||
|
|
||||||
void wav_player_view_set_end(WavPlayerView* wav_view, size_t end);
|
|
||||||
|
|
||||||
void wav_player_view_set_current(WavPlayerView* wav_view, size_t current);
|
|
||||||
|
|
||||||
void wav_player_view_set_play(WavPlayerView* wav_view, bool play);
|
|
||||||
|
|
||||||
void wav_player_view_set_data(WavPlayerView* wav_view, uint16_t* data, size_t data_count);
|
|
||||||
|
|
||||||
void wav_player_view_set_ctrl_callback(WavPlayerView* wav_view, WavPlayerCtrlCallback callback);
|
|
||||||
|
|
||||||
void wav_player_view_set_context(WavPlayerView* wav_view, void* context);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,53 +1,29 @@
|
|||||||
Filetype: Flipper SubGhz Setting File
|
Filetype: Flipper SubGhz Setting File
|
||||||
Version: 1
|
Version: 1
|
||||||
|
|
||||||
# Add Standard frequencies for your region
|
# Add All Standard frequencies
|
||||||
#add_standard_frequencies: true
|
#add_standard_frequencies: true
|
||||||
|
|
||||||
# Default Frequency: used as default for "Read" and "Read Raw"
|
# Default Frequency: used as default for "Read" and "Read Raw"
|
||||||
#default_frequency: 433920000
|
#default_frequency: 433920000
|
||||||
|
|
||||||
# Frequencies used for "Read", "Read Raw" and "Frequency Analyzer"
|
# Frequencies used for "Read", "Read Raw" and "Frequency Analyzer" + default ones if enabled in add_standard_frequencies
|
||||||
frequency: 300000000
|
|
||||||
frequency: 302757000
|
frequency: 302757000
|
||||||
frequency: 303875000
|
|
||||||
frequency: 304250000
|
|
||||||
frequency: 310000000
|
|
||||||
frequency: 312000000
|
frequency: 312000000
|
||||||
frequency: 312100000
|
frequency: 312100000
|
||||||
frequency: 313850000
|
frequency: 313850000
|
||||||
frequency: 314000000
|
frequency: 314000000
|
||||||
frequency: 314350000
|
frequency: 314350000
|
||||||
frequency: 315000000
|
|
||||||
frequency: 318000000
|
|
||||||
frequency: 345000000
|
frequency: 345000000
|
||||||
frequency: 348000000
|
frequency: 348000000
|
||||||
frequency: 387000000
|
frequency: 387000000
|
||||||
frequency: 390000000
|
|
||||||
frequency: 418000000
|
|
||||||
frequency: 433075000
|
|
||||||
frequency: 433220000
|
frequency: 433220000
|
||||||
frequency: 433420000
|
|
||||||
frequency: 433889000
|
frequency: 433889000
|
||||||
frequency: 433920000
|
|
||||||
frequency: 434420000
|
|
||||||
frequency: 434775000
|
|
||||||
frequency: 438900000
|
|
||||||
frequency: 464000000
|
frequency: 464000000
|
||||||
frequency: 779000000
|
frequency: 779000000
|
||||||
frequency: 868350000
|
|
||||||
frequency: 915000000
|
|
||||||
frequency: 925000000
|
|
||||||
frequency: 928000000
|
frequency: 928000000
|
||||||
|
|
||||||
# Frequencies used for hopping mode (keep this list small or flipper will miss signal)
|
# Frequencies used for hopping mode (keep this list small or flipper will miss signal) + default ones if enabled in add_standard_frequencies
|
||||||
hopper_frequency: 300000000
|
#hopper_frequency: 300000000
|
||||||
hopper_frequency: 345000000
|
hopper_frequency: 345000000
|
||||||
#hopper_frequency: 310000000
|
hopper_frequency: 434420000
|
||||||
#hopper_frequency: 312000000
|
|
||||||
#hopper_frequency: 314000000
|
|
||||||
#hopper_frequency: 315000000
|
|
||||||
#hopper_frequency: 318000000
|
|
||||||
#hopper_frequency: 390000000
|
|
||||||
#hopper_frequency: 433920000
|
|
||||||
#hopper_frequency: 868350000
|
|
||||||
|
|||||||
@@ -54,12 +54,16 @@ FIRMWARE_APPS = {
|
|||||||
"basic_apps",
|
"basic_apps",
|
||||||
"updater_app",
|
"updater_app",
|
||||||
"archive",
|
"archive",
|
||||||
|
# Custom Apps
|
||||||
|
"custom_apps",
|
||||||
# Settings
|
# Settings
|
||||||
"passport",
|
"passport",
|
||||||
"system_settings",
|
"system_settings",
|
||||||
"about",
|
"about",
|
||||||
# Plugins
|
# Plugins
|
||||||
"basic_plugins",
|
"basic_plugins",
|
||||||
|
# Custom Games
|
||||||
|
"custom_games",
|
||||||
# Debug
|
# Debug
|
||||||
"debug_apps",
|
"debug_apps",
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -277,6 +277,7 @@ LevelDuration subghz_protocol_encoder_came_atomo_yield(void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* subghz_protocol_decoder_came_atomo_alloc(SubGhzEnvironment* environment) {
|
void* subghz_protocol_decoder_came_atomo_alloc(SubGhzEnvironment* environment) {
|
||||||
|
UNUSED(environment);
|
||||||
SubGhzProtocolDecoderCameAtomo* instance = malloc(sizeof(SubGhzProtocolDecoderCameAtomo));
|
SubGhzProtocolDecoderCameAtomo* instance = malloc(sizeof(SubGhzProtocolDecoderCameAtomo));
|
||||||
instance->base.protocol = &subghz_protocol_came_atomo;
|
instance->base.protocol = &subghz_protocol_came_atomo;
|
||||||
instance->generic.protocol_name = instance->base.protocol->name;
|
instance->generic.protocol_name = instance->base.protocol->name;
|
||||||
|
|||||||
@@ -3,20 +3,41 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal.h>
|
|
||||||
|
|
||||||
void set_random_name(char* name, uint8_t max_name_size) {
|
void set_random_name(char* name, uint8_t max_name_size) {
|
||||||
FuriHalRtcDateTime datetime;
|
static bool rand_generator_inited = false;
|
||||||
furi_hal_rtc_get_datetime(&datetime);
|
|
||||||
char strings[1][25];
|
if(!rand_generator_inited) {
|
||||||
sprintf(
|
srand(DWT->CYCCNT);
|
||||||
strings[0],
|
rand_generator_inited = true;
|
||||||
"%s%.4d%.2d%.2d%.2d%.2d",
|
}
|
||||||
"s",
|
const char* prefix[] = {
|
||||||
datetime.year,
|
"super",
|
||||||
datetime.month,
|
"big",
|
||||||
datetime.day,
|
"little",
|
||||||
datetime.hour,
|
"liquid",
|
||||||
datetime.minute);
|
"unknown",
|
||||||
sniprintf(name, max_name_size, "%s", strings[0]);
|
"thin",
|
||||||
|
"thick",
|
||||||
|
"great",
|
||||||
|
"my",
|
||||||
|
};
|
||||||
|
|
||||||
|
const char* suffix[] = {
|
||||||
|
"maslina",
|
||||||
|
"sus",
|
||||||
|
"anomalija",
|
||||||
|
"artefact",
|
||||||
|
"monolit",
|
||||||
|
"burer",
|
||||||
|
"sidorovich",
|
||||||
|
"habar",
|
||||||
|
};
|
||||||
|
// sus is not (sus)pect - this is about super sus
|
||||||
|
uint8_t prefix_i = rand() % COUNT_OF(prefix);
|
||||||
|
uint8_t suffix_i = rand() % COUNT_OF(suffix);
|
||||||
|
|
||||||
|
sniprintf(name, max_name_size, "%s_%s", prefix[prefix_i], suffix[suffix_i]);
|
||||||
|
// Set first symbol to upper case
|
||||||
|
name[0] = name[0] - 0x20;
|
||||||
}
|
}
|
||||||
@@ -32,10 +32,10 @@ class GitVersion:
|
|||||||
|
|
||||||
branch_num = self._exec_git("rev-list --count HEAD") or "n/a"
|
branch_num = self._exec_git("rev-list --count HEAD") or "n/a"
|
||||||
|
|
||||||
try:
|
version = (
|
||||||
version = self._exec_git("describe --tags --abbrev=0 --exact-match")
|
os.environ.get("DIST_SUFFIX", None)
|
||||||
except subprocess.CalledProcessError:
|
or "unknown"
|
||||||
version = "unknown"
|
)
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"GIT_COMMIT": commit,
|
"GIT_COMMIT": commit,
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class FlipperAppType(Enum):
|
|||||||
STARTUP = "StartupHook"
|
STARTUP = "StartupHook"
|
||||||
EXTERNAL = "External"
|
EXTERNAL = "External"
|
||||||
METAPACKAGE = "Package"
|
METAPACKAGE = "Package"
|
||||||
|
GAME = "Game"
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@@ -98,6 +99,7 @@ class AppBuildset:
|
|||||||
FlipperAppType.ARCHIVE,
|
FlipperAppType.ARCHIVE,
|
||||||
FlipperAppType.SETTINGS,
|
FlipperAppType.SETTINGS,
|
||||||
FlipperAppType.STARTUP,
|
FlipperAppType.STARTUP,
|
||||||
|
FlipperAppType.GAME,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __init__(self, appmgr: AppManager, appnames: List[str]):
|
def __init__(self, appmgr: AppManager, appnames: List[str]):
|
||||||
@@ -190,6 +192,7 @@ class ApplicationsCGenerator:
|
|||||||
FlipperAppType.SYSTEM: ("FlipperApplication", "FLIPPER_SYSTEM_APPS"),
|
FlipperAppType.SYSTEM: ("FlipperApplication", "FLIPPER_SYSTEM_APPS"),
|
||||||
FlipperAppType.APP: ("FlipperApplication", "FLIPPER_APPS"),
|
FlipperAppType.APP: ("FlipperApplication", "FLIPPER_APPS"),
|
||||||
FlipperAppType.PLUGIN: ("FlipperApplication", "FLIPPER_PLUGINS"),
|
FlipperAppType.PLUGIN: ("FlipperApplication", "FLIPPER_PLUGINS"),
|
||||||
|
FlipperAppType.GAME: ("FlipperApplication", "FLIPPER_GAMES"),
|
||||||
FlipperAppType.DEBUG: ("FlipperApplication", "FLIPPER_DEBUG_APPS"),
|
FlipperAppType.DEBUG: ("FlipperApplication", "FLIPPER_DEBUG_APPS"),
|
||||||
FlipperAppType.SETTINGS: ("FlipperApplication", "FLIPPER_SETTINGS_APPS"),
|
FlipperAppType.SETTINGS: ("FlipperApplication", "FLIPPER_SETTINGS_APPS"),
|
||||||
FlipperAppType.STARTUP: ("FlipperOnStartHook", "FLIPPER_ON_SYSTEM_START"),
|
FlipperAppType.STARTUP: ("FlipperOnStartHook", "FLIPPER_ON_SYSTEM_START"),
|
||||||
|
|||||||
Reference in New Issue
Block a user