USB Host WAN Dongle library

Fork of USBHostWANDongle_bleedingedge by Donatien Garnier

Committer:
donatien
Date:
Tue Jul 31 10:37:16 2012 +0000
Revision:
9:c9e9817c398c
Parent:
USBHost/Endpoint.cpp@7:c4483d48fe96
Child:
12:a712bad7a979
Renamed Endpoint->USBEndpoint because it conflicted with the Socket API! Made some weird symbols mixups happen that made everything explode when the first USB endpoint was allocated.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
donatien 9:c9e9817c398c 1 /* Copyright (c) 2010-2012 mbed.org, MIT License
donatien 0:ae46a0638b2c 2 *
donatien 0:ae46a0638b2c 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
donatien 0:ae46a0638b2c 4 * and associated documentation files (the "Software"), to deal in the Software without
donatien 0:ae46a0638b2c 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
donatien 0:ae46a0638b2c 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
donatien 0:ae46a0638b2c 7 * Software is furnished to do so, subject to the following conditions:
donatien 0:ae46a0638b2c 8 *
donatien 0:ae46a0638b2c 9 * The above copyright notice and this permission notice shall be included in all copies or
donatien 0:ae46a0638b2c 10 * substantial portions of the Software.
donatien 0:ae46a0638b2c 11 *
donatien 0:ae46a0638b2c 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
donatien 0:ae46a0638b2c 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
donatien 0:ae46a0638b2c 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
donatien 0:ae46a0638b2c 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
donatien 0:ae46a0638b2c 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
donatien 0:ae46a0638b2c 17 */
donatien 0:ae46a0638b2c 18
donatien 0:ae46a0638b2c 19
donatien 0:ae46a0638b2c 20 #define __DEBUG__ 0 //Maximum verbosity
donatien 0:ae46a0638b2c 21 #ifndef __MODULE__
donatien 9:c9e9817c398c 22 #define __MODULE__ "USBEndpoint.cpp"
donatien 0:ae46a0638b2c 23 #endif
donatien 0:ae46a0638b2c 24
donatien 0:ae46a0638b2c 25 #include "dbg.h"
donatien 0:ae46a0638b2c 26 #include <cstdint>
donatien 0:ae46a0638b2c 27
donatien 9:c9e9817c398c 28 #include "USBEndpoint.h"
donatien 0:ae46a0638b2c 29
donatien 0:ae46a0638b2c 30
donatien 9:c9e9817c398c 31 void USBEndpoint::init(HCED * hced, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t ep_number, HCTD* td_list[2]) {
donatien 0:ae46a0638b2c 32 this->hced = hced;
donatien 0:ae46a0638b2c 33 this->type = type;
donatien 0:ae46a0638b2c 34 this->dir = /*(type == CONTROL_ENDPOINT) ? OUT :*/ dir;
donatien 0:ae46a0638b2c 35 setup = (type == CONTROL_ENDPOINT) ? true : false;
donatien 0:ae46a0638b2c 36
donatien 0:ae46a0638b2c 37 //TDs have been allocated by the host
donatien 0:ae46a0638b2c 38 memcpy((HCTD**)this->td_list, td_list, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define
donatien 0:ae46a0638b2c 39 memcpy(td_list[0], 0, sizeof(HCTD));
donatien 0:ae46a0638b2c 40 memcpy(td_list[1], 0, sizeof(HCTD));
donatien 0:ae46a0638b2c 41
donatien 0:ae46a0638b2c 42 this->hced->control = 0;
donatien 0:ae46a0638b2c 43 //Empty queue
donatien 0:ae46a0638b2c 44 this->hced->tailTD = (uint32_t)td_list[0];
donatien 0:ae46a0638b2c 45 this->hced->headTD = (uint32_t)td_list[0];
donatien 0:ae46a0638b2c 46 this->hced->nextED = 0;
donatien 0:ae46a0638b2c 47
donatien 0:ae46a0638b2c 48 this->hced->control = ((ep_number & 0x7F) << 7) // Endpoint address
donatien 0:ae46a0638b2c 49 | (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 ) // direction : Out = 1, 2 = In
donatien 0:ae46a0638b2c 50 | ((size & 0x3ff) << 16); // MaxPkt Size
donatien 0:ae46a0638b2c 51
donatien 0:ae46a0638b2c 52 //carry = false;
donatien 0:ae46a0638b2c 53 transfer_len = 0;
donatien 0:ae46a0638b2c 54 transferred = 0;
donatien 0:ae46a0638b2c 55 buf_start = 0;
donatien 0:ae46a0638b2c 56 nextEp = NULL;
donatien 0:ae46a0638b2c 57
donatien 0:ae46a0638b2c 58 td_current = td_list[0];
donatien 0:ae46a0638b2c 59 td_next = td_list[1];
donatien 0:ae46a0638b2c 60
donatien 0:ae46a0638b2c 61 state = USB_TYPE_IDLE;
donatien 0:ae46a0638b2c 62 }
donatien 0:ae46a0638b2c 63
donatien 9:c9e9817c398c 64 void USBEndpoint::setSize(uint32_t size) {
donatien 0:ae46a0638b2c 65 hced->control &= ~(0x3ff << 16);
donatien 0:ae46a0638b2c 66 hced->control |= (size << 16);
donatien 0:ae46a0638b2c 67 }
donatien 0:ae46a0638b2c 68
donatien 0:ae46a0638b2c 69
donatien 9:c9e9817c398c 70 uint32_t USBEndpoint::getSize() {
donatien 0:ae46a0638b2c 71 return (hced->control >> 16) & 0x3ff;
donatien 0:ae46a0638b2c 72 }
donatien 0:ae46a0638b2c 73
donatien 9:c9e9817c398c 74 void USBEndpoint::setDeviceAddress(uint8_t addr) {
donatien 0:ae46a0638b2c 75 hced->control &= ~(0x7f);
donatien 0:ae46a0638b2c 76 hced->control |= (addr & 0x7F);
donatien 0:ae46a0638b2c 77 }
donatien 0:ae46a0638b2c 78
donatien 9:c9e9817c398c 79 uint8_t USBEndpoint::getDeviceAddress() {
donatien 0:ae46a0638b2c 80 return hced->control & 0x7f;
donatien 0:ae46a0638b2c 81 }
donatien 0:ae46a0638b2c 82
donatien 9:c9e9817c398c 83 void USBEndpoint::setSpeed(uint8_t speed) {
donatien 0:ae46a0638b2c 84 if(speed) {
donatien 0:ae46a0638b2c 85 DBG("SET LOW SPEED");
donatien 0:ae46a0638b2c 86 }
donatien 0:ae46a0638b2c 87 hced->control &= ~(1 << 13);
donatien 0:ae46a0638b2c 88 hced->control |= (speed << 13);
donatien 0:ae46a0638b2c 89 }
donatien 0:ae46a0638b2c 90
donatien 0:ae46a0638b2c 91
donatien 9:c9e9817c398c 92 void USBEndpoint::setNextToken(uint32_t token) { //Only for control Eps
donatien 0:ae46a0638b2c 93 switch (token) {
donatien 0:ae46a0638b2c 94 case TD_SETUP:
donatien 0:ae46a0638b2c 95 dir = OUT;
donatien 0:ae46a0638b2c 96 setup = true;
donatien 0:ae46a0638b2c 97 break;
donatien 0:ae46a0638b2c 98 case TD_IN:
donatien 0:ae46a0638b2c 99 dir = IN;
donatien 0:ae46a0638b2c 100 setup = false;
donatien 0:ae46a0638b2c 101 break;
donatien 0:ae46a0638b2c 102 case TD_OUT:
donatien 0:ae46a0638b2c 103 dir = OUT;
donatien 0:ae46a0638b2c 104 setup = false;
donatien 0:ae46a0638b2c 105 break;
donatien 0:ae46a0638b2c 106 }
donatien 0:ae46a0638b2c 107 }
donatien 0:ae46a0638b2c 108
donatien 9:c9e9817c398c 109 volatile HCTD* USBEndpoint::getNextTD()
donatien 0:ae46a0638b2c 110 {
donatien 0:ae46a0638b2c 111 return td_current/*(HCTD*) hced->tailTD*/; //It's the tailing one
donatien 0:ae46a0638b2c 112 }
donatien 0:ae46a0638b2c 113
donatien 9:c9e9817c398c 114 void USBEndpoint::queueTransfer() {
donatien 0:ae46a0638b2c 115 //Try with OHCI impl
donatien 0:ae46a0638b2c 116 //Caller of getNextTD() has now populated the td
donatien 0:ae46a0638b2c 117 //So insert it into queue
donatien 0:ae46a0638b2c 118
donatien 0:ae46a0638b2c 119 //Find an OTHER free td
donatien 0:ae46a0638b2c 120 //TODO: if we had more than 2 tds, this would have to be changed
donatien 0:ae46a0638b2c 121 /*HCTD* toSendTD = (HCTD*) hced->tailTD;*/
donatien 0:ae46a0638b2c 122 //HCTD* freeTD;
donatien 0:ae46a0638b2c 123 /*
donatien 0:ae46a0638b2c 124 if( hced->tailTD == td_list[0] )
donatien 0:ae46a0638b2c 125 {
donatien 0:ae46a0638b2c 126 freeTD = td_list[1];
donatien 0:ae46a0638b2c 127 }
donatien 0:ae46a0638b2c 128 else *//*if( hced->tailTD == (uint32_t) td_list[1] )*/
donatien 0:ae46a0638b2c 129 /*{
donatien 0:ae46a0638b2c 130 freeTD = td_list[0];
donatien 0:ae46a0638b2c 131 }
donatien 0:ae46a0638b2c 132 */
donatien 0:ae46a0638b2c 133
donatien 0:ae46a0638b2c 134 /*
donatien 0:ae46a0638b2c 135 freeTD->control = 0;
donatien 0:ae46a0638b2c 136 freeTD->currBufPtr = 0;
donatien 0:ae46a0638b2c 137 freeTD->bufEnd = 0;
donatien 0:ae46a0638b2c 138 freeTD->nextTD = 0;
donatien 0:ae46a0638b2c 139
donatien 0:ae46a0638b2c 140 td_current = toSendTD;
donatien 0:ae46a0638b2c 141 */
donatien 0:ae46a0638b2c 142 transfer_len = td_current->bufEnd - td_current->currBufPtr + 1;
donatien 0:ae46a0638b2c 143 transferred = transfer_len;
donatien 0:ae46a0638b2c 144 buf_start = td_current->currBufPtr;
donatien 0:ae46a0638b2c 145
donatien 0:ae46a0638b2c 146 //No add this free TD at this end of the queue
donatien 0:ae46a0638b2c 147 state = USB_TYPE_PROCESSING;
donatien 0:ae46a0638b2c 148 td_current->nextTD = (volatile uint32_t)td_next;
donatien 0:ae46a0638b2c 149 hced->tailTD = (volatile uint32_t)td_next;
donatien 0:ae46a0638b2c 150
donatien 0:ae46a0638b2c 151 #if 0
donatien 0:ae46a0638b2c 152 // if TD list empty -> we put the head of the list
donatien 0:ae46a0638b2c 153 if (!hced->headTD) {
donatien 0:ae46a0638b2c 154 state = USB_TYPE_IDLE;
donatien 0:ae46a0638b2c 155 hced->headTD = (uint32_t)(td);
donatien 0:ae46a0638b2c 156 hced->tailTD = (uint32_t)(td);
donatien 0:ae46a0638b2c 157 tailTD = (HCTD *) (hced->headTD);
donatien 0:ae46a0638b2c 158 //DBG("queue null transfer: endpoint: %p, %08X\r\n", this, (uint32_t)(td));
donatien 0:ae46a0638b2c 159 } else {
donatien 0:ae46a0638b2c 160 state = USB_TYPE_PROCESSING;
donatien 0:ae46a0638b2c 161 td->nextTD = (uint32_t)headTD & ~(0x0f);
donatien 0:ae46a0638b2c 162 hced->headTD = (uint32_t)(td) | ((carry) ? 0x2 : 0);
donatien 0:ae46a0638b2c 163 }
donatien 0:ae46a0638b2c 164 headTD = (HCTD *) ((hced->headTD) & ~(0x3));
donatien 0:ae46a0638b2c 165 transfer_len = td->bufEnd - td->currBufPtr + 1;
donatien 0:ae46a0638b2c 166 transferred = transfer_len;
donatien 0:ae46a0638b2c 167 buf_start = td->currBufPtr;
donatien 0:ae46a0638b2c 168 #endif
donatien 0:ae46a0638b2c 169 //printf("queue real transfer: endpoint: %p \t headTD: %p \t head: %08X \t tail: %08X \t td: %08X \t nexttd: %08X\r\n", this, hced->headTD, hced->headTD, ((HCTD *)((hced->headTD) & ~(0x0f)))->nextTD, toSendTD, toSendTD->nextTD);
donatien 0:ae46a0638b2c 170 }
donatien 0:ae46a0638b2c 171
donatien 9:c9e9817c398c 172 volatile HCTD * USBEndpoint::getProcessedTD()
donatien 0:ae46a0638b2c 173 {
donatien 0:ae46a0638b2c 174 return td_current;
donatien 0:ae46a0638b2c 175 }
donatien 0:ae46a0638b2c 176
donatien 9:c9e9817c398c 177 void USBEndpoint::setLengthTransferred(int len) {
donatien 0:ae46a0638b2c 178 transferred = len;
donatien 0:ae46a0638b2c 179 }
donatien 0:ae46a0638b2c 180
donatien 9:c9e9817c398c 181 uint32_t USBEndpoint::getBufStart() {
donatien 0:ae46a0638b2c 182 return buf_start;
donatien 0:ae46a0638b2c 183 }
donatien 0:ae46a0638b2c 184
donatien 9:c9e9817c398c 185 void USBEndpoint::unqueueTransfer(volatile HCTD * td) {
donatien 0:ae46a0638b2c 186 //printf("unqueue transfer: %p on endpoint: %p\r\n", (void *)td, this);
donatien 0:ae46a0638b2c 187 //headTD = tailTD; //FIXME FIXME
donatien 0:ae46a0638b2c 188 // hced->headTD = hced->headTD | (td-> & 0x02);
donatien 0:ae46a0638b2c 189 if(td != td_current)
donatien 0:ae46a0638b2c 190 {
donatien 0:ae46a0638b2c 191 ERR("MISMATCH");
donatien 0:ae46a0638b2c 192 ERR("this=%p, td_current = %p, td_next=%p, td=%p", this, td_current, td_next, td);
donatien 0:ae46a0638b2c 193 error("");
donatien 0:ae46a0638b2c 194 }
donatien 0:ae46a0638b2c 195 td->control=0;
donatien 0:ae46a0638b2c 196 td->currBufPtr=0;
donatien 0:ae46a0638b2c 197 td->bufEnd=0;
donatien 0:ae46a0638b2c 198 td->nextTD=0;
donatien 0:ae46a0638b2c 199 hced->headTD = hced->tailTD | (hced->headTD & 0x2); //Carry bit
donatien 0:ae46a0638b2c 200 td_current = td_next;
donatien 0:ae46a0638b2c 201 td_next = td;
donatien 0:ae46a0638b2c 202 DBG("current:%p, next:%p", td_current, td_next);
donatien 0:ae46a0638b2c 203 }
donatien 0:ae46a0638b2c 204
donatien 9:c9e9817c398c 205 ENDPOINT_TYPE USBEndpoint::getType() {
donatien 0:ae46a0638b2c 206 return type;
donatien 0:ae46a0638b2c 207 }
donatien 0:ae46a0638b2c 208
donatien 0:ae46a0638b2c 209
donatien 9:c9e9817c398c 210 USBEndpoint * USBEndpoint::nextEndpoint() {
donatien 9:c9e9817c398c 211 return (USBEndpoint*)nextEp;
donatien 0:ae46a0638b2c 212 }
donatien 0:ae46a0638b2c 213
donatien 0:ae46a0638b2c 214
donatien 9:c9e9817c398c 215 void USBEndpoint::queueEndpoint(USBEndpoint * ed) {
donatien 0:ae46a0638b2c 216 nextEp = ed;
donatien 0:ae46a0638b2c 217 hced->nextED = (ed == NULL) ? 0 : (uint32_t)ed->getHCED();
donatien 0:ae46a0638b2c 218 }
donatien 0:ae46a0638b2c 219
donatien 9:c9e9817c398c 220 volatile HCED * USBEndpoint::getHCED() {
donatien 0:ae46a0638b2c 221 return hced;
donatien 0:ae46a0638b2c 222 }
donatien 0:ae46a0638b2c 223
donatien 0:ae46a0638b2c 224
donatien 9:c9e9817c398c 225 volatile HCTD * USBEndpoint::getHeadTD() {
donatien 0:ae46a0638b2c 226 //return headTD;
donatien 0:ae46a0638b2c 227 return (volatile HCTD*) (hced->headTD & ~0xF);
donatien 0:ae46a0638b2c 228 }
donatien 7:c4483d48fe96 229
donatien 9:c9e9817c398c 230 volatile HCTD ** USBEndpoint::getTDList()
donatien 7:c4483d48fe96 231 {
donatien 7:c4483d48fe96 232 return td_list;
donatien 7:c4483d48fe96 233 }