mirror of
https://github.com/DarkFlippers/unleashed-firmware.git
synced 2024-11-23 10:01:58 +03:00
Merge branch 'ofw-dev' into dev
This commit is contained in:
commit
0ab530e750
22
.gitignore
vendored
22
.gitignore
vendored
@ -30,28 +30,26 @@ bindings/
|
||||
.mxproject
|
||||
Brewfile.lock.json
|
||||
|
||||
# Visual Studio Code
|
||||
/.vscode/
|
||||
|
||||
# Kate
|
||||
.kateproject
|
||||
.kateconfig
|
||||
|
||||
# legendary cmake's
|
||||
build
|
||||
CMakeLists.txt
|
||||
|
||||
# bundle output
|
||||
dist
|
||||
|
||||
# kde
|
||||
.directory
|
||||
null.d
|
||||
|
||||
# SCons
|
||||
.sconsign.dblite
|
||||
|
||||
|
||||
# Visual Studio Code
|
||||
/.vscode
|
||||
|
||||
# bundle output
|
||||
/dist
|
||||
|
||||
# SCons build dir
|
||||
build/
|
||||
/build
|
||||
|
||||
# Toolchain
|
||||
/toolchain
|
||||
@ -65,3 +63,5 @@ PVS-Studio.log
|
||||
*.PVS-Studio.*
|
||||
|
||||
.gdbinit
|
||||
|
||||
/fbt_options_local.py
|
@ -14,9 +14,7 @@ void lfrfid_debug_scene_tune_on_enter(void* context) {
|
||||
furi_hal_rfid_comp_set_callback(comparator_trigger_callback, app);
|
||||
furi_hal_rfid_comp_start();
|
||||
|
||||
furi_hal_rfid_pins_read();
|
||||
furi_hal_rfid_tim_read(125000, 0.5);
|
||||
furi_hal_rfid_tim_read_start();
|
||||
furi_hal_rfid_tim_read_start(125000, 0.5);
|
||||
|
||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewTune);
|
||||
}
|
||||
@ -43,6 +41,5 @@ void lfrfid_debug_scene_tune_on_exit(void* context) {
|
||||
|
||||
furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
|
||||
furi_hal_rfid_tim_read_stop();
|
||||
furi_hal_rfid_tim_reset();
|
||||
furi_hal_rfid_pins_reset();
|
||||
}
|
||||
|
@ -52,6 +52,7 @@ void nfc_scene_device_info_on_enter(void* context) {
|
||||
}
|
||||
} else if(
|
||||
dev_data->protocol == NfcDeviceProtocolMifareClassic ||
|
||||
dev_data->protocol == NfcDeviceProtocolMifareDesfire ||
|
||||
dev_data->protocol == NfcDeviceProtocolMifareUl) {
|
||||
furi_string_set(temp_str, nfc->dev->dev_data.parsed_data);
|
||||
}
|
||||
|
@ -20,35 +20,40 @@ void nfc_scene_mf_desfire_read_success_on_enter(void* context) {
|
||||
Widget* widget = nfc->widget;
|
||||
|
||||
// Prepare string for data display
|
||||
FuriString* temp_str = furi_string_alloc_printf("\e#MIFARE DESfire\n");
|
||||
furi_string_cat_printf(temp_str, "UID:");
|
||||
for(size_t i = 0; i < nfc_data->uid_len; i++) {
|
||||
furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]);
|
||||
}
|
||||
|
||||
uint32_t bytes_total = 1UL << (data->version.sw_storage >> 1);
|
||||
uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0;
|
||||
furi_string_cat_printf(temp_str, "\n%lu", bytes_total);
|
||||
if(data->version.sw_storage & 1) {
|
||||
furi_string_push_back(temp_str, '+');
|
||||
}
|
||||
furi_string_cat_printf(temp_str, " bytes, %lu bytes free\n", bytes_free);
|
||||
|
||||
uint16_t n_apps = 0;
|
||||
uint16_t n_files = 0;
|
||||
for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
|
||||
n_apps++;
|
||||
for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
|
||||
n_files++;
|
||||
FuriString* temp_str = NULL;
|
||||
if(furi_string_size(nfc->dev->dev_data.parsed_data)) {
|
||||
temp_str = furi_string_alloc_set(nfc->dev->dev_data.parsed_data);
|
||||
} else {
|
||||
temp_str = furi_string_alloc_printf("\e#MIFARE DESFire\n");
|
||||
furi_string_cat_printf(temp_str, "UID:");
|
||||
for(size_t i = 0; i < nfc_data->uid_len; i++) {
|
||||
furi_string_cat_printf(temp_str, " %02X", nfc_data->uid[i]);
|
||||
}
|
||||
|
||||
uint32_t bytes_total = 1UL << (data->version.sw_storage >> 1);
|
||||
uint32_t bytes_free = data->free_memory ? data->free_memory->bytes : 0;
|
||||
furi_string_cat_printf(temp_str, "\n%lu", bytes_total);
|
||||
if(data->version.sw_storage & 1) {
|
||||
furi_string_push_back(temp_str, '+');
|
||||
}
|
||||
furi_string_cat_printf(temp_str, " bytes, %lu bytes free\n", bytes_free);
|
||||
|
||||
uint16_t n_apps = 0;
|
||||
uint16_t n_files = 0;
|
||||
for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
|
||||
n_apps++;
|
||||
for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
|
||||
n_files++;
|
||||
}
|
||||
}
|
||||
furi_string_cat_printf(temp_str, "%d Application", n_apps);
|
||||
if(n_apps != 1) {
|
||||
furi_string_push_back(temp_str, 's');
|
||||
}
|
||||
furi_string_cat_printf(temp_str, ", %d file", n_files);
|
||||
if(n_files != 1) {
|
||||
furi_string_push_back(temp_str, 's');
|
||||
}
|
||||
}
|
||||
furi_string_cat_printf(temp_str, "%d Application", n_apps);
|
||||
if(n_apps != 1) {
|
||||
furi_string_push_back(temp_str, 's');
|
||||
}
|
||||
furi_string_cat_printf(temp_str, ", %d file", n_files);
|
||||
if(n_files != 1) {
|
||||
furi_string_push_back(temp_str, 's');
|
||||
}
|
||||
|
||||
notification_message_block(nfc->notifications, &sequence_set_green_255);
|
||||
|
@ -51,7 +51,7 @@ void nfc_scene_nfc_data_info_on_enter(void* context) {
|
||||
furi_string_cat_printf(
|
||||
temp_str, "\e#%s\n", nfc_mf_classic_type(dev_data->mf_classic_data.type));
|
||||
} else if(protocol == NfcDeviceProtocolMifareDesfire) {
|
||||
furi_string_cat_printf(temp_str, "\e#MIFARE DESfire\n");
|
||||
furi_string_cat_printf(temp_str, "\e#MIFARE DESFire\n");
|
||||
} else if(protocol == NfcDeviceProtocolNfcV) {
|
||||
switch(dev_data->nfcv_data.sub_type) {
|
||||
case NfcVTypePlain:
|
||||
|
@ -152,6 +152,7 @@ bool nfc_scene_saved_menu_on_event(void* context, SceneManagerEvent event) {
|
||||
application_info_present = true;
|
||||
} else if(
|
||||
dev_data->protocol == NfcDeviceProtocolMifareClassic ||
|
||||
dev_data->protocol == NfcDeviceProtocolMifareDesfire ||
|
||||
dev_data->protocol == NfcDeviceProtocolMifareUl) {
|
||||
application_info_present = nfc_supported_card_verify_and_parse(dev_data);
|
||||
}
|
||||
|
113
documentation/FuriHalBus.md
Normal file
113
documentation/FuriHalBus.md
Normal file
@ -0,0 +1,113 @@
|
||||
# Using FuriHalBus API
|
||||
|
||||
## Basic info
|
||||
|
||||
On system startup, most of the peripheral devices are under reset and not clocked by default. This is done to reduce power consumption and to guarantee that the device will always be in the same state before use.
|
||||
Some crucial peripherals are enabled right away by the system, others must be explicitly enabled by the user code.
|
||||
|
||||
**NOTE:** Here and afterwards the word *"system"* refers to any code belonging to the operating system, hardware drivers or built-in applications.
|
||||
|
||||
To **ENABLE** a peripheral, call `furi_hal_bus_enable()`. At the time of the call, the peripheral in question MUST be disabled, otherwise a crash will occur to indicate improper use. This means that any given peripheral cannot be enabled twice or more without disabling it first.
|
||||
|
||||
To **DISABLE** a peripheral, call `furi_hal_bus_disable()`. Likewise, the peripheral in question MUST be enabled, otherwise a crash will occur.
|
||||
|
||||
To **RESET** a peripheral, call `furi_hal_bus_reset()`. The peripheral in question MUST be enabled, otherwise a crash will occur. This method is used whenever it is necessary to reset all the peripheral's registers to their initial states without disabling it.
|
||||
|
||||
## Peripherals
|
||||
|
||||
Built-in peripherals are divided into three categories:
|
||||
- Enabled by the system on startup, never disabled;
|
||||
- Enabled and disabled by the system on demand;
|
||||
- Enabled and disabled by the user code.
|
||||
|
||||
### Always-on peripherals
|
||||
|
||||
Below is the list of peripherals that are enabled by the system. The user code must NEVER attempt to disable them. If a corresponding API is provided, the user code must employ it in order to access the peripheral.
|
||||
|
||||
*Table 1* - Peripherals enabled by the system
|
||||
|
||||
| Peripheral | Enabled at |
|
||||
| :-----------: | :-----------------------: |
|
||||
| DMA1 | `furi_hal_dma.c` |
|
||||
| DMA2 | -- |
|
||||
| DMAMUX | -- |
|
||||
| GPIOA | `furi_hal_resources.c` |
|
||||
| GPIOB | -- |
|
||||
| GPIOC | -- |
|
||||
| GPIOD | -- |
|
||||
| GPIOE | -- |
|
||||
| GPIOH | -- |
|
||||
| PKA | `furi_hal_bt.c` |
|
||||
| AES2 | -- |
|
||||
| HSEM | -- |
|
||||
| IPCC | -- |
|
||||
| FLASH | enabled by hardware |
|
||||
|
||||
### On-demand system peripherals
|
||||
|
||||
Below is the list of peripherals that are enabled and disabled by the system. The user code must avoid using them directly, preferring the respective APIs instead.
|
||||
|
||||
When not using the API, these peripherals MUST be enabled by the user code and then disabled when not needed anymore.
|
||||
|
||||
*Table 2* - Peripherals enabled and disabled by the system
|
||||
|
||||
| Peripheral | API header file |
|
||||
| :-----------: | :-------------------: |
|
||||
| RNG | `furi_hal_random.h` |
|
||||
| SPI1 | `furi_hal_spi.h` |
|
||||
| SPI2 | -- |
|
||||
| I2C1 | `furi_hal_i2c.h` |
|
||||
| I2C3 | -- |
|
||||
| USART1 | `furi_hal_uart.h` |
|
||||
| LPUART1 | -- |
|
||||
| USB | `furi_hal_usb.h` |
|
||||
|
||||
### On-demand shared peripherals
|
||||
|
||||
Below is the list of peripherals that are not enabled by default and MUST be enabled by the user code each time it accesses them.
|
||||
|
||||
Note that some of these peripherals may also be used by the system to implement its certain features.
|
||||
The system will take over any given peripheral only when the respective feature is in use.
|
||||
|
||||
*Table 3* - Peripherals enabled and disabled by user
|
||||
|
||||
| Peripheral | System | Purpose |
|
||||
| :-----------: | :-------: | ------------------------------------- |
|
||||
| CRC | | |
|
||||
| TSC | | |
|
||||
| ADC | | |
|
||||
| QUADSPI | | |
|
||||
| TIM1 | yes | subghz, lfrfid, nfc, infrared, etc... |
|
||||
| TIM2 | yes | -- |
|
||||
| TIM16 | yes | speaker |
|
||||
| TIM17 | | |
|
||||
| LPTIM1 | yes | tickless idle timer |
|
||||
| LPTIM2 | yes | pwm |
|
||||
| SAI1 | | |
|
||||
| LCD | | |
|
||||
|
||||
|
||||
## DMA
|
||||
|
||||
The DMA1,2 peripherals are a special case in that they have multiple independent channels. Some of the channels may be in use by the system.
|
||||
|
||||
Below is the list of DMA channels and their usage by the system.
|
||||
|
||||
*Table 4* - DMA channels
|
||||
|
||||
| DMA | Channel | System | Purpose |
|
||||
| :---: | :-------: | :-------: | ------------------------- |
|
||||
| DMA1 | 1 | yes | digital signal |
|
||||
| -- | 2 | yes | -- |
|
||||
| -- | 3 | | |
|
||||
| -- | 4 | yes | pulse reader |
|
||||
| -- | 5 | | |
|
||||
| -- | 6 | | |
|
||||
| -- | 7 | | |
|
||||
| DMA2 | 1 | yes | infrared, lfrfid, subghz |
|
||||
| -- | 2 | yes | -- |
|
||||
| -- | 3 | yes | SPI |
|
||||
| -- | 4 | yes | SPI |
|
||||
| -- | 5 | | |
|
||||
| -- | 6 | | |
|
||||
| -- | 7 | | |
|
@ -114,6 +114,8 @@ To run cleanup (think of `make clean`) for specified targets, add the `-c` optio
|
||||
Default configuration variables are set in the configuration file: `fbt_options.py`.
|
||||
Values set in the command line have higher precedence over the configuration file.
|
||||
|
||||
You can also create a file called `fbt_options_local.py` that will be evaluated when loading default options file, enabling persisent overriding of default options without modifying default configuration.
|
||||
|
||||
You can find out available options with `./fbt -h`.
|
||||
|
||||
### Firmware application set
|
||||
|
@ -1,7 +1,9 @@
|
||||
from pathlib import Path
|
||||
import posixpath
|
||||
|
||||
# For more details on these options, run 'fbt -h'
|
||||
|
||||
FIRMWARE_ORIGIN = "Official"
|
||||
|
||||
# Default hardware target
|
||||
TARGET_HW = 7
|
||||
@ -88,3 +90,8 @@ FIRMWARE_APPS = {
|
||||
}
|
||||
|
||||
FIRMWARE_APP_SET = "default"
|
||||
|
||||
custom_options_fn = "fbt_options_local.py"
|
||||
|
||||
if Path(custom_options_fn).exists():
|
||||
exec(compile(Path(custom_options_fn).read_text(), custom_options_fn, "exec"))
|
||||
|
@ -18,6 +18,7 @@ env = ENV.Clone(
|
||||
"fbt_apps",
|
||||
"pvsstudio",
|
||||
"fbt_hwtarget",
|
||||
"fbt_envhooks",
|
||||
],
|
||||
COMPILATIONDB_USE_ABSPATH=False,
|
||||
BUILD_DIR=fw_build_meta["build_dir"],
|
||||
@ -72,6 +73,8 @@ env = ENV.Clone(
|
||||
_APP_ICONS=None,
|
||||
)
|
||||
|
||||
env.PreConfigureFwEnvionment()
|
||||
|
||||
if env["IS_BASE_FIRMWARE"]:
|
||||
env.Append(
|
||||
FIRMWARE_BUILD_CFG="firmware",
|
||||
@ -100,6 +103,13 @@ lib_targets = env.BuildModules(
|
||||
],
|
||||
)
|
||||
|
||||
# Configure firmware origin definitions
|
||||
env.Append(
|
||||
CPPDEFINES=[
|
||||
env.subst("FW_ORIGIN_${FIRMWARE_ORIGIN}"),
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# Now, env is fully set up with everything to build apps
|
||||
fwenv = env.Clone(FW_ARTIFACTS=[])
|
||||
@ -271,5 +281,6 @@ if should_gen_cdb_and_link_dir(fwenv, BUILD_TARGETS):
|
||||
|
||||
Alias(fwenv["FIRMWARE_BUILD_CFG"] + "_all", fw_artifacts)
|
||||
|
||||
env.PostConfigureFwEnvionment()
|
||||
|
||||
Return("fwenv")
|
||||
|
@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,27.0,,
|
||||
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,,
|
||||
@ -873,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"
|
||||
@ -915,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,
|
||||
@ -1033,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*,
|
||||
@ -1048,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,
|
||||
@ -1060,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*
|
||||
@ -1989,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
entry,status,name,type,params
|
||||
Version,+,27.0,,
|
||||
Version,+,28.1,,
|
||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||
Header,+,applications/services/cli/cli.h,,
|
||||
Header,+,applications/services/cli/cli_vcp.h,,
|
||||
@ -36,8 +36,10 @@ Header,+,applications/services/notification/notification_messages.h,,
|
||||
Header,+,applications/services/power/power_service/power.h,,
|
||||
Header,+,applications/services/rpc/rpc_app.h,,
|
||||
Header,+,applications/services/storage/storage.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,,
|
||||
@ -1090,6 +1092,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"
|
||||
@ -1132,6 +1140,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,
|
||||
@ -1300,6 +1310,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*,
|
||||
@ -1310,35 +1321,29 @@ Function,-,furi_hal_resources_deinit_early,void,
|
||||
Function,+,furi_hal_resources_get_ext_pin_number,int32_t,const GpioPin*
|
||||
Function,-,furi_hal_resources_init,void,
|
||||
Function,-,furi_hal_resources_init_early,void,
|
||||
Function,+,furi_hal_rfid_change_read_config,void,"float, float"
|
||||
Function,+,furi_hal_rfid_comp_set_callback,void,"FuriHalRfidCompCallback, void*"
|
||||
Function,+,furi_hal_rfid_comp_start,void,
|
||||
Function,+,furi_hal_rfid_comp_stop,void,
|
||||
Function,-,furi_hal_rfid_init,void,
|
||||
Function,+,furi_hal_rfid_pin_pull_pulldown,void,
|
||||
Function,+,furi_hal_rfid_pin_pull_release,void,
|
||||
Function,+,furi_hal_rfid_pins_emulate,void,
|
||||
Function,+,furi_hal_rfid_pins_read,void,
|
||||
Function,+,furi_hal_rfid_pins_reset,void,
|
||||
Function,+,furi_hal_rfid_set_emulate_period,void,uint32_t
|
||||
Function,+,furi_hal_rfid_set_emulate_pulse,void,uint32_t
|
||||
Function,+,furi_hal_rfid_set_read_period,void,uint32_t
|
||||
Function,+,furi_hal_rfid_set_read_pulse,void,uint32_t
|
||||
Function,+,furi_hal_rfid_tim_emulate,void,float
|
||||
Function,+,furi_hal_rfid_tim_emulate_dma_start,void,"uint32_t*, uint32_t*, size_t, FuriHalRfidDMACallback, void*"
|
||||
Function,+,furi_hal_rfid_tim_emulate_dma_stop,void,
|
||||
Function,+,furi_hal_rfid_tim_emulate_start,void,"FuriHalRfidEmulateCallback, void*"
|
||||
Function,+,furi_hal_rfid_tim_emulate_stop,void,
|
||||
Function,+,furi_hal_rfid_tim_read,void,"float, float"
|
||||
Function,+,furi_hal_rfid_tim_read_capture_start,void,"FuriHalRfidReadCaptureCallback, void*"
|
||||
Function,+,furi_hal_rfid_tim_read_capture_stop,void,
|
||||
Function,+,furi_hal_rfid_tim_read_start,void,
|
||||
Function,+,furi_hal_rfid_tim_read_continue,void,
|
||||
Function,+,furi_hal_rfid_tim_read_pause,void,
|
||||
Function,+,furi_hal_rfid_tim_read_start,void,"float, float"
|
||||
Function,+,furi_hal_rfid_tim_read_stop,void,
|
||||
Function,+,furi_hal_rfid_tim_reset,void,
|
||||
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,
|
||||
@ -1351,6 +1356,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*
|
||||
@ -2039,6 +2045,8 @@ Function,-,mf_df_cat_key_settings,void,"MifareDesfireKeySettings*, FuriString*"
|
||||
Function,-,mf_df_cat_version,void,"MifareDesfireVersion*, FuriString*"
|
||||
Function,-,mf_df_check_card_type,_Bool,"uint8_t, uint8_t, uint8_t"
|
||||
Function,-,mf_df_clear,void,MifareDesfireData*
|
||||
Function,-,mf_df_get_application,MifareDesfireApplication*,"MifareDesfireData*, const uint8_t[3]*"
|
||||
Function,-,mf_df_get_file,MifareDesfireFile*,"MifareDesfireApplication*, uint8_t"
|
||||
Function,-,mf_df_parse_get_application_ids_response,_Bool,"uint8_t*, uint16_t, MifareDesfireApplication**"
|
||||
Function,-,mf_df_parse_get_file_ids_response,_Bool,"uint8_t*, uint16_t, MifareDesfireFile**"
|
||||
Function,-,mf_df_parse_get_file_settings_response,_Bool,"uint8_t*, uint16_t, MifareDesfireFile*"
|
||||
@ -3539,6 +3547,8 @@ Function,+,version_get,const Version*,
|
||||
Function,+,version_get_builddate,const char*,const Version*
|
||||
Function,+,version_get_custom_name,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();
|
||||
|
@ -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,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" {
|
||||
|
@ -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
|
||||
|
@ -78,6 +78,11 @@ extern "C" {
|
||||
#define TOSTRING(x) STRINGIFY(x)
|
||||
#endif
|
||||
|
||||
#ifndef CONCATENATE
|
||||
#define CONCATENATE(a, b) CONCATENATE_(a, b)
|
||||
#define CONCATENATE_(a, b) a##b
|
||||
#endif
|
||||
|
||||
#ifndef REVERSE_BYTES_U32
|
||||
#define REVERSE_BYTES_U32(x) \
|
||||
((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \
|
||||
|
@ -243,10 +243,12 @@ static void digital_signal_stop_timer() {
|
||||
LL_TIM_DisableCounter(TIM2);
|
||||
LL_TIM_DisableUpdateEvent(TIM2);
|
||||
LL_TIM_DisableDMAReq_UPDATE(TIM2);
|
||||
|
||||
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||
}
|
||||
|
||||
static void digital_signal_setup_timer() {
|
||||
digital_signal_stop_timer();
|
||||
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||
|
||||
LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
|
||||
|
@ -151,9 +151,7 @@ static int32_t lfrfid_raw_read_worker_thread(void* thread_context) {
|
||||
|
||||
if(file_valid) {
|
||||
// setup carrier
|
||||
furi_hal_rfid_pins_read();
|
||||
furi_hal_rfid_tim_read(worker->frequency, worker->duty_cycle);
|
||||
furi_hal_rfid_tim_read_start();
|
||||
furi_hal_rfid_tim_read_start(worker->frequency, worker->duty_cycle);
|
||||
|
||||
// stabilize detector
|
||||
furi_delay_ms(1500);
|
||||
|
@ -100,24 +100,21 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal(
|
||||
uint32_t timeout,
|
||||
ProtocolId* result_protocol) {
|
||||
LFRFIDWorkerReadState state = LFRFIDWorkerReadTimeout;
|
||||
furi_hal_rfid_pins_read();
|
||||
|
||||
if(feature & LFRFIDFeatureASK) {
|
||||
furi_hal_rfid_tim_read(125000, 0.5);
|
||||
furi_hal_rfid_tim_read_start(125000, 0.5);
|
||||
FURI_LOG_D(TAG, "Start ASK");
|
||||
if(worker->read_cb) {
|
||||
worker->read_cb(LFRFIDWorkerReadStartASK, PROTOCOL_NO, worker->cb_ctx);
|
||||
}
|
||||
} else {
|
||||
furi_hal_rfid_tim_read(62500, 0.25);
|
||||
furi_hal_rfid_tim_read_start(62500, 0.25);
|
||||
FURI_LOG_D(TAG, "Start PSK");
|
||||
if(worker->read_cb) {
|
||||
worker->read_cb(LFRFIDWorkerReadStartPSK, PROTOCOL_NO, worker->cb_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
furi_hal_rfid_tim_read_start();
|
||||
|
||||
// stabilize detector
|
||||
lfrfid_worker_delay(worker, LFRFID_WORKER_READ_STABILIZE_TIME_MS);
|
||||
|
||||
@ -205,7 +202,7 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal(
|
||||
average_index = 0;
|
||||
|
||||
if(worker->read_cb) {
|
||||
if(average > 0.2 && average < 0.8) {
|
||||
if(average > 0.2f && average < 0.8f) {
|
||||
if(!card_detected) {
|
||||
card_detected = true;
|
||||
worker->read_cb(
|
||||
|
@ -14,9 +14,7 @@
|
||||
#define T5577_OPCODE_RESET 0b00
|
||||
|
||||
static void t5577_start() {
|
||||
furi_hal_rfid_tim_read(125000, 0.5);
|
||||
furi_hal_rfid_pins_read();
|
||||
furi_hal_rfid_tim_read_start();
|
||||
furi_hal_rfid_tim_read_start(125000, 0.5);
|
||||
|
||||
// do not ground the antenna
|
||||
furi_hal_rfid_pin_pull_release();
|
||||
@ -24,14 +22,13 @@ static void t5577_start() {
|
||||
|
||||
static void t5577_stop() {
|
||||
furi_hal_rfid_tim_read_stop();
|
||||
furi_hal_rfid_tim_reset();
|
||||
furi_hal_rfid_pins_reset();
|
||||
}
|
||||
|
||||
static void t5577_write_gap(uint32_t gap_time) {
|
||||
furi_hal_rfid_tim_read_stop();
|
||||
furi_hal_rfid_tim_read_pause();
|
||||
furi_delay_us(gap_time * 8);
|
||||
furi_hal_rfid_tim_read_start();
|
||||
furi_hal_rfid_tim_read_continue();
|
||||
}
|
||||
|
||||
static void t5577_write_bit(bool value) {
|
||||
|
@ -464,6 +464,19 @@ static bool nfc_worker_read_mf_desfire(NfcWorker* nfc_worker, FuriHalNfcTxRxCont
|
||||
do {
|
||||
if(!furi_hal_nfc_detect(&nfc_worker->dev_data->nfc_data, 300)) break;
|
||||
if(!mf_df_read_card(tx_rx, data)) break;
|
||||
FURI_LOG_I(TAG, "Trying to parse a supported card ...");
|
||||
|
||||
// The model for parsing DESFire is a little different to other cards;
|
||||
// we don't have parsers to provide encryption keys, so we can read the
|
||||
// data normally, and then pass the read data to a parser.
|
||||
//
|
||||
// There are fully-protected DESFire cards, but providing keys for them
|
||||
// is difficult (and unnessesary for many transit cards).
|
||||
for(size_t i = 0; i < NfcSupportedCardTypeEnd; i++) {
|
||||
if(nfc_supported_card[i].protocol == NfcDeviceProtocolMifareDesfire) {
|
||||
if(nfc_supported_card[i].parse(nfc_worker->dev_data)) break;
|
||||
}
|
||||
}
|
||||
read_success = true;
|
||||
} while(false);
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "troika_4k_parser.h"
|
||||
#include "two_cities.h"
|
||||
#include "all_in_one.h"
|
||||
#include "opal.h"
|
||||
|
||||
NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd] = {
|
||||
[NfcSupportedCardTypePlantain] =
|
||||
@ -50,6 +51,14 @@ NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd] = {
|
||||
.read = all_in_one_parser_read,
|
||||
.parse = all_in_one_parser_parse,
|
||||
},
|
||||
[NfcSupportedCardTypeOpal] =
|
||||
{
|
||||
.protocol = NfcDeviceProtocolMifareDesfire,
|
||||
.verify = stub_parser_verify_read,
|
||||
.read = stub_parser_verify_read,
|
||||
.parse = opal_parser_parse,
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data) {
|
||||
@ -65,3 +74,9 @@ bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data) {
|
||||
|
||||
return card_parsed;
|
||||
}
|
||||
|
||||
bool stub_parser_verify_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx) {
|
||||
UNUSED(nfc_worker);
|
||||
UNUSED(tx_rx);
|
||||
return false;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ typedef enum {
|
||||
NfcSupportedCardTypeTroika4K,
|
||||
NfcSupportedCardTypeTwoCities,
|
||||
NfcSupportedCardTypeAllInOne,
|
||||
NfcSupportedCardTypeOpal,
|
||||
|
||||
NfcSupportedCardTypeEnd,
|
||||
} NfcSupportedCardType;
|
||||
@ -31,3 +32,8 @@ typedef struct {
|
||||
extern NfcSupportedCard nfc_supported_card[NfcSupportedCardTypeEnd];
|
||||
|
||||
bool nfc_supported_card_verify_and_parse(NfcDeviceData* dev_data);
|
||||
|
||||
// stub_parser_verify_read does nothing, and always reports that it does not
|
||||
// support the card. This is needed for DESFire card parsers which can't
|
||||
// provide keys, and only use NfcSupportedCard->parse.
|
||||
bool stub_parser_verify_read(NfcWorker* nfc_worker, FuriHalNfcTxRxContext* tx_rx);
|
||||
|
204
lib/nfc/parsers/opal.c
Normal file
204
lib/nfc/parsers/opal.c
Normal file
@ -0,0 +1,204 @@
|
||||
/*
|
||||
* opal.c - Parser for Opal card (Sydney, Australia).
|
||||
*
|
||||
* Copyright 2023 Michael Farrell <micolous+git@gmail.com>
|
||||
*
|
||||
* This will only read "standard" MIFARE DESFire-based Opal cards. Free travel
|
||||
* cards (including School Opal cards, veteran, vision-impaired persons and
|
||||
* TfNSW employees' cards) and single-trip tickets are MIFARE Ultralight C
|
||||
* cards and not supported.
|
||||
*
|
||||
* Reference: https://github.com/metrodroid/metrodroid/wiki/Opal
|
||||
*
|
||||
* Note: The card values are all little-endian (like Flipper), but the above
|
||||
* reference was originally written based on Java APIs, which are big-endian.
|
||||
* This implementation presumes a little-endian system.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "nfc_supported_card.h"
|
||||
#include "opal.h"
|
||||
|
||||
#include <applications/services/locale/locale.h>
|
||||
#include <gui/modules/widget.h>
|
||||
#include <nfc_worker_i.h>
|
||||
|
||||
#include <furi_hal.h>
|
||||
|
||||
static const uint8_t opal_aid[3] = {0x31, 0x45, 0x53};
|
||||
static const char* opal_modes[5] =
|
||||
{"Rail / Metro", "Ferry / Light Rail", "Bus", "Unknown mode", "Manly Ferry"};
|
||||
static const char* opal_usages[14] = {
|
||||
"New / Unused",
|
||||
"Tap on: new journey",
|
||||
"Tap on: transfer from same mode",
|
||||
"Tap on: transfer from other mode",
|
||||
"", // Manly Ferry: new journey
|
||||
"", // Manly Ferry: transfer from ferry
|
||||
"", // Manly Ferry: transfer from other
|
||||
"Tap off: distance fare",
|
||||
"Tap off: flat fare",
|
||||
"Automated tap off: failed to tap off",
|
||||
"Tap off: end of trip without start",
|
||||
"Tap off: reversal",
|
||||
"Tap on: rejected",
|
||||
"Unknown usage",
|
||||
};
|
||||
|
||||
// Opal file 0x7 structure. Assumes a little-endian CPU.
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint32_t serial : 32;
|
||||
uint8_t check_digit : 4;
|
||||
bool blocked : 1;
|
||||
uint16_t txn_number : 16;
|
||||
int32_t balance : 21;
|
||||
uint16_t days : 15;
|
||||
uint16_t minutes : 11;
|
||||
uint8_t mode : 3;
|
||||
uint16_t usage : 4;
|
||||
bool auto_topup : 1;
|
||||
uint8_t weekly_journeys : 4;
|
||||
uint16_t checksum : 16;
|
||||
} OpalFile;
|
||||
|
||||
static_assert(sizeof(OpalFile) == 16);
|
||||
|
||||
// Converts an Opal timestamp to FuriHalRtcDateTime.
|
||||
//
|
||||
// Opal measures days since 1980-01-01 and minutes since midnight, and presumes
|
||||
// all days are 1440 minutes.
|
||||
void opal_date_time_to_furi(uint16_t days, uint16_t minutes, FuriHalRtcDateTime* out) {
|
||||
if(!out) return;
|
||||
uint16_t diy;
|
||||
out->year = 1980;
|
||||
out->month = 1;
|
||||
// 1980-01-01 is a Tuesday
|
||||
out->weekday = ((days + 1) % 7) + 1;
|
||||
out->hour = minutes / 60;
|
||||
out->minute = minutes % 60;
|
||||
out->second = 0;
|
||||
|
||||
// What year is it?
|
||||
for(;;) {
|
||||
diy = furi_hal_rtc_get_days_per_year(out->year);
|
||||
if(days < diy) break;
|
||||
days -= diy;
|
||||
out->year++;
|
||||
}
|
||||
|
||||
// 1-index the day of the year
|
||||
days++;
|
||||
// What month is it?
|
||||
bool is_leap = furi_hal_rtc_is_leap_year(out->year);
|
||||
|
||||
for(;;) {
|
||||
uint8_t dim = furi_hal_rtc_get_days_per_month(is_leap, out->month);
|
||||
if(days <= dim) break;
|
||||
days -= dim;
|
||||
out->month++;
|
||||
}
|
||||
|
||||
out->day = days;
|
||||
}
|
||||
|
||||
bool opal_parser_parse(NfcDeviceData* dev_data) {
|
||||
if(dev_data->protocol != NfcDeviceProtocolMifareDesfire) {
|
||||
return false;
|
||||
}
|
||||
|
||||
MifareDesfireApplication* app = mf_df_get_application(&dev_data->mf_df_data, &opal_aid);
|
||||
if(app == NULL) {
|
||||
return false;
|
||||
}
|
||||
MifareDesfireFile* f = mf_df_get_file(app, 0x07);
|
||||
if(f == NULL || f->type != MifareDesfireFileTypeStandard || f->settings.data.size != 16 ||
|
||||
!f->contents) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OpalFile* o = (OpalFile*)f->contents;
|
||||
|
||||
uint8_t serial2 = o->serial / 10000000;
|
||||
uint16_t serial3 = (o->serial / 1000) % 10000;
|
||||
uint16_t serial4 = (o->serial % 1000);
|
||||
|
||||
if(o->check_digit > 9) {
|
||||
return false;
|
||||
}
|
||||
|
||||
char* sign = "";
|
||||
if(o->balance < 0) {
|
||||
// Negative balance. Make this a positive value again and record the
|
||||
// sign separately, because then we can handle balances of -99..-1
|
||||
// cents, as the "dollars" division below would result in a positive
|
||||
// zero value.
|
||||
o->balance = abs(o->balance); //-V1081
|
||||
sign = "-";
|
||||
}
|
||||
uint8_t cents = o->balance % 100;
|
||||
int32_t dollars = o->balance / 100;
|
||||
|
||||
FuriHalRtcDateTime timestamp;
|
||||
opal_date_time_to_furi(o->days, o->minutes, ×tamp);
|
||||
|
||||
if(o->mode >= 3) {
|
||||
// 3..7 are "reserved", but we use 4 to indicate the Manly Ferry.
|
||||
o->mode = 3;
|
||||
}
|
||||
|
||||
if(o->usage >= 4 && o->usage <= 6) {
|
||||
// Usages 4..6 associated with the Manly Ferry, which correspond to
|
||||
// usages 1..3 for other modes.
|
||||
o->usage -= 3;
|
||||
o->mode = 4;
|
||||
}
|
||||
|
||||
const char* mode_str = (o->mode <= 4 ? opal_modes[o->mode] : opal_modes[3]); //-V547
|
||||
const char* usage_str = (o->usage <= 12 ? opal_usages[o->usage] : opal_usages[13]);
|
||||
|
||||
furi_string_printf(
|
||||
dev_data->parsed_data,
|
||||
"\e#Opal: $%s%ld.%02hu\n3085 22%02hhu %04hu %03hu%01hhu\n%s, %s\n",
|
||||
sign,
|
||||
dollars,
|
||||
cents,
|
||||
serial2,
|
||||
serial3,
|
||||
serial4,
|
||||
o->check_digit,
|
||||
mode_str,
|
||||
usage_str);
|
||||
FuriString* timestamp_str = furi_string_alloc();
|
||||
locale_format_date(timestamp_str, ×tamp, locale_get_date_format(), "-");
|
||||
furi_string_cat(dev_data->parsed_data, timestamp_str);
|
||||
furi_string_cat_str(dev_data->parsed_data, " at ");
|
||||
|
||||
locale_format_time(timestamp_str, ×tamp, locale_get_time_format(), false);
|
||||
furi_string_cat(dev_data->parsed_data, timestamp_str);
|
||||
|
||||
furi_string_free(timestamp_str);
|
||||
furi_string_cat_printf(
|
||||
dev_data->parsed_data,
|
||||
"\nWeekly journeys: %hhu, Txn #%hu\n",
|
||||
o->weekly_journeys,
|
||||
o->txn_number);
|
||||
|
||||
if(o->auto_topup) {
|
||||
furi_string_cat_str(dev_data->parsed_data, "Auto-topup enabled\n");
|
||||
}
|
||||
if(o->blocked) {
|
||||
furi_string_cat_str(dev_data->parsed_data, "Card blocked\n");
|
||||
}
|
||||
return true;
|
||||
}
|
5
lib/nfc/parsers/opal.h
Normal file
5
lib/nfc/parsers/opal.h
Normal file
@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "nfc_supported_card.h"
|
||||
|
||||
bool opal_parser_parse(NfcDeviceData* dev_data);
|
@ -42,6 +42,30 @@ void mf_df_clear(MifareDesfireData* data) {
|
||||
data->app_head = NULL;
|
||||
}
|
||||
|
||||
MifareDesfireApplication* mf_df_get_application(MifareDesfireData* data, const uint8_t (*aid)[3]) {
|
||||
if(!data) {
|
||||
return NULL;
|
||||
}
|
||||
for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
|
||||
if(memcmp(aid, app->id, 3) == 0) {
|
||||
return app;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MifareDesfireFile* mf_df_get_file(MifareDesfireApplication* app, uint8_t id) {
|
||||
if(!app) {
|
||||
return NULL;
|
||||
}
|
||||
for(MifareDesfireFile* file = app->file_head; file; file = file->next) {
|
||||
if(file->id == id) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void mf_df_cat_data(MifareDesfireData* data, FuriString* out) {
|
||||
mf_df_cat_card_info(data, out);
|
||||
for(MifareDesfireApplication* app = data->app_head; app; app = app->next) {
|
||||
|
@ -130,6 +130,9 @@ void mf_df_cat_file(MifareDesfireFile* file, FuriString* out);
|
||||
|
||||
bool mf_df_check_card_type(uint8_t ATQA0, uint8_t ATQA1, uint8_t SAK);
|
||||
|
||||
MifareDesfireApplication* mf_df_get_application(MifareDesfireData* data, const uint8_t (*aid)[3]);
|
||||
MifareDesfireFile* mf_df_get_file(MifareDesfireApplication* app, uint8_t id);
|
||||
|
||||
uint16_t mf_df_prepare_get_version(uint8_t* dest);
|
||||
bool mf_df_parse_get_version_response(uint8_t* buf, uint16_t len, MifareDesfireVersion* out);
|
||||
|
||||
|
@ -135,6 +135,7 @@ void pulse_reader_stop(PulseReader* signal) {
|
||||
LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1);
|
||||
LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
|
||||
LL_TIM_DisableCounter(TIM2);
|
||||
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||
furi_hal_gpio_init_simple(signal->gpio, GpioModeAnalog);
|
||||
}
|
||||
|
||||
@ -146,6 +147,8 @@ void pulse_reader_start(PulseReader* signal) {
|
||||
signal->dma_config_gpio.MemoryOrM2MDstAddress = (uint32_t)signal->gpio_buffer;
|
||||
signal->dma_config_gpio.NbData = signal->size;
|
||||
|
||||
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||
|
||||
/* start counter */
|
||||
LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
|
||||
LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#define VERSION_MAGIC (0xBE40u)
|
||||
#define VERSION_MAJOR (0x1u)
|
||||
#define VERSION_MINOR (0x0u)
|
||||
#define VERSION_MINOR (0x1u)
|
||||
|
||||
struct Version {
|
||||
// Header
|
||||
@ -20,6 +20,9 @@ struct Version {
|
||||
// Payload bits and pieces
|
||||
const uint8_t target;
|
||||
const bool build_is_dirty;
|
||||
// v 1.1
|
||||
const char* firmware_origin;
|
||||
const char* git_origin;
|
||||
const char* custom_flipper_name;
|
||||
};
|
||||
|
||||
@ -38,6 +41,8 @@ static Version version = {
|
||||
,
|
||||
.target = TARGET,
|
||||
.build_is_dirty = BUILD_DIRTY,
|
||||
.firmware_origin = FIRMWARE_ORIGIN,
|
||||
.git_origin = GIT_ORIGIN,
|
||||
.custom_flipper_name = NULL,
|
||||
};
|
||||
|
||||
@ -83,3 +88,11 @@ uint8_t version_get_target(const Version* v) {
|
||||
bool version_get_dirty_flag(const Version* v) {
|
||||
return v ? v->build_is_dirty : version.build_is_dirty;
|
||||
}
|
||||
|
||||
const char* version_get_firmware_origin(const Version* v) {
|
||||
return v ? v->firmware_origin : version.firmware_origin;
|
||||
}
|
||||
|
||||
const char* version_get_git_origin(const Version* v) {
|
||||
return v ? v->git_origin : version.git_origin;
|
||||
}
|
||||
|
@ -100,6 +100,17 @@ uint8_t version_get_target(const Version* v);
|
||||
*/
|
||||
bool version_get_dirty_flag(const Version* v);
|
||||
|
||||
/**
|
||||
* Get firmware origin. "Official" for mainline firmware, fork name for forks.
|
||||
* Set by FIRMWARE_ORIGIN fbt argument.
|
||||
*/
|
||||
const char* version_get_firmware_origin(const Version* v);
|
||||
|
||||
/**
|
||||
* Get git repo origin
|
||||
*/
|
||||
const char* version_get_git_origin(const Version* v);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -23,6 +23,10 @@ class VersionData:
|
||||
version: str
|
||||
target: int
|
||||
build_is_dirty: bool
|
||||
# Since version 1.1
|
||||
firmware_origin: str = ""
|
||||
git_origin: str = ""
|
||||
# More fields may be added in the future
|
||||
extra: Optional[Dict[str, str]] = field(default_factory=dict)
|
||||
|
||||
|
||||
@ -52,7 +56,7 @@ class VersionLoader:
|
||||
|
||||
# Struct version 1.0
|
||||
extra_data = int(self.version_ptr[5].cast(self._uint_type))
|
||||
return VersionData(
|
||||
version_data = VersionData(
|
||||
git_hash=self.version_ptr[1].cast(self._cstr_type).string(),
|
||||
git_branch=self.version_ptr[2].cast(self._cstr_type).string(),
|
||||
build_date=self.version_ptr[3].cast(self._cstr_type).string(),
|
||||
@ -60,6 +64,12 @@ class VersionLoader:
|
||||
target=extra_data & 0xF,
|
||||
build_is_dirty=bool((extra_data >> 8) & 0xF),
|
||||
)
|
||||
if minor >= 1:
|
||||
version_data.firmware_origin = (
|
||||
self.version_ptr[6].cast(self._cstr_type).string()
|
||||
)
|
||||
version_data.git_origin = self.version_ptr[7].cast(self._cstr_type).string()
|
||||
return version_data
|
||||
|
||||
def load_unversioned(self):
|
||||
"""Parse an early version of the version struct."""
|
||||
@ -104,6 +114,10 @@ class FlipperFwVersion(gdb.Command):
|
||||
print(f"\tGit commit: {v.version.git_hash}")
|
||||
print(f"\tDirty: {v.version.build_is_dirty}")
|
||||
print(f"\tHW Target: {v.version.target}")
|
||||
if v.version.firmware_origin:
|
||||
print(f"\tOrigin: {v.version.firmware_origin}")
|
||||
if v.version.git_origin:
|
||||
print(f"\tGit origin: {v.version.git_origin}")
|
||||
|
||||
|
||||
FlipperFwVersion()
|
||||
|
67
scripts/fbt_tools/fbt_envhooks.py
Normal file
67
scripts/fbt_tools/fbt_envhooks.py
Normal file
@ -0,0 +1,67 @@
|
||||
"""
|
||||
|
||||
To introduce changes to firmware build environment that are specific to your fork:
|
||||
|
||||
create a file "scripts/fbt/fbt_hooks.py"
|
||||
|
||||
With it, you can define functions that will be called at specific points of
|
||||
firmware build configuration, with environment as an argument.
|
||||
|
||||
For example, you can define a function `PreConfigureFwEnvionment(env)` that
|
||||
defines that will be a part of SDK build, so applications can
|
||||
use them for conditional compilation.
|
||||
|
||||
Here is a list of all available hooks:
|
||||
|
||||
PreConfigureFwEnvionment(env):
|
||||
This function is called on firmware environment (incl. updater)
|
||||
before any major configuration is done.
|
||||
|
||||
PostConfigureFwEnvionment(env):
|
||||
This function is called on firmware environment (incl. updater)
|
||||
after all configuration is done.
|
||||
|
||||
PreConfigureUfbtEnvionment(env):
|
||||
This function is called on ufbt environment at the beginning of
|
||||
its configuration, before dist environment is created.
|
||||
|
||||
PostConfigureUfbtEnvionment(env):
|
||||
This function is called on ufbt dist_env environment after all
|
||||
configuration and target creation is done.
|
||||
"""
|
||||
|
||||
|
||||
class DefaultFbtHooks:
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
from fbt import fbt_hooks
|
||||
except ImportError:
|
||||
fbt_hooks = DefaultFbtHooks()
|
||||
|
||||
|
||||
def generate(env):
|
||||
stub_hook = lambda env: None
|
||||
control_hooks = [
|
||||
"PreConfigureFwEnvionment",
|
||||
"PostConfigureFwEnvionment",
|
||||
"PreConfigureUfbtEnvionment",
|
||||
"PostConfigureUfbtEnvionment",
|
||||
]
|
||||
|
||||
if (
|
||||
isinstance(fbt_hooks, DefaultFbtHooks)
|
||||
and env.subst("${FIRMWARE_ORIGIN}") != "Official"
|
||||
):
|
||||
# If fbt_hooks.py is not present, but we are not building official firmware,
|
||||
# create "scripts/fbt/fbt_hooks.py" to implement changes to firmware build environment.
|
||||
pass
|
||||
|
||||
for hook_name in control_hooks:
|
||||
hook_fn = getattr(fbt_hooks, hook_name, stub_hook)
|
||||
env.AddMethod(hook_fn, hook_name)
|
||||
|
||||
|
||||
def exists():
|
||||
return True
|
@ -19,7 +19,9 @@ def generate(env):
|
||||
BUILDERS={
|
||||
"VersionBuilder": Builder(
|
||||
action=Action(
|
||||
'${PYTHON3} "${VERSION_SCRIPT}" generate -t ${TARGET_HW} -o ${TARGET.dir.posix} --dir "${ROOT_DIR}"',
|
||||
'${PYTHON3} "${VERSION_SCRIPT}" generate '
|
||||
"-t ${TARGET_HW} -fw-origin ${FIRMWARE_ORIGIN} "
|
||||
'-o ${TARGET.dir.posix} --dir "${ROOT_DIR}"',
|
||||
"${VERSIONCOMSTR}",
|
||||
),
|
||||
emitter=version_emitter,
|
||||
|
@ -98,6 +98,7 @@ env = core_env.Clone(
|
||||
"fbt_apps",
|
||||
"fbt_extapps",
|
||||
"fbt_assets",
|
||||
"fbt_envhooks",
|
||||
("compilation_db", {"COMPILATIONDB_COMSTR": "\tCDB\t${TARGET}"}),
|
||||
],
|
||||
FBT_FAP_DEBUG_ELF_ROOT=ufbt_build_dir,
|
||||
@ -117,6 +118,8 @@ env = core_env.Clone(
|
||||
wrap_tempfile(env, "LINKCOM")
|
||||
wrap_tempfile(env, "ARCOM")
|
||||
|
||||
env.PreConfigureUfbtEnvionment()
|
||||
|
||||
# print(env.Dump())
|
||||
|
||||
# Dist env
|
||||
@ -474,3 +477,5 @@ dist_env.PhonyTarget(
|
||||
"env",
|
||||
"@echo $( ${FBT_SCRIPT_DIR}/toolchain/fbtenv.sh $)",
|
||||
)
|
||||
|
||||
dist_env.PostConfigureUfbtEnvionment()
|
||||
|
@ -52,8 +52,23 @@ class GitVersion:
|
||||
"GIT_BRANCH": branch,
|
||||
"VERSION": version,
|
||||
"BUILD_DIRTY": dirty and 1 or 0,
|
||||
"GIT_ORIGIN": ",".join(self._get_git_origins()),
|
||||
}
|
||||
|
||||
def _get_git_origins(self):
|
||||
try:
|
||||
remotes = self._exec_git("remote -v")
|
||||
except subprocess.CalledProcessError:
|
||||
return set()
|
||||
origins = set()
|
||||
for line in remotes.split("\n"):
|
||||
if not line:
|
||||
continue
|
||||
_, destination = line.split("\t")
|
||||
url, _ = destination.split(" ")
|
||||
origins.add(url)
|
||||
return origins
|
||||
|
||||
def _exec_git(self, args):
|
||||
cmd = ["git"]
|
||||
cmd.extend(args.split(" "))
|
||||
@ -81,6 +96,13 @@ class Main(App):
|
||||
help="hardware target",
|
||||
required=True,
|
||||
)
|
||||
self.parser_generate.add_argument(
|
||||
"-fw-origin",
|
||||
dest="firmware_origin",
|
||||
type=str,
|
||||
help="firmware origin",
|
||||
required=True,
|
||||
)
|
||||
self.parser_generate.add_argument("--dir", dest="sourcedir", required=True)
|
||||
self.parser_generate.set_defaults(func=self.generate)
|
||||
|
||||
@ -96,6 +118,7 @@ class Main(App):
|
||||
{
|
||||
"BUILD_DATE": build_date.strftime("%d-%m-%Y"),
|
||||
"TARGET": self.args.target,
|
||||
"FIRMWARE_ORIGIN": self.args.firmware_origin,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -241,6 +241,13 @@ vars.AddVariables(
|
||||
help="Don't open browser after generating error repots",
|
||||
default=False,
|
||||
),
|
||||
(
|
||||
"FIRMWARE_ORIGIN",
|
||||
"Firmware origin. 'Official' if follows upstream's API structure, otherwise fork name. "
|
||||
" This will also create a C define FW_ORIGIN_<origin> so that "
|
||||
" app can check what version it is being built for.",
|
||||
"Official",
|
||||
),
|
||||
)
|
||||
|
||||
Return("vars")
|
||||
|
Loading…
Reference in New Issue
Block a user