I've started to outline some stuff of the manual and wrote a nice page with sdcc- examples:
I'm going to introduce the stuff i did with the an2131 from cypress.
There were some problems for me at the beginning because linux pages about this are a bit rare.
Ok, surely you'll need a board - the question is where from.
Since the an2131 is quite cheap (about 3-6€) and many available boards are too expensive, i've started with creating a low cost board.
Using the an2131 is quite easy. - I've only used some resistors, capacitors, an oscillator and for generating the 3.3V supply a voltage regulator.
The 3.3V are quite helpful when your usb-device need's a lot of power. As you know, when consuming more power the voltage decreases.
USB has a 5V supply, so there is enough room until 3.3V.
Here is a complete part-list of my device:
part name | count |
---|---|
an2131 | 1 |
capacitor, 100nF | 5 |
capacitor, 15pF | 4 |
white smd led | 1 |
oscillator,12MHz | 1 |
i2c eeprom, 24C02 | 1 |
resistor, 2k2 | 2 |
resistor, 10k | 1 |
connector, RM2 2rows, each 10 pins | 2 |
As your can see, the whole thing is cheaper than 10€ but a warning at this point - all parts are SMD and it's a 2 layer layout.
Maybe you'd like to browse the whole folder here: browse
In fact, there are two good ways for writing firmware.
I prefer assembly language, which is quite easy because the ez-usb core is a modified 8051.
With a 12MHz oscillator you'll get 24MHz clock rate. And in contrast to normal 8051, the ezusb uses only 3 clocks and not 12 for 1 cycle.
I used as31 for assembly, i found it on http://www.cn.stir.ac.uk/linux-daq/as31/. Well, it had some error's in code - I've made some changes, see AS31 for details.
You can test it with my led-rotation example.
Another great way for coding is C, visit http://sdcc.sf.net.
The most important thing is, that you have to upload firmware after each reset of the device cos youre just downloading into the ez-usb ram.
I've used a kernel module written by Tony Cureington first, see EZ-USB Firmware-Downloader. It worked very well and contain's some good examples, even in C and some stuff for bulk transfers via usermode.
I was a bit disgusted that this module claims my interface, so any other access is only possible after reenumeration and that's why I'm using fxload now.
After firmware upload CPUCS is reseted and maybe reenumeration started.
Here is an example:
C1VE root # fxload -D $(getdevpath -v 0547 -p 2131) -I world_domination.hex C1VE root # _
Maybe you need getdevpath - I've downloaded it somewhere from http://www.cypress.com.
I've copied it to /usr/bin and did a chmod +x. Not sure, perhaps I'll wirte a clone in C.
It took me quite a while for getting some endpoint zero call's working. So first of all many thanks to Tony Cureington and Tom De Rybel! If you don't know what exactly I'm talking about, read chapter 7 of ez-usb manual.
Let's start usb-robot-slave and connect it to the first device with an an2131.
C1VE root # usb-robot-slave vendor=0x0547 product=0x2131 usb-robot-slave: starting usb-robot version 0.2.0 (c) 2000, 2001 John Fremlin Licensed under the GNU Public License version 2, see file COPYING. You didn't pay me for this program. You have no rights. doing bus scan for: idVendor 0x547 idProduct 0x2131 found bus 001 scanning bus 001 found device 007 on bus 001 (idVendor 0x547 idProduct 0x2131) opening device 007 on bus 001 OK: id=0 Type help and press return for a list of commands usb-robot> _
By the way, the interface is not claimed yet, so firmware upload is still possible. Now some setups.
usb-robot> encoding hex Output format changed to hex OK: id=1 usb-robot> decoding hex Input format changed to hex OK: id=2 usb-robot> _
You can read up to 1024 via VENDOR_REQUEST_IN.
“value” contains your address offset (starting at 0x0000) and “size” (up to 1024) tells how mutch to read.
usb-robot> transfer type=control ep=0 dir=in requesttype=0xc0 request=0xa0 value=0x7f9a index=0x00 size=2 doing control message id 18 from device, size 2, timeout 10000 frames, c0:a0:7f99:0 DATA: id=18 length=2 0000: 00 01 OK: id=18 usb-robot> _
usb-robot> transfer type=control ep=0 dir=in requesttype=0xc0 request=0xa0 value=0x7f9a index=0x00 size=2 doing control message id 17 from device, size 2, timeout 10000 frames, c0:a0:7f99:0 DATA: id=17 length=2 0000: 00 02 OK: id=17 usb-robot> _
As you can see, register 0x7f9b changed -that's PINSC.
Ok, the next one use VENDOR_REQUEST_OUT.
As far as i know it's only possible to read 1 byte per packet -so “size” is everytime 1.
0x7f92 is CPUCS, that means 0x01 here stops our ez-usb (you can still read and write through ep0!) CPU, 0 means resuming.
When you've uploaded the LED example mentioned before, you can watch the light stop after this call.
usb-robot> transfer type=control ep=0 dir=out requesttype=0x40 request=0xa0 value=0x7f92 index=0 size=1 Enter data in format FF FB 00 FC 01 doing control message id 12 to device, size 1, timeout 10000 frames, 40:a0:7f92: 0 OK: id=12 usb-robot> _
And resume after this one.
usb-robot> transfer type=control ep=0 dir=out requesttype=0x40 request=0xa0 value=0x7f92 index=0 size=1 Enter data in format FF FB 00 FC 00 doing control message id 12 to device, size 1, timeout 10000 frames, 40:a0:7f92: 0 OK: id=13 usb-robot> _
Kewl, eh?
Writing is not possible to all registers, for example OUTA,OUTB,OUTC doesn't work.
For this stuff you'll need some lines in your firmware.
I used 0x000a for caching, see 0x000atoOUTC.asm. Writing work's with these lines:
mov dptr, #0x000ah movx a,@dptr mov dptr, #OUTC movx @dptr, a
usb-robot> transfer type=control ep=0 dir=out requesttype=0x40 request=0xa0 value=0x000a index=0 size=1 Enter data in format FF FB 00 FC ff doing control message id 3 to device, size 1, timeout 10000 frames, c0:a0:a:0 OK: id=3 usb-robot> _
2004-2005 © Alexander 'E-Razor' Krause