Merge branch 'ul-dev' into xfw-dev

This commit is contained in:
Willy-JL
2023-04-23 17:48:05 +01:00
170 changed files with 3650 additions and 1489 deletions

View File

@@ -63,6 +63,10 @@ void furi_hal_clock_init() {
LL_RCC_HSI_Enable();
while(!HS_CLOCK_IS_READY())
;
/* Select HSI as system clock source after Wake Up from Stop mode
* Must be set before enabling CSS */
LL_RCC_SetClkAfterWakeFromStop(LL_RCC_STOP_WAKEUPCLOCK_HSI);
LL_RCC_HSE_EnableCSS();
/* LSE and LSI1 configuration and activation */
@@ -215,11 +219,14 @@ void furi_hal_clock_switch_to_hsi() {
void furi_hal_clock_switch_to_pll() {
LL_RCC_HSE_Enable();
LL_RCC_PLL_Enable();
LL_RCC_PLLSAI1_Enable();
while(!LL_RCC_HSE_IsReady())
;
while(!LL_RCC_PLL_IsReady())
;
while(!LL_RCC_PLLSAI1_IsReady())
;
LL_FLASH_SetLatency(LL_FLASH_LATENCY_3);
@@ -296,4 +303,4 @@ void furi_hal_clock_mco_disable() {
LL_RCC_MSI_Disable();
while(LL_RCC_MSI_IsReady() != 0)
;
}
}

View File

@@ -3,12 +3,26 @@
#include <stm32wbxx_ll_exti.h>
#include <stm32wbxx_ll_system.h>
#include <furi_hal_gpio.h>
#include <furi_hal_resources.h>
volatile bool furi_hal_debug_gdb_session_active = false;
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);
// SWD GPIO
furi_hal_gpio_init_ex(
&gpio_swdio,
GpioModeAltFunctionPushPull,
GpioPullUp,
GpioSpeedVeryHigh,
GpioAltFn0JTMS_SWDIO);
furi_hal_gpio_init_ex(
&gpio_swclk, GpioModeAltFunctionPushPull, GpioPullDown, GpioSpeedLow, GpioAltFn0JTCK_SWCLK);
}
void furi_hal_debug_disable() {
@@ -17,4 +31,11 @@ void furi_hal_debug_disable() {
LL_DBGMCU_DisableDBGStopMode();
LL_DBGMCU_DisableDBGStandbyMode();
LL_EXTI_DisableIT_32_63(LL_EXTI_LINE_48);
// SWD GPIO
furi_hal_gpio_init_simple(&gpio_swdio, GpioModeAnalog);
furi_hal_gpio_init_simple(&gpio_swclk, GpioModeAnalog);
}
bool furi_hal_debug_is_gdb_session_active() {
return furi_hal_debug_gdb_session_active;
}

View File

@@ -1,5 +1,7 @@
#include <furi_hal_flash.h>
#include <furi_hal_bt.h>
#include <furi_hal_power.h>
#include <furi_hal_cortex.h>
#include <furi.h>
#include <ble/ble.h>
#include <interface/patterns/ble_thread/shci/shci.h>
@@ -25,6 +27,16 @@
#define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F
#define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2))
/* lib/STM32CubeWB/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash/Core/Src/flash_driver.c
* ProcessSingleFlashOperation, quote:
> In most BLE application, the flash should not be blocked by the CPU2 longer than FLASH_TIMEOUT_VALUE (1000ms)
> However, it could be that for some marginal application, this time is longer.
> ... there is no other way than waiting the operation to be completed.
> If for any reason this test is never passed, this means there is a failure in the system and there is no other
> way to recover than applying a device reset.
*/
#define FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS 3000u /* 3 seconds */
#define IS_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL))
#define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \
(((__VALUE__) >= FLASH_BASE) && ((__VALUE__) <= (FLASH_BASE + FLASH_SIZE - 8UL)) && \
@@ -114,6 +126,7 @@ static void furi_hal_flash_lock(void) {
}
static void furi_hal_flash_begin_with_core2(bool erase_flag) {
furi_hal_power_insomnia_enter();
/* Take flash controller ownership */
while(LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID) != 0) {
furi_thread_yield();
@@ -129,9 +142,11 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
for(volatile uint32_t i = 0; i < 35; i++)
;
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(FURI_HAL_FLASH_C2_LOCK_TIMEOUT_MS * 1000);
while(true) {
/* Wait till flash controller become usable */
while(LL_FLASH_IsActiveFlag_OperationSuspended()) {
furi_check(!furi_hal_cortex_timer_is_expired(timer));
furi_thread_yield();
};
@@ -141,6 +156,7 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
/* Actually we already have mutex for it, but specification is specification */
if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) {
taskEXIT_CRITICAL();
furi_check(!furi_hal_cortex_timer_is_expired(timer));
furi_thread_yield();
continue;
}
@@ -148,6 +164,7 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
/* Take sempahopre and prevent core2 from anything funky */
if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) {
taskEXIT_CRITICAL();
furi_check(!furi_hal_cortex_timer_is_expired(timer));
furi_thread_yield();
continue;
}
@@ -188,6 +205,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) {
/* Release flash controller ownership */
LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0);
furi_hal_power_insomnia_exit();
}
static void furi_hal_flash_end(bool erase_flag) {
@@ -228,17 +246,13 @@ static void furi_hal_flush_cache(void) {
bool furi_hal_flash_wait_last_operation(uint32_t timeout) {
uint32_t error = 0;
uint32_t countdown = 0;
/* Wait for the FLASH operation to complete by polling on BUSY flag to be reset.
Even if the FLASH operation fails, the BUSY flag will be reset and an error
flag will be set */
countdown = timeout;
FuriHalCortexTimer timer = furi_hal_cortex_timer_get(timeout * 1000);
while(READ_BIT(FLASH->SR, FLASH_SR_BSY)) {
if(LL_SYSTICK_IsActiveCounterFlag()) {
countdown--;
}
if(countdown == 0) {
if(furi_hal_cortex_timer_is_expired(timer)) {
return false;
}
}
@@ -261,12 +275,9 @@ bool furi_hal_flash_wait_last_operation(uint32_t timeout) {
CLEAR_BIT(FLASH->SR, error);
/* Wait for control register to be written */
countdown = timeout;
timer = furi_hal_cortex_timer_get(timeout * 1000);
while(READ_BIT(FLASH->SR, FLASH_SR_CFGBSY)) {
if(LL_SYSTICK_IsActiveCounterFlag()) {
countdown--;
}
if(countdown == 0) {
if(furi_hal_cortex_timer_is_expired(timer)) {
return false;
}
}

View File

@@ -178,10 +178,13 @@ void furi_hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, vo
FURI_CRITICAL_ENTER();
uint8_t pin_num = furi_hal_gpio_get_pin_num(gpio);
furi_assert(gpio_interrupt[pin_num].callback == NULL);
gpio_interrupt[pin_num].callback = cb;
gpio_interrupt[pin_num].context = ctx;
gpio_interrupt[pin_num].ready = true;
volatile GpioInterrupt* interrupt = &gpio_interrupt[pin_num];
furi_check(
(interrupt->callback == NULL) ||
((interrupt->callback == cb) && (interrupt->context == ctx)));
interrupt->callback = cb;
interrupt->context = ctx;
interrupt->ready = true;
FURI_CRITICAL_EXIT();
}

View File

@@ -570,9 +570,9 @@ static void furi_hal_infrared_async_tx_free_resources(void) {
(furi_hal_infrared_state == InfraredStateAsyncTxStopped));
if(infrared_external_output) {
furi_hal_gpio_init(&gpio_ext_pa7, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow);
furi_hal_gpio_init(&gpio_ext_pa7, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
} else {
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow);
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
}
furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL);
furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL);

View File

@@ -28,11 +28,24 @@
// Arbitrary (but small) number for better tick consistency
#define FURI_HAL_OS_EXTRA_CNT 3
#ifndef FURI_HAL_OS_DEBUG_AWAKE_GPIO
#define FURI_HAL_OS_DEBUG_AWAKE_GPIO (&gpio_ext_pa7)
#endif
#ifndef FURI_HAL_OS_DEBUG_TICK_GPIO
#define FURI_HAL_OS_DEBUG_TICK_GPIO (&gpio_ext_pa6)
#endif
#ifndef FURI_HAL_OS_DEBUG_SECOND_GPIO
#define FURI_HAL_OS_DEBUG_SECOND_GPIO (&gpio_ext_pa4)
#endif
#ifdef FURI_HAL_OS_DEBUG
#include <stm32wbxx_ll_gpio.h>
void furi_hal_os_timer_callback() {
furi_hal_gpio_write(&gpio_ext_pa4, !furi_hal_gpio_read(&gpio_ext_pa4));
furi_hal_gpio_write(
FURI_HAL_OS_DEBUG_SECOND_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_SECOND_GPIO));
}
#endif
@@ -44,9 +57,11 @@ void furi_hal_os_init() {
furi_hal_idle_timer_init();
#ifdef FURI_HAL_OS_DEBUG
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);
furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_AWAKE_GPIO, GpioModeOutputPushPull);
furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_TICK_GPIO, GpioModeOutputPushPull);
furi_hal_gpio_init_simple(FURI_HAL_OS_DEBUG_SECOND_GPIO, GpioModeOutputPushPull);
furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1);
FuriTimer* second_timer =
furi_timer_alloc(furi_hal_os_timer_callback, FuriTimerTypePeriodic, NULL);
furi_timer_start(second_timer, FURI_HAL_OS_TICK_HZ);
@@ -58,7 +73,8 @@ void furi_hal_os_init() {
void furi_hal_os_tick() {
if(xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED) {
#ifdef FURI_HAL_OS_DEBUG
furi_hal_gpio_write(&gpio_ext_pa6, !furi_hal_gpio_read(&gpio_ext_pa6));
furi_hal_gpio_write(
FURI_HAL_OS_DEBUG_TICK_GPIO, !furi_hal_gpio_read(FURI_HAL_OS_DEBUG_TICK_GPIO));
#endif
xPortSysTickHandler();
}
@@ -121,14 +137,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
furi_hal_gpio_write(&gpio_ext_pa7, 0);
furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 0);
#endif
// Go to sleep mode
furi_hal_power_sleep();
#ifdef FURI_HAL_OS_DEBUG
furi_hal_gpio_write(&gpio_ext_pa7, 1);
furi_hal_gpio_write(FURI_HAL_OS_DEBUG_AWAKE_GPIO, 1);
#endif
// Calculate how much time we spent in the sleep

View File

@@ -4,6 +4,8 @@
#include <furi_hal_vibro.h>
#include <furi_hal_resources.h>
#include <furi_hal_uart.h>
#include <furi_hal_rtc.h>
#include <furi_hal_debug.h>
#include <stm32wbxx_ll_rcc.h>
#include <stm32wbxx_ll_pwr.h>
@@ -19,15 +21,24 @@
#define TAG "FuriHalPower"
#ifdef FURI_HAL_POWER_DEEP_SLEEP_ENABLED
#define FURI_HAL_POWER_DEEP_INSOMNIA 0
#else
#define FURI_HAL_POWER_DEEP_INSOMNIA 1
#ifndef FURI_HAL_POWER_DEBUG_WFI_GPIO
#define FURI_HAL_POWER_DEBUG_WFI_GPIO (&gpio_ext_pb2)
#endif
#ifndef FURI_HAL_POWER_DEBUG_STOP_GPIO
#define FURI_HAL_POWER_DEBUG_STOP_GPIO (&gpio_ext_pc3)
#endif
#ifndef FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO
#define FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO (&gpio_ext_pb3)
#endif
#ifndef FURI_HAL_POWER_STOP_MODE
#define FURI_HAL_POWER_STOP_MODE (LL_PWR_MODE_STOP2)
#endif
typedef struct {
volatile uint8_t insomnia;
volatile uint8_t deep_insomnia;
volatile uint8_t suppress_charge;
uint8_t gauge_initialized;
@@ -36,7 +47,6 @@ typedef struct {
static volatile FuriHalPower furi_hal_power = {
.insomnia = 0,
.deep_insomnia = FURI_HAL_POWER_DEEP_INSOMNIA,
.suppress_charge = 0,
};
@@ -79,19 +89,25 @@ const ParamCEDV cedv = {
};
void furi_hal_power_init() {
#ifdef FURI_HAL_POWER_DEBUG
furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_WFI_GPIO, GpioModeOutputPushPull);
furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_STOP_GPIO, GpioModeOutputPushPull);
furi_hal_gpio_init_simple(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, GpioModeOutputPushPull);
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0);
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0);
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, 0);
#endif
LL_PWR_SetRegulVoltageScaling(LL_PWR_REGU_VOLTAGE_SCALE1);
LL_PWR_SMPS_SetMode(LL_PWR_SMPS_STEP_DOWN);
LL_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);
LL_C2_PWR_SetPowerMode(FURI_HAL_POWER_STOP_MODE);
furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
bq27220_init(&furi_hal_i2c_handle_power, &cedv);
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");
}
@@ -140,11 +156,14 @@ bool furi_hal_power_sleep_available() {
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;
static inline bool furi_hal_power_deep_sleep_available() {
return furi_hal_bt_is_alive() && !furi_hal_rtc_is_flag_set(FuriHalRtcFlagLegacySleep) &&
!furi_hal_debug_is_gdb_session_active() && !LL_PWR_IsActiveFlag_CRPE() &&
!LL_PWR_IsActiveFlag_CRP() && !LL_PWR_IsActiveFlag_BLEA() &&
!LL_PWR_IsActiveFlag_BLEWU();
}
void furi_hal_power_light_sleep() {
static inline void furi_hal_power_light_sleep() {
__WFI();
}
@@ -152,17 +171,15 @@ 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() {
static inline void furi_hal_power_deep_sleep() {
furi_hal_power_suspend_aux_periphs();
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RCC_SEMID))
@@ -187,8 +204,6 @@ void furi_hal_power_deep_sleep() {
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
// Prepare deep sleep
LL_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
LL_C2_PWR_SetPowerMode(LL_PWR_MODE_STOP2);
LL_LPM_EnableDeepSleep();
#if defined(__CC_ARM)
@@ -196,17 +211,19 @@ void furi_hal_power_deep_sleep() {
__force_stores();
#endif
__WFI();
bool should_abort_sleep = LL_PWR_IsActiveFlag_CRPE() || LL_PWR_IsActiveFlag_CRP() ||
LL_PWR_IsActiveFlag_BLEA() || LL_PWR_IsActiveFlag_BLEWU();
if(should_abort_sleep) {
#ifdef FURI_HAL_POWER_DEBUG
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_ABNORMAL_GPIO, 1);
#endif
} else {
__WFI();
}
LL_LPM_EnableSleep();
// 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);
@@ -220,28 +237,25 @@ void furi_hal_power_deep_sleep() {
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RCC_SEMID, 0);
furi_hal_power_resume_aux_periphs();
furi_hal_rtc_sync_shadow();
}
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);
#ifdef FURI_HAL_POWER_DEBUG
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 1);
#endif
furi_hal_power_deep_sleep();
#ifdef FURI_HAL_OS_DEBUG
furi_hal_gpio_write(&gpio_ext_pc3, 0);
#ifdef FURI_HAL_POWER_DEBUG
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_STOP_GPIO, 0);
#endif
} else {
#ifdef FURI_HAL_OS_DEBUG
furi_hal_gpio_write(&gpio_ext_pb2, 1);
#ifdef FURI_HAL_POWER_DEBUG
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 1);
#endif
furi_hal_power_light_sleep();
#ifdef FURI_HAL_OS_DEBUG
furi_hal_gpio_write(&gpio_ext_pb2, 0);
#ifdef FURI_HAL_POWER_DEBUG
furi_hal_gpio_write(FURI_HAL_POWER_DEBUG_WFI_GPIO, 0);
#endif
}
}

View File

@@ -9,19 +9,35 @@
#define TAG "FuriHalRandom"
static uint32_t furi_hal_random_read_rng() {
while(LL_RNG_IsActiveFlag_CECS(RNG) && LL_RNG_IsActiveFlag_SECS(RNG) &&
!LL_RNG_IsActiveFlag_DRDY(RNG)) {
/* Error handling as described in RM0434, pg. 582-583 */
if(LL_RNG_IsActiveFlag_CECS(RNG)) {
/* Clock error occurred */
LL_RNG_ClearFlag_CEIS(RNG);
}
if(LL_RNG_IsActiveFlag_SECS(RNG)) {
/* Noise source error occurred */
LL_RNG_ClearFlag_SEIS(RNG);
for(uint32_t i = 0; i < 12; ++i) {
const volatile uint32_t discard = LL_RNG_ReadRandData32(RNG);
UNUSED(discard);
}
}
}
return LL_RNG_ReadRandData32(RNG);
}
uint32_t furi_hal_random_get() {
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID))
;
LL_RNG_Enable(RNG);
while(!LL_RNG_IsActiveFlag_DRDY(RNG))
;
if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) {
furi_crash("TRNG error");
}
uint32_t random_val = LL_RNG_ReadRandData32(RNG);
const uint32_t random_val = furi_hal_random_read_rng();
LL_RNG_Disable(RNG);
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
@@ -35,15 +51,7 @@ void furi_hal_random_fill_buf(uint8_t* buf, uint32_t len) {
LL_RNG_Enable(RNG);
for(uint32_t i = 0; i < len; i += 4) {
while(!LL_RNG_IsActiveFlag_DRDY(RNG))
;
if((LL_RNG_IsActiveFlag_CECS(RNG)) || (LL_RNG_IsActiveFlag_SECS(RNG))) {
furi_crash("TRNG error");
}
uint32_t random_val = LL_RNG_ReadRandData32(RNG);
const uint32_t random_val = furi_hal_random_read_rng();
uint8_t len_cur = ((i + 4) < len) ? (4) : (len - i);
memcpy(&buf[i], &random_val, len_cur);
}

View File

@@ -6,6 +6,9 @@
#define TAG "FuriHalResources"
const GpioPin gpio_swdio = {.port = GPIOA, .pin = LL_GPIO_PIN_13};
const GpioPin gpio_swclk = {.port = GPIOA, .pin = LL_GPIO_PIN_14};
const GpioPin gpio_vibro = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin};
const GpioPin gpio_ibutton = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin};
@@ -158,10 +161,11 @@ void furi_hal_resources_init() {
// Button pins
furi_hal_resources_init_input_pins(GpioModeInterruptRiseFall);
// Explicit pulls pins
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
furi_hal_gpio_init(&gpio_vibro, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
// Explicit, surviving reset, pulls
LL_PWR_EnablePUPDCfg();
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_9); // gpio_infrared_tx
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_B, LL_PWR_GPIO_BIT_8); // gpio_speaker
LL_PWR_EnableGPIOPullDown(LL_PWR_GPIO_A, LL_PWR_GPIO_BIT_8); // gpio_vibro
// Display pins
furi_hal_gpio_init(&gpio_display_rst_n, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);

View File

@@ -50,6 +50,9 @@ extern const size_t input_pins_count;
extern const GpioPinRecord gpio_pins[];
extern const size_t gpio_pins_count;
extern const GpioPin gpio_swdio;
extern const GpioPin gpio_swclk;
extern const GpioPin gpio_vibro;
extern const GpioPin gpio_ibutton;

View File

@@ -165,6 +165,14 @@ void furi_hal_rtc_init() {
FURI_LOG_I(TAG, "Init OK");
}
void furi_hal_rtc_sync_shadow() {
if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) {
LL_RTC_ClearFlag_RS(RTC);
while(!LL_RTC_IsActiveFlag_RS(RTC)) {
};
}
}
uint32_t furi_hal_rtc_get_register(FuriHalRtcRegister reg) {
return LL_RTC_BAK_GetRegister(RTC, reg);
}
@@ -312,12 +320,7 @@ void furi_hal_rtc_set_datetime(FuriHalRtcDateTime* datetime) {
/* Exit Initialization mode */
LL_RTC_DisableInitMode(RTC);
/* If RTC_CR_BYPSHAD bit = 0, wait for synchro else this check is not needed */
if(!LL_RTC_IsShadowRegBypassEnabled(RTC)) {
LL_RTC_ClearFlag_RS(RTC);
while(!LL_RTC_IsActiveFlag_RS(RTC)) {
};
}
furi_hal_rtc_sync_shadow();
/* Enable write protection */
LL_RTC_EnableWriteProtection(RTC);

View File

@@ -40,6 +40,7 @@ volatile FuriHalSubGhz furi_hal_subghz = {
.cc1101_g0_pin = &gpio_cc1101_g0,
.rolling_counter_mult = 1,
.ext_module_power_disabled = false,
.timestamp_file_names = false,
};
bool furi_hal_subghz_set_radio_type(SubGhzRadioType state) {
@@ -79,6 +80,14 @@ bool furi_hal_subghz_get_external_power_disable(void) {
return furi_hal_subghz.ext_module_power_disabled;
}
void furi_hal_subghz_set_timestamp_file_names(bool state) {
furi_hal_subghz.timestamp_file_names = state;
}
bool furi_hal_subghz_get_timestamp_file_names(void) {
return furi_hal_subghz.timestamp_file_names;
}
void furi_hal_subghz_set_async_mirror_pin(const GpioPin* pin) {
furi_hal_subghz.async_mirror_pin = pin;
}
@@ -702,11 +711,12 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
GpioModeInterruptRiseFall,
GpioPullUp,
GpioSpeedVeryHigh);
furi_hal_gpio_disable_int_callback(furi_hal_subghz.cc1101_g0_pin);
furi_hal_gpio_remove_int_callback(furi_hal_subghz.cc1101_g0_pin);
furi_hal_gpio_add_int_callback(
furi_hal_subghz.cc1101_g0_pin,
furi_hal_subghz_capture_ext_ISR,
furi_hal_subghz_capture_callback);
furi_hal_gpio_enable_int_callback(furi_hal_subghz.cc1101_g0_pin);
}
// Start timer

View File

@@ -79,6 +79,7 @@ typedef struct {
const GpioPin* cc1101_g0_pin;
uint8_t rolling_counter_mult;
bool ext_module_power_disabled;
bool timestamp_file_names;
} FuriHalSubGhz;
extern volatile FuriHalSubGhz furi_hal_subghz;
@@ -344,6 +345,14 @@ void furi_hal_subghz_set_external_power_disable(bool state);
*/
bool furi_hal_subghz_get_external_power_disable(void);
/** If true - disable generation of random name and add timestamp to filenames instead
*/
void furi_hal_subghz_set_timestamp_file_names(bool state);
/** Get the current state of the timestamp instead of random name flag
*/
bool furi_hal_subghz_get_timestamp_file_names(void);
#ifdef __cplusplus
}
#endif