<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
	<id>https://www.sequencer.de/synth/index.php?action=history&amp;feed=atom&amp;title=MCV876_Controller_Update%3A_Bootloader</id>
	<title>MCV876 Controller Update: Bootloader - Versionsgeschichte</title>
	<link rel="self" type="application/atom+xml" href="https://www.sequencer.de/synth/index.php?action=history&amp;feed=atom&amp;title=MCV876_Controller_Update%3A_Bootloader"/>
	<link rel="alternate" type="text/html" href="https://www.sequencer.de/synth/index.php?title=MCV876_Controller_Update:_Bootloader&amp;action=history"/>
	<updated>2026-10-28T23:02:59Z</updated>
	<subtitle>Versionsgeschichte dieser Seite in Synthesizer Wiki</subtitle>
	<generator>MediaWiki 1.44.2</generator>
	<entry>
		<id>https://www.sequencer.de/synth/index.php?title=MCV876_Controller_Update:_Bootloader&amp;diff=7316&amp;oldid=prev</id>
		<title>Fetz: Programmieranleitung zugefügt</title>
		<link rel="alternate" type="text/html" href="https://www.sequencer.de/synth/index.php?title=MCV876_Controller_Update:_Bootloader&amp;diff=7316&amp;oldid=prev"/>
		<updated>2011-06-26T21:55:57Z</updated>

		<summary type="html">&lt;p&gt;Programmieranleitung zugefügt&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;de&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Nächstältere Version&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Version vom 26. Juni 2011, 22:55 Uhr&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l12&quot;&gt;Zeile 12:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Zeile 12:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;(Im Prinzip ist das hier nicht viel anders als das, was hier beschrieben wird: http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung )  &lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;(Im Prinzip ist das hier nicht viel anders als das, was hier beschrieben wird: http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung )  &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;= Controller programmieren = &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Der Bootlader muss mit einem Programmiergerät in den Controller &quot;geflasht&quot; werden. Das sollte mit jedem Programmieradapter gehen, der für den ATmega 88 gedacht ist. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Für ISP-Adapter braucht man irgendeine Platine mit ISP-Sockel, da der Adapter keine Programmierpins hat. Ich habe einfach eine Platine eines anderen Projektes genommen... &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Damit der Bootlader so arbeitet wie gewünscht, muss man die &quot;Fuses&quot; des Controllers richtig setzen:&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[File:fuses1.gif]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;[[File:fuses2.gif]]&lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Hier als Screen-Shot aus dem AVR-Studio 4, so sieht das mit dem Dragon als Programmieradapter aus. Sollte sich aber problemlos auf andere Programmiergeräte übertragen lassen. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Der Bootbereich darf sich nicht selber überschreiben (Look SPM in Boot Section) &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* 2k-Byte Boot-Bereich (kleiner hat keinen Zweck, da die ganzen 2k immer nur unter CPU-Halt beschrieben werden können, was unsere Update-Infrastruktur aber nicht zulässt) &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Reset springt in den Bootlader &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Der Reset-Pin ist I/O Pin. (Vorsicht, das sperrt den ISP-Prgrammer final aus - erst ganz zum Schluß machen!) &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Unterspannungsdetektor bei 4.3V (eher theoretisch...) &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;* Oszillator für externen Quarz. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;Ein &quot;neuer&quot; Atmega steht übrigens auf intern 8MHz-RC/8, da muss man, zumindest beim Dragon, den Takt erst mal kleiner stellen, sonst spricht der Dragon gar nicht mit dem Controller. &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-side-deleted&quot;&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;= Quelltext = &lt;/ins&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;&amp;lt;pre&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;/*&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;/*&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Fetz</name></author>
	</entry>
	<entry>
		<id>https://www.sequencer.de/synth/index.php?title=MCV876_Controller_Update:_Bootloader&amp;diff=7289&amp;oldid=prev</id>
		<title>Fetz: Created page with &#039;= Worum geht&#039;s? = Midi-Bootlader für den ATMega 88.  Empfängt einen als Midi-Sys-Ex Datenstrom eingepacktes Programm-Update und schreibt das in den Programm-Speicher des Contro…&#039;</title>
		<link rel="alternate" type="text/html" href="https://www.sequencer.de/synth/index.php?title=MCV876_Controller_Update:_Bootloader&amp;diff=7289&amp;oldid=prev"/>
		<updated>2011-06-25T22:31:00Z</updated>

		<summary type="html">&lt;p&gt;Created page with &amp;#039;= Worum geht&amp;#039;s? = Midi-Bootlader für den ATMega 88.  Empfängt einen als Midi-Sys-Ex Datenstrom eingepacktes Programm-Update und schreibt das in den Programm-Speicher des Contro…&amp;#039;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= Worum geht&amp;#039;s? =&lt;br /&gt;
Midi-Bootlader für den ATMega 88.&lt;br /&gt;
&lt;br /&gt;
Empfängt einen als Midi-Sys-Ex Datenstrom eingepacktes Programm-Update und schreibt das in den Programm-Speicher des Controllers. &lt;br /&gt;
 &lt;br /&gt;
= Compilieren =&lt;br /&gt;
Der Code wird mit dem AVR-Studio 4 erzeugt (neues Projekt erzeugen, Quelltext in das Default-File kopieren, fertig) &lt;br /&gt;
&lt;br /&gt;
Einzige Besonderheit ist, dass der Code für die Boolader-Adresse gelinkt werden muss. &lt;br /&gt;
Dazu unter Projekt-&amp;gt; Configuration Options -&amp;gt; Custom Options -&amp;gt; Linker Options eine neue Option &amp;quot;-Ttext=0x1800&amp;quot; zufügen (add) &lt;br /&gt;
&lt;br /&gt;
(Im Prinzip ist das hier nicht viel anders als das, was hier beschrieben wird: http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung ) &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
/*&lt;br /&gt;
	MCV876 with ATMega 88 &lt;br /&gt;
&lt;br /&gt;
	Bootloader &lt;br /&gt;
&lt;br /&gt;
	Preliminary &lt;br /&gt;
	Version 0.98 2011-06-26&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
    This program is free software: you can redistribute it and/or modify&lt;br /&gt;
    it under the terms of the GNU General Public License as published by&lt;br /&gt;
    the Free Software Foundation, either version 3 of the License, or&lt;br /&gt;
    (at your option) any later version.&lt;br /&gt;
&lt;br /&gt;
    This program is distributed in the hope that it will be useful,&lt;br /&gt;
    but WITHOUT ANY WARRANTY; without even the implied warranty of&lt;br /&gt;
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the&lt;br /&gt;
    GNU General Public License for more details.&lt;br /&gt;
&lt;br /&gt;
    You should have received a copy of the GNU General Public License&lt;br /&gt;
    along with this program.  If not, see &amp;lt;http://www.gnu.org/licenses/&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#include &amp;lt;avr/boot.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/pgmspace.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/io.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/eeprom.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/delay.h&amp;gt;&lt;br /&gt;
#include &amp;lt;avr/interrupt.h&amp;gt;&lt;br /&gt;
#include &amp;lt;util/crc16.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define LEDGATE0 0	// Led an Gate 0, keine LED Ansteuerung&lt;br /&gt;
#define LEDGATE4 4	// LED an Gate 5, &lt;br /&gt;
#define LEDLED   6  // LED an Reset-Pin (Serie, kein Debuging) &lt;br /&gt;
&lt;br /&gt;
#define LEDOUT LEDLED&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define BUTTON (!(PIND &amp;amp; (1&amp;lt;&amp;lt;4)))&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void (*applicationmain)(void) = (void *)0x0000;&lt;br /&gt;
void (*bootloader)(void) = (void *)0x1800;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
volatile unsigned char program_it;&lt;br /&gt;
volatile unsigned char prog_active; &lt;br /&gt;
volatile unsigned char flash_buf[64];&lt;br /&gt;
volatile unsigned char blockAdress;&lt;br /&gt;
&lt;br /&gt;
#define EESTATUS_OK 1		// last flash was ok &lt;br /&gt;
#define EESTATUS_START 2 	// last flash was started (if read on boot-up: ... but never finished) &lt;br /&gt;
&lt;br /&gt;
#define BOOTEEPROMADR ((uint8_t *) 500) // permanent Flag for last update status (&amp;#039;started&amp;#039; or &amp;#039;success&amp;#039;) &lt;br /&gt;
										// more or less obvisious the permanent state musst be success, else it failed to complete &lt;br /&gt;
										// and that can&amp;#039;t be ok... &lt;br /&gt;
&lt;br /&gt;
#define PROGRAM_IDLE 0 &lt;br /&gt;
#define PROGRAM_DO 1&lt;br /&gt;
#define PROGRAM_FINISH 2&lt;br /&gt;
#define PROGRAM_ERROR 3&lt;br /&gt;
#define PROGRAM_START 4&lt;br /&gt;
#define PROGRAM_ABORT 5&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ***********************************************************************************&lt;br /&gt;
&lt;br /&gt;
	LED&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
void setLed(unsigned char on)&lt;br /&gt;
{&lt;br /&gt;
#if LEDOUT == LEDLED&lt;br /&gt;
	if (on)	// PC6&lt;br /&gt;
		PORTC |= (1&amp;lt;&amp;lt; 6);&lt;br /&gt;
	else &lt;br /&gt;
		PORTC &amp;amp;=~(1&amp;lt;&amp;lt; 6);&lt;br /&gt;
#endif &lt;br /&gt;
#if LEDOUT == LEDGATE4&lt;br /&gt;
	if (on)	// PB1&lt;br /&gt;
		PORTB |= (1&amp;lt;&amp;lt; 1);&lt;br /&gt;
	else &lt;br /&gt;
		PORTB &amp;amp;=~(1&amp;lt;&amp;lt; 1);&lt;br /&gt;
#endif &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/* ***********************************************************************************&lt;br /&gt;
&lt;br /&gt;
	Main&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
int main(void)&lt;br /&gt;
{&lt;br /&gt;
	unsigned char i,j; &lt;br /&gt;
	unsigned short int flashAdress;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	volatile uint16_t tmp;&lt;br /&gt;
	volatile uint16_t adr;&lt;br /&gt;
&lt;br /&gt;
/* &lt;br /&gt;
&lt;br /&gt;
		HARDWARE INIT &lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
	cli();	// just to be sure... its not allways a cold boot which runs here.. &lt;br /&gt;
&lt;br /&gt;
   // Input/Output Ports initialization&lt;br /&gt;
    // DDRx  = Define I/O direction for each pins&lt;br /&gt;
    // PORTx = If pin is Output then `0&amp;#039; = lo, `1&amp;#039; = hi&lt;br /&gt;
    //         If pin is input then `0&amp;#039; = no pullup, `1&amp;#039; = pullup enabled&lt;br /&gt;
    // `0&amp;#039; = Input `1&amp;#039; = Output&lt;br /&gt;
    // Port B initialization&lt;br /&gt;
    DDRB  = 0x3f;                 // PB0=G4; PB1=G5 (Opt. LED); PB2=G6 ; PB3=WR1; PB4=D0; PB5=D1 (all output)&lt;br /&gt;
    PORTB = 0x04;                 // WR1 High, Rest Low &lt;br /&gt;
&lt;br /&gt;
    // Port C initialization&lt;br /&gt;
    DDRC  = 0x7F;                 // PC0=D2; PC1=D3; PC2=D4; PC3=D5; PC4=D6; PC5=D7; PC6=LED (opt.) (all output)&lt;br /&gt;
	PORTC = 0x00;                 // all Low&lt;br /&gt;
&lt;br /&gt;
    // Port D initialization&lt;br /&gt;
    DDRD  = 0xee;                 // [PD0=RX]; PD1=WR2; PD2=WR3; PD3=WR4; PD4=Button; PD5=G1; PD6=G2; PD7=G3 &lt;br /&gt;
    PORTD = 0x1F;                 // Pullup on RX &amp;amp; Button, all WR High, Gates Low &lt;br /&gt;
&lt;br /&gt;
	if(GPIOR1==0xAB)&lt;br /&gt;
	{&lt;br /&gt;
		// app intended Boot Load&lt;br /&gt;
		GPIOR1 = 0;&lt;br /&gt;
	}&lt;br /&gt;
	else&lt;br /&gt;
	{	// no main application intended Boot-Load&lt;br /&gt;
&lt;br /&gt;
		_delay_ms(10);	// Wait for Button-Pin to get High if not pressed&lt;br /&gt;
		&lt;br /&gt;
		GPIOR1=0;&lt;br /&gt;
		&lt;br /&gt;
		while(BUTTON &amp;amp;&amp;amp; GPIOR1 &amp;lt; 8)&lt;br /&gt;
		{&lt;br /&gt;
			_delay_ms(1800);&lt;br /&gt;
			setLed(1);&lt;br /&gt;
			_delay_ms(200);&lt;br /&gt;
			setLed(0);&lt;br /&gt;
			GPIOR1++;&lt;br /&gt;
		}&lt;br /&gt;
		_delay_ms(10);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
		if( ( !BUTTON &amp;amp;&amp;amp; GPIOR1==0 ) || GPIOR1 &amp;gt;= 8)&lt;br /&gt;
		{&lt;br /&gt;
			unsigned char x; &lt;br /&gt;
		&lt;br /&gt;
			_delay_ms(100);&lt;br /&gt;
		&lt;br /&gt;
			x=eeprom_read_byte(BOOTEEPROMADR); 	&lt;br /&gt;
			if(x != EESTATUS_START &amp;amp;&amp;amp; pgm_read_word(0)!=0xffff ) // if no failed update atemps and not erased &lt;br /&gt;
			{&lt;br /&gt;
				_delay_ms(100);&lt;br /&gt;
				applicationmain();&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	/* Enable change of Interrupt Vectors */&lt;br /&gt;
	MCUCR = (1 &amp;lt;&amp;lt; IVCE );&lt;br /&gt;
	/* Move Interrupts to boot flash section */&lt;br /&gt;
	MCUCR = ( 1 &amp;lt;&amp;lt; IVSEL ); &lt;br /&gt;
&lt;br /&gt;
    // Timer/Counter 1 initialization&lt;br /&gt;
    // Clock source: System Clock&lt;br /&gt;
    // Clock value: 20Mhz /64&lt;br /&gt;
    // Mode: CTC &lt;br /&gt;
    // OC0 output: Disconnected&lt;br /&gt;
	OCR1A= 625; // 2 ms  &lt;br /&gt;
	TCCR1A =0; &lt;br /&gt;
	TCCR1B =8+3; // CTC Mode, TOP from OCR1A + Clock/64 &lt;br /&gt;
	TIMSK1 =2; // OCF1A Interupt &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    // USART initialization&lt;br /&gt;
    // Communication Parameters: 8 Data, 1 Stop, No Parity&lt;br /&gt;
    // USART Receiver: On&lt;br /&gt;
    // USART Transmitter: OFF&lt;br /&gt;
    // USART Mode: Asynchronous&lt;br /&gt;
    UCSR0A = 0x00;&lt;br /&gt;
	/* Set frame format: 8data, 1stop bit */&lt;br /&gt;
	UCSR0C = 6;&lt;br /&gt;
&lt;br /&gt;
    // USART Baud rate: 31250;  20E6/16/31250 - 1&lt;br /&gt;
   	UBRR0H = 0;&lt;br /&gt;
    UBRR0L = 39;&lt;br /&gt;
&lt;br /&gt;
    /*Enable receiver , Enable Rx-int  */&lt;br /&gt;
	UCSR0B = ((1&amp;lt;&amp;lt;RXEN0)|(1&amp;lt;&amp;lt;RXCIE0) ) ;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/*&lt;br /&gt;
	HARDWARE READY &lt;br /&gt;
*/&lt;br /&gt;
	sei(); // Interupts on &lt;br /&gt;
&lt;br /&gt;
	while(1) // Main Loop &lt;br /&gt;
	{&lt;br /&gt;
		if(program_it== PROGRAM_DO || program_it== PROGRAM_FINISH)&lt;br /&gt;
		{&lt;br /&gt;
			flashAdress=blockAdress  ;  // Block number &lt;br /&gt;
			flashAdress&amp;lt;&amp;lt;=6;			// * block size of 64 bytes &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
			cli();		// some register writes must be done within 4 clock cycles max, Interupts can kill that &lt;br /&gt;
			boot_page_erase(flashAdress);	// issue the block erease command &lt;br /&gt;
			sei();&lt;br /&gt;
&lt;br /&gt;
						&lt;br /&gt;
			do&lt;br /&gt;
			{&lt;br /&gt;
				cli();&lt;br /&gt;
				j=(__SPM_REG &amp;amp; (uint8_t)_BV(__SPM_ENABLE));	// j=it&amp;#039;s done? &lt;br /&gt;
				sei();&lt;br /&gt;
			}while(j);		// wait until j says, that it is done &lt;br /&gt;
			// this takes some millisekonds, during which we&amp;#039;ll receive about a quarter of the next block&lt;br /&gt;
			// so interupts can&amp;#039;t be off the whole time. &lt;br /&gt;
;&lt;br /&gt;
			for (i = 0; i &amp;lt; 64; i+=2) // fill page buffer with 32 words (à two bytes each) &lt;br /&gt;
			{&lt;br /&gt;
				tmp = (flash_buf[i]) | (flash_buf[i + 1]&amp;lt;&amp;lt;8);&lt;br /&gt;
				adr=flashAdress+i;&lt;br /&gt;
				cli();	// again, one of the &amp;quot;max 4 cycle&amp;quot; macros &lt;br /&gt;
				boot_page_fill(adr, tmp);	// write a word &lt;br /&gt;
				sei();&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			cli();&lt;br /&gt;
			boot_page_write(flashAdress);	// write to flash &lt;br /&gt;
			sei();&lt;br /&gt;
			&lt;br /&gt;
			do	// wait until write is done &lt;br /&gt;
			{	&lt;br /&gt;
				cli();										// prepare uninteruptable max. 4 Cylce sequence &lt;br /&gt;
				j=(__SPM_REG &amp;amp; (uint8_t)_BV(__SPM_ENABLE));	// read ready flag &lt;br /&gt;
				sei();										// done &lt;br /&gt;
			}while(j);		// while not ready. Again this takes 3.5 to 4.5ms, during which about another quarter of the &lt;br /&gt;
							// next block comes in. As we don&amp;#039;t want to lose any chars, the interupts cant be turned off the whole time &lt;br /&gt;
&lt;br /&gt;
			cli();&lt;br /&gt;
			boot_rww_enable();	// enable read access to programm flash. &lt;br /&gt;
			sei();&lt;br /&gt;
			&lt;br /&gt;
			if(program_it==PROGRAM_FINISH)	// if last block&lt;br /&gt;
			{&lt;br /&gt;
				eeprom_write_byte(BOOTEEPROMADR,EESTATUS_OK);		// store flag for successfull update &lt;br /&gt;
				prog_active=PROGRAM_IDLE;		// should be senseless, but inhibits permanent eeprom writes if something goes wrong... &lt;br /&gt;
&lt;br /&gt;
				// Update done, go to new application programm &lt;br /&gt;
				cli();										// no more intupts &lt;br /&gt;
				/* Enable change of Interrupt Vectors */	// set interupt vectors to program &lt;br /&gt;
				MCUCR = (1 &amp;lt;&amp;lt; IVCE );&lt;br /&gt;
				/* Move Interrupts to regular flash section */&lt;br /&gt;
				MCUCR = 0; // ( 0 &amp;lt;&amp;lt; IVSEL ); &lt;br /&gt;
&lt;br /&gt;
				applicationmain();							// call application (never comes back, stack is lost...) &lt;br /&gt;
			}&lt;br /&gt;
			if(program_it!=PROGRAM_ERROR)	// if not error 		// which might happen asynchronous - and should be kept&lt;br /&gt;
				program_it=PROGRAM_IDLE;	// programming of current page done. &lt;br /&gt;
		}&lt;br /&gt;
		if(program_it==PROGRAM_START)&lt;br /&gt;
		{&lt;br /&gt;
			prog_active=PROGRAM_START;&lt;br /&gt;
			eeprom_write_byte(BOOTEEPROMADR,EESTATUS_START);&lt;br /&gt;
&lt;br /&gt;
			if(program_it!=PROGRAM_ERROR)	// might happen asynchronous &lt;br /&gt;
				program_it=PROGRAM_IDLE;&lt;br /&gt;
		}&lt;br /&gt;
		if(program_it==PROGRAM_ABORT)&lt;br /&gt;
		{&lt;br /&gt;
			cli();&lt;br /&gt;
			/* Enable change of Interrupt Vectors */&lt;br /&gt;
			MCUCR = (1 &amp;lt;&amp;lt; IVCE );&lt;br /&gt;
			/* Move Interrupts to regular flash section */&lt;br /&gt;
			MCUCR = 0; // ( 0 &amp;lt;&amp;lt; IVSEL ); &lt;br /&gt;
&lt;br /&gt;
			bootloader(); 	// checks, if there is a valid program to start &lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
/* ***********************************************************************************&lt;br /&gt;
&lt;br /&gt;
	2ms Timer Interupt&lt;br /&gt;
&lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
volatile unsigned char dataRx; &lt;br /&gt;
#define DATARX 4&lt;br /&gt;
&lt;br /&gt;
ISR(TIMER1_COMPA_vect)&lt;br /&gt;
{&lt;br /&gt;
	static unsigned char bit;&lt;br /&gt;
	static unsigned char blinker;&lt;br /&gt;
	static unsigned char blinks[]={ 40 , 10, 200, 10,   15,15,15,15 }; &lt;br /&gt;
	static unsigned char btn;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	if (blinker-- == 0)&lt;br /&gt;
	{&lt;br /&gt;
		bit++;&lt;br /&gt;
		bit&amp;amp;=3;&lt;br /&gt;
		blinker=blinks[bit | dataRx];&lt;br /&gt;
&lt;br /&gt;
		setLed(bit&amp;amp;1);&lt;br /&gt;
&lt;br /&gt;
		dataRx=0;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	if(BUTTON)&lt;br /&gt;
	{&lt;br /&gt;
		btn=10;&lt;br /&gt;
	}&lt;br /&gt;
	else &lt;br /&gt;
	{&lt;br /&gt;
		if(btn&amp;gt;0)&lt;br /&gt;
		{	&lt;br /&gt;
			btn--;&lt;br /&gt;
			if(btn == 0)&lt;br /&gt;
			{&lt;br /&gt;
				if(prog_active==PROGRAM_IDLE &amp;amp;&amp;amp; program_it == PROGRAM_IDLE)			&lt;br /&gt;
					program_it=PROGRAM_ABORT;&lt;br /&gt;
			}&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
/*  ***********************************************************************************&lt;br /&gt;
	SERIAL MIDI INTERFACE &lt;br /&gt;
*/&lt;br /&gt;
&lt;br /&gt;
#define SYSEX 			0xF0&lt;br /&gt;
#define SYSEND			0xF7&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define FRAMING_ERROR (1&amp;lt;&amp;lt;FE0)&lt;br /&gt;
#define PARITY_ERROR (1&amp;lt;&amp;lt;UPE0)&lt;br /&gt;
#define DATA_OVERRUN (1&amp;lt;&amp;lt;DOR0)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
#define STAT_IDLE 	  0&lt;br /&gt;
#define STAT_INSYSEX1 1&lt;br /&gt;
#define STAT_INSYSEX2 2&lt;br /&gt;
#define STAT_INSYSEX3 3&lt;br /&gt;
#define STAT_INSYSEX4 4&lt;br /&gt;
#define STAT_INSYSEX5 5&lt;br /&gt;
#define STAT_INSYSEX6 6&lt;br /&gt;
#define STAT_PROGRAM_BYTES 7&lt;br /&gt;
#define STAT_WAITEND 8&lt;br /&gt;
#define STAT_ERROR 9&lt;br /&gt;
&lt;br /&gt;
unsigned char rx_buf[68]; // 1Byte Block-Adress,  64 Data-Bytes, 2Byte CRC &lt;br /&gt;
&lt;br /&gt;
// USART Receiver interrupt service routine&lt;br /&gt;
ISR(USART_RX_vect) &lt;br /&gt;
{&lt;br /&gt;
	static unsigned char status, error, current_block,num_blocks; &lt;br /&gt;
//	static unsigned char nibble_cnt,  data;&lt;br /&gt;
	static unsigned short int runningByte; // no joke, this accumulates our 8-bit-bytes from 7bit midi, so it must hold up to 14bit in between... &lt;br /&gt;
	static unsigned char byte_cnt,bits;&lt;br /&gt;
&lt;br /&gt;
	static unsigned short int crc;&lt;br /&gt;
	unsigned char rxStat,byte;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
    rxStat = UCSR0A;&lt;br /&gt;
    byte   = UDR0;&lt;br /&gt;
&lt;br /&gt;
    if ((rxStat &amp;amp; (FRAMING_ERROR | PARITY_ERROR | DATA_OVERRUN))==0 )&lt;br /&gt;
	{&lt;br /&gt;
		if(status &amp;gt; STAT_IDLE)&lt;br /&gt;
			dataRx=DATARX; &lt;br /&gt;
			 &lt;br /&gt;
		if (byte &amp;gt; 0x7F )		// Command byte &lt;br /&gt;
		{&lt;br /&gt;
			if( byte &amp;lt; 0xF8 ) // no Real-Time Message &lt;br /&gt;
			{&lt;br /&gt;
				if(byte == SYSEX )	// Start&lt;br /&gt;
				{&lt;br /&gt;
					status=STAT_INSYSEX1;&lt;br /&gt;
				}&lt;br /&gt;
				else if(byte==SYSEND)  // SysEx-End (might not be ours)&lt;br /&gt;
				{&lt;br /&gt;
					if( status==STAT_PROGRAM_BYTES)	// properly framed SysEx received &lt;br /&gt;
					{&lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
						if(crc==0 ) &lt;br /&gt;
						{&lt;br /&gt;
							unsigned char i;&lt;br /&gt;
&lt;br /&gt;
							if(rx_buf[0]==0 &amp;amp;&amp;amp; byte_cnt==6 ) // first block = info block&lt;br /&gt;
							{&lt;br /&gt;
								error=0;&lt;br /&gt;
								current_block=1;&lt;br /&gt;
								num_blocks=rx_buf[1];&lt;br /&gt;
								for(i=0;i&amp;lt;2;i++)&lt;br /&gt;
									flash_buf[i]=rx_buf[i+2];&lt;br /&gt;
								program_it=PROGRAM_START;&lt;br /&gt;
		&lt;br /&gt;
							}&lt;br /&gt;
							else if(byte_cnt==67 &amp;amp;&amp;amp; current_block==rx_buf[0] ) &lt;br /&gt;
							{	// Programm Data Block &lt;br /&gt;
&lt;br /&gt;
								for(i=0;i&amp;lt;64;i++)&lt;br /&gt;
									flash_buf[i]=rx_buf[i+1];&lt;br /&gt;
								blockAdress=rx_buf[0]-1;&lt;br /&gt;
&lt;br /&gt;
								if(!error)&lt;br /&gt;
								{&lt;br /&gt;
									if(num_blocks==current_block)&lt;br /&gt;
									{&lt;br /&gt;
										program_it=PROGRAM_FINISH;&lt;br /&gt;
									}&lt;br /&gt;
									else &lt;br /&gt;
									{&lt;br /&gt;
										program_it=PROGRAM_DO;									&lt;br /&gt;
									}&lt;br /&gt;
								}&lt;br /&gt;
								current_block++;&lt;br /&gt;
							}&lt;br /&gt;
							else&lt;br /&gt;
							{&lt;br /&gt;
								status=STAT_ERROR;&lt;br /&gt;
							}&lt;br /&gt;
						}&lt;br /&gt;
						else &lt;br /&gt;
							status=STAT_ERROR;&lt;br /&gt;
					}&lt;br /&gt;
					else // not my frame format  &lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
				}&lt;br /&gt;
				else 	// some other Status byte &lt;br /&gt;
				{&lt;br /&gt;
					if(status!=STAT_IDLE)&lt;br /&gt;
					{&lt;br /&gt;
						if(status&amp;lt;STAT_PROGRAM_BYTES) // might be unrelated to us &lt;br /&gt;
							status=STAT_IDLE;&lt;br /&gt;
						else &lt;br /&gt;
							status=STAT_ERROR; // our Data gets messed up &lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			} // no real time message &lt;br /&gt;
		}&lt;br /&gt;
		else // Data Byte&lt;br /&gt;
		{&lt;br /&gt;
			switch(status)&lt;br /&gt;
			{&lt;br /&gt;
				default:	// should never happen&lt;br /&gt;
					status=STAT_ERROR;&lt;br /&gt;
				case STAT_IDLE: // any Data which is not in our SysExFrame &lt;br /&gt;
					break; &lt;br /&gt;
				case STAT_INSYSEX1: // Manufacturer &lt;br /&gt;
					if(byte==0x70)&lt;br /&gt;
					{&lt;br /&gt;
						status=STAT_INSYSEX2;&lt;br /&gt;
					}&lt;br /&gt;
					else &lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
					break;&lt;br /&gt;
				case STAT_INSYSEX2:	// Unit ID&lt;br /&gt;
					if(byte==0x7D)&lt;br /&gt;
					{&lt;br /&gt;
						status=STAT_INSYSEX4;&lt;br /&gt;
					}&lt;br /&gt;
					else &lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
					break;&lt;br /&gt;
				case STAT_INSYSEX4:	// Unit Adress (ignored) &lt;br /&gt;
					if(byte&amp;lt; 0x10)&lt;br /&gt;
					{	status=STAT_INSYSEX5;&lt;br /&gt;
					}&lt;br /&gt;
					else &lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
					break;&lt;br /&gt;
				case STAT_INSYSEX5:	// &amp;quot;Data Adress&amp;quot; (magic byte 1) &lt;br /&gt;
					if(byte == 0x15)&lt;br /&gt;
					{&lt;br /&gt;
						status=STAT_INSYSEX6;&lt;br /&gt;
					}&lt;br /&gt;
					else &lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
					break;&lt;br /&gt;
				case STAT_INSYSEX6:	// magic byte 2 (this would stop the regular SysEx Decoder from taking this as data) &lt;br /&gt;
					if(byte == 0x55)&lt;br /&gt;
					{&lt;br /&gt;
						status=STAT_PROGRAM_BYTES;&lt;br /&gt;
						crc=0xffff;&lt;br /&gt;
						byte_cnt=0;&lt;br /&gt;
						bits=0;&lt;br /&gt;
					}&lt;br /&gt;
					else &lt;br /&gt;
						status=STAT_IDLE;&lt;br /&gt;
					break;&lt;br /&gt;
				case STAT_PROGRAM_BYTES:	// we&amp;#039;ve made it: now the new flash data rolls in 			&lt;br /&gt;
					runningByte &amp;lt;&amp;lt;=7;&lt;br /&gt;
					runningByte|=byte;&lt;br /&gt;
					bits+=7;&lt;br /&gt;
					if(bits&amp;gt;=8) // if enough for one Byte &lt;br /&gt;
					{&lt;br /&gt;
						unsigned char b;&lt;br /&gt;
&lt;br /&gt;
						bits-=8;&lt;br /&gt;
						b=runningByte&amp;gt;&amp;gt;bits;&lt;br /&gt;
						rx_buf[byte_cnt]=b;&lt;br /&gt;
						crc=_crc16_update(crc,b);&lt;br /&gt;
						if(++byte_cnt&amp;gt;67)&lt;br /&gt;
							status=STAT_ERROR;&lt;br /&gt;
					}&lt;br /&gt;
					break;&lt;br /&gt;
			} // switch status&lt;br /&gt;
		}	// data byte&lt;br /&gt;
	}&lt;br /&gt;
	else // any Rx-Erros =&amp;gt; abort &lt;br /&gt;
		status=STAT_ERROR;&lt;br /&gt;
	&lt;br /&gt;
	if(status==STAT_ERROR)&lt;br /&gt;
	{&lt;br /&gt;
		status=STAT_IDLE;&lt;br /&gt;
		error=1;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;/div&gt;</summary>
		<author><name>Fetz</name></author>
	</entry>
</feed>