mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-04-24 03:29:57 -07:00
Add automatic IR blaster detection
removed last_settings because it isnt needed anymore
This commit is contained in:
@@ -204,10 +204,7 @@ static InfraredApp* infrared_alloc() {
|
|||||||
infrared->loading = loading_alloc();
|
infrared->loading = loading_alloc();
|
||||||
infrared->progress = infrared_progress_view_alloc();
|
infrared->progress = infrared_progress_view_alloc();
|
||||||
|
|
||||||
infrared->last_settings = infrared_last_settings_alloc();
|
if(furi_hal_infrared_is_external_connected()) {
|
||||||
infrared_last_settings_load(infrared->last_settings);
|
|
||||||
|
|
||||||
if(infrared->last_settings->ext_5v) {
|
|
||||||
uint8_t attempts = 0;
|
uint8_t attempts = 0;
|
||||||
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||||
furi_hal_power_enable_otg();
|
furi_hal_power_enable_otg();
|
||||||
@@ -215,9 +212,7 @@ static InfraredApp* infrared_alloc() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(infrared->last_settings->ext_out && !furi_hal_infrared_get_debug_out_status()) {
|
furi_hal_infrared_block_external_output(false);
|
||||||
furi_hal_infrared_set_debug_out(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
return infrared;
|
return infrared;
|
||||||
}
|
}
|
||||||
@@ -286,13 +281,11 @@ static void infrared_free(InfraredApp* infrared) {
|
|||||||
furi_string_free(infrared->file_path);
|
furi_string_free(infrared->file_path);
|
||||||
furi_string_free(infrared->button_name);
|
furi_string_free(infrared->button_name);
|
||||||
|
|
||||||
if(infrared->last_settings->ext_5v) {
|
if(furi_hal_power_is_otg_enabled()) {
|
||||||
if(furi_hal_power_is_otg_enabled()) {
|
furi_hal_power_disable_otg();
|
||||||
furi_hal_power_disable_otg();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
infrared_last_settings_free(infrared->last_settings);
|
furi_hal_infrared_block_external_output(false);
|
||||||
|
|
||||||
free(infrared);
|
free(infrared);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
#include "infrared_remote.h"
|
#include "infrared_remote.h"
|
||||||
#include "infrared_brute_force.h"
|
#include "infrared_brute_force.h"
|
||||||
#include "infrared_custom_event.h"
|
#include "infrared_custom_event.h"
|
||||||
#include "infrared_last_settings.h"
|
// #include "infrared_last_settings.h"
|
||||||
|
|
||||||
#include "scenes/infrared_scene.h"
|
#include "scenes/infrared_scene.h"
|
||||||
#include "views/infrared_progress_view.h"
|
#include "views/infrared_progress_view.h"
|
||||||
@@ -129,7 +129,7 @@ struct InfraredApp {
|
|||||||
/** Arbitrary text storage for various inputs. */
|
/** Arbitrary text storage for various inputs. */
|
||||||
char text_store[INFRARED_TEXT_STORE_NUM][INFRARED_TEXT_STORE_SIZE + 1];
|
char text_store[INFRARED_TEXT_STORE_NUM][INFRARED_TEXT_STORE_SIZE + 1];
|
||||||
InfraredAppState app_state; /**< Application state. */
|
InfraredAppState app_state; /**< Application state. */
|
||||||
InfraredLastSettings* last_settings; /**< Last settings. */
|
//InfraredLastSettings* last_settings; /**< Last settings. */
|
||||||
|
|
||||||
void* rpc_ctx; /**< Pointer to the RPC context object. */
|
void* rpc_ctx; /**< Pointer to the RPC context object. */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,88 +0,0 @@
|
|||||||
#include "infrared_last_settings.h"
|
|
||||||
|
|
||||||
#define TAG "InfraredLastSettings"
|
|
||||||
|
|
||||||
#define INFRARED_LAST_SETTINGS_FILE_TYPE "Flipper Infrared Last Settings File"
|
|
||||||
#define INFRARED_LAST_SETTINGS_FILE_VERSION 1
|
|
||||||
#define INFRARED_LAST_SETTINGS_PATH EXT_PATH("infrared/assets/last_infrared.settings")
|
|
||||||
|
|
||||||
#define INFRARED_LAST_SETTINGS_FIELD_EXTPOWER "External5V"
|
|
||||||
#define INFRARED_LAST_SETTINGS_FIELD_EXTOUT "ExternalOut"
|
|
||||||
|
|
||||||
InfraredLastSettings* infrared_last_settings_alloc(void) {
|
|
||||||
InfraredLastSettings* instance = malloc(sizeof(InfraredLastSettings));
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
void infrared_last_settings_free(InfraredLastSettings* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
free(instance);
|
|
||||||
}
|
|
||||||
|
|
||||||
void infrared_last_settings_load(InfraredLastSettings* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
FlipperFormat* fff_data_file = flipper_format_file_alloc(storage);
|
|
||||||
|
|
||||||
bool temp_extpower = false;
|
|
||||||
bool temp_extout = false;
|
|
||||||
|
|
||||||
if(FSE_OK == storage_sd_status(storage) && INFRARED_LAST_SETTINGS_PATH &&
|
|
||||||
flipper_format_file_open_existing(fff_data_file, INFRARED_LAST_SETTINGS_PATH)) {
|
|
||||||
flipper_format_read_bool(
|
|
||||||
fff_data_file, INFRARED_LAST_SETTINGS_FIELD_EXTPOWER, (bool*)&temp_extpower, 1);
|
|
||||||
flipper_format_read_bool(
|
|
||||||
fff_data_file, INFRARED_LAST_SETTINGS_FIELD_EXTOUT, (bool*)&temp_extout, 1);
|
|
||||||
} else {
|
|
||||||
FURI_LOG_E(TAG, "Error open file %s", INFRARED_LAST_SETTINGS_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
instance->ext_5v = temp_extpower;
|
|
||||||
instance->ext_out = temp_extout;
|
|
||||||
|
|
||||||
flipper_format_file_close(fff_data_file);
|
|
||||||
flipper_format_free(fff_data_file);
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool infrared_last_settings_save(InfraredLastSettings* instance) {
|
|
||||||
furi_assert(instance);
|
|
||||||
|
|
||||||
bool saved = false;
|
|
||||||
Storage* storage = furi_record_open(RECORD_STORAGE);
|
|
||||||
FlipperFormat* file = flipper_format_file_alloc(storage);
|
|
||||||
|
|
||||||
do {
|
|
||||||
if(FSE_OK != storage_sd_status(storage)) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open file
|
|
||||||
if(!flipper_format_file_open_always(file, INFRARED_LAST_SETTINGS_PATH)) break;
|
|
||||||
|
|
||||||
// Write header
|
|
||||||
if(!flipper_format_write_header_cstr(
|
|
||||||
file, INFRARED_LAST_SETTINGS_FILE_TYPE, INFRARED_LAST_SETTINGS_FILE_VERSION))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!flipper_format_insert_or_update_bool(
|
|
||||||
file, INFRARED_LAST_SETTINGS_FIELD_EXTPOWER, &instance->ext_5v, 1))
|
|
||||||
break;
|
|
||||||
if(!flipper_format_insert_or_update_bool(
|
|
||||||
file, INFRARED_LAST_SETTINGS_FIELD_EXTOUT, &instance->ext_out, 1))
|
|
||||||
break;
|
|
||||||
|
|
||||||
saved = true;
|
|
||||||
} while(0);
|
|
||||||
|
|
||||||
if(!saved) {
|
|
||||||
FURI_LOG_E(TAG, "Error save file %s", INFRARED_LAST_SETTINGS_PATH);
|
|
||||||
}
|
|
||||||
|
|
||||||
flipper_format_file_close(file);
|
|
||||||
flipper_format_free(file);
|
|
||||||
furi_record_close(RECORD_STORAGE);
|
|
||||||
|
|
||||||
return saved;
|
|
||||||
}
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <furi_hal.h>
|
|
||||||
#include <storage/storage.h>
|
|
||||||
#include <lib/flipper_format/flipper_format.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bool ext_5v;
|
|
||||||
bool ext_out;
|
|
||||||
} InfraredLastSettings;
|
|
||||||
|
|
||||||
InfraredLastSettings* infrared_last_settings_alloc(void);
|
|
||||||
void infrared_last_settings_free(InfraredLastSettings* instance);
|
|
||||||
void infrared_last_settings_load(InfraredLastSettings* instance);
|
|
||||||
bool infrared_last_settings_save(InfraredLastSettings* instance);
|
|
||||||
@@ -9,19 +9,22 @@ const char* const infrared_debug_cfg_variables_text[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static void infrared_scene_debug_settings_changed(VariableItem* item) {
|
static void infrared_scene_debug_settings_changed(VariableItem* item) {
|
||||||
InfraredApp* infrared = variable_item_get_context(item);
|
|
||||||
value_index_ir = variable_item_get_current_value_index(item);
|
value_index_ir = variable_item_get_current_value_index(item);
|
||||||
|
|
||||||
variable_item_set_current_value_text(item, infrared_debug_cfg_variables_text[value_index_ir]);
|
variable_item_set_current_value_text(item, infrared_debug_cfg_variables_text[value_index_ir]);
|
||||||
|
|
||||||
furi_hal_infrared_set_debug_out(value_index_ir);
|
if(value_index_ir == 0) {
|
||||||
|
furi_hal_infrared_set_debug_out(false);
|
||||||
infrared->last_settings->ext_out = value_index_ir == 1;
|
furi_hal_infrared_block_external_output(true);
|
||||||
infrared_last_settings_save(infrared->last_settings);
|
if(furi_hal_power_is_otg_enabled()) {
|
||||||
|
furi_hal_power_disable_otg();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
furi_hal_infrared_block_external_output(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void infrared_scene_debug_settings_power_changed(VariableItem* item) {
|
static void infrared_scene_debug_settings_power_changed(VariableItem* item) {
|
||||||
InfraredApp* infrared = variable_item_get_context(item);
|
|
||||||
bool value = variable_item_get_current_value_index(item);
|
bool value = variable_item_get_current_value_index(item);
|
||||||
if(value) {
|
if(value) {
|
||||||
for(int i = 0; i < 5 && !furi_hal_power_is_otg_enabled(); i++) {
|
for(int i = 0; i < 5 && !furi_hal_power_is_otg_enabled(); i++) {
|
||||||
@@ -34,9 +37,6 @@ static void infrared_scene_debug_settings_power_changed(VariableItem* item) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
variable_item_set_current_value_text(item, value ? "ON" : "OFF");
|
variable_item_set_current_value_text(item, value ? "ON" : "OFF");
|
||||||
|
|
||||||
infrared->last_settings->ext_5v = value;
|
|
||||||
infrared_last_settings_save(infrared->last_settings);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void infrared_debug_settings_start_var_list_enter_callback(void* context, uint32_t index) {
|
static void infrared_debug_settings_start_var_list_enter_callback(void* context, uint32_t index) {
|
||||||
@@ -49,7 +49,10 @@ void infrared_scene_debug_settings_on_enter(void* context) {
|
|||||||
|
|
||||||
VariableItemList* variable_item_list = infrared->variable_item_list;
|
VariableItemList* variable_item_list = infrared->variable_item_list;
|
||||||
|
|
||||||
value_index_ir = furi_hal_infrared_get_debug_out_status();
|
value_index_ir =
|
||||||
|
(furi_hal_infrared_is_external_connected() &&
|
||||||
|
!furi_hal_infrared_is_external_output_blocked());
|
||||||
|
|
||||||
VariableItem* item = variable_item_list_add(
|
VariableItem* item = variable_item_list_add(
|
||||||
variable_item_list,
|
variable_item_list,
|
||||||
"Send signal to",
|
"Send signal to",
|
||||||
@@ -70,10 +73,19 @@ void infrared_scene_debug_settings_on_enter(void* context) {
|
|||||||
infrared_scene_debug_settings_power_changed,
|
infrared_scene_debug_settings_power_changed,
|
||||||
infrared);
|
infrared);
|
||||||
bool enabled = furi_hal_power_is_otg_enabled() ||
|
bool enabled = furi_hal_power_is_otg_enabled() ||
|
||||||
furi_hal_power_is_charging(); // 5v is enabled via hardware if charging
|
furi_hal_power_is_charging() || // 5v is enabled via hardware if charging
|
||||||
|
furi_hal_infrared_is_external_connected();
|
||||||
variable_item_set_current_value_index(item, enabled);
|
variable_item_set_current_value_index(item, enabled);
|
||||||
variable_item_set_current_value_text(item, enabled ? "ON" : "OFF");
|
variable_item_set_current_value_text(item, enabled ? "ON" : "OFF");
|
||||||
|
|
||||||
|
if(furi_hal_infrared_is_external_connected() && !furi_hal_power_is_otg_enabled()) {
|
||||||
|
uint8_t attempts = 0;
|
||||||
|
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||||
|
furi_hal_power_enable_otg();
|
||||||
|
furi_delay_ms(10);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewVariableItemList);
|
view_dispatcher_switch_to_view(infrared->view_dispatcher, InfraredViewVariableItemList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1319,8 +1319,11 @@ Function,+,furi_hal_infrared_async_tx_set_signal_sent_isr_callback,void,"FuriHal
|
|||||||
Function,+,furi_hal_infrared_async_tx_start,void,"uint32_t, float"
|
Function,+,furi_hal_infrared_async_tx_start,void,"uint32_t, float"
|
||||||
Function,+,furi_hal_infrared_async_tx_stop,void,
|
Function,+,furi_hal_infrared_async_tx_stop,void,
|
||||||
Function,+,furi_hal_infrared_async_tx_wait_termination,void,
|
Function,+,furi_hal_infrared_async_tx_wait_termination,void,
|
||||||
|
Function,+,furi_hal_infrared_block_external_output,void,_Bool
|
||||||
Function,+,furi_hal_infrared_get_debug_out_status,_Bool,
|
Function,+,furi_hal_infrared_get_debug_out_status,_Bool,
|
||||||
Function,+,furi_hal_infrared_is_busy,_Bool,
|
Function,+,furi_hal_infrared_is_busy,_Bool,
|
||||||
|
Function,+,furi_hal_infrared_is_external_connected,_Bool,
|
||||||
|
Function,+,furi_hal_infrared_is_external_output_blocked,_Bool,
|
||||||
Function,+,furi_hal_infrared_set_debug_out,void,_Bool
|
Function,+,furi_hal_infrared_set_debug_out,void,_Bool
|
||||||
Function,-,furi_hal_init,void,
|
Function,-,furi_hal_init,void,
|
||||||
Function,-,furi_hal_init_early,void,
|
Function,-,furi_hal_init_early,void,
|
||||||
|
|||||||
|
@@ -2,6 +2,7 @@
|
|||||||
#include <furi_hal_interrupt.h>
|
#include <furi_hal_interrupt.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
#include <furi_hal_bus.h>
|
#include <furi_hal_bus.h>
|
||||||
|
#include <furi_hal_power.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
#include <stm32wbxx_ll_tim.h>
|
||||||
#include <stm32wbxx_ll_dma.h>
|
#include <stm32wbxx_ll_dma.h>
|
||||||
@@ -79,6 +80,7 @@ static volatile InfraredState furi_hal_infrared_state = InfraredStateIdle;
|
|||||||
static InfraredTimTx infrared_tim_tx;
|
static InfraredTimTx infrared_tim_tx;
|
||||||
static InfraredTimRx infrared_tim_rx;
|
static InfraredTimRx infrared_tim_rx;
|
||||||
static bool infrared_external_output;
|
static bool infrared_external_output;
|
||||||
|
static bool block_external;
|
||||||
|
|
||||||
static void furi_hal_infrared_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift);
|
static void furi_hal_infrared_tx_fill_buffer(uint8_t buf_num, uint8_t polarity_shift);
|
||||||
static void furi_hal_infrared_async_tx_free_resources(void);
|
static void furi_hal_infrared_async_tx_free_resources(void);
|
||||||
@@ -648,12 +650,29 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
|||||||
furi_delay_us(5);
|
furi_delay_us(5);
|
||||||
LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* DMA -> TIMx_RCR */
|
LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* DMA -> TIMx_RCR */
|
||||||
furi_delay_us(5);
|
furi_delay_us(5);
|
||||||
|
|
||||||
|
if(block_external) {
|
||||||
|
infrared_external_output = false;
|
||||||
|
} else {
|
||||||
|
infrared_external_output = furi_hal_infrared_is_external_connected();
|
||||||
|
}
|
||||||
|
|
||||||
if(infrared_external_output) {
|
if(infrared_external_output) {
|
||||||
|
if(!furi_hal_power_is_otg_enabled()) {
|
||||||
|
uint8_t attempts = 0;
|
||||||
|
while(!furi_hal_power_is_otg_enabled() && attempts++ < 5) {
|
||||||
|
furi_hal_power_enable_otg();
|
||||||
|
furi_delay_ms(10);
|
||||||
|
}
|
||||||
|
furi_delay_ms(100);
|
||||||
|
}
|
||||||
|
|
||||||
LL_GPIO_ResetOutputPin(
|
LL_GPIO_ResetOutputPin(
|
||||||
gpio_ext_pa7.port, gpio_ext_pa7.pin); /* when disable it prevents false pulse */
|
gpio_ext_pa7.port, gpio_ext_pa7.pin); /* when disable it prevents false pulse */
|
||||||
furi_hal_gpio_init_ex(
|
furi_hal_gpio_init_ex(
|
||||||
&gpio_ext_pa7, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1);
|
&gpio_ext_pa7, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1);
|
||||||
} else {
|
} else {
|
||||||
|
furi_hal_power_disable_otg();
|
||||||
LL_GPIO_ResetOutputPin(
|
LL_GPIO_ResetOutputPin(
|
||||||
gpio_infrared_tx.port,
|
gpio_infrared_tx.port,
|
||||||
gpio_infrared_tx.pin); /* when disable it prevents false pulse */
|
gpio_infrared_tx.pin); /* when disable it prevents false pulse */
|
||||||
@@ -708,3 +727,19 @@ void furi_hal_infrared_async_tx_set_signal_sent_isr_callback(
|
|||||||
infrared_tim_tx.signal_sent_callback = callback;
|
infrared_tim_tx.signal_sent_callback = callback;
|
||||||
infrared_tim_tx.signal_sent_context = context;
|
infrared_tim_tx.signal_sent_context = context;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool furi_hal_infrared_is_external_connected() {
|
||||||
|
furi_hal_gpio_init(&gpio_ext_pa7, GpioModeInput, GpioPullUp, GpioSpeedHigh);
|
||||||
|
furi_delay_ms(1);
|
||||||
|
bool is_external_connected = !furi_hal_gpio_read(&gpio_ext_pa7);
|
||||||
|
furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||||
|
return is_external_connected;
|
||||||
|
}
|
||||||
|
|
||||||
|
void furi_hal_infrared_block_external_output(bool block) {
|
||||||
|
block_external = block;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool furi_hal_infrared_is_external_output_blocked(void) {
|
||||||
|
return block_external;
|
||||||
|
}
|
||||||
@@ -149,6 +149,25 @@ void furi_hal_infrared_async_tx_set_signal_sent_isr_callback(
|
|||||||
FuriHalInfraredTxSignalSentISRCallback callback,
|
FuriHalInfraredTxSignalSentISRCallback callback,
|
||||||
void* context);
|
void* context);
|
||||||
|
|
||||||
|
/** Check if a module (like IR Blaster) is connected to PA7
|
||||||
|
*
|
||||||
|
* return true if a module is connected, false otherwise
|
||||||
|
*/
|
||||||
|
bool furi_hal_infrared_is_external_connected();
|
||||||
|
|
||||||
|
/** Block external output on PA7
|
||||||
|
*
|
||||||
|
* if blocked, its forced to internal IR. If unblocked, external IR is used if connected
|
||||||
|
* @param block true to block, false to unblock
|
||||||
|
*/
|
||||||
|
void furi_hal_infrared_block_external_output(bool block);
|
||||||
|
|
||||||
|
/** Check if external output on PA7 is blocked
|
||||||
|
*
|
||||||
|
* @return true if blocked, false otherwise
|
||||||
|
*/
|
||||||
|
bool furi_hal_infrared_is_external_output_blocked();
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user