📄 hostctrl.c
字号:
}
}
return 0;
}
void OTG242HC_DoPeriodicList(Otg242Hc *hc)
{
U32 intrEd;
U32 currentEd;
OhciEd* ed;
Otg242EtdBank* etd;
SctBool rc;
U32 frames;
U32 startFrame;
U32 i;
static U32 totalMissed = 0;
static U32 totalFrames = 0;
/* Since 1ms interrupt is not guaranteed, we may miss certain interrupts */
if (hc->previousFrameNo == 0xFFFFFFFF)
{
frames = 1;
totalFrames = hc->frameNo;
}
else
{
frames = (hc->frameNo - hc->previousFrameNo) & 0xFFFF;
totalMissed += frames - 1;
if (frames > 32)
{
frames = 32;
}
if (hc->previousFrameNo > hc->frameNo)
{
totalFrames = hc->frameNo + 0xFFFF - totalFrames;
OS_DEBUG_MSG3(15, "DoPeriodicList: total 0x%0x frames, missed 0x%0x frames\r\n",
totalFrames, totalMissed);
totalFrames = hc->frameNo;
totalMissed = 0;
}
}
hc->previousFrameNo = hc->frameNo;
for (i = 0, startFrame = hc->frameNo; i < frames; i++, startFrame--)
{
intrEd = *(hc->hcca + (startFrame & 0x1F));
if (!intrEd)
{
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: interrupt list is NULL\r\n");
return;
}
currentEd = intrEd;
for
(
#if HC_MASS_STORAGE_NEW
ed = (OhciEd*)OS_PhysicalToVirtual((void*)currentEd);
#else
ed = (OhciEd*)OS_PhysicalToVirtual(currentEd);
#endif
ed;
currentEd = ed->nextEd,
ed = (OHCIED_IsEof(currentEd)) ? 0 :
#if HC_MASS_STORAGE_NEW
(OhciEd*)OS_PhysicalToVirtual((void*)(currentEd & OHCIED_POINTER))
#else
(OhciEd*)OS_PhysicalToVirtual(currentEd & OHCIED_POINTER)
#endif
)
{
if (ed->desc & OHCIED_FORMAT)
{
break;
}
if (ed->desc & OHCIED_SKIP)
{
continue;
}
if (ed->headP & OHCIED_HALTED)
{
continue;
}
if ((ed->headP & OHCIED_POINTER) == (ed->tailP & OHCIED_POINTER))
{
/* No TD for this ED */
continue;
}
etd = OTG242ETD_IsInChip(hc->etdBank, ed);
if (etd != NULL)
{
continue;
}
/* Find TD, find an empty slot */
etd = OTG242ETD_Allocate(hc->etdBank);
if (NULL == etd)
{
/* Run out of ETDs */
return;
}
etd->ed = ed;
#if HC_MASS_STORAGE_NEW
etd->td = (OhciTd*)OS_PhysicalToVirtual((void*)(ed->headP & OHCIED_POINTER));
#else
etd->td = (OhciTd*)OS_PhysicalToVirtual((U32)ed->headP & OHCIED_POINTER);
#endif
etd->type = EpTypeIntr;
etd->intrIndex = startFrame & 0x1F;
rc = OTG242ETD_FillEtd(etd);
if (rc == SCC_FALSE)
{
/* Run out of memory etc. */
OTG242ETD_Free(etd);
return;
}
hc->etdIntrEnable |= OTG242ETD_XYIntrEnable(etd->index) ;
if (hc->freeEtdCount == 0)
{
/* Can't process more TD, exit */
return;
}
}
}
}
void OTG242HC_DoCtrlList(Otg242Hc *hc)
{
U32 ctrlEd;
U32 command;
/* OS_DEBUG_MSG1(OS_ZONE_INTR, "DoCtrlList: \r\n"); */
ctrlEd = OTG242HC_GetHcControlCurrentEd(hc);
if (ctrlEd)
{
ctrlEd = OTG242HC_DoList(hc, ctrlEd, EpTypeCtrl);
OTG242HC_SetHcControlCurrentEd(hc, ctrlEd);
if (ctrlEd != 0)
{
/* Run out of ETDs, no need to continue */
return;
}
}
command = OTG242HC_GetHcCommandStatus(hc);
if (!(command &OHCI_HC_CMD_STATUS_CLF))
{
return;
}
ctrlEd = OTG242HC_GetHcControlHeadEd(hc);
OTG242HC_SetHcControlCurrentEd(hc, ctrlEd);
command &= ~OHCI_HC_CMD_STATUS_CLF;
OTG242HC_SetHcCommandStatus(hc, command);
if (hc->freeEtdCount != 0)
{
ctrlEd = OTG242HC_DoList(hc, ctrlEd, EpTypeCtrl);
OTG242HC_SetHcControlCurrentEd(hc, ctrlEd);
}
}
void OTG242HC_DoBulkList(Otg242Hc *hc)
{
U32 bulkEd;
U32 command;
/* OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc:process bulk\r\n"); */
bulkEd = OTG242HC_GetHcBulkCurrentEd(hc);
if (bulkEd)
{
bulkEd = OTG242HC_DoList(hc, bulkEd, EpTypeBulk);
OTG242HC_SetHcBulkCurrentEd(hc, bulkEd);
if (bulkEd != 0)
{
/* Run out of ETDs, no need to continue */
return;
}
}
command = OTG242HC_GetHcCommandStatus(hc);
if (!(command &OHCI_HC_CMD_STATUS_BLF))
{
return;
}
bulkEd = OTG242HC_GetHcBulkHeadEd(hc);
OTG242HC_SetHcBulkCurrentEd(hc, bulkEd);
command &= ~OHCI_HC_CMD_STATUS_BLF;
OTG242HC_SetHcCommandStatus(hc, command);
if (hc->freeEtdCount != 0)
{
bulkEd = OTG242HC_DoList(hc, bulkEd, EpTypeBulk);
OTG242HC_SetHcBulkCurrentEd(hc, bulkEd);
}
}
void OTG242HC_Operational(Otg242Hc *hc)
{
if (hc->hcca == NULL)
{
OS_DEBUG_MSG1(OS_ZONE_INTR, "Otg242Hc: hcca not set\r\n");
return;
}
}
void OTG242HC_WriteToChip(Otg242Hc *hc, U32 source, U32 hc_mem, U32 len, U32 endPage)
{
U32 i;
U32 addr;
void* buffer;
U32 length;
void* buffer2;
U32 bufaddr;
#ifdef OTG_16_BIT_DATA_BUS
U16 w;
#else
U32 w;
#endif
#ifdef DEBUG_OTG_SUBMIT
info("BulkWrite: hc_mem=0x%0x buffer=%p len=0x%0x",hc_mem,buffer,len);
#endif
/* Copy data from memory to host controller */
bufaddr = hc_mem | OTG242HC_START_ADDRESS_DATA;
#if HC_MASS_STORAGE_NEW
buffer = (void*)OS_PhysicalToVirtual((void*)source);
#else
buffer = (void*)OS_PhysicalToVirtual(source);
#endif
addr = source + len;
if ((source & 0xFFFFF000) == (addr & 0xFFFFF000))
{
buffer2 = NULL;
length = len;
}
else
{
#if HC_MASS_STORAGE_NEW
buffer2 = (void*)OS_PhysicalToVirtual((void*)endPage);
#else
buffer2 = (void*)OS_PhysicalToVirtual(endPage);
#endif
length = 0x1000 - (source & 0xFFF);
}
#ifdef OTG_16_BIT_DATA_BUS
if ((S32)buffer & 0x1)
{
/* Buffer is not Word aligned */
U8 *dp;
dp = (U8 *)buffer;
w = 0; /* to shutoff warning by compiler */
i = 0;
while(i < len)
{
switch (i & 1)
{
case 0:
#ifdef OTG_BIG_ENDIAN
w = *dp++ << 8;
#else
w = *dp++;
#endif
break;
case 1:
#ifdef OTG_BIG_ENDIAN
w |= *dp++;
#else
w |= (*dp++) << 8;
#endif
OTG242HC_WriteReg16(hc, bufaddr, w);
bufaddr += 2;
break;
}
i++;
}
if (length < len)
{
length = len - length + (i & 1);
dp = (U8 *)buffer2;
for(; i < len; i++)
{
switch (i & 1)
{
case 0:
#ifdef OTG_BIG_ENDIAN
w = *dp++ << 8;
#else
w = *dp++;
#endif
break;
case 1:
#ifdef OTG_BIG_ENDIAN
w |= *dp++;
#else
w |= (*dp++) << 8;
#endif
OTG242HC_WriteReg16(hc, bufaddr, w);
bufaddr += 2;
break;
}
}
}
if (len & 1)
{
/* Last partial dword */
OTG242HC_WriteReg16(hc, bufaddr, w);
bufaddr += 2;
}
}
else
{
/* Buffer is Word aligned */
U16 *wp;
wp = (U16 *)buffer;
for(i = 0; i < length; i+=2)
{
#ifdef OTG_BIG_ENDIAN
w = *wp++;
OTG242HC_WriteReg16(hc, bufaddr, w);
bufaddr += 2;
#else
OTG242HC_WriteReg16(hc, bufaddr, *wp++);
bufaddr += 2;
#endif
}
if (length < len)
{
length = len - length;
wp = (U16 *)buffer2;
for(i = 0; i < length; i+=2)
{
#ifdef OTG_BIG_ENDIAN
w = *wp++;
OTG242HC_WriteReg16(hc, bufaddr, w);
bufaddr += 2;
#else
OTG242HC_WriteReg16(hc, bufaddr, *wp++);
bufaddr += 2;
#endif
}
}
}
len &= 3;
if (len == 2 || len == 1)
{
OTG242HC_WriteReg16(hc, bufaddr, 0);
bufaddr += 2;
}
#else /* OTG_16_BIT_DATA_BUS */
if ((S32)buffer & 0x3)
{
/* Buffer is not DWord aligned */
U8 *dp;
dp = (U8 *)buffer;
w = 0; /* to shutoff warning by compiler */
i = 0;
while(i < length)
{
switch (i & 3)
{
case 0:
#ifdef OTG_BIG_ENDIAN
w = (*dp++) << 24;
#else
w = *dp++;
#endif
break;
case 1:
#ifdef OTG_BIG_ENDIAN
w |= (*dp++) << 16;
#else
w |= (*dp++) << 8;
#endif
break;
case 2:
#ifdef OTG_BIG_ENDIAN
w |= (*dp++) << 8;
#else
w |= (*dp++) << 16;
#endif
break;
case 3:
#ifdef OTG_BIG_ENDIAN
w |= *dp++;
#else
w |= (*dp++) << 24;
#endif
OTG242HC_WriteReg(hc, bufaddr , w);
bufaddr += 4;
}
i++;
}
if (length < len)
{
dp = (U8 *)buffer2;
length = len - length + (i & 3);
for( ; i < length; i++)
{
switch (i & 3)
{
case 0:
#ifdef OTG_BIG_ENDIAN
w = (*dp++) << 24;
#else
w = *dp++;
#endif
break;
case 1:
#ifdef OTG_BIG_ENDIAN
w |= (*dp++) << 16;
#else
w |= (*dp++) << 8;
#endif
break;
case 2:
#ifdef OTG_BIG_ENDIAN
w |= (*dp++) << 8;
#else
w |= (*dp++) << 16;
#endif
break;
case 3:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -