feat: Flysky PL18U Support (#6114)
Co-authored-by: Peter Feerick <peter.feerick@gmail.com>
This commit is contained in:
co-authored by
Peter Feerick
parent
d81513d4f2
commit
f4c019bbb1
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hal/key_driver.h"
|
||||
|
||||
#include "stm32_hal_ll.h"
|
||||
#include "stm32_gpio_driver.h"
|
||||
|
||||
#include "hal.h"
|
||||
#include "delays_driver.h"
|
||||
#include "keys.h"
|
||||
|
||||
#define REPEAT_DELAY 20
|
||||
|
||||
/* The output bit-order has to be (D = L, U = R):
|
||||
PL18U
|
||||
0 LHL TR4L
|
||||
1 LHR TR4R
|
||||
2 LVD TR3D
|
||||
3 LVU TR3U
|
||||
4 RVD TR2D
|
||||
5 RVU TR2U
|
||||
6 RHL TR1L
|
||||
7 RHR TR1R
|
||||
8 LSD TR6D
|
||||
9 LSU TR6U
|
||||
10 RSD TR5D
|
||||
11 RSU TR5U
|
||||
|
||||
12 EX1D KLD
|
||||
13 EX1U KLU
|
||||
14 EX2D KRD
|
||||
15 EX2U KRU
|
||||
*/
|
||||
|
||||
enum PhysicalTrims
|
||||
{
|
||||
TR4L = 0,
|
||||
TR4R,
|
||||
TR3D = 2,
|
||||
TR3U,
|
||||
TR2D = 4,
|
||||
TR2U,
|
||||
TR1L = 6,
|
||||
TR1R,
|
||||
TR6D = 8,
|
||||
TR6U,
|
||||
TR5D = 10,
|
||||
TR5U,
|
||||
KLD = 12,
|
||||
KLU,
|
||||
KRD = 14,
|
||||
KRU,
|
||||
};
|
||||
|
||||
volatile uint32_t rotencDt = 0;
|
||||
static rotenc_t rotencValue = 0;
|
||||
static uint8_t lastRotState = 0;
|
||||
static uint8_t stateCount = 0;
|
||||
|
||||
void keysInit()
|
||||
{
|
||||
stm32_gpio_enable_clock(GPIOB);
|
||||
stm32_gpio_enable_clock(GPIOC);
|
||||
stm32_gpio_enable_clock(GPIOD);
|
||||
stm32_gpio_enable_clock(GPIOG);
|
||||
stm32_gpio_enable_clock(GPIOH);
|
||||
stm32_gpio_enable_clock(GPIOI);
|
||||
stm32_gpio_enable_clock(GPIOJ);
|
||||
|
||||
LL_GPIO_InitTypeDef pinInit;
|
||||
LL_GPIO_StructInit(&pinInit);
|
||||
pinInit.Mode = LL_GPIO_MODE_INPUT;
|
||||
pinInit.Pull = LL_GPIO_PULL_NO;
|
||||
|
||||
pinInit.Pin = KEYS_GPIOB_PINS;
|
||||
LL_GPIO_Init(GPIOB, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOC_PINS;
|
||||
LL_GPIO_Init(GPIOC, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOD_PINS;
|
||||
LL_GPIO_Init(GPIOD, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_GPIOJ_PINS;
|
||||
LL_GPIO_Init(GPIOJ, &pinInit);
|
||||
|
||||
// Matrix outputs
|
||||
pinInit.Mode = LL_GPIO_MODE_OUTPUT;
|
||||
pinInit.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
|
||||
|
||||
pinInit.Pin = KEYS_OUT_GPIOG_PINS;
|
||||
LL_GPIO_Init(GPIOG, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_OUT_GPIOH_PINS;
|
||||
LL_GPIO_Init(GPIOH, &pinInit);
|
||||
|
||||
pinInit.Pin = KEYS_OUT_GPIOI_PINS;
|
||||
LL_GPIO_Init(GPIOI, &pinInit);
|
||||
}
|
||||
|
||||
static uint32_t _readKeyMatrix()
|
||||
{
|
||||
// This function avoids concurrent matrix agitation
|
||||
|
||||
uint32_t result = 0;
|
||||
|
||||
volatile static struct
|
||||
{
|
||||
uint32_t oldResult = 0;
|
||||
uint8_t ui8ReadInProgress = 0;
|
||||
} syncelem;
|
||||
|
||||
if (syncelem.ui8ReadInProgress != 0) return syncelem.oldResult;
|
||||
|
||||
// ui8ReadInProgress was 0, increment it
|
||||
syncelem.ui8ReadInProgress++;
|
||||
// Double check before continuing, as non-atomic, non-blocking so far
|
||||
// If ui8ReadInProgress is above 1, then there was concurrent task calling it, exit
|
||||
if (syncelem.ui8ReadInProgress > 1) return syncelem.oldResult;
|
||||
|
||||
// If we land here, we have exclusive access to Matrix
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN);
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN);
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN);
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN);
|
||||
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << KLD;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << KLU;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << TR4L;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << TR4R;
|
||||
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT1, TRIMS_GPIO_OUT1_PIN);
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN);
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << TR3D;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << TR3U;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << TR2U;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << TR2D;
|
||||
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT2, TRIMS_GPIO_OUT2_PIN);
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN);
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << TR1R;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << TR1L;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << KRD;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << KRU;
|
||||
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT3, TRIMS_GPIO_OUT3_PIN);
|
||||
|
||||
LL_GPIO_ResetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN);
|
||||
delay_us(10);
|
||||
if (~TRIMS_GPIO_REG_IN1 & TRIMS_GPIO_PIN_IN1)
|
||||
result |= 1 << TR6U;
|
||||
if (~TRIMS_GPIO_REG_IN2 & TRIMS_GPIO_PIN_IN2)
|
||||
result |= 1 << TR6D;
|
||||
if (~TRIMS_GPIO_REG_IN3 & TRIMS_GPIO_PIN_IN3)
|
||||
result |= 1 << TR5D;
|
||||
if (~TRIMS_GPIO_REG_IN4 & TRIMS_GPIO_PIN_IN4)
|
||||
result |= 1 << TR5U;
|
||||
LL_GPIO_SetOutputPin(TRIMS_GPIO_OUT4, TRIMS_GPIO_OUT4_PIN);
|
||||
|
||||
syncelem.oldResult = result;
|
||||
syncelem.ui8ReadInProgress = 0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t readKeys()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
uint32_t mkeys = _readKeyMatrix();
|
||||
if (mkeys & (1 << KRD)) result |= 1 << KEY_ENTER;
|
||||
if (mkeys & (1 << KRU)) result |= 1 << KEY_EXIT;
|
||||
|
||||
uint8_t rotState = 0;
|
||||
if (mkeys & (1 << KLD)) rotState |= 1;
|
||||
if (mkeys & (1 << KLU)) rotState |= 2;
|
||||
|
||||
if (rotState != lastRotState) {
|
||||
lastRotState = rotState;
|
||||
stateCount = 0;
|
||||
} else {
|
||||
stateCount++;
|
||||
if (stateCount == 3) {
|
||||
if (rotState == 1)
|
||||
rotencValue++;
|
||||
else if (rotState == 2)
|
||||
rotencValue--;
|
||||
} else if (stateCount >= REPEAT_DELAY) {
|
||||
stateCount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
uint32_t readTrims()
|
||||
{
|
||||
uint32_t result = 0;
|
||||
|
||||
result |= _readKeyMatrix();
|
||||
result &= 0xfff; // Only 12 bits for 6 trims
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
rotenc_t rotaryEncoderGetValue()
|
||||
{
|
||||
return rotencValue;
|
||||
}
|
||||
|
||||
void rotaryEncoderInit()
|
||||
{
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user