Fix XInput send_report + cleanup esp32 i2c logic
This commit is contained in:
4
Firmware/ESP32/.vscode/settings.json
vendored
4
Firmware/ESP32/.vscode/settings.json
vendored
@@ -100,5 +100,7 @@
|
||||
},
|
||||
"idf.portWin": "COM26",
|
||||
"idf.flashType": "UART",
|
||||
"C_Cpp.intelliSenseEngine": "default"
|
||||
"C_Cpp.intelliSenseEngine": "default",
|
||||
"idf.espIdfPathWin": "C:\\Programming\\esp\\v5.1\\esp-idf",
|
||||
"idf.toolsPathWin": "C:\\Programming\\.espressif"
|
||||
}
|
||||
@@ -4,9 +4,11 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(EXTERNAL_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../external)
|
||||
|
||||
include(${EXTERNAL_DIR}/init_submodules.cmake)
|
||||
include(${EXTERNAL_DIR}/patch_libs.cmake)
|
||||
include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/integrate_btstack.cmake)
|
||||
|
||||
init_git_submodules(${EXTERNAL_DIR})
|
||||
apply_lib_patches(${EXTERNAL_DIR})
|
||||
integrate_btstack(${EXTERNAL_DIR})
|
||||
|
||||
|
||||
@@ -45,6 +45,7 @@ static inline void send_feedback_cb(void* context)
|
||||
}
|
||||
}
|
||||
|
||||
//This will have to be changed once full support for multiple devices is added
|
||||
static inline void feedback_timer_cb(btstack_timer_source *ts)
|
||||
{
|
||||
static btstack_context_callback_registration_t cb_registration[MAX_DEVICES];
|
||||
@@ -63,18 +64,13 @@ static inline void feedback_timer_cb(btstack_timer_source *ts)
|
||||
cb_registration[i].callback = send_feedback_cb;
|
||||
cb_registration[i].context = reinterpret_cast<void*>(&packets_out[i]);
|
||||
|
||||
//Get i2c rumble packet then register callback on BTStack thread
|
||||
i2c_driver_.push_task([i]
|
||||
{
|
||||
I2CDriver::PacketOut packet_out;
|
||||
if (i2c_driver_.i2c_read_blocking( I2CDriver::MULTI_SLAVE ? i + 1 : 0x01,
|
||||
reinterpret_cast<uint8_t*>(&packet_out),
|
||||
sizeof(I2CDriver::PacketOut)) == ESP_OK)
|
||||
{
|
||||
packets_out[i].store(packet_out);
|
||||
btstack_run_loop_execute_on_main_thread(&cb_registration[i]);
|
||||
}
|
||||
});
|
||||
//Register a read on i2c thread, with callback to send feedback on btstack thread
|
||||
i2c_driver_.i2c_read_blocking_safe( I2CDriver::MULTI_SLAVE ? i + 1 : 0x01,
|
||||
[i](const I2CDriver::PacketOut& packet_out)
|
||||
{
|
||||
packets_out[i].store(packet_out);
|
||||
btstack_run_loop_execute_on_main_thread(&cb_registration[i]);
|
||||
});
|
||||
}
|
||||
|
||||
btstack_run_loop_set_timer(ts, FEEDBACK_TIME_MS);
|
||||
@@ -160,12 +156,7 @@ void device_disconnected_cb(uni_hid_device_t* device)
|
||||
I2CDriver::PacketIn packet_in = I2CDriver::PacketIn();
|
||||
packet_in.index = static_cast<uint8_t>(idx);
|
||||
|
||||
i2c_driver_.push_task([packet_in]
|
||||
{
|
||||
i2c_driver_.i2c_write_blocking( I2CDriver::MULTI_SLAVE ? packet_in.index + 1 : 0x01,
|
||||
reinterpret_cast<const uint8_t*>(&packet_in),
|
||||
sizeof(I2CDriver::PacketIn));
|
||||
});
|
||||
i2c_driver_.i2c_write_blocking_safe(I2CDriver::MULTI_SLAVE ? packet_in.index + 1 : 0x01, packet_in);
|
||||
}
|
||||
|
||||
static uni_error_t device_ready_cb(uni_hid_device_t* device)
|
||||
@@ -258,12 +249,7 @@ static inline void controller_data_cb(uni_hid_device_t* device, uni_controller_t
|
||||
packet_in.joystick_rx = Scale::int10_to_int16(uni_gp->axis_rx);
|
||||
packet_in.joystick_ry = Scale::int10_to_int16(uni_gp->axis_ry);
|
||||
|
||||
i2c_driver_.push_task([packet_in]
|
||||
{
|
||||
i2c_driver_.i2c_write_blocking( I2CDriver::MULTI_SLAVE ? packet_in.index + 1 : 0x01,
|
||||
reinterpret_cast<const uint8_t*>(&packet_in),
|
||||
sizeof(I2CDriver::PacketIn));
|
||||
});
|
||||
i2c_driver_.i2c_write_blocking_safe(I2CDriver::MULTI_SLAVE ? packet_in.index + 1 : 0x01, packet_in);
|
||||
|
||||
std::memcpy(&prev_uni_gps[idx], uni_gp, sizeof(uni_gamepad_t));
|
||||
}
|
||||
@@ -296,6 +282,12 @@ uni_platform* get_driver()
|
||||
return &driver;
|
||||
}
|
||||
|
||||
void run_i2c_task(void* parameter)
|
||||
{
|
||||
i2c_driver_.initialize_i2c();
|
||||
i2c_driver_.run_tasks();
|
||||
}
|
||||
|
||||
//Public
|
||||
|
||||
bool any_connected()
|
||||
@@ -319,10 +311,8 @@ void run_task()
|
||||
{
|
||||
board_api::init_pins();
|
||||
|
||||
i2c_driver_.initialize_i2c();
|
||||
|
||||
xTaskCreatePinnedToCore(
|
||||
i2c_driver_.run_tasks,
|
||||
run_i2c_task,
|
||||
"i2c",
|
||||
2048 * 2,
|
||||
nullptr,
|
||||
|
||||
@@ -7,8 +7,6 @@
|
||||
#include "I2CDriver/I2CDriver.h"
|
||||
#include "Bluepad32/Bluepad32.h"
|
||||
|
||||
I2CDriver::TaskQueue I2CDriver::task_queue_;
|
||||
|
||||
I2CDriver::~I2CDriver()
|
||||
{
|
||||
i2c_driver_delete(I2C_NUM_0);
|
||||
@@ -30,7 +28,7 @@ void I2CDriver::initialize_i2c()
|
||||
i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0);
|
||||
}
|
||||
|
||||
void I2CDriver::run_tasks(void* parameter)
|
||||
void I2CDriver::run_tasks()
|
||||
{
|
||||
std::function<void()> task;
|
||||
|
||||
|
||||
@@ -70,15 +70,32 @@ public:
|
||||
void initialize_i2c();
|
||||
|
||||
//Does not return
|
||||
static void run_tasks(void* parameter);
|
||||
void run_tasks();
|
||||
|
||||
//Thread safe
|
||||
inline void push_task(std::function<void()> task)
|
||||
{
|
||||
task_queue_.push(task);
|
||||
inline void i2c_write_blocking_safe(uint8_t address, const PacketIn& packet_in)
|
||||
{
|
||||
task_queue_.push([this, address, packet_in]()
|
||||
{
|
||||
i2c_write_blocking(address, reinterpret_cast<const uint8_t*>(&packet_in), sizeof(PacketIn));
|
||||
});
|
||||
}
|
||||
|
||||
//Don't call directly from another thread, use in push_task
|
||||
inline void i2c_read_blocking_safe(uint8_t address, std::function<void(const PacketOut&)> callback)
|
||||
{
|
||||
task_queue_.push([this, address, callback]()
|
||||
{
|
||||
PacketOut packet_out;
|
||||
if (i2c_read_blocking(address, reinterpret_cast<uint8_t*>(&packet_out), sizeof(PacketOut)) == ESP_OK)
|
||||
{
|
||||
callback(packet_out);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private:
|
||||
using TaskQueue = RingBuffer<std::function<void()>, 6>;
|
||||
TaskQueue task_queue_;
|
||||
|
||||
inline esp_err_t i2c_write_blocking(uint8_t address, const uint8_t* buffer, size_t len)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
@@ -92,7 +109,6 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Don't call directly from another thread, use in push_task
|
||||
inline esp_err_t i2c_read_blocking(uint8_t address, uint8_t* buffer, size_t len)
|
||||
{
|
||||
i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
@@ -111,10 +127,6 @@ public:
|
||||
i2c_cmd_link_delete(cmd);
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
using TaskQueue = RingBuffer<std::function<void()>, 6>;
|
||||
static TaskQueue task_queue_;
|
||||
};
|
||||
|
||||
#endif // _I2C_DRIVER_H_
|
||||
@@ -1,6 +1,6 @@
|
||||
#
|
||||
# Automatically generated file. DO NOT EDIT.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Configuration
|
||||
# Espressif IoT Development Framework (ESP-IDF) 5.1.5 Project Configuration
|
||||
#
|
||||
CONFIG_SOC_BROWNOUT_RESET_SUPPORTED="Not determined"
|
||||
CONFIG_SOC_TWAI_BRP_DIV_SUPPORTED="Not determined"
|
||||
|
||||
2
Firmware/RP2040/.vscode/settings.json
vendored
2
Firmware/RP2040/.vscode/settings.json
vendored
@@ -7,7 +7,7 @@
|
||||
"PICO_SDK_PATH": "C:/Programming/pico-sdk"
|
||||
},
|
||||
"cmake.configureArgs": [
|
||||
"-DOGXM_BOARD=PI_PICO",
|
||||
"-DOGXM_BOARD=W_ESP32",
|
||||
"-DMAX_GAMEPADS=1"
|
||||
],
|
||||
"files.associations": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
|
||||
set(FW_NAME "OGX-Mini")
|
||||
set(FW_VERSION "v1.0.0a")
|
||||
set(FW_VERSION "v1.0.0a2")
|
||||
|
||||
set(CMAKE_C_COMPILER arm-none-eabi-gcc)
|
||||
set(CMAKE_CXX_COMPILER arm-none-eabi-g++)
|
||||
@@ -13,9 +13,11 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||
set(SRC ${CMAKE_CURRENT_LIST_DIR}/src)
|
||||
set(EXTERNAL_DIR ${CMAKE_CURRENT_LIST_DIR}/../external)
|
||||
|
||||
include(${EXTERNAL_DIR}/init_submodules.cmake)
|
||||
include(${EXTERNAL_DIR}/patch_libs.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/cmake/get_pico_sdk.cmake)
|
||||
|
||||
init_git_submodules(${EXTERNAL_DIR})
|
||||
apply_lib_patches(${EXTERNAL_DIR})
|
||||
get_pico_sdk(${EXTERNAL_DIR})
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include "Board/board_api.h"
|
||||
|
||||
#ifndef CONFIG_BLUEPAD32_PLATFORM_CUSTOM
|
||||
#error "Pico W must use BLUEPAD32_PLATFORM_CUSTOM"
|
||||
#error "Pico W must use BLUEPAD32_PLATFORM_CUSTOM"
|
||||
#endif
|
||||
|
||||
static_assert((CONFIG_BLUEPAD32_MAX_DEVICES == MAX_GAMEPADS), "Mismatch between BP32 and Gamepad max devices");
|
||||
@@ -124,7 +124,14 @@ static void check_led_cb(btstack_timer_source *ts)
|
||||
|
||||
static void init(int argc, const char** arg_V)
|
||||
{
|
||||
|
||||
if (!led_timer_set_)
|
||||
{
|
||||
led_timer_set_ = true;
|
||||
led_timer_.process = check_led_cb;
|
||||
led_timer_.context = nullptr;
|
||||
btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS);
|
||||
btstack_run_loop_add_timer(&led_timer_);
|
||||
}
|
||||
}
|
||||
|
||||
static void init_complete_cb(void)
|
||||
@@ -310,12 +317,6 @@ void run_task(Gamepad (&gamepads)[MAX_GAMEPADS])
|
||||
uni_platform_set_custom(get_driver());
|
||||
uni_init(0, nullptr);
|
||||
|
||||
led_timer_set_ = true;
|
||||
led_timer_.process = check_led_cb;
|
||||
led_timer_.context = nullptr;
|
||||
btstack_run_loop_set_timer(&led_timer_, LED_CHECK_TIME_MS);
|
||||
btstack_run_loop_add_timer(&led_timer_);
|
||||
|
||||
btstack_run_loop_execute();
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "Gamepad.h"
|
||||
#include "board_config.h"
|
||||
#include "UserSettings/UserProfile.h"
|
||||
|
||||
/* NOTE: Everything bluepad32/uni needs to be wrapped
|
||||
and kept away from tinyusb due to naming conflicts */
|
||||
|
||||
@@ -191,9 +191,12 @@ void init_board()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!set_sys_clock_khz(SYSCLOCK_KHZ, true) && !set_sys_clock_khz(120000, true))
|
||||
if (!set_sys_clock_khz(SYSCLOCK_KHZ, true))
|
||||
{
|
||||
panic("Failed to set sys clock");
|
||||
if (!set_sys_clock_khz((SYSCLOCK_KHZ / 2), true))
|
||||
{
|
||||
panic("Failed to set sys clock");
|
||||
}
|
||||
}
|
||||
|
||||
stdio_init_all();
|
||||
@@ -216,7 +219,7 @@ void init_board()
|
||||
|
||||
mutex_exit(&gpio_mutex_);
|
||||
|
||||
#if (OGXM_BOARD != PI_PICOW)
|
||||
#if (OGXM_BOARD != PI_PICOW) // cyw43_arch needs to be inited from core1 first
|
||||
set_led(false);
|
||||
#endif
|
||||
|
||||
|
||||
@@ -108,15 +108,26 @@ namespace XInput
|
||||
int16_t joystick_rx;
|
||||
int16_t joystick_ry;
|
||||
uint8_t reserved[6];
|
||||
|
||||
InReport()
|
||||
{
|
||||
std::memset(this, 0, sizeof(InReport));
|
||||
report_size = sizeof(InReport);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(InReport) == 20, "XInput::InReport is not the correct size");
|
||||
static_assert(sizeof(InReport) == 20, "XInput::InReport is misaligned");
|
||||
|
||||
struct WiredChatpadReport
|
||||
{
|
||||
uint8_t report_id;
|
||||
uint8_t chatpad[3];
|
||||
|
||||
WiredChatpadReport()
|
||||
{
|
||||
std::memset(this, 0, sizeof(WiredChatpadReport));
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(WiredChatpadReport) == 4, "XInput::WiredChatpadReport is not the correct size");
|
||||
static_assert(sizeof(WiredChatpadReport) == 4, "XInput::WiredChatpadReport is misaligned");
|
||||
|
||||
struct InReportWireless
|
||||
{
|
||||
@@ -137,9 +148,10 @@ namespace XInput
|
||||
InReportWireless()
|
||||
{
|
||||
std::memset(this, 0, sizeof(InReportWireless));
|
||||
report_size = sizeof(InReportWireless);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(InReportWireless) == 28, "XInput::InReportWireless is not the correct size");
|
||||
static_assert(sizeof(InReportWireless) == 28, "XInput::InReportWireless is misaligned");
|
||||
|
||||
struct OutReport
|
||||
{
|
||||
@@ -149,8 +161,13 @@ namespace XInput
|
||||
uint8_t rumble_l;
|
||||
uint8_t rumble_r;
|
||||
uint8_t reserved[3];
|
||||
|
||||
OutReport()
|
||||
{
|
||||
std::memset(this, 0, sizeof(OutReport));
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(OutReport) == 8, "XInput::OutReport is not the correct size");
|
||||
static_assert(sizeof(OutReport) == 8, "XInput::OutReport is misaligned");
|
||||
#pragma pack(pop)
|
||||
|
||||
static const uint8_t STRING_LANGUAGE[] = { 0x09, 0x04 };
|
||||
@@ -158,7 +175,7 @@ namespace XInput
|
||||
static const uint8_t STRING_PRODUCT[] = "XInput STANDARD GAMEPAD";
|
||||
static const uint8_t STRING_VERSION[] = "1.0";
|
||||
|
||||
static const uint8_t *STRING_DESCRIPTORS[] __attribute__((unused)) =
|
||||
static const uint8_t *DESC_STRING[] __attribute__((unused)) =
|
||||
{
|
||||
STRING_LANGUAGE,
|
||||
STRING_MANUFACTURER,
|
||||
@@ -166,7 +183,7 @@ namespace XInput
|
||||
STRING_VERSION
|
||||
};
|
||||
|
||||
static const uint8_t DEVICE_DESCRIPTORS[] =
|
||||
static const uint8_t DESC_DEVICE[] =
|
||||
{
|
||||
0x12, // bLength
|
||||
0x01, // bDescriptorType (Device)
|
||||
@@ -184,7 +201,7 @@ namespace XInput
|
||||
0x01, // bNumConfigurations 1
|
||||
};
|
||||
|
||||
static const uint8_t CONFIGURATION_DESCRIPTORS[] =
|
||||
static const uint8_t DESC_CONFIGURATION[] =
|
||||
{
|
||||
0x09, // bLength
|
||||
0x02, // bDescriptorType (Configuration)
|
||||
|
||||
@@ -129,7 +129,6 @@ public:
|
||||
reset_pad_in();
|
||||
reset_pad_out();
|
||||
reset_chatpad_in();
|
||||
setup_deadzones();
|
||||
};
|
||||
|
||||
~Gamepad() = default;
|
||||
@@ -143,10 +142,8 @@ public:
|
||||
|
||||
inline PadIn get_pad_in()
|
||||
{
|
||||
PadIn pad_in;
|
||||
|
||||
mutex_enter_blocking(&pad_in_mutex_);
|
||||
pad_in = pad_in_;
|
||||
PadIn pad_in = pad_in_;
|
||||
new_pad_in_.store(false);
|
||||
mutex_exit(&pad_in_mutex_);
|
||||
|
||||
@@ -155,10 +152,8 @@ public:
|
||||
|
||||
inline PadOut get_pad_out()
|
||||
{
|
||||
PadOut pad_out;
|
||||
|
||||
mutex_enter_blocking(&pad_out_mutex_);
|
||||
pad_out = pad_out_;
|
||||
PadOut pad_out = pad_out_;
|
||||
new_pad_out_.store(false);
|
||||
mutex_exit(&pad_out_mutex_);
|
||||
|
||||
@@ -167,10 +162,8 @@ public:
|
||||
|
||||
inline ChatpadIn get_chatpad_in()
|
||||
{
|
||||
ChatpadIn chatpad_in;
|
||||
|
||||
mutex_enter_blocking(&chatpad_in_mutex_);
|
||||
chatpad_in = chatpad_in_;
|
||||
ChatpadIn chatpad_in = chatpad_in_;
|
||||
mutex_exit(&chatpad_in_mutex_);
|
||||
|
||||
return chatpad_in;
|
||||
@@ -181,7 +174,7 @@ public:
|
||||
void set_analog_device(bool value)
|
||||
{
|
||||
analog_device_.store(value);
|
||||
if (analog_host_.load() && analog_device_.load() && profile_.analog_enabled)
|
||||
if (analog_host_.load() && analog_device_.load() && profile_analog_enabled_)
|
||||
{
|
||||
analog_enabled_.store(true);
|
||||
}
|
||||
@@ -190,7 +183,7 @@ public:
|
||||
void set_analog_host(bool value)
|
||||
{
|
||||
analog_host_.store(value);
|
||||
if (analog_host_.load() && analog_device_.load() && profile_.analog_enabled)
|
||||
if (analog_host_.load() && analog_device_.load() && profile_analog_enabled_)
|
||||
{
|
||||
analog_enabled_.store(true);
|
||||
}
|
||||
@@ -198,9 +191,9 @@ public:
|
||||
|
||||
void set_profile(const UserProfile& user_profile)
|
||||
{
|
||||
profile_ = user_profile;
|
||||
setup_mappings();
|
||||
setup_deadzones();
|
||||
set_profile_options(user_profile);
|
||||
set_profile_mappings(user_profile);
|
||||
set_profile_deadzones(user_profile);
|
||||
}
|
||||
|
||||
inline void set_pad_in(PadIn pad_in)
|
||||
@@ -211,8 +204,8 @@ public:
|
||||
pad_in.joystick_ly = (pad_in.joystick_ly < dz_.joystick_l_neg || pad_in.joystick_ly > dz_.joystick_l_pos) ? pad_in.joystick_ly : INT_16::MID;
|
||||
pad_in.joystick_rx = (pad_in.joystick_rx < dz_.joystick_r_neg || pad_in.joystick_rx > dz_.joystick_r_pos) ? pad_in.joystick_rx : INT_16::MID;
|
||||
pad_in.joystick_ry = (pad_in.joystick_ry < dz_.joystick_r_neg || pad_in.joystick_ry > dz_.joystick_r_pos) ? pad_in.joystick_ry : INT_16::MID;
|
||||
pad_in.joystick_ly = profile_.invert_ly ? Scale::invert_joy(pad_in.joystick_ly) : pad_in.joystick_ly;
|
||||
pad_in.joystick_ry = profile_.invert_ry ? Scale::invert_joy(pad_in.joystick_ry) : pad_in.joystick_ry;
|
||||
pad_in.joystick_ly = profile_invert_ly_ ? Scale::invert_joy(pad_in.joystick_ly) : pad_in.joystick_ly;
|
||||
pad_in.joystick_ry = profile_invert_ry_ ? Scale::invert_joy(pad_in.joystick_ry) : pad_in.joystick_ry;
|
||||
|
||||
mutex_enter_blocking(&pad_in_mutex_);
|
||||
pad_in_ = pad_in;
|
||||
@@ -238,7 +231,7 @@ public:
|
||||
inline void reset_pad_in()
|
||||
{
|
||||
mutex_enter_blocking(&pad_in_mutex_);
|
||||
std::memset(reinterpret_cast<void*>(&pad_in_), 0, sizeof(pad_in_));
|
||||
pad_in_ = PadIn();
|
||||
mutex_exit(&pad_in_mutex_);
|
||||
new_pad_in_.store(true);
|
||||
}
|
||||
@@ -246,7 +239,7 @@ public:
|
||||
inline void reset_pad_out()
|
||||
{
|
||||
mutex_enter_blocking(&pad_out_mutex_);
|
||||
std::memset(reinterpret_cast<void*>(&pad_out_), 0, sizeof(pad_out_));
|
||||
pad_out_ = PadOut();
|
||||
new_pad_out_.store(true);
|
||||
mutex_exit(&pad_out_mutex_);
|
||||
}
|
||||
@@ -274,7 +267,9 @@ private:
|
||||
std::atomic<bool> analog_host_{false};
|
||||
std::atomic<bool> analog_device_{false};
|
||||
|
||||
UserProfile profile_;
|
||||
bool profile_invert_ly_{false};
|
||||
bool profile_invert_ry_{false};
|
||||
bool profile_analog_enabled_{false};
|
||||
|
||||
struct Deadzones
|
||||
{
|
||||
@@ -286,51 +281,58 @@ private:
|
||||
int16_t joystick_r_pos{0};
|
||||
} dz_;
|
||||
|
||||
void setup_mappings()
|
||||
void set_profile_options(const UserProfile& profile)
|
||||
{
|
||||
MAP_DPAD_UP = profile_.dpad_up;
|
||||
MAP_DPAD_DOWN = profile_.dpad_down;
|
||||
MAP_DPAD_LEFT = profile_.dpad_left;
|
||||
MAP_DPAD_RIGHT = profile_.dpad_right;
|
||||
MAP_DPAD_UP_LEFT = profile_.dpad_up | profile_.dpad_left;
|
||||
MAP_DPAD_UP_RIGHT = profile_.dpad_up | profile_.dpad_right;
|
||||
MAP_DPAD_DOWN_LEFT = profile_.dpad_down | profile_.dpad_left;
|
||||
MAP_DPAD_DOWN_RIGHT = profile_.dpad_down | profile_.dpad_right;
|
||||
MAP_DPAD_NONE = 0;
|
||||
|
||||
MAP_BUTTON_A = profile_.button_a;
|
||||
MAP_BUTTON_B = profile_.button_b;
|
||||
MAP_BUTTON_X = profile_.button_x;
|
||||
MAP_BUTTON_Y = profile_.button_y;
|
||||
MAP_BUTTON_L3 = profile_.button_l3;
|
||||
MAP_BUTTON_R3 = profile_.button_r3;
|
||||
MAP_BUTTON_BACK = profile_.button_back;
|
||||
MAP_BUTTON_START = profile_.button_start;
|
||||
MAP_BUTTON_LB = profile_.button_lb;
|
||||
MAP_BUTTON_RB = profile_.button_rb;
|
||||
MAP_BUTTON_SYS = profile_.button_sys;
|
||||
MAP_BUTTON_MISC = profile_.button_misc;
|
||||
|
||||
MAP_ANALOG_OFF_UP = profile_.analog_off_up;
|
||||
MAP_ANALOG_OFF_DOWN = profile_.analog_off_down;
|
||||
MAP_ANALOG_OFF_LEFT = profile_.analog_off_left;
|
||||
MAP_ANALOG_OFF_RIGHT = profile_.analog_off_right;
|
||||
MAP_ANALOG_OFF_A = profile_.analog_off_a;
|
||||
MAP_ANALOG_OFF_B = profile_.analog_off_b;
|
||||
MAP_ANALOG_OFF_X = profile_.analog_off_x;
|
||||
MAP_ANALOG_OFF_Y = profile_.analog_off_y;
|
||||
MAP_ANALOG_OFF_LB = profile_.analog_off_lb;
|
||||
MAP_ANALOG_OFF_RB = profile_.analog_off_rb;
|
||||
profile_invert_ly_ = profile.invert_ly ? true : false;
|
||||
profile_invert_ry_ = profile.invert_ry ? true : false;
|
||||
profile_analog_enabled_ = profile.analog_enabled ? true : false;
|
||||
}
|
||||
|
||||
void setup_deadzones() //Deadzones in the profile are 0-255 (0-100%)
|
||||
void set_profile_mappings(const UserProfile& profile)
|
||||
{
|
||||
dz_.trigger_l = profile_.dz_trigger_l;
|
||||
dz_.trigger_r = profile_.dz_trigger_r;
|
||||
MAP_DPAD_UP = profile.dpad_up;
|
||||
MAP_DPAD_DOWN = profile.dpad_down;
|
||||
MAP_DPAD_LEFT = profile.dpad_left;
|
||||
MAP_DPAD_RIGHT = profile.dpad_right;
|
||||
MAP_DPAD_UP_LEFT = profile.dpad_up | profile.dpad_left;
|
||||
MAP_DPAD_UP_RIGHT = profile.dpad_up | profile.dpad_right;
|
||||
MAP_DPAD_DOWN_LEFT = profile.dpad_down | profile.dpad_left;
|
||||
MAP_DPAD_DOWN_RIGHT = profile.dpad_down | profile.dpad_right;
|
||||
MAP_DPAD_NONE = 0;
|
||||
|
||||
dz_.joystick_l_pos = Scale::uint8_to_int16(profile_.dz_joystick_l / 2);
|
||||
MAP_BUTTON_A = profile.button_a;
|
||||
MAP_BUTTON_B = profile.button_b;
|
||||
MAP_BUTTON_X = profile.button_x;
|
||||
MAP_BUTTON_Y = profile.button_y;
|
||||
MAP_BUTTON_L3 = profile.button_l3;
|
||||
MAP_BUTTON_R3 = profile.button_r3;
|
||||
MAP_BUTTON_BACK = profile.button_back;
|
||||
MAP_BUTTON_START = profile.button_start;
|
||||
MAP_BUTTON_LB = profile.button_lb;
|
||||
MAP_BUTTON_RB = profile.button_rb;
|
||||
MAP_BUTTON_SYS = profile.button_sys;
|
||||
MAP_BUTTON_MISC = profile.button_misc;
|
||||
|
||||
MAP_ANALOG_OFF_UP = profile.analog_off_up;
|
||||
MAP_ANALOG_OFF_DOWN = profile.analog_off_down;
|
||||
MAP_ANALOG_OFF_LEFT = profile.analog_off_left;
|
||||
MAP_ANALOG_OFF_RIGHT = profile.analog_off_right;
|
||||
MAP_ANALOG_OFF_A = profile.analog_off_a;
|
||||
MAP_ANALOG_OFF_B = profile.analog_off_b;
|
||||
MAP_ANALOG_OFF_X = profile.analog_off_x;
|
||||
MAP_ANALOG_OFF_Y = profile.analog_off_y;
|
||||
MAP_ANALOG_OFF_LB = profile.analog_off_lb;
|
||||
MAP_ANALOG_OFF_RB = profile.analog_off_rb;
|
||||
}
|
||||
|
||||
void set_profile_deadzones(const UserProfile& profile) //Deadzones in the profile are 0-255 (0-100%)
|
||||
{
|
||||
dz_.trigger_l = profile.dz_trigger_l;
|
||||
dz_.trigger_r = profile.dz_trigger_r;
|
||||
|
||||
dz_.joystick_l_pos = Scale::uint8_to_int16(profile.dz_joystick_l / 2);
|
||||
dz_.joystick_l_neg = Scale::invert_joy(dz_.joystick_l_pos);
|
||||
dz_.joystick_r_pos = Scale::uint8_to_int16(profile_.dz_joystick_r / 2);
|
||||
dz_.joystick_r_pos = Scale::uint8_to_int16(profile.dz_joystick_r / 2);
|
||||
dz_.joystick_r_neg = Scale::invert_joy(dz_.joystick_r_pos);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -32,6 +32,19 @@ void core1_task()
|
||||
bluepad32::run_task(gamepads_);
|
||||
}
|
||||
|
||||
void set_gp_check_timer(uint32_t task_id, UserSettings& user_settings)
|
||||
{
|
||||
TaskQueue::Core0::queue_delayed_task(task_id, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings]
|
||||
{
|
||||
//Check gamepad inputs for button combo to change usb device driver
|
||||
if (user_settings.check_for_driver_change(gamepads_[0]))
|
||||
{
|
||||
//This will store the new mode and reboot the pico
|
||||
user_settings.store_driver_type_safe(user_settings.get_current_driver());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void run_program()
|
||||
{
|
||||
UserSettings user_settings;
|
||||
@@ -50,15 +63,7 @@ void run_program()
|
||||
multicore_launch_core1(core1_task);
|
||||
|
||||
uint32_t tid_gp_check = TaskQueue::Core0::get_new_task_id();
|
||||
TaskQueue::Core0::queue_delayed_task(tid_gp_check, UserSettings::GP_CHECK_DELAY_MS, true, [&user_settings]
|
||||
{
|
||||
//Check gamepad inputs for button combo to change usb device driver
|
||||
if (user_settings.check_for_driver_change(gamepads_[0]))
|
||||
{
|
||||
//This will store the new mode and reboot the pico
|
||||
user_settings.store_driver_type_safe(user_settings.get_current_driver());
|
||||
}
|
||||
});
|
||||
set_gp_check_timer(tid_gp_check, user_settings);
|
||||
|
||||
DeviceDriver* device_driver = DeviceManager::get_instance().get_driver();
|
||||
|
||||
|
||||
@@ -282,7 +282,7 @@ private:
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
}; // class CoreQueue
|
||||
|
||||
CoreQueue* CoreQueue::instances_[static_cast<uint8_t>(CoreQueue::CoreNum::Core1) + 1]{nullptr};
|
||||
|
||||
|
||||
@@ -6,14 +6,15 @@
|
||||
void XInputDevice::initialize()
|
||||
{
|
||||
class_driver_ = *tud_xinput::class_driver();
|
||||
in_report_.report_size = XInput::ENDPOINT_IN_SIZE;
|
||||
}
|
||||
|
||||
void XInputDevice::process(const uint8_t idx, Gamepad& gamepad)
|
||||
{
|
||||
if (gamepad.new_pad_in())
|
||||
{
|
||||
std::memset(&in_report_.buttons, 0, sizeof(in_report_.buttons));
|
||||
in_report_.buttons[0] = 0;
|
||||
in_report_.buttons[1] = 0;
|
||||
|
||||
Gamepad::PadIn gp_in = gamepad.get_pad_in();
|
||||
|
||||
switch (gp_in.dpad)
|
||||
@@ -71,10 +72,8 @@ void XInputDevice::process(const uint8_t idx, Gamepad& gamepad)
|
||||
{
|
||||
tud_remote_wakeup();
|
||||
}
|
||||
if (tud_xinput::send_report_ready())
|
||||
{
|
||||
tud_xinput::send_report(reinterpret_cast<uint8_t*>(&in_report_), sizeof(XInput::InReport));
|
||||
}
|
||||
|
||||
tud_xinput::send_report((uint8_t*)&in_report_, sizeof(XInput::InReport));
|
||||
}
|
||||
|
||||
if (tud_xinput::receive_report(reinterpret_cast<uint8_t*>(&out_report_), sizeof(XInput::OutReport)) &&
|
||||
@@ -89,7 +88,7 @@ void XInputDevice::process(const uint8_t idx, Gamepad& gamepad)
|
||||
|
||||
uint16_t XInputDevice::get_report_cb(uint8_t itf, uint8_t report_id, hid_report_type_t report_type, uint8_t *buffer, uint16_t reqlen)
|
||||
{
|
||||
std::memcpy(buffer, &in_report_, sizeof(in_report_));
|
||||
std::memcpy(buffer, &in_report_, sizeof(XInput::InReport));
|
||||
return sizeof(XInput::InReport);
|
||||
}
|
||||
|
||||
@@ -102,13 +101,13 @@ bool XInputDevice::vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_co
|
||||
|
||||
const uint16_t * XInputDevice::get_descriptor_string_cb(uint8_t index, uint16_t langid)
|
||||
{
|
||||
const char *value = (const char *)XInput::STRING_DESCRIPTORS[index];
|
||||
const char *value = reinterpret_cast<const char*>(XInput::DESC_STRING[index]);
|
||||
return get_string_descriptor(value, index);
|
||||
}
|
||||
|
||||
const uint8_t * XInputDevice::get_descriptor_device_cb()
|
||||
{
|
||||
return XInput::DEVICE_DESCRIPTORS;
|
||||
return XInput::DESC_DEVICE;
|
||||
}
|
||||
|
||||
const uint8_t * XInputDevice::get_hid_descriptor_report_cb(uint8_t itf)
|
||||
@@ -118,7 +117,7 @@ const uint8_t * XInputDevice::get_hid_descriptor_report_cb(uint8_t itf)
|
||||
|
||||
const uint8_t * XInputDevice::get_descriptor_configuration_cb(uint8_t index)
|
||||
{
|
||||
return XInput::CONFIGURATION_DESCRIPTORS;
|
||||
return XInput::DESC_CONFIGURATION;
|
||||
}
|
||||
|
||||
const uint8_t * XInputDevice::get_descriptor_device_qualifier_cb()
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XINPUT)
|
||||
|
||||
#include <cstring>
|
||||
@@ -13,12 +12,12 @@
|
||||
|
||||
namespace tud_xinput {
|
||||
|
||||
static constexpr uint8_t ENDPOINT_SIZE = 32;
|
||||
static constexpr uint16_t ENDPOINT_SIZE = 32;
|
||||
|
||||
uint8_t endpoint_in_ = 0xFF;
|
||||
uint8_t endpoint_out_ = 0xFF;
|
||||
uint8_t out_buffer_[ENDPOINT_SIZE];
|
||||
uint8_t in_buffer_[ENDPOINT_SIZE];
|
||||
uint8_t ep_in_buffer_[ENDPOINT_SIZE];
|
||||
uint8_t ep_out_buffer_[ENDPOINT_SIZE];
|
||||
|
||||
//Class Driver
|
||||
|
||||
@@ -26,7 +25,8 @@ static void init(void)
|
||||
{
|
||||
endpoint_in_ = 0xFF;
|
||||
endpoint_out_ = 0xFF;
|
||||
std::memset(out_buffer_, 0, ENDPOINT_SIZE);
|
||||
std::memset(ep_out_buffer_, 0, ENDPOINT_SIZE);
|
||||
std::memset(ep_in_buffer_, 0, ENDPOINT_SIZE);
|
||||
}
|
||||
|
||||
static bool deinit(void)
|
||||
@@ -42,26 +42,28 @@ static void reset(uint8_t rhport)
|
||||
|
||||
static uint16_t open(uint8_t rhport, tusb_desc_interface_t const *itf_descriptor, uint16_t max_length)
|
||||
{
|
||||
uint16_t driver_length = static_cast<uint16_t>(sizeof(tusb_desc_interface_t) + (itf_descriptor->bNumEndpoints * sizeof(tusb_desc_endpoint_t)) + 16);
|
||||
uint16_t driver_length = sizeof(tusb_desc_interface_t) + (itf_descriptor->bNumEndpoints * sizeof(tusb_desc_endpoint_t)) + 16;
|
||||
|
||||
TU_VERIFY(max_length >= driver_length, 0);
|
||||
|
||||
uint8_t const *current_descriptor = tu_desc_next(itf_descriptor);
|
||||
uint8_t found_endpoints = 0;
|
||||
|
||||
while ((found_endpoints < itf_descriptor->bNumEndpoints) && (driver_length <= max_length))
|
||||
{
|
||||
tusb_desc_endpoint_t const *endpoint_descriptor = reinterpret_cast<const tusb_desc_endpoint_t*>(current_descriptor);
|
||||
|
||||
tusb_desc_endpoint_t const *endpoint_descriptor = (tusb_desc_endpoint_t const *)current_descriptor;
|
||||
if (TUSB_DESC_ENDPOINT == tu_desc_type(endpoint_descriptor))
|
||||
{
|
||||
TU_ASSERT(usbd_edpt_open(rhport, endpoint_descriptor));
|
||||
|
||||
if (tu_edpt_dir(endpoint_descriptor->bEndpointAddress) == TUSB_DIR_IN)
|
||||
{
|
||||
endpoint_in_ = endpoint_descriptor->bEndpointAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
endpoint_out_ = endpoint_descriptor->bEndpointAddress;
|
||||
|
||||
}
|
||||
|
||||
++found_endpoints;
|
||||
}
|
||||
|
||||
@@ -75,11 +77,11 @@ static bool control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool xfer_callback(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||
static bool xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||
{
|
||||
if (ep_addr == endpoint_out_)
|
||||
{
|
||||
usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_out_, out_buffer_, ENDPOINT_SIZE);
|
||||
usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -100,7 +102,7 @@ const usbd_class_driver_t* class_driver()
|
||||
.reset = reset,
|
||||
.open = open,
|
||||
.control_xfer_cb = control_xfer_cb,
|
||||
.xfer_cb = xfer_callback,
|
||||
.xfer_cb = xfer_cb,
|
||||
.sof = NULL
|
||||
};
|
||||
return &tud_class_driver_;
|
||||
@@ -108,31 +110,52 @@ const usbd_class_driver_t* class_driver()
|
||||
|
||||
bool send_report_ready()
|
||||
{
|
||||
TU_VERIFY(tud_ready() && endpoint_in_ != 0xFF && !usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_in_));
|
||||
return true;
|
||||
if (tud_ready() &&
|
||||
(endpoint_in_ != 0xFF) &&
|
||||
(!usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_in_)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool receive_report_ready()
|
||||
{
|
||||
if (tud_ready() &&
|
||||
(endpoint_out_ != 0xFF) &&
|
||||
(!usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_out_)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool send_report(const uint8_t *report, uint16_t len)
|
||||
{
|
||||
usbd_edpt_claim(BOARD_TUD_RHPORT, endpoint_in_);
|
||||
usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_in_, const_cast<uint8_t*>(report), ENDPOINT_SIZE);
|
||||
usbd_edpt_release(BOARD_TUD_RHPORT, endpoint_in_);
|
||||
return true;
|
||||
if (send_report_ready())
|
||||
{
|
||||
std::memcpy(ep_in_buffer_, report, std::min(len, ENDPOINT_SIZE));
|
||||
usbd_edpt_claim(BOARD_TUD_RHPORT, endpoint_in_);
|
||||
usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_in_, ep_in_buffer_, sizeof(XInput::InReport));
|
||||
usbd_edpt_release(BOARD_TUD_RHPORT, endpoint_in_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool receive_report(uint8_t *report, uint16_t len)
|
||||
{
|
||||
TU_VERIFY(endpoint_out_ != 0xFF && len <= ENDPOINT_SIZE);
|
||||
|
||||
if (tud_ready() && !usbd_edpt_busy(BOARD_TUD_RHPORT, endpoint_out_))
|
||||
if (receive_report_ready())
|
||||
{
|
||||
usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_out_, out_buffer_, len);
|
||||
usbd_edpt_claim(BOARD_TUD_RHPORT, endpoint_out_);
|
||||
usbd_edpt_xfer(BOARD_TUD_RHPORT, endpoint_out_, ep_out_buffer_, ENDPOINT_SIZE);
|
||||
usbd_edpt_release(BOARD_TUD_RHPORT, endpoint_out_);
|
||||
}
|
||||
|
||||
std::memcpy(report, out_buffer_, len);
|
||||
std::memcpy(report, ep_out_buffer_, std::min(len, ENDPOINT_SIZE));
|
||||
return true;
|
||||
}
|
||||
|
||||
}; // namespace TUDXInput
|
||||
} // namespace tud_xinput
|
||||
|
||||
#endif // (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XINPUT)
|
||||
@@ -12,6 +12,7 @@ namespace tud_xinput
|
||||
bool send_report(const uint8_t *report, uint16_t len);
|
||||
bool receive_report(uint8_t *report, uint16_t len);
|
||||
const usbd_class_driver_t* class_driver();
|
||||
};
|
||||
|
||||
} // namespace tud_xinput
|
||||
|
||||
#endif // _TUD_XINPUT_H_
|
||||
@@ -1,454 +1,4 @@
|
||||
// #include "tusb_option.h"
|
||||
|
||||
// #if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XID)
|
||||
|
||||
// #include <cstring>
|
||||
|
||||
// #include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.h"
|
||||
// #include "Descriptors/XboxOG.h"
|
||||
|
||||
// #ifndef CFG_TUD_XID_XREMOTE_ENABLE
|
||||
// #define CFG_TUD_XID_XREMOTE_ENABLE 0
|
||||
// #endif
|
||||
|
||||
// #ifdef XREMOTE_ROM_AVAILABLE
|
||||
// #define XREMOTE_ENABLED (CFG_TUD_XID_XREMOTE_ENABLE ? 1 : 0)
|
||||
// #include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h"
|
||||
// #else
|
||||
// #define XREMOTE_ENABLED 0
|
||||
// #endif
|
||||
|
||||
// namespace tud_xid {
|
||||
|
||||
// static constexpr uint8_t ENDPOINT_SIZE = 32;
|
||||
// static constexpr uint8_t INTERFACE_MULT = XREMOTE_ENABLED + 1;
|
||||
// static constexpr uint8_t INTERFACE_CLASS = 0x58;
|
||||
// static constexpr uint8_t INTERFACE_SUBCLASS = 0x42;
|
||||
|
||||
// enum class RequestType { SET_REPORT, GET_REPORT, GET_DESC, GET_CAPABILITIES_IN, GET_CAPABILITIES_OUT, UNKNOWN };
|
||||
|
||||
// struct Interface
|
||||
// {
|
||||
// Type type{Type::GAMEPAD};
|
||||
|
||||
// uint8_t itf_num{0xFF};
|
||||
|
||||
// uint8_t ep_in{0xFF};
|
||||
// uint8_t ep_out{0xFF};
|
||||
|
||||
// uint8_t ep_in_size{0xFF};
|
||||
// uint8_t ep_out_size{0xFF};
|
||||
|
||||
// std::array<uint8_t, ENDPOINT_SIZE> ep_out_buffer;
|
||||
// std::array<uint8_t, ENDPOINT_SIZE> gp_in_buffer;
|
||||
// std::array<uint8_t, ENDPOINT_SIZE> gp_out_buffer;
|
||||
|
||||
// Interface()
|
||||
// {
|
||||
// ep_out_buffer.fill(0);
|
||||
// gp_in_buffer.fill(0);
|
||||
// gp_out_buffer.fill(0);
|
||||
// }
|
||||
// };
|
||||
|
||||
// static std::array<Interface, CFG_TUD_XID * INTERFACE_MULT> interfaces_;
|
||||
// static Type xid_type_{Type::GAMEPAD};
|
||||
|
||||
// static inline RequestType get_request_type(const tusb_control_request_t *request)
|
||||
// {
|
||||
// if (request->bmRequestType == XboxOG::GET_REPORT_REQ_TYPE && request->bRequest == XboxOG::GET_REPORT_REQ && request->wValue == XboxOG::GET_REPORT_VALUE)
|
||||
// {
|
||||
// return RequestType::GET_REPORT;
|
||||
// }
|
||||
// if (request->bmRequestType == XboxOG::SET_REPORT_REQ_TYPE && request->bRequest == XboxOG::SET_REPORT_REQ && request->wValue == XboxOG::SET_REPORT_VALUE && request->wLength == static_cast<uint16_t>(0x06))
|
||||
// {
|
||||
// return RequestType::SET_REPORT;
|
||||
// }
|
||||
// if (request->bmRequestType == XboxOG::GET_DESC_REQ_TYPE && request->bRequest == XboxOG::GET_DESC_REQ && request->wValue == XboxOG::GET_DESC_VALUE)
|
||||
// {
|
||||
// return RequestType::GET_DESC;
|
||||
// }
|
||||
// if (request->bmRequestType == XboxOG::GET_CAP_REQ_TYPE && request->bRequest == XboxOG::GET_CAP_REQ)
|
||||
// {
|
||||
// if (request->wValue == XboxOG::GET_CAP_VALUE_IN)
|
||||
// {
|
||||
// return RequestType::GET_CAPABILITIES_IN;
|
||||
// }
|
||||
// else if (request->wValue == XboxOG::GET_CAP_VALUE_OUT)
|
||||
// {
|
||||
// return RequestType::GET_CAPABILITIES_OUT;
|
||||
// }
|
||||
// }
|
||||
// return RequestType::UNKNOWN;
|
||||
// }
|
||||
|
||||
// static inline uint8_t get_idx_by_itf(uint8_t itf)
|
||||
// {
|
||||
// for (uint8_t i = 0; i < interfaces_.size(); i++)
|
||||
// {
|
||||
// if (interfaces_[i].itf_num == itf)
|
||||
// {
|
||||
// return i;
|
||||
// }
|
||||
// if (interfaces_[i].type == Type::XREMOTE)
|
||||
// {
|
||||
// if (itf == interfaces_[i].itf_num + 1)
|
||||
// {
|
||||
// return i;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// return 0xFF;
|
||||
// }
|
||||
|
||||
// static inline uint8_t get_idx_by_edpt(uint8_t edpt)
|
||||
// {
|
||||
// for (uint8_t i = 0; i < interfaces_.size(); i++)
|
||||
// {
|
||||
// if (interfaces_[i].ep_in == edpt || interfaces_[i].ep_out == edpt)
|
||||
// {
|
||||
// return i;
|
||||
// }
|
||||
// }
|
||||
// return 0xFF;
|
||||
// }
|
||||
|
||||
// uint8_t get_index_by_type(uint8_t type_idx, Type type)
|
||||
// {
|
||||
// uint8_t type_idx_ = 0;
|
||||
// for (uint8_t i = 0; i < interfaces_.size(); i++)
|
||||
// {
|
||||
// if (interfaces_[i].type == type)
|
||||
// {
|
||||
// if (type_idx_ == type_idx)
|
||||
// {
|
||||
// return i;
|
||||
// }
|
||||
// type_idx_++;
|
||||
// }
|
||||
// }
|
||||
// return 0xFF;
|
||||
// }
|
||||
|
||||
// static inline Interface* find_available_interface()
|
||||
// {
|
||||
// for (Interface &itf : interfaces_)
|
||||
// {
|
||||
// if (itf.itf_num == 0xFF)
|
||||
// {
|
||||
// return &itf;
|
||||
// }
|
||||
// }
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// const uint8_t *xremote_get_rom()
|
||||
// {
|
||||
// #if XREMOTE_ENABLED
|
||||
// return XRemote::ROM;
|
||||
// #else
|
||||
// return nullptr;
|
||||
// #endif
|
||||
// }
|
||||
|
||||
// //Class driver
|
||||
|
||||
// static void xid_init()
|
||||
// {
|
||||
// for (Interface &itf : interfaces_)
|
||||
// {
|
||||
// itf = Interface();
|
||||
// itf.type = xid_type_;
|
||||
// }
|
||||
// }
|
||||
|
||||
// static void xid_reset(uint8_t rhport)
|
||||
// {
|
||||
// xid_init();
|
||||
// }
|
||||
|
||||
// static uint16_t xid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc, uint16_t max_len)
|
||||
// {
|
||||
// TU_VERIFY(itf_desc->bInterfaceClass == INTERFACE_CLASS, 0);
|
||||
// TU_VERIFY(itf_desc->bInterfaceSubClass == INTERFACE_SUBCLASS, 0);
|
||||
|
||||
// Interface *interface = find_available_interface();
|
||||
// TU_ASSERT(interface != nullptr, 0);
|
||||
|
||||
// uint16_t driver_len = 0;
|
||||
|
||||
// switch (interface->type)
|
||||
// {
|
||||
// case Type::GAMEPAD:
|
||||
// driver_len = XboxOG::GP::DRIVER_LEN;
|
||||
// break;
|
||||
// case Type::STEELBATTALION:
|
||||
// driver_len = XboxOG::SB::DRIVER_LEN;
|
||||
// break;
|
||||
// case Type::XREMOTE:
|
||||
// driver_len = XboxOG::XR::DRIVER_LEN;
|
||||
// break;
|
||||
// }
|
||||
|
||||
// TU_ASSERT(max_len >= driver_len, 0);
|
||||
|
||||
// interface->itf_num = itf_desc->bInterfaceNumber;
|
||||
|
||||
// tusb_desc_endpoint_t *ep_desc;
|
||||
// ep_desc = (tusb_desc_endpoint_t *)tu_desc_next(itf_desc);
|
||||
|
||||
// if (tu_desc_type(ep_desc) == TUSB_DESC_ENDPOINT)
|
||||
// {
|
||||
// usbd_edpt_open(rhport, ep_desc);
|
||||
// (ep_desc->bEndpointAddress & 0x80) ? (interface->ep_in = ep_desc->bEndpointAddress) :
|
||||
// (interface->ep_out = ep_desc->bEndpointAddress);
|
||||
// }
|
||||
|
||||
// TU_VERIFY(itf_desc->bNumEndpoints >= 2, driver_len);
|
||||
// ep_desc = (tusb_desc_endpoint_t *)tu_desc_next(ep_desc);
|
||||
|
||||
// if (tu_desc_type(ep_desc) == TUSB_DESC_ENDPOINT)
|
||||
// {
|
||||
// usbd_edpt_open(rhport, ep_desc);
|
||||
// (ep_desc->bEndpointAddress & 0x80) ? (interface->ep_in = ep_desc->bEndpointAddress) :
|
||||
// (interface->ep_out = ep_desc->bEndpointAddress);
|
||||
// }
|
||||
|
||||
// return driver_len;
|
||||
// }
|
||||
|
||||
// static bool xid_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||
// {
|
||||
// uint8_t index = get_idx_by_edpt(ep_addr);
|
||||
|
||||
// TU_VERIFY(result == XFER_RESULT_SUCCESS, true);
|
||||
// TU_VERIFY(index != 0xFF, true);
|
||||
// TU_VERIFY(xferred_bytes < ENDPOINT_SIZE, true);
|
||||
|
||||
// if (ep_addr == interfaces_[index].ep_out)
|
||||
// {
|
||||
// std::memcpy(interfaces_[index].gp_out_buffer.data(), interfaces_[index].ep_out_buffer.data(), std::min(static_cast<uint8_t>(xferred_bytes), ENDPOINT_SIZE));
|
||||
// }
|
||||
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// bool xremote_control_xfer(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request, Interface *interface)
|
||||
// {
|
||||
// if (request->bmRequestType == 0xC1 && request->bRequest == 0x01 && request->wIndex == 1 && request->wValue == 0x0000)
|
||||
// {
|
||||
// if (stage == CONTROL_STAGE_SETUP)
|
||||
// {
|
||||
// TU_LOG1("Sending XREMOTE INFO\r\n");
|
||||
// const uint8_t *rom = xremote_get_rom();
|
||||
// if (rom == nullptr)
|
||||
// {
|
||||
// return false; //STALL
|
||||
// }
|
||||
// tud_control_xfer(rhport, request, const_cast<uint8_t*>(&rom[0]), request->wLength);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
// //ROM DATA (Interface 1)
|
||||
// else if (request->bmRequestType == 0xC1 && request->bRequest == 0x02 && request->wIndex == 1)
|
||||
// {
|
||||
// if (stage == CONTROL_STAGE_SETUP)
|
||||
// {
|
||||
// const uint8_t *rom = xremote_get_rom();
|
||||
// if (rom == nullptr)
|
||||
// {
|
||||
// return false; //STALL
|
||||
// }
|
||||
// tud_control_xfer(rhport, request, const_cast<uint8_t*>(&rom[request->wValue * 1024]), request->wLength);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// bool xid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const *request)
|
||||
// {
|
||||
// TU_VERIFY(request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_INTERFACE);
|
||||
|
||||
// uint8_t index = get_idx_by_itf(static_cast<uint8_t>(request->wIndex));
|
||||
// TU_VERIFY(index != 0xFF, false);
|
||||
|
||||
// void* desc_buffer;
|
||||
// uint16_t desc_buffer_len;
|
||||
|
||||
// switch (get_request_type(request))
|
||||
// {
|
||||
// case RequestType::GET_REPORT:
|
||||
// if (stage == CONTROL_STAGE_SETUP)
|
||||
// {
|
||||
// tud_control_xfer(rhport, request, interfaces_[index].gp_in_buffer.data(), std::min(static_cast<uint8_t>(request->wLength), ENDPOINT_SIZE));
|
||||
// }
|
||||
// return true;
|
||||
|
||||
// case RequestType::SET_REPORT:
|
||||
// if (stage == CONTROL_STAGE_SETUP) //Getting rumble report
|
||||
// {
|
||||
// tud_control_xfer(rhport, request, interfaces_[index].ep_out_buffer.data(), std::min(static_cast<uint8_t>(request->wLength), ENDPOINT_SIZE));
|
||||
// }
|
||||
// else if (stage == CONTROL_STAGE_ACK) //Got rumble report
|
||||
// {
|
||||
// std::memcpy(interfaces_[index].gp_out_buffer.data(), interfaces_[index].ep_out_buffer.data(), std::min(static_cast<uint8_t>(request->wLength), ENDPOINT_SIZE));
|
||||
// }
|
||||
// return true;
|
||||
|
||||
// case RequestType::GET_DESC:
|
||||
// if (stage == CONTROL_STAGE_SETUP)
|
||||
// {
|
||||
// switch (interfaces_[index].type)
|
||||
// {
|
||||
// case Type::GAMEPAD:
|
||||
// desc_buffer = (void*)XboxOG::GP::XID_DEVICE_DESCRIPTORS;
|
||||
// desc_buffer_len = sizeof(XboxOG::GP::XID_DEVICE_DESCRIPTORS);
|
||||
// break;
|
||||
// case Type::STEELBATTALION:
|
||||
// desc_buffer = (void*)XboxOG::SB::XID_DEVICE_DESCRIPTORS;
|
||||
// desc_buffer_len = sizeof(XboxOG::SB::XID_DEVICE_DESCRIPTORS);
|
||||
// break;
|
||||
// case Type::XREMOTE:
|
||||
// desc_buffer = (void*)XboxOG::XR::XID_DEVICE_DESCRIPTORS;
|
||||
// desc_buffer_len = sizeof(XboxOG::XR::XID_DEVICE_DESCRIPTORS);
|
||||
// break;
|
||||
// default:
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// tud_control_xfer(rhport, request, desc_buffer, desc_buffer_len);
|
||||
// }
|
||||
// return true;
|
||||
|
||||
// case RequestType::GET_CAPABILITIES_IN:
|
||||
// if (stage == CONTROL_STAGE_SETUP)
|
||||
// {
|
||||
// switch (interfaces_[index].type)
|
||||
// {
|
||||
// case Type::GAMEPAD:
|
||||
// desc_buffer = (void*)XboxOG::GP::XID_CAPABILITIES_IN;
|
||||
// desc_buffer_len = sizeof(XboxOG::GP::XID_CAPABILITIES_IN);
|
||||
// break;
|
||||
// case Type::STEELBATTALION:
|
||||
// desc_buffer = (void*)XboxOG::SB::XID_CAPABILITIES_IN;
|
||||
// desc_buffer_len = sizeof(XboxOG::SB::XID_CAPABILITIES_IN);
|
||||
// break;
|
||||
// default:
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// tud_control_xfer(rhport, request, desc_buffer, desc_buffer_len);
|
||||
// }
|
||||
// return true;
|
||||
|
||||
// case RequestType::GET_CAPABILITIES_OUT:
|
||||
// if (stage == CONTROL_STAGE_SETUP)
|
||||
// {
|
||||
// switch (interfaces_[index].type)
|
||||
// {
|
||||
// case Type::GAMEPAD:
|
||||
// desc_buffer = (void*)XboxOG::GP::XID_CAPABILITIES_OUT;
|
||||
// desc_buffer_len = sizeof(XboxOG::GP::XID_CAPABILITIES_OUT);
|
||||
// break;
|
||||
// case Type::STEELBATTALION:
|
||||
// desc_buffer = (void*)XboxOG::SB::XID_CAPABILITIES_OUT;
|
||||
// desc_buffer_len = sizeof(XboxOG::SB::XID_CAPABILITIES_OUT);
|
||||
// break;
|
||||
// default:
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// tud_control_xfer(rhport, request, desc_buffer, desc_buffer_len);
|
||||
// }
|
||||
// return true;
|
||||
|
||||
// default:
|
||||
// if (interfaces_[index].type != Type::XREMOTE)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// return xremote_control_xfer(rhport, stage, request, &interfaces_[index]);
|
||||
// }
|
||||
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// static const usbd_class_driver_t tud_xid_class_driver_ =
|
||||
// {
|
||||
// #if CFG_TUSB_DEBUG >= 2
|
||||
// .name = "XID DRIVER (DUKE,SB OR XREMOTE)",
|
||||
// #endif
|
||||
// .init = xid_init,
|
||||
// .reset = xid_reset,
|
||||
// .open = xid_open,
|
||||
// .control_xfer_cb = xid_control_xfer_cb,
|
||||
// .xfer_cb = xid_xfer_cb,
|
||||
// .sof = NULL
|
||||
// };
|
||||
|
||||
// //Public API
|
||||
|
||||
// //Call first before device stack is initialized with tud_init(), will default to Duke/Gamepad otherwise
|
||||
// void initialize(Type xid_type)
|
||||
// {
|
||||
// xid_type_ = xid_type;
|
||||
// }
|
||||
|
||||
// const usbd_class_driver_t* class_driver()
|
||||
// {
|
||||
// return &tud_xid_class_driver_;
|
||||
// }
|
||||
|
||||
// bool send_report_ready(uint8_t index)
|
||||
// {
|
||||
// TU_VERIFY(index < interfaces_.size(), false);
|
||||
// TU_VERIFY(interfaces_[index].ep_in != 0xFF, false);
|
||||
// return (tud_ready() && !usbd_edpt_busy(BOARD_TUD_RHPORT, interfaces_[index].ep_in));
|
||||
// }
|
||||
|
||||
// bool send_report(uint8_t index, const uint8_t* report, uint16_t len)
|
||||
// {
|
||||
// TU_VERIFY(len < ENDPOINT_SIZE, false);
|
||||
// TU_VERIFY(send_report_ready(index), false);
|
||||
|
||||
// if (tud_suspended())
|
||||
// {
|
||||
// tud_remote_wakeup();
|
||||
// }
|
||||
|
||||
// std::memcpy(interfaces_[index].gp_in_buffer.data(), report, len);
|
||||
|
||||
// return usbd_edpt_xfer(BOARD_TUD_RHPORT, interfaces_[index].ep_in, interfaces_[index].gp_in_buffer.data(), len);
|
||||
// }
|
||||
|
||||
// bool receive_report(uint8_t index, uint8_t *report, uint16_t len)
|
||||
// {
|
||||
// TU_VERIFY(index < interfaces_.size(), false);
|
||||
// TU_VERIFY(interfaces_[index].ep_out != 0xFF, false);
|
||||
// TU_VERIFY(len < ENDPOINT_SIZE, false);
|
||||
|
||||
// std::memcpy(report, interfaces_[index].gp_out_buffer.data(), len);
|
||||
|
||||
// if (tud_ready() && !usbd_edpt_busy(BOARD_TUD_RHPORT, interfaces_[index].ep_out))
|
||||
// {
|
||||
// usbd_edpt_xfer(BOARD_TUD_RHPORT, interfaces_[index].ep_out, interfaces_[index].ep_out_buffer.data(), len);
|
||||
// }
|
||||
// return true;
|
||||
// }
|
||||
|
||||
// bool xremote_rom_available()
|
||||
// {
|
||||
// return (xremote_get_rom() != nullptr);
|
||||
// }
|
||||
|
||||
// } // namespace TUDXID
|
||||
|
||||
// #endif // TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XID
|
||||
|
||||
#include "tusb_option.h"
|
||||
|
||||
#if (TUSB_OPT_DEVICE_ENABLED && CFG_TUD_XID)
|
||||
|
||||
#include <cstring>
|
||||
@@ -456,12 +6,8 @@
|
||||
#include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid.h"
|
||||
#include "Descriptors/XboxOG.h"
|
||||
|
||||
#ifndef CFG_TUD_XID_XREMOTE_ENABLE
|
||||
#define CFG_TUD_XID_XREMOTE_ENABLE 0
|
||||
#endif
|
||||
|
||||
#ifdef XREMOTE_ROM_AVAILABLE
|
||||
#define XREMOTE_ENABLED (CFG_TUD_XID_XREMOTE_ENABLE ? 1 : 0)
|
||||
#if defined(XREMOTE_ROM_AVAILABLE)
|
||||
#define XREMOTE_ENABLED 1
|
||||
#include "USBDevice/DeviceDriver/XboxOG/tud_xid/tud_xid_xremote_rom.h"
|
||||
#else
|
||||
#define XREMOTE_ENABLED 0
|
||||
@@ -469,7 +15,7 @@
|
||||
|
||||
namespace tud_xid {
|
||||
|
||||
static constexpr uint8_t ENDPOINT_SIZE = 32;
|
||||
static constexpr uint16_t ENDPOINT_SIZE = 32;
|
||||
static constexpr uint8_t INTERFACE_MULT = XREMOTE_ENABLED + 1;
|
||||
static constexpr uint8_t INTERFACE_CLASS = 0x58;
|
||||
static constexpr uint8_t INTERFACE_SUBCLASS = 0x42;
|
||||
@@ -680,44 +226,6 @@ static uint16_t xid_open(uint8_t rhport, tusb_desc_interface_t const *itf_desc,
|
||||
endpoint++;
|
||||
}
|
||||
|
||||
// interface->itf_num = itf_desc->bInterfaceNumber;
|
||||
|
||||
// tusb_desc_endpoint_t *ep_desc;
|
||||
// ep_desc = (tusb_desc_endpoint_t *)tu_desc_next(itf_desc);
|
||||
|
||||
// if (tu_desc_type(ep_desc) == TUSB_DESC_ENDPOINT)
|
||||
// {
|
||||
// TU_VERIFY(usbd_edpt_open(rhport, ep_desc), 0);
|
||||
// if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN)
|
||||
// {
|
||||
// interface->ep_in = ep_desc->bEndpointAddress;
|
||||
// interface->ep_in_size = ep_desc->wMaxPacketSize;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// interface->ep_out = ep_desc->bEndpointAddress;
|
||||
// interface->ep_out_size = ep_desc->wMaxPacketSize;
|
||||
// }
|
||||
// }
|
||||
|
||||
// TU_VERIFY(itf_desc->bNumEndpoints >= 2, driver_len);
|
||||
// ep_desc = (tusb_desc_endpoint_t *)tu_desc_next(ep_desc);
|
||||
|
||||
// if (tu_desc_type(ep_desc) == TUSB_DESC_ENDPOINT)
|
||||
// {
|
||||
// TU_VERIFY(usbd_edpt_open(rhport, ep_desc), driver_len);
|
||||
// if (tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN)
|
||||
// {
|
||||
// interface->ep_in = ep_desc->bEndpointAddress;
|
||||
// interface->ep_in_size = ep_desc->wMaxPacketSize;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// interface->ep_out = ep_desc->bEndpointAddress;
|
||||
// interface->ep_out_size = ep_desc->wMaxPacketSize;
|
||||
// }
|
||||
// }
|
||||
|
||||
return driver_len;
|
||||
}
|
||||
|
||||
@@ -836,22 +344,6 @@ bool xid_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t c
|
||||
return true;
|
||||
}
|
||||
|
||||
static const usbd_class_driver_t tud_xid_class_driver_ =
|
||||
{
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
.name = "XID DRIVER (DUKE,SB OR XREMOTE)",
|
||||
#else
|
||||
.name = nullptr,
|
||||
#endif
|
||||
.init = xid_init,
|
||||
.deinit = xid_deinit,
|
||||
.reset = xid_reset,
|
||||
.open = xid_open,
|
||||
.control_xfer_cb = xid_control_xfer_cb,
|
||||
.xfer_cb = xid_xfer_cb,
|
||||
.sof = NULL
|
||||
};
|
||||
|
||||
//Public API
|
||||
|
||||
//Call first before device stack is initialized with tud_init(), will default to Duke/Gamepad otherwise
|
||||
@@ -862,7 +354,22 @@ void initialize(Type xid_type)
|
||||
|
||||
const usbd_class_driver_t* class_driver()
|
||||
{
|
||||
return &tud_xid_class_driver_;
|
||||
static const usbd_class_driver_t tud_xid_class_driver =
|
||||
{
|
||||
#if CFG_TUSB_DEBUG >= 2
|
||||
.name = "XID",
|
||||
#else
|
||||
.name = nullptr,
|
||||
#endif
|
||||
.init = xid_init,
|
||||
.deinit = xid_deinit,
|
||||
.reset = xid_reset,
|
||||
.open = xid_open,
|
||||
.control_xfer_cb = xid_control_xfer_cb,
|
||||
.xfer_cb = xid_xfer_cb,
|
||||
.sof = NULL
|
||||
};
|
||||
return &tud_xid_class_driver;
|
||||
}
|
||||
|
||||
bool send_report_ready(uint8_t index)
|
||||
@@ -882,7 +389,7 @@ bool send_report(uint8_t index, const uint8_t* report, uint16_t len)
|
||||
tud_remote_wakeup();
|
||||
}
|
||||
|
||||
uint16_t size = std::min(len, static_cast<uint16_t>(interfaces_[index].ep_in_size));
|
||||
uint16_t size = std::min(len, interfaces_[index].ep_in_size);
|
||||
|
||||
std::memcpy(interfaces_[index].ep_in_buffer.data(), report, size);
|
||||
|
||||
@@ -895,7 +402,7 @@ bool receive_report(uint8_t index, uint8_t *report, uint16_t len)
|
||||
TU_VERIFY(interfaces_[index].ep_out != 0xFF);
|
||||
TU_VERIFY(len < ENDPOINT_SIZE);
|
||||
|
||||
uint16_t size = std::min(len, static_cast<uint16_t>(interfaces_[index].ep_out_size));
|
||||
uint16_t size = std::min(len, interfaces_[index].ep_out_size);
|
||||
|
||||
if (tud_ready() && !usbd_edpt_busy(BOARD_TUD_RHPORT, interfaces_[index].ep_out))
|
||||
{
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include <cstring>
|
||||
#include <chrono>
|
||||
|
||||
#include "Board/board_api.h"
|
||||
#include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput.h"
|
||||
#include "USBHost/HostDriver/XInput/tuh_xinput/tuh_xinput_cmd.h"
|
||||
|
||||
@@ -283,11 +282,11 @@ static bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uin
|
||||
{
|
||||
if (dir == TUSB_DIR_IN)
|
||||
{
|
||||
report_received_cb(dev_addr, instance, interface->ep_in_buffer.data(), static_cast<uint16_t>(interface->ep_in_size));
|
||||
report_received_cb(dev_addr, instance, interface->ep_in_buffer.data(), interface->ep_in_size);
|
||||
}
|
||||
else if (report_sent_cb)
|
||||
{
|
||||
report_sent_cb(dev_addr, instance, interface->ep_out_buffer.data(), static_cast<uint16_t>(interface->ep_out_size));
|
||||
report_sent_cb(dev_addr, instance, interface->ep_out_buffer.data(), interface->ep_out_size);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -195,9 +195,7 @@ public:
|
||||
{
|
||||
if (device_slot.address == address)
|
||||
{
|
||||
TU_LOG2("Deinit driver\r\n");
|
||||
device_slot.reset();
|
||||
TU_LOG2("Driver deinitialized\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,20 @@
|
||||
#ifndef _BOARD_CONFIG_H_
|
||||
#define _BOARD_CONFIG_H_
|
||||
#ifndef _OGXM_BOARD_CONFIG_H_
|
||||
#define _OGXM_BOARD_CONFIG_H_
|
||||
|
||||
/* Don't edit this file directly, instead use CMake to configure the board.
|
||||
Add args -DOGXM_BOARD=PI_PICO and -DMAX_GAMEPADS=1 (or = whatever option you want)
|
||||
to set the board and the number of gamepads.
|
||||
If you're setting MAX_GAMEPADS > 1 only D-Input, Switch, and WebApp device drivers will work. */
|
||||
|
||||
#define ADA_FEATHER 1
|
||||
#define PI_PICO 2
|
||||
#define RP_ZERO 3
|
||||
#define PI_PICOW 4
|
||||
#define INTERNAL_4CH 5
|
||||
#define EXTERNAL_4CH 6
|
||||
#define W_ESP32 7
|
||||
#define PI_PICO 1
|
||||
#define PI_PICO2 2
|
||||
#define PI_PICOW 3
|
||||
#define PI_PICOW2 4
|
||||
#define RP_ZERO 5
|
||||
#define ADA_FEATHER 6
|
||||
#define INTERNAL_4CH 7
|
||||
#define EXTERNAL_4CH 8
|
||||
#define W_ESP32 9
|
||||
|
||||
#define SYSCLOCK_KHZ 240000
|
||||
|
||||
@@ -24,25 +26,25 @@
|
||||
#define OGXM_BOARD PI_PICO
|
||||
#endif
|
||||
|
||||
#if OGXM_BOARD == ADA_FEATHER
|
||||
#define RGB_PWR_PIN 20
|
||||
#define RGB_PXL_PIN 21
|
||||
|
||||
#define PIO_USB_DP_PIN 16 // DM = 17
|
||||
#define LED_INDICATOR_PIN 13
|
||||
#define VCC_EN_PIN 18
|
||||
|
||||
#elif OGXM_BOARD == PI_PICO || OGXM_BOARD == PI_PICO2
|
||||
#if OGXM_BOARD == PI_PICO || OGXM_BOARD == PI_PICO2
|
||||
#define PIO_USB_DP_PIN 0 // DM = 1
|
||||
#define LED_INDICATOR_PIN 25
|
||||
|
||||
#elif OGXM_BOARD == PI_PICOW || OGXM_BOARD == PI_PICOW2
|
||||
|
||||
#elif OGXM_BOARD == RP_ZERO
|
||||
#define RGB_PXL_PIN 16
|
||||
|
||||
#define PIO_USB_DP_PIN 10 // DM = 11
|
||||
#define LED_INDICATOR_PIN 14
|
||||
|
||||
#elif OGXM_BOARD == PI_PICOW
|
||||
#elif OGXM_BOARD == ADA_FEATHER
|
||||
#define RGB_PWR_PIN 20
|
||||
#define RGB_PXL_PIN 21
|
||||
|
||||
#define PIO_USB_DP_PIN 16 // DM = 17
|
||||
#define LED_INDICATOR_PIN 13
|
||||
#define VCC_EN_PIN 18
|
||||
|
||||
#elif OGXM_BOARD == INTERNAL_4CH
|
||||
#define PIO_USB_DP_PIN 16 // DM = 17
|
||||
@@ -63,7 +65,7 @@
|
||||
#elif OGXM_BOARD == W_ESP32
|
||||
#define I2C_SDA_PIN 18 // SCL = 19
|
||||
#define UART0_TX_PIN 16 // RX = 17
|
||||
#define UART0_RX_PIN (UART0_TX_PIN + 1)
|
||||
#define UART0_RX_PIN (UART0_TX_PIN + 1)
|
||||
#define MODE_SEL_PIN 21
|
||||
#define ESP_PROG_PIN 20 // ESP32 IO0
|
||||
#define ESP_RST_PIN 8 // ESP32 EN
|
||||
@@ -114,4 +116,4 @@
|
||||
#define DEBUG_UART_PORT __CONCAT(uart,PICO_DEFAULT_UART)
|
||||
#endif // defined(OGXM_DEBUG)
|
||||
|
||||
#endif // _BOARD_CONFIG_H_
|
||||
#endif // _OGXM_BOARD_CONFIG_H_
|
||||
@@ -110,8 +110,6 @@
|
||||
#define CFG_TUD_XID 1
|
||||
#define CFG_TUD_XINPUT 1
|
||||
|
||||
#define CFG_TUD_XID_XREMOTE_ENABLE 1
|
||||
|
||||
// HID buffer size Should be sufficient to hold ID (if any) + Data
|
||||
#define CFG_TUD_HID_EP_BUFSIZE 64
|
||||
#define CFG_TUD_CDC_EP_BUFSIZE 64
|
||||
|
||||
18
Firmware/external/init_submodules.cmake
vendored
Normal file
18
Firmware/external/init_submodules.cmake
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
function(init_git_submodules EXTERNAL_DIR)
|
||||
set(REPO_DIR "${EXTERNAL_DIR}/../../")
|
||||
message(STATUS "Initializing submodules in ${REPO_DIR}")
|
||||
|
||||
execute_process(
|
||||
COMMAND git submodule update --init --recursive
|
||||
WORKING_DIRECTORY ${REPO_DIR}
|
||||
RESULT_VARIABLE INIT_SUBMODULES_RESULT
|
||||
OUTPUT_VARIABLE INIT_SUBMODULES_OUTPUT
|
||||
ERROR_VARIABLE INIT_SUBMODULES_ERROR
|
||||
)
|
||||
|
||||
if(INIT_SUBMODULES_RESULT EQUAL 0)
|
||||
message(STATUS "Subnmodules initialized successfully.")
|
||||
else()
|
||||
message(FATAL_ERROR "Failed to initialize submodules: ${INIT_SUBMODULES_ERROR}")
|
||||
endif()
|
||||
endfunction()
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in many flavors, supported on the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Pi Pico 2, Waveshare RP2040-Zero, Pi Pico W, RP2040/ESP32 hybrid, and a 4-Channel RP2040-Zero setup.
|
||||
|
||||
Visit the web app here: [https://wiredopposite.github.io/OGX-Mini-WebApp/](https://wiredopposite.github.io/OGX-Mini-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter Web app mode. Click "Connect" in the web app and select the OGX-Mini.
|
||||
Visit the web app here: [https://wiredopposite.github.io/OGX-Mini-WebApp/](https://wiredopposite.github.io/OGX-Mini-WebApp/) to change your mappings and deadzone settings. To pair the OGX-Mini with the web app, plug your controller in, then connect it to your PC, hold **Start + Left Bumper + Right Bumper** to enter web app mode. Click "Connect" in the web app and select the OGX-Mini.
|
||||
|
||||
## Supported platforms
|
||||
- Original Xbox
|
||||
@@ -127,4 +127,8 @@ Or just install the GCC ARM toolchain and use the CMake Tools extension in VSCod
|
||||
CMake scripts will patch some files in TinyUSB, Bluepad32 and BTStack. If the patches fail, it's because of a text encoding issue, so open each .diff file in ```OGX-Mini/Firmware/external/patches``` in Notepad++. At the top of the window, click Encoding > UTF-8 and save. They should work after that.
|
||||
|
||||
### ESP32
|
||||
You will need ESP-IDF v5.1 and esptools installed. If you use VSCode you can install the ESP-IDF extension and configure the project for v5.1, it'll download everything for you and then you just click the build button at the bottom of the window.
|
||||
Please see the Hardware directory for a schematic showing how to hookup the ESP32 to your RP2040.
|
||||
|
||||
You will need ESP-IDF v5.1, esptools, and python3 installed. If you use VSCode you can install the ESP-IDF extension and configure the project for v5.1, it'll download everything for you and then you just click the build button at the bottom of the window.
|
||||
|
||||
When you build with ESP-IDF, Cmake will run a python script that copies the necessary BTStack files components directory, this is needed since BTStack isn't configured as an IDF component when you download it.
|
||||
Reference in New Issue
Block a user