Initializing a USB device requires some support from higher-level
code, typically the application, in the form of enumeration data.
Hence it is not possible for the low-level USB driver to activate a
USB device itself. Instead the higher-level code has to take care of
this by invoking usbs_start
. This function takes
a pointer to a USB control endpoint data structure. USB device drivers
should provide exactly one such data structure for every USB device,
so the pointer uniquely identifies the device.
const usbs_enumeration_data usb_enum_data = { … }; int main(int argc, char** argv) { usbs_sa11x0_ep0.enumeration_data = &usb_enum_data; … usbs_start(&usbs_sa11x0_ep0); … } |
The exact behaviour of usbs_start
depends on the
USB hardware and the device driver. A typical implementation would
change the USB data pins from tristated to active. If the peripheral
is already plugged into a host then the latter should detect this
change and start interacting with the peripheral, including requesting
the enumeration data. Some of this may happen before
usbs_start
returns, but given that multiple
interactions between USB host and peripheral are required it is likely
that the function will return before the peripheral is fully
configured. Control endpoints provide a mechanism for informing
higher-level code of USB state changes.
usbs_start
will return even if the peripheral is
not currently connected to a host: it will not block until the
connection is established.
usbs_start
should only be called once for a given
USB device. There are no defined error conditions. Note that the
function affects the entire USB device and not just the control
endpoint: there is no need to start any data endpoints as well.