🚸 New encoder logic & debounce (#26723)
Co-authored-by: Scott Lahteine <thinkyhead@users.noreply.github.com>
This commit is contained in:
@@ -893,10 +893,11 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FSMC/SPI TFT Panels (LVGL)
|
// FSMC/SPI TFT Panels (LVGL) with encoder click wheel
|
||||||
#if ENABLED(TFT_LVGL_UI)
|
#if ENABLED(TFT_LVGL_UI)
|
||||||
#define HAS_TFT_LVGL_UI 1
|
#define HAS_TFT_LVGL_UI 1
|
||||||
#define SERIAL_RUNTIME_HOOK 1
|
#define SERIAL_RUNTIME_HOOK 1
|
||||||
|
#define STD_ENCODER_PULSES_PER_STEP 4
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FSMC/SPI TFT Panels
|
// FSMC/SPI TFT Panels
|
||||||
@@ -976,6 +977,17 @@
|
|||||||
#define DETECT_I2C_LCD_DEVICE 1
|
#define DETECT_I2C_LCD_DEVICE 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ender-3 V2 DWIN with Encoder
|
||||||
|
*/
|
||||||
|
#if ANY(DWIN_CREALITY_LCD, DWIN_LCD_PROUI)
|
||||||
|
#define HAS_DWIN_E3V2_BASIC 1
|
||||||
|
#endif
|
||||||
|
#if ANY(HAS_DWIN_E3V2_BASIC, DWIN_CREALITY_LCD_JYERSUI)
|
||||||
|
#define HAS_DWIN_E3V2 1
|
||||||
|
#define STD_ENCODER_PULSES_PER_STEP 4
|
||||||
|
#endif
|
||||||
|
|
||||||
// Encoder behavior
|
// Encoder behavior
|
||||||
#ifndef STD_ENCODER_PULSES_PER_STEP
|
#ifndef STD_ENCODER_PULSES_PER_STEP
|
||||||
#if ENABLED(TOUCH_SCREEN)
|
#if ENABLED(TOUCH_SCREEN)
|
||||||
@@ -997,10 +1009,12 @@
|
|||||||
#define ENCODER_FEEDRATE_DEADZONE 6
|
#define ENCODER_FEEDRATE_DEADZONE 6
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Shift register panels
|
/**
|
||||||
// ---------------------
|
* Shift register panels
|
||||||
// 2 wire Non-latching LCD SR from:
|
* ---------------------
|
||||||
// https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection
|
* 2 wire Non-latching LCD SR from:
|
||||||
|
* https://github.com/fmalpartida/New-LiquidCrystal/wiki/schematics#user-content-ShiftRegister_connection
|
||||||
|
*/
|
||||||
#if ENABLED(FF_INTERFACEBOARD)
|
#if ENABLED(FF_INTERFACEBOARD)
|
||||||
#define SR_LCD_3W_NL // Non latching 3 wire shift register
|
#define SR_LCD_3W_NL // Non latching 3 wire shift register
|
||||||
#define IS_ULTIPANEL 1
|
#define IS_ULTIPANEL 1
|
||||||
@@ -1040,11 +1054,6 @@
|
|||||||
#define EXTENSIBLE_UI
|
#define EXTENSIBLE_UI
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Aliases for LCD features
|
|
||||||
#if ANY(DWIN_CREALITY_LCD, DWIN_LCD_PROUI, DWIN_CREALITY_LCD_JYERSUI)
|
|
||||||
#define HAS_DWIN_E3V2 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// E3V2 extras
|
// E3V2 extras
|
||||||
#if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI
|
#if HAS_DWIN_E3V2 || IS_DWIN_MARLINUI
|
||||||
#define SERIAL_CATCHALL 0
|
#define SERIAL_CATCHALL 0
|
||||||
|
@@ -24,9 +24,9 @@
|
|||||||
#include "../inc/MarlinConfig.h"
|
#include "../inc/MarlinConfig.h"
|
||||||
|
|
||||||
#if ((!HAS_ADC_BUTTONS && IS_NEWPANEL) || BUTTONS_EXIST(EN1, EN2)) && !IS_TFTGLCD_PANEL
|
#if ((!HAS_ADC_BUTTONS && IS_NEWPANEL) || BUTTONS_EXIST(EN1, EN2)) && !IS_TFTGLCD_PANEL
|
||||||
#define HAS_ENCODER_WHEEL 1
|
#define HAS_MARLINUI_ENCODER 1
|
||||||
#endif
|
#endif
|
||||||
#if (HAS_ENCODER_WHEEL || ANY_BUTTON(ENC, BACK, UP, DOWN, LEFT, RIGHT)) && DISABLED(TOUCH_UI_FTDI_EVE)
|
#if (HAS_MARLINUI_ENCODER || ANY_BUTTON(ENC, BACK, UP, DOWN, LEFT, RIGHT)) && DISABLED(TOUCH_UI_FTDI_EVE)
|
||||||
#define HAS_DIGITAL_BUTTONS 1
|
#define HAS_DIGITAL_BUTTONS 1
|
||||||
#endif
|
#endif
|
||||||
#if !HAS_ADC_BUTTONS && (IS_RRW_KEYPAD || (HAS_WIRED_LCD && !IS_NEWPANEL))
|
#if !HAS_ADC_BUTTONS && (IS_RRW_KEYPAD || (HAS_WIRED_LCD && !IS_NEWPANEL))
|
||||||
|
@@ -42,10 +42,6 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#ifndef ENCODER_PULSES_PER_STEP
|
|
||||||
#define ENCODER_PULSES_PER_STEP 4
|
|
||||||
#endif
|
|
||||||
|
|
||||||
EncoderRate encoderRate;
|
EncoderRate encoderRate;
|
||||||
|
|
||||||
// TODO: Replace with ui.quick_feedback
|
// TODO: Replace with ui.quick_feedback
|
||||||
@@ -53,32 +49,12 @@ void Encoder_tick() {
|
|||||||
TERN_(HAS_BEEPER, if (ui.sound_on) buzzer.click(10));
|
TERN_(HAS_BEEPER, if (ui.sound_on) buzzer.click(10));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encoder initialization
|
|
||||||
void encoderConfiguration() {
|
|
||||||
#if BUTTON_EXISTS(EN1)
|
|
||||||
SET_INPUT_PULLUP(BTN_EN1);
|
|
||||||
#endif
|
|
||||||
#if BUTTON_EXISTS(EN2)
|
|
||||||
SET_INPUT_PULLUP(BTN_EN2);
|
|
||||||
#endif
|
|
||||||
#if BUTTON_EXISTS(ENC)
|
|
||||||
SET_INPUT_PULLUP(BTN_ENC);
|
|
||||||
#endif
|
|
||||||
#if HAS_BEEPER
|
|
||||||
SET_OUTPUT(BEEPER_PIN); // TODO: Use buzzer.h which already inits this
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Analyze encoder value and return state
|
// Analyze encoder value and return state
|
||||||
EncoderState encoderReceiveAnalyze() {
|
EncoderState encoderReceiveAnalyze() {
|
||||||
const millis_t now = millis();
|
const millis_t now = millis();
|
||||||
static uint8_t lastEncoderBits;
|
static int8_t temp_diff = 0; // Cleared on each full step, as configured
|
||||||
uint8_t newbutton = 0;
|
|
||||||
static signed char temp_diff = 0;
|
|
||||||
|
|
||||||
EncoderState temp_diffState = ENCODER_DIFF_NO;
|
EncoderState temp_diffState = ENCODER_DIFF_NO;
|
||||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
|
||||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
|
||||||
if (BUTTON_PRESSED(ENC)) {
|
if (BUTTON_PRESSED(ENC)) {
|
||||||
static millis_t next_click_update_ms;
|
static millis_t next_click_update_ms;
|
||||||
if (ELAPSED(now, next_click_update_ms)) {
|
if (ELAPSED(now, next_click_update_ms)) {
|
||||||
@@ -98,71 +74,47 @@ EncoderState encoderReceiveAnalyze() {
|
|||||||
}
|
}
|
||||||
else return ENCODER_DIFF_NO;
|
else return ENCODER_DIFF_NO;
|
||||||
}
|
}
|
||||||
if (newbutton != lastEncoderBits) {
|
|
||||||
switch (newbutton) {
|
|
||||||
case 0:
|
|
||||||
if (lastEncoderBits == 1) temp_diff++;
|
|
||||||
else if (lastEncoderBits == 2) temp_diff--;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (lastEncoderBits == 0) temp_diff++;
|
|
||||||
else if (lastEncoderBits == 3) temp_diff--;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
if (lastEncoderBits == 2) temp_diff++;
|
|
||||||
else if (lastEncoderBits == 1) temp_diff--;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
if (lastEncoderBits == 3) temp_diff++;
|
|
||||||
else if (lastEncoderBits == 0) temp_diff--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lastEncoderBits = newbutton;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ABS(temp_diff) >= ENCODER_PULSES_PER_STEP) {
|
temp_diff += ui.get_encoder_delta();
|
||||||
if (temp_diff > 0) temp_diffState = TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CCW, ENCODER_DIFF_CW);
|
|
||||||
else temp_diffState = TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CW, ENCODER_DIFF_CCW);
|
const int8_t abs_diff = ABS(temp_diff);
|
||||||
|
if (abs_diff >= ENCODER_PULSES_PER_STEP) {
|
||||||
|
temp_diffState = temp_diff > 0
|
||||||
|
? TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CCW, ENCODER_DIFF_CW)
|
||||||
|
: TERN(REVERSE_ENCODER_DIRECTION, ENCODER_DIFF_CW, ENCODER_DIFF_CCW);
|
||||||
|
|
||||||
|
int32_t encoder_multiplier = 1;
|
||||||
|
|
||||||
#if ENABLED(ENCODER_RATE_MULTIPLIER)
|
#if ENABLED(ENCODER_RATE_MULTIPLIER)
|
||||||
|
|
||||||
millis_t ms = millis();
|
const millis_t ms = millis();
|
||||||
int32_t encoder_multiplier = 1;
|
|
||||||
|
|
||||||
// if must encoder rati multiplier
|
// Encoder rate multiplier
|
||||||
if (encoderRate.enabled) {
|
if (encoderRate.enabled) {
|
||||||
const float abs_diff = ABS(temp_diff),
|
// Note that the rate is always calculated between two passes through the
|
||||||
encoderMovementSteps = abs_diff / (ENCODER_PULSES_PER_STEP);
|
// loop and that the abs of the temp_diff value is tracked.
|
||||||
if (encoderRate.lastEncoderTime) {
|
const float encoderStepRate = ((float(abs_diff) / float(ENCODER_PULSES_PER_STEP)) * 1000.0f) / float(ms - encoderRate.lastEncoderTime);
|
||||||
// Note that the rate is always calculated between two passes through the
|
|
||||||
// loop and that the abs of the temp_diff value is tracked.
|
|
||||||
const float encoderStepRate = encoderMovementSteps / float(ms - encoderRate.lastEncoderTime) * 1000;
|
|
||||||
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
|
||||||
encoder_multiplier = 100;
|
|
||||||
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
|
||||||
encoder_multiplier = 10;
|
|
||||||
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
|
||||||
encoder_multiplier = 5;
|
|
||||||
}
|
|
||||||
encoderRate.lastEncoderTime = ms;
|
encoderRate.lastEncoderTime = ms;
|
||||||
|
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
||||||
|
encoder_multiplier = 100;
|
||||||
|
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
||||||
|
encoder_multiplier = 10;
|
||||||
|
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
||||||
|
encoder_multiplier = 5;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
constexpr int32_t encoder_multiplier = 1;
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// encoderRate.encoderMoveValue += (temp_diff * encoder_multiplier) / (ENCODER_PULSES_PER_STEP);
|
encoderRate.encoderMoveValue = abs_diff * encoder_multiplier / (ENCODER_PULSES_PER_STEP);
|
||||||
encoderRate.encoderMoveValue = (temp_diff * encoder_multiplier) / (ENCODER_PULSES_PER_STEP);
|
|
||||||
if (encoderRate.encoderMoveValue < 0) encoderRate.encoderMoveValue = -encoderRate.encoderMoveValue;
|
|
||||||
|
|
||||||
temp_diff = 0;
|
temp_diff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (temp_diffState != ENCODER_DIFF_NO) {
|
if (temp_diffState != ENCODER_DIFF_NO) {
|
||||||
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
|
TERN_(HAS_BACKLIGHT_TIMEOUT, ui.refresh_backlight_timeout());
|
||||||
if (!ui.backlight) ui.refresh_brightness();
|
if (!ui.backlight) ui.refresh_brightness();
|
||||||
}
|
}
|
||||||
|
|
||||||
return temp_diffState;
|
return temp_diffState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -47,9 +47,6 @@ typedef enum {
|
|||||||
|
|
||||||
#define ENCODER_WAIT_MS TERN(DWIN_LCD_PROUI, 10, 20)
|
#define ENCODER_WAIT_MS TERN(DWIN_LCD_PROUI, 10, 20)
|
||||||
|
|
||||||
// Encoder initialization
|
|
||||||
void encoderConfiguration();
|
|
||||||
|
|
||||||
// Analyze encoder value and return state
|
// Analyze encoder value and return state
|
||||||
EncoderState encoderReceiveAnalyze();
|
EncoderState encoderReceiveAnalyze();
|
||||||
|
|
||||||
|
@@ -4078,7 +4078,6 @@ void hmiInit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void dwinInitScreen() {
|
void dwinInitScreen() {
|
||||||
encoderConfiguration();
|
|
||||||
hmiInit();
|
hmiInit();
|
||||||
hmiSetLanguageCache();
|
hmiSetLanguageCache();
|
||||||
hmiStartFrame(true);
|
hmiStartFrame(true);
|
||||||
|
@@ -5143,7 +5143,6 @@ void MarlinUI::init_lcd() {
|
|||||||
if (dwinHandshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error.");
|
if (dwinHandshake()) SERIAL_ECHOLNPGM("ok."); else SERIAL_ECHOLNPGM("error.");
|
||||||
dwinFrameSetDir(1); // Orientation 90°
|
dwinFrameSetDir(1); // Orientation 90°
|
||||||
dwinUpdateLCD(); // Show bootscreen (first image)
|
dwinUpdateLCD(); // Show bootscreen (first image)
|
||||||
encoderConfiguration();
|
|
||||||
for (uint16_t t = 0; t <= 100; t += 2) {
|
for (uint16_t t = 0; t <= 100; t += 2) {
|
||||||
dwinIconShow(ICON, ICON_Bar, 15, 260);
|
dwinIconShow(ICON, ICON_Bar, 15, 260);
|
||||||
dwinDrawRectangle(1, COLOR_BG_BLACK, 15 + t * 242 / 100, 260, 257, 280);
|
dwinDrawRectangle(1, COLOR_BG_BLACK, 15 + t * 242 / 100, 260, 257, 280);
|
||||||
|
@@ -1910,7 +1910,6 @@ void MarlinUI::init_lcd() {
|
|||||||
const bool hs = dwinHandshake(); UNUSED(hs);
|
const bool hs = dwinHandshake(); UNUSED(hs);
|
||||||
dwinFrameSetDir(1);
|
dwinFrameSetDir(1);
|
||||||
dwinJPGCacheTo1(Language_English);
|
dwinJPGCacheTo1(Language_English);
|
||||||
encoderConfiguration();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dwinInitScreen() {
|
void dwinInitScreen() {
|
||||||
|
@@ -216,7 +216,6 @@ void tft_lvgl_init() {
|
|||||||
|
|
||||||
tft_style_init();
|
tft_style_init();
|
||||||
filament_pin_setup();
|
filament_pin_setup();
|
||||||
lv_encoder_pin_init();
|
|
||||||
|
|
||||||
#if ENABLED(MKS_WIFI_MODULE)
|
#if ENABLED(MKS_WIFI_MODULE)
|
||||||
mks_esp_wifi_init();
|
mks_esp_wifi_init();
|
||||||
@@ -331,12 +330,12 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int16_t enc_diff = 0;
|
int16_t enc_diff = 0;
|
||||||
lv_indev_state_t state = LV_INDEV_STATE_REL;
|
lv_indev_state_t indev_enc_state = LV_INDEV_STATE_REL; // ENC button is pressed or released
|
||||||
|
|
||||||
bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {
|
bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) {
|
||||||
(void) indev_drv; // Unused
|
UNUSED(indev_drv);
|
||||||
|
|
||||||
data->state = state;
|
data->state = indev_enc_state;
|
||||||
data->enc_diff = enc_diff;
|
data->enc_diff = enc_diff;
|
||||||
enc_diff = 0;
|
enc_diff = 0;
|
||||||
|
|
||||||
@@ -446,102 +445,50 @@ lv_fs_res_t sd_tell_cb(lv_fs_drv_t * drv, void * file_p, uint32_t * pos_p) {
|
|||||||
return LV_FS_RES_OK;
|
return LV_FS_RES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void lv_encoder_pin_init() {
|
void lv_update_encoder() {
|
||||||
#if BUTTON_EXISTS(EN1)
|
|
||||||
SET_INPUT_PULLUP(BTN_EN1);
|
#if ANY_BUTTON(EN1, EN2)
|
||||||
|
constexpr uint8_t epps = ENCODER_PULSES_PER_STEP; // We can fill in
|
||||||
|
static uint8_t pulse_count;
|
||||||
|
pulse_count += ui.get_encoder_delta();
|
||||||
|
const int8_t fullSteps = pulse_count / epps;
|
||||||
|
pulse_count -= fullSteps * epps;
|
||||||
|
enc_diff += fullSteps;
|
||||||
#endif
|
#endif
|
||||||
#if BUTTON_EXISTS(EN2)
|
|
||||||
SET_INPUT_PULLUP(BTN_EN2);
|
#if ANY_BUTTON(ENC, BACK, UP, DOWN, LEFT, RIGHT)
|
||||||
|
static millis_t last_encoder_ms;
|
||||||
|
const millis_t now = millis(), diffTime = getTickDiff(now, last_encoder_ms);
|
||||||
|
if (diffTime <= 50) return;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUTTON_EXISTS(ENC)
|
#if BUTTON_EXISTS(ENC)
|
||||||
SET_INPUT_PULLUP(BTN_ENC);
|
static uint8_t old_button_enc = LV_INDEV_STATE_REL;
|
||||||
|
const uint8_t enc_c = BUTTON_PRESSED(ENC) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||||
|
if (enc_c != old_button_enc) {
|
||||||
|
indev_enc_state = enc_c ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
||||||
|
old_button_enc = enc_c;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUTTON_EXISTS(BACK)
|
#if BUTTON_EXISTS(BACK)
|
||||||
SET_INPUT_PULLUP(BTN_BACK);
|
if (BUTTON_PRESSED(BACK)) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BUTTON_EXISTS(UP)
|
#if BUTTON_EXISTS(UP)
|
||||||
SET_INPUT(BTN_UP);
|
if (BUTTON_PRESSED(UP)) {}
|
||||||
#endif
|
#endif
|
||||||
#if BUTTON_EXISTS(DOWN)
|
#if BUTTON_EXISTS(DOWN)
|
||||||
SET_INPUT(BTN_DOWN);
|
if (BUTTON_PRESSED(DOWN)) {}
|
||||||
#endif
|
#endif
|
||||||
#if BUTTON_EXISTS(LEFT)
|
#if BUTTON_EXISTS(LEFT)
|
||||||
SET_INPUT(BTN_LEFT);
|
if (BUTTON_PRESSED(LEFT)) {}
|
||||||
#endif
|
#endif
|
||||||
#if BUTTON_EXISTS(RIGHT)
|
#if BUTTON_EXISTS(RIGHT)
|
||||||
SET_INPUT(BTN_RIGHT);
|
if (BUTTON_PRESSED(RIGHT)) {}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 1 // HAS_ENCODER_ACTION
|
|
||||||
|
|
||||||
void lv_update_encoder() {
|
|
||||||
static uint32_t encoder_time1;
|
|
||||||
uint32_t tmpTime, diffTime = 0;
|
|
||||||
tmpTime = millis();
|
|
||||||
diffTime = getTickDiff(tmpTime, encoder_time1);
|
|
||||||
if (diffTime > 50) {
|
|
||||||
|
|
||||||
#if HAS_ENCODER_WHEEL
|
|
||||||
|
|
||||||
#if ANY_BUTTON(EN1, EN2, ENC, BACK)
|
|
||||||
|
|
||||||
uint8_t newbutton = 0;
|
|
||||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
|
||||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
|
||||||
if (BUTTON_PRESSED(ENC)) newbutton |= EN_C;
|
|
||||||
if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
constexpr uint8_t newbutton = 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static uint8_t buttons = 0;
|
|
||||||
buttons = newbutton;
|
|
||||||
static uint8_t lastEncoderBits;
|
|
||||||
|
|
||||||
#define encrot0 0
|
|
||||||
#define encrot1 1
|
|
||||||
#define encrot2 2
|
|
||||||
|
|
||||||
uint8_t enc = 0;
|
|
||||||
if (buttons & EN_A) enc |= B01;
|
|
||||||
if (buttons & EN_B) enc |= B10;
|
|
||||||
if (enc != lastEncoderBits) {
|
|
||||||
switch (enc) {
|
|
||||||
case encrot1:
|
|
||||||
if (lastEncoderBits == encrot0) {
|
|
||||||
enc_diff--;
|
|
||||||
encoder_time1 = tmpTime;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case encrot2:
|
|
||||||
if (lastEncoderBits == encrot0) {
|
|
||||||
enc_diff++;
|
|
||||||
encoder_time1 = tmpTime;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
lastEncoderBits = enc;
|
|
||||||
}
|
|
||||||
static uint8_t last_button_state = LV_INDEV_STATE_REL;
|
|
||||||
const uint8_t enc_c = (buttons & EN_C) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
|
||||||
if (enc_c != last_button_state) {
|
|
||||||
state = enc_c ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
|
|
||||||
last_button_state = enc_c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAS_ENCODER_WHEEL
|
|
||||||
|
|
||||||
} // encoder_time1
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // HAS_ENCODER_ACTION
|
|
||||||
|
|
||||||
#ifdef __PLAT_NATIVE_SIM__
|
#ifdef __PLAT_NATIVE_SIM__
|
||||||
#include <lv_misc/lv_log.h>
|
#include <lv_misc/lv_log.h>
|
||||||
typedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char *, uint32_t, const char *);
|
typedef void (*lv_log_print_g_cb_t)(lv_log_level_t level, const char *, uint32_t, const char *);
|
||||||
|
@@ -41,7 +41,6 @@ bool my_touchpad_read(lv_indev_drv_t * indev_driver, lv_indev_data_t * data);
|
|||||||
bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
bool my_mousewheel_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data);
|
||||||
|
|
||||||
void lcdClear(uint16_t color);
|
void lcdClear(uint16_t color);
|
||||||
void lv_encoder_pin_init();
|
|
||||||
void lv_update_encoder();
|
void lv_update_encoder();
|
||||||
|
|
||||||
lv_fs_res_t spi_flash_open_cb(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
|
lv_fs_res_t spi_flash_open_cb(lv_fs_drv_t * drv, void * file_p, const char * path, lv_fs_mode_t mode);
|
||||||
|
@@ -227,34 +227,32 @@ void MarlinUI::init() {
|
|||||||
|
|
||||||
init_lcd();
|
init_lcd();
|
||||||
|
|
||||||
#if HAS_DIGITAL_BUTTONS
|
#if BUTTON_EXISTS(EN1)
|
||||||
#if BUTTON_EXISTS(EN1)
|
SET_INPUT_PULLUP(BTN_EN1);
|
||||||
SET_INPUT_PULLUP(BTN_EN1);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(EN2)
|
||||||
#if BUTTON_EXISTS(EN2)
|
SET_INPUT_PULLUP(BTN_EN2);
|
||||||
SET_INPUT_PULLUP(BTN_EN2);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(ENC)
|
||||||
#if BUTTON_EXISTS(ENC)
|
SET_INPUT_PULLUP(BTN_ENC);
|
||||||
SET_INPUT_PULLUP(BTN_ENC);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(ENC_EN)
|
||||||
#if BUTTON_EXISTS(ENC_EN)
|
SET_INPUT_PULLUP(BTN_ENC_EN);
|
||||||
SET_INPUT_PULLUP(BTN_ENC_EN);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(BACK)
|
||||||
#if BUTTON_EXISTS(BACK)
|
SET_INPUT_PULLUP(BTN_BACK);
|
||||||
SET_INPUT_PULLUP(BTN_BACK);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(UP)
|
||||||
#if BUTTON_EXISTS(UP)
|
SET_INPUT(BTN_UP);
|
||||||
SET_INPUT(BTN_UP);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(DOWN)
|
||||||
#if BUTTON_EXISTS(DOWN)
|
SET_INPUT(BTN_DOWN);
|
||||||
SET_INPUT(BTN_DOWN);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(LFT)
|
||||||
#if BUTTON_EXISTS(LFT)
|
SET_INPUT(BTN_LEFT);
|
||||||
SET_INPUT(BTN_LEFT);
|
#endif
|
||||||
#endif
|
#if BUTTON_EXISTS(RT)
|
||||||
#if BUTTON_EXISTS(RT)
|
SET_INPUT(BTN_RIGHT);
|
||||||
SET_INPUT(BTN_RIGHT);
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAS_SHIFT_ENCODER
|
#if HAS_SHIFT_ENCODER
|
||||||
@@ -1026,72 +1024,56 @@ void MarlinUI::init() {
|
|||||||
if (TERN0(IS_RRW_KEYPAD, handle_keypad()))
|
if (TERN0(IS_RRW_KEYPAD, handle_keypad()))
|
||||||
reset_status_timeout(ms);
|
reset_status_timeout(ms);
|
||||||
|
|
||||||
uint8_t abs_diff = ABS(encoderDiff);
|
static int8_t lastEncoderDiff;
|
||||||
|
if (lastEncoderDiff != encoderDiff) wake_display();
|
||||||
#if ENCODER_PULSES_PER_STEP > 1
|
lastEncoderDiff = encoderDiff;
|
||||||
// When reversing the encoder direction, a movement step can be missed because
|
|
||||||
// encoderDiff has a non-zero residual value, making the controller unresponsive.
|
|
||||||
// The fix clears the residual value when the encoder is idle.
|
|
||||||
// Also check if past half the threshold to compensate for missed single steps.
|
|
||||||
static int8_t lastEncoderDiff;
|
|
||||||
|
|
||||||
// Timeout? No decoder change since last check. 10 or 20 times per second.
|
|
||||||
if (encoderDiff == lastEncoderDiff && abs_diff <= epps / 2) // Same direction & size but not over a half-step?
|
|
||||||
encoderDiff = 0; // Clear residual pulses.
|
|
||||||
else if (WITHIN(abs_diff, epps / 2 + 1, epps - 1)) { // Past half of threshold?
|
|
||||||
abs_diff = epps; // Treat as a full step size
|
|
||||||
encoderDiff = (encoderDiff < 0 ? -1 : 1) * abs_diff; // ...in the spin direction.
|
|
||||||
}
|
|
||||||
if (lastEncoderDiff != encoderDiff) wake_display();
|
|
||||||
lastEncoderDiff = encoderDiff;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
const uint8_t abs_diff = ABS(encoderDiff);
|
||||||
const bool encoderPastThreshold = (abs_diff >= epps);
|
const bool encoderPastThreshold = (abs_diff >= epps);
|
||||||
if (encoderPastThreshold || lcd_clicked) {
|
if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) {
|
||||||
if (encoderPastThreshold && TERN1(IS_TFTGLCD_PANEL, !external_control)) {
|
|
||||||
|
|
||||||
#if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER)
|
int32_t encoder_multiplier = 1;
|
||||||
|
|
||||||
int32_t encoder_multiplier = 1;
|
#if ALL(HAS_MARLINUI_MENU, ENCODER_RATE_MULTIPLIER)
|
||||||
|
|
||||||
if (encoder_multiplier_enabled) {
|
if (encoder_multiplier_enabled) {
|
||||||
// Note that the rate is always calculated between two passes through the
|
// Note that the rate is always calculated between two passes through the
|
||||||
// loop and that the abs of the encoderDiff value is tracked.
|
// loop and that the abs of the encoderDiff value is tracked.
|
||||||
static millis_t encoder_mult_prev_ms = 0;
|
static millis_t encoder_mult_prev_ms = 0;
|
||||||
const float encoderStepRate = ((float(abs_diff) / float(epps)) * 1000.0f) / float(ms - encoder_mult_prev_ms);
|
const float encoderStepRate = ((float(abs_diff) / float(epps)) * 1000.0f) / float(ms - encoder_mult_prev_ms);
|
||||||
encoder_mult_prev_ms = ms;
|
encoder_mult_prev_ms = ms;
|
||||||
|
|
||||||
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
if (ENCODER_100X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_100X_STEPS_PER_SEC)
|
||||||
encoder_multiplier = 100;
|
encoder_multiplier = 100;
|
||||||
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
else if (ENCODER_10X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_10X_STEPS_PER_SEC)
|
||||||
encoder_multiplier = 10;
|
encoder_multiplier = 10;
|
||||||
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
else if (ENCODER_5X_STEPS_PER_SEC > 0 && encoderStepRate >= ENCODER_5X_STEPS_PER_SEC)
|
||||||
encoder_multiplier = 5;
|
encoder_multiplier = 5;
|
||||||
|
|
||||||
// Enable to output the encoder steps per second value
|
// Enable to output the encoder steps per second value
|
||||||
//#define ENCODER_RATE_MULTIPLIER_DEBUG
|
//#define ENCODER_RATE_MULTIPLIER_DEBUG
|
||||||
#if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG)
|
#if ENABLED(ENCODER_RATE_MULTIPLIER_DEBUG)
|
||||||
SERIAL_ECHO_MSG(
|
SERIAL_ECHO_MSG(
|
||||||
"Enc Step Rate: ", encoderStepRate,
|
"Enc Step Rate: ", encoderStepRate,
|
||||||
" Mult: ", encoder_multiplier,
|
" Mult: ", encoder_multiplier,
|
||||||
" 5X Steps: ", ENCODER_5X_STEPS_PER_SEC,
|
" 5X Steps: ", ENCODER_5X_STEPS_PER_SEC,
|
||||||
" 10X Steps: ", ENCODER_10X_STEPS_PER_SEC,
|
" 10X Steps: ", ENCODER_10X_STEPS_PER_SEC,
|
||||||
" 100X Steps: ", ENCODER_100X_STEPS_PER_SEC
|
" 100X Steps: ", ENCODER_100X_STEPS_PER_SEC
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#endif // ENCODER_RATE_MULTIPLIER
|
||||||
|
|
||||||
constexpr int32_t encoder_multiplier = 1;
|
const int8_t fullSteps = encoderDiff / epps;
|
||||||
|
if (fullSteps != 0) {
|
||||||
#endif // ENCODER_RATE_MULTIPLIER
|
encoderDiff -= fullSteps * epps;
|
||||||
|
if (can_encode() && !lcd_clicked)
|
||||||
if (can_encode()) encoderPosition += (encoderDiff * encoder_multiplier) / epps;
|
encoderPosition += (fullSteps * encoder_multiplier);
|
||||||
|
|
||||||
encoderDiff = 0;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (encoderPastThreshold || lcd_clicked) {
|
||||||
reset_status_timeout(ms);
|
reset_status_timeout(ms);
|
||||||
|
|
||||||
#if HAS_BACKLIGHT_TIMEOUT
|
#if HAS_BACKLIGHT_TIMEOUT
|
||||||
@@ -1312,124 +1294,156 @@ void MarlinUI::init() {
|
|||||||
*/
|
*/
|
||||||
void MarlinUI::update_buttons() {
|
void MarlinUI::update_buttons() {
|
||||||
const millis_t now = millis();
|
const millis_t now = millis();
|
||||||
if (ELAPSED(now, next_button_update_ms)) {
|
|
||||||
|
|
||||||
#if HAS_DIGITAL_BUTTONS
|
#if HAS_MARLINUI_ENCODER
|
||||||
|
|
||||||
#if ANY_BUTTON(EN1, EN2, ENC, BACK)
|
const int8_t delta = get_encoder_delta(now);
|
||||||
|
if (delta) {
|
||||||
uint8_t newbutton = 0;
|
encoderDiff += delta * encoderDirection;
|
||||||
if (BUTTON_PRESSED(EN1)) newbutton |= EN_A;
|
|
||||||
if (BUTTON_PRESSED(EN2)) newbutton |= EN_B;
|
|
||||||
if (can_encode() && BUTTON_PRESSED(ENC)) newbutton |= EN_C;
|
|
||||||
if (BUTTON_PRESSED(BACK)) newbutton |= EN_D;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
constexpr uint8_t newbutton = 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
|
||||||
// Directional buttons
|
|
||||||
//
|
|
||||||
#if ANY_BUTTON(UP, DOWN, LEFT, RIGHT)
|
|
||||||
|
|
||||||
const int8_t pulses = epps * encoderDirection;
|
|
||||||
|
|
||||||
if (BUTTON_PRESSED(UP)) {
|
|
||||||
encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
|
||||||
next_button_update_ms = now + 300;
|
|
||||||
}
|
|
||||||
else if (BUTTON_PRESSED(DOWN)) {
|
|
||||||
encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
|
||||||
next_button_update_ms = now + 300;
|
|
||||||
}
|
|
||||||
else if (BUTTON_PRESSED(LEFT)) {
|
|
||||||
encoderDiff = -pulses;
|
|
||||||
next_button_update_ms = now + 300;
|
|
||||||
}
|
|
||||||
else if (BUTTON_PRESSED(RIGHT)) {
|
|
||||||
encoderDiff = pulses;
|
|
||||||
next_button_update_ms = now + 300;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // UP || DOWN || LEFT || RIGHT
|
|
||||||
|
|
||||||
buttons = (newbutton | TERN0(HAS_SLOW_BUTTONS, slow_buttons)
|
|
||||||
#if ALL(HAS_TOUCH_BUTTONS, HAS_ENCODER_ACTION)
|
|
||||||
| (touch_buttons & TERN(HAS_ENCODER_WHEEL, ~(EN_A | EN_B), 0xFF))
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
|
|
||||||
#elif HAS_ADC_BUTTONS
|
|
||||||
|
|
||||||
buttons = 0;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAS_ADC_BUTTONS
|
|
||||||
if (keypad_buttons == 0) {
|
|
||||||
const uint8_t b = get_ADC_keyValue();
|
|
||||||
if (WITHIN(b, 1, 8)) keypad_buttons = _BV(b - 1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if HAS_SHIFT_ENCODER
|
|
||||||
/**
|
|
||||||
* Set up Rotary Encoder bit values (for two pin encoders to indicate movement).
|
|
||||||
* These values are independent of which pins are used for EN_A / EN_B indications.
|
|
||||||
* The rotary encoder part is also independent of the LCD chipset.
|
|
||||||
*/
|
|
||||||
uint8_t val = 0;
|
|
||||||
WRITE(SHIFT_LD_PIN, LOW);
|
|
||||||
WRITE(SHIFT_LD_PIN, HIGH);
|
|
||||||
for (uint8_t i = 0; i < 8; ++i) {
|
|
||||||
val >>= 1;
|
|
||||||
if (READ(SHIFT_OUT_PIN)) SBI(val, 7);
|
|
||||||
WRITE(SHIFT_CLK_PIN, HIGH);
|
|
||||||
WRITE(SHIFT_CLK_PIN, LOW);
|
|
||||||
}
|
|
||||||
TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if IS_TFTGLCD_PANEL
|
|
||||||
next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2);
|
|
||||||
buttons = slow_buttons;
|
|
||||||
TERN_(AUTO_BED_LEVELING_UBL, external_encoder());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // next_button_update_ms
|
|
||||||
|
|
||||||
#if HAS_ENCODER_WHEEL
|
|
||||||
static uint8_t lastEncoderBits;
|
|
||||||
|
|
||||||
// Manage encoder rotation
|
|
||||||
#define ENCODER_SPIN(_E1, _E2) switch (lastEncoderBits) { case _E1: encoderDiff += encoderDirection; break; case _E2: encoderDiff -= encoderDirection; }
|
|
||||||
|
|
||||||
uint8_t enc = 0;
|
|
||||||
if (buttons & EN_A) enc |= B01;
|
|
||||||
if (buttons & EN_B) enc |= B10;
|
|
||||||
if (enc != lastEncoderBits) {
|
|
||||||
switch (enc) {
|
|
||||||
case 0: ENCODER_SPIN(1, 2); break;
|
|
||||||
case 2: ENCODER_SPIN(0, 3); break;
|
|
||||||
case 3: ENCODER_SPIN(2, 1); break;
|
|
||||||
case 1: ENCODER_SPIN(3, 0); break;
|
|
||||||
}
|
|
||||||
#if ALL(HAS_MARLINUI_MENU, AUTO_BED_LEVELING_UBL)
|
#if ALL(HAS_MARLINUI_MENU, AUTO_BED_LEVELING_UBL)
|
||||||
external_encoder();
|
external_encoder();
|
||||||
#endif
|
#endif
|
||||||
lastEncoderBits = enc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // HAS_ENCODER_WHEEL
|
#endif
|
||||||
}
|
|
||||||
|
if (PENDING(now, next_button_update_ms)) return;
|
||||||
|
|
||||||
|
#if HAS_DIGITAL_BUTTONS
|
||||||
|
|
||||||
|
uint8_t newbuttons = 0;
|
||||||
|
#if ANY_BUTTON(ENC, BACK)
|
||||||
|
if (can_encode() && BUTTON_PRESSED(ENC)) newbuttons |= EN_C;
|
||||||
|
if (BUTTON_PRESSED(BACK)) newbuttons |= EN_D;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//
|
||||||
|
// Directional buttons
|
||||||
|
//
|
||||||
|
#if ANY_BUTTON(UP, DOWN, LEFT, RIGHT)
|
||||||
|
|
||||||
|
const int8_t pulses = epps * encoderDirection;
|
||||||
|
|
||||||
|
if (BUTTON_PRESSED(UP)) {
|
||||||
|
encoderDiff = (ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
||||||
|
next_button_update_ms = now + 300;
|
||||||
|
}
|
||||||
|
else if (BUTTON_PRESSED(DOWN)) {
|
||||||
|
encoderDiff = -(ENCODER_STEPS_PER_MENU_ITEM) * pulses;
|
||||||
|
next_button_update_ms = now + 300;
|
||||||
|
}
|
||||||
|
else if (BUTTON_PRESSED(LEFT)) {
|
||||||
|
encoderDiff = -pulses;
|
||||||
|
next_button_update_ms = now + 300;
|
||||||
|
}
|
||||||
|
else if (BUTTON_PRESSED(RIGHT)) {
|
||||||
|
encoderDiff = pulses;
|
||||||
|
next_button_update_ms = now + 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // UP || DOWN || LEFT || RIGHT
|
||||||
|
|
||||||
|
buttons = (newbuttons | TERN0(HAS_SLOW_BUTTONS, slow_buttons)
|
||||||
|
#if ALL(HAS_TOUCH_BUTTONS, HAS_ENCODER_ACTION)
|
||||||
|
| (touch_buttons & TERN(HAS_MARLINUI_ENCODER, ~(EN_A | EN_B), 0xFF))
|
||||||
|
#endif
|
||||||
|
);
|
||||||
|
|
||||||
|
#elif HAS_ADC_BUTTONS
|
||||||
|
|
||||||
|
buttons = 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_ADC_BUTTONS
|
||||||
|
if (keypad_buttons == 0) {
|
||||||
|
const uint8_t b = get_ADC_keyValue();
|
||||||
|
if (WITHIN(b, 1, 8)) keypad_buttons = _BV(b - 1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HAS_SHIFT_ENCODER
|
||||||
|
/**
|
||||||
|
* Set up Rotary Encoder bit values (for two pin encoders to indicate movement).
|
||||||
|
* These values are independent of which pins are used for EN_A / EN_B indications.
|
||||||
|
* The rotary encoder part is also independent of the LCD chipset.
|
||||||
|
*/
|
||||||
|
uint8_t val = 0;
|
||||||
|
WRITE(SHIFT_LD_PIN, LOW);
|
||||||
|
WRITE(SHIFT_LD_PIN, HIGH);
|
||||||
|
for (uint8_t i = 0; i < 8; ++i) {
|
||||||
|
val >>= 1;
|
||||||
|
if (READ(SHIFT_OUT_PIN)) SBI(val, 7);
|
||||||
|
WRITE(SHIFT_CLK_PIN, HIGH);
|
||||||
|
WRITE(SHIFT_CLK_PIN, LOW);
|
||||||
|
}
|
||||||
|
TERN(REPRAPWORLD_KEYPAD, keypad_buttons, buttons) = ~val;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if IS_TFTGLCD_PANEL
|
||||||
|
next_button_update_ms = now + (LCD_UPDATE_INTERVAL / 2);
|
||||||
|
buttons = slow_buttons;
|
||||||
|
TERN_(AUTO_BED_LEVELING_UBL, external_encoder());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
} // update_buttons
|
||||||
|
|
||||||
#endif // HAS_ENCODER_ACTION
|
#endif // HAS_ENCODER_ACTION
|
||||||
|
|
||||||
#endif // HAS_WIRED_LCD
|
#endif // HAS_WIRED_LCD
|
||||||
|
|
||||||
|
#if MARLINUI_ENCODER_DELTA
|
||||||
|
|
||||||
|
#define ENCODER_DEBOUNCE_MS 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the encoder delta (-2 -1 0 +1 +2) since the last call, reading the live encoder state.
|
||||||
|
* Pins may be debounced to filter noise.
|
||||||
|
*/
|
||||||
|
int8_t MarlinUI::get_encoder_delta(const millis_t &now/*=millis()*/) {
|
||||||
|
|
||||||
|
typedef struct { bool a:1, b:1; } enc_t;
|
||||||
|
|
||||||
|
const enc_t live_enc = { BUTTON_PRESSED(EN1), BUTTON_PRESSED(EN2) };
|
||||||
|
|
||||||
|
#if ENCODER_DEBOUNCE_MS
|
||||||
|
|
||||||
|
static enc_t enc;
|
||||||
|
static enc_t old_live;
|
||||||
|
|
||||||
|
static millis_t en_A_bounce_ms;
|
||||||
|
if (old_live.a != live_enc.a) en_A_bounce_ms = now + (ENCODER_DEBOUNCE_MS);
|
||||||
|
else if (ELAPSED(now, en_A_bounce_ms)) enc.a = live_enc.a;
|
||||||
|
|
||||||
|
static millis_t en_B_bounce_ms;
|
||||||
|
if (old_live.b != live_enc.b) en_B_bounce_ms = now + (ENCODER_DEBOUNCE_MS);
|
||||||
|
else if (ELAPSED(now, en_B_bounce_ms)) enc.b = live_enc.b;
|
||||||
|
|
||||||
|
old_live = live_enc;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
const enc_t &enc = live_enc;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static uint8_t old_pos;
|
||||||
|
const uint8_t pos = (enc.a ^ enc.b) | (enc.a << 1); // 0:00 1:10 2:11 3:01
|
||||||
|
int8_t delta = 0;
|
||||||
|
if (pos != old_pos) {
|
||||||
|
delta = (pos - old_pos + 4 + 1) % 4 - 1;
|
||||||
|
old_pos = pos;
|
||||||
|
|
||||||
|
static int8_t last_dir;
|
||||||
|
if (delta == 2) delta = last_dir * 2;
|
||||||
|
else last_dir = delta;
|
||||||
|
}
|
||||||
|
return delta;
|
||||||
|
|
||||||
|
} // get_encoder_delta
|
||||||
|
|
||||||
|
#endif // MARLINUI_ENCODER_DELTA
|
||||||
|
|
||||||
void MarlinUI::completion_feedback(const bool good/*=true*/) {
|
void MarlinUI::completion_feedback(const bool good/*=true*/) {
|
||||||
wake_display(); // Wake the screen for all audio feedback
|
wake_display(); // Wake the screen for all audio feedback
|
||||||
#if HAS_SOUND
|
#if HAS_SOUND
|
||||||
|
@@ -254,6 +254,11 @@ public:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if (HAS_WIRED_LCD && HAS_ENCODER_ACTION && HAS_MARLINUI_ENCODER) || HAS_DWIN_E3V2 || HAS_TFT_LVGL_UI
|
||||||
|
#define MARLINUI_ENCODER_DELTA 1
|
||||||
|
static int8_t get_encoder_delta(const millis_t &now=millis());
|
||||||
|
#endif
|
||||||
|
|
||||||
#if HAS_MEDIA
|
#if HAS_MEDIA
|
||||||
#define MEDIA_MENU_GATEWAY TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media)
|
#define MEDIA_MENU_GATEWAY TERN(PASSWORD_ON_SD_PRINT_MENU, password.media_gatekeeper, menu_media)
|
||||||
static void media_changed(const uint8_t old_stat, const uint8_t stat);
|
static void media_changed(const uint8_t old_stat, const uint8_t stat);
|
||||||
|
@@ -246,7 +246,7 @@ void menu_main() {
|
|||||||
START_MENU();
|
START_MENU();
|
||||||
BACK_ITEM(MSG_INFO_SCREEN);
|
BACK_ITEM(MSG_INFO_SCREEN);
|
||||||
|
|
||||||
#if HAS_MEDIA && !defined(MEDIA_MENU_AT_TOP) && !HAS_ENCODER_WHEEL
|
#if HAS_MEDIA && !defined(MEDIA_MENU_AT_TOP) && !HAS_MARLINUI_ENCODER
|
||||||
#define MEDIA_MENU_AT_TOP
|
#define MEDIA_MENU_AT_TOP
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user