in IDE dependency tree / definition lookup - for porting

Post here first, or if you can't find a relevant section!
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 »

Years ago, I played heavily with V-USB on AVR under Arduino. In fact, Adafruit's Trinket uses this approach... lite enough for the Tiny85 (also DigiSpark.)

https://www.obdev.at/products/vusb/index.html

Image

Some of you (us) may be old enough to remember LUFA
http://www.fourwalledcubicle.com/LUFA.php

There is a tremendous volume of USB 1.1 information in the V-USB history...
https://dicks.home.xs4all.nl/avr/usbtiny/
https://web.archive.org/web/20160414132 ... R)_eng.htm
http://vusb.wikidot.com/
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 »

there are a bunch of stuff i've confronted while i started off messing in usb. one of them is device descriptors, those map directly to the device class specs from usb. a most difficult yet common of them that i mess with is hid report descriptors. it is 'worth learning' but i'd guess for a start one can start with the 'easier' protocols like usb-serial and maybe mass storage. it turns out device descriptors is simply a bunch of fixed data that the device can transmit when asked for get_descriptor(). it can be simply declared in a byte array and sent back to the host.

i've not gotten deeper, but i'd guess if everything is initiated by the host, what would then matter would be to look for callback to receiving those 'IN', 'OUT' and 'SETUP' token packets from the host. that would be 'usb simplified' in a sense of thinking in terms that when the device receive 'IN', 'OUT', 'SETUP' packets and the endpoint the host wants. the device can then use switch-case or if-then-else constructs to determine what to do with each of those tokens.

the device class specs are sometimes 'incomplete' or rather 'obtuse'. while reading the mass storage specs. it takes me research else where to learn that usb-mass storage is really scsi over usb-mass storage. so one would need to get familiar with scsi commands as well getting into that

@ray, i've in the course of figuring out usb ran into lufa, but i'd think with stm32 we'd have an 'easier' time as we've support directly from hardware itself (for the low level electrical phy parts of it). and we simply get the token/data packets as a bunch of bytes. then we have the core generic usb 'driver' stub from st. we'd mainly need to handle the rest of the 'difficult' parts which is implementing the device class protocols itself. i think st literally have fully working 'examples' for common classes comm, hid, mass storage etc. in terms of ourselves, i'd think we could get by with simply the core generic usb 'driver' stub, and do the rest of the 'hard work' which is dealing with the device class specs implementation itself.
Last edited by ag123 on Sat Mar 13, 2021 10:42 am, 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 »

Well, what I think I need to do is figure out how far up the stack the lib maple implementation went vs how far the STM implementation goes. I think the latter has more code in application space meaning the USBComposite library is doing more on libmaple than it would need to on STM's core. Then it's just a case of removing the excess and refactoring /abstracting any structures to the STM equivalents.... I think lol.

Incidentally much of the documentation linked to by the leaflabs documentation is still really very useful. This section specifically: http://docs.leaflabs.com/static.leaflab ... t/usb.html#
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 i'd start messing with my 'java clunky usbmon log decoder' again, for usb i mostly depend on linux usbmon as my 'usb sniffer'.
i may release it to open source as one of the hardest part while i'm leaning it is to decode that hid report descriptor. that is a core part getting into usb-hid.
as once you can create your own hid report descriptor, you can create any kind of hid device. only thing is it may not be supported at the host end except for the most basic like keyboard and mouse

in the mean time for hid report descriptor, the keyword to search is 'hid report descriptor parser', there are various open sourced implementations already out there
e.g.
https://eleccelerator.com/usbdescreqparser/
https://github.com/NZSmartie/PyHIDParser
http://www.fourwalledcubicle.com/files/ ... arser.html
https://summerofcode.withgoogle.com/arc ... 932900352/
https://www.google.com/search?q=hid+rep ... tor+parser
User avatar
fpiSTM
Posts: 1738
Joined: Wed Dec 11, 2019 7:11 pm
Answers: 91
Location: Le Mans
Contact:

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

Post by fpiSTM »

In fact the best way would be to move to plugable USB then it would be easier to integrate other USB module.
https://github.com/arduino/Arduino/wiki ... eHID-howto


One other stuff I think is to use the tiny USB stack:
https://github.com/hathach/tinyusb
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 »

fpiSTM wrote: Sat Mar 13, 2021 12:36 pm In fact the best way would be to move to plugable USB then it would be easier to integrate other USB module.
https://github.com/arduino/Arduino/wiki ... eHID-howto


One other stuff I think is to use the tiny USB stack:
https://github.com/hathach/tinyusb
Yup, the more I dig into this, the more the library appears to be extending the stack in libmaple space, and encroaching into HID class territory on STM32's core. I was thinking that basically to port it I'd have to overload the HID class somehow - I'm not the best at c++

Of course I might have gotten the wrong end of the stick.

Anyhow, I think both of the above approaches are even further beyond me, and probably require work from someone like you frederic - but as with all things your time is the magic essence. So, that's why I was hoping I could do something in user library space that wouldn't stomp on the core.

From what I can see, I either have to overload the HID class (and have the user select HID support in the IDE when compiling), or disable/rely on all USB being disabled and bring all the initialisation code into the library. Which I think makes it prone to breaking changes as the core moves on.

Naturally if you're about to pull a rabbit out of a hat it's not something I would spend the time against, but I'm thinking the rabbit is very deep inside that hat right now :D
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 »

looks like pluggable usb is a interesting api, however the api seemed quite 'new' and rather 'sketchy' (incomplete)

the callback to respond to the 'IN', 'OUT' and maybe with exception 'SETUP' token packets seem to be not defined
https://github.com/arduino/ArduinoCore- ... gableUSB.h

instead those are found in USBAPH.h
https://github.com/arduino/ArduinoCore- ... API.h#L202

Code: Select all

int USB_SendControl(uint8_t flags, const void* d, int len);
int USB_RecvControl(void* d, int len);
int USB_RecvControlLong(void* d, int len);

uint8_t	USB_Available(uint8_t ep);
uint8_t USB_SendSpace(uint8_t ep);
int USB_Send(uint8_t ep, const void* data, int len);	// blocking
int USB_Recv(uint8_t ep, void* data, int len);		// non-blocking
int USB_Recv(uint8_t ep);							// non-blocking
void USB_Flush(uint8_t ep);
in fact usb_send is *blocking* from the original specs which may not be good
i'm not too sure if it would help to have some sort of call back (e.g. virtual function) so that if a USB_Recv happen with one of 'IN', 'OUT' or ('SETUP'?) tokens, then the the core calls the sketch USB_Rev() callback, so that sketch can do a USB_Send() with an appropriate response. i've not dug into the stm usb core functionality, but i'd guess such a callback probably exist given the design of usb ('IN', 'OUT', 'SETUP' token packets are initiated by the host)
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 »

IN, OUT, SETUP are all handled seemlessly inside the USB stack, the only thing we need to worry about in user space is the endpoints, descriptors, associated buffers & interrupt callbacks. Or at least that's my current understanding - it will likely change as I continue delving.
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 »

just reviewed stm32f103 rm0008
https://www.st.com/resource/en/referenc ... ronics.pdf
IN packets (data transmission)
When receiving an IN token packet, if the received address matches a configured and valid
endpoint one, the USB peripheral accesses the contents of ADDRn_TX and COUNTn_TX
locations inside buffer descriptor table entry related to the addressed endpoint. The content
of these locations is stored in its internal 16 bit registers ADDR and COUNT (not accessible
by software). The packet memory is accessed again to read the first word to be transmitted
(refer to Structure and usage of packet buffers) and starts sending a DATA0 or DATA1 PID
according to USB_EPnR bit DTOG_TX. When the PID is completed, the first byte from the
word, read from buffer memory, is loaded into the output shift register to be transmitted on
the USB bus. After the last data byte is transmitted, the computed CRC is sent. If the
addressed endpoint is not valid, a NAK or STALL handshake packet is sent instead of the
data packet, according to STAT_TX bits in the USB_EPnR register.
...
OUT and SETUP packets (data reception)
These two tokens are handled by the USB peripheral more or less in the same way; the
differences in the handling of SETUP packets are detailed in the following paragraph about
control transfers. When receiving an OUT/SETUP PID, if the address matches a valid
endpoint, the USB peripheral accesses the contents of the ADDRn_RX and COUNTn_RX
locations inside the buffer descriptor table entry related to the addressed endpoint. The
content of the ADDRn_RX is stored directly in its internal register ADDR. While COUNT is
now reset and the values of BL_SIZE and NUM_BLOCK bit fields, which are read within
COUNTn_RX content are used to initialize BUF_COUNT, an internal 16 bit counter, which is
used to check the buffer overrun condition (all these internal registers are not accessible by
software). Data bytes subsequently received by the USB peripheral are packed in words
(the first byte received is stored as least significant byte) and then transferred to the packet
buffer starting from the address contained in the internal ADDR register while BUF_COUNT
is decremented and COUNT is incremented at each byte transfer. When the end of DATA
packet is detected, the correctness of the received CRC is tested and only if no errors
occurred during the reception, an ACK handshake packet is sent back to the transmitting
host.
...
so the stm32 hardware does much more than that, literally for stuff going to the host just leave data in the 'IN' mailbox and hardware sends it.
then for 'OUT' data to device, it is in the 'OUT' mailbox

but i think callbacks are still relevant, in the form of 'you have mail' and 'mail sent' interrupts.
e.g. for 'IN' (i.e. host wants data') we'd put the 1st 'packet' of data in the 'IN', mailbox, once that is sent.
the core (in fact usb core) interrupts and says 'mail sent', so we'd place the next 'bucket' of data to be sent
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 »

Yup callbacks are appropriate - I've not visited the CDC implementation for quite some time (since hacking it to accept the magic words for the bootloader implementations), but I guess there's code in there covering it off. As a reference point this is.

The problem I think comes in that there's a simple HID implementation in the core for mouse/keyboard, and probably all the structures are private within there so can't be overloaded - meaning that to implement USBComposite library it can't be used and all the necessary stuff will need to be handled in the lib, but again not sure if there's any way to interact with the USB stack in user space other than via the exposed API.

Also been having a look at how mbed implements pluggable USB, it's referenced in this issue against STM's core-> https://github.com/stm32duino/Arduino_C ... issues/687

Essentially a composite plugin would need to be built (I think), if the core goes in that direction. (although tbh the mbed core doesn't look to handle composite devices either and it should happen at the device level and not as a 'plugin' which would then need to reinvent the wheel for each class.)
Last edited by BennehBoy on Sat Mar 13, 2021 3:46 pm, edited 1 time in total.
Post Reply

Return to “General discussion”