Просмотр исходного кода

[FL-2366] HAL to LL migration part 2 (#1053)

* iButton, FuriHal: add onewire HAL, migrate to LL, add missing critical section guards
* FuriHal: rename onewire to ibutton, cleanup RCC domain usage, fix ibutton and rfid
* FuriHal: cleanup RCC usage
あく 3 лет назад
Родитель
Сommit
1fdc5f2950

+ 18 - 52
applications/ibutton/helpers/pulse_sequencer.cpp

@@ -1,7 +1,7 @@
 #include "pulse_sequencer.h"
+
 #include <furi.h>
-#include <callback-connector.h>
-#include <furi_hal_resources.h>
+#include <furi_hal.h>
 
 void PulseSequencer::set_periods(
     uint32_t* _periods,
@@ -13,74 +13,40 @@ void PulseSequencer::set_periods(
 }
 
 void PulseSequencer::start() {
-    callback_pointer = cbc::obtain_connector(this, &PulseSequencer::timer_elapsed_callback);
-    api_interrupt_add(callback_pointer, InterruptTypeTimerUpdate, this);
-
     period_index = 1;
-    init_timer(periods[period_index]);
     pin_state = pin_start_state;
     hal_gpio_write(&ibutton_gpio, pin_state);
     pin_state = !pin_state;
 
-    HAL_TIM_Base_Start_IT(&htim1);
+    hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedVeryHigh);
+    furi_hal_ibutton_emulate_start(
+        periods[period_index], PulseSequencer::timer_elapsed_callback, this);
 }
 
 void PulseSequencer::stop() {
-    HAL_TIM_Base_Stop_IT(&htim1);
-
-    api_interrupt_remove(callback_pointer, InterruptTypeTimerUpdate);
-    deinit_timer();
+    furi_hal_ibutton_emulate_stop();
 }
 
 PulseSequencer::~PulseSequencer() {
     stop();
 }
 
-void PulseSequencer::init_timer(uint32_t period) {
-    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
+void PulseSequencer::timer_elapsed_callback(void* context) {
+    PulseSequencer* self = static_cast<PulseSequencer*>(context);
 
-    htim1.Instance = TIM1;
-    htim1.Init.Prescaler = 0;
-    htim1.Init.CounterMode = TIM_COUNTERMODE_UP;
-    htim1.Init.Period = period;
-    htim1.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
-    htim1.Init.RepetitionCounter = 0;
-    htim1.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
-    if(HAL_TIM_Base_Init(&htim1) != HAL_OK) {
-        Error_Handler();
-    }
-    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
-    if(HAL_TIM_ConfigClockSource(&htim1, &sClockSourceConfig) != HAL_OK) {
-        Error_Handler();
-    }
+    furi_hal_ibutton_emulate_set_next(self->periods[self->period_index]);
 
-    HAL_NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);
-
-    hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedVeryHigh);
-}
-
-void PulseSequencer::deinit_timer() {
-}
-
-void PulseSequencer::timer_elapsed_callback(void* hw, void* context) {
-    PulseSequencer* _this = static_cast<PulseSequencer*>(context);
-    TIM_HandleTypeDef* htim = static_cast<TIM_HandleTypeDef*>(hw);
-
-    if(htim->Instance == TIM1) {
-        htim->Instance->ARR = _this->periods[_this->period_index];
-
-        if(_this->period_index == 0) {
-            _this->pin_state = _this->pin_start_state;
-        } else {
-            _this->pin_state = !_this->pin_state;
-        }
+    if(self->period_index == 0) {
+        self->pin_state = self->pin_start_state;
+    } else {
+        self->pin_state = !self->pin_state;
+    }
 
-        hal_gpio_write(&ibutton_gpio, _this->pin_state);
+    hal_gpio_write(&ibutton_gpio, self->pin_state);
 
-        _this->period_index++;
+    self->period_index++;
 
-        if(_this->period_index == _this->periods_count) {
-            _this->period_index = 0;
-        }
+    if(self->period_index == self->periods_count) {
+        self->period_index = 0;
     }
 }

+ 3 - 3
applications/ibutton/helpers/pulse_sequencer.h

@@ -17,10 +17,10 @@ private:
     bool pin_state;
 
     void init_timer(uint32_t period);
-    void deinit_timer();
 
     void reset_period_index(PulseSequencer* _this);
 
     void (*callback_pointer)(void*, void*);
-    void timer_elapsed_callback(void* hcomp, void* comp_ctx);
-};
+
+    static void timer_elapsed_callback(void* comp_ctx);
+};

+ 0 - 24
firmware/targets/f7/Inc/main.h

@@ -117,30 +117,6 @@ void Error_Handler(void);
 #define SPI_R_SCK_GPIO_Port GPIOA
 #define SPI_R_SCK_Pin GPIO_PIN_5
 
-extern TIM_HandleTypeDef htim1;
-extern TIM_HandleTypeDef htim2;
-extern TIM_HandleTypeDef htim16;
-
-#define TIM_A htim1
-#define TIM_B htim2
-#define TIM_C htim16
-
-#define SPEAKER_TIM htim16
-#define SPEAKER_CH TIM_CHANNEL_1
-
-#define LFRFID_TIM htim1
-#define LFRFID_CH TIM_CHANNEL_1
-
-#define INFRARED_TX_TIM htim1
-#define INFRARED_TX_CH TIM_CHANNEL_3
-
-// only for reference
-// INFRARED RX timer dont exist in F2
-// and timer need more data to init (NVIC IRQn to set priority)
-#define INFRARED_RX_TIM htim2
-#define INFRARED_RX_FALLING_CH TIM_CHANNEL_1
-#define INFRARED_RX_RISING_CH TIM_CHANNEL_2
-
 #define NFC_IRQ_Pin RFID_PULL_Pin
 #define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port
 

+ 0 - 8
firmware/targets/f7/Src/gpio.c

@@ -3,14 +3,6 @@
 void MX_GPIO_Init(void) {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
 
-    /* GPIO Ports Clock Enable */
-    __HAL_RCC_GPIOA_CLK_ENABLE();
-    __HAL_RCC_GPIOB_CLK_ENABLE();
-    __HAL_RCC_GPIOC_CLK_ENABLE();
-    __HAL_RCC_GPIOD_CLK_ENABLE();
-    __HAL_RCC_GPIOE_CLK_ENABLE();
-    __HAL_RCC_GPIOH_CLK_ENABLE();
-
     /*Configure GPIO pin : PtPin */
     GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
     GPIO_InitStruct.Pull = GPIO_PULLUP;

+ 1 - 82
firmware/targets/f7/Src/stm32wbxx_hal_msp.c

@@ -1,92 +1,11 @@
-/* USER CODE BEGIN Header */
-/**
-  ******************************************************************************
-  * File Name          : stm32wbxx_hal_msp.c
-  * Description        : This file provides code for the MSP Initialization
-  *                      and de-Initialization codes.
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under Ultimate Liberty license
-  * SLA0044, the "License"; You may not use this file except in compliance with
-  * the License. You may obtain a copy of the License at:
-  *                             www.st.com/SLA0044
-  *
-  ******************************************************************************
-  */
-/* USER CODE END Header */
-
-/* Includes ------------------------------------------------------------------*/
 #include "main.h"
-/* USER CODE BEGIN Includes */
-
-/* USER CODE END Includes */
-
-/* Private typedef -----------------------------------------------------------*/
-/* USER CODE BEGIN TD */
-
-/* USER CODE END TD */
-
-/* Private define ------------------------------------------------------------*/
-/* USER CODE BEGIN Define */
-
-/* USER CODE END Define */
-
-/* Private macro -------------------------------------------------------------*/
-/* USER CODE BEGIN Macro */
-
-/* USER CODE END Macro */
-
-/* Private variables ---------------------------------------------------------*/
-/* USER CODE BEGIN PV */
-
-/* USER CODE END PV */
-
-/* Private function prototypes -----------------------------------------------*/
-/* USER CODE BEGIN PFP */
-
-/* USER CODE END PFP */
 
-/* External functions --------------------------------------------------------*/
-/* USER CODE BEGIN ExternalFunctions */
-
-/* USER CODE END ExternalFunctions */
-
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-/**
-  * Initializes the Global MSP.
-  */
 void HAL_MspInit(void) {
-    /* USER CODE BEGIN MspInit 0 */
-
-    /* USER CODE END MspInit 0 */
-
-    __HAL_RCC_HSEM_CLK_ENABLE();
-
-    /* System interrupt init*/
-    /* PendSV_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
 
-    /* Peripheral interrupt init */
-    /* RCC_IRQn interrupt configuration */
     HAL_NVIC_SetPriority(RCC_IRQn, 5, 0);
     HAL_NVIC_EnableIRQ(RCC_IRQn);
-    /* HSEM_IRQn interrupt configuration */
+
     HAL_NVIC_SetPriority(HSEM_IRQn, 5, 0);
     HAL_NVIC_EnableIRQ(HSEM_IRQn);
-
-    /* USER CODE BEGIN MspInit 1 */
-
-    /* USER CODE END MspInit 1 */
 }
-
-/* USER CODE BEGIN 1 */
-
-/* USER CODE END 1 */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 1 - 89
firmware/targets/f7/Src/tim.c

@@ -1,29 +1,5 @@
-/**
-  ******************************************************************************
-  * @file    tim.c
-  * @brief   This file provides code for the configuration
-  *          of the TIM instances.
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2021 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under Ultimate Liberty license
-  * SLA0044, the "License"; You may not use this file except in compliance with
-  * the License. You may obtain a copy of the License at:
-  *                             www.st.com/SLA0044
-  *
-  ******************************************************************************
-  */
-
-/* Includes ------------------------------------------------------------------*/
 #include "tim.h"
 
-/* USER CODE BEGIN 0 */
-
-/* USER CODE END 0 */
-
 TIM_HandleTypeDef htim1;
 TIM_HandleTypeDef htim2;
 
@@ -92,6 +68,7 @@ void MX_TIM1_Init(void) {
     }
     HAL_TIM_MspPostInit(&htim1);
 }
+
 /* TIM2 init function */
 void MX_TIM2_Init(void) {
     TIM_ClockConfigTypeDef sClockSourceConfig = {0};
@@ -136,29 +113,9 @@ void MX_TIM2_Init(void) {
 void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     if(tim_baseHandle->Instance == TIM1) {
-        /* USER CODE BEGIN TIM1_MspInit 0 */
-
-        /* USER CODE END TIM1_MspInit 0 */
-        /* TIM1 clock enable */
-        __HAL_RCC_TIM1_CLK_ENABLE();
-
-        /* TIM1 interrupt Init */
         HAL_NVIC_SetPriority(TIM1_TRG_COM_TIM17_IRQn, 0, 0);
         HAL_NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn);
-        /* USER CODE BEGIN TIM1_MspInit 1 */
-
-        /* USER CODE END TIM1_MspInit 1 */
     } else if(tim_baseHandle->Instance == TIM2) {
-        /* USER CODE BEGIN TIM2_MspInit 0 */
-
-        /* USER CODE END TIM2_MspInit 0 */
-        /* TIM2 clock enable */
-        __HAL_RCC_TIM2_CLK_ENABLE();
-
-        __HAL_RCC_GPIOA_CLK_ENABLE();
-        /**TIM2 GPIO Configuration
-    PA0     ------> TIM2_CH1
-    */
         GPIO_InitStruct.Pin = IR_RX_Pin;
         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
         GPIO_InitStruct.Pull = GPIO_NOPULL;
@@ -169,70 +126,25 @@ void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* tim_baseHandle) {
         /* TIM2 interrupt Init */
         HAL_NVIC_SetPriority(TIM2_IRQn, 5, 0);
         HAL_NVIC_EnableIRQ(TIM2_IRQn);
-        /* USER CODE BEGIN TIM2_MspInit 1 */
-
-        /* USER CODE END TIM2_MspInit 1 */
     }
 }
 void HAL_TIM_MspPostInit(TIM_HandleTypeDef* timHandle) {
     GPIO_InitTypeDef GPIO_InitStruct = {0};
     if(timHandle->Instance == TIM1) {
-        /* USER CODE BEGIN TIM1_MspPostInit 0 */
-
-        /* USER CODE END TIM1_MspPostInit 0 */
-        __HAL_RCC_GPIOB_CLK_ENABLE();
-        /**TIM1 GPIO Configuration
-    PB9     ------> TIM1_CH3N
-    PB13     ------> TIM1_CH1N
-    */
         GPIO_InitStruct.Pin = IR_TX_Pin | RFID_OUT_Pin;
         GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
         GPIO_InitStruct.Pull = GPIO_NOPULL;
         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
         GPIO_InitStruct.Alternate = GPIO_AF1_TIM1;
         HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-
-        /* USER CODE BEGIN TIM1_MspPostInit 1 */
-
-        /* USER CODE END TIM1_MspPostInit 1 */
     }
 }
 
 void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* tim_baseHandle) {
     if(tim_baseHandle->Instance == TIM1) {
-        /* USER CODE BEGIN TIM1_MspDeInit 0 */
-
-        /* USER CODE END TIM1_MspDeInit 0 */
-        /* Peripheral clock disable */
-        __HAL_RCC_TIM1_CLK_DISABLE();
-
-        /* TIM1 interrupt Deinit */
         HAL_NVIC_DisableIRQ(TIM1_TRG_COM_TIM17_IRQn);
-        /* USER CODE BEGIN TIM1_MspDeInit 1 */
-
-        /* USER CODE END TIM1_MspDeInit 1 */
     } else if(tim_baseHandle->Instance == TIM2) {
-        /* USER CODE BEGIN TIM2_MspDeInit 0 */
-
-        /* USER CODE END TIM2_MspDeInit 0 */
-        /* Peripheral clock disable */
-        __HAL_RCC_TIM2_CLK_DISABLE();
-
-        /**TIM2 GPIO Configuration
-    PA0     ------> TIM2_CH1
-    */
         HAL_GPIO_DeInit(IR_RX_GPIO_Port, IR_RX_Pin);
-
-        /* TIM2 interrupt Deinit */
         HAL_NVIC_DisableIRQ(TIM2_IRQn);
-        /* USER CODE BEGIN TIM2_MspDeInit 1 */
-
-        /* USER CODE END TIM2_MspDeInit 1 */
     }
 }
-
-/* USER CODE BEGIN 1 */
-
-/* USER CODE END 1 */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 1 - 3
firmware/targets/f7/ble_glue/app_debug.c

@@ -164,12 +164,10 @@ void APPD_Init(void) {
     gpio_config.Pin = GPIO_PIN_15 | GPIO_PIN_14 | GPIO_PIN_13;
     __HAL_RCC_GPIOA_CLK_ENABLE();
     HAL_GPIO_Init(GPIOA, &gpio_config);
-    __HAL_RCC_GPIOA_CLK_DISABLE();
 
     gpio_config.Pin = GPIO_PIN_4 | GPIO_PIN_3;
     __HAL_RCC_GPIOB_CLK_ENABLE();
     HAL_GPIO_Init(GPIOB, &gpio_config);
-    __HAL_RCC_GPIOB_CLK_DISABLE();
 
     HAL_DBGMCU_DisableDBGSleepMode();
     HAL_DBGMCU_DisableDBGStopMode();
@@ -354,4 +352,4 @@ void DbgOutputTraces(uint8_t* p_data, uint16_t size, void (*cb)(void)) {
 }
 #endif
 
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 0 - 4
firmware/targets/f7/ble_glue/hw_ipcc.c

@@ -159,8 +159,6 @@ void HW_IPCC_Enable(void) {
   * Such as IPCC IP available to the CPU2, it is required to keep the IPCC clock running
     when FUS is running on CPU2 and CPU1 enters deep sleep mode
   */
-    LL_C2_AHB3_GRP1_EnableClock(LL_C2_AHB3_GRP1_PERIPH_IPCC);
-
     /**
    * When the device is out of standby, it is required to use the EXTI mechanism to wakeup CPU2
    */
@@ -184,8 +182,6 @@ void HW_IPCC_Enable(void) {
 }
 
 void HW_IPCC_Init(void) {
-    LL_AHB3_GRP1_EnableClock(LL_AHB3_GRP1_PERIPH_IPCC);
-
     LL_C1_IPCC_EnableIT_RXO(IPCC);
     LL_C1_IPCC_EnableIT_TXF(IPCC);
 

+ 3 - 0
firmware/targets/f7/furi_hal/furi_hal.c

@@ -26,6 +26,9 @@ void furi_hal_init() {
     FURI_LOG_I(TAG, "TIM1 OK");
     MX_TIM2_Init();
     FURI_LOG_I(TAG, "TIM2 OK");
+
+    furi_hal_ibutton_init();
+    FURI_LOG_I(TAG, "iButton OK");
     furi_hal_speaker_init();
     FURI_LOG_I(TAG, "Speaker OK");
 

+ 32 - 9
firmware/targets/f7/furi_hal/furi_hal_clock.c

@@ -98,33 +98,56 @@ void furi_hal_clock_init() {
     LL_RCC_SetSMPSPrescaler(LL_RCC_SMPS_DIV_1);
     LL_RCC_SetRFWKPClockSource(LL_RCC_RFWKP_CLKSOURCE_LSE);
 
-    // AHB1
-    LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);
+    // AHB1 GRP1
     LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);
-    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
-    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
+    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
+    // 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_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
+    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC);
     LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_AES1);
 
-    // AHB3
+    // 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_RNG);
     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
+    // 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);
+    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2);
 
     // 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");
 }

+ 0 - 2
firmware/targets/f7/furi_hal/furi_hal_i2c_config.c

@@ -20,7 +20,6 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent
     if(event == FuriHalI2cBusEventInit) {
         furi_hal_i2c_bus_power_mutex = osMutexNew(NULL);
         FURI_CRITICAL_ENTER();
-        LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1);
         LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1);
         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1);
         FURI_CRITICAL_EXIT();
@@ -52,7 +51,6 @@ osMutexId_t furi_hal_i2c_bus_external_mutex = NULL;
 static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) {
     if(event == FuriHalI2cBusEventActivate) {
         FURI_CRITICAL_ENTER();
-        LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3);
         LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1);
         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3);
         FURI_CRITICAL_EXIT();

+ 86 - 0
firmware/targets/f7/furi_hal/furi_hal_ibutton.c

@@ -1,6 +1,92 @@
 #include <furi_hal_ibutton.h>
+#include <furi_hal_interrupt.h>
 #include <furi_hal_resources.h>
 
+#include <stm32wbxx_ll_tim.h>
+
+#include <furi.h>
+
+#define FURI_HAL_IBUTTON_TIMER TIM1
+#define FURI_HAL_IBUTTON_TIMER_IRQ TIM1_UP_TIM16_IRQn
+
+typedef enum {
+    FuriHalIbuttonStateIdle,
+    FuriHalIbuttonStateRunning,
+} FuriHalIbuttonState;
+
+typedef struct {
+    FuriHalIbuttonState state;
+    FuriHalIbuttonEmulateCallback callback;
+    void* context;
+} FuriHalIbutton;
+
+FuriHalIbutton* furi_hal_ibutton = NULL;
+
+static void furi_hal_ibutton_emulate_isr() {
+    if(LL_TIM_IsActiveFlag_UPDATE(FURI_HAL_IBUTTON_TIMER)) {
+        LL_TIM_ClearFlag_UPDATE(FURI_HAL_IBUTTON_TIMER);
+        furi_hal_ibutton->callback(furi_hal_ibutton->context);
+    }
+}
+
+void furi_hal_ibutton_init() {
+    furi_hal_ibutton = malloc(sizeof(FuriHalIbutton));
+    furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
+}
+
+void furi_hal_ibutton_emulate_start(
+    uint32_t period,
+    FuriHalIbuttonEmulateCallback callback,
+    void* context) {
+    furi_assert(furi_hal_ibutton);
+    furi_assert(furi_hal_ibutton->state == FuriHalIbuttonStateIdle);
+
+    furi_hal_ibutton->state = FuriHalIbuttonStateRunning;
+    furi_hal_ibutton->callback = callback;
+    furi_hal_ibutton->context = context;
+
+    FURI_CRITICAL_ENTER();
+    LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
+    FURI_CRITICAL_EXIT();
+
+    LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0);
+    LL_TIM_SetCounterMode(FURI_HAL_IBUTTON_TIMER, LL_TIM_COUNTERMODE_UP);
+    LL_TIM_SetAutoReload(FURI_HAL_IBUTTON_TIMER, period);
+    LL_TIM_DisableARRPreload(FURI_HAL_IBUTTON_TIMER);
+    LL_TIM_SetRepetitionCounter(FURI_HAL_IBUTTON_TIMER, 0);
+
+    LL_TIM_SetClockDivision(FURI_HAL_IBUTTON_TIMER, LL_TIM_CLOCKDIVISION_DIV1);
+    LL_TIM_SetClockSource(FURI_HAL_IBUTTON_TIMER, LL_TIM_CLOCKSOURCE_INTERNAL);
+    LL_TIM_GenerateEvent_UPDATE(FURI_HAL_IBUTTON_TIMER);
+
+    LL_TIM_EnableIT_UPDATE(FURI_HAL_IBUTTON_TIMER);
+
+    furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, furi_hal_ibutton_emulate_isr);
+
+    NVIC_SetPriority(
+        FURI_HAL_IBUTTON_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
+    NVIC_EnableIRQ(FURI_HAL_IBUTTON_TIMER_IRQ);
+
+    LL_TIM_EnableCounter(FURI_HAL_IBUTTON_TIMER);
+}
+
+void furi_hal_ibutton_emulate_set_next(uint32_t period) {
+    LL_TIM_SetAutoReload(FURI_HAL_IBUTTON_TIMER, period);
+}
+
+void furi_hal_ibutton_emulate_stop() {
+    furi_assert(furi_hal_ibutton);
+
+    if(furi_hal_ibutton->state == FuriHalIbuttonStateRunning) {
+        furi_hal_ibutton->state = FuriHalIbuttonStateIdle;
+        LL_TIM_DisableCounter(FURI_HAL_IBUTTON_TIMER);
+        furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, NULL);
+
+        furi_hal_ibutton->callback = NULL;
+        furi_hal_ibutton->context = NULL;
+    }
+}
+
 void furi_hal_ibutton_start() {
     furi_hal_ibutton_pin_high();
     hal_gpio_init(&ibutton_gpio, GpioModeOutputOpenDrain, GpioPullNo, GpioSpeedLow);

+ 5 - 15
firmware/targets/f7/furi_hal/furi_hal_infrared.c

@@ -138,11 +138,6 @@ static void furi_hal_infrared_tim_rx_isr() {
 void furi_hal_infrared_async_rx_start(void) {
     furi_assert(furi_hal_infrared_state == InfraredStateIdle);
 
-    FURI_CRITICAL_ENTER();
-    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
-    LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA);
-    FURI_CRITICAL_EXIT();
-
     hal_gpio_init_ex(
         &gpio_infrared_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2);
 
@@ -188,15 +183,17 @@ void furi_hal_infrared_async_rx_start(void) {
 
 void furi_hal_infrared_async_rx_stop(void) {
     furi_assert(furi_hal_infrared_state == InfraredStateAsyncRx);
+
+    FURI_CRITICAL_ENTER();
+
     LL_TIM_DeInit(TIM2);
     furi_hal_interrupt_set_timer_isr(TIM2, NULL);
-    LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2);
     furi_hal_infrared_state = InfraredStateIdle;
+
+    FURI_CRITICAL_EXIT();
 }
 
 void furi_hal_infrared_async_rx_set_timeout(uint32_t timeout_us) {
-    furi_assert(LL_APB1_GRP1_IsEnabledClock(LL_APB1_GRP1_PERIPH_TIM2));
-
     LL_TIM_OC_SetCompareCH3(TIM2, timeout_us);
     LL_TIM_OC_SetMode(TIM2, LL_TIM_CHANNEL_CH3, LL_TIM_OCMODE_ACTIVE);
     LL_TIM_CC_EnableChannel(TIM2, LL_TIM_CHANNEL_CH3);
@@ -322,7 +319,6 @@ static void furi_hal_infrared_tx_dma_isr() {
 }
 
 static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cycle) {
-    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM1);
     /*    LL_DBGMCU_APB2_GRP1_FreezePeriph(LL_DBGMCU_APB2_GRP1_TIM1_STOP); */
 
     LL_TIM_DisableCounter(TIM1);
@@ -362,8 +358,6 @@ static void furi_hal_infrared_configure_tim_pwm_tx(uint32_t freq, float duty_cyc
 }
 
 static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
-    LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1);
-
     LL_DMA_InitTypeDef dma_config = {0};
 #if INFRARED_TX_DEBUG == 1
     dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->CCMR1);
@@ -394,8 +388,6 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
 }
 
 static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
-    LL_C2_AHB1_GRP1_EnableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1);
-
     LL_DMA_InitTypeDef dma_config = {0};
     dma_config.PeriphOrM2MSrcAddress = (uint32_t) & (TIM1->RCR);
     dma_config.MemoryOrM2MDstAddress = (uint32_t)NULL;
@@ -562,8 +554,6 @@ static void furi_hal_infrared_async_tx_free_resources(void) {
     furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL);
     furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, NULL);
     LL_TIM_DeInit(TIM1);
-    LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1);
-    LL_C2_AHB1_GRP1_DisableClock(LL_C2_AHB1_GRP1_PERIPH_DMA1);
 
     status = osSemaphoreDelete(infrared_tim_tx.stop_semaphore);
     furi_check(status == osOK);

+ 2 - 0
firmware/targets/f7/furi_hal/furi_hal_interrupt.c

@@ -2,6 +2,8 @@
 
 #include <furi.h>
 #include <main.h>
+
+#include <tim.h>
 #include <stm32wbxx_ll_tim.h>
 
 #define TAG "FuriHalInterrupt"

+ 0 - 1
firmware/targets/f7/furi_hal/furi_hal_os_timer.h

@@ -13,7 +13,6 @@
 static inline void furi_hal_os_timer_init() {
     // Configure clock source
     LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_LSE);
-    LL_APB1_GRP2_EnableClock(LL_APB1_GRP2_PERIPH_LPTIM2);
     // Set interrupt priority and enable them
     NVIC_SetPriority(
         FURI_HAL_OS_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));

+ 7 - 2
firmware/targets/f7/furi_hal/furi_hal_rfid.c

@@ -3,9 +3,12 @@
 #include <furi_hal_resources.h>
 #include <furi_hal_version.h>
 
+#include <tim.h>
 #include <stm32wbxx_ll_tim.h>
 #include <stm32wbxx_ll_comp.h>
 
+#define LFRFID_TIM htim1
+#define LFRFID_CH TIM_CHANNEL_1
 #define LFRFID_READ_TIM htim1
 #define LFRFID_READ_CHANNEL TIM_CHANNEL_1
 #define LFRFID_EMULATE_TIM htim2
@@ -246,12 +249,14 @@ void furi_hal_rfid_tim_emulate_stop() {
 }
 
 void furi_hal_rfid_tim_reset() {
+    FURI_CRITICAL_ENTER();
+
     HAL_TIM_Base_DeInit(&LFRFID_READ_TIM);
     LL_TIM_DeInit(TIM1);
-    LL_APB2_GRP1_DisableClock(LL_APB2_GRP1_PERIPH_TIM1);
     HAL_TIM_Base_DeInit(&LFRFID_EMULATE_TIM);
     LL_TIM_DeInit(TIM2);
-    LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2);
+
+    FURI_CRITICAL_EXIT();
 }
 
 bool furi_hal_rfid_is_tim_emulate(TIM_HandleTypeDef* hw) {

+ 0 - 1
firmware/targets/f7/furi_hal/furi_hal_rtc.c

@@ -23,7 +23,6 @@ void furi_hal_rtc_init() {
     }
 
     LL_RCC_EnableRTC();
-    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_RTCAPB);
 
     LL_RTC_InitTypeDef RTC_InitStruct = {0};
     RTC_InitStruct.HourFormat = LL_RTC_HOURFORMAT_24HOUR;

+ 3 - 1
firmware/targets/f7/furi_hal/furi_hal_speaker.c

@@ -12,8 +12,10 @@
 // #define FURI_HAL_SPEAKER_NEW_VOLUME
 
 void furi_hal_speaker_init() {
-    LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_TIM16);
+    FURI_CRITICAL_ENTER();
     LL_TIM_DeInit(FURI_HAL_SPEAKER_TIMER);
+    FURI_CRITICAL_EXIT();
+
     hal_gpio_init_ex(
         &gpio_speaker, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn14TIM16);
 }

+ 0 - 2
firmware/targets/f7/furi_hal/furi_hal_spi_config.c

@@ -76,7 +76,6 @@ static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE
     if(event == FuriHalSpiBusEventInit) {
         furi_hal_spi_bus_r_mutex = osMutexNew(NULL);
         FURI_CRITICAL_ENTER();
-        LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1);
         LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1);
         FURI_CRITICAL_EXIT();
         bus->current_handle = NULL;
@@ -108,7 +107,6 @@ static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE
     if(event == FuriHalSpiBusEventInit) {
         furi_hal_spi_bus_d_mutex = osMutexNew(NULL);
         FURI_CRITICAL_ENTER();
-        LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2);
         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2);
         FURI_CRITICAL_EXIT();
         bus->current_handle = NULL;

+ 0 - 9
firmware/targets/f7/furi_hal/furi_hal_subghz.c

@@ -692,10 +692,6 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
         &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2);
 
     // Timer: base
-    FURI_CRITICAL_ENTER();
-    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
-    FURI_CRITICAL_EXIT();
-
     LL_TIM_InitTypeDef TIM_InitStruct = {0};
     TIM_InitStruct.Prescaler = 64 - 1;
     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
@@ -757,7 +753,6 @@ void furi_hal_subghz_stop_async_rx() {
 
     FURI_CRITICAL_ENTER();
     LL_TIM_DeInit(TIM2);
-    LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2);
     FURI_CRITICAL_EXIT();
     furi_hal_interrupt_set_timer_isr(TIM2, NULL);
 
@@ -903,9 +898,6 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
     LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
 
     // Configure TIM2
-    FURI_CRITICAL_ENTER();
-    LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2);
-    FURI_CRITICAL_EXIT();
     LL_TIM_InitTypeDef TIM_InitStruct = {0};
     TIM_InitStruct.Prescaler = 64 - 1;
     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP;
@@ -966,7 +958,6 @@ void furi_hal_subghz_stop_async_tx() {
     // Deinitialize Timer
     FURI_CRITICAL_ENTER();
     LL_TIM_DeInit(TIM2);
-    LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2);
     furi_hal_interrupt_set_timer_isr(TIM2, NULL);
 
     // Deinitialize DMA

+ 16 - 1
firmware/targets/furi_hal_include/furi_hal_ibutton.h

@@ -6,11 +6,26 @@
 #pragma once
 
 #include <stdbool.h>
+#include <stdint.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+typedef void (*FuriHalIbuttonEmulateCallback)(void* context);
+
+/** Initialize */
+void furi_hal_ibutton_init();
+
+void furi_hal_ibutton_emulate_start(
+    uint32_t period,
+    FuriHalIbuttonEmulateCallback callback,
+    void* context);
+
+void furi_hal_ibutton_emulate_set_next(uint32_t period);
+
+void furi_hal_ibutton_emulate_stop();
+
 void furi_hal_ibutton_start();
 
 void furi_hal_ibutton_stop();
@@ -23,4 +38,4 @@ bool furi_hal_ibutton_pin_get_level();
 
 #ifdef __cplusplus
 }
-#endif
+#endif