fix(gx12): periodically read IO expander in mixer (#7105)
This commit is contained in:
@@ -35,6 +35,9 @@
|
||||
#include "luminosity_sensor.h"
|
||||
#endif
|
||||
|
||||
#if defined(RADIO_GX12)
|
||||
#include "targets/taranis/gx12/bsp_io.h"
|
||||
#endif
|
||||
#define DELAY_POS_MARGIN 3
|
||||
|
||||
uint8_t s_mixer_first_run_done = false;
|
||||
@@ -1144,6 +1147,11 @@ void evalMixes(uint8_t tick10ms)
|
||||
static uint16_t delta = 0;
|
||||
static uint16_t flightModesFade = 0;
|
||||
|
||||
#if defined(RADIO_GX12)
|
||||
// see #6159
|
||||
_poll_switches();
|
||||
#endif
|
||||
|
||||
uint8_t fm = getFlightMode();
|
||||
|
||||
if (lastFlightMode != fm) {
|
||||
|
||||
@@ -42,6 +42,10 @@ struct hw_switch_def {
|
||||
|
||||
int8_t switchesStates[MAX_SWITCHES];
|
||||
|
||||
#if defined(RADIO_GX12)
|
||||
void _poll_switches() {}
|
||||
#endif
|
||||
|
||||
void simuSetSwitch(uint8_t swtch, int8_t state)
|
||||
{
|
||||
assert(swtch < switchGetMaxAllSwitches());
|
||||
|
||||
@@ -19,24 +19,16 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "hal/switch_driver.h"
|
||||
#include "drivers/pca95xx.h"
|
||||
#include "hal/switch_driver.h"
|
||||
#include "myeeprom.h"
|
||||
#include "stm32_i2c_driver.h"
|
||||
#include "timers_driver.h"
|
||||
#include "delays_driver.h"
|
||||
#include "stm32_ws2812.h"
|
||||
#include "stm32_switch_driver.h"
|
||||
|
||||
#include "os/async.h"
|
||||
#include "os/timer.h"
|
||||
|
||||
#include "myeeprom.h"
|
||||
|
||||
constexpr uint8_t MAX_UNREAD_CYCLE = 100; // Force a read every 100 cycles even if no interrupt was triggered
|
||||
#define IO_INT_GPIO GPIO_PIN(GPIOE, 14)
|
||||
#define IO_RESET_GPIO GPIO_PIN(GPIOE, 15)
|
||||
|
||||
extern const stm32_switch_t* boardGetSwitchDef(uint8_t idx);
|
||||
extern bool suspendI2CTasks;
|
||||
|
||||
struct bsp_io_expander {
|
||||
pca95xx_t exp;
|
||||
@@ -44,17 +36,19 @@ struct bsp_io_expander {
|
||||
uint32_t state;
|
||||
};
|
||||
|
||||
static volatile bool _poll_switches_in_queue = false;
|
||||
|
||||
static volatile uint8_t _poll_switches_cnt = 0;
|
||||
static bsp_io_expander _io_switches;
|
||||
static bsp_io_expander _io_fs_switches;
|
||||
|
||||
static timer_handle_t _poll_timer = TIMER_INITIALIZER;
|
||||
static void _io_int_handler()
|
||||
{
|
||||
_poll_switches_cnt = 0;
|
||||
}
|
||||
|
||||
static void _init_io_expander(bsp_io_expander* io, uint32_t mask)
|
||||
{
|
||||
io->mask = mask;
|
||||
io->state = 0;
|
||||
io->state = 0;
|
||||
}
|
||||
|
||||
static uint32_t _read_io_expander(bsp_io_expander* io)
|
||||
@@ -68,46 +62,28 @@ static uint32_t _read_io_expander(bsp_io_expander* io)
|
||||
delay_us(1); // Only 6ns are needed according to PCA datasheet, but lets be safe
|
||||
gpio_set(IO_RESET_GPIO);
|
||||
}
|
||||
return io->state;
|
||||
return io->state;
|
||||
}
|
||||
|
||||
typedef enum {
|
||||
TRIGGERED_BY_TIMER = 0,
|
||||
TRIGGERED_BY_IRQ,
|
||||
} trigger_source_t;
|
||||
|
||||
static void _poll_switches(void *param1, uint32_t trigger_source)
|
||||
void _poll_switches()
|
||||
{
|
||||
(void)param1;
|
||||
|
||||
if (trigger_source == TRIGGERED_BY_IRQ) {
|
||||
_poll_switches_in_queue = false;
|
||||
timer_reset(&_poll_timer);
|
||||
if ( _poll_switches_cnt == 0) {
|
||||
_read_io_expander(&_io_switches);
|
||||
_read_io_expander(&_io_fs_switches);
|
||||
_poll_switches_cnt = MAX_UNREAD_CYCLE;
|
||||
} else {
|
||||
_poll_switches_cnt--;
|
||||
}
|
||||
|
||||
// Suspend hardware reads when required
|
||||
if (suspendI2CTasks) return;
|
||||
|
||||
_read_io_expander(&_io_switches);
|
||||
_read_io_expander(&_io_fs_switches);
|
||||
}
|
||||
|
||||
static void _io_int_handler()
|
||||
uint32_t bsp_io_read_switches()
|
||||
{
|
||||
async_call_isr(_poll_switches, &_poll_switches_in_queue, nullptr,
|
||||
TRIGGERED_BY_IRQ);
|
||||
return _read_io_expander(&_io_switches);
|
||||
}
|
||||
|
||||
static void _poll_cb(timer_handle_t* timer)
|
||||
uint32_t bsp_io_read_fs_switches()
|
||||
{
|
||||
(void)timer;
|
||||
_poll_switches(nullptr, TRIGGERED_BY_TIMER);
|
||||
}
|
||||
|
||||
static void start_poll_timer()
|
||||
{
|
||||
timer_create(&_poll_timer, _poll_cb, "portex", 100, true);
|
||||
timer_start(&_poll_timer);
|
||||
return _read_io_expander(&_io_fs_switches);
|
||||
}
|
||||
|
||||
int bsp_io_init()
|
||||
@@ -135,10 +111,8 @@ int bsp_io_init()
|
||||
gpio_init(IO_RESET_GPIO, GPIO_OUT, GPIO_PIN_SPEED_LOW);
|
||||
gpio_set(IO_RESET_GPIO);
|
||||
|
||||
_read_io_expander(&_io_switches);
|
||||
_read_io_expander(&_io_fs_switches);
|
||||
|
||||
start_poll_timer();
|
||||
bsp_io_read_switches();
|
||||
bsp_io_read_fs_switches();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -148,6 +122,14 @@ void boardInitSwitches()
|
||||
bsp_io_init();
|
||||
}
|
||||
|
||||
struct bsp_io_sw_def {
|
||||
uint32_t pin_high;
|
||||
uint32_t pin_low;
|
||||
};
|
||||
|
||||
static constexpr uint32_t RGB_OFFSET = (1 << 16); // first after bspio pins
|
||||
static uint16_t soft2POSLogicalState = 0xFFFF;
|
||||
|
||||
static SwitchHwPos _get_switch_pos(uint8_t idx)
|
||||
{
|
||||
SwitchHwPos pos = SWITCH_HW_UP;
|
||||
@@ -161,8 +143,7 @@ static SwitchHwPos _get_switch_pos(uint8_t idx)
|
||||
} else {
|
||||
return SWITCH_HW_UP;
|
||||
}
|
||||
}
|
||||
else if (!def->Pin_low) {
|
||||
} else if (!def->Pin_low) {
|
||||
// 2POS switch
|
||||
if ((state & def->Pin_high) == 0) {
|
||||
pos = SWITCH_HW_DOWN;
|
||||
@@ -194,7 +175,6 @@ static SwitchHwPos _get_fs_switch_pos(uint8_t idx)
|
||||
|
||||
SwitchHwPos boardSwitchGetPosition(uint8_t idx)
|
||||
{
|
||||
if (idx < 8)
|
||||
return _get_switch_pos(idx);
|
||||
if (idx < 8) return _get_switch_pos(idx);
|
||||
return _get_fs_switch_pos(idx);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* Based on code named
|
||||
* opentx - https://github.com/opentx/opentx
|
||||
* th9x - http://code.google.com/p/th9x
|
||||
* er9x - http://code.google.com/p/er9x
|
||||
* gruvin9x - http://code.google.com/p/gruvin9x
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
void _poll_switches();
|
||||
Reference in New Issue
Block a user