📄 enr.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 + -