CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

Committer:
daniele
Date:
Sat Aug 03 13:16:14 2013 +0000
Revision:
2:540f6e142d59
Moved to single package

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 2:540f6e142d59 1 /*********************************************************************
daniele 2:540f6e142d59 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 2:540f6e142d59 3 See LICENSE and COPYING for usage.
daniele 2:540f6e142d59 4
daniele 2:540f6e142d59 5 *********************************************************************/
daniele 2:540f6e142d59 6 #ifndef _INCLUDE_PICO_QUEUE
daniele 2:540f6e142d59 7 #define _INCLUDE_PICO_QUEUE
daniele 2:540f6e142d59 8 #include <stdint.h>
daniele 2:540f6e142d59 9 #include "pico_config.h"
daniele 2:540f6e142d59 10 #include "pico_frame.h"
daniele 2:540f6e142d59 11
daniele 2:540f6e142d59 12 #define Q_LIMIT 0
daniele 2:540f6e142d59 13
daniele 2:540f6e142d59 14 #ifndef NULL
daniele 2:540f6e142d59 15 #define NULL ((void *)0)
daniele 2:540f6e142d59 16 #endif
daniele 2:540f6e142d59 17
daniele 2:540f6e142d59 18 struct pico_queue {
daniele 2:540f6e142d59 19 uint32_t frames;
daniele 2:540f6e142d59 20 uint32_t size;
daniele 2:540f6e142d59 21 uint32_t max_frames;
daniele 2:540f6e142d59 22 uint32_t max_size;
daniele 2:540f6e142d59 23 struct pico_frame *head;
daniele 2:540f6e142d59 24 struct pico_frame *tail;
daniele 2:540f6e142d59 25 #ifdef PICO_SUPPORT_MUTEX
daniele 2:540f6e142d59 26 void * mutex;
daniele 2:540f6e142d59 27 #endif
daniele 2:540f6e142d59 28 uint8_t shared;
daniele 2:540f6e142d59 29 };
daniele 2:540f6e142d59 30
daniele 2:540f6e142d59 31 #ifdef PICO_SUPPORT_MUTEX
daniele 2:540f6e142d59 32 #define LOCK(x) {\
daniele 2:540f6e142d59 33 if (x == NULL) \
daniele 2:540f6e142d59 34 x = pico_mutex_init(); \
daniele 2:540f6e142d59 35 pico_mutex_lock(x); \
daniele 2:540f6e142d59 36 }
daniele 2:540f6e142d59 37 #define UNLOCK(x) pico_mutex_unlock(x);
daniele 2:540f6e142d59 38
daniele 2:540f6e142d59 39 #else
daniele 2:540f6e142d59 40 #define LOCK(x) do{}while(0)
daniele 2:540f6e142d59 41 #define UNLOCK(x) do{}while(0)
daniele 2:540f6e142d59 42 #endif
daniele 2:540f6e142d59 43
daniele 2:540f6e142d59 44 #ifdef PICO_SUPPORT_DEBUG_TOOLS
daniele 2:540f6e142d59 45 static void debug_q(struct pico_queue *q)
daniele 2:540f6e142d59 46 {
daniele 2:540f6e142d59 47 struct pico_frame *p = q->head;
daniele 2:540f6e142d59 48 dbg("%d: ", q->frames);
daniele 2:540f6e142d59 49 while(p) {
daniele 2:540f6e142d59 50 dbg("(%p)-->", p);
daniele 2:540f6e142d59 51 p = p->next;
daniele 2:540f6e142d59 52 }
daniele 2:540f6e142d59 53 dbg("X\n");
daniele 2:540f6e142d59 54 }
daniele 2:540f6e142d59 55
daniele 2:540f6e142d59 56 #else
daniele 2:540f6e142d59 57
daniele 2:540f6e142d59 58 #define debug_q(x) do{}while(0)
daniele 2:540f6e142d59 59 #endif
daniele 2:540f6e142d59 60
daniele 2:540f6e142d59 61 static inline int pico_enqueue(struct pico_queue *q, struct pico_frame *p)
daniele 2:540f6e142d59 62 {
daniele 2:540f6e142d59 63 if ((q->max_frames) && (q->max_frames <= q->frames))
daniele 2:540f6e142d59 64 return -1;
daniele 2:540f6e142d59 65
daniele 2:540f6e142d59 66 if ((Q_LIMIT) && (Q_LIMIT < p->buffer_len + q->size))
daniele 2:540f6e142d59 67 return -1;
daniele 2:540f6e142d59 68
daniele 2:540f6e142d59 69 if ((q->max_size) && (q->max_size < (p->buffer_len + q->size)))
daniele 2:540f6e142d59 70 return -1;
daniele 2:540f6e142d59 71
daniele 2:540f6e142d59 72 if (q->shared)
daniele 2:540f6e142d59 73 LOCK(q->mutex);
daniele 2:540f6e142d59 74
daniele 2:540f6e142d59 75 p->next = NULL;
daniele 2:540f6e142d59 76 if (!q->head) {
daniele 2:540f6e142d59 77 q->head = p;
daniele 2:540f6e142d59 78 q->tail = p;
daniele 2:540f6e142d59 79 q->size = 0;
daniele 2:540f6e142d59 80 q->frames = 0;
daniele 2:540f6e142d59 81 } else {
daniele 2:540f6e142d59 82 q->tail->next = p;
daniele 2:540f6e142d59 83 q->tail = p;
daniele 2:540f6e142d59 84 }
daniele 2:540f6e142d59 85 q->size += p->buffer_len;
daniele 2:540f6e142d59 86 q->frames++;
daniele 2:540f6e142d59 87 debug_q(q);
daniele 2:540f6e142d59 88
daniele 2:540f6e142d59 89 if (q->shared)
daniele 2:540f6e142d59 90 UNLOCK(q->mutex);
daniele 2:540f6e142d59 91 return q->size;
daniele 2:540f6e142d59 92 }
daniele 2:540f6e142d59 93
daniele 2:540f6e142d59 94 static inline struct pico_frame *pico_dequeue(struct pico_queue *q)
daniele 2:540f6e142d59 95 {
daniele 2:540f6e142d59 96 struct pico_frame *p = q->head;
daniele 2:540f6e142d59 97 if (q->frames < 1)
daniele 2:540f6e142d59 98 return NULL;
daniele 2:540f6e142d59 99 if (q->shared)
daniele 2:540f6e142d59 100 LOCK(q->mutex);
daniele 2:540f6e142d59 101
daniele 2:540f6e142d59 102 q->head = p->next;
daniele 2:540f6e142d59 103 q->frames--;
daniele 2:540f6e142d59 104 q->size -= p->buffer_len;
daniele 2:540f6e142d59 105 if (q->head == NULL)
daniele 2:540f6e142d59 106 q->tail = NULL;
daniele 2:540f6e142d59 107 debug_q(q);
daniele 2:540f6e142d59 108 p->next = NULL;
daniele 2:540f6e142d59 109 if (q->shared)
daniele 2:540f6e142d59 110 UNLOCK(q->mutex);
daniele 2:540f6e142d59 111 return p;
daniele 2:540f6e142d59 112 }
daniele 2:540f6e142d59 113
daniele 2:540f6e142d59 114 static inline struct pico_frame *pico_queue_peek(struct pico_queue *q)
daniele 2:540f6e142d59 115 {
daniele 2:540f6e142d59 116 struct pico_frame *p = q->head;
daniele 2:540f6e142d59 117 if (q->frames < 1)
daniele 2:540f6e142d59 118 return NULL;
daniele 2:540f6e142d59 119 debug_q(q);
daniele 2:540f6e142d59 120 return p;
daniele 2:540f6e142d59 121 }
daniele 2:540f6e142d59 122
daniele 2:540f6e142d59 123 static inline void pico_queue_empty(struct pico_queue *q)
daniele 2:540f6e142d59 124 {
daniele 2:540f6e142d59 125 struct pico_frame *p = pico_dequeue(q);
daniele 2:540f6e142d59 126 while(p) {
daniele 2:540f6e142d59 127 pico_free(p);
daniele 2:540f6e142d59 128 p = pico_dequeue(q);
daniele 2:540f6e142d59 129 }
daniele 2:540f6e142d59 130 }
daniele 2:540f6e142d59 131
daniele 2:540f6e142d59 132 static inline void pico_queue_protect(struct pico_queue *q)
daniele 2:540f6e142d59 133 {
daniele 2:540f6e142d59 134 q->shared = 1;
daniele 2:540f6e142d59 135 }
daniele 2:540f6e142d59 136
daniele 2:540f6e142d59 137 #endif