|
@@ -39,9 +39,9 @@ typedef enum {
|
|
|
} SubGhzHopperState;
|
|
} SubGhzHopperState;
|
|
|
|
|
|
|
|
static const Icon* ReceiverItemIcons[] = {
|
|
static const Icon* ReceiverItemIcons[] = {
|
|
|
- [TYPE_PROTOCOL_UNKNOWN] = &I_quest_7x8,
|
|
|
|
|
- [TYPE_PROTOCOL_STATIC] = &I_unlock_7x8,
|
|
|
|
|
- [TYPE_PROTOCOL_DYNAMIC] = &I_lock_7x8,
|
|
|
|
|
|
|
+ [TYPE_PROTOCOL_UNKNOWN] = &I_Quest_7x8,
|
|
|
|
|
+ [TYPE_PROTOCOL_STATIC] = &I_Unlock_7x8,
|
|
|
|
|
+ [TYPE_PROTOCOL_DYNAMIC] = &I_Lock_7x8,
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
struct SubghzReceiver {
|
|
struct SubghzReceiver {
|
|
@@ -53,6 +53,7 @@ struct SubghzReceiver {
|
|
|
osTimerId timer;
|
|
osTimerId timer;
|
|
|
SubGhzHopperState hopper_state;
|
|
SubGhzHopperState hopper_state;
|
|
|
uint8_t hopper_timeout;
|
|
uint8_t hopper_timeout;
|
|
|
|
|
+ uint32_t event_key_sequence;
|
|
|
};
|
|
};
|
|
|
|
|
|
|
|
typedef struct {
|
|
typedef struct {
|
|
@@ -172,44 +173,40 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) {
|
|
|
string_clean(str_buff);
|
|
string_clean(str_buff);
|
|
|
}
|
|
}
|
|
|
if(scrollbar) {
|
|
if(scrollbar) {
|
|
|
- elements_scrollbar_pos(canvas, 126, 0, 49, model->idx, model->history_item);
|
|
|
|
|
|
|
+ elements_scrollbar_pos(canvas, 128, 0, 49, model->idx, model->history_item);
|
|
|
}
|
|
}
|
|
|
canvas_set_color(canvas, ColorBlack);
|
|
canvas_set_color(canvas, ColorBlack);
|
|
|
canvas_set_font(canvas, FontSecondary);
|
|
canvas_set_font(canvas, FontSecondary);
|
|
|
|
|
|
|
|
- elements_button_left(canvas, "Conf");
|
|
|
|
|
- if((model->real_frequency / 1000 % 10) > 4) {
|
|
|
|
|
- frequency = model->real_frequency + 10000;
|
|
|
|
|
|
|
+ elements_button_left(canvas, "Config");
|
|
|
|
|
+ canvas_draw_line(canvas, 46, 51, 125, 51);
|
|
|
|
|
+ if(subghz_history_get_text_space_left(model->history, str_buff)) {
|
|
|
|
|
+ canvas_draw_str(canvas, 54, 62, string_get_cstr(str_buff));
|
|
|
} else {
|
|
} else {
|
|
|
- frequency = model->real_frequency;
|
|
|
|
|
|
|
+ if((model->real_frequency / 1000 % 10) > 4) {
|
|
|
|
|
+ frequency = model->real_frequency + 10000;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ frequency = model->real_frequency;
|
|
|
|
|
+ }
|
|
|
|
|
+ snprintf(
|
|
|
|
|
+ buffer,
|
|
|
|
|
+ sizeof(buffer),
|
|
|
|
|
+ "%03ld.%02ld",
|
|
|
|
|
+ frequency / 1000000 % 1000,
|
|
|
|
|
+ frequency / 10000 % 100);
|
|
|
|
|
+ canvas_draw_str(canvas, 44, 62, buffer);
|
|
|
|
|
+ canvas_draw_str(canvas, 79, 62, "AM");
|
|
|
|
|
+ canvas_draw_str(canvas, 96, 62, string_get_cstr(str_buff));
|
|
|
}
|
|
}
|
|
|
- snprintf(
|
|
|
|
|
- buffer,
|
|
|
|
|
- sizeof(buffer),
|
|
|
|
|
- "%03ld.%02ld",
|
|
|
|
|
- frequency / 1000000 % 1000,
|
|
|
|
|
- frequency / 10000 % 100);
|
|
|
|
|
- canvas_draw_str(canvas, 40, 62, buffer);
|
|
|
|
|
- canvas_draw_str(canvas, 75, 62, "AM");
|
|
|
|
|
- subghz_history_get_text_space_left(model->history, str_buff);
|
|
|
|
|
- canvas_draw_str(canvas, 94, 62, string_get_cstr(str_buff));
|
|
|
|
|
- canvas_draw_line(canvas, 38, 51, 125, 51);
|
|
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case ReceiverSceneStart:
|
|
case ReceiverSceneStart:
|
|
|
- canvas_draw_icon(canvas, 0, 0, &I_RFIDDolphinReceive_97x61);
|
|
|
|
|
- canvas_invert_color(canvas);
|
|
|
|
|
- canvas_draw_box(canvas, 80, 2, 20, 20);
|
|
|
|
|
- canvas_invert_color(canvas);
|
|
|
|
|
- canvas_draw_icon(canvas, 75, 8, &I_sub1_10px);
|
|
|
|
|
|
|
+ canvas_draw_icon(canvas, 0, 0, &I_Scanning_123x52);
|
|
|
canvas_set_font(canvas, FontPrimary);
|
|
canvas_set_font(canvas, FontPrimary);
|
|
|
- canvas_draw_str(canvas, 63, 40, "Scanning...");
|
|
|
|
|
|
|
+ canvas_draw_str(canvas, 63, 46, "Scanning...");
|
|
|
canvas_set_color(canvas, ColorBlack);
|
|
canvas_set_color(canvas, ColorBlack);
|
|
|
canvas_set_font(canvas, FontSecondary);
|
|
canvas_set_font(canvas, FontSecondary);
|
|
|
- elements_button_left(canvas, "Conf");
|
|
|
|
|
- canvas_invert_color(canvas);
|
|
|
|
|
- canvas_draw_box(canvas, 38, 52, 10, 10);
|
|
|
|
|
- canvas_invert_color(canvas);
|
|
|
|
|
|
|
+ elements_button_left(canvas, "Config");
|
|
|
if((model->real_frequency / 1000 % 10) > 4) {
|
|
if((model->real_frequency / 1000 % 10) > 4) {
|
|
|
frequency = model->real_frequency + 10000;
|
|
frequency = model->real_frequency + 10000;
|
|
|
} else {
|
|
} else {
|
|
@@ -221,11 +218,11 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) {
|
|
|
"%03ld.%02ld",
|
|
"%03ld.%02ld",
|
|
|
frequency / 1000000 % 1000,
|
|
frequency / 1000000 % 1000,
|
|
|
frequency / 10000 % 100);
|
|
frequency / 10000 % 100);
|
|
|
- canvas_draw_str(canvas, 40, 62, buffer);
|
|
|
|
|
- canvas_draw_str(canvas, 75, 62, "AM");
|
|
|
|
|
|
|
+ canvas_draw_str(canvas, 44, 62, buffer);
|
|
|
|
|
+ canvas_draw_str(canvas, 79, 62, "AM");
|
|
|
subghz_history_get_text_space_left(model->history, str_buff);
|
|
subghz_history_get_text_space_left(model->history, str_buff);
|
|
|
- canvas_draw_str(canvas, 94, 62, string_get_cstr(str_buff));
|
|
|
|
|
- canvas_draw_line(canvas, 48, 51, 125, 51);
|
|
|
|
|
|
|
+ canvas_draw_str(canvas, 96, 62, string_get_cstr(str_buff));
|
|
|
|
|
+ canvas_draw_line(canvas, 46, 51, 125, 51);
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case ReceiverSceneConfig:
|
|
case ReceiverSceneConfig:
|
|
@@ -237,9 +234,12 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) {
|
|
|
model->real_frequency / 1000000 % 1000,
|
|
model->real_frequency / 1000000 % 1000,
|
|
|
model->real_frequency / 1000 % 1000);
|
|
model->real_frequency / 1000 % 1000);
|
|
|
canvas_draw_str(canvas, 0, 8, buffer);
|
|
canvas_draw_str(canvas, 0, 8, buffer);
|
|
|
|
|
+ canvas_draw_str(canvas, 0, 18, "Frequency Hopping: <OFF>");
|
|
|
} else {
|
|
} else {
|
|
|
- canvas_draw_str(canvas, 0, 8, "Frequency: <auto>");
|
|
|
|
|
|
|
+ canvas_draw_str(canvas, 0, 8, "Frequency: < --- >");
|
|
|
|
|
+ canvas_draw_str(canvas, 0, 18, "Frequency Hopping: <ON>");
|
|
|
}
|
|
}
|
|
|
|
|
+ canvas_draw_str(canvas, 0, 28, "Modulation: <AM>");
|
|
|
|
|
|
|
|
elements_button_center(canvas, "Save");
|
|
elements_button_center(canvas, "Save");
|
|
|
break;
|
|
break;
|
|
@@ -269,6 +269,13 @@ void subghz_receiver_draw(Canvas* canvas, SubghzReceiverModel* model) {
|
|
|
string_clear(str_buff);
|
|
string_clear(str_buff);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void subghz_receiver_history_full(void* context) {
|
|
|
|
|
+ furi_assert(context);
|
|
|
|
|
+ SubghzReceiver* subghz_receiver = context;
|
|
|
|
|
+ subghz_receiver->callback(SubghzReceverEventSendHistoryFull, subghz_receiver->context);
|
|
|
|
|
+ subghz_receiver->hopper_state = SubGhzHopperStateOFF;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
furi_assert(context);
|
|
furi_assert(context);
|
|
|
|
|
|
|
@@ -280,13 +287,11 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
return false;
|
|
return false;
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
- if(scene != ReceiverSceneInfo && event->type != InputTypeShort) return false;
|
|
|
|
|
-
|
|
|
|
|
bool can_be_saved = false;
|
|
bool can_be_saved = false;
|
|
|
|
|
|
|
|
switch(scene) {
|
|
switch(scene) {
|
|
|
case ReceiverSceneMain:
|
|
case ReceiverSceneMain:
|
|
|
- if(event->key == InputKeyBack) {
|
|
|
|
|
|
|
+ if(event->key == InputKeyBack && event->type == InputTypeShort) {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
|
model->idx = 0;
|
|
model->idx = 0;
|
|
@@ -296,19 +301,23 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
return false;
|
|
return false;
|
|
|
- } else if(event->key == InputKeyUp) {
|
|
|
|
|
|
|
+ } else if(
|
|
|
|
|
+ event->key == InputKeyUp &&
|
|
|
|
|
+ (event->type == InputTypeShort || event->type == InputTypeRepeat)) {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
|
if(model->idx != 0) model->idx--;
|
|
if(model->idx != 0) model->idx--;
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
- } else if(event->key == InputKeyDown) {
|
|
|
|
|
|
|
+ } else if(
|
|
|
|
|
+ event->key == InputKeyDown &&
|
|
|
|
|
+ (event->type == InputTypeShort || event->type == InputTypeRepeat)) {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
|
if(model->idx != subghz_history_get_item(model->history) - 1) model->idx++;
|
|
if(model->idx != subghz_history_get_item(model->history) - 1) model->idx++;
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
- } else if(event->key == InputKeyLeft) {
|
|
|
|
|
|
|
+ } else if(event->key == InputKeyLeft && event->type == InputTypeShort) {
|
|
|
subghz_receiver->hopper_state = SubGhzHopperStatePause;
|
|
subghz_receiver->hopper_state = SubGhzHopperStatePause;
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
@@ -317,7 +326,8 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context);
|
|
subghz_receiver->callback(SubghzReceverEventConfig, subghz_receiver->context);
|
|
|
- } else if(event->key == InputKeyOk) {
|
|
|
|
|
|
|
+ } else if(event->key == InputKeyOk && event->type == InputTypeShort) {
|
|
|
|
|
+ subghz_receiver->event_key_sequence = event->sequence;
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
|
string_clean(model->text);
|
|
string_clean(model->text);
|
|
@@ -358,18 +368,23 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
} else if(can_be_saved && event->key == InputKeyRight) {
|
|
} else if(can_be_saved && event->key == InputKeyRight) {
|
|
|
subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context);
|
|
subghz_receiver->callback(SubghzReceverEventSave, subghz_receiver->context);
|
|
|
return false;
|
|
return false;
|
|
|
- } else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypePress) {
|
|
|
|
|
|
|
+ } else if(
|
|
|
|
|
+ can_be_saved && event->key == InputKeyOk && event->type == InputTypePress &&
|
|
|
|
|
+ subghz_receiver->event_key_sequence != event->sequence) {
|
|
|
subghz_receiver->hopper_state = SubGhzHopperStatePause;
|
|
subghz_receiver->hopper_state = SubGhzHopperStatePause;
|
|
|
subghz_rx_end(subghz_receiver->worker);
|
|
subghz_rx_end(subghz_receiver->worker);
|
|
|
subghz_receiver->callback(SubghzReceverEventSendStart, subghz_receiver->context);
|
|
subghz_receiver->callback(SubghzReceverEventSendStart, subghz_receiver->context);
|
|
|
return true;
|
|
return true;
|
|
|
- } else if(can_be_saved && event->key == InputKeyOk && event->type == InputTypeRelease) {
|
|
|
|
|
|
|
+ } else if(
|
|
|
|
|
+ can_be_saved && event->key == InputKeyOk && event->type == InputTypeRelease &&
|
|
|
|
|
+ subghz_receiver->event_key_sequence != event->sequence) {
|
|
|
subghz_receiver->callback(SubghzReceverEventSendStop, subghz_receiver->context);
|
|
subghz_receiver->callback(SubghzReceverEventSendStop, subghz_receiver->context);
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case ReceiverSceneConfig:
|
|
case ReceiverSceneConfig:
|
|
|
|
|
+ if(event->type != InputTypeShort) return false;
|
|
|
if(event->key == InputKeyBack) {
|
|
if(event->key == InputKeyBack) {
|
|
|
with_view_model(
|
|
with_view_model(
|
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
@@ -396,7 +411,6 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
osTimerStart(subghz_receiver->timer, 1024 / 10);
|
|
osTimerStart(subghz_receiver->timer, 1024 / 10);
|
|
|
subghz_receiver->hopper_state = SubGhzHopperStateRunnig;
|
|
subghz_receiver->hopper_state = SubGhzHopperStateRunnig;
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
if(subghz_history_get_item(model->history) == 0) {
|
|
if(subghz_history_get_item(model->history) == 0) {
|
|
|
model->scene = ReceiverSceneStart;
|
|
model->scene = ReceiverSceneStart;
|
|
|
} else {
|
|
} else {
|
|
@@ -426,6 +440,7 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
break;
|
|
break;
|
|
|
|
|
|
|
|
case ReceiverSceneStart:
|
|
case ReceiverSceneStart:
|
|
|
|
|
+ if(event->type != InputTypeShort) return false;
|
|
|
if(event->key == InputKeyBack) {
|
|
if(event->key == InputKeyBack) {
|
|
|
return false;
|
|
return false;
|
|
|
} else if(event->key == InputKeyLeft) {
|
|
} else if(event->key == InputKeyLeft) {
|
|
@@ -445,6 +460,16 @@ bool subghz_receiver_input(InputEvent* event, void* context) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
subghz_receiver_update_offset(subghz_receiver);
|
|
subghz_receiver_update_offset(subghz_receiver);
|
|
|
|
|
+ if(scene != ReceiverSceneInfo) {
|
|
|
|
|
+ with_view_model(
|
|
|
|
|
+ subghz_receiver->view, (SubghzReceiverModel * model) {
|
|
|
|
|
+ if(subghz_history_get_text_space_left(model->history, NULL)) {
|
|
|
|
|
+ subghz_receiver_history_full(subghz_receiver);
|
|
|
|
|
+ }
|
|
|
|
|
+ return false;
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
return true;
|
|
return true;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -476,6 +501,9 @@ void subghz_receiver_protocol_callback(SubGhzProtocolCommon* parser, void* conte
|
|
|
|
|
|
|
|
model->history_item = subghz_history_get_item(model->history);
|
|
model->history_item = subghz_history_get_item(model->history);
|
|
|
model->scene = ReceiverSceneMain;
|
|
model->scene = ReceiverSceneMain;
|
|
|
|
|
+ if(subghz_history_get_text_space_left(model->history, NULL)) {
|
|
|
|
|
+ subghz_receiver_history_full(subghz_receiver);
|
|
|
|
|
+ }
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|
|
|
subghz_protocol_reset(subghz_receiver->protocol);
|
|
subghz_protocol_reset(subghz_receiver->protocol);
|
|
@@ -528,10 +556,11 @@ static void subghz_receiver_timer_callback(void* context) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Restart radio
|
|
// Restart radio
|
|
|
- subghz_rx_end(subghz_receiver->worker);
|
|
|
|
|
|
|
+ furi_hal_subghz_idle();
|
|
|
subghz_protocol_reset(subghz_receiver->protocol);
|
|
subghz_protocol_reset(subghz_receiver->protocol);
|
|
|
- model->real_frequency =
|
|
|
|
|
- subghz_rx(subghz_receiver->worker, subghz_frequencies_hopper[model->frequency]);
|
|
|
|
|
|
|
+ model->real_frequency = furi_hal_subghz_set_frequency_and_path(
|
|
|
|
|
+ subghz_frequencies_hopper[model->frequency]);
|
|
|
|
|
+ furi_hal_subghz_rx();
|
|
|
|
|
|
|
|
return true;
|
|
return true;
|
|
|
});
|
|
});
|