This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/EK-TM4C1294XL: usb_dev_bulk example with linux

Part Number: EK-TM4C1294XL


Tool/software: Linux

Hi,

I've been trying to exchange data between my TM4C1294XL and my PC running on Linux Fedora 25 using the usb_dev_bulk example, but without success. In the TM4C1294XL code I removed the UART part entirely and added GPIOPinWrite() to the RXHandler()  just to indicate any receive events, nothing happened. Also on the PC side which I realized through libusb library in C++ there is no incoming data.

Any suggestions?

Best regards,

Milos

  • Hi Milos,

     Is it possible for you to test your same modified code on a Windows (i.e. Win7) machine and see if it works. Perhaps it is a driver issue on the linux side. Please take a look at this webpage for Linux usb driver.  

     You will need to modify the USB vendor and product IDs. The below modified code I pasted is for another TI device. You can modify it for TM4C. 

    usb_transfer.c
    
    #include <linux/module.h>
    #include <linux/kernel.h>
    #include <linux/usb.h>
    
    #define MIN(a,b) (((a) <= (b)) ? (a) : (b))
    #define BULK_EP_OUT 0x01
    #define BULK_EP_IN 0x82
    #define MAX_PKT_SIZE 512
    
    static struct usb_device *device;
    static struct usb_class_driver class;
    static unsigned char bulk_buf[MAX_PKT_SIZE];
    
    static int pen_open(struct inode *i, struct file *f)
    {
    return 0;
    }
    static int pen_close(struct inode *i, struct file *f)
    {
    return 0;
    }
    static ssize_t pen_read(struct file *f, char __user *buf, size_t cnt, loff_t *off)
    {
    int retval;
    int read_cnt;
    
    /* Read the data from the bulk endpoint */
    retval = usb_bulk_msg(device, usb_rcvbulkpipe(device, BULK_EP_IN),
    bulk_buf, MAX_PKT_SIZE, &read_cnt, 5000);
    if (retval)
    {
    printk(KERN_ERR "Bulk message returned %d\n", retval);
    return retval;
    }
    if (copy_to_user(buf, bulk_buf, MIN(cnt, read_cnt)))
    {
    return -EFAULT;
    }
    
    return MIN(cnt, read_cnt);
    }
    static ssize_t pen_write(struct file *f, const char __user *buf, size_t cnt, loff_t *off)
    {
    int retval;
    int wrote_cnt = MIN(cnt, MAX_PKT_SIZE);
    
    if (copy_from_user(bulk_buf, buf, MIN(cnt, MAX_PKT_SIZE)))
    {
    return -EFAULT;
    }
    
    /* Write the data into the bulk endpoint */
    retval = usb_bulk_msg(device, usb_sndbulkpipe(device, BULK_EP_OUT),
    bulk_buf, MIN(cnt, MAX_PKT_SIZE), &wrote_cnt, 5000);
    if (retval)
    {
    printk(KERN_ERR "Bulk message returned %d\n", retval);
    return retval;
    }
    
    return wrote_cnt;
    }
    
    static struct file_operations fops =
    {
    .open = pen_open,
    .release = pen_close,
    .read = pen_read,
    .write = pen_write,
    };
    
    static int pen_probe(struct usb_interface *interface, const struct usb_device_id *id)
    {
    int retval;
    
    device = interface_to_usbdev(interface);
    
    class.name = "usb/ti_usbbulk%d";
    class.fops = &fops;
    if ((retval = usb_register_dev(interface, &class)) < 0)
    {
    /* Something prevented us from registering this driver */
    printk("Not able to get a minor for this device.");
    }
    else
    {
    printk(KERN_INFO "Minor obtained: %d\n", interface->minor);
    }
    
    return retval;
    }
    
    static void pen_disconnect(struct usb_interface *interface)
    {
    usb_deregister_dev(interface, &class);
    }
    
    /* Table of devices that work with this driver */
    static struct usb_device_id pen_table[] =
    {
    { USB_DEVICE(0x1CBE, 0x0003) }, //TI's USB bulk device (OMAPL138)
    {} /* Terminating entry */
    };
    MODULE_DEVICE_TABLE (usb, pen_table);
    
    static struct usb_driver pen_driver =
    {
    .name = "pen_driver",
    .probe = pen_probe,
    .disconnect = pen_disconnect,
    .id_table = pen_table,
    };
    
    static int __init pen_init(void)
    {
    int result;
    
    /* Register this driver with the USB subsystem */
    if ((result = usb_register(&pen_driver)))
    {
    printk("usb_register failed. Error number %d", result);
    }
    return result;
    }
    
    static void __exit pen_exit(void)
    {
    /* Deregister this driver with the USB subsystem */
    usb_deregister(&pen_driver);
    }
    
    module_init(pen_init);
    module_exit(pen_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>");
    MODULE_DESCRIPTION("USB Pen Device Driver");
    
    
    Makefile:
    
    obj-m += usb_transfer.o
    
    all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
    
    
    clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
    
    
    Insert the driver:
    
    insmod usb_transfer.ko
    
    
    And connect the USB cable into PC then run the code......
    
    To test:
    echo "USB BULK TESTING..." > /dev/ti_usbbulk
    
    You can see the Rx bytes count increasing on the VGA monitor which is connected to LCDK board.

  • Hi Charles,

    you are my hero!!! Thank you so much. It works :)))

    Best regards,

    Milos

  • Glad your problem is solved.