USB Host Library for Sprint Dongles

Fork of USBHostWANDongleSprint_bleedingedge by Donatien Garnier

Legacy Warning

This is an mbed 2 libary. To learn more about mbed OS 5, visit the docs.

Committer:
donatien
Date:
Mon Dec 10 18:18:35 2012 +0000
Revision:
9:2a7b7333245f
Parent:
0:bfed5767d0a5
Merge

Who changed what in which revision?

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