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"
105 USB_REG(HostID)->OTGClkCtrl = 0x00000019;
106 while ((
USB_REG(HostID)->OTGClkSt & 0x00000019) != 0x00000019) ;
107 #if defined(__LPC175X_6X__)
109 #elif defined(__LPC177X_8X__) || defined(__LPC407X_8X__)
128 uint16_t MaxPacketSize,
131 uint8_t HSHubDevAddr,
132 uint8_t HSHubPortNum,
138 (void) Mult; (void) HSHubDevAddr; (void) HSHubPortNum;
146 #if !INTERRUPT_LIST_ENABLE
154 TransferDir, MaxPacketSize, Interval, 0) );
156 EndpointNumber &= 0xF;
157 MaxPacketSize &= 0x3FF;
159 switch (TransferType) {
187 HcdED(EdIdx)->ListIndex = ListIdx;
196 uint8_t HostID,
EdIdx;
200 HcdED(EdIdx)->hcED.Skip = 1;
214 HcdED(EdIdx)->hcED.HeadP.HeadTD = ((PHCD_GeneralTransferDescriptor) HeadTD)->hcGTD.NextTD;
215 FreeGtd((PHCD_GeneralTransferDescriptor) HeadTD);
219 HcdED(EdIdx)->hcED.HeadP.ToggleCarry = 0;
221 HcdED(EdIdx)->hcED.Skip = 0;
227 uint8_t HostID,
EdIdx;
233 HcdED(EdIdx)->hcED.Skip = 1;
243 uint8_t HostID,
EdIdx;
246 HcdED(EdIdx)->hcED.HeadP.Halted = 0;
247 HcdED(EdIdx)->hcED.HeadP.ToggleCarry = 0;
258 uint8_t HostID,
EdIdx;
260 if ((pDeviceRequest ==
NULL) || (buffer ==
NULL)) {
274 if (pDeviceRequest->wLength) {
276 (pDeviceRequest->bmRequestType & 0x80) ? 2 : 1, 3, 0) );
301 (TDLen /
HcdED(EdIdx)->hcED.MaxPackageSize) + (TDLen %
HcdED(EdIdx)->hcED.MaxPackageSize ? 1 : 0) - 1;
302 pItd->BufferPage0 = Align4k( (
uint32_t) dataBuff);
303 pItd->BufferEnd = (
uint32_t) (dataBuff + TDLen - 1);
305 for (i = 0; TDLen > 0 && i < 8; i++) {
310 12) | (Align4k((
uint32_t) dataBuff) != Align4k(pItd->BufferPage0) ? _BIT(12) : 0) |
329 uint8_t MaxXactPerITD, FramePeriod;
330 if (
HcdED(EdIdx)->Interval < 4) {
331 MaxXactPerITD = 1 << ( 4 -
HcdED(EdIdx)->Interval );
336 FramePeriod = 1 << (
HcdED(EdIdx)->Interval - 4 );
339 #define MaxXactPerITD 8
340 #define FramePeriod 1
343 MaxDataSize = MaxXactPerITD *
HcdED(EdIdx)->hcED.MaxPackageSize;
346 while (xferLen > 0) {
349 MaxTDLen =
MIN(MaxDataSize, MaxTDLen);
351 TdLen =
MIN(xferLen, MaxTDLen);
357 FrameIdx = (FrameIdx + FramePeriod) % (1 << 16);
364 uint8_t *
const buffer,
366 uint16_t *
const pActualTransferred)
368 uint8_t HostID,
EdIdx;
371 if ((buffer ==
NULL) || (length == 0)) {
391 HcdED(EdIdx)->pActualTransferCount = pActualTransferred;
398 uint8_t HostID,
EdIdx;
405 static void OHciRhStatusChangeIsr(uint8_t HostID,
uint32_t deviceConnect)
415 static void ProcessDoneQueue(uint8_t HostID,
uint32_t donehead)
428 pCurTD->NextTD = (
uint32_t) pTDList;
433 while (pTDList !=
NULL) {
437 pTDList = (
PHC_GTD) pTDList->NextTD;
445 PHCD_GeneralTransferDescriptor pGtd = (PHCD_GeneralTransferDescriptor) pCurTD;
448 if (pGtd->hcGTD.CurrentBufferPointer) {
449 pGtd->TransferCount -=
450 ( Align4k( ((
uint32_t) pGtd->hcGTD.BufferEnd) ^
451 ((
uint32_t) pGtd->hcGTD.CurrentBufferPointer) ) ? 0x00001000 : 0 ) +
452 Offset4k((
uint32_t) pGtd->hcGTD.BufferEnd) - Offset4k(
453 (
uint32_t) pGtd->hcGTD.CurrentBufferPointer) + 1;
455 if (
HcdED(EdIdx)->pActualTransferCount) {
456 *(
HcdED(EdIdx)->pActualTransferCount) = pGtd->TransferCount;
462 HcdED(EdIdx)->status = pCurTD->ConditionCode;
465 if ( pCurTD->ConditionCode ) {
466 HcdED(EdIdx)->status =
468 HcdED(EdIdx)->hcED.HeadP.Halted = 0;
469 hcd_printf(
"Error on Endpoint 0x%X has HCD_STATUS code %d\r\n",
470 HcdED(EdIdx)->hcED.FunctionAddr | (
HcdED(EdIdx)->hcED.Direction == 2 ? 0x80 : 0x00),
471 pCurTD->ConditionCode);
479 FreeGtd( (PHCD_GeneralTransferDescriptor) pCurTD);
486 #if SCHEDULING_OVRERRUN_INTERRUPT
487 static void OHciSchedulingOverrunIsr(uint8_t HostID)
493 static void OHciStartofFrameIsr(uint8_t HostID)
498 #if RESUME_DETECT_INTERRUPT
499 static void OHciResumeDetectedIsr(uint8_t HostID)
504 #if UNRECOVERABLE_ERROR_INTERRUPT
505 static void OHciUnrecoverableErrorIsr(uint8_t HostID)
510 #if FRAMENUMBER_OVERFLOW_INTERRUPT
511 static void OHciFramenumberOverflowIsr(uint8_t HostID)
516 #if OWNERSHIP_CHANGE_INTERRUPT
517 static void OHciOwnershipChangeIsr(uint8_t HostID)
526 IntStatus =
USB_REG(HostID)->InterruptStatus;
530 IntStatus &=
USB_REG(HostID)->InterruptEnable;
531 if (IntStatus == 0) {
574 #if SCHEDULING_OVRERRUN_INTERRUPT
576 OHciSchedulingOverrunIsr(HostID);
581 if (
USB_REG(HostID)->HcInterruptStatus & HC_INTERRUPT_StartofFrame) {
582 OHciStartofFrameIsr(HostID);
586 #if RESUME_DETECT_INTERRUPT
588 OHciResumeDetectedIsr(HostID);
592 #if UNRECOVERABLE_ERROR_INTERRUPT
594 OHciUnrecoverableErrorIsr(HostID);
598 #if FRAMENUMBER_OVERFLOW_INTERRUPT
600 OHciFramenumberOverflowIsr(HostID);
604 #if OWNERSHIP_CHANGE_INTERRUPT
606 OHciOwnershipChangeIsr(HostID);
620 PHCD_GeneralTransferDescriptor
TailP;
622 TailP = ( (PHCD_GeneralTransferDescriptor)
HcdED(EdIdx)->hcED.TailP );
626 TailP->hcGTD.BufferEnd = (xferLen) ? (CurrentBufferPointer + xferLen - 1) :
NULL;
627 TailP->TransferCount = xferLen;
640 while (xferLen > 0) {
644 TdLen =
MIN(xferLen, MaxTDLen);
668 HcdED(EdIdx)->hcED.NextED = list_head->NextED;
681 PHCD_EndpointDescriptor prevED;
683 prevED = (PHCD_EndpointDescriptor) & (
ohci_data[HostID].staticEDs[
HcdED(EdIdx)->ListIndex]);
685 prevED = (PHCD_EndpointDescriptor) (prevED->hcED.NextED);
692 prevED->hcED.NextED =
HcdED(EdIdx)->hcED.NextED;
699 __INLINE uint8_t FindInterruptTransferListIndex(uint8_t HostID, uint8_t Interval)
701 uint8_t ListLeastBandwidth;
706 while ( (ListIdx >= Interval) && (ListIdx >>= 1) ) {}
707 ListEnd = ListIdx << 1;
711 for (ListLeastBandwidth = ListIdx; ListIdx <= ListEnd; ListIdx++ )
712 if (
ohci_data[HostID].staticEDs[ListIdx].TailP <
ohci_data[HostID].staticEDs[ListLeastBandwidth].TailP ) {
713 ListLeastBandwidth = ListIdx;
715 return ListLeastBandwidth;
720 #if INTERRUPT_LIST_ENABLE
723 uint32_t Balance[16] = {0x0, 0x8, 0x4, 0xC, 0x2, 0xA, 0x6, 0xE, 0x1, 0x9, 0x5, 0xD, 0x3, 0xB, 0x7, 0xF};
726 OHCI_HOST_DATA->staticEDs[0].NextED = 0;
728 OHCI_HOST_DATA->staticEDs[idx].NextED = (
uint32_t) &(OHCI_HOST_DATA->staticEDs[(idx - 1) / 2]);
730 for (count = 0, idx = INTERRUPT_32ms_LIST_HEAD; count < 32; count++, idx++)
731 OHCI_HOST_DATA->staticEDs[idx].NextED =
734 for (idx = 0; idx < 32; idx++)
737 #elif ISO_LIST_ENABLE
738 for (idx = 0; idx < 32; idx++)
750 for (idx = 0; idx < 32; idx++)
759 return Value & 0xFFFFFFF0UL;
762 static __INLINE PHCD_EndpointDescriptor
HcdED(uint8_t idx)
767 static __INLINE PHCD_GeneralTransferDescriptor
HcdGTD(uint8_t idx)
786 #if 0 // just to clear warning
787 static __INLINE
Bool IsInterruptEndpoint(uint8_t EdIdx)
795 *pPipeHandle = ((
uint32_t) (HostID << 8)) + EdIdx;
800 *HostID = Pipehandle >> 8;
801 *EdIdx = Pipehandle & 0xFF;
802 if ((*HostID >= MAX_USB_CORE) || (*EdIdx >=
MAX_ED) || (
HcdED(*EdIdx)->inUse == 0)) {
812 uint8_t EndpointNumber,
815 uint16_t MaxPacketSize,
820 for ((*pEdIdx) = 0; ((*pEdIdx) <
MAX_ED) &&
HcdED((*pEdIdx))->inUse; (*pEdIdx)++) {}
821 if ((*pEdIdx) >=
MAX_ED) {
828 HcdED((*pEdIdx))->inUse = 1;
830 HcdED((*pEdIdx))->hcED.FunctionAddr = DeviceAddr;
834 HcdED((*pEdIdx))->hcED.Skip = 0;
836 HcdED((*pEdIdx))->hcED.MaxPackageSize = MaxPacketSize;
855 for (GtdIdx = 0; (GtdIdx <
MAX_GTD) &&
HcdGTD(GtdIdx)->inUse; GtdIdx++) {}
868 HcdGTD(GtdIdx)->inUse = 1;
871 HcdGTD(GtdIdx)->hcGTD.BufferRounding = 1;
875 if (
HcdED(EdIdx)->hcED.TailP) {
876 ( (PHCD_GeneralTransferDescriptor)
HcdED(EdIdx)->hcED.TailP )->hcGTD.NextTD = (
uint32_t)
HcdGTD(GtdIdx);
895 for (ItdIdx = 0; (ItdIdx <
MAX_ITD) &&
HcdITD(ItdIdx)->inUse; ItdIdx++) {}
898 memset(
HcdITD(ItdIdx), 0,
sizeof(HCD_IsoTransferDescriptor) );
899 HcdITD(ItdIdx)->inUse = 1;
905 if (
HcdED(EdIdx)->hcED.TailP) {
927 FreeGtd( (PHCD_GeneralTransferDescriptor)
HcdED(EdIdx)->hcED.TailP);
931 HcdED(EdIdx)->inUse = 0;
991 tem =
USB_REG(HostID)->InterruptStatus;
992 USB_REG(HostID)->InterruptStatus |= tem;
996 HC_INTERRUPT_RootHubStatusChange |
1022 #if 0 // just to clear warning
1023 static __INLINE
HCD_STATUS OHciHostSuspend(uint8_t HostID)
1030 static __INLINE
HCD_STATUS OHciRhPortPowerOn(uint8_t HostID, uint8_t uPortNumber)
1038 static __INLINE
HCD_STATUS OHciRhPortPowerOff(uint8_t HostID, uint8_t uPortNumber)
1044 static __INLINE
HCD_STATUS OHciRhPortSuspend(uint8_t HostID, uint8_t uPortNumber)
1054 static __INLINE
HCD_STATUS OHciRhPortResume(uint8_t HostID, uint8_t uPortNumber)