Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add Xbox gamepad driver component to SDK #1

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions components/usb/cherryusb/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ sdk_add_include_directories(osal)
sdk_add_include_directories(core)
sdk_add_include_directories(class/cdc)
sdk_add_include_directories(class/hid)
sdk_add_include_directories(class/xbox)
sdk_add_include_directories(class/msc)
sdk_add_include_directories(class/audio)
sdk_add_include_directories(class/video)
Expand Down Expand Up @@ -54,6 +55,7 @@ sdk_library_add_sources(class/hid/usbh_hid.c)
sdk_library_add_sources(class/hub/usbh_hub.c)
sdk_library_add_sources(class/video/usbh_video.c)
sdk_library_add_sources(class/audio/usbh_audio.c)
sdk_library_add_sources(class/vendor/xbox/usbh_xbox.c)

if(CONFIG_CHERRYUSB_HOST_ECM)
sdk_library_add_sources(class/cdc/usbh_cdc_ecm.c)
Expand Down
121 changes: 121 additions & 0 deletions components/usb/cherryusb/class/vendor/xbox/usbh_xbox.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2024 Till Harbaum
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbh_core.h"
#include "usbh_xbox.h"

#define DEV_FORMAT "/dev/xbox%d"

USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t g_xbox_buf[128];

static struct usbh_xbox g_xbox_class[CONFIG_USBHOST_MAX_XBOX_CLASS];
static uint32_t g_devinuse = 0;

static struct usbh_xbox *usbh_xbox_class_alloc(void)
{
int devno;

for (devno = 0; devno < CONFIG_USBHOST_MAX_XBOX_CLASS; devno++) {
if ((g_devinuse & (1 << devno)) == 0) {
g_devinuse |= (1 << devno);
memset(&g_xbox_class[devno], 0, sizeof(struct usbh_xbox));
g_xbox_class[devno].minor = devno;
return &g_xbox_class[devno];
}
}
return NULL;
}

static void usbh_xbox_class_free(struct usbh_xbox *xbox_class)
{
int devno = xbox_class->minor;

if (devno >= 0 && devno < 32) {
g_devinuse &= ~(1 << devno);
}
memset(xbox_class, 0, sizeof(struct usbh_xbox));
}

int usbh_xbox_connect(struct usbh_hubport *hport, uint8_t intf)
{
struct usb_endpoint_descriptor *ep_desc;

struct usbh_xbox *xbox_class = usbh_xbox_class_alloc();
if (xbox_class == NULL) {
USB_LOG_ERR("Fail to alloc xbox_class\r\n");
return -USB_ERR_NOMEM;
}

xbox_class->hport = hport;
xbox_class->intf = intf;

hport->config.intf[intf].priv = xbox_class;

for (uint8_t i = 0; i < hport->config.intf[intf].altsetting[0].intf_desc.bNumEndpoints; i++) {
ep_desc = &hport->config.intf[intf].altsetting[0].ep[i].ep_desc;
if (ep_desc->bEndpointAddress & 0x80) {
USBH_EP_INIT(xbox_class->intin, ep_desc);
} else {
USBH_EP_INIT(xbox_class->intout, ep_desc);
}
}

snprintf(hport->config.intf[intf].devname, CONFIG_USBHOST_DEV_NAMELEN, DEV_FORMAT, xbox_class->minor);

USB_LOG_INFO("Register XBOX Class:%s\r\n", hport->config.intf[intf].devname);

usbh_xbox_run(xbox_class);
return 0;
}

int usbh_xbox_disconnect(struct usbh_hubport *hport, uint8_t intf)
{
int ret = 0;

struct usbh_xbox *xbox_class = (struct usbh_xbox *)hport->config.intf[intf].priv;

if (xbox_class) {
if (xbox_class->intin) {
usbh_kill_urb(&xbox_class->intin_urb);
}

if (xbox_class->intout) {
usbh_kill_urb(&xbox_class->intout_urb);
}

if (hport->config.intf[intf].devname[0] != '\0') {
USB_LOG_INFO("Unregister XBOX Class:%s\r\n", hport->config.intf[intf].devname);
usbh_xbox_stop(xbox_class);
}

usbh_xbox_class_free(xbox_class);
}

return ret;
}

__WEAK void usbh_xbox_run(struct usbh_xbox *xbox_class)
{
}

__WEAK void usbh_xbox_stop(struct usbh_xbox *xbox_class)
{
}

const struct usbh_class_driver xbox_class_driver = {
.driver_name = "xbox",
.connect = usbh_xbox_connect,
.disconnect = usbh_xbox_disconnect
};

CLASS_INFO_DEFINE const struct usbh_class_info xbox_custom_class_info = {
.match_flags = USB_CLASS_MATCH_INTF_CLASS| USB_CLASS_MATCH_INTF_SUBCLASS | USB_CLASS_MATCH_INTF_PROTOCOL,
.class = USB_DEVICE_CLASS_VEND_SPECIFIC,
.subclass = 0x5d,
.protocol = 0x01,
.vid = 0x00,
.pid = 0x00,
.class_driver = &xbox_class_driver
};
31 changes: 31 additions & 0 deletions components/usb/cherryusb/class/vendor/xbox/usbh_xbox.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* Copyright (c) 2024, Till Harbaum
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef USBH_XBOX_H
#define USBH_XBOX_H

struct usbh_xbox {
struct usbh_hubport *hport;
struct usb_endpoint_descriptor *intin; /* INTR IN endpoint */
struct usb_endpoint_descriptor *intout; /* INTR OUT endpoint */
struct usbh_urb intin_urb; /* INTR IN urb */
struct usbh_urb intout_urb; /* INTR OUT urb */

uint8_t intf; /* interface number */
uint8_t minor;
};

#ifdef __cplusplus
extern "C" {
#endif

void usbh_xbox_run(struct usbh_xbox *xbox_class);
void usbh_xbox_stop(struct usbh_xbox *xbox_class);

#ifdef __cplusplus
}
#endif

#endif /* USBH_XBOX_H */