📄 etd.c
字号:
OTG242ETD_SetBufferRounding(etd, OhciTd_GetBufferRounding(td));
OTG242ETD_SetDelayIntr(etd, OhciTd_GetDelayInterrupt(td));
#if ETD_TOGGLE_CARRY_FIX
if( etdBank->type != EpTypeIsoc )
{ /* if get datatoggle from togglecarry, update our LSB to match togglecarry */
if( (OhciTd_GetDataToggle(td) & 0x02000000) == 0 )
{
OTG242ETD_SetDataToggle(etd, (OhciEd_GetToggleCarry(ed) << 23) );
}
else
{
OTG242ETD_SetDataToggle(etd, OhciTd_GetDataToggle(td));
}
}
#else
OTG242ETD_SetDataToggle(etd, OhciTd_GetDataToggle(td));
#endif
OTG242ETD_SetErrorCount(etd, OhciTd_GetErrorCount(td));
OTG242ETD_SetCompletionCode(etd, OhciTd_GetCompletionCode(td));
OTG242ETD_SetTotByteCount(etd, etdBank->totalLength);
OTG242ETD_SetBufSize(etd, (etdBank->maxPacketSize * etdBank->xPacketCount) - 1);
if (OhciTd_IsSetup(td))
{
OTG242ETD_SetRetryDelay(etd, 1);
}
}
OTG242ETD_SetFunctionAddress(etd, OhciEd_GetFunctionAddress(ed));
OTG242ETD_SetEpNumber(etd, OhciEd_GetEndpointNumber(ed));
OTG242ETD_SetDirection(etd, OhciEd_GetDirection(ed));
OTG242ETD_SetSpeed(etd, OhciEd_GetSpeed(ed));
switch (etdBank->type)
{
case EpTypeCtrl:
OTG242ETD_SetFormat(etd, OTG242ETD_FORMAT_CTRL);
break;
case EpTypeBulk:
OTG242ETD_SetFormat(etd, OTG242ETD_FORMAT_BULK);
break;
case EpTypeIntr:
OTG242ETD_SetFormat(etd, OTG242ETD_FORMAT_BULK);
/* OTG242ETD_SetFormat(etd, OTG242ETD_FORMAT_INTR); */
/* fill in Relative Polling Position and Polling Interval */
/* etd->control |= ((etdBank->hc->frameNo + 3) & 0xFF) << 8;
etd->control |= 8; */
OTG242ETD_SetStopOnNak(etd);
break;
case EpTypeIsoc:
OTG242ETD_SetFormat(etd, OTG242ETD_FORMAT_ISOC);
break;
default:
OS_DEBUG_MSG2(OS_ZONE_ERR, "Otg242Etd: unknown type=%d\r\n", etdBank->type);
}
OTG242ETD_SetMaxPacketSize(etd, OhciEd_GetMaxPacketSize(ed));
OTG242ETD_SetHalted(etd, OhciEd_GetHalted(ed));
OTG242ETD_SetToggleCarry(etd, OhciEd_GetToggleCarry(ed));
OS_DEBUG_MSG3(OS_ZONE_INTR, "Otg242Etd:-FillEd etd->desc=0x%0x etd->control=0x%0x\r\n",
etd->desc, etd->control);
return SCC_TRUE;
}
SctBool OTG242ETD_FillEtdIsoc(Otg242EtdBank* etdBank)
{
S32 length;
OhciTd* td;
OS_DEBUG_MSG2(OS_ZONE_INTR, "Otg242Etd: +FillEtdIsoc index=%d\r\n", etdBank->index);
/* Calculate the data length for this TD. Data may cross 4K boundary */
td = etdBank->td;
if (OhciTd_GetOffsetPsw(td, 0) & 0x1000)
{
etdBank->memoryAddress = OhciTd_GetBufferEnd(td) & 0xFFFFF000;
}
else
{
etdBank->memoryAddress = OhciTd_GetBufferPage0(td) & 0xFFFFF000;
}
etdBank->memoryAddress |= OhciTd_GetOffsetPsw(td, 0) & 0xFFF;
if (OhciTd_GetBufferPage0(td) == 0)
{
length = 0;
}
else
{
length = (OhciTd_GetBufferEnd(td) & 0xFFF) - (etdBank->memoryAddress & 0xFFF) + 1;
if ((OhciTd_GetBufferEnd(td) & 0xFFFFF000) != (etdBank->memoryAddress & 0xFFFFF000))
{
length += 0x1000;
}
}
if (length > 8192)
{
OS_DEBUG_MSG2(OS_ZONE_INTR, "FillEtd: length 0x%0x\r\n", length);
return SCC_FALSE;
}
etdBank->totalLength = length;
etdBank->finishedLength = 0;
etdBank->maxPacketSize = OhciEd_GetMaxPacketSizeValue(etdBank->ed);
/* on 242 there is only 2 frame count */
etdBank->totalFrameCount = OhciTd_GetFrameCountValue(td) + 1;
etdBank->finishedFrameCount = 0;
if (OhciEd_IsDirectionIn(etdBank->ed, td))
{
etdBank->isDirectionIn = 1;
}
else
{
etdBank->isDirectionIn = 0;
}
OS_MemSet(&etdBank->etd, 0, sizeof(Otg242Etd));
OTG242ETD_FillTdIsoc(etdBank);
OTG242ETD_FillEd(etdBank);
OTG242HC_WriteEtdToChip(etdBank->hc, &etdBank->etd, etdBank->index);
OTG242ETD_EtdEnableSet(etdBank, (U8)etdBank->index);
/* enable ETD done interrupt */
OTG242ETD_ETDDoneEnableSet(etdBank, (U8)etdBank->index);
OTG242ETD_XYInterruptEnablesSet(etdBank, (U8)etdBank->index);
OS_DEBUG_MSG2(OS_ZONE_INTR, "Otg242Etd: -FillEtdIsoc desc=0x%0x\r\n", etdBank->etd.desc);
return SCC_TRUE;
}
SctBool OTG242ETD_FillTdIsoc(Otg242EtdBank *etdBank)
{
OhciTd* td;
SctBool rc;
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Etd:+FillTd\r\n");
td = etdBank->td;
if (etdBank->totalLength > 0)
{
etdBank->xBufferLength = etdBank->maxPacketSize;
if (etdBank->totalFrameCount > 1)
{
etdBank->yBufferLength = etdBank->maxPacketSize;
}
else
{
etdBank->yBufferLength = 0;
}
}
else
{
etdBank->xBufferLength = 0;
etdBank->yBufferLength = 0;
}
etdBank->xPacketCount = (etdBank->xBufferLength - 1) / etdBank->maxPacketSize + 1;
etdBank->yPacketCount = (etdBank->yBufferLength - 1) / etdBank->maxPacketSize + 1;
rc = SCC_TRUE;
if(OhciEd_IsDirectionOut(etdBank->ed, td))
{
rc = OTG242ETD_DoXBufferOut(etdBank);
if (SCC_FALSE == rc)
{
return rc;
}
if (etdBank->yBufferLength > 0)
{
rc = OTG242ETD_DoYBufferOut(etdBank);
}
}
else /* IN transfer */
{
rc = OTG242ETD_DoXBufferIn(etdBank);
if (SCC_FALSE == rc)
{
return rc;
}
if (etdBank->yBufferLength > 0)
{
rc = OTG242ETD_DoYBufferIn(etdBank);
}
}
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Etd:-FillTd\r\n");
return rc;
}
void OTG242ETD_EtdDone(Otg242EtdBank* etdBank)
{
U32 filledX, filledY;
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Etd: +EtdDone\r\n");
if (!etdBank->ed)
{
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Etd:!!! Endpt info removed already\r\n");
OTG242ETD_EtdEnableClear(etdBank, (U8)etdBank->index);
OTG242ETD_Free(etdBank);
return;
}
filledX = OTG242ETD_ReadReg(etdBank, OTG242HC_XBUFFERINTERRUPTSTATUS);
filledY = OTG242ETD_ReadReg(etdBank, OTG242HC_YBUFFERINTERRUPTSTATUS);
filledX &= OTG242ETD_ReadReg(etdBank, OTG242HC_XYINTERRUPTENABLES);
filledY &= OTG242ETD_ReadReg(etdBank, OTG242HC_XYINTERRUPTENABLES);
filledX &= OTG242ETD_XYIntrEnable(etdBank->index);
filledY &= OTG242ETD_XYIntrEnable(etdBank->index);
if (filledX)
{
OTG242ETD_XBufferInterruptStatusClear(etdBank, (U8)etdBank->index);
}
if (filledY)
{
OTG242ETD_YBufferInterruptStatusClear(etdBank, (U8)etdBank->index);
}
/*************************************************************
This ETD information is kept in the chip, and now read it
out to check whether its halt bit is set
*************************************************************/
OTG242HC_ReadEtdFromChip(etdBank->hc, &etdBank->etd, etdBank->index);
if (filledX /*& OTG242ETD_XIntrEnable(etdBank->index)*/)
{
OTG242ETD_NextPacket(etdBank);
}
if (filledY /*& OTG242ETD_YIntrEnable(etdBank->index)*/)
{
OTG242ETD_NextPacket(etdBank);
}
/* disable ETD interrupt */
OTG242ETD_XYInterruptEnablesClear( etdBank, (U8)etdBank->index);
if (etdBank->type == EpTypeIsoc)
{
OS_DEBUG_MSG2(OS_ZONE_INTR, "Otg242Etd: Read back Iso transfer, index %d\r\n", etdBank->index);
OTG242ETD_IsocDone(etdBank);
}
else
{
OTG242ETD_CtrlDone(etdBank);
}
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Etd: -EtdDone\r\n");
}
void OTG242ETD_dump(Otg242EtdBank *etdBank)
{
Otg242Etd* etd;
Otg242EtdBank *e;
U32 w;
w = OTG242ETD_ReadReg(etdBank, OTG242HC_CTRL);
OS_DEBUG_MSG2(OS_ZONE_ERR, "hc control=0x%0x\r\n", w);
etd = &etdBank->etd;
OS_DEBUG_MSG3(OS_ZONE_ERR, "current ETD%d dw0=0x%0x\r\n", etdBank->index, etd->desc);
OS_DEBUG_MSG3(OS_ZONE_ERR, "dw2=0x%0x dw3=0x%0x\r\n", etd->control, etd->td.packetControl);
/* OS_DEBUG_MSG2(OS_ZONE_ERR, "dw7=0x%0x\r\n", etd->dword7); */
if (etdBank->index == 0)
{
e = &(etdBank->hc->etdBank[1]);
}
else if (etdBank->index == 1)
{
e = &(etdBank->hc->etdBank[0]);
}
else
{
e = &(etdBank->hc->etdBank[0]);
}
etd = &e->etd;
if (e->filled)
{
OS_DEBUG_MSG3(OS_ZONE_ERR, "other ETD%d dw0=0x%0x\r\n", e->index, etd->desc);
OS_DEBUG_MSG3(OS_ZONE_ERR, "dw2=0x%0x dw3=0x%0x\r\n", etd->control, etd->td.packetControl);
/* OS_DEBUG_MSG2(OS_ZONE_ERR, "dw7=0x%0x\r\n", etd->dword7); */
}
}
void OTG242ETD_CtrlDone(Otg242EtdBank *etdBank)
{
OhciTd* td;
OhciEd* ed;
Otg242Etd* etd;
S32 actualLength;
#if ETD_MASS_STORAGE_NEW
U32 w;
#endif
td = etdBank->td;
ed = etdBank->ed;
etd = &etdBank->etd;
#if ETD_MASS_STORAGE_NEW
w = ed->headP & OHCIED_POINTER;
if (w != (U32)OS_VirtualToPhysical(td))
{
OS_DEBUG_MSG2(OS_ZONE_INTR, "OTG243ETD_CtrlDone td=%x unlinked\r\n", td);
OTG242ETD_Free(etdBank);
return;
}
#endif
actualLength = etdBank->totalLength - OTG242ETD_GetTotByteCount(etd);
if (OTG242ETD_GetCompletionCode(etd) == OTG242ETD_COMPLETION_CODE_DATA_OVERRUN)
{
actualLength += etdBank->maxPacketSize;
}
else if ((OTG242ETD_GetCompletionCode(etd)) == OTG242ETD_COMPLETION_CODE_NAK)
{
actualLength -= etdBank->maxPacketSize;
if( actualLength < 0 )
{
actualLength = 0;
}
}
if ((OTG242ETD_GetCompletionCode(etd)) == OTG242ETD_COMPLETION_CODE_ACK)
{
OhciTd_SetConditionCode(td, OTG242ETD_COMPLETION_CODE_NO_ERROR);
}
else
{
OhciTd_SetConditionCode(td, OTG242ETD_GetCompletionCode(etd));
}
OhciTd_SetErrorCount(td, OTG242ETD_GetErrorCount(etd));
OhciEd_SetToggleCarry(ed, OTG242ETD_GetToggleCarry(etd));
/*****************************************************
First of all, we should check error returned. If
this endpoint is halted, we should put this Td to
the done quee. If error is 3, we should remove this
TD too.
******************************************************/
/*****************************************************
Since interrupt endpoint is used as bulk and set
stop on NAK, we need to check for the NAK either
the ETD was halted or not.
*****************************************************/
if ( (OTG242ETD_GetHalted(etd) == 0) && (etd->desc & OTG242ETD_FORMAT_BULK) )
{
if (OTG242ETD_GetCompletionCode(etd) == OTG242ETD_COMPLETION_CODE_NAK)
{
OhciTd_SetConditionCode(td, OTG242ETD_COMPLETION_CODE_NO_ERROR);
OhciTd_MoveBufferPointer(td, actualLength);
OTG242ETD_Free(etdBank);
return;
}
}
if (OTG242ETD_GetHalted(etd) != 0)
{
if (OTG242ETD_GetCompletionCode(etd) == OTG242ETD_COMPLETION_CODE_DATA_UNDERRUN)
{
OhciTd_MoveBufferPointer(td, actualLength);
}
else if (OTG242ETD_GetCompletionCode(etd) == OTG242ETD_COMPLETION_CODE_NAK)
{
OhciTd_SetConditionCode(td, OTG242ETD_COMPLETION_CODE_NO_ERROR);
OhciTd_MoveBufferPointer(td, actualLength);
OTG242ETD_Free(etdBank);
return;
}
else
{
OhciTd_MoveBufferPointer(td, actualLength);
}
OhciEd_SetHalted(ed);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -