[FL-1250, FL-1252, FL-1323, FL-1324] New IRDA Application (part 1) (#497)
* Add new IrdaApp (half ready), add ButtonMenu * Fix NEC's extension * clang-format * Fix leak * Add submenu optional header * IRDA: add Edit button * clang-format * IrdaApp: Fix scene flow * Add IRDA NEC extended protocol * IRDA: Add address/command length Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
parent
d040515f84
commit
31c31db479
6
.gitignore
vendored
6
.gitignore
vendored
@ -1,4 +1,10 @@
|
|||||||
*.swp
|
*.swp
|
||||||
|
*.gdb_history
|
||||||
|
|
||||||
|
|
||||||
|
# LSP
|
||||||
|
.cache
|
||||||
|
compile_commands.json
|
||||||
|
|
||||||
# JetBrains IDEs
|
# JetBrains IDEs
|
||||||
.idea/
|
.idea/
|
||||||
|
@ -202,6 +202,19 @@ void canvas_draw_box(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_
|
|||||||
u8g2_DrawBox(&canvas->fb, x, y, width, height);
|
u8g2_DrawBox(&canvas->fb, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void canvas_draw_rbox(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t x,
|
||||||
|
uint8_t y,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t height,
|
||||||
|
uint8_t radius) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
x += canvas->offset_x;
|
||||||
|
y += canvas->offset_y;
|
||||||
|
u8g2_DrawRBox(&canvas->fb, x, y, width, height, radius);
|
||||||
|
}
|
||||||
|
|
||||||
void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint8_t height) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
x += canvas->offset_x;
|
x += canvas->offset_x;
|
||||||
@ -209,6 +222,19 @@ void canvas_draw_frame(Canvas* canvas, uint8_t x, uint8_t y, uint8_t width, uint
|
|||||||
u8g2_DrawFrame(&canvas->fb, x, y, width, height);
|
u8g2_DrawFrame(&canvas->fb, x, y, width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void canvas_draw_rframe(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t x,
|
||||||
|
uint8_t y,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t height,
|
||||||
|
uint8_t radius) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
x += canvas->offset_x;
|
||||||
|
y += canvas->offset_y;
|
||||||
|
u8g2_DrawRFrame(&canvas->fb, x, y, width, height, radius);
|
||||||
|
}
|
||||||
|
|
||||||
void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
|
void canvas_draw_line(Canvas* canvas, uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
x1 += canvas->offset_x;
|
x1 += canvas->offset_x;
|
||||||
|
@ -157,6 +157,28 @@ void canvas_draw_glyph(Canvas* canvas, uint8_t x, uint8_t y, uint16_t ch);
|
|||||||
*/
|
*/
|
||||||
void canvas_set_bitmap_mode(Canvas* canvas, bool alpha);
|
void canvas_set_bitmap_mode(Canvas* canvas, bool alpha);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw rounded-corner frame of width, height at x,y, with round value raduis
|
||||||
|
*/
|
||||||
|
void canvas_draw_rframe(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t x,
|
||||||
|
uint8_t y,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t height,
|
||||||
|
uint8_t radius);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw rounded-corner box of width, height at x,y, with round value raduis
|
||||||
|
*/
|
||||||
|
void canvas_draw_rbox(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t x,
|
||||||
|
uint8_t y,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t height,
|
||||||
|
uint8_t radius);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
#include "elements.h"
|
#include "elements.h"
|
||||||
|
#include "gui/canvas.h"
|
||||||
#include <assets_icons.h>
|
#include <assets_icons.h>
|
||||||
#include <gui/icon_i.h>
|
#include <gui/icon_i.h>
|
||||||
|
#include <m-string.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include "canvas_i.h"
|
#include "canvas_i.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -44,7 +46,7 @@ void elements_scrollbar(Canvas* canvas, uint8_t pos, uint8_t total) {
|
|||||||
}
|
}
|
||||||
// Position block
|
// Position block
|
||||||
if(total) {
|
if(total) {
|
||||||
uint8_t block_h = ((float)height) / total;
|
float block_h = ((float)height) / total;
|
||||||
canvas_draw_box(canvas, width - 3, block_h * pos, 3, MAX(block_h, 1));
|
canvas_draw_box(canvas, width - 3, block_h * pos, 3, MAX(block_h, 1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,13 +251,17 @@ void elements_slightly_rounded_frame(
|
|||||||
uint8_t width,
|
uint8_t width,
|
||||||
uint8_t height) {
|
uint8_t height) {
|
||||||
furi_assert(canvas);
|
furi_assert(canvas);
|
||||||
canvas_draw_frame(canvas, x, y, width, height);
|
canvas_draw_rframe(canvas, x, y, width, height, 1);
|
||||||
canvas_invert_color(canvas);
|
}
|
||||||
canvas_draw_dot(canvas, x, y);
|
|
||||||
canvas_draw_dot(canvas, x + width - 1, y + height - 1);
|
void elements_slightly_rounded_box(
|
||||||
canvas_draw_dot(canvas, x + width - 1, y);
|
Canvas* canvas,
|
||||||
canvas_draw_dot(canvas, x, y + height - 1);
|
uint8_t x,
|
||||||
canvas_invert_color(canvas);
|
uint8_t y,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t height) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
canvas_draw_rbox(canvas, x, y, width, height, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width) {
|
void elements_string_fit_width(Canvas* canvas, string_t string, uint8_t width) {
|
||||||
|
@ -106,6 +106,18 @@ void elements_slightly_rounded_frame(
|
|||||||
uint8_t width,
|
uint8_t width,
|
||||||
uint8_t height);
|
uint8_t height);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Draw slightly rounded box
|
||||||
|
* @param x, y - top left corner coordinates
|
||||||
|
* @param width, height - size of box
|
||||||
|
*/
|
||||||
|
void elements_slightly_rounded_box(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t x,
|
||||||
|
uint8_t y,
|
||||||
|
uint8_t width,
|
||||||
|
uint8_t height);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Trim string buffer to fit width in pixels
|
* Trim string buffer to fit width in pixels
|
||||||
* @param string - string to trim
|
* @param string - string to trim
|
||||||
|
288
applications/gui/modules/button_menu.c
Normal file
288
applications/gui/modules/button_menu.c
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
#include "button_menu.h"
|
||||||
|
#include "gui/canvas.h"
|
||||||
|
#include "gui/elements.h"
|
||||||
|
#include <m-array.h>
|
||||||
|
#include <furi.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define ITEM_FIRST_OFFSET 17
|
||||||
|
#define ITEM_NEXT_OFFSET 4
|
||||||
|
#define ITEM_HEIGHT 14
|
||||||
|
#define ITEM_WIDTH 64
|
||||||
|
#define BUTTONS_PER_SCREEN 6
|
||||||
|
|
||||||
|
struct ButtonMenuItem {
|
||||||
|
const char* label;
|
||||||
|
int32_t index;
|
||||||
|
ButtonMenuItemCallback callback;
|
||||||
|
ButtonMenuItemType type;
|
||||||
|
void* callback_context;
|
||||||
|
};
|
||||||
|
|
||||||
|
ARRAY_DEF(ButtonMenuItemArray, ButtonMenuItem, M_POD_OPLIST);
|
||||||
|
|
||||||
|
struct ButtonMenu {
|
||||||
|
View* view;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ButtonMenuItemArray_t items;
|
||||||
|
uint8_t position;
|
||||||
|
const char* header;
|
||||||
|
} ButtonMenuModel;
|
||||||
|
|
||||||
|
static void button_menu_draw_control_button(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t item_position,
|
||||||
|
const char* text,
|
||||||
|
bool selected) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
furi_assert(text);
|
||||||
|
|
||||||
|
uint8_t item_x = 0;
|
||||||
|
uint8_t item_y = ITEM_FIRST_OFFSET + (item_position * (ITEM_HEIGHT + ITEM_NEXT_OFFSET));
|
||||||
|
|
||||||
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
|
||||||
|
if(selected) {
|
||||||
|
elements_slightly_rounded_box(canvas, item_x, item_y, ITEM_WIDTH, ITEM_HEIGHT);
|
||||||
|
canvas_set_color(canvas, ColorWhite);
|
||||||
|
}
|
||||||
|
canvas_draw_str_aligned(
|
||||||
|
canvas,
|
||||||
|
item_x + (ITEM_WIDTH / 2),
|
||||||
|
item_y + (ITEM_HEIGHT / 2),
|
||||||
|
AlignCenter,
|
||||||
|
AlignCenter,
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_menu_draw_common_button(
|
||||||
|
Canvas* canvas,
|
||||||
|
uint8_t item_position,
|
||||||
|
const char* text,
|
||||||
|
bool selected) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
furi_assert(text);
|
||||||
|
|
||||||
|
uint8_t item_x = 0;
|
||||||
|
uint8_t item_y = ITEM_FIRST_OFFSET + (item_position * (ITEM_HEIGHT + ITEM_NEXT_OFFSET));
|
||||||
|
|
||||||
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
|
||||||
|
if(selected) {
|
||||||
|
canvas_draw_rbox(canvas, item_x, item_y, ITEM_WIDTH, ITEM_HEIGHT, 5);
|
||||||
|
canvas_set_color(canvas, ColorWhite);
|
||||||
|
} else {
|
||||||
|
canvas_draw_rframe(canvas, item_x, item_y, ITEM_WIDTH, ITEM_HEIGHT, 5);
|
||||||
|
}
|
||||||
|
canvas_draw_str_aligned(
|
||||||
|
canvas,
|
||||||
|
item_x + (ITEM_WIDTH / 2),
|
||||||
|
item_y + (ITEM_HEIGHT / 2),
|
||||||
|
AlignCenter,
|
||||||
|
AlignCenter,
|
||||||
|
text);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_menu_view_draw_callback(Canvas* canvas, void* _model) {
|
||||||
|
furi_assert(canvas);
|
||||||
|
furi_assert(_model);
|
||||||
|
|
||||||
|
ButtonMenuModel* model = (ButtonMenuModel*)_model;
|
||||||
|
|
||||||
|
canvas_clear(canvas);
|
||||||
|
canvas_set_font(canvas, FontSecondary);
|
||||||
|
|
||||||
|
uint8_t item_position = 0;
|
||||||
|
int8_t active_screen = model->position / BUTTONS_PER_SCREEN;
|
||||||
|
size_t items_size = ButtonMenuItemArray_size(model->items);
|
||||||
|
int8_t max_screen = ((int16_t)items_size - 1) / BUTTONS_PER_SCREEN;
|
||||||
|
ButtonMenuItemArray_it_t it;
|
||||||
|
|
||||||
|
if(active_screen > 0) {
|
||||||
|
canvas_draw_icon_name(canvas, 28, 1, I_IrdaArrowUp_4x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(max_screen > active_screen) {
|
||||||
|
canvas_draw_icon_name(canvas, 28, 123, I_IrdaArrowDown_4x8);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas_draw_str_aligned(canvas, 32, 10, AlignCenter, AlignCenter, model->header);
|
||||||
|
|
||||||
|
for(ButtonMenuItemArray_it(it, model->items); !ButtonMenuItemArray_end_p(it);
|
||||||
|
ButtonMenuItemArray_next(it), ++item_position) {
|
||||||
|
if(active_screen == (item_position / BUTTONS_PER_SCREEN)) {
|
||||||
|
if(ButtonMenuItemArray_cref(it)->type == ButtonMenuItemTypeControl) {
|
||||||
|
button_menu_draw_control_button(
|
||||||
|
canvas,
|
||||||
|
item_position % BUTTONS_PER_SCREEN,
|
||||||
|
ButtonMenuItemArray_cref(it)->label,
|
||||||
|
(item_position == model->position));
|
||||||
|
} else if(ButtonMenuItemArray_cref(it)->type == ButtonMenuItemTypeCommon) {
|
||||||
|
button_menu_draw_common_button(
|
||||||
|
canvas,
|
||||||
|
item_position % BUTTONS_PER_SCREEN,
|
||||||
|
ButtonMenuItemArray_cref(it)->label,
|
||||||
|
(item_position == model->position));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_menu_process_up(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
if(model->position > 0) {
|
||||||
|
model->position--;
|
||||||
|
} else {
|
||||||
|
model->position = ButtonMenuItemArray_size(model->items) - 1;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_menu_process_down(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
if(model->position < (ButtonMenuItemArray_size(model->items) - 1)) {
|
||||||
|
model->position++;
|
||||||
|
} else {
|
||||||
|
model->position = 0;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static void button_menu_process_ok(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
ButtonMenuItem* item = NULL;
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
if(model->position < (ButtonMenuItemArray_size(model->items))) {
|
||||||
|
item = ButtonMenuItemArray_get(model->items, model->position);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if(item && item->callback) {
|
||||||
|
item->callback(item->callback_context, item->index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool button_menu_view_input_callback(InputEvent* event, void* context) {
|
||||||
|
furi_assert(event);
|
||||||
|
|
||||||
|
ButtonMenu* button_menu = context;
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == InputTypeShort) {
|
||||||
|
switch(event->key) {
|
||||||
|
case InputKeyUp:
|
||||||
|
consumed = true;
|
||||||
|
button_menu_process_up(button_menu);
|
||||||
|
break;
|
||||||
|
case InputKeyDown:
|
||||||
|
consumed = true;
|
||||||
|
button_menu_process_down(button_menu);
|
||||||
|
break;
|
||||||
|
case InputKeyOk:
|
||||||
|
consumed = true;
|
||||||
|
button_menu_process_ok(button_menu);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
View* button_menu_get_view(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
return button_menu->view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void button_menu_clean(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
ButtonMenuItemArray_clean(model->items);
|
||||||
|
model->position = 0;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void button_menu_set_header(ButtonMenu* button_menu, const char* header) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
model->header = header;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonMenuItem* button_menu_add_item(
|
||||||
|
ButtonMenu* button_menu,
|
||||||
|
const char* label,
|
||||||
|
int32_t index,
|
||||||
|
ButtonMenuItemCallback callback,
|
||||||
|
ButtonMenuItemType type,
|
||||||
|
void* callback_context) {
|
||||||
|
ButtonMenuItem* item = NULL;
|
||||||
|
furi_assert(label);
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
item = ButtonMenuItemArray_push_new(model->items);
|
||||||
|
item->label = label;
|
||||||
|
item->index = index;
|
||||||
|
item->type = type;
|
||||||
|
item->callback = callback;
|
||||||
|
item->callback_context = callback_context;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonMenu* button_menu_alloc(void) {
|
||||||
|
ButtonMenu* button_menu = furi_alloc(sizeof(ButtonMenu));
|
||||||
|
button_menu->view = view_alloc();
|
||||||
|
view_set_orientation(button_menu->view, ViewOrientationVertical);
|
||||||
|
view_set_context(button_menu->view, button_menu);
|
||||||
|
view_allocate_model(button_menu->view, ViewModelTypeLocking, sizeof(ButtonMenuModel));
|
||||||
|
view_set_draw_callback(button_menu->view, button_menu_view_draw_callback);
|
||||||
|
view_set_input_callback(button_menu->view, button_menu_view_input_callback);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
ButtonMenuItemArray_init(model->items);
|
||||||
|
model->position = 0;
|
||||||
|
model->header = NULL;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return button_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
void button_menu_free(ButtonMenu* button_menu) {
|
||||||
|
furi_assert(button_menu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
button_menu->view, (ButtonMenuModel * model) {
|
||||||
|
ButtonMenuItemArray_clear(model->items);
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
view_free(button_menu->view);
|
||||||
|
free(button_menu);
|
||||||
|
}
|
73
applications/gui/modules/button_menu.h
Normal file
73
applications/gui/modules/button_menu.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <gui/view.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* ButtonMenu anonymous structure */
|
||||||
|
typedef struct ButtonMenu ButtonMenu;
|
||||||
|
typedef struct ButtonMenuItem ButtonMenuItem;
|
||||||
|
|
||||||
|
/* Callback for any button menu actions */
|
||||||
|
typedef void (*ButtonMenuItemCallback)(void* context, int32_t index);
|
||||||
|
|
||||||
|
/* Type of button. Difference in drawing buttons. */
|
||||||
|
typedef enum {
|
||||||
|
ButtonMenuItemTypeCommon,
|
||||||
|
ButtonMenuItemTypeControl,
|
||||||
|
} ButtonMenuItemType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get button menu view
|
||||||
|
* @param button_menu - ButtonMenu instance
|
||||||
|
* @return View instance that can be used for embedding
|
||||||
|
*/
|
||||||
|
View* button_menu_get_view(ButtonMenu* button_menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clean button menu
|
||||||
|
* @param button_menu - ButtonMenu instance
|
||||||
|
*/
|
||||||
|
void button_menu_clean(ButtonMenu* button_menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Add item to button menu instance
|
||||||
|
* @param button_menu - ButtonMenu instance
|
||||||
|
* @param label - text inside new button
|
||||||
|
* @param index - value to distinct between buttons inside ButtonMenuItemCallback
|
||||||
|
* @param type - type of button to create. Differ by button drawing.
|
||||||
|
* Control buttons have no frames, and have more squared borders.
|
||||||
|
* @return pointer to just-created item
|
||||||
|
*/
|
||||||
|
ButtonMenuItem* button_menu_add_item(
|
||||||
|
ButtonMenu* button_menu,
|
||||||
|
const char* label,
|
||||||
|
int32_t index,
|
||||||
|
ButtonMenuItemCallback callback,
|
||||||
|
ButtonMenuItemType type,
|
||||||
|
void* callback_context);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Allocate and initialize new instance of ButtonMenu model
|
||||||
|
* @return just-created ButtonMenu model
|
||||||
|
*/
|
||||||
|
ButtonMenu* button_menu_alloc(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free ButtonMenu element
|
||||||
|
* @param button_menu - ButtonMenu instance
|
||||||
|
*/
|
||||||
|
void button_menu_free(ButtonMenu* button_menu);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set ButtonMenu header on top of canvas
|
||||||
|
* @param button_menu - ButtonMenu instance
|
||||||
|
* @param header - header on the top of button menu
|
||||||
|
*/
|
||||||
|
void button_menu_set_header(ButtonMenu* button_menu, const char* header);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,7 +1,9 @@
|
|||||||
#include "submenu.h"
|
#include "submenu.h"
|
||||||
|
#include "gui/canvas.h"
|
||||||
#include <m-array.h>
|
#include <m-array.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <gui/elements.h>
|
#include <gui/elements.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
struct SubmenuItem {
|
struct SubmenuItem {
|
||||||
const char* label;
|
const char* label;
|
||||||
@ -18,6 +20,7 @@ struct Submenu {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SubmenuItemArray_t items;
|
SubmenuItemArray_t items;
|
||||||
|
const char* header;
|
||||||
uint8_t position;
|
uint8_t position;
|
||||||
uint8_t window_position;
|
uint8_t window_position;
|
||||||
} SubmenuModel;
|
} SubmenuModel;
|
||||||
@ -33,34 +36,39 @@ static void submenu_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
const uint8_t item_width = 123;
|
const uint8_t item_width = 123;
|
||||||
|
|
||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
canvas_set_font(canvas, FontSecondary);
|
canvas_set_font(canvas, FontPrimary);
|
||||||
|
|
||||||
uint8_t position = 0;
|
uint8_t position = 0;
|
||||||
SubmenuItemArray_it_t it;
|
SubmenuItemArray_it_t it;
|
||||||
|
|
||||||
|
if(model->header) {
|
||||||
|
canvas_draw_str(canvas, 4, 11, model->header);
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas_set_font(canvas, FontSecondary);
|
||||||
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
for(SubmenuItemArray_it(it, model->items); !SubmenuItemArray_end_p(it);
|
||||||
SubmenuItemArray_next(it)) {
|
SubmenuItemArray_next(it)) {
|
||||||
uint8_t item_position = position - model->window_position;
|
uint8_t item_position = position - model->window_position;
|
||||||
|
uint8_t elements_on_screen = model->header ? 3 : 4;
|
||||||
|
uint8_t y_offset = model->header ? 16 : 0;
|
||||||
|
|
||||||
if(item_position < 4) {
|
if(item_position < elements_on_screen) {
|
||||||
if(position == model->position) {
|
if(position == model->position) {
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
canvas_draw_box(
|
elements_slightly_rounded_box(
|
||||||
canvas, 0, (item_position * item_height) + 1, item_width, item_height - 2);
|
canvas,
|
||||||
|
0,
|
||||||
|
y_offset + (item_position * item_height) + 1,
|
||||||
|
item_width,
|
||||||
|
item_height - 2);
|
||||||
canvas_set_color(canvas, ColorWhite);
|
canvas_set_color(canvas, ColorWhite);
|
||||||
|
|
||||||
canvas_draw_dot(canvas, 0, (item_position * item_height) + 1);
|
|
||||||
canvas_draw_dot(canvas, 0, (item_position * item_height) + item_height - 2);
|
|
||||||
canvas_draw_dot(canvas, item_width - 1, (item_position * item_height) + 1);
|
|
||||||
canvas_draw_dot(
|
|
||||||
canvas, item_width - 1, (item_position * item_height) + item_height - 2);
|
|
||||||
} else {
|
} else {
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
}
|
}
|
||||||
canvas_draw_str(
|
canvas_draw_str(
|
||||||
canvas,
|
canvas,
|
||||||
6,
|
6,
|
||||||
(item_position * item_height) + item_height - 4,
|
y_offset + (item_position * item_height) + item_height - 4,
|
||||||
SubmenuItemArray_cref(it)->label);
|
SubmenuItemArray_cref(it)->label);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,6 +118,7 @@ Submenu* submenu_alloc() {
|
|||||||
SubmenuItemArray_init(model->items);
|
SubmenuItemArray_init(model->items);
|
||||||
model->position = 0;
|
model->position = 0;
|
||||||
model->window_position = 0;
|
model->window_position = 0;
|
||||||
|
model->header = NULL;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -164,6 +173,7 @@ void submenu_clean(Submenu* submenu) {
|
|||||||
SubmenuItemArray_clean(model->items);
|
SubmenuItemArray_clean(model->items);
|
||||||
model->position = 0;
|
model->position = 0;
|
||||||
model->window_position = 0;
|
model->window_position = 0;
|
||||||
|
model->header = NULL;
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -207,15 +217,17 @@ void submenu_set_selected_item(Submenu* submenu, uint32_t index) {
|
|||||||
void submenu_process_up(Submenu* submenu) {
|
void submenu_process_up(Submenu* submenu) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
submenu->view, (SubmenuModel * model) {
|
submenu->view, (SubmenuModel * model) {
|
||||||
|
uint8_t elements_on_screen = model->header ? 3 : 4;
|
||||||
if(model->position > 0) {
|
if(model->position > 0) {
|
||||||
model->position--;
|
model->position--;
|
||||||
if((model->position - model->window_position) < 1 && model->window_position > 0) {
|
if(((model->position - model->window_position) < 1) &&
|
||||||
|
model->window_position > 0) {
|
||||||
model->window_position--;
|
model->window_position--;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
model->position = SubmenuItemArray_size(model->items) - 1;
|
model->position = SubmenuItemArray_size(model->items) - 1;
|
||||||
if(model->position > 3) {
|
if(model->position > (elements_on_screen - 1)) {
|
||||||
model->window_position = model->position - 3;
|
model->window_position = model->position - (elements_on_screen - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -225,10 +237,12 @@ void submenu_process_up(Submenu* submenu) {
|
|||||||
void submenu_process_down(Submenu* submenu) {
|
void submenu_process_down(Submenu* submenu) {
|
||||||
with_view_model(
|
with_view_model(
|
||||||
submenu->view, (SubmenuModel * model) {
|
submenu->view, (SubmenuModel * model) {
|
||||||
|
uint8_t elements_on_screen = model->header ? 3 : 4;
|
||||||
if(model->position < (SubmenuItemArray_size(model->items) - 1)) {
|
if(model->position < (SubmenuItemArray_size(model->items) - 1)) {
|
||||||
model->position++;
|
model->position++;
|
||||||
if((model->position - model->window_position) > 2 &&
|
if((model->position - model->window_position) > (elements_on_screen - 2) &&
|
||||||
model->window_position < (SubmenuItemArray_size(model->items) - 4)) {
|
model->window_position <
|
||||||
|
(SubmenuItemArray_size(model->items) - elements_on_screen)) {
|
||||||
model->window_position++;
|
model->window_position++;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -254,3 +268,13 @@ void submenu_process_ok(Submenu* submenu) {
|
|||||||
item->callback(item->callback_context, item->index);
|
item->callback(item->callback_context, item->index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void submenu_set_header(Submenu* submenu, const char* header) {
|
||||||
|
furi_assert(submenu);
|
||||||
|
|
||||||
|
with_view_model(
|
||||||
|
submenu->view, (SubmenuModel * model) {
|
||||||
|
model->header = header;
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
@ -16,12 +16,6 @@ typedef void (*SubmenuItemCallback)(void* context, uint32_t index);
|
|||||||
*/
|
*/
|
||||||
Submenu* submenu_alloc();
|
Submenu* submenu_alloc();
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Allocate and initialize submenu for vertical display
|
|
||||||
* This submenu is used to select one option
|
|
||||||
*/
|
|
||||||
Submenu* submenu_vertical_alloc();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Deinitialize and free submenu
|
* @brief Deinitialize and free submenu
|
||||||
* @param submenu - Submenu instance
|
* @param submenu - Submenu instance
|
||||||
@ -64,6 +58,13 @@ void submenu_clean(Submenu* submenu);
|
|||||||
*/
|
*/
|
||||||
void submenu_set_selected_item(Submenu* submenu, uint32_t index);
|
void submenu_set_selected_item(Submenu* submenu, uint32_t index);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set optional header for submenu
|
||||||
|
* @param submenu - submenu entity
|
||||||
|
* @param header - header to set
|
||||||
|
*/
|
||||||
|
void submenu_set_header(Submenu* submenu, const char* header);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
26
applications/irda/irda-app-event.hpp
Normal file
26
applications/irda/irda-app-event.hpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <irda.h>
|
||||||
|
#include <gui/modules/dialog_ex.h>
|
||||||
|
|
||||||
|
class IrdaAppEvent {
|
||||||
|
public:
|
||||||
|
enum class Type : uint8_t {
|
||||||
|
Tick,
|
||||||
|
Back,
|
||||||
|
MenuSelected,
|
||||||
|
DialogExSelected,
|
||||||
|
NextScene,
|
||||||
|
IrdaMessageReceived,
|
||||||
|
TextEditDone,
|
||||||
|
PopupTimer,
|
||||||
|
};
|
||||||
|
|
||||||
|
union {
|
||||||
|
int32_t menu_index;
|
||||||
|
DialogExResult dialog_ex_result;
|
||||||
|
} payload;
|
||||||
|
|
||||||
|
Type type;
|
||||||
|
};
|
||||||
|
|
46
applications/irda/irda-app-receiver.cpp
Normal file
46
applications/irda/irda-app-receiver.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "irda-app.hpp"
|
||||||
|
#include "irda.h"
|
||||||
|
#include <api-hal-irda.h>
|
||||||
|
|
||||||
|
void IrdaAppSignalReceiver::irda_rx_callback(void* ctx, bool level, uint32_t duration) {
|
||||||
|
IrdaAppEvent event;
|
||||||
|
const IrdaMessage* irda_message;
|
||||||
|
IrdaAppSignalReceiver* this_ = static_cast<IrdaAppSignalReceiver*>(ctx);
|
||||||
|
|
||||||
|
irda_message = irda_decode(this_->decoder, level, duration);
|
||||||
|
if(irda_message) {
|
||||||
|
this_->capture_stop();
|
||||||
|
this_->message = *irda_message;
|
||||||
|
event.type = IrdaAppEvent::Type::IrdaMessageReceived;
|
||||||
|
osStatus_t result = osMessageQueuePut(this_->event_queue, &event, 0, 0);
|
||||||
|
furi_check(result == osOK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaAppSignalReceiver::IrdaAppSignalReceiver(void)
|
||||||
|
: decoder(irda_alloc_decoder()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaAppSignalReceiver::~IrdaAppSignalReceiver() {
|
||||||
|
api_hal_irda_rx_irq_deinit();
|
||||||
|
irda_free_decoder(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSignalReceiver::capture_once_start(osMessageQueueId_t queue) {
|
||||||
|
event_queue = queue;
|
||||||
|
irda_reset_decoder(decoder);
|
||||||
|
api_hal_irda_rx_irq_init();
|
||||||
|
api_hal_irda_rx_irq_set_callback(IrdaAppSignalReceiver::irda_rx_callback, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSignalReceiver::capture_stop(void) {
|
||||||
|
api_hal_irda_rx_irq_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaMessage* IrdaAppSignalReceiver::get_last_message(void) {
|
||||||
|
return &message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSignalReceiver::send_message(const IrdaMessage* message) {
|
||||||
|
irda_send(message, 1);
|
||||||
|
}
|
19
applications/irda/irda-app-receiver.hpp
Normal file
19
applications/irda/irda-app-receiver.hpp
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#include <furi.h>
|
||||||
|
#include <irda.h>
|
||||||
|
|
||||||
|
class IrdaAppSignalReceiver {
|
||||||
|
public:
|
||||||
|
IrdaAppSignalReceiver(void);
|
||||||
|
~IrdaAppSignalReceiver(void);
|
||||||
|
void capture_once_start(osMessageQueueId_t event_queue);
|
||||||
|
void capture_stop(void);
|
||||||
|
IrdaMessage* get_last_message(void);
|
||||||
|
void send_message(const IrdaMessage* message);
|
||||||
|
|
||||||
|
private:
|
||||||
|
osMessageQueueId_t event_queue;
|
||||||
|
static void irda_rx_callback(void* ctx, bool level, uint32_t duration);
|
||||||
|
IrdaHandler* decoder;
|
||||||
|
IrdaMessage message;
|
||||||
|
};
|
||||||
|
|
130
applications/irda/irda-app-remote-manager.cpp
Normal file
130
applications/irda/irda-app-remote-manager.cpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#include "irda-app-remote-manager.hpp"
|
||||||
|
#include "furi.h"
|
||||||
|
#include <string>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
IrdaAppRemoteManager::IrdaAppRemoteManager() {
|
||||||
|
// Read from api-hal-storage, and fill remotes
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::string default_remote_name = "remote";
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::add_button(const char* button_name, const IrdaMessage* message) {
|
||||||
|
remotes[current_remote_index].buttons.emplace_back(button_name, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::add_remote_with_button(
|
||||||
|
const char* button_name,
|
||||||
|
const IrdaMessage* message) {
|
||||||
|
bool found = true;
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
// find first free common name for remote
|
||||||
|
do {
|
||||||
|
found = false;
|
||||||
|
++i;
|
||||||
|
for(const auto& it : remotes) {
|
||||||
|
if(it.name == (default_remote_name + std::to_string(i))) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} while(found);
|
||||||
|
|
||||||
|
remotes.emplace_back(default_remote_name + std::to_string(i));
|
||||||
|
current_remote_index = remotes.size() - 1;
|
||||||
|
add_button(button_name, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaAppRemote::IrdaAppRemote(std::string name)
|
||||||
|
: name(name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> IrdaAppRemoteManager::get_button_list(void) const {
|
||||||
|
std::vector<std::string> name_vector;
|
||||||
|
auto remote = remotes[current_remote_index];
|
||||||
|
name_vector.reserve(remote.buttons.size());
|
||||||
|
|
||||||
|
for(const auto& it : remote.buttons) {
|
||||||
|
name_vector.emplace_back(it.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy elision
|
||||||
|
return name_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> IrdaAppRemoteManager::get_remote_list() const {
|
||||||
|
std::vector<std::string> name_vector;
|
||||||
|
name_vector.reserve(remotes.size());
|
||||||
|
|
||||||
|
for(const auto& it : remotes) {
|
||||||
|
name_vector.push_back(it.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy elision
|
||||||
|
return name_vector;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IrdaAppRemoteManager::get_current_remote(void) const {
|
||||||
|
return current_remote_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IrdaAppRemoteManager::get_current_button(void) const {
|
||||||
|
return current_button_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemote::add_button(
|
||||||
|
size_t remote_index,
|
||||||
|
const char* button_name,
|
||||||
|
const IrdaMessage* message) {
|
||||||
|
buttons.emplace_back(button_name, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
const IrdaMessage* IrdaAppRemoteManager::get_button_data(size_t button_index) const {
|
||||||
|
furi_check(remotes[current_remote_index].buttons.size() > button_index);
|
||||||
|
auto& b = remotes[current_remote_index].buttons.at(button_index);
|
||||||
|
return &b.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::set_current_remote(size_t index) {
|
||||||
|
furi_check(index < remotes.size());
|
||||||
|
current_remote_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::set_current_button(size_t index) {
|
||||||
|
furi_check(current_remote_index < remotes.size());
|
||||||
|
furi_check(index < remotes[current_remote_index].buttons.size());
|
||||||
|
current_button_index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::delete_current_remote() {
|
||||||
|
remotes.erase(remotes.begin() + current_remote_index);
|
||||||
|
current_remote_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::delete_current_button() {
|
||||||
|
auto& buttons = remotes[current_remote_index].buttons;
|
||||||
|
buttons.erase(buttons.begin() + current_button_index);
|
||||||
|
current_button_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string IrdaAppRemoteManager::get_current_button_name() {
|
||||||
|
auto buttons = remotes[current_remote_index].buttons;
|
||||||
|
return buttons[current_button_index].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string IrdaAppRemoteManager::get_current_remote_name() {
|
||||||
|
return remotes[current_remote_index].name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::rename_remote(const char* str) {
|
||||||
|
remotes[current_remote_index].name = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppRemoteManager::rename_button(const char* str) {
|
||||||
|
remotes[current_remote_index].buttons[current_button_index].name = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t IrdaAppRemoteManager::get_current_remote_buttons_number() {
|
||||||
|
return remotes[current_remote_index].buttons.size();
|
||||||
|
}
|
53
applications/irda/irda-app-remote-manager.hpp
Normal file
53
applications/irda/irda-app-remote-manager.hpp
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <vector>
|
||||||
|
#include <irda.h>
|
||||||
|
|
||||||
|
class IrdaAppRemoteButton {
|
||||||
|
friend class IrdaAppRemoteManager;
|
||||||
|
std::string name;
|
||||||
|
IrdaMessage message;
|
||||||
|
public:
|
||||||
|
IrdaAppRemoteButton(const char* name, const IrdaMessage* message)
|
||||||
|
: name(name), message (*message) {}
|
||||||
|
~IrdaAppRemoteButton() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppRemote {
|
||||||
|
friend class IrdaAppRemoteManager;
|
||||||
|
std::vector<IrdaAppRemoteButton> buttons;
|
||||||
|
std::string name;
|
||||||
|
bool add(const IrdaMessage*);
|
||||||
|
void add_button(size_t remote_index, const char* button_name, const IrdaMessage* message);
|
||||||
|
public:
|
||||||
|
IrdaAppRemote(std::string name);
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppRemoteManager {
|
||||||
|
size_t current_remote_index;
|
||||||
|
size_t current_button_index;
|
||||||
|
std::vector<IrdaAppRemote> remotes;
|
||||||
|
public:
|
||||||
|
std::vector<std::string> get_remote_list() const;
|
||||||
|
std::vector<std::string> get_button_list() const;
|
||||||
|
void add_remote_with_button(const char* button_name, const IrdaMessage* message);
|
||||||
|
void add_button(const char* button_name, const IrdaMessage* message);
|
||||||
|
|
||||||
|
size_t get_current_remote(void) const;
|
||||||
|
size_t get_current_button(void) const;
|
||||||
|
const IrdaMessage* get_button_data(size_t button_index) const;
|
||||||
|
void set_current_remote(size_t index);
|
||||||
|
void set_current_button(size_t index);
|
||||||
|
void rename_button(const char* str);
|
||||||
|
void rename_remote(const char* str);
|
||||||
|
std::string get_current_button_name();
|
||||||
|
std::string get_current_remote_name();
|
||||||
|
size_t get_current_remote_buttons_number();
|
||||||
|
void delete_current_button();
|
||||||
|
void delete_current_remote();
|
||||||
|
IrdaAppRemoteManager();
|
||||||
|
~IrdaAppRemoteManager() {};
|
||||||
|
};
|
||||||
|
|
110
applications/irda/irda-app-view-manager.cpp
Normal file
110
applications/irda/irda-app-view-manager.cpp
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#include "furi.h"
|
||||||
|
#include "gui/modules/button_menu.h"
|
||||||
|
#include "gui/modules/dialog_ex.h"
|
||||||
|
#include "gui/modules/text_input.h"
|
||||||
|
#include "irda-app.hpp"
|
||||||
|
#include <callback-connector.h>
|
||||||
|
|
||||||
|
IrdaAppViewManager::IrdaAppViewManager() {
|
||||||
|
event_queue = osMessageQueueNew(10, sizeof(IrdaAppEvent), NULL);
|
||||||
|
|
||||||
|
view_dispatcher = view_dispatcher_alloc();
|
||||||
|
auto callback = cbc::obtain_connector(this, &IrdaAppViewManager::previous_view_callback);
|
||||||
|
|
||||||
|
gui = static_cast<Gui*>(furi_record_open("gui"));
|
||||||
|
view_dispatcher_attach_to_gui(view_dispatcher, gui, ViewDispatcherTypeFullscreen);
|
||||||
|
|
||||||
|
button_menu = button_menu_alloc();
|
||||||
|
submenu = submenu_alloc();
|
||||||
|
popup = popup_alloc();
|
||||||
|
dialog_ex = dialog_ex_alloc();
|
||||||
|
text_input = text_input_alloc();
|
||||||
|
|
||||||
|
add_view(ViewType::ButtonMenu, button_menu_get_view(button_menu));
|
||||||
|
add_view(ViewType::Submenu, submenu_get_view(submenu));
|
||||||
|
add_view(ViewType::Popup, popup_get_view(popup));
|
||||||
|
add_view(ViewType::DialogEx, dialog_ex_get_view(dialog_ex));
|
||||||
|
add_view(ViewType::TextInput, text_input_get_view(text_input));
|
||||||
|
|
||||||
|
view_set_previous_callback(button_menu_get_view(button_menu), callback);
|
||||||
|
view_set_previous_callback(submenu_get_view(submenu), callback);
|
||||||
|
view_set_previous_callback(popup_get_view(popup), callback);
|
||||||
|
view_set_previous_callback(dialog_ex_get_view(dialog_ex), callback);
|
||||||
|
view_set_previous_callback(text_input_get_view(text_input), callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaAppViewManager::~IrdaAppViewManager() {
|
||||||
|
view_dispatcher_remove_view(
|
||||||
|
view_dispatcher, static_cast<uint32_t>(IrdaAppViewManager::ViewType::ButtonMenu));
|
||||||
|
view_dispatcher_remove_view(
|
||||||
|
view_dispatcher, static_cast<uint32_t>(IrdaAppViewManager::ViewType::TextInput));
|
||||||
|
view_dispatcher_remove_view(
|
||||||
|
view_dispatcher, static_cast<uint32_t>(IrdaAppViewManager::ViewType::DialogEx));
|
||||||
|
view_dispatcher_remove_view(
|
||||||
|
view_dispatcher, static_cast<uint32_t>(IrdaAppViewManager::ViewType::Submenu));
|
||||||
|
view_dispatcher_remove_view(
|
||||||
|
view_dispatcher, static_cast<uint32_t>(IrdaAppViewManager::ViewType::Popup));
|
||||||
|
|
||||||
|
submenu_free(submenu);
|
||||||
|
popup_free(popup);
|
||||||
|
button_menu_free(button_menu);
|
||||||
|
dialog_ex_free(dialog_ex);
|
||||||
|
text_input_free(text_input);
|
||||||
|
|
||||||
|
view_dispatcher_free(view_dispatcher);
|
||||||
|
furi_record_close("gui");
|
||||||
|
osMessageQueueDelete(event_queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppViewManager::switch_to(ViewType type) {
|
||||||
|
view_dispatcher_switch_to_view(view_dispatcher, static_cast<uint32_t>(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
TextInput* IrdaAppViewManager::get_text_input() {
|
||||||
|
return text_input;
|
||||||
|
}
|
||||||
|
|
||||||
|
DialogEx* IrdaAppViewManager::get_dialog_ex() {
|
||||||
|
return dialog_ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
Submenu* IrdaAppViewManager::get_submenu() {
|
||||||
|
return submenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
Popup* IrdaAppViewManager::get_popup() {
|
||||||
|
return popup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ButtonMenu* IrdaAppViewManager::get_button_menu() {
|
||||||
|
return button_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
osMessageQueueId_t IrdaAppViewManager::get_event_queue() {
|
||||||
|
return event_queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppViewManager::receive_event(IrdaAppEvent* event) {
|
||||||
|
if(osMessageQueueGet(event_queue, event, NULL, 100) != osOK) {
|
||||||
|
event->type = IrdaAppEvent::Type::Tick;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppViewManager::send_event(IrdaAppEvent* event) {
|
||||||
|
osStatus_t result = osMessageQueuePut(event_queue, event, 0, 0);
|
||||||
|
furi_check(result == osOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t IrdaAppViewManager::previous_view_callback(void* context) {
|
||||||
|
if(event_queue != NULL) {
|
||||||
|
IrdaAppEvent event;
|
||||||
|
event.type = IrdaAppEvent::Type::Back;
|
||||||
|
send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
return VIEW_IGNORE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppViewManager::add_view(ViewType view_type, View* view) {
|
||||||
|
view_dispatcher_add_view(view_dispatcher, static_cast<uint32_t>(view_type), view);
|
||||||
|
}
|
52
applications/irda/irda-app-view-manager.hpp
Normal file
52
applications/irda/irda-app-view-manager.hpp
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "gui/modules/button_menu.h"
|
||||||
|
#include "gui/modules/text_input.h"
|
||||||
|
#include <furi.h>
|
||||||
|
#include <gui/view_dispatcher.h>
|
||||||
|
#include <gui/modules/dialog_ex.h>
|
||||||
|
#include <gui/modules/submenu.h>
|
||||||
|
#include <gui/modules/popup.h>
|
||||||
|
#include "irda-app.hpp"
|
||||||
|
|
||||||
|
class IrdaAppViewManager {
|
||||||
|
public:
|
||||||
|
enum class ViewType : uint8_t {
|
||||||
|
DialogEx,
|
||||||
|
TextInput,
|
||||||
|
Submenu,
|
||||||
|
ButtonMenu,
|
||||||
|
Popup,
|
||||||
|
};
|
||||||
|
|
||||||
|
IrdaAppViewManager();
|
||||||
|
~IrdaAppViewManager();
|
||||||
|
|
||||||
|
void switch_to(ViewType type);
|
||||||
|
|
||||||
|
void receive_event(IrdaAppEvent* event);
|
||||||
|
void send_event(IrdaAppEvent* event);
|
||||||
|
|
||||||
|
DialogEx* get_dialog_ex();
|
||||||
|
Submenu* get_submenu();
|
||||||
|
Popup* get_popup();
|
||||||
|
TextInput* get_text_input();
|
||||||
|
ButtonMenu* get_button_menu();
|
||||||
|
|
||||||
|
osMessageQueueId_t get_event_queue();
|
||||||
|
|
||||||
|
uint32_t previous_view_callback(void* context);
|
||||||
|
|
||||||
|
private:
|
||||||
|
ViewDispatcher* view_dispatcher;
|
||||||
|
Gui* gui;
|
||||||
|
TextInput* text_input;
|
||||||
|
DialogEx* dialog_ex;
|
||||||
|
Submenu* submenu;
|
||||||
|
Popup* popup;
|
||||||
|
ButtonMenu* button_menu;
|
||||||
|
|
||||||
|
osMessageQueueId_t event_queue;
|
||||||
|
|
||||||
|
void add_view(ViewType view_type, View* view);
|
||||||
|
};
|
||||||
|
|
156
applications/irda/irda-app.cpp
Normal file
156
applications/irda/irda-app.cpp
Normal file
@ -0,0 +1,156 @@
|
|||||||
|
#include "irda-app.hpp"
|
||||||
|
#include <furi.h>
|
||||||
|
#include <gui/gui.h>
|
||||||
|
#include <input/input.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <callback-connector.h>
|
||||||
|
|
||||||
|
void IrdaApp::run(void) {
|
||||||
|
IrdaAppEvent event;
|
||||||
|
bool consumed;
|
||||||
|
bool exit = false;
|
||||||
|
|
||||||
|
scenes[current_scene]->on_enter(this);
|
||||||
|
|
||||||
|
while(!exit) {
|
||||||
|
view_manager.receive_event(&event);
|
||||||
|
|
||||||
|
consumed = scenes[current_scene]->on_event(this, &event);
|
||||||
|
|
||||||
|
if(!consumed) {
|
||||||
|
if(event.type == IrdaAppEvent::Type::Back) {
|
||||||
|
exit = switch_to_previous_scene();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
scenes[current_scene]->on_exit(this);
|
||||||
|
};
|
||||||
|
|
||||||
|
IrdaAppViewManager* IrdaApp::get_view_manager() {
|
||||||
|
return &view_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::set_learn_new_remote(bool value) {
|
||||||
|
learn_new_remote = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaApp::get_learn_new_remote() {
|
||||||
|
return learn_new_remote;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::switch_to_next_scene(Scene next_scene) {
|
||||||
|
previous_scenes_list.push_front(current_scene);
|
||||||
|
switch_to_next_scene_without_saving(next_scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::switch_to_next_scene_without_saving(Scene next_scene) {
|
||||||
|
if(next_scene != Scene::Exit) {
|
||||||
|
scenes[current_scene]->on_exit(this);
|
||||||
|
current_scene = next_scene;
|
||||||
|
scenes[current_scene]->on_enter(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::search_and_switch_to_previous_scene(const std::initializer_list<Scene>& scenes_list) {
|
||||||
|
Scene previous_scene = Scene::Start;
|
||||||
|
bool scene_found = false;
|
||||||
|
|
||||||
|
while(!scene_found) {
|
||||||
|
previous_scene = get_previous_scene();
|
||||||
|
for(Scene element : scenes_list) {
|
||||||
|
if(previous_scene == element) {
|
||||||
|
scene_found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
scenes[current_scene]->on_exit(this);
|
||||||
|
current_scene = previous_scene;
|
||||||
|
scenes[current_scene]->on_enter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaApp::switch_to_previous_scene(uint8_t count) {
|
||||||
|
Scene previous_scene = Scene::Start;
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < count; i++) previous_scene = get_previous_scene();
|
||||||
|
|
||||||
|
if(previous_scene == Scene::Exit) return true;
|
||||||
|
|
||||||
|
scenes[current_scene]->on_exit(this);
|
||||||
|
current_scene = previous_scene;
|
||||||
|
scenes[current_scene]->on_enter(this);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaApp::Scene IrdaApp::get_previous_scene() {
|
||||||
|
Scene scene = Scene::Exit;
|
||||||
|
|
||||||
|
if(!previous_scenes_list.empty()) {
|
||||||
|
scene = previous_scenes_list.front();
|
||||||
|
previous_scenes_list.pop_front();
|
||||||
|
}
|
||||||
|
|
||||||
|
return scene;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaAppRemoteManager* IrdaApp::get_remote_manager() {
|
||||||
|
return &remote_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaAppSignalReceiver* IrdaApp::get_receiver() {
|
||||||
|
return &receiver;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::set_text_store(uint8_t index, const char* text...) {
|
||||||
|
furi_check(index < text_store_max);
|
||||||
|
|
||||||
|
va_list args;
|
||||||
|
va_start(args, text);
|
||||||
|
|
||||||
|
vsnprintf(text_store[index], text_store_size, text, args);
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* IrdaApp::get_text_store(uint8_t index) {
|
||||||
|
furi_check(index < text_store_max);
|
||||||
|
|
||||||
|
return text_store[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t IrdaApp::get_text_store_size() {
|
||||||
|
return text_store_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::text_input_callback(void* context, char* text) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
event.type = IrdaAppEvent::Type::TextEditDone;
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::popup_callback(void* context) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
event.type = IrdaAppEvent::Type::PopupTimer;
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::set_edit_element(IrdaApp::EditElement value) {
|
||||||
|
element = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaApp::EditElement IrdaApp::get_edit_element(void) {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaApp::set_edit_action(IrdaApp::EditAction value) {
|
||||||
|
action = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
IrdaApp::EditAction IrdaApp::get_edit_action(void) {
|
||||||
|
return action;
|
||||||
|
}
|
108
applications/irda/irda-app.hpp
Normal file
108
applications/irda/irda-app.hpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#pragma once
|
||||||
|
#include <map>
|
||||||
|
#include <irda.h>
|
||||||
|
#include <furi.h>
|
||||||
|
#include "irda-app-event.hpp"
|
||||||
|
#include "scene/irda-app-scene.hpp"
|
||||||
|
#include "irda-app-view-manager.hpp"
|
||||||
|
#include "irda-app-remote-manager.hpp"
|
||||||
|
#include "irda-app-receiver.hpp"
|
||||||
|
#include <forward_list>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
class IrdaApp {
|
||||||
|
public:
|
||||||
|
enum class EditElement : uint8_t {
|
||||||
|
Button,
|
||||||
|
Remote,
|
||||||
|
};
|
||||||
|
enum class EditAction : uint8_t {
|
||||||
|
Rename,
|
||||||
|
Delete,
|
||||||
|
};
|
||||||
|
enum class Scene : uint8_t {
|
||||||
|
Exit,
|
||||||
|
Start,
|
||||||
|
Universal,
|
||||||
|
UniversalTV,
|
||||||
|
UniversalAudio,
|
||||||
|
UniversalAirConditioner,
|
||||||
|
Learn,
|
||||||
|
LearnSuccess,
|
||||||
|
LearnEnterName,
|
||||||
|
LearnDone,
|
||||||
|
LearnDoneAfter,
|
||||||
|
Remote,
|
||||||
|
RemoteList,
|
||||||
|
Edit,
|
||||||
|
EditKeySelect,
|
||||||
|
EditRename,
|
||||||
|
EditDelete,
|
||||||
|
EditRenameDone,
|
||||||
|
EditDeleteDone,
|
||||||
|
};
|
||||||
|
|
||||||
|
void run(void);
|
||||||
|
void switch_to_next_scene(Scene index);
|
||||||
|
void switch_to_next_scene_without_saving(Scene index);
|
||||||
|
bool switch_to_previous_scene(uint8_t count = 1);
|
||||||
|
Scene get_previous_scene();
|
||||||
|
IrdaAppViewManager* get_view_manager();
|
||||||
|
IrdaAppSignalReceiver* get_receiver();
|
||||||
|
void set_text_store(uint8_t index, const char* text...);
|
||||||
|
char* get_text_store(uint8_t index);
|
||||||
|
uint8_t get_text_store_size();
|
||||||
|
IrdaAppRemoteManager* get_remote_manager();
|
||||||
|
void search_and_switch_to_previous_scene(const std::initializer_list<Scene>& scenes_list);
|
||||||
|
|
||||||
|
void set_edit_element(EditElement value);
|
||||||
|
EditElement get_edit_element(void);
|
||||||
|
|
||||||
|
void set_edit_action(EditAction value);
|
||||||
|
EditAction get_edit_action(void);
|
||||||
|
|
||||||
|
bool get_learn_new_remote();
|
||||||
|
void set_learn_new_remote(bool value);
|
||||||
|
|
||||||
|
static void text_input_callback(void* context, char* text);
|
||||||
|
static void popup_callback(void* context);
|
||||||
|
|
||||||
|
IrdaApp() {}
|
||||||
|
~IrdaApp() {
|
||||||
|
for (auto &it : scenes)
|
||||||
|
delete it.second;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static const uint8_t text_store_size = 128;
|
||||||
|
static const uint8_t text_store_max = 2;
|
||||||
|
char text_store[text_store_max][text_store_size + 1];
|
||||||
|
bool learn_new_remote;
|
||||||
|
EditElement element;
|
||||||
|
EditAction action;
|
||||||
|
|
||||||
|
IrdaAppSignalReceiver receiver;
|
||||||
|
IrdaAppViewManager view_manager;
|
||||||
|
IrdaAppRemoteManager remote_manager;
|
||||||
|
|
||||||
|
std::forward_list<Scene> previous_scenes_list;
|
||||||
|
Scene current_scene = Scene::Start;
|
||||||
|
|
||||||
|
std::map<Scene, IrdaAppScene*> scenes = {
|
||||||
|
{Scene::Start, new IrdaAppSceneStart()},
|
||||||
|
{Scene::Universal, new IrdaAppSceneUniversal()},
|
||||||
|
{Scene::Learn, new IrdaAppSceneLearn()},
|
||||||
|
{Scene::LearnSuccess, new IrdaAppSceneLearnSuccess()},
|
||||||
|
{Scene::LearnEnterName, new IrdaAppSceneLearnEnterName()},
|
||||||
|
{Scene::LearnDone, new IrdaAppSceneLearnDone()},
|
||||||
|
{Scene::LearnDoneAfter, new IrdaAppSceneLearnDoneAfter()},
|
||||||
|
{Scene::Remote, new IrdaAppSceneRemote()},
|
||||||
|
{Scene::RemoteList, new IrdaAppSceneRemoteList()},
|
||||||
|
{Scene::Edit, new IrdaAppSceneEdit()},
|
||||||
|
{Scene::EditKeySelect, new IrdaAppSceneEditKeySelect()},
|
||||||
|
{Scene::EditRename, new IrdaAppSceneEditRename()},
|
||||||
|
{Scene::EditDelete, new IrdaAppSceneEditDelete()},
|
||||||
|
{Scene::EditRenameDone, new IrdaAppSceneEditRenameDone()},
|
||||||
|
{Scene::EditDeleteDone, new IrdaAppSceneEditDeleteDone()},
|
||||||
|
};
|
||||||
|
};
|
@ -1,146 +0,0 @@
|
|||||||
#include "irda-decoder-nec.h"
|
|
||||||
#include "string.h"
|
|
||||||
|
|
||||||
const uint32_t PREAMBULA_HIGH_MIN = 9000 - 900;
|
|
||||||
const uint32_t PREAMBULA_HIGH_MAX = 9000 + 900;
|
|
||||||
|
|
||||||
const uint32_t PREAMBULA_LOW_MIN = 4500 - 450;
|
|
||||||
const uint32_t PREAMBULA_LOW_MAX = 4500 + 450;
|
|
||||||
|
|
||||||
const uint32_t PREAMBULA_RETRY_LOW_MIN = 2500 - 350;
|
|
||||||
const uint32_t PREAMBULA_RETRY_LOW_MAX = 2500 + 250;
|
|
||||||
|
|
||||||
const uint32_t BIT_HIGH_MIN = 560 - 100;
|
|
||||||
const uint32_t BIT_HIGH_MAX = 560 + 100;
|
|
||||||
|
|
||||||
const uint32_t BIT_LOW_ONE_MIN = 1690 - 200;
|
|
||||||
const uint32_t BIT_LOW_ONE_MAX = 1690 + 200;
|
|
||||||
|
|
||||||
const uint32_t BIT_LOW_ZERO_MIN = 560 - 100;
|
|
||||||
const uint32_t BIT_LOW_ZERO_MAX = 560 + 100;
|
|
||||||
|
|
||||||
#define SET_STATE(_state) \
|
|
||||||
{ decoder->state = _state; }
|
|
||||||
|
|
||||||
#define TIME_FIT(_prefix) ((time > _prefix##_MIN) && (time < _prefix##_MAX))
|
|
||||||
|
|
||||||
#ifndef MIN
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool save_decoder_nec_data(IrDANecDecoder* decoder, IrDADecoderOutputData* out) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if((decoder->data.simple.cmd + decoder->data.simple.cmd_inverse) == 0xFF) {
|
|
||||||
if(out->data_length < sizeof(IrDANecDataType)) {
|
|
||||||
out->flags |= IRDA_TOO_SHORT_BUFFER;
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(out->data, &decoder->data.data, MIN(sizeof(IrDANecDataType), out->data_length));
|
|
||||||
result = true;
|
|
||||||
} else {
|
|
||||||
reset_decoder_nec(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool process_decoder_nec(
|
|
||||||
IrDANecDecoder* decoder,
|
|
||||||
bool polarity,
|
|
||||||
uint32_t time,
|
|
||||||
IrDADecoderOutputData* out) {
|
|
||||||
bool error = true;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
switch(decoder->state) {
|
|
||||||
case(WAIT_PREAMBULA_HIGH):
|
|
||||||
if(polarity) {
|
|
||||||
if(TIME_FIT(PREAMBULA_HIGH)) {
|
|
||||||
SET_STATE(WAIT_PREAMBULA_LOW);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// any values before preambula start is correct
|
|
||||||
error = false;
|
|
||||||
break;
|
|
||||||
case(WAIT_PREAMBULA_LOW):
|
|
||||||
if(!polarity) {
|
|
||||||
if(TIME_FIT(PREAMBULA_LOW)) {
|
|
||||||
// new data, reset storage
|
|
||||||
reset_decoder_nec(decoder);
|
|
||||||
SET_STATE(WAIT_BIT_HIGH);
|
|
||||||
error = false;
|
|
||||||
} else if(TIME_FIT(PREAMBULA_RETRY_LOW)) {
|
|
||||||
// wait for data repeat command
|
|
||||||
SET_STATE(WAIT_RETRY_HIGH);
|
|
||||||
error = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case(WAIT_RETRY_HIGH):
|
|
||||||
if(polarity) {
|
|
||||||
if(TIME_FIT(BIT_HIGH)) {
|
|
||||||
SET_STATE(WAIT_PREAMBULA_HIGH);
|
|
||||||
|
|
||||||
// repeat event
|
|
||||||
result = save_decoder_nec_data(decoder, out);
|
|
||||||
out->flags |= IRDA_REPEAT;
|
|
||||||
error = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case(WAIT_BIT_HIGH):
|
|
||||||
if(polarity) {
|
|
||||||
if(TIME_FIT(BIT_HIGH)) {
|
|
||||||
SET_STATE(WAIT_BIT_LOW);
|
|
||||||
error = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case(WAIT_BIT_STOP_HIGH):
|
|
||||||
if(polarity) {
|
|
||||||
if(TIME_FIT(BIT_HIGH)) {
|
|
||||||
SET_STATE(WAIT_PREAMBULA_HIGH);
|
|
||||||
|
|
||||||
// message end event
|
|
||||||
result = save_decoder_nec_data(decoder, out);
|
|
||||||
error = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case(WAIT_BIT_LOW):
|
|
||||||
if(!polarity) {
|
|
||||||
int8_t bit = -1;
|
|
||||||
if(TIME_FIT(BIT_LOW_ZERO)) {
|
|
||||||
SET_STATE(WAIT_BIT_HIGH);
|
|
||||||
bit = 0;
|
|
||||||
error = false;
|
|
||||||
} else if(TIME_FIT(BIT_LOW_ONE)) {
|
|
||||||
SET_STATE(WAIT_BIT_HIGH);
|
|
||||||
bit = 1;
|
|
||||||
error = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bit != -1) {
|
|
||||||
decoder->data.data |= (bit << decoder->current_data_index);
|
|
||||||
decoder->current_data_index++;
|
|
||||||
|
|
||||||
if(decoder->current_data_index > 31) {
|
|
||||||
decoder->current_data_index = 0;
|
|
||||||
SET_STATE(WAIT_BIT_STOP_HIGH);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(error) reset_decoder_nec(decoder);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset_decoder_nec(IrDANecDecoder* decoder) {
|
|
||||||
decoder->state = WAIT_PREAMBULA_HIGH;
|
|
||||||
decoder->data.data = 0;
|
|
||||||
decoder->current_data_index = 0;
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "irda-decoder-types.h"
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
WAIT_PREAMBULA_HIGH,
|
|
||||||
WAIT_PREAMBULA_LOW,
|
|
||||||
WAIT_RETRY_HIGH,
|
|
||||||
WAIT_BIT_HIGH,
|
|
||||||
WAIT_BIT_LOW,
|
|
||||||
WAIT_BIT_STOP_HIGH,
|
|
||||||
} IrDANecDecoderState;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t addr2;
|
|
||||||
uint8_t addr1;
|
|
||||||
uint8_t cmd_inverse;
|
|
||||||
uint8_t cmd;
|
|
||||||
} IrDANecData;
|
|
||||||
|
|
||||||
typedef uint32_t IrDANecDataType;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
union {
|
|
||||||
IrDANecData simple;
|
|
||||||
IrDANecDataType data;
|
|
||||||
} data;
|
|
||||||
uint8_t current_data_index;
|
|
||||||
IrDANecDecoderState state;
|
|
||||||
} IrDANecDecoder;
|
|
||||||
|
|
||||||
bool process_decoder_nec(
|
|
||||||
IrDANecDecoder* decoder,
|
|
||||||
bool polarity,
|
|
||||||
uint32_t time,
|
|
||||||
IrDADecoderOutputData* out);
|
|
||||||
|
|
||||||
void reset_decoder_nec(IrDANecDecoder* decoder);
|
|
@ -1,12 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
typedef enum { IRDA_UNKNOWN, IRDA_NEC, IRDA_SAMSUNG } IrDAProtocolType;
|
|
||||||
typedef enum { IRDA_REPEAT = (1 << 0), IRDA_TOO_SHORT_BUFFER = (1 << 1) } IrDAProtocolFlags;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
IrDAProtocolType protocol;
|
|
||||||
uint8_t flags;
|
|
||||||
uint8_t* data; /** < ponter to output data, filled by app */
|
|
||||||
uint32_t data_length; /** < output data length, filled by app */
|
|
||||||
} IrDADecoderOutputData;
|
|
@ -1,41 +0,0 @@
|
|||||||
#include "irda-decoder.h"
|
|
||||||
|
|
||||||
IrDADecoder* alloc_decoder(void) {
|
|
||||||
IrDADecoder* decoder = malloc(sizeof(IrDADecoder));
|
|
||||||
|
|
||||||
// init decoders
|
|
||||||
reset_decoder_nec(&decoder->nec);
|
|
||||||
|
|
||||||
return decoder;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free_decoder(IrDADecoder* decoder) {
|
|
||||||
free(decoder);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool process_decoder(
|
|
||||||
IrDADecoder* decoder,
|
|
||||||
bool start_polarity,
|
|
||||||
uint32_t* timings,
|
|
||||||
uint32_t timings_length,
|
|
||||||
IrDADecoderOutputData* out) {
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
// zero result
|
|
||||||
memset(out->data, 0, out->data_length);
|
|
||||||
out->protocol = IRDA_UNKNOWN;
|
|
||||||
out->flags = 0;
|
|
||||||
|
|
||||||
// process data
|
|
||||||
for(uint32_t timings_index = 0; timings_index < timings_length; timings_index++) {
|
|
||||||
if(process_decoder_nec(&decoder->nec, start_polarity, timings[timings_index], out)) {
|
|
||||||
out->protocol = IRDA_NEC;
|
|
||||||
result = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
start_polarity = !start_polarity;
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <furi.h>
|
|
||||||
#include "irda-decoder-nec.h"
|
|
||||||
#include "irda-decoder-types.h"
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
IrDANecDecoder nec;
|
|
||||||
} IrDADecoder;
|
|
||||||
|
|
||||||
IrDADecoder* alloc_decoder(void);
|
|
||||||
void free_decoder(IrDADecoder* decoder);
|
|
||||||
bool process_decoder(
|
|
||||||
IrDADecoder* decoder,
|
|
||||||
bool start_polarity,
|
|
||||||
uint32_t* timings,
|
|
||||||
uint32_t timings_length,
|
|
||||||
IrDADecoderOutputData* out);
|
|
9
applications/irda/irda-runner.cpp
Normal file
9
applications/irda/irda-runner.cpp
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
#include "irda-app.hpp"
|
||||||
|
|
||||||
|
extern "C" int32_t irda(void* p) {
|
||||||
|
IrdaApp* app = new IrdaApp();
|
||||||
|
app->run();
|
||||||
|
delete app;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -290,7 +290,7 @@ void irda_rx_callback(void* ctx, bool level, uint32_t duration) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int32_t irda(void* p) {
|
int32_t irda2(void* p) {
|
||||||
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(AppEvent), NULL);
|
osMessageQueueId_t event_queue = osMessageQueueNew(32, sizeof(AppEvent), NULL);
|
||||||
|
|
||||||
State _state;
|
State _state;
|
@ -1,19 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
// our tx pin is TIM2_CH4
|
|
||||||
extern TIM_HandleTypeDef TIM_A;
|
|
||||||
|
|
||||||
#define RC5_CARRIER_FREQUENCY 36000
|
|
||||||
#define RC5_DUTY_CYCLE 0.33
|
|
||||||
|
|
||||||
#define RC6_CARRIER_FREQUENCY 36000
|
|
||||||
#define RC6_DUTY_CYCLE 0.33
|
|
||||||
|
|
||||||
#define SAMSUNG_CARRIER_FREQUENCY 37900
|
|
||||||
#define SAMSUNG_DUTY_CYCLE 0.33
|
|
||||||
|
|
||||||
#define NEC_CARRIER_FREQUENCY 38000
|
|
||||||
#define NEC_DUTY_CYCLE 0.33
|
|
||||||
|
|
||||||
#define SIRC_CARRIER_FREQUENCY 40000
|
|
||||||
#define SIRC_DUTY_CYCLE 0.5
|
|
35
applications/irda/scene/irda-app-scene-edit-delete-done.cpp
Normal file
35
applications/irda/scene/irda-app-scene-edit-delete-done.cpp
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
void IrdaAppSceneEditDeleteDone::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Popup* popup = view_manager->get_popup();
|
||||||
|
|
||||||
|
popup_set_icon(popup, 0, 2, I_DolphinMafia_115x62);
|
||||||
|
popup_set_text(popup, "Deleted", 83, 19, AlignLeft, AlignBottom);
|
||||||
|
|
||||||
|
popup_set_callback(popup, IrdaApp::popup_callback);
|
||||||
|
popup_set_context(popup, app);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneEditDeleteDone::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::PopupTimer) {
|
||||||
|
if(app->get_edit_element() == IrdaApp::EditElement::Remote) {
|
||||||
|
app->search_and_switch_to_previous_scene(
|
||||||
|
{IrdaApp::Scene::Start, IrdaApp::Scene::RemoteList});
|
||||||
|
} else {
|
||||||
|
app->search_and_switch_to_previous_scene({IrdaApp::Scene::Remote});
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditDeleteDone::on_exit(IrdaApp* app) {
|
||||||
|
}
|
81
applications/irda/scene/irda-app-scene-edit-delete.cpp
Normal file
81
applications/irda/scene/irda-app-scene-edit-delete.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include "irda.h"
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void dialog_result_callback(DialogExResult result, void* context) {
|
||||||
|
auto app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::DialogExSelected;
|
||||||
|
event.payload.dialog_ex_result = result;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditDelete::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
DialogEx* dialog_ex = view_manager->get_dialog_ex();
|
||||||
|
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
|
||||||
|
if(app->get_edit_element() == IrdaApp::EditElement::Button) {
|
||||||
|
auto message = remote_manager->get_button_data(remote_manager->get_current_button());
|
||||||
|
dialog_ex_set_header(dialog_ex, "Delete button?", 64, 6, AlignCenter, AlignCenter);
|
||||||
|
app->set_text_store(
|
||||||
|
0,
|
||||||
|
"%s\n%s\nA=0x%0*lX C=0x%0*lX",
|
||||||
|
remote_manager->get_current_button_name().c_str(),
|
||||||
|
irda_get_protocol_name(message->protocol),
|
||||||
|
irda_get_protocol_address_length(message->protocol),
|
||||||
|
message->address,
|
||||||
|
irda_get_protocol_command_length(message->protocol),
|
||||||
|
message->command);
|
||||||
|
} else {
|
||||||
|
dialog_ex_set_header(dialog_ex, "Delete remote?", 64, 6, AlignCenter, AlignCenter);
|
||||||
|
app->set_text_store(
|
||||||
|
0,
|
||||||
|
"%s\n with %lu buttons",
|
||||||
|
remote_manager->get_current_remote_name().c_str(),
|
||||||
|
remote_manager->get_current_remote_buttons_number());
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog_ex_set_text(dialog_ex, app->get_text_store(0), 64, 32, AlignCenter, AlignCenter);
|
||||||
|
dialog_ex_set_icon(dialog_ex, -1, -1, I_ButtonCenter_7x7);
|
||||||
|
dialog_ex_set_left_button_text(dialog_ex, "Back");
|
||||||
|
dialog_ex_set_right_button_text(dialog_ex, "Delete");
|
||||||
|
dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
|
||||||
|
dialog_ex_set_context(dialog_ex, app);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::DialogEx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneEditDelete::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::DialogExSelected) {
|
||||||
|
switch(event->payload.dialog_ex_result) {
|
||||||
|
case DialogExResultLeft:
|
||||||
|
app->switch_to_previous_scene();
|
||||||
|
break;
|
||||||
|
case DialogExResultCenter:
|
||||||
|
furi_assert(0);
|
||||||
|
break;
|
||||||
|
case DialogExResultRight:
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
if(app->get_edit_element() == IrdaApp::EditElement::Remote) {
|
||||||
|
remote_manager->delete_current_remote();
|
||||||
|
} else {
|
||||||
|
remote_manager->delete_current_button();
|
||||||
|
}
|
||||||
|
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditDeleteDone);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditDelete::on_exit(IrdaApp* app) {
|
||||||
|
}
|
54
applications/irda/scene/irda-app-scene-edit-key-select.cpp
Normal file
54
applications/irda/scene/irda-app-scene-edit-key-select.cpp
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include "gui/modules/submenu.h"
|
||||||
|
|
||||||
|
static void submenu_callback(void* context, uint32_t index) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::MenuSelected;
|
||||||
|
event.payload.menu_index = index;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditKeySelect::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
const char* header = app->get_edit_action() == IrdaApp::EditAction::Rename ? "Rename key:" :
|
||||||
|
"Delete key:";
|
||||||
|
submenu_set_header(submenu, header);
|
||||||
|
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
buttons_names = remote_manager->get_button_list();
|
||||||
|
for(const auto& it : buttons_names) {
|
||||||
|
submenu_add_item(submenu, it.c_str(), i++, submenu_callback, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneEditKeySelect::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::MenuSelected) {
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
remote_manager->set_current_button(event->payload.menu_index);
|
||||||
|
consumed = true;
|
||||||
|
if(app->get_edit_action() == IrdaApp::EditAction::Rename) {
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditRename);
|
||||||
|
} else {
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditDelete);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditKeySelect::on_exit(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_clean(submenu);
|
||||||
|
}
|
31
applications/irda/scene/irda-app-scene-edit-rename-done.cpp
Normal file
31
applications/irda/scene/irda-app-scene-edit-rename-done.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
void IrdaAppSceneEditRenameDone::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Popup* popup = view_manager->get_popup();
|
||||||
|
|
||||||
|
popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
|
||||||
|
|
||||||
|
popup_set_text(popup, "Saved!", 13, 22, AlignLeft, AlignTop);
|
||||||
|
|
||||||
|
popup_set_callback(popup, IrdaApp::popup_callback);
|
||||||
|
popup_set_context(popup, app);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneEditRenameDone::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::PopupTimer) {
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Remote);
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditRenameDone::on_exit(IrdaApp* app) {
|
||||||
|
}
|
46
applications/irda/scene/irda-app-scene-edit-rename.cpp
Normal file
46
applications/irda/scene/irda-app-scene-edit-rename.cpp
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
void IrdaAppSceneEditRename::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
TextInput* text_input = view_manager->get_text_input();
|
||||||
|
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
if(app->get_edit_element() == IrdaApp::EditElement::Button) {
|
||||||
|
auto button_name = remote_manager->get_current_button_name();
|
||||||
|
strncpy(app->get_text_store(0), button_name.c_str(), app->get_text_store_size());
|
||||||
|
} else {
|
||||||
|
auto remote_name = remote_manager->get_current_remote_name();
|
||||||
|
strncpy(app->get_text_store(0), remote_name.c_str(), app->get_text_store_size());
|
||||||
|
}
|
||||||
|
|
||||||
|
text_input_set_header_text(text_input, "Name the key");
|
||||||
|
text_input_set_result_callback(
|
||||||
|
text_input,
|
||||||
|
IrdaApp::text_input_callback,
|
||||||
|
app,
|
||||||
|
app->get_text_store(0),
|
||||||
|
app->get_text_store_size());
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::TextInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneEditRename::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::TextEditDone) {
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
if(app->get_edit_element() == IrdaApp::EditElement::Button) {
|
||||||
|
remote_manager->rename_button(app->get_text_store(0));
|
||||||
|
} else {
|
||||||
|
remote_manager->rename_remote(app->get_text_store(0));
|
||||||
|
}
|
||||||
|
app->switch_to_next_scene_without_saving(IrdaApp::Scene::EditRenameDone);
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEditRename::on_exit(IrdaApp* app) {
|
||||||
|
}
|
74
applications/irda/scene/irda-app-scene-edit.cpp
Normal file
74
applications/irda/scene/irda-app-scene-edit.cpp
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SubmenuIndexAddKey,
|
||||||
|
SubmenuIndexRenameKey,
|
||||||
|
SubmenuIndexDeleteKey,
|
||||||
|
SubmenuIndexRenameRemote,
|
||||||
|
SubmenuIndexDeleteRemote,
|
||||||
|
} SubmenuIndex;
|
||||||
|
|
||||||
|
static void submenu_callback(void* context, uint32_t index) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::MenuSelected;
|
||||||
|
event.payload.menu_index = index;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEdit::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_add_item(submenu, "Add key", SubmenuIndexAddKey, submenu_callback, app);
|
||||||
|
submenu_add_item(submenu, "Rename key", SubmenuIndexRenameKey, submenu_callback, app);
|
||||||
|
submenu_add_item(submenu, "Delete key", SubmenuIndexDeleteKey, submenu_callback, app);
|
||||||
|
submenu_add_item(submenu, "Rename remote", SubmenuIndexRenameRemote, submenu_callback, app);
|
||||||
|
submenu_add_item(submenu, "Delete remote", SubmenuIndexDeleteRemote, submenu_callback, app);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneEdit::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::MenuSelected) {
|
||||||
|
switch(event->payload.menu_index) {
|
||||||
|
case SubmenuIndexAddKey:
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Learn);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexRenameKey:
|
||||||
|
app->set_edit_action(IrdaApp::EditAction::Rename);
|
||||||
|
app->set_edit_element(IrdaApp::EditElement::Button);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditKeySelect);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexDeleteKey:
|
||||||
|
app->set_edit_action(IrdaApp::EditAction::Delete);
|
||||||
|
app->set_edit_element(IrdaApp::EditElement::Button);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditKeySelect);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexRenameRemote:
|
||||||
|
app->set_edit_action(IrdaApp::EditAction::Rename);
|
||||||
|
app->set_edit_element(IrdaApp::EditElement::Remote);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditRename);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexDeleteRemote:
|
||||||
|
app->set_edit_action(IrdaApp::EditAction::Delete);
|
||||||
|
app->set_edit_element(IrdaApp::EditElement::Remote);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::EditDelete);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneEdit::on_exit(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_clean(submenu);
|
||||||
|
}
|
34
applications/irda/scene/irda-app-scene-learn-done-after.cpp
Normal file
34
applications/irda/scene/irda-app-scene-learn-done-after.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <gui/modules/popup.h>
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnDoneAfter::on_enter(IrdaApp* app) {
|
||||||
|
auto view_manager = app->get_view_manager();
|
||||||
|
auto popup = view_manager->get_popup();
|
||||||
|
|
||||||
|
popup_set_icon(popup, 0, 30, I_IrdaSendShort_128x34);
|
||||||
|
popup_set_text(
|
||||||
|
popup, "Get ready!\nPoint flipper at target.", 64, 16, AlignCenter, AlignCenter);
|
||||||
|
|
||||||
|
popup_set_callback(popup, IrdaApp::popup_callback);
|
||||||
|
popup_set_context(popup, app);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneLearnDoneAfter::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::PopupTimer) {
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Remote);
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnDoneAfter::on_exit(IrdaApp* app) {
|
||||||
|
}
|
42
applications/irda/scene/irda-app-scene-learn-done.cpp
Normal file
42
applications/irda/scene/irda-app-scene-learn-done.cpp
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnDone::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Popup* popup = view_manager->get_popup();
|
||||||
|
|
||||||
|
popup_set_icon(popup, 32, 5, I_DolphinNice_96x59);
|
||||||
|
|
||||||
|
if(app->get_learn_new_remote()) {
|
||||||
|
popup_set_text(popup, "New remote\ncreated!", 5, 7, AlignLeft, AlignTop);
|
||||||
|
} else {
|
||||||
|
popup_set_text(popup, "Saved!", 5, 7, AlignLeft, AlignTop);
|
||||||
|
}
|
||||||
|
|
||||||
|
popup_set_callback(popup, IrdaApp::popup_callback);
|
||||||
|
popup_set_context(popup, app);
|
||||||
|
popup_set_timeout(popup, 1500);
|
||||||
|
popup_enable_timeout(popup);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneLearnDone::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::PopupTimer) {
|
||||||
|
if(app->get_learn_new_remote()) {
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::LearnDoneAfter);
|
||||||
|
} else {
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Remote);
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnDone::on_exit(IrdaApp* app) {
|
||||||
|
app->set_learn_new_remote(false);
|
||||||
|
}
|
51
applications/irda/scene/irda-app-scene-learn-enter-name.cpp
Normal file
51
applications/irda/scene/irda-app-scene-learn-enter-name.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include "gui/modules/text_input.h"
|
||||||
|
#include <callback-connector.h>
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnEnterName::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
TextInput* text_input = view_manager->get_text_input();
|
||||||
|
|
||||||
|
auto receiver = app->get_receiver();
|
||||||
|
auto message = receiver->get_last_message();
|
||||||
|
|
||||||
|
app->set_text_store(
|
||||||
|
0,
|
||||||
|
"%.4s_%0*lX",
|
||||||
|
irda_get_protocol_name(message->protocol),
|
||||||
|
irda_get_protocol_command_length(message->protocol),
|
||||||
|
message->command);
|
||||||
|
|
||||||
|
text_input_set_header_text(text_input, "Name the key");
|
||||||
|
text_input_set_result_callback(
|
||||||
|
text_input,
|
||||||
|
IrdaApp::text_input_callback,
|
||||||
|
app,
|
||||||
|
app->get_text_store(0),
|
||||||
|
app->get_text_store_size());
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::TextInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneLearnEnterName::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::TextEditDone) {
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
auto receiver = app->get_receiver();
|
||||||
|
if(app->get_learn_new_remote()) {
|
||||||
|
remote_manager->add_remote_with_button(
|
||||||
|
app->get_text_store(0), receiver->get_last_message());
|
||||||
|
} else {
|
||||||
|
remote_manager->add_button(app->get_text_store(0), receiver->get_last_message());
|
||||||
|
}
|
||||||
|
|
||||||
|
app->switch_to_next_scene_without_saving(IrdaApp::Scene::LearnDone);
|
||||||
|
}
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnEnterName::on_exit(IrdaApp* app) {
|
||||||
|
}
|
63
applications/irda/scene/irda-app-scene-learn-success.cpp
Normal file
63
applications/irda/scene/irda-app-scene-learn-success.cpp
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include "irda.h"
|
||||||
|
#include <string>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
static void dialog_result_callback(DialogExResult result, void* context) {
|
||||||
|
auto app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::DialogExSelected;
|
||||||
|
event.payload.dialog_ex_result = result;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnSuccess::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
DialogEx* dialog_ex = view_manager->get_dialog_ex();
|
||||||
|
|
||||||
|
auto receiver = app->get_receiver();
|
||||||
|
auto message = receiver->get_last_message();
|
||||||
|
|
||||||
|
app->set_text_store(0, "%s", irda_get_protocol_name(message->protocol));
|
||||||
|
app->set_text_store(
|
||||||
|
1,
|
||||||
|
"A: 0x%0*lX\nC: 0x%0*lX\n",
|
||||||
|
irda_get_protocol_address_length(message->protocol),
|
||||||
|
message->address,
|
||||||
|
irda_get_protocol_command_length(message->protocol),
|
||||||
|
message->command);
|
||||||
|
dialog_ex_set_header(dialog_ex, app->get_text_store(0), 95, 10, AlignCenter, AlignCenter);
|
||||||
|
dialog_ex_set_text(dialog_ex, app->get_text_store(1), 75, 23, AlignLeft, AlignTop);
|
||||||
|
dialog_ex_set_left_button_text(dialog_ex, "Retry");
|
||||||
|
dialog_ex_set_right_button_text(dialog_ex, "Save");
|
||||||
|
dialog_ex_set_icon(dialog_ex, 0, 1, I_DolphinExcited_64x63);
|
||||||
|
dialog_ex_set_result_callback(dialog_ex, dialog_result_callback);
|
||||||
|
dialog_ex_set_context(dialog_ex, app);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::DialogEx);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneLearnSuccess::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::DialogExSelected) {
|
||||||
|
switch(event->payload.dialog_ex_result) {
|
||||||
|
case DialogExResultLeft:
|
||||||
|
app->switch_to_next_scene_without_saving(IrdaApp::Scene::Learn);
|
||||||
|
break;
|
||||||
|
case DialogExResultCenter:
|
||||||
|
furi_assert(0);
|
||||||
|
break;
|
||||||
|
case DialogExResultRight:
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::LearnEnterName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneLearnSuccess::on_exit(IrdaApp* app) {
|
||||||
|
}
|
31
applications/irda/scene/irda-app-scene-learn.cpp
Normal file
31
applications/irda/scene/irda-app-scene-learn.cpp
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
void IrdaAppSceneLearn::on_enter(IrdaApp* app) {
|
||||||
|
auto view_manager = app->get_view_manager();
|
||||||
|
auto receiver = app->get_receiver();
|
||||||
|
auto event_queue = view_manager->get_event_queue();
|
||||||
|
|
||||||
|
receiver->capture_once_start(event_queue);
|
||||||
|
|
||||||
|
auto popup = view_manager->get_popup();
|
||||||
|
|
||||||
|
popup_set_icon(popup, 0, 32, I_IrdaLearnShort_128x31);
|
||||||
|
popup_set_text(
|
||||||
|
popup, "Point the remote at IR port\nand push the button", 5, 10, AlignLeft, AlignCenter);
|
||||||
|
popup_set_callback(popup, NULL);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Popup);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneLearn::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::IrdaMessageReceived) {
|
||||||
|
app->switch_to_next_scene_without_saving(IrdaApp::Scene::LearnSuccess);
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneLearn::on_exit(IrdaApp* app) {
|
||||||
|
}
|
59
applications/irda/scene/irda-app-scene-remote-list.cpp
Normal file
59
applications/irda/scene/irda-app-scene-remote-list.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SubmenuIndexPlus = -1,
|
||||||
|
} SubmenuIndex;
|
||||||
|
|
||||||
|
static void submenu_callback(void* context, uint32_t index) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::MenuSelected;
|
||||||
|
event.payload.menu_index = index;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneRemoteList::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
remote_names = remote_manager->get_remote_list();
|
||||||
|
for(auto& a : remote_names) {
|
||||||
|
submenu_add_item(submenu, a.c_str(), i++, submenu_callback, app);
|
||||||
|
}
|
||||||
|
submenu_add_item(
|
||||||
|
submenu, " +", SubmenuIndexPlus, submenu_callback, app);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneRemoteList::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::MenuSelected) {
|
||||||
|
switch(event->payload.menu_index) {
|
||||||
|
case SubmenuIndexPlus:
|
||||||
|
app->set_learn_new_remote(true);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Learn);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
remote_manager->set_current_remote(event->payload.menu_index);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Remote);
|
||||||
|
consumed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneRemoteList::on_exit(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_clean(submenu);
|
||||||
|
}
|
75
applications/irda/scene/irda-app-scene-remote.cpp
Normal file
75
applications/irda/scene/irda-app-scene-remote.cpp
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include "gui/modules/button_menu.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
ButtonIndexPlus = -2,
|
||||||
|
ButtonIndexEdit = -1,
|
||||||
|
} ButtonIndex;
|
||||||
|
|
||||||
|
static void button_menu_callback(void* context, int32_t index) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::MenuSelected;
|
||||||
|
event.payload.menu_index = index;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneRemote::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
ButtonMenu* button_menu = view_manager->get_button_menu();
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
buttons_names = remote_manager->get_button_list();
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
for(auto& name : buttons_names) {
|
||||||
|
button_menu_add_item(
|
||||||
|
button_menu, name.c_str(), i++, button_menu_callback, ButtonMenuItemTypeCommon, app);
|
||||||
|
}
|
||||||
|
|
||||||
|
button_menu_add_item(
|
||||||
|
button_menu, "+", ButtonIndexPlus, button_menu_callback, ButtonMenuItemTypeControl, app);
|
||||||
|
button_menu_add_item(
|
||||||
|
button_menu, "Edit", ButtonIndexEdit, button_menu_callback, ButtonMenuItemTypeControl, app);
|
||||||
|
|
||||||
|
app->set_text_store(0, "%s", remote_manager->get_current_remote_name().c_str());
|
||||||
|
button_menu_set_header(button_menu, app->get_text_store(0));
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::ButtonMenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneRemote::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = true;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::MenuSelected) {
|
||||||
|
switch(event->payload.menu_index) {
|
||||||
|
case ButtonIndexPlus:
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Learn);
|
||||||
|
break;
|
||||||
|
case ButtonIndexEdit:
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Edit);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
auto remote_manager = app->get_remote_manager();
|
||||||
|
auto message = remote_manager->get_button_data(event->payload.menu_index);
|
||||||
|
app->get_receiver()->send_message(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if(event->type == IrdaAppEvent::Type::Back) {
|
||||||
|
app->search_and_switch_to_previous_scene(
|
||||||
|
{IrdaApp::Scene::Start, IrdaApp::Scene::RemoteList});
|
||||||
|
} else {
|
||||||
|
consumed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneRemote::on_exit(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
ButtonMenu* button_menu = view_manager->get_button_menu();
|
||||||
|
|
||||||
|
button_menu_clean(button_menu);
|
||||||
|
}
|
59
applications/irda/scene/irda-app-scene-start.cpp
Normal file
59
applications/irda/scene/irda-app-scene-start.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SubmenuIndexUniversalLibrary,
|
||||||
|
SubmenuIndexLearnNewRemote,
|
||||||
|
SubmenuIndexSavedRemotes,
|
||||||
|
} SubmenuIndex;
|
||||||
|
|
||||||
|
static void submenu_callback(void* context, uint32_t index) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::MenuSelected;
|
||||||
|
event.payload.menu_index = index;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneStart::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_add_item(
|
||||||
|
submenu, "Universal library", SubmenuIndexUniversalLibrary, submenu_callback, app);
|
||||||
|
submenu_add_item(
|
||||||
|
submenu, "Learn new remote", SubmenuIndexLearnNewRemote, submenu_callback, app);
|
||||||
|
submenu_add_item(submenu, "Saved remotes", SubmenuIndexSavedRemotes, submenu_callback, app);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneStart::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::MenuSelected) {
|
||||||
|
switch(event->payload.menu_index) {
|
||||||
|
case SubmenuIndexUniversalLibrary:
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Universal);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexLearnNewRemote:
|
||||||
|
app->set_learn_new_remote(true);
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::Learn);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexSavedRemotes:
|
||||||
|
app->switch_to_next_scene(IrdaApp::Scene::RemoteList);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneStart::on_exit(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_clean(submenu);
|
||||||
|
}
|
57
applications/irda/scene/irda-app-scene-universal.cpp
Normal file
57
applications/irda/scene/irda-app-scene-universal.cpp
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
#include "../irda-app.hpp"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SubmenuIndexUniversalTV,
|
||||||
|
SubmenuIndexUniversalAudio,
|
||||||
|
SubmenuIndexUniversalAirConditioner,
|
||||||
|
} SubmenuIndex;
|
||||||
|
|
||||||
|
static void submenu_callback(void* context, uint32_t index) {
|
||||||
|
IrdaApp* app = static_cast<IrdaApp*>(context);
|
||||||
|
IrdaAppEvent event;
|
||||||
|
|
||||||
|
event.type = IrdaAppEvent::Type::MenuSelected;
|
||||||
|
event.payload.menu_index = index;
|
||||||
|
|
||||||
|
app->get_view_manager()->send_event(&event);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneUniversal::on_enter(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_add_item(submenu, "TV's", SubmenuIndexUniversalTV, submenu_callback, app);
|
||||||
|
submenu_add_item(submenu, "Audio Players", SubmenuIndexUniversalAudio, submenu_callback, app);
|
||||||
|
submenu_add_item(
|
||||||
|
submenu, "Air Conditioners", SubmenuIndexUniversalAirConditioner, submenu_callback, app);
|
||||||
|
|
||||||
|
view_manager->switch_to(IrdaAppViewManager::ViewType::Submenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IrdaAppSceneUniversal::on_event(IrdaApp* app, IrdaAppEvent* event) {
|
||||||
|
bool consumed = false;
|
||||||
|
|
||||||
|
if(event->type == IrdaAppEvent::Type::MenuSelected) {
|
||||||
|
switch(event->payload.menu_index) {
|
||||||
|
case SubmenuIndexUniversalTV:
|
||||||
|
// app->switch_to_next_scene(IrdaApp::Scene::UniversalTV);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexUniversalAudio:
|
||||||
|
// app->switch_to_next_scene(IrdaApp::Scene::UniversalAudio);
|
||||||
|
break;
|
||||||
|
case SubmenuIndexUniversalAirConditioner:
|
||||||
|
// app->switch_to_next_scene(IrdaApp::Scene::UniversalAirConditioner);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
consumed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return consumed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IrdaAppSceneUniversal::on_exit(IrdaApp* app) {
|
||||||
|
IrdaAppViewManager* view_manager = app->get_view_manager();
|
||||||
|
Submenu* submenu = view_manager->get_submenu();
|
||||||
|
|
||||||
|
submenu_clean(submenu);
|
||||||
|
}
|
130
applications/irda/scene/irda-app-scene.hpp
Normal file
130
applications/irda/scene/irda-app-scene.hpp
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "../irda-app.hpp"
|
||||||
|
#include <api-hal-irda.h>
|
||||||
|
#include "irda.h"
|
||||||
|
#include <gui/elements.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class IrdaApp;
|
||||||
|
|
||||||
|
class IrdaAppScene {
|
||||||
|
public:
|
||||||
|
virtual void on_enter(IrdaApp* app) = 0;
|
||||||
|
virtual bool on_event(IrdaApp* app, IrdaAppEvent* event) = 0;
|
||||||
|
virtual void on_exit(IrdaApp* app) = 0;
|
||||||
|
virtual ~IrdaAppScene(){};
|
||||||
|
|
||||||
|
private:
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneStart : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneUniversal : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneLearn : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneLearnSuccess : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneLearnEnterName : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneLearnDone : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneLearnDoneAfter : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneRemote : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
private:
|
||||||
|
std::vector<std::string> buttons_names;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneRemoteList : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
std::vector<std::string> remote_names;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneEdit : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneEditKeySelect : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
private:
|
||||||
|
std::vector<std::string> buttons_names;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneEditRename : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneEditDelete : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneEditRenameDone : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
||||||
|
class IrdaAppSceneEditDeleteDone : public IrdaAppScene {
|
||||||
|
public:
|
||||||
|
void on_enter(IrdaApp* app) final;
|
||||||
|
bool on_event(IrdaApp* app, IrdaAppEvent* event) final;
|
||||||
|
void on_exit(IrdaApp* app) final;
|
||||||
|
};
|
||||||
|
|
@ -110,9 +110,11 @@ int32_t irda_monitor_app(void* p) {
|
|||||||
snprintf(
|
snprintf(
|
||||||
irda_monitor->display_text,
|
irda_monitor->display_text,
|
||||||
sizeof(irda_monitor->display_text),
|
sizeof(irda_monitor->display_text),
|
||||||
"%s\nA:0x%02lX\nC:0x%02lX\n%s\n",
|
"%s\nA:0x%0*lX\nC:0x%0*lX\n%s\n",
|
||||||
irda_get_protocol_name(message->protocol),
|
irda_get_protocol_name(message->protocol),
|
||||||
|
irda_get_protocol_address_length(message->protocol),
|
||||||
message->address,
|
message->address,
|
||||||
|
irda_get_protocol_command_length(message->protocol),
|
||||||
message->command,
|
message->command,
|
||||||
message->repeat ? " R" : "");
|
message->repeat ? " R" : "");
|
||||||
view_port_update(view_port);
|
view_port_update(view_port);
|
||||||
@ -124,9 +126,11 @@ int32_t irda_monitor_app(void* p) {
|
|||||||
if(message || (distance > (IRDA_TIMINGS_SIZE / 2))) {
|
if(message || (distance > (IRDA_TIMINGS_SIZE / 2))) {
|
||||||
if(message) {
|
if(message) {
|
||||||
printf(
|
printf(
|
||||||
"== %s, A:0x%02lX, C:0x%02lX%s ==\r\n",
|
"== %s, A:0x%0*lX, C:0x%0*lX%s ==\r\n",
|
||||||
irda_get_protocol_name(message->protocol),
|
irda_get_protocol_name(message->protocol),
|
||||||
|
irda_get_protocol_address_length(message->protocol),
|
||||||
message->address,
|
message->address,
|
||||||
|
irda_get_protocol_command_length(message->protocol),
|
||||||
message->command,
|
message->command,
|
||||||
message->repeat ? " R" : "");
|
message->repeat ? " R" : "");
|
||||||
} else {
|
} else {
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#include "../minunit.h"
|
#include "../minunit.h"
|
||||||
#include "irda.h"
|
#include "irda.h"
|
||||||
#include "test_data/irda_decoder_nec_test_data.srcdata"
|
#include "test_data/irda_decoder_nec_test_data.srcdata"
|
||||||
|
#include "test_data/irda_decoder_necext_test_data.srcdata"
|
||||||
#include "test_data/irda_decoder_samsung_test_data.srcdata"
|
#include "test_data/irda_decoder_samsung_test_data.srcdata"
|
||||||
|
|
||||||
#define RUN_DECODER(data, expected) \
|
#define RUN_DECODER(data, expected) \
|
||||||
@ -52,10 +53,12 @@ MU_TEST(test_samsung32) {
|
|||||||
RUN_DECODER(test_samsung32_input1, test_samsung32_expected1);
|
RUN_DECODER(test_samsung32_input1, test_samsung32_expected1);
|
||||||
}
|
}
|
||||||
|
|
||||||
MU_TEST(test_mix_nec_samsung32) {
|
MU_TEST(test_mix) {
|
||||||
|
RUN_DECODER(test_necext_input1, test_necext_expected1);
|
||||||
RUN_DECODER(test_samsung32_input1, test_samsung32_expected1);
|
RUN_DECODER(test_samsung32_input1, test_samsung32_expected1);
|
||||||
RUN_DECODER(test_nec_input1, test_nec_expected1);
|
RUN_DECODER(test_nec_input1, test_nec_expected1);
|
||||||
RUN_DECODER(test_samsung32_input1, test_samsung32_expected1);
|
RUN_DECODER(test_samsung32_input1, test_samsung32_expected1);
|
||||||
|
RUN_DECODER(test_necext_input1, test_necext_expected1);
|
||||||
RUN_DECODER(test_nec_input2, test_nec_expected2);
|
RUN_DECODER(test_nec_input2, test_nec_expected2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,6 +78,11 @@ MU_TEST(test_unexpected_end_in_sequence) {
|
|||||||
RUN_DECODER(test_nec_input2, test_nec_expected2);
|
RUN_DECODER(test_nec_input2, test_nec_expected2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MU_TEST(test_necext1) {
|
||||||
|
RUN_DECODER(test_necext_input1, test_necext_expected1);
|
||||||
|
RUN_DECODER(test_necext_input1, test_necext_expected1);
|
||||||
|
}
|
||||||
|
|
||||||
MU_TEST_SUITE(test_irda_decoder) {
|
MU_TEST_SUITE(test_irda_decoder) {
|
||||||
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
MU_SUITE_CONFIGURE(&test_setup, &test_teardown);
|
||||||
|
|
||||||
@ -82,7 +90,8 @@ MU_TEST_SUITE(test_irda_decoder) {
|
|||||||
MU_RUN_TEST(test_nec1);
|
MU_RUN_TEST(test_nec1);
|
||||||
MU_RUN_TEST(test_nec2);
|
MU_RUN_TEST(test_nec2);
|
||||||
MU_RUN_TEST(test_samsung32);
|
MU_RUN_TEST(test_samsung32);
|
||||||
MU_RUN_TEST(test_mix_nec_samsung32);
|
MU_RUN_TEST(test_necext1);
|
||||||
|
MU_RUN_TEST(test_mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
int run_minunit_test_irda_decoder() {
|
int run_minunit_test_irda_decoder() {
|
||||||
|
@ -11,9 +11,9 @@ const uint32_t test_nec_input1[] = {
|
|||||||
1415838, 9080, 4436, 611, 494, 600, 505, 578, 500, 608, 501, 602, 502, 580, 498, 606, 508, 605, 500, 583, 1633, 608, 1608, 611, 1631, 578, 1638, 602, 1614, 606, 1637, 583, 1633, 607, 1609, 611, 494, 600, 505, 570, 500, 604, 501, 602, 502, 581, 497, 606, 499, 605, 499, 583, 1633, 617, 1608, 611, 1631, 579, 1638, 602};
|
1415838, 9080, 4436, 611, 494, 600, 505, 578, 500, 608, 501, 602, 502, 580, 498, 606, 508, 605, 500, 583, 1633, 608, 1608, 611, 1631, 578, 1638, 602, 1614, 606, 1637, 583, 1633, 607, 1609, 611, 494, 600, 505, 570, 500, 604, 501, 602, 502, 581, 497, 606, 499, 605, 499, 583, 1633, 617, 1608, 611, 1631, 579, 1638, 602};
|
||||||
|
|
||||||
const IrdaMessage test_nec_expected1[] = {
|
const IrdaMessage test_nec_expected1[] = {
|
||||||
{IrdaProtocolNEC, 0xFF00, 0, false},
|
{IrdaProtocolNEC, 0x00, 0, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0, true},
|
{IrdaProtocolNEC, 0x00, 0, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0, false},
|
{IrdaProtocolNEC, 0x00, 0, false},
|
||||||
};
|
};
|
||||||
|
|
||||||
const uint32_t test_nec_input2[] = {
|
const uint32_t test_nec_input2[] = {
|
||||||
@ -124,57 +124,57 @@ const uint32_t test_nec_input2[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const IrdaMessage test_nec_expected2[] = {
|
const IrdaMessage test_nec_expected2[] = {
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, false},
|
{IrdaProtocolNEC, 0x00, 0x02, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, false},
|
{IrdaProtocolNEC, 0x00, 0x02, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x02, true},
|
{IrdaProtocolNEC, 0x00, 0x02, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x06, false},
|
{IrdaProtocolNEC, 0x00, 0x06, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x06, true},
|
{IrdaProtocolNEC, 0x00, 0x06, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x04, false},
|
{IrdaProtocolNEC, 0x00, 0x04, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x04, true},
|
{IrdaProtocolNEC, 0x00, 0x04, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, true},
|
{IrdaProtocolNEC, 0x00, 0x08, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, true},
|
{IrdaProtocolNEC, 0x00, 0x08, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x09, false},
|
{IrdaProtocolNEC, 0x00, 0x09, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x09, false},
|
{IrdaProtocolNEC, 0x00, 0x09, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x09, false},
|
{IrdaProtocolNEC, 0x00, 0x09, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x0A, false},
|
{IrdaProtocolNEC, 0x00, 0x0A, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, true},
|
{IrdaProtocolNEC, 0x00, 0x08, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, true},
|
{IrdaProtocolNEC, 0x00, 0x08, true},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x0A, false},
|
{IrdaProtocolNEC, 0x00, 0x0A, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x08, false},
|
{IrdaProtocolNEC, 0x00, 0x08, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x0A, false},
|
{IrdaProtocolNEC, 0x00, 0x0A, false},
|
||||||
{IrdaProtocolNEC, 0xFF00, 0x0A, true},
|
{IrdaProtocolNEC, 0x00, 0x0A, true},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -0,0 +1,223 @@
|
|||||||
|
const uint32_t test_necext_input1[] = {
|
||||||
|
1915384, 8967, 4463, 587, 527, 590, 524, 584, 1647, 590, 524, 583, 531, 586, 527, 590, 524, 583, 1646, 589, 1640, 586, 527, 590, 524, 583, 1647, 590, 1640, 587, 1644, 582, 1647, 589, 524, 583, 531, 586, 1644, 593, 521, 586, 527, 589, 1641, 586, 528, 589, 525, 592, 521, 585, 1644, 592, 522, 585, 1645, 592, 1638, 589, 524, 592, 1637, 588, 1641, 585, 1645, 592,
|
||||||
|
41082, 8965, 2220, 591,
|
||||||
|
409594, 8972, 4458, 591, 523, 584, 530, 587, 1642, 584, 529, 588, 526, 591, 522, 583, 530, 587, 1643, 584, 1646, 590, 523, 584, 530, 587, 1643, 584, 1647, 590, 1640, 586, 1643, 583, 531, 586, 527, 589, 1641, 586, 528, 589, 524, 593, 1637, 589, 524, 593, 521, 586, 529, 589, 1641, 585, 528, 589, 1640, 586, 1644, 592, 521, 585, 1645, 592, 1638, 588, 1641, 585,
|
||||||
|
41088, 8968, 2218, 582,
|
||||||
|
95791, 8971, 2214, 587,
|
||||||
|
95787, 8965, 2220, 591,
|
||||||
|
95783, 8971, 2215, 585,
|
||||||
|
95787, 8964, 2221, 590,
|
||||||
|
95783, 8971, 2215, 586,
|
||||||
|
95788, 8965, 2220, 591,
|
||||||
|
95783, 8969, 2216, 585,
|
||||||
|
95789, 8965, 2220, 590,
|
||||||
|
95782, 8970, 2215, 586,
|
||||||
|
95788, 9047, 2139, 591,
|
||||||
|
95782, 8970, 2216, 585,
|
||||||
|
95788, 8966, 2220, 591,
|
||||||
|
95782, 8972, 2214, 588,
|
||||||
|
95786, 8964, 2222, 590,
|
||||||
|
95784, 8971, 2214, 586,
|
||||||
|
95787, 8967, 2218, 583,
|
||||||
|
95791, 8964, 2222, 588,
|
||||||
|
95785, 8969, 2217, 584,
|
||||||
|
333740, 8967, 4464, 586, 528, 590, 524, 592, 1637, 589, 525, 592, 521, 586, 528, 589, 525, 593, 1637, 588, 1640, 585, 528, 589, 525, 592, 1638, 589, 1641, 586, 1644, 592, 1638, 588, 525, 592, 522, 585, 1644, 592, 522, 585, 528, 588, 1642, 585, 529, 588, 526, 591, 522, 585, 1645, 591, 522, 584, 1646, 591, 1639, 587, 526, 591, 1639, 588, 1642, 583, 1646, 590,
|
||||||
|
41082, 8963, 2223, 588,
|
||||||
|
95785, 8967, 2219, 591,
|
||||||
|
95782, 8968, 2217, 584,
|
||||||
|
246369, 8972, 4459, 591, 523, 583, 530, 587, 1643, 583, 530, 587, 527, 590, 523, 584, 530, 586, 1643, 583, 1647, 590, 524, 583, 530, 586, 1643, 583, 1646, 589, 1641, 586, 1644, 583, 531, 586, 528, 589, 1640, 585, 528, 588, 525, 592, 1638, 588, 525, 592, 522, 585, 529, 589, 1641, 584, 529, 588, 1642, 585, 1645, 591, 522, 585, 1645, 590, 1639, 587, 1642, 584,
|
||||||
|
41090, 8966, 2220, 591,
|
||||||
|
95782, 8966, 2220, 592,
|
||||||
|
95782, 8967, 2218, 583,
|
||||||
|
165604, 9017, 4413, 586, 527, 590, 524, 583, 1647, 589, 523, 582, 531, 586, 528, 589, 525, 593, 1637, 589, 1640, 585, 527, 588, 525, 592, 1638, 589, 1641, 585, 1644, 592, 1638, 588, 525, 591, 523, 585, 1645, 591, 522, 584, 529, 588, 1642, 584, 530, 587, 527, 591, 523, 584, 1646, 591, 523, 584, 1646, 591, 1640, 586, 527, 590, 1640, 586, 1643, 583, 1646, 589,
|
||||||
|
41084, 8972, 2214, 587,
|
||||||
|
95787, 8967, 2219, 581,
|
||||||
|
95792, 8971, 2215, 586,
|
||||||
|
208929, 9016, 4414, 584, 529, 588, 526, 591, 1638, 588, 525, 591, 522, 584, 529, 587, 526, 591, 1639, 587, 1642, 584, 529, 588, 526, 591, 1638, 587, 1643, 584, 1646, 591, 1639, 587, 526, 590, 523, 584, 1646, 590, 524, 583, 530, 587, 1643, 583, 530, 587, 527, 590, 524, 583, 1647, 590, 524, 583, 1647, 590, 1640, 586, 527, 589, 1640, 586, 1644, 592, 1637, 589,
|
||||||
|
41085, 8972, 2214, 587,
|
||||||
|
95787, 8964, 2221, 590,
|
||||||
|
95784, 8965, 2221, 590,
|
||||||
|
167378, 8969, 4460, 589, 525, 582, 532, 586, 1644, 592, 521, 586, 528, 589, 524, 592, 522, 585, 1645, 592, 1638, 589, 525, 592, 522, 585, 1644, 591, 1639, 588, 1642, 585, 1645, 591, 522, 585, 529, 587, 1641, 584, 530, 587, 526, 591, 1639, 588, 526, 591, 522, 584, 530, 587, 1643, 584, 530, 587, 1642, 584, 1646, 591, 523, 584, 1647, 590, 1640, 587, 1643, 583,
|
||||||
|
41090, 9017, 2169, 591,
|
||||||
|
95781, 8969, 2216, 585,
|
||||||
|
95788, 8964, 2223, 588,
|
||||||
|
192781, 8969, 4461, 589, 525, 592, 522, 586, 1644, 592, 521, 586, 528, 589, 525, 592, 522, 585, 1644, 592, 1638, 589, 524, 592, 521, 586, 1645, 591, 1638, 588, 1642, 585, 1645, 590, 522, 584, 530, 587, 1642, 584, 530, 587, 526, 591, 1639, 588, 526, 590, 524, 583, 530, 587, 1643, 584, 530, 587, 1643, 584, 1646, 590, 524, 583, 1646, 590, 1640, 587, 1643, 583,
|
||||||
|
41090, 8967, 2219, 591,
|
||||||
|
95782, 8970, 2215, 586,
|
||||||
|
95788, 8963, 2222, 589,
|
||||||
|
179978, 8967, 4464, 586, 528, 589, 524, 593, 1637, 588, 525, 592, 522, 585, 529, 589, 525, 592, 1638, 589, 1641, 585, 529, 588, 526, 591, 1638, 588, 1641, 585, 1645, 590, 1639, 587, 527, 590, 523, 584, 1646, 591, 523, 584, 530, 587, 1643, 583, 530, 586, 527, 590, 524, 583, 1646, 590, 523, 584, 1646, 589, 1640, 586, 528, 589, 1640, 586, 1644, 593, 1638, 589,
|
||||||
|
41084, 8971, 2214, 587,
|
||||||
|
95787, 8964, 2221, 589,
|
||||||
|
95785, 8966, 2219, 592,
|
||||||
|
196616, 8967, 4463, 585, 527, 590, 525, 592, 1637, 589, 525, 592, 521, 586, 528, 589, 524, 592, 1638, 588, 1641, 585, 528, 589, 525, 592, 1637, 589, 1641, 585, 1645, 591, 1638, 588, 526, 591, 522, 585, 1645, 591, 522, 584, 530, 587, 1642, 584, 529, 588, 526, 591, 523, 583, 1645, 590, 523, 584, 1646, 590, 1639, 587, 527, 590, 1639, 586, 1644, 583, 1647, 589,
|
||||||
|
41084, 8971, 2214, 587,
|
||||||
|
95787, 8964, 2222, 589,
|
||||||
|
2112164, 8969, 4462, 588, 525, 592, 522, 585, 1645, 591, 523, 584, 529, 588, 526, 591, 523, 584, 1645, 591, 1639, 587, 527, 590, 524, 583, 1646, 590, 1639, 587, 1643, 584, 1673, 563, 524, 583, 531, 586, 1643, 593, 521, 586, 528, 589, 1641, 585, 528, 589, 525, 592, 521, 585, 1644, 592, 522, 584, 1645, 591, 1639, 588, 526, 591, 1639, 588, 1642, 583, 1646, 590,
|
||||||
|
41082, 8962, 2223, 588,
|
||||||
|
95785, 8965, 2220, 591,
|
||||||
|
95783, 8968, 2217, 583,
|
||||||
|
164778, 8969, 4462, 588, 525, 591, 522, 585, 1645, 591, 522, 585, 530, 587, 527, 591, 523, 584, 1646, 591, 1639, 588, 526, 591, 523, 583, 1646, 590, 1639, 587, 1643, 584, 1672, 564, 523, 584, 531, 586, 1643, 583, 530, 587, 527, 590, 1639, 587, 527, 589, 524, 583, 531, 586, 1644, 583, 531, 586, 1643, 583, 1647, 590, 525, 582, 1647, 589, 1639, 586, 1644, 593,
|
||||||
|
41081, 8965, 2220, 590,
|
||||||
|
95784, 8968, 2217, 583,
|
||||||
|
95790, 8970, 2215, 586,
|
||||||
|
161053, 8963, 4468, 592, 521, 586, 528, 589, 1641, 585, 529, 588, 526, 591, 522, 585, 529, 588, 1642, 585, 1645, 591, 523, 584, 530, 587, 1642, 584, 1646, 591, 1639, 586, 1669, 557, 531, 586, 527, 590, 1640, 586, 527, 590, 525, 592, 1638, 589, 525, 592, 522, 585, 528, 588, 1641, 585, 528, 588, 1642, 584, 1645, 591, 523, 584, 1645, 591, 1639, 587, 1643, 583,
|
||||||
|
41090, 8964, 2221, 590,
|
||||||
|
95784, 8963, 2222, 589,
|
||||||
|
95785, 8965, 2220, 590,
|
||||||
|
139334, 8968, 4463, 587, 527, 590, 523, 584, 1646, 590, 523, 583, 531, 586, 527, 589, 524, 583, 1647, 590, 1640, 586, 527, 590, 525, 592, 1637, 589, 1641, 585, 1644, 592, 1665, 562, 524, 591, 522, 584, 1645, 591, 523, 584, 529, 588, 1642, 584, 529, 587, 527, 590, 523, 584, 1646, 590, 523, 584, 1646, 590, 1639, 587, 527, 589, 1640, 586, 1644, 592, 1637, 589,
|
||||||
|
41085, 8970, 2217, 584,
|
||||||
|
95789, 8972, 2213, 586,
|
||||||
|
95787, 8965, 2221, 590,
|
||||||
|
141444, 8969, 4461, 589, 525, 592, 522, 584, 1644, 591, 522, 585, 529, 588, 526, 591, 522, 585, 1645, 592, 1638, 587, 526, 591, 523, 584, 1646, 591, 1639, 588, 1642, 583, 1672, 564, 523, 584, 530, 587, 1643, 584, 530, 587, 527, 590, 1640, 587, 527, 590, 524, 584, 530, 587, 1643, 584, 530, 586, 1644, 583, 1647, 589, 524, 583, 1647, 590, 1640, 586, 1645, 592,
|
||||||
|
41081, 8964, 2222, 589,
|
||||||
|
95784, 8968, 2218, 583,
|
||||||
|
95790, 8971, 2214, 586,
|
||||||
|
154119, 8969, 4462, 588, 526, 591, 522, 585, 1645, 592, 522, 585, 529, 589, 526, 591, 522, 584, 1646, 591, 1639, 588, 526, 591, 523, 583, 1645, 590, 1639, 587, 1642, 584, 1671, 564, 523, 584, 529, 587, 1643, 583, 530, 587, 527, 590, 1639, 587, 526, 590, 523, 583, 530, 586, 1643, 583, 529, 586, 1643, 583, 1646, 590, 524, 583, 1648, 589, 1641, 586, 1644, 592,
|
||||||
|
41081, 8965, 2220, 590,
|
||||||
|
95784, 8969, 2216, 585,
|
||||||
|
95790, 8964, 2221, 590,
|
||||||
|
147134, 8966, 4464, 586, 528, 589, 525, 593, 1637, 589, 524, 593, 522, 585, 529, 589, 525, 592, 1638, 589, 1641, 586, 528, 589, 525, 591, 1638, 588, 1641, 585, 1645, 592, 1664, 561, 525, 592, 523, 584, 1646, 591, 523, 584, 530, 588, 1642, 585, 526, 587, 527, 590, 523, 584, 1646, 591, 523, 584, 1646, 591, 1639, 586, 526, 590, 1640, 587, 1643, 583, 1646, 590,
|
||||||
|
41083, 8963, 2223, 587,
|
||||||
|
95786, 8965, 2221, 590,
|
||||||
|
95784, 8968, 2217, 584,
|
||||||
|
158330, 8965, 4465, 585, 529, 588, 526, 590, 1639, 587, 526, 590, 523, 584, 530, 586, 526, 590, 1639, 587, 1643, 583, 530, 587, 527, 590, 1639, 587, 1643, 584, 1647, 590, 1666, 561, 527, 589, 523, 583, 1646, 590, 523, 583, 531, 586, 1643, 583, 530, 586, 527, 590, 524, 582, 1646, 590, 525, 582, 1647, 589, 1640, 586, 528, 589, 1640, 586, 1644, 592, 1638, 589,
|
||||||
|
41085, 8971, 2214, 586,
|
||||||
|
95787, 8962, 2223, 588,
|
||||||
|
95786, 8965, 2222, 589,
|
||||||
|
206063, 8962, 4467, 591, 521, 585, 529, 588, 1642, 585, 529, 588, 525, 591, 522, 584, 530, 587, 1642, 584, 1646, 591, 523, 584, 529, 588, 1642, 583, 1646, 590, 1640, 587, 1668, 558, 530, 587, 526, 589, 1639, 586, 528, 589, 524, 583, 1647, 589, 524, 593, 521, 585, 528, 589, 1641, 585, 529, 589, 1641, 585, 1645, 592, 522, 585, 1644, 591, 1639, 587, 1642, 584,
|
||||||
|
41090, 8965, 2221, 590,
|
||||||
|
95784, 8963, 2223, 588,
|
||||||
|
95785, 8964, 2222, 589,
|
||||||
|
183026, 8970, 4460, 590, 524, 583, 531, 586, 1643, 583, 530, 587, 528, 589, 525, 592, 522, 586, 1644, 592, 1637, 588, 525, 591, 522, 585, 1645, 592, 1638, 588, 1641, 585, 1672, 565, 522, 584, 530, 588, 1642, 584, 529, 588, 526, 591, 1639, 587, 527, 590, 523, 584, 530, 587, 1642, 584, 530, 587, 1642, 583, 1647, 590, 524, 583, 1647, 590, 1640, 587, 1643, 582,
|
||||||
|
41090, 8965, 2221, 590,
|
||||||
|
95783, 8970, 2216, 584,
|
||||||
|
95789, 8962, 2223, 587,
|
||||||
|
184104, 8964, 4467, 583, 530, 587, 527, 590, 1640, 587, 527, 590, 523, 582, 531, 586, 528, 589, 1640, 586, 1644, 593, 521, 586, 528, 589, 1640, 585, 1644, 592, 1638, 589, 1667, 558, 528, 589, 526, 591, 1638, 588, 526, 591, 522, 585, 1645, 591, 522, 585, 530, 587, 527, 591, 1639, 587, 526, 591, 1639, 587, 1642, 584, 530, 587, 1643, 583, 1646, 590, 1639, 587,
|
||||||
|
41087, 9020, 2166, 584,
|
||||||
|
95790, 8972, 2213, 587,
|
||||||
|
95787, 8963, 2222, 589,
|
||||||
|
169833, 8964, 4465, 583, 529, 587, 527, 590, 1639, 587, 527, 591, 523, 584, 530, 586, 527, 590, 1640, 587, 1643, 583, 531, 587, 527, 590, 1640, 586, 1644, 583, 1647, 590, 1666, 560, 527, 590, 524, 582, 1647, 589, 525, 592, 521, 586, 1644, 592, 521, 586, 528, 589, 526, 592, 1638, 588, 525, 592, 1638, 589, 1641, 585, 528, 589, 1641, 585, 1645, 591, 1638, 588,
|
||||||
|
41086, 8971, 2215, 585,
|
||||||
|
95789, 8964, 2222, 588,
|
||||||
|
95785, 8967, 2218, 583,
|
||||||
|
185701, 8971, 4460, 590, 523, 584, 530, 587, 1642, 584, 530, 587, 527, 590, 524, 583, 531, 586, 1644, 583, 1647, 590, 524, 592, 521, 585, 1644, 592, 1638, 589, 1641, 585, 1671, 565, 522, 586, 529, 588, 1642, 585, 529, 588, 526, 591, 1638, 588, 525, 590, 523, 584, 530, 587, 1642, 584, 530, 587, 1642, 584, 1646, 590, 524, 583, 1646, 590, 1640, 586, 1643, 583,
|
||||||
|
41091, 8965, 2222, 589,
|
||||||
|
95784, 8965, 2221, 589,
|
||||||
|
95784, 8968, 2217, 583,
|
||||||
|
146332, 8969, 4461, 669, 445, 591, 522, 584, 1644, 591, 523, 584, 529, 588, 526, 591, 522, 585, 1645, 591, 1638, 587, 527, 590, 524, 584, 1646, 590, 1639, 587, 1642, 583, 1673, 564, 524, 583, 531, 586, 1643, 583, 531, 586, 528, 589, 1641, 585, 528, 589, 525, 592, 522, 585, 1644, 591, 521, 585, 1645, 592, 1638, 588, 525, 592, 1638, 588, 1641, 584, 1646, 591,
|
||||||
|
41083, 8963, 2222, 589,
|
||||||
|
95785, 8966, 2220, 592,
|
||||||
|
261924, 8965, 4465, 585, 529, 588, 525, 592, 1638, 588, 525, 592, 523, 584, 530, 587, 526, 591, 1639, 587, 1642, 583, 529, 587, 527, 590, 1639, 587, 1643, 584, 1646, 590,
|
||||||
|
};
|
||||||
|
|
||||||
|
const IrdaMessage test_necext_expected1[] = {
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, false},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
{IrdaProtocolNECext, 0x7984, 0x12, true},
|
||||||
|
};
|
||||||
|
|
BIN
assets/icons/Irda/IrdaArrowDown_4x8.png
Normal file
BIN
assets/icons/Irda/IrdaArrowDown_4x8.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
assets/icons/Irda/IrdaArrowUp_4x8.png
Normal file
BIN
assets/icons/Irda/IrdaArrowUp_4x8.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
assets/icons/Irda/IrdaLearnShort_128x31.png
Normal file
BIN
assets/icons/Irda/IrdaLearnShort_128x31.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/icons/Irda/IrdaLearn_128x64.png
Normal file
BIN
assets/icons/Irda/IrdaLearn_128x64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
BIN
assets/icons/Irda/IrdaSendShort_128x34.png
Normal file
BIN
assets/icons/Irda/IrdaSendShort_128x34.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.9 KiB |
BIN
assets/icons/Irda/IrdaSend_128x64.png
Normal file
BIN
assets/icons/Irda/IrdaSend_128x64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
@ -1,6 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "check.h"
|
#include "check.h"
|
||||||
|
|
||||||
@ -11,11 +12,6 @@ extern "C" {
|
|||||||
// define for test case "link against furi memmgr"
|
// define for test case "link against furi memmgr"
|
||||||
#define FURI_MEMMGR_GUARD 1
|
#define FURI_MEMMGR_GUARD 1
|
||||||
|
|
||||||
void* malloc(size_t size);
|
|
||||||
void free(void* ptr);
|
|
||||||
void* realloc(void* ptr, size_t size);
|
|
||||||
void* calloc(size_t count, size_t size);
|
|
||||||
|
|
||||||
size_t memmgr_get_free_heap(void);
|
size_t memmgr_get_free_heap(void);
|
||||||
size_t memmgr_get_minimum_free_heap(void);
|
size_t memmgr_get_minimum_free_heap(void);
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ struct IrdaHandler {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
IrdaAlloc alloc;
|
IrdaAlloc alloc;
|
||||||
IrdaDecode decode;
|
IrdaDecode decode;
|
||||||
|
IrdaReset reset;
|
||||||
IrdaFree free;
|
IrdaFree free;
|
||||||
} IrdaDecoders;
|
} IrdaDecoders;
|
||||||
|
|
||||||
@ -24,6 +25,8 @@ typedef struct {
|
|||||||
const char* name;
|
const char* name;
|
||||||
IrdaDecoders decoder;
|
IrdaDecoders decoder;
|
||||||
IrdaEncoders encoder;
|
IrdaEncoders encoder;
|
||||||
|
uint8_t address_length;
|
||||||
|
uint8_t command_length;
|
||||||
} IrdaProtocolImplementation;
|
} IrdaProtocolImplementation;
|
||||||
|
|
||||||
|
|
||||||
@ -35,9 +38,12 @@ static const IrdaProtocolImplementation irda_protocols[] = {
|
|||||||
.decoder = {
|
.decoder = {
|
||||||
.alloc = irda_decoder_samsung32_alloc,
|
.alloc = irda_decoder_samsung32_alloc,
|
||||||
.decode = irda_decoder_samsung32_decode,
|
.decode = irda_decoder_samsung32_decode,
|
||||||
|
.reset = irda_decoder_samsung32_reset,
|
||||||
.free = irda_decoder_samsung32_free},
|
.free = irda_decoder_samsung32_free},
|
||||||
.encoder = {
|
.encoder = {
|
||||||
.encode = irda_encoder_samsung32_encode}
|
.encode = irda_encoder_samsung32_encode},
|
||||||
|
.address_length = 2,
|
||||||
|
.command_length = 2,
|
||||||
},
|
},
|
||||||
// #1
|
// #1
|
||||||
{ .protocol = IrdaProtocolNEC,
|
{ .protocol = IrdaProtocolNEC,
|
||||||
@ -45,9 +51,25 @@ static const IrdaProtocolImplementation irda_protocols[] = {
|
|||||||
.decoder = {
|
.decoder = {
|
||||||
.alloc = irda_decoder_nec_alloc,
|
.alloc = irda_decoder_nec_alloc,
|
||||||
.decode = irda_decoder_nec_decode,
|
.decode = irda_decoder_nec_decode,
|
||||||
|
.reset = irda_decoder_nec_reset,
|
||||||
.free = irda_decoder_nec_free},
|
.free = irda_decoder_nec_free},
|
||||||
.encoder = {
|
.encoder = {
|
||||||
.encode = irda_encoder_nec_encode}
|
.encode = irda_encoder_nec_encode},
|
||||||
|
.address_length = 2,
|
||||||
|
.command_length = 2,
|
||||||
|
},
|
||||||
|
// #2
|
||||||
|
{ .protocol = IrdaProtocolNECext,
|
||||||
|
.name = "NECext",
|
||||||
|
.decoder = {
|
||||||
|
.alloc = irda_decoder_necext_alloc,
|
||||||
|
.decode = irda_decoder_nec_decode,
|
||||||
|
.reset = irda_decoder_nec_reset,
|
||||||
|
.free = irda_decoder_nec_free},
|
||||||
|
.encoder = {
|
||||||
|
.encode = irda_encoder_necext_encode},
|
||||||
|
.address_length = 4,
|
||||||
|
.command_length = 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -93,6 +115,12 @@ void irda_free_decoder(IrdaHandler* handler) {
|
|||||||
free(handler);
|
free(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void irda_reset_decoder(IrdaHandler* handler) {
|
||||||
|
for (int i = 0; i < COUNT_OF(irda_protocols); ++i) {
|
||||||
|
irda_protocols[i].decoder.reset(handler->ctx[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void irda_send(const IrdaMessage* message, int times) {
|
void irda_send(const IrdaMessage* message, int times) {
|
||||||
furi_assert(message);
|
furi_assert(message);
|
||||||
|
|
||||||
@ -109,3 +137,11 @@ const char* irda_get_protocol_name(IrdaProtocol protocol) {
|
|||||||
return irda_protocols[protocol].name;
|
return irda_protocols[protocol].name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8_t irda_get_protocol_address_length(IrdaProtocol protocol) {
|
||||||
|
return irda_protocols[protocol].address_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t irda_get_protocol_command_length(IrdaProtocol protocol) {
|
||||||
|
return irda_protocols[protocol].command_length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ typedef struct IrdaHandler IrdaHandler;
|
|||||||
typedef enum {
|
typedef enum {
|
||||||
IrdaProtocolSamsung32 = 0,
|
IrdaProtocolSamsung32 = 0,
|
||||||
IrdaProtocolNEC = 1,
|
IrdaProtocolNEC = 1,
|
||||||
|
IrdaProtocolNECext = 2,
|
||||||
} IrdaProtocol;
|
} IrdaProtocol;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -50,6 +51,13 @@ const IrdaMessage* irda_decode(IrdaHandler* handler, bool level, uint32_t durati
|
|||||||
*/
|
*/
|
||||||
void irda_free_decoder(IrdaHandler* handler);
|
void irda_free_decoder(IrdaHandler* handler);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset IRDA decoder.
|
||||||
|
*
|
||||||
|
* \param[in] handler - handler to irda decoders. Should be aquired with \c irda_alloc_decoder().
|
||||||
|
*/
|
||||||
|
void irda_reset_decoder(IrdaHandler* handler);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Send message over IRDA.
|
* Send message over IRDA.
|
||||||
*
|
*
|
||||||
@ -66,6 +74,22 @@ void irda_send(const IrdaMessage* message, int times);
|
|||||||
*/
|
*/
|
||||||
const char* irda_get_protocol_name(IrdaProtocol protocol);
|
const char* irda_get_protocol_name(IrdaProtocol protocol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get address length by protocol enum.
|
||||||
|
*
|
||||||
|
* \param[in] protocol - protocol identifier.
|
||||||
|
* \return length of address in nibbles.
|
||||||
|
*/
|
||||||
|
uint8_t irda_get_protocol_address_length(IrdaProtocol protocol);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get command length by protocol enum.
|
||||||
|
*
|
||||||
|
* \param[in] protocol - protocol identifier.
|
||||||
|
* \return length of command in nibbles.
|
||||||
|
*/
|
||||||
|
uint8_t irda_get_protocol_command_length(IrdaProtocol protocol);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#include "irda_common_decoder_i.h"
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include "irda_i.h"
|
#include "irda_i.h"
|
||||||
@ -164,3 +165,12 @@ void irda_common_decoder_free(void* decoder) {
|
|||||||
free(decoder);
|
free(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void irda_common_decoder_reset(void* decoder) {
|
||||||
|
furi_assert(decoder);
|
||||||
|
IrdaCommonDecoder* common_decoder = decoder;
|
||||||
|
|
||||||
|
common_decoder->state = IrdaCommonStateWaitPreamble;
|
||||||
|
common_decoder->timings_cnt = 0;
|
||||||
|
common_decoder->databit_cnt = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -68,5 +68,6 @@ static inline void shift_left_array(uint32_t *array, uint32_t len, uint32_t shif
|
|||||||
IrdaMessage* irda_common_decode(IrdaCommonDecoder *decoder, bool level, uint32_t duration);
|
IrdaMessage* irda_common_decode(IrdaCommonDecoder *decoder, bool level, uint32_t duration);
|
||||||
void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec *protocol);
|
void* irda_common_decoder_alloc(const IrdaCommonProtocolSpec *protocol);
|
||||||
void irda_common_decoder_free(void* decoder);
|
void irda_common_decoder_free(void* decoder);
|
||||||
|
void irda_common_decoder_reset(void* decoder);
|
||||||
DecodeStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder);
|
DecodeStatus irda_common_decode_pdwm(IrdaCommonDecoder* decoder);
|
||||||
|
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
typedef void* (*IrdaAlloc) (void);
|
typedef void* (*IrdaAlloc) (void);
|
||||||
typedef IrdaMessage* (*IrdaDecode) (void* ctx, bool level, uint32_t duration);
|
typedef IrdaMessage* (*IrdaDecode) (void* ctx, bool level, uint32_t duration);
|
||||||
|
typedef void (*IrdaReset) (void*);
|
||||||
typedef void (*IrdaFree) (void*);
|
typedef void (*IrdaFree) (void*);
|
||||||
|
|
||||||
typedef void (*IrdaEncode)(uint32_t address, uint32_t command, bool repeat);
|
typedef void (*IrdaEncode)(uint32_t address, uint32_t command, bool repeat);
|
||||||
|
@ -36,7 +36,10 @@
|
|||||||
#define IRDA_NEC_BIT_TOLERANCE 120 // us
|
#define IRDA_NEC_BIT_TOLERANCE 120 // us
|
||||||
|
|
||||||
void* irda_decoder_nec_alloc(void);
|
void* irda_decoder_nec_alloc(void);
|
||||||
|
void* irda_decoder_necext_alloc(void);
|
||||||
void irda_encoder_nec_encode(uint32_t address, uint32_t command, bool repeat);
|
void irda_encoder_nec_encode(uint32_t address, uint32_t command, bool repeat);
|
||||||
|
void irda_encoder_necext_encode(uint32_t address, uint32_t command, bool repeat);
|
||||||
|
void irda_decoder_nec_reset(void* decoder);
|
||||||
void irda_decoder_nec_free(void* decoder);
|
void irda_decoder_nec_free(void* decoder);
|
||||||
IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration);
|
IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
@ -73,6 +76,7 @@ IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duratio
|
|||||||
|
|
||||||
void* irda_decoder_samsung32_alloc(void);
|
void* irda_decoder_samsung32_alloc(void);
|
||||||
void irda_encoder_samsung32_encode(uint32_t address, uint32_t command, bool repeat);
|
void irda_encoder_samsung32_encode(uint32_t address, uint32_t command, bool repeat);
|
||||||
|
void irda_decoder_samsung32_reset(void* decoder);
|
||||||
void irda_decoder_samsung32_free(void* decoder);
|
void irda_decoder_samsung32_free(void* decoder);
|
||||||
IrdaMessage* irda_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
|
IrdaMessage* irda_decoder_samsung32_decode(void* decoder, bool level, uint32_t duration);
|
||||||
|
|
||||||
|
@ -3,9 +3,12 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include "../irda_i.h"
|
#include "../irda_i.h"
|
||||||
|
|
||||||
|
|
||||||
static bool interpret_nec(IrdaCommonDecoder* decoder);
|
static bool interpret_nec(IrdaCommonDecoder* decoder);
|
||||||
|
static bool interpret_necext(IrdaCommonDecoder* decoder);
|
||||||
static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder);
|
static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder);
|
||||||
|
|
||||||
|
|
||||||
static const IrdaCommonProtocolSpec protocol_nec = {
|
static const IrdaCommonProtocolSpec protocol_nec = {
|
||||||
{
|
{
|
||||||
IRDA_NEC_PREAMBULE_MARK,
|
IRDA_NEC_PREAMBULE_MARK,
|
||||||
@ -23,15 +26,33 @@ static const IrdaCommonProtocolSpec protocol_nec = {
|
|||||||
decode_repeat_nec,
|
decode_repeat_nec,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const IrdaCommonProtocolSpec protocol_necext = {
|
||||||
|
{
|
||||||
|
IRDA_NEC_PREAMBULE_MARK,
|
||||||
|
IRDA_NEC_PREAMBULE_SPACE,
|
||||||
|
IRDA_NEC_BIT1_MARK,
|
||||||
|
IRDA_NEC_BIT1_SPACE,
|
||||||
|
IRDA_NEC_BIT0_MARK,
|
||||||
|
IRDA_NEC_BIT0_SPACE,
|
||||||
|
IRDA_NEC_PREAMBLE_TOLERANCE,
|
||||||
|
IRDA_NEC_BIT_TOLERANCE,
|
||||||
|
},
|
||||||
|
32,
|
||||||
|
irda_common_decode_pdwm,
|
||||||
|
interpret_necext,
|
||||||
|
decode_repeat_nec,
|
||||||
|
};
|
||||||
|
|
||||||
static bool interpret_nec(IrdaCommonDecoder* decoder) {
|
static bool interpret_nec(IrdaCommonDecoder* decoder) {
|
||||||
furi_assert(decoder);
|
furi_assert(decoder);
|
||||||
|
|
||||||
bool result = false;
|
bool result = false;
|
||||||
uint16_t address = decoder->data[0] | (decoder->data[1] << 8);
|
uint8_t address = decoder->data[0];
|
||||||
|
uint8_t address_inverse = decoder->data[1];
|
||||||
uint8_t command = decoder->data[2];
|
uint8_t command = decoder->data[2];
|
||||||
uint8_t command_inverse = decoder->data[3];
|
uint8_t command_inverse = decoder->data[3];
|
||||||
|
|
||||||
if((command == (uint8_t)~command_inverse)) {
|
if ((command == (uint8_t) ~command_inverse) && (address == (uint8_t) ~address_inverse)) {
|
||||||
decoder->message.command = command;
|
decoder->message.command = command;
|
||||||
decoder->message.address = address;
|
decoder->message.address = address;
|
||||||
decoder->message.repeat = false;
|
decoder->message.repeat = false;
|
||||||
@ -41,6 +62,24 @@ static bool interpret_nec(IrdaCommonDecoder* decoder) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some NEC's extensions allow 16 bit address
|
||||||
|
static bool interpret_necext(IrdaCommonDecoder* decoder) {
|
||||||
|
furi_assert(decoder);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
uint8_t command = decoder->data[2];
|
||||||
|
uint8_t command_inverse = decoder->data[3];
|
||||||
|
|
||||||
|
if(command == (uint8_t)~command_inverse) {
|
||||||
|
decoder->message.command = command;
|
||||||
|
decoder->message.address = decoder->data[0] | (decoder->data[1] << 8);
|
||||||
|
decoder->message.repeat = false;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// timings start from Space (delay between message and repeat)
|
// timings start from Space (delay between message and repeat)
|
||||||
static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder) {
|
static DecodeStatus decode_repeat_nec(IrdaCommonDecoder* decoder) {
|
||||||
furi_assert(decoder);
|
furi_assert(decoder);
|
||||||
@ -69,6 +108,10 @@ void* irda_decoder_nec_alloc(void) {
|
|||||||
return irda_common_decoder_alloc(&protocol_nec);
|
return irda_common_decoder_alloc(&protocol_nec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* irda_decoder_necext_alloc(void) {
|
||||||
|
return irda_common_decoder_alloc(&protocol_necext);
|
||||||
|
}
|
||||||
|
|
||||||
IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration) {
|
IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duration) {
|
||||||
return irda_common_decode(decoder, level, duration);
|
return irda_common_decode(decoder, level, duration);
|
||||||
}
|
}
|
||||||
@ -76,3 +119,8 @@ IrdaMessage* irda_decoder_nec_decode(void* decoder, bool level, uint32_t duratio
|
|||||||
void irda_decoder_nec_free(void* decoder) {
|
void irda_decoder_nec_free(void* decoder) {
|
||||||
irda_common_decoder_free(decoder);
|
irda_common_decoder_free(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void irda_decoder_nec_reset(void* decoder) {
|
||||||
|
irda_common_decoder_reset(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -42,3 +42,21 @@ void irda_encoder_nec_encode(uint32_t addr, uint32_t cmd, bool repeat) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some NEC's extensions allow 16 bit address
|
||||||
|
void irda_encoder_necext_encode(uint32_t addr, uint32_t cmd, bool repeat) {
|
||||||
|
uint16_t address = addr & 0xFFFF;
|
||||||
|
uint8_t command = cmd & 0xFF;
|
||||||
|
uint8_t command_inverse = (uint8_t) ~command;
|
||||||
|
|
||||||
|
if (!repeat) {
|
||||||
|
irda_encode_nec_preamble();
|
||||||
|
irda_encode_byte(&encoder_timings, (uint8_t) address);
|
||||||
|
irda_encode_byte(&encoder_timings, (uint8_t) (address >> 8));
|
||||||
|
irda_encode_byte(&encoder_timings, command);
|
||||||
|
irda_encode_byte(&encoder_timings, command_inverse);
|
||||||
|
irda_encode_bit(&encoder_timings, 1);
|
||||||
|
} else {
|
||||||
|
irda_encode_nec_repeat();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -85,3 +85,7 @@ void irda_decoder_samsung32_free(void* decoder) {
|
|||||||
irda_common_decoder_free(decoder);
|
irda_common_decoder_free(decoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void irda_decoder_samsung32_reset(void* decoder) {
|
||||||
|
irda_common_decoder_reset(decoder);
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user