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

📄 uh1.c

📁 TDI的USB HOST芯片UHC124的编程手册和固件驱动源代码
💻 C
字号:
/*
	UH1.C: UH124 user interface library Level 1.

(C) Copyright TransDimension, Inc.  All rights reserved.             
                                                                   
Modification history
====================
17Aug2000 Original Release
31Jan2001 Modified, JW
20Mar2001 Modified, JW

*/

#include "types.h"
#include "uhc124.h"
#include "uh0.h"
#include "uh1.h"
#include "err.h"

/*	enter power saving mode */

void UH_PwrSav(void)
{
	UH_Write(UhcControl, CtlPwrSav);
}

/*	soft reset */

void UH_SoftReset(void)
{
	UH_Write(UhcControl, CtlSoftReset);
}

/*	read system operating state */

U8 UH_USBSysState(void)
{
	return(UH_Read(UhcControl) & CtlUSBState);
}

/*	USB system reset */

void UH_USBReset(void)
{
	UH_Write(UhcControl, CtlUSBReset);
}

/*	host initiated resume */

I16 UH_USBResume(void)
{
	U8 c = UH_USBSysState();

	/* invalid unless system in suspend state */
	if (c != CtlUSBSuspend) return(ERR_STATE);

	UH_Write(UhcControl, CtlUSBResume);
	return(ERR_NONE);
}

/*	host initiated suspend */

I16 UH_USBSuspend(void)
{
	U8 c = UH_USBSysState();

	/* invalid unless system in operational state */
	if (c != CtlUSBOperational) return(ERR_STATE);

	UH_Write(UhcControl, CtlUSBSuspend);
	return(ERR_NONE);
}

/*	enter state USBoperational */

I16 UH_USBOperational(void)
{
	U8 c = UH_USBSysState(); 

	/* invalid unless sys in either reset or suspend state */
	if (c != CtlUSBReset && c != CtlUSBSuspend)
		return(ERR_STATE);

	UH_Write(UhcControl, CtlUSBOperational);
	return(ERR_NONE);
}

/*	set maximum overhead register */

void UH_SetMaxOverhead(U8 mo)
{
	UH_Write(UhcMaxOverhead, mo);
}

/*	read maximum overhead register */

U8 UH_MaxOverhead(void)
{
	return(UH_Read(UhcMaxOverhead));
}

/*	read frame number register */

U16 UH_FmNumber(void)
{
	U16 c = UH_Read(UhcFmNumber);
	U16 d = UH_Read(UhcFmNumber+1);

	return(((d << 8) | c) & 0x7ff);
}

/*	read frame remaining register */

U16 UH_FmRemaining(void)
{
	U16 c = UH_Read(UhcFmRemaining);
	U16 d = UH_Read(UhcFmRemaining+1);

	return(((d << 8) | c) & 0x3fff);
}

/*	read frame interval register */

U16 UH_FmInterval(void)
{
	U16 c = UH_Read(UhcFmInterval+1);

	return(((c << 8) | UH_Read(UhcFmInterval)) & 0x3fff);
}

/*	set frame interval register */

void UH_SetFmInterval(U16 intv)
{
	intv &= 0x3fff;

	UH_Write(UhcFmInterval, (U8) (intv & 0xff));
	UH_Write(UhcFmInterval+1, (U8) ((intv >> 8) & 0xff));
}

/*	read magic number register */

U8 UH_MagicNumber(void)
{
	return(UH_Read(UhcMagicNumber));
}

/*	read transaction select register */

U16 UH_TransSel(void)
{
	U16 c = UH_Read(UhcTransSel+1);

	return((U16) ((c << 8) | UH_Read(UhcTransSel)));
}

/*	set transaction select register */

I16 UH_SetTransSel(U16 sel)
{
	U8 c =  UH_Read(UhcControl);

	/* cannot set this register if batch on */
	if (c & CtlBatchOn) return(ERR_BATCH);

	/* write register */
	UH_Write(UhcTransSel, (U8) (sel & 0xff));
	UH_Write(UhcTransSel+1, (U8) ((sel >> 8) & 0xff));

	return(ERR_NONE);
}

/*	read transaction done register */

U16 UH_TransDone(void)
{
	U16 c = UH_Read(UhcTransDone+1);

	return((U16) ((c << 8) | UH_Read(UhcTransDone)));
}

/*	read interrupt enable register */

U8 UH_IntpEnb(void)
{
	return((U8) (UH_Read(UhcIntpEnb) & INTP_MASK));
}

/*	set interrupt enable register */

void UH_SetIntpEnb(U8 mask)
{
	UH_Write(UhcIntpEnb, (U8) (mask & INTP_MASK));
}

/*	interrupt status clear */

void UH_ClrIntpStatus(U8 mask)
{
	UH_Write(UhcIntpStatus, (U8) (mask & INTP_MASK));
}

/*	read interrupt status */

U8 UH_IntpStatus(void)
{
	return((U8) (UH_Read(UhcIntpStatus) & INTP_MASK));
}

/*	prepare XD for a setup xact */

void UH_DispSetup(U8 xd, U8 dev, U8 ep, 
		U16 setup, U8 stop, U8 spd)
{
	U16 b = MXFD_BASE + ((xd &= 0xf) << 4);

	/* XD control word */
	UH_Write(b+XDControl, 
		(U8) (XDCTL_SETUP | 
		((spd) ? XDCTL_LSPD : XDCTL_FSPD) | 
		(stop & XDCtlStop)));

	/* device address and endpoint number */
	UH_Write(b+XDDevAddr, dev);
	UH_Write(b+XDEpNum, ep);

	/* data buf address */
	UH_Write(b+XDBufAddr, (U8)(setup & 0xff));
	UH_Write(b+XDBufAddr+1, (U8)((setup >> 8) & 0xff));

	/* data length */
	UH_Write(b+XDBufLen, SP_SIZE);
	UH_Write(b+XDBufLen+1, 0);
}

/*	prepare an IN or OUT transaction */

void UH_DispData(U8 xd, U8 dev, U8 ep, 
		U16 data, U16 len, U8 ctl, U8 stop, U8 spd)
{
	U16 b = MXFD_BASE + (xd << 4);
	U8 c;
                                                                
	/* control word */
	c = ((ctl & CTL_DIR) ? XDCTL_IN : XDCTL_OUT) | 
			(stop & XDCtlStop);
	if (spd) c |= XDCTL_LSPD;
	if ((ctl & (CTL_DIR | CTL_SEQ | CTL_ISO)) == 
			(CTL_OUT | CTL_DATA1))
		 c |= XDCTL_DATA1;
	if (ctl & CTL_ISO) c |= XDCTL_ISO;
	UH_Write(b+XDControl, c);             
	
	/* device address and endpoint number */
	UH_Write(b + XDDevAddr, dev);
	UH_Write(b + XDEpNum, ep);

	/* data/buffer address */
	UH_Write(b+XDBufAddr, (U8)(data & 0xff));
	UH_Write(b+XDBufAddr+1, (U8)((data >> 8) & 0xff));

	/* data length */
	UH_Write(b+XDBufLen,   (U8)(len & 0xff));
	UH_Write(b+XDBufLen+1, (U8)((len >> 8) & 0xff));
}

/*	read transfer status */

U8 UH_XDStatus(U8 xd)
{
	U16 b = MXFD_BASE + (xd << 4);

	return(UH_Read(b + XDStatus));
}

/*	read XD type */

U8 UH_XDType(U8 xd)
{
	U16 b = MXFD_BASE + (xd << 4);
	return((U8) (UH_Read(b + XDControl) & XDCtlPid));
}

/*	read XD stop */

U8 UH_XDStop(U8 xd)
{
	U16 b = MXFD_BASE + (xd << 4);
	return((U8) (UH_Read(b + XDControl) & XDCtlStop));
}

/*	read buffer address */

U16 UH_XDXferCnt(U8 xd)
{
	U16 b = MXFD_BASE + (xd << 4);
	U16 c = UH_Read(b + XDXferCnt + 1);

	return((U8) (((c << 8) | UH_Read(b+XDXferCnt)) & 0x3ff));
}

/*	read xd buf address */

U16 UH_XDBufAddr(U8 xd)
{
	U16 b = MXFD_BASE + (xd << 4);
	U16 c = UH_Read(b + XDBufAddr + 1);

	return((c << 8) | UH_Read(b+XDBufAddr) & 0x7ff | MDAT_BASE);
}

/*	read xd buffer length */

U16 UH_XDBufLength(U8 xd)
{
	U16 b = MXFD_BASE + (xd << 4);
	U16 c = UH_Read(b + XDBufLen + 1);

	return((c << 8) | UH_Read(b + XDBufLen) & 0x3ff);
}

/*	dispatch a transaction batch */

I16 UH_DispBatch(void)
{
	U8 s = UH_Read(UhcControl);

	/* invalid if another batch is still on */
	if (s & CtlBatchOn) return(ERR_BATCH);

	/* invalid unless sys is in operational state */
	if ((s & CtlUSBState) != CtlUSBOperational) 
		return(ERR_STATE);

	UH_Write(UhcControl, CtlBatchOn);	
	return(ERR_NONE);
}

/*	wait until batch done, modify for RTOS */ 

U16 UH_EndBatch(void)
{
	/* wait until batch done or stopped - tailor to your own system */
	while (!(UH_IntpStatus() & (IntpBatchCompl | 
				IntpBatchStop)));

	/* xd's that are selected but not done */
	return(UH_TransSel() & ~UH_TransDone()); 
}

/*	only used for reading port change */

void UH_SetMagicNumber(U8 mn)
{
	UH_Write(UhcMagicNumber, mn);
}

/*	read port change */

U8 UH_PortChange(void)
{
	UH_MagicNumber();
	UH_SetMagicNumber(MagicKey1);
	UH_SetMagicNumber(MagicKey2);
	return(UH_MagicNumber());
}

/*	magic reset: used for factory test only */

void UH_MagicReset(void)
{   
	UH_Write(0x700, 0x00);
	UH_USBReset();
} 

⌨️ 快捷键说明

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