USB Host

From wiki.gp2x.org
GP2X Wikipedia.jpgThis page needs to be cleaned up.
This page should include some information for more non-technical users who want to attach USB devices to the GP2X

Contents

Introduction

The EXT Port contains pins to allow the GP2x to act as a USB Host.
I.e. you can connect a Mouse / Keyboard / USB Hard Disk etc. etc.

I will try to document exactly what I have done to make this appear in the boot log:

hub.c: new USB device 1, assigned address 2
Manufacturer: Cypress Semiconductor
Product: USB2.0 Storage Device
SerialNumber: DEF106207355
scsi0 : SCSI emulation for USB Mass Storage devices
  Vendor: IC35L040  Model: AVVN07-0          Rev:  0 0
  Type:   Direct-Access                      ANSI SCSI revision: 02
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0
SCSI device sda: 80418240 512-byte hdwr sectors (41174 MB)
Partition check:
 /dev/scsi/host0/bus0/target0/lun0: p1

Full log at the bottom.

Buy a Cable

See http://www.artaylor.co.uk/gp2x/ to purchase, for instructions and downloads.

Developers

A Modified, better U-Boot (and source) is available at http://www.artaylor.co.uk/gp2x/dev/u-boot.html
Until we move over to svn at http://open2x.sourceforge.net

Hardware

This has reduced significantly from my initial version!

Now:

- A GP2x <--> USB Cable with +5v external source
- USB Hard Disk

USB Host Cable

See http://www.artaylor.co.uk/gp2x/

Break Out Board

This is the bit that takes the time to build. the scope picture shows what happens when you don't terminate USB correctly!

Art103 breakout.png USB Scope.png

The important thing to note is that USB requires +5V on the VUSB line. This allows the device that you are connecting to pull the D+ line high, letting the host know it is there.

Schematic

USB_Host_BoB_Schematic

Software

I followed the Building_a_Custom_Kernel Information to build myself a kernel, and convert it to the correct format for u-boot.

After some messing around, and by using torpor's kernel config, I came up with a working config.

USB_Kernel_Config.txt Copy this to .config in the root of the kernel source tree, then follow the link above.

I modified the u-boot that we have source for to bypass the copy out of NAND. This is so that we don't over-write the u-boot loaded in via JTAG.

Update: The U-Boot modification is no longer required - the shipped u-boot disables the clocks to the USB Host controller, so a simple mod in "drivers/usb/host/usb-ohci-mmsp2.c" is required.

static void __init mmsp2_ohci_configure(void)
{
        unsigned long fclk = mmsp2_get_fclk();
        unsigned long aclk = mmsp2_get_aclk();
        unsigned long uclk = mmsp2_get_uclk();
        unsigned long f_fact = fclk / DESIRED_CLOCK;
        unsigned long a_fact = aclk / DESIRED_CLOCK;
        unsigned long u_fact = uclk / DESIRED_CLOCK;
        unsigned long f_clk = (fclk / f_fact);
        unsigned long a_clk = (aclk / a_fact);
        unsigned long u_clk = (uclk / u_fact);
        unsigned long f_err = abs(DESIRED_CLOCK - f_clk);
        unsigned long a_err = abs(DESIRED_CLOCK - a_clk);
        unsigned long u_err = abs(DESIRED_CLOCK - u_clk);

        printk("f_fact = %ld, f_clk = %ld, f_err = %c%ld\n",
                        f_fact, f_clk, f_clk > DESIRED_CLOCK ? '+':'-', f_err);
        printk("a_fact = %ld, a_clk = %ld, a_err = %c%ld\n",
                        a_fact, a_clk, a_clk > DESIRED_CLOCK ? '+':'-', a_err);
        printk("u_fact = %ld, u_clk = %ld, u_err = %c%ld\n",
                        u_fact, u_clk, u_clk > DESIRED_CLOCK ? '+':'-', u_err);

        /* Enable the USB Host Controller Clocks */
        COMCLKEN |= 0x01;

        /* from EBOOT */
        UIRMCSET &= 0xff00;
        UIRMCSET |= ((0x02) << 6) | 1;

        gpio_pad_select(USB_PAD_3T, 0);         // PAD3 --> USB host
        gpio_pad_select(USB_PAD_1T, 0);         // PAD1 --> USB host
#ifdef CONFIG_MMSP2_UPAD3_TO_DEVICE
        gpio_pad_select(USB_PAD_3T, 1);         // PAD3 --> USB device
        gpio_pad_select(USB_PAD_1T, 0);         // PAD1 --> USB host
#endif

        udelay(11);
}


static void __exit mmsp2_ohci_exit(void)
{
        /* Disable the USB Host Controller Clocks */
        COMCLKEN &= ~(0x01);

        hc_remove_ohci(mmsp2_ohci);
}

The Process

Copy your custom modules to SD Card.
Connect either: your power supply to the break out board (for +5V USB).
OR your USB self powered cable.
Connect your USB client (HDD etc).
Power on your GP2x.
Log into the GP2x via the serial cable.
Manually insmod the modules from your SD card (the order is important - script to follow).

Sit back an watch the USB connect

Full Boot Log

Full boot log with mp3 playback from external HDD:




U-Boot 1.0.0 (Jan 16 2006 - 12:26:05)

U-Boot code: 03F00000 -> 03F6A648  BSS: -> 03FA3074
DRAM Configuration:
Bank #0: 00100000 63 MB
Flash:  0 kB
NAND:Probing at 0x9c000000
Flash chip found:
	 Manufacturer ID: 0xEC, Chip ID: 0x76 (Samsung K9F1208 64Mb)
1 flash chips found. Total nand_chip size: 64 MB
Get Environment from NAND offset 0x70000 ... 
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial

SD found : SD Frequency is 2MHz
DATA:finish=0x20
dat error
(with MBR)

UPDATE ...
BOOT UPDATE ----------------------------
reading gp2xboot.img

** Unable to read "gp2xboot.img" from mmc 0:1 **
1 : g_filesize 0
gp2xboot.img not found
KERNEL UPDATE ----------------------------
reading gp2xkernel.img

** Unable to read "gp2xkernel.img" from mmc 0:1 **
2 : g_filesize 0
gp2xkernel.img not found
FILE UPDATE ----------------------------
reading gp2xfile.img

** Unable to read "gp2xfile.img" from mmc 0:1 **
3 : g_filesize 0
gp2xfile.img not found
### main_loop: bootcmd="nand read 0x1000000 0x80000 0x180000; bootm"
Hit any key to stop autoboot:  0 

NAND read: device 0 offset 0x80000, size 0x180000 ...  1572864 bytes read: OK
## Booting image at 01000000 ...
   Image Name:   My Custom Kernel
   Created:      2006-02-07  23:31:33 UTC
   Image Type:   ARM Linux Kernel Image (gzip compressed)
   Data Size:    889219 Bytes = 868.4 kB
   Load Address: 00008000
   Entry Point:  00008000
   Verifying Checksum ... OK
   Uncompressing Kernel Image ... OK

Starting kernel ...

Uncompressing Linux.............................................................. done, booting the kernel.
Linux version 2.4.25 (art103@#gp2xdev) (gcc version 2.95.3 20010315 (release)) #47 Tue Feb 7 23:31:04 GMT 2006
CPU: Arm920Tid(wb) revision 0
Machine: MagicEye-MDK
Warning: bad configuration page, trying to continue
MP2520F FCLK: 199065600 Hz, M = 0x49 P = 1 S = 0
MP2520F UCLK:  95846400 Hz, M = 0x60 P = 0 S = 2
MP2520F ACLK: 147456000 Hz, M = 0x98 P = 0 S = 2
MP2520F PCLK:  49766400 Hz
On node 0 totalpages: 8192
zone(0): 8192 pages.
zone(1): 0 pages.
zone(2): 0 pages.
Kernel command line: root=/dev/mtdblock3 rw
Console: colour dummy device 80x30
Calibrating delay loop... 99.32 BogoMIPS
Memory: 32MB = 32MB total
Memory: 30280KB available (1156K code, 610K data, 284K init)
Dentry cache hash table entries: 4096 (order: 3, 32768 bytes)
Inode cache hash table entries: 2048 (order: 2, 16384 bytes)
Mount cache hash table entries: 512 (order: 0, 4096 bytes)
Buffer cache hash table entries: 1024 (order: 0, 4096 bytes)
Page-cache hash table entries: 8192 (order: 3, 32768 bytes)
CPU: Testing write buffer: pass
POSIX conformance testing by UNIFIX
Linux NET4.0 for Linux 2.4
Based upon Swansea University Computer Society NET3.039
mmsp2_usbh.c: initializing MMSP2 USB host PCI-DMA workaround
mmsp2_usbh.c: Communication Reg Value = 0x00000115 
Starting kswapd
devfs: v1.12c (20020818) Richard Gooch (rgooch@atnf.csiro.au)
devfs: boot_options: 0x1
JFFS2 version 2.2. (NAND) (C) 2001-2003 Red Hat, Inc.
i2c-core.o: i2c core module version 2.6.1 (20010830)
i2c-dev.o: i2c /dev entries driver module version 2.6.1 (20010830)
I2C: MMSP2 algorithm module loaded.
 <6>I2C: Adding MMSP2-I2C-Adapter.
I2C: Successfully added bus
ttyS0 at MMIO 0xc0001200 (irq = 48) is a MMSP2
ttyS1 at MMIO 0xc0001220 (irq = 52) is a MMSP2
ttyS2 at MMIO 0xc0001240 (irq = 56) is a MMSP2
IRQ_DISP Number = 0 
Console: switching to colour frame buffer device 40x30
MMSP2 mmsp2_RGB0 framebuffer driver start
MMSP2 mmsp2_RGB1 framebuffer driver start
MMSP2 DualCPU Interface Driver
MMSP2 Video Post Processor Driver
 register device MMSP2 GPIO KEY OK
MMSP2 Real Time Clock driver
RAMDISK driver initialized: 16 RAM disks of 4096K size 1024 blocksize
SCSI subsystem driver Revision: 1.00
kmod: failed to exec /sbin/modprobe -s -k scsi_hostadapter, errno = 2
kmod: failed to exec /sbin/modprobe -s -k scsi_hostadapter, errno = 2
ac97_codec: AC97 Audio codec, id: WML18 (Wolfson WM9711/9712)
mp2520f.c: Using NAND S/W ECC
NAND device: Manufacturer ID: 0xec, Chip ID: 0x76 (Samsung NAND 64MiB 3,3V 8-bit)
Creating 5 MTD partitions on "NAND 64MiB 3,3V 8-bit":
0x00000000-0x00080000 : "Bootloader"
0x00080000-0x000a0000 : "Param"
0x000a0000-0x001a0000 : "Kernel"
0x001a0000-0x019a0000 : "Filesystem"
0x019a0000-0x04000000 : "Extend"
usb.c: registered new driver usbdevfs
usb.c: registered new driver hub
f_fact = 4, f_clk = 49766400, f_err = +1766400
a_fact = 3, a_clk = 49152000, a_err = +1152000
u_fact = 1, u_clk = 95846400, u_err = +47846400
host/usb-ohci.c: USB OHCI at membase 0xf0004300, IRQ 13
usb.c: new USB bus registered, assigned bus number 1
Product: USB OHCI Root Hub
SerialNumber: f0004300
hub.c: USB hub found
hub.c: 3 ports detected
Initializing USB Mass Storage driver...
usb.c: registered new driver usb-storage
USB Mass Storage support registered.
MMC/SD Slot initialized
NetWinder Floating Point Emulator V0.97 (double precision)
FAT: bogus logical sector size 65535
FAT: bogus logical sector size 65535
SD Detceted
Partition check:
 mmcsda:<7>hub.c: port 1, portstatus 101, change 1, 12 Mb/s
 p1
Register SD 982MB
hub.c: new USB device 1, assigned address 2
Manufacturer: Cypress Semiconductor
Product: USB2.0 Storage Device
SerialNumber: DEF106207355
scsi0 : SCSI emulation for USB Mass Storage devices
  Vendor: IC35L040  Model: AVVN07-0          Rev:  0 0
  Type:   Direct-Access                      ANSI SCSI revision: 02
Attached scsi disk sda at scsi0, channel 0, id 0, lun 0
SCSI device sda: 80418240 512-byte hdwr sectors (41174 MB)
 /dev/scsi/host0/bus0/target0/lun0: p1
hub.c: new USB device 2, assigned address 3
usb.c: USB device not accepting new address=3 (error=-110)
hub.c: new USB device 2, assigned address 4
usb.c: USB device not accepting new address=4 (error=-110)
jffs2_scan_eraseblock(): Node at 0x0142c1fc {0x1985, 0xe001, 0xe0021985) has invalid CRC 0x00000044 (calculated 0x515918d5)
Inode #27 was a directory with children - removing those too...
VFS: Mounted root (jffs2 filesystem).
Mounted devfs on /dev
Freeing init memory: 284K
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
 
INIT:  version 2.84 booting 

<7>hub.c: port 1, portstatus 103, change 0, 12 Mb/s
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
 Started device management daemon v1.3.25 for /dev
<7>hub.c: port 3, portstatus 301, change 2, 1.5 Mb/s
Mount proc and devpts filesystem
mount: Mounting none on /dev/pts failed: No such file or directory
Expand RAM file system image
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?

INIT: Entering runlevel: 3

Last login: Thu Jan  1 00:00:19 on ttyS0
-t and -C not supported
MSDOS FS: IO charset utf8
rm: cannot remove `/mnt/sd/gp2xboot.img': No such file or directory
rm: cannot remove `/mnt/sd/gp2xkernel.img': No such file or directory
rm: cannot remove `/mnt/sd/gp2xfile.img': No such file or directory
mtd->read(0x985 bytes from 0x4682b0) returned ECC error
-t and -C not supported
-t and -C not supported
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
SDL_SYS_JoystickInit
LOAD_LCD_TIMING: 8
GET_LCD_TIMING: -1
EXIT
[root@Linux gp2x]$hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
mount /dev/sda1 /mnt/nand
VFS: Can't find ext2 filesystem on dev sd(8,1).
[root@Linux gp2x]$/usr/gp2x/gp2xmenu � �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� �� ���mount
rootfs on / type rootfs (rw)
/dev/sda on / type jffs2 (rw)
none on /dev type devfs (rw)
/proc on /proc type proc (rw)
/dev/discs/disc0/part1 on /mnt/sd type vfat (rw)
/dev/sda1 on /mnt/nand type msdos (rw)
[root@Linux gp2x]$df
Filesystem           1k-blocks      Used Available Use% Mounted on
rootfs                   24576     10048     14528  41% /
/dev/sda                 24576     10048     14528  41% /
/dev/discs/disc0/part1   1003976    623664    380312  62% /mnt/sd
/dev/sda1             40192800  36039200   4153600  90% /mnt/nand
[root@Linux gp2x]$/usr/gp2x/gp2xmenu 
SDL_SYS_JoystickInit
LOAD_LCD_TIMING: 8
GET_LCD_TIMING: -1
VK_DOWN_RIGHT	
VK_RIGHT		
VK_DOWN_RIGHT	
VK_RIGHT		
VK_TAT			
SDL_SYS_JoystickInit
EEPROM READ volume : 40
EEPROM READ EQ : 0
bpp = 16, linelen = 640
0 FBMMSP2CTRL rt msg = 1000, size = 0
prect->xoff = 0
prect->yoff = 0
prect->w    = 320
prect->h    = 240
graphic device initialize done
screen device open success: pixelvalue = 2
psd->xres = 320, psd->yres = 240, psd->linelen = 320
init draw text context
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: new USB device 3, assigned address 5
usb.c: USB device not accepting new address=5 (error=-110)
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: new USB device 3, assigned address 6
usb.c: USB device not accepting new address=6 (error=-110)
hub.c: Cannot enable port 3 of hub 1, disabling port.
hub.c: Maybe the USB cable is bad?
hub.c: new USB device 3, assigned address 7
usb.c: USB device not accepting new address=7 (error=-110)
hub.c: new USB device 3, assigned address 8
usb.c: USB device not accepting new address=8 (error=-110)
OnPlay()
play file name : /mnt/nand/mp3s/apollo~1/apollo~1.mp3
Audio file detected.
Clip info:
 Title: Crazee Horse                  
 Artist: Apollo 440                    
 Album: Gettin' High on Your Own Suppl
 Year:     
 Comment:                               
 Genre: Pop
========================================================================
Opening audio decoder: [libmad] libmad mpeg audio decoder
AUDIO: 44100 Hz, 2 ch, 16 bit (0x10), ratio: 6000->176400 (48.0 kbit)
Selected audio codec: [mad] afm:libmad (libMAD MPEG layer 1-2-3)
========================================================================
Checking audio filter chain for 44100Hz/2ch/16bit -> 44100Hz/2ch/16bit...
AF_pre: af format: 2 bps, 2 ch, 44100 hz, little endian signed int 
AF_pre: 44100Hz 2ch Signed 16-bit (Little-Endian)
ao_data_buffer size = 524288, 262144/o_bps = 1.486077


Building audio filter chain for 44100Hz/2ch/16bit -> 44100Hz/2ch/16bit...
Video: no video
Starting playback...

==============================
Total Playing Time: 00:08:23
==============================

g_eq 0
#### leftVol 40
Personal tools