0
点赞
收藏
分享

微信扫一扫

NET2272.C代码分析 BindPhysicalEndpoints(ENDPOINT_OBJECT *pLogicalEp)

/***************************************************************************
* Physical Endpoint structure. USB core operates at logical endpoint level.
* once host selects a configuration and an interface the associated logical endpoint objects
* of the currently active interface will be binded with the physical endpoint objects.
* The bind holds good until host again sets or resets the configuration and interface
*/
typedef struct PhysicalEndpointObject
{
ENDPOINT_OBJECT *pLogicalEndpointObj; /* logical endpoint object */
int eEndpointStat; /* endpoint state */
int PhysicalEndpointID; /* Physical endpoint ID */
}PHYSICAL_ENDPOINT_OBJECT;



/* Endpoint Descriptor -Size 7 bytes - 6 fields */
typedef struct EndPointDescriptor
{
u8_t bLength; /* Descriptor size in bytes */
u8_t bDescriptorType; /* Descriptor type ENDPOINT 05h */
u8_t bEndpointAddress; /* Endpoint Address */
u8_t bAttributes; /* Transfer type supported */
u16_t wMaxPacketSize; /* Maximum packet size supported */
u8_t bInternal; /* Maximum latency/polling/NACK rate */
}ENDPOINT_DESCRIPTOR, *PENDPOINT_DESCRIPTOR;


/* Endpoint Object */
typedef struct EndpointObject
{
ENDPOINT_DESCRIPTOR *pEndpointDesc; /*Endpoint Descriptor */
ENDPOINT_SPECIFIC_OBJECT *pEndpointSpecificObj; /* EP-Specific Config Obj */
struct EndponitObject *pNext; /* Next Endpoint object */
/* pNextActiveEp is used by the peripheral driver to get the currently active endpoint list */
struct EndponitObject *pNextActiveEpObj; /* Pointers to the next peer endpoint object */
int ID; /* Endpoint ID */
USB_EP_INFO EPInfo;
}ENDPOINT_OBJECT, *PENDPOINT_OBJECT;



/* Endpoint Specific Configuration Object */
typedef struct EndpointSpecificObject
{
int length; /* total length of ep specific config */
void *pEpSpecificData; /* Endpoint specific data */
struct EndpointSpecificObject *pNext; /* Next object */
}ENDPOINT_SPECIFIC_OBJECT, *PENDPOINT_SPECIFIC_OBJECT;


typedef enum { /* Data direction */
ADI_DEV_DIRECTION_UNDEFINED, /* undefined */
ADI_DEV_DIRECTION_INBOUND, /* inbound (read) */
ADI_DEV_DIRECTION_OUTBOUND, /* outbound (write) */
ADI_DEV_DIRECTION_BIDIRECTIONAL,/* both (read and write) */
} ADI_DEV_DIRECTION;

typedef enum DeviceState
{
DEV_STATE_RESET=0,
DEV_STATE_OPEN_IN_PROCESS,
DEV_STATE_OPENED,
DEV_STATE_CLOSED,
DEV_STATE_STARTED,
}DEVICE_STATE;

typedef enum { // Stream IDs for memory DMA
ADI_DMA_MDMA_0, // memory DMA stream 0
ADI_DMA_MDMA_1, // memory DMA stream 1

ADI_DMA_MEMORY_STREAM_COUNT, // number of memory DMA streams
} ADI_DMA_STREAM_ID;

/* USB bus speeds */
typedef enum UsbDeviceSpeed
{
ADI_USB_DEVICE_SPEED_UNKNOWN,
ADI_USB_DEVICE_SPEED_HIGH,
ADI_USB_DEVICE_SPEED_FULL,
ADI_USB_DEVICE_SPEED_LOW,
}ADI_USB_DEVICE_SPEED;

/* NET2272 Core Device Structure */
typedef struct Net2272DeviceData
{
ADI_DEV_DEVICE_HANDLE DeviceHandle; /* 设备控制 */
ADI_DMA_MANAGER_HANDLE DMAHandle; /* DMA控制 */
ADI_DCB_HANDLE DCBHandle; /* 数据控制块(DCB) */
ADI_DCB_CALLBACK_FN DMCallback; /* 回调函数 */
ADI_DEV_DIRECTION Direction; /* 设备方向 */
void *pCriticalRegionArg; /* 关键区参数指针 */
bool Started; /* 开始标志 */
DEVICE_STATE State; /* 设备状态 */
PHYSICAL_ENDPOINT_OBJECT PhysicalEndpointObjects[NUM_PHYSICAL_ENDPOINTS]; /* 物理终点对象*/
int NumPhysicalEndpoints; /* 物理中点数量 */
ADI_DMA_STREAM_ID DmaStreamID; /* DMA流的ID */
void* DmaChannelHandle; /* DMA通道句柄 */
ADI_INT_PERIPHERAL_ID PeripheralID; /* 外围设备ID *、
u32 PeripheralIVG; /* 外围设备中断向量优先级*/
int PF_Reset; /* PF(Programmable Flag)角复位 */
int PF_Int; /* PF角中断 */
int PF_Clear; /* PF角清空 */
int PF_Set; /* PF角设置 */
int DeviceID; /* 设备ID */
DEVICE_OBJECT *pDeviceObj; /* 设备对象指针 */
NET2272_STATS Stats; /* NET2272的状态 */
bool Cache; /* Cache */
void *ConfigMemoryArea; /* 配置内存区指针 */
int ConfigMemorySize; /* 配置内存区大小 */
int BufferPrefix; /* 缓冲区前缀 */
ADI_USB_DEVICE_SPEED Speed; /* USB 设备速度 */
}ADI_NET2272_DEVICE;


/* We bind each logical Endpoint object with the physical Endpoint objects. The Endpoint Object
* that is passed in is the logical endpoint object present in the currently active configuration */

section("L1_code") int BindPhysicalEndpoints(ENDPOINT_OBJECT *pLogicalEp)
{
int i = 1;
PHYSICAL_ENDPOINT_OBJECT *pPhyEpO;
ENDPOINT_OBJECT pLogEp = pLogicalEp;
ENDPOINT_DESCRIPTOR *pEpD;
ADI_NET2272_DEVICE *pDev = &Net2272Device;
volatile unsigned char EpCfg = 0x00, e;

for (i = 1; ((i <= NUM_PHYSICAL_ENDPOINTS) && (pLogEp != NULL)); i++)
{
_outpb_d(PAGESEL_ADDR, (unsigned char)i & 0xff);
e = _inpb_d(PAGESEL_ADDR);
/* Set the logical endpoint object associated for this point */
pDev->PhysicalEndpointObject[i].pLogicalEndpointObj = pLogEp;

/* Get the endpoint descriptor */
pEpD = pLogEp->pEndpointDesc;

/* Set endpoint ID */
pDev->PhysicalEndpointObjects[i].PhysicalEndpointID = pEpD->bEndpointAddress & 0x0F;

/* configure the Max packet size */
_outpb_ind(EP_MAXPKT0, LOW_BYTE_LW(pEpD->wMaxPacketSize));
_outpb_ind(EP_MAXPKT1, HIGH_BYTE_LW(pEpD->wMaxPacketSize));

/* EP_CFG register settings */
EpCfg = ((pEpD->bEndpointAddress & 0x0F) | /* Endpoint Number */
(((pEpD->bEndpointAddress >> 7) & 0x1) << 4) | /* Endpoint Direction. Host in from device */
(pEpD->bAttributes << 5) | /* Endpoint type */
1 << 7); /* Endpoint Enable */

_outpb_ind(EP_CFG, EpCfg);

e = _inpb_d(PAGESEL_ADDR);

/* disable all interrupts */
_outpb_d(EP_IRQENB_ADDR, 0x00);

/* reset all status registers */ /* write 1 set and write 1 clear */
_outpb_d(EP_STAT0_ADDR, _inpb_d(EP_STAT0_ADDR));
_outpb_d(EP_STAT1_ADDR, _inpb_d(EP_STAT1_ADDR));

/* Check the direction if its 0x1 means IN endpoint (host perspective)
* i.e you are going to send data on it, since endpoints are uni-directional
* we really care about only one handler at a time */
if ((pEpD->bEndpointAddress >> 7) & 0x1)
{
_outpb_d(EP_IRQENB_ADDR, EP_DATA_XMTD_INT);
}
else /* OUT endpoint, you receive data on it */
{
_outpb_d(EP_IRQENB_ADDR, EP_DATA_RCVD_INT | EP_DATA_OUT_TOKEN_INT);

/* initially clear NAK_OUT_PACKETS */
_outpb_d(EP_RSPCLR_ADDR, (_inpb_d(EP_RSPCLR_ADDR) | EP_NAK_OUT_PACKETS_MODE));
}
DUMP_REGISTER();

/* get the next logical endpoint */
pLogEp = pLogEp->pNextActiveEpObj;
}
/* If the number of logical endpoint objects if larger than physical ones, then it's an error */
/* enable interrupt */
_outpb_ind(IRQENB0, (_inpb_ind(IRQENB0) | (EP_A_INTERRUPT | EP_B_INTERRUPT | EP_C_INTERRUPT | EP_0_INTERRUPT)));
DUMP_REGISTER();
return 1;
}

举报

相关推荐

0 条评论