HID-RP

The hid-rp component provides a wrapper around https://github.com/intergatedcircuits/hid-rp and also provides an example implementation of a configurable HID Gamepad using hid-rp.

API Reference

Header File

Header File

Classes

template<size_t BUTTON_COUNT = 15, typename JOYSTICK_TYPE = std::uint16_t, typename TRIGGER_TYPE = std::uint16_t, JOYSTICK_TYPE JOYSTICK_MIN = 0, JOYSTICK_TYPE JOYSTICK_MAX = 65535, TRIGGER_TYPE TRIGGER_MIN = 0, TRIGGER_TYPE TRIGGER_MAX = 1023, uint8_t REPORT_ID = 1>
class GamepadInputReport : public hid::report::base<hid::report::type::INPUT, 1>

HID Gamepad Input Report This class implements a HID Gamepad with a configurable number of buttons, a hat switch, 4 joystick axes and two trigger axes. It supports setting the buttons, hat switch, joysticks, and triggers, as well as serializing the input report and getting the report descriptor.

HID-RP Example

  static constexpr uint8_t input_report_id = 1;
  static constexpr uint8_t battery_report_id = 4;
  static constexpr size_t num_buttons = 15;
  static constexpr int joystick_min = 0;
  static constexpr int joystick_max = 65535;
  static constexpr int trigger_min = 0;
  static constexpr int trigger_max = 1023;

  using GamepadInput =
      espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min,
                               joystick_max, trigger_min, trigger_max, input_report_id>;
  GamepadInput gamepad_input_report;

  using XboxInput = espp::XboxGamepadInputReport<input_report_id>;
  XboxInput xbox_input_report;

  using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>;
  BatteryReport battery_input_report;

  static constexpr uint8_t led_output_report_id = 2;
  static constexpr size_t num_leds = 4;
  using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>;
  GamepadLeds gamepad_leds_report;

  static constexpr uint8_t rumble_output_report_id = 3;
  using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>;
  RumbleReport rumble_output_report;

  using namespace hid::page;
  using namespace hid::rdf;
  auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD),
                                   collection::application(gamepad_input_report.get_descriptor(),
                                                           rumble_output_report.get_descriptor(),
                                                           battery_input_report.get_descriptor(),
                                                           gamepad_leds_report.get_descriptor()));

  // Generate the report descriptor for the gamepad
  auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end());

  logger.info("Report Descriptor:");
  logger.info("  Size: {}", descriptor.size());
  logger.info("  Data: {::#04X}", descriptor);

  using SwitchProInput = espp::SwitchProGamepadInputReport<>;
  SwitchProInput switch_pro_input_report;
  switch_pro_input_report.reset();
  logger.info("{}", switch_pro_input_report);
  logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size());
  logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report());

  auto sp_raw_descriptor = espp::switch_pro_descriptor();
  auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end());

  logger.info("Switch Report Descriptor:");
  logger.info("  Size: {}", sp_descriptor.size());
  std::string str = "";
  for (auto &byte : sp_descriptor) {
    str += fmt::format("0x{:02X}, ", byte);
  }
  logger.info("  Data: [{}]", str);

  GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT;
  int button_index = 5;
  float angle = 2.0f * M_PI * button_index / num_buttons;

  // update the gamepad input report
  gamepad_input_report.reset();
  logger.info("{}", gamepad_input_report);
  gamepad_input_report.set_hat(hat);
  gamepad_input_report.set_button(button_index, true);
  // joystick inputs are in the range [-1, 1] float
  gamepad_input_report.set_right_joystick(cos(angle), sin(angle));
  gamepad_input_report.set_left_joystick(sin(angle), cos(angle));
  // trigger inputs are in the range [0, 1] float
  gamepad_input_report.set_accelerator(std::abs(sin(angle)));
  gamepad_input_report.set_brake(std::abs(cos(angle)));

  button_index = (button_index % num_buttons) + 1;

  // send an input report
  auto report = gamepad_input_report.get_report();
  logger.info("Input report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

  // update the battery input report
  battery_input_report.reset();
  battery_input_report.set_rechargeable(true);
  battery_input_report.set_charging(false);
  battery_input_report.set_rechargeable(true);
  // note: it can only show 5, 40, 70, 100 so this will be rounded to 40
  battery_input_report.set_battery_level(50);

  // send a battery report
  report = battery_input_report.get_report();
  logger.info("Battery report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

Subclassed by espp::XboxGamepadInputReport< REPORT_ID >

Public Types

enum class Hat

Possible Hat switch directions.

Values:

enumerator CENTERED

Centered, no direction pressed.

enumerator UP
enumerator UP_RIGHT
enumerator RIGHT
enumerator DOWN_RIGHT
enumerator DOWN
enumerator DOWN_LEFT
enumerator LEFT
enumerator UP_LEFT

Public Functions

constexpr GamepadInputReport() = default

Construct a new Gamepad Input Report object.

inline constexpr void reset()

Reset the gamepad inputs.

inline constexpr void set_left_joystick(float lx, float ly)

Set the left joystick X and Y axis values

Parameters
  • lx – left joystick x axis value, in the range [-1, 1]

  • ly – left joystick y axis value, in the range [-1, 1]

inline constexpr void set_right_joystick(float rx, float ry)

Set the right joystick X and Y axis values

Parameters
  • rx – right joystick x axis value, in the range [-1, 1]

  • ry – right joystick y axis value, in the range [-1, 1]

inline constexpr void set_brake(float value)

Set the brake trigger value

Parameters

value – brake trigger value, in the range [0, 1]

inline constexpr void set_accelerator(float value)

Set the accelerator trigger value

Parameters

value – accelerator trigger value, in the range [0, 1]

inline constexpr void set_hat(Hat hat)

Set the hat switch (d-pad) value

Parameters

hat – Hat enum / direction to set

inline constexpr void set_button(int button_index, bool value)

Set the button value

Parameters
  • button_index – The button for which you want to set the value. Should be between 1 and BUTTON_COUNT, inclusive.

  • value – The true/false value you want to se the button to.

inline constexpr void set_joystick_axis(size_t index, JOYSTICK_TYPE value)

Set the joystick axis value

Note

The value should be in the range [joystick_min, joystick_max].

Parameters
  • index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.

  • value – The value to set the joystick axis to.

inline constexpr void set_joystick_axis(size_t index, float value)

Set the joystick axis value

Note

The value should be in the range [-1, 1].

Parameters
  • index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.

  • value – The value to set the joystick axis to.

inline constexpr void set_trigger_axis(size_t index, TRIGGER_TYPE value)

Set the trigger axis value

Note

The value should be in the range [trigger_min, trigger_max].

Parameters
  • index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.

  • value – The value to set the trigger axis to.

inline constexpr void set_trigger_axis(size_t index, float value)

Set the trigger axis value

Note

The value should be in the range [0, 1].

Parameters
  • index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.

  • value – The value to set the trigger axis to.

inline constexpr void set_hat_switch(Hat hat)

Set the hat switch value

Parameters

hat – The hat switch value to set.

inline constexpr void set_hat_switch(std::uint8_t value)

Set the hat switch value

Note

The value should match the values within the Hat enum.

Parameters

value – The hat switch value to set.

inline constexpr void set_consumer_record(bool value)

Set the consumer record button value

Parameters

value – The true/false value you want to se the consumer record button to.

inline constexpr auto get_report()

Get the input report as a vector of bytes

Note

The report id is not included in the returned vector.

Returns

The input report as a vector of bytes.

inline constexpr void set_data(const std::vector<uint8_t> &data)

Set the output report data from a vector of bytes

Parameters

data – The data to set the output report to.

Public Static Functions

static inline constexpr auto get_descriptor()

Get the report descriptor as a hid::rdf::descriptor

Note

This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.

using namespace hid::page;
using namespace hid::rdf;
auto gamepad_descriptor = gamepad_input_report.get_descriptor();
auto rdf_descriptor = descriptor(
    usage_page<generic_desktop>(),
    usage(generic_desktop::GAMEPAD),
    collection::application(
        gamepad_descriptor
    )
);
auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());

Returns

The report descriptor as a hid::rdf::descriptor.

template<size_t LED_COUNT = 4, uint8_t REPORT_ID = 2>
class GamepadLedOutputReport : public hid::report::base<hid::report::type::OUTPUT, 2>

HID Gamepad LED Output Report This class implements a HID Gamepad with a configurable number of LEDs. It supports setting the LEDs, as well as serializing the output report and getting the report descriptor.

Public Functions

inline constexpr void set_led(int led_index, bool value)

Set the LED value

Parameters
  • led_index – The LED for which you want to set the value. Should be between 1 and LED_COUNT, inclusive.

  • value – The true/false value you want to se the LED to.

inline constexpr auto get_min_led()

Get the minimum led usage

Returns

The minimum led usage

inline constexpr auto get_max_led()

Get the maximum led usage

Returns

The maximum led usage

inline constexpr bool get_led(hid::page::leds led)

Get the LED value

Parameters

led – The LED for which you want to get the value.

Returns

The true/false value of the LED.

inline constexpr bool get_led(int led_index)

Get the LED value

Parameters

led_index – The LED for which you want to get the value. Should be between 1 and LED_COUNT, inclusive.

Returns

The true/false value of the LED.

inline constexpr auto get_report()

Get the output report as a vector of bytes

Note

The report id is not included in the returned vector.

Returns

The output report as a vector of bytes.

inline constexpr void set_data(const std::vector<uint8_t> &data)

Set the output report data from a vector of bytes

Parameters

data – The data to set the output report to.

Public Static Functions

static inline constexpr auto get_descriptor()

Get the report descriptor as a hid::rdf::descriptor

Note

This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.

using namespace hid::page;
using namespace hid::rdf;
auto led_descriptor = gamepad_led_report.get_descriptor();
auto rdf_descriptor = descriptor(
    usage_page<generic_desktop>(),
    usage(generic_desktop::GAMEPAD),
    collection::application(
        led_descriptor
    )
);
auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());

Returns

The report descriptor as a hid::rdf::descriptor.

Header File

Classes

template<uint8_t REPORT_ID = 0x30>
class SwitchProGamepadInputReport : public hid::report::base<hid::report::type::INPUT, 0x30>

HID Switch Pro Gamepad Input Report

This class implements a HID Switch Pro Gamepad Input Report. It supports 15 buttons, a d-pad, 4 joystick axes and two trigger buttons. It supports setting the buttons, d-pad, joysticks, and triggers, as well as serializing the input report and getting the report descriptor.

HID-RP Example

  static constexpr uint8_t input_report_id = 1;
  static constexpr uint8_t battery_report_id = 4;
  static constexpr size_t num_buttons = 15;
  static constexpr int joystick_min = 0;
  static constexpr int joystick_max = 65535;
  static constexpr int trigger_min = 0;
  static constexpr int trigger_max = 1023;

  using GamepadInput =
      espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min,
                               joystick_max, trigger_min, trigger_max, input_report_id>;
  GamepadInput gamepad_input_report;

  using XboxInput = espp::XboxGamepadInputReport<input_report_id>;
  XboxInput xbox_input_report;

  using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>;
  BatteryReport battery_input_report;

  static constexpr uint8_t led_output_report_id = 2;
  static constexpr size_t num_leds = 4;
  using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>;
  GamepadLeds gamepad_leds_report;

  static constexpr uint8_t rumble_output_report_id = 3;
  using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>;
  RumbleReport rumble_output_report;

  using namespace hid::page;
  using namespace hid::rdf;
  auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD),
                                   collection::application(gamepad_input_report.get_descriptor(),
                                                           rumble_output_report.get_descriptor(),
                                                           battery_input_report.get_descriptor(),
                                                           gamepad_leds_report.get_descriptor()));

  // Generate the report descriptor for the gamepad
  auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end());

  logger.info("Report Descriptor:");
  logger.info("  Size: {}", descriptor.size());
  logger.info("  Data: {::#04X}", descriptor);

  using SwitchProInput = espp::SwitchProGamepadInputReport<>;
  SwitchProInput switch_pro_input_report;
  switch_pro_input_report.reset();
  logger.info("{}", switch_pro_input_report);
  logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size());
  logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report());

  auto sp_raw_descriptor = espp::switch_pro_descriptor();
  auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end());

  logger.info("Switch Report Descriptor:");
  logger.info("  Size: {}", sp_descriptor.size());
  std::string str = "";
  for (auto &byte : sp_descriptor) {
    str += fmt::format("0x{:02X}, ", byte);
  }
  logger.info("  Data: [{}]", str);

  GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT;
  int button_index = 5;
  float angle = 2.0f * M_PI * button_index / num_buttons;

  // update the gamepad input report
  gamepad_input_report.reset();
  logger.info("{}", gamepad_input_report);
  gamepad_input_report.set_hat(hat);
  gamepad_input_report.set_button(button_index, true);
  // joystick inputs are in the range [-1, 1] float
  gamepad_input_report.set_right_joystick(cos(angle), sin(angle));
  gamepad_input_report.set_left_joystick(sin(angle), cos(angle));
  // trigger inputs are in the range [0, 1] float
  gamepad_input_report.set_accelerator(std::abs(sin(angle)));
  gamepad_input_report.set_brake(std::abs(cos(angle)));

  button_index = (button_index % num_buttons) + 1;

  // send an input report
  auto report = gamepad_input_report.get_report();
  logger.info("Input report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

  // update the battery input report
  battery_input_report.reset();
  battery_input_report.set_rechargeable(true);
  battery_input_report.set_charging(false);
  battery_input_report.set_rechargeable(true);
  // note: it can only show 5, 40, 70, 100 so this will be rounded to 40
  battery_input_report.set_battery_level(50);

  // send a battery report
  report = battery_input_report.get_report();
  logger.info("Battery report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

Public Functions

constexpr SwitchProGamepadInputReport() = default

Construct a new Gamepad Input Report object.

inline constexpr void reset()

Reset the gamepad inputs.

inline constexpr void set_left_joystick(float lx, float ly)

Set the left joystick X and Y axis values

Parameters
  • lx – left joystick x axis value, in the range [-1, 1]

  • ly – left joystick y axis value, in the range [-1, 1]

inline constexpr void set_right_joystick(float rx, float ry)

Set the right joystick X and Y axis values

Parameters
  • rx – right joystick x axis value, in the range [-1, 1]

  • ry – right joystick y axis value, in the range [-1, 1]

inline constexpr void set_brake(bool pressed)

Set the brake trigger value

Parameters

pressed – Whether the brake trigger is pressed or not

inline constexpr void set_brake(float value)

Set the brake trigger value

Parameters

value – The value to set the brake trigger to. Should be in the range [0, 1].

inline constexpr void set_accelerator(bool pressed)

Set the accelerator trigger value

Parameters

pressed – Whether the accelerator trigger is pressed or not

inline constexpr void set_accelerator(float value)

Set the accelerator trigger value

Parameters

value – The value to set the accelerator trigger to. Should be in the range [0, 1].

inline constexpr void set_battery_level(float level)

Set the battery level

Parameters

level – battery level, in the range [0, 100]

inline constexpr void set_connection_info(uint8_t info)

Set the connection info

Parameters

info – connection info

inline constexpr void set_dpad(bool up, bool down, bool left, bool right)

Set the dpad value

Parameters
  • up – up dpad value

  • down – down dpad value

  • left – left dpad value

  • right – right dpad value

inline constexpr void set_button(int button_index, bool value)

Set the button value

Parameters
  • button_index – The button for which you want to set the value. Should be between 1 and 24, inclusive.

  • value – The true/false value you want to se the button to.

inline constexpr void set_trigger_axis(size_t index, float value)

Set the trigger axis value

Note

The value should be in the range [0, 1].

Parameters
  • index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.

  • value – The value to set the trigger axis to.

inline constexpr void set_trigger_axis(size_t index, bool pressed)

Set the trigger pressed value

Parameters
  • index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.

  • pressed – Whether the trigger is pressed or not

inline constexpr auto get_report()

Get the input report as a vector of bytes

Note

The report id is not included in the returned vector.

Returns

The input report as a vector of bytes.

inline constexpr void set_data(const std::vector<uint8_t> &data)

Set the output report data from a vector of bytes

Parameters

data – The data to set the output report to.

Public Static Functions

static inline constexpr auto get_descriptor()

Get the report descriptor as a hid::rdf::descriptor

Note

This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.

Returns

The report descriptor as a hid::rdf::descriptor.

Header File

Classes

template<uint8_t REPORT_ID = 1>
class XboxGamepadInputReport : public espp::GamepadInputReport<15, std::uint16_t, std::uint16_t, 0, 65535, 0, 1023, 1>

HID Xbox Gamepad Input Report

This class implements a HID Xbox Gamepad Report. It supports 15 buttons, a d-pad, 4 joystick axes, 2 trigger axes as well as consumer record button.

HID-RP Example

  static constexpr uint8_t input_report_id = 1;
  static constexpr uint8_t battery_report_id = 4;
  static constexpr size_t num_buttons = 15;
  static constexpr int joystick_min = 0;
  static constexpr int joystick_max = 65535;
  static constexpr int trigger_min = 0;
  static constexpr int trigger_max = 1023;

  using GamepadInput =
      espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min,
                               joystick_max, trigger_min, trigger_max, input_report_id>;
  GamepadInput gamepad_input_report;

  using XboxInput = espp::XboxGamepadInputReport<input_report_id>;
  XboxInput xbox_input_report;

  using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>;
  BatteryReport battery_input_report;

  static constexpr uint8_t led_output_report_id = 2;
  static constexpr size_t num_leds = 4;
  using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>;
  GamepadLeds gamepad_leds_report;

  static constexpr uint8_t rumble_output_report_id = 3;
  using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>;
  RumbleReport rumble_output_report;

  using namespace hid::page;
  using namespace hid::rdf;
  auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD),
                                   collection::application(gamepad_input_report.get_descriptor(),
                                                           rumble_output_report.get_descriptor(),
                                                           battery_input_report.get_descriptor(),
                                                           gamepad_leds_report.get_descriptor()));

  // Generate the report descriptor for the gamepad
  auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end());

  logger.info("Report Descriptor:");
  logger.info("  Size: {}", descriptor.size());
  logger.info("  Data: {::#04X}", descriptor);

  using SwitchProInput = espp::SwitchProGamepadInputReport<>;
  SwitchProInput switch_pro_input_report;
  switch_pro_input_report.reset();
  logger.info("{}", switch_pro_input_report);
  logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size());
  logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report());

  auto sp_raw_descriptor = espp::switch_pro_descriptor();
  auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end());

  logger.info("Switch Report Descriptor:");
  logger.info("  Size: {}", sp_descriptor.size());
  std::string str = "";
  for (auto &byte : sp_descriptor) {
    str += fmt::format("0x{:02X}, ", byte);
  }
  logger.info("  Data: [{}]", str);

  GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT;
  int button_index = 5;
  float angle = 2.0f * M_PI * button_index / num_buttons;

  // update the gamepad input report
  gamepad_input_report.reset();
  logger.info("{}", gamepad_input_report);
  gamepad_input_report.set_hat(hat);
  gamepad_input_report.set_button(button_index, true);
  // joystick inputs are in the range [-1, 1] float
  gamepad_input_report.set_right_joystick(cos(angle), sin(angle));
  gamepad_input_report.set_left_joystick(sin(angle), cos(angle));
  // trigger inputs are in the range [0, 1] float
  gamepad_input_report.set_accelerator(std::abs(sin(angle)));
  gamepad_input_report.set_brake(std::abs(cos(angle)));

  button_index = (button_index % num_buttons) + 1;

  // send an input report
  auto report = gamepad_input_report.get_report();
  logger.info("Input report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

  // update the battery input report
  battery_input_report.reset();
  battery_input_report.set_rechargeable(true);
  battery_input_report.set_charging(false);
  battery_input_report.set_rechargeable(true);
  // note: it can only show 5, 40, 70, 100 so this will be rounded to 40
  battery_input_report.set_battery_level(50);

  // send a battery report
  report = battery_input_report.get_report();
  logger.info("Battery report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

Public Types

enum class Hat

Possible Hat switch directions.

Values:

enumerator CENTERED

Centered, no direction pressed.

enumerator UP
enumerator UP_RIGHT
enumerator RIGHT
enumerator DOWN_RIGHT
enumerator DOWN
enumerator DOWN_LEFT
enumerator LEFT
enumerator UP_LEFT

Public Functions

inline constexpr void reset()

Reset the gamepad inputs.

inline constexpr void set_left_joystick(float lx, float ly)

Set the left joystick X and Y axis values

Parameters
  • lx – left joystick x axis value, in the range [-1, 1]

  • ly – left joystick y axis value, in the range [-1, 1]

inline constexpr void set_right_joystick(float rx, float ry)

Set the right joystick X and Y axis values

Parameters
  • rx – right joystick x axis value, in the range [-1, 1]

  • ry – right joystick y axis value, in the range [-1, 1]

inline constexpr void set_brake(float value)

Set the brake trigger value

Parameters

value – brake trigger value, in the range [0, 1]

inline constexpr void set_accelerator(float value)

Set the accelerator trigger value

Parameters

value – accelerator trigger value, in the range [0, 1]

inline constexpr void set_hat(Hat hat)

Set the hat switch (d-pad) value

Parameters

hat – Hat enum / direction to set

inline constexpr void set_button(int button_index, bool value)

Set the button value

Parameters
  • button_index – The button for which you want to set the value. Should be between 1 and BUTTON_COUNT, inclusive.

  • value – The true/false value you want to se the button to.

inline constexpr void set_joystick_axis(size_t index, JOYSTICK_TYPE value)

Set the joystick axis value

Note

The value should be in the range [joystick_min, joystick_max].

Parameters
  • index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.

  • value – The value to set the joystick axis to.

inline constexpr void set_joystick_axis(size_t index, float value)

Set the joystick axis value

Note

The value should be in the range [-1, 1].

Parameters
  • index – The index of the joystick axis to set. Should be between 0 and 3, inclusive.

  • value – The value to set the joystick axis to.

inline constexpr void set_trigger_axis(size_t index, TRIGGER_TYPE value)

Set the trigger axis value

Note

The value should be in the range [trigger_min, trigger_max].

Parameters
  • index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.

  • value – The value to set the trigger axis to.

inline constexpr void set_trigger_axis(size_t index, float value)

Set the trigger axis value

Note

The value should be in the range [0, 1].

Parameters
  • index – The index of the trigger axis to set. Should be between 0 and 1, inclusive.

  • value – The value to set the trigger axis to.

inline constexpr void set_hat_switch(Hat hat)

Set the hat switch value

Parameters

hat – The hat switch value to set.

inline constexpr void set_hat_switch(std::uint8_t value)

Set the hat switch value

Note

The value should match the values within the Hat enum.

Parameters

value – The hat switch value to set.

inline constexpr void set_consumer_record(bool value)

Set the consumer record button value

Parameters

value – The true/false value you want to se the consumer record button to.

inline constexpr auto get_report()

Get the input report as a vector of bytes

Note

The report id is not included in the returned vector.

Returns

The input report as a vector of bytes.

inline constexpr void set_data(const std::vector<uint8_t> &data)

Set the output report data from a vector of bytes

Parameters

data – The data to set the output report to.

Public Static Functions

static inline constexpr auto get_descriptor()

Get the report descriptor as a hid::rdf::descriptor

Note

This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.

using namespace hid::page;
using namespace hid::rdf;
auto gamepad_descriptor = gamepad_input_report.get_descriptor();
auto rdf_descriptor = descriptor(
    usage_page<generic_desktop>(),
    usage(generic_desktop::GAMEPAD),
    collection::application(
        gamepad_descriptor
    )
);
auto descriptor = std::vector<uint8_t>(rdf_descriptor.begin(), rdf_descriptor.end());

Returns

The report descriptor as a hid::rdf::descriptor.

template<uint8_t REPORT_ID = 3>
class XboxRumbleOutputReport : public hid::report::base<hid::report::type::OUTPUT, 3>

HID Xbox Rumble Output Report

This class implements a HID Rumble Output Report providing rumble effect on the left and right motors, as well as serializing the output report and getting the report descriptor.

Public Functions

constexpr XboxRumbleOutputReport() = default

Construct a new Xbox Rumble Output Report object.

inline constexpr void reset()

Reset the rumble effect.

inline constexpr auto get_enabled()

Get the enabled mask for the rumble motors

Returns

The enabled mask for the rumble motors

inline constexpr void set_enabled(std::uint8_t new_enabled)

Set the enabled mask for the rumble motors

Parameters

enabled – The enabled mask for the rumble motors

inline constexpr auto get_magnitude(std::size_t motor)

Get the magnitude of the rumble effect for the specified motor

Parameters

motor – The motor for which you want to get the magnitude.

Returns

The magnitude of the rumble effect for the specified motor.

inline constexpr void set_magnitude(std::size_t motor, std::uint8_t value)

Set the magnitude of the rumble effect for the specified motor

Note

The value should be in the range [0, 100].

Parameters
  • motor – The motor for which you want to set the magnitude.

  • value – The magnitude of the rumble effect for the specified motor.

inline constexpr void set_magnitude(std::size_t motor, float value)

Set the magnitude of the rumble effect for the specified motor

Note

The value should be in the range [0, 1].

Parameters
  • motor – The motor for which you want to set the magnitude.

  • value – The magnitude of the rumble effect for the specified motor.

inline constexpr auto get_duration()

Get the duration of the rumble effect

Returns

The duration of the rumble effect

inline constexpr void set_duration(std::uint8_t value)

Set the duration of the rumble effect

Note

The value should be in the range [0, 255].

Parameters

value – The duration of the rumble effect.

inline constexpr auto get_start_delay()

Get the start delay of the rumble effect

Returns

The start delay of the rumble effect

inline constexpr void set_start_delay(std::uint8_t value)

Set the start delay of the rumble effect

Note

The value should be in the range [0, 255].

Parameters

value – The start delay of the rumble effect.

inline constexpr auto get_loop_count()

Get the loop count of the rumble effect

Returns

The loop count of the rumble effect

inline constexpr void set_loop_count(std::uint8_t value)

Set the loop count of the rumble effect

Note

The value should be in the range [0, 255].

Parameters

value – The loop count of the rumble effect.

inline constexpr auto get_report()

Get the output report as a vector of bytes

Note

The report id is not included in the returned vector.

Returns

The output report as a vector of bytes.

inline constexpr void set_data(const std::vector<uint8_t> &data)

Set the output report data from a vector of bytes

Parameters

data – The data to set the output report to.

Public Static Functions

static inline constexpr auto get_descriptor()

Get the report descriptor as a hid::rdf::descriptor

Note

This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.

Returns

The report descriptor as a hid::rdf::descriptor.

template<uint8_t REPORT_ID = 4>
class XboxBatteryInputReport : public hid::report::base<hid::report::type::INPUT, 4>

HID Xbox Battery Input Report This class implements a copy of the Xbox Battery input report. It is a single byte input which contains information about the type of the battery, its battery level, as well as a few other things.

HID-RP Example

  static constexpr uint8_t input_report_id = 1;
  static constexpr uint8_t battery_report_id = 4;
  static constexpr size_t num_buttons = 15;
  static constexpr int joystick_min = 0;
  static constexpr int joystick_max = 65535;
  static constexpr int trigger_min = 0;
  static constexpr int trigger_max = 1023;

  using GamepadInput =
      espp::GamepadInputReport<num_buttons, std::uint16_t, std::uint16_t, joystick_min,
                               joystick_max, trigger_min, trigger_max, input_report_id>;
  GamepadInput gamepad_input_report;

  using XboxInput = espp::XboxGamepadInputReport<input_report_id>;
  XboxInput xbox_input_report;

  using BatteryReport = espp::XboxBatteryInputReport<battery_report_id>;
  BatteryReport battery_input_report;

  static constexpr uint8_t led_output_report_id = 2;
  static constexpr size_t num_leds = 4;
  using GamepadLeds = espp::GamepadLedOutputReport<num_leds, led_output_report_id>;
  GamepadLeds gamepad_leds_report;

  static constexpr uint8_t rumble_output_report_id = 3;
  using RumbleReport = espp::XboxRumbleOutputReport<rumble_output_report_id>;
  RumbleReport rumble_output_report;

  using namespace hid::page;
  using namespace hid::rdf;
  auto raw_descriptor = descriptor(usage_page<generic_desktop>(), usage(generic_desktop::GAMEPAD),
                                   collection::application(gamepad_input_report.get_descriptor(),
                                                           rumble_output_report.get_descriptor(),
                                                           battery_input_report.get_descriptor(),
                                                           gamepad_leds_report.get_descriptor()));

  // Generate the report descriptor for the gamepad
  auto descriptor = std::vector<uint8_t>(raw_descriptor.begin(), raw_descriptor.end());

  logger.info("Report Descriptor:");
  logger.info("  Size: {}", descriptor.size());
  logger.info("  Data: {::#04X}", descriptor);

  using SwitchProInput = espp::SwitchProGamepadInputReport<>;
  SwitchProInput switch_pro_input_report;
  switch_pro_input_report.reset();
  logger.info("{}", switch_pro_input_report);
  logger.info("Switch Pro Input Report Size: {}", switch_pro_input_report.get_report().size());
  logger.info("Switch Pro Input Report Data: {::#04X}", switch_pro_input_report.get_report());

  auto sp_raw_descriptor = espp::switch_pro_descriptor();
  auto sp_descriptor = std::vector<uint8_t>(sp_raw_descriptor.begin(), sp_raw_descriptor.end());

  logger.info("Switch Report Descriptor:");
  logger.info("  Size: {}", sp_descriptor.size());
  std::string str = "";
  for (auto &byte : sp_descriptor) {
    str += fmt::format("0x{:02X}, ", byte);
  }
  logger.info("  Data: [{}]", str);

  GamepadInput::Hat hat = GamepadInput::Hat::UP_RIGHT;
  int button_index = 5;
  float angle = 2.0f * M_PI * button_index / num_buttons;

  // update the gamepad input report
  gamepad_input_report.reset();
  logger.info("{}", gamepad_input_report);
  gamepad_input_report.set_hat(hat);
  gamepad_input_report.set_button(button_index, true);
  // joystick inputs are in the range [-1, 1] float
  gamepad_input_report.set_right_joystick(cos(angle), sin(angle));
  gamepad_input_report.set_left_joystick(sin(angle), cos(angle));
  // trigger inputs are in the range [0, 1] float
  gamepad_input_report.set_accelerator(std::abs(sin(angle)));
  gamepad_input_report.set_brake(std::abs(cos(angle)));

  button_index = (button_index % num_buttons) + 1;

  // send an input report
  auto report = gamepad_input_report.get_report();
  logger.info("Input report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

  // update the battery input report
  battery_input_report.reset();
  battery_input_report.set_rechargeable(true);
  battery_input_report.set_charging(false);
  battery_input_report.set_rechargeable(true);
  // note: it can only show 5, 40, 70, 100 so this will be rounded to 40
  battery_input_report.set_battery_level(50);

  // send a battery report
  report = battery_input_report.get_report();
  logger.info("Battery report:");
  logger.info("  Size: {}", report.size());
  logger.info("  Data: {::#02X}", report);

Public Types

enum class Error

The possible errors for the battery.

Values:

enumerator NONE

No error.

enumerator BATTERY_LOW

The battery is low.

enumerator BATTERY_CRITICAL

The battery is critically low.

Public Functions

inline constexpr void reset()

Reset the battery status.

inline constexpr void set_rechargeable(bool rechargeable)

Set whether the battery is rechargeable

Parameters

rechargeable – True if the battery is rechargeable, false otherwise.

inline constexpr void set_battery_level(int level)

Set the battery level

Parameters

level – The battery level as a percentage, from 0 to 100.

inline constexpr void set_cable_connected(bool connected)

Set whether the battery is connected to a cable

Parameters

connected – True if the battery is connected to a cable, false otherwise.

inline constexpr void set_charging(bool charging)

Set whether the battery is charging

Parameters

charging – True if the battery is charging, false otherwise.

inline constexpr void set_error(Error error)

Set the error state of the battery

Parameters

error – The error state of the battery.

inline constexpr auto get_report()

Get the input report as a vector of bytes

Note

The report id is not included in the returned vector.

Returns

The input report as a vector of bytes.

Public Static Functions

static inline constexpr auto get_descriptor()

Get the report descriptor as a hid::rdf::descriptor

Note

This is an incomplete descriptor, you will need to add it to a collection::application descriptor to create a complete report descriptor.

Returns

The report descriptor as a hid::rdf::descriptor.