mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
usbus/cdc_ecm: Make use of URBs for inbound frames
This commit is contained in:
parent
7bfdd73818
commit
ba88608749
@ -831,6 +831,7 @@ ifneq (,$(filter usbus_cdc_ecm,$(USEMODULE)))
|
||||
USEMODULE += iolist
|
||||
USEMODULE += fmt
|
||||
USEMODULE += usbus
|
||||
USEMODULE += usbus_urb
|
||||
USEMODULE += netdev_eth
|
||||
USEMODULE += luid
|
||||
endif
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "usb/descriptor.h"
|
||||
#include "usb/usbus.h"
|
||||
#include "usb/usbus/control.h"
|
||||
#include "macros/math.h"
|
||||
#include "net/netdev.h"
|
||||
#include "mutex.h"
|
||||
|
||||
@ -77,6 +78,11 @@ extern "C" {
|
||||
*/
|
||||
#define USBUS_CDCECM_EP_DATA_SIZE 64
|
||||
|
||||
/**
|
||||
* @brief Full ethernet frame rounded up to a whole number of transfers
|
||||
*/
|
||||
#define USBUS_ETHERNET_FRAME_BUF MATH_ALIGN(ETHERNET_FRAME_LEN, USBUS_CDCECM_EP_DATA_SIZE)
|
||||
|
||||
/**
|
||||
* @brief notification state, used to track which information must be send to
|
||||
* the host
|
||||
@ -108,14 +114,13 @@ typedef struct usbus_cdcecm_device {
|
||||
usbus_t *usbus; /**< Ptr to the USBUS context */
|
||||
mutex_t out_lock; /**< mutex used for locking netif/USBUS send */
|
||||
size_t tx_len; /**< Length of the current tx frame */
|
||||
size_t len; /**< Length of the current rx frame */
|
||||
usbus_cdcecm_notif_t notif; /**< Startup message notification tracker */
|
||||
unsigned active_iface; /**< Current active data interface */
|
||||
|
||||
/**
|
||||
* @brief Buffer for received frames from the host
|
||||
*/
|
||||
usbdev_ep_buf_t data_out[ETHERNET_FRAME_LEN];
|
||||
usbdev_ep_buf_t data_out[USBUS_ETHERNET_FRAME_BUF];
|
||||
|
||||
/**
|
||||
* @brief Host in device out data buffer
|
||||
@ -126,6 +131,10 @@ typedef struct usbus_cdcecm_device {
|
||||
* @brief Host out device in control buffer
|
||||
*/
|
||||
usbdev_ep_buf_t control_in[USBUS_CDCECM_EP_CTRL_SIZE];
|
||||
/**
|
||||
* @brief Host out device in reception URB
|
||||
*/
|
||||
usbus_urb_t out_urb;
|
||||
} usbus_cdcecm_device_t;
|
||||
|
||||
/**
|
||||
|
@ -162,6 +162,14 @@ static void _fill_ethernet(usbus_cdcecm_device_t *cdcecm)
|
||||
|
||||
}
|
||||
|
||||
void _start_urb(usbus_cdcecm_device_t *cdcecm)
|
||||
{
|
||||
usbus_urb_init(&cdcecm->out_urb,
|
||||
cdcecm->data_out,
|
||||
USBUS_ETHERNET_FRAME_BUF, 0);
|
||||
usbus_urb_submit(cdcecm->usbus, cdcecm->ep_out, &cdcecm->out_urb);
|
||||
}
|
||||
|
||||
void usbus_cdcecm_init(usbus_t *usbus, usbus_cdcecm_device_t *handler)
|
||||
{
|
||||
assert(usbus);
|
||||
@ -251,9 +259,9 @@ static int _control_handler(usbus_t *usbus, usbus_handler_t *handler,
|
||||
setup->value);
|
||||
cdcecm->active_iface = (uint8_t)setup->value;
|
||||
if (cdcecm->active_iface == 1) {
|
||||
usbdev_ep_xmit(cdcecm->ep_out->ep, cdcecm->data_out,
|
||||
USBUS_CDCECM_EP_DATA_SIZE);
|
||||
_notify_link_up(cdcecm);
|
||||
/* Start URB */
|
||||
_start_urb(cdcecm);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -298,8 +306,8 @@ static void _handle_rx_flush_ev(event_t *ev)
|
||||
{
|
||||
usbus_cdcecm_device_t *cdcecm = container_of(ev, usbus_cdcecm_device_t,
|
||||
rx_flush);
|
||||
cdcecm->len = 0; /* Flush packet */
|
||||
usbdev_ep_xmit(cdcecm->ep_out->ep, cdcecm->data_out, USBUS_CDCECM_EP_DATA_SIZE);
|
||||
/* Start URB */
|
||||
_start_urb(cdcecm);
|
||||
}
|
||||
|
||||
static void _transfer_handler(usbus_t *usbus, usbus_handler_t *handler,
|
||||
@ -310,20 +318,7 @@ static void _transfer_handler(usbus_t *usbus, usbus_handler_t *handler,
|
||||
usbus_cdcecm_device_t *cdcecm = (usbus_cdcecm_device_t *)handler;
|
||||
if (ep == cdcecm->ep_out->ep) {
|
||||
/* Retrieve incoming data */
|
||||
if (cdcecm->notif == USBUS_CDCECM_NOTIF_NONE) {
|
||||
_notify_link_up(cdcecm);
|
||||
}
|
||||
size_t len = 0;
|
||||
usbdev_ep_get(ep, USBOPT_EP_AVAILABLE, &len, sizeof(size_t));
|
||||
cdcecm->len += len;
|
||||
if (len == USBUS_CDCECM_EP_DATA_SIZE) {
|
||||
/* ready next chunk */
|
||||
usbdev_ep_xmit(ep, cdcecm->data_out + cdcecm->len,
|
||||
USBUS_CDCECM_EP_DATA_SIZE);
|
||||
}
|
||||
else {
|
||||
netdev_trigger_event_isr(&cdcecm->netdev);
|
||||
}
|
||||
netdev_trigger_event_isr(&cdcecm->netdev);
|
||||
}
|
||||
else if (ep == cdcecm->ep_in->ep) {
|
||||
_handle_in_complete(usbus, handler);
|
||||
@ -341,7 +336,6 @@ static void _handle_reset(usbus_t *usbus, usbus_handler_t *handler)
|
||||
DEBUG("CDC ECM: Reset\n");
|
||||
_handle_in_complete(usbus, handler);
|
||||
cdcecm->notif = USBUS_CDCECM_NOTIF_NONE;
|
||||
cdcecm->len = 0; /* Flush received data */
|
||||
cdcecm->active_iface = 0;
|
||||
mutex_unlock(&cdcecm->out_lock);
|
||||
}
|
||||
|
@ -132,7 +132,7 @@ static int _recv(netdev_t *netdev, void *buf, size_t max_len, void *info)
|
||||
(void)info;
|
||||
usbus_cdcecm_device_t *cdcecm = _netdev_to_cdcecm(netdev);
|
||||
|
||||
size_t pktlen = cdcecm->len;
|
||||
size_t pktlen = cdcecm->out_urb.transferred;
|
||||
|
||||
if (max_len == 0 && buf == NULL) {
|
||||
return pktlen;
|
||||
@ -198,7 +198,7 @@ static void _isr(netdev_t *dev)
|
||||
{
|
||||
usbus_cdcecm_device_t *cdcecm = _netdev_to_cdcecm(dev);
|
||||
|
||||
if (cdcecm->len) {
|
||||
if (cdcecm->out_urb.transferred) {
|
||||
cdcecm->netdev.event_callback(&cdcecm->netdev,
|
||||
NETDEV_EVENT_RX_COMPLETE);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user