<?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>shapeshifter.se &#187; AVR</title>
	<atom:link href="http://www.shapeshifter.se/tag/avr/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.shapeshifter.se</link>
	<description>Mostly miscellaneous technical mumbo-jumbo.</description>
	<lastBuildDate>Sat, 12 Dec 2009 12:00:49 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>1-wire meets IPv6</title>
		<link>http://www.shapeshifter.se/2009/07/10/1-wire-meets-ipv6/</link>
		<comments>http://www.shapeshifter.se/2009/07/10/1-wire-meets-ipv6/#comments</comments>
		<pubDate>Fri, 10 Jul 2009 12:25:19 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[1-wire]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[Ethernet]]></category>
		<category><![CDATA[IPv6]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=548</guid>
		<description><![CDATA[A project I&#8217;ve been hacking on for a while is a self-contained 1-wire to IPv6 bridge based on an Atmel AVR ATmega644 and the ENC28J60 Ethernet controller from Microchip.
1-wire: is a serial bus from Dallas Semiconductor/Maxim that only requires 1 data line, there are a number of cheap sensors and other devices for this bus. [...]]]></description>
			<content:encoded><![CDATA[<p>A project I&#8217;ve been hacking on for a while is a self-contained <a href="http://www.maxim-ic.com/products/1-wire/">1-wire</a> to IPv6 bridge based on an <a href="http://www.atmel.com/dyn/products/product_card.asp?PN=ATmega644P%20Automotive">Atmel AVR ATmega644</a> and the <a href="http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en022889">ENC28J60</a> Ethernet controller from Microchip.</p>
<p><strong>1-wire</strong>: is a serial bus from Dallas Semiconductor/Maxim that only requires 1 data line, there are a number of cheap sensors and other devices for this bus. The strength of this bus is not its speed but that it supports large ranges (up to 300 meters).<br />
Also, each 1-wire device has a permanent <em>unique</em> 64-bit serial number.</p>
<p><strong>IPv6</strong>: Insanely large address space. It&#8217;s common to use a 64-bit netmask for site networks so that <a href="http://en.wikipedia.org/wiki/EUI-64">EUI-64</a> based addresses can be used for auto configuration. This leaves 64-bit for the node address &#8211; do you see where this is going now&#8230; <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>Yes..I&#8217;ve built a device that assigned each 1-wire device it&#8217;s connected to its own IPv6 address. Why? you ask, mostly because I can.</p>
<p><!-- WSA: rules for context 'adsense-post-top' did not apply --></p>
<h3>Hardware</h3>
<p>As mentioned above, the device is based on an AVR ATmega644. It has 64KB of flash memory for program code and 4KB of RAM. It&#8217;s running on its built-in oscillator at 8MHz. The ENC28J60 Ethernet chip is connected to the AVR using SPI. The rest of the hardware is mostly for power distribution and management.</p>
<p>The PCB was manufactured by <a href="http://www.batchpcb.com/">BatchPCB</a>, cheap service but a bit slow turn-around time.</p>
<p><a href="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00658.JPG"><img class="aligncenter size-medium wp-image-608" title="Populated PCB" src="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00658-300x225.jpg" alt="Populated PCB" width="300" height="225" /></a></p>
<p>Unfortunately I  screwed up the SPI connection but I managed to fix that with some green wires (or black wires in this case). You&#8217;ll note them in the picture above.<br />
I also intended to run the AVR at 5V and the ethernet chip at 3.3V. This is what the quad AND-gate in the upper right<br />
corner was for, but since I screwed up the SPI routing it&#8217;s disconnected and the whole circuit is running at 3.3V.<br />
The ENC28J60 can only run at 3.3V, the AVR has a range from 2.8-5V and 1-wire should be ran at 5V but works at 3.3V. Hence the need for TTL voltage translation.</p>
<p>As for the 1-wire devices I had implemented a bus master in software that generated the require waveforms. It worked great up to about 10-15 meters. Any cable length greater than that refused to work.<br />
This was a bit unexpected and without an oscilloscope it was more or less impossible to figure out where and how the signals got mangled. So I simply got a <a href="http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2923">DS2480</a> 1-wire line driver that generates the required signals in hardware with more precise timing.</p>
<div id="attachment_595" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00725.JPG"><img class="size-medium wp-image-595" title="DSC00725" src="http://www.shapeshifter.se/wp-content/uploads/2009/07/DSC00725-300x189.jpg" alt="Add-on board with a 1-wire master" width="300" height="189" /></a><p class="wp-caption-text">Add-on board with a 1-wire master</p></div>
<p>This required an add-on board and because I didn&#8217;t want to wait for a new PCB I used a 2.54mm prototype board. With the DS2480 only available in SOIC8 packages it required some &#8220;creative&#8221; soldering <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .<br />
The DS2480 required 5V, thus It had to get its own power supply and also required level translation on the UART line between this device and the AVR. I choose an approach using MOSFETs and a few resistors for this (the TO92 packages in the picture above). This turned out to work really good and I think I&#8217;m going to use this for the SPI level translation in the next revision of the board.<br />
The wire leaving the board on the left side leads to the 1-wire sensor devices.</p>
<p>The add-on board is extremely ugly. But hey, it works.</p>
<p>Future improvements for the next revision</p>
<ul>
<li>Use of external crystal at 16MHz instead of internal 8MHz clock.</li>
<li>Use MOSFETs for 3.3-5 V translation. Need to test it at 16MHz before manufacturing a PCB though.</li>
<li>Obviously fix all PCB errors <img src='http://www.shapeshifter.se/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
<li>All SMD parts (resistors and voltage regulators) to shrink PCB size even more.</li>
<li>Better power distribution. I was a bit too conservative with the decoupling capacitors resulting in some weird power problems (fixable with some caps)</li>
<li>Create a real add-on board</li>
</ul>
<p>I&#8217;ll publish the PCB CAD files when the next revision is complete.</p>
<h3>Software</h3>
<p>The only small IPv6 stack I know of is the uIPv6 stack in the <a href="http://www.sics.se/contiki/">Contiki operating system</a> created by Adam Dunkel et al. This is unfortunately only available together with Contiki and not as a stand alone package as the originally uIP (IPv4) stack.</p>
<p>Contiki is a great operating system, but when you only have 4KB of RAM it becomes a bit heavy weight. So I broke out the uIPv6 stack from Contiki and made it run stand alone and ported in to AVR. I also ported the web server application from Contiki and made it run on AVR. As I wanted to use multiple IPv6 addresses I also had to add support for IP aliases to the uIPv6 stack.</p>
<p>Since the uIPv6 was integrated with Contiki it used the Contiki process model which it self is based on &#8220;proto-threads&#8221; (another thing invented by Adam Dunkel). I felt that this didn&#8217;t fit so I turned all processes into a polling mode instead. So one has to call a set of polling functions from the main application loop or from timers.</p>
<p>The other major parts of the code are drivers for ENC28J60, DS2480 and DS1820.</p>
<h5>Software</h5>
<dl>
<dt>1-wire devices</dt>
<dd>30 second polling interval with auto-discovery of new devices.<br />
Each device is assigned its own IPv6 address, requires a /64 network to be available.</dd>
<dt>Webserver</dt>
<dd>Integrated web server makes it possible to visit each address. An XML file with the latest sensor reading is returned. An &#8220;age timestamp&#8221; is also provided which makes it possible to determine how old the reading is. </dd>
</dl>
<p>Currently, with 5 1-wire devices connected it uses about 3KB of RAM.</p>
<ul>
<li><a href="http://svn.h3q.net/work/avr/ethernode/src">Source code</a></li>
<li><a href="http://www.shapeshifter.se/code/uipv6/">uIPv6 port</a></li>
</ul>
<h3>In-action</h3>
<p>I only have temperature sensors connected at the moment. If you happen to have an IPv6 capable connection you can access the sensors through a web browser.</p>
<p><a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:2894:eaf6:100:0c7]">2001:16d8:ffe5:002:2894:eaf6:100:0c7</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:28c1:b4f6:100:035]">2001:16d8:ffe5:002:28c1:b4f6:100:035</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:2809:aef6:100:0ca]">2001:16d8:ffe5:002:2809:aef6:100:0ca</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:28c5:a5f6:100:058]">2001:16d8:ffe5:002:28c5:a5f6:100:058</a><br />
<a rel="nofollow,noindex" href="http://[2001:16d8:ffe5:002:2813:caf6:100:050]">2001:16d8:ffe5:002:2813:caf6:100:050</a></p>
<p style="text-align: center;">(If you don&#8217;t have IPv6 you should get it, or you can view graphs based on the sensor values at <a rel="nofollow" href="http://www.lindberg.tl">lindberg.tl</a> instead).</p>
<table style="text-align: center;" border="0" cellspacing="2">
<tbody>
<tr>
<td><a href="/wp-content/uploads/2009/07/DSC00664.JPG"><img title="DSC00664" src="/wp-content/uploads/2009/07/DSC00664-300x225.jpg" alt="DSC00664" width="300" height="225" /></a></td>
<td><a href="/wp-content/uploads/2009/07/DSC00661.JPG"><img title="DSC00661" src="/wp-content/uploads/2009/07/DSC00661-300x225.jpg" alt="DSC00661" width="300" height="225" /></a></td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/07/10/1-wire-meets-ipv6/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>AVR System Timer</title>
		<link>http://www.shapeshifter.se/2009/06/02/avr-system-timer/</link>
		<comments>http://www.shapeshifter.se/2009/06/02/avr-system-timer/#comments</comments>
		<pubDate>Tue, 02 Jun 2009 10:17:41 +0000</pubDate>
		<dc:creator>fli</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[AVR]]></category>
		<category><![CDATA[microcontroller]]></category>

		<guid isPermaLink="false">http://www.shapeshifter.se/?p=546</guid>
		<description><![CDATA[Handy system clock for AVR 8-bit microcontrollers suitable for measuring elapsed time or for use with timers. This provides
a monotonic time since system startup (like the POSIX CLOCK_MONOTONIC).
The system clock is based around a 32kHz clock crystal and one of the 8-bit timers provided by the AVR, it is possible to use the CPU frequency [...]]]></description>
			<content:encoded><![CDATA[<p>Handy system clock for AVR 8-bit microcontrollers suitable for measuring elapsed time or for use with timers. This provides<br />
a monotonic time since system startup (like the POSIX CLOCK_MONOTONIC).</p>
<p>The system clock is based around a 32kHz clock crystal and one of the 8-bit timers provided by the AVR, it is possible to use the CPU frequency as a timer base as  long as it&#8217;s a nice, dividable, frequency.<br />
To be able to provide a stable 1 Hz clock but still have sub-second precision we divide 1 second into an arbitrary number of<br />
system ticks. To minimize CPU usage the tick counter should be increased at each interrupt, this means that the number of<br />
ticks per second we we choose determines our interrupt frequency and timer resolution.<br />
How to choose number of ticks? It all depends on your required resolution, if you only want a 1 second resolution a tick and a second becomes equal.</p>
<p>The AVR timer is a 8-bit register that simply counts at the rate of its clock source. The clock source can be either the CPU<br />
clock or an external oscillator, the clock source is also subject to a prescaler to further decrease the frequency.<br />
The timer then generates an interrupt on overflow and/or when it hits a pre-configured value.<br />
Since its a 8-bit timer, we have a maximum of 256 cycles before an interrupt is generated, a smaller interval can be achieved by using the comparator match to generate an interrupt at a specific value.</p>
<p>This example is creating a 1/32 second resolution timer (32 ticks per second) using an external 32768 Hz watch crystal.<br />
<em>comp</em> is the comparator value, to avoid re-arming it with different values it should be limited to 128 or 256, otherwise it has to be changed at each interrupt.</p>
<img src='http://s.wordpress.com/latex.php?latex=F_%7Btimer%7D%20%3D%2032768&#038;bg=FAFAFA&#038;fg=000000&#038;s=1' alt='F_{timer} = 32768' title='F_{timer} = 32768' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=ticks%20%3D%2032&#038;bg=FAFAFA&#038;fg=000000&#038;s=1' alt='ticks = 32' title='ticks = 32' class='latex' />
<p>The following to equations can be used to calculate either <em>comp</em> or the <em>prescale</em> value.<br />
<em>prescale</em> is limited by the target device, but common values are powers of 2 (8,32,64,128,256,1024).</p>
<p style="text-align: center;"><img src='http://s.wordpress.com/latex.php?latex=comp%20%3D%20%5Cfrac%7B%5Cfrac%7BF_%7Btimer%7D%7D%7Bprescale%7D%7D%7Bticks%7D&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='comp = \frac{\frac{F_{timer}}{prescale}}{ticks}' title='comp = \frac{\frac{F_{timer}}{prescale}}{ticks}' class='latex' /><br />
<img src='http://s.wordpress.com/latex.php?latex=prescale%20%3D%20%5Cfrac%7BF_%7Btimer%7D%7D%7Bcomp%20%5Ctimes%20ticks%7D&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='prescale = \frac{F_{timer}}{comp \times ticks}' title='prescale = \frac{F_{timer}}{comp \times ticks}' class='latex' /></p>
<p>Using 128 as the <em>comp</em> value and inserting the other values into equation 2 yields the following prescaler</p>
<p style="text-align: center;">
<img src='http://s.wordpress.com/latex.php?latex=%5Cfrac%7B32768%7D%7B128%20%5Ctimes%2032%7D%20%3D%208&#038;bg=FAFAFA&#038;fg=000000&#038;s=2' alt='\frac{32768}{128 \times 32} = 8' title='\frac{32768}{128 \times 32} = 8' class='latex' />
</p>
<p>So, a prescaler of 8 gives us two interrupts per 256 cycles, one at 128 and one at 256 (overflow). Using 256 as <em>comp</em> would yield a perscaler of 4 but the target device I used didn&#8217;t have a TS/4 prescaler.</p>
<p>Complete source code for a 1/32 (or 31.25ms) second resolution timer for the ATmegaxx4 using Timer 2 and a 32kHz watch crystal connected to the pins TOSC1 and TOSC2.<br />
Requires <a href="http://www.nongnu.org/avr-libc/">AVR libc</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#include &lt;avr/io.h&gt;</span>
<span style="color: #339933;">#include &lt;avr/interrupt.h&gt;</span>
&nbsp;
<span style="color: #993333;">typedef</span> uint32_t clock_time_t<span style="color: #339933;">;</span>
<span style="color: #993333;">static</span> clock_time_t global_system_ticks <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ISR for the timer overflow */</span>
ISR<span style="color: #009900;">&#40;</span>TIMER2_OVF_vect<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    global_system_ticks<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ISR for the comparator */</span>
ISR<span style="color: #009900;">&#40;</span>TIMER2_COMPA_vect<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    global_system_ticks<span style="color: #339933;">++;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Return number of elapsed ticks */</span>
clock_time_t clock_time<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>global_system_ticks<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Return number of elapsed seconds */</span>
<span style="color: #993333;">unsigned</span> <span style="color: #993333;">long</span> clock_seconds<span style="color: #009900;">&#40;</span><span style="color: #993333;">void</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
    uint32_t tmp<span style="color: #339933;">;</span>
&nbsp;
    TIMSK2 <span style="color: #339933;">&amp;=</span> ~<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    tmp <span style="color: #339933;">=</span> global_system_ticks <span style="color: #339933;">/</span> <span style="color: #0000dd;">32</span><span style="color: #339933;">;</span>
    TIMSK2 <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #b1b100;">return</span> <span style="color: #009900;">&#40;</span>tmp<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #993333;">void</span> clock_init<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Enable external oscillator (32 kHz crystal) connected to TOSC{1,2} */</span>
    ASSR <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> AS2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Reset timer */</span>
    TCNT2 <span style="color: #339933;">=</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Set TS/8 prescaler, results in a 4096Hz clock */</span>
    TCCR2B <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> CS21<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/* Compare at half counter value */</span>
    OCR2A <span style="color: #339933;">=</span> <span style="color: #0000dd;">128</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #808080; font-style: italic;">/*
     * Enable overflow and compare interrupt.
     * Triggers each 1/32 secs
     */</span>
    TIMSK2 <span style="color: #339933;">|=</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> OCIE2A<span style="color: #009900;">&#41;</span> <span style="color: #339933;">|</span> <span style="color: #009900;">&#40;</span><span style="color: #0000dd;">1</span> <span style="color: #339933;">&lt;&lt;</span> TOIE2<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://www.shapeshifter.se/2009/06/02/avr-system-timer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
