Skip to content

Commit 87f2f7f

Browse files
committed
USBCDC_ECM: Add receive functionality
Handle SET_ETHERNET_PACKET_FILTER request
1 parent fc00718 commit 87f2f7f

File tree

2 files changed

+120
-30
lines changed

2 files changed

+120
-30
lines changed

usb/device/USBCDC_ECM/USBCDC_ECM.cpp

Lines changed: 69 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -22,31 +22,28 @@
2222
#include "mbed_interface.h"
2323
#include "mbed_assert.h"
2424

25-
#define MAX_SEGMENT_SIZE (1514)
26-
#define FLAG_WRITE_DONE (1 << 0)
27-
#define FLAG_DISCONNECT (1 << 1)
28-
#define FLAG_CONNECT (1 << 2)
29-
#define FLAG_INT_DONE (1 << 3)
25+
#ifndef MAX_SEGMENT_SIZE
26+
#define MAX_SEGMENT_SIZE (1514)
27+
#endif
28+
29+
#define FLAG_WRITE_DONE (1 << 0)
30+
#define FLAG_DISCONNECT (1 << 1)
31+
#define FLAG_CONNECT (1 << 2)
32+
#define FLAG_INT_DONE (1 << 3)
3033

3134
#define SET_ETHERNET_MULTICAST_FILTERS 0x40
3235
#define SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x41
3336
#define GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x42
3437
#define SET_ETHERNET_PACKET_FILTER 0x43
3538
#define GET_ETHERNET_STATISTIC 0x44
3639

37-
#define PACKET_TYPE_PROMISCUOUS (1<<0)
38-
#define PACKET_TYPE_ALL_MULTICAST (1<<1)
39-
#define PACKET_TYPE_DIRECTED (1<<2)
40-
#define PACKET_TYPE_BROADCAST (1<<3)
41-
#define PACKET_TYPE_MULTICAST (1<<4)
42-
4340
#define CS_INTERFACE 0x24
4441
#define NETWORK_CONNECTION 0x00
4542
#define CONNECTION_SPEED_CHANGE 0x2A
4643
#define LINK_SPEED (10000000)
4744

4845
USBCDC_ECM::USBCDC_ECM(bool connect_blocking, uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
49-
: USBDevice(get_usb_phy(), vendor_id, product_id, product_release), _queue(4 * EVENTS_EVENT_SIZE)
46+
: USBDevice(get_usb_phy(), vendor_id, product_id, product_release), _packet_filter(0), _queue(4 * EVENTS_EVENT_SIZE)
5047
{
5148
_init();
5249

@@ -60,7 +57,7 @@ USBCDC_ECM::USBCDC_ECM(bool connect_blocking, uint16_t vendor_id, uint16_t produ
6057
}
6158

6259
USBCDC_ECM::USBCDC_ECM(USBPhy *phy, uint16_t vendor_id, uint16_t product_id, uint16_t product_release)
63-
: USBDevice(phy, vendor_id, product_id, product_release), _queue(4 * EVENTS_EVENT_SIZE)
60+
: USBDevice(phy, vendor_id, product_id, product_release), _packet_filter(0), _queue(4 * EVENTS_EVENT_SIZE)
6461
{
6562

6663
_init();
@@ -235,6 +232,41 @@ bool USBCDC_ECM::send(uint8_t *buffer, uint32_t size)
235232
return ret;
236233
}
237234

235+
void USBCDC_ECM::receive_nb(uint8_t *buffer, uint32_t size, uint32_t *actual)
236+
{
237+
lock();
238+
239+
uint32_t available = _rx_queue.size();
240+
uint32_t copy_size = available > size ? size : available;
241+
_rx_queue.read(buffer, copy_size);
242+
*actual = copy_size;
243+
244+
unlock();
245+
}
246+
247+
void USBCDC_ECM::attach_rx(mbed::Callback<void()> cb)
248+
{
249+
lock();
250+
251+
_callback_rx = cb;
252+
253+
unlock();
254+
}
255+
256+
void USBCDC_ECM::attach_filter(mbed::Callback<void()> cb)
257+
{
258+
lock();
259+
260+
_callback_filter = cb;
261+
262+
unlock();
263+
}
264+
265+
uint16_t USBCDC_ECM::read_packet_filter()
266+
{
267+
return _packet_filter;
268+
}
269+
238270
void USBCDC_ECM::callback_request(const setup_packet_t *setup)
239271
{
240272
assert_locked();
@@ -247,30 +279,26 @@ void USBCDC_ECM::callback_request(const setup_packet_t *setup)
247279
//printf("In USBCallback_request: CLASS specific Request: %02x\n", setup->bRequest);
248280
switch (setup->bRequest) {
249281
case SET_ETHERNET_MULTICAST_FILTERS:
282+
/* TODO: Support is optional, not implemented here */
250283
break;
251284
case SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER:
285+
/* TODO: Support is optional, not implemented here */
252286
break;
253287
case GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER:
288+
/* TODO: Support is optional, not implemented here */
254289
break;
255290
case SET_ETHERNET_PACKET_FILTER:
256-
/*if (setup->wValue & PACKET_TYPE_PROMISCUOUS) {
257-
printf("PROMISCUOUS\n");
258-
}
259-
if (setup->wValue & PACKET_TYPE_ALL_MULTICAST) {
260-
printf("ALL_MULTICAST\n");
291+
if (_packet_filter != setup->wValue) {
292+
_packet_filter = setup->wValue;
293+
// Signal that packet filter configuration is changed
294+
if (_callback_filter) {
295+
_callback_filter();
296+
}
261297
}
262-
if (setup->wValue & PACKET_TYPE_DIRECTED) {
263-
printf("DIRECTED\n");
264-
}
265-
if (setup->wValue & PACKET_TYPE_BROADCAST) {
266-
printf("BROADCAST\n");
267-
}
268-
if (setup->wValue & PACKET_TYPE_MULTICAST) {
269-
printf("MULTICAST\n");
270-
}*/
271298
result = Success;
272299
break;
273300
case GET_ETHERNET_STATISTIC:
301+
/* TODO: Support is optional, not implemented here */
274302
break;
275303
default:
276304
result = Failure;
@@ -287,6 +315,9 @@ void USBCDC_ECM::callback_set_interface(uint16_t interface, uint8_t alternate)
287315
/* Called in ISR context */
288316

289317
if (alternate) {
318+
_packet_filter = 0;
319+
_rx_queue.resize(MAX_SEGMENT_SIZE);
320+
290321
endpoint_add(_int_in, MAX_PACKET_SIZE_INT, USB_EP_TYPE_INT, &USBCDC_ECM::_int_callback);
291322
endpoint_add(_bulk_in, MAX_PACKET_SIZE_BULK, USB_EP_TYPE_BULK, &USBCDC_ECM::_bulk_in_callback);
292323
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()
511542
{
512543
assert_locked();
513544

514-
_bulk_buf_size = read_finish(_bulk_out);
545+
uint32_t read_size = read_finish(_bulk_out);
546+
547+
if (read_size <= _rx_queue.free()) {
548+
// Copy data over
549+
_rx_queue.write(_bulk_buf, read_size);
550+
}
551+
552+
// Signal that there is ethernet packet available
553+
if (_callback_rx && (read_size < USBDevice::endpoint_max_packet_size(_bulk_out))) {
554+
_callback_rx();
555+
}
515556

516557
read_start(_bulk_out, _bulk_buf, MAX_PACKET_SIZE_BULK);
517558
}

usb/device/USBCDC_ECM/USBCDC_ECM.h

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,24 @@
2020

2121
#include "USBDescriptor.h"
2222
#include "USBDevice.h"
23-
23+
#include "ByteBuffer.h"
2424
#include "Mutex.h"
2525
#include "EventFlags.h"
2626
#include "EventQueue.h"
2727
#include "Thread.h"
28+
#include "Callback.h"
2829

2930
#define MAX_PACKET_SIZE_INT (64)
3031
#define MAX_PACKET_SIZE_BULK (64)
3132
#define MAX_PACKET_SIZE_EP0 (64)
3233
#define DEFAULT_CONFIGURATION (1)
3334

35+
#define PACKET_TYPE_PROMISCUOUS (1<<0)
36+
#define PACKET_TYPE_ALL_MULTICAST (1<<1)
37+
#define PACKET_TYPE_DIRECTED (1<<2)
38+
#define PACKET_TYPE_BROADCAST (1<<3)
39+
#define PACKET_TYPE_MULTICAST (1<<4)
40+
3441
class USBCDC_ECM: public USBDevice {
3542
public:
3643

@@ -98,6 +105,45 @@ class USBCDC_ECM: public USBDevice {
98105
*/
99106
bool send(uint8_t *buffer, uint32_t size);
100107

108+
/**
109+
* Read from the receive buffer
110+
*
111+
* @param buffer buffer to fill with data
112+
* @param size maximum number of bytes read
113+
* @param actual a pointer to where to store the number of bytes actually received
114+
*/
115+
void receive_nb(uint8_t *buffer, uint32_t size, uint32_t *actual);
116+
117+
/**
118+
* Return ethernet packet filter bitmap
119+
*
120+
* The Packet Filter is the inclusive OR of the bitmap
121+
* D0: PACKET_TYPE_PROMISCUOUS
122+
* D1: PACKET_TYPE_ALL_MULTICAST
123+
* D2: PACKET_TYPE_DIRECTED
124+
* D3: PACKET_TYPE_BROADCAST
125+
* D4: PACKET_TYPE_MULTICAST
126+
* D5-D15: Reserved (zero)
127+
*
128+
* @return ethernet packet filter bitmap
129+
*/
130+
uint16_t read_packet_filter();
131+
132+
/**
133+
* Attach a callback for when an ethernet packet is received
134+
*
135+
* @param cb code to call when a packet is received
136+
*/
137+
void attach_rx(mbed::Callback<void()> cb);
138+
139+
/**
140+
* Attach a callback for when a request to configure device ethernet
141+
* packet filter is received
142+
*
143+
* @param cb code to call when a packet filter request is received
144+
*/
145+
void attach_filter(mbed::Callback<void()> cb);
146+
101147
protected:
102148

103149
/*
@@ -200,13 +246,16 @@ class USBCDC_ECM: public USBDevice {
200246
uint8_t _string_imac_addr[26];
201247

202248
uint8_t _bulk_buf[MAX_PACKET_SIZE_BULK];
203-
uint32_t _bulk_buf_size;
249+
uint16_t _packet_filter;
250+
ByteBuffer _rx_queue;
204251

205252
rtos::EventFlags _flags;
206253
rtos::Mutex _write_mutex;
207254

208255
events::EventQueue _queue;
209256
rtos::Thread _thread;
257+
mbed::Callback<void()> _callback_rx;
258+
mbed::Callback<void()> _callback_filter;
210259

211260
void _init();
212261
void _int_callback();

0 commit comments

Comments
 (0)