in IDE dependency tree / definition lookup - for porting

Post here first, or if you can't find a relevant section!
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

ok i dug in a little, found it, callbacks are here
https://github.com/stm32duino/Arduino_C ... def.h#L196

Code: Select all

typedef struct _Device_cb
{
  uint8_t (*Init)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
  uint8_t (*DeInit)(struct _USBD_HandleTypeDef *pdev, uint8_t cfgidx);
  /* Control Endpoints*/
  uint8_t (*Setup)(struct _USBD_HandleTypeDef *pdev, USBD_SetupReqTypedef  *req);
  uint8_t (*EP0_TxSent)(struct _USBD_HandleTypeDef *pdev);
  uint8_t (*EP0_RxReady)(struct _USBD_HandleTypeDef *pdev);
  /* Class Specific Endpoints*/
  uint8_t (*DataIn)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
  uint8_t (*DataOut)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
  uint8_t (*SOF)(struct _USBD_HandleTypeDef *pdev);
  uint8_t (*IsoINIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);
  uint8_t (*IsoOUTIncomplete)(struct _USBD_HandleTypeDef *pdev, uint8_t epnum);

  uint8_t  *(*GetHSConfigDescriptor)(uint16_t *length);
  uint8_t  *(*GetFSConfigDescriptor)(uint16_t *length);
  uint8_t  *(*GetOtherSpeedConfigDescriptor)(uint16_t *length);
  uint8_t  *(*GetDeviceQualifierDescriptor)(uint16_t *length);
#if (USBD_SUPPORT_USER_STRING_DESC == 1U)
  uint8_t  *(*GetUsrStrDescriptor)(struct _USBD_HandleTypeDef *pdev, uint8_t index,  uint16_t *length);
#endif

} USBD_ClassTypeDef;
and here
https://github.com/stm32duino/Arduino_C ... def.h#L238

Code: Select all

/* USB Device descriptors structure */
typedef struct
{
  uint8_t *(*GetDeviceDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetLangIDStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetManufacturerStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetProductStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetSerialStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetConfigurationStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
  uint8_t *(*GetInterfaceStrDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#if (USBD_CLASS_USER_STRING_DESC == 1)
  uint8_t *(*GetUserStrDescriptor)(USBD_SpeedTypeDef speed, uint8_t idx, uint16_t *length);
#endif
#if ((USBD_LPM_ENABLED == 1U) || (USBD_CLASS_BOS_ENABLED == 1))
  uint8_t *(*GetBOSDescriptor)(USBD_SpeedTypeDef speed, uint16_t *length);
#endif
} USBD_DescriptorsTypeDef;
i'm thinking perhaps there can be a c++ .h include wrapper around them in which these callbacks are *virtual functions*, i.e. they can be overridden
then our 'usb device class driver', would literally be a c++ class that inherits that and implements those functions.

i think there could be a catch as normally it is rather tricky to call c++ methods from c. but otherwise, to implement things with c, it would simply be patching function pointers there
Last edited by ag123 on Sat Mar 13, 2021 3:47 pm, edited 1 time in total.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

haha, and that's where @fpiSTM will need some convincing, I know others are also keen to do something similar in the SPI space.

See here -> https://github.com/stm32duino/Arduino_C ... ssues/1035
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

i'd guess we'd 'evolve this slowly' as it seemed there really isn't a 'industry best practice' for doing usb.
it is likely due to that hardware differences are likely to be huge between different usb hardware

that 'pluggable usb' may help so that the core can register an entry point to call our 'driver'.
either way, i'd guess the arduino idiom is driver.begin() in setup(). it could stay that way for a 'convenient' approach to usb.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

This page is a really useful view, essentially the part we're interested in is defining multiple interfaces, everything above that is already covered by the stack implementation in the core. See https://www.beyondlogic.org/usbnutshell/usb5.shtml

The CDC & HID classes defined within the core occupy this space.

Essentially we need to be able to nail mutiple interfaces against a device, then call begin.
mrburnette
Posts: 633
Joined: Thu Dec 19, 2019 1:23 am
Answers: 7

Re: in IDE dependency tree / definition lookup - for porting

Post by mrburnette »

Historical note:

Frank Zhao is the father of Adafruit's Trinket product. The link to eleccelerator was mentioned earlier up.

Frank actually had his own USB hardware early on during his university days: USnooBie
and was the inventor of the USB HID business card.

Frank's tutorial on USB HID descriptors
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

i think a main thing about 'multiple interfaces' is
for one part we'd need to pack different 'device class descriptors' into interfaces (i.e. same device class different interfaces)
i've not really dug into that though and i'm not sure what if i've a mass storage device class but below it i've both serial cdc and mass storage interfaces.

the other challenge would be that e.g. on stm32f103 the hardware takes care of 4 endpoints (both IN and OUT), implementing 'composite' devices
could quickly use up all available endpoints - it may be short of endpoints to implement multiple different concurrent device classes.
another thing is like for HID, HID can have fat bloated report descriptors. but i think the buffer size and after all each usb data frame is max 64 bytes for full speed connections. so while it is possible to declare elaborate HID report descriptors, they may finally be so bloated it doesn't fit in that 64 bytes. i'm not too sure if get_descriptor() could have those same limitations and if that matters.

that could mean that each composite device would need to be a custom development than a mix and match development

@ray that hid biz card is fun :)
there is some stuff i'd want to play with hid on stm32, e.g. it can control the 'mouse' (or rather the cursor), let imagination go wild :lol:

frank's tutorial on hid descriptors is good i partly learned hid from there.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

ag123 wrote: Sat Mar 13, 2021 4:33 pm i think a main thing about 'multiple interfaces' is
for one part we'd need to pack different 'device class descriptors' into interfaces (i.e. same device class different interfaces)
i've not really dug into that though and i'm not sure what if i've a mass storage device class but below it i've both serial cdc and mass storage interfaces.
The classes in terms of the core ARE the interfaces.
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

ag123 wrote: Sat Mar 13, 2021 4:33 pm the other challenge would be that e.g. on stm32f103 the hardware takes care of 4 endpoints (both IN and OUT), implementing 'composite' devices
could quickly use up all available endpoints - it may be short of endpoints to implement multiple different concurrent device classes.
another thing is like for HID, HID can have fat bloated report descriptors. but i think the buffer size and after all each usb data frame is max 64 bytes for full speed connections. so while it is possible to declare elaborate HID report descriptors, they may finally be so bloated it doesn't fit in that 64 bytes. i'm not too sure if get_descriptor() could have those same limitations and if that matters.

that could mean that each composite device would need to be a custom development than a mix and match development
Yes, not every device is capable of actually having many interfaces active, and in some cases it depends on the way they are mixed.

There's actually some good text on this in arpruss's repo, see the limitations in the readme.md here -> https://github.com/arpruss/USBComposite_stm32f1
Last edited by BennehBoy on Sat Mar 13, 2021 5:14 pm, edited 1 time in total.
ag123
Posts: 1655
Joined: Thu Dec 19, 2019 5:30 am
Answers: 24

Re: in IDE dependency tree / definition lookup - for porting

Post by ag123 »

oh saw that
https://www.beyondlogic.org/usbnutshell/usb5.shtml
Device Descriptors
4 bDeviceClass 1 Class
Class Code (Assigned by USB Org)
If equal to Zero, each interface specifies it’s own class code
If equal to 0xFF, the class code is vendor specified.
Otherwise field is valid Class Code.
that means for 'multi class' devices we'd simply declare zero in the device descriptor and declare them in each of the interface descriptors
BennehBoy
Posts: 135
Joined: Sat Jan 04, 2020 2:38 am
Answers: 1

Re: in IDE dependency tree / definition lookup - for porting

Post by BennehBoy »

ag123 wrote: Sat Mar 13, 2021 5:10 pm oh saw that
https://www.beyondlogic.org/usbnutshell/usb5.shtml
Device Descriptors
4 bDeviceClass 1 Class
Class Code (Assigned by USB Org)
If equal to Zero, each interface specifies it’s own class code
If equal to 0xFF, the class code is vendor specified.
Otherwise field is valid Class Code.
that means for 'multi class' devices we'd simply declare zero in the device descriptor and declare them in each of the interface descriptors
Yup exactly so.

I _think_ this can be done in user space if we ensure that neither CDC or HID are enabled at compile time. We just do the USB device initiation in our library - assuming the necessary parts are exposed as previously discussed.
Post Reply

Return to “General discussion”