[FL-3295] FuriHal: add bus abstraction (#2614)
* FuriHal: add bus abstraction and port some subsystem to it * Make PVS happy, cleanup code * Update API symbols for f18 * F18: backport bus changes from f7 * Revert to STOP2 sleep mode * Fix downgrading the firmware via updater * Port iButton TIM1 to furi_hal_bus * Port Infrared TIM1 and TIM2 to furi_hal_bus * Just enable the timer bus * Port furi_hal_pwm to bus API * Fix include statement * Port furi_hal_rfid to bus API * Port furi_hal_subghz and others to bus API * Remove unneeded include * Improve furi_hal_infrared defines * Reset LPTIM1 via furi_hal_bus API * Crash when trying to enable an already enabled peripheral * Better defines * Improved checks * Lots of macro wrappers * Copy spi changes for f18 * Fix crashes in LFRFID system * Fix crashes in NFC system * Improve comments * Create FuriHalBus.md * Update FuriHalBus.md * Fix crash when launching updater * Documentation: couple small fixes in FuriHalBus * FuriHal: fix copypaste in furi_hal_rfid_tim_reset * FuriHal: reset radio core related peripherals on restart * FuriHalBus: is enabled routine and bug fix for uart * RFID HAL: accomodate furi hal bus Co-authored-by: Georgii Surkov <georgii.surkov@outlook.com> Co-authored-by: Georgii Surkov <37121527+gsurkov@users.noreply.github.com> Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
parent
363f555ed7
commit
3de856f8d5
@ -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_set_callback(comparator_trigger_callback, app);
|
||||||
furi_hal_rfid_comp_start();
|
furi_hal_rfid_comp_start();
|
||||||
|
|
||||||
furi_hal_rfid_pins_read();
|
furi_hal_rfid_tim_read_start(125000, 0.5);
|
||||||
furi_hal_rfid_tim_read(125000, 0.5);
|
|
||||||
furi_hal_rfid_tim_read_start();
|
|
||||||
|
|
||||||
view_dispatcher_switch_to_view(app->view_dispatcher, LfRfidDebugViewTune);
|
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_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
|
||||||
furi_hal_rfid_tim_read_stop();
|
furi_hal_rfid_tim_read_stop();
|
||||||
furi_hal_rfid_tim_reset();
|
|
||||||
furi_hal_rfid_pins_reset();
|
furi_hal_rfid_pins_reset();
|
||||||
}
|
}
|
||||||
|
|||||||
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 | | |
|
||||||
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,27.1,,
|
Version,+,28.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.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_resources.h,,
|
||||||
Header,+,firmware/targets/f18/furi_hal/furi_hal_spi_config.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/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_clock.h,,
|
||||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_console.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_flash.h,,
|
||||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,,
|
Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,,
|
||||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.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_unlock_core2,void,
|
||||||
Function,+,furi_hal_bt_update_battery_level,void,uint8_t
|
Function,+,furi_hal_bt_update_battery_level,void,uint8_t
|
||||||
Function,+,furi_hal_bt_update_power_state,void,
|
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_ctrl_line_state,uint8_t,uint8_t
|
||||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,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"
|
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_enable,void,
|
||||||
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
||||||
Function,-,furi_hal_deinit_early,void,
|
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_erase,void,uint8_t
|
||||||
Function,-,furi_hal_flash_get_base,size_t,
|
Function,-,furi_hal_flash_get_base,size_t,
|
||||||
Function,-,furi_hal_flash_get_cycles_count,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_pwm_stop,void,FuriHalPwmOutputId
|
||||||
Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t"
|
Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t"
|
||||||
Function,+,furi_hal_random_get,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,const FuriHalRegion*,
|
||||||
Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t
|
Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t
|
||||||
Function,+,furi_hal_region_get_name,const char*,
|
Function,+,furi_hal_region_get_name,const char*,
|
||||||
|
|||||||
|
@ -9,6 +9,8 @@
|
|||||||
void furi_hal_init_early() {
|
void furi_hal_init_early() {
|
||||||
furi_hal_cortex_init_early();
|
furi_hal_cortex_init_early();
|
||||||
furi_hal_clock_init_early();
|
furi_hal_clock_init_early();
|
||||||
|
furi_hal_bus_init_early();
|
||||||
|
furi_hal_dma_init_early();
|
||||||
furi_hal_resources_init_early();
|
furi_hal_resources_init_early();
|
||||||
furi_hal_os_init();
|
furi_hal_os_init();
|
||||||
furi_hal_spi_config_init_early();
|
furi_hal_spi_config_init_early();
|
||||||
@ -22,12 +24,15 @@ void furi_hal_deinit_early() {
|
|||||||
furi_hal_i2c_deinit_early();
|
furi_hal_i2c_deinit_early();
|
||||||
furi_hal_spi_config_deinit_early();
|
furi_hal_spi_config_deinit_early();
|
||||||
furi_hal_resources_deinit_early();
|
furi_hal_resources_deinit_early();
|
||||||
|
furi_hal_dma_deinit_early();
|
||||||
|
furi_hal_bus_deinit_early();
|
||||||
furi_hal_clock_deinit_early();
|
furi_hal_clock_deinit_early();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_init() {
|
void furi_hal_init() {
|
||||||
furi_hal_mpu_init();
|
furi_hal_mpu_init();
|
||||||
furi_hal_clock_init();
|
furi_hal_clock_init();
|
||||||
|
furi_hal_random_init();
|
||||||
furi_hal_console_init();
|
furi_hal_console_init();
|
||||||
furi_hal_rtc_init();
|
furi_hal_rtc_init();
|
||||||
furi_hal_interrupt_init();
|
furi_hal_interrupt_init();
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_rcc.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() {
|
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);
|
furi_hal_resources_init_input_pins(GpioModeInput);
|
||||||
|
|
||||||
// SD Card stepdown control
|
// SD Card stepdown control
|
||||||
@ -162,6 +170,12 @@ void furi_hal_resources_init_early() {
|
|||||||
|
|
||||||
void furi_hal_resources_deinit_early() {
|
void furi_hal_resources_deinit_early() {
|
||||||
furi_hal_resources_init_input_pins(GpioModeAnalog);
|
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() {
|
void furi_hal_resources_init() {
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
#include <furi_hal_spi_config.h>
|
#include <furi_hal_spi_config.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi_hal_spi.h>
|
#include <furi_hal_spi.h>
|
||||||
#include <furi.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) {
|
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||||
if(event == FuriHalSpiBusEventInit) {
|
if(event == FuriHalSpiBusEventInit) {
|
||||||
furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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;
|
bus->current_handle = NULL;
|
||||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||||
furi_mutex_free(furi_hal_spi_bus_r_mutex);
|
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) {
|
} else if(event == FuriHalSpiBusEventLock) {
|
||||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
|
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||||
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventActivate) {
|
} else if(event == FuriHalSpiBusEventActivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FuriHalBusSPI1);
|
||||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusSPI1);
|
||||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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) {
|
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||||
if(event == FuriHalSpiBusEventInit) {
|
if(event == FuriHalSpiBusEventInit) {
|
||||||
furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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;
|
bus->current_handle = NULL;
|
||||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||||
furi_mutex_free(furi_hal_spi_bus_d_mutex);
|
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) {
|
} else if(event == FuriHalSpiBusEventLock) {
|
||||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
|
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||||
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventActivate) {
|
} else if(event == FuriHalSpiBusEventActivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FuriHalBusSPI2);
|
||||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusSPI2);
|
||||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
entry,status,name,type,params
|
entry,status,name,type,params
|
||||||
Version,+,27.1,,
|
Version,+,28.0,,
|
||||||
Header,+,applications/services/bt/bt_service/bt.h,,
|
Header,+,applications/services/bt/bt_service/bt.h,,
|
||||||
Header,+,applications/services/cli/cli.h,,
|
Header,+,applications/services/cli/cli.h,,
|
||||||
Header,+,applications/services/cli/cli_vcp.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/power/power_service/power.h,,
|
||||||
Header,+,applications/services/rpc/rpc_app.h,,
|
Header,+,applications/services/rpc/rpc_app.h,,
|
||||||
Header,+,applications/services/storage/storage.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_clock.h,,
|
||||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_console.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_flash.h,,
|
||||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,,
|
Header,+,firmware/targets/f7/furi_hal/furi_hal_gpio.h,,
|
||||||
Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.h,,
|
Header,+,firmware/targets/f7/furi_hal/furi_hal_i2c_config.h,,
|
||||||
@ -1065,6 +1067,12 @@ Function,+,furi_hal_bt_stop_tone_tx,void,
|
|||||||
Function,+,furi_hal_bt_unlock_core2,void,
|
Function,+,furi_hal_bt_unlock_core2,void,
|
||||||
Function,+,furi_hal_bt_update_battery_level,void,uint8_t
|
Function,+,furi_hal_bt_update_battery_level,void,uint8_t
|
||||||
Function,+,furi_hal_bt_update_power_state,void,
|
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_ctrl_line_state,uint8_t,uint8_t
|
||||||
Function,+,furi_hal_cdc_get_port_settings,usb_cdc_line_coding*,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"
|
Function,+,furi_hal_cdc_receive,int32_t,"uint8_t, uint8_t*, uint16_t"
|
||||||
@ -1107,6 +1115,8 @@ Function,+,furi_hal_debug_disable,void,
|
|||||||
Function,+,furi_hal_debug_enable,void,
|
Function,+,furi_hal_debug_enable,void,
|
||||||
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
Function,+,furi_hal_debug_is_gdb_session_active,_Bool,
|
||||||
Function,-,furi_hal_deinit_early,void,
|
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_erase,void,uint8_t
|
||||||
Function,-,furi_hal_flash_get_base,size_t,
|
Function,-,furi_hal_flash_get_base,size_t,
|
||||||
Function,-,furi_hal_flash_get_cycles_count,size_t,
|
Function,-,furi_hal_flash_get_cycles_count,size_t,
|
||||||
@ -1273,6 +1283,7 @@ Function,+,furi_hal_pwm_start,void,"FuriHalPwmOutputId, uint32_t, uint8_t"
|
|||||||
Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId
|
Function,+,furi_hal_pwm_stop,void,FuriHalPwmOutputId
|
||||||
Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t"
|
Function,+,furi_hal_random_fill_buf,void,"uint8_t*, uint32_t"
|
||||||
Function,+,furi_hal_random_get,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,const FuriHalRegion*,
|
||||||
Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t
|
Function,+,furi_hal_region_get_band,const FuriHalRegionBand*,uint32_t
|
||||||
Function,+,furi_hal_region_get_name,const char*,
|
Function,+,furi_hal_region_get_name,const char*,
|
||||||
@ -1284,31 +1295,23 @@ Function,-,furi_hal_resources_deinit_early,void,
|
|||||||
Function,+,furi_hal_resources_get_ext_pin_number,int32_t,const GpioPin*
|
Function,+,furi_hal_resources_get_ext_pin_number,int32_t,const GpioPin*
|
||||||
Function,-,furi_hal_resources_init,void,
|
Function,-,furi_hal_resources_init,void,
|
||||||
Function,-,furi_hal_resources_init_early,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_set_callback,void,"FuriHalRfidCompCallback, void*"
|
||||||
Function,+,furi_hal_rfid_comp_start,void,
|
Function,+,furi_hal_rfid_comp_start,void,
|
||||||
Function,+,furi_hal_rfid_comp_stop,void,
|
Function,+,furi_hal_rfid_comp_stop,void,
|
||||||
Function,-,furi_hal_rfid_init,void,
|
Function,-,furi_hal_rfid_init,void,
|
||||||
Function,+,furi_hal_rfid_pin_pull_pulldown,void,
|
Function,+,furi_hal_rfid_pin_pull_pulldown,void,
|
||||||
Function,+,furi_hal_rfid_pin_pull_release,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_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_period,void,uint32_t
|
||||||
Function,+,furi_hal_rfid_set_read_pulse,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_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_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_start,void,"FuriHalRfidReadCaptureCallback, void*"
|
||||||
Function,+,furi_hal_rfid_tim_read_capture_stop,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_read_stop,void,
|
||||||
Function,+,furi_hal_rfid_tim_reset,void,
|
|
||||||
Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime*
|
Function,+,furi_hal_rtc_datetime_to_timestamp,uint32_t,FuriHalRtcDateTime*
|
||||||
Function,-,furi_hal_rtc_deinit_early,void,
|
Function,-,furi_hal_rtc_deinit_early,void,
|
||||||
Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode,
|
Function,+,furi_hal_rtc_get_boot_mode,FuriHalRtcBootMode,
|
||||||
|
|||||||
|
@ -9,6 +9,8 @@
|
|||||||
void furi_hal_init_early() {
|
void furi_hal_init_early() {
|
||||||
furi_hal_cortex_init_early();
|
furi_hal_cortex_init_early();
|
||||||
furi_hal_clock_init_early();
|
furi_hal_clock_init_early();
|
||||||
|
furi_hal_bus_init_early();
|
||||||
|
furi_hal_dma_init_early();
|
||||||
furi_hal_resources_init_early();
|
furi_hal_resources_init_early();
|
||||||
furi_hal_os_init();
|
furi_hal_os_init();
|
||||||
furi_hal_spi_config_init_early();
|
furi_hal_spi_config_init_early();
|
||||||
@ -22,12 +24,15 @@ void furi_hal_deinit_early() {
|
|||||||
furi_hal_i2c_deinit_early();
|
furi_hal_i2c_deinit_early();
|
||||||
furi_hal_spi_config_deinit_early();
|
furi_hal_spi_config_deinit_early();
|
||||||
furi_hal_resources_deinit_early();
|
furi_hal_resources_deinit_early();
|
||||||
|
furi_hal_dma_deinit_early();
|
||||||
|
furi_hal_bus_deinit_early();
|
||||||
furi_hal_clock_deinit_early();
|
furi_hal_clock_deinit_early();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_init() {
|
void furi_hal_init() {
|
||||||
furi_hal_mpu_init();
|
furi_hal_mpu_init();
|
||||||
furi_hal_clock_init();
|
furi_hal_clock_init();
|
||||||
|
furi_hal_random_init();
|
||||||
furi_hal_console_init();
|
furi_hal_console_init();
|
||||||
furi_hal_rtc_init();
|
furi_hal_rtc_init();
|
||||||
furi_hal_interrupt_init();
|
furi_hal_interrupt_init();
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <furi_hal_version.h>
|
#include <furi_hal_version.h>
|
||||||
#include <furi_hal_bt_hid.h>
|
#include <furi_hal_bt_hid.h>
|
||||||
#include <furi_hal_bt_serial.h>
|
#include <furi_hal_bt_serial.h>
|
||||||
|
#include <furi_hal_bus.c>
|
||||||
#include "battery_service.h"
|
#include "battery_service.h"
|
||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
@ -80,6 +81,11 @@ FuriHalBtProfileConfig profile_config[FuriHalBtProfileNumber] = {
|
|||||||
FuriHalBtProfileConfig* current_profile = NULL;
|
FuriHalBtProfileConfig* current_profile = NULL;
|
||||||
|
|
||||||
void furi_hal_bt_init() {
|
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) {
|
if(!furi_hal_bt_core2_mtx) {
|
||||||
furi_hal_bt_core2_mtx = furi_mutex_alloc(FuriMutexTypeNormal);
|
furi_hal_bt_core2_mtx = furi_mutex_alloc(FuriMutexTypeNormal);
|
||||||
furi_assert(furi_hal_bt_core2_mtx);
|
furi_assert(furi_hal_bt_core2_mtx);
|
||||||
@ -256,6 +262,11 @@ void furi_hal_bt_reinit() {
|
|||||||
furi_delay_ms(100);
|
furi_delay_ms(100);
|
||||||
ble_glue_thread_stop();
|
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_LOG_I(TAG, "Start BT initialization");
|
||||||
furi_hal_bt_init();
|
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_rcc.h>
|
||||||
#include <stm32wbxx_ll_utils.h>
|
#include <stm32wbxx_ll_utils.h>
|
||||||
#include <stm32wbxx_ll_cortex.h>
|
#include <stm32wbxx_ll_cortex.h>
|
||||||
#include <stm32wbxx_ll_bus.h>
|
|
||||||
|
|
||||||
#define TAG "FuriHalClock"
|
#define TAG "FuriHalClock"
|
||||||
|
|
||||||
@ -19,36 +18,9 @@
|
|||||||
void furi_hal_clock_init_early() {
|
void furi_hal_clock_init_early() {
|
||||||
LL_SetSystemCoreClock(CPU_CLOCK_HZ_EARLY);
|
LL_SetSystemCoreClock(CPU_CLOCK_HZ_EARLY);
|
||||||
LL_Init1msTick(SystemCoreClock);
|
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() {
|
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() {
|
void furi_hal_clock_init() {
|
||||||
@ -137,68 +109,12 @@ void furi_hal_clock_init() {
|
|||||||
SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TICK_INT_PRIORITY, 0));
|
SysTick_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), TICK_INT_PRIORITY, 0));
|
||||||
NVIC_EnableIRQ(SysTick_IRQn);
|
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_SetCLK48ClockSource(LL_RCC_CLK48_CLKSOURCE_PLLSAI1);
|
||||||
LL_RCC_HSI_EnableInStopMode(); // Ensure that MR is capable of work in STOP0
|
LL_RCC_HSI_EnableInStopMode(); // Ensure that MR is capable of work in STOP0
|
||||||
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE);
|
LL_RCC_SetSMPSClockSource(LL_RCC_SMPS_CLKSOURCE_HSE);
|
||||||
LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1);
|
LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1);
|
||||||
LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
|
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");
|
FURI_LOG_I(TAG, "Init OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
#include <furi_hal_crypto.h>
|
#include <furi_hal_crypto.h>
|
||||||
#include <furi_hal_bt.h>
|
#include <furi_hal_bt.h>
|
||||||
#include <furi_hal_random.h>
|
#include <furi_hal_random.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_cortex.h>
|
#include <stm32wbxx_ll_cortex.h>
|
||||||
#include <stm32wbxx_ll_bus.h>
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <interface/patterns/ble_thread/shci/shci.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_assert(furi_hal_crypto_mutex);
|
||||||
furi_check(furi_mutex_acquire(furi_hal_crypto_mutex, FuriWaitForever) == FuriStatusOk);
|
furi_check(furi_mutex_acquire(furi_hal_crypto_mutex, FuriWaitForever) == FuriStatusOk);
|
||||||
|
|
||||||
|
furi_hal_bus_enable(FuriHalBusAES1);
|
||||||
|
|
||||||
if(!furi_hal_bt_is_alive()) {
|
if(!furi_hal_bt_is_alive()) {
|
||||||
return false;
|
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);
|
SHCI_CmdStatus_t shci_state = SHCI_C2_FUS_UnloadUsrKey(slot);
|
||||||
furi_assert(shci_state == SHCI_Success);
|
furi_assert(shci_state == SHCI_Success);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusAES1);
|
||||||
LL_AHB2_GRP1_ForceReset(LL_AHB2_GRP1_PERIPH_AES1);
|
|
||||||
LL_AHB2_GRP1_ReleaseReset(LL_AHB2_GRP1_PERIPH_AES1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(furi_hal_crypto_mutex) == FuriStatusOk);
|
||||||
return (shci_state == SHCI_Success);
|
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 TAG "FuriHalFlash"
|
||||||
|
|
||||||
#define FURI_HAL_CRITICAL_MSG "Critical flash operation fail"
|
#define FURI_HAL_CRITICAL_MSG "Critical flash operation fail"
|
||||||
#define FURI_HAL_FLASH_READ_BLOCK 8
|
#define FURI_HAL_FLASH_READ_BLOCK (8U)
|
||||||
#define FURI_HAL_FLASH_WRITE_BLOCK 8
|
#define FURI_HAL_FLASH_WRITE_BLOCK (8U)
|
||||||
#define FURI_HAL_FLASH_PAGE_SIZE 4096
|
#define FURI_HAL_FLASH_PAGE_SIZE (4096U)
|
||||||
#define FURI_HAL_FLASH_CYCLES_COUNT 10000
|
#define FURI_HAL_FLASH_CYCLES_COUNT (10000U)
|
||||||
#define FURI_HAL_FLASH_TIMEOUT 1000
|
#define FURI_HAL_FLASH_TIMEOUT (1000U)
|
||||||
#define FURI_HAL_FLASH_KEY1 0x45670123U
|
#define FURI_HAL_FLASH_KEY1 (0x45670123U)
|
||||||
#define FURI_HAL_FLASH_KEY2 0xCDEF89ABU
|
#define FURI_HAL_FLASH_KEY2 (0xCDEF89ABU)
|
||||||
#define FURI_HAL_FLASH_TOTAL_PAGES 256
|
#define FURI_HAL_FLASH_TOTAL_PAGES (256U)
|
||||||
#define FURI_HAL_FLASH_SR_ERRORS \
|
#define FURI_HAL_FLASH_SR_ERRORS \
|
||||||
(FLASH_SR_OPERR | FLASH_SR_PROGERR | FLASH_SR_WRPERR | FLASH_SR_PGAERR | FLASH_SR_SIZERR | \
|
(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)
|
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_KEY1 (0x08192A3BU)
|
||||||
#define FURI_HAL_FLASH_OPT_KEY2 0x4C5D6E7F
|
#define FURI_HAL_FLASH_OPT_KEY2 (0x4C5D6E7FU)
|
||||||
#define FURI_HAL_FLASH_OB_TOTAL_WORDS (0x80 / (sizeof(uint32_t) * 2))
|
#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
|
/* 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
|
> 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.
|
> 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_ADDR_ALIGNED_64BITS(__VALUE__) (((__VALUE__)&0x7U) == (0x00UL))
|
||||||
#define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \
|
#define IS_FLASH_PROGRAM_ADDRESS(__VALUE__) \
|
||||||
|
|||||||
@ -1,7 +1,8 @@
|
|||||||
#include <furi_hal_i2c_config.h>
|
#include <furi_hal_i2c_config.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
#include <furi_hal_version.h>
|
#include <furi_hal_version.h>
|
||||||
#include <stm32wbxx_ll_bus.h>
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
|
|
||||||
/** Timing register value is computed with the STM32CubeMX Tool,
|
/** 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) {
|
static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
||||||
if(event == FuriHalI2cBusEventInit) {
|
if(event == FuriHalI2cBusEventInit) {
|
||||||
furi_hal_i2c_bus_power_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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;
|
bus->current_handle = NULL;
|
||||||
} else if(event == FuriHalI2cBusEventDeinit) {
|
} else if(event == FuriHalI2cBusEventDeinit) {
|
||||||
furi_mutex_free(furi_hal_i2c_bus_power_mutex);
|
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) {
|
} else if(event == FuriHalI2cBusEventLock) {
|
||||||
furi_check(
|
furi_check(
|
||||||
furi_mutex_acquire(furi_hal_i2c_bus_power_mutex, FuriWaitForever) == FuriStatusOk);
|
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);
|
furi_check(furi_mutex_release(furi_hal_i2c_bus_power_mutex) == FuriStatusOk);
|
||||||
} else if(event == FuriHalI2cBusEventActivate) {
|
} else if(event == FuriHalI2cBusEventActivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
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();
|
FURI_CRITICAL_EXIT();
|
||||||
} else if(event == FuriHalI2cBusEventDeactivate) {
|
} else if(event == FuriHalI2cBusEventDeactivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusI2C1);
|
||||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,17 +50,9 @@ FuriMutex* furi_hal_i2c_bus_external_mutex = NULL;
|
|||||||
static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
|
||||||
if(event == FuriHalI2cBusEventInit) {
|
if(event == FuriHalI2cBusEventInit) {
|
||||||
furi_hal_i2c_bus_external_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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;
|
bus->current_handle = NULL;
|
||||||
} else if(event == FuriHalI2cBusEventDeinit) {
|
} else if(event == FuriHalI2cBusEventDeinit) {
|
||||||
furi_mutex_free(furi_hal_i2c_bus_external_mutex);
|
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) {
|
} else if(event == FuriHalI2cBusEventLock) {
|
||||||
furi_check(
|
furi_check(
|
||||||
furi_mutex_acquire(furi_hal_i2c_bus_external_mutex, FuriWaitForever) == FuriStatusOk);
|
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);
|
furi_check(furi_mutex_release(furi_hal_i2c_bus_external_mutex) == FuriStatusOk);
|
||||||
} else if(event == FuriHalI2cBusEventActivate) {
|
} else if(event == FuriHalI2cBusEventActivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
|
furi_hal_bus_enable(FuriHalBusI2C3);
|
||||||
LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
|
LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
|
||||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
|
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
} else if(event == FuriHalI2cBusEventDeactivate) {
|
} else if(event == FuriHalI2cBusEventDeactivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusI2C3);
|
||||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,14 +1,15 @@
|
|||||||
#include <furi_hal_ibutton.h>
|
#include <furi_hal_ibutton.h>
|
||||||
#include <furi_hal_interrupt.h>
|
#include <furi_hal_interrupt.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
#include <stm32wbxx_ll_tim.h>
|
||||||
#include <stm32wbxx_ll_exti.h>
|
|
||||||
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#define TAG "FuriHalIbutton"
|
#define TAG "FuriHalIbutton"
|
||||||
#define FURI_HAL_IBUTTON_TIMER TIM1
|
#define FURI_HAL_IBUTTON_TIMER TIM1
|
||||||
|
#define FURI_HAL_IBUTTON_TIMER_BUS FuriHalBusTIM1
|
||||||
#define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16
|
#define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
@ -49,9 +50,7 @@ void furi_hal_ibutton_emulate_start(
|
|||||||
furi_hal_ibutton->callback = callback;
|
furi_hal_ibutton->callback = callback;
|
||||||
furi_hal_ibutton->context = context;
|
furi_hal_ibutton->context = context;
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FURI_HAL_IBUTTON_TIMER_BUS);
|
||||||
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, furi_hal_ibutton_emulate_isr, NULL);
|
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;
|
furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
|
||||||
LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER);
|
LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FURI_HAL_IBUTTON_TIMER_BUS);
|
||||||
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, NULL, NULL);
|
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, NULL, NULL);
|
||||||
|
|
||||||
furi_hal_ibutton->callback = NULL;
|
furi_hal_ibutton->callback = NULL;
|
||||||
|
|||||||
@ -1,9 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stm32wbxx_ll_lptim.h>
|
#include <stm32wbxx_ll_lptim.h>
|
||||||
#include <stm32wbxx_ll_bus.h>
|
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
#include <stdint.h>
|
#include <stm32wbxx_ll_bus.h>
|
||||||
|
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
// Timer used for tickless idle
|
// Timer used for tickless idle
|
||||||
#define FURI_HAL_IDLE_TIMER_MAX 0xFFFF
|
#define FURI_HAL_IDLE_TIMER_MAX 0xFFFF
|
||||||
@ -11,6 +12,7 @@
|
|||||||
#define FURI_HAL_IDLE_TIMER_IRQ LPTIM1_IRQn
|
#define FURI_HAL_IDLE_TIMER_IRQ LPTIM1_IRQn
|
||||||
|
|
||||||
static inline void furi_hal_idle_timer_init() {
|
static inline void furi_hal_idle_timer_init() {
|
||||||
|
furi_hal_bus_enable(FuriHalBusLPTIM1);
|
||||||
// Configure clock source
|
// Configure clock source
|
||||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
|
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_LSE);
|
||||||
// There is a theoretical possibility that we need it
|
// There is a theoretical possibility that we need it
|
||||||
@ -41,7 +43,7 @@ static inline void furi_hal_idle_timer_start(uint32_t count) {
|
|||||||
static inline void furi_hal_idle_timer_reset() {
|
static inline void furi_hal_idle_timer_reset() {
|
||||||
// Hard reset timer
|
// Hard reset timer
|
||||||
// THE ONLY RELIABLE WAY to stop it according to errata
|
// 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
|
// Prevent IRQ handler call
|
||||||
NVIC_ClearPendingIRQ(FURI_HAL_IDLE_TIMER_IRQ);
|
NVIC_ClearPendingIRQ(FURI_HAL_IDLE_TIMER_IRQ);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,11 @@
|
|||||||
#include <furi_hal_infrared.h>
|
#include <furi_hal_infrared.h>
|
||||||
#include <core/check.h>
|
|
||||||
#include "stm32wbxx_ll_dma.h"
|
|
||||||
#include <furi_hal_interrupt.h>
|
#include <furi_hal_interrupt.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
#include <stm32wbxx_ll_tim.h>
|
||||||
#include <stm32wbxx_ll_gpio.h>
|
#include <stm32wbxx_ll_dma.h>
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
@ -27,13 +24,23 @@
|
|||||||
(TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */
|
(TIM_CCMR2_OC3PE | LL_TIM_OCMODE_FORCED_INACTIVE) /* Space time - force low */
|
||||||
|
|
||||||
/* DMA Channels definition */
|
/* DMA Channels definition */
|
||||||
#define IR_DMA DMA2
|
#define INFRARED_DMA DMA2
|
||||||
#define IR_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
|
#define INFRARED_DMA_CH1_CHANNEL LL_DMA_CHANNEL_1
|
||||||
#define IR_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
|
#define INFRARED_DMA_CH2_CHANNEL LL_DMA_CHANNEL_2
|
||||||
#define IR_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
|
#define INFRARED_DMA_CH1_IRQ FuriHalInterruptIdDma2Ch1
|
||||||
#define IR_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2
|
#define INFRARED_DMA_CH2_IRQ FuriHalInterruptIdDma2Ch2
|
||||||
#define IR_DMA_CH1_DEF IR_DMA, IR_DMA_CH1_CHANNEL
|
#define INFRARED_DMA_CH1_DEF INFRARED_DMA, INFRARED_DMA_CH1_CHANNEL
|
||||||
#define IR_DMA_CH2_DEF IR_DMA, IR_DMA_CH2_CHANNEL
|
#define INFRARED_DMA_CH2_DEF INFRARED_DMA, INFRARED_DMA_CH2_CHANNEL
|
||||||
|
|
||||||
|
/* Timers definition */
|
||||||
|
#define INFRARED_RX_TIMER TIM2
|
||||||
|
#define INFRARED_DMA_TIMER TIM1
|
||||||
|
#define INFRARED_RX_TIMER_BUS FuriHalBusTIM2
|
||||||
|
#define INFRARED_DMA_TIMER_BUS FuriHalBusTIM1
|
||||||
|
|
||||||
|
/* Misc */
|
||||||
|
#define INFRARED_RX_GPIO_ALT GpioAltFn1TIM2
|
||||||
|
#define INFRARED_RX_IRQ FuriHalInterruptIdTIM2
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FuriHalInfraredRxCaptureCallback capture_callback;
|
FuriHalInfraredRxCaptureCallback capture_callback;
|
||||||
@ -91,8 +98,8 @@ static void furi_hal_infrared_tim_rx_isr() {
|
|||||||
static uint32_t previous_captured_ch2 = 0;
|
static uint32_t previous_captured_ch2 = 0;
|
||||||
|
|
||||||
/* Timeout */
|
/* Timeout */
|
||||||
if(LL_TIM_IsActiveFlag_CC3(TIM2)) {
|
if(LL_TIM_IsActiveFlag_CC3(INFRARED_RX_TIMER)) {
|
||||||
LL_TIM_ClearFlag_CC3(TIM2);
|
LL_TIM_ClearFlag_CC3(INFRARED_RX_TIMER);
|
||||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||||
|
|
||||||
/* Timers CNT register starts to counting from 0 to ARR, but it is
|
/* Timers CNT register starts to counting from 0 to ARR, but it is
|
||||||
@ -108,13 +115,13 @@ static void furi_hal_infrared_tim_rx_isr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Rising Edge */
|
/* Rising Edge */
|
||||||
if(LL_TIM_IsActiveFlag_CC1(TIM2)) {
|
if(LL_TIM_IsActiveFlag_CC1(INFRARED_RX_TIMER)) {
|
||||||
LL_TIM_ClearFlag_CC1(TIM2);
|
LL_TIM_ClearFlag_CC1(INFRARED_RX_TIMER);
|
||||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||||
|
|
||||||
if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC1S)) {
|
if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC1S)) {
|
||||||
/* Low pin level is a Mark state of INFRARED signal. Invert level for further processing. */
|
/* Low pin level is a Mark state of INFRARED signal. Invert level for further processing. */
|
||||||
uint32_t duration = LL_TIM_IC_GetCaptureCH1(TIM2) - previous_captured_ch2;
|
uint32_t duration = LL_TIM_IC_GetCaptureCH1(INFRARED_RX_TIMER) - previous_captured_ch2;
|
||||||
if(infrared_tim_rx.capture_callback)
|
if(infrared_tim_rx.capture_callback)
|
||||||
infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 1, duration);
|
infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 1, duration);
|
||||||
} else {
|
} else {
|
||||||
@ -123,13 +130,13 @@ static void furi_hal_infrared_tim_rx_isr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Falling Edge */
|
/* Falling Edge */
|
||||||
if(LL_TIM_IsActiveFlag_CC2(TIM2)) {
|
if(LL_TIM_IsActiveFlag_CC2(INFRARED_RX_TIMER)) {
|
||||||
LL_TIM_ClearFlag_CC2(TIM2);
|
LL_TIM_ClearFlag_CC2(INFRARED_RX_TIMER);
|
||||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||||
|
|
||||||
if(READ_BIT(TIM2->CCMR1, TIM_CCMR1_CC2S)) {
|
if(READ_BIT(INFRARED_RX_TIMER->CCMR1, TIM_CCMR1_CC2S)) {
|
||||||
/* High pin level is a Space state of INFRARED signal. Invert level for further processing. */
|
/* High pin level is a Space state of INFRARED signal. Invert level for further processing. */
|
||||||
uint32_t duration = LL_TIM_IC_GetCaptureCH2(TIM2);
|
uint32_t duration = LL_TIM_IC_GetCaptureCH2(INFRARED_RX_TIMER);
|
||||||
previous_captured_ch2 = duration;
|
previous_captured_ch2 = duration;
|
||||||
if(infrared_tim_rx.capture_callback)
|
if(infrared_tim_rx.capture_callback)
|
||||||
infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 0, duration);
|
infrared_tim_rx.capture_callback(infrared_tim_rx.capture_context, 0, duration);
|
||||||
@ -143,62 +150,66 @@ void furi_hal_infrared_async_rx_start(void) {
|
|||||||
furi_assert(furi_hal_infrared_state == InfraredStateIdle);
|
furi_assert(furi_hal_infrared_state == InfraredStateIdle);
|
||||||
|
|
||||||
furi_hal_gpio_init_ex(
|
furi_hal_gpio_init_ex(
|
||||||
&gpio_infrared_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2);
|
&gpio_infrared_rx,
|
||||||
|
GpioModeAltFunctionPushPull,
|
||||||
|
GpioPullNo,
|
||||||
|
GpioSpeedLow,
|
||||||
|
INFRARED_RX_GPIO_ALT);
|
||||||
|
|
||||||
|
furi_hal_bus_enable(INFRARED_RX_TIMER_BUS);
|
||||||
|
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
TIM_InitStruct.Prescaler = 64 - 1;
|
TIM_InitStruct.Prescaler = 64 - 1;
|
||||||
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
|
||||||
TIM_InitStruct.Autoreload = 0x7FFFFFFE;
|
TIM_InitStruct.Autoreload = 0x7FFFFFFE;
|
||||||
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
TIM_InitStruct.ClockDivision = LL_TIM_CLOCKDIVISION_DIV1;
|
||||||
LL_TIM_Init(TIM2, &TIM_InitStruct);
|
LL_TIM_Init(INFRARED_RX_TIMER, &TIM_InitStruct);
|
||||||
|
|
||||||
LL_TIM_SetClockSource(TIM2, LL_TIM_CLOCKSOURCE_INTERNAL);
|
LL_TIM_SetClockSource(INFRARED_RX_TIMER, LL_TIM_CLOCKSOURCE_INTERNAL);
|
||||||
LL_TIM_DisableARRPreload(TIM2);
|
LL_TIM_DisableARRPreload(INFRARED_RX_TIMER);
|
||||||
LL_TIM_SetTriggerInput(TIM2, LL_TIM_TS_TI1FP1);
|
LL_TIM_SetTriggerInput(INFRARED_RX_TIMER, LL_TIM_TS_TI1FP1);
|
||||||
LL_TIM_SetSlaveMode(TIM2, LL_TIM_SLAVEMODE_RESET);
|
LL_TIM_SetSlaveMode(INFRARED_RX_TIMER, LL_TIM_SLAVEMODE_RESET);
|
||||||
LL_TIM_CC_DisableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
LL_TIM_CC_DisableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2);
|
||||||
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
|
LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV1);
|
||||||
LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING);
|
LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_IC_POLARITY_FALLING);
|
||||||
LL_TIM_DisableIT_TRIG(TIM2);
|
LL_TIM_DisableIT_TRIG(INFRARED_RX_TIMER);
|
||||||
LL_TIM_DisableDMAReq_TRIG(TIM2);
|
LL_TIM_DisableDMAReq_TRIG(INFRARED_RX_TIMER);
|
||||||
LL_TIM_SetTriggerOutput(TIM2, LL_TIM_TRGO_RESET);
|
LL_TIM_SetTriggerOutput(INFRARED_RX_TIMER, LL_TIM_TRGO_RESET);
|
||||||
LL_TIM_EnableMasterSlaveMode(TIM2);
|
LL_TIM_EnableMasterSlaveMode(INFRARED_RX_TIMER);
|
||||||
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ACTIVEINPUT_DIRECTTI);
|
||||||
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
|
LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_ICPSC_DIV1);
|
||||||
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
|
LL_TIM_IC_SetFilter(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_FILTER_FDIV1);
|
||||||
LL_TIM_IC_SetPolarity(TIM2, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
|
LL_TIM_IC_SetPolarity(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_IC_POLARITY_RISING);
|
||||||
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
|
LL_TIM_IC_SetActiveInput(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
|
||||||
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
|
LL_TIM_IC_SetPrescaler(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_infrared_tim_rx_isr, NULL);
|
furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, furi_hal_infrared_tim_rx_isr, NULL);
|
||||||
furi_hal_infrared_state = InfraredStateAsyncRx;
|
furi_hal_infrared_state = InfraredStateAsyncRx;
|
||||||
|
|
||||||
LL_TIM_EnableIT_CC1(TIM2);
|
LL_TIM_EnableIT_CC1(INFRARED_RX_TIMER);
|
||||||
LL_TIM_EnableIT_CC2(TIM2);
|
LL_TIM_EnableIT_CC2(INFRARED_RX_TIMER);
|
||||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH1);
|
LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH1);
|
||||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH2);
|
LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH2);
|
||||||
|
|
||||||
LL_TIM_SetCounter(TIM2, 0);
|
LL_TIM_SetCounter(INFRARED_RX_TIMER, 0);
|
||||||
LL_TIM_EnableCounter(TIM2);
|
LL_TIM_EnableCounter(INFRARED_RX_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_infrared_async_rx_stop(void) {
|
void furi_hal_infrared_async_rx_stop(void) {
|
||||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
|
furi_hal_bus_disable(INFRARED_RX_TIMER_BUS);
|
||||||
LL_TIM_DeInit(TIM2);
|
furi_hal_interrupt_set_isr(INFRARED_RX_IRQ, NULL, NULL);
|
||||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
|
|
||||||
furi_hal_infrared_state = InfraredStateIdle;
|
furi_hal_infrared_state = InfraredStateIdle;
|
||||||
|
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us) {
|
void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us) {
|
||||||
LL_TIM_OC_SetCompareCH3(TIM2, timeout_us);
|
LL_TIM_OC_SetCompareCH3(INFRARED_RX_TIMER, timeout_us);
|
||||||
LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);
|
LL_TIM_OC_SetMode(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);
|
||||||
LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3);
|
LL_TIM_CC_EnableChannel(INFRARED_RX_TIMER, LL_TIM_CHANNEL_CH3);
|
||||||
LL_TIM_EnableIT_CC3(TIM2);
|
LL_TIM_EnableIT_CC3(INFRARED_RX_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool furi_hal_infrared_is_busy(void) {
|
bool furi_hal_infrared_is_busy(void) {
|
||||||
@ -220,16 +231,16 @@ void furi_hal_infrared_async_rx_set_timeout_isr_callback(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_infrared_tx_dma_terminate(void) {
|
static void furi_hal_infrared_tx_dma_terminate(void) {
|
||||||
LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF);
|
LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF);
|
||||||
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
|
LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||||
LL_DMA_DisableIT_TC(IR_DMA_CH2_DEF);
|
LL_DMA_DisableIT_TC(INFRARED_DMA_CH2_DEF);
|
||||||
|
|
||||||
furi_assert(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress);
|
furi_assert(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress);
|
||||||
|
|
||||||
LL_DMA_DisableIT_TC(IR_DMA_CH1_DEF);
|
LL_DMA_DisableIT_TC(INFRARED_DMA_CH1_DEF);
|
||||||
LL_DMA_DisableChannel(IR_DMA_CH2_DEF);
|
LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF);
|
||||||
LL_DMA_DisableChannel(IR_DMA_CH1_DEF);
|
LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF);
|
||||||
LL_TIM_DisableCounter(TIM1);
|
LL_TIM_DisableCounter(INFRARED_DMA_TIMER);
|
||||||
FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore);
|
FuriStatus status = furi_semaphore_release(infrared_tim_tx.stop_semaphore);
|
||||||
furi_check(status == FuriStatusOk);
|
furi_check(status == FuriStatusOk);
|
||||||
furi_hal_infrared_state = InfraredStateAsyncTxStopped;
|
furi_hal_infrared_state = InfraredStateAsyncTxStopped;
|
||||||
@ -237,7 +248,7 @@ static void furi_hal_infrared_tx_dma_terminate(void) {
|
|||||||
|
|
||||||
static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
|
static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
|
||||||
uint8_t buf_num = 0;
|
uint8_t buf_num = 0;
|
||||||
uint32_t buffer_adr = LL_DMA_GetMemoryAddress(IR_DMA_CH2_DEF);
|
uint32_t buffer_adr = LL_DMA_GetMemoryAddress(INFRARED_DMA_CH2_DEF);
|
||||||
if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[0].data) {
|
if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[0].data) {
|
||||||
buf_num = 0;
|
buf_num = 0;
|
||||||
} else if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[1].data) {
|
} else if(buffer_adr == (uint32_t)infrared_tim_tx.buffer[1].data) {
|
||||||
@ -249,13 +260,13 @@ static uint8_t furi_hal_infrared_get_current_dma_tx_buffer(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_infrared_tx_dma_polarity_isr() {
|
static void furi_hal_infrared_tx_dma_polarity_isr() {
|
||||||
#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
||||||
if(LL_DMA_IsActiveFlag_TE1(IR_DMA)) {
|
if(LL_DMA_IsActiveFlag_TE1(INFRARED_DMA)) {
|
||||||
LL_DMA_ClearFlag_TE1(IR_DMA);
|
LL_DMA_ClearFlag_TE1(INFRARED_DMA);
|
||||||
furi_crash(NULL);
|
furi_crash(NULL);
|
||||||
}
|
}
|
||||||
if(LL_DMA_IsActiveFlag_TC1(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH1_DEF)) {
|
if(LL_DMA_IsActiveFlag_TC1(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH1_DEF)) {
|
||||||
LL_DMA_ClearFlag_TC1(IR_DMA);
|
LL_DMA_ClearFlag_TC1(INFRARED_DMA);
|
||||||
|
|
||||||
furi_check(
|
furi_check(
|
||||||
(furi_hal_infrared_state == InfraredStateAsyncTx) ||
|
(furi_hal_infrared_state == InfraredStateAsyncTx) ||
|
||||||
@ -271,23 +282,23 @@ static void furi_hal_infrared_tx_dma_polarity_isr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_infrared_tx_dma_isr() {
|
static void furi_hal_infrared_tx_dma_isr() {
|
||||||
#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
||||||
if(LL_DMA_IsActiveFlag_TE2(IR_DMA)) {
|
if(LL_DMA_IsActiveFlag_TE2(INFRARED_DMA)) {
|
||||||
LL_DMA_ClearFlag_TE2(IR_DMA);
|
LL_DMA_ClearFlag_TE2(INFRARED_DMA);
|
||||||
furi_crash(NULL);
|
furi_crash(NULL);
|
||||||
}
|
}
|
||||||
if(LL_DMA_IsActiveFlag_HT2(IR_DMA) && LL_DMA_IsEnabledIT_HT(IR_DMA_CH2_DEF)) {
|
if(LL_DMA_IsActiveFlag_HT2(INFRARED_DMA) && LL_DMA_IsEnabledIT_HT(INFRARED_DMA_CH2_DEF)) {
|
||||||
LL_DMA_ClearFlag_HT2(IR_DMA);
|
LL_DMA_ClearFlag_HT2(INFRARED_DMA);
|
||||||
uint8_t buf_num = furi_hal_infrared_get_current_dma_tx_buffer();
|
uint8_t buf_num = furi_hal_infrared_get_current_dma_tx_buffer();
|
||||||
uint8_t next_buf_num = !buf_num;
|
uint8_t next_buf_num = !buf_num;
|
||||||
if(infrared_tim_tx.buffer[buf_num].last_packet_end) {
|
if(infrared_tim_tx.buffer[buf_num].last_packet_end) {
|
||||||
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
|
LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||||
} else if(
|
} else if(
|
||||||
!infrared_tim_tx.buffer[buf_num].packet_end ||
|
!infrared_tim_tx.buffer[buf_num].packet_end ||
|
||||||
(furi_hal_infrared_state == InfraredStateAsyncTx)) {
|
(furi_hal_infrared_state == InfraredStateAsyncTx)) {
|
||||||
furi_hal_infrared_tx_fill_buffer(next_buf_num, 0);
|
furi_hal_infrared_tx_fill_buffer(next_buf_num, 0);
|
||||||
if(infrared_tim_tx.buffer[next_buf_num].last_packet_end) {
|
if(infrared_tim_tx.buffer[next_buf_num].last_packet_end) {
|
||||||
LL_DMA_DisableIT_HT(IR_DMA_CH2_DEF);
|
LL_DMA_DisableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||||
}
|
}
|
||||||
} else if(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) {
|
} else if(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) {
|
||||||
/* fallthrough */
|
/* fallthrough */
|
||||||
@ -295,8 +306,8 @@ static void furi_hal_infrared_tx_dma_isr() {
|
|||||||
furi_crash(NULL);
|
furi_crash(NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(LL_DMA_IsActiveFlag_TC2(IR_DMA) && LL_DMA_IsEnabledIT_TC(IR_DMA_CH2_DEF)) {
|
if(LL_DMA_IsActiveFlag_TC2(INFRARED_DMA) && LL_DMA_IsEnabledIT_TC(INFRARED_DMA_CH2_DEF)) {
|
||||||
LL_DMA_ClearFlag_TC2(IR_DMA);
|
LL_DMA_ClearFlag_TC2(INFRARED_DMA);
|
||||||
furi_check(
|
furi_check(
|
||||||
(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress) ||
|
(furi_hal_infrared_state == InfraredStateAsyncTxStopInProgress) ||
|
||||||
(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) ||
|
(furi_hal_infrared_state == InfraredStateAsyncTxStopReq) ||
|
||||||
@ -328,37 +339,40 @@ static void furi_hal_infrared_tx_dma_isr() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) {
|
static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) {
|
||||||
LL_TIM_DisableCounter(TIM1);
|
LL_TIM_DisableCounter(INFRARED_DMA_TIMER);
|
||||||
LL_TIM_SetRepetitionCounter(TIM1, 0);
|
LL_TIM_SetRepetitionCounter(INFRARED_DMA_TIMER, 0);
|
||||||
LL_TIM_SetCounter(TIM1, 0);
|
LL_TIM_SetCounter(INFRARED_DMA_TIMER, 0);
|
||||||
LL_TIM_SetPrescaler(TIM1, 0);
|
LL_TIM_SetPrescaler(INFRARED_DMA_TIMER, 0);
|
||||||
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(INFRARED_DMA_TIMER, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_EnableARRPreload(TIM1);
|
LL_TIM_EnableARRPreload(INFRARED_DMA_TIMER);
|
||||||
LL_TIM_SetAutoReload(
|
LL_TIM_SetAutoReload(
|
||||||
TIM1, __LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(TIM1), freq));
|
INFRARED_DMA_TIMER,
|
||||||
|
__LL_TIM_CALC_ARR(SystemCoreClock, LL_TIM_GetPrescaler(INFRARED_DMA_TIMER), freq));
|
||||||
#if defined INFRARED_TX_DEBUG
|
#if defined INFRARED_TX_DEBUG
|
||||||
LL_TIM_OC_SetCompareCH1(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle)));
|
LL_TIM_OC_SetCompareCH1(
|
||||||
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH1);
|
INFRARED_DMA_TIMER, ((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle)));
|
||||||
|
LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1);
|
||||||
/* LL_TIM_OCMODE_PWM2 set by DMA */
|
/* LL_TIM_OCMODE_PWM2 set by DMA */
|
||||||
LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE);
|
LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1, LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||||
LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH);
|
LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N, LL_TIM_OCPOLARITY_HIGH);
|
||||||
LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH1);
|
LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1);
|
||||||
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH1N);
|
LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH1N);
|
||||||
LL_TIM_DisableIT_CC1(TIM1);
|
LL_TIM_DisableIT_CC1(INFRARED_DMA_TIMER);
|
||||||
#else
|
#else
|
||||||
LL_TIM_OC_SetCompareCH3(TIM1, ((LL_TIM_GetAutoReload(TIM1) + 1) * (1 - duty_cycle)));
|
LL_TIM_OC_SetCompareCH3(
|
||||||
LL_TIM_OC_EnablePreload(TIM1, LL_TIM_CHANNEL_CH3);
|
INFRARED_DMA_TIMER, ((LL_TIM_GetAutoReload(INFRARED_DMA_TIMER) + 1) * (1 - duty_cycle)));
|
||||||
|
LL_TIM_OC_EnablePreload(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3);
|
||||||
/* LL_TIM_OCMODE_PWM2 set by DMA */
|
/* LL_TIM_OCMODE_PWM2 set by DMA */
|
||||||
LL_TIM_OC_SetMode(TIM1, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE);
|
LL_TIM_OC_SetMode(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_FORCED_INACTIVE);
|
||||||
LL_TIM_OC_SetPolarity(TIM1, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH);
|
LL_TIM_OC_SetPolarity(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N, LL_TIM_OCPOLARITY_HIGH);
|
||||||
LL_TIM_OC_DisableFast(TIM1, LL_TIM_CHANNEL_CH3);
|
LL_TIM_OC_DisableFast(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3);
|
||||||
LL_TIM_CC_EnableChannel(TIM1, LL_TIM_CHANNEL_CH3N);
|
LL_TIM_CC_EnableChannel(INFRARED_DMA_TIMER, LL_TIM_CHANNEL_CH3N);
|
||||||
LL_TIM_DisableIT_CC3(TIM1);
|
LL_TIM_DisableIT_CC3(INFRARED_DMA_TIMER);
|
||||||
#endif
|
#endif
|
||||||
LL_TIM_DisableMasterSlaveMode(TIM1);
|
LL_TIM_DisableMasterSlaveMode(INFRARED_DMA_TIMER);
|
||||||
LL_TIM_EnableAllOutputs(TIM1);
|
LL_TIM_EnableAllOutputs(INFRARED_DMA_TIMER);
|
||||||
LL_TIM_DisableIT_UPDATE(TIM1);
|
LL_TIM_DisableIT_UPDATE(INFRARED_DMA_TIMER);
|
||||||
LL_TIM_EnableDMAReq_UPDATE(TIM1);
|
LL_TIM_EnableDMAReq_UPDATE(INFRARED_DMA_TIMER);
|
||||||
|
|
||||||
NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
NVIC_SetPriority(TIM1_UP_TIM16_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
|
||||||
NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
|
NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
|
||||||
@ -367,9 +381,9 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc
|
|||||||
static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
|
static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
|
||||||
LL_DMA_InitTypeDef dma_config = {0};
|
LL_DMA_InitTypeDef dma_config = {0};
|
||||||
#if defined INFRARED_TX_DEBUG
|
#if defined INFRARED_TX_DEBUG
|
||||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1);
|
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR1);
|
||||||
#else
|
#else
|
||||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR2);
|
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->CCMR2);
|
||||||
#endif
|
#endif
|
||||||
dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
|
dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
|
||||||
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||||
@ -382,24 +396,25 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
|
|||||||
dma_config.NbData = 0;
|
dma_config.NbData = 0;
|
||||||
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
|
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
|
||||||
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
|
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
|
||||||
LL_DMA_Init(IR_DMA_CH1_DEF, &dma_config);
|
LL_DMA_Init(INFRARED_DMA_CH1_DEF, &dma_config);
|
||||||
|
|
||||||
#if IR_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
#if INFRARED_DMA_CH1_CHANNEL == LL_DMA_CHANNEL_1
|
||||||
LL_DMA_ClearFlag_TE1(IR_DMA);
|
LL_DMA_ClearFlag_TE1(INFRARED_DMA);
|
||||||
LL_DMA_ClearFlag_TC1(IR_DMA);
|
LL_DMA_ClearFlag_TC1(INFRARED_DMA);
|
||||||
#else
|
#else
|
||||||
#error Update this code. Would you kindly?
|
#error Update this code. Would you kindly?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LL_DMA_EnableIT_TE(IR_DMA_CH1_DEF);
|
LL_DMA_EnableIT_TE(INFRARED_DMA_CH1_DEF);
|
||||||
LL_DMA_EnableIT_TC(IR_DMA_CH1_DEF);
|
LL_DMA_EnableIT_TC(INFRARED_DMA_CH1_DEF);
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr_ex(IR_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
|
furi_hal_interrupt_set_isr_ex(
|
||||||
|
INFRARED_DMA_CH1_IRQ, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
|
static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
|
||||||
LL_DMA_InitTypeDef dma_config = {0};
|
LL_DMA_InitTypeDef dma_config = {0};
|
||||||
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->RCR);
|
dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (INFRARED_DMA_TIMER->RCR);
|
||||||
dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
|
dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
|
||||||
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
dma_config.Direction = LL_DMA_DIRECTION_MEMORY_TO_PERIPH;
|
||||||
dma_config.Mode = LL_DMA_MODE_NORMAL;
|
dma_config.Mode = LL_DMA_MODE_NORMAL;
|
||||||
@ -410,21 +425,21 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
|
|||||||
dma_config.NbData = 0;
|
dma_config.NbData = 0;
|
||||||
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
|
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
|
||||||
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
|
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
|
||||||
LL_DMA_Init(IR_DMA_CH2_DEF, &dma_config);
|
LL_DMA_Init(INFRARED_DMA_CH2_DEF, &dma_config);
|
||||||
|
|
||||||
#if IR_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
#if INFRARED_DMA_CH2_CHANNEL == LL_DMA_CHANNEL_2
|
||||||
LL_DMA_ClearFlag_TC2(IR_DMA);
|
LL_DMA_ClearFlag_TC2(INFRARED_DMA);
|
||||||
LL_DMA_ClearFlag_HT2(IR_DMA);
|
LL_DMA_ClearFlag_HT2(INFRARED_DMA);
|
||||||
LL_DMA_ClearFlag_TE2(IR_DMA);
|
LL_DMA_ClearFlag_TE2(INFRARED_DMA);
|
||||||
#else
|
#else
|
||||||
#error Update this code. Would you kindly?
|
#error Update this code. Would you kindly?
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
LL_DMA_EnableIT_TC(IR_DMA_CH2_DEF);
|
LL_DMA_EnableIT_TC(INFRARED_DMA_CH2_DEF);
|
||||||
LL_DMA_EnableIT_HT(IR_DMA_CH2_DEF);
|
LL_DMA_EnableIT_HT(INFRARED_DMA_CH2_DEF);
|
||||||
LL_DMA_EnableIT_TE(IR_DMA_CH2_DEF);
|
LL_DMA_EnableIT_TE(INFRARED_DMA_CH2_DEF);
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr_ex(IR_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL);
|
furi_hal_interrupt_set_isr_ex(INFRARED_DMA_CH2_IRQ, 5, furi_hal_infrared_tx_dma_isr, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) {
|
static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) {
|
||||||
@ -526,14 +541,14 @@ static void furi_hal_infrared_tx_dma_set_polarity(uint8_t buf_num, uint8_t polar
|
|||||||
furi_assert(buffer->polarity != NULL);
|
furi_assert(buffer->polarity != NULL);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH1_DEF);
|
bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH1_DEF);
|
||||||
if(channel_enabled) {
|
if(channel_enabled) {
|
||||||
LL_DMA_DisableChannel(IR_DMA_CH1_DEF);
|
LL_DMA_DisableChannel(INFRARED_DMA_CH1_DEF);
|
||||||
}
|
}
|
||||||
LL_DMA_SetMemoryAddress(IR_DMA_CH1_DEF, (uint32_t)buffer->polarity);
|
LL_DMA_SetMemoryAddress(INFRARED_DMA_CH1_DEF, (uint32_t)buffer->polarity);
|
||||||
LL_DMA_SetDataLength(IR_DMA_CH1_DEF, buffer->size + polarity_shift);
|
LL_DMA_SetDataLength(INFRARED_DMA_CH1_DEF, buffer->size + polarity_shift);
|
||||||
if(channel_enabled) {
|
if(channel_enabled) {
|
||||||
LL_DMA_EnableChannel(IR_DMA_CH1_DEF);
|
LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF);
|
||||||
}
|
}
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
}
|
}
|
||||||
@ -546,14 +561,14 @@ static void furi_hal_infrared_tx_dma_set_buffer(uint8_t buf_num) {
|
|||||||
|
|
||||||
/* non-circular mode requires disabled channel before setup */
|
/* non-circular mode requires disabled channel before setup */
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
bool channel_enabled = LL_DMA_IsEnabledChannel(IR_DMA_CH2_DEF);
|
bool channel_enabled = LL_DMA_IsEnabledChannel(INFRARED_DMA_CH2_DEF);
|
||||||
if(channel_enabled) {
|
if(channel_enabled) {
|
||||||
LL_DMA_DisableChannel(IR_DMA_CH2_DEF);
|
LL_DMA_DisableChannel(INFRARED_DMA_CH2_DEF);
|
||||||
}
|
}
|
||||||
LL_DMA_SetMemoryAddress(IR_DMA_CH2_DEF, (uint32_t)buffer->data);
|
LL_DMA_SetMemoryAddress(INFRARED_DMA_CH2_DEF, (uint32_t)buffer->data);
|
||||||
LL_DMA_SetDataLength(IR_DMA_CH2_DEF, buffer->size);
|
LL_DMA_SetDataLength(INFRARED_DMA_CH2_DEF, buffer->size);
|
||||||
if(channel_enabled) {
|
if(channel_enabled) {
|
||||||
LL_DMA_EnableChannel(IR_DMA_CH2_DEF);
|
LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF);
|
||||||
}
|
}
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
}
|
}
|
||||||
@ -564,9 +579,10 @@ static void furi_hal_infrared_async_tx_free_resources(void) {
|
|||||||
(furi_hal_infrared_state == InfraredStateAsyncTxStopped));
|
(furi_hal_infrared_state == InfraredStateAsyncTxStopped));
|
||||||
|
|
||||||
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
furi_hal_gpio_init(&gpio_infrared_tx, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||||
furi_hal_interrupt_set_isr(IR_DMA_CH1_IRQ, NULL, NULL);
|
furi_hal_interrupt_set_isr(INFRARED_DMA_CH1_IRQ, NULL, NULL);
|
||||||
furi_hal_interrupt_set_isr(IR_DMA_CH2_IRQ, NULL, NULL);
|
furi_hal_interrupt_set_isr(INFRARED_DMA_CH2_IRQ, NULL, NULL);
|
||||||
LL_TIM_DeInit(TIM1);
|
|
||||||
|
furi_hal_bus_disable(INFRARED_DMA_TIMER_BUS);
|
||||||
|
|
||||||
furi_semaphore_free(infrared_tim_tx.stop_semaphore);
|
furi_semaphore_free(infrared_tim_tx.stop_semaphore);
|
||||||
free(infrared_tim_tx.buffer[0].data);
|
free(infrared_tim_tx.buffer[0].data);
|
||||||
@ -607,6 +623,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
|||||||
|
|
||||||
furi_hal_infrared_tx_fill_buffer(0, INFRARED_POLARITY_SHIFT);
|
furi_hal_infrared_tx_fill_buffer(0, INFRARED_POLARITY_SHIFT);
|
||||||
|
|
||||||
|
furi_hal_bus_enable(INFRARED_DMA_TIMER_BUS);
|
||||||
|
|
||||||
furi_hal_infrared_configure_tim_pwm_tx(freq, duty_cycle);
|
furi_hal_infrared_configure_tim_pwm_tx(freq, duty_cycle);
|
||||||
furi_hal_infrared_configure_tim_cmgr2_dma_tx();
|
furi_hal_infrared_configure_tim_cmgr2_dma_tx();
|
||||||
furi_hal_infrared_configure_tim_rcr_dma_tx();
|
furi_hal_infrared_configure_tim_rcr_dma_tx();
|
||||||
@ -615,11 +633,11 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
|||||||
|
|
||||||
furi_hal_infrared_state = InfraredStateAsyncTx;
|
furi_hal_infrared_state = InfraredStateAsyncTx;
|
||||||
|
|
||||||
LL_TIM_ClearFlag_UPDATE(TIM1);
|
LL_TIM_ClearFlag_UPDATE(INFRARED_DMA_TIMER);
|
||||||
LL_DMA_EnableChannel(IR_DMA_CH1_DEF);
|
LL_DMA_EnableChannel(INFRARED_DMA_CH1_DEF);
|
||||||
LL_DMA_EnableChannel(IR_DMA_CH2_DEF);
|
LL_DMA_EnableChannel(INFRARED_DMA_CH2_DEF);
|
||||||
furi_delay_us(5);
|
furi_delay_us(5);
|
||||||
LL_TIM_GenerateEvent_UPDATE(TIM1); /* DMA -> TIMx_RCR */
|
LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* DMA -> TIMx_RCR */
|
||||||
furi_delay_us(5);
|
furi_delay_us(5);
|
||||||
LL_GPIO_ResetOutputPin(
|
LL_GPIO_ResetOutputPin(
|
||||||
gpio_infrared_tx.port, gpio_infrared_tx.pin); /* when disable it prevents false pulse */
|
gpio_infrared_tx.port, gpio_infrared_tx.pin); /* when disable it prevents false pulse */
|
||||||
@ -627,8 +645,8 @@ void furi_hal_infrared_async_tx_start(uint32_t freq, float duty_cycle) {
|
|||||||
&gpio_infrared_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1);
|
&gpio_infrared_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */
|
LL_TIM_GenerateEvent_UPDATE(INFRARED_DMA_TIMER); /* TIMx_RCR -> Repetition counter */
|
||||||
LL_TIM_EnableCounter(TIM1);
|
LL_TIM_EnableCounter(INFRARED_DMA_TIMER);
|
||||||
FURI_CRITICAL_EXIT();
|
FURI_CRITICAL_EXIT();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
#include <furi_hal_pwm.h>
|
#include <furi_hal_pwm.h>
|
||||||
#include <core/check.h>
|
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
#include <stm32wbxx_ll_tim.h>
|
||||||
#include <stm32wbxx_ll_lptim.h>
|
#include <stm32wbxx_ll_lptim.h>
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
@ -29,9 +28,7 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty)
|
|||||||
GpioSpeedVeryHigh,
|
GpioSpeedVeryHigh,
|
||||||
GpioAltFn1TIM1);
|
GpioAltFn1TIM1);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FuriHalBusTIM1);
|
||||||
LL_TIM_DeInit(TIM1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(TIM1, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetRepetitionCounter(TIM1, 0);
|
LL_TIM_SetRepetitionCounter(TIM1, 0);
|
||||||
@ -58,9 +55,7 @@ void furi_hal_pwm_start(FuriHalPwmOutputId channel, uint32_t freq, uint8_t duty)
|
|||||||
GpioSpeedVeryHigh,
|
GpioSpeedVeryHigh,
|
||||||
GpioAltFn14LPTIM2);
|
GpioAltFn14LPTIM2);
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FuriHalBusLPTIM2);
|
||||||
LL_LPTIM_DeInit(LPTIM2);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
LL_LPTIM_SetUpdateMode(LPTIM2, LL_LPTIM_UPDATE_MODE_ENDOFPERIOD);
|
LL_LPTIM_SetUpdateMode(LPTIM2, LL_LPTIM_UPDATE_MODE_ENDOFPERIOD);
|
||||||
LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK1);
|
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) {
|
void furi_hal_pwm_stop(FuriHalPwmOutputId channel) {
|
||||||
if(channel == FuriHalPwmOutputIdTim1PA7) {
|
if(channel == FuriHalPwmOutputIdTim1PA7) {
|
||||||
furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
|
furi_hal_gpio_init_simple(&gpio_ext_pa7, GpioModeAnalog);
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusTIM1);
|
||||||
LL_TIM_DeInit(TIM1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
} else if(channel == FuriHalPwmOutputIdLptim2PA4) {
|
} else if(channel == FuriHalPwmOutputIdLptim2PA4) {
|
||||||
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog);
|
furi_hal_gpio_init_simple(&gpio_ext_pa4, GpioModeAnalog);
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusLPTIM2);
|
||||||
LL_LPTIM_DeInit(LPTIM2);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
#include <furi_hal_random.h>
|
#include <furi_hal_random.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <furi_hal.h>
|
|
||||||
|
|
||||||
#include <stm32wbxx_ll_rng.h>
|
#include <stm32wbxx_ll_rng.h>
|
||||||
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
#include <stm32wbxx_ll_hsem.h>
|
#include <stm32wbxx_ll_hsem.h>
|
||||||
|
|
||||||
#include <hw_conf.h>
|
#include <hw_conf.h>
|
||||||
@ -32,6 +33,11 @@ static uint32_t furi_hal_random_read_rng() {
|
|||||||
return LL_RNG_ReadRandData32(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() {
|
uint32_t furi_hal_random_get() {
|
||||||
while(LL_HSEM_1StepLock(HSEM, CFG_HW_RNG_SEMID))
|
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();
|
const uint32_t random_val = furi_hal_random_read_rng();
|
||||||
|
|
||||||
LL_RNG_Disable(RNG);
|
LL_RNG_Disable(RNG);
|
||||||
|
;
|
||||||
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
|
LL_HSEM_ReleaseLock(HSEM, CFG_HW_RNG_SEMID, 0);
|
||||||
|
|
||||||
return random_val;
|
return random_val;
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
@ -106,6 +107,13 @@ static void furi_hal_resources_init_input_pins(GpioMode mode) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_resources_init_early() {
|
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);
|
furi_hal_resources_init_input_pins(GpioModeInput);
|
||||||
|
|
||||||
// SD Card stepdown control
|
// SD Card stepdown control
|
||||||
@ -150,6 +158,12 @@ void furi_hal_resources_init_early() {
|
|||||||
|
|
||||||
void furi_hal_resources_deinit_early() {
|
void furi_hal_resources_deinit_early() {
|
||||||
furi_hal_resources_init_input_pins(GpioModeAnalog);
|
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() {
|
void furi_hal_resources_init() {
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <furi_hal_ibutton.h>
|
#include <furi_hal_ibutton.h>
|
||||||
#include <furi_hal_interrupt.h>
|
#include <furi_hal_interrupt.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
#include <stm32wbxx_ll_tim.h>
|
||||||
@ -9,15 +10,18 @@
|
|||||||
#include <stm32wbxx_ll_dma.h>
|
#include <stm32wbxx_ll_dma.h>
|
||||||
|
|
||||||
#define FURI_HAL_RFID_READ_TIMER TIM1
|
#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
|
#define FURI_HAL_RFID_READ_TIMER_CHANNEL LL_TIM_CHANNEL_CH1N
|
||||||
// We can't use N channel for LL_TIM_OC_Init, so...
|
// 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_READ_TIMER_CHANNEL_CONFIG LL_TIM_CHANNEL_CH1
|
||||||
|
|
||||||
#define FURI_HAL_RFID_EMULATE_TIMER TIM2
|
#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_IRQ FuriHalInterruptIdTIM2
|
||||||
#define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
|
#define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
|
||||||
|
|
||||||
#define RFID_CAPTURE_TIM TIM2
|
#define RFID_CAPTURE_TIM TIM2
|
||||||
|
#define RFID_CAPTURE_TIM_BUS FuriHalBusTIM2
|
||||||
#define RFID_CAPTURE_IND_CH LL_TIM_CHANNEL_CH3
|
#define RFID_CAPTURE_IND_CH LL_TIM_CHANNEL_CH3
|
||||||
#define RFID_CAPTURE_DIR_CH LL_TIM_CHANNEL_CH4
|
#define RFID_CAPTURE_DIR_CH LL_TIM_CHANNEL_CH4
|
||||||
|
|
||||||
@ -30,7 +34,6 @@
|
|||||||
#define RFID_DMA_CH2_DEF RFID_DMA, RFID_DMA_CH2_CHANNEL
|
#define RFID_DMA_CH2_DEF RFID_DMA, RFID_DMA_CH2_CHANNEL
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FuriHalRfidEmulateCallback callback;
|
|
||||||
FuriHalRfidDMACallback dma_callback;
|
FuriHalRfidDMACallback dma_callback;
|
||||||
FuriHalRfidReadCaptureCallback read_capture_callback;
|
FuriHalRfidReadCaptureCallback read_capture_callback;
|
||||||
void* context;
|
void* context;
|
||||||
@ -56,11 +59,7 @@ void furi_hal_rfid_init() {
|
|||||||
COMP_InitStruct.InputPlus = LL_COMP_INPUT_PLUS_IO1;
|
COMP_InitStruct.InputPlus = LL_COMP_INPUT_PLUS_IO1;
|
||||||
COMP_InitStruct.InputMinus = LL_COMP_INPUT_MINUS_1_2VREFINT;
|
COMP_InitStruct.InputMinus = LL_COMP_INPUT_MINUS_1_2VREFINT;
|
||||||
COMP_InitStruct.InputHysteresis = LL_COMP_HYSTERESIS_HIGH;
|
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;
|
COMP_InitStruct.OutputPolarity = LL_COMP_OUTPUTPOL_NONINVERTED;
|
||||||
#endif
|
|
||||||
COMP_InitStruct.OutputBlankingSource = LL_COMP_BLANKINGSRC_NONE;
|
COMP_InitStruct.OutputBlankingSource = LL_COMP_BLANKINGSRC_NONE;
|
||||||
LL_COMP_Init(COMP1, &COMP_InitStruct);
|
LL_COMP_Init(COMP1, &COMP_InitStruct);
|
||||||
LL_COMP_SetCommonWindowMode(__LL_COMP_COMMON_INSTANCE(COMP1), LL_COMP_WINDOWMODE_DISABLE);
|
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);
|
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
|
// ibutton low
|
||||||
furi_hal_ibutton_pin_configure();
|
furi_hal_ibutton_pin_configure();
|
||||||
furi_hal_ibutton_pin_write(false);
|
furi_hal_ibutton_pin_write(false);
|
||||||
@ -113,7 +112,7 @@ void furi_hal_rfid_pins_emulate() {
|
|||||||
&gpio_rfid_carrier, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn2TIM2);
|
&gpio_rfid_carrier, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn2TIM2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rfid_pins_read() {
|
static void furi_hal_rfid_pins_read() {
|
||||||
// ibutton low
|
// ibutton low
|
||||||
furi_hal_ibutton_pin_configure();
|
furi_hal_ibutton_pin_configure();
|
||||||
furi_hal_ibutton_pin_write(false);
|
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);
|
furi_hal_gpio_write(&gpio_nfc_irq_rfid_pull, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rfid_tim_read(float freq, float duty_cycle) {
|
void furi_hal_rfid_tim_read_start(float freq, float duty_cycle) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FURI_HAL_RFID_READ_TIMER_BUS);
|
||||||
LL_TIM_DeInit(FURI_HAL_RFID_READ_TIMER);
|
|
||||||
FURI_CRITICAL_EXIT();
|
furi_hal_rfid_pins_read();
|
||||||
|
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
TIM_InitStruct.Autoreload = (SystemCoreClock / freq) - 1;
|
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);
|
FURI_HAL_RFID_READ_TIMER, FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG, &TIM_OC_InitStruct);
|
||||||
|
|
||||||
LL_TIM_EnableCounter(FURI_HAL_RFID_READ_TIMER);
|
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);
|
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);
|
LL_TIM_DisableAllOutputs(FURI_HAL_RFID_READ_TIMER);
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_rfid_tim_emulate(float freq) {
|
void furi_hal_rfid_tim_read_stop() {
|
||||||
UNUSED(freq); // FIXME
|
furi_hal_bus_disable(FURI_HAL_RFID_READ_TIMER_BUS);
|
||||||
// basic PWM setup with needed freq and internal clock
|
}
|
||||||
FURI_CRITICAL_ENTER();
|
|
||||||
LL_TIM_DeInit(FURI_HAL_RFID_EMULATE_TIMER);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
|
static void furi_hal_rfid_tim_emulate() {
|
||||||
LL_TIM_SetPrescaler(FURI_HAL_RFID_EMULATE_TIMER, 0);
|
LL_TIM_SetPrescaler(FURI_HAL_RFID_EMULATE_TIMER, 0);
|
||||||
LL_TIM_SetCounterMode(FURI_HAL_RFID_EMULATE_TIMER, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(FURI_HAL_RFID_EMULATE_TIMER, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetAutoReload(FURI_HAL_RFID_EMULATE_TIMER, 1);
|
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);
|
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) {
|
static void furi_hal_capture_dma_isr(void* context) {
|
||||||
UNUSED(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) {
|
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_assert(furi_hal_rfid);
|
||||||
|
|
||||||
furi_hal_rfid->read_capture_callback = callback;
|
furi_hal_rfid->read_capture_callback = callback;
|
||||||
furi_hal_rfid->context = context;
|
furi_hal_rfid->context = context;
|
||||||
|
|
||||||
|
furi_hal_bus_enable(RFID_CAPTURE_TIM_BUS);
|
||||||
|
|
||||||
// Timer: base
|
// Timer: base
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
TIM_InitStruct.Prescaler = 64 - 1;
|
TIM_InitStruct.Prescaler = 64 - 1;
|
||||||
@ -303,10 +274,7 @@ void furi_hal_rfid_tim_read_capture_stop() {
|
|||||||
furi_hal_rfid_comp_stop();
|
furi_hal_rfid_comp_stop();
|
||||||
|
|
||||||
furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL);
|
furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL);
|
||||||
|
furi_hal_bus_disable(RFID_CAPTURE_TIM_BUS);
|
||||||
FURI_CRITICAL_ENTER();
|
|
||||||
LL_TIM_DeInit(RFID_CAPTURE_TIM);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_rfid_dma_isr() {
|
static void furi_hal_rfid_dma_isr() {
|
||||||
@ -341,7 +309,8 @@ void furi_hal_rfid_tim_emulate_dma_start(
|
|||||||
furi_hal_rfid_pins_emulate();
|
furi_hal_rfid_pins_emulate();
|
||||||
|
|
||||||
// configure timer
|
// 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(
|
LL_TIM_OC_SetPolarity(
|
||||||
FURI_HAL_RFID_EMULATE_TIMER, FURI_HAL_RFID_EMULATE_TIMER_CHANNEL, LL_TIM_OCPOLARITY_HIGH);
|
FURI_HAL_RFID_EMULATE_TIMER, FURI_HAL_RFID_EMULATE_TIMER_CHANNEL, LL_TIM_OCPOLARITY_HIGH);
|
||||||
LL_TIM_EnableDMAReq_UPDATE(FURI_HAL_RFID_EMULATE_TIMER);
|
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_CH1_DEF);
|
||||||
LL_DMA_DeInit(RFID_DMA_CH2_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();
|
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) {
|
void furi_hal_rfid_set_read_period(uint32_t period) {
|
||||||
LL_TIM_SetAutoReload(FURI_HAL_RFID_READ_TIMER, 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
|
#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() {
|
void furi_hal_rfid_comp_start() {
|
||||||
LL_COMP_Enable(COMP1);
|
LL_COMP_Enable(COMP1);
|
||||||
// Magic
|
// Magic
|
||||||
|
|||||||
@ -21,14 +21,6 @@ void furi_hal_rfid_init();
|
|||||||
*/
|
*/
|
||||||
void furi_hal_rfid_pins_reset();
|
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
|
/** Release rfid pull pin
|
||||||
*/
|
*/
|
||||||
void furi_hal_rfid_pin_pull_release();
|
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();
|
void furi_hal_rfid_pin_pull_pulldown();
|
||||||
|
|
||||||
/** Config rfid timer to read state
|
/** Start read timer
|
||||||
*
|
|
||||||
* @param freq timer frequency
|
* @param freq timer frequency
|
||||||
* @param duty_cycle timer duty cycle, 0.0-1.0
|
* @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
|
/** Stop read timer
|
||||||
*/
|
*/
|
||||||
void furi_hal_rfid_tim_read_stop();
|
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);
|
typedef void (*FuriHalRfidReadCaptureCallback)(bool level, uint32_t duration, void* context);
|
||||||
|
|
||||||
void furi_hal_rfid_tim_read_capture_start(FuriHalRfidReadCaptureCallback callback, 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();
|
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
|
/** Set read timer period
|
||||||
*
|
*
|
||||||
* @param period overall duration
|
* @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);
|
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 */
|
/** Start/Enable comparator */
|
||||||
void furi_hal_rfid_comp_start();
|
void furi_hal_rfid_comp_start();
|
||||||
|
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
#include <furi_hal_light.h>
|
#include <furi_hal_light.h>
|
||||||
#include <furi_hal_debug.h>
|
#include <furi_hal_debug.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_bus.h>
|
|
||||||
#include <stm32wbxx_ll_pwr.h>
|
#include <stm32wbxx_ll_pwr.h>
|
||||||
|
#include <stm32wbxx_ll_bus.h>
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
#include <stm32wbxx_ll_rtc.h>
|
#include <stm32wbxx_ll_rtc.h>
|
||||||
#include <stm32wbxx_ll_utils.h>
|
#include <stm32wbxx_ll_utils.h>
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
#include <furi_hal_gpio.h>
|
#include <furi_hal_gpio.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
#include <furi_hal_power.h>
|
#include <furi_hal_power.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_tim.h>
|
#include <stm32wbxx_ll_tim.h>
|
||||||
#include <furi_hal_cortex.h>
|
#include <furi_hal_cortex.h>
|
||||||
@ -20,16 +21,11 @@ static FuriMutex* furi_hal_speaker_mutex = NULL;
|
|||||||
void furi_hal_speaker_init() {
|
void furi_hal_speaker_init() {
|
||||||
furi_assert(furi_hal_speaker_mutex == NULL);
|
furi_assert(furi_hal_speaker_mutex == NULL);
|
||||||
furi_hal_speaker_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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");
|
FURI_LOG_I(TAG, "Init OK");
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_speaker_deinit() {
|
void furi_hal_speaker_deinit() {
|
||||||
furi_check(furi_hal_speaker_mutex != NULL);
|
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_mutex_free(furi_hal_speaker_mutex);
|
||||||
furi_hal_speaker_mutex = NULL;
|
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) {
|
if(furi_mutex_acquire(furi_hal_speaker_mutex, timeout) == FuriStatusOk) {
|
||||||
furi_hal_power_insomnia_enter();
|
furi_hal_power_insomnia_enter();
|
||||||
|
furi_hal_bus_enable(FuriHalBusTIM16);
|
||||||
furi_hal_gpio_init_ex(
|
furi_hal_gpio_init_ex(
|
||||||
&gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
|
&gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
|
||||||
return true;
|
return true;
|
||||||
@ -53,6 +50,8 @@ void furi_hal_speaker_release() {
|
|||||||
|
|
||||||
furi_hal_speaker_stop();
|
furi_hal_speaker_stop();
|
||||||
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
furi_hal_gpio_init(&gpio_speaker, GpioModeAnalog, GpioPullDown, GpioSpeedLow);
|
||||||
|
|
||||||
|
furi_hal_bus_disable(FuriHalBusTIM16);
|
||||||
furi_hal_power_insomnia_exit();
|
furi_hal_power_insomnia_exit();
|
||||||
|
|
||||||
furi_check(furi_mutex_release(furi_hal_speaker_mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(furi_hal_speaker_mutex) == FuriStatusOk);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
#include <furi_hal_spi_config.h>
|
#include <furi_hal_spi_config.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
#include <furi_hal_spi.h>
|
#include <furi_hal_spi.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
|
|
||||||
#define TAG "FuriHalSpiConfig"
|
#define TAG "FuriHalSpiConfig"
|
||||||
@ -100,28 +101,17 @@ void furi_hal_spi_config_init() {
|
|||||||
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||||
if(event == FuriHalSpiBusEventInit) {
|
if(event == FuriHalSpiBusEventInit) {
|
||||||
furi_hal_spi_bus_r_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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;
|
bus->current_handle = NULL;
|
||||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||||
furi_mutex_free(furi_hal_spi_bus_r_mutex);
|
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) {
|
} else if(event == FuriHalSpiBusEventLock) {
|
||||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
|
furi_check(furi_mutex_acquire(furi_hal_spi_bus_r_mutex, FuriWaitForever) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||||
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(furi_hal_spi_bus_r_mutex) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventActivate) {
|
} else if(event == FuriHalSpiBusEventActivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FuriHalBusSPI1);
|
||||||
LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusSPI1);
|
||||||
LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -135,28 +125,17 @@ FuriMutex* furi_hal_spi_bus_d_mutex = NULL;
|
|||||||
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) {
|
||||||
if(event == FuriHalSpiBusEventInit) {
|
if(event == FuriHalSpiBusEventInit) {
|
||||||
furi_hal_spi_bus_d_mutex = furi_mutex_alloc(FuriMutexTypeNormal);
|
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;
|
bus->current_handle = NULL;
|
||||||
} else if(event == FuriHalSpiBusEventDeinit) {
|
} else if(event == FuriHalSpiBusEventDeinit) {
|
||||||
furi_mutex_free(furi_hal_spi_bus_d_mutex);
|
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) {
|
} else if(event == FuriHalSpiBusEventLock) {
|
||||||
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
|
furi_check(furi_mutex_acquire(furi_hal_spi_bus_d_mutex, FuriWaitForever) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventUnlock) {
|
} else if(event == FuriHalSpiBusEventUnlock) {
|
||||||
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
|
furi_check(furi_mutex_release(furi_hal_spi_bus_d_mutex) == FuriStatusOk);
|
||||||
} else if(event == FuriHalSpiBusEventActivate) {
|
} else if(event == FuriHalSpiBusEventActivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_enable(FuriHalBusSPI2);
|
||||||
LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
} else if(event == FuriHalSpiBusEventDeactivate) {
|
} else if(event == FuriHalSpiBusEventDeactivate) {
|
||||||
FURI_CRITICAL_ENTER();
|
furi_hal_bus_disable(FuriHalBusSPI2);
|
||||||
LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
|
|
||||||
FURI_CRITICAL_EXIT();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,8 +6,6 @@
|
|||||||
#include <furi_hal_gpio.h>
|
#include <furi_hal_gpio.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_spi.h>
|
#include <stm32wbxx_ll_spi.h>
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
|
||||||
#include <stm32wbxx_ll_bus.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|||||||
@ -7,6 +7,7 @@
|
|||||||
#include <furi_hal_spi.h>
|
#include <furi_hal_spi.h>
|
||||||
#include <furi_hal_interrupt.h>
|
#include <furi_hal_interrupt.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_dma.h>
|
#include <stm32wbxx_ll_dma.h>
|
||||||
|
|
||||||
@ -433,6 +434,8 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
|
|||||||
furi_hal_gpio_init_ex(
|
furi_hal_gpio_init_ex(
|
||||||
&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2);
|
&gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2);
|
||||||
|
|
||||||
|
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||||
|
|
||||||
// Timer: base
|
// Timer: base
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
TIM_InitStruct.Prescaler = 64 - 1;
|
TIM_InitStruct.Prescaler = 64 - 1;
|
||||||
@ -496,7 +499,7 @@ void furi_hal_subghz_stop_async_rx() {
|
|||||||
furi_hal_subghz_idle();
|
furi_hal_subghz_idle();
|
||||||
|
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
LL_TIM_DeInit(TIM2);
|
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||||
|
|
||||||
// Stop debug
|
// Stop debug
|
||||||
furi_hal_subghz_stop_debug();
|
furi_hal_subghz_stop_debug();
|
||||||
@ -658,6 +661,8 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
|
|||||||
LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF);
|
LL_DMA_EnableIT_HT(SUBGHZ_DMA_CH1_DEF);
|
||||||
LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF);
|
LL_DMA_EnableChannel(SUBGHZ_DMA_CH1_DEF);
|
||||||
|
|
||||||
|
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||||
|
|
||||||
// Configure TIM2
|
// Configure TIM2
|
||||||
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
LL_TIM_InitTypeDef TIM_InitStruct = {0};
|
||||||
TIM_InitStruct.Prescaler = 64 - 1;
|
TIM_InitStruct.Prescaler = 64 - 1;
|
||||||
@ -740,7 +745,7 @@ void furi_hal_subghz_stop_async_tx() {
|
|||||||
|
|
||||||
// Deinitialize Timer
|
// Deinitialize Timer
|
||||||
FURI_CRITICAL_ENTER();
|
FURI_CRITICAL_ENTER();
|
||||||
LL_TIM_DeInit(TIM2);
|
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||||
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
|
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
|
||||||
|
|
||||||
// Deinitialize DMA
|
// Deinitialize DMA
|
||||||
|
|||||||
@ -4,6 +4,7 @@
|
|||||||
#include <stm32wbxx_ll_usart.h>
|
#include <stm32wbxx_ll_usart.h>
|
||||||
#include <stm32wbxx_ll_rcc.h>
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
#include <furi_hal_resources.h>
|
#include <furi_hal_resources.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
|
|
||||||
#include <furi.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* irq_ctx[2];
|
||||||
|
|
||||||
static void furi_hal_usart_init(uint32_t baud) {
|
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(
|
furi_hal_gpio_init_ex(
|
||||||
&gpio_usart_tx,
|
&gpio_usart_tx,
|
||||||
GpioModeAltFunctionPushPull,
|
GpioModeAltFunctionPushPull,
|
||||||
@ -50,6 +54,9 @@ static void furi_hal_usart_init(uint32_t baud) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void furi_hal_lpuart_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(
|
furi_hal_gpio_init_ex(
|
||||||
&gpio_ext_pc0,
|
&gpio_ext_pc0,
|
||||||
GpioModeAltFunctionPushPull,
|
GpioModeAltFunctionPushPull,
|
||||||
@ -86,10 +93,11 @@ static void furi_hal_lpuart_init(uint32_t baud) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) {
|
void furi_hal_uart_init(FuriHalUartId ch, uint32_t baud) {
|
||||||
if(ch == FuriHalUartIdLPUART1)
|
if(ch == FuriHalUartIdLPUART1) {
|
||||||
furi_hal_lpuart_init(baud);
|
furi_hal_lpuart_init(baud);
|
||||||
else if(ch == FuriHalUartIdUSART1)
|
} else if(ch == FuriHalUartIdUSART1) {
|
||||||
furi_hal_usart_init(baud);
|
furi_hal_usart_init(baud);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void furi_hal_uart_set_br(FuriHalUartId ch, uint32_t 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) {
|
void furi_hal_uart_deinit(FuriHalUartId ch) {
|
||||||
furi_hal_uart_set_irq_cb(ch, NULL, NULL);
|
furi_hal_uart_set_irq_cb(ch, NULL, NULL);
|
||||||
if(ch == FuriHalUartIdUSART1) {
|
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_tx, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||||
furi_hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
furi_hal_gpio_init(&gpio_usart_rx, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||||
} else if(ch == FuriHalUartIdLPUART1) {
|
} 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_pc0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
|
||||||
furi_hal_gpio_init(&gpio_ext_pc1, 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_i.h>
|
||||||
#include <furi_hal_usb.h>
|
#include <furi_hal_usb.h>
|
||||||
#include <furi_hal_power.h>
|
#include <furi_hal_power.h>
|
||||||
|
|
||||||
#include <stm32wbxx_ll_pwr.h>
|
#include <stm32wbxx_ll_pwr.h>
|
||||||
|
#include <stm32wbxx_ll_rcc.h>
|
||||||
#include <furi.h>
|
#include <furi.h>
|
||||||
#include <toolbox/api_lock.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 */
|
/* Low-level init */
|
||||||
void furi_hal_usb_init(void) {
|
void furi_hal_usb_init(void) {
|
||||||
|
LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLLSAI1);
|
||||||
|
|
||||||
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
LL_GPIO_InitTypeDef GPIO_InitStruct = {0};
|
||||||
LL_PWR_EnableVddUSB();
|
LL_PWR_EnableVddUSB();
|
||||||
|
|
||||||
@ -98,7 +102,10 @@ void furi_hal_usb_init(void) {
|
|||||||
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
LL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||||
|
|
||||||
usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf));
|
usbd_init(&udev, &usbd_hw, USB_EP0_SIZE, ubuf, sizeof(ubuf));
|
||||||
|
|
||||||
|
FURI_CRITICAL_ENTER();
|
||||||
usbd_enable(&udev, true);
|
usbd_enable(&udev, true);
|
||||||
|
FURI_CRITICAL_EXIT();
|
||||||
|
|
||||||
usbd_reg_descr(&udev, usb_descriptor_get);
|
usbd_reg_descr(&udev, usb_descriptor_get);
|
||||||
usbd_reg_event(&udev, usbd_evt_susp, susp_evt);
|
usbd_reg_event(&udev, usbd_evt_susp, susp_evt);
|
||||||
@ -359,8 +366,10 @@ static void usb_process_mode_reinit() {
|
|||||||
usbd_connect(&udev, false);
|
usbd_connect(&udev, false);
|
||||||
usb.enabled = false;
|
usb.enabled = false;
|
||||||
|
|
||||||
|
FURI_CRITICAL_ENTER();
|
||||||
usbd_enable(&udev, false);
|
usbd_enable(&udev, false);
|
||||||
usbd_enable(&udev, true);
|
usbd_enable(&udev, true);
|
||||||
|
FURI_CRITICAL_EXIT();
|
||||||
|
|
||||||
furi_delay_ms(USB_RECONNECT_DELAY);
|
furi_delay_ms(USB_RECONNECT_DELAY);
|
||||||
usb_process_mode_start(usb.interface, usb.interface_context);
|
usb_process_mode_start(usb.interface, usb.interface_context);
|
||||||
|
|||||||
@ -38,6 +38,12 @@ static bool flipper_update_mount_sd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool flipper_update_init() {
|
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_clock_init();
|
||||||
furi_hal_rtc_init();
|
furi_hal_rtc_init();
|
||||||
furi_hal_interrupt_init();
|
furi_hal_interrupt_init();
|
||||||
|
|||||||
@ -12,9 +12,11 @@ struct STOP_EXTERNING_ME {};
|
|||||||
|
|
||||||
#include <furi_hal_cortex.h>
|
#include <furi_hal_cortex.h>
|
||||||
#include <furi_hal_clock.h>
|
#include <furi_hal_clock.h>
|
||||||
|
#include <furi_hal_bus.h>
|
||||||
#include <furi_hal_crypto.h>
|
#include <furi_hal_crypto.h>
|
||||||
#include <furi_hal_console.h>
|
#include <furi_hal_console.h>
|
||||||
#include <furi_hal_debug.h>
|
#include <furi_hal_debug.h>
|
||||||
|
#include <furi_hal_dma.h>
|
||||||
#include <furi_hal_os.h>
|
#include <furi_hal_os.h>
|
||||||
#include <furi_hal_sd.h>
|
#include <furi_hal_sd.h>
|
||||||
#include <furi_hal_i2c.h>
|
#include <furi_hal_i2c.h>
|
||||||
|
|||||||
@ -6,6 +6,9 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** Initialize random subsystem */
|
||||||
|
void furi_hal_random_init();
|
||||||
|
|
||||||
/** Get random value
|
/** Get random value
|
||||||
*
|
*
|
||||||
* @return random value
|
* @return random value
|
||||||
|
|||||||
@ -243,10 +243,12 @@ static void digital_signal_stop_timer() {
|
|||||||
LL_TIM_DisableCounter(TIM2);
|
LL_TIM_DisableCounter(TIM2);
|
||||||
LL_TIM_DisableUpdateEvent(TIM2);
|
LL_TIM_DisableUpdateEvent(TIM2);
|
||||||
LL_TIM_DisableDMAReq_UPDATE(TIM2);
|
LL_TIM_DisableDMAReq_UPDATE(TIM2);
|
||||||
|
|
||||||
|
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void digital_signal_setup_timer() {
|
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_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
|
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) {
|
if(file_valid) {
|
||||||
// setup carrier
|
// setup carrier
|
||||||
furi_hal_rfid_pins_read();
|
furi_hal_rfid_tim_read_start(worker->frequency, worker->duty_cycle);
|
||||||
furi_hal_rfid_tim_read(worker->frequency, worker->duty_cycle);
|
|
||||||
furi_hal_rfid_tim_read_start();
|
|
||||||
|
|
||||||
// stabilize detector
|
// stabilize detector
|
||||||
furi_delay_ms(1500);
|
furi_delay_ms(1500);
|
||||||
|
|||||||
@ -100,24 +100,21 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal(
|
|||||||
uint32_t timeout,
|
uint32_t timeout,
|
||||||
ProtocolId* result_protocol) {
|
ProtocolId* result_protocol) {
|
||||||
LFRFIDWorkerReadState state = LFRFIDWorkerReadTimeout;
|
LFRFIDWorkerReadState state = LFRFIDWorkerReadTimeout;
|
||||||
furi_hal_rfid_pins_read();
|
|
||||||
|
|
||||||
if(feature & LFRFIDFeatureASK) {
|
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");
|
FURI_LOG_D(TAG, "Start ASK");
|
||||||
if(worker->read_cb) {
|
if(worker->read_cb) {
|
||||||
worker->read_cb(LFRFIDWorkerReadStartASK, PROTOCOL_NO, worker->cb_ctx);
|
worker->read_cb(LFRFIDWorkerReadStartASK, PROTOCOL_NO, worker->cb_ctx);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
furi_hal_rfid_tim_read(62500, 0.25);
|
furi_hal_rfid_tim_read_start(62500, 0.25);
|
||||||
FURI_LOG_D(TAG, "Start PSK");
|
FURI_LOG_D(TAG, "Start PSK");
|
||||||
if(worker->read_cb) {
|
if(worker->read_cb) {
|
||||||
worker->read_cb(LFRFIDWorkerReadStartPSK, PROTOCOL_NO, worker->cb_ctx);
|
worker->read_cb(LFRFIDWorkerReadStartPSK, PROTOCOL_NO, worker->cb_ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
furi_hal_rfid_tim_read_start();
|
|
||||||
|
|
||||||
// stabilize detector
|
// stabilize detector
|
||||||
lfrfid_worker_delay(worker, LFRFID_WORKER_READ_STABILIZE_TIME_MS);
|
lfrfid_worker_delay(worker, LFRFID_WORKER_READ_STABILIZE_TIME_MS);
|
||||||
|
|
||||||
@ -205,7 +202,7 @@ static LFRFIDWorkerReadState lfrfid_worker_read_internal(
|
|||||||
average_index = 0;
|
average_index = 0;
|
||||||
|
|
||||||
if(worker->read_cb) {
|
if(worker->read_cb) {
|
||||||
if(average > 0.2 && average < 0.8) {
|
if(average > 0.2f && average < 0.8f) {
|
||||||
if(!card_detected) {
|
if(!card_detected) {
|
||||||
card_detected = true;
|
card_detected = true;
|
||||||
worker->read_cb(
|
worker->read_cb(
|
||||||
|
|||||||
@ -14,9 +14,7 @@
|
|||||||
#define T5577_OPCODE_RESET 0b00
|
#define T5577_OPCODE_RESET 0b00
|
||||||
|
|
||||||
static void t5577_start() {
|
static void t5577_start() {
|
||||||
furi_hal_rfid_tim_read(125000, 0.5);
|
furi_hal_rfid_tim_read_start(125000, 0.5);
|
||||||
furi_hal_rfid_pins_read();
|
|
||||||
furi_hal_rfid_tim_read_start();
|
|
||||||
|
|
||||||
// do not ground the antenna
|
// do not ground the antenna
|
||||||
furi_hal_rfid_pin_pull_release();
|
furi_hal_rfid_pin_pull_release();
|
||||||
@ -24,14 +22,13 @@ static void t5577_start() {
|
|||||||
|
|
||||||
static void t5577_stop() {
|
static void t5577_stop() {
|
||||||
furi_hal_rfid_tim_read_stop();
|
furi_hal_rfid_tim_read_stop();
|
||||||
furi_hal_rfid_tim_reset();
|
|
||||||
furi_hal_rfid_pins_reset();
|
furi_hal_rfid_pins_reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void t5577_write_gap(uint32_t gap_time) {
|
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_delay_us(gap_time * 8);
|
||||||
furi_hal_rfid_tim_read_start();
|
furi_hal_rfid_tim_read_continue();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void t5577_write_bit(bool value) {
|
static void t5577_write_bit(bool value) {
|
||||||
|
|||||||
@ -143,7 +143,7 @@ bool opal_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
// sign separately, because then we can handle balances of -99..-1
|
// sign separately, because then we can handle balances of -99..-1
|
||||||
// cents, as the "dollars" division below would result in a positive
|
// cents, as the "dollars" division below would result in a positive
|
||||||
// zero value.
|
// zero value.
|
||||||
o->balance = abs(o->balance);
|
o->balance = abs(o->balance); //-V1081
|
||||||
sign = "-";
|
sign = "-";
|
||||||
}
|
}
|
||||||
uint8_t cents = o->balance % 100;
|
uint8_t cents = o->balance % 100;
|
||||||
@ -164,7 +164,7 @@ bool opal_parser_parse(NfcDeviceData* dev_data) {
|
|||||||
o->mode = 4;
|
o->mode = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* mode_str = (o->mode <= 4 ? opal_modes[o->mode] : opal_modes[3]);
|
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]);
|
const char* usage_str = (o->usage <= 12 ? opal_usages[o->usage] : opal_usages[13]);
|
||||||
|
|
||||||
furi_string_printf(
|
furi_string_printf(
|
||||||
|
|||||||
@ -135,6 +135,7 @@ void pulse_reader_stop(PulseReader* signal) {
|
|||||||
LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1);
|
LL_DMA_DisableChannel(DMA1, signal->dma_channel + 1);
|
||||||
LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
|
LL_DMAMUX_DisableRequestGen(NULL, LL_DMAMUX_REQ_GEN_0);
|
||||||
LL_TIM_DisableCounter(TIM2);
|
LL_TIM_DisableCounter(TIM2);
|
||||||
|
furi_hal_bus_disable(FuriHalBusTIM2);
|
||||||
furi_hal_gpio_init_simple(signal->gpio, GpioModeAnalog);
|
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.MemoryOrM2MDstAddress = (uint32_t)signal->gpio_buffer;
|
||||||
signal->dma_config_gpio.NbData = signal->size;
|
signal->dma_config_gpio.NbData = signal->size;
|
||||||
|
|
||||||
|
furi_hal_bus_enable(FuriHalBusTIM2);
|
||||||
|
|
||||||
/* start counter */
|
/* start counter */
|
||||||
LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
|
LL_TIM_SetCounterMode(TIM2, LL_TIM_COUNTERMODE_UP);
|
||||||
LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
|
LL_TIM_SetClockDivision(TIM2, LL_TIM_CLOCKDIVISION_DIV1);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user