Add abort API to USBDevice

Add the function endpoint_abort and ensure ongoing transfer are
aborted when an endpoint is removed.
pull/9768/head
Russ Butler 2018-03-17 18:09:09 -05:00
parent 544282d934
commit 09c1d2cf1e
2 changed files with 56 additions and 2 deletions

View File

@ -916,7 +916,8 @@ void USBDevice::out(usb_ep_t endpoint)
endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)];
info->pending += 1;
MBED_ASSERT(info->pending >= 1);
info->pending -= 1;
if (info->callback) {
(this->*(info->callback))(endpoint);
}
@ -1071,6 +1072,10 @@ void USBDevice::endpoint_remove(usb_ep_t endpoint)
endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)];
MBED_ASSERT(info->flags & ENDPOINT_ENABLED);
if (info->pending) {
_phy->endpoint_abort(endpoint);
}
info->callback = NULL;
info->flags = 0;
info->pending = 0;
@ -1256,6 +1261,38 @@ uint32_t USBDevice::endpoint_max_packet_size(usb_ep_t endpoint)
return size;
}
void USBDevice::endpoint_abort(usb_ep_t endpoint)
{
lock();
if (!EP_INDEXABLE(endpoint)) {
MBED_ASSERT(0);
unlock();
return;
}
bool configuring = _transfer.user_callback == SetConfiguration;
if (!configured() && !configuring) {
unlock();
return;
}
endpoint_info_t *info = &_endpoint_info[EP_TO_INDEX(endpoint)];
if (!(info->flags & ENDPOINT_ENABLED)) {
// Invalid endpoint is being used
MBED_ASSERT(0);
unlock();
return;
}
if (info->pending) {
_phy->endpoint_abort(endpoint);
info->pending = 0;
}
unlock();
}
bool USBDevice::read_start(usb_ep_t endpoint, uint8_t *buffer, uint32_t max_size)
{
lock();
@ -1286,7 +1323,16 @@ bool USBDevice::read_start(usb_ep_t endpoint, uint8_t *buffer, uint32_t max_size
return false;
}
_phy->endpoint_read(endpoint, buffer, info->max_packet_size);
if (info->pending) {
// Only allow 1 packet
unlock();
return false;
}
bool ret = _phy->endpoint_read(endpoint, buffer, info->max_packet_size);
if (ret) {
info->pending += 1;
}
unlock();

View File

@ -201,6 +201,14 @@ public:
*/
uint32_t endpoint_max_packet_size(usb_ep_t endpoint);
/**
* Abort the current transfer on this endpoint
*
* @param endpoint endpoint with transfer to abort
* @note This endpoint must already have been setup with endpoint_add
*/
void endpoint_abort(usb_ep_t endpoint);
/**
* start a read on the given endpoint
*