[FL-2219, FL-2251] System, FuriCore, FuriHal: various bug fixes and improvements (#986)
* Replace irq shenanigans with critical section * Power: halt system on power off instead of crash. * Gui: properly handle input event on NULL current_view * FuriHal: correct gpio configuration sequence * FuriHal: cleanup uart initialization. Makefile: allow to disable thread support. * Loader: improve locking, fix simultaneous app start crash, full command line args support for gui apps, more consistent insomnia * Loader: correct spelling * FuriHal: increase gpio configuration readability * FuriHal: correct gpio configuration error when mode is GpioModeEventRiseFall Co-authored-by: DrZlo13 <who.just.the.doctor@gmail.com>
This commit is contained in:
		| @@ -68,25 +68,37 @@ void hal_gpio_init_ex( | ||||
|     uint32_t exti_line = GET_EXTI_LINE(gpio->pin); | ||||
|  | ||||
|     // Configure gpio with interrupts disabled | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|  | ||||
|     // Set gpio speed | ||||
|     if(speed == GpioSpeedLow) { | ||||
|     switch(speed) { | ||||
|     case GpioSpeedLow: | ||||
|         LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_LOW); | ||||
|     } else if(speed == GpioSpeedMedium) { | ||||
|         break; | ||||
|     case GpioSpeedMedium: | ||||
|         LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_MEDIUM); | ||||
|     } else if(speed == GpioSpeedHigh) { | ||||
|         break; | ||||
|     case GpioSpeedHigh: | ||||
|         LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_HIGH); | ||||
|     } else { | ||||
|         break; | ||||
|     case GpioSpeedVeryHigh: | ||||
|         LL_GPIO_SetPinSpeed(gpio->port, gpio->pin, LL_GPIO_SPEED_FREQ_VERY_HIGH); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     // Set gpio pull mode | ||||
|     if(pull == GpioPullNo) { | ||||
|     switch(pull) { | ||||
|     case GpioPullNo: | ||||
|         LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_NO); | ||||
|     } else if(pull == GpioPullUp) { | ||||
|         break; | ||||
|     case GpioPullUp: | ||||
|         LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_UP); | ||||
|     } else { | ||||
|         break; | ||||
|     case GpioPullDown: | ||||
|         LL_GPIO_SetPinPull(gpio->port, gpio->pin, LL_GPIO_PULL_DOWN); | ||||
|         break; | ||||
|     } | ||||
|  | ||||
|     // Set gpio mode | ||||
|     if(mode >= GpioModeInterruptRise) { | ||||
|         // Set pin in interrupt mode | ||||
| @@ -100,93 +112,106 @@ void hal_gpio_init_ex( | ||||
|             LL_EXTI_EnableIT_0_31(exti_line); | ||||
|             LL_EXTI_EnableFallingTrig_0_31(exti_line); | ||||
|         } | ||||
|         if(mode == GpioModeEventRise || mode == GpioModeInterruptRiseFall) { | ||||
|         if(mode == GpioModeEventRise || mode == GpioModeEventRiseFall) { | ||||
|             LL_EXTI_EnableEvent_0_31(exti_line); | ||||
|             LL_EXTI_EnableRisingTrig_0_31(exti_line); | ||||
|         } | ||||
|         if(mode == GpioModeEventFall || mode == GpioModeInterruptRiseFall) { | ||||
|         if(mode == GpioModeEventFall || mode == GpioModeEventRiseFall) { | ||||
|             LL_EXTI_EnableEvent_0_31(exti_line); | ||||
|             LL_EXTI_EnableFallingTrig_0_31(exti_line); | ||||
|         } | ||||
|     } else { | ||||
|         // Disable interrupt if it was set | ||||
|         // Disable interrupts if set | ||||
|         if(LL_SYSCFG_GetEXTISource(sys_exti_line) == sys_exti_port && | ||||
|            LL_EXTI_IsEnabledIT_0_31(exti_line)) { | ||||
|             LL_EXTI_DisableIT_0_31(exti_line); | ||||
|             LL_EXTI_DisableRisingTrig_0_31(exti_line); | ||||
|             LL_EXTI_DisableFallingTrig_0_31(exti_line); | ||||
|         } | ||||
|  | ||||
|         // Prepare alternative part if any | ||||
|         if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { | ||||
|             // set alternate function | ||||
|             if(hal_gpio_get_pin_num(gpio) < 8) { | ||||
|                 LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); | ||||
|             } else { | ||||
|                 LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         // Set not interrupt pin modes | ||||
|         if(mode == GpioModeInput) { | ||||
|         switch(mode) { | ||||
|         case GpioModeInput: | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_INPUT); | ||||
|         } else if(mode == GpioModeOutputPushPull || mode == GpioModeAltFunctionPushPull) { | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); | ||||
|             break; | ||||
|         case GpioModeOutputPushPull: | ||||
|             LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_PUSHPULL); | ||||
|         } else if(mode == GpioModeOutputOpenDrain || mode == GpioModeAltFunctionOpenDrain) { | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); | ||||
|             break; | ||||
|         case GpioModeAltFunctionPushPull: | ||||
|             LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_PUSHPULL); | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); | ||||
|             break; | ||||
|         case GpioModeOutputOpenDrain: | ||||
|             LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_OPENDRAIN); | ||||
|         } else if(mode == GpioModeAnalog) { | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_OUTPUT); | ||||
|             break; | ||||
|         case GpioModeAltFunctionOpenDrain: | ||||
|             LL_GPIO_SetPinOutputType(gpio->port, gpio->pin, LL_GPIO_OUTPUT_OPENDRAIN); | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); | ||||
|             break; | ||||
|         case GpioModeAnalog: | ||||
|             LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ANALOG); | ||||
|             break; | ||||
|         default: | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if(mode == GpioModeAltFunctionPushPull || mode == GpioModeAltFunctionOpenDrain) { | ||||
|         // enable alternate mode | ||||
|         LL_GPIO_SetPinMode(gpio->port, gpio->pin, LL_GPIO_MODE_ALTERNATE); | ||||
|  | ||||
|         // set alternate function | ||||
|         if(hal_gpio_get_pin_num(gpio) < 8) { | ||||
|             LL_GPIO_SetAFPin_0_7(gpio->port, gpio->pin, alt_fn); | ||||
|         } else { | ||||
|             LL_GPIO_SetAFPin_8_15(gpio->port, gpio->pin, alt_fn); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| void hal_gpio_add_int_callback(const GpioPin* gpio, GpioExtiCallback cb, void* ctx) { | ||||
|     furi_assert(gpio); | ||||
|     furi_assert(cb); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     uint8_t pin_num = hal_gpio_get_pin_num(gpio); | ||||
|     furi_assert(gpio_interrupt[pin_num].callback == NULL); | ||||
|     gpio_interrupt[pin_num].callback = cb; | ||||
|     gpio_interrupt[pin_num].context = ctx; | ||||
|     gpio_interrupt[pin_num].ready = true; | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| void hal_gpio_enable_int_callback(const GpioPin* gpio) { | ||||
|     furi_assert(gpio); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     uint8_t pin_num = hal_gpio_get_pin_num(gpio); | ||||
|     if(gpio_interrupt[pin_num].callback) { | ||||
|         gpio_interrupt[pin_num].ready = true; | ||||
|     } | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| void hal_gpio_disable_int_callback(const GpioPin* gpio) { | ||||
|     furi_assert(gpio); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     uint8_t pin_num = hal_gpio_get_pin_num(gpio); | ||||
|     gpio_interrupt[pin_num].ready = false; | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| void hal_gpio_remove_int_callback(const GpioPin* gpio) { | ||||
|     furi_assert(gpio); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     uint8_t pin_num = hal_gpio_get_pin_num(gpio); | ||||
|     gpio_interrupt[pin_num].callback = NULL; | ||||
|     gpio_interrupt[pin_num].context = NULL; | ||||
|     gpio_interrupt[pin_num].ready = false; | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| static void hal_gpio_int_call(uint16_t pin_num) { | ||||
|   | ||||
| @@ -516,7 +516,7 @@ static void furi_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_ | ||||
|     IrdaTxBuf* buffer = &irda_tim_tx.buffer[buf_num]; | ||||
|     furi_assert(buffer->polarity != NULL); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     bool channel_enabled = LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_1); | ||||
|     if(channel_enabled) { | ||||
|         LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_1); | ||||
| @@ -526,7 +526,7 @@ static void furi_hal_irda_tx_dma_set_polarity(uint8_t buf_num, uint8_t polarity_ | ||||
|     if(channel_enabled) { | ||||
|         LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); | ||||
|     } | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { | ||||
| @@ -536,7 +536,7 @@ static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { | ||||
|     furi_assert(buffer->data != NULL); | ||||
|  | ||||
|     /* non-circular mode requires disabled channel before setup */ | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     bool channel_enabled = LL_DMA_IsEnabledChannel(DMA1, LL_DMA_CHANNEL_2); | ||||
|     if(channel_enabled) { | ||||
|         LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2); | ||||
| @@ -546,7 +546,7 @@ static void furi_hal_irda_tx_dma_set_buffer(uint8_t buf_num) { | ||||
|     if(channel_enabled) { | ||||
|         LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2); | ||||
|     } | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| static void furi_hal_irda_async_tx_free_resources(void) { | ||||
| @@ -621,10 +621,10 @@ void furi_hal_irda_async_tx_start(uint32_t freq, float duty_cycle) { | ||||
|     hal_gpio_init_ex( | ||||
|         &gpio_irda_tx, GpioModeAltFunctionPushPull, GpioPullUp, GpioSpeedHigh, GpioAltFn1TIM1); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     LL_TIM_GenerateEvent_UPDATE(TIM1); /* TIMx_RCR -> Repetition counter */ | ||||
|     LL_TIM_EnableCounter(TIM1); | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| void furi_hal_irda_async_tx_wait_termination(void) { | ||||
| @@ -642,9 +642,9 @@ void furi_hal_irda_async_tx_stop(void) { | ||||
|     furi_assert(furi_hal_irda_state >= IrdaStateAsyncTx); | ||||
|     furi_assert(furi_hal_irda_state < IrdaStateMAX); | ||||
|  | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|     if(furi_hal_irda_state == IrdaStateAsyncTx) furi_hal_irda_state = IrdaStateAsyncTxStopReq; | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
|  | ||||
|     furi_hal_irda_async_tx_wait_termination(); | ||||
| } | ||||
|   | ||||
| @@ -115,11 +115,11 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | ||||
|     } | ||||
|  | ||||
|     // Stop IRQ handling, no one should disturb us till we finish | ||||
|     __disable_irq(); | ||||
|     FURI_CRITICAL_ENTER(); | ||||
|  | ||||
|     // Confirm OS that sleep is still possible | ||||
|     if(eTaskConfirmSleepModeStatus() == eAbortSleep) { | ||||
|         __enable_irq(); | ||||
|         FURI_CRITICAL_EXIT(); | ||||
|         return; | ||||
|     } | ||||
|  | ||||
| @@ -136,7 +136,7 @@ void vPortSuppressTicksAndSleep(TickType_t expected_idle_ticks) { | ||||
|     } | ||||
|  | ||||
|     // Reenable IRQ | ||||
|     __enable_irq(); | ||||
|     FURI_CRITICAL_EXIT(); | ||||
| } | ||||
|  | ||||
| void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName) { | ||||
|   | ||||
| @@ -5,6 +5,7 @@ | ||||
| #include <furi_hal_resources.h> | ||||
|  | ||||
| #include <furi.h> | ||||
| #include <furi_hal_delay.h> | ||||
|  | ||||
| static void (*irq_cb[2])(uint8_t ev, uint8_t data, void* context); | ||||
| static void* irq_ctx[2]; | ||||
| @@ -33,13 +34,12 @@ static void furi_hal_usart_init(uint32_t baud) { | ||||
|     USART_InitStruct.HardwareFlowControl = LL_USART_HWCONTROL_NONE; | ||||
|     USART_InitStruct.OverSampling = LL_USART_OVERSAMPLING_16; | ||||
|     LL_USART_Init(USART1, &USART_InitStruct); | ||||
|     LL_USART_SetTXFIFOThreshold(USART1, LL_USART_FIFOTHRESHOLD_1_2); | ||||
|     LL_USART_EnableFIFO(USART1); | ||||
|     LL_USART_ConfigAsyncMode(USART1); | ||||
|  | ||||
|     LL_USART_Enable(USART1); | ||||
|  | ||||
|     while(!LL_USART_IsActiveFlag_TEACK(USART1)) | ||||
|     while(!LL_USART_IsActiveFlag_TEACK(USART1) || !LL_USART_IsActiveFlag_REACK(USART1)) | ||||
|         ; | ||||
|  | ||||
|     LL_USART_EnableIT_RXNE_RXFNE(USART1); | ||||
| @@ -70,13 +70,11 @@ static void furi_hal_lpuart_init(uint32_t baud) { | ||||
|     LPUART_InitStruct.TransferDirection = LL_LPUART_DIRECTION_TX_RX; | ||||
|     LPUART_InitStruct.HardwareFlowControl = LL_LPUART_HWCONTROL_NONE; | ||||
|     LL_LPUART_Init(LPUART1, &LPUART_InitStruct); | ||||
|     LL_LPUART_SetTXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); | ||||
|     LL_LPUART_SetRXFIFOThreshold(LPUART1, LL_LPUART_FIFOTHRESHOLD_1_8); | ||||
|     LL_LPUART_EnableFIFO(LPUART1); | ||||
|  | ||||
|     LL_LPUART_Enable(LPUART1); | ||||
|  | ||||
|     while((!(LL_LPUART_IsActiveFlag_TEACK(LPUART1))) || (!(LL_LPUART_IsActiveFlag_REACK(LPUART1)))) | ||||
|     while(!LL_LPUART_IsActiveFlag_TEACK(LPUART1) || !LL_LPUART_IsActiveFlag_REACK(LPUART1)) | ||||
|         ; | ||||
|  | ||||
|     furi_hal_uart_set_br(FuriHalUartIdLPUART1, baud); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user