improved Horus rotary encoder driver and generic behavior (#5510)
Improved Horus rotary encoder driver
This commit is contained in:
committed by
Bertrand Songis
parent
04547a9206
commit
d13e770ac4
+30
-16
@@ -135,27 +135,41 @@ void per10ms()
|
||||
#if defined(ROTARY_ENCODER_NAVIGATION)
|
||||
if (IS_ROTARY_ENCODER_NAVIGATION_ENABLE()) {
|
||||
static rotenc_t rePreviousValue;
|
||||
static bool cw = false;
|
||||
rotenc_t reNewValue = (ROTARY_ENCODER_NAVIGATION_VALUE / ROTARY_ENCODER_GRANULARITY);
|
||||
int8_t scrollRE = reNewValue - rePreviousValue;
|
||||
rotenc_t scrollRE = reNewValue - rePreviousValue;
|
||||
if (scrollRE) {
|
||||
static uint32_t lastEvent;
|
||||
rePreviousValue = reNewValue;
|
||||
putEvent(scrollRE < 0 ? EVT_ROTARY_LEFT : EVT_ROTARY_RIGHT);
|
||||
}
|
||||
|
||||
bool new_cw = (scrollRE < 0) ? false : true;
|
||||
if ((g_tmr10ms - lastEvent >= 10) || (cw == new_cw)) { // 100ms
|
||||
|
||||
putEvent(new_cw ? EVT_ROTARY_RIGHT : EVT_ROTARY_LEFT);
|
||||
|
||||
#if defined(CPUARM)
|
||||
// rotary encoder navigation speed (acceleration) detection/calculation
|
||||
if (scrollRE) {
|
||||
static uint32_t lastTick = 0;
|
||||
static uint32_t delay = 0;
|
||||
delay = (((get_tmr10ms() - lastTick) << 3) + delay) >> 1; // Modified moving average filter used for smoother change of speed
|
||||
lastTick = get_tmr10ms();
|
||||
if (delay < ROTENC_DELAY_HIGHSPEED)
|
||||
rotencSpeed = ROTENC_HIGHSPEED;
|
||||
else if (delay < ROTENC_DELAY_MIDSPEED)
|
||||
rotencSpeed = ROTENC_MIDSPEED;
|
||||
else
|
||||
rotencSpeed = ROTENC_LOWSPEED;
|
||||
}
|
||||
// rotary encoder navigation speed (acceleration) detection/calculation
|
||||
static uint32_t delay = 2*ROTENC_DELAY_MIDSPEED;
|
||||
|
||||
if (new_cw == cw) {
|
||||
// Modified moving average filter used for smoother change of speed
|
||||
delay = (((g_tmr10ms - lastEvent) << 3) + delay) >> 1;
|
||||
}
|
||||
else {
|
||||
delay = 2*ROTENC_DELAY_MIDSPEED;
|
||||
}
|
||||
|
||||
if (delay < ROTENC_DELAY_HIGHSPEED)
|
||||
rotencSpeed = ROTENC_HIGHSPEED;
|
||||
else if (delay < ROTENC_DELAY_MIDSPEED)
|
||||
rotencSpeed = ROTENC_MIDSPEED;
|
||||
else
|
||||
rotencSpeed = ROTENC_LOWSPEED;
|
||||
#endif
|
||||
cw = new_cw;
|
||||
lastEvent = g_tmr10ms;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -769,6 +769,8 @@ int getTrimValue(uint8_t phase, uint8_t idx);
|
||||
#define ROTARY_ENCODER_GRANULARITY (1)
|
||||
#elif defined(PCBSKY9X)
|
||||
#define ROTARY_ENCODER_GRANULARITY (2 << g_eeGeneral.rotarySteps)
|
||||
#elif defined(PCBHORUS)
|
||||
#define ROTARY_ENCODER_GRANULARITY (1)
|
||||
#else
|
||||
#define ROTARY_ENCODER_GRANULARITY (2)
|
||||
#endif
|
||||
|
||||
@@ -20,7 +20,63 @@
|
||||
|
||||
#include "opentx.h"
|
||||
|
||||
uint32_t rotencPosition;
|
||||
/*
|
||||
* Rotary encoder handling based on state table:
|
||||
* Copyright (C) by Ben Buxton
|
||||
*
|
||||
* This includes the state table definition bellow
|
||||
* as well as the implementation of checkRotaryEncoder().
|
||||
*
|
||||
* The below state table has, for each state (row), the new state
|
||||
* to set based on the next encoder output. From left to right in,
|
||||
* the table, the encoder outputs are 00, 01, 10, 11, and the value
|
||||
* in that position is the new state to set.
|
||||
*/
|
||||
|
||||
#define R_START 0x0
|
||||
#define DIR_CW 0x10
|
||||
#define DIR_CCW 0x20
|
||||
|
||||
// Use the half-step state table (emits a code at 00 and 11)
|
||||
#define R_CCW_BEGIN 0x1
|
||||
#define R_CW_BEGIN 0x2
|
||||
#define R_START_M 0x3
|
||||
#define R_CW_BEGIN_M 0x4
|
||||
#define R_CCW_BEGIN_M 0x5
|
||||
const unsigned char rotenc_table[6][4] = {
|
||||
// R_START (00)
|
||||
{R_START_M, R_CW_BEGIN, R_CCW_BEGIN, R_START},
|
||||
// R_CCW_BEGIN
|
||||
{R_START_M | DIR_CCW, R_START, R_CCW_BEGIN, R_START},
|
||||
// R_CW_BEGIN
|
||||
{R_START_M | DIR_CW, R_CW_BEGIN, R_START, R_START},
|
||||
// R_START_M (11)
|
||||
{R_START_M, R_CCW_BEGIN_M, R_CW_BEGIN_M, R_START},
|
||||
// R_CW_BEGIN_M
|
||||
{R_START_M, R_START_M, R_CW_BEGIN_M, R_START | DIR_CW},
|
||||
// R_CCW_BEGIN_M
|
||||
{R_START_M, R_CCW_BEGIN_M, R_START_M, R_START | DIR_CCW},
|
||||
};
|
||||
|
||||
void checkRotaryEncoder()
|
||||
{
|
||||
static uint8_t state = 0;
|
||||
uint32_t pins = ROTARY_ENCODER_POSITION();
|
||||
|
||||
state = rotenc_table[state & 0x0F][pins];
|
||||
if ((state & 0x30) && !keyState(KEY_ENTER)) {
|
||||
if ((state & 0x30) == DIR_CW) {
|
||||
--rotencValue[0];
|
||||
}
|
||||
else {
|
||||
++rotencValue[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* End of the rotary encoder handler code
|
||||
*/
|
||||
|
||||
uint32_t readKeys()
|
||||
{
|
||||
@@ -91,20 +147,6 @@ uint8_t keyDown()
|
||||
return readKeys();
|
||||
}
|
||||
|
||||
void checkRotaryEncoder()
|
||||
{
|
||||
uint32_t newpos = ROTARY_ENCODER_POSITION();
|
||||
if (newpos != rotencPosition && !keyState(KEY_ENTER)) {
|
||||
if ((rotencPosition & 0x01) ^ ((newpos & 0x02) >> 1)) {
|
||||
--rotencValue[0];
|
||||
}
|
||||
else {
|
||||
++rotencValue[0];
|
||||
}
|
||||
rotencPosition = newpos;
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO common to ARM */
|
||||
void readKeysAndTrims()
|
||||
{
|
||||
@@ -239,6 +281,4 @@ void keysInit()
|
||||
|
||||
GPIO_InitStructure.GPIO_Pin = KEYS_GPIOJ_PINS;
|
||||
GPIO_Init(GPIOJ, &GPIO_InitStructure);
|
||||
|
||||
rotencPosition = ROTARY_ENCODER_POSITION();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user