[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