Version of http://mbed.org/cookbook/NetServicesTribute with setting set the same for LPC2368

Dependents:   UDPSocketExample 24LCxx_I2CApp WeatherPlatform_pachube HvZServerLib ... more

Committer:
simon
Date:
Tue Nov 23 14:15:36 2010 +0000
Revision:
0:350011bf8be7
Experimental version for testing UDP

Who changed what in which revision?

UserRevisionLine numberNew contents of line
simon 0:350011bf8be7 1
simon 0:350011bf8be7 2 /*
simon 0:350011bf8be7 3 Copyright (c) 2010 Donatien Garnier (donatiengar [at] gmail [dot] com)
simon 0:350011bf8be7 4
simon 0:350011bf8be7 5 Permission is hereby granted, free of charge, to any person obtaining a copy
simon 0:350011bf8be7 6 of this software and associated documentation files (the "Software"), to deal
simon 0:350011bf8be7 7 in the Software without restriction, including without limitation the rights
simon 0:350011bf8be7 8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
simon 0:350011bf8be7 9 copies of the Software, and to permit persons to whom the Software is
simon 0:350011bf8be7 10 furnished to do so, subject to the following conditions:
simon 0:350011bf8be7 11
simon 0:350011bf8be7 12 The above copyright notice and this permission notice shall be included in
simon 0:350011bf8be7 13 all copies or substantial portions of the Software.
simon 0:350011bf8be7 14
simon 0:350011bf8be7 15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
simon 0:350011bf8be7 16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
simon 0:350011bf8be7 17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
simon 0:350011bf8be7 18 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
simon 0:350011bf8be7 19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
simon 0:350011bf8be7 20 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
simon 0:350011bf8be7 21 THE SOFTWARE.
simon 0:350011bf8be7 22 */
simon 0:350011bf8be7 23
simon 0:350011bf8be7 24 #include "UsbEndpoint.h"
simon 0:350011bf8be7 25
simon 0:350011bf8be7 26 #include "UsbDevice.h"
simon 0:350011bf8be7 27
simon 0:350011bf8be7 28 #include "usb_mem.h"
simon 0:350011bf8be7 29
simon 0:350011bf8be7 30 #include "netCfg.h"
simon 0:350011bf8be7 31 #if NET_USB
simon 0:350011bf8be7 32
simon 0:350011bf8be7 33 //#define __DEBUG
simon 0:350011bf8be7 34 #include "dbg/dbg.h"
simon 0:350011bf8be7 35
simon 0:350011bf8be7 36 UsbEndpoint::UsbEndpoint( UsbDevice* pDevice, uint8_t ep, bool dir, UsbEndpointType type, uint16_t size, int addr /*= -1*/ ) : m_pDevice(pDevice), m_result(true), m_status((int)USBERR_OK), m_len(0), m_pBufStartPtr(NULL),
simon 0:350011bf8be7 37 m_pCbItem(NULL), m_pCbMeth(NULL), m_pNextEp(NULL)
simon 0:350011bf8be7 38 {
simon 0:350011bf8be7 39 //Insert into Eps list
simon 0:350011bf8be7 40 //FIXME: Assert that no USB interrupt is triggered meanwhile
simon 0:350011bf8be7 41 if(m_pHeadEp)
simon 0:350011bf8be7 42 {
simon 0:350011bf8be7 43 m_pNextEp = m_pHeadEp;
simon 0:350011bf8be7 44 m_pHeadEp = this;
simon 0:350011bf8be7 45 }
simon 0:350011bf8be7 46 else
simon 0:350011bf8be7 47 {
simon 0:350011bf8be7 48 m_pNextEp = NULL;
simon 0:350011bf8be7 49 m_pHeadEp = this;
simon 0:350011bf8be7 50 }
simon 0:350011bf8be7 51
simon 0:350011bf8be7 52 m_pEd = (volatile HCED*)usb_get_ed();
simon 0:350011bf8be7 53
simon 0:350011bf8be7 54 m_pTdHead = (volatile HCTD*)usb_get_td();
simon 0:350011bf8be7 55 m_pTdTail = (volatile HCTD*)usb_get_td();
simon 0:350011bf8be7 56
simon 0:350011bf8be7 57 //printf("\r\n--m_pEd = %p--\r\n", m_pEd);
simon 0:350011bf8be7 58 DBG("m_pEd = %p\n", m_pEd);
simon 0:350011bf8be7 59 DBG("m_pTdHead = %p\n", m_pTdHead);
simon 0:350011bf8be7 60 DBG("m_pTdTail = %p\n", m_pTdTail);
simon 0:350011bf8be7 61
simon 0:350011bf8be7 62 //Init Ed & Td
simon 0:350011bf8be7 63 //printf("\r\n--Ep Init--\r\n");
simon 0:350011bf8be7 64 memset((void*)m_pEd, 0, sizeof(HCED));
simon 0:350011bf8be7 65 //printf("\r\n--Td Init--\r\n");
simon 0:350011bf8be7 66
simon 0:350011bf8be7 67 memset((void*)m_pTdHead, 0, sizeof(HCTD));
simon 0:350011bf8be7 68 memset((void*)m_pTdTail, 0, sizeof(HCTD));
simon 0:350011bf8be7 69
simon 0:350011bf8be7 70 if(addr == -1)
simon 0:350011bf8be7 71 addr = pDevice->m_addr;
simon 0:350011bf8be7 72
simon 0:350011bf8be7 73 //Setup Ed
simon 0:350011bf8be7 74 //printf("\r\n--Ep Setup--\r\n");
simon 0:350011bf8be7 75 m_pEd->Control = addr | /* USB address */
simon 0:350011bf8be7 76 ((ep & 0x7F) << 7) | /* Endpoint address */
simon 0:350011bf8be7 77 (type!=USB_CONTROL?((dir?2:1) << 11):0) | /* direction : Out = 1, 2 = In */
simon 0:350011bf8be7 78 (size << 16); /* MaxPkt Size */
simon 0:350011bf8be7 79
simon 0:350011bf8be7 80 m_dir = dir;
simon 0:350011bf8be7 81 m_setup = false;
simon 0:350011bf8be7 82 m_type = type;
simon 0:350011bf8be7 83
simon 0:350011bf8be7 84 m_pEd->TailTd = m_pEd->HeadTd = (uint32_t) m_pTdTail; //Empty TD list
simon 0:350011bf8be7 85
simon 0:350011bf8be7 86 DBG("Before link\n");
simon 0:350011bf8be7 87
simon 0:350011bf8be7 88 //printf("\r\n--Ep Reg--\r\n");
simon 0:350011bf8be7 89 //Append Ed to Ed list
simon 0:350011bf8be7 90 volatile HCED* prevEd;
simon 0:350011bf8be7 91 switch( m_type )
simon 0:350011bf8be7 92 {
simon 0:350011bf8be7 93 case USB_CONTROL:
simon 0:350011bf8be7 94 prevEd = (volatile HCED*) LPC_USB->HcControlHeadED;
simon 0:350011bf8be7 95 break;
simon 0:350011bf8be7 96 case USB_BULK:
simon 0:350011bf8be7 97 default:
simon 0:350011bf8be7 98 prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
simon 0:350011bf8be7 99 break;
simon 0:350011bf8be7 100 }
simon 0:350011bf8be7 101
simon 0:350011bf8be7 102 DBG("prevEd is %p\n", prevEd);
simon 0:350011bf8be7 103
simon 0:350011bf8be7 104 if(prevEd)
simon 0:350011bf8be7 105 {
simon 0:350011bf8be7 106 DBG("prevEd set\n")
simon 0:350011bf8be7 107
simon 0:350011bf8be7 108 while(prevEd->Next)
simon 0:350011bf8be7 109 {
simon 0:350011bf8be7 110 DBG("prevEd->Next = %08x\n", prevEd->Next);
simon 0:350011bf8be7 111 prevEd = (volatile HCED*) prevEd->Next;
simon 0:350011bf8be7 112 }
simon 0:350011bf8be7 113 prevEd->Next = (uint32_t) m_pEd;
simon 0:350011bf8be7 114
simon 0:350011bf8be7 115 }
simon 0:350011bf8be7 116 else
simon 0:350011bf8be7 117 {
simon 0:350011bf8be7 118 switch( m_type )
simon 0:350011bf8be7 119 {
simon 0:350011bf8be7 120 case USB_CONTROL:
simon 0:350011bf8be7 121 LPC_USB->HcControlHeadED = (uint32_t) m_pEd;
simon 0:350011bf8be7 122 break;
simon 0:350011bf8be7 123 case USB_BULK:
simon 0:350011bf8be7 124 default:
simon 0:350011bf8be7 125 LPC_USB->HcBulkHeadED = (uint32_t) m_pEd;
simon 0:350011bf8be7 126 break;
simon 0:350011bf8be7 127 }
simon 0:350011bf8be7 128 }
simon 0:350011bf8be7 129
simon 0:350011bf8be7 130 DBG("Ep init\n");
simon 0:350011bf8be7 131 }
simon 0:350011bf8be7 132
simon 0:350011bf8be7 133 UsbEndpoint::~UsbEndpoint()
simon 0:350011bf8be7 134 {
simon 0:350011bf8be7 135 //Remove from Eps list
simon 0:350011bf8be7 136 //FIXME: Assert that no USB interrupt is triggered meanwhile
simon 0:350011bf8be7 137 if(m_pHeadEp != this)
simon 0:350011bf8be7 138 {
simon 0:350011bf8be7 139 UsbEndpoint* prevEp = m_pHeadEp;
simon 0:350011bf8be7 140 while(prevEp->m_pNextEp != this)
simon 0:350011bf8be7 141 prevEp = prevEp->m_pNextEp;
simon 0:350011bf8be7 142 prevEp->m_pNextEp = m_pNextEp;
simon 0:350011bf8be7 143 }
simon 0:350011bf8be7 144 else
simon 0:350011bf8be7 145 {
simon 0:350011bf8be7 146 m_pHeadEp = m_pNextEp;
simon 0:350011bf8be7 147 }
simon 0:350011bf8be7 148
simon 0:350011bf8be7 149 m_pEd->Control |= ED_SKIP; //Skip this Ep in queue
simon 0:350011bf8be7 150
simon 0:350011bf8be7 151 //Remove from queue
simon 0:350011bf8be7 152 volatile HCED* prevEd;
simon 0:350011bf8be7 153 switch( m_type )
simon 0:350011bf8be7 154 {
simon 0:350011bf8be7 155 case USB_CONTROL:
simon 0:350011bf8be7 156 prevEd = (volatile HCED*) LPC_USB->HcControlHeadED;
simon 0:350011bf8be7 157 break;
simon 0:350011bf8be7 158 case USB_BULK:
simon 0:350011bf8be7 159 default:
simon 0:350011bf8be7 160 prevEd = (volatile HCED*) LPC_USB->HcBulkHeadED;
simon 0:350011bf8be7 161 break;
simon 0:350011bf8be7 162 }
simon 0:350011bf8be7 163 if( m_pEd == prevEd )
simon 0:350011bf8be7 164 {
simon 0:350011bf8be7 165 switch( m_type )
simon 0:350011bf8be7 166 {
simon 0:350011bf8be7 167 case USB_CONTROL:
simon 0:350011bf8be7 168 LPC_USB->HcControlHeadED = m_pEd->Next;
simon 0:350011bf8be7 169 break;
simon 0:350011bf8be7 170 case USB_BULK:
simon 0:350011bf8be7 171 default:
simon 0:350011bf8be7 172 LPC_USB->HcBulkHeadED = m_pEd->Next;
simon 0:350011bf8be7 173 break;
simon 0:350011bf8be7 174 }
simon 0:350011bf8be7 175 LPC_USB->HcBulkHeadED = m_pEd->Next;
simon 0:350011bf8be7 176 }
simon 0:350011bf8be7 177 else
simon 0:350011bf8be7 178 {
simon 0:350011bf8be7 179 while( prevEd->Next != (uint32_t) m_pEd )
simon 0:350011bf8be7 180 {
simon 0:350011bf8be7 181 prevEd = (volatile HCED*) prevEd->Next;
simon 0:350011bf8be7 182 }
simon 0:350011bf8be7 183 prevEd->Next = m_pEd->Next;
simon 0:350011bf8be7 184 }
simon 0:350011bf8be7 185
simon 0:350011bf8be7 186 //
simon 0:350011bf8be7 187 usb_free_ed((volatile byte*)m_pEd);
simon 0:350011bf8be7 188
simon 0:350011bf8be7 189 usb_free_td((volatile byte*)m_pTdHead);
simon 0:350011bf8be7 190 usb_free_td((volatile byte*)m_pTdTail);
simon 0:350011bf8be7 191 }
simon 0:350011bf8be7 192
simon 0:350011bf8be7 193 void UsbEndpoint::setNextToken(uint32_t token) //Only for control Eps
simon 0:350011bf8be7 194 {
simon 0:350011bf8be7 195 switch(token)
simon 0:350011bf8be7 196 {
simon 0:350011bf8be7 197 case TD_SETUP:
simon 0:350011bf8be7 198 m_dir = false;
simon 0:350011bf8be7 199 m_setup = true;
simon 0:350011bf8be7 200 break;
simon 0:350011bf8be7 201 case TD_IN:
simon 0:350011bf8be7 202 m_dir = true;
simon 0:350011bf8be7 203 m_setup = false;
simon 0:350011bf8be7 204 break;
simon 0:350011bf8be7 205 case TD_OUT:
simon 0:350011bf8be7 206 m_dir = false;
simon 0:350011bf8be7 207 m_setup = false;
simon 0:350011bf8be7 208 break;
simon 0:350011bf8be7 209 }
simon 0:350011bf8be7 210 }
simon 0:350011bf8be7 211
simon 0:350011bf8be7 212 UsbErr UsbEndpoint::transfer(volatile uint8_t* buf, uint32_t len)
simon 0:350011bf8be7 213 {
simon 0:350011bf8be7 214 if(!m_result)
simon 0:350011bf8be7 215 return USBERR_BUSY; //The previous trasnfer is not completed
simon 0:350011bf8be7 216 //FIXME: We should be able to queue the next transfer, still needs to be implemented
simon 0:350011bf8be7 217
simon 0:350011bf8be7 218 if( !m_pDevice->connected() )
simon 0:350011bf8be7 219 return USBERR_DISCONNECTED;
simon 0:350011bf8be7 220
simon 0:350011bf8be7 221 m_result = false;
simon 0:350011bf8be7 222
simon 0:350011bf8be7 223 volatile uint32_t token = (m_setup?TD_SETUP:(m_dir?TD_IN:TD_OUT));
simon 0:350011bf8be7 224
simon 0:350011bf8be7 225 volatile uint32_t td_toggle;
simon 0:350011bf8be7 226 if (m_type == USB_CONTROL)
simon 0:350011bf8be7 227 {
simon 0:350011bf8be7 228 if (m_setup)
simon 0:350011bf8be7 229 {
simon 0:350011bf8be7 230 td_toggle = TD_TOGGLE_0;
simon 0:350011bf8be7 231 }
simon 0:350011bf8be7 232 else
simon 0:350011bf8be7 233 {
simon 0:350011bf8be7 234 td_toggle = TD_TOGGLE_1;
simon 0:350011bf8be7 235 }
simon 0:350011bf8be7 236 }
simon 0:350011bf8be7 237 else
simon 0:350011bf8be7 238 {
simon 0:350011bf8be7 239 td_toggle = 0;
simon 0:350011bf8be7 240 }
simon 0:350011bf8be7 241
simon 0:350011bf8be7 242 //Swap Tds
simon 0:350011bf8be7 243 volatile HCTD* pTdSwap;
simon 0:350011bf8be7 244 pTdSwap = m_pTdTail;
simon 0:350011bf8be7 245 m_pTdTail = m_pTdHead;
simon 0:350011bf8be7 246 m_pTdHead = pTdSwap;
simon 0:350011bf8be7 247
simon 0:350011bf8be7 248 m_pTdHead->Control = (TD_ROUNDING |
simon 0:350011bf8be7 249 token |
simon 0:350011bf8be7 250 TD_DELAY_INT(0) |//7
simon 0:350011bf8be7 251 td_toggle |
simon 0:350011bf8be7 252 TD_CC);
simon 0:350011bf8be7 253
simon 0:350011bf8be7 254 m_pTdTail->Control = 0;
simon 0:350011bf8be7 255 m_pTdHead->CurrBufPtr = (uint32_t) buf;
simon 0:350011bf8be7 256 m_pBufStartPtr = buf;
simon 0:350011bf8be7 257 m_pTdTail->CurrBufPtr = 0;
simon 0:350011bf8be7 258 m_pTdHead->Next = (uint32_t) m_pTdTail;
simon 0:350011bf8be7 259 m_pTdTail->Next = 0;
simon 0:350011bf8be7 260 m_pTdHead->BufEnd = (uint32_t)(buf + (len - 1));
simon 0:350011bf8be7 261 m_pTdTail->BufEnd = 0;
simon 0:350011bf8be7 262
simon 0:350011bf8be7 263 m_pEd->HeadTd = (uint32_t)m_pTdHead | ((m_pEd->HeadTd) & 0x00000002); //Carry bit
simon 0:350011bf8be7 264 m_pEd->TailTd = (uint32_t)m_pTdTail;
simon 0:350011bf8be7 265
simon 0:350011bf8be7 266 //DBG("m_pEd->HeadTd = %08x\n", m_pEd->HeadTd);
simon 0:350011bf8be7 267
simon 0:350011bf8be7 268 if(m_type == USB_CONTROL)
simon 0:350011bf8be7 269 {
simon 0:350011bf8be7 270 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_CLF;
simon 0:350011bf8be7 271 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_CLE; //Enable control list
simon 0:350011bf8be7 272 }
simon 0:350011bf8be7 273 else //USB_BULK
simon 0:350011bf8be7 274 {
simon 0:350011bf8be7 275 LPC_USB->HcCommandStatus = LPC_USB->HcCommandStatus | OR_CMD_STATUS_BLF;
simon 0:350011bf8be7 276 LPC_USB->HcControl = LPC_USB->HcControl | OR_CONTROL_BLE; //Enable bulk list
simon 0:350011bf8be7 277 }
simon 0:350011bf8be7 278
simon 0:350011bf8be7 279 //m_done = false;
simon 0:350011bf8be7 280 m_len = len;
simon 0:350011bf8be7 281
simon 0:350011bf8be7 282 return USBERR_PROCESSING;
simon 0:350011bf8be7 283
simon 0:350011bf8be7 284 }
simon 0:350011bf8be7 285
simon 0:350011bf8be7 286 int UsbEndpoint::status()
simon 0:350011bf8be7 287 {
simon 0:350011bf8be7 288 if( !m_pDevice->connected() )
simon 0:350011bf8be7 289 {
simon 0:350011bf8be7 290 if(!m_result)
simon 0:350011bf8be7 291 onCompletion();
simon 0:350011bf8be7 292 m_result = true;
simon 0:350011bf8be7 293 return (int)USBERR_DISCONNECTED;
simon 0:350011bf8be7 294 }
simon 0:350011bf8be7 295 else if( !m_result )
simon 0:350011bf8be7 296 {
simon 0:350011bf8be7 297 return (int)USBERR_PROCESSING;
simon 0:350011bf8be7 298 }
simon 0:350011bf8be7 299 /*else if( m_done )
simon 0:350011bf8be7 300 {
simon 0:350011bf8be7 301 return (int)USBERR_OK;
simon 0:350011bf8be7 302 }*/
simon 0:350011bf8be7 303 else
simon 0:350011bf8be7 304 {
simon 0:350011bf8be7 305 return m_status;
simon 0:350011bf8be7 306 }
simon 0:350011bf8be7 307 }
simon 0:350011bf8be7 308
simon 0:350011bf8be7 309 void UsbEndpoint::updateAddr(int addr)
simon 0:350011bf8be7 310 {
simon 0:350011bf8be7 311 DBG("m_pEd->Control = %08x\n", m_pEd->Control);
simon 0:350011bf8be7 312 m_pEd->Control &= ~0x7F;
simon 0:350011bf8be7 313 m_pEd->Control |= addr;
simon 0:350011bf8be7 314 DBG("m_pEd->Control = %08x\n", m_pEd->Control);
simon 0:350011bf8be7 315 }
simon 0:350011bf8be7 316
simon 0:350011bf8be7 317 void UsbEndpoint::updateSize(uint16_t size)
simon 0:350011bf8be7 318 {
simon 0:350011bf8be7 319 DBG("m_pEd->Control = %08x\n", m_pEd->Control);
simon 0:350011bf8be7 320 m_pEd->Control &= ~0x3FF0000;
simon 0:350011bf8be7 321 m_pEd->Control |= (size << 16);
simon 0:350011bf8be7 322 DBG("m_pEd->Control = %08x\n", m_pEd->Control);
simon 0:350011bf8be7 323 }
simon 0:350011bf8be7 324
simon 0:350011bf8be7 325 #if 0 //For doc only
simon 0:350011bf8be7 326 template <class T>
simon 0:350011bf8be7 327 void UsbEndpoint::setOnCompletion( T* pCbItem, void (T::*pCbMeth)() )
simon 0:350011bf8be7 328 {
simon 0:350011bf8be7 329 m_pCbItem = (CDummy*) pCbItem;
simon 0:350011bf8be7 330 m_pCbMeth = (void (CDummy::*)()) pCbMeth;
simon 0:350011bf8be7 331 }
simon 0:350011bf8be7 332 #endif
simon 0:350011bf8be7 333
simon 0:350011bf8be7 334 void UsbEndpoint::onCompletion()
simon 0:350011bf8be7 335 {
simon 0:350011bf8be7 336 //DBG("Transfer completed\n");
simon 0:350011bf8be7 337 if( m_pTdHead->Control >> 28 )
simon 0:350011bf8be7 338 {
simon 0:350011bf8be7 339 DBG("TD Failed with condition code %01x\n", m_pTdHead->Control >> 28 );
simon 0:350011bf8be7 340 m_status = (int)USBERR_TDFAIL;
simon 0:350011bf8be7 341 }
simon 0:350011bf8be7 342 else if( m_pEd->HeadTd & 0x1 )
simon 0:350011bf8be7 343 {
simon 0:350011bf8be7 344 m_pEd->HeadTd = m_pEd->HeadTd & ~0x1;
simon 0:350011bf8be7 345 DBG("\r\nHALTED!!\r\n");
simon 0:350011bf8be7 346 m_status = (int)USBERR_HALTED;
simon 0:350011bf8be7 347 }
simon 0:350011bf8be7 348 else if( (m_pEd->HeadTd & ~0xF) == (uint32_t) m_pTdTail )
simon 0:350011bf8be7 349 {
simon 0:350011bf8be7 350 //Done
simon 0:350011bf8be7 351 int len;
simon 0:350011bf8be7 352 //DBG("m_pTdHead->CurrBufPtr = %08x, m_pBufStartPtr=%08x\n", m_pTdHead->CurrBufPtr, (uint32_t) m_pBufStartPtr);
simon 0:350011bf8be7 353 if(m_pTdHead->CurrBufPtr)
simon 0:350011bf8be7 354 len = m_pTdHead->CurrBufPtr - (uint32_t) m_pBufStartPtr;
simon 0:350011bf8be7 355 else
simon 0:350011bf8be7 356 len = m_len;
simon 0:350011bf8be7 357 /*if(len == 0) //Packet transfered completely
simon 0:350011bf8be7 358 len = m_len;*/
simon 0:350011bf8be7 359 //m_done = true;
simon 0:350011bf8be7 360 DBG("Transfered %d bytes\n", len);
simon 0:350011bf8be7 361 m_status = len;
simon 0:350011bf8be7 362 }
simon 0:350011bf8be7 363 else
simon 0:350011bf8be7 364 {
simon 0:350011bf8be7 365 DBG("Unknown error...\n");
simon 0:350011bf8be7 366 m_status = (int)USBERR_ERROR;
simon 0:350011bf8be7 367 }
simon 0:350011bf8be7 368 m_result = true;
simon 0:350011bf8be7 369 if(m_pCbItem && m_pCbMeth)
simon 0:350011bf8be7 370 (m_pCbItem->*m_pCbMeth)();
simon 0:350011bf8be7 371 }
simon 0:350011bf8be7 372
simon 0:350011bf8be7 373 void UsbEndpoint::sOnCompletion(uint32_t pTd)
simon 0:350011bf8be7 374 {
simon 0:350011bf8be7 375 if(!m_pHeadEp)
simon 0:350011bf8be7 376 return;
simon 0:350011bf8be7 377 do
simon 0:350011bf8be7 378 {
simon 0:350011bf8be7 379 //DBG("sOnCompletion (pTd = %08x)\n", pTd);
simon 0:350011bf8be7 380 UsbEndpoint* pEp = m_pHeadEp;
simon 0:350011bf8be7 381 do
simon 0:350011bf8be7 382 {
simon 0:350011bf8be7 383 if((uint32_t)pEp->m_pTdHead == pTd)
simon 0:350011bf8be7 384 {
simon 0:350011bf8be7 385 pEp->onCompletion();
simon 0:350011bf8be7 386 break;
simon 0:350011bf8be7 387 }
simon 0:350011bf8be7 388 } while(pEp = pEp->m_pNextEp);
simon 0:350011bf8be7 389 } while( pTd = (uint32_t)( ((HCTD*)pTd)->Next ) ); //Go around the Done queue
simon 0:350011bf8be7 390 }
simon 0:350011bf8be7 391
simon 0:350011bf8be7 392 UsbEndpoint* UsbEndpoint::m_pHeadEp = NULL;
simon 0:350011bf8be7 393
simon 0:350011bf8be7 394 #endif