Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of USBHostWANDongle 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 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
