コード例 #1
0
ファイル: sd.c プロジェクト: Pikrass/pios
// For now, start and len are a number of 512-byte blocks
int sd_read(struct sd_card *card, int start, int len, void *dest) {
	int bl_addr;
	struct dma_cb ctrl __attribute__ ((__aligned__(32)));

	if(card->type == 0)
		start *= 512;

	dmb();
	*BLKSIZECNT = BLKSIZE(512) | BLKCNT(len);

	sd_send_command(CMD_READ_MULTIPLE_BLOCK,
			TM_BLKCNT_EN | TM_AUTO_CMD_12 | TM_DAT_CARD_TO_HOST |
			TM_MULTI_BLOCK | CMD_RSPNS_48 | CMD_ISDATA, start);

	ctrl.ti = DMA_TI_INTEN | DMA_TI_WAIT_RESP |
		DMA_TI_DEST_INC | DMA_TI_DEST_WIDTH |
		DMA_TI_SRC_DREQ | DMA_TI_PERMAP_EMMC;
	ctrl.source_ad = IO_TO_BUS(DATA);
	ctrl.dest_ad = virt_to_phy(dest);
	ctrl.txfr_len = 512 * len;
	ctrl.stride = 0;
	ctrl.nextconbk = 0;

	return dma_initiate(DMA_CHAN_EMMC, &ctrl);
}
コード例 #2
0
ファイル: 1usbctrl.c プロジェクト: acctomhse/sq8000
void process_bulk_out(int ch)
{
	// bulk out the nth block
	UINT rxvalue = readw( UDC_RXSTAT(ChannelSet[ch].uBulk_OUT) );
    
    DEBUG_OUT('R');
    
#if 0
	if ( (rxvalue & RxVOID  ) != 0 )
	if ( (rxvalue & RxERR   ) != 0 )
	if ( (rxvalue & RxURF   ) != 0 )
#endif

	if ( (rxvalue & RxACK   ) != 0 ) {
		// get Bulk Out byte count
		ChannelSet[ch].sBulkBlockSizeBuffer[ChannelSet[ch].uCurrentBulkOutBlockNum] = rxvalue & RxCNT;

		// step next DMA block
		ChannelSet[ch].uCurrentBulkOutBlockNum = ++ChannelSet[ch].uCurrentBulkOutBlockNum % uMaxBlockNumber;
		writew( virt_to_phy((u32_t)(ChannelSet[ch].pBulkOutBuffer + ChannelSet[ch].uCurrentBulkOutBlockNum * uBulkBlockSize)),
				UDC_DMALM_OADDR(ChannelSet[ch].uBulk_OUT) );
		writew( ENP_DMA_START, UDC_DMACTRLO(ChannelSet[ch].uBulk_OUT) );

		// loop back to Bulk Out transfer
		ChannelSet[ch].uLoopbackCount++;
	}
}
コード例 #3
0
ファイル: 1usbctrl.c プロジェクト: acctomhse/sq8000
// tx0 handler
void process_in0()
{
    readw( UDC_TX0STAT ); //added by Ivan Chiang 040805
	if ( uControlStage == DATA_STAGE ) {
		// data stage

        //;//printf("tx0 handler uControlDataSize = %x\n",uControlDataSize); 
		if ( uControlDataSize > 0 )
			uNeedDoProcCtrlBlockNum++;
		else {
			// open OUT gate
			writew( readw( UDC_RX0CON ) & ~RxNAK, UDC_RX0CON );
			writew( virt_to_phy((u32_t)CtrlInBuffer), UDC_DMA0LM_OADDR );
			writew( ENP_DMA_START ,  UDC_DMA0CTLO );
			uControlStage = STATUS_STAGE;
		}

	}
	else if ( uControlStage == STATUS_STAGE ) {
		// status stage, close gates

		writew( readw( UDC_TX0CON ) | TxNAK, UDC_TX0CON );
		writew( readw( UDC_RX0CON ) | RxNAK, UDC_RX0CON );
	}

	//DEBUG_OUT(uControlDataSize);
	return;
}
コード例 #4
0
static s32 dma_FPGAmem2ARMmem_use_acp(void)
{
	s32 ret = ALT_E_SUCCESS;
	/* for DMAC PC, not cache-able */
	ALT_DMA_PROGRAM_t *program = (ALT_DMA_PROGRAM_t *)AMP_SHARE_DMABUF_START;
	//u32 dma_phy = AMPPHY_START + 0x200000; //physical address: 0x1e200000
	u32 src_phy = FPGA_SDRAM_PHYS_BASE;			//source physical address for dma : offset: 0
	u32 dst_phy = (SH_MEM_START + 0x200000);			// destination physical address for dma: offset 0x200000
	//source virtual address for mpu, cache-able, WBWA shareable
	u8 * src_virt	= (u8 *)phy_to_virt(src_phy);
	// desination virtual address for mpu,  cache-able, WBWA shareable
	u8 * dst_virt = (u8 *)phy_to_virt(dst_phy);	
	int i, size = 0x4000;

	gDMAtestIrqInfoChan0.src_mpu = src_virt;
	gDMAtestIrqInfoChan0.dst_mpu = dst_virt;
	gDMAtestIrqInfoChan0.size       = size;

	dma_use_acp_init_fpga(ALT_DMA_CHANNEL_0);

	memset(program, 0x0, sizeof(ALT_DMA_PROGRAM_t));
	ret = alt_dma_channel_alloc(ALT_DMA_CHANNEL_0);
	if(ret != ALT_E_SUCCESS)
	{
		bmlog("ERROR: dma_channel_alloc error!\n");
		return ret;
	}

	/* init the source memory and the destination memory for dma using ACP */
	for(i = 0; i < size; i++)
	{
		src_virt[i] = i + 1;
		dst_virt[i] = 0x0;	
	}

	dma_init_interrupt_channel0();

	/* Init the dma engine's micro code PC */
	program->program_phy = virt_to_phy((u32)(program->program));

	
	ret = alt_dma_memory_to_memory(ALT_DMA_CHANNEL_0,
		                                       program,
		                                       (void *)(dst_phy|(0x1 << 31)),
		                                       (const void *)(src_phy&(~(0x1 << 30))),
		                                       size,
		                                       true,
		                                       ALT_DMA_EVENT_0,
		                                       1);
	if(ret != ALT_E_SUCCESS)
	{
		bmlog("ERROR: dma memory_to_memory acp failed!\n");
		return ret;
	}

	return ret;
	

}
コード例 #5
0
static int dma_ARMmem2FPGAmem(void)
{
	s32 ret = ALT_E_SUCCESS;
	/* for DMAC PC, not cache-able */
	ALT_DMA_PROGRAM_t *program = (ALT_DMA_PROGRAM_t *)AMP_SHARE_DMABUF_START;
	u32 dma_phy = AMPPHY_START + AMPMAP_SIZE - DMABUF_SIZE;
	u32 src_phy = (dma_phy + 0x100000);//offset: 1MB
	u32 dst_phy = FPGA_SDRAM_PHYS_BASE + (FPGA_SDRAM_SIZE/2);
	//non-cacherable, bufferable src
	u8 * src_virt	= (u8 *)phy_to_virt(src_phy);
	//non-cacherable, bufferable dest
	u8 * dst_virt = (u8 *)phy_to_virt(dst_phy);		
	int i, size = 0x4000;

	gDMAtestIrqInfoChan0.src_mpu  = src_virt;
	gDMAtestIrqInfoChan0.dst_mpu	= dst_virt;
	gDMAtestIrqInfoChan0.size		= size;

	memset(program, 0x0, sizeof(ALT_DMA_PROGRAM_t));

	ret = alt_dma_channel_alloc(ALT_DMA_CHANNEL_0);
	if(ret != ALT_E_SUCCESS)
	{
		bmlog("ERROR: dma_channel_alloc error!\n");
		return ret;
	}

	for(i = 0; i < size; i++)
	{
		src_virt[i] = i + 1;
		dst_virt[i] = 0x0;
	}

	dma_init_interrupt_channel0();
	
	program->program_phy = virt_to_phy((u32)(program->program));

	ret = alt_dma_memory_to_memory(ALT_DMA_CHANNEL_0,
		                                       program,
		                                       (void *)dst_phy,
		                                       (const void *)src_phy,
		                                       size,
		                                       true,
		                                       ALT_DMA_EVENT_0,
		                                       0);

	if(ret != ALT_E_SUCCESS)
	{
		bmlog("ERROR: dma memory_to_memory failed!\n");
		return ret;
	}
	
	return ret;

}
コード例 #6
0
static s32 check_dma_memory_result(u8 *src, u8 *dst, int size)
{
	while(size && size--)
	{
		if(*src != *dst)
			break;
		src++;
		dst++;
	}
	
	if(size)
	{
		bmlog("src =0x%p, *src=%u; dst = 0x%p, *dst = %u;size=%d\n", src, *src, dst, *dst, size);
		return ALT_E_ERROR;
	}
	else
		bmlog("DMA test memory(0x%x) to memory(0x%x) is ok!\n", virt_to_phy((u32)src), virt_to_phy((u32)dst));
	
	return ALT_E_SUCCESS;
}
コード例 #7
0
ファイル: 1usbctrl.c プロジェクト: acctomhse/sq8000
u32_t fn_vendor_test_out0()
{

	// ctrl-out via control pipe
	uControlDataSize = ___swab16 ( SetupRequestData.wLength );
	writew( virt_to_phy( (u32_t)CtrlInBuffer ), UDC_DMA0LM_OADDR );
	writew( ENP_DMA_START ,  UDC_DMA0CTLO );

	// deassert RX0NAK --- let host data rush into DMA buffer
	writew( readw( UDC_RX0CON ) & ~RxNAK, UDC_RX0CON
 );

	return 0;
}
コード例 #8
0
ファイル: 1usbctrl.c プロジェクト: acctomhse/sq8000
// rx0 handler
void process_out0()
{
	int len;

	if ( uControlStage == STATUS_STAGE ) {
		// status stage

		// read clear RX0ACK interrupt
		readw( UDC_RX0STAT );

		// assert both TX0NAK, RX0NAK at status stage
		writew( readw( UDC_TX0CON ) | TxNAK, UDC_TX0CON );
		writew( readw( UDC_RX0CON ) | RxNAK, UDC_RX0CON );

	} else if ( uControlStage == DATA_STAGE ) {
		// data stage

		// read length from H/W
		len = readw( UDC_RX0STAT ) & RxCNT;

		// record received result
		uControlDataSize -= len;
		//DEBUG_OUT(uControlDataSize);

		// step next dma block
		uCurrentCtrlBlockNum = ++uCurrentCtrlBlockNum % MAX_CTRL_NUM;
		writew( virt_to_phy((u32_t)( CtrlInBuffer + uCurrentCtrlBlockNum * uCurrentCtrlPacketSize)), UDC_DMA0LM_OADDR );
		writew( ENP_DMA_START ,  UDC_DMA0CTLO );
/*
		if ( uControlDataSize <= 0 ) {
			// open IN gate
			writew( readw( UDC_TX0CON ) & ~TX0NAK, UDC_TX0CON );
			writew( 0, UDC_TX0STAT );
			writew( virt_to_phy((u32_t)CtrlInBuffer) , UDC_DMA0LM_IADDR );
			writew( DMA0INSTA , UDC_DMA0CTLI );
	   		uControlStage = STATUS_STAGE;
		}
*/

	}

	return;
}
コード例 #9
0
ファイル: 1usbctrl.c プロジェクト: acctomhse/sq8000
void process_setup_req()
{
	u32_t* p;

	u32_t request_type;

	UINT	ch;		// channel number
	int i;
//	DEBUG_OUT('s');

	bRequestError   = NO;
	uCurrentCtrlBlockNum    = 0;
	uNeedDoProcCtrlBlockNum = 0;

	uControlStage = SETUP_STAGE;



	if (ResetFlag == 1)
	{
		if ( IS_HIGH_SPEED() ) {
			;//printf(" USB connect with HIGH Speed!\n");
			bIsFullSpeed = 0;
			uBulkBlockSize  = HI_SPEED_BULK_PACKET_SIZE;
			uCurrentCtrlPacketSize  = HI_SPEED_CTRL_PACKET_SIZE;
			uCurrentBulklPacketSize = HI_SPEED_BULK_PACKET_SIZE;
		} else {
			;//printf(" USB connect with FULL Speed!\n");
			bIsFullSpeed = 1;
			uBulkBlockSize  = FULL_SPEED_BULK_PACKET_SIZE;
			uCurrentCtrlPacketSize  = FULL_SPEED_CTRL_PACKET_SIZE;
			uCurrentBulklPacketSize = FULL_SPEED_BULK_PACKET_SIZE;
		}
		uMaxBlockNumber = (BK_BUF_SIZE / uBulkBlockSize);
	
		// change device MaxPacketSize of descriptor
		scusbDscr[7] = uCurrentCtrlPacketSize;		
		ResetFlag = 0;
		for (ch = 0; ch < NUM_OF_USB_CHANNEL; ch++) {
			ChannelSet[ch].uLoopbackCount = 0;
			ChannelSet[ch].uIntrINCount   = 0;

			// start receive from Bulk_OUT pipe
			writew(virt_to_phy( (u32_t)ChannelSet[ch].pBulkOutBuffer), UDC_DMALM_OADDR(ChannelSet[ch].uBulk_OUT));
			writew( ENP_DMA_START, UDC_DMACTRLO(ChannelSet[ch].uBulk_OUT));
		}
		for (i = 0; i < NUM_OF_USB_CHANNEL; i++)
			ChannelSet[i].uCurrentBulkInBlockNum = ChannelSet[i].uCurrentBulkOutBlockNum = ChannelSet[i].uCurrentIntrInBlockNum = 0;		

	}
	// clear previous buffer
	/*
	writew( readw( UDC_TX0CON ) | TxCLR,  UDC_TX0CON );
	writew( readw( UDC_TX0CON ) & ~TxCLR, UDC_TX0CON );
	writew( readw( UDC_RX0CON ) | RxCLR,  UDC_RX0CON );
	writew( readw( UDC_RX0CON ) & ~RxCLR, UDC_RX0CON );
*/
	// read setup data

	p = (u32_t*)&SetupRequestData;
	*p++ = *(volatile u32_t *)UDC_SETUP1;
	*p   = *(volatile u32_t *)UDC_SETUP2;

	// identify standard request
	request_type = GET_REQ_TYPE(SetupRequestData.bmRequestType);
	if (request_type == REQ_TYPE_STANDARD) {
		if (SetupRequestData.bRequest == GET_DESCRIPTOR ) {
			fn_get_descriptor();
		}
	} else if (request_type == REQ_TYPE_CLASS ) {
		if (SetupRequestData.bRequest == GET_DEVICE_ID) {
			;//printf("process_setup_req() - get device id!\n");
			fn_get_device_id();
		}
	} else if (request_type == REQ_TYPE_VENDOR ) {
		if (SetupRequestData.bRequest == VENDOR_TEST_OUT0 ) {
			;//printf("process_setup_req() - vendor test out!\n");
			fn_vendor_test_out0();
		} else if ( SetupRequestData.bRequest == VENDOR_TEST_IN0 ) {
			;//printf("process_setup_req() - vendor test in!\n");
			fn_vendor_test_in0();
		}
	}

	uControlStage = DATA_STAGE ;
}
コード例 #10
0
ファイル: 1usbctrl.c プロジェクト: acctomhse/sq8000
int USBTesting()
{
	UINT	ch;		// channel number
	UINT	TX_Status;
	CHAR	*dma_src_addr;
	char	Continue_test = 1;
	
//cyli++ 01/17/07
	if (IS_16_ENDPT()) {
		printf("16 end-points\n");
	} else if (IS_10_ENDPT()) {
		printf("10 end-points\n");
	} else if (IS_4_ENDPT()) {
		printf("4 end-points\n");
	} else {
		printf("Error end-point number!\n");
		printf("DEV_INFO = 0x%08x", readw(UDC_DEVINFO) & ENDPT_NUM_MASK);
	}

// CY+ to fix program reload Socle phy hang up problem
#ifdef	UDC_SOCLE_PHY
		ASSERT_SOFT_POR();
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 1;
		setup_1ms_timer(1);
#else
		MSDELAY(1);
#endif

		while (isr_time_value != isr_waiting_time);

		DEASSERT_SOFT_POR();
#endif

#ifdef	UDC_SOCLE_PHY
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 8;
		setup_1ms_timer(8);
#else
		MSDELAY(8);
#endif

		while (isr_time_value != isr_waiting_time);

//		SET_PHY_16_BIT();
#endif

	ResetFlag = 0;
	bIsConnected = VBUS_OK();
//	if (bIsConnected)
//		printf(" -> USB VBus connect\n");
//	else
//		printf(" -> USB VBus disconnect");

	// enable interrupt
	INT0_ENABLE(LDK_INTC_UDC);

	// setup interrupt handler
	connectInterrupt( LDK_INTC_UDC, UDCIintHandler, NULL);

	INT0_SET_MASK(LDK_INTC_UDC);

	while (1) {
//		;printf("\n USB cable disconnected!\n");

		SOFT_DISCONNECT();

		// wait for plugin stable on vbus
//		printf("\nWait for USB Host connect...");
//		while ( !bIsConnected );
//CY++ for checking USB Host connect waiting
		int wait=0;
		while ( !bIsConnected ){
          		MSDELAY(60);
			printf("%4d", wait);			
          		wait++;
          		if(wait > 100)
             			return USB_NO_CONNECT_ERROR;
			printf("\b\b\b\b");
        	}

#ifdef	UDC_SOCLE_PHY
		ASSERT_SOFT_POR();
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 1;
		setup_1ms_timer(1);
#else
		MSDELAY(1);
#endif

		while (isr_time_value != isr_waiting_time);

		DEASSERT_SOFT_POR();
#endif

#ifdef	UDC_SOCLE_PHY
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 8;
		setup_1ms_timer(8);
#else
		MSDELAY(8);
#endif

		while (isr_time_value != isr_waiting_time);

//		SET_PHY_16_BIT();
#endif
		initUDCController();	// initialize UDC Controller
		initUDCTestingEnv();	// initialize UDC testing environment
		SOFT_CONNECT();
		;//printf("\n USB cable connected!\n");
		uNeedDoProcCtrlBlockNum = 0;
		while ( bIsConnected ) {
			// check ENP 0 transmit request
			if ( uNeedDoProcCtrlBlockNum > 0 ) {
				int		dma_size;
				
				// dma done now, polling for empty data set
				if (!( readw(UDC_TX0BUF) & TxFULL)) {

					// critical section
					DisableInterrupt();
					uNeedDoProcCtrlBlockNum--;
					dma_src_addr = CtrlInBuffer + uCurrentCtrlBlockNum++ * uCurrentCtrlPacketSize;

					if ( uControlDataSize > uCurrentCtrlPacketSize ) {
						dma_size = uCurrentCtrlPacketSize;
					}
					else {
						dma_size = uControlDataSize;
					}

					// calculate remaining bytes need transfer
					uControlDataSize -= dma_size;

					writew( dma_size, UDC_TX0STAT );
					writew( virt_to_phy((u32_t)dma_src_addr) , UDC_DMA0LM_IADDR );
					writew( ENP_DMA_START , UDC_DMA0CTLI );
					EnableInterrupt();
					
					// set ACK--after we have overwritten the previously incorrect data
					writew( readw( UDC_TX0CON ) & ~TxNAK, UDC_TX0CON );
				
					
				}
			}
		    if (Continue_test){
				printf("Done\n");
		            	printf("USB initialize...Done\n");
		            	printf("HandShaking...Done\n");
				printf("Waiting for Bulk Read/Write test...\n");
				printf("Remove Socle USB Bulk device Hardware from Windows and USB cable to Exit !!!\n");
				Continue_test = 0;
	    		}
			// check channel group transmit request
			for (ch = 0; ch < NUM_OF_USB_CHANNEL; ch++) {

				// check each Bulk_IN End Point transmit request
				if ( ChannelSet[ch].uLoopbackCount > 0 ) {
					if (ChannelSet[ch].bBulkDMAOnGoing == false) {

						// check buffer is available for transmit data
						TX_Status = readw(UDC_TXBUF(ChannelSet[ch].uBulk_IN));	// get buffer status

						if ((TX_Status & TxFULL) == 0) {
#if 0
							if ((TX_Status & TxDS0) == 0)
								DEBUG_OUT('0');
							if ((TX_Status & TxDS1) == 0)
								DEBUG_OUT('1');
#endif

							//DEBUG_OUT('i');

							// enter critical section, protect share variable
							DisableInterrupt();

							//DEBUG_OUT('+');

							ChannelSet[ch].uLoopbackCount--;
							// get transmit buffer address & move buffer to next position
							dma_src_addr = ChannelSet[ch].pBulkInBuffer + ChannelSet[ch].uCurrentBulkInBlockNum * uBulkBlockSize;

							// setup DMA
							writew( ChannelSet[ch].sBulkBlockSizeBuffer[ChannelSet[ch].uCurrentBulkInBlockNum],
									UDC_TXSTAT(ChannelSet[ch].uBulk_IN) );	// write transmit count
							writew( virt_to_phy((u32_t)dma_src_addr),	// set transmit buffer pointer
									UDC_DMALM_IADDR(ChannelSet[ch].uBulk_IN) );
							writew( ENP_DMA_START , UDC_DMACTRLI(ChannelSet[ch].uBulk_IN) );			// start transmit DMA

							// move to next buffer
							ChannelSet[ch].uCurrentBulkInBlockNum = ++ChannelSet[ch].uCurrentBulkInBlockNum % uMaxBlockNumber;

#if 0
							WAIT_DMA_DONE(UDC_TXSTAT(ChannelSet[ch].uBulk_IN));
#endif
#if 0
							for (delay = 0; delay < 1000; delay++) {
								TX2_DMAOnGoing = true;
							}
#endif

							ChannelSet[ch].bBulkDMAOnGoing = true;

							//DEBUG_OUT('-');

							EnableInterrupt();

							// leave critical section
						}
					}
				}

				// check each Intr_IN End Point transmit request
				if ( ChannelSet[ch].uIntrINCount > 0 ) {
//					if (!( readw(UDC_TXBUF(ChannelSet[ch].uIntr_IN)) & TxFULL)) {
					if (ChannelSet[ch].bIntrDMAOnGoing == false) {

						// critical section
						DisableInterrupt();
						ChannelSet[ch].uCurrentIntrInBlockNum--;
						dma_src_addr = ChannelSet[ch].pIntrInBuffer + ChannelSet[ch].uCurrentIntrInBlockNum * INTR_BLOCK_SIZE;
						EnableInterrupt();

						writew( INTR_BLOCK_SIZE, UDC_TXSTAT(ChannelSet[ch].uIntr_IN) );
						writew( virt_to_phy((u32_t)dma_src_addr), UDC_DMALM_IADDR(ChannelSet[ch].uIntr_IN) );
						writew( ENP_DMA_START, UDC_DMACTRLI(ChannelSet[ch].uIntr_IN) );

						ChannelSet[ch].bIntrDMAOnGoing = true;
#if 0
						WAIT_DMA_DONE(UDC_DMACTRLI(ChannelSet[ch].uIntr_IN) );
#endif
						ChannelSet[ch].uCurrentBulkInBlockNum = ++ChannelSet[ch].uCurrentBulkInBlockNum % MAX_INTR_NUM;
					}
				}
			}
		}
 		// CY+ for disconnect detect and exit testing program	
		printf ("USB Host disconnected !!!\n");
		printf ("Press Y to continue and any other Key to exit? ");
		char	i;	
		i=getchar();
		if((i!='Y')&&(i!='y'))
		{
			printf ("\n");		
			return UPF_TEST_SUCCESS;
		}
		else
			Continue_test = 1;
	}

	// leave usb test now, should never been here
	return USB_UNKONW_ERROR;
}
コード例 #11
0
ファイル: 3usbctrl.c プロジェクト: acctomhse/sq8000
int USBTesting()
{
	UINT	ch;		// channel number
	UINT	TX_Status;
	CHAR	*dma_src_addr;
#ifdef	UDC_SOCLE_PHY
		ASSERT_SOFT_POR();
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 1;
		setup_1ms_timer(1);
#else
		MSDELAY(1);
#endif

		while (isr_time_value != isr_waiting_time);

		DEASSERT_SOFT_POR();
#endif

#ifdef	UDC_SOCLE_PHY
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 8;
		setup_1ms_timer(8);
#else
		MSDELAY(8);
#endif

		while (isr_time_value != isr_waiting_time);

//		SET_PHY_16_BIT();
#endif

	ResetFlag = 0;
	bIsConnected = VBUS_OK();
//	if (bIsConnected)
//		printf(" -> USB VBus connect\n");
//	else
//		printf(" -> USB VBus disconnect");

	// enable interrupt
	INT0_ENABLE(LDK_INTC_UDC);

	// setup interrupt handler
	connectInterrupt( LDK_INTC_UDC, UDCIintHandler, NULL);

	INT0_SET_MASK(LDK_INTC_UDC);

	while (1) {
//		;printf("\n USB cable disconnected!\n");

		SOFT_DISCONNECT();

		// wait for plugin stable on vbus
		printf("\nWait for USB Host connect...");
//		while ( !bIsConnected );
//CY++ for checking USB Host connect waiting
		int wait=0;
		while ( !bIsConnected ){
          		MSDELAY(60);
			printf("%4d", wait);			
          		wait++;
          		if(wait > 100)
             			return USB_NO_CONNECT_ERROR;
			printf("\b\b\b\b");
        	}

#ifdef	UDC_SOCLE_PHY
		ASSERT_SOFT_POR();
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 1;
		setup_1ms_timer(1);
#else
		MSDELAY(1);
#endif

		while (isr_time_value != isr_waiting_time);

		DEASSERT_SOFT_POR();
#endif

#ifdef	UDC_SOCLE_PHY
#if 0
		isr_time_value   = 0;
		isr_waiting_time = 8;
		setup_1ms_timer(8);
#else
		MSDELAY(8);
#endif

		while (isr_time_value != isr_waiting_time);

//		SET_PHY_16_BIT();
#endif
		initUDCController();	// initialize UDC Controller
		initUDCTestingEnv();	// initialize UDC testing environment

		SOFT_CONNECT();

		;//printf("\n USB cable connected!\n");

		uNeedDoProcCtrlBlockNum = 0;
		for (ch = 0; ch < NUM_OF_USB_CHANNEL; ch++) {
			ChannelSet[ch].uLoopbackCount = 0;
			ChannelSet[ch].uIntrINCount   = 0;

			// start receive from Bulk_OUT pipe
			writew(virt_to_phy( (u32_t)ChannelSet[ch].pBulkOutBuffer), UDC_DMALM_OADDR(ChannelSet[ch].uBulk_OUT));
			writew( ENP_DMA_START, UDC_DMACTRLO(ChannelSet[ch].uBulk_OUT));
		}

		while ( bIsConnected ) {
			// check ENP 0 transmit request
			if ( uNeedDoProcCtrlBlockNum > 0 ) {
				int		dma_size;
				
				// dma done now, polling for empty data set
				if (!( readw(UDC_TX0BUF) & TxFULL)) {

					// critical section
					DisableInterrupt();
					uNeedDoProcCtrlBlockNum--;
					dma_src_addr = CtrlInBuffer + uCurrentCtrlBlockNum++ * uCurrentCtrlPacketSize;

					if ( uControlDataSize > uCurrentCtrlPacketSize ) {
						dma_size = uCurrentCtrlPacketSize;
					}
					else {
						dma_size = uControlDataSize;
					}

					// calculate remaining bytes need transfer
					uControlDataSize -= dma_size;

					writew( dma_size, UDC_TX0STAT );
					writew( virt_to_phy((u32_t)dma_src_addr) , UDC_DMA0LM_IADDR );
					writew( ENP_DMA_START , UDC_DMA0CTLI );
					
					EnableInterrupt();
					
					// set ACK--after we have overwritten the previously incorrect data
					writew( readw( UDC_TX0CON ) & ~TxNAK, UDC_TX0CON );					
				
					
				}
			}

			// check channel group transmit request
			for (ch = 0; ch < NUM_OF_USB_CHANNEL; ch++) {

				// check each Bulk_IN End Point transmit request
				if ( ChannelSet[ch].uLoopbackCount > 0 ) {
					if (ChannelSet[ch].bBulkDMAOnGoing == false) {

						// check buffer is available for transmit data
						TX_Status = readw(UDC_TXBUF(ChannelSet[ch].uBulk_IN));	// get buffer status

						if ((TX_Status & TxFULL) == 0) {
#if 0
							if ((TX_Status & TxDS0) == 0)
								DEBUG_OUT('0');
							if ((TX_Status & TxDS1) == 0)
								DEBUG_OUT('1');
#endif

							//DEBUG_OUT('i');

							// enter critical section, protect share variable
							DisableInterrupt();

							//DEBUG_OUT('+');

							ChannelSet[ch].uLoopbackCount--;
							// get transmit buffer address & move buffer to next position
							dma_src_addr = ChannelSet[ch].pBulkInBuffer + ChannelSet[ch].uCurrentBulkInBlockNum * uBulkBlockSize;

							// setup DMA
							writew( ChannelSet[ch].sBulkBlockSizeBuffer[ChannelSet[ch].uCurrentBulkInBlockNum],
									UDC_TXSTAT(ChannelSet[ch].uBulk_IN) );	// write transmit count
							writew( virt_to_phy((u32_t)dma_src_addr),	// set transmit buffer pointer
									UDC_DMALM_IADDR(ChannelSet[ch].uBulk_IN) );
							writew( ENP_DMA_START , UDC_DMACTRLI(ChannelSet[ch].uBulk_IN) );			// start transmit DMA

							// move to next buffer
							ChannelSet[ch].uCurrentBulkInBlockNum = ++ChannelSet[ch].uCurrentBulkInBlockNum % uMaxBlockNumber;

#if 0
							WAIT_DMA_DONE(UDC_TXSTAT(ChannelSet[ch].uBulk_IN));
#endif
#if 0
							for (delay = 0; delay < 1000; delay++) {
								TX2_DMAOnGoing = true;
							}
#endif

							ChannelSet[ch].bBulkDMAOnGoing = true;

							//DEBUG_OUT('-');

							EnableInterrupt();

							// leave critical section
						}
					}
				}

				// check each Intr_IN End Point transmit request
				if ( ChannelSet[ch].uIntrINCount > 0 ) {
//					if (!( readw(UDC_TXBUF(ChannelSet[ch].uIntr_IN)) & TxFULL)) {
					if (ChannelSet[ch].bIntrDMAOnGoing == false) {

						// critical section
						DisableInterrupt();
						ChannelSet[ch].uCurrentIntrInBlockNum--;
						dma_src_addr = ChannelSet[ch].pIntrInBuffer + ChannelSet[ch].uCurrentIntrInBlockNum * INTR_BLOCK_SIZE;
						EnableInterrupt();

						writew( INTR_BLOCK_SIZE, UDC_TXSTAT(ChannelSet[ch].uIntr_IN) );
						writew( virt_to_phy((u32_t)dma_src_addr), UDC_DMALM_IADDR(ChannelSet[ch].uIntr_IN) );
						writew( ENP_DMA_START, UDC_DMACTRLI(ChannelSet[ch].uIntr_IN) );

						ChannelSet[ch].bIntrDMAOnGoing = true;
#if 0
						WAIT_DMA_DONE(UDC_DMACTRLI(ChannelSet[ch].uIntr_IN) );
#endif
						ChannelSet[ch].uCurrentBulkInBlockNum = ++ChannelSet[ch].uCurrentBulkInBlockNum % MAX_INTR_NUM;
					}
				}
			}
		}
	}

	// leave usb test now, should never been here
	return 0;
}