Skip to content

Commit

Permalink
Various Fixes for 0.95 (#3215)
Browse files Browse the repository at this point in the history
* FuriHal: retry gauge/charger initialization
* FuriHal: lower logging level for flash known errata
* FuriHal: graceful fail if subghz chip is not working
* Furi: issue stop command even if timer is not active, document timer behavior
  • Loading branch information
skotopes authored Nov 15, 2023
1 parent a61b5d4 commit 457aa53
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 42 deletions.
11 changes: 2 additions & 9 deletions furi/core/timer.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,17 +122,10 @@ FuriStatus furi_timer_stop(FuriTimer* instance) {
furi_assert(instance);

TimerHandle_t hTimer = (TimerHandle_t)instance;
FuriStatus stat;

if(xTimerIsTimerActive(hTimer) == pdFALSE) {
stat = FuriStatusErrorResource;
} else {
furi_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS);
stat = FuriStatusOk;
}
furi_check(xTimerStop(hTimer, portMAX_DELAY) == pdPASS);

/* Return execution status */
return (stat);
return FuriStatusOk;
}

uint32_t furi_timer_is_running(FuriTimer* instance) {
Expand Down
13 changes: 13 additions & 0 deletions furi/core/timer.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ FuriTimer* furi_timer_alloc(FuriTimerCallback func, FuriTimerType type, void* co
void furi_timer_free(FuriTimer* instance);

/** Start timer
*
* @warning This is asynchronous call, real operation will happen as soon as
* timer service process this request.
*
* @param instance The pointer to FuriTimer instance
* @param[in] ticks The interval in ticks
Expand All @@ -41,6 +44,9 @@ void furi_timer_free(FuriTimer* instance);
FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks);

/** Restart timer with previous timeout value
*
* @warning This is asynchronous call, real operation will happen as soon as
* timer service process this request.
*
* @param instance The pointer to FuriTimer instance
* @param[in] ticks The interval in ticks
Expand All @@ -50,6 +56,9 @@ FuriStatus furi_timer_start(FuriTimer* instance, uint32_t ticks);
FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks);

/** Stop timer
*
* @warning This is asynchronous call, real operation will happen as soon as
* timer service process this request.
*
* @param instance The pointer to FuriTimer instance
*
Expand All @@ -58,6 +67,10 @@ FuriStatus furi_timer_restart(FuriTimer* instance, uint32_t ticks);
FuriStatus furi_timer_stop(FuriTimer* instance);

/** Is timer running
*
* @warning This cal may and will return obsolete timer state if timer
* commands are still in the queue. Please read FreeRTOS timer
* documentation first.
*
* @param instance The pointer to FuriTimer instance
*
Expand Down
2 changes: 1 addition & 1 deletion targets/f7/furi_hal/furi_hal_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ void furi_hal_flash_init() {
// WRITE_REG(FLASH->SR, FLASH_SR_OPTVERR);
/* Actually, reset all error flags on start */
if(READ_BIT(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS)) {
FURI_LOG_E(TAG, "FLASH->SR 0x%08lX", FLASH->SR);
FURI_LOG_W(TAG, "FLASH->SR 0x%08lX(Known ERRATA)", FLASH->SR);
WRITE_REG(FLASH->SR, FURI_HAL_FLASH_SR_ERRORS);
}
}
Expand Down
33 changes: 29 additions & 4 deletions targets/f7/furi_hal/furi_hal_power.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,37 @@ void furi_hal_power_init() {

furi_hal_i2c_acquire(&furi_hal_i2c_handle_power);
// Find and init gauge
if(bq27220_init(&furi_hal_i2c_handle_power)) {
furi_hal_power.gauge_ok = bq27220_apply_data_memory(
&furi_hal_i2c_handle_power, furi_hal_power_gauge_data_memory);
size_t retry = 2;
while(retry > 0) {
furi_hal_power.gauge_ok = bq27220_init(&furi_hal_i2c_handle_power);
if(furi_hal_power.gauge_ok) {
furi_hal_power.gauge_ok = bq27220_apply_data_memory(
&furi_hal_i2c_handle_power, furi_hal_power_gauge_data_memory);
}
if(furi_hal_power.gauge_ok) {
break;
} else {
// Normal startup time is 250ms
// But if we try to access gauge at that stage it will become unresponsive
// 2 seconds timeout needed to restart communication
furi_delay_us(2020202);
}
retry--;
}
// Find and init charger
furi_hal_power.charger_ok = bq25896_init(&furi_hal_i2c_handle_power);
retry = 2;
while(retry > 0) {
furi_hal_power.charger_ok = bq25896_init(&furi_hal_i2c_handle_power);
if(furi_hal_power.charger_ok) {
break;
} else {
// Most likely I2C communication error
// 2 seconds should be enough for all chips on the line to timeout
// Also timing out here is very abnormal
furi_delay_us(2020202);
}
retry--;
}
furi_hal_i2c_release(&furi_hal_i2c_handle_power);

FURI_LOG_I(TAG, "Init OK");
Expand Down
78 changes: 50 additions & 28 deletions targets/f7/furi_hal/furi_hal_subghz.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <furi_hal_version.h>
#include <furi_hal_rtc.h>
#include <furi_hal_spi.h>
#include <furi_hal_cortex.h>
#include <furi_hal_interrupt.h>
#include <furi_hal_resources.h>
#include <furi_hal_bus.h>
Expand All @@ -29,7 +30,7 @@ static uint32_t furi_hal_subghz_debug_gpio_buff[2];
/** SubGhz state */
typedef enum {
SubGhzStateInit, /**< Init pending */

SubGhzStateBroken, /**< Chip power-on self test failed */
SubGhzStateIdle, /**< Idle, energy save mode */

SubGhzStateAsyncRx, /**< Async RX started */
Expand Down Expand Up @@ -69,46 +70,67 @@ const GpioPin* furi_hal_subghz_get_data_gpio() {

void furi_hal_subghz_init() {
furi_assert(furi_hal_subghz.state == SubGhzStateInit);
furi_hal_subghz.state = SubGhzStateIdle;
furi_hal_subghz.state = SubGhzStateBroken;

furi_hal_spi_acquire(&furi_hal_spi_bus_handle_subghz);

do {
#ifdef FURI_HAL_SUBGHZ_TX_GPIO
furi_hal_gpio_init(&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
furi_hal_gpio_init(
&FURI_HAL_SUBGHZ_TX_GPIO, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
#endif

// Reset
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
cc1101_reset(&furi_hal_spi_bus_handle_subghz);
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance);
// Reset
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
cc1101_reset(&furi_hal_spi_bus_handle_subghz);
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance);

// Prepare GD0 for power on self test
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);
// Prepare GD0 for power on self test
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeInput, GpioPullNo, GpioSpeedLow);

// GD0 low
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW);
while(furi_hal_gpio_read(&gpio_cc1101_g0) != false)
;
// GD0 low
FuriHalCortexTimer timeout = furi_hal_cortex_timer_get(10000);
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW);
while(furi_hal_gpio_read(&gpio_cc1101_g0) != false &&
!furi_hal_cortex_timer_is_expired(timeout))
;

// GD0 high
cc1101_write_reg(
&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV);
while(furi_hal_gpio_read(&gpio_cc1101_g0) != true)
;
if(furi_hal_gpio_read(&gpio_cc1101_g0) != false) {
break;
}

// Reset GD0 to floating state
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance);
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
// GD0 high
timeout = furi_hal_cortex_timer_get(10000);
cc1101_write_reg(
&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHW | CC1101_IOCFG_INV);
while(furi_hal_gpio_read(&gpio_cc1101_g0) != true &&
!furi_hal_cortex_timer_is_expired(timeout))
;

if(furi_hal_gpio_read(&gpio_cc1101_g0) != true) {
break;
}

// RF switches
furi_hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW);
// Reset GD0 to floating state
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG0, CC1101IocfgHighImpedance);
furi_hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);

// Go to sleep
cc1101_shutdown(&furi_hal_spi_bus_handle_subghz);
// RF switches
furi_hal_gpio_init(&gpio_rf_sw_0, GpioModeOutputPushPull, GpioPullNo, GpioSpeedLow);
cc1101_write_reg(&furi_hal_spi_bus_handle_subghz, CC1101_IOCFG2, CC1101IocfgHW);

// Go to sleep
cc1101_shutdown(&furi_hal_spi_bus_handle_subghz);

furi_hal_subghz.state = SubGhzStateIdle;
} while(false);

furi_hal_spi_release(&furi_hal_spi_bus_handle_subghz);
FURI_LOG_I(TAG, "Init OK");

if(furi_hal_subghz.state == SubGhzStateIdle) {
FURI_LOG_I(TAG, "Init OK");
} else {
FURI_LOG_E(TAG, "Init Fail");
}
}

void furi_hal_subghz_sleep() {
Expand Down

0 comments on commit 457aa53

Please sign in to comment.