Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/ClusterM/flipperzero-firmware.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorあく <alleteam@gmail.com>2022-07-04 17:26:02 +0300
committerGitHub <noreply@github.com>2022-07-04 17:26:02 +0300
commitc495677eb5c202280c7a904594479e4dc8879ed5 (patch)
tree3fe6eea27f5a6ab80d4e63c6319f1a4a864c7719 /firmware
parentb95cd2df143d20a5dc5a236e83b455a4c7d2d9b1 (diff)
FuriHal: RTC recovery routine and ext3v3 enabled on start (#1357)
* FuriHal: leave ext3v3 enabled on start * FuriHal: RTC recovery routine, cleanup resources Co-authored-by: SG <who.just.the.doctor@gmail.com>
Diffstat (limited to 'firmware')
-rw-r--r--firmware/targets/f7/furi_hal/furi_hal_power.c9
-rw-r--r--firmware/targets/f7/furi_hal/furi_hal_resources.c8
-rw-r--r--firmware/targets/f7/furi_hal/furi_hal_resources.h3
-rw-r--r--firmware/targets/f7/furi_hal/furi_hal_rtc.c106
4 files changed, 87 insertions, 39 deletions
diff --git a/firmware/targets/f7/furi_hal/furi_hal_power.c b/firmware/targets/f7/furi_hal/furi_hal_power.c
index 52bb7bcf..28e6cb05 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_power.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_power.c
@@ -1,5 +1,6 @@
#include <furi_hal_power.h>
#include <furi_hal_clock.h>
+#include <furi_hal_delay.h>
#include <furi_hal_bt.h>
#include <furi_hal_resources.h>
#include <furi_hal_uart.h>
@@ -299,6 +300,10 @@ void furi_hal_power_shutdown() {
}
void furi_hal_power_off() {
+ // Crutch: shutting down with ext 3V3 off is causing LSE to stop
+ furi_hal_power_enable_external_3_3v();
+ furi_hal_delay_us(1000);
+ // Send poweroff to charger
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
bq25896_poweroff(&furi_hal_i2c_handle_power);
furi_hal_i2c_release(&furi_hal_i2c_handle_power);
@@ -482,11 +487,11 @@ void furi_hal_power_dump_state() {
}
void furi_hal_power_enable_external_3_3v() {
- LL_GPIO_SetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin);
+ furi_hal_gpio_write(&periph_power, 1);
}
void furi_hal_power_disable_external_3_3v() {
- LL_GPIO_ResetOutputPin(PERIPH_POWER_GPIO_Port, PERIPH_POWER_Pin);
+ furi_hal_gpio_write(&periph_power, 0);
}
void furi_hal_power_suppress_charge_enter() {
diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.c b/firmware/targets/f7/furi_hal/furi_hal_resources.c
index 21fac834..c1238212 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_resources.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_resources.c
@@ -58,7 +58,7 @@ const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9};
const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8};
-const GpioPin periph_power = {.port = PERIPH_POWER_GPIO_Port, .pin = PERIPH_POWER_Pin};
+const GpioPin periph_power = {.port = GPIOA, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_usb_dm = {.port = GPIOA, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_usb_dp = {.port = GPIOA, .pin = LL_GPIO_PIN_12};
@@ -77,6 +77,10 @@ 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);
+ // SD Card stepdown control
+ furi_hal_gpio_write(&periph_power, 1);
+ furi_hal_gpio_init(&periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
+
// Display pins
furi_hal_gpio_write(&gpio_display_rst_n, 1);
furi_hal_gpio_init_simple(&gpio_display_rst_n, GpioModeOutputPushPull);
@@ -142,8 +146,6 @@ void furi_hal_resources_init() {
furi_hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
- furi_hal_gpio_init(&periph_power, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);
-
NVIC_SetPriority(EXTI0_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(EXTI0_IRQn);
diff --git a/firmware/targets/f7/furi_hal/furi_hal_resources.h b/firmware/targets/f7/furi_hal/furi_hal_resources.h
index 820760a1..d16c567e 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_resources.h
+++ b/firmware/targets/f7/furi_hal/furi_hal_resources.h
@@ -147,9 +147,6 @@ extern const GpioPin gpio_usb_dp;
#define PC3_GPIO_Port GPIOC
#define PC3_Pin LL_GPIO_PIN_3
-#define PERIPH_POWER_GPIO_Port GPIOA
-#define PERIPH_POWER_Pin LL_GPIO_PIN_3
-
#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC
#define QUARTZ_32MHZ_IN_Pin LL_GPIO_PIN_14
#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC
diff --git a/firmware/targets/f7/furi_hal/furi_hal_rtc.c b/firmware/targets/f7/furi_hal/furi_hal_rtc.c
index df410a9f..24dad38f 100644
--- a/firmware/targets/f7/furi_hal/furi_hal_rtc.c
+++ b/firmware/targets/f7/furi_hal/furi_hal_rtc.c
@@ -12,7 +12,9 @@
#define TAG "FuriHalRtc"
-#define RTC_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady())
+#define FURI_HAL_RTC_LSE_STARTUP_TIME 300
+
+#define FURI_HAL_RTC_CLOCK_IS_READY() (LL_RCC_LSE_IsReady() && LL_RCC_LSI1_IsReady())
#define FURI_HAL_RTC_HEADER_MAGIC 0x10F1
#define FURI_HAL_RTC_HEADER_VERSION 0
@@ -47,33 +49,83 @@ static const uint8_t furi_hal_rtc_days_per_month[][FURI_HAL_RTC_MONTHS_COUNT] =
static const uint16_t furi_hal_rtc_days_per_year[] = {365, 366};
-void furi_hal_rtc_init_early() {
- // LSE and RTC
+static void furi_hal_rtc_reset() {
+ LL_RCC_ForceBackupDomainReset();
+ LL_RCC_ReleaseBackupDomainReset();
+}
+
+static bool furi_hal_rtc_start_clock_and_switch() {
+ // Clock operation require access to Backup Domain
LL_PWR_EnableBkUpAccess();
- if(!RTC_CLOCK_IS_READY()) {
- LL_RCC_LSI1_Enable();
- // Try to start LSE normal way
- LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
- LL_RCC_LSE_Enable();
- uint32_t c = 0;
- while(!RTC_CLOCK_IS_READY() && c < 200) {
- LL_mDelay(10);
- c++;
- }
- // Plan B: reset backup domain
- if(!RTC_CLOCK_IS_READY()) {
- furi_hal_light_sequence("rgb R.r.R.r.R");
- LL_RCC_ForceBackupDomainReset();
- LL_RCC_ReleaseBackupDomainReset();
- NVIC_SystemReset();
- }
- // Set RTC domain clock to LSE
+
+ // Enable LSI and LSE
+ LL_RCC_LSI1_Enable();
+ LL_RCC_LSE_SetDriveCapability(LL_RCC_LSEDRIVE_HIGH);
+ LL_RCC_LSE_Enable();
+
+ // Wait for LSI and LSE startup
+ uint32_t c = 0;
+ while(!FURI_HAL_RTC_CLOCK_IS_READY() && c < FURI_HAL_RTC_LSE_STARTUP_TIME) {
+ LL_mDelay(1);
+ c++;
+ }
+
+ if(FURI_HAL_RTC_CLOCK_IS_READY()) {
LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
+ LL_RCC_EnableRTC();
+ return LL_RCC_GetRTCClockSource() == LL_RCC_RTC_CLKSOURCE_LSE;
+ } else {
+ return false;
+ }
+}
+
+static void furi_hal_rtc_recover() {
+ FuriHalRtcDateTime datetime = {0};
+
+ // Handle fixable LSE failure
+ if(LL_RCC_LSE_IsCSSDetected()) {
+ furi_hal_light_sequence("rgb B");
+ // Shutdown LSE and LSECSS
+ LL_RCC_LSE_DisableCSS();
+ LL_RCC_LSE_Disable();
+ } else {
+ furi_hal_light_sequence("rgb R");
}
- // Enable clocking
- LL_RCC_EnableRTC();
+
+ // Temporary switch to LSI
+ LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI);
+ if(LL_RCC_GetRTCClockSource() == LL_RCC_RTC_CLKSOURCE_LSI) {
+ // Get datetime before RTC Domain reset
+ furi_hal_rtc_get_datetime(&datetime);
+ }
+
+ // Reset RTC Domain
+ furi_hal_rtc_reset();
+
+ // Start Clock
+ if(!furi_hal_rtc_start_clock_and_switch()) {
+ // Plan C: reset RTC and restart
+ furi_hal_light_sequence("rgb R.r.R.r.R.r");
+ furi_hal_rtc_reset();
+ NVIC_SystemReset();
+ }
+
+ // Set date if it valid
+ if(datetime.year != 0) {
+ furi_hal_rtc_set_datetime(&datetime);
+ }
+}
+
+void furi_hal_rtc_init_early() {
+ // Enable RTCAPB clock
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
+ // Prepare clock
+ if(!furi_hal_rtc_start_clock_and_switch()) {
+ // Plan B: try to recover
+ furi_hal_rtc_recover();
+ }
+
// Verify header register
uint32_t data_reg = furi_hal_rtc_get_register(FuriHalRtcRegisterHeader);
FuriHalRtcHeader* data = (FuriHalRtcHeader*)&data_reg;
@@ -98,14 +150,6 @@ void furi_hal_rtc_deinit_early() {
}
void furi_hal_rtc_init() {
- if(LL_RCC_GetRTCClockSource() != LL_RCC_RTC_CLKSOURCE_LSE) {
- LL_RCC_ForceBackupDomainReset();
- LL_RCC_ReleaseBackupDomainReset();
- LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE);
- }
-
- LL_RCC_EnableRTC();
-
LL_RTC_InitTypeDef RTC_InitStruct = {0};
RTC_InitStruct.HourFormat = LL_RTC_HOURFORMAT_24HOUR;
RTC_InitStruct.AsynchPrescaler = 127;