Changes to support Vodafone K4606
Fork of USBHostWANDongle by
Embed:
(wiki syntax)
Show/hide line numbers
USBEndpoint.cpp
00001 /* Copyright (c) 2010-2012 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 00020 #define __DEBUG__ 0 //Maximum verbosity 00021 #ifndef __MODULE__ 00022 #define __MODULE__ "USBEndpoint.cpp" 00023 #endif 00024 00025 #include "core/dbg.h" 00026 #include <cstdint> 00027 00028 #include "USBEndpoint.h" 00029 00030 00031 void USBEndpoint::init(HCED * hced, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t ep_number, HCTD* td_list[2]) { 00032 this->hced = hced; 00033 this->type = type; 00034 this->dir = /*(type == CONTROL_ENDPOINT) ? OUT :*/ dir; 00035 setup = (type == CONTROL_ENDPOINT) ? true : false; 00036 00037 //TDs have been allocated by the host 00038 memcpy((HCTD**)this->td_list, td_list, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define 00039 memcpy(td_list[0], 0, sizeof(HCTD)); 00040 memcpy(td_list[1], 0, sizeof(HCTD)); 00041 00042 this->hced->control = 0; 00043 //Empty queue 00044 this->hced->tailTD = (uint32_t)td_list[0]; 00045 this->hced->headTD = (uint32_t)td_list[0]; 00046 this->hced->nextED = 0; 00047 00048 this->hced->control = ((ep_number & 0x7F) << 7) // Endpoint address 00049 | (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 ) // direction : Out = 1, 2 = In 00050 | ((size & 0x3ff) << 16); // MaxPkt Size 00051 00052 //carry = false; 00053 transfer_len = 0; 00054 transferred = 0; 00055 buf_start = 0; 00056 nextEp = NULL; 00057 00058 td_current = td_list[0]; 00059 td_next = td_list[1]; 00060 00061 state = USB_TYPE_IDLE; 00062 } 00063 00064 void USBEndpoint::setSize(uint32_t size) { 00065 hced->control &= ~(0x3ff << 16); 00066 hced->control |= (size << 16); 00067 } 00068 00069 00070 uint32_t USBEndpoint::getSize() { 00071 return (hced->control >> 16) & 0x3ff; 00072 } 00073 00074 void USBEndpoint::setDeviceAddress(uint8_t addr) { 00075 hced->control &= ~(0x7f); 00076 hced->control |= (addr & 0x7F); 00077 } 00078 00079 uint8_t USBEndpoint::getDeviceAddress() { 00080 return hced->control & 0x7f; 00081 } 00082 00083 void USBEndpoint::setSpeed(uint8_t speed) { 00084 if(speed) { 00085 DBG("SET LOW SPEED"); 00086 } 00087 hced->control &= ~(1 << 13); 00088 hced->control |= (speed << 13); 00089 } 00090 00091 00092 void USBEndpoint::setNextToken(uint32_t token) { //Only for control Eps 00093 switch (token) { 00094 case TD_SETUP: 00095 dir = OUT; 00096 setup = true; 00097 break; 00098 case TD_IN: 00099 dir = IN; 00100 setup = false; 00101 break; 00102 case TD_OUT: 00103 dir = OUT; 00104 setup = false; 00105 break; 00106 } 00107 } 00108 00109 volatile HCTD* USBEndpoint::getNextTD() 00110 { 00111 return td_current/*(HCTD*) hced->tailTD*/; //It's the tailing one 00112 } 00113 00114 void USBEndpoint::queueTransfer() { 00115 //Try with OHCI impl 00116 //Caller of getNextTD() has now populated the td 00117 //So insert it into queue 00118 00119 //Find an OTHER free td 00120 //TODO: if we had more than 2 tds, this would have to be changed 00121 /*HCTD* toSendTD = (HCTD*) hced->tailTD;*/ 00122 //HCTD* freeTD; 00123 /* 00124 if( hced->tailTD == td_list[0] ) 00125 { 00126 freeTD = td_list[1]; 00127 } 00128 else *//*if( hced->tailTD == (uint32_t) td_list[1] )*/ 00129 /*{ 00130 freeTD = td_list[0]; 00131 } 00132 */ 00133 00134 /* 00135 freeTD->control = 0; 00136 freeTD->currBufPtr = 0; 00137 freeTD->bufEnd = 0; 00138 freeTD->nextTD = 0; 00139 00140 td_current = toSendTD; 00141 */ 00142 transfer_len = td_current->bufEnd - td_current->currBufPtr + 1; 00143 transferred = transfer_len; 00144 buf_start = td_current->currBufPtr; 00145 00146 //No add this free TD at this end of the queue 00147 state = USB_TYPE_PROCESSING; 00148 td_current->nextTD = (volatile uint32_t)td_next; 00149 hced->tailTD = (volatile uint32_t)td_next; 00150 00151 #if 0 00152 // if TD list empty -> we put the head of the list 00153 if (!hced->headTD) { 00154 state = USB_TYPE_IDLE; 00155 hced->headTD = (uint32_t)(td); 00156 hced->tailTD = (uint32_t)(td); 00157 tailTD = (HCTD *) (hced->headTD); 00158 //DBG("queue null transfer: endpoint: %p, %08X\r\n", this, (uint32_t)(td)); 00159 } else { 00160 state = USB_TYPE_PROCESSING; 00161 td->nextTD = (uint32_t)headTD & ~(0x0f); 00162 hced->headTD = (uint32_t)(td) | ((carry) ? 0x2 : 0); 00163 } 00164 headTD = (HCTD *) ((hced->headTD) & ~(0x3)); 00165 transfer_len = td->bufEnd - td->currBufPtr + 1; 00166 transferred = transfer_len; 00167 buf_start = td->currBufPtr; 00168 #endif 00169 //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); 00170 } 00171 00172 volatile HCTD * USBEndpoint::getProcessedTD() 00173 { 00174 return td_current; 00175 } 00176 00177 void USBEndpoint::setLengthTransferred(int len) { 00178 transferred = len; 00179 } 00180 00181 uint32_t USBEndpoint::getBufStart() { 00182 return buf_start; 00183 } 00184 00185 void USBEndpoint::unqueueTransfer(volatile HCTD * td) { 00186 //printf("unqueue transfer: %p on endpoint: %p\r\n", (void *)td, this); 00187 //headTD = tailTD; //FIXME FIXME 00188 // hced->headTD = hced->headTD | (td-> & 0x02); 00189 if(td != td_current) 00190 { 00191 ERR("MISMATCH"); 00192 ERR("this=%p, td_current = %p, td_next=%p, td=%p", this, td_current, td_next, td); 00193 error(""); 00194 } 00195 td->control=0; 00196 td->currBufPtr=0; 00197 td->bufEnd=0; 00198 td->nextTD=0; 00199 hced->headTD = hced->tailTD | (hced->headTD & 0x2); //Carry bit 00200 td_current = td_next; 00201 td_next = td; 00202 DBG("current:%p, next:%p", td_current, td_next); 00203 } 00204 00205 ENDPOINT_TYPE USBEndpoint::getType() { 00206 return type; 00207 } 00208 00209 00210 USBEndpoint * USBEndpoint::nextEndpoint() { 00211 return (USBEndpoint*)nextEp; 00212 } 00213 00214 00215 void USBEndpoint::queueEndpoint(USBEndpoint * ed) { 00216 nextEp = ed; 00217 hced->nextED = (ed == NULL) ? 0 : (uint32_t)ed->getHCED(); 00218 } 00219 00220 volatile HCED * USBEndpoint::getHCED() { 00221 return hced; 00222 } 00223 00224 00225 volatile HCTD * USBEndpoint::getHeadTD() { 00226 //return headTD; 00227 return (volatile HCTD*) (hced->headTD & ~0xF); 00228 } 00229 00230 volatile HCTD ** USBEndpoint::getTDList() 00231 { 00232 return td_list; 00233 }
Generated on Thu Jul 14 2022 09:11:27 by 1.7.2