<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>http://www.opencircuits.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mdwebster</id>
	<title>OpenCircuits - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="http://www.opencircuits.com/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Mdwebster"/>
	<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Special:Contributions/Mdwebster"/>
	<updated>2026-06-02T05:41:34Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.34.2</generator>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Passives&amp;diff=2941</id>
		<title>Passives</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Passives&amp;diff=2941"/>
		<updated>2007-03-11T20:10:09Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Flavor quote and note on impedance inverter&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{stub}}&lt;br /&gt;
== Capacitors ==&lt;br /&gt;
=== Electrolytic ===&lt;br /&gt;
==== Aluminum ====&lt;br /&gt;
==== Tantalum ====&lt;br /&gt;
* [[10uF Tantalum Capacitor]]&lt;br /&gt;
=== Ceramic ===&lt;br /&gt;
=== Film ===&lt;br /&gt;
==== Polyester (Mylar) ====&lt;br /&gt;
==== Polystyrene ====&lt;br /&gt;
==== Polycarbonate ====&lt;br /&gt;
==== Polypropylene ====&lt;br /&gt;
==== Teflon ====&lt;br /&gt;
=== Exotics ===&lt;br /&gt;
==== Mica ====&lt;br /&gt;
==== Glass ====&lt;br /&gt;
==== Oil ====&lt;br /&gt;
==== Vacuum ====&lt;br /&gt;
&lt;br /&gt;
== Inductors ==&lt;br /&gt;
&amp;quot;Ferrites?  I don't know much about 'em, I only use ferrites in switching regulators.&amp;quot;  --National Semiconductor's Bob Pease&lt;br /&gt;
&lt;br /&gt;
Can be replaced in many circumstances with an impedance inverter using only an opamp, a capacitor, and a few resistors.&lt;br /&gt;
&lt;br /&gt;
== Resistors ==&lt;br /&gt;
=== Carbon ===&lt;br /&gt;
=== Metal Film ===&lt;br /&gt;
=== Wire-Wound ===&lt;br /&gt;
=== Precision ===&lt;br /&gt;
=== Potentiometers ===&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=File:SwitchExamples.jpg&amp;diff=2855</id>
		<title>File:SwitchExamples.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=File:SwitchExamples.jpg&amp;diff=2855"/>
		<updated>2007-03-01T17:48:04Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Drawn using Visio 2007&lt;br /&gt;
[[User:Mdwebster|Mdwebster]] 09:48, 1 March 2007 (PST)&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Switch_Terminology&amp;diff=2854</id>
		<title>Switch Terminology</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Switch_Terminology&amp;diff=2854"/>
		<updated>2007-03-01T17:45:50Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: New page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;xPyT = x Poles, y Throws&lt;br /&gt;
&lt;br /&gt;
The number of poles is the number of separate switches that a single switch contains.  A 3P switch is the equivalent of 3 separate switches in one package.&lt;br /&gt;
The number of throws is the number of different lines that an incoming pole can be switched to.  A 1P4T switch can switch a single incoming pole to any of four different lines.&lt;br /&gt;
&lt;br /&gt;
[[Image:SwitchExamples.jpg]]&lt;br /&gt;
&lt;br /&gt;
[http://en.wikipedia.org/wiki/Switch More on Switches]&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=File:SwitchExamples.jpg&amp;diff=2853</id>
		<title>File:SwitchExamples.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=File:SwitchExamples.jpg&amp;diff=2853"/>
		<updated>2007-03-01T17:39:44Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Switches&amp;diff=2852</id>
		<title>Switches</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Switches&amp;diff=2852"/>
		<updated>2007-03-01T17:23:37Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Adding link to switch terminology page&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Switch Terminology]] _P_T - SPST - SPDT - DPST - DPDT - 3PDT - ....&lt;br /&gt;
&lt;br /&gt;
[[Image:Main-G5Q-14.jpg|69px|Relays]] [[Relays]] - Use these to control large power sources that a microcontroller cannot do alone&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Passives&amp;diff=2851</id>
		<title>Passives</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Passives&amp;diff=2851"/>
		<updated>2007-03-01T17:21:12Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Set up a template for future work&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{stub}}&lt;br /&gt;
== Capacitors ==&lt;br /&gt;
=== Electrolytic ===&lt;br /&gt;
==== Aluminum ====&lt;br /&gt;
==== Tantalum ====&lt;br /&gt;
* [[10uF Tantalum Capacitor]]&lt;br /&gt;
=== Ceramic ===&lt;br /&gt;
=== Film ===&lt;br /&gt;
==== Polyester (Mylar) ====&lt;br /&gt;
==== Polystyrene ====&lt;br /&gt;
==== Polycarbonate ====&lt;br /&gt;
==== Polypropylene ====&lt;br /&gt;
==== Teflon ====&lt;br /&gt;
=== Exotics ===&lt;br /&gt;
==== Mica ====&lt;br /&gt;
==== Glass ====&lt;br /&gt;
==== Oil ====&lt;br /&gt;
==== Vacuum ====&lt;br /&gt;
&lt;br /&gt;
== Inductors ==&lt;br /&gt;
&lt;br /&gt;
== Resistors ==&lt;br /&gt;
=== Carbon ===&lt;br /&gt;
=== Metal Film ===&lt;br /&gt;
=== Wire-Wound ===&lt;br /&gt;
=== Precision ===&lt;br /&gt;
=== Potentiometers ===&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Supplier&amp;diff=2848</id>
		<title>Supplier</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Supplier&amp;diff=2848"/>
		<updated>2007-02-28T22:07:40Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Added Electronics Goldmine, added some site links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Even if you can find the perfect part, sometimes you can't find anyone who is willing to sell you one. Here is some information on suppliers.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Giant Catalogs ==&lt;br /&gt;
&lt;br /&gt;
[[Image:Digikey-Logo.gif|150px|Digikey]] [[Digikey]]&lt;br /&gt;
[[Image:Mouser-Logo.png|150px|Mouser]] [[Mouser]]&lt;br /&gt;
[[Image:Farnell_logo.gif|150px|Farnell]] [[Farnell]] &lt;br /&gt;
&lt;br /&gt;
These guys have huge catalogs and an immense selection of parts, yet are still willing to sell things in onseies-and-twosies to hobbyists who can't claim to be prototyping something that'll sell a million units next year. Digi-Key actually got its start in the ham radio market, selling digital keyers.&lt;br /&gt;
&lt;br /&gt;
I ([[Wiml]]) find that Digi-Key is the place to go for digital stuff, microcontrollers, and the like. For discretes and analog parts, Mouser is usually cheaper and has a better selection. Neither company has a minimum order, but of course they do have shipping and handling fees which make small orders impractical.&lt;br /&gt;
&lt;br /&gt;
I, myself (who?) appear to have found that [[Jameco]] is good for small quantities of a fairly common part.  They don't have anything surface mount, though.  For that stuff, I had to go to Digi-Key.  I called up Digi-Key to see if I could alter an order I had just placed before it got fulfilled.  My order was already far enough along that they couldn't stop it.  I believe the phrase was &amp;quot;too far gone&amp;quot;.  That speaks well of their order fulfillment process.  I hear Mouser should be in there too, but I've never had a compelling reason to use them.&lt;br /&gt;
&lt;br /&gt;
== Mid-size Suppliers ==&lt;br /&gt;
&lt;br /&gt;
[[Jameco]]'s catalogs have been getting fatter recently and their prices are good for common parts.  Their Jameco ValueBrand parts are often much cheaper than the competition. (I have yet to notice the difference, personally -mdwebster)&lt;br /&gt;
&lt;br /&gt;
Radio Shack is OK if you need a common part NOW, but expect to pay probably 10 times the mail order price.  In the past couple of years (2005-2006), I've noticed many Radio Shacks have ceased carrying ANY electronics parts.  You're most likely to find solder, wire, switches, led's, and project boxes.  The selection of transistors or IC's are poor to nonexistent.&lt;br /&gt;
If you have a Fry's in your area, they have a much better selection, but their component prices are not much better then RS. Unless you need a part immediately, you'll be much better off getting it mail order. &lt;br /&gt;
&lt;br /&gt;
X-10 is a joke.&lt;br /&gt;
&lt;br /&gt;
Pricewatch is good for locating certain computer gear at its version of the best price.  Froogle is sort of the same thing, but without the seedy side filtered out.&lt;br /&gt;
&lt;br /&gt;
== Smaller and niche suppliers ==&lt;br /&gt;
&lt;br /&gt;
[[All Electronics]] (http://www.allelectronics.com) Corp. needs to even out their stuff a bit.  Either specialize in a few types of parts or be more even across the board.  Spark Fun Electronics appears to be trying to do it right.  It is still weird that I can't just order a bunch of 0603 resistors from them.  Seems like a no-brainer.&lt;br /&gt;
&lt;br /&gt;
[[Alltronics]] (http://www.alltronics.com/) is similar to All Electronics in what they carry. Fairly sure they're different companies with annoyingly similar names.&lt;br /&gt;
&lt;br /&gt;
[[Electronics Goldmine]] (http://www.goldmine-elec.com/) is another surplus warehouse.  Don't expect to find any particular part, but they have good prices on what they do carry.&lt;br /&gt;
&lt;br /&gt;
[[Futurlec.com]] (http://www.futurlec.com) I've been very happy with Futurlec. Their prices are outstanding, especially on value packs. Their customer service isn't stellar, but in the end they've always resolved any problems that I've had. They ship from Australia, but their shipping prices are reasonable &amp;amp; the shipping is quick enough.&lt;br /&gt;
&lt;br /&gt;
[[MPJA.com]] (http://www.mpja.com) - prototyping tools, components.  Not a huge selection, but prices are low.  If you order something that comes with an instruction sheet that was translated into English, the directions may be hard to decipher due to poor translation, possibly from Chinese.  They ship from Florida.&lt;br /&gt;
&lt;br /&gt;
[[Surplus Sales]] (http://www.surplussales.com/) more exotic surplus parts.&lt;br /&gt;
&lt;br /&gt;
[[Surplus Shed]] (http://www.surplusshed.com/) carries a some electronics and lots of optics. (Prisms, microscopes, etc)&lt;br /&gt;
&lt;br /&gt;
[[American Science and Surplus]] (http://www.sciplus.com/) has a little bit of everything. Rubber spiders, speakers, prisms, lab equipment, electromechanical timers, Slinkies, motors, switches, fake vomit, glow-in-the-dark pencils, radio-controlled toy rats... Good selection of fans and motors, and an oddball attitude to boot. If you're near Chicago, their retail store is even weirder.&lt;br /&gt;
&lt;br /&gt;
American Science &amp;amp;amp; Surplus&lt;br /&gt;
[http://www.sciplus.com/recommend.cfm?recommendid=11013&amp;amp;jump=index%2Ecfm%3Fstart%3D1  seems to have good prices on breadboards].&lt;br /&gt;
&lt;br /&gt;
== Comments ==&lt;br /&gt;
&lt;br /&gt;
I want to see some competition in the micro dev/app board market.  I just paid approximately 34.95 + its share of the shipping for a 32 bit ARM microcontroller on a PCB and with a USB device port on one end and a series of  header sockets on the other.  If that is considered  cheap, then this is never going to take off.&lt;br /&gt;
&lt;br /&gt;
I realize that other authors will have different opinions than I, and that this entry is probably not going to remain as it is for long.  Come on, everybody.  These comments do not reflect the opinions of Open Circuits.  They are only my own.  Add yours.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
I've had great experiences with [[Mouser]] and [[Jameco]] for smallish orders (&amp;lt;$200). I've also had several good experiences with [[SparkFun]]. I now avoid Fry's. In addition to their horrible return policies, their stock is very random and prices aren't very good.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
My personal experiance with Surplus Sales was very good. I would highly recommend them for anyone that needs a blower motor, hydraulic pump, etc. Good prices, good service.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
IguanaLabs ( http://www.iguanalabs.com/ ) seems to be very hobbyist-friendly. They have a very small selection of parts, but it includes the lowest-cost [[breadboard]]s I've seen. &lt;br /&gt;
&lt;br /&gt;
Please note that IguanaLabs will be closing its doors for good on August 11th, 2007.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
See also the list at http://techref.massmind.org/techref/supplies.htm .&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Basic_soldering&amp;diff=2847</id>
		<title>Basic soldering</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Basic_soldering&amp;diff=2847"/>
		<updated>2007-02-28T21:55:55Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Added some basic info and some links&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Basic Soldering ==&lt;br /&gt;
Required tools:&lt;br /&gt;
Hot metal object (preferably with an insulating handle like in a soldering iron)&lt;br /&gt;
Solder (preferably with rosin flux core)&lt;br /&gt;
&lt;br /&gt;
Technique:&lt;br /&gt;
Apply hot metal object to both surfaces that are to be soldered together.  Feed the flux-core solder into the joint from the side opposite the h.m.o.  Once enough solder has flowed, remove heat.&lt;br /&gt;
&lt;br /&gt;
Preferred tools:&lt;br /&gt;
A temperature-controlled soldering iron/station.  &lt;br /&gt;
Please be aware that many cheap soldering stations and irons, even if they are adjustable, simply adjust the overall wattage feeding into the tip.  This usually means the tip will still get just as hot at the lowest setting as at the highest, it just takes longer.  Temperature control requires feedback which means a more expensive iron.  Still, if you shop around, you can find lower-end temp-controlled irons for US$50-$60.  The recommended temperature is around 380F for 63-37 (tin-lead ratio).  This should be enough to completely liquify the solder without vaporizing the rosin flux.  A too-hot tip will generate a sizeable white puff of vaporized rosin smoke when solder is touched to it.  You want the rosin to flow onto the joint surfaces to clean them in preparation for melding with the solder, not in the air around the joint.&lt;br /&gt;
Thin (fine-pitch) rosin-core solder.&lt;br /&gt;
Thinner solder melts more easily and allows more control over the joint formation than thicker solder.  Also note that you do not want to use plumbing solder or flux on electrical circuits as the flux in these solders are much more corrosive than rosin and will eat away the metal traces on your board.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Advanced Soldering ==&lt;br /&gt;
The [http://www.psocdeveloper.com/forums/viewtopic.php?t=2358 &amp;quot;Packaging information&amp;quot;] thread&lt;br /&gt;
has a few tips for soldering surface-mount (SMT) components:&lt;br /&gt;
SOIC (1.27mm/50 mil pitch), SSOP (0.65mm pitch), TQFP (0.50mm-0.80mm pitch), and MLF/QFN (0.50mm pitch).&lt;br /&gt;
&lt;br /&gt;
== Desoldering ==&lt;br /&gt;
Solder suckers can be hand-held, pump-driven, and with or without active heating.  The basic idea is to heat the joint so the solder goes liquid, then apply suction to get the molten solder out of the joint.  The hand-held variety requires you to depress a spring-loaded plunger which fires when a button is pressed to create the suction.  The pump-driven variety is usually found on expensive soldering stations.  Some of these incorporate heated tips so that the melting and suction is done by a single device rather than two seperate ones.&lt;br /&gt;
&lt;br /&gt;
Solder braid is a rosin-loaded copper braid that is pressed onto a joint and heated so that the liquified solder flows into the braid.  Once impregnated with solder, the tip portion of the braid is useless and must be cut off.  Solder braid is quite prone to going &amp;quot;stale&amp;quot; and braid obtained from surplus sites is likely to not work very well.&lt;br /&gt;
&lt;br /&gt;
Other methods involve using a hotplate, a hot air gun, or a combination of the two in order to bring the solder just up to its melting point then plucking the chips out with tweezers.&lt;br /&gt;
&lt;br /&gt;
== Links ==&lt;br /&gt;
[http://www.elexp.com/t_solder.htm Electronix Express Soldering Tips]&lt;br /&gt;
&lt;br /&gt;
[http://radiojove.gsfc.nasa.gov/telescope/soldering.htm Instructional Soldering Videos from NASA]&lt;br /&gt;
&lt;br /&gt;
[http://www.inlandcraft.com/Uguides/tipfailure.htm InlandCraft Tip Failure Article]&lt;br /&gt;
&lt;br /&gt;
[http://www.geofex.com/Article_Folders/how_to_solder.htm Geofex.com How-To Solder]&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=DsPIC30F_5011_Development_Board&amp;diff=2778</id>
		<title>DsPIC30F 5011 Development Board</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=DsPIC30F_5011_Development_Board&amp;diff=2778"/>
		<updated>2007-02-14T23:34:34Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: revert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
&lt;br /&gt;
===Features of dsPIC30F5011===&lt;br /&gt;
*2.5 to 5V	&lt;br /&gt;
*Up to 30MIPs&lt;br /&gt;
*High current/sink source I/O pins: 25mA&lt;br /&gt;
*DSP Instruction Set&lt;br /&gt;
*Dual programming techniques: ICSP and RTSP&lt;br /&gt;
*UART: up to 2 modules&lt;br /&gt;
*I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C: up to 1Mbps&lt;br /&gt;
*10-bit A/D, 1.1 Msps	&lt;br /&gt;
*12-bit A/D, 200 ksps&lt;br /&gt;
*44K flash (66Kb), 4Kb RAM, 1Kb EEPROM&lt;br /&gt;
*No DAC&lt;br /&gt;
			&lt;br /&gt;
===Web Page===&lt;br /&gt;
*[http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=2529&amp;amp;param=en024856 Microchip Official Website]&lt;br /&gt;
&lt;br /&gt;
===Forum===&lt;br /&gt;
*[http://direct.forum.microchip.com/default.aspx Microchip]: Official forum by Microchip&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=49 MPLAB ICD 2]: Subforum on ICD 2 programmer&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=57 MPLAB IDE]: Subforum on IDE&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=101 MPLAB C30 Compiler, ASM30, Link30 forum]: Subforum on C compiler. Refer to [http://ww1.microchip.com/downloads/en/DeviceDoc/C30_Users_Guide_51284e.pdf MPLAB C30 C Compiler User's Guide] Chapter 3&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=153 dsPIC30F Topics]: Subformum on dsPIC30F&lt;br /&gt;
*[http://www.gnupic.org/ GNUPIC]: Discussion on PIC in Linux Systems&lt;br /&gt;
**[http://www.linuxhacker.org/cgi-bin/ezmlm-cgi?1:dds:5443#b Debian]&lt;br /&gt;
*[http://www.htsoft.com/forum/all/ubbthreads.php/Cat/0/C/6 HI-TECH Software Forum]: Discussion on dsPICC, a C compiler developed by HI-TECH&lt;br /&gt;
*[http://piclist.com/techref/piclist/index.htm PICList]: Discussion on older PIC systems (not dsPIC)&lt;br /&gt;
*[http://groups.google.com/group/pickit-devel PicKit]: Discussion on PICkit/PICkit 2 programmers&lt;br /&gt;
*[http://sourceforge.net/forum/forum.php?forum_id=382005 FreeRTOS Real Time Kernel]: Open Discussion and Support on FreeRTOS	&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
*dsPIC30F&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70043F.pdf Family Overview]&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70046E.pdf Family Reference Manual]: Contains detailed descriptions on dsPIC30F register definitions and example codes&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70116F.pdf 5011 Data Sheet]	**[http://ww1.microchip.com/downloads/en/DeviceDoc/70102G.pdf Flash Programming Specification]&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70157B.pdf Programmer Reference Manual]&lt;br /&gt;
*ICD2 Programmer&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/51331B.pdf ICD2 User's Guide]	&lt;br /&gt;
*MPLAB&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/51519B.pdf MPLAB IDE User's Guide]&lt;br /&gt;
*C30 Compiler&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/C30_Users_Guide_51284e.pdf MPLAB C30 C Compiler User's Guide]: Contains commands for using pic30-elf-gcc		&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/16bit_Language_Tool_Libraries_51456c.pdf 16-bit Language Tools Libraries]: Contains summaries and examples of using DSP libraries, standard C libraries and device libraries&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/Asm30_Link_Util_51317e.pdf MPLAB ASM30, MPLAB LINK30 and Utilities User's Guide]&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/51322d.pdf dsPIC30F Language Tools Quick Reference Card]&lt;br /&gt;
&lt;br /&gt;
==Programming Methods==&lt;br /&gt;
*There are 2 programming methods: In-Circuit Serial Programming (ICSP) and Run-Time Self-Programming (RTSP)&lt;br /&gt;
*ICSP allows the devices to be programmed after being placed in a circuit board.&lt;br /&gt;
*RTSP allows the devices to be programmed when an embedded program is already in operation.&lt;br /&gt;
&lt;br /&gt;
===ICSP: External Programmer (ICD2)===&lt;br /&gt;
*Two types of ICSP are available: '''ICSP''' and '''Enhanced ICSP'''. Both of them require setting MCLR# to V&amp;lt;sub&amp;gt;IHH&amp;lt;/sub&amp;gt; (9V – 13.25V).&lt;br /&gt;
*Standard ICSP&lt;br /&gt;
**Use external programmer (e.g. MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; ICD 2, MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; PM3 or PRO MATE&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; II) only.&lt;br /&gt;
**Required low-level programming to erase, program and verify the chip.&lt;br /&gt;
**Slower, because codes are serially executed.&lt;br /&gt;
**Program memory can be erased using ''Normal-Voltage'' (4.5 – 5.5V) or ''Low-Voltage'' (2.5V – 4.5V).&lt;br /&gt;
&lt;br /&gt;
*Enhanced ICSP&lt;br /&gt;
**Use external programmer and '''Programming Executive''' (PE).&lt;br /&gt;
**PE is stored in the on-chip memory.&lt;br /&gt;
**PE allows faster programming.&lt;br /&gt;
**PE can be downloaded to the chip by external programmer using the standard ICSP method.&lt;br /&gt;
**PE contains a small command set to erase, program and verify the chip, avoiding the need of low-level programming.&lt;br /&gt;
&lt;br /&gt;
====Hardware Interface====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.1 Pin Used by ICSP&lt;br /&gt;
! Pin Label !! Function !! Pin Number&lt;br /&gt;
|- &lt;br /&gt;
| MCLR# || Programming Enable|| 7&lt;br /&gt;
|-&lt;br /&gt;
| V&amp;lt;sub&amp;gt;DD&amp;lt;/sub&amp;gt; || Power Supply || 10, 26, 38, 57&lt;br /&gt;
|-&lt;br /&gt;
| V&amp;lt;sub&amp;gt;SS&amp;lt;/sub&amp;gt; || Ground || 9, 25, 41, 56&lt;br /&gt;
|- &lt;br /&gt;
| PGC || Serial Clock || 17&lt;br /&gt;
|-&lt;br /&gt;
| PGD || Serial Data || 18&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.2 Available Programmers in the Market&lt;br /&gt;
! Product Name&lt;br /&gt;
! Interface with PC&lt;br /&gt;
! Interface with Device&lt;br /&gt;
! Price (US)&lt;br /&gt;
! Postage (US)&lt;br /&gt;
! Total (US)&lt;br /&gt;
|- &lt;br /&gt;
| [http://direct.www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010046&amp;amp;part=DV164005 MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; ICD 2]&lt;br /&gt;
| USB or RS232&lt;br /&gt;
| [http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en010046&amp;amp;lang=en&amp;amp;ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010046&amp;amp;part=DV164005# 6-PIN RJ-12 connector]&lt;br /&gt;
| $159.99&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.etekronics.com/product_info.php?cPath=24&amp;amp;products_id=48  Full Speed USB Microchip ICD2&amp;lt;br&amp;gt; Debugger and Programmer]&lt;br /&gt;
| USB&lt;br /&gt;
| 6-PIN ICSP connector&amp;lt;br&amp;gt;6-PIN RJ-12 connector&lt;br /&gt;
| $72.00&lt;br /&gt;
| $12.00&lt;br /&gt;
| $84.00&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.etekronics.com/product_info.php?cPath=24&amp;amp;products_id=47 Mini Microchip Compatible ICD2&amp;lt;br&amp;gt; Debugger and Programmer]&lt;br /&gt;
| RS232&lt;br /&gt;
| 6-PIN ICSP connector&amp;lt;br&amp;gt;6-PIN RJ-12 connector&lt;br /&gt;
| $45.00&lt;br /&gt;
| $10.00&lt;br /&gt;
| $55.00&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.inexglobal.com/microcontroller.php ICDX30]&lt;br /&gt;
| RS232&lt;br /&gt;
| 6-pin RJ-11&lt;br /&gt;
| $51.00&lt;br /&gt;
| $47.46&lt;br /&gt;
| $98.46&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.sure-electronics.net/englishsite/icd2/icd2.htm Clone Microchip ICD2]&lt;br /&gt;
| USB&lt;br /&gt;
| 6-pin flat cables&lt;br /&gt;
| $30.00&lt;br /&gt;
| $12.00&lt;br /&gt;
| $42.00&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.3 DIY ICD 2 Programmer Circuit&lt;br /&gt;
! Source !! Schematic !! PIC16F877A Bootloader&lt;br /&gt;
|- &lt;br /&gt;
| [http://membres.lycos.fr/silicium31/Electronique/PIC/FreeIcdEnglish.htm Patrick Touzet]&lt;br /&gt;
| [http://membres.lycos.fr/silicium31/Electronique/PIC/ICD2%20V1.3.pdf Yes]&lt;br /&gt;
| [http://membres.lycos.fr/silicium31/Electronique/PIC/ICD2_FW.zip HEX]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.nebadje.org/doku.php?id=neblab:icd2clone Nebadje]&lt;br /&gt;
| [http://people.ee.ethz.ch/~jbiveron/nebadje/ICD2_DOC.pdf Yes]&lt;br /&gt;
| [http://people.ee.ethz.ch/~jbiveron/nebadje/ICD2_FW.zip Zip]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Software Interface====&lt;br /&gt;
*The program can be written and compiled in an Integrated Development Environment (IDE) using either Assembly or C. The complied codes are then loaded to the device through the external programmer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.4 Summary of IDE&lt;br /&gt;
! Product Name !! Features !! OS !! Price (US$)&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002 MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; IDE]&lt;br /&gt;
| Assembler Only&lt;br /&gt;
| Windows&lt;br /&gt;
| Free&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010065&amp;amp;part=SW006012 MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; C30]&lt;br /&gt;
| Assembler and C-Compiler&lt;br /&gt;
| Windows&lt;br /&gt;
| $895.00 (Free student version&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| [http://linux.softpedia.com/get/Science-and-Engineering/Electronic-Design-Automation-EDA-/Piklab-8099.shtml Piklab 0.12.0]&lt;br /&gt;
| Assembler and C-Compiler&lt;br /&gt;
| Linux&lt;br /&gt;
| Free&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
# Full-featured for the first 60 days. After 60 days only optimization level 1 can be enabled in the compiler. The compiler will continue to function after 60 days, but code size may increase.&lt;br /&gt;
# The current version supports external programmer ICD 2, but not yet tested.&lt;br /&gt;
&lt;br /&gt;
===RTSP: COM Port (Bootloader)===&lt;br /&gt;
*RTSP works in normal voltage (^MCLR no need to raise to V&amp;lt;sub&amp;gt;IHH&amp;lt;/sub&amp;gt;).&lt;br /&gt;
*No literature has mentioned the incorporation of Programming Executive (PE). Presumably, since Enhanced ICSP needs to set MCLR# to V&amp;lt;sub&amp;gt;IHH&amp;lt;/sub&amp;gt;, RTSP cannot use PE.&lt;br /&gt;
*Refer to bootloader section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Circuit Design and PCB==&lt;br /&gt;
&lt;br /&gt;
===IC Requirements===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 3.1 IC Requirements&lt;br /&gt;
! Part No. !! Description &lt;br /&gt;
! Min Temp !! Max Temp !! Min Volt !! Max Volt !! Typ Cur !! Max Cur&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://ww1.microchip.com/downloads/en/DeviceDoc/70116F.pdf dsPIC30F5011-30I/PT] || uP &lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 2.5V &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;|| 5.5V&lt;br /&gt;
|     || 250mA&lt;br /&gt;
|-&lt;br /&gt;
| [http://datasheets.maxim-ic.com/en/ds/MAX3222-MAX3241.pdf MAX3232ESE] || RS232 driver&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 3.0V || 5.5V&lt;br /&gt;
| 0.3mA || 1.0mA&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.analog.com/UploadedFiles/Data_Sheets/ADM483E.pdf ADM483E ANZ] || RS485 driver&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 4.5V || 5.5V&lt;br /&gt;
| 0.036mA || &lt;br /&gt;
|-&lt;br /&gt;
| [http://focus.ti.com/lit/ds/symlink/dac6574.pdf DAC6574DGS] || 10-bit Quad-DAC I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 105&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 2.7V || 5.5V&lt;br /&gt;
| 0.6mA || 0.9mA&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat/datasheets/74HC_HCT14_3.pdf 74HC14D] || Quad-Schmitt Trigger&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 125&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 2.0V || 6.0V&lt;br /&gt;
| || 50mA&lt;br /&gt;
|-&lt;br /&gt;
| Overall || &lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 4.5V || 5.5V&lt;br /&gt;
| || &amp;lt;310mA &amp;lt;sup&amp;gt;[2]&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
#Minimum voltage measured is 3.3V (with 2 LEDs blinking) running at 30MHz.&lt;br /&gt;
#Measured current at 5V is 180mA (with 2 LEDs blinking only)&lt;br /&gt;
&lt;br /&gt;
===Module Board===&lt;br /&gt;
*Functions&lt;br /&gt;
**Primary communication with other module boards via RS232 over short distance.&lt;br /&gt;
**Secondary communication with benchtop via RS458 over longer distance.&lt;br /&gt;
**Digital control I/O for 1 laser (e.g. on/off, detect temp overheat, current alarm)&lt;br /&gt;
**Analog input for data acquisation on power, current and temperature&lt;br /&gt;
**Analog output for power and current control&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 3.2 Module&lt;br /&gt;
! Digital Input !! Digital Output !! Analog Input !! Analog Output&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| 1. ICSP&lt;br /&gt;
| 1. LED&amp;lt;br&amp;gt; 2. Bi-color LED&amp;lt;br&amp;gt; 3. RS232&amp;lt;br&amp;gt; 4. RS458&amp;lt;br&amp;gt; 5. Case temp overheat&amp;lt;br&amp;gt; 6. Laser on/off 1,2&amp;lt;br&amp;gt; 7. Interlock&amp;lt;br&amp;gt; 8. Digital ctrl&amp;lt;br&amp;gt; 9. Current 0,1 alarm&amp;lt;br&amp;gt;&lt;br /&gt;
| 1. Case temp&amp;lt;br&amp;gt; 2. pow 0,1&amp;lt;br&amp;gt; 3. cur0&amp;lt;br&amp;gt; 4. temp0&lt;br /&gt;
| 1. 10-bit DAC&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Benchtop===&lt;br /&gt;
*Functions&lt;br /&gt;
**Primary communciation with module boards via RS485&lt;br /&gt;
**Secondary communication with other benchtops via RS232&lt;br /&gt;
**Digital I/O control for 2 lasers&lt;br /&gt;
**Analog inputs on power, current and temperature&lt;br /&gt;
**Analog outputs for power and current control&lt;br /&gt;
**LCD display and rotary key for user input&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 3.3 Base Benchtop&lt;br /&gt;
! Digital Input !! Digital Output !! Analog Input !! Analog Output&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| 1. ICSP&amp;lt;br&amp;gt; 2. Rotary Key&amp;lt;br&amp;gt; 3. Push Buttons&lt;br /&gt;
| 1. LED&amp;lt;br&amp;gt; 2. RS232&amp;lt;br&amp;gt; 3. RS458&amp;lt;br&amp;gt; 4.LCD display&amp;lt;br&amp;gt; 5. Buzzer&amp;lt;br&amp;gt; 6. Digital Ctrl 0,1&lt;br /&gt;
| 1. Case temp&amp;lt;br&amp;gt; 2. CurrentDetect 0,1&amp;lt;br&amp;gt; 3. PowerDetect 0,1,2,3&amp;lt;br&amp;gt; 4. TempDetect&lt;br /&gt;
| 1. 10-bit DAC (PowerCurrentCtrl 0,1)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Development Environment==&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
&lt;br /&gt;
[[Image:PIC_setup_win.JPG]]&lt;br /&gt;
&lt;br /&gt;
*C-Compiler, Assembler and Linker are under GNU license.&lt;br /&gt;
**MPLAB C30 C Compiler (*.c -&amp;gt; *.s)&lt;br /&gt;
**MPLAB ASM30 Assembler (*.s -&amp;gt; *.o)&lt;br /&gt;
**MPLAB LINK30 Linker (*.o -&amp;gt; *.bin)&lt;br /&gt;
&lt;br /&gt;
*PA optimizer, simulator, runtime libraries, header files, include files, and linker scripts are not covered by GNU. Reference is [http://direct.forum.microchip.com/tm.aspx?m=107208 here].&lt;br /&gt;
&lt;br /&gt;
*Microchip has integrated ASM30, LINK30, assembly header files, linker scripts in MPLAB IDE, which is free for download.&lt;br /&gt;
*MPLAB C30 costs US$895. A 60-day free student version is also available. After 60-days, the optimizer is automatically disabled, while other tools can still function properly. Refer to Table 2.4.&lt;br /&gt;
&lt;br /&gt;
*C-libraries contained in C30 includes (Refer to [http://ww1.microchip.com/downloads/en/DeviceDoc/16bit_Language_Tool_Libraries_51456c.pdf 16-Bit Language Tools Libraries] from Microchip).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 4.1 C Libraries in MPLAB C30&lt;br /&gt;
! Library !! Directory &amp;lt;br&amp;gt;(\\Microchip\MPLAB C30) !! Major functions&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| DSP Library &amp;lt;br&amp;gt;(e.g. libdsp-coff.a)&lt;br /&gt;
| \lib &amp;lt;br&amp;gt; \src\dsp &amp;lt;br&amp;gt; \support\h&lt;br /&gt;
| Vector, Matrix, Filter, etc.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| 16-Bit Peripheral Libraries &amp;lt;br&amp;gt;(e.g. libp30F5011-coff.a)&lt;br /&gt;
| \lib &amp;lt;br&amp;gt; \src\peripheral &amp;lt;br&amp;gt; \support\h&lt;br /&gt;
| ADC12, IOPort, UART, I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C, etc.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Standard C Libraries &amp;lt;br&amp;gt;(e.g. libc-coff.a, libm-coff.a, libpic-coff.a)&lt;br /&gt;
| \lib &amp;lt;br&amp;gt; \src\libm &amp;lt;br&amp;gt; \include&lt;br /&gt;
| stdio.h, time.h, float.h, math.h, &lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| MPLAB C30 Built-in Functions&lt;br /&gt;
| none&lt;br /&gt;
| _buildin_addab, _buildin_add, _buildinmpy, etc&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Linux===&lt;br /&gt;
&lt;br /&gt;
[[Image:PIC_setup_linux.JPG]]&lt;br /&gt;
&lt;br /&gt;
*C Compiler, Assembler and Linker are under GNU license.&lt;br /&gt;
**The code can be downloaded from Microchip at [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en023073 here].&lt;br /&gt;
**Current MPLAB ASM30 Assembler: v2.04&lt;br /&gt;
**Current MPLAB C30 Compiler: v2.04&lt;br /&gt;
&lt;br /&gt;
*[http://gcc.gnu.org/ml/gcc/2005-02/msg01144.html John Steele Scott] has made templates that can be readily used by Debian-based systems. Someone at http://noel.feld.cvut.cz/dspic/ has done the necessary conversion to *.deb already.&lt;br /&gt;
**Download '''pic30-1.32-debian.tar.bz2''' for Template v1.32. (For v2.01, please goto [http://thread.gmane.org/gmane.comp.hardware.microcontrollers.gnupic/3768/focus=3768  pic30-debian-2.01.tar.bz2]).&lt;br /&gt;
**Download '''pic30-binutils_1.32-1_i386.deb''' for the assember.&lt;br /&gt;
**Download '''pic30-gcc_1.32-1_i386.deb''' for the compiler.&lt;br /&gt;
&lt;br /&gt;
*'''Important Note''': Only the compiler is free. The header files and library is owned by Microchip. &lt;br /&gt;
**Thomas Sailer suggested to download the Student version of C30 compiler and then build the libraries without source code. A package template for Fedora system is available [http://www.baycom.org/~tom/dspic/ here].&lt;br /&gt;
**Instructions for filling the upstream direction is available [http://forum.microchip.com/printable.aspx?m=139360 here].&lt;br /&gt;
**Alteratively, [https://gna.org/projects/pic30-libc/ Stephan Walter] has started a project to develop C Runtime Library for dsPIC. &lt;br /&gt;
***Current libraries in version 0.1.1 include: assert.h, cdefs.h, ctype.h, errno.h, inttypes.h, stdint.h, stdio.h, stdlib.h, string.h&lt;br /&gt;
&lt;br /&gt;
*Burning Program Codes to Target Board&lt;br /&gt;
#Use 'dspicprg and dspicdmp' utilities developed by [http://homerreid.ath.cx/misc/dspicprg/ Homer Reid] to burn hex code (*.hex) to devices. See Reference [http://forum.microchip.com/tm.aspx?m=94243 here]. Through serial port only?&lt;br /&gt;
#Use [http://piklab.sourceforge.net/ Piklab IDE]. Details on file format not known.&lt;br /&gt;
#Use [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002 MPLAB IDE] to burn hex code (*.hex) to devices.&lt;br /&gt;
&lt;br /&gt;
===Code Optimization===&lt;br /&gt;
*Code Optimization under GNU license supports O0 and O1 only.&lt;br /&gt;
*MPLAB C-Compiler supports O0, O1, O2, Os and O3. The Student version will disable O2, Os, and O3 after 60 days.&lt;br /&gt;
*Below is a comparsion between different optimization levels for the project including drivers for 2 projects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 4.2 Comparison between differnt optimization levels&lt;br /&gt;
! Optimization !! Description !! Project 1&amp;lt;br&amp;gt;Code Size&amp;lt;br&amp;gt;(byte) !! Project 1&amp;lt;br&amp;gt;Data Usage&amp;lt;br&amp;gt;(byte) !! Project 2&amp;lt;br&amp;gt;Code Size&amp;lt;br&amp;gt;(byte) !! Project 2&amp;lt;br&amp;gt;Data Usage&amp;lt;br&amp;gt;(byte)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O0 &lt;br /&gt;
| No optimization&amp;lt;br&amp;gt;Fastest Compilation&lt;br /&gt;
| 6222 (9%) || 178 (4%) || 26,037 (38%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O1 &lt;br /&gt;
| Optimize&amp;lt;br&amp;gt; Tries to reduce code size and execution time.&lt;br /&gt;
| 4473 (6%) || 178 (4%) || 22,290 (32%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O2 &lt;br /&gt;
| Optimize even more&amp;lt;br&amp;gt; Performs nearly all supported optimizations &amp;lt;br&amp;gt;that do not involve a space-speed trade-off. &amp;lt;br&amp;gt;Increases both compilation time and the &amp;lt;br&amp;gt;performance of the generated code.&lt;br /&gt;
| 4422 (6%) || 178 (4%) || 21,993 (32%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O3 &lt;br /&gt;
| Optimize yet more. &amp;lt;br&amp;gt;O3 turns on all optimizations specified by O2 &amp;lt;br&amp;gt;and also turns on the inline-functions option.&lt;br /&gt;
| 4485 (6%) || 178 (4%) || 22,176 (32%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Os &lt;br /&gt;
| Optimize for size. &amp;lt;br&amp;gt;Os enables all O2 optimizations that do not &amp;lt;br&amp;gt;typically increase code size. It also performs &amp;lt;br&amp;gt;further optimizations designed to reduce code &amp;lt;br&amp;gt;size.&lt;br /&gt;
| 4356 (6%) || 178 (4%) || 21,885 (32%) || 710 (17%)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Software Architecture==&lt;br /&gt;
   +----------+-----------+---------+---------+&lt;br /&gt;
   |   local  |  remote   |         |         |&lt;br /&gt;
   +----------+-----------+  host   |   UI    |&lt;br /&gt;
   |      data access     | channel |         |&lt;br /&gt;
   |     (DI,DO,AI,AO)    |         |         |&lt;br /&gt;
   +----------------------+---------+---------+&lt;br /&gt;
   |               Application                |&lt;br /&gt;
   |                                          |&lt;br /&gt;
   +------------------------------------------+&lt;br /&gt;
   |            Applications Model            |&lt;br /&gt;
   |       +--------------+-----------+       |&lt;br /&gt;
   |       |    GUI       |   CLib    |       |&lt;br /&gt;
   |       |       +------+-----------+-------+&lt;br /&gt;
   |       |       |     Operating System     |&lt;br /&gt;
   +-------+-------+--------------------------+&lt;br /&gt;
   |                Drivers                   |   &lt;br /&gt;
   +------------------------------------------+&lt;br /&gt;
   |               Hardware                   |   &lt;br /&gt;
   +------------------------------------------+&lt;br /&gt;
*Currently, operating system is based on [http://www.psocdeveloper.com/forums/viewtopic.php?p=973&amp;amp;sid=717d6b7e86472a5036f7cfbbcb0c05aa linlike8]. The possibility of using other OS (e.g. [http://www.freertos.org/ FreeRTOS]) will be explored later.&lt;br /&gt;
*Software Drivers are to be developed to allow users at Application Level to use the hardware (e.g. ADC, DAC, UART, EEPROM) through the OS.&lt;br /&gt;
*The interface between the drivers and the OS should be compliant with [http://www.die.net/doc/linux/man/man2/ POSIX standard] for Linux (e.g. open(), write(), read(), ioctl() etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming Tips==&lt;br /&gt;
&lt;br /&gt;
===Memory Map for 5011===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.1 Memory Location&lt;br /&gt;
! Type !! Start Address !! End Address !! Size&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Flash || 0x000000 ||0x00AFFF || 44K&amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: Reset Vector || 0x000000 ||0x000003 || 4&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: Interrupt Vector Table || 0x000004 ||0x00007F || 124&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: Alternate Vector Table || 0x000084 ||0x0000FF || 124&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: User Program || 0x000100 ||0x00AFFF || 43.7K&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| EEPROM || 0x7FFC00 || 0x7FFFFF || 1K&amp;lt;sup&amp;gt;[2]&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Programming Executive || 0x800000 || 0x8005BF || 1472&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Unit ID || 0x8005C0 || 0x8005FF || 64&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Config  Registers || 0xF80000 || 0xF8000F || 16&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Device ID || 0xFF0000 || 0xFF0003 || 4&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[1] Each address is 16-bit wide. Every two addresses correspond to a 24-bit instruction. Each even address contains 2 valid bytes; each odd address contains 1 valid byte plus 1 phathom byte.&amp;lt;br&amp;gt;&lt;br /&gt;
[2] Each address is 8-bit wide.&lt;br /&gt;
&lt;br /&gt;
===Data Location===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.2 Data Location&lt;br /&gt;
! Type !! Description !! Example&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _XBSS(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in X-memory, aligned at N, no initilization&lt;br /&gt;
| int _XBSS(32) xbuf[16];&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _XDATA(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in X-memory, aligned at N, with initilization&lt;br /&gt;
| int _XDATA(32) xbuf[] = {1, 2, 3, 4, 5};&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _YBSS(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in Y-memory, aligned at N, no initilization&lt;br /&gt;
| int _YBSS(32) ybuf[16];&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _YDATA(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in Y-memory, aligned at N, with initilization&lt;br /&gt;
| int _YDATA(32) ybuf[16] = {1, 2, 3, 4, 5};&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(const)))&lt;br /&gt;
| Flash ROM data, constant, accessed by normal C&amp;lt;br&amp;gt;statements, but 32K max.&lt;br /&gt;
| int i __attribute__((space(const))) = 10;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(prog)))&lt;br /&gt;
| Flash ROM data, read/write by program space visibility&amp;lt;br&amp;gt;window (psv)&lt;br /&gt;
| int i __attribute__((space(prog)));&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(auto_psv)))&lt;br /&gt;
| Flash ROM data, read by normal C statements, write&amp;lt;br&amp;gt;by accessing psv&lt;br /&gt;
| int i __attribute__((space(auto_psv)));&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(psv)))&lt;br /&gt;
| Flash ROM data, read/write by (psv)&lt;br /&gt;
| int i __attribute__((space(psv)));&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _EEDATA(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| ROM Data in EEPROM, aligned at N, read/write with psv&lt;br /&gt;
| int _EEDATA(2) table[]={0, 1, 2, 3, 5, 8};&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _PERSISTENT&lt;br /&gt;
| RAM Data, data remain after reset&lt;br /&gt;
| int _PERSISTENT var1, var2;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _NEAR&lt;br /&gt;
| RAM Data at near section&lt;br /&gt;
| int _NEAR var1, var2;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _ISR&lt;br /&gt;
| Interrupt service rountine&lt;br /&gt;
| void _ISR _INT0Interrupt(void);&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _ISRFAST&lt;br /&gt;
| Fast interrupt service rountine&lt;br /&gt;
| void _ISRFAST _T0Interrupt(void);&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
#N must be a power of two, with a minimum value of 2.&lt;br /&gt;
&lt;br /&gt;
===Configuration Bits===&lt;br /&gt;
----&lt;br /&gt;
*System clock source can be provided by:&lt;br /&gt;
#Primary oscillator (OSC1, OSC2)&lt;br /&gt;
#Secondary oscillator (SOSCO and SOSCI) with 32kHz crystal&lt;br /&gt;
#Internal Fast RC (FRC) oscillator at 7.37MHz (7372800Hz)&lt;br /&gt;
#Low-Power RC (LPRC) oscillator (Watchdog Timer) at 512 kHz.&lt;br /&gt;
*These clock sources can be incorporated with interal Phase-locked-loop (PLL) x4, x8 or x16 to yield the osciallator frequrence F&amp;lt;sub&amp;gt;OSC&amp;lt;/sub&amp;gt;&lt;br /&gt;
*The system clock is divided by 4 to yield the internal instruction cycle clock, F&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;=F&amp;lt;sub&amp;gt;OSC&amp;lt;/sub&amp;gt;/4&lt;br /&gt;
*FRC with PLLx16 is used to achieve F&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;=29.49MHz (29491200Hz or 30MIPS)&lt;br /&gt;
&lt;br /&gt;
  //The code (MACRO) below is to be placed at the top of program (before main)&lt;br /&gt;
     _FOSC(CSW_FSCM_OFF &amp;amp; FRC_PLL16);&lt;br /&gt;
     _FWDT(WDT_OFF);    //Turn off Watchdog Timer&lt;br /&gt;
     _FBORPOR(PBOR_ON &amp;amp; BORV_27 &amp;amp; MCLR_DIS &amp;amp; PWRT_16);&lt;br /&gt;
     _FGS(CODE_PROT_OFF); //Disable Code Protection&lt;br /&gt;
&lt;br /&gt;
===Timer===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Each timer is 16-bit (i.e. counting from 0 to 65535).&lt;br /&gt;
*Timer 2 and 3 can be incorporated together to form a 32-bit timer.&lt;br /&gt;
*Prescale is the ratio between timer counts and system clock counts. Prescales of 1:1, 1:8, 1:64 and 1:256 are available.&lt;br /&gt;
*Timers may be used to implement free time clock or mesaure time.&lt;br /&gt;
&lt;br /&gt;
====Free Time Clock====&lt;br /&gt;
*Let required time for ticking be PERIOD.&lt;br /&gt;
*Number of instruction cycles during PERIOD = PERIOD*F&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt; cycles&lt;br /&gt;
*Using a prescale of 1:x, the timer period count register = # of cycles/x&lt;br /&gt;
*e.g. PERIOD = 10ms; # of cycles = 10ms*30MHz = 300000 cylces; Using 1:64 Prescale, register setting = 300000/64 = 4688&lt;br /&gt;
   void time_init(void){&lt;br /&gt;
      TMR1 = 0;		// Clear register&lt;br /&gt;
      PR1 = 4688;	// Set period&lt;br /&gt;
      //============================================================&lt;br /&gt;
      _T1IF = 0;		// Clear interrupt flag&lt;br /&gt;
      _T1IE = 1;		// Enable interrupts&lt;br /&gt;
      //============================================================&lt;br /&gt;
      T1CONbits.TCS = 0;		// Use internal clock source&lt;br /&gt;
      T1CONbits.TCKPS = 2;	// Prescale Select 1:64&lt;br /&gt;
      T1CONbits.TON = 1;		// Start the timer &lt;br /&gt;
   }&lt;br /&gt;
   //********************************************************************&lt;br /&gt;
   void _ISRFAST _T1Interrupt(void){&lt;br /&gt;
      _T1IF = 0;		// Clear interrupt flag&lt;br /&gt;
      //Place user code here&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
====Time Measurement====&lt;br /&gt;
*To measure the time taken for action(), use the code below:&lt;br /&gt;
   unsigned int measure_time(void){	&lt;br /&gt;
      PR3 = 0xFFFF;		// Set counter to maximum&lt;br /&gt;
      _T3IF = 0;			// Clear interrupt flag&lt;br /&gt;
      _T3IE = 0;			// Disable interrupt&lt;br /&gt;
      T3CONbits.TON = 1;		// Start the timer, TMR3 count up&lt;br /&gt;
      TMR3 = 0;			//Clear TMR3 to start count up&lt;br /&gt;
      //====================================================&lt;br /&gt;
      //Add code here to wait for something to happen&lt;br /&gt;
      action();&lt;br /&gt;
      //====================================================&lt;br /&gt;
      T3CONbits.TON = 0;	//Stop the timer&lt;br /&gt;
      //====================================================&lt;br /&gt;
      return (unsigned int) TMR3/FCY;      //TMR/FCY yields the actual time&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
===Interrupt===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Registers are involved in Interrupts includes: &lt;br /&gt;
#Interrupt Flag Status (IFS0-IFS2) registers&lt;br /&gt;
#Interrupt Enable Control (IEC0-IEC2) registers&lt;br /&gt;
#Interrupt Priority Control (IPC0-IPC10) registers&lt;br /&gt;
#Interrupt Priority Level (IPL) register&lt;br /&gt;
#Global Interrupt Control (INTCON1, INTCON2) registers&lt;br /&gt;
#Interrupt vector (INTTREG) register&lt;br /&gt;
*User may assign priority level 0-7 to a specific interrupt using IPC. Setting priority to 0 disable a specific interrupt. Level 7 interrupt has the highest priority.&lt;br /&gt;
*Current priority level is stored in IPL. Setting IPL to 7 disables all interrupts (except traps). The following MACROs are defined in &amp;lt;p30f5011.h&amp;gt;:&lt;br /&gt;
#SET_CPU_IPL(ipl): Set IPL to ipl&lt;br /&gt;
#SET_AND_SAVE_CPU_IPL(save_to, ipl): Store the current IPL to save_to and then set to ipl&lt;br /&gt;
#RESTORE_CPU_IPL(saved_to): Restore the previously saved ipl&lt;br /&gt;
*sti() and cli() are defined to enable and disable global interrupts for time critical functions:&lt;br /&gt;
  extern int SAVE_IPL;&lt;br /&gt;
  #define sti()	RESTORE_CPU_IPL(SAVE_IPL)&lt;br /&gt;
  #define cli()	SET_AND_SAVE_CPU_IPL(SAVE_IPL, 7)&lt;br /&gt;
  //============================================================&lt;br /&gt;
  char adc_ioctl(unsigned char request, unsigned char* argp){&lt;br /&gt;
    //...&lt;br /&gt;
    cli();		//Disable global interrupt&lt;br /&gt;
    for(;ch&amp;lt;=argp[0];ch++)&lt;br /&gt;
       adc_add_ch(argp[ch]);	//Add adc channels&lt;br /&gt;
    sti();		//Enable global interrupt&lt;br /&gt;
    //...&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
===UART===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*5011 provides two UART channels UxART, for x=1, 2.&lt;br /&gt;
*UxMODE, UxSTA, UxBRG are registers used to set the mode, indicate the status, and set the baud rate respectively.&lt;br /&gt;
*For UART communications compatiable with RS232 standard, an external driver (e.g. MAX3232ESE) is needed.&lt;br /&gt;
*For UART communications compatiable with RS485 standard, an external driver (e.g. DS3695N) is needed.&lt;br /&gt;
====Auto baud rate detection====&lt;br /&gt;
*The method is provided by [http://www.opencircuits.com/DsPIC30F_5011_Development_Board ingenia bootloader].&lt;br /&gt;
*The PC sends a ASCII character 'U' (0x55) to the target board.&lt;br /&gt;
*On the first rising edge of the start bit, the target board starts the timer.&lt;br /&gt;
*At the fifth rising edge, the timer is stopped, let the count number be ''t_count''. &lt;br /&gt;
**The measured period corresponds to 8 bits transmitted at a baud rate ''uxbrg''.&lt;br /&gt;
     _   _   _   _   _   _&lt;br /&gt;
   _|S|_|1|_|1|_|1|_|1|_|S|_  (S = Start Bit)&lt;br /&gt;
    &amp;lt;---------------&amp;gt;&lt;br /&gt;
    Measured Time&lt;br /&gt;
*The relationship between ''uxbrg'' and ''TMR'' is&lt;br /&gt;
   Measured Time (in seconds) = t_count/F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;&lt;br /&gt;
   uxbrg = 1/(Measured Time/8)&lt;br /&gt;
         = 8*F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/t_count&lt;br /&gt;
*Since UxBRG is computed by:&lt;br /&gt;
   UxBRG = (F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/(16*Baudrate)) -1&lt;br /&gt;
         = (F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/(16*8*F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/t_count)) -1&lt;br /&gt;
         = t_count/128 -1&lt;br /&gt;
*The following is the code for auto baud rate detection for U2ART:&lt;br /&gt;
   unsigned int uart2_autobaud(void){&lt;br /&gt;
      U2MODEbits.ABAUD = 1;		//Enable Autobaud detect from U2RX (from IC2 if 0)&lt;br /&gt;
      U2MODEbits.UARTEN = 1;		//U2ART enable&lt;br /&gt;
      //Timer 3 Config==========================================================&lt;br /&gt;
      PR3 = 0xFFFF;			// Set counter to maximum&lt;br /&gt;
      _T3IF = 0;			// Clear interrupt flag&lt;br /&gt;
      _T3IE = 0;			// Disable interrupt&lt;br /&gt;
      T3CONbits.TON = 1;		// Start the timer, TMR3 count up&lt;br /&gt;
      //Input Capture Config====================================================&lt;br /&gt;
      IC2CONbits.ICM = 3;		//Detect rising	&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      _IC2IE = 0; 			//Disable interrupt&lt;br /&gt;
      //Start Auto baud detection===============================================&lt;br /&gt;
      unsigned int i=0;&lt;br /&gt;
      cli();				//Disable Global Interrupt&lt;br /&gt;
      while(!_IC2IF);			//1st rising edge detected&lt;br /&gt;
      TMR3 = 0;			//Clear TMR3 to start count up&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//2nd rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//3rd rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//4th rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//5th rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      T3CONbits.TON = 0;		//Stop the timer&lt;br /&gt;
      sti(); 			//Enable Global Interrupt&lt;br /&gt;
      //Compute value for BRG register==========================================&lt;br /&gt;
      unsigned int time;&lt;br /&gt;
      time = ((TMR3+0x40)&amp;gt;&amp;gt;7)-1;	//+0x40 for rounding&lt;br /&gt;
      //========================================================================&lt;br /&gt;
      return time;&lt;br /&gt;
   }&lt;br /&gt;
*For 30MIP, tested speeds of transmission include 9600bps, 19200bps, 28800bps, 38400bps and 57600bps.&lt;br /&gt;
====Initialize UART====&lt;br /&gt;
   void uart2_init(void){&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Baud rate&lt;br /&gt;
      //  +-- Default Baud rate = 19.2 kbps&lt;br /&gt;
      //	+-- U2BRG = 30e6 / (16 * 19200) - 1 = 97&lt;br /&gt;
      unsigned int u2brg = 97; &lt;br /&gt;
      #if(AUTO_BAUD_DECT&amp;gt;0)&lt;br /&gt;
      u2brg = uart2_autobaud();&lt;br /&gt;
      #endif&lt;br /&gt;
      U2BRG  = u2brg;					&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Disable U2ART&lt;br /&gt;
      U2MODEbits.UARTEN = 0;			//Disable U2ART module&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Interrupt Priority&lt;br /&gt;
      _U2RXIF = 0;	//Clear Rx interrupt flags&lt;br /&gt;
      _U2TXIF = 0;	//Clear Tx interrupt flags&lt;br /&gt;
      _U2RXIE = 1;	//Receive interrupt: 0 disable, 1 enable &lt;br /&gt;
      _U2TXIE = 1;	//Transmit interrupt: 0 disable, 1 enable&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Mode&lt;br /&gt;
      //  +--Default: 8N1, no loopback, no wake in sleep mode, continue in idle mode&lt;br /&gt;
      //  +--Diable autobaud detect&lt;br /&gt;
      //  +--Enable U2ART module&lt;br /&gt;
      U2MODEbits.ABAUD = 0;	//Disable Autobaud detect from U2RX &lt;br /&gt;
      U2MODEbits.UARTEN = 1;	//U2ART enable&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Status&lt;br /&gt;
      //  +--Default: TxInt when a char is transmitted, no break char&lt;br /&gt;
      //  +--Default: RxInt when a char is received, no address detect, clear overflow&lt;br /&gt;
      //  +--Enable Transmit&lt;br /&gt;
      U2STAbits.UTXEN = 1;	//Tx enable&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
====Sending and Receiving Data====&lt;br /&gt;
   void _ISR _U2TXInterrupt(void){&lt;br /&gt;
      _U2TXIF = 0;	//Clear Interrupt Flag&lt;br /&gt;
      if(tx_data_ready())&lt;br /&gt;
         U2TXREG = tx_buf[POS]; 	//send next byte...&lt;br /&gt;
   }&lt;br /&gt;
   void _ISR _U2RXInterrupt(void){&lt;br /&gt;
      _U2RXIF = 0;		//Clear the flag&lt;br /&gt;
      if ( U2STAbits.URXDA ){&lt;br /&gt;
         rx_buf[POS] = (unsigned char) U2RXREG; //Read the data from buffer&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
===I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Two lines are devoted for the serial communication. SCL for clock, SDA for data.&lt;br /&gt;
*Standard communication speed includes&lt;br /&gt;
#Standard speed mode: 100kHz&lt;br /&gt;
#Fast speed mode: 400kHz&lt;br /&gt;
#High speed mode: 3.4MHz&lt;br /&gt;
*dsPIC30f5011 supports standard and fast speed modes. The maximum speed attainable is 1MHz.&lt;br /&gt;
*Pull-up resistors are required for both SCL and SDA. Minimum pull-up resistance is given by:&lt;br /&gt;
     Pull-up resistor (min) = (V&amp;lt;sub&amp;gt;dd&amp;lt;/sub&amp;gt;-0.4)/0.003  ......  [See section 21.8 in Family reference manual]&lt;br /&gt;
*2.2Kohm is typical for standard speed mode.&lt;br /&gt;
*After initiating a start/stop/restart bit, add a small delay (e.g. no operation) before polling the corresponding control bit (hardware controlled). For example: &lt;br /&gt;
      StartI2C();&amp;lt;br&amp;gt;				&lt;br /&gt;
      Nop();			//A small delay for hardware to respond&amp;lt;br&amp;gt;&lt;br /&gt;
      while(I2CCONbits.SEN);	//Wait till Start sequence is completed&lt;br /&gt;
*After sending a byte and receiving an acknowledgement from the slave device, ensure to change to idle state. For example:&lt;br /&gt;
      MasterWriteI2C(0x55);&amp;lt;br&amp;gt;&lt;br /&gt;
      while(I2CSTATbits.TBF);		//Wait for transmit buffer to empty&amp;lt;br&amp;gt;&lt;br /&gt;
      while(I2CSTATbits.ACKSTAT);	//Wait for slave acknowledgement&amp;lt;br&amp;gt;&lt;br /&gt;
      IdleI2C();&lt;br /&gt;
&lt;br /&gt;
===ADC===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*12-bit ADC: (Max 16 Channels)&lt;br /&gt;
*Allow a maximum of 2 sets of analog input multiplexer configurations, MUX A and MUX B (Normally use one only).&lt;br /&gt;
*A maximum of 200kps of sampling rate when using auto sampling mode.&lt;br /&gt;
====Configuration====&lt;br /&gt;
*Interrupt: Clear ADC interrupt flag and enable ADC interrupt. The ADC module will be set to interrupt when the specified channels are updated.&lt;br /&gt;
   _ADIF = 0;				//clear ADC interrupt flag&lt;br /&gt;
   _ADIE = 1;				//enable adc interrupt&lt;br /&gt;
*I/O: Set the corresponding TRISBX bits (digit i/o config) to input (i.e. = 1), and set corresponding bits in ADPCFG (analog config) to zero.&lt;br /&gt;
   _TRISB2 = 1;		//Set AN2 [Case Temp] as analog input&lt;br /&gt;
   _TRISB8 = 1;		//Set AN8 [Power detect 0] as analog input&lt;br /&gt;
   _TRISB9 = 1;		//Set AN9 [Power detect 1] as analog input&lt;br /&gt;
   _TRISB10 = 1;		//Set AN10 [Current detect 0] as analog input&lt;br /&gt;
   _TRISB11 = 1;		//Set AN11 [Temp detect 0] as analog input&lt;br /&gt;
   ADPCFG = 0xF0FB;	//0 =&amp;gt; Analog, 1 =&amp;gt; Digital&lt;br /&gt;
*Scanning Mode: Scan mode is used. In this mode, the Sample and Hold (S/H) is switched between the channels specified by ADCSSL (Scan select register).&lt;br /&gt;
   ADCSSL = 0x0F04;	//0 =&amp;gt; Skip, 1 =&amp;gt; Scan&lt;br /&gt;
*Reference Voltage for S/H: Only MUX A is used. By default, the negative reference voltage of the S/H is connected to V&amp;lt;sub&amp;gt;REF-&amp;lt;/sub&amp;gt;.&lt;br /&gt;
   ADCHSbits.CH0NA = 0;&lt;br /&gt;
*Sampling Rate: T&amp;lt;sub&amp;gt;AD&amp;lt;/sub&amp;gt; refers to the time unit for the ADC clock. To configure the ADC module at 200kbps, the minimum sampling time of 1T&amp;lt;sub&amp;gt;AD&amp;lt;/sub&amp;gt; = 334ns is required. ADCS&amp;lt;5:0&amp;gt; in ADCON3 register is used to set the time, which is given by:&lt;br /&gt;
      ADCS&amp;lt;5:0&amp;gt; = 2(T&amp;lt;sub&amp;gt;AD&amp;lt;/sub&amp;gt;/T&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;)-1 &lt;br /&gt;
                = 2(334e-9/33.34e-9)-1 &lt;br /&gt;
                = 19&lt;br /&gt;
&lt;br /&gt;
      ADCON3bits.SAMC = 1;	//1TAD for sampling time&lt;br /&gt;
      ADCON3bits.ADRC = 1;	//Use internal ADC clock&lt;br /&gt;
      ADCON3bits.ADCS = 19;	//Set TAD = 334ns&lt;br /&gt;
*Settings for ADC Operation: For 200kbps operation, the voltage references for the ADC voltage are connected to V&amp;lt;sub&amp;gt;REF+&amp;lt;/sub&amp;gt; and V&amp;lt;sub&amp;gt;REF-&amp;lt;/sub&amp;gt;. Scan input is enabled, and the module will generate an interrupt when all selected channels have been scanned.&lt;br /&gt;
      ADCON2bits.VCFG = 3;	//External Vref+, Vref-&lt;br /&gt;
      ADCON2bits.CSCNA = 1;	//Scan input&lt;br /&gt;
      ADCON2bits.SMPI = 4;	//take 5 samples (one sample per channel) per interrupt&lt;br /&gt;
*More Settings for ADC Operation: Turn on the module, select the data output format as unsigned integer, and allow auto setting of SAMP bit (auto sampling).&lt;br /&gt;
      ADCON1bits.ADON = 1;	//Turn on module&lt;br /&gt;
      ADCON1bits.FORM = 0;	//[2 fractional]; [3 siged fractional]&lt;br /&gt;
      ADCON1bits.SSRC = 7;	//auto covert, using internal clock source&lt;br /&gt;
      ADCON1bits.ASAM = 1;	//auto setting of SAMP bit&lt;br /&gt;
====Storing ADC Data====&lt;br /&gt;
*16 registers (ADCBUF0 -ADCBUF15) are dedicated to store the ADC data between interrupts. However, the data in ADCBUFx does not necessarily correspond to the data taken for channel x. Since the lowest register will always be filled first, when some of the channels are not scanned (i.e. skipped), care must be taken. The following code checks the ADCSSL register for the current scanning channels and moves the data to the corresponding position in *adc_buf.&lt;br /&gt;
      void _ISR _ADCInterrupt(void){&lt;br /&gt;
           _ADIF = 0;	//Clear adc interrupt&lt;br /&gt;
           //==========================================================&lt;br /&gt;
           unsigned char channel = 0;&lt;br /&gt;
           unsigned char buffer = 0;&lt;br /&gt;
           for (; channel&amp;lt;ADC_MAX_CH; channel++){&lt;br /&gt;
               if(adc_ch_updated(channel)){	//Check if channel has updated&lt;br /&gt;
                    adc_buf[channel] = ADC16Ptr[buffer]; //Copy data to adc_buf&lt;br /&gt;
                    buffer++;&lt;br /&gt;
               }&lt;br /&gt;
           }&lt;br /&gt;
      }&lt;br /&gt;
      unsigned char adc_ch_updated(unsigned char ch){&lt;br /&gt;
           unsigned int mask;&lt;br /&gt;
           mask = 0x0001 &amp;lt;&amp;lt; ch;&lt;br /&gt;
           if(ADCSSL &amp;amp; mask)&lt;br /&gt;
              return 1;&lt;br /&gt;
         return 0;&lt;br /&gt;
      }&lt;br /&gt;
====Adding and Removing Channels====&lt;br /&gt;
*Channels may be added or removed by changing _TRISBX, ADPCFG, ADCSSL and ADCON2bits.SMPI.&lt;br /&gt;
   void adc_add_ch(unsigned char ch){&lt;br /&gt;
      //Enable i/o pin as input===========================================&lt;br /&gt;
      switch(ch){&lt;br /&gt;
        case 0: _TRISB0 = 1; break;&lt;br /&gt;
        case 1: _TRISB1 = 1; break;&lt;br /&gt;
        case 2: _TRISB2 = 1; break;&lt;br /&gt;
        case 3: _TRISB3 = 1; break;&lt;br /&gt;
        case 4: _TRISB4 = 1; break;&lt;br /&gt;
        case 5: _TRISB5 = 1; break;&lt;br /&gt;
        case 6: _TRISB6 = 1; break;&lt;br /&gt;
        case 7: _TRISB7 = 1; break;&lt;br /&gt;
        case 8: _TRISB8 = 1; break;&lt;br /&gt;
        case 9: _TRISB9 = 1; break;&lt;br /&gt;
        case 10: _TRISB10 = 1; break;&lt;br /&gt;
        case 11: _TRISB11 = 1; break;&lt;br /&gt;
        case 12: _TRISB12 = 1; break;&lt;br /&gt;
        case 13: _TRISB13 = 1; break;&lt;br /&gt;
        case 14: _TRISB14 = 1; break;&lt;br /&gt;
        default: _TRISB15 = 1;&lt;br /&gt;
      }&lt;br /&gt;
      unsigned int mask;&lt;br /&gt;
      mask = 0x0001 &amp;lt;&amp;lt; ch;&lt;br /&gt;
      ADCSSL = ADCSSL | mask;		 &lt;br /&gt;
      ADPCFG = ~ADCSSL;&lt;br /&gt;
      ADCON2bits.SMPI++;	//take one more sample per interrupt&lt;br /&gt;
   }&lt;br /&gt;
   void adc_rm_ch(unsigned char ch){&lt;br /&gt;
      unsigned int mask;&lt;br /&gt;
      mask = 0x0001 &amp;lt;&amp;lt; ch;&lt;br /&gt;
      ADPCFG = ADPCFG | mask;&lt;br /&gt;
      ADCSSL = ~ADPCFG;&lt;br /&gt;
      ADCON2bits.SMPI--;	//take one less sample per interrupt&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
===EEPROM===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*5011 has 1024 bytes of EEPROM, readable and writable under normal voltage (5V).&lt;br /&gt;
*To use, declare:&lt;br /&gt;
  unsigned char _EEDATA(2) eeData[1024]={ 0x00, 0x00, 0x00, 0x00, .... }&lt;br /&gt;
  unsigned int byte_pointer = 0;&lt;br /&gt;
====Seek====&lt;br /&gt;
*This function moves the pointer to the desired position before a reading/writing operation is performed.&lt;br /&gt;
   int eeprom_lseek(int offset, unsigned char whence){&lt;br /&gt;
      byte_pointer = offset;&lt;br /&gt;
      return byte_pointer;&lt;br /&gt;
   }&lt;br /&gt;
====Read====&lt;br /&gt;
*This function read ''count'' bytes from the eeprom.&lt;br /&gt;
   int eeprom_read(unsigned char* buf, int count){&lt;br /&gt;
      int i=0;&lt;br /&gt;
      for(; i&amp;lt;count &amp;amp;&amp;amp; byte_pointer &amp;lt; 1024; i++){&lt;br /&gt;
         readEEByte( __builtin_tblpage(eeData), &lt;br /&gt;
                     __builtin_tbloffset(eeData) + byte_pointer, &lt;br /&gt;
                     &amp;amp;buf[i]);&lt;br /&gt;
         byte_pointer++;		//Update global pointer&lt;br /&gt;
      }&lt;br /&gt;
      return i;	//read i bytes successful	&lt;br /&gt;
   }&lt;br /&gt;
*readEEByte() is implemented in assembly code as follows:&lt;br /&gt;
   .global _readEEByte&lt;br /&gt;
   _readEEByte:&lt;br /&gt;
      push      TBLPAG		;w0 = base of eeData&lt;br /&gt;
      mov       w0, TBLPAG	;w1 = offset for eeData in byte&lt;br /&gt;
      tblrdl.b  [w1], [w2]	;w2 = pointer to user buffer&lt;br /&gt;
      pop     	TBLPAG&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
====Write====&lt;br /&gt;
*This function write ''count'' bytes to eeprom.&lt;br /&gt;
   int eeprom_write(unsigned char* buf, int count){&lt;br /&gt;
      char isOddAddr = byte_pointer%2;	//current address is odd&lt;br /&gt;
      char isOddByte = count%2;		//number of bytes to write is odd&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      unsigned int word_offset = byte_pointer&amp;gt;&amp;gt;1; //div by 2 and round down&lt;br /&gt;
      int max_write;&lt;br /&gt;
      max_write = (isOddAddr == 0 &amp;amp;&amp;amp; isOddByte == 0) ? (count&amp;gt;&amp;gt;1) : (count&amp;gt;&amp;gt;1)+1;&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      unsigned int word_data;	//Store word to be written&lt;br /&gt;
      int byte_wr = 0;		//number of bytes written, i.e buffer pointer&lt;br /&gt;
      int i = 0;&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      for(; i&amp;lt;max_write &amp;amp;&amp;amp; word_offset&amp;lt;512; i++, word_offset++){&lt;br /&gt;
         if(i==0 &amp;amp;&amp;amp; isOddAddr){&lt;br /&gt;
            //First byte not used&lt;br /&gt;
            //============================================save first byte&lt;br /&gt;
            readEEByte( __builtin_tblpage(eeData), &lt;br /&gt;
                        __builtin_tbloffset(eeData) + byte_pointer - 1,&lt;br /&gt;
                        &amp;amp;word_data);&lt;br /&gt;
            //===========================================================&lt;br /&gt;
            word_data = ((unsigned int)buf[0] &amp;lt;&amp;lt; 8) + (0xFF &amp;amp; word_data);&lt;br /&gt;
            byte_wr++;				//Update buffer pointer&lt;br /&gt;
            byte_pointer++;			//Update global pointer&lt;br /&gt;
          } else if(i==max_write-1 &amp;amp;&amp;amp; ((isOddAddr &amp;amp;&amp;amp; sOddByte==0)||(isOddAddr==0 &amp;amp;&amp;amp; isOddByte))){&lt;br /&gt;
            //Last byte not used&lt;br /&gt;
            //=============================================save last byte&lt;br /&gt;
            readEEByte(	__builtin_tblpage(eeData), &lt;br /&gt;
                        __builtin_tbloffset(eeData) + byte_pointer + 1,&lt;br /&gt;
                        &amp;amp;word_data);&lt;br /&gt;
            //============================================================&lt;br /&gt;
            word_data = (word_data &amp;lt;&amp;lt; 8) + buf[byte_wr];&lt;br /&gt;
            byte_wr++;				//Update buffer pointer&lt;br /&gt;
            byte_pointer++;			//Update global pointer&lt;br /&gt;
          } else{&lt;br /&gt;
            //Both bytes valid&lt;br /&gt;
            word_data = ((unsigned int)buf[byte_wr+1] &amp;lt;&amp;lt; 8) + buf[byte_wr];&lt;br /&gt;
            byte_wr+=2;				//Update buffer pointer&lt;br /&gt;
            byte_pointer+=2;		//Update global pointer&lt;br /&gt;
          }&lt;br /&gt;
       //==================================================================&lt;br /&gt;
       eraseEEWord( __builtin_tblpage(eeData), &lt;br /&gt;
                    __builtin_tbloffset(eeData) + 2*word_offset);&lt;br /&gt;
       writeEEWord( __builtin_tblpage(eeData), &lt;br /&gt;
                    __builtin_tbloffset(eeData) + 2*word_offset,&lt;br /&gt;
                    &amp;amp;word_data);&lt;br /&gt;
       //==================================================================&lt;br /&gt;
       }&lt;br /&gt;
       return byte_wr;		//No. of byte written&lt;br /&gt;
   }&lt;br /&gt;
*eraseEEWord and writeEEWord are implemented in assembly.&lt;br /&gt;
   .global _eraseEEWord&lt;br /&gt;
   _eraseEEWord:&lt;br /&gt;
      push   TBLPAG				&lt;br /&gt;
      mov    w0, NVMADRU	;w0 = base of eeData&lt;br /&gt;
      mov    w1, NVMADR		;w1 = offset for eeData in word&lt;br /&gt;
      mov    #0x4044, w0			&lt;br /&gt;
      mov    w0, NVMCON		;Set to erase operation&lt;br /&gt;
      push   SR			;Disable global interrupts&lt;br /&gt;
      mov    #0x00E0, w0&lt;br /&gt;
      ior    SR&lt;br /&gt;
      mov    #0x55, w0 		;Write the KEY sequence&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      mov    #0xAA, w0			&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      bset   NVMCON, #15	;Start the erase cycle, bit 15 = WR&lt;br /&gt;
      nop&lt;br /&gt;
      nop&lt;br /&gt;
  L1: btsc   NVMCON, #15	;while(NVMCONbits.WR)&lt;br /&gt;
      bra    L1&lt;br /&gt;
      clr    w0&lt;br /&gt;
      pop    SR			;Enable global interrupts&lt;br /&gt;
      pop    TBLPAG&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
  .global _writeEEWord&lt;br /&gt;
  _writeEEWord:&lt;br /&gt;
      push   TBLPAG		;w0 = base of eeData&lt;br /&gt;
      mov    w0, TBLPAG		;w1 = offset for eeData in byte&lt;br /&gt;
      tblwtl [w2], [w1]		;w2 = pointer to user buffer&lt;br /&gt;
      mov    #0x4004, w0        ;Set to write operation&lt;br /&gt;
      MOV    w0, NVMCON&lt;br /&gt;
      push   SR			;Disable global interrupts&lt;br /&gt;
      mov    #0x00E0, w0&lt;br /&gt;
      ior    SR&lt;br /&gt;
      mov    #0x55, w0 		;Write the KEY sequence&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      mov    #0xAA, w0			&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      bset   NVMCON, #15	;Start the erase cycle, bit 15 = WR&lt;br /&gt;
      nop&lt;br /&gt;
      nop&lt;br /&gt;
  L2: btsc   NVMCON, #15	;while(NVMCONbits.WR)&lt;br /&gt;
      bra    L2&lt;br /&gt;
      clr    w0&lt;br /&gt;
      pop    SR			;Enable global interrupts&lt;br /&gt;
      pop    TBLPAG&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
===Simple PWM (Output Compare Module)===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
*The PWM module consists of 8 channels using the output compare module of dsPic.&lt;br /&gt;
*These channels are locate at pin 46 (OC1), 49 (OC2), 50 (OC3), 51 (OC4), 52 (OC5), 53 (OC6), 54 (OC7), 55 (OC8). These pins are shared with port D.&lt;br /&gt;
*The range of PWM freqeuencies obtainable is 2Hz to 15MHz (See Figure 6.3). Suggested range of operation is 2Hz to 120kHz. The relationship between resolution ''r'' and PWM frequency ''f''&amp;lt;sub&amp;gt;PWM&amp;lt;/sub&amp;gt; is given by:&lt;br /&gt;
         f&amp;lt;sub&amp;gt;PWM&amp;lt;/sub&amp;gt; = f&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;/(Prescale*10&amp;lt;sup&amp;gt;rlog(2)&amp;lt;/sup&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.3 Relationship of Resolution and PWM Frequency&lt;br /&gt;
! Resolution (bit) !! Prescale=1 !! Prescale=8 !! Prescale=64 !! Prescale=256&lt;br /&gt;
|- &lt;br /&gt;
|1||15,000,000 ||1,875,000 ||234,375||58,594 &lt;br /&gt;
|- &lt;br /&gt;
|2||7,500,000 ||937,500 ||117,188 ||29,297 &lt;br /&gt;
|- &lt;br /&gt;
|3||3,750,000 ||468,750 ||58,594 ||14,648 &lt;br /&gt;
|- &lt;br /&gt;
|4||1,875,000 ||234,375 ||29,297 ||7,324 &lt;br /&gt;
|- &lt;br /&gt;
|5||937,500 ||117,188 ||14,648 ||3,662 &lt;br /&gt;
|- &lt;br /&gt;
|6||468,750 ||58,594 ||7,324 ||1,831 &lt;br /&gt;
  |- &lt;br /&gt;
|7||234,375 ||29,297 ||3,662 ||916 &lt;br /&gt;
|- &lt;br /&gt;
|8||117,188 ||14,648 ||1,831||458 &lt;br /&gt;
|- &lt;br /&gt;
|9||58,594 ||7,324 ||916 ||229 &lt;br /&gt;
|- &lt;br /&gt;
|10||29,297 ||3,662 ||458 ||114 &lt;br /&gt;
|- &lt;br /&gt;
|11||14,648 ||1,831 ||229||57 &lt;br /&gt;
|- &lt;br /&gt;
|12||7,324 ||916 ||114 ||29 &lt;br /&gt;
|- &lt;br /&gt;
|13||3,662 ||458 ||57 ||14 &lt;br /&gt;
|- &lt;br /&gt;
|14||1,831 ||229 ||29 ||7 &lt;br /&gt;
|- &lt;br /&gt;
|15||916 ||114 ||14 ||4 &lt;br /&gt;
|- &lt;br /&gt;
|16||458 ||57 ||7 ||2 &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====open()====&lt;br /&gt;
*A timer (either Timer 2 or 3) is needed to determine the pwm period. The following code uses timer 2 for all 8 channels.&lt;br /&gt;
  void pwm_open(void){&lt;br /&gt;
    OC1CON = 0;	OC2CON = 0; //Disable all output compare modules&lt;br /&gt;
    OC3CON = 0; OC4CON = 0;&lt;br /&gt;
    OC5CON = 0; OC6CON = 0;&lt;br /&gt;
    OC7CON = 0; OC8CON = 0;&lt;br /&gt;
    //============================================================&lt;br /&gt;
    TMR2 = 0;		// Clear register&lt;br /&gt;
    PR2 = 0xFFFF;	// Set to Maximum&lt;br /&gt;
    //============================================================&lt;br /&gt;
    _T2IP = 7;		// Set priority level to 7 (7 Highest)&lt;br /&gt;
    _T2IF = 0;		// Clear interrupt flag&lt;br /&gt;
    _T2IE = 1;		// Enable interrupts&lt;br /&gt;
    //============================================================&lt;br /&gt;
    T2CONbits.TCS = 0;		// Use internal clock source&lt;br /&gt;
    T2CONbits.TCKPS = 0;	// Prescale Select 1:1&lt;br /&gt;
    //============================================================&lt;br /&gt;
    T2CONbits.TON = 1;		// Start the timer 	&lt;br /&gt;
  }&lt;br /&gt;
  void _ISR _T2Interrupt(void){&lt;br /&gt;
    _T2IF = 0;			// Clear interrupt flag&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====ioctl()====&lt;br /&gt;
*User should select the channel and set the pwm period using the functions below before issuing the duty cycle:&lt;br /&gt;
  char pwm_ioctl(unsigned char request, unsigned long* argp){&lt;br /&gt;
    unsigned int value;&lt;br /&gt;
    unsigned char mask;&lt;br /&gt;
    switch(request){&lt;br /&gt;
      case PWM_SET_PERIOD:&lt;br /&gt;
        return setPeriodNPrescale(argp[0]);&lt;br /&gt;
      case PWM_SELECT_CH:&lt;br /&gt;
        pwm_channel = argp[0];&lt;br /&gt;
        mask = 0x01 &amp;lt;&amp;lt; pwm_channel;&lt;br /&gt;
        pwm_status = pwm_status | mask;&lt;br /&gt;
            return 0;&lt;br /&gt;
      default:&lt;br /&gt;
            return -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  char setPeriodNPrescale(unsigned long value_ns){&lt;br /&gt;
    unsigned long ans;&lt;br /&gt;
    unsigned long long numerator = (unsigned long long)value_ns*SYSTEM_FREQ_MHZ;&lt;br /&gt;
    unsigned char index= -1;&lt;br /&gt;
    unsigned long denominator;&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    do{&lt;br /&gt;
        denominator = (unsigned long)1000*pwm_prescale[++index];&lt;br /&gt;
        ans = (unsigned long)(((long double)numerator/denominator) + 0.5) - 1; //rounding to nearest integer&lt;br /&gt;
    } while(ans &amp;gt; 0x0000FFFF &amp;amp;&amp;amp; index &amp;lt; 3);&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    if(ans &amp;gt; 0x0000FFFF)&lt;br /&gt;
        return -1;&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    T2CONbits.TON = 0;		// Turn off the timer&lt;br /&gt;
    T2CONbits.TCKPS = index;	// Change prescale factor&lt;br /&gt;
    PR2 = (unsigned int) ans;	// Set to Maximum&lt;br /&gt;
    T2CONbits.TON = 1;		// Turn on the timer 	&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====write()====&lt;br /&gt;
*User can change the duty cycle using teh following functions&lt;br /&gt;
  int pwm_write(unsigned long* buf){&lt;br /&gt;
    if((pwm_status &amp;amp; (0x01 &amp;lt;&amp;lt; pwm_channel)) == 0){&lt;br /&gt;
        return -1;		//Channel has not been enabled&lt;br /&gt;
    }&lt;br /&gt;
    switch(pwm_channel){&lt;br /&gt;
        case 0:&lt;br /&gt;
            OC1RS = calcDCycle(buf[0]); OC1R = OC1RS; &lt;br /&gt;
            OC1CONbits.OCM = 6; //Simple PWM, Fault pin disabled&lt;br /&gt;
            break;&lt;br /&gt;
        case 1:&lt;br /&gt;
            OC2RS = calcDCycle(buf[0]);	OC2R = OC2RS; &lt;br /&gt;
            OC2CONbits.OCM = 6; //Simple PWM, Fault pin disabled&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        case 7:&lt;br /&gt;
            OC8RS = calcDCycle(buf[0]); OC8R = OC8RS; &lt;br /&gt;
            OC8CONbits.OCM = 6; //Simple PWM, Fault pin disabled&lt;br /&gt;
            break;	&lt;br /&gt;
        default:&lt;br /&gt;
            return -1;&lt;br /&gt;
    }&lt;br /&gt;
    return 4;&lt;br /&gt;
 }&lt;br /&gt;
  unsigned int calcDCycle(unsigned long value_ns){&lt;br /&gt;
    unsigned long long numerator = (unsigned long long)value_ns*SYSTEM_FREQ_MHZ;&lt;br /&gt;
    unsigned int index = T2CONbits.TCKPS;&lt;br /&gt;
    unsigned long denominator = (unsigned long)1000*pwm_prescale[index];&lt;br /&gt;
    return (unsigned int)(((long double)numerator/denominator) + 0.5) - 1; //rounding to nearest integer&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====Propagration Delay====&lt;br /&gt;
*PWM channels sharing the same timer will have their PWM signals synchronised (i.e. the HIGH state of the duty cycle are all triggered together).&lt;br /&gt;
*To introduced delay to the PWM signals, the signal from selected channels may be made to pass through a series of inverters (e.g. 74HC14D). This adds propagation delay to the signal.&lt;br /&gt;
*However, as propagration delay of logic gates depends on applied voltage, temperature and load capacitance, the accuracy is low and performance is poor. For accurate delay, delay lines may be used, but they are expensive.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.4 Propagation Delay of [http://www.nxp.com/acrobat_download/datasheets/74HC_HCT14_3.pdf Philips 74HC14D]&amp;lt;sup&amp;gt;[1], [2]&amp;lt;/sup&amp;gt;&lt;br /&gt;
! !! 3.3V !! !! !! 5.0V !! !!&lt;br /&gt;
|- &lt;br /&gt;
! Number of Gates !! A !! B !! C !! A !! B !! C&lt;br /&gt;
|- &lt;br /&gt;
| 2 &lt;br /&gt;
| 21ns (10.5)|| 23ns (11.5)|| 22ns (11.0)&lt;br /&gt;
| 15ns (7.5)|| 14ns (7.0)|| 14ns (7.0)&lt;br /&gt;
|-&lt;br /&gt;
| 4 &lt;br /&gt;
| 45ns (11.3)|| 46ns (11.5)|| 46ns (11.5) &lt;br /&gt;
| 30ns (7.5)|| 30ns (7.5)|| 30ns (7.5)&lt;br /&gt;
|-&lt;br /&gt;
| 6 &lt;br /&gt;
| 69ns (11.5)|| 70ns (11.7)|| 72ns (12.0) &lt;br /&gt;
| 45ns (7.5)|| 46ns (7.7)|| 47ns (7.8)&lt;br /&gt;
|- &lt;br /&gt;
|}&lt;br /&gt;
[1] Data in specification for 4.5V: Typical 15ns, Maximum 25ns&amp;lt;br&amp;gt;&lt;br /&gt;
[2] Data in specification for 6.0V: Typical 12ns, Maximum 21ns&lt;br /&gt;
&lt;br /&gt;
===DSP Library===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Library functions in &amp;lt;dsp.h&amp;gt; include the following categories: &lt;br /&gt;
#Vector&lt;br /&gt;
#Window&lt;br /&gt;
#Matrix&lt;br /&gt;
#Filtering&lt;br /&gt;
#Transform&lt;br /&gt;
#Control&lt;br /&gt;
&lt;br /&gt;
====Data Types====&lt;br /&gt;
*Signed Fractional Value (1.15 data format)&lt;br /&gt;
**Inputs and outputs of the dsp functions adopt 1.15 data format, which consumes 16 bits to represent values between -1 to 1-2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt; inclusive.&lt;br /&gt;
**Bit&amp;lt;15&amp;gt; is a signed bit, positive = 0, negative = 1.&lt;br /&gt;
**Bit&amp;lt;14:0&amp;gt; are the exponent bits ''e''.&lt;br /&gt;
**Positive value = 1 - 2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;*(32768 - ''e'')&lt;br /&gt;
**Negative value = 0 - 2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;*(32768 - ''e'')&lt;br /&gt;
*40-bit Accumulator operations (9.31 data format)&lt;br /&gt;
**The dsp functions use the 40 bits accumalators during arithmatic calculations.&lt;br /&gt;
**Bit&amp;lt;39:31&amp;gt; are signed bits, positive = 0x000, negative = 0x1FF.&lt;br /&gt;
**Bit&amp;lt;30:0&amp;gt; are exponent bits.&lt;br /&gt;
*IEEE Floating Point Values&lt;br /&gt;
**Fractional values can be converted to Floating point values using: '''fo = Fract2Float(fr);''' for fr = [-1, 1-2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;]&lt;br /&gt;
**Floating point values can be converted to Fractional values using: '''fr = Float2Fract(fo);''' or '''fr = Q15(fo);''' for fo = [-1, 1-2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;]&lt;br /&gt;
**Float2Fract() is same as Q15(), except having saturation control. When +ve &amp;gt;= 1, answer = 2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt;-1 = 32767 (0x7FFF). When -ve &amp;lt; -1, answer = -2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt; = -32767 (0x8000)&lt;br /&gt;
&lt;br /&gt;
====Overflow and Saturation Traps====&lt;br /&gt;
*To be added.&lt;br /&gt;
&lt;br /&gt;
===Build-in Library===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Some assembler operators can only be accessed by inline assembly code, for example, &lt;br /&gt;
#Manuipulation of accumulators A and B (add, sub, mul, divide, shift, clear, square)&lt;br /&gt;
#Bit toggling&lt;br /&gt;
#Access to psv (program space visiblity) page and offset&lt;br /&gt;
#Access to table instruction page and offset&lt;br /&gt;
*Built-in functions are written as C-like function calls to utilize these assembler operators.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Bootloader Development==&lt;br /&gt;
&lt;br /&gt;
===Concepts===&lt;br /&gt;
*Programming with ICSP is useful when the target board is produced in batch. The producer can download a program even when the chip is on the target board.&lt;br /&gt;
*However, ICSP requires an external programmer.&lt;br /&gt;
*To allow the user to change the program after production but without the need of an external programmer, bootloader becomes useful.&lt;br /&gt;
*Bootloader is a small program installed via ICSP. Everytime the device is reset, the bootloader is run first. The bootloader first detects the default serial channel whether the user wishes to download a new program to the device. If so, the bootloader will pause there, and wait for the user to download the hex file from the PC. The hex file is written to the device via RTSP instructions in the bootloader. If a new download is not necessary, the bootloader redirects to the previously installed user's program.&lt;br /&gt;
*The disadvantage of bootloaders is that they consume some of the memory of the device.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 7.1 Free bootloaders for dsPIC&lt;br /&gt;
! Developer&lt;br /&gt;
! Source&lt;br /&gt;
! Platform&lt;br /&gt;
! User Guide&lt;br /&gt;
! Remarks&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://www.ingenia-cat.com/index.php?lang=en ingenia]&lt;br /&gt;
| [http://www.ingenia-cat.com/download/iBL.s Assembly]&lt;br /&gt;
| [http://www.ingenia-cat.com/download/ingeniadsPICbootloader1.1.zip Windows]&lt;br /&gt;
| [http://www.ingenia-cat.com/reference/pdf/iBL.UG.V1.2.pdf pdf]&lt;br /&gt;
| &lt;br /&gt;
*Works for all dsPIC supporting RTSP&lt;br /&gt;
*Auto baudrate detection&lt;br /&gt;
*Use about 1.15% of the flash memory space (0xAFFF-0xAE00)/(0xAFFF-0x0100)&lt;br /&gt;
*Development of Linux platform is underway&lt;br /&gt;
*Modification of code for dsPIC30F5011 is successful&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm Tiny]&lt;br /&gt;
| [http://www.etc.ugal.ro/cchiculita/software/tinybld191.zip Assembly]&lt;br /&gt;
| Windows&lt;br /&gt;
| [http://www.etc.ugal.ro/cchiculita/software/tinybldusage.htm Web]&lt;br /&gt;
| &lt;br /&gt;
*By default, only supports 601X, 601X, 401X, 2010&lt;br /&gt;
*Smaller code size than ingenia, but not as easy to modify&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://www.via.si/software/dsPIC_bootloader/ Elektronika]&lt;br /&gt;
| [http://www.via.si/software/dsPIC_bootloader/data/ Hex]&lt;br /&gt;
| Windows&lt;br /&gt;
| [http://www.via.si/software/dsPIC_bootloader/data/README.txt txt]&lt;br /&gt;
| &lt;br /&gt;
*Only works for dsPIC30F6014 serial port UART2 at baudrate 57600&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===dsPicBootloader===&lt;br /&gt;
&lt;br /&gt;
*The bootloader developed by ingenia is open source and it has been modified (see below) to suit our development using dsPic30f5011.&lt;br /&gt;
*The bootloader (hereafter called dsPicBootloader) employs the following settings:&lt;br /&gt;
# Use U2ART channel&lt;br /&gt;
# Use FRC, PLL16&lt;br /&gt;
# For 5011, the bootloader is located between 0x00AE00 to 0x00AFFE (512bytes). Refer to C:\Program Files\Ingenia\ingeniadsPICbootloader\ibl_dspiclist.xml after installing the GUI interface.&lt;br /&gt;
*Changes made to [http://www.ingenia-cat.com/download/iBL.s assembly code]  includes:&lt;br /&gt;
1. including p30f5011.gld and p30f5011.inc&lt;br /&gt;
        .include &amp;quot;p30f5011.inc&amp;quot;&lt;br /&gt;
2. changing the config code of UART #0x8420 -&amp;gt; #0x8020&lt;br /&gt;
        ; Uart init&lt;br /&gt;
        mov '''#0x8020''', W0           ; W0 = 0x8020 -&amp;gt; 1000 0000 0010 0000b&lt;br /&gt;
        mov W0, U2MODE            ; Enable UART, AutoBaud and 8N1&lt;br /&gt;
        clr U2STA&lt;br /&gt;
3. changing the start address 0xAE00 - 0x0100 = 0AD00&lt;br /&gt;
          .equ CRC, W4&lt;br /&gt;
          .equ ACK, 0x55&lt;br /&gt;
          .equ NACK, 0xFF&lt;br /&gt;
          .equ USER_ADDRESS, 0x0100&lt;br /&gt;
          .equ START_ADDRESS, '''0xAD00'''                ; Relative to 0x0100&lt;br /&gt;
4. using Internal FRC and PLL16&lt;br /&gt;
        config __FOSC, CSW_FSCM_OFF &amp;amp; '''FRC_PLL16''' ;Turn off clock switching and&lt;br /&gt;
                                           	;fail-safe clock monitoring and&lt;br /&gt;
                                            	;use the Internal Clock as the&lt;br /&gt;
                                           	;system clock&lt;br /&gt;
5. disabling MCLR (optional)&lt;br /&gt;
        config __FBORPOR, PBOR_ON &amp;amp; BORV_27 &amp;amp; PWRT_16 &amp;amp; '''MCLR_DIS'''&lt;br /&gt;
                                            ;Set Brown-out Reset voltage and&lt;br /&gt;
                                            ;and set Power-up Timer to 16msecs&lt;br /&gt;
6. changing all the related registers of U1ART to U2ART, all U1XXX =&amp;gt; U2XXX&lt;br /&gt;
        '''U2MODE, U2STA, U2BRG, U2RXREG, U2TXREG'''&lt;br /&gt;
7. changing all the related registers of IC1 to IC2, all IC1XXX =&amp;gt; IC2XXX&lt;br /&gt;
        '''IC2CON, #IC2IF, #IC2IE'''&lt;br /&gt;
&lt;br /&gt;
===dsPicProgrammer (Java-based Multi-Platformed)===&lt;br /&gt;
*Ingenia developed a programmer (PC-side) that works only in Windows environment. The project for Linux environment is currently suspended.&lt;br /&gt;
*A simple programmer (hereafter called dsPicProgrammer) written in Java based on the library developed by [http://www.rxtx.org/ RXTX] has been developed here. The programmer supports both Linux and Windows environments, and may be used as a substitution for the official programmer developed by ingenia.&lt;br /&gt;
*The programmer has the following specification and limitations:&lt;br /&gt;
#Use baud rate of 57600bps (Not selectable).&lt;br /&gt;
#Only program dsPic30f5011 devices (Developers may change the source code for your devices).&lt;br /&gt;
#Protection against overwriting bootloader codes on devices.&lt;br /&gt;
#Dectection if application program does not have its reset() at address 0x100.&lt;br /&gt;
&lt;br /&gt;
===Special Consideration===&lt;br /&gt;
*The bootloader assumes that the user program starts at address 0x100. This is usually the case, but there are always exceptions.&lt;br /&gt;
*To ensure that the user program always starts at address 0x100, you can create a customized linker script and customized reset() function as follows:&lt;br /&gt;
:*Copy and modify the file named &amp;quot;crt0.s&amp;quot; from the directory &amp;quot;C:\Program Files\Microchip\MPLAB C30\src\pic30&amp;quot; to the project directory and include it.&lt;br /&gt;
    .section .reset, code      //previously .section .libc, code &lt;br /&gt;
:*Copy and modify the linkerscript for the device (e.g. p30f5011.gld) to the project directory and include it.&lt;br /&gt;
   .text __CODE_BASE :&lt;br /&gt;
   {&lt;br /&gt;
      *(.reset);              //&amp;lt;-insert this line here&lt;br /&gt;
      *(.handle);&lt;br /&gt;
      *(.libc) *(.libm) *(.libdsp);  /* keep together in this order */&lt;br /&gt;
      *(.lib*);&lt;br /&gt;
      *(.text);&lt;br /&gt;
   } &amp;gt;program&lt;br /&gt;
&lt;br /&gt;
===Downloads===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 7.2 dsPicBootloader and dsPicProgrammer for dsPIC30f5011&lt;br /&gt;
! Program&lt;br /&gt;
! Site 1&lt;br /&gt;
! Site 2&lt;br /&gt;
! Remarks&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| dsPicBootloader&lt;br /&gt;
| [http://chungyan5.no-ip.org/websvn/listing.php click]&lt;br /&gt;
| [http://www.opencircuits.com/images/e/ed/DsPicBootloader.zip click]&lt;br /&gt;
| Under &amp;quot;dsPicBootloader/&amp;quot;, download ingenia.s and compile yourself&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| dsPicProgrammer&lt;br /&gt;
| [http://chungyan5.no-ip.org/websvn/listing.php click]&lt;br /&gt;
| [http://www.opencircuits.com/images/1/13/DsPicProgrammer.zip click]&lt;br /&gt;
| Under &amp;quot;dsPicProgrammer/&amp;quot;, dowload dsPicProgrammer.jar&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Alternatively, if you want to compile yourself or modify the source code, download &amp;lt;br&amp;gt;COMDataHandler.java, COMPortManager.java, Pic5011Prog.java, Pic5011Protocol.java, &amp;lt;br&amp;gt;and WriteBuffer.java under &amp;quot;dsPicProgrammer/&amp;quot; '''plus''' RdFileIntelHex.java under &amp;lt;br&amp;gt;&amp;quot;IntelHexPaser/tags/0.02.00/&amp;quot;.&amp;lt;br&amp;gt;You should also install RXTX on your local machine as recommended in the readme file.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Communication Protocol===&lt;br /&gt;
* Communication Protocol is reviewed in [http://www.ingenia-cat.com/reference/pdf/iBL.UG.V1.2.pdf ingenia bootloader user's guide] section 2.1.3. The following summarises the key steps on the PC side (Refer also to section 2.2.2).&lt;br /&gt;
* Transmission is conducted in 8N1, i.e. 8-bit, no parity, 1 stop-bit&lt;br /&gt;
* '''Stage 1: User's configuation'''&lt;br /&gt;
**Select a baudrate&lt;br /&gt;
**Select a COM port channel&lt;br /&gt;
* '''Stage 2: Autobaud rate detection and version control'''&lt;br /&gt;
**Continuously sending a character &amp;quot;U&amp;quot; [0x55] via COM port&lt;br /&gt;
**Continuously waiting for an acknowledgment character &amp;quot;U&amp;quot;, [ACK] = [0x55]&lt;br /&gt;
**Send command character [0x03]&lt;br /&gt;
**Receive 3 characters 1) Major Version 2) Minor Version 3) Acknowledgment [0x55]&lt;br /&gt;
**Prints the version number [Major.Minor] (e.g. 1.1) on screen.&lt;br /&gt;
* '''Stage 3: Loading and writing the program'''&lt;br /&gt;
**Load the user hex file, check integrity.&lt;br /&gt;
**Start loading file using:&lt;br /&gt;
***Read command character [0x01] + 24-bit address [High][Medium][Low]&lt;br /&gt;
***Receive 4-byte data [High][Medium][Low][ACK]&lt;br /&gt;
***Write command character [0x02] + 24-bit address [High][Medium][Low]+ Number of bytes [N] + [data 0] + [data 1] + ... + [data N-1] + [CRC]=(INTEL HEX8 Checksum - Sum modulo 256)&lt;br /&gt;
***Receive [ACK] or [NACK] = [0xFF]&lt;br /&gt;
***Note: Writing is in row mode access (i.e. erase and write a whole row, each row has 32 instructions, or 96 bytes because each instruction has 24 bits)&lt;br /&gt;
::# Ensure the initial address of writing match an initial row position,&lt;br /&gt;
::# Send the data corresponding to the whole row.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==USB-RS232 Bridge==&lt;br /&gt;
&lt;br /&gt;
*As USB ports are becoming more and more common, COM ports and Parallel ports may be redundant in the next few years. This section explore the possibilities of programming the target board through a USB port.&lt;br /&gt;
*There are two options:&lt;br /&gt;
#Use an external USB/RS232 adaptor, the driver will emulate a virtual COM port, such as [http://www.prolific.com.tw/eng/downloads.asp?ID=31 Prolific] and [http://www.ftdichip.com/Drivers/VCP.htm FDTI]. Ingenia has tested its bootloader with some USB-232 manufacturers (silabs, FTDI, etc..). However, the programming failed with our Prolific adapter. Application program may use [http://java.sun.com/products/javacomm/ JavaComm API] (javax.comm) and/or [http://www.rxtx.org/ RXTX] to drive the COM port.&lt;br /&gt;
#Modified the bootloader program on PC to support USB communication. e.g. using [http://jusb.sourceforge.net/ jUSB] and [http://javax-usb.org/ JSR-80] (javax.usb). External circuits such as PIC18F4550 and MAX232 are required.&lt;br /&gt;
&lt;br /&gt;
    |--User's App.--|-------Device Manager------|-------USB-RS232 Interface------|---dsPIC---|&lt;br /&gt;
   Option 1:&lt;br /&gt;
     +-------------+  +----------+  +----------+  +---+  +------------+  +-----+  +--------+&lt;br /&gt;
     | Application |--| JavaComm |--| Virtual  |==|USB|--|    FDTI    |--|RS232|==| Target |&lt;br /&gt;
     |   Program   |  |  RXTX    |  | COM Port |  +---+  | Circuitary |  +-----+  | Board  |&lt;br /&gt;
     +-------------+  +----------+  +----------+         +------------+           +--------+&lt;br /&gt;
   Option 2:&lt;br /&gt;
     +-------------+          +--------+          +---+  +------------+  +-----+  +--------+&lt;br /&gt;
     | Application |----------| JSR-80 |==========|USB|--| PIC18F4550 |--|RS232|==| Target |&lt;br /&gt;
     |   Program   |          |  jUSB  |          +---+  |   MAX232   |  +-----+  | Board  |&lt;br /&gt;
     +-------------+          +--------+                 +------------+           +--------+&lt;br /&gt;
&lt;br /&gt;
*Currently, when RXTX is incorporated with JavaComm API, operating systems supported include Linux, Windows, Mac OS, Solaris and other operating systems. On the other hand, jUSB and JSR-80 only works for linux.&lt;br /&gt;
&lt;br /&gt;
===FDTI Chipset===&lt;br /&gt;
*FT232RL communicates with PC via USB to provide 1 UART channel.&lt;br /&gt;
*Datasheet can be downloaded [http://www.ftdichip.com/Documents/DataSheets/DS_FT232R.pdf here]. &lt;br /&gt;
**Refer to Fig. 11 (Page 19) for Bus Powered Configuration.&lt;br /&gt;
**Refer to Fig. 16 (Page 24) for for UART TTL-level Receive [RXD -&amp;gt; 1], Transmit [TXD -&amp;gt; 4], Transmit Enable [CBUS2/TXDEN -&amp;gt; 3]. Omit Receive Enable [CBUS3/PWREN#] and use [CBUS2/TXDEN -&amp;gt; 2] &lt;br /&gt;
**Refer to Fig. 15 (Page 23) for LED Configuration: [CBUS0/TXLED#] and [CBUS1/RXLED#]&lt;br /&gt;
*Virtual COM Port Drivers can be downloaded [http://www.ftdichip.com/Drivers/VCP.htm here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming the Device==&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
*Hardware&lt;br /&gt;
#PC with COM port (Windows XP Installed for MPLAB)&lt;br /&gt;
#ICD2 Programmer&lt;br /&gt;
#Target Board&lt;br /&gt;
#5V Power Supply&lt;br /&gt;
&lt;br /&gt;
*Software&lt;br /&gt;
#[http://ww1.microchip.com/downloads/en/DeviceDoc/MP750.zip MPLAB IDE v7.50 or higher]&lt;br /&gt;
#[http://chungyan5.no-ip.org/websvn/listing.php dsPicProgrammer] ('''dsPicProgrammer.jar''')&lt;br /&gt;
#[http://users.frii.com/jarvi/rxtx/download.html RXTX driver]&lt;br /&gt;
&lt;br /&gt;
*Files&lt;br /&gt;
#[http://chungyan5.no-ip.org/websvn/listing.php dsPicBootloader] ('''ingenia.hex'''). Original assembly code by ingenia can be downloaded from [http://www.ingenia-cat.com/download/iBL.s here].&lt;br /&gt;
#Application hex file (e.g. '''app.hex''')&lt;br /&gt;
&lt;br /&gt;
===Loading Bootloader (Once only)===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 9.1 Loading Bootloader&lt;br /&gt;
! Step !! Remarks &lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Install [http://ww1.microchip.com/downloads/en/DeviceDoc/MP750.zip MPLAB IDE] || &lt;br /&gt;
*Do '''NOT''' connect ICD 2 (via USB) to PC&lt;br /&gt;
*Execute '''MPLAB vX.XX Install.exe'''&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Install USB Driver ||&lt;br /&gt;
*Follow the instruction in (C:\Program Files\Microchip\MPLAB IDE\ICD2\Drivers\Ddicd2.htm)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Select Target Chip ||&lt;br /&gt;
*Run MPLAB IDE on PC&lt;br /&gt;
*Select: Configure&amp;gt;Select Devices...&lt;br /&gt;
*Choose dsPIC30F5011&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Target &amp;lt;-&amp;gt; ICD 2  ||&lt;br /&gt;
*Use six pin cable. Beware of the pin assignments. Only pin 1 - 5 should be used.&lt;br /&gt;
*Place Jumper on target board (if any). The Jumper connects target V&amp;lt;sub&amp;gt;cc&amp;lt;/sub&amp;gt; to ICD 2.&lt;br /&gt;
*Do '''NOT''' power-up the target.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| ICD 2 &amp;lt;-&amp;gt; PC ||&lt;br /&gt;
*Plug-in ICD 2 to PC via USB cable&lt;br /&gt;
*Power-up the target.&lt;br /&gt;
*Select: Programmer&amp;gt;Select Programmer&amp;gt;MPLAB ICD 2&lt;br /&gt;
*If this is the first time the ICD 2 is connected to PC, MPLAB IDE will automatically download the required OS to ICD 2, wait until it has finished&lt;br /&gt;
*If you have not connected and powered up the target, you might see Warnings on invalid device IDs, and/or running self tests.&lt;br /&gt;
*See results of self test if necessary: Programmer&amp;gt;Settings, Status Tab. Refer to [http://ww1.microchip.com/downloads/en/DeviceDoc/51331B.pdf ICD2 User's Guide] Chapter 7.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Load Bootloader ||&lt;br /&gt;
*Select: File&amp;gt;Import...&lt;br /&gt;
*Select '''ingenia.hex'''&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Start Programming ||&lt;br /&gt;
*Select: Programmer&amp;gt;Program&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Finishing ||&lt;br /&gt;
*Power-down the Taget&lt;br /&gt;
*Select: Programmer&amp;gt;Select Programmer&amp;gt;None&lt;br /&gt;
*Unplug USB cable&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Loading Application===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 9.2 Loading Application File&lt;br /&gt;
! Step !! Remarks &lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Install RXTX ||&lt;br /&gt;
*For Windows User:&lt;br /&gt;
**copy RXTXcomm.jar to \jre\lib\ext (under java)&lt;br /&gt;
**copy rxtxSerial.dll to \jre\bin&lt;br /&gt;
*For Linux User:&lt;br /&gt;
**copy RXTXcomm.jar to /jre/lib/ext (under java)&lt;br /&gt;
**copy librxtxSerial.so to /jre/lib/[machine type] (i386 for instance)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Connect target board ||&lt;br /&gt;
*For Windows User:&lt;br /&gt;
**connect to COM1 (or other useable port)&lt;br /&gt;
*For Linux User:&lt;br /&gt;
**connect to ttyS0 (or other useable port)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Open a console window ||&lt;br /&gt;
*In Windows, Start&amp;gt;Run, and type cmd.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Start Programming ||&lt;br /&gt;
*Change to the directory containing dsPicProgrammer.jar&lt;br /&gt;
*Execute dsPicProgrammer.jar&lt;br /&gt;
**For Windows User: java -jar dsPicProgrammer.jar COMi Y:\foo2\app.hex&lt;br /&gt;
**For Linux User: java -jar dsPicProgrammer.jar /dev/ttySi Y:/foo2/app.hex&lt;br /&gt;
*Power-up target board&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Finishing ||&lt;br /&gt;
*Power-down target board&lt;br /&gt;
*Disconnect from COM port&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Remote Access==&lt;br /&gt;
*At the moment, local devices (e.g. EEPROM, ADC, DAC, etc.) can only be accessed locally through POSIX functions such as open(), read(), write(), ioctl().&lt;br /&gt;
*However, a client may need to access these devices on a remote server. This section reviews the background and gives some ideas on its possible implementation.&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
*A remote file access protocol, to transfer &amp;quot;files&amp;quot; (i.e. device's data) such as:&lt;br /&gt;
#[http://en.wikipedia.org/wiki/FTP File Transfer Protocol] (FTP): Required files are copied from sever to client for manipulation&lt;br /&gt;
#[http://en.wikipedia.org/wiki/Remote_Shell Remote Shell] (RSH): Required files are copied from sever to client for manipulation&lt;br /&gt;
#[http://en.wikipedia.org/wiki/Network_File_System_%28Sun%29 Network File System] (NFS): Required files are manipulated on sever&lt;br /&gt;
*An API to access files using a selected protocol, such as:&lt;br /&gt;
#[http://www.die.net/doc/linux/man/man2/lam_rfposix.2.html lam_rfposix]: A POSIX-like remote file service for Local Area Multicomputer&lt;br /&gt;
#API employed by VxWorks: [http://en.wikipedia.org/wiki/VxWorks VxWorks] is a Unix-like real-time operating system, commonly used for embedded systems.&lt;br /&gt;
&lt;br /&gt;
===API Reference for VxWorks===&lt;br /&gt;
*Reference:&lt;br /&gt;
**[http://www.windriver.com/vxworks/ VxWorks Official Website]&lt;br /&gt;
**[http://www-cdfonline.fnal.gov/daq/commercial/ OS Libraries API Reference]&lt;br /&gt;
*Related Libraies&lt;br /&gt;
**netDrv (netDrv.h): an API using FTP or RSH&lt;br /&gt;
**nfsDrv (nfsDrv.h): an API using NFS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==To Do List==&lt;br /&gt;
#Construct examples codes for using DSP library&lt;br /&gt;
#Construct examples codes for using Build-in library&lt;br /&gt;
#GUI Interface for Benchtop boards&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=DsPIC30F_5011_Development_Board&amp;diff=2771</id>
		<title>DsPIC30F 5011 Development Board</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=DsPIC30F_5011_Development_Board&amp;diff=2771"/>
		<updated>2007-02-13T23:19:13Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Revert&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Introduction==&lt;br /&gt;
&lt;br /&gt;
===Features of dsPIC30F5011===&lt;br /&gt;
*2.5 to 5V	&lt;br /&gt;
*Up to 30MIPs&lt;br /&gt;
*High current/sink source I/O pins: 25mA&lt;br /&gt;
*DSP Instruction Set&lt;br /&gt;
*Dual programming techniques: ICSP and RTSP&lt;br /&gt;
*UART: up to 2 modules&lt;br /&gt;
*I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C: up to 1Mbps&lt;br /&gt;
*10-bit A/D, 1.1 Msps	&lt;br /&gt;
*12-bit A/D, 200 ksps&lt;br /&gt;
*44K flash (66Kb), 4Kb RAM, 1Kb EEPROM&lt;br /&gt;
*No DAC&lt;br /&gt;
			&lt;br /&gt;
===Web Page===&lt;br /&gt;
*[http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=2529&amp;amp;param=en024856 Microchip Official Website]&lt;br /&gt;
&lt;br /&gt;
===Forum===&lt;br /&gt;
*[http://direct.forum.microchip.com/default.aspx Microchip]: Official forum by Microchip&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=49 MPLAB ICD 2]: Subforum on ICD 2 programmer&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=57 MPLAB IDE]: Subforum on IDE&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=101 MPLAB C30 Compiler, ASM30, Link30 forum]: Subforum on C compiler. Refer to [http://ww1.microchip.com/downloads/en/DeviceDoc/C30_Users_Guide_51284e.pdf MPLAB C30 C Compiler User's Guide] Chapter 3&lt;br /&gt;
**[http://direct.forum.microchip.com/tt.aspx?forumid=153 dsPIC30F Topics]: Subformum on dsPIC30F&lt;br /&gt;
*[http://www.gnupic.org/ GNUPIC]: Discussion on PIC in Linux Systems&lt;br /&gt;
**[http://www.linuxhacker.org/cgi-bin/ezmlm-cgi?1:dds:5443#b Debian]&lt;br /&gt;
*[http://www.htsoft.com/forum/all/ubbthreads.php/Cat/0/C/6 HI-TECH Software Forum]: Discussion on dsPICC, a C compiler developed by HI-TECH&lt;br /&gt;
*[http://piclist.com/techref/piclist/index.htm PICList]: Discussion on older PIC systems (not dsPIC)&lt;br /&gt;
*[http://groups.google.com/group/pickit-devel PicKit]: Discussion on PICkit/PICkit 2 programmers&lt;br /&gt;
*[http://sourceforge.net/forum/forum.php?forum_id=382005 FreeRTOS Real Time Kernel]: Open Discussion and Support on FreeRTOS	&lt;br /&gt;
&lt;br /&gt;
===References===&lt;br /&gt;
*dsPIC30F&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70043F.pdf Family Overview]&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70046E.pdf Family Reference Manual]: Contains detailed descriptions on dsPIC30F register definitions and example codes&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70116F.pdf 5011 Data Sheet]	**[http://ww1.microchip.com/downloads/en/DeviceDoc/70102G.pdf Flash Programming Specification]&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/70157B.pdf Programmer Reference Manual]&lt;br /&gt;
*ICD2 Programmer&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/51331B.pdf ICD2 User's Guide]	&lt;br /&gt;
*MPLAB&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/51519B.pdf MPLAB IDE User's Guide]&lt;br /&gt;
*C30 Compiler&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/C30_Users_Guide_51284e.pdf MPLAB C30 C Compiler User's Guide]: Contains commands for using pic30-elf-gcc		&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/16bit_Language_Tool_Libraries_51456c.pdf 16-bit Language Tools Libraries]: Contains summaries and examples of using DSP libraries, standard C libraries and device libraries&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/Asm30_Link_Util_51317e.pdf MPLAB ASM30, MPLAB LINK30 and Utilities User's Guide]&lt;br /&gt;
**[http://ww1.microchip.com/downloads/en/DeviceDoc/51322d.pdf dsPIC30F Language Tools Quick Reference Card]&lt;br /&gt;
&lt;br /&gt;
==Programming Methods==&lt;br /&gt;
*There are 2 programming methods: In-Circuit Serial Programming (ICSP) and Run-Time Self-Programming (RTSP)&lt;br /&gt;
*ICSP allows the devices to be programmed after being placed in a circuit board.&lt;br /&gt;
*RTSP allows the devices to be programmed when an embedded program is already in operation.&lt;br /&gt;
&lt;br /&gt;
===ICSP: External Programmer (ICD2)===&lt;br /&gt;
*Two types of ICSP are available: '''ICSP''' and '''Enhanced ICSP'''. Both of them require setting MCLR# to V&amp;lt;sub&amp;gt;IHH&amp;lt;/sub&amp;gt; (9V – 13.25V).&lt;br /&gt;
*Standard ICSP&lt;br /&gt;
**Use external programmer (e.g. MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; ICD 2, MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; PM3 or PRO MATE&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; II) only.&lt;br /&gt;
**Required low-level programming to erase, program and verify the chip.&lt;br /&gt;
**Slower, because codes are serially executed.&lt;br /&gt;
**Program memory can be erased using ''Normal-Voltage'' (4.5 – 5.5V) or ''Low-Voltage'' (2.5V – 4.5V).&lt;br /&gt;
&lt;br /&gt;
*Enhanced ICSP&lt;br /&gt;
**Use external programmer and '''Programming Executive''' (PE).&lt;br /&gt;
**PE is stored in the on-chip memory.&lt;br /&gt;
**PE allows faster programming.&lt;br /&gt;
**PE can be downloaded to the chip by external programmer using the standard ICSP method.&lt;br /&gt;
**PE contains a small command set to erase, program and verify the chip, avoiding the need of low-level programming.&lt;br /&gt;
&lt;br /&gt;
====Hardware Interface====&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.1 Pin Used by ICSP&lt;br /&gt;
! Pin Label !! Function !! Pin Number&lt;br /&gt;
|- &lt;br /&gt;
| MCLR# || Programming Enable|| 7&lt;br /&gt;
|-&lt;br /&gt;
| V&amp;lt;sub&amp;gt;DD&amp;lt;/sub&amp;gt; || Power Supply || 10, 26, 38, 57&lt;br /&gt;
|-&lt;br /&gt;
| V&amp;lt;sub&amp;gt;SS&amp;lt;/sub&amp;gt; || Ground || 9, 25, 41, 56&lt;br /&gt;
|- &lt;br /&gt;
| PGC || Serial Clock || 17&lt;br /&gt;
|-&lt;br /&gt;
| PGD || Serial Data || 18&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.2 Available Programmers in the Market&lt;br /&gt;
! Product Name&lt;br /&gt;
! Interface with PC&lt;br /&gt;
! Interface with Device&lt;br /&gt;
! Price (US)&lt;br /&gt;
! Postage (US)&lt;br /&gt;
! Total (US)&lt;br /&gt;
|- &lt;br /&gt;
| [http://direct.www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010046&amp;amp;part=DV164005 MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; ICD 2]&lt;br /&gt;
| USB or RS232&lt;br /&gt;
| [http://www.microchip.com/Microchip.WWW.SecureSoftwareList/secsoftwaredownload.aspx?device=en010046&amp;amp;lang=en&amp;amp;ReturnURL=http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010046&amp;amp;part=DV164005# 6-PIN RJ-12 connector]&lt;br /&gt;
| $159.99&lt;br /&gt;
| -&lt;br /&gt;
| -&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.etekronics.com/product_info.php?cPath=24&amp;amp;products_id=48  Full Speed USB Microchip ICD2&amp;lt;br&amp;gt; Debugger and Programmer]&lt;br /&gt;
| USB&lt;br /&gt;
| 6-PIN ICSP connector&amp;lt;br&amp;gt;6-PIN RJ-12 connector&lt;br /&gt;
| $72.00&lt;br /&gt;
| $12.00&lt;br /&gt;
| $84.00&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.etekronics.com/product_info.php?cPath=24&amp;amp;products_id=47 Mini Microchip Compatible ICD2&amp;lt;br&amp;gt; Debugger and Programmer]&lt;br /&gt;
| RS232&lt;br /&gt;
| 6-PIN ICSP connector&amp;lt;br&amp;gt;6-PIN RJ-12 connector&lt;br /&gt;
| $45.00&lt;br /&gt;
| $10.00&lt;br /&gt;
| $55.00&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.inexglobal.com/microcontroller.php ICDX30]&lt;br /&gt;
| RS232&lt;br /&gt;
| 6-pin RJ-11&lt;br /&gt;
| $51.00&lt;br /&gt;
| $47.46&lt;br /&gt;
| $98.46&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.sure-electronics.net/englishsite/icd2/icd2.htm Clone Microchip ICD2]&lt;br /&gt;
| USB&lt;br /&gt;
| 6-pin flat cables&lt;br /&gt;
| $30.00&lt;br /&gt;
| $12.00&lt;br /&gt;
| $42.00&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.3 DIY ICD 2 Programmer Circuit&lt;br /&gt;
! Source !! Schematic !! PIC16F877A Bootloader&lt;br /&gt;
|- &lt;br /&gt;
| [http://membres.lycos.fr/silicium31/Electronique/PIC/FreeIcdEnglish.htm Patrick Touzet]&lt;br /&gt;
| [http://membres.lycos.fr/silicium31/Electronique/PIC/ICD2%20V1.3.pdf Yes]&lt;br /&gt;
| [http://membres.lycos.fr/silicium31/Electronique/PIC/ICD2_FW.zip HEX]&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.nebadje.org/doku.php?id=neblab:icd2clone Nebadje]&lt;br /&gt;
| [http://people.ee.ethz.ch/~jbiveron/nebadje/ICD2_DOC.pdf Yes]&lt;br /&gt;
| [http://people.ee.ethz.ch/~jbiveron/nebadje/ICD2_FW.zip Zip]&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====Software Interface====&lt;br /&gt;
*The program can be written and compiled in an Integrated Development Environment (IDE) using either Assembly or C. The complied codes are then loaded to the device through the external programmer.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 2.4 Summary of IDE&lt;br /&gt;
! Product Name !! Features !! OS !! Price (US$)&lt;br /&gt;
|- &lt;br /&gt;
| [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002 MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; IDE]&lt;br /&gt;
| Assembler Only&lt;br /&gt;
| Windows&lt;br /&gt;
| Free&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en010065&amp;amp;part=SW006012 MPLAB&amp;lt;sup&amp;gt;®&amp;lt;/sup&amp;gt; C30]&lt;br /&gt;
| Assembler and C-Compiler&lt;br /&gt;
| Windows&lt;br /&gt;
| $895.00 (Free student version&amp;lt;sup&amp;gt;1&amp;lt;/sup&amp;gt;)&lt;br /&gt;
|-&lt;br /&gt;
| [http://linux.softpedia.com/get/Science-and-Engineering/Electronic-Design-Automation-EDA-/Piklab-8099.shtml Piklab 0.12.0]&lt;br /&gt;
| Assembler and C-Compiler&lt;br /&gt;
| Linux&lt;br /&gt;
| Free&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
# Full-featured for the first 60 days. After 60 days only optimization level 1 can be enabled in the compiler. The compiler will continue to function after 60 days, but code size may increase.&lt;br /&gt;
# The current version supports external programmer ICD 2, but not yet tested.&lt;br /&gt;
&lt;br /&gt;
===RTSP: COM Port (Bootloader)===&lt;br /&gt;
*RTSP works in normal voltage (^MCLR no need to raise to V&amp;lt;sub&amp;gt;IHH&amp;lt;/sub&amp;gt;).&lt;br /&gt;
*No literature has mentioned the incorporation of Programming Executive (PE). Presumably, since Enhanced ICSP needs to set MCLR# to V&amp;lt;sub&amp;gt;IHH&amp;lt;/sub&amp;gt;, RTSP cannot use PE.&lt;br /&gt;
*Refer to bootloader section.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Circuit Design and PCB==&lt;br /&gt;
&lt;br /&gt;
===IC Requirements===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 3.1 IC Requirements&lt;br /&gt;
! Part No. !! Description &lt;br /&gt;
! Min Temp !! Max Temp !! Min Volt !! Max Volt !! Typ Cur !! Max Cur&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://ww1.microchip.com/downloads/en/DeviceDoc/70116F.pdf dsPIC30F5011-30I/PT] || uP &lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 2.5V &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;|| 5.5V&lt;br /&gt;
|     || 250mA&lt;br /&gt;
|-&lt;br /&gt;
| [http://datasheets.maxim-ic.com/en/ds/MAX3222-MAX3241.pdf MAX3232ESE] || RS232 driver&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 3.0V || 5.5V&lt;br /&gt;
| 0.3mA || 1.0mA&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.analog.com/UploadedFiles/Data_Sheets/ADM483E.pdf ADM483E ANZ] || RS485 driver&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 4.5V || 5.5V&lt;br /&gt;
| 0.036mA || &lt;br /&gt;
|-&lt;br /&gt;
| [http://focus.ti.com/lit/ds/symlink/dac6574.pdf DAC6574DGS] || 10-bit Quad-DAC I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 105&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 2.7V || 5.5V&lt;br /&gt;
| 0.6mA || 0.9mA&lt;br /&gt;
|-&lt;br /&gt;
| [http://www.semiconductors.philips.com/acrobat/datasheets/74HC_HCT14_3.pdf 74HC14D] || Quad-Schmitt Trigger&lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 125&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 2.0V || 6.0V&lt;br /&gt;
| || 50mA&lt;br /&gt;
|-&lt;br /&gt;
| Overall || &lt;br /&gt;
| -40&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C || 85&amp;lt;sup&amp;gt;o&amp;lt;/sup&amp;gt;C&lt;br /&gt;
| 4.5V || 5.5V&lt;br /&gt;
| || &amp;lt;310mA &amp;lt;sup&amp;gt;[2]&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
#Minimum voltage measured is 3.3V (with 2 LEDs blinking) running at 30MHz.&lt;br /&gt;
#Measured current at 5V is 180mA (with 2 LEDs blinking only)&lt;br /&gt;
&lt;br /&gt;
===Module Board===&lt;br /&gt;
*Functions&lt;br /&gt;
**Primary communication with other module boards via RS232 over short distance.&lt;br /&gt;
**Secondary communication with benchtop via RS458 over longer distance.&lt;br /&gt;
**Digital control I/O for 1 laser (e.g. on/off, detect temp overheat, current alarm)&lt;br /&gt;
**Analog input for data acquisation on power, current and temperature&lt;br /&gt;
**Analog output for power and current control&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 3.2 Module&lt;br /&gt;
! Digital Input !! Digital Output !! Analog Input !! Analog Output&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| 1. ICSP&lt;br /&gt;
| 1. LED&amp;lt;br&amp;gt; 2. Bi-color LED&amp;lt;br&amp;gt; 3. RS232&amp;lt;br&amp;gt; 4. RS458&amp;lt;br&amp;gt; 5. Case temp overheat&amp;lt;br&amp;gt; 6. Laser on/off 1,2&amp;lt;br&amp;gt; 7. Interlock&amp;lt;br&amp;gt; 8. Digital ctrl&amp;lt;br&amp;gt; 9. Current 0,1 alarm&amp;lt;br&amp;gt;&lt;br /&gt;
| 1. Case temp&amp;lt;br&amp;gt; 2. pow 0,1&amp;lt;br&amp;gt; 3. cur0&amp;lt;br&amp;gt; 4. temp0&lt;br /&gt;
| 1. 10-bit DAC&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Benchtop===&lt;br /&gt;
*Functions&lt;br /&gt;
**Primary communciation with module boards via RS485&lt;br /&gt;
**Secondary communication with other benchtops via RS232&lt;br /&gt;
**Digital I/O control for 2 lasers&lt;br /&gt;
**Analog inputs on power, current and temperature&lt;br /&gt;
**Analog outputs for power and current control&lt;br /&gt;
**LCD display and rotary key for user input&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 3.3 Base Benchtop&lt;br /&gt;
! Digital Input !! Digital Output !! Analog Input !! Analog Output&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| 1. ICSP&amp;lt;br&amp;gt; 2. Rotary Key&amp;lt;br&amp;gt; 3. Push Buttons&lt;br /&gt;
| 1. LED&amp;lt;br&amp;gt; 2. RS232&amp;lt;br&amp;gt; 3. RS458&amp;lt;br&amp;gt; 4.LCD display&amp;lt;br&amp;gt; 5. Buzzer&amp;lt;br&amp;gt; 6. Digital Ctrl 0,1&lt;br /&gt;
| 1. Case temp&amp;lt;br&amp;gt; 2. CurrentDetect 0,1&amp;lt;br&amp;gt; 3. PowerDetect 0,1,2,3&amp;lt;br&amp;gt; 4. TempDetect&lt;br /&gt;
| 1. 10-bit DAC (PowerCurrentCtrl 0,1)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Development Environment==&lt;br /&gt;
&lt;br /&gt;
===Windows===&lt;br /&gt;
&lt;br /&gt;
[[Image:PIC_setup_win.JPG]]&lt;br /&gt;
&lt;br /&gt;
*C-Compiler, Assembler and Linker are under GNU license.&lt;br /&gt;
**MPLAB C30 C Compiler (*.c -&amp;gt; *.s)&lt;br /&gt;
**MPLAB ASM30 Assembler (*.s -&amp;gt; *.o)&lt;br /&gt;
**MPLAB LINK30 Linker (*.o -&amp;gt; *.bin)&lt;br /&gt;
&lt;br /&gt;
*PA optimizer, simulator, runtime libraries, header files, include files, and linker scripts are not covered by GNU. Reference is [http://direct.forum.microchip.com/tm.aspx?m=107208 here].&lt;br /&gt;
&lt;br /&gt;
*Microchip has integrated ASM30, LINK30, assembly header files, linker scripts in MPLAB IDE, which is free for download.&lt;br /&gt;
*MPLAB C30 costs US$895. A 60-day free student version is also available. After 60-days, the optimizer is automatically disabled, while other tools can still function properly. Refer to Table 2.4.&lt;br /&gt;
&lt;br /&gt;
*C-libraries contained in C30 includes (Refer to [http://ww1.microchip.com/downloads/en/DeviceDoc/16bit_Language_Tool_Libraries_51456c.pdf 16-Bit Language Tools Libraries] from Microchip).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 4.1 C Libraries in MPLAB C30&lt;br /&gt;
! Library !! Directory &amp;lt;br&amp;gt;(\\Microchip\MPLAB C30) !! Major functions&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| DSP Library &amp;lt;br&amp;gt;(e.g. libdsp-coff.a)&lt;br /&gt;
| \lib &amp;lt;br&amp;gt; \src\dsp &amp;lt;br&amp;gt; \support\h&lt;br /&gt;
| Vector, Matrix, Filter, etc.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| 16-Bit Peripheral Libraries &amp;lt;br&amp;gt;(e.g. libp30F5011-coff.a)&lt;br /&gt;
| \lib &amp;lt;br&amp;gt; \src\peripheral &amp;lt;br&amp;gt; \support\h&lt;br /&gt;
| ADC12, IOPort, UART, I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C, etc.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Standard C Libraries &amp;lt;br&amp;gt;(e.g. libc-coff.a, libm-coff.a, libpic-coff.a)&lt;br /&gt;
| \lib &amp;lt;br&amp;gt; \src\libm &amp;lt;br&amp;gt; \include&lt;br /&gt;
| stdio.h, time.h, float.h, math.h, &lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| MPLAB C30 Built-in Functions&lt;br /&gt;
| none&lt;br /&gt;
| _buildin_addab, _buildin_add, _buildinmpy, etc&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Linux===&lt;br /&gt;
&lt;br /&gt;
[[Image:PIC_setup_linux.JPG]]&lt;br /&gt;
&lt;br /&gt;
*C Compiler, Assembler and Linker are under GNU license.&lt;br /&gt;
**The code can be downloaded from Microchip at [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en023073 here].&lt;br /&gt;
**Current MPLAB ASM30 Assembler: v2.04&lt;br /&gt;
**Current MPLAB C30 Compiler: v2.04&lt;br /&gt;
&lt;br /&gt;
*[http://gcc.gnu.org/ml/gcc/2005-02/msg01144.html John Steele Scott] has made templates that can be readily used by Debian-based systems. Someone at http://noel.feld.cvut.cz/dspic/ has done the necessary conversion to *.deb already.&lt;br /&gt;
**Download '''pic30-1.32-debian.tar.bz2''' for Template v1.32. (For v2.01, please goto [http://thread.gmane.org/gmane.comp.hardware.microcontrollers.gnupic/3768/focus=3768  pic30-debian-2.01.tar.bz2]).&lt;br /&gt;
**Download '''pic30-binutils_1.32-1_i386.deb''' for the assember.&lt;br /&gt;
**Download '''pic30-gcc_1.32-1_i386.deb''' for the compiler.&lt;br /&gt;
&lt;br /&gt;
*'''Important Note''': Only the compiler is free. The header files and library is owned by Microchip. &lt;br /&gt;
**Thomas Sailer suggested to download the Student version of C30 compiler and then build the libraries without source code. A package template for Fedora system is available [http://www.baycom.org/~tom/dspic/ here].&lt;br /&gt;
**Instructions for filling the upstream direction is available [http://forum.microchip.com/printable.aspx?m=139360 here].&lt;br /&gt;
**Alteratively, [https://gna.org/projects/pic30-libc/ Stephan Walter] has started a project to develop C Runtime Library for dsPIC. &lt;br /&gt;
***Current libraries in version 0.1.1 include: assert.h, cdefs.h, ctype.h, errno.h, inttypes.h, stdint.h, stdio.h, stdlib.h, string.h&lt;br /&gt;
&lt;br /&gt;
*Burning Program Codes to Target Board&lt;br /&gt;
#Use 'dspicprg and dspicdmp' utilities developed by [http://homerreid.ath.cx/misc/dspicprg/ Homer Reid] to burn hex code (*.hex) to devices. See Reference [http://forum.microchip.com/tm.aspx?m=94243 here]. Through serial port only?&lt;br /&gt;
#Use [http://piklab.sourceforge.net/ Piklab IDE]. Details on file format not known.&lt;br /&gt;
#Use [http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&amp;amp;nodeId=1406&amp;amp;dDocName=en019469&amp;amp;part=SW007002 MPLAB IDE] to burn hex code (*.hex) to devices.&lt;br /&gt;
&lt;br /&gt;
===Code Optimization===&lt;br /&gt;
*Code Optimization under GNU license supports O0 and O1 only.&lt;br /&gt;
*MPLAB C-Compiler supports O0, O1, O2, Os and O3. The Student version will disable O2, Os, and O3 after 60 days.&lt;br /&gt;
*Below is a comparsion between different optimization levels for the project including drivers for 2 projects.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 4.2 Comparison between differnt optimization levels&lt;br /&gt;
! Optimization !! Description !! Project 1&amp;lt;br&amp;gt;Code Size&amp;lt;br&amp;gt;(byte) !! Project 1&amp;lt;br&amp;gt;Data Usage&amp;lt;br&amp;gt;(byte) !! Project 2&amp;lt;br&amp;gt;Code Size&amp;lt;br&amp;gt;(byte) !! Project 2&amp;lt;br&amp;gt;Data Usage&amp;lt;br&amp;gt;(byte)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O0 &lt;br /&gt;
| No optimization&amp;lt;br&amp;gt;Fastest Compilation&lt;br /&gt;
| 6222 (9%) || 178 (4%) || 26,037 (38%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O1 &lt;br /&gt;
| Optimize&amp;lt;br&amp;gt; Tries to reduce code size and execution time.&lt;br /&gt;
| 4473 (6%) || 178 (4%) || 22,290 (32%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O2 &lt;br /&gt;
| Optimize even more&amp;lt;br&amp;gt; Performs nearly all supported optimizations &amp;lt;br&amp;gt;that do not involve a space-speed trade-off. &amp;lt;br&amp;gt;Increases both compilation time and the &amp;lt;br&amp;gt;performance of the generated code.&lt;br /&gt;
| 4422 (6%) || 178 (4%) || 21,993 (32%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| O3 &lt;br /&gt;
| Optimize yet more. &amp;lt;br&amp;gt;O3 turns on all optimizations specified by O2 &amp;lt;br&amp;gt;and also turns on the inline-functions option.&lt;br /&gt;
| 4485 (6%) || 178 (4%) || 22,176 (32%) || 710 (17%)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Os &lt;br /&gt;
| Optimize for size. &amp;lt;br&amp;gt;Os enables all O2 optimizations that do not &amp;lt;br&amp;gt;typically increase code size. It also performs &amp;lt;br&amp;gt;further optimizations designed to reduce code &amp;lt;br&amp;gt;size.&lt;br /&gt;
| 4356 (6%) || 178 (4%) || 21,885 (32%) || 710 (17%)&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Software Architecture==&lt;br /&gt;
   +----------+-----------+---------+---------+&lt;br /&gt;
   |   local  |  remote   |         |         |&lt;br /&gt;
   +----------+-----------+  host   |   UI    |&lt;br /&gt;
   |      data access     | channel |         |&lt;br /&gt;
   |     (DI,DO,AI,AO)    |         |         |&lt;br /&gt;
   +----------------------+---------+---------+&lt;br /&gt;
   |               Application                |&lt;br /&gt;
   |                                          |&lt;br /&gt;
   +------------------------------------------+&lt;br /&gt;
   |            Applications Model            |&lt;br /&gt;
   |       +--------------+-----------+       |&lt;br /&gt;
   |       |    GUI       |   CLib    |       |&lt;br /&gt;
   |       |       +------+-----------+-------+&lt;br /&gt;
   |       |       |     Operating System     |&lt;br /&gt;
   +-------+-------+--------------------------+&lt;br /&gt;
   |                Drivers                   |   &lt;br /&gt;
   +------------------------------------------+&lt;br /&gt;
   |               Hardware                   |   &lt;br /&gt;
   +------------------------------------------+&lt;br /&gt;
*Currently, operating system is based on [http://www.psocdeveloper.com/forums/viewtopic.php?p=973&amp;amp;sid=717d6b7e86472a5036f7cfbbcb0c05aa linlike8]. The possibility of using other OS (e.g. [http://www.freertos.org/ FreeRTOS]) will be explored later.&lt;br /&gt;
*Software Drivers are to be developed to allow users at Application Level to use the hardware (e.g. ADC, DAC, UART, EEPROM) through the OS.&lt;br /&gt;
*The interface between the drivers and the OS should be compliant with [http://www.die.net/doc/linux/man/man2/ POSIX standard] for Linux (e.g. open(), write(), read(), ioctl() etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming Tips==&lt;br /&gt;
&lt;br /&gt;
===Memory Map for 5011===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.1 Memory Location&lt;br /&gt;
! Type !! Start Address !! End Address !! Size&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Flash || 0x000000 ||0x00AFFF || 44K&amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: Reset Vector || 0x000000 ||0x000003 || 4&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: Interrupt Vector Table || 0x000004 ||0x00007F || 124&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: Alternate Vector Table || 0x000084 ||0x0000FF || 124&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| +--Flash: User Program || 0x000100 ||0x00AFFF || 43.7K&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| EEPROM || 0x7FFC00 || 0x7FFFFF || 1K&amp;lt;sup&amp;gt;[2]&amp;lt;/sup&amp;gt;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Programming Executive || 0x800000 || 0x8005BF || 1472&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Unit ID || 0x8005C0 || 0x8005FF || 64&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Config  Registers || 0xF80000 || 0xF8000F || 16&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Device ID || 0xFF0000 || 0xFF0003 || 4&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
[1] Each address is 16-bit wide. Every two addresses correspond to a 24-bit instruction. Each even address contains 2 valid bytes; each odd address contains 1 valid byte plus 1 phathom byte.&amp;lt;br&amp;gt;&lt;br /&gt;
[2] Each address is 8-bit wide.&lt;br /&gt;
&lt;br /&gt;
===Data Location===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.2 Data Location&lt;br /&gt;
! Type !! Description !! Example&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _XBSS(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in X-memory, aligned at N, no initilization&lt;br /&gt;
| int _XBSS(32) xbuf[16];&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _XDATA(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in X-memory, aligned at N, with initilization&lt;br /&gt;
| int _XDATA(32) xbuf[] = {1, 2, 3, 4, 5};&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _YBSS(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in Y-memory, aligned at N, no initilization&lt;br /&gt;
| int _YBSS(32) ybuf[16];&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _YDATA(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| RAM Data in Y-memory, aligned at N, with initilization&lt;br /&gt;
| int _YDATA(32) ybuf[16] = {1, 2, 3, 4, 5};&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(const)))&lt;br /&gt;
| Flash ROM data, constant, accessed by normal C&amp;lt;br&amp;gt;statements, but 32K max.&lt;br /&gt;
| int i __attribute__((space(const))) = 10;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(prog)))&lt;br /&gt;
| Flash ROM data, read/write by program space visibility&amp;lt;br&amp;gt;window (psv)&lt;br /&gt;
| int i __attribute__((space(prog)));&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(auto_psv)))&lt;br /&gt;
| Flash ROM data, read by normal C statements, write&amp;lt;br&amp;gt;by accessing psv&lt;br /&gt;
| int i __attribute__((space(auto_psv)));&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| __attribute__((space(psv)))&lt;br /&gt;
| Flash ROM data, read/write by (psv)&lt;br /&gt;
| int i __attribute__((space(psv)));&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _EEDATA(N) &amp;lt;sup&amp;gt;[1]&amp;lt;/sup&amp;gt;&lt;br /&gt;
| ROM Data in EEPROM, aligned at N, read/write with psv&lt;br /&gt;
| int _EEDATA(2) table[]={0, 1, 2, 3, 5, 8};&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _PERSISTENT&lt;br /&gt;
| RAM Data, data remain after reset&lt;br /&gt;
| int _PERSISTENT var1, var2;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _NEAR&lt;br /&gt;
| RAM Data at near section&lt;br /&gt;
| int _NEAR var1, var2;&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _ISR&lt;br /&gt;
| Interrupt service rountine&lt;br /&gt;
| void _ISR _INT0Interrupt(void);&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| _ISRFAST&lt;br /&gt;
| Fast interrupt service rountine&lt;br /&gt;
| void _ISRFAST _T0Interrupt(void);&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
#N must be a power of two, with a minimum value of 2.&lt;br /&gt;
&lt;br /&gt;
===Configuration Bits===&lt;br /&gt;
----&lt;br /&gt;
*System clock source can be provided by:&lt;br /&gt;
#Primary oscillator (OSC1, OSC2)&lt;br /&gt;
#Secondary oscillator (SOSCO and SOSCI) with 32kHz crystal&lt;br /&gt;
#Internal Fast RC (FRC) oscillator at 7.37MHz (7372800Hz)&lt;br /&gt;
#Low-Power RC (LPRC) oscillator (Watchdog Timer) at 512 kHz.&lt;br /&gt;
*These clock sources can be incorporated with interal Phase-locked-loop (PLL) x4, x8 or x16 to yield the osciallator frequrence F&amp;lt;sub&amp;gt;OSC&amp;lt;/sub&amp;gt;&lt;br /&gt;
*The system clock is divided by 4 to yield the internal instruction cycle clock, F&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;=F&amp;lt;sub&amp;gt;OSC&amp;lt;/sub&amp;gt;/4&lt;br /&gt;
*FRC with PLLx16 is used to achieve F&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;=29.49MHz (29491200Hz or 30MIPS)&lt;br /&gt;
&lt;br /&gt;
  //The code (MACRO) below is to be placed at the top of program (before main)&lt;br /&gt;
     _FOSC(CSW_FSCM_OFF &amp;amp; FRC_PLL16);&lt;br /&gt;
     _FWDT(WDT_OFF);    //Turn off Watchdog Timer&lt;br /&gt;
     _FBORPOR(PBOR_ON &amp;amp; BORV_27 &amp;amp; MCLR_DIS &amp;amp; PWRT_16);&lt;br /&gt;
     _FGS(CODE_PROT_OFF); //Disable Code Protection&lt;br /&gt;
&lt;br /&gt;
===Timer===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Each timer is 16-bit (i.e. counting from 0 to 65535).&lt;br /&gt;
*Timer 2 and 3 can be incorporated together to form a 32-bit timer.&lt;br /&gt;
*Prescale is the ratio between timer counts and system clock counts. Prescales of 1:1, 1:8, 1:64 and 1:256 are available.&lt;br /&gt;
*Timers may be used to implement free time clock or mesaure time.&lt;br /&gt;
&lt;br /&gt;
====Free Time Clock====&lt;br /&gt;
*Let required time for ticking be PERIOD.&lt;br /&gt;
*Number of instruction cycles during PERIOD = PERIOD*F&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt; cycles&lt;br /&gt;
*Using a prescale of 1:x, the timer period count register = # of cycles/x&lt;br /&gt;
*e.g. PERIOD = 10ms; # of cycles = 10ms*30MHz = 300000 cylces; Using 1:64 Prescale, register setting = 300000/64 = 4688&lt;br /&gt;
   void time_init(void){&lt;br /&gt;
      TMR1 = 0;		// Clear register&lt;br /&gt;
      PR1 = 4688;	// Set period&lt;br /&gt;
      //============================================================&lt;br /&gt;
      _T1IF = 0;		// Clear interrupt flag&lt;br /&gt;
      _T1IE = 1;		// Enable interrupts&lt;br /&gt;
      //============================================================&lt;br /&gt;
      T1CONbits.TCS = 0;		// Use internal clock source&lt;br /&gt;
      T1CONbits.TCKPS = 2;	// Prescale Select 1:64&lt;br /&gt;
      T1CONbits.TON = 1;		// Start the timer &lt;br /&gt;
   }&lt;br /&gt;
   //********************************************************************&lt;br /&gt;
   void _ISRFAST _T1Interrupt(void){&lt;br /&gt;
      _T1IF = 0;		// Clear interrupt flag&lt;br /&gt;
      //Place user code here&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
====Time Measurement====&lt;br /&gt;
*To measure the time taken for action(), use the code below:&lt;br /&gt;
   unsigned int measure_time(void){	&lt;br /&gt;
      PR3 = 0xFFFF;		// Set counter to maximum&lt;br /&gt;
      _T3IF = 0;			// Clear interrupt flag&lt;br /&gt;
      _T3IE = 0;			// Disable interrupt&lt;br /&gt;
      T3CONbits.TON = 1;		// Start the timer, TMR3 count up&lt;br /&gt;
      TMR3 = 0;			//Clear TMR3 to start count up&lt;br /&gt;
      //====================================================&lt;br /&gt;
      //Add code here to wait for something to happen&lt;br /&gt;
      action();&lt;br /&gt;
      //====================================================&lt;br /&gt;
      T3CONbits.TON = 0;	//Stop the timer&lt;br /&gt;
      //====================================================&lt;br /&gt;
      return (unsigned int) TMR3/FCY;      //TMR/FCY yields the actual time&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
===Interrupt===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Registers are involved in Interrupts includes: &lt;br /&gt;
#Interrupt Flag Status (IFS0-IFS2) registers&lt;br /&gt;
#Interrupt Enable Control (IEC0-IEC2) registers&lt;br /&gt;
#Interrupt Priority Control (IPC0-IPC10) registers&lt;br /&gt;
#Interrupt Priority Level (IPL) register&lt;br /&gt;
#Global Interrupt Control (INTCON1, INTCON2) registers&lt;br /&gt;
#Interrupt vector (INTTREG) register&lt;br /&gt;
*User may assign priority level 0-7 to a specific interrupt using IPC. Setting priority to 0 disable a specific interrupt. Level 7 interrupt has the highest priority.&lt;br /&gt;
*Current priority level is stored in IPL. Setting IPL to 7 disables all interrupts (except traps). The following MACROs are defined in &amp;lt;p30f5011.h&amp;gt;:&lt;br /&gt;
#SET_CPU_IPL(ipl): Set IPL to ipl&lt;br /&gt;
#SET_AND_SAVE_CPU_IPL(save_to, ipl): Store the current IPL to save_to and then set to ipl&lt;br /&gt;
#RESTORE_CPU_IPL(saved_to): Restore the previously saved ipl&lt;br /&gt;
*sti() and cli() are defined to enable and disable global interrupts for time critical functions:&lt;br /&gt;
  extern int SAVE_IPL;&lt;br /&gt;
  #define sti()	RESTORE_CPU_IPL(SAVE_IPL)&lt;br /&gt;
  #define cli()	SET_AND_SAVE_CPU_IPL(SAVE_IPL, 7)&lt;br /&gt;
  //============================================================&lt;br /&gt;
  char adc_ioctl(unsigned char request, unsigned char* argp){&lt;br /&gt;
    //...&lt;br /&gt;
    cli();		//Disable global interrupt&lt;br /&gt;
    for(;ch&amp;lt;=argp[0];ch++)&lt;br /&gt;
       adc_add_ch(argp[ch]);	//Add adc channels&lt;br /&gt;
    sti();		//Enable global interrupt&lt;br /&gt;
    //...&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
===UART===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*5011 provides two UART channels UxART, for x=1, 2.&lt;br /&gt;
*UxMODE, UxSTA, UxBRG are registers used to set the mode, indicate the status, and set the baud rate respectively.&lt;br /&gt;
*For UART communications compatiable with RS232 standard, an external driver (e.g. MAX3232ESE) is needed.&lt;br /&gt;
*For UART communications compatiable with RS485 standard, an external driver (e.g. DS3695N) is needed.&lt;br /&gt;
====Auto baud rate detection====&lt;br /&gt;
*The method is provided by [http://www.opencircuits.com/DsPIC30F_5011_Development_Board ingenia bootloader].&lt;br /&gt;
*The PC sends a ASCII character 'U' (0x55) to the target board.&lt;br /&gt;
*On the first rising edge of the start bit, the target board starts the timer.&lt;br /&gt;
*At the fifth rising edge, the timer is stopped, let the count number be ''t_count''. &lt;br /&gt;
**The measured period corresponds to 8 bits transmitted at a baud rate ''uxbrg''.&lt;br /&gt;
     _   _   _   _   _   _&lt;br /&gt;
   _|S|_|1|_|1|_|1|_|1|_|S|_  (S = Start Bit)&lt;br /&gt;
    &amp;lt;---------------&amp;gt;&lt;br /&gt;
    Measured Time&lt;br /&gt;
*The relationship between ''uxbrg'' and ''TMR'' is&lt;br /&gt;
   Measured Time (in seconds) = t_count/F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;&lt;br /&gt;
   uxbrg = 1/(Measured Time/8)&lt;br /&gt;
         = 8*F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/t_count&lt;br /&gt;
*Since UxBRG is computed by:&lt;br /&gt;
   UxBRG = (F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/(16*Baudrate)) -1&lt;br /&gt;
         = (F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/(16*8*F&amp;lt;sub&amp;gt;cy&amp;lt;/sub&amp;gt;/t_count)) -1&lt;br /&gt;
         = t_count/128 -1&lt;br /&gt;
*The following is the code for auto baud rate detection for U2ART:&lt;br /&gt;
   unsigned int uart2_autobaud(void){&lt;br /&gt;
      U2MODEbits.ABAUD = 1;		//Enable Autobaud detect from U2RX (from IC2 if 0)&lt;br /&gt;
      U2MODEbits.UARTEN = 1;		//U2ART enable&lt;br /&gt;
      //Timer 3 Config==========================================================&lt;br /&gt;
      PR3 = 0xFFFF;			// Set counter to maximum&lt;br /&gt;
      _T3IF = 0;			// Clear interrupt flag&lt;br /&gt;
      _T3IE = 0;			// Disable interrupt&lt;br /&gt;
      T3CONbits.TON = 1;		// Start the timer, TMR3 count up&lt;br /&gt;
      //Input Capture Config====================================================&lt;br /&gt;
      IC2CONbits.ICM = 3;		//Detect rising	&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      _IC2IE = 0; 			//Disable interrupt&lt;br /&gt;
      //Start Auto baud detection===============================================&lt;br /&gt;
      unsigned int i=0;&lt;br /&gt;
      cli();				//Disable Global Interrupt&lt;br /&gt;
      while(!_IC2IF);			//1st rising edge detected&lt;br /&gt;
      TMR3 = 0;			//Clear TMR3 to start count up&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//2nd rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//3rd rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//4th rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      while(!_IC2IF);			//5th rising edge detected&lt;br /&gt;
      _IC2IF = 0;			//Clear interrupt flag&lt;br /&gt;
      T3CONbits.TON = 0;		//Stop the timer&lt;br /&gt;
      sti(); 			//Enable Global Interrupt&lt;br /&gt;
      //Compute value for BRG register==========================================&lt;br /&gt;
      unsigned int time;&lt;br /&gt;
      time = ((TMR3+0x40)&amp;gt;&amp;gt;7)-1;	//+0x40 for rounding&lt;br /&gt;
      //========================================================================&lt;br /&gt;
      return time;&lt;br /&gt;
   }&lt;br /&gt;
*For 30MIP, tested speeds of transmission include 9600bps, 19200bps, 28800bps, 38400bps and 57600bps.&lt;br /&gt;
====Initialize UART====&lt;br /&gt;
   void uart2_init(void){&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Baud rate&lt;br /&gt;
      //  +-- Default Baud rate = 19.2 kbps&lt;br /&gt;
      //	+-- U2BRG = 30e6 / (16 * 19200) - 1 = 97&lt;br /&gt;
      unsigned int u2brg = 97; &lt;br /&gt;
      #if(AUTO_BAUD_DECT&amp;gt;0)&lt;br /&gt;
      u2brg = uart2_autobaud();&lt;br /&gt;
      #endif&lt;br /&gt;
      U2BRG  = u2brg;					&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Disable U2ART&lt;br /&gt;
      U2MODEbits.UARTEN = 0;			//Disable U2ART module&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Interrupt Priority&lt;br /&gt;
      _U2RXIF = 0;	//Clear Rx interrupt flags&lt;br /&gt;
      _U2TXIF = 0;	//Clear Tx interrupt flags&lt;br /&gt;
      _U2RXIE = 1;	//Receive interrupt: 0 disable, 1 enable &lt;br /&gt;
      _U2TXIE = 1;	//Transmit interrupt: 0 disable, 1 enable&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Mode&lt;br /&gt;
      //  +--Default: 8N1, no loopback, no wake in sleep mode, continue in idle mode&lt;br /&gt;
      //  +--Diable autobaud detect&lt;br /&gt;
      //  +--Enable U2ART module&lt;br /&gt;
      U2MODEbits.ABAUD = 0;	//Disable Autobaud detect from U2RX &lt;br /&gt;
      U2MODEbits.UARTEN = 1;	//U2ART enable&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      // Configure Status&lt;br /&gt;
      //  +--Default: TxInt when a char is transmitted, no break char&lt;br /&gt;
      //  +--Default: RxInt when a char is received, no address detect, clear overflow&lt;br /&gt;
      //  +--Enable Transmit&lt;br /&gt;
      U2STAbits.UTXEN = 1;	//Tx enable&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
====Sending and Receiving Data====&lt;br /&gt;
   void _ISR _U2TXInterrupt(void){&lt;br /&gt;
      _U2TXIF = 0;	//Clear Interrupt Flag&lt;br /&gt;
      if(tx_data_ready())&lt;br /&gt;
         U2TXREG = tx_buf[POS]; 	//send next byte...&lt;br /&gt;
   }&lt;br /&gt;
   void _ISR _U2RXInterrupt(void){&lt;br /&gt;
      _U2RXIF = 0;		//Clear the flag&lt;br /&gt;
      if ( U2STAbits.URXDA ){&lt;br /&gt;
         rx_buf[POS] = (unsigned char) U2RXREG; //Read the data from buffer&lt;br /&gt;
      }&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
===I&amp;lt;sup&amp;gt;2&amp;lt;/sup&amp;gt;C===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Two lines are devoted for the serial communication. SCL for clock, SDA for data.&lt;br /&gt;
*Standard communication speed includes&lt;br /&gt;
#Standard speed mode: 100kHz&lt;br /&gt;
#Fast speed mode: 400kHz&lt;br /&gt;
#High speed mode: 3.4MHz&lt;br /&gt;
*dsPIC30f5011 supports standard and fast speed modes. The maximum speed attainable is 1MHz.&lt;br /&gt;
*Pull-up resistors are required for both SCL and SDA. Minimum pull-up resistance is given by:&lt;br /&gt;
     Pull-up resistor (min) = (V&amp;lt;sub&amp;gt;dd&amp;lt;/sub&amp;gt;-0.4)/0.003  ......  [See section 21.8 in Family reference manual]&lt;br /&gt;
*2.2Kohm is typical for standard speed mode.&lt;br /&gt;
*After initiating a start/stop/restart bit, add a small delay (e.g. no operation) before polling the corresponding control bit (hardware controlled). For example: &lt;br /&gt;
      StartI2C();&amp;lt;br&amp;gt;				&lt;br /&gt;
      Nop();			//A small delay for hardware to respond&amp;lt;br&amp;gt;&lt;br /&gt;
      while(I2CCONbits.SEN);	//Wait till Start sequence is completed&lt;br /&gt;
*After sending a byte and receiving an acknowledgement from the slave device, ensure to change to idle state. For example:&lt;br /&gt;
      MasterWriteI2C(0x55);&amp;lt;br&amp;gt;&lt;br /&gt;
      while(I2CSTATbits.TBF);		//Wait for transmit buffer to empty&amp;lt;br&amp;gt;&lt;br /&gt;
      while(I2CSTATbits.ACKSTAT);	//Wait for slave acknowledgement&amp;lt;br&amp;gt;&lt;br /&gt;
      IdleI2C();&lt;br /&gt;
&lt;br /&gt;
===ADC===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*12-bit ADC: (Max 16 Channels)&lt;br /&gt;
*Allow a maximum of 2 sets of analog input multiplexer configurations, MUX A and MUX B (Normally use one only).&lt;br /&gt;
*A maximum of 200kps of sampling rate when using auto sampling mode.&lt;br /&gt;
====Configuration====&lt;br /&gt;
*Interrupt: Clear ADC interrupt flag and enable ADC interrupt. The ADC module will be set to interrupt when the specified channels are updated.&lt;br /&gt;
   _ADIF = 0;				//clear ADC interrupt flag&lt;br /&gt;
   _ADIE = 1;				//enable adc interrupt&lt;br /&gt;
*I/O: Set the corresponding TRISBX bits (digit i/o config) to input (i.e. = 1), and set corresponding bits in ADPCFG (analog config) to zero.&lt;br /&gt;
   _TRISB2 = 1;		//Set AN2 [Case Temp] as analog input&lt;br /&gt;
   _TRISB8 = 1;		//Set AN8 [Power detect 0] as analog input&lt;br /&gt;
   _TRISB9 = 1;		//Set AN9 [Power detect 1] as analog input&lt;br /&gt;
   _TRISB10 = 1;		//Set AN10 [Current detect 0] as analog input&lt;br /&gt;
   _TRISB11 = 1;		//Set AN11 [Temp detect 0] as analog input&lt;br /&gt;
   ADPCFG = 0xF0FB;	//0 =&amp;gt; Analog, 1 =&amp;gt; Digital&lt;br /&gt;
*Scanning Mode: Scan mode is used. In this mode, the Sample and Hold (S/H) is switched between the channels specified by ADCSSL (Scan select register).&lt;br /&gt;
   ADCSSL = 0x0F04;	//0 =&amp;gt; Skip, 1 =&amp;gt; Scan&lt;br /&gt;
*Reference Voltage for S/H: Only MUX A is used. By default, the negative reference voltage of the S/H is connected to V&amp;lt;sub&amp;gt;REF-&amp;lt;/sub&amp;gt;.&lt;br /&gt;
   ADCHSbits.CH0NA = 0;&lt;br /&gt;
*Sampling Rate: T&amp;lt;sub&amp;gt;AD&amp;lt;/sub&amp;gt; refers to the time unit for the ADC clock. To configure the ADC module at 200kbps, the minimum sampling time of 1T&amp;lt;sub&amp;gt;AD&amp;lt;/sub&amp;gt; = 334ns is required. ADCS&amp;lt;5:0&amp;gt; in ADCON3 register is used to set the time, which is given by:&lt;br /&gt;
      ADCS&amp;lt;5:0&amp;gt; = 2(T&amp;lt;sub&amp;gt;AD&amp;lt;/sub&amp;gt;/T&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;)-1 &lt;br /&gt;
                = 2(334e-9/33.34e-9)-1 &lt;br /&gt;
                = 19&lt;br /&gt;
&lt;br /&gt;
      ADCON3bits.SAMC = 1;	//1TAD for sampling time&lt;br /&gt;
      ADCON3bits.ADRC = 1;	//Use internal ADC clock&lt;br /&gt;
      ADCON3bits.ADCS = 19;	//Set TAD = 334ns&lt;br /&gt;
*Settings for ADC Operation: For 200kbps operation, the voltage references for the ADC voltage are connected to V&amp;lt;sub&amp;gt;REF+&amp;lt;/sub&amp;gt; and V&amp;lt;sub&amp;gt;REF-&amp;lt;/sub&amp;gt;. Scan input is enabled, and the module will generate an interrupt when all selected channels have been scanned.&lt;br /&gt;
      ADCON2bits.VCFG = 3;	//External Vref+, Vref-&lt;br /&gt;
      ADCON2bits.CSCNA = 1;	//Scan input&lt;br /&gt;
      ADCON2bits.SMPI = 4;	//take 5 samples (one sample per channel) per interrupt&lt;br /&gt;
*More Settings for ADC Operation: Turn on the module, select the data output format as unsigned integer, and allow auto setting of SAMP bit (auto sampling).&lt;br /&gt;
      ADCON1bits.ADON = 1;	//Turn on module&lt;br /&gt;
      ADCON1bits.FORM = 0;	//[2 fractional]; [3 siged fractional]&lt;br /&gt;
      ADCON1bits.SSRC = 7;	//auto covert, using internal clock source&lt;br /&gt;
      ADCON1bits.ASAM = 1;	//auto setting of SAMP bit&lt;br /&gt;
====Storing ADC Data====&lt;br /&gt;
*16 registers (ADCBUF0 -ADCBUF15) are dedicated to store the ADC data between interrupts. However, the data in ADCBUFx does not necessarily correspond to the data taken for channel x. Since the lowest register will always be filled first, when some of the channels are not scanned (i.e. skipped), care must be taken. The following code checks the ADCSSL register for the current scanning channels and moves the data to the corresponding position in *adc_buf.&lt;br /&gt;
      void _ISR _ADCInterrupt(void){&lt;br /&gt;
           _ADIF = 0;	//Clear adc interrupt&lt;br /&gt;
           //==========================================================&lt;br /&gt;
           unsigned char channel = 0;&lt;br /&gt;
           unsigned char buffer = 0;&lt;br /&gt;
           for (; channel&amp;lt;ADC_MAX_CH; channel++){&lt;br /&gt;
               if(adc_ch_updated(channel)){	//Check if channel has updated&lt;br /&gt;
                    adc_buf[channel] = ADC16Ptr[buffer]; //Copy data to adc_buf&lt;br /&gt;
                    buffer++;&lt;br /&gt;
               }&lt;br /&gt;
           }&lt;br /&gt;
      }&lt;br /&gt;
      unsigned char adc_ch_updated(unsigned char ch){&lt;br /&gt;
           unsigned int mask;&lt;br /&gt;
           mask = 0x0001 &amp;lt;&amp;lt; ch;&lt;br /&gt;
           if(ADCSSL &amp;amp; mask)&lt;br /&gt;
              return 1;&lt;br /&gt;
         return 0;&lt;br /&gt;
      }&lt;br /&gt;
====Adding and Removing Channels====&lt;br /&gt;
*Channels may be added or removed by changing _TRISBX, ADPCFG, ADCSSL and ADCON2bits.SMPI.&lt;br /&gt;
   void adc_add_ch(unsigned char ch){&lt;br /&gt;
      //Enable i/o pin as input===========================================&lt;br /&gt;
      switch(ch){&lt;br /&gt;
        case 0: _TRISB0 = 1; break;&lt;br /&gt;
        case 1: _TRISB1 = 1; break;&lt;br /&gt;
        case 2: _TRISB2 = 1; break;&lt;br /&gt;
        case 3: _TRISB3 = 1; break;&lt;br /&gt;
        case 4: _TRISB4 = 1; break;&lt;br /&gt;
        case 5: _TRISB5 = 1; break;&lt;br /&gt;
        case 6: _TRISB6 = 1; break;&lt;br /&gt;
        case 7: _TRISB7 = 1; break;&lt;br /&gt;
        case 8: _TRISB8 = 1; break;&lt;br /&gt;
        case 9: _TRISB9 = 1; break;&lt;br /&gt;
        case 10: _TRISB10 = 1; break;&lt;br /&gt;
        case 11: _TRISB11 = 1; break;&lt;br /&gt;
        case 12: _TRISB12 = 1; break;&lt;br /&gt;
        case 13: _TRISB13 = 1; break;&lt;br /&gt;
        case 14: _TRISB14 = 1; break;&lt;br /&gt;
        default: _TRISB15 = 1;&lt;br /&gt;
      }&lt;br /&gt;
      unsigned int mask;&lt;br /&gt;
      mask = 0x0001 &amp;lt;&amp;lt; ch;&lt;br /&gt;
      ADCSSL = ADCSSL | mask;		 &lt;br /&gt;
      ADPCFG = ~ADCSSL;&lt;br /&gt;
      ADCON2bits.SMPI++;	//take one more sample per interrupt&lt;br /&gt;
   }&lt;br /&gt;
   void adc_rm_ch(unsigned char ch){&lt;br /&gt;
      unsigned int mask;&lt;br /&gt;
      mask = 0x0001 &amp;lt;&amp;lt; ch;&lt;br /&gt;
      ADPCFG = ADPCFG | mask;&lt;br /&gt;
      ADCSSL = ~ADPCFG;&lt;br /&gt;
      ADCON2bits.SMPI--;	//take one less sample per interrupt&lt;br /&gt;
   }&lt;br /&gt;
&lt;br /&gt;
===EEPROM===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*5011 has 1024 bytes of EEPROM, readable and writable under normal voltage (5V).&lt;br /&gt;
*To use, declare:&lt;br /&gt;
  unsigned char _EEDATA(2) eeData[1024]={ 0x00, 0x00, 0x00, 0x00, .... }&lt;br /&gt;
  unsigned int byte_pointer = 0;&lt;br /&gt;
====Seek====&lt;br /&gt;
*This function moves the pointer to the desired position before a reading/writing operation is performed.&lt;br /&gt;
   int eeprom_lseek(int offset, unsigned char whence){&lt;br /&gt;
      byte_pointer = offset;&lt;br /&gt;
      return byte_pointer;&lt;br /&gt;
   }&lt;br /&gt;
====Read====&lt;br /&gt;
*This function read ''count'' bytes from the eeprom.&lt;br /&gt;
   int eeprom_read(unsigned char* buf, int count){&lt;br /&gt;
      int i=0;&lt;br /&gt;
      for(; i&amp;lt;count &amp;amp;&amp;amp; byte_pointer &amp;lt; 1024; i++){&lt;br /&gt;
         readEEByte( __builtin_tblpage(eeData), &lt;br /&gt;
                     __builtin_tbloffset(eeData) + byte_pointer, &lt;br /&gt;
                     &amp;amp;buf[i]);&lt;br /&gt;
         byte_pointer++;		//Update global pointer&lt;br /&gt;
      }&lt;br /&gt;
      return i;	//read i bytes successful	&lt;br /&gt;
   }&lt;br /&gt;
*readEEByte() is implemented in assembly code as follows:&lt;br /&gt;
   .global _readEEByte&lt;br /&gt;
   _readEEByte:&lt;br /&gt;
      push      TBLPAG		;w0 = base of eeData&lt;br /&gt;
      mov       w0, TBLPAG	;w1 = offset for eeData in byte&lt;br /&gt;
      tblrdl.b  [w1], [w2]	;w2 = pointer to user buffer&lt;br /&gt;
      pop     	TBLPAG&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
====Write====&lt;br /&gt;
*This function write ''count'' bytes to eeprom.&lt;br /&gt;
   int eeprom_write(unsigned char* buf, int count){&lt;br /&gt;
      char isOddAddr = byte_pointer%2;	//current address is odd&lt;br /&gt;
      char isOddByte = count%2;		//number of bytes to write is odd&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      unsigned int word_offset = byte_pointer&amp;gt;&amp;gt;1; //div by 2 and round down&lt;br /&gt;
      int max_write;&lt;br /&gt;
      max_write = (isOddAddr == 0 &amp;amp;&amp;amp; isOddByte == 0) ? (count&amp;gt;&amp;gt;1) : (count&amp;gt;&amp;gt;1)+1;&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      unsigned int word_data;	//Store word to be written&lt;br /&gt;
      int byte_wr = 0;		//number of bytes written, i.e buffer pointer&lt;br /&gt;
      int i = 0;&lt;br /&gt;
      //=================================================================&lt;br /&gt;
      for(; i&amp;lt;max_write &amp;amp;&amp;amp; word_offset&amp;lt;512; i++, word_offset++){&lt;br /&gt;
         if(i==0 &amp;amp;&amp;amp; isOddAddr){&lt;br /&gt;
            //First byte not used&lt;br /&gt;
            //============================================save first byte&lt;br /&gt;
            readEEByte( __builtin_tblpage(eeData), &lt;br /&gt;
                        __builtin_tbloffset(eeData) + byte_pointer - 1,&lt;br /&gt;
                        &amp;amp;word_data);&lt;br /&gt;
            //===========================================================&lt;br /&gt;
            word_data = ((unsigned int)buf[0] &amp;lt;&amp;lt; 8) + (0xFF &amp;amp; word_data);&lt;br /&gt;
            byte_wr++;				//Update buffer pointer&lt;br /&gt;
            byte_pointer++;			//Update global pointer&lt;br /&gt;
          } else if(i==max_write-1 &amp;amp;&amp;amp; ((isOddAddr &amp;amp;&amp;amp; sOddByte==0)||(isOddAddr==0 &amp;amp;&amp;amp; isOddByte))){&lt;br /&gt;
            //Last byte not used&lt;br /&gt;
            //=============================================save last byte&lt;br /&gt;
            readEEByte(	__builtin_tblpage(eeData), &lt;br /&gt;
                        __builtin_tbloffset(eeData) + byte_pointer + 1,&lt;br /&gt;
                        &amp;amp;word_data);&lt;br /&gt;
            //============================================================&lt;br /&gt;
            word_data = (word_data &amp;lt;&amp;lt; 8) + buf[byte_wr];&lt;br /&gt;
            byte_wr++;				//Update buffer pointer&lt;br /&gt;
            byte_pointer++;			//Update global pointer&lt;br /&gt;
          } else{&lt;br /&gt;
            //Both bytes valid&lt;br /&gt;
            word_data = ((unsigned int)buf[byte_wr+1] &amp;lt;&amp;lt; 8) + buf[byte_wr];&lt;br /&gt;
            byte_wr+=2;				//Update buffer pointer&lt;br /&gt;
            byte_pointer+=2;		//Update global pointer&lt;br /&gt;
          }&lt;br /&gt;
       //==================================================================&lt;br /&gt;
       eraseEEWord( __builtin_tblpage(eeData), &lt;br /&gt;
                    __builtin_tbloffset(eeData) + 2*word_offset);&lt;br /&gt;
       writeEEWord( __builtin_tblpage(eeData), &lt;br /&gt;
                    __builtin_tbloffset(eeData) + 2*word_offset,&lt;br /&gt;
                    &amp;amp;word_data);&lt;br /&gt;
       //==================================================================&lt;br /&gt;
       }&lt;br /&gt;
       return byte_wr;		//No. of byte written&lt;br /&gt;
   }&lt;br /&gt;
*eraseEEWord and writeEEWord are implemented in assembly.&lt;br /&gt;
   .global _eraseEEWord&lt;br /&gt;
   _eraseEEWord:&lt;br /&gt;
      push   TBLPAG				&lt;br /&gt;
      mov    w0, NVMADRU	;w0 = base of eeData&lt;br /&gt;
      mov    w1, NVMADR		;w1 = offset for eeData in word&lt;br /&gt;
      mov    #0x4044, w0			&lt;br /&gt;
      mov    w0, NVMCON		;Set to erase operation&lt;br /&gt;
      push   SR			;Disable global interrupts&lt;br /&gt;
      mov    #0x00E0, w0&lt;br /&gt;
      ior    SR&lt;br /&gt;
      mov    #0x55, w0 		;Write the KEY sequence&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      mov    #0xAA, w0			&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      bset   NVMCON, #15	;Start the erase cycle, bit 15 = WR&lt;br /&gt;
      nop&lt;br /&gt;
      nop&lt;br /&gt;
  L1: btsc   NVMCON, #15	;while(NVMCONbits.WR)&lt;br /&gt;
      bra    L1&lt;br /&gt;
      clr    w0&lt;br /&gt;
      pop    SR			;Enable global interrupts&lt;br /&gt;
      pop    TBLPAG&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
  .global _writeEEWord&lt;br /&gt;
  _writeEEWord:&lt;br /&gt;
      push   TBLPAG		;w0 = base of eeData&lt;br /&gt;
      mov    w0, TBLPAG		;w1 = offset for eeData in byte&lt;br /&gt;
      tblwtl [w2], [w1]		;w2 = pointer to user buffer&lt;br /&gt;
      mov    #0x4004, w0        ;Set to write operation&lt;br /&gt;
      MOV    w0, NVMCON&lt;br /&gt;
      push   SR			;Disable global interrupts&lt;br /&gt;
      mov    #0x00E0, w0&lt;br /&gt;
      ior    SR&lt;br /&gt;
      mov    #0x55, w0 		;Write the KEY sequence&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      mov    #0xAA, w0			&lt;br /&gt;
      mov    w0, NVMKEY&lt;br /&gt;
      bset   NVMCON, #15	;Start the erase cycle, bit 15 = WR&lt;br /&gt;
      nop&lt;br /&gt;
      nop&lt;br /&gt;
  L2: btsc   NVMCON, #15	;while(NVMCONbits.WR)&lt;br /&gt;
      bra    L2&lt;br /&gt;
      clr    w0&lt;br /&gt;
      pop    SR			;Enable global interrupts&lt;br /&gt;
      pop    TBLPAG&lt;br /&gt;
      return&lt;br /&gt;
&lt;br /&gt;
===Simple PWM (Output Compare Module)===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
*The PWM module consists of 8 channels using the output compare module of dsPic.&lt;br /&gt;
*These channels are locate at pin 46 (OC1), 49 (OC2), 50 (OC3), 51 (OC4), 52 (OC5), 53 (OC6), 54 (OC7), 55 (OC8). These pins are shared with port D.&lt;br /&gt;
*The range of PWM freqeuencies obtainable is 2Hz to 15MHz (See Figure 6.3). Suggested range of operation is 2Hz to 120kHz. The relationship between resolution ''r'' and PWM frequency ''f''&amp;lt;sub&amp;gt;PWM&amp;lt;/sub&amp;gt; is given by:&lt;br /&gt;
         f&amp;lt;sub&amp;gt;PWM&amp;lt;/sub&amp;gt; = f&amp;lt;sub&amp;gt;CY&amp;lt;/sub&amp;gt;/(Prescale*10&amp;lt;sup&amp;gt;rlog(2)&amp;lt;/sup&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.3 Relationship of Resolution and PWM Frequency&lt;br /&gt;
! Resolution (bit) !! Prescale=1 !! Prescale=8 !! Prescale=64 !! Prescale=256&lt;br /&gt;
|- &lt;br /&gt;
|1||15,000,000 ||1,875,000 ||234,375||58,594 &lt;br /&gt;
|- &lt;br /&gt;
|2||7,500,000 ||937,500 ||117,188 ||29,297 &lt;br /&gt;
|- &lt;br /&gt;
|3||3,750,000 ||468,750 ||58,594 ||14,648 &lt;br /&gt;
|- &lt;br /&gt;
|4||1,875,000 ||234,375 ||29,297 ||7,324 &lt;br /&gt;
|- &lt;br /&gt;
|5||937,500 ||117,188 ||14,648 ||3,662 &lt;br /&gt;
|- &lt;br /&gt;
|6||468,750 ||58,594 ||7,324 ||1,831 &lt;br /&gt;
  |- &lt;br /&gt;
|7||234,375 ||29,297 ||3,662 ||916 &lt;br /&gt;
|- &lt;br /&gt;
|8||117,188 ||14,648 ||1,831||458 &lt;br /&gt;
|- &lt;br /&gt;
|9||58,594 ||7,324 ||916 ||229 &lt;br /&gt;
|- &lt;br /&gt;
|10||29,297 ||3,662 ||458 ||114 &lt;br /&gt;
|- &lt;br /&gt;
|11||14,648 ||1,831 ||229||57 &lt;br /&gt;
|- &lt;br /&gt;
|12||7,324 ||916 ||114 ||29 &lt;br /&gt;
|- &lt;br /&gt;
|13||3,662 ||458 ||57 ||14 &lt;br /&gt;
|- &lt;br /&gt;
|14||1,831 ||229 ||29 ||7 &lt;br /&gt;
|- &lt;br /&gt;
|15||916 ||114 ||14 ||4 &lt;br /&gt;
|- &lt;br /&gt;
|16||458 ||57 ||7 ||2 &lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
====open()====&lt;br /&gt;
*A timer (either Timer 2 or 3) is needed to determine the pwm period. The following code uses timer 2 for all 8 channels.&lt;br /&gt;
  void pwm_open(void){&lt;br /&gt;
    OC1CON = 0;	OC2CON = 0; //Disable all output compare modules&lt;br /&gt;
    OC3CON = 0; OC4CON = 0;&lt;br /&gt;
    OC5CON = 0; OC6CON = 0;&lt;br /&gt;
    OC7CON = 0; OC8CON = 0;&lt;br /&gt;
    //============================================================&lt;br /&gt;
    TMR2 = 0;		// Clear register&lt;br /&gt;
    PR2 = 0xFFFF;	// Set to Maximum&lt;br /&gt;
    //============================================================&lt;br /&gt;
    _T2IP = 7;		// Set priority level to 7 (7 Highest)&lt;br /&gt;
    _T2IF = 0;		// Clear interrupt flag&lt;br /&gt;
    _T2IE = 1;		// Enable interrupts&lt;br /&gt;
    //============================================================&lt;br /&gt;
    T2CONbits.TCS = 0;		// Use internal clock source&lt;br /&gt;
    T2CONbits.TCKPS = 0;	// Prescale Select 1:1&lt;br /&gt;
    //============================================================&lt;br /&gt;
    T2CONbits.TON = 1;		// Start the timer 	&lt;br /&gt;
  }&lt;br /&gt;
  void _ISR _T2Interrupt(void){&lt;br /&gt;
    _T2IF = 0;			// Clear interrupt flag&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====ioctl()====&lt;br /&gt;
*User should select the channel and set the pwm period using the functions below before issuing the duty cycle:&lt;br /&gt;
  char pwm_ioctl(unsigned char request, unsigned long* argp){&lt;br /&gt;
    unsigned int value;&lt;br /&gt;
    unsigned char mask;&lt;br /&gt;
    switch(request){&lt;br /&gt;
      case PWM_SET_PERIOD:&lt;br /&gt;
        return setPeriodNPrescale(argp[0]);&lt;br /&gt;
      case PWM_SELECT_CH:&lt;br /&gt;
        pwm_channel = argp[0];&lt;br /&gt;
        mask = 0x01 &amp;lt;&amp;lt; pwm_channel;&lt;br /&gt;
        pwm_status = pwm_status | mask;&lt;br /&gt;
            return 0;&lt;br /&gt;
      default:&lt;br /&gt;
            return -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
  char setPeriodNPrescale(unsigned long value_ns){&lt;br /&gt;
    unsigned long ans;&lt;br /&gt;
    unsigned long long numerator = (unsigned long long)value_ns*SYSTEM_FREQ_MHZ;&lt;br /&gt;
    unsigned char index= -1;&lt;br /&gt;
    unsigned long denominator;&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    do{&lt;br /&gt;
        denominator = (unsigned long)1000*pwm_prescale[++index];&lt;br /&gt;
        ans = (unsigned long)(((long double)numerator/denominator) + 0.5) - 1; //rounding to nearest integer&lt;br /&gt;
    } while(ans &amp;gt; 0x0000FFFF &amp;amp;&amp;amp; index &amp;lt; 3);&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    if(ans &amp;gt; 0x0000FFFF)&lt;br /&gt;
        return -1;&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    T2CONbits.TON = 0;		// Turn off the timer&lt;br /&gt;
    T2CONbits.TCKPS = index;	// Change prescale factor&lt;br /&gt;
    PR2 = (unsigned int) ans;	// Set to Maximum&lt;br /&gt;
    T2CONbits.TON = 1;		// Turn on the timer 	&lt;br /&gt;
    //-------------------------------------------------&lt;br /&gt;
    return 0;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====write()====&lt;br /&gt;
*User can change the duty cycle using teh following functions&lt;br /&gt;
  int pwm_write(unsigned long* buf){&lt;br /&gt;
    if((pwm_status &amp;amp; (0x01 &amp;lt;&amp;lt; pwm_channel)) == 0){&lt;br /&gt;
        return -1;		//Channel has not been enabled&lt;br /&gt;
    }&lt;br /&gt;
    switch(pwm_channel){&lt;br /&gt;
        case 0:&lt;br /&gt;
            OC1RS = calcDCycle(buf[0]); OC1R = OC1RS; &lt;br /&gt;
            OC1CONbits.OCM = 6; //Simple PWM, Fault pin disabled&lt;br /&gt;
            break;&lt;br /&gt;
        case 1:&lt;br /&gt;
            OC2RS = calcDCycle(buf[0]);	OC2R = OC2RS; &lt;br /&gt;
            OC2CONbits.OCM = 6; //Simple PWM, Fault pin disabled&lt;br /&gt;
            break;&lt;br /&gt;
        ...&lt;br /&gt;
        case 7:&lt;br /&gt;
            OC8RS = calcDCycle(buf[0]); OC8R = OC8RS; &lt;br /&gt;
            OC8CONbits.OCM = 6; //Simple PWM, Fault pin disabled&lt;br /&gt;
            break;	&lt;br /&gt;
        default:&lt;br /&gt;
            return -1;&lt;br /&gt;
    }&lt;br /&gt;
    return 4;&lt;br /&gt;
 }&lt;br /&gt;
  unsigned int calcDCycle(unsigned long value_ns){&lt;br /&gt;
    unsigned long long numerator = (unsigned long long)value_ns*SYSTEM_FREQ_MHZ;&lt;br /&gt;
    unsigned int index = T2CONbits.TCKPS;&lt;br /&gt;
    unsigned long denominator = (unsigned long)1000*pwm_prescale[index];&lt;br /&gt;
    return (unsigned int)(((long double)numerator/denominator) + 0.5) - 1; //rounding to nearest integer&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
====Propagration Delay====&lt;br /&gt;
*PWM channels sharing the same timer will have their PWM signals synchronised (i.e. the HIGH state of the duty cycle are all triggered together).&lt;br /&gt;
*To introduced delay to the PWM signals, the signal from selected channels may be made to pass through a series of inverters (e.g. 74HC14D). This adds propagation delay to the signal.&lt;br /&gt;
*However, as propagration delay of logic gates depends on applied voltage, temperature and load capacitance, the accuracy is low and performance is poor. For accurate delay, delay lines may be used, but they are expensive.&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 6.4 Propagation Delay of [http://www.nxp.com/acrobat_download/datasheets/74HC_HCT14_3.pdf Philips 74HC14D]&amp;lt;sup&amp;gt;[1], [2]&amp;lt;/sup&amp;gt;&lt;br /&gt;
! !! 3.3V !! !! !! 5.0V !! !!&lt;br /&gt;
|- &lt;br /&gt;
! Number of Gates !! A !! B !! C !! A !! B !! C&lt;br /&gt;
|- &lt;br /&gt;
| 2 &lt;br /&gt;
| 21ns (10.5)|| 23ns (11.5)|| 22ns (11.0)&lt;br /&gt;
| 15ns (7.5)|| 14ns (7.0)|| 14ns (7.0)&lt;br /&gt;
|-&lt;br /&gt;
| 4 &lt;br /&gt;
| 45ns (11.3)|| 46ns (11.5)|| 46ns (11.5) &lt;br /&gt;
| 30ns (7.5)|| 30ns (7.5)|| 30ns (7.5)&lt;br /&gt;
|-&lt;br /&gt;
| 6 &lt;br /&gt;
| 69ns (11.5)|| 70ns (11.7)|| 72ns (12.0) &lt;br /&gt;
| 45ns (7.5)|| 46ns (7.7)|| 47ns (7.8)&lt;br /&gt;
|- &lt;br /&gt;
|}&lt;br /&gt;
[1] Data in specification for 4.5V: Typical 15ns, Maximum 25ns&amp;lt;br&amp;gt;&lt;br /&gt;
[2] Data in specification for 6.0V: Typical 12ns, Maximum 21ns&lt;br /&gt;
&lt;br /&gt;
===DSP Library===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Library functions in &amp;lt;dsp.h&amp;gt; include the following categories: &lt;br /&gt;
#Vector&lt;br /&gt;
#Window&lt;br /&gt;
#Matrix&lt;br /&gt;
#Filtering&lt;br /&gt;
#Transform&lt;br /&gt;
#Control&lt;br /&gt;
&lt;br /&gt;
====Data Types====&lt;br /&gt;
*Signed Fractional Value (1.15 data format)&lt;br /&gt;
**Inputs and outputs of the dsp functions adopt 1.15 data format, which consumes 16 bits to represent values between -1 to 1-2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt; inclusive.&lt;br /&gt;
**Bit&amp;lt;15&amp;gt; is a signed bit, positive = 0, negative = 1.&lt;br /&gt;
**Bit&amp;lt;14:0&amp;gt; are the exponent bits ''e''.&lt;br /&gt;
**Positive value = 1 - 2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;*(32768 - ''e'')&lt;br /&gt;
**Negative value = 0 - 2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;*(32768 - ''e'')&lt;br /&gt;
*40-bit Accumulator operations (9.31 data format)&lt;br /&gt;
**The dsp functions use the 40 bits accumalators during arithmatic calculations.&lt;br /&gt;
**Bit&amp;lt;39:31&amp;gt; are signed bits, positive = 0x000, negative = 0x1FF.&lt;br /&gt;
**Bit&amp;lt;30:0&amp;gt; are exponent bits.&lt;br /&gt;
*IEEE Floating Point Values&lt;br /&gt;
**Fractional values can be converted to Floating point values using: '''fo = Fract2Float(fr);''' for fr = [-1, 1-2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;]&lt;br /&gt;
**Floating point values can be converted to Fractional values using: '''fr = Float2Fract(fo);''' or '''fr = Q15(fo);''' for fo = [-1, 1-2&amp;lt;sup&amp;gt;-15&amp;lt;/sup&amp;gt;]&lt;br /&gt;
**Float2Fract() is same as Q15(), except having saturation control. When +ve &amp;gt;= 1, answer = 2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt;-1 = 32767 (0x7FFF). When -ve &amp;lt; -1, answer = -2&amp;lt;sup&amp;gt;15&amp;lt;/sup&amp;gt; = -32767 (0x8000)&lt;br /&gt;
&lt;br /&gt;
====Overflow and Saturation Traps====&lt;br /&gt;
*To be added.&lt;br /&gt;
&lt;br /&gt;
===Build-in Library===&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
*Some assembler operators can only be accessed by inline assembly code, for example, &lt;br /&gt;
#Manuipulation of accumulators A and B (add, sub, mul, divide, shift, clear, square)&lt;br /&gt;
#Bit toggling&lt;br /&gt;
#Access to psv (program space visiblity) page and offset&lt;br /&gt;
#Access to table instruction page and offset&lt;br /&gt;
*Built-in functions are written as C-like function calls to utilize these assembler operators.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Bootloader Development==&lt;br /&gt;
&lt;br /&gt;
===Concepts===&lt;br /&gt;
*Programming with ICSP is useful when the target board is produced in batch. The producer can download a program even when the chip is on the target board.&lt;br /&gt;
*However, ICSP requires an external programmer.&lt;br /&gt;
*To allow the user to change the program after production but without the need of an external programmer, bootloader becomes useful.&lt;br /&gt;
*Bootloader is a small program installed via ICSP. Everytime the device is reset, the bootloader is run first. The bootloader first detects the default serial channel whether the user wishes to download a new program to the device. If so, the bootloader will pause there, and wait for the user to download the hex file from the PC. The hex file is written to the device via RTSP instructions in the bootloader. If a new download is not necessary, the bootloader redirects to the previously installed user's program.&lt;br /&gt;
*The disadvantage of bootloaders is that they consume some of the memory of the device.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 7.1 Free bootloaders for dsPIC&lt;br /&gt;
! Developer&lt;br /&gt;
! Source&lt;br /&gt;
! Platform&lt;br /&gt;
! User Guide&lt;br /&gt;
! Remarks&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://www.ingenia-cat.com/index.php?lang=en ingenia]&lt;br /&gt;
| [http://www.ingenia-cat.com/download/iBL.s Assembly]&lt;br /&gt;
| [http://www.ingenia-cat.com/download/ingeniadsPICbootloader1.1.zip Windows]&lt;br /&gt;
| [http://www.ingenia-cat.com/reference/pdf/iBL.UG.V1.2.pdf pdf]&lt;br /&gt;
| &lt;br /&gt;
*Works for all dsPIC supporting RTSP&lt;br /&gt;
*Auto baudrate detection&lt;br /&gt;
*Use about 1.15% of the flash memory space (0xAFFF-0xAE00)/(0xAFFF-0x0100)&lt;br /&gt;
*Development of Linux platform is underway&lt;br /&gt;
*Modification of code for dsPIC30F5011 is successful&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm Tiny]&lt;br /&gt;
| [http://www.etc.ugal.ro/cchiculita/software/tinybld191.zip Assembly]&lt;br /&gt;
| Windows&lt;br /&gt;
| [http://www.etc.ugal.ro/cchiculita/software/tinybldusage.htm Web]&lt;br /&gt;
| &lt;br /&gt;
*By default, only supports 601X, 601X, 401X, 2010&lt;br /&gt;
*Smaller code size than ingenia, but not as easy to modify&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| [http://www.via.si/software/dsPIC_bootloader/ Elektronika]&lt;br /&gt;
| [http://www.via.si/software/dsPIC_bootloader/data/ Hex]&lt;br /&gt;
| Windows&lt;br /&gt;
| [http://www.via.si/software/dsPIC_bootloader/data/README.txt txt]&lt;br /&gt;
| &lt;br /&gt;
*Only works for dsPIC30F6014 serial port UART2 at baudrate 57600&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===dsPicBootloader===&lt;br /&gt;
&lt;br /&gt;
*The bootloader developed by ingenia is open source and it has been modified (see below) to suit our development using dsPic30f5011.&lt;br /&gt;
*The bootloader (hereafter called dsPicBootloader) employs the following settings:&lt;br /&gt;
# Use U2ART channel&lt;br /&gt;
# Use FRC, PLL16&lt;br /&gt;
# For 5011, the bootloader is located between 0x00AE00 to 0x00AFFE (512bytes). Refer to C:\Program Files\Ingenia\ingeniadsPICbootloader\ibl_dspiclist.xml after installing the GUI interface.&lt;br /&gt;
*Changes made to [http://www.ingenia-cat.com/download/iBL.s assembly code]  includes:&lt;br /&gt;
1. including p30f5011.gld and p30f5011.inc&lt;br /&gt;
        .include &amp;quot;p30f5011.inc&amp;quot;&lt;br /&gt;
2. changing the config code of UART #0x8420 -&amp;gt; #0x8020&lt;br /&gt;
        ; Uart init&lt;br /&gt;
        mov '''#0x8020''', W0           ; W0 = 0x8020 -&amp;gt; 1000 0000 0010 0000b&lt;br /&gt;
        mov W0, U2MODE            ; Enable UART, AutoBaud and 8N1&lt;br /&gt;
        clr U2STA&lt;br /&gt;
3. changing the start address 0xAE00 - 0x0100 = 0AD00&lt;br /&gt;
          .equ CRC, W4&lt;br /&gt;
          .equ ACK, 0x55&lt;br /&gt;
          .equ NACK, 0xFF&lt;br /&gt;
          .equ USER_ADDRESS, 0x0100&lt;br /&gt;
          .equ START_ADDRESS, '''0xAD00'''                ; Relative to 0x0100&lt;br /&gt;
4. using Internal FRC and PLL16&lt;br /&gt;
        config __FOSC, CSW_FSCM_OFF &amp;amp; '''FRC_PLL16''' ;Turn off clock switching and&lt;br /&gt;
                                           	;fail-safe clock monitoring and&lt;br /&gt;
                                            	;use the Internal Clock as the&lt;br /&gt;
                                           	;system clock&lt;br /&gt;
5. disabling MCLR (optional)&lt;br /&gt;
        config __FBORPOR, PBOR_ON &amp;amp; BORV_27 &amp;amp; PWRT_16 &amp;amp; '''MCLR_DIS'''&lt;br /&gt;
                                            ;Set Brown-out Reset voltage and&lt;br /&gt;
                                            ;and set Power-up Timer to 16msecs&lt;br /&gt;
6. changing all the related registers of U1ART to U2ART, all U1XXX =&amp;gt; U2XXX&lt;br /&gt;
        '''U2MODE, U2STA, U2BRG, U2RXREG, U2TXREG'''&lt;br /&gt;
7. changing all the related registers of IC1 to IC2, all IC1XXX =&amp;gt; IC2XXX&lt;br /&gt;
        '''IC2CON, #IC2IF, #IC2IE'''&lt;br /&gt;
&lt;br /&gt;
===dsPicProgrammer (Java-based Multi-Platformed)===&lt;br /&gt;
*Ingenia developed a programmer (PC-side) that works only in Windows environment. The project for Linux environment is currently suspended.&lt;br /&gt;
*A simple programmer (hereafter called dsPicProgrammer) written in Java based on the library developed by [http://www.rxtx.org/ RXTX] has been developed here. The programmer supports both Linux and Windows environments, and may be used as a substitution for the official programmer developed by ingenia.&lt;br /&gt;
*The programmer has the following specification and limitations:&lt;br /&gt;
#Use baud rate of 57600bps (Not selectable).&lt;br /&gt;
#Only program dsPic30f5011 devices (Developers may change the source code for your devices).&lt;br /&gt;
#Protection against overwriting bootloader codes on devices.&lt;br /&gt;
#Dectection if application program does not have its reset() at address 0x100.&lt;br /&gt;
&lt;br /&gt;
===Special Consideration===&lt;br /&gt;
*The bootloader assumes that the user program starts at address 0x100. This is usually the case, but there are always exceptions.&lt;br /&gt;
*To ensure that the user program always starts at address 0x100, you can create a customized linker script and customized reset() function as follows:&lt;br /&gt;
:*Copy and modify the file named &amp;quot;crt0.s&amp;quot; from the directory &amp;quot;C:\Program Files\Microchip\MPLAB C30\src\pic30&amp;quot; to the project directory and include it.&lt;br /&gt;
    .section .reset, code      //previously .section .libc, code &lt;br /&gt;
:*Copy and modify the linkerscript for the device (e.g. p30f5011.gld) to the project directory and include it.&lt;br /&gt;
   .text __CODE_BASE :&lt;br /&gt;
   {&lt;br /&gt;
      *(.reset);              //&amp;lt;-insert this line here&lt;br /&gt;
      *(.handle);&lt;br /&gt;
      *(.libc) *(.libm) *(.libdsp);  /* keep together in this order */&lt;br /&gt;
      *(.lib*);&lt;br /&gt;
      *(.text);&lt;br /&gt;
   } &amp;gt;program&lt;br /&gt;
&lt;br /&gt;
===Downloads===&lt;br /&gt;
{| border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 7.2 dsPicBootloader and dsPicProgrammer for dsPIC30f5011&lt;br /&gt;
! Program&lt;br /&gt;
! Site 1&lt;br /&gt;
! Site 2&lt;br /&gt;
! Remarks&lt;br /&gt;
|- valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| dsPicBootloader&lt;br /&gt;
| [http://chungyan5.no-ip.org/websvn/listing.php click]&lt;br /&gt;
| [http://www.opencircuits.com/images/e/ed/DsPicBootloader.zip click]&lt;br /&gt;
| Under &amp;quot;dsPicBootloader/&amp;quot;, download ingenia.s and compile yourself&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| dsPicProgrammer&lt;br /&gt;
| [http://chungyan5.no-ip.org/websvn/listing.php click]&lt;br /&gt;
| [http://www.opencircuits.com/images/1/13/DsPicProgrammer.zip click]&lt;br /&gt;
| Under &amp;quot;dsPicProgrammer/&amp;quot;, dowload dsPicProgrammer.jar&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Alternatively, if you want to compile yourself or modify the source code, download &amp;lt;br&amp;gt;COMDataHandler.java, COMPortManager.java, Pic5011Prog.java, Pic5011Protocol.java, &amp;lt;br&amp;gt;and WriteBuffer.java under &amp;quot;dsPicProgrammer/&amp;quot; '''plus''' RdFileIntelHex.java under &amp;lt;br&amp;gt;&amp;quot;IntelHexPaser/tags/0.02.00/&amp;quot;.&amp;lt;br&amp;gt;You should also install RXTX on your local machine as recommended in the readme file.&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Communication Protocol===&lt;br /&gt;
* Communication Protocol is reviewed in [http://www.ingenia-cat.com/reference/pdf/iBL.UG.V1.2.pdf ingenia bootloader user's guide] section 2.1.3. The following summarises the key steps on the PC side (Refer also to section 2.2.2).&lt;br /&gt;
* Transmission is conducted in 8N1, i.e. 8-bit, no parity, 1 stop-bit&lt;br /&gt;
* '''Stage 1: User's configuation'''&lt;br /&gt;
**Select a baudrate&lt;br /&gt;
**Select a COM port channel&lt;br /&gt;
* '''Stage 2: Autobaud rate detection and version control'''&lt;br /&gt;
**Continuously sending a character &amp;quot;U&amp;quot; [0x55] via COM port&lt;br /&gt;
**Continuously waiting for an acknowledgment character &amp;quot;U&amp;quot;, [ACK] = [0x55]&lt;br /&gt;
**Send command character [0x03]&lt;br /&gt;
**Receive 3 characters 1) Major Version 2) Minor Version 3) Acknowledgment [0x55]&lt;br /&gt;
**Prints the version number [Major.Minor] (e.g. 1.1) on screen.&lt;br /&gt;
* '''Stage 3: Loading and writing the program'''&lt;br /&gt;
**Load the user hex file, check integrity.&lt;br /&gt;
**Start loading file using:&lt;br /&gt;
***Read command character [0x01] + 24-bit address [High][Medium][Low]&lt;br /&gt;
***Receive 4-byte data [High][Medium][Low][ACK]&lt;br /&gt;
***Write command character [0x02] + 24-bit address [High][Medium][Low]+ Number of bytes [N] + [data 0] + [data 1] + ... + [data N-1] + [CRC]=(INTEL HEX8 Checksum - Sum modulo 256)&lt;br /&gt;
***Receive [ACK] or [NACK] = [0xFF]&lt;br /&gt;
***Note: Writing is in row mode access (i.e. erase and write a whole row, each row has 32 instructions, or 96 bytes because each instruction has 24 bits)&lt;br /&gt;
::# Ensure the initial address of writing match an initial row position,&lt;br /&gt;
::# Send the data corresponding to the whole row.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==USB-RS232 Bridge==&lt;br /&gt;
&lt;br /&gt;
*As USB ports are becoming more and more common, COM ports and Parallel ports may be redundant in the next few years. This section explore the possibilities of programming the target board through a USB port.&lt;br /&gt;
*There are two options:&lt;br /&gt;
#Use an external USB/RS232 adaptor, the driver will emulate a virtual COM port, such as [http://www.prolific.com.tw/eng/downloads.asp?ID=31 Prolific] and [http://www.ftdichip.com/Drivers/VCP.htm FDTI]. Ingenia has tested its bootloader with some USB-232 manufacturers (silabs, FTDI, etc..). However, the programming failed with our Prolific adapter. Application program may use [http://java.sun.com/products/javacomm/ JavaComm API] (javax.comm) and/or [http://www.rxtx.org/ RXTX] to drive the COM port.&lt;br /&gt;
#Modified the bootloader program on PC to support USB communication. e.g. using [http://jusb.sourceforge.net/ jUSB] and [http://javax-usb.org/ JSR-80] (javax.usb). External circuits such as PIC18F4550 and MAX232 are required.&lt;br /&gt;
&lt;br /&gt;
    |--User's App.--|-------Device Manager------|-------USB-RS232 Interface------|---dsPIC---|&lt;br /&gt;
   Option 1:&lt;br /&gt;
     +-------------+  +----------+  +----------+  +---+  +------------+  +-----+  +--------+&lt;br /&gt;
     | Application |--| JavaComm |--| Virtual  |==|USB|--|    FDTI    |--|RS232|==| Target |&lt;br /&gt;
     |   Program   |  |  RXTX    |  | COM Port |  +---+  | Circuitary |  +-----+  | Board  |&lt;br /&gt;
     +-------------+  +----------+  +----------+         +------------+           +--------+&lt;br /&gt;
   Option 2:&lt;br /&gt;
     +-------------+          +--------+          +---+  +------------+  +-----+  +--------+&lt;br /&gt;
     | Application |----------| JSR-80 |==========|USB|--| PIC18F4550 |--|RS232|==| Target |&lt;br /&gt;
     |   Program   |          |  jUSB  |          +---+  |   MAX232   |  +-----+  | Board  |&lt;br /&gt;
     +-------------+          +--------+                 +------------+           +--------+&lt;br /&gt;
&lt;br /&gt;
*Currently, when RXTX is incorporated with JavaComm API, operating systems supported include Linux, Windows, Mac OS, Solaris and other operating systems. On the other hand, jUSB and JSR-80 only works for linux.&lt;br /&gt;
&lt;br /&gt;
===FDTI Chipset===&lt;br /&gt;
*FT232RL communicates with PC via USB to provide 1 UART channel.&lt;br /&gt;
*Datasheet can be downloaded [http://www.ftdichip.com/Documents/DataSheets/DS_FT232R.pdf here]. &lt;br /&gt;
**Refer to Fig. 11 (Page 19) for Bus Powered Configuration.&lt;br /&gt;
**Refer to Fig. 16 (Page 24) for for UART TTL-level Receive [RXD -&amp;gt; 1], Transmit [TXD -&amp;gt; 4], Transmit Enable [CBUS2/TXDEN -&amp;gt; 3]. Omit Receive Enable [CBUS3/PWREN#] and use [CBUS2/TXDEN -&amp;gt; 2] &lt;br /&gt;
**Refer to Fig. 15 (Page 23) for LED Configuration: [CBUS0/TXLED#] and [CBUS1/RXLED#]&lt;br /&gt;
*Virtual COM Port Drivers can be downloaded [http://www.ftdichip.com/Drivers/VCP.htm here].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Programming the Device==&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
*Hardware&lt;br /&gt;
#PC with COM port (Windows XP Installed for MPLAB)&lt;br /&gt;
#ICD2 Programmer&lt;br /&gt;
#Target Board&lt;br /&gt;
#5V Power Supply&lt;br /&gt;
&lt;br /&gt;
*Software&lt;br /&gt;
#[http://ww1.microchip.com/downloads/en/DeviceDoc/MP750.zip MPLAB IDE v7.50 or higher]&lt;br /&gt;
#[http://chungyan5.no-ip.org/websvn/listing.php dsPicProgrammer] ('''dsPicProgrammer.jar''')&lt;br /&gt;
#[http://users.frii.com/jarvi/rxtx/download.html RXTX driver]&lt;br /&gt;
&lt;br /&gt;
*Files&lt;br /&gt;
#[http://chungyan5.no-ip.org/websvn/listing.php dsPicBootloader] ('''ingenia.hex'''). Original assembly code by ingenia can be downloaded from [http://www.ingenia-cat.com/download/iBL.s here].&lt;br /&gt;
#Application hex file (e.g. '''app.hex''')&lt;br /&gt;
&lt;br /&gt;
===Loading Bootloader (Once only)===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 9.1 Loading Bootloader&lt;br /&gt;
! Step !! Remarks &lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Install [http://ww1.microchip.com/downloads/en/DeviceDoc/MP750.zip MPLAB IDE] || &lt;br /&gt;
*Do '''NOT''' connect ICD 2 (via USB) to PC&lt;br /&gt;
*Execute '''MPLAB vX.XX Install.exe'''&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Install USB Driver ||&lt;br /&gt;
*Follow the instruction in (C:\Program Files\Microchip\MPLAB IDE\ICD2\Drivers\Ddicd2.htm)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Select Target Chip ||&lt;br /&gt;
*Run MPLAB IDE on PC&lt;br /&gt;
*Select: Configure&amp;gt;Select Devices...&lt;br /&gt;
*Choose dsPIC30F5011&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Target &amp;lt;-&amp;gt; ICD 2  ||&lt;br /&gt;
*Use six pin cable. Beware of the pin assignments. Only pin 1 - 5 should be used.&lt;br /&gt;
*Place Jumper on target board (if any). The Jumper connects target V&amp;lt;sub&amp;gt;cc&amp;lt;/sub&amp;gt; to ICD 2.&lt;br /&gt;
*Do '''NOT''' power-up the target.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| ICD 2 &amp;lt;-&amp;gt; PC ||&lt;br /&gt;
*Plug-in ICD 2 to PC via USB cable&lt;br /&gt;
*Power-up the target.&lt;br /&gt;
*Select: Programmer&amp;gt;Select Programmer&amp;gt;MPLAB ICD 2&lt;br /&gt;
*If this is the first time the ICD 2 is connected to PC, MPLAB IDE will automatically download the required OS to ICD 2, wait until it has finished&lt;br /&gt;
*If you have not connected and powered up the target, you might see Warnings on invalid device IDs, and/or running self tests.&lt;br /&gt;
*See results of self test if necessary: Programmer&amp;gt;Settings, Status Tab. Refer to [http://ww1.microchip.com/downloads/en/DeviceDoc/51331B.pdf ICD2 User's Guide] Chapter 7.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Load Bootloader ||&lt;br /&gt;
*Select: File&amp;gt;Import...&lt;br /&gt;
*Select '''ingenia.hex'''&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Start Programming ||&lt;br /&gt;
*Select: Programmer&amp;gt;Program&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Finishing ||&lt;br /&gt;
*Power-down the Taget&lt;br /&gt;
*Select: Programmer&amp;gt;Select Programmer&amp;gt;None&lt;br /&gt;
*Unplug USB cable&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Loading Application===&lt;br /&gt;
{|border=&amp;quot;1&amp;quot; cellspacing=&amp;quot;0&amp;quot; cellpadding=&amp;quot;5&amp;quot;&lt;br /&gt;
|+ Table 9.2 Loading Application File&lt;br /&gt;
! Step !! Remarks &lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Install RXTX ||&lt;br /&gt;
*For Windows User:&lt;br /&gt;
**copy RXTXcomm.jar to \jre\lib\ext (under java)&lt;br /&gt;
**copy rxtxSerial.dll to \jre\bin&lt;br /&gt;
*For Linux User:&lt;br /&gt;
**copy RXTXcomm.jar to /jre/lib/ext (under java)&lt;br /&gt;
**copy librxtxSerial.so to /jre/lib/[machine type] (i386 for instance)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Connect target board ||&lt;br /&gt;
*For Windows User:&lt;br /&gt;
**connect to COM1 (or other useable port)&lt;br /&gt;
*For Linux User:&lt;br /&gt;
**connect to ttyS0 (or other useable port)&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Open a console window ||&lt;br /&gt;
*In Windows, Start&amp;gt;Run, and type cmd.&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Start Programming ||&lt;br /&gt;
*Change to the directory containing dsPicProgrammer.jar&lt;br /&gt;
*Execute dsPicProgrammer.jar&lt;br /&gt;
**For Windows User: java -jar dsPicProgrammer.jar COMi Y:\foo2\app.hex&lt;br /&gt;
**For Linux User: java -jar dsPicProgrammer.jar /dev/ttySi Y:/foo2/app.hex&lt;br /&gt;
*Power-up target board&lt;br /&gt;
|-valign=&amp;quot;top&amp;quot;&lt;br /&gt;
| Finishing ||&lt;br /&gt;
*Power-down target board&lt;br /&gt;
*Disconnect from COM port&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Remote Access==&lt;br /&gt;
*At the moment, local devices (e.g. EEPROM, ADC, DAC, etc.) can only be accessed locally through POSIX functions such as open(), read(), write(), ioctl().&lt;br /&gt;
*However, a client may need to access these devices on a remote server. This section reviews the background and gives some ideas on its possible implementation.&lt;br /&gt;
&lt;br /&gt;
===Requirements===&lt;br /&gt;
*A remote file access protocol, to transfer &amp;quot;files&amp;quot; (i.e. device's data) such as:&lt;br /&gt;
#[http://en.wikipedia.org/wiki/FTP File Transfer Protocol] (FTP): Required files are copied from sever to client for manipulation&lt;br /&gt;
#[http://en.wikipedia.org/wiki/Remote_Shell Remote Shell] (RSH): Required files are copied from sever to client for manipulation&lt;br /&gt;
#[http://en.wikipedia.org/wiki/Network_File_System_%28Sun%29 Network File System] (NFS): Required files are manipulated on sever&lt;br /&gt;
*An API to access files using a selected protocol, such as:&lt;br /&gt;
#[http://www.die.net/doc/linux/man/man2/lam_rfposix.2.html lam_rfposix]: A POSIX-like remote file service for Local Area Multicomputer&lt;br /&gt;
#API employed by VxWorks: [http://en.wikipedia.org/wiki/VxWorks VxWorks] is a Unix-like real-time operating system, commonly used for embedded systems.&lt;br /&gt;
&lt;br /&gt;
===API Reference for VxWorks===&lt;br /&gt;
*Reference:&lt;br /&gt;
**[http://www.windriver.com/vxworks/ VxWorks Official Website]&lt;br /&gt;
**[http://www-cdfonline.fnal.gov/daq/commercial/ OS Libraries API Reference]&lt;br /&gt;
*Related Libraies&lt;br /&gt;
**netDrv (netDrv.h): an API using FTP or RSH&lt;br /&gt;
**nfsDrv (nfsDrv.h): an API using NFS&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==To Do List==&lt;br /&gt;
#Construct examples codes for using DSP library&lt;br /&gt;
#Construct examples codes for using Build-in library&lt;br /&gt;
#GUI Interface for Benchtop boards&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=Dead_bug_style&amp;diff=2768</id>
		<title>Dead bug style</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=Dead_bug_style&amp;diff=2768"/>
		<updated>2007-02-13T16:31:45Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: Expanding a stub&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;A method for prototyping high-speed circuits that helps to eliminate capacitive coupling.  The method gets its name from the idea that upside down IC's look like dead bugs with their legs sticking up in the air.&lt;br /&gt;
&lt;br /&gt;
When prototyping high-speed circuits, generally in the RF range (&amp;gt;1-2MHz), capacitive coupling between traces can lead to signal degradation.  The dead-bug style helps to eliminate this by building the traces in the air to maximize the distance and minimize the parallel runs that various leads travel with one another.  The dead-bug style also has the advantage of having a monolithic ground plane which helps to minimize circuit noise.&lt;br /&gt;
&lt;br /&gt;
The generic dead-bug style begins with a single-sided copper-clad PCB.  The IC's are glued upside-down to the surface of the copper cladding.  The circuit is wired up in the air above the IC's with ground connections bent over and tacked down to the ground plane.  Care must be taken with IC's that are in conductive packages (metal cans), that the metal portion is meant to be at ground potential, otherwise it must be isolated from the ground plane when gluing down.&lt;br /&gt;
&lt;br /&gt;
Shown below is a picture of a 10MHz amplifier that I built using this style of construction.  The PCB material used here was very thin and flexible and could even be cut with scissors.  Two thin strips were cut off and glued down to carry the positive and negative 15V.  RCA jacks were used to provide power because I had several laying around not earning their keep.&lt;br /&gt;
&lt;br /&gt;
[[Image:Dead_bug.jpg]]&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
	<entry>
		<id>http://www.opencircuits.com/index.php?title=File:Dead_bug.jpg&amp;diff=2767</id>
		<title>File:Dead bug.jpg</title>
		<link rel="alternate" type="text/html" href="http://www.opencircuits.com/index.php?title=File:Dead_bug.jpg&amp;diff=2767"/>
		<updated>2007-02-13T16:29:12Z</updated>

		<summary type="html">&lt;p&gt;Mdwebster: 10MHz amplifier with DC offset built in dead-bug fashion&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;10MHz amplifier with DC offset built in dead-bug fashion&lt;/div&gt;</summary>
		<author><name>Mdwebster</name></author>
		
	</entry>
</feed>