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

📄 enr.c

📁 TDI的USB HOST芯片UHC124的编程手册和固件驱动源代码
💻 C
字号:
/*
	ENR.C:  Enumeration record related functions. To
	be used with functions of Levels 2-4 in UHC124
	programming interface library.

(C) Copyright TransDimension, Inc.  All rights reserved.             
                                                                   
Modification history
====================
3May2000 Original Release

*/

#include "types.h"
#include "enr.h"
#include "err.h"

#define DEV0		0
#define NULL		0

static ENR enr_tab[ENR_SIZE];
static U8 enr_last;

/*	initilize the ENR table */

void UH_EnrInit(void)
{
	U8 i;

	for (i = 0; i < ENR_SIZE; enr_tab[i++].dev = 0);

	enr_tab[DEV0].mode = ENR_CTL; 
	enr_tab[DEV0].bsize = 8;
	enr_last = 0;
}

/*	remove entries for a device from the enr table */

I16 UH_EnrDelete(U8 dev)
{
	ENR *enr = enr_tab + 1;
	U8 i;
	I16 f = 0;

	if (!dev) return(ERR_DEV0);

	for (i = 1; i <= enr_last; i++, enr++)
		if (enr->dev == dev) { f++; enr->dev = 0; }

	return((f) ? f : ERR_ENRNONE);
}

/*	look for an enumeration record */

ENR *UH_EnrGet(U8 dev, U8 ep, I16 dir)
{
	ENR *enr;
	U8 i;

	if (ep <= 15)
		for (i = 0, enr = enr_tab; i <= enr_last; i++, enr++) {
			if (enr->dev != dev || enr->ep != ep)
				continue;
			if (dir < 0 || log_eq(dir, enr->mode & ENR_DIR))  
				return(enr);
		}
	else
		for (i = 0, enr = enr_tab; i <= enr_last; i++, enr++) {
			if (enr->dev == dev) return(enr);
		}

	return(NULL);
}

/*	look for an available enumeration record slot */

static ENR *UH_EnrAvail(U8 dev, U8 ep, I16 dir)
{
	ENR *enr;
	U8 i;

	/* find a slot above enr_last in enr table */
	for (i = 1, enr = enr_tab+1; i <= enr_last; i++, enr++)
		if (!(enr->dev) || 
				enr->dev == dev && enr->ep == ep &&
				log_eq(enr->mode & ENR_DIR, dir)) 
			return(enr);

	/* if enr table not full, return slot at enr_last */
	if (enr_last == ENR_SIZE - 1) return(NULL);
	return(enr_tab + ++enr_last);
}

/*	set speed for DEV0 */

void UH_EnrDev0(U8 spd)
{
	enr_tab->mode = ENR_CTL;
	if (spd) enr_tab->mode |= ENR_SPD;
}

/*	register an enumeration record */

I16 UH_EnrSet(U8 dev, U8 ep, U8 xfer, I16 dir, U8 spd, U16 bsize)
{
	ENR *enr;
	U8 m, x;
	I16 r;

	if (!dev) return(ERR_DEV0);

	/* prepare for mode */
	m = (x = xfer & ENR_XFER) | ENR_DATA0;
	if (dir) m |= ENR_DIR;
	if (spd) m |= ENR_SPD;

	/* check if endpoint xfer type is valid */
	if (!ep && x != ENR_CTL || spd && 
			x != ENR_CTL && x != ENR_INT)
		return(ERR_INVEP);

	/* check if endpoint buf size is valid */
	if (!bsize || spd && x == ENR_CTL && bsize != 8 ||
			spd && x == ENR_INT && bsize > 8 || 
			!spd && (x == ENR_CTL || x == ENR_BUL) && 
				bsize != 8 && bsize != 16 && 
				bsize != 32 && bsize != 64 || 
			x == ENR_ISO && bsize > 1023) 
		return(ERR_BSIZE);

	/* look for an empty slot in enr table */
	if (!(enr = UH_EnrAvail(dev, ep, dir))) return(ERR_FULL);

	/* if <dev, ep, dir> exists, replace */
	if (enr->dev == dev && enr->ep == ep && 
		log_eq(enr->mode & ENR_DIR, dir))
		r = ERR_UPDATE;
	else {
		enr->dev = dev; enr->ep = ep;
		r = ERR_NONE;
	}

	/* set mode and bsize fields */
	enr->mode = m; enr->bsize = bsize;

	return(r); 
}

/*	sequential access of all enr's */

ENR *UH_EnrAccess(U8 mode)
{
	static U8 i;

	if (!mode) { i = 1; return(enr_tab); }
	
	while (i <= enr_last && !(enr_tab[i].dev)) i++;

	return((i <= enr_last) ? enr_tab+i++ : NULL);
}

/*	find a useable address */

U8 UH_AddrNew(void)
{
	U8 a[128];
	I16 i;
	ENR *enr = UH_EnrAccess(0);

	for (i = 0; i < 128; a[i++] = 0);

	while (enr = UH_EnrAccess(1)) a[enr->dev] = 1;

	enr = UH_EnrAccess(0);

	for (i = 1; i < 128; i++) if (!a[i]) return(i);  
	
	return(0);
}

⌨️ 快捷键说明

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