Skip to content

Commit f2c8df3

Browse files
author
Orlando Eduardo Pereira
committed
Add Logitech G27 shifter fix and SPI3 support for wheel rim buttons
## ShifterAnalog G27 Mode Fix - Fix SPI clock configuration for 74HC165 (CLKPhase, CLKPolarity) - Add CS polarity configuration for active-low operation - Change to synchronous SPI read for reliable button reading - Fix CS pin index off-by-one error in setMode() and setCSPin() - Add startRead() method to trigger SPI before processing data ## SPI Buttons 3 (SPI3 Support) - Add SPI_Buttons_3 class using SPI3 peripheral for separate button source - Required because 74HC165 lacks tri-state output (cannot share MISO) - Allows G27 shifter (SPI2) and wheel rim (SPI3) to work simultaneously - SPI3 pins: PC10 (SCK), PC11 (MISO), PA15 (CS1) ## Hardware Configuration (F407VG) - Reduce SPI3 baud rate for reliable 74HC165 communication - Initialize SPI CS pins HIGH (inactive) to prevent bus contention - Enable SPIBUTTONS3 feature flag ## Documentation - Add complete wiring guide for all G27 components - Add technical reports documenting bugs and solutions - Bilingual documentation (English/Portuguese) Tested with Logitech G27 on STM32F407VET6 board. Made-with: Cursor
1 parent cafe50c commit f2c8df3

14 files changed

Lines changed: 1736 additions & 97 deletions

Firmware/FFBoard/UserExtensions/Inc/SPIButtons.h

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ struct ButtonSourceConfig{
3535
class SPI_Buttons: public ButtonSource,public CommandHandler,public SPIDevice {
3636

3737
enum class SPIButtons_commands : uint32_t {
38-
mode,btncut,btnpol,btnnum,cs,spispeed
38+
mode,btncut,btnpol,btnnum,cs,spispeed,debug,syncread
3939
};
4040

4141
public:
@@ -45,13 +45,14 @@ class SPI_Buttons: public ButtonSource,public CommandHandler,public SPIDevice {
4545
virtual ~SPI_Buttons();
4646

4747
uint8_t readButtons(uint64_t* buf);
48+
uint16_t getBtnNum() override; // Override to return conf.numButtons
4849

4950
CommandStatus command(const ParsedCommand& cmd,std::vector<CommandReply>& replies) override;
5051
void registerCommands();
5152
virtual std::string getHelpstring(){return "SPI 2 Button";}
5253

5354
void saveFlash();
54-
void restoreFlash();
55+
virtual void restoreFlash();
5556

5657
const uint8_t maxButtons = 64;
5758
std::string printModes(const std::vector<std::string>& names);
@@ -63,32 +64,29 @@ class SPI_Buttons: public ButtonSource,public CommandHandler,public SPIDevice {
6364
void setSpiSpeed(uint8_t speedPreset);
6465

6566
protected:
66-
SPI_Buttons(uint16_t configuration_address, uint16_t configuration_address_2);
67-
68-
private:
67+
SPI_Buttons(uint16_t configuration_address, uint16_t configuration_address_2, SPIPort* spiPort = &external_spi, uint8_t instance = 0);
6968
uint16_t configuration_address;
7069
uint16_t configuration_address_2;
71-
bool ready = false;
7270
void setConfig(ButtonSourceConfig config);
7371
virtual ButtonSourceConfig* getConfig();
74-
void process(uint64_t* buf);
75-
uint8_t bytes = 4;
72+
73+
private:
74+
bool ready = false;
7675
uint64_t mask = 0xff;
7776
uint8_t offset = 0;
7877

79-
ButtonSourceConfig conf;
78+
static constexpr std::array<uint32_t,3> speedPresets= {SPI_BAUDRATEPRESCALER_16,SPI_BAUDRATEPRESCALER_32,SPI_BAUDRATEPRESCALER_64};
8079

80+
protected:
81+
void process(uint64_t* buf);
82+
uint8_t bytes = 4;
8183
uint8_t spi_buf[4] = {0};
82-
83-
static constexpr std::array<uint32_t,3> speedPresets= {SPI_BAUDRATEPRESCALER_16,SPI_BAUDRATEPRESCALER_32,SPI_BAUDRATEPRESCALER_64};
84+
ButtonSourceConfig conf;
8485
};
8586

8687
class SPI_Buttons_1 : public SPI_Buttons {
8788
public:
88-
SPI_Buttons_1()
89-
: SPI_Buttons{ADR_SPI_BTN_1_CONF, ADR_SPI_BTN_1_CONF_2} {
90-
setInstance(0);
91-
}
89+
SPI_Buttons_1();
9290

9391
const ClassIdentifier getInfo() override;
9492
static ClassIdentifier info;
@@ -98,14 +96,24 @@ class SPI_Buttons_1 : public SPI_Buttons {
9896

9997
class SPI_Buttons_2 : public SPI_Buttons {
10098
public:
101-
SPI_Buttons_2()
102-
: SPI_Buttons{ADR_SPI_BTN_2_CONF, ADR_SPI_BTN_2_CONF_2} {
103-
setInstance(1);
104-
}
99+
SPI_Buttons_2();
100+
101+
const ClassIdentifier getInfo() override;
102+
static ClassIdentifier info;
103+
static bool isCreatable();
104+
};
105+
106+
class SPI_Buttons_3 : public SPI_Buttons {
107+
public:
108+
SPI_Buttons_3();
105109

106110
const ClassIdentifier getInfo() override;
107111
static ClassIdentifier info;
108112
static bool isCreatable();
113+
114+
void restoreFlash() override; // Override to set default values
115+
uint8_t readButtons(uint64_t* buf) override; // Override to use synchronous read for SPI3
116+
std::string getHelpstring() override {return "SPI 3 Button (SPI3)";}
109117
};
110118

111119
#endif /* SPIBUTTONS_H_ */

Firmware/FFBoard/UserExtensions/Inc/ShifterAnalog.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,14 @@ enum class ShifterAnalog_commands : uint32_t{
6363
G27ShifterButtonClient(OutputPin& csPin);
6464

6565
static constexpr int numUserButtons{12};
66+
static constexpr int bytesToRead{2}; // 16 buttons = 2 bytes (same as SPI Buttons with 16 buttons)
6667

6768
uint16_t getUserButtons();
6869
bool getReverseButton();
69-
private:
70-
uint16_t buttonStates{0};
70+
void startRead(); // Start a new DMA read (like SPI_Buttons does)
71+
void spiRxCompleted(SPIPort* port) override; // Called when DMA completes
72+
73+
uint8_t spi_buf[2]{0}; // Buffer for SPI read (2 bytes for 16 buttons) - DMA writes directly here
7174

7275
};
7376

Firmware/FFBoard/UserExtensions/Inc/eeprom_addresses.h

Lines changed: 25 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
1-
/*
2-
* eeprom_addresses.h
3-
*
4-
* Created on: 24.01.2020
5-
* Author: Yannick
6-
*
7-
* /!\ Generated from the file memory_map.csv
8-
/ ! \ DO NOT EDIT THIS DIRECTLY !!!
9-
*/
10-
1+
/*
2+
* eeprom_addresses.h
3+
*
4+
* Created on: 24.01.2020
5+
* Author: Yannick
6+
*
7+
* /!\ Generated from the file memory_map.csv
8+
/ ! \ DO NOT EDIT THIS DIRECTLY !!!
9+
*/
10+
1111
#ifndef EEPROM_ADDRESSES_H_
1212
#define EEPROM_ADDRESSES_H_
1313

@@ -21,19 +21,19 @@ extern const uint16_t VirtAddVarTab[NB_OF_VAR];
2121
extern const uint16_t exportableFlashAddresses[NB_EXPORTABLE_ADR];
2222

2323

24-
25-
/* Add your addresses here. 0xffff is invalid as it marks an erased field.
26-
Anything below 0x00ff is reserved for system variables.
27-
28-
Use ranges that are clear to distinguish between configurations. Address ranges can have gaps.
29-
Label the names clearly.
30-
Example: 0x0100 - 0x01ff for one class and 0x0200-0x02ff for another class would be reasonable even if they each need only 3 variables
31-
32-
33-
Important: Add your variable to the VirtAddVarTab[NB_OF_VAR] array in eeprom_addresses.c!
34-
35-
Tip to check if a cell is intialized:
36-
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if the address is not found or 0 if it was found.
24+
25+
/* Add your addresses here. 0xffff is invalid as it marks an erased field.
26+
Anything below 0x00ff is reserved for system variables.
27+
28+
Use ranges that are clear to distinguish between configurations. Address ranges can have gaps.
29+
Label the names clearly.
30+
Example: 0x0100 - 0x01ff for one class and 0x0200-0x02ff for another class would be reasonable even if they each need only 3 variables
31+
32+
33+
Important: Add your variable to the VirtAddVarTab[NB_OF_VAR] array in eeprom_addresses.c!
34+
35+
Tip to check if a cell is intialized:
36+
uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if the address is not found or 0 if it was found.
3737
*/
3838
// System variables
3939
#define ADR_HW_VERSION 1
@@ -58,6 +58,8 @@ uint16_t EE_ReadVariable(uint16_t VirtAddress, uint16_t* Data) will return 1 if
5858
#define ADR_SPI_BTN_2_CONF 0x205
5959
#define ADR_SPI_BTN_1_CONF_2 0x206
6060
#define ADR_SPI_BTN_2_CONF_2 0x207
61+
#define ADR_SPI_BTN_3_CONF 0x209
62+
#define ADR_SPI_BTN_3_CONF_2 0x20A
6163
#define ADR_LOCAL_BTN_CONF_3 0x208 // Pulse mask
6264
// Local encoder
6365
#define ADR_ENCLOCAL_CPR 0x210

Firmware/FFBoard/UserExtensions/Src/ButtonSources.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@ const std::vector<class_entry<ButtonSource>> ButtonSource::all_buttonsources =
2424
#ifdef SPIBUTTONS2
2525
add_class<SPI_Buttons_2,ButtonSource>(2),
2626
#endif
27+
#ifdef SPIBUTTONS3
28+
add_class<SPI_Buttons_3,ButtonSource>(6),
29+
#endif
2730
#ifdef SHIFTERBUTTONS
2831
add_class<ShifterAnalog,ButtonSource>(3),
2932
#endif

0 commit comments

Comments
 (0)