Replies: 1 comment
-
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
Hello, So imnot a programmer, All I know about programming I learned from looing at code (mostly linux kernel) So keep that in mind when i say foolish things :) Im currently amongst other projects adding gpio support to i2c-star (usb to i2c usb device with kernel driver)
https://github.com/daniel-thompson/i2c-star
The firmware and kernel driver work, but its a WIP and more of a playground for me ATM. Its written using libopencm3 because They are for me at least the easiest way to make vendor devices with an interrupt endpoint for irqs. Libopencm3 is great but its hardware support is lacking and even the basic patches that make the usb work on most my devices have literally been sitting un-applied for years! My one usb high speed device arduino portenta h7 works with tinyusb https://github.com/bm16ton/portenta-tinyusb but Im still far to green to understand how to implement a basic interrupt enpoint. While on the subject I also prefer my usb descriptors in a more list like fashion IE
static const struct usb_device_descriptor dev_desc = {
.bLength = USB_DT_DEVICE_SIZE,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bDeviceClass = 0xEF, /* Miscellaneous Device /
.bDeviceSubClass = 2, / Common Class /
.bDeviceProtocol = 1, / Interface Association /
/ The USB specification requires that the control endpoint size for hig
h
* speed devices (e.g., stlinkv3) is 64 bytes.
* Best to have its size set to 64 bytes in all cases. */
.bMaxPacketSize0 = 64,
.idVendor = 0x1D50,
.idProduct = 0x6018,
.bcdDevice = 0x0100,
.iManufacturer = 1,
.iProduct = 2,
.iSerialNumber = 3,
.bNumConfigurations = 1,
};
/* This notification endpoint isn't implemented. According to CDC spec its
static const struct usb_endpoint_descriptor gdb_comm_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = (CDCACM_GDB_ENDPOINT + 1) | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 16,
.bInterval = MAX_BINTERVAL,
}};
static const struct usb_endpoint_descriptor gdb_data_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_GDB_ENDPOINT,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_GDB_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}};
static const struct {
struct usb_cdc_header_descriptor header;
struct usb_cdc_call_management_descriptor call_mgmt;
struct usb_cdc_acm_descriptor acm;
struct usb_cdc_union_descriptor cdc_union;
} attribute((packed)) gdb_cdcacm_functional_descriptors = {
.header = {
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
.bcdCDC = 0x0110,
},
.call_mgmt = {
.bFunctionLength =
sizeof(struct usb_cdc_call_management_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
.bmCapabilities = 0,
.bDataInterface = GDB_IF_NO + 1,
},
.acm = {
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
.bmCapabilities = 2, /* SET_LINE_CODING supported */
},
.cdc_union = {
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = GDB_IF_NO,
.bSubordinateInterface0 = GDB_IF_NO + 1,
}
};
static const struct usb_interface_descriptor gdb_comm_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = GDB_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 4,
}};
static const struct usb_interface_descriptor gdb_data_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = GDB_IF_NO + 1,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
}};
static const struct usb_iface_assoc_descriptor gdb_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = GDB_IF_NO,
.bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 4,
};
/* Serial ACM interface */
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = (CDCACM_UART_ENDPOINT + 1) | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 16,
.bInterval = MAX_BINTERVAL,
}};
static const struct usb_endpoint_descriptor uart_data_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_UART_ENDPOINT,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
#if defined(USB_HS)
.wMaxPacketSize = CDCACM_PACKET_SIZE,
#else
.wMaxPacketSize = CDCACM_PACKET_SIZE / 2,
#endif
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_UART_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}};
static const struct {
struct usb_cdc_header_descriptor header;
struct usb_cdc_call_management_descriptor call_mgmt;
struct usb_cdc_acm_descriptor acm;
struct usb_cdc_union_descriptor cdc_union;
} attribute((packed)) uart_cdcacm_functional_descriptors = {
.header = {
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
.bcdCDC = 0x0110,
},
.call_mgmt = {
.bFunctionLength =
sizeof(struct usb_cdc_call_management_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
.bmCapabilities = 0,
.bDataInterface = UART_IF_NO + 1,
},
.acm = {
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
.bmCapabilities = 2, /* SET_LINE_CODING supported*/
},
.cdc_union = {
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = UART_IF_NO,
.bSubordinateInterface0 = UART_IF_NO + 1,
}
};
static const struct usb_interface_descriptor uart_comm_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = UART_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 5,
}};
static const struct usb_interface_descriptor uart_data_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = UART_IF_NO + 1,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0,
}};
static const struct usb_iface_assoc_descriptor uart_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = UART_IF_NO,
.bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 5,
};
const struct usb_dfu_descriptor dfu_function = {
.bLength = sizeof(struct usb_dfu_descriptor),
.bDescriptorType = DFU_FUNCTIONAL,
.bmAttributes = USB_DFU_CAN_DOWNLOAD | USB_DFU_WILL_DETACH,
.wDetachTimeout = 255,
.wTransferSize = 1024,
.bcdDFUVersion = 0x011A,
};
const struct usb_interface_descriptor dfu_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = DFU_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 0,
.bInterfaceClass = 0xFE,
.bInterfaceSubClass = 1,
.bInterfaceProtocol = 1,
.iInterface = 6,
};
static const struct usb_iface_assoc_descriptor dfu_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = DFU_IF_NO,
.bInterfaceCount = 1,
.bFunctionClass = 0xFE,
.bFunctionSubClass = 1,
.bFunctionProtocol = 1,
.iFunction = 6,
};
#if defined(PLATFORM_HAS_TRACESWO)
static const struct usb_endpoint_descriptor trace_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = TRACE_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = TRACE_ENDPOINT_SIZE,
.bInterval = 0,
}};
const struct usb_interface_descriptor trace_iface = {
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = TRACE_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = 0xFF,
.bInterfaceSubClass = 0xFF,
.bInterfaceProtocol = 0xFF,
.iInterface = 7,
};
static const struct usb_iface_assoc_descriptor trace_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = TRACE_IF_NO,
.bInterfaceCount = 1,
.bFunctionClass = 0xFF,
.bFunctionSubClass = 0xFF,
.bFunctionProtocol = 0xFF,
.iFunction = 7,
};
#endif
#if defined(PLATFORM_HAS_SLCAN)
/*SLCAN interface */
static const struct usb_endpoint_descriptor slcan_comm_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = (CDCACM_SLCAN_ENDPOINT + 1) | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_INTERRUPT,
.wMaxPacketSize = 16,
.bInterval = MAX_BINTERVAL,
}};
static const struct usb_endpoint_descriptor slcan_data_endp[] = {{
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_SLCAN_ENDPOINT,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}, {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = CDCACM_SLCAN_ENDPOINT | USB_REQ_TYPE_IN,
.bmAttributes = USB_ENDPOINT_ATTR_BULK,
.wMaxPacketSize = CDCACM_PACKET_SIZE,
.bInterval = 1,
}};
static const struct {
struct usb_cdc_header_descriptor header;
struct usb_cdc_call_management_descriptor call_mgmt;
struct usb_cdc_acm_descriptor acm;
struct usb_cdc_union_descriptor cdc_union;
} attribute((packed)) slcan_cdcacm_functional_descriptors = {
.header = {
.bFunctionLength = sizeof(struct usb_cdc_header_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_HEADER,
.bcdCDC = 0x0110,
},
.call_mgmt = {
.bFunctionLength =
sizeof(struct usb_cdc_call_management_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_CALL_MANAGEMENT,
.bmCapabilities = 0,
.bDataInterface = SLCAN_IF_NO + 1,
},
.acm = {
.bFunctionLength = sizeof(struct usb_cdc_acm_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_ACM,
.bmCapabilities = 2, /* SET_LINE_CODING supported */
},
.cdc_union = {
.bFunctionLength = sizeof(struct usb_cdc_union_descriptor),
.bDescriptorType = CS_INTERFACE,
.bDescriptorSubtype = USB_CDC_TYPE_UNION,
.bControlInterface = SLCAN_IF_NO,
.bSubordinateInterface0 = SLCAN_IF_NO + 1,
}
};
static const struct usb_interface_descriptor slcan_comm_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = SLCAN_IF_NO,
.bAlternateSetting = 0,
.bNumEndpoints = 1,
.bInterfaceClass = USB_CLASS_CDC,
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
.bInterfaceProtocol = USB_CDC_PROTOCOL_NONE,
.iInterface = 8,
}};
static const struct usb_interface_descriptor slcan_data_iface[] = {{
.bLength = USB_DT_INTERFACE_SIZE,
.bDescriptorType = USB_DT_INTERFACE,
.bInterfaceNumber = SLCAN_IF_NO + 1,
.bAlternateSetting = 0,
.bNumEndpoints = 2,
.bInterfaceClass = USB_CLASS_DATA,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 8,
}};
static const struct usb_iface_assoc_descriptor slcan_assoc = {
.bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE,
.bDescriptorType = USB_DT_INTERFACE_ASSOCIATION,
.bFirstInterface = SLCAN_IF_NO,
.bInterfaceCount = 2,
.bFunctionClass = USB_CLASS_CDC,
.bFunctionSubClass = USB_CDC_SUBCLASS_ACM,
.bFunctionProtocol = USB_CDC_PROTOCOL_NONE,
.iFunction = 8,
};
#endif
I assume this can be done with tinyusb? Anyboy have an example of listing the descriptors or basic interrupt for vendor please let me know. And in case anyone would find it usefull to have a usb to i2c/gpio device (with kernel drivers) It works but the code aint pretty and currently things are left in for me to play with or learn from. After I impliment IRQ and maybe pwm and analog in Ill clean it up all nice. Currently works on stm32f411 blackpill and stm32f412zh nucleo;
https://github.com/bm16ton/i2c-star-blackpill-gpio
Now that im thinking on it, If you do try it and fix/improve things or just any other general help would be beyong appreciative I have no-one to help me learn and even basic BASIC things can take me hours, days or even weeks to get. For example my portenta port to tinyusb caint be mainlined until I move the vector offset for the bootloader outa the first line in main loop to its board folder, and Ive never understood why some of my boards with bootloaders I can simply change the flash start address in the .ld file and others require verying levels of pain in the ass-ness up to and including adding it to first line in main. So if anyone knows how I could move that (the ldflags and cflags didnt work) so it can be added to supported boards Im sure someone sumwhere besides myself would be greatfull for the support. I woulda love tinyusb just for havnig this discussion area which no other project i use has, let alone how awesome the maintainer is and friendly the people are. Truly great project, great community, can build cool stuff! Thank you in advance!
Beta Was this translation helpful? Give feedback.
All reactions