From 0aecb28ca0e03de02c87f674811aadd53b14f4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Orhan=20Yi=C4=9Fit=20Durmaz?= Date: Mon, 17 Feb 2025 06:43:33 -0800 Subject: [PATCH 01/19] remove tusb_config from USB folder and move it to appropriate target folders --- .../F407VG/Core/Inc}/tusb_config.h | 0 .../F407VG_DISCO/Core/Inc/tusb_config.h | 120 ++++++++++++++++++ .../Targets/F411RE/Core/Inc/tusb_config.h | 120 ++++++++++++++++++ 3 files changed, 240 insertions(+) rename Firmware/{FFBoard/USB => Targets/F407VG/Core/Inc}/tusb_config.h (100%) create mode 100644 Firmware/Targets/F407VG_DISCO/Core/Inc/tusb_config.h create mode 100644 Firmware/Targets/F411RE/Core/Inc/tusb_config.h diff --git a/Firmware/FFBoard/USB/tusb_config.h b/Firmware/Targets/F407VG/Core/Inc/tusb_config.h similarity index 100% rename from Firmware/FFBoard/USB/tusb_config.h rename to Firmware/Targets/F407VG/Core/Inc/tusb_config.h diff --git a/Firmware/Targets/F407VG_DISCO/Core/Inc/tusb_config.h b/Firmware/Targets/F407VG_DISCO/Core/Inc/tusb_config.h new file mode 100644 index 000000000..e7c792181 --- /dev/null +++ b/Firmware/Targets/F407VG_DISCO/Core/Inc/tusb_config.h @@ -0,0 +1,120 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by board.mk + +#define CFG_TUSB_MCU OPT_MCU_STM32F4 // target config +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +// RHPort max operational speed can defined by board.mk +// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +#ifndef BOARD_DEVICE_RHPORT_SPEED + #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #else + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #endif +#endif + +// Device mode with rhport and speed defined by board.mk +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) + + +#define CFG_TUSB_OS OPT_OS_FREERTOS + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//#define USE_SOF 1 no sof for now + +//------------- CLASS -------------// + // Which classes are compiled and available +#define CFG_TUD_CDC 1 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 1 +#define CFG_TUD_HID 1 +#define CFG_TUD_VENDOR 0 +#define CFG_TUD_AUDIO 0 +#define CFG_TUD_DFU_RT 0 + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE 512//(TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_BUFSIZE 1024//(TUD_OPT_HIGH_SPEED ? 512 : 64) + +// MIDI FIFO size of TX and RX +#define CFG_TUD_MIDI_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_MIDI_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +// MSC Buffer size of Device Mass storage +#define CFG_TUD_MSC_EP_BUFSIZE 512 + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ diff --git a/Firmware/Targets/F411RE/Core/Inc/tusb_config.h b/Firmware/Targets/F411RE/Core/Inc/tusb_config.h new file mode 100644 index 000000000..e7c792181 --- /dev/null +++ b/Firmware/Targets/F411RE/Core/Inc/tusb_config.h @@ -0,0 +1,120 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#ifndef _TUSB_CONFIG_H_ +#define _TUSB_CONFIG_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +//-------------------------------------------------------------------- +// COMMON CONFIGURATION +//-------------------------------------------------------------------- + +// defined by board.mk + +#define CFG_TUSB_MCU OPT_MCU_STM32F4 // target config +#ifndef CFG_TUSB_MCU + #error CFG_TUSB_MCU must be defined +#endif + +// RHPort number used for device can be defined by board.mk, default to port 0 +#ifndef BOARD_DEVICE_RHPORT_NUM + #define BOARD_DEVICE_RHPORT_NUM 0 +#endif + +// RHPort max operational speed can defined by board.mk +// Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed +#ifndef BOARD_DEVICE_RHPORT_SPEED + #if (CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX || \ + CFG_TUSB_MCU == OPT_MCU_NUC505 || CFG_TUSB_MCU == OPT_MCU_CXD56) + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_HIGH_SPEED + #else + #define BOARD_DEVICE_RHPORT_SPEED OPT_MODE_FULL_SPEED + #endif +#endif + +// Device mode with rhport and speed defined by board.mk +#define CFG_TUSB_RHPORT0_MODE (OPT_MODE_DEVICE | BOARD_DEVICE_RHPORT_SPEED) + + +#define CFG_TUSB_OS OPT_OS_FREERTOS + +// CFG_TUSB_DEBUG is defined by compiler in DEBUG build +// #define CFG_TUSB_DEBUG 0 + +/* USB DMA on some MCUs can only access a specific SRAM region with restriction on alignment. + * Tinyusb use follows macros to declare transferring memory so that they can be put + * into those specific section. + * e.g + * - CFG_TUSB_MEM SECTION : __attribute__ (( section(".usb_ram") )) + * - CFG_TUSB_MEM_ALIGN : __attribute__ ((aligned(4))) + */ +#ifndef CFG_TUSB_MEM_SECTION +#define CFG_TUSB_MEM_SECTION +#endif + +#ifndef CFG_TUSB_MEM_ALIGN +#define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) +#endif + +//-------------------------------------------------------------------- +// DEVICE CONFIGURATION +//-------------------------------------------------------------------- + +#ifndef CFG_TUD_ENDPOINT0_SIZE +#define CFG_TUD_ENDPOINT0_SIZE 64 +#endif + +//#define USE_SOF 1 no sof for now + +//------------- CLASS -------------// + // Which classes are compiled and available +#define CFG_TUD_CDC 1 +#define CFG_TUD_MSC 0 +#define CFG_TUD_MIDI 1 +#define CFG_TUD_HID 1 +#define CFG_TUD_VENDOR 0 +#define CFG_TUD_AUDIO 0 +#define CFG_TUD_DFU_RT 0 + +// CDC FIFO size of TX and RX +#define CFG_TUD_CDC_RX_BUFSIZE 512//(TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_CDC_TX_BUFSIZE 1024//(TUD_OPT_HIGH_SPEED ? 512 : 64) + +// MIDI FIFO size of TX and RX +#define CFG_TUD_MIDI_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) +#define CFG_TUD_MIDI_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) + +// MSC Buffer size of Device Mass storage +#define CFG_TUD_MSC_EP_BUFSIZE 512 + + +#ifdef __cplusplus + } +#endif + +#endif /* _TUSB_CONFIG_H_ */ From bbf251240ba5fdc6592350c91b3edd13674e1a2c Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Wed, 26 Feb 2025 19:07:19 +0100 Subject: [PATCH 02/19] Axis tmc4671 set ext enc allowed before restore --- Firmware/FFBoard/Inc/Axis.h | 18 ------------------ Firmware/FFBoard/Src/Axis.cpp | 2 +- 2 files changed, 1 insertion(+), 19 deletions(-) diff --git a/Firmware/FFBoard/Inc/Axis.h b/Firmware/FFBoard/Inc/Axis.h index 18d6c1775..8c335e77b 100644 --- a/Firmware/FFBoard/Inc/Axis.h +++ b/Firmware/FFBoard/Inc/Axis.h @@ -203,24 +203,6 @@ class Axis : public PersistentStorage, public CommandHandler, public ErrorHandle .pid_vel_lim = 2147483647, .pid_pos_low = -2147483647, .pid_pos_high = 2147483647}); - - // Lowpass 500Hz Q 0.7 @ 25khz - const TMC4671Biquad_t tmcbq_500hz_07q_25k = TMC4671Biquad_t( - { .a1 = 979476766, - .a2 = -450370144, - .b0 = 1941073, - .b1 = 3882145, - .b2 = 1941073}); - - // Lowpass 1000Hz Q 0.7 @ 25khz - const TMC4671Biquad_t tmcbq_1000hz_07q_25k = TMC4671Biquad_t( - { .a1 = 886773302, - .a2 = -378358476, - .b0 = 7114021, - .b1 = 14228043, - .b2 = 7114021}); - - #endif float encoderOffset = 0; // Offset for absolute encoders uint16_t degreesOfRotation = 900; // How many degrees of range for the full gamepad range diff --git a/Firmware/FFBoard/Src/Axis.cpp b/Firmware/FFBoard/Src/Axis.cpp index 3469ce4e2..f75e28a3b 100644 --- a/Firmware/FFBoard/Src/Axis.cpp +++ b/Firmware/FFBoard/Src/Axis.cpp @@ -419,11 +419,11 @@ void Axis::setupTMC4671() { TMC4671 *drv = static_cast(this->drv.get()); // drv->setAxis(axis); + drv->setExternalEncoderAllowed(true); drv->restoreFlash(); tmclimits.pid_torque_flux = getPower(); drv->setLimits(tmclimits); //drv->setBiquadTorque(TMC4671Biquad(tmcbq_500hz_07q_25k)); - drv->setExternalEncoderAllowed(true); // Enable driver From aa957c9d06e3b948bb85dc5c42933846eb689afd Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Thu, 27 Feb 2025 15:45:31 +0100 Subject: [PATCH 03/19] TMC4671 default to interrupt SPI for async write instead of DMA --- Firmware/FFBoard/UserExtensions/Inc/TMC4671.h | 2 +- Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp | 9 ++++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h b/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h index 88cdeec48..00824b177 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h +++ b/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h @@ -368,7 +368,7 @@ friend class TMCDebugBridge; uint32_t readReg(uint8_t reg); void writeReg(uint8_t reg,uint32_t dat); - void writeRegDMA(uint8_t reg,uint32_t dat); + void writeRegAsync(uint8_t reg,uint32_t dat); void updateReg(uint8_t reg,uint32_t dat,uint32_t mask,uint8_t shift); //void SpiTxCplt(SPI_HandleTypeDef *hspi); diff --git a/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp b/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp index e3a991e73..982046528 100644 --- a/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp +++ b/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp @@ -2507,11 +2507,10 @@ void TMC4671::writeReg(uint8_t reg,uint32_t dat){ memcpy(spi_buf+1,&dat,4); // ----- - //spiPort.transmit_DMA(this->spi_buf, 5, this); // not using DMA enforces the required delays spiPort.transmit(spi_buf, 5, this, SPITIMEOUT); } -void TMC4671::writeRegDMA(uint8_t reg,uint32_t dat){ +void TMC4671::writeRegAsync(uint8_t reg,uint32_t dat){ // wait until ready spiPort.takeSemaphore(); @@ -2520,7 +2519,11 @@ void TMC4671::writeRegDMA(uint8_t reg,uint32_t dat){ memcpy(spi_buf+1,&dat,4); // ----- +#ifdef TMC4671_ALLOW_DMA spiPort.transmit_DMA(this->spi_buf, 5, this); +#else + spiPort.transmit_IT(this->spi_buf, 5, this); +#endif } void TMC4671::updateReg(uint8_t reg,uint32_t dat,uint32_t mask,uint8_t shift){ @@ -3235,7 +3238,7 @@ void TMC4671::TMC_ExternalEncoderUpdateThread::Run(){ while(true){ this->WaitForNotification(); if(tmc->usingExternalEncoder() && !tmc->spiPort.isTaken()){ - tmc->writeRegDMA(0x1C, (tmc->getPhiEfromExternalEncoder())); // Write phiE_ext + tmc->writeRegAsync(0x1C, (tmc->getPhiEfromExternalEncoder())); // Write phiE_ext } } } From d19d616137f60553b77a9ee78bfddd6fbabba910 Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Mon, 17 Feb 2025 18:13:18 +0100 Subject: [PATCH 04/19] Remove forza fix, changed linear direction and inverted Y axis --- Firmware/FFBoard/Inc/ffb_defs.h | 4 +- Firmware/FFBoard/Src/HidFFB.cpp | 74 +++++++++---------- .../UserExtensions/Inc/usb_hid_ffb_desc.h | 2 +- .../UserExtensions/Src/usb_hid_2ffb_desc.c | 8 +- 4 files changed, 40 insertions(+), 48 deletions(-) diff --git a/Firmware/FFBoard/Inc/ffb_defs.h b/Firmware/FFBoard/Inc/ffb_defs.h index 8fa0e3b23..e78b1e6fd 100644 --- a/Firmware/FFBoard/Inc/ffb_defs.h +++ b/Firmware/FFBoard/Inc/ffb_defs.h @@ -169,7 +169,7 @@ typedef struct uint8_t triggerButton = 0; // button ID. unused uint8_t enableAxis = 0; // bits: 0=X, 1=Y, 2=DirectionEnable uint16_t directionX = 0; // angle (0=0 .. 36000=360deg) -// uint16_t directionY = 0; // angle (0=0 .. 36000=360deg) TODO axes are last bytes in struct if fewer axes are used. use different report if this is not enough anymore! + uint16_t directionY = 0; // angle (0=0 .. 36000=360deg) TODO axes are last bytes in struct if fewer axes are used. use different report if this is not enough anymore! //#if MAX_AXIS == 3 // uint8_t directionZ = 0; // angle (0=0 .. 255=360deg) //#endif @@ -255,7 +255,7 @@ typedef struct uint16_t deadBand = 0; bool isActive(){ // Condition is active if either coefficient is not zero - return positiveCoefficient != 0 || negativeCoefficient != 0; + return (positiveCoefficient != 0 && positiveSaturation != 0) || (negativeCoefficient != 0 && negativeSaturation != 0); } } FFB_Effect_Condition; diff --git a/Firmware/FFBoard/Src/HidFFB.cpp b/Firmware/FFBoard/Src/HidFFB.cpp index a211fcb3f..21835fef3 100644 --- a/Firmware/FFBoard/Src/HidFFB.cpp +++ b/Firmware/FFBoard/Src/HidFFB.cpp @@ -290,48 +290,36 @@ void HidFFB::set_effect(FFB_SetEffect_t* effect){ effect_p->type = effect->effectType; effect_p->samplePeriod = effect->samplePeriod; - if(axisCount == 1){ - /* Compatibility fix. Some games may send a 0° or 90° angle for the first axis. - * If we only have 1 axis defined we ignore any directions and force enable the first axis - */ - effect->enableAxis = X_AXIS_ENABLE; - } - bool directionEnable = (effect->enableAxis & this->directionEnableMask); + bool overridesCondition = false; - if(effect_p->useSingleCondition){ // Only allow turning single condition off in case it was overridden by sending multiple conditions previously - effect_p->useSingleCondition = directionEnable; // If direction is used only a single parameter block is allowed. Somehow this is still set while 2 conditions are sent... - }else if(directionEnable){ - directionEnable = false; // If multiple conditions were previously sent we ignore direction enable and instead activate axes +// if(effect_p->useSingleCondition){ // Only allow turning single condition off in case it was overridden by sending multiple conditions previously +// effect_p->useSingleCondition = directionEnable; // If direction is used only a single parameter block is allowed. Somehow this is still set while 2 conditions are sent... +// } + // Conditional effects usually do not use directions + if(!effect_p->useSingleCondition && (effect->effectType == FFB_EFFECT_SPRING || effect->effectType == FFB_EFFECT_DAMPER || effect->effectType == FFB_EFFECT_INERTIA || effect->effectType == FFB_EFFECT_FRICTION)) + { if(effect_p->conditions[0].isActive()){ - effect->enableAxis |= X_AXIS_ENABLE; + effect_p->axisMagnitudes[0] = 1.0f; + overridesCondition = true; } - if(effect_p->conditions[1].isActive()){ - effect->enableAxis |= Y_AXIS_ENABLE; + if(effect_p->conditions[1].isActive() || effect_p->useSingleCondition){ + effect_p->axisMagnitudes[1] = 1.0f; + overridesCondition = true; } } - float phaseX = M_PI*2.0 * (effect->directionX/36000.0); - if(axisCount == 1){ - /* - * Angular vector if dirEnable used or axis enabled otherwise 0 if axis disabled - * Compatibility fix. - * Some single axis games send no directionEnable but enableAxis but still use phase vectors to scale a single axis effect - */ - effect_p->axisMagnitudes[0] = (directionEnable || (effect->enableAxis & X_AXIS_ENABLE) ? sin(phaseX) : 0); - }else{ - /* - * Some 2 axis games send no vector and require the axis to be enable via enableAxis - */ - effect_p->axisMagnitudes[0] = directionEnable ? sin(phaseX) : (effect->enableAxis & X_AXIS_ENABLE ? 1 : 0); // Angular vector if dirEnable used otherwise full or 0 if axis enabled - effect_p->axisMagnitudes[1] = directionEnable ? cos(phaseX) : (effect->enableAxis & Y_AXIS_ENABLE ? 1 : 0); // Angular vector if + if(!overridesCondition){ + float phaseX = M_PI*2.0 * (effect->directionX/36000.0f); + + effect_p->axisMagnitudes[0] = directionEnable ? sin(phaseX) : (effect->enableAxis & X_AXIS_ENABLE ? (effect->directionX - 18000.0f) / 18000.0f : 0); // Angular vector if dirEnable used otherwise linear or 0 if axis enabled + effect_p->axisMagnitudes[1] = directionEnable ? -cos(phaseX) : (effect->enableAxis & Y_AXIS_ENABLE ? -(effect->directionY - 18000.0f) / 18000.0f : 0); } #if MAX_AXIS == 3 float phaseY = M_PI*2.0 * (effect->directionY/36000.0); - effect_p->axisMagnitudes[3] = (directionEnable || (effect->enableAxis & Z_AXIS_ENABLE) ? sin(phaseY) : 0); // Angular vector if dirEnable used otherwise full or 0 if axis enabled - + effect_p->axisMagnitudes[3] = directionEnable ? sin(phaseY) : (effect->enableAxis & Z_AXIS_ENABLE ? (effect->directionZ - 18000.0f) / 18000.0f : 0); #endif if(effect->duration == 0){ // Fix for games assuming 0 is infinite effect_p->duration = FFB_EFFECT_DURATION_INFINITE; @@ -372,20 +360,24 @@ void HidFFB::set_condition(FFB_SetCondition_Data_t *cond){ effect->conditions[axis].negativeSaturation = cond->negativeSaturation; effect->conditions[axis].positiveSaturation = cond->positiveSaturation; effect->conditions[axis].deadBand = cond->deadBand; - //effect->conditionsCount++; - if(effect->conditions[axis].positiveSaturation == 0){ - effect->conditions[axis].positiveSaturation = 0x7FFF; - } - if(effect->conditions[axis].negativeSaturation == 0){ - effect->conditions[axis].negativeSaturation = 0x7FFF; - } - if(axis>0){ // Workaround when direction enable is set but multiple conditions are defined... Resets direction and uses conditions again +// if(effect->conditions[axis].positiveSaturation == 0){ +// effect->conditions[axis].positiveSaturation = 0x7FFF; +// } +// if(effect->conditions[axis].negativeSaturation == 0){ +// effect->conditions[axis].negativeSaturation = 0x7FFF; +// } + + if(axis>0 && axis < MAX_AXIS && effect->conditions[axis].isActive()){ // Workaround when direction enable is set but multiple conditions are defined... Resets direction and uses conditions again effect->useSingleCondition = false; - for(uint8_t i = 0;iaxisMagnitudes[i] = 1.0; - } } + if((effect->conditions[axis].isActive() || (axis > 0 && effect->useSingleCondition)) && effect->axisMagnitudes[axis] == 0){ + effect->axisMagnitudes[axis] = 1.0; + } + +// for(uint8_t i = 0;iaxisMagnitudes[i] = 1.0; +// } } void HidFFB::set_effect_operation(FFB_EffOp_Data_t* report){ diff --git a/Firmware/FFBoard/UserExtensions/Inc/usb_hid_ffb_desc.h b/Firmware/FFBoard/UserExtensions/Inc/usb_hid_ffb_desc.h index 50cd821ad..d6067effe 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/usb_hid_ffb_desc.h +++ b/Firmware/FFBoard/UserExtensions/Inc/usb_hid_ffb_desc.h @@ -15,7 +15,7 @@ extern const uint8_t hid_1ffb_desc[USB_HID_1FFB_REPORT_DESC_SIZE]; #endif -#define USB_HID_2FFB_REPORT_DESC_SIZE 1208//1213 +#define USB_HID_2FFB_REPORT_DESC_SIZE 1215//1213 #ifdef AXIS2_FFB_HID_DESC extern const uint8_t hid_2ffb_desc[USB_HID_2FFB_REPORT_DESC_SIZE]; #endif diff --git a/Firmware/FFBoard/UserExtensions/Src/usb_hid_2ffb_desc.c b/Firmware/FFBoard/UserExtensions/Src/usb_hid_2ffb_desc.c index daeea9007..79e98bcb0 100644 --- a/Firmware/FFBoard/UserExtensions/Src/usb_hid_2ffb_desc.c +++ b/Firmware/FFBoard/UserExtensions/Src/usb_hid_2ffb_desc.c @@ -314,9 +314,9 @@ __ALIGN_BEGIN const uint8_t hid_2ffb_desc[USB_HID_2FFB_REPORT_DESC_SIZE] __ALIGN 0x09,0x57, // Usage Direction 0xA1,0x02, // Collection Datalink 0x0B,0x01,0x00,0x0A,0x00, // Usage Ordinals: Instance 1 -// 0x0B,0x02,0x00,0x0A,0x00, // Usage Ordinals: Instance 2 + 0x0B,0x02,0x00,0x0A,0x00, // Usage Ordinals: Instance 2 0x66,0x14,0x00, // Unit 14h (20d) Angular position -// 0x55,0xFE, // Unit Exponent FEh (254d) + 0x55,0xFE, // Unit Exponent FEh (254d) // 0x15,0x00, // Logical Minimum 0 // 0x26,0xFF,0x00, // Logical Maximum FFh (255d) 0x15,0x00, // Logical Minimum 0 @@ -325,8 +325,8 @@ __ALIGN_BEGIN const uint8_t hid_2ffb_desc[USB_HID_2FFB_REPORT_DESC_SIZE] __ALIGN 0x47,0xA0,0x8C,0x00,0x00, // Physical Maximum 8CA0h (36000d) 0x66,0x00,0x00, // Unit 0 0x75,0x10, // Report Size 16 - 0x95,0x01, // Report Count 1 -// 0x95,0x02, // Report Count 2 +// 0x95,0x01, // Report Count 1 + 0x95,0x02, // Report Count 2 0x91,0x02, // Output (Variable) 0x55,0x00, // Unit Exponent 0 0x66,0x00,0x00, // Unit 0 From c7c4c5febb9c368809b06c7a2e64b97f4c55dd3e Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 2 Mar 2025 22:44:17 +0100 Subject: [PATCH 05/19] Changelog update --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f987e68c1..956d0b276 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,12 @@ -### Changes this version from 1.16 to 1.15: +### Changes this version: +- Inverted Y axis direction vector magnitude + - Fixes 2 axis setups in XPforce and DCS and other flight sims +- Changed 2 axis conditional effects to ignore direction vectors (Fixes DCS) +- Modified HID 2 axis descriptor, added back second direction for compliance + + + +### Changes in 1.16: - Added MyActuator RMD CAN support class. - Temporary implementation until CAN protocol changes. Usable but might be improved in the future - Fixed issues in CAN analog class for packet 2. Allow shorter frames From 3e01e2f61555f7d27f0194015fed3eaf4dec5d3d Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 2 Mar 2025 22:45:21 +0100 Subject: [PATCH 06/19] Version bump 1.16.1 --- Firmware/FFBoard/Inc/constants.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/FFBoard/Inc/constants.h b/Firmware/FFBoard/Inc/constants.h index f9215be80..c9627ca07 100644 --- a/Firmware/FFBoard/Inc/constants.h +++ b/Firmware/FFBoard/Inc/constants.h @@ -8,7 +8,7 @@ * For more settings see target_constants.h in a target specific folder */ -static const uint8_t SW_VERSION_INT[3] = {1,16,0}; // Version as array. 8 bit each! +static const uint8_t SW_VERSION_INT[3] = {1,16,1}; // Version as array. 8 bit each! #ifndef MAX_AXIS #define MAX_AXIS 2 // ONLY USE 2 for now else screws HID Reports #endif From d367fc05ca857a65780a439ae6e57fc1e0f6646d Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sat, 8 Mar 2025 14:46:43 +0100 Subject: [PATCH 07/19] TMC4671 increase encoder ADC rate for stability --- Firmware/FFBoard/UserExtensions/Inc/TMC4671.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h b/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h index 00824b177..dd19e51fb 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h +++ b/Firmware/FFBoard/UserExtensions/Inc/TMC4671.h @@ -150,7 +150,7 @@ struct TMC4671MainConfig{ uint8_t bbmL = 50; uint8_t bbmH = 50; uint16_t mdecA = 660; // 334 default. 331 recommended by datasheet,662 double. 660 lowest noise - uint16_t mdecB = 660; // Encoder ADC high resolution recommended + uint16_t mdecB = 331; // Encoder ADC fast rate recommended uint32_t mclkA = 0x20000000; //0x20000000 default uint32_t mclkB = 0x20000000; // For AENC uint16_t adc_I0_offset = 33415; From 32caeee2c8ec480de42e730c03a8c81a3107d391 Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Mon, 17 Mar 2025 12:33:31 +0100 Subject: [PATCH 08/19] Add separate openloop speed torque and pwm modes to tmc debug bridge --- .../FFBoard/UserExtensions/Inc/TMCDebugBridge.h | 2 +- .../FFBoard/UserExtensions/Src/TMCDebugBridge.cpp | 15 +++++++++++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/Firmware/FFBoard/UserExtensions/Inc/TMCDebugBridge.h b/Firmware/FFBoard/UserExtensions/Inc/TMCDebugBridge.h index 406004b24..817671053 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/TMCDebugBridge.h +++ b/Firmware/FFBoard/UserExtensions/Inc/TMCDebugBridge.h @@ -23,7 +23,7 @@ extern SPI_HandleTypeDef HSPIDRV; class TMCDebugBridge: public FFBoardMain { enum class TMCDebugBridge_commands : uint32_t{ - torque,pos,openloopspeed,velocity,mode,reg + torque,pos,openloopspeed,velocity,mode,reg,openloopspeedpwm }; public: diff --git a/Firmware/FFBoard/UserExtensions/Src/TMCDebugBridge.cpp b/Firmware/FFBoard/UserExtensions/Src/TMCDebugBridge.cpp index 98398ffb4..e59b5e3ad 100644 --- a/Firmware/FFBoard/UserExtensions/Src/TMCDebugBridge.cpp +++ b/Firmware/FFBoard/UserExtensions/Src/TMCDebugBridge.cpp @@ -36,9 +36,10 @@ void TMCDebugBridge::registerCommands(){ registerCommand("reg", TMCDebugBridge_commands::reg, "Read or write a TMC register at adr",CMDFLAG_GETADR | CMDFLAG_SETADR); registerCommand("torque", TMCDebugBridge_commands::torque, "Change torque and enter torque mode",CMDFLAG_GET | CMDFLAG_SET); registerCommand("pos", TMCDebugBridge_commands::pos, "Change pos and enter pos mode",CMDFLAG_GET | CMDFLAG_SET); - registerCommand("openloopspeed", TMCDebugBridge_commands::openloopspeed, "Move openloop. adr=strength;val=speed",CMDFLAG_SETADR | CMDFLAG_SET); + registerCommand("openloopspeed", TMCDebugBridge_commands::openloopspeed, "Move openloop (current controlled). adr=strength;val=speed",CMDFLAG_SETADR | CMDFLAG_SET); registerCommand("velocity", TMCDebugBridge_commands::velocity, "Change velocity and enter velocity mode",CMDFLAG_GET | CMDFLAG_SET); registerCommand("mode", TMCDebugBridge_commands::mode, "Change motion mode",CMDFLAG_GET | CMDFLAG_SET); + registerCommand("openloopspeedpwm", TMCDebugBridge_commands::openloopspeedpwm, "Move openloop raw PWM. adr=strength;val=speed",CMDFLAG_SETADR | CMDFLAG_SET); } @@ -72,7 +73,17 @@ CommandStatus TMCDebugBridge::command(const ParsedCommand& cmd,std::vectorsetOpenLoopSpeedAccel(cmd.val,100); }else if(cmd.type == CMDtype::setat){ - drv->runOpenLoop(cmd.adr,0,cmd.val,10); + drv->runOpenLoop(cmd.adr,0,cmd.val,10,true); + }else{ + return CommandStatus::ERR; + } + break; + + case TMCDebugBridge_commands::openloopspeedpwm: + if(cmd.type == CMDtype::set){ + drv->setOpenLoopSpeedAccel(cmd.val,100); + }else if(cmd.type == CMDtype::setat){ + drv->runOpenLoop(cmd.adr,0,cmd.val,10,false); }else{ return CommandStatus::ERR; } From 5556f6705b78654c7a4406481846ca2da58bb32b Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Tue, 18 Mar 2025 10:04:26 +0100 Subject: [PATCH 09/19] TMC4671 do not disable enable pin on motor stop (only on estop) --- Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp b/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp index 982046528..3b331632a 100644 --- a/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp +++ b/Firmware/FFBoard/UserExtensions/Src/TMC4671.cpp @@ -1626,6 +1626,7 @@ void TMC4671::runOpenLoop(uint16_t ud,uint16_t uq,int32_t speed,int32_t accel,bo if(this->conf.motconf.motor_type == MotorType::DC){ uq = ud+uq; // dc motor has no flux. add to torque } + startMotor(); if(torqueMode){ if(this->conf.motconf.motor_type == MotorType::DC){ uq = ud+uq; // dc motor has no flux. add to torque @@ -1649,7 +1650,7 @@ void TMC4671::setUdUq(int16_t ud,int16_t uq){ void TMC4671::stopMotor(){ // Stop driver if running - enablePin.reset(); +// enablePin.reset(); motorEnabledRequested = false; if(state == TMC_ControlState::Running || state == TMC_ControlState::EncoderFinished){ setMotionMode(MotionMode::stop,true); From e45943faa1253a3f351072935a68e0b44fe4ca61 Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Fri, 21 Mar 2025 21:06:27 +0100 Subject: [PATCH 10/19] CAN2B corrected packet length --- Firmware/FFBoard/Inc/CANPort2B.h | 2 +- Firmware/FFBoard/Src/CANPort2B.cpp | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Firmware/FFBoard/Inc/CANPort2B.h b/Firmware/FFBoard/Inc/CANPort2B.h index bd98cbcae..fbdfb155d 100644 --- a/Firmware/FFBoard/Inc/CANPort2B.h +++ b/Firmware/FFBoard/Inc/CANPort2B.h @@ -69,7 +69,7 @@ class CANPort_2B : public CANPort, public CommandHandler,public CanHandler{ static const uint32_t sendTimeout = 20; CAN_TxHeaderTypeDef header = {0,0,0,CAN_RTR_DATA,8,(FunctionalState)0}; - + uint8_t nextLen = 8; }; #endif diff --git a/Firmware/FFBoard/Src/CANPort2B.cpp b/Firmware/FFBoard/Src/CANPort2B.cpp index 2604d4c58..21d3cda14 100644 --- a/Firmware/FFBoard/Src/CANPort2B.cpp +++ b/Firmware/FFBoard/Src/CANPort2B.cpp @@ -356,6 +356,7 @@ CommandStatus CANPort_2B::command(const ParsedCommand& cmd,std::vector(header.DLC,8); + handleGetSet(cmd, replies, nextLen); + nextLen = std::min(nextLen,8); break; default: return CommandStatus::NOT_FOUND; From 75617e64322347105847f5fea9804d63387a3cfc Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sat, 22 Mar 2025 15:50:20 +0100 Subject: [PATCH 11/19] Corrected CAN speedToPreset function --- Firmware/FFBoard/Inc/CAN.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/FFBoard/Inc/CAN.h b/Firmware/FFBoard/Inc/CAN.h index f6059a92d..6a1a0d408 100644 --- a/Firmware/FFBoard/Inc/CAN.h +++ b/Firmware/FFBoard/Inc/CAN.h @@ -50,7 +50,7 @@ class CANPortHardwareConfig{ constexpr PresetEntry getPreset(uint8_t idx) const {return PresetEntry(presets[std::min(idx,presets.size())]);} constexpr uint32_t speedToPreset(uint32_t speed) const { auto it = std::find_if( presets.begin(), presets.end(), [&speed](const PresetEntry &e){return e.speed == speed;}); - return it == presets.end() ? 255 : std::distance(it, presets.begin()); + return it == presets.end() ? 255 : std::distance(presets.begin(),it); } constexpr uint32_t presetToSpeed(uint8_t preset) const {return presets[preset].speed;} const std::span presets; // Name for listing and init types for setup From a089c6050ff4cdc063da11be6ba9defcdbd3bf59 Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 23 Mar 2025 11:28:45 +0100 Subject: [PATCH 12/19] Fixed sign issue in moving average (Should fix temperature glitch) --- Firmware/FFBoard/Inc/FastAvg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/FFBoard/Inc/FastAvg.h b/Firmware/FFBoard/Inc/FastAvg.h index cbefa576b..491dd4b6e 100644 --- a/Firmware/FFBoard/Inc/FastAvg.h +++ b/Firmware/FFBoard/Inc/FastAvg.h @@ -62,7 +62,7 @@ class FastAvg { template class FastMovingAverage{ public: - FastMovingAverage(uint32_t len = 0) : fixedLen(len), count(0){}; + FastMovingAverage(int32_t len = 0) : fixedLen(len), count(0){}; ~FastMovingAverage(){}; void clear(){ @@ -96,8 +96,8 @@ class FastMovingAverage{ } private: T curAvg = 0; - const uint32_t fixedLen; - uint32_t count = 0; + const int32_t fixedLen; + int32_t count = 0; }; #endif From f115e12e80f39e72f3617fb716018c00a9c1cd94 Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 23 Mar 2025 11:54:57 +0100 Subject: [PATCH 13/19] Reduced chiptemp averaging to 3 --- Firmware/FFBoard/Src/voltagesense.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/FFBoard/Src/voltagesense.cpp b/Firmware/FFBoard/Src/voltagesense.cpp index d56811cce..b9c1f6929 100644 --- a/Firmware/FFBoard/Src/voltagesense.cpp +++ b/Firmware/FFBoard/Src/voltagesense.cpp @@ -92,7 +92,7 @@ void brakeCheck(){ } -FastMovingAveragechipTempAvg{5}; +FastMovingAveragechipTempAvg{3}; __weak int32_t getChipTemp(){ #if !defined(TEMPSENSOR_ADC_VAL) || !defined(__LL_ADC_CALC_TEMPERATURE) return 0; From 3c2d7faeef58136437d11f604eeb62f2ee745f1e Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 23 Mar 2025 22:25:40 +0100 Subject: [PATCH 14/19] FastMovingAverage treat length 0 as 0x7FFFFFFF --- Firmware/FFBoard/Inc/FastAvg.h | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/Firmware/FFBoard/Inc/FastAvg.h b/Firmware/FFBoard/Inc/FastAvg.h index 491dd4b6e..b12a29b2e 100644 --- a/Firmware/FFBoard/Inc/FastAvg.h +++ b/Firmware/FFBoard/Inc/FastAvg.h @@ -54,21 +54,20 @@ class FastAvg { }; /** - * Calculates a moving average of unknown length + * Calculates a moving average of variable length * Can periodically get and reset a value to average for an unknown amount of data points * If len != 0 calculates an exponential moving average with length len. - * If len = 0 length equals the current amount of samples. + * If len = 0 length equals the current amount of samples up to 0x7FFFFFFF. */ template class FastMovingAverage{ public: - FastMovingAverage(int32_t len = 0) : fixedLen(len), count(0){}; + FastMovingAverage(int32_t len = 0) : fixedLen(len > 0 ? len : INT32_MAX), count(0){}; ~FastMovingAverage(){}; void clear(){ curAvg = 0; - if(!fixedLen) - count=0; + count=0; } /** * Gets current average and clears current average and counter @@ -89,7 +88,7 @@ class FastMovingAverage{ * Adds a value and returns current average */ T addValue(T v){ - if(!fixedLen || count < fixedLen) + if(count < fixedLen) count++; curAvg += (v - curAvg)/count; return curAvg; From e321424c7091ac15800ec6e4638c7bcf6393279f Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 30 Mar 2025 13:45:27 +0200 Subject: [PATCH 15/19] Changelog update --- CHANGELOG.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 956d0b276..87a82a287 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ - Fixes 2 axis setups in XPforce and DCS and other flight sims - Changed 2 axis conditional effects to ignore direction vectors (Fixes DCS) - Modified HID 2 axis descriptor, added back second direction for compliance - +- Fixed chip temp sometimes glitching +- TMC debug mode: Changed openloopspeed command to use torque mode instead of raw PWM. Added new openloopspeedpwm to control raw PWM. +- CAN bus corrected packet length when packet is sent as command +- Corrected CAN speed preset in can bridge GVRET mode (savvycan works again) ### Changes in 1.16: From 7c866dd1ca13f850aa558dcaa87cdca3ccb8796a Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Sun, 30 Mar 2025 15:07:19 +0200 Subject: [PATCH 16/19] Configurator update --- Configurator | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Configurator b/Configurator index 3b1736c83..142d72111 160000 --- a/Configurator +++ b/Configurator @@ -1 +1 @@ -Subproject commit 3b1736c8334a0ff187026e4c80f8e2d4357d97f2 +Subproject commit 142d72111b732d40caf6f781d4ea87c42e0e9e1b From 266f78f054de2236cd8647f72adf24bb7afdf4ff Mon Sep 17 00:00:00 2001 From: Yannick Richter Date: Wed, 16 Apr 2025 11:14:20 +0200 Subject: [PATCH 17/19] Update submodules --- Configurator | 2 +- Hardware | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Configurator b/Configurator index 142d72111..f3fec28c6 160000 --- a/Configurator +++ b/Configurator @@ -1 +1 @@ -Subproject commit 142d72111b732d40caf6f781d4ea87c42e0e9e1b +Subproject commit f3fec28c639aa2150f646252dd7051639c6007c8 diff --git a/Hardware b/Hardware index 35455f46a..26f51cdf9 160000 --- a/Hardware +++ b/Hardware @@ -1 +1 @@ -Subproject commit 35455f46a8681cc453317c700f1cad9c9ef20fab +Subproject commit 26f51cdf97d69dac9670b93828234213b053079c From 6044f9d7d3fadd00842b0f2f6a0242d042d3df47 Mon Sep 17 00:00:00 2001 From: tinybox Date: Wed, 23 Apr 2025 22:12:00 +0800 Subject: [PATCH 18/19] debounce added --- .../FFBoard/UserExtensions/Inc/SPIButtons.h | 14 ++++- .../FFBoard/UserExtensions/Src/SPIButtons.cpp | 57 ++++++++++++++++++- 2 files changed, 69 insertions(+), 2 deletions(-) diff --git a/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h b/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h index 9f8f061df..0dbae7ffd 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h +++ b/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h @@ -29,13 +29,15 @@ struct ButtonSourceConfig{ SPI_BtnMode mode=SPI_BtnMode::TM; // Mode preset uint8_t cs_num = 0; uint8_t spi_speed = 1; // Medium + bool debounce_enabled = true; // 默认开启消抖 + uint16_t debounce_time = 20; // 默认20ms消抖时间 }; class SPI_Buttons: public ButtonSource,public CommandHandler,public SPIDevice { enum class SPIButtons_commands : uint32_t { - mode,btncut,btnpol,btnnum,cs,spispeed + mode,btncut,btnpol,btnnum,cs,spispeed,debounceen,debouncetime }; public: @@ -62,6 +64,11 @@ class SPI_Buttons: public ButtonSource,public CommandHandler,public SPIDevice { void setSpiSpeed(uint8_t speedPreset); + void setDebounceEnabled(bool enabled); + void setDebounceTime(uint16_t time_ms); + bool isDebounceEnabled() { return conf.debounce_enabled; } + uint16_t getDebounceTime() { return conf.debounce_time; } + protected: SPI_Buttons(uint16_t configuration_address, uint16_t configuration_address_2); @@ -77,6 +84,11 @@ class SPI_Buttons: public ButtonSource,public CommandHandler,public SPIDevice { uint8_t offset = 0; ButtonSourceConfig conf; + + // Button debouncing variables + uint64_t last_button_state = 0; // Last button state for debounce detection + uint64_t debounced_state = 0; // Current stable debounced button state + uint32_t last_debounce_time = 0; // Timestamp of last button state change uint8_t spi_buf[4] = {0}; diff --git a/Firmware/FFBoard/UserExtensions/Src/SPIButtons.cpp b/Firmware/FFBoard/UserExtensions/Src/SPIButtons.cpp index f4a0512a6..c4c41e4ef 100644 --- a/Firmware/FFBoard/UserExtensions/Src/SPIButtons.cpp +++ b/Firmware/FFBoard/UserExtensions/Src/SPIButtons.cpp @@ -84,6 +84,8 @@ void SPI_Buttons::registerCommands(){ registerCommand("btnnum", SPIButtons_commands::btnnum, "Number of buttons",CMDFLAG_GET | CMDFLAG_SET); registerCommand("cs", SPIButtons_commands::cs, "SPI CS pin",CMDFLAG_GET | CMDFLAG_SET); registerCommand("spispeed", SPIButtons_commands::spispeed, "SPI speed preset",CMDFLAG_INFOSTRING | CMDFLAG_GET | CMDFLAG_SET); + registerCommand("debounceen", SPIButtons_commands::debounceen, "Debounce enabled",CMDFLAG_GET | CMDFLAG_SET); + registerCommand("debouncetime", SPIButtons_commands::debouncetime, "Debounce time ms",CMDFLAG_GET | CMDFLAG_SET); } /** @@ -177,11 +179,38 @@ void SPI_Buttons::process(uint64_t* buf){ *buf = *buf & mask; } +void SPI_Buttons::setDebounceEnabled(bool enabled) { + this->conf.debounce_enabled = enabled; +} + +void SPI_Buttons::setDebounceTime(uint16_t time_ms) { + this->conf.debounce_time = time_ms; +} + __attribute__((optimize("-Ofast"))) uint8_t SPI_Buttons::readButtons(uint64_t* buf){ memcpy(buf,this->spi_buf,std::min(this->bytes,8)); process(buf); // give back last buffer + // Apply debouncing if enabled + if (conf.debounce_enabled) { + uint32_t current_time = HAL_GetTick(); + + // If button state has changed + if (*buf != last_button_state) { + last_debounce_time = current_time; + last_button_state = *buf; + } + + // If time elapsed exceeds debounce time, update stable state + if ((current_time - last_debounce_time) > conf.debounce_time) { + debounced_state = last_button_state; + } + + // Use debounced state + *buf = debounced_state; + } + if(spiPort.isTaken() || !ready) return this->btnnum; // Don't wait. @@ -265,6 +294,26 @@ CommandStatus SPI_Buttons::command(const ParsedCommand& cmd,std::vector> 8); c.cs_num = (config_int_2 & 0x3); c.spi_speed = (config_int_2 >> 3) & 0x3; + // Decode debounce settings + c.debounce_enabled = (config_int_2 >> 5) & 0x1; + c.debounce_time = ((config_int_2 >> 6) & 0x3FF) * 5; // Store in 5ms units, range 0-5115ms return c; } static std::tuple encodeConfToInt(ButtonSourceConfig* c){ @@ -289,7 +341,10 @@ static std::tuple encodeConfToInt(ButtonSourceConfig* c){ val |= (uint16_t)c->mode << 8; uint16_t val2 = c->cs_num & 0x3; val2 |= (c->spi_speed & 0x3) << 3; - + // Encode debounce settings + val2 |= (c->debounce_enabled ? 1 : 0) << 5; + val2 |= (std::min(c->debounce_time / 5, 0x3FF)) << 6; // Store in 5ms units, max about 5 seconds + return { val, val2 }; } From 343b753a14a1c3f8bf948040c36758154b9fb77e Mon Sep 17 00:00:00 2001 From: tinyboxxx Date: Wed, 23 Apr 2025 22:26:53 +0800 Subject: [PATCH 19/19] Update SPIButtons.h --- Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h b/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h index 0dbae7ffd..4218c4330 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h +++ b/Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h @@ -29,8 +29,8 @@ struct ButtonSourceConfig{ SPI_BtnMode mode=SPI_BtnMode::TM; // Mode preset uint8_t cs_num = 0; uint8_t spi_speed = 1; // Medium - bool debounce_enabled = true; // 默认开启消抖 - uint16_t debounce_time = 20; // 默认20ms消抖时间 + bool debounce_enabled = false; + uint16_t debounce_time = 0; // in ms };