Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 8 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,17 @@
### 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
- 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)
- Using interrupt transfer for TMC4671 encoder forwarding (Fixed again)

- Added remote CAN button/analog source mainclass

### 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
- F407: ADC now triggered by timer to reduce interrupt frequency
- Using analog VREF for voltage sensing (better accuracy with unstable 3.3V)
- Added chip temperature readout

Internal changes:
- CAN port interfaces rewritten
- HAL updated
- Migrated to CPP20
- Upgraded to tinyusb 0.17
- Improved microsecond counter implementation
- Improved microsecond counter implementation
- 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
- F407: ADC now triggered by timer to reduce interrupt frequency
- Using analog VREF for voltage sensing (better accuracy with unstable 3.3V)
- Added chip temperature readout
2 changes: 1 addition & 1 deletion Configurator
49 changes: 49 additions & 0 deletions Firmware/FFBoard/Inc/SelectableInputs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* SelectableInputs.h
*
* Created on: Apr 28, 2025
* Author: Yannick
*/

#ifndef SRC_SELECTABLEINPUTS_H_
#define SRC_SELECTABLEINPUTS_H_
#include "AnalogSource.h"
#include "ButtonSource.h"
#include "semaphore.hpp"

/**
* Helper class with common functions to manage input sources
*/
class SelectableInputs {
public:
SelectableInputs(const ClassChooser<ButtonSource>& btn_chooser,const ClassChooser<AnalogSource>& analog_chooser);
virtual ~SelectableInputs();

virtual void setBtnTypes(uint16_t btntypes);
virtual void addBtnType(uint16_t id);
virtual void clearBtnTypes();

virtual void setAinTypes(uint16_t aintypes);
virtual void addAinType(uint16_t id);
virtual void clearAinTypes();

virtual uint8_t getButtonValues(uint64_t &values);
virtual std::vector<int32_t>* getAnalogValues();


protected:
std::vector<std::unique_ptr<ButtonSource>> btns;
std::vector<std::unique_ptr<AnalogSource>> analog_inputs;

cpp_freertos::BinarySemaphore sourcesSem = cpp_freertos::BinarySemaphore(true);

uint16_t btnsources = 0; // Disabled by default
uint16_t ainsources = 0;

std::vector<int32_t> analogsources_buf; // Persistent buffer

ClassChooser<ButtonSource> btn_chooser;
ClassChooser<AnalogSource> analog_chooser;
};

#endif /* SRC_SELECTABLEINPUTS_H_ */
4 changes: 3 additions & 1 deletion Firmware/FFBoard/Inc/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,2}; // Version as array. 8 bit each!
static const uint8_t SW_VERSION_INT[3] = {1,16,3}; // Version as array. 8 bit each!
#ifndef MAX_AXIS
#define MAX_AXIS 2 // ONLY USE 2 for now else screws HID Reports
#endif
Expand All @@ -24,6 +24,8 @@ static const uint8_t SW_VERSION_INT[3] = {1,16,2}; // Version as array. 8 bit ea
#undef ODRIVE
#undef CANBUTTONS
#undef VESC
#undef CANBRIDGE
#undef CANINPUTMAIN
#endif


Expand Down
114 changes: 114 additions & 0 deletions Firmware/FFBoard/Src/SelectableInputs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* SelectableInputs.cpp
*
* Created on: Apr 28, 2025
* Author: Yannick
*/

#include "SelectableInputs.h"

SelectableInputs::SelectableInputs(const ClassChooser<ButtonSource>& btn_chooser,const ClassChooser<AnalogSource>& analog_chooser)
: btn_chooser(btn_chooser), analog_chooser(analog_chooser)
{
analogsources_buf.reserve(8);
}

SelectableInputs::~SelectableInputs() {
clearAinTypes();
clearBtnTypes();
}

// Buttons
void SelectableInputs::clearBtnTypes(){
// Destruct all button sources

this->btns.clear();
}

void SelectableInputs::setBtnTypes(uint16_t btntypes){
sourcesSem.Take();
this->btnsources = btntypes;
clearBtnTypes();
for(uint8_t id = 0;id<16;id++){
if((btntypes >> id) & 0x1){
// Matching flag
ButtonSource* btn = btn_chooser.Create(id);
if(btn!=nullptr)
this->btns.push_back(std::unique_ptr<ButtonSource>(btn));
}
}
sourcesSem.Give();
}

void SelectableInputs::addBtnType(uint16_t id){
for(auto &btn : this->btns){
if(btn->getInfo().id == id){
return;
}
}
ButtonSource* btn = btn_chooser.Create(id);
if(btn!=nullptr)
this->btns.push_back(std::unique_ptr<ButtonSource>(btn));
}

// Analog
void SelectableInputs::clearAinTypes(){
// Destruct all button sources

this->analog_inputs.clear();
}

void SelectableInputs::setAinTypes(uint16_t aintypes){
sourcesSem.Take();
this->ainsources = aintypes;
clearAinTypes();
for(uint8_t id = 0;id<16;id++){
if((aintypes >> id) & 0x1){
// Matching flag
AnalogSource* ain = analog_chooser.Create(id);
if(ain!=nullptr)
this->analog_inputs.push_back(std::unique_ptr<AnalogSource>(ain));
}
}
sourcesSem.Give();
}
void SelectableInputs::addAinType(uint16_t id){
for(auto &ain : this->analog_inputs){
if(ain->getInfo().id == id){
return;
}
}
AnalogSource* ain = analog_chooser.Create(id);
if(ain!=nullptr)
this->analog_inputs.push_back(std::unique_ptr<AnalogSource>(ain));
}

/**
* Gets button values from all button sources
*/
uint8_t SelectableInputs::getButtonValues(uint64_t &values){
uint8_t shift = 0;
if(btns.size() != 0){
for(auto &btn : btns){
uint64_t buf = 0;
uint8_t amount = btn->readButtons(&buf);
values |= buf << shift;
shift += amount;
}
}
return shift;
}

/**
* Gets analog values from all analog sources
*/
std::vector<int32_t>* SelectableInputs::getAnalogValues(){
sourcesSem.Take();
analogsources_buf.clear();
for(auto &ain : analog_inputs){
std::vector<int32_t>* buf = ain->getAxes();
analogsources_buf.insert(analogsources_buf.end(), buf->begin(), buf->end());
}
sourcesSem.Give();
return &analogsources_buf;
}
72 changes: 72 additions & 0 deletions Firmware/FFBoard/UserExtensions/Inc/CanInputMain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/*
* CanInputMain.h
*
* Created on: Apr 28, 2025
* Author: Yannick
*/

#ifndef USEREXTENSIONS_INC_CANINPUTMAIN_H_
#define USEREXTENSIONS_INC_CANINPUTMAIN_H_
#include "constants.h"
#ifdef CANINPUTMAIN

#include "FFBoardMain.h"
#include "PersistentStorage.h"
#include "ButtonSource.h"
#include "AnalogSource.h"
#include "thread.hpp"
#include "CAN.h"
#include "SelectableInputs.h"

class CANInputMain : public FFBoardMain, public PersistentStorage, public SelectableInputs, public cpp_freertos::Thread {
enum class CANInput_commands : uint32_t{
caniddigital,canidanalog,btntypes,lsbtn,addbtn,aintypes,lsain,addain,rate,dvals,avals
};
public:
CANInputMain();
CANInputMain(CANPort& canport);
virtual ~CANInputMain();

static ClassIdentifier info;
const ClassIdentifier getInfo();
static bool isCreatable() {return true;};

CommandStatus command(const ParsedCommand& cmd,std::vector<CommandReply>& replies);
void registerCommands();
virtual std::string getHelpstring(){
return "Remote CAN Analog/Digital source";
}

void usbInit() override;

void saveFlash();
void restoreFlash();

void Run();

void updateControl();
void sendReport();

void setReportRate(uint8_t rateidx);
std::string report_rates_names();


protected:
uint32_t report_rate_cnt = 0;
uint32_t report_rate = 1;

std::vector<int32_t> analogBuffer;
uint64_t digitalBuffer;

CANPort& can;

uint32_t buttons_id = 100;
uint32_t analog_id = 110;

uint8_t rate_idx = 0;
const std::array<uint8_t,7> report_rates = {1,2,4,8,10,16,32}; // Maps speed preset to report rates


};
#endif
#endif /* USEREXTENSIONS_INC_CANINPUTMAIN_H_ */
1 change: 1 addition & 0 deletions Firmware/FFBoard/UserExtensions/Inc/ClassIDs.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ enum class ClassType : uint16_t {
#define CLSID_MAIN_FFBWHEEL 0x1
#define CLSID_MAIN_FFBJOY 0x2
#define CLSID_MAIN_FFBEXT 0x3
#define CLSID_MAIN_CANINPUT 0x5
#define CLSID_MAIN_TMCDBG 0xB
#define CLSID_MAIN_CAN 0xC
#define CLSID_MAIN_MIDI 0xD
Expand Down
19 changes: 2 additions & 17 deletions Firmware/FFBoard/UserExtensions/Inc/FFBHIDMain.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,10 @@
#include "ErrorHandler.h"
#include "memory"
#include "HidCommandInterface.h"

#include "SelectableInputs.h"
#include "thread.hpp"

class FFBHIDMain: public FFBoardMain, public cpp_freertos::Thread, PersistentStorage,ExtiHandler,public UsbHidHandler, ErrorHandler{
class FFBHIDMain: public FFBoardMain, public cpp_freertos::Thread, PersistentStorage,ExtiHandler,public UsbHidHandler, ErrorHandler, SelectableInputs{
enum class FFBWheel_commands : uint32_t{
ffbactive,axes,btntypes,lsbtn,addbtn,aintypes,lsain,addain,hidrate,hidsendspd,estop,cfrate
};
Expand All @@ -52,13 +52,6 @@ class FFBHIDMain: public FFBoardMain, public cpp_freertos::Thread, PersistentSto
virtual std::string getHelpstring(){
return "Force feedback HID game controller";
}
void setBtnTypes(uint16_t btntypes);
void addBtnType(uint16_t id);
void clearBtnTypes();

void setAinTypes(uint16_t aintypes);
void addAinType(uint16_t id);
void clearAinTypes();


virtual void usbInit() = 0; // initialize a composite usb device
Expand Down Expand Up @@ -117,18 +110,10 @@ class FFBHIDMain: public FFBoardMain, public cpp_freertos::Thread, PersistentSto
uint8_t reportSendCounter = 0;

const uint8_t analogAxisCount = 8;
uint16_t btnsources = 0; // Disabled by default
uint16_t ainsources = 0;


ClassChooser<ButtonSource> btn_chooser;
ClassChooser<AnalogSource> analog_chooser;

//HID_CommandInterface hidCommands; // Enables full HID control
std::unique_ptr<HID_CommandInterface> hidCommands = std::make_unique<HID_CommandInterface>();

uint32_t lastUsbReportTick = 0;
cpp_freertos::BinarySemaphore sourcesSem = cpp_freertos::BinarySemaphore(true);

volatile uint32_t lastEstop = 0;
};
Expand Down
7 changes: 5 additions & 2 deletions Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@

#include "main.h"
// Change this to the amount of currently registered variables
#define NB_OF_VAR 159
#define NB_OF_VAR 161
extern const uint16_t VirtAddVarTab[NB_OF_VAR];

// Amount of variables in exportable list
#define NB_EXPORTABLE_ADR 144
#define NB_EXPORTABLE_ADR 146
extern const uint16_t exportableFlashAddresses[NB_EXPORTABLE_ADR];


Expand Down Expand Up @@ -47,6 +47,9 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if
#define ADR_FFBWHEEL_BUTTONCONF 0x101
#define ADR_FFBWHEEL_ANALOGCONF 0x102
#define ADR_FFBWHEEL_CONF1 0x103
// CAN remote
#define ADR_CANREMOTE_CONF1 0x120
#define ADR_CANREMOTE_CONF2 0x121
// Button Sources:
#define ADR_SPI_BTN_1_CONF 0x201
#define ADR_SHIFTERANALOG_CONF 0x202
Expand Down
2 changes: 1 addition & 1 deletion Firmware/FFBoard/UserExtensions/Src/CanAnalog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ void CanAnalogBase::canRxPendCallback(CANPort* port,CAN_rx_msg& msg){
continue;
}
for(uint8_t i = 0; i < 4 && (i + packet*4) < axes && (i*2+1) < msg.header.length; i++) {
this->buf[i + packet*4] = msg.data[i*2] | (msg.data[i*2+1] << 8);
this->buf[i + packet*4] = (int16_t)(msg.data[i*2] | (msg.data[i*2+1] << 8));
}
}
}
Expand Down
1 change: 0 additions & 1 deletion Firmware/FFBoard/UserExtensions/Src/CanButtons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@ CommandStatus CanButtons::command(const ParsedCommand& cmd,std::vector<CommandRe
void CanButtons::canRxPendCallback(CANPort* port,CAN_rx_msg& msg){

uint32_t id = (msg.header.id) & 0x7FF;
pulseClipLed();
if(id != this->canId || msg.header.rtr || msg.header.length != 8){
return;
}
Expand Down
Loading