diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d2d37a6b..db5c11a6e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 \ No newline at end of file +- 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 diff --git a/Configurator b/Configurator index f3fec28c6..ea43f41d9 160000 --- a/Configurator +++ b/Configurator @@ -1 +1 @@ -Subproject commit f3fec28c639aa2150f646252dd7051639c6007c8 +Subproject commit ea43f41d94d016dae70183ac31f20df8948274e9 diff --git a/Firmware/FFBoard/Inc/SelectableInputs.h b/Firmware/FFBoard/Inc/SelectableInputs.h new file mode 100644 index 000000000..f5827faf5 --- /dev/null +++ b/Firmware/FFBoard/Inc/SelectableInputs.h @@ -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& btn_chooser,const ClassChooser& 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* getAnalogValues(); + + +protected: + std::vector> btns; + std::vector> analog_inputs; + + cpp_freertos::BinarySemaphore sourcesSem = cpp_freertos::BinarySemaphore(true); + + uint16_t btnsources = 0; // Disabled by default + uint16_t ainsources = 0; + + std::vector analogsources_buf; // Persistent buffer + + ClassChooser btn_chooser; + ClassChooser analog_chooser; +}; + +#endif /* SRC_SELECTABLEINPUTS_H_ */ diff --git a/Firmware/FFBoard/Inc/constants.h b/Firmware/FFBoard/Inc/constants.h index 78f9b5e81..f5ad36f15 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,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 @@ -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 diff --git a/Firmware/FFBoard/Src/SelectableInputs.cpp b/Firmware/FFBoard/Src/SelectableInputs.cpp new file mode 100644 index 000000000..938214e14 --- /dev/null +++ b/Firmware/FFBoard/Src/SelectableInputs.cpp @@ -0,0 +1,114 @@ +/* + * SelectableInputs.cpp + * + * Created on: Apr 28, 2025 + * Author: Yannick + */ + +#include "SelectableInputs.h" + +SelectableInputs::SelectableInputs(const ClassChooser& btn_chooser,const ClassChooser& 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(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(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(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(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* SelectableInputs::getAnalogValues(){ + sourcesSem.Take(); + analogsources_buf.clear(); + for(auto &ain : analog_inputs){ + std::vector* buf = ain->getAxes(); + analogsources_buf.insert(analogsources_buf.end(), buf->begin(), buf->end()); + } + sourcesSem.Give(); + return &analogsources_buf; +} diff --git a/Firmware/FFBoard/UserExtensions/Inc/CanInputMain.h b/Firmware/FFBoard/UserExtensions/Inc/CanInputMain.h new file mode 100644 index 000000000..4b7dd0db8 --- /dev/null +++ b/Firmware/FFBoard/UserExtensions/Inc/CanInputMain.h @@ -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& 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 analogBuffer; + uint64_t digitalBuffer; + + CANPort& can; + + uint32_t buttons_id = 100; + uint32_t analog_id = 110; + + uint8_t rate_idx = 0; + const std::array report_rates = {1,2,4,8,10,16,32}; // Maps speed preset to report rates + + +}; +#endif +#endif /* USEREXTENSIONS_INC_CANINPUTMAIN_H_ */ diff --git a/Firmware/FFBoard/UserExtensions/Inc/ClassIDs.h b/Firmware/FFBoard/UserExtensions/Inc/ClassIDs.h index c741973e8..498bf173c 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/ClassIDs.h +++ b/Firmware/FFBoard/UserExtensions/Inc/ClassIDs.h @@ -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 diff --git a/Firmware/FFBoard/UserExtensions/Inc/FFBHIDMain.h b/Firmware/FFBoard/UserExtensions/Inc/FFBHIDMain.h index d52024d9a..72855f793 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/FFBHIDMain.h +++ b/Firmware/FFBoard/UserExtensions/Inc/FFBHIDMain.h @@ -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 }; @@ -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 @@ -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 btn_chooser; - ClassChooser analog_chooser; - //HID_CommandInterface hidCommands; // Enables full HID control std::unique_ptr hidCommands = std::make_unique(); uint32_t lastUsbReportTick = 0; - cpp_freertos::BinarySemaphore sourcesSem = cpp_freertos::BinarySemaphore(true); volatile uint32_t lastEstop = 0; }; diff --git a/Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h b/Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h index 589331d96..20b22adca 100644 --- a/Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h +++ b/Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h @@ -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]; @@ -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 diff --git a/Firmware/FFBoard/UserExtensions/Src/CanAnalog.cpp b/Firmware/FFBoard/UserExtensions/Src/CanAnalog.cpp index b6fb9e225..5651f7a86 100644 --- a/Firmware/FFBoard/UserExtensions/Src/CanAnalog.cpp +++ b/Firmware/FFBoard/UserExtensions/Src/CanAnalog.cpp @@ -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)); } } } diff --git a/Firmware/FFBoard/UserExtensions/Src/CanButtons.cpp b/Firmware/FFBoard/UserExtensions/Src/CanButtons.cpp index 80e3e4afc..03a03972c 100644 --- a/Firmware/FFBoard/UserExtensions/Src/CanButtons.cpp +++ b/Firmware/FFBoard/UserExtensions/Src/CanButtons.cpp @@ -135,7 +135,6 @@ CommandStatus CanButtons::command(const ParsedCommand& cmd,std::vectorcanId || msg.header.rtr || msg.header.length != 8){ return; } diff --git a/Firmware/FFBoard/UserExtensions/Src/CanInputMain.cpp b/Firmware/FFBoard/UserExtensions/Src/CanInputMain.cpp new file mode 100644 index 000000000..b21070d1f --- /dev/null +++ b/Firmware/FFBoard/UserExtensions/Src/CanInputMain.cpp @@ -0,0 +1,270 @@ +/* + * CanInputMain.cpp + * + * Created on: Apr 28, 2025 + * Author: Yannick + */ + + +#include "CanInputMain.h" +#include "usb_hid_ffb_desc.h" +#ifdef CANINPUTMAIN +// Unique identifier for listing +ClassIdentifier CANInputMain::info = { + .name = "CAN remote Digital/Analog" , + .id=CLSID_MAIN_CANINPUT, + }; + +const ClassIdentifier CANInputMain::getInfo(){ + return info; +} + +extern CANPort& canport; // Must be defined in target constants +CANInputMain::CANInputMain() : CANInputMain(canport) +{ + +} +CANInputMain::CANInputMain(CANPort& can): + SelectableInputs(ButtonSource::all_buttonsources,AnalogSource::all_analogsources), + Thread("FFBMAIN", 256, 30), + can(can) +{ + this->restoreFlash(); + this->registerCommands(); + analogBuffer.reserve(8); + this->Start(); +} + +CANInputMain::~CANInputMain() { + +} + + + +void CANInputMain::usbInit(){ + this->usbdev = std::make_unique(&usb_devdesc_ffboard_composite,usb_cdc_conf,&usb_ffboard_strings_default); + usbdev->registerUsb(); +} + + + +/** + * Read parameters from flash and restore settings + */ +void CANInputMain::restoreFlash(){ + + Flash_Read(ADR_FFBWHEEL_BUTTONCONF, &this->btnsources); + setBtnTypes(this->btnsources); + + Flash_Read(ADR_FFBWHEEL_ANALOGCONF, &this->ainsources); + setAinTypes(this->ainsources); + + uint16_t conf1; + if(Flash_Read(ADR_CANREMOTE_CONF1,&conf1)){ + buttons_id = conf1 & 0x7ff; // 11b + uint8_t rateidx = (conf1 >> 11) & 0x7; + setReportRate(rateidx); + } + if(Flash_Read(ADR_CANREMOTE_CONF2,&conf1)){ + analog_id = conf1 & 0x7ff; // 11b + } + +} +/** + * Save parameters to flash + */ +void CANInputMain::saveFlash(){ + + Flash_Write(ADR_FFBWHEEL_BUTTONCONF,this->btnsources); + Flash_Write(ADR_FFBWHEEL_ANALOGCONF,this->ainsources); + + uint16_t conf; + conf = buttons_id & 0x7ff; + conf |= (rate_idx & 0x7) << 11; + Flash_Write(ADR_CANREMOTE_CONF1,conf); + conf = analog_id & 0x7ff; + Flash_Write(ADR_CANREMOTE_CONF2,conf); +} + + + +void CANInputMain::Run(){ + + while(true){ + Delay(1); + updateControl(); + } +} + + +/** + * Main update loop + */ +void CANInputMain::updateControl(){ + if(++report_rate_cnt >= report_rate){ + report_rate_cnt = 0; + + sendReport(); + } +} + +void CANInputMain::sendReport(){ + uint64_t prevDigital = digitalBuffer; + digitalBuffer = 0; // Clear buffer + SelectableInputs::getButtonValues(digitalBuffer); + if(prevDigital != digitalBuffer){ // Only send when data changed + CAN_tx_msg msg; + msg.header.id = buttons_id; + msg.header.length = 8; // 64 buttons + for(uint8_t i = 0;i<8;i++){ + msg.data[i] = ((digitalBuffer >> (i*8)) & 0xff); + } + can.sendMessage(msg); + } + + std::vector* analogValues = SelectableInputs::getAnalogValues(); + if(analogValues->size() != analogBuffer.size()){ + analogBuffer.assign(analogValues->size(), 0); // Initialize vector if size changes + } + + CAN_tx_msg msg; + const uint8_t valuesPerMsg = 4; + for(uint8_t i = 0;isize();i+=valuesPerMsg){ + bool changed = false; + msg.header.id = analog_id + (i/valuesPerMsg); + msg.header.length = 8; + for(uint8_t v = 0;v= analogValues->size()){ + break; + } + int32_t val = analogValues->at(idx); + if(val != analogBuffer[idx]){ + changed = true; + } + msg.data[v*2] = val & 0xff; + msg.data[(v*2) +1] = (val >> 8) & 0xff; + } + if(changed){ + can.sendMessage(msg); + msg = CAN_tx_msg(); // Clear + } + } + analogBuffer = *analogValues; // Copy values +} + +/** + * Changes the report rate based on the index for report_rates + */ +void CANInputMain::setReportRate(uint8_t rateidx){ + rateidx = clip(rateidx, 0,report_rates.size()); + rate_idx = rateidx; + report_rate = report_rates[rateidx]; +} + +/** + * Generates the speed strings to display to the user + */ +std::string CANInputMain::report_rates_names() { + std::string s = ""; + for(uint8_t i = 0 ; i < report_rates.size();i++){ + s += std::to_string(1000/(report_rates[i])) + "Hz:"+std::to_string(i); + if(i < sizeof(report_rates)-1) + s += ","; + } + return s; +} + + +void CANInputMain::registerCommands(){ + // CAN speed controlled by CAN port commands directly + registerCommand("canidbtn", CANInput_commands::caniddigital, "Button output CAN ID",CMDFLAG_GET|CMDFLAG_SET); + registerCommand("canidain", CANInput_commands::canidanalog, "Analog output start CAN ID",CMDFLAG_GET|CMDFLAG_SET); + + registerCommand("btntypes", CANInput_commands::btntypes, "Enabled button sources",CMDFLAG_GET|CMDFLAG_SET); + registerCommand("addbtn", CANInput_commands::addbtn, "Enable button source",CMDFLAG_SET); + registerCommand("lsbtn", CANInput_commands::lsbtn, "Get available button sources",CMDFLAG_GET|CMDFLAG_STR_ONLY); + + registerCommand("aintypes", CANInput_commands::aintypes, "Enabled analog sources",CMDFLAG_GET|CMDFLAG_SET); + registerCommand("lsain", CANInput_commands::lsain, "Get available analog sources",CMDFLAG_GET|CMDFLAG_STR_ONLY); + registerCommand("addain", CANInput_commands::addain, "Enable analog source",CMDFLAG_SET); + + registerCommand("rate", CANInput_commands::rate, "CAN interval rate",CMDFLAG_GET|CMDFLAG_SET|CMDFLAG_INFOSTRING); + + registerCommand("dvals", CANInput_commands::dvals, "Current digital outputs",CMDFLAG_GET); + registerCommand("avals", CANInput_commands::avals, "Current analog outputs",CMDFLAG_GET); +} + +CommandStatus CANInputMain::command(const ParsedCommand& cmd,std::vector& replies){ + switch(static_cast(cmd.cmdId)){ + case CANInput_commands::caniddigital: + handleGetSet(cmd, replies, buttons_id); + break; + case CANInput_commands::canidanalog: + handleGetSet(cmd, replies, analog_id); + break; + // Source management + case CANInput_commands::btntypes: + if(cmd.type == CMDtype::get){ + replies.emplace_back(btnsources); + }else if(cmd.type == CMDtype::set){ + setBtnTypes(cmd.val); + } + break; + case CANInput_commands::lsbtn: + btn_chooser.replyAvailableClasses(replies); + break; + case CANInput_commands::addbtn: + if(cmd.type == CMDtype::set){ + this->addBtnType(cmd.val); + } + break; + case CANInput_commands::aintypes: + if(cmd.type == CMDtype::get){ + replies.emplace_back(ainsources); + }else if(cmd.type == CMDtype::set){ + setAinTypes(cmd.val); + } + break; + case CANInput_commands::lsain: + analog_chooser.replyAvailableClasses(replies); + break; + case CANInput_commands::addain: + if(cmd.type == CMDtype::set){ + this->addAinType(cmd.val); + } + break; + + case CANInput_commands::rate: + if(cmd.type == CMDtype::get){ + replies.emplace_back(rate_idx); + }else if(cmd.type == CMDtype::set){ + setReportRate(cmd.val); + }else if(cmd.type == CMDtype::info){ + replies.emplace_back(report_rates_names()); + } + break; + + case CANInput_commands::dvals: + if(cmd.type == CMDtype::get){ + replies.emplace_back(digitalBuffer,0); + } + break; + + case CANInput_commands::avals: + if(cmd.type == CMDtype::get){ + for(uint8_t i = 0;ibtns.clear(); -} - -void FFBHIDMain::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(btn)); - } - } - sourcesSem.Give(); -} - -void FFBHIDMain::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(btn)); -} - -// Analog -void FFBHIDMain::clearAinTypes(){ - // Destruct all button sources - - this->analog_inputs.clear(); -} - -void FFBHIDMain::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(ain)); - } - } - sourcesSem.Give(); -} -void FFBHIDMain::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(ain)); -} - uint32_t FFBHIDMain::getRate() { return this->ffb->getRate(); } @@ -215,21 +151,15 @@ void FFBHIDMain::send_report(){ return; } //Try semaphore - if(!sourcesSem.Take(10)){ - return; - } +// if(!sourcesSem.Take(10)){ +// return; +// } // Read buttons reportHID.buttons = 0; // Reset buttons - uint8_t shift = 0; - if(btns.size() != 0){ - for(auto &btn : btns){ - uint64_t buf = 0; - uint8_t amount = btn->readButtons(&buf); - reportHID.buttons |= buf << shift; - shift += amount; - } - } + uint64_t b = 0; + SelectableInputs::getButtonValues(b); + reportHID.buttons = b; // Encoder //axes_manager->addAxesToReport(analogAxesReport, &count); @@ -241,15 +171,13 @@ void FFBHIDMain::send_report(){ } // Fill remaining values with analog inputs - for(auto &ain : analog_inputs){ - std::vector* axes = ain->getAxes(); - for(int32_t val : *axes){ - if(count >= analogAxisCount) - break; - setHidReportAxis(&reportHID,count++,val); - } + axes = SelectableInputs::getAnalogValues(); + for(int32_t val : *axes){ + if(count >= analogAxisCount) + break; + setHidReportAxis(&reportHID,count++,val); } - sourcesSem.Give(); +// sourcesSem.Give(); // Fill rest for(;count> class_registry = add_class(), #endif +#ifdef CANINPUTMAIN + add_class(), +#endif + add_class() }; #endif diff --git a/Firmware/Targets/F407VG/Core/Inc/target_constants.h b/Firmware/Targets/F407VG/Core/Inc/target_constants.h index d74893d82..7f7ea606c 100644 --- a/Firmware/Targets/F407VG/Core/Inc/target_constants.h +++ b/Firmware/Targets/F407VG/Core/Inc/target_constants.h @@ -29,6 +29,7 @@ #define CANBRIDGE #define FFBHIDEXT #define RMDCAN +#define CANINPUTMAIN /* * FFBWheel uses 2 FFB axis descriptor instead of 1 axis. diff --git a/Firmware/Targets/F407VG_DISCO/Core/Inc/target_constants.h b/Firmware/Targets/F407VG_DISCO/Core/Inc/target_constants.h index 8ec3d29a2..f083732d7 100644 --- a/Firmware/Targets/F407VG_DISCO/Core/Inc/target_constants.h +++ b/Firmware/Targets/F407VG_DISCO/Core/Inc/target_constants.h @@ -28,6 +28,7 @@ //#define TMCDEBUG #define CANBRIDGE #define FFBHIDEXT +#define CANINPUTMAIN /* * FFBWheel uses 2 FFB axis descriptor instead of 1 axis. diff --git a/Firmware/scripts/memory_map.csv b/Firmware/scripts/memory_map.csv index d26131c20..5060f6739 100644 --- a/Firmware/scripts/memory_map.csv +++ b/Firmware/scripts/memory_map.csv @@ -11,6 +11,9 @@ Section comment,Name,Value,Comment on key,VirtAddVarTab,exportableFlashAddresses ,ADR_FFBWHEEL_BUTTONCONF,0x101,,1,1 ,ADR_FFBWHEEL_ANALOGCONF,0x102,,1,1 ,ADR_FFBWHEEL_CONF1,0x103,,1,1 +// CAN remote,,,,, +,ADR_CANREMOTE_CONF1,0x120,,1,1 +,ADR_CANREMOTE_CONF2,0x121,,1,1 // Button Sources:,,,,, ,ADR_SPI_BTN_1_CONF,0x201,,1,1 ,ADR_SHIFTERANALOG_CONF,0x202,,1,1