Hello!
I have a board with a 5208 Coldfire and an EZ-Host used in coprocessor mode.
I try to make the device driver working using the de1_dev.c example.for
the moment I havent modified it (expect for number of endpoints and some
descriptors)
My uClinux has a 2.4.27 kernel and the device port is on SIE2 of PORT0.
When I connect the board to a PC , it is correctly enumerated. I have
successfully register my driver so I can open and close it.
But when I attempt to read data coming from a PC (using the read
fonction), nothing happens : the recv_urb call back is not called. I
have found that no interrupt is set but the data sent by the PC are
acknowledged by the EZ-Host
I have the same kind of problem on the write function: data are
correctly transmitted to lower layers, but when I try to recover them
from an external PC, data are sent which are not the data I've prepared
and the sent_urb call back, is not called. As for read function, there
are no interrupts set.
I join my test application and the modified de1_dev.c. Perhaps, I do not
used correctly the functions
Thanks in advance for help
Vincent Fourvel
/*******************************************************************************
*
* Copyright (c) 2003 Cypress Semiconductor
*
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
/*******************************************************************
*
* DESCRIPTION: Peripheral driver for EZ-HOST Design Example
* One of the development kit. This example is
* for an USB OTG driver.
*******************************************************************/
/** include files **/
//#define MODULE
#include <linux/module.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/list.h>
#include <linux/ctype.h>
#include <linux/string.h>
#include <linux/fs.h>
#include <linux/compatmac.h>
#include <linux/slab.h>
#include <asm/semaphore.h>
#include <asm/ioctls.h>
#include "../usbd.h"
#include "../usbd-func.h"
#include "../usbd-bus.h"
#include "../usbd-debug.h"
#include "../usbd-inline.h"
#include "../usbd-arch.h"
#include "../usbd-export.h"
#include "../usbd-build.h"
#include "../../cy7c67200_300_common.h"
#include "../../cy7c67200_300_debug.h"
#include "de1_dev.h"
/** local definitions **/
struct de1_priv
{
int major_number;
struct usb_device_instance * device;
struct urb_link bulk_out_rcv;
/*struct urb_link int_out_rcv;*/
struct urb_link bulk_in_tx;
/*struct urb_link int_in_tx;*/
int open_count;
struct semaphore sem;
};
static struct de1_priv * de1_priv = NULL;
extern int dbgflg_usbdfd_usbe;
#define dbg_usbe(lvl,fmt,args...) dbgPRINT(dbgflg_usbdfd_usbe,lvl,fmt,##args)
/* function prototypes */
static void de1_event(struct usb_device_instance *, usb_device_event_t, int);
static int de1_urb_sent(struct usbd_urb *, int);
static int de1_recv_urb(struct usbd_urb *);
static void de1_function_init(struct usb_bus_instance *,
struct usb_device_instance *,
struct usb_function_driver *);
static void de1_function_exit(struct usb_device_instance *);
static ssize_t de1_read(struct file *, char *, size_t, loff_t *);
static ssize_t ep_read(struct de1_priv *, char *, size_t, int);
static ssize_t de1_write(struct file *, const char *, size_t, loff_t *);
static ssize_t ep_write(struct de1_priv *, const char *, size_t, int);
static int de1_open(struct inode *, struct file *);
static int de1_release(struct inode *, struct file *);
static int de1_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static void de1_recycle_urb(struct usbd_urb *urb, struct urb_link *link);
/******************************************************************************
* FUNCTION CONFIGURATION DESCRIPTORS
*/
struct usb_otg_description de1_otg_description =
{
bmAttributes : BMATTRIBUTE_HNP_SUPPORT | BMATTRIBUTE_SRP_SUPPORT
};
struct usb_endpoint_description de1_endpoint_description[] =
{
{
bEndpointAddress : BULK_IN_EP,
bmAttributes : BULK,
wMaxPacketSize : 64,
bInterval : 0,
direction : IN,
transferSize : 1024
},
{
bEndpointAddress : BULK_OUT_EP,
bmAttributes : BULK,
wMaxPacketSize : 64,
bInterval : 0,
direction : OUT,
transferSize : 1024
},
/* MODIF CREALIE ************************/
/*ce 3eme endpoint nesert à rien mais évite le bug du paquet vide*/
{
bEndpointAddress : INT_IN_EP,
bmAttributes : INTERRUPT,
wMaxPacketSize : 64,
bInterval : 100, // polling interval, from 1 to 255
direction : IN,
transferSize : 64
},
/*{
bEndpointAddress : INT_OUT_EP,
bmAttributes : INTERRUPT,
wMaxPacketSize : 64,
bInterval : 100, // polling interval, from 1 to 255
direction : OUT,
transferSize : 64
} */
};
struct usb_alternate_description de1_alternate_description =
{
iInterface : 0,
bAlternateSetting : 0,
classes : 0,
class_list : NULL,
endpoints : 3,
/* MODIF CREALIE ************************/
/* sizeof(de1_endpoint_description) /
sizeof(struct usb_endpoint_description),*/
endpoint_list : de1_endpoint_description,
otg_description : NULL
};
struct usb_interface_description de1_interface_description =
{
bInterfaceClass : 0xFF,
bInterfaceSubClass : 0,
bInterfaceProtocol : 0,
iInterface : 0,
alternates : 1,
/* MODIF CREALIE ************************/
/*sizeof(de1_alternate_description) /
sizeof(struct usb_alternate_description),*/
alternate_list : &de1_alternate_description
};
struct usb_configuration_description de1_configuration_description =
{
iConfiguration : 0,
bmAttributes : BMATTRIBUTE_RESERVED | BMATTRIBUTE_SELF_POWERED,
bMaxPower : 0,
interfaces : 1,
/* MODIF CREALIE **************************/
/*sizeof(de1_interface_description) /
sizeof(struct usb_interface_description),*/
interface_list : &de1_interface_description,
};
struct usb_device_description de1_device_description =
{
bDeviceClass : DVK1_DEVICE_CLASS,
bDeviceSubClass : DVK1_DEVICE_SUBCLASS,
bDeviceProtocol : DVK1_DEVICE_PROTOCOL,
idVendor : DVK1_VENDOR_ID,
idProduct : DVK1_PRODUCT_ID,
iManufacturer : DVK1_MANUFACTURER_STR,
iProduct : DVK1_PRODUCT_STR,
iSerialNumber : DVK1_SERIAL_NUMBER_STR
};
/*****************************************************************************/
struct usb_function_operations de1_function_ops =
{
event : de1_event,
urb_sent : de1_urb_sent,
recv_urb : de1_recv_urb,
recv_setup : 0,
function_init : de1_function_init,
function_exit : de1_function_exit,
};
struct usb_function_driver de1_function_driver =
{
name : "DVK1_function_driver",
ops : &de1_function_ops,
device_description : &de1_device_description,
configurations : sizeof(de1_configuration_description) /
sizeof(struct usb_configuration_description),
configuration_description : &de1_configuration_description,
this_module : THIS_MODULE,
};
struct file_operations de1_file_ops =
{
owner : THIS_MODULE,
read : de1_read,
write : de1_write,
open : de1_open,
release : de1_release,
ioctl : de1_ioctl,
};
/******************************************************************************
* PARAMETERS: bus -> pointer to usb_bus_instance
* device -> pointer to usb_device_instance
* func_driver -> pointer to usb_function_driver
*
* DESCRIPTION: This routine will initialize the function driver's private
* data. It is called from the peripheral controller
*
* RETURNS:
*
*/
void de1_function_init(struct usb_bus_instance * bus,
struct usb_device_instance * device,
struct usb_function_driver * func_driver)
{
cy_dbg("de1_function_init enter");
de1_priv = kmalloc( sizeof(struct de1_priv), GFP_KERNEL);
if(de1_priv == NULL)
{
cy_err("de1_priv memory allocation failed.");
return;
}
/* Register device driver */
de1_priv->major_number =
register_chrdev( USB_DE1_MAJOR, DE1_DEVICE_NAME, &de1_file_ops );
/* MODIF CREALIE ****************/
if( de1_priv->major_number < 0 )
{
cy_err("register_chrdev() failed.");
kfree(de1_priv);
de1_priv = NULL;
return;
}
/* save off the usb_device_instance pointer */
de1_priv->device = device;
de1_priv->open_count = 0;
/* initialize the semaphore, (kernel) */
sema_init(&de1_priv->sem, 1);
/* save our private data into the usb_function_instance private pointer */
device->function_instance_array->privdata = de1_priv;
}
/******************************************************************************
* PARAMETERS: device -> pointer to usb_device_instance
*
* DESCRIPTION: Not used for DE1
*
* RETURNS:
*
*/
void de1_function_exit(struct usb_device_instance * device)
{
int i;
cy_dbg("de1_function_exit enter");
/* deallocate URB's for each endpoint */
for(i = 0; i < TOTAL_ENDPOINTS; i++)
{
/* free up URB buffers */
}
unregister_chrdev( de1_priv->major_number, DE1_DEVICE_NAME );
/* deallocate the function private structure */
kfree(de1_priv);
de1_priv = NULL;
/* set the usb_function_instance privdata pointer to null */
device->function_instance_array->privdata = NULL;
}
/******************************************************************************
* PARAMETERS: device -> pointer to usb_device_instance
* event -> device event to handle
* data -> event data
*
* DESCRIPTION: Handle an event from the usbd core.
*
* RETURNS:
*
*/
void de1_event(struct usb_device_instance * device, usb_device_event_t event,
int data)
{
//extern char *usbd_device_events[];
cy_dbg("de1_event enter: event: %s, data = %d",
usbd_device_events[event], data);
switch(event)
{
case DEVICE_INIT:
{
struct usbd_urb * urb;
size_t i;
/* initialize URB linked lists */
urb_link_init(&de1_priv->bulk_out_rcv);
/*urb_link_init(&de1_priv->int_out_rcv);*/
urb_link_init(&de1_priv->bulk_in_tx);
/*urb_link_init(&de1_priv->int_in_tx);*/
/* allocate bulk send urbs */
for(i=0; i<5; i++)
{
urb = usbd_alloc_urb(device,
device->function_instance_array,
BULK_IN_EP,
BULK_IN_BUFF_SZ);
de1_recycle_urb(urb, &de1_priv->bulk_in_tx);
}
/* allocate int send urbs */
/*urb = usbd_alloc_urb(device,
device->function_instance_array,
INT_IN_EP,
INT_IN_BUFF_SZ);
de1_recycle_urb(urb, &de1_priv->int_in_tx);*/
}
break;
case DEVICE_CONFIGURED:
cy_err("Device is configured");
break;
case DEVICE_BUS_ACTIVITY:
cy_err("Activity on bus");
break;
case DEVICE_SET_INTERFACE:
case DEVICE_SET_FEATURE:
case DEVICE_CLEAR_FEATURE:
case DEVICE_DE_CONFIGURED:
case DEVICE_BUS_INACTIVE:
case DEVICE_POWER_INTERRUPTION:
case DEVICE_HUB_RESET:
case DEVICE_DESTROY:
case DEVICE_FUNCTION_PRIVATE:
case DEVICE_UNKNOWN:
case DEVICE_CREATE:
case DEVICE_HUB_CONFIGURED:
case DEVICE_RESET:
case DEVICE_ADDRESS_ASSIGNED:
break;
}
}
/******************************************************************************
* PARAMETERS: sent_urb -> pointer to the URB that was sent
* data -> unused value
*
* DESCRIPTION: Callback to notify function that a URB has been transmitted
* on the bus.
*
* RETURNS: Zero for SUCCESS, negative for ERROR.
*
*/
static int de1_urb_sent(struct usbd_urb * sent_urb, int data)
{
int return_value = ERROR;
cy_dbg("de1_urb_sent enter");
cy_err("de1_urb_sent enter");
/* check the status of the completed URB */
switch(sent_urb->status)
{
case SEND_FINISHED_OK:
case SEND_FINISHED_ERROR:
switch( sent_urb->endpoint->endpoint_address & 0xf)
{
case BULK_IN_EP:
de1_recycle_urb(sent_urb, &de1_priv->bulk_in_tx);
return_value = SUCCESS;
cy_err("Envoie, case %d",sent_urb->status);
break;
/* case INT_IN_EP:
de1_recycle_urb(sent_urb, &de1_priv->int_in_tx);
return_value = SUCCESS;
break;*/
default:
cy_warn("ERROR didn't recycle urb");
break;
}
break;
default:
cy_err("ERROR de1_urb_sent: unhandled sent status.");
break;
}
return(return_value);
}
/******************************************************************************
* PARAMETERS: recv_urb -> a pointer to a URB passed from the peripheral core
* layer.
*
* DESCRIPTION: Called to receive a URB, called in the interrupt context.
* This function determines to which endpoint the received URB belongs, and
* saves off the pointer to this URB in the function's private data. This
* will then be processed in the read() function when called by the
* application. The read() function will then recycle the URB.
*
* In the future, this may just store the data in a buffer and return. Then
* the read function would read directly from the buffer. This implementation
* would return the URB's immediately to the peripheral controller driver.
* Currently, instead of allocating a separate buffer, this function saves
* off a pointer to the URB and the read() function handles it directly,
* essentially using the URB buffer to store the data, instead of allocating
* separate buffer space.
*
* RETURNS: A negative value for an error condition, and zero for success.
* If an error is returned, then the calling function will check this return
* value, and recycle the URB, essentially discarding the data.
*
*/
int de1_recv_urb(struct usbd_urb * recv_urb)
{
int port = 0;
struct usb_device_instance *device = recv_urb->device;
struct de1_priv * priv = (device->function_instance_array+port)->privdata;
int ret_value = -EINVAL;
cy_dbg("de1_recv_urb enter");
cy_err("de1_recv_urb enter");
if((recv_urb != NULL) && (recv_urb->status != RECV_ERROR))
{
// determine which endpoint received the URB.
switch(recv_urb->endpoint->endpoint_address & 0xf) {
/* save off the URB pointer for a subsequent read by the
* application, this will add the URB to a linked list, it
* allows us to receive data faster than the application
* may request it */
case BULK_OUT_EP:
urb_append_irq(&priv->bulk_out_rcv, recv_urb);
cy_err("urb_append_irq");
/* the read() function will recycle the URB after the
* application retrieves the data, so we are done */
ret_value = SUCCESS;
break;
/* save off the pointer to this URB, it will be read by
* the application through an IOCTL call, which will then
* recycle the URB */
/* case INT_OUT_EP:
urb_append_irq(&priv->int_out_rcv, recv_urb);
cy_dbg("int urb received");*/
/* the ioctl() function will recycle the URB after the
* application retrieves the data, so we are done */
/*ret_value = SUCCESS;
break;*/
default:
usbd_recycle_urb(recv_urb);
ret_value = -EINVAL;
break;
}
}
else
{
ret_value = -EINVAL;
usbd_recycle_urb(recv_urb);
}
return ret_value;
}
/******************************************************************************
*
* DESCRIPTION: Linux device read
*
* RETURNS:
*
*/
static ssize_t de1_read(struct file *file, char *buffer, size_t count,
loff_t *ppos)
{
ssize_t ret;
struct usbd_urb * urb;
struct de1_priv * priv = (struct de1_priv *) file->private_data;
//cy_err("Lecture en cours\n");
down(&priv->sem);
/* urb = usbd_alloc_urb(device,
device->function_instance_array,
BULK_OUT_EP,
BULK_IN_BUFF_SZ);
de1_recycle_urb(urb, &de1_priv->bulk_out_rx)*/
ret = ep_read( priv, buffer, count, BULK_OUT_EP );
up(&priv->sem);
//cy_err("Lecture terminee\n");
return ret;
}
/******************************************************************************
*
* DESCRIPTION: Common read function for device read and ioctl.
*
* RETURNS:
*
*/
static ssize_t ep_read(struct de1_priv *priv, char *buffer, size_t count,
int endpoint)
{
struct usbd_urb * urb;
ssize_t return_value = ERROR;
int length;
struct urb_link *urb_link;
cy_dbg("ep_read enter, count:%d, ep:%d", count, endpoint);
/*if( endpoint == INT_OUT_EP )
{
urb_link = &priv->int_out_rcv;
}
else*/ if( endpoint == BULK_OUT_EP )
{
urb_link = &priv->bulk_out_rcv;
}
else
{
cy_err("Reading on unknown endpoint");
return -EINVAL;
}
/* verify that the device wasn't unplugged */
if( priv->device != NULL &&
!( priv->device->status == USBD_OK &&
priv->device->device_state == DEVICE_CONFIGURED ) )
{
cy_dbg("device not connected");
return -ENOTCONN;
}
if( (urb = first_urb_detached(urb_link)) == NULL )
{
/* urb = usbd_alloc_urb(priv->device,
priv->device->function_instance_array,
BULK_OUT_EP,
BULK_OUT_BUFF_SZ);
de1_recycle_urb(urb, &de1_priv->bulk_out_rcv);*/
return -EAGAIN;
}
length = urb->actual_length;
cy_err("Longueur actuelle : %d \n",length);
if(count >= length)
{
if( copy_to_user(buffer, urb->buffer, length) )
{
/* put back on queue */
urb_link_init(&urb->link);
urb_append_irq(urb_link, urb);
cy_err("copy_to_user failure");
return_value = -EFAULT;
}
else
{
cy_err("On passe la");
usbd_recycle_urb(urb);
return_value = length;
}
cy_dbg("1:de1_read, return:%d", return_value);
}
else
{
/* there is more data in this URB than is currently requested,
return the requested amount, and then place the remaining data
back in the receive queue, at the head. */
int difference;
difference = length - count; /* size of remaining data of URB buffer */
if( copy_to_user(buffer, urb->buffer, count) )
{
/* put back on queue */
urb_link_init(&urb->link);
urb_append_irq(urb_link, urb);
cy_err("copy_to_user failure");
return_value = -EFAULT;
}
else {
memcpy(urb->buffer, urb->buffer + count, difference);
urb->actual_length = difference;
/* put back on queue */
urb_link_init(&urb->link);
urb_append_irq(urb_link, urb);
return_value = count;
}
cy_dbg("2:de1_read, return:%d", return_value);
}
return return_value;
}
/******************************************************************************
*
* DESCRIPTION: Linux device write
*
* RETURNS:
*
*/
static ssize_t de1_write(struct file *file, const char *buffer, size_t count,
loff_t *ppos)
{
ssize_t ret;
struct de1_priv *priv = (struct de1_priv *) file->private_data;
down(&priv->sem);
ret = ep_write(priv, buffer, count, BULK_IN_EP);
up(&priv->sem);
return ret;
}
/******************************************************************************
*
* DESCRIPTION: Common write function for device write and ioctl
*
* RETURNS:
*
*/
static ssize_t ep_write(struct de1_priv *priv, const char *buffer,
size_t count, int endpoint)
{
struct usbd_urb * urb;
ssize_t return_value = ERROR;
ssize_t bytes_written = 0;
struct urb_link *urb_link;
cy_dbg("ep_write enter - count:%d, ep:%d", count, endpoint);
/* verify that the device wasn't unplugged */
if( priv->device != NULL &&
!( priv->device->status == USBD_OK &&
priv->device->device_state == DEVICE_CONFIGURED ) )
{
cy_dbg("device not connected");
return -ENOTCONN;
}
/* is the count set */
if(count <= 0 || buffer == NULL) {
cy_err("invalid count/buffer");
return -EINVAL;
}
/*if( endpoint == INT_IN_EP )
{
urb_link = &priv->int_in_tx;
}
else*/ if( endpoint == BULK_IN_EP )
{
urb_link = &priv->bulk_in_tx;
}
else
{
cy_err("Writing on unknown endpoint");
return -EINVAL;
}
/* we have some data to send, get a URB and send it */
urb = first_urb_detached(urb_link);
if( urb == 0 ) {
cy_err("no urb pointer");
return -EAGAIN;
}
/* we can only write as much as 1 urb will hold */
bytes_written = (count > urb->buffer_length) ? urb->buffer_length :
count;
/* copy the data from userspace into our urb */
if (copy_from_user(urb->buffer, buffer, bytes_written)) {
de1_recycle_urb(urb, urb_link);
cy_err("copy from user error");
return -EFAULT;
}
urb->actual_length = bytes_written;
/* submit the URB */
if( usbd_send_urb(urb) == 0 )
{
return_value = bytes_written;
}
else
{
cy_err("Failed to send urb");
de1_recycle_urb(urb, urb_link);
return_value = -EAGAIN;
}
cy_dbg("write exit");
return return_value;
}
/******************************************************************************
*
* DESCRIPTION: Linux device open
*
* RETURNS:
*
*/
static int de1_open(struct inode *inode, struct file *file)
{
int subminor;
int retval = 0;
cy_dbg("de1_open enter");
cy_err("Ouverture en cours\n");
subminor = MINOR(inode->i_rdev) - USB_DE1_MINOR_BASE;
if ((subminor < 0) ||
(subminor >= MAX_DEVICES))
{
return -ENODEV;
}
MOD_INC_USE_COUNT;
/* lock this device */
down(&de1_priv->sem);
/* increment our usage count for the driver */
++de1_priv->open_count;
/* save our object in the file's private structure */
file->private_data = de1_priv;
/* unlock this device */
up(&de1_priv->sem);
cy_dbg("de1_open exit");
cy_err("Ouverture terminee\n");
return retval;
}
/******************************************************************************
*
* DESCRIPTION: Linux driver call
*
* RETURNS:
*
*/
int de1_release(struct inode *inode, struct file *filp)
{
cy_dbg("de1_release enter");
if (de1_priv == NULL)
{
cy_err("%s - object is NULL", __FUNCTION__);
return -EFAULT;
}
/* lock our device */
down(&de1_priv->sem);
/* decrement our usage count for the module */
MOD_DEC_USE_COUNT;
up(&de1_priv->sem);
cy_dbg("de1_release exit");
return 0;
}
/******************************************************************************
*
* DESCRIPTION: Linux device ioctl
*
* RETURNS:
*
*/
static int de1_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
{
struct de1_priv * priv;
int return_value = ERROR;
cy_dbg("de1_ioctl enter, %d", cmd);
if((priv = (struct de1_priv *) file->private_data) != NULL)
{
/* lock this object */
down(&priv->sem);
/* verify that the device wasn't unplugged */
if(priv->device != NULL) {
/* we have a valid device */
switch(cmd)
{
case IOCTL_ACCEPT_HNP:
usbd_device_event(de1_priv->device, DEVICE_ACCEPT_HNP, 0);
return_value = SUCCESS;
break;
case IOCTL_REQUEST_SRP:
/* usbd_device_event(de1_priv->device, DEVICE_REQUEST_SRP, 0);
return_value = SUCCESS;
break;*/
case IOCTL_GET_DE_RPT:
/*{
unsigned char count;
if( arg != 0 &&
!copy_from_user(&count, (void*)arg, 1) )
{
return_value = ep_read( priv, (char*)arg, count,
INT_OUT_EP );
if( return_value >=0 )
{
return_value = SUCCESS;
}
}
}*/
break;
case IOCTL_SEND_DE_RPT:
/* {
unsigned char count;
if( arg != 0 &&
!copy_from_user(&count, (void*)arg, 1) )
{
cy_dbg("rpt size: %d", count);
return_value =
ep_write( priv, (char*)arg, count, INT_IN_EP );
if( return_value >=0 )
{
return_value = SUCCESS;
}
}
}
break;*/
case TCGETS:
break;
default:
cy_err("unrecognized ioctl command: 0x%x", cmd);
break;
}
}
/* unlock the device */
up(&priv->sem);
}
cy_dbg("de1_ioctl exit");
return return_value;
}
/******************************************************************************
*
* DESCRIPTION: recycle transmit urbs
*
* RETURNS:
*
*/
void de1_recycle_urb(struct usbd_urb *urb, struct urb_link *link)
{
if( urb != 0 && link != 0)
{
unsigned long int_flags;
urb_link_init(&urb->link);
local_irq_save(int_flags);
urb_append_irq(link, urb);
local_irq_restore(int_flags);
}
}
/******************************************************************************
*
* DESCRIPTION: Initialize module for design example one
*
* RETURNS:
*
*/
int __init de1_modinit(void)
{
int err;
cy_dbg("de1_modinit enter");
/* optional name override */
de1_function_driver.name = DRIVER_NAME;
/* register this function driver with the USBD core */
err = usbd_register_function(&de1_function_driver);
if( err != 0 )
{
cy_err("usbd_register_function() failed.");
}
return err;
}
/******************************************************************************
*
* DESCRIPTION: Clean up for module exit. Not used in DE1.
*
* RETURNS:
*
*/
void __exit de1_modexit(void)
{
cy_dbg("de1_modexit enter");
usbd_deregister_function(&de1_function_driver);
}
/*****************************************************************************/
#ifdef MODULE
module_init(de1_modinit);
module_exit(de1_modexit);
#endif
/*****************************************************************************/
/*
* USB_Test.c -- USB device Test.
*
* (C) Copyright 2006, Jean-Christophe Mirouse, ReflexCes
*/
/*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <getopt.h>
#include <errno.h>
#include <signal.h>
#include <string.h>
#include <sys/types.h>
#include <sys/termios.h>
#include <sys/time.h>
#include <sys/ioctl.h>
#include <time.h>
//#include <asm/ioctls.h>
#define I_NO_READ ((int) 0)
#define I_WITH_READ ((int) 1)
void TestUSB(int i_option);
/*****************************************************************************/
char *version = "1.0.0";
/*****************************************************************************/
void sig_handler()
{
printf("1");
}
/*****************************************************************************/
void usage( int rc)
{
printf("Usage: usb_test\n\n");
printf(" -h? this help\n");
printf(" -w only write test\n");
printf("This fonction print on screen the data receive by usb and send
their negative value\n");
exit(rc); /* install the signal handler before making the device
asynchronous */
}
/*****************************************************************************/
int main(int argc, char *argv[])
{
int flag_write,flag_read;
char c;
flag_read = 0;
flag_write = 0;
c = getopt(argc, argv, "h?w");
if(c > 0)
{
switch (c)
{
case 'h':
case '?':
usage(0);
break;
case 'w':
TestUSB(I_NO_READ);
break;
default:
printf("ERROR: unknown option '%c'\n", c);
usage(1);
break;
}
}
else
{
TestUSB(I_WITH_READ);
}
return 0;
}
void TestUSB(int i_option)
{
int device_fp;
int i;
unsigned char ucByte[10];
for (i = 0; i < 10 ; i++)
{
ucByte[i] = i ;
}
printf("Test USB device\n");
sleep(1);
if ((device_fp = open("/dev/usbdev", O_RDWR|O_SYNC)) == 0)
{
printf("\nERROR: failed to open /dev/usbdev,
errno=%d\n",
errno);
exit(0);
}
else
{
printf("Device open successfully\n");
}
sleep(1);
if (i_option == I_WITH_READ)
{
printf("wait for 10 data bytes\n");
printf("To stop waiting, press ctrl-c\n\n");
sleep(1);
while (read(device_fp,ucByte,10) != 10)
{
sleep(1);
}
}
for (i = 0; i < 10 ; i++)
{
printf("Octets no %d :%d \n",i,ucByte[i]);
}
sleep(1);
/*inversion données*/
for (i = 0; i < 10 ; i++)
{
ucByte[i] = ucByte[i]*2;
}
if(write(device_fp,ucByte,10)!=10)
{
printf("ERROR: failed to fwrite /dev/usbdev,
errno=%d\n",
errno);
sleep(1);
exit(0);
}
else
{
printf("All bytes sent");
}
close(device_fp);
}
_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev