mirror of
https://github.com/Next-Flip/Momentum-Firmware.git
synced 2026-05-03 04:49:59 -07:00
Merge branch 'dev' into keeloq_move_mf_to_keystore
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,26.3,,
|
||||
Version,+,28.1,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@@ -40,8 +40,10 @@ Header,-,firmware/targets/f18/furi_hal/furi_hal_power_calibration.h,,
|
||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_resources.h,,
|
||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_spi_config.h,,
|
||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_target_hw.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_bus.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_clock.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_console.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_dma.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_flash.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,,
|
||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.h,,
|
||||
@@ -129,6 +131,7 @@ Header,+,lib/one_wire/maxim_crc.h,,
|
||||
Header,+,lib/one_wire/one_wire_host.h,,
|
||||
Header,+,lib/one_wire/one_wire_slave.h,,
|
||||
Header,+,lib/print/wrappers.h,,
|
||||
Header,+,lib/pulse_reader/pulse_reader.h,,
|
||||
Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_adc.h,,
|
||||
Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_bus.h,,
|
||||
Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_comp.h,,
|
||||
@@ -156,7 +159,7 @@ Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_tim.h,,
|
||||
Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_usart.h,,
|
||||
Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_utils.h,,
|
||||
Header,+,lib/stm32wb_hal/Inc/stm32wbxx_ll_wwdg.h,,
|
||||
Header,+,lib/pulse_reader/pulse_reader.h,,
|
||||
Header,+,lib/toolbox/api_lock.h,,
|
||||
Header,+,lib/toolbox/args.h,,
|
||||
Header,+,lib/toolbox/crc32_calc.h,,
|
||||
Header,+,lib/toolbox/dir_walk.h,,
|
||||
@@ -872,6 +875,12 @@ Function,+,furi_hal_bt_stop_tone_tx,void,
|
||||
Function,+,furi_hal_bt_unlock_core2,void,
|
||||
Function,+,furi_hal_bt_update_battery_level,void,uint8_t
|
||||
Function,+,furi_hal_bt_update_power_state,void,
|
||||
Function,+,furi_hal_bus_deinit_early,void,
|
||||
Function,+,furi_hal_bus_disable,void,FuriHalBus
|
||||
Function,+,furi_hal_bus_enable,void,FuriHalBus
|
||||
Function,+,furi_hal_bus_init_early,void,
|
||||
Function,+,furi_hal_bus_is_enabled,_Bool,FuriHalBus
|
||||
Function,+,furi_hal_bus_reset,void,FuriHalBus
|
||||
Function,+,furi_hal_cdc_get_ctrl_line_state,uint8_t,uint8_t
|
||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,uint8_t
|
||||
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
||||
@@ -914,6 +923,8 @@ Function,+,furi_hal_debug_disable,void,
|
||||
Function,+,furi_hal_debug_enable,void,
|
||||
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
||||
Function,-,furi_hal_deinit_early,void,
|
||||
Function,+,furi_hal_dma_deinit_early,void,
|
||||
Function,+,furi_hal_dma_init_early,void,
|
||||
Function,-,furi_hal_flash_erase,void,uint8_t
|
||||
Function,-,furi_hal_flash_get_base,size_t,
|
||||
Function,-,furi_hal_flash_get_cycles_count,size_t,
|
||||
@@ -1032,6 +1043,7 @@ Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t"
|
||||
Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId
|
||||
Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t"
|
||||
Function,+,furi_hal_random_get,uint32_t,
|
||||
Function,+,furi_hal_random_init,void,
|
||||
Function,+,furi_hal_region_get,const FuriHalRegion*,
|
||||
Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t
|
||||
Function,+,furi_hal_region_get_name,const char*,
|
||||
@@ -1047,6 +1059,8 @@ Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime*
|
||||
Function,-,furi_hal_rtc_deinit_early,void,
|
||||
Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode,
|
||||
Function,+,furi_hal_rtc_get_datetime,void,FuriHalRtcDateTime*
|
||||
Function,+,furi_hal_rtc_get_days_per_month,uint8_t,"_Bool, uint8_t"
|
||||
Function,+,furi_hal_rtc_get_days_per_year,uint16_t,uint16_t
|
||||
Function,+,furi_hal_rtc_get_fault_data,uint32_t,
|
||||
Function,+,furi_hal_rtc_get_heap_track_mode,FuriHalRtcHeapTrackMode,
|
||||
Function,+,furi_hal_rtc_get_locale_dateformat,FuriHalRtcLocaleDateFormat,
|
||||
@@ -1059,6 +1073,7 @@ Function,+,furi_hal_rtc_get_timestamp,uint32_t,
|
||||
Function,-,furi_hal_rtc_init,void,
|
||||
Function,-,furi_hal_rtc_init_early,void,
|
||||
Function,+,furi_hal_rtc_is_flag_set,_Bool,FuriHalRtcFlag
|
||||
Function,+,furi_hal_rtc_is_leap_year,_Bool,uint16_t
|
||||
Function,+,furi_hal_rtc_reset_flag,void,FuriHalRtcFlag
|
||||
Function,+,furi_hal_rtc_set_boot_mode,void,FuriHalRtcBootMode
|
||||
Function,+,furi_hal_rtc_set_datetime,void,FuriHalRtcDateTime*
|
||||
@@ -1988,6 +2003,8 @@ Function,-,vdprintf,int,"int, const char*, __gnuc_va_list"
|
||||
Function,+,version_get,const Version*,
|
||||
Function,+,version_get_builddate,const char*,const Version*
|
||||
Function,+,version_get_dirty_flag,_Bool,const Version*
|
||||
Function,+,version_get_firmware_origin,const char*,const Version*
|
||||
Function,+,version_get_git_origin,const char*,const Version*
|
||||
Function,+,version_get_gitbranch,const char*,const Version*
|
||||
Function,+,version_get_gitbranchnum,const char*,const Version*
|
||||
Function,+,version_get_githash,const char*,const Version*
|
||||
|
||||
|
@@ -9,6 +9,8 @@
|
||||
void furi_hal_init_early() {
|
||||
furi_hal_cortex_init_early();
|
||||
furi_hal_clock_init_early();
|
||||
furi_hal_bus_init_early();
|
||||
furi_hal_dma_init_early();
|
||||
furi_hal_resources_init_early();
|
||||
furi_hal_os_init();
|
||||
furi_hal_spi_config_init_early();
|
||||
@@ -22,12 +24,15 @@ void furi_hal_deinit_early() {
|
||||
furi_hal_i2c_deinit_early();
|
||||
furi_hal_spi_config_deinit_early();
|
||||
furi_hal_resources_deinit_early();
|
||||
furi_hal_dma_deinit_early();
|
||||
furi_hal_bus_deinit_early();
|
||||
furi_hal_clock_deinit_early();
|
||||
}
|
||||
|
||||
void furi_hal_init() {
|
||||
furi_hal_mpu_init();
|
||||
furi_hal_clock_init();
|
||||
furi_hal_random_init();
|
||||
furi_hal_console_init();
|
||||
furi_hal_rtc_init();
|
||||
furi_hal_interrupt_init();
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
@@ -118,6 +119,13 @@ static void furi_hal_resources_init_input_pins(GpioMode mode) {
|
||||
}
|
||||
|
||||
void furi_hal_resources_init_early() {
|
||||
furi_hal_bus_enable(FuriHalBusGPIOA);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOB);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOC);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOD);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOE);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOH);
|
||||
|
||||
furi_hal_resources_init_input_pins(GpioModeInput);
|
||||
|
||||
// SD Card stepdown control
|
||||
@@ -162,6 +170,12 @@ void furi_hal_resources_init_early() {
|
||||
|
||||
void furi_hal_resources_deinit_early() {
|
||||
furi_hal_resources_init_input_pins(GpioModeAnalog);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOA);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOB);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOC);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOD);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOE);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOH);
|
||||
}
|
||||
|
||||
void furi_hal_resources_init() {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <furi_hal_spi_config.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi_hal_spi.h>
|
||||
#include <furi.h>
|
||||
|
||||
@@ -96,28 +97,17 @@ void furi_hal_spi_config_init() {
|
||||
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||
if(event == FuriHalSpiBusEventInit) {
|
||||
furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||
furi_mutex_free(furi_hal_spi_bus_r_mutex);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalSpiBusEventLock) {
|
||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FuriHalBusSPI1);
|
||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusSPI1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -131,28 +121,17 @@ FuriMutex* furi_hal_spi_bus_d_mutex = NULL;
|
||||
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||
if(event == FuriHalSpiBusEventInit) {
|
||||
furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||
furi_mutex_free(furi_hal_spi_bus_d_mutex);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalSpiBusEventLock) {
|
||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FuriHalBusSPI2);
|
||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusSPI2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,6 +9,8 @@
|
||||
void furi_hal_init_early() {
|
||||
furi_hal_cortex_init_early();
|
||||
furi_hal_clock_init_early();
|
||||
furi_hal_bus_init_early();
|
||||
furi_hal_dma_init_early();
|
||||
furi_hal_resources_init_early();
|
||||
furi_hal_os_init();
|
||||
furi_hal_spi_config_init_early();
|
||||
@@ -22,12 +24,15 @@ void furi_hal_deinit_early() {
|
||||
furi_hal_i2c_deinit_early();
|
||||
furi_hal_spi_config_deinit_early();
|
||||
furi_hal_resources_deinit_early();
|
||||
furi_hal_dma_deinit_early();
|
||||
furi_hal_bus_deinit_early();
|
||||
furi_hal_clock_deinit_early();
|
||||
}
|
||||
|
||||
void furi_hal_init() {
|
||||
furi_hal_mpu_init();
|
||||
furi_hal_clock_init();
|
||||
furi_hal_random_init();
|
||||
furi_hal_console_init();
|
||||
furi_hal_rtc_init();
|
||||
furi_hal_interrupt_init();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <furi_hal_version.h>
|
||||
#include <furi_hal_bt_hid.h>
|
||||
#include <furi_hal_bt_serial.h>
|
||||
#include <furi_hal_bus.c>
|
||||
#include "battery_service.h"
|
||||
|
||||
#include <furi.h>
|
||||
@@ -80,6 +81,11 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = {
|
||||
FuriHalBtProfileConfig* current_profile = NULL;
|
||||
|
||||
void furi_hal_bt_init() {
|
||||
furi_hal_bus_enable(FuriHalBusHSEM);
|
||||
furi_hal_bus_enable(FuriHalBusIPCC);
|
||||
furi_hal_bus_enable(FuriHalBusAES2);
|
||||
furi_hal_bus_enable(FuriHalBusPKA);
|
||||
|
||||
if(!furi_hal_bt_core2_mtx) {
|
||||
furi_hal_bt_core2_mtx = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
furi_assert(furi_hal_bt_core2_mtx);
|
||||
@@ -269,6 +275,11 @@ void furi_hal_bt_reinit() {
|
||||
furi_delay_ms(100);
|
||||
ble_glue_thread_stop();
|
||||
|
||||
furi_hal_bus_disable(FuriHalBusHSEM);
|
||||
furi_hal_bus_disable(FuriHalBusIPCC);
|
||||
furi_hal_bus_disable(FuriHalBusAES2);
|
||||
furi_hal_bus_disable(FuriHalBusPKA);
|
||||
|
||||
FURI_LOG_I(TAG, "Start BT initialization");
|
||||
furi_hal_bt_init();
|
||||
|
||||
|
||||
302
firmware/targets/f7/furi_hal/furi_hal_bus.c
Normal file
302
firmware/targets/f7/furi_hal/furi_hal_bus.c
Normal file
@@ -0,0 +1,302 @@
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
|
||||
/* Bus bitmask definitions */
|
||||
#define FURI_HAL_BUS_IGNORE (0x0U)
|
||||
|
||||
#define FURI_HAL_BUS_AHB1_GRP1 \
|
||||
(LL_AHB1_GRP1_PERIPH_DMA1 | LL_AHB1_GRP1_PERIPH_DMA2 | LL_AHB1_GRP1_PERIPH_DMAMUX1 | \
|
||||
LL_AHB1_GRP1_PERIPH_CRC | LL_AHB1_GRP1_PERIPH_TSC)
|
||||
|
||||
#if defined(ADC_SUPPORT_5_MSPS)
|
||||
#define FURI_HAL_BUS_AHB2_GRP1 \
|
||||
(LL_AHB2_GRP1_PERIPH_GPIOA | LL_AHB2_GRP1_PERIPH_GPIOB | LL_AHB2_GRP1_PERIPH_GPIOC | \
|
||||
LL_AHB2_GRP1_PERIPH_GPIOD | LL_AHB2_GRP1_PERIPH_GPIOE | LL_AHB2_GRP1_PERIPH_GPIOH | \
|
||||
LL_AHB2_GRP1_PERIPH_ADC | LL_AHB2_GRP1_PERIPH_AES1)
|
||||
|
||||
#define FURI_HAL_BUS_APB2_GRP1 \
|
||||
(LL_APB2_GRP1_PERIPH_TIM1 | LL_APB2_GRP1_PERIPH_SPI1 | LL_APB2_GRP1_PERIPH_USART1 | \
|
||||
LL_APB2_GRP1_PERIPH_TIM16 | LL_APB2_GRP1_PERIPH_TIM17 | LL_APB2_GRP1_PERIPH_SAI1)
|
||||
#else
|
||||
#define FURI_HAL_BUS_AHB2_GRP1 \
|
||||
(LL_AHB2_GRP1_PERIPH_GPIOA | LL_AHB2_GRP1_PERIPH_GPIOB | LL_AHB2_GRP1_PERIPH_GPIOC | \
|
||||
LL_AHB2_GRP1_PERIPH_GPIOD | LL_AHB2_GRP1_PERIPH_GPIOE | LL_AHB2_GRP1_PERIPH_GPIOH | \
|
||||
LL_AHB2_GRP1_PERIPH_AES1)
|
||||
|
||||
#define FURI_HAL_BUS_APB2_GRP1 \
|
||||
(LL_APB2_GRP1_PERIPH_ADC | LL_APB2_GRP1_PERIPH_TIM1 | LL_APB2_GRP1_PERIPH_SPI1 | \
|
||||
LL_APB2_GRP1_PERIPH_USART1 | LL_APB2_GRP1_PERIPH_TIM16 | LL_APB2_GRP1_PERIPH_TIM17 | \
|
||||
LL_APB2_GRP1_PERIPH_SAI1)
|
||||
#endif
|
||||
|
||||
#define FURI_HAL_BUS_AHB3_GRP1 \
|
||||
(LL_AHB3_GRP1_PERIPH_QUADSPI | LL_AHB3_GRP1_PERIPH_PKA | LL_AHB3_GRP1_PERIPH_AES2 | \
|
||||
LL_AHB3_GRP1_PERIPH_RNG | LL_AHB3_GRP1_PERIPH_HSEM | LL_AHB3_GRP1_PERIPH_IPCC)
|
||||
// LL_AHB3_GRP1_PERIPH_FLASH enabled by default
|
||||
|
||||
#define FURI_HAL_BUS_APB1_GRP1 \
|
||||
(LL_APB1_GRP1_PERIPH_TIM2 | LL_APB1_GRP1_PERIPH_LCD | LL_APB1_GRP1_PERIPH_RTCAPB | \
|
||||
LL_APB1_GRP1_PERIPH_SPI2 | LL_APB1_GRP1_PERIPH_I2C1 | LL_APB1_GRP1_PERIPH_I2C3 | \
|
||||
LL_APB1_GRP1_PERIPH_CRS | LL_APB1_GRP1_PERIPH_USB | LL_APB1_GRP1_PERIPH_LPTIM1)
|
||||
|
||||
#define FURI_HAL_BUS_APB1_GRP2 (LL_APB1_GRP2_PERIPH_LPUART1 | LL_APB1_GRP2_PERIPH_LPTIM2)
|
||||
#define FURI_HAL_BUS_APB3_GRP1 (LL_APB3_GRP1_PERIPH_RF)
|
||||
|
||||
/* Test macro definitions */
|
||||
#define FURI_HAL_BUS_IS_ALL_CLEAR(reg, value) (READ_BIT((reg), (value)) == 0UL)
|
||||
#define FURI_HAL_BUS_IS_ALL_SET(reg, value) (READ_BIT((reg), (value)) == (value))
|
||||
|
||||
#define FURI_HAL_BUS_IS_CLOCK_ENABLED(bus, value, ...) \
|
||||
(FURI_HAL_BUS_IS_ALL_SET(RCC->bus##ENR##__VA_ARGS__, (value)))
|
||||
#define FURI_HAL_BUS_IS_CLOCK_DISABLED(bus, value, ...) \
|
||||
(FURI_HAL_BUS_IS_ALL_CLEAR(RCC->bus##ENR##__VA_ARGS__, (value)))
|
||||
|
||||
#define FURI_HAL_BUS_IS_RESET_ASSERTED(bus, value, ...) \
|
||||
(FURI_HAL_BUS_IS_ALL_SET(RCC->bus##RSTR##__VA_ARGS__, (value)))
|
||||
#define FURI_HAL_BUS_IS_RESET_DEASSERTED(bus, value, ...) \
|
||||
(FURI_HAL_BUS_IS_ALL_CLEAR(RCC->bus##RSTR##__VA_ARGS__, (value)))
|
||||
|
||||
#define FURI_HAL_BUS_IS_PERIPH_ENABLED(bus, value, ...) \
|
||||
(FURI_HAL_BUS_IS_RESET_DEASSERTED(bus, (value), __VA_ARGS__) && \
|
||||
FURI_HAL_BUS_IS_CLOCK_ENABLED(bus, (value), __VA_ARGS__))
|
||||
|
||||
#define FURI_HAL_BUS_IS_PERIPH_DISABLED(bus, value, ...) \
|
||||
(FURI_HAL_BUS_IS_CLOCK_DISABLED(bus, (value), __VA_ARGS__) && \
|
||||
FURI_HAL_BUS_IS_RESET_ASSERTED(bus, (value), __VA_ARGS__))
|
||||
|
||||
/* Control macro definitions */
|
||||
#define FURI_HAL_BUS_RESET_ASSERT(bus, value, grp) LL_##bus##_GRP##grp##_ForceReset(value)
|
||||
#define FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp) LL_##bus##_GRP##grp##_ReleaseReset(value)
|
||||
|
||||
#define FURI_HAL_BUS_CLOCK_ENABLE(bus, value, grp) LL_##bus##_GRP##grp##_EnableClock(value)
|
||||
#define FURI_HAL_BUS_CLOCK_DISABLE(bus, value, grp) LL_##bus##_GRP##grp##_DisableClock(value)
|
||||
|
||||
#define FURI_HAL_BUS_PERIPH_ENABLE(bus, value, grp) \
|
||||
FURI_HAL_BUS_CLOCK_ENABLE(bus, value, grp); \
|
||||
FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp)
|
||||
|
||||
#define FURI_HAL_BUS_PERIPH_DISABLE(bus, value, grp) \
|
||||
FURI_HAL_BUS_RESET_ASSERT(bus, value, grp); \
|
||||
FURI_HAL_BUS_CLOCK_DISABLE(bus, value, grp)
|
||||
|
||||
#define FURI_HAL_BUS_PERIPH_RESET(bus, value, grp) \
|
||||
FURI_HAL_BUS_RESET_ASSERT(bus, value, grp); \
|
||||
FURI_HAL_BUS_RESET_DEASSERT(bus, value, grp)
|
||||
|
||||
static const uint32_t furi_hal_bus[] = {
|
||||
[FuriHalBusAHB1_GRP1] = FURI_HAL_BUS_AHB1_GRP1,
|
||||
[FuriHalBusDMA1] = LL_AHB1_GRP1_PERIPH_DMA1,
|
||||
[FuriHalBusDMA2] = LL_AHB1_GRP1_PERIPH_DMA2,
|
||||
[FuriHalBusDMAMUX1] = LL_AHB1_GRP1_PERIPH_DMAMUX1,
|
||||
[FuriHalBusCRC] = LL_AHB1_GRP1_PERIPH_CRC,
|
||||
[FuriHalBusTSC] = LL_AHB1_GRP1_PERIPH_TSC,
|
||||
|
||||
[FuriHalBusAHB2_GRP1] = FURI_HAL_BUS_AHB2_GRP1,
|
||||
[FuriHalBusGPIOA] = LL_AHB2_GRP1_PERIPH_GPIOA,
|
||||
[FuriHalBusGPIOB] = LL_AHB2_GRP1_PERIPH_GPIOB,
|
||||
[FuriHalBusGPIOC] = LL_AHB2_GRP1_PERIPH_GPIOC,
|
||||
[FuriHalBusGPIOD] = LL_AHB2_GRP1_PERIPH_GPIOD,
|
||||
[FuriHalBusGPIOE] = LL_AHB2_GRP1_PERIPH_GPIOE,
|
||||
[FuriHalBusGPIOH] = LL_AHB2_GRP1_PERIPH_GPIOH,
|
||||
#if defined(ADC_SUPPORT_5_MSPS)
|
||||
[FuriHalBusADC] = LL_AHB2_GRP1_PERIPH_ADC,
|
||||
#endif
|
||||
[FuriHalBusAES1] = LL_AHB2_GRP1_PERIPH_AES1,
|
||||
|
||||
[FuriHalBusAHB3_GRP1] = FURI_HAL_BUS_AHB3_GRP1,
|
||||
[FuriHalBusQUADSPI] = LL_AHB3_GRP1_PERIPH_QUADSPI,
|
||||
[FuriHalBusPKA] = LL_AHB3_GRP1_PERIPH_PKA,
|
||||
[FuriHalBusAES2] = LL_AHB3_GRP1_PERIPH_AES2,
|
||||
[FuriHalBusRNG] = LL_AHB3_GRP1_PERIPH_RNG,
|
||||
[FuriHalBusHSEM] = LL_AHB3_GRP1_PERIPH_HSEM,
|
||||
[FuriHalBusIPCC] = LL_AHB3_GRP1_PERIPH_IPCC,
|
||||
[FuriHalBusFLASH] = LL_AHB3_GRP1_PERIPH_FLASH,
|
||||
|
||||
[FuriHalBusAPB1_GRP1] = FURI_HAL_BUS_APB1_GRP1,
|
||||
[FuriHalBusTIM2] = LL_APB1_GRP1_PERIPH_TIM2,
|
||||
[FuriHalBusLCD] = LL_APB1_GRP1_PERIPH_LCD,
|
||||
[FuriHalBusSPI2] = LL_APB1_GRP1_PERIPH_SPI2,
|
||||
[FuriHalBusI2C1] = LL_APB1_GRP1_PERIPH_I2C1,
|
||||
[FuriHalBusI2C3] = LL_APB1_GRP1_PERIPH_I2C3,
|
||||
[FuriHalBusCRS] = LL_APB1_GRP1_PERIPH_CRS,
|
||||
[FuriHalBusUSB] = LL_APB1_GRP1_PERIPH_USB,
|
||||
[FuriHalBusLPTIM1] = LL_APB1_GRP1_PERIPH_LPTIM1,
|
||||
|
||||
[FuriHalBusAPB1_GRP2] = FURI_HAL_BUS_APB1_GRP2,
|
||||
[FuriHalBusLPUART1] = LL_APB1_GRP2_PERIPH_LPUART1,
|
||||
[FuriHalBusLPTIM2] = LL_APB1_GRP2_PERIPH_LPTIM2,
|
||||
|
||||
[FuriHalBusAPB2_GRP1] = FURI_HAL_BUS_APB2_GRP1,
|
||||
#if defined(ADC_SUPPORT_2_5_MSPS)
|
||||
[FuriHalBusADC] = LL_APB2_GRP1_PERIPH_ADC,
|
||||
#endif
|
||||
[FuriHalBusTIM1] = LL_APB2_GRP1_PERIPH_TIM1,
|
||||
[FuriHalBusSPI1] = LL_APB2_GRP1_PERIPH_SPI1,
|
||||
[FuriHalBusUSART1] = LL_APB2_GRP1_PERIPH_USART1,
|
||||
[FuriHalBusTIM16] = LL_APB2_GRP1_PERIPH_TIM16,
|
||||
[FuriHalBusTIM17] = LL_APB2_GRP1_PERIPH_TIM17,
|
||||
[FuriHalBusSAI1] = LL_APB2_GRP1_PERIPH_SAI1,
|
||||
|
||||
[FuriHalBusAPB3_GRP1] = FURI_HAL_BUS_IGNORE, // APB3_GRP1 clocking cannot be changed
|
||||
[FuriHalBusRF] = LL_APB3_GRP1_PERIPH_RF,
|
||||
};
|
||||
|
||||
void furi_hal_bus_init_early() {
|
||||
FURI_CRITICAL_ENTER();
|
||||
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(AHB1, FURI_HAL_BUS_AHB1_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(AHB2, FURI_HAL_BUS_AHB2_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(AHB3, FURI_HAL_BUS_AHB3_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(APB1, FURI_HAL_BUS_APB1_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(APB1, FURI_HAL_BUS_APB1_GRP2, 2);
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(APB2, FURI_HAL_BUS_APB2_GRP1, 1);
|
||||
|
||||
FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
|
||||
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_bus_deinit_early() {
|
||||
FURI_CRITICAL_ENTER();
|
||||
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(AHB1, FURI_HAL_BUS_AHB1_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(AHB2, FURI_HAL_BUS_AHB2_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(AHB3, FURI_HAL_BUS_AHB3_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(APB1, FURI_HAL_BUS_APB1_GRP1, 1);
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(APB1, FURI_HAL_BUS_APB1_GRP2, 2);
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(APB2, FURI_HAL_BUS_APB2_GRP1, 1);
|
||||
|
||||
FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
|
||||
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_bus_enable(FuriHalBus bus) {
|
||||
furi_check(bus < FuriHalBusMAX);
|
||||
const uint32_t value = furi_hal_bus[bus];
|
||||
if(!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
if(bus < FuriHalBusAHB2_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB1, value));
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(AHB1, value, 1);
|
||||
} else if(bus < FuriHalBusAHB3_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB2, value));
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(AHB2, value, 1);
|
||||
} else if(bus < FuriHalBusAPB1_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(AHB3, value));
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(AHB3, value, 1);
|
||||
} else if(bus < FuriHalBusAPB1_GRP2) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB1, value, 1));
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(APB1, value, 1);
|
||||
} else if(bus < FuriHalBusAPB2_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB1, value, 2));
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(APB1, value, 2);
|
||||
} else if(bus < FuriHalBusAPB3_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_DISABLED(APB2, value));
|
||||
FURI_HAL_BUS_PERIPH_ENABLE(APB2, value, 1);
|
||||
} else {
|
||||
furi_check(FURI_HAL_BUS_IS_RESET_ASSERTED(APB3, value));
|
||||
FURI_HAL_BUS_RESET_DEASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
|
||||
}
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_bus_reset(FuriHalBus bus) {
|
||||
furi_check(bus < FuriHalBusMAX);
|
||||
const uint32_t value = furi_hal_bus[bus];
|
||||
if(!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
if(bus < FuriHalBusAHB2_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value));
|
||||
FURI_HAL_BUS_PERIPH_RESET(AHB1, value, 1);
|
||||
} else if(bus < FuriHalBusAHB3_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value));
|
||||
FURI_HAL_BUS_PERIPH_RESET(AHB2, value, 1);
|
||||
} else if(bus < FuriHalBusAPB1_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value));
|
||||
FURI_HAL_BUS_PERIPH_RESET(AHB3, value, 1);
|
||||
} else if(bus < FuriHalBusAPB1_GRP2) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1));
|
||||
FURI_HAL_BUS_PERIPH_RESET(APB1, value, 1);
|
||||
} else if(bus < FuriHalBusAPB2_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2));
|
||||
FURI_HAL_BUS_PERIPH_RESET(APB1, value, 2);
|
||||
} else if(bus < FuriHalBusAPB3_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value));
|
||||
FURI_HAL_BUS_PERIPH_RESET(APB2, value, 1);
|
||||
} else {
|
||||
furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value));
|
||||
FURI_HAL_BUS_PERIPH_RESET(APB3, value, 1);
|
||||
}
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_bus_disable(FuriHalBus bus) {
|
||||
furi_check(bus < FuriHalBusMAX);
|
||||
const uint32_t value = furi_hal_bus[bus];
|
||||
if(!value) {
|
||||
return;
|
||||
}
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
if(bus < FuriHalBusAHB2_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value));
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(AHB1, value, 1);
|
||||
} else if(bus < FuriHalBusAHB3_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value));
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(AHB2, value, 1);
|
||||
} else if(bus < FuriHalBusAPB1_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value));
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(AHB3, value, 1);
|
||||
} else if(bus < FuriHalBusAPB1_GRP2) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1));
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(APB1, value, 1);
|
||||
} else if(bus < FuriHalBusAPB2_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2));
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(APB1, value, 2);
|
||||
} else if(bus < FuriHalBusAPB3_GRP1) {
|
||||
furi_check(FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value));
|
||||
FURI_HAL_BUS_PERIPH_DISABLE(APB2, value, 1);
|
||||
} else {
|
||||
furi_check(FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value));
|
||||
FURI_HAL_BUS_RESET_ASSERT(APB3, FURI_HAL_BUS_APB3_GRP1, 1);
|
||||
}
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
bool furi_hal_bus_is_enabled(FuriHalBus bus) {
|
||||
furi_check(bus < FuriHalBusMAX);
|
||||
const uint32_t value = furi_hal_bus[bus];
|
||||
if(value == FURI_HAL_BUS_IGNORE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ret = false;
|
||||
FURI_CRITICAL_ENTER();
|
||||
if(bus < FuriHalBusAHB2_GRP1) {
|
||||
ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB1, value);
|
||||
} else if(bus < FuriHalBusAHB3_GRP1) {
|
||||
ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB2, value);
|
||||
} else if(bus < FuriHalBusAPB1_GRP1) {
|
||||
ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(AHB3, value);
|
||||
} else if(bus < FuriHalBusAPB1_GRP2) {
|
||||
ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 1);
|
||||
} else if(bus < FuriHalBusAPB2_GRP1) {
|
||||
ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB1, value, 2);
|
||||
} else if(bus < FuriHalBusAPB3_GRP1) {
|
||||
ret = FURI_HAL_BUS_IS_PERIPH_ENABLED(APB2, value);
|
||||
} else {
|
||||
ret = FURI_HAL_BUS_IS_RESET_DEASSERTED(APB3, value);
|
||||
}
|
||||
FURI_CRITICAL_EXIT();
|
||||
|
||||
return ret;
|
||||
}
|
||||
112
firmware/targets/f7/furi_hal/furi_hal_bus.h
Normal file
112
firmware/targets/f7/furi_hal/furi_hal_bus.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "stm32wbxx.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
typedef enum {
|
||||
FuriHalBusAHB1_GRP1,
|
||||
FuriHalBusDMA1,
|
||||
FuriHalBusDMA2,
|
||||
FuriHalBusDMAMUX1,
|
||||
FuriHalBusCRC,
|
||||
FuriHalBusTSC,
|
||||
|
||||
FuriHalBusAHB2_GRP1,
|
||||
FuriHalBusGPIOA,
|
||||
FuriHalBusGPIOB,
|
||||
FuriHalBusGPIOC,
|
||||
FuriHalBusGPIOD,
|
||||
FuriHalBusGPIOE,
|
||||
FuriHalBusGPIOH,
|
||||
#if defined(ADC_SUPPORT_5_MSPS)
|
||||
FuriHalBusADC,
|
||||
#endif
|
||||
FuriHalBusAES1,
|
||||
|
||||
FuriHalBusAHB3_GRP1,
|
||||
FuriHalBusQUADSPI,
|
||||
FuriHalBusPKA,
|
||||
FuriHalBusAES2,
|
||||
FuriHalBusRNG,
|
||||
FuriHalBusHSEM,
|
||||
FuriHalBusIPCC,
|
||||
FuriHalBusFLASH,
|
||||
|
||||
FuriHalBusAPB1_GRP1,
|
||||
FuriHalBusTIM2,
|
||||
FuriHalBusLCD,
|
||||
FuriHalBusSPI2,
|
||||
FuriHalBusI2C1,
|
||||
FuriHalBusI2C3,
|
||||
FuriHalBusCRS,
|
||||
FuriHalBusUSB,
|
||||
FuriHalBusLPTIM1,
|
||||
|
||||
FuriHalBusAPB1_GRP2,
|
||||
FuriHalBusLPUART1,
|
||||
FuriHalBusLPTIM2,
|
||||
|
||||
FuriHalBusAPB2_GRP1,
|
||||
#if defined(ADC_SUPPORT_2_5_MSPS)
|
||||
FuriHalBusADC,
|
||||
#endif
|
||||
FuriHalBusTIM1,
|
||||
FuriHalBusSPI1,
|
||||
FuriHalBusUSART1,
|
||||
FuriHalBusTIM16,
|
||||
FuriHalBusTIM17,
|
||||
FuriHalBusSAI1,
|
||||
|
||||
FuriHalBusAPB3_GRP1,
|
||||
FuriHalBusRF,
|
||||
|
||||
FuriHalBusMAX,
|
||||
} FuriHalBus;
|
||||
|
||||
/** Early initialization */
|
||||
void furi_hal_bus_init_early();
|
||||
|
||||
/** Early de-initialization */
|
||||
void furi_hal_bus_deinit_early();
|
||||
|
||||
/**
|
||||
* Enable a peripheral by turning the clocking on and deasserting the reset.
|
||||
* @param [in] bus Peripheral to be enabled.
|
||||
* @warning Peripheral must be in disabled state in order to be enabled.
|
||||
*/
|
||||
void furi_hal_bus_enable(FuriHalBus bus);
|
||||
|
||||
/**
|
||||
* Reset a peripheral by sequentially asserting and deasserting the reset.
|
||||
* @param [in] bus Peripheral to be reset.
|
||||
* @warning Peripheral must be in enabled state in order to be reset.
|
||||
*/
|
||||
void furi_hal_bus_reset(FuriHalBus bus);
|
||||
|
||||
/**
|
||||
* Disable a peripheral by turning the clocking off and asserting the reset.
|
||||
* @param [in] bus Peripheral to be disabled.
|
||||
* @warning Peripheral must be in enabled state in order to be disabled.
|
||||
*/
|
||||
void furi_hal_bus_disable(FuriHalBus bus);
|
||||
|
||||
/** Check if peripheral is enabled
|
||||
*
|
||||
* @warning FuriHalBusAPB3_GRP1 is a special group of shared peripherals, for
|
||||
* core1 its clock is always on and the only status we can report is
|
||||
* peripheral reset status. Check code and Reference Manual for
|
||||
* details.
|
||||
*
|
||||
* @param[in] bus The peripheral to check
|
||||
*
|
||||
* @return true if enabled or always enabled, false otherwise
|
||||
*/
|
||||
bool furi_hal_bus_is_enabled(FuriHalBus bus);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -6,7 +6,6 @@
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_utils.h>
|
||||
#include <stm32wbxx_ll_cortex.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
|
||||
#define TAG "FuriHalClock"
|
||||
|
||||
@@ -19,36 +18,9 @@
|
||||
void furi_hal_clock_init_early() {
|
||||
LL_SetSystemCoreClock(CPU_CLOCK_HZ_EARLY);
|
||||
LL_Init1msTick(SystemCoreClock);
|
||||
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH);
|
||||
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2);
|
||||
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
}
|
||||
|
||||
void furi_hal_clock_deinit_early() {
|
||||
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
|
||||
LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
|
||||
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
|
||||
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
|
||||
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
|
||||
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOD);
|
||||
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOE);
|
||||
LL_AHB2_GRP1_DisableClock(LL_AHB2_GRP1_PERIPH_GPIOH);
|
||||
}
|
||||
|
||||
void furi_hal_clock_init() {
|
||||
@@ -137,68 +109,12 @@ void furi_hal_clock_init() {
|
||||
SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TICK_INT_PRIORITY, 0));
|
||||
NVIC_EnableIRQ(SysTick_IRQn);
|
||||
|
||||
LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2);
|
||||
LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1);
|
||||
LL_RCC_SetADCClockSource(LL_RCC_ADC_CLKSOURCE_PLLSAI1);
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
|
||||
LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48);
|
||||
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1);
|
||||
LL_RCC_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1);
|
||||
LL_RCC_HSI_EnableInStopMode(); // Ensure that MR is capable of work in STOP0
|
||||
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE);
|
||||
LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1);
|
||||
LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
|
||||
|
||||
// AHB1 GRP1
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA2);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);
|
||||
LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);
|
||||
// LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_TSC);
|
||||
|
||||
// AHB2 GRP1
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOB);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOC);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOD);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOE);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOH);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
|
||||
LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AES1);
|
||||
|
||||
// AHB3 GRP1
|
||||
// LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_QUADSPI);
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_PKA);
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_AES2);
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_RNG);
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_HSEM);
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
|
||||
LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_FLASH);
|
||||
|
||||
// APB1 GRP1
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
|
||||
// LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LCD);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
|
||||
// LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_WWDG);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_CRS);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_USB);
|
||||
LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_LPTIM1);
|
||||
|
||||
// APB1 GRP2
|
||||
LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPUART1);
|
||||
|
||||
// APB2
|
||||
// LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_ADC);
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_USART1);
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM16);
|
||||
LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM17);
|
||||
// LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SAI1);
|
||||
|
||||
FURI_LOG_I(TAG, "Init OK");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <furi_hal_crypto.h>
|
||||
#include <furi_hal_bt.h>
|
||||
#include <furi_hal_random.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stm32wbxx_ll_cortex.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
#include <furi.h>
|
||||
#include <interface/patterns/ble_thread/shci/shci.h>
|
||||
|
||||
@@ -241,6 +242,8 @@ bool furi_hal_crypto_store_load_key(uint8_t slot, const uint8_t* iv) {
|
||||
furi_assert(furi_hal_crypto_mutex);
|
||||
furi_check(furi_mutex_acquire(furi_hal_crypto_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
|
||||
furi_hal_bus_enable(FuriHalBusAES1);
|
||||
|
||||
if(!furi_hal_bt_is_alive()) {
|
||||
return false;
|
||||
}
|
||||
@@ -267,10 +270,7 @@ bool furi_hal_crypto_store_unload_key(uint8_t slot) {
|
||||
SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_UnloadUsrKey(slot);
|
||||
furi_assert(shci_state == SHCI_Success);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_AES1);
|
||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_AES1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusAES1);
|
||||
|
||||
furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk);
|
||||
return (shci_state == SHCI_Success);
|
||||
|
||||
14
firmware/targets/f7/furi_hal/furi_hal_dma.c
Normal file
14
firmware/targets/f7/furi_hal/furi_hal_dma.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include <furi_hal_dma.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
void furi_hal_dma_init_early() {
|
||||
furi_hal_bus_enable(FuriHalBusDMA1);
|
||||
furi_hal_bus_enable(FuriHalBusDMA2);
|
||||
furi_hal_bus_enable(FuriHalBusDMAMUX1);
|
||||
}
|
||||
|
||||
void furi_hal_dma_deinit_early() {
|
||||
furi_hal_bus_disable(FuriHalBusDMA1);
|
||||
furi_hal_bus_disable(FuriHalBusDMA2);
|
||||
furi_hal_bus_disable(FuriHalBusDMAMUX1);
|
||||
}
|
||||
15
firmware/targets/f7/furi_hal/furi_hal_dma.h
Normal file
15
firmware/targets/f7/furi_hal/furi_hal_dma.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Early initialization */
|
||||
void furi_hal_dma_init_early();
|
||||
|
||||
/** Early de-initialization */
|
||||
void furi_hal_dma_deinit_early();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
@@ -11,20 +11,20 @@
|
||||
#define TAG "FuriHalFlash"
|
||||
|
||||
#define FURI_HAL_CRITICAL_MSG "Critical flash operation fail"
|
||||
#define FURI_HAL_FLASH_READ_BLOCK 8
|
||||
#define FURI_HAL_FLASH_WRITE_BLOCK 8
|
||||
#define FURI_HAL_FLASH_PAGE_SIZE 4096
|
||||
#define FURI_HAL_FLASH_CYCLES_COUNT 10000
|
||||
#define FURI_HAL_FLASH_TIMEOUT 1000
|
||||
#define FURI_HAL_FLASH_KEY1 0x45670123U
|
||||
#define FURI_HAL_FLASH_KEY2 0xCDEF89ABU
|
||||
#define FURI_HAL_FLASH_TOTAL_PAGES 256
|
||||
#define FURI_HAL_FLASH_READ_BLOCK (8U)
|
||||
#define FURI_HAL_FLASH_WRITE_BLOCK (8U)
|
||||
#define FURI_HAL_FLASH_PAGE_SIZE (4096U)
|
||||
#define FURI_HAL_FLASH_CYCLES_COUNT (10000U)
|
||||
#define FURI_HAL_FLASH_TIMEOUT (1000U)
|
||||
#define FURI_HAL_FLASH_KEY1 (0x45670123U)
|
||||
#define FURI_HAL_FLASH_KEY2 (0xCDEF89ABU)
|
||||
#define FURI_HAL_FLASH_TOTAL_PAGES (256U)
|
||||
#define FURI_HAL_FLASH_SR_ERRORS \
|
||||
(FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | \
|
||||
FLASH_SR_PGSERR | FLASH_SR_MISERR | FLASH_SR_FASTERR | FLASH_SR_RDERR | FLASH_SR_OPTVERR)
|
||||
|
||||
#define FURI_HAL_FLASH_OPT_KEY1 0x08192A3B
|
||||
#define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F
|
||||
#define FURI_HAL_FLASH_OPT_KEY1 (0x08192A3BU)
|
||||
#define FURI_HAL_FLASH_OPT_KEY2 (0x4C5D6E7FU)
|
||||
#define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2))
|
||||
|
||||
/* STM32CubeWB/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_RfWithFlash/Core/Src/flash_driver.c
|
||||
@@ -35,7 +35,7 @@
|
||||
> 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 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__) \
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
#include <furi_hal_i2c_config.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_version.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
|
||||
/** Timing register value is computed with the STM32CubeMX Tool,
|
||||
@@ -21,17 +22,9 @@ FuriMutex* furi_hal_i2c_bus_power_mutex = NULL;
|
||||
static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
||||
if(event == FuriHalI2cBusEventInit) {
|
||||
furi_hal_i2c_bus_power_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if(event == FuriHalI2cBusEventDeinit) {
|
||||
furi_mutex_free(furi_hal_i2c_bus_power_mutex);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalI2cBusEventLock) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(furi_hal_i2c_bus_power_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
@@ -39,12 +32,11 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent
|
||||
furi_check(furi_mutex_release(furi_hal_i2c_bus_power_mutex) == FuriStatusOk);
|
||||
} else if(event == FuriHalI2cBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
furi_hal_bus_enable(FuriHalBusI2C1);
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalI2cBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusI2C1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -58,17 +50,9 @@ FuriMutex* furi_hal_i2c_bus_external_mutex = NULL;
|
||||
static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
||||
if(event == FuriHalI2cBusEventInit) {
|
||||
furi_hal_i2c_bus_external_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if(event == FuriHalI2cBusEventDeinit) {
|
||||
furi_mutex_free(furi_hal_i2c_bus_external_mutex);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalI2cBusEventLock) {
|
||||
furi_check(
|
||||
furi_mutex_acquire(furi_hal_i2c_bus_external_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
@@ -76,13 +60,11 @@ static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEve
|
||||
furi_check(furi_mutex_release(furi_hal_i2c_bus_external_mutex) == FuriStatusOk);
|
||||
} else if(event == FuriHalI2cBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
furi_hal_bus_enable(FuriHalBusI2C3);
|
||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalI2cBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusI2C3);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
#include <furi_hal_ibutton.h>
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stm32wbxx_ll_tim.h>
|
||||
#include <stm32wbxx_ll_exti.h>
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
#define TAG "FuriHalIbutton"
|
||||
#define FURI_HAL_IBUTTON_TIMER TIM1
|
||||
#define FURI_HAL_IBUTTON_TIMER_BUS FuriHalBusTIM1
|
||||
#define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16
|
||||
|
||||
typedef enum {
|
||||
@@ -49,9 +50,7 @@ void furi_hal_ibutton_emulate_start(
|
||||
furi_hal_ibutton->callback = callback;
|
||||
furi_hal_ibutton->context = context;
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FURI_HAL_IBUTTON_TIMER_BUS);
|
||||
|
||||
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, furi_hal_ibutton_emulate_isr, NULL);
|
||||
|
||||
@@ -81,10 +80,7 @@ void furi_hal_ibutton_emulate_stop() {
|
||||
furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
|
||||
LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
||||
FURI_CRITICAL_EXIT();
|
||||
|
||||
furi_hal_bus_disable(FURI_HAL_IBUTTON_TIMER_BUS);
|
||||
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, NULL, NULL);
|
||||
|
||||
furi_hal_ibutton->callback = NULL;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <stm32wbxx_ll_lptim.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
// Timer used for tickless idle
|
||||
#define FURI_HAL_IDLE_TIMER_MAX 0xFFFF
|
||||
@@ -10,6 +12,7 @@
|
||||
#define FURI_HAL_IDLE_TIMER_IRQ LPTIM1_IRQn
|
||||
|
||||
static inline void furi_hal_idle_timer_init() {
|
||||
furi_hal_bus_enable(FuriHalBusLPTIM1);
|
||||
// Configure clock source
|
||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
|
||||
// There is a theoretical possibility that we need it
|
||||
@@ -40,7 +43,7 @@ static inline void furi_hal_idle_timer_start(uint32_t count) {
|
||||
static inline void furi_hal_idle_timer_reset() {
|
||||
// Hard reset timer
|
||||
// THE ONLY RELIABLE WAY to stop it according to errata
|
||||
LL_LPTIM_DeInit(FURI_HAL_IDLE_TIMER);
|
||||
furi_hal_bus_reset(FuriHalBusLPTIM1);
|
||||
// Prevent IRQ handler call
|
||||
NVIC_ClearPendingIRQ(FURI_HAL_IDLE_TIMER_IRQ);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
||||
property_value_out(&property_context, NULL, 2, "format", "minor", "1");
|
||||
} else {
|
||||
property_value_out(&property_context, NULL, 3, "device", "info", "major", "2");
|
||||
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "1");
|
||||
property_value_out(&property_context, NULL, 3, "device", "info", "minor", "2");
|
||||
}
|
||||
|
||||
// Model name
|
||||
@@ -173,6 +173,24 @@ void furi_hal_info_get(PropertyValueCallback out, char sep, void* context) {
|
||||
&property_context, "%d", 3, "firmware", "api", "major", api_version_major);
|
||||
property_value_out(
|
||||
&property_context, "%d", 3, "firmware", "api", "minor", api_version_minor);
|
||||
|
||||
property_value_out(
|
||||
&property_context,
|
||||
NULL,
|
||||
3,
|
||||
"firmware",
|
||||
"origin",
|
||||
"fork",
|
||||
version_get_firmware_origin(firmware_version));
|
||||
|
||||
property_value_out(
|
||||
&property_context,
|
||||
NULL,
|
||||
3,
|
||||
"firmware",
|
||||
"origin",
|
||||
"git",
|
||||
version_get_git_origin(firmware_version));
|
||||
}
|
||||
|
||||
if(furi_hal_bt_is_alive()) {
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
#include <furi_hal_infrared.h>
|
||||
#include <core/check.h>
|
||||
#include "stm32wbxx_ll_dma.h"
|
||||
#include "sys/_stdint.h"
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stm32wbxx_ll_tim.h>
|
||||
#include <stm32wbxx_ll_gpio.h>
|
||||
#include <stm32wbxx_ll_dma.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <furi.h>
|
||||
#include <math.h>
|
||||
|
||||
@@ -22,13 +18,23 @@
|
||||
(TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */
|
||||
|
||||
/* DMA Channels definition */
|
||||
#define IR_DMA DMA2
|
||||
#define IR_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
|
||||
#define IR_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
|
||||
#define IR_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
|
||||
#define IR_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2
|
||||
#define IR_DMA_CH1_DEF IR_DMA, IR_DMA_CH1_CHANNEL
|
||||
#define IR_DMA_CH2_DEF IR_DMA, IR_DMA_CH2_CHANNEL
|
||||
#define INFRARED_DMA DMA2
|
||||
#define INFRARED_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
|
||||
#define INFRARED_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
|
||||
#define INFRARED_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
|
||||
#define INFRARED_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2
|
||||
#define INFRARED_DMA_CH1_DEF INFRARED_DMA, INFRARED_DMA_CH1_CHANNEL
|
||||
#define INFRARED_DMA_CH2_DEF INFRARED_DMA, INFRARED_DMA_CH2_CHANNEL
|
||||
|
||||
/* Timers definition */
|
||||
#define INFRARED_RX_TIMER TIM2
|
||||
#define INFRARED_DMA_TIMER TIM1
|
||||
#define INFRARED_RX_TIMER_BUS FuriHalBusTIM2
|
||||
#define INFRARED_DMA_TIMER_BUS FuriHalBusTIM1
|
||||
|
||||
/* Misc */
|
||||
#define INFRARED_RX_GPIO_ALT GpioAltFn1TIM2
|
||||
#define INFRARED_RX_IRQ FuriHalInterruptIdTIM2
|
||||
|
||||
typedef struct {
|
||||
FuriHalInfraredRxCaptureCallback capture_callback;
|
||||
@@ -95,8 +101,8 @@ static void furi_hal_infrared_tim_rx_isr() {
|
||||
static uint32_t previous_captured_ch2 = 0;
|
||||
|
||||
/* Timeout */
|
||||
if(LL_TIM_IsActiveFlag_CC3(TIM2)) {
|
||||
LL_TIM_ClearFlag_CC3(TIM2);
|
||||
if(LL_TIM_IsActiveFlag_CC3(INFRARED_RX_TIMER)) {
|
||||
LL_TIM_ClearFlag_CC3(INFRARED_RX_TIMER);
|
||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||
|
||||
/* Timers CNT register starts to counting from 0 to ARR, but it is
|
||||
@@ -112,13 +118,13 @@ static void furi_hal_infrared_tim_rx_isr() {
|
||||
}
|
||||
|
||||
/* Rising Edge */
|
||||
if(LL_TIM_IsActiveFlag_CC1(TIM2)) {
|
||||
LL_TIM_ClearFlag_CC1(TIM2);
|
||||
if(LL_TIM_IsActiveFlag_CC1(INFRARED_RX_TIMER)) {
|
||||
LL_TIM_ClearFlag_CC1(INFRARED_RX_TIMER);
|
||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||
|
||||
if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC1S)) {
|
||||
if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC1S)) {
|
||||
/* Low pin level is a Mark state of INFRARED signal. Invert level for further processing. */
|
||||
uint32_t duration = LL_TIM_IC_GetCaptureCH1(TIM2) - previous_captured_ch2;
|
||||
uint32_t duration = LL_TIM_IC_GetCaptureCH1(INFRARED_RX_TIMER) - previous_captured_ch2;
|
||||
if(infrared_tim_rx.capture_callback)
|
||||
infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 1, duration);
|
||||
} else {
|
||||
@@ -127,13 +133,13 @@ static void furi_hal_infrared_tim_rx_isr() {
|
||||
}
|
||||
|
||||
/* Falling Edge */
|
||||
if(LL_TIM_IsActiveFlag_CC2(TIM2)) {
|
||||
LL_TIM_ClearFlag_CC2(TIM2);
|
||||
if(LL_TIM_IsActiveFlag_CC2(INFRARED_RX_TIMER)) {
|
||||
LL_TIM_ClearFlag_CC2(INFRARED_RX_TIMER);
|
||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||
|
||||
if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC2S)) {
|
||||
if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC2S)) {
|
||||
/* High pin level is a Space state of INFRARED signal. Invert level for further processing. */
|
||||
uint32_t duration = LL_TIM_IC_GetCaptureCH2(TIM2);
|
||||
uint32_t duration = LL_TIM_IC_GetCaptureCH2(INFRARED_RX_TIMER);
|
||||
previous_captured_ch2 = duration;
|
||||
if(infrared_tim_rx.capture_callback)
|
||||
infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 0, duration);
|
||||
@@ -147,62 +153,66 @@ void furi_hal_infrared_async_rx_start(void) {
|
||||
furi_assert(furi_hal_infrared_state == InfraredStateIdle);
|
||||
|
||||
furi_hal_gpio_init_ex(
|
||||
&gpio_infrared_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2);
|
||||
&gpio_infrared_rx,
|
||||
GpioModeAltFunctionPushPull,
|
||||
GpioPullNo,
|
||||
GpioSpeedLow,
|
||||
INFRARED_RX_GPIO_ALT);
|
||||
|
||||
furi_hal_bus_enable(INFRARED_RX_TIMER_BUS);
|
||||
|
||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||
TIM_InitStruct.Prescaler = 64 - 1;
|
||||
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||
TIM_InitStruct.Autoreload = 0x7FFFFFFE;
|
||||
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||
LL_TIM_Init(TIM2, &TIM_InitStruct);
|
||||
LL_TIM_Init(INFRARED_RX_TIMER, &TIM_InitStruct);
|
||||
|
||||
LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
|
||||
LL_TIM_DisableARRPreload(TIM2);
|
||||
LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI1FP1);
|
||||
LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET);
|
||||
LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
||||
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
|
||||
LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING);
|
||||
LL_TIM_DisableIT_TRIG(TIM2);
|
||||
LL_TIM_DisableDMAReq_TRIG(TIM2);
|
||||
LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET);
|
||||
LL_TIM_EnableMasterSlaveMode(TIM2);
|
||||
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
||||
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
|
||||
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
|
||||
LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
|
||||
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
|
||||
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
|
||||
LL_TIM_SetClockSource(INFRARED_RX_TIMER, LL_TIM_CLOCKSOURCE_INTERNAL);
|
||||
LL_TIM_DisableARRPreload(INFRARED_RX_TIMER);
|
||||
LL_TIM_SetTriggerInput(INFRARED_RX_TIMER, LL_TIM_TS_TI1FP1);
|
||||
LL_TIM_SetSlaveMode(INFRARED_RX_TIMER, LL_TIM_SLAVEMODE_RESET);
|
||||
LL_TIM_CC_DisableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2);
|
||||
LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
|
||||
LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING);
|
||||
LL_TIM_DisableIT_TRIG(INFRARED_RX_TIMER);
|
||||
LL_TIM_DisableDMAReq_TRIG(INFRARED_RX_TIMER);
|
||||
LL_TIM_SetTriggerOutput(INFRARED_RX_TIMER, LL_TIM_TRGO_RESET);
|
||||
LL_TIM_EnableMasterSlaveMode(INFRARED_RX_TIMER);
|
||||
LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
||||
LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
|
||||
LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
|
||||
LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
|
||||
LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
|
||||
LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
|
||||
|
||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_infrared_tim_rx_isr, NULL);
|
||||
furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, furi_hal_infrared_tim_rx_isr, NULL);
|
||||
furi_hal_infrared_state = InfraredStateAsyncRx;
|
||||
|
||||
LL_TIM_EnableIT_CC1(TIM2);
|
||||
LL_TIM_EnableIT_CC2(TIM2);
|
||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
|
||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
||||
LL_TIM_EnableIT_CC1(INFRARED_RX_TIMER);
|
||||
LL_TIM_EnableIT_CC2(INFRARED_RX_TIMER);
|
||||
LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1);
|
||||
LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2);
|
||||
|
||||
LL_TIM_SetCounter(TIM2, 0);
|
||||
LL_TIM_EnableCounter(TIM2);
|
||||
LL_TIM_SetCounter(INFRARED_RX_TIMER, 0);
|
||||
LL_TIM_EnableCounter(INFRARED_RX_TIMER);
|
||||
}
|
||||
|
||||
void furi_hal_infrared_async_rx_stop(void) {
|
||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
|
||||
LL_TIM_DeInit(TIM2);
|
||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
|
||||
furi_hal_bus_disable(INFRARED_RX_TIMER_BUS);
|
||||
furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, NULL, NULL);
|
||||
furi_hal_infrared_state = InfraredStateIdle;
|
||||
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us) {
|
||||
LL_TIM_OC_SetCompareCH3(TIM2, timeout_us);
|
||||
LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);
|
||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3);
|
||||
LL_TIM_EnableIT_CC3(TIM2);
|
||||
LL_TIM_OC_SetCompareCH3(INFRARED_RX_TIMER, timeout_us);
|
||||
LL_TIM_OC_SetMode(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);
|
||||
LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3);
|
||||
LL_TIM_EnableIT_CC3(INFRARED_RX_TIMER);
|
||||
}
|
||||
|
||||
bool furi_hal_infrared_is_busy(void) {
|
||||
@@ -224,16 +234,16 @@ void furi_hal_infrared_async_rx_set_timeout_isr_callback(
|
||||
}
|
||||
|
||||
static void furi_hal_infrared_tx_dma_terminate(void) {
|
||||
LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF);
|
||||
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
|
||||
LL_DMA_DisableIT_TC(IR_DMA_CH2_DEF);
|
||||
LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF);
|
||||
LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||
LL_DMA_DisableIT_TC(INFRARED_DMA_CH2_DEF);
|
||||
|
||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress);
|
||||
|
||||
LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF);
|
||||
LL_DMA_DisableChannel(IR_DMA_CH2_DEF);
|
||||
LL_DMA_DisableChannel(IR_DMA_CH1_DEF);
|
||||
LL_TIM_DisableCounter(TIM1);
|
||||
LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF);
|
||||
LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF);
|
||||
LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF);
|
||||
LL_TIM_DisableCounter(INFRARED_DMA_TIMER);
|
||||
FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore);
|
||||
furi_check(status == FuriStatusOk);
|
||||
furi_hal_infrared_state = InfraredStateAsyncTxStopped;
|
||||
@@ -241,7 +251,7 @@ static void furi_hal_infrared_tx_dma_terminate(void) {
|
||||
|
||||
static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
|
||||
uint8_t buf_num = 0;
|
||||
uint32_t buffer_adr = LL_DMA_GetMemoryAddress(IR_DMA_CH2_DEF);
|
||||
uint32_t buffer_adr = LL_DMA_GetMemoryAddress(INFRARED_DMA_CH2_DEF);
|
||||
if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[0].data) {
|
||||
buf_num = 0;
|
||||
} else if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[1].data) {
|
||||
@@ -253,13 +263,13 @@ static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
|
||||
}
|
||||
|
||||
static void furi_hal_infrared_tx_dma_polarity_isr() {
|
||||
#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
||||
if(LL_DMA_IsActiveFlag_TE1(IR_DMA)) {
|
||||
LL_DMA_ClearFlag_TE1(IR_DMA);
|
||||
#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
||||
if(LL_DMA_IsActiveFlag_TE1(INFRARED_DMA)) {
|
||||
LL_DMA_ClearFlag_TE1(INFRARED_DMA);
|
||||
furi_crash(NULL);
|
||||
}
|
||||
if(LL_DMA_IsActiveFlag_TC1(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH1_DEF)) {
|
||||
LL_DMA_ClearFlag_TC1(IR_DMA);
|
||||
if(LL_DMA_IsActiveFlag_TC1(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH1_DEF)) {
|
||||
LL_DMA_ClearFlag_TC1(INFRARED_DMA);
|
||||
|
||||
furi_check(
|
||||
(furi_hal_infrared_state == InfraredStateAsyncTx) ||
|
||||
@@ -275,23 +285,23 @@ static void furi_hal_infrared_tx_dma_polarity_isr() {
|
||||
}
|
||||
|
||||
static void furi_hal_infrared_tx_dma_isr() {
|
||||
#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
||||
if(LL_DMA_IsActiveFlag_TE2(IR_DMA)) {
|
||||
LL_DMA_ClearFlag_TE2(IR_DMA);
|
||||
#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
||||
if(LL_DMA_IsActiveFlag_TE2(INFRARED_DMA)) {
|
||||
LL_DMA_ClearFlag_TE2(INFRARED_DMA);
|
||||
furi_crash(NULL);
|
||||
}
|
||||
if(LL_DMA_IsActiveFlag_HT2(IR_DMA) && LL_DMA_IsEnabledIT_HT(IR_DMA_CH2_DEF)) {
|
||||
LL_DMA_ClearFlag_HT2(IR_DMA);
|
||||
if(LL_DMA_IsActiveFlag_HT2(INFRARED_DMA) && LL_DMA_IsEnabledIT_HT(INFRARED_DMA_CH2_DEF)) {
|
||||
LL_DMA_ClearFlag_HT2(INFRARED_DMA);
|
||||
uint8_t buf_num = furi_hal_infrared_get_current_dma_tx_buffer();
|
||||
uint8_t next_buf_num = !buf_num;
|
||||
if(infrared_tim_tx.buffer[buf_num].last_packet_end) {
|
||||
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
|
||||
LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||
} else if(
|
||||
!infrared_tim_tx.buffer[buf_num].packet_end ||
|
||||
(furi_hal_infrared_state == InfraredStateAsyncTx)) {
|
||||
furi_hal_infrared_tx_fill_buffer(next_buf_num, 0);
|
||||
if(infrared_tim_tx.buffer[next_buf_num].last_packet_end) {
|
||||
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
|
||||
LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||
}
|
||||
} else if(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) {
|
||||
/* fallthrough */
|
||||
@@ -299,8 +309,8 @@ static void furi_hal_infrared_tx_dma_isr() {
|
||||
furi_crash(NULL);
|
||||
}
|
||||
}
|
||||
if(LL_DMA_IsActiveFlag_TC2(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH2_DEF)) {
|
||||
LL_DMA_ClearFlag_TC2(IR_DMA);
|
||||
if(LL_DMA_IsActiveFlag_TC2(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH2_DEF)) {
|
||||
LL_DMA_ClearFlag_TC2(INFRARED_DMA);
|
||||
furi_check(
|
||||
(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress) ||
|
||||
(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) ||
|
||||
@@ -332,39 +342,42 @@ static void furi_hal_infrared_tx_dma_isr() {
|
||||
}
|
||||
|
||||
static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) {
|
||||
/* LL_DBGMCU_APB2_GRP1_FreezePeriph(LL_DBGMCU_APB2_GRP1_TIM1_STOP); */
|
||||
|
||||
LL_TIM_DisableCounter(TIM1);
|
||||
LL_TIM_SetRepetitionCounter(TIM1, 0);
|
||||
LL_TIM_SetCounter(TIM1, 0);
|
||||
LL_TIM_SetPrescaler(TIM1, 0);
|
||||
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_EnableARRPreload(TIM1);
|
||||
LL_TIM_DisableCounter(INFRARED_DMA_TIMER);
|
||||
LL_TIM_SetRepetitionCounter(INFRARED_DMA_TIMER, 0);
|
||||
LL_TIM_SetCounter(INFRARED_DMA_TIMER, 0);
|
||||
LL_TIM_SetPrescaler(INFRARED_DMA_TIMER, 0);
|
||||
LL_TIM_SetCounterMode(INFRARED_DMA_TIMER, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_EnableARRPreload(INFRARED_DMA_TIMER);
|
||||
LL_TIM_SetAutoReload(
|
||||
TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq));
|
||||
INFRARED_DMA_TIMER,
|
||||
__LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(INFRARED_DMA_TIMER), freq));
|
||||
if(infrared_external_output) {
|
||||
LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle)));
|
||||
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
|
||||
LL_TIM_OC_SetCompareCH1(
|
||||
INFRARED_DMA_TIMER,
|
||||
((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle)));
|
||||
LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1);
|
||||
/* LL_TIM_OCMODE_PWM2 set by DMA */
|
||||
LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||
LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH);
|
||||
LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1);
|
||||
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N);
|
||||
LL_TIM_DisableIT_CC1(TIM1);
|
||||
LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||
LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH);
|
||||
LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1);
|
||||
LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N);
|
||||
LL_TIM_DisableIT_CC1(INFRARED_DMA_TIMER);
|
||||
} else {
|
||||
LL_TIM_OC_SetCompareCH3(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle)));
|
||||
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3);
|
||||
LL_TIM_OC_SetCompareCH3(
|
||||
INFRARED_DMA_TIMER,
|
||||
((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle)));
|
||||
LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3);
|
||||
/* LL_TIM_OCMODE_PWM2 set by DMA */
|
||||
LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||
LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH);
|
||||
LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3);
|
||||
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N);
|
||||
LL_TIM_DisableIT_CC3(TIM1);
|
||||
LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||
LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH);
|
||||
LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3);
|
||||
LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N);
|
||||
LL_TIM_DisableIT_CC3(INFRARED_DMA_TIMER);
|
||||
}
|
||||
LL_TIM_DisableMasterSlaveMode(TIM1);
|
||||
LL_TIM_EnableAllOutputs(TIM1);
|
||||
LL_TIM_DisableIT_UPDATE(TIM1);
|
||||
LL_TIM_EnableDMAReq_UPDATE(TIM1);
|
||||
LL_TIM_DisableMasterSlaveMode(INFRARED_DMA_TIMER);
|
||||
LL_TIM_EnableAllOutputs(INFRARED_DMA_TIMER);
|
||||
LL_TIM_DisableIT_UPDATE(INFRARED_DMA_TIMER);
|
||||
LL_TIM_EnableDMAReq_UPDATE(INFRARED_DMA_TIMER);
|
||||
|
||||
NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
||||
NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
|
||||
@@ -373,9 +386,9 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc
|
||||
static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
|
||||
LL_DMA_InitTypeDef dma_config = {0};
|
||||
if(infrared_external_output) {
|
||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1);
|
||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR1);
|
||||
} else {
|
||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2);
|
||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR2);
|
||||
}
|
||||
dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
|
||||
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||
@@ -388,24 +401,25 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
|
||||
dma_config.NbData = 0;
|
||||
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
|
||||
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
|
||||
LL_DMA_Init(IR_DMA_CH1_DEF, &dma_config);
|
||||
LL_DMA_Init(INFRARED_DMA_CH1_DEF, &dma_config);
|
||||
|
||||
#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
||||
LL_DMA_ClearFlag_TE1(IR_DMA);
|
||||
LL_DMA_ClearFlag_TC1(IR_DMA);
|
||||
#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
||||
LL_DMA_ClearFlag_TE1(INFRARED_DMA);
|
||||
LL_DMA_ClearFlag_TC1(INFRARED_DMA);
|
||||
#else
|
||||
#error Update this code. Would you kindly?
|
||||
#endif
|
||||
|
||||
LL_DMA_EnableIT_TE(IR_DMA_CH1_DEF);
|
||||
LL_DMA_EnableIT_TC(IR_DMA_CH1_DEF);
|
||||
LL_DMA_EnableIT_TE(INFRARED_DMA_CH1_DEF);
|
||||
LL_DMA_EnableIT_TC(INFRARED_DMA_CH1_DEF);
|
||||
|
||||
furi_hal_interrupt_set_isr_ex(IR_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
|
||||
furi_hal_interrupt_set_isr_ex(
|
||||
INFRARED_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
|
||||
}
|
||||
|
||||
static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
|
||||
LL_DMA_InitTypeDef dma_config = {0};
|
||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->RCR);
|
||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->RCR);
|
||||
dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
|
||||
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||
dma_config.Mode = LL_DMA_MODE_NORMAL;
|
||||
@@ -416,21 +430,21 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
|
||||
dma_config.NbData = 0;
|
||||
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
|
||||
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
|
||||
LL_DMA_Init(IR_DMA_CH2_DEF, &dma_config);
|
||||
LL_DMA_Init(INFRARED_DMA_CH2_DEF, &dma_config);
|
||||
|
||||
#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
||||
LL_DMA_ClearFlag_TC2(IR_DMA);
|
||||
LL_DMA_ClearFlag_HT2(IR_DMA);
|
||||
LL_DMA_ClearFlag_TE2(IR_DMA);
|
||||
#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
||||
LL_DMA_ClearFlag_TC2(INFRARED_DMA);
|
||||
LL_DMA_ClearFlag_HT2(INFRARED_DMA);
|
||||
LL_DMA_ClearFlag_TE2(INFRARED_DMA);
|
||||
#else
|
||||
#error Update this code. Would you kindly?
|
||||
#endif
|
||||
|
||||
LL_DMA_EnableIT_TC(IR_DMA_CH2_DEF);
|
||||
LL_DMA_EnableIT_HT(IR_DMA_CH2_DEF);
|
||||
LL_DMA_EnableIT_TE(IR_DMA_CH2_DEF);
|
||||
LL_DMA_EnableIT_TC(INFRARED_DMA_CH2_DEF);
|
||||
LL_DMA_EnableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||
LL_DMA_EnableIT_TE(INFRARED_DMA_CH2_DEF);
|
||||
|
||||
furi_hal_interrupt_set_isr_ex(IR_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL);
|
||||
furi_hal_interrupt_set_isr_ex(INFRARED_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL);
|
||||
}
|
||||
|
||||
static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) {
|
||||
@@ -532,14 +546,14 @@ static void furi_hal_infrared_tx_dma_set_polarity(uint8_t buf_num, uint8_t polar
|
||||
furi_assert(buffer->polarity != NULL);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH1_DEF);
|
||||
bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH1_DEF);
|
||||
if(channel_enabled) {
|
||||
LL_DMA_DisableChannel(IR_DMA_CH1_DEF);
|
||||
LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF);
|
||||
}
|
||||
LL_DMA_SetMemoryAddress(IR_DMA_CH1_DEF, (uint32_t)buffer->polarity);
|
||||
LL_DMA_SetDataLength(IR_DMA_CH1_DEF, buffer->size + polarity_shift);
|
||||
LL_DMA_SetMemoryAddress(INFRARED_DMA_CH1_DEF, (uint32_t)buffer->polarity);
|
||||
LL_DMA_SetDataLength(INFRARED_DMA_CH1_DEF, buffer->size + polarity_shift);
|
||||
if(channel_enabled) {
|
||||
LL_DMA_EnableChannel(IR_DMA_CH1_DEF);
|
||||
LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF);
|
||||
}
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
@@ -552,14 +566,14 @@ static void furi_hal_infrared_tx_dma_set_buffer(uint8_t buf_num) {
|
||||
|
||||
/* non-circular mode requires disabled channel before setup */
|
||||
FURI_CRITICAL_ENTER();
|
||||
bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH2_DEF);
|
||||
bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH2_DEF);
|
||||
if(channel_enabled) {
|
||||
LL_DMA_DisableChannel(IR_DMA_CH2_DEF);
|
||||
LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF);
|
||||
}
|
||||
LL_DMA_SetMemoryAddress(IR_DMA_CH2_DEF, (uint32_t)buffer->data);
|
||||
LL_DMA_SetDataLength(IR_DMA_CH2_DEF, buffer->size);
|
||||
LL_DMA_SetMemoryAddress(INFRARED_DMA_CH2_DEF, (uint32_t)buffer->data);
|
||||
LL_DMA_SetDataLength(INFRARED_DMA_CH2_DEF, buffer->size);
|
||||
if(channel_enabled) {
|
||||
LL_DMA_EnableChannel(IR_DMA_CH2_DEF);
|
||||
LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF);
|
||||
}
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
@@ -574,9 +588,10 @@ static void furi_hal_infrared_async_tx_free_resources(void) {
|
||||
} else {
|
||||
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);
|
||||
LL_TIM_DeInit(TIM1);
|
||||
furi_hal_interrupt_set_isr(INFRARED_DMA_CH1_IRQ, NULL, NULL);
|
||||
furi_hal_interrupt_set_isr(INFRARED_DMA_CH2_IRQ, NULL, NULL);
|
||||
|
||||
furi_hal_bus_disable(INFRARED_DMA_TIMER_BUS);
|
||||
|
||||
furi_semaphore_free(infrared_tim_tx.stop_semaphore);
|
||||
free(infrared_tim_tx.buffer[0].data);
|
||||
@@ -617,6 +632,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
||||
|
||||
furi_hal_infrared_tx_fill_buffer(0, INFRARED_POLARITY_SHIFT);
|
||||
|
||||
furi_hal_bus_enable(INFRARED_DMA_TIMER_BUS);
|
||||
|
||||
furi_hal_infrared_configure_tim_pwm_tx(freq, duty_cycle);
|
||||
furi_hal_infrared_configure_tim_cmgr2_dma_tx();
|
||||
furi_hal_infrared_configure_tim_rcr_dma_tx();
|
||||
@@ -625,11 +642,11 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
||||
|
||||
furi_hal_infrared_state = InfraredStateAsyncTx;
|
||||
|
||||
LL_TIM_ClearFlag_UPDATE(TIM1);
|
||||
LL_DMA_EnableChannel(IR_DMA_CH1_DEF);
|
||||
LL_DMA_EnableChannel(IR_DMA_CH2_DEF);
|
||||
LL_TIM_ClearFlag_UPDATE(INFRARED_DMA_TIMER);
|
||||
LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF);
|
||||
LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF);
|
||||
furi_delay_us(5);
|
||||
LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */
|
||||
LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* DMA -> TIMx_RCR */
|
||||
furi_delay_us(5);
|
||||
if(infrared_external_output) {
|
||||
LL_GPIO_ResetOutputPin(
|
||||
@@ -649,8 +666,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
||||
}
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */
|
||||
LL_TIM_EnableCounter(TIM1);
|
||||
LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* TIMx_RCR -> Repetition counter */
|
||||
LL_TIM_EnableCounter(INFRARED_DMA_TIMER);
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
#include <furi_hal_pwm.h>
|
||||
#include <core/check.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stm32wbxx_ll_tim.h>
|
||||
#include <stm32wbxx_ll_lptim.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
@@ -29,9 +28,7 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty)
|
||||
GpioSpeedVeryHigh,
|
||||
GpioAltFn1TIM1);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(TIM1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FuriHalBusTIM1);
|
||||
|
||||
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_SetRepetitionCounter(TIM1, 0);
|
||||
@@ -58,9 +55,7 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty)
|
||||
GpioSpeedVeryHigh,
|
||||
GpioAltFn14LPTIM2);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_LPTIM_DeInit(LPTIM2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FuriHalBusLPTIM2);
|
||||
|
||||
LL_LPTIM_SetUpdateMode(LPTIM2, LL_LPTIM_UPDATE_MODE_ENDOFPERIOD);
|
||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1);
|
||||
@@ -80,14 +75,10 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty)
|
||||
void furi_hal_pwm_stop(FuriHalPwmOutputId channel) {
|
||||
if(channel == FuriHalPwmOutputIdTim1PA7) {
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(TIM1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusTIM1);
|
||||
} else if(channel == FuriHalPwmOutputIdLptim2PA4) {
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_LPTIM_DeInit(LPTIM2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusLPTIM2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <furi_hal_random.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal.h>
|
||||
|
||||
#include <stm32wbxx_ll_rng.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_hsem.h>
|
||||
|
||||
#include <hw_conf.h>
|
||||
@@ -32,6 +33,11 @@ static uint32_t furi_hal_random_read_rng() {
|
||||
return LL_RNG_ReadRandData32(RNG);
|
||||
}
|
||||
|
||||
void furi_hal_random_init() {
|
||||
furi_hal_bus_enable(FuriHalBusRNG);
|
||||
LL_RCC_SetRNGClockSource(LL_RCC_RNG_CLKSOURCE_CLK48);
|
||||
}
|
||||
|
||||
uint32_t furi_hal_random_get() {
|
||||
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID))
|
||||
;
|
||||
@@ -40,6 +46,7 @@ uint32_t furi_hal_random_get() {
|
||||
const uint32_t random_val = furi_hal_random_read_rng();
|
||||
|
||||
LL_RNG_Disable(RNG);
|
||||
;
|
||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
|
||||
|
||||
return random_val;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
@@ -111,6 +112,13 @@ static void furi_hal_resources_init_input_pins(GpioMode mode) {
|
||||
}
|
||||
|
||||
void furi_hal_resources_init_early() {
|
||||
furi_hal_bus_enable(FuriHalBusGPIOA);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOB);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOC);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOD);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOE);
|
||||
furi_hal_bus_enable(FuriHalBusGPIOH);
|
||||
|
||||
furi_hal_resources_init_input_pins(GpioModeInput);
|
||||
|
||||
// SD Card stepdown control
|
||||
@@ -155,6 +163,12 @@ void furi_hal_resources_init_early() {
|
||||
|
||||
void furi_hal_resources_deinit_early() {
|
||||
furi_hal_resources_init_input_pins(GpioModeAnalog);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOA);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOB);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOC);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOD);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOE);
|
||||
furi_hal_bus_disable(FuriHalBusGPIOH);
|
||||
}
|
||||
|
||||
void furi_hal_resources_init() {
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <furi_hal_ibutton.h>
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi.h>
|
||||
|
||||
#include <stm32wbxx_ll_tim.h>
|
||||
@@ -9,15 +10,18 @@
|
||||
#include <stm32wbxx_ll_dma.h>
|
||||
|
||||
#define FURI_HAL_RFID_READ_TIMER TIM1
|
||||
#define FURI_HAL_RFID_READ_TIMER_BUS FuriHalBusTIM1
|
||||
#define FURI_HAL_RFID_READ_TIMER_CHANNEL LL_TIM_CHANNEL_CH1N
|
||||
// We can't use N channel for LL_TIM_OC_Init, so...
|
||||
#define FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG LL_TIM_CHANNEL_CH1
|
||||
|
||||
#define FURI_HAL_RFID_EMULATE_TIMER TIM2
|
||||
#define FURI_HAL_RFID_EMULATE_TIMER_BUS FuriHalBusTIM2
|
||||
#define FURI_HAL_RFID_EMULATE_TIMER_IRQ FuriHalInterruptIdTIM2
|
||||
#define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
|
||||
|
||||
#define RFID_CAPTURE_TIM TIM2
|
||||
#define RFID_CAPTURE_TIM_BUS FuriHalBusTIM2
|
||||
#define RFID_CAPTURE_IND_CH LL_TIM_CHANNEL_CH3
|
||||
#define RFID_CAPTURE_DIR_CH LL_TIM_CHANNEL_CH4
|
||||
|
||||
@@ -30,7 +34,6 @@
|
||||
#define RFID_DMA_CH2_DEF RFID_DMA, RFID_DMA_CH2_CHANNEL
|
||||
|
||||
typedef struct {
|
||||
FuriHalRfidEmulateCallback callback;
|
||||
FuriHalRfidDMACallback dma_callback;
|
||||
FuriHalRfidReadCaptureCallback read_capture_callback;
|
||||
void* context;
|
||||
@@ -56,11 +59,7 @@ void furi_hal_rfid_init() {
|
||||
COMP_InitStruct.InputPlus = LL_COMP_INPUT_PLUS_IO1;
|
||||
COMP_InitStruct.InputMinus = LL_COMP_INPUT_MINUS_1_2VREFINT;
|
||||
COMP_InitStruct.InputHysteresis = LL_COMP_HYSTERESIS_HIGH;
|
||||
#ifdef INVERT_RFID_IN
|
||||
COMP_InitStruct.OutputPolarity = LL_COMP_OUTPUTPOL_INVERTED;
|
||||
#else
|
||||
COMP_InitStruct.OutputPolarity = LL_COMP_OUTPUTPOL_NONINVERTED;
|
||||
#endif
|
||||
COMP_InitStruct.OutputBlankingSource = LL_COMP_BLANKINGSRC_NONE;
|
||||
LL_COMP_Init(COMP1, &COMP_InitStruct);
|
||||
LL_COMP_SetCommonWindowMode(__LL_COMP_COMMON_INSTANCE(COMP1), LL_COMP_WINDOWMODE_DISABLE);
|
||||
@@ -92,7 +91,7 @@ void furi_hal_rfid_pins_reset() {
|
||||
furi_hal_gpio_init(&gpio_rfid_data_in, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_pins_emulate() {
|
||||
static void furi_hal_rfid_pins_emulate() {
|
||||
// ibutton low
|
||||
furi_hal_ibutton_pin_configure();
|
||||
furi_hal_ibutton_pin_write(false);
|
||||
@@ -113,7 +112,7 @@ void furi_hal_rfid_pins_emulate() {
|
||||
&gpio_rfid_carrier, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn2TIM2);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_pins_read() {
|
||||
static void furi_hal_rfid_pins_read() {
|
||||
// ibutton low
|
||||
furi_hal_ibutton_pin_configure();
|
||||
furi_hal_ibutton_pin_write(false);
|
||||
@@ -142,10 +141,10 @@ void furi_hal_rfid_pin_pull_pulldown() {
|
||||
furi_hal_gpio_write(&gpio_nfc_irq_rfid_pull, false);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_read(float freq, float duty_cycle) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(FURI_HAL_RFID_READ_TIMER);
|
||||
FURI_CRITICAL_EXIT();
|
||||
void furi_hal_rfid_tim_read_start(float freq, float duty_cycle) {
|
||||
furi_hal_bus_enable(FURI_HAL_RFID_READ_TIMER_BUS);
|
||||
|
||||
furi_hal_rfid_pins_read();
|
||||
|
||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||
TIM_InitStruct.Autoreload = (SystemCoreClock / freq) - 1;
|
||||
@@ -160,23 +159,23 @@ void furi_hal_rfid_tim_read(float freq, float duty_cycle) {
|
||||
FURI_HAL_RFID_READ_TIMER, FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG, &TIM_OC_InitStruct);
|
||||
|
||||
LL_TIM_EnableCounter(FURI_HAL_RFID_READ_TIMER);
|
||||
|
||||
furi_hal_rfid_tim_read_continue();
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_read_start() {
|
||||
void furi_hal_rfid_tim_read_continue() {
|
||||
LL_TIM_EnableAllOutputs(FURI_HAL_RFID_READ_TIMER);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_read_stop() {
|
||||
void furi_hal_rfid_tim_read_pause() {
|
||||
LL_TIM_DisableAllOutputs(FURI_HAL_RFID_READ_TIMER);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_emulate(float freq) {
|
||||
UNUSED(freq); // FIXME
|
||||
// basic PWM setup with needed freq and internal clock
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
FURI_CRITICAL_EXIT();
|
||||
void furi_hal_rfid_tim_read_stop() {
|
||||
furi_hal_bus_disable(FURI_HAL_RFID_READ_TIMER_BUS);
|
||||
}
|
||||
|
||||
static void furi_hal_rfid_tim_emulate() {
|
||||
LL_TIM_SetPrescaler(FURI_HAL_RFID_EMULATE_TIMER, 0);
|
||||
LL_TIM_SetCounterMode(FURI_HAL_RFID_EMULATE_TIMER, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_SetAutoReload(FURI_HAL_RFID_EMULATE_TIMER, 1);
|
||||
@@ -201,32 +200,6 @@ void furi_hal_rfid_tim_emulate(float freq) {
|
||||
LL_TIM_GenerateEvent_UPDATE(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
}
|
||||
|
||||
static void furi_hal_rfid_emulate_isr() {
|
||||
if(LL_TIM_IsActiveFlag_UPDATE(FURI_HAL_RFID_EMULATE_TIMER)) {
|
||||
LL_TIM_ClearFlag_UPDATE(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
furi_hal_rfid->callback(furi_hal_rfid->context);
|
||||
}
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* context) {
|
||||
furi_assert(furi_hal_rfid);
|
||||
|
||||
furi_hal_rfid->callback = callback;
|
||||
furi_hal_rfid->context = context;
|
||||
|
||||
furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, furi_hal_rfid_emulate_isr, NULL);
|
||||
|
||||
LL_TIM_EnableIT_UPDATE(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
LL_TIM_EnableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
LL_TIM_EnableCounter(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_emulate_stop() {
|
||||
LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
LL_TIM_DisableAllOutputs(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL);
|
||||
}
|
||||
|
||||
static void furi_hal_capture_dma_isr(void* context) {
|
||||
UNUSED(context);
|
||||
|
||||
@@ -247,15 +220,13 @@ static void furi_hal_capture_dma_isr(void* context) {
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_read_capture_start(FuriHalRfidReadCaptureCallback callback, void* context) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(RFID_CAPTURE_TIM);
|
||||
FURI_CRITICAL_EXIT();
|
||||
|
||||
furi_assert(furi_hal_rfid);
|
||||
|
||||
furi_hal_rfid->read_capture_callback = callback;
|
||||
furi_hal_rfid->context = context;
|
||||
|
||||
furi_hal_bus_enable(RFID_CAPTURE_TIM_BUS);
|
||||
|
||||
// Timer: base
|
||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||
TIM_InitStruct.Prescaler = 64 - 1;
|
||||
@@ -303,10 +274,7 @@ void furi_hal_rfid_tim_read_capture_stop() {
|
||||
furi_hal_rfid_comp_stop();
|
||||
|
||||
furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL);
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(RFID_CAPTURE_TIM);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(RFID_CAPTURE_TIM_BUS);
|
||||
}
|
||||
|
||||
static void furi_hal_rfid_dma_isr() {
|
||||
@@ -341,7 +309,8 @@ void furi_hal_rfid_tim_emulate_dma_start(
|
||||
furi_hal_rfid_pins_emulate();
|
||||
|
||||
// configure timer
|
||||
furi_hal_rfid_tim_emulate(125000);
|
||||
furi_hal_bus_enable(FURI_HAL_RFID_EMULATE_TIMER_BUS);
|
||||
furi_hal_rfid_tim_emulate();
|
||||
LL_TIM_OC_SetPolarity(
|
||||
FURI_HAL_RFID_EMULATE_TIMER, FURI_HAL_RFID_EMULATE_TIMER_CHANNEL, LL_TIM_OCPOLARITY_HIGH);
|
||||
LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
@@ -405,32 +374,12 @@ void furi_hal_rfid_tim_emulate_dma_stop() {
|
||||
|
||||
LL_DMA_DeInit(RFID_DMA_CH1_DEF);
|
||||
LL_DMA_DeInit(RFID_DMA_CH2_DEF);
|
||||
LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
|
||||
furi_hal_bus_disable(FURI_HAL_RFID_EMULATE_TIMER_BUS);
|
||||
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_rfid_tim_reset() {
|
||||
FURI_CRITICAL_ENTER();
|
||||
|
||||
LL_TIM_DeInit(FURI_HAL_RFID_READ_TIMER);
|
||||
LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER);
|
||||
|
||||
FURI_CRITICAL_EXIT();
|
||||
}
|
||||
|
||||
void furi_hal_rfid_set_emulate_period(uint32_t period) {
|
||||
LL_TIM_SetAutoReload(FURI_HAL_RFID_EMULATE_TIMER, period);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_set_emulate_pulse(uint32_t pulse) {
|
||||
#if FURI_HAL_RFID_EMULATE_TIMER_CHANNEL == LL_TIM_CHANNEL_CH3
|
||||
LL_TIM_OC_SetCompareCH3(FURI_HAL_RFID_EMULATE_TIMER, pulse);
|
||||
#else
|
||||
#error Update this code. Would you kindly?
|
||||
#endif
|
||||
}
|
||||
|
||||
void furi_hal_rfid_set_read_period(uint32_t period) {
|
||||
LL_TIM_SetAutoReload(FURI_HAL_RFID_READ_TIMER, period);
|
||||
}
|
||||
@@ -443,12 +392,6 @@ void furi_hal_rfid_set_read_pulse(uint32_t pulse) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void furi_hal_rfid_change_read_config(float freq, float duty_cycle) {
|
||||
uint32_t period = (uint32_t)((SystemCoreClock) / freq) - 1;
|
||||
furi_hal_rfid_set_read_period(period);
|
||||
furi_hal_rfid_set_read_pulse(period * duty_cycle);
|
||||
}
|
||||
|
||||
void furi_hal_rfid_comp_start() {
|
||||
LL_COMP_Enable(COMP1);
|
||||
// Magic
|
||||
@@ -483,4 +426,4 @@ void COMP_IRQHandler() {
|
||||
(LL_COMP_ReadOutputLevel(COMP1) == LL_COMP_OUTPUT_LEVEL_LOW),
|
||||
furi_hal_rfid_comp_callback_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,14 +21,6 @@ void furi_hal_rfid_init();
|
||||
*/
|
||||
void furi_hal_rfid_pins_reset();
|
||||
|
||||
/** Config rfid pins to emulate state
|
||||
*/
|
||||
void furi_hal_rfid_pins_emulate();
|
||||
|
||||
/** Config rfid pins to read state
|
||||
*/
|
||||
void furi_hal_rfid_pins_read();
|
||||
|
||||
/** Release rfid pull pin
|
||||
*/
|
||||
void furi_hal_rfid_pin_pull_release();
|
||||
@@ -37,33 +29,24 @@ void furi_hal_rfid_pin_pull_release();
|
||||
*/
|
||||
void furi_hal_rfid_pin_pull_pulldown();
|
||||
|
||||
/** Config rfid timer to read state
|
||||
*
|
||||
/** Start read timer
|
||||
* @param freq timer frequency
|
||||
* @param duty_cycle timer duty cycle, 0.0-1.0
|
||||
*/
|
||||
void furi_hal_rfid_tim_read(float freq, float duty_cycle);
|
||||
void furi_hal_rfid_tim_read_start(float freq, float duty_cycle);
|
||||
|
||||
/** Start read timer
|
||||
/** Pause read timer, to be able to continue later
|
||||
*/
|
||||
void furi_hal_rfid_tim_read_start();
|
||||
void furi_hal_rfid_tim_read_pause();
|
||||
|
||||
/** Continue read timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_read_continue();
|
||||
|
||||
/** Stop read timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_read_stop();
|
||||
|
||||
/** Config rfid timer to emulate state
|
||||
*
|
||||
* @param freq timer frequency
|
||||
*/
|
||||
void furi_hal_rfid_tim_emulate(float freq);
|
||||
|
||||
typedef void (*FuriHalRfidEmulateCallback)(void* context);
|
||||
|
||||
/** Start emulation timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* context);
|
||||
|
||||
typedef void (*FuriHalRfidReadCaptureCallback)(bool level, uint32_t duration, void* context);
|
||||
|
||||
void furi_hal_rfid_tim_read_capture_start(FuriHalRfidReadCaptureCallback callback, void* context);
|
||||
@@ -81,26 +64,6 @@ void furi_hal_rfid_tim_emulate_dma_start(
|
||||
|
||||
void furi_hal_rfid_tim_emulate_dma_stop();
|
||||
|
||||
/** Stop emulation timer
|
||||
*/
|
||||
void furi_hal_rfid_tim_emulate_stop();
|
||||
|
||||
/** Config rfid timers to reset state
|
||||
*/
|
||||
void furi_hal_rfid_tim_reset();
|
||||
|
||||
/** Set emulation timer period
|
||||
*
|
||||
* @param period overall duration
|
||||
*/
|
||||
void furi_hal_rfid_set_emulate_period(uint32_t period);
|
||||
|
||||
/** Set emulation timer pulse
|
||||
*
|
||||
* @param pulse duration of high level
|
||||
*/
|
||||
void furi_hal_rfid_set_emulate_pulse(uint32_t pulse);
|
||||
|
||||
/** Set read timer period
|
||||
*
|
||||
* @param period overall duration
|
||||
@@ -113,13 +76,6 @@ void furi_hal_rfid_set_read_period(uint32_t period);
|
||||
*/
|
||||
void furi_hal_rfid_set_read_pulse(uint32_t pulse);
|
||||
|
||||
/** Сhanges the configuration of the RFID timer "on a fly"
|
||||
*
|
||||
* @param freq new frequency
|
||||
* @param duty_cycle new duty cycle
|
||||
*/
|
||||
void furi_hal_rfid_change_read_config(float freq, float duty_cycle);
|
||||
|
||||
/** Start/Enable comparator */
|
||||
void furi_hal_rfid_comp_start();
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
#include <furi_hal_light.h>
|
||||
#include <furi_hal_debug.h>
|
||||
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
#include <stm32wbxx_ll_pwr.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_rtc.h>
|
||||
#include <stm32wbxx_ll_utils.h>
|
||||
@@ -44,10 +44,8 @@ _Static_assert(sizeof(SystemReg) == 4, "SystemReg size mismatch");
|
||||
#define FURI_HAL_RTC_SECONDS_PER_DAY (FURI_HAL_RTC_SECONDS_PER_HOUR * 24)
|
||||
#define FURI_HAL_RTC_MONTHS_COUNT 12
|
||||
#define FURI_HAL_RTC_EPOCH_START_YEAR 1970
|
||||
#define FURI_HAL_RTC_IS_LEAP_YEAR(year) \
|
||||
((((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0))
|
||||
|
||||
static const uint8_t furi_hal_rtc_days_per_month[][FURI_HAL_RTC_MONTHS_COUNT] = {
|
||||
static const uint8_t furi_hal_rtc_days_per_month[2][FURI_HAL_RTC_MONTHS_COUNT] = {
|
||||
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
|
||||
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}};
|
||||
|
||||
@@ -395,7 +393,7 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {
|
||||
uint8_t leap_years = 0;
|
||||
|
||||
for(uint16_t y = FURI_HAL_RTC_EPOCH_START_YEAR; y < datetime->year; y++) {
|
||||
if(FURI_HAL_RTC_IS_LEAP_YEAR(y)) {
|
||||
if(furi_hal_rtc_is_leap_year(y)) {
|
||||
leap_years++;
|
||||
} else {
|
||||
years++;
|
||||
@@ -406,10 +404,10 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {
|
||||
((years * furi_hal_rtc_days_per_year[0]) + (leap_years * furi_hal_rtc_days_per_year[1])) *
|
||||
FURI_HAL_RTC_SECONDS_PER_DAY;
|
||||
|
||||
uint8_t year_index = (FURI_HAL_RTC_IS_LEAP_YEAR(datetime->year)) ? 1 : 0;
|
||||
bool leap_year = furi_hal_rtc_is_leap_year(datetime->year);
|
||||
|
||||
for(uint8_t m = 0; m < (datetime->month - 1); m++) {
|
||||
timestamp += furi_hal_rtc_days_per_month[year_index][m] * FURI_HAL_RTC_SECONDS_PER_DAY;
|
||||
for(uint8_t m = 1; m < datetime->month; m++) {
|
||||
timestamp += furi_hal_rtc_get_days_per_month(leap_year, m) * FURI_HAL_RTC_SECONDS_PER_DAY;
|
||||
}
|
||||
|
||||
timestamp += (datetime->day - 1) * FURI_HAL_RTC_SECONDS_PER_DAY;
|
||||
@@ -419,3 +417,15 @@ uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime) {
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
||||
uint16_t furi_hal_rtc_get_days_per_year(uint16_t year) {
|
||||
return furi_hal_rtc_days_per_year[furi_hal_rtc_is_leap_year(year) ? 1 : 0];
|
||||
}
|
||||
|
||||
bool furi_hal_rtc_is_leap_year(uint16_t year) {
|
||||
return (((year) % 4 == 0) && ((year) % 100 != 0)) || ((year) % 400 == 0);
|
||||
}
|
||||
|
||||
uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month) {
|
||||
return furi_hal_rtc_days_per_month[leap_year ? 1 : 0][month - 1];
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <furi_hal_gpio.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_power.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stm32wbxx_ll_tim.h>
|
||||
#include <furi_hal_cortex.h>
|
||||
@@ -20,16 +21,11 @@ static FuriMutex* furi_hal_speaker_mutex = NULL;
|
||||
void furi_hal_speaker_init() {
|
||||
furi_assert(furi_hal_speaker_mutex == NULL);
|
||||
furi_hal_speaker_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER);
|
||||
FURI_CRITICAL_EXIT();
|
||||
FURI_LOG_I(TAG, "Init OK");
|
||||
}
|
||||
|
||||
void furi_hal_speaker_deinit() {
|
||||
furi_check(furi_hal_speaker_mutex != NULL);
|
||||
LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER);
|
||||
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
furi_mutex_free(furi_hal_speaker_mutex);
|
||||
furi_hal_speaker_mutex = NULL;
|
||||
}
|
||||
@@ -39,6 +35,7 @@ bool furi_hal_speaker_acquire(uint32_t timeout) {
|
||||
|
||||
if(furi_mutex_acquire(furi_hal_speaker_mutex, timeout) == FuriStatusOk) {
|
||||
furi_hal_power_insomnia_enter();
|
||||
furi_hal_bus_enable(FuriHalBusTIM16);
|
||||
furi_hal_gpio_init_ex(
|
||||
&gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
|
||||
return true;
|
||||
@@ -53,6 +50,8 @@ void furi_hal_speaker_release() {
|
||||
|
||||
furi_hal_speaker_stop();
|
||||
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||
|
||||
furi_hal_bus_disable(FuriHalBusTIM16);
|
||||
furi_hal_power_insomnia_exit();
|
||||
|
||||
furi_check(furi_mutex_release(furi_hal_speaker_mutex) == FuriStatusOk);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <furi_hal_spi_config.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_spi.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi.h>
|
||||
#include <furi_hal_subghz.h>
|
||||
|
||||
@@ -101,28 +102,17 @@ void furi_hal_spi_config_init() {
|
||||
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||
if(event == FuriHalSpiBusEventInit) {
|
||||
furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||
furi_mutex_free(furi_hal_spi_bus_r_mutex);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalSpiBusEventLock) {
|
||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FuriHalBusSPI1);
|
||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusSPI1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,28 +126,17 @@ FuriMutex* furi_hal_spi_bus_d_mutex = NULL;
|
||||
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||
if(event == FuriHalSpiBusEventInit) {
|
||||
furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
bus->current_handle = NULL;
|
||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||
furi_mutex_free(furi_hal_spi_bus_d_mutex);
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
} else if(event == FuriHalSpiBusEventLock) {
|
||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
|
||||
} else if(event == FuriHalSpiBusEventActivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_enable(FuriHalBusSPI2);
|
||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
||||
FURI_CRITICAL_EXIT();
|
||||
furi_hal_bus_disable(FuriHalBusSPI2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
#include <furi_hal_gpio.h>
|
||||
|
||||
#include <stm32wbxx_ll_spi.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <stm32wbxx_ll_bus.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
#include <furi_hal_interrupt.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_power.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <stm32wbxx_ll_dma.h>
|
||||
|
||||
@@ -596,6 +597,8 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
|
||||
furi_hal_subghz_capture_callback = callback;
|
||||
furi_hal_subghz_capture_callback_context = context;
|
||||
|
||||
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||
|
||||
// Timer: base
|
||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||
TIM_InitStruct.Prescaler = 64 - 1;
|
||||
@@ -680,7 +683,7 @@ void furi_hal_subghz_stop_async_rx() {
|
||||
furi_hal_subghz_idle();
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(TIM2);
|
||||
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||
|
||||
// Stop debug
|
||||
furi_hal_subghz_stop_debug();
|
||||
@@ -859,6 +862,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
|
||||
LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF);
|
||||
LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF);
|
||||
|
||||
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||
|
||||
// Configure TIM2
|
||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||
TIM_InitStruct.Prescaler = 64 - 1;
|
||||
@@ -958,7 +963,7 @@ void furi_hal_subghz_stop_async_tx() {
|
||||
|
||||
// Deinitialize Timer
|
||||
FURI_CRITICAL_ENTER();
|
||||
LL_TIM_DeInit(TIM2);
|
||||
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
|
||||
|
||||
// Deinitialize DMA
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <stm32wbxx_ll_usart.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <furi_hal_resources.h>
|
||||
#include <furi_hal_bus.h>
|
||||
|
||||
#include <furi.h>
|
||||
|
||||
@@ -13,6 +14,9 @@ static void (*irq_cb[2])(uint8_t ev, uint8_t data, void* context);
|
||||
static void* irq_ctx[2];
|
||||
|
||||
static void furi_hal_usart_init(uint32_t baud) {
|
||||
furi_hal_bus_enable(FuriHalBusUSART1);
|
||||
LL_RCC_SetUSARTClockSource(LL_RCC_USART1_CLKSOURCE_PCLK2);
|
||||
|
||||
furi_hal_gpio_init_ex(
|
||||
&gpio_usart_tx,
|
||||
GpioModeAltFunctionPushPull,
|
||||
@@ -50,6 +54,9 @@ static void furi_hal_usart_init(uint32_t baud) {
|
||||
}
|
||||
|
||||
static void furi_hal_lpuart_init(uint32_t baud) {
|
||||
furi_hal_bus_enable(FuriHalBusLPUART1);
|
||||
LL_RCC_SetLPUARTClockSource(LL_RCC_LPUART1_CLKSOURCE_PCLK1);
|
||||
|
||||
furi_hal_gpio_init_ex(
|
||||
&gpio_ext_pc0,
|
||||
GpioModeAltFunctionPushPull,
|
||||
@@ -86,10 +93,11 @@ static void furi_hal_lpuart_init(uint32_t baud) {
|
||||
}
|
||||
|
||||
void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) {
|
||||
if(ch == FuriHalUartIdLPUART1)
|
||||
if(ch == FuriHalUartIdLPUART1) {
|
||||
furi_hal_lpuart_init(baud);
|
||||
else if(ch == FuriHalUartIdUSART1)
|
||||
} else if(ch == FuriHalUartIdUSART1) {
|
||||
furi_hal_usart_init(baud);
|
||||
}
|
||||
}
|
||||
|
||||
void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud) {
|
||||
@@ -126,11 +134,15 @@ void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t baud) {
|
||||
void furi_hal_uart_deinit(FuriHalUartId ch) {
|
||||
furi_hal_uart_set_irq_cb(ch, NULL, NULL);
|
||||
if(ch == FuriHalUartIdUSART1) {
|
||||
LL_USART_Disable(USART1);
|
||||
if(furi_hal_bus_is_enabled(FuriHalBusUSART1)) {
|
||||
furi_hal_bus_disable(FuriHalBusUSART1);
|
||||
}
|
||||
furi_hal_gpio_init(&gpio_usart_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
} else if(ch == FuriHalUartIdLPUART1) {
|
||||
LL_LPUART_Disable(LPUART1);
|
||||
if(furi_hal_bus_is_enabled(FuriHalBusLPUART1)) {
|
||||
furi_hal_bus_disable(FuriHalBusLPUART1);
|
||||
}
|
||||
furi_hal_gpio_init(&gpio_ext_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
furi_hal_gpio_init(&gpio_ext_pc1, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
#include <furi_hal_usb_i.h>
|
||||
#include <furi_hal_usb.h>
|
||||
#include <furi_hal_power.h>
|
||||
|
||||
#include <stm32wbxx_ll_pwr.h>
|
||||
#include <stm32wbxx_ll_rcc.h>
|
||||
#include <furi.h>
|
||||
#include <toolbox/api_lock.h>
|
||||
|
||||
@@ -86,6 +88,8 @@ static void wkup_evt(usbd_device* dev, uint8_t event, uint8_t ep);
|
||||
|
||||
/* Low-level init */
|
||||
void furi_hal_usb_init(void) {
|
||||
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1);
|
||||
|
||||
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||
LL_PWR_EnableVddUSB();
|
||||
|
||||
@@ -98,7 +102,10 @@ void furi_hal_usb_init(void) {
|
||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
|
||||
usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf));
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
usbd_enable(&udev, true);
|
||||
FURI_CRITICAL_EXIT();
|
||||
|
||||
usbd_reg_descr(&udev, usb_descriptor_get);
|
||||
usbd_reg_event(&udev, usbd_evt_susp, susp_evt);
|
||||
@@ -359,8 +366,10 @@ static void usb_process_mode_reinit() {
|
||||
usbd_connect(&udev, false);
|
||||
usb.enabled = false;
|
||||
|
||||
FURI_CRITICAL_ENTER();
|
||||
usbd_enable(&udev, false);
|
||||
usbd_enable(&udev, true);
|
||||
FURI_CRITICAL_EXIT();
|
||||
|
||||
furi_delay_ms(USB_RECONNECT_DELAY);
|
||||
usb_process_mode_start(usb.interface, usb.interface_context);
|
||||
|
||||
@@ -38,6 +38,12 @@ static bool flipper_update_mount_sd() {
|
||||
}
|
||||
|
||||
static bool flipper_update_init() {
|
||||
// TODO: Configure missing peripherals properly
|
||||
furi_hal_bus_enable(FuriHalBusHSEM);
|
||||
furi_hal_bus_enable(FuriHalBusIPCC);
|
||||
furi_hal_bus_enable(FuriHalBusRNG);
|
||||
furi_hal_bus_enable(FuriHalBusUSART1);
|
||||
|
||||
furi_hal_clock_init();
|
||||
furi_hal_rtc_init();
|
||||
furi_hal_interrupt_init();
|
||||
|
||||
@@ -12,9 +12,11 @@ struct STOP_EXTERNING_ME {};
|
||||
|
||||
#include <furi_hal_cortex.h>
|
||||
#include <furi_hal_clock.h>
|
||||
#include <furi_hal_bus.h>
|
||||
#include <furi_hal_crypto.h>
|
||||
#include <furi_hal_console.h>
|
||||
#include <furi_hal_debug.h>
|
||||
#include <furi_hal_dma.h>
|
||||
#include <furi_hal_os.h>
|
||||
#include <furi_hal_sd.h>
|
||||
#include <furi_hal_i2c.h>
|
||||
|
||||
@@ -6,6 +6,9 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Initialize random subsystem */
|
||||
void furi_hal_random_init();
|
||||
|
||||
/** Get random value
|
||||
*
|
||||
* @return random value
|
||||
|
||||
@@ -255,6 +255,30 @@ uint32_t furi_hal_rtc_get_timestamp();
|
||||
*/
|
||||
uint32_t furi_hal_rtc_datetime_to_timestamp(FuriHalRtcDateTime* datetime);
|
||||
|
||||
/** Gets the number of days in the year according to the Gregorian calendar.
|
||||
*
|
||||
* @param year Input year.
|
||||
*
|
||||
* @return number of days in `year`.
|
||||
*/
|
||||
uint16_t furi_hal_rtc_get_days_per_year(uint16_t year);
|
||||
|
||||
/** Check if a year a leap year in the Gregorian calendar.
|
||||
*
|
||||
* @param year Input year.
|
||||
*
|
||||
* @return true if `year` is a leap year.
|
||||
*/
|
||||
bool furi_hal_rtc_is_leap_year(uint16_t year);
|
||||
|
||||
/** Get the number of days in the month.
|
||||
*
|
||||
* @param leap_year true to calculate based on leap years
|
||||
* @param month month to check, where 1 = January
|
||||
* @return the number of days in the month
|
||||
*/
|
||||
uint8_t furi_hal_rtc_get_days_per_month(bool leap_year, uint8_t month);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user