1
0
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:
Koen Zandberg 2021-10-31 21:40:09 +01:00
parent 7bfdd73818
commit ba88608749
No known key found for this signature in database
GPG Key ID: BA1718B37D79F51C
4 changed files with 27 additions and 23 deletions

View File

@ -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

View File

@ -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;
/**

View File

@ -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);
}

View File

@ -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);
}