[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" | #include "input_i.h" | ||||||
| 
 | 
 | ||||||
| #define GPIO_Read(input_pin)                                                    \ | #define GPIO_Read(input_pin) (hal_gpio_read(input_pin.pin->pin) ^ input_pin.pin->inverted) | ||||||
|     (HAL_GPIO_ReadPin((GPIO_TypeDef*)input_pin.pin->port, input_pin.pin->pin) ^ \ |  | ||||||
|      input_pin.pin->inverted) |  | ||||||
| 
 | 
 | ||||||
| static Input* input = NULL; | static Input* input = NULL; | ||||||
| 
 | 
 | ||||||
| @ -81,8 +79,7 @@ int32_t input_srv() { | |||||||
|     input->pin_states = malloc(input_pins_count * sizeof(InputPinState)); |     input->pin_states = malloc(input_pins_count * sizeof(InputPinState)); | ||||||
| 
 | 
 | ||||||
|     for(size_t i = 0; i < input_pins_count; i++) { |     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(input_pins[i].pin, input_isr, NULL); | ||||||
|         hal_gpio_add_int_callback(&gpio, input_isr, NULL); |  | ||||||
|         input->pin_states[i].pin = &input_pins[i]; |         input->pin_states[i].pin = &input_pins[i]; | ||||||
|         input->pin_states[i].state = GPIO_Read(input->pin_states[i]); |         input->pin_states[i].state = GPIO_Read(input->pin_states[i]); | ||||||
|         input->pin_states[i].debounce = INPUT_DEBOUNCE_TICKS_HALF; |         input->pin_states[i].debounce = INPUT_DEBOUNCE_TICKS_HALF; | ||||||
|  | |||||||
| @ -1,11 +1,12 @@ | |||||||
| #include "check.h" | #include "check.h" | ||||||
| #include "furi_hal_task.h" | #include "common_defines.h" | ||||||
|  | 
 | ||||||
| #include <furi_hal_console.h> | #include <furi_hal_console.h> | ||||||
| #include <furi_hal_rtc.h> | #include <furi_hal_rtc.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| 
 | 
 | ||||||
| void __furi_print_name() { | void __furi_print_name() { | ||||||
|     if(task_is_isr_context()) { |     if(FURI_IS_ISR()) { | ||||||
|         furi_hal_console_puts("[ISR] "); |         furi_hal_console_puts("[ISR] "); | ||||||
|     } else { |     } else { | ||||||
|         const char* name = osThreadGetName(osThreadGetId()); |         const char* name = osThreadGetName(osThreadGetId()); | ||||||
|  | |||||||
							
								
								
									
										34
									
								
								core/furi/common_defines.h
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										34
									
								
								core/furi/common_defines.h
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @ -1,5 +1,8 @@ | |||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
|  | #include <stdbool.h> | ||||||
|  | #include <cmsis_os2.h> | ||||||
|  | 
 | ||||||
| #ifndef MAX | #ifndef MAX | ||||||
| #define MAX(a, b)               \ | #define MAX(a, b)               \ | ||||||
|     ({                          \ |     ({                          \ | ||||||
| @ -75,12 +78,35 @@ | |||||||
| #define FURI_BIT(x, n) ((x) >> (n)&1) | #define FURI_BIT(x, n) ((x) >> (n)&1) | ||||||
| #endif | #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 | #ifndef FURI_CRITICAL_ENTER | ||||||
| #define FURI_CRITICAL_ENTER()               \ | #define FURI_CRITICAL_ENTER()                   \ | ||||||
|     uint32_t primask_bit = __get_PRIMASK(); \ |     uint32_t __isrm = 0;                        \ | ||||||
|     __disable_irq() |     bool __from_isr = FURI_IS_ISR();            \ | ||||||
|  |     if(__from_isr) {                            \ | ||||||
|  |         __isrm = taskENTER_CRITICAL_FROM_ISR(); \ | ||||||
|  |     } else {                                    \ | ||||||
|  |         taskENTER_CRITICAL();                   \ | ||||||
|  |     } | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #ifndef FURI_CRITICAL_EXIT | #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 | #endif | ||||||
|  | |||||||
| @ -41,7 +41,6 @@ | |||||||
| #include <stm32wbxx.h> | #include <stm32wbxx.h> | ||||||
| #include <furi_hal_console.h> | #include <furi_hal_console.h> | ||||||
| #include <furi/common_defines.h> | #include <furi/common_defines.h> | ||||||
| #include <furi_hal_task.h> |  | ||||||
| 
 | 
 | ||||||
| /* Defining MPU_WRAPPERS_INCLUDED_FROM_API_FILE prevents task.h from redefining
 | /* 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 | all the API functions to use the MPU wrappers.  That should only be done when | ||||||
|  | |||||||
| @ -5,117 +5,112 @@ extern "C" { | |||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| #include "stm32wbxx_hal.h" | #include "stm32wbxx_hal.h" | ||||||
|  | #include "stm32wbxx_ll_gpio.h" | ||||||
| 
 | 
 | ||||||
| void Error_Handler(void); | void Error_Handler(void); | ||||||
| 
 | 
 | ||||||
| #define BUTTON_BACK_EXTI_IRQn EXTI15_10_IRQn |  | ||||||
| #define BUTTON_BACK_GPIO_Port GPIOC | #define BUTTON_BACK_GPIO_Port GPIOC | ||||||
| #define BUTTON_BACK_Pin GPIO_PIN_13 | #define BUTTON_BACK_Pin LL_GPIO_PIN_13 | ||||||
| #define BUTTON_DOWN_EXTI_IRQn EXTI6_IRQn |  | ||||||
| #define BUTTON_DOWN_GPIO_Port GPIOC | #define BUTTON_DOWN_GPIO_Port GPIOC | ||||||
| #define BUTTON_DOWN_Pin GPIO_PIN_6 | #define BUTTON_DOWN_Pin LL_GPIO_PIN_6 | ||||||
| #define BUTTON_LEFT_EXTI_IRQn EXTI15_10_IRQn |  | ||||||
| #define BUTTON_LEFT_GPIO_Port GPIOB | #define BUTTON_LEFT_GPIO_Port GPIOB | ||||||
| #define BUTTON_LEFT_Pin GPIO_PIN_11 | #define BUTTON_LEFT_Pin LL_GPIO_PIN_11 | ||||||
| #define BUTTON_OK_EXTI_IRQn EXTI3_IRQn |  | ||||||
| #define BUTTON_OK_GPIO_Port GPIOH | #define BUTTON_OK_GPIO_Port GPIOH | ||||||
| #define BUTTON_OK_Pin GPIO_PIN_3 | #define BUTTON_OK_Pin LL_GPIO_PIN_3 | ||||||
| #define BUTTON_RIGHT_EXTI_IRQn EXTI15_10_IRQn |  | ||||||
| #define BUTTON_RIGHT_GPIO_Port GPIOB | #define BUTTON_RIGHT_GPIO_Port GPIOB | ||||||
| #define BUTTON_RIGHT_Pin GPIO_PIN_12 | #define BUTTON_RIGHT_Pin LL_GPIO_PIN_12 | ||||||
| #define BUTTON_UP_EXTI_IRQn EXTI15_10_IRQn |  | ||||||
| #define BUTTON_UP_GPIO_Port GPIOB | #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_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_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_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_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_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_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_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_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_GPIO_Port GPIOA | ||||||
| #define PA4_Pin GPIO_PIN_4 | #define PA4_Pin LL_GPIO_PIN_4 | ||||||
| #define PA6_GPIO_Port GPIOA | #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_GPIO_Port GPIOA | ||||||
| #define PA7_Pin GPIO_PIN_7 | #define PA7_Pin LL_GPIO_PIN_7 | ||||||
| #define PB2_GPIO_Port GPIOB | #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_GPIO_Port GPIOB | ||||||
| #define PB3_Pin GPIO_PIN_3 | #define PB3_Pin LL_GPIO_PIN_3 | ||||||
| #define PC0_GPIO_Port GPIOC | #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_GPIO_Port GPIOC | ||||||
| #define PC1_Pin GPIO_PIN_1 | #define PC1_Pin LL_GPIO_PIN_1 | ||||||
| #define PC3_GPIO_Port GPIOC | #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_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_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_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_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_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_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_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_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_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_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_GPIO_Port GPIOB | ||||||
| #define SPEAKER_Pin GPIO_PIN_8 | #define SPEAKER_Pin LL_GPIO_PIN_8 | ||||||
| 
 | 
 | ||||||
| #define VIBRO_GPIO_Port GPIOA | #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_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_TX_Port GPIOB | ||||||
| #define USART1_RX_Pin GPIO_PIN_7 | #define USART1_RX_Pin LL_GPIO_PIN_7 | ||||||
| #define USART1_RX_Port GPIOB | #define USART1_RX_Port GPIOB | ||||||
| 
 | 
 | ||||||
| #define SPI_D_MISO_GPIO_Port GPIOC | #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_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_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_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_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_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_Pin RFID_PULL_Pin | ||||||
| #define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port | #define NFC_IRQ_GPIO_Port RFID_PULL_GPIO_Port | ||||||
|  | |||||||
| @ -37,7 +37,7 @@ extern "C" { | |||||||
| #define HAL_CRYP_MODULE_ENABLED | #define HAL_CRYP_MODULE_ENABLED | ||||||
| /*#define HAL_COMP_MODULE_ENABLED   */ | /*#define HAL_COMP_MODULE_ENABLED   */ | ||||||
| /*#define HAL_CRC_MODULE_ENABLED    */ | /*#define HAL_CRC_MODULE_ENABLED    */ | ||||||
| #define HAL_HSEM_MODULE_ENABLED | /*#define HAL_HSEM_MODULE_ENABLED   */ | ||||||
| /*#define HAL_I2C_MODULE_ENABLED    */ | /*#define HAL_I2C_MODULE_ENABLED    */ | ||||||
| /*#define HAL_IPCC_MODULE_ENABLED   */ | /*#define HAL_IPCC_MODULE_ENABLED   */ | ||||||
| /*#define HAL_IRDA_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" | #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
 | /*!< Uncomment the following line if you need to relocate your vector Table in
 | ||||||
|      Internal SRAM. */ |      Internal SRAM. */ | ||||||
| /* #define VECT_TAB_SRAM */ | /* #define VECT_TAB_SRAM */ | ||||||
| @ -131,21 +10,7 @@ | |||||||
| #define VECT_TAB_BASE_ADDRESS \ | #define VECT_TAB_BASE_ADDRESS \ | ||||||
|     SRAM1_BASE /*!< Vector Table base offset field.
 |     SRAM1_BASE /*!< Vector Table base offset field.
 | ||||||
|                                                      This value must be a multiple of 0x200. */ |                                                      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:
 | /* The SystemCoreClock variable is updated in three ways:
 | ||||||
|       1) by calling CMSIS function SystemCoreClockUpdate() |       1) by calling CMSIS function SystemCoreClockUpdate() | ||||||
|       2) by calling HAL API function HAL_RCC_GetHCLKFreq() |       2) by calling HAL API function HAL_RCC_GetHCLKFreq() | ||||||
| @ -179,30 +44,6 @@ const uint32_t MSIRangeTable[16UL] = { | |||||||
|     0UL, |     0UL, | ||||||
|     0UL}; /* 0UL values are incorrect cases */ |     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. |   * @brief  Setup the microcontroller system. | ||||||
|   * @param  None |   * @param  None | ||||||
| @ -254,118 +95,3 @@ void SystemInit(void) { | |||||||
|     /* Disable all interrupts */ |     /* Disable all interrupts */ | ||||||
|     RCC->CIER = 0x00000000; |     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 "cmsis_compiler.h" | ||||||
| #include "string.h" | #include "string.h" | ||||||
|  | #include <furi.h> | ||||||
| 
 | 
 | ||||||
| /******************************************************************************
 | /******************************************************************************
 | ||||||
|  * common |  * common | ||||||
|  ******************************************************************************/ |  ******************************************************************************/ | ||||||
| #define UTILS_ENTER_CRITICAL_SECTION()      \ | #define UTILS_ENTER_CRITICAL_SECTION() FURI_CRITICAL_ENTER() | ||||||
|     uint32_t primask_bit = __get_PRIMASK(); \ |  | ||||||
|     __disable_irq() |  | ||||||
| 
 | 
 | ||||||
| #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); | #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
 |     // Explicitly tell that we are in charge of CLK48 domain
 | ||||||
|     if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { |     if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { | ||||||
|         HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); |         furi_assert(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Start Core2
 |     // Start Core2
 | ||||||
| @ -124,8 +124,8 @@ bool furi_hal_bt_start_radio_stack() { | |||||||
|     osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever); |     osMutexAcquire(furi_hal_bt_core2_mtx, osWaitForever); | ||||||
| 
 | 
 | ||||||
|     // Explicitly tell that we are in charge of CLK48 domain
 |     // Explicitly tell that we are in charge of CLK48 domain
 | ||||||
|     if(!HAL_HSEM_IsSemTaken(CFG_HW_CLK48_CONFIG_SEMID)) { |     if(!LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_CLK48_CONFIG_SEMID)) { | ||||||
|         HAL_HSEM_FastTake(CFG_HW_CLK48_CONFIG_SEMID); |         furi_assert(LL_HSEM_1StepLock(HSEM, CFG_HW_CLK48_CONFIG_SEMID) == 0); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     do { |     do { | ||||||
| @ -283,13 +283,13 @@ void furi_hal_bt_set_key_storage_change_callback( | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_hal_bt_nvm_sram_sem_acquire() { | void furi_hal_bt_nvm_sram_sem_acquire() { | ||||||
|     while(HAL_HSEM_FastTake(CFG_HW_BLE_NVM_SRAM_SEMID) != HAL_OK) { |     while(LL_HSEM_1StepLock(HSEM, CFG_HW_BLE_NVM_SRAM_SEMID)) { | ||||||
|         osDelay(1); |         osThreadYield(); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_hal_bt_nvm_sram_sem_release() { | 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() { | 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) { | static void furi_hal_flash_begin_with_core2(bool erase_flag) { | ||||||
|     // Take flash controller ownership
 |     // Take flash controller ownership
 | ||||||
|     while(HAL_HSEM_FastTake(CFG_HW_FLASH_SEMID) != HAL_OK) { |     while(LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID) != 0) { | ||||||
|         taskYIELD(); |         osThreadYield(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Unlock flash operation
 |     // Unlock flash operation
 | ||||||
| @ -97,27 +97,35 @@ static void furi_hal_flash_begin_with_core2(bool erase_flag) { | |||||||
|     // Erase activity notification
 |     // Erase activity notification
 | ||||||
|     if(erase_flag) SHCI_C2_FLASH_EraseActivity(ERASE_ACTIVITY_ON); |     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) { |     while(true) { | ||||||
|         // Wait till flash controller become usable
 |         // Wait till flash controller become usable
 | ||||||
|         while(LL_FLASH_IsActiveFlag_OperationSuspended()) { |         while(LL_FLASH_IsActiveFlag_OperationSuspended()) { | ||||||
|             taskYIELD(); |             osThreadYield(); | ||||||
|         }; |         }; | ||||||
| 
 | 
 | ||||||
|         // Just a little more love
 |         // Just a little more love
 | ||||||
|         taskENTER_CRITICAL(); |         taskENTER_CRITICAL(); | ||||||
| 
 | 
 | ||||||
|         // Actually we already have mutex for it, but specification is specification
 |         // 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(); |             taskEXIT_CRITICAL(); | ||||||
|             continue; |             continue; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Take sempahopre and prevent core2 from anyting funky
 |         //
 | ||||||
|         if(!HAL_HSEM_IsSemTaken(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) { |         if(LL_HSEM_IsSemaphoreLocked(HSEM, CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID)) { | ||||||
|             if(HAL_HSEM_FastTake(CFG_HW_BLOCK_FLASH_REQ_BY_CPU2_SEMID) != HAL_OK) { |             taskEXIT_CRITICAL(); | ||||||
|                 taskEXIT_CRITICAL(); |             continue; | ||||||
|                 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; |         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) { | static void furi_hal_flash_end_with_core2(bool erase_flag) { | ||||||
|     // Funky ops are ok at this point
 |     // 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
 |     // Task switching is ok
 | ||||||
|     taskEXIT_CRITICAL(); |     taskEXIT_CRITICAL(); | ||||||
| 
 | 
 | ||||||
|     // Doesn't make much sense, does it?
 |     // Doesn't make much sense, does it?
 | ||||||
|     while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { |     while(__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) { | ||||||
|         taskYIELD(); |         osThreadYield(); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Erase activity over, core2 can continue
 |     // 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(); |     furi_hal_flash_lock(); | ||||||
| 
 | 
 | ||||||
|     // Release flash controller ownership
 |     // 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) { | static void furi_hal_flash_end(bool erase_flag) { | ||||||
|  | |||||||
| @ -8,7 +8,7 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| 
 | 
 | ||||||
| #define FURI_HAL_IBUTTON_TIMER TIM1 | #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 { | typedef enum { | ||||||
|     FuriHalIbuttonStateIdle, |     FuriHalIbuttonStateIdle, | ||||||
| @ -50,10 +50,7 @@ void furi_hal_ibutton_emulate_start( | |||||||
|     LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); |     LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); | ||||||
|     FURI_CRITICAL_EXIT(); |     FURI_CRITICAL_EXIT(); | ||||||
| 
 | 
 | ||||||
|     furi_hal_interrupt_set_timer_isr(FURI_HAL_IBUTTON_TIMER, furi_hal_ibutton_emulate_isr); |     furi_hal_interrupt_set_isr(FURI_HAL_IBUTTON_TIMER_IRQ, furi_hal_ibutton_emulate_isr, NULL); | ||||||
|     NVIC_SetPriority( |  | ||||||
|         FURI_HAL_IBUTTON_TIMER_IRQ, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); |  | ||||||
|     NVIC_EnableIRQ(FURI_HAL_IBUTTON_TIMER_IRQ); |  | ||||||
| 
 | 
 | ||||||
|     LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0); |     LL_TIM_SetPrescaler(FURI_HAL_IBUTTON_TIMER, 0); | ||||||
|     LL_TIM_SetCounterMode(FURI_HAL_IBUTTON_TIMER, LL_TIM_COUNTERMODE_UP); |     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); |         LL_TIM_DeInit(FURI_HAL_IBUTTON_TIMER); | ||||||
|         FURI_CRITICAL_EXIT(); |         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->callback = NULL; | ||||||
|         furi_hal_ibutton->context = 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_SetActiveInput(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ACTIVEINPUT_INDIRECTTI); | ||||||
|     LL_TIM_IC_SetPrescaler(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_ICPSC_DIV1); |     LL_TIM_IC_SetPrescaler(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; |     furi_hal_infrared_state = InfraredStateAsyncRx; | ||||||
| 
 | 
 | ||||||
|     LL_TIM_EnableIT_CC1(TIM2); |     LL_TIM_EnableIT_CC1(TIM2); | ||||||
| @ -176,9 +176,6 @@ void furi_hal_infrared_async_rx_start(void) { | |||||||
| 
 | 
 | ||||||
|     LL_TIM_SetCounter(TIM2, 0); |     LL_TIM_SetCounter(TIM2, 0); | ||||||
|     LL_TIM_EnableCounter(TIM2); |     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) { | void furi_hal_infrared_async_rx_stop(void) { | ||||||
| @ -187,7 +184,7 @@ void furi_hal_infrared_async_rx_stop(void) { | |||||||
|     FURI_CRITICAL_ENTER(); |     FURI_CRITICAL_ENTER(); | ||||||
| 
 | 
 | ||||||
|     LL_TIM_DeInit(TIM2); |     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_hal_infrared_state = InfraredStateIdle; | ||||||
| 
 | 
 | ||||||
|     FURI_CRITICAL_EXIT(); |     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.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; | ||||||
|     dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; |     dma_config.Priority = LL_DMA_PRIORITY_VERYHIGH; | ||||||
|     LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); |     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_TE1(DMA1); | ||||||
|     LL_DMA_ClearFlag_TC1(DMA1); |     LL_DMA_ClearFlag_TC1(DMA1); | ||||||
|  | 
 | ||||||
|     LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); |     LL_DMA_EnableIT_TE(DMA1, LL_DMA_CHANNEL_1); | ||||||
|     LL_DMA_EnableIT_TC(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)); |     furi_hal_interrupt_set_isr_ex( | ||||||
|     NVIC_EnableIRQ(DMA1_Channel1_IRQn); |         FuriHalInterruptIdDma1Ch1, 4, furi_hal_infrared_tx_dma_polarity_isr, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { | static void furi_hal_infrared_configure_tim_rcr_dma_tx(void) { | ||||||
| @ -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.PeriphRequest = LL_DMAMUX_REQ_TIM1_UP; | ||||||
|     dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; |     dma_config.Priority = LL_DMA_PRIORITY_MEDIUM; | ||||||
|     LL_DMA_Init(DMA1, LL_DMA_CHANNEL_2, &dma_config); |     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_TC2(DMA1); | ||||||
|     LL_DMA_ClearFlag_HT2(DMA1); |     LL_DMA_ClearFlag_HT2(DMA1); | ||||||
|     LL_DMA_ClearFlag_TE2(DMA1); |     LL_DMA_ClearFlag_TE2(DMA1); | ||||||
|  | 
 | ||||||
|     LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2); |     LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_2); | ||||||
|     LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_2); |     LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_2); | ||||||
|     LL_DMA_EnableIT_TE(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)); |     furi_hal_interrupt_set_isr_ex( | ||||||
|     NVIC_EnableIRQ(DMA1_Channel2_IRQn); |         FuriHalInterruptIdDma1Ch2, 5, furi_hal_infrared_tx_dma_isr, NULL); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) { | static void furi_hal_infrared_tx_fill_buffer_last(uint8_t buf_num) { | ||||||
| @ -551,8 +549,8 @@ static void furi_hal_infrared_async_tx_free_resources(void) { | |||||||
|     osStatus_t status; |     osStatus_t status; | ||||||
| 
 | 
 | ||||||
|     hal_gpio_init(&gpio_infrared_tx, GpioModeOutputOpenDrain, GpioPullDown, GpioSpeedLow); |     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_isr(FuriHalInterruptIdDma1Ch1, NULL, NULL); | ||||||
|     furi_hal_interrupt_set_dma_channel_isr(DMA1, LL_DMA_CHANNEL_2, NULL); |     furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch2, NULL, NULL); | ||||||
|     LL_TIM_DeInit(TIM1); |     LL_TIM_DeInit(TIM1); | ||||||
| 
 | 
 | ||||||
|     status = osSemaphoreDelete(infrared_tim_tx.stop_semaphore); |     status = osSemaphoreDelete(infrared_tim_tx.stop_semaphore); | ||||||
|  | |||||||
| @ -3,153 +3,201 @@ | |||||||
| #include <furi.h> | #include <furi.h> | ||||||
| #include <main.h> | #include <main.h> | ||||||
| 
 | 
 | ||||||
|  | #include <stm32wbxx.h> | ||||||
| #include <stm32wbxx_ll_tim.h> | #include <stm32wbxx_ll_tim.h> | ||||||
| 
 | 
 | ||||||
| #define TAG "FuriHalInterrupt" | #define TAG "FuriHalInterrupt" | ||||||
| 
 | 
 | ||||||
| volatile FuriHalInterruptISR furi_hal_tim_tim2_isr = NULL; | #define FURI_HAL_INTERRUPT_DEFAULT_PRIORITY 5 | ||||||
| volatile FuriHalInterruptISR furi_hal_tim_tim1_isr = NULL; |  | ||||||
| 
 | 
 | ||||||
| #define FURI_HAL_INTERRUPT_DMA_COUNT 2 | typedef struct { | ||||||
| #define FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT 8 |     FuriHalInterruptISR isr; | ||||||
|  |     void* context; | ||||||
|  | } FuriHalInterruptISRPair; | ||||||
| 
 | 
 | ||||||
| volatile FuriHalInterruptISR furi_hal_dma_channel_isr[FURI_HAL_INTERRUPT_DMA_COUNT] | FuriHalInterruptISRPair furi_hal_interrupt_isr[FuriHalInterruptIdMax] = {0}; | ||||||
|                                                      [FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT] = {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() { | void furi_hal_interrupt_init() { | ||||||
|     NVIC_SetPriority(RCC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); |  | ||||||
|     NVIC_EnableIRQ(RCC_IRQn); |  | ||||||
| 
 |  | ||||||
|     NVIC_SetPriority( |     NVIC_SetPriority( | ||||||
|         TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); |         TAMP_STAMP_LSECSS_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0)); | ||||||
|     NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); |     NVIC_EnableIRQ(TAMP_STAMP_LSECSS_IRQn); | ||||||
| 
 | 
 | ||||||
|     NVIC_SetPriority(DMA1_Channel1_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); |     NVIC_SetPriority(PendSV_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 15, 0)); | ||||||
|     NVIC_EnableIRQ(DMA1_Channel1_IRQn); | 
 | ||||||
|  |     NVIC_SetPriority(HSEM_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); | ||||||
|  |     HAL_NVIC_EnableIRQ(HSEM_IRQn); | ||||||
| 
 | 
 | ||||||
|     FURI_LOG_I(TAG, "Init OK"); |     FURI_LOG_I(TAG, "Init OK"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void furi_hal_interrupt_set_timer_isr(TIM_TypeDef* timer, FuriHalInterruptISR isr) { | void furi_hal_interrupt_set_isr(FuriHalInterruptId index, FuriHalInterruptISR isr, void* context) { | ||||||
|     if(timer == TIM2) { |     furi_hal_interrupt_set_isr_ex(index, FURI_HAL_INTERRUPT_DEFAULT_PRIORITY, isr, context); | ||||||
|         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_dma_channel_isr( | void furi_hal_interrupt_set_isr_ex( | ||||||
|     DMA_TypeDef* dma, |     FuriHalInterruptId index, | ||||||
|     uint32_t channel, |     uint16_t priority, | ||||||
|     FuriHalInterruptISR isr) { |     FuriHalInterruptISR isr, | ||||||
|     --channel; // Pascal
 |     void* context) { | ||||||
|     furi_check(dma); |     furi_assert(index < FuriHalInterruptIdMax); | ||||||
|     furi_check(channel < FURI_HAL_INTERRUPT_DMA_CHANNELS_COUNT); |     furi_assert(priority < 15); | ||||||
|     if(dma == DMA1) { |     furi_assert(furi_hal_interrupt_irqn[index]); | ||||||
|         furi_hal_dma_channel_isr[0][channel] = isr; | 
 | ||||||
|     } else if(dma == DMA2) { |     if(isr) { | ||||||
|         furi_hal_dma_channel_isr[1][channel] = isr; |         // Pre ISR set
 | ||||||
|  |         furi_assert(furi_hal_interrupt_isr[index].isr == NULL); | ||||||
|     } else { |     } 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 */ | /* Timer 2 */ | ||||||
| void TIM2_IRQHandler(void) { | void TIM2_IRQHandler(void) { | ||||||
|     if(furi_hal_tim_tim2_isr) { |     furi_hal_interrupt_call(FuriHalInterruptIdTIM2); | ||||||
|         furi_hal_tim_tim2_isr(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* Timer 1 Update */ | /* Timer 1 Update */ | ||||||
| void TIM1_UP_TIM16_IRQHandler(void) { | void TIM1_UP_TIM16_IRQHandler(void) { | ||||||
|     if(furi_hal_tim_tim1_isr) { |     furi_hal_interrupt_call(FuriHalInterruptIdTim1UpTim16); | ||||||
|         furi_hal_tim_tim1_isr(); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TIM1_TRG_COM_TIM17_IRQHandler(void) { | void TIM1_TRG_COM_TIM17_IRQHandler(void) { | ||||||
|  |     furi_hal_interrupt_call(FuriHalInterruptIdTim1TrgComTim17); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TIM1_CC_IRQHandler(void) { | void TIM1_CC_IRQHandler(void) { | ||||||
|  |     furi_hal_interrupt_call(FuriHalInterruptIdTim1Cc); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* DMA 1 */ | /* DMA 1 */ | ||||||
| void DMA1_Channel1_IRQHandler(void) { | 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) { | 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) { | 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) { | 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) { | 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) { | 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) { | void DMA1_Channel7_IRQHandler(void) { | ||||||
|     if(furi_hal_dma_channel_isr[0][6]) furi_hal_dma_channel_isr[0][6](); |     furi_hal_interrupt_call(FuriHalInterruptIdDma1Ch7); | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void DMA1_Channel8_IRQHandler(void) { |  | ||||||
|     if(furi_hal_dma_channel_isr[0][7]) furi_hal_dma_channel_isr[0][7](); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* DMA 2 */ | /* DMA 2 */ | ||||||
| void DMA2_Channel1_IRQHandler(void) { | 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) { | 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) { | 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) { | 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) { | 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) { | 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) { | 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) { | void HSEM_IRQHandler(void) { | ||||||
|     if(furi_hal_dma_channel_isr[1][7]) furi_hal_dma_channel_isr[1][7](); |     furi_hal_interrupt_call(FuriHalInterruptIdHsem); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void TAMP_STAMP_LSECSS_IRQHandler(void) { | void TAMP_STAMP_LSECSS_IRQHandler(void) { | ||||||
| @ -165,6 +213,7 @@ void TAMP_STAMP_LSECSS_IRQHandler(void) { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void RCC_IRQHandler(void) { | void RCC_IRQHandler(void) { | ||||||
|  |     furi_hal_interrupt_call(FuriHalInterruptIdRcc); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void NMI_Handler(void) { | void NMI_Handler(void) { | ||||||
| @ -193,3 +242,26 @@ void UsageFault_Handler(void) { | |||||||
| 
 | 
 | ||||||
| void DebugMon_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 | #endif | ||||||
| 
 | 
 | ||||||
| /** Timer ISR */ | /** 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 */ | /** Initialize interrupt subsystem */ | ||||||
| void furi_hal_interrupt_init(); | 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. |  * We don't clear interrupt flags for you, do it by your self. | ||||||
|  * @param dma - DMA instance |  * @param index - interrupt ID | ||||||
|  * @param channel - DMA channel |  | ||||||
|  * @param isr - your interrupt service routine or use NULL to clear |  * @param isr - your interrupt service routine or use NULL to clear | ||||||
|  |  * @param context - isr context | ||||||
|  */ |  */ | ||||||
| void furi_hal_interrupt_set_dma_channel_isr( | void furi_hal_interrupt_set_isr(FuriHalInterruptId index, FuriHalInterruptISR isr, void* context); | ||||||
|     DMA_TypeDef* dma, |  | ||||||
|     uint32_t channel, |  | ||||||
|     FuriHalInterruptISR isr); |  | ||||||
| 
 | 
 | ||||||
| /** Set Timer ISR
 | /** Set ISR and enable interrupt with custom priority
 | ||||||
|  * By default ISR is serviced by ST HAL. Use this function to override it. |  | ||||||
|  * We don't clear interrupt flags for you, do it by your self. |  * 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 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 | #ifdef __cplusplus | ||||||
| } | } | ||||||
|  | |||||||
| @ -115,11 +115,11 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Stop IRQ handling, no one should disturb us till we finish
 |     // Stop IRQ handling, no one should disturb us till we finish
 | ||||||
|     FURI_CRITICAL_ENTER(); |     __disable_irq(); | ||||||
| 
 | 
 | ||||||
|     // Confirm OS that sleep is still possible
 |     // Confirm OS that sleep is still possible
 | ||||||
|     if(eTaskConfirmSleepModeStatus() == eAbortSleep) { |     if(eTaskConfirmSleepModeStatus() == eAbortSleep) { | ||||||
|         FURI_CRITICAL_EXIT(); |         __enable_irq(); | ||||||
|         return; |         return; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
| @ -136,7 +136,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // Reenable IRQ
 |     // Reenable IRQ
 | ||||||
|     FURI_CRITICAL_EXIT(); |     __enable_irq(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName) { | void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName) { | ||||||
|  | |||||||
| @ -2,41 +2,6 @@ | |||||||
| #include "main.h" | #include "main.h" | ||||||
| #include <furi.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 vibro_gpio = {.port = VIBRO_GPIO_Port, .pin = VIBRO_Pin}; | ||||||
| const GpioPin ibutton_gpio = {.port = iBTN_GPIO_Port, .pin = iBTN_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_i2c_power_scl = {.port = GPIOA, .pin = LL_GPIO_PIN_9}; | ||||||
| 
 | 
 | ||||||
| const GpioPin gpio_speaker = {.port = GPIOB, .pin = LL_GPIO_PIN_8}; | 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; | } Light; | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
|     const GPIO_TypeDef* port; |     const GpioPin* pin; | ||||||
|     const uint16_t pin; |  | ||||||
|     const InputKey key; |     const InputKey key; | ||||||
|     const bool inverted; |     const bool inverted; | ||||||
|     const char* name; |     const char* name; | ||||||
| } InputPin; | } InputPin; | ||||||
| 
 | 
 | ||||||
| extern const InputPin input_pins[]; |  | ||||||
| extern const size_t input_pins_count; |  | ||||||
| 
 |  | ||||||
| extern const GpioPin vibro_gpio; | extern const GpioPin vibro_gpio; | ||||||
| extern const GpioPin ibutton_gpio; | extern const GpioPin ibutton_gpio; | ||||||
| 
 | 
 | ||||||
| @ -86,6 +82,10 @@ extern const GpioPin gpio_i2c_power_scl; | |||||||
| 
 | 
 | ||||||
| extern const GpioPin gpio_speaker; | extern const GpioPin gpio_speaker; | ||||||
| 
 | 
 | ||||||
|  | // Input pins
 | ||||||
|  | extern const InputPin input_pins[]; | ||||||
|  | extern const size_t input_pins_count; | ||||||
|  | 
 | ||||||
| #ifdef __cplusplus | #ifdef __cplusplus | ||||||
| } | } | ||||||
| #endif | #endif | ||||||
|  | |||||||
| @ -13,7 +13,7 @@ | |||||||
| #define FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG LL_TIM_CHANNEL_CH1 | #define FURI_HAL_RFID_READ_TIMER_CHANNEL_CONFIG LL_TIM_CHANNEL_CH1 | ||||||
| 
 | 
 | ||||||
| #define FURI_HAL_RFID_EMULATE_TIMER TIM2 | #define FURI_HAL_RFID_EMULATE_TIMER TIM2 | ||||||
| #define FURI_HAL_RFID_EMULATE_TIMER_IRQ TIM2_IRQn | #define FURI_HAL_RFID_EMULATE_TIMER_IRQ FuriHalInterruptIdTIM2 | ||||||
| #define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3 | #define FURI_HAL_RFID_EMULATE_TIMER_CHANNEL LL_TIM_CHANNEL_CH3 | ||||||
| 
 | 
 | ||||||
| typedef struct { | typedef struct { | ||||||
| @ -194,15 +194,7 @@ void furi_hal_rfid_tim_emulate_start(FuriHalRfidEmulateCallback callback, void* | |||||||
|     furi_hal_rfid->callback = callback; |     furi_hal_rfid->callback = callback; | ||||||
|     furi_hal_rfid->context = context; |     furi_hal_rfid->context = context; | ||||||
| 
 | 
 | ||||||
|     // TODO make api for interrupts priority
 |     furi_hal_interrupt_set_isr(FURI_HAL_RFID_EMULATE_TIMER_IRQ, furi_hal_rfid_emulate_isr, NULL); | ||||||
|     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); |  | ||||||
| 
 | 
 | ||||||
|     LL_TIM_EnableIT_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); |     LL_TIM_EnableIT_UPDATE(FURI_HAL_RFID_EMULATE_TIMER); | ||||||
|     LL_TIM_EnableAllOutputs(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() { | void furi_hal_rfid_tim_emulate_stop() { | ||||||
|     LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER); |     LL_TIM_DisableCounter(FURI_HAL_RFID_EMULATE_TIMER); | ||||||
|     LL_TIM_DisableAllOutputs(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() { | 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); |     LL_TIM_IC_SetFilter(TIM2, LL_TIM_CHANNEL_CH2, LL_TIM_IC_FILTER_FDIV32_N8); | ||||||
| 
 | 
 | ||||||
|     // ISR setup
 |     // ISR setup
 | ||||||
|     furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_capture_ISR); |     furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_capture_ISR, NULL); | ||||||
|     NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); |  | ||||||
|     NVIC_EnableIRQ(TIM2_IRQn); |  | ||||||
| 
 | 
 | ||||||
|     // Interrupts and channels
 |     // Interrupts and channels
 | ||||||
|     LL_TIM_EnableIT_CC1(TIM2); |     LL_TIM_EnableIT_CC1(TIM2); | ||||||
| @ -750,7 +748,7 @@ void furi_hal_subghz_stop_async_rx() { | |||||||
|     FURI_CRITICAL_ENTER(); |     FURI_CRITICAL_ENTER(); | ||||||
|     LL_TIM_DeInit(TIM2); |     LL_TIM_DeInit(TIM2); | ||||||
|     FURI_CRITICAL_EXIT(); |     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); |     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.PeriphRequest = LL_DMAMUX_REQ_TIM2_UP; | ||||||
|     dma_config.Priority = LL_DMA_MODE_NORMAL; |     dma_config.Priority = LL_DMA_MODE_NORMAL; | ||||||
|     LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); |     LL_DMA_Init(DMA1, LL_DMA_CHANNEL_1, &dma_config); | ||||||
|     furi_hal_interrupt_set_dma_channel_isr( |     furi_hal_interrupt_set_isr(FuriHalInterruptIdDma1Ch1, furi_hal_subghz_async_tx_dma_isr, NULL); | ||||||
|         DMA1, LL_DMA_CHANNEL_1, furi_hal_subghz_async_tx_dma_isr); |  | ||||||
|     LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); |     LL_DMA_EnableIT_TC(DMA1, LL_DMA_CHANNEL_1); | ||||||
|     LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); |     LL_DMA_EnableIT_HT(DMA1, LL_DMA_CHANNEL_1); | ||||||
|     LL_DMA_EnableChannel(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_OC_DisableFast(TIM2, LL_TIM_CHANNEL_CH2); | ||||||
|     LL_TIM_DisableMasterSlaveMode(TIM2); |     LL_TIM_DisableMasterSlaveMode(TIM2); | ||||||
| 
 | 
 | ||||||
|     furi_hal_interrupt_set_timer_isr(TIM2, furi_hal_subghz_async_tx_timer_isr); |     furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, furi_hal_subghz_async_tx_timer_isr, NULL); | ||||||
|     NVIC_SetPriority(TIM2_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); |  | ||||||
|     NVIC_EnableIRQ(TIM2_IRQn); |  | ||||||
| 
 | 
 | ||||||
|     LL_TIM_EnableIT_UPDATE(TIM2); |     LL_TIM_EnableIT_UPDATE(TIM2); | ||||||
|     LL_TIM_EnableDMAReq_UPDATE(TIM2); |     LL_TIM_EnableDMAReq_UPDATE(TIM2); | ||||||
| @ -953,11 +948,12 @@ void furi_hal_subghz_stop_async_tx() { | |||||||
|     // Deinitialize Timer
 |     // Deinitialize Timer
 | ||||||
|     FURI_CRITICAL_ENTER(); |     FURI_CRITICAL_ENTER(); | ||||||
|     LL_TIM_DeInit(TIM2); |     LL_TIM_DeInit(TIM2); | ||||||
|     furi_hal_interrupt_set_timer_isr(TIM2, NULL); |     furi_hal_interrupt_set_isr(FuriHalInterruptIdTIM2, NULL, NULL); | ||||||
| 
 | 
 | ||||||
|     // Deinitialize DMA
 |     // Deinitialize DMA
 | ||||||
|     LL_DMA_DeInit(DMA1, LL_DMA_CHANNEL_1); |     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
 |     // Deinitialize GPIO
 | ||||||
|     hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); |     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_cryp.c \
 | ||||||
| 	$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_exti.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_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.c \
 | ||||||
| 	$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \
 | 	$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pcd_ex.c \
 | ||||||
| 	$(CUBE_DIR)/Drivers/STM32WBxx_HAL_Driver/Src/stm32wbxx_hal_pwr.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_gpio.h" | ||||||
| #include "furi_hal_light.h" | #include "furi_hal_light.h" | ||||||
| #include "furi_hal_delay.h" | #include "furi_hal_delay.h" | ||||||
| #include "furi_hal_task.h" |  | ||||||
| #include "furi_hal_power.h" | #include "furi_hal_power.h" | ||||||
| #include "furi_hal_vcp.h" | #include "furi_hal_vcp.h" | ||||||
| #include "furi_hal_interrupt.h" | #include "furi_hal_interrupt.h" | ||||||
|  | |||||||
| @ -87,18 +87,11 @@ void platformUnprotectST25RComm(); | |||||||
| #define platformUnprotectST25RIrqStatus() \ | #define platformUnprotectST25RIrqStatus() \ | ||||||
|     platformUnprotectST25RComm() /*!< Unprotect the IRQ status var - IRQ enable on a single thread environment (MCU) ; Mutex unlock on a multi thread environment         */ |     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) \ | #define platformGpioSet(port, pin) LL_GPIO_SetOutputPin(port, pin) | ||||||
|     HAL_GPIO_WritePin(port, pin, GPIO_PIN_SET) /*!< Turns the given GPIO High                   */ | 
 | ||||||
| #define platformGpioClear(port, pin) \ | #define platformGpioClear(port, pin) LL_GPIO_ResetOutputPin(port, pin) | ||||||
|     HAL_GPIO_WritePin(               \ | 
 | ||||||
|         port, pin, GPIO_PIN_RESET) /*!< Turns the given GPIO Low                    */ | #define platformGpioIsHigh(port, pin) LL_GPIO_IsInputPinSet(port, pin) | ||||||
| #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 platformTimerCreate(t) \ | #define platformTimerCreate(t) \ | ||||||
|     timerCalculateTimer(t) /*!< Create a timer with the given time (ms)     */ |     timerCalculateTimer(t) /*!< Create a timer with the given time (ms)     */ | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく