In order to support 11xx MCUs (and, turns out, the special 1010), we can't assume that the USB and USBPHY register blocks are at a fixed location. Instead, we need a way to vary the register block location based on the chip, but (ideally) without bringing in imxrt-ral. This PR changes the Peripherals trait to achieve that goal. Implementations now return pointers to the register blocks, not USB instance numbers.
Once we drop the USB instance numbers, we can't immediately assign static endpoint state, like endpoint queue heads (QH) and transfer descriptors (TD), to the USB driver. Instead of asking Peripherals implementations to also identify their USB instance, I took an approach where the endpoint state is allocated by the user, outside of the library.
After this PR, users are responsible for allocating an EndpointState and supplying it to the driver. EndpointState maintains QHs, TDs, and Endpoint objects, and runtime checks assert that states are not assigned to multiple USB drivers. The benefit is that the user can shrink the total number of supported endpoints, and the associated memory footprint, through a const generic.
The PR also changes the API for supplying endpoint memory. Users now use an EndpointMemory to define a byte allocation for the driver. Users no longer need an unsafe when supplying the buffer to the driver.
Tested with the test_class example. Also tested through imxrt-log (imxrt-rs/imxrt-hal#121).
In order to support 11xx MCUs (and, turns out, the special 1010), we can't assume that the USB and USBPHY register blocks are at a fixed location. Instead, we need a way to vary the register block location based on the chip, but (ideally) without bringing in
imxrt-ral
. This PR changes thePeripherals
trait to achieve that goal. Implementations now return pointers to the register blocks, not USB instance numbers.Once we drop the USB instance numbers, we can't immediately assign static endpoint state, like endpoint queue heads (QH) and transfer descriptors (TD), to the USB driver. Instead of asking
Peripherals
implementations to also identify their USB instance, I took an approach where the endpoint state is allocated by the user, outside of the library.After this PR, users are responsible for allocating an
EndpointState
and supplying it to the driver.EndpointState
maintains QHs, TDs, andEndpoint
objects, and runtime checks assert that states are not assigned to multiple USB drivers. The benefit is that the user can shrink the total number of supported endpoints, and the associated memory footprint, through a const generic.The PR also changes the API for supplying endpoint memory. Users now use an
EndpointMemory
to define a byte allocation for the driver. Users no longer need anunsafe
when supplying the buffer to the driver.Tested with the
test_class
example. Also tested throughimxrt-log
(imxrt-rs/imxrt-hal#121).