⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 devio.c

📁 USB2.0 HOST 芯片驱动源代码
💻 C
字号:
/* Copyright 1997-2002, ESS Technology, Inc. */
/* SCCSID @(#)devio.c	1.1 09/30/04 */
/********************************************************************

	Copyright (C) 2003 UBiSYS Technology Limited.
	All rights reserved.

    author    : dahlsse
    created   : 2004-08-16
    filename  : DevIO.c
    purpose   : Device Interface Layer for UBi9021
    target mcu: ES 6218S
    notes     :
	history   :

*********************************************************************/
#ifdef UBI9021
#include "common.h"
#include "mvd.h"
#include "util.h"
#include "ioport.h"
#include "debug.h"

#include	"ubicmn.h"
#include	"ubi9021_.h"
#include	"DevIO.h"

//#define GL812_base_ptr  0x14000000

extern volatile unsigned char* GL812_base_ptr;

#ifdef REC_FMM
#define GL812_CS       ((volatile unsigned char*)GL812_base_ptr+0x604)
#define GL812_ALE_down ((volatile unsigned char*)GL812_base_ptr+0x600)
#define GL812_deselect  ((volatile unsigned char*)GL812_base_ptr+0x606)
#define GL812_data_port  ((volatile unsigned char*)GL812_base_ptr+0x200)
#elif defined(BD_VIPER)
#define GL812_CS       ((volatile unsigned char*)GL812_base_ptr+0x1c)
#define GL812_ALE_down ((volatile unsigned char*)GL812_base_ptr+0x18)
#define GL812_deselect  ((volatile unsigned char*)GL812_base_ptr+0x1e)
#define GL812_data_port  ((volatile unsigned char*)GL812_base_ptr+0x10)
#else
#define GL812_CS       ((volatile unsigned char*)GL812_base_ptr+0xc)
#define GL812_ALE_down ((volatile unsigned char*)GL812_base_ptr+0x8)
#define GL812_deselect  ((volatile unsigned char*)GL812_base_ptr+0xe)
#define GL812_data_port  ((volatile unsigned char*)GL812_base_ptr+0x0)
#endif

//-------------------------------------------------------------------------------
//  gloable variables
//-------------------------------------------------------------------------------


U8	gBUF[512];		//sector buffer (available for other jobs, if not accessing USB)
					//..must be aligned to DWORD(?)
U8*	pBUF;			//pointer to gBUF

U32	gWaitPktTicks = UMO_WAIT_USB_PKT_TICKS;	//timeout value for usb packet waiting
U8	gInitState    = IS_NO_INIT;


//-------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------



void DEV_WriteReg(U8 addr, U8 data)
{

    *GL812_ALE_down= 0xff;
    *GL812_data_port= addr;
    RISC_sleep_cycles(25);
    //*GL812_deselect=0xff;
    *GL812_CS= 0xff;
    *GL812_data_port= data;
    RISC_sleep_cycles(25);
    *GL812_deselect=0xff;

}


U8 DEV_ReadReg(U8 addr)
{
    register U8 data;

    *GL812_ALE_down= 0xff;
    *GL812_data_port= addr;
    RISC_sleep_cycles(20);
    //*GL812_deselect=0xff;
    *GL812_CS= 0xff;
    data =*GL812_data_port;
    RISC_sleep_cycles(20);
    *GL812_deselect=0xff;
    return data;
}

void DEV_WriteRegMulti(U8 addr, U16 cnt, U8* buf)
{
    unsigned short i;
    unsigned char *dptr;
    dptr = buf;

    *GL812_ALE_down= 0xff;
    *GL812_data_port= addr;
    RISC_sleep_cycles(25);
    //*GL812_deselect=0xff;
    *GL812_CS= 0xff;
    for(i=0x0;i<cnt;i++) {
        *GL812_data_port= *dptr++;
        RISC_sleep_cycles(25);
    }
    *GL812_deselect=0xff;
}

U8 DEV_ReadRegMulti(U8 addr, U16 cnt, U8* buf)
{
    unsigned short i;
    register U8 data;

    *GL812_ALE_down= 0xff;
    *GL812_data_port= addr;
    RISC_sleep_cycles(20);
    //*GL812_deselect=0xff;
    *GL812_CS= 0xff;
    if(buf!=TxNULL){
        for(i=0x0;i<cnt;i++) {
            *buf++ =*GL812_data_port;
            RISC_sleep_cycles(20);
        }
    }
    else{
        for(i=0x0;i<cnt;i++) {
            data =*GL812_data_port;
            RISC_sleep_cycles(20);
        }
    }
    *GL812_deselect= 0xff;
    return data;
}

//_____________________________________________________________________________
//
//	UBi9021 Register Read / Write Test Routine
//
//   * When you confirm register read and write,     *
//   * you must plug-in the usb mass storage device. *
//   * Because when usb device is not connected,     *
//   * UBi9021 registers are not working.            *
//_____________________________________________________________________________
//

#if defined(DEV_IO_TEST)


R8	DEV_TEST_Exit(void)
{
	U8 volatile i=1;
	while(i);
	return RES_ERR;
}



/******************************************************************************
 *
 *	DSESCRIPION:
 *		write to an UBi9021 register..
 *		and compare with read value
 *
 *	INPUT:
 *		- reg: register address
 *		- iterCnt: interation count
 *
 *	RETURN:
 *		RES_OK:
 *		RES_ERR:
 *
 ******************************************************************************/

R8	DEV_TEST_1_RegRW(U8 reg, U16 iterCnt)
{
	U16 i;

	if(iterCnt==0)iterCnt=1;
	else if(iterCnt>256)iterCnt=256;

	for(i=0;i<iterCnt;i++){
		DEV_WriteReg(reg,i);
		if(DEV_ReadReg(reg)!=i){
			return RES_ERR;
		}
	}

	return RES_OK;
}


/******************************************************************************
 *
 *	DSESCRIPION:
 *		UBi9021 SOF interrupt test
 *
 *	RETURN:
 *		RES_OK:
 *		RES_ERR: timeout
 *
 ******************************************************************************/

R8	DEV_TEST_2_SOF_n_Interrupt(void)
{
	U16 ticks;

	DEV_WriteReg(RH_CHIP_CTR2,0x20);	//reset
	DEV_WriteReg(RD_CHIP_CTR,0x40);		//host mode
	DEV_WriteReg(RH_CHIP_CTR2,0x10);	//enable SOF
	DEV_WriteReg(RH_INT_EN,UH_IRQ_SOF);	//enable SOF interrupt

	for(ticks=0;ticks<30000;ticks++)
	{
		if(UBi9021_IRQ_PENDING())
		{
			U8 irqSts = DEV_ReadReg(RH_INT_STS);
			if(irqSts&UH_IRQ_SOF) return RES_OK;
		}
	}

	return RES_ERR;
}



/******************************************************************************
 *
 *	DSESCRIPION:
 *		write "rwSize" bytes to UBi9021 FIFO
 *		and read ,, then compare both values
 *
 *	INPUT:
 *		- mode		: 1=using multiple-read-write,
 *					  0=using singe-read-write
 *		- iterCnt	: interation count (1~256)
 *		- rwSize	: read-write byte size (1~512)
 *
 *	RETURN:
 *		RES_OK:
 *		RES_ERR:
 *
 ******************************************************************************/

R8	DEV_TEST_3_FifoRW(U8 mode, U16 iterCnt, U16 rwSize)
{
	U16 i,j;

	if(iterCnt==0)iterCnt=1;
	else if(iterCnt>256)iterCnt=256;

	if(rwSize==0)rwSize=1;
	else if(rwSize>512)rwSize=512;

	for (i=0; i<iterCnt; i++)
	{
		//FIFO write
		//
		for(j=0;j<rwSize;j++)gBUF[j]=j+i;
		DEV_WriteReg(0x06,0x08);//fifo pointer: 0, fifo direction : out

		if(mode==1){//using Multiple-Read-Write Routine
			DEV_WriteRegMulti(0x0B,rwSize,gBUF);
		}
		else{//using Single-Read-Write Routine
			for(j=0;j<rwSize;j++) DEV_WriteReg(0x0B,j+i);
		}

		//FIFO read
		//
		for(j=0;j<10;j++)NOOP();//idle
		DEV_WriteReg(0x06,0x09);//fifo pointer: 0, fifo direction : in

		if(mode==1){//using Multiple-Read-Write Routine
			DEV_ReadRegMulti(0x0B,rwSize,gBUF);
		}
		else{//using Single-Read-Write Routine
			for(j=0;j<rwSize;j++) gBUF[j]=DEV_ReadReg(0x0B);
		}

		//compare
		//
		for(j=0;j<rwSize;j++){
			if(gBUF[j]!=(U8)(j+i)){
				return RES_ERR;
			}
		}
	}

	return RES_OK;
}


/******************************************************************************
 *	get "gWaitPktTicks"(interation count between specified SOF interrupt)
 *
 *	RETURN:
 *		- 0
 *		- Wait ticks value
 *
 ******************************************************************************/
XD U8 usbIrq, pktSts;

U32	DEV_TEST_4_GetWaitPacketTicks(U16 sofCount)
{
	volatile U16 sofCnt;
	volatile U32 ticks;
	
	if(!UH_DEV_IS_PLUGGEDIN()) return 0;	
	DEV_WriteReg(RH_CHIP_CTR2,0x20);	//reset
	DEV_WriteReg(RD_CHIP_CTR,0x40);		//host mode
	DEV_WriteReg(RH_CHIP_CTR2,0x10);	//enable SOF
	DEV_WriteReg(RH_INT_EN,UH_IRQ_SOF);
	
	while(!UBi9021_IRQ_PENDING());
		
	for(usbIrq=0,ticks=0,sofCnt=0; ticks<0x70000000; ticks++)
	{			
		/*
		 *	Intentionally made similar to "DEV_WaitTicks" 
		 *	so that delay effects can be same as far as possible.
		 */
		 
		if(UBi9021_IRQ_PENDING()){						
			GET_UBi9021_IRQ_STS(usbIrq);	
		}						
	
		if(usbIrq&UH_IRQ_SOF){
			if(++sofCnt>=(U16)sofCount){
				DEV_WriteReg(RH_INT_EN,0);
				return ticks;
			}
		}
		
		//pktSts = DEV_ReadReg(RH_LAST_PKT_STS);		
		//if(pktSts&UH_LST_PKT_STS_NAK) pktSts=0;	
		usbIrq = 0;
		if(ISERR(DEV_CheckDeviceConnection())) break;	
		
		UBi9021_SLEEP_BETWEEN_IRQ_CHECK();	//if any, maximum 100usec (?)
	}
		
	return 0;
}


#if 0
void main(void)
{
	U8 res;

	#if defined(CASPO64)
		output(XMCRA,(XMCRA|0x4c));
		output(XMCRB,(XMCRB&0));
		output(MCUCR,(MCUCR|0x80));
	#else
		ERROR: need initialization for 9021 interfacing!!		
	#endif
	 
	 	
	res = DEV_TEST_1_RegRW(0x0C,256);//RH_FIFO_SZ_LO
	if(ISERR(res))DEV_TEST_Exit();

	
	res = DEV_TEST_2_SOF_n_Interrupt();
	if(ISERR(res))DEV_TEST_Exit();

	
	res = DEV_TEST_3_FifoRW(1,256,512);
	if(ISERR(res))DEV_TEST_Exit();

	//
	// get initial value for "gWaitPktTicks"
	// set macro UMO_WAIT_USB_PKT_TICKS in "DevIO.h" as this value.
	//
	gWaitPktTicks = DEV_TEST_4_GetWaitPacketTicks(200);
	
	while(1);
}
#endif//1

#endif//DEV_IO_TEST


#if 0
U32	DEV_TEST_4_GetWaitPacketTicks(U16 sofCount)
{
	volatile U16 usbIrq, pktSts;
	volatile U16 sofCnt;
	volatile U32 ticks;
	usbIrq  = 0;

	if(!UH_DEV_IS_PLUGGEDIN()) return 0;

	DEV_WriteReg(RH_CHIP_CTR2,0x20);	//reset
	DEV_WriteReg(RD_CHIP_CTR,0x40);		//host mode
	DEV_WriteReg(RH_CHIP_CTR2,0x10);	//enable SOF
	DEV_WriteReg(RH_INT_EN,UH_IRQ_SOF);

	for(ticks=0,sofCnt=0; ticks<0x10000000; ticks++)
	{
		/*
		 *	Intentionally made similar to "DEV_WaitTicks"
		 *	so that delay effects is similar.
		 */

		if(UBi9021_IRQ_PENDING())
		{
			GET_UBi9021_IRQ_STS(usbIrq);

			pktSts = DEV_ReadReg(RH_LAST_PKT_STS);

			if(usbIrq&UH_IRQ_SOF){
				if(sofCnt++>=sofCount){
					DEV_WriteReg(RH_INT_EN,0);
					return ticks;
				}
			}

			if(pktSts&UH_LST_PKT_STS_NAK){
				pktSts = 0;
			}
			else if(pktSts&UH_LST_PKT_STS_STALL){
				pktSts = 0;
			}
			else if(pktSts==UH_LST_PKT_STS_ACK){
				pktSts = 0;
			}
			usbIrq = 0;
		}

		RISC_sleep_nsec(WFIRQ_SLEEP_TIME); 
	}
	return 0;
}
#endif

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -