Reimplement atomic code in inline assembly. This can improve
optimisation, and avoids potential architectural problems with using
LDREX/STREX intrinsics.
API further extended:
* Bitwise operations (fetch_and/fetch_or/fetch_xor)
* fetch_add and fetch_sub (like incr/decr, but returning old value -
aligning with C++11)
* compare_exchange_weak
* Explicit memory order specification
* Basic freestanding template overloads for C++
This gives our existing C implementation essentially all the functionality
needed by C++11.
An actual Atomic<T> template based upon these C functions could follow.
It is undefined behavior if stalling and unstalling clears an ongoing
transfer. Abort any ongoing transfers explicitly when stalling and
unstalling so the behavior is consistent across devices.
Remove the endpoint parameter from endpoint callbacks. This
information is redundant because endpoints are known at
construction time because they must be in the configuration
descriptor.
Only assert if disabled endpoints are used when USBDevice is
configured. USBDevice can leave the configured state due to a
reset at any time, which disables all endpoints. Because this
can happen at any time, thread processing could be performing
any endpoint operation. The endpoint operation should return
failure and do nothing in this case, rather than asserting
as this is not an application error.
An assert should only be triggered when an invalid endpoint is
used after the use of USBDevice acknoledges the switch to
configured mode by complete_set_configuration.
In specific this PR fixes the assert caused with the following
sequence:
-ISR: OUT event sent
-ISR: USB reset event
-ISR: USB configure request start
-Thread: OUT event processed on thread and next read starts
***endpoint is used while disabled causing an invalid assert***
-Thread: reset event processed
-Thread: configure event processed
This patch fixes this problem by making the following changes:
1. Operations done on disabled endpoints only assert when in the configured state
2. Adding and removing endpoints is only allowed when
the flag _endpoint_add_remove_allowed is set
3. The flag _endpoint_add_remove_allowed is set on the set
configuration request and cleared if the request is aborted or
fails
Make the function configuration_desc pure virtual inside USBDevice.
This should be a compile time error since no subclass will work
without a configuration descriptor.
Add a destructor to USBDevice to ensure that resources have been
properly released. Additionally add an assert in the destructor that
deinit has already been called. If it has not been called then
interrupts can still occur which may cause a crash.
Remove the option to block in USBDevice::connect since this
should be handled at a higher level. Also call init to ensure that
the USBDevice has been initalized.
Add the helper function endpoint_remove_all which removes all added
endpoints. This is useful for class drivers switching between
different USB configurations.
Perform processing triggered by user callbacks when USB is being
unlocked rather than synchronously. This prevents recursive callbacks
which reduces stack usage. This also prevents state change inside
the user callback which makes the code easier to reason about.
Remove the USBDevice function read_start and automatically start all
reads internally in USBDevice. This patch also renames the function
read_finish to read.