📄 sc2410_usb_hw.c
字号:
// MDD will recall RxIntHandler by chekcing SC2400_USB_GetInterruptType().
// So, usbdShMem->usbdEir:USBDEIR_EP3 must not be cleared //:-)
//Sleep(100);
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
return fRXFlag;
}
usbdShMem->usbdEir&=~USBDEIR_EP4;
DEBUGMSG(1, (TEXT("--SC2400_USB_RxIntHandler\r\n")));
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
return fRXFlag;
#else
saveCnt= cnt = pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low | pHWHead->pUSBCtrlAddr->OFCR2.out_cnt_high << 8;
if (buflen <(INT)saveCnt)
{
DEBUGMSG(1, (TEXT("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r\n")));
cnt= buflen;
}
if (saveCnt == 0) // No data to read
{
USBDMSG(1, (TEXT("[R0]")));
}
else
{
// USBDMSG(1, (TEXT("Copying <%d>"),cnt));
(*pBuffLen)=cnt;
while(cnt--)
{
*pRxBuffer++ = cRxChar = (BYTE)pHWHead->pUSBCtrlAddr->EP4F.fifo_data;
if( cRxChar == cEvtChar ) fRXFlag = TRUE;
}
}
//not be needed. Only for test
if(pHWHead->pUSBCtrlAddr->OFCR1.out_cnt_low==0 )
if(pHWHead->pUSBCtrlAddr->OCSR1.out_pkt_rdy==1)
{
USBDMSG(1, (TEXT("__OPR__(NEVER EXECUTED)")));
UDC_REG_BITSET(struct OCSR1Bits,&pHWHead->pUSBCtrlAddr->OCSR1, out_pkt_rdy, 0);
}
if ( buflen<(INT)saveCnt) usbdShMem->usbdEir|=USBDEIR_EP4;
else {
usbdShMem->usbdEir&=~USBDEIR_EP4;
DEBUGMSG(1, (TEXT("--SC2400_USB_RxIntHandler\r\n")));
}
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
return fRXFlag;
#endif
}
/*************************************************************************
SC2400_USB_TxIntHandler
Send the next packet to the USB. The first packet gets sent by directly
calling this function (via dispatch table) from the MDD. After the first
call the interrupt mechanism will keep things going.
We return the actual number of bytes we've queued to the UDC. Note that
until the next interrupt we wont know if it has been transmitted. We'll
deal with the failure by saving the original packet and retransmitting if
we get an error. In that case we'll return 0 as the number of bytes sent
since no new bytes have been consumed from the caller's buffer.
When the packet is accepted we return the number of bytes and grab the
next packet (or portion thereof).
*************************************************************************/
//:-)
void SC2400_USB_TxIntHandler( PSER_INFO pHWHead,
PUCHAR pTxBuffer,
ULONG *pBuffLen )
{
unsigned int i;
UCHAR ucLen;
BYTE saveIndex;
DEBUGMSG(1, (TEXT("++SC2400_USB_TxIntHandler\r\n")));
USBDMSG(1, (TEXT("<T:%d>\r\n"),*pBuffLen));
usbdShMem->usbdEir&=~USBDEIR_EP1;
// Endpoint 1 mode
saveIndex=*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX;
UDC_REG_BITSET(struct INDEXBits, &pHWHead->pUSBCtrlAddr->INDEX, index, 0x1);
//pHWHead->pUSBCtrlAddr->INDEX.index=0x1; //:-)
pHWHead->CommErrors &= ~CE_TXFULL;
// If nothing to send, just return after clearing interrupt.
if (! *pBuffLen )
{
DEBUGMSG (1, (TEXT("[TX:nothing to send]\r\n")));
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
return;
}
// Don't try to send more than EP1 can handle.
if( *pBuffLen > EP1Len )
ucLen = EP1Len;
else {
// If we end exactly on a packet boundary, the host doesn't
// realize there is no more data. So if we exactly fill the final
// packet, truncate it so we can send a short packet next frame
// indicating end of the transmission
if( *pBuffLen == EP1Len )
{
USBDMSG (1, (TEXT("Tx breaking packet\r\n")));
ucLen = EP1Len - 2;
} else {
ucLen = (UCHAR)*pBuffLen;
}
}
if (!pHWHead->pUSBCtrlAddr->EP0ICSR1.opr_ipr)
{
// Write to the FIFO directly to send the bytes.
for (i=0; i < ucLen; i++)
{
pHWHead->pUSBCtrlAddr->EP1F.fifo_data = *pTxBuffer++;
// by Neo : Align Problem
// IOW_REG_FIELD(struct EP1FBits,
// &pHWHead->pUSBCtrlAddr->EP1F, fifo_data, *pTxBuffer++);
}
// Return number of bytes transmitted via pBuffLen.
*pBuffLen = ucLen;
//UDC_REG_WRITE(struct EP0ICSR1Bits, &pHWHead->pUSBCtrlAddr->EP0ICSR1, opr_ipr, 1); by Neo : Align Problem
pHWHead->pUSBCtrlAddr->EP0ICSR1.opr_ipr= 1;
} else {
// Transmit already in progress. Just return and wait for current
// transmission to complete before sending more.
USBDMSG(1, (TEXT("Write Pend !!!\r\n")));
*pBuffLen = 0;
}
DEBUGMSG(1, (TEXT("--SC2400_USB_TxIntHandler\r\n")));
*(volatile BYTE *)&pHWHead->pUSBCtrlAddr->INDEX=saveIndex;
}
BOOL
HW_PowerOff(
PSER_INFO pHWHead
)
{
pHWHead->State = OFF;
// cache the interrupt regs
pHWHead->cIntStat_uir = *(BYTE *)&pHWHead->pUSBCtrlAddr->UIR;
pHWHead->cIntStat_eir = *(BYTE *)&pHWHead->pUSBCtrlAddr->EIR;
// disable the USB Clocks
EnterCriticalSection(&pHWHead->HwRegCritSec);
//DEBUGMSG(1, (TEXT("USB:HW_PowerOff()\r\n")));
RETAILMSG(1, (TEXT("USB:HW_PowerOff()\r\n")));
HW_USBClocks(pHWHead);
LeaveCriticalSection(&pHWHead->HwRegCritSec);
return TRUE;
}
BOOL
HW_PowerOn(
PSER_INFO pHWHead
)
{
pHWHead->State = RESUME;
// enable the USB Clocks
EnterCriticalSection(&pHWHead->HwRegCritSec);
//DEBUGMSG(1, (TEXT("USB:HW_PowerOn()\r\n")));
RETAILMSG(1, (TEXT("USB:HW_PowerOn()\r\n")));
HW_USBClocks(pHWHead);
LeaveCriticalSection(&pHWHead->HwRegCritSec);
SetInterruptEvent(pHWHead->pHWObj->dwIntID);
return TRUE;
}
VOID
HW_USBClocks(PSER_INFO pHWHead)
{
if ((pHWHead->State == IDLE) || (pHWHead->State == RESUME))
{
DEBUGMSG(1, (TEXT("HW_USBClocks::IDLE\r\n")));
//
// Enable the USB Clocks
// Fin=12MHz, Fout=48MHz
}
else if (pHWHead->State == OFF)
{
DEBUGMSG(1, (TEXT("HW_USBClocks::OFF\r\n")));
//
// Disable the USB Clocks
//
// Fin=12MHz, Fout=48MHz
// MISCCR: USBD Pads, Suspend mode
}
}
// :-)
/***************************************
Added routines for USBD Rx:DMA Tx:ISR
***************************************/
BOOL InitUsbdDriverGlobals(PSER_INFO pHWHead)
{
BOOL Ret;
int i;
if ( v_pDriverGlobals == NULL )
{
DEBUGMSG(1, (TEXT("Before VirtualAlloc:%08x\r\n"), DRIVER_GLOBALS_PHYSICAL_MEMORY_START));
v_pDriverGlobals =(PDRIVER_GLOBALS)VirtualAlloc( 0,
DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
MEM_RESERVE,
PAGE_NOACCESS);
if ( v_pDriverGlobals == NULL )
{
USBDMSG( 1, (TEXT( "InitUsbdDriverGlobals : VirtualAlloc failed!\r\n")) );
return ( FALSE );
}
Ret = VirtualCopy( (LPVOID)v_pDriverGlobals,
(LPVOID)(DRIVER_GLOBALS_PHYSICAL_MEMORY_START+0x20000000),
DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
PAGE_READWRITE | PAGE_NOCACHE
);
v_pDriverGlobals = (PDRIVER_GLOBALS) (DRIVER_GLOBALS_PHYSICAL_MEMORY_START+0x20000000);
if ( Ret == FALSE )
{
DEBUGMSG( ZONE_ERROR, (TEXT( "InitUsbdDriverGlobals: VirtualCopy failed!\r\n")) );
if ( v_pDriverGlobals )
{
VirtualFree( v_pDriverGlobals,
DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE ,
MEM_RELEASE
);
v_pDriverGlobals = NULL;
}
return ( FALSE );
}
}
DEBUGMSG( 1, (TEXT("v_pDriverGlobals: %x\r\n"), (ULONG)(&(v_pDriverGlobals->usbd))) );
usbdShMem=&(v_pDriverGlobals->usbd);
DEBUGMSG( 1, (TEXT("Before Clear Global\r\n")));
for(i=0;i<USBD_GLOBALS_BUF_SIZE;i++)
{
usbdShMem->usbdRxBuf[i]=0x0;
//usbdShMem->usbdTxBuf[i]=0x0;
}
DEBUGMSG( 1, (TEXT("Before Setting Global\r\n")));
usbdShMem->usbBaseAddress = pHWHead->dwIOBase ;
usbdShMem->usbIRQ = pHWHead->dwIRQ ;
usbdShMem->usbDMANum = pHWHead->dwDMANum ;
usbdShMem->usbdRxRdPt=0;
usbdShMem->usbdRxWrPt=0;
usbdShMem->usbdRxCnt=0;
//usbdShMem->usbdTxRdPt=0;
//usbdShMem->usbdTxWrPt=0;
//usbdShMem->usbdTxCnt=0;
usbdShMem->usbdEir=0;
usbdShMem->usbdUir=0;
usbdShMem->usbdDma3Int=0;
//usbdShMem->usbdMddRxCnt=0;
USBDMSG( 1, (TEXT( "USBD:DRIVER_GLOBALS is initialized\r\n")) );
return( TRUE );
}
BOOL UsbdAllocateVm(void)
{
BOOL Result;
DWORD PhysBase, VirtualBase;
DWORD Return;
MES_DEVINFO DevInfo;
int i;
USBDMSG( 1, (TEXT("USBD:UsbdAllocateVm\r\n")) );
//*************************************************************************
// DMA Initialize
//*************************************************************************
// DMA_GetDeviceInfo ( &DevInfo );
PhysBase= 0xc0000000;
USBDMSG( 1, (TEXT("DevInfo.pDevName : %s\r\n"), DevInfo.pDevName) );
Result = KernelIoControl(IOCTL_CODE_GET_VIRTUAL_ADDR,
&PhysBase, 4,
&VirtualBase, 4,
&Return);
if (Result==FALSE) USBDMSG(1, (TEXT("FALSE")));
DMA_Initialize ( VirtualBase + 0x20000000 );
//*************************************************************************
// Interrupt Initialize
//*************************************************************************
// GPIO PAD Selection Register : USB PAD3 -> USB Device
*(volatile short *)(0xb0001120) |= 0x2;
USBDMSG( 1, (TEXT("USBD:VirtualBase:%08x\r\n"), VirtualBase) );
return TRUE;
}
void UsbdDeallocateVm(void)
{
USBDMSG( 1, (TEXT("USBD:UsbdDeallocateVm\r\n")) );
/*
if(v_pDMAregs)
{
VirtualFree((void*)v_pDMAregs, sizeof(DMAreg), MEM_RELEASE);
v_pDMAregs=NULL;
}
if(v_pINTregs)
{
VirtualFree((void*)v_pINTregs, sizeof(INTreg), MEM_RELEASE);
v_pINTregs=NULL;
}
*/
}
void UsbdInitDma(int DmaNum, int bufIndex,int bufOffset)
{
TDMAC_ChannelData ChData;
// ULONG realPhysicalAddr_UsbdRxBuf;
USBDMSG( 1, (TEXT("UsbdInitDma .... \r\n")));
// If DMA15 is Turned on, DMA15 should be tunred off.
if ( DMA_IsRunChannel ( usbdShMem->usbDMANum ) )
{
USBDMSG( 1, (TEXT("[DMA15 is stopped]\r\n")));
DMA_StopChannel ( usbdShMem->usbDMANum );
while ( DMA_IsRunChannel ( usbdShMem->usbDMANum ) ) NULL;
USBDMSG( 1, (TEXT("[DMA15 is stopped]\r\n")));
}
// DMA Set Channel
realPhysicalAddr_UsbdRxBuf = \
(ULONG)&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd.usbdRxBuf \
- VA_RAM_BASE;
// - DMA_BUFFER_BASE + DMA_PHYSICAL_BASE;
USBDMSG( 1, (TEXT( "[USBD:RPA_URxBuf=%x]"),realPhysicalAddr_UsbdRxBuf) );
DEBUGMSG(1, (TEXT( "%08x\r\n"), (ULONG)&((DRIVER_GLOBALS *)DRIVER_GLOBALS_PHYSICAL_MEMORY_START)->usbd.usbdRxBuf));
#if USB_DMAMODE
DEBUGMSG(1, (TEXT( "DMA_BUFFER_BASE : %08x\r\n"), DMA_BUFFER_BASE));
DEBUGMSG(1, (TEXT( "DMA_PHYSICAL_BASE : %08x\r\n"), DMA_PHYSICAL_BASE));
#endif
if(bufIndex==0)
{
ChData.Target.dwAddr = realPhysicalAddr_UsbdRxBuf + 0 + bufOffset;
}
else
{
ChData.Target.dwAddr = realPhysicalAddr_UsbdRxBuf+(USBD_GLOBALS_BUF_SIZE/2)+bufOffset;
}
ChData.iChannel = usbdShMem->usbDMANum;
ChData.Source.dwType = DMA_MEMTYPE_IO_BYTE;
ChData.Source.iStep = 0;
ChData.Source.dwAddr = 0xC0000000; // Base Address of Peripheral
ChData.Source.bFlyBy = FALSE;
ChData.Source.IOIndex = DMA_PERIPHERAL_INDEX_USBD_EP4;
ChData.Target.dwType = DMA_MEMTYPE_MEM_WORD;
ChData.Target.iStep = 1;
ChData.Target.bFlyBy = FALSE;
ChData.Target.IOIndex = 0;
ChData.dwDataSize = (U16)(USBD_GLOBALS_BUF_SIZE-bufOffset)-1;
ChData.dwBurstType = DMA_BURSTTYPE_NOBURST;
ChData.dwIntType = DMA_INTTYPE_END;
DMA_SetChannel ( &ChData );
DMA_ClrInterruptPend( usbdShMem->usbDMANum );
DMA_RunChannel ( usbdShMem->usbDMANum );
USBDMSG( 0, (TEXT("UsbdInitDma .... : DMA Run \r\n")));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -