// -------------------------------------------------------------------- // Copyright (c) 2007 by Terasic Technologies Inc. // -------------------------------------------------------------------- // // Permission: // // Terasic grants permission to use and modify this code for use // in synthesis for all Terasic Development Boards and Altera Development // Kits made by Terasic. Other use of this code, including the selling // ,duplication, or modification of any portion is strictly prohibited. // // Disclaimer: // // This VHDL/Verilog or C/C++ source code is intended as a design reference // which illustrates how these types of functions can be implemented. // It is the user's responsibility to verify their design for // consistency and functionality through the use of formal // verification methods. Terasic provides no warranty regarding the use // or functionality of this code. // // -------------------------------------------------------------------- // // Terasic Technologies Inc // 356 Fu-Shin E. Rd Sec. 1. JhuBei City, // HsinChu County, Taiwan // 302 // // web: http://www.terasic.com/ // email: support@terasic.com // // -------------------------------------------------------------------- // Author: Richard Chang #include #include #include #include #include #include #include "terasic_includes.h" #include "isp1761_transport.h" //#include "isp1761_transfer.h" #include "..\hal\isp1761_hal_nios2.h" #include "isp1761_register.h" #ifdef DEBUG_USB_PORT #define DEBUG_DATA(x) {printf x;} #define DEBUG_OUT(x) // {printf x;} #define DEBUG_STATUS(x) {printf x;} #define DEBUG_ERR(x) {printf("[PORT_ERR]"); printf x;} #define DEBUG_DECODE(x) {printf("[PTD Decode]"); printf x;} #else #define DEBUG_DATA(x) #define DEBUG_OUT(x) #define DEBUG_STATUS(x) #define DEBUG_ERR(x) #define DEBUG_DECODE(x) #endif //DEBUG_USB_PORT ////////////////////////////////////////////////////////////////////////////// // internal function ////////////////////////////////////////////////////////////////////////////// #define STALL_MAX_TRY_NUM 1000 //#define NACK_MAX_TRY_NUM 1000 #define NACK_MS_TIMEOUT 500 // ms #define MEM_BANK0 0x00000 #define MEM_BANK1 0x00000 //0x10000 #define MEM_BANK2 0x00000 //0x20000 #define MEM_BANK2 0x00000 //0x30000 // PTD_RESULT port_AltOut(USB_DEVICE *pUsbDevice, alt_u8 *szData, alt_u16 DataLen, alt_u8 Token, alt_u8 EPType, alt_u8 EndPt, alt_u8 DataToggle); PTD_RESULT port_AltIn(USB_DEVICE *pUsbDevice, alt_u8 *szBuf, alt_u16 BufLen, alt_u8 Token, alt_u8 EPType, alt_u8 EndPt, alt_u8 DataToggle, alt_u16 *pInLen); // PTD for high-speed void HPTD_BuildAltHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, alt_u8 DeviceAddr, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 EPType, alt_u8 DataToggle); void HPTD_BuildIntHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, alt_u8 DeviceAddr, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 DataToggle); // PTD fro low-speed void PTD_BuildAltHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, USB_DEVICE *pUsbDevice, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 EPType, alt_u8 DataToggle); void PTD_BuildIntHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, USB_DEVICE *pUsbDevice, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 DataToggle); // PDT common function void PTD_WriteHeader(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen); alt_u16 HPTD_ReadHeader(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen); alt_u16 PTD_ReadHeader(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen); void PTD_WritePlayload(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen); void PTD_ReadPayload(alt_u32 Addr, alt_u32 *szData, alt_u32 ByteLen); // Common alt_u32 Mem2CpuAddr(alt_u32 MemAddr); alt_u32 Cpu2MemAddr(alt_u32 CpuAddr); // debug void PTD_Dump(alt_u32 PTD[8]); void PTD_SplitIntDump(alt_u32 PTD[8]); ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //////////// Control Port In/Out: External API ////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// PTD_RESULT PORT_ControlOut(USB_DEVICE *pUsbDevice, alt_u8 *szData, alt_u16 DataLen, alt_u8 Token, alt_u8 DataToggle){ PTD_RESULT PtdResult; const alt_u8 EPType = EPType_CONTROL; const alt_u8 EndPt = 0; // alwasy 0 for control-pipe PtdResult = port_AltOut(pUsbDevice, szData, DataLen, Token, EPType, EndPt, DataToggle); return PtdResult; } PTD_RESULT PORT_ControlIn(USB_DEVICE *pUsbDevice, alt_u8 *szBuf, alt_u16 BufLen, alt_u8 Token, alt_u8 DataToggle, alt_u16 *pInLen){ PTD_RESULT PtdResult; const alt_u8 EPType = EPType_CONTROL; const alt_u8 EndPt = 0; // alwasy 0 for control-pipe PtdResult = port_AltIn(pUsbDevice, szBuf, BufLen, Token, EPType, EndPt, DataToggle, pInLen); return PtdResult; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //////////// Bulk Port In/Out: External API ////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// PTD_RESULT PORT_BulkOut(USB_DEVICE *pUsbDevice, alt_u8 *szData, alt_u16 DataLen, alt_u8 Token, alt_u8 EndPt, alt_u8 DataToggle){ PTD_RESULT PtdResult; const alt_u8 EPType = EPType_BULK; PtdResult = port_AltOut(pUsbDevice, szData, DataLen, Token, EPType, EndPt, DataToggle); return PtdResult; } PTD_RESULT PORT_BulkIn(USB_DEVICE *pUsbDevice, alt_u8 *szBuf, alt_u16 BufLen, alt_u8 Token, alt_u8 EndPt, alt_u8 DataToggle, alt_u16 *pInLen){ PTD_RESULT PtdResult; const alt_u8 EPType = EPType_BULK; PtdResult = port_AltIn(pUsbDevice, szBuf, BufLen, Token, EPType, EndPt, DataToggle, pInLen); return PtdResult; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //////////// ALT (Control & Bulk) Port: internal API ////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// PTD_RESULT port_AltOut(USB_DEVICE *pUsbDevice, alt_u8 *szData, alt_u16 DataLen, alt_u8 Token, alt_u8 EPType, alt_u8 EndPt, alt_u8 DataToggle){ PTD_RESULT PtdResult = PTD_RESULT_UNKOWN; bool bDoneMap = FALSE; bool bXferDone = FALSE, bComplete; alt_u32 InternalMemAddr = 0x380, donemap; alt_u32 szPTD[8], szResultPTD[8]; alt_u32 CpuAddr = Mem2CpuAddr(InternalMemAddr) | MEM_BANK1; int ComplteCheckCnt, NackRetyrCnt=0; const alt_u32 PtdAddr = 0x0C00; const alt_u16 MaxPacketLength = pUsbDevice->EpOut[EndPt].MaxPacketSize; //(EndPt == 0)?64:512; alt_u16 XferLen; alt_32 timeout_abort; // DEBUG_OUT((" %s Transaction\n", szTokenName[Token] )); HAL1761_RegWrite32(HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); // write payload to to ISP761's Payload memory if (DataLen) PTD_WritePlayload(CpuAddr, (alt_u32 *)szData, DataLen); // build PTD if (pUsbDevice->Speed == USB_SPEED_HIGH){ HPTD_BuildAltHeader(szPTD, DataLen, MaxPacketLength, EndPt, pUsbDevice->Addr, Token, InternalMemAddr, EPType, DataToggle); }else{ PTD_BuildAltHeader(szPTD, DataLen, MaxPacketLength, EndPt, pUsbDevice, Token, InternalMemAddr, EPType, DataToggle); } timeout_abort = alt_nticks() + NACK_MS_TIMEOUT * alt_ticks_per_second() / 1000; //while(!bXferDone){ do{ // write PTD to ISP1761's ASYNC memory of PTD area PTD_WriteHeader(PtdAddr, szPTD, PTD_HEADER_SIZE); // start PTD HAL1761_RegWrite32(HC_ATL_PTD_SKIPMAP_REG, 0xfffffffe); /*set the last td*/ HAL1761_RegWrite32(HC_ATL_PTD_LASTPTD_REG, 0x00000001); /* indicate one of the ATL PTDs is filled, and the ALT PTD area will be processed */ HAL1761_RegWrite32(0x334 /*HC_BUFFER_STATUS_REG */ ,0x1); //msleep(20); usleep(10); /*wait for the setup to complete*/ bDoneMap = FALSE; bComplete = FALSE; ComplteCheckCnt = 0; while(!bComplete){ donemap = HAL1761_RegRead32(HC_ATL_PTD_DONEMAP_REG); if(donemap & 0x1){ bDoneMap = TRUE; bComplete = TRUE; }else if (ComplteCheckCnt++ > 100000){ DEBUG_ERR(("done map %lXh(timeout)\n", donemap)); bComplete = TRUE; }else{ usleep(5); } } // while(bComplete) // readback to check bXferDone = TRUE; if (bDoneMap){ XferLen = HPTD_ReadHeader(PtdAddr, szResultPTD, PTD_HEADER_SIZE); if (szResultPTD[3] & PTD_A_ACTIVE){ // NOT ACK or HAL // re-try for none ack PtdResult = PTD_RESULT_NACK; if (alt_nticks() < timeout_abort){ NackRetyrCnt++; bXferDone = FALSE; usleep(100); }else{ DEBUG_ERR(("Nack retry timeout, retry %d times\n", NackRetyrCnt)); } }else if (szResultPTD[3] & PTD_H_STALL){ PtdResult = PTD_RESULT_STALL; // re-try for stall? //if (XferCnt++ < NACK_MAX_TRY_NUM){ // bXferDone = FALSE; // re-try //} }else if (XferLen != DataLen){ PtdResult = PTD_RESULT_NLEN; }else{ PtdResult = PTD_RESULT_SUCCESS; } }else{ PtdResult = PTD_RESULT_NCOMP; } HAL1761_RegWrite32(HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); //} // while(!bDone) }while(!bXferDone); if (PtdResult != PTD_RESULT_SUCCESS){ DEBUG_OUT(("[ERR]AltOut Error!!!!!!!!!!!!!!!!\n")); } return PtdResult; } PTD_RESULT port_AltIn(USB_DEVICE *pUsbDevice, alt_u8 *szBuf, alt_u16 BufLen, alt_u8 Token, alt_u8 EPType, alt_u8 EndPt, alt_u8 DataToggle, alt_u16 *pInLen){ PTD_RESULT PtdResult = PTD_RESULT_UNKOWN; bool bXferDone = FALSE, bDoneMap, bComplete; alt_u32 InternalMemAddr = 0x380, donemap; alt_u32 szPTD[8], szResultPTD[8]; alt_u32 CpuAddr = Mem2CpuAddr(InternalMemAddr) | MEM_BANK2; int ComplteCheckCnt, NackRetyrCnt=0; const alt_u32 PtdAddr = 0x0C00; const alt_16 MaxPacketLength = pUsbDevice->EpIn[EndPt].MaxPacketSize;//(EndPt == 0)?64:512; alt_u16 XferLen; alt_32 timeout_abort, time_domap_start; // DEBUG_OUT((" %s Transaction\n", szTokenName[Token] )); HAL1761_RegWrite32(HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); HAL1761_RegWrite32(HC_BUFFER_STATUS_REG,0x00); // build PTD if (pUsbDevice->Speed == USB_SPEED_HIGH){ HPTD_BuildAltHeader(szPTD, BufLen, MaxPacketLength, EndPt, pUsbDevice->Addr, Token, InternalMemAddr, EPType,DataToggle); }else{ PTD_BuildAltHeader(szPTD, BufLen, MaxPacketLength, EndPt, pUsbDevice, Token, InternalMemAddr, EPType, DataToggle); } timeout_abort = alt_nticks() + NACK_MS_TIMEOUT * alt_ticks_per_second() / 1000; //while(!bXferDone){ do{ // write PTD to ISP1761's ASYNC memory of PTD area PTD_WriteHeader(PtdAddr, szPTD, PTD_HEADER_SIZE); // start PTD HAL1761_RegWrite32(HC_ATL_PTD_SKIPMAP_REG, 0xfffffffe); /*set the last td*/ HAL1761_RegWrite32(HC_ATL_PTD_LASTPTD_REG, 0x00000001); /*set the HAL1761_Write32 full*/ HAL1761_RegWrite32(HC_BUFFER_STATUS_REG,0x1); //msleep(20); usleep(10); /*wait for the setup to complete*/ bDoneMap = FALSE; bComplete = FALSE; ComplteCheckCnt = 0; time_domap_start = alt_nticks(); while(!bComplete){ donemap = HAL1761_RegRead32(HC_ATL_PTD_DONEMAP_REG); // after read, all 1-value will become 0-value //DEBUG_OUT(("done map %lXh\n", donemap)); if(donemap & 0x1){ bDoneMap = TRUE; bComplete = TRUE; }else if (ComplteCheckCnt++ > 100000){ DEBUG_ERR(("done map %lXh(timeout=%.3fsec)\n", donemap, (float)(alt_nticks()-time_domap_start)/(float)alt_ticks_per_second() )); bComplete = TRUE; }else{ usleep(5); } } // readback to check bXferDone = TRUE; if (bDoneMap){ XferLen = HPTD_ReadHeader(PtdAddr, szResultPTD, PTD_HEADER_SIZE); if (szResultPTD[3] & PTD_A_ACTIVE){ // NOT ACK or HAL // re-try for none ack PtdResult = PTD_RESULT_NACK; if (alt_nticks() < timeout_abort){ NackRetyrCnt++; bXferDone = FALSE; usleep(100); }else{ DEBUG_ERR(("Nack retry timeout, retry %d times\n", NackRetyrCnt)); } }else if (szResultPTD[3] & PTD_H_STALL){ PtdResult = PTD_RESULT_STALL; DEBUG_ERR(("Stall\n")); }else{ PtdResult = PTD_RESULT_SUCCESS; } }else{ PtdResult = PTD_RESULT_NCOMP; } HAL1761_RegWrite32(HC_ATL_PTD_SKIPMAP_REG, 0xffffffff); }while(!bXferDone);// // while(!bDone) if (PtdResult == PTD_RESULT_SUCCESS){ if (XferLen) PTD_ReadPayload(CpuAddr, (alt_u32 *)szBuf, XferLen); *pInLen = XferLen; }else{ *pInLen = 0; DEBUG_OUT(("[ERR]AltOut Error!!!!!!!!!!!!!!!!\n")); } return PtdResult; } // build PTD for high speed device void HPTD_BuildAltHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, alt_u8 DeviceAddr, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 EPType, alt_u8 DataToggle){ const alt_u8 Mult=0x01; const alt_u8 PortNumber=0; const alt_u8 HubAddr = 0; memset(szPTD, 0, 8*sizeof(alt_u32)); alt_u8 V = 0x01; alt_u8 S = 0; //bHighSpeed?0:1;//1; // 0:high-speed transaction, 1:split transaction szPTD[0] = V | ((NrBytesToTransfer & 0x7FFF) << 3) | ((MaxPacketLength & 0x7FF) << 18) | ((Mult & 0x03) << 29) | ((EndPt & 0x01) << 31); szPTD[1] = ((EndPt & 0x0E) >> 1) | ((DeviceAddr & 0x7F) << 3) | ((Token & 0x03) << 10) | ((EPType & 0x03) << 12) | ((S & 0x01) << 14) | ((PortNumber & 0x7F) << 18) | ((HubAddr & 0x7F) << 25); szPTD[2] = (0x01 << 28) | ((DataStartAddr & 0xFFFF) << 8); szPTD[3] = 0x01800000 | ((V & 0x01) << 31) | ((DataToggle & 0x01) << 25) ; } // build PTD fow full or low speed device // see ISP1761_4.pdf, Page 73, Table 70 void PTD_BuildAltHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, USB_DEVICE *pUsbDevice, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 EPType, alt_u8 DataToggle){ alt_u8 SE = (pUsbDevice->Speed == USB_SPEED_FULL)?0x00:0x02; memset(szPTD, 0, 8*sizeof(alt_u32)); alt_u8 V = 0x01; alt_u8 S = 1;//1; // 0:high-speed transaction, 1:Split transaction alt_u8 SC = 0; // 0: Start split, 1: Complte Split alt_u8 Cerr = 0; szPTD[0] = V | ((NrBytesToTransfer & 0x7FFF) << 3) | ((MaxPacketLength & 0x7FF) << 18) | ((EndPt & 0x01) << 31);; szPTD[1] = ((EndPt & 0x0E) >> 1) | ((pUsbDevice->Addr & 0x7F) << 3) | ((Token & 0x03) << 10) | ((EPType & 0x03) << 12) | ((S & 0x01) << 14); szPTD[1] |= ((SE & 0x03) << 16) | ((pUsbDevice->Port & 0x7F) << 18) | ((pUsbDevice->HubAddr & 0x7F) << 25); szPTD[2] = ((DataStartAddr & 0xFFFF) << 8); szPTD[3] = ((V & 0x01) << 31) | ((DataToggle & 0x01) << 25) | ((SC & 0x01) << 27) | ((Cerr & 0x03) << 23); } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //////////// INT Port: Internal API ////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // external function PTD_RESULT PORT_IntIn(USB_DEVICE *pUsbDevice, alt_u8 *szBuf, alt_u16 BufLen, alt_u8 EndPt, alt_u8 DataToggle, alt_u16 *pInLen){ PTD_RESULT PtdResult = PTD_RESULT_UNKOWN; bool bXferDone = FALSE, bDoneMap, bComplete; int ComplteCheckCnt, NackRetyrCnt=0; alt_u32 InternalMemAddr = 0x180, donemap; alt_u32 szPTD[8], szResultPTD[8]; alt_u32 CpuAddr = Mem2CpuAddr(InternalMemAddr); const alt_u32 PtdAddr = 0x0800; // INTERRUPT PTD Header Area const alt_u8 MaxPacketLength = pUsbDevice->EpIn[EndPt].MaxPacketSize; //4;//64;//4; //8; alt_u16 XferLen; const alt_u8 Token = TOKEN_IN; alt_32 timeout_abort; HAL1761_RegWrite32(HC_INT_PTD_SKIPMAP_REG, 0xffffffff); HAL1761_RegWrite32(HC_BUFFER_STATUS_REG,NO_BUF_FILL); // build USB Interrupt PTD if (pUsbDevice->Speed == USB_SPEED_HIGH){ HPTD_BuildIntHeader(szPTD, BufLen, MaxPacketLength, EndPt, pUsbDevice->Addr, Token, InternalMemAddr, DataToggle); }else{ PTD_BuildIntHeader(szPTD, BufLen, MaxPacketLength, EndPt, pUsbDevice, Token, InternalMemAddr, DataToggle); } //DEBUG_OUT((" INT-IN Transaction\n")); timeout_abort = alt_nticks() + NACK_MS_TIMEOUT * alt_ticks_per_second() / 1000; do{ //while(!bXferDone){ // write PTD to ISP1761's INTERRUPT memory of PTD area PTD_WriteHeader(PtdAddr, szPTD, PTD_HEADER_SIZE); // start PTD HAL1761_RegWrite32(HC_INT_PTD_SKIPMAP_REG, 0xfffffffe); /*set the last td*/ HAL1761_RegWrite32(HC_INT_PTD_LASTPTD_REG, 0x00000001); /*set the HAL1761_Write32 full*/ HAL1761_RegWrite32(HC_BUFFER_STATUS_REG, INT_BUF_FILL); //msleep(5); usleep(1); /*wait for the setup to complete*/ bDoneMap = FALSE; bComplete = FALSE; ComplteCheckCnt = 0; while(!bComplete){ donemap = HAL1761_RegRead32(HC_INT_PTD_DONEMAP_REG); // after read, all 1-value will become 0-value //DEBUG_OUT(("done map %lXh\n", donemap)); if(donemap & 0x1){ bDoneMap = TRUE; bComplete = TRUE; }else if (ComplteCheckCnt++ > 10000){ DEBUG_OUT(("done map %lXh(timeout)\n", donemap)); bComplete = TRUE; }else{ usleep(1); } } // readback to check bXferDone = TRUE; if (bDoneMap){ if (pUsbDevice->Speed == USB_SPEED_HIGH) XferLen = HPTD_ReadHeader(PtdAddr, szResultPTD, PTD_HEADER_SIZE); else XferLen = PTD_ReadHeader(PtdAddr, szResultPTD, PTD_HEADER_SIZE); if (szResultPTD[3] & PTD_A_ACTIVE){ // NOT ACK or HAL // re-try for none ack PtdResult = PTD_RESULT_NACK; if (alt_nticks() < timeout_abort){ NackRetyrCnt++; bXferDone = FALSE; usleep(100); }else{ DEBUG_ERR(("Nack retry timeout, retry %d times\n", NackRetyrCnt)); } }else if (szResultPTD[3] & PTD_H_STALL){ PtdResult = PTD_RESULT_STALL; }else{ PtdResult = PTD_RESULT_SUCCESS; } }else{ PtdResult = PTD_RESULT_NCOMP; } HAL1761_RegWrite32(HC_INT_PTD_SKIPMAP_REG, 0xffffffff); }while(!bXferDone); if (PtdResult == PTD_RESULT_SUCCESS){ if (XferLen) PTD_ReadPayload(CpuAddr, (alt_u32 *)szBuf, XferLen); *pInLen = XferLen; }else{ *pInLen = 0; } return PtdResult; } // internal function // build PTD high speed device // see ISP1761_4.pdf, Page 69, Table 67 void HPTD_BuildIntHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, alt_u8 DeviceAddr, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 DataToggle){ const alt_u8 Mult=0x01; memset(szPTD, 0, 8*sizeof(alt_u32)); const alt_u8 V = 0x01; const alt_u8 EPType = EPType_INTERRUPT; // INTERRUPT const alt_u8 S = 0x00;// high-speed transaction // const alt_u8 S = 0x01;// high-speed transaction const alt_u8 uFrame = 0xFF; const alt_u8 uSA = 0xFF; szPTD[0] = V | ((NrBytesToTransfer & 0x7FFF) << 3) | ((MaxPacketLength & 0x7FF) << 18) | ((Mult & 0x03) << 29) | ((EndPt & 0x01) << 31); szPTD[1] = ((EndPt & 0x0E) >> 1) | ((DeviceAddr & 0x7F) << 3) | ((Token & 0x03) << 10) | ((EPType & 0x03) << 12) | ((S & 0x01) << 14); szPTD[2] = (uFrame & 0xFF) | ((DataStartAddr & 0xFFFF) << 8); szPTD[3] = 0x01800000 | ((V & 0x01) << 31) | ((DataToggle & 0x01) << 25) ; szPTD[4] = uSA; } // build PTD fow full or low speed device // see ISP1761_4.pdf, Page 81, Table 75 void PTD_BuildIntHeader(alt_u32 szPTD[8], alt_16 NrBytesToTransfer, alt_16 MaxPacketLength, alt_u8 EndPt, USB_DEVICE *pUsbDevice, alt_u8 Token, alt_u16 DataStartAddr, alt_u8 DataToggle){ memset(szPTD, 0, 8*sizeof(alt_u32)); alt_u8 SE = (pUsbDevice->Speed == USB_SPEED_FULL)?0x00:0x02; const alt_u8 V = 0x01; const alt_u8 EPType = EPType_INTERRUPT; // INTERRUPT alt_u8 S = 1;//1; // 0:high-speed transaction, 1:Split transaction alt_u8 SC = 0; // 0: Start split, 1: Complte Split alt_u8 Cerr = 0x03;//0x03; #if 0 const alt_u8 uFrame = 0xFF; const alt_u8 uSA = 0xFF; const alt_u8 uSCS = 0xFF; #else const alt_u8 uFrame = 0x20; // 8ms const alt_u8 uSA = 0x01; const alt_u8 uSCS = 0xFE;//0x01 << 2; #endif szPTD[0] = (V & 0x01) | ((NrBytesToTransfer & 0x7FFF) << 3) | ((MaxPacketLength & 0x7FF) << 18) | ((EndPt & 0x01) << 31); szPTD[1] = ((EndPt & 0x0E) >> 1) | ((pUsbDevice->Addr & 0x7F) << 3) | ((Token & 0x03) << 10) | ((EPType & 0x03) << 12) | ((S & 0x01) << 14); szPTD[1] |= ((SE & 0x03) << 16) | ((pUsbDevice->Port & 0x7F) << 18) | ((pUsbDevice->HubAddr & 0x7F) << 25); szPTD[2] = (uFrame & 0xFF) | ((DataStartAddr & 0xFFFF) << 8); szPTD[3] = ((V & 0x01) << 31) | ((Cerr & 0x03) << 23) | ((DataToggle & 0x01) << 25) | ((SC & 0x01) << 27) ; szPTD[4] = uSA & 0xFF; szPTD[5] = uSCS & 0xFF; } ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// //////////// PTD ///////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// alt_u32 Mem2CpuAddr(alt_u32 MemAddr){ alt_u32 CpuAddr; CpuAddr = (MemAddr << 3) + 0x400; return CpuAddr; } alt_u32 Cpu2MemAddr(alt_u32 CpuAddr){ alt_u32 MemAddr; MemAddr = (CpuAddr - 0x400) >> 3; return MemAddr; } void PTD_WriteHeader(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen){ assert(ByteLen == 32); #ifdef DEBUG_PTD int i; DEBUG_OUT((" PTD Write Header:\n")); for(i=0;i<(ByteLen+3)/4;i++){ DEBUG_OUT((" DW%d=%04lX %04lXh\n", i, (szData[i] >> 16) & 0xFFFF, szData[i] & 0xFFFF)); } #endif //DEBUG_PTD HAL1761_MemWrite(Addr, szData, ByteLen); } alt_u16 HPTD_ReadHeader(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen){ assert(ByteLen == 32); alt_u16 XferLen = -1; HAL1761_MemRead(Addr, szData, ByteLen); if ((szData[0] & 0x01) == 0) // V become 0 XferLen = szData[3] & 0x7FFF; //15-bits return XferLen; } alt_u16 PTD_ReadHeader(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen){ assert(ByteLen == 32); alt_u16 XferLen = -1; HAL1761_MemRead(Addr, szData, ByteLen); if ((szData[0] & 0x01) == 0) // V become 0 XferLen = szData[3] & 0xFFF; //12-bits return XferLen; } void PTD_WritePlayload(alt_u32 Addr, alt_u32 szData[], alt_u32 ByteLen){ /* for debug if (ByteLen){ int i; alt_u8 *pData = (alt_u8 *)szData; DEBUG_OUT((" Tx Payload(len=%d):", (int)ByteLen)); for(i=0;i 10) DEBUG_OUT(("\n ")); for(i=0;i> 16)& 0xFFFF), (alt_u16)(PTD[i] & 0xFFFF) )); } } void PTD_SplitIntDump(alt_u32 PTD[8]){ DEBUG_DECODE(("V=%d\n", (int)(PTD[0] & 0x01) )); DEBUG_DECODE(("NrBytesToTransfer=%d\n", (int)((PTD[0] >> 3 ) & 0x7FFF ))); DEBUG_DECODE(("MaxPacketLength=%d\n", (int)(PTD[0] >> 18 ) & 0x7FF )); DEBUG_DECODE(("EndPt=%d\n", (int)(((PTD[0] >> 31 ) & 0x01) + (PTD[1] & 0x07)) )); DEBUG_DECODE(("DeviceAddress=%d\n", (int)((PTD[1] >> 3 ) & 0x7F) )); DEBUG_DECODE(("Token=%d\n", (int)((PTD[1] >> 10 ) & 0x3) )); DEBUG_DECODE(("EPType=%d\n", (int)((PTD[1] >> 12 ) & 0x3) )); DEBUG_DECODE(("S=%d\n", (int)((PTD[1] >> 14 ) & 0x1) )); DEBUG_DECODE(("SE=%d\n", (int)((PTD[1] >> 16 ) & 0x3) )); DEBUG_DECODE(("PortNumber=%d\n", (int)((PTD[1] >> 18 ) & 0x3F) )); DEBUG_DECODE(("HubAddress=%d\n", (int)((PTD[1] >> 25 ) & 0x3F) )); DEBUG_DECODE(("uFrame=%d\n", (int)((PTD[2] >> 0 ) & 0xFF) )); DEBUG_DECODE(("DataStartAddress=%d\n", (int)((PTD[2] >> 8 ) & 0xFFFF) )); DEBUG_DECODE(("reserved=%d (0 is expected)\n", (int)((PTD[2] >> 24 ) & 0xFF) )); DEBUG_DECODE(("NrBytesTransferred=%d\n", (int)((PTD[3] >> 0 ) & 0xFFF) )); DEBUG_DECODE(("reserved=%d (0 is expected)\n", (int)((PTD[3] >> 10 ) & 0x7FF) )); DEBUG_DECODE(("Cerr=%d\n", (int)((PTD[3] >> 23 ) & 0x3) )); DEBUG_DECODE(("DT=%d\n", (int)((PTD[3] >> 25 ) & 0x1) )); DEBUG_DECODE(("SC=%d\n", (int)((PTD[3] >> 27 ) & 0x1) )); DEBUG_DECODE(("X=%d\n", (int)((PTD[3] >> 28 ) & 0x1) )); DEBUG_DECODE(("B=%d\n", (int)((PTD[3] >> 29 ) & 0x1) )); DEBUG_DECODE(("H=%d\n", (int)((PTD[3] >> 30 ) & 0x1) )); DEBUG_DECODE(("A=%d\n", (int)((PTD[3] >> 31 ) & 0x1) )); DEBUG_DECODE(("uSA=%d\n", (int)((PTD[4] >> 0 ) & 0xFF) )); DEBUG_DECODE(("Status0=%d\n", (int)((PTD[4] >> 8 ) & 0x7) )); DEBUG_DECODE(("Status1=%d\n", (int)((PTD[4] >> 11 ) & 0x7) )); DEBUG_DECODE(("Status2=%d\n", (int)((PTD[4] >> 14 ) & 0x7) )); DEBUG_DECODE(("Status3=%d\n", (int)((PTD[4] >> 17 ) & 0x7) )); DEBUG_DECODE(("Status4=%d\n", (int)((PTD[4] >> 20 ) & 0x7) )); DEBUG_DECODE(("Status5=%d\n", (int)((PTD[4] >> 23 ) & 0x7) )); DEBUG_DECODE(("Status6=%d\n", (int)((PTD[4] >> 26 ) & 0x7) )); DEBUG_DECODE(("Status7=%d\n", (int)((PTD[4] >> 29 ) & 0x7) )); DEBUG_DECODE(("uSCS=%d\n", (int)((PTD[5] >> 0 ) & 0xFF) )); // DEBUG_DECODE(("INT_IN_0=%d\n", (int)((PTD[5] >> 8 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_1=%d\n", (int)((PTD[5] >> 16 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_2=%d\n", (int)((PTD[5] >> 24 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_3=%d\n", (int)((PTD[6] >> 0 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_4=%d\n", (int)((PTD[6] >> 8 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_5=%d\n", (int)((PTD[6] >> 16 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_6=%d\n", (int)((PTD[6] >> 24 ) & 0xFF) )); DEBUG_DECODE(("INT_IN_7=%d\n", (int)((PTD[7] >> 0 ) & 0xFF) )); }