mirror of https://github.com/ARMmbed/mbed-os.git
USBCDC_ECM: Add receive functionality
Handle SET_ETHERNET_PACKET_FILTER requestpull/9443/head
parent
fc00718917
commit
87f2f7f93f
|
@ -22,11 +22,14 @@
|
|||
#include "mbed_interface.h"
|
||||
#include "mbed_assert.h"
|
||||
|
||||
#define MAX_SEGMENT_SIZE (1514)
|
||||
#define FLAG_WRITE_DONE (1 << 0)
|
||||
#define FLAG_DISCONNECT (1 << 1)
|
||||
#define FLAG_CONNECT (1 << 2)
|
||||
#define FLAG_INT_DONE (1 << 3)
|
||||
#ifndef MAX_SEGMENT_SIZE
|
||||
#define MAX_SEGMENT_SIZE (1514)
|
||||
#endif
|
||||
|
||||
#define FLAG_WRITE_DONE (1 << 0)
|
||||
#define FLAG_DISCONNECT (1 << 1)
|
||||
#define FLAG_CONNECT (1 << 2)
|
||||
#define FLAG_INT_DONE (1 << 3)
|
||||
|
||||
#define SET_ETHERNET_MULTICAST_FILTERS 0x40
|
||||
#define SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x41
|
||||
|
@ -34,19 +37,13 @@
|
|||
#define SET_ETHERNET_PACKET_FILTER 0x43
|
||||
#define GET_ETHERNET_STATISTIC 0x44
|
||||
|
||||
#define PACKET_TYPE_PROMISCUOUS (1<<0)
|
||||
#define PACKET_TYPE_ALL_MULTICAST (1<<1)
|
||||
#define PACKET_TYPE_DIRECTED (1<<2)
|
||||
#define PACKET_TYPE_BROADCAST (1<<3)
|
||||
#define PACKET_TYPE_MULTICAST (1<<4)
|
||||
|
||||
#define CS_INTERFACE 0x24
|
||||
#define NETWORK_CONNECTION 0x00
|
||||
#define CONNECTION_SPEED_CHANGE 0x2A
|
||||
#define LINK_SPEED (10000000)
|
||||
|
||||
USBCDC_ECM::USBCDC_ECM(bool connect_blocking, uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
|
||||
: USBDevice(get_usb_phy(), vendor_id, product_id, product_release), _queue(4 * EVENTS_EVENT_SIZE)
|
||||
: USBDevice(get_usb_phy(), vendor_id, product_id, product_release), _packet_filter(0), _queue(4 * EVENTS_EVENT_SIZE)
|
||||
{
|
||||
_init();
|
||||
|
||||
|
@ -60,7 +57,7 @@ USBCDC_ECM::USBCDC_ECM(bool connect_blocking, uint16_t vendor_id, uint16_t produ
|
|||
}
|
||||
|
||||
USBCDC_ECM::USBCDC_ECM(USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
|
||||
: USBDevice(phy, vendor_id, product_id, product_release), _queue(4 * EVENTS_EVENT_SIZE)
|
||||
: USBDevice(phy, vendor_id, product_id, product_release), _packet_filter(0), _queue(4 * EVENTS_EVENT_SIZE)
|
||||
{
|
||||
|
||||
_init();
|
||||
|
@ -235,6 +232,41 @@ bool USBCDC_ECM::send(uint8_t *buffer, uint32_t size)
|
|||
return ret;
|
||||
}
|
||||
|
||||
void USBCDC_ECM::receive_nb(uint8_t *buffer, uint32_t size, uint32_t *actual)
|
||||
{
|
||||
lock();
|
||||
|
||||
uint32_t available = _rx_queue.size();
|
||||
uint32_t copy_size = available > size ? size : available;
|
||||
_rx_queue.read(buffer, copy_size);
|
||||
*actual = copy_size;
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
void USBCDC_ECM::attach_rx(mbed::Callback<void()> cb)
|
||||
{
|
||||
lock();
|
||||
|
||||
_callback_rx = cb;
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
void USBCDC_ECM::attach_filter(mbed::Callback<void()> cb)
|
||||
{
|
||||
lock();
|
||||
|
||||
_callback_filter = cb;
|
||||
|
||||
unlock();
|
||||
}
|
||||
|
||||
uint16_t USBCDC_ECM::read_packet_filter()
|
||||
{
|
||||
return _packet_filter;
|
||||
}
|
||||
|
||||
void USBCDC_ECM::callback_request(const setup_packet_t *setup)
|
||||
{
|
||||
assert_locked();
|
||||
|
@ -247,30 +279,26 @@ void USBCDC_ECM::callback_request(const setup_packet_t *setup)
|
|||
//printf("In USBCallback_request: CLASS specific Request: %02x\n", setup->bRequest);
|
||||
switch (setup->bRequest) {
|
||||
case SET_ETHERNET_MULTICAST_FILTERS:
|
||||
/* TODO: Support is optional, not implemented here */
|
||||
break;
|
||||
case SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER:
|
||||
/* TODO: Support is optional, not implemented here */
|
||||
break;
|
||||
case GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER:
|
||||
/* TODO: Support is optional, not implemented here */
|
||||
break;
|
||||
case SET_ETHERNET_PACKET_FILTER:
|
||||
/*if (setup->wValue & PACKET_TYPE_PROMISCUOUS) {
|
||||
printf("PROMISCUOUS\n");
|
||||
if (_packet_filter != setup->wValue) {
|
||||
_packet_filter = setup->wValue;
|
||||
// Signal that packet filter configuration is changed
|
||||
if (_callback_filter) {
|
||||
_callback_filter();
|
||||
}
|
||||
}
|
||||
if (setup->wValue & PACKET_TYPE_ALL_MULTICAST) {
|
||||
printf("ALL_MULTICAST\n");
|
||||
}
|
||||
if (setup->wValue & PACKET_TYPE_DIRECTED) {
|
||||
printf("DIRECTED\n");
|
||||
}
|
||||
if (setup->wValue & PACKET_TYPE_BROADCAST) {
|
||||
printf("BROADCAST\n");
|
||||
}
|
||||
if (setup->wValue & PACKET_TYPE_MULTICAST) {
|
||||
printf("MULTICAST\n");
|
||||
}*/
|
||||
result = Success;
|
||||
break;
|
||||
case GET_ETHERNET_STATISTIC:
|
||||
/* TODO: Support is optional, not implemented here */
|
||||
break;
|
||||
default:
|
||||
result = Failure;
|
||||
|
@ -287,6 +315,9 @@ void USBCDC_ECM::callback_set_interface(uint16_t interface, uint8_t alternate)
|
|||
/* Called in ISR context */
|
||||
|
||||
if (alternate) {
|
||||
_packet_filter = 0;
|
||||
_rx_queue.resize(MAX_SEGMENT_SIZE);
|
||||
|
||||
endpoint_add(_int_in, MAX_PACKET_SIZE_INT, USB_EP_TYPE_INT, &USBCDC_ECM::_int_callback);
|
||||
endpoint_add(_bulk_in, MAX_PACKET_SIZE_BULK, USB_EP_TYPE_BULK, &USBCDC_ECM::_bulk_in_callback);
|
||||
endpoint_add(_bulk_out, MAX_PACKET_SIZE_BULK, USB_EP_TYPE_BULK, &USBCDC_ECM::_bulk_out_callback);
|
||||
|
@ -511,7 +542,17 @@ void USBCDC_ECM::_bulk_out_callback()
|
|||
{
|
||||
assert_locked();
|
||||
|
||||
_bulk_buf_size = read_finish(_bulk_out);
|
||||
uint32_t read_size = read_finish(_bulk_out);
|
||||
|
||||
if (read_size <= _rx_queue.free()) {
|
||||
// Copy data over
|
||||
_rx_queue.write(_bulk_buf, read_size);
|
||||
}
|
||||
|
||||
// Signal that there is ethernet packet available
|
||||
if (_callback_rx && (read_size < USBDevice::endpoint_max_packet_size(_bulk_out))) {
|
||||
_callback_rx();
|
||||
}
|
||||
|
||||
read_start(_bulk_out, _bulk_buf, MAX_PACKET_SIZE_BULK);
|
||||
}
|
||||
|
|
|
@ -20,17 +20,24 @@
|
|||
|
||||
#include "USBDescriptor.h"
|
||||
#include "USBDevice.h"
|
||||
|
||||
#include "ByteBuffer.h"
|
||||
#include "Mutex.h"
|
||||
#include "EventFlags.h"
|
||||
#include "EventQueue.h"
|
||||
#include "Thread.h"
|
||||
#include "Callback.h"
|
||||
|
||||
#define MAX_PACKET_SIZE_INT (64)
|
||||
#define MAX_PACKET_SIZE_BULK (64)
|
||||
#define MAX_PACKET_SIZE_EP0 (64)
|
||||
#define DEFAULT_CONFIGURATION (1)
|
||||
|
||||
#define PACKET_TYPE_PROMISCUOUS (1<<0)
|
||||
#define PACKET_TYPE_ALL_MULTICAST (1<<1)
|
||||
#define PACKET_TYPE_DIRECTED (1<<2)
|
||||
#define PACKET_TYPE_BROADCAST (1<<3)
|
||||
#define PACKET_TYPE_MULTICAST (1<<4)
|
||||
|
||||
class USBCDC_ECM: public USBDevice {
|
||||
public:
|
||||
|
||||
|
@ -98,6 +105,45 @@ public:
|
|||
*/
|
||||
bool send(uint8_t *buffer, uint32_t size);
|
||||
|
||||
/**
|
||||
* Read from the receive buffer
|
||||
*
|
||||
* @param buffer buffer to fill with data
|
||||
* @param size maximum number of bytes read
|
||||
* @param actual a pointer to where to store the number of bytes actually received
|
||||
*/
|
||||
void receive_nb(uint8_t *buffer, uint32_t size, uint32_t *actual);
|
||||
|
||||
/**
|
||||
* Return ethernet packet filter bitmap
|
||||
*
|
||||
* The Packet Filter is the inclusive OR of the bitmap
|
||||
* D0: PACKET_TYPE_PROMISCUOUS
|
||||
* D1: PACKET_TYPE_ALL_MULTICAST
|
||||
* D2: PACKET_TYPE_DIRECTED
|
||||
* D3: PACKET_TYPE_BROADCAST
|
||||
* D4: PACKET_TYPE_MULTICAST
|
||||
* D5-D15: Reserved (zero)
|
||||
*
|
||||
* @return ethernet packet filter bitmap
|
||||
*/
|
||||
uint16_t read_packet_filter();
|
||||
|
||||
/**
|
||||
* Attach a callback for when an ethernet packet is received
|
||||
*
|
||||
* @param cb code to call when a packet is received
|
||||
*/
|
||||
void attach_rx(mbed::Callback<void()> cb);
|
||||
|
||||
/**
|
||||
* Attach a callback for when a request to configure device ethernet
|
||||
* packet filter is received
|
||||
*
|
||||
* @param cb code to call when a packet filter request is received
|
||||
*/
|
||||
void attach_filter(mbed::Callback<void()> cb);
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
|
@ -200,13 +246,16 @@ private:
|
|||
uint8_t _string_imac_addr[26];
|
||||
|
||||
uint8_t _bulk_buf[MAX_PACKET_SIZE_BULK];
|
||||
uint32_t _bulk_buf_size;
|
||||
uint16_t _packet_filter;
|
||||
ByteBuffer _rx_queue;
|
||||
|
||||
rtos::EventFlags _flags;
|
||||
rtos::Mutex _write_mutex;
|
||||
|
||||
events::EventQueue _queue;
|
||||
rtos::Thread _thread;
|
||||
mbed::Callback<void()> _callback_rx;
|
||||
mbed::Callback<void()> _callback_filter;
|
||||
|
||||
void _init();
|
||||
void _int_callback();
|
||||
|
|
Loading…
Reference in New Issue