[FL-2392] FuriHal: refactor interrupts subsystem (#1066)

* FuriHal: refactor interrupts subsystem

* Furi,FuriHal: gather all ISRs under interrupt API, improve crtitical section and cleanup garbage

* FuriHal: mirgate ipcc and hsem to LL

* Format Sources

* FuriHal,BleGlue: move to new critical section

* Format Sources

* FuriHal: correct flash locking

* FuriHal: replace critical section with interrupt disable in OS routine, minor fixex
This commit is contained in:
あく 2022-03-29 20:37:23 +03:00 committed by GitHub
parent bdba15b366
commit 489caa8e77
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 360 additions and 715 deletions

View File

@ -1,8 +1,6 @@
#include "input_i.h"
#define GPIO_Read(input_pin) \
(HAL_GPIO_ReadPin((GPIO_TypeDef*)input_pin.pin->port, input_pin.pin->pin) ^ \
input_pin.pin->inverted)
#define GPIO_Read(input_pin) (hal_gpio_read(input_pin.pin->pin) ^ input_pin.pin->inverted)
static Input* input = NULL;
@ -81,8 +79,7 @@ int32_t input_srv() {
input->pin_states = malloc(input_pins_count * sizeof(InputPinState));
for(size_t i = 0; i < input_pins_count; i++) {
GpioPin gpio = {(GPIO_TypeDef*)input_pins[i].port, (uint16_t)input_pins[i].pin};
hal_gpio_add_int_callback(&gpio, input_isr, NULL);
hal_gpio_add_int_callback(input_pins[i].pin, input_isr, NULL);
input->pin_states[i].pin = &input_pins[i];
input->pin_states[i].state = GPIO_Read(input->pin_states[i]);
input->pin_states[i].debounce = INPUT_DEBOUNCE_TICKS_HALF;

View File

@ -1,11 +1,12 @@
#include "check.h"
#include "furi_hal_task.h"
#include "common_defines.h"
#include <furi_hal_console.h>
#include <furi_hal_rtc.h>
#include <stdio.h>
void __furi_print_name() {
if(task_is_isr_context()) {
if(FURI_IS_ISR()) {
furi_hal_console_puts("[ISR] ");
} else {
const char* name = osThreadGetName(osThreadGetId());

32
core/furi/common_defines.h Executable file → Normal file
View File

@ -1,5 +1,8 @@
#pragma once
#include <stdbool.h>
#include <cmsis_os2.h>
#ifndef MAX
#define MAX(a, b) \
({ \
@ -75,12 +78,35 @@
#define FURI_BIT(x, n) ((x) >> (n)&1)
#endif
#ifndef FURI_IS_IRQ_MASKED
#define FURI_IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#endif
#ifndef FURI_IS_IRQ_MODE
#define FURI_IS_IRQ_MODE() (__get_IPSR() != 0U)
#endif
#ifndef FURI_IS_ISR
#define FURI_IS_ISR() \
(FURI_IS_IRQ_MODE() || (FURI_IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning)))
#endif
#ifndef FURI_CRITICAL_ENTER
#define FURI_CRITICAL_ENTER() \
uint32_t primask_bit = __get_PRIMASK(); \
__disable_irq()
uint32_t __isrm = 0; \
bool __from_isr = FURI_IS_ISR(); \
if(__from_isr) { \
__isrm = taskENTER_CRITICAL_FROM_ISR(); \
} else { \
taskENTER_CRITICAL(); \
}
#endif
#ifndef FURI_CRITICAL_EXIT
#define FURI_CRITICAL_EXIT() __set_PRIMASK(primask_bit)
#define FURI_CRITICAL_EXIT() \
if(__from_isr) { \
taskEXIT_CRITICAL_FROM_ISR(__isrm); \
} else { \
taskEXIT_CRITICAL(); \
}
#endif

View File

@ -41,7 +41,6 @@
#include <stm32wbxx.h>
#include <furi_hal_console.h>
#include <furi/common_defines.h>
#include <furi_hal_task.h>
/* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
all the API functions to use the MPU wrappers. That should only be done when

View File

@ -5,117 +5,112 @@ extern "C" {
#endif
#include "stm32wbxx_hal.h"
#include "stm32wbxx_ll_gpio.h"
void Error_Handler(void);
#define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_BACK_GPIO_Port GPIOC
#define BUTTON_BACK_Pin GPIO_PIN_13
#define BUTTON_DOWN_EXTI_IRQn EXTI6_IRQn
#define BUTTON_BACK_Pin LL_GPIO_PIN_13
#define BUTTON_DOWN_GPIO_Port GPIOC
#define BUTTON_DOWN_Pin GPIO_PIN_6
#define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_DOWN_Pin LL_GPIO_PIN_6
#define BUTTON_LEFT_GPIO_Port GPIOB
#define BUTTON_LEFT_Pin GPIO_PIN_11
#define BUTTON_OK_EXTI_IRQn EXTI3_IRQn
#define BUTTON_LEFT_Pin LL_GPIO_PIN_11
#define BUTTON_OK_GPIO_Port GPIOH
#define BUTTON_OK_Pin GPIO_PIN_3
#define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_OK_Pin LL_GPIO_PIN_3
#define BUTTON_RIGHT_GPIO_Port GPIOB
#define BUTTON_RIGHT_Pin GPIO_PIN_12
#define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn
#define BUTTON_RIGHT_Pin LL_GPIO_PIN_12
#define BUTTON_UP_GPIO_Port GPIOB
#define BUTTON_UP_Pin GPIO_PIN_10
#define BUTTON_UP_Pin LL_GPIO_PIN_10
#define CC1101_CS_GPIO_Port GPIOD
#define CC1101_CS_Pin GPIO_PIN_0
#define CC1101_CS_Pin LL_GPIO_PIN_0
#define CC1101_G0_GPIO_Port GPIOA
#define CC1101_G0_Pin GPIO_PIN_1
#define CC1101_G0_Pin LL_GPIO_PIN_1
#define DISPLAY_CS_GPIO_Port GPIOC
#define DISPLAY_CS_Pin GPIO_PIN_11
#define DISPLAY_CS_Pin LL_GPIO_PIN_11
#define DISPLAY_DI_GPIO_Port GPIOB
#define DISPLAY_DI_Pin GPIO_PIN_1
#define DISPLAY_DI_Pin LL_GPIO_PIN_1
#define DISPLAY_RST_GPIO_Port GPIOB
#define DISPLAY_RST_Pin GPIO_PIN_0
#define DISPLAY_RST_Pin LL_GPIO_PIN_0
#define IR_RX_GPIO_Port GPIOA
#define IR_RX_Pin GPIO_PIN_0
#define IR_RX_Pin LL_GPIO_PIN_0
#define IR_TX_GPIO_Port GPIOB
#define IR_TX_Pin GPIO_PIN_9
#define IR_TX_Pin LL_GPIO_PIN_9
#define NFC_CS_GPIO_Port GPIOE
#define NFC_CS_Pin GPIO_PIN_4
#define NFC_CS_Pin LL_GPIO_PIN_4
#define PA4_GPIO_Port GPIOA
#define PA4_Pin GPIO_PIN_4
#define PA4_Pin LL_GPIO_PIN_4
#define PA6_GPIO_Port GPIOA
#define PA6_Pin GPIO_PIN_6
#define PA6_Pin LL_GPIO_PIN_6
#define PA7_GPIO_Port GPIOA
#define PA7_Pin GPIO_PIN_7
#define PA7_Pin LL_GPIO_PIN_7
#define PB2_GPIO_Port GPIOB
#define PB2_Pin GPIO_PIN_2
#define PB2_Pin LL_GPIO_PIN_2
#define PB3_GPIO_Port GPIOB
#define PB3_Pin GPIO_PIN_3
#define PB3_Pin LL_GPIO_PIN_3
#define PC0_GPIO_Port GPIOC
#define PC0_Pin GPIO_PIN_0
#define PC0_Pin LL_GPIO_PIN_0
#define PC1_GPIO_Port GPIOC
#define PC1_Pin GPIO_PIN_1
#define PC1_Pin LL_GPIO_PIN_1
#define PC3_GPIO_Port GPIOC
#define PC3_Pin GPIO_PIN_3
#define PC3_Pin LL_GPIO_PIN_3
#define PERIPH_POWER_GPIO_Port GPIOA
#define PERIPH_POWER_Pin GPIO_PIN_3
#define PERIPH_POWER_Pin LL_GPIO_PIN_3
#define QUARTZ_32MHZ_IN_GPIO_Port GPIOC
#define QUARTZ_32MHZ_IN_Pin GPIO_PIN_14
#define QUARTZ_32MHZ_IN_Pin LL_GPIO_PIN_14
#define QUARTZ_32MHZ_OUT_GPIO_Port GPIOC
#define QUARTZ_32MHZ_OUT_Pin GPIO_PIN_15
#define QUARTZ_32MHZ_OUT_Pin LL_GPIO_PIN_15
#define RFID_OUT_GPIO_Port GPIOB
#define RFID_OUT_Pin GPIO_PIN_13
#define RFID_OUT_Pin LL_GPIO_PIN_13
#define RFID_PULL_GPIO_Port GPIOA
#define RFID_PULL_Pin GPIO_PIN_2
#define RFID_PULL_Pin LL_GPIO_PIN_2
#define RFID_RF_IN_GPIO_Port GPIOC
#define RFID_RF_IN_Pin GPIO_PIN_5
#define RFID_RF_IN_Pin LL_GPIO_PIN_5
#define RFID_CARRIER_GPIO_Port GPIOA
#define RFID_CARRIER_Pin GPIO_PIN_15
#define RFID_CARRIER_Pin LL_GPIO_PIN_15
#define RF_SW_0_GPIO_Port GPIOC
#define RF_SW_0_Pin GPIO_PIN_4
#define RF_SW_0_Pin LL_GPIO_PIN_4
#define SD_CD_GPIO_Port GPIOC
#define SD_CD_Pin GPIO_PIN_10
#define SD_CD_Pin LL_GPIO_PIN_10
#define SD_CS_GPIO_Port GPIOC
#define SD_CS_Pin GPIO_PIN_12
#define SD_CS_Pin LL_GPIO_PIN_12
#define SPEAKER_GPIO_Port GPIOB
#define SPEAKER_Pin GPIO_PIN_8
#define SPEAKER_Pin LL_GPIO_PIN_8
#define VIBRO_GPIO_Port GPIOA
#define VIBRO_Pin GPIO_PIN_8
#define VIBRO_Pin LL_GPIO_PIN_8
#define iBTN_GPIO_Port GPIOB
#define iBTN_Pin GPIO_PIN_14
#define iBTN_Pin LL_GPIO_PIN_14
#define USART1_TX_Pin GPIO_PIN_6
#define USART1_TX_Pin LL_GPIO_PIN_6
#define USART1_TX_Port GPIOB
#define USART1_RX_Pin GPIO_PIN_7
#define USART1_RX_Pin LL_GPIO_PIN_7
#define USART1_RX_Port GPIOB
#define SPI_D_MISO_GPIO_Port GPIOC
#define SPI_D_MISO_Pin GPIO_PIN_2
#define SPI_D_MISO_Pin LL_GPIO_PIN_2
#define SPI_D_MOSI_GPIO_Port GPIOB
#define SPI_D_MOSI_Pin GPIO_PIN_15
#define SPI_D_MOSI_Pin LL_GPIO_PIN_15
#define SPI_D_SCK_GPIO_Port GPIOD
#define SPI_D_SCK_Pin GPIO_PIN_1
#define SPI_D_SCK_Pin LL_GPIO_PIN_1
#define SPI_R_MISO_GPIO_Port GPIOB
#define SPI_R_MISO_Pin GPIO_PIN_4
#define SPI_R_MISO_Pin LL_GPIO_PIN_4
#define SPI_R_MOSI_GPIO_Port GPIOB
#define SPI_R_MOSI_Pin GPIO_PIN_5
#define SPI_R_MOSI_Pin LL_GPIO_PIN_5
#define SPI_R_SCK_GPIO_Port GPIOA
#define SPI_R_SCK_Pin GPIO_PIN_5
#define SPI_R_SCK_Pin LL_GPIO_PIN_5
#define NFC_IRQ_Pin RFID_PULL_Pin
#define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port

View File

@ -37,7 +37,7 @@ extern "C" {
#define HAL_CRYP_MODULE_ENABLED
/*#define HAL_COMP_MODULE_ENABLED */
/*#define HAL_CRC_MODULE_ENABLED */
#define HAL_HSEM_MODULE_ENABLED
/*#define HAL_HSEM_MODULE_ENABLED */
/*#define HAL_I2C_MODULE_ENABLED */
/*#define HAL_IPCC_MODULE_ENABLED */
/*#define HAL_IRDA_MODULE_ENABLED */

View File

@ -1,69 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32wbxx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @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 */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32WBxx_IT_H
#define __STM32WBxx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void SysTick_Handler(void);
void ADC1_IRQHandler(void);
void USB_LP_IRQHandler(void);
void COMP_IRQHandler(void);
void TIM1_UP_TIM16_IRQHandler(void);
void TIM1_TRG_COM_TIM17_IRQHandler(void);
void TIM1_CC_IRQHandler(void);
void TIM2_IRQHandler(void);
void HSEM_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32WBxx_IT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -1,11 +0,0 @@
#include "main.h"
void HAL_MspInit(void) {
HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
HAL_NVIC_SetPriority(RCC_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(RCC_IRQn);
HAL_NVIC_SetPriority(HSEM_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(HSEM_IRQn);
}

View File

@ -1,31 +0,0 @@
#include "main.h"
#include "stm32wbxx_it.h"
#include "FreeRTOS.h"
#include "task.h"
#include "usbd_core.h"
extern usbd_device udev;
extern void HW_TS_RTC_Wakeup_Handler();
extern void HW_IPCC_Tx_Handler();
extern void HW_IPCC_Rx_Handler();
void SysTick_Handler(void) {
HAL_IncTick();
}
void USB_LP_IRQHandler(void) {
usbd_poll(&udev);
}
void HSEM_IRQHandler(void) {
HAL_HSEM_IRQHandler();
}
void IPCC_C1_TX_IRQHandler(void) {
HW_IPCC_Tx_Handler();
}
void IPCC_C1_RX_IRQHandler(void) {
HW_IPCC_Rx_Handler();
}

View File

@ -1,126 +1,5 @@
/**
******************************************************************************
* @file system_stm32wbxx.c
* @author MCD Application Team
* @brief CMSIS Cortex Device Peripheral Access Layer System Source File
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32wbxx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
* After each device reset the MSI (4 MHz) is used as system clock source.
* Then SystemInit() function is called, in "startup_stm32wbxx.s" file, to
* configure the system clock before to branch to main program.
*
* This file configures the system clock as follows:
*=============================================================================
*-----------------------------------------------------------------------------
* System Clock source | MSI
*-----------------------------------------------------------------------------
* SYSCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* HCLK(Hz) | 4000000
*-----------------------------------------------------------------------------
* AHB Prescaler | 1
*-----------------------------------------------------------------------------
* APB1 Prescaler | 1
*-----------------------------------------------------------------------------
* APB2 Prescaler | 1
*-----------------------------------------------------------------------------
* PLL_M | 1
*-----------------------------------------------------------------------------
* PLL_N | 8
*-----------------------------------------------------------------------------
* PLL_P | 7
*-----------------------------------------------------------------------------
* PLL_Q | 2
*-----------------------------------------------------------------------------
* PLL_R | 2
*-----------------------------------------------------------------------------
* PLLSAI1_P | NA
*-----------------------------------------------------------------------------
* PLLSAI1_Q | NA
*-----------------------------------------------------------------------------
* PLLSAI1_R | NA
*-----------------------------------------------------------------------------
* Require 48MHz for USB OTG FS, | Disabled
* SDIO and RNG clock |
*-----------------------------------------------------------------------------
*=============================================================================
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2019 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32WBxx_system
* @{
*/
/** @addtogroup stm32WBxx_System_Private_Includes
* @{
*/
#include "stm32wbxx.h"
#if !defined(HSE_VALUE)
#define HSE_VALUE (32000000UL) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined(MSI_VALUE)
#define MSI_VALUE (4000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* MSI_VALUE */
#if !defined(HSI_VALUE)
#define HSI_VALUE (16000000UL) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
#if !defined(LSI_VALUE)
#define LSI_VALUE (32000UL) /*!< Value of LSI in Hz*/
#endif /* LSI_VALUE */
#if !defined(LSE_VALUE)
#define LSE_VALUE (32768UL) /*!< Value of LSE in Hz*/
#endif /* LSE_VALUE */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Defines
* @{
*/
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
@ -131,21 +10,7 @@
#define VECT_TAB_BASE_ADDRESS \
SRAM1_BASE /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Variables
* @{
*/
/* The SystemCoreClock variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
@ -179,30 +44,6 @@ const uint32_t MSIRangeTable[16UL] = {
0UL,
0UL}; /* 0UL values are incorrect cases */
#if defined(STM32WB55xx) || defined(STM32WB5Mxx) || defined(STM32WB35xx)
const uint32_t SmpsPrescalerTable[4UL][6UL] = {
{1UL, 3UL, 2UL, 2UL, 1UL, 2UL},
{2UL, 6UL, 4UL, 3UL, 2UL, 4UL},
{4UL, 12UL, 8UL, 6UL, 4UL, 8UL},
{4UL, 12UL, 8UL, 6UL, 4UL, 8UL}};
#endif
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_FunctionPrototypes
* @{
*/
/**
* @}
*/
/** @addtogroup STM32WBxx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system.
* @param None
@ -254,118 +95,3 @@ void SystemInit(void) {
/* Disable all interrupts */
RCC->CIER = 0x00000000;
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is MSI, SystemCoreClock will contain the MSI_VALUE(*)
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(**)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(***)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(***)
* or HSI_VALUE(*) or MSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) MSI_VALUE is a constant defined in stm32wbxx_hal.h file (default value
* 4 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSI_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (***) HSE_VALUE is a constant defined in stm32wbxx_hal_conf.h file (default value
* 32 MHz), user has to ensure that HSE_VALUE is same as the real
* frequency of the crystal used. Otherwise, this function may
* have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void) {
uint32_t tmp, msirange, pllvco, pllr, pllsource, pllm;
/* Get MSI Range frequency--------------------------------------------------*/
/*MSI frequency range in Hz*/
msirange = MSIRangeTable[(RCC->CR & RCC_CR_MSIRANGE) >> RCC_CR_MSIRANGE_Pos];
/* Get SYSCLK source -------------------------------------------------------*/
switch(RCC->CFGR & RCC_CFGR_SWS) {
case 0x00: /* MSI used as system clock source */
SystemCoreClock = msirange;
break;
case 0x04: /* HSI used as system clock source */
/* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x08: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x0C: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE or MSI_VALUE/ PLLM) * PLLN
SYSCLK = PLL_VCO / PLLR
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC);
pllm = ((RCC->PLLCFGR & RCC_PLLCFGR_PLLM) >> RCC_PLLCFGR_PLLM_Pos) + 1UL;
if(pllsource == 0x02UL) /* HSI used as PLL clock source */
{
pllvco = (HSI_VALUE / pllm);
} else if(pllsource == 0x03UL) /* HSE used as PLL clock source */
{
pllvco = (HSE_VALUE / pllm);
} else /* MSI used as PLL clock source */
{
pllvco = (msirange / pllm);
}
pllvco = pllvco * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> RCC_PLLCFGR_PLLN_Pos);
pllr = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLR) >> RCC_PLLCFGR_PLLR_Pos) + 1UL);
SystemCoreClock = pllvco / pllr;
break;
default:
SystemCoreClock = msirange;
break;
}
/* Compute HCLK clock frequency --------------------------------------------*/
/* Get HCLK1 prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> RCC_CFGR_HPRE_Pos)];
/* HCLK clock frequency */
SystemCoreClock = SystemCoreClock / tmp;
}
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

View File

@ -29,15 +29,14 @@ extern "C" {
#include "cmsis_compiler.h"
#include "string.h"
#include <furi.h>
/******************************************************************************
* common
******************************************************************************/
#define UTILS_ENTER_CRITICAL_SECTION() \
uint32_t primask_bit = __get_PRIMASK(); \
__disable_irq()
#define UTILS_ENTER_CRITICAL_SECTION() FURI_CRITICAL_ENTER()
#define UTILS_EXIT_CRITICAL_SECTION() __set_PRIMASK(primask_bit)
#define UTILS_EXIT_CRITICAL_SECTION() FURI_CRITICAL_EXIT()
#define UTILS_MEMSET8(dest, value, size) memset(dest, value, size);

View File

@ -82,8 +82,8 @@ void furi_hal_bt_init() {
}
// Explicitly tell that we are in charge of CLK48 domain
if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) {
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) {
furi_assert(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0);
}
// Start Core2
@ -124,8 +124,8 @@ bool furi_hal_bt_start_radio_stack() {
osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever);
// Explicitly tell that we are in charge of CLK48 domain
if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) {
HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID);
if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) {
furi_assert(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0);
}
do {
@ -283,13 +283,13 @@ void furi_hal_bt_set_key_storage_change_callback(
}
void furi_hal_bt_nvm_sram_sem_acquire() {
while(HAL_HSEM_FastTake(CFG_HW_BLE_NVM_SRAM_SEMID) != HAL_OK) {
osDelay(1);
while(LL_HSEM_1StepLock(HSEM, CFG_HW_BLE_NVM_SRAM_SEMID)) {
osThreadYield();
}
}
void furi_hal_bt_nvm_sram_sem_release() {
HAL_HSEM_Release(CFG_HW_BLE_NVM_SRAM_SEMID, 0);
LL_HSEM_ReleaseLock(HSEM, CFG_HW_BLE_NVM_SRAM_SEMID, 0);
}
bool furi_hal_bt_clear_white_list() {

View File

@ -87,8 +87,8 @@ static void furi_hal_flash_lock(void) {
static void furi_hal_flash_begin_with_core2(bool erase_flag) {
// Take flash controller ownership
while(HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) {
taskYIELD();
while(LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID) != 0) {
osThreadYield();
}
// Unlock flash operation
@ -97,27 +97,35 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) {
// Erase activity notification
if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON);
// 64mHz 5us core2 flag protection
for(volatile uint32_t i = 0; i < 35; i++)
;
while(true) {
// Wait till flash controller become usable
while(LL_FLASH_IsActiveFlag_OperationSuspended()) {
taskYIELD();
osThreadYield();
};
// Just a little more love
taskENTER_CRITICAL();
// Actually we already have mutex for it, but specification is specification
if(HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) {
if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU1_SEMID)) {
taskEXIT_CRITICAL();
continue;
}
// Take sempahopre and prevent core2 from anyting funky
if(!HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) {
if(HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) {
//
if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) {
taskEXIT_CRITICAL();
continue;
}
// Take sempahopre and prevent core2 from anything funky
if(LL_HSEM_1StepLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != 0) {
taskEXIT_CRITICAL();
continue;
}
break;
@ -138,14 +146,14 @@ static void furi_hal_flash_begin(bool erase_flag) {
static void furi_hal_flash_end_with_core2(bool erase_flag) {
// Funky ops are ok at this point
HAL_HSEM_Release(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0);
LL_HSEM_ReleaseLock(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID, 0);
// Task switching is ok
taskEXIT_CRITICAL();
// Doesn't make much sense, does it?
while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {
taskYIELD();
osThreadYield();
}
// Erase activity over, core2 can continue
@ -155,7 +163,7 @@ static void furi_hal_flash_end_with_core2(bool erase_flag) {
furi_hal_flash_lock();
// Release flash controller ownership
HAL_HSEM_Release(CFG_HW_FLASH_SEMID, 0);
LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0);
}
static void furi_hal_flash_end(bool erase_flag) {

View File

@ -8,7 +8,7 @@
#include <furi.h>
#define FURI_HAL_IBUTTON_TIMER TIM1
#define FURI_HAL_IBUTTON_TIMER_IRQ TIM1_UP_TIM16_IRQn
#define FURI_HAL_IBUTTON_TIMER_IRQ FuriHalInterruptIdTim1UpTim16
typedef enum {
FuriHalIbuttonStateIdle,
@ -50,10 +50,7 @@ void furi_hal_ibutton_emulate_start(
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
FURI_CRITICAL_EXIT();
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);
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, furi_hal_ibutton_emulate_isr, NULL);
LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0);
LL_TIM_SetCounterMode(FURI_HAL_IBUTTON_TIMER, LL_TIM_COUNTERMODE_UP);
@ -85,7 +82,7 @@ void furi_hal_ibutton_emulate_stop() {
LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER);
FURI_CRITICAL_EXIT();
furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, NULL);
furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, NULL, NULL);
furi_hal_ibutton->callback = NULL;
furi_hal_ibutton->context = NULL;

View File

@ -166,7 +166,7 @@ void furi_hal_infrared_async_rx_start(void) {
LL_TIM_IC_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI);
LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1);
furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_infrared_tim_rx_isr);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_infrared_tim_rx_isr, NULL);
furi_hal_infrared_state = InfraredStateAsyncRx;
LL_TIM_EnableIT_CC1(TIM2);
@ -176,9 +176,6 @@ void furi_hal_infrared_async_rx_start(void) {
LL_TIM_SetCounter(TIM2, 0);
LL_TIM_EnableCounter(TIM2);
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(TIM2_IRQn);
}
void furi_hal_infrared_async_rx_stop(void) {
@ -187,7 +184,7 @@ void furi_hal_infrared_async_rx_stop(void) {
FURI_CRITICAL_ENTER();
LL_TIM_DeInit(TIM2);
furi_hal_interrupt_set_timer_isr(TIM2, NULL);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
furi_hal_infrared_state = InfraredStateIdle;
FURI_CRITICAL_EXIT();
@ -376,15 +373,15 @@ static void furi_hal_infrared_configure_tim_cmgr2_dma_tx(void) {
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config);
furi_hal_interrupt_set_dma_channel_isr(
DMA1, LL_DMA_CHANNEL_1, furi_hal_infrared_tx_dma_polarity_isr);
LL_DMA_ClearFlag_TE1(DMA1);
LL_DMA_ClearFlag_TC1(DMA1);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 4, 0));
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
furi_hal_interrupt_set_isr_ex(
FuriHalInterruptIdDma1Ch1, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL);
}
static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
@ -401,16 +398,17 @@ static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) {
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP;
dma_config.Priority = LL_DMA_PRIORITY_MEDIUM;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config);
furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, furi_hal_infrared_tx_dma_isr);
LL_DMA_ClearFlag_TC2(DMA1);
LL_DMA_ClearFlag_HT2(DMA1);
LL_DMA_ClearFlag_TE2(DMA1);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_2);
NVIC_SetPriority(DMA1_Channel2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(DMA1_Channel2_IRQn);
furi_hal_interrupt_set_isr_ex(
FuriHalInterruptIdDma1Ch2, 5, furi_hal_infrared_tx_dma_isr, NULL);
}
static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) {
@ -551,8 +549,8 @@ static void furi_hal_infrared_async_tx_free_resources(void) {
osStatus_t status;
hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow);
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);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch2, NULL, NULL);
LL_TIM_DeInit(TIM1);
status = osSemaphoreDelete(infrared_tim_tx.stop_semaphore);

View File

@ -3,153 +3,201 @@
#include <furi.h>
#include <main.h>
#include <stm32wbxx.h>
#include <stm32wbxx_ll_tim.h>
#define TAG "FuriHalInterrupt"
volatile FuriHalInterruptISR furi_hal_tim_tim2_isr = NULL;
volatile FuriHalInterruptISR furi_hal_tim_tim1_isr = NULL;
#define FURI_HAL_INTERRUPT_DEFAULT_PRIORITY 5
#define FURI_HAL_INTERRUPT_DMA_COUNT 2
#define FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8
typedef struct {
FuriHalInterruptISR isr;
void* context;
} FuriHalInterruptISRPair;
volatile FuriHalInterruptISR furi_hal_dma_channel_isr[FURI_HAL_INTERRUPT_DMA_COUNT]
[FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {0};
FuriHalInterruptISRPair furi_hal_interrupt_isr[FuriHalInterruptIdMax] = {0};
const IRQn_Type furi_hal_interrupt_irqn[FuriHalInterruptIdMax] = {
// TIM1, TIM16, TIM17
[FuriHalInterruptIdTim1TrgComTim17] = TIM1_TRG_COM_TIM17_IRQn,
[FuriHalInterruptIdTim1Cc] = TIM1_CC_IRQn,
[FuriHalInterruptIdTim1UpTim16] = TIM1_UP_TIM16_IRQn,
// TIM2
[FuriHalInterruptIdTIM2] = TIM2_IRQn,
// DMA1
[FuriHalInterruptIdDma1Ch1] = DMA1_Channel1_IRQn,
[FuriHalInterruptIdDma1Ch2] = DMA1_Channel2_IRQn,
[FuriHalInterruptIdDma1Ch3] = DMA1_Channel3_IRQn,
[FuriHalInterruptIdDma1Ch4] = DMA1_Channel4_IRQn,
[FuriHalInterruptIdDma1Ch5] = DMA1_Channel5_IRQn,
[FuriHalInterruptIdDma1Ch6] = DMA1_Channel6_IRQn,
[FuriHalInterruptIdDma1Ch7] = DMA1_Channel7_IRQn,
// DMA2
[FuriHalInterruptIdDma2Ch1] = DMA2_Channel1_IRQn,
[FuriHalInterruptIdDma2Ch2] = DMA2_Channel2_IRQn,
[FuriHalInterruptIdDma2Ch3] = DMA2_Channel3_IRQn,
[FuriHalInterruptIdDma2Ch4] = DMA2_Channel4_IRQn,
[FuriHalInterruptIdDma2Ch5] = DMA2_Channel5_IRQn,
[FuriHalInterruptIdDma2Ch6] = DMA2_Channel6_IRQn,
[FuriHalInterruptIdDma2Ch7] = DMA2_Channel7_IRQn,
// RCC
[FuriHalInterruptIdRcc] = RCC_IRQn,
// COMP
[FuriHalInterruptIdCOMP] = COMP_IRQn,
// HSEM
[FuriHalInterruptIdHsem] = HSEM_IRQn,
};
__attribute__((always_inline)) static inline void
furi_hal_interrupt_call(FuriHalInterruptId index) {
furi_assert(furi_hal_interrupt_isr[index].isr);
furi_hal_interrupt_isr[index].isr(furi_hal_interrupt_isr[index].context);
}
__attribute__((always_inline)) static inline void
furi_hal_interrupt_enable(FuriHalInterruptId index, uint16_t priority) {
NVIC_SetPriority(
furi_hal_interrupt_irqn[index],
NVIC_EncodePriority(NVIC_GetPriorityGrouping(), priority, 0));
NVIC_EnableIRQ(furi_hal_interrupt_irqn[index]);
}
__attribute__((always_inline)) static inline void
furi_hal_interrupt_disable(FuriHalInterruptId index) {
NVIC_DisableIRQ(furi_hal_interrupt_irqn[index]);
}
void furi_hal_interrupt_init() {
NVIC_SetPriority(RCC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
NVIC_EnableIRQ(RCC_IRQn);
NVIC_SetPriority(
TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn);
NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(DMA1_Channel1_IRQn);
NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0));
NVIC_SetPriority(HSEM_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
HAL_NVIC_EnableIRQ(HSEM_IRQn);
FURI_LOG_I(TAG, "Init OK");
}
void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr) {
if(timer == TIM2) {
if(isr) {
furi_assert(furi_hal_tim_tim2_isr == NULL);
} else {
furi_assert(furi_hal_tim_tim2_isr != NULL);
}
furi_hal_tim_tim2_isr = isr;
} else if(timer == TIM1) {
if(isr) {
furi_assert(furi_hal_tim_tim1_isr == NULL);
} else {
furi_assert(furi_hal_tim_tim1_isr != NULL);
}
furi_hal_tim_tim1_isr = isr;
} else {
furi_crash(NULL);
}
void furi_hal_interrupt_set_isr(FuriHalInterruptId index, FuriHalInterruptISR isr, void* context) {
furi_hal_interrupt_set_isr_ex(index, FURI_HAL_INTERRUPT_DEFAULT_PRIORITY, isr, context);
}
void furi_hal_interrupt_set_dma_channel_isr(
DMA_TypeDef* dma,
uint32_t channel,
FuriHalInterruptISR isr) {
--channel; // Pascal
furi_check(dma);
furi_check(channel < FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT);
if(dma == DMA1) {
furi_hal_dma_channel_isr[0][channel] = isr;
} else if(dma == DMA2) {
furi_hal_dma_channel_isr[1][channel] = isr;
void furi_hal_interrupt_set_isr_ex(
FuriHalInterruptId index,
uint16_t priority,
FuriHalInterruptISR isr,
void* context) {
furi_assert(index < FuriHalInterruptIdMax);
furi_assert(priority < 15);
furi_assert(furi_hal_interrupt_irqn[index]);
if(isr) {
// Pre ISR set
furi_assert(furi_hal_interrupt_isr[index].isr == NULL);
} else {
furi_crash(NULL);
// Pre ISR clear
furi_assert(furi_hal_interrupt_isr[index].isr != NULL);
furi_hal_interrupt_disable(index);
}
furi_hal_interrupt_isr[index].isr = isr;
furi_hal_interrupt_isr[index].context = context;
__DMB();
if(isr) {
// Post ISR set
furi_hal_interrupt_enable(index, priority);
} else {
// Post ISR clear
}
}
/* Timer 2 */
void TIM2_IRQHandler(void) {
if(furi_hal_tim_tim2_isr) {
furi_hal_tim_tim2_isr();
}
furi_hal_interrupt_call(FuriHalInterruptIdTIM2);
}
/* Timer 1 Update */
void TIM1_UP_TIM16_IRQHandler(void) {
if(furi_hal_tim_tim1_isr) {
furi_hal_tim_tim1_isr();
}
furi_hal_interrupt_call(FuriHalInterruptIdTim1UpTim16);
}
void TIM1_TRG_COM_TIM17_IRQHandler(void) {
furi_hal_interrupt_call(FuriHalInterruptIdTim1TrgComTim17);
}
void TIM1_CC_IRQHandler(void) {
furi_hal_interrupt_call(FuriHalInterruptIdTim1Cc);
}
/* DMA 1 */
void DMA1_Channel1_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][0]) furi_hal_dma_channel_isr[0][0]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch1);
}
void DMA1_Channel2_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][1]) furi_hal_dma_channel_isr[0][1]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch2);
}
void DMA1_Channel3_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][2]) furi_hal_dma_channel_isr[0][2]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch3);
}
void DMA1_Channel4_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][3]) furi_hal_dma_channel_isr[0][3]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch4);
}
void DMA1_Channel5_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][4]) furi_hal_dma_channel_isr[0][4]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch5);
}
void DMA1_Channel6_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][5]) furi_hal_dma_channel_isr[0][5]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch6);
}
void DMA1_Channel7_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][6]) furi_hal_dma_channel_isr[0][6]();
}
void DMA1_Channel8_IRQHandler(void) {
if(furi_hal_dma_channel_isr[0][7]) furi_hal_dma_channel_isr[0][7]();
furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch7);
}
/* DMA 2 */
void DMA2_Channel1_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][0]) furi_hal_dma_channel_isr[1][0]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch1);
}
void DMA2_Channel2_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][1]) furi_hal_dma_channel_isr[1][1]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch2);
}
void DMA2_Channel3_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][2]) furi_hal_dma_channel_isr[1][2]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch3);
}
void DMA2_Channel4_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][3]) furi_hal_dma_channel_isr[1][3]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch4);
}
void DMA2_Channel5_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][4]) furi_hal_dma_channel_isr[1][4]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch5);
}
void DMA2_Channel6_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][5]) furi_hal_dma_channel_isr[1][5]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch6);
}
void DMA2_Channel7_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][6]) furi_hal_dma_channel_isr[1][6]();
furi_hal_interrupt_call(FuriHalInterruptIdDma2Ch7);
}
void DMA2_Channel8_IRQHandler(void) {
if(furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7]();
void HSEM_IRQHandler(void) {
furi_hal_interrupt_call(FuriHalInterruptIdHsem);
}
void TAMP_STAMP_LSECSS_IRQHandler(void) {
@ -165,6 +213,7 @@ void TAMP_STAMP_LSECSS_IRQHandler(void) {
}
void RCC_IRQHandler(void) {
furi_hal_interrupt_call(FuriHalInterruptIdRcc);
}
void NMI_Handler(void) {
@ -193,3 +242,26 @@ void UsageFault_Handler(void) {
void DebugMon_Handler(void) {
}
#include "usbd_core.h"
extern usbd_device udev;
extern void HW_IPCC_Tx_Handler();
extern void HW_IPCC_Rx_Handler();
void SysTick_Handler(void) {
HAL_IncTick();
}
void USB_LP_IRQHandler(void) {
usbd_poll(&udev);
}
void IPCC_C1_TX_IRQHandler(void) {
HW_IPCC_Tx_Handler();
}
void IPCC_C1_RX_IRQHandler(void) {
HW_IPCC_Rx_Handler();
}

View File

@ -7,29 +7,71 @@ extern "C" {
#endif
/** Timer ISR */
typedef void (*FuriHalInterruptISR)();
typedef void (*FuriHalInterruptISR)(void* context);
typedef enum {
// TIM1, TIM16, TIM17
FuriHalInterruptIdTim1TrgComTim17,
FuriHalInterruptIdTim1Cc,
FuriHalInterruptIdTim1UpTim16,
// TIM2
FuriHalInterruptIdTIM2,
// DMA1
FuriHalInterruptIdDma1Ch1,
FuriHalInterruptIdDma1Ch2,
FuriHalInterruptIdDma1Ch3,
FuriHalInterruptIdDma1Ch4,
FuriHalInterruptIdDma1Ch5,
FuriHalInterruptIdDma1Ch6,
FuriHalInterruptIdDma1Ch7,
// DMA2
FuriHalInterruptIdDma2Ch1,
FuriHalInterruptIdDma2Ch2,
FuriHalInterruptIdDma2Ch3,
FuriHalInterruptIdDma2Ch4,
FuriHalInterruptIdDma2Ch5,
FuriHalInterruptIdDma2Ch6,
FuriHalInterruptIdDma2Ch7,
// RCC
FuriHalInterruptIdRcc,
// Comp
FuriHalInterruptIdCOMP,
// HSEM
FuriHalInterruptIdHsem,
// Service value
FuriHalInterruptIdMax,
} FuriHalInterruptId;
/** Initialize interrupt subsystem */
void furi_hal_interrupt_init();
/** Set DMA Channel ISR
/** Set ISR and enable interrupt with default priority
* We don't clear interrupt flags for you, do it by your self.
* @param dma - DMA instance
* @param channel - DMA channel
* @param index - interrupt ID
* @param isr - your interrupt service routine or use NULL to clear
* @param context - isr context
*/
void furi_hal_interrupt_set_dma_channel_isr(
DMA_TypeDef* dma,
uint32_t channel,
FuriHalInterruptISR isr);
void furi_hal_interrupt_set_isr(FuriHalInterruptId index, FuriHalInterruptISR isr, void* context);
/** Set Timer ISR
* By default ISR is serviced by ST HAL. Use this function to override it.
/** Set ISR and enable interrupt with custom priority
* We don't clear interrupt flags for you, do it by your self.
* @param timer - timer instance
* @param index - interrupt ID
* @param priority - 0 to 15, 0 highest
* @param isr - your interrupt service routine or use NULL to clear
* @param context - isr context
*/
void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr);
void furi_hal_interrupt_set_isr_ex(
FuriHalInterruptId index,
uint16_t priority,
FuriHalInterruptISR isr,
void* context);
#ifdef __cplusplus
}

View File

@ -115,11 +115,11 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) {
}
// Stop IRQ handling, no one should disturb us till we finish
FURI_CRITICAL_ENTER();
__disable_irq();
// Confirm OS that sleep is still possible
if(eTaskConfirmSleepModeStatus() == eAbortSleep) {
FURI_CRITICAL_EXIT();
__enable_irq();
return;
}
@ -136,7 +136,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) {
}
// Reenable IRQ
FURI_CRITICAL_EXIT();
__enable_irq();
}
void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName) {

View File

@ -2,41 +2,6 @@
#include "main.h"
#include <furi.h>
const InputPin input_pins[] = {
{.port = BUTTON_UP_GPIO_Port,
.pin = BUTTON_UP_Pin,
.key = InputKeyUp,
.inverted = true,
.name = "Up"},
{.port = BUTTON_DOWN_GPIO_Port,
.pin = BUTTON_DOWN_Pin,
.key = InputKeyDown,
.inverted = true,
.name = "Down"},
{.port = BUTTON_RIGHT_GPIO_Port,
.pin = BUTTON_RIGHT_Pin,
.key = InputKeyRight,
.inverted = true,
.name = "Right"},
{.port = BUTTON_LEFT_GPIO_Port,
.pin = BUTTON_LEFT_Pin,
.key = InputKeyLeft,
.inverted = true,
.name = "Left"},
{.port = BUTTON_OK_GPIO_Port,
.pin = BUTTON_OK_Pin,
.key = InputKeyOk,
.inverted = false,
.name = "Ok"},
{.port = BUTTON_BACK_GPIO_Port,
.pin = BUTTON_BACK_Pin,
.key = InputKeyBack,
.inverted = true,
.name = "Back"},
};
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);
const GpioPin vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin};
const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_Pin};
@ -81,3 +46,21 @@ const GpioPin gpio_i2c_power_sda = {.port = GPIOA, .pin = LL_GPIO_PIN_10};
const GpioPin gpio_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9};
const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8};
const GpioPin gpio_button_up = {.port = GPIOB, .pin = LL_GPIO_PIN_10};
const GpioPin gpio_button_down = {.port = GPIOC, .pin = LL_GPIO_PIN_6};
const GpioPin gpio_button_right = {.port = GPIOB, .pin = LL_GPIO_PIN_12};
const GpioPin gpio_button_left = {.port = GPIOB, .pin = LL_GPIO_PIN_11};
const GpioPin gpio_button_ok = {.port = GPIOH, .pin = LL_GPIO_PIN_3};
const GpioPin gpio_button_back = {.port = GPIOC, .pin = LL_GPIO_PIN_13};
const InputPin input_pins[] = {
{.pin = &gpio_button_up, .key = InputKeyUp, .inverted = true, .name = "Up"},
{.pin = &gpio_button_down, .key = InputKeyDown, .inverted = true, .name = "Down"},
{.pin = &gpio_button_right, .key = InputKeyRight, .inverted = true, .name = "Right"},
{.pin = &gpio_button_left, .key = InputKeyLeft, .inverted = true, .name = "Left"},
{.pin = &gpio_button_ok, .key = InputKeyOk, .inverted = false, .name = "Ok"},
{.pin = &gpio_button_back, .key = InputKeyBack, .inverted = true, .name = "Back"},
};
const size_t input_pins_count = sizeof(input_pins) / sizeof(InputPin);

View File

@ -32,16 +32,12 @@ typedef enum {
} Light;
typedef struct {
const GPIO_TypeDef* port;
const uint16_t pin;
const GpioPin* pin;
const InputKey key;
const bool inverted;
const char* name;
} InputPin;
extern const InputPin input_pins[];
extern const size_t input_pins_count;
extern const GpioPin vibro_gpio;
extern const GpioPin ibutton_gpio;
@ -86,6 +82,10 @@ extern const GpioPin gpio_i2c_power_scl;
extern const GpioPin gpio_speaker;
// Input pins
extern const InputPin input_pins[];
extern const size_t input_pins_count;
#ifdef __cplusplus
}
#endif

View File

@ -13,7 +13,7 @@
#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_IRQ TIM2_IRQn
#define FURI_HAL_RFID_EMULATE_TIMER_IRQ FuriHalInterruptIdTIM2
#define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3
typedef struct {
@ -194,15 +194,7 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void*
furi_hal_rfid->callback = callback;
furi_hal_rfid->context = context;
// TODO make api for interrupts priority
for(size_t i = WWDG_IRQn; i <= DMAMUX1_OVR_IRQn; i++) {
HAL_NVIC_SetPriority(i, 15, 0);
}
furi_hal_interrupt_set_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, furi_hal_rfid_emulate_isr);
NVIC_SetPriority(
FURI_HAL_RFID_EMULATE_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(FURI_HAL_RFID_EMULATE_TIMER_IRQ);
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);
@ -212,7 +204,7 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void*
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_timer_isr(FURI_HAL_RFID_EMULATE_TIMER, NULL);
furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, NULL, NULL);
}
void furi_hal_rfid_tim_reset() {

View File

@ -722,9 +722,7 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void*
LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8);
// ISR setup
furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR);
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(TIM2_IRQn);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL);
// Interrupts and channels
LL_TIM_EnableIT_CC1(TIM2);
@ -750,7 +748,7 @@ void furi_hal_subghz_stop_async_rx() {
FURI_CRITICAL_ENTER();
LL_TIM_DeInit(TIM2);
FURI_CRITICAL_EXIT();
furi_hal_interrupt_set_timer_isr(TIM2, NULL);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);
}
@ -887,8 +885,7 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
dma_config.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP;
dma_config.Priority = LL_DMA_MODE_NORMAL;
LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config);
furi_hal_interrupt_set_dma_channel_isr(
DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, furi_hal_subghz_async_tx_dma_isr, NULL);
LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1);
@ -914,9 +911,7 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void*
LL_TIM_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2);
LL_TIM_DisableMasterSlaveMode(TIM2);
furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr);
NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0));
NVIC_EnableIRQ(TIM2_IRQn);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_async_tx_timer_isr, NULL);
LL_TIM_EnableIT_UPDATE(TIM2);
LL_TIM_EnableDMAReq_UPDATE(TIM2);
@ -953,11 +948,12 @@ void furi_hal_subghz_stop_async_tx() {
// Deinitialize Timer
FURI_CRITICAL_ENTER();
LL_TIM_DeInit(TIM2);
furi_hal_interrupt_set_timer_isr(TIM2, NULL);
furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL);
// Deinitialize DMA
LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1);
furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_1, NULL);
furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL);
// Deinitialize GPIO
hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow);

View File

@ -1,53 +0,0 @@
#include "furi_hal_task.h"
//-----------------------------cmsis_os2.c-------------------------------
// helpers to get isr context
// get arch
#ifndef __ARM_ARCH_6M__
#define __ARM_ARCH_6M__ 0
#endif
#ifndef __ARM_ARCH_7M__
#define __ARM_ARCH_7M__ 0
#endif
#ifndef __ARM_ARCH_7EM__
#define __ARM_ARCH_7EM__ 0
#endif
#ifndef __ARM_ARCH_8M_MAIN__
#define __ARM_ARCH_8M_MAIN__ 0
#endif
#ifndef __ARM_ARCH_7A__
#define __ARM_ARCH_7A__ 0
#endif
// get masks
#if((__ARM_ARCH_7M__ == 1U) || (__ARM_ARCH_7EM__ == 1U) || (__ARM_ARCH_8M_MAIN__ == 1U))
#define IS_IRQ_MASKED() ((__get_PRIMASK() != 0U) || (__get_BASEPRI() != 0U))
#elif(__ARM_ARCH_6M__ == 1U)
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#elif(__ARM_ARCH_7A__ == 1U)
/* CPSR mask bits */
#define CPSR_MASKBIT_I 0x80U
#define IS_IRQ_MASKED() ((__get_CPSR() & CPSR_MASKBIT_I) != 0U)
#else
#define IS_IRQ_MASKED() (__get_PRIMASK() != 0U)
#endif
// get is irq mode
#if(__ARM_ARCH_7A__ == 1U)
/* CPSR mode bitmasks */
#define CPSR_MODE_USER 0x10U
#define CPSR_MODE_SYSTEM 0x1FU
#define IS_IRQ_MODE() ((__get_mode() != CPSR_MODE_USER) && (__get_mode() != CPSR_MODE_SYSTEM))
#else
#define IS_IRQ_MODE() (__get_IPSR() != 0U)
#endif
// added osKernelGetState(), because KernelState is a static var
#define IS_IRQ() (IS_IRQ_MODE() || (IS_IRQ_MASKED() && (osKernelGetState() == osKernelRunning)))
//-------------------------end of cmsis_os2.c----------------------------
bool task_is_isr_context(void) {
return IS_IRQ();
}

View File

@ -1,12 +0,0 @@
#pragma once
#include "main.h"
#include <cmsis_os2.h>
#include <stdbool.h>
// Task stack size in bytes
#define DEFAULT_STACK_SIZE 4096
// Max system tasks count
#define MAX_TASK_COUNT 14
bool task_is_isr_context(void);

View File

@ -55,8 +55,6 @@ C_SOURCES += \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_cryp.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_gpio.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_hsem.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_ipcc.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \
$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.c \

View File

@ -22,7 +22,6 @@ template <unsigned int N> struct STOP_EXTERNING_ME {};
#include "furi_hal_gpio.h"
#include "furi_hal_light.h"
#include "furi_hal_delay.h"
#include "furi_hal_task.h"
#include "furi_hal_power.h"
#include "furi_hal_vcp.h"
#include "furi_hal_interrupt.h"

View File

@ -87,18 +87,11 @@ void platformUnprotectST25RComm();
#define platformUnprotectST25RIrqStatus() \
platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment */
#define platformGpioSet(port, pin) \
HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High */
#define platformGpioClear(port, pin) \
HAL_GPIO_WritePin( \
port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low */
#define platformGpioToogle(port, pin) \
HAL_GPIO_TogglePin(port, pin) /*!< Toogles the given GPIO */
#define platformGpioIsHigh(port, pin) \
(HAL_GPIO_ReadPin(port, pin) == \
GPIO_PIN_SET) /*!< Checks if the given LED is High */
#define platformGpioIsLow(port, pin) \
(!platformGpioIsHigh(port, pin)) /*!< Checks if the given LED is Low */
#define platformGpioSet(port, pin) LL_GPIO_SetOutputPin(port, pin)
#define platformGpioClear(port, pin) LL_GPIO_ResetOutputPin(port, pin)
#define platformGpioIsHigh(port, pin) LL_GPIO_IsInputPinSet(port, pin)
#define platformTimerCreate(t) \
timerCalculateTimer(t) /*!< Create a timer with the given time (ms) */