[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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく