Boot splash and more (#98)
* Boot splash and more - Added developer sdkconfig - Refactored the way FreeRTOS includes are included - Improved Gui/Loader logic - Implemented boot app with splash screen * Updated naming for Gui and Loader services * Renamed Screenshot service methods * Renames * Service renames
This commit is contained in:
parent
3f62ec2efa
commit
0188ce721c
11
App/Kconfig
11
App/Kconfig
@ -16,5 +16,16 @@ menu "Tactility App"
|
|||||||
bool "M5Stack CoreS3"
|
bool "M5Stack CoreS3"
|
||||||
config TT_BOARD_WAVESHARE_S3_TOUCH
|
config TT_BOARD_WAVESHARE_S3_TOUCH
|
||||||
bool "Waveshare S3 Touch LCD 4.3\""
|
bool "Waveshare S3 Touch LCD 4.3\""
|
||||||
|
help
|
||||||
|
Select a board/hardware configuration.
|
||||||
|
Use TT_BOARD_CUSTOM if you will manually configure the board in your project.
|
||||||
endchoice
|
endchoice
|
||||||
|
|
||||||
|
config TT_SPLASH_DURATION
|
||||||
|
int "Splash Duration (ms)"
|
||||||
|
default 1500
|
||||||
|
range 0 3000
|
||||||
|
help
|
||||||
|
The minimum time to show the splash screen in milliseconds.
|
||||||
|
When set to 0, startup will continue to desktop as soon as boot operations are finished.
|
||||||
endmenu
|
endmenu
|
||||||
|
|||||||
@ -9,9 +9,7 @@
|
|||||||
#include <esp_lcd_panel_rgb.h>
|
#include <esp_lcd_panel_rgb.h>
|
||||||
#include <esp_timer.h>
|
#include <esp_timer.h>
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
#include "RtosCompatSemaphore.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/semphr.h"
|
|
||||||
|
|
||||||
#define TAG "waveshare_s3_touch_display"
|
#define TAG "waveshare_s3_touch_display"
|
||||||
|
|
||||||
|
|||||||
13
COPYRIGHT.md
13
COPYRIGHT.md
@ -1,3 +1,13 @@
|
|||||||
|
## Tactility
|
||||||
|
|
||||||
|
The Tactility logo copyrights are owned by Ken Van Hoeylandt.
|
||||||
|
Firmwares built from [the original repository](https://github.com/ByteWelder/Tactility) can be redistributed with the Tactility logo.
|
||||||
|
For other usages, [contact me](https://kenvanhoeylandt.net).
|
||||||
|
|
||||||
|
The Tactility firmware and code are published under [GPL License Version 3](./LICENSE.md).
|
||||||
|
|
||||||
|
# Dependencies
|
||||||
|
|
||||||
### ESP-IDF
|
### ESP-IDF
|
||||||
|
|
||||||
This project uses ESP-IDF to compile the ESP32 firmware.
|
This project uses ESP-IDF to compile the ESP32 firmware.
|
||||||
@ -15,13 +25,12 @@ Website: https://github.com/flipperdevices/flipperzero-firmware/
|
|||||||
|
|
||||||
License: [GPL v3.0](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/LICENSE)
|
License: [GPL v3.0](https://github.com/flipperdevices/flipperzero-firmware/blob/dev/LICENSE)
|
||||||
|
|
||||||
|
|
||||||
### Google Fonts
|
### Google Fonts
|
||||||
|
|
||||||
Website: https://fonts.google.com/icons
|
Website: https://fonts.google.com/icons
|
||||||
|
|
||||||
License: [Apache License, version 2.0](https://fonts.google.com/attribution)
|
License: [Apache License, version 2.0](https://fonts.google.com/attribution)
|
||||||
|
|
||||||
### Components
|
### Other Components
|
||||||
|
|
||||||
See `/components` for the respective projects and their licenses.
|
See `/components` for the respective projects and their licenses.
|
||||||
|
|||||||
BIN
Data/assets/boot_logo.png
Normal file
BIN
Data/assets/boot_logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.6 KiB |
285
Data/assets_sources/Tactility.svg
Normal file
285
Data/assets_sources/Tactility.svg
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="800"
|
||||||
|
height="800"
|
||||||
|
viewBox="0 0 211.66667 211.66667"
|
||||||
|
version="1.1"
|
||||||
|
id="svg1"
|
||||||
|
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
|
||||||
|
sodipodi:docname="Tactility.svg"
|
||||||
|
inkscape:export-filename="Tactility.png"
|
||||||
|
inkscape:export-xdpi="96"
|
||||||
|
inkscape:export-ydpi="96"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="namedview1"
|
||||||
|
pagecolor="#505050"
|
||||||
|
bordercolor="#eeeeee"
|
||||||
|
borderopacity="1"
|
||||||
|
inkscape:showpageshadow="0"
|
||||||
|
inkscape:pageopacity="0"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d1d1d1"
|
||||||
|
inkscape:document-units="mm"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="410.5"
|
||||||
|
inkscape:cy="336.5"
|
||||||
|
inkscape:window-width="2115"
|
||||||
|
inkscape:window-height="1295"
|
||||||
|
inkscape:window-x="26"
|
||||||
|
inkscape:window-y="23"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:current-layer="svg1"
|
||||||
|
showgrid="false" />
|
||||||
|
<defs
|
||||||
|
id="defs1">
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect4"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,9.9852864,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect3"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,9.96875,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect2"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,10.022406,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect1"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,10.022406,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect34"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,9.5761962,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect33"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,9.7667784,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect32"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,10.151862,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect31"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,9.8324877,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect30"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,10.269671,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
<inkscape:path-effect
|
||||||
|
effect="fillet_chamfer"
|
||||||
|
id="path-effect29"
|
||||||
|
is_visible="true"
|
||||||
|
lpeversion="1"
|
||||||
|
nodesatellites_param="F,0,0,1,0,9.7906096,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1 @ F,0,0,1,0,0,0,1"
|
||||||
|
radius="0"
|
||||||
|
unit="px"
|
||||||
|
method="auto"
|
||||||
|
mode="F"
|
||||||
|
chamfer_steps="1"
|
||||||
|
flexible="false"
|
||||||
|
use_knot_distance="true"
|
||||||
|
apply_no_radius="true"
|
||||||
|
apply_with_radius="true"
|
||||||
|
only_selected="false"
|
||||||
|
hide_knots="false" />
|
||||||
|
</defs>
|
||||||
|
<g
|
||||||
|
id="g4"
|
||||||
|
inkscape:label="Large with textt"
|
||||||
|
inkscape:export-filename="g4.png"
|
||||||
|
inkscape:export-xdpi="21.879999"
|
||||||
|
inkscape:export-ydpi="21.879999">
|
||||||
|
<g
|
||||||
|
id="g29"
|
||||||
|
transform="translate(50,-70)"
|
||||||
|
inkscape:label="Glyph">
|
||||||
|
<g
|
||||||
|
id="g28"
|
||||||
|
inkscape:label="Upright T">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke-width:0.289836;paint-order:stroke fill markers"
|
||||||
|
id="rect26"
|
||||||
|
width="60"
|
||||||
|
height="10"
|
||||||
|
x="10"
|
||||||
|
y="150"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
inkscape:path-effect="#path-effect1"
|
||||||
|
d="M 20.022406,150 H 70 v 10 H 10 a 10.011209,10.011209 135.06412 0 1 10.022406,-10 z" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke-width:0.264583;paint-order:stroke fill markers"
|
||||||
|
id="rect28"
|
||||||
|
width="10"
|
||||||
|
height="60"
|
||||||
|
x="40"
|
||||||
|
y="150"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
inkscape:path-effect="#path-effect4"
|
||||||
|
d="m 40,150 h 10 v 60 h -0.01471 A 9.9852864,9.9852864 45 0 1 40,200.01471 Z" />
|
||||||
|
</g>
|
||||||
|
<g
|
||||||
|
id="g28-0"
|
||||||
|
transform="rotate(180,55,165)"
|
||||||
|
inkscape:label="Upside-down T">
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke-width:0.289836;paint-order:stroke fill markers"
|
||||||
|
id="rect26-4"
|
||||||
|
width="60"
|
||||||
|
height="10"
|
||||||
|
x="10"
|
||||||
|
y="150"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
inkscape:path-effect="#path-effect3"
|
||||||
|
d="M 19.96875,150 H 70 v 10 H 10 v -0.0312 A 9.96875,9.96875 135 0 1 19.96875,150 Z" />
|
||||||
|
<path
|
||||||
|
style="fill:#ffffff;stroke-width:0.264583;paint-order:stroke fill markers"
|
||||||
|
id="rect28-8"
|
||||||
|
width="10"
|
||||||
|
height="60"
|
||||||
|
x="40"
|
||||||
|
y="150"
|
||||||
|
sodipodi:type="rect"
|
||||||
|
inkscape:path-effect="#path-effect2"
|
||||||
|
d="m 40,150 h 10 v 60 A 10.011209,10.011209 45.064117 0 1 40,199.97759 Z" />
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
<text
|
||||||
|
xml:space="preserve"
|
||||||
|
style="font-weight:bold;font-size:16.7003px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold';text-align:center;writing-mode:lr-tb;direction:ltr;text-anchor:middle;fill:#ffffff;stroke-width:0.0490925;paint-order:stroke fill markers"
|
||||||
|
x="104.63994"
|
||||||
|
y="162.85924"
|
||||||
|
id="text29"
|
||||||
|
inkscape:label="Text"><tspan
|
||||||
|
sodipodi:role="line"
|
||||||
|
id="tspan29"
|
||||||
|
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:16.7003px;font-family:'Source Code Pro';-inkscape-font-specification:'Source Code Pro Bold';stroke-width:0.0490925"
|
||||||
|
x="104.63994"
|
||||||
|
y="162.85924">Tactility</tspan></text>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 8.9 KiB |
@ -72,6 +72,7 @@ public:
|
|||||||
|
|
||||||
Flags getFlags() const;
|
Flags getFlags() const;
|
||||||
void setFlags(Flags flags);
|
void setFlags(Flags flags);
|
||||||
|
Flags& mutableFlags() { return flags; }
|
||||||
|
|
||||||
_Nullable void* getData() const;
|
_Nullable void* getData() const;
|
||||||
void setData(void* data);
|
void setData(void* data);
|
||||||
|
|||||||
@ -33,7 +33,7 @@ struct Gui {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** Update GUI, request redraw */
|
/** Update GUI, request redraw */
|
||||||
void request_draw();
|
void requestDraw();
|
||||||
|
|
||||||
/** Lock GUI */
|
/** Lock GUI */
|
||||||
void lock();
|
void lock();
|
||||||
|
|||||||
@ -7,19 +7,50 @@
|
|||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include "service/gui/ViewPort.h"
|
#include "service/gui/ViewPort.h"
|
||||||
#include "service/loader/Loader.h"
|
#include "service/loader/Loader.h"
|
||||||
|
#include "RtosCompatSemaphore.h"
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/semphr.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "semphr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace tt::service::loader {
|
namespace tt::service::loader {
|
||||||
|
|
||||||
#define APP_STACK_SIZE 32
|
|
||||||
|
// region LoaderEvent
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LoaderEventTypeApplicationStarted,
|
||||||
|
LoaderEventTypeApplicationShowing,
|
||||||
|
LoaderEventTypeApplicationHiding,
|
||||||
|
LoaderEventTypeApplicationStopped
|
||||||
|
} LoaderEventType;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
app::AppInstance& app;
|
||||||
|
} LoaderEventAppStarted;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
app::AppInstance& app;
|
||||||
|
} LoaderEventAppShowing;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
app::AppInstance& app;
|
||||||
|
} LoaderEventAppHiding;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const app::Manifest& manifest;
|
||||||
|
} LoaderEventAppStopped;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
LoaderEventType type;
|
||||||
|
union {
|
||||||
|
LoaderEventAppStarted app_started;
|
||||||
|
LoaderEventAppShowing app_showing;
|
||||||
|
LoaderEventAppHiding app_hiding;
|
||||||
|
LoaderEventAppStopped app_stopped;
|
||||||
|
};
|
||||||
|
} LoaderEvent;
|
||||||
|
|
||||||
|
// endregion LoaderEvent
|
||||||
|
|
||||||
|
// region LoaderMessage
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LoaderMessageTypeNone,
|
LoaderMessageTypeNone,
|
||||||
@ -104,11 +135,13 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// endregion LoaderMessage
|
||||||
|
|
||||||
struct Loader {
|
struct Loader {
|
||||||
Thread* thread;
|
Thread* thread;
|
||||||
PubSub* pubsub_internal;
|
PubSub* pubsub_internal;
|
||||||
PubSub* pubsub_external;
|
PubSub* pubsub_external;
|
||||||
MessageQueue queue = MessageQueue(1, sizeof(LoaderMessage));
|
MessageQueue queue = MessageQueue(2, sizeof(LoaderMessage)); // 2 entries, so you can stop the current app while starting a new one without blocking
|
||||||
Mutex* mutex;
|
Mutex* mutex;
|
||||||
std::stack<app::AppInstance*> app_stack;
|
std::stack<app::AppInstance*> app_stack;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,6 +35,7 @@ static const std::vector<const service::Manifest*> system_services = {
|
|||||||
// region Default apps
|
// region Default apps
|
||||||
|
|
||||||
namespace app {
|
namespace app {
|
||||||
|
namespace boot { extern const Manifest manifest; }
|
||||||
namespace desktop { extern const Manifest manifest; }
|
namespace desktop { extern const Manifest manifest; }
|
||||||
namespace files { extern const Manifest manifest; }
|
namespace files { extern const Manifest manifest; }
|
||||||
namespace gpio { extern const Manifest manifest; }
|
namespace gpio { extern const Manifest manifest; }
|
||||||
@ -57,6 +58,7 @@ extern const app::Manifest screenshot_app;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
static const std::vector<const app::Manifest*> system_apps = {
|
static const std::vector<const app::Manifest*> system_apps = {
|
||||||
|
&app::boot::manifest,
|
||||||
&app::desktop::manifest,
|
&app::desktop::manifest,
|
||||||
&app::display::manifest,
|
&app::display::manifest,
|
||||||
&app::files::manifest,
|
&app::files::manifest,
|
||||||
@ -145,11 +147,11 @@ void init(const Configuration* config) {
|
|||||||
register_user_apps(config->apps);
|
register_user_apps(config->apps);
|
||||||
|
|
||||||
TT_LOG_I(TAG, "init starting desktop app");
|
TT_LOG_I(TAG, "init starting desktop app");
|
||||||
service::loader::start_app(app::desktop::manifest.id, true, Bundle());
|
service::loader::startApp(app::boot::manifest.id, true, Bundle());
|
||||||
|
|
||||||
if (config->auto_start_app_id) {
|
if (config->auto_start_app_id) {
|
||||||
TT_LOG_I(TAG, "init auto-starting %s", config->auto_start_app_id);
|
TT_LOG_I(TAG, "init auto-starting %s", config->auto_start_app_id);
|
||||||
service::loader::start_app(config->auto_start_app_id, true, Bundle());
|
service::loader::startApp(config->auto_start_app_id, true, Bundle());
|
||||||
}
|
}
|
||||||
|
|
||||||
TT_LOG_I(TAG, "init complete");
|
TT_LOG_I(TAG, "init complete");
|
||||||
|
|||||||
@ -12,6 +12,8 @@ namespace tt::app {
|
|||||||
class App;
|
class App;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
/** Boot screen, shown before desktop is launched. */
|
||||||
|
TypeBoot,
|
||||||
/** A desktop app sits at the root of the app stack managed by the Loader service */
|
/** A desktop app sits at the root of the app stack managed by the Loader service */
|
||||||
TypeDesktop,
|
TypeDesktop,
|
||||||
/** Apps that generally aren't started from the desktop (e.g. image viewer) */
|
/** Apps that generally aren't started from the desktop (e.g. image viewer) */
|
||||||
|
|||||||
73
Tactility/Source/app/boot/Boot.cpp
Normal file
73
Tactility/Source/app/boot/Boot.cpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#include <Timer.h>
|
||||||
|
#include <Check.h>
|
||||||
|
#include <Thread.h>
|
||||||
|
#include <Kernel.h>
|
||||||
|
#include "Assets.h"
|
||||||
|
#include "app/App.h"
|
||||||
|
#include "lvgl.h"
|
||||||
|
#include "service/loader/Loader.h"
|
||||||
|
#include "lvgl/Style.h"
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "sdkconfig.h"
|
||||||
|
#else
|
||||||
|
#define CONFIG_TT_SPLASH_DURATION 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace tt::app::boot {
|
||||||
|
|
||||||
|
static int32_t threadCallback(void* context);
|
||||||
|
|
||||||
|
struct Data {
|
||||||
|
Data() : thread("", 4096, threadCallback, this) {}
|
||||||
|
|
||||||
|
Thread thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int32_t threadCallback(TT_UNUSED void* context) {
|
||||||
|
TickType_t start_time = tt::get_ticks();
|
||||||
|
// Do stuff
|
||||||
|
TickType_t end_time = tt::get_ticks();
|
||||||
|
TickType_t ticks_passed = end_time - start_time;
|
||||||
|
TickType_t minimum_ticks = (CONFIG_TT_SPLASH_DURATION / portTICK_PERIOD_MS);
|
||||||
|
if (minimum_ticks > ticks_passed) {
|
||||||
|
tt::delay_ticks(minimum_ticks - ticks_passed);
|
||||||
|
}
|
||||||
|
tt::service::loader::stopApp();
|
||||||
|
tt::service::loader::startApp("Desktop");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onShow(TT_UNUSED App& app, lv_obj_t* parent) {
|
||||||
|
Data* data = (Data*)app.getData();
|
||||||
|
|
||||||
|
lv_obj_t* image = lv_image_create(parent);
|
||||||
|
lv_obj_set_size(image, LV_PCT(100), LV_PCT(100));
|
||||||
|
lv_image_set_src(image, TT_ASSETS_BOOT_LOGO);
|
||||||
|
lvgl::obj_set_style_bg_blacken(parent);
|
||||||
|
|
||||||
|
data->thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onStart(App& app) {
|
||||||
|
Data* data = new Data();
|
||||||
|
app.setData(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void onStop(App& app) {
|
||||||
|
Data* data = (Data*)app.getData();
|
||||||
|
data->thread.join();
|
||||||
|
tt_assert(data);
|
||||||
|
delete data;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern const Manifest manifest = {
|
||||||
|
.id = "Boot",
|
||||||
|
.name = "Boot",
|
||||||
|
.type = TypeBoot,
|
||||||
|
.onStart = onStart,
|
||||||
|
.onStop = onStop,
|
||||||
|
.onShow = onShow,
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace
|
||||||
@ -11,7 +11,7 @@ static void on_app_pressed(lv_event_t* e) {
|
|||||||
lv_event_code_t code = lv_event_get_code(e);
|
lv_event_code_t code = lv_event_get_code(e);
|
||||||
if (code == LV_EVENT_CLICKED) {
|
if (code == LV_EVENT_CLICKED) {
|
||||||
const auto* manifest = static_cast<const Manifest*>(lv_event_get_user_data(e));
|
const auto* manifest = static_cast<const Manifest*>(lv_event_get_user_data(e));
|
||||||
service::loader::start_app(manifest->id, false, Bundle());
|
service::loader::startApp(manifest->id, false, Bundle());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -72,7 +72,7 @@ static void on_navigate_up_pressed(lv_event_t* event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void on_exit_app_pressed(TT_UNUSED lv_event_t* event) {
|
static void on_exit_app_pressed(TT_UNUSED lv_event_t* event) {
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void view_file(const char* path, const char* filename) {
|
static void view_file(const char* path, const char* filename) {
|
||||||
@ -84,7 +84,7 @@ static void view_file(const char* path, const char* filename) {
|
|||||||
// For PC we need to make the path relative to the current work directory,
|
// For PC we need to make the path relative to the current work directory,
|
||||||
// because that's how LVGL maps its 'drive letter' to the file system.
|
// because that's how LVGL maps its 'drive letter' to the file system.
|
||||||
char* processed_filepath;
|
char* processed_filepath;
|
||||||
if (get_platform() == PlatformPc) {
|
if (get_platform() == PlatformSimulator) {
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
if (getcwd(cwd, sizeof(cwd)) == nullptr) {
|
if (getcwd(cwd, sizeof(cwd)) == nullptr) {
|
||||||
TT_LOG_E(TAG, "Failed to get current working directory");
|
TT_LOG_E(TAG, "Failed to get current working directory");
|
||||||
@ -105,7 +105,7 @@ static void view_file(const char* path, const char* filename) {
|
|||||||
if (is_supported_image_file(filename)) {
|
if (is_supported_image_file(filename)) {
|
||||||
Bundle bundle;
|
Bundle bundle;
|
||||||
bundle.putString(IMAGE_VIEWER_FILE_ARGUMENT, processed_filepath);
|
bundle.putString(IMAGE_VIEWER_FILE_ARGUMENT, processed_filepath);
|
||||||
service::loader::start_app("ImageViewer", false, bundle);
|
service::loader::startApp("ImageViewer", false, bundle);
|
||||||
} else if (is_supported_text_file(filename)) {
|
} else if (is_supported_text_file(filename)) {
|
||||||
Bundle bundle;
|
Bundle bundle;
|
||||||
if (get_platform() == PlatformEsp) {
|
if (get_platform() == PlatformEsp) {
|
||||||
@ -114,7 +114,7 @@ static void view_file(const char* path, const char* filename) {
|
|||||||
// Remove forward slash, because we need a relative path
|
// Remove forward slash, because we need a relative path
|
||||||
bundle.putString(TEXT_VIEWER_FILE_ARGUMENT, processed_filepath + 1);
|
bundle.putString(TEXT_VIEWER_FILE_ARGUMENT, processed_filepath + 1);
|
||||||
}
|
}
|
||||||
service::loader::start_app("TextViewer", false, bundle);
|
service::loader::startApp("TextViewer", false, bundle);
|
||||||
} else {
|
} else {
|
||||||
TT_LOG_W(TAG, "opening files of this type is not supported");
|
TT_LOG_W(TAG, "opening files of this type is not supported");
|
||||||
}
|
}
|
||||||
@ -199,7 +199,7 @@ static void on_show(App& app, lv_obj_t* parent) {
|
|||||||
static void on_start(App& app) {
|
static void on_start(App& app) {
|
||||||
auto* data = data_alloc();
|
auto* data = data_alloc();
|
||||||
// PC platform is bound to current work directory because of the LVGL file system mapping
|
// PC platform is bound to current work directory because of the LVGL file system mapping
|
||||||
if (get_platform() == PlatformPc) {
|
if (get_platform() == PlatformSimulator) {
|
||||||
char cwd[PATH_MAX];
|
char cwd[PATH_MAX];
|
||||||
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
|
if (getcwd(cwd, sizeof(cwd)) != nullptr) {
|
||||||
data_set_entries_for_path(data, cwd);
|
data_set_entries_for_path(data, cwd);
|
||||||
|
|||||||
@ -12,7 +12,7 @@ namespace tt::app::screenshot {
|
|||||||
|
|
||||||
static void update_mode(ScreenshotUi* ui) {
|
static void update_mode(ScreenshotUi* ui) {
|
||||||
lv_obj_t* label = ui->start_stop_button_label;
|
lv_obj_t* label = ui->start_stop_button_label;
|
||||||
if (service::screenshot::is_started()) {
|
if (service::screenshot::isStarted()) {
|
||||||
lv_label_set_text(label, "Stop");
|
lv_label_set_text(label, "Stop");
|
||||||
} else {
|
} else {
|
||||||
lv_label_set_text(label, "Start");
|
lv_label_set_text(label, "Start");
|
||||||
@ -34,7 +34,7 @@ static void on_mode_set(lv_event_t* event) {
|
|||||||
static void on_start_pressed(lv_event_t* event) {
|
static void on_start_pressed(lv_event_t* event) {
|
||||||
auto* ui = static_cast<ScreenshotUi*>(lv_event_get_user_data(event));
|
auto* ui = static_cast<ScreenshotUi*>(lv_event_get_user_data(event));
|
||||||
|
|
||||||
if (service::screenshot::is_started()) {
|
if (service::screenshot::isStarted()) {
|
||||||
TT_LOG_I(TAG, "Stop screenshot");
|
TT_LOG_I(TAG, "Stop screenshot");
|
||||||
service::screenshot::stop();
|
service::screenshot::stop();
|
||||||
} else {
|
} else {
|
||||||
@ -45,13 +45,13 @@ static void on_start_pressed(lv_event_t* event) {
|
|||||||
const char* delay_text = lv_textarea_get_text(ui->delay_textarea);
|
const char* delay_text = lv_textarea_get_text(ui->delay_textarea);
|
||||||
int delay = atoi(delay_text);
|
int delay = atoi(delay_text);
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
service::screenshot::start_timed(path, delay, 1);
|
service::screenshot::startTimed(path, delay, 1);
|
||||||
} else {
|
} else {
|
||||||
TT_LOG_W(TAG, "Ignored screenshot start because delay was 0");
|
TT_LOG_W(TAG, "Ignored screenshot start because delay was 0");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TT_LOG_I(TAG, "Start app screenshots");
|
TT_LOG_I(TAG, "Start app screenshots");
|
||||||
service::screenshot::start_apps(path);
|
service::screenshot::startApps(path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +73,7 @@ static void create_mode_setting_ui(ScreenshotUi* ui, lv_obj_t* parent) {
|
|||||||
lv_obj_align_to(mode_dropdown, mode_label, LV_ALIGN_OUT_RIGHT_MID, 8, 0);
|
lv_obj_align_to(mode_dropdown, mode_label, LV_ALIGN_OUT_RIGHT_MID, 8, 0);
|
||||||
lv_obj_add_event_cb(mode_dropdown, on_mode_set, LV_EVENT_VALUE_CHANGED, ui);
|
lv_obj_add_event_cb(mode_dropdown, on_mode_set, LV_EVENT_VALUE_CHANGED, ui);
|
||||||
ui->mode_dropdown = mode_dropdown;
|
ui->mode_dropdown = mode_dropdown;
|
||||||
service::screenshot::ScreenshotMode mode = service::screenshot::get_mode();
|
service::screenshot::Mode mode = service::screenshot::getMode();
|
||||||
if (mode == service::screenshot::ScreenshotModeApps) {
|
if (mode == service::screenshot::ScreenshotModeApps) {
|
||||||
lv_dropdown_set_selected(mode_dropdown, 1);
|
lv_dropdown_set_selected(mode_dropdown, 1);
|
||||||
}
|
}
|
||||||
@ -168,8 +168,8 @@ void create_ui(const App& app, ScreenshotUi* ui, lv_obj_t* parent) {
|
|||||||
create_path_ui(ui, wrapper);
|
create_path_ui(ui, wrapper);
|
||||||
create_timer_settings_ui(ui, wrapper);
|
create_timer_settings_ui(ui, wrapper);
|
||||||
|
|
||||||
service::gui::keyboard_add_textarea(ui->delay_textarea);
|
service::gui::keyboardAddTextArea(ui->delay_textarea);
|
||||||
service::gui::keyboard_add_textarea(ui->path_textarea);
|
service::gui::keyboardAddTextArea(ui->path_textarea);
|
||||||
|
|
||||||
update_mode(ui);
|
update_mode(ui);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -49,11 +49,11 @@ static void onListItemSelected(lv_event_t* e) {
|
|||||||
if (code == LV_EVENT_CLICKED) {
|
if (code == LV_EVENT_CLICKED) {
|
||||||
size_t index = (size_t)(e->user_data);
|
size_t index = (size_t)(e->user_data);
|
||||||
TT_LOG_I(TAG, "Selected item at index %d", index);
|
TT_LOG_I(TAG, "Selected item at index %d", index);
|
||||||
tt::app::App* app = service::loader::get_current_app();
|
tt::app::App* app = service::loader::getCurrentApp();
|
||||||
Bundle bundle;
|
Bundle bundle;
|
||||||
setResultIndex(bundle, (int32_t)index);
|
setResultIndex(bundle, (int32_t)index);
|
||||||
app->setResult(app::ResultOk, bundle);
|
app->setResult(app::ResultOk, bundle);
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -79,12 +79,12 @@ static void onShow(App& app, lv_obj_t* parent) {
|
|||||||
if (items.empty() || items.front().empty()) {
|
if (items.empty() || items.front().empty()) {
|
||||||
TT_LOG_E(TAG, "No items provided");
|
TT_LOG_E(TAG, "No items provided");
|
||||||
app.setResult(ResultError);
|
app.setResult(ResultError);
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
} else if (items.size() == 1) {
|
} else if (items.size() == 1) {
|
||||||
Bundle result_bundle;
|
Bundle result_bundle;
|
||||||
setResultIndex(result_bundle, 0);
|
setResultIndex(result_bundle, 0);
|
||||||
app.setResult(ResultOk, result_bundle);
|
app.setResult(ResultOk, result_bundle);
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
TT_LOG_W(TAG, "Auto-selecting single item");
|
TT_LOG_W(TAG, "Auto-selecting single item");
|
||||||
} else {
|
} else {
|
||||||
size_t index = 0;
|
size_t index = 0;
|
||||||
@ -95,7 +95,7 @@ static void onShow(App& app, lv_obj_t* parent) {
|
|||||||
} else {
|
} else {
|
||||||
TT_LOG_E(TAG, "No items provided");
|
TT_LOG_E(TAG, "No items provided");
|
||||||
app.setResult(ResultError);
|
app.setResult(ResultError);
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -12,7 +12,7 @@ static void on_app_pressed(lv_event_t* e) {
|
|||||||
lv_event_code_t code = lv_event_get_code(e);
|
lv_event_code_t code = lv_event_get_code(e);
|
||||||
if (code == LV_EVENT_CLICKED) {
|
if (code == LV_EVENT_CLICKED) {
|
||||||
const auto* manifest = static_cast<const Manifest*>(lv_event_get_user_data(e));
|
const auto* manifest = static_cast<const Manifest*>(lv_event_get_user_data(e));
|
||||||
service::loader::start_app(manifest->id, false, Bundle());
|
service::loader::startApp(manifest->id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,7 +24,7 @@ static void on_connect(const service::wifi::settings::WifiApSettings* ap_setting
|
|||||||
static WifiConnect* wifi_connect_alloc() {
|
static WifiConnect* wifi_connect_alloc() {
|
||||||
auto* wifi = static_cast<WifiConnect*>(malloc(sizeof(WifiConnect)));
|
auto* wifi = static_cast<WifiConnect*>(malloc(sizeof(WifiConnect)));
|
||||||
|
|
||||||
PubSub* wifi_pubsub = service::wifi::get_pubsub();
|
PubSub* wifi_pubsub = service::wifi::getPubsub();
|
||||||
wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &event_callback, wifi);
|
wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &event_callback, wifi);
|
||||||
wifi->mutex = tt_mutex_alloc(MutexTypeNormal);
|
wifi->mutex = tt_mutex_alloc(MutexTypeNormal);
|
||||||
wifi->state = (WifiConnectState) {
|
wifi->state = (WifiConnectState) {
|
||||||
@ -46,7 +46,7 @@ static WifiConnect* wifi_connect_alloc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void wifi_connect_free(WifiConnect* wifi) {
|
static void wifi_connect_free(WifiConnect* wifi) {
|
||||||
PubSub* wifi_pubsub = service::wifi::get_pubsub();
|
PubSub* wifi_pubsub = service::wifi::getPubsub();
|
||||||
tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription);
|
tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription);
|
||||||
tt_mutex_free(wifi->mutex);
|
tt_mutex_free(wifi->mutex);
|
||||||
|
|
||||||
@ -92,7 +92,7 @@ static void event_callback(const void* message, void* context) {
|
|||||||
case service::wifi::WifiEventTypeConnectionSuccess:
|
case service::wifi::WifiEventTypeConnectionSuccess:
|
||||||
if (wifi->state.is_connecting) {
|
if (wifi->state.is_connecting) {
|
||||||
state_set_connecting(wifi, false);
|
state_set_connecting(wifi, false);
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -191,8 +191,8 @@ void view_create(const App& app, void* wifi, lv_obj_t* parent) {
|
|||||||
view_create_bottom_buttons(wifi_connect, wrapper);
|
view_create_bottom_buttons(wifi_connect, wrapper);
|
||||||
|
|
||||||
// Keyboard bindings
|
// Keyboard bindings
|
||||||
service::gui::keyboard_add_textarea(view->ssid_textarea);
|
service::gui::keyboardAddTextArea(view->ssid_textarea);
|
||||||
service::gui::keyboard_add_textarea(view->password_textarea);
|
service::gui::keyboardAddTextArea(view->password_textarea);
|
||||||
|
|
||||||
// Init from app parameters
|
// Init from app parameters
|
||||||
const Bundle& bundle = app.getParameters();
|
const Bundle& bundle = app.getParameters();
|
||||||
|
|||||||
@ -26,7 +26,7 @@ static void on_connect(const char* ssid) {
|
|||||||
Bundle bundle;
|
Bundle bundle;
|
||||||
bundle.putString(WIFI_CONNECT_PARAM_SSID, ssid);
|
bundle.putString(WIFI_CONNECT_PARAM_SSID, ssid);
|
||||||
bundle.putString(WIFI_CONNECT_PARAM_PASSWORD, "");
|
bundle.putString(WIFI_CONNECT_PARAM_PASSWORD, "");
|
||||||
service::loader::start_app("WifiConnect", false, bundle);
|
service::loader::startApp("WifiConnect", false, bundle);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ static void on_disconnect() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void on_wifi_toggled(bool enabled) {
|
static void on_wifi_toggled(bool enabled) {
|
||||||
service::wifi::set_enabled(enabled);
|
service::wifi::setEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
static WifiManage* wifi_manage_alloc() {
|
static WifiManage* wifi_manage_alloc() {
|
||||||
@ -44,8 +44,8 @@ static WifiManage* wifi_manage_alloc() {
|
|||||||
wifi->wifi_subscription = nullptr;
|
wifi->wifi_subscription = nullptr;
|
||||||
wifi->mutex = tt_mutex_alloc(MutexTypeNormal);
|
wifi->mutex = tt_mutex_alloc(MutexTypeNormal);
|
||||||
wifi->state = (WifiManageState) {
|
wifi->state = (WifiManageState) {
|
||||||
.scanning = service::wifi::is_scanning(),
|
.scanning = service::wifi::isScanning(),
|
||||||
.radio_state = service::wifi::get_radio_state(),
|
.radio_state = service::wifi::getRadioState(),
|
||||||
.connect_ssid = { 0 },
|
.connect_ssid = { 0 },
|
||||||
.ap_records = { },
|
.ap_records = { },
|
||||||
.ap_records_count = 0
|
.ap_records_count = 0
|
||||||
@ -94,8 +94,8 @@ void request_view_update(WifiManage* wifi) {
|
|||||||
static void wifi_manage_event_callback(const void* message, void* context) {
|
static void wifi_manage_event_callback(const void* message, void* context) {
|
||||||
auto* event = (service::wifi::WifiEvent*)message;
|
auto* event = (service::wifi::WifiEvent*)message;
|
||||||
auto* wifi = (WifiManage*)context;
|
auto* wifi = (WifiManage*)context;
|
||||||
TT_LOG_I(TAG, "Update with state %d", service::wifi::get_radio_state());
|
TT_LOG_I(TAG, "Update with state %d", service::wifi::getRadioState());
|
||||||
state_set_radio_state(wifi, service::wifi::get_radio_state());
|
state_set_radio_state(wifi, service::wifi::getRadioState());
|
||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case tt::service::wifi::WifiEventTypeScanStarted:
|
case tt::service::wifi::WifiEventTypeScanStarted:
|
||||||
state_set_scanning(wifi, true);
|
state_set_scanning(wifi, true);
|
||||||
@ -105,7 +105,7 @@ static void wifi_manage_event_callback(const void* message, void* context) {
|
|||||||
state_update_scanned_records(wifi);
|
state_update_scanned_records(wifi);
|
||||||
break;
|
break;
|
||||||
case tt::service::wifi::WifiEventTypeRadioStateOn:
|
case tt::service::wifi::WifiEventTypeRadioStateOn:
|
||||||
if (!service::wifi::is_scanning()) {
|
if (!service::wifi::isScanning()) {
|
||||||
service::wifi::scan();
|
service::wifi::scan();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -119,12 +119,12 @@ static void wifi_manage_event_callback(const void* message, void* context) {
|
|||||||
static void app_show(App& app, lv_obj_t* parent) {
|
static void app_show(App& app, lv_obj_t* parent) {
|
||||||
auto* wifi = (WifiManage*)app.getData();
|
auto* wifi = (WifiManage*)app.getData();
|
||||||
|
|
||||||
PubSub* wifi_pubsub = service::wifi::get_pubsub();
|
PubSub* wifi_pubsub = service::wifi::getPubsub();
|
||||||
wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &wifi_manage_event_callback, wifi);
|
wifi->wifi_subscription = tt_pubsub_subscribe(wifi_pubsub, &wifi_manage_event_callback, wifi);
|
||||||
|
|
||||||
// State update (it has its own locking)
|
// State update (it has its own locking)
|
||||||
state_set_radio_state(wifi, service::wifi::get_radio_state());
|
state_set_radio_state(wifi, service::wifi::getRadioState());
|
||||||
state_set_scanning(wifi, service::wifi::is_scanning());
|
state_set_scanning(wifi, service::wifi::isScanning());
|
||||||
state_update_scanned_records(wifi);
|
state_update_scanned_records(wifi);
|
||||||
|
|
||||||
// View update
|
// View update
|
||||||
@ -135,11 +135,11 @@ static void app_show(App& app, lv_obj_t* parent) {
|
|||||||
view_update(&wifi->view, &wifi->bindings, &wifi->state);
|
view_update(&wifi->view, &wifi->bindings, &wifi->state);
|
||||||
unlock(wifi);
|
unlock(wifi);
|
||||||
|
|
||||||
service::wifi::WifiRadioState radio_state = service::wifi::get_radio_state();
|
service::wifi::WifiRadioState radio_state = service::wifi::getRadioState();
|
||||||
bool can_scan = radio_state == service::wifi::WIFI_RADIO_ON ||
|
bool can_scan = radio_state == service::wifi::WIFI_RADIO_ON ||
|
||||||
radio_state == service::wifi::WIFI_RADIO_CONNECTION_PENDING ||
|
radio_state == service::wifi::WIFI_RADIO_CONNECTION_PENDING ||
|
||||||
radio_state == service::wifi::WIFI_RADIO_CONNECTION_ACTIVE;
|
radio_state == service::wifi::WIFI_RADIO_CONNECTION_ACTIVE;
|
||||||
if (can_scan && !service::wifi::is_scanning()) {
|
if (can_scan && !service::wifi::isScanning()) {
|
||||||
service::wifi::scan();
|
service::wifi::scan();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -147,7 +147,7 @@ static void app_show(App& app, lv_obj_t* parent) {
|
|||||||
static void app_hide(App& app) {
|
static void app_hide(App& app) {
|
||||||
auto* wifi = (WifiManage*)app.getData();
|
auto* wifi = (WifiManage*)app.getData();
|
||||||
lock(wifi);
|
lock(wifi);
|
||||||
PubSub* wifi_pubsub = service::wifi::get_pubsub();
|
PubSub* wifi_pubsub = service::wifi::getPubsub();
|
||||||
tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription);
|
tt_pubsub_unsubscribe(wifi_pubsub, wifi->wifi_subscription);
|
||||||
wifi->wifi_subscription = nullptr;
|
wifi->wifi_subscription = nullptr;
|
||||||
wifi->view_enabled = false;
|
wifi->view_enabled = false;
|
||||||
|
|||||||
@ -16,7 +16,7 @@ void state_set_radio_state(WifiManage* wifi, service::wifi::WifiRadioState state
|
|||||||
|
|
||||||
void state_update_scanned_records(WifiManage* wifi) {
|
void state_update_scanned_records(WifiManage* wifi) {
|
||||||
lock(wifi);
|
lock(wifi);
|
||||||
service::wifi::get_scan_results(
|
service::wifi::getScanResults(
|
||||||
wifi->state.ap_records,
|
wifi->state.ap_records,
|
||||||
WIFI_SCAN_AP_RECORD_COUNT,
|
WIFI_SCAN_AP_RECORD_COUNT,
|
||||||
&wifi->state.ap_records_count
|
&wifi->state.ap_records_count
|
||||||
|
|||||||
@ -43,7 +43,7 @@ static void connect(lv_event_t* event) {
|
|||||||
|
|
||||||
static void create_network_button(WifiManageView* view, WifiManageBindings* bindings, service::wifi::WifiApRecord* record) {
|
static void create_network_button(WifiManageView* view, WifiManageBindings* bindings, service::wifi::WifiApRecord* record) {
|
||||||
const char* ssid = (const char*)record->ssid;
|
const char* ssid = (const char*)record->ssid;
|
||||||
const char* icon = service::statusbar::get_status_icon_for_rssi(record->rssi, record->auth_mode != WIFI_AUTH_OPEN);
|
const char* icon = service::statusbar::getWifiStatusIconForRssi(record->rssi, record->auth_mode != WIFI_AUTH_OPEN);
|
||||||
lv_obj_t* ap_button = lv_list_add_btn(
|
lv_obj_t* ap_button = lv_list_add_btn(
|
||||||
view->networks_list,
|
view->networks_list,
|
||||||
icon,
|
icon,
|
||||||
|
|||||||
@ -31,7 +31,7 @@ static const lv_obj_class_t toolbar_class = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void stop_app(TT_UNUSED lv_event_t* event) {
|
static void stop_app(TT_UNUSED lv_event_t* event) {
|
||||||
service::loader::stop_app();
|
service::loader::stopApp();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void toolbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) {
|
static void toolbar_constructor(const lv_obj_class_t* class_p, lv_obj_t* obj) {
|
||||||
|
|||||||
@ -1,14 +1,9 @@
|
|||||||
#include "Tactility.h"
|
#include "Tactility.h"
|
||||||
#include "service/gui/Gui_i.h"
|
#include "service/gui/Gui_i.h"
|
||||||
#include "service/loader/Loader.h"
|
#include "service/loader/Loader_i.h"
|
||||||
#include "lvgl/LvglKeypad.h"
|
#include "lvgl/LvglKeypad.h"
|
||||||
#include "lvgl/LvglSync.h"
|
#include "lvgl/LvglSync.h"
|
||||||
|
#include "RtosCompat.h"
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace tt::service::gui {
|
namespace tt::service::gui {
|
||||||
|
|
||||||
@ -25,9 +20,9 @@ void loader_callback(const void* message, TT_UNUSED void* context) {
|
|||||||
if (event->type == loader::LoaderEventTypeApplicationShowing) {
|
if (event->type == loader::LoaderEventTypeApplicationShowing) {
|
||||||
app::App& app = event->app_showing.app;
|
app::App& app = event->app_showing.app;
|
||||||
const app::Manifest& app_manifest = app.getManifest();
|
const app::Manifest& app_manifest = app.getManifest();
|
||||||
show_app(app, app_manifest.onShow, app_manifest.onHide);
|
showApp(app, app_manifest.onShow, app_manifest.onHide);
|
||||||
} else if (event->type == loader::LoaderEventTypeApplicationHiding) {
|
} else if (event->type == loader::LoaderEventTypeApplicationHiding) {
|
||||||
hide_app();
|
hideApp();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +38,7 @@ Gui* gui_alloc() {
|
|||||||
);
|
);
|
||||||
instance->mutex = tt_mutex_alloc(MutexTypeRecursive);
|
instance->mutex = tt_mutex_alloc(MutexTypeRecursive);
|
||||||
instance->keyboard = nullptr;
|
instance->keyboard = nullptr;
|
||||||
instance->loader_pubsub_subscription = tt_pubsub_subscribe(loader::get_pubsub(), &loader_callback, instance);
|
instance->loader_pubsub_subscription = tt_pubsub_subscribe(loader::getPubsub(), &loader_callback, instance);
|
||||||
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
tt_check(lvgl::lock(1000 / portTICK_PERIOD_MS));
|
||||||
instance->keyboard_group = lv_group_create();
|
instance->keyboard_group = lv_group_create();
|
||||||
instance->lvgl_parent = lv_scr_act();
|
instance->lvgl_parent = lv_scr_act();
|
||||||
@ -76,21 +71,21 @@ void unlock() {
|
|||||||
tt_check(tt_mutex_release(gui->mutex) == TtStatusOk);
|
tt_check(tt_mutex_release(gui->mutex) == TtStatusOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
void request_draw() {
|
void requestDraw() {
|
||||||
tt_assert(gui);
|
tt_assert(gui);
|
||||||
ThreadId thread_id = gui->thread->getId();
|
ThreadId thread_id = gui->thread->getId();
|
||||||
thread_flags_set(thread_id, GUI_THREAD_FLAG_DRAW);
|
thread_flags_set(thread_id, GUI_THREAD_FLAG_DRAW);
|
||||||
}
|
}
|
||||||
|
|
||||||
void show_app(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide) {
|
void showApp(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide) {
|
||||||
lock();
|
lock();
|
||||||
tt_check(gui->app_view_port == nullptr);
|
tt_check(gui->app_view_port == nullptr);
|
||||||
gui->app_view_port = view_port_alloc(app, on_show, on_hide);
|
gui->app_view_port = view_port_alloc(app, on_show, on_hide);
|
||||||
unlock();
|
unlock();
|
||||||
request_draw();
|
requestDraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
void hide_app() {
|
void hideApp() {
|
||||||
lock();
|
lock();
|
||||||
ViewPort* view_port = gui->app_view_port;
|
ViewPort* view_port = gui->app_view_port;
|
||||||
tt_check(view_port != nullptr);
|
tt_check(view_port != nullptr);
|
||||||
|
|||||||
@ -14,26 +14,26 @@ typedef struct Gui Gui;
|
|||||||
* @param on_show
|
* @param on_show
|
||||||
* @param on_hide
|
* @param on_hide
|
||||||
*/
|
*/
|
||||||
void show_app(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide);
|
void showApp(app::App& app, ViewPortShowCallback on_show, ViewPortHideCallback on_hide);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide the current app's viewport.
|
* Hide the current app's viewport.
|
||||||
* Does not request a re-draw because after hiding the current app,
|
* Does not request a re-draw because after hiding the current app,
|
||||||
* we always show the previous app, and there is always at least 1 app running.
|
* we always show the previous app, and there is always at least 1 app running.
|
||||||
*/
|
*/
|
||||||
void hide_app();
|
void hideApp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show the on-screen keyboard.
|
* Show the on-screen keyboard.
|
||||||
* @param textarea the textarea to focus the input for
|
* @param textarea the textarea to focus the input for
|
||||||
*/
|
*/
|
||||||
void keyboard_show(lv_obj_t* textarea);
|
void keyboardShow(lv_obj_t* textarea);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide the on-screen keyboard.
|
* Hide the on-screen keyboard.
|
||||||
* Has no effect when the keyboard is not visible.
|
* Has no effect when the keyboard is not visible.
|
||||||
*/
|
*/
|
||||||
void keyboard_hide();
|
void keyboardHide();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The on-screen keyboard is only shown when both of these conditions are true:
|
* The on-screen keyboard is only shown when both of these conditions are true:
|
||||||
@ -41,7 +41,7 @@ void keyboard_hide();
|
|||||||
* - TT_CONFIG_FORCE_ONSCREEN_KEYBOARD is set to true in tactility_config.h
|
* - TT_CONFIG_FORCE_ONSCREEN_KEYBOARD is set to true in tactility_config.h
|
||||||
* @return if we should show a on-screen keyboard for text input inside our apps
|
* @return if we should show a on-screen keyboard for text input inside our apps
|
||||||
*/
|
*/
|
||||||
bool keyboard_is_enabled();
|
bool keyboardIsEnabled();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Glue code for the on-screen keyboard and the hardware keyboard:
|
* Glue code for the on-screen keyboard and the hardware keyboard:
|
||||||
@ -49,6 +49,6 @@ bool keyboard_is_enabled();
|
|||||||
* - Registers the textarea to the default lv_group_t for hardware keyboards.
|
* - Registers the textarea to the default lv_group_t for hardware keyboards.
|
||||||
* @param textarea
|
* @param textarea
|
||||||
*/
|
*/
|
||||||
void keyboard_add_textarea(lv_obj_t* textarea);
|
void keyboardAddTextArea(lv_obj_t* textarea);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -28,7 +28,7 @@ static lv_obj_t* create_app_views(Gui* gui, lv_obj_t* parent, app::App& app) {
|
|||||||
lv_obj_set_width(child_container, LV_PCT(100));
|
lv_obj_set_width(child_container, LV_PCT(100));
|
||||||
lv_obj_set_flex_grow(child_container, 1);
|
lv_obj_set_flex_grow(child_container, 1);
|
||||||
|
|
||||||
if (keyboard_is_enabled()) {
|
if (keyboardIsEnabled()) {
|
||||||
gui->keyboard = lv_keyboard_create(vertical_container);
|
gui->keyboard = lv_keyboard_create(vertical_container);
|
||||||
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
lv_obj_add_flag(gui->keyboard, LV_OBJ_FLAG_HIDDEN);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -10,19 +10,19 @@ extern Gui* gui;
|
|||||||
|
|
||||||
static void show_keyboard(lv_event_t* event) {
|
static void show_keyboard(lv_event_t* event) {
|
||||||
lv_obj_t* target = lv_event_get_current_target_obj(event);
|
lv_obj_t* target = lv_event_get_current_target_obj(event);
|
||||||
keyboard_show(target);
|
keyboardShow(target);
|
||||||
lv_obj_scroll_to_view(target, LV_ANIM_ON);
|
lv_obj_scroll_to_view(target, LV_ANIM_ON);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hide_keyboard(TT_UNUSED lv_event_t* event) {
|
static void hide_keyboard(TT_UNUSED lv_event_t* event) {
|
||||||
keyboard_hide();
|
keyboardHide();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool keyboard_is_enabled() {
|
bool keyboardIsEnabled() {
|
||||||
return !lvgl::keypad_is_available() || TT_CONFIG_FORCE_ONSCREEN_KEYBOARD;
|
return !lvgl::keypad_is_available() || TT_CONFIG_FORCE_ONSCREEN_KEYBOARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_show(lv_obj_t* textarea) {
|
void keyboardShow(lv_obj_t* textarea) {
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
if (gui->keyboard) {
|
if (gui->keyboard) {
|
||||||
@ -33,7 +33,7 @@ void keyboard_show(lv_obj_t* textarea) {
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_hide() {
|
void keyboardHide() {
|
||||||
lock();
|
lock();
|
||||||
|
|
||||||
if (gui->keyboard) {
|
if (gui->keyboard) {
|
||||||
@ -43,11 +43,11 @@ void keyboard_hide() {
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void keyboard_add_textarea(lv_obj_t* textarea) {
|
void keyboardAddTextArea(lv_obj_t* textarea) {
|
||||||
lock();
|
lock();
|
||||||
tt_check(lvgl::lock(0), "lvgl should already be locked before calling this method");
|
tt_check(lvgl::lock(0), "lvgl should already be locked before calling this method");
|
||||||
|
|
||||||
if (keyboard_is_enabled()) {
|
if (keyboardIsEnabled()) {
|
||||||
lv_obj_add_event_cb(textarea, show_keyboard, LV_EVENT_FOCUSED, nullptr);
|
lv_obj_add_event_cb(textarea, show_keyboard, LV_EVENT_FOCUSED, nullptr);
|
||||||
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_DEFOCUSED, nullptr);
|
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_DEFOCUSED, nullptr);
|
||||||
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_READY, nullptr);
|
lv_obj_add_event_cb(textarea, hide_keyboard, LV_EVENT_READY, nullptr);
|
||||||
|
|||||||
@ -5,14 +5,12 @@
|
|||||||
#include "service/Manifest.h"
|
#include "service/Manifest.h"
|
||||||
#include "service/gui/Gui.h"
|
#include "service/gui/Gui.h"
|
||||||
#include "service/loader/Loader_i.h"
|
#include "service/loader/Loader_i.h"
|
||||||
|
#include "RtosCompat.h"
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include "esp_heap_caps.h"
|
#include "esp_heap_caps.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#else
|
#else
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "lvgl/LvglSync.h"
|
#include "lvgl/LvglSync.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace tt::service::loader {
|
namespace tt::service::loader {
|
||||||
@ -65,7 +63,7 @@ static void loader_unlock() {
|
|||||||
tt_check(tt_mutex_release(loader_singleton->mutex) == TtStatusOk);
|
tt_check(tt_mutex_release(loader_singleton->mutex) == TtStatusOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundle) {
|
LoaderStatus startApp(const std::string& id, bool blocking, const Bundle& arguments) {
|
||||||
TT_LOG_I(TAG, "Start app %s", id.c_str());
|
TT_LOG_I(TAG, "Start app %s", id.c_str());
|
||||||
tt_assert(loader_singleton);
|
tt_assert(loader_singleton);
|
||||||
|
|
||||||
@ -73,7 +71,7 @@ LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundl
|
|||||||
.value = LoaderStatusOk
|
.value = LoaderStatusOk
|
||||||
};
|
};
|
||||||
|
|
||||||
auto* start_message = new LoaderMessageAppStart(id, bundle);
|
auto* start_message = new LoaderMessageAppStart(id, arguments);
|
||||||
LoaderMessage message(start_message, result);
|
LoaderMessage message(start_message, result);
|
||||||
|
|
||||||
EventFlag* event_flag = blocking ? new EventFlag() : nullptr;
|
EventFlag* event_flag = blocking ? new EventFlag() : nullptr;
|
||||||
@ -94,14 +92,14 @@ LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundl
|
|||||||
return result.value;
|
return result.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
void stop_app() {
|
void stopApp() {
|
||||||
TT_LOG_I(TAG, "Stop app");
|
TT_LOG_I(TAG, "Stop app");
|
||||||
tt_check(loader_singleton);
|
tt_check(loader_singleton);
|
||||||
LoaderMessage message(LoaderMessageTypeAppStop);
|
LoaderMessage message(LoaderMessageTypeAppStop);
|
||||||
loader_singleton->queue.put(&message, TtWaitForever);
|
loader_singleton->queue.put(&message, TtWaitForever);
|
||||||
}
|
}
|
||||||
|
|
||||||
app::App* _Nullable get_current_app() {
|
app::App* _Nullable getCurrentApp() {
|
||||||
tt_assert(loader_singleton);
|
tt_assert(loader_singleton);
|
||||||
loader_lock();
|
loader_lock();
|
||||||
app::AppInstance* app = loader_singleton->app_stack.top();
|
app::AppInstance* app = loader_singleton->app_stack.top();
|
||||||
@ -109,7 +107,7 @@ app::App* _Nullable get_current_app() {
|
|||||||
return dynamic_cast<app::App*>(app);
|
return dynamic_cast<app::App*>(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
PubSub* get_pubsub() {
|
PubSub* getPubsub() {
|
||||||
tt_assert(loader_singleton);
|
tt_assert(loader_singleton);
|
||||||
// it's safe to return pubsub without locking
|
// it's safe to return pubsub without locking
|
||||||
// because it's never freed and loader is never exited
|
// because it's never freed and loader is never exited
|
||||||
@ -160,7 +158,7 @@ static void app_transition_to_state(app::AppInstance& app, app::State state) {
|
|||||||
LoaderEvent event_showing = {
|
LoaderEvent event_showing = {
|
||||||
.type = LoaderEventTypeApplicationShowing,
|
.type = LoaderEventTypeApplicationShowing,
|
||||||
.app_showing = {
|
.app_showing = {
|
||||||
.app = dynamic_cast<app::App&>(app)
|
.app = app
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tt_pubsub_publish(loader_singleton->pubsub_external, &event_showing);
|
tt_pubsub_publish(loader_singleton->pubsub_external, &event_showing);
|
||||||
@ -171,7 +169,7 @@ static void app_transition_to_state(app::AppInstance& app, app::State state) {
|
|||||||
LoaderEvent event_hiding = {
|
LoaderEvent event_hiding = {
|
||||||
.type = LoaderEventTypeApplicationHiding,
|
.type = LoaderEventTypeApplicationHiding,
|
||||||
.app_hiding = {
|
.app_hiding = {
|
||||||
.app = dynamic_cast<app::App&>(app)
|
.app = app
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tt_pubsub_publish(loader_singleton->pubsub_external, &event_hiding);
|
tt_pubsub_publish(loader_singleton->pubsub_external, &event_hiding);
|
||||||
@ -198,6 +196,8 @@ static LoaderStatus loader_do_start_app_with_manifest(
|
|||||||
|
|
||||||
auto previous_app = !loader_singleton->app_stack.empty() ? loader_singleton->app_stack.top() : nullptr;
|
auto previous_app = !loader_singleton->app_stack.empty() ? loader_singleton->app_stack.top() : nullptr;
|
||||||
auto new_app = new app::AppInstance(*manifest, bundle);
|
auto new_app = new app::AppInstance(*manifest, bundle);
|
||||||
|
new_app->mutableFlags().showStatusbar = (manifest->type != app::TypeBoot);
|
||||||
|
|
||||||
loader_singleton->app_stack.push(new_app);
|
loader_singleton->app_stack.push(new_app);
|
||||||
app_transition_to_state(*new_app, app::StateInitial);
|
app_transition_to_state(*new_app, app::StateInitial);
|
||||||
app_transition_to_state(*new_app, app::StateStarted);
|
app_transition_to_state(*new_app, app::StateStarted);
|
||||||
@ -217,7 +217,7 @@ static LoaderStatus loader_do_start_app_with_manifest(
|
|||||||
LoaderEvent event_external = {
|
LoaderEvent event_external = {
|
||||||
.type = LoaderEventTypeApplicationStarted,
|
.type = LoaderEventTypeApplicationStarted,
|
||||||
.app_started = {
|
.app_started = {
|
||||||
.app = dynamic_cast<app::App&>(*new_app)
|
.app = *new_app
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
tt_pubsub_publish(loader_singleton->pubsub_external, &event_external);
|
tt_pubsub_publish(loader_singleton->pubsub_external, &event_external);
|
||||||
@ -233,6 +233,7 @@ static LoaderStatus do_start_by_id(
|
|||||||
|
|
||||||
const app::Manifest* manifest = app::findAppById(id);
|
const app::Manifest* manifest = app::findAppById(id);
|
||||||
if (manifest == nullptr) {
|
if (manifest == nullptr) {
|
||||||
|
TT_LOG_E(TAG, "App not found: %s", id.c_str());
|
||||||
return LoaderStatusErrorUnknownApp;
|
return LoaderStatusErrorUnknownApp;
|
||||||
} else {
|
} else {
|
||||||
return loader_do_start_app_with_manifest(manifest, bundle);
|
return loader_do_start_app_with_manifest(manifest, bundle);
|
||||||
@ -251,14 +252,15 @@ static void do_stop_app() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (original_stack_size == 1) {
|
// Stop current app
|
||||||
|
app::AppInstance* app_to_stop = loader_singleton->app_stack.top();
|
||||||
|
|
||||||
|
if (original_stack_size == 1 && app_to_stop->getManifest().type != app::TypeBoot) {
|
||||||
loader_unlock();
|
loader_unlock();
|
||||||
TT_LOG_E(TAG, "Stop app: can't stop root app");
|
TT_LOG_E(TAG, "Stop app: can't stop root app");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop current app
|
|
||||||
app::AppInstance* app_to_stop = loader_singleton->app_stack.top();
|
|
||||||
std::unique_ptr<app::ResultHolder> result_holder = std::move(app_to_stop->getResult());
|
std::unique_ptr<app::ResultHolder> result_holder = std::move(app_to_stop->getResult());
|
||||||
|
|
||||||
const app::Manifest& manifest = app_to_stop->getManifest();
|
const app::Manifest& manifest = app_to_stop->getManifest();
|
||||||
@ -272,6 +274,8 @@ static void do_stop_app() {
|
|||||||
TT_LOG_I(TAG, "Free heap: %zu", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
TT_LOG_I(TAG, "Free heap: %zu", heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// If there's a previous app, resume it
|
||||||
|
if (!loader_singleton->app_stack.empty()) {
|
||||||
app::AppInstance* app_to_resume = loader_singleton->app_stack.top();
|
app::AppInstance* app_to_resume = loader_singleton->app_stack.top();
|
||||||
tt_assert(app_to_resume);
|
tt_assert(app_to_resume);
|
||||||
app_transition_to_state(*app_to_resume, app::StateShowing);
|
app_transition_to_state(*app_to_resume, app::StateShowing);
|
||||||
@ -303,6 +307,7 @@ static void do_stop_app() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
loader_unlock();
|
loader_unlock();
|
||||||
|
|
||||||
|
|||||||
@ -16,58 +16,26 @@ typedef enum {
|
|||||||
LoaderStatusErrorInternal,
|
LoaderStatusErrorInternal,
|
||||||
} LoaderStatus;
|
} LoaderStatus;
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
LoaderEventTypeApplicationStarted,
|
|
||||||
LoaderEventTypeApplicationShowing,
|
|
||||||
LoaderEventTypeApplicationHiding,
|
|
||||||
LoaderEventTypeApplicationStopped
|
|
||||||
} LoaderEventType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
app::App& app;
|
|
||||||
} LoaderEventAppStarted;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
app::App& app;
|
|
||||||
} LoaderEventAppShowing;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
app::App& app;
|
|
||||||
} LoaderEventAppHiding;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const app::Manifest& manifest;
|
|
||||||
} LoaderEventAppStopped;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
LoaderEventType type;
|
|
||||||
union {
|
|
||||||
LoaderEventAppStarted app_started;
|
|
||||||
LoaderEventAppShowing app_showing;
|
|
||||||
LoaderEventAppHiding app_hiding;
|
|
||||||
LoaderEventAppStopped app_stopped;
|
|
||||||
};
|
|
||||||
} LoaderEvent;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Start an app
|
* @brief Start an app
|
||||||
* @param[in] id application name or id
|
* @param[in] id application name or id
|
||||||
* @param[in] blocking application arguments
|
* @param[in] blocking whether this call is blocking or not. You cannot call this from an LVGL thread.
|
||||||
* @param[in] bundle optional bundle. Ownership is transferred to Loader.
|
* @param[in] arguments optional parameters to pass onto the application
|
||||||
* @return LoaderStatus
|
* @return LoaderStatus
|
||||||
*/
|
*/
|
||||||
LoaderStatus start_app(const std::string& id, bool blocking, const Bundle& bundle);
|
LoaderStatus startApp(const std::string& id, bool blocking = false, const Bundle& arguments = Bundle());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stop the currently showing app. Show the previous app if any app was still running.
|
* @brief Stop the currently showing app. Show the previous app if any app was still running.
|
||||||
*/
|
*/
|
||||||
void stop_app();
|
void stopApp();
|
||||||
|
|
||||||
app::App* _Nullable get_current_app();
|
app::App* _Nullable getCurrentApp();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief PubSub for LoaderEvent
|
* @brief PubSub for LoaderEvent
|
||||||
*/
|
*/
|
||||||
PubSub* get_pubsub();
|
PubSub* getPubsub();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -15,8 +15,8 @@ extern const Manifest manifest;
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Mutex* mutex;
|
Mutex* mutex;
|
||||||
ScreenshotTask* task;
|
task::ScreenshotTask* task;
|
||||||
ScreenshotMode mode;
|
Mode mode;
|
||||||
} ServiceData;
|
} ServiceData;
|
||||||
|
|
||||||
static ServiceData* service_data_alloc() {
|
static ServiceData* service_data_alloc() {
|
||||||
@ -49,14 +49,14 @@ static void on_start(Service& service) {
|
|||||||
static void on_stop(Service& service) {
|
static void on_stop(Service& service) {
|
||||||
auto* data = static_cast<ServiceData*>(service.getData());
|
auto* data = static_cast<ServiceData*>(service.getData());
|
||||||
if (data->task) {
|
if (data->task) {
|
||||||
task_free(data->task);
|
task::free(data->task);
|
||||||
data->task = nullptr;
|
data->task = nullptr;
|
||||||
}
|
}
|
||||||
tt_mutex_free(data->mutex);
|
tt_mutex_free(data->mutex);
|
||||||
service_data_free(data);
|
service_data_free(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_apps(const char* path) {
|
void startApps(const char* path) {
|
||||||
_Nullable auto* service = findServiceById(manifest.id);
|
_Nullable auto* service = findServiceById(manifest.id);
|
||||||
if (service == nullptr) {
|
if (service == nullptr) {
|
||||||
TT_LOG_E(TAG, "Service not found");
|
TT_LOG_E(TAG, "Service not found");
|
||||||
@ -66,16 +66,16 @@ void start_apps(const char* path) {
|
|||||||
auto* data = static_cast<ServiceData*>(service->getData());
|
auto* data = static_cast<ServiceData*>(service->getData());
|
||||||
service_data_lock(data);
|
service_data_lock(data);
|
||||||
if (data->task == nullptr) {
|
if (data->task == nullptr) {
|
||||||
data->task = task_alloc();
|
data->task = task::alloc();
|
||||||
data->mode = ScreenshotModeApps;
|
data->mode = ScreenshotModeApps;
|
||||||
task_start_apps(data->task, path);
|
task::startApps(data->task, path);
|
||||||
} else {
|
} else {
|
||||||
TT_LOG_E(TAG, "Screenshot task already running");
|
TT_LOG_E(TAG, "Screenshot task already running");
|
||||||
}
|
}
|
||||||
service_data_unlock(data);
|
service_data_unlock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void start_timed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
void startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||||
_Nullable auto* service = findServiceById(manifest.id);
|
_Nullable auto* service = findServiceById(manifest.id);
|
||||||
if (service == nullptr) {
|
if (service == nullptr) {
|
||||||
TT_LOG_E(TAG, "Service not found");
|
TT_LOG_E(TAG, "Service not found");
|
||||||
@ -85,9 +85,9 @@ void start_timed(const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
|||||||
auto* data = static_cast<ServiceData*>(service->getData());
|
auto* data = static_cast<ServiceData*>(service->getData());
|
||||||
service_data_lock(data);
|
service_data_lock(data);
|
||||||
if (data->task == nullptr) {
|
if (data->task == nullptr) {
|
||||||
data->task = task_alloc();
|
data->task = task::alloc();
|
||||||
data->mode = ScreenshotModeTimed;
|
data->mode = ScreenshotModeTimed;
|
||||||
task_start_timed(data->task, path, delay_in_seconds, amount);
|
task::startTimed(data->task, path, delay_in_seconds, amount);
|
||||||
} else {
|
} else {
|
||||||
TT_LOG_E(TAG, "Screenshot task already running");
|
TT_LOG_E(TAG, "Screenshot task already running");
|
||||||
}
|
}
|
||||||
@ -104,8 +104,8 @@ void stop() {
|
|||||||
auto data = static_cast<ServiceData*>(service->getData());
|
auto data = static_cast<ServiceData*>(service->getData());
|
||||||
service_data_lock(data);
|
service_data_lock(data);
|
||||||
if (data->task != nullptr) {
|
if (data->task != nullptr) {
|
||||||
task_stop(data->task);
|
task::stop(data->task);
|
||||||
task_free(data->task);
|
task::free(data->task);
|
||||||
data->task = nullptr;
|
data->task = nullptr;
|
||||||
data->mode = ScreenshotModeNone;
|
data->mode = ScreenshotModeNone;
|
||||||
} else {
|
} else {
|
||||||
@ -114,7 +114,7 @@ void stop() {
|
|||||||
service_data_unlock(data);
|
service_data_unlock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotMode get_mode() {
|
Mode getMode() {
|
||||||
_Nullable auto* service = findServiceById(manifest.id);
|
_Nullable auto* service = findServiceById(manifest.id);
|
||||||
if (service == nullptr) {
|
if (service == nullptr) {
|
||||||
TT_LOG_E(TAG, "Service not found");
|
TT_LOG_E(TAG, "Service not found");
|
||||||
@ -122,14 +122,14 @@ ScreenshotMode get_mode() {
|
|||||||
} else {
|
} else {
|
||||||
auto* data = static_cast<ServiceData*>(service->getData());
|
auto* data = static_cast<ServiceData*>(service->getData());
|
||||||
service_data_lock(data);
|
service_data_lock(data);
|
||||||
ScreenshotMode mode = data->mode;
|
Mode mode = data->mode;
|
||||||
service_data_unlock(data);
|
service_data_unlock(data);
|
||||||
return mode;
|
return mode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_started() {
|
bool isStarted() {
|
||||||
return get_mode() != ScreenshotModeNone;
|
return getMode() != ScreenshotModeNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern const Manifest manifest = {
|
extern const Manifest manifest = {
|
||||||
|
|||||||
@ -8,24 +8,24 @@ typedef enum {
|
|||||||
ScreenshotModeNone,
|
ScreenshotModeNone,
|
||||||
ScreenshotModeTimed,
|
ScreenshotModeTimed,
|
||||||
ScreenshotModeApps
|
ScreenshotModeApps
|
||||||
} ScreenshotMode;
|
} Mode;
|
||||||
|
|
||||||
/** @brief Starts taking screenshot with a timer
|
/** @brief Starts taking screenshot with a timer
|
||||||
* @param path the path to store the screenshots in
|
* @param path the path to store the screenshots in
|
||||||
* @param delay_in_seconds the delay before starting (and between successive screenshots)
|
* @param delay_in_seconds the delay before starting (and between successive screenshots)
|
||||||
* @param amount 0 = indefinite, >0 for a specific
|
* @param amount 0 = indefinite, >0 for a specific
|
||||||
*/
|
*/
|
||||||
void start_timed(const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
void startTimed(const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
||||||
|
|
||||||
/** @brief Starts taking screenshot when an app is started
|
/** @brief Starts taking screenshot when an app is started
|
||||||
* @param path the path to store the screenshots in
|
* @param path the path to store the screenshots in
|
||||||
*/
|
*/
|
||||||
void start_apps(const char* path);
|
void startApps(const char* path);
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
ScreenshotMode get_mode();
|
Mode getMode();
|
||||||
|
|
||||||
bool is_started();
|
bool isStarted();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -8,7 +8,7 @@
|
|||||||
#include "service/loader/Loader.h"
|
#include "service/loader/Loader.h"
|
||||||
#include "lvgl/LvglSync.h"
|
#include "lvgl/LvglSync.h"
|
||||||
|
|
||||||
namespace tt::service::screenshot {
|
namespace tt::service::screenshot::task {
|
||||||
|
|
||||||
#define TAG "screenshot_task"
|
#define TAG "screenshot_task"
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ static void task_unlock(ScreenshotTaskData* data) {
|
|||||||
tt_check(tt_mutex_release(data->mutex) == TtStatusOk);
|
tt_check(tt_mutex_release(data->mutex) == TtStatusOk);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScreenshotTask* task_alloc() {
|
ScreenshotTask* alloc() {
|
||||||
auto* data = static_cast<ScreenshotTaskData*>(malloc(sizeof(ScreenshotTaskData)));
|
auto* data = static_cast<ScreenshotTaskData*>(malloc(sizeof(ScreenshotTaskData)));
|
||||||
*data = (ScreenshotTaskData) {
|
*data = (ScreenshotTaskData) {
|
||||||
.thread = nullptr,
|
.thread = nullptr,
|
||||||
@ -49,10 +49,10 @@ ScreenshotTask* task_alloc() {
|
|||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_free(ScreenshotTask* task) {
|
void free(ScreenshotTask* task) {
|
||||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||||
if (data->thread) {
|
if (data->thread) {
|
||||||
task_stop(data);
|
stop(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ static int32_t screenshot_task(void* context) {
|
|||||||
break; // Interrupted loop
|
break; // Interrupted loop
|
||||||
}
|
}
|
||||||
} else if (data->work.type == TASK_WORK_TYPE_APPS) {
|
} else if (data->work.type == TASK_WORK_TYPE_APPS) {
|
||||||
app::App* _Nullable app = loader::get_current_app();
|
app::App* _Nullable app = loader::getCurrentApp();
|
||||||
if (app) {
|
if (app) {
|
||||||
const app::Manifest& manifest = app->getManifest();
|
const app::Manifest& manifest = app->getManifest();
|
||||||
if (manifest.id != last_app_id) {
|
if (manifest.id != last_app_id) {
|
||||||
@ -136,7 +136,7 @@ static void task_start(ScreenshotTaskData* data) {
|
|||||||
task_unlock(data);
|
task_unlock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_start_apps(ScreenshotTask* task, const char* path) {
|
void startApps(ScreenshotTask* task, const char* path) {
|
||||||
tt_check(strlen(path) < (SCREENSHOT_PATH_LIMIT - 1));
|
tt_check(strlen(path) < (SCREENSHOT_PATH_LIMIT - 1));
|
||||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||||
task_lock(data);
|
task_lock(data);
|
||||||
@ -151,7 +151,7 @@ void task_start_apps(ScreenshotTask* task, const char* path) {
|
|||||||
task_unlock(data);
|
task_unlock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_start_timed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
void startTimed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount) {
|
||||||
tt_check(strlen(path) < (SCREENSHOT_PATH_LIMIT - 1));
|
tt_check(strlen(path) < (SCREENSHOT_PATH_LIMIT - 1));
|
||||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||||
task_lock(data);
|
task_lock(data);
|
||||||
@ -168,7 +168,7 @@ void task_start_timed(ScreenshotTask* task, const char* path, uint8_t delay_in_s
|
|||||||
task_unlock(data);
|
task_unlock(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
void task_stop(ScreenshotTask* task) {
|
void stop(ScreenshotTask* task) {
|
||||||
auto* data = static_cast<ScreenshotTaskData*>(task);
|
auto* data = static_cast<ScreenshotTaskData*>(task);
|
||||||
if (data->thread != nullptr) {
|
if (data->thread != nullptr) {
|
||||||
task_lock(data);
|
task_lock(data);
|
||||||
|
|||||||
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
namespace tt::service::screenshot {
|
namespace tt::service::screenshot::task {
|
||||||
|
|
||||||
typedef void ScreenshotTask;
|
typedef void ScreenshotTask;
|
||||||
|
|
||||||
ScreenshotTask* task_alloc();
|
ScreenshotTask* alloc();
|
||||||
|
|
||||||
void task_free(ScreenshotTask* task);
|
void free(ScreenshotTask* task);
|
||||||
|
|
||||||
/** @brief Start taking screenshots after a certain delay
|
/** @brief Start taking screenshots after a certain delay
|
||||||
* @param task the screenshot task
|
* @param task the screenshot task
|
||||||
@ -16,17 +16,17 @@ void task_free(ScreenshotTask* task);
|
|||||||
* @param delay_in_seconds the delay before starting (and between successive screenshots)
|
* @param delay_in_seconds the delay before starting (and between successive screenshots)
|
||||||
* @param amount 0 = indefinite, >0 for a specific
|
* @param amount 0 = indefinite, >0 for a specific
|
||||||
*/
|
*/
|
||||||
void task_start_timed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
void startTimed(ScreenshotTask* task, const char* path, uint8_t delay_in_seconds, uint8_t amount);
|
||||||
|
|
||||||
/** @brief Start taking screenshot whenever an app is started
|
/** @brief Start taking screenshot whenever an app is started
|
||||||
* @param task the screenshot task
|
* @param task the screenshot task
|
||||||
* @param path the path to store the screenshots at
|
* @param path the path to store the screenshots at
|
||||||
*/
|
*/
|
||||||
void task_start_apps(ScreenshotTask* task, const char* path);
|
void startApps(ScreenshotTask* task, const char* path);
|
||||||
|
|
||||||
/** @brief Stop taking screenshots
|
/** @brief Stop taking screenshots
|
||||||
* @param task the screenshot task
|
* @param task the screenshot task
|
||||||
*/
|
*/
|
||||||
void task_stop(ScreenshotTask* task);
|
void stop(ScreenshotTask* task);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -25,7 +25,7 @@ typedef struct {
|
|||||||
|
|
||||||
// region wifi
|
// region wifi
|
||||||
|
|
||||||
const char* get_status_icon_for_rssi(int rssi, bool secured) {
|
const char* getWifiStatusIconForRssi(int rssi, bool secured) {
|
||||||
if (rssi > 0) {
|
if (rssi > 0) {
|
||||||
return TT_ASSETS_ICON_WIFI_CONNECTION_ISSUE;
|
return TT_ASSETS_ICON_WIFI_CONNECTION_ISSUE;
|
||||||
} else if (rssi >= -30) {
|
} else if (rssi >= -30) {
|
||||||
@ -52,16 +52,16 @@ static const char* wifi_get_status_icon(wifi::WifiRadioState state, bool secure)
|
|||||||
case wifi::WIFI_RADIO_CONNECTION_PENDING:
|
case wifi::WIFI_RADIO_CONNECTION_PENDING:
|
||||||
return TT_ASSETS_ICON_WIFI_FIND;
|
return TT_ASSETS_ICON_WIFI_FIND;
|
||||||
case wifi::WIFI_RADIO_CONNECTION_ACTIVE:
|
case wifi::WIFI_RADIO_CONNECTION_ACTIVE:
|
||||||
rssi = wifi::get_rssi();
|
rssi = wifi::getRssi();
|
||||||
return get_status_icon_for_rssi(rssi, secure);
|
return getWifiStatusIconForRssi(rssi, secure);
|
||||||
default:
|
default:
|
||||||
tt_crash("not implemented");
|
tt_crash("not implemented");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void update_wifi_icon(ServiceData* data) {
|
static void update_wifi_icon(ServiceData* data) {
|
||||||
wifi::WifiRadioState radio_state = wifi::get_radio_state();
|
wifi::WifiRadioState radio_state = wifi::getRadioState();
|
||||||
bool is_secure = wifi::is_connection_secure();
|
bool is_secure = wifi::isConnectionSecure();
|
||||||
const char* desired_icon = wifi_get_status_icon(radio_state, is_secure);
|
const char* desired_icon = wifi_get_status_icon(radio_state, is_secure);
|
||||||
if (data->wifi_last_icon != desired_icon) {
|
if (data->wifi_last_icon != desired_icon) {
|
||||||
lvgl::statusbar_icon_set_image(data->wifi_icon_id, desired_icon);
|
lvgl::statusbar_icon_set_image(data->wifi_icon_id, desired_icon);
|
||||||
|
|||||||
@ -8,6 +8,6 @@ namespace tt::service::statusbar {
|
|||||||
* @param secured whether the access point is a secured one (as in: not an open one)
|
* @param secured whether the access point is a secured one (as in: not an open one)
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
const char* get_status_icon_for_rssi(int rssi, bool secured);
|
const char* getWifiStatusIconForRssi(int rssi, bool secured);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -2,14 +2,7 @@
|
|||||||
|
|
||||||
#include "CoreDefines.h"
|
#include "CoreDefines.h"
|
||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
|
#include "RtosCompatTask.h"
|
||||||
#ifdef ESP_TARGET
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define TAG "kernel"
|
#define TAG "kernel"
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "RtosCompatEventGroups.h"
|
||||||
#ifdef ESP_TARGET
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/event_groups.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "event_groups.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
|
|||||||
@ -2,14 +2,7 @@
|
|||||||
#include "Check.h"
|
#include "Check.h"
|
||||||
#include "CoreDefines.h"
|
#include "CoreDefines.h"
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "RtosCompatTask.h"
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
#include "rom/ets_sys.h"
|
#include "rom/ets_sys.h"
|
||||||
@ -118,7 +111,7 @@ uint32_t kernel_get_tick_frequency() {
|
|||||||
return (configTICK_RATE_HZ);
|
return (configTICK_RATE_HZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
void delay_tick(uint32_t ticks) {
|
void delay_ticks(TickType_t ticks) {
|
||||||
tt_assert(!kernel_is_irq());
|
tt_assert(!kernel_is_irq());
|
||||||
if (ticks == 0U) {
|
if (ticks == 0U) {
|
||||||
taskYIELD();
|
taskYIELD();
|
||||||
@ -127,7 +120,7 @@ void delay_tick(uint32_t ticks) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TtStatus delay_until_tick(uint32_t tick) {
|
TtStatus delay_until_tick(TickType_t tick) {
|
||||||
tt_assert(!kernel_is_irq());
|
tt_assert(!kernel_is_irq());
|
||||||
|
|
||||||
TickType_t tcnt, delay;
|
TickType_t tcnt, delay;
|
||||||
@ -154,7 +147,7 @@ TtStatus delay_until_tick(uint32_t tick) {
|
|||||||
return (stat);
|
return (stat);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t get_tick() {
|
TickType_t get_ticks() {
|
||||||
TickType_t ticks;
|
TickType_t ticks;
|
||||||
|
|
||||||
if (kernel_is_irq() != 0U) {
|
if (kernel_is_irq() != 0U) {
|
||||||
@ -166,11 +159,11 @@ uint32_t get_tick() {
|
|||||||
return ticks;
|
return ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t ms_to_ticks(uint32_t milliseconds) {
|
TickType_t ms_to_ticks(uint32_t milliseconds) {
|
||||||
#if configTICK_RATE_HZ == 1000
|
#if configTICK_RATE_HZ == 1000
|
||||||
return milliseconds;
|
return (TickType_t)milliseconds;
|
||||||
#else
|
#else
|
||||||
return (uint32_t)((float)configTICK_RATE_HZ) / 1000.0f * (float)milliseconds;
|
return (TickType_t)((float)configTICK_RATE_HZ) / 1000.0f * (float)milliseconds;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -182,7 +175,7 @@ void delay_ms(uint32_t milliseconds) {
|
|||||||
#if configTICK_RATE_HZ_RAW == 1000
|
#if configTICK_RATE_HZ_RAW == 1000
|
||||||
tt_delay_tick(milliseconds);
|
tt_delay_tick(milliseconds);
|
||||||
#else
|
#else
|
||||||
delay_tick(ms_to_ticks(milliseconds));
|
delay_ticks(ms_to_ticks(milliseconds));
|
||||||
#endif
|
#endif
|
||||||
} else if (milliseconds > 0) {
|
} else if (milliseconds > 0) {
|
||||||
delay_us(milliseconds * 1000);
|
delay_us(milliseconds * 1000);
|
||||||
@ -201,7 +194,7 @@ Platform get_platform() {
|
|||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
return PlatformEsp;
|
return PlatformEsp;
|
||||||
#else
|
#else
|
||||||
return PlatformPc;
|
return PlatformSimulator;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,11 +2,17 @@
|
|||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#else
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PlatformEsp,
|
PlatformEsp,
|
||||||
PlatformPc
|
PlatformSimulator
|
||||||
} Platform;
|
} Platform;
|
||||||
|
|
||||||
/** Check if CPU is in IRQ or kernel running and IRQ is masked
|
/** Check if CPU is in IRQ or kernel running and IRQ is masked
|
||||||
@ -64,6 +70,8 @@ int32_t kernel_restore_lock(int32_t lock);
|
|||||||
*/
|
*/
|
||||||
uint32_t kernel_get_tick_frequency();
|
uint32_t kernel_get_tick_frequency();
|
||||||
|
|
||||||
|
TickType_t get_ticks();
|
||||||
|
|
||||||
/** Delay execution
|
/** Delay execution
|
||||||
*
|
*
|
||||||
* @warning This should never be called in interrupt request context.
|
* @warning This should never be called in interrupt request context.
|
||||||
@ -72,7 +80,7 @@ uint32_t kernel_get_tick_frequency();
|
|||||||
*
|
*
|
||||||
* @param[in] ticks The ticks count to pause
|
* @param[in] ticks The ticks count to pause
|
||||||
*/
|
*/
|
||||||
void delay_tick(uint32_t ticks);
|
void delay_ticks(TickType_t ticks);
|
||||||
|
|
||||||
/** Delay until tick
|
/** Delay until tick
|
||||||
*
|
*
|
||||||
@ -89,7 +97,7 @@ TtStatus delay_until_tick(uint32_t tick);
|
|||||||
* @param[in] milliseconds time in milliseconds
|
* @param[in] milliseconds time in milliseconds
|
||||||
* @return time in ticks
|
* @return time in ticks
|
||||||
*/
|
*/
|
||||||
uint32_t ms_to_ticks(uint32_t milliseconds);
|
TickType_t ms_to_ticks(uint32_t milliseconds);
|
||||||
|
|
||||||
/** Delay in milliseconds
|
/** Delay in milliseconds
|
||||||
*
|
*
|
||||||
|
|||||||
@ -6,14 +6,7 @@
|
|||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
|
#include "RtosCompatSemaphore.h"
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/semphr.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "semphr.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
|
|||||||
13
TactilityCore/Source/RtosCompat.h
Normal file
13
TactilityCore/Source/RtosCompat.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compatibility includes for FreeRTOS.
|
||||||
|
* Custom FreeRTOS from ESP-IDF prefixes paths with "freertos/",
|
||||||
|
* but this isn't the normal behaviour for the regular FreeRTOS project.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#else
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#endif
|
||||||
14
TactilityCore/Source/RtosCompatEventGroups.h
Normal file
14
TactilityCore/Source/RtosCompatEventGroups.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See explanation in RtosCompat.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/event_groups.h"
|
||||||
|
#else
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "event_groups.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
14
TactilityCore/Source/RtosCompatSemaphore.h
Normal file
14
TactilityCore/Source/RtosCompatSemaphore.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See explanation in RtosCompat.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/semphr.h"
|
||||||
|
#else
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "semphr.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
14
TactilityCore/Source/RtosCompatTask.h
Normal file
14
TactilityCore/Source/RtosCompatTask.h
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See explanation in RtosCompat.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/task.h"
|
||||||
|
#else
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "task.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
13
TactilityCore/Source/RtosCompatTimers.h
Normal file
13
TactilityCore/Source/RtosCompatTimers.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* See explanation in RtosCompat.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef ESP_PLATFORM
|
||||||
|
#include "freertos/FreeRTOS.h"
|
||||||
|
#include "freertos/timers.h"
|
||||||
|
#else
|
||||||
|
#include "FreeRTOS.h"
|
||||||
|
#include "timers.h"
|
||||||
|
#endif
|
||||||
@ -1,6 +1,7 @@
|
|||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
#include "Check.h"
|
#include "Check.h"
|
||||||
#include "Kernel.h"
|
#include "Kernel.h"
|
||||||
|
#include "RtosCompat.h"
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
@ -73,7 +74,7 @@ uint32_t Timer::getExpireTime() {
|
|||||||
return (uint32_t)xTimerGetExpiryTime(timerHandle);
|
return (uint32_t)xTimerGetExpiryTime(timerHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Timer::pendingCallback(PendigCallback callback, void* callbackContext, uint32_t arg) {
|
void Timer::pendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg) {
|
||||||
BaseType_t ret = pdFAIL;
|
BaseType_t ret = pdFAIL;
|
||||||
if (kernel_is_irq()) {
|
if (kernel_is_irq()) {
|
||||||
ret = xTimerPendFunctionCallFromISR(callback, callbackContext, arg, nullptr);
|
ret = xTimerPendFunctionCallFromISR(callback, callbackContext, arg, nullptr);
|
||||||
|
|||||||
@ -2,24 +2,17 @@
|
|||||||
|
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#include "RtosCompatTimers.h"
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/timers.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "timers.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace tt {
|
namespace tt {
|
||||||
|
|
||||||
|
|
||||||
class Timer {
|
class Timer {
|
||||||
private:
|
private:
|
||||||
TimerHandle_t timerHandle;
|
TimerHandle_t timerHandle;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef void (*Callback)(void* context);
|
typedef void (*Callback)(void* context);
|
||||||
typedef void (*PendigCallback)(void* context, uint32_t arg);
|
typedef void (*PendingCallback)(void* context, uint32_t arg);
|
||||||
|
|
||||||
|
|
||||||
Callback callback;
|
Callback callback;
|
||||||
@ -88,7 +81,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
uint32_t getExpireTime();
|
uint32_t getExpireTime();
|
||||||
|
|
||||||
void pendingCallback(PendigCallback callback, void* callbackContext, uint32_t arg);
|
void pendingCallback(PendingCallback callback, void* callbackContext, uint32_t arg);
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TimerThreadPriorityNormal, /**< Lower then other threads */
|
TimerThreadPriorityNormal, /**< Lower then other threads */
|
||||||
@ -102,9 +95,4 @@ public:
|
|||||||
void setThreadPriority(TimerThreadPriority priority);
|
void setThreadPriority(TimerThreadPriority priority);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -1,13 +1,6 @@
|
|||||||
#include "Critical.h"
|
#include "Critical.h"
|
||||||
#include "CoreDefines.h"
|
#include "CoreDefines.h"
|
||||||
|
#include "RtosCompatTask.h"
|
||||||
#ifdef ESP_PLATFORM
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#include "freertos/task.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#include "task.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef ESP_PLATFORM
|
#ifdef ESP_PLATFORM
|
||||||
static portMUX_TYPE critical_mutex;
|
static portMUX_TYPE critical_mutex;
|
||||||
|
|||||||
@ -3,6 +3,9 @@
|
|||||||
#define TT_ASSET_FOLDER "A:/assets/"
|
#define TT_ASSET_FOLDER "A:/assets/"
|
||||||
#define TT_ASSET(file) TT_ASSET_FOLDER file
|
#define TT_ASSET(file) TT_ASSET_FOLDER file
|
||||||
|
|
||||||
|
// Splash
|
||||||
|
#define TT_ASSETS_BOOT_LOGO TT_ASSET("boot_logo.png")
|
||||||
|
|
||||||
// App icons
|
// App icons
|
||||||
#define TT_ASSETS_APP_ICON_FALLBACK TT_ASSET("app_icon_fallback.png")
|
#define TT_ASSETS_APP_ICON_FALLBACK TT_ASSET("app_icon_fallback.png")
|
||||||
#define TT_ASSETS_APP_ICON_FILES TT_ASSET("app_icon_files.png")
|
#define TT_ASSETS_APP_ICON_FILES TT_ASSET("app_icon_files.png")
|
||||||
|
|||||||
@ -2,16 +2,11 @@
|
|||||||
|
|
||||||
#include "I2cCompat.h"
|
#include "I2cCompat.h"
|
||||||
#include "CoreTypes.h"
|
#include "CoreTypes.h"
|
||||||
|
#include "RtosCompat.h"
|
||||||
#include <climits>
|
#include <climits>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#ifdef ESP_TARGET
|
|
||||||
#include "freertos/FreeRTOS.h"
|
|
||||||
#else
|
|
||||||
#include "FreeRTOS.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace tt::hal::i2c {
|
namespace tt::hal::i2c {
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|||||||
@ -74,9 +74,9 @@ typedef struct {
|
|||||||
* @brief Get wifi pubsub
|
* @brief Get wifi pubsub
|
||||||
* @return PubSub*
|
* @return PubSub*
|
||||||
*/
|
*/
|
||||||
PubSub* get_pubsub();
|
PubSub* getPubsub();
|
||||||
|
|
||||||
WifiRadioState get_radio_state();
|
WifiRadioState getRadioState();
|
||||||
/**
|
/**
|
||||||
* @brief Request scanning update. Returns immediately. Results are through pubsub.
|
* @brief Request scanning update. Returns immediately. Results are through pubsub.
|
||||||
*/
|
*/
|
||||||
@ -85,26 +85,26 @@ void scan();
|
|||||||
/**
|
/**
|
||||||
* @return true if wifi is actively scanning
|
* @return true if wifi is actively scanning
|
||||||
*/
|
*/
|
||||||
bool is_scanning();
|
bool isScanning();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns the access points from the last scan (if any). It only contains public APs.
|
* @brief Returns the access points from the last scan (if any). It only contains public APs.
|
||||||
* @param records the allocated buffer to store the records in
|
* @param records the allocated buffer to store the records in
|
||||||
* @param limit the maximum amount of records to store
|
* @param limit the maximum amount of records to store
|
||||||
*/
|
*/
|
||||||
void get_scan_results(WifiApRecord records[], uint16_t limit, uint16_t* result_count);
|
void getScanResults(WifiApRecord records[], uint16_t limit, uint16_t* result_count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Overrides the default scan result size of 16.
|
* @brief Overrides the default scan result size of 16.
|
||||||
* @param records the record limit for the scan result (84 bytes per record!)
|
* @param records the record limit for the scan result (84 bytes per record!)
|
||||||
*/
|
*/
|
||||||
void set_scan_records(uint16_t records);
|
void setScanRecords(uint16_t records);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Enable/disable the radio. Ignores input if desired state matches current state.
|
* @brief Enable/disable the radio. Ignores input if desired state matches current state.
|
||||||
* @param enabled
|
* @param enabled
|
||||||
*/
|
*/
|
||||||
void set_enabled(bool enabled);
|
void setEnabled(bool enabled);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Connect to a network. Disconnects any existing connection.
|
* @brief Connect to a network. Disconnects any existing connection.
|
||||||
@ -121,11 +121,11 @@ void disconnect();
|
|||||||
/**
|
/**
|
||||||
* Return true if the connection isn't unencrypted.
|
* Return true if the connection isn't unencrypted.
|
||||||
*/
|
*/
|
||||||
bool is_connection_secure();
|
bool isConnectionSecure();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the RSSI value (negative number) or return 1 when not connected
|
* Returns the RSSI value (negative number) or return 1 when not connected
|
||||||
*/
|
*/
|
||||||
int get_rssi();
|
int getRssi();
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -99,12 +99,12 @@ Wifi::~Wifi() {
|
|||||||
|
|
||||||
// region Public functions
|
// region Public functions
|
||||||
|
|
||||||
PubSub* get_pubsub() {
|
PubSub* getPubsub() {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
return wifi_singleton->pubsub;
|
return wifi_singleton->pubsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiRadioState get_radio_state() {
|
WifiRadioState getRadioState() {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
lock(wifi_singleton);
|
lock(wifi_singleton);
|
||||||
WifiRadioState state = wifi_singleton->radio_state;
|
WifiRadioState state = wifi_singleton->radio_state;
|
||||||
@ -121,7 +121,7 @@ void scan() {
|
|||||||
unlock(wifi_singleton);
|
unlock(wifi_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_scanning() {
|
bool isScanning() {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
lock(wifi_singleton);
|
lock(wifi_singleton);
|
||||||
bool is_scanning = wifi_singleton->scan_active;
|
bool is_scanning = wifi_singleton->scan_active;
|
||||||
@ -152,7 +152,7 @@ void disconnect() {
|
|||||||
unlock(wifi_singleton);
|
unlock(wifi_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_scan_records(uint16_t records) {
|
void setScanRecords(uint16_t records) {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
lock(wifi_singleton);
|
lock(wifi_singleton);
|
||||||
if (records != wifi_singleton->scan_list_limit) {
|
if (records != wifi_singleton->scan_list_limit) {
|
||||||
@ -162,7 +162,7 @@ void set_scan_records(uint16_t records) {
|
|||||||
unlock(wifi_singleton);
|
unlock(wifi_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_scan_results(WifiApRecord records[], uint16_t limit, uint16_t* result_count) {
|
void getScanResults(WifiApRecord records[], uint16_t limit, uint16_t* result_count) {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
tt_assert(result_count);
|
tt_assert(result_count);
|
||||||
|
|
||||||
@ -185,7 +185,7 @@ void get_scan_results(WifiApRecord records[], uint16_t limit, uint16_t* result_c
|
|||||||
unlock(wifi_singleton);
|
unlock(wifi_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_enabled(bool enabled) {
|
void setEnabled(bool enabled) {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
lock(wifi_singleton);
|
lock(wifi_singleton);
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
@ -200,7 +200,7 @@ void set_enabled(bool enabled) {
|
|||||||
unlock(wifi_singleton);
|
unlock(wifi_singleton);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_connection_secure() {
|
bool isConnectionSecure() {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
lock(wifi_singleton);
|
lock(wifi_singleton);
|
||||||
bool is_secure = wifi_singleton->secure_connection;
|
bool is_secure = wifi_singleton->secure_connection;
|
||||||
@ -208,7 +208,7 @@ bool is_connection_secure() {
|
|||||||
return is_secure;
|
return is_secure;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_rssi() {
|
int getRssi() {
|
||||||
tt_assert(wifi_singleton);
|
tt_assert(wifi_singleton);
|
||||||
static int rssi = 0;
|
static int rssi = 0;
|
||||||
if (esp_wifi_sta_get_rssi(&rssi) == ESP_OK) {
|
if (esp_wifi_sta_get_rssi(&rssi) == ESP_OK) {
|
||||||
|
|||||||
@ -67,12 +67,12 @@ static void wifi_free(Wifi* instance) {
|
|||||||
|
|
||||||
// region Public functions
|
// region Public functions
|
||||||
|
|
||||||
PubSub* get_pubsub() {
|
PubSub* getPubsub() {
|
||||||
tt_assert(wifi);
|
tt_assert(wifi);
|
||||||
return wifi->pubsub;
|
return wifi->pubsub;
|
||||||
}
|
}
|
||||||
|
|
||||||
WifiRadioState get_radio_state() {
|
WifiRadioState getRadioState() {
|
||||||
return wifi->radio_state;
|
return wifi->radio_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ void scan() {
|
|||||||
wifi->scan_active = false; // TODO: enable and then later disable automatically
|
wifi->scan_active = false; // TODO: enable and then later disable automatically
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_scanning() {
|
bool isScanning() {
|
||||||
tt_assert(wifi);
|
tt_assert(wifi);
|
||||||
return wifi->scan_active;
|
return wifi->scan_active;
|
||||||
}
|
}
|
||||||
@ -95,12 +95,12 @@ void disconnect() {
|
|||||||
tt_assert(wifi);
|
tt_assert(wifi);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_scan_records(uint16_t records) {
|
void setScanRecords(uint16_t records) {
|
||||||
tt_assert(wifi);
|
tt_assert(wifi);
|
||||||
// TODO: implement
|
// TODO: implement
|
||||||
}
|
}
|
||||||
|
|
||||||
void get_scan_results(WifiApRecord records[], uint16_t limit, uint16_t* result_count) {
|
void getScanResults(WifiApRecord records[], uint16_t limit, uint16_t* result_count) {
|
||||||
tt_check(wifi);
|
tt_check(wifi);
|
||||||
tt_check(result_count);
|
tt_check(result_count);
|
||||||
|
|
||||||
@ -126,7 +126,7 @@ void get_scan_results(WifiApRecord records[], uint16_t limit, uint16_t* result_c
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_enabled(bool enabled) {
|
void setEnabled(bool enabled) {
|
||||||
tt_assert(wifi != NULL);
|
tt_assert(wifi != NULL);
|
||||||
if (enabled) {
|
if (enabled) {
|
||||||
wifi->radio_state = WIFI_RADIO_ON;
|
wifi->radio_state = WIFI_RADIO_ON;
|
||||||
@ -136,11 +136,11 @@ void set_enabled(bool enabled) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_connection_secure() {
|
bool isConnectionSecure() {
|
||||||
return wifi->secure_connection;
|
return wifi->secure_connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_rssi() {
|
int getRssi() {
|
||||||
if (wifi->radio_state == WIFI_RADIO_CONNECTION_ACTIVE) {
|
if (wifi->radio_state == WIFI_RADIO_CONNECTION_ACTIVE) {
|
||||||
return -30;
|
return -30;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -14,7 +14,7 @@ TEST_CASE("dispatcher should not call callback if consume isn't called") {
|
|||||||
|
|
||||||
uint32_t counter = 0;
|
uint32_t counter = 0;
|
||||||
dispatcher.dispatch(&increment_callback, &counter);
|
dispatcher.dispatch(&increment_callback, &counter);
|
||||||
delay_tick(10);
|
delay_ticks(10);
|
||||||
|
|
||||||
CHECK_EQ(counter, 0);
|
CHECK_EQ(counter, 0);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -18,7 +18,7 @@ TEST_CASE("a timer passes the context correctly") {
|
|||||||
int foo = 1;
|
int foo = 1;
|
||||||
auto* timer = new Timer(Timer::TypeOnce, &timer_callback_with_context, &foo);
|
auto* timer = new Timer(Timer::TypeOnce, &timer_callback_with_context, &foo);
|
||||||
timer->start(1);
|
timer->start(1);
|
||||||
delay_tick(10);
|
delay_ticks(10);
|
||||||
timer->stop();
|
timer->stop();
|
||||||
delete timer;
|
delete timer;
|
||||||
|
|
||||||
@ -29,10 +29,10 @@ TEST_CASE("TimerTypePeriodic timers can be stopped and restarted") {
|
|||||||
int counter = 0;
|
int counter = 0;
|
||||||
auto* timer = new Timer(Timer::TypePeriodic, &timer_callback_with_counter, &counter);
|
auto* timer = new Timer(Timer::TypePeriodic, &timer_callback_with_counter, &counter);
|
||||||
timer->start(1);
|
timer->start(1);
|
||||||
delay_tick(10);
|
delay_ticks(10);
|
||||||
timer->stop();
|
timer->stop();
|
||||||
timer->start(1);
|
timer->start(1);
|
||||||
delay_tick(10);
|
delay_ticks(10);
|
||||||
timer->stop();
|
timer->stop();
|
||||||
delete timer;
|
delete timer;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ TEST_CASE("TimerTypePeriodic calls the callback periodically") {
|
|||||||
int ticks_to_run = 10;
|
int ticks_to_run = 10;
|
||||||
auto* timer = new Timer(Timer::TypePeriodic, &timer_callback_with_counter, &counter);
|
auto* timer = new Timer(Timer::TypePeriodic, &timer_callback_with_counter, &counter);
|
||||||
timer->start(1);
|
timer->start(1);
|
||||||
delay_tick(ticks_to_run);
|
delay_ticks(ticks_to_run);
|
||||||
timer->stop();
|
timer->stop();
|
||||||
delete timer;
|
delete timer;
|
||||||
|
|
||||||
@ -55,10 +55,10 @@ TEST_CASE("restarting TimerTypeOnce timers calls the callback again") {
|
|||||||
int counter = 0;
|
int counter = 0;
|
||||||
auto* timer = new Timer(Timer::TypeOnce, &timer_callback_with_counter, &counter);
|
auto* timer = new Timer(Timer::TypeOnce, &timer_callback_with_counter, &counter);
|
||||||
timer->start(1);
|
timer->start(1);
|
||||||
delay_tick(10);
|
delay_ticks(10);
|
||||||
timer->stop();
|
timer->stop();
|
||||||
timer->start(1);
|
timer->start(1);
|
||||||
delay_tick(10);
|
delay_ticks(10);
|
||||||
timer->stop();
|
timer->stop();
|
||||||
delete timer;
|
delete timer;
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ CONFIG_FREERTOS_HZ=1000
|
|||||||
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
CONFIG_FREERTOS_SMP=n
|
CONFIG_FREERTOS_SMP=n
|
||||||
CONFIG_FREERTOS_UNICORE=n
|
CONFIG_FREERTOS_UNICORE=n
|
||||||
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
|||||||
@ -13,7 +13,7 @@ CONFIG_FREERTOS_HZ=1000
|
|||||||
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
CONFIG_FREERTOS_SMP=n
|
CONFIG_FREERTOS_SMP=n
|
||||||
CONFIG_FREERTOS_UNICORE=n
|
CONFIG_FREERTOS_UNICORE=n
|
||||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
@ -25,6 +25,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
|||||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||||
CONFIG_FLASHMODE_QIO=y
|
CONFIG_FLASHMODE_QIO=y
|
||||||
|
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||||
# Hardware: SPI RAM
|
# Hardware: SPI RAM
|
||||||
CONFIG_SPIRAM=y
|
CONFIG_SPIRAM=y
|
||||||
CONFIG_SPIRAM_MODE_OCT=y
|
CONFIG_SPIRAM_MODE_OCT=y
|
||||||
|
|||||||
@ -13,7 +13,7 @@ CONFIG_FREERTOS_HZ=1000
|
|||||||
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
CONFIG_FREERTOS_SMP=n
|
CONFIG_FREERTOS_SMP=n
|
||||||
CONFIG_FREERTOS_UNICORE=n
|
CONFIG_FREERTOS_UNICORE=n
|
||||||
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
@ -25,6 +25,7 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
|
|||||||
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
CONFIG_ESP32_DEFAULT_CPU_FREQ_240=y
|
||||||
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
CONFIG_ESPTOOLPY_FLASHSIZE_16MB=y
|
||||||
CONFIG_FLASHMODE_QIO=y
|
CONFIG_FLASHMODE_QIO=y
|
||||||
|
CONFIG_FREERTOS_PLACE_FUNCTIONS_INTO_FLASH=y
|
||||||
# Hardware: SPI RAM
|
# Hardware: SPI RAM
|
||||||
CONFIG_SPIRAM=y
|
CONFIG_SPIRAM=y
|
||||||
CONFIG_SPIRAM_MODE_QUAD=y
|
CONFIG_SPIRAM_MODE_QUAD=y
|
||||||
|
|||||||
@ -13,6 +13,7 @@ CONFIG_FREERTOS_HZ=1000
|
|||||||
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
CONFIG_FREERTOS_SMP=n
|
CONFIG_FREERTOS_SMP=n
|
||||||
CONFIG_FREERTOS_UNICORE=n
|
CONFIG_FREERTOS_UNICORE=n
|
||||||
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
|||||||
@ -13,6 +13,7 @@ CONFIG_FREERTOS_HZ=1000
|
|||||||
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
CONFIG_FREERTOS_TASK_NOTIFICATION_ARRAY_ENTRIES=2
|
||||||
CONFIG_FREERTOS_SMP=n
|
CONFIG_FREERTOS_SMP=n
|
||||||
CONFIG_FREERTOS_UNICORE=n
|
CONFIG_FREERTOS_UNICORE=n
|
||||||
|
CONFIG_FREERTOS_TIMER_TASK_STACK_DEPTH=4096
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||||
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv"
|
||||||
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
CONFIG_PARTITION_TABLE_FILENAME="partitions.csv"
|
||||||
|
|||||||
4
sdkconfig.developer
Normal file
4
sdkconfig.developer
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
CONFIG_STACK_CHECK_STRONG=y
|
||||||
|
LV_USE_SYSMON=y
|
||||||
|
CONFIG_LV_USE_OBSERVER=y
|
||||||
|
CONFIG_LV_USE_PERF_MONITOR=y
|
||||||
Loading…
x
Reference in New Issue
Block a user