📄 host_811.lst
字号:
237 {
238 if(uHub.bPortSpeed[usbaddr]) // If transfer of LS on Hub & previous is
239 cmd = psDATA0_RD; // SETUP & current is IN, no sync to sof,
240 }
241 }
242 //------------------------------------------------
243 // For OUT token
244 //------------------------------------------------
245 else if(pid==PID_OUT) // for OUT tokens
246 {
247 if(xferLen) // only when there are
248 SL811BufWrite(data0,buffer,xferLen); // data to transfer on USB
249
250 if(FULL_SPEED)
251 cmd = sDATA0_WR; // FS/FS on Hub, sync to sof
252 else // LS, no sync to sof for OUT
253 cmd = DATA0_WR;
254 //--------------------------------------------
255 // handling LS device on HUB
256 //--------------------------------------------
257 if(HUB_DEVICE && usbaddr!=HUB_ADDR) // Transfer on Hub, USB addr #0, #2..#5 only
258 {
259 if(uHub.bPortSpeed[usbaddr]) // If transfer of LS on Hub, previous
260 cmd = psDATA0_WR;
261 }
262 // implement data toggle
263 bData1 = uDev[usbaddr].bData1[endpoint];
264 uDev[usbaddr].bData1[endpoint] = (uDev[usbaddr].bData1[endpoint] ? 0 : 1); // DataToggle
265 if(bData1)
266 cmd |= 0x40; // Set Data1 bit in command
267 }
268 //------------------------------------------------
269 // For SETUP/OUT token
270 //------------------------------------------------
271 else // for current SETUP/OUT tokens
272 {
273 if(xferLen) // only when there are
274 SL811BufWrite(data0,buffer,xferLen); // data to transfer on USB
275
276 if(FULL_SPEED)
277 cmd = sDATA0_WR; // FS/FS on Hub, sync to sof
278 else // LS, no sync to sof for OUT
279 cmd = DATA0_WR;
280 //--------------------------------------------
281 // handling LS device on HUB
282 //--------------------------------------------
283 if(HUB_DEVICE && usbaddr!=HUB_ADDR) // Transfer on Hub, USB addr #0, #2..#5 only
284 {
285 if(uHub.bPortSpeed[usbaddr]) // If transfer of LS on Hub, previous
286 cmd = psDATA0_WR;
287 }
288 }
289
290 //------------------------------------------------
291 // Isochronous data transfer setting
292 //------------------------------------------------
293 if (iso)
294 cmd |= ISO_BIT; // if iso setup ISO mode
295
296 //------------------------------------------------
C51 COMPILER V6.10 HOST_811 09/04/2002 22:22:07 PAGE 6
297 // For EP0's IN/OUT token data, start with DATA1
298 // Control Endpoint0's status stage.
299 // For data endpoint, IN/OUT data, start ????
300 //------------------------------------------------
301 if (endpoint == 0 && pid != PID_SETUP) // for Ep0's IN/OUT token
302 cmd |= 0x40; // always set DATA1
303
304 //------------------------------------------------
305 // Arming of USB data transfer for the first pkt
306 //------------------------------------------------
307 SL811Write(EP0Status,((endpoint&0x0F)|pid)); // PID + EP address
308 SL811Write(EP0Counter,usbaddr); // USB address
309 SL811Write(EP0Address,data0); // buffer address, start with "data0"
310 SL811Write(EP0XferLen,xferLen); // data transfer length
311 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
312 SL811Write(EP0Control,cmd); // Enable ARM and USB transfer start here
313
314 //------------------------------------------------
315 // Main loop for completing a wLen data trasnfer
316 //------------------------------------------------
317 while(TRUE)
318 {
319 //---------------Wait for done interrupt------------------
320 while(TRUE) // always ensure requested device is
321 { // inserted at all time, then you will
322 intr = SL811Read(IntStatus); // wait for interrupt to be done, and
323 if((intr & USB_RESET) || (intr & INSERT_REMOVE)) // proceed to parse result from slave
324 { // device.
325 DATA_STOP = TRUE; // if device is removed, set DATA_STOP
326 return FALSE; // flag true, so that main loop will
327 } // know this condition and exit gracefully
328 if(intr & USB_A_DONE)
329 break; // interrupt done !!!
330 }
331
332 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status
333 result = SL811Read(EP0Status); // read EP0status register
334 remainder = SL811Read(EP0Counter); // remainder value in last pkt xfer
335
336 //-------------------------ACK----------------------------
337 if (result & EP0_ACK) // Transmission ACK
338 {
339
340 // SETUP TOKEN
341 if(pid == PID_SETUP) // do nothing for SETUP/OUT token
342 break; // exit while(1) immediately
343
344 // OUT TOKEN
345 else if(pid == PID_OUT)
346 break;
347
348 // IN TOKEN
349 else if(pid == PID_IN)
350 { // for IN token only
351 wLen -= (WORD)xferLen; // update remainding wLen value
352 cmd ^= 0x40; // toggle DATA0/DATA1
353 dataX++; // point to next dataX
354
355 //------------------------------------------------
356 // If host requested for more data than the slave
357 // have, and if the slave's data len is a multiple
358 // of its endpoint payload size/last xferLen. Do
C51 COMPILER V6.10 HOST_811 09/04/2002 22:22:07 PAGE 7
359 // not overwrite data in previous buffer.
360 //------------------------------------------------
361 if(remainder==xferLen) // empty data detected
362 bufLen = 0; // do not overwriten previous data
363 else // reset bufLen to zero
364 bufLen = xferLen; // update previous buffer length
365
366 //------------------------------------------------
367 // Arm for next data transfer when requested data
368 // length have not reach zero, i.e. wLen!=0, and
369 // last xferlen of data was completed, i.e.
370 // remainder is equal to zero, not a short pkt
371 //------------------------------------------------
372 if(!remainder && wLen) // remainder==0 when last xferLen
373 { // was all completed or wLen!=0
374 addr = (dataX & 1) ? data1:data0; // select next address for data
375 xferLen = (BYTE)(wLen>=wPayload) ? wPayload:wLen; // get data length required
376 if (FULL_SPEED) // sync with SOF transfer
377 cmd |= 0x20; // always sync SOF when FS, regardless
378 SL811Write(EP0XferLen, xferLen); // select next xfer length
379 SL811Write(EP0Address, addr); // data buffer addr
380 SL811Write(IntStatus,INT_CLEAR); // is a LS is on Hub.
381 SL811Write(EP0Control,cmd); // Enable USB transfer and re-arm
382 }
383
384 //------------------------------------------------
385 // Copy last IN token data pkt from prev transfer
386 // Check if there was data available during the
387 // last data transfer
388 //------------------------------------------------
389 if(bufLen)
390 {
391 SL811BufRead(((dataX&1)?data0:data1), buffer, bufLen);
392 buffer += bufLen;
393 }
394
395 //------------------------------------------------
396 // Terminate on short packets, i.e. remainder!=0
397 // a short packet or empty data packet OR when
398 // requested data len have completed, i.e.wLen=0
399 // For a LOWSPEED device, the 1st device descp,
400 // wPayload is default to 64-byte, LS device will
401 // only send back a max of 8-byte device descp,
402 // and host detect this as a short packet, and
403 // terminate with OUT status stage
404 //------------------------------------------------
405 if(remainder || !wLen)
406 break;
407 }
408 }
409
410 //-------------------------NAK----------------------------
411 if (result & EP0_NAK) // NAK Detected
412 {
413 if(endpoint==0) // on ep0 during enumeration of LS device
414 { // happen when slave is not fast enough,
415 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status, need to
416 SL811Write(EP0Control,cmd); // re-arm and request for last cmd, IN token
417 result = 0; // respond to NAK status only
418 }
419 else // normal data endpoint, exit now !!! , non-zero ep
420 break; // main loop control the interval polling
C51 COMPILER V6.10 HOST_811 09/04/2002 22:22:07 PAGE 8
421 }
422
423 //-----------------------TIMEOUT--------------------------
424 if (result & EP0_TIMEOUT) // TIMEOUT Detected
425 {
426 if(endpoint==0) // happens when hub enumeration
427 {
428 if(++timeout >= TIMEOUT_RETRY)
429 {
430 timeout--;
431 break; // exit on the timeout detected
432 }
433 SL811Write(IntStatus,INT_CLEAR); // clear interrupt status, need to
434 SL811Write(EP0Control,cmd); // re-arm and request for last cmd again
435 }
436 else
437 { // all other data endpoint, data transfer
438 TIMEOUT_ERR = TRUE; // failed, set flag to terminate transfer
439 break; // happens when data transfer on a device
440 } // through the hub
441 }
442
443 //-----------------------STALL----------------------------
444 if (result & EP0_STALL) // STALL detected
445 return TRUE; // for unsupported request.
446
447 //----------------------OVEFLOW---------------------------
448 if (result & EP0_OVERFLOW) // OVERFLOW detected
449 break;
450 //-----------------------ERROR----------------------------
451 if (result & EP0_ERROR) // ERROR detected
452 break;
453 } // end of While(1)
454
455 if (result & EP0_ACK) // on ACK transmission
456 return TRUE; // return OK
457
458 return FALSE; // fail transmission
459 }
460
461 //*****************************************************************************************
462 // Control Endpoint 0's USB Data Xfer
463 // ep0Xfer, endpoint 0 data transfer
464 //*****************************************************************************************
465 int ep0Xfer(BYTE usbaddr, WORD payload, pSetupPKG setup, BYTE *pData)
466 {
467 xdata BYTE pid = PID_IN;
468 xdata WORD wLen = WordSwap(setup->wLength); // swap back for correct length
469 xdata BYTE ep0 = 0; // always endpoint zero
470
471 //----------------------------------------------------
472 // SETUP token with 8-byte request on endpoint 0
473 //----------------------------------------------------
474 if (!usbXfer(usbaddr, ep0, PID_SETUP, 0, payload, 8, (BYTE*)setup))
475 return FALSE;
476
477 //----------------------------------------------------
478 // IN or OUT data stage on endpoint 0
479 //----------------------------------------------------
480 if (wLen) // if there are data for transfer
481 {
482 if (setup->bmRequest & 0x80) // host-to-device : IN token
C51 COMPILER V6.10 HOST_811 09/04/2002 22:22:07 PAGE 9
483 {
484 pid = PID_OUT;
485 if(!usbXfer(usbaddr, ep0, PID_IN, 0, payload, wLen, pData))
486 return FALSE;
487 payload = 0;
488 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -