mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-06-20 20:38:24 -07:00
V45 Hotfix (#231)
This commit is contained in:
@@ -12,37 +12,37 @@ if __name__ == "__main__":
|
||||
event = json.load(f)
|
||||
|
||||
release = requests.get(
|
||||
event["repository"]["releases_url"].rsplit("{/")[0] + "latest",
|
||||
event["repository"]["releases_url"].rsplit("{/")[0] + "/latest",
|
||||
headers={
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
"Authorization": f"token {os.environ['GITHUB_TOKEN']}"
|
||||
}
|
||||
).json()
|
||||
|
||||
artifacts = (
|
||||
os.environ['ARTIFACT_TGZ'],
|
||||
os.environ['ARTIFACT_ZIP']
|
||||
)
|
||||
artifacts = {
|
||||
os.environ['ARTIFACT_TGZ']: "application/gzip",
|
||||
os.environ['ARTIFACT_ZIP']: "application/zip"
|
||||
}
|
||||
|
||||
for asset in release["assets"]:
|
||||
if asset["name"] in artifacts:
|
||||
req = requests.delete(
|
||||
asset["url"],
|
||||
headers={
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
"Authorization": f"token {os.environ['GITHUB_TOKEN']}"
|
||||
}
|
||||
)
|
||||
if not req.ok:
|
||||
print(f"{req.url = }\n{req.status_code = }\n{req.content = }")
|
||||
sys.exit(1)
|
||||
req = requests.delete(
|
||||
asset["url"],
|
||||
headers={
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
"Authorization": f"token {os.environ['GITHUB_TOKEN']}"
|
||||
}
|
||||
)
|
||||
if not req.ok:
|
||||
print(f"{req.url = }\n{req.status_code = }\n{req.content = }")
|
||||
sys.exit(1)
|
||||
|
||||
for artifact in artifacts:
|
||||
for artifact, mediatype in artifacts.items():
|
||||
req = requests.post(
|
||||
release["upload_url"].rsplit("{?", 1)[0],
|
||||
headers={
|
||||
"Accept": "application/vnd.github.v3+json",
|
||||
"Authorization": f"token {os.environ['GITHUB_TOKEN']}"
|
||||
"Authorization": f"token {os.environ['GITHUB_TOKEN']}",
|
||||
"Content-Type": mediatype
|
||||
},
|
||||
params={
|
||||
"name": artifact
|
||||
@@ -59,8 +59,13 @@ if __name__ == "__main__":
|
||||
|
||||
body = release["body"]
|
||||
body = re.sub(
|
||||
r"(https://lab\.flipper\.net/\?url=).*?(&channel=XFW-Updater&version=" + os.environ['VERSION_TAG'] + r")",
|
||||
r"\1" + os.environ['ARTIFACT_WEB'] + r"\2",
|
||||
r"(https://lab\.flipper\.net/\?url=).*?(&channel=XFW-Updater&version=)[A-Za-z0-9_-]+",
|
||||
r"\1" + os.environ['ARTIFACT_WEB'] + r"\2" + os.environ['VERSION_TAG'],
|
||||
body
|
||||
)
|
||||
body = re.sub(
|
||||
r"(https://github\.com/ClaraCrazy/Flipper-Xtreme/releases/download/[A-Za-z0-9_-]+?/)[A-Za-z0-9_-]+",
|
||||
r"\1" + os.environ['VERSION_TAG'],
|
||||
body
|
||||
)
|
||||
body = body.replace("<!--- <HOTFIXES>\n", "")
|
||||
|
||||
@@ -5,7 +5,7 @@ if __name__ == "__main__":
|
||||
client = nextcloud_client.Client(os.environ["NC_HOST"])
|
||||
client.login(os.environ["NC_USER"], os.environ["NC_PASS"])
|
||||
file = os.environ["NC_FILE"]
|
||||
path = os.environ["NC_PATH"] + file
|
||||
path = os.environ["NC_PATH"] + "/" + file
|
||||
try:
|
||||
client.delete(path)
|
||||
except Exception:
|
||||
|
||||
@@ -55,6 +55,8 @@ jobs:
|
||||
|
||||
- name: "Upload hotfix"
|
||||
run: python .github/workflow_data/hotfix.py
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
|
||||
- name: "Merge pull request"
|
||||
uses: "pascalgn/automerge-action@v0.15.6"
|
||||
|
||||
Vendored
+16
@@ -9,6 +9,7 @@ enum HidDebugSubmenuIndex {
|
||||
HidSubmenuIndexKeynote,
|
||||
HidSubmenuIndexKeynoteVertical,
|
||||
HidSubmenuIndexKeyboard,
|
||||
HidSubmenuIndexNumpad,
|
||||
HidSubmenuIndexMedia,
|
||||
HidSubmenuIndexTikTok,
|
||||
HidSubmenuIndexYTShorts,
|
||||
@@ -29,6 +30,9 @@ static void hid_submenu_callback(void* context, uint32_t index) {
|
||||
} else if(index == HidSubmenuIndexKeyboard) {
|
||||
app->view_id = HidViewKeyboard;
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, HidViewKeyboard);
|
||||
} else if(index == HidSubmenuIndexNumpad) {
|
||||
app->view_id = HidViewNumpad;
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, HidViewNumpad);
|
||||
} else if(index == HidSubmenuIndexMedia) {
|
||||
app->view_id = HidViewMedia;
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, HidViewMedia);
|
||||
@@ -64,6 +68,7 @@ static void bt_hid_connection_status_changed_callback(BtStatus status, void* con
|
||||
hid_keynote_set_connected_status(hid->hid_keynote, connected);
|
||||
hid_keynote_vertical_set_connected_status(hid->hid_keynote_vertical, connected);
|
||||
hid_keyboard_set_connected_status(hid->hid_keyboard, connected);
|
||||
hid_numpad_set_connected_status(hid->hid_numpad, connected);
|
||||
hid_media_set_connected_status(hid->hid_media, connected);
|
||||
hid_mouse_set_connected_status(hid->hid_mouse, connected);
|
||||
hid_mouse_clicker_set_connected_status(hid->hid_mouse_clicker, connected);
|
||||
@@ -123,6 +128,8 @@ Hid* hid_alloc(HidTransport transport) {
|
||||
app);
|
||||
submenu_add_item(
|
||||
app->device_type_submenu, "Keyboard", HidSubmenuIndexKeyboard, hid_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
app->device_type_submenu, "Numpad", HidSubmenuIndexNumpad, hid_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
app->device_type_submenu, "Media", HidSubmenuIndexMedia, hid_submenu_callback, app);
|
||||
submenu_add_item(
|
||||
@@ -196,6 +203,12 @@ Hid* hid_app_alloc_view(void* context) {
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, HidViewKeyboard, hid_keyboard_get_view(app->hid_keyboard));
|
||||
|
||||
//Numpad keyboard view
|
||||
app->hid_numpad = hid_numpad_alloc(app);
|
||||
view_set_previous_callback(hid_numpad_get_view(app->hid_numpad), hid_exit_confirm_view);
|
||||
view_dispatcher_add_view(
|
||||
app->view_dispatcher, HidViewNumpad, hid_numpad_get_view(app->hid_numpad));
|
||||
|
||||
// Media view
|
||||
app->hid_media = hid_media_alloc(app);
|
||||
view_set_previous_callback(hid_media_get_view(app->hid_media), hid_exit_confirm_view);
|
||||
@@ -228,6 +241,7 @@ Hid* hid_app_alloc_view(void* context) {
|
||||
app->view_dispatcher,
|
||||
HidViewMouseClicker,
|
||||
hid_mouse_clicker_get_view(app->hid_mouse_clicker));
|
||||
|
||||
// Mouse jiggler view
|
||||
app->hid_mouse_jiggler = hid_mouse_jiggler_alloc(app);
|
||||
view_set_previous_callback(
|
||||
@@ -259,6 +273,8 @@ void hid_free(Hid* app) {
|
||||
hid_keynote_vertical_free(app->hid_keynote_vertical);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, HidViewKeyboard);
|
||||
hid_keyboard_free(app->hid_keyboard);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, HidViewNumpad);
|
||||
hid_numpad_free(app->hid_numpad);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, HidViewMedia);
|
||||
hid_media_free(app->hid_media);
|
||||
view_dispatcher_remove_view(app->view_dispatcher, HidViewMouse);
|
||||
|
||||
Vendored
+2
@@ -19,6 +19,7 @@
|
||||
#include "views/hid_keynote.h"
|
||||
#include "views/hid_keynote_vertical.h"
|
||||
#include "views/hid_keyboard.h"
|
||||
#include "views/hid_numpad.h"
|
||||
#include "views/hid_media.h"
|
||||
#include "views/hid_mouse.h"
|
||||
#include "views/hid_mouse_jiggler.h"
|
||||
@@ -45,6 +46,7 @@ struct Hid {
|
||||
HidKeynote* hid_keynote;
|
||||
HidKeynoteVertical* hid_keynote_vertical;
|
||||
HidKeyboard* hid_keyboard;
|
||||
HidNumpad* hid_numpad;
|
||||
HidMedia* hid_media;
|
||||
HidMouse* hid_mouse;
|
||||
HidMouseClicker* hid_mouse_clicker;
|
||||
|
||||
+1
@@ -3,6 +3,7 @@ typedef enum {
|
||||
HidViewKeynote,
|
||||
HidViewKeynoteVertical,
|
||||
HidViewKeyboard,
|
||||
HidViewNumpad,
|
||||
HidViewMedia,
|
||||
HidViewMouse,
|
||||
HidViewMouseClicker,
|
||||
|
||||
+1
-1
@@ -118,7 +118,7 @@ static bool hid_mouse_clicker_input_callback(InputEvent* event, void* context) {
|
||||
bool consumed = false;
|
||||
bool rate_changed = false;
|
||||
|
||||
if(event->type != InputTypeRelease) {
|
||||
if(event->type != InputTypeShort && event->type != InputTypeRepeat) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+302
@@ -0,0 +1,302 @@
|
||||
#include "hid_numpad.h"
|
||||
#include <furi.h>
|
||||
#include <gui/elements.h>
|
||||
#include <gui/icon_i.h>
|
||||
#include "../hid.h"
|
||||
#include "hid_icons.h"
|
||||
|
||||
#define TAG "HidNumpad"
|
||||
|
||||
struct HidNumpad {
|
||||
View* view;
|
||||
Hid* hid;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t last_x;
|
||||
uint8_t last_y;
|
||||
uint8_t x;
|
||||
uint8_t y;
|
||||
uint8_t last_key_code;
|
||||
uint16_t modifier_code;
|
||||
bool ok_pressed;
|
||||
bool back_pressed;
|
||||
bool connected;
|
||||
char key_string[5];
|
||||
HidTransport transport;
|
||||
} HidNumpadModel;
|
||||
|
||||
typedef struct {
|
||||
uint8_t width;
|
||||
char* key;
|
||||
uint8_t height;
|
||||
const Icon* icon;
|
||||
uint8_t value;
|
||||
} HidNumpadKey;
|
||||
|
||||
typedef struct {
|
||||
int8_t x;
|
||||
int8_t y;
|
||||
} HidNumpadPoint;
|
||||
|
||||
#define MARGIN_TOP 0
|
||||
#define MARGIN_LEFT 24
|
||||
#define KEY_WIDTH 20
|
||||
#define KEY_HEIGHT 15
|
||||
#define KEY_PADDING 1
|
||||
#define ROW_COUNT 5
|
||||
#define COLUMN_COUNT 4
|
||||
|
||||
const HidNumpadKey hid_numpad_keyset[ROW_COUNT][COLUMN_COUNT] = {
|
||||
{
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "NL", .value = HID_KEYPAD_NUMLOCK},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "/", .value = HID_KEYPAD_SLASH},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "*", .value = HID_KEYPAD_ASTERISK},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "-", .value = HID_KEYPAD_MINUS},
|
||||
},
|
||||
{
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "7", .value = HID_KEYPAD_7},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "8", .value = HID_KEYBOARD_8},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "9", .value = HID_KEYBOARD_9},
|
||||
{.width = 1, .height = 2, .icon = NULL, .key = "+", .value = HID_KEYPAD_PLUS},
|
||||
},
|
||||
{
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "4", .value = HID_KEYPAD_4},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "5", .value = HID_KEYPAD_5},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "6", .value = HID_KEYPAD_6},
|
||||
},
|
||||
{
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "1", .value = HID_KEYPAD_1},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "2", .value = HID_KEYPAD_2},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = "3", .value = HID_KEYPAD_3},
|
||||
{.width = 1, .height = 2, .icon = NULL, .key = "En", .value = HID_KEYPAD_ENTER},
|
||||
},
|
||||
{
|
||||
{.width = 2, .height = 1, .icon = NULL, .key = "0", .value = HID_KEYBOARD_0},
|
||||
{.width = 0, .height = 0, .icon = NULL, .key = "0", .value = HID_KEYBOARD_0},
|
||||
{.width = 1, .height = 1, .icon = NULL, .key = ".", .value = HID_KEYPAD_DOT},
|
||||
},
|
||||
};
|
||||
|
||||
static void hid_numpad_draw_key(
|
||||
Canvas* canvas,
|
||||
HidNumpadModel* model,
|
||||
uint8_t x,
|
||||
uint8_t y,
|
||||
HidNumpadKey key,
|
||||
bool selected) {
|
||||
if(!key.width || !key.height) return;
|
||||
|
||||
canvas_set_color(canvas, ColorBlack);
|
||||
uint8_t keyWidth = KEY_WIDTH * key.width + KEY_PADDING * (key.width - 1);
|
||||
uint8_t keyHeight = KEY_HEIGHT * key.height + KEY_PADDING * (key.height - 1);
|
||||
if(selected) {
|
||||
elements_slightly_rounded_box(
|
||||
canvas,
|
||||
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING),
|
||||
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING),
|
||||
keyWidth,
|
||||
keyHeight);
|
||||
canvas_set_color(canvas, ColorWhite);
|
||||
} else {
|
||||
elements_slightly_rounded_frame(
|
||||
canvas,
|
||||
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING),
|
||||
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING),
|
||||
keyWidth,
|
||||
keyHeight);
|
||||
}
|
||||
if(key.icon != NULL) {
|
||||
canvas_draw_icon(
|
||||
canvas,
|
||||
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 - key.icon->width / 2,
|
||||
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + keyHeight / 2 - key.icon->height / 2,
|
||||
key.icon);
|
||||
} else {
|
||||
strcpy(model->key_string, key.key);
|
||||
canvas_draw_str_aligned(
|
||||
canvas,
|
||||
MARGIN_LEFT + x * (KEY_WIDTH + KEY_PADDING) + keyWidth / 2 + 1,
|
||||
MARGIN_TOP + y * (KEY_HEIGHT + KEY_PADDING) + keyHeight / 2 + 1,
|
||||
AlignCenter,
|
||||
AlignCenter,
|
||||
model->key_string);
|
||||
}
|
||||
}
|
||||
|
||||
static void hid_numpad_draw_callback(Canvas* canvas, void* context) {
|
||||
furi_assert(context);
|
||||
HidNumpadModel* model = context;
|
||||
|
||||
if((!model->connected) && (model->transport == HidTransportBle)) {
|
||||
canvas_draw_icon(canvas, 0, 0, &I_Ble_disconnected_15x15);
|
||||
canvas_set_font(canvas, FontPrimary);
|
||||
elements_multiline_text_aligned(canvas, 17, 3, AlignLeft, AlignTop, "Numpad");
|
||||
|
||||
canvas_draw_icon(canvas, 68, 3, &I_Pin_back_arrow_10x8);
|
||||
canvas_set_font(canvas, FontSecondary);
|
||||
elements_multiline_text_aligned(canvas, 127, 4, AlignRight, AlignTop, "Hold to exit");
|
||||
|
||||
elements_multiline_text_aligned(
|
||||
canvas, 4, 60, AlignLeft, AlignBottom, "Waiting for Connection...");
|
||||
return;
|
||||
}
|
||||
|
||||
canvas_set_font(canvas, FontKeyboard);
|
||||
uint8_t initY = model->y == 0 ? 0 : 1;
|
||||
|
||||
if(model->y > 5) {
|
||||
initY = model->y - 4;
|
||||
}
|
||||
|
||||
for(uint8_t y = initY; y < ROW_COUNT; y++) {
|
||||
const HidNumpadKey* numpadKeyRow = hid_numpad_keyset[y];
|
||||
uint8_t x = 0;
|
||||
for(uint8_t i = 0; i < COLUMN_COUNT; i++) {
|
||||
HidNumpadKey key = numpadKeyRow[i];
|
||||
bool keySelected = (x <= model->x && model->x < (x + key.width)) && y == model->y;
|
||||
bool backSelected = model->back_pressed && key.value == HID_KEYBOARD_DELETE;
|
||||
hid_numpad_draw_key(
|
||||
canvas,
|
||||
model,
|
||||
x,
|
||||
y - initY,
|
||||
key,
|
||||
(!model->ok_pressed && keySelected) || backSelected);
|
||||
x += key.width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static uint8_t hid_numpad_get_selected_key(HidNumpadModel* model) {
|
||||
HidNumpadKey key = hid_numpad_keyset[model->y][model->x];
|
||||
return key.value;
|
||||
}
|
||||
|
||||
static void hid_numpad_get_select_key(HidNumpadModel* model, HidNumpadPoint delta) {
|
||||
do {
|
||||
const int delta_sum = model->y + delta.y;
|
||||
model->y = delta_sum < 0 ? ROW_COUNT - 1 : delta_sum % ROW_COUNT;
|
||||
} while(delta.y != 0 && hid_numpad_keyset[model->y][model->x].value == 0);
|
||||
|
||||
do {
|
||||
const int delta_sum = model->x + delta.x;
|
||||
model->x = delta_sum < 0 ? COLUMN_COUNT - 1 : delta_sum % COLUMN_COUNT;
|
||||
} while(delta.x != 0 && hid_numpad_keyset[model->y][model->x].width == 0);
|
||||
}
|
||||
|
||||
static void hid_numpad_process(HidNumpad* hid_numpad, InputEvent* event) {
|
||||
with_view_model(
|
||||
hid_numpad->view,
|
||||
HidNumpadModel * model,
|
||||
{
|
||||
if(event->key == InputKeyOk) {
|
||||
if(event->type == InputTypePress) {
|
||||
model->ok_pressed = true;
|
||||
} else if(event->type == InputTypeLong || event->type == InputTypeShort) {
|
||||
model->last_key_code = hid_numpad_get_selected_key(model);
|
||||
hid_hal_keyboard_press(
|
||||
hid_numpad->hid, model->modifier_code | model->last_key_code);
|
||||
} else if(event->type == InputTypeRelease) {
|
||||
hid_hal_keyboard_release(
|
||||
hid_numpad->hid, model->modifier_code | model->last_key_code);
|
||||
model->ok_pressed = false;
|
||||
}
|
||||
} else if(event->key == InputKeyBack) {
|
||||
if(event->type == InputTypePress) {
|
||||
model->back_pressed = true;
|
||||
} else if(event->type == InputTypeShort) {
|
||||
hid_hal_keyboard_press(hid_numpad->hid, HID_KEYBOARD_DELETE);
|
||||
hid_hal_keyboard_release(hid_numpad->hid, HID_KEYBOARD_DELETE);
|
||||
} else if(event->type == InputTypeRelease) {
|
||||
model->back_pressed = false;
|
||||
}
|
||||
} else if(event->type == InputTypePress || event->type == InputTypeRepeat) {
|
||||
if(event->key == InputKeyUp) {
|
||||
hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 0, .y = -1});
|
||||
} else if(event->key == InputKeyDown) {
|
||||
hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 0, .y = 1});
|
||||
} else if(event->key == InputKeyLeft) {
|
||||
if(model->last_x == 2 && model->last_y == 2 && model->y == 1 &&
|
||||
model->x == 3) {
|
||||
model->x = model->last_x;
|
||||
model->y = model->last_y;
|
||||
} else if(
|
||||
model->last_x == 2 && model->last_y == 4 && model->y == 3 &&
|
||||
model->x == 3) {
|
||||
model->x = model->last_x;
|
||||
model->y = model->last_y;
|
||||
} else
|
||||
hid_numpad_get_select_key(model, (HidNumpadPoint){.x = -1, .y = 0});
|
||||
model->last_x = 0;
|
||||
model->last_y = 0;
|
||||
} else if(event->key == InputKeyRight) {
|
||||
if(model->x == 2 && model->y == 2) {
|
||||
model->last_x = model->x;
|
||||
model->last_y = model->y;
|
||||
hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 1, .y = -1});
|
||||
} else if(model->x == 2 && model->y == 4) {
|
||||
model->last_x = model->x;
|
||||
model->last_y = model->y;
|
||||
hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 1, .y = -1});
|
||||
} else {
|
||||
hid_numpad_get_select_key(model, (HidNumpadPoint){.x = 1, .y = 0});
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
true);
|
||||
}
|
||||
|
||||
static bool hid_numpad_input_callback(InputEvent* event, void* context) {
|
||||
furi_assert(context);
|
||||
HidNumpad* hid_numpad = context;
|
||||
bool consumed = false;
|
||||
|
||||
if(event->type == InputTypeLong && event->key == InputKeyBack) {
|
||||
hid_hal_keyboard_release_all(hid_numpad->hid);
|
||||
} else {
|
||||
hid_numpad_process(hid_numpad, event);
|
||||
consumed = true;
|
||||
}
|
||||
|
||||
return consumed;
|
||||
}
|
||||
|
||||
HidNumpad* hid_numpad_alloc(Hid* bt_hid) {
|
||||
HidNumpad* hid_numpad = malloc(sizeof(HidNumpad));
|
||||
hid_numpad->view = view_alloc();
|
||||
hid_numpad->hid = bt_hid;
|
||||
view_set_context(hid_numpad->view, hid_numpad);
|
||||
view_allocate_model(hid_numpad->view, ViewModelTypeLocking, sizeof(HidNumpadModel));
|
||||
view_set_draw_callback(hid_numpad->view, hid_numpad_draw_callback);
|
||||
view_set_input_callback(hid_numpad->view, hid_numpad_input_callback);
|
||||
|
||||
with_view_model(
|
||||
hid_numpad->view,
|
||||
HidNumpadModel * model,
|
||||
{
|
||||
model->transport = bt_hid->transport;
|
||||
model->y = 0;
|
||||
},
|
||||
true);
|
||||
|
||||
return hid_numpad;
|
||||
}
|
||||
|
||||
void hid_numpad_free(HidNumpad* hid_numpad) {
|
||||
furi_assert(hid_numpad);
|
||||
view_free(hid_numpad->view);
|
||||
free(hid_numpad);
|
||||
}
|
||||
|
||||
View* hid_numpad_get_view(HidNumpad* hid_numpad) {
|
||||
furi_assert(hid_numpad);
|
||||
return hid_numpad->view;
|
||||
}
|
||||
|
||||
void hid_numpad_set_connected_status(HidNumpad* hid_numpad, bool connected) {
|
||||
furi_assert(hid_numpad);
|
||||
with_view_model(
|
||||
hid_numpad->view, HidNumpadModel * model, { model->connected = connected; }, true);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
#pragma once
|
||||
|
||||
#include <gui/view.h>
|
||||
|
||||
typedef struct Hid Hid;
|
||||
typedef struct HidNumpad HidNumpad;
|
||||
|
||||
HidNumpad* hid_numpad_alloc(Hid* bt_hid);
|
||||
|
||||
void hid_numpad_free(HidNumpad* hid_numpad);
|
||||
|
||||
View* hid_numpad_get_view(HidNumpad* hid_numpad);
|
||||
|
||||
void hid_numpad_set_connected_status(HidNumpad* hid_numpad, bool connected);
|
||||
@@ -5,7 +5,7 @@
|
||||
/*
|
||||
* Wendox W6726
|
||||
*
|
||||
* Temperature -50°Ñ to +70°Ñ
|
||||
* Temperature -50C to +70C
|
||||
* _ _ _ __ _
|
||||
* _| |___| |___| |___ ... | |_| |__...._______________
|
||||
* preamble data guard time
|
||||
@@ -22,7 +22,7 @@
|
||||
*
|
||||
* I: identification;
|
||||
* Z: temperature sign;
|
||||
* T: temperature sign dependent +12 Ѱ;
|
||||
* T: temperature sign dependent +12C;
|
||||
* B: battery low; flag to indicate low battery voltage;
|
||||
* C: CRC4 (polynomial = 0x9, start_data = 0xD);
|
||||
* u: unknown;
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define WIFI_MARAUDER_APP_VERSION "v0.3.3"
|
||||
#define WIFI_MARAUDER_APP_VERSION "v0.3.4"
|
||||
|
||||
typedef struct WifiMarauderApp WifiMarauderApp;
|
||||
|
||||
|
||||
@@ -13,12 +13,6 @@
|
||||
|
||||
#define BAD_KB_SETTINGS_PATH BAD_KB_APP_BASE_FOLDER "/" BAD_KB_SETTINGS_FILE_NAME
|
||||
|
||||
// this is the MAC address used when we do not forget paired device (BOUND STATE)
|
||||
const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] =
|
||||
{0x41, 0x4a, 0xef, 0xb6, 0xa9, 0xd4};
|
||||
const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
static bool bad_kb_app_custom_event_callback(void* context, uint32_t event) {
|
||||
furi_assert(context);
|
||||
BadKbApp* app = context;
|
||||
|
||||
@@ -12,6 +12,11 @@
|
||||
#include <dolphin/dolphin.h>
|
||||
#include <toolbox/hex.h>
|
||||
|
||||
const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] =
|
||||
{0x41, 0x4a, 0xef, 0xb6, 0xa9, 0xd4};
|
||||
const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN] =
|
||||
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
#define TAG "BadKB"
|
||||
#define WORKER_TAG TAG "Worker"
|
||||
|
||||
@@ -383,7 +388,8 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) {
|
||||
bad_kb->app->switch_mode_thread = NULL;
|
||||
}
|
||||
// Looking for ID or BT_ID command at first line
|
||||
bool reset_bt_id = !!bad_kb->bt;
|
||||
bool usb_id = false;
|
||||
bool bt_id = false;
|
||||
if(strncmp(line_tmp, ducky_cmd_id, strlen(ducky_cmd_id)) == 0) {
|
||||
if(bad_kb->bt) {
|
||||
bad_kb->app->is_bt = false;
|
||||
@@ -395,11 +401,7 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) {
|
||||
furi_thread_start(bad_kb->app->switch_mode_thread);
|
||||
return false;
|
||||
}
|
||||
if(ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1])) {
|
||||
furi_check(furi_hal_usb_set_config(&usb_hid, &bad_kb->hid_cfg));
|
||||
} else {
|
||||
furi_check(furi_hal_usb_set_config(&usb_hid, NULL));
|
||||
}
|
||||
usb_id = ducky_set_usb_id(bad_kb, &line_tmp[strlen(ducky_cmd_id) + 1]);
|
||||
} else if(strncmp(line_tmp, ducky_cmd_bt_id, strlen(ducky_cmd_bt_id)) == 0) {
|
||||
if(!bad_kb->bt) {
|
||||
bad_kb->app->is_bt = true;
|
||||
@@ -412,12 +414,39 @@ static bool ducky_script_preload(BadKbScript* bad_kb, File* script_file) {
|
||||
return false;
|
||||
}
|
||||
if(!bad_kb->app->bt_remember) {
|
||||
reset_bt_id = !ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]);
|
||||
bt_id = ducky_set_bt_id(bad_kb, &line_tmp[strlen(ducky_cmd_bt_id) + 1]);
|
||||
}
|
||||
}
|
||||
if(reset_bt_id) {
|
||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, bad_kb->app->config.bt_name);
|
||||
bt_set_profile_mac_address(bad_kb->bt, bad_kb->app->config.bt_mac);
|
||||
|
||||
if(bad_kb->bt) {
|
||||
if(!bt_id) {
|
||||
const char* bt_name = bad_kb->app->config.bt_name;
|
||||
const uint8_t* bt_mac = bad_kb->app->bt_remember ?
|
||||
(uint8_t*)&BAD_KB_BOUND_MAC_ADDRESS :
|
||||
bad_kb->app->config.bt_mac;
|
||||
bool reset_name = strncmp(
|
||||
bt_name,
|
||||
furi_hal_bt_get_profile_adv_name(FuriHalBtProfileHidKeyboard),
|
||||
BAD_KB_ADV_NAME_MAX_LEN);
|
||||
bool reset_mac = memcmp(
|
||||
bt_mac,
|
||||
furi_hal_bt_get_profile_mac_addr(FuriHalBtProfileHidKeyboard),
|
||||
BAD_KB_MAC_ADDRESS_LEN);
|
||||
if(reset_name && reset_mac) {
|
||||
furi_hal_bt_set_profile_adv_name(FuriHalBtProfileHidKeyboard, bt_name);
|
||||
} else if(reset_name) {
|
||||
bt_set_profile_adv_name(bad_kb->bt, bt_name);
|
||||
}
|
||||
if(reset_mac) {
|
||||
bt_set_profile_mac_address(bad_kb->bt, bt_mac);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if(usb_id) {
|
||||
furi_check(furi_hal_usb_set_config(&usb_hid, &bad_kb->hid_cfg));
|
||||
} else {
|
||||
furi_check(furi_hal_usb_set_config(&usb_hid, NULL));
|
||||
}
|
||||
}
|
||||
|
||||
storage_file_seek(script_file, 0, true);
|
||||
|
||||
@@ -103,6 +103,10 @@ BadKbState* bad_kb_script_get_state(BadKbScript* bad_kb);
|
||||
#define BAD_KB_ADV_NAME_MAX_LEN FURI_HAL_BT_ADV_NAME_LENGTH
|
||||
#define BAD_KB_MAC_ADDRESS_LEN GAP_MAC_ADDR_SIZE
|
||||
|
||||
// this is the MAC address used when we do not forget paired device (BOUND STATE)
|
||||
extern const uint8_t BAD_KB_BOUND_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN];
|
||||
extern const uint8_t BAD_KB_EMPTY_MAC_ADDRESS[BAD_KB_MAC_ADDRESS_LEN];
|
||||
|
||||
typedef enum {
|
||||
BadKbAppErrorNoFiles,
|
||||
BadKbAppErrorCloseRpc,
|
||||
|
||||
@@ -171,6 +171,7 @@ static int32_t ducky_fnc_waitforbutton(BadKbScript* bad_kb, const char* line, in
|
||||
static const DuckyCmd ducky_commands[] = {
|
||||
{"REM", NULL, -1},
|
||||
{"ID", NULL, -1},
|
||||
{"BT_ID", NULL, -1},
|
||||
{"DELAY", ducky_fnc_delay, -1},
|
||||
{"STRING", ducky_fnc_string, 0},
|
||||
{"STRINGLN", ducky_fnc_string, 1},
|
||||
|
||||
@@ -124,7 +124,7 @@ void subghz_scene_read_raw_on_enter(void* context) {
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdReadRAW);
|
||||
|
||||
// Start sending immediately with favorites
|
||||
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW)) {
|
||||
if(subghz->fav_timeout) {
|
||||
with_view_model(
|
||||
subghz->subghz_read_raw->view,
|
||||
SubGhzReadRAWModel * model,
|
||||
@@ -293,7 +293,7 @@ bool subghz_scene_read_raw_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz_read_raw_stop_send(subghz->subghz_read_raw);
|
||||
|
||||
// Exit / stop with favorites
|
||||
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneReadRAW)) {
|
||||
if(subghz->fav_timeout) {
|
||||
while(scene_manager_handle_back_event(subghz->scene_manager))
|
||||
;
|
||||
view_dispatcher_stop(subghz->view_dispatcher);
|
||||
|
||||
@@ -51,8 +51,6 @@ bool subghz_scene_transmitter_update_data_show(void* context) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
FuriTimer* fav_timer = NULL;
|
||||
|
||||
void fav_timer_callback(void* context) {
|
||||
SubGhz* subghz = context;
|
||||
scene_manager_handle_custom_event(
|
||||
@@ -77,7 +75,7 @@ void subghz_scene_transmitter_on_enter(void* context) {
|
||||
view_dispatcher_switch_to_view(subghz->view_dispatcher, SubGhzViewIdTransmitter);
|
||||
|
||||
// Auto send and exit with favorites
|
||||
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTransmitter)) {
|
||||
if(subghz->fav_timeout) {
|
||||
subghz_custom_btn_set(0);
|
||||
scene_manager_handle_custom_event(
|
||||
subghz->scene_manager, SubGhzCustomEventViewTransmitterSendStart);
|
||||
@@ -86,9 +84,10 @@ void subghz_scene_transmitter_on_enter(void* context) {
|
||||
SubGhzViewTransmitterModel * model,
|
||||
{ model->show_button = false; },
|
||||
true);
|
||||
fav_timer = furi_timer_alloc(fav_timer_callback, FuriTimerTypeOnce, subghz);
|
||||
subghz->fav_timer = furi_timer_alloc(fav_timer_callback, FuriTimerTypeOnce, subghz);
|
||||
furi_timer_start(
|
||||
fav_timer, XTREME_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency());
|
||||
subghz->fav_timer,
|
||||
XTREME_SETTINGS()->favorite_timeout * furi_kernel_get_tick_frequency());
|
||||
subghz->state_notifications = SubGhzNotificationStateTx;
|
||||
}
|
||||
}
|
||||
@@ -134,11 +133,7 @@ bool subghz_scene_transmitter_on_event(void* context, SceneManagerEvent event) {
|
||||
subghz_sleep(subghz);
|
||||
furi_hal_subghz_set_rolling_counter_mult(tmp_counter);
|
||||
}
|
||||
if(scene_manager_get_scene_state(subghz->scene_manager, SubGhzSceneTransmitter)) {
|
||||
if(fav_timer) {
|
||||
furi_timer_stop(fav_timer);
|
||||
furi_timer_free(fav_timer);
|
||||
}
|
||||
if(subghz->fav_timeout) {
|
||||
while(scene_manager_handle_back_event(subghz->scene_manager))
|
||||
;
|
||||
view_dispatcher_stop(subghz->view_dispatcher);
|
||||
|
||||
@@ -474,16 +474,13 @@ int32_t subghz_app(char* p) {
|
||||
if(subghz_key_load(subghz, p, true)) {
|
||||
furi_string_set(subghz->file_path, (const char*)p);
|
||||
|
||||
subghz->fav_timeout = is_favorite;
|
||||
if((!strcmp(subghz->txrx->decoder_result->protocol->name, "RAW"))) {
|
||||
//Load Raw TX
|
||||
subghz->txrx->rx_key_state = SubGhzRxKeyStateRAWLoad;
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneReadRAW, is_favorite);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneReadRAW);
|
||||
} else {
|
||||
//Load transmitter TX
|
||||
scene_manager_set_scene_state(
|
||||
subghz->scene_manager, SubGhzSceneTransmitter, is_favorite);
|
||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneTransmitter);
|
||||
}
|
||||
} else {
|
||||
@@ -512,6 +509,11 @@ int32_t subghz_app(char* p) {
|
||||
|
||||
view_dispatcher_run(subghz->view_dispatcher);
|
||||
|
||||
if(subghz->fav_timer) {
|
||||
furi_timer_stop(subghz->fav_timer);
|
||||
furi_timer_free(subghz->fav_timer);
|
||||
}
|
||||
|
||||
furi_hal_power_suppress_charge_exit();
|
||||
// Disable power for External CC1101 if it was enabled and module is connected
|
||||
furi_hal_subghz_disable_ext_power();
|
||||
|
||||
@@ -131,6 +131,9 @@ struct SubGhz {
|
||||
SubGhzDecodeRawState decode_raw_state;
|
||||
SubGhzFileEncoderWorker* decode_raw_file_worker_encoder;
|
||||
|
||||
bool fav_timeout;
|
||||
FuriTimer* fav_timer;
|
||||
|
||||
void* rpc_ctx;
|
||||
};
|
||||
|
||||
|
||||
@@ -133,7 +133,6 @@ void desktop_lock(Desktop* desktop) {
|
||||
scene_manager_set_scene_state(
|
||||
desktop->scene_manager, DesktopSceneLocked, SCENE_LOCKED_FIRST_ENTER);
|
||||
scene_manager_next_scene(desktop->scene_manager, DesktopSceneLocked);
|
||||
notification_message(desktop->notification, &sequence_display_backlight_off_delay_1000);
|
||||
}
|
||||
|
||||
void desktop_unlock(Desktop* desktop) {
|
||||
|
||||
@@ -19,19 +19,16 @@ void view_tie_icon_animation(View* view, IconAnimation* icon_animation) {
|
||||
|
||||
void view_set_draw_callback(View* view, ViewDrawCallback callback) {
|
||||
furi_assert(view);
|
||||
furi_assert(view->draw_callback == NULL);
|
||||
view->draw_callback = callback;
|
||||
}
|
||||
|
||||
void view_set_input_callback(View* view, ViewInputCallback callback) {
|
||||
furi_assert(view);
|
||||
furi_assert(view->input_callback == NULL);
|
||||
view->input_callback = callback;
|
||||
}
|
||||
|
||||
void view_set_custom_callback(View* view, ViewCustomCallback callback) {
|
||||
furi_assert(view);
|
||||
furi_assert(callback);
|
||||
view->custom_callback = callback;
|
||||
}
|
||||
|
||||
@@ -62,7 +59,6 @@ void view_set_update_callback_context(View* view, void* context) {
|
||||
|
||||
void view_set_context(View* view, void* context) {
|
||||
furi_assert(view);
|
||||
furi_assert(context);
|
||||
view->context = context;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
/* Generated table */
|
||||
#include <firmware_api_table.h>
|
||||
|
||||
#include <furi_hal_info.h>
|
||||
|
||||
static_assert(!has_hash_collisions(elf_api_table), "Detected API method hash collision!");
|
||||
|
||||
constexpr HashtableApiInterface elf_api_interface{
|
||||
@@ -19,3 +21,8 @@ constexpr HashtableApiInterface elf_api_interface{
|
||||
};
|
||||
|
||||
const ElfApiInterface* const firmware_api_interface = &elf_api_interface;
|
||||
|
||||
extern "C" void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) {
|
||||
*major = elf_api_interface.api_version_major;
|
||||
*minor = elf_api_interface.api_version_minor;
|
||||
}
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Import("env")
|
||||
|
||||
from fbt.version import get_git_commit_unix_timestamp
|
||||
|
||||
Import("env")
|
||||
|
||||
assetsenv = env.Clone(
|
||||
tools=["fbt_assets"],
|
||||
FW_LIB_NAME="assets",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 14th Apr, 2023
|
||||
# Last Checked 25th Apr, 2023
|
||||
# Last Updated 2nd May, 2023
|
||||
# Last Checked 2nd May, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
@@ -1740,3 +1740,33 @@ type: parsed
|
||||
protocol: NEC
|
||||
address: 04 00 00 00
|
||||
command: 00 00 00 00
|
||||
#
|
||||
name: TEMP+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 443 457 418 451 424 445 420 449 416 453 422 25403 3487 1758 421 1325 416 445 420 452 423 446 419 1319 422 447 418 450 415 456 419 449 416 1323 418 454 421 1316 414 1326 415 462 424 1307 423 1315 415 1323 418 1322 419 1321 420 449 416 452 423 1316 414 455 420 448 417 453 422 447 418 452 423 448 417 451 424 443 422 450 415 452 423 445 420 450 415 456 419 450 415 452 423 447 418 450 415 456 419 1318 423 447 418 454 421 445 420 450 415 453 422 446 419 451 424 1315 415 1324 417 454 421 446 419 1321 420 1319 422 448 417 452 423 445 420 449 416 453 422 448 417 452 423 445 420 449 416 455 420 1319 422 1314 416 1325 416 1322 419 1322 419 1318 423 1317 424 447 418 1320 421 1317 424 1317 424 1315 415 455 420 449 416 452 423 447 418 451 414 454 421 448 417 453 422 448 417 452 423 444 421 449 416 452 423 447 418 453 422 445 420 450 415 456 419 448 417 453 422 446 419 450 415 455 420 450 415 453 422 448 417 452 423 444 421 448 417 454 421 446 419 452 423 445 420 450 415 453 422 447 418 451 424 446 419 449 416 454 421 447 418 452 423 446 419 452 423 1315 415 451 424 1316 414 456 419 451 414 453 422 1317 424 1316 425 444 421 447 418 452 423 448 417 450 415 455 420 456 419 449 416 446 419 451 414 455 420 1320 421 447 418 452 423 453 422 439 415 1324 417 459 416 446 419 451 424 446 419 1320 421 446 419 1319 422
|
||||
#
|
||||
name: TEMP-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 444 455 420 449 416 454 421 448 417 451 424 25402 3487 1758 421 1317 424 445 420 452 423 443 422 1317 424 447 418 451 424 447 418 449 416 1324 417 452 423 1315 415 1324 417 452 423 1316 425 1315 415 1325 416 1323 418 1319 422 449 416 452 423 1318 423 445 420 448 417 453 422 447 418 452 423 446 419 449 416 455 420 447 418 453 422 446 419 452 423 446 419 451 424 444 421 447 418 451 424 445 420 1320 421 448 417 454 421 445 420 452 423 445 420 450 415 454 421 1316 414 1324 417 454 421 448 417 1321 420 1320 421 448 417 453 422 446 419 452 423 446 419 449 416 455 420 448 417 451 424 445 420 1321 420 1319 422 1316 414 1324 417 1324 417 1321 420 1320 421 449 416 1323 418 1323 418 1319 422 1317 424 446 419 453 422 445 420 450 415 453 422 448 417 452 423 447 418 450 415 455 420 448 417 454 421 445 420 451 414 455 420 449 416 454 421 448 417 452 423 446 419 449 416 454 421 447 418 452 423 445 420 450 415 454 421 450 415 454 421 447 418 452 423 444 421 451 424 442 423 449 416 451 424 445 420 450 415 455 420 448 417 454 421 447 418 450 415 457 418 1317 424 448 417 1320 421 448 417 453 422 449 416 1321 420 1320 421 448 417 452 423 449 416 451 424 446 419 448 417 454 421 449 416 452 423 447 418 452 423 1315 415 452 423 447 418 451 424 446 419 1319 422 448 417 451 424 446 419 449 416 1324 417 453 422 1316 414
|
||||
# SWING_HORIZONTAL
|
||||
name: SWING
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 446 455 420 449 416 461 393 467 419 454 421 25402 3484 1759 419 1319 422 449 416 454 421 447 418 1322 419 449 416 454 421 449 416 452 423 1317 424 444 421 1321 420 1316 425 446 419 1329 422 1308 422 1318 422 1317 424 1314 416 453 422 447 418 1323 418 451 424 444 421 448 417 454 421 449 416 458 417 444 421 449 416 454 421 447 418 453 422 446 419 456 419 445 420 448 417 452 423 446 419 451 424 1316 414 453 422 447 418 453 422 446 419 451 414 455 420 449 416 1324 417 1321 420 452 423 444 421 1318 423 1317 423 445 420 450 415 455 420 447 418 455 420 447 418 451 424 445 420 456 419 444 421 1317 424 1316 424 1315 415 1323 417 452 423 1316 414 456 419 1318 423 448 417 452 423 444 421 450 415 456 419 448 417 453 422 447 418 450 415 454 421 448 417 454 421 446 419 452 423 446 419 449 416 455 420 448 417 452 423 448 417 451 424 451 424 445 420 444 421 447 418 460 415 446 419 451 424 446 419 450 415 454 421 449 416 1321 420 451 424 444 421 449 416 453 422 447 418 454 421 445 420 449 416 456 419 449 416 452 423 447 418 451 424 444 421 451 424 1314 416 453 422 1324 417 445 420 449 416 453 422 1319 422 1315 415 455 420 448 417 452 423 453 422 442 423 451 424 439 415 454 421 447 418 451 424 447 418 1322 418 451 424 442 423 448 417 451 424 1317 423 1315 415 454 421 449 416 460 415 446 419 1320 421 1319 422
|
||||
# OFF
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 445 455 421 449 416 453 422 447 418 451 424 25400 3494 1753 416 1322 419 450 415 456 420 449 416 1325 416 451 425 444 421 448 417 453 423 1318 423 444 421 1320 421 1316 414 457 419 1320 421 1318 423 1314 417 1322 419 1320 421 449 416 453 422 1317 424 445 420 450 415 456 419 447 418 451 414 456 420 449 416 452 424 448 417 453 422 445 420 450 415 456 419 448 417 452 423 447 418 449 416 453 423 448 417 453 423 446 419 449 416 453 423 447 418 1321 420 451 414 454 422 449 416 1322 419 1319 422 449 416 1322 419 451 424 445 420 449 416 455 421 445 420 449 416 455 420 448 417 452 424 446 419 1321 420 1317 424 1315 416 1324 417 1322 419 1320 421 1320 421 446 419 1319 422 1319 422 1318 423 1313 417 453 423 445 420 450 415 454 421 449 416 454 422 446 419 449 416 456 420 448 417 453 423 444 421 450 415 454 422 447 418 451 424 445 420 450 415 455 420 447 418 452 424 447 418 451 424 445 420 448 417 453 423 446 419 451 424 444 421 448 417 452 423 446 419 451 424 445 420 448 417 451 414 456 420 452 424 443 422 449 416 451 424 448 417 449 416 455 420 1318 423 446 419 1319 422 448 417 451 424 447 418 1320 421 1316 415 455 421 451 414 455 421 449 416 451 424 446 419 1319 422 448 417 454 422 446 419 451 414 1325 416 452 423 447 418 451 424 447 418 1318 423 446 419 449 416 1327 424 1312 419 449 416 455 421 449 416
|
||||
# OFF
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 645 17766 3059 8884 533 461 557 1427 560 435 584 433 534 458 534 458 534 458 588 404 587 405 586 1399 586 407 584 408 558 1429 555 1457 502 491 525 1460 528 1458 554 1431 554 1431 555 1431 554 438 555 438 554 439 553 440 553 464 528 464 528 464 529 465 528 465 526 467 526 467 527 465 553 439 554 439 554 438 554 439 554 439 553 439 554 439 553 439 553 439 554 440 552 464 528 464 528 465 528 466 527 466 501 492 525 468 526 466 527 466 553 439 554 439 553 440 552 1433 553 1433 553 2936 3024 8893 552 1458 527 465 528 465 527 467 526 467 500 493 524 468 526 467 526 467 552 1434 552 441 552 441 552 1435 550 465 528 1458 527 1458 528 1459 527 1485 501 1485 500 1486 501 491 527 466 528 465 528 465 527 465 528 465 527 465 528 465 528 465 527 465 528 465 527 466 527 466 527 492 500 492 501 492 500 493 500 493 500 492 526 466 527 465 527 465 527 465 527 466 527 466 527 466 527 465 527 466 526 466 527 466 526 467 526 493 499 493 474 518 499 494 500 493 526 2936 3025 8918 526 1459 527 466 527 466 527 466 526 466 527 466 526 467 526 467 525 467 526 1460 525 493 499 493 498 495 498 495 499 493 500 493 525 1460 527 1460 525 1460 526 1460 525 1460 526 1460 526 468 525 1487 499 1487 497 495 498 495 499 493 500 1486 525 1460 525 1460 525 467 525 467 526 467 525 467 526 468 524 1462 524 468 524 494 498 1488 497 1488 499 494 499 493 525 468 525 1461 524 468 525 468 524 468 525 468 525 468 524 468 525 469 524 494 498 494 499 1488 473 1514 524
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 14th Apr, 2023
|
||||
# Last Checked 25th Apr, 2023
|
||||
# Last Checked 2nd May, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 14th Apr, 2023
|
||||
# Last Checked 25th Apr, 2023
|
||||
# Last Updated 2nd May, 2023
|
||||
# Last Checked 2nd May, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
@@ -1497,3 +1497,9 @@ type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 3534 3439 954 2505 985 2535 955 798 954 2535 899 2591 899 2599 899 853 925 2566 924 2567 922 2596 894 2596 894 867 894 859 894 860 893 2597 894 859 894 859 894 867 894 2597 893 859 894 859 894 860 893 859 894 2605 894 40336 3531 3469 894 2597 893 2597 893 859 894 2597 893 2597 893 2605 893 860 893 2597 893 2597 893 2597 894 2597 893 868 893 860 893 860 893 2597 893 860 893 860 893 868 893 2597 893 860 893 860 893 860 893 860 893 2605 893
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 80 00 00 00
|
||||
command: 1A 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 14th Apr, 2023
|
||||
# Last Checked 25th Apr, 2023
|
||||
# Last Updated 2nd May, 2023
|
||||
# Last Checked 2nd May, 2023
|
||||
#
|
||||
# ON
|
||||
name: POWER
|
||||
@@ -886,3 +886,27 @@ type: parsed
|
||||
protocol: NECext
|
||||
address: 84 F4 00 00
|
||||
command: 2F D0 00 00
|
||||
#
|
||||
name: MUTE
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 4F 50 00 00
|
||||
command: 0F F0 00 00
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 02 00 00 00
|
||||
command: 12 00 00 00
|
||||
#
|
||||
name: VOL-
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 02 00 00 00
|
||||
command: 06 00 00 00
|
||||
#
|
||||
name: VOL+
|
||||
type: parsed
|
||||
protocol: NEC
|
||||
address: 02 00 00 00
|
||||
command: 00 00 00 00
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Filetype: IR library file
|
||||
Version: 1
|
||||
# Last Updated 2, May, 2023
|
||||
# Last Checked 2, May, 2023
|
||||
# Last Updated 2nd May, 2023
|
||||
# Last Checked 2nd May, 2023
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
@@ -1899,39 +1899,77 @@ type: parsed
|
||||
protocol: SIRC20
|
||||
address: 10 01 00 00
|
||||
command: 33 00 00 00
|
||||
#
|
||||
# Sharp TV
|
||||
#
|
||||
name: POWER
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 BD 00 00
|
||||
command: 01 FE 00 00
|
||||
#
|
||||
name: VOL+
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 BD 00 00
|
||||
command: 0C F3 00 00
|
||||
#
|
||||
name: VOL-
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 BD 00 00
|
||||
command: 10 EF 00 00
|
||||
#
|
||||
name: CH+
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 BD 00 00
|
||||
command: 18 E7 00 00
|
||||
#
|
||||
name: CH-
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 BD 00 00
|
||||
command: 1C E3 00 00
|
||||
#
|
||||
name: MUTE
|
||||
type: parsed
|
||||
protocol: NECext
|
||||
address: 00 BD 00 00
|
||||
command: 04 FB 00 00
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 195 1833 300 766 280 760 275 790 276 737 309 731 304 1801 301 1804 309 731 304 1801 270 795 282 758 277 762 273 1832 270 769 246 45851 326 1780 302 739 307 785 282 732 303 736 310 1795 307 732 303 763 303 1775 307 733 334 1798 273 1832 270 1810 251 814 273 1780 281 43762 302 1804 309 758 277 737 330 762 284 730 305 734 301 1803 310 1796 306 733 302 1829 273 767 279 734 301 791 275 1804 278 762 253 45870 307 1798 304 763 272 767 279 787 279 760 275 1829 284 730 305 734 301 1804 309 757 278 1827 275 1804 278 1828 274 765 270 1835 278 43740 303 1776 306 787 279 760 275 765 281 759 307 758 277 1775 307 1799 303 736 299 1832 281 759 276 763 304 736 299 1832 281 733 302 45820 306 1800 302 764 282 758 277 788 278 762 284 1821 281 732 303 736 310 1796 307 733 302 1829 273 1806 276 1830 272 767 268 1837 245 43772 302 1778 304 789 277 762 284 756 279 786 249 765 301 1777 336 1770 301 764 282 1824 278 761 274 765 301 738 308 1824 278 761 274
|
||||
data: 278 1811 277 788 246 794 250 764 280 786 248 792 252 1813 275 1815 273 791 253 1812 276 789 255 785 249 791 253 1812 276 789 255 45322 280 1809 279 786 248 766 278 788 246 794 250 1815 273 792 252 788 246 1819 280 785 249 1817 271 1819 280 1810 278 787 247 1818 281 43217 274 1818 270 794 250 764 280 786 248 792 252 788 256 1809 279 1811 277 788 246 1819 280 785 249 766 278 762 272 1819 280 785 248
|
||||
#
|
||||
name: MUTE
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 254 1721 360 681 354 738 308 706 329 711 355 1774 307 1772 361 1744 327 687 359 1772 299 742 335 705 330 736 279 1825 298 742 283 44773 384 1721 360 707 308 707 359 733 302 711 335 705 361 704 331 708 338 1766 336 704 331 1773 329 1776 306 1773 360 681 323 1782 331 44726 411 1722 328 686 360 733 302 711 335 705 361 1742 329 1803 330 1749 332 708 327 1777 335 705 330 710 325 741 274 1830 303 737 278 44778 359 1747 355 712 303 711 355 711 335 705 330 709 337 703 363 703 332 1770 332 709 337 1767 335 1771 300 1752 360 733 302 1776 326 44731 355 1751 330 711 355 737 309 705 330 710 336 1793 309 1771 331 1774 307 706 360 1771 300 740 326 714 332 735 280 1798 325 741 274
|
||||
#
|
||||
name: POWER
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 9219 4484 662 469 661 469 661 1627 660 471 658 474 656 499 631 499 631 499 631 1657 630 1657 631 500 630 1657 631 1657 631 1657 630 1657 631 1657 631 500 630 500 630 500 630 1657 630 500 631 500 630 500 631 500 630 1657 630 1658 630 1657 631 500 630 1657 631 1658 630 1658 630 1658 630 40107 9106 2202 631
|
||||
data: 278 1812 276 762 282 758 276 765 279 761 273 1818 281 1809 279 1811 277 762 282 1809 279 760 274 766 278 762 282 1809 279 760 274 44279 276 1813 275 763 281 759 275 766 278 762 272 768 276 764 280 760 274 1817 271 768 276 1815 273 1817 271 1819 280 759 275 1816 272 44276 279 1812 276 763 281 758 276 765 279 761 273 1818 281 1810 278 1811 277 762 272 1819 279 760 274 766 278 762 282 1809 279 760 274
|
||||
#
|
||||
name: VOL+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 9218 4484 636 495 660 469 661 1627 660 471 658 472 658 474 656 475 655 474 656 1632 655 1632 656 474 657 1632 656 1631 657 1632 656 1631 656 1632 656 474 656 1632 655 475 656 474 657 474 656 474 656 474 656 474 656 1632 655 474 656 1632 656 1632 656 1632 656 1632 656 1632 656 1632 656 40103 9107 2177 655
|
||||
#
|
||||
data: 272 1817 271 794 250 790 254 786 248 792 252 762 272 794 250 1815 273 792 252 1813 275 790 254 785 249 766 278 1813 275 789 255 46372 273 1817 271 794 250 763 281 785 248 792 252 1813 275 1814 274 791 253 1812 276 789 255 1810 278 1812 276 1813 275 790 254 1811 277 42170 277 1814 274 791 253 787 247 793 251 763 281 759 275 791 253 1812 276 789 255 1810 278 787 247 793 251 789 255 1810 278 787 247
|
||||
#
|
||||
name: VOL-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 9245 4429 689 467 662 468 661 1626 660 471 658 473 657 474 656 474 656 474 656 1631 657 1631 657 474 656 1631 656 1632 656 1631 657 1631 657 1631 656 1632 656 1631 657 474 656 474 656 474 657 474 656 474 656 474 657 474 656 474 656 1631 656 1632 656 1632 656 1632 656 1632 656 1631 656 40082 9109 2175 656
|
||||
data: 275 1814 274 791 253 787 247 793 251 789 255 1810 278 787 247 1818 281 785 249 1816 272 793 251 789 255 785 249 1816 272 766 278 45325 274 1815 273 792 252 762 272 794 250 790 254 786 247 1818 270 794 250 1815 273 792 252 1813 275 1815 273 1816 272 793 251 1814 274 43224 277 1814 274 764 280 786 248 792 252 788 246 1820 279 786 247 1817 271 768 276 1815 273 792 252 761 273 794 250 1815 273 791 253
|
||||
#
|
||||
name: MUTE
|
||||
name: CH+
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 9219 4485 636 495 660 469 661 1626 661 471 658 473 657 474 656 499 631 500 630 1657 630 1657 631 500 630 1657 630 1657 631 1657 631 1657 630 1657 631 1657 631 500 630 500 630 1657 631 500 630 500 630 500 630 500 631 500 630 1657 631 1657 631 500 630 1657 631 1658 630 1657 631 1658 630 39868 9106 2178 655
|
||||
data: 272 1817 271 794 250 790 254 786 248 792 252 1813 275 790 254 759 275 792 252 1813 275 789 255 785 248 792 252 1813 275 789 255 46372 273 1817 271 793 251 763 281 759 275 791 253 787 247 1818 281 1810 278 1812 276 789 255 1809 279 1811 277 1813 275 790 254 1811 277 42169 277 1815 273 792 252 787 247 794 250 789 255 1810 278 787 247 794 250 789 255 1810 278 761 273 793 251 789 255 1810 278 787 247
|
||||
#
|
||||
name: CH-
|
||||
type: raw
|
||||
frequency: 38000
|
||||
duty_cycle: 0.330000
|
||||
data: 273 1816 272 767 277 789 255 785 249 791 253 787 246 1818 281 785 248 765 279 1812 276 789 255 759 275 791 253 1812 276 789 255 46372 281 1808 280 785 249 791 253 787 247 793 251 1814 274 791 253 1812 276 1814 274 791 253 1812 276 1814 274 1815 273 792 252 1813 275 42172 272 1819 280 785 249 765 279 761 273 768 276 764 280 1811 277 788 246 768 276 1815 273 792 252 788 246 794 250 1815 273 791 253
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ DEBUG = 0
|
||||
|
||||
# Suffix to add to files when building distribution
|
||||
# If OS environment has DIST_SUFFIX set, it will be used instead
|
||||
DIST_SUFFIX = "XFW-0045_02052023"
|
||||
DIST_SUFFIX = "XFW-0045_04052023"
|
||||
|
||||
# Coprocessor firmware
|
||||
COPRO_OB_DATA = "scripts/ob.data"
|
||||
|
||||
+2
-2
@@ -1,5 +1,3 @@
|
||||
Import("ENV", "fw_build_meta")
|
||||
|
||||
from SCons.Errors import UserError
|
||||
from SCons.Node import FS
|
||||
|
||||
@@ -10,6 +8,8 @@ from fbt_extra.util import (
|
||||
link_elf_dir_as_latest,
|
||||
)
|
||||
|
||||
Import("ENV", "fw_build_meta")
|
||||
|
||||
# Building initial C environment for libs
|
||||
env = ENV.Clone(
|
||||
tools=[
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,23.0,,
|
||||
Version,+,23.3,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -36,6 +36,7 @@ Header,+,applications/services/notification/notification_messages.h,,
|
||||
Header,+,applications/services/power/power_service/power.h,,
|
||||
Header,+,applications/services/rpc/rpc_app.h,,
|
||||
Header,+,applications/services/storage/storage.h,,
|
||||
Header,-,firmware/targets/f18/furi_hal/furi_hal_power_calibration.h,,
|
||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_resources.h,,
|
||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_spi_config.h,,
|
||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_target_hw.h,,
|
||||
@@ -111,6 +112,7 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,,
|
||||
Header,+,lib/flipper_application/plugins/plugin_manager.h,,
|
||||
Header,+,lib/flipper_format/flipper_format.h,,
|
||||
Header,+,lib/flipper_format/flipper_format_i.h,,
|
||||
Header,+,lib/flipper_format/flipper_format_stream.h,,
|
||||
Header,+,lib/libusb_stm32/inc/hid_usage_button.h,,
|
||||
Header,+,lib/libusb_stm32/inc/hid_usage_consumer.h,,
|
||||
Header,+,lib/libusb_stm32/inc/hid_usage_desktop.h,,
|
||||
@@ -754,6 +756,11 @@ Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32
|
||||
Function,+,flipper_format_rewind,_Bool,FlipperFormat*
|
||||
Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat*
|
||||
Function,+,flipper_format_set_strict_mode,void,"FlipperFormat*, _Bool"
|
||||
Function,+,flipper_format_stream_delete_key_and_write,_Bool,"Stream*, FlipperStreamWriteData*, _Bool"
|
||||
Function,+,flipper_format_stream_get_value_count,_Bool,"Stream*, const char*, uint32_t*, _Bool"
|
||||
Function,+,flipper_format_stream_read_value_line,_Bool,"Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool"
|
||||
Function,+,flipper_format_stream_write_comment_cstr,_Bool,"Stream*, const char*"
|
||||
Function,+,flipper_format_stream_write_value_line,_Bool,"Stream*, FlipperStreamWriteData*"
|
||||
Function,+,flipper_format_string_alloc,FlipperFormat*,
|
||||
Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t"
|
||||
Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t"
|
||||
@@ -959,6 +966,7 @@ Function,+,furi_hal_i2c_write_mem,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t,
|
||||
Function,+,furi_hal_i2c_write_reg_16,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint16_t, uint32_t"
|
||||
Function,+,furi_hal_i2c_write_reg_8,_Bool,"FuriHalI2cBusHandle*, uint8_t, uint8_t, uint8_t, uint32_t"
|
||||
Function,+,furi_hal_info_get,void,"PropertyValueCallback, char, void*"
|
||||
Function,+,furi_hal_info_get_api_version,void,"uint16_t*, uint16_t*"
|
||||
Function,-,furi_hal_init,void,
|
||||
Function,-,furi_hal_init_early,void,
|
||||
Function,-,furi_hal_interrupt_init,void,
|
||||
|
||||
|
@@ -0,0 +1,37 @@
|
||||
const ParamCEDV cedv = {
|
||||
.cedv_conf.gauge_conf =
|
||||
{
|
||||
.CCT = 1,
|
||||
.CSYNC = 0,
|
||||
.EDV_CMP = 0,
|
||||
.SC = 1,
|
||||
.FIXED_EDV0 = 1,
|
||||
.FCC_LIM = 1,
|
||||
.FC_FOR_VDQ = 1,
|
||||
.IGNORE_SD = 1,
|
||||
.SME0 = 0,
|
||||
},
|
||||
.full_charge_cap = 1300,
|
||||
.design_cap = 1300,
|
||||
.EDV0 = 3300,
|
||||
.EDV1 = 3321,
|
||||
.EDV2 = 3355,
|
||||
.EMF = 3679,
|
||||
.C0 = 430,
|
||||
.C1 = 0,
|
||||
.R1 = 408,
|
||||
.R0 = 334,
|
||||
.T0 = 4626,
|
||||
.TC = 11,
|
||||
.DOD0 = 4044,
|
||||
.DOD10 = 3905,
|
||||
.DOD20 = 3807,
|
||||
.DOD30 = 3718,
|
||||
.DOD40 = 3642,
|
||||
.DOD50 = 3585,
|
||||
.DOD60 = 3546,
|
||||
.DOD70 = 3514,
|
||||
.DOD80 = 3477,
|
||||
.DOD90 = 3411,
|
||||
.DOD100 = 3299,
|
||||
};
|
||||
@@ -51,6 +51,7 @@ Header,+,firmware/targets/f7/furi_hal/furi_hal_idle_timer.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_interrupt.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_nfc.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_os.h,,
|
||||
Header,-,firmware/targets/f7/furi_hal/furi_hal_power_calibration.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_pwm.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_resources.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_rfid.h,,
|
||||
@@ -123,6 +124,7 @@ Header,+,lib/flipper_application/plugins/composite_resolver.h,,
|
||||
Header,+,lib/flipper_application/plugins/plugin_manager.h,,
|
||||
Header,+,lib/flipper_format/flipper_format.h,,
|
||||
Header,+,lib/flipper_format/flipper_format_i.h,,
|
||||
Header,+,lib/flipper_format/flipper_format_stream.h,,
|
||||
Header,+,lib/ibutton/ibutton_key.h,,
|
||||
Header,+,lib/ibutton/ibutton_protocols.h,,
|
||||
Header,+,lib/ibutton/ibutton_worker.h,,
|
||||
@@ -1006,6 +1008,11 @@ Function,+,flipper_format_read_uint32,_Bool,"FlipperFormat*, const char*, uint32
|
||||
Function,+,flipper_format_rewind,_Bool,FlipperFormat*
|
||||
Function,+,flipper_format_seek_to_end,_Bool,FlipperFormat*
|
||||
Function,+,flipper_format_set_strict_mode,void,"FlipperFormat*, _Bool"
|
||||
Function,+,flipper_format_stream_delete_key_and_write,_Bool,"Stream*, FlipperStreamWriteData*, _Bool"
|
||||
Function,+,flipper_format_stream_get_value_count,_Bool,"Stream*, const char*, uint32_t*, _Bool"
|
||||
Function,+,flipper_format_stream_read_value_line,_Bool,"Stream*, const char*, FlipperStreamValue, void*, size_t, _Bool"
|
||||
Function,+,flipper_format_stream_write_comment_cstr,_Bool,"Stream*, const char*"
|
||||
Function,+,flipper_format_stream_write_value_line,_Bool,"Stream*, FlipperStreamWriteData*"
|
||||
Function,+,flipper_format_string_alloc,FlipperFormat*,
|
||||
Function,+,flipper_format_update_bool,_Bool,"FlipperFormat*, const char*, const _Bool*, const uint16_t"
|
||||
Function,+,flipper_format_update_float,_Bool,"FlipperFormat*, const char*, const float*, const uint16_t"
|
||||
@@ -1245,6 +1252,7 @@ Function,+,furi_hal_ibutton_pin_configure,void,
|
||||
Function,+,furi_hal_ibutton_pin_reset,void,
|
||||
Function,+,furi_hal_ibutton_pin_write,void,const _Bool
|
||||
Function,+,furi_hal_info_get,void,"PropertyValueCallback, char, void*"
|
||||
Function,+,furi_hal_info_get_api_version,void,"uint16_t*, uint16_t*"
|
||||
Function,+,furi_hal_infrared_async_rx_set_capture_isr_callback,void,"FuriHalInfraredRxCaptureCallback, void*"
|
||||
Function,+,furi_hal_infrared_async_rx_set_timeout,void,uint32_t
|
||||
Function,+,furi_hal_infrared_async_rx_set_timeout_isr_callback,void,"FuriHalInfraredRxTimeoutCallback, void*"
|
||||
|
||||
|
@@ -8,6 +8,11 @@
|
||||
#include <furi.h>
|
||||
#include <protobuf_version.h>
|
||||
|
||||
FURI_WEAK void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor) {
|
||||
*major = 0;
|
||||
*minor = 0;
|
||||
}
|
||||
|
||||
void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
||||
FuriString* key = furi_string_alloc();
|
||||
FuriString* value = furi_string_alloc();
|
||||
@@ -18,10 +23,10 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
||||
// Device Info version
|
||||
if(sep == '.') {
|
||||
property_value_out(&property_context, NULL, 2, "format", "major", "3");
|
||||
property_value_out(&property_context, NULL, 2, "format", "minor", "0");
|
||||
property_value_out(&property_context, NULL, 2, "format", "minor", "1");
|
||||
} else {
|
||||
property_value_out(&property_context, NULL, 3, "device", "info", "major", "2");
|
||||
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "0");
|
||||
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "1");
|
||||
}
|
||||
|
||||
// Model name
|
||||
@@ -161,6 +166,13 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
||||
version_get_builddate(firmware_version));
|
||||
property_value_out(
|
||||
&property_context, "%d", 2, "firmware", "target", version_get_target(firmware_version));
|
||||
|
||||
uint16_t api_version_major, api_version_minor;
|
||||
furi_hal_info_get_api_version(&api_version_major, &api_version_minor);
|
||||
property_value_out(
|
||||
&property_context, "%d", 3, "firmware", "api", "major", api_version_major);
|
||||
property_value_out(
|
||||
&property_context, "%d", 3, "firmware", "api", "minor", api_version_minor);
|
||||
}
|
||||
|
||||
if(furi_hal_bt_is_alive()) {
|
||||
|
||||
@@ -46,43 +46,7 @@ static volatile FuriHalPower furi_hal_power = {
|
||||
.suppress_charge = 0,
|
||||
};
|
||||
|
||||
const ParamCEDV cedv = {
|
||||
.cedv_conf.gauge_conf =
|
||||
{
|
||||
.CCT = 1,
|
||||
.CSYNC = 0,
|
||||
.EDV_CMP = 0,
|
||||
.SC = 1,
|
||||
.FIXED_EDV0 = 1,
|
||||
.FCC_LIM = 1,
|
||||
.FC_FOR_VDQ = 1,
|
||||
.IGNORE_SD = 1,
|
||||
.SME0 = 0,
|
||||
},
|
||||
.full_charge_cap = 2101,
|
||||
.design_cap = 2101,
|
||||
.EDV0 = 3300,
|
||||
.EDV1 = 3321,
|
||||
.EDV2 = 3355,
|
||||
.EMF = 3679,
|
||||
.C0 = 430,
|
||||
.C1 = 0,
|
||||
.R1 = 408,
|
||||
.R0 = 334,
|
||||
.T0 = 4626,
|
||||
.TC = 11,
|
||||
.DOD0 = 4044,
|
||||
.DOD10 = 3905,
|
||||
.DOD20 = 3807,
|
||||
.DOD30 = 3718,
|
||||
.DOD40 = 3642,
|
||||
.DOD50 = 3585,
|
||||
.DOD60 = 3546,
|
||||
.DOD70 = 3514,
|
||||
.DOD80 = 3477,
|
||||
.DOD90 = 3411,
|
||||
.DOD100 = 3299,
|
||||
};
|
||||
#include <furi_hal_power_calibration.h>
|
||||
|
||||
void furi_hal_power_init() {
|
||||
#ifdef FURI_HAL_POWER_DEBUG
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
const ParamCEDV cedv = {
|
||||
.cedv_conf.gauge_conf =
|
||||
{
|
||||
.CCT = 1,
|
||||
.CSYNC = 0,
|
||||
.EDV_CMP = 0,
|
||||
.SC = 1,
|
||||
.FIXED_EDV0 = 1,
|
||||
.FCC_LIM = 1,
|
||||
.FC_FOR_VDQ = 1,
|
||||
.IGNORE_SD = 1,
|
||||
.SME0 = 0,
|
||||
},
|
||||
.full_charge_cap = 2101,
|
||||
.design_cap = 2101,
|
||||
.EDV0 = 3300,
|
||||
.EDV1 = 3321,
|
||||
.EDV2 = 3355,
|
||||
.EMF = 3679,
|
||||
.C0 = 430,
|
||||
.C1 = 0,
|
||||
.R1 = 408,
|
||||
.R0 = 334,
|
||||
.T0 = 4626,
|
||||
.TC = 11,
|
||||
.DOD0 = 4044,
|
||||
.DOD10 = 3905,
|
||||
.DOD20 = 3807,
|
||||
.DOD30 = 3718,
|
||||
.DOD40 = 3642,
|
||||
.DOD50 = 3585,
|
||||
.DOD60 = 3546,
|
||||
.DOD70 = 3514,
|
||||
.DOD80 = 3477,
|
||||
.DOD90 = 3411,
|
||||
.DOD100 = 3299,
|
||||
};
|
||||
@@ -14,6 +14,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void furi_hal_info_get_api_version(uint16_t* major, uint16_t* minor);
|
||||
|
||||
/** Get device information
|
||||
*
|
||||
* @param[in] callback callback to provide with new data
|
||||
|
||||
@@ -15,6 +15,10 @@ extern "C" {
|
||||
#define FURI_WARN_UNUSED __attribute__((warn_unused_result))
|
||||
#endif
|
||||
|
||||
#ifndef FURI_WEAK
|
||||
#define FURI_WEAK __attribute__((weak))
|
||||
#endif
|
||||
|
||||
#ifndef FURI_IS_IRQ_MASKED
|
||||
#define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
|
||||
#endif
|
||||
|
||||
@@ -7,6 +7,7 @@ env.Append(
|
||||
SDK_HEADERS=[
|
||||
File("flipper_format.h"),
|
||||
File("flipper_format_i.h"),
|
||||
File("flipper_format_stream.h"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -7,9 +7,6 @@ env.Append(
|
||||
"#/lib/FreeRTOS-Kernel/portable/GCC/ARM_CM4F",
|
||||
"#/lib/FreeRTOS-glue",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
"HAVE_FREERTOS",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -4,9 +4,6 @@ env.Append(
|
||||
CPPPATH=[
|
||||
"#/lib/libusb_stm32/inc",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
("USB_PMASIZE", "0x400"),
|
||||
],
|
||||
SDK_HEADERS=env.GlobRecursive(
|
||||
"*.h",
|
||||
Dir("libusb_stm32/inc"),
|
||||
@@ -16,6 +13,11 @@ env.Append(
|
||||
|
||||
libenv = env.Clone(FW_LIB_NAME="usb_stm32")
|
||||
libenv.ApplyLibFlags()
|
||||
libenv.Append(
|
||||
CPPDEFINES=[
|
||||
("USB_PMASIZE", "0x400"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
sources = [
|
||||
|
||||
+5
-3
@@ -4,14 +4,16 @@ env.Append(
|
||||
CPPPATH=[
|
||||
"#/lib/littlefs",
|
||||
],
|
||||
CPPDEFINES=[
|
||||
("LFS_CONFIG", "lfs_config.h"),
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
libenv = env.Clone(FW_LIB_NAME="littlefs")
|
||||
libenv.ApplyLibFlags()
|
||||
libenv.Append(
|
||||
CPPDEFINES=[
|
||||
("LFS_CONFIG", "lfs_config.h"),
|
||||
],
|
||||
)
|
||||
|
||||
sources = Glob("littlefs/*.c", source=True)
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
Import("env")
|
||||
|
||||
from fbt.util import GLOB_FILE_EXCLUSION
|
||||
|
||||
Import("env")
|
||||
|
||||
env.Append(
|
||||
CPPPATH=[
|
||||
"#/lib/digital_signal",
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Import("env")
|
||||
|
||||
from fbt.version import get_fast_git_version_id
|
||||
|
||||
|
||||
Import("env")
|
||||
|
||||
env.Append(
|
||||
CPPPATH=[
|
||||
"#/lib/toolbox",
|
||||
|
||||
+17
-17
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
import asset_packer
|
||||
from flipper.app import App
|
||||
from flipper.assets.icon import file2image
|
||||
|
||||
import os
|
||||
import pathlib
|
||||
|
||||
ICONS_SUPPORTED_FORMATS = ["png"]
|
||||
|
||||
ICONS_TEMPLATE_H_HEADER = """#pragma once
|
||||
@@ -129,7 +129,7 @@ class Main(App):
|
||||
if not filenames:
|
||||
continue
|
||||
if "frame_rate" in filenames:
|
||||
self.logger.debug(f"Folder contains animation")
|
||||
self.logger.debug("Folder contains animation")
|
||||
icon_name = "A_" + os.path.split(dirpath)[1].replace("-", "_")
|
||||
width = height = None
|
||||
frame_count = 0
|
||||
@@ -188,7 +188,7 @@ class Main(App):
|
||||
icons_c.write("\n")
|
||||
icons.append((icon_name, width, height, 0, 1))
|
||||
# Create array of images:
|
||||
self.logger.debug(f"Finalizing source file")
|
||||
self.logger.debug("Finalizing source file")
|
||||
for name, width, height, frame_rate, frame_count in icons:
|
||||
icons_c.write(
|
||||
ICONS_TEMPLATE_C_ICONS.format(
|
||||
@@ -203,7 +203,7 @@ class Main(App):
|
||||
icons_c.close()
|
||||
|
||||
# Create Public Header
|
||||
self.logger.debug(f"Creating header")
|
||||
self.logger.debug("Creating header")
|
||||
icons_h = open(
|
||||
os.path.join(self.args.output_directory, f"{self.args.filename}.h"),
|
||||
"w",
|
||||
@@ -213,7 +213,7 @@ class Main(App):
|
||||
for name, width, height, frame_rate, frame_count in icons:
|
||||
icons_h.write(ICONS_TEMPLATE_H_ICON_NAME.format(name=name))
|
||||
icons_h.close()
|
||||
self.logger.debug(f"Done")
|
||||
self.logger.debug("Done")
|
||||
return 0
|
||||
|
||||
def manifest(self):
|
||||
@@ -234,7 +234,7 @@ class Main(App):
|
||||
new_manifest = Manifest(self.args.timestamp)
|
||||
new_manifest.create(directory_path)
|
||||
|
||||
self.logger.info(f"Comparing new manifest with existing")
|
||||
self.logger.info("Comparing new manifest with existing")
|
||||
only_in_old, changed, only_in_new = Manifest.compare(old_manifest, new_manifest)
|
||||
for record in only_in_old:
|
||||
self.logger.info(f"Only in old: {record}")
|
||||
@@ -256,38 +256,38 @@ class Main(App):
|
||||
self.logger.info,
|
||||
)
|
||||
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
|
||||
return 0
|
||||
|
||||
def copro(self):
|
||||
from flipper.assets.copro import Copro
|
||||
|
||||
self.logger.info(f"Bundling coprocessor binaries")
|
||||
self.logger.info("Bundling coprocessor binaries")
|
||||
copro = Copro(self.args.mcu)
|
||||
self.logger.info(f"Loading CUBE info")
|
||||
self.logger.info("Loading CUBE info")
|
||||
copro.loadCubeInfo(self.args.cube_dir, self.args.cube_ver)
|
||||
self.logger.info(f"Bundling")
|
||||
self.logger.info("Bundling")
|
||||
copro.bundle(
|
||||
self.args.output_dir,
|
||||
self.args.stack_file,
|
||||
self.args.stack_type,
|
||||
self.args.stack_addr,
|
||||
)
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
|
||||
return 0
|
||||
|
||||
def dolphin(self):
|
||||
from flipper.assets.dolphin import Dolphin
|
||||
|
||||
self.logger.info(f"Processing Dolphin sources")
|
||||
self.logger.info("Processing Dolphin sources")
|
||||
dolphin = Dolphin()
|
||||
self.logger.info(f"Loading data")
|
||||
self.logger.info("Loading data")
|
||||
dolphin.load(self.args.input_directory)
|
||||
self.logger.info(f"Packing")
|
||||
self.logger.info("Packing")
|
||||
dolphin.pack(self.args.output_directory, self.args.symbol_name)
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
|
||||
return 0
|
||||
|
||||
|
||||
+3
-3
@@ -1,12 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.storage import FlipperStorage, FlipperStorageOperations
|
||||
from flipper.utils.cdc import resolve_port
|
||||
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
|
||||
class Main(App):
|
||||
def init(self):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from dataclasses import dataclass, field
|
||||
from typing import List, Optional, Tuple, Callable
|
||||
from enum import Enum
|
||||
import os
|
||||
from dataclasses import dataclass, field
|
||||
from enum import Enum
|
||||
from typing import Callable, List, Optional, Tuple
|
||||
|
||||
|
||||
class FlipperManifestException(Exception):
|
||||
@@ -94,7 +94,7 @@ class AppManager:
|
||||
def get(self, appname: str):
|
||||
try:
|
||||
return self.known_apps[appname]
|
||||
except KeyError as _:
|
||||
except KeyError:
|
||||
raise FlipperManifestException(
|
||||
f"Missing application manifest for '{appname}'"
|
||||
)
|
||||
@@ -298,7 +298,7 @@ class AppBuildset:
|
||||
try:
|
||||
parent_app = self.appmgr.get(parent_app_id)
|
||||
parent_app._plugins.append(extension_app)
|
||||
except FlipperManifestException as e:
|
||||
except FlipperManifestException:
|
||||
self._writer(
|
||||
f"Module {extension_app.appid} has unknown parent {parent_app_id}"
|
||||
)
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
from dataclasses import dataclass
|
||||
import os
|
||||
|
||||
import struct
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
from .appmanifest import FlipperApplication
|
||||
from flipper.assets.icon import file2image
|
||||
|
||||
from .appmanifest import FlipperApplication
|
||||
|
||||
_MANIFEST_MAGIC = 0x52474448
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import os
|
||||
import hashlib
|
||||
import os
|
||||
import struct
|
||||
from typing import TypedDict
|
||||
|
||||
|
||||
@@ -1,20 +1,13 @@
|
||||
import operator
|
||||
import os
|
||||
import csv
|
||||
import operator
|
||||
|
||||
from enum import Enum, auto
|
||||
from typing import Set, ClassVar, Any
|
||||
import os
|
||||
from dataclasses import dataclass
|
||||
from enum import Enum, auto
|
||||
from typing import Any, ClassVar, Set
|
||||
|
||||
from ansi.color import fg
|
||||
|
||||
from . import (
|
||||
ApiEntries,
|
||||
ApiEntryFunction,
|
||||
ApiEntryVariable,
|
||||
ApiHeader,
|
||||
)
|
||||
from . import ApiEntries, ApiEntryFunction, ApiEntryVariable, ApiHeader
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@@ -137,7 +130,7 @@ class SdkCache:
|
||||
f"API version is still WIP: {self.version}. Review the changes and re-run command."
|
||||
)
|
||||
)
|
||||
print(f"CSV file entries to mark up:")
|
||||
print("CSV file entries to mark up:")
|
||||
print(
|
||||
fg.yellow(
|
||||
"\n".join(
|
||||
|
||||
+4
-5
@@ -1,10 +1,9 @@
|
||||
import SCons
|
||||
from SCons.Subst import quote_spaces
|
||||
from SCons.Errors import StopError
|
||||
|
||||
import re
|
||||
import os
|
||||
import re
|
||||
|
||||
import SCons
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Subst import quote_spaces
|
||||
|
||||
WINPATHSEP_RE = re.compile(r"\\([^\"'\\]|$)")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import subprocess
|
||||
import datetime
|
||||
import subprocess
|
||||
from functools import cache
|
||||
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ def exists():
|
||||
|
||||
|
||||
def generate(env):
|
||||
if ccache := env.WhereIs("ccache"):
|
||||
if env.WhereIs("ccache"):
|
||||
env["CCACHE"] = "ccache"
|
||||
env["CC_NOCACHE"] = env["CC"]
|
||||
env["CC"] = "$CCACHE $CC_NOCACHE"
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Tool import asm
|
||||
from SCons.Tool import gcc
|
||||
from SCons.Tool import gxx
|
||||
from SCons.Tool import ar
|
||||
from SCons.Tool import gnulink
|
||||
import strip
|
||||
import subprocess
|
||||
|
||||
import gdb
|
||||
import objdump
|
||||
|
||||
import strip
|
||||
from SCons.Action import _subproc
|
||||
import subprocess
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Tool import ar, asm, gcc, gnulink, gxx
|
||||
|
||||
|
||||
def prefix_commands(env, command_prefix, cmd_list):
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Warnings import warn, WarningOnByDefault
|
||||
from ansi.color import fg
|
||||
|
||||
from fbt.appmanifest import (
|
||||
FlipperAppType,
|
||||
AppManager,
|
||||
ApplicationsCGenerator,
|
||||
AppManager,
|
||||
FlipperAppType,
|
||||
FlipperManifestException,
|
||||
)
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Errors import StopError
|
||||
from SCons.Warnings import WarningOnByDefault, warn
|
||||
|
||||
# Adding objects for application management to env
|
||||
# AppManager env["APPMGR"] - loads all manifests; manages list of known apps
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Errors import StopError
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from ansi.color import fg
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Errors import StopError
|
||||
|
||||
|
||||
def icons_emitter(target, source, env):
|
||||
@@ -76,11 +76,11 @@ def proto_ver_generator(target, source, env):
|
||||
target_file = target[0]
|
||||
src_dir = source[0].dir.abspath
|
||||
try:
|
||||
git_fetch = _invoke_git(
|
||||
_invoke_git(
|
||||
["fetch", "--tags"],
|
||||
source_dir=src_dir,
|
||||
)
|
||||
except (subprocess.CalledProcessError, EnvironmentError) as e:
|
||||
except (subprocess.CalledProcessError, EnvironmentError):
|
||||
# Not great, not terrible
|
||||
print(fg.boldred("Git: fetch failed"))
|
||||
|
||||
@@ -89,7 +89,7 @@ def proto_ver_generator(target, source, env):
|
||||
["describe", "--tags", "--abbrev=0"],
|
||||
source_dir=src_dir,
|
||||
)
|
||||
except (subprocess.CalledProcessError, EnvironmentError) as e:
|
||||
except (subprocess.CalledProcessError, EnvironmentError):
|
||||
raise StopError("Git: describe failed")
|
||||
|
||||
git_major, git_minor = git_describe.split(".")
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from re import search
|
||||
|
||||
from SCons.Errors import UserError
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Script import Mkdir
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Defaults import Touch
|
||||
|
||||
|
||||
|
||||
@@ -3,23 +3,19 @@ import os
|
||||
import pathlib
|
||||
import shutil
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Optional, TypedDict
|
||||
|
||||
from ansi.color import fg
|
||||
from typing import Optional
|
||||
|
||||
import SCons.Warnings
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Errors import UserError
|
||||
from SCons.Node import NodeList
|
||||
from SCons.Node.FS import File, Entry
|
||||
|
||||
from ansi.color import fg
|
||||
from fbt.appmanifest import FlipperApplication, FlipperAppType, FlipperManifestException
|
||||
from fbt.elfmanifest import assemble_manifest_data
|
||||
from fbt.fapassets import FileBundler
|
||||
from fbt.sdk.cache import SdkCache
|
||||
from fbt.util import extract_abs_dir_path
|
||||
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Errors import UserError
|
||||
from SCons.Node.FS import Entry, File
|
||||
|
||||
_FAP_META_SECTION = ".fapmeta"
|
||||
_FAP_FILEASSETS_SECTION = ".fapassets"
|
||||
@@ -289,7 +285,7 @@ def GetExtAppByIdOrPath(env, app_dir):
|
||||
try:
|
||||
# Maybe user passed an appid?
|
||||
app = appmgr.get(app_dir)
|
||||
except FlipperManifestException as _:
|
||||
except FlipperManifestException:
|
||||
# Look up path components in known app dirs
|
||||
for dir_part in reversed(pathlib.Path(app_dir).parts):
|
||||
if app := appmgr.find_by_appdir(dir_part):
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
import json
|
||||
|
||||
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
import json
|
||||
import os.path
|
||||
import pathlib
|
||||
import posixpath
|
||||
import shutil
|
||||
from SCons.Builder import Builder
|
||||
|
||||
from fbt.sdk.cache import SdkCache
|
||||
from fbt.sdk.collector import SdkCollector
|
||||
from fbt.util import path_as_posix
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Errors import UserError
|
||||
|
||||
# from SCons.Scanner import C
|
||||
from SCons.Script import Entry
|
||||
from SCons.Util import LogicalLines
|
||||
|
||||
import os.path
|
||||
import posixpath
|
||||
import pathlib
|
||||
import json
|
||||
|
||||
from fbt.sdk.collector import SdkCollector
|
||||
from fbt.sdk.cache import SdkCache
|
||||
from fbt.util import path_as_posix
|
||||
|
||||
|
||||
def ProcessSdkDepends(env, filename):
|
||||
try:
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
import os
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
import SCons.Warnings as Warnings
|
||||
from ansi.color import fg
|
||||
from SCons.Errors import UserError
|
||||
|
||||
|
||||
# from SCons.Script.Main import find_deepest_user_frame
|
||||
|
||||
from ansi.color import fg, bg, fx
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import os
|
||||
|
||||
|
||||
def find_deepest_user_frame(tb):
|
||||
tb.reverse()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
|
||||
|
||||
def version_emitter(target, source, env):
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
import SCons
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
|
||||
__OBJCOPY_ARM_BIN = "arm-none-eabi-objcopy"
|
||||
__NM_ARM_BIN = "arm-none-eabi-nm"
|
||||
|
||||
@@ -1,7 +1,3 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
|
||||
|
||||
def generate(env):
|
||||
env.SetDefault(
|
||||
GDB="gdb",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
|
||||
|
||||
def generate(env):
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Defaults import Touch
|
||||
import SCons
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Defaults import Touch
|
||||
|
||||
__OPENOCD_BIN = "openocd"
|
||||
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Script import Delete, Mkdir, GetBuildFailures, Flatten
|
||||
import multiprocessing
|
||||
import webbrowser
|
||||
import atexit
|
||||
import sys
|
||||
import multiprocessing
|
||||
import subprocess
|
||||
import sys
|
||||
import webbrowser
|
||||
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Script import Delete, Flatten, GetBuildFailures, Mkdir
|
||||
|
||||
__no_browser = False
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import posixpath
|
||||
import os
|
||||
import posixpath
|
||||
|
||||
from SCons.Errors import UserError
|
||||
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import SCons
|
||||
from SCons.Script import Flatten
|
||||
from fbt.util import GLOB_FILE_EXCLUSION
|
||||
from SCons.Script import Flatten
|
||||
|
||||
|
||||
def GlobRecursive(env, pattern, node=".", exclude=[]):
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from SCons.Builder import Builder
|
||||
from SCons.Action import Action
|
||||
from SCons.Builder import Builder
|
||||
|
||||
|
||||
def generate(env):
|
||||
|
||||
+23
-27
@@ -1,13 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import argparse
|
||||
import sys
|
||||
import os
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.cube import CubeProgrammer
|
||||
from flipper.assets.coprobin import CoproBinary
|
||||
from flipper.cube import CubeProgrammer
|
||||
|
||||
STATEMENT = "AGREE_TO_LOSE_FLIPPER_FEATURES_THAT_USE_CRYPTO_ENCLAVE"
|
||||
|
||||
@@ -94,59 +90,59 @@ class Main(App):
|
||||
}
|
||||
|
||||
def wipe(self):
|
||||
self.logger.info(f"Wiping flash")
|
||||
self.logger.info("Wiping flash")
|
||||
cp = CubeProgrammer(self._getCubeParams())
|
||||
self.logger.info(f"Setting RDP to 0xBB")
|
||||
self.logger.info("Setting RDP to 0xBB")
|
||||
cp.setOptionBytes({"RDP": ("0xBB", "rw")})
|
||||
self.logger.info(f"Verifying RDP")
|
||||
self.logger.info("Verifying RDP")
|
||||
r = cp.checkOptionBytes({"RDP": ("0xBB", "rw")})
|
||||
assert r == True
|
||||
assert r is True
|
||||
self.logger.info(f"Result: {r}")
|
||||
self.logger.info(f"Setting RDP to 0xAA")
|
||||
self.logger.info("Setting RDP to 0xAA")
|
||||
cp.setOptionBytes({"RDP": ("0xAA", "rw")})
|
||||
self.logger.info(f"Verifying RDP")
|
||||
self.logger.info("Verifying RDP")
|
||||
r = cp.checkOptionBytes({"RDP": ("0xAA", "rw")})
|
||||
assert r == True
|
||||
assert r is True
|
||||
self.logger.info(f"Result: {r}")
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
return 0
|
||||
|
||||
def core1bootloader(self):
|
||||
self.logger.info(f"Flashing bootloader")
|
||||
self.logger.info("Flashing bootloader")
|
||||
cp = CubeProgrammer(self._getCubeParams())
|
||||
cp.flashBin("0x08000000", self.args.bootloader)
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
cp.resetTarget()
|
||||
return 0
|
||||
|
||||
def core1firmware(self):
|
||||
self.logger.info(f"Flashing firmware")
|
||||
self.logger.info("Flashing firmware")
|
||||
cp = CubeProgrammer(self._getCubeParams())
|
||||
cp.flashBin("0x08008000", self.args.firmware)
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
cp.resetTarget()
|
||||
return 0
|
||||
|
||||
def core1(self):
|
||||
self.logger.info(f"Flashing bootloader")
|
||||
self.logger.info("Flashing bootloader")
|
||||
cp = CubeProgrammer(self._getCubeParams())
|
||||
cp.flashBin("0x08000000", self.args.bootloader)
|
||||
self.logger.info(f"Flashing firmware")
|
||||
self.logger.info("Flashing firmware")
|
||||
cp.flashBin("0x08008000", self.args.firmware)
|
||||
cp.resetTarget()
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
return 0
|
||||
|
||||
def core2fus(self):
|
||||
if self.args.statement != STATEMENT:
|
||||
self.logger.error(
|
||||
f"PLEASE DON'T. THIS FEATURE INTENDED ONLY FOR FACTORY FLASHING"
|
||||
"PLEASE DON'T. THIS FEATURE INTENDED ONLY FOR FACTORY FLASHING"
|
||||
)
|
||||
return 1
|
||||
self.logger.info(f"Flashing Firmware Update Service")
|
||||
self.logger.info("Flashing Firmware Update Service")
|
||||
cp = CubeProgrammer(self._getCubeParams())
|
||||
cp.flashCore2(self.args.fus_address, self.args.fus)
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
return 0
|
||||
|
||||
def core2radio(self):
|
||||
@@ -163,15 +159,15 @@ class Main(App):
|
||||
f"Radio address not provided, guessed as 0x{radio_address:X}"
|
||||
)
|
||||
if radio_address > 0x080E0000:
|
||||
self.logger.error(f"I KNOW WHAT YOU DID LAST SUMMER")
|
||||
self.logger.error("I KNOW WHAT YOU DID LAST SUMMER")
|
||||
return 1
|
||||
|
||||
cp = CubeProgrammer(self._getCubeParams())
|
||||
self.logger.info(f"Removing Current Radio Stack")
|
||||
self.logger.info("Removing Current Radio Stack")
|
||||
cp.deleteCore2RadioStack()
|
||||
self.logger.info(f"Flashing Radio Stack")
|
||||
self.logger.info("Flashing Radio Stack")
|
||||
cp.flashCore2(radio_address, self.args.radio)
|
||||
self.logger.info(f"Complete")
|
||||
self.logger.info("Complete")
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ class App:
|
||||
if isinstance(return_code, int):
|
||||
return self._exit(return_code)
|
||||
else:
|
||||
self.logger.error(f"Missing return code")
|
||||
self.logger.error("Missing return code")
|
||||
return self._exit(255)
|
||||
|
||||
def _exit(self, code):
|
||||
|
||||
@@ -6,7 +6,7 @@ import xml.etree.ElementTree as ET
|
||||
import posixpath
|
||||
import os
|
||||
|
||||
from flipper.utils import *
|
||||
from flipper.utils import file_sha256, timestamp
|
||||
from flipper.assets.coprobin import CoproBinary, get_stack_type
|
||||
|
||||
|
||||
@@ -45,13 +45,13 @@ class Copro:
|
||||
cube_manifest = ET.parse(cube_manifest_file)
|
||||
cube_package = cube_manifest.find("PackDescription")
|
||||
if not cube_package:
|
||||
raise Exception(f"Unknown Cube manifest format")
|
||||
raise Exception("Unknown Cube manifest format")
|
||||
cube_version = cube_package.get("Patch") or cube_package.get("Release")
|
||||
if not cube_version or not cube_version.startswith("FW.WB"):
|
||||
raise Exception(f"Incorrect Cube package or version info")
|
||||
raise Exception("Incorrect Cube package or version info")
|
||||
cube_version = cube_version.replace("FW.WB.", "", 1)
|
||||
if cube_version != reference_cube_version:
|
||||
raise Exception(f"Unsupported cube version")
|
||||
raise Exception("Unsupported cube version")
|
||||
self.version = cube_version
|
||||
|
||||
def _getFileName(self, name):
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import struct
|
||||
import math
|
||||
import os, os.path
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import multiprocessing
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
import shutil
|
||||
from collections import Counter
|
||||
|
||||
from flipper.utils.fff import *
|
||||
from flipper.utils.templite import *
|
||||
from .icon import *
|
||||
from flipper.utils.fff import FlipperFormatFile
|
||||
from flipper.utils.templite import Templite
|
||||
from .icon import ImageTools, file2image
|
||||
|
||||
|
||||
def _convert_image_to_bm(pair: set):
|
||||
@@ -121,7 +119,7 @@ class DolphinBubbleAnimation:
|
||||
self.meta["Passive frames"] + self.meta["Active frames"]
|
||||
== ordered_frames_count
|
||||
)
|
||||
except EOFError as e:
|
||||
except EOFError:
|
||||
raise Exception("Invalid meta file: too short")
|
||||
except AssertionError as e:
|
||||
self.logger.exception(e)
|
||||
@@ -158,7 +156,7 @@ class DolphinBubbleAnimation:
|
||||
except AssertionError as e:
|
||||
self.logger.exception(e)
|
||||
self.logger.error(
|
||||
f"Animation {self.name} bubble slot {bubble_slot} got incorrect data: {bubble}"
|
||||
f"Animation {self.name} bubble slot {bubble['Slot']} got incorrect data: {bubble}"
|
||||
)
|
||||
raise Exception("Meta file is invalid: incorrect bubble data")
|
||||
except EOFError:
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
import logging
|
||||
import argparse
|
||||
import subprocess
|
||||
import io
|
||||
import os
|
||||
import sys
|
||||
|
||||
ICONS_SUPPORTED_FORMATS = ["png"]
|
||||
|
||||
@@ -36,11 +33,8 @@ class ImageTools:
|
||||
@staticmethod
|
||||
def is_processing_slow():
|
||||
try:
|
||||
from PIL import Image, ImageOps
|
||||
import heatshrink2
|
||||
|
||||
return False
|
||||
except ImportError as e:
|
||||
except ImportError:
|
||||
return True
|
||||
|
||||
def __init__(self):
|
||||
@@ -52,7 +46,7 @@ class ImageTools:
|
||||
|
||||
try:
|
||||
from PIL import Image, ImageOps
|
||||
except ImportError as e:
|
||||
except ImportError:
|
||||
self.__pil_unavailable = True
|
||||
self.logger.info("pillow module is missing, using convert cli util")
|
||||
return self.png2xbm(file)
|
||||
@@ -72,7 +66,7 @@ class ImageTools:
|
||||
|
||||
try:
|
||||
import heatshrink2
|
||||
except ImportError as e:
|
||||
except ImportError:
|
||||
self.__hs2_unavailable = True
|
||||
self.logger.info("heatshrink2 module is missing, using heatshrink cli util")
|
||||
return self.xbm2hs(data)
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import datetime
|
||||
import logging
|
||||
import os
|
||||
import posixpath
|
||||
from pathlib import Path
|
||||
|
||||
from flipper.utils import *
|
||||
from flipper.utils.fstree import *
|
||||
from flipper.utils import timestamp, file_md5
|
||||
from flipper.utils.fstree import FsNode, compare_fs_trees
|
||||
|
||||
MANIFEST_VERSION = 0
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import logging
|
||||
import struct
|
||||
|
||||
from enum import Enum
|
||||
from dataclasses import dataclass
|
||||
@@ -181,7 +179,7 @@ class OptionBytesData:
|
||||
|
||||
def gen_values(self):
|
||||
obref = ObReferenceValuesGenerator()
|
||||
converted_refs = list(obref.apply(ob) for ob in self.obs)
|
||||
list(obref.apply(ob) for ob in self.obs)
|
||||
return obref
|
||||
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ class CubeProgrammer:
|
||||
if "port" in config and config["port"]:
|
||||
connect.append(f"port={config['port']}")
|
||||
else:
|
||||
connect.append(f"port=swd")
|
||||
connect.append("port=swd")
|
||||
if "serial" in config and config["serial"]:
|
||||
connect.append(f"sn={config['serial']}")
|
||||
self.params.append("-c " + " ".join(connect))
|
||||
@@ -43,20 +43,20 @@ class CubeProgrammer:
|
||||
return output.decode()
|
||||
|
||||
def getVersion(self):
|
||||
output = self._execute(["--version"])
|
||||
self._execute(["--version"])
|
||||
|
||||
def checkOptionBytes(self, option_bytes):
|
||||
output = self._execute(["-ob displ"])
|
||||
ob_correct = True
|
||||
for line in output.split("\n"):
|
||||
line = line.strip()
|
||||
if not ":" in line:
|
||||
if ":" not in line:
|
||||
self.logger.debug(f"Skipping line: {line}")
|
||||
continue
|
||||
key, data = line.split(":", 1)
|
||||
key = key.strip()
|
||||
data = data.strip()
|
||||
if not key in option_bytes.keys():
|
||||
if key not in option_bytes.keys():
|
||||
self.logger.debug(f"Skipping key: {key}")
|
||||
continue
|
||||
self.logger.debug(f"Processing key: {key} {data}")
|
||||
|
||||
@@ -151,7 +151,7 @@ class FlipperStorage:
|
||||
try:
|
||||
# TODO: better decoding, considering non-ascii characters
|
||||
line = line.decode("ascii")
|
||||
except:
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
line = line.strip()
|
||||
@@ -194,7 +194,7 @@ class FlipperStorage:
|
||||
try:
|
||||
# TODO: better decoding, considering non-ascii characters
|
||||
line = line.decode("ascii")
|
||||
except:
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
line = line.strip()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import datetime
|
||||
import hashlib
|
||||
import os
|
||||
|
||||
|
||||
def timestamp():
|
||||
|
||||
@@ -31,13 +31,13 @@ class OpenOCDProgrammer(Programmer):
|
||||
config["interface"] = interface
|
||||
config["target"] = "target/stm32wbx.cfg"
|
||||
|
||||
if not serial is None:
|
||||
if serial is not None:
|
||||
if interface == "interface/cmsis-dap.cfg":
|
||||
config["serial"] = f"cmsis_dap_serial {serial}"
|
||||
elif "stlink" in interface:
|
||||
config["serial"] = f"stlink_serial {serial}"
|
||||
|
||||
if not port_base is None:
|
||||
if port_base is not None:
|
||||
config["port_base"] = port_base
|
||||
|
||||
self.openocd = OpenOCD(config)
|
||||
@@ -59,7 +59,7 @@ class OpenOCDProgrammer(Programmer):
|
||||
raise Exception(f"File {file_path} not found")
|
||||
|
||||
self.openocd.start()
|
||||
self.openocd.send_tcl(f"init")
|
||||
self.openocd.send_tcl("init")
|
||||
self.openocd.send_tcl(
|
||||
f"program {file_path} 0x{address:08x}{' verify' if verify else ''} reset exit"
|
||||
)
|
||||
@@ -196,7 +196,7 @@ class OpenOCDProgrammer(Programmer):
|
||||
if ob_need_to_apply:
|
||||
stm32.option_bytes_apply(self.openocd)
|
||||
else:
|
||||
self.logger.info(f"Option Bytes are already correct")
|
||||
self.logger.info("Option Bytes are already correct")
|
||||
|
||||
# Load Option Bytes
|
||||
# That will reset and also lock the Option Bytes and the Flash
|
||||
@@ -256,7 +256,7 @@ class OpenOCDProgrammer(Programmer):
|
||||
already_written = False
|
||||
|
||||
if already_written:
|
||||
self.logger.info(f"OTP memory is already written with the given data")
|
||||
self.logger.info("OTP memory is already written with the given data")
|
||||
return OpenOCDProgrammerResult.Success
|
||||
|
||||
self.reset(self.RunMode.Stop)
|
||||
|
||||
@@ -123,7 +123,7 @@ class STM32WB55:
|
||||
def clear_flash_errors(self, oocd: OpenOCD):
|
||||
# Errata 2.2.9: Flash OPTVERR flag is always set after system reset
|
||||
# And also clear all other flash error flags
|
||||
self.logger.debug(f"Resetting flash errors")
|
||||
self.logger.debug("Resetting flash errors")
|
||||
self.FLASH_SR.load(oocd)
|
||||
self.FLASH_SR.OP_ERR = 1
|
||||
self.FLASH_SR.PROG_ERR = 1
|
||||
@@ -218,7 +218,7 @@ class STM32WB55:
|
||||
raise Exception("Flash lock failed")
|
||||
|
||||
def option_bytes_apply(self, oocd: OpenOCD):
|
||||
self.logger.debug(f"Applying Option Bytes")
|
||||
self.logger.debug("Applying Option Bytes")
|
||||
|
||||
self.FLASH_CR.load(oocd)
|
||||
self.FLASH_CR.OPT_STRT = 1
|
||||
@@ -228,7 +228,7 @@ class STM32WB55:
|
||||
self.flash_wait_for_operation(oocd)
|
||||
|
||||
def option_bytes_load(self, oocd: OpenOCD):
|
||||
self.logger.debug(f"Loading Option Bytes")
|
||||
self.logger.debug("Loading Option Bytes")
|
||||
self.FLASH_CR.load(oocd)
|
||||
self.FLASH_CR.OBL_LAUNCH = 1
|
||||
self.FLASH_CR.store(oocd)
|
||||
|
||||
@@ -77,8 +77,8 @@ class TempliteCompiler:
|
||||
return
|
||||
|
||||
lines = self.block.splitlines()
|
||||
margin = min(len(l) - len(l.lstrip()) for l in lines if l.strip())
|
||||
self.block = "\n".join("\t" * self.offset + l[margin:] for l in lines)
|
||||
margin = min(len(line) - len(line.lstrip()) for line in lines if line.strip())
|
||||
self.block = "\n".join("\t" * self.offset + line[margin:] for line in lines)
|
||||
self.blocks.append(self.block)
|
||||
if self.block.endswith(":"):
|
||||
self.offset += 1
|
||||
|
||||
+4
-3
@@ -1,10 +1,11 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from flipper.app import App
|
||||
import subprocess
|
||||
import os
|
||||
import math
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from ansi.color import fg
|
||||
from flipper.app import App
|
||||
|
||||
|
||||
class Main(App):
|
||||
|
||||
+7
-7
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import ssl
|
||||
import json
|
||||
import os
|
||||
import shlex
|
||||
import re
|
||||
import string
|
||||
import random
|
||||
import argparse
|
||||
import datetime
|
||||
import json
|
||||
import os
|
||||
import random
|
||||
import re
|
||||
import shlex
|
||||
import ssl
|
||||
import string
|
||||
import urllib.request
|
||||
|
||||
|
||||
|
||||
+5
-6
@@ -1,14 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import multiprocessing
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
import subprocess
|
||||
import multiprocessing
|
||||
|
||||
from flipper.app import App
|
||||
|
||||
|
||||
SOURCE_CODE_FILE_EXTENSIONS = [".h", ".c", ".cpp", ".cxx", ".hpp"]
|
||||
SOURCE_CODE_FILE_PATTERN = r"^[0-9A-Za-z_]+\.[a-z]+$"
|
||||
SOURCE_CODE_DIR_PATTERN = r"^[0-9A-Za-z_]+$"
|
||||
@@ -59,7 +58,7 @@ class Main(App):
|
||||
show_message = True
|
||||
if show_message:
|
||||
self.logger.warning(
|
||||
f"Folders are not renamed automatically, please fix it by yourself"
|
||||
"Folders are not renamed automatically, please fix it by yourself"
|
||||
)
|
||||
|
||||
def _find_sources(self, folders: list):
|
||||
@@ -70,7 +69,7 @@ class Main(App):
|
||||
|
||||
for filename in filenames:
|
||||
ext = os.path.splitext(filename.lower())[1]
|
||||
if not ext in SOURCE_CODE_FILE_EXTENSIONS:
|
||||
if ext not in SOURCE_CODE_FILE_EXTENSIONS:
|
||||
continue
|
||||
output.append(os.path.join(dirpath, filename))
|
||||
return output
|
||||
@@ -80,7 +79,7 @@ class Main(App):
|
||||
try:
|
||||
subprocess.check_call(task)
|
||||
return True
|
||||
except subprocess.CalledProcessError as e:
|
||||
except subprocess.CalledProcessError:
|
||||
return False
|
||||
|
||||
def _format_sources(self, sources: list, dry_run: bool = False):
|
||||
@@ -144,7 +143,7 @@ class Main(App):
|
||||
|
||||
def _apply_file_permissions(self, sources: list, dry_run: bool = False):
|
||||
execute_permissions = 0o111
|
||||
pattern = re.compile(SOURCE_CODE_FILE_PATTERN)
|
||||
re.compile(SOURCE_CODE_FILE_PATTERN)
|
||||
good = []
|
||||
bad = []
|
||||
# Check sources for unexpected execute permissions
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
from slack_sdk import WebClient
|
||||
from slack_sdk.errors import SlackApiError
|
||||
|
||||
|
||||
+2
-1
@@ -1,8 +1,9 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from flipper.app import App
|
||||
import json
|
||||
|
||||
from flipper.app import App
|
||||
|
||||
|
||||
class Main(App):
|
||||
def init(self):
|
||||
|
||||
+2
-2
@@ -44,7 +44,7 @@ class Main(App):
|
||||
)
|
||||
|
||||
def check(self):
|
||||
self.logger.info(f"Checking Option Bytes")
|
||||
self.logger.info("Checking Option Bytes")
|
||||
|
||||
# OpenOCD
|
||||
openocd = OpenOCDProgrammer(
|
||||
@@ -60,7 +60,7 @@ class Main(App):
|
||||
return return_code
|
||||
|
||||
def set(self):
|
||||
self.logger.info(f"Setting Option Bytes")
|
||||
self.logger.info("Setting Option Bytes")
|
||||
|
||||
# OpenOCD
|
||||
openocd = OpenOCDProgrammer(
|
||||
|
||||
+17
-20
@@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import datetime
|
||||
import logging
|
||||
import argparse
|
||||
import subprocess
|
||||
import os
|
||||
import sys
|
||||
import re
|
||||
import struct
|
||||
import datetime
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult
|
||||
|
||||
OTP_MAGIC = 0xBABE
|
||||
OTP_VERSION = 0x02
|
||||
@@ -33,9 +33,6 @@ OTP_DISPLAYS = {
|
||||
"mgg": 0x02,
|
||||
}
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.utils.programmer_openocd import OpenOCDProgrammer, OpenOCDProgrammerResult
|
||||
|
||||
|
||||
class OTPException(Exception):
|
||||
def __init__(self, message: str, result: OpenOCDProgrammerResult):
|
||||
@@ -158,7 +155,7 @@ class Main(App):
|
||||
)
|
||||
|
||||
def generate_all(self):
|
||||
self.logger.info(f"Generating OTP")
|
||||
self.logger.info("Generating OTP")
|
||||
self._processFirstArgs()
|
||||
self._processSecondArgs()
|
||||
with open(f"{self.args.file}_first.bin", "wb") as file:
|
||||
@@ -172,18 +169,18 @@ class Main(App):
|
||||
return 0
|
||||
|
||||
def flash_first(self):
|
||||
self.logger.info(f"Flashing first block of OTP")
|
||||
self.logger.info("Flashing first block of OTP")
|
||||
|
||||
self._processFirstArgs()
|
||||
|
||||
filename = f"otp_unknown_first_{self.timestamp}.bin"
|
||||
|
||||
try:
|
||||
self.logger.info(f"Packing binary data")
|
||||
self.logger.info("Packing binary data")
|
||||
with open(filename, "wb") as file:
|
||||
file.write(self._packFirst())
|
||||
|
||||
self.logger.info(f"Flashing OTP")
|
||||
self.logger.info("Flashing OTP")
|
||||
|
||||
openocd = OpenOCDProgrammer(
|
||||
self.args.interface,
|
||||
@@ -195,7 +192,7 @@ class Main(App):
|
||||
if programmer_result != OpenOCDProgrammerResult.Success:
|
||||
raise OTPException("Failed to flash OTP", programmer_result)
|
||||
|
||||
self.logger.info(f"Flashed Successfully")
|
||||
self.logger.info("Flashed Successfully")
|
||||
except OTPException as e:
|
||||
self.logger.exception(e)
|
||||
return e.get_exit_code()
|
||||
@@ -205,18 +202,18 @@ class Main(App):
|
||||
return 0
|
||||
|
||||
def flash_second(self):
|
||||
self.logger.info(f"Flashing second block of OTP")
|
||||
self.logger.info("Flashing second block of OTP")
|
||||
|
||||
self._processSecondArgs()
|
||||
|
||||
filename = f"otp_{self.args.name}_second_{self.timestamp}.bin"
|
||||
|
||||
try:
|
||||
self.logger.info(f"Packing binary data")
|
||||
self.logger.info("Packing binary data")
|
||||
with open(filename, "wb") as file:
|
||||
file.write(self._packSecond())
|
||||
|
||||
self.logger.info(f"Flashing OTP")
|
||||
self.logger.info("Flashing OTP")
|
||||
|
||||
openocd = OpenOCDProgrammer(
|
||||
self.args.interface,
|
||||
@@ -228,7 +225,7 @@ class Main(App):
|
||||
if programmer_result != OpenOCDProgrammerResult.Success:
|
||||
raise OTPException("Failed to flash OTP", programmer_result)
|
||||
|
||||
self.logger.info(f"Flashed Successfully")
|
||||
self.logger.info("Flashed Successfully")
|
||||
except OTPException as e:
|
||||
self.logger.exception(e)
|
||||
return e.get_exit_code()
|
||||
@@ -238,7 +235,7 @@ class Main(App):
|
||||
return 0
|
||||
|
||||
def flash_all(self):
|
||||
self.logger.info(f"Flashing OTP")
|
||||
self.logger.info("Flashing OTP")
|
||||
|
||||
self._processFirstArgs()
|
||||
self._processSecondArgs()
|
||||
@@ -246,12 +243,12 @@ class Main(App):
|
||||
filename = f"otp_{self.args.name}_whole_{self.timestamp}.bin"
|
||||
|
||||
try:
|
||||
self.logger.info(f"Packing binary data")
|
||||
self.logger.info("Packing binary data")
|
||||
with open(filename, "wb") as file:
|
||||
file.write(self._packFirst())
|
||||
file.write(self._packSecond())
|
||||
|
||||
self.logger.info(f"Flashing OTP")
|
||||
self.logger.info("Flashing OTP")
|
||||
|
||||
openocd = OpenOCDProgrammer(
|
||||
self.args.interface,
|
||||
@@ -263,7 +260,7 @@ class Main(App):
|
||||
if programmer_result != OpenOCDProgrammerResult.Success:
|
||||
raise OTPException("Failed to flash OTP", programmer_result)
|
||||
|
||||
self.logger.info(f"Flashed Successfully")
|
||||
self.logger.info("Flashed Successfully")
|
||||
except OTPException as e:
|
||||
self.logger.exception(e)
|
||||
return e.get_exit_code()
|
||||
|
||||
+7
-7
@@ -1,13 +1,13 @@
|
||||
#!/usr/bin/env python3
|
||||
import typing
|
||||
import subprocess
|
||||
import logging
|
||||
import time
|
||||
import os
|
||||
import socket
|
||||
|
||||
import subprocess
|
||||
import time
|
||||
import typing
|
||||
from abc import ABC, abstractmethod
|
||||
from dataclasses import dataclass
|
||||
|
||||
from flipper.app import App
|
||||
|
||||
|
||||
@@ -223,7 +223,7 @@ class BlackmagicProgrammer(Programmer):
|
||||
try:
|
||||
socket.inet_aton(address)
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def set_serial(self, serial: str):
|
||||
@@ -415,12 +415,12 @@ class Main(App):
|
||||
if len(interfaces) == 0:
|
||||
interfaces = [p for p in network_programmers if p.get_name() == i_name]
|
||||
else:
|
||||
self.logger.info(f"Probing for interfaces...")
|
||||
self.logger.info("Probing for interfaces...")
|
||||
interfaces = self._search_interface(self.args.serial)
|
||||
|
||||
if len(interfaces) == 0:
|
||||
# Probe network blackmagic
|
||||
self.logger.info(f"Probing for network interfaces...")
|
||||
self.logger.info("Probing for network interfaces...")
|
||||
interfaces = self._search_network_interface(self.args.serial)
|
||||
|
||||
if len(interfaces) == 0:
|
||||
|
||||
+5
-7
@@ -1,14 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import operator
|
||||
from functools import reduce
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.storage import FlipperStorage, FlipperStorageOperations
|
||||
from flipper.utils.cdc import resolve_port
|
||||
|
||||
import os
|
||||
import posixpath
|
||||
from functools import reduce
|
||||
import operator
|
||||
|
||||
|
||||
class Main(App):
|
||||
def init(self):
|
||||
@@ -38,8 +36,8 @@ class Main(App):
|
||||
self.parser.set_defaults(func=self.install)
|
||||
|
||||
@staticmethod
|
||||
def flatten(l):
|
||||
return reduce(operator.concat, l, [])
|
||||
def flatten(item_list):
|
||||
return reduce(operator.concat, item_list, [])
|
||||
|
||||
def install(self):
|
||||
self.args.sources = self.flatten(self.args.sources)
|
||||
|
||||
@@ -5,7 +5,7 @@ import shutil
|
||||
import tarfile
|
||||
import zipfile
|
||||
from os import makedirs, walk, environ
|
||||
from os.path import exists, join, relpath, basename, split
|
||||
from os.path import basename, exists, join, relpath
|
||||
|
||||
from ansi.color import fg
|
||||
from flipper.app import App
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from typing import final
|
||||
from flipper.app import App
|
||||
from flipper.storage import FlipperStorage, FlipperStorageOperations
|
||||
from flipper.utils.cdc import resolve_port
|
||||
|
||||
import logging
|
||||
import os
|
||||
import pathlib
|
||||
import serial.tools.list_ports as list_ports
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.storage import FlipperStorage, FlipperStorageOperations
|
||||
from flipper.utils.cdc import resolve_port
|
||||
|
||||
|
||||
class Main(App):
|
||||
@@ -54,7 +52,7 @@ class Main(App):
|
||||
f"update install {flipper_update_path}/{manifest_name}\r"
|
||||
)
|
||||
result = storage.read.until(storage.CLI_EOL)
|
||||
if not b"Verifying" in result:
|
||||
if b"Verifying" not in result:
|
||||
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
|
||||
return 3
|
||||
result = storage.read.until(storage.CLI_EOL)
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
import logging
|
||||
import subprocess
|
||||
from flipper.utils.cdc import resolve_port
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
from flipper.utils.cdc import resolve_port
|
||||
|
||||
|
||||
def main():
|
||||
logger = logging.getLogger()
|
||||
|
||||
+6
-6
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import binascii
|
||||
import filecmp
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from flipper.app import App
|
||||
from flipper.storage import FlipperStorage, FlipperStorageOperations
|
||||
from flipper.utils.cdc import resolve_port
|
||||
|
||||
import os
|
||||
import binascii
|
||||
import filecmp
|
||||
import tempfile
|
||||
|
||||
|
||||
def WrapStorageOp(func):
|
||||
def wrapper(*args, **kwargs):
|
||||
@@ -122,7 +122,7 @@ class Main(App):
|
||||
try:
|
||||
print("Text data:")
|
||||
print(data.decode())
|
||||
except:
|
||||
except Exception:
|
||||
print("Binary hexadecimal data:")
|
||||
print(binascii.hexlify(data).decode())
|
||||
|
||||
|
||||
@@ -56,6 +56,16 @@ fbtenv_restore_env()
|
||||
unset SSL_CERT_FILE;
|
||||
unset REQUESTS_CA_BUNDLE;
|
||||
fi
|
||||
|
||||
if [ "$SYS_TYPE" = "Linux" ]; then
|
||||
if [ -n "$SAVED_TERMINFO_DIRS" ]; then
|
||||
export TERMINFO_DIRS="$SAVED_TERMINFO_DIRS";
|
||||
else
|
||||
unset TERMINFO_DIRS;
|
||||
fi
|
||||
unset SAVED_TERMINFO_DIRS;
|
||||
fi
|
||||
|
||||
export PYTHONNOUSERSITE="$SAVED_PYTHONNOUSERSITE";
|
||||
export PYTHONPATH="$SAVED_PYTHONPATH";
|
||||
export PYTHONHOME="$SAVED_PYTHONHOME";
|
||||
@@ -335,6 +345,11 @@ fbtenv_main()
|
||||
export PYTHONNOUSERSITE=1;
|
||||
export PYTHONPATH=;
|
||||
export PYTHONHOME=;
|
||||
|
||||
if [ "$SYS_TYPE" = "Linux" ]; then
|
||||
export SAVED_TERMINFO_DIRS="${TERMINFO_DIRS:-""}";
|
||||
export TERMINFO_DIRS="$TOOLCHAIN_ARCH_DIR/ncurses/share/terminfo";
|
||||
fi
|
||||
}
|
||||
|
||||
fbtenv_main "${1:-""}";
|
||||
|
||||
+25
-12
@@ -1,7 +1,6 @@
|
||||
from SCons.Platform import TempFileMunge
|
||||
from SCons.Node import FS
|
||||
from SCons.Errors import UserError
|
||||
from SCons.Warnings import warn, WarningOnByDefault
|
||||
|
||||
|
||||
import os
|
||||
@@ -14,6 +13,7 @@ SetOption("max_drift", 1)
|
||||
|
||||
ufbt_state_dir = Dir(os.environ.get("UFBT_STATE_DIR", "#.ufbt"))
|
||||
ufbt_script_dir = Dir(os.environ.get("UFBT_SCRIPT_DIR"))
|
||||
ufbt_build_dir = ufbt_state_dir.Dir("build")
|
||||
|
||||
ufbt_current_sdk_dir = ufbt_state_dir.Dir("current")
|
||||
|
||||
@@ -63,16 +63,7 @@ core_env = Environment(
|
||||
],
|
||||
)
|
||||
|
||||
if "update" in BUILD_TARGETS:
|
||||
SConscript(
|
||||
"update.scons",
|
||||
exports={"core_env": core_env},
|
||||
)
|
||||
|
||||
if "purge" in BUILD_TARGETS:
|
||||
core_env.Execute(Delete(ufbt_state_dir))
|
||||
print("uFBT state purged")
|
||||
Exit(0)
|
||||
core_env.Append(CPPDEFINES=GetOption("extra_defines"))
|
||||
|
||||
# Now we can import stuff bundled with SDK - it was added to sys.path by ufbt_state
|
||||
|
||||
@@ -109,7 +100,7 @@ env = core_env.Clone(
|
||||
"fbt_assets",
|
||||
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
|
||||
],
|
||||
FBT_FAP_DEBUG_ELF_ROOT=ufbt_state_dir.Dir("build"),
|
||||
FBT_FAP_DEBUG_ELF_ROOT=ufbt_build_dir,
|
||||
TEMPFILE=TempFileMunge,
|
||||
MAXLINELENGTH=2048,
|
||||
PROGSUFFIX=".elf",
|
||||
@@ -427,3 +418,25 @@ dist_env.PhonyTarget(
|
||||
"get_apiversion",
|
||||
"@echo $( ${UFBT_API_VERSION} $)",
|
||||
)
|
||||
|
||||
# Dolphin animation builder. Expects "external" directory in current dir
|
||||
# with animation sources & manifests. Builds & uploads them to connected Flipper
|
||||
dolphin_src_dir = original_app_dir.Dir("external")
|
||||
if dolphin_src_dir.exists():
|
||||
dolphin_dir = ufbt_build_dir.Dir("dolphin")
|
||||
dolphin_external = dist_env.DolphinExtBuilder(
|
||||
ufbt_build_dir.Dir("dolphin"),
|
||||
original_app_dir,
|
||||
DOLPHIN_RES_TYPE="external",
|
||||
)
|
||||
dist_env.PhonyTarget(
|
||||
"dolphin_ext",
|
||||
'${PYTHON3} ${FBT_SCRIPT_DIR}/storage.py send "${SOURCE}" /ext/dolphin',
|
||||
source=ufbt_build_dir.Dir("dolphin"),
|
||||
)
|
||||
else:
|
||||
|
||||
def missing_dolphin_folder(**kw):
|
||||
raise UserError(f"Dolphin folder not found: {dolphin_src_dir}")
|
||||
|
||||
dist_env.PhonyTarget("dolphin_ext", Action(missing_dolphin_folder, None))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user