improved Horus rotary encoder driver and generic behavior (#5510)

Improved Horus rotary encoder driver
This commit is contained in:
Raphael Coeffic
2017-12-18 23:12:29 +01:00
committed by Bertrand Songis
parent 04547a9206
commit d13e770ac4
3 changed files with 89 additions and 33 deletions
+30 -16
View File
@@ -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
+2
View File
@@ -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
+57 -17
View File
@@ -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();
}