I have managed to enable the device side USB port, using some spare bits from a dead Epson printer and some old power supplies. any EE's in the crowd will cringe when they see this, as I have made no attempt to impedance match any of the circuit, and violate the USB protocol by not having the pull-up under software control. that said, this does work just fine, and I have used the NSLU2 as a mass-storage device (it pretends to be a flash drive) back to my Linux box.
Background
USB has 4 wires, 5V, D-, D+, and ground. the D (data) lines are a differential pair, like 10Base-T ethernet uses, but unlike ethernet which has separate TX and RX pairs (enabling full duplex), USB has one pair. The host (PC) initiates all transactions on this pair to avoid collisions. The standard type-A ports on the NSLU2 are host side ports. we are adding a device side port, which will enable the NSLU2 to show up as an external hardrive or even a networking or serial device, when plugged into a PC (or other NSLU2!)
USB 1.1 spec says that any device running at full speed (12Mb/s) should have a pullup resistor between the D+ line and a source of 3.0V to 3.6V. This source must be derived from the 5V line in the USB cable, and not from the power supply of the device itself. we use a simple divider network.
You will need
- Three 1/8th watt resistors (15K, 1.5K, and 1K)
- Two lengths of fine (~20 gauge or less) multi-strand wire, 5 inches each.
- Female USB type-B connector (the square one, surface mount is fine)
Installation
- Install port
I scuffed the side of the new USB port and the side of the ethernet port with sandpaper, then used superglue to attach the port, right over the crystal can Y1. I even used a bit of glue on top of that crystal too. make the face of the port flush with the ethernet port. Let it set. Cut a square out of the back plastic housing, removing all of the word ethernet.
- Ground port
Then use a bit of solder to make sure the shield of the USB port is grounded to the ethernet port's shield. use flux. If you cant bridge the gap cause you got crazy with the superglue, add a bit of wire.
- Ground pin 4
Bend the back of pin 4 so that it touches the shield, and solder it. Mine had a convenient tab for surface mounting, that I rolled inwards to reach the pin.
- Add resistors
Solder 1K resistor to pin 1, 15K resistor to pin 4 or shield ground, and 1.5K resistor to pin 3. All the resistors should stick out in the same direction. Solder the other end of all three of them together. this little 'tripod' will provide ~3.5 volts to the D+ pin (#3) whenever the cable is connected to a powered-on host, even if the NSLU2 is OFF.
- Remove SMD resistors
We have to get R130 and 131 off the back of the board. easiest way is with a forked-tip soldering iron. I don't have one :) The next easiest way involves desoldering wick. I ran out :) So, get yourself a bit of thin stranded wire, dip the tip in flux, put it on one end of the resistor, and press down on wire with soldering iron. you should see solder 'wick' up the wire. Use fresh wire at all four joints. be careful to pull the wire away while the solder is still hot, not after it has cooled. Now, while the resistor is still hot, put your iron down against one end of the resistor, wait a second, and push. it should slide off.
- Add wire
We are going to connect pin 2 to the left side of where R130 was. do not bridge over to the right side accidentally. It won't work, and it might burn out the driver in the CPU. connect pin 3 (same place the resistor connects) to left side of R131. Don't bridge it either. Keep those wires as short as possible, and the same length (± 1/4 inch).
- Software
I used the crosstool instructions on the wiki to build a compiler. then I used the newest testing release of uCLinux-dist to build a 2.4 kernel and ramdisk. I had to modify the file drivers/USB/gadget/pxa2xx_udc.c before compiling, because that kernel (2.4.27) did not know the IXP420.
Down around line 2420:
default:
out_dma = 0;
printk(KERN_ERR "%s: unrecognized processor: %08x\n",
driver_name, chiprev);
return -ENODEV;
becomes:
default:
out_dma = 0;
printk(KERN_ERR "%s: unrecognized processor: %08x\n",
driver_name, chiprev);
break;
Make sure to enable the USB gadget stuff, especially the Intel pxa2xx_udc driver.
- Load
Put the kernel and ramdisk on your TFTP server and load them from RedBoot. you should see a message during bootup 'unrecognized processor: 690541f1' don't have the USB cable plugged in during this.
- Make file
On the NSLU2 type 'dd bs=1k if=/dev/zero of=/foo.fs count=512' then 'insmod /lib/modules/2.4.27-uc0/kernel/drivers/USB/gadget/g_file_storage.o file=/foo.fs' (all on one line). this makes a 512KB file with nothing in it, and tells the gadget driver to make that file available via the mass storage interface.
- Connect
Plug in the new port into your PC. it should show up as a SCSI device on linux, though it will have no partition table or FS. you can add them now from the PC side. 'fdisk /dev/sda', 'mkdosfs /dev/sda1', 'mount /dev/sda1 /mnt/flash', etc.
You can unmount/disconnect cable, then reconnect cable/remount, and the files will still be there. if you have an attached disk, you can make foo.fs on it instead, or even use the disk partition directly, I suppose.
Known bugs
The pullup on D+ should not be connected if the device is not ready to answer enumeration setup packets. to do this right, we have to connect a GPIO pin to control a flipflop or transistor between D+ and the resistor, and have the GPIO pin go off after the gadget driver is loaded. we are out of such pins, so you have to remember to re-plug the NSLU2 after it has booted.
enjoy.
allan
Please note that Device Side USB is not currently supported in any 2.6 kernel on the NSLU2 up to and including 2.6.18. There is a possibility that support will be included in a later kernel. However, due to the lack of a spare GPIO pin, I don't think that this will ever be anything other than a clever hack on the NSLU2. Sorry, blaster8
:could you use an I2C? chip of some sort to get an io line? -- plugwash
@plugwash - I'd love it if we could since I'm working on a project that needs the device side USB. You can do all of Allan's instructions, but you'll have to use uClinux because, as blaster8 said...there's no support for the PXA2xx? USB gadget drivers on 2.6.x kernels...believe me...I'VE TRIED! You will need to download and compile uClinux with the 2.4.x kernel (make sure to select this when running xconfig, or you will get 2.6. I had this working once but lost my source files and had to rebuild...it isn't working for me right now. -- NeoMatrixJR?