diff --git a/applications/gui/icon_animation.c b/applications/gui/icon_animation.c index 90a89349..22089d63 100644 --- a/applications/gui/icon_animation.c +++ b/applications/gui/icon_animation.c @@ -2,6 +2,7 @@ #include "icon_i.h" #include +#include IconAnimation* icon_animation_alloc(const Icon* icon) { furi_assert(icon); @@ -63,8 +64,9 @@ void icon_animation_start(IconAnimation* instance) { if(!instance->animating) { instance->animating = true; furi_check( - osTimerStart(instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate)) == - osOK); + xTimerChangePeriod( + instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate), 0) == + pdPASS); } } @@ -72,7 +74,7 @@ void icon_animation_stop(IconAnimation* instance) { furi_assert(instance); if(instance->animating) { instance->animating = false; - furi_check(osTimerStop(instance->timer) == osOK); + furi_check(xTimerStop(instance->timer, 0) == pdPASS); instance->frame = 0; } } diff --git a/applications/subghz/subghz.c b/applications/subghz/subghz.c index 02da799d..38145697 100644 --- a/applications/subghz/subghz.c +++ b/applications/subghz/subghz.c @@ -260,8 +260,12 @@ int32_t subghz_app(void* p) { scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart); } + furi_hal_power_suppress_charge_enter(); + view_dispatcher_run(subghz->view_dispatcher); + furi_hal_power_suppress_charge_exit(); + subghz_free(subghz); return 0; diff --git a/applications/subghz/subghz_cli.c b/applications/subghz/subghz_cli.c index 1a33beab..94c2cd03 100644 --- a/applications/subghz/subghz_cli.c +++ b/applications/subghz/subghz_cli.c @@ -48,6 +48,8 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { hal_gpio_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); hal_gpio_write(&gpio_cc1101_g0, true); + furi_hal_power_suppress_charge_enter(); + if(furi_hal_subghz_tx()) { printf("Transmitting at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); @@ -60,6 +62,8 @@ void subghz_cli_command_tx_carrier(Cli* cli, string_t args, void* context) { furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); furi_hal_subghz_sleep(); + + furi_hal_power_suppress_charge_exit(); } void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { @@ -86,6 +90,8 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { printf("Receiving at frequency %lu Hz\r\n", frequency); printf("Press CTRL+C to stop\r\n"); + furi_hal_power_suppress_charge_enter(); + furi_hal_subghz_rx(); while(!cli_cmd_interrupt_received(cli)) { @@ -94,6 +100,8 @@ void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) { fflush(stdout); } + furi_hal_power_suppress_charge_exit(); + furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate); furi_hal_subghz_sleep(); } @@ -143,6 +151,9 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { furi_hal_subghz_reset(); furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async); frequency = furi_hal_subghz_set_frequency_and_path(frequency); + + furi_hal_power_suppress_charge_enter(); + furi_hal_subghz_start_async_tx(subghz_protocol_encoder_common_yield, encoder); while(!(furi_hal_subghz_is_async_tx_complete() || cli_cmd_interrupt_received(cli))) { @@ -153,6 +164,8 @@ void subghz_cli_command_tx(Cli* cli, string_t args, void* context) { furi_hal_subghz_stop_async_tx(); furi_hal_subghz_sleep(); + furi_hal_power_suppress_charge_exit(); + subghz_decoder_princeton_free(protocol); subghz_protocol_encoder_common_free(encoder); } @@ -218,6 +231,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { frequency = furi_hal_subghz_set_frequency_and_path(frequency); hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow); + furi_hal_power_suppress_charge_enter(); + // Prepare and start RX furi_hal_subghz_start_async_rx(subghz_cli_command_rx_callback, instance); @@ -243,6 +258,8 @@ void subghz_cli_command_rx(Cli* cli, string_t args, void* context) { furi_hal_subghz_stop_async_rx(); furi_hal_subghz_sleep(); + furi_hal_power_suppress_charge_exit(); + printf("\r\nPackets recieved %u\r\n", instance->packet_count); // Cleanup diff --git a/firmware/targets/f6/furi-hal/furi-hal-power.c b/firmware/targets/f6/furi-hal/furi-hal-power.c index afc430ab..47ce5f4d 100644 --- a/firmware/targets/f6/furi-hal/furi-hal-power.c +++ b/firmware/targets/f6/furi-hal/furi-hal-power.c @@ -16,13 +16,15 @@ #include typedef struct { - volatile uint32_t insomnia; - volatile uint32_t deep_insomnia; + volatile uint8_t insomnia; + volatile uint8_t deep_insomnia; + volatile uint8_t suppress_charge; } FuriHalPower; static volatile FuriHalPower furi_hal_power = { .insomnia = 0, .deep_insomnia = 1, + .suppress_charge = 0, }; const ParamCEDV cedv = { @@ -80,11 +82,15 @@ uint16_t furi_hal_power_insomnia_level() { } void furi_hal_power_insomnia_enter() { + vTaskSuspendAll(); furi_hal_power.insomnia++; + xTaskResumeAll(); } void furi_hal_power_insomnia_exit() { + vTaskSuspendAll(); furi_hal_power.insomnia--; + xTaskResumeAll(); } bool furi_hal_power_sleep_available() { @@ -282,3 +288,25 @@ void furi_hal_power_enable_external_3_3v(){ void furi_hal_power_disable_external_3_3v(){ LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); } + +void furi_hal_power_suppress_charge_enter() { + vTaskSuspendAll(); + bool disable_charging = furi_hal_power.suppress_charge == 0; + furi_hal_power.suppress_charge++; + xTaskResumeAll(); + + if (disable_charging) { + bq25896_disable_charging(); + } +} + +void furi_hal_power_suppress_charge_exit() { + vTaskSuspendAll(); + furi_hal_power.suppress_charge--; + bool enable_charging = furi_hal_power.suppress_charge == 0; + xTaskResumeAll(); + + if (enable_charging) { + bq25896_enable_charging(); + } +} \ No newline at end of file diff --git a/firmware/targets/f7/furi-hal/furi-hal-flash.h b/firmware/targets/f7/furi-hal/furi-hal-flash.h index 3ef9b730..583d53eb 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-flash.h +++ b/firmware/targets/f7/furi-hal/furi-hal-flash.h @@ -5,70 +5,88 @@ #include /** Get flash base address - * @return pointer to flash base + * + * @return pointer to flash base */ size_t furi_hal_flash_get_base(); /** Get flash read block size - * @return size in bytes + * + * @return size in bytes */ size_t furi_hal_flash_get_read_block_size(); /** Get flash write block size - * @return size in bytes + * + * @return size in bytes */ size_t furi_hal_flash_get_write_block_size(); /** Get flash page size - * @return size in bytes + * + * @return size in bytes */ size_t furi_hal_flash_get_page_size(); /** Get expected flash cycles count - * @return count of erase-write operations + * + * @return count of erase-write operations */ size_t furi_hal_flash_get_cycles_count(); /** Get free flash start address - * @return pointer to free region start + * + * @return pointer to free region start */ const void* furi_hal_flash_get_free_start_address(); /** Get free flash end address - * @return pointer to free region end + * + * @return pointer to free region end */ const void* furi_hal_flash_get_free_end_address(); /** Get first free page start address - * @return first free page memory address + * + * @return first free page memory address */ size_t furi_hal_flash_get_free_page_start_address(); /** Get free page count - * @return free page count + * + * @return free page count */ size_t furi_hal_flash_get_free_page_count(); -/* - * Erase Flash +/** Erase Flash + * * Locking operation, uses HSEM to manage shared access. - * @param page, page number - * @param count, page count to erase + * + * @param page page number + * @param count page count to erase + * + * @return true on success */ bool furi_hal_flash_erase(uint8_t page, uint8_t count); -/* - * Write double word (64 bits) +/** Write double word (64 bits) + * * Locking operation, uses HSEM to manage shared access. - * @param address - destination address, must be double word aligned. - * @param data - data to write + * + * @param address destination address, must be double word aligned. + * @param data data to write + * + * @return true on success */ bool furi_hal_flash_write_dword(size_t address, uint64_t data); -/* - * Write double word (64 bits) from address +/** Write double word (64 bits) from address + * * Locking operation, uses HSEM to manage shared access. - * @param address - destination address, must be block aligned - * @param source_address - source address + * + * @param address destination address, must be block aligned + * @param source_address source address + * + * @return true on success */ bool furi_hal_flash_write_dword_from(size_t address, size_t source_address); diff --git a/firmware/targets/f7/furi-hal/furi-hal-power.c b/firmware/targets/f7/furi-hal/furi-hal-power.c index afc430ab..47ce5f4d 100644 --- a/firmware/targets/f7/furi-hal/furi-hal-power.c +++ b/firmware/targets/f7/furi-hal/furi-hal-power.c @@ -16,13 +16,15 @@ #include typedef struct { - volatile uint32_t insomnia; - volatile uint32_t deep_insomnia; + volatile uint8_t insomnia; + volatile uint8_t deep_insomnia; + volatile uint8_t suppress_charge; } FuriHalPower; static volatile FuriHalPower furi_hal_power = { .insomnia = 0, .deep_insomnia = 1, + .suppress_charge = 0, }; const ParamCEDV cedv = { @@ -80,11 +82,15 @@ uint16_t furi_hal_power_insomnia_level() { } void furi_hal_power_insomnia_enter() { + vTaskSuspendAll(); furi_hal_power.insomnia++; + xTaskResumeAll(); } void furi_hal_power_insomnia_exit() { + vTaskSuspendAll(); furi_hal_power.insomnia--; + xTaskResumeAll(); } bool furi_hal_power_sleep_available() { @@ -282,3 +288,25 @@ void furi_hal_power_enable_external_3_3v(){ void furi_hal_power_disable_external_3_3v(){ LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin); } + +void furi_hal_power_suppress_charge_enter() { + vTaskSuspendAll(); + bool disable_charging = furi_hal_power.suppress_charge == 0; + furi_hal_power.suppress_charge++; + xTaskResumeAll(); + + if (disable_charging) { + bq25896_disable_charging(); + } +} + +void furi_hal_power_suppress_charge_exit() { + vTaskSuspendAll(); + furi_hal_power.suppress_charge--; + bool enable_charging = furi_hal_power.suppress_charge == 0; + xTaskResumeAll(); + + if (enable_charging) { + bq25896_enable_charging(); + } +} \ No newline at end of file diff --git a/firmware/targets/furi-hal-include/furi-hal-power.h b/firmware/targets/furi-hal-include/furi-hal-power.h index 8bbdcfed..d44138ab 100644 --- a/firmware/targets/furi-hal-include/furi-hal-power.h +++ b/firmware/targets/furi-hal-include/furi-hal-power.h @@ -157,6 +157,16 @@ void furi_hal_power_enable_external_3_3v(); */ void furi_hal_power_disable_external_3_3v(); +/** Enter supress charge mode. + * + * Use this function when your application need clean power supply. + */ +void furi_hal_power_suppress_charge_enter(); + +/** Exit supress charge mode + */ +void furi_hal_power_suppress_charge_exit(); + #ifdef __cplusplus } #endif diff --git a/lib/drivers/bq25896.c b/lib/drivers/bq25896.c index e767179f..9062653b 100644 --- a/lib/drivers/bq25896.c +++ b/lib/drivers/bq25896.c @@ -91,6 +91,16 @@ bool bq25896_is_charging() { return bq25896_regs.r0B.CHRG_STAT != ChrgStatNo; } +void bq25896_enable_charging() { + bq25896_regs.r03.CHG_CONFIG = 1; + bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); +} + +void bq25896_disable_charging() { + bq25896_regs.r03.CHG_CONFIG = 0; + bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); +} + void bq25896_enable_otg() { bq25896_regs.r03.OTG_CONFIG = 1; bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03); diff --git a/lib/drivers/bq25896.h b/lib/drivers/bq25896.h index e60fb247..03bf7ba2 100644 --- a/lib/drivers/bq25896.h +++ b/lib/drivers/bq25896.h @@ -12,6 +12,12 @@ void bq25896_poweroff(); /** Is currently charging */ bool bq25896_is_charging(); +/** Enable charging */ +void bq25896_enable_charging(); + +/** Disable charging */ +void bq25896_disable_charging(); + /** Enable otg */ void bq25896_enable_otg();