Merge branch 'ofw-dev' into dev
@ -1,6 +1,7 @@
|
|||||||
#include "../infrared_i.h"
|
#include "../infrared_i.h"
|
||||||
|
|
||||||
#include "common/infrared_scene_universal_common.h"
|
#include "common/infrared_scene_universal_common.h"
|
||||||
|
#include <furi_hal_rtc.h>
|
||||||
|
|
||||||
void infrared_scene_universal_ac_on_enter(void* context) {
|
void infrared_scene_universal_ac_on_enter(void* context) {
|
||||||
infrared_scene_universal_common_on_enter(context);
|
infrared_scene_universal_common_on_enter(context);
|
||||||
@ -18,24 +19,26 @@ void infrared_scene_universal_ac_on_enter(void* context) {
|
|||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
3,
|
6,
|
||||||
22,
|
15,
|
||||||
&I_Off_25x27,
|
&I_power_19x20,
|
||||||
&I_Off_hvr_25x27,
|
&I_power_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 4, 37, &I_power_text_24x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Off");
|
infrared_brute_force_add_record(brute_force, i++, "Off");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
36,
|
39,
|
||||||
22,
|
15,
|
||||||
&I_Dehumidify_25x27,
|
&I_dry_19x20,
|
||||||
&I_Dehumidify_hvr_25x27,
|
&I_dry_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 41, 37, &I_dry_text_15x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Dh");
|
infrared_brute_force_add_record(brute_force, i++, "Dh");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
@ -43,9 +46,9 @@ void infrared_scene_universal_ac_on_enter(void* context) {
|
|||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
3,
|
3,
|
||||||
59,
|
49,
|
||||||
&I_CoolHi_25x27,
|
&I_max_24x23,
|
||||||
&I_CoolHi_hvr_25x27,
|
&I_max_hover_24x23,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Cool_hi");
|
infrared_brute_force_add_record(brute_force, i++, "Cool_hi");
|
||||||
@ -54,39 +57,71 @@ void infrared_scene_universal_ac_on_enter(void* context) {
|
|||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
1,
|
1,
|
||||||
36,
|
37,
|
||||||
59,
|
49,
|
||||||
&I_HeatHi_25x27,
|
&I_max_24x23,
|
||||||
&I_HeatHi_hvr_25x27,
|
&I_max_hover_24x23,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Heat_hi");
|
infrared_brute_force_add_record(brute_force, i++, "Heat_hi");
|
||||||
button_panel_add_item(
|
if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) {
|
||||||
button_panel,
|
button_panel_add_item(
|
||||||
i,
|
button_panel,
|
||||||
0,
|
i,
|
||||||
2,
|
0,
|
||||||
3,
|
2,
|
||||||
91,
|
3,
|
||||||
&I_CoolLo_25x27,
|
100,
|
||||||
&I_CoolLo_hvr_25x27,
|
&I_celsius_24x23,
|
||||||
infrared_scene_universal_common_item_callback,
|
&I_celsius_hover_24x23,
|
||||||
context);
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
} else {
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
0,
|
||||||
|
2,
|
||||||
|
3,
|
||||||
|
100,
|
||||||
|
&I_fahren_24x23,
|
||||||
|
&I_fahren_hover_24x23,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
}
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Cool_lo");
|
infrared_brute_force_add_record(brute_force, i++, "Cool_lo");
|
||||||
button_panel_add_item(
|
|
||||||
button_panel,
|
if(furi_hal_rtc_get_locale_units() == FuriHalRtcLocaleUnitsMetric) {
|
||||||
i,
|
button_panel_add_item(
|
||||||
1,
|
button_panel,
|
||||||
2,
|
i,
|
||||||
36,
|
1,
|
||||||
91,
|
2,
|
||||||
&I_HeatLo_25x27,
|
37,
|
||||||
&I_HeatLo_hvr_25x27,
|
100,
|
||||||
infrared_scene_universal_common_item_callback,
|
&I_celsius_24x23,
|
||||||
context);
|
&I_celsius_hover_24x23,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
} else {
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
1,
|
||||||
|
2,
|
||||||
|
37,
|
||||||
|
100,
|
||||||
|
&I_fahren_24x23,
|
||||||
|
&I_fahren_hover_24x23,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
}
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Heat_lo");
|
infrared_brute_force_add_record(brute_force, i++, "Heat_lo");
|
||||||
|
|
||||||
button_panel_add_label(button_panel, 6, 10, FontPrimary, "AC remote");
|
button_panel_add_icon(button_panel, 0, 60, &I_cool_30x51);
|
||||||
|
button_panel_add_icon(button_panel, 34, 60, &I_heat_30x51);
|
||||||
|
|
||||||
|
button_panel_add_label(button_panel, 4, 10, FontPrimary, "AC remote");
|
||||||
|
|
||||||
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
||||||
|
@ -18,82 +18,88 @@ void infrared_scene_universal_audio_on_enter(void* context) {
|
|||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
3,
|
6,
|
||||||
11,
|
13,
|
||||||
&I_Power_25x27,
|
&I_power_19x20,
|
||||||
&I_Power_hvr_25x27,
|
&I_power_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 4, 35, &I_power_text_24x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Power");
|
infrared_brute_force_add_record(brute_force, i++, "Power");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
36,
|
39,
|
||||||
11,
|
13,
|
||||||
&I_Mute_25x27,
|
&I_mute_19x20,
|
||||||
&I_Mute_hvr_25x27,
|
&I_mute_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 39, 35, &I_mute_text_19x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
3,
|
6,
|
||||||
41,
|
42,
|
||||||
&I_Play_25x27,
|
&I_play_19x20,
|
||||||
&I_Play_hvr_25x27,
|
&I_play_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 6, 64, &I_play_text_19x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Play");
|
infrared_brute_force_add_record(brute_force, i++, "Play");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
0,
|
||||||
1,
|
2,
|
||||||
36,
|
6,
|
||||||
41,
|
71,
|
||||||
&I_Pause_25x27,
|
&I_pause_19x20,
|
||||||
&I_Pause_hvr_25x27,
|
&I_pause_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 4, 93, &I_pause_text_23x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
2,
|
|
||||||
3,
|
3,
|
||||||
71,
|
6,
|
||||||
&I_TrackPrev_25x27,
|
101,
|
||||||
&I_TrackPrev_hvr_25x27,
|
&I_prev_19x20,
|
||||||
|
&I_prev_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 6, 123, &I_prev_text_19x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Prev");
|
infrared_brute_force_add_record(brute_force, i++, "Prev");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
2,
|
3,
|
||||||
36,
|
39,
|
||||||
71,
|
101,
|
||||||
&I_TrackNext_25x27,
|
&I_next_19x20,
|
||||||
&I_TrackNext_hvr_25x27,
|
&I_next_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 39, 123, &I_next_text_19x6);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Next");
|
infrared_brute_force_add_record(brute_force, i++, "Next");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
0,
|
1,
|
||||||
3,
|
2,
|
||||||
3,
|
37,
|
||||||
101,
|
77,
|
||||||
&I_Vol_down_25x27,
|
&I_voldown_24x21,
|
||||||
&I_Vol_down_hvr_25x27,
|
&I_voldown_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
||||||
@ -101,16 +107,17 @@ void infrared_scene_universal_audio_on_enter(void* context) {
|
|||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
3,
|
1,
|
||||||
36,
|
37,
|
||||||
101,
|
43,
|
||||||
&I_Vol_up_25x27,
|
&I_volup_24x21,
|
||||||
&I_Vol_up_hvr_25x27,
|
&I_volup_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
||||||
|
|
||||||
button_panel_add_label(button_panel, 1, 8, FontPrimary, "Mus. remote");
|
button_panel_add_label(button_panel, 1, 10, FontPrimary, "Mus. remote");
|
||||||
|
button_panel_add_icon(button_panel, 34, 56, &I_vol_ac_text_30x30);
|
||||||
|
|
||||||
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
||||||
|
@ -18,46 +18,49 @@ void infrared_scene_universal_projector_on_enter(void* context) {
|
|||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
3,
|
6,
|
||||||
19,
|
23,
|
||||||
&I_Power_25x27,
|
&I_power_19x20,
|
||||||
&I_Power_hvr_25x27,
|
&I_power_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 4, 45, &I_power_text_24x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Power");
|
infrared_brute_force_add_record(brute_force, i++, "Power");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
36,
|
39,
|
||||||
19,
|
23,
|
||||||
&I_Mute_25x27,
|
&I_mute_19x20,
|
||||||
&I_Mute_hvr_25x27,
|
&I_mute_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 39, 45, &I_mute_text_19x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
3,
|
20,
|
||||||
64,
|
59,
|
||||||
&I_Vol_up_25x27,
|
&I_volup_24x21,
|
||||||
&I_Vol_up_hvr_25x27,
|
&I_volup_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
||||||
|
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
0,
|
||||||
1,
|
2,
|
||||||
36,
|
20,
|
||||||
64,
|
93,
|
||||||
&I_Vol_down_25x27,
|
&I_voldown_24x21,
|
||||||
&I_Vol_down_hvr_25x27,
|
&I_voldown_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
||||||
@ -86,8 +89,8 @@ void infrared_scene_universal_projector_on_enter(void* context) {
|
|||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
infrared_brute_force_add_record(brute_force, i++, "Pause");
|
||||||
|
|
||||||
button_panel_add_label(button_panel, 10, 11, FontPrimary, "Projector");
|
button_panel_add_label(button_panel, 3, 11, FontPrimary, "Proj. remote");
|
||||||
button_panel_add_label(button_panel, 17, 60, FontSecondary, "Volume");
|
button_panel_add_icon(button_panel, 17, 72, &I_vol_ac_text_30x30);
|
||||||
|
|
||||||
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
||||||
|
@ -18,77 +18,82 @@ void infrared_scene_universal_tv_on_enter(void* context) {
|
|||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
3,
|
6,
|
||||||
19,
|
16,
|
||||||
&I_Power_25x27,
|
&I_power_19x20,
|
||||||
&I_Power_hvr_25x27,
|
&I_power_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 4, 38, &I_power_text_24x5);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Power");
|
infrared_brute_force_add_record(brute_force, i++, "Power");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
1,
|
||||||
0,
|
0,
|
||||||
36,
|
39,
|
||||||
19,
|
16,
|
||||||
&I_Mute_25x27,
|
&I_mute_19x20,
|
||||||
&I_Mute_hvr_25x27,
|
&I_mute_hover_19x20,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
|
button_panel_add_icon(button_panel, 39, 38, &I_mute_text_19x5);
|
||||||
|
|
||||||
|
button_panel_add_icon(button_panel, 0, 66, &I_ch_text_31x34);
|
||||||
|
button_panel_add_icon(button_panel, 35, 66, &I_vol_tv_text_29x34);
|
||||||
|
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
infrared_brute_force_add_record(brute_force, i++, "Mute");
|
||||||
|
button_panel_add_item(
|
||||||
|
button_panel,
|
||||||
|
i,
|
||||||
|
1,
|
||||||
|
1,
|
||||||
|
38,
|
||||||
|
53,
|
||||||
|
&I_volup_24x21,
|
||||||
|
&I_volup_hover_24x21,
|
||||||
|
infrared_scene_universal_common_item_callback,
|
||||||
|
context);
|
||||||
|
|
||||||
|
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
0,
|
0,
|
||||||
1,
|
1,
|
||||||
3,
|
3,
|
||||||
66,
|
53,
|
||||||
&I_Vol_up_25x27,
|
&I_ch_up_24x21,
|
||||||
&I_Vol_up_hvr_25x27,
|
&I_ch_up_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
|
||||||
context);
|
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Vol_up");
|
|
||||||
button_panel_add_item(
|
|
||||||
button_panel,
|
|
||||||
i,
|
|
||||||
1,
|
|
||||||
1,
|
|
||||||
36,
|
|
||||||
66,
|
|
||||||
&I_Up_25x27,
|
|
||||||
&I_Up_hvr_25x27,
|
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Ch_next");
|
infrared_brute_force_add_record(brute_force, i++, "Ch_next");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
0,
|
1,
|
||||||
2,
|
2,
|
||||||
3,
|
38,
|
||||||
98,
|
91,
|
||||||
&I_Vol_down_25x27,
|
&I_voldown_24x21,
|
||||||
&I_Vol_down_hvr_25x27,
|
&I_voldown_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
infrared_brute_force_add_record(brute_force, i++, "Vol_dn");
|
||||||
button_panel_add_item(
|
button_panel_add_item(
|
||||||
button_panel,
|
button_panel,
|
||||||
i,
|
i,
|
||||||
1,
|
0,
|
||||||
2,
|
2,
|
||||||
36,
|
3,
|
||||||
98,
|
91,
|
||||||
&I_Down_25x27,
|
&I_ch_down_24x21,
|
||||||
&I_Down_hvr_25x27,
|
&I_ch_down_hover_24x21,
|
||||||
infrared_scene_universal_common_item_callback,
|
infrared_scene_universal_common_item_callback,
|
||||||
context);
|
context);
|
||||||
infrared_brute_force_add_record(brute_force, i++, "Ch_prev");
|
infrared_brute_force_add_record(brute_force, i++, "Ch_prev");
|
||||||
|
|
||||||
button_panel_add_label(button_panel, 6, 11, FontPrimary, "TV remote");
|
button_panel_add_label(button_panel, 5, 10, FontPrimary, "TV remote");
|
||||||
button_panel_add_label(button_panel, 9, 64, FontSecondary, "Vol");
|
|
||||||
button_panel_add_label(button_panel, 43, 64, FontSecondary, "Ch");
|
|
||||||
|
|
||||||
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
view_set_orientation(view_stack_get_view(infrared->view_stack), ViewOrientationVertical);
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewStack);
|
||||||
|
@ -29,6 +29,9 @@ typedef struct {
|
|||||||
const Icon* name_selected;
|
const Icon* name_selected;
|
||||||
} IconElement;
|
} IconElement;
|
||||||
|
|
||||||
|
LIST_DEF(IconList, IconElement, M_POD_OPLIST)
|
||||||
|
#define M_OPL_IconList_t() LIST_OPLIST(IconList)
|
||||||
|
|
||||||
typedef struct ButtonItem {
|
typedef struct ButtonItem {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
ButtonItemCallback callback;
|
ButtonItemCallback callback;
|
||||||
@ -47,6 +50,7 @@ struct ButtonPanel {
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
ButtonMatrix_t button_matrix;
|
ButtonMatrix_t button_matrix;
|
||||||
|
IconList_t icons;
|
||||||
LabelList_t labels;
|
LabelList_t labels;
|
||||||
uint16_t reserve_x;
|
uint16_t reserve_x;
|
||||||
uint16_t reserve_y;
|
uint16_t reserve_y;
|
||||||
@ -157,6 +161,7 @@ void button_panel_reset(ButtonPanel* button_panel) {
|
|||||||
model->selected_item_x = 0;
|
model->selected_item_x = 0;
|
||||||
model->selected_item_y = 0;
|
model->selected_item_y = 0;
|
||||||
LabelList_reset(model->labels);
|
LabelList_reset(model->labels);
|
||||||
|
IconList_reset(model->icons);
|
||||||
ButtonMatrix_reset(model->button_matrix);
|
ButtonMatrix_reset(model->button_matrix);
|
||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
@ -219,9 +224,17 @@ static void button_panel_view_draw_callback(Canvas* canvas, void* _model) {
|
|||||||
canvas_clear(canvas);
|
canvas_clear(canvas);
|
||||||
canvas_set_color(canvas, ColorBlack);
|
canvas_set_color(canvas, ColorBlack);
|
||||||
|
|
||||||
|
for
|
||||||
|
M_EACH(icon, model->icons, IconList_t) {
|
||||||
|
canvas_draw_icon(canvas, icon->x, icon->y, icon->name);
|
||||||
|
}
|
||||||
|
|
||||||
for(size_t x = 0; x < model->reserve_x; ++x) {
|
for(size_t x = 0; x < model->reserve_x; ++x) {
|
||||||
for(size_t y = 0; y < model->reserve_y; ++y) {
|
for(size_t y = 0; y < model->reserve_y; ++y) {
|
||||||
ButtonItem* button_item = *button_panel_get_item(model, x, y);
|
ButtonItem* button_item = *button_panel_get_item(model, x, y);
|
||||||
|
if(!button_item) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
const Icon* icon_name = button_item->icon.name;
|
const Icon* icon_name = button_item->icon.name;
|
||||||
if((model->selected_item_x == x) && (model->selected_item_y == y)) {
|
if((model->selected_item_x == x) && (model->selected_item_y == y)) {
|
||||||
icon_name = button_item->icon.name_selected;
|
icon_name = button_item->icon.name_selected;
|
||||||
@ -417,3 +430,24 @@ void button_panel_add_label(
|
|||||||
},
|
},
|
||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Draw an icon but don't make it a button.
|
||||||
|
void button_panel_add_icon(
|
||||||
|
ButtonPanel* button_panel,
|
||||||
|
uint16_t x,
|
||||||
|
uint16_t y,
|
||||||
|
const Icon* icon_name) {
|
||||||
|
furi_assert(button_panel);
|
||||||
|
|
||||||
|
with_view_model( //-V773
|
||||||
|
button_panel->view,
|
||||||
|
ButtonPanelModel * model,
|
||||||
|
{
|
||||||
|
IconElement* icon = IconList_push_raw(model->icons);
|
||||||
|
icon->x = x;
|
||||||
|
icon->y = y;
|
||||||
|
icon->name = icon_name;
|
||||||
|
icon->name_selected = icon_name;
|
||||||
|
},
|
||||||
|
true);
|
||||||
|
}
|
@ -106,6 +106,19 @@ void button_panel_add_label(
|
|||||||
Font font,
|
Font font,
|
||||||
const char* label_str);
|
const char* label_str);
|
||||||
|
|
||||||
|
/** Add a non-button icon to button_panel module.
|
||||||
|
*
|
||||||
|
* @param button_panel ButtonPanel instance
|
||||||
|
* @param x x-coordinate to place icon
|
||||||
|
* @param y y-coordinate to place icon
|
||||||
|
* @param icon_name name of the icon to draw
|
||||||
|
*/
|
||||||
|
void button_panel_add_icon(
|
||||||
|
ButtonPanel* button_panel,
|
||||||
|
uint16_t x,
|
||||||
|
uint16_t y,
|
||||||
|
const Icon* icon_name);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 9.3 KiB |
Before Width: | Height: | Size: 8.3 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB |
BIN
assets/icons/Infrared/celsius_24x23.png
Normal file
After Width: | Height: | Size: 257 B |
BIN
assets/icons/Infrared/celsius_hover_24x23.png
Normal file
After Width: | Height: | Size: 204 B |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.9 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.9 KiB |
BIN
assets/icons/Infrared/ch_up_24x21.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/ch_up_hover_24x21.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
assets/icons/Infrared/dry_19x20.png
Normal file
After Width: | Height: | Size: 996 B |
BIN
assets/icons/Infrared/dry_hover_19x20.png
Normal file
After Width: | Height: | Size: 978 B |
BIN
assets/icons/Infrared/dry_text_15x5.png
Normal file
After Width: | Height: | Size: 968 B |
BIN
assets/icons/Infrared/fahren_24x23.png
Normal file
After Width: | Height: | Size: 258 B |
BIN
assets/icons/Infrared/fahren_hover_24x23.png
Normal file
After Width: | Height: | Size: 205 B |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.7 KiB |
BIN
assets/icons/Infrared/hourglass0_24x24.png
Normal file
After Width: | Height: | Size: 231 B |
BIN
assets/icons/Infrared/hourglass1_24x24.png
Normal file
After Width: | Height: | Size: 246 B |
BIN
assets/icons/Infrared/hourglass2_24x24.png
Normal file
After Width: | Height: | Size: 237 B |
BIN
assets/icons/Infrared/hourglass3_24x24.png
Normal file
After Width: | Height: | Size: 223 B |
BIN
assets/icons/Infrared/hourglass4_24x24.png
Normal file
After Width: | Height: | Size: 239 B |
BIN
assets/icons/Infrared/hourglass5_24x24.png
Normal file
After Width: | Height: | Size: 218 B |
BIN
assets/icons/Infrared/hourglass6_24x24.png
Normal file
After Width: | Height: | Size: 238 B |
BIN
assets/icons/Infrared/max_24x23.png
Normal file
After Width: | Height: | Size: 224 B |
BIN
assets/icons/Infrared/max_hover_24x23.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
assets/icons/Infrared/mute_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/mute_hover_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/mute_text_19x5.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/next_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/next_hover_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/next_text_19x6.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/pause_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/pause_hover_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/pause_text_23x5.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/play_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/play_text_19x5.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/power_19x20.png
Normal file
After Width: | Height: | Size: 1006 B |
BIN
assets/icons/Infrared/power_hover_19x20.png
Normal file
After Width: | Height: | Size: 996 B |
BIN
assets/icons/Infrared/power_text_24x5.png
Normal file
After Width: | Height: | Size: 981 B |
BIN
assets/icons/Infrared/prev_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/prev_hover_19x20.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/prev_text_19x5.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/vol_ac_text_30x30.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/vol_tv_text_29x34.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
BIN
assets/icons/Infrared/voldown_24x21.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/voldown_hover_24x21.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/volup_24x21.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
assets/icons/Infrared/volup_hover_24x21.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,35.0,,
|
Version,+,35.1,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.h,,
|
Header,+,applications/services/cli/cli_vcp.h,,
|
||||||
@ -556,6 +556,7 @@ Function,+,button_menu_get_view,View*,ButtonMenu*
|
|||||||
Function,+,button_menu_reset,void,ButtonMenu*
|
Function,+,button_menu_reset,void,ButtonMenu*
|
||||||
Function,+,button_menu_set_header,void,"ButtonMenu*, const char*"
|
Function,+,button_menu_set_header,void,"ButtonMenu*, const char*"
|
||||||
Function,+,button_menu_set_selected_item,void,"ButtonMenu*, uint32_t"
|
Function,+,button_menu_set_selected_item,void,"ButtonMenu*, uint32_t"
|
||||||
|
Function,+,button_panel_add_icon,void,"ButtonPanel*, uint16_t, uint16_t, const Icon*"
|
||||||
Function,+,button_panel_add_item,void,"ButtonPanel*, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t, const Icon*, const Icon*, ButtonItemCallback, void*"
|
Function,+,button_panel_add_item,void,"ButtonPanel*, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t, const Icon*, const Icon*, ButtonItemCallback, void*"
|
||||||
Function,+,button_panel_add_label,void,"ButtonPanel*, uint16_t, uint16_t, Font, const char*"
|
Function,+,button_panel_add_label,void,"ButtonPanel*, uint16_t, uint16_t, Font, const char*"
|
||||||
Function,+,button_panel_alloc,ButtonPanel*,
|
Function,+,button_panel_alloc,ButtonPanel*,
|
||||||
|
|
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,35.0,,
|
Version,+,35.1,,
|
||||||
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
Header,+,applications/drivers/subghz/cc1101_ext/cc1101_ext_interconnect.h,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
@ -629,6 +629,7 @@ Function,+,button_menu_get_view,View*,ButtonMenu*
|
|||||||
Function,+,button_menu_reset,void,ButtonMenu*
|
Function,+,button_menu_reset,void,ButtonMenu*
|
||||||
Function,+,button_menu_set_header,void,"ButtonMenu*, const char*"
|
Function,+,button_menu_set_header,void,"ButtonMenu*, const char*"
|
||||||
Function,+,button_menu_set_selected_item,void,"ButtonMenu*, uint32_t"
|
Function,+,button_menu_set_selected_item,void,"ButtonMenu*, uint32_t"
|
||||||
|
Function,+,button_panel_add_icon,void,"ButtonPanel*, uint16_t, uint16_t, const Icon*"
|
||||||
Function,+,button_panel_add_item,void,"ButtonPanel*, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t, const Icon*, const Icon*, ButtonItemCallback, void*"
|
Function,+,button_panel_add_item,void,"ButtonPanel*, uint32_t, uint16_t, uint16_t, uint16_t, uint16_t, const Icon*, const Icon*, ButtonItemCallback, void*"
|
||||||
Function,+,button_panel_add_label,void,"ButtonPanel*, uint16_t, uint16_t, Font, const char*"
|
Function,+,button_panel_add_label,void,"ButtonPanel*, uint16_t, uint16_t, Font, const char*"
|
||||||
Function,+,button_panel_alloc,ButtonPanel*,
|
Function,+,button_panel_alloc,ButtonPanel*,
|
||||||
|
|
@ -744,7 +744,6 @@ static bool
|
|||||||
|
|
||||||
bin_raw_debug("\r\n\r\n");
|
bin_raw_debug("\r\n\r\n");
|
||||||
#endif
|
#endif
|
||||||
//TODO FL-3557: can be optimized
|
|
||||||
BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
|
BinRAW_Markup markup_temp[BIN_RAW_MAX_MARKUP_COUNT];
|
||||||
memcpy(
|
memcpy(
|
||||||
markup_temp,
|
markup_temp,
|
||||||
@ -770,7 +769,6 @@ static bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//TODO FL-3557: can be optimized
|
|
||||||
if(bin_raw_type == BinRAWTypeGap) {
|
if(bin_raw_type == BinRAWTypeGap) {
|
||||||
if(data_temp != 0) { //there are sequences with the same number of bits
|
if(data_temp != 0) { //there are sequences with the same number of bits
|
||||||
|
|
||||||
|
@ -15,10 +15,9 @@ class App:
|
|||||||
# Application specific initialization
|
# Application specific initialization
|
||||||
self.init()
|
self.init()
|
||||||
|
|
||||||
def __call__(self, args=None, skip_logger_init=False):
|
def __call__(self, args=None):
|
||||||
self.args, self.other_args = self.parser.parse_known_args(args=args)
|
self.args, self.other_args = self.parser.parse_known_args(args=args)
|
||||||
# configure log output
|
# configure log output
|
||||||
# if skip_logger_init:
|
|
||||||
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
|
self.log_level = logging.DEBUG if self.args.debug else logging.INFO
|
||||||
self.logger.setLevel(self.log_level)
|
self.logger.setLevel(self.log_level)
|
||||||
if not self.logger.hasHandlers():
|
if not self.logger.hasHandlers():
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import socket
|
import socket
|
||||||
import subprocess
|
import subprocess
|
||||||
import time
|
import time
|
||||||
@ -10,11 +11,12 @@ from dataclasses import dataclass, field
|
|||||||
|
|
||||||
from flipper.app import App
|
from flipper.app import App
|
||||||
|
|
||||||
|
# When adding an interface, also add it to SWD_TRANSPORT in fbt/ufbt options
|
||||||
# When adding an interface, also add it to SWD_TRANSPORT in fbt options
|
|
||||||
|
|
||||||
|
|
||||||
class Programmer(ABC):
|
class Programmer(ABC):
|
||||||
|
root_logger = logging.getLogger("Programmer")
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def flash(self, file_path: str, do_verify: bool) -> bool:
|
def flash(self, file_path: str, do_verify: bool) -> bool:
|
||||||
pass
|
pass
|
||||||
@ -31,6 +33,26 @@ class Programmer(ABC):
|
|||||||
def set_serial(self, serial: str):
|
def set_serial(self, serial: str):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def _spawn_and_await(cls, process_params, show_progress: bool = False):
|
||||||
|
cls.root_logger.debug(f"Launching: {' '.join(process_params)}")
|
||||||
|
|
||||||
|
process = subprocess.Popen(
|
||||||
|
process_params,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
)
|
||||||
|
|
||||||
|
if show_progress:
|
||||||
|
while process.poll() is None:
|
||||||
|
time.sleep(0.25)
|
||||||
|
print(".", end="", flush=True)
|
||||||
|
print()
|
||||||
|
else:
|
||||||
|
process.wait()
|
||||||
|
|
||||||
|
return process
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class OpenOCDInterface:
|
class OpenOCDInterface:
|
||||||
@ -43,7 +65,7 @@ class OpenOCDInterface:
|
|||||||
class OpenOCDProgrammer(Programmer):
|
class OpenOCDProgrammer(Programmer):
|
||||||
def __init__(self, interface: OpenOCDInterface):
|
def __init__(self, interface: OpenOCDInterface):
|
||||||
self.interface = interface
|
self.interface = interface
|
||||||
self.logger = logging.getLogger("OpenOCD")
|
self.logger = self.root_logger.getChild("OpenOCD")
|
||||||
self.serial: typing.Optional[str] = None
|
self.serial: typing.Optional[str] = None
|
||||||
|
|
||||||
def _add_file(self, params: list[str], file: str):
|
def _add_file(self, params: list[str], file: str):
|
||||||
@ -87,17 +109,7 @@ class OpenOCDProgrammer(Programmer):
|
|||||||
|
|
||||||
self.logger.debug(f"Launching: {openocd_launch_params_string}")
|
self.logger.debug(f"Launching: {openocd_launch_params_string}")
|
||||||
|
|
||||||
process = subprocess.Popen(
|
process = self._spawn_and_await(openocd_launch_params, True)
|
||||||
openocd_launch_params,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
)
|
|
||||||
|
|
||||||
while process.poll() is None:
|
|
||||||
time.sleep(0.25)
|
|
||||||
print(".", end="", flush=True)
|
|
||||||
print()
|
|
||||||
|
|
||||||
success = process.returncode == 0
|
success = process.returncode == 0
|
||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
@ -108,35 +120,41 @@ class OpenOCDProgrammer(Programmer):
|
|||||||
return success
|
return success
|
||||||
|
|
||||||
def probe(self) -> bool:
|
def probe(self) -> bool:
|
||||||
i = self.interface
|
|
||||||
|
|
||||||
openocd_launch_params = ["openocd"]
|
openocd_launch_params = ["openocd"]
|
||||||
self._add_file(openocd_launch_params, i.config_file)
|
self._add_file(openocd_launch_params, self.interface.config_file)
|
||||||
if self.serial:
|
if self.serial:
|
||||||
self._add_serial(openocd_launch_params, self.serial)
|
self._add_serial(openocd_launch_params, self.serial)
|
||||||
if i.additional_args:
|
for additional_arg in self.interface.additional_args:
|
||||||
for a in i.additional_args:
|
self._add_command(openocd_launch_params, additional_arg)
|
||||||
self._add_command(openocd_launch_params, a)
|
|
||||||
self._add_file(openocd_launch_params, "target/stm32wbx.cfg")
|
self._add_file(openocd_launch_params, "target/stm32wbx.cfg")
|
||||||
self._add_command(openocd_launch_params, "init")
|
self._add_command(openocd_launch_params, "init")
|
||||||
self._add_command(openocd_launch_params, "exit")
|
self._add_command(openocd_launch_params, "exit")
|
||||||
|
|
||||||
self.logger.debug(f"Launching: {' '.join(openocd_launch_params)}")
|
process = self._spawn_and_await(openocd_launch_params)
|
||||||
|
success = process.returncode == 0
|
||||||
|
|
||||||
process = subprocess.Popen(
|
output = process.stdout.read().decode("utf-8").strip() if process.stdout else ""
|
||||||
openocd_launch_params,
|
self.logger.debug(output)
|
||||||
stderr=subprocess.STDOUT,
|
# Find target voltage using regex
|
||||||
stdout=subprocess.PIPE,
|
if match := re.search(r"Target voltage: (\d+\.\d+)", output):
|
||||||
)
|
voltage = float(match.group(1))
|
||||||
|
if not success:
|
||||||
|
if voltage < 1:
|
||||||
|
self.logger.warning(
|
||||||
|
f"Found {self.get_name()}, but device is not connected"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
self.logger.warning(
|
||||||
|
f"Device is connected, but {self.get_name()} failed to attach. Is System>Debug enabled?"
|
||||||
|
)
|
||||||
|
|
||||||
# Wait for OpenOCD to end and get the return code
|
if "cannot read IDR" in output:
|
||||||
process.wait()
|
self.logger.warning(
|
||||||
found = process.returncode == 0
|
f"Found {self.get_name()}, but failed to attach. Is device connected and is System>Debug enabled?"
|
||||||
|
)
|
||||||
|
success = False
|
||||||
|
|
||||||
if process.stdout:
|
return success
|
||||||
self.logger.debug(process.stdout.read().decode("utf-8").strip())
|
|
||||||
|
|
||||||
return found
|
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
return self.interface.name
|
return self.interface.name
|
||||||
@ -218,7 +236,7 @@ class BlackmagicProgrammer(Programmer):
|
|||||||
):
|
):
|
||||||
self.port_resolver = port_resolver
|
self.port_resolver = port_resolver
|
||||||
self.name = name
|
self.name = name
|
||||||
self.logger = logging.getLogger("BlackmagicUSB")
|
self.logger = self.root_logger.getChild(f"Blackmagic{name}")
|
||||||
self.port: typing.Optional[str] = None
|
self.port: typing.Optional[str] = None
|
||||||
|
|
||||||
def _add_command(self, params: list[str], command: str):
|
def _add_command(self, params: list[str], command: str):
|
||||||
@ -240,6 +258,14 @@ class BlackmagicProgrammer(Programmer):
|
|||||||
else:
|
else:
|
||||||
self.port = serial
|
self.port = serial
|
||||||
|
|
||||||
|
def _get_gdb_core_params(self) -> list[str]:
|
||||||
|
gdb_launch_params = ["arm-none-eabi-gdb"]
|
||||||
|
self._add_command(gdb_launch_params, f"target extended-remote {self.port}")
|
||||||
|
self._add_command(gdb_launch_params, "set pagination off")
|
||||||
|
self._add_command(gdb_launch_params, "set confirm off")
|
||||||
|
self._add_command(gdb_launch_params, "monitor swdp_scan")
|
||||||
|
return gdb_launch_params
|
||||||
|
|
||||||
def flash(self, file_path: str, do_verify: bool) -> bool:
|
def flash(self, file_path: str, do_verify: bool) -> bool:
|
||||||
if not self.port:
|
if not self.port:
|
||||||
if not self.probe():
|
if not self.probe():
|
||||||
@ -268,43 +294,25 @@ class BlackmagicProgrammer(Programmer):
|
|||||||
# -ex 'compare-sections'
|
# -ex 'compare-sections'
|
||||||
# -ex 'quit'
|
# -ex 'quit'
|
||||||
|
|
||||||
gdb_launch_params = ["arm-none-eabi-gdb", file_path]
|
gdb_launch_params = self._get_gdb_core_params()
|
||||||
self._add_command(gdb_launch_params, f"target extended-remote {self.port}")
|
|
||||||
self._add_command(gdb_launch_params, "set pagination off")
|
|
||||||
self._add_command(gdb_launch_params, "set confirm off")
|
|
||||||
self._add_command(gdb_launch_params, "monitor swdp_scan")
|
|
||||||
self._add_command(gdb_launch_params, "attach 1")
|
self._add_command(gdb_launch_params, "attach 1")
|
||||||
self._add_command(gdb_launch_params, "set mem inaccessible-by-default off")
|
self._add_command(gdb_launch_params, "set mem inaccessible-by-default off")
|
||||||
self._add_command(gdb_launch_params, "load")
|
self._add_command(gdb_launch_params, "load")
|
||||||
if do_verify:
|
if do_verify:
|
||||||
self._add_command(gdb_launch_params, "compare-sections")
|
self._add_command(gdb_launch_params, "compare-sections")
|
||||||
self._add_command(gdb_launch_params, "quit")
|
self._add_command(gdb_launch_params, "quit")
|
||||||
|
gdb_launch_params.append(file_path)
|
||||||
|
|
||||||
self.logger.debug(f"Launching: {' '.join(gdb_launch_params)}")
|
process = self._spawn_and_await(gdb_launch_params, True)
|
||||||
|
|
||||||
process = subprocess.Popen(
|
|
||||||
gdb_launch_params,
|
|
||||||
stdout=subprocess.PIPE,
|
|
||||||
stderr=subprocess.STDOUT,
|
|
||||||
)
|
|
||||||
|
|
||||||
while process.poll() is None:
|
|
||||||
time.sleep(0.5)
|
|
||||||
print(".", end="", flush=True)
|
|
||||||
print()
|
|
||||||
|
|
||||||
if not process.stdout:
|
if not process.stdout:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
output = process.stdout.read().decode("utf-8").strip()
|
output = process.stdout.read().decode("utf-8").strip()
|
||||||
flashed = "Loading section .text," in output
|
flashed = (
|
||||||
|
"Loading section .text," in output
|
||||||
# Check flash verification
|
and "MIS-MATCHED!" not in output
|
||||||
if "MIS-MATCHED!" in output:
|
and "target image does not match the loaded file" not in output
|
||||||
flashed = False
|
)
|
||||||
|
|
||||||
if "target image does not match the loaded file" in output:
|
|
||||||
flashed = False
|
|
||||||
|
|
||||||
if not flashed:
|
if not flashed:
|
||||||
self.logger.error("Blackmagic failed to flash")
|
self.logger.error("Blackmagic failed to flash")
|
||||||
@ -317,6 +325,20 @@ class BlackmagicProgrammer(Programmer):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
self.port = port
|
self.port = port
|
||||||
|
|
||||||
|
gdb_launch_params = self._get_gdb_core_params()
|
||||||
|
self._add_command(gdb_launch_params, "quit")
|
||||||
|
|
||||||
|
process = self._spawn_and_await(gdb_launch_params)
|
||||||
|
if not process.stdout or process.returncode != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
output = process.stdout.read().decode("utf-8").strip()
|
||||||
|
if "SW-DP scan failed!" in output:
|
||||||
|
self.logger.warning(
|
||||||
|
f"Found {self.get_name()} at {self.port}, but failed to attach. Is device connected and is System>Debug enabled?"
|
||||||
|
)
|
||||||
|
return False
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_name(self) -> str:
|
def get_name(self) -> str:
|
||||||
@ -358,6 +380,8 @@ class Main(App):
|
|||||||
AUTO_INTERFACE = "auto"
|
AUTO_INTERFACE = "auto"
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
|
Programmer.root_logger = self.logger
|
||||||
|
|
||||||
self.parser.add_argument(
|
self.parser.add_argument(
|
||||||
"filename",
|
"filename",
|
||||||
type=str,
|
type=str,
|
||||||
@ -433,10 +457,10 @@ class Main(App):
|
|||||||
available_interfaces = self._search_interface(network_flash_interfaces)
|
available_interfaces = self._search_interface(network_flash_interfaces)
|
||||||
|
|
||||||
if not available_interfaces:
|
if not available_interfaces:
|
||||||
self.logger.error("No interface found")
|
self.logger.error("No availiable interfaces")
|
||||||
return 1
|
return 1
|
||||||
elif len(available_interfaces) > 1:
|
elif len(available_interfaces) > 1:
|
||||||
self.logger.error("Multiple interfaces found: ")
|
self.logger.error("Multiple interfaces found:")
|
||||||
self.logger.error(
|
self.logger.error(
|
||||||
f"Please specify '--interface={[i.get_name() for i in available_interfaces]}'"
|
f"Please specify '--interface={[i.get_name() for i in available_interfaces]}'"
|
||||||
)
|
)
|
||||||
@ -446,11 +470,10 @@ class Main(App):
|
|||||||
|
|
||||||
if self.args.serial != self.AUTO_INTERFACE:
|
if self.args.serial != self.AUTO_INTERFACE:
|
||||||
interface.set_serial(self.args.serial)
|
interface.set_serial(self.args.serial)
|
||||||
self.logger.info(
|
self.logger.info(f"Using {interface.get_name()} with {self.args.serial}")
|
||||||
f"Flashing {file_path} via {interface.get_name()} with {self.args.serial}"
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
self.logger.info(f"Flashing {file_path} via {interface.get_name()}")
|
self.logger.info(f"Using {interface.get_name()}")
|
||||||
|
self.logger.info(f"Flashing {file_path}")
|
||||||
|
|
||||||
if not interface.flash(file_path, self.args.verify):
|
if not interface.flash(file_path, self.args.verify):
|
||||||
self.logger.error(f"Failed to flash via {interface.get_name()}")
|
self.logger.error(f"Failed to flash via {interface.get_name()}")
|
||||||
|