BLE demo for mbed Ported RunningElectronics's SBDBT firmware for BLE. It can communicate with iOS
Dependencies: FatFileSystem mbed
Fork of BTstack by
UsbEndpoint.cpp
00001 00002 /* 00003 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com) 00004 00005 Permission is hereby granted, free of charge, to any person obtaining a copy 00006 of this software and associated documentation files (the "Software"), to deal 00007 in the Software without restriction, including without limitation the rights 00008 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00009 copies of the Software, and to permit persons to whom the Software is 00010 furnished to do so, subject to the following conditions: 00011 00012 The above copyright notice and this permission notice shall be included in 00013 all copies or substantial portions of the Software. 00014 00015 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00016 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00017 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00018 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00019 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00020 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00021 THE SOFTWARE. 00022 */ 00023 00024 #include "UsbEndpoint.h" 00025 #include "UsbDevice.h" 00026 #include "usb_mem.h" 00027 #include "Usb_td.h" 00028 #include "netCfg.h" 00029 #if NET_USB 00030 00031 //#define __DEBUG 00032 //#define __DEBUG3 00033 //#include "dbg/dbg.h" 00034 #include "mydbg.h" 00035 00036 UsbEndpoint::UsbEndpoint( UsbDevice* pDevice, uint8_t ep, bool dir, UsbEndpointType type, uint16_t size, int addr /*= -1*/ ) 00037 : m_pDevice(pDevice), m_result(true), m_status((int)USBERR_OK), m_len(0), m_pBufStartPtr(NULL), 00038 m_pCbItem(NULL), m_pCbMeth(NULL) 00039 { 00040 if (type == USB_ISO) { 00041 UsbEndpoint_iso(pDevice, ep, dir, type, size, addr); 00042 return; 00043 } 00044 00045 m_pEd = (volatile HCED*)usb_get_ed(); 00046 DBG_ASSERT(m_pEd); 00047 memset((void*)m_pEd, 0, sizeof(HCED)); 00048 00049 m_pTdHead = (volatile HCTD*)usb_get_td((uint32_t)this); 00050 DBG_ASSERT(m_pTdHead); 00051 m_pTdTail = (volatile HCTD*)usb_get_td((uint32_t)this); 00052 DBG_ASSERT(m_pTdTail); 00053 DBG("m_pEd =%p\n", m_pEd); 00054 DBG("m_pTdHead=%p\n", m_pTdHead); 00055 DBG("m_pTdTail=%p\n", m_pTdTail); 00056 00057 if(addr == -1) 00058 addr = pDevice->m_addr; 00059 00060 //Setup Ed 00061 //printf("\r\n--Ep Setup--\r\n"); 00062 m_pEd->Control = addr | /* USB address */ 00063 ((ep & 0x7F) << 7) | /* Endpoint address */ 00064 (type!=USB_CONTROL?((dir?2:1) << 11):0) | /* direction : Out = 1, 2 = In */ 00065 (size << 16); /* MaxPkt Size */ 00066 DBG3("m_pEd->Control=%08X\n", m_pEd->Control); 00067 m_dir = dir; 00068 m_setup = false; 00069 m_type = type; 00070 00071 m_pEd->TailTd = m_pEd->HeadTd = (uint32_t) m_pTdTail; //Empty TD list 00072 00073 DBG("Before link\n"); 00074 00075 //printf("\r\n--Ep Reg--\r\n"); 00076 //Append Ed to Ed list 00077 HCCA* hcca; 00078 //volatile HCED* nextEd; 00079 DBG("m_type=%d\n", m_type); 00080 switch( m_type ) 00081 { 00082 case USB_CONTROL: 00083 m_pEd->Next = LPC_USB->HcControlHeadED; 00084 LPC_USB->HcControlHeadED = (uint32_t)m_pEd; 00085 return; 00086 00087 case USB_BULK: 00088 m_pEd->Next = LPC_USB->HcBulkHeadED; 00089 LPC_USB->HcBulkHeadED = (uint32_t)m_pEd; 00090 return; 00091 00092 case USB_INT: 00093 hcca = (HCCA*)usb_get_hcca(); 00094 m_pEd->Next = hcca->IntTable[0]; 00095 hcca->IntTable[0] = (uint32_t)m_pEd; 00096 return; 00097 00098 default: 00099 DBG_ASSERT(0); 00100 } 00101 } 00102 00103 00104 UsbEndpoint::~UsbEndpoint() 00105 { 00106 DBG_ASSERT(0); 00107 00108 m_pEd->Control |= ED_SKIP; //Skip this Ep in queue 00109 00110 //Remove from queue 00111 volatile HCED* prevEd; 00112 HCCA* hcca; 00113 switch( m_type ) 00114 { 00115 case USB_CONTROL: 00116 prevEd = (volatile HCED*) LPC_USB->HcControlHeadED; 00117 break; 00118 case USB_BULK: 00119 prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED; 00120 break; 00121 case USB_INT: 00122 hcca = (HCCA*)usb_get_hcca(); 00123 prevEd = (volatile HCED*)hcca->IntTable[0]; 00124 break; 00125 default: 00126 DBG_ASSERT(0); 00127 } 00128 if( m_pEd == prevEd ) 00129 { 00130 switch( m_type ) 00131 { 00132 case USB_CONTROL: 00133 LPC_USB->HcControlHeadED = m_pEd->Next; 00134 break; 00135 case USB_BULK: 00136 LPC_USB->HcBulkHeadED = m_pEd->Next; 00137 break; 00138 case USB_INT: 00139 hcca = (HCCA*)usb_get_hcca(); 00140 hcca->IntTable[0] = m_pEd->Next; 00141 break; 00142 default: 00143 DBG_ASSERT(0); 00144 } 00145 LPC_USB->HcBulkHeadED = m_pEd->Next; 00146 } 00147 else 00148 { 00149 while( prevEd->Next != (uint32_t) m_pEd ) 00150 { 00151 prevEd = (volatile HCED*) prevEd->Next; 00152 } 00153 prevEd->Next = m_pEd->Next; 00154 } 00155 00156 // 00157 usb_free_ed((volatile byte*)m_pEd); 00158 00159 usb_free_td((volatile byte*)m_pTdHead); 00160 usb_free_td((volatile byte*)m_pTdTail); 00161 } 00162 00163 void UsbEndpoint::setNextToken(uint32_t token) //Only for control Eps 00164 { 00165 switch(token) 00166 { 00167 case TD_SETUP: 00168 m_dir = false; 00169 m_setup = true; 00170 break; 00171 case TD_IN: 00172 m_dir = true; 00173 m_setup = false; 00174 break; 00175 case TD_OUT: 00176 m_dir = false; 00177 m_setup = false; 00178 break; 00179 } 00180 } 00181 00182 UsbErr UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len) 00183 { 00184 DBG("buf=%p\n", buf); 00185 if(!m_result) 00186 return USBERR_BUSY; //The previous trasnfer is not completed 00187 //FIXME: We should be able to queue the next transfer, still needs to be implemented 00188 00189 if( !m_pDevice->connected() ) 00190 return USBERR_DISCONNECTED; 00191 00192 m_result = false; 00193 00194 volatile uint32_t token = (m_setup?TD_SETUP:(m_dir?TD_IN:TD_OUT)); 00195 00196 volatile uint32_t td_toggle; 00197 if (m_type == USB_CONTROL) 00198 { 00199 if (m_setup) 00200 { 00201 td_toggle = TD_TOGGLE_0; 00202 } 00203 else 00204 { 00205 td_toggle = TD_TOGGLE_1; 00206 } 00207 } 00208 else 00209 { 00210 td_toggle = 0; 00211 } 00212 00213 //Swap Tds 00214 volatile HCTD* pTdSwap; 00215 pTdSwap = m_pTdTail; 00216 m_pTdTail = m_pTdHead; 00217 m_pTdHead = pTdSwap; 00218 00219 m_pTdHead->Control = (TD_ROUNDING | 00220 token | 00221 TD_DELAY_INT(0) |//7 00222 td_toggle | 00223 TD_CC); 00224 00225 m_pTdTail->Control = 0; 00226 m_pTdHead->CurrBufPtr = (uint32_t) buf; 00227 m_pBufStartPtr = buf; 00228 m_pTdTail->CurrBufPtr = 0; 00229 m_pTdHead->Next = (uint32_t) m_pTdTail; 00230 m_pTdTail->Next = 0; 00231 m_pTdHead->BufEnd = (uint32_t)(buf + (len - 1)); 00232 m_pTdTail->BufEnd = 0; 00233 00234 m_pEd->HeadTd = (uint32_t)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit 00235 m_pEd->TailTd = (uint32_t)m_pTdTail; 00236 00237 //DBG("m_pEd->HeadTd = %08x\n", m_pEd->HeadTd); 00238 00239 if(m_type == USB_CONTROL) { 00240 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF; 00241 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE; //Enable control list 00242 } else if (m_type == USB_BULK) { //USB_BULK 00243 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF; 00244 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; //Enable bulk list 00245 } else if (m_type == USB_INT) { // USB_INT 00246 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_PLE; //Enable Periodic 00247 } else { // USB_ISO 00248 DBG_ASSERT(0); 00249 } 00250 00251 //m_done = false; 00252 m_len = len; 00253 00254 return USBERR_PROCESSING; 00255 00256 } 00257 00258 int UsbEndpoint::status() 00259 { 00260 if( !m_pDevice->connected() ) 00261 { 00262 if(!m_result) 00263 onCompletion(); 00264 m_result = true; 00265 return (int)USBERR_DISCONNECTED; 00266 } 00267 else if( !m_result ) 00268 { 00269 return (int)USBERR_PROCESSING; 00270 } 00271 /*else if( m_done ) 00272 { 00273 return (int)USBERR_OK; 00274 }*/ 00275 else 00276 { 00277 return m_status; 00278 } 00279 } 00280 00281 void UsbEndpoint::updateAddr(int addr) 00282 { 00283 DBG("m_pEd->Control = %08x\n", m_pEd->Control); 00284 m_pEd->Control &= ~0x7F; 00285 m_pEd->Control |= addr; 00286 DBG("m_pEd->Control = %08x\n", m_pEd->Control); 00287 } 00288 00289 void UsbEndpoint::updateSize(uint16_t size) 00290 { 00291 DBG("m_pEd->Control = %08x\n", m_pEd->Control); 00292 m_pEd->Control &= ~0x3FF0000; 00293 m_pEd->Control |= (size << 16); 00294 DBG("m_pEd->Control = %08x\n", m_pEd->Control); 00295 } 00296 00297 #if 0 //For doc only 00298 template <class T> 00299 void UsbEndpoint::setOnCompletion( T* pCbItem, void (T::*pCbMeth)() ) 00300 { 00301 m_pCbItem = (CDummy*) pCbItem; 00302 m_pCbMeth = (void (CDummy::*)()) pCbMeth; 00303 } 00304 #endif 00305 00306 void UsbEndpoint::onCompletion() 00307 { 00308 DBG_ASSERT(m_type != USB_ISO); 00309 DBG_ASSERT(m_pTdHead); 00310 //DBG("Transfer completed\n"); 00311 if( m_pTdHead->Control >> 28 ) 00312 { 00313 DBG("TD Failed with condition code %01x\n", m_pTdHead->Control >> 28 ); 00314 m_status = (int)USBERR_TDFAIL; 00315 } 00316 else if( m_pEd->HeadTd & 0x1 ) 00317 { 00318 m_pEd->HeadTd = m_pEd->HeadTd & ~0x1; 00319 DBG("\r\nHALTED!!\r\n"); 00320 m_status = (int)USBERR_HALTED; 00321 } 00322 else if( (m_pEd->HeadTd & ~0xF) == (uint32_t) m_pTdTail ) 00323 { 00324 //Done 00325 int len; 00326 DBG("m_pEp=%p\n", m_pEd); 00327 DBG("m_pTdHead->CurrBufPtr=%08x\n", (uint32_t)m_pTdHead->CurrBufPtr); 00328 DBG("m_pBufStartPtr=%08x\n", (uint32_t) m_pBufStartPtr); 00329 if(m_pTdHead->CurrBufPtr) 00330 len = m_pTdHead->CurrBufPtr - (uint32_t) m_pBufStartPtr; 00331 else 00332 len = m_len; 00333 /*if(len == 0) //Packet transfered completely 00334 len = m_len;*/ 00335 //m_done = true; 00336 DBG("Transfered %d bytes\n", len); 00337 m_status = len; 00338 } 00339 else 00340 { 00341 DBG("Unknown error...\n"); 00342 m_status = (int)USBERR_ERROR; 00343 } 00344 m_result = true; 00345 if(m_pCbItem && m_pCbMeth) 00346 (m_pCbItem->*m_pCbMeth)(); 00347 } 00348 00349 00350 00351 void UsbEndpoint::sOnCompletion(uint32_t pTd) 00352 { 00353 HCTD* td = td_reverse((HCTD*)pTd); 00354 while(td) { 00355 HCTD* next = (HCTD*)td->Next; 00356 HCUTD* utd = (HCUTD*)td; 00357 UsbEndpoint* pEp = (UsbEndpoint*)utd->UsbEndpoint; 00358 DBG_ASSERT(pEp); 00359 if (usb_is_itd((byte*)td)) { 00360 HCITD* itd = (HCITD*)td; 00361 DBG_ASSERT(pEp->m_type == USB_ISO); 00362 pEp->queue_done_itd.push(itd); 00363 } else { 00364 DBG_ASSERT(pEp->m_pTdHead == td); 00365 if(pEp->m_pTdHead == td) { // found? 00366 pEp->onCompletion(); 00367 } 00368 } 00369 td = next; 00370 } 00371 } 00372 00373 #endif
Generated on Thu Jul 14 2022 15:03:49 by 1.7.2