分享

linux下PC与AT91SAM9X35 USB通讯

 quasiceo 2015-07-04
最近在做PC和开发板的USB通讯,借鉴了内核中的代码zero.c和usb-skeieton.c,实现了linux环境下USB的通讯,在此做点记录,如有疑问,请发邮箱:lutao614@126.com
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include  
#include  
#include
#include
#include
#include "g_zero.h"
#include "gadget_chips.h"
#include "composite.c"
#include "usbstring.c"
#include "config.c"
#include "epautoconf.c"
#include "f_sink.c"  ////自己添加的

#define DRIVER_VERSION "Gestton 2013"
static const char longname[] = "Gestton USB Device";
unsigned buflen = 4096;
static int loopdefault = 0;
#define DRIVER_VENDOR_NUM 0x03EB
#define DRIVER_PRODUCT_NUM 0x6119
#define DEFAULT_AUTORESUME 0
unsigned autoresume = DEFAULT_AUTORESUME;
static struct usb_device_descriptor device_desc = {
.bLength = sizeof device_desc,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = cpu_to_le16(0x0200),
.bDeviceClass = USB_CLASS_VENDOR_SPEC,
.idVendor = cpu_to_le16(DRIVER_VENDOR_NUM),
.idProduct = cpu_to_le16(DRIVER_PRODUCT_NUM),
.bNumConfigurations = 2,
};
#define STRING_MANUFACTURER_IDX 0
#define STRING_PRODUCT_IDX 1
#define STRING_SERIAL_IDX 2
static char manufacturer[50];
static char serial[] = "0123456789.0123456789.0123456789";
static struct usb_string strings_dev[] = {
[STRING_MANUFACTURER_IDX].s = manufacturer,
[STRING_PRODUCT_IDX].s = longname,
[STRING_SERIAL_IDX].s = serial,
{  }
};

static struct usb_gadget_strings stringtab_dev = {
.language = 0x0409,  
.strings = strings_dev,
};

static struct usb_gadget_strings *dev_strings[] = {
&stringtab_dev,
NULL,
};

struct usb_request *alloc_ep_req(struct usb_ep *ep)
{
struct usb_request *req;
req = usb_ep_alloc_request(ep, GFP_ATOMIC);
if (req) {
req->length = buflen;
req->buf = kmalloc(buflen, GFP_ATOMIC);
if (!req->buf) {
usb_ep_free_request(ep, req);
req = NULL;
}
}
return req;
}

void free_ep_req(struct usb_ep *ep, struct usb_request *req)
{
kfree(req->buf);
usb_ep_free_request(ep, req);
}

static void disable_ep(struct usb_composite_dev *cdev, struct usb_ep *ep)
{
int value;
if (ep->driver_data) {
value = usb_ep_disable(ep);
if (value < 0)
DBG(cdev, "disable %s --> %d\n",ep->name, value);
ep->driver_data = NULL;
}
}

void disable_endpoints(struct usb_composite_dev *cdev,struct usb_ep *in, struct usb_ep *out)
{
disable_ep(cdev, in);
disable_ep(cdev, out);
}

static struct timer_list autoresume_timer;
static void zero_autoresume(unsigned long _c)
{
struct usb_composite_dev *cdev = (void *)_c;
struct usb_gadget *g = cdev->gadget;
if (!cdev->config)
return;
if (g->speed != USB_SPEED_UNKNOWN) {
int status = usb_gadget_wakeup(g);
INFO(cdev, "%s --> %d\n", __func__, status);
}
}

static void zero_suspend(struct usb_composite_dev *cdev)
{
if (cdev->gadget->speed == USB_SPEED_UNKNOWN)
return;
if (autoresume) {
mod_timer(&autoresume_timer, jiffies + (HZ * autoresume));
DBG(cdev, "suspend, wakeup in %d seconds\n", autoresume);
} else
DBG(cdev, "%s\n", __func__);
}

static void zero_resume(struct usb_composite_dev *cdev)
{
DBG(cdev, "%s\n", __func__);
del_timer(&autoresume_timer);
}

static int __init zero_bind(struct usb_composite_dev *cdev)
{
int gcnum;
struct usb_gadget *gadget = cdev->gadget;
int id;

id = usb_string_id(cdev);
if (id < 0)
return id;
strings_dev[STRING_MANUFACTURER_IDX].id = id;
device_desc.iManufacturer = id;

id = usb_string_id(cdev);
if (id < 0)
return id;
strings_dev[STRING_PRODUCT_IDX].id = id;
device_desc.iProduct = id;

id = usb_string_id(cdev);
if (id < 0)
return id;
strings_dev[STRING_SERIAL_IDX].id = id;
device_desc.iSerialNumber = id;
setup_timer(&autoresume_timer, zero_autoresume, (unsigned long) cdev);

if (loopdefault) {
loopback_add(cdev, autoresume != 0);
sourcesink_add(cdev, autoresume != 0);
} else {
                sourcesink_add(cdev, 1);
}

gcnum = usb_gadget_controller_number(gadget);//获得控制器代号
if (gcnum >= 0)
device_desc.bcdDevice = cpu_to_le16(0x0200 + gcnum);
else {
pr_warning("%s: controller '%s' not recognized\n",
longname, gadget->name);
device_desc.bcdDevice = cpu_to_le16(0x9999);
}

INFO(cdev, "%s, version: " DRIVER_VERSION "\n", longname);
snprintf(manufacturer, sizeof manufacturer, "%s %s with %s",
init_utsname()->sysname, init_utsname()->release,
gadget->name);

return 0;
}

static int zero_unbind(struct usb_composite_dev *cdev)
{
del_timer_sync(&autoresume_timer);
return 0;
}

static struct usb_composite_driver zero_driver = {
.name = "zero",
.dev = &device_desc,
.strings = dev_strings,
.unbind = zero_unbind,
.suspend = zero_suspend,
.resume = zero_resume,
};


static int __init init(void)
{
return usb_composite_probe(&zero_driver, zero_bind);
}
static void __exit cleanup(void)
{
usb_composite_unregister(&zero_driver);
}
module_init(init);
module_exit(cleanup);
MODULE_AUTHOR("LUTAO");
MODULE_LICENSE("GPL");

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多