mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-12-24 22:07:14 +03:00
Merge branch 'fz-dev' into dev
This commit is contained in:
commit
c708a301f5
@ -1 +1 @@
|
|||||||
--rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap
|
--ignore-ccache -C gccarm --rules-config .pvsconfig -e lib/fatfs -e lib/fnv1a-hash -e lib/FreeRTOS-Kernel -e lib/heatshrink -e lib/libusb_stm32 -e lib/littlefs -e lib/mbedtls -e lib/micro-ecc -e lib/microtar -e lib/mlib -e lib/qrcode -e lib/ST25RFAL002 -e lib/STM32CubeWB -e lib/u8g2 -e lib/nanopb -e */arm-none-eabi/* -e applications/plugins/dap_link/lib/free-dap
|
||||||
|
18
.vscode/example/tasks.json
vendored
18
.vscode/example/tasks.json
vendored
@ -105,6 +105,12 @@
|
|||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
|
"command": "./fbt COMPACT=1 DEBUG=0 FORCE=1 flash_usb_full"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "[Debug] Create PVS-Studio report",
|
||||||
|
"group": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./fbt firmware_pvs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "[Debug] Build FAPs",
|
"label": "[Debug] Build FAPs",
|
||||||
"group": "build",
|
"group": "build",
|
||||||
@ -138,6 +144,18 @@
|
|||||||
"Serial Console"
|
"Serial Console"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "[Debug] Build and upload all FAPs to Flipper over USB",
|
||||||
|
"group": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./fbt fap_deploy"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "[Release] Build and upload all FAPs to Flipper over USB",
|
||||||
|
"group": "build",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "./fbt COMPACT=1 DEBUG=0 fap_deploy"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
// Press Ctrl+] to quit
|
// Press Ctrl+] to quit
|
||||||
"label": "Serial Console",
|
"label": "Serial Console",
|
||||||
|
15
SConstruct
15
SConstruct
@ -148,9 +148,12 @@ fap_dist = [
|
|||||||
for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
|
for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
*(
|
||||||
distenv.Install(
|
distenv.Install(
|
||||||
f"#/dist/{dist_dir}/apps",
|
f"#/dist/{dist_dir}/apps/{app_artifact.app.fap_category}",
|
||||||
"#/assets/resources/apps",
|
app_artifact.compact[0],
|
||||||
|
)
|
||||||
|
for app_artifact in firmware_env["FW_EXTAPPS"].applications.values()
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
Depends(
|
Depends(
|
||||||
@ -165,6 +168,14 @@ Alias("fap_dist", fap_dist)
|
|||||||
|
|
||||||
distenv.Depends(firmware_env["FW_RESOURCES"], firmware_env["FW_EXTAPPS"].resources_dist)
|
distenv.Depends(firmware_env["FW_RESOURCES"], firmware_env["FW_EXTAPPS"].resources_dist)
|
||||||
|
|
||||||
|
# Copy all faps to device
|
||||||
|
|
||||||
|
fap_deploy = distenv.PhonyTarget(
|
||||||
|
"fap_deploy",
|
||||||
|
"${PYTHON3} ${ROOT_DIR}/scripts/storage.py send ${SOURCE} /ext/apps",
|
||||||
|
source=Dir("#/assets/resources/apps"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
# Target for bundling core2 package for qFlipper
|
# Target for bundling core2 package for qFlipper
|
||||||
copro_dist = distenv.CoproBuilder(
|
copro_dist = distenv.CoproBuilder(
|
||||||
|
@ -31,7 +31,8 @@ void AccessorApp::run(void) {
|
|||||||
onewire_host_stop(onewire_host);
|
onewire_host_stop(onewire_host);
|
||||||
}
|
}
|
||||||
|
|
||||||
AccessorApp::AccessorApp() {
|
AccessorApp::AccessorApp()
|
||||||
|
: text_store{0} {
|
||||||
notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
|
notification = static_cast<NotificationApp*>(furi_record_open(RECORD_NOTIFICATION));
|
||||||
onewire_host = onewire_host_alloc();
|
onewire_host = onewire_host_alloc();
|
||||||
furi_hal_power_enable_otg();
|
furi_hal_power_enable_otg();
|
||||||
|
@ -171,9 +171,6 @@ bool WIEGAND::DoWiegandConversion() {
|
|||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
_lastWiegand = sysTick;
|
_lastWiegand = sysTick;
|
||||||
_bitCount = 0;
|
|
||||||
_cardTemp = 0;
|
|
||||||
_cardTempHigh = 0;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
|
|
||||||
#include <gui/canvas.h>
|
#include <gui/canvas.h>
|
||||||
#include <gui/elements.h>
|
#include <gui/elements.h>
|
||||||
|
|
||||||
|
#include <lib/toolbox/float_tools.h>
|
||||||
#include <m-array.h>
|
#include <m-array.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
#include <inttypes.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct BtTestParam {
|
struct BtTestParam {
|
||||||
@ -98,16 +101,16 @@ static void bt_test_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
elements_scrollbar(canvas, model->position, BtTestParamArray_size(model->params));
|
elements_scrollbar(canvas, model->position, BtTestParamArray_size(model->params));
|
||||||
canvas_draw_str(canvas, 6, 60, model->message);
|
canvas_draw_str(canvas, 6, 60, model->message);
|
||||||
if(model->state == BtTestStateStarted) {
|
if(model->state == BtTestStateStarted) {
|
||||||
if(model->rssi != 0.0f) {
|
if(!float_is_equal(model->rssi, 0.0f)) {
|
||||||
snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi);
|
snprintf(info_str, sizeof(info_str), "RSSI:%3.1f dB", (double)model->rssi);
|
||||||
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
||||||
}
|
}
|
||||||
} else if(model->state == BtTestStateStopped) {
|
} else if(model->state == BtTestStateStopped) {
|
||||||
if(model->packets_num_rx) {
|
if(model->packets_num_rx) {
|
||||||
snprintf(info_str, sizeof(info_str), "%ld pack rcv", model->packets_num_rx);
|
snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack rcv", model->packets_num_rx);
|
||||||
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
||||||
} else if(model->packets_num_tx) {
|
} else if(model->packets_num_tx) {
|
||||||
snprintf(info_str, sizeof(info_str), "%ld pack sent", model->packets_num_tx);
|
snprintf(info_str, sizeof(info_str), "%" PRIu32 " pack sent", model->packets_num_tx);
|
||||||
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
canvas_draw_str_aligned(canvas, 124, 60, AlignRight, AlignBottom, info_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,7 +156,7 @@ static bool bt_test_input_callback(InputEvent* event, void* context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void bt_test_process_up(BtTest* bt_test) {
|
void bt_test_process_up(BtTest* bt_test) {
|
||||||
with_view_model(
|
with_view_model( // -V658
|
||||||
bt_test->view,
|
bt_test->view,
|
||||||
BtTestModel * model,
|
BtTestModel * model,
|
||||||
{
|
{
|
||||||
|
@ -48,7 +48,7 @@ FileBrowserApp* file_browser_app_alloc(char* arg) {
|
|||||||
|
|
||||||
app->file_path = furi_string_alloc();
|
app->file_path = furi_string_alloc();
|
||||||
app->file_browser = file_browser_alloc(app->file_path);
|
app->file_browser = file_browser_alloc(app->file_path);
|
||||||
file_browser_configure(app->file_browser, "*", NULL, true, &I_badusb_10px, true);
|
file_browser_configure(app->file_browser, "*", NULL, true, false, &I_badusb_10px, true);
|
||||||
|
|
||||||
view_dispatcher_add_view(
|
view_dispatcher_add_view(
|
||||||
app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget));
|
app->view_dispatcher, FileBrowserAppViewStart, widget_get_view(app->widget));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
App(
|
App(
|
||||||
appid="sample_apps",
|
appid="example_apps",
|
||||||
name="Sample apps bundle",
|
name="Example apps bundle",
|
||||||
apptype=FlipperAppType.METAPACKAGE,
|
apptype=FlipperAppType.METAPACKAGE,
|
||||||
)
|
)
|
||||||
|
@ -75,8 +75,8 @@ static const DuckyKey ducky_keys[] = {
|
|||||||
{"BREAK", HID_KEYBOARD_PAUSE},
|
{"BREAK", HID_KEYBOARD_PAUSE},
|
||||||
{"PAUSE", HID_KEYBOARD_PAUSE},
|
{"PAUSE", HID_KEYBOARD_PAUSE},
|
||||||
{"CAPSLOCK", HID_KEYBOARD_CAPS_LOCK},
|
{"CAPSLOCK", HID_KEYBOARD_CAPS_LOCK},
|
||||||
{"DELETE", HID_KEYBOARD_DELETE},
|
{"DELETE", HID_KEYBOARD_DELETE_FORWARD},
|
||||||
{"BACKSPACE", HID_KEYPAD_BACKSPACE},
|
{"BACKSPACE", HID_KEYBOARD_DELETE},
|
||||||
{"END", HID_KEYBOARD_END},
|
{"END", HID_KEYBOARD_END},
|
||||||
{"ESC", HID_KEYBOARD_ESCAPE},
|
{"ESC", HID_KEYBOARD_ESCAPE},
|
||||||
{"ESCAPE", HID_KEYBOARD_ESCAPE},
|
{"ESCAPE", HID_KEYBOARD_ESCAPE},
|
||||||
|
@ -14,9 +14,12 @@ static const char* uart_ch[] = {"13,14", "15,16"};
|
|||||||
static const char* flow_pins[] = {"None", "2,3", "6,7", "16,15"};
|
static const char* flow_pins[] = {"None", "2,3", "6,7", "16,15"};
|
||||||
static const char* baudrate_mode[] = {"Host"};
|
static const char* baudrate_mode[] = {"Host"};
|
||||||
static const uint32_t baudrate_list[] = {
|
static const uint32_t baudrate_list[] = {
|
||||||
|
1200,
|
||||||
2400,
|
2400,
|
||||||
|
4800,
|
||||||
9600,
|
9600,
|
||||||
19200,
|
19200,
|
||||||
|
28800,
|
||||||
38400,
|
38400,
|
||||||
57600,
|
57600,
|
||||||
115200,
|
115200,
|
||||||
|
@ -56,7 +56,7 @@ static bool desktop_view_slideshow_input(InputEvent* event, void* context) {
|
|||||||
instance->callback(DesktopSlideshowCompleted, instance->context);
|
instance->callback(DesktopSlideshowCompleted, instance->context);
|
||||||
}
|
}
|
||||||
update_view = true;
|
update_view = true;
|
||||||
} else if(event->key == InputKeyOk) {
|
} else if(event->key == InputKeyOk && instance->timer) {
|
||||||
if(event->type == InputTypePress) {
|
if(event->type == InputTypePress) {
|
||||||
furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT);
|
furi_timer_start(instance->timer, DESKTOP_SLIDESHOW_POWEROFF_SHORT);
|
||||||
} else if(event->type == InputTypeRelease) {
|
} else if(event->type == InputTypeRelease) {
|
||||||
|
@ -178,6 +178,47 @@ static void button_menu_process_down(ButtonMenu* button_menu) {
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void button_menu_process_right(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view,
|
||||||
|
ButtonMenuModel * model,
|
||||||
|
{
|
||||||
|
if(ButtonMenuItemArray_size(model->items) > BUTTONS_PER_SCREEN) {
|
||||||
|
size_t position_candidate = model->position + BUTTONS_PER_SCREEN;
|
||||||
|
position_candidate -= position_candidate % BUTTONS_PER_SCREEN;
|
||||||
|
if(position_candidate < (ButtonMenuItemArray_size(model->items))) {
|
||||||
|
model->position = position_candidate;
|
||||||
|
} else {
|
||||||
|
model->position = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_menu_process_left(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view,
|
||||||
|
ButtonMenuModel * model,
|
||||||
|
{
|
||||||
|
if(ButtonMenuItemArray_size(model->items) > BUTTONS_PER_SCREEN) {
|
||||||
|
size_t position_candidate;
|
||||||
|
if(model->position < BUTTONS_PER_SCREEN) {
|
||||||
|
position_candidate = (ButtonMenuItemArray_size(model->items) - 1);
|
||||||
|
} else {
|
||||||
|
position_candidate = model->position - BUTTONS_PER_SCREEN;
|
||||||
|
};
|
||||||
|
position_candidate -= position_candidate % BUTTONS_PER_SCREEN;
|
||||||
|
model->position = position_candidate;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) {
|
static void button_menu_process_ok(ButtonMenu* button_menu, InputType type) {
|
||||||
furi_assert(button_menu);
|
furi_assert(button_menu);
|
||||||
|
|
||||||
@ -239,6 +280,14 @@ static bool button_menu_view_input_callback(InputEvent* event, void* context) {
|
|||||||
consumed = true;
|
consumed = true;
|
||||||
button_menu_process_down(button_menu);
|
button_menu_process_down(button_menu);
|
||||||
break;
|
break;
|
||||||
|
case InputKeyRight:
|
||||||
|
consumed = true;
|
||||||
|
button_menu_process_right(button_menu);
|
||||||
|
break;
|
||||||
|
case InputKeyLeft:
|
||||||
|
consumed = true;
|
||||||
|
button_menu_process_left(button_menu);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ typedef struct {
|
|||||||
TextInputValidatorCallback validator_callback;
|
TextInputValidatorCallback validator_callback;
|
||||||
void* validator_callback_context;
|
void* validator_callback_context;
|
||||||
FuriString* validator_text;
|
FuriString* validator_text;
|
||||||
bool valadator_message_visible;
|
bool validator_message_visible;
|
||||||
} TextInputModel;
|
} TextInputModel;
|
||||||
|
|
||||||
static const uint8_t keyboard_origin_x = 1;
|
static const uint8_t keyboard_origin_x = 1;
|
||||||
@ -138,7 +138,7 @@ static bool char_is_lowercase(char letter) {
|
|||||||
static char char_to_uppercase(const char letter) {
|
static char char_to_uppercase(const char letter) {
|
||||||
if(letter == '_') {
|
if(letter == '_') {
|
||||||
return 0x20;
|
return 0x20;
|
||||||
} else if(isalpha(letter)) {
|
} else if(islower(letter)) {
|
||||||
return (letter - 0x20);
|
return (letter - 0x20);
|
||||||
} else {
|
} else {
|
||||||
return letter;
|
return letter;
|
||||||
@ -254,7 +254,7 @@ static void text_input_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(model->valadator_message_visible) {
|
if(model->validator_message_visible) {
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontSecondary);
|
||||||
canvas_set_color(canvas, ColorWhite);
|
canvas_set_color(canvas, ColorWhite);
|
||||||
canvas_draw_box(canvas, 8, 10, 110, 48);
|
canvas_draw_box(canvas, 8, 10, 110, 48);
|
||||||
@ -309,7 +309,9 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b
|
|||||||
char selected = get_selected_char(model);
|
char selected = get_selected_char(model);
|
||||||
size_t text_length = strlen(model->text_buffer);
|
size_t text_length = strlen(model->text_buffer);
|
||||||
|
|
||||||
if(shift) {
|
bool toogle_case = text_length == 0;
|
||||||
|
if(shift) toogle_case = !toogle_case;
|
||||||
|
if(toogle_case) {
|
||||||
selected = char_to_uppercase(selected);
|
selected = char_to_uppercase(selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +319,7 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b
|
|||||||
if(model->validator_callback &&
|
if(model->validator_callback &&
|
||||||
(!model->validator_callback(
|
(!model->validator_callback(
|
||||||
model->text_buffer, model->validator_text, model->validator_callback_context))) {
|
model->text_buffer, model->validator_text, model->validator_callback_context))) {
|
||||||
model->valadator_message_visible = true;
|
model->validator_message_visible = true;
|
||||||
furi_timer_start(text_input->timer, furi_kernel_get_tick_frequency() * 4);
|
furi_timer_start(text_input->timer, furi_kernel_get_tick_frequency() * 4);
|
||||||
} else if(model->callback != 0 && text_length > 0) {
|
} else if(model->callback != 0 && text_length > 0) {
|
||||||
model->callback(model->callback_context);
|
model->callback(model->callback_context);
|
||||||
@ -329,9 +331,6 @@ static void text_input_handle_ok(TextInput* text_input, TextInputModel* model, b
|
|||||||
text_length = 0;
|
text_length = 0;
|
||||||
}
|
}
|
||||||
if(text_length < (model->text_buffer_size - 1)) {
|
if(text_length < (model->text_buffer_size - 1)) {
|
||||||
if(text_length == 0 && char_is_lowercase(selected)) {
|
|
||||||
selected = char_to_uppercase(selected);
|
|
||||||
}
|
|
||||||
model->text_buffer[text_length] = selected;
|
model->text_buffer[text_length] = selected;
|
||||||
model->text_buffer[text_length + 1] = 0;
|
model->text_buffer[text_length + 1] = 0;
|
||||||
}
|
}
|
||||||
@ -349,8 +348,8 @@ static bool text_input_view_input_callback(InputEvent* event, void* context) {
|
|||||||
TextInputModel* model = view_get_model(text_input->view);
|
TextInputModel* model = view_get_model(text_input->view);
|
||||||
|
|
||||||
if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
|
if((!(event->type == InputTypePress) && !(event->type == InputTypeRelease)) &&
|
||||||
model->valadator_message_visible) {
|
model->validator_message_visible) {
|
||||||
model->valadator_message_visible = false;
|
model->validator_message_visible = false;
|
||||||
consumed = true;
|
consumed = true;
|
||||||
} else if(event->type == InputTypeShort) {
|
} else if(event->type == InputTypeShort) {
|
||||||
consumed = true;
|
consumed = true;
|
||||||
@ -436,7 +435,7 @@ void text_input_timer_callback(void* context) {
|
|||||||
with_view_model(
|
with_view_model(
|
||||||
text_input->view,
|
text_input->view,
|
||||||
TextInputModel * model,
|
TextInputModel * model,
|
||||||
{ model->valadator_message_visible = false; },
|
{ model->validator_message_visible = false; },
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -496,7 +495,7 @@ void text_input_reset(TextInput* text_input) {
|
|||||||
model->validator_callback = NULL;
|
model->validator_callback = NULL;
|
||||||
model->validator_callback_context = NULL;
|
model->validator_callback_context = NULL;
|
||||||
furi_string_reset(model->validator_text);
|
furi_string_reset(model->validator_text);
|
||||||
model->valadator_message_visible = false;
|
model->validator_message_visible = false;
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ void widget_add_string_element(
|
|||||||
* @param[in] text Formatted text. The following formats are available:
|
* @param[in] text Formatted text. The following formats are available:
|
||||||
* "\e#Bold text\e#" - bold font is used
|
* "\e#Bold text\e#" - bold font is used
|
||||||
* "\e*Monospaced text\e*" - monospaced font is used
|
* "\e*Monospaced text\e*" - monospaced font is used
|
||||||
* "\e#Inversed text\e#" - white text on black background
|
* "\e!Inversed text\e!" - white text on black background
|
||||||
* @param strip_to_dots Strip text to ... if does not fit to width
|
* @param strip_to_dots Strip text to ... if does not fit to width
|
||||||
*/
|
*/
|
||||||
void widget_add_text_box_element(
|
void widget_add_text_box_element(
|
||||||
|
@ -19,7 +19,7 @@ extern "C" {
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
InputTypePress, /**< Press event, emitted after debounce */
|
InputTypePress, /**< Press event, emitted after debounce */
|
||||||
InputTypeRelease, /**< Release event, emitted after debounce */
|
InputTypeRelease, /**< Release event, emitted after debounce */
|
||||||
InputTypeShort, /**< Short event, emitted after InputTypeRelease done withing INPUT_LONG_PRESS interval */
|
InputTypeShort, /**< Short event, emitted after InputTypeRelease done within INPUT_LONG_PRESS interval */
|
||||||
InputTypeLong, /**< Long event, emitted after INPUT_LONG_PRESS_COUNTS interval, asynchronous to InputTypeRelease */
|
InputTypeLong, /**< Long event, emitted after INPUT_LONG_PRESS_COUNTS interval, asynchronous to InputTypeRelease */
|
||||||
InputTypeRepeat, /**< Repeat event, emitted with INPUT_LONG_PRESS_COUNTS period after InputTypeLong event */
|
InputTypeRepeat, /**< Repeat event, emitted with INPUT_LONG_PRESS_COUNTS period after InputTypeLong event */
|
||||||
InputTypeMAX, /**< Special value for exceptional */
|
InputTypeMAX, /**< Special value for exceptional */
|
||||||
|
@ -54,13 +54,14 @@ assetsenv.Alias("proto_ver", proto_ver)
|
|||||||
|
|
||||||
# Gather everything into a static lib
|
# Gather everything into a static lib
|
||||||
assets_parts = (icons, proto, dolphin_blocking, dolphin_internal, proto_ver)
|
assets_parts = (icons, proto, dolphin_blocking, dolphin_internal, proto_ver)
|
||||||
|
env.Replace(FW_ASSETS_HEADERS=assets_parts)
|
||||||
|
|
||||||
assetslib = assetsenv.Library("${FW_LIB_NAME}", assets_parts)
|
assetslib = assetsenv.Library("${FW_LIB_NAME}", assets_parts)
|
||||||
assetsenv.Install("${LIB_DIST_DIR}", assetslib)
|
assetsenv.Install("${LIB_DIST_DIR}", assetslib)
|
||||||
|
|
||||||
|
|
||||||
# Resources for SD card
|
# Resources for SD card
|
||||||
|
env.SetDefault(FW_RESOURCES=None)
|
||||||
if assetsenv["IS_BASE_FIRMWARE"]:
|
if assetsenv["IS_BASE_FIRMWARE"]:
|
||||||
# External dolphin animations
|
# External dolphin animations
|
||||||
dolphin_external = assetsenv.DolphinExtBuilder(
|
dolphin_external = assetsenv.DolphinExtBuilder(
|
||||||
@ -92,8 +93,7 @@ if assetsenv["IS_BASE_FIRMWARE"]:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Exporting resources node to external environment
|
# Exporting resources node to external environment
|
||||||
env["FW_ASSETS_HEADERS"] = assets_parts
|
env.Replace(FW_RESOURCES=resources)
|
||||||
env["FW_RESOURCES"] = resources
|
|
||||||
assetsenv.Alias("resources", resources)
|
assetsenv.Alias("resources", resources)
|
||||||
|
|
||||||
Return("assetslib")
|
Return("assetslib")
|
||||||
|
@ -79,7 +79,7 @@ STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script fo
|
|||||||
ENTER
|
ENTER
|
||||||
STRING More information about script syntax can be found here:
|
STRING More information about script syntax can be found here:
|
||||||
ENTER
|
ENTER
|
||||||
STRING https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript
|
STRING https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/BadUsbScriptFormat.md
|
||||||
ENTER
|
ENTER
|
||||||
|
|
||||||
STRING EOF
|
STRING EOF
|
||||||
|
@ -80,5 +80,5 @@ STRING Flipper Zero BadUSB feature is compatible with USB Rubber Ducky script fo
|
|||||||
ENTER
|
ENTER
|
||||||
STRING More information about script syntax can be found here:
|
STRING More information about script syntax can be found here:
|
||||||
ENTER
|
ENTER
|
||||||
STRING https://github.com/hak5darren/USB-Rubber-Ducky/wiki/Duckyscript
|
STRING https://github.com/flipperdevices/flipperzero-firmware/blob/dev/documentation/file_formats/BadUsbScriptFormat.md
|
||||||
ENTER
|
ENTER
|
||||||
|
@ -56,6 +56,7 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
|
|||||||
- `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `OPENOCD_ADAPTER_SERIAL=...`.
|
- `get_stlink` - output serial numbers for attached STLink probes. Used for specifying an adapter with `OPENOCD_ADAPTER_SERIAL=...`.
|
||||||
- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs.
|
- `lint`, `format` - run clang-format on the C source code to check and reformat it according to the `.clang-format` specs.
|
||||||
- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests.
|
- `lint_py`, `format_py` - run [black](https://black.readthedocs.io/en/stable/index.html) on the Python source code, build system files & application manifests.
|
||||||
|
- `firmware_pvs` - generate a PVS Studio report for the firmware. Requires PVS Studio to be availabe on your system's `PATH`.
|
||||||
- `cli` - start a Flipper CLI session over USB.
|
- `cli` - start a Flipper CLI session over USB.
|
||||||
|
|
||||||
### Firmware targets
|
### Firmware targets
|
||||||
|
@ -15,6 +15,7 @@ env = ENV.Clone(
|
|||||||
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
|
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
|
||||||
"fwbin",
|
"fwbin",
|
||||||
"fbt_apps",
|
"fbt_apps",
|
||||||
|
"pvsstudio",
|
||||||
],
|
],
|
||||||
COMPILATIONDB_USE_ABSPATH=False,
|
COMPILATIONDB_USE_ABSPATH=False,
|
||||||
BUILD_DIR=fw_build_meta["build_dir"],
|
BUILD_DIR=fw_build_meta["build_dir"],
|
||||||
@ -69,6 +70,8 @@ env = ENV.Clone(
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
SDK_APISYMS=None,
|
||||||
|
_APP_ICONS=None,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -128,9 +131,6 @@ if extra_int_apps := GetOption("extra_int_apps"):
|
|||||||
fwenv.Append(APPS=extra_int_apps.split(","))
|
fwenv.Append(APPS=extra_int_apps.split(","))
|
||||||
|
|
||||||
|
|
||||||
if fwenv["FAP_EXAMPLES"]:
|
|
||||||
fwenv.Append(APPDIRS=[("applications/examples", False)])
|
|
||||||
|
|
||||||
for app_dir, _ in env["APPDIRS"]:
|
for app_dir, _ in env["APPDIRS"]:
|
||||||
app_dir_node = env.Dir("#").Dir(app_dir)
|
app_dir_node = env.Dir("#").Dir(app_dir)
|
||||||
|
|
||||||
@ -273,6 +273,24 @@ Precious(fwcdb)
|
|||||||
NoClean(fwcdb)
|
NoClean(fwcdb)
|
||||||
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb)
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_cdb", fwcdb)
|
||||||
|
|
||||||
|
pvscheck = fwenv.PVSCheck("pvsreport.log", fwcdb)
|
||||||
|
Depends(
|
||||||
|
pvscheck,
|
||||||
|
[
|
||||||
|
fwenv["FW_VERSION_JSON"],
|
||||||
|
fwenv["FW_ASSETS_HEADERS"],
|
||||||
|
fwenv["SDK_APISYMS"],
|
||||||
|
fwenv["_APP_ICONS"],
|
||||||
|
],
|
||||||
|
)
|
||||||
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_pvscheck", pvscheck)
|
||||||
|
AlwaysBuild(pvscheck)
|
||||||
|
Precious(pvscheck)
|
||||||
|
|
||||||
|
pvsreport = fwenv.PVSReport(None, pvscheck, REPORT_DIR=Dir("pvsreport"))
|
||||||
|
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_pvs", pvsreport)
|
||||||
|
AlwaysBuild(pvsreport)
|
||||||
|
|
||||||
# If current configuration was explicitly requested, generate compilation database
|
# If current configuration was explicitly requested, generate compilation database
|
||||||
# and link its directory as build/latest
|
# and link its directory as build/latest
|
||||||
if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):
|
if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,11.6,,
|
Version,+,11.7,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@ -1649,6 +1649,7 @@ Function,+,infrared_get_protocol_by_name,InfraredProtocol,const char*
|
|||||||
Function,+,infrared_get_protocol_command_length,uint8_t,InfraredProtocol
|
Function,+,infrared_get_protocol_command_length,uint8_t,InfraredProtocol
|
||||||
Function,+,infrared_get_protocol_duty_cycle,float,InfraredProtocol
|
Function,+,infrared_get_protocol_duty_cycle,float,InfraredProtocol
|
||||||
Function,+,infrared_get_protocol_frequency,uint32_t,InfraredProtocol
|
Function,+,infrared_get_protocol_frequency,uint32_t,InfraredProtocol
|
||||||
|
Function,+,infrared_get_protocol_min_repeat_count,size_t,InfraredProtocol
|
||||||
Function,+,infrared_get_protocol_name,const char*,InfraredProtocol
|
Function,+,infrared_get_protocol_name,const char*,InfraredProtocol
|
||||||
Function,+,infrared_is_protocol_valid,_Bool,InfraredProtocol
|
Function,+,infrared_is_protocol_valid,_Bool,InfraredProtocol
|
||||||
Function,+,infrared_reset_decoder,void,InfraredDecoderHandler*
|
Function,+,infrared_reset_decoder,void,InfraredDecoderHandler*
|
||||||
|
|
@ -93,7 +93,11 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef FURI_BIT_CLEAR
|
#ifndef FURI_BIT_CLEAR
|
||||||
#define FURI_BIT_CLEAR(x, n) ((x) &= ~(1UL << (n)))
|
#define FURI_BIT_CLEAR(x, n) \
|
||||||
|
({ \
|
||||||
|
__typeof__(x) _x = (1); \
|
||||||
|
(x) &= ~(_x << (n)); \
|
||||||
|
})
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define FURI_SW_MEMBARRIER() asm volatile("" : : : "memory")
|
#define FURI_SW_MEMBARRIER() asm volatile("" : : : "memory")
|
||||||
|
@ -315,6 +315,7 @@ static bool elf_relocate_symbol(ELFFile* elf, Elf32_Addr relAddr, int type, Elf3
|
|||||||
FURI_LOG_D(TAG, " R_ARM_ABS32 relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
|
FURI_LOG_D(TAG, " R_ARM_ABS32 relocated is 0x%08X", (unsigned int)*((uint32_t*)relAddr));
|
||||||
break;
|
break;
|
||||||
case R_ARM_THM_PC22:
|
case R_ARM_THM_PC22:
|
||||||
|
case R_ARM_CALL:
|
||||||
case R_ARM_THM_JUMP24:
|
case R_ARM_THM_JUMP24:
|
||||||
elf_relocate_jmp_call(elf, relAddr, type, symAddr);
|
elf_relocate_jmp_call(elf, relAddr, type, symAddr);
|
||||||
FURI_LOG_D(
|
FURI_LOG_D(
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
|
#include "infrared_common_i.h"
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
#include <core/common_defines.h>
|
#include <core/common_defines.h>
|
||||||
#include "infrared.h"
|
|
||||||
#include "infrared_common_i.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <furi.h>
|
|
||||||
#include "infrared_i.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
static void infrared_common_decoder_reset_state(InfraredCommonDecoder* decoder);
|
static void infrared_common_decoder_reset_state(InfraredCommonDecoder* decoder);
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
#include <core/check.h>
|
|
||||||
#include "infrared.h"
|
|
||||||
#include "infrared_common_i.h"
|
#include "infrared_common_i.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <furi.h>
|
#include <stdlib.h>
|
||||||
#include "infrared_i.h"
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <core/check.h>
|
||||||
|
#include <core/common_defines.h>
|
||||||
|
|
||||||
static InfraredStatus
|
static InfraredStatus
|
||||||
infrared_common_encode_bits(InfraredCommonEncoder* encoder, uint32_t* duration, bool* level) {
|
infrared_common_encode_bits(InfraredCommonEncoder* encoder, uint32_t* duration, bool* level) {
|
||||||
|
@ -1,140 +0,0 @@
|
|||||||
#include "infrared_common_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
const InfraredCommonProtocolSpec protocol_nec = {
|
|
||||||
.timings =
|
|
||||||
{
|
|
||||||
.preamble_mark = INFRARED_NEC_PREAMBLE_MARK,
|
|
||||||
.preamble_space = INFRARED_NEC_PREAMBLE_SPACE,
|
|
||||||
.bit1_mark = INFRARED_NEC_BIT1_MARK,
|
|
||||||
.bit1_space = INFRARED_NEC_BIT1_SPACE,
|
|
||||||
.bit0_mark = INFRARED_NEC_BIT0_MARK,
|
|
||||||
.bit0_space = INFRARED_NEC_BIT0_SPACE,
|
|
||||||
.preamble_tolerance = INFRARED_NEC_PREAMBLE_TOLERANCE,
|
|
||||||
.bit_tolerance = INFRARED_NEC_BIT_TOLERANCE,
|
|
||||||
.silence_time = INFRARED_NEC_SILENCE,
|
|
||||||
.min_split_time = INFRARED_NEC_MIN_SPLIT_TIME,
|
|
||||||
},
|
|
||||||
.databit_len[0] = 42,
|
|
||||||
.databit_len[1] = 32,
|
|
||||||
.no_stop_bit = false,
|
|
||||||
.decode = infrared_common_decode_pdwm,
|
|
||||||
.encode = infrared_common_encode_pdwm,
|
|
||||||
.interpret = infrared_decoder_nec_interpret,
|
|
||||||
.decode_repeat = infrared_decoder_nec_decode_repeat,
|
|
||||||
.encode_repeat = infrared_encoder_nec_encode_repeat,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredCommonProtocolSpec protocol_samsung32 = {
|
|
||||||
.timings =
|
|
||||||
{
|
|
||||||
.preamble_mark = INFRARED_SAMSUNG_PREAMBLE_MARK,
|
|
||||||
.preamble_space = INFRARED_SAMSUNG_PREAMBLE_SPACE,
|
|
||||||
.bit1_mark = INFRARED_SAMSUNG_BIT1_MARK,
|
|
||||||
.bit1_space = INFRARED_SAMSUNG_BIT1_SPACE,
|
|
||||||
.bit0_mark = INFRARED_SAMSUNG_BIT0_MARK,
|
|
||||||
.bit0_space = INFRARED_SAMSUNG_BIT0_SPACE,
|
|
||||||
.preamble_tolerance = INFRARED_SAMSUNG_PREAMBLE_TOLERANCE,
|
|
||||||
.bit_tolerance = INFRARED_SAMSUNG_BIT_TOLERANCE,
|
|
||||||
.silence_time = INFRARED_SAMSUNG_SILENCE,
|
|
||||||
.min_split_time = INFRARED_SAMSUNG_MIN_SPLIT_TIME,
|
|
||||||
},
|
|
||||||
.databit_len[0] = 32,
|
|
||||||
.no_stop_bit = false,
|
|
||||||
.decode = infrared_common_decode_pdwm,
|
|
||||||
.encode = infrared_common_encode_pdwm,
|
|
||||||
.interpret = infrared_decoder_samsung32_interpret,
|
|
||||||
.decode_repeat = infrared_decoder_samsung32_decode_repeat,
|
|
||||||
.encode_repeat = infrared_encoder_samsung32_encode_repeat,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredCommonProtocolSpec protocol_rc6 = {
|
|
||||||
.timings =
|
|
||||||
{
|
|
||||||
.preamble_mark = INFRARED_RC6_PREAMBLE_MARK,
|
|
||||||
.preamble_space = INFRARED_RC6_PREAMBLE_SPACE,
|
|
||||||
.bit1_mark = INFRARED_RC6_BIT,
|
|
||||||
.preamble_tolerance = INFRARED_RC6_PREAMBLE_TOLERANCE,
|
|
||||||
.bit_tolerance = INFRARED_RC6_BIT_TOLERANCE,
|
|
||||||
.silence_time = INFRARED_RC6_SILENCE,
|
|
||||||
.min_split_time = INFRARED_RC6_MIN_SPLIT_TIME,
|
|
||||||
},
|
|
||||||
.databit_len[0] =
|
|
||||||
1 + 3 + 1 + 8 +
|
|
||||||
8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
|
|
||||||
.manchester_start_from_space = false,
|
|
||||||
.decode = infrared_decoder_rc6_decode_manchester,
|
|
||||||
.encode = infrared_encoder_rc6_encode_manchester,
|
|
||||||
.interpret = infrared_decoder_rc6_interpret,
|
|
||||||
.decode_repeat = NULL,
|
|
||||||
.encode_repeat = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredCommonProtocolSpec protocol_rc5 = {
|
|
||||||
.timings =
|
|
||||||
{
|
|
||||||
.preamble_mark = 0,
|
|
||||||
.preamble_space = 0,
|
|
||||||
.bit1_mark = INFRARED_RC5_BIT,
|
|
||||||
.preamble_tolerance = 0,
|
|
||||||
.bit_tolerance = INFRARED_RC5_BIT_TOLERANCE,
|
|
||||||
.silence_time = INFRARED_RC5_SILENCE,
|
|
||||||
.min_split_time = INFRARED_RC5_MIN_SPLIT_TIME,
|
|
||||||
},
|
|
||||||
.databit_len[0] = 1 + 1 + 1 + 5 +
|
|
||||||
6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
|
|
||||||
.manchester_start_from_space = true,
|
|
||||||
.decode = infrared_common_decode_manchester,
|
|
||||||
.encode = infrared_common_encode_manchester,
|
|
||||||
.interpret = infrared_decoder_rc5_interpret,
|
|
||||||
.decode_repeat = NULL,
|
|
||||||
.encode_repeat = NULL,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredCommonProtocolSpec protocol_sirc = {
|
|
||||||
.timings =
|
|
||||||
{
|
|
||||||
.preamble_mark = INFRARED_SIRC_PREAMBLE_MARK,
|
|
||||||
.preamble_space = INFRARED_SIRC_PREAMBLE_SPACE,
|
|
||||||
.bit1_mark = INFRARED_SIRC_BIT1_MARK,
|
|
||||||
.bit1_space = INFRARED_SIRC_BIT1_SPACE,
|
|
||||||
.bit0_mark = INFRARED_SIRC_BIT0_MARK,
|
|
||||||
.bit0_space = INFRARED_SIRC_BIT0_SPACE,
|
|
||||||
.preamble_tolerance = INFRARED_SIRC_PREAMBLE_TOLERANCE,
|
|
||||||
.bit_tolerance = INFRARED_SIRC_BIT_TOLERANCE,
|
|
||||||
.silence_time = INFRARED_SIRC_SILENCE,
|
|
||||||
.min_split_time = INFRARED_SIRC_MIN_SPLIT_TIME,
|
|
||||||
},
|
|
||||||
.databit_len[0] = 20,
|
|
||||||
.databit_len[1] = 15,
|
|
||||||
.databit_len[2] = 12,
|
|
||||||
.no_stop_bit = true,
|
|
||||||
.decode = infrared_common_decode_pdwm,
|
|
||||||
.encode = infrared_common_encode_pdwm,
|
|
||||||
.interpret = infrared_decoder_sirc_interpret,
|
|
||||||
.decode_repeat = NULL,
|
|
||||||
.encode_repeat = infrared_encoder_sirc_encode_repeat,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredCommonProtocolSpec protocol_kaseikyo = {
|
|
||||||
.timings =
|
|
||||||
{
|
|
||||||
.preamble_mark = INFRARED_KASEIKYO_PREAMBLE_MARK,
|
|
||||||
.preamble_space = INFRARED_KASEIKYO_PREAMBLE_SPACE,
|
|
||||||
.bit1_mark = INFRARED_KASEIKYO_BIT1_MARK,
|
|
||||||
.bit1_space = INFRARED_KASEIKYO_BIT1_SPACE,
|
|
||||||
.bit0_mark = INFRARED_KASEIKYO_BIT0_MARK,
|
|
||||||
.bit0_space = INFRARED_KASEIKYO_BIT0_SPACE,
|
|
||||||
.preamble_tolerance = INFRARED_KASEIKYO_PREAMBLE_TOLERANCE,
|
|
||||||
.bit_tolerance = INFRARED_KASEIKYO_BIT_TOLERANCE,
|
|
||||||
.silence_time = INFRARED_KASEIKYO_SILENCE,
|
|
||||||
.min_split_time = INFRARED_KASEIKYO_MIN_SPLIT_TIME,
|
|
||||||
},
|
|
||||||
.databit_len[0] = 48,
|
|
||||||
.no_stop_bit = false,
|
|
||||||
.decode = infrared_common_decode_pdwm,
|
|
||||||
.encode = infrared_common_encode_pdwm,
|
|
||||||
.interpret = infrared_decoder_kaseikyo_interpret,
|
|
||||||
.decode_repeat = NULL,
|
|
||||||
.encode_repeat = NULL,
|
|
||||||
};
|
|
@ -1,13 +1,16 @@
|
|||||||
#include "infrared.h"
|
#include "infrared.h"
|
||||||
#include <core/check.h>
|
|
||||||
#include "common/infrared_common_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <furi.h>
|
#include <string.h>
|
||||||
#include "infrared_i.h"
|
#include <core/check.h>
|
||||||
#include <furi_hal_infrared.h>
|
#include <core/common_defines.h>
|
||||||
|
|
||||||
|
#include "nec/infrared_protocol_nec.h"
|
||||||
|
#include "samsung/infrared_protocol_samsung.h"
|
||||||
|
#include "rc5/infrared_protocol_rc5.h"
|
||||||
|
#include "rc6/infrared_protocol_rc6.h"
|
||||||
|
#include "sirc/infrared_protocol_sirc.h"
|
||||||
|
#include "kaseikyo/infrared_protocol_kaseikyo.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
InfraredAlloc alloc;
|
InfraredAlloc alloc;
|
||||||
@ -36,7 +39,7 @@ struct InfraredEncoderHandler {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
InfraredEncoders encoder;
|
InfraredEncoders encoder;
|
||||||
InfraredDecoders decoder;
|
InfraredDecoders decoder;
|
||||||
InfraredGetProtocolSpec get_protocol_spec;
|
InfraredGetProtocolVariant get_protocol_variant;
|
||||||
} InfraredEncoderDecoder;
|
} InfraredEncoderDecoder;
|
||||||
|
|
||||||
static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
||||||
@ -52,7 +55,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
|||||||
.encode = infrared_encoder_nec_encode,
|
.encode = infrared_encoder_nec_encode,
|
||||||
.reset = infrared_encoder_nec_reset,
|
.reset = infrared_encoder_nec_reset,
|
||||||
.free = infrared_encoder_nec_free},
|
.free = infrared_encoder_nec_free},
|
||||||
.get_protocol_spec = infrared_nec_get_spec,
|
.get_protocol_variant = infrared_protocol_nec_get_variant,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.decoder =
|
.decoder =
|
||||||
@ -66,7 +69,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
|||||||
.encode = infrared_encoder_samsung32_encode,
|
.encode = infrared_encoder_samsung32_encode,
|
||||||
.reset = infrared_encoder_samsung32_reset,
|
.reset = infrared_encoder_samsung32_reset,
|
||||||
.free = infrared_encoder_samsung32_free},
|
.free = infrared_encoder_samsung32_free},
|
||||||
.get_protocol_spec = infrared_samsung32_get_spec,
|
.get_protocol_variant = infrared_protocol_samsung32_get_variant,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.decoder =
|
.decoder =
|
||||||
@ -80,7 +83,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
|||||||
.encode = infrared_encoder_rc5_encode,
|
.encode = infrared_encoder_rc5_encode,
|
||||||
.reset = infrared_encoder_rc5_reset,
|
.reset = infrared_encoder_rc5_reset,
|
||||||
.free = infrared_encoder_rc5_free},
|
.free = infrared_encoder_rc5_free},
|
||||||
.get_protocol_spec = infrared_rc5_get_spec,
|
.get_protocol_variant = infrared_protocol_rc5_get_variant,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.decoder =
|
.decoder =
|
||||||
@ -94,7 +97,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
|||||||
.encode = infrared_encoder_rc6_encode,
|
.encode = infrared_encoder_rc6_encode,
|
||||||
.reset = infrared_encoder_rc6_reset,
|
.reset = infrared_encoder_rc6_reset,
|
||||||
.free = infrared_encoder_rc6_free},
|
.free = infrared_encoder_rc6_free},
|
||||||
.get_protocol_spec = infrared_rc6_get_spec,
|
.get_protocol_variant = infrared_protocol_rc6_get_variant,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.decoder =
|
.decoder =
|
||||||
@ -108,7 +111,7 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
|||||||
.encode = infrared_encoder_sirc_encode,
|
.encode = infrared_encoder_sirc_encode,
|
||||||
.reset = infrared_encoder_sirc_reset,
|
.reset = infrared_encoder_sirc_reset,
|
||||||
.free = infrared_encoder_sirc_free},
|
.free = infrared_encoder_sirc_free},
|
||||||
.get_protocol_spec = infrared_sirc_get_spec,
|
.get_protocol_variant = infrared_protocol_sirc_get_variant,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.decoder =
|
.decoder =
|
||||||
@ -122,13 +125,12 @@ static const InfraredEncoderDecoder infrared_encoder_decoder[] = {
|
|||||||
.encode = infrared_encoder_kaseikyo_encode,
|
.encode = infrared_encoder_kaseikyo_encode,
|
||||||
.reset = infrared_encoder_kaseikyo_reset,
|
.reset = infrared_encoder_kaseikyo_reset,
|
||||||
.free = infrared_encoder_kaseikyo_free},
|
.free = infrared_encoder_kaseikyo_free},
|
||||||
.get_protocol_spec = infrared_kaseikyo_get_spec,
|
.get_protocol_variant = infrared_protocol_kaseikyo_get_variant,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
static int infrared_find_index_by_protocol(InfraredProtocol protocol);
|
static int infrared_find_index_by_protocol(InfraredProtocol protocol);
|
||||||
static const InfraredProtocolSpecification*
|
static const InfraredProtocolVariant* infrared_get_variant_by_protocol(InfraredProtocol protocol);
|
||||||
infrared_get_spec_by_protocol(InfraredProtocol protocol);
|
|
||||||
|
|
||||||
const InfraredMessage*
|
const InfraredMessage*
|
||||||
infrared_decode(InfraredDecoderHandler* handler, bool level, uint32_t duration) {
|
infrared_decode(InfraredDecoderHandler* handler, bool level, uint32_t duration) {
|
||||||
@ -224,7 +226,7 @@ void infrared_free_encoder(InfraredEncoderHandler* handler) {
|
|||||||
|
|
||||||
static int infrared_find_index_by_protocol(InfraredProtocol protocol) {
|
static int infrared_find_index_by_protocol(InfraredProtocol protocol) {
|
||||||
for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) {
|
for(size_t i = 0; i < COUNT_OF(infrared_encoder_decoder); ++i) {
|
||||||
if(infrared_encoder_decoder[i].get_protocol_spec(protocol)) {
|
if(infrared_encoder_decoder[i].get_protocol_variant(protocol)) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,34 +284,37 @@ InfraredProtocol infrared_get_protocol_by_name(const char* protocol_name) {
|
|||||||
return InfraredProtocolUnknown;
|
return InfraredProtocolUnknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const InfraredProtocolSpecification*
|
static const InfraredProtocolVariant* infrared_get_variant_by_protocol(InfraredProtocol protocol) {
|
||||||
infrared_get_spec_by_protocol(InfraredProtocol protocol) {
|
|
||||||
int index = infrared_find_index_by_protocol(protocol);
|
int index = infrared_find_index_by_protocol(protocol);
|
||||||
const InfraredProtocolSpecification* spec = NULL;
|
const InfraredProtocolVariant* variant = NULL;
|
||||||
if(index >= 0) {
|
if(index >= 0) {
|
||||||
spec = infrared_encoder_decoder[index].get_protocol_spec(protocol);
|
variant = infrared_encoder_decoder[index].get_protocol_variant(protocol);
|
||||||
}
|
}
|
||||||
|
|
||||||
furi_assert(spec);
|
furi_assert(variant);
|
||||||
return spec;
|
return variant;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* infrared_get_protocol_name(InfraredProtocol protocol) {
|
const char* infrared_get_protocol_name(InfraredProtocol protocol) {
|
||||||
return infrared_get_spec_by_protocol(protocol)->name;
|
return infrared_get_variant_by_protocol(protocol)->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t infrared_get_protocol_address_length(InfraredProtocol protocol) {
|
uint8_t infrared_get_protocol_address_length(InfraredProtocol protocol) {
|
||||||
return infrared_get_spec_by_protocol(protocol)->address_length;
|
return infrared_get_variant_by_protocol(protocol)->address_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t infrared_get_protocol_command_length(InfraredProtocol protocol) {
|
uint8_t infrared_get_protocol_command_length(InfraredProtocol protocol) {
|
||||||
return infrared_get_spec_by_protocol(protocol)->command_length;
|
return infrared_get_variant_by_protocol(protocol)->command_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t infrared_get_protocol_frequency(InfraredProtocol protocol) {
|
uint32_t infrared_get_protocol_frequency(InfraredProtocol protocol) {
|
||||||
return infrared_get_spec_by_protocol(protocol)->frequency;
|
return infrared_get_variant_by_protocol(protocol)->frequency;
|
||||||
}
|
}
|
||||||
|
|
||||||
float infrared_get_protocol_duty_cycle(InfraredProtocol protocol) {
|
float infrared_get_protocol_duty_cycle(InfraredProtocol protocol) {
|
||||||
return infrared_get_spec_by_protocol(protocol)->duty_cycle;
|
return infrared_get_variant_by_protocol(protocol)->duty_cycle;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t infrared_get_protocol_min_repeat_count(InfraredProtocol protocol) {
|
||||||
|
return infrared_get_variant_by_protocol(protocol)->repeat_count;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -201,6 +202,15 @@ uint32_t infrared_get_protocol_frequency(InfraredProtocol protocol);
|
|||||||
*/
|
*/
|
||||||
float infrared_get_protocol_duty_cycle(InfraredProtocol protocol);
|
float infrared_get_protocol_duty_cycle(InfraredProtocol protocol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the minimum count of signal repeats for the selected protocol
|
||||||
|
*
|
||||||
|
* \param[in] protocol - protocol to get the repeat count from
|
||||||
|
*
|
||||||
|
* \return repeat count
|
||||||
|
*/
|
||||||
|
size_t infrared_get_protocol_min_repeat_count(InfraredProtocol protocol);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -22,9 +22,10 @@ typedef struct {
|
|||||||
uint8_t command_length;
|
uint8_t command_length;
|
||||||
uint32_t frequency;
|
uint32_t frequency;
|
||||||
float duty_cycle;
|
float duty_cycle;
|
||||||
} InfraredProtocolSpecification;
|
size_t repeat_count;
|
||||||
|
} InfraredProtocolVariant;
|
||||||
|
|
||||||
typedef const InfraredProtocolSpecification* (*InfraredGetProtocolSpec)(InfraredProtocol protocol);
|
typedef const InfraredProtocolVariant* (*InfraredGetProtocolVariant)(InfraredProtocol protocol);
|
||||||
|
|
||||||
typedef void* (*InfraredAlloc)(void);
|
typedef void* (*InfraredAlloc)(void);
|
||||||
typedef void (*InfraredFree)(void*);
|
typedef void (*InfraredFree)(void*);
|
||||||
|
@ -1,320 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "infrared.h"
|
|
||||||
#include "common/infrared_common_i.h"
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* NEC protocol description
|
|
||||||
* https://radioparty.ru/manuals/encyclopedia/213-ircontrol?start=1
|
|
||||||
****************************************************************************************************
|
|
||||||
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Stop
|
|
||||||
* mark space Modulation up to period repeat repeat bit
|
|
||||||
* mark space
|
|
||||||
*
|
|
||||||
* 9000 4500 32 bit + stop bit ...110000 9000 2250
|
|
||||||
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________ _
|
|
||||||
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ____________ ___
|
|
||||||
*
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#define INFRARED_NEC_PREAMBLE_MARK 9000
|
|
||||||
#define INFRARED_NEC_PREAMBLE_SPACE 4500
|
|
||||||
#define INFRARED_NEC_BIT1_MARK 560
|
|
||||||
#define INFRARED_NEC_BIT1_SPACE 1690
|
|
||||||
#define INFRARED_NEC_BIT0_MARK 560
|
|
||||||
#define INFRARED_NEC_BIT0_SPACE 560
|
|
||||||
#define INFRARED_NEC_REPEAT_PERIOD 110000
|
|
||||||
#define INFRARED_NEC_SILENCE INFRARED_NEC_REPEAT_PERIOD
|
|
||||||
#define INFRARED_NEC_MIN_SPLIT_TIME INFRARED_NEC_REPEAT_PAUSE_MIN
|
|
||||||
#define INFRARED_NEC_REPEAT_PAUSE_MIN 4000
|
|
||||||
#define INFRARED_NEC_REPEAT_PAUSE_MAX 150000
|
|
||||||
#define INFRARED_NEC_REPEAT_MARK 9000
|
|
||||||
#define INFRARED_NEC_REPEAT_SPACE 2250
|
|
||||||
#define INFRARED_NEC_PREAMBLE_TOLERANCE 200 // us
|
|
||||||
#define INFRARED_NEC_BIT_TOLERANCE 120 // us
|
|
||||||
|
|
||||||
void* infrared_decoder_nec_alloc(void);
|
|
||||||
void infrared_decoder_nec_reset(void* decoder);
|
|
||||||
void infrared_decoder_nec_free(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_nec_check_ready(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration);
|
|
||||||
void* infrared_encoder_nec_alloc(void);
|
|
||||||
InfraredStatus infrared_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
|
||||||
void infrared_encoder_nec_reset(void* encoder_ptr, const InfraredMessage* message);
|
|
||||||
void infrared_encoder_nec_free(void* encoder_ptr);
|
|
||||||
bool infrared_decoder_nec_interpret(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_decoder_nec_decode_repeat(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_encoder_nec_encode_repeat(
|
|
||||||
InfraredCommonEncoder* encoder,
|
|
||||||
uint32_t* duration,
|
|
||||||
bool* level);
|
|
||||||
const InfraredProtocolSpecification* infrared_nec_get_spec(InfraredProtocol protocol);
|
|
||||||
|
|
||||||
extern const InfraredCommonProtocolSpec protocol_nec;
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* SAMSUNG32 protocol description
|
|
||||||
* https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG
|
|
||||||
****************************************************************************************************
|
|
||||||
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Bit1 Stop
|
|
||||||
* mark space Modulation repeat repeat bit
|
|
||||||
* mark space
|
|
||||||
*
|
|
||||||
* 4500 4500 32 bit + stop bit 40000/100000 4500 4500
|
|
||||||
* __________ _ _ _ _ _ _ _ _ _ _ _ ___________ _ _
|
|
||||||
* _ __________ __ _ __ __ __ _ _ __ __ _ ________________ ____________ ____ ___
|
|
||||||
*
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#define INFRARED_SAMSUNG_PREAMBLE_MARK 4500
|
|
||||||
#define INFRARED_SAMSUNG_PREAMBLE_SPACE 4500
|
|
||||||
#define INFRARED_SAMSUNG_BIT1_MARK 550
|
|
||||||
#define INFRARED_SAMSUNG_BIT1_SPACE 1650
|
|
||||||
#define INFRARED_SAMSUNG_BIT0_MARK 550
|
|
||||||
#define INFRARED_SAMSUNG_BIT0_SPACE 550
|
|
||||||
#define INFRARED_SAMSUNG_REPEAT_PAUSE_MIN 30000
|
|
||||||
#define INFRARED_SAMSUNG_REPEAT_PAUSE1 46000
|
|
||||||
#define INFRARED_SAMSUNG_REPEAT_PAUSE2 97000
|
|
||||||
/* Samsung silence have to be greater than REPEAT MAX
|
|
||||||
* otherwise there can be problems during unit tests parsing
|
|
||||||
* of some data. Real tolerances we don't know, but in real life
|
|
||||||
* silence time should be greater than max repeat time. This is
|
|
||||||
* because of similar preambule timings for repeat and first messages. */
|
|
||||||
#define INFRARED_SAMSUNG_MIN_SPLIT_TIME 5000
|
|
||||||
#define INFRARED_SAMSUNG_SILENCE 145000
|
|
||||||
#define INFRARED_SAMSUNG_REPEAT_PAUSE_MAX 140000
|
|
||||||
#define INFRARED_SAMSUNG_REPEAT_MARK 4500
|
|
||||||
#define INFRARED_SAMSUNG_REPEAT_SPACE 4500
|
|
||||||
#define INFRARED_SAMSUNG_PREAMBLE_TOLERANCE 200 // us
|
|
||||||
#define INFRARED_SAMSUNG_BIT_TOLERANCE 120 // us
|
|
||||||
|
|
||||||
void* infrared_decoder_samsung32_alloc(void);
|
|
||||||
void infrared_decoder_samsung32_reset(void* decoder);
|
|
||||||
void infrared_decoder_samsung32_free(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx);
|
|
||||||
InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
|
|
||||||
InfraredStatus
|
|
||||||
infrared_encoder_samsung32_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
|
||||||
void infrared_encoder_samsung32_reset(void* encoder_ptr, const InfraredMessage* message);
|
|
||||||
void* infrared_encoder_samsung32_alloc(void);
|
|
||||||
void infrared_encoder_samsung32_free(void* encoder_ptr);
|
|
||||||
bool infrared_decoder_samsung32_interpret(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_decoder_samsung32_decode_repeat(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_encoder_samsung32_encode_repeat(
|
|
||||||
InfraredCommonEncoder* encoder,
|
|
||||||
uint32_t* duration,
|
|
||||||
bool* level);
|
|
||||||
const InfraredProtocolSpecification* infrared_samsung32_get_spec(InfraredProtocol protocol);
|
|
||||||
|
|
||||||
extern const InfraredCommonProtocolSpec protocol_samsung32;
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* RC6 protocol description
|
|
||||||
* https://www.mikrocontroller.net/articles/IRMP_-_english#RC6_.2B_RC6A
|
|
||||||
****************************************************************************************************
|
|
||||||
* Preamble Manchester/biphase Silence
|
|
||||||
* mark/space Modulation
|
|
||||||
*
|
|
||||||
* 2666 889 444/888 - bit (x2 for toggle bit) 2666
|
|
||||||
*
|
|
||||||
* ________ __ __ __ __ ____ __ __ __ __ __ __ __ __
|
|
||||||
* _ _________ ____ __ __ ____ __ __ __ __ __ __ __ __ _______________
|
|
||||||
* | 1 | 0 | 0 | 0 | 0 | ... | ... | |
|
|
||||||
* s m2 m1 m0 T address (MSB) command (MSB)
|
|
||||||
*
|
|
||||||
* s - start bit (always 1)
|
|
||||||
* m0-2 - mode (000 for RC6)
|
|
||||||
* T - toggle bit, twice longer
|
|
||||||
* address - 8 bit
|
|
||||||
* command - 8 bit
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#define INFRARED_RC6_CARRIER_FREQUENCY 36000
|
|
||||||
#define INFRARED_RC6_DUTY_CYCLE 0.33
|
|
||||||
|
|
||||||
#define INFRARED_RC6_PREAMBLE_MARK 2666
|
|
||||||
#define INFRARED_RC6_PREAMBLE_SPACE 889
|
|
||||||
#define INFRARED_RC6_BIT 444 // half of time-quant for 1 bit
|
|
||||||
#define INFRARED_RC6_PREAMBLE_TOLERANCE 200 // us
|
|
||||||
#define INFRARED_RC6_BIT_TOLERANCE 120 // us
|
|
||||||
/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
|
|
||||||
#define INFRARED_RC6_SILENCE (2700 * 10)
|
|
||||||
#define INFRARED_RC6_MIN_SPLIT_TIME 2700
|
|
||||||
|
|
||||||
void* infrared_decoder_rc6_alloc(void);
|
|
||||||
void infrared_decoder_rc6_reset(void* decoder);
|
|
||||||
void infrared_decoder_rc6_free(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_rc6_check_ready(void* ctx);
|
|
||||||
InfraredMessage* infrared_decoder_rc6_decode(void* decoder, bool level, uint32_t duration);
|
|
||||||
void* infrared_encoder_rc6_alloc(void);
|
|
||||||
void infrared_encoder_rc6_reset(void* encoder_ptr, const InfraredMessage* message);
|
|
||||||
void infrared_encoder_rc6_free(void* decoder);
|
|
||||||
InfraredStatus infrared_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
|
|
||||||
bool infrared_decoder_rc6_interpret(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_decoder_rc6_decode_manchester(
|
|
||||||
InfraredCommonDecoder* decoder,
|
|
||||||
bool level,
|
|
||||||
uint32_t timing);
|
|
||||||
InfraredStatus infrared_encoder_rc6_encode_manchester(
|
|
||||||
InfraredCommonEncoder* encoder_ptr,
|
|
||||||
uint32_t* duration,
|
|
||||||
bool* polarity);
|
|
||||||
const InfraredProtocolSpecification* infrared_rc6_get_spec(InfraredProtocol protocol);
|
|
||||||
|
|
||||||
extern const InfraredCommonProtocolSpec protocol_rc6;
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* RC5 protocol description
|
|
||||||
* https://www.mikrocontroller.net/articles/IRMP_-_english#RC5_.2B_RC5X
|
|
||||||
****************************************************************************************************
|
|
||||||
* Manchester/biphase
|
|
||||||
* Modulation
|
|
||||||
*
|
|
||||||
* 888/1776 - bit (x2 for toggle bit)
|
|
||||||
*
|
|
||||||
* __ ____ __ __ __ __ __ __ __ __
|
|
||||||
* __ __ ____ __ __ __ __ __ __ __ _
|
|
||||||
* | 1 | 1 | 0 | ... | ... |
|
|
||||||
* s si T address (MSB) command (MSB)
|
|
||||||
*
|
|
||||||
* Note: manchester starts from space timing, so it have to be handled properly
|
|
||||||
* s - start bit (always 1)
|
|
||||||
* si - RC5: start bit (always 1), RC5X - 7-th bit of address (in our case always 0)
|
|
||||||
* T - toggle bit, change it's value every button press
|
|
||||||
* address - 5 bit
|
|
||||||
* command - 6/7 bit
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#define INFRARED_RC5_CARRIER_FREQUENCY 36000
|
|
||||||
#define INFRARED_RC5_DUTY_CYCLE 0.33
|
|
||||||
|
|
||||||
#define INFRARED_RC5_PREAMBLE_MARK 0
|
|
||||||
#define INFRARED_RC5_PREAMBLE_SPACE 0
|
|
||||||
#define INFRARED_RC5_BIT 888 // half of time-quant for 1 bit
|
|
||||||
#define INFRARED_RC5_PREAMBLE_TOLERANCE 200 // us
|
|
||||||
#define INFRARED_RC5_BIT_TOLERANCE 120 // us
|
|
||||||
/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
|
|
||||||
#define INFRARED_RC5_SILENCE (2700 * 10)
|
|
||||||
#define INFRARED_RC5_MIN_SPLIT_TIME 2700
|
|
||||||
|
|
||||||
void* infrared_decoder_rc5_alloc(void);
|
|
||||||
void infrared_decoder_rc5_reset(void* decoder);
|
|
||||||
void infrared_decoder_rc5_free(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_rc5_check_ready(void* ctx);
|
|
||||||
InfraredMessage* infrared_decoder_rc5_decode(void* decoder, bool level, uint32_t duration);
|
|
||||||
void* infrared_encoder_rc5_alloc(void);
|
|
||||||
void infrared_encoder_rc5_reset(void* encoder_ptr, const InfraredMessage* message);
|
|
||||||
void infrared_encoder_rc5_free(void* decoder);
|
|
||||||
InfraredStatus infrared_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
|
|
||||||
bool infrared_decoder_rc5_interpret(InfraredCommonDecoder* decoder);
|
|
||||||
const InfraredProtocolSpecification* infrared_rc5_get_spec(InfraredProtocol protocol);
|
|
||||||
|
|
||||||
extern const InfraredCommonProtocolSpec protocol_rc5;
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* Sony SIRC protocol description
|
|
||||||
* https://www.sbprojects.net/knowledge/ir/sirc.php
|
|
||||||
* http://picprojects.org.uk/
|
|
||||||
****************************************************************************************************
|
|
||||||
* Preamble Preamble Pulse Width Modulation Pause Entirely repeat
|
|
||||||
* mark space up to period message..
|
|
||||||
*
|
|
||||||
* 2400 600 12/15/20 bits (600,1200) ...45000 2400 600
|
|
||||||
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ __________ _ _
|
|
||||||
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ____________________ __________ _
|
|
||||||
* | command | address |
|
|
||||||
* SIRC | 7b LSB | 5b LSB |
|
|
||||||
* SIRC15 | 7b LSB | 8b LSB |
|
|
||||||
* SIRC20 | 7b LSB | 13b LSB |
|
|
||||||
*
|
|
||||||
* No way to determine either next message is repeat or not,
|
|
||||||
* so recognize only fact message received. Sony remotes always send at least 3 messages.
|
|
||||||
* Assume 8 last extended bits for SIRC20 are address bits.
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#define INFRARED_SIRC_CARRIER_FREQUENCY 40000
|
|
||||||
#define INFRARED_SIRC_DUTY_CYCLE 0.33
|
|
||||||
#define INFRARED_SIRC_PREAMBLE_MARK 2400
|
|
||||||
#define INFRARED_SIRC_PREAMBLE_SPACE 600
|
|
||||||
#define INFRARED_SIRC_BIT1_MARK 1200
|
|
||||||
#define INFRARED_SIRC_BIT1_SPACE 600
|
|
||||||
#define INFRARED_SIRC_BIT0_MARK 600
|
|
||||||
#define INFRARED_SIRC_BIT0_SPACE 600
|
|
||||||
#define INFRARED_SIRC_PREAMBLE_TOLERANCE 200 // us
|
|
||||||
#define INFRARED_SIRC_BIT_TOLERANCE 120 // us
|
|
||||||
#define INFRARED_SIRC_SILENCE 10000
|
|
||||||
#define INFRARED_SIRC_MIN_SPLIT_TIME (INFRARED_SIRC_SILENCE - 1000)
|
|
||||||
#define INFRARED_SIRC_REPEAT_PERIOD 45000
|
|
||||||
|
|
||||||
void* infrared_decoder_sirc_alloc(void);
|
|
||||||
void infrared_decoder_sirc_reset(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_sirc_check_ready(void* decoder);
|
|
||||||
uint32_t infrared_decoder_sirc_get_timeout(void* decoder);
|
|
||||||
void infrared_decoder_sirc_free(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration);
|
|
||||||
void* infrared_encoder_sirc_alloc(void);
|
|
||||||
void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message);
|
|
||||||
void infrared_encoder_sirc_free(void* decoder);
|
|
||||||
InfraredStatus infrared_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
|
|
||||||
bool infrared_decoder_sirc_interpret(InfraredCommonDecoder* decoder);
|
|
||||||
const InfraredProtocolSpecification* infrared_sirc_get_spec(InfraredProtocol protocol);
|
|
||||||
InfraredStatus infrared_encoder_sirc_encode_repeat(
|
|
||||||
InfraredCommonEncoder* encoder,
|
|
||||||
uint32_t* duration,
|
|
||||||
bool* level);
|
|
||||||
|
|
||||||
extern const InfraredCommonProtocolSpec protocol_sirc;
|
|
||||||
|
|
||||||
/***************************************************************************************************
|
|
||||||
* Kaseikyo protocol description
|
|
||||||
* https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_Kaseikyo.hpp
|
|
||||||
****************************************************************************************************
|
|
||||||
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble
|
|
||||||
* mark space Modulation up to period repeat repeat
|
|
||||||
* mark space
|
|
||||||
*
|
|
||||||
* 3360 1665 48 bit ...130000 3456 1728
|
|
||||||
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________
|
|
||||||
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ___________
|
|
||||||
*
|
|
||||||
***************************************************************************************************/
|
|
||||||
|
|
||||||
#define INFRARED_KASEIKYO_UNIT 432
|
|
||||||
#define INFRARED_KASEIKYO_PREAMBLE_MARK (8 * INFRARED_KASEIKYO_UNIT)
|
|
||||||
#define INFRARED_KASEIKYO_PREAMBLE_SPACE (4 * INFRARED_KASEIKYO_UNIT)
|
|
||||||
#define INFRARED_KASEIKYO_BIT1_MARK INFRARED_KASEIKYO_UNIT
|
|
||||||
#define INFRARED_KASEIKYO_BIT1_SPACE (3 * INFRARED_KASEIKYO_UNIT)
|
|
||||||
#define INFRARED_KASEIKYO_BIT0_MARK INFRARED_KASEIKYO_UNIT
|
|
||||||
#define INFRARED_KASEIKYO_BIT0_SPACE INFRARED_KASEIKYO_UNIT
|
|
||||||
#define INFRARED_KASEIKYO_REPEAT_PERIOD 130000
|
|
||||||
#define INFRARED_KASEIKYO_SILENCE INFRARED_KASEIKYO_REPEAT_PERIOD
|
|
||||||
#define INFRARED_KASEIKYO_MIN_SPLIT_TIME INFRARED_KASEIKYO_REPEAT_PAUSE_MIN
|
|
||||||
#define INFRARED_KASEIKYO_REPEAT_PAUSE_MIN 4000
|
|
||||||
#define INFRARED_KASEIKYO_REPEAT_PAUSE_MAX 150000
|
|
||||||
#define INFRARED_KASEIKYO_REPEAT_MARK INFRARED_KASEIKYO_PREAMBLE_MARK
|
|
||||||
#define INFRARED_KASEIKYO_REPEAT_SPACE (INFRARED_KASEIKYO_REPEAT_PERIOD - 56000)
|
|
||||||
#define INFRARED_KASEIKYO_PREAMBLE_TOLERANCE 200 // us
|
|
||||||
#define INFRARED_KASEIKYO_BIT_TOLERANCE 120 // us
|
|
||||||
|
|
||||||
void* infrared_decoder_kaseikyo_alloc(void);
|
|
||||||
void infrared_decoder_kaseikyo_reset(void* decoder);
|
|
||||||
void infrared_decoder_kaseikyo_free(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* decoder);
|
|
||||||
InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration);
|
|
||||||
void* infrared_encoder_kaseikyo_alloc(void);
|
|
||||||
InfraredStatus
|
|
||||||
infrared_encoder_kaseikyo_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
|
||||||
void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message);
|
|
||||||
void infrared_encoder_kaseikyo_free(void* encoder_ptr);
|
|
||||||
bool infrared_decoder_kaseikyo_interpret(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_decoder_kaseikyo_decode_repeat(InfraredCommonDecoder* decoder);
|
|
||||||
InfraredStatus infrared_encoder_kaseikyo_encode_repeat(
|
|
||||||
InfraredCommonEncoder* encoder,
|
|
||||||
uint32_t* duration,
|
|
||||||
bool* level);
|
|
||||||
const InfraredProtocolSpecification* infrared_kaseikyo_get_spec(InfraredProtocol protocol);
|
|
||||||
|
|
||||||
extern const InfraredCommonProtocolSpec protocol_kaseikyo;
|
|
@ -1,9 +1,5 @@
|
|||||||
#include "infrared.h"
|
#include "infrared_protocol_kaseikyo_i.h"
|
||||||
#include "infrared_protocol_defs_i.h"
|
#include <core/check.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <furi.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* ctx) {
|
InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* ctx) {
|
||||||
return infrared_common_decoder_check_ready(ctx);
|
return infrared_common_decoder_check_ready(ctx);
|
||||||
@ -38,7 +34,7 @@ bool infrared_decoder_kaseikyo_interpret(InfraredCommonDecoder* decoder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_decoder_kaseikyo_alloc(void) {
|
void* infrared_decoder_kaseikyo_alloc(void) {
|
||||||
return infrared_common_decoder_alloc(&protocol_kaseikyo);
|
return infrared_common_decoder_alloc(&infrared_protocol_kaseikyo);
|
||||||
}
|
}
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration) {
|
InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration) {
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
|
#include "infrared_protocol_kaseikyo_i.h"
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
#include "common/infrared_common_i.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <furi.h>
|
|
||||||
|
|
||||||
void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message) {
|
void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message) {
|
||||||
furi_assert(encoder_ptr);
|
furi_assert(encoder_ptr);
|
||||||
@ -32,7 +28,7 @@ void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* m
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_encoder_kaseikyo_alloc(void) {
|
void* infrared_encoder_kaseikyo_alloc(void) {
|
||||||
return infrared_common_encoder_alloc(&protocol_kaseikyo);
|
return infrared_common_encoder_alloc(&infrared_protocol_kaseikyo);
|
||||||
}
|
}
|
||||||
|
|
||||||
void infrared_encoder_kaseikyo_free(void* encoder_ptr) {
|
void infrared_encoder_kaseikyo_free(void* encoder_ptr) {
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_kaseikyo_protocol_specification = {
|
|
||||||
.name = "Kaseikyo",
|
|
||||||
.address_length = 26,
|
|
||||||
.command_length = 10,
|
|
||||||
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredProtocolSpecification* infrared_kaseikyo_get_spec(InfraredProtocol protocol) {
|
|
||||||
if(protocol == InfraredProtocolKaseikyo)
|
|
||||||
return &infrared_kaseikyo_protocol_specification;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -0,0 +1,40 @@
|
|||||||
|
#include "infrared_protocol_kaseikyo_i.h"
|
||||||
|
|
||||||
|
const InfraredCommonProtocolSpec infrared_protocol_kaseikyo = {
|
||||||
|
.timings =
|
||||||
|
{
|
||||||
|
.preamble_mark = INFRARED_KASEIKYO_PREAMBLE_MARK,
|
||||||
|
.preamble_space = INFRARED_KASEIKYO_PREAMBLE_SPACE,
|
||||||
|
.bit1_mark = INFRARED_KASEIKYO_BIT1_MARK,
|
||||||
|
.bit1_space = INFRARED_KASEIKYO_BIT1_SPACE,
|
||||||
|
.bit0_mark = INFRARED_KASEIKYO_BIT0_MARK,
|
||||||
|
.bit0_space = INFRARED_KASEIKYO_BIT0_SPACE,
|
||||||
|
.preamble_tolerance = INFRARED_KASEIKYO_PREAMBLE_TOLERANCE,
|
||||||
|
.bit_tolerance = INFRARED_KASEIKYO_BIT_TOLERANCE,
|
||||||
|
.silence_time = INFRARED_KASEIKYO_SILENCE,
|
||||||
|
.min_split_time = INFRARED_KASEIKYO_MIN_SPLIT_TIME,
|
||||||
|
},
|
||||||
|
.databit_len[0] = 48,
|
||||||
|
.no_stop_bit = false,
|
||||||
|
.decode = infrared_common_decode_pdwm,
|
||||||
|
.encode = infrared_common_encode_pdwm,
|
||||||
|
.interpret = infrared_decoder_kaseikyo_interpret,
|
||||||
|
.decode_repeat = NULL,
|
||||||
|
.encode_repeat = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_kaseikyo = {
|
||||||
|
.name = "Kaseikyo",
|
||||||
|
.address_length = 26,
|
||||||
|
.command_length = 10,
|
||||||
|
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_KASEIKYO_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_kaseikyo_get_variant(InfraredProtocol protocol) {
|
||||||
|
if(protocol == InfraredProtocolKaseikyo)
|
||||||
|
return &infrared_protocol_variant_kaseikyo;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Kaseikyo protocol description
|
||||||
|
* https://github.com/Arduino-IRremote/Arduino-IRremote/blob/master/src/ir_Kaseikyo.hpp
|
||||||
|
****************************************************************************************************
|
||||||
|
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble
|
||||||
|
* mark space Modulation up to period repeat repeat
|
||||||
|
* mark space
|
||||||
|
*
|
||||||
|
* 3360 1665 48 bit ...130000 3456 1728
|
||||||
|
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________
|
||||||
|
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ___________
|
||||||
|
*
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
void* infrared_decoder_kaseikyo_alloc(void);
|
||||||
|
void infrared_decoder_kaseikyo_reset(void* decoder);
|
||||||
|
void infrared_decoder_kaseikyo_free(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_kaseikyo_check_ready(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_kaseikyo_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
void* infrared_encoder_kaseikyo_alloc(void);
|
||||||
|
InfraredStatus
|
||||||
|
infrared_encoder_kaseikyo_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
||||||
|
void infrared_encoder_kaseikyo_reset(void* encoder_ptr, const InfraredMessage* message);
|
||||||
|
void infrared_encoder_kaseikyo_free(void* encoder_ptr);
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_kaseikyo_get_variant(InfraredProtocol protocol);
|
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common/infrared_common_i.h"
|
||||||
|
|
||||||
|
#define INFRARED_KASEIKYO_UNIT 432
|
||||||
|
#define INFRARED_KASEIKYO_PREAMBLE_MARK (8 * INFRARED_KASEIKYO_UNIT)
|
||||||
|
#define INFRARED_KASEIKYO_PREAMBLE_SPACE (4 * INFRARED_KASEIKYO_UNIT)
|
||||||
|
#define INFRARED_KASEIKYO_BIT1_MARK INFRARED_KASEIKYO_UNIT
|
||||||
|
#define INFRARED_KASEIKYO_BIT1_SPACE (3 * INFRARED_KASEIKYO_UNIT)
|
||||||
|
#define INFRARED_KASEIKYO_BIT0_MARK INFRARED_KASEIKYO_UNIT
|
||||||
|
#define INFRARED_KASEIKYO_BIT0_SPACE INFRARED_KASEIKYO_UNIT
|
||||||
|
#define INFRARED_KASEIKYO_REPEAT_PERIOD 130000
|
||||||
|
#define INFRARED_KASEIKYO_SILENCE INFRARED_KASEIKYO_REPEAT_PERIOD
|
||||||
|
#define INFRARED_KASEIKYO_MIN_SPLIT_TIME INFRARED_KASEIKYO_REPEAT_PAUSE_MIN
|
||||||
|
#define INFRARED_KASEIKYO_REPEAT_PAUSE_MIN 4000
|
||||||
|
#define INFRARED_KASEIKYO_REPEAT_PAUSE_MAX 150000
|
||||||
|
#define INFRARED_KASEIKYO_REPEAT_COUNT_MIN 1
|
||||||
|
#define INFRARED_KASEIKYO_REPEAT_MARK INFRARED_KASEIKYO_PREAMBLE_MARK
|
||||||
|
#define INFRARED_KASEIKYO_REPEAT_SPACE (INFRARED_KASEIKYO_REPEAT_PERIOD - 56000)
|
||||||
|
#define INFRARED_KASEIKYO_PREAMBLE_TOLERANCE 200 // us
|
||||||
|
#define INFRARED_KASEIKYO_BIT_TOLERANCE 120 // us
|
||||||
|
|
||||||
|
extern const InfraredCommonProtocolSpec infrared_protocol_kaseikyo;
|
||||||
|
|
||||||
|
bool infrared_decoder_kaseikyo_interpret(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_decoder_kaseikyo_decode_repeat(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_encoder_kaseikyo_encode_repeat(
|
||||||
|
InfraredCommonEncoder* encoder,
|
||||||
|
uint32_t* duration,
|
||||||
|
bool* level);
|
@ -1,10 +1,5 @@
|
|||||||
#include "common/infrared_common_i.h"
|
#include "infrared_protocol_nec_i.h"
|
||||||
#include "infrared.h"
|
#include <core/check.h>
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <furi.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_nec_check_ready(void* ctx) {
|
InfraredMessage* infrared_decoder_nec_check_ready(void* ctx) {
|
||||||
return infrared_common_decoder_check_ready(ctx);
|
return infrared_common_decoder_check_ready(ctx);
|
||||||
@ -86,7 +81,7 @@ InfraredStatus infrared_decoder_nec_decode_repeat(InfraredCommonDecoder* decoder
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_decoder_nec_alloc(void) {
|
void* infrared_decoder_nec_alloc(void) {
|
||||||
return infrared_common_decoder_alloc(&protocol_nec);
|
return infrared_common_decoder_alloc(&infrared_protocol_nec);
|
||||||
}
|
}
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration) {
|
InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration) {
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
|
#include "infrared_protocol_nec_i.h"
|
||||||
|
|
||||||
|
#include <core/core_defines.h>
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
#include "infrared.h"
|
|
||||||
#include "common/infrared_common_i.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <furi.h>
|
|
||||||
|
|
||||||
static const uint32_t repeat_timings[] = {
|
static const uint32_t repeat_timings[] = {
|
||||||
INFRARED_NEC_REPEAT_PERIOD - INFRARED_NEC_REPEAT_MARK - INFRARED_NEC_REPEAT_SPACE -
|
INFRARED_NEC_REPEAT_PERIOD - INFRARED_NEC_REPEAT_MARK - INFRARED_NEC_REPEAT_SPACE -
|
||||||
@ -81,7 +78,7 @@ InfraredStatus infrared_encoder_nec_encode_repeat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_encoder_nec_alloc(void) {
|
void* infrared_encoder_nec_alloc(void) {
|
||||||
return infrared_common_encoder_alloc(&protocol_nec);
|
return infrared_common_encoder_alloc(&infrared_protocol_nec);
|
||||||
}
|
}
|
||||||
|
|
||||||
void infrared_encoder_nec_free(void* encoder_ptr) {
|
void infrared_encoder_nec_free(void* encoder_ptr) {
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_nec_protocol_specification = {
|
|
||||||
.name = "NEC",
|
|
||||||
.address_length = 8,
|
|
||||||
.command_length = 8,
|
|
||||||
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_necext_protocol_specification = {
|
|
||||||
.name = "NECext",
|
|
||||||
.address_length = 16,
|
|
||||||
.command_length = 16,
|
|
||||||
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_nec42_protocol_specification = {
|
|
||||||
.name = "NEC42",
|
|
||||||
.address_length = 13,
|
|
||||||
.command_length = 8,
|
|
||||||
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_nec42ext_protocol_specification = {
|
|
||||||
.name = "NEC42ext",
|
|
||||||
.address_length = 26,
|
|
||||||
.command_length = 16,
|
|
||||||
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredProtocolSpecification* infrared_nec_get_spec(InfraredProtocol protocol) {
|
|
||||||
if(protocol == InfraredProtocolNEC)
|
|
||||||
return &infrared_nec_protocol_specification;
|
|
||||||
else if(protocol == InfraredProtocolNECext)
|
|
||||||
return &infrared_necext_protocol_specification;
|
|
||||||
else if(protocol == InfraredProtocolNEC42)
|
|
||||||
return &infrared_nec42_protocol_specification;
|
|
||||||
else if(protocol == InfraredProtocolNEC42ext)
|
|
||||||
return &infrared_nec42ext_protocol_specification;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
74
lib/infrared/encoder_decoder/nec/infrared_protocol_nec.c
Normal file
74
lib/infrared/encoder_decoder/nec/infrared_protocol_nec.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "infrared_protocol_nec_i.h"
|
||||||
|
|
||||||
|
const InfraredCommonProtocolSpec infrared_protocol_nec = {
|
||||||
|
.timings =
|
||||||
|
{
|
||||||
|
.preamble_mark = INFRARED_NEC_PREAMBLE_MARK,
|
||||||
|
.preamble_space = INFRARED_NEC_PREAMBLE_SPACE,
|
||||||
|
.bit1_mark = INFRARED_NEC_BIT1_MARK,
|
||||||
|
.bit1_space = INFRARED_NEC_BIT1_SPACE,
|
||||||
|
.bit0_mark = INFRARED_NEC_BIT0_MARK,
|
||||||
|
.bit0_space = INFRARED_NEC_BIT0_SPACE,
|
||||||
|
.preamble_tolerance = INFRARED_NEC_PREAMBLE_TOLERANCE,
|
||||||
|
.bit_tolerance = INFRARED_NEC_BIT_TOLERANCE,
|
||||||
|
.silence_time = INFRARED_NEC_SILENCE,
|
||||||
|
.min_split_time = INFRARED_NEC_MIN_SPLIT_TIME,
|
||||||
|
},
|
||||||
|
.databit_len[0] = 42,
|
||||||
|
.databit_len[1] = 32,
|
||||||
|
.no_stop_bit = false,
|
||||||
|
.decode = infrared_common_decode_pdwm,
|
||||||
|
.encode = infrared_common_encode_pdwm,
|
||||||
|
.interpret = infrared_decoder_nec_interpret,
|
||||||
|
.decode_repeat = infrared_decoder_nec_decode_repeat,
|
||||||
|
.encode_repeat = infrared_encoder_nec_encode_repeat,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_nec = {
|
||||||
|
.name = "NEC",
|
||||||
|
.address_length = 8,
|
||||||
|
.command_length = 8,
|
||||||
|
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_necext = {
|
||||||
|
.name = "NECext",
|
||||||
|
.address_length = 16,
|
||||||
|
.command_length = 16,
|
||||||
|
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_nec42 = {
|
||||||
|
.name = "NEC42",
|
||||||
|
.address_length = 13,
|
||||||
|
.command_length = 8,
|
||||||
|
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_nec42ext = {
|
||||||
|
.name = "NEC42ext",
|
||||||
|
.address_length = 26,
|
||||||
|
.command_length = 16,
|
||||||
|
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_NEC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_nec_get_variant(InfraredProtocol protocol) {
|
||||||
|
if(protocol == InfraredProtocolNEC)
|
||||||
|
return &infrared_protocol_variant_nec;
|
||||||
|
else if(protocol == InfraredProtocolNECext)
|
||||||
|
return &infrared_protocol_variant_necext;
|
||||||
|
else if(protocol == InfraredProtocolNEC42)
|
||||||
|
return &infrared_protocol_variant_nec42;
|
||||||
|
else if(protocol == InfraredProtocolNEC42ext)
|
||||||
|
return &infrared_protocol_variant_nec42ext;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
30
lib/infrared/encoder_decoder/nec/infrared_protocol_nec.h
Normal file
30
lib/infrared/encoder_decoder/nec/infrared_protocol_nec.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* NEC protocol description
|
||||||
|
* https://radioparty.ru/manuals/encyclopedia/213-ircontrol?start=1
|
||||||
|
****************************************************************************************************
|
||||||
|
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Stop
|
||||||
|
* mark space Modulation up to period repeat repeat bit
|
||||||
|
* mark space
|
||||||
|
*
|
||||||
|
* 9000 4500 32 bit + stop bit ...110000 9000 2250
|
||||||
|
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________ _
|
||||||
|
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ________________ ____________ ___
|
||||||
|
*
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
void* infrared_decoder_nec_alloc(void);
|
||||||
|
void infrared_decoder_nec_reset(void* decoder);
|
||||||
|
void infrared_decoder_nec_free(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_nec_check_ready(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_nec_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
void* infrared_encoder_nec_alloc(void);
|
||||||
|
InfraredStatus infrared_encoder_nec_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
||||||
|
void infrared_encoder_nec_reset(void* encoder_ptr, const InfraredMessage* message);
|
||||||
|
void infrared_encoder_nec_free(void* encoder_ptr);
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_nec_get_variant(InfraredProtocol protocol);
|
29
lib/infrared/encoder_decoder/nec/infrared_protocol_nec_i.h
Normal file
29
lib/infrared/encoder_decoder/nec/infrared_protocol_nec_i.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common/infrared_common_i.h"
|
||||||
|
|
||||||
|
#define INFRARED_NEC_PREAMBLE_MARK 9000
|
||||||
|
#define INFRARED_NEC_PREAMBLE_SPACE 4500
|
||||||
|
#define INFRARED_NEC_BIT1_MARK 560
|
||||||
|
#define INFRARED_NEC_BIT1_SPACE 1690
|
||||||
|
#define INFRARED_NEC_BIT0_MARK 560
|
||||||
|
#define INFRARED_NEC_BIT0_SPACE 560
|
||||||
|
#define INFRARED_NEC_REPEAT_PERIOD 110000
|
||||||
|
#define INFRARED_NEC_SILENCE INFRARED_NEC_REPEAT_PERIOD
|
||||||
|
#define INFRARED_NEC_MIN_SPLIT_TIME INFRARED_NEC_REPEAT_PAUSE_MIN
|
||||||
|
#define INFRARED_NEC_REPEAT_PAUSE_MIN 4000
|
||||||
|
#define INFRARED_NEC_REPEAT_PAUSE_MAX 150000
|
||||||
|
#define INFRARED_NEC_REPEAT_COUNT_MIN 1
|
||||||
|
#define INFRARED_NEC_REPEAT_MARK 9000
|
||||||
|
#define INFRARED_NEC_REPEAT_SPACE 2250
|
||||||
|
#define INFRARED_NEC_PREAMBLE_TOLERANCE 200 // us
|
||||||
|
#define INFRARED_NEC_BIT_TOLERANCE 120 // us
|
||||||
|
|
||||||
|
extern const InfraredCommonProtocolSpec infrared_protocol_nec;
|
||||||
|
|
||||||
|
bool infrared_decoder_nec_interpret(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_decoder_nec_decode_repeat(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_encoder_nec_encode_repeat(
|
||||||
|
InfraredCommonEncoder* encoder,
|
||||||
|
uint32_t* duration,
|
||||||
|
bool* level);
|
@ -1,10 +1,7 @@
|
|||||||
#include "infrared.h"
|
#include "infrared_protocol_rc5_i.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <core/check.h>
|
||||||
#include <furi.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
#include "../infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
InfraredCommonDecoder* common_decoder;
|
InfraredCommonDecoder* common_decoder;
|
||||||
@ -60,7 +57,7 @@ bool infrared_decoder_rc5_interpret(InfraredCommonDecoder* decoder) {
|
|||||||
void* infrared_decoder_rc5_alloc(void) {
|
void* infrared_decoder_rc5_alloc(void) {
|
||||||
InfraredRc5Decoder* decoder = malloc(sizeof(InfraredRc5Decoder));
|
InfraredRc5Decoder* decoder = malloc(sizeof(InfraredRc5Decoder));
|
||||||
decoder->toggle = false;
|
decoder->toggle = false;
|
||||||
decoder->common_decoder = infrared_common_decoder_alloc(&protocol_rc5);
|
decoder->common_decoder = infrared_common_decoder_alloc(&infrared_protocol_rc5);
|
||||||
decoder->common_decoder->context = decoder;
|
decoder->common_decoder->context = decoder;
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#include <core/memmgr.h>
|
#include "infrared_protocol_rc5_i.h"
|
||||||
#include "infrared.h"
|
|
||||||
#include "common/infrared_common_i.h"
|
#include <stdlib.h>
|
||||||
#include "infrared_protocol_defs_i.h"
|
#include <core/check.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
|
|
||||||
typedef struct InfraredEncoderRC5 {
|
typedef struct InfraredEncoderRC5 {
|
||||||
InfraredCommonEncoder* common_encoder;
|
InfraredCommonEncoder* common_encoder;
|
||||||
@ -41,7 +39,7 @@ InfraredStatus infrared_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration
|
|||||||
|
|
||||||
void* infrared_encoder_rc5_alloc(void) {
|
void* infrared_encoder_rc5_alloc(void) {
|
||||||
InfraredEncoderRC5* encoder = malloc(sizeof(InfraredEncoderRC5));
|
InfraredEncoderRC5* encoder = malloc(sizeof(InfraredEncoderRC5));
|
||||||
encoder->common_encoder = infrared_common_encoder_alloc(&protocol_rc5);
|
encoder->common_encoder = infrared_common_encoder_alloc(&infrared_protocol_rc5);
|
||||||
encoder->toggle_bit = false;
|
encoder->toggle_bit = false;
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
49
lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.c
Normal file
49
lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#include "infrared_protocol_rc5_i.h"
|
||||||
|
|
||||||
|
const InfraredCommonProtocolSpec infrared_protocol_rc5 = {
|
||||||
|
.timings =
|
||||||
|
{
|
||||||
|
.preamble_mark = 0,
|
||||||
|
.preamble_space = 0,
|
||||||
|
.bit1_mark = INFRARED_RC5_BIT,
|
||||||
|
.preamble_tolerance = 0,
|
||||||
|
.bit_tolerance = INFRARED_RC5_BIT_TOLERANCE,
|
||||||
|
.silence_time = INFRARED_RC5_SILENCE,
|
||||||
|
.min_split_time = INFRARED_RC5_MIN_SPLIT_TIME,
|
||||||
|
},
|
||||||
|
.databit_len[0] = 1 + 1 + 1 + 5 +
|
||||||
|
6, // start_bit + start_bit/command_bit + toggle_bit + 5 address + 6 command
|
||||||
|
.manchester_start_from_space = true,
|
||||||
|
.decode = infrared_common_decode_manchester,
|
||||||
|
.encode = infrared_common_encode_manchester,
|
||||||
|
.interpret = infrared_decoder_rc5_interpret,
|
||||||
|
.decode_repeat = NULL,
|
||||||
|
.encode_repeat = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_rc5 = {
|
||||||
|
.name = "RC5",
|
||||||
|
.address_length = 5,
|
||||||
|
.command_length = 6,
|
||||||
|
.frequency = INFRARED_RC5_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_RC5_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_RC5_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_rc5x = {
|
||||||
|
.name = "RC5X",
|
||||||
|
.address_length = 5,
|
||||||
|
.command_length = 7,
|
||||||
|
.frequency = INFRARED_RC5_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_RC5_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_RC5_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_rc5_get_variant(InfraredProtocol protocol) {
|
||||||
|
if(protocol == InfraredProtocolRC5)
|
||||||
|
return &infrared_protocol_variant_rc5;
|
||||||
|
else if(protocol == InfraredProtocolRC5X)
|
||||||
|
return &infrared_protocol_variant_rc5x;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
38
lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.h
Normal file
38
lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* RC5 protocol description
|
||||||
|
* https://www.mikrocontroller.net/articles/IRMP_-_english#RC5_.2B_RC5X
|
||||||
|
****************************************************************************************************
|
||||||
|
* Manchester/biphase
|
||||||
|
* Modulation
|
||||||
|
*
|
||||||
|
* 888/1776 - bit (x2 for toggle bit)
|
||||||
|
*
|
||||||
|
* __ ____ __ __ __ __ __ __ __ __
|
||||||
|
* __ __ ____ __ __ __ __ __ __ __ _
|
||||||
|
* | 1 | 1 | 0 | ... | ... |
|
||||||
|
* s si T address (MSB) command (MSB)
|
||||||
|
*
|
||||||
|
* Note: manchester starts from space timing, so it have to be handled properly
|
||||||
|
* s - start bit (always 1)
|
||||||
|
* si - RC5: start bit (always 1), RC5X - 7-th bit of address (in our case always 0)
|
||||||
|
* T - toggle bit, change it's value every button press
|
||||||
|
* address - 5 bit
|
||||||
|
* command - 6/7 bit
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
void* infrared_decoder_rc5_alloc(void);
|
||||||
|
void infrared_decoder_rc5_reset(void* decoder);
|
||||||
|
void infrared_decoder_rc5_free(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_rc5_check_ready(void* ctx);
|
||||||
|
InfraredMessage* infrared_decoder_rc5_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
void* infrared_encoder_rc5_alloc(void);
|
||||||
|
void infrared_encoder_rc5_reset(void* encoder_ptr, const InfraredMessage* message);
|
||||||
|
void infrared_encoder_rc5_free(void* decoder);
|
||||||
|
InfraredStatus infrared_encoder_rc5_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_rc5_get_variant(InfraredProtocol protocol);
|
20
lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5_i.h
Normal file
20
lib/infrared/encoder_decoder/rc5/infrared_protocol_rc5_i.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common/infrared_common_i.h"
|
||||||
|
|
||||||
|
#define INFRARED_RC5_CARRIER_FREQUENCY 36000
|
||||||
|
#define INFRARED_RC5_DUTY_CYCLE 0.33
|
||||||
|
|
||||||
|
#define INFRARED_RC5_PREAMBLE_MARK 0
|
||||||
|
#define INFRARED_RC5_PREAMBLE_SPACE 0
|
||||||
|
#define INFRARED_RC5_BIT 888 // half of time-quant for 1 bit
|
||||||
|
#define INFRARED_RC5_PREAMBLE_TOLERANCE 200 // us
|
||||||
|
#define INFRARED_RC5_BIT_TOLERANCE 120 // us
|
||||||
|
/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
|
||||||
|
#define INFRARED_RC5_SILENCE (2700 * 10)
|
||||||
|
#define INFRARED_RC5_MIN_SPLIT_TIME 2700
|
||||||
|
#define INFRARED_RC5_REPEAT_COUNT_MIN 1
|
||||||
|
|
||||||
|
extern const InfraredCommonProtocolSpec infrared_protocol_rc5;
|
||||||
|
|
||||||
|
bool infrared_decoder_rc5_interpret(InfraredCommonDecoder* decoder);
|
@ -1,27 +0,0 @@
|
|||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_rc5_protocol_specification = {
|
|
||||||
.name = "RC5",
|
|
||||||
.address_length = 5,
|
|
||||||
.command_length = 6,
|
|
||||||
.frequency = INFRARED_RC5_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_RC5_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_rc5x_protocol_specification = {
|
|
||||||
.name = "RC5X",
|
|
||||||
.address_length = 5,
|
|
||||||
.command_length = 7,
|
|
||||||
.frequency = INFRARED_RC5_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_RC5_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredProtocolSpecification* infrared_rc5_get_spec(InfraredProtocol protocol) {
|
|
||||||
if(protocol == InfraredProtocolRC5)
|
|
||||||
return &infrared_rc5_protocol_specification;
|
|
||||||
else if(protocol == InfraredProtocolRC5X)
|
|
||||||
return &infrared_rc5x_protocol_specification;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -1,10 +1,7 @@
|
|||||||
#include "infrared.h"
|
#include "infrared_protocol_rc6_i.h"
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <core/check.h>
|
||||||
#include <furi.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
#include "../infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
InfraredCommonDecoder* common_decoder;
|
InfraredCommonDecoder* common_decoder;
|
||||||
@ -93,7 +90,7 @@ InfraredStatus infrared_decoder_rc6_decode_manchester(
|
|||||||
void* infrared_decoder_rc6_alloc(void) {
|
void* infrared_decoder_rc6_alloc(void) {
|
||||||
InfraredRc6Decoder* decoder = malloc(sizeof(InfraredRc6Decoder));
|
InfraredRc6Decoder* decoder = malloc(sizeof(InfraredRc6Decoder));
|
||||||
decoder->toggle = false;
|
decoder->toggle = false;
|
||||||
decoder->common_decoder = infrared_common_decoder_alloc(&protocol_rc6);
|
decoder->common_decoder = infrared_common_decoder_alloc(&infrared_protocol_rc6);
|
||||||
decoder->common_decoder->context = decoder;
|
decoder->common_decoder->context = decoder;
|
||||||
return decoder;
|
return decoder;
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
#include <core/memmgr.h>
|
#include "infrared_protocol_rc6_i.h"
|
||||||
#include "infrared.h"
|
|
||||||
#include "common/infrared_common_i.h"
|
#include <stdlib.h>
|
||||||
#include "infrared_protocol_defs_i.h"
|
#include <core/check.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
|
|
||||||
typedef struct InfraredEncoderRC6 {
|
typedef struct InfraredEncoderRC6 {
|
||||||
InfraredCommonEncoder* common_encoder;
|
InfraredCommonEncoder* common_encoder;
|
||||||
@ -35,7 +33,7 @@ InfraredStatus infrared_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration
|
|||||||
|
|
||||||
void* infrared_encoder_rc6_alloc(void) {
|
void* infrared_encoder_rc6_alloc(void) {
|
||||||
InfraredEncoderRC6* encoder = malloc(sizeof(InfraredEncoderRC6));
|
InfraredEncoderRC6* encoder = malloc(sizeof(InfraredEncoderRC6));
|
||||||
encoder->common_encoder = infrared_common_encoder_alloc(&protocol_rc6);
|
encoder->common_encoder = infrared_common_encoder_alloc(&infrared_protocol_rc6);
|
||||||
encoder->toggle_bit = false;
|
encoder->toggle_bit = false;
|
||||||
return encoder;
|
return encoder;
|
||||||
}
|
}
|
||||||
|
39
lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.c
Normal file
39
lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.c
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "infrared_protocol_rc6_i.h"
|
||||||
|
|
||||||
|
const InfraredCommonProtocolSpec infrared_protocol_rc6 = {
|
||||||
|
.timings =
|
||||||
|
{
|
||||||
|
.preamble_mark = INFRARED_RC6_PREAMBLE_MARK,
|
||||||
|
.preamble_space = INFRARED_RC6_PREAMBLE_SPACE,
|
||||||
|
.bit1_mark = INFRARED_RC6_BIT,
|
||||||
|
.preamble_tolerance = INFRARED_RC6_PREAMBLE_TOLERANCE,
|
||||||
|
.bit_tolerance = INFRARED_RC6_BIT_TOLERANCE,
|
||||||
|
.silence_time = INFRARED_RC6_SILENCE,
|
||||||
|
.min_split_time = INFRARED_RC6_MIN_SPLIT_TIME,
|
||||||
|
},
|
||||||
|
.databit_len[0] =
|
||||||
|
1 + 3 + 1 + 8 +
|
||||||
|
8, // start_bit + 3 mode bits, + 1 toggle bit (x2 timing) + 8 address + 8 command
|
||||||
|
.manchester_start_from_space = false,
|
||||||
|
.decode = infrared_decoder_rc6_decode_manchester,
|
||||||
|
.encode = infrared_encoder_rc6_encode_manchester,
|
||||||
|
.interpret = infrared_decoder_rc6_interpret,
|
||||||
|
.decode_repeat = NULL,
|
||||||
|
.encode_repeat = NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_rc6 = {
|
||||||
|
.name = "RC6",
|
||||||
|
.address_length = 8,
|
||||||
|
.command_length = 8,
|
||||||
|
.frequency = INFRARED_RC6_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_RC6_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_RC6_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_rc6_get_variant(InfraredProtocol protocol) {
|
||||||
|
if(protocol == InfraredProtocolRC6)
|
||||||
|
return &infrared_protocol_variant_rc6;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
37
lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.h
Normal file
37
lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* RC6 protocol description
|
||||||
|
* https://www.mikrocontroller.net/articles/IRMP_-_english#RC6_.2B_RC6A
|
||||||
|
****************************************************************************************************
|
||||||
|
* Preamble Manchester/biphase Silence
|
||||||
|
* mark/space Modulation
|
||||||
|
*
|
||||||
|
* 2666 889 444/888 - bit (x2 for toggle bit) 2666
|
||||||
|
*
|
||||||
|
* ________ __ __ __ __ ____ __ __ __ __ __ __ __ __
|
||||||
|
* _ _________ ____ __ __ ____ __ __ __ __ __ __ __ __ _______________
|
||||||
|
* | 1 | 0 | 0 | 0 | 0 | ... | ... | |
|
||||||
|
* s m2 m1 m0 T address (MSB) command (MSB)
|
||||||
|
*
|
||||||
|
* s - start bit (always 1)
|
||||||
|
* m0-2 - mode (000 for RC6)
|
||||||
|
* T - toggle bit, twice longer
|
||||||
|
* address - 8 bit
|
||||||
|
* command - 8 bit
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
void* infrared_decoder_rc6_alloc(void);
|
||||||
|
void infrared_decoder_rc6_reset(void* decoder);
|
||||||
|
void infrared_decoder_rc6_free(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_rc6_check_ready(void* ctx);
|
||||||
|
InfraredMessage* infrared_decoder_rc6_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
void* infrared_encoder_rc6_alloc(void);
|
||||||
|
void infrared_encoder_rc6_reset(void* encoder_ptr, const InfraredMessage* message);
|
||||||
|
void infrared_encoder_rc6_free(void* decoder);
|
||||||
|
InfraredStatus infrared_encoder_rc6_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_rc6_get_variant(InfraredProtocol protocol);
|
28
lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6_i.h
Normal file
28
lib/infrared/encoder_decoder/rc6/infrared_protocol_rc6_i.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common/infrared_common_i.h"
|
||||||
|
|
||||||
|
#define INFRARED_RC6_CARRIER_FREQUENCY 36000
|
||||||
|
#define INFRARED_RC6_DUTY_CYCLE 0.33
|
||||||
|
|
||||||
|
#define INFRARED_RC6_PREAMBLE_MARK 2666
|
||||||
|
#define INFRARED_RC6_PREAMBLE_SPACE 889
|
||||||
|
#define INFRARED_RC6_BIT 444 // half of time-quant for 1 bit
|
||||||
|
#define INFRARED_RC6_PREAMBLE_TOLERANCE 200 // us
|
||||||
|
#define INFRARED_RC6_BIT_TOLERANCE 120 // us
|
||||||
|
/* protocol allows 2700 silence, but it is hard to send 1 message without repeat */
|
||||||
|
#define INFRARED_RC6_SILENCE (2700 * 10)
|
||||||
|
#define INFRARED_RC6_MIN_SPLIT_TIME 2700
|
||||||
|
#define INFRARED_RC6_REPEAT_COUNT_MIN 1
|
||||||
|
|
||||||
|
extern const InfraredCommonProtocolSpec infrared_protocol_rc6;
|
||||||
|
|
||||||
|
bool infrared_decoder_rc6_interpret(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_decoder_rc6_decode_manchester(
|
||||||
|
InfraredCommonDecoder* decoder,
|
||||||
|
bool level,
|
||||||
|
uint32_t timing);
|
||||||
|
InfraredStatus infrared_encoder_rc6_encode_manchester(
|
||||||
|
InfraredCommonEncoder* encoder_ptr,
|
||||||
|
uint32_t* duration,
|
||||||
|
bool* polarity);
|
@ -1,17 +0,0 @@
|
|||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_rc6_protocol_specification = {
|
|
||||||
.name = "RC6",
|
|
||||||
.address_length = 8,
|
|
||||||
.command_length = 8,
|
|
||||||
.frequency = INFRARED_RC6_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_RC6_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredProtocolSpecification* infrared_rc6_get_spec(InfraredProtocol protocol) {
|
|
||||||
if(protocol == InfraredProtocolRC6)
|
|
||||||
return &infrared_rc6_protocol_specification;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -1,9 +1,5 @@
|
|||||||
#include "infrared.h"
|
#include "infrared_protocol_samsung_i.h"
|
||||||
#include "infrared_protocol_defs_i.h"
|
#include <core/check.h>
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <furi.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx) {
|
InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx) {
|
||||||
return infrared_common_decoder_check_ready(ctx);
|
return infrared_common_decoder_check_ready(ctx);
|
||||||
@ -57,7 +53,7 @@ InfraredStatus infrared_decoder_samsung32_decode_repeat(InfraredCommonDecoder* d
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_decoder_samsung32_alloc(void) {
|
void* infrared_decoder_samsung32_alloc(void) {
|
||||||
return infrared_common_decoder_alloc(&protocol_samsung32);
|
return infrared_common_decoder_alloc(&infrared_protocol_samsung32);
|
||||||
}
|
}
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration) {
|
InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration) {
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
|
#include "infrared_protocol_samsung_i.h"
|
||||||
|
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
#include "common/infrared_common_i.h"
|
#include <core/common_defines.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <furi.h>
|
|
||||||
|
|
||||||
static const uint32_t repeat_timings[] = {
|
static const uint32_t repeat_timings[] = {
|
||||||
INFRARED_SAMSUNG_REPEAT_PAUSE2,
|
INFRARED_SAMSUNG_REPEAT_PAUSE2,
|
||||||
@ -58,7 +56,7 @@ InfraredStatus infrared_encoder_samsung32_encode_repeat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_encoder_samsung32_alloc(void) {
|
void* infrared_encoder_samsung32_alloc(void) {
|
||||||
return infrared_common_encoder_alloc(&protocol_samsung32);
|
return infrared_common_encoder_alloc(&infrared_protocol_samsung32);
|
||||||
}
|
}
|
||||||
|
|
||||||
void infrared_encoder_samsung32_free(void* encoder_ptr) {
|
void infrared_encoder_samsung32_free(void* encoder_ptr) {
|
||||||
|
@ -0,0 +1,40 @@
|
|||||||
|
#include "infrared_protocol_samsung_i.h"
|
||||||
|
|
||||||
|
const InfraredCommonProtocolSpec infrared_protocol_samsung32 = {
|
||||||
|
.timings =
|
||||||
|
{
|
||||||
|
.preamble_mark = INFRARED_SAMSUNG_PREAMBLE_MARK,
|
||||||
|
.preamble_space = INFRARED_SAMSUNG_PREAMBLE_SPACE,
|
||||||
|
.bit1_mark = INFRARED_SAMSUNG_BIT1_MARK,
|
||||||
|
.bit1_space = INFRARED_SAMSUNG_BIT1_SPACE,
|
||||||
|
.bit0_mark = INFRARED_SAMSUNG_BIT0_MARK,
|
||||||
|
.bit0_space = INFRARED_SAMSUNG_BIT0_SPACE,
|
||||||
|
.preamble_tolerance = INFRARED_SAMSUNG_PREAMBLE_TOLERANCE,
|
||||||
|
.bit_tolerance = INFRARED_SAMSUNG_BIT_TOLERANCE,
|
||||||
|
.silence_time = INFRARED_SAMSUNG_SILENCE,
|
||||||
|
.min_split_time = INFRARED_SAMSUNG_MIN_SPLIT_TIME,
|
||||||
|
},
|
||||||
|
.databit_len[0] = 32,
|
||||||
|
.no_stop_bit = false,
|
||||||
|
.decode = infrared_common_decode_pdwm,
|
||||||
|
.encode = infrared_common_encode_pdwm,
|
||||||
|
.interpret = infrared_decoder_samsung32_interpret,
|
||||||
|
.decode_repeat = infrared_decoder_samsung32_decode_repeat,
|
||||||
|
.encode_repeat = infrared_encoder_samsung32_encode_repeat,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_samsung32 = {
|
||||||
|
.name = "Samsung32",
|
||||||
|
.address_length = 8,
|
||||||
|
.command_length = 8,
|
||||||
|
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_SAMSUNG_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_samsung32_get_variant(InfraredProtocol protocol) {
|
||||||
|
if(protocol == InfraredProtocolSamsung32)
|
||||||
|
return &infrared_protocol_variant_samsung32;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* SAMSUNG32 protocol description
|
||||||
|
* https://www.mikrocontroller.net/articles/IRMP_-_english#SAMSUNG
|
||||||
|
****************************************************************************************************
|
||||||
|
* Preamble Preamble Pulse Distance/Width Pause Preamble Preamble Bit1 Stop
|
||||||
|
* mark space Modulation repeat repeat bit
|
||||||
|
* mark space
|
||||||
|
*
|
||||||
|
* 4500 4500 32 bit + stop bit 40000/100000 4500 4500
|
||||||
|
* __________ _ _ _ _ _ _ _ _ _ _ _ ___________ _ _
|
||||||
|
* _ __________ __ _ __ __ __ _ _ __ __ _ ________________ ____________ ____ ___
|
||||||
|
*
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
void* infrared_decoder_samsung32_alloc(void);
|
||||||
|
void infrared_decoder_samsung32_reset(void* decoder);
|
||||||
|
void infrared_decoder_samsung32_free(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_samsung32_check_ready(void* ctx);
|
||||||
|
InfraredMessage* infrared_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
InfraredStatus
|
||||||
|
infrared_encoder_samsung32_encode(void* encoder_ptr, uint32_t* duration, bool* level);
|
||||||
|
void infrared_encoder_samsung32_reset(void* encoder_ptr, const InfraredMessage* message);
|
||||||
|
void* infrared_encoder_samsung32_alloc(void);
|
||||||
|
void infrared_encoder_samsung32_free(void* encoder_ptr);
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_samsung32_get_variant(InfraredProtocol protocol);
|
@ -0,0 +1,35 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common/infrared_common_i.h"
|
||||||
|
|
||||||
|
#define INFRARED_SAMSUNG_PREAMBLE_MARK 4500
|
||||||
|
#define INFRARED_SAMSUNG_PREAMBLE_SPACE 4500
|
||||||
|
#define INFRARED_SAMSUNG_BIT1_MARK 550
|
||||||
|
#define INFRARED_SAMSUNG_BIT1_SPACE 1650
|
||||||
|
#define INFRARED_SAMSUNG_BIT0_MARK 550
|
||||||
|
#define INFRARED_SAMSUNG_BIT0_SPACE 550
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_PAUSE_MIN 30000
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_PAUSE_MAX 140000
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_PAUSE1 46000
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_PAUSE2 97000
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_COUNT_MIN 1
|
||||||
|
/* Samsung silence have to be greater than REPEAT MAX
|
||||||
|
* otherwise there can be problems during unit tests parsing
|
||||||
|
* of some data. Real tolerances we don't know, but in real life
|
||||||
|
* silence time should be greater than max repeat time. This is
|
||||||
|
* because of similar preambule timings for repeat and first messages. */
|
||||||
|
#define INFRARED_SAMSUNG_MIN_SPLIT_TIME 5000
|
||||||
|
#define INFRARED_SAMSUNG_SILENCE 145000
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_MARK 4500
|
||||||
|
#define INFRARED_SAMSUNG_REPEAT_SPACE 4500
|
||||||
|
#define INFRARED_SAMSUNG_PREAMBLE_TOLERANCE 200 // us
|
||||||
|
#define INFRARED_SAMSUNG_BIT_TOLERANCE 120 // us
|
||||||
|
|
||||||
|
bool infrared_decoder_samsung32_interpret(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_decoder_samsung32_decode_repeat(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_encoder_samsung32_encode_repeat(
|
||||||
|
InfraredCommonEncoder* encoder,
|
||||||
|
uint32_t* duration,
|
||||||
|
bool* level);
|
||||||
|
|
||||||
|
extern const InfraredCommonProtocolSpec infrared_protocol_samsung32;
|
@ -1,17 +0,0 @@
|
|||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_samsung32_protocol_specification = {
|
|
||||||
.name = "Samsung32",
|
|
||||||
.address_length = 8,
|
|
||||||
.command_length = 8,
|
|
||||||
.frequency = INFRARED_COMMON_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_COMMON_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredProtocolSpecification* infrared_samsung32_get_spec(InfraredProtocol protocol) {
|
|
||||||
if(protocol == InfraredProtocolSamsung32)
|
|
||||||
return &infrared_samsung32_protocol_specification;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -1,10 +1,5 @@
|
|||||||
#include "common/infrared_common_i.h"
|
#include "infrared_protocol_sirc_i.h"
|
||||||
#include "infrared.h"
|
#include <core/check.h>
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <furi.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_sirc_check_ready(void* ctx) {
|
InfraredMessage* infrared_decoder_sirc_check_ready(void* ctx) {
|
||||||
return infrared_common_decoder_check_ready(ctx);
|
return infrared_common_decoder_check_ready(ctx);
|
||||||
@ -44,7 +39,7 @@ bool infrared_decoder_sirc_interpret(InfraredCommonDecoder* decoder) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_decoder_sirc_alloc(void) {
|
void* infrared_decoder_sirc_alloc(void) {
|
||||||
return infrared_common_decoder_alloc(&protocol_sirc);
|
return infrared_common_decoder_alloc(&infrared_protocol_sirc);
|
||||||
}
|
}
|
||||||
|
|
||||||
InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration) {
|
InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration) {
|
||||||
|
@ -1,10 +1,5 @@
|
|||||||
|
#include "infrared_protocol_sirc_i.h"
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
#include "infrared.h"
|
|
||||||
#include "common/infrared_common_i.h"
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
#include <furi.h>
|
|
||||||
|
|
||||||
void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message) {
|
void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message) {
|
||||||
furi_assert(encoder_ptr);
|
furi_assert(encoder_ptr);
|
||||||
@ -53,7 +48,7 @@ InfraredStatus infrared_encoder_sirc_encode_repeat(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void* infrared_encoder_sirc_alloc(void) {
|
void* infrared_encoder_sirc_alloc(void) {
|
||||||
return infrared_common_encoder_alloc(&protocol_sirc);
|
return infrared_common_encoder_alloc(&infrared_protocol_sirc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void infrared_encoder_sirc_free(void* encoder_ptr) {
|
void infrared_encoder_sirc_free(void* encoder_ptr) {
|
||||||
|
64
lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.c
Normal file
64
lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "infrared_protocol_sirc_i.h"
|
||||||
|
|
||||||
|
const InfraredCommonProtocolSpec infrared_protocol_sirc = {
|
||||||
|
.timings =
|
||||||
|
{
|
||||||
|
.preamble_mark = INFRARED_SIRC_PREAMBLE_MARK,
|
||||||
|
.preamble_space = INFRARED_SIRC_PREAMBLE_SPACE,
|
||||||
|
.bit1_mark = INFRARED_SIRC_BIT1_MARK,
|
||||||
|
.bit1_space = INFRARED_SIRC_BIT1_SPACE,
|
||||||
|
.bit0_mark = INFRARED_SIRC_BIT0_MARK,
|
||||||
|
.bit0_space = INFRARED_SIRC_BIT0_SPACE,
|
||||||
|
.preamble_tolerance = INFRARED_SIRC_PREAMBLE_TOLERANCE,
|
||||||
|
.bit_tolerance = INFRARED_SIRC_BIT_TOLERANCE,
|
||||||
|
.silence_time = INFRARED_SIRC_SILENCE,
|
||||||
|
.min_split_time = INFRARED_SIRC_MIN_SPLIT_TIME,
|
||||||
|
},
|
||||||
|
.databit_len[0] = 20,
|
||||||
|
.databit_len[1] = 15,
|
||||||
|
.databit_len[2] = 12,
|
||||||
|
.no_stop_bit = true,
|
||||||
|
.decode = infrared_common_decode_pdwm,
|
||||||
|
.encode = infrared_common_encode_pdwm,
|
||||||
|
.interpret = infrared_decoder_sirc_interpret,
|
||||||
|
.decode_repeat = NULL,
|
||||||
|
.encode_repeat = infrared_encoder_sirc_encode_repeat,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_sirc = {
|
||||||
|
.name = "SIRC",
|
||||||
|
.address_length = 5,
|
||||||
|
.command_length = 7,
|
||||||
|
.frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_SIRC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_sirc15 = {
|
||||||
|
.name = "SIRC15",
|
||||||
|
.address_length = 8,
|
||||||
|
.command_length = 7,
|
||||||
|
.frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_SIRC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const InfraredProtocolVariant infrared_protocol_variant_sirc20 = {
|
||||||
|
.name = "SIRC20",
|
||||||
|
.address_length = 13,
|
||||||
|
.command_length = 7,
|
||||||
|
.frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
|
||||||
|
.duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
|
||||||
|
.repeat_count = INFRARED_SIRC_REPEAT_COUNT_MIN,
|
||||||
|
};
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_sirc_get_variant(InfraredProtocol protocol) {
|
||||||
|
if(protocol == InfraredProtocolSIRC)
|
||||||
|
return &infrared_protocol_variant_sirc;
|
||||||
|
else if(protocol == InfraredProtocolSIRC15)
|
||||||
|
return &infrared_protocol_variant_sirc15;
|
||||||
|
else if(protocol == InfraredProtocolSIRC20)
|
||||||
|
return &infrared_protocol_variant_sirc20;
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
37
lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.h
Normal file
37
lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
|
/***************************************************************************************************
|
||||||
|
* Sony SIRC protocol description
|
||||||
|
* https://www.sbprojects.net/knowledge/ir/sirc.php
|
||||||
|
* http://picprojects.org.uk/
|
||||||
|
****************************************************************************************************
|
||||||
|
* Preamble Preamble Pulse Width Modulation Pause Entirely repeat
|
||||||
|
* mark space up to period message..
|
||||||
|
*
|
||||||
|
* 2400 600 12/15/20 bits (600,1200) ...45000 2400 600
|
||||||
|
* __________ _ _ _ _ _ _ _ _ _ _ _ _ _ __________ _ _
|
||||||
|
* ____ __________ _ _ _ __ __ __ _ _ __ __ _ _ ____________________ __________ _
|
||||||
|
* | command | address |
|
||||||
|
* SIRC | 7b LSB | 5b LSB |
|
||||||
|
* SIRC15 | 7b LSB | 8b LSB |
|
||||||
|
* SIRC20 | 7b LSB | 13b LSB |
|
||||||
|
*
|
||||||
|
* No way to determine either next message is repeat or not,
|
||||||
|
* so recognize only fact message received. Sony remotes always send at least 3 messages.
|
||||||
|
* Assume 8 last extended bits for SIRC20 are address bits.
|
||||||
|
***************************************************************************************************/
|
||||||
|
|
||||||
|
void* infrared_decoder_sirc_alloc(void);
|
||||||
|
void infrared_decoder_sirc_reset(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_sirc_check_ready(void* decoder);
|
||||||
|
void infrared_decoder_sirc_free(void* decoder);
|
||||||
|
InfraredMessage* infrared_decoder_sirc_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
void* infrared_encoder_sirc_alloc(void);
|
||||||
|
void infrared_encoder_sirc_reset(void* encoder_ptr, const InfraredMessage* message);
|
||||||
|
void infrared_encoder_sirc_free(void* decoder);
|
||||||
|
InfraredStatus infrared_encoder_sirc_encode(void* encoder_ptr, uint32_t* duration, bool* polarity);
|
||||||
|
|
||||||
|
const InfraredProtocolVariant* infrared_protocol_sirc_get_variant(InfraredProtocol protocol);
|
26
lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc_i.h
Normal file
26
lib/infrared/encoder_decoder/sirc/infrared_protocol_sirc_i.h
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "../common/infrared_common_i.h"
|
||||||
|
|
||||||
|
#define INFRARED_SIRC_CARRIER_FREQUENCY 40000
|
||||||
|
#define INFRARED_SIRC_DUTY_CYCLE 0.33
|
||||||
|
#define INFRARED_SIRC_PREAMBLE_MARK 2400
|
||||||
|
#define INFRARED_SIRC_PREAMBLE_SPACE 600
|
||||||
|
#define INFRARED_SIRC_BIT1_MARK 1200
|
||||||
|
#define INFRARED_SIRC_BIT1_SPACE 600
|
||||||
|
#define INFRARED_SIRC_BIT0_MARK 600
|
||||||
|
#define INFRARED_SIRC_BIT0_SPACE 600
|
||||||
|
#define INFRARED_SIRC_PREAMBLE_TOLERANCE 200 // us
|
||||||
|
#define INFRARED_SIRC_BIT_TOLERANCE 120 // us
|
||||||
|
#define INFRARED_SIRC_SILENCE 10000
|
||||||
|
#define INFRARED_SIRC_MIN_SPLIT_TIME (INFRARED_SIRC_SILENCE - 1000)
|
||||||
|
#define INFRARED_SIRC_REPEAT_PERIOD 45000
|
||||||
|
#define INFRARED_SIRC_REPEAT_COUNT_MIN 3
|
||||||
|
|
||||||
|
extern const InfraredCommonProtocolSpec infrared_protocol_sirc;
|
||||||
|
|
||||||
|
bool infrared_decoder_sirc_interpret(InfraredCommonDecoder* decoder);
|
||||||
|
InfraredStatus infrared_encoder_sirc_encode_repeat(
|
||||||
|
InfraredCommonEncoder* encoder,
|
||||||
|
uint32_t* duration,
|
||||||
|
bool* level);
|
@ -1,37 +0,0 @@
|
|||||||
#include "../infrared_i.h"
|
|
||||||
#include "infrared_protocol_defs_i.h"
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_sirc_protocol_specification = {
|
|
||||||
.name = "SIRC",
|
|
||||||
.address_length = 5,
|
|
||||||
.command_length = 7,
|
|
||||||
.frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_sirc15_protocol_specification = {
|
|
||||||
.name = "SIRC15",
|
|
||||||
.address_length = 8,
|
|
||||||
.command_length = 7,
|
|
||||||
.frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const InfraredProtocolSpecification infrared_sirc20_protocol_specification = {
|
|
||||||
.name = "SIRC20",
|
|
||||||
.address_length = 13,
|
|
||||||
.command_length = 7,
|
|
||||||
.frequency = INFRARED_SIRC_CARRIER_FREQUENCY,
|
|
||||||
.duty_cycle = INFRARED_SIRC_DUTY_CYCLE,
|
|
||||||
};
|
|
||||||
|
|
||||||
const InfraredProtocolSpecification* infrared_sirc_get_spec(InfraredProtocol protocol) {
|
|
||||||
if(protocol == InfraredProtocolSIRC)
|
|
||||||
return &infrared_sirc_protocol_specification;
|
|
||||||
else if(protocol == InfraredProtocolSIRC15)
|
|
||||||
return &infrared_sirc15_protocol_specification;
|
|
||||||
else if(protocol == InfraredProtocolSIRC20)
|
|
||||||
return &infrared_sirc20_protocol_specification;
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@ -101,7 +101,8 @@ void infrared_send(const InfraredMessage* message, int times) {
|
|||||||
|
|
||||||
InfraredEncoderHandler* handler = infrared_alloc_encoder();
|
InfraredEncoderHandler* handler = infrared_alloc_encoder();
|
||||||
infrared_reset_encoder(handler, message);
|
infrared_reset_encoder(handler, message);
|
||||||
infrared_tx_number_of_transmissions = times;
|
infrared_tx_number_of_transmissions =
|
||||||
|
MAX((int)infrared_get_protocol_min_repeat_count(message->protocol), times);
|
||||||
|
|
||||||
uint32_t frequency = infrared_get_protocol_frequency(message->protocol);
|
uint32_t frequency = infrared_get_protocol_frequency(message->protocol);
|
||||||
float duty_cycle = infrared_get_protocol_duty_cycle(message->protocol);
|
float duty_cycle = infrared_get_protocol_duty_cycle(message->protocol);
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
|
#include "infrared_worker.h"
|
||||||
|
|
||||||
|
#include <furi_hal_infrared.h>
|
||||||
|
#include <float_tools.h>
|
||||||
|
|
||||||
#include <core/check.h>
|
#include <core/check.h>
|
||||||
#include <core/common_defines.h>
|
#include <core/common_defines.h>
|
||||||
#include "sys/_stdint.h"
|
|
||||||
#include "infrared_worker.h"
|
|
||||||
#include <infrared.h>
|
|
||||||
#include <furi_hal_infrared.h>
|
|
||||||
#include <limits.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <furi.h>
|
|
||||||
#include <float_tools.h>
|
|
||||||
|
|
||||||
#include <notification/notification_messages.h>
|
#include <notification/notification_messages.h>
|
||||||
|
|
||||||
@ -471,18 +468,23 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
|||||||
furi_assert(instance->state == InfraredWorkerStateStartTx);
|
furi_assert(instance->state == InfraredWorkerStateStartTx);
|
||||||
furi_assert(thread_context);
|
furi_assert(thread_context);
|
||||||
|
|
||||||
|
size_t repeats_left =
|
||||||
|
instance->signal.decoded ?
|
||||||
|
infrared_get_protocol_min_repeat_count(instance->signal.message.protocol) :
|
||||||
|
1;
|
||||||
uint32_t events = 0;
|
uint32_t events = 0;
|
||||||
bool new_data_available = true;
|
|
||||||
bool exit = false;
|
|
||||||
|
|
||||||
exit = !infrared_get_new_signal(instance);
|
bool exit_pending = false;
|
||||||
furi_assert(!exit);
|
|
||||||
|
|
||||||
while(!exit) {
|
bool running = infrared_get_new_signal(instance);
|
||||||
|
furi_assert(running);
|
||||||
|
|
||||||
|
while(running) {
|
||||||
switch(instance->state) {
|
switch(instance->state) {
|
||||||
case InfraredWorkerStateStartTx:
|
case InfraredWorkerStateStartTx:
|
||||||
|
--repeats_left; /* The first message does not result in TX_MESSAGE_SENT event for some reason */
|
||||||
instance->tx.need_reinitialization = false;
|
instance->tx.need_reinitialization = false;
|
||||||
new_data_available = infrared_worker_tx_fill_buffer(instance);
|
const bool new_data_available = infrared_worker_tx_fill_buffer(instance);
|
||||||
furi_hal_infrared_async_tx_start(instance->tx.frequency, instance->tx.duty_cycle);
|
furi_hal_infrared_async_tx_start(instance->tx.frequency, instance->tx.duty_cycle);
|
||||||
|
|
||||||
if(!new_data_available) {
|
if(!new_data_available) {
|
||||||
@ -496,7 +498,7 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
|||||||
break;
|
break;
|
||||||
case InfraredWorkerStateStopTx:
|
case InfraredWorkerStateStopTx:
|
||||||
furi_hal_infrared_async_tx_stop();
|
furi_hal_infrared_async_tx_stop();
|
||||||
exit = true;
|
running = false;
|
||||||
break;
|
break;
|
||||||
case InfraredWorkerStateWaitTxEnd:
|
case InfraredWorkerStateWaitTxEnd:
|
||||||
furi_hal_infrared_async_tx_wait_termination();
|
furi_hal_infrared_async_tx_wait_termination();
|
||||||
@ -504,18 +506,18 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
|||||||
|
|
||||||
events = furi_thread_flags_get();
|
events = furi_thread_flags_get();
|
||||||
if(events & INFRARED_WORKER_EXIT) {
|
if(events & INFRARED_WORKER_EXIT) {
|
||||||
exit = true;
|
running = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case InfraredWorkerStateRunTx:
|
case InfraredWorkerStateRunTx:
|
||||||
events = furi_thread_flags_wait(INFRARED_WORKER_ALL_TX_EVENTS, 0, FuriWaitForever);
|
events = furi_thread_flags_wait(
|
||||||
|
INFRARED_WORKER_ALL_TX_EVENTS, FuriFlagWaitAny, FuriWaitForever);
|
||||||
furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */
|
furi_check(events & INFRARED_WORKER_ALL_TX_EVENTS); /* at least one caught */
|
||||||
|
|
||||||
if(events & INFRARED_WORKER_EXIT) {
|
if(events & INFRARED_WORKER_EXIT) {
|
||||||
instance->state = InfraredWorkerStateStopTx;
|
exit_pending = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(events & INFRARED_WORKER_TX_FILL_BUFFER) {
|
if(events & INFRARED_WORKER_TX_FILL_BUFFER) {
|
||||||
@ -527,9 +529,19 @@ static int32_t infrared_worker_tx_thread(void* thread_context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(events & INFRARED_WORKER_TX_MESSAGE_SENT) {
|
if(events & INFRARED_WORKER_TX_MESSAGE_SENT) {
|
||||||
if(instance->tx.message_sent_callback)
|
if(repeats_left > 0) {
|
||||||
|
--repeats_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(instance->tx.message_sent_callback) {
|
||||||
instance->tx.message_sent_callback(instance->tx.message_sent_context);
|
instance->tx.message_sent_callback(instance->tx.message_sent_context);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(exit_pending && repeats_left == 0) {
|
||||||
|
instance->state = InfraredWorkerStateStopTx;
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
furi_assert(0);
|
furi_assert(0);
|
||||||
|
@ -244,7 +244,7 @@ LevelDuration protocol_fdx_b_encoder_yield(ProtocolFDXB* protocol) {
|
|||||||
static uint64_t protocol_fdx_b_get_national_code(const uint8_t* data) {
|
static uint64_t protocol_fdx_b_get_national_code(const uint8_t* data) {
|
||||||
uint64_t national_code = bit_lib_get_bits_32(data, 0, 32);
|
uint64_t national_code = bit_lib_get_bits_32(data, 0, 32);
|
||||||
national_code = national_code << 32;
|
national_code = national_code << 32;
|
||||||
national_code |= bit_lib_get_bits_32(data, 32, 6) << (32 - 6);
|
national_code |= (uint64_t)bit_lib_get_bits_32(data, 32, 6) << (32 - 6);
|
||||||
bit_lib_reverse_bits((uint8_t*)&national_code, 0, 64);
|
bit_lib_reverse_bits((uint8_t*)&national_code, 0, 64);
|
||||||
return national_code;
|
return national_code;
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,16 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
|
#define bit_read(value, bit) (((value) >> (bit)) & 0x01)
|
||||||
#define bit_set(value, bit) ((value) |= (1UL << (bit)))
|
#define bit_set(value, bit) \
|
||||||
#define bit_clear(value, bit) ((value) &= ~(1UL << (bit)))
|
({ \
|
||||||
|
__typeof__(value) _one = (1); \
|
||||||
|
(value) |= (_one << (bit)); \
|
||||||
|
})
|
||||||
|
#define bit_clear(value, bit) \
|
||||||
|
({ \
|
||||||
|
__typeof__(value) _one = (1); \
|
||||||
|
(value) &= ~(_one << (bit)); \
|
||||||
|
})
|
||||||
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
|
#define bit_write(value, bit, bitvalue) (bitvalue ? bit_set(value, bit) : bit_clear(value, bit))
|
||||||
#define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
|
#define DURATION_DIFF(x, y) (((x) < (y)) ? ((y) - (x)) : ((x) - (y)))
|
||||||
|
|
||||||
|
@ -280,9 +280,9 @@ static bool subghz_protocol_chamb_code_to_bit(uint64_t* data, uint8_t size) {
|
|||||||
uint64_t data_tmp = data[0];
|
uint64_t data_tmp = data[0];
|
||||||
uint64_t data_res = 0;
|
uint64_t data_res = 0;
|
||||||
for(uint8_t i = 0; i < size; i++) {
|
for(uint8_t i = 0; i < size; i++) {
|
||||||
if((data_tmp & 0xF) == CHAMBERLAIN_CODE_BIT_0) {
|
if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_0) {
|
||||||
bit_write(data_res, i, 0);
|
bit_write(data_res, i, 0);
|
||||||
} else if((data_tmp & 0xF) == CHAMBERLAIN_CODE_BIT_1) {
|
} else if((data_tmp & 0xFll) == CHAMBERLAIN_CODE_BIT_1) {
|
||||||
bit_write(data_res, i, 1);
|
bit_write(data_res, i, 1);
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -224,7 +224,7 @@ static bool subghz_protocol_secplus_v1_encode(SubGhzProtocolEncoderSecPlus_v1* i
|
|||||||
instance->generic.data &= 0xFFFFFFFF00000000;
|
instance->generic.data &= 0xFFFFFFFF00000000;
|
||||||
instance->generic.data |= rolling;
|
instance->generic.data |= rolling;
|
||||||
|
|
||||||
if(rolling > 0xFFFFFFFF) {
|
if(rolling == 0xFFFFFFFF) {
|
||||||
rolling = 0xE6000000;
|
rolling = 0xE6000000;
|
||||||
}
|
}
|
||||||
if(fixed > 0xCFD41B90) {
|
if(fixed > 0xCFD41B90) {
|
||||||
|
@ -7,7 +7,7 @@ from SCons.Node import NodeList
|
|||||||
import SCons.Warnings
|
import SCons.Warnings
|
||||||
|
|
||||||
from fbt.elfmanifest import assemble_manifest_data
|
from fbt.elfmanifest import assemble_manifest_data
|
||||||
from fbt.appmanifest import FlipperApplication, FlipperManifestException
|
from fbt.appmanifest import FlipperApplication, FlipperManifestException, FlipperAppType
|
||||||
from fbt.sdk.cache import SdkCache
|
from fbt.sdk.cache import SdkCache
|
||||||
from fbt.util import extract_abs_dir_path
|
from fbt.util import extract_abs_dir_path
|
||||||
|
|
||||||
@ -32,6 +32,7 @@ def BuildAppElf(env, app):
|
|||||||
ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR")
|
ext_apps_work_dir = env.subst("$EXT_APPS_WORK_DIR")
|
||||||
app_work_dir = os.path.join(ext_apps_work_dir, app.appid)
|
app_work_dir = os.path.join(ext_apps_work_dir, app.appid)
|
||||||
|
|
||||||
|
env.SetDefault(_APP_ICONS=[])
|
||||||
env.VariantDir(app_work_dir, app._appdir, duplicate=False)
|
env.VariantDir(app_work_dir, app._appdir, duplicate=False)
|
||||||
|
|
||||||
app_env = env.Clone(FAP_SRC_DIR=app._appdir, FAP_WORK_DIR=app_work_dir)
|
app_env = env.Clone(FAP_SRC_DIR=app._appdir, FAP_WORK_DIR=app_work_dir)
|
||||||
@ -63,6 +64,7 @@ def BuildAppElf(env, app):
|
|||||||
icon_bundle_name=f"{app.fap_icon_assets_symbol if app.fap_icon_assets_symbol else app.appid }_icons",
|
icon_bundle_name=f"{app.fap_icon_assets_symbol if app.fap_icon_assets_symbol else app.appid }_icons",
|
||||||
)
|
)
|
||||||
app_env.Alias("_fap_icons", fap_icons)
|
app_env.Alias("_fap_icons", fap_icons)
|
||||||
|
env.Append(_APP_ICONS=[fap_icons])
|
||||||
|
|
||||||
private_libs = []
|
private_libs = []
|
||||||
|
|
||||||
@ -232,11 +234,18 @@ def GetExtAppFromPath(env, app_dir):
|
|||||||
return app_artifacts
|
return app_artifacts
|
||||||
|
|
||||||
|
|
||||||
def fap_dist_emitter(target, source, env):
|
def resources_fap_dist_emitter(target, source, env):
|
||||||
target_dir = target[0]
|
target_dir = target[0]
|
||||||
|
|
||||||
target = []
|
target = []
|
||||||
for _, app_artifacts in env["EXT_APPS"].items():
|
for _, app_artifacts in env["EXT_APPS"].items():
|
||||||
|
# We don't deploy example apps & debug tools with SD card resources
|
||||||
|
if (
|
||||||
|
app_artifacts.app.apptype == FlipperAppType.DEBUG
|
||||||
|
or app_artifacts.app.fap_category == "Examples"
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
|
||||||
source.extend(app_artifacts.compact)
|
source.extend(app_artifacts.compact)
|
||||||
target.append(
|
target.append(
|
||||||
target_dir.Dir(app_artifacts.app.fap_category).File(
|
target_dir.Dir(app_artifacts.app.fap_category).File(
|
||||||
@ -247,7 +256,7 @@ def fap_dist_emitter(target, source, env):
|
|||||||
return (target, source)
|
return (target, source)
|
||||||
|
|
||||||
|
|
||||||
def fap_dist_action(target, source, env):
|
def resources_fap_dist_action(target, source, env):
|
||||||
# FIXME
|
# FIXME
|
||||||
target_dir = env.Dir("#/assets/resources/apps")
|
target_dir = env.Dir("#/assets/resources/apps")
|
||||||
|
|
||||||
@ -280,10 +289,10 @@ def generate(env, **kw):
|
|||||||
BUILDERS={
|
BUILDERS={
|
||||||
"FapDist": Builder(
|
"FapDist": Builder(
|
||||||
action=Action(
|
action=Action(
|
||||||
fap_dist_action,
|
resources_fap_dist_action,
|
||||||
"$FAPDISTCOMSTR",
|
"$FAPDISTCOMSTR",
|
||||||
),
|
),
|
||||||
emitter=fap_dist_emitter,
|
emitter=resources_fap_dist_emitter,
|
||||||
),
|
),
|
||||||
"EmbedAppMetadata": Builder(
|
"EmbedAppMetadata": Builder(
|
||||||
action=[
|
action=[
|
||||||
|
@ -11,6 +11,8 @@ Building:
|
|||||||
Build all FAP apps
|
Build all FAP apps
|
||||||
fap_{APPID}, launch_app APPSRC={APPID}:
|
fap_{APPID}, launch_app APPSRC={APPID}:
|
||||||
Build FAP app with appid={APPID}; upload & start it over USB
|
Build FAP app with appid={APPID}; upload & start it over USB
|
||||||
|
fap_deploy:
|
||||||
|
Build and upload all FAP apps over USB
|
||||||
|
|
||||||
Flashing & debugging:
|
Flashing & debugging:
|
||||||
flash, flash_blackmagic, jflash:
|
flash, flash_blackmagic, jflash:
|
||||||
@ -29,6 +31,8 @@ Other:
|
|||||||
run linters
|
run linters
|
||||||
format, format_py:
|
format, format_py:
|
||||||
run code formatters
|
run code formatters
|
||||||
|
firmware_pvs:
|
||||||
|
generate a PVS-Studio report
|
||||||
|
|
||||||
For more targets & info, see documentation/fbt.md
|
For more targets & info, see documentation/fbt.md
|
||||||
"""
|
"""
|
||||||
|
106
scripts/fbt_tools/pvsstudio.py
Normal file
106
scripts/fbt_tools/pvsstudio.py
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
from SCons.Builder import Builder
|
||||||
|
from SCons.Action import Action
|
||||||
|
from SCons.Script import Delete, Mkdir, GetBuildFailures
|
||||||
|
import multiprocessing
|
||||||
|
import webbrowser
|
||||||
|
import atexit
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
__no_browser = False
|
||||||
|
|
||||||
|
|
||||||
|
def _set_browser_action(target, source, env):
|
||||||
|
if env["PVSNOBROWSER"]:
|
||||||
|
global __no_browser
|
||||||
|
__no_browser = True
|
||||||
|
|
||||||
|
|
||||||
|
def emit_pvsreport(target, source, env):
|
||||||
|
target_dir = env["REPORT_DIR"]
|
||||||
|
if env["PLATFORM"] == "win32":
|
||||||
|
# Report generator on Windows emits to a subfolder of given output folder
|
||||||
|
target_dir = target_dir.Dir("fullhtml")
|
||||||
|
return [target_dir.File("index.html")], source
|
||||||
|
|
||||||
|
|
||||||
|
def atexist_handler():
|
||||||
|
global __no_browser
|
||||||
|
if __no_browser:
|
||||||
|
return
|
||||||
|
|
||||||
|
for bf in GetBuildFailures():
|
||||||
|
if bf.node.exists and bf.node.name.endswith(".html"):
|
||||||
|
# macOS
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
subprocess.run(["open", bf.node.abspath])
|
||||||
|
else:
|
||||||
|
webbrowser.open(bf.node.abspath)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def generate(env):
|
||||||
|
env.SetDefault(
|
||||||
|
PVSNCORES=multiprocessing.cpu_count(),
|
||||||
|
PVSOPTIONS=[
|
||||||
|
"@.pvsoptions",
|
||||||
|
"-j${PVSNCORES}",
|
||||||
|
# "--incremental", # kinda broken on PVS side
|
||||||
|
],
|
||||||
|
PVSCONVOPTIONS=[
|
||||||
|
"-a",
|
||||||
|
"GA:1,2,3",
|
||||||
|
"-t",
|
||||||
|
"fullhtml",
|
||||||
|
"--indicate-warnings",
|
||||||
|
],
|
||||||
|
)
|
||||||
|
|
||||||
|
if env["PLATFORM"] == "win32":
|
||||||
|
env.SetDefault(
|
||||||
|
PVSCHECKBIN="CompilerCommandsAnalyzer.exe",
|
||||||
|
PVSCONVBIN="PlogConverter.exe",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
env.SetDefault(
|
||||||
|
PVSCHECKBIN="pvs-studio-analyzer",
|
||||||
|
PVSCONVBIN="plog-converter",
|
||||||
|
)
|
||||||
|
|
||||||
|
if not env["VERBOSE"]:
|
||||||
|
env.SetDefault(
|
||||||
|
PVSCHECKCOMSTR="\tPVS\t${TARGET}",
|
||||||
|
PVSCONVCOMSTR="\tPVSREP\t${TARGET}",
|
||||||
|
)
|
||||||
|
|
||||||
|
env.Append(
|
||||||
|
BUILDERS={
|
||||||
|
"PVSCheck": Builder(
|
||||||
|
action=Action(
|
||||||
|
'${PVSCHECKBIN} analyze ${PVSOPTIONS} -f "${SOURCE}" -o "${TARGET}"',
|
||||||
|
"${PVSCHECKCOMSTR}",
|
||||||
|
),
|
||||||
|
suffix=".log",
|
||||||
|
src_suffix=".json",
|
||||||
|
),
|
||||||
|
"PVSReport": Builder(
|
||||||
|
action=Action(
|
||||||
|
[
|
||||||
|
Delete("${TARGET.dir}"),
|
||||||
|
# PlogConverter.exe and plog-converter have different behavior
|
||||||
|
Mkdir("${TARGET.dir}") if env["PLATFORM"] == "win32" else None,
|
||||||
|
Action(_set_browser_action, None),
|
||||||
|
'${PVSCONVBIN} ${PVSCONVOPTIONS} "${SOURCE}" -o "${REPORT_DIR}"',
|
||||||
|
],
|
||||||
|
"${PVSCONVCOMSTR}",
|
||||||
|
),
|
||||||
|
emitter=emit_pvsreport,
|
||||||
|
src_suffix=".log",
|
||||||
|
),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
atexit.register(atexist_handler)
|
||||||
|
|
||||||
|
|
||||||
|
def exists(env):
|
||||||
|
return True
|
@ -15,6 +15,13 @@ import serial.tools.list_ports as list_ports
|
|||||||
class Main(App):
|
class Main(App):
|
||||||
def init(self):
|
def init(self):
|
||||||
self.parser.add_argument("-p", "--port", help="CDC Port", default="auto")
|
self.parser.add_argument("-p", "--port", help="CDC Port", default="auto")
|
||||||
|
self.parser.add_argument(
|
||||||
|
"-n",
|
||||||
|
"--no-launch",
|
||||||
|
dest="launch_app",
|
||||||
|
action="store_false",
|
||||||
|
help="Don't launch app",
|
||||||
|
)
|
||||||
|
|
||||||
self.parser.add_argument("fap_src_path", help="App file to upload")
|
self.parser.add_argument("fap_src_path", help="App file to upload")
|
||||||
self.parser.add_argument(
|
self.parser.add_argument(
|
||||||
@ -84,7 +91,10 @@ class Main(App):
|
|||||||
self.logger.error(f"Error: upload failed: {storage.last_error}")
|
self.logger.error(f"Error: upload failed: {storage.last_error}")
|
||||||
return -3
|
return -3
|
||||||
|
|
||||||
storage.send_and_wait_eol(f'loader open "Applications" {fap_dst_path}\r')
|
if self.args.launch_app:
|
||||||
|
storage.send_and_wait_eol(
|
||||||
|
f'loader open "Applications" {fap_dst_path}\r'
|
||||||
|
)
|
||||||
result = storage.read.until(storage.CLI_EOL)
|
result = storage.read.until(storage.CLI_EOL)
|
||||||
if len(result):
|
if len(result):
|
||||||
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
|
self.logger.error(f"Unexpected response: {result.decode('ascii')}")
|
||||||
|
@ -43,9 +43,11 @@ fbtenv_restore_env()
|
|||||||
|
|
||||||
PYTHONNOUSERSITE="$SAVED_PYTHONNOUSERSITE";
|
PYTHONNOUSERSITE="$SAVED_PYTHONNOUSERSITE";
|
||||||
PYTHONPATH="$SAVED_PYTHONPATH";
|
PYTHONPATH="$SAVED_PYTHONPATH";
|
||||||
|
PYTHONHOME="$SAVED_PYTHONHOME";
|
||||||
|
|
||||||
unset SAVED_PYTHONNOUSERSITE;
|
unset SAVED_PYTHONNOUSERSITE;
|
||||||
unset SAVED_PYTHONPATH;
|
unset SAVED_PYTHONPATH;
|
||||||
|
unset SAVED_PYTHONHOME;
|
||||||
|
|
||||||
unset SCRIPT_PATH;
|
unset SCRIPT_PATH;
|
||||||
unset FBT_TOOLCHAIN_VERSION;
|
unset FBT_TOOLCHAIN_VERSION;
|
||||||
@ -69,7 +71,7 @@ fbtenv_check_sourced()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbtenv_chck_many_source()
|
fbtenv_check_if_sourced_multiple_times()
|
||||||
{
|
{
|
||||||
if ! echo "${PS1:-""}" | grep -qF "[fbt]"; then
|
if ! echo "${PS1:-""}" | grep -qF "[fbt]"; then
|
||||||
if ! echo "${PROMPT:-""}" | grep -qF "[fbt]"; then
|
if ! echo "${PROMPT:-""}" | grep -qF "[fbt]"; then
|
||||||
@ -285,7 +287,7 @@ fbtenv_main()
|
|||||||
fbtenv_restore_env;
|
fbtenv_restore_env;
|
||||||
return 0;
|
return 0;
|
||||||
fi
|
fi
|
||||||
fbtenv_chck_many_source; # many source it's just a warning
|
fbtenv_check_if_sourced_multiple_times; # many source it's just a warning
|
||||||
fbtenv_check_script_path || return 1;
|
fbtenv_check_script_path || return 1;
|
||||||
fbtenv_check_download_toolchain || return 1;
|
fbtenv_check_download_toolchain || return 1;
|
||||||
fbtenv_set_shell_prompt;
|
fbtenv_set_shell_prompt;
|
||||||
@ -296,9 +298,11 @@ fbtenv_main()
|
|||||||
|
|
||||||
SAVED_PYTHONNOUSERSITE="${PYTHONNOUSERSITE:-""}";
|
SAVED_PYTHONNOUSERSITE="${PYTHONNOUSERSITE:-""}";
|
||||||
SAVED_PYTHONPATH="${PYTHONPATH:-""}";
|
SAVED_PYTHONPATH="${PYTHONPATH:-""}";
|
||||||
|
SAVED_PYTHONHOME="${PYTHONHOME:-""}";
|
||||||
|
|
||||||
PYTHONNOUSERSITE=1;
|
PYTHONNOUSERSITE=1;
|
||||||
PYTHONPATH=;
|
PYTHONPATH=;
|
||||||
|
PYTHONHOME=;
|
||||||
}
|
}
|
||||||
|
|
||||||
fbtenv_main "${1:-""}";
|
fbtenv_main "${1:-""}";
|
||||||
|
@ -81,16 +81,6 @@ vars.AddVariables(
|
|||||||
"7",
|
"7",
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
BoolVariable(
|
|
||||||
"DEBUG_TOOLS",
|
|
||||||
help="Enable debug tools to be built",
|
|
||||||
default=False,
|
|
||||||
),
|
|
||||||
BoolVariable(
|
|
||||||
"FAP_EXAMPLES",
|
|
||||||
help="Enable example applications to be built",
|
|
||||||
default=False,
|
|
||||||
),
|
|
||||||
(
|
(
|
||||||
"DIST_SUFFIX",
|
"DIST_SUFFIX",
|
||||||
"Suffix for binaries in build output for dist targets",
|
"Suffix for binaries in build output for dist targets",
|
||||||
@ -242,9 +232,15 @@ vars.AddVariables(
|
|||||||
("applications/system", False),
|
("applications/system", False),
|
||||||
("applications/debug", False),
|
("applications/debug", False),
|
||||||
("applications/plugins", False),
|
("applications/plugins", False),
|
||||||
|
("applications/examples", False),
|
||||||
("applications_user", False),
|
("applications_user", False),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
BoolVariable(
|
||||||
|
"PVSNOBROWSER",
|
||||||
|
help="Don't open browser after generating error repots",
|
||||||
|
default=False,
|
||||||
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
Return("vars")
|
Return("vars")
|
||||||
|
@ -65,9 +65,8 @@ class FlipperExtAppBuildArtifacts:
|
|||||||
apps_to_build_as_faps = [
|
apps_to_build_as_faps = [
|
||||||
FlipperAppType.PLUGIN,
|
FlipperAppType.PLUGIN,
|
||||||
FlipperAppType.EXTERNAL,
|
FlipperAppType.EXTERNAL,
|
||||||
|
FlipperAppType.DEBUG,
|
||||||
]
|
]
|
||||||
if appenv["DEBUG_TOOLS"]:
|
|
||||||
apps_to_build_as_faps.append(FlipperAppType.DEBUG)
|
|
||||||
|
|
||||||
known_extapps = [
|
known_extapps = [
|
||||||
app
|
app
|
||||||
@ -143,6 +142,11 @@ sdk_apisyms = appenv.SDKSymGenerator(
|
|||||||
"${BUILD_DIR}/assets/compiled/symbols.h", appenv["SDK_DEFINITION"]
|
"${BUILD_DIR}/assets/compiled/symbols.h", appenv["SDK_DEFINITION"]
|
||||||
)
|
)
|
||||||
Alias("api_syms", sdk_apisyms)
|
Alias("api_syms", sdk_apisyms)
|
||||||
|
ENV.Replace(
|
||||||
|
SDK_APISYMS=sdk_apisyms,
|
||||||
|
_APP_ICONS=appenv["_APP_ICONS"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
if appenv["FORCE"]:
|
if appenv["FORCE"]:
|
||||||
appenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms)
|
appenv.AlwaysBuild(sdk_source, sdk_tree, sdk_apicheck, sdk_apisyms)
|
||||||
|
Loading…
Reference in New Issue
Block a user