35 #define __INCLUDE_FROM_USB_DRIVER
36 #include "../../../USBMode.h"
38 #if (defined(USB_CAN_BE_HOST) && defined(__LPC_OHCI__))
40 #define __LPC_OHCI_C__
41 #include "../../../../../../Common/Common.h"
42 #include "../../../USBTask.h"
104 OHCI_REG(HostID)->OTGClkCtrl = 0x00000019;
105 while ((
OHCI_REG(HostID)->OTGClkSt & 0x00000019) != 0x00000019) ;
106 #if defined(__LPC17XX__)
108 #elif defined(__LPC177X_8X__)
127 uint16_t MaxPacketSize,
130 uint8_t HSHubDevAddr,
131 uint8_t HSHubPortNum,
137 (void) Mult; (void) HSHubDevAddr; (void) HSHubPortNum;
145 #if !INTERRUPT_LIST_ENABLE
153 TransferDir, MaxPacketSize, Interval, 0) );
155 EndpointNumber &= 0xF;
156 MaxPacketSize &= 0x3FF;
158 switch (TransferType) {
181 HcdED(EdIdx)->ListIndex = ListIdx;
190 uint8_t HostID,
EdIdx;
194 HcdED(EdIdx)->hcED.Skip = 1;
208 HcdED(EdIdx)->hcED.HeadP.HeadTD = ((PHCD_GeneralTransferDescriptor) HeadTD)->hcGTD.NextTD;
209 FreeGtd((PHCD_GeneralTransferDescriptor) HeadTD);
213 HcdED(EdIdx)->hcED.HeadP.ToggleCarry = 0;
215 HcdED(EdIdx)->hcED.Skip = 0;
221 uint8_t HostID,
EdIdx;
227 HcdED(EdIdx)->hcED.Skip = 1;
237 uint8_t HostID,
EdIdx;
240 HcdED(EdIdx)->hcED.HeadP.Halted = 0;
241 HcdED(EdIdx)->hcED.HeadP.ToggleCarry = 0;
250 uint8_t *
const buffer)
252 uint8_t HostID,
EdIdx;
254 if ((pDeviceRequest ==
NULL) || (buffer ==
NULL)) {
268 if (pDeviceRequest->wLength) {
270 (pDeviceRequest->bmRequestType & 0x80) ? 2 : 1, 3, 0) );
295 (TDLen /
HcdED(EdIdx)->hcED.MaxPackageSize) + (TDLen %
HcdED(EdIdx)->hcED.MaxPackageSize ? 1 : 0) - 1;
296 pItd->BufferPage0 = Align4k( (
uint32_t) dataBuff);
297 pItd->BufferEnd = (
uint32_t) (dataBuff + TDLen - 1);
299 for (i = 0; TDLen > 0 && i < 8; i++) {
304 12) | (Align4k((
uint32_t) dataBuff) != Align4k(pItd->BufferPage0) ? _BIT(12) : 0) |
323 uint8_t MaxXactPerITD, FramePeriod;
324 if (
HcdED(EdIdx)->Interval < 4) {
325 MaxXactPerITD = 1 << ( 4 -
HcdED(EdIdx)->Interval );
330 FramePeriod = 1 << (
HcdED(EdIdx)->Interval - 4 );
333 #define MaxXactPerITD 8
334 #define FramePeriod 1
337 MaxDataSize = MaxXactPerITD *
HcdED(EdIdx)->hcED.MaxPackageSize;
340 while (xferLen > 0) {
343 MaxTDLen =
MIN(MaxDataSize, MaxTDLen);
345 TdLen =
MIN(xferLen, MaxTDLen);
351 FrameIdx = (FrameIdx + FramePeriod) % (1 << 16);
358 uint8_t *
const buffer,
360 uint16_t *
const pActualTransferred)
362 uint8_t HostID,
EdIdx;
365 if ((buffer ==
NULL) || (length == 0)) {
385 HcdED(EdIdx)->pActualTransferCount = pActualTransferred;
392 uint8_t HostID,
EdIdx;
396 return HcdED(EdIdx)->status;
399 static void OHciRhStatusChangeIsr(uint8_t HostID,
uint32_t deviceConnect)
409 static void ProcessDoneQueue(uint8_t HostID,
uint32_t donehead)
422 pCurTD->NextTD = (
uint32_t) pTDList;
427 while (pTDList !=
NULL) {
431 pTDList = (
PHC_GTD) pTDList->NextTD;
439 PHCD_GeneralTransferDescriptor pGtd = (PHCD_GeneralTransferDescriptor) pCurTD;
442 if (pGtd->hcGTD.CurrentBufferPointer) {
443 pGtd->TransferCount -=
444 ( Align4k( ((
uint32_t) pGtd->hcGTD.BufferEnd) ^
445 ((
uint32_t) pGtd->hcGTD.CurrentBufferPointer) ) ? 0x00001000 : 0 ) +
446 Offset4k((
uint32_t) pGtd->hcGTD.BufferEnd) - Offset4k(
447 (
uint32_t) pGtd->hcGTD.CurrentBufferPointer) + 1;
449 if (
HcdED(EdIdx)->pActualTransferCount) {
450 *(
HcdED(EdIdx)->pActualTransferCount) = pGtd->TransferCount;
456 HcdED(EdIdx)->status = pCurTD->ConditionCode;
459 if ( pCurTD->ConditionCode ) {
460 HcdED(EdIdx)->status =
462 HcdED(EdIdx)->hcED.HeadP.Halted = 0;
463 hcd_printf(
"Error on Endpoint 0x%X has HCD_STATUS code %d\r\n",
464 HcdED(EdIdx)->hcED.FunctionAddr | (
HcdED(EdIdx)->hcED.Direction == 2 ? 0x80 : 0x00),
465 pCurTD->ConditionCode);
473 FreeGtd( (PHCD_GeneralTransferDescriptor) pCurTD);
480 #if SCHEDULING_OVRERRUN_INTERRUPT
481 static void OHciSchedulingOverrunIsr(uint8_t HostID)
487 static void OHciStartofFrameIsr(uint8_t HostID)
492 #if RESUME_DETECT_INTERRUPT
493 static void OHciResumeDetectedIsr(uint8_t HostID)
498 #if UNRECOVERABLE_ERROR_INTERRUPT
499 static void OHciUnrecoverableErrorIsr(uint8_t HostID)
504 #if FRAMENUMBER_OVERFLOW_INTERRUPT
505 static void OHciFramenumberOverflowIsr(uint8_t HostID)
510 #if OWNERSHIP_CHANGE_INTERRUPT
511 static void OHciOwnershipChangeIsr(uint8_t HostID)
520 IntStatus =
OHCI_REG(HostID)->HcInterruptStatus &
OHCI_REG(HostID)->HcInterruptEnable;
522 if (IntStatus == 0) {
560 ProcessDoneQueue(HostID,
Align16(ohci_data[HostID].hcca.HccaDoneHead) );
563 #if SCHEDULING_OVRERRUN_INTERRUPT
565 OHciSchedulingOverrunIsr(HostID);
570 if (
OHCI_REG(HostID)->HcInterruptStatus & HC_INTERRUPT_StartofFrame) {
571 OHciStartofFrameIsr(HostID);
575 #if RESUME_DETECT_INTERRUPT
577 OHciResumeDetectedIsr(HostID);
581 #if UNRECOVERABLE_ERROR_INTERRUPT
583 OHciUnrecoverableErrorIsr(HostID);
587 #if FRAMENUMBER_OVERFLOW_INTERRUPT
589 OHciFramenumberOverflowIsr(HostID);
593 #if OWNERSHIP_CHANGE_INTERRUPT
595 OHciOwnershipChangeIsr(HostID);
610 PHCD_GeneralTransferDescriptor
TailP;
612 TailP = ( (PHCD_GeneralTransferDescriptor)
HcdED(EdIdx)->hcED.TailP );
616 TailP->hcGTD.BufferEnd = (xferLen) ? (CurrentBufferPointer + xferLen - 1) :
NULL;
617 TailP->TransferCount = xferLen;
630 while (xferLen > 0) {
634 TdLen =
MIN(xferLen, MaxTDLen);
658 HcdED(EdIdx)->hcED.NextED = list_head->NextED;
671 PHCD_EndpointDescriptor prevED;
673 prevED = (PHCD_EndpointDescriptor) & (ohci_data[HostID].staticEDs[
HcdED(EdIdx)->ListIndex]);
675 prevED = (PHCD_EndpointDescriptor) (prevED->hcED.NextED);
682 prevED->hcED.NextED =
HcdED(EdIdx)->hcED.NextED;
689 __INLINE uint8_t FindInterruptTransferListIndex(uint8_t HostID, uint8_t Interval)
691 uint8_t ListLeastBandwidth;
696 while ( (ListIdx >= Interval) && (ListIdx >>= 1) ) {}
697 ListEnd = ListIdx << 1;
701 for (ListLeastBandwidth = ListIdx; ListIdx <= ListEnd; ListIdx++ )
702 if ( ohci_data[HostID].staticEDs[ListIdx].TailP < ohci_data[HostID].staticEDs[ListLeastBandwidth].TailP ) {
703 ListLeastBandwidth = ListIdx;
705 return ListLeastBandwidth;
710 #if INTERRUPT_LIST_ENABLE
713 uint32_t Balance[16] = {0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF};
716 OHCI_HOST_DATA->staticEDs[0].NextED = 0;
718 OHCI_HOST_DATA->staticEDs[idx].NextED = (
uint32_t) &(OHCI_HOST_DATA->staticEDs[(idx - 1) / 2]);
720 for (count = 0, idx = INTERRUPT_32ms_LIST_HEAD; count < 32; count++, idx++)
721 OHCI_HOST_DATA->staticEDs[idx].NextED =
724 for (idx = 0; idx < 32; idx++)
727 #elif ISO_LIST_ENABLE
728 for (idx = 0; idx < 32; idx++)
740 for (idx = 0; idx < 32; idx++)
749 return Value & 0xFFFFFFF0UL;
752 static __INLINE PHCD_EndpointDescriptor
HcdED(uint8_t idx)
757 static __INLINE PHCD_GeneralTransferDescriptor
HcdGTD(uint8_t idx)
773 return HcdED(EdIdx)->hcED.Format;
783 *pPipeHandle = ((
uint32_t) (HostID << 8)) + EdIdx;
788 *HostID = Pipehandle >> 8;
789 *EdIdx = Pipehandle & 0xFF;
790 if ((*HostID >= MAX_USB_CORE) || (*EdIdx >=
MAX_ED) || (
HcdED(*EdIdx)->inUse == 0)) {
800 uint8_t EndpointNumber,
803 uint16_t MaxPacketSize,
808 for ((*pEdIdx) = 0; ((*pEdIdx) <
MAX_ED) &&
HcdED((*pEdIdx))->inUse; (*pEdIdx)++) {}
809 if ((*pEdIdx) >=
MAX_ED) {
816 HcdED((*pEdIdx))->inUse = 1;
818 HcdED((*pEdIdx))->hcED.FunctionAddr = DeviceAddr;
822 HcdED((*pEdIdx))->hcED.Skip = 0;
824 HcdED((*pEdIdx))->hcED.MaxPackageSize = MaxPacketSize;
843 for (GtdIdx = 0; (GtdIdx <
MAX_GTD) &&
HcdGTD(GtdIdx)->inUse; GtdIdx++) {}
856 HcdGTD(GtdIdx)->inUse = 1;
859 HcdGTD(GtdIdx)->hcGTD.BufferRounding = 1;
863 if (
HcdED(EdIdx)->hcED.TailP) {
864 ( (PHCD_GeneralTransferDescriptor)
HcdED(EdIdx)->hcED.TailP )->hcGTD.NextTD = (
uint32_t)
HcdGTD(GtdIdx);
883 for (ItdIdx = 0; (ItdIdx <
MAX_ITD) &&
HcdITD(ItdIdx)->inUse; ItdIdx++) {}
886 memset(
HcdITD(ItdIdx), 0,
sizeof(HCD_IsoTransferDescriptor) );
887 HcdITD(ItdIdx)->inUse = 1;
893 if (
HcdED(EdIdx)->hcED.TailP) {
915 FreeGtd( (PHCD_GeneralTransferDescriptor)
HcdED(EdIdx)->hcED.TailP);
919 HcdED(EdIdx)->inUse = 0;
949 ohci_data[HostID].staticEDs[idx].
Skip = 1;
983 HC_INTERRUPT_RootHubStatusChange |