Beispiel #1
0
static HCD_STATUS QueueOneITD(uint32_t EdIdx, uint8_t *dataBuff, uint32_t TDLen, uint16_t StartingFrame)
{
    uint32_t i;
    PHCD_IsoTransferDescriptor pItd = (PHCD_IsoTransferDescriptor) Align16(HcdED(EdIdx)->hcED.TailP);

    pItd->StartingFrame = StartingFrame;
    pItd->FrameCount =
        (TDLen / HcdED(EdIdx)->hcED.MaxPackageSize) + (TDLen % HcdED(EdIdx)->hcED.MaxPackageSize ? 1 : 0) - 1;
    pItd->BufferPage0 = Align4k( (uint32_t) dataBuff);
    pItd->BufferEnd = (uint32_t) (dataBuff + TDLen - 1);

    for (i = 0; TDLen > 0 && i < 8; i++) {
        uint32_t XactLen = MIN(TDLen, HcdED(EdIdx)->hcED.MaxPackageSize);

        pItd->OffsetPSW[i] =
            (HCD_STATUS_TRANSFER_NotAccessed <<
             12) | (Align4k((uint32_t) dataBuff) != Align4k(pItd->BufferPage0) ? _BIT(12) : 0) |
            Offset4k((uint32_t) dataBuff);					/*-- FIXME take into cross page account later 15-12: ConditionCode, 11-0: offset --*/

        TDLen -= XactLen;
        dataBuff += XactLen;
    }

    /* Create a new place holder TD & link setup TD to the new place holder */
    ASSERT_STATUS_OK(AllocItdForEd(EdIdx) );

    return HCD_STATUS_OK;
}
Beispiel #2
0
static HCD_STATUS QueueGTDs(uint32_t EdIdx, uint8_t *dataBuff, uint32_t xferLen, uint8_t Direction)
{
    while (xferLen > 0) {
        uint16_t TdLen;
        uint32_t MaxTDLen   = TD_MAX_XFER_LENGTH - Offset4k((uint32_t) dataBuff);

        TdLen = MIN(xferLen, MaxTDLen);
        xferLen -= TdLen;

        ASSERT_STATUS_OK(QueueOneGTD(EdIdx, dataBuff, TdLen, Direction, 0, (xferLen ? 0 : 1)) );
        dataBuff += TdLen;
    }
    return HCD_STATUS_OK;
}
Beispiel #3
0
static HCD_STATUS QueueITDs(uint32_t EdIdx, uint8_t* dataBuff, uint32_t xferLen)
{
	uint32_t FrameIdx;
	uint32_t MaxDataSize;

#if 0 /* Maximum bandwidth (Interval = 1) regardless of Interval value */
	uint8_t MaxXactPerITD, FramePeriod;
	if (HcdED(EdIdx)->Interval < 4) /*-- Period < 8 --*/
	{
		MaxXactPerITD = 1 << ( 4 - HcdED(EdIdx)->Interval ) ;	/*-- Interval 1 => 8, 2 => 4, 3 => 2 --*/
		FramePeriod = 1;
	}else
	{
		MaxXactPerITD = 1;
		FramePeriod = 1 << ( HcdED(EdIdx)->Interval - 4 );	/*-- Frame step 4 => 1, 5 => 2, 6 => 3 --*/
	}
#else
	#define MaxXactPerITD	8
	#define FramePeriod		1
#endif

	MaxDataSize = MaxXactPerITD * HcdED(EdIdx)->hcED.MaxPackageSize;
	FrameIdx = HcdGetFrameNumber(0)+1;	/* FIXME dual controller */

	while (xferLen > 0)
	{
		uint16_t TdLen;
		uint32_t MaxTDLen = TD_MAX_XFER_LENGTH - Offset4k((uint32_t)dataBuff);
		MaxTDLen = MIN(MaxDataSize, MaxTDLen);

		TdLen = MIN(xferLen, MaxTDLen);
		xferLen -= TdLen;

		/*---------- Fill data to Place hodler TD ----------*/
		ASSERT_STATUS_OK ( QueueOneITD(EdIdx, dataBuff, TdLen, FrameIdx) );
		
		FrameIdx = (FrameIdx + FramePeriod) % (1<<16);
		dataBuff += TdLen;
	}
	return HCD_STATUS_OK;
}
Beispiel #4
0
static void ProcessDoneQueue(uint8_t HostID, uint32_t donehead)
{
    PHC_GTD pCurTD = (PHC_GTD) donehead;
    PHC_GTD pTDList = NULL;

    /* do nothing if done queue is empty */
    if (!donehead) {
        return;
    }

    /* reverse done queue order */
    do {
        uint32_t nextTD = pCurTD->NextTD;
        pCurTD->NextTD = (uint32_t) pTDList;
        pTDList = pCurTD;
        pCurTD = (PHC_GTD) nextTD;
    } while (pCurTD);

    while (pTDList != NULL) {
        uint32_t EdIdx;

        pCurTD  = pTDList;
        pTDList = (PHC_GTD) pTDList->NextTD;

        /* TODO Cannot determine EdIdx because GTD and ITD have different offsets for EdIdx  */
        if ( ((uint32_t) pCurTD) <=  ((uint32_t) HcdITD(MAX_ITD - 1)) ) {	/* ISO TD address range */
            PHCD_IsoTransferDescriptor pItd = (PHCD_IsoTransferDescriptor) pCurTD;
            EdIdx = pItd->EdIdx;
        }
        else {	/* GTD */
            PHCD_GeneralTransferDescriptor pGtd = (PHCD_GeneralTransferDescriptor) pCurTD;
            EdIdx = pGtd->EdIdx;

            if (pGtd->hcGTD.CurrentBufferPointer) {
                pGtd->TransferCount -=
                    ( Align4k( ((uint32_t) pGtd->hcGTD.BufferEnd) ^
                               ((uint32_t) pGtd->hcGTD.CurrentBufferPointer) ) ? 0x00001000 : 0 ) +
                    Offset4k((uint32_t) pGtd->hcGTD.BufferEnd) - Offset4k(
                        (uint32_t) pGtd->hcGTD.CurrentBufferPointer) + 1;
            }
            if (HcdED(EdIdx)->pActualTransferCount) {
                *(HcdED(EdIdx)->pActualTransferCount) = pGtd->TransferCount;/* increase usb request transfer count */

            }
        }

        if (pCurTD->DelayInterrupt != TD_NoInterruptOnComplete) {	/* Update ED status if Interrupt on Complete is set */
            HcdED(EdIdx)->status = pCurTD->ConditionCode;
        }

        if ( pCurTD->ConditionCode ) {	/* also update ED status if TD complete with error */
            HcdED(EdIdx)->status =
                (HcdED(EdIdx)->hcED.HeadP.Halted == 1) ? HCD_STATUS_TRANSFER_Stall : pCurTD->ConditionCode;
            HcdED(EdIdx)->hcED.HeadP.Halted = 0;
            hcd_printf("Error on Endpoint 0x%X has HCD_STATUS code %d\r\n",
                       HcdED(EdIdx)->hcED.FunctionAddr | (HcdED(EdIdx)->hcED.Direction == 2 ? 0x80 : 0x00),
                       pCurTD->ConditionCode);
        }

        /* remove completed TD from usb request list, if request list is now empty complete usb request */
        if (IsIsoEndpoint(EdIdx)) {
            FreeItd( (PHCD_IsoTransferDescriptor) pCurTD);
        }
        else {
            FreeGtd( (PHCD_GeneralTransferDescriptor) pCurTD);
        }

        /* Post Semaphore to signal TDs are transfer */
    }
}