Skip to content

Commit

Permalink
gs_usb: make dummy endpoint selecatble by KConfig
Browse files Browse the repository at this point in the history
This change adds dummy endpoint KConfig select flag
to support dynamic endpoint enumeration made in
newer version of gs_usb driver in linux kernel.

Additional effect of this change is no need of
dummy usb endpoint at all if newer version of gs_usb
driver is used.

Signed-off-by: Alexander Kozhinov <[email protected]>
  • Loading branch information
KozhinovAlexander committed Dec 21, 2024
1 parent 42bbcd1 commit e5e50cd
Show file tree
Hide file tree
Showing 8 changed files with 351 additions and 147 deletions.
6 changes: 6 additions & 0 deletions app/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,12 @@ config CANNECTIVITY_USB_MAX_POWER
CANnectivity USB maximum current draw in milliampere (mA) divided by 2.
A value of 125 results in a maximum current draw value of 250 mA.

config CANNECTIVITY_USB_DUMMY_EP
bool "CANnectivity USB dummy endpoint select"
default y
help
Enables dummy endpoint to support older gs_usb versions.

if USB_DEVICE_STACK

configdefault USB_DEVICE_MANUFACTURER
Expand Down
9 changes: 9 additions & 0 deletions include/cannectivity/usb/class/gs_usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -466,10 +466,19 @@ struct gs_usb_host_frame_hdr {

/** USB bulk IN endpoint address */
#define GS_USB_IN_EP_ADDR 0x81
#ifdef CONFIG_CANNECTIVITY_USB_DUMMY_EP
/** USB (dummy) bulk OUT endpoint address */
#define GS_USB_DUMMY_EP_ADDR 0x01
/** USB bulk OUT endpoint address */
#define GS_USB_OUT_EP_ADDR 0x02
/** USB bulk total endpoints number */
#define GS_USB_NUM_ENDPOINTS 3U
#else
/** USB bulk OUT endpoint address */
#define GS_USB_OUT_EP_ADDR 0x01
/** USB bulk total endpoints number */
#define GS_USB_NUM_ENDPOINTS 2U
#endif /* CONFIG_CANNECTIVITY_USB_DUMMY_EP */

/** @} */

Expand Down
67 changes: 14 additions & 53 deletions subsys/usb/device/class/gs_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,20 @@ LOG_MODULE_REGISTER(gs_usb, CONFIG_USB_DEVICE_GS_USB_LOG_LEVEL);

/* USB endpoint indexes */
#define GS_USB_IN_EP_IDX 0U
#ifdef CONFIG_CANNECTIVITY_USB_DUMMY_EP
#define GS_USB_DUMMY_EP_IDX 1U
#define GS_USB_OUT_EP_IDX 2U
#else
#define GS_USB_OUT_EP_IDX 1U
#endif /* CONFIG_CANNECTIVITY_USB_DUMMY_EP */

struct gs_usb_config {
struct usb_association_descriptor iad;
struct usb_if_descriptor if0;
struct usb_ep_descriptor if0_in_ep;
#ifdef CONFIG_CANNECTIVITY_USB_DUMMY_EP
struct usb_ep_descriptor if0_dummy_ep;
#endif /* CONFIG_CANNECTIVITY_USB_DUMMY_EP */
struct usb_ep_descriptor if0_out_ep;
} __packed;

Expand Down Expand Up @@ -1354,7 +1360,9 @@ static void gs_usb_status_callback(struct usb_cfg_data *cfg, enum usb_dc_status_
case USB_DC_CONFIGURED:
LOG_DBG("USB device configured");
LOG_DBG("EP IN addr = 0x%02x", cfg->endpoint[GS_USB_IN_EP_IDX].ep_addr);
#ifdef CONFIG_CANNECTIVITY_USB_DUMMY_EP
LOG_DBG("EP DUMMY addr = 0x%02x", cfg->endpoint[GS_USB_DUMMY_EP_IDX].ep_addr);
#endif /* CONFIG_CANNECTIVITY_USB_DUMMY_EP */
LOG_DBG("EP OUT addr = 0x%02x", cfg->endpoint[GS_USB_OUT_EP_IDX].ep_addr);
gs_usb_transfer_tx_prepare(common->dev);
break;
Expand Down Expand Up @@ -1456,7 +1464,7 @@ static int gs_usb_init(const struct device *dev)
.bDescriptorType = USB_DESC_INTERFACE, \
.bInterfaceNumber = 0, \
.bAlternateSetting = 0, \
.bNumEndpoints = 3, \
.bNumEndpoints = GS_USB_NUM_ENDPOINTS, \
.bInterfaceClass = USB_BCC_VENDOR, \
.bInterfaceSubClass = 0, \
.bInterfaceProtocol = 0, \
Expand All @@ -1473,57 +1481,10 @@ static int gs_usb_init(const struct device *dev)
.bInterval = 0x01, \
}

#define GS_USB_DEVICE_DEFINE(inst) \
BUILD_ASSERT(DT_INST_ON_BUS(inst, usb), \
"node " DT_NODE_PATH( \
DT_DRV_INST(inst)) " is not assigned to a USB device controller"); \
\
NET_BUF_POOL_FIXED_DEFINE(gs_usb_pool_##inst, CONFIG_USB_DEVICE_GS_USB_POOL_SIZE, \
GS_USB_HOST_FRAME_MAX_SIZE, 0, NULL); \
\
USBD_CLASS_DESCR_DEFINE(primary, 0) \
struct gs_usb_config gs_usb_config_##inst = { \
.iad = INITIALIZER_IAD, \
.if0 = INITIALIZER_IF, \
.if0_in_ep = INITIALIZER_IF_EP(GS_USB_IN_EP_ADDR), \
.if0_dummy_ep = INITIALIZER_IF_EP(GS_USB_DUMMY_EP_ADDR), \
.if0_out_ep = INITIALIZER_IF_EP(GS_USB_OUT_EP_ADDR), \
}; \
\
static struct usb_ep_cfg_data gs_usb_ep_cfg_data_##inst[] = { \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_IN_EP_ADDR, \
}, \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_DUMMY_EP_ADDR, \
}, \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_OUT_EP_ADDR, \
}, \
}; \
\
USBD_DEFINE_CFG_DATA(gs_usb_cfg_##inst) = { \
.usb_device_description = NULL, \
.interface_config = gs_usb_interface_config, \
.interface_descriptor = &gs_usb_config_##inst.if0, \
.cb_usb_status = gs_usb_status_callback, \
.interface = { \
.class_handler = NULL, \
.custom_handler = NULL, \
.vendor_handler = gs_usb_vendor_request_handler, \
}, \
.num_endpoints = ARRAY_SIZE(gs_usb_ep_cfg_data_##inst), \
.endpoint = gs_usb_ep_cfg_data_##inst, \
}; \
\
static struct gs_usb_data gs_usb_data_##inst = { \
.pool = &gs_usb_pool_##inst, \
}; \
\
DEVICE_DT_INST_DEFINE(inst, gs_usb_init, NULL, &gs_usb_data_##inst, &gs_usb_cfg_##inst, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);
#ifdef CONFIG_CANNECTIVITY_USB_DUMMY_EP
#include "gs_usb_device_define_dummy.h"
#else
#include "gs_usb_device_define.h"
#endif /* CONFIG_CANNECTIVITY_USB_DUMMY_EP */

DT_INST_FOREACH_STATUS_OKAY(GS_USB_DEVICE_DEFINE);
58 changes: 58 additions & 0 deletions subsys/usb/device/class/gs_usb_device_define.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2022-2024 Alexander Kozhinov <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef CANNECTIVITY_INCLUDE_GS_USB_DEVICE_DEFINE_H_
#define CANNECTIVITY_INCLUDE_GS_USB_DEVICE_DEFINE_H_

#define GS_USB_DEVICE_DEFINE(inst) \
BUILD_ASSERT(DT_INST_ON_BUS(inst, usb), \
"node " DT_NODE_PATH( \
DT_DRV_INST(inst)) " is not assigned to a USB device controller"); \
\
NET_BUF_POOL_FIXED_DEFINE(gs_usb_pool_##inst, CONFIG_USB_DEVICE_GS_USB_POOL_SIZE, \
GS_USB_HOST_FRAME_MAX_SIZE, 0, NULL); \
\
USBD_CLASS_DESCR_DEFINE(primary, 0) \
struct gs_usb_config gs_usb_config_##inst = { \
.iad = INITIALIZER_IAD, \
.if0 = INITIALIZER_IF, \
.if0_in_ep = INITIALIZER_IF_EP(GS_USB_IN_EP_ADDR), \
.if0_out_ep = INITIALIZER_IF_EP(GS_USB_OUT_EP_ADDR), \
}; \
\
static struct usb_ep_cfg_data gs_usb_ep_cfg_data_##inst[] = { \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_IN_EP_ADDR, \
}, \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_OUT_EP_ADDR, \
}, \
}; \
\
USBD_DEFINE_CFG_DATA(gs_usb_cfg_##inst) = { \
.usb_device_description = NULL, \
.interface_config = gs_usb_interface_config, \
.interface_descriptor = &gs_usb_config_##inst.if0, \
.cb_usb_status = gs_usb_status_callback, \
.interface = { \
.class_handler = NULL, \
.custom_handler = NULL, \
.vendor_handler = gs_usb_vendor_request_handler, \
}, \
.num_endpoints = ARRAY_SIZE(gs_usb_ep_cfg_data_##inst), \
.endpoint = gs_usb_ep_cfg_data_##inst, \
}; \
\
static struct gs_usb_data gs_usb_data_##inst = { \
.pool = &gs_usb_pool_##inst, \
}; \
\
DEVICE_DT_INST_DEFINE(inst, gs_usb_init, NULL, &gs_usb_data_##inst, &gs_usb_cfg_##inst, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);

#endif /* CANNECTIVITY_INCLUDE_GS_USB_DEVICE_DEFINE_H_ */
63 changes: 63 additions & 0 deletions subsys/usb/device/class/gs_usb_device_define_dummy.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2022-2024 Alexander Kozhinov <[email protected]>
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef CANNECTIVITY_INCLUDE_GS_USB_DEVICE_DEFINE_DUMMY_H_
#define CANNECTIVITY_INCLUDE_GS_USB_DEVICE_DEFINE_DUMMY_H_

#define GS_USB_DEVICE_DEFINE(inst) \
BUILD_ASSERT(DT_INST_ON_BUS(inst, usb), \
"node " DT_NODE_PATH( \
DT_DRV_INST(inst)) " is not assigned to a USB device controller"); \
\
NET_BUF_POOL_FIXED_DEFINE(gs_usb_pool_##inst, CONFIG_USB_DEVICE_GS_USB_POOL_SIZE, \
GS_USB_HOST_FRAME_MAX_SIZE, 0, NULL); \
\
USBD_CLASS_DESCR_DEFINE(primary, 0) \
struct gs_usb_config gs_usb_config_##inst = { \
.iad = INITIALIZER_IAD, \
.if0 = INITIALIZER_IF, \
.if0_in_ep = INITIALIZER_IF_EP(GS_USB_IN_EP_ADDR), \
.if0_dummy_ep = INITIALIZER_IF_EP(GS_USB_DUMMY_EP_ADDR), \
.if0_out_ep = INITIALIZER_IF_EP(GS_USB_OUT_EP_ADDR), \
}; \
\
static struct usb_ep_cfg_data gs_usb_ep_cfg_data_##inst[] = { \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_IN_EP_ADDR, \
}, \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_DUMMY_EP_ADDR, \
}, \
{ \
.ep_cb = usb_transfer_ep_callback, \
.ep_addr = GS_USB_OUT_EP_ADDR, \
}, \
}; \
\
USBD_DEFINE_CFG_DATA(gs_usb_cfg_##inst) = { \
.usb_device_description = NULL, \
.interface_config = gs_usb_interface_config, \
.interface_descriptor = &gs_usb_config_##inst.if0, \
.cb_usb_status = gs_usb_status_callback, \
.interface = { \
.class_handler = NULL, \
.custom_handler = NULL, \
.vendor_handler = gs_usb_vendor_request_handler, \
}, \
.num_endpoints = ARRAY_SIZE(gs_usb_ep_cfg_data_##inst), \
.endpoint = gs_usb_ep_cfg_data_##inst, \
}; \
\
static struct gs_usb_data gs_usb_data_##inst = { \
.pool = &gs_usb_pool_##inst, \
}; \
\
DEVICE_DT_INST_DEFINE(inst, gs_usb_init, NULL, &gs_usb_data_##inst, &gs_usb_cfg_##inst, \
POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT, NULL);

#endif /* CANNECTIVITY_INCLUDE_GS_USB_DEVICE_DEFINE_DUMMY_H_ */
Loading

0 comments on commit e5e50cd

Please sign in to comment.