local fork (temporary)
Dependents: VodafoneUSBModem_bleedingedge2
Fork of USBHostWANDongle_bleedingedge by
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 #include "capi/error.h" 00028 00029 #include "USBEndpoint.h" 00030 00031 00032 void USBEndpoint::init(HCED * hced, ENDPOINT_TYPE type, ENDPOINT_DIRECTION dir, uint32_t size, uint8_t ep_number, HCTD* td_list[2]) { 00033 this->hced = hced; 00034 this->type = type; 00035 this->dir = /*(type == CONTROL_ENDPOINT) ? OUT :*/ dir; 00036 setup = (type == CONTROL_ENDPOINT) ? true : false; 00037 00038 //TDs have been allocated by the host 00039 memcpy((HCTD**)this->td_list, td_list, sizeof(HCTD*)*2); //TODO: Maybe should add a param for td_list size... at least a define 00040 memcpy(td_list[0], 0, sizeof(HCTD)); 00041 memcpy(td_list[1], 0, sizeof(HCTD)); 00042 00043 this->hced->control = 0; 00044 //Empty queue 00045 this->hced->tailTD = (uint32_t)td_list[0]; 00046 this->hced->headTD = (uint32_t)td_list[0]; 00047 this->hced->nextED = 0; 00048 00049 this->hced->control = ((ep_number & 0x7F) << 7) // Endpoint address 00050 | (type != CONTROL_ENDPOINT ? ( dir << 11) : 0 ) // direction : Out = 1, 2 = In 00051 | ((size & 0x3ff) << 16); // MaxPkt Size 00052 00053 //carry = false; 00054 transfer_len = 0; 00055 transferred = 0; 00056 buf_start = 0; 00057 nextEp = NULL; 00058 00059 td_current = td_list[0]; 00060 td_next = td_list[1]; 00061 00062 state = USB_TYPE_IDLE; 00063 } 00064 00065 void USBEndpoint::setSize(uint32_t size) { 00066 hced->control &= ~(0x3ff << 16); 00067 hced->control |= (size << 16); 00068 } 00069 00070 00071 uint32_t USBEndpoint::getSize() { 00072 return (hced->control >> 16) & 0x3ff; 00073 } 00074 00075 void USBEndpoint::setDeviceAddress(uint8_t addr) { 00076 hced->control &= ~(0x7f); 00077 hced->control |= (addr & 0x7F); 00078 } 00079 00080 uint8_t USBEndpoint::getDeviceAddress() { 00081 return hced->control & 0x7f; 00082 } 00083 00084 void USBEndpoint::setSpeed(uint8_t speed) { 00085 if(speed) { 00086 DBG("SET LOW SPEED"); 00087 } 00088 hced->control &= ~(1 << 13); 00089 hced->control |= (speed << 13); 00090 } 00091 00092 00093 void USBEndpoint::setNextToken(uint32_t token) { //Only for control Eps 00094 switch (token) { 00095 case TD_SETUP: 00096 dir = OUT; 00097 setup = true; 00098 break; 00099 case TD_IN: 00100 dir = IN; 00101 setup = false; 00102 break; 00103 case TD_OUT: 00104 dir = OUT; 00105 setup = false; 00106 break; 00107 } 00108 } 00109 00110 volatile HCTD* USBEndpoint::getNextTD() 00111 { 00112 return td_current/*(HCTD*) hced->tailTD*/; //It's the tailing one 00113 } 00114 00115 void USBEndpoint::queueTransfer() { 00116 //Try with OHCI impl 00117 //Caller of getNextTD() has now populated the td 00118 //So insert it into queue 00119 00120 //Find an OTHER free td 00121 //TODO: if we had more than 2 tds, this would have to be changed 00122 /*HCTD* toSendTD = (HCTD*) hced->tailTD;*/ 00123 //HCTD* freeTD; 00124 /* 00125 if( hced->tailTD == td_list[0] ) 00126 { 00127 freeTD = td_list[1]; 00128 } 00129 else *//*if( hced->tailTD == (uint32_t) td_list[1] )*/ 00130 /*{ 00131 freeTD = td_list[0]; 00132 } 00133 */ 00134 00135 /* 00136 freeTD->control = 0; 00137 freeTD->currBufPtr = 0; 00138 freeTD->bufEnd = 0; 00139 freeTD->nextTD = 0; 00140 00141 td_current = toSendTD; 00142 */ 00143 transfer_len = td_current->bufEnd - td_current->currBufPtr + 1; 00144 transferred = transfer_len; 00145 buf_start = td_current->currBufPtr; 00146 00147 //No add this free TD at this end of the queue 00148 state = USB_TYPE_PROCESSING; 00149 td_current->nextTD = (volatile uint32_t)td_next; 00150 hced->tailTD = (volatile uint32_t)td_next; 00151 00152 #if 0 00153 // if TD list empty -> we put the head of the list 00154 if (!hced->headTD) { 00155 state = USB_TYPE_IDLE; 00156 hced->headTD = (uint32_t)(td); 00157 hced->tailTD = (uint32_t)(td); 00158 tailTD = (HCTD *) (hced->headTD); 00159 //DBG("queue null transfer: endpoint: %p, %08X\r\n", this, (uint32_t)(td)); 00160 } else { 00161 state = USB_TYPE_PROCESSING; 00162 td->nextTD = (uint32_t)headTD & ~(0x0f); 00163 hced->headTD = (uint32_t)(td) | ((carry) ? 0x2 : 0); 00164 } 00165 headTD = (HCTD *) ((hced->headTD) & ~(0x3)); 00166 transfer_len = td->bufEnd - td->currBufPtr + 1; 00167 transferred = transfer_len; 00168 buf_start = td->currBufPtr; 00169 #endif 00170 //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); 00171 } 00172 00173 volatile HCTD * USBEndpoint::getProcessedTD() 00174 { 00175 return td_current; 00176 } 00177 00178 void USBEndpoint::setLengthTransferred(int len) { 00179 transferred = len; 00180 } 00181 00182 uint32_t USBEndpoint::getBufStart() { 00183 return buf_start; 00184 } 00185 00186 void USBEndpoint::unqueueTransfer(volatile HCTD * td) { 00187 //printf("unqueue transfer: %p on endpoint: %p\r\n", (void *)td, this); 00188 //headTD = tailTD; //FIXME FIXME 00189 // hced->headTD = hced->headTD | (td-> & 0x02); 00190 if(td != td_current) 00191 { 00192 ERR("MISMATCH"); 00193 ERR("this=%p, td_current = %p, td_next=%p, td=%p", this, td_current, td_next, td); 00194 error(""); 00195 } 00196 td->control=0; 00197 td->currBufPtr=0; 00198 td->bufEnd=0; 00199 td->nextTD=0; 00200 hced->headTD = hced->tailTD | (hced->headTD & 0x2); //Carry bit 00201 td_current = td_next; 00202 td_next = td; 00203 DBG("current:%p, next:%p", td_current, td_next); 00204 } 00205 00206 ENDPOINT_TYPE USBEndpoint::getType() { 00207 return type; 00208 } 00209 00210 00211 USBEndpoint * USBEndpoint::nextEndpoint() { 00212 return (USBEndpoint*)nextEp; 00213 } 00214 00215 00216 void USBEndpoint::queueEndpoint(USBEndpoint * ed) { 00217 nextEp = ed; 00218 hced->nextED = (ed == NULL) ? 0 : (uint32_t)ed->getHCED(); 00219 } 00220 00221 volatile HCED * USBEndpoint::getHCED() { 00222 return hced; 00223 } 00224 00225 00226 volatile HCTD * USBEndpoint::getHeadTD() { 00227 //return headTD; 00228 return (volatile HCTD*) (hced->headTD & ~0xF); 00229 } 00230 00231 volatile HCTD ** USBEndpoint::getTDList() 00232 { 00233 return td_list; 00234 }
Generated on Sun Jul 17 2022 23:31:27 by 1.7.2