USB OTG on DaVinci

From Texas Instruments Wiki
Jump to: navigation, search


This page describes how to bring up USB On-The-Go for the DM6446 EVM and for the DM355 EVM using the LSP 1.20 kernel and a set of beta patches. For the DM6446 this process further requires some electrical board patches. The operation and visible behaviour of the devices after those change is documented.

Prerequisites

  • TI DaVinci LSP kernel version 1.20.00.014 or later (this is contains the musb_hdrc driver for the Inventra HDRC USB Controller).
  • A DaVinci EVM. Either DM355 or DM6446 rev F. NOTE: If you wish to test this functionality following the procedures below you will need two DaVinci EVMs.
  • A USB mini-A to mini-B cable. Testing was performed using a goldx cable P/N GXQU-06.
  • A root file system where the g_file_storage gadget driver used in testing can be installed. NFS was used during testing.

Limitations

OTG specification requires that the driver (USB Linux Kernel stack + MUSB Controller Driver) communicate several events to the “Application Layer”. MV 2.6.10 kernel lacks infrastructure to communicate OTG events to the “Application Layer”.

Pro v4.0 MV 2.6.10 kernel lacks interface for “Application Layer” to request for USB bus access. This is required in OTG mode to initiate a Device/Host modes from “Application Layer” and to perform role switching.

MUSB Controller driver uses a “/proc” interface to work around the kernel limitation, to expose a interface to the user for requesting USB bus access and to perform role switching. The MUSB driver is tested for OTG functionalities using this interface on the DaVinci platform.

The above mentioned points are the limitations from the USB stack perspective in supporting the full fledged OTG functionality on Davinci platform.

Configuring the EVM Hardware

This section will cover how to configure the DaVinci hardware for USB OTG support.

DM355

On the DM355 there are no hardware modification required for USB OTG. In order to use the DM355 in USB OTG mode jumpers J9 and J10 must be un-jumpered. This allows for the USB ID pin and VBUS to be driven correctly. You can store the removed jumpers on J13.

DM6446

The DM6446 rev F EVM requires the following hardware modifications to enable USB OTG functionality. These modification use GPIO2 to controll the USB VBUS. GPIO2 is pinmuxed with the G0 pin in RGB888 mode. If you want to use RGB888 video then you will need to use a different GPIO for USB VBUS control that GPIO2. You can refer to the Changing the GPIO used for USB OTG section at the end of this article for more information on using a different GPIO pin.

Hardware Modifications

The Hardware modification below are required for USB OTG support to function of the DM6446 EVM. These modifications are valid only for revision F or later of the DM6446 EVM. To check the revision of your EVM check REV field on the bottom of the EVM next to the hard disk drive.

Replace USB Connector

Replace the full size A connector at J10 with a mini-A/B connector.

USB OTG replace connector.jpg
Replace R132

Replace the zero Ohm resistor R132 with a 2-pin jumper. With this jumper C133 can be switched into the circuit to control the VBUS charge/discharge rate in order to meet USB OTG requirements. This jumper should be depopulated for OTG operation and populated for normal operation.

The pictures below will show the new circuit diagram and an example of the EVM modification

Connect DRVVBUSz

Disconnect the USB DRVVBUSz from U15 by lifting and rotating resistor R379 as illustrated. In addition, install a 3-pin jumper with the following connections:

  • Pin 1: Connect to rotated resistor as shown
  • Pin 2: Connect to TP71
  • Pin 3: Connect to GPIO2 (Pin 2 of DC5 connector on the top of the board)

Shorting jumper pins 1&2 enables USB VBUS drive via the I2C IO expander chip (EVM default setup). Shorting pins 2&3 enables USB VBUS drive via GPIO2 (USB OTG setup). The pictures below will show the new circuit diagram and example board modifications.

Jumper Settings

This section covers the jumpers settings used in USB OTG mode as well has how to revert these settings back to the default values.

  • Jumper J7 - This jumper should be set to jumper pins 1&2 for USB OTG mode. When not in USB OTG mode this jumper determines whether the board is a USB host or peripheral as defined in the DM6446 technical reference manual that shipped with the EVM.
  • Jumper Replacing R132 - This jumper is used to control the capacitance used by the USB controller which controls the VBUS charge/discharge rate. For USB OTG mode this jumper should be un-jumpered. For normal EVM operation this jumper should be closed.
  • 3 pin Jumper for GPIO - This jumper is the 3 pin jumper installed on the bottom of the board which can be used to connect the DRVVBUSz line to either GPIO2 or the I2C line. For USB OTG this jumper should be set to use GPIO2. For normal EVM operation this jumper should be set to use I2C.

Creating the Kernel Image

This section will cover patching the kernel for USB OTG support, configuring the kernel for USB OTG, and building the kernel and modules.

Obtaining USB OTG Patches

Currently the USB OTG patches are still in system test and have not been released to the updates site. These patches are listed below in the Beta Patches section. Once these patches are released this section will be updated to their new location.

NOTE: These patches are still listed as Beta and have only undergone basic testing. When the patches are released to the updates site they will have been fully system tested.

DM355

Pending patch release. See Beta Patches for now.

DM6446

Pending patch release. See Beta Patches for now.

Beta Patches

These patches are ones that have gone through basic functionality testing but have not been fully system tested.

  1. Patch 1 - This patch fixes the USB OTG support for DM355 and DM6446 in the LSP 1.20 kernel.
  2. Patch 2 - This patch allows the DM6446 EVM to use GPIO2 instead of the default GPIO3.3V_16 which would cause the ethernet to be disabled.
  3. Patch 3 - This patch fixes a problem with OTG where the device node for the initial peripheral would persist on the initial host after a dynamic role switch.

Applying USB OTG Patches

  1. Download the above patches into a working directory. i.e. /home/user/workdir
  2. gunzip the patches.
    • gunzip *.gz
  3. Copy the LSP 1.20 kernel sources to the working directory.
    • cp -rf <lsp install path> ./ti-davinci
  4. Change directory into the kernel sources directory.
    • cd ti-davinci
  5. Apply the patches using the patch command.
    • patch -p1 < ../lsp_1_20_usb_otg_fixes_012.patch
    • patch -p1 < ../lsp_1_20_usb_otg_dm644x_use_gpio2_for_vbus_013.patch
    • patch -p1 < ../lsp_1_20_usb_otg_disconnect.patch

Configuring the Kernel for USB OTG

In order to configure the LSP 1.20 kernel for USB OTG support the following options must be enabled in the kernel configuration. The following steps will detail how to enable these options using xconfig.

  1. Configure the kernel with the default options first.
    • For DM6446
      • make davinci_dm644x_defconfig
    • For DM355
      • make davinci_dm355_evm_defconfig
  2. Enable Support for USB Gadgets as static and the File-backed Storage Gadget as a module
    Kernel config storage gadget.jpg
  3. Configure the USB Driver Mode to be Both host and peripheral: USB OTG (On The Go) Device
    Kernel config OTG support.jpg
  4. Disable the Rely on OTG Targeted Peripheral List. This is done so that the USB OTG device can talk to any other OTG device. If not you have to add your USB OTG device into the whitelist of devices which is outside of the scope of this page.
    Kernel config disable wl.jpg
  5. Verify the USB Peripheral Controller is set to Inventra (M)HDRC USB Peripheral
    Kernel config periph controller.jpg

Building the Kernel Image

  1. Compile the kernel uImage
    make uImage
  2. Compile the kernel modules (this includes the g_file_storage module)
    make modules
  3. Install the modules to the target file system. In this case it is easiest to install them to an NFS file system
    make modules_install INSTALL_MOD_PATH=<path to nfs>

NOTE: If you are going to build the kernel for both DM355 and DM6446 you will need to install the kernel modules into seperate file system so as not to overwrite the modules from the previous build.

Testing USB OTG Functionality

This section will discuss how to test the USB OTG functionality using two USB OTG enabled EVMs. The EVMs can be DM355, DM6446, or a combination of the two.

Test Configuration

  • One DM6446 to be the initial host
  • One DM355 to be the initial peripheral
  • An NFS target file system for each board
  • A backing file for the g_file_storage module for each board. For more information on how to create a backing file please see the USB File Storage Gadget page.

Initial Setup

  1. Boot both boards using the kernel image created above and an NFS file system with the corresponding modules installed.
  2. Connect the boards with the mini-A to mini-B USB cable. The board on the mini-A side is the initial host (in this case the DM6446) and the board on the mini-B side will be the initial peripheral (in this case the DM355)
  3. Load the g_file_storage module on the peripheral device (you can also load it on the host device at this time). This can be done using the following command assuming the backing file is located at /root/test. Adjust the file arguement accordingly for your setup.
    modprobe g_file_storage file=/root/test
    You should see output similar to
DVEVM# modprobe g_file_storage file=/root/test
g_file_storage gadget: File-backed Storage Gadget, version: 20 October 2004
g_file_storage gadget: Number of LUNs=1
g_file_storage gadget-lun0: ro=0, file: /root/test


Doing Initial Role Negotiation

  1. On the board that is connected to the mini-A side of the cable, which is the initial host (in this case the DM6446) enter the following command to perform initial role negotiation.
    echo i > /proc/driver/otg
    You should see output like the following
HOST OUTPUT PERIPHERAL OUTPUT
DVEVM# echo i > /proc/driver/otg
DVEVM# usb 1-1: new high speed USB device using musb_hdrc and address 2
usb 1-1: Dual-Role OTG device on HNP port
usb 1-1: device v0525 pa4a5 is not supported
scsi0 : SCSI emulation for USB Mass Storage devices
  Vendor: Linux     Model: File-Stor Gadget  Rev: 0316
  Type:   Direct-Access                      ANSI SCSI revision: 02
SCSI device sda: 131072 512-byte hdwr sectors (67 MB)
sda: assuming drive cache: write through
SCSI device sda: 131072 512-byte hdwr sectors (67 MB)
sda: assuming drive cache: write through
 sda: sda1
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0
DVEVM# g_file_storage gadget: high speed config #1

Doing Dynamic Role Switching

  1. If you have not already loaded the file backed storage on the host device (DM6446) do so now.
  2. On the host board (in this case the DM6446) issue the following command to perform a dynamic role switch. This will make the DM6446 a peripheral device and change the DM355 role to host.
    echo s > /proc/driver/otg
    You should see output like the following
HOST OUTPUT PERIPHERAL OUTPUT
DVEVM# usb 1-1: USB disconnect, address 2
g_file_storage gadget: high speed config #1
usb 1-1: new high speed USB device using musb_hdrc and address 2
usb 1-1: Dual-Role OTG device on HNP port
usb 1-1: device v0525 pa4a5 is not supported
scsi0 : SCSI emulation for USB Mass Storage devices
  Vendor: Linux     Model: File-Stor Gadget  Rev: 0316
  Type:   Direct-Access                      ANSI SCSI revision: 02
SCSI device sda: 131072 512-byte hdwr sectors (67 MB)
sda: assuming drive cache: write through
SCSI device sda: 131072 512-byte hdwr sectors (67 MB)
sda: assuming drive cache: write through
 sda: sda1
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0

You can continue to echo s > /proc/driver/otg on whichever device is the host device to cause a role switch

Mounting the File Backed Storage Device

To test that the USB OTG session is properly working you can mount the peripheral device on the host device and perform I/O operations to it.

On the host device do:

  1. Mount the peripheral device. This is the sd device that was printed on the host screen when the session was started. In this example the device is sda.
    mount /dev/sda /mnt
  2. Change directory to the mounted device and view the contents (There will only be contents if you put them there when you created the backing file
    cd /mnt
    ls
  3. Perform I/O by reading and writing to the device. This can be done with the Linux dd command.
    To test the write ability do:
    dd if=/dev/zero of=./test.out bs=1M count=20
    To test the read ability do:
    dd if=./test.out of=/dev/null
  4. Unmount the file system
    cd /
    umount /mnt

If the above steps succeeded then the OTG session is working correctly. You can then switch the roles on the devices and repeat the above steps to verify that the role switching works correctly.

Ending a Session and Restarting

To end a session you must issue the echo e > /proc/driver/otg command from the host device. You should see output like the following on the host device

 DVEVM# echo e > /proc/driver/otg
 otg_timeout 176: No response from B-device

This timeout is expected. However, the device /dev/sda is still present on the system even though the session has ended. You should not try to access this device node as there is not real device present. This will be fixed in a future release.

If you wish to restart the session you can do initial role negotiation again and the session will be restarted.

Changing the GPIO used for USB OTG

NOTE: These steps only apply to the DM6446 EVM as the DM355 EVM does not require modifications for USB OTG support.

If for some reason you do not want to use GPIO2 (i.e. you need RGB888 video output) it is possible to use other GPIOs for the USB DRVVBUSz signal. There is already code present in the driver to allow the use of 3.3V GPIO16.

Limitations

Using the 3.3V GPIO16 will cause the ethernet to become inoperative when USB OTG in enabled due to the pinmuxing of the EMAC pins and GPIO3.3V_16.

Change in Hardware Modifications

The only change in the hardware modifications required is in the Connect DRVVBUSz step. Instead of connecting pin 3 to pin 2 of the DC5 connector on the top of the board it should be connected to TP72.

Change in USB Driver

The files <TI kernel dir>/drivers/usb/musb/davinci.c and <TI kernel dir>/drivers/usb/musb/davinci.h will need to be modified to use GPIO3.3V_16 rather than GPIO2. The easiest way to do this is to unapply the lsp_1_20_usb_otg_dm644x_use_gpio2_for_vbus_013 patch. If not you can use the patch as a reference and comment out the GPIO2 code and uncomment the GPIO3.3V_16 code.

Change in Kernel Configuration

In the kernel configuration for DM6446 you will need to disable the TI DaVinci EMAC Support. This is located under Networking support -> Ethernet (10 or 100Mbit) -> TI DaVinci EMAC Support