<?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>Stack Overflow &#187; Hardware</title>
	<atom:link href="http://embeddedgurus.com/stack-overflow/category/hardware/feed/" rel="self" type="application/rss+xml" />
	<link>http://embeddedgurus.com/stack-overflow</link>
	<description>Thoughts on embedded systems by Nigel Jones</description>
	<lastBuildDate>Wed, 01 Feb 2012 20:38:30 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Novel uses for RTC registers</title>
		<link>http://embeddedgurus.com/stack-overflow/2011/12/novel-uses-for-rtc-registers/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2011/12/novel-uses-for-rtc-registers/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 14:25:44 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=646</guid>
		<description><![CDATA[For obvious reasons, I usually write about things that are widely applicable. Today I&#8217;m going to deviate from this slightly and talk about the real time clock registers / RAM that are available on some (many?) ARM processors as well as I suspect a number of other architectures. An excerpt from the NXP data sheet [...]]]></description>
			<content:encoded><![CDATA[<p>For obvious reasons, I usually write about things that are widely applicable. Today I&#8217;m going to deviate from this slightly and talk about the real time clock registers / RAM that are available on some (many?) ARM processors as well as I suspect a number of other architectures. An excerpt from the NXP data sheet is shown in the figure below.</p>
<div id="attachment_672" class="wp-caption aligncenter" style="width: 714px"><a href="http://embeddedgurus.com/stack-overflow/files/2011/02/ARM_RTC_Registers.jpg"><img class="size-full wp-image-672" src="http://embeddedgurus.com/stack-overflow/files/2011/02/ARM_RTC_Registers.jpg" alt="" width="704" height="777" /></a><p class="wp-caption-text">NXP LPC17xx RTC registers</p></div>
<p>Of most interest is the column labeled &#8216;Reset Value&#8217;. You will notice that the values highlighted in red are &#8216;NC&#8217;. &#8216;NC&#8217; means that the registers are unaffected by a reset condition. Furthermore, these particular registers may also be powered from an alternate power source such that they are also unaffected by loss of power. So why is this useful? Well I have found a couple of uses for them beyond the obvious and intended applications of maintaining date and time (for the RTC registers) and for providing non-volatile R/W storage for the General Purpose registers.</p>
<h2>Communicating with the Bootstrap loader</h2>
<p>Most embedded applications today contain a bootstrap loader (BSL). Although there are several ways of entering the BSL from the main application, the most common that I see is to force a watchdog reset, resulting in the CPU rebooting and starting up in the BSL. This technique is pretty good and I use it all the time. However I usually find it necessary for the main application to communicate some information to the BSL. For example, at a minimum the BSL needs to know that it has been intentionally entered for the purposes of performing a firmware update (as opposed to being entered as a result of a genuine watchdog failure). Under some circumstances I also need to pass other information to the BSL such as the port that initiated the update. In the past I have tended to pass this information via EEPROM. However with these registers available to me, I now use them for this task.</p>
<h2>Debugging</h2>
<p>If you are plagued with your system taking unexpected resets, then it&#8217;s a relatively trivial matter to write some debug code that writes context information to these registers. For example most RTOS provide mechanisms for calling user functions prior to performing a task switch. Within this function it&#8217;s trivial to write the task ID to one of these registers. Then it&#8217;s just a matter of putting a breakpoint on the entry into main() to discover which task was running when the reset occurred. Once you have it narrowed down to a task, you can then instrument functions in a similar manner.</p>
<p>I suspect I may find other uses for these registers in the future. Suffice to say I&#8217;d really like it if this feature became widespread across all processor families.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2011/12/novel-uses-for-rtc-registers/feed/</wfw:commentRss>
		<slash:comments>14</slash:comments>
		</item>
		<item>
		<title>An embedded systems hardware test &#8211; a collaborative effort</title>
		<link>http://embeddedgurus.com/stack-overflow/2011/02/an-embedded-systems-hardware-test-a-collaborative-effort/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2011/02/an-embedded-systems-hardware-test-a-collaborative-effort/#comments</comments>
		<pubDate>Fri, 25 Feb 2011 23:14:39 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=686</guid>
		<description><![CDATA[Regular readers will probably be aware that back in 2000 I wrote an article for Embedded Systems Programming magazine entitled A ‘C’ Test: The 0×10 Best Questions for Would-be Embedded Programmers. In the intervening years I have often thought that it would be entertaining / useful to come up with a similar test—except this time [...]]]></description>
			<content:encoded><![CDATA[<p>Regular readers will probably be aware that back in 2000 I wrote an article for Embedded Systems Programming magazine entitled <a href="http://embeddedgurus.com/stack-overflow/2009/09/a-c-test-the-0x10-best-questions-for-would-be-embedded-programmers-reprised/">A ‘C’ Test: The 0×10 Best Questions for Would-be Embedded Programmers</a>. In the intervening years I have often thought that it would be entertaining / useful to come up with a similar test—except this time I would be testing someone&#8217;s hardware knowledge. As a result over the years I have collected together a number of fun questions, which I intend to use in the forth-coming article. However it occurred to me that I have a lot of very smart readers and that collectively we could put together a far better test than I could do so on my own. Thus I&#8217;m looking for your hardware questions! Before you flood me with your suggestions here are the ground rules:</p>
<ol>
<li><a href="http://www.rmbconsulting.us/embedded-systems-design">Embedded systems design</a>, not hardware design<br />
The test is intended to test the hardware knowledge of persons <em>writing embedded code</em>. It is NOT a test for persons that will be <em>designing</em> hardware. Thus questions about the minutiae of hardware filter design are not what I&#8217;m looking for.</li>
<li>Traps<br />
The best questions will be examples from your past where someone got into trouble because they didn&#8217;t understand something about the hardware that you thought they should have.</li>
<li>Why<br />
As well as posing the question (and giving the answer!), please explain why you think it&#8217;s important that someone should know what you are asking.</li>
<li>Oscilloscope and logic analyzer<br />
I expect that the questions will cover circuits, processor architectures and tools. While I&#8217;m interested in all three, I&#8217;m particularly interested in elegant questions that will allow the questioner to determine if the candidate knows how to use an oscilloscope or logic analyzer.</li>
<li>Original<br />
Please don&#8217;t send me any copyrighted or plagiarized material. Links are of course fine. (I mention this because not only is it legally and morally wrong &#8211; but I&#8217;m also tired of people ripping off my work and claiming it as their own).</li>
<li>Attribution<br />
If I choose to use your suggestion, then tell me how you&#8217;d like it attributed. Full name + email address through anonymous are all fine.</li>
<li>Early bird&#8230;<br />
If I get multiple similar suggestions, then the first one received gets the credit.</li>
<li>Fame<br />
By sending me something you are agreeing to let me publish it. Other than attribution (and the accompanying fame <img src='http://embeddedgurus.com/stack-overflow/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ), no other compensation will be given.</li>
</ol>
<p>Anyway, if you&#8217;d like to participate then <a href="mailto:najones@rmbconsulting.us?subject=HW%20Test">contact me</a></p>
<p>Thanks! I expect that I will publish the article in a few weeks.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2011/02/an-embedded-systems-hardware-test-a-collaborative-effort/feed/</wfw:commentRss>
		<slash:comments>15</slash:comments>
		</item>
		<item>
		<title>Configuring hardware &#8211; part 3</title>
		<link>http://embeddedgurus.com/stack-overflow/2011/01/configuring-hardware-part-3/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2011/01/configuring-hardware-part-3/#comments</comments>
		<pubDate>Wed, 26 Jan 2011 13:32:48 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Effective C/C++]]></category>
		<category><![CDATA[General C issues]]></category>
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=618</guid>
		<description><![CDATA[This is the final part in a series on configuring the hardware peripherals in a microcontroller. In the first part I talked about how to set / clear bits in a configuration register, and in the second part I talked about putting together the basic framework for the driver. When I finished part 2, we [...]]]></description>
			<content:encoded><![CDATA[<p>This is the final part in a <a href="http://embeddedgurus.com/stack-overflow/2010/11/configuring-hardware-part-1/">series</a> on configuring the hardware peripherals in a microcontroller. In the  first part I talked about how to set / clear bits in a configuration  register, and in the second part I talked about putting together the basic framework for the driver. When I finished part 2, we had got as far as configuring all the bits in the open function. It&#8217;s at this point that things get interesting. In my experience the majority of driver problems fall into three areas:</p>
<ol>
<li>Failing to place the peripheral into the correct mode.</li>
<li>Getting the clocking wrong.</li>
<li>Mishandling interrupts.</li>
</ol>
<p>I think most people tend to focus on the first item. Personally I have learned that it&#8217;s usually better to tackle the above problems in the reverse order.</p>
<h2>Mishandling interrupts</h2>
<p>Almost all peripheral drivers need interrupt handlers, and these are often the source of many problems.  If you have followed my advice, then at this stage you should have a skeleton interrupt handler for every possible interrupt vector that the peripheral uses.  You should also have an open and close function. A smart thing to do at this stage is to download your code to your debug environment. I then place a break-point on every interrupt handler and then I call  the open function. If the open function merely configures the peripheral, yet does not enable it, then presumably no interrupts should occur. If they do, then you need to find out why and fix the problem.</p>
<p>At this point I now add just enough code to each interrupt handler such that it will clear the source of the interrupt and generate the requisite interrupt acknowledge. Sometimes this is done for you in hardware. In other cases you have to write a surprising amount of code to get the job done. I strongly recommend that you take your time over this stage as getting an interrupt acknowledge wrong can cause you endless problems.</p>
<p>The next stage is to write the enable function, download the code and open and enable the peripheral. This time you need to check that you do get the expected interrupts (e.g. a timer overflow interrupt) and that you acknowledge them correctly. Just as importantly you also need to check that you don&#8217;t get an unexpected interrupt (e.g. a timer match interrupt). On the assumption that all is well, then you can be reasonably confident that  there are no egregious errors in your setup of interrupts. At this point you will probably have to further flesh out the interrupt handlers in order to give the driver some limited functionality. Although I&#8217;m sure you&#8217;ll be tempted to get on with the problem at hand, I recommend that you don&#8217;t do this, but rather write code to help tackle the next problem &#8211; namely that of clocking verification.</p>
<h2>Clocking</h2>
<p>Most peripherals use a clock source internal to the microprocessor. Now modern processors have multiple clock domains, PLL based frequency multipliers, and of course multi-level pre-scalars. As a result it can be a real nightmare trying to get the correct frequency to a peripheral. Even worse it is remarkably easy to get the <em>approximately </em>correct frequency to a peripheral. This issue can be a real problem with asynchronous communications links where a 1% error in frequency may be OK with one host and fail with another. As a result I now make it a rule to always try and verify that I am indeed clocking a peripheral with the correct frequency. To do this, there is no substitute for breaking out the oscilloscope or logic analyzer and measuring something. For timers one can normally output the signal on a port pin (even if this is just for verification purposes). For communications links one can simply set up the port to constantly transmit a fixed pattern. For devices such as A2D converters I usually have to resort to toggling  a port pin at the start and end of conversion. Regardless of the peripheral, it&#8217;s nearly always worth taking the time to write some code to help you verify that the peripheral is indeed being clocked at the correct frequency.</p>
<p>When you are doing this, there are a couple of things to watch out for:</p>
<ol>
<li>If your processor has an EMI reduction mode, then consider turning it off while performing clocking measurements. The reason for this is that &#8216;EMI reduction&#8217; is actually achieved by dithering (quasi randomly varying) the clock frequency. Clearly a randomly varying clock isn&#8217;t conducive to accurate frequency measurements.</li>
<li>Make sure that your system is indeed being clocked by the correct source. I mention this because some debuggers can provide the clock to the target.</li>
</ol>
<p>Finally, if you find that you have an occasional problem with a peripheral, then checking that the clocking is precise is always a good place to start.</p>
<h2>Mode</h2>
<p>At this stage you have done the following:</p>
<ol>
<li>Considered every bit in every register in your open function.</li>
<li>Verified that you have interrupts set up correctly.</li>
<li>Written the enable function and at least part of the interrupt handler(s).</li>
<li>Verified that you have the correct frequency clocks going to the peripheral.</li>
</ol>
<p>You should now complete writing the driver. This is where you write the bulk of the application specific code. Clearly this part is highly application specific. Notwithstanding this, I can offer one piece of advice. Probably the single biggest mistake that I have made over the years is to assume that because the driver &#8216;works&#8217; that it must be correct. I will give you a simple example to demonstrate what I mean.</p>
<p>It&#8217;s well known that the popular SPI port found on many devices can operate in one of four modes (often imaginatively called Mode0, Mode1, Mode2 &amp; Mode3). These modes differ based on the phase relationship of the clock and data lines and whether the data are valid on the rising or falling edge of the clock. Thus it&#8217;s necessary to study the data sheet of the SPI peripheral to find out its required mode. Let&#8217;s assume that after studying the data sheet you conclude that Mode2 operation is called for &#8211; and you implement the code and it works. If you then walk away from the code then I humbly suggest you are asking for it. The reason is that it&#8217;s possible that a peripheral will &#8216;work&#8217; in Mode 2, even though it should be operated in Mode 3. The peripheral &#8216;works&#8217; in Mode 2 even though you are right on the edge of violating the various required setup and hold times. A different temperature or a different chip lot and your code will fall over. It&#8217;s for this reason that I strongly recommend that you break out the logic analyzer and carefully compare the signals to what is specified in the data sheet. There is nothing quite like comparing waveforms to what is in the data sheet to give you a warm fuzzy feeling that the driver really is doing its job correctly.</p>
<h2>Final Thoughts</h2>
<p>Driver writing is hard. Engineers that can take on this task and write clean, fast and correct drivers in a timely manner are immensely valuable to organizations. Thus even if you cringe at the thought of having to write a device driver, you might want to put the effort into learning how to do it &#8211; your career will thank you!</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2011/01/configuring-hardware-part-3/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Configuring hardware – part 2.</title>
		<link>http://embeddedgurus.com/stack-overflow/2010/12/configuring-hardware-%e2%80%93-part-2/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2010/12/configuring-hardware-%e2%80%93-part-2/#comments</comments>
		<pubDate>Wed, 15 Dec 2010 15:59:18 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Effective C/C++]]></category>
		<category><![CDATA[General C issues]]></category>
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=604</guid>
		<description><![CDATA[This is the second in a series on configuring the hardware peripherals in a microcontroller. In the first part I talked about how to set / clear bits in a configuration register.  Now while setting bits is an essential part of the problem, it is by no means the most difficult task. Instead the real [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second in a <a href="http://embeddedgurus.com/stack-overflow/2010/11/configuring-hardware-part-1/">series</a> on configuring the hardware peripherals in a microcontroller. In the first part I talked about how to set / clear bits in a configuration register.  Now while setting bits is an essential part of the problem, it is by no means the most difficult task. Instead the real problem is this. You need to configure the peripheral but on examining the data sheet you discover that the peripheral has twenty registers, can operate in a huge number of modes and has multiple interrupt sources. To compound the difficulty, you may not fully understand the task the peripheral performs &#8211; and the data sheet appear to have been written by someone who has clearly never written a device driver in their life. If this sounds a lot like what you have experienced, then read on!</p>
<p>When I first started working in embedded systems, I used to dread having to write a device driver. I knew I was in for days, if not weeks of anguish trying to make the stupid thing work. Today I can usually get a peripheral to do what I want with almost no heartache &#8211; and in a fraction of the time it used to take me. I do this by following a standard approach that helps minimize various problems that seem to crop up all the time in device drivers. These problems are as follows:</p>
<ol>
<li>Setting the wrong bits in a register</li>
<li>Failing to configure a register at all.</li>
<li>Setting the correct configuration bits &#8211; but in the wrong temporal order.</li>
<li>Interrupts incorrectly handled.</li>
</ol>
<p>To help minimize these types of problems, this is what I do.</p>
<h2>Step 0 &#8211; Document *what* the driver is supposed to do</h2>
<p>This is a crucial step. If you can&#8217;t write in plain English (or French etc) <strong>what </strong>the driver is supposed to do then you stand no chance of making it work correctly.  This is a remarkably difficult thing to do. If you find that you can&#8217;t succinctly and unambiguously describe the driver&#8217;s functionality then attempting to write code is futile. I typically put this explanation in the module header block where future  readers of the code can see it. An explanation may look something like this.</p>
<p style="padding-left: 30px"><em>This is a serial port driver. It is intended to be used on an RS232 line at 38400 baud, 8 data bits, no parity, one stop bit. The driver supports CTS / RTS handshaking. It does not support Xon / Xoff handshaking.</em></p>
<p style="padding-left: 30px"><em>Characters to be transmitted are buffered and sent out under interrupt. If the transmit buffer fills up then incoming characters are dropped.</em></p>
<p style="padding-left: 30px"><em>Characters are received under interrupt and placed in a buffer. When the receive buffer is almost full, the CTS line is asserted. Once the receive buffer has dropped below the low threshold, CTS is negated. If the host ignores the CTS line and continues to transmit then characters received after the receive buffer is full are discarded.</em></p>
<p>As it stands, this description is incomplete; for example it doesn&#8217;t say what happens if a receiver overrun is detected. However you should get the idea.</p>
<p>Incidentally I can&#8217;t stress the importance of this step enough. This was the single biggest breakthrough I made in improving my driver writing. This is also the step that I see missing from almost all driver code.</p>
<h2>Step 1 &#8211; Create standard function outlines</h2>
<p>Nearly all drivers need the following functions:</p>
<ol>
<li>Open function. This function does the bulk of the peripheral configuration, but typically does not activate (enable) the peripheral.</li>
<li>Close function. This is the opposite of the open function in that it returns a peripheral to its initial (usually reset) condition. Even if your application would never expect to close a peripheral it is often useful to write this function as it can deepen your understanding of the peripheral&#8217;s functionality.</li>
<li>Start function. This function typically activates the peripheral. For peripherals such as timers, the start function is aptly and accurately named. For more complex peripherals, the start function may be more of an enable function. For example a CAN controller&#8217;s start function may start the CAN controller listening for packets.</li>
<li>Stop function. This is the opposite of the start function. Its job is to stop the peripheral from running, while leaving it configured.</li>
<li>Update function(s). These function(s) are highly application specific. For example an ADC peripheral may not need an update function. A PWM channel&#8217;s update function would be used to update the PWM depth. A UART&#8217;s update function would be the transmit function. In some cases you may need multiple update functions.</li>
<li>Interrupt handler(s). Most peripheral&#8217;s need at least one interrupt handler. Even if you aren&#8217;t planning on using an interrupt source, I strongly recommend you put together a function outline for it. The reason will become clear!</li>
</ol>
<p>At this stage, your driver looks something like this:</p>
<pre>/*
 Detailed description of what the driver does goes here
*/

void driver_Open(void)
{
}

void driver_Close(void)
{
}

void driver_Start(void)
{
}

void driver_Stop(void)
{
}

void driver_Update(void)
{
}

__interrupt void driver_Interrupt1(void)
{
}

__interrupt void driver_Interrupt2(void)
{
}</pre>
<h2>Step 2 &#8211; Set up power, clocks, port pins</h2>
<p>In most modern processors, a peripheral does not exist in isolation. Many times peripherals  need to be powered up, clocks need to routed to  the peripheral and port  pins need to be configured. This step is separate from the configuration of the peripheral. Furthermore documentation on these requirements is often located in non-obvious places &#8211; and thus this step is often overlooked. This is an area where I must give a thumbs-up to NXP. At the start of each of their peripherals is a short clear write up documenting the ancillary registers that need to be configured for the peripheral to be used. An example is shown below:</p>
<p><a href="http://embeddedgurus.com/stack-overflow/files/2010/12/SSP_Basic_Configuration.jpg"><img class="aligncenter size-full wp-image-606" title="SSP_Basic_Configuration" src="http://embeddedgurus.com/stack-overflow/files/2010/12/SSP_Basic_Configuration.jpg" alt="Basic Configuration Steps for the SSP" width="777" height="436" /></a></p>
<p>Personally, I usually place the configuration of these registers in a central location which is thus outside the driver. However there is also a case for placing the configuration of these registers in the driver open function. I will address why I do it this way in a separate blog post.</p>
<h2>Step 3 &#8211; Add all the peripheral registers to the open function</h2>
<p>This step is crucial. In my experience a large number of driver problems come about because a register hasn&#8217;t been configured. The surest way to kill this potential problem is to open up the data sheet at the register list for the peripheral and simply add all the registers to the open function. For example, here is the register list for the SSP controller on an NXP ARM processor:</p>
<p><a href="http://embeddedgurus.com/stack-overflow/files/2010/12/SSP_Registers.jpg"><img class="aligncenter size-full wp-image-605" title="SSP_Registers" src="http://embeddedgurus.com/stack-overflow/files/2010/12/SSP_Registers.jpg" alt="" width="620" height="502" /></a></p>
<p>Ten registers are listed.  Even though one register is listed as read only, I still add it to the driver_Open function as I may need to read it in order to clear status flags. Thus my open function now becomes this:</p>
<pre>void driver_Open(void)
{
 SSP0CR0 = 0;
 SSP0CR1 = 0;
 SSP0DR = 0;
 SSP0SR;            /* Status register - read and discard */
 SSP0CPSR = 0;
 SSP0IMSC = 0;
 SSP0RIS = 0;
 SSP0MIS = 0;
 SSP0ICR = 0;
 SSP0DMACR = 0;
}</pre>
<p>At this stage all I have done is ensure that my code is at least aware of the requisite registers.</p>
<h2>Step 4 &#8211; Arrange the registers in the correct order</h2>
<p>For many peripherals, it is important that registers be configured in a specific order. In some cases a register must be partially configured, then other registers must be configured, and then the initial register must be completely configured. There is no way around this, other than to read the data sheet to determine if this ordering exists. I should note that the order that registers appear in the data sheet is rarely the order in which they should be configured. In my example, I will assume that the registers are correctly ordered.</p>
<h2>Step 5 &#8211; Write the close function</h2>
<p>While manufacturer&#8217;s often put a lot of effort into telling you how to configure a peripheral, it&#8217;s rare to see information on how to shut a peripheral down. In the absence of this information, I have found that a good starting point is to simply take the register list from the open function and reverse it. Thus the first pass close function looks like this:</p>
<pre>void driver_Close(void)
{
 SSP0DMACR = 0;
 SSP0ICR = 0;
 SSP0MIS = 0;
 SSP0RIS = 0;
 SSP0IMSC = 0;
 SSP0CPSR = 0;
 SSP0DR = 0;
 SSP0CR1 = 0;    
 SSP0CR0 = 0;
}</pre>
<h2>Step 6 &#8211; Configure the bits in the open function</h2>
<p>This is the step where you have to set and clear the bits in the registers. If you use the technique that I espoused in <a href="http://embeddedgurus.com/stack-overflow/2010/11/configuring-hardware-part-1/">part 1 of this series</a>, then your open function will now explicitly consider every bit in every register.  An example of a partially completed open function is shown below:</p>
<pre>void driver_Open(void)
{
 SSP1CR0 = ((4 - 1) &lt;&lt; 0) |    /* DSS = 4 bit transfer (min value allowed) */
            (0U &lt;&lt; 4) |        /* SPI format */
            (1U &lt;&lt; 6) |        /* CPOL = 1 =&gt; Clock idles high */
            (1U &lt;&lt; 7) |        /* CPHA = 1 =&gt; Output data valid on rising edge */
            (5U &lt;&lt; 8);         /* SCR = 5 to give a division by 6 */

 SSP1CR1 =  (0U &lt;&lt; 0) |        /* LPM = 0 ==&gt; no loopback mode */
            (1U &lt;&lt; 1) |        /* SSE = 1 ==&gt; SSP1 is enabled */
            (0U &lt;&lt; 2) |        /* MS = 0 ==&gt; Master mode */
            (0U &lt;&lt; 3);         /* SOD = 0 (don't care as we are in master mode */

 SSP0DR = 0;
 SSP0SR;            /* Status register - read and discard */
 SSP0CPSR = 0;
 SSP0IMSC = 0;
 SSP0RIS = 0;
 SSP0MIS = 0;
 SSP0ICR = 0;
 SSP0DMACR = 0;
}
</pre>
<p>Clearly this is the toughest part of the exercise. However at least if you have followed these steps, then you are guaranteed not to have made an error of omission.</p>
<p>This blog posting has got long enough. In the next part of this series, I will address common misconfiguration issues, interrupts etc.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2010/12/configuring-hardware-%e2%80%93-part-2/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Configuring hardware &#8211; part 1.</title>
		<link>http://embeddedgurus.com/stack-overflow/2010/11/configuring-hardware-part-1/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2010/11/configuring-hardware-part-1/#comments</comments>
		<pubDate>Sat, 13 Nov 2010 14:06:01 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Coding Standards]]></category>
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=575</guid>
		<description><![CDATA[One of the more challenging tasks in embedded systems programming is configuring the hardware peripherals in a microcontroller. This task is challenging because: Some peripherals are stunningly complex. If you have ever configured the ATM controller on a PowerQUICC processor then you know what I mean! The documentation is often poor. See for example just [...]]]></description>
			<content:encoded><![CDATA[<p>One of the more challenging tasks in embedded systems programming is configuring the hardware peripherals in a microcontroller. This task is challenging because:</p>
<ol>
<li>Some peripherals are stunningly complex. If you have ever configured the ATM controller on a PowerQUICC processor then you know what I mean!</li>
<li>The documentation is often poor. See for example just about any LCD controller&#8217;s data sheet.</li>
<li>The person configuring the hardware (i.e. me in my case) has an incomplete understanding of how the peripheral works.</li>
<li>One often has to write the code before the hardware is available for testing.</li>
<li>Manufacturer supplied example code is stunningly bad</li>
</ol>
<p>I think I could extend this list a little further &#8211; but you get the idea. Anyway, I have struggled with this problem for many years. Now while it is impossible to come up with a methodology that guarantees correct results, I have come up with a system that really seems to make this task easier. In the first part of this series I will address the most elemental task &#8211; and that is how to set the requisite bits in the register.</p>
<p>By way of example, consider this register definition.</p>
<p><a href="http://embeddedgurus.com/stack-overflow/files/2010/11/ADC12CTL0-bit-definitions.jpg"><img class="aligncenter size-full wp-image-576" title="ADC12CTL0 bit definitions" src="http://embeddedgurus.com/stack-overflow/files/2010/11/ADC12CTL0-bit-definitions.jpg" alt="" width="597" height="303" /></a>This is a control register for an ADC found in the MSP430 series of microcontrollers. The task at hand is how to write the code to set the desired bits. Now in some ways this is trivial. However if you are serious about your work, then your concern isn&#8217;t just setting the correct bits &#8211; but doing so in such a manner that it is crystal clear to someone else (normally a future version of yourself) as to what you have done &#8211; and why. With this as a premise, let&#8217;s look at some of the ways you can tackle this problem.</p>
<h2>Magic Number</h2>
<p>Probably the most common methodology I see is the magic number approach. For example:</p>
<pre>ADC12CTL0 = 0x362C;</pre>
<p>This method is an abomination. It&#8217;s error prone, and very difficult to maintain. Having said that, there is one case in which this approach is useful &#8211; and that&#8217;s when one wants to shutdown a peripheral. In which case I may use the construct:</p>
<pre>ADC12CTL0 = 0;   /* Return register to its reset condition */</pre>
<p>Other than that, I really can&#8217;t see any justification for this approach.</p>
<h2>Bit Fields</h2>
<p>Even worse than the magic number approach is to attempt to impose a bit field structure on to the register. While on first glance this may be appealing &#8211; don&#8217;t do it! Now while I think <a href="http://embeddedgurus.com/stack-overflow/2009/10/effective-c-tip-6-creating-a-flags-variable/">bitfields have their place</a>, I certainly don&#8217;t recommend them for mapping on to hardware registers. The reason is that in a nutshell the C standard essentially allows the compiler vendor carte blanche in how they implement them. For a passionate exposition on this topic, see this <a href="http://embeddedgurus.com/stack-overflow/2009/10/effective-c-tip-6-creating-a-flags-variable/#comment-2390">comment </a>on the aforementioned post. Anyway, this approach is so bad I refuse to give an example of it!</p>
<h2>Defined fields &#8211; method 1</h2>
<p>This method is quite good. The idea is that one defines the various fields. The definitions below are taken from an IAR supplied header file:</p>
<pre>#define ADC12SC             (0x001)   /* ADC12 Start Conversion */
#define ENC                 (0x002)   /* ADC12 Enable Conversion */
#define ADC12TOVIE          (0x004)   /* ADC12 Timer Overflow interrupt enable */
#define ADC12OVIE           (0x008)   /* ADC12 Overflow interrupt enable */
#define ADC12ON             (0x010)   /* ADC12 On/enable */
#define REFON               (0x020)   /* ADC12 Reference on */
#define REF2_5V             (0x040)   /* ADC12 Ref 0:1.5V / 1:2.5V */
#define MSC                 (0x080)   /* ADC12 Multiple Sample Conversion */
#define SHT00               (0x0100)  /* ADC12 Sample Hold 0 Select 0 */
#define SHT01               (0x0200)  /* ADC12 Sample Hold 0 Select 1 */
#define SHT02               (0x0400)  /* ADC12 Sample Hold 0 Select 2 */
#define SHT03               (0x0800)  /* ADC12 Sample Hold 0 Select 3 */
#define SHT10               (0x1000)  /* ADC12 Sample Hold 1 Select 0 */
#define SHT11               (0x2000)  /* ADC12 Sample Hold 1 Select 1 */
#define SHT12               (0x4000)  /* ADC12 Sample Hold 2 Select 2 */
#define SHT13               (0x8000)  /* ADC12 Sample Hold 3 Select 3 */</pre>
<p>With these definitions, one can now write code that looks something like this:</p>
<pre>ADCT12CTL0 = ADC12TOVIE + ADC12ON + REFON + MSC;</pre>
<p>However, there is a fundamental problem with this approach. To see what I mean, examine the comment associated with the define REF2_5V. You will notice that in this case, setting the bit to zero selects a 1.5V reference. Thus in my example code, I have implicitly set the reference voltage to 1.5V. If one examines the code at a later date, then it&#8217;s unclear if I intended to select a 1.5V reference &#8211; or whether I just forgot to select any reference &#8211; and ended up with the 1.5V by default. One possible way around this is to add the following definition:</p>
<pre>#define REF1_5V             (0x000)   /* ADC12 Ref = 1.5V */</pre>
<p>One can then write:</p>
<pre>ADCT12CTL0 = ADC12TOVIE + ADC12ON + REF1_5V + REFON + MSC;</pre>
<p>Clearly this is an improvement. However there is nothing stopping you writing:</p>
<pre>ADCT12CTL0 = ADC12TOVIE + ADC12ON + REF1_5V + REFON + MSC + REF2_5V;</pre>
<p>Don&#8217;t laugh &#8211; I have seen this done. There is also another problem with the way the fields have been defined, and that concerns the fields which are more than 1 bit wide. For example the field SHT0x is used to define the number of clock cycles the sample and hold should be active. It&#8217;s a 4 bit field, and thus has 16 possible combinations. If I need 13 clocks of sample and hold, then I have to write code that looks like this:</p>
<pre>ADCT12CTL0 = ADC12TOVIE + ADC12ON + REF1_5V + REFON + MSC + SHT00 + SHT02 + SHT03;</pre>
<p>It&#8217;s not exactly clear from the above that I desire 13 clock samples on the sample and hold. Now clearly one can overcome this problem by having additional defines &#8211; and that&#8217;s precisely what IAR does. For example:</p>
<pre>#define SHT0_0               (0*0x100u)
#define SHT0_1               (1*0x100u)
#define SHT0_2               (2*0x100u)
...
#define SHT0_15             (15*0x100u)</pre>
<p>Now you can write:</p>
<pre>ADCT12CTL0 = ADC12TOVIE + ADC12ON + REF1_5V + REFON + MSC + SHT0_13;</pre>
<p>However, if you use this approach you will inevitably end up confusing SHT00 and SHT0_0 &#8211; with disastrous and very frustrating results.</p>
<h2>Defining Fields &#8211; method 2</h2>
<p>In this method, one defines the <strong>bit position</strong> of the fields. Thus our definitions now look like this:</p>
<pre>#define ADC12SC             (0)   /* ADC12 Start Conversion */
#define ENC                 (1)   /* ADC12 Enable Conversion */
#define ADC12TOVIE          (2)   /* ADC12 Timer Overflow interrupt enable */
#define ADC12OVIE           (3)   /* ADC12 Overflow interrupt enable */
#define ADC12ON             (4)   /* ADC12 On/enable */
#define REFON               (5)   /* ADC12 Reference on */
#define REF2_5V             (6)   /* ADC12 Ref */
#define MSC                 (7)   /* ADC12 Multiple Sample Conversion */
#define SHT0                (8)   /* ADC12 Sample Hold 0 */
#define SHT1                (12)  /* ADC12 Sample Hold 1 */</pre>
<p>Our example configuration now looks like this:</p>
<pre>ADCT12CTL0 = (1 &lt;&lt; ADC12TOVIE) + (1 &lt;&lt; ADC12ON) + (1 &lt;&lt; REFON) + (0 &lt;&lt; REF2_5V) + (1 &lt;&lt; MSC) + (13 &lt;&lt; SHT0);</pre>
<p>Note that zero is given to the REF2_5V argument and 13 to the SHT0 argument. This was my preferred approach for a long time. However it had certain practical weaknesses:</p>
<ol>
<li>It relies upon the manifest constants being correct / me using the correct manifest constant. You only need to spend a few hours tracking down a bug that ends up being an incorrect #define to know how frustrating this can be.</li>
<li>It still doesn&#8217;t really address the issue of fields that aren&#8217;t set. That is, was it my intention to leave them at zero, or was it an oversight?</li>
<li>There is often a mismatch between what the compiler vendor calls a field and what appears in the data sheet. For example, the data sheet shows that the SHT0 field is called SHT0x. However the compiler vendor may choose to simply call this SHT0, or SHT0X etc. Thus I end up fighting compilation errors because of trivial naming mismatches.</li>
<li>When debugging, I often end up looking at a window that tells me that ADC12CTL0 bit 6 is set &#8211; and I&#8217;m stuck trying to determine what that means. (I recognize that some debuggers will symbolically label the bits &#8211; however it isn&#8217;t universal).</li>
</ol>
<h2>Eschewing definitions</h2>
<p>We now come to my preferred methodology. What I wanted was a method that has the following properties:</p>
<ol>
<li>It requires me to explicitly set / clear every bit.</li>
<li>It is not susceptible to errors in definition / use of #defines.</li>
<li>It allows easy interaction with a debugger.</li>
</ol>
<p>This is what I ended up with:</p>
<pre>ADC12CTL0 =
 (0u &lt;&lt; 0) |        /* Don't start conversion yet */
 (0u &lt;&lt; 1) |        /* Don't enable conversion yet */
 (1u &lt;&lt; 2) |        /* Enable conversion-time-overflow interrupt */
 (0u &lt;&lt; 3) |        /* Disable ADC12MEMx overflow-interrupt */
 (1u &lt;&lt; 4) |        /* Turn ADC on */
 (1u &lt;&lt; 5) |        /* Turn reference on */
 (0u &lt;&lt; 6) |        /* Reference = 1.5V */
 (1u &lt;&lt; 7) |        /* Automatic sample and conversion */
 (13u &lt;&lt;  <img src='http://embeddedgurus.com/stack-overflow/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> |      /* Sample and hold of 13 clocks for channels 0-7 */
 (0u &lt;&lt; 12);        /* Sample and hold of don't care clocks for channels 8-15 */</pre>
<p>There are multiple things to note here:</p>
<ol>
<li>I have done away with the various #defines. At the end of the day, the hardware requires that bit 5 be set to turn the reference on. The best way to ensure that bit 5 is set is to explicitly set it. Now this thinking tends to fly in the face of conventional wisdom. However, having adopted this approach I have found it to be less error prone &#8211; and a lot easier to debug / maintain.</li>
<li>Every bit position is explicitly set or cleared. This forces me to consider every bit in turn and decide what it&#8217;s appropriate value should be.</li>
<li>The layout is important. By looking down the columns, I can check that I haven&#8217;t missed any fields. Just as important, many debuggers present the bit fields of a register as a column just like this. Thus it&#8217;s trivial to map what you see in the debugger to what you have written.</li>
<li>The value being shifted has a &#8216;u&#8217; appended to it. This keeps the MISRA folks happy &#8211; and it&#8217;s a good habit to get into.</li>
<li>The comments are an integral part of this approach</li>
</ol>
<p>There are still a few problems with this approach. This is what I have discovered so far:</p>
<ol>
<li>It can be tedious with a 32 bit register.</li>
<li>Lint will complain about shifting zero (as it considers it pointless). It will also complain about shifting anything zero places (as it also considers it pointless). In which case you have to suppress these complaints. The following macros do the trick:</li>
</ol>
<pre>#define LINT_SUPPRESS(n)  /*lint --e{n} */
LINT_SUPPRESS(835)        /**&lt; Inform Lint not to worry about zero being given as an argument to &lt;&lt; */
LINT_SUPPRESS(845)        /**&lt; Inform Lint not to worry about the right side of the | operator being zero */</pre>
<p>In the next part of this article I will describe how one can extend this technique to make configuring peripherals a lot less painful.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2010/11/configuring-hardware-part-1/feed/</wfw:commentRss>
		<slash:comments>29</slash:comments>
		</item>
		<item>
		<title>DigiView Logic Analyzer</title>
		<link>http://embeddedgurus.com/stack-overflow/2010/10/digiview-logic-analyzer/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2010/10/digiview-logic-analyzer/#comments</comments>
		<pubDate>Wed, 06 Oct 2010 12:18:27 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Compilers / Tools]]></category>
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=554</guid>
		<description><![CDATA[Today is one of those rare days on which I recommend a product. I only do this when I find a product that has genuinely made my life easier, and which by extension I think will also make your life easier. The product in question is a  DigiView logic analyzer. Now the fact that logic [...]]]></description>
			<content:encoded><![CDATA[<p>Today is one of those rare days on which I recommend a product. I only do this when I find a product that has genuinely made my life easier, and which by extension I think will also make your life easier. The product in question is a  <a href="http://www.tech-tools.com/dv_dv3100.htm">DigiView logic analyzer</a>. Now the fact that logic analyzers are useful tools should not be news to you. Indeed if you have been in this business long enough you will no doubt remember the bad old days of debugging code by decoding execution traces on a logic analyzer. That being said, I almost stopped using logic analyzers because they were big, expensive, difficult to set up and highly oriented towards bus-based systems. Given that I had my own consulting company with limited cash, limited space and a propensity to work on non-bus based systems (i.e. single chip microcontrollers), it&#8217;s hardly surprising that a logic analyzer wasn&#8217;t part of my toolbox.</p>
<p>This state of affairs persisted for a number of years until I obtained via a convoluted route a DigiView DV1-100. This is a USB powered, hand-sized box, with 18 channels at 100 MHz. It&#8217;s successor (The DV3100) sells for $499. The device sat on my shelf for a while until I decided to give it a spin one day. Since then I have found it to be an indispensable tool. Interestingly I find I use it the most when implementing the myriad of synchronous protocols that seem to exist on peripheral ICs today. While it is of course very useful for getting the interfaces working, I also find it extremely useful in fine tuning the interfaces. Via the use of the logic analyzer I can really examine set-up and hold times, clock frequencies, transmission latencies and so on. Doing so has allowed me to dramatically improve the performance of these interfaces in many cases. Indeed, I have had such success in this area that I now routinely hook the analyzer up, even when the interface works first time. If nothing else it gives me a nice warm fuzzy feeling that the interface is working the way it was designed &#8211; and not by luck.</p>
<p>Another area where I find it very useful is when I need to reverse engineer a product. I do this a lot as part of my expert witness work &#8211; and it is really quite remarkable how much you can learn from looking at a logic analyzer trace.</p>
<p>Anyway, the bottom line is this. $499 gets you an 18 channel 100 MHz personal logic analyzer that can handle most of the circuitry most of us see on a daily basis. If you value your time at all, then the DigiView will pay for itself the first time you use it. Go hassle your boss to get one.</p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2010/10/digiview-logic-analyzer/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Hardware vs. firmware naming conventions</title>
		<link>http://embeddedgurus.com/stack-overflow/2010/03/hardware-vs-firmware-naming-conventions/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2010/03/hardware-vs-firmware-naming-conventions/#comments</comments>
		<pubDate>Sun, 28 Mar 2010 16:01:32 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Coding Standards]]></category>
		<category><![CDATA[General C issues]]></category>
		<category><![CDATA[Hardware]]></category>

		<guid isPermaLink="false">http://embeddedgurus.com/stack-overflow/?p=255</guid>
		<description><![CDATA[Today&#8217;s post is motivated in part by Gary Stringham. Gary is the newest member of EmbeddedGurus and he consults and blogs on what he calls the bridge between hardware and firmware. Since I work on both hardware and firmware, I&#8217;m looking forward to what Gary has to say in the coming months. Anyway, I&#8217;d recently [...]]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s post is motivated in part by Gary Stringham. Gary is the newest member of EmbeddedGurus and he consults and <a href="http://embeddedgurus.com/embedded-bridge/">blogs </a>on what he calls the bridge between hardware and firmware. Since I work on both hardware and firmware, I&#8217;m looking forward to what Gary has to say in the coming months. Anyway, I&#8217;d recently read his posting on <a href="http://embeddedgurus.com/embedded-bridge/2010/03/early-hardwarefirmware-collaboration/">Early hardware / firmware collaboration</a> when I found myself looking at a fairly complex schematic. The microprocessor had a lot of IO pins, most of which were being used. When I looked at the code to gain insight on how some of the IO was being used I found that the hardware engineer and firmware engineer had adopted completely different naming conventions. For example, what appeared on the schematic as &#8220;Relay 6&#8243; appeared in the code as &#8220;ALARM_RELAY_2&#8243;. As a result the only way I could reconcile the schematic and the code was to look at a signal&#8217;s port pin assignment on the schematic and then search the code to see what name was associated with that port pin. After I&#8217;d done this a few times, I realized I needed a more systematic approach and ended up going through all the port pin assignments in the code and using them to hand mark up the schematic. Clearly this was not only a colossal time waster, it also had the potential for introducing stupid bugs.</p>
<p>So how had this come about? Well if you have ever designed hardware, you will know that naming nets is essentially optional. In other words one can create a perfectly correct schematic without naming any of the nets. Instead all you have to do is ensure that their connectivity is correct. (This is loosely analogous in firmware to referring to variables via their absolute addresses instead of assigning a name to the variable and using it. However, the consequences for the hardware design are nowhere near as dire). Furthermore, if the engineer does decide to name a net, then in most schematic packages I&#8217;ve seen, one is free to use virtually any combination of characters. For example &#8220;~LED A&#8221; would be a perfectly valid net name &#8211; but is most definitely not a valid C variable name. If one throws in the usual issue of numbering things from zero or one (should the first of four LED&#8217;s be named LED0 or LED1?), together with hardware engineer&#8217;s frequent (and understandable) desire to indicate if a signal is active low or active high by using some form of naming convention, then one has the recipe for a real mess.</p>
<p>So what&#8217;s to be done? Well here are my suggestions:</p>
<ol>
<li>The hardware team should have a rigorously enforced naming standards convention (in much the same way that most companies have a coding standards manual).</li>
<li>All nets that are used by firmware must be named on the schematic.</li>
<li>The net names must adhere to the C standard for naming variables.</li>
<li>The firmware must use the identical name to that appearing on the schematic.</li>
</ol>
<p>Clearly this can be facilitated by having very early meetings between the hardware and firmware teams, such that when the first version of the schematic is released, there is complete agreement on the net names. If you read Gary&#8217;s blog post you&#8217;ll see that this is his point too &#8211; albeit in a slightly different field.<br />
<a href="http://www.embeddedgurus.com/stack-overflow/">Home</a></p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2010/03/hardware-vs-firmware-naming-conventions/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Voltage gradients in embedded systems</title>
		<link>http://embeddedgurus.com/stack-overflow/2010/01/voltage-gradients-in-embedded-systems/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2010/01/voltage-gradients-in-embedded-systems/#comments</comments>
		<pubDate>Sun, 24 Jan 2010 15:05:00 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[corrosion]]></category>
		<category><![CDATA[voltage gradient]]></category>

		<guid isPermaLink="false">http://www.gfcdev.org/test-stack/2010/01/24/voltage-gradients-in-embedded-systems/</guid>
		<description><![CDATA[Today&#8217;s&#8217; post was prompted by an excellent comment from Phil Ouellette in a recent newsletter from Jack Ganssle. In a nutshell Phil was advocating strobing switches with an alternating voltage waveform, rather than a direct voltage in order to minimize corrosion and premature switch failure. This happens to be an area in which I have [...]]]></description>
			<content:encoded><![CDATA[<p>Today&#8217;s&#8217; post was prompted by an excellent comment from Phil Ouellette in a recent <a href="http://www.ganssle.com/tem/tem187.htm">newsletter </a>from Jack Ganssle. In a nutshell Phil was advocating strobing switches with an alternating voltage waveform, rather than a direct voltage in order to minimize corrosion and premature switch failure. This happens to be an area in which I have some experience and so I thought I&#8217;d extend the concept a little bit and also give you some food for thought.</p>
<p>The basic idea behind Phil Ouellette&#8217;s comments is that if one has a bias voltage between two pins (such as between switch contacts), and if this bias is always in one direction (i.e. DC), then the bias can act so as to drive an electrochemical reaction. The exact results of this electrochemical reaction vary (corrosion, dendrite growth etc.), but the net result is normally the same &#8211; namely an unwanted short circuit between two pins.</p>
<p>These problems arise particularly on products that have to operate in humid environments and / or products that have to spend a very long time under power over their expected operational life.</p>
<p>So what can be done about this? Well the most important thing to understand is that it is voltage gradient (volts per meter) that is the driving force in this problem and that furthermore, voltage gradient is a vector quantity and thus its direction is important. With this understanding, it should be clear that to minimize these types of problems, one has to minimize the integral of the voltage gradient over time. To do this one has three basic choices:</p>
<ol>
<li>Minimize the voltage</li>
<li>Maximize the separation</li>
<li>Modulate the voltage</li>
</ol>
<p>Let&#8217;s take a look at each of these in turn:</p>
<p><strong>Minimize the voltage</strong><br />
Clearly technology is progressing in the right direction for us here, as 5V systems are rapidly becoming extinct and 1.8V systems becoming more common place. Thus all other things being equal, the voltage gradient between any two pins on a 5V system will be 2.8 times greater than on a 1.8V system. Thus if you are designing a system where corrosion is a concern you will do yourself a big favor for opting for as low a voltage system as you can. However, see the caveat below.</p>
<p>Note also that given that what counts is minimizing the voltage over time, it follows that you can normally improve the system performance by powering down systems that are not needed at any given time. This also of course saves you power and thus is a highly recommended step.</p>
<p><strong>Maximize the separation</strong><br />
This is by far and away the toughest problem. Twenty years ago, ICs ran on 5V and had 0.1 inch lead spacing, giving a maximum voltage gradient between pins of 5 / 0.00254 = 1969 V/m. Today, a typical 1.8V IC has a lead spacing of 0.5 mm giving a maximum voltage gradient of 1.8 / 0.0005 = 3600 V/m. Thus the voltage gradient between pins on a typical IC has gone up &#8211; despite the decrease in the operating voltage. Thus if selecting a low voltage part means that you must use a fine lead pitch part, then you are almost certainly shooting yourself in the foot!</p>
<p>Other areas where you can increase separation without too much pain is in the selection of passive components. For example a 1206 resistor has a much lower voltage gradient than an 0402 resistor, and an axial leaded capacitor is usually preferable to a radially leaded device. As a result, when I&#8217;m designing systems that have potential corrosion issues I really prefer to use larger components. Of course this can put you into conflict with marketing and production.</p>
<p><strong>Modulate the voltage</strong><br />
The method suggested by Phil Ouellette is reasonably straightforward for something like a switch. However, if one generalizes the problem to all the components on the board, then it becomes a much more complex problem. For example, consider an address bus to an external memory. The most significant address lines will presumably change state at a much lower frequency than the low order address lines. Indeed it is not uncommon for a system that has booted up and is running normally to be in a situation where the top two or three address lines never change state. Now if they are all at the same state (for example high), then no voltage gradient exists between them and so there is no problem. However if the lines are say High &#8211; Low &#8211; High, then the voltage gradient is as bad as it gets &#8211; and you have a potential problem. There are of course various solutions to this particular problem. The easiest solution is to ensure that the most significant address lines are routed to non contiguous pins on the memory chip (sometimes known as address scrambling) so that high frequency address lines are adjacent to low frequency lines. A much more difficult problem is to link the application so that all address lines are guaranteed to toggle at a reasonable frequency&#8230;</p>
<p>Another interesting example comes when one performs microcontroller port pin assignment. Normally one has little choice about certain pin assignments &#8211; but for the remainder one has free rein. The next time you find yourself in this position you may want to try performing the assignment so as to minimize the voltage gradients. I think you will find it to be a very challenging task.</p>
<p>Anyway, I hope this has given you some food for thought. Please let us know via the comments section if you have faced any of these types of problems and how you solved them.</p>
<p><a href="http://www.embeddedgurus.com/stack-overflow/">Home</a></p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2010/01/voltage-gradients-in-embedded-systems/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hardware costs versus development costs</title>
		<link>http://embeddedgurus.com/stack-overflow/2009/12/hardware-costs-versus-development-costs/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2009/12/hardware-costs-versus-development-costs/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 23:16:00 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Consulting]]></category>
		<category><![CDATA[Hardware]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[development costs]]></category>
		<category><![CDATA[PIC]]></category>

		<guid isPermaLink="false">http://www.gfcdev.org/test-stack/2009/12/24/hardware-costs-versus-development-costs/</guid>
		<description><![CDATA[Earlier this year I posted about how to solve the problem of PIC stack overflow. As part of that article I asked the question as to why does anybody use a PIC anyway when there are superior architectures such as the AVR available? Well, various people have linked to the posting and so I get [...]]]></description>
			<content:encoded><![CDATA[<p>Earlier this year I posted about how to solve the problem of PIC <a href="http://embeddedgurus.com/stack-overflow/2009/04/pic-stack-overflow/">stack overflow</a>. As part of that article I asked the question as to why does anybody use a PIC anyway when there are superior architectures such as the AVR available? Well, various people have linked to the posting and so I get a regular stream of visitors to it, some of whom weigh in on the topic. The other day, one visitor offered as a reason for using the PIC the fact that they are cheap. Is this the case I asked myself? So I did some rough comparisons of the AVR &amp; 8 bit PIC processors &#8211; and sure enough PIC processors are cheaper to buy. For example comparing the ATmega168P vs the PIC16F1936 (two roughly equivalent processors &#8211; the AVR has more memory and a lot more throughput, the PIC has more peripherals) I found that Digikey was selling the AVR for 2.60 per 980 and the PIC for $1.66 per 1600. A considerable difference &#8211; or is it?</p>
<p>Most of the products I work on have sales volumes of 1000 pieces a year, with a product life of 5 years. Thus if I chose the AVR for such a product, then my client would be paying approximately $1000 a year more for say 5 years. Applying a very modest 5% discount rate, this translates to a Net Present Value of $4,329.</p>
<p>This is when it gets interesting. Does the AVR&#8217;s architecture allow a programmer to be more productive? Well, clearly this is a somewhat subjective manner. However my sense is that the AVR does indeed allow greater programmer productivity. The reasons are as follows:</p>
<ol>
<li>The AVR&#8217;s architecture lends itself by design to being coded in a HLL. The PIC does not. As a result, programming the PIC in a HLL is always a challenge and one is far more likely to have to resort to assembly language &#8211; with the attendant drop in productivity.</li>
<li>The AVR&#8217;s inherent higher processing speed means that one has to be less concerned with fine tuning code in order to get the job done. Fine tuning code can be very time consuming.</li>
<li>The AVR&#8217;s greater code density means that one is less likely to be concerned with making the application fit in the available memory (something that can be extremely time consuming when things gets tight).</li>
<li>The AVR&#8217;s superior interrupt structure means that interrupt handling is far easier. Again interrupts are something that can consume inordinate amounts of time when things aren&#8217;t working.</li>
</ol>
<p>Now if one is a skilled PIC programmer and a novice on the AVR, then your experience will probably offset what I have postulated are inherent inefficiencies in the PIC architecture. However what about someone such as myself who is equally comfortable in both arenas? In this case the question becomes &#8211; how many more days will it take to code up the PIC versus the AVR and what do those days cost?</p>
<p>Of course if you are a salaried employee, then your salary is &#8216;hidden&#8217;. However when you are a consultant the cost of extra days is clearly visible to the client. In this case, if using an AVR reduces the number of development days by even a few, the cost difference between the two processors rapidly dwindles to nothing. Thus the bottom line is &#8211; I&#8217;m not sure that PICs are cheaper. However I suspect that in many organizations what counts is the BOM cost of a product &#8211; and perhaps this finally explains why PIC&#8217;s are more popular than AVR&#8217;s.</p>
<p>As always, I&#8217;m interested in your thoughts.<br />
<a href="http://www.embeddedgurus.com/stack-overflow/">Home</a></p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2009/12/hardware-costs-versus-development-costs/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Lowering power consumption tip #2 &#8211; modulate LEDs</title>
		<link>http://embeddedgurus.com/stack-overflow/2009/09/lowering-power-consumption-tip-2-modulate-leds/</link>
		<comments>http://embeddedgurus.com/stack-overflow/2009/09/lowering-power-consumption-tip-2-modulate-leds/#comments</comments>
		<pubDate>Tue, 22 Sep 2009 18:08:00 +0000</pubDate>
		<dc:creator>Nigel Jones</dc:creator>
				<category><![CDATA[Hardware]]></category>
		<category><![CDATA[Low Power Design]]></category>
		<category><![CDATA[LED]]></category>
		<category><![CDATA[PWM]]></category>

		<guid isPermaLink="false">http://www.gfcdev.org/test-stack/2009/09/22/lowering-power-consumption-tip-2-modulate-leds/</guid>
		<description><![CDATA[This is the second in a series of tips on lowering power consumption in embedded systems. LEDs are found on a huge percentage of embedded systems. Furthermore their current consumption can often be a very large percentage of the overall power budget for a system. As such reducing the power consumption of LEDs can have [...]]]></description>
			<content:encoded><![CDATA[<p>This is the second in a <a href="http://embeddedgurus.com/stack-overflow/2009/07/lowering-power-consumption-tip-1-avoid-zeros-on-the-i2c-bus/">series</a> of tips on lowering power consumption in embedded systems.</p>
<p>LEDs are found on a huge percentage of embedded systems. Furthermore their current consumption can often be a very large percentage of the overall power budget for a system. As such reducing the power consumption of LEDs can have a dramatic impact on the overall system power consumption. So how can this be done you ask? Well, it turns out that LEDs are highly amenable to high power strobing. That is, pulsing an LED at say 100 mA with a 10% on time (average current 10 mA) will cause it to appear as bright as an LED that is being statically powered at 20mA. However, like most things, this tradeoff does not come for free, as to take advantage of it, you have to be aware of the following:</p>
<ul>
<li>LEDs are very prone to over heating failures. Thus putting a constant 100 mA through a 20 mA LED will rapidly lead to its failure. Thus any system that that intentionally puts 100 mA through a 20 mA LED needs to be designed such that it can never allow 100 mA to flow for more than a few milliseconds at a time. Be aware that this limit can easily be exceeded when breaking a debugger &#8211; so design the circuit accordingly!</li>
<li>The eye is very sensitive to flicker, and so the modulation frequency needs to be high enough that it is imperceptible.</li>
<li>You can&#8217;t sink these large currents into a typical microcontroller port pin. Thus an external driver is essential.</li>
<li>If the LED current is indeed a large portion of the overall power budget then you have to be aware that the pulsed 100 mA current can put tremendous strain on the power supply</li>
</ul>
<p>Clearly then, this technique needs to be used with care. However, if you plan to do this from the start, then the hardware details are not typically that onerous and the firmware implementation details are normally straight forward. What I do is drive the LED off a spare PWM output. I typically set the frequency at about 1 kHz, and then set the PWM depth to obtain the desired current flow. Doing it this way imposes no overhead on the firmware and requires just a few setup instructions to get working. Furthermore a software crash is unlikely to freeze the PWM output in the on condition.  Incidentally, as well as lowering your overall power consumption, this technique has two other benefits:</p>
<ul>
<li>You get brightness control for free. Indeed by modulating the PWM depth you can achieve all sorts of neat effects. I have actually used this to convey multiple state information on a single LED. My experience is that it&#8217;s quite easy to differentiate between four states (off, dim, on, bright). Thus next time you need to get more mileage<br />
out of the ubiquitous debug LED, consider adding brightness control to it.</li>
<li>It can allow you to run LEDs off unregulated power. Thus as the supply voltage changes, you can simply adjust the PWM depth to compensate, thus maintaining quasi constant brightness. This actually gives a you further power savings because you are no longer having to accept the efficiency losses of the power supply</li>
</ul>
<p>Anyway, give it a try on your next project. I think you&#8217;ll like it.<br />
<a href="http://embeddedgurus.com/stack-overflow/2009/11/lowering-power-consumption-tip-3-using-relays/">Next Tip</a><br />
<a href="http://embeddedgurus.com/stack-overflow/2009/07/lowering-power-consumption-tip-1-avoid-zeros-on-the-i2c-bus/">Previous Tip</a>.<br />
<a href="http://www.embeddedgurus.com/stack-overflow/">Home</a></p>
]]></content:encoded>
			<wfw:commentRss>http://embeddedgurus.com/stack-overflow/2009/09/lowering-power-consumption-tip-2-modulate-leds/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

