22
22
#include " mbed_interface.h"
23
23
#include " mbed_assert.h"
24
24
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 )
30
33
31
34
#define SET_ETHERNET_MULTICAST_FILTERS 0x40
32
35
#define SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x41
33
36
#define GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER 0x42
34
37
#define SET_ETHERNET_PACKET_FILTER 0x43
35
38
#define GET_ETHERNET_STATISTIC 0x44
36
39
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
-
43
40
#define CS_INTERFACE 0x24
44
41
#define NETWORK_CONNECTION 0x00
45
42
#define CONNECTION_SPEED_CHANGE 0x2A
46
43
#define LINK_SPEED (10000000 )
47
44
48
45
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)
50
47
{
51
48
_init ();
52
49
@@ -60,7 +57,7 @@ USBCDC_ECM::USBCDC_ECM(bool connect_blocking, uint16_t vendor_id, uint16_t produ
60
57
}
61
58
62
59
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)
64
61
{
65
62
66
63
_init ();
@@ -235,6 +232,41 @@ bool USBCDC_ECM::send(uint8_t *buffer, uint32_t size)
235
232
return ret;
236
233
}
237
234
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
+
238
270
void USBCDC_ECM::callback_request (const setup_packet_t *setup)
239
271
{
240
272
assert_locked ();
@@ -247,30 +279,26 @@ void USBCDC_ECM::callback_request(const setup_packet_t *setup)
247
279
// printf("In USBCallback_request: CLASS specific Request: %02x\n", setup->bRequest);
248
280
switch (setup->bRequest ) {
249
281
case SET_ETHERNET_MULTICAST_FILTERS:
282
+ /* TODO: Support is optional, not implemented here */
250
283
break ;
251
284
case SET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER:
285
+ /* TODO: Support is optional, not implemented here */
252
286
break ;
253
287
case GET_ETHERNET_POWER_MANAGEMENT_PATTERN_FILTER:
288
+ /* TODO: Support is optional, not implemented here */
254
289
break ;
255
290
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
+ }
261
297
}
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
- }*/
271
298
result = Success;
272
299
break ;
273
300
case GET_ETHERNET_STATISTIC:
301
+ /* TODO: Support is optional, not implemented here */
274
302
break ;
275
303
default :
276
304
result = Failure;
@@ -287,6 +315,9 @@ void USBCDC_ECM::callback_set_interface(uint16_t interface, uint8_t alternate)
287
315
/* Called in ISR context */
288
316
289
317
if (alternate) {
318
+ _packet_filter = 0 ;
319
+ _rx_queue.resize (MAX_SEGMENT_SIZE);
320
+
290
321
endpoint_add (_int_in, MAX_PACKET_SIZE_INT, USB_EP_TYPE_INT, &USBCDC_ECM::_int_callback);
291
322
endpoint_add (_bulk_in, MAX_PACKET_SIZE_BULK, USB_EP_TYPE_BULK, &USBCDC_ECM::_bulk_in_callback);
292
323
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()
511
542
{
512
543
assert_locked ();
513
544
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
+ }
515
556
516
557
read_start (_bulk_out, _bulk_buf, MAX_PACKET_SIZE_BULK);
517
558
}
0 commit comments