Guard RCC registers access with critical section (#854)
* Core: critical section macros. FuriHal: guard rcc registers access with critical section, fix condition race. * FuriHal: update documentation. Co-authored-by: SG <who.just.the.doctor@gmail.com>
This commit is contained in:
		
							parent
							
								
									6f7d93fe72
								
							
						
					
					
						commit
						418c0939a0
					
				| @ -31,11 +31,11 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); | ||||
| 
 | ||||
| /** Perform I2C tx transfer
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      data      pointer to data buffer | ||||
|  * @param      size      size of data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      data     pointer to data buffer | ||||
|  * @param      size     size of data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
| @ -48,11 +48,11 @@ bool furi_hal_i2c_tx( | ||||
| 
 | ||||
| /** Perform I2C rx transfer
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      data      pointer to data buffer | ||||
|  * @param      size      size of data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      data     pointer to data buffer | ||||
|  * @param      size     size of data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
| @ -65,13 +65,13 @@ bool furi_hal_i2c_rx( | ||||
| 
 | ||||
| /** Perform I2C tx and rx transfers
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      tx_data   pointer to tx data buffer | ||||
|  * @param      tx_size   size of tx data buffer | ||||
|  * @param      rx_data   pointer to rx data buffer | ||||
|  * @param      rx_size   size of rx data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      tx_data  pointer to tx data buffer | ||||
|  * @param      tx_size  size of tx data buffer | ||||
|  * @param      rx_data  pointer to rx data buffer | ||||
|  * @param      rx_size  size of rx data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
|  | ||||
| @ -31,11 +31,11 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); | ||||
| 
 | ||||
| /** Perform I2C tx transfer
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      data      pointer to data buffer | ||||
|  * @param      size      size of data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      data     pointer to data buffer | ||||
|  * @param      size     size of data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
| @ -48,11 +48,11 @@ bool furi_hal_i2c_tx( | ||||
| 
 | ||||
| /** Perform I2C rx transfer
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      data      pointer to data buffer | ||||
|  * @param      size      size of data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      data     pointer to data buffer | ||||
|  * @param      size     size of data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
| @ -65,13 +65,13 @@ bool furi_hal_i2c_rx( | ||||
| 
 | ||||
| /** Perform I2C tx and rx transfers
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      tx_data   pointer to tx data buffer | ||||
|  * @param      tx_size   size of tx data buffer | ||||
|  * @param      rx_data   pointer to rx data buffer | ||||
|  * @param      rx_size   size of rx data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      tx_data  pointer to tx data buffer | ||||
|  * @param      tx_size  size of tx data buffer | ||||
|  * @param      rx_data  pointer to rx data buffer | ||||
|  * @param      rx_size  size of rx data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
|  | ||||
							
								
								
									
										10
									
								
								core/furi/common_defines.h
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										10
									
								
								core/furi/common_defines.h
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							| @ -71,3 +71,13 @@ | ||||
|     ((((x)&0x000000FF) << 24) | (((x)&0x0000FF00) << 8) | (((x)&0x00FF0000) >> 8) | \ | ||||
|      (((x)&0xFF000000) >> 24)) | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FURI_CRITICAL_ENTER | ||||
| #define FURI_CRITICAL_ENTER()               \ | ||||
|     uint32_t primask_bit = __get_PRIMASK(); \ | ||||
|     __disable_irq() | ||||
| #endif | ||||
| 
 | ||||
| #ifndef FURI_CRITICAL_EXIT | ||||
| #define FURI_CRITICAL_EXIT() __set_PRIMASK(primask_bit) | ||||
| #endif | ||||
| @ -39,26 +39,26 @@ void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { | ||||
|     if (!furi_hal_console_alive) | ||||
|         return; | ||||
| 
 | ||||
|     UTILS_ENTER_CRITICAL_SECTION(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     // Transmit data
 | ||||
|     furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); | ||||
|     // Wait for TC flag to be raised for last char
 | ||||
|     while (!LL_USART_IsActiveFlag_TC(USART1)); | ||||
|     UTILS_EXIT_CRITICAL_SECTION(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) { | ||||
|     if (!furi_hal_console_alive) | ||||
|         return; | ||||
| 
 | ||||
|     UTILS_ENTER_CRITICAL_SECTION(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     // Transmit data
 | ||||
|     furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); | ||||
|     // Transmit new line symbols
 | ||||
|     furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)"\r\n", 2); | ||||
|     // Wait for TC flag to be raised for last char
 | ||||
|     while (!LL_USART_IsActiveFlag_TC(USART1)); | ||||
|     UTILS_EXIT_CRITICAL_SECTION(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_printf(const char format[], ...) { | ||||
|  | ||||
| @ -19,9 +19,11 @@ osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; | ||||
| static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { | ||||
|     if (event == FuriHalI2cBusEventInit) { | ||||
|         furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         bus->current_handle = NULL; | ||||
|     } else if (event == FuriHalI2cBusEventDeinit) { | ||||
|         osMutexDelete(furi_hal_i2c_bus_power_mutex); | ||||
| @ -30,9 +32,13 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent | ||||
|     } else if (event == FuriHalI2cBusEventUnlock) { | ||||
|         furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); | ||||
|     } else if (event == FuriHalI2cBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalI2cBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -45,11 +51,15 @@ osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; | ||||
| 
 | ||||
| static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { | ||||
|     if (event == FuriHalI2cBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); | ||||
|         LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); | ||||
|         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalI2cBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -76,13 +86,12 @@ void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2c | ||||
|             I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; | ||||
|         } | ||||
|         LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); | ||||
| 
 | ||||
|         // I2C is enabled at this point
 | ||||
|         LL_I2C_EnableAutoEndMode(handle->bus->i2c); | ||||
|         LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); | ||||
|         LL_I2C_DisableOwnAddress2(handle->bus->i2c); | ||||
|         LL_I2C_DisableGeneralCall(handle->bus->i2c); | ||||
|         LL_I2C_EnableClockStretching(handle->bus->i2c); | ||||
|         LL_I2C_Enable(handle->bus->i2c); | ||||
|     } else if (event == FuriHalI2cBusHandleEventDeactivate) { | ||||
|         LL_I2C_Disable(handle->bus->i2c); | ||||
|         hal_gpio_write(&gpio_i2c_power_sda, 1); | ||||
| @ -111,13 +120,12 @@ void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHal | ||||
|         I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; | ||||
|         I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; | ||||
|         LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); | ||||
| 
 | ||||
|         // I2C is enabled at this point
 | ||||
|         LL_I2C_EnableAutoEndMode(handle->bus->i2c); | ||||
|         LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); | ||||
|         LL_I2C_DisableOwnAddress2(handle->bus->i2c); | ||||
|         LL_I2C_DisableGeneralCall(handle->bus->i2c); | ||||
|         LL_I2C_EnableClockStretching(handle->bus->i2c); | ||||
|         LL_I2C_Enable(handle->bus->i2c); | ||||
|     } else if (event == FuriHalI2cBusHandleEventDeactivate) { | ||||
|         LL_I2C_Disable(handle->bus->i2c); | ||||
|         hal_gpio_write(&gpio_ext_pc0, 1); | ||||
|  | ||||
| @ -136,8 +136,10 @@ static void furi_hal_irda_tim_rx_isr() { | ||||
| void furi_hal_irda_async_rx_start(void) { | ||||
|     furi_assert(furi_hal_irda_state == IrdaStateIdle); | ||||
| 
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| 
 | ||||
|     hal_gpio_init_ex(&gpio_irda_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); | ||||
| 
 | ||||
|  | ||||
| @ -75,8 +75,10 @@ osMutexId_t furi_hal_spi_bus_r_mutex = NULL; | ||||
| static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { | ||||
|     if (event == FuriHalSpiBusEventInit) { | ||||
|         furi_hal_spi_bus_r_mutex = osMutexNew(NULL); | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         bus->current_handle = NULL; | ||||
|     } else if (event == FuriHalSpiBusEventDeinit) { | ||||
|         furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); | ||||
| @ -85,9 +87,13 @@ static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE | ||||
|     } else if (event == FuriHalSpiBusEventUnlock) { | ||||
|         furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); | ||||
|     } else if (event == FuriHalSpiBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalSpiBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -101,8 +107,10 @@ osMutexId_t furi_hal_spi_bus_d_mutex = NULL; | ||||
| static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { | ||||
|     if (event == FuriHalSpiBusEventInit) { | ||||
|         furi_hal_spi_bus_d_mutex = osMutexNew(NULL); | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         bus->current_handle = NULL; | ||||
|     } else if (event == FuriHalSpiBusEventDeinit) { | ||||
|         furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); | ||||
| @ -111,9 +119,13 @@ static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE | ||||
|     } else if (event == FuriHalSpiBusEventUnlock) { | ||||
|         furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); | ||||
|     } else if (event == FuriHalSpiBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalSpiBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -575,7 +575,10 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* | ||||
|         &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); | ||||
| 
 | ||||
|     // Timer: base
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| 
 | ||||
|     LL_TIM_InitTypeDef TIM_InitStruct = {0}; | ||||
|     TIM_InitStruct.Prescaler = 64 - 1; | ||||
|     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; | ||||
| @ -635,8 +638,10 @@ void furi_hal_subghz_stop_async_rx() { | ||||
|     // Shutdown radio
 | ||||
|     furi_hal_subghz_idle(); | ||||
| 
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_TIM_DeInit(TIM2); | ||||
|     LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
|     furi_hal_interrupt_set_timer_isr(TIM2, NULL); | ||||
| 
 | ||||
|     hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); | ||||
| @ -761,7 +766,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* | ||||
|     LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); | ||||
| 
 | ||||
|     // Configure TIM2
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
|     LL_TIM_InitTypeDef TIM_InitStruct = {0}; | ||||
|     TIM_InitStruct.Prescaler = 64 - 1; | ||||
|     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; | ||||
| @ -820,6 +827,7 @@ void furi_hal_subghz_stop_async_tx() { | ||||
| #endif | ||||
| 
 | ||||
|     // Deinitialize Timer
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_TIM_DeInit(TIM2); | ||||
|     LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     furi_hal_interrupt_set_timer_isr(TIM2, NULL); | ||||
| @ -830,6 +838,7 @@ void furi_hal_subghz_stop_async_tx() { | ||||
| 
 | ||||
|     // Deinitialize GPIO
 | ||||
|     hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| 
 | ||||
|     free(furi_hal_subghz_async_tx.buffer); | ||||
| 
 | ||||
|  | ||||
| @ -25,42 +25,40 @@ void furi_hal_console_init() { | ||||
| 
 | ||||
| void furi_hal_console_enable() { | ||||
|     furi_hal_uart_set_irq_cb(FuriHalUartIdUSART1, NULL, NULL); | ||||
|     while(!LL_USART_IsActiveFlag_TC(USART1)) | ||||
|         ; | ||||
|     while (!LL_USART_IsActiveFlag_TC(USART1)); | ||||
|     furi_hal_uart_set_br(FuriHalUartIdUSART1, CONSOLE_BAUDRATE); | ||||
|     furi_hal_console_alive = true; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_disable() { | ||||
|     while(!LL_USART_IsActiveFlag_TC(USART1)) | ||||
|         ; | ||||
|     while (!LL_USART_IsActiveFlag_TC(USART1)); | ||||
|     furi_hal_console_alive = false; | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_tx(const uint8_t* buffer, size_t buffer_size) { | ||||
|     if(!furi_hal_console_alive) return; | ||||
|     if (!furi_hal_console_alive) | ||||
|         return; | ||||
| 
 | ||||
|     UTILS_ENTER_CRITICAL_SECTION(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     // Transmit data
 | ||||
|     furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); | ||||
|     // Wait for TC flag to be raised for last char
 | ||||
|     while(!LL_USART_IsActiveFlag_TC(USART1)) | ||||
|         ; | ||||
|     UTILS_EXIT_CRITICAL_SECTION(); | ||||
|     while (!LL_USART_IsActiveFlag_TC(USART1)); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_tx_with_new_line(const uint8_t* buffer, size_t buffer_size) { | ||||
|     if(!furi_hal_console_alive) return; | ||||
|     if (!furi_hal_console_alive) | ||||
|         return; | ||||
| 
 | ||||
|     UTILS_ENTER_CRITICAL_SECTION(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     // Transmit data
 | ||||
|     furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)buffer, buffer_size); | ||||
|     // Transmit new line symbols
 | ||||
|     furi_hal_uart_tx(FuriHalUartIdUSART1, (uint8_t*)"\r\n", 2); | ||||
|     // Wait for TC flag to be raised for last char
 | ||||
|     while(!LL_USART_IsActiveFlag_TC(USART1)) | ||||
|         ; | ||||
|     UTILS_EXIT_CRITICAL_SECTION(); | ||||
|     while (!LL_USART_IsActiveFlag_TC(USART1)); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_printf(const char format[], ...) { | ||||
| @ -73,6 +71,6 @@ void furi_hal_console_printf(const char format[], ...) { | ||||
|     string_clear(string); | ||||
| } | ||||
| 
 | ||||
| void furi_hal_console_puts(const char* data) { | ||||
| void furi_hal_console_puts(const char *data) { | ||||
|     furi_hal_console_tx((const uint8_t*)data, strlen(data)); | ||||
| } | ||||
|  | ||||
| @ -19,9 +19,11 @@ osMutexId_t furi_hal_i2c_bus_power_mutex = NULL; | ||||
| static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { | ||||
|     if (event == FuriHalI2cBusEventInit) { | ||||
|         furi_hal_i2c_bus_power_mutex = osMutexNew(NULL); | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_PCLK1); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         bus->current_handle = NULL; | ||||
|     } else if (event == FuriHalI2cBusEventDeinit) { | ||||
|         osMutexDelete(furi_hal_i2c_bus_power_mutex); | ||||
| @ -30,9 +32,13 @@ static void furi_hal_i2c_bus_power_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent | ||||
|     } else if (event == FuriHalI2cBusEventUnlock) { | ||||
|         furi_check(osMutexRelease(furi_hal_i2c_bus_power_mutex) == osOK); | ||||
|     } else if (event == FuriHalI2cBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalI2cBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -45,11 +51,15 @@ osMutexId_t furi_hal_i2c_bus_external_mutex = NULL; | ||||
| 
 | ||||
| static void furi_hal_i2c_bus_external_event(FuriHalI2cBus* bus, FuriHalI2cBusEvent event) { | ||||
|     if (event == FuriHalI2cBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_I2C3); | ||||
|         LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_PCLK1); | ||||
|         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_I2C3); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalI2cBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_I2C3); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -76,13 +86,12 @@ void furi_hal_i2c_bus_handle_power_event(FuriHalI2cBusHandle* handle, FuriHalI2c | ||||
|             I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; | ||||
|         } | ||||
|         LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); | ||||
| 
 | ||||
|         // I2C is enabled at this point
 | ||||
|         LL_I2C_EnableAutoEndMode(handle->bus->i2c); | ||||
|         LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); | ||||
|         LL_I2C_DisableOwnAddress2(handle->bus->i2c); | ||||
|         LL_I2C_DisableGeneralCall(handle->bus->i2c); | ||||
|         LL_I2C_EnableClockStretching(handle->bus->i2c); | ||||
|         LL_I2C_Enable(handle->bus->i2c); | ||||
|     } else if (event == FuriHalI2cBusHandleEventDeactivate) { | ||||
|         LL_I2C_Disable(handle->bus->i2c); | ||||
|         hal_gpio_write(&gpio_i2c_power_sda, 1); | ||||
| @ -111,13 +120,12 @@ void furi_hal_i2c_bus_handle_external_event(FuriHalI2cBusHandle* handle, FuriHal | ||||
|         I2C_InitStruct.OwnAddrSize = LL_I2C_OWNADDRESS1_7BIT; | ||||
|         I2C_InitStruct.Timing = FURI_HAL_I2C_CONFIG_POWER_I2C_TIMINGS_100; | ||||
|         LL_I2C_Init(handle->bus->i2c, &I2C_InitStruct); | ||||
| 
 | ||||
|         // I2C is enabled at this point
 | ||||
|         LL_I2C_EnableAutoEndMode(handle->bus->i2c); | ||||
|         LL_I2C_SetOwnAddress2(handle->bus->i2c, 0, LL_I2C_OWNADDRESS2_NOMASK); | ||||
|         LL_I2C_DisableOwnAddress2(handle->bus->i2c); | ||||
|         LL_I2C_DisableGeneralCall(handle->bus->i2c); | ||||
|         LL_I2C_EnableClockStretching(handle->bus->i2c); | ||||
|         LL_I2C_Enable(handle->bus->i2c); | ||||
|     } else if (event == FuriHalI2cBusHandleEventDeactivate) { | ||||
|         LL_I2C_Disable(handle->bus->i2c); | ||||
|         hal_gpio_write(&gpio_ext_pc0, 1); | ||||
|  | ||||
| @ -136,8 +136,10 @@ static void furi_hal_irda_tim_rx_isr() { | ||||
| void furi_hal_irda_async_rx_start(void) { | ||||
|     furi_assert(furi_hal_irda_state == IrdaStateIdle); | ||||
| 
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| 
 | ||||
|     hal_gpio_init_ex(&gpio_irda_rx, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); | ||||
| 
 | ||||
|  | ||||
| @ -75,8 +75,10 @@ osMutexId_t furi_hal_spi_bus_r_mutex = NULL; | ||||
| static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { | ||||
|     if (event == FuriHalSpiBusEventInit) { | ||||
|         furi_hal_spi_bus_r_mutex = osMutexNew(NULL); | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         bus->current_handle = NULL; | ||||
|     } else if (event == FuriHalSpiBusEventDeinit) { | ||||
|         furi_check(osMutexDelete(furi_hal_spi_bus_r_mutex)); | ||||
| @ -85,9 +87,13 @@ static void furi_hal_spi_bus_r_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE | ||||
|     } else if (event == FuriHalSpiBusEventUnlock) { | ||||
|         furi_check(osMutexRelease(furi_hal_spi_bus_r_mutex) == osOK); | ||||
|     } else if (event == FuriHalSpiBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB2_GRP1_ReleaseReset(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalSpiBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB2_GRP1_ForceReset(LL_APB2_GRP1_PERIPH_SPI1); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| @ -101,8 +107,10 @@ osMutexId_t furi_hal_spi_bus_d_mutex = NULL; | ||||
| static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusEvent event) { | ||||
|     if (event == FuriHalSpiBusEventInit) { | ||||
|         furi_hal_spi_bus_d_mutex = osMutexNew(NULL); | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         bus->current_handle = NULL; | ||||
|     } else if (event == FuriHalSpiBusEventDeinit) { | ||||
|         furi_check(osMutexDelete(furi_hal_spi_bus_d_mutex)); | ||||
| @ -111,9 +119,13 @@ static void furi_hal_spi_bus_d_event_callback(FuriHalSpiBus* bus, FuriHalSpiBusE | ||||
|     } else if (event == FuriHalSpiBusEventUnlock) { | ||||
|         furi_check(osMutexRelease(furi_hal_spi_bus_d_mutex) == osOK); | ||||
|     } else if (event == FuriHalSpiBusEventActivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ReleaseReset(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } else if (event == FuriHalSpiBusEventDeactivate) { | ||||
|         FURI_CRITICAL_ENTER(); | ||||
|         LL_APB1_GRP1_ForceReset(LL_APB1_GRP1_PERIPH_SPI2); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -575,7 +575,10 @@ void furi_hal_subghz_start_async_rx(FuriHalSubGhzCaptureCallback callback, void* | ||||
|         &gpio_cc1101_g0, GpioModeAltFunctionPushPull, GpioPullNo, GpioSpeedLow, GpioAltFn1TIM2); | ||||
| 
 | ||||
|     // Timer: base
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| 
 | ||||
|     LL_TIM_InitTypeDef TIM_InitStruct = {0}; | ||||
|     TIM_InitStruct.Prescaler = 64 - 1; | ||||
|     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; | ||||
| @ -635,8 +638,10 @@ void furi_hal_subghz_stop_async_rx() { | ||||
|     // Shutdown radio
 | ||||
|     furi_hal_subghz_idle(); | ||||
| 
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_TIM_DeInit(TIM2); | ||||
|     LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
|     furi_hal_interrupt_set_timer_isr(TIM2, NULL); | ||||
| 
 | ||||
|     hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); | ||||
| @ -761,7 +766,9 @@ bool furi_hal_subghz_start_async_tx(FuriHalSubGhzAsyncTxCallback callback, void* | ||||
|     LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); | ||||
| 
 | ||||
|     // Configure TIM2
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
|     LL_TIM_InitTypeDef TIM_InitStruct = {0}; | ||||
|     TIM_InitStruct.Prescaler = 64 - 1; | ||||
|     TIM_InitStruct.CounterMode = LL_TIM_COUNTERMODE_UP; | ||||
| @ -820,6 +827,7 @@ void furi_hal_subghz_stop_async_tx() { | ||||
| #endif | ||||
| 
 | ||||
|     // Deinitialize Timer
 | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_TIM_DeInit(TIM2); | ||||
|     LL_APB1_GRP1_DisableClock(LL_APB1_GRP1_PERIPH_TIM2); | ||||
|     furi_hal_interrupt_set_timer_isr(TIM2, NULL); | ||||
| @ -830,6 +838,7 @@ void furi_hal_subghz_stop_async_tx() { | ||||
| 
 | ||||
|     // Deinitialize GPIO
 | ||||
|     hal_gpio_init(&gpio_cc1101_g0, GpioModeAnalog, GpioPullNo, GpioSpeedLow); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| 
 | ||||
|     free(furi_hal_subghz_async_tx.buffer); | ||||
| 
 | ||||
|  | ||||
| @ -31,11 +31,11 @@ void furi_hal_i2c_release(FuriHalI2cBusHandle* handle); | ||||
| 
 | ||||
| /** Perform I2C tx transfer
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      data      pointer to data buffer | ||||
|  * @param      size      size of data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      data     pointer to data buffer | ||||
|  * @param      size     size of data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
| @ -48,11 +48,11 @@ bool furi_hal_i2c_tx( | ||||
| 
 | ||||
| /** Perform I2C rx transfer
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      data      pointer to data buffer | ||||
|  * @param      size      size of data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      data     pointer to data buffer | ||||
|  * @param      size     size of data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
| @ -65,13 +65,13 @@ bool furi_hal_i2c_rx( | ||||
| 
 | ||||
| /** Perform I2C tx and rx transfers
 | ||||
|  * | ||||
|  * @param      instance  I2C_TypeDef instance | ||||
|  * @param      address   I2C slave address | ||||
|  * @param      tx_data   pointer to tx data buffer | ||||
|  * @param      tx_size   size of tx data buffer | ||||
|  * @param      rx_data   pointer to rx data buffer | ||||
|  * @param      rx_size   size of rx data buffer | ||||
|  * @param      timeout   timeout in ticks | ||||
|  * @param      handle   pointer to FuriHalI2cBusHandle instance | ||||
|  * @param      address  I2C slave address | ||||
|  * @param      tx_data  pointer to tx data buffer | ||||
|  * @param      tx_size  size of tx data buffer | ||||
|  * @param      rx_data  pointer to rx data buffer | ||||
|  * @param      rx_size  size of rx data buffer | ||||
|  * @param      timeout  timeout in ticks | ||||
|  * | ||||
|  * @return     true on successful transfer, false otherwise | ||||
|  */ | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 あく
						あく