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:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 ()
|
||||
|
||||
Reference in New Issue
Block a user