📄 usb.c
字号:
/****************************************************************
* MT View Silicon Tech. Inc.
*
* Copyright 2007, MT View Silicon Tech. Inc., ShangHai, China
* All rights reserved.
*
*
* Filename: usb.h
*
* Programmer: Grey
*
* Created: 01/xx/2008
*
* Description: usb driver(using optimization level 1, for function pointer)
*
*
*****************************************************************/
#include "usb.h"
#include <string.h>
USB_BUS XDATA gUsbBus[TOTAL_USB_BUS_NUM];
BYTE XDATA gUsbBusMap = 0;
USB_DEVICE XDATA gUsbDevice[TOTAL_USB_DEV_NUM];
BYTE XDATA gUsbDeviceMap = 0;
USB_CONFIG XDATA gUsbConfig[TOTAL_USB_CONFIG_NUM];
BYTE XDATA gUsbConfigMap = 0;
USB_INTERFACE XDATA gUsbInterface[TOTAL_USB_INTERFACE_NUM];
WORD XDATA gUsbInterfaceMap = 0;
USB_ENDPOINT XDATA gUsbEndpoint[TOTAL_USB_ENDPOINT_NUM];
DWORD XDATA gUsbEndpointMap = 0;
/*----------------------------USB allocate source---------------------------*/
/*
* Allocate usb device address
* Valid device address from 1 to 7, address 0 is not used.
*/
extern BYTE /* Return: success return address number, else return 0 */
UsbAllocDeviceAddress(
USB_BUS *usb /* Input: usb bus structure pointer */
)
{
BYTE DATA i;
i = SearchMapZero(&usb->UsbDevAddressMap, MAX_USB_DEV_NUM);
if (i == MAX_USB_DEV_NUM)
return 0;
SetMap(&usb->UsbDevAddressMap, i);
return i + 1;
}
/*
* Free usb device address
*/
extern VOID
UsbFreeDeviceAddress(
USB_BUS *usb, /* Input: usb bus structure pointer */
BYTE address /* device address number */
)
{
ClearMap(&usb->UsbDevAddressMap, address - 1);
}
/*
* Allocate usb endpoint source
* Valid endpoint index from 0 to 31, support 32 endpoints.
*/
extern USB_ENDPOINT* /* Return: success return endpoint structure pointer, else return NULL */
AllocUsbEndpoint(VOID)
{
BYTE DATA i;
USB_ENDPOINT* DATA endpoint;
i = SearchMapZero(&gUsbEndpointMap, TOTAL_USB_ENDPOINT_NUM);
if (i == TOTAL_USB_ENDPOINT_NUM)
return NULL;
SetMap(&gUsbEndpointMap, i);
endpoint = &gUsbEndpoint[i];
memset(endpoint, 0, sizeof(USB_ENDPOINT));
endpoint->Set = i;
return endpoint;
}
/*
* Free usb endpoint source
*/
extern VOID
FreeUsbEndpoint(
USB_ENDPOINT *endpoint /* Input: endpoint pointer */
)
{
/* free this endpoint */
ClearMap(&gUsbEndpointMap, endpoint->Set);
}
/*
* Allocate usb interface source
*/
extern USB_INTERFACE* /* Return: success return interface structure pointer, else return NULL */
AllocUsbInterface(VOID)
{
BYTE DATA i;
USB_INTERFACE* DATA interface;
i = SearchMapZero(&gUsbInterfaceMap, TOTAL_USB_INTERFACE_NUM);
if (i == TOTAL_USB_INTERFACE_NUM)
return NULL;
SetMap(&gUsbInterfaceMap, i);
interface = &gUsbInterface[i];
memset(interface, 0, sizeof(USB_INTERFACE));
interface->Set = i;
return interface;
}
/*
* Free usb interface source
* Before free this interface, endpoints of this interface will be free first.
*/
extern VOID
FreeUsbInterface(
USB_INTERFACE *interface /* Input: interface structure pointer */
)
{
BYTE DATA i;
/* free interface function class */
if (interface->FunctionDevice != NULL)
(*interface->CloseFunctionDevice)(interface->FunctionDevice);
/* free endpoints of this interface */
for (i = 0; i < MAX_INTERFACE_ENDPOINT_NUM; ++i)
{
if (interface->Endpoint[i] != NULL)
FreeUsbEndpoint(interface->Endpoint[i]);
}
/* free this interface */
ClearMap(&gUsbInterfaceMap, interface->Set);
}
/*
* Allocate usb configuration source
*/
extern USB_CONFIG* /* Return: success return config structure pointer, else return NULL */
AllocUsbConfig(VOID)
{
BYTE DATA i;
USB_CONFIG* DATA config;
i = SearchMapZero(&gUsbConfigMap, TOTAL_USB_CONFIG_NUM);
if (i == TOTAL_USB_CONFIG_NUM)
return NULL;
SetMap(&gUsbConfigMap, i);
config = &gUsbConfig[i];
memset(config, 0, sizeof(USB_CONFIG));
config->Set = i;
return config;
}
/*
* Free usb configuration source
* Before free this configuration, interfaces of this configuration will be free first.
*/
extern VOID
FreeUsbConfig(
USB_CONFIG *config /* Input: config structure pointer */
)
{
BYTE DATA i;
/* free interfaces of this config */
for (i = 0; i < MAX_CONFIG_INTERFACE_NUM; ++i)
{
if (config->Interface[i] != NULL)
FreeUsbInterface(config->Interface[i]);
}
/* free this config */
ClearMap(&gUsbConfigMap, config->Set);
}
/*
* Allocate usb device source
*/
extern USB_DEVICE* /* Return: success return VOID* of device structure, else return NULL */
AllocUsbDevice(VOID)
{
BYTE DATA i;
USB_DEVICE* DATA device;
i = SearchMapZero(&gUsbDeviceMap, TOTAL_USB_DEV_NUM);
if (i == TOTAL_USB_DEV_NUM)
return NULL;
SetMap(&gUsbDeviceMap, i);
device = &gUsbDevice[i];
memset(device, 0, sizeof(USB_DEVICE));
device->PipeCtrlIn = 0x80000080; /* set default pipe */
device->PipeCtrlOut = 0x80000000;
device->Set = i;
return device;
}
/*
* Free usb device source
* Before free this device, configuration of this device will be free first.
*/
extern VOID
FreeUsbDevice(
USB_DEVICE *device /* Input: VOID* of device structure */
)
{
BYTE DATA i;
USB_DEVICE *tempDev = device; /* using temp pointer save parameter, optimization level 8 have bug??? */
/* free configs of this device */
for (i = 0; i < MAX_DEV_CONFIG_NUM; ++i)
{
if (device->Config[i] != NULL)
FreeUsbConfig(device->Config[i]);
}
/* free device allocated address */
if (tempDev->DevAddress != 0)
UsbFreeDeviceAddress(tempDev->Usb, tempDev->DevAddress);
/* free this device */
ClearMap(&gUsbDeviceMap, tempDev->Set);
}
/*
* Allocate usb bus source
*/
extern VOID* /* Return: success return VOID* of usb structure, else return NULL */
AllocUsbBus(VOID)
{
BYTE DATA i;
USB_BUS* DATA usb;
i = SearchMapZero(&gUsbBusMap, TOTAL_USB_BUS_NUM);
if (i == TOTAL_USB_BUS_NUM)
return NULL;
SetMap(&gUsbBusMap, i);
usb = &gUsbBus[i];
memset(usb, 0, sizeof(USB_BUS));
usb->Set = i;
return (VOID *)usb;
}
/*
* Free usb bus source
* Before free this usb bus, hc of this usb bus will be free first.
*/
extern VOID
FreeUsbBus(
VOID *usbpriv /* Input: VOID* of usb structure */
)
{
USB_BUS *usb = (USB_BUS *)usbpriv;
/* free hci of this usb */
FreeHci(usb->HcPriv);
/* free this usb */
ClearMap(&gUsbBusMap, usb->Set);
}
/*---------------------------------------------------------------------------*/
/*---------------------------USB control pipe--------------------------------*/
/*
* USB control transfer massage operation
* Reference to chapter 9 of USB2.0 spec for the standard USB request
*/
extern BYTE /* Return: usb operation error code */
UsbControlMsg(
USB_DEVICE *device, /* Input: usb device structure pointer */
DWORD pipe, /* usb control pipe define */
BYTE request, /* request number */
BYTE requestType, /* request type */
WORD value, /* request value */
WORD index, /* request index */
WORD size, /* request size */
VOID *dat /* request data buffer pointer */
)
{
BYTE XDATA setup[8];
URB urb;
/* config setup packet */
setup[0] = requestType;
setup[1] = request;
setup[2] = (BYTE)value;
setup[3] = (BYTE)(value >> 8);
setup[4] = (BYTE)index;
setup[5] = (BYTE)(index >> 8);
setup[6] = (BYTE)size;
setup[7] = (BYTE)(size >> 8);
/* config control transfer urb */
urb.Pipe = pipe;
urb.MaxPacketSize = (device->DevAddress != 0) ? device->DeviceDescriptor.bMaxPacketSize0 : 8;
urb.Interval = 0;
urb.SetupPacket = setup;
urb.DataBuffer = dat;
urb.DataLength = size;
urb.IsUseDMA = FALSE;
urb.Err = NO_ERROR;
urb.HcPriv = device->Usb->HcPriv;
/* send control transfer urb */
return HciSendUrb(&urb);
}
/*
* Protocol get status
*/
extern BYTE /* Return: usb operation error code */
UsbGetStatus(
USB_DEVICE *device, /* Input: usb device structure pointer */
BYTE type, /* get status request type information */
BYTE target, /* target number */
VOID *dat /* status data buffer */
)
{
/* send get status request */
return UsbControlMsg(device,
device->PipeCtrlIn,
USB_REQ_GET_STATUS,
type,
0,
target,
2,
dat
);
}
/*
* Protocol clear endpoint stall
* This function use clear feature request, only clear endpoint stall.
*/
extern BYTE /* Return: usb operation error code */
UsbClearHalt(
USB_DEVICE *device, /* Input: usb device structure pointer */
BYTE pipe /* endpoint pipe */
)
{
WORD index;
/* set request index, select pipe endpoint number */
index = PipeEndpoint(pipe);
index |= PipeIn(pipe);
/* send clear feature request */
return UsbControlMsg(device,
device->PipeCtrlOut,
USB_REQ_CLEAR_FEATURE,
(USB_DIR_OUT | USB_TYPE_STANDARD | USB_RECIP_ENDPOINT),
USB_ENDPOINT_HALT,
index,
0,
NULL
);
}
/*
* Protocol set usb device address
*/
extern BYTE /* Return: usb operation error code */
UsbSetAddress(
USB_DEVICE *device /* Input: usb device structure pointer */
)
{
BYTE address;
BYTE err;
/* device address has been allocated */
if (device->DevAddress != 0)
return NO_ERROR;
/* allocate new device address */
address = UsbAllocDeviceAddress(device->Usb);
if (address == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -