[FL-1228] FuriHal: add charge suppress API. (#743)
* FuriHal: add charge suppress API. * FuriHal: add guards to insomnia and charge suppress routines. * FuriHal: proper API for scheduler in power. * FuriHal: move charging control from critical section, fix deadlock. * Gui: use FreeRTOS native timers controls for IconAnimation, fix crash on animation start stop
This commit is contained in:
parent
a7edebce69
commit
832fb1b795
@ -2,6 +2,7 @@
|
|||||||
#include "icon_i.h"
|
#include "icon_i.h"
|
||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
#include <timers.h>
|
||||||
|
|
||||||
IconAnimation* icon_animation_alloc(const Icon* icon) {
|
IconAnimation* icon_animation_alloc(const Icon* icon) {
|
||||||
furi_assert(icon);
|
furi_assert(icon);
|
||||||
@ -63,8 +64,9 @@ void icon_animation_start(IconAnimation* instance) {
|
|||||||
if(!instance->animating) {
|
if(!instance->animating) {
|
||||||
instance->animating = true;
|
instance->animating = true;
|
||||||
furi_check(
|
furi_check(
|
||||||
osTimerStart(instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate)) ==
|
xTimerChangePeriod(
|
||||||
osOK);
|
instance->timer, (osKernelGetTickFreq() / instance->icon->frame_rate), 0) ==
|
||||||
|
pdPASS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +74,7 @@ void icon_animation_stop(IconAnimation* instance) {
|
|||||||
furi_assert(instance);
|
furi_assert(instance);
|
||||||
if(instance->animating) {
|
if(instance->animating) {
|
||||||
instance->animating = false;
|
instance->animating = false;
|
||||||
furi_check(osTimerStop(instance->timer) == osOK);
|
furi_check(xTimerStop(instance->timer, 0) == pdPASS);
|
||||||
instance->frame = 0;
|
instance->frame = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -260,8 +260,12 @@ int32_t subghz_app(void* p) {
|
|||||||
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart);
|
scene_manager_next_scene(subghz->scene_manager, SubGhzSceneStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_enter();
|
||||||
|
|
||||||
view_dispatcher_run(subghz->view_dispatcher);
|
view_dispatcher_run(subghz->view_dispatcher);
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_exit();
|
||||||
|
|
||||||
subghz_free(subghz);
|
subghz_free(subghz);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -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_init(&gpio_cc1101_g0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
|
||||||
hal_gpio_write(&gpio_cc1101_g0, true);
|
hal_gpio_write(&gpio_cc1101_g0, true);
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_enter();
|
||||||
|
|
||||||
if(furi_hal_subghz_tx()) {
|
if(furi_hal_subghz_tx()) {
|
||||||
printf("Transmitting at frequency %lu Hz\r\n", frequency);
|
printf("Transmitting at frequency %lu Hz\r\n", frequency);
|
||||||
printf("Press CTRL+C to stop\r\n");
|
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_set_path(FuriHalSubGhzPathIsolate);
|
||||||
furi_hal_subghz_sleep();
|
furi_hal_subghz_sleep();
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void subghz_cli_command_rx_carrier(Cli* cli, string_t args, void* context) {
|
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("Receiving at frequency %lu Hz\r\n", frequency);
|
||||||
printf("Press CTRL+C to stop\r\n");
|
printf("Press CTRL+C to stop\r\n");
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_enter();
|
||||||
|
|
||||||
furi_hal_subghz_rx();
|
furi_hal_subghz_rx();
|
||||||
|
|
||||||
while(!cli_cmd_interrupt_received(cli)) {
|
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);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_exit();
|
||||||
|
|
||||||
furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
|
furi_hal_subghz_set_path(FuriHalSubGhzPathIsolate);
|
||||||
furi_hal_subghz_sleep();
|
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_reset();
|
||||||
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
furi_hal_subghz_load_preset(FuriHalSubGhzPresetOok650Async);
|
||||||
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
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);
|
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))) {
|
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_stop_async_tx();
|
||||||
furi_hal_subghz_sleep();
|
furi_hal_subghz_sleep();
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_exit();
|
||||||
|
|
||||||
subghz_decoder_princeton_free(protocol);
|
subghz_decoder_princeton_free(protocol);
|
||||||
subghz_protocol_encoder_common_free(encoder);
|
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);
|
frequency = furi_hal_subghz_set_frequency_and_path(frequency);
|
||||||
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_enter();
|
||||||
|
|
||||||
// Prepare and start RX
|
// Prepare and start RX
|
||||||
furi_hal_subghz_start_async_rx(subghz_cli_command_rx_callback, instance);
|
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_stop_async_rx();
|
||||||
furi_hal_subghz_sleep();
|
furi_hal_subghz_sleep();
|
||||||
|
|
||||||
|
furi_hal_power_suppress_charge_exit();
|
||||||
|
|
||||||
printf("\r\nPackets recieved %u\r\n", instance->packet_count);
|
printf("\r\nPackets recieved %u\r\n", instance->packet_count);
|
||||||
|
|
||||||
// Cleanup
|
// Cleanup
|
||||||
|
@ -16,13 +16,15 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
volatile uint32_t insomnia;
|
volatile uint8_t insomnia;
|
||||||
volatile uint32_t deep_insomnia;
|
volatile uint8_t deep_insomnia;
|
||||||
|
volatile uint8_t suppress_charge;
|
||||||
} FuriHalPower;
|
} FuriHalPower;
|
||||||
|
|
||||||
static volatile FuriHalPower furi_hal_power = {
|
static volatile FuriHalPower furi_hal_power = {
|
||||||
.insomnia = 0,
|
.insomnia = 0,
|
||||||
.deep_insomnia = 1,
|
.deep_insomnia = 1,
|
||||||
|
.suppress_charge = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ParamCEDV cedv = {
|
const ParamCEDV cedv = {
|
||||||
@ -80,11 +82,15 @@ uint16_t furi_hal_power_insomnia_level() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_insomnia_enter() {
|
void furi_hal_power_insomnia_enter() {
|
||||||
|
vTaskSuspendAll();
|
||||||
furi_hal_power.insomnia++;
|
furi_hal_power.insomnia++;
|
||||||
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_insomnia_exit() {
|
void furi_hal_power_insomnia_exit() {
|
||||||
|
vTaskSuspendAll();
|
||||||
furi_hal_power.insomnia--;
|
furi_hal_power.insomnia--;
|
||||||
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_power_sleep_available() {
|
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(){
|
void furi_hal_power_disable_external_3_3v(){
|
||||||
LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin);
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -5,70 +5,88 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/** Get flash base address
|
/** Get flash base address
|
||||||
* @return pointer to flash base
|
*
|
||||||
|
* @return pointer to flash base
|
||||||
*/
|
*/
|
||||||
size_t furi_hal_flash_get_base();
|
size_t furi_hal_flash_get_base();
|
||||||
|
|
||||||
/** Get flash read block size
|
/** Get flash read block size
|
||||||
* @return size in bytes
|
*
|
||||||
|
* @return size in bytes
|
||||||
*/
|
*/
|
||||||
size_t furi_hal_flash_get_read_block_size();
|
size_t furi_hal_flash_get_read_block_size();
|
||||||
|
|
||||||
/** Get flash write block size
|
/** Get flash write block size
|
||||||
* @return size in bytes
|
*
|
||||||
|
* @return size in bytes
|
||||||
*/
|
*/
|
||||||
size_t furi_hal_flash_get_write_block_size();
|
size_t furi_hal_flash_get_write_block_size();
|
||||||
|
|
||||||
/** Get flash page size
|
/** Get flash page size
|
||||||
* @return size in bytes
|
*
|
||||||
|
* @return size in bytes
|
||||||
*/
|
*/
|
||||||
size_t furi_hal_flash_get_page_size();
|
size_t furi_hal_flash_get_page_size();
|
||||||
|
|
||||||
/** Get expected flash cycles count
|
/** 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();
|
size_t furi_hal_flash_get_cycles_count();
|
||||||
|
|
||||||
/** Get free flash start address
|
/** 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();
|
const void* furi_hal_flash_get_free_start_address();
|
||||||
|
|
||||||
/** Get free flash end 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();
|
const void* furi_hal_flash_get_free_end_address();
|
||||||
|
|
||||||
/** Get first free page start 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();
|
size_t furi_hal_flash_get_free_page_start_address();
|
||||||
|
|
||||||
/** Get free page count
|
/** Get free page count
|
||||||
* @return free page count
|
*
|
||||||
|
* @return free page count
|
||||||
*/
|
*/
|
||||||
size_t furi_hal_flash_get_free_page_count();
|
size_t furi_hal_flash_get_free_page_count();
|
||||||
|
|
||||||
/*
|
/** Erase Flash
|
||||||
* Erase Flash
|
*
|
||||||
* Locking operation, uses HSEM to manage shared access.
|
* 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);
|
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.
|
* 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);
|
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.
|
* 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);
|
bool furi_hal_flash_write_dword_from(size_t address, size_t source_address);
|
||||||
|
@ -16,13 +16,15 @@
|
|||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
volatile uint32_t insomnia;
|
volatile uint8_t insomnia;
|
||||||
volatile uint32_t deep_insomnia;
|
volatile uint8_t deep_insomnia;
|
||||||
|
volatile uint8_t suppress_charge;
|
||||||
} FuriHalPower;
|
} FuriHalPower;
|
||||||
|
|
||||||
static volatile FuriHalPower furi_hal_power = {
|
static volatile FuriHalPower furi_hal_power = {
|
||||||
.insomnia = 0,
|
.insomnia = 0,
|
||||||
.deep_insomnia = 1,
|
.deep_insomnia = 1,
|
||||||
|
.suppress_charge = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
const ParamCEDV cedv = {
|
const ParamCEDV cedv = {
|
||||||
@ -80,11 +82,15 @@ uint16_t furi_hal_power_insomnia_level() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_insomnia_enter() {
|
void furi_hal_power_insomnia_enter() {
|
||||||
|
vTaskSuspendAll();
|
||||||
furi_hal_power.insomnia++;
|
furi_hal_power.insomnia++;
|
||||||
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_power_insomnia_exit() {
|
void furi_hal_power_insomnia_exit() {
|
||||||
|
vTaskSuspendAll();
|
||||||
furi_hal_power.insomnia--;
|
furi_hal_power.insomnia--;
|
||||||
|
xTaskResumeAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_power_sleep_available() {
|
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(){
|
void furi_hal_power_disable_external_3_3v(){
|
||||||
LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin);
|
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();
|
||||||
|
}
|
||||||
|
}
|
@ -157,6 +157,16 @@ void furi_hal_power_enable_external_3_3v();
|
|||||||
*/
|
*/
|
||||||
void furi_hal_power_disable_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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,6 +91,16 @@ bool bq25896_is_charging() {
|
|||||||
return bq25896_regs.r0B.CHRG_STAT != ChrgStatNo;
|
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() {
|
void bq25896_enable_otg() {
|
||||||
bq25896_regs.r03.OTG_CONFIG = 1;
|
bq25896_regs.r03.OTG_CONFIG = 1;
|
||||||
bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03);
|
bq25896_write_reg(0x03, (uint8_t*)&bq25896_regs.r03);
|
||||||
|
@ -12,6 +12,12 @@ void bq25896_poweroff();
|
|||||||
/** Is currently charging */
|
/** Is currently charging */
|
||||||
bool bq25896_is_charging();
|
bool bq25896_is_charging();
|
||||||
|
|
||||||
|
/** Enable charging */
|
||||||
|
void bq25896_enable_charging();
|
||||||
|
|
||||||
|
/** Disable charging */
|
||||||
|
void bq25896_disable_charging();
|
||||||
|
|
||||||
/** Enable otg */
|
/** Enable otg */
|
||||||
void bq25896_enable_otg();
|
void bq25896_enable_otg();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user