From 8f1e07db7975556f5c1033b6ce5172aad34cd5af Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 21 Apr 2022 22:31:22 +0300 Subject: [PATCH 01/37] Disable USART in sleep --- firmware/targets/f7/ble_glue/app_conf.h | 2 +- firmware/targets/f7/furi_hal/furi_hal_os.c | 36 +++++++++++++++++++ firmware/targets/f7/furi_hal/furi_hal_power.c | 2 +- firmware/targets/f7/furi_hal/furi_hal_uart.c | 18 ++++++++++ firmware/targets/f7/furi_hal/furi_hal_uart.h | 16 ++++++++- 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/firmware/targets/f7/ble_glue/app_conf.h b/firmware/targets/f7/ble_glue/app_conf.h index 96a0c25b6e4..1406f96496a 100644 --- a/firmware/targets/f7/ble_glue/app_conf.h +++ b/firmware/targets/f7/ble_glue/app_conf.h @@ -396,7 +396,7 @@ typedef enum { * keep debugger enabled while in any low power mode when set to 1 * should be set to 0 in production */ -#define CFG_DEBUGGER_SUPPORTED 0 +#define CFG_DEBUGGER_SUPPORTED 1 /** * When set to 1, the traces are enabled in the BLE services diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index e282645bc41..2a17ec519cb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -1,4 +1,6 @@ #include +#include +#include #include #include #include @@ -18,6 +20,12 @@ #define FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH (FURI_HAL_OS_IDLE_CNT_TO_TICKS(FURI_HAL_IDLE_TIMER_MAX)) #define FURI_HAL_OS_MAX_SLEEP (FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH - 1) +#define FURI_HAL_OS_EXTI_IRQ_MASK_0 \ + ((1 << EXTI0_IRQn) | (1 << EXTI1_IRQn) | (1 << EXTI2_IRQn) | (1 << EXTI3_IRQn) | \ + (1 << EXTI4_IRQn) | (1 << EXTI9_5_IRQn)) +#define FURI_HAL_OS_EXTI_IRQ_MASK_1 ((1 << (EXTI15_10_IRQn - 32))) +#define FURI_HAL_OS_IPCC_IRQ_MASK_1 ((1 << (IPCC_C1_TX_IRQn - 32)) | (1 << (IPCC_C1_TX_IRQn - 32))) + #ifdef FURI_HAL_OS_DEBUG #include @@ -60,6 +68,27 @@ void furi_hal_os_tick() { } } +static inline void furi_hal_os_suspend_aux_periphs() { + // Disable USART + furi_hal_uart_suspend(FuriHalUartIdUSART1); + furi_hal_uart_suspend(FuriHalUartIdLPUART1); + // Disable USB +} + +static inline void furi_hal_os_resume_aux_periphs() { + // Re-enable USART + furi_hal_uart_resume(FuriHalUartIdUSART1); + furi_hal_uart_resume(FuriHalUartIdLPUART1); + // Re-enable USB +} + +static inline bool furi_hal_os_is_bad_interrupt_pending() { + // Only EXTI and IPCC interrupts are allowed in sleep mode + return (NVIC->ICPR[0] & ~FURI_HAL_OS_EXTI_IRQ_MASK_0) || + (NVIC->ICPR[1] & ~FURI_HAL_OS_EXTI_IRQ_MASK_1) || + (NVIC->ICPR[1] & ~FURI_HAL_OS_IPCC_IRQ_MASK_1); +} + static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Stop ticks furi_hal_clock_suspend_tick(); @@ -106,15 +135,21 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { expected_idle_ticks = FURI_HAL_OS_MAX_SLEEP; } + furi_hal_os_suspend_aux_periphs(); // Stop IRQ handling, no one should disturb us till we finish __disable_irq(); // Confirm OS that sleep is still possible if(eTaskConfirmSleepModeStatus() == eAbortSleep) { + furi_hal_os_resume_aux_periphs(); __enable_irq(); return; } + if(furi_hal_os_is_bad_interrupt_pending()) { + furi_crash("Bad interrupt pending before sleep"); + } + // Sleep and track how much ticks we spent sleeping uint32_t completed_ticks = furi_hal_os_sleep(expected_idle_ticks); // Notify system about time spent in sleep @@ -122,6 +157,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { vTaskStepTick(MIN(completed_ticks, expected_idle_ticks)); } + furi_hal_os_resume_aux_periphs(); // Reenable IRQ __enable_irq(); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 2b78c7f0b2c..53a60c587af 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -28,7 +28,7 @@ typedef struct { static volatile FuriHalPower furi_hal_power = { .insomnia = 0, - .deep_insomnia = 1, + .deep_insomnia = 0, .suppress_charge = 0, }; diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.c b/firmware/targets/f7/furi_hal/furi_hal_uart.c index c4ad20162fe..345f8768b8d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.c +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.c @@ -136,6 +136,24 @@ void furi_hal_uart_deinit(FuriHalUartId ch) { } } +void furi_hal_uart_suspend(FuriHalUartId channel) { + if(channel == FuriHalUartIdLPUART1) { + LL_LPUART_Disable(LPUART1); + NVIC_ClearPendingIRQ(LPUART1_IRQn); + } else if(channel == FuriHalUartIdUSART1) { + LL_USART_Disable(USART1); + NVIC_ClearPendingIRQ(USART1_IRQn); + } +} + +void furi_hal_uart_resume(FuriHalUartId channel) { + if(channel == FuriHalUartIdLPUART1) { + LL_LPUART_Enable(LPUART1); + } else if(channel == FuriHalUartIdUSART1) { + LL_USART_Enable(USART1); + } +} + void furi_hal_uart_tx(FuriHalUartId ch, uint8_t* buffer, size_t buffer_size) { if(ch == FuriHalUartIdUSART1) { if(LL_USART_IsEnabled(USART1) == 0) return; diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.h b/firmware/targets/f7/furi_hal/furi_hal_uart.h index 9224a0b2c8d..78b9c0718a7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.h +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.h @@ -46,6 +46,20 @@ void furi_hal_uart_init(FuriHalUartId channel, uint32_t baud); */ void furi_hal_uart_deinit(FuriHalUartId channel); +/** + * Suspend UART operation + * Disables UART hardware, settings and callbacks are preserved + * @param channel UART channel + */ +void furi_hal_uart_suspend(FuriHalUartId channel); + +/** + * Resume UART operation + * Resumes UART hardware from suspended state + * @param channel UART channel + */ +void furi_hal_uart_resume(FuriHalUartId channel); + /** * Changes UART baudrate * @param channel UART channel @@ -74,4 +88,4 @@ void furi_hal_uart_set_irq_cb( #ifdef __cplusplus } -#endif \ No newline at end of file +#endif From 030181740779a2b76d218e27796108fa5b468b7c Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 21 Apr 2022 23:18:16 +0300 Subject: [PATCH 02/37] Restore UART state on suspend/resume --- firmware/targets/f7/furi_hal/furi_hal_uart.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.c b/firmware/targets/f7/furi_hal/furi_hal_uart.c index 345f8768b8d..ee7172fb14d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.c +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.c @@ -8,6 +8,8 @@ #include #include +static bool furi_hal_usart_prev_enabled[2]; + static void (*irq_cb[2])(uint8_t ev, uint8_t data, void* context); static void* irq_ctx[2]; @@ -137,17 +139,21 @@ void furi_hal_uart_deinit(FuriHalUartId ch) { } void furi_hal_uart_suspend(FuriHalUartId channel) { - if(channel == FuriHalUartIdLPUART1) { + if(channel == FuriHalUartIdLPUART1 && LL_LPUART_IsEnabled(LPUART1)) { LL_LPUART_Disable(LPUART1); NVIC_ClearPendingIRQ(LPUART1_IRQn); - } else if(channel == FuriHalUartIdUSART1) { + furi_hal_usart_prev_enabled[channel] = true; + } else if(channel == FuriHalUartIdUSART1 && LL_USART_IsEnabled(USART1)) { LL_USART_Disable(USART1); NVIC_ClearPendingIRQ(USART1_IRQn); + furi_hal_usart_prev_enabled[channel] = true; } } void furi_hal_uart_resume(FuriHalUartId channel) { - if(channel == FuriHalUartIdLPUART1) { + if(!furi_hal_usart_prev_enabled[channel]) { + return; + } else if(channel == FuriHalUartIdLPUART1) { LL_LPUART_Enable(LPUART1); } else if(channel == FuriHalUartIdUSART1) { LL_USART_Enable(USART1); From 55f8f2a02b29613b99e123eeb6e3a473081e13f3 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 21 Apr 2022 23:26:11 +0300 Subject: [PATCH 03/37] FuriHal: Enable stop mode and add insomnia to I2C and SPI --- applications/loader/loader.c | 4 +- firmware/targets/f7/furi_hal/furi_hal.c | 4 ++ firmware/targets/f7/furi_hal/furi_hal_i2c.c | 3 ++ firmware/targets/f7/furi_hal/furi_hal_os.c | 30 +++++++------- firmware/targets/f7/furi_hal/furi_hal_power.c | 39 ++++++++++++++++++- .../targets/f7/furi_hal/furi_hal_resources.c | 16 ++++---- firmware/targets/f7/furi_hal/furi_hal_spi.c | 5 +++ 7 files changed, 73 insertions(+), 28 deletions(-) diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 3882647efdb..2c1467ddba9 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -238,7 +238,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con if(thread_state == FuriThreadStateRunning) { event.type = LoaderEventTypeApplicationStarted; furi_pubsub_publish(loader_instance->pubsub, &event); - furi_hal_power_insomnia_enter(); + // furi_hal_power_insomnia_enter(); } else if(thread_state == FuriThreadStateStopped) { FURI_LOG_I( TAG, @@ -251,7 +251,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con loader_instance->application_arguments = NULL; } - furi_hal_power_insomnia_exit(); + // furi_hal_power_insomnia_exit(); loader_unlock(instance); event.type = LoaderEventTypeApplicationStopped; diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index b3362ba88ea..48669c78cc9 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -20,6 +20,10 @@ void furi_hal_init_early() { furi_hal_light_init(); furi_hal_rtc_init_early(); + + LL_DBGMCU_EnableDBGSleepMode(); + LL_DBGMCU_EnableDBGStopMode(); + LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); } void furi_hal_deinit_early() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_i2c.c b/firmware/targets/f7/furi_hal/furi_hal_i2c.c index 7e0bee58b64..fdef1127091 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_i2c.c +++ b/firmware/targets/f7/furi_hal/furi_hal_i2c.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -23,6 +24,7 @@ void furi_hal_i2c_init() { } void furi_hal_i2c_acquire(FuriHalI2cBusHandle* handle) { + furi_hal_power_insomnia_enter(); // Lock bus access handle->bus->callback(handle->bus, FuriHalI2cBusEventLock); // Ensuree that no active handle set @@ -46,6 +48,7 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle) { handle->bus->current_handle = NULL; // Unlock bus handle->bus->callback(handle->bus, FuriHalI2cBusEventUnlock); + furi_hal_power_insomnia_exit(); } bool furi_hal_i2c_tx( diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 2a17ec519cb..9380dbf2ec4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -3,8 +3,11 @@ #include #include #include +#include +#include #include #include + #include #include @@ -29,15 +32,8 @@ #ifdef FURI_HAL_OS_DEBUG #include -#define LED_SLEEP_PORT GPIOA -#define LED_SLEEP_PIN LL_GPIO_PIN_7 -#define LED_TICK_PORT GPIOA -#define LED_TICK_PIN LL_GPIO_PIN_6 -#define LED_SECOND_PORT GPIOA -#define LED_SECOND_PIN LL_GPIO_PIN_4 - void furi_hal_os_timer_callback() { - LL_GPIO_TogglePin(LED_SECOND_PORT, LED_SECOND_PIN); + furi_hal_gpio_write(&gpio_ext_pa4, !furi_hal_gpio_read(&gpio_ext_pa4)); } #endif @@ -49,9 +45,9 @@ void furi_hal_os_init() { furi_hal_idle_timer_init(); #ifdef FURI_HAL_OS_DEBUG - LL_GPIO_SetPinMode(LED_SLEEP_PORT, LED_SLEEP_PIN, LL_GPIO_MODE_OUTPUT); - LL_GPIO_SetPinMode(LED_TICK_PORT, LED_TICK_PIN, LL_GPIO_MODE_OUTPUT); - LL_GPIO_SetPinMode(LED_SECOND_PORT, LED_SECOND_PIN, LL_GPIO_MODE_OUTPUT); + furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_ext_pa6, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeOutputPushPull); osTimerId_t second_timer = osTimerNew(furi_hal_os_timer_callback, osTimerPeriodic, NULL, NULL); osTimerStart(second_timer, FURI_HAL_OS_TICK_HZ); #endif @@ -62,7 +58,7 @@ void furi_hal_os_init() { void furi_hal_os_tick() { if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) { #ifdef FURI_HAL_OS_DEBUG - LL_GPIO_TogglePin(LED_TICK_PORT, LED_TICK_PIN); + furi_hal_gpio_write(&gpio_ext_pa6, !furi_hal_gpio_read(&gpio_ext_pa6)); #endif xPortSysTickHandler(); } @@ -97,14 +93,14 @@ static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { furi_hal_idle_timer_start(FURI_HAL_OS_TICKS_TO_IDLE_CNT(expected_idle_ticks)); #ifdef FURI_HAL_OS_DEBUG - LL_GPIO_ResetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN); + furi_hal_gpio_write(&gpio_ext_pa7, 0); #endif // Go to sleep mode furi_hal_power_sleep(); #ifdef FURI_HAL_OS_DEBUG - LL_GPIO_SetOutputPin(LED_SLEEP_PORT, LED_SLEEP_PIN); + furi_hal_gpio_write(&gpio_ext_pa7, 1); #endif // Calculate how much time we spent in the sleep @@ -146,9 +142,9 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { return; } - if(furi_hal_os_is_bad_interrupt_pending()) { - furi_crash("Bad interrupt pending before sleep"); - } + // if(furi_hal_os_is_bad_interrupt_pending()) { + // furi_crash("Bad interrupt pending before sleep"); + // } // Sleep and track how much ticks we spent sleeping uint32_t completed_ticks = furi_hal_os_sleep(expected_idle_ticks); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 53a60c587af..faceb534314 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -84,6 +85,11 @@ void furi_hal_power_init() { bq25896_init(&furi_hal_i2c_handle_power); furi_hal_i2c_release(&furi_hal_i2c_handle_power); +#ifdef FURI_HAL_OS_DEBUG + furi_hal_gpio_init_simple(&gpio_ext_pb2, GpioModeOutputPushPull); + furi_hal_gpio_init_simple(&gpio_ext_pc3, GpioModeOutputPushPull); +#endif + FURI_LOG_I(TAG, "Init OK"); } @@ -133,7 +139,18 @@ bool furi_hal_power_sleep_available() { } bool furi_hal_power_deep_sleep_available() { - return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; + for(int32_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { + if(NVIC_GetPendingIRQ(i)) { + FURI_LOG_D("DS", "%d", i); + return false; + } + } + + if(!furi_hal_bt_is_alive() || furi_hal_power.deep_insomnia > 0) { + return false; + } + + return true; } void furi_hal_power_light_sleep() { @@ -162,6 +179,8 @@ void furi_hal_power_deep_sleep() { /* Release RCC semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); + LL_USART_Disable(USART1); + // Prepare deep sleep LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); LL_LPM_EnableDeepSleep(); @@ -173,6 +192,8 @@ void furi_hal_power_deep_sleep() { __WFI(); + LL_USART_Enable(USART1); + /* Release ENTRY_STOP_MODE semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); @@ -188,9 +209,25 @@ void furi_hal_power_deep_sleep() { void furi_hal_power_sleep() { if(furi_hal_power_deep_sleep_available()) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_gpio_write(&gpio_ext_pc3, 1); +#endif + furi_hal_power_deep_sleep(); + +#ifdef FURI_HAL_OS_DEBUG + furi_hal_gpio_write(&gpio_ext_pc3, 0); +#endif } else { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_gpio_write(&gpio_ext_pb2, 1); +#endif + furi_hal_power_light_sleep(); + +#ifdef FURI_HAL_OS_DEBUG + furi_hal_gpio_write(&gpio_ext_pb2, 0); +#endif } } diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 901955856c7..0a60bb814d2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -93,14 +93,14 @@ void furi_hal_resources_init() { } // External header pins - furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + // furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow); // Display pins furi_hal_gpio_init(&gpio_display_rst, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); diff --git a/firmware/targets/f7/furi_hal/furi_hal_spi.c b/firmware/targets/f7/furi_hal/furi_hal_spi.c index d74a394a7cc..01cb3ae68d1 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_spi.c +++ b/firmware/targets/f7/furi_hal/furi_hal_spi.c @@ -1,5 +1,6 @@ #include "furi_hal_spi.h" #include "furi_hal_resources.h" +#include #include #include @@ -55,6 +56,8 @@ void furi_hal_spi_bus_handle_deinit(FuriHalSpiBusHandle* handle) { void furi_hal_spi_acquire(FuriHalSpiBusHandle* handle) { furi_assert(handle); + furi_hal_power_insomnia_enter(); + handle->bus->callback(handle->bus, FuriHalSpiBusEventLock); handle->bus->callback(handle->bus, FuriHalSpiBusEventActivate); @@ -75,6 +78,8 @@ void furi_hal_spi_release(FuriHalSpiBusHandle* handle) { // Bus events handle->bus->callback(handle->bus, FuriHalSpiBusEventDeactivate); handle->bus->callback(handle->bus, FuriHalSpiBusEventUnlock); + + furi_hal_power_insomnia_exit(); } static void furi_hal_spi_bus_end_txrx(FuriHalSpiBusHandle* handle, uint32_t timeout) { From 3acb21b756ead6ef96c87513b85f852e7bfbf417 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 21 Apr 2022 23:51:47 +0300 Subject: [PATCH 04/37] Remove IDLE interrupt --- firmware/targets/f7/furi_hal/furi_hal_uart.c | 13 ++----------- firmware/targets/f7/furi_hal/furi_hal_uart.h | 2 -- 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.c b/firmware/targets/f7/furi_hal/furi_hal_uart.c index ee7172fb14d..74b14f4fdbe 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.c +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.c @@ -46,7 +46,6 @@ static void furi_hal_usart_init(uint32_t baud) { ; LL_USART_EnableIT_RXNE_RXFNE(USART1); - LL_USART_EnableIT_IDLE(USART1); NVIC_SetPriority(USART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); } @@ -83,7 +82,6 @@ static void furi_hal_lpuart_init(uint32_t baud) { furi_hal_uart_set_br(FuriHalUartIdLPUART1, baud); LL_LPUART_EnableIT_RXNE_RXFNE(LPUART1); - LL_LPUART_EnableIT_IDLE(LPUART1); NVIC_SetPriority(LPUART1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); } @@ -141,11 +139,9 @@ void furi_hal_uart_deinit(FuriHalUartId ch) { void furi_hal_uart_suspend(FuriHalUartId channel) { if(channel == FuriHalUartIdLPUART1 && LL_LPUART_IsEnabled(LPUART1)) { LL_LPUART_Disable(LPUART1); - NVIC_ClearPendingIRQ(LPUART1_IRQn); furi_hal_usart_prev_enabled[channel] = true; } else if(channel == FuriHalUartIdUSART1 && LL_USART_IsEnabled(USART1)) { LL_USART_Disable(USART1); - NVIC_ClearPendingIRQ(USART1_IRQn); furi_hal_usart_prev_enabled[channel] = true; } } @@ -158,6 +154,8 @@ void furi_hal_uart_resume(FuriHalUartId channel) { } else if(channel == FuriHalUartIdUSART1) { LL_USART_Enable(USART1); } + + furi_hal_usart_prev_enabled[channel] = false; } void furi_hal_uart_tx(FuriHalUartId ch, uint8_t* buffer, size_t buffer_size) { @@ -213,22 +211,15 @@ void LPUART1_IRQHandler(void) { if(LL_LPUART_IsActiveFlag_RXNE_RXFNE(LPUART1)) { uint8_t data = LL_LPUART_ReceiveData8(LPUART1); irq_cb[FuriHalUartIdLPUART1](UartIrqEventRXNE, data, irq_ctx[FuriHalUartIdLPUART1]); - } else if(LL_LPUART_IsActiveFlag_IDLE(LPUART1)) { - irq_cb[FuriHalUartIdLPUART1](UartIrqEventIDLE, 0, irq_ctx[FuriHalUartIdLPUART1]); - LL_LPUART_ClearFlag_IDLE(LPUART1); } else if(LL_LPUART_IsActiveFlag_ORE(LPUART1)) { LL_LPUART_ClearFlag_ORE(LPUART1); } - //TODO: more events } void USART1_IRQHandler(void) { if(LL_USART_IsActiveFlag_RXNE_RXFNE(USART1)) { uint8_t data = LL_USART_ReceiveData8(USART1); irq_cb[FuriHalUartIdUSART1](UartIrqEventRXNE, data, irq_ctx[FuriHalUartIdUSART1]); - } else if(LL_USART_IsActiveFlag_IDLE(USART1)) { - irq_cb[FuriHalUartIdUSART1](UartIrqEventIDLE, 0, irq_ctx[FuriHalUartIdUSART1]); - LL_USART_ClearFlag_IDLE(USART1); } else if(LL_USART_IsActiveFlag_ORE(USART1)) { LL_USART_ClearFlag_ORE(USART1); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_uart.h b/firmware/targets/f7/furi_hal/furi_hal_uart.h index 78b9c0718a7..07211db8bc2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_uart.h +++ b/firmware/targets/f7/furi_hal/furi_hal_uart.h @@ -27,8 +27,6 @@ typedef enum { */ typedef enum { UartIrqEventRXNE, - UartIrqEventIDLE, - //TODO: more events } UartIrqEvent; /** From dc8346b77507ba94bd95025849cc1ab6fdea57d1 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 22 Apr 2022 01:02:39 +0300 Subject: [PATCH 05/37] FuriHal: add FPU isr and disable all FPU interrupt, add core2 stop mode configuration on deep sleep --- .../targets/f7/furi_hal/furi_hal_interrupt.c | 76 +++++++++++-------- firmware/targets/f7/furi_hal/furi_hal_power.c | 5 +- 2 files changed, 46 insertions(+), 35 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index d122fbc73e5..20dfaf26a78 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -82,6 +82,16 @@ void furi_hal_interrupt_init() { NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); + NVIC_SetPriority(FPU_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); + NVIC_EnableIRQ(FPU_IRQn); + + LL_SYSCFG_DisableIT_FPU_IOC(); + LL_SYSCFG_DisableIT_FPU_DZC(); + LL_SYSCFG_DisableIT_FPU_UFC(); + LL_SYSCFG_DisableIT_FPU_OFC(); + LL_SYSCFG_DisableIT_FPU_IDC(); + LL_SYSCFG_DisableIT_FPU_IXC(); + FURI_LOG_I(TAG, "Init OK"); } @@ -120,86 +130,86 @@ void furi_hal_interrupt_set_isr_ex( } /* Timer 2 */ -void TIM2_IRQHandler(void) { +void TIM2_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdTIM2); } /* Timer 1 Update */ -void TIM1_UP_TIM16_IRQHandler(void) { +void TIM1_UP_TIM16_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdTim1UpTim16); } -void TIM1_TRG_COM_TIM17_IRQHandler(void) { +void TIM1_TRG_COM_TIM17_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdTim1TrgComTim17); } -void TIM1_CC_IRQHandler(void) { +void TIM1_CC_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdTim1Cc); } /* DMA 1 */ -void DMA1_Channel1_IRQHandler(void) { +void DMA1_Channel1_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch1); } -void DMA1_Channel2_IRQHandler(void) { +void DMA1_Channel2_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch2); } -void DMA1_Channel3_IRQHandler(void) { +void DMA1_Channel3_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch3); } -void DMA1_Channel4_IRQHandler(void) { +void DMA1_Channel4_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch4); } -void DMA1_Channel5_IRQHandler(void) { +void DMA1_Channel5_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch5); } -void DMA1_Channel6_IRQHandler(void) { +void DMA1_Channel6_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch6); } -void DMA1_Channel7_IRQHandler(void) { +void DMA1_Channel7_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch7); } /* DMA 2 */ -void DMA2_Channel1_IRQHandler(void) { +void DMA2_Channel1_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch1); } -void DMA2_Channel2_IRQHandler(void) { +void DMA2_Channel2_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch2); } -void DMA2_Channel3_IRQHandler(void) { +void DMA2_Channel3_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch3); } -void DMA2_Channel4_IRQHandler(void) { +void DMA2_Channel4_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch4); } -void DMA2_Channel5_IRQHandler(void) { +void DMA2_Channel5_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch5); } -void DMA2_Channel6_IRQHandler(void) { +void DMA2_Channel6_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch6); } -void DMA2_Channel7_IRQHandler(void) { +void DMA2_Channel7_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch7); } -void HSEM_IRQHandler(void) { +void HSEM_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdHsem); } -void TAMP_STAMP_LSECSS_IRQHandler(void) { +void TAMP_STAMP_LSECSS_IRQHandler() { if(LL_RCC_IsActiveFlag_LSECSS()) { LL_RCC_ClearFlag_LSECSS(); if(!LL_RCC_LSE_IsReady()) { @@ -211,11 +221,11 @@ void TAMP_STAMP_LSECSS_IRQHandler(void) { } } -void RCC_IRQHandler(void) { +void RCC_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdRcc); } -void NMI_Handler(void) { +void NMI_Handler() { if(LL_RCC_IsActiveFlag_HSECSS()) { LL_RCC_ClearFlag_HSECSS(); FURI_LOG_E(TAG, "HSE CSS fired: resetting system"); @@ -223,23 +233,23 @@ void NMI_Handler(void) { } } -void HardFault_Handler(void) { +void HardFault_Handler() { furi_crash("HardFault"); } -void MemManage_Handler(void) { +void MemManage_Handler() { furi_crash("MemManage"); } -void BusFault_Handler(void) { +void BusFault_Handler() { furi_crash("BusFault"); } -void UsageFault_Handler(void) { +void UsageFault_Handler() { furi_crash("UsageFault"); } -void DebugMon_Handler(void) { +void DebugMon_Handler() { } #include "usbd_core.h" @@ -249,20 +259,24 @@ extern usbd_device udev; extern void HW_IPCC_Tx_Handler(); extern void HW_IPCC_Rx_Handler(); -void SysTick_Handler(void) { +void SysTick_Handler() { furi_hal_os_tick(); } -void USB_LP_IRQHandler(void) { +void USB_LP_IRQHandler() { #ifndef FURI_RAM_EXEC usbd_poll(&udev); #endif } -void IPCC_C1_TX_IRQHandler(void) { +void IPCC_C1_TX_IRQHandler() { HW_IPCC_Tx_Handler(); } -void IPCC_C1_RX_IRQHandler(void) { +void IPCC_C1_RX_IRQHandler() { HW_IPCC_Rx_Handler(); } + +void FPU_IRQHandler() { + furi_crash("FpuFault"); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index faceb534314..ae682262614 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -179,10 +179,9 @@ void furi_hal_power_deep_sleep() { /* Release RCC semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); - LL_USART_Disable(USART1); - // Prepare deep sleep LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP1); LL_LPM_EnableDeepSleep(); #if defined(__CC_ARM) @@ -192,8 +191,6 @@ void furi_hal_power_deep_sleep() { __WFI(); - LL_USART_Enable(USART1); - /* Release ENTRY_STOP_MODE semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); From 14be76ce57f2f4e93366e48c15930b22a21bc378 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 22 Apr 2022 01:39:27 +0300 Subject: [PATCH 06/37] FuriHal: tie stop mode debug with debug rtc flag --- firmware/targets/f7/furi_hal/furi_hal.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index 48669c78cc9..939f8d594e6 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -21,9 +21,15 @@ void furi_hal_init_early() { furi_hal_rtc_init_early(); - LL_DBGMCU_EnableDBGSleepMode(); - LL_DBGMCU_EnableDBGStopMode(); - LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + LL_DBGMCU_EnableDBGSleepMode(); + LL_DBGMCU_EnableDBGStopMode(); + LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + }else { + LL_DBGMCU_DisableDBGSleepMode(); + LL_DBGMCU_DisableDBGStopMode(); + LL_DBGMCU_DisableDBGStandbyMode(); + } } void furi_hal_deinit_early() { From 9e3f6de962e7e4f05acd227c64fd991e160ceadb Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 22 Apr 2022 11:44:58 +0300 Subject: [PATCH 07/37] FuriHal: adjust flash latency on clock switch, tie mcu debug with RTC debug flag --- firmware/targets/f7/furi_hal/furi_hal.c | 10 --------- firmware/targets/f7/furi_hal/furi_hal_clock.c | 4 ++++ firmware/targets/f7/furi_hal/furi_hal_power.c | 2 +- firmware/targets/f7/furi_hal/furi_hal_rtc.c | 22 +++++++++++++++++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index 939f8d594e6..b3362ba88ea 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -20,16 +20,6 @@ void furi_hal_init_early() { furi_hal_light_init(); furi_hal_rtc_init_early(); - - if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - LL_DBGMCU_EnableDBGSleepMode(); - LL_DBGMCU_EnableDBGStopMode(); - LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); - }else { - LL_DBGMCU_DisableDBGSleepMode(); - LL_DBGMCU_DisableDBGStopMode(); - LL_DBGMCU_DisableDBGStandbyMode(); - } } void furi_hal_deinit_early() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 0226442204a..09efe76dd13 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -204,6 +204,8 @@ void furi_hal_clock_switch_to_hsi() { while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) ; + + LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); } void furi_hal_clock_switch_to_pll() { @@ -215,6 +217,8 @@ void furi_hal_clock_switch_to_pll() { while(!LL_RCC_PLL_IsReady()) ; + LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); + LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index ae682262614..1c58056308d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -162,7 +162,7 @@ void furi_hal_power_deep_sleep() { ; if(!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) { - if(LL_PWR_IsActiveFlag_C2DS()) { + if(LL_PWR_IsActiveFlag_C2DS() || LL_PWR_IsActiveFlag_C2SB()) { // Release ENTRY_STOP_MODE semaphore LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 748d7e41c28..3a09803c9cf 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -74,6 +74,16 @@ void furi_hal_rtc_init_early() { data->version = FURI_HAL_RTC_HEADER_VERSION; furi_hal_rtc_set_register(FuriHalRtcRegisterHeader, data_reg); } + + if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { + LL_DBGMCU_EnableDBGSleepMode(); + LL_DBGMCU_EnableDBGStopMode(); + LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + } else { + LL_DBGMCU_DisableDBGSleepMode(); + LL_DBGMCU_DisableDBGStopMode(); + LL_DBGMCU_DisableDBGStandbyMode(); + } } void furi_hal_rtc_deinit_early() { @@ -126,6 +136,12 @@ void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) { DeveloperReg* data = (DeveloperReg*)&data_reg; data->flags |= flag; furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); + + if(flag & FuriHalRtcFlagDebug) { + LL_DBGMCU_EnableDBGSleepMode(); + LL_DBGMCU_EnableDBGStopMode(); + LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + } } void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) { @@ -133,6 +149,12 @@ void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) { DeveloperReg* data = (DeveloperReg*)&data_reg; data->flags &= ~flag; furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); + + if(flag & FuriHalRtcFlagDebug) { + LL_DBGMCU_DisableDBGSleepMode(); + LL_DBGMCU_DisableDBGStopMode(); + LL_DBGMCU_DisableDBGStandbyMode(); + } } bool furi_hal_rtc_is_flag_set(FuriHalRtcFlag flag) { From 01ea3e38eb785b7708e83f87b02ec574ca8726b9 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 22 Apr 2022 12:16:31 +0300 Subject: [PATCH 08/37] FuriHal: move resource init to early stage --- firmware/targets/f7/furi_hal/furi_hal.c | 4 ++-- .../targets/f7/furi_hal/furi_hal_resources.c | 20 +++++++++---------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal.c b/firmware/targets/f7/furi_hal/furi_hal.c index b3362ba88ea..00ddbc64cc8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal.c +++ b/firmware/targets/f7/furi_hal/furi_hal.c @@ -10,10 +10,10 @@ void furi_hal_init_early() { furi_hal_clock_init_early(); furi_hal_delay_init(); - furi_hal_os_init(); - furi_hal_resources_init_early(); + furi_hal_os_init(); + furi_hal_spi_init_early(); furi_hal_i2c_init_early(); diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 0a60bb814d2..35dbce8edec 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -80,6 +80,16 @@ void furi_hal_resources_init_early() { furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeOutputOpenDrain); furi_hal_gpio_write(&gpio_usb_dm, 0); furi_hal_gpio_write(&gpio_usb_dp, 0); + + // External header pins + furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow); } void furi_hal_resources_deinit_early() { @@ -92,16 +102,6 @@ void furi_hal_resources_init() { input_pins[i].gpio, GpioModeInterruptRiseFall, GpioPullUp, GpioSpeedLow); } - // External header pins - // furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pc3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pb2, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pb3, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pa4, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pa6, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullNo, GpioSpeedLow); - // Display pins furi_hal_gpio_init(&gpio_display_rst, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_display_rst, 0); From 656339210e4907af93ec165e94c4c19571c475dc Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 22 Apr 2022 17:45:32 +0300 Subject: [PATCH 09/37] Add EXTI pending check, enable debug traps with compile-time flag --- firmware/targets/f7/furi_hal/furi_hal_os.c | 17 ------- firmware/targets/f7/furi_hal/furi_hal_power.c | 45 +++++++++++++++++-- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 9380dbf2ec4..e7ad91b883b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -23,12 +23,6 @@ #define FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH (FURI_HAL_OS_IDLE_CNT_TO_TICKS(FURI_HAL_IDLE_TIMER_MAX)) #define FURI_HAL_OS_MAX_SLEEP (FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH - 1) -#define FURI_HAL_OS_EXTI_IRQ_MASK_0 \ - ((1 << EXTI0_IRQn) | (1 << EXTI1_IRQn) | (1 << EXTI2_IRQn) | (1 << EXTI3_IRQn) | \ - (1 << EXTI4_IRQn) | (1 << EXTI9_5_IRQn)) -#define FURI_HAL_OS_EXTI_IRQ_MASK_1 ((1 << (EXTI15_10_IRQn - 32))) -#define FURI_HAL_OS_IPCC_IRQ_MASK_1 ((1 << (IPCC_C1_TX_IRQn - 32)) | (1 << (IPCC_C1_TX_IRQn - 32))) - #ifdef FURI_HAL_OS_DEBUG #include @@ -78,13 +72,6 @@ static inline void furi_hal_os_resume_aux_periphs() { // Re-enable USB } -static inline bool furi_hal_os_is_bad_interrupt_pending() { - // Only EXTI and IPCC interrupts are allowed in sleep mode - return (NVIC->ICPR[0] & ~FURI_HAL_OS_EXTI_IRQ_MASK_0) || - (NVIC->ICPR[1] & ~FURI_HAL_OS_EXTI_IRQ_MASK_1) || - (NVIC->ICPR[1] & ~FURI_HAL_OS_IPCC_IRQ_MASK_1); -} - static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Stop ticks furi_hal_clock_suspend_tick(); @@ -142,10 +129,6 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { return; } - // if(furi_hal_os_is_bad_interrupt_pending()) { - // furi_crash("Bad interrupt pending before sleep"); - // } - // Sleep and track how much ticks we spent sleeping uint32_t completed_ticks = furi_hal_os_sleep(expected_idle_ticks); // Notify system about time spent in sleep diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 1c58056308d..fa5b18a7585 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -17,6 +17,9 @@ #include #define TAG "FuriHalPower" +#define FURI_HAL_POWER_NVIC_IS_PENDING() (NVIC->ISPR[0] || NVIC->ISPR[1]) +#define FURI_HAL_POWER_EXTI_LINE_0_31 0 +#define FURI_HAL_POWER_EXTI_LINE_32_63 1 typedef struct { volatile uint8_t insomnia; @@ -138,13 +141,49 @@ bool furi_hal_power_sleep_available() { return furi_hal_power.insomnia == 0; } -bool furi_hal_power_deep_sleep_available() { +// Find out the IRQ number while debugging +static void furi_hal_power_nvic_dbg_trap() { for(int32_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { if(NVIC_GetPendingIRQ(i)) { - FURI_LOG_D("DS", "%d", i); - return false; + (void)i; + // Break here + __NOP(); + } + } +} + +// Find out the EXTI line number while debugging +static void furi_hal_power_exti_dbg_trap(uint32_t exti, uint32_t val) { + for(uint32_t i = 0; val; val >>= 1U, ++i) { + if(val & 1U) { + (void)exti; + (void)i; + // Break here + __NOP(); } } +} + +bool furi_hal_power_deep_sleep_available() { + if(FURI_HAL_POWER_NVIC_IS_PENDING()) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_power_nvic_dbg_trap(); +#endif + return false; + } + + uint32_t exti_lines_active; + if((exti_lines_active = LL_EXTI_ReadFlag_0_31(LL_EXTI_LINE_ALL_0_31))) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_power_exti_dbg_trap(FURI_HAL_POWER_EXTI_LINE_0_31, exti_lines_active); +#endif + return false; + } else if((exti_lines_active = LL_EXTI_ReadFlag_32_63(LL_EXTI_LINE_ALL_32_63))) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_power_exti_dbg_trap(FURI_HAL_POWER_EXTI_LINE_32_63, exti_lines_active); +#endif + return false; + } if(!furi_hal_bt_is_alive() || furi_hal_power.deep_insomnia > 0) { return false; From 5c37066447d662a92cdadedd4bc79e70de20e63a Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 22 Apr 2022 18:01:16 +0300 Subject: [PATCH 10/37] Wrap sleep debug functions in conditional compilation --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 +++ firmware/targets/f7/furi_hal/furi_hal_power.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 09efe76dd13..f0c5af6916e 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -180,6 +180,9 @@ void furi_hal_clock_init() { // APB1 GRP2 LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); + // APB1 GRP2 Sleep modes + LL_APB1_GRP2_EnableClockSleep(LL_APB1_GRP2_PERIPH_LPUART1); + LL_APB1_GRP2_EnableClockSleep(LL_APB1_GRP2_PERIPH_LPTIM2); // APB2 // LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index fa5b18a7585..dc4d2dfc9fa 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -141,6 +141,7 @@ bool furi_hal_power_sleep_available() { return furi_hal_power.insomnia == 0; } +#ifdef FURI_HAL_OS_DEBUG // Find out the IRQ number while debugging static void furi_hal_power_nvic_dbg_trap() { for(int32_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { @@ -163,6 +164,7 @@ static void furi_hal_power_exti_dbg_trap(uint32_t exti, uint32_t val) { } } } +#endif bool furi_hal_power_deep_sleep_available() { if(FURI_HAL_POWER_NVIC_IS_PENDING()) { From 07057667ab1a8e65a596ea8172b8f6236d775113 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 22 Apr 2022 18:19:25 +0300 Subject: [PATCH 11/37] Remove erroneous changed --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index f0c5af6916e..09efe76dd13 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -180,9 +180,6 @@ void furi_hal_clock_init() { // APB1 GRP2 LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1); - // APB1 GRP2 Sleep modes - LL_APB1_GRP2_EnableClockSleep(LL_APB1_GRP2_PERIPH_LPUART1); - LL_APB1_GRP2_EnableClockSleep(LL_APB1_GRP2_PERIPH_LPTIM2); // APB2 // LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC); From b5bee827488efc9e6b43b22036ea3429be062b28 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 22 Apr 2022 18:58:43 +0300 Subject: [PATCH 12/37] Do not use CSS, remove it from everywhere --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 --- .../targets/f7/furi_hal/furi_hal_interrupt.c | 21 ------------------- firmware/targets/f7/furi_hal/furi_hal_power.c | 5 ----- firmware/targets/f7/furi_hal/furi_hal_rtc.c | 3 --- 4 files changed, 32 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 09efe76dd13..72fbd8af012 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -62,7 +62,6 @@ void furi_hal_clock_init() { LL_RCC_HSI_Enable(); while(!HS_CLOCK_IS_READY()) ; - LL_RCC_HSE_EnableCSS(); /* LSE and LSI1 configuration and activation */ LL_PWR_EnableBkUpAccess(); @@ -74,8 +73,6 @@ void furi_hal_clock_init() { LL_EXTI_EnableIT_0_31( LL_EXTI_LINE_18); /* Why? Because that's why. See RM0434, Table 61. CPU1 vector table. */ LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_18); - LL_RCC_EnableIT_LSECSS(); - LL_RCC_LSE_EnableCSS(); /* Main PLL configuration and activation */ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLR_DIV_2); diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 20dfaf26a78..336fb524416 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -76,10 +76,6 @@ __attribute__((always_inline)) static inline void } void furi_hal_interrupt_init() { - NVIC_SetPriority( - TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); - NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); - NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); NVIC_SetPriority(FPU_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); @@ -209,28 +205,11 @@ void HSEM_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdHsem); } -void TAMP_STAMP_LSECSS_IRQHandler() { - if(LL_RCC_IsActiveFlag_LSECSS()) { - LL_RCC_ClearFlag_LSECSS(); - if(!LL_RCC_LSE_IsReady()) { - FURI_LOG_E(TAG, "LSE CSS fired: resetting system"); - NVIC_SystemReset(); - } else { - FURI_LOG_E(TAG, "LSE CSS fired: but LSE is alive"); - } - } -} - void RCC_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdRcc); } void NMI_Handler() { - if(LL_RCC_IsActiveFlag_HSECSS()) { - LL_RCC_ClearFlag_HSECSS(); - FURI_LOG_E(TAG, "HSE CSS fired: resetting system"); - NVIC_SystemReset(); - } } void HardFault_Handler() { diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index dc4d2dfc9fa..3d75adc2e7d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -74,11 +74,6 @@ const ParamCEDV cedv = { .DOD100 = 3299, }; -void HAL_RCC_CSSCallback(void) { - // TODO: notify user about issue with HSE - furi_hal_power_reset(); -} - void furi_hal_power_init() { LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1); LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN); diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index 3a09803c9cf..d066c3b932d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -36,7 +36,6 @@ void furi_hal_rtc_init_early() { // LSE and RTC LL_PWR_EnableBkUpAccess(); if(!RTC_CLOCK_IS_READY()) { - // Start LSI1 needed for CSS LL_RCC_LSI1_Enable(); // Try to start LSE normal way LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH); @@ -55,8 +54,6 @@ void furi_hal_rtc_init_early() { } // Set RTC domain clock to LSE LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); - // Enable LSE CSS - LL_RCC_LSE_EnableCSS(); } // Enable clocking LL_RCC_EnableRTC(); From 82677e6a6de61f87561c12c9f532c14a3d02b206 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Fri, 22 Apr 2022 20:07:58 +0300 Subject: [PATCH 13/37] Enable/disable USB on VBUS connect (prototype) --- applications/power/power_service/power.c | 24 ++++++++++++++++++++- applications/power/power_service/power_i.h | 1 + firmware/targets/f7/furi_hal/furi_hal_usb.c | 18 ++++++++++------ 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index 5f7eeb84713..e41c14a9877 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -5,8 +5,11 @@ #include #include #include +#include #define POWER_OFF_TIMEOUT 90 +#define VBUS_MIN_VOLTAGE 4.0f +#define VBUS_CHANGE_THRESHOLD 2.0f void power_draw_battery_callback(Canvas* canvas, void* context) { furi_assert(context); @@ -151,7 +154,7 @@ static void power_check_low_battery(Power* power) { } // Check battery charge and vbus voltage - if((power->info.charge == 0) && (power->info.voltage_vbus < 4.0f) && + if((power->info.charge == 0) && (power->info.voltage_vbus < VBUS_MIN_VOLTAGE) && power->show_low_bat_level_message) { if(!power->battery_low) { view_dispatcher_send_to_front(power->view_dispatcher); @@ -184,6 +187,22 @@ static void power_check_battery_level_change(Power* power) { } } +static void power_check_vbus_level_change(Power* power) { + if(fabsf(power->voltage_vbus - power->info.voltage_vbus) + >= VBUS_CHANGE_THRESHOLD) { + power->voltage_vbus = power->info.voltage_vbus; + if(power->voltage_vbus >= VBUS_MIN_VOLTAGE) { + furi_hal_power_insomnia_enter(); +// furi_hal_usb_enable(); + FURI_LOG_D("VBUS", "VBUS connected: %f v", power->voltage_vbus); + } else { +// furi_hal_usb_disable(); + furi_hal_power_insomnia_exit(); + FURI_LOG_D("VBUS", "VBUS disconnected: %f v", power->voltage_vbus); + } + } +} + int32_t power_srv(void* p) { (void)p; Power* power = power_alloc(); @@ -203,6 +222,9 @@ int32_t power_srv(void* p) { // Check and notify about battery level change power_check_battery_level_change(power); + // Check and notify about vbus level change + power_check_vbus_level_change(power); + // Update battery view port if(need_refresh) view_port_update(power->battery_view_port); diff --git a/applications/power/power_service/power_i.h b/applications/power/power_service/power_i.h index f88b8f24b4b..b43054f00cd 100755 --- a/applications/power/power_service/power_i.h +++ b/applications/power/power_service/power_i.h @@ -37,6 +37,7 @@ struct Power { bool show_low_bat_level_message; uint8_t battery_level; uint8_t power_off_timeout; + float voltage_vbus; osMutexId_t api_mtx; }; diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index f1044c36bba..787f567c813 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -67,7 +67,6 @@ void furi_hal_usb_init(void) { LL_GPIO_Init(GPIOA, &GPIO_InitStruct); usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf)); - usbd_enable(&udev, true); usbd_reg_descr(&udev, usb_descriptor_get); usbd_reg_event(&udev, usbd_evt_susp, susp_evt); @@ -199,7 +198,7 @@ static void susp_evt(usbd_device* dev, uint8_t event, uint8_t ep) { usb.connected = false; usb.if_cur->suspend(&udev); - furi_hal_power_insomnia_exit(); +// furi_hal_power_insomnia_exit(); } if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventSuspend, usb.cb_ctx); @@ -211,7 +210,7 @@ static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep) { usb.connected = true; usb.if_cur->wakeup(&udev); - furi_hal_power_insomnia_enter(); +// furi_hal_power_insomnia_enter(); } if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventWakeup, usb.cb_ctx); @@ -264,16 +263,22 @@ static int32_t furi_hal_usb_thread(void* context) { usb.if_cur->deinit(&udev); } if(if_new != NULL) { - if_new->init(&udev, if_new, if_ctx_new); + if(usb.if_cur != NULL) { + // Previous interface was already configured + if_new->init(&udev, if_new, if_ctx_new); + usb.enabled = true; + } usbd_reg_event(&udev, usbd_evt_reset, reset_evt); FURI_LOG_I(TAG, "USB Mode change done"); - usb.enabled = true; } usb.if_cur = if_new; } if(flags & EventEnable) { if((!usb.enabled) && (usb.if_cur != NULL)) { - usbd_connect(&udev, true); + usbd_enable(&udev, true); + FURI_LOG_D(TAG, "No delay"); + osDelay(USB_RECONNECT_DELAY); + usb.if_cur->init(&udev, usb.if_cur, usb.if_ctx); usb.enabled = true; FURI_LOG_I(TAG, "USB Enable"); } @@ -282,6 +287,7 @@ static int32_t furi_hal_usb_thread(void* context) { if(usb.enabled) { susp_evt(&udev, 0, 0); usbd_connect(&udev, false); + usbd_enable(&udev, false); usb.enabled = false; usb_request_pending = false; FURI_LOG_I(TAG, "USB Disable"); From 1abeed8c1627dcfd03411da5086744b21a52d9ca Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Mon, 25 Apr 2022 21:07:32 +0300 Subject: [PATCH 14/37] FuriHal: add LPMS and DEEPSLEEP magic, workaround state inconsistency between cores --- applications/loader/loader.c | 4 ++-- applications/power/power_service/power.c | 7 +++---- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 +++ firmware/targets/f7/furi_hal/furi_hal_power.c | 9 +++++++-- firmware/targets/f7/furi_hal/furi_hal_usb.c | 4 ++-- 5 files changed, 17 insertions(+), 10 deletions(-) diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 2c1467ddba9..3882647efdb 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -238,7 +238,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con if(thread_state == FuriThreadStateRunning) { event.type = LoaderEventTypeApplicationStarted; furi_pubsub_publish(loader_instance->pubsub, &event); - // furi_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); } else if(thread_state == FuriThreadStateStopped) { FURI_LOG_I( TAG, @@ -251,7 +251,7 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con loader_instance->application_arguments = NULL; } - // furi_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); loader_unlock(instance); event.type = LoaderEventTypeApplicationStopped; diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index e41c14a9877..eb7c63cd8f3 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -188,15 +188,14 @@ static void power_check_battery_level_change(Power* power) { } static void power_check_vbus_level_change(Power* power) { - if(fabsf(power->voltage_vbus - power->info.voltage_vbus) - >= VBUS_CHANGE_THRESHOLD) { + if(fabsf(power->voltage_vbus - power->info.voltage_vbus) >= VBUS_CHANGE_THRESHOLD) { power->voltage_vbus = power->info.voltage_vbus; if(power->voltage_vbus >= VBUS_MIN_VOLTAGE) { furi_hal_power_insomnia_enter(); -// furi_hal_usb_enable(); + // furi_hal_usb_enable(); FURI_LOG_D("VBUS", "VBUS connected: %f v", power->voltage_vbus); } else { -// furi_hal_usb_disable(); + // furi_hal_usb_disable(); furi_hal_power_insomnia_exit(); FURI_LOG_D("VBUS", "VBUS disconnected: %f v", power->voltage_vbus); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index 72fbd8af012..ea60388cad7 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -202,6 +202,8 @@ void furi_hal_clock_switch_to_hsi() { while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) ; + LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); + LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); } @@ -216,6 +218,7 @@ void furi_hal_clock_switch_to_pll() { LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); + LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 3d75adc2e7d..8b77434b576 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -143,7 +143,7 @@ static void furi_hal_power_nvic_dbg_trap() { if(NVIC_GetPendingIRQ(i)) { (void)i; // Break here - __NOP(); + asm volatile("bkpt 0"); } } } @@ -155,7 +155,7 @@ static void furi_hal_power_exti_dbg_trap(uint32_t exti, uint32_t val) { (void)exti; (void)i; // Break here - __NOP(); + asm volatile("bkpt 0"); } } } @@ -217,6 +217,7 @@ void furi_hal_power_deep_sleep() { // Prepare deep sleep LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); + uint32_t c2_lpms = LL_C2_PWR_GetPowerMode(); LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP1); LL_LPM_EnableDeepSleep(); @@ -227,6 +228,10 @@ void furi_hal_power_deep_sleep() { __WFI(); + LL_LPM_EnableSleep(); + + LL_C2_PWR_SetPowerMode(c2_lpms); + /* Release ENTRY_STOP_MODE semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index 787f567c813..1af2941c600 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -198,7 +198,7 @@ static void susp_evt(usbd_device* dev, uint8_t event, uint8_t ep) { usb.connected = false; usb.if_cur->suspend(&udev); -// furi_hal_power_insomnia_exit(); + // furi_hal_power_insomnia_exit(); } if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventSuspend, usb.cb_ctx); @@ -210,7 +210,7 @@ static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep) { usb.connected = true; usb.if_cur->wakeup(&udev); -// furi_hal_power_insomnia_enter(); + // furi_hal_power_insomnia_enter(); } if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventWakeup, usb.cb_ctx); From 80a0014e70e472df72a439af8d7499f62bc62756 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Mon, 25 Apr 2022 21:52:38 +0300 Subject: [PATCH 15/37] FuriHal: honor c1 LMPS --- firmware/targets/f7/furi_hal/furi_hal_power.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 8b77434b576..2d36b21674b 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -216,8 +216,9 @@ void furi_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); // Prepare deep sleep - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); + uint32_t c1_lpms = LL_PWR_GetPowerMode(); uint32_t c2_lpms = LL_C2_PWR_GetPowerMode(); + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP1); LL_LPM_EnableDeepSleep(); @@ -230,6 +231,7 @@ void furi_hal_power_deep_sleep() { LL_LPM_EnableSleep(); + LL_PWR_SetPowerMode(c1_lpms); LL_C2_PWR_SetPowerMode(c2_lpms); /* Release ENTRY_STOP_MODE semaphore */ From 2d8827b4ee2a708e45fd6d103f8be39b050c7415 Mon Sep 17 00:00:00 2001 From: nminaylov Date: Mon, 25 Apr 2022 22:52:12 +0300 Subject: [PATCH 16/37] USB mode switch fix --- firmware/targets/f7/furi_hal/furi_hal_usb.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index 1af2941c600..575ba1e8ead 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -67,6 +67,7 @@ void furi_hal_usb_init(void) { LL_GPIO_Init(GPIOA, &GPIO_InitStruct); usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf)); + usbd_enable(&udev, false); usbd_reg_descr(&udev, usb_descriptor_get); usbd_reg_event(&udev, usbd_evt_susp, susp_evt); @@ -248,7 +249,6 @@ static int32_t furi_hal_usb_thread(void* context) { usbd_reg_event(&udev, usbd_evt_reset, NULL); FURI_LOG_I(TAG, "USB Reinit"); susp_evt(&udev, 0, 0); - usbd_connect(&udev, false); usb.enabled = false; usbd_enable(&udev, false); @@ -262,23 +262,22 @@ static int32_t furi_hal_usb_thread(void* context) { if(usb.if_cur != NULL) { usb.if_cur->deinit(&udev); } + usbd_enable(&udev, false); + usbd_enable(&udev, true); if(if_new != NULL) { - if(usb.if_cur != NULL) { - // Previous interface was already configured - if_new->init(&udev, if_new, if_ctx_new); - usb.enabled = true; - } + if_new->init(&udev, if_new, if_ctx_new); usbd_reg_event(&udev, usbd_evt_reset, reset_evt); FURI_LOG_I(TAG, "USB Mode change done"); + usb.enabled = true; } usb.if_cur = if_new; } if(flags & EventEnable) { if((!usb.enabled) && (usb.if_cur != NULL)) { usbd_enable(&udev, true); - FURI_LOG_D(TAG, "No delay"); - osDelay(USB_RECONNECT_DELAY); - usb.if_cur->init(&udev, usb.if_cur, usb.if_ctx); + if(usb.if_cur != NULL) { + usb.if_cur->init(&udev, if_new, if_ctx_new); + } usb.enabled = true; FURI_LOG_I(TAG, "USB Enable"); } From 1a5a2633a1cebf637f4dcd44befbcc7ed0286158 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Tue, 26 Apr 2022 01:41:38 +0300 Subject: [PATCH 17/37] Applications: add flags and insomnia bypass system --- applications/applications.c | 293 +++++++++++++++++++++++++++++------ applications/applications.h | 6 + applications/loader/loader.c | 9 +- 3 files changed, 256 insertions(+), 52 deletions(-) diff --git a/applications/applications.c b/applications/applications.c index 6b4c6321154..af81b8e3d9e 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -74,61 +74,113 @@ extern int32_t system_settings_app(void* p); const FlipperApplication FLIPPER_SERVICES[] = { /* Services */ #ifdef SRV_RPC - {.app = rpc_srv, .name = "RpcSrv", .stack_size = 1024 * 4, .icon = NULL}, + {.app = rpc_srv, + .name = "RpcSrv", + .stack_size = 1024 * 4, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_BT - {.app = bt_srv, .name = "BtSrv", .stack_size = 1024, .icon = NULL}, + {.app = bt_srv, + .name = "BtSrv", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_CLI - {.app = cli_srv, .name = "CliSrv", .stack_size = 4096, .icon = NULL}, + {.app = cli_srv, + .name = "CliSrv", + .stack_size = 4096, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_DIALOGS - {.app = dialogs_srv, .name = "DialogsSrv", .stack_size = 1024, .icon = NULL}, + {.app = dialogs_srv, + .name = "DialogsSrv", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_DOLPHIN - {.app = dolphin_srv, .name = "DolphinSrv", .stack_size = 1024, .icon = NULL}, + {.app = dolphin_srv, + .name = "DolphinSrv", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_DESKTOP #ifdef SRV_UPDATER #error SRV_UPDATER and SRV_DESKTOP are mutually exclusive! #endif - {.app = desktop_srv, .name = "DesktopSrv", .stack_size = 2048, .icon = NULL}, + {.app = desktop_srv, + .name = "DesktopSrv", + .stack_size = 2048, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_GUI - {.app = gui_srv, .name = "GuiSrv", .stack_size = 2048, .icon = NULL}, + {.app = gui_srv, + .name = "GuiSrv", + .stack_size = 2048, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_INPUT - {.app = input_srv, .name = "InputSrv", .stack_size = 1024, .icon = NULL}, + {.app = input_srv, + .name = "InputSrv", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_LOADER - {.app = loader_srv, .name = "LoaderSrv", .stack_size = 1024, .icon = NULL}, + {.app = loader_srv, + .name = "LoaderSrv", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_NOTIFICATION - {.app = notification_srv, .name = "NotificationSrv", .stack_size = 1536, .icon = NULL}, + {.app = notification_srv, + .name = "NotificationSrv", + .stack_size = 1536, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_POWER - {.app = power_srv, .name = "PowerSrv", .stack_size = 1024, .icon = NULL}, + {.app = power_srv, + .name = "PowerSrv", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_STORAGE - {.app = storage_srv, .name = "StorageSrv", .stack_size = 3072, .icon = NULL}, + {.app = storage_srv, + .name = "StorageSrv", + .stack_size = 3072, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_UPDATER #ifdef SRV_DESKTOP #error SRV_UPDATER and SRV_DESKTOP are mutually exclusive! #endif - {.app = updater_srv, .name = "UpdaterSrv", .stack_size = 2048, .icon = NULL}, + {.app = updater_srv, + .name = "UpdaterSrv", + .stack_size = 2048, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif }; @@ -139,7 +191,11 @@ const FlipperApplication FLIPPER_SYSTEM_APPS[] = { #ifdef SRV_UPDATER #error APP_UPDATER and SRV_UPDATER are mutually exclusive! #endif - {.app = updater_srv, .name = "UpdaterApp", .stack_size = 2048, .icon = NULL}, + {.app = updater_srv, + .name = "UpdaterApp", + .stack_size = 2048, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif }; @@ -149,35 +205,67 @@ const size_t FLIPPER_SYSTEM_APPS_COUNT = COUNT_OF(FLIPPER_SYSTEM_APPS); const FlipperApplication FLIPPER_APPS[] = { #ifdef APP_SUBGHZ - {.app = subghz_app, .name = "Sub-GHz", .stack_size = 2048, .icon = &A_Sub1ghz_14}, + {.app = subghz_app, + .name = "Sub-GHz", + .stack_size = 2048, + .icon = &A_Sub1ghz_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_LF_RFID - {.app = lfrfid_app, .name = "125 kHz RFID", .stack_size = 2048, .icon = &A_125khz_14}, + {.app = lfrfid_app, + .name = "125 kHz RFID", + .stack_size = 2048, + .icon = &A_125khz_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_NFC - {.app = nfc_app, .name = "NFC", .stack_size = 4096, .icon = &A_NFC_14}, + {.app = nfc_app, + .name = "NFC", + .stack_size = 4096, + .icon = &A_NFC_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_INFRARED - {.app = infrared_app, .name = "Infrared", .stack_size = 1024 * 3, .icon = &A_Infrared_14}, + {.app = infrared_app, + .name = "Infrared", + .stack_size = 1024 * 3, + .icon = &A_Infrared_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_GPIO - {.app = gpio_app, .name = "GPIO", .stack_size = 1024, .icon = &A_GPIO_14}, + {.app = gpio_app, + .name = "GPIO", + .stack_size = 1024, + .icon = &A_GPIO_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_IBUTTON - {.app = ibutton_app, .name = "iButton", .stack_size = 2048, .icon = &A_iButton_14}, + {.app = ibutton_app, + .name = "iButton", + .stack_size = 2048, + .icon = &A_iButton_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_BAD_USB - {.app = bad_usb_app, .name = "Bad USB", .stack_size = 2048, .icon = &A_BadUsb_14}, + {.app = bad_usb_app, + .name = "Bad USB", + .stack_size = 2048, + .icon = &A_BadUsb_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_U2F - {.app = u2f_app, .name = "U2F", .stack_size = 2048, .icon = &A_U2F_14}, + {.app = u2f_app, + .name = "U2F", + .stack_size = 2048, + .icon = &A_U2F_14, + .flags = FlipperApplicationFlagDeafult}, #endif }; @@ -234,15 +322,27 @@ const size_t FLIPPER_ON_SYSTEM_START_COUNT = COUNT_OF(FLIPPER_ON_SYSTEM_START); // Plugin menu const FlipperApplication FLIPPER_PLUGINS[] = { #ifdef APP_BLE_HID - {.app = bt_hid_app, .name = "Bluetooth Remote", .stack_size = 1024, .icon = NULL}, + {.app = bt_hid_app, + .name = "Bluetooth Remote", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_MUSIC_PLAYER - {.app = music_player_app, .name = "Music Player", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = music_player_app, + .name = "Music Player", + .stack_size = 1024, + .icon = &A_Plugins_14, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_SNAKE_GAME - {.app = snake_game_app, .name = "Snake Game", .stack_size = 1024, .icon = &A_Plugins_14}, + {.app = snake_game_app, + .name = "Snake Game", + .stack_size = 1024, + .icon = &A_Plugins_14, + .flags = FlipperApplicationFlagDeafult}, #endif }; @@ -251,108 +351,201 @@ const size_t FLIPPER_PLUGINS_COUNT = COUNT_OF(FLIPPER_PLUGINS); // Plugin menu const FlipperApplication FLIPPER_DEBUG_APPS[] = { #ifdef APP_BLINK - {.app = blink_test_app, .name = "Blink Test", .stack_size = 1024, .icon = NULL}, + {.app = blink_test_app, + .name = "Blink Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_VIBRO_TEST - {.app = vibro_test_app, .name = "Vibro Test", .stack_size = 1024, .icon = NULL}, + {.app = vibro_test_app, + .name = "Vibro Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_KEYPAD_TEST - {.app = keypad_test_app, .name = "Keypad Test", .stack_size = 1024, .icon = NULL}, + {.app = keypad_test_app, + .name = "Keypad Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_ACCESSOR - {.app = accessor_app, .name = "Accessor", .stack_size = 4096, .icon = NULL}, + {.app = accessor_app, + .name = "Accessor", + .stack_size = 4096, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_USB_TEST - {.app = usb_test_app, .name = "USB Test", .stack_size = 1024, .icon = NULL}, + {.app = usb_test_app, + .name = "USB Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_USB_MOUSE - {.app = usb_mouse_app, .name = "USB Mouse Demo", .stack_size = 1024, .icon = NULL}, + {.app = usb_mouse_app, + .name = "USB Mouse Demo", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_UART_ECHO - {.app = uart_echo_app, .name = "Uart Echo", .stack_size = 2048, .icon = NULL}, + {.app = uart_echo_app, + .name = "Uart Echo", + .stack_size = 2048, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_INFRARED_MONITOR - {.app = infrared_monitor_app, .name = "Infrared Monitor", .stack_size = 1024, .icon = NULL}, + {.app = infrared_monitor_app, + .name = "Infrared Monitor", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_SCENED - {.app = scened_app, .name = "Templated Scene", .stack_size = 1024, .icon = NULL}, + {.app = scened_app, + .name = "Templated Scene", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_LF_RFID - {.app = lfrfid_debug_app, .name = "LF-RFID Debug", .stack_size = 1024, .icon = NULL}, + {.app = lfrfid_debug_app, + .name = "LF-RFID Debug", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_BT - {.app = bt_debug_app, .name = "Bluetooth Debug", .stack_size = 1024, .icon = NULL}, + {.app = bt_debug_app, + .name = "Bluetooth Debug", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_UNIT_TESTS - {.app = delay_test_app, .name = "Delay Test", .stack_size = 1024, .icon = NULL}, + {.app = delay_test_app, + .name = "Delay Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_DISPLAY_TEST - {.app = display_test_app, .name = "Display Test", .stack_size = 1024, .icon = NULL}, + {.app = display_test_app, + .name = "Display Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_BATTERY_TEST - {.app = battery_test_app, .name = "Battery Test", .stack_size = 1024, .icon = NULL}, + {.app = battery_test_app, + .name = "Battery Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_TEXT_BOX_TEST - {.app = text_box_test_app, .name = "Text Box Test", .stack_size = 1024, .icon = NULL}, + {.app = text_box_test_app, + .name = "Text Box Test", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif }; const size_t FLIPPER_DEBUG_APPS_COUNT = COUNT_OF(FLIPPER_DEBUG_APPS); #ifdef APP_ARCHIVE -const FlipperApplication FLIPPER_ARCHIVE = - {.app = archive_app, .name = "Archive", .stack_size = 4096, .icon = &A_FileManager_14}; +const FlipperApplication FLIPPER_ARCHIVE = { + .app = archive_app, + .name = "Archive", + .stack_size = 4096, + .icon = &A_FileManager_14, + .flags = FlipperApplicationFlagDeafult}; #endif // Settings menu const FlipperApplication FLIPPER_SETTINGS_APPS[] = { #ifdef SRV_BT - {.app = bt_settings_app, .name = "Bluetooth", .stack_size = 1024, .icon = NULL}, + {.app = bt_settings_app, + .name = "Bluetooth", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_NOTIFICATION {.app = notification_settings_app, .name = "LCD and Notifications", .stack_size = 1024, - .icon = NULL}, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_STORAGE - {.app = storage_settings_app, .name = "Storage", .stack_size = 2048, .icon = NULL}, + {.app = storage_settings_app, + .name = "Storage", + .stack_size = 2048, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_POWER - {.app = power_settings_app, .name = "Power", .stack_size = 1024, .icon = NULL}, + {.app = power_settings_app, + .name = "Power", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagInsomniaSafe}, #endif #ifdef SRV_DESKTOP - {.app = desktop_settings_app, .name = "Desktop", .stack_size = 1024, .icon = NULL}, + {.app = desktop_settings_app, + .name = "Desktop", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_PASSPORT - {.app = passport_app, .name = "Passport", .stack_size = 1024, .icon = NULL}, + {.app = passport_app, + .name = "Passport", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef SRV_GUI - {.app = system_settings_app, .name = "System", .stack_size = 1024, .icon = NULL}, + {.app = system_settings_app, + .name = "System", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif #ifdef APP_ABOUT - {.app = about_settings_app, .name = "About", .stack_size = 1024, .icon = NULL}, + {.app = about_settings_app, + .name = "About", + .stack_size = 1024, + .icon = NULL, + .flags = FlipperApplicationFlagDeafult}, #endif }; diff --git a/applications/applications.h b/applications/applications.h index 705dba28d4b..24884d65cde 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -3,11 +3,17 @@ #include #include +typedef enum { + FlipperApplicationFlagDeafult = 0, + FlipperApplicationFlagInsomniaSafe = (1 << 0), +} FlipperApplicationFlag; + typedef struct { const FuriThreadCallback app; const char* name; const size_t stack_size; const Icon* icon; + const FlipperApplicationFlag flags; } FlipperApplication; typedef void (*FlipperOnStartHook)(void); diff --git a/applications/loader/loader.c b/applications/loader/loader.c index 3882647efdb..43e275ab988 100644 --- a/applications/loader/loader.c +++ b/applications/loader/loader.c @@ -238,7 +238,10 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con if(thread_state == FuriThreadStateRunning) { event.type = LoaderEventTypeApplicationStarted; furi_pubsub_publish(loader_instance->pubsub, &event); - furi_hal_power_insomnia_enter(); + + if(!loader_instance->application->flags & FlipperApplicationFlagInsomniaSafe) { + furi_hal_power_insomnia_enter(); + } } else if(thread_state == FuriThreadStateStopped) { FURI_LOG_I( TAG, @@ -251,7 +254,9 @@ static void loader_thread_state_callback(FuriThreadState thread_state, void* con loader_instance->application_arguments = NULL; } - furi_hal_power_insomnia_exit(); + if(!loader_instance->application->flags & FlipperApplicationFlagInsomniaSafe) { + furi_hal_power_insomnia_exit(); + } loader_unlock(instance); event.type = LoaderEventTypeApplicationStopped; From 1be0aeea90782d73d927f905fe7dc34c35fc324e Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Tue, 26 Apr 2022 11:36:41 +0300 Subject: [PATCH 18/37] Correct spelling --- applications/applications.c | 96 ++++++++++++++++++------------------- applications/applications.h | 2 +- 2 files changed, 49 insertions(+), 49 deletions(-) diff --git a/applications/applications.c b/applications/applications.c index af81b8e3d9e..b9e8bbd4776 100644 --- a/applications/applications.c +++ b/applications/applications.c @@ -78,7 +78,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "RpcSrv", .stack_size = 1024 * 4, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_BT @@ -86,7 +86,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "BtSrv", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_CLI @@ -94,7 +94,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "CliSrv", .stack_size = 4096, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_DIALOGS @@ -102,7 +102,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "DialogsSrv", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_DOLPHIN @@ -110,7 +110,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "DolphinSrv", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_DESKTOP @@ -121,7 +121,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "DesktopSrv", .stack_size = 2048, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_GUI @@ -129,7 +129,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "GuiSrv", .stack_size = 2048, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_INPUT @@ -137,7 +137,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "InputSrv", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_LOADER @@ -145,7 +145,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "LoaderSrv", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_NOTIFICATION @@ -153,7 +153,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "NotificationSrv", .stack_size = 1536, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_POWER @@ -161,7 +161,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "PowerSrv", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_STORAGE @@ -169,7 +169,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "StorageSrv", .stack_size = 3072, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_UPDATER @@ -180,7 +180,7 @@ const FlipperApplication FLIPPER_SERVICES[] = { .name = "UpdaterSrv", .stack_size = 2048, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif }; @@ -195,7 +195,7 @@ const FlipperApplication FLIPPER_SYSTEM_APPS[] = { .name = "UpdaterApp", .stack_size = 2048, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif }; @@ -209,7 +209,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "Sub-GHz", .stack_size = 2048, .icon = &A_Sub1ghz_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_LF_RFID @@ -217,7 +217,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "125 kHz RFID", .stack_size = 2048, .icon = &A_125khz_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_NFC @@ -225,7 +225,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "NFC", .stack_size = 4096, .icon = &A_NFC_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_INFRARED @@ -233,7 +233,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "Infrared", .stack_size = 1024 * 3, .icon = &A_Infrared_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_GPIO @@ -241,7 +241,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "GPIO", .stack_size = 1024, .icon = &A_GPIO_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_IBUTTON @@ -249,7 +249,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "iButton", .stack_size = 2048, .icon = &A_iButton_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_BAD_USB @@ -257,7 +257,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "Bad USB", .stack_size = 2048, .icon = &A_BadUsb_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_U2F @@ -265,7 +265,7 @@ const FlipperApplication FLIPPER_APPS[] = { .name = "U2F", .stack_size = 2048, .icon = &A_U2F_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif }; @@ -326,7 +326,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { .name = "Bluetooth Remote", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_MUSIC_PLAYER @@ -334,7 +334,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { .name = "Music Player", .stack_size = 1024, .icon = &A_Plugins_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_SNAKE_GAME @@ -342,7 +342,7 @@ const FlipperApplication FLIPPER_PLUGINS[] = { .name = "Snake Game", .stack_size = 1024, .icon = &A_Plugins_14, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif }; @@ -355,7 +355,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Blink Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_VIBRO_TEST @@ -363,7 +363,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Vibro Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_KEYPAD_TEST @@ -371,7 +371,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Keypad Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_ACCESSOR @@ -379,7 +379,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Accessor", .stack_size = 4096, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_USB_TEST @@ -387,7 +387,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "USB Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_USB_MOUSE @@ -395,7 +395,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "USB Mouse Demo", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_UART_ECHO @@ -403,7 +403,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Uart Echo", .stack_size = 2048, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_INFRARED_MONITOR @@ -411,7 +411,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Infrared Monitor", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_SCENED @@ -419,7 +419,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Templated Scene", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_LF_RFID @@ -427,7 +427,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "LF-RFID Debug", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_BT @@ -435,7 +435,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Bluetooth Debug", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_UNIT_TESTS @@ -443,7 +443,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Delay Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_DISPLAY_TEST @@ -451,7 +451,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Display Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_BATTERY_TEST @@ -459,7 +459,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Battery Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_TEXT_BOX_TEST @@ -467,7 +467,7 @@ const FlipperApplication FLIPPER_DEBUG_APPS[] = { .name = "Text Box Test", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif }; @@ -479,7 +479,7 @@ const FlipperApplication FLIPPER_ARCHIVE = { .name = "Archive", .stack_size = 4096, .icon = &A_FileManager_14, - .flags = FlipperApplicationFlagDeafult}; + .flags = FlipperApplicationFlagDefault}; #endif // Settings menu @@ -489,7 +489,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "Bluetooth", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_NOTIFICATION @@ -497,7 +497,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "LCD and Notifications", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_STORAGE @@ -505,7 +505,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "Storage", .stack_size = 2048, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_POWER @@ -521,7 +521,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "Desktop", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_PASSPORT @@ -529,7 +529,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "Passport", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef SRV_GUI @@ -537,7 +537,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "System", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif #ifdef APP_ABOUT @@ -545,7 +545,7 @@ const FlipperApplication FLIPPER_SETTINGS_APPS[] = { .name = "About", .stack_size = 1024, .icon = NULL, - .flags = FlipperApplicationFlagDeafult}, + .flags = FlipperApplicationFlagDefault}, #endif }; diff --git a/applications/applications.h b/applications/applications.h index 24884d65cde..bebe438ab30 100644 --- a/applications/applications.h +++ b/applications/applications.h @@ -4,7 +4,7 @@ #include typedef enum { - FlipperApplicationFlagDeafult = 0, + FlipperApplicationFlagDefault = 0, FlipperApplicationFlagInsomniaSafe = (1 << 0), } FlipperApplicationFlag; From 517195de7354744c33f9cd53f68fbf8bcb3bc67e Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Wed, 27 Apr 2022 17:57:10 +0300 Subject: [PATCH 19/37] FuriHal: cleanup insomnia usage, reset sleep flags on wakeup, add shutdown api --- applications/accessor/accessor_app.cpp | 4 +- applications/gui/canvas.c | 4 -- applications/ibutton/ibutton_app.cpp | 5 +- applications/lfrfid/lfrfid_app.cpp | 4 +- applications/nfc/nfc_worker.c | 2 - applications/power/power_service/power.c | 4 +- applications/storage/storage_glue.c | 2 - firmware/targets/f7/ble_glue/ble_glue.c | 5 -- firmware/targets/f7/ble_glue/gap.c | 6 +-- firmware/targets/f7/furi_hal/furi_hal_bt.c | 12 ++--- .../targets/f7/furi_hal/furi_hal_interrupt.c | 8 +++ firmware/targets/f7/furi_hal/furi_hal_power.c | 53 ++++++++++++++++++- .../targets/furi_hal_include/furi_hal_power.h | 3 ++ 13 files changed, 75 insertions(+), 37 deletions(-) diff --git a/applications/accessor/accessor_app.cpp b/applications/accessor/accessor_app.cpp index 21b2e258732..f021a816e59 100644 --- a/applications/accessor/accessor_app.cpp +++ b/applications/accessor/accessor_app.cpp @@ -32,7 +32,6 @@ void AccessorApp::run(void) { } AccessorApp::AccessorApp() { - furi_hal_power_insomnia_enter(); notification = static_cast(furi_record_open("notification")); onewire_host = onewire_host_alloc(); furi_hal_power_enable_otg(); @@ -42,7 +41,6 @@ AccessorApp::~AccessorApp() { furi_hal_power_disable_otg(); furi_record_close("notification"); onewire_host_free(onewire_host); - furi_hal_power_insomnia_exit(); } AccessorAppViewManager* AccessorApp::get_view_manager() { @@ -139,4 +137,4 @@ WIEGAND* AccessorApp::get_wiegand() { OneWireHost* AccessorApp::get_one_wire() { return onewire_host; -} \ No newline at end of file +} diff --git a/applications/gui/canvas.c b/applications/gui/canvas.c index fe07bd5e373..1e275aafb43 100644 --- a/applications/gui/canvas.c +++ b/applications/gui/canvas.c @@ -17,8 +17,6 @@ const CanvasFontParameters canvas_font_params[FontTotalNumber] = { Canvas* canvas_init() { Canvas* canvas = malloc(sizeof(Canvas)); - furi_hal_power_insomnia_enter(); - // Setup u8g2 u8g2_Setup_st756x_flipper(&canvas->fb, U8G2_R0, u8x8_hw_spi_stm32, u8g2_gpio_and_delay_stm32); canvas->orientation = CanvasOrientationHorizontal; @@ -31,8 +29,6 @@ Canvas* canvas_init() { canvas_clear(canvas); canvas_commit(canvas); - furi_hal_power_insomnia_exit(); - return canvas; } diff --git a/applications/ibutton/ibutton_app.cpp b/applications/ibutton/ibutton_app.cpp index 61bbcffca89..3266b4009e4 100644 --- a/applications/ibutton/ibutton_app.cpp +++ b/applications/ibutton/ibutton_app.cpp @@ -41,7 +41,6 @@ iButtonApp::iButtonApp() : notification{"notification"} , storage{"storage"} , dialogs{"dialogs"} { - furi_hal_power_insomnia_enter(); key = ibutton_key_alloc(); key_worker = ibutton_worker_alloc(); ibutton_worker_start_thread(key_worker); @@ -56,8 +55,6 @@ iButtonApp::~iButtonApp() { ibutton_worker_stop_thread(key_worker); ibutton_worker_free(key_worker); ibutton_key_free(key); - - furi_hal_power_insomnia_exit(); } iButtonAppViewManager* iButtonApp::get_view_manager() { @@ -342,4 +339,4 @@ void iButtonApp::make_app_folder() { if(!storage_simply_mkdir(storage, app_folder)) { dialog_message_show_storage_error(dialogs, "Cannot create\napp folder"); } -} \ No newline at end of file +} diff --git a/applications/lfrfid/lfrfid_app.cpp b/applications/lfrfid/lfrfid_app.cpp index 4653eb2d5c2..c2274234b97 100644 --- a/applications/lfrfid/lfrfid_app.cpp +++ b/applications/lfrfid/lfrfid_app.cpp @@ -31,11 +31,9 @@ LfRfidApp::LfRfidApp() , storage{"storage"} , dialogs{"dialogs"} , text_store(40) { - furi_hal_power_insomnia_enter(); } LfRfidApp::~LfRfidApp() { - furi_hal_power_insomnia_exit(); } void LfRfidApp::run(void* _args) { @@ -201,4 +199,4 @@ void LfRfidApp::make_app_folder() { if(!storage_simply_mkdir(storage, app_folder)) { dialog_message_show_storage_error(dialogs, "Cannot create\napp folder"); } -} \ No newline at end of file +} diff --git a/applications/nfc/nfc_worker.c b/applications/nfc/nfc_worker.c index 132483943db..e66ac318840 100644 --- a/applications/nfc/nfc_worker.c +++ b/applications/nfc/nfc_worker.c @@ -86,7 +86,6 @@ void nfc_worker_change_state(NfcWorker* nfc_worker, NfcWorkerState state) { int32_t nfc_worker_task(void* context) { NfcWorker* nfc_worker = context; - furi_hal_power_insomnia_enter(); furi_hal_nfc_exit_sleep(); if(nfc_worker->state == NfcWorkerStateDetect) { @@ -110,7 +109,6 @@ int32_t nfc_worker_task(void* context) { } furi_hal_nfc_sleep(); nfc_worker_change_state(nfc_worker, NfcWorkerStateReady); - furi_hal_power_insomnia_exit(); return 0; } diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index eb7c63cd8f3..1aa5517772a 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -192,10 +192,10 @@ static void power_check_vbus_level_change(Power* power) { power->voltage_vbus = power->info.voltage_vbus; if(power->voltage_vbus >= VBUS_MIN_VOLTAGE) { furi_hal_power_insomnia_enter(); - // furi_hal_usb_enable(); + // furi_hal_usb_enable(); FURI_LOG_D("VBUS", "VBUS connected: %f v", power->voltage_vbus); } else { - // furi_hal_usb_disable(); + // furi_hal_usb_disable(); furi_hal_power_insomnia_exit(); FURI_LOG_D("VBUS", "VBUS disconnected: %f v", power->voltage_vbus); } diff --git a/applications/storage/storage_glue.c b/applications/storage/storage_glue.c index 7ce8ec2c2a2..09656ae345c 100644 --- a/applications/storage/storage_glue.c +++ b/applications/storage/storage_glue.c @@ -39,12 +39,10 @@ void storage_data_init(StorageData* storage) { } bool storage_data_lock(StorageData* storage) { - furi_hal_power_insomnia_enter(); return (osMutexAcquire(storage->mutex, osWaitForever) == osOK); } bool storage_data_unlock(StorageData* storage) { - furi_hal_power_insomnia_exit(); return (osMutexRelease(storage->mutex) == osOK); } diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 9142a261a07..5783bbfc5ee 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -70,7 +70,6 @@ void ble_glue_init() { LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI); /* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */ LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); - furi_hal_power_insomnia_enter(); // APPD_Init(); @@ -142,7 +141,6 @@ bool ble_glue_start() { } bool ret = false; - furi_hal_power_insomnia_enter(); if(ble_app_init()) { FURI_LOG_I(TAG, "Radio stack started"); ble_glue->status = BleGlueStatusRadioStackStarted; @@ -157,7 +155,6 @@ bool ble_glue_start() { ble_glue->status = BleGlueStatusRadioStackMissing; ble_app_thread_stop(); } - furi_hal_power_insomnia_exit(); return ret; } @@ -230,10 +227,8 @@ static void ble_glue_sys_user_event_callback(void* pPayload) { if(p_sys_event->subevtcode == SHCI_SUB_EVT_CODE_READY) { FURI_LOG_I(TAG, "Fus started"); ble_glue->status = BleGlueStatusFusStarted; - furi_hal_power_insomnia_exit(); } else if(p_sys_event->subevtcode == SHCI_SUB_EVT_ERROR_NOTIF) { FURI_LOG_E(TAG, "Error during initialization"); - furi_hal_power_insomnia_exit(); } else if(p_sys_event->subevtcode == SHCI_SUB_EVT_BLE_NVM_RAM_UPDATE) { SHCI_C2_BleNvmRamUpdate_Evt_t* p_sys_ble_nvm_ram_update_event = (SHCI_C2_BleNvmRamUpdate_Evt_t*)p_sys_event->payload; diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index b21095ed7dc..57fdaa92ced 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -115,7 +115,6 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { if(gap->enable_adv) { // Restart advertising gap_advertise_start(GapStateAdvFast); - furi_hal_power_insomnia_exit(); } GapEvent event = {.type = GapEventTypeDisconnected}; gap->on_event_cb(event, gap->context); @@ -151,8 +150,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { } break; - case EVT_LE_CONN_COMPLETE: - furi_hal_power_insomnia_enter(); + case EVT_LE_CONN_COMPLETE: { hci_le_connection_complete_event_rp0* event = (hci_le_connection_complete_event_rp0*)meta_evt->data; gap->connection_params.conn_interval = event->Conn_Interval; @@ -169,7 +167,7 @@ SVCCTL_UserEvtFlowStatus_t SVCCTL_App_Notification(void* pckt) { gap_verify_connection_parameters(gap); // Start pairing by sending security request aci_gap_slave_security_req(event->Connection_Handle); - break; + } break; case EVT_LE_ADVERTISING_REPORT: { if(gap_scan) { diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index a8b85495300..d93dd8d4011 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -132,7 +132,6 @@ bool furi_hal_bt_start_radio_stack() { WirelessFwInfo_t info = {}; if(!ble_glue_wait_for_fus_start(&info)) { FURI_LOG_E(TAG, "FUS start failed"); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); ble_glue_thread_stop(); break; } @@ -150,7 +149,6 @@ bool furi_hal_bt_start_radio_stack() { // Starting radio stack if(!ble_glue_start()) { FURI_LOG_E(TAG, "Failed to start radio stack"); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); ble_glue_thread_stop(); ble_app_thread_stop(); break; @@ -222,17 +220,19 @@ bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, furi_assert(profile < FuriHalBtProfileNumber); bool ret = true; - FURI_LOG_I(TAG, "Stop current profile services"); - current_profile->stop(); FURI_LOG_I(TAG, "Disconnect and stop advertising"); furi_hal_bt_stop_advertising(); - FURI_LOG_I(TAG, "Shutdow 2nd core"); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); + + FURI_LOG_I(TAG, "Stop current profile services"); + current_profile->stop(); + FURI_LOG_I(TAG, "Stop BLE related RTOS threads"); ble_app_thread_stop(); gap_thread_stop(); + FURI_LOG_I(TAG, "Reset SHCI"); SHCI_C2_Reinit(); + osDelay(100); ble_glue_thread_stop(); FURI_LOG_I(TAG, "Start BT initialization"); diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 336fb524416..630c51c4c1a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -259,3 +259,11 @@ void IPCC_C1_RX_IRQHandler() { void FPU_IRQHandler() { furi_crash("FpuFault"); } + +void LPTIM1_IRQHandler() { + furi_crash("LPTIM1"); +} + +void LPTIM2_IRQHandler() { + furi_crash("LPTIM2"); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 2d36b21674b..f86cadb0ca0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include @@ -218,8 +219,8 @@ void furi_hal_power_deep_sleep() { // Prepare deep sleep uint32_t c1_lpms = LL_PWR_GetPowerMode(); uint32_t c2_lpms = LL_C2_PWR_GetPowerMode(); - LL_PWR_SetPowerMode(LL_PWR_MODE_STOP1); - LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP1); + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); LL_LPM_EnableDeepSleep(); #if defined(__CC_ARM) @@ -230,6 +231,7 @@ void furi_hal_power_deep_sleep() { __WFI(); LL_LPM_EnableSleep(); + LL_PWR_ClearFlag_C1STOP_C1STB(); LL_PWR_SetPowerMode(c1_lpms); LL_C2_PWR_SetPowerMode(c2_lpms); @@ -292,6 +294,53 @@ bool furi_hal_power_is_charging() { return ret; } +void furi_hal_power_shutdown() { + while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) + ; + + if(!LL_HSEM_1StepLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID)) { + if(LL_PWR_IsActiveFlag_C2DS() || LL_PWR_IsActiveFlag_C2SB()) { + // Release ENTRY_STOP_MODE semaphore + LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); + + // The switch on HSI before entering Stop Mode is required + furi_hal_clock_switch_to_hsi(); + } + } else { + /** + * The switch on HSI before entering Stop Mode is required + */ + furi_hal_clock_switch_to_hsi(); + } + + SET_BIT(PWR->PUCRB, DISPLAY_DI_Pin); + furi_hal_delay_us(30); + CLEAR_BIT(PWR->PDCRB, DISPLAY_DI_Pin); + furi_hal_delay_us(30); + + SET_BIT(PWR->PUCRB, DISPLAY_RST_Pin); + furi_hal_delay_us(30); + CLEAR_BIT(PWR->PDCRB, DISPLAY_RST_Pin); + furi_hal_delay_us(30); + + SET_BIT(PWR->CR3, PWR_CR3_APC); + + /* Release RCC semaphore */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); + + // Prepare Wakeup pin + LL_PWR_SetWakeUpPinPolarityLow(LL_PWR_WAKEUP_PIN2); + LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN2); + + LL_PWR_DisableBootC2(); + LL_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); + LL_LPM_EnableDeepSleep(); + + __WFI(); + furi_crash("Core2 is insomniac"); +} + void furi_hal_power_off() { furi_hal_i2c_acquire(&furi_hal_i2c_handle_power); bq25896_poweroff(&furi_hal_i2c_handle_power); diff --git a/firmware/targets/furi_hal_include/furi_hal_power.h b/firmware/targets/furi_hal_include/furi_hal_power.h index 717f6570649..16af959cf5b 100644 --- a/firmware/targets/furi_hal_include/furi_hal_power.h +++ b/firmware/targets/furi_hal_include/furi_hal_power.h @@ -85,6 +85,9 @@ uint8_t furi_hal_power_get_bat_health_pct(); */ bool furi_hal_power_is_charging(); +/** Switch MCU to SHUTDOWN */ +void furi_hal_power_shutdown(); + /** Poweroff device */ void furi_hal_power_off(); From 9fdb8fc187e4088c4e12f64f8a6ba8a649af76ac Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Wed, 27 Apr 2022 19:41:22 +0300 Subject: [PATCH 20/37] FuriHal: extra check on reinit request --- firmware/targets/f7/furi_hal/furi_hal_bt.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 4e839443525..b36e3874726 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -235,11 +235,14 @@ bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, gap_thread_stop(); FURI_LOG_I(TAG, "Reset SHCI"); - ble_glue_reinit_c2(); + furi_check(ble_glue_reinit_c2()); + osDelay(100); ble_glue_thread_stop(); + FURI_LOG_I(TAG, "Start BT initialization"); furi_hal_bt_init(); + furi_hal_bt_start_radio_stack(); ret = furi_hal_bt_start_app(profile, event_cb, context); if(ret) { From 7aad57630423a3dc39c95132c345b605a088c700 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 28 Apr 2022 00:22:34 +0300 Subject: [PATCH 21/37] FuriHal: rename gpio_display_rst pin to gpio_display_rst_n --- .../targets/f7/furi_hal/furi_hal_resources.c | 19 +++++++++++++++---- .../targets/f7/furi_hal/furi_hal_resources.h | 2 +- lib/u8g2/u8g2_glue.c | 2 +- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c index 35dbce8edec..e548ffaf3d4 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.c +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c @@ -1,6 +1,9 @@ #include #include +#include +#include + const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin}; @@ -9,7 +12,7 @@ const GpioPin gpio_rf_sw_0 = {.port = RF_SW_0_GPIO_Port, .pin = RF_SW_0_Pin}; const GpioPin gpio_subghz_cs = {.port = CC1101_CS_GPIO_Port, .pin = CC1101_CS_Pin}; const GpioPin gpio_display_cs = {.port = DISPLAY_CS_GPIO_Port, .pin = DISPLAY_CS_Pin}; -const GpioPin gpio_display_rst = {.port = DISPLAY_RST_GPIO_Port, .pin = DISPLAY_RST_Pin}; +const GpioPin gpio_display_rst_n = {.port = DISPLAY_RST_GPIO_Port, .pin = DISPLAY_RST_Pin}; const GpioPin gpio_display_di = {.port = DISPLAY_DI_GPIO_Port, .pin = DISPLAY_DI_Pin}; const GpioPin gpio_sdcard_cs = {.port = SD_CS_GPIO_Port, .pin = SD_CS_Pin}; const GpioPin gpio_sdcard_cd = {.port = SD_CD_GPIO_Port, .pin = SD_CD_Pin}; @@ -72,9 +75,17 @@ const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin); void furi_hal_resources_init_early() { furi_hal_gpio_init(&gpio_button_left, GpioModeInput, GpioPullUp, GpioSpeedLow); - furi_hal_gpio_init_simple(&gpio_display_rst, GpioModeOutputPushPull); + + // Display pins + furi_hal_gpio_write(&gpio_display_rst_n, 1); + furi_hal_gpio_init_simple(&gpio_display_rst_n, GpioModeOutputPushPull); furi_hal_gpio_init_simple(&gpio_display_di, GpioModeOutputPushPull); + // Alternative pull configuration for shutdown + SET_BIT(PWR->PUCRB, DISPLAY_RST_Pin); + CLEAR_BIT(PWR->PDCRB, DISPLAY_RST_Pin); + SET_BIT(PWR->CR3, PWR_CR3_APC); + // Hard reset USB furi_hal_gpio_init_simple(&gpio_usb_dm, GpioModeOutputOpenDrain); furi_hal_gpio_init_simple(&gpio_usb_dp, GpioModeOutputOpenDrain); @@ -103,8 +114,8 @@ void furi_hal_resources_init() { } // Display pins - furi_hal_gpio_init(&gpio_display_rst, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); - furi_hal_gpio_write(&gpio_display_rst, 0); + furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); + furi_hal_gpio_write(&gpio_display_rst_n, 0); furi_hal_gpio_init(&gpio_display_di, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow); furi_hal_gpio_write(&gpio_display_di, 0); diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h index eaafd7c524e..69485307b1a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_resources.h +++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h @@ -48,7 +48,7 @@ extern const GpioPin gpio_rf_sw_0; extern const GpioPin gpio_subghz_cs; extern const GpioPin gpio_display_cs; -extern const GpioPin gpio_display_rst; +extern const GpioPin gpio_display_rst_n; extern const GpioPin gpio_display_di; extern const GpioPin gpio_sdcard_cs; extern const GpioPin gpio_sdcard_cd; diff --git a/lib/u8g2/u8g2_glue.c b/lib/u8g2/u8g2_glue.c index 550a46104fc..cc186663f32 100644 --- a/lib/u8g2/u8g2_glue.c +++ b/lib/u8g2/u8g2_glue.c @@ -17,7 +17,7 @@ uint8_t u8g2_gpio_and_delay_stm32(u8x8_t* u8x8, uint8_t msg, uint8_t arg_int, vo asm("nop"); break; case U8X8_MSG_GPIO_RESET: - furi_hal_gpio_write(&gpio_display_rst, arg_int); + furi_hal_gpio_write(&gpio_display_rst_n, arg_int); break; default: return 0; From 5a2e5c30d764888ea63b130d3ca669a3d72a6222 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 28 Apr 2022 00:23:28 +0300 Subject: [PATCH 22/37] FuriHal: add debug HAL --- firmware/targets/f7/furi_hal/furi_hal_debug.c | 20 ++++++++++++++++ firmware/targets/f7/furi_hal/furi_hal_rtc.c | 17 ++++---------- firmware/targets/furi_hal_include/furi_hal.h | 1 + .../targets/furi_hal_include/furi_hal_debug.h | 23 +++++++++++++++++++ 4 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 firmware/targets/f7/furi_hal/furi_hal_debug.c create mode 100644 firmware/targets/furi_hal_include/furi_hal_debug.h diff --git a/firmware/targets/f7/furi_hal/furi_hal_debug.c b/firmware/targets/f7/furi_hal/furi_hal_debug.c new file mode 100644 index 00000000000..3b5dfe622e0 --- /dev/null +++ b/firmware/targets/f7/furi_hal/furi_hal_debug.c @@ -0,0 +1,20 @@ +#include + +#include +#include + +void furi_hal_debug_enable() { + // Low power mode debug + LL_DBGMCU_EnableDBGSleepMode(); + LL_DBGMCU_EnableDBGStopMode(); + LL_DBGMCU_EnableDBGStandbyMode(); + LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); +} + +void furi_hal_debug_disable() { + // Low power mode debug + LL_DBGMCU_DisableDBGSleepMode(); + LL_DBGMCU_DisableDBGStopMode(); + LL_DBGMCU_DisableDBGStandbyMode(); + LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48); +} diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c index d066c3b932d..b580a04b7b2 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c +++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -73,13 +74,9 @@ void furi_hal_rtc_init_early() { } if(furi_hal_rtc_is_flag_set(FuriHalRtcFlagDebug)) { - LL_DBGMCU_EnableDBGSleepMode(); - LL_DBGMCU_EnableDBGStopMode(); - LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + furi_hal_debug_enable(); } else { - LL_DBGMCU_DisableDBGSleepMode(); - LL_DBGMCU_DisableDBGStopMode(); - LL_DBGMCU_DisableDBGStandbyMode(); + furi_hal_debug_disable(); } } @@ -135,9 +132,7 @@ void furi_hal_rtc_set_flag(FuriHalRtcFlag flag) { furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); if(flag & FuriHalRtcFlagDebug) { - LL_DBGMCU_EnableDBGSleepMode(); - LL_DBGMCU_EnableDBGStopMode(); - LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); + furi_hal_debug_enable(); } } @@ -148,9 +143,7 @@ void furi_hal_rtc_reset_flag(FuriHalRtcFlag flag) { furi_hal_rtc_set_register(FuriHalRtcRegisterSystem, data_reg); if(flag & FuriHalRtcFlagDebug) { - LL_DBGMCU_DisableDBGSleepMode(); - LL_DBGMCU_DisableDBGStopMode(); - LL_DBGMCU_DisableDBGStandbyMode(); + furi_hal_debug_disable(); } } diff --git a/firmware/targets/furi_hal_include/furi_hal.h b/firmware/targets/furi_hal_include/furi_hal.h index a1e4a90fbb1..d70a52ad9ea 100644 --- a/firmware/targets/furi_hal_include/furi_hal.h +++ b/firmware/targets/furi_hal_include/furi_hal.h @@ -12,6 +12,7 @@ template struct STOP_EXTERNING_ME {}; #include "furi_hal_clock.h" #include "furi_hal_crypto.h" #include "furi_hal_console.h" +#include "furi_hal_debug.h" #include "furi_hal_os.h" #include "furi_hal_sd.h" #include "furi_hal_i2c.h" diff --git a/firmware/targets/furi_hal_include/furi_hal_debug.h b/firmware/targets/furi_hal_include/furi_hal_debug.h new file mode 100644 index 00000000000..88397bbbafb --- /dev/null +++ b/firmware/targets/furi_hal_include/furi_hal_debug.h @@ -0,0 +1,23 @@ +/** + * @file furi_hal_debug.h + * Debug HAL API + */ + +#pragma once + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** Enable MCU debug */ +void furi_hal_debug_enable(); + +/** Disable MCU debug */ +void furi_hal_debug_disable(); + +#ifdef __cplusplus +} +#endif From 0288e8a057a835fa5fa7215825421f6e34e8acb5 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 28 Apr 2022 00:44:08 +0300 Subject: [PATCH 23/37] FuriHal: add some magic to core2 reload procedure, fix issue with crash on ble keyboard exit --- firmware/targets/f7/furi_hal/furi_hal_bt.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index b36e3874726..9a7d5dc302f 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -230,6 +230,9 @@ bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, FURI_LOG_I(TAG, "Stop current profile services"); current_profile->stop(); + // Magic happens here + hci_reset(); + FURI_LOG_I(TAG, "Stop BLE related RTOS threads"); ble_app_thread_stop(); gap_thread_stop(); From 8629da4795017ce680c360cc35a491843e294ef6 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 28 Apr 2022 00:49:12 +0300 Subject: [PATCH 24/37] FuriHal: cleanup ble glue, add BLE_GLUE_DEBUG flag --- firmware/targets/f7/ble_glue/app_debug.c | 111 ++--------------------- firmware/targets/f7/ble_glue/ble_glue.c | 10 +- firmware/targets/f7/ble_glue/gap.c | 21 ++++- firmware/targets/f7/target.mk | 4 + 4 files changed, 36 insertions(+), 110 deletions(-) diff --git a/firmware/targets/f7/ble_glue/app_debug.c b/firmware/targets/f7/ble_glue/app_debug.c index 41d6670484a..e480ea364a7 100644 --- a/firmware/targets/f7/ble_glue/app_debug.c +++ b/firmware/targets/f7/ble_glue/app_debug.c @@ -1,25 +1,3 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * File Name : app_debug.c - * Description : Debug capabilities source file for STM32WPAN Middleware - ****************************************************************************** - * @attention - * - *

© Copyright (c) 2020 STMicroelectronics. - * All rights reserved.

- * - * This software component is licensed by ST under Ultimate Liberty license - * SLA0044, the "License"; You may not use this file except in compliance with - * the License. You may obtain a copy of the License at: - * www.st.com/SLA0044 - * - ****************************************************************************** - */ -/* USER CODE END Header */ - -/* Includes ------------------------------------------------------------------*/ -/* USER CODE BEGIN Includes */ #include "utilities_common.h" #include "app_common.h" @@ -28,10 +6,7 @@ #include "tl.h" #include "dbg_trace.h" #include -/* USER CODE END Includes */ -/* Private typedef -----------------------------------------------------------*/ -/* USER CODE BEGIN PTD */ typedef PACKED_STRUCT { GPIO_TypeDef* port; uint16_t pin; @@ -39,10 +14,7 @@ typedef PACKED_STRUCT { uint8_t reserved; } APPD_GpioConfig_t; -/* USER CODE END PTD */ -/* Private defines -----------------------------------------------------------*/ -/* USER CODE BEGIN PD */ #define GPIO_NBR_OF_RF_SIGNALS 9 #define GPIO_CFG_NBR_OF_FEATURES 34 #define NBR_OF_TRACES_CONFIG_PARAMETERS 4 @@ -51,12 +23,11 @@ APPD_GpioConfig_t; /** * THIS SHALL BE SET TO A VALUE DIFFERENT FROM 0 ONLY ON REQUEST FROM ST SUPPORT */ -#define BLE_DTB_CFG 7 +#define BLE_DTB_CFG 0 +// #define BLE_DTB_CFG 7 #define SYS_DBG_CFG1 (SHCI_C2_DEBUG_OPTIONS_IPCORE_LP | SHCI_C2_DEBUG_OPTIONS_CPU2_STOP_EN) -/* USER CODE END PD */ /* Private variables ---------------------------------------------------------*/ -/* USER CODE BEGIN PV */ PLACE_IN_SECTION("MB_MEM2") ALIGN(4) static SHCI_C2_DEBUG_TracesConfig_t APPD_TracesConfig = {0, 0, 0, 0}; PLACE_IN_SECTION("MB_MEM2") @@ -91,7 +62,7 @@ static const APPD_GpioConfig_t aGpioConfigList[GPIO_CFG_NBR_OF_FEATURES] = { {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IPCC_TRACES_TX - Set on Entry / Reset on Exit */ {GPIOA, LL_GPIO_PIN_6, 1, 0}, /* HARD_FAULT - Set on Entry / Reset on Exit */ /* From v1.1.1 */ - {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* IP_CORE_LP_STATUS - Set on Entry / Reset on Exit */ + {GPIOC, LL_GPIO_PIN_1, 1, 0}, /* IP_CORE_LP_STATUS - Set on Entry / Reset on Exit */ /* From v1.2.0 */ {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* END_OF_CONNECTION_EVENT - Set on Entry / Reset on Exit */ {GPIOA, LL_GPIO_PIN_0, 0, 0}, /* TIMER_SERVER_CALLBACK - Toggle on Entry */ @@ -130,65 +101,20 @@ static const APPD_GpioConfig_t aRfConfigList[GPIO_NBR_OF_RF_SIGNALS] = { {GPIOB, LL_GPIO_PIN_10, 0, 0}, /* DTB18 - FSM4 */ }; #endif -/* USER CODE END PV */ -/* Global variables ----------------------------------------------------------*/ -/* USER CODE BEGIN GV */ -/* USER CODE END GV */ - -/* Private function prototypes -----------------------------------------------*/ -/* USER CODE BEGIN PFP */ static void APPD_SetCPU2GpioConfig(void); static void APPD_BleDtbCfg(void); -/* USER CODE END PFP */ - -/* Functions Definition ------------------------------------------------------*/ -void APPD_Init(void) { -/* USER CODE BEGIN APPD_Init */ -#if(CFG_DEBUGGER_SUPPORTED == 1) - /** - * Keep debugger enabled while in any low power mode - */ - LL_DBGMCU_EnableDBGSleepMode(); - LL_DBGMCU_EnableDBGStopMode(); - - /***************** ENABLE DEBUGGER *************************************/ - LL_EXTI_EnableIT_32_63(LL_EXTI_LINE_48); - -#else - LL_GPIO_InitTypeDef gpio_config = {0}; - LL_PWR_EnableVddUSB(); - - gpio_config.Mode = LL_GPIO_MODE_ANALOG; - gpio_config.Speed = LL_GPIO_SPEED_FREQ_LOW; - // gpio_config.OutputType = LL_GPIO_OUTPUT_PUSHPULL; - // gpio_config.Pull = LL_GPIO_PULL_NO; - // gpio_config.Alternate = LL_GPIO_AF_10; - gpio_config.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13; - LL_GPIO_Init(GPIOA, &gpio_config); - - gpio_config.Pin = LL_GPIO_PIN_4 | LL_GPIO_PIN_3; - LL_GPIO_Init(GPIOB, &gpio_config); - - LL_DBGMCU_DisableDBGSleepMode(); - LL_DBGMCU_DisableDBGStopMode(); - LL_DBGMCU_DisableDBGStandbyMode(); - -#endif /* (CFG_DEBUGGER_SUPPORTED == 1) */ +void APPD_Init() { #if(CFG_DEBUG_TRACE != 0) DbgTraceInit(); #endif APPD_SetCPU2GpioConfig(); APPD_BleDtbCfg(); - - /* USER CODE END APPD_Init */ - return; } void APPD_EnableCPU2(void) { - /* USER CODE BEGIN APPD_EnableCPU2 */ SHCI_C2_DEBUG_Init_Cmd_Packet_t DebugCmdPacket = { {{0, 0, 0}}, /**< Does not need to be initialized */ {(uint8_t*)aGpioConfigList, @@ -204,6 +130,7 @@ void APPD_EnableCPU2(void) { /** GPIO DEBUG Initialization */ SHCI_C2_DEBUG_Init(&DebugCmdPacket); + // We don't need External Power Amplifier // LL_GPIO_InitTypeDef gpio_config; // gpio_config.Pull = GPIO_NOPULL; // gpio_config.Mode = GPIO_MODE_OUTPUT_PP; @@ -212,17 +139,10 @@ void APPD_EnableCPU2(void) { // HAL_GPIO_Init(GPIOC, &gpio_config); // SHCI_C2_ExtpaConfig((uint32_t)GPIOC, LL_GPIO_PIN_3, EXT_PA_ENABLED_LOW, EXT_PA_ENABLED); - /* USER CODE END APPD_EnableCPU2 */ return; } -/************************************************************* - * - * LOCAL FUNCTIONS - * - *************************************************************/ static void APPD_SetCPU2GpioConfig(void) { - /* USER CODE BEGIN APPD_SetCPU2GpioConfig */ LL_GPIO_InitTypeDef gpio_config = {0}; uint8_t local_loop; uint16_t gpioa_pin_list; @@ -259,8 +179,9 @@ static void APPD_SetCPU2GpioConfig(void) { gpio_config.OutputType = LL_GPIO_OUTPUT_PUSHPULL; gpio_config.Pull = LL_GPIO_PULL_NO; - gpio_config.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13; - LL_GPIO_Init(GPIOA, &gpio_config); + // Never disable SWD, why would you? + // gpio_config.Pin = LL_GPIO_PIN_15 | LL_GPIO_PIN_14 | LL_GPIO_PIN_13; + // LL_GPIO_Init(GPIOA, &gpio_config); if(gpioa_pin_list != 0) { gpio_config.Pin = gpioa_pin_list; @@ -282,13 +203,9 @@ static void APPD_SetCPU2GpioConfig(void) { LL_GPIO_Init(GPIOC, &gpio_config); LL_GPIO_ResetOutputPin(GPIOC, gpioa_pin_list); } - - /* USER CODE END APPD_SetCPU2GpioConfig */ - return; } static void APPD_BleDtbCfg(void) { -/* USER CODE BEGIN APPD_BleDtbCfg */ #if(BLE_DTB_CFG != 0) LL_GPIO_InitTypeDef gpio_config = {0}; uint8_t local_loop; @@ -304,11 +221,9 @@ static void APPD_BleDtbCfg(void) { case(uint32_t)GPIOA: gpioa_pin_list |= aRfConfigList[local_loop].pin; break; - case(uint32_t)GPIOB: gpiob_pin_list |= aRfConfigList[local_loop].pin; break; - default: break; } @@ -334,16 +249,8 @@ static void APPD_BleDtbCfg(void) { LL_GPIO_Init(GPIOB, &gpio_config); } #endif - - /* USER CODE END APPD_BleDtbCfg */ - return; } -/************************************************************* - * - * WRAP FUNCTIONS - * -*************************************************************/ #if(CFG_DEBUG_TRACE != 0) void DbgOutputInit(void) { } @@ -353,5 +260,3 @@ void DbgOutputTraces(uint8_t* p_data, uint16_t size, void (*cb)(void)) { cb(); } #endif - -/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/firmware/targets/f7/ble_glue/ble_glue.c b/firmware/targets/f7/ble_glue/ble_glue.c index 56f5a755fc1..ec4a617b8a3 100644 --- a/firmware/targets/f7/ble_glue/ble_glue.c +++ b/firmware/targets/f7/ble_glue/ble_glue.c @@ -64,7 +64,9 @@ void ble_glue_init() { /* Initialize the CPU2 reset value before starting CPU2 with C2BOOT */ LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); - // APPD_Init(); +#ifdef BLE_GLUE_DEBUG + APPD_Init(); +#endif // Initialize all transport layers TL_MM_Config_t tl_mm_config; @@ -290,8 +292,10 @@ static void ble_glue_sys_status_not_callback(SHCI_TL_CmdStatus_t status) { */ static void ble_glue_sys_user_event_callback(void* pPayload) { UNUSED(pPayload); - /* Traces channel initialization */ - // APPD_EnableCPU2( ); + +#ifdef BLE_GLUE_DEBUG + APPD_EnableCPU2(); +#endif TL_AsynchEvt_t* p_sys_event = (TL_AsynchEvt_t*)(((tSHCI_UserEvtRxParam*)pPayload)->pckt->evtserial.evt.payload); diff --git a/firmware/targets/f7/ble_glue/gap.c b/firmware/targets/f7/ble_glue/gap.c index 57fdaa92ced..45191a5a5b2 100644 --- a/firmware/targets/f7/ble_glue/gap.c +++ b/firmware/targets/f7/ble_glue/gap.c @@ -412,7 +412,9 @@ static void gap_advertise_start(GapState new_state) { // Stop advertising status = aci_gap_set_non_discoverable(); if(status) { - FURI_LOG_E(TAG, "Stop Advertising Failed, result: %d", status); + FURI_LOG_E(TAG, "set_non_discoverable failed %d", status); + } else { + FURI_LOG_D(TAG, "set_non_discoverable success"); } } // Configure advertising @@ -429,7 +431,7 @@ static void gap_advertise_start(GapState new_state) { 0, 0); if(status) { - FURI_LOG_E(TAG, "Set discoverable err: %d", status); + FURI_LOG_E(TAG, "set_discoverable failed %d", status); } gap->state = new_state; GapEvent event = {.type = GapEventTypeStartAdvertising}; @@ -438,14 +440,25 @@ static void gap_advertise_start(GapState new_state) { } static void gap_advertise_stop() { + tBleStatus ret; if(gap->state > GapStateIdle) { if(gap->state == GapStateConnected) { // Terminate connection - aci_gap_terminate(gap->service.connection_handle, 0x13); + ret = aci_gap_terminate(gap->service.connection_handle, 0x13); + if(ret != BLE_STATUS_SUCCESS) { + FURI_LOG_E(TAG, "terminate failed %d", ret); + } else { + FURI_LOG_D(TAG, "terminate success"); + } } // Stop advertising osTimerStop(gap->advertise_timer); - aci_gap_set_non_discoverable(); + ret = aci_gap_set_non_discoverable(); + if(ret != BLE_STATUS_SUCCESS) { + FURI_LOG_E(TAG, "set_non_discoverable failed %d", ret); + } else { + FURI_LOG_D(TAG, "set_non_discoverable success"); + } gap->state = GapStateIdle; } GapEvent event = {.type = GapEventTypeStopAdvertising}; diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index 1822b6284e1..baf853a229a 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -128,6 +128,10 @@ ifeq ($(INVERT_RFID_IN), 1) CFLAGS += -DINVERT_RFID_IN endif +ifeq ($(BLE_GLUE_DEBUG), 1) +CFLAGS += -DBLE_GLUE_DEBUG +endif + FURI_HAL_DIR = $(TARGET_DIR)/furi_hal CFLAGS += -I$(FURI_HAL_DIR) C_SOURCES += $(wildcard $(FURI_HAL_DIR)/*.c) From 225d2b399ed922d942a2f7246dfe4ee7ac29b78b Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 28 Apr 2022 01:50:54 +0300 Subject: [PATCH 25/37] FuriHal: ble reinit API, move os timer to LPTIM1 for deep sleep capability, shutdown that works --- firmware/targets/f7/furi_hal/furi_hal_bt.c | 15 ++++-- .../targets/f7/furi_hal/furi_hal_idle_timer.h | 8 +-- firmware/targets/f7/furi_hal/furi_hal_power.c | 50 ++++++++----------- firmware/targets/f7/target.mk | 4 ++ .../targets/furi_hal_include/furi_hal_bt.h | 6 +++ 5 files changed, 45 insertions(+), 38 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_bt.c b/firmware/targets/f7/furi_hal/furi_hal_bt.c index 9a7d5dc302f..48d69844df4 100755 --- a/firmware/targets/f7/furi_hal/furi_hal_bt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_bt.c @@ -219,11 +219,7 @@ bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb, return ret; } -bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, void* context) { - furi_assert(event_cb); - furi_assert(profile < FuriHalBtProfileNumber); - bool ret = true; - +void furi_hal_bt_reinit() { FURI_LOG_I(TAG, "Disconnect and stop advertising"); furi_hal_bt_stop_advertising(); @@ -247,6 +243,15 @@ bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, furi_hal_bt_init(); furi_hal_bt_start_radio_stack(); +} + +bool furi_hal_bt_change_app(FuriHalBtProfile profile, GapEventCallback event_cb, void* context) { + furi_assert(event_cb); + furi_assert(profile < FuriHalBtProfileNumber); + bool ret = true; + + furi_hal_bt_reinit(); + ret = furi_hal_bt_start_app(profile, event_cb, context); if(ret) { current_profile = &profile_config[profile]; diff --git a/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h b/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h index 61afd631c85..a165441527a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h +++ b/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h @@ -7,12 +7,14 @@ // Timer used for tickless idle #define FURI_HAL_IDLE_TIMER_MAX 0xFFFF -#define FURI_HAL_IDLE_TIMER LPTIM2 -#define FURI_HAL_IDLE_TIMER_IRQ LPTIM2_IRQn +#define FURI_HAL_IDLE_TIMER LPTIM1 +#define FURI_HAL_IDLE_TIMER_IRQ LPTIM1_IRQn static inline void furi_hal_idle_timer_init() { // Configure clock source - LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE); + LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE); + // There is a theoretical possibility that we need it + LL_C2_APB1_GRP1_EnableClockSleep(LL_C2_APB1_GRP1_PERIPH_LPTIM1); // Set interrupt priority and enable them NVIC_SetPriority( FURI_HAL_IDLE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index f86cadb0ca0..d06c73c70c9 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -22,6 +22,12 @@ #define FURI_HAL_POWER_EXTI_LINE_0_31 0 #define FURI_HAL_POWER_EXTI_LINE_32_63 1 +#ifdef FURI_HAL_POWER_DEEP_SLEEP_ENABLED +#define FURI_HAL_POWER_DEEP_INSOMNIA 0 +#else +#define FURI_HAL_POWER_DEEP_INSOMNIA 1 +#endif + typedef struct { volatile uint8_t insomnia; volatile uint8_t deep_insomnia; @@ -33,7 +39,7 @@ typedef struct { static volatile FuriHalPower furi_hal_power = { .insomnia = 0, - .deep_insomnia = 0, + .deep_insomnia = FURI_HAL_POWER_DEEP_INSOMNIA, .suppress_charge = 0, }; @@ -217,8 +223,6 @@ void furi_hal_power_deep_sleep() { LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); // Prepare deep sleep - uint32_t c1_lpms = LL_PWR_GetPowerMode(); - uint32_t c2_lpms = LL_C2_PWR_GetPowerMode(); LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2); LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2); LL_LPM_EnableDeepSleep(); @@ -231,10 +235,13 @@ void furi_hal_power_deep_sleep() { __WFI(); LL_LPM_EnableSleep(); - LL_PWR_ClearFlag_C1STOP_C1STB(); - LL_PWR_SetPowerMode(c1_lpms); - LL_C2_PWR_SetPowerMode(c2_lpms); + // Make sure that values differ to prevent disaster on wfi + LL_PWR_SetPowerMode(LL_PWR_MODE_STOP0); + LL_C2_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); + + LL_PWR_ClearFlag_C1STOP_C1STB(); + LL_PWR_ClearFlag_C2STOP_C2STB(); /* Release ENTRY_STOP_MODE semaphore */ LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); @@ -295,6 +302,8 @@ bool furi_hal_power_is_charging() { } void furi_hal_power_shutdown() { + furi_hal_bt_reinit(); + while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) ; @@ -302,35 +311,16 @@ void furi_hal_power_shutdown() { if(LL_PWR_IsActiveFlag_C2DS() || LL_PWR_IsActiveFlag_C2SB()) { // Release ENTRY_STOP_MODE semaphore LL_HSEM_ReleaseLock(HSEM, CFG_HW_ENTRY_STOP_MODE_SEMID, 0); - - // The switch on HSI before entering Stop Mode is required - furi_hal_clock_switch_to_hsi(); } - } else { - /** - * The switch on HSI before entering Stop Mode is required - */ - furi_hal_clock_switch_to_hsi(); } - SET_BIT(PWR->PUCRB, DISPLAY_DI_Pin); - furi_hal_delay_us(30); - CLEAR_BIT(PWR->PDCRB, DISPLAY_DI_Pin); - furi_hal_delay_us(30); - - SET_BIT(PWR->PUCRB, DISPLAY_RST_Pin); - furi_hal_delay_us(30); - CLEAR_BIT(PWR->PDCRB, DISPLAY_RST_Pin); - furi_hal_delay_us(30); - - SET_BIT(PWR->CR3, PWR_CR3_APC); - - /* Release RCC semaphore */ - LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); - // Prepare Wakeup pin LL_PWR_SetWakeUpPinPolarityLow(LL_PWR_WAKEUP_PIN2); LL_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN2); + LL_C2_PWR_EnableWakeUpPin(LL_PWR_WAKEUP_PIN2); + + /* Release RCC semaphore */ + LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); LL_PWR_DisableBootC2(); LL_PWR_SetPowerMode(LL_PWR_MODE_SHUTDOWN); @@ -338,7 +328,7 @@ void furi_hal_power_shutdown() { LL_LPM_EnableDeepSleep(); __WFI(); - furi_crash("Core2 is insomniac"); + furi_crash("Insomniac core2"); } void furi_hal_power_off() { diff --git a/firmware/targets/f7/target.mk b/firmware/targets/f7/target.mk index baf853a229a..6410ba13099 100644 --- a/firmware/targets/f7/target.mk +++ b/firmware/targets/f7/target.mk @@ -119,6 +119,10 @@ ifeq ($(FURI_HAL_USB_VCP_DEBUG), 1) CFLAGS += -DFURI_HAL_USB_VCP_DEBUG endif +ifeq ($(FURI_HAL_POWER_DEEP_SLEEP_ENABLED), 1) +CFLAGS += -DFURI_HAL_POWER_DEEP_SLEEP_ENABLED +endif + FURI_HAL_SUBGHZ_TX_GPIO ?= 0 ifneq ($(FURI_HAL_SUBGHZ_TX_GPIO), 0) CFLAGS += -DFURI_HAL_SUBGHZ_TX_GPIO=$(FURI_HAL_SUBGHZ_TX_GPIO) diff --git a/firmware/targets/furi_hal_include/furi_hal_bt.h b/firmware/targets/furi_hal_include/furi_hal_bt.h index 74e8d3214b8..73b16becbee 100644 --- a/firmware/targets/furi_hal_include/furi_hal_bt.h +++ b/firmware/targets/furi_hal_include/furi_hal_bt.h @@ -68,6 +68,12 @@ FuriHalBtStack furi_hal_bt_get_radio_stack(); */ bool furi_hal_bt_start_app(FuriHalBtProfile profile, GapEventCallback event_cb, void* context); +/** Reinitialize core2 + * + * Also can be used to prepare core2 for stop modes + */ +void furi_hal_bt_reinit(); + /** Change BLE app * Restarts 2nd core * From d2002c3b37d0ebdf05a1145f8ee8431b5bf6f996 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Thu, 28 Apr 2022 02:28:37 +0300 Subject: [PATCH 26/37] FuriHal: take insomnia while shutdown --- firmware/targets/f7/furi_hal/furi_hal_power.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index d06c73c70c9..5b2a90b1da8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -302,6 +302,8 @@ bool furi_hal_power_is_charging() { } void furi_hal_power_shutdown() { + furi_hal_power_insomnia_enter(); + furi_hal_bt_reinit(); while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) From 67fb70dc5943f7267cc162fccf67dfd290f8feaa Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 15:25:08 +0300 Subject: [PATCH 27/37] Remove USB switch on/off on VBUS change --- applications/power/power_service/power.c | 23 +--------------- applications/power/power_service/power_i.h | 1 - firmware/targets/f7/furi_hal/furi_hal_os.c | 29 +++++++++------------ firmware/targets/f7/furi_hal/furi_hal_usb.c | 15 ++++------- 4 files changed, 19 insertions(+), 49 deletions(-) diff --git a/applications/power/power_service/power.c b/applications/power/power_service/power.c index 1aa5517772a..5f7eeb84713 100644 --- a/applications/power/power_service/power.c +++ b/applications/power/power_service/power.c @@ -5,11 +5,8 @@ #include #include #include -#include #define POWER_OFF_TIMEOUT 90 -#define VBUS_MIN_VOLTAGE 4.0f -#define VBUS_CHANGE_THRESHOLD 2.0f void power_draw_battery_callback(Canvas* canvas, void* context) { furi_assert(context); @@ -154,7 +151,7 @@ static void power_check_low_battery(Power* power) { } // Check battery charge and vbus voltage - if((power->info.charge == 0) && (power->info.voltage_vbus < VBUS_MIN_VOLTAGE) && + if((power->info.charge == 0) && (power->info.voltage_vbus < 4.0f) && power->show_low_bat_level_message) { if(!power->battery_low) { view_dispatcher_send_to_front(power->view_dispatcher); @@ -187,21 +184,6 @@ static void power_check_battery_level_change(Power* power) { } } -static void power_check_vbus_level_change(Power* power) { - if(fabsf(power->voltage_vbus - power->info.voltage_vbus) >= VBUS_CHANGE_THRESHOLD) { - power->voltage_vbus = power->info.voltage_vbus; - if(power->voltage_vbus >= VBUS_MIN_VOLTAGE) { - furi_hal_power_insomnia_enter(); - // furi_hal_usb_enable(); - FURI_LOG_D("VBUS", "VBUS connected: %f v", power->voltage_vbus); - } else { - // furi_hal_usb_disable(); - furi_hal_power_insomnia_exit(); - FURI_LOG_D("VBUS", "VBUS disconnected: %f v", power->voltage_vbus); - } - } -} - int32_t power_srv(void* p) { (void)p; Power* power = power_alloc(); @@ -221,9 +203,6 @@ int32_t power_srv(void* p) { // Check and notify about battery level change power_check_battery_level_change(power); - // Check and notify about vbus level change - power_check_vbus_level_change(power); - // Update battery view port if(need_refresh) view_port_update(power->battery_view_port); diff --git a/applications/power/power_service/power_i.h b/applications/power/power_service/power_i.h index b43054f00cd..f88b8f24b4b 100755 --- a/applications/power/power_service/power_i.h +++ b/applications/power/power_service/power_i.h @@ -37,7 +37,6 @@ struct Power { bool show_low_bat_level_message; uint8_t battery_level; uint8_t power_off_timeout; - float voltage_vbus; osMutexId_t api_mtx; }; diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index e7ad91b883b..5bad2a18ffb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -58,19 +58,19 @@ void furi_hal_os_tick() { } } -static inline void furi_hal_os_suspend_aux_periphs() { - // Disable USART - furi_hal_uart_suspend(FuriHalUartIdUSART1); - furi_hal_uart_suspend(FuriHalUartIdLPUART1); - // Disable USB -} - -static inline void furi_hal_os_resume_aux_periphs() { - // Re-enable USART - furi_hal_uart_resume(FuriHalUartIdUSART1); - furi_hal_uart_resume(FuriHalUartIdLPUART1); - // Re-enable USB -} +// static inline void furi_hal_os_suspend_aux_periphs() { +// // Disable USART +// furi_hal_uart_suspend(FuriHalUartIdUSART1); +// furi_hal_uart_suspend(FuriHalUartIdLPUART1); +// // Disable USB +// } +// +// static inline void furi_hal_os_resume_aux_periphs() { +// // Re-enable USART +// furi_hal_uart_resume(FuriHalUartIdUSART1); +// furi_hal_uart_resume(FuriHalUartIdLPUART1); +// // Re-enable USB +// } static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Stop ticks @@ -118,13 +118,11 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { expected_idle_ticks = FURI_HAL_OS_MAX_SLEEP; } - furi_hal_os_suspend_aux_periphs(); // Stop IRQ handling, no one should disturb us till we finish __disable_irq(); // Confirm OS that sleep is still possible if(eTaskConfirmSleepModeStatus() == eAbortSleep) { - furi_hal_os_resume_aux_periphs(); __enable_irq(); return; } @@ -136,7 +134,6 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { vTaskStepTick(MIN(completed_ticks, expected_idle_ticks)); } - furi_hal_os_resume_aux_periphs(); // Reenable IRQ __enable_irq(); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index 575ba1e8ead..f1044c36bba 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -67,7 +67,7 @@ void furi_hal_usb_init(void) { LL_GPIO_Init(GPIOA, &GPIO_InitStruct); usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf)); - usbd_enable(&udev, false); + usbd_enable(&udev, true); usbd_reg_descr(&udev, usb_descriptor_get); usbd_reg_event(&udev, usbd_evt_susp, susp_evt); @@ -199,7 +199,7 @@ static void susp_evt(usbd_device* dev, uint8_t event, uint8_t ep) { usb.connected = false; usb.if_cur->suspend(&udev); - // furi_hal_power_insomnia_exit(); + furi_hal_power_insomnia_exit(); } if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventSuspend, usb.cb_ctx); @@ -211,7 +211,7 @@ static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep) { usb.connected = true; usb.if_cur->wakeup(&udev); - // furi_hal_power_insomnia_enter(); + furi_hal_power_insomnia_enter(); } if(usb.callback != NULL) { usb.callback(FuriHalUsbStateEventWakeup, usb.cb_ctx); @@ -249,6 +249,7 @@ static int32_t furi_hal_usb_thread(void* context) { usbd_reg_event(&udev, usbd_evt_reset, NULL); FURI_LOG_I(TAG, "USB Reinit"); susp_evt(&udev, 0, 0); + usbd_connect(&udev, false); usb.enabled = false; usbd_enable(&udev, false); @@ -262,8 +263,6 @@ static int32_t furi_hal_usb_thread(void* context) { if(usb.if_cur != NULL) { usb.if_cur->deinit(&udev); } - usbd_enable(&udev, false); - usbd_enable(&udev, true); if(if_new != NULL) { if_new->init(&udev, if_new, if_ctx_new); usbd_reg_event(&udev, usbd_evt_reset, reset_evt); @@ -274,10 +273,7 @@ static int32_t furi_hal_usb_thread(void* context) { } if(flags & EventEnable) { if((!usb.enabled) && (usb.if_cur != NULL)) { - usbd_enable(&udev, true); - if(usb.if_cur != NULL) { - usb.if_cur->init(&udev, if_new, if_ctx_new); - } + usbd_connect(&udev, true); usb.enabled = true; FURI_LOG_I(TAG, "USB Enable"); } @@ -286,7 +282,6 @@ static int32_t furi_hal_usb_thread(void* context) { if(usb.enabled) { susp_evt(&udev, 0, 0); usbd_connect(&udev, false); - usbd_enable(&udev, false); usb.enabled = false; usb_request_pending = false; FURI_LOG_I(TAG, "USB Disable"); From e522bf44e84565c5d8199a656056d948bd1e1476 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 18:04:33 +0300 Subject: [PATCH 28/37] Better tick skew handling --- firmware/targets/f7/Inc/FreeRTOSConfig.h | 2 +- firmware/targets/f7/furi_hal/furi_hal_os.c | 16 +----- firmware/targets/f7/furi_hal/furi_hal_power.c | 53 ++++++++++++------- 3 files changed, 36 insertions(+), 35 deletions(-) diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index c3b2117c5a8..e62a6b9fda3 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -20,7 +20,7 @@ extern uint32_t SystemCoreClock; #define configCPU_CLOCK_HZ (SystemCoreClock) #define configTICK_RATE_HZ ((TickType_t)1000) #define configMAX_PRIORITIES (56) -#define configMINIMAL_STACK_SIZE ((uint16_t)128) +#define configMINIMAL_STACK_SIZE ((uint16_t)1024) /* Heap size determined automatically by linker */ // #define configTOTAL_HEAP_SIZE ((size_t)0) diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 5bad2a18ffb..3f387e37ae0 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -58,20 +58,6 @@ void furi_hal_os_tick() { } } -// static inline void furi_hal_os_suspend_aux_periphs() { -// // Disable USART -// furi_hal_uart_suspend(FuriHalUartIdUSART1); -// furi_hal_uart_suspend(FuriHalUartIdLPUART1); -// // Disable USB -// } -// -// static inline void furi_hal_os_resume_aux_periphs() { -// // Re-enable USART -// furi_hal_uart_resume(FuriHalUartIdUSART1); -// furi_hal_uart_resume(FuriHalUartIdLPUART1); -// // Re-enable USB -// } - static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Stop ticks furi_hal_clock_suspend_tick(); @@ -93,7 +79,7 @@ static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Calculate how much time we spent in the sleep uint32_t after_cnt = furi_hal_idle_timer_get_cnt() + furi_hal_os_skew; uint32_t after_tick = FURI_HAL_OS_IDLE_CNT_TO_TICKS(after_cnt); - furi_hal_os_skew = after_cnt - (after_cnt / after_tick); + furi_hal_os_skew = after_cnt - FURI_HAL_OS_TICKS_TO_IDLE_CNT(after_tick); bool cmpm = LL_LPTIM_IsActiveFlag_CMPM(FURI_HAL_IDLE_TIMER); bool arrm = LL_LPTIM_IsActiveFlag_ARRM(FURI_HAL_IDLE_TIMER); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 5b2a90b1da8..61e59938c55 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -126,21 +127,17 @@ uint16_t furi_hal_power_insomnia_level() { } void furi_hal_power_insomnia_enter() { - FURI_CRITICAL_ENTER(); - furi_assert(furi_hal_power.insomnia < UINT8_MAX); - furi_hal_power.insomnia++; - FURI_CRITICAL_EXIT(); +// FURI_CRITICAL_ENTER(); +// furi_assert(furi_hal_power.insomnia < UINT8_MAX); +// furi_hal_power.insomnia++; +// FURI_CRITICAL_EXIT(); } void furi_hal_power_insomnia_exit() { - FURI_CRITICAL_ENTER(); - furi_assert(furi_hal_power.insomnia > 0); - furi_hal_power.insomnia--; - FURI_CRITICAL_EXIT(); -} - -bool furi_hal_power_sleep_available() { - return furi_hal_power.insomnia == 0; +// FURI_CRITICAL_ENTER(); +// furi_assert(furi_hal_power.insomnia > 0); +// furi_hal_power.insomnia--; +// FURI_CRITICAL_EXIT(); } #ifdef FURI_HAL_OS_DEBUG @@ -150,7 +147,7 @@ static void furi_hal_power_nvic_dbg_trap() { if(NVIC_GetPendingIRQ(i)) { (void)i; // Break here - asm volatile("bkpt 0"); +// asm volatile("bkpt 0"); } } } @@ -162,13 +159,13 @@ static void furi_hal_power_exti_dbg_trap(uint32_t exti, uint32_t val) { (void)exti; (void)i; // Break here - asm volatile("bkpt 0"); +// asm volatile("bkpt 0"); } } } #endif -bool furi_hal_power_deep_sleep_available() { +bool furi_hal_power_sleep_available() { if(FURI_HAL_POWER_NVIC_IS_PENDING()) { #ifdef FURI_HAL_OS_DEBUG furi_hal_power_nvic_dbg_trap(); @@ -189,18 +186,34 @@ bool furi_hal_power_deep_sleep_available() { return false; } - if(!furi_hal_bt_is_alive() || furi_hal_power.deep_insomnia > 0) { - return false; - } + return furi_hal_power.insomnia == 0; +} - return true; +bool furi_hal_power_deep_sleep_available() { + return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; } void furi_hal_power_light_sleep() { __WFI(); } +static inline void furi_hal_power_suspend_aux_periphs() { + // Disable USART + furi_hal_uart_suspend(FuriHalUartIdUSART1); + furi_hal_uart_suspend(FuriHalUartIdLPUART1); + // TODO: Disable USB +} + +static inline void furi_hal_power_resume_aux_periphs() { + // Re-enable USART + furi_hal_uart_resume(FuriHalUartIdUSART1); + furi_hal_uart_resume(FuriHalUartIdLPUART1); + // TODO: Re-enable USB +} + void furi_hal_power_deep_sleep() { + furi_hal_power_suspend_aux_periphs(); + while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID)) ; @@ -254,6 +267,8 @@ void furi_hal_power_deep_sleep() { } LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0); + + furi_hal_power_resume_aux_periphs(); } void furi_hal_power_sleep() { From d10f38b807f3a162ecce892997ed4298369a5699 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 21:03:20 +0300 Subject: [PATCH 29/37] Improve tick consistency under load --- firmware/targets/f7/Inc/FreeRTOSConfig.h | 2 +- firmware/targets/f7/furi_hal/furi_hal_os.c | 5 ++++- firmware/targets/f7/furi_hal/furi_hal_power.c | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/firmware/targets/f7/Inc/FreeRTOSConfig.h b/firmware/targets/f7/Inc/FreeRTOSConfig.h index e62a6b9fda3..c3b2117c5a8 100644 --- a/firmware/targets/f7/Inc/FreeRTOSConfig.h +++ b/firmware/targets/f7/Inc/FreeRTOSConfig.h @@ -20,7 +20,7 @@ extern uint32_t SystemCoreClock; #define configCPU_CLOCK_HZ (SystemCoreClock) #define configTICK_RATE_HZ ((TickType_t)1000) #define configMAX_PRIORITIES (56) -#define configMINIMAL_STACK_SIZE ((uint16_t)1024) +#define configMINIMAL_STACK_SIZE ((uint16_t)128) /* Heap size determined automatically by linker */ // #define configTOTAL_HEAP_SIZE ((size_t)0) diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 3f387e37ae0..9fae042e370 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -23,6 +23,9 @@ #define FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH (FURI_HAL_OS_IDLE_CNT_TO_TICKS(FURI_HAL_IDLE_TIMER_MAX)) #define FURI_HAL_OS_MAX_SLEEP (FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH - 1) +// Arbitrary (but small) number for better tick consistency +#define FURI_HAL_OS_EXTRA_CNT 3 + #ifdef FURI_HAL_OS_DEBUG #include @@ -77,7 +80,7 @@ static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { #endif // Calculate how much time we spent in the sleep - uint32_t after_cnt = furi_hal_idle_timer_get_cnt() + furi_hal_os_skew; + uint32_t after_cnt = furi_hal_idle_timer_get_cnt() + furi_hal_os_skew + FURI_HAL_OS_EXTRA_CNT; uint32_t after_tick = FURI_HAL_OS_IDLE_CNT_TO_TICKS(after_cnt); furi_hal_os_skew = after_cnt - FURI_HAL_OS_TICKS_TO_IDLE_CNT(after_tick); diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 61e59938c55..a1e022cacb8 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -147,7 +147,7 @@ static void furi_hal_power_nvic_dbg_trap() { if(NVIC_GetPendingIRQ(i)) { (void)i; // Break here -// asm volatile("bkpt 0"); + __NOP(); } } } @@ -159,7 +159,7 @@ static void furi_hal_power_exti_dbg_trap(uint32_t exti, uint32_t val) { (void)exti; (void)i; // Break here -// asm volatile("bkpt 0"); + __NOP(); } } } From 348580469c7ca39770be5d03d201bb309a4b06ed Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 21:26:20 +0300 Subject: [PATCH 30/37] Add USB_HP dummy IRQ handler --- firmware/targets/f7/furi_hal/furi_hal_interrupt.c | 3 +++ firmware/targets/f7/furi_hal/furi_hal_usb.c | 2 ++ 2 files changed, 5 insertions(+) diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 630c51c4c1a..2024f761216 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -248,6 +248,9 @@ void USB_LP_IRQHandler() { #endif } +void USB_HP_IRQHandler() { +} + void IPCC_C1_TX_IRQHandler() { HW_IPCC_Tx_Handler(); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_usb.c b/firmware/targets/f7/furi_hal/furi_hal_usb.c index f1044c36bba..19e5ab00513 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_usb.c +++ b/firmware/targets/f7/furi_hal/furi_hal_usb.c @@ -77,7 +77,9 @@ void furi_hal_usb_init(void) { usb.enabled = false; usb.if_cur = NULL; NVIC_SetPriority(USB_LP_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + NVIC_SetPriority(USB_HP_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); NVIC_EnableIRQ(USB_LP_IRQn); + NVIC_EnableIRQ(USB_HP_IRQn); usb.thread = furi_thread_alloc(); furi_thread_set_name(usb.thread, "UsbDriver"); From d6b22ffef697ecec3b6c428de0440d299e01f24c Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 21:42:57 +0300 Subject: [PATCH 31/37] Move interrupt check closer to sleep --- firmware/targets/f7/furi_hal/furi_hal_os.c | 59 +++++++++++++++++-- firmware/targets/f7/furi_hal/furi_hal_power.c | 50 +--------------- 2 files changed, 56 insertions(+), 53 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index 9fae042e370..e62c55bcade 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -1,11 +1,9 @@ #include -#include #include #include #include #include #include -#include #include #include @@ -23,6 +21,10 @@ #define FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH (FURI_HAL_OS_IDLE_CNT_TO_TICKS(FURI_HAL_IDLE_TIMER_MAX)) #define FURI_HAL_OS_MAX_SLEEP (FURI_HAL_IDLE_TIMER_TICK_PER_EPOCH - 1) +#define FURI_HAL_OS_NVIC_IS_PENDING() (NVIC->ISPR[0] || NVIC->ISPR[1]) +#define FURI_HAL_OS_EXTI_LINE_0_31 0 +#define FURI_HAL_OS_EXTI_LINE_32_63 1 + // Arbitrary (but small) number for better tick consistency #define FURI_HAL_OS_EXTRA_CNT 3 @@ -36,7 +38,7 @@ void furi_hal_os_timer_callback() { extern void xPortSysTickHandler(); -static volatile uint32_t furi_hal_os_skew = 0; +static volatile uint32_t furi_hal_os_skew; void furi_hal_os_init() { furi_hal_idle_timer_init(); @@ -61,6 +63,55 @@ void furi_hal_os_tick() { } } +#ifdef FURI_HAL_OS_DEBUG +// Find out the IRQ number while debugging +static void furi_hal_os_nvic_dbg_trap() { + for(int32_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { + if(NVIC_GetPendingIRQ(i)) { + (void)i; + // Break here + __NOP(); + } + } +} + +// Find out the EXTI line number while debugging +static void furi_hal_os_exti_dbg_trap(uint32_t exti, uint32_t val) { + for(uint32_t i = 0; val; val >>= 1U, ++i) { + if(val & 1U) { + (void)exti; + (void)i; + // Break here + __NOP(); + } + } +} +#endif + +static inline bool furi_hal_os_is_pending_irq() { + if(FURI_HAL_OS_NVIC_IS_PENDING()) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_os_nvic_dbg_trap(); +#endif + return true; + } + + uint32_t exti_lines_active; + if((exti_lines_active = LL_EXTI_ReadFlag_0_31(LL_EXTI_LINE_ALL_0_31))) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_os_exti_dbg_trap(FURI_HAL_OS_EXTI_LINE_0_31, exti_lines_active); +#endif + return true; + } else if((exti_lines_active = LL_EXTI_ReadFlag_32_63(LL_EXTI_LINE_ALL_32_63))) { +#ifdef FURI_HAL_OS_DEBUG + furi_hal_os_exti_dbg_trap(FURI_HAL_OS_EXTI_LINE_32_63, exti_lines_active); +#endif + return true; + } + + return false; +} + static inline uint32_t furi_hal_os_sleep(TickType_t expected_idle_ticks) { // Stop ticks furi_hal_clock_suspend_tick(); @@ -111,7 +162,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { __disable_irq(); // Confirm OS that sleep is still possible - if(eTaskConfirmSleepModeStatus() == eAbortSleep) { + if(eTaskConfirmSleepModeStatus() == eAbortSleep || furi_hal_os_is_pending_irq()) { __enable_irq(); return; } diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index a1e022cacb8..852f0e4bd0d 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -19,9 +19,6 @@ #include #define TAG "FuriHalPower" -#define FURI_HAL_POWER_NVIC_IS_PENDING() (NVIC->ISPR[0] || NVIC->ISPR[1]) -#define FURI_HAL_POWER_EXTI_LINE_0_31 0 -#define FURI_HAL_POWER_EXTI_LINE_32_63 1 #ifdef FURI_HAL_POWER_DEEP_SLEEP_ENABLED #define FURI_HAL_POWER_DEEP_INSOMNIA 0 @@ -140,57 +137,12 @@ void furi_hal_power_insomnia_exit() { // FURI_CRITICAL_EXIT(); } -#ifdef FURI_HAL_OS_DEBUG -// Find out the IRQ number while debugging -static void furi_hal_power_nvic_dbg_trap() { - for(int32_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) { - if(NVIC_GetPendingIRQ(i)) { - (void)i; - // Break here - __NOP(); - } - } -} - -// Find out the EXTI line number while debugging -static void furi_hal_power_exti_dbg_trap(uint32_t exti, uint32_t val) { - for(uint32_t i = 0; val; val >>= 1U, ++i) { - if(val & 1U) { - (void)exti; - (void)i; - // Break here - __NOP(); - } - } -} -#endif - bool furi_hal_power_sleep_available() { - if(FURI_HAL_POWER_NVIC_IS_PENDING()) { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_power_nvic_dbg_trap(); -#endif - return false; - } - - uint32_t exti_lines_active; - if((exti_lines_active = LL_EXTI_ReadFlag_0_31(LL_EXTI_LINE_ALL_0_31))) { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_power_exti_dbg_trap(FURI_HAL_POWER_EXTI_LINE_0_31, exti_lines_active); -#endif - return false; - } else if((exti_lines_active = LL_EXTI_ReadFlag_32_63(LL_EXTI_LINE_ALL_32_63))) { -#ifdef FURI_HAL_OS_DEBUG - furi_hal_power_exti_dbg_trap(FURI_HAL_POWER_EXTI_LINE_32_63, exti_lines_active); -#endif - return false; - } - return furi_hal_power.insomnia == 0; } bool furi_hal_power_deep_sleep_available() { - return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; + return furi_hal_bt_is_alive() && furi_hal_power.deep_insomnia == 0; } void furi_hal_power_light_sleep() { From e5bfdcb11b162a2d4d26fb8b7ae544bf87fe9f36 Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 21:49:31 +0300 Subject: [PATCH 32/37] Clean up includes --- firmware/targets/f7/furi_hal/furi_hal_os.c | 1 - firmware/targets/f7/furi_hal/furi_hal_power.c | 2 -- 2 files changed, 3 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_os.c b/firmware/targets/f7/furi_hal/furi_hal_os.c index e62c55bcade..8beb0d084cb 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_os.c +++ b/firmware/targets/f7/furi_hal/furi_hal_os.c @@ -1,5 +1,4 @@ #include -#include #include #include #include diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 852f0e4bd0d..1f107e1625a 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -10,7 +9,6 @@ #include #include #include -#include #include #include From b6c96d2987850fb5df61373d7c6a781bc6a6733e Mon Sep 17 00:00:00 2001 From: Georgii Surkov Date: Thu, 28 Apr 2022 21:51:55 +0300 Subject: [PATCH 33/37] Re-enable Insomnia globally --- firmware/targets/f7/furi_hal/furi_hal_power.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c index 1f107e1625a..52bb7bcfe31 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_power.c +++ b/firmware/targets/f7/furi_hal/furi_hal_power.c @@ -122,17 +122,17 @@ uint16_t furi_hal_power_insomnia_level() { } void furi_hal_power_insomnia_enter() { -// FURI_CRITICAL_ENTER(); -// furi_assert(furi_hal_power.insomnia < UINT8_MAX); -// furi_hal_power.insomnia++; -// FURI_CRITICAL_EXIT(); + FURI_CRITICAL_ENTER(); + furi_assert(furi_hal_power.insomnia < UINT8_MAX); + furi_hal_power.insomnia++; + FURI_CRITICAL_EXIT(); } void furi_hal_power_insomnia_exit() { -// FURI_CRITICAL_ENTER(); -// furi_assert(furi_hal_power.insomnia > 0); -// furi_hal_power.insomnia--; -// FURI_CRITICAL_EXIT(); + FURI_CRITICAL_ENTER(); + furi_assert(furi_hal_power.insomnia > 0); + furi_hal_power.insomnia--; + FURI_CRITICAL_EXIT(); } bool furi_hal_power_sleep_available() { From 07324483386740dcc9cac285b15428402bfb2f0f Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 29 Apr 2022 15:25:47 +0300 Subject: [PATCH 34/37] FuriHal: enable CSS --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index ea60388cad7..ebe8af78d98 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -62,6 +62,7 @@ void furi_hal_clock_init() { LL_RCC_HSI_Enable(); while(!HS_CLOCK_IS_READY()) ; + LL_RCC_HSE_EnableCSS(); /* LSE and LSI1 configuration and activation */ LL_PWR_EnableBkUpAccess(); @@ -73,6 +74,8 @@ void furi_hal_clock_init() { LL_EXTI_EnableIT_0_31( LL_EXTI_LINE_18); /* Why? Because that's why. See RM0434, Table 61. CPU1 vector table. */ LL_EXTI_EnableRisingTrig_0_31(LL_EXTI_LINE_18); + LL_RCC_EnableIT_LSECSS(); + LL_RCC_LSE_EnableCSS(); /* Main PLL configuration and activation */ LL_RCC_PLL_ConfigDomain_SYS(LL_RCC_PLLSOURCE_HSE, LL_RCC_PLLM_DIV_2, 8, LL_RCC_PLLR_DIV_2); From 1e3b83a4fbe80823469dd6d42d9b5e58215f8cf4 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 29 Apr 2022 15:30:18 +0300 Subject: [PATCH 35/37] FuriHal: remove questionable core2 clock shenanigans --- firmware/targets/f7/furi_hal/furi_hal_clock.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_clock.c b/firmware/targets/f7/furi_hal/furi_hal_clock.c index ebe8af78d98..09efe76dd13 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_clock.c +++ b/firmware/targets/f7/furi_hal/furi_hal_clock.c @@ -205,8 +205,6 @@ void furi_hal_clock_switch_to_hsi() { while(LL_RCC_GetSysClkSource() != LL_RCC_SYS_CLKSOURCE_STATUS_HSI) ; - LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_1); - LL_FLASH_SetLatency(LL_FLASH_LATENCY_1); } @@ -221,7 +219,6 @@ void furi_hal_clock_switch_to_pll() { LL_FLASH_SetLatency(LL_FLASH_LATENCY_3); - LL_C2_RCC_SetAHBPrescaler(LL_RCC_SYSCLK_DIV_2); LL_RCC_SetSysClkSource(LL_RCC_SYS_CLKSOURCE_PLL); LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE); From 40e52f22e7e6eba7055cb312aa9e92a64187a72c Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 29 Apr 2022 15:32:49 +0300 Subject: [PATCH 36/37] FuriHal: use core1 RCC registers in idle timer config --- firmware/targets/f7/furi_hal/furi_hal_idle_timer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h b/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h index a165441527a..36b45755a92 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h +++ b/firmware/targets/f7/furi_hal/furi_hal_idle_timer.h @@ -14,7 +14,7 @@ static inline void furi_hal_idle_timer_init() { // Configure clock source LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE); // There is a theoretical possibility that we need it - LL_C2_APB1_GRP1_EnableClockSleep(LL_C2_APB1_GRP1_PERIPH_LPTIM1); + LL_APB1_GRP1_EnableClockSleep(LL_APB1_GRP1_PERIPH_LPTIM1); // Set interrupt priority and enable them NVIC_SetPriority( FURI_HAL_IDLE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); From 08fe172ad7e3873495e50e7beb759a247c1dbdd6 Mon Sep 17 00:00:00 2001 From: Aleksandr Kutuzov Date: Fri, 29 Apr 2022 15:44:46 +0300 Subject: [PATCH 37/37] FuriHal: return back CSS handlers, add lptim isr dispatching --- .../targets/f7/furi_hal/furi_hal_interrupt.c | 29 +++++++++++++++++-- .../targets/f7/furi_hal/furi_hal_interrupt.h | 4 +++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c index 2024f761216..526c9f3daea 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.c +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.c @@ -54,6 +54,10 @@ const IRQn_Type furi_hal_interrupt_irqn[FuriHalInterruptIdMax] = { // HSEM [FuriHalInterruptIdHsem] = HSEM_IRQn, + + // LPTIMx + [FuriHalInterruptIdLpTim1] = LPTIM1_IRQn, + [FuriHalInterruptIdLpTim2] = LPTIM2_IRQn, }; __attribute__((always_inline)) static inline void @@ -76,6 +80,10 @@ __attribute__((always_inline)) static inline void } void furi_hal_interrupt_init() { + NVIC_SetPriority( + TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); + NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); + NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); NVIC_SetPriority(FPU_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); @@ -205,11 +213,28 @@ void HSEM_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdHsem); } +void TAMP_STAMP_LSECSS_IRQHandler(void) { + if(LL_RCC_IsActiveFlag_LSECSS()) { + LL_RCC_ClearFlag_LSECSS(); + if(!LL_RCC_LSE_IsReady()) { + FURI_LOG_E(TAG, "LSE CSS fired: resetting system"); + NVIC_SystemReset(); + } else { + FURI_LOG_E(TAG, "LSE CSS fired: but LSE is alive"); + } + } +} + void RCC_IRQHandler() { furi_hal_interrupt_call(FuriHalInterruptIdRcc); } void NMI_Handler() { + if(LL_RCC_IsActiveFlag_HSECSS()) { + LL_RCC_ClearFlag_HSECSS(); + FURI_LOG_E(TAG, "HSE CSS fired: resetting system"); + NVIC_SystemReset(); + } } void HardFault_Handler() { @@ -264,9 +289,9 @@ void FPU_IRQHandler() { } void LPTIM1_IRQHandler() { - furi_crash("LPTIM1"); + furi_hal_interrupt_call(FuriHalInterruptIdLpTim1); } void LPTIM2_IRQHandler() { - furi_crash("LPTIM2"); + furi_hal_interrupt_call(FuriHalInterruptIdLpTim2); } diff --git a/firmware/targets/f7/furi_hal/furi_hal_interrupt.h b/firmware/targets/f7/furi_hal/furi_hal_interrupt.h index 725e779e03a..8a280ff8d68 100644 --- a/firmware/targets/f7/furi_hal/furi_hal_interrupt.h +++ b/firmware/targets/f7/furi_hal/furi_hal_interrupt.h @@ -45,6 +45,10 @@ typedef enum { // HSEM FuriHalInterruptIdHsem, + // LPTIMx + FuriHalInterruptIdLpTim1, + FuriHalInterruptIdLpTim2, + // Service value FuriHalInterruptIdMax, } FuriHalInterruptId;