Editing Linuxstamp

Jump to navigation Jump to search

Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

The edit can be undone. Please check the comparison below to verify that this is what you want to do, and then save the changes below to finish undoing the edit.

Latest revision Your text
Line 1: Line 1:
 
[[Image:linuxstamp_top_02.jpg]]
 
[[Image:linuxstamp_top_02.jpg]]
 +
== Status ==
 +
You can now purchase Linuxstamp boards from [http://thelinuxstamp.com/shop/catalog/browse?shop_param= thelinuxstamp.com]
  
 
== Description ==
 
== Description ==
 
The Linuxstamp is designed to be a general purpose processor module. It is designed to work as a stand alone module (SD card, Ethernet and USB/Serial converter are all on the module). This allows all initial development to be done without a motherboard, but for integration into a specific project a motherboard with specific features could be designed. Check out the start of the first mother board for the Linuxstamp, [http://opencircuits.com/Linuxstamp_Mboard_1 Mboard 1].
 
The Linuxstamp is designed to be a general purpose processor module. It is designed to work as a stand alone module (SD card, Ethernet and USB/Serial converter are all on the module). This allows all initial development to be done without a motherboard, but for integration into a specific project a motherboard with specific features could be designed. Check out the start of the first mother board for the Linuxstamp, [http://opencircuits.com/Linuxstamp_Mboard_1 Mboard 1].
 
== Status ==
 
You can now purchase Linuxstamp boards from [http://thelinuxstamp.com/shop/catalog/browse?shop_param= thelinuxstamp.com]
 
  
 
== Features ==
 
== Features ==
Line 24: Line 23:
 
== Hardware design files ==
 
== Hardware design files ==
 
Warning!!! Use this design at your own risk.
 
Warning!!! Use this design at your own risk.
* [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=linuxstamp_design.zip Project zip file]
+
* [http://datasrv04.webmatrix.com.br/symphony/Linuxstamp_120.zip Project zip file]
* [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=linuxstamp121-sch.pdf Schematic]
+
* [http://datasrv04.webmatrix.com.br/symphony/pdfs/linuxstamp120-sch.pdf Schematic]
* [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=linuxstamp121-top.pdf Top layer]
+
* [http://datasrv04.webmatrix.com.br/symphony/pdfs/linuxstamp120-top.pdf Top layer]
* [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=linuxstamp121-bottom.pdf Bottom layer]
+
* [http://datasrv04.webmatrix.com.br/symphony/pdfs/linuxstamp120-bottom.pdf Bottom layer]
If you want to use the Linuxstamp for your project you can get an Eagle library file [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=linuxstamp.lbr here]
 
or just an image [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=headers.PNG here]
 
  
 
== Power ==
 
== Power ==
Line 38: Line 35:
  
 
When you plug the Linuxstamp into your host (Linux) machine a device should appear '''/dev/ttyUSB0''' (I think the postfix number will increment as you add more devices). '''/dev/ttyUSB0''' will behave as any other serial port now. '''Minicom''' is the standard program to access the serial port in Linux. The first time you run minicom you will have to be root in order to do the setup, after that you can change the permissions on /dev/ttyUSB0 so any user can run minicom. To enter configuration mode in minicom type '''CTRL-A o''', now scroll down to '''Serial port setup'''. Use the letters to navigate. You will want the device to be '''/dev/ttyUSB0''' and '''Bps/Par/Bits''' to read '''115200 8N1'''. Both hardware and software flow control should be OFF. Connection to the board is important for loading Atmel's tiny program and u-boot, but once the board is working it might not be as important.
 
When you plug the Linuxstamp into your host (Linux) machine a device should appear '''/dev/ttyUSB0''' (I think the postfix number will increment as you add more devices). '''/dev/ttyUSB0''' will behave as any other serial port now. '''Minicom''' is the standard program to access the serial port in Linux. The first time you run minicom you will have to be root in order to do the setup, after that you can change the permissions on /dev/ttyUSB0 so any user can run minicom. To enter configuration mode in minicom type '''CTRL-A o''', now scroll down to '''Serial port setup'''. Use the letters to navigate. You will want the device to be '''/dev/ttyUSB0''' and '''Bps/Par/Bits''' to read '''115200 8N1'''. Both hardware and software flow control should be OFF. Connection to the board is important for loading Atmel's tiny program and u-boot, but once the board is working it might not be as important.
 +
<br><br>
  
The default installation of minicom does not automatically include the XModem file transfer module 'sx' which you will need to send files.  It is part of the Linux package named lrzsz ([http://packages.debian.org/lenny/lrzsz lrzsz]).  Just type 'sx' at a command line to see if it is installed.  If not, install the lrzsz package and minicom will find and use 'sx' automatically.
+
XModem transfers between Minicom and U-Boot seem to work fine. This means that you can update U-Boot itself as well as the kernel and root file systems using Minicom. However, the built in xmodem in minicom does not seem to work with the hardware bootloader in the AT91RM9200. If you see "Retry 0: NAK on Sector", you have likely hit this problem. The folks at [http://www.koansoftware.com/it/art.php?art=68 Koan] have created a workaround. The one thing you have to do is edit the .c file for the proper serial port ttyUSB0 in my case. (This link does not seem to work any more, does someone have an alternate?)
 
 
XModem transfers between Minicom and U-Boot seem to work fine. This means that you can update U-Boot itself as well as the kernel and root file systems using Minicom after getting U-Boot itself installed via the built-in hardware bootloader in the AT91RM9200.  The bootloader is much more finicky than U-Boot itself, so getting U-Boot installed can be tricky.  Here is my technique:
 
 
 
* Connect the USB cable to LinuxStamp and start minicom from a terminal window.
 
* Boot the LinuxStamp.  You should see CCC... on the minicom console, with a new C every second or two.
 
* Hit Enter twice.  This will stall the bootloader, and the CCC... sequence will stop.  It will also synchronize the USB/serial converter.
 
* Hit Ctrl-A Z S sequence to bring up the file transfer dialog in minicom.  Select XModem and navigate to and select your u-boot.bin file (space bar).
 
* Hit Enter to start the xmodem transfer in minicom.
 
* Press and release the reset pushbutton on the LinuxStamp. The transfer should happen very quickly (a few seconds).
 
* Immediately hit Enter twice when you see the transfer complete.  You *must* do this very quickly (within 1 second or so), and you *must* hit Enter twice. The first time exits the minicom file tranfer dialog, and the second time stalls the newly-loaded U-Boot program so that it doesn't try to auto-run the not-yet-loaded Linux kernel image.
 
 
 
You now have U-Boot in RAM, but not yet in flash. However, U-Boot is a lot nicer than the hardware bootloader, so you can now use U-Boot to load itself into flash by using the U-Boot menu and retransferring the u-boot.bin file again. This second time, the transfer will end up in flash, and will persist through poweroff/on.
 
  
Another alternative is to use HyperTerm on Windows, which works fine with the Hardware boot loader. If you are updating the Darrel Bootloader, note that the loader only has a short delay after you initiate the "receive" (on the loader) after which it send out the "ready to receive" signal. As a result, you'll need to be rather quick to initiate the Xmodem "send" (on HyperTerm). If you are seeing time outs on HyperTerm when you try and send the loader.bin file, you are probably hitting this problem ... you need to have initiated the send before you see the "C" on the screen from the bootloader.
+
Another alternative is to use HyperTerm on Windows, which works fine with the Hardware boot loader. If you are updating the Darren Bootloader, note that the loader only has a short delay after you initiate the "receive" (on the loader) after which it send out the "ready to receive" signal. As a result, you'll need to be rather quick to initiate the Xmodem "send" (on HyperTerm). If you are seeing time outs on HyperTerm when you try and send the loader.bin file, you are probably hitting this problem ... you need to have initiated the send before you see the "C" on the screen from the bootloader.
  
 
== nfs & tftp ==
 
== nfs & tftp ==
Line 90: Line 76:
 
*"'''eval `cat arm.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest'''"<br>
 
*"'''eval `cat arm.dat gcc-3.4.5-glibc-2.3.6.dat` sh all.sh --notest'''"<br>
 
In the "arm.dat" file I changed the TARGET to "arm-linux" (By default u-boot looks for arm-linux-* tools). Now if you run "demo-arm.sh" you should get a cross compilier.
 
In the "arm.dat" file I changed the TARGET to "arm-linux" (By default u-boot looks for arm-linux-* tools). Now if you run "demo-arm.sh" you should get a cross compilier.
 
On Debian-style-systems you need to run something like ''apt-get install build-essential bison flex'' to get the above to work.
 
  
 
== Booting ==
 
== Booting ==
Line 107: Line 91:
 
* > '''setenv bootcmd 'tftpboot 20800000 uImage; bootm 20800000'''' Sets the boot command to load a image over tftp and boot it
 
* > '''setenv bootcmd 'tftpboot 20800000 uImage; bootm 20800000'''' Sets the boot command to load a image over tftp and boot it
 
* > '''setenv bootargs mem=32M nfsroot=192.168.0.3:/nfs_root ip=192.168.0.51 console=ttyS0,115200n8 rootdelay=1'''
 
* > '''setenv bootargs mem=32M nfsroot=192.168.0.3:/nfs_root ip=192.168.0.51 console=ttyS0,115200n8 rootdelay=1'''
This sets the command line to be passed to the kernel. As you can see it sets the nfsroot, ip address and console
+
This sets the command line to be passed to the kernel. As you can see it sets the nfsrot, ip address and console
  
 
== Busybox ==
 
== Busybox ==
Line 122: Line 106:
  
 
== Building the Linux Kernel ==
 
== Building the Linux Kernel ==
If you have ever built the kernel for your desktop, then cross-compiling the kernel isn't that much harder. First get the latest kernel from [http://kernel.org/ kernel.org] (I was using 2.6.23-rc9), then get the AT91RM9200 patch from [http://maxim.org.za/at91_26.html here]. After you unpack both of these you can apply the patch. From a Fedora 11 Live install you need the following packages: gcc, gcc-c++ and qt3-devel (for xconfig).
+
If you have ever built the kernel for your desktop, then cross-compiling the kernel isn't that much harder. First get the latest kernel from [http://kernel.org/ kernel.org] (I was using 2.6.23-rc9), then get the AT91RM9200 patch from [http://maxim.org.za/at91_26.html here]. After you unpack both of these you can apply the patch.
 
* $ '''patch -p1 < 2.6.23-rc3-at91.patch'''
 
* $ '''patch -p1 < 2.6.23-rc3-at91.patch'''
 
Now lets take a look at the default configurations
 
Now lets take a look at the default configurations
Line 132: Line 116:
 
Now we're are ready to build the kernel. You will have to have the u-boot tool '''mkimage''' in the '''PATH''' for this to work
 
Now we're are ready to build the kernel. You will have to have the u-boot tool '''mkimage''' in the '''PATH''' for this to work
 
* $ '''make ARCH=arm CROSS_COMPILE=arm-linux- uImage'''
 
* $ '''make ARCH=arm CROSS_COMPILE=arm-linux- uImage'''
If you want to build the modules you can do
 
* $ '''make ARCH=arm CROSS_COMPILE=arm-linux- modules'''
 
And then if you want to install the modules to an an NFS root or somewhere else do
 
* # '''make ARCH=arm CROSS_COMPILE=arm-linux- modules_install INSTALL_MOD_PATH=/path_to_nfs_root/'''
 
  
 
== Minimal filesystem ==
 
== Minimal filesystem ==
Line 144: Line 124:
 
The '''c''' says this is a character device. The '''5''' is the major node, and the '''1''' is the minor node.
 
The '''c''' says this is a character device. The '''5''' is the major node, and the '''1''' is the minor node.
 
<br><br>
 
<br><br>
For development the most convenient way to work is by mounting an NFS root file system. Another easy way to deal with the root file system is by mounting it on either a USB drive or SD card, but if you want a stand alone system you will want the root filesystem to come from the onboard Dataflash. There are several steps to do this. The Dataflash on the Linuxstamp is 8MB. A little under 2MB is used for the bootloaders and the Linux kernel. This leaves about 6MB for the filesystem. The filesystem I am working with is about 10MB, so we will need to compress the filesystem. One method of doing this is to use the initramfs function in the kernel. The kernel expects the image to be a gzipped CPIO archive. In the kernel source there are tools to create the CPIO archive. First we must create a file list from our file system (presumedly this is just the root of your current NFS mount).
+
For development the most convenient way to work is by mounting an NFS root file system. Another easy way to deal with thre root file system is by mounting it on either a USB drive or SD card, but if you want a stand alone system you will want the root filesystem to come from the onboard Dataflash. There are several steps to do this. The Dataflash on the Linuxstamp is 8MB. A little under 2MB is used for the bootloaders and the Linux kernel. This leaves about 6MB for the filesystem. The filesystem I am working with is about 10MB, so we will need to compress the filesystem. One method of doing this is to use the initramfs function in the kernel. The kernel expects the image to be a gzipped CPIO archive. In the kernel source there are tools to create the CPIO archive. First we must create a file list from our file system (presumedly this is just the root of your current NFS mount).
 
<br>
 
<br>
 
/!!Remember that you need a 'init' file in /. You can just link to /sbin/init
 
/!!Remember that you need a 'init' file in /. You can just link to /sbin/init
Line 151: Line 131:
 
Next create the CPIO archive
 
Next create the CPIO archive
 
* # '''usr/gen_init_cpio cpio_list > initramfs.cpio'''
 
* # '''usr/gen_init_cpio cpio_list > initramfs.cpio'''
You might have to make gen_init_cpio (in the usr dir)
+
You might have to make gen_init_cpio
 
* # '''make gen_init_cpio'''
 
* # '''make gen_init_cpio'''
 
Gzip the CPIO archive
 
Gzip the CPIO archive
 
* $ '''gzip initramfs.cpio'''
 
* $ '''gzip initramfs.cpio'''
 
Now copy initramfs.cpio.gz to usr/initramfs_data.cpio.gz, and run the normal kernel make. You will notice that uImage is much larger (size = kernel + fs).
 
Now copy initramfs.cpio.gz to usr/initramfs_data.cpio.gz, and run the normal kernel make. You will notice that uImage is much larger (size = kernel + fs).
 
== Debian ==
 
If want the full Linux enviroment your used to then you can try out Debian on the Linuxstamp. A working Debian filesystem can be found on the [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=sid_20080726.tar.bz2 ftp site.]
 
 
== Ptxdist ==
 
If you looking for more features than the minimal filesystem, but don't need the full Debian system then ptxdist is right for you. The folks over at [http://www.pengutronix.de/ Pengutronix] have done a very good job creating [http://www.pengutronix.de/software/ptxdist/index_en.html Ptxdist], a simple tool for building an embedded Linux distribution. If you want to test it out with the Linuxstamp, you can grab a build of the [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=ptxroot_linuxstamp_20090124.tar.bz2 filesystem] and [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=uImage_ptx_2.6.27_20090124 kernel]. If you want to try out ptxdist yourself, you can get the Linuxstamp project [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=ptx_linuxstamp_pjt_20090124.tar.bz2 here].
 
  
 
== Dropbear SSH ==
 
== Dropbear SSH ==
 
One of the first non busybox tools you will want is SSH. Dropbear is a small SSH client/server. I was able to get version 0.50 working.
 
One of the first non busybox tools you will want is SSH. Dropbear is a small SSH client/server. I was able to get version 0.50 working.
*[http://matt.ucc.asn.au/dropbear/dropbear.html http://matt.ucc.asn.au/dropbear/dropbear.html]
 
 
 
 
* $ '''./configure --host="arm-linux" --disable-zlib --prefix=/staging_path'''
 
* $ '''./configure --host="arm-linux" --disable-zlib --prefix=/staging_path'''
 
* $ '''make all'''
 
* $ '''make all'''
Line 175: Line 146:
 
* # '''mknod /dev/tty c 5 0'''
 
* # '''mknod /dev/tty c 5 0'''
 
You will also have to have the devpts filesystem mounted.
 
You will also have to have the devpts filesystem mounted.
 
== 802.11 Wireless Networking ==
 
With the 2.6.27 vanilla kernel the ralink USB driver works very well. I've been using the AZIO AWU254 without any problems.
 
 
== GPIO / Hardware Pin I/O ==
 
 
If you need some guidance figuring out how to 'bit twiddle' the GPIO (General Purpose I/O) pins on the at91 processor, here is a simple example with make file.  If you have your arm-linux cross compiler configured with CrossTool just unpack this file into a folder and type 'make' to generate the executable binary.
 
 
* [http://linuxstamp.budgetdedicated.com/downloads/at91_gpio_example.zip at91_gpio_example.zip]
 
 
This example shows how to set and clear output pins read input pins.
 
  
 
== Servos ==
 
== Servos ==
 
[[Image:Servos.jpg]]
 
[[Image:Servos.jpg]]
  
It is very easy to use the Linuxstamp with a RC servo controller like this one from [http://www.pololu.com/catalog/product/208/pictures pololu]. In this setup the board is powered from the USB connector, so I was able to use the power terminal to power the pololu module. On the under side of the pololu module I connected the servo power with the chip power. The only other thing that is needed is the serial TX line from the Linuxstamp (yellow wire). I created a very simple [http://linuxstamp.budgetdedicated.com/index.php?dir=&file=servo_test.tar.bz2 program] to run the servos. The following example would set servo 0 to a speed of 54 (64 is stopped) with an acceleration of 2.
+
It is very easy to use the Linuxstamp with a RC servo controller like this one from [http://www.pololu.com/catalog/product/208/pictures pololu]. In this setup the board is powered from the USB connector, so I was able to use the power terminal to power the pololu module. On the under side of the pololu module I connected the servo power with the chip power. The only other thing that is needed is the serial TX line from the Linuxstamp (yellow wire). I created a very simple [http://datasrv04.webmatrix.com.br/symphony/servo_test.tar.bz2 program] to run the servos. The following example would set servo 0 to a speed of 54 (64 is stopped) with an acceleration of 2.
 
*'''# ./servo_ser 0 2 54'''
 
*'''# ./servo_ser 0 2 54'''
 +
 +
== Eagle Stuff ==
 +
I will put tools and libraries here.
 +
* I would post a cam job, but opencircuits won't let me upload a .cam file
 +
** Maybe you could tar.gz it? **
  
 
== Links ==
 
== Links ==
Line 198: Line 163:
 
*[http://cadsoft.de/ Cadsoft.de]: Free (as in beer) tools for schematic and PCB design
 
*[http://cadsoft.de/ Cadsoft.de]: Free (as in beer) tools for schematic and PCB design
 
*[http://openhardware.wordpress.com/ openhardware.wordpress.com]: Here is my openhardware blog
 
*[http://openhardware.wordpress.com/ openhardware.wordpress.com]: Here is my openhardware blog
*[http://linuxstamp.budgetdedicated.com/ ftp site]: Here you will find tools and images like the crosscompilier and a debian file system
+
*[http://datasrv04.webmatrix.com.br/symphony/ ftp site]: Here you will find tools and images like the crosscompilier and a debian file system
 
*[http://www.atmel.com/dyn/products/app_notes.asp?family_id=605 App notes]: for Atmel arm processors
 
*[http://www.atmel.com/dyn/products/app_notes.asp?family_id=605 App notes]: for Atmel arm processors
*[[Linuxstamp Mboard 1| Mborad 1]] for the Linuxstamp
+
*[http://www.jendylabs.com/ Jendy Labs]
*[http://wiki.emqbit.com/free-ecb-at91 ECB AT91] This is another open source project similar to the Linuxstamp. They have some [http://wiki.emqbit.com/wiki very good documentation].
+
*[http://opencircuits.com/Linuxstamp_Mboard_1 Mborad 1] for the Linuxstamp
*[http://www.budgetdedicated.com/ Budgetdedicated] Graciously hosts our ftp [http://linuxstamp.budgetdedicated.com/ site]
+
*[http://wiki.emqbit.com/wiki ECB AT91] This is another open source project similar to the Linuxstamp. They have somve very good documentation.
 +
 
 +
== Pricing ==
 +
The parts cost for qty 1 is $75 from digikey, and $55 for qty 100<br>
 +
I'm sure this can be greatly reduced with higher quantity<br>
 +
We will make a small run soon, and I will let you know when these are available.<br>
 +
 
 +
== USB Discussion ==
 +
 
 +
Can I plug a USB peripheral into the Linuxstamp, such as a USB Wifi adapter? --[[User:DavidCary|DavidCary]] 22:02, 17 April 2007 (PDT)<br>
 +
:Yes, any USB device that is supported by the kernel should work with the Linuxstamp. --[[User:Linuxvolts|Linuxvolts]] 23:15, 18 April 2007 (PDT)
 +
 
 +
This is not a true USB port is it? Its just a usb serial peripheral port, therefore USB stick will not work.
 +
:Should be answered by the last answer, too. An USB stick is also USB peripheral^^ --SebDE
 +
 
 +
This is not a USB host....it (Linuxstamp)is seen as the peripheral surely?
 +
:From the Features:
 +
:''1x USB host port (allows wifi adapters, flash drives and other USB devices to be used)''
 +
:You can plug in any USB device that is supported by the kernel. The Linuxstamp is not supposed to be plugged via USB to a PC.
 +
:--SebDE
 +
 
 +
The FTDI driver creates a device /dev/ttyUSB0, a character device.  You can read/write to it as if it was a terminal, tty, or serial port.  Above section on "Minicom & the debug port" points to communicating with the linuxstamp from a host computer. The FTDI232 chip connects to the mini-USB port.  It looks like the larger USB port interfaces with the MCU, through U4.  What IC is U4?
 +
 
 +
 
 +
The AT91RM9200 has 2x USB host ports and 1x device port. I bring out one of the USB host ports directly from the chip to a USB A connector. There is also a mini USB B connector on the board this is connected to the FT232RQ (USB/serial converter) which in turn is connected to the debug serial port on the AT91RM9200. So the linuxstamp can be both a USB host and a USB device. --[[User:Linuxvolts|Linuxvolts]] 20:10, 4 July 2007 (PDT)
 +
 
 +
== discussion ==
 +
 
 +
Do you ship to other countries, such as, for example, France?
 +
 
 +
 
 +
In the specs above, it says "32MB SDRAM (Only limited by 1x 54-TSOP SDRAM chip)" but the excel file from your .Zip says that you used the part 557-1059-1-ND which is a 256mb chip, and its labeled as 32mb, is this a mistake, am I misunderstanding? Would something like this work? 557-1078-1-ND
  
== USB Info ==
+
: ''A bit is the fundamental unit of information storage. The 557-1059-1-ND stores 256 mebibit (equal to 32 mebibyte). Alas, some people use the same abbreviation "MB" for all of "mebibit", "mebibyte", "megabit", and "megabyte", leading to confusion. The 557-1078-1-ND physically fits on the board; could someone confirm or deny whether it would actually work? --[[User:DavidCary|DavidCary]] 11:24, 16 August 2008 (PDT)''
The AT91RM9200 has 2x USB host ports and 1x device port. I bring out one of the USB host ports directly from the chip to a USB A connector. There is also a mini USB B connector on the board this is connected to the FT232RQ (USB/serial converter) which in turn is connected to the debug serial port on the AT91RM9200. So the linuxstamp can be both a USB host and a USB device.
 
  
The FTDI driver creates a device /dev/ttyUSB0, a character device (this is how the Linuxstamp shows up on the host system).  You can read/write to it as if it was a terminal, tty, or serial port.  Above section on "Minicom & the debug port" points to communicating with the linuxstamp from a host computer. The FTDI232 chip connects to the mini-USB port.
 
  
== Discussion ==
+
Is it possible to add multiple ethernet ports?
Please join the google group for the Linuxstamp discussion
 
http://groups.google.com/group/linuxstamp
 
  
 
== Contact ==
 
== Contact ==
Line 220: Line 212:
 
* [[ARMUS Embedded Linux Board]]
 
* [[ARMUS Embedded Linux Board]]
 
* [http://balloonboard.org/ Balloon board]
 
* [http://balloonboard.org/ Balloon board]
* [http://www.bifferos.com/ Bifferboard]
 
* [[Linuxstamp II 9260]]
 
  
 
[[Category:Projects]]
 
[[Category:Projects]]

Please note that all contributions to OpenCircuits may be edited, altered, or removed by other contributors. If you do not want your writing to be edited mercilessly, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource (see OpenCircuits:Copyrights for details). Do not submit copyrighted work without permission!

Cancel Editing help (opens in new window)