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
daniele 2:540f6e142d59 7 Authors: Daniele Lacamera
daniele 2:540f6e142d59 8 *********************************************************************/
daniele 2:540f6e142d59 9
daniele 2:540f6e142d59 10
daniele 2:540f6e142d59 11 #include "pico_config.h"
daniele 2:540f6e142d59 12 #include "pico_frame.h"
daniele 2:540f6e142d59 13
daniele 2:540f6e142d59 14 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 2:540f6e142d59 15 static int n_frames_allocated;
daniele 2:540f6e142d59 16 #endif
daniele 2:540f6e142d59 17
daniele 2:540f6e142d59 18 /** frame alloc/dealloc/copy **/
daniele 2:540f6e142d59 19 void pico_frame_discard(struct pico_frame *f)
daniele 2:540f6e142d59 20 {
daniele 2:540f6e142d59 21 (*f->usage_count)--;
daniele 2:540f6e142d59 22 if (*f->usage_count <= 0) {
daniele 2:540f6e142d59 23 pico_free(f->usage_count);
daniele 2:540f6e142d59 24 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 2:540f6e142d59 25 dbg("Discarded buffer @%p, caller: %p\n", f->buffer, __builtin_return_address(3));
daniele 2:540f6e142d59 26 dbg("DEBUG MEMORY: %d frames in use.\n", --n_frames_allocated);
daniele 2:540f6e142d59 27 #endif
daniele 2:540f6e142d59 28 pico_free(f->buffer);
daniele 2:540f6e142d59 29 if (f->info)
daniele 2:540f6e142d59 30 pico_free(f->info);
daniele 2:540f6e142d59 31 }
daniele 2:540f6e142d59 32 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 2:540f6e142d59 33 else {
daniele 2:540f6e142d59 34 dbg("Removed frame @%p(copy), usage count now: %d\n", f, *f->usage_count);
daniele 2:540f6e142d59 35 }
daniele 2:540f6e142d59 36 #endif
daniele 2:540f6e142d59 37 pico_free(f);
daniele 2:540f6e142d59 38 }
daniele 2:540f6e142d59 39
daniele 2:540f6e142d59 40 struct pico_frame *pico_frame_copy(struct pico_frame *f)
daniele 2:540f6e142d59 41 {
daniele 2:540f6e142d59 42 struct pico_frame *new = pico_zalloc(sizeof(struct pico_frame));
daniele 2:540f6e142d59 43 if (!new)
daniele 2:540f6e142d59 44 return NULL;
daniele 2:540f6e142d59 45 memcpy(new, f, sizeof(struct pico_frame));
daniele 2:540f6e142d59 46 *(new->usage_count) += 1;
daniele 2:540f6e142d59 47 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 2:540f6e142d59 48 dbg("Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
daniele 2:540f6e142d59 49 #endif
daniele 2:540f6e142d59 50 new->next = NULL;
daniele 2:540f6e142d59 51 return new;
daniele 2:540f6e142d59 52 }
daniele 2:540f6e142d59 53
daniele 2:540f6e142d59 54
daniele 2:540f6e142d59 55 struct pico_frame *pico_frame_alloc(int size)
daniele 2:540f6e142d59 56 {
daniele 2:540f6e142d59 57 struct pico_frame *p = pico_zalloc(sizeof(struct pico_frame));
daniele 2:540f6e142d59 58 if (!p)
daniele 2:540f6e142d59 59 return NULL;
daniele 2:540f6e142d59 60 p->buffer = pico_zalloc(size);
daniele 2:540f6e142d59 61 if (!p->buffer) {
daniele 2:540f6e142d59 62 pico_free(p);
daniele 2:540f6e142d59 63 return NULL;
daniele 2:540f6e142d59 64 }
daniele 2:540f6e142d59 65 p->usage_count = pico_zalloc(sizeof(uint32_t));
daniele 2:540f6e142d59 66 if (!p->usage_count) {
daniele 2:540f6e142d59 67 pico_free(p->buffer);
daniele 2:540f6e142d59 68 pico_free(p);
daniele 2:540f6e142d59 69 return NULL;
daniele 2:540f6e142d59 70 }
daniele 2:540f6e142d59 71 p->buffer_len = size;
daniele 2:540f6e142d59 72
daniele 2:540f6e142d59 73
daniele 2:540f6e142d59 74 /* By default, frame content is the full buffer. */
daniele 2:540f6e142d59 75 p->start = p->buffer;
daniele 2:540f6e142d59 76 p->len = p->buffer_len;
daniele 2:540f6e142d59 77 *p->usage_count = 1;
daniele 2:540f6e142d59 78 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 2:540f6e142d59 79 dbg("Allocated buffer @%p, len= %d caller: %p\n", p->buffer, p->buffer_len, __builtin_return_address(2));
daniele 2:540f6e142d59 80 dbg("DEBUG MEMORY: %d frames in use.\n", ++n_frames_allocated);
daniele 2:540f6e142d59 81 #endif
daniele 2:540f6e142d59 82 return p;
daniele 2:540f6e142d59 83 }
daniele 2:540f6e142d59 84
daniele 2:540f6e142d59 85 struct pico_frame *pico_frame_deepcopy(struct pico_frame *f)
daniele 2:540f6e142d59 86 {
daniele 2:540f6e142d59 87 struct pico_frame *new = pico_frame_alloc(f->buffer_len);
daniele 2:540f6e142d59 88 int addr_diff;
daniele 2:540f6e142d59 89 unsigned char *buf;
daniele 2:540f6e142d59 90 uint32_t *uc;
daniele 2:540f6e142d59 91 if (!new)
daniele 2:540f6e142d59 92 return NULL;
daniele 2:540f6e142d59 93
daniele 2:540f6e142d59 94 /* Save the two key pointers... */
daniele 2:540f6e142d59 95 buf = new->buffer;
daniele 2:540f6e142d59 96 uc = new->usage_count;
daniele 2:540f6e142d59 97
daniele 2:540f6e142d59 98 /* Overwrite all fields with originals */
daniele 2:540f6e142d59 99 memcpy(new, f, sizeof(struct pico_frame));
daniele 2:540f6e142d59 100
daniele 2:540f6e142d59 101 /* ...restore the two key pointers */
daniele 2:540f6e142d59 102 new->buffer = buf;
daniele 2:540f6e142d59 103 new->usage_count = uc;
daniele 2:540f6e142d59 104
daniele 2:540f6e142d59 105 /* Update in-buffer pointers with offset */
daniele 2:540f6e142d59 106 addr_diff = (int)new->buffer - (int)f->buffer;
daniele 2:540f6e142d59 107 new->net_hdr += addr_diff;
daniele 2:540f6e142d59 108 new->transport_hdr += addr_diff;
daniele 2:540f6e142d59 109 new->app_hdr += addr_diff;
daniele 2:540f6e142d59 110 new->start += addr_diff;
daniele 2:540f6e142d59 111 new->payload += addr_diff;
daniele 2:540f6e142d59 112
daniele 2:540f6e142d59 113 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 2:540f6e142d59 114 dbg("Deep-Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
daniele 2:540f6e142d59 115 #endif
daniele 2:540f6e142d59 116 new->next = NULL;
daniele 2:540f6e142d59 117 return new;
daniele 2:540f6e142d59 118 }
daniele 2:540f6e142d59 119
daniele 2:540f6e142d59 120 /**
daniele 2:540f6e142d59 121 * Calculate checksum of a given string
daniele 2:540f6e142d59 122 */
daniele 2:540f6e142d59 123 uint16_t pico_checksum(void *inbuf, int len)
daniele 2:540f6e142d59 124 {
daniele 2:540f6e142d59 125 uint8_t *buf = (uint8_t *) inbuf;
daniele 2:540f6e142d59 126 uint16_t tmp = 0;
daniele 2:540f6e142d59 127 uint32_t sum = 0;
daniele 2:540f6e142d59 128 int i = 0;
daniele 2:540f6e142d59 129
daniele 2:540f6e142d59 130 for(i=0; i < len; i++) {
daniele 2:540f6e142d59 131 if (i%2) {
daniele 2:540f6e142d59 132 sum += buf[i];
daniele 2:540f6e142d59 133 } else {
daniele 2:540f6e142d59 134 tmp = buf[i];
daniele 2:540f6e142d59 135 sum += (tmp << 8);
daniele 2:540f6e142d59 136 }
daniele 2:540f6e142d59 137 }
daniele 2:540f6e142d59 138
daniele 2:540f6e142d59 139 while (sum >> 16) { /* a second carry is possible! */
daniele 2:540f6e142d59 140 sum = (sum & 0x0000FFFF) + (sum >> 16);
daniele 2:540f6e142d59 141 }
daniele 2:540f6e142d59 142 return (uint16_t) (~sum);
daniele 2:540f6e142d59 143 }
daniele 2:540f6e142d59 144
daniele 2:540f6e142d59 145 uint16_t pico_dualbuffer_checksum(void *inbuf1, int len1, void *inbuf2, int len2)
daniele 2:540f6e142d59 146 {
daniele 2:540f6e142d59 147 uint8_t *b1 = (uint8_t *) inbuf1;
daniele 2:540f6e142d59 148 uint8_t *b2 = (uint8_t *) inbuf2;
daniele 2:540f6e142d59 149 uint16_t tmp = 0;
daniele 2:540f6e142d59 150 uint32_t sum = 0;
daniele 2:540f6e142d59 151 int i = 0, j = 0;
daniele 2:540f6e142d59 152
daniele 2:540f6e142d59 153 for(i=0; i < len1; i++) {
daniele 2:540f6e142d59 154 if (j%2) {
daniele 2:540f6e142d59 155 sum += b1[i];
daniele 2:540f6e142d59 156 } else {
daniele 2:540f6e142d59 157 tmp = b1[i];
daniele 2:540f6e142d59 158 sum += (tmp << 8);
daniele 2:540f6e142d59 159 }
daniele 2:540f6e142d59 160 j++;
daniele 2:540f6e142d59 161 }
daniele 2:540f6e142d59 162
daniele 2:540f6e142d59 163 j = 0; /* j has to be reset if len1 is odd */
daniele 2:540f6e142d59 164 for(i=0; i < len2; i++) {
daniele 2:540f6e142d59 165 if (j%2) {
daniele 2:540f6e142d59 166 sum += b2[i];
daniele 2:540f6e142d59 167 } else {
daniele 2:540f6e142d59 168 tmp = b2[i];
daniele 2:540f6e142d59 169 sum += (tmp << 8);
daniele 2:540f6e142d59 170 }
daniele 2:540f6e142d59 171 j++;
daniele 2:540f6e142d59 172 }
daniele 2:540f6e142d59 173 while (sum >> 16) { /* a second carry is possible! */
daniele 2:540f6e142d59 174 sum = (sum & 0x0000FFFF) + (sum >> 16);
daniele 2:540f6e142d59 175 }
daniele 2:540f6e142d59 176 return (uint16_t) (~sum);
daniele 2:540f6e142d59 177 }
daniele 2:540f6e142d59 178
daniele 2:540f6e142d59 179 uint16_t pico_dualbuffer_checksum_broken(void *inbuf1, int len1, void *inbuf2, int len2)
daniele 2:540f6e142d59 180 {
daniele 2:540f6e142d59 181 uint16_t *b1 = (uint16_t *) inbuf1;
daniele 2:540f6e142d59 182 uint16_t *b2 = (uint16_t *) inbuf2;
daniele 2:540f6e142d59 183 uint32_t sum = 0;
daniele 2:540f6e142d59 184 int i=0, j=0;
daniele 2:540f6e142d59 185 for(i=0; i<(len1>>1); i++){
daniele 2:540f6e142d59 186 sum += short_be(b1[i]);
daniele 2:540f6e142d59 187 j++;
daniele 2:540f6e142d59 188 }
daniele 2:540f6e142d59 189 for(i=0; i<(len2>>1); i++){
daniele 2:540f6e142d59 190 sum += short_be(b2[i]);
daniele 2:540f6e142d59 191 j++;
daniele 2:540f6e142d59 192 }
daniele 2:540f6e142d59 193 sum = (sum & 0xFFFF) + (sum >> 16);
daniele 2:540f6e142d59 194 sum += (sum >> 16);
daniele 2:540f6e142d59 195
daniele 2:540f6e142d59 196 // Take the bitwise complement of sum
daniele 2:540f6e142d59 197 sum = ~sum;
daniele 2:540f6e142d59 198 return (uint16_t) (sum) ;
daniele 2:540f6e142d59 199 }
daniele 2:540f6e142d59 200
daniele 2:540f6e142d59 201