fix: Corrupt data using soft serial driver (#3329)

* restore bit start detection IRQ for soft serial

* restore bit start detection IRQ for softserial (target Taranis and Horus)

* target Taranis: EXTI9_5 is a shared interrupt for Rotary Encoder and Heartbeat for X7, X7-ACCESS und TPRO radios. Changed IRQ priority accordingly

* fix crashes where the heartbeat ISR running at interrupt priorities higher than 5 interferes with FreeRTOS calls made from within the heartbeat ISR.

* changed mixer scheduler timer initialization to allow for software generated update events to avoid freeRTOS calls from now prio 0 heartbeat ISR.

* resolved review feedback: using defines for IRQ prio settings

* following review by @raphaelcoeffic:

- new function void mixerSchedulerSoftTrigger() (to be called by heartbeat driver)
- defines in hal.h for targets horus and taranis

* following @raphaelcoeffics review

- changed all but telemetry EXIT IRQ (soft serial) definition back to their original state and added define to override EXIT IRQ (soft serial) prio
This commit is contained in:
Michael
2023-04-19 19:43:25 +10:00
committed by GitHub
parent a4689d0b00
commit 74d44ed057
5 changed files with 26 additions and 19 deletions
+5 -5
View File
@@ -40,9 +40,6 @@ void mixerSchedulerStart();
// Stop the scheduler timer
void mixerSchedulerStop();
// Set the timer counter to 0
void mixerSchedulerResetTimer();
// Set the scheduling period for a given module
void mixerSchedulerSetPeriod(uint8_t moduleIdx, uint16_t periodUs);
@@ -55,6 +52,9 @@ void mixerSchedulerEnableTrigger();
// Disable the timer trigger
void mixerSchedulerDisableTrigger();
// Trigger mixer from heartbeat interrupt
void mixerSchedulerSoftTrigger();
// Fetch the current scheduling period
uint16_t getMixerSchedulerPeriod();
@@ -66,14 +66,14 @@ void mixerSchedulerISRTrigger();
#define mixerSchedulerInit()
#define mixerSchedulerStart()
#define mixerSchedulerStop()
#define mixerSchedulerResetTimer()
#define mixerSchedulerSetPeriod(m,p) ((void)(p))
#define mixerSchedulerGetPeriod(m) ((uint16_t)MIXER_SCHEDULER_DEFAULT_PERIOD_US)
#define mixerSchedulerClearTrigger()
#define mixerSchedulerEnableTrigger()
#define mixerSchedulerDisableTrigger()
#define mixerSchedulerSoftTrigger()
#define getMixerSchedulerPeriod() (MIXER_SCHEDULER_DEFAULT_PERIOD_US)
#define mixerSchedulerISRTrigger()
@@ -41,8 +41,7 @@ static void trigger_intmodule_heartbeat()
heartbeatCapture.count++;
#endif
mixerSchedulerResetTimer();
mixerSchedulerISRTrigger();
mixerSchedulerSoftTrigger();
}
void init_intmodule_heartbeat()
@@ -30,13 +30,11 @@
void mixerSchedulerStart()
{
MIXER_SCHEDULER_TIMER->CR1 &= ~TIM_CR1_CEN;
MIXER_SCHEDULER_TIMER->CR1 = TIM_CR1_URS; // do not generate interrupt on soft update
MIXER_SCHEDULER_TIMER->PSC = MIXER_SCHEDULER_TIMER_FREQ / 1000000 - 1; // 1uS (1Mhz)
MIXER_SCHEDULER_TIMER->CCER = 0;
MIXER_SCHEDULER_TIMER->CCMR1 = 0;
MIXER_SCHEDULER_TIMER->ARR = getMixerSchedulerPeriod() - 1;
MIXER_SCHEDULER_TIMER->EGR = TIM_EGR_UG; // reset timer
MIXER_SCHEDULER_TIMER->CNT = 0; // reset counter
NVIC_EnableIRQ(MIXER_SCHEDULER_TIMER_IRQn);
NVIC_SetPriority(MIXER_SCHEDULER_TIMER_IRQn,
@@ -53,13 +51,6 @@ void mixerSchedulerStop()
NVIC_DisableIRQ(MIXER_SCHEDULER_TIMER_IRQn);
}
void mixerSchedulerResetTimer()
{
mixerSchedulerDisableTrigger();
MIXER_SCHEDULER_TIMER->CNT = 0;
mixerSchedulerEnableTrigger();
}
void mixerSchedulerEnableTrigger()
{
MIXER_SCHEDULER_TIMER->DIER |= TIM_DIER_UIE; // enable interrupt
@@ -70,6 +61,15 @@ void mixerSchedulerDisableTrigger()
MIXER_SCHEDULER_TIMER->DIER &= ~TIM_DIER_UIE; // disable interrupt
}
void mixerSchedulerSoftTrigger() {
// Generate a timer update event (TIM_EGR_UG) to reload the Prescaler and the repetition
// counter value immediately to avoid making FreeRTOS calls within this ISR:
// - fires MIXER_SCHEDULER_TIMER interrupt after returning from this ISR
// - MIXER_SCHEDULER_TIMER_IRQHandler(void) takes care of making FreeRTOS calls
// to ensure switching to highest priority task.
MIXER_SCHEDULER_TIMER->EGR = TIM_EGR_UG;
}
extern "C" void MIXER_SCHEDULER_TIMER_IRQHandler(void)
{
MIXER_SCHEDULER_TIMER->SR &= ~TIM_SR_UIF; // clear flag
+5 -1
View File
@@ -28,6 +28,8 @@
#define TIMER_MULT_APB1 2
#define TIMER_MULT_APB2 2
#define TELEMETRY_EXTI_PRIO 0 // required for soft serial
// Keys
#define KEYS_RCC_AHB1Periph (RCC_AHB1Periph_GPIOB | RCC_AHB1Periph_GPIOC | RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOH | RCC_AHB1Periph_GPIOI | RCC_AHB1Periph_GPIOJ)
#if defined(PCBX12S)
@@ -521,8 +523,10 @@
// TELEMETRY_EXTI IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
// overwrite priority
#undef EXTI9_5_IRQ_Priority
#define EXTI9_5_IRQ_Priority TELEMETRY_EXTI_PRIO
#define TELEMETRY_TIMER TIM11
#define TELEMETRY_TIMER_IRQn TIM1_TRG_COM_TIM11_IRQn
+5 -1
View File
@@ -35,6 +35,8 @@
#define TIMER_MULT_APB1 2
#define TIMER_MULT_APB2 2
#define TELEMETRY_EXTI_PRIO 0 // required for soft serial
// Keys
#if defined(PCBX9E)
#define KEYS_GPIO_REG_MENU GPIOD->IDR
@@ -1962,8 +1964,10 @@
// TELEMETRY_EXTI IRQ
#if !defined(USE_EXTI9_5_IRQ)
#define USE_EXTI9_5_IRQ
#define EXTI9_5_IRQ_Priority 5
#endif
// overwrite priority
#undef EXTI9_5_IRQ_Priority
#define EXTI9_5_IRQ_Priority TELEMETRY_EXTI_PRIO
#define TELEMETRY_TIMER TIM11
#define TELEMETRY_TIMER_PRESCALER ()