Bsongis/rotary encoder delay (#6503)

Rotary encoder fixed on X10 / X12S
This commit is contained in:
Bertrand Songis
2019-06-14 19:19:52 +02:00
committed by GitHub
parent 618bcfe72f
commit 55ec942610
16 changed files with 195 additions and 146 deletions
-2
View File
@@ -588,8 +588,6 @@ void audioTimerCountdown(uint8_t timer, int value);
#define AUDIO_TRAINER_LOST() audioEvent(AU_TRAINER_LOST)
#define AUDIO_TRAINER_BACK() audioEvent(AU_TRAINER_BACK)
#define AUDIO_HEARTBEAT()
enum AutomaticPromptsCategories {
SYSTEM_AUDIO_CATEGORY,
MODEL_AUDIO_CATEGORY,
+55
View File
@@ -0,0 +1,55 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* 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.
*/
#ifndef _DEBOUNCE_H_
#define _DEBOUNCE_H_
#include "board.h"
template <class T>
class Debounce
{
public:
T debounce(T state)
{
if (state == lastState)
debouncedState = state;
else
lastState = state;
return debouncedState;
}
private:
T lastState;
T debouncedState;
};
#if defined(STM32)
class PinDebounce: public Debounce<uint8_t>
{
public:
uint8_t debounce(GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
{
return Debounce<uint8_t>::debounce(GPIO_ReadInputDataBit(GPIOx, GPIO_Pin));
}
};
#endif
#endif // _DEBOUNCE_H_
+1 -2
View File
@@ -28,6 +28,7 @@
#include <math.h>
#include "definitions.h"
#include "opentx_types.h"
#include "debounce.h"
#if defined(STM32)
#include "usbd_conf.h"
@@ -542,8 +543,6 @@ bool setTrimValue(uint8_t phase, uint8_t idx, int trim);
#if 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
@@ -201,7 +201,7 @@ int main()
AUX_SERIAL_RCC_AHB1Periph | I2C_RCC_AHB1Periph |
SD_RCC_AHB1Periph, ENABLE);
RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph |
RCC_APB1PeriphClockCmd(ROTARY_ENCODER_RCC_APB1Periph | LCD_RCC_APB1Periph | BACKLIGHT_RCC_APB1Periph |
INTERRUPT_xMS_RCC_APB1Periph | I2C_RCC_APB1Periph |
AUX_SERIAL_RCC_APB1Periph |
SD_RCC_APB1Periph, ENABLE);
@@ -20,7 +20,7 @@
#include "opentx.h"
uint32_t rotencPosition;
uint8_t rotencPosition;
void rotaryEncoderInit()
{
@@ -56,19 +56,29 @@ void rotaryEncoderInit()
#endif
rotencPosition = ROTARY_ENCODER_POSITION();
ROTARY_ENCODER_TIMER->ARR = 99; // 100uS
ROTARY_ENCODER_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS
ROTARY_ENCODER_TIMER->CCER = 0;
ROTARY_ENCODER_TIMER->CCMR1 = 0;
ROTARY_ENCODER_TIMER->EGR = 0;
ROTARY_ENCODER_TIMER->CR1 = 0;
ROTARY_ENCODER_TIMER->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(ROTARY_ENCODER_TIMER_IRQn);
NVIC_SetPriority(ROTARY_ENCODER_TIMER_IRQn, 7);
}
void rotaryEncoderCheck()
{
uint32_t newpos = ROTARY_ENCODER_POSITION();
if (newpos != rotencPosition && !keyState(KEY_ENTER)) {
if ((rotencPosition & 0x01) ^ ((newpos & 0x02) >> 1)) {
uint8_t newPosition = ROTARY_ENCODER_POSITION();
if (newPosition != rotencPosition && !keyState(KEY_ENTER)) {
if ((rotencPosition & 0x01) ^ ((newPosition & 0x02) >> 1)) {
--rotencValue;
}
else {
++rotencValue;
}
rotencPosition = newpos;
rotencPosition = newPosition;
#if !defined(BOOT)
if (g_eeGeneral.backlightMode & e_backlight_mode_keys) {
backlightOn();
@@ -77,16 +87,21 @@ void rotaryEncoderCheck()
}
}
void rotaryEncoderStartDelay()
{
ROTARY_ENCODER_TIMER->CR1 = TIM_CR1_CEN | TIM_CR1_URS;
}
extern "C" void ROTARY_ENCODER_EXTI_IRQHandler1(void)
{
if (EXTI_GetITStatus(ROTARY_ENCODER_EXTI_LINE1) != RESET) {
rotaryEncoderCheck();
rotaryEncoderStartDelay();
EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE1);
}
#if !defined(ROTARY_ENCODER_EXTI_IRQn2)
if (EXTI_GetITStatus(ROTARY_ENCODER_EXTI_LINE2) != RESET) {
rotaryEncoderCheck();
rotaryEncoderStartDelay();
EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE2);
}
#endif
@@ -100,8 +115,15 @@ extern "C" void ROTARY_ENCODER_EXTI_IRQHandler1(void)
extern "C" void ROTARY_ENCODER_EXTI_IRQHandler2(void)
{
if (EXTI_GetITStatus(ROTARY_ENCODER_EXTI_LINE2) != RESET) {
rotaryEncoderCheck();
rotaryEncoderStartDelay();
EXTI_ClearITPendingBit(ROTARY_ENCODER_EXTI_LINE2);
}
}
#endif
extern "C" void ROTARY_ENCODER_TIMER_IRQHandler(void)
{
ROTARY_ENCODER_TIMER->SR &= ~TIM_SR_UIF;
ROTARY_ENCODER_TIMER->CR1 = 0;
rotaryEncoderCheck();
}
@@ -0,0 +1,79 @@
/*
* Copyright (C) OpenTX
*
* Based on code named
* 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 "opentx.h"
// Start TIMER at 2000000Hz
void init2MhzTimer()
{
TIMER_2MHz_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5 uS, 2 MHz
TIMER_2MHz_TIMER->ARR = 65535;
TIMER_2MHz_TIMER->CR2 = 0;
TIMER_2MHz_TIMER->CR1 = TIM_CR1_CEN;
}
// Start TIMER at 200Hz
void init5msTimer()
{
INTERRUPT_xMS_TIMER->ARR = 4999; // 5mS in uS
INTERRUPT_xMS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS
INTERRUPT_xMS_TIMER->CCER = 0;
INTERRUPT_xMS_TIMER->CCMR1 = 0;
INTERRUPT_xMS_TIMER->EGR = 0;
INTERRUPT_xMS_TIMER->CR1 = TIM_CR1_CEN | TIM_CR1_URS;
INTERRUPT_xMS_TIMER->DIER |= TIM_DIER_UIE;
NVIC_EnableIRQ(INTERRUPT_xMS_IRQn);
NVIC_SetPriority(INTERRUPT_xMS_IRQn, 7);
}
void stop5msTimer()
{
INTERRUPT_xMS_TIMER->CR1 = 0 ; // stop timer
NVIC_DisableIRQ(INTERRUPT_xMS_IRQn) ;
}
// TODO use the same than board_sky9x.cpp
void interrupt5ms()
{
static uint8_t pre_scale; // Used to get 10 Hz counter
++pre_scale;
#if defined(HAPTIC)
DEBUG_TIMER_START(debugTimerHaptic);
HAPTIC_HEARTBEAT();
DEBUG_TIMER_STOP(debugTimerHaptic);
#endif
if (pre_scale == 2) {
pre_scale = 0;
DEBUG_TIMER_START(debugTimerPer10ms);
DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod);
per10ms();
DEBUG_TIMER_STOP(debugTimerPer10ms);
}
}
extern "C" void INTERRUPT_xMS_IRQHandler()
{
INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF;
interrupt5ms();
DEBUG_INTERRUPT(INT_1MS);
}
@@ -49,23 +49,8 @@ void setSelectedUsbMode(int mode)
int usbPlugged()
{
// debounce
static uint8_t debounced_state = 0;
static uint8_t last_state = 0;
if (GPIO_ReadInputDataBit(USB_GPIO, USB_GPIO_PIN_VBUS)) {
if (last_state) {
debounced_state = 1;
}
last_state = 1;
}
else {
if (!last_state) {
debounced_state = 0;
}
last_state = 0;
}
return debounced_state;
static PinDebounce debounce;
return debounce.debounce(USB_GPIO, USB_GPIO_PIN_VBUS);
}
USB_OTG_CORE_HANDLE USB_OTG_dev;
+1
View File
@@ -128,6 +128,7 @@ set(TARGET_SRC
led_driver.cpp
extmodule_driver.cpp
trainer_driver.cpp
../common/arm/stm32/timers_driver.cpp
../common/arm/stm32/intmodule_serial_driver.cpp
../common/arm/stm32/bluetooth_driver.cpp
../common/arm/stm32/rotary_encoder_driver.cpp
+3 -56
View File
@@ -41,60 +41,6 @@ void watchdogInit(unsigned int duration)
IWDG->KR = 0xCCCC; // start
}
// Start TIMER7 at 2000000Hz
void init2MhzTimer()
{
TIMER_2MHz_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1; // 0.5 uS, 2 MHz
TIMER_2MHz_TIMER->ARR = 65535;
TIMER_2MHz_TIMER->CR2 = 0;
TIMER_2MHz_TIMER->CR1 = TIM_CR1_CEN;
}
// Starts TIMER at 1000Hz
void init1msTimer()
{
INTERRUPT_xMS_TIMER->ARR = 999; // 1mS in uS
INTERRUPT_xMS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1; // 1uS
INTERRUPT_xMS_TIMER->CCER = 0;
INTERRUPT_xMS_TIMER->CCMR1 = 0;
INTERRUPT_xMS_TIMER->EGR = 0;
INTERRUPT_xMS_TIMER->CR1 = 5;
INTERRUPT_xMS_TIMER->DIER |= 1;
NVIC_EnableIRQ(INTERRUPT_xMS_IRQn);
NVIC_SetPriority(INTERRUPT_xMS_IRQn, 7);
}
// TODO use the same than board_sky9x.cpp
void interrupt1ms()
{
static uint8_t pre_scale; // Used to get 10 Hz counter
++pre_scale;
#if defined(HAPTIC)
if (pre_scale == 5 || pre_scale == 10) {
DEBUG_TIMER_START(debugTimerHaptic);
HAPTIC_HEARTBEAT();
DEBUG_TIMER_STOP(debugTimerHaptic);
}
#endif
if (pre_scale == 10) {
pre_scale = 0;
DEBUG_TIMER_START(debugTimerPer10ms);
DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod);
per10ms();
DEBUG_TIMER_STOP(debugTimerPer10ms);
}
}
extern "C" void INTERRUPT_xMS_IRQHandler()
{
INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF;
interrupt1ms();
DEBUG_INTERRUPT(INT_1MS);
}
#if defined(SEMIHOSTING)
extern "C" void initialise_monitor_handles();
#endif
@@ -150,7 +96,8 @@ void boardInit()
SPORT_UPDATE_RCC_AHB1Periph,
ENABLE);
RCC_APB1PeriphClockCmd(INTERRUPT_xMS_RCC_APB1Periph |
RCC_APB1PeriphClockCmd(ROTARY_ENCODER_RCC_APB1Periph |
INTERRUPT_xMS_RCC_APB1Periph |
ADC_RCC_APB1Periph |
TIMER_2MHz_RCC_APB1Periph |
AUDIO_RCC_APB1Periph |
@@ -208,7 +155,7 @@ void boardInit()
backlightInit();
init2MhzTimer();
init1msTimer();
init5msTimer();
usbInit();
hapticInit();
+4
View File
@@ -112,6 +112,10 @@ void boardPreInit(void);
void boardInit(void);
void boardOff(void);
// Timers driver
void init2MhzTimer();
void init5msTimer();
// Delays driver
#ifdef __cplusplus
extern "C" {
+4
View File
@@ -54,6 +54,7 @@
#endif
// Rotary Encoder
#define ROTARY_ENCODER_RCC_APB1Periph RCC_APB1Periph_TIM4
#define ROTARY_ENCODER_GPIO GPIOH
#define ROTARY_ENCODER_GPIO_PIN_A GPIO_Pin_11 // PH.11
#define ROTARY_ENCODER_GPIO_PIN_B GPIO_Pin_10 // PH.10
@@ -65,6 +66,9 @@
#define ROTARY_ENCODER_EXTI_PortSource EXTI_PortSourceGPIOH
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource11
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource10
#define ROTARY_ENCODER_TIMER TIM4
#define ROTARY_ENCODER_TIMER_IRQn TIM4_IRQn
#define ROTARY_ENCODER_TIMER_IRQHandler TIM4_IRQHandler
// Switches
#define STORAGE_SWITCH_A
-1
View File
@@ -148,7 +148,6 @@ void interrupt5ms()
static uint32_t pre_scale ; // Used to get 10 Hz counter
HAPTIC_HEARTBEAT();
AUDIO_HEARTBEAT();
if ( ++pre_scale >= 2 ) {
BUZZER_HEARTBEAT();
+1
View File
@@ -253,6 +253,7 @@ set(TARGET_SRC
backlight_driver.cpp
extmodule_driver.cpp
trainer_driver.cpp
../common/arm/stm32/timers_driver.cpp
../common/arm/stm32/audio_dac_driver.cpp
../common/arm/stm32/adc_driver.cpp
../common/arm/stm32/heartbeat_driver.cpp
+2 -59
View File
@@ -41,64 +41,6 @@ void watchdogInit(unsigned int duration)
IWDG->KR = 0xCCCC; // start
}
// Starts TIMER at 2MHz
void init2MhzTimer()
{
TIMER_2MHz_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 2000000 - 1 ; // 0.5 uS, 2 MHz
TIMER_2MHz_TIMER->ARR = 65535;
TIMER_2MHz_TIMER->CR2 = 0;
TIMER_2MHz_TIMER->CR1 = TIM_CR1_CEN;
}
// Starts TIMER at 200Hz (5ms)
void init5msTimer()
{
INTERRUPT_xMS_TIMER->ARR = 4999 ; // 5mS in uS
INTERRUPT_xMS_TIMER->PSC = (PERI1_FREQUENCY * TIMER_MULT_APB1) / 1000000 - 1 ; // 1uS
INTERRUPT_xMS_TIMER->CCER = 0 ;
INTERRUPT_xMS_TIMER->CCMR1 = 0 ;
INTERRUPT_xMS_TIMER->EGR = 0 ;
INTERRUPT_xMS_TIMER->CR1 = 5 ;
INTERRUPT_xMS_TIMER->DIER |= 1 ;
NVIC_EnableIRQ(INTERRUPT_xMS_IRQn) ;
NVIC_SetPriority(INTERRUPT_xMS_IRQn, 7);
}
void stop5msTimer( void )
{
INTERRUPT_xMS_TIMER->CR1 = 0 ; // stop timer
NVIC_DisableIRQ(INTERRUPT_xMS_IRQn) ;
}
// TODO use the same than board_sky9x.cpp
void interrupt5ms()
{
static uint32_t pre_scale ; // Used to get 10 Hz counter
AUDIO_HEARTBEAT();
#if defined(HAPTIC)
HAPTIC_HEARTBEAT();
#endif
if (++pre_scale >= 2) {
pre_scale = 0 ;
DEBUG_TIMER_START(debugTimerPer10ms);
DEBUG_TIMER_SAMPLE(debugTimerPer10msPeriod);
per10ms();
DEBUG_TIMER_STOP(debugTimerPer10ms);
}
}
#if !defined(SIMU)
extern "C" void INTERRUPT_xMS_IRQHandler()
{
INTERRUPT_xMS_TIMER->SR &= ~TIM_SR_UIF ;
interrupt5ms() ;
DEBUG_INTERRUPT(INT_5MS);
}
#endif
#if defined(PWR_BUTTON_PRESS)
#define PWR_PRESS_DURATION_MIN 100 // 1s
#define PWR_PRESS_DURATION_MAX 500 // 5s
@@ -160,7 +102,8 @@ void boardInit()
GYRO_RCC_AHB1Periph,
ENABLE);
RCC_APB1PeriphClockCmd(LCD_RCC_APB1Periph |
RCC_APB1PeriphClockCmd(ROTARY_ENCODER_RCC_APB1Periph |
LCD_RCC_APB1Periph |
AUDIO_RCC_APB1Periph |
ADC_RCC_APB1Periph |
BACKLIGHT_RCC_APB1Periph |
+4
View File
@@ -124,6 +124,10 @@ void boardPreInit(void);
void boardInit(void);
void boardOff(void);
// Timers driver
void init2MhzTimer();
void init5msTimer();
// Delays driver
#ifdef __cplusplus
extern "C" {
+8
View File
@@ -135,6 +135,14 @@
#define ROTARY_ENCODER_EXTI_PinSource1 EXTI_PinSource10
#define ROTARY_ENCODER_EXTI_PinSource2 EXTI_PinSource12
#endif
#if defined(ROTARY_ENCODER_NAVIGATION)
#define ROTARY_ENCODER_RCC_APB1Periph RCC_APB1Periph_TIM5
#define ROTARY_ENCODER_TIMER TIM5
#define ROTARY_ENCODER_TIMER_IRQn TIM5_IRQn
#define ROTARY_ENCODER_TIMER_IRQHandler TIM5_IRQHandler
#else
#define ROTARY_ENCODER_RCC_APB1Periph 0
#endif
// Trims
#if defined(PCBX9E)