v1.0.0-alpha
This commit is contained in:
@@ -27,8 +27,8 @@ static constexpr uint32_t LED_TIME_MS = 500;
|
||||
struct Device
|
||||
{
|
||||
std::atomic<bool> connected{false};
|
||||
std::atomic<ReportIn> report_in;
|
||||
std::atomic<ReportOut> report_out;
|
||||
std::atomic<ReportIn> report_in{ReportIn()};
|
||||
std::atomic<ReportOut> report_out{ReportOut()};
|
||||
};
|
||||
|
||||
std::array<Device, CONFIG_BLUEPAD32_MAX_DEVICES> devices_;
|
||||
@@ -46,9 +46,13 @@ static inline void send_feedback_cb(btstack_timer_source *ts)
|
||||
}
|
||||
|
||||
ReportOut report_out = devices_[i].report_out.load();
|
||||
if (!report_out.rumble_l && !report_out.rumble_r)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
bp_device->report_parser.play_dual_rumble(bp_device, 0, FEEDBACK_TIME_MS, report_out.rumble_l, report_out.rumble_r);
|
||||
}
|
||||
// btstack_run_loop_remove_timer(ts);
|
||||
|
||||
btstack_run_loop_set_timer(ts, FEEDBACK_TIME_MS);
|
||||
btstack_run_loop_add_timer(ts);
|
||||
}
|
||||
@@ -69,7 +73,7 @@ static inline void check_led_cb(btstack_timer_source *ts)
|
||||
board_api::set_led(i, devices_[i].connected.load() ? 1 : (led_state ? 1 : 0));
|
||||
}
|
||||
}
|
||||
// btstack_run_loop_remove_timer(ts);
|
||||
|
||||
btstack_run_loop_set_timer(ts, LED_TIME_MS);
|
||||
btstack_run_loop_add_timer(ts);
|
||||
}
|
||||
@@ -85,15 +89,15 @@ static void init_complete_cb(void)
|
||||
{
|
||||
uni_bt_enable_new_connections_unsafe(true);
|
||||
|
||||
// Based on runtime condition, you can delete or list the stored BT keys.
|
||||
if (1)
|
||||
{
|
||||
uni_bt_del_keys_unsafe();
|
||||
}
|
||||
else
|
||||
{
|
||||
uni_bt_list_keys_unsafe();
|
||||
}
|
||||
// // Based on runtime condition, you can delete or list the stored BT keys.
|
||||
// if (1)
|
||||
// {
|
||||
// uni_bt_del_keys_unsafe();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// uni_bt_list_keys_unsafe();
|
||||
// }
|
||||
|
||||
uni_property_dump_all();
|
||||
}
|
||||
@@ -132,8 +136,8 @@ static void device_disconnected_cb(uni_hid_device_t* device)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ReportIn report_in;
|
||||
|
||||
ReportIn report_in = ReportIn();
|
||||
report_in.index = static_cast<uint8_t>(idx);
|
||||
devices_[idx].report_in.store(report_in);
|
||||
devices_[idx].connected.store(false);
|
||||
@@ -252,10 +256,6 @@ uni_platform* get_driver()
|
||||
|
||||
ReportIn get_report_in(uint8_t index)
|
||||
{
|
||||
// if (index >= CONFIG_BLUEPAD32_MAX_DEVICES)
|
||||
// {
|
||||
// return ReportIn();
|
||||
// }
|
||||
return devices_[index].report_in.load();
|
||||
}
|
||||
|
||||
@@ -270,6 +270,14 @@ void set_report_out(const ReportOut& report_out)
|
||||
|
||||
void run_task()
|
||||
{
|
||||
for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i)
|
||||
{
|
||||
ReportIn report_in;
|
||||
report_in.index = i;
|
||||
devices_[i].report_in.store(report_in);
|
||||
devices_[i].report_out.store(ReportOut());
|
||||
}
|
||||
|
||||
board_api::init_pins();
|
||||
|
||||
btstack_init();
|
||||
@@ -312,333 +320,4 @@ bool connected(uint8_t index)
|
||||
return devices_[index].connected.load();
|
||||
}
|
||||
|
||||
} // namespace bluepad32
|
||||
|
||||
// #include <cstdint>
|
||||
// #include <atomic>
|
||||
// #include <cstring>
|
||||
// #include <array>
|
||||
// #include <freertos/FreeRTOS.h>
|
||||
// #include <freertos/task.h>
|
||||
// #include <freertos/timers.h>
|
||||
// #include <freertos/queue.h>
|
||||
// #include <esp_log.h>
|
||||
|
||||
// #include "btstack_port_esp32.h"
|
||||
// #include "btstack_run_loop.h"
|
||||
// #include "btstack_stdio_esp32.h"
|
||||
// #include "uni.h"
|
||||
|
||||
// #include "sdkconfig.h"
|
||||
// #include "Board/board_api.h"
|
||||
// #include "I2CDriver/I2CDriver.h"
|
||||
// #include "Bluepad32/Gamepad.h"
|
||||
// #include "Bluepad32/Bluepad32.h"
|
||||
|
||||
// namespace bluepad32 {
|
||||
|
||||
// static constexpr uint32_t FEEDBACK_TIME_MS = 200;
|
||||
// static constexpr uint32_t LED_TIME_MS = 500;
|
||||
|
||||
// struct Device
|
||||
// {
|
||||
// std::atomic<bool> connected{false};
|
||||
// std::atomic<ReportIn> report_in;
|
||||
// std::atomic<bool> new_report_in{false};
|
||||
// std::atomic<ReportOut> report_out;
|
||||
// };
|
||||
|
||||
// std::array<Device, CONFIG_BLUEPAD32_MAX_DEVICES> devices_;
|
||||
|
||||
// static inline void send_feedback_cb(btstack_timer_source *ts)
|
||||
// {
|
||||
// uni_hid_device_t* bp_device;
|
||||
|
||||
// for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i)
|
||||
// {
|
||||
// bp_device = uni_hid_device_get_instance_for_idx(i);
|
||||
// if (!bp_device || !bp_device->report_parser.play_dual_rumble)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// ReportOut report_out = devices_[i].report_out.load();
|
||||
// bp_device->report_parser.play_dual_rumble(bp_device, 0, FEEDBACK_TIME_MS, report_out.rumble_l, report_out.rumble_r);
|
||||
// }
|
||||
|
||||
// btstack_run_loop_remove_timer(ts);
|
||||
// btstack_run_loop_set_timer(ts, FEEDBACK_TIME_MS);
|
||||
// btstack_run_loop_add_timer(ts);
|
||||
// }
|
||||
|
||||
// static inline void check_led_cb(btstack_timer_source *ts)
|
||||
// {
|
||||
// static bool led_state = false;
|
||||
// led_state = !led_state;
|
||||
|
||||
// if constexpr (board_api::NUM_LEDS == 1)
|
||||
// {
|
||||
// board_api::set_led(any_connected() ? 1 : (led_state ? 1 : 0));
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// for (uint8_t i = 0; i < board_api::NUM_LEDS; ++i)
|
||||
// {
|
||||
// board_api::set_led(i, devices_[i].connected.load() ? 1 : (led_state ? 1 : 0));
|
||||
// }
|
||||
// }
|
||||
|
||||
// btstack_run_loop_remove_timer(ts);
|
||||
// btstack_run_loop_set_timer(ts, LED_TIME_MS);
|
||||
// btstack_run_loop_add_timer(ts);
|
||||
// }
|
||||
|
||||
// //BT Driver
|
||||
|
||||
// static void init(int argc, const char** arg_V)
|
||||
// {
|
||||
|
||||
// }
|
||||
|
||||
// static void init_complete_cb(void)
|
||||
// {
|
||||
// uni_bt_enable_new_connections_unsafe(true);
|
||||
|
||||
// // Based on runtime condition, you can delete or list the stored BT keys.
|
||||
// if (1)
|
||||
// {
|
||||
// uni_bt_del_keys_unsafe();
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// uni_bt_list_keys_unsafe();
|
||||
// }
|
||||
|
||||
// uni_property_dump_all();
|
||||
// }
|
||||
|
||||
// static uni_error_t device_discovered_cb(bd_addr_t addr, const char* name, uint16_t cod, uint8_t rssi)
|
||||
// {
|
||||
// if (!((cod & UNI_BT_COD_MINOR_MASK) & UNI_BT_COD_MINOR_GAMEPAD))
|
||||
// {
|
||||
// return UNI_ERROR_IGNORE_DEVICE;
|
||||
// }
|
||||
// return UNI_ERROR_SUCCESS;
|
||||
// }
|
||||
|
||||
// static void device_connected_cb(uni_hid_device_t* device)
|
||||
// {
|
||||
// #ifdef CONFIG_BLUEPAD32_USB_CONSOLE_ENABLE
|
||||
// logd("BP32", "Device connected, addr: %p, index: %i\n", device, uni_hid_device_get_idx_for_instance(device));
|
||||
// #endif
|
||||
|
||||
// int idx = uni_hid_device_get_idx_for_instance(device);
|
||||
// if (idx >= CONFIG_BLUEPAD32_MAX_DEVICES || idx < 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// devices_[idx].connected.store(true);
|
||||
// }
|
||||
|
||||
// static void device_disconnected_cb(uni_hid_device_t* device)
|
||||
// {
|
||||
// #ifdef CONFIG_BLUEPAD32_USB_CONSOLE_ENABLE
|
||||
// logd("BP32", "Device disconnected, addr: %p, index: %i\n", device, uni_hid_device_get_idx_for_instance(device));
|
||||
// #endif
|
||||
|
||||
// int idx = uni_hid_device_get_idx_for_instance(device);
|
||||
// if (idx >= CONFIG_BLUEPAD32_MAX_DEVICES || idx < 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// ReportIn report_in = ReportIn();
|
||||
// report_in.index = static_cast<uint8_t>(idx);
|
||||
// devices_[idx].report_in.store(report_in);
|
||||
// devices_[idx].connected.store(false);
|
||||
// }
|
||||
|
||||
// static uni_error_t device_ready_cb(uni_hid_device_t* device)
|
||||
// {
|
||||
// return UNI_ERROR_SUCCESS;
|
||||
// }
|
||||
|
||||
// static void oob_event_cb(uni_platform_oob_event_t event, void* data)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// static void controller_data_cb(uni_hid_device_t* device, uni_controller_t* controller)
|
||||
// {
|
||||
// static uni_gamepad_t prev_uni_gp[CONFIG_BLUEPAD32_MAX_DEVICES] = {};
|
||||
|
||||
// if (!device || !controller || controller->klass != UNI_CONTROLLER_CLASS_GAMEPAD)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// uni_gamepad_t *uni_gp = &controller->gamepad;
|
||||
// int idx = uni_hid_device_get_idx_for_instance(device);
|
||||
|
||||
// if (idx >= CONFIG_BLUEPAD32_MAX_DEVICES || idx < 0 || std::memcmp(uni_gp, &prev_uni_gp[idx], sizeof(uni_gamepad_t)) == 0)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// #ifdef CONFIG_BLUEPAD32_USB_CONSOLE_ENABLE
|
||||
// logi("BP32 Stack", "Remaining stack: %d\n", uxTaskGetStackHighWaterMark(NULL));
|
||||
// #endif
|
||||
|
||||
// ReportIn report_in;
|
||||
// report_in.index = static_cast<uint8_t>(idx);
|
||||
|
||||
// switch (uni_gp->dpad)
|
||||
// {
|
||||
// case DPAD_UP:
|
||||
// report_in.dpad = Gamepad::DPad::UP;
|
||||
// break;
|
||||
// case DPAD_DOWN:
|
||||
// report_in.dpad = Gamepad::DPad::DOWN;
|
||||
// break;
|
||||
// case DPAD_LEFT:
|
||||
// report_in.dpad = Gamepad::DPad::LEFT;
|
||||
// break;
|
||||
// case DPAD_RIGHT:
|
||||
// report_in.dpad = Gamepad::DPad::RIGHT;
|
||||
// break;
|
||||
// case DPAD_UP | DPAD_RIGHT:
|
||||
// report_in.dpad = Gamepad::DPad::UP_RIGHT;
|
||||
// break;
|
||||
// case DPAD_DOWN | DPAD_RIGHT:
|
||||
// report_in.dpad = Gamepad::DPad::DOWN_RIGHT;
|
||||
// break;
|
||||
// case DPAD_DOWN | DPAD_LEFT:
|
||||
// report_in.dpad = Gamepad::DPad::DOWN_LEFT;
|
||||
// break;
|
||||
// case DPAD_UP | DPAD_LEFT:
|
||||
// report_in.dpad = Gamepad::DPad::UP_LEFT;
|
||||
// break;
|
||||
// default:
|
||||
// break;
|
||||
// }
|
||||
|
||||
// if (uni_gp->buttons & BUTTON_A) report_in.buttons |= Gamepad::Button::A;
|
||||
// if (uni_gp->buttons & BUTTON_B) report_in.buttons |= Gamepad::Button::B;
|
||||
// if (uni_gp->buttons & BUTTON_X) report_in.buttons |= Gamepad::Button::X;
|
||||
// if (uni_gp->buttons & BUTTON_Y) report_in.buttons |= Gamepad::Button::Y;
|
||||
// if (uni_gp->buttons & BUTTON_SHOULDER_L) report_in.buttons |= Gamepad::Button::LB;
|
||||
// if (uni_gp->buttons & BUTTON_SHOULDER_R) report_in.buttons |= Gamepad::Button::RB;
|
||||
// if (uni_gp->buttons & BUTTON_THUMB_L) report_in.buttons |= Gamepad::Button::L3;
|
||||
// if (uni_gp->buttons & BUTTON_THUMB_R) report_in.buttons |= Gamepad::Button::R3;
|
||||
// if (uni_gp->misc_buttons & MISC_BUTTON_BACK) report_in.buttons |= Gamepad::Button::BACK;
|
||||
// if (uni_gp->misc_buttons & MISC_BUTTON_START) report_in.buttons |= Gamepad::Button::START;
|
||||
// if (uni_gp->misc_buttons & MISC_BUTTON_SYSTEM) report_in.buttons |= Gamepad::Button::SYS;
|
||||
// if (uni_gp->misc_buttons & MISC_BUTTON_CAPTURE) report_in.buttons |= Gamepad::Button::MISC;
|
||||
|
||||
// report_in.trigger_l = Gamepad::scale_trigger(uni_gp->brake);
|
||||
// report_in.trigger_r = Gamepad::scale_trigger(uni_gp->throttle);
|
||||
|
||||
// report_in.joystick_lx = static_cast<int16_t>(uni_gp->axis_x);
|
||||
// report_in.joystick_ly = static_cast<int16_t>(uni_gp->axis_y);
|
||||
// report_in.joystick_rx = static_cast<int16_t>(uni_gp->axis_rx);
|
||||
// report_in.joystick_ry = static_cast<int16_t>(uni_gp->axis_ry);
|
||||
|
||||
// devices_[idx].report_in.store(report_in);
|
||||
// devices_[idx].new_report_in.store(true);
|
||||
|
||||
// std::memcpy(uni_gp, &prev_uni_gp[idx], sizeof(uni_gamepad_t));
|
||||
// }
|
||||
|
||||
// const uni_property_t* get_property_cb(uni_property_idx_t idx)
|
||||
// {
|
||||
// return nullptr;
|
||||
// }
|
||||
|
||||
// uni_platform* get_driver()
|
||||
// {
|
||||
// static uni_platform driver =
|
||||
// {
|
||||
// .name = "OGXMiniW",
|
||||
// .init = init,
|
||||
// .on_init_complete = init_complete_cb,
|
||||
// .on_device_discovered = device_discovered_cb,
|
||||
// .on_device_connected = device_connected_cb,
|
||||
// .on_device_disconnected = device_disconnected_cb,
|
||||
// .on_device_ready = device_ready_cb,
|
||||
// .on_controller_data = controller_data_cb,
|
||||
// .get_property = get_property_cb,
|
||||
// .on_oob_event = oob_event_cb,
|
||||
// };
|
||||
// return &driver;
|
||||
// }
|
||||
|
||||
// //Public
|
||||
|
||||
// void run_task()
|
||||
// {
|
||||
// board_api::init_pins();
|
||||
|
||||
// btstack_init();
|
||||
|
||||
// uni_platform_set_custom(get_driver());
|
||||
// uni_init(0, nullptr);
|
||||
|
||||
// btstack_timer_source_t feedback_timer;
|
||||
// feedback_timer.process = send_feedback_cb;
|
||||
// feedback_timer.context = nullptr;
|
||||
|
||||
// btstack_run_loop_set_timer(&feedback_timer, FEEDBACK_TIME_MS);
|
||||
// btstack_run_loop_add_timer(&feedback_timer);
|
||||
|
||||
// btstack_timer_source_t led_timer;
|
||||
// led_timer.process = check_led_cb;
|
||||
// led_timer.context = nullptr;
|
||||
|
||||
// btstack_run_loop_set_timer(&led_timer, LED_TIME_MS);
|
||||
// btstack_run_loop_add_timer(&led_timer);
|
||||
|
||||
// btstack_run_loop_execute();
|
||||
// }
|
||||
|
||||
// //Thread safe
|
||||
// bool any_connected()
|
||||
// {
|
||||
// for (auto& device : devices_)
|
||||
// {
|
||||
// if (device.connected.load())
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// bool connected(uint8_t index)
|
||||
// {
|
||||
// return devices_[index].connected.load();
|
||||
// }
|
||||
|
||||
// bool get_report_in(uint8_t index, ReportIn& report)
|
||||
// {
|
||||
// if (index >= CONFIG_BLUEPAD32_MAX_DEVICES)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// if (devices_[index].new_report_in.exchange(false))
|
||||
// {
|
||||
// report = devices_[index].report_in.load();
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// void set_report_out(const ReportOut& report)
|
||||
// {
|
||||
// if (report.index >= CONFIG_BLUEPAD32_MAX_DEVICES)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
// devices_[report.index].report_out.store(report);
|
||||
// }
|
||||
|
||||
// } // namespace bluepad32
|
||||
} // namespace bluepad32
|
||||
@@ -1,149 +1,3 @@
|
||||
// #include <cstring>
|
||||
// #include <atomic>
|
||||
// #include <array>
|
||||
// #include <freertos/FreeRTOS.h>
|
||||
// #include <freertos/task.h>
|
||||
// #include <freertos/timers.h>
|
||||
// #include <driver/i2c.h>
|
||||
// #include <driver/gpio.h>
|
||||
// #include <esp_log.h>
|
||||
|
||||
// #include "sdkconfig.h"
|
||||
// #include "Board/board_api.h"
|
||||
// #include "I2CDriver/I2CDriver.h"
|
||||
// #include "Bluepad32/Bluepad32.h"
|
||||
|
||||
// namespace i2c_driver {
|
||||
|
||||
// static constexpr bool MULTI_SLAVE =
|
||||
// #if CONFIG_MULTI_SLAVE_MODE == 0
|
||||
// false;
|
||||
// #else
|
||||
// true;
|
||||
// #endif
|
||||
|
||||
// std::atomic<bool> poll_rumble_{false};
|
||||
|
||||
// void i2c_initialize()
|
||||
// {
|
||||
// i2c_config_t conf;
|
||||
// std::memset(&conf, 0, sizeof(i2c_config_t));
|
||||
// conf.mode = I2C_MODE_MASTER;
|
||||
// conf.sda_io_num = GPIO_NUM_21;
|
||||
// conf.scl_io_num = GPIO_NUM_22;
|
||||
// conf.sda_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
// conf.scl_pullup_en = GPIO_PULLUP_ENABLE;
|
||||
// conf.master.clk_speed = 400 * 1000;
|
||||
|
||||
// i2c_param_config(I2C_NUM_0, &conf);
|
||||
// i2c_driver_install(I2C_NUM_0, conf.mode, 0, 0, 0);
|
||||
|
||||
// ESP_LOGD("I2C", "I2C initialized at pins {SDA: %d, SCL: %d}", conf.sda_io_num, conf.scl_io_num);
|
||||
// }
|
||||
|
||||
// static inline esp_err_t i2c_write_blocking(uint8_t slave_address, uint8_t* data, size_t data_len)
|
||||
// {
|
||||
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
// i2c_master_start(cmd);
|
||||
// i2c_master_write_byte(cmd, (slave_address << 1) | I2C_MASTER_WRITE, true);
|
||||
// i2c_master_write(cmd, data, data_len, true);
|
||||
// i2c_master_stop(cmd);
|
||||
|
||||
// esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, pdMS_TO_TICKS(2));
|
||||
// i2c_cmd_link_delete(cmd);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// static inline esp_err_t i2c_read_blocking(uint8_t slave_address, uint8_t* data, size_t data_len)
|
||||
// {
|
||||
// i2c_cmd_handle_t cmd = i2c_cmd_link_create();
|
||||
// i2c_master_start(cmd);
|
||||
// i2c_master_write_byte(cmd, (slave_address << 1) | I2C_MASTER_READ, true);
|
||||
|
||||
// if (data_len > 1)
|
||||
// {
|
||||
// i2c_master_read(cmd, data, data_len - 1, I2C_MASTER_ACK);
|
||||
// }
|
||||
|
||||
// i2c_master_read_byte(cmd, data + data_len - 1, I2C_MASTER_NACK);
|
||||
// i2c_master_stop(cmd);
|
||||
|
||||
// esp_err_t ret = i2c_master_cmd_begin(I2C_NUM_0, cmd, pdMS_TO_TICKS(2));
|
||||
// i2c_cmd_link_delete(cmd);
|
||||
// return ret;
|
||||
// }
|
||||
|
||||
// void run_loop(void* queue)
|
||||
// {
|
||||
// ReportIn report_in = ReportIn();
|
||||
// ReportOut report_out = ReportOut();
|
||||
|
||||
// i2c_initialize();
|
||||
|
||||
// ESP_LOGD("I2C Stack", "Remaining stack: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
// while (true)
|
||||
// {
|
||||
// for (uint8_t i = 0; i < CONFIG_BLUEPAD32_MAX_DEVICES; ++i)
|
||||
// {
|
||||
// vTaskDelay(1);
|
||||
|
||||
// if (!bluepad32::connected(i))
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// report_in = bluepad32::get_report_in(i);
|
||||
// if (i2c_write_blocking(MULTI_SLAVE ? (report_in.index + 1) : 0x01, reinterpret_cast<uint8_t*>(&report_in), sizeof(ReportIn)) != ESP_OK)
|
||||
// {
|
||||
// ESP_LOGD("I2C", "Failed to write report_in");
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// vTaskDelay(1);
|
||||
|
||||
// if (i2c_read_blocking(MULTI_SLAVE ? (report_in.index + 1) : 0x01, reinterpret_cast<uint8_t*>(&report_out), sizeof(ReportOut)) != ESP_OK)
|
||||
// {
|
||||
// ESP_LOGD("I2C", "Failed to read report_out");
|
||||
// continue;
|
||||
// }
|
||||
|
||||
// bluepad32::set_report_out(report_out);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// // void run_loop()
|
||||
// // {
|
||||
// // ESP_LOGD("Stack", "Remaining stack: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
// // ReportIn report_in = ReportIn();
|
||||
|
||||
// // ESP_LOGD("I2C", "ReportIn 1 created: size: %d", sizeof(report_in));
|
||||
// // ESP_LOGD("Stack", "Remaining stack: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
// // ReportIn different_rep = ReportIn();
|
||||
|
||||
// // ESP_LOGD("I2C", "ReportIn 2 created: size: %d", sizeof(different_rep));
|
||||
// // ESP_LOGD("Stack", "Remaining stack: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
// // ReportOut report_out = ReportOut();
|
||||
|
||||
// // ESP_LOGD("I2C", "ReportOut created: size: %d", sizeof(report_out));
|
||||
// // ESP_LOGD("Stack", "Remaining stack: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
// // i2c_initialize();
|
||||
// // ESP_LOGD("Stack", "Remaining stack: %d", uxTaskGetStackHighWaterMark(NULL));
|
||||
|
||||
// // while (true)
|
||||
// // {
|
||||
// // i2c_write_blocking(MULTI_SLAVE ? (report_in.index + 1) : 0x01, reinterpret_cast<uint8_t*>(&report_in), sizeof(ReportIn));
|
||||
// // vTaskDelay(1);
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// } // namespace I2CDriver
|
||||
|
||||
#include <array>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
@@ -186,14 +40,12 @@ void I2CDriver::run_task()
|
||||
vTaskDelay(1);
|
||||
continue;
|
||||
}
|
||||
// if (bluepad32::get_report_in(i, report_in))
|
||||
// {
|
||||
|
||||
report_in = bluepad32::get_report_in(i);
|
||||
if (i2c_write_blocking(MULTI_SLAVE ? (i + 1) : 0x01, reinterpret_cast<const uint8_t*>(&report_in), sizeof(ReportIn)) != ESP_OK)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// }
|
||||
|
||||
vTaskDelay(1);
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include "Reports.h"
|
||||
|
||||
//Will probably refactor this to be event driven
|
||||
class I2CDriver
|
||||
{
|
||||
public:
|
||||
@@ -23,6 +24,9 @@ private:
|
||||
#else
|
||||
true;
|
||||
#endif
|
||||
// std::array<ReportIn, CONFIG_BLUEPAD32_MAX_DEVICES> report_in_buffer_{};
|
||||
// std::array<std::atomic<bool>, CONFIG_BLUEPAD32_MAX_DEVICES> new_report_in_{false};
|
||||
// std::array<ReportOut, CONFIG_BLUEPAD32_MAX_DEVICES> report_out_buffer_{};
|
||||
|
||||
void initialize_i2c();
|
||||
|
||||
|
||||
@@ -1383,19 +1383,20 @@ CONFIG_HEAP_TRACING_OFF=y
|
||||
#
|
||||
# Log output
|
||||
#
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_NONE is not set
|
||||
CONFIG_LOG_DEFAULT_LEVEL_ERROR=y
|
||||
CONFIG_LOG_DEFAULT_LEVEL_NONE=y
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_ERROR is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_WARN is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_INFO is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_DEBUG is not set
|
||||
# CONFIG_LOG_DEFAULT_LEVEL_VERBOSE is not set
|
||||
CONFIG_LOG_DEFAULT_LEVEL=1
|
||||
CONFIG_LOG_DEFAULT_LEVEL=0
|
||||
CONFIG_LOG_MAXIMUM_EQUALS_DEFAULT=y
|
||||
# CONFIG_LOG_MAXIMUM_LEVEL_ERROR is not set
|
||||
# CONFIG_LOG_MAXIMUM_LEVEL_WARN is not set
|
||||
# CONFIG_LOG_MAXIMUM_LEVEL_INFO is not set
|
||||
# CONFIG_LOG_MAXIMUM_LEVEL_DEBUG is not set
|
||||
# CONFIG_LOG_MAXIMUM_LEVEL_VERBOSE is not set
|
||||
CONFIG_LOG_MAXIMUM_LEVEL=1
|
||||
CONFIG_LOG_MAXIMUM_LEVEL=0
|
||||
CONFIG_LOG_COLORS=y
|
||||
CONFIG_LOG_TIMESTAMP_SOURCE_RTOS=y
|
||||
# CONFIG_LOG_TIMESTAMP_SOURCE_SYSTEM is not set
|
||||
|
||||
@@ -272,16 +272,13 @@ uni_platform* get_driver()
|
||||
|
||||
//Public API
|
||||
|
||||
void initialize(std::array<Gamepad, MAX_GAMEPADS>& gamepads)
|
||||
void run_task(std::array<Gamepad, MAX_GAMEPADS>& gamepads)
|
||||
{
|
||||
for (uint8_t i = 0; i < MAX_GAMEPADS; ++i)
|
||||
{
|
||||
devices_[i].gamepad = &gamepads[i];
|
||||
}
|
||||
}
|
||||
|
||||
void run_loop()
|
||||
{
|
||||
uni_platform_set_custom(get_driver());
|
||||
uni_init(0, nullptr);
|
||||
|
||||
|
||||
@@ -11,10 +11,9 @@
|
||||
/* NOTE: Everything bluepad32/uni needs to be wrapped
|
||||
and kept away from tinyusb due to naming conflicts */
|
||||
|
||||
namespace bluepad32 {
|
||||
|
||||
void initialize(std::array<Gamepad, MAX_GAMEPADS>& gamepads);
|
||||
void run_loop();
|
||||
namespace bluepad32
|
||||
{
|
||||
void run_task(std::array<Gamepad, MAX_GAMEPADS>& gamepads);
|
||||
std::array<bool, MAX_GAMEPADS> get_connected_map();
|
||||
bool any_connected();
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ static constexpr size_t MAX_BUFFER_SIZE = std::max(sizeof(ReportOut), sizeof(Rep
|
||||
static constexpr uint8_t I2C_ADDR = 0x01;
|
||||
|
||||
std::array<Gamepad*, MAX_GAMEPADS> gamepads_{nullptr};
|
||||
std::atomic<bool> pad_connected_ = false;
|
||||
// std::atomic<bool> pad_connected_ = false;
|
||||
|
||||
inline void process_in_report(ReportIn* report_in)
|
||||
{
|
||||
@@ -174,108 +174,9 @@ void initialize(std::array<Gamepad, MAX_GAMEPADS>& gamepad)
|
||||
i2c_slave_init(I2C_PORT, I2C_ADDR, &slave_handler);
|
||||
}
|
||||
|
||||
bool pad_connected()
|
||||
{
|
||||
return pad_connected_.load();
|
||||
}
|
||||
|
||||
} // namespace i2c_driver_esp
|
||||
|
||||
// #include <array>
|
||||
// #include <cstring>
|
||||
// #include <pico/i2c_slave.h>
|
||||
// #include <hardware/gpio.h>
|
||||
// #include <hardware/i2c.h>
|
||||
|
||||
// #include "Gamepad.h"
|
||||
// #include "board_config.h"
|
||||
// #include "Board/board_api.h"
|
||||
// #include "I2CDriver/I2CDriver_ESP.h"
|
||||
|
||||
// namespace i2c_driver_esp {
|
||||
|
||||
// #pragma pack(push, 1)
|
||||
// struct ReportIn
|
||||
// bool pad_connected()
|
||||
// {
|
||||
// uint8_t dpad;
|
||||
// uint16_t buttons;
|
||||
// uint8_t trigger_l;
|
||||
// uint8_t trigger_r;
|
||||
// int16_t joystick_lx;
|
||||
// int16_t joystick_ly;
|
||||
// int16_t joystick_rx;
|
||||
// int16_t joystick_ry;
|
||||
|
||||
// ReportIn()
|
||||
// {
|
||||
// std::memset(this, 0, sizeof(ReportIn));
|
||||
// }
|
||||
// };
|
||||
// static_assert(sizeof(ReportIn) == 13, "i2c_driver_esp::ReportIn size mismatch");
|
||||
|
||||
// struct ReportOut
|
||||
// {
|
||||
// uint8_t rumble_l;
|
||||
// uint8_t rumble_r;
|
||||
|
||||
// ReportOut()
|
||||
// {
|
||||
// std::memset(this, 0, sizeof(ReportOut));
|
||||
// }
|
||||
// };
|
||||
// static_assert(sizeof(ReportOut) == 2, "i2c_driver_esp::ReportOut size mismatch");
|
||||
// #pragma pack(pop)
|
||||
|
||||
// static constexpr uint8_t I2C_ADDR = 0x50;
|
||||
|
||||
// Gamepad* gamepad_ = nullptr;
|
||||
|
||||
// inline void get_in_report()
|
||||
// {
|
||||
// static ReportIn report_in = ReportIn();
|
||||
// int count = i2c_read_timeout_us(I2C_PORT, I2C_ADDR, reinterpret_cast<uint8_t*>(&report_in), sizeof(ReportIn), false, 1000);
|
||||
// if (count > 0)
|
||||
// {
|
||||
// gamepad_->set_buttons(report_in.buttons);
|
||||
// gamepad_->set_dpad(report_in.dpad);
|
||||
// gamepad_->set_trigger_l(report_in.trigger_l);
|
||||
// gamepad_->set_trigger_r(report_in.trigger_r);
|
||||
// gamepad_->set_joystick_lx_int10(report_in.joystick_lx);
|
||||
// gamepad_->set_joystick_ly_int10(report_in.joystick_ly);
|
||||
// gamepad_->set_joystick_rx_int10(report_in.joystick_rx);
|
||||
// gamepad_->set_joystick_ry_int10(report_in.joystick_ry);
|
||||
// }
|
||||
// return pad_connected_.load();
|
||||
// }
|
||||
|
||||
// inline void set_out_report()
|
||||
// {
|
||||
// static ReportOut report_out = ReportOut();
|
||||
// report_out.rumble_l = gamepad_->get_rumble_l().uint8();
|
||||
// report_out.rumble_r = gamepad_->get_rumble_r().uint8();
|
||||
// i2c_write_timeout_us(I2C_PORT, I2C_ADDR, reinterpret_cast<uint8_t*>(&report_out), sizeof(ReportOut), false, 1000);
|
||||
// }
|
||||
|
||||
// void initialize(std::array<Gamepad, MAX_GAMEPADS>& gamepad)
|
||||
// {
|
||||
// gamepad_ = &gamepad[0];
|
||||
|
||||
// i2c_init(I2C_PORT, I2C_BAUDRATE);
|
||||
|
||||
// gpio_init(I2C_SDA_PIN);
|
||||
// gpio_set_function(I2C_SDA_PIN, GPIO_FUNC_I2C);
|
||||
// gpio_pull_up(I2C_SDA_PIN);
|
||||
|
||||
// gpio_init(I2C_SCL_PIN);
|
||||
// gpio_set_function(I2C_SCL_PIN, GPIO_FUNC_I2C);
|
||||
// gpio_pull_up(I2C_SCL_PIN);
|
||||
// }
|
||||
|
||||
// void task()
|
||||
// {
|
||||
// get_in_report();
|
||||
// sleep_us(100);
|
||||
// // set_out_report();
|
||||
// // sleep_us(100);
|
||||
// }
|
||||
|
||||
// } // namespace i2c_driver_esp
|
||||
} // namespace i2c_driver_esp32
|
||||
@@ -8,7 +8,7 @@
|
||||
namespace i2c_driver_esp32
|
||||
{
|
||||
void initialize(std::array<Gamepad, MAX_GAMEPADS>& gamepad);
|
||||
bool pad_connected();
|
||||
// bool pad_connected();
|
||||
}
|
||||
|
||||
#endif // _I2CDRIVER_ESP_H_
|
||||
@@ -13,79 +13,24 @@
|
||||
#include "USBDevice/DeviceManager.h"
|
||||
#include "Board/board_api.h"
|
||||
#include "OGXMini/OGXMini.h"
|
||||
#include "I2CDriver/I2CDriver_ESP.h"
|
||||
#include "I2CDriver/i2c_driver_esp32.h"
|
||||
#include "Gamepad.h"
|
||||
|
||||
namespace OGXMini {
|
||||
|
||||
std::array<Gamepad, MAX_GAMEPADS> gamepads_;
|
||||
|
||||
// void init_esp32_gpio()
|
||||
// {
|
||||
// gpio_init(ESP_PROG_PIN);
|
||||
// gpio_set_dir(ESP_PROG_PIN, GPIO_IN);
|
||||
// gpio_pull_up(ESP_PROG_PIN);
|
||||
|
||||
// gpio_init(ESP_RST_PIN);
|
||||
// gpio_set_dir(ESP_RST_PIN, GPIO_IN);
|
||||
// gpio_pull_up(ESP_RST_PIN);
|
||||
// }
|
||||
|
||||
// bool uart_passthrough_mode()
|
||||
// {
|
||||
// gpio_init(MODE_SEL_PIN);
|
||||
// gpio_set_dir(MODE_SEL_PIN, GPIO_IN);
|
||||
// gpio_pull_up(MODE_SEL_PIN);
|
||||
|
||||
// if (gpio_get(MODE_SEL_PIN) == 0)
|
||||
// {
|
||||
// return true;
|
||||
// }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// void reset_esp32()
|
||||
// {
|
||||
// gpio_init(ESP_RST_PIN);
|
||||
// gpio_set_dir(ESP_RST_PIN, GPIO_OUT);
|
||||
// gpio_put(ESP_RST_PIN, 0);
|
||||
// sleep_ms(500);
|
||||
// gpio_put(ESP_RST_PIN, 1);
|
||||
// sleep_ms(250);
|
||||
// }
|
||||
|
||||
// void reset_esp32()
|
||||
// {
|
||||
// gpio_init(ESP_PROG_PIN);
|
||||
// gpio_set_dir(ESP_PROG_PIN, GPIO_OUT);
|
||||
// gpio_put(ESP_PROG_PIN, 1);
|
||||
|
||||
// gpio_init(ESP_RST_PIN);
|
||||
// gpio_set_dir(ESP_RST_PIN, GPIO_OUT);
|
||||
// gpio_put(ESP_PROG_PIN, 1);
|
||||
|
||||
// gpio_put(ESP_PROG_PIN, 0);
|
||||
// sleep_ms(250);
|
||||
|
||||
// gpio_put(ESP_RST_PIN, 0);
|
||||
// sleep_ms(500);
|
||||
// gpio_put(ESP_RST_PIN, 1);
|
||||
// sleep_ms(250);
|
||||
// gpio_put(ESP_PROG_PIN, 1);
|
||||
// }
|
||||
|
||||
void run_esp32_uart_bridge()
|
||||
{
|
||||
DeviceManager& device_manager = DeviceManager::get_instance();
|
||||
device_manager.initialize_driver(DeviceDriver::Type::UART_BRIDGE);
|
||||
board_api::enter_esp32_prog_mode();
|
||||
// reset_esp32();
|
||||
device_manager.get_driver()->process(0, gamepads_.front()); //Runs UART Bridge task
|
||||
}
|
||||
|
||||
void core1_task()
|
||||
{
|
||||
i2c_driver_esp::initialize(gamepads_);
|
||||
i2c_driver_esp32::initialize(gamepads_);
|
||||
|
||||
while (true)
|
||||
{
|
||||
@@ -107,10 +52,7 @@ void run_program()
|
||||
|
||||
board_api::init_gpio();
|
||||
|
||||
// init_esp32_gpio();
|
||||
|
||||
if (board_api::uart_bridge_mode())
|
||||
// if (uart_passthrough_mode())
|
||||
{
|
||||
run_esp32_uart_bridge();
|
||||
return;
|
||||
@@ -119,8 +61,6 @@ void run_program()
|
||||
// {
|
||||
// user_settings.write_firmware_version();
|
||||
// }
|
||||
|
||||
// user_settings.initialize_flash();
|
||||
|
||||
board_init();
|
||||
|
||||
@@ -130,18 +70,16 @@ void run_program()
|
||||
}
|
||||
|
||||
DeviceManager& device_manager = DeviceManager::get_instance();
|
||||
// device_manager.initialize_driver(user_settings.get_current_driver());
|
||||
device_manager.initialize_driver(DeviceDriver::Type::XINPUT);
|
||||
device_manager.initialize_driver(user_settings.get_current_driver());
|
||||
|
||||
multicore_reset_core1();
|
||||
multicore_launch_core1(core1_task);
|
||||
|
||||
board_api::reset_esp32();
|
||||
// reset_esp32();
|
||||
|
||||
// GPCheckContext gp_check_ctx = { false, user_settings };
|
||||
// repeating_timer_t gp_check_timer;
|
||||
// add_repeating_timer_ms(UserSettings::GP_CHECK_DELAY_MS, gp_check_cb, &gp_check_ctx, &gp_check_timer);
|
||||
GPCheckContext gp_check_ctx = { false, user_settings };
|
||||
repeating_timer_t gp_check_timer;
|
||||
add_repeating_timer_ms(UserSettings::GP_CHECK_DELAY_MS, gp_check_cb, &gp_check_ctx, &gp_check_timer);
|
||||
|
||||
DeviceDriver* device_driver = device_manager.get_driver();
|
||||
|
||||
@@ -154,16 +92,14 @@ void run_program()
|
||||
device_driver->process(i, gamepads_[i]);
|
||||
tud_task();
|
||||
}
|
||||
// device_driver->process(0, gamepads_.front());
|
||||
// tud_task();
|
||||
|
||||
sleep_us(100);
|
||||
|
||||
// if (gp_check_ctx.driver_changed)
|
||||
// {
|
||||
// cancel_repeating_timer(&gp_check_timer);
|
||||
// user_settings.store_driver_type_safe(user_settings.get_current_driver());
|
||||
// }
|
||||
if (gp_check_ctx.driver_changed)
|
||||
{
|
||||
cancel_repeating_timer(&gp_check_timer);
|
||||
user_settings.store_driver_type_safe(user_settings.get_current_driver());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
#if (OGXM_BOARD == PI_PICOW)
|
||||
|
||||
#include <array>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <pico/multicore.h>
|
||||
#include <hardware/gpio.h>
|
||||
#include <hardware/clocks.h>
|
||||
@@ -28,8 +26,7 @@ void core1_task()
|
||||
return;
|
||||
}
|
||||
|
||||
bluepad32::initialize(gamepads_);
|
||||
bluepad32::run_loop();
|
||||
bluepad32::run_task(gamepads_);
|
||||
}
|
||||
|
||||
bool gp_check_cb(repeating_timer_t* rt)
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
#include <array>
|
||||
|
||||
#include "tusb_option.h"
|
||||
#include "tusb.h"
|
||||
#include "host/usbh.h"
|
||||
#include "host/usbh_pvt.h"
|
||||
#include "class/hid/hid_host.h"
|
||||
|
||||
#include "USBHost/HostDriver/tuh_uni/tuh_uni.h"
|
||||
@@ -11,44 +14,63 @@ namespace tuh_uni {
|
||||
enum class HostType { UNKNOWN = 0, HID, XINPUT };
|
||||
|
||||
static std::array<HostType, CFG_TUH_DEVICE_MAX> host_type_;
|
||||
// const usbh_class_driver_t* xinput_class_driver_ = nullptr;
|
||||
const usbh_class_driver_t* xinput_class_driver_ = nullptr;
|
||||
|
||||
static inline HostType& get_host_type(uint8_t dev_addr)
|
||||
{
|
||||
return host_type_[dev_addr - 1];
|
||||
}
|
||||
|
||||
bool init()
|
||||
{
|
||||
host_type_.fill(HostType::UNKNOWN);
|
||||
hidh_init();
|
||||
tuh_xinput::class_driver()->init();
|
||||
xinput_class_driver_ = tuh_xinput::class_driver();
|
||||
xinput_class_driver_->init();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool deinit()
|
||||
{
|
||||
hidh_deinit();
|
||||
tuh_xinput::class_driver()->deinit();
|
||||
xinput_class_driver_->deinit();
|
||||
host_type_.fill(HostType::UNKNOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const* desc_itf, uint16_t max_len)
|
||||
{
|
||||
if (tuh_xinput::class_driver()->open(rhport, dev_addr, desc_itf, max_len))
|
||||
HostType& host_type = get_host_type(dev_addr);
|
||||
switch (host_type)
|
||||
{
|
||||
host_type_[dev_addr - 1] = HostType::XINPUT;
|
||||
return true;
|
||||
case HostType::HID:
|
||||
return hidh_open(rhport, dev_addr, desc_itf, max_len);
|
||||
case HostType::XINPUT:
|
||||
return xinput_class_driver_->open(rhport, dev_addr, desc_itf, max_len);
|
||||
default:
|
||||
if (xinput_class_driver_->open(rhport, dev_addr, desc_itf, max_len))
|
||||
{
|
||||
host_type = HostType::XINPUT;
|
||||
return true;
|
||||
}
|
||||
else if (hidh_open(rhport, dev_addr, desc_itf, max_len))
|
||||
{
|
||||
host_type = HostType::HID;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
host_type_[dev_addr - 1] = HostType::HID;
|
||||
return hidh_open(rhport, dev_addr, desc_itf, max_len);;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool set_config(uint8_t dev_addr, uint8_t itf_num)
|
||||
{
|
||||
switch (host_type_[dev_addr - 1])
|
||||
switch (get_host_type(dev_addr))
|
||||
{
|
||||
case HostType::HID:
|
||||
return hidh_set_config(dev_addr, itf_num);
|
||||
case HostType::XINPUT:
|
||||
return tuh_xinput::class_driver()->set_config(dev_addr, itf_num);
|
||||
return xinput_class_driver_->set_config(dev_addr, itf_num);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -56,12 +78,12 @@ bool set_config(uint8_t dev_addr, uint8_t itf_num)
|
||||
|
||||
bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes)
|
||||
{
|
||||
switch (host_type_[dev_addr - 1])
|
||||
switch (get_host_type(dev_addr))
|
||||
{
|
||||
case HostType::HID:
|
||||
return hidh_xfer_cb(dev_addr, ep_addr, result, xferred_bytes);
|
||||
case HostType::XINPUT:
|
||||
return tuh_xinput::class_driver()->xfer_cb(dev_addr, ep_addr, result, xferred_bytes);
|
||||
return xinput_class_driver_->xfer_cb(dev_addr, ep_addr, result, xferred_bytes);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -69,17 +91,19 @@ bool xfer_cb(uint8_t dev_addr, uint8_t ep_addr, xfer_result_t result, uint32_t x
|
||||
|
||||
void close(uint8_t dev_addr)
|
||||
{
|
||||
switch (host_type_[dev_addr - 1])
|
||||
HostType& host_type = get_host_type(dev_addr);
|
||||
switch (host_type)
|
||||
{
|
||||
case HostType::HID:
|
||||
hidh_close(dev_addr);
|
||||
break;
|
||||
case HostType::XINPUT:
|
||||
tuh_xinput::class_driver()->close(dev_addr);
|
||||
xinput_class_driver_->close(dev_addr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
host_type = HostType::UNKNOWN;
|
||||
}
|
||||
|
||||
const usbh_class_driver_t* class_driver()
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include <cstdint>
|
||||
|
||||
#include "tusb.h"
|
||||
#include "host/usbh.h"
|
||||
#include "host/usbh_pvt.h"
|
||||
|
||||
/* This solves a conflict with tinyusb using multiple host class drivers */
|
||||
/* There seems to be a conflict with tinyusb using multiple host class drivers */
|
||||
namespace tuh_uni
|
||||
{
|
||||
const usbh_class_driver_t* class_driver();
|
||||
|
||||
@@ -175,14 +175,14 @@ public:
|
||||
{
|
||||
for (auto& host_slot : host_slots_)
|
||||
{
|
||||
// if (host_slot.driver_class == driver_class && host_slot.address == address)
|
||||
// {
|
||||
// host_slot.reset();
|
||||
// }
|
||||
if (host_slot.address == address)
|
||||
if (host_slot.driver_class == driver_class && host_slot.address == address)
|
||||
{
|
||||
host_slot.reset();
|
||||
}
|
||||
// if (host_slot.address == address)
|
||||
// {
|
||||
// host_slot.reset();
|
||||
// }
|
||||
}
|
||||
|
||||
if (OGXMini::update_tuh_status)
|
||||
|
||||
@@ -31,10 +31,6 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
|
||||
tuh_vid_pid_get(dev_addr, &vid, &pid);
|
||||
|
||||
HostManager& host_manager = HostManager::get_instance();
|
||||
// if (host_manager.setup_driver(HostDriver::Type::HID_GENERIC, dev_addr, instance, desc_report, desc_len))
|
||||
// {
|
||||
// }
|
||||
|
||||
if (host_manager.setup_driver(HostManager::get_type({ vid, pid }), dev_addr, instance, desc_report, desc_len))
|
||||
{
|
||||
#if defined(CONFIG_EN_4CH)
|
||||
|
||||
8
LICENSE
8
LICENSE
@@ -1,5 +1,11 @@
|
||||
MIT License
|
||||
|
||||
Note: Wired configurations of this project exclusively contain MIT licensed
|
||||
code, configurations using Bluetooth libraries/functionality are licensed
|
||||
under Apache 2.0 (Bluepad32) and BTStack's proprietary (non-commercial)
|
||||
license. For full details, please refer to the repositories contained in the
|
||||
Firmware/external directory of this project.
|
||||
|
||||
Copyright (c) 2024 wiredOpposite (wiredopposite.com)
|
||||
Copyright (c) 2024 OpenStickCommunity (gp2040-ce.info)
|
||||
Copyright (c) 2021 Jason Skuby (mytechtoybox.com)
|
||||
@@ -21,4 +27,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
50
README.md
50
README.md
@@ -1,13 +1,13 @@
|
||||
# OGX-Mini
|
||||

|
||||
|
||||
Firmware for the RP2040, capable of emulating gamepads for several consoles. The firmware now comes in 3 flavors, for the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), the Pi Pico, and the Waveshare RP2040-Zero.
|
||||
Firmware for the RP2040, capable of emulating gamepads for several game consoles. The firmware comes in 6 flavors, the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), Pi Pico, Waveshare RP2040-Zero, Pi Pico W, RP2040/ESP32 hybrid, and 4-Channel RP2040-Zero.
|
||||
|
||||
## Supported platforms
|
||||
- Original Xbox
|
||||
- Playstation 3
|
||||
- Nintendo Switch (docked)
|
||||
- XInput (not Xbox 360)
|
||||
- XInput (use [UsbdSecPatch](https://github.com/InvoxiPlayGames/UsbdSecPatch) for Xbox 360)
|
||||
- Playstation Classic
|
||||
|
||||
## Supported devices
|
||||
@@ -16,19 +16,31 @@ Firmware for the RP2040, capable of emulating gamepads for several consoles. The
|
||||
- Xbox 360, One, Series, and Elite
|
||||
- Dualshock 3 (PS3)
|
||||
- Dualshock 4 (PS4)
|
||||
- Dualsense (PS5, Dualsense Edge should work but it's untested)
|
||||
- Dualsense (PS5)
|
||||
- Nintendo Switch Pro
|
||||
- Nintendo Switch wired (tested with PowerA brand)
|
||||
- Nintendo 64 USB (experimental, tested with RetroLink brand)
|
||||
- Nintendo Switch wired
|
||||
- Nintendo 64 Generic USB
|
||||
- Playstation Classic
|
||||
- Generic DInput
|
||||
- Generic HID (Limited)
|
||||
|
||||
Note: There are some third party controllers that can change their VID/PID, these might not work correctly.
|
||||
|
||||
### Wireless adapters
|
||||
- Xbox 360 PC adapter (Microsoft or clones, syncs 1 controller)
|
||||
- 8Bitdo v1 and v2 Bluetooth adapters (set to XInput mode)
|
||||
- Most wireless adapters that present themselves as Switch/XInput/PlayStation controllers should work
|
||||
|
||||
Note: There are some third party controllers that can change their VID/PID, these might not work correctly.
|
||||
### Wireless Bluetooth controllers (Pico W & ESP32)
|
||||
Note: Bluetooth functionality is in early testing, some may have quirks.
|
||||
- Xbox Series, One, and Elite 2
|
||||
- Dualshock 3
|
||||
- Dualshock 4
|
||||
- Dualsense
|
||||
- Switch Pro
|
||||
- Steam
|
||||
- Stadia
|
||||
Please visit [this page](https://bluepad32.readthedocs.io/en/latest/supported_gamepads/) for a more comprehensive list of supported controllers.
|
||||
|
||||
## Changing input mode
|
||||
By default the input mode is set to OG Xbox, you must hold a button combo for 3 seconds to change which platform you want to play on. Your chosen input mode will persist after powering off the device.
|
||||
@@ -48,28 +60,30 @@ Start + A (Cross for PlayStation and B for Switch gamepads)
|
||||
|
||||
After a new mode is stored, the RP2040 will reset itself so you don't need to unplug it.
|
||||
|
||||
## Features new to v1.0.0
|
||||
- Web application for configuring deadzones and buttons mappings, supports up to 8 saved configurations.
|
||||
- Bluetooth functionality for the Pico W and ESP32 (in combination with an RP2040).
|
||||
- 4 channel functionality, connect 4 Picos via I2C and use your Xbox 360 wireless adapter.
|
||||
- Delayed USB mount until a controller is plugged in, useful for internal installation.
|
||||
- Generic HID controller support.
|
||||
- Steel Battalion controller emulation with a wireless Xbox 360 chatpad.
|
||||
- Xbox DVD dongle emulation.
|
||||
|
||||
## Hardware
|
||||
For the Pi Pico, RP2040-Zero, 4 channel, and ESP32 configurations, please see the hardware folder for diagrams.
|
||||
|
||||
I've designed a PCB for the RP2040-Zero so you can make a small form-factor adapter yourself. The gerber files, schematic, and BOM are in Hardware folder.
|
||||
|
||||

|
||||
|
||||
If you would like a prebuilt unit, you can purchase one, with cable and Xbox adapter included, from my website [wiredopposite.com](https://wiredopposite.com/product/ogx-mini-controller-adapter-for-original-xbox-playstation-3-and-switch-ogx360/) or my [Etsy store](https://www.etsy.com/listing/1426992904/ogx-mini-controller-adapter-for-original).
|
||||
|
||||
For the Pi Pico, this is a diagram of how you'd connect the extra USB port:
|
||||
|
||||

|
||||
|
||||
For the [Adafruit Feather USB Host board](https://www.adafruit.com/product/5723), no extra work is needed.
|
||||
If you would like a prebuilt unit, you can purchase one, with cable and Xbox adapter included, from my [Etsy store](https://www.etsy.com/listing/1426992904/ogx-mini-controller-adapter-for-original).
|
||||
|
||||
## Adding supported controllers
|
||||
If your third party controller isn't working, but the original version is listed above, send me the device's VID and PID and I'll add it so it's recognized properly.
|
||||
|
||||
## Compiling
|
||||
You can compile this for different boards by changing USBD_BOARD in the usbd_config.h file, you can also adjust USBD_MAX_GAMEPADS to enable more controllers on PlayStation 3 (this is experimental).
|
||||
You can compile this for different boards with CMake arguments while configuring the project.
|
||||
|
||||
Choosing OGXM_PI_PICO will set the D+ and D- host pins to GPIO 0 and 1.
|
||||
|
||||
You can also choose OGXM_RPZERO_INTERPOSER for the RP2040-Zero and that will set D+ and D- to GPIO 10 and 11, so connecting a USB port is easier. You can still use the Pi Pico firmware on the RP2040-Zero (the other way around has not been tested though).
|
||||
|
||||
## Special thanks
|
||||
Thank you to Ryzee119 and the OpenStickCommunity, without their work this project would not exist.
|
||||
You can also choose OGXM_RPZERO_INTERPOSER for the RP2040-Zero and that will set D+ and D- to GPIO 10 and 11, so connecting a USB port is easier. You can still use the Pi Pico firmware on the RP2040-Zero (the other way around has not been tested though).
|
||||
Reference in New Issue
Block a user