<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Frank&#039;s Random Wanderings &#187; Computers</title>
	<atom:link href="http://blog.frankvh.com/category/computers/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.frankvh.com</link>
	<description>A bunch of random musings, with a leaning towards electronics &#38; computers.</description>
	<lastBuildDate>Sat, 14 Jan 2012 00:40:17 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>If Apple Wins We All Lose</title>
		<link>http://blog.frankvh.com/2011/12/20/if-apple-wins-we-all-lose/</link>
		<comments>http://blog.frankvh.com/2011/12/20/if-apple-wins-we-all-lose/#comments</comments>
		<pubDate>Wed, 21 Dec 2011 06:23:58 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=617</guid>
		<description><![CDATA[I&#8217;m not generally one to repost articles and links to articles &#8211; you won&#8217;t find much of that on my blog. Nor am I particularly pro-this or anti-that when it comes to technologies, brands, companies, etc. I have Apple products and non-Apple products. I&#8217;ve used various flavours of Mac OS, of DOS, of Windows, of [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m not generally one to repost articles and links to articles &#8211; you won&#8217;t find much of that on my blog. Nor am I particularly pro-this or anti-that when it comes to technologies, brands, companies, etc. I have Apple products and non-Apple products. I&#8217;ve used various flavours of Mac OS, of DOS, of Windows, of Unix, of Linux, and much more. It&#8217;s all good to me.</p>
<p>However, I&#8217;m not agnostic when it comes to the on-going development of technology. I&#8217;ve been in this business long enough to realise that every new development builds upon the back of some new development before it. Like kicking steps up a snowbank, making each new step upwards requires you to stand in the step you&#8217;ve got. That&#8217;s the way innovation and technology develops, and it&#8217;s critical for everyone that this is able to continue.</p>
<p><a href="http://gizmodo.com/5869598/if-apple-wins-we-all-lose">Gizmodo recently posted this article:</a></p>
<blockquote><p>
If Apple Wins We All Lose</p>
<p>Yesterday&#8217;s news that courts had ruled against HTC in favor of Apple was a tidy little victory for Apple. But HTC is just an initial skirmish in a much larger fight. The real war is against Android, and if Apple wins that, we&#8217;ll all lose&#8230;
</p></blockquote>
<p><a href="http://gizmodo.com/5869598/if-apple-wins-we-all-lose">It&#8217;s well worth the read.</a> Many patent systems and legal systems around the world are increasingly allowing existing &#8220;technology holders&#8221; to supress and quash the development of new evolutionary technologies. The USA is the most obvious example of this, but it&#8217;s certainly not the only one. And the trends indicate this problem is getting worse &#8211; not better. Truely, when it comes to anti-competitive behaviour and legal policies, this is an area where indeed, &#8220;we all lose&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2011/12/20/if-apple-wins-we-all-lose/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Do It Yourself Signal Generator Probe</title>
		<link>http://blog.frankvh.com/2011/10/02/do-it-yourself-signal-generator-probe/</link>
		<comments>http://blog.frankvh.com/2011/10/02/do-it-yourself-signal-generator-probe/#comments</comments>
		<pubDate>Sun, 02 Oct 2011 18:56:51 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=536</guid>
		<description><![CDATA[Some time ago I built a signal generator, which is a reasonably handy bit of equipment. But I was periodically frustrated with not having a suitable probe to easily inject a signal into a circuit. The standard BNC &#8211; BNC cable has its uses, but isn&#8217;t too great for that kind of thing. And a [...]]]></description>
			<content:encoded><![CDATA[<p>Some time ago I <a href="http://www.frankvh.com/dds-signal-generator.html" target="_blank">built a signal generator</a>, which is a reasonably handy bit of equipment. But I was periodically frustrated with not having a suitable probe to easily inject a signal into a circuit. The standard BNC &#8211; BNC cable has its uses, but isn&#8217;t too great for that kind of thing. And a dangling bit of wire causes nothing but troubles.</p>
<p>What I really wanted was an oscilloscope probe. Scope probes have a nice sharp tip on them, they have a ground lead with a clip, they even have a hooky tip for grabbing onto things. Scope probes are great. But some experiments proved that a scope probe makes a terrible signal generator cable, because scope probes contain resistor-divider circuits, trimmer capacitors, etc, which get in the way of the signal generator output.</p>
<p>So I decided to hack a scope probe, to build a signal generator cable  / probe. From <a href="http://www.dealextreme.com" target="_blank">DealExtreme</a> I ordered a cheap oscilloscope probe &#8211; their SKU 32422 for a big $6. About three weeks later it landed in my mailbox. I quickly found it can easily be taken apart. Like so:</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2011/10/probe-far.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/10/probe-far.jpg" alt="Oscilloscope probe disassembled" title="probe-far" width="640" height="140" class="aligncenter size-full wp-image-539" /></a><br />
The strain relief (on the left of the photo) can simply be pulled off. That holds the little square box covering the PCB in place &#8211; with the strain relief gone the cover now slides off as well. A minute of quality time with the soldering iron removes the resistors and trimmer capacitor on the PCB (done before I took these photos), then I soldered a wire across the middle of the PCB to connect the BNC connector back to the centre of the cable. Here&#8217;s a close-up:</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2011/10/probe-close.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/10/probe-close.jpg" alt="hacked oscilloscope probe" title="probe-close" width="640" height="270" class="aligncenter size-full wp-image-542" /></a></p>
<p>Then the PCB cover and strain relief were slipped back into place, and the X1/X10 switch on the probe handle was placed in the X1 position, then wrapped in tape to make sure it couldn&#8217;t be accidently switched to X10. When the switch is in the X10 position a big resistor is switched in series with the tip &#8211; don&#8217;t want that! Finally I stuck a label on the probe so I won&#8217;t confuse it with the regular scope probes. Done! </p>
<p>This is awesome. For a few dollars and maybe 10 minutes work we get a nice signal generator probe complete with sharp tip, hooky tip, ground lead, etc. Can&#8217;t beat that.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2011/10/02/do-it-yourself-signal-generator-probe/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Class 10 SD Card &#8211; Or Not?</title>
		<link>http://blog.frankvh.com/2011/09/11/class-10-sd-card-or-not/</link>
		<comments>http://blog.frankvh.com/2011/09/11/class-10-sd-card-or-not/#comments</comments>
		<pubDate>Sun, 11 Sep 2011 23:05:38 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=522</guid>
		<description><![CDATA[Recently I purchased a Class 10 SD Card from a major retailer. I was very excited &#8211; now I have a fast card for testing. Here&#8217;s my new baby:

Note the 10 in the part-circle indicating the speed. For those who don&#8217;t know, the &#8220;class&#8221; speed system for SD cards is very simple. It&#8217;s the write [...]]]></description>
			<content:encoded><![CDATA[<p>Recently I purchased a Class 10 SD Card from a major retailer. I was very excited &#8211; now I have a fast card for testing. Here&#8217;s my new baby:</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2011/09/duracell_sd.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/09/duracell_sd.jpg" alt="" title="duracell_sd" width="317" height="400" class="aligncenter size-full wp-image-523" /></a></p>
<p>Note the 10 in the part-circle indicating the speed. For those who don&#8217;t know, the &#8220;class&#8221; speed system for SD cards is very simple. It&#8217;s the write speed, in MB/s (megabytes per second). So a class 4 card can be written to at 4 MB/s, a class 6 at 6 MB/s etc. So yes, a class 10 could be written to at 10 MB/s.</p>
<p>And it worked really well for small files, but when writing large files it would sometimes slow down. Some investigation produced the following oscilloscope screen capture:</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2011/09/sd_busy_duracell_class10.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/09/sd_busy_duracell_class10.jpg" alt="" title="sd_busy_duracell_class10" width="640" height="480" class="aligncenter size-full wp-image-524" /></a></p>
<p>What you&#8217;re seeing is the card crying out, &#8220;I&#8217;m Busy!&#8221; for extended periods of time. The top (purple) trace is a trigger pulse. The middle (yellow) trace is the CMD line, and the bottom (green) trace is the DATA0 line. SD cards hold their DATA0 line low when they&#8217;re busy; this is how they tell you to wait. I was seeing this Duracell SD card pull busy for up to 250 ms at a time. It seems to me it&#8217;d be real tough to sustain 10 MB/s writes to the card, if the card is busy a quarter of a second at a time, every few seconds.</p>
<p>So I wrote to Duracell tech support (yes, they really do have one), and they replied, &#8216;Thanks very much &#8211; we&#8217;ll look into it.&#8221; </p>
<p>Most interestingly, I&#8217;m pretty sure I read somewhere that the SD Card spec actually allows for these long &#8220;busy&#8221; periods to happen. So a card can actually do this, yet remain compliant with the spec. That can make life hard for a user of the card however.</p>
<p>I have a pretty good collection of SD cards, so I started looking at a bunch of them, comparing their labels to what the internal card register says. Almost all cards had the label agree with the register. But I did find an interesting &#8220;happy&#8221; exception. A Lexar &#8220;class 4&#8243; card actually read as a class 6. And for large file sizes, this Lexar &#8220;class 4&#8243; card actually outperforms the &#8220;class 10&#8243; Duracell. Like the Duracell. the Lexar also asserts busy from time to time. But the Lexar busy durations are far shorter than the Duracell &#8211; a maximum of around 80 ms, compared to a quarter of a second for the Duracell. Making the Lexar much easier to deal with from a file-writing perspective.</p>
<p>How about that hey? A Lexar &#8220;class 4&#8243; card outperforming a Duracell &#8220;class 10&#8243; SD card. When it comes to SD cards, things aren&#8217;t always as they seem. And sometimes it really is worth paying the extra money for the top-brand cards.</p>
<p><strong>Update 27 Sept 2011:</strong> I&#8217;ve done a bunch more testing on my various cards and I&#8217;ve managed to write to this particular Duracell card at 9 MB/s. Pretty darn close to a &#8220;class 10&#8243; card if you ask me (and I might yet be able to write faster still). How? By writing a 32 MB block of data consecutively to the card without any filesystem &#8211; just a raw data write as fast as possible. This highlights an important consideration with SD cards &#8211; the write speed really is affected by the amount of data you write. With a filesystem on the card, writing one 32 kB cluster at a time, the &#8220;write plus programming time&#8221; gets pretty slow. To hit the big write-speed numbers you really need to find a way to write much larger blocks of data at a time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2011/09/11/class-10-sd-card-or-not/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>STM32F2xx Digital Camera Interface (DCMI)</title>
		<link>http://blog.frankvh.com/2011/08/19/stm32f2xx-digital-camera-interface-dcmi/</link>
		<comments>http://blog.frankvh.com/2011/08/19/stm32f2xx-digital-camera-interface-dcmi/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 20:10:20 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[STM32]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=469</guid>
		<description><![CDATA[I’m using the STM32F2xx DCMI port to receive data from an CMOS image sensor. There aren&#8217;t too many Cortex-M3 or M4 parts which have this ability natively; the STM32F2xx is a rare breed. It&#8217;s a very nice feature. Along the way I’ve learnt a few things about the DCMI port, some of which are documented, [...]]]></description>
			<content:encoded><![CDATA[<p>I’m using the STM32F2xx DCMI port to receive data from an CMOS image sensor. There aren&#8217;t too many Cortex-M3 or M4 parts which have this ability natively; the STM32F2xx is a rare breed. It&#8217;s a very nice feature. Along the way I’ve learnt a few things about the DCMI port, some of which are documented, some of which are not.</p>
<p><strong>DCMI Interrupt Only At Frame End</strong></p>
<p>There’s no way to get a DCMI interrupt at the start of a frame. If you need that, route the image sensor’s frame sync pin to a processor GPIO pin, and generate a GPIO interrupt on the rising or falling edge as appropriate.</p>
<p><strong>Data Count Register</strong></p>
<p>One of the things you notice once you start trying to use the DCMI port is that it doesn’t have a simple “data count” register. The way the DCMI port works, is it receives data from an external source and puts it into a small FIFO, which then gets fed to the STM32F2xx DMA controller. For some data types you know exactly how much data you’re going to receive; for other types (particularly jpeg data) you have no idea. But you always need to know how much you have received, and with the DCMI there’s no easy way to know. It’s a surprisingly difficult problem to solve, particularly when you start inserting other things into your image data buffers (like image file headers and the like). When I queried ST tech support about this, they suggested setting things up so an interrupt was generated every time a byte was received. Can you imagine 4 million interrupts a second? </p>
<p>I ended up writing some code to count with the help of the DMA controller. The DMA doesn’t have a “data count up” register either, however it does have a “data count down” register, the NDTR. It gets tricky when you’re using the double-buffer or circular-buffer modes of the DMA controller, because the NDTR register is automatically reloaded by hardware. But with enough puzzling, thinking, head-scratching and experimenting it can be done. Although it’s only accurate to multiples of 4 bytes – see the “zero padding” discussion below.</p>
<p>Ideally I’d like to see ST add a simple “data count” register to the DCMI port, but I’m guessing it probably won&#8217;t happen for these parts.</p>
<p><strong>Zero Padding</strong></p>
<p>Talking about JPEG mode, there’s a nasty little “gotcha” in the DCMI port that the documentation does mention in the “JPEG Format” section, but I’ll re-iterate it here. It very much ties in to the lack of a data count register mentioned earlier.</p>
<p>If the amount of data received in a frame is not a multiple of 4 bytes, the DCMI will pad out the end of the frame to a multiple of 4 bytes by inserting zeros. For example, if your frame is 1001 bytes long, you’ll receive from the DCMI port 1004 bytes, consisting of 1001 bytes of “real” data, followed by 3 bytes of zeros.</p>
<p>And therein lies the rub. If you (a) don’t know how many bytes you’re expecting to receive, and (b) don’t know how many bytes were actually received by the DCMI port because it doesn’t have a data count register, then how do you know whether those 3 bytes at the end are padding zeros, or “real data” zeros? In short, you don’t know, there’s no way to tell. You need to consider this, and decide whether or not it might be a problem in your application.</p>
<p>Strangely enough, the DCMI documentation only mentions this zero padding for the JPEG mode, however I would assume (and it’s only an assumption – not confirmed with ST) that this zero padding would occur in the other capture modes as well.</p>
<p><strong>Control Signals Polarity</strong></p>
<p>The documentation is remarkably confusing on this point. If a control signal (eg vsync) is active-high, what DCMI setting is required for that? It&#8217;s a bit too difficult to explain, so here&#8217;s a repost of a code snippet I posted on the STM32F forum for exactly that question.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">// DCMI configuration</span>
<span style="color: #666666; font-style: italic;">// For the image sensor, vsync is &quot;frame sync&quot; and is high when the sensor is transmitting an image.</span>
<span style="color: #666666; font-style: italic;">// hsync is &quot;line sync&quot; and is high when the sensor is transmitting data, low when it's not. It</span>
<span style="color: #666666; font-style: italic;">// will go high and low many times during a frame. The sensor outputs data on the falling edge</span>
<span style="color: #666666; font-style: italic;">// of the clock, hence this processor must clock data in on the rising edge of the clock.</span>
<span style="color: #666666; font-style: italic;">// Note: the F2xx datasheet is incredibly confusing regard V &amp; Hsync polarity. &quot;Polarity_Low&quot; here</span>
<span style="color: #666666; font-style: italic;">// means the DCMI_CR register bit VSPOL/HSPOL is clear, which means the CPU interprets a logic-1 (high)</span>
<span style="color: #666666; font-style: italic;">// sync as meaning &quot;valid data available&quot;. Makes no sense I know, but the processor logic is inverted</span>
<span style="color: #666666; font-style: italic;">// from what you'd expect. Tell it zero, it grabs on a 1.</span>
&nbsp;
DCMI_InitStructure.<span style="color: #202020;">DCMI_CaptureMode</span> <span style="color: #339933;">=</span> DCMI_CaptureMode_Continuous<span style="color: #339933;">;</span>  <span style="color: #666666; font-style: italic;">// repeatedly process frames</span>
DCMI_InitStructure.<span style="color: #202020;">DCMI_SynchroMode</span> <span style="color: #339933;">=</span> DCMI_SynchroMode_Hardware<span style="color: #339933;">;</span>
DCMI_InitStructure.<span style="color: #202020;">DCMI_PCKPolarity</span> <span style="color: #339933;">=</span> DCMI_PCKPolarity_Rising<span style="color: #339933;">;</span>      <span style="color: #666666; font-style: italic;">// read data on clk rising edge</span>
DCMI_InitStructure.<span style="color: #202020;">DCMI_VSPolarity</span> <span style="color: #339933;">=</span> DCMI_VSPolarity_Low<span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// data valid on vsync high</span>
DCMI_InitStructure.<span style="color: #202020;">DCMI_HSPolarity</span> <span style="color: #339933;">=</span> DCMI_HSPolarity_Low<span style="color: #339933;">;</span>           <span style="color: #666666; font-style: italic;">// data valid on hsync high</span>
DCMI_InitStructure.<span style="color: #202020;">DCMI_CaptureRate</span> <span style="color: #339933;">=</span> DCMI_CaptureRate_All_Frame<span style="color: #339933;">;</span>
DCMI_InitStructure.<span style="color: #202020;">DCMI_ExtendedDataMode</span> <span style="color: #339933;">=</span> DCMI_ExtendedDataMode_8b<span style="color: #339933;">;</span>
DCMI_Init<span style="color: #009900;">&#40;</span><span style="color: #339933;">&amp;</span>DCMI_InitStructure<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
DCMI_JPEGCmd <span style="color: #009900;">&#40;</span>ENABLE<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>                            <span style="color: #666666; font-style: italic;">// enable DCMI JPEG mode</span></pre></div></div>

<p>Hopefully this will help. As a bonus this code snippet shows how to enable the DCMI JPEG mode.</p>
<p><strong>Unexpected &#8220;Frame Skipping&#8221; in Continuous Mode</strong></p>
<p>The STM32F2xx DCMI control register DCMI_CR contains a couple of bits called FCRC to select which frames are grabbed. Clearing the bits means “grab all frames”, which is how I use the port.</p>
<p>However, I’ve found that despite this, the DCMI can appear to “skip frames”. Take a look at the following two oscilloscope captures. The top trace is a GPIO pin toggled at the start of the DCMI interrupt service routine. The middle trace is the image sensor frame sync pin, and the bottom trace is the image sensor clock pin. As you can plainly see, the first screenshot shows the DCMI triggering on every frame (as expected), where the second screenshot shows the DCMI triggering on every second frame (as you’d certainly not expect).</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2011/08/dcmi_cap_all_frms.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/08/dcmi_cap_all_frms.jpg" alt="DCMI Capture All Frames" title="dcmi_cap_all_frms" width="640" height="480" class="aligncenter size-full wp-image-472" /></a></p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2011/08/dcmi_cap_half_frms.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/08/dcmi_cap_half_frms.jpg" alt="DCMI Skipping Frames" title="dcmi_cap_half_frms" width="640" height="480" class="aligncenter size-full wp-image-473" /></a></p>
<p>The difference between these two is a DCMI FIFO overflow. In the case of the first screenshot, the DMA controller is always taking the received data from the DCMI, so the DCMI internal FIFO never overflows. In the second case, the DMA is being turned off halfway through the frame, every second frame. This causes the STM32F2xx DCMI port FIFO to overflow and generate a DCMI error, badly enough to prevent it from generating an “end of frame” interrupt at the end of that frame. However it resets itself at the start of the next frame, which allows it to capture and complete the next frame normally. Then for the subsequent frame the DMA is turned off partway through and the cycle repeats itself.</p>
<p>This was rather unexpected. It seemed like a good idea, turning off the DMA controller once the necessary data was received to save on internal bus bandwidth. However it appears the DCMI peripheral doesn’t like this idea so much, because it doesn’t generate IT_FRAME interrupts properly when this happens. I have not yet had this DCMI behavior confirmed by ST, however it is clear and repeatable on my hardware. I will update this post if I receive any information from ST.</p>
<p>Depending upon the application, losing the IT_FRAME interrupt at the end of a corrupted or overflow frame may, or may not, be a problem. One way to work around this (ahem) “undocumented feature” is to also route the frame sync signal to a GPIO pin, and have the GPIO pin generate an interrupt at the end of each frame. That way you’re guaranteed a GPIO interrupt at the completion of every frame, even if you don’t receive the DCMI IT_FRAME interrupt.</p>
<p><strong>STM32F2xx DCMI Overflow</strong></p>
<p>In my working with the DCMI port I’ve found some other DCMI-overflow related behavior that’s worth mentioning, even though I can’t explain it entirely clearly.</p>
<p>In the second screenshot above, we see IT_FRAME interrupts being missed due to a periodic DCMI overflow, which in turn is caused by software turning off the DCMI’s DMA controller.</p>
<p>The DCMI port can generate an overflow interrupt, called IT_OVR. I tried enabling this interrupt, to see if I would get this interrupt for those frames which are missing the IT_FRAME interrupt. Turning on the IT_OVR interrupt (by setting the OVR_IE bit in the DCMI_IER register) was actually a bit of a disaster – I no longer received any IT_FRAME interrupts at all, and the DCMI port stopped receiving data. It effectively killed the system.</p>
<p>The behavior I saw was this. With both the FRAME and OVR interrupts enabled, initially (after powerup) the DCMI port worked fine, receiving data and passing it to the DMA. After 20 or 30 frames of data I triggered an overflow by momentarily turning off the DMA controller. This resulted in the IT_ OVR interrupt occuring and no IT_FRAME interrupt taking place. I expected this state of affairs to be brief. In fact what happened was the IT_OVR interrupt triggered continuously after that point, and the IT_FRAME never triggered again. Nothing I could dream up would clear the OVR overflow error – it always error’ed again on the next frame, and the next, etc. Even turning off the DCMI port and re-enabling it didn’t cure the problem. It took a reset of the STM32F2xx to have the DCMI port working normally again. This behavior happened even if the OVR interrupt service routine did nothing at all &#8211; not even clear the interrupt. Somehow, enabling that OVR interrupt causes the DCMI to behave differently than leaving that interrupt disabled.</p>
<p>I can’t rule out that there was something I was doing wrong, or strange. But for identical incoming DCMI data, if I didn’t enable the OVR interrupt, the DCMI port would recover from an overflow. But if I did enable the OVR interrupt, once an overflow occurred, the DCMI port appeared broken forever. Very strange.</p>
<p>For this reason, obviously, I don’t enable the OVR overflow interrupt – I simply pretend it doesn’t exist.</p>
<p>Other testing I performed, reading the status of the overflow bit in the DCMI port, indicated that the port seems to be tolerant of a certain amount of overflow. Either that or it’s a bit quick to set the flag. I found that even during normal DCMI operation, with the port receiving data and everything apparently going perfectly, the OVR bit could become set. But the DCMI port seemed to ignore it and just continue. I never saw any data corruption or missed data despite the bit being set. Of course forcing a “real” overflow, by momentarily disabling the DMA controller, would also set the OVR flag and in addition would usually cause the IT_FRAME for that particular frame to be skipped. But the subsequent frame would be OK again.</p>
<p>Long story short: don’t enable the overflow interrupt. And if you do, test it (by generating some overflows) very carefully to ensure you don’t end up in some apparently unrecoverable state.</p>
<p>That’s it for the DCMI  – the next post will talk about the STM32F2xx SDIO SD Card interface.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2011/08/19/stm32f2xx-digital-camera-interface-dcmi/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>STM32F2xx DMA Controllers</title>
		<link>http://blog.frankvh.com/2011/08/18/stm32f2xx-dma-controllers/</link>
		<comments>http://blog.frankvh.com/2011/08/18/stm32f2xx-dma-controllers/#comments</comments>
		<pubDate>Thu, 18 Aug 2011 15:01:17 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[STM32]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=458</guid>
		<description><![CDATA[If you’re moving a bunch of data around, the DMA controllers are going to be your best friends. However they have their quirks and undocumented features. This post will describe what I’ve learned about them, and hopefully others can contribute if they can shed light as well.
Note there is also a Part 2 to this [...]]]></description>
			<content:encoded><![CDATA[<p>If you’re moving a bunch of data around, the DMA controllers are going to be your best friends. However they have their quirks and undocumented features. This post will describe what I’ve learned about them, and hopefully others can contribute if they can shed light as well.</p>
<p>Note there is also a <a href="http://blog.frankvh.com/2011/11/21/stm32f2xx-dma-controllers-part-2/" target="_blank">Part 2</a> to this post.</p>
<p><strong>FIFOs</strong></p>
<p>The DMA controller contains a bunch of small FIFOs, one for each stream. You don’t need to use them (well, sometimes you do, but usually it’s optional) however you’d be a bit crazy not to. The FIFOs allow the DMA to function without losing data if something else with a higher priority is using the bus. But the FIFOs do introduce complexities, as we shall soon see.</p>
<p><strong>DMA Configuration Register</strong></p>
<p>A number of bits in the configuration register (eg channel selection) are marked: “These bits are protected and can be written only if EN is ‘0’ “. What does that mean? The register defaults to zero. If I want to set these bits and enable the DMA controller, do I need to perform two writes: one to set these bits while keeping EN = 0. Then a second write which only sets EN = 1?</p>
<p>The short answer is “yes”, you should do two writes to the configuration register to enable the DMA. My experiments seem to indicate that performing a single write the configuration register, setting those bits AND setting EN = 1 in one hit, appears to work. But that’s not guaranteed, and ST tech support recommends performing two writes.</p>
<p><strong>Start Me Up</strong></p>
<p>Configuring the various STM32F2xx DMA registers and setting EN = 1 should cause the DMA to start. Imagine my surprise then, when the DMA worked the first time, but not the second.</p>
<p>From performing some experiments I discovered, and ST subsequently confirmed, that the DMA stream will NOT start up if its interrupt status bits are set. This is not described in the current documentation. Even if you’re not using interrupts, you MUST clear the appropriate bits in the DMA Interrupt Flag Clear register. I don’t know which bit in particular the hardware cares about, so I just clear them all for that stream.</p>
<p><strong>Reading DMA Registers</strong></p>
<p>This wasn’t obvious to me from the documentation: the address registers (M0AR and M1AR) do not change during the course of a DMA transfer. For example, in the documentation, for the configuration register MINC bit, it states:</p>
<blockquote><p>Memory address pointer is incremented after each data transfer (increment is done according to MSIZE)</p></blockquote>
<p>Certainly sounds like the address register would increment, doesn’t it? In fact they do not. What actually happens is when the DMA starts up (or restarts in the case of circular or double-buffer mode) the address register(s) are copied to internal shadow registers that we lowly programmers cannot see. It’s the shadow address registers which increment during a DMA; not the visible M0AR / M1AR registers. M0AR and M1AR remain unaltered during the DMA.</p>
<p>This is an important point. If you think you can simply read the value of M0AR at the completion of a DMA to determine where the DMA stopped writing, for example, that won’t work. M0AR will still be pointing to the beginning of your data buffer.</p>
<p>NTDR does decrement though – you can read this register (at any time) to see where the DMA controller is.</p>
<p><strong>Circular Mode</strong></p>
<p> The documentation for circular mode is pretty skimpy. It says: </p>
<blockquote><p>When the circular mode is activated, the number of data items to be transferred is automatically reloaded with the initial value programmed during the stream configuration phase, and the DMA requests continue to be served.</p></blockquote>
<p>This tells us the NDTR register is reloaded once it falls to zero, in the same manner as the double-buffer mode. What about everything else? I asked ST tech support a bunch of questions and here’s what I learned.</p>
<p>M0AR is the address register used for circular mode (M1AR is only used for double-buffer mode and nothing else). When circular mode is enabled, once NDTR counts down to zero, the following takes place:</p>
<ul>
<li>The TCIF flag is set (which can generate an interrupt if enabled)</li>
<li>The “M0AR shadow register” is reloaded to its initial (M0AR) value, so the DMA will continue writing at the start of the buffer once again</li>
<li>NDTR is reloaded to its initial value</li>
</ul>
<p>In short, the DMA will keep writing to the same buffer, over and over again, triggering an interrupt each time it fills the buffer, and it’ll do this forever until its disabled (usually by software writing to the DMA configuration register).</p>
<p>As noted before, you’ll never see the value of the M0AR register change so don’t bother trying, however you will see the NDTR register decrement as the DMA proceeds to write the buffer.</p>
<p><strong>Double-Buffer Mode</strong></p>
<p>This is simply a variant of Circular Mode, where two address pointers M0AR and M1AR are used instead of one, and the SMT32F2xx DMA reloads them alternately, each time NDTR counts down to zero. So the DMA fills buffer 0, then buffer 1, then buffer 0, then buffer 1, etc, for example. The really nice thing about this mode is you’re permitted to update the not-currently-in-use address register, on the fly. Which means you can extend this mode to as many buffers as you wish, by changing the inactive register. The CT bit in the DMA configuration register tells you which address register is currently in use; you’re free to update the other register to point to a new buffer.</p>
<p><strong>Burst Mode</strong></p>
<p>It states this in the documentation, but just to re-iterate: If you’re using the DMA in burst mode (for example allow the FIFO to fill with 16 bytes / 4 words, then write the whole FIFO to memory in one burst) which is the most efficient method, be aware that your buffer needs to be aligned on a 1kB address boundary. If its not, if the burst straddles a 1kB boundary, it’ll generate an AHB bus error.</p>
<p><strong>Flow Controller</strong></p>
<p>The documentation is very clear about this, still I’ve seen it pop up on the forums. In almost all cases the DMA will itself be the DMA flow controller. The only possible exception is the STM32F2xx SDIO port (for which you have the option).</p>
<p><strong>STM32F2xx FIFO Flush</strong></p>
<p>I found this topic to be very confusing, primarily because the documentation mentions it very briefly, and that very briefness (is “briefness” even a word?) led to a number of misconceptions which took some time to iron out with ST tech support. Hopefully the following section will help clarify things.</p>
<p>In an “ideal” DMA operation, you would specify the amount of data to be transferred in the NDTR register, specify things like burst mode (or not), FIFO fullness, etc, and start the DMA running. Ideally everything would be a neat multiple of everything else; for example you set a FIFO threshold of “FIFO full” (16 bytes) and your data quantity is a multiple of 16 bytes.  The DMA would run to completion, in this case for an integer number of FIFO fills and empties, and life’s good.</p>
<p>As we all know, real life isn’t always this neat and tidy. What happens if you (via software) turn off the DMA controller partway through?  In this kind of example the DMA can “terminate” with data remaining in its FIFO. This is the purpose of the FIFO flush.</p>
<p>For starters, it’s worth noting that the DMA will not accept any more data than what the NDTR register specifies for it. For example, if your data source is the DCMI port, which can happily throw data at the DMA all day long, and you specify “18 bytes” for the NDTR register along with a “FIFO full” threshold and a burst mode, the DMA will not take 32 bytes from the DCMI. The DMA will only accept 18 bytes from the DCMI, resulting in one and a quarter FIFO loads (so to speak). When reading out the FIFO, the DMA will do the first 16 bytes as a burst as you specified, and the remaining two bytes as single accesses. Hence the DMA will complete normally, even though the amount of DMA data wasn’t a nice multiple of the FIFO or burst size.</p>
<p>This is an important point because it means the DMA can never overrun the end of your destination data buffer. Even in the event of a FIFO flush, provided your NDTR register is never programmed with a value larger than your buffer size, this specifies the maximum amount of data the DMA will accept from the data source, and hence the maximum amount of data that can be written into the destination buffer.</p>
<p>If software turns off the DMA transfer partway through, there may be data sitting in the DMA FIFO at the moment the DMA is disabled. This is the scenario for a FIFO flush. In this case the DMA will continue emptying the FIFO, writing that data to memory, until the FIFO is empty. </p>
<p>I <em>do not know</em> the value of the NDTR register in this scenario. Is NDTR the value at the moment the DMA stream was turned off, or is NDTR the value after the flush is completed, IE including the amount of data that was written out as a result of the flush? I suspect the latter, but I don’t know for certain. </p>
<p>In any case, it’s important to note that the TCIF flag will be set. If you turn off the DMA and want to know if the flush is complete, all you need do is wait on the TCIF flag becoming set, and at that point you know the DMA stream is finished and idle. Even though you might think the DMA transfer wasn’t complete because you halted it partway through, the DMA controller thinks it was completed and will set its TCIF flag (potentially generating an interrupt if you have that enabled). If you plan on restarting the DMA, to have it continue on from where you stopped it, remember you need to update the M0AR (and/or possibly the M1AR) register, because the address register will still be pointing to the start of your buffer, and not to where the DMA just finished writing to.</p>
<p>That’s it for this post. Those are the things I’ve learnt so far about the SMT32F2xx DMA controllers, as well as any still-open questions. Next post will talk about the STM32F2xx DCMI (Digital Camera Interface) peripheral.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2011/08/18/stm32f2xx-dma-controllers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>STM32F2xx Processor Learnings</title>
		<link>http://blog.frankvh.com/2011/08/16/stm32f2xx-processor-learnings/</link>
		<comments>http://blog.frankvh.com/2011/08/16/stm32f2xx-processor-learnings/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 15:39:40 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[STM32]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=439</guid>
		<description><![CDATA[I’ve been doing a lot of work recently with the new ST processor, the STM32F2xx family. It’s a Cortex-M3 part running at 120 MHz. It’s a nice part, however I’ve lost a lot of time discovering, well, let’s not call them “bugs”, let’s instead call them “undocumented features” of the part. At the time of [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve been doing a lot of work recently with the new ST processor, the STM32F2xx family. It’s a Cortex-M3 part running at 120 MHz. It’s a nice part, however I’ve lost a lot of time discovering, well, let’s not call them “bugs”, let’s instead call them “undocumented features” of the part. At the time of writing (Aug 2011) I’ve reported a lot of this to ST, however they have not yet been documented in any errata or updates.  So I’m posting everything I know here, in the hope it’ll help others using this family of ST processors.</p>
<p>The next few posts will talk about some of the peripherals of the STM32F2xx family, mainly the DMA controllers and the DCMI port. I’ll also touch on the SDIO SD Card interface. However for this first post I want to mention a couple of things related to “getting help” for these processors, so you can avoid some of the pain I’ve suffered.</p>
<p><strong>ST Web Site</strong></p>
<p>The ST website is found at <a href="http://www.st.com" target="_blank">st.com</a> Sounds pretty simple. For some reason ST breaks their processors down into two groups: “microcontrollers” and “embedded microprocessors”.  Given that ST puts ARM-based CPUs in the “embedded microprocessors” section, and ARM Cortex-M3 parts are used in embedded applications, this is where people tend to look. Which is as good a reason as any why they’re not there. The ARM Cortex-M3 parts are found in the “microcontrollers” section of the ST website, and that’s where you’ll find the datasheets, programming manuals, errata, etc.</p>
<p>The very important software, called the “Standard Peripherals Library”, is found in the “Resources” subsection, then look under “firmware”. You will absolutely want this, as it contains start-up code for the processor, examples of how to use the peripherals, etc. It contains a wealth of useful information. Be careful to treat it as example code however, not necessarily production-ready code, until you’ve confirmed it’s completely suitable for your needs. You’ll discover it’s often lacking in error-handling, among other things. However for getting things running quickly, it’s a huge help.</p>
<p><strong>Web Forum</strong></p>
<p>ST runs a forum here:<br />
<a href="https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx" target="_blank">https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/AllItems.aspx</a><br />
I’m a little loath to post this link, because I know it won’t last long – the forum address periodically changes. ST has a lot of problems with their forums. </p>
<p>The forum will throw a lot of error messages at you. Like this:<br />
<a href="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg.jpg" alt="" title="st_error_msg" width="530" height="234" class="aligncenter size-full wp-image-440" /></a><br />
And this:<br />
<a href="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg2.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg2.jpg" alt="" title="st_error_msg2" width="912" height="255" class="aligncenter size-full wp-image-441" /></a><br />
This is a good one &#8211; even their error message contains a spelling error:<br />
<a href="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg4.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg4.jpg" alt="" title="st_error_msg4" width="825" height="434" class="aligncenter size-full wp-image-498" /></a><br />
Or this crowd pleaser, the &#8220;Windows Sharepoint Services&#8221; error message:<br />
<a href="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg3.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2011/08/st_error_msg3.jpg" alt="" title="st_error_msg3" width="668" height="307" class="aligncenter size-full wp-image-493" /></a><br />
And a great many more. That’s “normal”. Well, ok, it’s not normal for any decent forum, but it’s normal for the ST forum – it’s not anything you&#8217;re doing wrong. </p>
<p>It’s critical for your own sanity that you keep a copy of anything you post to the forum, before you hit the “OK” button to submit your posting. Just doing a copy&#038;paste is probably sufficient. Because you’ll be very unhappy if you take a bunch of time to write your masterful post, only to get a “this page doesn’t exist” message when you submit it, thereby losing all your work.</p>
<p>The forum sometimes crashes and falls apart completely, requiring the entire forum to be rebuilt at a new web address and all the old messages to be copied over to the new site. At the time of writing this happened only a few months ago. So if you see postings that don’t appear to make any sense (missing titles or missing bodies) that’s probably because you’re looking at an earlier posting that didn’t entirely survive the transfer from the last crash. A lot of attachments (code snippets and the like) were also lost in the crash.</p>
<p>The forum has a search function, however the search covers the entire set of ST forums, not just the STM32 subforum. You cannot narrow the search. Performing a search for “PLL” for example, will return many hundreds of responses, covering a broad range of processors, making the search function pretty much useless. You’re better off doing a <a href="http://www.google.ca/advanced_search" target="_blank">google “advanced search”</a>, specifying something like this as the website:</p>
<p>https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32</p>
<p>At least this way you can limit your results to the STM32 forum.</p>
<p>The forum has some genuinely helpful people on it, and it’s worth getting on there. It’s just that the ST forum software has some real issues, but these tips should help you skirt around the worst of it.</p>
<p><strong>Tech Support</strong></p>
<p>I surmise that the tech support interface is based on the same code as the forum, because in many ways its quite a bit worse than the forum. I actually feel a bit sorry for the ST tech support folks, because I’ve dealt with them a few times and always found them to be very pleasant and helpful. But they’re stuck with this interface every day, and I’ll bet they hear about it. It can’t be easy for them.</p>
<p>The comments made about the many and assorted error messages for the forum, and the necessity to keep a copy of your work before hitting the submit button, also apply to the tech support form. But more so – it appears (in my limited experience) that the ST tech support form throws even more errors than the forum does.</p>
<p>Also, there’s no way to see your posting to the tech support form, or know if they ever received it. So save a copy for yourself, in case you need to re-send it a few days later. </p>
<p>The text entry box is slightly larger than a postage stamp – you can forget about trying to see your formatting. You cannot attach files (like source code, or an oscilloscope screenshot, or anything useful like that) to your submission. Text entry is limited to 4000 characters, so doing a copy&#038;paste of code doesn&#8217;t work too well either. What I do is tell them I have these things and can email them – when they reply they provide an email address to send them to. However aside from that, they want all submissions to go through the postage-stamp web interface.</p>
<p>Once again, like the forum, it’s worth using tech support if you need it. I find the folks to be helpful, and I generally see a response about a week after I submit it. If you’re in a hurry this might not be ideal, but if you’ve tripped over a hardware “funny” and can prove it, this is going to be your best bet. For general software questions however, you’re probably better off using the forums.</p>
<p><strong>The Mythical Reset</strong></p>
<p>The ST documentation sometimes uses the terminology “reset” when referring to bits. This can get confusing in places. I asked ST tech support to clarify what “reset” means – does it mean bit set (bit = 1) or bit clear (bit = 0) when talking about the DMA EN bit. Here was their response (3 August 2011):</p>
<p><em>&#8220;resetting the EN bit&#8221; means setting to EN=1.  &#8230;  The EN bit is reset (EN=0) …</em></p>
<p>You know it’s confusing when even their own tech support people can’t tell you if “reset” means a ‘1’ or a ‘0’! </p>
<p>From reading other portions of the documentation, I believe the correct answer is that ST means a bit clear (bit = 0) when they use the term “reset”. Update: ST tech support has now confirmed this: reset means bit equals zero.</p>
<p>That’s it for this post – the next post will talk about the STM32F2xx DMA controllers.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2011/08/16/stm32f2xx-processor-learnings/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Reduce EMI by Altering Clock Duty Cycle</title>
		<link>http://blog.frankvh.com/2010/12/02/reduce-emi-by-altering-clockduty-cycle/</link>
		<comments>http://blog.frankvh.com/2010/12/02/reduce-emi-by-altering-clockduty-cycle/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 20:53:11 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=386</guid>
		<description><![CDATA[If you&#8217;re designing an electronics product that will ultimately be sold, you need to comply with EMI rules. FCC, CE / CISPR, whatever it might be in your market, these regulations set limits to how much EMI your product can radiate. After all, nobody wants the TV to stop working when your product is switched [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re designing an electronics product that will ultimately be sold, you need to comply with EMI rules. FCC, CE / CISPR, whatever it might be in your market, these regulations set limits to how much EMI your product can radiate. After all, nobody wants the TV to stop working when your product is switched on.</p>
<p>I&#8217;ve recently been playing around, looking at the effect on EMI by changing various parameters of a noisy clock. As we all (should) know, EMI is proportional to current, so reducing signal current (by increasing load impedance, and/or by placing a series resistor in the signal path at the clock driver, and/or by reducing the clock voltage) is the first thing you should do. Shortening the length of the clock trace is a very good idea as well &#8211; longer antennas with large loop areas radiate more than short tight antennas.</p>
<p>Beyond that, I noticed that altering the duty cycle of the clock seemed to knock a couple of dB from the EMI level, so I did some simulations in LTspice which appear to confirm this. In LTspice I generated a couple of simple 10 kHz square waves, with 50% duty cycle and 45% duty cycle, and performed an FFT analysis of each. Take a look.</p>
<p>This is the FFT of the 50% duty cycle clock (click on image to enlarge it).  The vertical axis is in dB, the horizontal axis is linear. This is similar to how you typically view a spectrum analyzer. Notice the FFT follows the classic F / 3F / 5F / 7F etc harmonics pattern for a square wave.</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2010/11/fft_10khz-50.jpg"><img class="aligncenter size-full wp-image-385" title="fft_10khz-50_small" src="http://blog.frankvh.com/wp-content/uploads/2010/11/fft_10khz-50_small.jpg" alt="" width="400" height="181" /></a></p>
<p>This is the FFT for that same square wave but now with a 45% duty cycle. Click on image to enlarge it.</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2010/11/fft_10khz-45.jpg"><img class="aligncenter size-full wp-image-383" title="fft_10khz-45_small" src="http://blog.frankvh.com/wp-content/uploads/2010/11/fft_10khz-45_small.jpg" alt="" width="400" height="168" /></a></p>
<p>The scales are the same as before. Notice the big difference &#8211; we now have even harmonics as well as odd. So the harmonics are now F / 2F / 3F / 4F / 5F etc. And some of those even harmonics can be strong &#8211; you can see the 8th harmonic is noticeably higher than the 7th. Terrible you say?</p>
<p>Not necessarily! Because there&#8217;s a deal being made here, which might just be a good deal. In exchange for having even harmonics as well as odd, the harmonics are now lower than they were for the 50% duty cycle case. You can think of energy being taken from the odd harmonics to create the evens. The numbers in the following table are approximate, but they tell the story.</p>
<table border="1">
<tr>
<th>Frequency </th>
<th>50%</th>
<th>45%</th>
</tr>
<tr>
<td>10</td>
<td>+7.3 dB</td>
<td>+6.9 dB</td>
</tr>
<tr>
<td>20</td>
<td> </td>
<td>-9.1 dB</td>
</tr>
<tr>
<td>30</td>
<td>-2.6 dB</td>
<td>-3.5 dB</td>
</tr>
<tr>
<td>40</td>
<td> </td>
<td>-9.7 dB</td>
</tr>
<tr>
<td>50</td>
<td>-7 dB</td>
<td>-10.1 dB</td>
</tr>
<tr>
<td>60</td>
<td> </td>
<td>-10.4 dB</td>
</tr>
<tr>
<td>70</td>
<td>-9.8 dB</td>
<td>-16.6 dB</td>
</tr>
<tr>
<td>80</td>
<td> </td>
<td>-11.5 dB</td>
</tr>
<tr>
<td>90</td>
<td>-12.1 dB</td>
<td>-28 dB</td>
</tr>
</table>
<p>When it comes to passing EMI testing, it&#8217;s the peaks that cause you to fail. If your EMI peaks exceed the regulatory threshold, you lose. So anything you can do to reduce those peaks is usually of benefit. That&#8217;s the tradeoff that&#8217;s being made here. By going with a 45% duty cycle clock, you&#8217;re introducing some new harmonics, but you&#8217;re reducing the peaks. The amplitude of the fundamental isn&#8217;t really being reduced, but for 3F and 5F it certainly is. If you can live with those even harmonics, this can potentially be a very good trade indeed.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2010/12/02/reduce-emi-by-altering-clockduty-cycle/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TI Chronos Watch &#8211; Custom Firmware</title>
		<link>http://blog.frankvh.com/2010/11/11/ti-chronos-watch-custom-firmware/</link>
		<comments>http://blog.frankvh.com/2010/11/11/ti-chronos-watch-custom-firmware/#comments</comments>
		<pubDate>Thu, 11 Nov 2010 19:07:51 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=346</guid>
		<description><![CDATA[Texas Instruments has a very cool little MSP430 development kit, in the form of a watch. It&#8217;s called the Chronos. At the recent MSP430 seminars they had a 50% off offer, so for $25 I purchased one with the intent of modifying its software.
The really neat thing about this watch is that it contains what [...]]]></description>
			<content:encoded><![CDATA[<p>Texas Instruments has a very cool little MSP430 development kit, in the form of a watch. It&#8217;s called the <a href="http://processors.wiki.ti.com/index.php/EZ430-Chronos" target="_blank">Chronos</a>. At the recent MSP430 seminars they had a 50% off offer, so for $25 I purchased one with the intent of modifying its software.</p>
<p>The really neat thing about this watch is that it contains what might be the best air-pressure sensor (altimeter / barometer) on the market today &#8211; the <a href="http://www.vti.fi/en/support/obsolete_products/pressure_sensors/" target="_blank">VTI SCP1000</a>. The sensitivity of this thing is remarkable when you read the datasheet, and I&#8217;ve seen it for real in practice. It can repeatedly resolve to less than a metre in altitude. I&#8217;ve played with it, holding it above my head while peering at the altitude readout, then holding it at my feet and reading it, then back above my head, etc. It&#8217;s kinda like magic watching the altimeter change, up and down, as you do this. The SCP1000 is now considered an obsolete component by VTI (very unfortunate), but it&#8217;s in the watch and it works very well.</p>
<p>My desire was to replicate an &#8220;altitude accumulator&#8221; function I used to have on an old Casio watch many years ago. The way it works is you enable / zero the accumulator, then it tracks your upwards-vertical distance, adding it all up. So if you go on a hike where you&#8217;re going up, then down, then up again, etc, it&#8217;s automatically summing up all those uphills you&#8217;ve done, so you can see your total vertical gain at the end of your adventure. I found it a really nice feature for hiking, biking and skiing.</p>
<p><strong>The MSP430 Chronos Programming Toolset</strong></p>
<p>Initially I wanted to use the <a href="https://github.com/poelzi/OpenChronos" target="_blank">OpenChronos</a> toolset for writing the altitude accumulator. OpenChronos uses <a href="http://mspgcc4.sourceforge.net/" target="_blank">MSPGCC</a>. Unfortunately I had a very hard time getting MSPGCC to work properly on my machine and gave up. This was unexpected because I&#8217;ve used GCC a fair bit on different machines. Searching the forums seemed to indicate I wasn&#8217;t the only one with problems. It does work for some people, and no doubt given enough time and effort I would have succeeded as well, but for a quick little project I didn&#8217;t want to spend more time getting the tools installed than actually coding.</p>
<p>So I downloaded and installed the free 30-day evaluation version of <a href="http://focus.ti.com/docs/toolsw/folders/print/ccstudio.html" target="_blank">Code Composer Studio</a> from the TI website. It includes the IDE, compiler, programmer, etc. </p>
<p><strong>Modified TI Chronos Software</strong></p>
<p>After downloading the <a href="http://processors.wiki.ti.com/index.php/EZ430-Chronos" target="_blank">latest version</a> of the stock software from the TI website and confirming I could rebuild it and program the watch with it, I set about removing everything I <em>didn&#8217;t</em> want. This included all the wireless functions (both SympliciTI and BlueRobin) and everything that depended on them, the accelerometer, the power-on test mode, etc. The reason was twofold.</p>
<ul>
<li>I wanted to simplify the watch&#8217;s menus to only those things I actually cared about. Any unnecessary menu items would only clutter the menus and make the watch more difficult to use.</li>
<li>Ideally I wanted to cut the code size down to a point where it would fit within the free code-size-limited version of Code Composer Studio.</li>
</ul>
<p>Removing the wireless functions means that the watch cannot be wirelessly updated with new software. The watch needs to be opened and the <a href="http://processors.wiki.ti.com/index.php/File:Chronos_%2B_emulator.jpg" target="_blank">little USB programming dongle physically plugged into the watch</a>. This is very easy to do.</p>
<p><a href='http://blog.frankvh.com/wp-content/uploads/2010/11/CCSworkspace.zip'><img src="http://blog.frankvh.com/wp-content/uploads/2009/06/folder.gif" alt="" title="Chronos Source Code" width="24" height="24" class="aligncenter size-full wp-image-87" /></a><br />
<a href='http://blog.frankvh.com/wp-content/uploads/2010/11/CCSworkspace.zip'>Click here to download the source code.</a></p>
<p>This file is the Chronos code as downloaded from the TI website, with files in this directory modified:</p>
<blockquote><p>ez430_chronos/915MHz &#8211; Unrestricted CCS Platinum</p></blockquote>
<p>In other words, I cheated like crazy and simply modified an existing project set of files, rather than creating a new set of project files.</p>
<p><strong>The Result</strong></p>
<p>The new top-line menu structure is:<br />
Time -> Alarm -> Temperature -> Altitude -> Altitude_Accumulator</p>
<p>One problem with the default TI software is it uses the top line for altitude display. The top line is only 4 digits, so when the altimeter is set to &#8220;feet&#8221;, it can only display a max of 9999 feet, which if you live around the mountains really isn&#8217;t high enough. So now I have the altimeter display &#8220;ALT&#8221; on the top line, and the altitude on the 5 digit bottom line.</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2010/11/altitude_2.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2010/11/altitude_2.jpg" alt="" title="altitude_2" width="297" height="400" class="aligncenter size-full wp-image-343" /></a></p>
<p>To change the altimeter display between metres (default) and feet, press-and-hold the top-left button while in altimeter mode. You&#8217;ll see the metres/feet icon flash; use the right-side up and down buttons to select which you want, then the top-left button to enter it in. Then the altimeter reading will be flashing &#8211; use the up / down buttons to set the altimeter, press the top-left button to enter it in. That&#8217;s it. (As an aside, the TI software had a minor bug where if the watch was set to feet when adjusting the altitude, the altimeter pressure table would be incorrectly set, due to a poor feet-to-metres conversion. This revised code now uses the correct value of 3.28 feet in a metre.)</p>
<p>The altitude accumulator is the next menu item, and by default it&#8217;s disabled, so the display will show &#8220;ALTA&#8221; on the top line and &#8220;off&#8221; on the bottom. Press and hold the top-left button to make the &#8220;off&#8221; start flashing, then use up/down to switch it on and press the top-left button to lock your selection in. When you have the altitude accumulator enabled the display will change.</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2010/11/3in1_2.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2010/11/3in1_2.jpg" alt="" title="3in1_2" width="800" height="440" class="aligncenter size-full wp-image-341" /></a></p>
<p>&#8220;ACCA&#8221; is the accumulated altitude (so far). &#8220;PEAK&#8221; is the peak altitude reached (so far). &#8220;DIFF&#8221; is the difference between your starting altitude (when you turned the altitude accumulator on) and your current altitude. In this example I went for a little bike ride and the display is set in metres. You can see I did 424 metres of vertical climbing, reached a peak altitude of 338 metres, and now I&#8217;m back at my starting point, the watch saying I&#8217;m only 1 metre above the altitude I started off from. Use the up/down buttons to switch between these 3 altitude-accumulator displays.</p>
<p>To turn off the altitude accumulator function, it&#8217;s much the same as turning it on. Press and hold the top-left button from any of these three displays until an &#8220;on&#8221; appears flashing, then use the up/down buttons to select &#8220;off&#8221; and press the top-left button to enter it in.</p>
<p><strong>How It Works</strong></p>
<p>It&#8217;s a little bit convoluted, so bear with me.</p>
<p>Once per minute the watch takes an altitude measurement, and updates the &#8220;peak&#8221; altitude if required. That&#8217;s pretty straightforward.</p>
<p>A &#8220;simple&#8221; way of accumulating altitude would be to take an altitude measurement, compare it to the previous altitude measurement from a minute ago, and if we&#8217;re now higher than the previous altitude, add the difference (the recent altitude gain) to the altitude accumulator.</p>
<p>The huge problem with this scheme is it accumulates errors like crazy. Any given altitude reading will have some error associated it. Imagine you&#8217;re on the flat, not going up nor down. For many reasons your measured altitude can vary: 100 m, 99 m, 100 m, etc. In the simple scheme all those little &#8220;noise&#8221; altitude changes would be added in.</p>
<p>&#8220;Easy!&#8221;, you say. Just put in a threshold &#8211; don&#8217;t add the altitude change unless it&#8217;s above a certain threshold. For example 5 metres. So now the 100 m, 99 m, 100 m, etc, wouldn&#8217;t trigger any accumulation. Fine, but now &#8220;slow and steady&#8221; altimeter rises won&#8217;t get collected either. If you&#8217;re slowly hiking up a gentle hill, unless you can exceed that altitude threshold each and every minute, a lot of your elevation changes will go unrecorded. Hmm.</p>
<p>This software works a different way. It looks for &#8220;peaks&#8221; and &#8220;valleys&#8221;, and it doesn&#8217;t add to the accumulator until you&#8217;ve gone over a peak (except for when displaying results, which we&#8217;ll mention in a moment). So imagine you&#8217;re going uphill, then down, then up again, over rolling terrain. The watch has your starting elevation, and it sees you&#8217;re climbing. At some point the watch gets a maximum altimeter reading when you&#8217;re at the top of the hill, then as you descend it sees lower altimeter values. It realises you&#8217;ve crested the hill and at that point adds your total gain (starting-point to hill-crest) to the accumulator. When it sees you&#8217;ve reached the valley bottom and the altimeter has begun to rise again, it remembers that low-point reading, so it can again measure your elevation gain from that most-recent valley-bottom-altitude the next time you reach a crest.</p>
<p>To minimise false hills and valleys detections, it has a threshold, stored as a #define, so that once you crest a hill (for example) you need to drop a certain number of metres elevation before the watch will declare that was a crest and add to the accumulator. Otherwise, just standing still the &#8220;noise&#8221; on the altimeter measurements could cause false peak/valley detections.</p>
<p>When displaying the accumulator result, the number displayed is the total in the accumulator plus any elevation you&#8217;ve done to this point. If you&#8217;ve only just started off for example, the accumulator may contain zero (because you haven&#8217;t crested any hills yet) but your current elevation is above your starting elevation, so that elevation difference is what is displayed.</p>
<p>Yes, it&#8217;s a bit convoluted to describe, but by searching for peaks and valleys, and recording the differences between them, we&#8217;re able to get much more accurate total measurements compared to the &#8220;simpler&#8221; accumulator schemes.</p>
<p><strong>Other Changes &#038; New Code Size</strong></p>
<p>There are a few other changes. Temperature is only in degrees C now (degrees F is gone). 12/24 time display selection is gone &#8211; it&#8217;s only 12H time now (with AM/PM icons of course).</p>
<p>The code size is showing roughly 14,500 bytes of &#8220;text&#8221; (code) plus 1098 bytes of data, for a total of a hair under 16k. I think the code-size-limit for the free CCS is 16k, so I suspect this code might just squeak in, but I haven&#8217;t personally tried it out to confirm.</p>
<p><strong>It&#8217;s Not Perfect</strong></p>
<p>I haven&#8217;t fully worked out how the TI display code works &#8211; it has some strange (to me) complexities, and similarly with button-presses (they may be the same thing). Anyway, sometimes you might have to press a button more than once to make the display change, even though the watch went &#8220;beep&#8221; when you pressed the button. Also sometimes the bottom display line may be overwritten by the date temporarily when looking at the altitude-related numbers. Nothing major &#8211; just some minor quirks. I&#8217;d like to better understand how their button-handling system works and their display-system works so I can fix these little quirks. I&#8217;d also like to take several altitude measurements and average them, to improve accuracy, but I found doing that caused the watch to reset (watchdog I guess) so the current code only takes a single altimeter reading each minute. For a quick bit of code however, this current version works fine and is eminently useable.</p>
<p><strong>Support</strong></p>
<p>Support seems to be a weak point with this fun little toy. The <a href="http://processors.wiki.ti.com/index.php/EZ430-Chronos" target="_blank">TI Chronos wiki</a> lists both the TI &#8220;E2E&#8221; forums and a google groups forum for support. I&#8217;ve personally posted quite different questions on both of those forums, and (at the time of writing) not had a single reply on either. So you need to be aware that you&#8217;re largely left to your own devices if you want to modify the software running inside the watch.</p>
<p>Having said that, it&#8217;s not that hard to do the basics, and as you can see, add something new and interesting to the watch. For the money it&#8217;s a great deal of fun, and where else can you say, &#8220;I programmed my own watch!&#8221;.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2010/11/11/ti-chronos-watch-custom-firmware/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>DDS Based Signal Generator</title>
		<link>http://blog.frankvh.com/2010/11/03/dds-based-signal-generator/</link>
		<comments>http://blog.frankvh.com/2010/11/03/dds-based-signal-generator/#comments</comments>
		<pubDate>Wed, 03 Nov 2010 19:41:55 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=332</guid>
		<description><![CDATA[This was a fun and short little project that I&#8217;ve recently updated. If you&#8217;re thinking about building a cheap signal generator that&#8217;ll work to 20 MHz or so, and would be DDS (direct digital synthesis) based, take a look at this:
http://www.frankvh.com/dds-signal-generator.html
It works pretty well.

I had a need for a cheap, quick &#038; not-so-dirty signal generator [...]]]></description>
			<content:encoded><![CDATA[<p>This was a fun and short little project that I&#8217;ve recently updated. If you&#8217;re thinking about building a cheap signal generator that&#8217;ll work to 20 MHz or so, and would be DDS (direct digital synthesis) based, take a look at this:</p>
<p><a href="http://www.frankvh.com/dds-signal-generator.html" target="_blank">http://www.frankvh.com/dds-signal-generator.html</a></p>
<p>It works pretty well.</p>
<p><img src="http://www.frankvh.com/uploads/images/both.jpg" alt="signal generator" /></p>
<p>I had a need for a cheap, quick &#038; not-so-dirty signal generator that was frequency-accurate. All I needed was sine and square waves &#8211; nothing fancy. But I really wanted a pretty accurate frequency control, so that if I entered 1.5 MHz that&#8217;s what I got. Using a DDS is a very simple way to achieve this. It&#8217;s not the only way, but it is an easy way.</p>
<p>I used the <a href="http://www.analog.com/en/rfif-components/direct-digital-synthesis-dds/ad9851/products/product.html" target="_blank">Analog Devices AD9851</a> DDS chip. There are a number of DDS chips out there, but this one has both the ease-of-use and the features required for this job. Plus, it&#8217;s readily available from digikey.</p>
<p>A completely different way of generating signals would to be use the <a href="http://www.maxim-ic.com/datasheet/index.mvp/id/1257" target="_blank">Maxim MAX038</a>. This part is a signal generator chip. It&#8217;s an interesting chip. Digikey doesn&#8217;t appear to hold it in stock, but there are other projects out there which use this chip. Personally, I think the DDS is more fun though.</p>
<p>It was fun putting the signal generator on the oscilloscope as well as on the spectrum analyzer to look at its output. You can see those photos on <a href="http://www.frankvh.com/dds-signal-generator/hardware.html" target="_blank">the website</a>. It&#8217;s a very interesting part. If you need to build a simple signal generator yourself, it&#8217;s worth taking a look.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2010/11/03/dds-based-signal-generator/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>USB to Serial &#8211; Fast and Easy</title>
		<link>http://blog.frankvh.com/2010/09/28/usb-to-serial-fast-and-easy/</link>
		<comments>http://blog.frankvh.com/2010/09/28/usb-to-serial-fast-and-easy/#comments</comments>
		<pubDate>Wed, 29 Sep 2010 05:17:02 +0000</pubDate>
		<dc:creator>frank</dc:creator>
				<category><![CDATA[Computers]]></category>
		<category><![CDATA[Electronics]]></category>

		<guid isPermaLink="false">http://blog.frankvh.com/?p=265</guid>
		<description><![CDATA[It seems that every little widget (processor or whatever) I work with has a serial port on it, which is extremely handy for printing status and debugging information, etc. These serial ports are of course &#8220;TTL&#8221; level, which means they&#8217;re at the level of whatever the part&#8217;s I/O voltage is, usually 3.3V but not always. [...]]]></description>
			<content:encoded><![CDATA[<p>It seems that every little widget (processor or whatever) I work with has a serial port on it, which is extremely handy for printing status and debugging information, etc. These serial ports are of course &#8220;TTL&#8221; level, which means they&#8217;re at the level of whatever the part&#8217;s I/O voltage is, usually 3.3V but not always. The question becomes, how do we connect this to a PC so we can view the widget&#8217;s output in our favourite terminal program?</p>
<p>The solution used to be simple &#8211; use a MAX232 part (or similar) and a DB9 connector. You just created an RS232 serial port. Voila.</p>
<p>But as we all know, those old-fashioned serial ports are almost completely gone now. You might still see a serial port on a new motherboard in rare circumstances. But I&#8217;ve never seen one on a recent laptop. It&#8217;s all USB now.</p>
<p>There is a standard composite device class for USB devices to implement a serial port, and there are several chips available which will implement it for you. But my favourite is a relatively new part, the <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en546923" target="_blank">Microchip MCP2200</a>. Why? Because it&#8217;s really easy to use, it works quite well, and it&#8217;s cheap. I like cheap.</p>
<p><strong>MCP2200 Example Schematic</strong></p>
<p>Take a look at this simple example schematic (click on it to make it bigger):</p>
<p><a href="http://blog.frankvh.com/wp-content/uploads/2010/09/MCP2200_example.jpg"><img src="http://blog.frankvh.com/wp-content/uploads/2010/09/MCP2200_example-350x179.jpg" alt="MCP2200 schematic" title="MCP2200_example" width="350" height="179" class="aligncenter size-medium wp-image-264" /></a></p>
<p>You really don&#8217;t need much. Aside from the chip itself, you need an R-C circuit for reset, a decoupling capacitor or two, and a cheap ceramic resonator (because why use an expensive crystal when a cheap resonator is good enough?). Oh, and the USB connector of course. That&#8217;s it. </p>
<p>Most of those parts should be very self-explanatory. The only question is: which resonator? I use the Murata CSTCE12M0G55-R0 which costs less than 30 cents when you buy a bunch, and less than 50 cents if you buy only one (those are digikey prices). Obviously not an expensive part. This is a 0.5% frequency tolerance resonator. In theory to fully meet the USB specification a 0.25% tolerance part is required, but in practice it&#8217;s not &#8211; I&#8217;ve never had a problem. And heck, it&#8217;s only a serial port.</p>
<p>You&#8217;ll notice there are a bunch of unconnected pins on the chip. If you read the datasheet you&#8217;ll discover the MCP2200 can do a bunch of other things too. But for our simple serial-to-USB task, that&#8217;s all we require. Easy.</p>
<p><strong>Size and Price</strong></p>
<p>Aside from its ease of use, there are a couple of other things I like about the part.</p>
<p>One is its packaging. It comes in three different packages, but two of them, the SOIC and the SSOP are pretty easy to solder, so those are the ones I choose. I can solder those parts by hand with a fine-tipped soldering iron and a bottle of flux.</p>
<p>The other thing is of course the price. If we go back to digikey, we discover the chip costs just over $2 if you only buy one, and around $1.50 if you buy a handful. Add in the cost of the resonator and you&#8217;re looking at a little over $2.50 for the solution, at a quantity of one. That&#8217;s cheap.</p>
<p><strong>Software</strong></p>
<p>The part works on Windows, Linux and Mac, and the <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en546923" target="_blank">Microchip MCP2200 page</a> has a zip file for driver downloads. On WinXP there&#8217;s little to do. In that zip file is a Windows INF file. When you plug your MCP2200 board into your PC&#8217;s USB port, Windows will automatically detect it, and ask in its usual way about installing software. Simply direct it to that INF file and it&#8217;ll be happy. You&#8217;ll have to do it several times because the MCP2200 is a composite device, so it identifies itself to the PC as several different devices, and the PC wants to read that same INF file for each one.</p>
<p>Here&#8217;s an important note. Basically, you MUST have <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyId=5B33B5A8-5E76-401F-BE08-1E1555D4F3D4&#038;displaylang=en" target="_blank">Service Pack 3</a> installed if you&#8217;re on WinXP. SP2 and older has bugs in its USB handling software. You can try to install the various hotfixes that are mentioned in the Microchip zip file. Or you can just fix everything in one swoop by installing SP3. By the way, installing SP3 can take a while (it took a couple of hours on my PC) so only do it when you can walk away from the computer for a while.</p>
<p>Once you&#8217;ve done the INF thing, the MCP2200 appears as another comm port on your PC. In hyperterminal or teraterm it often seems to show up as Com9 for me. Easy.</p>
<p><strong>Alternative Parts</strong></p>
<p>There are alternatives to the MCP2200. A popular one is the FTDI FT232; it&#8217;s been around for a while. Checking digikey, we see the one-off price is around $4.50 for the part. That&#8217;s almost double what the MCP2200 costs.</p>
<p>Another is the  Silicon Laboratories CP2102.  This is a popular chip that&#8217;s used in a lot of those USB to RS232 converters you can buy cheaply around the place. The difficulty with this chip is soldering it by hand &#8211; it comes in a very small package. Its pricing is decent though &#8211; $3 at digikey for one. There&#8217;s also the Exar XR21V1410, which is also in a tiny package. And no doubt many other manufacturers have similar parts too. It&#8217;s a competitive market.</p>
<p>Many microcontrollers can directly support USB. The Atmel AVR family has the excellent free <a href="http://www.fourwalledcubicle.com/LUFA.php" target="_blank">LUFA </a>project, which by all accounts works very well. This allows you to directly implement USB, including the same type of simple USB serial port, on many AVR processors. Other microcontrollers such as the Microchip PIC family, the TI MSP430 family, etc, have similar solutions. The downside of all these software solutions is that the USB code can consume a fair amount of space (RAM, Flash, CPU cycles) in the microcontroller, so you need to size your micro accordingly to accommodate both your application code <em>and</em> the USB stack code. However for simple applications, something like this can often be a great way to go.</p>
<p>The simplicity and low cost of the MCP2200 make it a great alternative however. If you don&#8217;t mind adding the chip to your PCB, it makes for a cheap and easy way to add USB connectivity to any design. I&#8217;m enjoying it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.frankvh.com/2010/09/28/usb-to-serial-fast-and-easy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

