[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:
		
							parent
							
								
									bdba15b366
								
							
						
					
					
						commit
						489caa8e77
					
				| @ -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; | ||||
|  | ||||
| @ -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
									
								
							
							
						
						
									
										32
									
								
								core/furi/common_defines.h
									
									
									
									
									
										
										
										Executable file → Normal 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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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   */ | ||||
|  | ||||
| @ -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>© 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****/ | ||||
| @ -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); | ||||
| } | ||||
| @ -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(); | ||||
| } | ||||
| @ -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>© 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****/ | ||||
|  | ||||
| @ -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); | ||||
| 
 | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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(); | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
| } | ||||
|  | ||||
| @ -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) { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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() { | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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(); | ||||
| } | ||||
| @ -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); | ||||
| @ -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 \
 | ||||
|  | ||||
| @ -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" | ||||
|  | ||||
| @ -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)     */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく