Tuesday, March 12, 2013

USB and MMC

USB

Search for "LINUX USB API - DAIICT Intranet" for Quick Reference.

USB driver link gives easy to understand and clear explanation.
Also see USB tutorial from Atmel.



Application prefers to use libusb library to access usb device/driver functanality.

Before we go to USB driver, we will have a look on USB sub-system.

USB physical interface joins system bus by a controller and is called host controller interface(HCI).
HCI driver is the one which let your system detect attached usb device. If wrong hci driver is used (for controller) devices will not be recognized.
Controller also virtualizes a root usb hub. And all usb devices/hub joins it in hierarchical order.

USBv1.0: Low speed: uhci.o is a driver lincenced by intel and ohci.o is a driver for all other vendors.
USBv2.0: High Speed: ehci.o, and we can see this driver in ARM devices too.

usbcore is the manager of USB sub-system. All drivers has to register with usbcore. Even hci drivers also registers with usbcore.

Endpoints:
Control, Interrupt, Bulk, isochronous.

Interface:
Contains array of settings and the 1st one at array index 0 is the default one.

Configuration:

Descriptor:


A good place to experiment with USB driver.
You can select any USB driver and try to understand. Even comments are brief and understandable. E.g. you can select omap_udc.c or pxa27x_udc.c
It is good to have look into zero.c driver code which is named as testusb driver and is a good test tool during driver development, works on bulk endpoint.


http://linuxgazette.net/133/tag.html
http://docs.blackfin.uclinux.org/kernel/generated/writing_usb_driver/ch03.html

http://www.embeddedlinux.org.cn/EssentialLinuxDeviceDrivers/final/ch11lev1sec2.html
http://www.lrr.in.tum.de/Par/arch/usb/usbdoc/node18.html

USB Class:
http://www.xat.nl/en/riscos/sw/usb/class.htm

Testing USB Driver:

usbmon in /dev is created for each usb interface at hci layer. It is a provision by kernel which could be used to monitor raw data I/O over the USB bus. usbdump and USBMon uses this device node for monitoring the device traffic. More details could be found at linux document, kernel/Documentation/usb/usbmon.txt.

http://www.sysnucleus.com/usbtrace_download.html #testusb -a
#lsusb -v
#usb-devices

testusb is a good tool. See this link for explanation.
Also work with lsusb(lsusb -v) which will show usb device tree.

Notice here for USB Bluetooth dongle: device descriptor, carrying interfaces and endpoints belonging to each interface.

  • It carries one device descriptor
  • one configuration descriptor(3g modam uses multiple)
  • Four interface descriptor
  • And multiple endpoints (2 to 3 here) for each interface
  • End point carries in or out (and same pipe should be used if you use urbs) and different end point type(again urb pipe will be used accordingly).
  • Here we can see alt setting numbers also(0-1-2-3). Which belongs to one interface.


#usb -v


Bus 003 Device 003: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          224 Wireless
  bDeviceSubClass         1 Radio Frequency
  bDeviceProtocol         1 Bluetooth
  bMaxPacketSize0        16
  idVendor           0x0a12 Cambridge Silicon Radio, Ltd
  idProduct          0x0001 Bluetooth Dongle (HCI mode)
  bcdDevice            1.34
  iManufacturer           0 
  iProduct                0 
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength          108
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       224 Wireless
      bInterfaceSubClass      1 Radio Frequency
      bInterfaceProtocol      1 Bluetooth
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0010  1x 16 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       224 Wireless
      bInterfaceSubClass      1 Radio Frequency
      bInterfaceProtocol      1 Bluetooth
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            1
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0000  1x 0 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            1
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0000  1x 0 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       1
      bNumEndpoints           2
      bInterfaceClass       224 Wireless
      bInterfaceSubClass      1 Radio Frequency
      bInterfaceProtocol      1 Bluetooth
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            1
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0009  1x 9 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            1
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0009  1x 9 bytes
        bInterval               1
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       2
      bNumEndpoints           2
      bInterfaceClass       224 Wireless
      bInterfaceSubClass      1 Radio Frequency
      bInterfaceProtocol      1 Bluetooth
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            1
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0011  1x 17 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            1
          Transfer Type            Isochronous
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0011  1x 17 bytes
        bInterval               1
cannot read device status, Operation not permitted (1)



USB Gadget Driver:

USB gadget driver explains about target USB device(like linux based firmware inside BT dongle or modem).

kernel/Documentation/usb/usbmon.txt

It is worth to work with dummy_hcd driver, which is good starting point with minimum effort.
dummy_hcd virtulizes gadget driver in host machine itself. It creates usb bus interface for gadget side device, and there is no real need of actual device at initial stage of gadget driver development. Once dummy_hcd is installed into the host system, one usb bus entry point could be found at /dev/bus/usb/<bus number>.

gadgetfs is good module ot explore gadget device file system, which work over the hci, and here dummy_hci. Could be used for debugging or communicating application to the driver.

One can start looking at gadget driver by installing any pre-build gadget driver.
Best way is to start working with g_zero driver, which is dependent on dummy_hcd driver and could be used to create virtual endpoint and interface. g_zero could virtulize control in/out and buld in/out endpoint for testing.

To understand device creation, if one installs g_serial gadget driver into the virtual gadget, /dev/ttyGS0 node gets created. Since, we virtual gadget is connected to the host computer, host side USB core immediately recognizes the devices as serial device and loads /dev/ttyACM0 driver in host.
So, /dev/ttyGS0 is node as gadget device, where as /dev/ttyACM0 is node at host side device.
We can see these details, of host side devices, into lsusb, which will not contain gadget devices.

Now this is the time to write our own gadget driver.
Well, lets consider I am interested to write usbtouch screen, an HID device, take a dummy product id and vendor id, registor it to host side usb touchscreen  driver. After fixing the product id and vendor id, lets start developing gadget driver.
Read kernel document, /kernel/Documentation/usb/gadget_serial.txt. This one carry very well explained serial driver information.


---------------------------

Gadget API lower boundery:
handling setup requests (ep0 protocol responses) possibly including class-specific functionality
returning configuration and string descriptors
(re)setting configurations and interface altsettings, including enabling and configuring endpoints
handling life cycle events, such as managing bindings to hardware, USB suspend/resume, remote wakeup, and disconnection from the USB host
managing IN and OUT transfers on all currently enabled endpoints

Upper layer:
user mode code, using generic (gadgetfs) or application specific files in /dev
networking subsystem (for network gadgets, like the CDC Ethernet Model gadget driver)
data capture drivers, perhaps video4Linux or a scanner driver; or test and measurement hardware
input subsystem (for HID gadgets)
sound subsystem (for audio gadgets)
file system (for PTP gadgets)
block i/o subsystem (for usb-storage gadgets)

usb_gadget structure: linux/usb/gadget.h
struct usb_gadget { // represents gadget device
/* readonly to gadget driver */
const struct usb_gadget_ops *ops; // callback for hardware operations
struct usb_ep *ep0;
struct list_head ep_list; /* of usb_ep */
enum usb_device_speed speed;
unsigned is_dualspeed:1;
unsigned is_otg:1;
unsigned is_a_peripheral:1;
unsigned b_hnp_enable:1;
unsigned a_hnp_support:1;
unsigned a_alt_hnp_support:1;
unsigned host_request:1;
const char *name;
struct device dev;
};

Gadget API main functions:

General operations (usb_gadget_x()):
● probe_driver / unregister_driver
● set_selfpowered / clear_selfpowered
● vbus_connect / vbus_disconnect
● connect / disconnect
● frame_number
Endpoint operations (usb_ep_x()):
● autoconf / autoconf_reset
● enable / disable
● alloc / free
● queue / dequeue
● set_halt / clear_halt
● fifo_status / fifo_flush
Decriptor operations:
● usb_descriptor_fillbuf
● usb_gadget_config_buf


http://linuxusbguide.sourceforge.net/USB-guide-1.0.9/book1.html

MMC

MMC card could be used in two mode, mmc mode as preferred mode and SPI as alternate option.
SPI has some limitation in speed of data transfer compare to MMC mode.

This blog shows a very good explanation of how to communicate with MMC hardware controller.
MMC talks with 6 bytes of commands which includes 

[ StartBit - command/dataBit - CommandNumber - CommandArgument - CRCcheck - endBit ]

MMC has a small set of attributes which are read only,


cid Card Identifaction Register
csd Card Specific Data Register
scr SD Card Configuration Register (SD only)
date Manufacturing Date (from CID Register)
fwrev Firmware/Product Revision (from CID Register) (SD and MMCv1 only)
hwrev Hardware/Product Revision (from CID Register) (SD and MMCv1 only)
manfid Manufacturer ID (from CID Register)
name Product Name (from CID Register)
oemid OEM/Application ID (from CID Register)
serial Product Serial Number (from CID Register)
erase_size Erase group size
preferred_erase_size Preferred erase size

Now if we come back to linux, linux has mmc subsystem and lies below the block device layer.


MMC subsystem: 


Block Driver
----------------
MMC Core
----------------
MMC HCI

_________________________________________________________________________

Boot Loader:
U-boot



Other Subsystems:
ALSA
Bluez
WiFi
V4L2

No comments:

Post a Comment