diff --git a/README.md b/README.md
index 8629481..581a0ac 100644
--- a/README.md
+++ b/README.md
@@ -34,3 +34,4 @@ The code repository contains
* Firmware: The complete firmware including a modified Atmel DFU bootloader and LUFA
* Software: Contains a python tool for an easy configuration (and more) of the ChameleonMini, Note that this is currently under construction
* RevE: Contains the whole contents of the discontinued RevE repository.
+* RevE-light: Contains our development files for the RevE-light - **WARNING:** currently not supported / not functional
diff --git a/RevE-light/EAGLE/RevE-light-board.pdf b/RevE-light/EAGLE/RevE-light-board.pdf
new file mode 100644
index 0000000..e63799b
Binary files /dev/null and b/RevE-light/EAGLE/RevE-light-board.pdf differ
diff --git a/RevE-light/EAGLE/RevE-light-schematic.pdf b/RevE-light/EAGLE/RevE-light-schematic.pdf
new file mode 100644
index 0000000..a312763
Binary files /dev/null and b/RevE-light/EAGLE/RevE-light-schematic.pdf differ
diff --git a/RevE-light/EAGLE/RevE-light.brd b/RevE-light/EAGLE/RevE-light.brd
new file mode 100644
index 0000000..636e750
--- /dev/null
+++ b/RevE-light/EAGLE/RevE-light.brd
@@ -0,0 +1,2459 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ON
+OFF
+RevE light
+RevE light
+
+
+
+
+
+
+
+V+
+VCC
++UB
+
+
+
+
+
+
+
+
+
+
+This is an unsupported development version, and NOT YET FUNCTIONAL!
+
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 1206 reflow solder</b><p>
+Metric Code Size 3216
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 0603 reflow solder</b><p>
+Metric Code Size 1608
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.10 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>INDUCTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<b>Small Outline Transistor; 6 leads</b><p>
+Philips Semiconductors, SOT363.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<B>DIODE</B>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<b>SOT-23</b>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<b>SOT-23</b>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>Trimm capacitor</b> AVX
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<b>Thin Quad Flat Pack</b><p>
+package type TQ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SMT SC70-5</b><p>
+SOT353 - Philips Semiconductors<br>
+Source: http://www.semiconductors.philips.com/acrobat_download/datasheets/74HC_HCT1G66_3.pdf
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>Small Outline Diode</b>
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>LEDs</b><p>
+<author>Created by librarian@cadsoft.de</author><br>
+Extended by Federico Battaglin <author><federico.rd@fdpinternational.com></author> with DUOLED
+
+
+<b>CHIPLED</b><p>
+Source: http://www.osram.convergy.de/ ... LG_LY Q971.pdf
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Outline Transistor; 6 leads</b><p>
+Philips Semiconductors, SOT363.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Outline Transistor</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<b>SMALL OUTLINE TRANSISTOR</b><p>
+reflow soldering
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<b>Test Pins/Pads</b><p>
+Cream on SMD OFF.<br>
+new: Attribute TP_SIGNAL_NAME<br>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Dirty Cheap Dirty Board Design Rules</b>
+<br>
+<br>Min width/Spacing: 5/5mil
+<br>Min diameter of finished hole 12mil
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/RevE-light/EAGLE/RevE-light.sch b/RevE-light/EAGLE/RevE-light.sch
new file mode 100644
index 0000000..2d92e3a
--- /dev/null
+++ b/RevE-light/EAGLE/RevE-light.sch
@@ -0,0 +1,12624 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b> wave soldering<p>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+wave soldering
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+Source: http://download.siliconexpert.com/pdfs/2005/02/24/Semi_Ap/2/VSH/Resistor/dcrcwfre.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b> wave soldering<p>
+Source: http://download.siliconexpert.com/pdfs/2005/02/24/Semi_Ap/2/VSH/Resistor/dcrcwfre.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.10 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.12 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.10 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.12 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+MELF 0.25 W
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0204, grid 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0204, grid 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0204, grid 2.5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 10 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 12 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 15mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 2.5 mm
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 5 mm
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0207, grid 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0309, grid 10mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0309, grid 12.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0309, grid 2.5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0411, grid 12.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0411, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0411, grid 3.81 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0414, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0414, grid 5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0617, grid 17.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0617, grid 22.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0617, grid 5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0922, grid 22.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>RESISTOR</b><p>
+type 0613, grid 5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b><p>
+type 0613, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type 0817, grid 22.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+0817
+
+
+
+
+<b>RESISTOR</b><p>
+type 0817, grid 6.35 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+0817
+
+
+
+<b>RESISTOR</b><p>
+type V234, grid 12.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type V235, grid 17.78 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>RESISTOR</b><p>
+type V526-0, grid 2.5 mm
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC2211</b> Reflow Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC2211</b> Wave Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC3715</b> Reflow Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC3715</b> Wave Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC6123</b> Reflow Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CECC Size RC6123</b> Wave Soldering<p>
+source Beyschlag
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>RESISTOR</b><p>
+type 0922, grid 7.5 mm
+
+
+
+
+
+
+>NAME
+>VALUE
+0922
+
+
+
+<b>RESISTOR</b><p>
+type RDH, grid 15 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+RDH
+
+
+
+
+<b>Mini MELF 0102 Axial</b>
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>RESISTOR</b> chip<p>
+Source: http://www.vishay.com/docs/20008/dcrcw.pdf
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR52<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR53<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR54<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR55<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RBR56<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RNC55<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Bulk Metal® Foil Technology</b>, Tubular Axial Lead Resistors, Meets or Exceeds MIL-R-39005 Requirements<p>
+MIL SIZE RNC60<br>
+Source: VISHAY .. vta56.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Package 4527</b><p>
+Source: http://www.vishay.com/docs/31059/wsrhigh.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Wirewound Resistors, Precision Power</b><p>
+Source: VISHAY wscwsn.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CRCW1218 Thick Film, Rectangular Chip Resistors</b><p>
+Source: http://www.vishay.com .. dcrcw.pdf
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b><p>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm, outline 2.4 x 4.4 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm, outline 2.5 x 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm, outline 3 x 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm, outline 4 x 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm, outline 5 x 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm, outline 6 x 5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 mm + 5 mm, outline 2.4 x 7 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 + 5 mm, outline 2.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 + 5 mm, outline 3.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 + 5 mm, outline 4.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 2.5 + 5 mm, outline 5.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 2.4 x 4.4 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 2.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 4.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 3 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 5.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 7.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+Horizontal, grid 5 mm, outline 7.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>CAPACITOR</b><p>
+grid 7.5 mm, outline 3.2 x 10.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 7.5 mm, outline 4.2 x 10.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 7.5 mm, outline 5.2 x 10.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 10.2 mm, outline 4.3 x 13.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 10.2 mm, outline 5.4 x 13.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 10.2 mm, outline 6.4 x 13.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 10.2 mm + 15.2 mm, outline 6.2 x 18.4 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 15 mm, outline 5.4 x 18.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 15 mm, outline 6.4 x 18.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 15 mm, outline 7.2 x 18.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 15 mm, outline 8.4 x 18.3 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 15 mm, outline 9.1 x 18.2 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 22.5 mm, outline 6.2 x 26.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 22.5 mm, outline 7.4 x 26.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 22.5 mm, outline 8.7 x 26.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 22.5 mm, outline 10.8 x 26.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 22.5 mm, outline 11.3 x 26.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 27.5 mm, outline 9.3 x 31.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 27.5 mm, outline 11.3 x 31.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 27.5 mm, outline 13.4 x 31.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 27.5 mm, outline 20.5 x 31.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 32.5 mm, outline 13.7 x 37.4 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 32.5 mm, outline 16.2 x 37.4 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 32.5 mm, outline 18.2 x 37.4 mm
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 37.5 mm, outline 19.2 x 41.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 37.5 mm, outline 20.3 x 41.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 5 mm, outline 3.5 x 7.5 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 37.5 mm, outline 15.5 x 41.8 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 7.5 mm, outline 6.3 x 10.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 27.5 mm, outline 15.4 x 31.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>CAPACITOR</b><p>
+grid 27.5 mm, outline 17.3 x 31.6 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Ceramic Chip Capacitor KEMET 0204 reflow solder</b><p>
+Metric Code Size 1005
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 0603 reflow solder</b><p>
+Metric Code Size 1608
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 0805 reflow solder</b><p>
+Metric Code Size 2012
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 1206 reflow solder</b><p>
+Metric Code Size 3216
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 1210 reflow solder</b><p>
+Metric Code Size 3225
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 1812 reflow solder</b><p>
+Metric Code Size 4532
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 1825 reflow solder</b><p>
+Metric Code Size 4564
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 2220 reflow solder</b><p>Metric Code Size 5650
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Ceramic Chip Capacitor KEMET 2225 reflow solder</b><p>Metric Code Size 5664
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b> </b><p>
+Source: http://www.vishay.com/docs/10129/hpc0201a.pdf
+
+
+>NAME
+>VALUE
+
+
+
+Source: http://www.avxcorp.com/docs/catalogs/cx5r.pdf
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>INDUCTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>INDUCTOR</b><p>
+precision wire wound
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>INDUCTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>INDUCTOR</b><p>
+molded
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+precision wire wound
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+molded
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+molded
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>INDUCTOR</b><p>
+molded
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+precision wire wound
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+precision wire wound
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+molded
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+molded
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<b>INDUCTOR</b><p>
+chip
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Inductor</b><p>
+Source: TJ-Serie Vishay.pdf
+
+
+
+>NAME
+>VALUE
+
+
+<b>POWER-CHOKE WE-TPC</b><p>
+Würth Elektronik, Partnumber: 744053220<br>
+Source: WE-TPC 744053220.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>newport components</b> 2200 Serie RM 12.7 mm<p>
+Miniatur Axial Lead Inductors<br>
+Source: www.rsonline.de<br>
+Order code 240-517
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>newport components</b> 2200 Serie RM 15.24 mm<p>
+Miniatur Axial Lead Inductors<br>
+Source: www.rsonline.de<br>
+Order code 240-517
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>newport components</b> 2200 Serie RM 11.43 mm<p>
+Miniatur Axial Lead Inductors<br>
+Source: www.rsonline.de<br>
+Order code 240-517
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>POWER INDUCTORS</b> (SMT Type)<p>
+Source: www.sumida.com/products/pdf/CEP125.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>NIS02 Chip Inductor</b><p>
+Source: http://www.niccomp.com/Catalog/nis.pdf
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>PIS 2826</b> Inductor<p>
+Source: http://www.stetco.com/products/inductors/pdf/PIS2816.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. ir.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. ir.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. irf.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. irf.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. irf24.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. irf36.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>Vishay Dale Inductor</b><p>
+Source: www.vishay.com .. irf46.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>TAYO YUDEN Inductor</b><p>
+Source: je999f5.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Axial Conformal Coated Inductor</b><p>
+Source: TOP MAGNETICS CORPORATION .. tfi.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Axial Conformal Coated Inductor</b><p>
+Source: TOP MAGNETICS CORPORATION .. tfi.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Axial Conformal Coated Inductor</b><p>
+Source: TOP MAGNETICS CORPORATION .. tfi.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Axial Conformal Coated Inductor</b><p>
+Source: TOP MAGNETICS CORPORATION .. tfi.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>Axial Conformal Coated Inductor</b><p>
+Source: TOP MAGNETICS CORPORATION .. tfi.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>CAPACITOR</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>Chip Monolithic Ceramic Capacitors</b> Medium Voltage High Capacitance for General Use<p>
+Source: http://www.murata.com .. GRM43DR72E224KW01.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<B>INDUCTOR</B>, European symbol
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<B>RESISTOR</B>, European symbol
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<B>CAPACITOR</B>, European symbol
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+
+
+
+
+
+>VALUE
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SOT143 / SOT143B Reflow soldering</b><p>
+Source: Philips SC01_Mounting_1996.pdf / BAS70_1PS7XSB70_SER_8.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>Small Outline Transistor; 6 leads</b><p>
+Philips Semiconductors, SOT363.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<b>SOT 666 Reflow soldering foorprint</b><p>
+Source: Philips - BAS70_1PS7XSB70_SER_8.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 2 mm, horizontal, grid 10.16mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 2.54 mm, horizontal, grid 10.16 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 3.5 mm, horizontal, grid 15.24 mm
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 6.35 mm metall, horizontal, grid 20.32 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 4 mm, vertical, grid 10.16 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 1.8 mm, horizontal, grid 7.62 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 4.8 mm, vertical, grid 10.16 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 4.8 mm, vertical, grid 12.7 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+3-lead smd
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 3 mm, horizontal, grid 10.16 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B><p>
+diameter 3 mm, horizontal, grid 12.7 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>Z DIODE</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Z DIODE</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Z DIODE</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Z DIODE</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>Z DIODE</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>DIODE</B><p>
+diameter 3 mm, horizontal, grid 12.7 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<B>DIODE</B>
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>Small Outline Transistor</b>
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+<B>DIODE</B>
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+<b>Silicon Schottky Diodes</b><p>
+General-purpose diode for high-speed switching<br>
+Source: BAS70_1PS7XSB70_SER_8.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Z-Diode
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SOT-23</b>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+<b>N-CHANNEL MOS FET</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>DRAWING_NAME
+>LAST_DATE_TIME
+>SHEET
+Sheet:
+
+
+
+
+
+<b>FRAME</b><p>
+DIN A4, landscape with location and doc. field
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SOT-23</b>
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<b>NPN Transistor</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Trimm capacitor</b> AVX
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Thin Quad Flat Pack</b><p>
+package type TQ
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Plastic Small Outline</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+CHECK!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Outline Transistor</b><p>
+SOT753 - Philips Semiconductors<br>
+Source: http://www.semiconductors.philips.com/acrobat_download/datasheets/74HC_HCT1G66_3.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>SMT SC70-5</b><p>
+SOT353 - Philips Semiconductors<br>
+Source: http://www.semiconductors.philips.com/acrobat_download/datasheets/74HC_HCT1G66_3.pdf
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+>NAME
+GND
+VCC
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+e
+
+
+
+
+
+
+
+2-input <b>AND</b> gate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+2-input <b>EXCLUSIV-OR</b> gate
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Outline Diode</b>
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>LEDs</b><p>
+<author>Created by librarian@cadsoft.de</author><br>
+Extended by Federico Battaglin <author><federico.rd@fdpinternational.com></author> with DUOLED
+
+
+<b>CHIPLED</b><p>
+Source: http://www.osram.convergy.de/ ... LG_LY Q971.pdf
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>CHICAGO MINIATURE LAMP, INC.</b><p>
+7022X Series SMT LEDs 1206 Package Size
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<B>LED</B><p>
+5 mm, square, Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>LED</B><p>
+2 x 5 mm, rectangle
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+<B>LED</B><p>
+3 mm, round
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>LED</B><p>
+5 mm, round
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>LED</B><p>
+1 mm, round, Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<B>LED BLOCK</B><p>
+1 LED, Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+<b>LED HOLDER</b><p>
+Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>LED HOLDER</b><p>
+Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>LED HOLDER</b><p>
+Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A+
+K-
+>NAME
+>VALUE
+
+
+
+
+
+<b>LED HOLDER</b><p>
+Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
++
+-
+
+
+<B>IR LED</B><p>
+infrared emitting diode, Infineon
+TO-18, lead spacing 2.54 mm, cathode marking<p>
+Inifineon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>IR LED</B><p>
+infrared emitting diode, Infineon
+TO-18, lead spacing 2.54 mm, cathode marking<p>
+Inifineon
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>LED</B><p>
+rectangle, 5.7 x 3.2 mm
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<B>IR LED</B><p>
+IR transmitter Siemens
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>TOPLED® High-optical Power LED (HOP)</b><p>
+Source: http://www.osram.convergy.de/ ... ls_t675.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+A
+C
+
+
+
+
+
+
+
+<b>BLUE LINETM Hyper Mini TOPLED® Hyper-Bright LED</b><p>
+Source: http://www.osram.convergy.de/ ... LB M676.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+A
+C
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>Super SIDELED® High-Current LED</b><p>
+LG A672, LP A672 <br>
+Source: http://www.osram.convergy.de/ ... LG_LP_A672.pdf (2004.05.13)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+C
+A
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>SmartLEDTM Hyper-Bright LED</b><p>
+Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY L896.pdf
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+<b>Hyper TOPLED® RG Hyper-Bright LED</b><p>
+Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY T776.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+A
+C
+
+
+
+
+
+
+
+
+
+
+<b>Hyper Micro SIDELED®</b><p>
+Source: http://www.osram.convergy.de/ ... LA_LO_LS_LY Y876.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+<b>Power TOPLED®</b><p>
+Source: http://www.osram.convergy.de/ ... LA_LO_LA_LY E67B.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+C
+A
+C
+C
+
+
+
+
+
+
+
+
+
+
+
+<b>Hyper CHIPLED Hyper-Bright LED</b><p>
+LB Q993<br>
+Source: http://www.osram.convergy.de/ ... Lb_q993.pdf
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>Hyper CHIPLED Hyper-Bright LED</b><p>
+LB R99A<br>
+Source: http://www.osram.convergy.de/ ... lb_r99a.pdf
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+<b>Mini TOPLED Santana®</b><p>
+Source: http://www.osram.convergy.de/ ... LG M470.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+<b>CHIPLED</b><p>
+Source: http://www.osram.convergy.de/ ... LG_R971.pdf
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>CHIPLED</b><p>
+Source: http://www.osram.convergy.de/ ... LG_LY N971.pdf
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>CHIPLED-0603</b><p>
+Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br>
+Package able to withstand TTW-soldering heat<br>
+Package suitable for TTW-soldering<br>
+Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SmartLED TTW</b><p>
+Recommended Solder Pad useable for SmartLEDTM and Chipled - Package 0603<br>
+Package able to withstand TTW-soldering heat<br>
+Package suitable for TTW-soldering<br>
+Source: http://www.osram.convergy.de/ ... LO_LS_LY L89K.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<b>Lumileds Lighting. LUXEON®</b> with cool pad<p>
+Source: K2.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Lumileds Lighting. LUXEON®</b> without cool pad<p>
+Source: K2.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<B>LED</B><p>
+10 mm, round
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>SURFACE MOUNT LED LAMP</b> 3.5x2.8mm<p>
+Source: http://www.kingbright.com/manager/upload/pdf/KA-3528ASYC(Ver1189474662.1)
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SML0805-2CW-TR (0805 PROFILE)</b> COOL WHITE<p>
+Source: http://www.ledtronics.com/ds/smd-0603/Dstr0093.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+<b>SML10XXKH-TR (HIGH INTENSITY) LED</b><p>
+<table>
+<tr><td>SML10R3KH-TR</td><td>ULTRA RED</td></tr>
+<tr><td>SML10E3KH-TR</td><td>SUPER REDSUPER BLUE</td></tr>
+<tr><td>SML10O3KH-TR</td><td>SUPER ORANGE</td></tr>
+<tr><td>SML10PY3KH-TR</td><td>PURE YELLOW</td></tr>
+<tr><td>SML10OY3KH-TR</td><td>ULTRA YELLOW</td></tr>
+<tr><td>SML10AG3KH-TR</td><td>AQUA GREEN</td></tr>
+<tr><td>SML10BG3KH-TR</td><td>BLUE GREEN</td></tr>
+<tr><td>SML10PB1KH-TR</td><td>SUPER BLUE</td></tr>
+<tr><td>SML10CW1KH-TR</td><td>WHITE</td></tr>
+</table>
+
+Source: http://www.ledtronics.com/ds/smd-1206/dstr0094.PDF
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+<b>SML0603-XXX (HIGH INTENSITY) LED</b><p>
+<table>
+<tr><td>AG3K</td><td>AQUA GREEN</td></tr>
+<tr><td>B1K</td><td>SUPER BLUE</td></tr>
+<tr><td>R1K</td><td>SUPER RED</td></tr>
+<tr><td>R3K</td><td>ULTRA RED</td></tr>
+<tr><td>O3K</td><td>SUPER ORANGE</td></tr>
+<tr><td>O3KH</td><td>SOFT ORANGE</td></tr>
+<tr><td>Y3KH</td><td>SUPER YELLOW</td></tr>
+<tr><td>Y3K</td><td>SUPER YELLOW</td></tr>
+<tr><td>2CW</td><td>WHITE</td></tr>
+</table>
+Source: http://www.ledtronics.com/ds/smd-0603/Dstr0092.pdf
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>LED</b><p>
+<u>OSRAM</u>:<br>
+
+- <u>CHIPLED</u><br>
+LG R971, LG N971, LY N971, LG Q971, LY Q971, LO R971, LY R971
+LH N974, LH R974<br>
+LS Q976, LO Q976, LY Q976<br>
+LO Q996<br>
+
+- <u>Hyper CHIPLED</u><br>
+LW Q18S<br>
+LB Q993, LB Q99A, LB R99A<br>
+
+- <u>SideLED</u><br>
+LS A670, LO A670, LY A670, LG A670, LP A670<br>
+LB A673, LV A673, LT A673, LW A673<br>
+LH A674<br>
+LY A675<br>
+LS A676, LA A676, LO A676, LY A676, LW A676<br>
+LS A679, LY A679, LG A679<br>
+
+- <u>Hyper Micro SIDELED®</u><br>
+LS Y876, LA Y876, LO Y876, LY Y876<br>
+LT Y87S<br>
+
+- <u>SmartLED</u><br>
+LW L88C, LW L88S<br>
+LB L89C, LB L89S, LG L890<br>
+LS L89K, LO L89K, LY L89K<br>
+LS L896, LA L896, LO L896, LY L896<br>
+
+- <u>TOPLED</u><br>
+LS T670, LO T670, LY T670, LG T670, LP T670<br>
+LSG T670, LSP T670, LSY T670, LOP T670, LYG T670<br>
+LG T671, LOG T671, LSG T671<br>
+LB T673, LV T673, LT T673, LW T673<br>
+LH T674<br>
+LS T676, LA T676, LO T676, LY T676, LB T676, LH T676, LSB T676, LW T676<br>
+LB T67C, LV T67C, LT T67C, LS T67K, LO T67K, LY T67K, LW E67C<br>
+LS E67B, LA E67B, LO E67B, LY E67B, LB E67C, LV E67C, LT E67C<br>
+LW T67C<br>
+LS T679, LY T679, LG T679<br>
+LS T770, LO T770, LY T770, LG T770, LP T770<br>
+LB T773, LV T773, LT T773, LW T773<br>
+LH T774<br>
+LS E675, LA E675, LY E675, LS T675<br>
+LS T776, LA T776, LO T776, LY T776, LB T776<br>
+LHGB T686<br>
+LT T68C, LB T68C<br>
+
+- <u>Hyper Mini TOPLED®</u><br>
+LB M676<br>
+
+- <u>Mini TOPLED Santana®</u><br>
+LG M470<br>
+LS M47K, LO M47K, LY M47K
+<p>
+Source: http://www.osram.convergy.de<p>
+
+<u>LUXEON:</u><br>
+- <u>LUMILED®</u><br>
+LXK2-PW12-R00, LXK2-PW12-S00, LXK2-PW14-U00, LXK2-PW14-V00<br>
+LXK2-PM12-R00, LXK2-PM12-S00, LXK2-PM14-U00<br>
+LXK2-PE12-Q00, LXK2-PE12-R00, LXK2-PE12-S00, LXK2-PE14-T00, LXK2-PE14-U00<br>
+LXK2-PB12-K00, LXK2-PB12-L00, LXK2-PB12-M00, LXK2-PB14-N00, LXK2-PB14-P00, LXK2-PB14-Q00<br>
+LXK2-PR12-L00, LXK2-PR12-M00, LXK2-PR14-Q00, LXK2-PR14-R00<br>
+LXK2-PD12-Q00, LXK2-PD12-R00, LXK2-PD12-S00<br>
+LXK2-PH12-R00, LXK2-PH12-S00<br>
+LXK2-PL12-P00, LXK2-PL12-Q00, LXK2-PL12-R00
+<p>
+Source: www.luxeon.com<p>
+
+<u>KINGBRIGHT:</U><p>
+KA-3528ASYC<br>
+Source: www.kingbright.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Supply Symbols</b><p>
+GND, VCC, 0V, +5V, -5V, etc.<p>
+Please keep in mind, that these devices are necessary for the
+automatic wiring of the supply signals.<p>
+The pin name defined in the symbol is identical to the net which is to be wired automatically.<p>
+In this library the device names are the same as the pin names of the symbols, therefore the correct signal names appear next to the supply symbols in the schematic.<p>
+<author>Created by librarian@cadsoft.de</author>
+
+
+
+
+
+
+
+>VALUE
+
+
+
+
+
+>VALUE
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SUPPLY SYMBOL</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Outline Transistor; 6 leads</b><p>
+Philips Semiconductors, SOT363.pdf
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>VALUE
+>NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Small Outline Transistor</b>
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+>Name
+>Value
+
+
+
+
+
+
+
+
+
+<h3> Microchip's MCP73831</h3>
+Miniature single cell, fully integrated Li-Ion, Li-polymer charge management controller<br>
+http://ww1.microchip.com/downloads/en/DeviceDoc/21984a.pdf
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>SMALL OUTLINE TRANSISTOR</b><p>
+reflow soldering
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>VALUE
+GND
+IN
+OUT
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<b>Test Pins/Pads</b><p>
+Cream on SMD OFF.<br>
+new: Attribute TP_SIGNAL_NAME<br>
+<author>Created by librarian@cadsoft.de</author>
+
+
+<b>TEST PAD</b>
+
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+<b>TEST PAD</b>
+
+>NAME
+>VALUE
+>TP_SIGNAL_NAME
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+>NAME
+>TP_SIGNAL_NAME
+
+
+
+
+
+
+<b>TEST PIN</b>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+1:20 Divider with 50R Termination
+Envelope Detector
+RSSI Lowpass
+AC-coupled Amp.
+Load Modulation
+Rectification
+USB Power Supply + ORing Diode
+Antenna + Tuning
+WARNING: this is a
+development version,
+and NOT YET
+FUNCTIONAL!!!
+N.M. = DO NOT MOUNT
+Unreg.
+input voltage
+A voltage > 6 V
+here will kill
+caps & charger
+was approx 0.6 V drop 22R @ 30mA
+changed to 3R
+approx 0.75V drop
+Replace with NXP BAT720
+WARNING: this is a development version, and NOT YET FUNCTIONAL!!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Regulated voltage for uC and other components
+Unregulated input voltage from USB or field
+Unreg. input
+LiIon 3.7 (nom.) / 4.2V (max.)
+Input to LDO
+Warning: Charger tolerates max. 6 V
+Should be clamped
+Series resistor after rectifier may protect a bit
+another 0.7 V drop
+-> 5V USB - 0.6 - 0.7 - 0.7
+ = 3 V
+WARNING: this is a
+development version,
+and NOT YET
+FUNCTIONAL!!!
+WARNING: this is a development version, and NOT YET FUNCTIONAL!!!
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Since Version 6.2.2 text objects can contain more than one line,
+which will not be processed correctly with this version.
+
+
+
diff --git a/RevE-light/EAGLE/WARNING.txt b/RevE-light/EAGLE/WARNING.txt
new file mode 100644
index 0000000..ae131bf
--- /dev/null
+++ b/RevE-light/EAGLE/WARNING.txt
@@ -0,0 +1 @@
+WARNING: The files in this folder are our current development version. The hardware and software is not functional yet - so do not use it. We will not answer any support inquiry regarding this version at the moment.
\ No newline at end of file
diff --git a/RevE-light/Firmware/.gitignore b/RevE-light/Firmware/.gitignore
new file mode 100644
index 0000000..e8d0311
--- /dev/null
+++ b/RevE-light/Firmware/.gitignore
@@ -0,0 +1 @@
+/.metadata
diff --git a/RevE-light/Firmware/Chameleon-Mini/.gitignore b/RevE-light/Firmware/Chameleon-Mini/.gitignore
new file mode 100644
index 0000000..a9d00d8
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/.gitignore
@@ -0,0 +1 @@
+/Bin
diff --git a/RevE-light/Firmware/Chameleon-Mini/AntennaLevel.h b/RevE-light/Firmware/Chameleon-Mini/AntennaLevel.h
new file mode 100644
index 0000000..6818ec9
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/AntennaLevel.h
@@ -0,0 +1,51 @@
+/*
+ * AntennaLevel.h
+ *
+ * Created on: 24.11.2013
+ * Author: skuser
+ */
+
+#ifndef ANTENNALEVEL_H_
+#define ANTENNALEVEL_H_
+
+#include "Common.h"
+
+#define ANTENNA_LEVEL_R1 10E3
+#define ANTENNA_LEVEL_R2 220E0
+#define ANTENNA_LEVEL_VREF 1.0
+#define ANTENNA_LEVEL_RES 4096
+#define ANTENNA_LEVEL_OFFSET 190 /* LSB */
+
+#define ANTENNA_LEVEL_MILLIVOLT 1E3
+#define ANTENNA_LEVEL_FACTOR (ANTENNA_LEVEL_VREF * (ANTENNA_LEVEL_R1 + ANTENNA_LEVEL_R2) / (ANTENNA_LEVEL_RES * ANTENNA_LEVEL_R2) )
+#define ANTENNA_LEVEL_SCALE ((uint32_t) 1<<16)
+#define ANTENNA_LEVEL_NUMERATOR ((uint32_t) (ANTENNA_LEVEL_MILLIVOLT * ANTENNA_LEVEL_FACTOR * ANTENNA_LEVEL_SCALE + .5))
+#define ANTENNA_LEVEL_DENOMINATOR (ANTENNA_LEVEL_SCALE)
+
+static inline
+void AntennaLevelInit(void)
+{
+ ADCA.CTRLA = ADC_ENABLE_bm;
+ ADCA.CTRLB = ADC_RESOLUTION_12BIT_gc;
+ ADCA.REFCTRL = ADC_REFSEL_INT1V_gc | ADC_BANDGAP_bm;
+ ADCA.PRESCALER = ADC_PRESCALER_DIV32_gc;
+ ADCA.CH0.CTRL = ADC_CH_INPUTMODE_SINGLEENDED_gc;
+ ADCA.CH0.MUXCTRL = ADC_CH_MUXPOS_PIN7_gc;
+
+}
+
+static inline
+uint16_t AntennaLevelGet(void)
+{
+ ADCA.CH0.CTRL |= ADC_CH_START_bm;
+ while( !(ADCA.CH0.INTFLAGS & ADC_CH_CHIF_bm) );
+
+ ADCA.CH0.INTFLAGS = ADC_CH_CHIF_bm;
+
+ int16_t Result = ADCA.CH0RES - ANTENNA_LEVEL_OFFSET;
+ if (Result < 0) Result = 0;
+
+ return (uint16_t) (((uint32_t) Result * ANTENNA_LEVEL_NUMERATOR) / ANTENNA_LEVEL_DENOMINATOR);
+}
+
+#endif /* ANTENNALEVEL_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/Application.h b/RevE-light/Firmware/Chameleon-Mini/Application/Application.h
new file mode 100644
index 0000000..0c70cfc
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/Application.h
@@ -0,0 +1,51 @@
+/*
+ * Application.h
+ *
+ * Created on: 18.02.2013
+ * Author: skuser
+ */
+
+#ifndef APPLICATION_H_
+#define APPLICATION_H_
+
+#include "../Common.h"
+#include "../Configuration.h"
+#include "../Log.h"
+
+/* Applications */
+#include "MifareUltralight.h"
+#include "MifareClassic.h"
+
+
+/* Function wrappers */
+INLINE void ApplicationInit(void) {
+ ActiveConfiguration.ApplicationInitFunc();
+}
+
+INLINE void ApplicationTask(void) {
+ ActiveConfiguration.ApplicationTaskFunc();
+}
+
+INLINE uint16_t ApplicationProcess(uint8_t* ByteBuffer, uint16_t ByteCount) {
+ return ActiveConfiguration.ApplicationProcessFunc(ByteBuffer, ByteCount);
+}
+
+INLINE void ApplicationTick(void) {
+ ActiveConfiguration.ApplicationTickFunc();
+}
+
+INLINE void ApplicationReset(void) {
+ ActiveConfiguration.ApplicationResetFunc();
+ //LogEntry(LOG_INFO_APP_RESET, NULL, 0);
+}
+
+INLINE void ApplicationGetUid(ConfigurationUidType Uid) {
+ ActiveConfiguration.ApplicationGetUidFunc(Uid);
+}
+
+INLINE void ApplicationSetUid(ConfigurationUidType Uid) {
+ ActiveConfiguration.ApplicationSetUidFunc(Uid);
+ LogEntry(LOG_INFO_UID_SET, Uid, ActiveConfiguration.UidSize);
+}
+
+#endif /* APPLICATION_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/Crypto1.c b/RevE-light/Firmware/Chameleon-Mini/Application/Crypto1.c
new file mode 100644
index 0000000..b35fcb0
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/Crypto1.c
@@ -0,0 +1,323 @@
+#include "Crypto1.h"
+
+#define PRNG_MASK 0x002D0000UL
+/* x^16 + x^14 + x^13 + x^11 + 1 */
+
+#define PRNG_SIZE 4 /* Bytes */
+
+#define LFSR_MASK_EVEN 0x2010E1UL
+#define LFSR_MASK_ODD 0x3A7394UL
+/* x^48 + x^43 + x^39 + x^38 + x^36 + x^34 + x^33 + x^31 + x^29 +
+ * x^24 + x^23 + x^21 + x^19 + x^13 + x^9 + x^7 + x^6 + x^5 + 1 */
+
+#define LFSR_SIZE 6 /* Bytes */
+
+/* Functions fa, fb and fc in filter output network. Definitions taken
+ * from Timo Kasper's thesis */
+#define FA(x3, x2, x1, x0) ( \
+ ( (x0 | x1) ^ (x0 & x3) ) ^ ( x2 & ( (x0 ^ x1) | x3 ) ) \
+)
+
+#define FB(x3, x2, x1, x0) ( \
+ ( (x0 & x1) | x2 ) ^ ( (x0 ^ x1) & (x2 | x3) ) \
+)
+
+#define FC(x4, x3, x2, x1, x0) ( \
+ ( x0 | ( (x1 | x4) & (x3 ^ x4) ) ) ^ ( ( x0 ^ (x1 & x3) ) & ( (x2 ^ x3) | (x1 & x4) ) ) \
+)
+
+/* Create tables from function fa, fb and fc for faster access */
+static const uint8_t TableAB[5][16] = {
+ { /* fa with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 0 */
+ FA(0,0,0,0) << 0, FA(0,0,0,1) << 0, FA(0,0,1,0) << 0, FA(0,0,1,1) << 0,
+ FA(0,1,0,0) << 0, FA(0,1,0,1) << 0, FA(0,1,1,0) << 0, FA(0,1,1,1) << 0,
+ FA(1,0,0,0) << 0, FA(1,0,0,1) << 0, FA(1,0,1,0) << 0, FA(1,0,1,1) << 0,
+ FA(1,1,0,0) << 0, FA(1,1,0,1) << 0, FA(1,1,1,0) << 0, FA(1,1,1,1) << 0,
+ },
+ { /* fb with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 1 */
+ FB(0,0,0,0) << 1, FB(0,0,0,1) << 1, FB(0,0,1,0) << 1, FB(0,0,1,1) << 1,
+ FB(0,1,0,0) << 1, FB(0,1,0,1) << 1, FB(0,1,1,0) << 1, FB(0,1,1,1) << 1,
+ FB(1,0,0,0) << 1, FB(1,0,0,1) << 1, FB(1,0,1,0) << 1, FB(1,0,1,1) << 1,
+ FB(1,1,0,0) << 1, FB(1,1,0,1) << 1, FB(1,1,1,0) << 1, FB(1,1,1,1) << 1,
+ },
+ { /* fb with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 2 */
+ FB(0,0,0,0) << 2, FB(0,0,0,1) << 2, FB(0,0,1,0) << 2, FB(0,0,1,1) << 2,
+ FB(0,1,0,0) << 2, FB(0,1,0,1) << 2, FB(0,1,1,0) << 2, FB(0,1,1,1) << 2,
+ FB(1,0,0,0) << 2, FB(1,0,0,1) << 2, FB(1,0,1,0) << 2, FB(1,0,1,1) << 2,
+ FB(1,1,0,0) << 2, FB(1,1,0,1) << 2, FB(1,1,1,0) << 2, FB(1,1,1,1) << 2,
+ },
+ { /* fa with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 3 */
+ FA(0,0,0,0) << 3, FA(0,0,0,1) << 3, FA(0,0,1,0) << 3, FA(0,0,1,1) << 3,
+ FA(0,1,0,0) << 3, FA(0,1,0,1) << 3, FA(0,1,1,0) << 3, FA(0,1,1,1) << 3,
+ FA(1,0,0,0) << 3, FA(1,0,0,1) << 3, FA(1,0,1,0) << 3, FA(1,0,1,1) << 3,
+ FA(1,1,0,0) << 3, FA(1,1,0,1) << 3, FA(1,1,1,0) << 3, FA(1,1,1,1) << 3,
+ },
+ { /* fb with Input {3,2,1,0} = (0,0,0,0) to (1,1,1,1) shifted by 4 */
+ FB(0,0,0,0) << 4, FB(0,0,0,1) << 4, FB(0,0,1,0) << 4, FB(0,0,1,1) << 4,
+ FB(0,1,0,0) << 4, FB(0,1,0,1) << 4, FB(0,1,1,0) << 4, FB(0,1,1,1) << 4,
+ FB(1,0,0,0) << 4, FB(1,0,0,1) << 4, FB(1,0,1,0) << 4, FB(1,0,1,1) << 4,
+ FB(1,1,0,0) << 4, FB(1,1,0,1) << 4, FB(1,1,1,0) << 4, FB(1,1,1,1) << 4,
+ }
+};
+
+static const uint8_t TableC[32] = {
+ /* fc with Input {4,3,2,1,0} = (0,0,0,0,0) to (1,1,1,1,1) */
+ FC(0,0,0,0,0), FC(0,0,0,0,1), FC(0,0,0,1,0), FC(0,0,0,1,1),
+ FC(0,0,1,0,0), FC(0,0,1,0,1), FC(0,0,1,1,0), FC(0,0,1,1,1),
+ FC(0,1,0,0,0), FC(0,1,0,0,1), FC(0,1,0,1,0), FC(0,1,0,1,1),
+ FC(0,1,1,0,0), FC(0,1,1,0,1), FC(0,1,1,1,0), FC(0,1,1,1,1),
+ FC(1,0,0,0,0), FC(1,0,0,0,1), FC(1,0,0,1,0), FC(1,0,0,1,1),
+ FC(1,0,1,0,0), FC(1,0,1,0,1), FC(1,0,1,1,0), FC(1,0,1,1,1),
+ FC(1,1,0,0,0), FC(1,1,0,0,1), FC(1,1,0,1,0), FC(1,1,0,1,1),
+ FC(1,1,1,0,0), FC(1,1,1,0,1), FC(1,1,1,1,0), FC(1,1,1,1,1),
+};
+
+/* Split Crypto1 state into even and odd bits to speed up the output filter network */
+static uint8_t StateEven[LFSR_SIZE/2] = {0};
+static uint8_t StateOdd[LFSR_SIZE/2] = {0};
+
+/* Proceed LFSR by one clock cycle */
+static void Crypto1LFSR(uint8_t In) {
+ uint8_t Feedback = 0;
+
+ /* Calculate feedback according to LFSR taps. XOR all 6 state bytes
+ * into a single bit. */
+ Feedback ^= StateEven[0] & (uint8_t) (LFSR_MASK_EVEN >> 0);
+ Feedback ^= StateEven[1] & (uint8_t) (LFSR_MASK_EVEN >> 8);
+ Feedback ^= StateEven[2] & (uint8_t) (LFSR_MASK_EVEN >> 16);
+
+ Feedback ^= StateOdd[0] & (uint8_t) (LFSR_MASK_ODD >> 0);
+ Feedback ^= StateOdd[1] & (uint8_t) (LFSR_MASK_ODD >> 8);
+ Feedback ^= StateOdd[2] & (uint8_t) (LFSR_MASK_ODD >> 16);
+
+ Feedback ^= Feedback >> 4;
+ Feedback ^= Feedback >> 2;
+ Feedback ^= Feedback >> 1;
+
+ /* Now the shifting of the Crypto1 state gets more complicated when
+ * split up into even/odd parts. After some hard thinking, one can
+ * see that after one LFSR clock cycle
+ * - the new even state becomes the old odd state
+ * - the new odd state becomes the old even state right-shifted by 1.
+ * For shifting the even state, we convert it into a 32 bit int first */
+ uint32_t Temp = 0;
+ Temp |= ((uint32_t) StateEven[0] << 0);
+ Temp |= ((uint32_t) StateEven[1] << 8);
+ Temp |= ((uint32_t) StateEven[2] << 16);
+
+ /* Proceed LFSR. Try to force compiler not to shift the unneded upper bits. */
+ Temp = (Temp >> 1) & 0x00FFFFFF;
+
+ /* Calculate MSBit of even state as input bit to LFSR */
+ if ( (Feedback & 0x01) ^ In ) {
+ Temp |= (uint32_t) 1 << (8 * LFSR_SIZE/2 - 1);
+ }
+
+ /* Convert even state back into byte array and swap odd/even state
+ * as explained above. */
+ StateEven[0] = StateOdd[0];
+ StateEven[1] = StateOdd[1];
+ StateEven[2] = StateOdd[2];
+
+ StateOdd[0] = (uint8_t) (Temp >> 0);
+ StateOdd[1] = (uint8_t) (Temp >> 8);
+ StateOdd[2] = (uint8_t) (Temp >> 16);
+}
+
+uint8_t Crypto1FilterOutput(void) {
+ /* Calculate the functions fa, fb.
+ * Note that only bits {4...23} of the odd state
+ * get fed into these function.
+ * The tables are designed to hold mask values, which
+ * can simply be ORed together to produce the resulting
+ * 5 bits that are used to lookup the output bit.
+ */
+ uint8_t Sum = 0;
+
+ Sum |= TableAB[0][(StateOdd[0] >> 4) & 0x0F];
+ Sum |= TableAB[1][(StateOdd[1] >> 0) & 0x0F];
+ Sum |= TableAB[2][(StateOdd[1] >> 4) & 0x0F];
+ Sum |= TableAB[3][(StateOdd[2] >> 0) & 0x0F];
+ Sum |= TableAB[4][(StateOdd[2] >> 4) & 0x0F];
+
+ return TableC[Sum];
+}
+
+void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4])
+{
+ uint8_t i;
+
+ /* Again, one trade off when splitting up the state into even/odd parts
+ * is that loading the key into the state becomes a little more difficult.
+ * The inner loop generates 8 even and 8 odd bits from 16 key bits and
+ * the outer loop stores them. */
+ for (i=0; i<(LFSR_SIZE/2); i++) {
+ uint8_t EvenByte = 0;
+ uint8_t OddByte = 0;
+ uint16_t KeyWord = ((uint16_t) Key[2*i+1] << 8) | Key[2*i+0];
+ uint8_t j;
+
+ for (j=0; j<8; j++) {
+ EvenByte >>= 1;
+ OddByte >>= 1;
+
+ if (KeyWord & (1<<0)) {
+ EvenByte |= 0x80;
+ }
+
+ if (KeyWord & (1<<1)) {
+ OddByte |= 0x80;
+ }
+
+ KeyWord >>= 2;
+ }
+
+ StateEven[i] = EvenByte;
+ StateOdd[i] = OddByte;
+ }
+
+ /* Use Uid XOR CardNonce as feed-in and do 32 clocks on the
+ * Crypto1 LFSR.*/
+ uint32_t Temp = 0;
+
+ Temp |= (uint32_t) (Uid[0] ^ CardNonce[0]) << 0;
+ Temp |= (uint32_t) (Uid[1] ^ CardNonce[1]) << 8;
+ Temp |= (uint32_t) (Uid[2] ^ CardNonce[2]) << 16;
+ Temp |= (uint32_t) (Uid[3] ^ CardNonce[3]) << 24;
+
+ for (i=0; i<32; i++) {
+ uint8_t Out = Crypto1FilterOutput();
+
+ Crypto1LFSR(Temp & 0x01);
+ Temp >>= 1;
+
+ /* Store the keystream for later use */
+ if (Out) {
+ Temp |= (uint32_t) 1 << 31;
+ }
+ }
+
+ /* Crypto1 state register is now set up to be used for authentication.
+ * In case of nested authentication, we need to use the produced keystream
+ * to encrypt the CardNonce. For this case we do the encryption in-place. */
+ CardNonce[0] ^= (uint8_t) (Temp >> 0);
+ CardNonce[1] ^= (uint8_t) (Temp >> 8);
+ CardNonce[2] ^= (uint8_t) (Temp >> 16);
+ CardNonce[3] ^= (uint8_t) (Temp >> 24);
+}
+
+void Crypto1Auth(uint8_t EncryptedReaderNonce[4])
+{
+ uint32_t Temp = 0;
+
+ /* For ease of processing, we convert the encrypted reader nonce
+ * into a 32 bit integer */
+ Temp |= (uint32_t) EncryptedReaderNonce[0] << 0;
+ Temp |= (uint32_t) EncryptedReaderNonce[1] << 8;
+ Temp |= (uint32_t) EncryptedReaderNonce[2] << 16;
+ Temp |= (uint32_t) EncryptedReaderNonce[3] << 24;
+
+ uint8_t i;
+
+ for (i=0; i<32; i++) {
+ /* Decrypt one output bit of the given encrypted nonce using the
+ * filter output as keystream. */
+ uint8_t Out = Crypto1FilterOutput();
+ uint8_t Bit = Out ^ (Temp & 0x01);
+
+ /* Feed back the bit to load the LFSR with the (decrypted) nonce */
+ Crypto1LFSR(Bit);
+ Temp >>= 1;
+ }
+}
+
+uint8_t Crypto1Byte(void)
+{
+ uint8_t KeyStream = 0;
+ uint8_t i;
+
+ /* Generate 8 keystream-bits */
+ for (i=0; i<8; i++) {
+
+ /* Calculate output of function-network and cycle LFSR with no
+ * additional input, thus linearly! */
+ uint8_t Out = Crypto1FilterOutput();
+ Crypto1LFSR(0);
+
+ /* Store keystream bit */
+ KeyStream >>= 1;
+
+ if (Out) {
+ KeyStream |= (1<<7);
+ }
+ }
+
+ return KeyStream;
+}
+
+uint8_t Crypto1Nibble(void)
+{
+ uint8_t KeyStream = 0;
+ uint8_t i;
+
+ /* Generate 4 keystream-bits */
+ for (i=0; i<4; i++) {
+
+ /* Calculate output of function-network and cycle LFSR with no
+ * additional input, thus linearly! */
+ uint8_t Out = Crypto1FilterOutput();
+ Crypto1LFSR(0);
+
+ /* Store keystream bit */
+ KeyStream >>= 1;
+
+ if (Out) {
+ KeyStream |= (1<<3);
+ }
+ }
+
+ return KeyStream;
+}
+
+void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount)
+{
+ while(ClockCount--) {
+ /* Actually, the PRNG is a 32 bit register with the upper 16 bit
+ * used as a LFSR. Furthermore only mask-byte 2 contains feedback at all.
+ * We rely on the compiler to optimize this for us here.
+ * XOR all tapped bits to a single feedback bit. */
+ uint8_t Feedback = 0;
+
+ Feedback ^= State[0] & (uint8_t) (PRNG_MASK >> 0);
+ Feedback ^= State[1] & (uint8_t) (PRNG_MASK >> 8);
+ Feedback ^= State[2] & (uint8_t) (PRNG_MASK >> 16);
+ Feedback ^= State[3] & (uint8_t) (PRNG_MASK >> 24);
+
+ Feedback ^= Feedback >> 4;
+ Feedback ^= Feedback >> 2;
+ Feedback ^= Feedback >> 1;
+
+ /* For ease of processing convert the state into a 32 bit integer first */
+ uint32_t Temp = 0;
+
+ Temp |= (uint32_t) State[0] << 0;
+ Temp |= (uint32_t) State[1] << 8;
+ Temp |= (uint32_t) State[2] << 16;
+ Temp |= (uint32_t) State[3] << 24;
+
+ /* Cycle LFSR and feed back. */
+ Temp >>= 1;
+
+ if (Feedback & 0x01) {
+ Temp |= (uint32_t) 1 << (8 * PRNG_SIZE - 1);
+ }
+
+ /* Store back state */
+ State[0] = (uint8_t) (Temp >> 0);
+ State[1] = (uint8_t) (Temp >> 8);
+ State[2] = (uint8_t) (Temp >> 16);
+ State[3] = (uint8_t) (Temp >> 24);
+ }
+
+
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/Crypto1.h b/RevE-light/Firmware/Chameleon-Mini/Application/Crypto1.h
new file mode 100644
index 0000000..7a00b7f
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/Crypto1.h
@@ -0,0 +1,25 @@
+#ifndef CRYPTO1_H
+#define CRYPTO1_H
+
+#include
+
+/* Gets the current keystream-bit, without shifting the internal LFSR */
+uint8_t Crypto1FilterOutput(void);
+
+/* Set up Crypto1 cipher using the given Key, Uid and CardNonce. Also encrypts
+ * the CardNonce in-place while in non-linear mode. */
+void Crypto1Setup(uint8_t Key[6], uint8_t Uid[4], uint8_t CardNonce[4]);
+
+/* Load the decrypted ReaderNonce into the Crypto1 state LFSR */
+void Crypto1Auth(uint8_t EncryptedReaderNonce[4]);
+
+/* Generate 8 Bits of key stream */
+uint8_t Crypto1Byte(void);
+
+/* Generate 4 Bits of key stream */
+uint8_t Crypto1Nibble(void);
+
+/* Execute 'ClockCount' cycles on the PRNG state 'State' */
+void Crypto1PRNG(uint8_t State[4], uint16_t ClockCount);
+
+#endif //CRYPTO1_H
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/ISO14443-3A.c b/RevE-light/Firmware/Chameleon-Mini/Application/ISO14443-3A.c
new file mode 100644
index 0000000..0b093e2
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/ISO14443-3A.c
@@ -0,0 +1,108 @@
+/*
+ * ISO14443A.c
+ *
+ * Created on: 19.03.2013
+ * Author: skuser
+ */
+
+#include "ISO14443-3A.h"
+
+void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount) {
+ uint16_t Checksum = 0x6363;
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+
+ while(ByteCount--) {
+ uint8_t Byte = *DataPtr++;
+
+ Byte ^= (uint8_t) (Checksum & 0x00FF);
+ Byte ^= Byte << 4;
+
+ Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^
+ ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 );
+ }
+
+ *DataPtr++ = (Checksum >> 0) & 0x00FF;
+ *DataPtr = (Checksum >> 8) & 0x00FF;
+}
+
+bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount)
+{
+ uint16_t Checksum = 0x6363;
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+
+ while(ByteCount--) {
+ uint8_t Byte = *DataPtr++;
+
+ Byte ^= (uint8_t) (Checksum & 0x00FF);
+ Byte ^= Byte << 4;
+
+ Checksum = (Checksum >> 8) ^ ( (uint16_t) Byte << 8 ) ^
+ ( (uint16_t) Byte << 3 ) ^ ( (uint16_t) Byte >> 4 );
+ }
+
+ return (DataPtr[0] == ((Checksum >> 0) & 0xFF)) && (DataPtr[1] == ((Checksum >> 8) & 0xFF));
+}
+
+#if 0
+bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
+{
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+ uint8_t NVB = DataPtr[1];
+ //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
+ //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;
+
+ switch (NVB) {
+ case ISO14443A_NVB_AC_START:
+ /* Start of anticollision procedure.
+ * Send whole UID CLn + BCC */
+ DataPtr[0] = UidCL[0];
+ DataPtr[1] = UidCL[1];
+ DataPtr[2] = UidCL[2];
+ DataPtr[3] = UidCL[3];
+ DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
+
+ *BitCount = ISO14443A_CL_FRAME_SIZE;
+
+ return false;
+
+ case ISO14443A_NVB_AC_END:
+ /* End of anticollision procedure.
+ * Send SAK CLn if we are selected. */
+ if ( (DataPtr[2] == UidCL[0]) &&
+ (DataPtr[3] == UidCL[1]) &&
+ (DataPtr[4] == UidCL[2]) &&
+ (DataPtr[5] == UidCL[3]) ) {
+
+ DataPtr[0] = SAKValue;
+ ISO14443AAppendCRCA(Buffer, 1);
+
+ *BitCount = ISO14443A_SAK_FRAME_SIZE;
+ return true;
+ } else {
+ /* We have not been selected. Don't send anything. */
+ *BitCount = 0;
+ return false;
+ }
+ default:
+ /* TODO: No anticollision supported */
+ *BitCount = 0;
+ return false;
+ }
+}
+
+bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue)
+{
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+
+ if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){
+ DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
+ DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
+
+ *BitCount = ISO14443A_ATQA_FRAME_SIZE;
+
+ return true;
+ } else {
+ return false;
+ }
+}
+#endif
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/ISO14443-3A.h b/RevE-light/Firmware/Chameleon-Mini/Application/ISO14443-3A.h
new file mode 100644
index 0000000..87f6ff2
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/ISO14443-3A.h
@@ -0,0 +1,117 @@
+/*
+ * ISO14443-2A.h
+ *
+ * Created on: 19.03.2013
+ * Author: skuser
+ */
+
+#ifndef ISO14443_3A_H_
+#define ISO14443_3A_H_
+
+#include "../Common.h"
+
+#define ISO14443A_UID_SIZE_SINGLE 4 /* bytes */
+#define ISO14443A_UID_SIZE_DOUBLE 7
+#define ISO14443A_UID_SIZE_TRIPLE 10
+
+#define ISO14443A_CMD_REQA 0x26
+#define ISO14443A_CMD_WUPA 0x52
+#define ISO14443A_CMD_SELECT_CL1 0x93
+#define ISO14443A_CMD_SELECT_CL2 0x95
+#define ISO14443A_CMD_SELECT_CL3 0x97
+#define ISO14443A_CMD_HLTA 0x50
+
+#define ISO14443A_NVB_AC_START 0x20
+#define ISO14443A_NVB_AC_END 0x70
+
+#define ISO14443A_CL_UID_OFFSET 0
+#define ISO14443A_CL_UID_SIZE 4
+#define ISO14443A_CL_BCC_OFFSET 4
+#define ISO14443A_CL_BCC_SIZE 1 /* Byte */
+#define ISO14443A_CL_FRAME_SIZE ((ISO14443A_CL_UID_SIZE + ISO14443A_CL_BCC_SIZE) * 8) /* UID[N...N+3] || BCCN */
+#define ISO14443A_SAK_INCOMPLETE 0x04
+#define ISO14443A_SAK_COMPLETE_COMPLIANT 0x20
+#define ISO14443A_SAK_COMPLETE_NOT_COMPLIANT 0x00
+
+#define ISO14443A_ATQA_FRAME_SIZE (2 * 8) /* Bit */
+#define ISO14443A_SAK_FRAME_SIZE (3 * 8) /* Bit */
+
+#define ISO14443A_UID0_RANDOM 0x08
+#define ISO14443A_UID0_CT 0x88
+
+#define ISO14443A_CRCA_SIZE 2
+
+#define ISO14443A_CALC_BCC(ByteBuffer) \
+ ( ByteBuffer[0] ^ ByteBuffer[1] ^ ByteBuffer[2] ^ ByteBuffer[3] )
+
+void ISO14443AAppendCRCA(void* Buffer, uint16_t ByteCount);
+bool ISO14443ACheckCRCA(void* Buffer, uint16_t ByteCount);
+
+INLINE bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue);
+INLINE bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue);
+
+INLINE
+bool ISO14443ASelect(void* Buffer, uint16_t* BitCount, uint8_t* UidCL, uint8_t SAKValue)
+{
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+ uint8_t NVB = DataPtr[1];
+ //uint8_t CollisionByteCount = (NVB >> 4) & 0x0F;
+ //uint8_t CollisionBitCount = (NVB >> 0) & 0x0F;
+
+ switch (NVB) {
+ case ISO14443A_NVB_AC_START:
+ /* Start of anticollision procedure.
+ * Send whole UID CLn + BCC */
+ DataPtr[0] = UidCL[0];
+ DataPtr[1] = UidCL[1];
+ DataPtr[2] = UidCL[2];
+ DataPtr[3] = UidCL[3];
+ DataPtr[4] = ISO14443A_CALC_BCC(DataPtr);
+
+ *BitCount = ISO14443A_CL_FRAME_SIZE;
+
+ return false;
+
+ case ISO14443A_NVB_AC_END:
+ /* End of anticollision procedure.
+ * Send SAK CLn if we are selected. */
+ if ( (DataPtr[2] == UidCL[0]) &&
+ (DataPtr[3] == UidCL[1]) &&
+ (DataPtr[4] == UidCL[2]) &&
+ (DataPtr[5] == UidCL[3]) ) {
+
+ DataPtr[0] = SAKValue;
+ ISO14443AAppendCRCA(Buffer, 1);
+
+ *BitCount = ISO14443A_SAK_FRAME_SIZE;
+ return true;
+ } else {
+ /* We have not been selected. Don't send anything. */
+ *BitCount = 0;
+ return false;
+ }
+ default:
+ /* TODO: No anticollision supported */
+ *BitCount = 0;
+ return false;
+ }
+}
+
+INLINE
+bool ISO14443AWakeUp(void* Buffer, uint16_t* BitCount, uint16_t ATQAValue)
+{
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+
+ if ( (DataPtr[0] == ISO14443A_CMD_REQA) || (DataPtr[0] == ISO14443A_CMD_WUPA) ){
+ DataPtr[0] = (ATQAValue >> 0) & 0x00FF;
+ DataPtr[1] = (ATQAValue >> 8) & 0x00FF;
+
+ *BitCount = ISO14443A_ATQA_FRAME_SIZE;
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+#endif
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/MifareClassic.c b/RevE-light/Firmware/Chameleon-Mini/Application/MifareClassic.c
new file mode 100644
index 0000000..a09345a
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/MifareClassic.c
@@ -0,0 +1,644 @@
+/*
+ * MifareClassic.c
+ *
+ * Created on: 13.05.2013
+ * Author: skuser
+ */
+
+#include "MifareClassic.h"
+
+#include "ISO14443-3A.h"
+#include "../Codec/ISO14443-2A.h"
+#include "../Memory.h"
+#include "Crypto1.h"
+#include "../Random.h"
+
+#define MFCLASSIC_1K_ATQA_VALUE 0x0004
+#define MFCLASSIC_4K_ATQA_VALUE 0x0002
+#define MFCLASSIC_1K_SAK_CL1_VALUE 0x08
+#define MFCLASSIC_4K_SAK_CL1_VALUE 0x18
+
+#define MEM_UID_CL1_ADDRESS 0x00
+#define MEM_UID_CL1_SIZE 4
+#define MEM_UID_BCC1_ADDRESS 0x04
+#define MEM_KEY_A_OFFSET 48 /* Bytes */
+#define MEM_KEY_B_OFFSET 58 /* Bytes */
+#define MEM_KEY_BIGSECTOR_OFFSET 192
+#define MEM_KEY_SIZE 6 /* Bytes */
+#define MEM_SECTOR_ADDR_MASK 0xFC
+#define MEM_BYTES_PER_BLOCK 16 /* Bytes */
+#define MEM_VALUE_SIZE 4 /* Bytes */
+
+#define ACK_NAK_FRAME_SIZE 4 /* Bits */
+#define ACK_VALUE 0x0A
+#define NAK_INVALID_ARG 0x00
+#define NAK_CRC_ERROR 0x01
+#define NAK_NOT_AUTHED 0x04
+#define NAK_EEPROM_ERROR 0x05
+#define NAK_OTHER_ERROR 0x06
+
+#define CMD_AUTH_A 0x60
+#define CMD_AUTH_B 0x61
+#define CMD_AUTH_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_AUTH_RB_FRAME_SIZE 4 /* Bytes */
+#define CMD_AUTH_AB_FRAME_SIZE 8 /* Bytes */
+#define CMD_AUTH_BA_FRAME_SIZE 4 /* Bytes */
+#define CMD_HALT 0x50
+#define CMD_HALT_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_READ 0x30
+#define CMD_READ_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_READ_RESPONSE_FRAME_SIZE 16 /* Bytes without CRCA */
+#define CMD_WRITE 0xA0
+#define CMD_WRITE_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_DECREMENT 0xC0
+#define CMD_DECREMENT_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_INCREMENT 0xC1
+#define CMD_INCREMENT_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_RESTORE 0xC2
+#define CMD_RESTORE_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_TRANSFER 0xB0
+#define CMD_TRANSFER_FRAME_SIZE 2 /* Bytes without CRCA */
+#define CMD_CHINESE_UNLOCK 0x40
+#define CMD_CHINESE_WIPE 0x41
+#define CMD_CHINESE_UNLOCK_RW 0x43
+
+static enum {
+ STATE_HALT,
+ STATE_IDLE,
+ STATE_CHINESE_IDLE,
+ STATE_CHINESE_WRITE,
+ STATE_READY,
+ STATE_ACTIVE,
+ STATE_AUTHING,
+ STATE_AUTHED_IDLE,
+ STATE_WRITE,
+ STATE_INCREMENT,
+ STATE_DECREMENT,
+ STATE_RESTORE
+} State;
+
+static uint8_t CardResponse[4];
+static uint8_t ReaderResponse[4];
+static uint8_t CurrentAddress;
+static uint8_t BlockBuffer[MEM_BYTES_PER_BLOCK];
+static uint16_t CardATQAValue;
+static uint8_t CardSAKValue;
+
+INLINE bool CheckValueIntegrity(uint8_t* Block)
+{
+ /* Value Blocks contain a value stored three times, with
+ * the middle portion inverted. */
+ if ( (Block[0] == (uint8_t) ~Block[4]) && (Block[0] == Block[8])
+ && (Block[1] == (uint8_t) ~Block[5]) && (Block[1] == Block[9])
+ && (Block[2] == (uint8_t) ~Block[6]) && (Block[2] == Block[10])
+ && (Block[3] == (uint8_t) ~Block[7]) && (Block[3] == Block[11])
+ && (Block[12] == (uint8_t) ~Block[13])
+ && (Block[12] == Block[14])
+ && (Block[14] == (uint8_t) ~Block[15])) {
+ return true;
+ } else {
+ return false;
+ }
+}
+
+INLINE void ValueFromBlock(uint32_t* Value, uint8_t* Block)
+{
+ *Value = 0;
+ *Value |= ((uint32_t) Block[0] << 0);
+ *Value |= ((uint32_t) Block[1] << 8);
+ *Value |= ((uint32_t) Block[2] << 16);
+ *Value |= ((uint32_t) Block[3] << 24);
+}
+
+INLINE void ValueToBlock(uint8_t* Block, uint32_t Value)
+{
+ Block[0] = (uint8_t) (Value >> 0);
+ Block[1] = (uint8_t) (Value >> 8);
+ Block[2] = (uint8_t) (Value >> 16);
+ Block[3] = (uint8_t) (Value >> 24);
+ Block[4] = ~Block[0];
+ Block[5] = ~Block[1];
+ Block[6] = ~Block[2];
+ Block[7] = ~Block[3];
+ Block[8] = Block[0];
+ Block[9] = Block[1];
+ Block[10] = Block[2];
+ Block[11] = Block[3];
+}
+
+void MifareClassicAppInit1K(void)
+{
+ State = STATE_IDLE;
+ CardATQAValue = MFCLASSIC_1K_ATQA_VALUE;
+ CardSAKValue = MFCLASSIC_1K_SAK_CL1_VALUE;
+}
+
+void MifareClassicAppInit4K(void)
+{
+ State = STATE_IDLE;
+ CardATQAValue = MFCLASSIC_4K_ATQA_VALUE;
+ CardSAKValue = MFCLASSIC_4K_SAK_CL1_VALUE;
+}
+
+void MifareClassicAppReset(void)
+{
+ State = STATE_IDLE;
+}
+
+void MifareClassicAppTask(void)
+{
+
+}
+
+uint16_t MifareClassicAppProcess(uint8_t* Buffer, uint16_t BitCount)
+{
+ switch(State) {
+ case STATE_IDLE:
+ case STATE_HALT:
+ if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) {
+ State = STATE_READY;
+ return BitCount;
+ }
+#ifdef SUPPORT_MF_CLASSIC_MAGIC_MODE
+ else if (Buffer[0] == CMD_CHINESE_UNLOCK) {
+ State = STATE_CHINESE_IDLE;
+ Buffer[0] = ACK_VALUE;
+ return ACK_NAK_FRAME_SIZE;
+ }
+#endif
+ break;
+
+#ifdef SUPPORT_MF_CLASSIC_MAGIC_MODE
+ case STATE_CHINESE_IDLE:
+ /* Support special china commands that dont require authentication. */
+ if (Buffer[0] == CMD_CHINESE_UNLOCK_RW) {
+ /* Unlock read and write commands */
+ Buffer[0] = ACK_VALUE;
+ return ACK_NAK_FRAME_SIZE;
+ } else if (Buffer[0] == CMD_CHINESE_WIPE) {
+ /* Wipe memory */
+ Buffer[0] = ACK_VALUE;
+ return ACK_NAK_FRAME_SIZE;
+ } else if (Buffer[0] == CMD_READ) {
+ if (ISO14443ACheckCRCA(Buffer, CMD_READ_FRAME_SIZE)) {
+ /* Read command. Read data from memory and append CRCA. */
+ MemoryReadBlock(Buffer, (uint16_t) Buffer[1] * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK);
+ ISO14443AAppendCRCA(Buffer, MEM_BYTES_PER_BLOCK);
+
+ return (CMD_READ_RESPONSE_FRAME_SIZE + ISO14443A_CRCA_SIZE )
+ * BITS_PER_BYTE;
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return ACK_NAK_FRAME_SIZE;
+ }
+ } else if (Buffer[0] == CMD_WRITE) {
+ if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) {
+ /* Write command. Store the address and prepare for the upcoming data.
+ * Respond with ACK. */
+ CurrentAddress = Buffer[1];
+ State = STATE_CHINESE_WRITE;
+
+ Buffer[0] = ACK_VALUE;
+ return ACK_NAK_FRAME_SIZE;
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return ACK_NAK_FRAME_SIZE;
+ }
+ } else if (Buffer[0] == CMD_HALT) {
+ /* Halts the tag. According to the ISO14443, the second
+ * byte is supposed to be 0. */
+ if (Buffer[1] == 0) {
+ if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) {
+ /* According to ISO14443, we must not send anything
+ * in order to acknowledge the HALT command. */
+ LogEntry(LOG_INFO_APP_CMD_HALT, NULL, 0);
+ State = STATE_HALT;
+ return ISO14443A_APP_NO_RESPONSE;
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return ACK_NAK_FRAME_SIZE;
+ }
+ } else {
+ Buffer[0] = NAK_INVALID_ARG;
+ return ACK_NAK_FRAME_SIZE;
+ }
+ }
+ break;
+
+ case STATE_CHINESE_WRITE:
+ if (ISO14443ACheckCRCA(Buffer, MEM_BYTES_PER_BLOCK)) {
+ /* CRC check passed. Write data into memory and send ACK. */
+ if (!ActiveConfiguration.ReadOnly) {
+ MemoryWriteBlock(Buffer, CurrentAddress * MEM_BYTES_PER_BLOCK, MEM_BYTES_PER_BLOCK);
+ }
+
+ Buffer[0] = ACK_VALUE;
+ } else {
+ /* CRC Error. */
+ Buffer[0] = NAK_CRC_ERROR;
+ }
+
+ State = STATE_CHINESE_IDLE;
+
+ return ACK_NAK_FRAME_SIZE;
+#endif
+
+ case STATE_READY:
+ if (ISO14443AWakeUp(Buffer, &BitCount, CardATQAValue)) {
+ State = STATE_READY;
+ return BitCount;
+ } else if (Buffer[0] == ISO14443A_CMD_SELECT_CL1) {
+ /* Load UID CL1 and perform anticollision */
+ uint8_t UidCL1[4];
+ MemoryReadBlock(UidCL1, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE);
+
+ if (ISO14443ASelect(Buffer, &BitCount, UidCL1, CardSAKValue)) {
+ State = STATE_ACTIVE;
+ }
+
+ return BitCount;
+ } else {
+ /* Unknown command. Enter HALT state. */
+ State = STATE_HALT;
+ }
+ break;
+
+ case STATE_ACTIVE:
+ if (ISO14443AWakeUp(Buffer, &BitCount, MFCLASSIC_1K_ATQA_VALUE)) {
+ State = STATE_READY;
+ return BitCount;
+ } else if (Buffer[0] == CMD_HALT) {
+ /* Halts the tag. According to the ISO14443, the second
+ * byte is supposed to be 0. */
+ if (Buffer[1] == 0) {
+ if (ISO14443ACheckCRCA(Buffer, CMD_HALT_FRAME_SIZE)) {
+ /* According to ISO14443, we must not send anything
+ * in order to acknowledge the HALT command. */
+ LogEntry(LOG_INFO_APP_CMD_HALT, NULL, 0);
+
+ State = STATE_HALT;
+ return ISO14443A_APP_NO_RESPONSE;
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return ACK_NAK_FRAME_SIZE;
+ }
+ } else {
+ Buffer[0] = NAK_INVALID_ARG;
+ return ACK_NAK_FRAME_SIZE;
+ }
+ } else if ( (Buffer[0] == CMD_AUTH_A) || (Buffer[0] == CMD_AUTH_B)) {
+ if (ISO14443ACheckCRCA(Buffer, CMD_AUTH_FRAME_SIZE)) {
+ uint8_t SectorAddress = Buffer[1] & MEM_SECTOR_ADDR_MASK;
+ uint8_t KeyOffset = (Buffer[0] == CMD_AUTH_A ? MEM_KEY_A_OFFSET : MEM_KEY_B_OFFSET);
+ uint16_t KeyAddress = (uint16_t) SectorAddress * MEM_BYTES_PER_BLOCK + KeyOffset;
+ uint8_t Key[6];
+ uint8_t Uid[4];
+ uint8_t CardNonce[4];
+
+ LogEntry(LOG_INFO_APP_CMD_AUTH, Buffer, 2);
+
+ /* Generate a random nonce and read UID and key from memory */
+ RandomGetBuffer(CardNonce, sizeof(CardNonce));
+ MemoryReadBlock(Uid, MEM_UID_CL1_ADDRESS, MEM_UID_CL1_SIZE);
+ MemoryReadBlock(Key, KeyAddress, MEM_KEY_SIZE);
+
+ /* Precalculate the reader response from card-nonce */
+ for (uint8_t i=0; i= PAGE_READ_MIN)
+ && (PageAddress <= PAGE_READ_MAX) ) {
+ /* TODO: Missing address wrap around behaviour.
+ * Implement using a for-loop copying 4 bytes each iteration
+ * and mask pageaddress */
+ MemoryReadBlock(Buffer, PageAddress * BYTES_PER_PAGE, BYTES_PER_READ);
+ ISO14443AAppendCRCA(Buffer, BYTES_PER_READ);
+ return (BYTES_PER_READ + ISO14443A_CRCA_SIZE) * 8;
+ } else {
+ Buffer[0] = NAK_INVALID_ARG;
+ return NAK_FRAME_SIZE;
+ }
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return NAK_FRAME_SIZE;
+ }
+ } else if (Cmd == CMD_WRITE) {
+ /* This is a write command containing 4 bytes of data that
+ * should be written to the given page address. */
+ uint8_t PageAddress = Buffer[1];
+ if (ISO14443ACheckCRCA(Buffer, CMD_WRITE_FRAME_SIZE)) {
+ /* CRC check passed */
+ if ( (PageAddress >= PAGE_WRITE_MIN)
+ && (PageAddress <= PAGE_WRITE_MAX) ) {
+ /* PageAddress is within bounds. */
+
+ if (!ActiveConfiguration.ReadOnly) {
+ MemoryWriteBlock(&Buffer[2], PageAddress * BYTES_PER_PAGE, BYTES_PER_WRITE);
+ } else {
+ /* If the chameleon is in read only mode, it silently
+ * ignores any attempt to write data. */
+ }
+
+ Buffer[0] = ACK_VALUE;
+ return ACK_FRAME_SIZE;
+
+ } else {
+ Buffer[0] = NAK_INVALID_ARG;
+ return NAK_FRAME_SIZE;
+ }
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return NAK_FRAME_SIZE;
+ }
+ } else if (Cmd == CMD_COMPAT_WRITE) {
+ /* The Mifare compatbility write command is a 2-frame command.
+ * The first frame contains the page-address and the second frame
+ * holds the data. */
+ uint8_t PageAddress = Buffer[1];
+
+ if (ISO14443ACheckCRCA(Buffer, CMD_COMPAT_WRITE_FRAME_SIZE)) {
+ if ( (PageAddress >= PAGE_WRITE_MIN)
+ && (PageAddress <= PAGE_WRITE_MAX) ) {
+ /* CRC check passed and page-address is within bounds.
+ * Store address and proceed to receiving the data. */
+ CompatWritePageAddress = PageAddress;
+ State = STATE_COMPAT_WRITE;
+
+ Buffer[0] = ACK_VALUE;
+ return ACK_FRAME_SIZE;
+ } else {
+ Buffer[0] = NAK_INVALID_ARG;
+ return NAK_FRAME_SIZE;
+ }
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return NAK_FRAME_SIZE;
+ }
+ } else if (Cmd == CMD_HALT) {
+ /* Halts the tag. According to the ISO14443, the second
+ * byte is supposed to be 0. */
+ if (Buffer[1] == 0) {
+ if (ISO14443ACheckCRCA(Buffer, 2)) {
+ /* According to ISO14443, we must not send anything
+ * in order to acknowledge the HALT command. */
+ State = STATE_HALT;
+ return ISO14443A_APP_NO_RESPONSE;
+ } else {
+ Buffer[0] = NAK_CRC_ERROR;
+ return NAK_FRAME_SIZE;
+ }
+ } else {
+ Buffer[0] = NAK_INVALID_ARG;
+ return NAK_FRAME_SIZE;
+ }
+ } else {
+ /* Unknown command. Enter halt state */
+ State = STATE_IDLE;
+ }
+ break;
+
+ case STATE_COMPAT_WRITE:
+ /* Compatibility write. Receiving 16 bytes of data of which 4 bytes are valid. */
+ if (ISO14443ACheckCRCA(Buffer, BYTES_PER_COMPAT_WRITE)) {
+ /* We don't perform any checks here. You will be able to program the
+ * whole memory. Also there is no OTP behaviour. */
+ if (!ActiveConfiguration.ReadOnly) {
+ MemoryWriteBlock(Buffer, CompatWritePageAddress * BYTES_PER_PAGE, BYTES_PER_WRITE);
+ } else {
+ /* If we are told to be read only, we silently ignore the write command
+ * and pretend to have written data. */
+ }
+
+ State = STATE_ACTIVE;
+ Buffer[0] = ACK_VALUE;
+ return ACK_FRAME_SIZE;
+ } else {
+ State = STATE_ACTIVE;
+ Buffer[0] = NAK_CRC_ERROR;
+ return NAK_FRAME_SIZE;
+ }
+
+ default:
+ /* Unknown state? Should never happen. */
+ break;
+ }
+
+ /* No response has been sent, when we reach here */
+ return ISO14443A_APP_NO_RESPONSE;
+}
+
+void MifareUltralightGetUid(ConfigurationUidType Uid)
+{
+ /* Read UID from memory */
+ MemoryReadBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
+ MemoryReadBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
+}
+
+void MifareUltralightSetUid(ConfigurationUidType Uid)
+{
+ /* Calculate check bytes and write everything into memory */
+ uint8_t BCC1 = ISO14443A_UID0_CT ^ Uid[0] ^ Uid[1] ^ Uid[2];
+ uint8_t BCC2 = Uid[3] ^ Uid[4] ^ Uid[5] ^ Uid[6];
+
+ MemoryWriteBlock(&Uid[0], UID_CL1_ADDRESS, UID_CL1_SIZE);
+ MemoryWriteBlock(&BCC1, UID_BCC1_ADDRESS, ISO14443A_CL_BCC_SIZE);
+ MemoryWriteBlock(&Uid[UID_CL1_SIZE], UID_CL2_ADDRESS, UID_CL2_SIZE);
+ MemoryWriteBlock(&BCC2, UID_BCC2_ADDRESS, ISO14443A_CL_BCC_SIZE);
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Application/MifareUltralight.h b/RevE-light/Firmware/Chameleon-Mini/Application/MifareUltralight.h
new file mode 100644
index 0000000..275685c
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Application/MifareUltralight.h
@@ -0,0 +1,28 @@
+/*
+ * MifareUltralight.h
+ *
+ * Created on: 20.03.2013
+ * Author: skuser
+ */
+
+#ifndef MIFAREULTRALIGHT_H_
+#define MIFAREULTRALIGHT_H_
+
+#include "Application.h"
+#include "ISO14443-3A.h"
+
+#define MIFARE_ULTRALIGHT_UID_SIZE ISO14443A_UID_SIZE_DOUBLE
+#define MIFARE_ULTRALIGHT_MEM_SIZE 64
+
+void MifareUltralightAppInit(void);
+void MifareUltralightAppReset(void);
+void MifareUltralightAppTask(void);
+
+uint16_t MifareUltralightAppProcess(uint8_t* Buffer, uint16_t BitCount);
+
+void MifareUltralightGetUid(ConfigurationUidType Uid);
+void MifareUltralightSetUid(ConfigurationUidType Uid);
+
+
+
+#endif /* MIFAREULTRALIGHT_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Battery.h b/RevE-light/Firmware/Chameleon-Mini/Battery.h
new file mode 100644
index 0000000..02faa14
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Battery.h
@@ -0,0 +1,36 @@
+/*
+ * Battery.h
+ *
+ * Created on: 20.08.2014
+ * Author: sk
+ */
+
+#ifndef BATTERY_H_
+#define BATTERY_H_
+
+#include "Common.h"
+
+#define BATTERY_PORT PORTD
+#define BATTERY_STAT_PIN PIN4_bm
+#define BATTERY_STAT_PINCTRL PIN4CTRL
+#define BATTERY_PORT_MASK (BATTERY_STAT_PIN)
+
+INLINE void BatteryInit(void)
+{
+ BATTERY_PORT.DIRCLR = BATTERY_PORT_MASK;
+ BATTERY_PORT.BATTERY_STAT_PINCTRL = PORT_OPC_PULLUP_gc;
+}
+
+INLINE bool BatteryIsCharging(void)
+{
+ if (!(BATTERY_PORT.IN & BATTERY_STAT_PIN))
+ {
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+}
+
+#endif /* BATTERY_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Button.c b/RevE-light/Firmware/Chameleon-Mini/Button.c
new file mode 100644
index 0000000..b6d38d7
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Button.c
@@ -0,0 +1,217 @@
+#include "Button.h"
+#include "Random.h"
+#include "Common.h"
+#include "Settings.h"
+#include "Memory.h"
+#include "Map.h"
+#include "Application/Application.h"
+
+#define BUTTON_PORT PORTA
+#define BUTTON_L PIN3_bm
+#define BUTTON_R PIN6_bm
+#define BUTTON_L_PINCTRL PIN3CTRL
+#define BUTTON_R_PINCTRL PIN6CTRL
+#define BUTTON_MASK (BUTTON_L | BUTTON_R)
+
+#define LONG_PRESS_TICK_COUNT 10
+
+static const MapEntryType PROGMEM ButtonActionMap[] = {
+ { .Id = BUTTON_ACTION_NONE, .Text = "NONE" },
+ { .Id = BUTTON_ACTION_UID_RANDOM, .Text = "UID_RANDOM" },
+ { .Id = BUTTON_ACTION_UID_LEFT_INCREMENT, .Text = "UID_LEFT_INCREMENT" },
+ { .Id = BUTTON_ACTION_UID_RIGHT_INCREMENT, .Text = "UID_RIGHT_INCREMENT" },
+ { .Id = BUTTON_ACTION_UID_LEFT_DECREMENT, .Text = "UID_LEFT_DECREMENT" },
+ { .Id = BUTTON_ACTION_UID_RIGHT_DECREMENT, .Text = "UID_RIGHT_DECREMENT" },
+ { .Id = BUTTON_ACTION_CYCLE_SETTINGS, .Text = "CYCLE_SETTINGS" },
+ { .Id = BUTTON_ACTION_STORE_MEM, .Text = "STORE_MEM" },
+ { .Id = BUTTON_ACTION_RECALL_MEM, .Text = "RECALL_MEM" },
+};
+
+static void ExecuteButtonAction(ButtonActionEnum ButtonAction)
+{
+ uint8_t UidBuffer[32];
+
+ if (ButtonAction == BUTTON_ACTION_UID_RANDOM) {
+ for (uint8_t i=0; i 0) {
+ if (Carry) {
+ if (UidBuffer[i] == 0xFF) {
+ Carry = 1;
+ } else {
+ Carry = 0;
+ }
+
+ UidBuffer[i] = (UidBuffer[i] + 1) & 0xFF;
+ }
+ }
+
+ ApplicationSetUid(UidBuffer);
+ } else if (ButtonAction == BUTTON_ACTION_UID_LEFT_DECREMENT) {
+ ApplicationGetUid(UidBuffer);
+ bool Carry = 1;
+ uint8_t i;
+
+ for (i=0; i 0) {
+ if (Carry) {
+ if (UidBuffer[i] == 0x00) {
+ Carry = 1;
+ } else {
+ Carry = 0;
+ }
+
+ UidBuffer[i] = (UidBuffer[i] - 1) & 0xFF;
+ }
+ }
+
+ ApplicationSetUid(UidBuffer);
+ } else if (ButtonAction == BUTTON_ACTION_CYCLE_SETTINGS) {
+ SettingsCycle();
+ } else if (ButtonAction == BUTTON_ACTION_STORE_MEM) {
+ MemoryStore();
+ } else if (ButtonAction == BUTTON_ACTION_RECALL_MEM) {
+ MemoryRecall();
+ }
+}
+
+void ButtonInit(void)
+{
+ BUTTON_PORT.DIRCLR = BUTTON_MASK;
+ BUTTON_PORT.BUTTON_R_PINCTRL = PORT_OPC_PULLUP_gc;
+ BUTTON_PORT.BUTTON_L_PINCTRL = PORT_OPC_PULLUP_gc;
+}
+
+void ButtonTick(void)
+{
+ static uint8_t ButtonRPressTick = 0;
+ static uint8_t ButtonLPressTick = 0;
+ uint8_t ThisButtonState = ~BUTTON_PORT.IN;
+
+ if (ThisButtonState & BUTTON_R) {
+ /* Button is currently pressed */
+ if (ButtonRPressTick < LONG_PRESS_TICK_COUNT) {
+ /* Count ticks while button is being pressed */
+ ButtonRPressTick++;
+ } else if (ButtonRPressTick == LONG_PRESS_TICK_COUNT) {
+ /* Long button press detected execute button action and advance PressTickCounter
+ * to an invalid state. */
+ ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_R_PRESS_LONG]);
+ ButtonRPressTick++;
+ } else {
+ /* Button is still pressed, ignore */
+ }
+ } else if (!(ThisButtonState & BUTTON_MASK)) {
+ /* Button is currently not being pressed. Check if PressTickCounter contains
+ * a recent short button press. */
+ if ( (ButtonRPressTick > 0) && (ButtonRPressTick <= LONG_PRESS_TICK_COUNT) ) {
+ /* We have a short button press */
+ ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_R_PRESS_SHORT]);
+ }
+
+ ButtonRPressTick = 0;
+ }
+
+ if (ThisButtonState & BUTTON_L) {
+ /* Button is currently pressed */
+ if (ButtonLPressTick < LONG_PRESS_TICK_COUNT) {
+ /* Count ticks while button is being pressed */
+ ButtonLPressTick++;
+ } else if (ButtonLPressTick == LONG_PRESS_TICK_COUNT) {
+ /* Long button press detected execute button action and advance PressTickCounter
+ * to an invalid state. */
+ ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_L_PRESS_LONG]);
+ ButtonLPressTick++;
+ } else {
+ /* Button is still pressed, ignore */
+ }
+ } else if (!(ThisButtonState & BUTTON_MASK)) {
+ /* Button is currently not being pressed. Check if PressTickCounter contains
+ * a recent short button press. */
+ if ( (ButtonLPressTick > 0) && (ButtonLPressTick <= LONG_PRESS_TICK_COUNT) ) {
+ /* We have a short button press */
+ ExecuteButtonAction(GlobalSettings.ActiveSettingPtr->ButtonActions[BUTTON_L_PRESS_SHORT]);
+ }
+
+ ButtonLPressTick = 0;
+ }
+}
+
+void ButtonGetActionList(char* List, uint16_t BufferSize)
+{
+ MapToString(ButtonActionMap, sizeof(ButtonActionMap)/sizeof(*ButtonActionMap), List, BufferSize);
+}
+
+void ButtonSetActionById(ButtonTypeEnum Type, ButtonActionEnum Action)
+{
+#ifndef BUTTON_SETTING_GLOBAL
+ GlobalSettings.ActiveSettingPtr->ButtonActions[Type] = Action;
+#else
+ /* Write button action to all settings when using global settings */
+ for (uint8_t i=0; iButtonActions[Type], Action, BufferSize);
+}
+
+bool ButtonSetActionByName(ButtonTypeEnum Type, const char* Action)
+{
+ MapIdType Id;
+
+ if (MapTextToId(ButtonActionMap, sizeof(ButtonActionMap)/sizeof(*ButtonActionMap),
+ Action, &Id)) {
+ ButtonSetActionById(Type, Id);
+ return true;
+ } else {
+ return false;
+ }
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Button.h b/RevE-light/Firmware/Chameleon-Mini/Button.h
new file mode 100644
index 0000000..154813c
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Button.h
@@ -0,0 +1,46 @@
+/*
+ * Button.h
+ *
+ * Created on: 13.05.2013
+ * Author: skuser
+ */
+
+#ifndef BUTTON_H_
+#define BUTTON_H_
+
+#include "Common.h"
+
+typedef enum {
+ BUTTON_R_PRESS_SHORT = 0,
+ BUTTON_R_PRESS_LONG,
+ BUTTON_L_PRESS_SHORT,
+ BUTTON_L_PRESS_LONG,
+
+ /* Must be last element */
+ BUTTON_TYPE_COUNT
+} ButtonTypeEnum;
+
+typedef enum {
+ BUTTON_ACTION_NONE,
+ BUTTON_ACTION_UID_RANDOM,
+ BUTTON_ACTION_UID_LEFT_INCREMENT,
+ BUTTON_ACTION_UID_RIGHT_INCREMENT,
+ BUTTON_ACTION_UID_LEFT_DECREMENT,
+ BUTTON_ACTION_UID_RIGHT_DECREMENT,
+ BUTTON_ACTION_CYCLE_SETTINGS,
+ BUTTON_ACTION_STORE_MEM,
+ BUTTON_ACTION_RECALL_MEM,
+
+ /* This has to be last element */
+ BUTTON_ACTION_COUNT
+} ButtonActionEnum;
+
+void ButtonInit(void);
+void ButtonTick(void);
+
+void ButtonGetActionList(char* List, uint16_t BufferSize);
+void ButtonSetActionById(ButtonTypeEnum Type, ButtonActionEnum Action);
+void ButtonGetActionByName(ButtonTypeEnum Type, char* Action, uint16_t BufferSize);
+bool ButtonSetActionByName(ButtonTypeEnum Type, const char* Action);
+
+#endif /* BUTTON_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Chameleon-Mini.c b/RevE-light/Firmware/Chameleon-Mini/Chameleon-Mini.c
new file mode 100644
index 0000000..220f1de
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Chameleon-Mini.c
@@ -0,0 +1,43 @@
+#include "Chameleon-Mini.h"
+#include "LEDHook.h"
+
+int main(void)
+{
+ SystemInit();
+ SettingsLoad();
+ LogInit();
+ LEDInit();
+ MemoryInit();
+ ConfigurationInit();
+ TerminalInit();
+ RandomInit();
+ ButtonInit();
+ AntennaLevelInit();
+
+ SystemInterruptInit();
+ SystemSleepEnable();
+
+
+ while(1)
+ {
+ if (SystemTick100ms())
+ {
+ RandomTick();
+ TerminalTick();
+ ButtonTick();
+ LogTick();
+ LEDTick();
+ ApplicationTick();
+
+ LEDHook(LED_POWERED, LED_ON);
+ }
+
+ TerminalTask();
+ ApplicationTask();
+ LogTask();
+ CodecTask();
+ }
+}
+
+
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Chameleon-Mini.h b/RevE-light/Firmware/Chameleon-Mini/Chameleon-Mini.h
new file mode 100644
index 0000000..709e178
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Chameleon-Mini.h
@@ -0,0 +1,25 @@
+#ifndef CHAMELEON_MINI_H
+#define CHAMELEON_MINI_H
+
+#include
+#include
+#include
+#include
+
+#include "System.h"
+#include "Memory.h"
+#include "LED.h"
+#include "Terminal/Terminal.h"
+#include "Codec/Codec.h"
+#include "Application/Application.h"
+#include "Configuration.h"
+#include "Random.h"
+#include "Button.h"
+#include "Log.h"
+#include "AntennaLevel.h"
+#include "Settings.h"
+
+#define CHAMELEON_MINI_VERSION_STRING BUILD_DATE
+
+#endif //CHAMELEON_MINI_H
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Codec/Codec.c b/RevE-light/Firmware/Chameleon-Mini/Codec/Codec.c
new file mode 100644
index 0000000..08729ef
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Codec/Codec.c
@@ -0,0 +1,10 @@
+/*
+ * CODEC.c
+ *
+ * Created on: 18.02.2013
+ * Author: skuser
+ */
+
+#include "Codec.h"
+
+uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
diff --git a/RevE-light/Firmware/Chameleon-Mini/Codec/Codec.h b/RevE-light/Firmware/Chameleon-Mini/Codec/Codec.h
new file mode 100644
index 0000000..beaaf2a
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Codec/Codec.h
@@ -0,0 +1,78 @@
+/*
+ * CODEC.h
+ *
+ * Created on: 18.02.2013
+ * Author: skuser
+ */
+
+#ifndef CODEC_H_
+#define CODEC_H_
+
+#include
+#include
+#include
+#include "../Common.h"
+#include "../Configuration.h"
+
+#include "ISO14443-2A.h"
+
+#define CODEC_DEMOD_POWER_PORT PORTB
+#define CODEC_DEMOD_POWER_MASK PIN1_bm
+#define CODEC_DEMOD_IN_PORT PORTB
+#define CODEC_DEMOD_IN_MASK (CODEC_DEMOD_IN_MASK0 | CODEC_DEMOD_IN_MASK1)
+#define CODEC_DEMOD_IN_MASK0 PIN2_bm
+#define CODEC_DEMOD_IN_MASK1 PIN0_bm
+#define CODEC_DEMOD_IN_PINCTRL0 PIN2CTRL
+#define CODEC_DEMOD_IN_PINCTRL1 PIN0CTRL
+#define CODEC_DEMOD_IN_EVMUX0 EVSYS_CHMUX_PORTB_PIN2_gc
+#define CODEC_DEMOD_IN_EVMUX1 EVSYS_CHMUX_PORTB_PIN0_gc
+#define CODEC_DEMOD_IN_INT0_VECT PORTB_INT0_vect
+#define CODEC_LOADMOD_PORT PORTC
+#define CODEC_LOADMOD_MASK PIN6_bm
+#define CODEC_CARRIER_IN_PORT PORTC
+#define CODEC_CARRIER_IN_MASK PIN2_bm
+#define CODEC_CARRIER_IN_PINCTRL PIN2CTRL
+#define CODEC_CARRIER_IN_EVMUX EVSYS_CHMUX_PORTC_PIN2_gc
+#define CODEC_SUBCARRIER_PORT PORTC
+#define CODEC_SUBCARRIER_MASK_PSK PIN0_bm
+#define CODEC_SUBCARRIER_MASK_OOK PIN1_bm
+#define CODEC_SUBCARRIER_MASK (CODEC_SUBCARRIER_MASK_PSK | CODEC_SUBCARRIER_MASK_OOK)
+#define CODEC_SUBCARRIER_TIMER TCC0
+#define CODEC_SUBCARRIER_CC_PSK CCA
+#define CODEC_SUBCARRIER_CC_OOK CCB
+#define CODEC_SUBCARRIER_CCEN_PSK TC0_CCAEN_bm
+#define CODEC_SUBCARRIER_CCEN_OOK TC0_CCBEN_bm
+#define CODEC_TIMER_SAMPLING TCC1
+#define CODEC_TIMER_SAMPLING_CCA_VECT TCC1_CCA_vect
+#define CODEC_TIMER_LOADMOD TCD1
+#define CODEC_TIMER_OVF_VECT TCD1_OVF_vect
+
+#define CODEC_BUFFER_SIZE 256 /* Byte */
+
+#define CODEC_CARRIER_FREQ 13560000
+
+extern uint8_t CodecBuffer[CODEC_BUFFER_SIZE];
+
+INLINE void CodecInit(void) {
+ ActiveConfiguration.CodecInitFunc();
+}
+
+INLINE void CodecDeInit(void) {
+ ActiveConfiguration.CodecDeInitFunc();
+}
+
+INLINE void CodecTask(void) {
+ ActiveConfiguration.CodecTaskFunc();
+}
+
+INLINE void CodecSetDemodPower(bool bOnOff) {
+ CODEC_DEMOD_POWER_PORT.DIRSET = CODEC_DEMOD_POWER_MASK;
+
+ if (bOnOff) {
+ CODEC_DEMOD_POWER_PORT.OUTSET = CODEC_DEMOD_POWER_MASK;
+ } else {
+ CODEC_DEMOD_POWER_PORT.OUTCLR = CODEC_DEMOD_POWER_MASK;
+ }
+}
+
+#endif /* CODEC_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c b/RevE-light/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c
new file mode 100644
index 0000000..fb4d0f3
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Codec/ISO14443-2A.c
@@ -0,0 +1,479 @@
+/*
+ * ISO14443A.c
+ *
+ * Created on: 18.02.2013
+ * Author: skuser
+ */
+
+#include "ISO14443-2A.h"
+#include "../System.h"
+#include "../Application/Application.h"
+#include "../LEDHook.h"
+#include "Codec.h"
+#include "Log.h"
+
+/* Timing definitions for ISO14443A */
+#define ISO14443A_SUBCARRIER_DIVIDER 16
+#define ISO14443A_BIT_GRID_CYCLES 128
+#define ISO14443A_BIT_RATE_CYCLES 128
+#define ISO14443A_FRAME_DELAY_PREV1 (1236 - 24) /* compensate for ISR prolog */
+#define ISO14443A_FRAME_DELAY_PREV0 (1172 - 24)
+
+/* Sampling is done using internal clock, synchronized to the field modulation.
+ * For that we need to convert the bit rate for the internal clock. */
+#define SAMPLE_RATE_SYSTEM_CYCLES ((uint16_t) (((uint64_t) F_CPU * ISO14443A_BIT_RATE_CYCLES) / CODEC_CARRIER_FREQ) )
+
+static volatile struct {
+ volatile bool DemodFinished;
+ volatile bool LoadmodFinished;
+} Flags = { 0 };
+
+typedef enum {
+ LOADMOD_FDT,
+ LOADMOD_START,
+ LOADMOD_START_BIT0,
+ LOADMOD_START_BIT1,
+ LOADMOD_DATA0,
+ LOADMOD_DATA1,
+ LOADMOD_PARITY0,
+ LOADMOD_PARITY1,
+ LOADMOD_STOP_BIT0,
+ LOADMOD_STOP_BIT1,
+ LOADMOD_FINISHED
+} LoadModStateType;
+
+static volatile uint8_t* CodecBufferPtr;
+static volatile uint8_t* ParityBufferPtr;
+static volatile uint16_t BitCount;
+static volatile uint16_t BitSent;
+static volatile uint8_t DataRegister;
+static volatile uint8_t SampleRegister;
+static volatile bool IsParityBit;
+static volatile uint8_t LastBit;
+static volatile LoadModStateType LoadModState;
+static volatile bool SamplePosition;
+
+static void Initialize(void) {
+ /* Configure CARRIER input pin and route it to EVSYS */
+ CODEC_CARRIER_IN_PORT.DIRCLR = CODEC_CARRIER_IN_MASK;
+ CODEC_CARRIER_IN_PORT.CODEC_CARRIER_IN_PINCTRL = PORT_ISC_BOTHEDGES_gc;
+ EVSYS.CH6MUX = CODEC_CARRIER_IN_EVMUX;
+
+ /* Configure two DEMOD pins for input.
+ * Configure event channel 0 for rising edge (begin of modulation pause)
+ * Configure event channel 1 for falling edge (end of modulation pause) */
+ CODEC_DEMOD_IN_PORT.DIRCLR = CODEC_DEMOD_IN_MASK;
+ CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL0 = PORT_ISC_RISING_gc;
+ CODEC_DEMOD_IN_PORT.CODEC_DEMOD_IN_PINCTRL1 = PORT_ISC_FALLING_gc;
+ CODEC_DEMOD_IN_PORT.INT0MASK = 0;
+ CODEC_DEMOD_IN_PORT.INTCTRL = PORT_INT0LVL_HI_gc;
+ EVSYS.CH0MUX = CODEC_DEMOD_IN_EVMUX0;
+ EVSYS.CH1MUX = CODEC_DEMOD_IN_EVMUX1;
+
+ /* Configure LOADMOD and SUBCARRIER output pins.
+ * Disable PSK modulation by setting pin to low. */
+ CODEC_LOADMOD_PORT.DIRSET = CODEC_LOADMOD_MASK;
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ CODEC_SUBCARRIER_PORT.DIRSET = CODEC_SUBCARRIER_MASK;
+ CODEC_SUBCARRIER_PORT.OUTCLR = CODEC_SUBCARRIER_MASK;
+
+ /* Configure subcarrier generation with 50% DC output using OOK */
+ CODEC_SUBCARRIER_TIMER.PER = ISO14443A_SUBCARRIER_DIVIDER - 1;
+ CODEC_SUBCARRIER_TIMER.CODEC_SUBCARRIER_CC_OOK = ISO14443A_SUBCARRIER_DIVIDER/2;
+ CODEC_SUBCARRIER_TIMER.CTRLB = CODEC_SUBCARRIER_CCEN_OOK | TC_WGMODE_SINGLESLOPE_gc;
+}
+
+static void StartDemod(void) {
+ /* Activate Power for demodulator */
+ CodecSetDemodPower(true);
+
+ CodecBufferPtr = CodecBuffer;
+ ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET];
+ DataRegister = 0;
+ SampleRegister = 0;
+ SamplePosition = 0;
+ BitCount = 0;
+ IsParityBit = false;
+
+ /* Configure sampling-timer free running and sync to first modulation-pause. */
+ CODEC_TIMER_SAMPLING.CNT = 0;
+ CODEC_TIMER_SAMPLING.PER = SAMPLE_RATE_SYSTEM_CYCLES - 1;
+ CODEC_TIMER_SAMPLING.CCA = 0xFFFF; /* CCA Interrupt is not active! */
+ CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_DIV1_gc;
+ CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc;
+ CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_HI_gc;
+
+ /* Start looking out for modulation pause via interrupt. */
+ CODEC_DEMOD_IN_PORT.INT0MASK = CODEC_DEMOD_IN_MASK0;
+ SystemSleepSetMode(SYSTEM_SMODE_PSAVE);
+}
+
+ISR(CODEC_DEMOD_IN_INT0_VECT) {
+ /* This is the first edge of the first modulation-pause after StartDemod.
+ * Now we have time to start
+ * demodulating beginning from one bit-width after this edge. */
+ SystemSleepSetMode(SYSTEM_SMODE_IDLE);
+
+ /* Sampling timer has been preset to sample-rate and has automatically synced
+ * to THIS first modulation pause. Thus after exactly one bit-width from here,
+ * an OVF is generated. We want to start sampling with the next bit and use the
+ * XYZBUF mechanism of the xmega to automatically double the sampling rate on the
+ * next overflow. For this we have to temporarily deactivate the automatical alignment
+ * in order to catch next overflow event for updating the BUF registers.
+ * We want to sample the demodulated data stream in the first quarter of the half-bit
+ * where the pulsed miller encoded is located. */
+ CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc;
+ CODEC_TIMER_SAMPLING.PERBUF = SAMPLE_RATE_SYSTEM_CYCLES/2 - 1; /* Half bit width */
+ CODEC_TIMER_SAMPLING.CCABUF = SAMPLE_RATE_SYSTEM_CYCLES/8 - 10 - 1; /* Compensate for DIGFILT and ISR prolog */
+
+ /* Setup Frame Delay Timer and wire to EVSYS. Frame delay time is
+ * measured from last change in RF field, therefore we use
+ * the event channel 1 (end of modulation pause) as the restart event.
+ * The preliminary frame delay time chosen here is irrelevant, because
+ * the correct FDT gets set automatically after demodulation. */
+ CODEC_TIMER_LOADMOD.CNT = 0;
+ CODEC_TIMER_LOADMOD.PER = 0xFFFF;
+ CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH1_gc;
+ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_EVCH6_gc;
+
+ /* Disable this interrupt */
+ CODEC_DEMOD_IN_PORT.INT0MASK = 0;
+}
+
+ISR(CODEC_TIMER_SAMPLING_CCA_VECT) {
+ /* This interrupt gets called twice for every bit to sample it. */
+ uint8_t SamplePin = CODEC_DEMOD_IN_PORT.IN & CODEC_DEMOD_IN_MASK;
+ uint8_t NewSampleRegister;
+
+ /* Shift sampled bit into sampling register and hold a local copy for fast access. */
+ NewSampleRegister = SampleRegister << 1;
+ NewSampleRegister |= (!SamplePin ? 0x01 : 0x00);
+ SampleRegister = NewSampleRegister;
+
+ if (SamplePosition) {
+ /* Analyze the sampling register after 2 samples. */
+ if ((NewSampleRegister & 0x07) == 0x07) {
+ /* No carrier modulation for 3 sample points. EOC! */
+ CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
+ CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCAIF_bm;
+
+ /* By this time, the FDT timer is aligned to the last modulation
+ * edge of the reader. So we disable the auto-synchronization and
+ * let it count the frame delay time in the background, and generate
+ * an interrupt once it has reached the FDT. */
+ CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc;
+
+ if (LastBit) {
+ CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV1;
+ } else {
+ CODEC_TIMER_LOADMOD.PER = ISO14443A_FRAME_DELAY_PREV0;
+ }
+
+ LoadModState = LOADMOD_FDT;
+
+ CODEC_TIMER_LOADMOD.INTFLAGS = TC1_OVFIF_bm;
+ CODEC_TIMER_LOADMOD.INTCTRLA = TC_OVFINTLVL_HI_gc;
+
+ /* Determine if we did not receive a multiple of 8 bits.
+ * If this is the case, right-align the remaining data and
+ * store it into the buffer. */
+ uint8_t RemainingBits = BitCount % 8;
+ if (RemainingBits != 0) {
+ uint8_t NewDataRegister = DataRegister;
+
+ while (RemainingBits++ < 8) {
+ /* Pad with zeroes to right-align. */
+ NewDataRegister >>= 1;
+ }
+
+ /* TODO: Prevent buffer overflow */
+ *CodecBufferPtr = NewDataRegister;
+ }
+
+ /* Signal, that we have finished sampling */
+ Flags.DemodFinished = 1;
+ } else {
+ /* Otherwise, we check the two sample bits from the bit before. */
+ uint8_t BitSample = NewSampleRegister & 0xC;
+ uint8_t Bit = 0;
+
+ if (BitSample != (0x0 << 2)) {
+ /* We have a valid bit. decode and process it. */
+ if (BitSample & (0x1 << 2)) {
+ /* 01 sequence or 11 sequence -> This is a zero bit */
+ Bit = 0;
+ } else {
+ /* 10 sequence -> This is a one bit */
+ Bit = 1;
+ }
+
+ LastBit = Bit;
+
+ if (!IsParityBit) {
+ /* This is a data bit, so shift it into the data register and
+ * hold a local copy of it. */
+ uint8_t NewDataRegister = DataRegister >> 1;
+ NewDataRegister |= (Bit ? 0x80 : 0x00);
+ DataRegister = NewDataRegister;
+
+ /* Update bitcount */
+ uint16_t NewBitCount = ++BitCount;
+ if ((NewBitCount & 0x07) == 0) {
+ /* We have reached a byte boundary! Store the data register. */
+ /* TODO: Prevent buffer overflow */
+ *CodecBufferPtr++ = NewDataRegister;
+
+ /* Store bit for determining FDT at EOC and enable parity
+ * handling on next bit. */
+ IsParityBit = true;
+ }
+
+ } else {
+ /* This is a parity bit. Store it */
+ /* TODO: Store parity and prevent overflow */
+ //*ParityBufferPtr++ = Bit;
+ IsParityBit = false;
+ }
+ } else {
+ /* 00 sequence. -> No valid data yet. This also occurs if we just started
+ * sampling and have sampled less than 2 bits yet. Thus ignore. */
+ }
+ }
+ } else {
+ /* On odd sample position just sample. */
+ }
+
+ SamplePosition = !SamplePosition;
+
+ /* Make sure the sampling timer gets automatically aligned to the
+ * modulation pauses by using the RESTART event.
+ * This can be understood as a "poor mans PLL" and makes sure that we are
+ * never too far out the bit-grid while sampling. */
+ CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_RESTART_gc | TC_EVSEL_CH0_gc;
+}
+
+ISR(CODEC_TIMER_OVF_VECT) {
+ /* Bit rate timer. Output a half bit on the output. */
+ uint8_t Temp8;
+ uint16_t Temp16;
+
+ switch (LoadModState) {
+ case LOADMOD_FDT:
+ /* No data has been produced, but FDT has ended. Switch over to bit-grid aligning. */
+ CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_GRID_CYCLES - 1;
+ break;
+
+ case LOADMOD_START:
+ /* Application produced data. With this interrupt we are aligned to the bit-grid.
+ * Start subcarrier generation and align to bitrate. */
+ CODEC_TIMER_LOADMOD.PER = ISO14443A_BIT_RATE_CYCLES / 2 - 1;
+ CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_EVCH6_gc;
+
+ /* Fallthrough to first bit */
+
+ case LOADMOD_START_BIT0:
+ CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK;
+ LoadModState = LOADMOD_START_BIT1;
+ break;
+
+ case LOADMOD_START_BIT1:
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ LoadModState = LOADMOD_DATA0;
+
+ /* Fetch first byte */
+ DataRegister = *CodecBufferPtr;
+ break;
+
+ case LOADMOD_DATA0:
+ if (DataRegister & 1) {
+ CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK;
+ } else {
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ }
+
+ LoadModState = LOADMOD_DATA1;
+ break;
+
+ case LOADMOD_DATA1:
+ Temp8 = DataRegister;
+
+ if (Temp8 & 1) {
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ } else {
+ CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK;
+ }
+
+ DataRegister = Temp8 >> 1;
+
+ Temp16 = BitSent;
+ BitSent = ++Temp16;
+
+ if ((Temp16 & 0x07) == 0) {
+ /* Byte boundary. Load parity bit and output it later. */
+ LoadModState = LOADMOD_PARITY0;
+ break;
+ }
+
+ if (Temp16 == BitCount) {
+ /* End of transmission without byte boundary. Don't send parity. */
+ LoadModState = LOADMOD_STOP_BIT0;
+ break;
+ }
+
+ /* Next bit is data */
+ LoadModState = LOADMOD_DATA0;
+
+ break;
+
+ case LOADMOD_PARITY0:
+ if (*ParityBufferPtr) {
+ CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK;
+ } else {
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ }
+
+ LoadModState = LOADMOD_PARITY1;
+ break;
+
+ case LOADMOD_PARITY1:
+ if (*ParityBufferPtr) {
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ } else {
+ CODEC_LOADMOD_PORT.OUTSET = CODEC_LOADMOD_MASK;
+ }
+
+ if (BitSent == BitCount) {
+ /* No data left */
+ LoadModState = LOADMOD_STOP_BIT0;
+ } else {
+ /* Fetch next data and continue sending bits. */
+ ParityBufferPtr++;
+ DataRegister = *++CodecBufferPtr;
+ LoadModState = LOADMOD_DATA0;
+ }
+
+ break;
+
+ case LOADMOD_STOP_BIT0:
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ LoadModState = LOADMOD_STOP_BIT1;
+ break;
+
+ case LOADMOD_STOP_BIT1:
+ CODEC_LOADMOD_PORT.OUTCLR = CODEC_LOADMOD_MASK;
+ LoadModState = LOADMOD_FINISHED;
+ break;
+
+ case LOADMOD_FINISHED:
+ /* We have written all of our bits. Deactivate the loadmod
+ * timer. Also disable the bit-rate interrupt again. And
+ * stop the subcarrier divider. */
+ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc;
+ CODEC_TIMER_LOADMOD.INTCTRLA = 0;
+ CODEC_SUBCARRIER_TIMER.CTRLA = TC_CLKSEL_OFF_gc;
+
+ /* Signal application that we have finished loadmod */
+ Flags.LoadmodFinished = 1;
+ break;
+
+ default:
+ break;
+ }
+}
+
+void ISO14443ACodecInit(void)
+{
+ /* Initialize common peripherals and start listening
+ * for incoming data. */
+ Initialize();
+ StartDemod();
+}
+
+/***
+ * CHECKME!!! Mostly copied from RevG
+ ***/
+void ISO14443ACodecDeInit(void)
+{
+ /* Gracefully shutdown codec */
+ CODEC_DEMOD_IN_PORT.INT0MASK = 0;
+
+ Flags.DemodFinished = 0;
+ Flags.LoadmodFinished = 0;
+
+ CODEC_TIMER_SAMPLING.CTRLA = TC_CLKSEL_OFF_gc;
+ CODEC_TIMER_SAMPLING.CTRLD = TC_EVACT_OFF_gc;
+ CODEC_TIMER_SAMPLING.INTCTRLB = TC_CCAINTLVL_OFF_gc;
+ CODEC_TIMER_SAMPLING.INTFLAGS = TC0_CCAIF_bm;
+
+
+ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc;
+ CODEC_TIMER_LOADMOD.CTRLD = TC_EVACT_OFF_gc;
+ CODEC_TIMER_LOADMOD.INTCTRLA = TC_OVFINTLVL_HI_gc;
+ CODEC_TIMER_LOADMOD.INTFLAGS = TC0_OVFIF_bm;
+
+ //CodecSetSubcarrier(CODEC_SUBCARRIERMOD_OFF, 0);
+ CodecSetDemodPower(false);
+ //CodecSetLoadmodState(false);
+
+}
+
+void ISO14443ACodecTask(void) {
+ if (Flags.DemodFinished) {
+ Flags.DemodFinished = 0;
+ /* Reception finished. Process the received bytes */
+ CodecSetDemodPower(false);
+
+ uint16_t DemodBitCount = BitCount;
+ uint16_t AnswerBitCount = ISO14443A_APP_NO_RESPONSE;
+
+ if (DemodBitCount > 0) {
+ LogEntry(LOG_INFO_CODEC_RX_DATA, CodecBuffer, (DemodBitCount+7)/8);
+ LEDHook(LED_CODEC_RX, LED_PULSE);
+
+ /* Call application if we received data */
+ AnswerBitCount = ApplicationProcess(CodecBuffer, DemodBitCount);
+
+ if (AnswerBitCount & ISO14443A_APP_CUSTOM_PARITY) {
+ /* Application has generated it's own parity bits.
+ * Clear this option bit. */
+ AnswerBitCount &= ~ISO14443A_APP_CUSTOM_PARITY;
+ } else {
+ /* We have to generate the parity bits ourself */
+ for (uint8_t i = 0; i < (AnswerBitCount / 8); i++) {
+ /* For each whole byte, generate a parity bit. */
+ CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET + i] =
+ ODD_PARITY(CodecBuffer[i]);
+ }
+ }
+ } else {
+ ApplicationReset();
+ }
+
+ if (AnswerBitCount != ISO14443A_APP_NO_RESPONSE) {
+ LogEntry(LOG_INFO_CODEC_TX_DATA, CodecBuffer, (AnswerBitCount + 7) / 8);
+ LEDHook(LED_CODEC_TX, LED_PULSE);
+
+ BitCount = AnswerBitCount;
+ BitSent = 0;
+ CodecBufferPtr = CodecBuffer;
+ ParityBufferPtr = &CodecBuffer[ISO14443A_BUFFER_PARITY_OFFSET];
+ LoadModState = LOADMOD_START;
+ } else {
+ /* No data to be processed. Disable loadmodding and start listening again */
+ CODEC_TIMER_LOADMOD.CTRLA = TC_CLKSEL_OFF_gc;
+ CODEC_TIMER_LOADMOD.INTCTRLA = 0;
+
+ StartDemod();
+ }
+ }
+
+ if (Flags.LoadmodFinished) {
+ Flags.LoadmodFinished = 0;
+ /* Load modulation has been finished. Stop it and start to listen
+ * for incoming data again. */
+ StartDemod();
+ }
+
+ //SystemSleep();
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h b/RevE-light/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h
new file mode 100644
index 0000000..7370ccb
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Codec/ISO14443-2A.h
@@ -0,0 +1,24 @@
+/*
+ * ISO14443-2A.h
+ *
+ * Created on: 18.02.2013
+ * Author: skuser
+ */
+
+#ifndef ISO14443_2A_H_
+#define ISO14443_2A_H_
+
+#include "Codec.h"
+
+#define ISO14443A_APP_NO_RESPONSE 0x0000
+#define ISO14443A_APP_CUSTOM_PARITY 0x1000
+
+#define ISO14443A_BUFFER_PARITY_OFFSET (CODEC_BUFFER_SIZE/2)
+
+/* Codec Interface */
+void ISO14443ACodecInit(void);
+void ISO14443ACodecTask(void);
+void ISO14443ACodecDeInit(void);
+
+
+#endif
diff --git a/RevE-light/Firmware/Chameleon-Mini/Common.c b/RevE-light/Firmware/Chameleon-Mini/Common.c
new file mode 100644
index 0000000..36af329
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Common.c
@@ -0,0 +1,64 @@
+#include "Common.h"
+
+uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount)
+{
+ uint8_t* ByteBuffer = (uint8_t*) Buffer;
+ uint16_t CharCount = 0;
+
+ /* Account for '\0' at the end */
+ MaxChars--;
+
+ while( (ByteCount > 0) && (MaxChars >= 2) ) {
+ uint8_t Byte = *ByteBuffer;
+
+ HexOut[0] = NIBBLE_TO_HEXCHAR( (Byte >> 4) & 0x0F );
+ HexOut[1] = NIBBLE_TO_HEXCHAR( (Byte >> 0) & 0x0F );
+
+ HexOut += 2;
+ MaxChars -= 2;
+ CharCount += 2;
+ ByteBuffer++;
+ ByteCount -= 1;
+ }
+
+ *HexOut = '\0';
+
+ return CharCount;
+}
+
+uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn)
+{
+ uint8_t* ByteBuffer = (uint8_t*) Buffer;
+ uint16_t ByteCount = 0;
+
+ while( (HexIn[0] != '\0') && (HexIn[1] != '\0') && (MaxBytes > 0) ) {
+ if (VALID_HEXCHAR(HexIn[0]) && VALID_HEXCHAR(HexIn[1])) {
+ uint8_t Byte = 0;
+
+ Byte |= HEXCHAR_TO_NIBBLE(HexIn[0]) << 4;
+ Byte |= HEXCHAR_TO_NIBBLE(HexIn[1]) << 0;
+
+ *ByteBuffer = Byte;
+
+ ByteBuffer++;
+ MaxBytes--;
+ ByteCount++;
+ HexIn += 2;
+ } else {
+ /* HEX chars only */
+ return 0;
+ }
+ }
+
+ if ( (HexIn[0] != '\0') && (HexIn[1] == '\0') ) {
+ /* Odd number of characters */
+ return 0;
+ }
+
+ return ByteCount;
+}
+
+
+
+
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Common.h b/RevE-light/Firmware/Chameleon-Mini/Common.h
new file mode 100644
index 0000000..8aeeff8
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Common.h
@@ -0,0 +1,48 @@
+/*
+ * Common.h
+ *
+ * Created on: 20.03.2013
+ * Author: skuser
+ */
+
+#ifndef COMMON_H_
+#define COMMON_H_
+
+#include
+#include
+#include
+#include
+#include
+
+#define ODD_PARITY(Value) (parity_even_bit(Value) ? 0 : 1)
+
+#define INLINE \
+ static inline __attribute__((always_inline))
+
+#define NIBBLE_TO_HEXCHAR(x) ( (x) < 0x0A ? (x) + '0' : (x) + 'A' - 0x0A )
+#define HEXCHAR_TO_NIBBLE(x) ( (x) < 'A' ? (x) - '0' : (x) - 'A' + 0x0A )
+#define VALID_HEXCHAR(x) ( ( (x) >= '0' && (x) <= '9' ) || ( (x) >= 'A' && (x) <= 'F' ) )
+#define MIN(x,y) ( (x) < (y) ? (x) : (y) )
+#define MAX(x,y) ( (x) > (y) ? (x) : (y) )
+
+#define BITS_PER_BYTE 8
+
+uint16_t BufferToHexString(char* HexOut, uint16_t MaxChars, const void* Buffer, uint16_t ByteCount);
+uint16_t HexStringToBuffer(void* Buffer, uint16_t MaxBytes, const char* HexIn);
+
+INLINE uint8_t StringLength(const char* Str, uint8_t MaxLen)
+{
+ uint8_t StrLen = 0;
+
+ while(MaxLen > 0) {
+ if (*Str++ == '\0')
+ break;
+
+ MaxLen--;
+ StrLen++;
+ }
+
+ return StrLen;
+}
+
+#endif /* COMMON_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Configuration.c b/RevE-light/Firmware/Chameleon-Mini/Configuration.c
new file mode 100644
index 0000000..15a78e8
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Configuration.c
@@ -0,0 +1,178 @@
+/*
+ * Standards.c
+ *
+ * Created on: 15.02.2013
+ * Author: skuser
+ */
+
+#include "Configuration.h"
+#include "Settings.h"
+#include
+#include "Map.h"
+
+/* Map IDs to text */
+static const MapEntryType PROGMEM ConfigurationMap[] = {
+ { .Id = CONFIG_NONE, .Text = "NONE" },
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+ { .Id = CONFIG_MF_ULTRALIGHT, .Text = "MF_ULTRALIGHT" },
+#endif
+#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+ { .Id = CONFIG_MF_CLASSIC_1K, .Text = "MF_CLASSIC_1K" },
+#endif
+#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
+ { .Id = CONFIG_MF_CLASSIC_4K, .Text = "MF_CLASSIC_4K" },
+#endif
+#ifdef CONFIG_ISO14443A_SNIFF_SUPPORT
+ { .Id = CONFIG_ISO14443A_SNIFF, .Text = "ISO14443A_SNIFF" },
+#endif
+};
+
+/* Include all Codecs and Applications */
+#include "Codec/Codec.h"
+#include "Application/Application.h"
+
+static void CodecInitDummy(void) { }
+static void CodecDeInitDummy(void) { }
+static void CodecTaskDummy(void) { }
+static void ApplicationInitDummy(void) {}
+static void ApplicationResetDummy(void) {}
+static void ApplicationTaskDummy(void) {}
+static void ApplicationTickDummy(void) {}
+static uint16_t ApplicationProcessDummy(uint8_t* ByteBuffer, uint16_t ByteCount) { return 0; }
+static void ApplicationGetUidDummy(ConfigurationUidType Uid) { }
+static void ApplicationSetUidDummy(ConfigurationUidType Uid) { }
+
+
+static const PROGMEM ConfigurationType ConfigurationTable[] = {
+ [CONFIG_NONE] = {
+ .CodecInitFunc = CodecInitDummy,
+ .CodecDeInitFunc = CodecDeInitDummy,
+ .CodecTaskFunc = CodecTaskDummy,
+ .ApplicationInitFunc = ApplicationInitDummy,
+ .ApplicationResetFunc = ApplicationResetDummy,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
+ .ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationProcessFunc = ApplicationProcessDummy,
+ .ApplicationGetUidFunc = ApplicationGetUidDummy,
+ .ApplicationSetUidFunc = ApplicationSetUidDummy,
+ .UidSize = 0,
+ .MemorySize = 0,
+ .ReadOnly = true
+ },
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+ [CONFIG_MF_ULTRALIGHT] = {
+ .CodecInitFunc = ISO14443ACodecInit,
+ .CodecDeInitFunc = ISO14443ACodecDeInit,
+ .CodecTaskFunc = ISO14443ACodecTask,
+ .ApplicationInitFunc = MifareUltralightAppInit,
+ .ApplicationResetFunc = MifareUltralightAppReset,
+ .ApplicationTaskFunc = MifareUltralightAppTask,
+ .ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationProcessFunc = MifareUltralightAppProcess,
+ .ApplicationGetUidFunc = MifareUltralightGetUid,
+ .ApplicationSetUidFunc = MifareUltralightSetUid,
+ .UidSize = MIFARE_ULTRALIGHT_UID_SIZE,
+ .MemorySize = MIFARE_ULTRALIGHT_MEM_SIZE,
+ .ReadOnly = false
+ },
+#endif
+#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+ [CONFIG_MF_CLASSIC_1K] = {
+ .CodecInitFunc = ISO14443ACodecInit,
+ .CodecDeInitFunc = ISO14443ACodecDeInit,
+ .CodecTaskFunc = ISO14443ACodecTask,
+ .ApplicationInitFunc = MifareClassicAppInit1K,
+ .ApplicationResetFunc = MifareClassicAppReset,
+ .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationProcessFunc = MifareClassicAppProcess,
+ .ApplicationGetUidFunc = MifareClassicGetUid,
+ .ApplicationSetUidFunc = MifareClassicSetUid,
+ .UidSize = MIFARE_CLASSIC_UID_SIZE,
+ .MemorySize = MIFARE_CLASSIC_1K_MEM_SIZE,
+ .ReadOnly = false
+ },
+#endif
+#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
+ [CONFIG_MF_CLASSIC_4K] = {
+ .CodecInitFunc = ISO14443ACodecInit,
+ .CodecDeInitFunc = ISO14443ACodecDeInit,
+ .CodecTaskFunc = ISO14443ACodecTask,
+ .ApplicationInitFunc = MifareClassicAppInit4K,
+ .ApplicationResetFunc = MifareClassicAppReset,
+ .ApplicationTaskFunc = MifareClassicAppTask,
+ .ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationProcessFunc = MifareClassicAppProcess,
+ .ApplicationGetUidFunc = MifareClassicGetUid,
+ .ApplicationSetUidFunc = MifareClassicSetUid,
+ .UidSize = MIFARE_CLASSIC_UID_SIZE,
+ .MemorySize = MIFARE_CLASSIC_4K_MEM_SIZE,
+ .ReadOnly = false
+ },
+#endif
+#ifdef CONFIG_ISO14443A_SNIFF_SUPPORT
+ [CONFIG_ISO14443A_SNIFF] = {
+ .CodecInitFunc = ISO14443ACodecInit,
+ .CodecDeInitFunc = ISO14443ACodecDeInit,
+ .CodecTaskFunc = ISO14443ACodecTask,
+ .ApplicationInitFunc = ApplicationInitDummy,
+ .ApplicationResetFunc = ApplicationResetDummy,
+ .ApplicationTaskFunc = ApplicationTaskDummy,
+ .ApplicationTickFunc = ApplicationTickDummy,
+ .ApplicationProcessFunc = ApplicationProcessDummy,
+ .ApplicationGetUidFunc = ApplicationGetUidDummy,
+ .ApplicationSetUidFunc = ApplicationSetUidDummy,
+ .UidSize = 0,
+ .MemorySize = 0,
+ .ReadOnly = true
+ },
+#endif
+};
+
+ConfigurationType ActiveConfiguration;
+
+void ConfigurationInit(void)
+{
+ memcpy_P(&ActiveConfiguration,
+ &ConfigurationTable[CONFIG_NONE], sizeof(ConfigurationType));
+
+ ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
+}
+
+void ConfigurationSetById( ConfigurationEnum Configuration )
+{
+ CodecDeInit();
+
+ GlobalSettings.ActiveSettingPtr->Configuration = Configuration;
+
+ /* Copy struct from PROGMEM to RAM */
+ memcpy_P(&ActiveConfiguration,
+ &ConfigurationTable[Configuration], sizeof(ConfigurationType));
+
+ ApplicationInit();
+ CodecInit();
+}
+
+void ConfigurationGetByName(char* Configuration, uint16_t BufferSize)
+{
+ MapIdToText(ConfigurationMap, sizeof(ConfigurationMap)/sizeof(*ConfigurationMap), GlobalSettings.ActiveSettingPtr->Configuration, Configuration, BufferSize);
+}
+
+bool ConfigurationSetByName(const char* Configuration)
+{
+ MapIdType Id;
+
+ if (MapTextToId(ConfigurationMap, sizeof(ConfigurationMap)/sizeof(*ConfigurationMap), Configuration, &Id)) {
+ ConfigurationSetById(Id);
+ LogEntry(LOG_INFO_CONFIG_SET, Configuration, StringLength(Configuration, CONFIGURATION_NAME_LENGTH_MAX-1));
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void ConfigurationGetList(char* List, uint16_t BufferSize)
+{
+ MapToString(ConfigurationMap, sizeof(ConfigurationMap)/sizeof(*ConfigurationMap), List, BufferSize);
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Configuration.h b/RevE-light/Firmware/Chameleon-Mini/Configuration.h
new file mode 100644
index 0000000..1d0ce71
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Configuration.h
@@ -0,0 +1,69 @@
+/*
+ * Standards.h
+ *
+ * Created on: 15.02.2013
+ * Author: skuser
+ */
+
+#ifndef STANDARDS_H_
+#define STANDARDS_H_
+
+#include
+#include
+
+#define CONFIGURATION_NAME_LENGTH_MAX 32
+#define CONFIGURATION_UID_SIZE_MAX 16
+
+typedef uint8_t ConfigurationUidType[CONFIGURATION_UID_SIZE_MAX];
+
+typedef enum {
+ /* This HAS to be the first element */
+ CONFIG_NONE = 0,
+
+#ifdef CONFIG_MF_ULTRALIGHT_SUPPORT
+ CONFIG_MF_ULTRALIGHT,
+#endif
+#ifdef CONFIG_MF_CLASSIC_1K_SUPPORT
+ CONFIG_MF_CLASSIC_1K,
+#endif
+#ifdef CONFIG_MF_CLASSIC_4K_SUPPORT
+ CONFIG_MF_CLASSIC_4K,
+#endif
+#ifdef CONFIG_ISO14443A_SNIFF_SUPPORT
+ CONFIG_ISO14443A_SNIFF,
+#endif
+
+ /* This HAS to be the last element */
+ CONFIG_COUNT
+} ConfigurationEnum;
+
+typedef struct {
+ /* Codec used for this configuration */
+ void (*CodecInitFunc) (void);
+ void (*CodecDeInitFunc) (void);
+ void (*CodecTaskFunc) (void);
+
+ /* Application used for this configuration */
+ void (*ApplicationInitFunc) (void);
+ void (*ApplicationResetFunc) (void);
+ void (*ApplicationTaskFunc) (void);
+ void (*ApplicationTickFunc) (void);
+ uint16_t (*ApplicationProcessFunc) (uint8_t* ByteBuffer, uint16_t ByteCount);
+ void (*ApplicationGetUidFunc) (ConfigurationUidType Uid);
+ void (*ApplicationSetUidFunc) (ConfigurationUidType Uid);
+
+ uint16_t MemorySize;
+ uint8_t UidSize;
+ bool ReadOnly;
+
+} ConfigurationType;
+
+extern ConfigurationType ActiveConfiguration;
+
+void ConfigurationInit(void);
+void ConfigurationSetById(ConfigurationEnum Configuration);
+void ConfigurationGetByName(char* Configuration, uint16_t BufferSize);
+bool ConfigurationSetByName(const char* Configuration);
+void ConfigurationGetList(char* ConfigurationList, uint16_t BufferSize);
+
+#endif /* STANDARDS_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/LED.c b/RevE-light/Firmware/Chameleon-Mini/LED.c
new file mode 100644
index 0000000..e6b2d72
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/LED.c
@@ -0,0 +1,163 @@
+#include "LED.h"
+#include "Settings.h"
+#include "Map.h"
+
+#define BLINK_PRESCALER 1 /* x LEDTick(); */
+
+LEDActionEnum LEDGreenAction = LED_NO_ACTION;
+LEDActionEnum LEDRedAction = LED_NO_ACTION;
+
+static const MapEntryType PROGMEM LEDFunctionMap[] = {
+ { .Id = LED_NO_FUNC, .Text = "NONE" },
+ { .Id = LED_POWERED, .Text = "POWERED" },
+ { .Id = LED_TERMINAL_CONN, .Text = "TERMINAL_CONN" },
+ { .Id = LED_TERMINAL_RXTX, .Text = "TERMINAL_RXTX" },
+ { .Id = LED_SETTING_CHANGE, .Text = "SETTING_CHANGE" },
+ { .Id = LED_MEMORY_STORED, .Text = "MEMORY_STORED" },
+ { .Id = LED_MEMORY_CHANGED, .Text = "MEMORY_CHANGED" },
+ { .Id = LED_CODEC_RX, .Text = "CODEC_RX" },
+ { .Id = LED_CODEC_TX, .Text = "CODEC_TX" }
+ //TODO: [LED_FIELD_DETECTED] = "FIELD_DETECTED",
+ //TODO: [LED_APP_SELECTED] = "APP_SELECTED",
+};
+
+INLINE void Tick(uint8_t Mask, LEDActionEnum* Action)
+{
+ static uint8_t BlinkPrescaler = 0;
+
+ switch (*Action)
+ {
+ case LED_NO_ACTION:
+ /* Do nothing */
+ break;
+
+ case LED_OFF:
+ LED_PORT.OUTCLR = Mask;
+ *Action = LED_NO_ACTION;
+ break;
+
+ case LED_ON:
+ LED_PORT.OUTSET = Mask;
+ *Action = LED_NO_ACTION;
+ break;
+
+ case LED_TOGGLE:
+ LED_PORT.OUTTGL = Mask;
+ *Action = LED_NO_ACTION;
+ break;
+
+ case LED_PULSE:
+ if (!(LED_PORT.OUT & Mask)) {
+ LED_PORT.OUTSET = Mask;
+ } else {
+ LED_PORT.OUTCLR = Mask;
+ *Action = LED_NO_ACTION;
+ }
+ break;
+
+ case LED_BLINK_1X ... LED_BLINK_8X:
+ if (++BlinkPrescaler == BLINK_PRESCALER) {
+ BlinkPrescaler = 0;
+ /* Blink functionality occurs at slower speed than Tick-frequency */
+
+ if (!(LED_PORT.OUT & Mask)) {
+ /* LED is off, turn it on */
+ LED_PORT.OUTSET = Mask;
+ } else {
+ /* LED is on, turn it off and change state */
+ LED_PORT.OUTCLR = Mask;
+
+ if (*Action == LED_BLINK_1X) {
+ *Action = LED_NO_ACTION;
+ } else {
+ /* Still some blinks to do. Use the fact that LED_BLINK_XY are ordered sequentially */
+ *Action = *Action - 1;
+ }
+ }
+ }
+ break;
+
+ default:
+ /* Should not happen (TM) */
+ *Action = LED_NO_ACTION;
+ break;
+
+ }
+}
+
+void LEDInit(void)
+{
+ LED_PORT.DIRSET = LED_MASK;
+}
+
+
+void LEDTick(void)
+{
+ Tick(LED_RED, &LEDRedAction);
+ Tick(LED_GREEN, &LEDGreenAction);
+}
+
+void LEDGetFuncList(char* List, uint16_t BufferSize)
+{
+ MapToString(LEDFunctionMap, sizeof(LEDFunctionMap)/sizeof(*LEDFunctionMap), List, BufferSize);
+}
+
+void LEDSetFuncById(uint8_t Mask, LEDHookEnum Function)
+{
+#ifndef LED_SETTING_GLOBAL
+ if (Mask & LED_GREEN) {
+ GlobalSettings.ActiveSettingPtr->LEDGreenFunction = Function;
+ }
+
+ if (Mask & LED_RED) {
+ GlobalSettings.ActiveSettingPtr->LEDRedFunction = Function;
+ }
+#else
+ /* Write LED func to all settings when using global settings */
+ for (uint8_t i=0; iLEDGreenFunction, Function, BufferSize);
+ } else if (Mask == LED_RED) {
+ MapIdToText(LEDFunctionMap, sizeof(LEDFunctionMap)/sizeof(*LEDFunctionMap),
+ GlobalSettings.ActiveSettingPtr->LEDRedFunction, Function, BufferSize);
+ }
+}
+
+bool LEDSetFuncByName(uint8_t Mask, const char* Function)
+{
+ MapIdType Id;
+
+ if (MapTextToId(LEDFunctionMap, sizeof(LEDFunctionMap)/sizeof(*LEDFunctionMap), Function, &Id)) {
+ LEDSetFuncById(Mask, Id);
+ return true;
+ } else {
+ return false;
+ }
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/LED.h b/RevE-light/Firmware/Chameleon-Mini/LED.h
new file mode 100644
index 0000000..03c1cc4
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/LED.h
@@ -0,0 +1,69 @@
+/*
+ * LED.h
+ *
+ * Created on: 10.02.2013
+ * Author: skuser
+ */
+
+#ifndef LED_H
+#define LED_H
+
+#include
+#include "Common.h"
+
+#define LED_PORT PORTA
+#define LED_GREEN PIN5_bm
+#define LED_RED PIN4_bm
+#define LED_MASK (LED_GREEN | LED_RED)
+
+typedef enum LEDFunctionEnum {
+ LED_NO_FUNC = 0, /* Don't light up the LED */
+ LED_POWERED, /* Light up the LED whenever the Chameleon is powered */
+
+ LED_TERMINAL_CONN, /* A Terminal/USB connection has been established */
+ LED_TERMINAL_RXTX, /* There is traffic on the terminal */
+
+ LED_SETTING_CHANGE, /* Outputs a blink code that shows the current setting */
+
+ LED_MEMORY_STORED, /* Blink once when memory has been stored to flash */
+ LED_MEMORY_CHANGED, /* Switch LED on when card memory has changed compared to flash */
+
+ //TODO: LED_FIELD_DETECTED, /* Shows LED while a reader field is being detected */
+
+ LED_CODEC_RX, /* Blink LED when receiving codec data */
+ LED_CODEC_TX, /* Blink LED when transmitting codec data */
+
+ //TODO: LED_APP_SELECTED, /* Show LED while the correct UID has been selected and the application is active */
+
+ /* Has to be last element */
+ LED_FUNC_COUNT
+} LEDHookEnum;
+
+typedef enum LEDActionEnum {
+ LED_NO_ACTION = 0x00,
+ LED_OFF = 0x10,
+ LED_ON = 0x11,
+ LED_TOGGLE = 0x12,
+ LED_PULSE = 0x13,
+ LED_BLINK = 0x20,
+ LED_BLINK_1X = 0x20,
+ LED_BLINK_2X, /* Have to be sequentially ordered */
+ LED_BLINK_3X,
+ LED_BLINK_4X,
+ LED_BLINK_5X,
+ LED_BLINK_6X,
+ LED_BLINK_7X,
+ LED_BLINK_8X,
+} LEDActionEnum;
+
+
+
+void LEDInit(void);
+void LEDTick(void);
+
+void LEDGetFuncList(char* List, uint16_t BufferSize);
+void LEDSetFuncById(uint8_t Mask, LEDHookEnum Func);
+void LEDGetFuncByName(uint8_t Mask, char* Function, uint16_t BufferSize);
+bool LEDSetFuncByName(uint8_t Mask, const char* Function);
+
+#endif /* LED_H */
\ No newline at end of file
diff --git a/RevE-light/Firmware/Chameleon-Mini/LEDHook.h b/RevE-light/Firmware/Chameleon-Mini/LEDHook.h
new file mode 100644
index 0000000..f187ab4
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/LEDHook.h
@@ -0,0 +1,29 @@
+/*
+ * LEDHook.h
+ *
+ * Created on: 02.12.2014
+ * Author: sk
+ */
+
+#ifndef LEDHOOK_H_
+#define LEDHOOK_H_
+
+#include "Settings.h"
+
+INLINE void LEDHook(LEDHookEnum Func, LEDActionEnum Action)
+{
+ extern LEDActionEnum LEDGreenAction;
+ extern LEDActionEnum LEDRedAction;
+
+ if (GlobalSettings.ActiveSettingPtr->LEDGreenFunction == Func)
+ {
+ LEDGreenAction = Action;
+ }
+
+ if (GlobalSettings.ActiveSettingPtr->LEDRedFunction == Func)
+ {
+ LEDRedAction = Action;
+ }
+}
+
+#endif /* LEDHOOK_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/LUFAConfig.h b/RevE-light/Firmware/Chameleon-Mini/LUFAConfig.h
new file mode 100644
index 0000000..98f60ed
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/LUFAConfig.h
@@ -0,0 +1,78 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ * \brief LUFA Library Configuration Header File
+ *
+ * This header file is used to configure LUFA's compile time options,
+ * as an alternative to the compile time constants supplied through
+ * a makefile.
+ *
+ * For information on what each token does, refer to the LUFA
+ * manual section "Summary of Compile Tokens".
+ */
+
+#ifndef _LUFA_CONFIG_H_
+#define _LUFA_CONFIG_H_
+
+ /* Non-USB Related Configuration Tokens: */
+// #define DISABLE_TERMINAL_CODES
+
+ /* USB Class Driver Related Tokens: */
+// #define HID_HOST_BOOT_PROTOCOL_ONLY
+// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here}
+// #define HID_USAGE_STACK_DEPTH {Insert Value Here}
+// #define HID_MAX_COLLECTIONS {Insert Value Here}
+// #define HID_MAX_REPORTITEMS {Insert Value Here}
+// #define HID_MAX_REPORT_IDS {Insert Value Here}
+// #define NO_CLASS_DRIVER_AUTOFLUSH
+
+ /* General USB Driver Related Tokens: */
+ #define USE_STATIC_OPTIONS \
+ (USB_OPT_BUSEVENT_PRIMED | USB_DEVICE_OPT_FULLSPEED | USB_OPT_PLLCLKSRC /*USB_OPT_RC32MCLKSRC*/)
+ #define USB_DEVICE_ONLY
+// #define USB_STREAM_TIMEOUT_MS {Insert Value Here}
+// #define NO_LIMITED_CONTROLLER_CONNECT
+// #define NO_SOF_EVENTS
+
+ /* USB Device Mode Driver Related Tokens: */
+// #define USE_RAM_DESCRIPTORS
+ #define USE_FLASH_DESCRIPTORS
+// #define USE_EEPROM_DESCRIPTORS
+// #define NO_INTERNAL_SERIAL
+ #define FIXED_CONTROL_ENDPOINT_SIZE 8
+// #define DEVICE_STATE_AS_GPIOR {Insert Value Here}
+ #define FIXED_NUM_CONFIGURATIONS 1
+// #define CONTROL_ONLY_DEVICE
+ #define MAX_ENDPOINT_INDEX 5
+// #define NO_DEVICE_REMOTE_WAKEUP
+// #define NO_DEVICE_SELF_POWER
+
+#endif
diff --git a/RevE-light/Firmware/Chameleon-Mini/LUFADescriptors.c b/RevE-light/Firmware/Chameleon-Mini/LUFADescriptors.c
new file mode 100644
index 0000000..6a9ed25
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/LUFADescriptors.c
@@ -0,0 +1,260 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * USB Device Descriptors, for library use when in USB device mode. Descriptors are special
+ * computer-readable structures which the host requests upon device enumeration, to determine
+ * the device's capabilities and functions.
+ */
+
+#include "LUFADescriptors.h"
+
+
+/** Device descriptor structure. This descriptor, located in FLASH memory, describes the overall
+ * device characteristics, including the supported USB version, control endpoint size and the
+ * number of device configurations. The descriptor is read out by the USB host when the enumeration
+ * process begins.
+ */
+const USB_Descriptor_Device_t PROGMEM DeviceDescriptor =
+{
+ .Header = {.Size = sizeof(USB_Descriptor_Device_t), .Type = DTYPE_Device},
+
+ .USBSpecification = VERSION_BCD(1,1,0),
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_NoSpecificSubclass,
+ .Protocol = CDC_CSCP_NoSpecificProtocol,
+
+ .Endpoint0Size = FIXED_CONTROL_ENDPOINT_SIZE,
+
+ .VendorID = 0x16D0, // MCS Electronics (http://www.mcselec.com)
+ .ProductID = 0x04B2, // darksimpson's PID #2 granted to Chameleon-Mini
+ .ReleaseNumber = VERSION_BCD(0,0,1),
+
+ .ManufacturerStrIndex = 0x01,
+ .ProductStrIndex = 0x02,
+ .SerialNumStrIndex = USE_INTERNAL_SERIAL,
+
+ .NumberOfConfigurations = FIXED_NUM_CONFIGURATIONS
+};
+
+/** Configuration descriptor structure. This descriptor, located in FLASH memory, describes the usage
+ * of the device in one of its supported configurations, including information about any device interfaces
+ * and endpoints. The descriptor is read out by the USB host during the enumeration process when selecting
+ * a configuration so that the host may correctly communicate with the USB device.
+ */
+const USB_Descriptor_Configuration_t PROGMEM ConfigurationDescriptor =
+{
+ .Config =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Configuration_Header_t), .Type = DTYPE_Configuration},
+
+ .TotalConfigurationSize = sizeof(USB_Descriptor_Configuration_t),
+ .TotalInterfaces = 2,
+
+ .ConfigurationNumber = 1,
+ .ConfigurationStrIndex = NO_DESCRIPTOR,
+
+ .ConfigAttributes = (USB_CONFIG_ATTR_RESERVED | USB_CONFIG_ATTR_SELFPOWERED),
+
+ .MaxPowerConsumption = USB_CONFIG_POWER_MA(100)
+ },
+
+ .CDC_CCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 0,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 1,
+
+ .Class = CDC_CSCP_CDCClass,
+ .SubClass = CDC_CSCP_ACMSubclass,
+ .Protocol = CDC_CSCP_ATCommandProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_Functional_Header =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalHeader_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Header,
+
+ .CDCSpecification = VERSION_BCD(1,1,0),
+ },
+
+ .CDC_Functional_ACM =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalACM_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_ACM,
+
+ .Capabilities = 0x06,
+ },
+
+ .CDC_Functional_Union =
+ {
+ .Header = {.Size = sizeof(USB_CDC_Descriptor_FunctionalUnion_t), .Type = DTYPE_CSInterface},
+ .Subtype = CDC_DSUBTYPE_CSInterface_Union,
+
+ .MasterInterfaceNumber = 0,
+ .SlaveInterfaceNumber = 1,
+ },
+
+ .CDC_NotificationEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = CDC_NOTIFICATION_EPADDR,
+ .Attributes = (EP_TYPE_INTERRUPT | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_NOTIFICATION_EPSIZE,
+ .PollingIntervalMS = 0xFF
+ },
+
+ .CDC_DCI_Interface =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Interface_t), .Type = DTYPE_Interface},
+
+ .InterfaceNumber = 1,
+ .AlternateSetting = 0,
+
+ .TotalEndpoints = 2,
+
+ .Class = CDC_CSCP_CDCDataClass,
+ .SubClass = CDC_CSCP_NoDataSubclass,
+ .Protocol = CDC_CSCP_NoDataProtocol,
+
+ .InterfaceStrIndex = NO_DESCRIPTOR
+ },
+
+ .CDC_DataOutEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = CDC_RX_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x05
+ },
+
+ .CDC_DataInEndpoint =
+ {
+ .Header = {.Size = sizeof(USB_Descriptor_Endpoint_t), .Type = DTYPE_Endpoint},
+
+ .EndpointAddress = CDC_TX_EPADDR,
+ .Attributes = (EP_TYPE_BULK | ENDPOINT_ATTR_NO_SYNC | ENDPOINT_USAGE_DATA),
+ .EndpointSize = CDC_TXRX_EPSIZE,
+ .PollingIntervalMS = 0x05
+ }
+};
+
+/** Language descriptor structure. This descriptor, located in FLASH memory, is returned when the host requests
+ * the string descriptor with index 0 (the first index). It is actually an array of 16-bit integers, which indicate
+ * via the language ID table available at USB.org what languages the device supports for its string descriptors.
+ */
+const USB_Descriptor_String_t PROGMEM LanguageString =
+{
+ .Header = {.Size = USB_STRING_LEN(1), .Type = DTYPE_String},
+
+ .UnicodeString = {LANGUAGE_ID_ENG}
+};
+
+/** Manufacturer descriptor string. This is a Unicode string containing the manufacturer's details in human readable
+ * form, and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ManufacturerString =
+{
+ .Header = {.Size = USB_STRING_LEN(11), .Type = DTYPE_String},
+
+ .UnicodeString = L"Dean Camera"
+};
+
+/** Product descriptor string. This is a Unicode string containing the product's details in human readable form,
+ * and is read out upon request by the host when the appropriate string ID is requested, listed in the Device
+ * Descriptor.
+ */
+const USB_Descriptor_String_t PROGMEM ProductString =
+{
+ .Header = {.Size = USB_STRING_LEN(13), .Type = DTYPE_String},
+
+ .UnicodeString = L"LUFA CDC Demo"
+};
+
+/** This function is called by the library when in device mode, and must be overridden (see library "USB Descriptors"
+ * documentation) by the application code so that the address and size of a requested descriptor can be given
+ * to the USB library. When the device receives a Get Descriptor request on the control endpoint, this function
+ * is called so that the descriptor details can be passed back and the appropriate descriptor sent back to the
+ * USB host.
+ */
+uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+{
+ const uint8_t DescriptorType = (wValue >> 8);
+ const uint8_t DescriptorNumber = (wValue & 0xFF);
+
+ const void* Address = NULL;
+ uint16_t Size = NO_DESCRIPTOR;
+
+ switch (DescriptorType)
+ {
+ case DTYPE_Device:
+ Address = &DeviceDescriptor;
+ Size = sizeof(USB_Descriptor_Device_t);
+ break;
+ case DTYPE_Configuration:
+ Address = &ConfigurationDescriptor;
+ Size = sizeof(USB_Descriptor_Configuration_t);
+ break;
+ case DTYPE_String:
+ switch (DescriptorNumber)
+ {
+ case 0x00:
+ Address = &LanguageString;
+ Size = pgm_read_byte(&LanguageString.Header.Size);
+ break;
+ case 0x01:
+ Address = &ManufacturerString;
+ Size = pgm_read_byte(&ManufacturerString.Header.Size);
+ break;
+ case 0x02:
+ Address = &ProductString;
+ Size = pgm_read_byte(&ProductString.Header.Size);
+ break;
+ }
+
+ break;
+ }
+
+ *DescriptorAddress = Address;
+ return Size;
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/LUFADescriptors.h b/RevE-light/Firmware/Chameleon-Mini/LUFADescriptors.h
new file mode 100644
index 0000000..500649f
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/LUFADescriptors.h
@@ -0,0 +1,89 @@
+/*
+ LUFA Library
+ Copyright (C) Dean Camera, 2012.
+
+ dean [at] fourwalledcubicle [dot] com
+ www.lufa-lib.org
+*/
+
+/*
+ Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com)
+
+ Permission to use, copy, modify, distribute, and sell this
+ software and its documentation for any purpose is hereby granted
+ without fee, provided that the above copyright notice appear in
+ all copies and that both that the copyright notice and this
+ permission notice and warranty disclaimer appear in supporting
+ documentation, and that the name of the author not be used in
+ advertising or publicity pertaining to distribution of the
+ software without specific, written prior permission.
+
+ The author disclaim all warranties with regard to this
+ software, including all implied warranties of merchantability
+ and fitness. In no event shall the author be liable for any
+ special, indirect or consequential damages or any damages
+ whatsoever resulting from loss of use, data or profits, whether
+ in an action of contract, negligence or other tortious action,
+ arising out of or in connection with the use or performance of
+ this software.
+*/
+
+/** \file
+ *
+ * Header file for Descriptors.c.
+ */
+
+#ifndef _DESCRIPTORS_H_
+#define _DESCRIPTORS_H_
+
+ /* Includes: */
+ #include
+
+ #include
+
+ /* Macros: */
+ /** Endpoint address of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPADDR (ENDPOINT_DIR_IN | 2)
+
+ /** Endpoint address of the CDC device-to-host data IN endpoint. */
+ #define CDC_TX_EPADDR (ENDPOINT_DIR_IN | 3)
+
+ /** Endpoint address of the CDC host-to-device data OUT endpoint. */
+ #define CDC_RX_EPADDR (ENDPOINT_DIR_OUT | 4)
+
+ /** Size in bytes of the CDC device-to-host notification IN endpoint. */
+ #define CDC_NOTIFICATION_EPSIZE 8
+
+ /** Size in bytes of the CDC data IN and OUT endpoints. */
+ #define CDC_TXRX_EPSIZE 16
+
+ /* Type Defines: */
+ /** Type define for the device configuration descriptor structure. This must be defined in the
+ * application code, as the configuration descriptor contains several sub-descriptors which
+ * vary between devices, and which describe the device's usage to the host.
+ */
+ typedef struct
+ {
+ USB_Descriptor_Configuration_Header_t Config;
+
+ // CDC Control Interface
+ USB_Descriptor_Interface_t CDC_CCI_Interface;
+ USB_CDC_Descriptor_FunctionalHeader_t CDC_Functional_Header;
+ USB_CDC_Descriptor_FunctionalACM_t CDC_Functional_ACM;
+ USB_CDC_Descriptor_FunctionalUnion_t CDC_Functional_Union;
+ USB_Descriptor_Endpoint_t CDC_NotificationEndpoint;
+
+ // CDC Data Interface
+ USB_Descriptor_Interface_t CDC_DCI_Interface;
+ USB_Descriptor_Endpoint_t CDC_DataOutEndpoint;
+ USB_Descriptor_Endpoint_t CDC_DataInEndpoint;
+ } USB_Descriptor_Configuration_t;
+
+ /* Function Prototypes: */
+ uint16_t CALLBACK_USB_GetDescriptor(const uint16_t wValue,
+ const uint8_t wIndex,
+ const void** const DescriptorAddress)
+ ATTR_WARN_UNUSED_RESULT ATTR_NON_NULL_PTR_ARG(3);
+
+#endif
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Log.c b/RevE-light/Firmware/Chameleon-Mini/Log.c
new file mode 100644
index 0000000..ada0f48
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Log.c
@@ -0,0 +1,161 @@
+#include "Log.h"
+#include "Settings.h"
+#include "Terminal/Terminal.h"
+#include "System.h"
+#include "Map.h"
+
+static uint8_t LogMem[LOG_SIZE];
+static uint8_t* LogMemPtr;
+static uint16_t LogMemLeft;
+LogFuncType CurrentLogFunc;
+
+static const MapEntryType PROGMEM LogModeMap[] = {
+ { .Id = LOG_MODE_OFF, .Text = "OFF" },
+ { .Id = LOG_MODE_MEMORY, .Text = "MEMORY" },
+ { .Id = LOG_MODE_LIVE, .Text = "LIVE" }
+};
+
+static void LogFuncOff(LogEntryEnum Entry, const void* Data, uint8_t Length)
+{
+ /* Do nothing */
+}
+
+static void LogFuncMemory(LogEntryEnum Entry, const void* Data, uint8_t Length)
+{
+ uint16_t SysTick = SystemGetSysTick();
+
+ if (LogMemLeft >= (Length + 4)) {
+ LogMemLeft -= Length + 4;
+
+ uint8_t* DataPtr = (uint8_t*) Data;
+
+ /* Write down Entry Id, Data length and Timestamp */
+ *LogMemPtr++ = (uint8_t) Entry;
+ *LogMemPtr++ = (uint8_t) Length;
+ *LogMemPtr++ = (uint8_t) (SysTick >> 8);
+ *LogMemPtr++ = (uint8_t) (SysTick >> 0);
+
+ /* Write down data bytes */
+ while(Length--) {
+ *LogMemPtr++ = *DataPtr++;
+ }
+ } else {
+ /* If memory full. Deactivate logmode */
+ LogSetModeById(LOG_MODE_OFF);
+ }
+}
+
+static void LogFuncLive(LogEntryEnum Entry, const void* Data, uint8_t Length)
+{
+ uint16_t SysTick = SystemGetSysTick();
+
+ TerminalSendByte((uint8_t) Entry);
+ TerminalSendByte((uint8_t) Length);
+ TerminalSendByte((uint8_t) (SysTick >> 8));
+ TerminalSendByte((uint8_t) (SysTick >> 0));
+ TerminalSendBlock(Data, Length);
+}
+
+void LogInit(void)
+{
+ LogMemClear();
+ LogSetModeById(GlobalSettings.ActiveSettingPtr->LogMode);
+}
+
+void LogTick(void)
+{
+
+}
+
+void LogTask(void)
+{
+
+}
+
+bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount)
+{
+ if (BlockAddress < sizeof(LogMem)) {
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+ uint8_t* MemPtr = &LogMem[BlockAddress];
+
+ while(ByteCount-- > 0) {
+ *DataPtr++ = *MemPtr++;
+ }
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+void LogMemClear(void)
+{
+ uint16_t i;
+
+ for (i=0; iLogMode = Mode;
+#else
+ /* Write Log settings globally */
+ for (uint8_t i=0; iLogMode, Mode, BufferSize);
+}
+
+void LogGetModeList(char* List, uint16_t BufferSize)
+{
+ MapToString(LogModeMap, sizeof(LogModeMap)/sizeof(*LogModeMap), List, BufferSize);
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Log.h b/RevE-light/Firmware/Chameleon-Mini/Log.h
new file mode 100644
index 0000000..37a3c68
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Log.h
@@ -0,0 +1,66 @@
+#ifndef LOG_H_
+#define LOG_H_
+
+#include "Common.h"
+
+#define LOG_SIZE 2048
+
+typedef enum {
+ /* Generic */
+ LOG_INFO_GENERIC = 0x10,
+ LOG_INFO_CONFIG_SET = 0x11,
+ LOG_INFO_SETTING_SET = 0x12,
+ LOG_INFO_UID_SET = 0x13,
+ LOG_INFO_RESET_APP = 0x20,
+
+ /* Codec */
+ LOG_INFO_CODEC_RX_DATA = 0x40,
+ LOG_INFO_CODEC_TX_DATA = 0x41,
+
+ /* App */
+ LOG_INFO_APP_CMD_READ = 0x80,
+ LOG_INFO_APP_CMD_WRITE = 0x81,
+ LOG_INFO_APP_CMD_INC = 0x84,
+ LOG_INFO_APP_CMD_DEC = 0x85,
+ LOG_INFO_APP_CMD_TRANSFER = 0x86,
+ LOG_INFO_APP_CMD_RESTORE = 0x87,
+ LOG_INFO_APP_CMD_AUTH = 0x90,
+ LOG_INFO_APP_CMD_HALT = 0x91,
+ LOG_INFO_APP_CMD_UNKNOWN = 0x92,
+ LOG_INFO_APP_AUTHING = 0xA0,
+ LOG_INFO_APP_AUTHED = 0xA1,
+ LOG_ERR_APP_AUTH_FAIL = 0xC0,
+ LOG_ERR_APP_CHECKSUM_FAIL = 0xC1,
+ LOG_ERR_APP_NOT_AUTHED = 0xC2,
+
+ LOG_EMPTY = 0x00
+} LogEntryEnum;
+
+typedef enum {
+ LOG_MODE_OFF,
+ LOG_MODE_MEMORY,
+ LOG_MODE_LIVE
+} LogModeEnum;
+
+typedef void (*LogFuncType) (LogEntryEnum Entry, const void* Data, uint8_t Length);
+
+extern LogFuncType CurrentLogFunc;
+
+void LogInit(void);
+void LogTick(void);
+void LogTask(void);
+
+void LogMemClear(void);
+uint16_t LogMemFree(void);
+/* XModem callback */
+bool LogMemLoadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount);
+
+void LogSetModeById(LogModeEnum Mode);
+bool LogSetModeByName(const char* Mode);
+void LogGetModeByName(char* Mode, uint16_t BufferSize);
+void LogGetModeList(char* List, uint16_t BufferSize);
+
+/* Wrapper function to call current logging function */
+INLINE void LogEntry(LogEntryEnum Entry, const void* Data, uint8_t Length) { CurrentLogFunc(Entry, Data, Length); }
+
+#endif /* LOG_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Makefile b/RevE-light/Firmware/Chameleon-Mini/Makefile
new file mode 100644
index 0000000..c1340a0
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Makefile
@@ -0,0 +1,185 @@
+# This makefile uses sh in order to build the project.
+# Note when using AVR-Toolchain, you have to install cygwin and
+# append cygwin's bin directory to the PATH environment variable
+# because Atmel does not ship sh.exe anymore with the toolchain.
+SHELL = /bin/sh
+
+# Supported configurations
+SETTINGS += -DCONFIG_MF_CLASSIC_1K_SUPPORT
+SETTINGS += -DCONFIG_MF_Plus1k_7B_SUPPORT
+SETTINGS += -DCONFIG_MF_CLASSIC_4K_SUPPORT
+SETTINGS += -DCONFIG_MF_ULTRALIGHT_SUPPORT
+SETTINGS += -DCONFIG_ISO14443A_SNIFF_SUPPORT
+
+# Support magic mode on mifare classic configuration
+SETTINGS += -DSUPPORT_MF_CLASSIC_MAGIC_MODE
+
+# Support activating firmware upgrade mode through command-line
+SETTINGS += -DSUPPORT_FIRMWARE_UPGRADE
+
+# Default configuration
+#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_Plus1k_7B
+#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_1K
+#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_4K
+#SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_ULTRALIGHT
+SETTINGS += -DDEFAULT_CONFIGURATION=CONFIG_MF_CLASSIC_1K
+
+# Default button actions
+#SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_UID_RANDOM
+#SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_UID_LEFT_INCREMENT
+#SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_INCREMENT
+#SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_UID_LEFT_DECREMENT
+#SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_UID_RIGHT_DECREMENT
+SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_CYCLE_SETTINGS
+#SETTINGS += -DDEFAULT_RBUTTON_ACTION=BUTTON_ACTION_STORE_MEM
+SETTINGS += -DDEFAULT_LBUTTON_ACTION=BUTTON_ACTION_STORE_MEM
+
+# Define if button action setting should be independent of active setting
+SETTINGS += -DBUTTON_SETTING_GLOBAL
+
+# Default LED functions
+
+#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_TERMINAL_CONN
+#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_TERMINAL_RXTX
+SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_SETTING_CHANGE
+#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_MEMORY_STORED
+#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_MEMORY_CHANGED
+#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_CODEC_RX
+#SETTINGS += -DDEFAULT_RED_LED_ACTION=LED_CODEC_TX
+
+SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_TERMINAL_CONN
+#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_TERMINAL_RXTX
+#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_SETTING_CHANGE
+#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_MEMORY_STORED
+#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_MEMORY_CHANGED
+#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_CODEC_RX
+#SETTINGS += -DDEFAULT_GREEN_LED_ACTION=LED_CODEC_TX
+
+
+# Define if LED function setting should be independent of active setting
+SETTINGS += -DLED_SETTING_GLOBAL
+
+# Default logging mode
+SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_OFF
+#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_MEMORY
+#SETTINGS += -DDEFAULT_LOG_MODE=LOG_MODE_TERMINAL
+
+# Default setting
+SETTINGS += -DDEFAULT_SETTING=SETTINGS_FIRST
+
+# Use EEPROM to store settings
+SETTINGS += -DENABLE_EEPROM_SETTINGS
+
+
+# Memory definitions and objcopy flags to include sections in binaries
+FLASH_DATA_ADDR = 0x10000 # Start of data section in flash
+FLASH_DATA_SIZE = 0x8000 # Size of data section in flash
+FLASH_DATA_OBJCOPY = --set-section-flags=.flashdata="alloc,load"
+SPM_HELPER_ADDR = 0x21FE0 # Start of SPM helper section. Should be last 32Byte in bootloader section
+SPM_HELPER_OBJCOPY = --set-section-flags=.spmhelper="alloc,load"
+
+
+# Build configuration
+BUILD_DATE = $(shell date +'\"%y%m%d\"')
+MCU = atxmega128a4u
+ARCH = XMEGA
+BOARD = NONE
+F_CPU = 32000000
+F_USB = 48000000
+TARGET = Chameleon-Mini
+OPTIMIZATION = 3
+
+# Core files
+SRC += $(TARGET).c
+SRC += Button.c
+SRC += Common.c
+SRC += Configuration.c
+SRC += LED.c
+SRC += LUFADescriptors.c
+SRC += Log.c
+SRC += Map.c
+SRC += Memory.c
+SRC += MemoryAsm.S
+SRC += Random.c
+SRC += Settings.c
+SRC += System.c
+
+# Terminal
+SRC += Terminal/Terminal.c
+SRC += Terminal/Commands.c
+SRC += Terminal/XModem.c
+SRC += Terminal/CommandLine.c
+
+# Codecs
+SRC += Codec/Codec.c
+SRC += Codec/ISO14443-2A.c
+
+# Applications
+SRC += Application/MifareUltralight.c
+SRC += Application/MifareClassic.c
+SRC += Application/ISO14443-3A.c
+SRC += Application/Crypto1.c
+
+# LUFA
+SRC += $(LUFA_SRC_USB) $(LUFA_SRC_USBCLASS)
+LUFA_PATH = ../../../Firmware/LUFA
+
+# General linker / compiler settings
+CC_FLAGS = -DUSE_LUFA_CONFIG_HEADER -DFLASH_DATA_ADDR=$(FLASH_DATA_ADDR) -DFLASH_DATA_SIZE=$(FLASH_DATA_SIZE) -DSPM_HELPER_ADDR=$(SPM_HELPER_ADDR) -DBUILD_DATE=$(BUILD_DATE) $(SETTINGS) -I$(LUFA_PATH)
+LD_FLAGS = -Wl,--section-start=.flashdata=$(FLASH_DATA_ADDR) -Wl,--section-start=.spmhelper=$(SPM_HELPER_ADDR)
+OBJDIR = Bin
+OBJECT_FILES =
+
+#AVRDUDE settings
+AVRDUDE_PROGRAMMER = jtag2pdi #avrisp2
+AVRDUDE_MCU = atxmega128a4
+AVRDUDE_PORT = usb
+AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex
+AVRDUDE_WRITE_EEPROM = -U eeprom:w:$(TARGET).eep
+AVRDUDE_FLAGS = -p $(AVRDUDE_MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
+
+# Default target
+all:
+
+# Include LUFA build script makefiles
+include $(LUFA_PATH)/Build/lufa_core.mk
+include $(LUFA_PATH)/Build/lufa_sources.mk
+include $(LUFA_PATH)/Build/lufa_build.mk
+include $(LUFA_PATH)/Build/lufa_cppcheck.mk
+# include $(LUFA_PATH)/Build/lufa_doxygen.mk
+# include $(LUFA_PATH)/Build/lufa_dfu.mk
+# include $(LUFA_PATH)/Build/lufa_hid.mk
+# include $(LUFA_PATH)/Build/lufa_avrdude.mk
+# include $(LUFA_PATH)/Build/lufa_atprogram.mk
+
+# Overwrite the LUFA versions of hex/bin file generation to include spmhelper and flashdata sections
+%.hex: %.elf
+ @echo $(MSG_OBJCPY_CMD) Chameleon: Extracting HEX file data from \"$<\"
+ @$(CROSS)-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $(FLASH_DATA_OBJCOPY) $< $@
+
+%.bin: %.elf
+ @echo $(MSG_OBJCPY_CMD) Chameleon: Extracting BIN file data from \"$<\"
+ @$(CROSS)-objcopy -O binary -R .eeprom -R .fuse -R .lock -R .signature $(FLASH_DATA_OBJCOPY) $< $@
+
+# Extract SPMHelper in the last 32 Byte of the bootloader section to externally combine it with any bootloader
+spmhelper: $(TARGET).elf
+ @echo $(MSG_OBJCPY_CMD) Chameleon: Extracting SPM helper HEX file from $(TARGET).elf
+ @$(CROSS)-objcopy -O ihex -j .spmhelper $(SPM_HELPER_OBJCOPY) $(TARGET).elf $(TARGET).hex
+
+# Program the device using avrdude
+program: $(TARGET).hex $(TARGET).eep
+ avrdude $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM)
+
+# Program the device using batchisp and the DFU bootloader
+# Note that the device has to be in bootloader mode already
+dfu-flip: $(TARGET).hex $(TARGET).eep
+ cp $(TARGET).eep EEPROM.hex
+ batchisp -hardware usb -device $(MCU) -operation erase f memory FLASH loadbuffer $(TARGET).hex program verify memory EEPROM loadbuffer EEPROM.hex program verify start reset 0
+ rm EEPROM.hex
+
+# Program the device using dfu-programmer
+dfu-prog: $(TARGET).hex $(TARGET).eep
+ dfu-programmer $(MCU) erase
+ dfu-programmer $(MCU) flash-eeprom $(TARGET).eep
+ dfu-programmer $(MCU) flash $(TARGET).hex
+ dfu-programmer $(MCU) reset
diff --git a/RevE-light/Firmware/Chameleon-Mini/Map.c b/RevE-light/Firmware/Chameleon-Mini/Map.c
new file mode 100644
index 0000000..b6011d4
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Map.c
@@ -0,0 +1,72 @@
+#include "Map.h"
+
+bool MapIdToText(const MapEntryType* MapPtr, uint8_t MapSize, MapIdType Id, char* Text, uint16_t MaxBufferSize)
+{
+ while (MapSize--) {
+ if (pgm_read_byte(&MapPtr->Id) == Id) {
+ strncpy_P(Text, MapPtr->Text, MaxBufferSize);
+ return true;
+ }
+
+ MapPtr++;
+ }
+
+ return false;
+}
+
+bool MapTextToId(const MapEntryType* MapPtr, uint8_t MapSize, MapTextPtrType Text, MapIdType* IdPtr)
+{
+ while (MapSize--) {
+ if (strcmp_P(Text, MapPtr->Text) == 0) {
+ if (sizeof(MapIdType) == 1) {
+ *IdPtr = pgm_read_byte(&MapPtr->Id);
+ } else if (sizeof(MapIdType) == 2) {
+ *IdPtr = pgm_read_word(&MapPtr->Id);
+ }
+ return true;
+ }
+
+ MapPtr++;
+ }
+
+ return false;
+}
+
+void MapToString(MapEntryType* MapPtr, uint8_t MapSize, char* String, uint16_t MaxBufferSize)
+{
+ uint8_t EntriesLeft = MapSize;
+ uint16_t BytesLeft = MaxBufferSize;
+
+ while (EntriesLeft > 0) {
+ const char* Text = MapPtr->Text;
+ char c;
+
+ while( (c = pgm_read_byte(Text)) != '\0') {
+ if (BytesLeft == 0) {
+ return;
+ }
+
+ *String++ = c;
+ Text++;
+ BytesLeft--;
+ }
+
+ if (EntriesLeft > 1) {
+ /* More than one map entries left */
+ if (BytesLeft == 0) {
+ return;
+ }
+
+ *String++ = ',';
+ }
+
+ MapPtr++;
+ EntriesLeft--;
+ }
+
+ /* Terminate string */
+ if (BytesLeft > 0) {
+ *String++ = '\0';
+ BytesLeft--;
+ }
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Map.h b/RevE-light/Firmware/Chameleon-Mini/Map.h
new file mode 100644
index 0000000..7180280
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Map.h
@@ -0,0 +1,30 @@
+/*
+ * Map.h
+ *
+ * Created on: 07.12.2014
+ * Author: sk
+ */
+
+#ifndef MAP_H_
+#define MAP_H_
+
+#include
+#include
+#include
+
+#define MAP_TEXT_BUF_SIZE 32
+#define MAP_MAX_TEXT_SIZE (MAP_TEXT_BUF_SIZE - 1)
+
+typedef uint8_t MapIdType;
+typedef const char* MapTextPtrType;
+
+const typedef struct {
+ MapIdType Id;
+ const char Text[MAP_TEXT_BUF_SIZE];
+} MapEntryType;
+
+bool MapIdToText(const MapEntryType* MapPtr, uint8_t MapSize, MapIdType Id, char* Text, uint16_t MaxBufferSize);
+bool MapTextToId(const MapEntryType* MapPtr, uint8_t MapSize, MapTextPtrType Text, MapIdType* IdPtr);
+void MapToString(const MapEntryType* MapPtr, uint8_t MapSize, char* String, uint16_t MaxBufferSize);
+
+#endif /* MAP_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Memory.c b/RevE-light/Firmware/Chameleon-Mini/Memory.c
new file mode 100644
index 0000000..cdaadb7
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Memory.c
@@ -0,0 +1,228 @@
+/*
+ * Flash.c
+ *
+ * Created on: 20.03.2013
+ * Author: skuser
+ */
+
+#include "Memory.h"
+#include "Configuration.h"
+#include "Common.h"
+#include "Settings.h"
+#include "LEDHook.h"
+
+/* 4k SRAM buffer */
+static uint8_t Memory[MEMORY_SIZE_PER_SETTING];
+
+/* Declarations from assembler file */
+uint16_t FlashReadWord(uint32_t Address);
+void FlashEraseApplicationPage(uint32_t Address);
+void FlashLoadFlashWord(uint16_t Address, uint16_t Data);
+void FlashEraseWriteApplicationPage(uint32_t Address);
+void FlashEraseFlashBuffer(void);
+void FlashWaitForSPM(void);
+
+/* Convert defines from Makefile */
+#define FLASH_DATA_START FLASH_DATA_ADDR
+#define FLASH_DATA_END (FLASH_DATA_ADDR + FLASH_DATA_SIZE - 1)
+
+INLINE void FlashRead(void* Buffer, uint32_t Address, uint16_t ByteCount)
+{
+ uint8_t* BufPtr = (uint8_t*) Buffer;
+
+ /* We assume that ByteCount is a multiple of 2 */
+ uint32_t PhysicalAddress = Address + FLASH_DATA_ADDR;
+
+ if ( (PhysicalAddress >= FLASH_DATA_START) && (PhysicalAddress <= FLASH_DATA_END) ) {
+ /* Sanity check to limit access to the allocated area */
+ while(ByteCount > 1) {
+ uint16_t Word = FlashReadWord(PhysicalAddress);
+
+ *BufPtr++ = (Word >> 0) & 0xFF;
+ *BufPtr++ = (Word >> 8) & 0xFF;
+
+ PhysicalAddress += 2;
+ ByteCount -= 2;
+ }
+ }
+}
+
+INLINE void FlashWrite(const void* Buffer, uint32_t Address, uint16_t ByteCount)
+{
+ const uint8_t* BufPtr = (uint8_t*) Buffer;
+
+ /* We assume that FlashWrite is always called for write actions that are
+ * aligned to APP_SECTION_PAGE_SIZE and a multiple of APP_SECTION_PAGE_SIZE.
+ * Thus only full pages are written into the flash. */
+ uint16_t PageCount = ByteCount / APP_SECTION_PAGE_SIZE;
+ uint32_t PhysicalAddress = Address + FLASH_DATA_ADDR;
+
+ if ( (PhysicalAddress >= FLASH_DATA_START) && (PhysicalAddress <= FLASH_DATA_END) ) {
+ /* Sanity check to limit access to the allocated area */
+
+ while(PageCount-- > 0) {
+ /* For each page to program, wait for NVM to get ready,
+ * erase the flash page buffer, program all data to the
+ * flash page buffer and write buffer to flash using
+ * the atomic erase and write operation. */
+
+ FlashWaitForSPM();
+
+ FlashEraseFlashBuffer();
+ FlashWaitForSPM();
+
+ for (uint16_t i=0; i= FLASH_DATA_START) && (PhysicalAddress <= FLASH_DATA_END) ) {
+ /* Sanity check to limit access to the allocated area */
+ while(PageCount-- > 0) {
+ FlashWaitForSPM();
+
+ FlashEraseApplicationPage(PhysicalAddress);
+ FlashWaitForSPM();
+
+ PhysicalAddress += APP_SECTION_PAGE_SIZE;
+ }
+ }
+}
+
+void MemoryInit(void)
+{
+ /* Load permanent flash contents to memory at startup */
+ MemoryRecall();
+}
+
+void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount)
+{
+ uint8_t* SrcPtr = &Memory[Address];
+ uint8_t* DstPtr = (uint8_t*) Buffer;
+
+ /* Prevent Buf Ovfs */
+ ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address);
+
+ while(ByteCount--)
+ {
+ *DstPtr++ = *SrcPtr++;
+ }
+}
+
+void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount)
+{
+ uint8_t* SrcPtr = (uint8_t*) Buffer;
+ uint8_t* DstPtr = &Memory[Address];
+
+ /* Prevent Buf Ovfs */
+ ByteCount = MIN(ByteCount, MEMORY_SIZE_PER_SETTING - Address);
+
+ while(ByteCount--) {
+ *DstPtr++ = *SrcPtr++;
+ }
+
+ LEDHook(LED_MEMORY_CHANGED, LED_ON);
+}
+
+void MemoryClear(void)
+{
+ for (uint16_t i = 0; i < MEMORY_SIZE_PER_SETTING; i++)
+ {
+ Memory[i] = 0;
+ }
+}
+
+void MemoryRecall(void)
+{
+ /* Recall memory from permanent internal flash */
+ FlashRead(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING);
+}
+
+void MemoryStore(void)
+{
+ /* Store current memory into permanent internal flash */
+ FlashWrite(Memory, (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING, MEMORY_SIZE_PER_SETTING);
+
+ LEDHook(LED_MEMORY_CHANGED, LED_OFF);
+ LEDHook(LED_MEMORY_STORED, LED_PULSE);
+}
+
+bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount)
+{
+ if (BlockAddress >= MEMORY_SIZE_PER_SETTING)
+ {
+ /* Prevent writing out of bounds by silently ignoring it */
+ return true;
+ }
+ else
+ {
+ /* Calculate bytes left in memory and start writing */
+ uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress;
+ uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSettingIdx * MEMORY_SIZE_PER_SETTING;
+ ByteCount = MIN(ByteCount, BytesLeft);
+
+ /* Store into flash */
+
+ /// TODO: Do we want to also upload to Flash or only to RAM (& do store then)
+ // FlashWrite(Buffer, FlashAddress, ByteCount);
+ //// FIXME, redirect to internal flash
+
+ /* Store to local memory */
+ uint8_t* DstPtr = &Memory[BlockAddress];
+ uint8_t* SrcPtr = (uint8_t*) Buffer;
+
+ while(ByteCount--)
+ {
+ *DstPtr++ = *SrcPtr++;
+ }
+
+ return true;
+ }
+
+}
+
+bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount)
+{
+ if (BlockAddress >= MEMORY_SIZE_PER_SETTING)
+ {
+ /* There are bytes out of bounds to be read. Notify that we are done. */
+ return false;
+ }
+ else
+ {
+ /* Calculate bytes left in memory and issue reading */
+ uint32_t BytesLeft = MEMORY_SIZE_PER_SETTING - BlockAddress;
+ //uint32_t FlashAddress = (uint32_t) BlockAddress + (uint32_t) GlobalSettings.ActiveSetting * MEMORY_SIZE_PER_SETTING;
+ ByteCount = MIN(ByteCount, BytesLeft);
+
+ /* Output local memory contents */
+ uint8_t* DstPtr = (uint8_t*) Buffer;
+ uint8_t* SrcPtr = &Memory[BlockAddress];
+
+ while(ByteCount--)
+ {
+ *DstPtr++ = *SrcPtr++;
+ }
+
+ return true;
+ }
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Memory.h b/RevE-light/Firmware/Chameleon-Mini/Memory.h
new file mode 100644
index 0000000..4a7f9bb
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Memory.h
@@ -0,0 +1,33 @@
+/*
+ * Flash.h
+ *
+ * Created on: 20.03.2013
+ * Author: skuser
+ */
+
+#ifndef MEMORY_H_
+#define MEMORY_H_
+
+#define MEMORY_SIZE (FLASH_DATA_SIZE) /* From makefile */
+#define MEMORY_INIT_VALUE 0x00
+#define MEMORY_SIZE_PER_SETTING 4096
+
+#ifndef __ASSEMBLER__
+#include "Common.h"
+
+void MemoryInit(void);
+void MemoryReadBlock(void* Buffer, uint16_t Address, uint16_t ByteCount);
+void MemoryWriteBlock(const void* Buffer, uint16_t Address, uint16_t ByteCount);
+void MemoryClear(void);
+
+
+void MemoryRecall(void);
+void MemoryStore(void);
+
+/* For use with XModem */
+bool MemoryUploadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount);
+bool MemoryDownloadBlock(void* Buffer, uint32_t BlockAddress, uint16_t ByteCount);
+
+#endif /* __ASSEMBLER__ */
+
+#endif /* MEMORY_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/MemoryAsm.S b/RevE-light/Firmware/Chameleon-Mini/MemoryAsm.S
new file mode 100644
index 0000000..efb3374
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/MemoryAsm.S
@@ -0,0 +1,225 @@
+#include
+#include "Memory.h"
+
+#define NVM_CMD_NO_OPERATION_gc (0x00<<0)
+#define NVM_CMD_READ_USER_SIG_ROW_gc (0x01<<0)
+#define NVM_CMD_READ_CALIB_ROW_gc (0x02<<0)
+#define NVM_CMD_READ_EEPROM_gc (0x06<<0)
+#define NVM_CMD_READ_FUSES_gc (0x07<<0)
+#define NVM_CMD_WRITE_LOCK_BITS_gc (0x08<<0)
+#define NVM_CMD_ERASE_USER_SIG_ROW_gc (0x18<<0)
+#define NVM_CMD_WRITE_USER_SIG_ROW_gc (0x1A<<0)
+#define NVM_CMD_ERASE_APP_gc (0x20<<0)
+#define NVM_CMD_ERASE_APP_PAGE_gc (0x22<<0)
+#define NVM_CMD_LOAD_FLASH_BUFFER_gc (0x23<<0)
+#define NVM_CMD_WRITE_APP_PAGE_gc (0x24<<0)
+#define NVM_CMD_ERASE_WRITE_APP_PAGE_gc (0x25<<0)
+#define NVM_CMD_ERASE_FLASH_BUFFER_gc (0x26<<0)
+#define NVM_CMD_ERASE_BOOT_PAGE_gc (0x2A<<0)
+#define NVM_CMD_WRITE_BOOT_PAGE_gc (0x2C<<0)
+#define NVM_CMD_ERASE_WRITE_BOOT_PAGE_gc (0x2D<<0)
+#define NVM_CMD_ERASE_EEPROM_gc (0x30<<0)
+#define NVM_CMD_ERASE_EEPROM_PAGE_gc (0x32<<0)
+#define NVM_CMD_LOAD_EEPROM_BUFFER_gc (0x33<<0)
+#define NVM_CMD_WRITE_EEPROM_PAGE_gc (0x34<<0)
+#define NVM_CMD_ERASE_WRITE_EEPROM_PAGE_gc (0x35<<0)
+#define NVM_CMD_ERASE_EEPROM_BUFFER_gc (0x36<<0)
+#define NVM_CMD_APP_CRC_gc (0x38<<0)
+#define NVM_CMD_BOOT_CRC_gc (0x39<<0)
+#define NVM_CMD_FLASH_RANGE_CRC_gc (0x3A<<0)
+#define CCP_SPM_gc (0x9D<<0)
+#define CCP_IOREG_gc (0xD8<<0)
+
+/* FlashCommonSPM needs to reside in boot loader section */
+#define SPM_HELPER_ADDR_REF (BOOT_SECTION_START + BOOT_SECTION_SIZE - 32)
+#ifdef SPM_HELPER_ADDR
+/* If enabled by makefile, we can check the hardcoded address from makefile
+ * against avr/io.h and generate an error on mismatch */
+#if ((SPM_HELPER_ADDR - SPM_HELPER_ADDR_REF) != 0)
+#error SPM helper function addresses from Makefile and avr/io.h do not match!
+#endif
+#endif
+
+/* The following assembly code is taken from Atmels sp_driver.S in AVR1316 */
+
+; This routine reads a word from flash given by the address in
+; R25:R24:R23:R22.
+;
+; Input:
+; R25:R24:R23:R22.
+;
+; Returns:
+; R25:R24 - Read word.
+.section .text
+.global FlashReadWord
+FlashReadWord:
+ in r19, RAMPZ ; Save RAMPZ.
+ out RAMPZ, r24 ; Load RAMPZ with the MSB of the address.
+ movw ZL, r22 ; Move the low bytes to the Z pointer
+ elpm r24, Z+ ; Extended load byte from address pointed to by Z.
+ elpm r25, Z ; Extended load byte from address pointed to by Z.
+ out RAMPZ, r19 ; Restore RAMPZ register.
+ ret
+
+; This routine erases the page at address R25:R24:R23:R22 in the application
+; section. The address can point anywhere inside the page.
+;
+; Input:
+; R25:R24:R23:R22 - Byte address into Flash page.
+;
+; Returns:
+; Nothing.
+.section .text
+.global FlashEraseApplicationPage
+FlashEraseApplicationPage:
+ in r19, RAMPZ ; Save RAMPZ, which is restored in FlashCommonSPM.
+ out RAMPZ, r24 ; Load RAMPZ with the MSB of the address.
+ movw r24, r22 ; Move low bytes for ZH:ZL to R25:R24
+ ldi r20, NVM_CMD_ERASE_APP_PAGE_gc ; Prepare NVM command in R20.
+ jmp FlashCommonSPM ; Jump to common SPM code.
+
+; This routine writes the word from R23:R22 into the Flash page buffer at
+; address R25:R24.
+;
+; Input:
+; R25:R24 - Byte address into Flash page.
+; R23:R22 - Word to write.
+;
+; Returns:
+; Nothing.
+.section .text
+.global FlashLoadFlashWord
+FlashLoadFlashWord:
+ in r19, RAMPZ ; Save RAMPZ, which is restored in FlashCommonSPM.
+ movw r0, r22 ; Prepare flash word in R1:R0.
+ ldi r20, NVM_CMD_LOAD_FLASH_BUFFER_gc ; Prepare NVM command in R20.
+ jmp FlashCommonSPM ; Jump to common SPM code.
+
+
+; This routine erases first and then writes the page buffer to the
+; Flash page at address R25:R24:R23:R22 in the application section. The address
+; can point anywhere inside the page.
+;
+; Input:
+; R25:R24:R23:R22 - Byte address into Flash page.
+;
+; Returns:
+; Nothing.
+.section .text
+.global FlashEraseWriteApplicationPage
+FlashEraseWriteApplicationPage:
+ in r19, RAMPZ ; Save RAMPZ, which is restored in FlashCommonSPM.
+ out RAMPZ, r24 ; Load RAMPZ with the MSB of the address.
+ movw r24, r22 ; Move low bytes of address to ZH:ZL from R23:R22
+ ldi r20, NVM_CMD_ERASE_WRITE_APP_PAGE_gc ; Prepare NVM command in R20.
+ jmp FlashCommonSPM ; Jump to common SPM code.
+
+; This routine flushes the Flash page buffer.
+;
+; Input:
+; Nothing.
+;
+; Returns:
+; Nothing.
+.section .text
+.global FlashEraseFlashBuffer
+FlashEraseFlashBuffer:
+ in r19, RAMPZ ; Save RAMPZ, which is restored in FlashCommonSPM.
+ ldi r20, NVM_CMD_ERASE_FLASH_BUFFER_gc ; Prepare NVM command in R20.
+ ;jmp FlashCommonSPM ; Jump to common SPM code.
+ jmp FlashCommonCMD
+
+; This routine wait for the SPM to finish and clears the command register.
+;
+; Note that this routine is blocking, and will halt any execution until the SPM
+; is finished.
+;
+; Input:
+; Nothing.
+;
+; Returns:
+; Nothing.
+.section .text
+.global FlashWaitForSPM
+FlashWaitForSPM:
+ lds r18, NVM_STATUS ; Load the NVM Status register.
+ sbrc r18, NVM_NVMBUSY_bp ; Check if bit is cleared.
+ rjmp FlashWaitForSPM ; Repeat check if bit is not cleared.
+ clr r18
+ sts NVM_CMD, r18 ; Clear up command register to NO_OPERATION.
+ ret
+
+; This routine is called by several other routines, and contains common code
+; for executing an NVM command, including the return statement itself.
+;
+; If the operation (NVM command) requires the NVM Address registers to be
+; prepared, this must be done before jumping to this routine.
+;
+; Note that R25:R24:R23:R22 is used for returning results, even if the
+; C-domain calling function only expects a single byte or even void.
+;
+; Input:
+; R20 - NVM Command code.
+;
+; Returns:
+; R25:R24:R23:R22 - 32-bit result from NVM operation.
+.section .text
+FlashCommonCMD:
+ sts NVM_CMD, r20 ; Load command into NVM Command register.
+ ldi r18, CCP_IOREG_gc ; Prepare Protect IO-register signature in R18.
+ ldi r19, NVM_CMDEX_bm ; Prepare bitmask for setting NVM Command Execute bit into R19.
+ sts CCP, r18 ; Enable IO-register operation (this disables interrupts for 4 cycles).
+ sts NVM_CTRLA, r19 ; Load bitmask into NVM Control Register A, which executes the command.
+ lds r22, NVM_DATA0 ; Load NVM Data Register 0 into R22.
+ lds r23, NVM_DATA1 ; Load NVM Data Register 1 into R23.
+ lds r24, NVM_DATA2 ; Load NVM Data Register 2 into R24.
+ clr r25 ; Clear R25 in order to return a clean 32-bit value.
+ ret
+
+; This routine is called by several other routines, and contains common code
+; for executing an LPM command, including the return statement itself.
+;
+; Note that R24 is used for returning results, even if the
+; C-domain calling function expects a void.
+;
+; Input:
+; R25:R24 - Low bytes of Z pointer.
+; R20 - NVM Command code.
+;
+; Returns:
+; R24 - Result from LPM operation.
+.section .text
+FlashCommonLPM:
+ movw ZL, r24 ; Load index into Z.
+ sts NVM_CMD, r20 ; Load prepared command into NVM Command register.
+ lpm r24,Z
+ ret
+
+; This routine is called by several other routines, and contains common code
+; for executing an SPM command, including the return statement itself.
+;
+; If the operation (SPM command) requires the R1:R0 registers to be
+; prepared, this must be done before jumping to this routine.
+;
+; Input:
+; R1:R0 - Optional input to SPM command.
+; R25:R24 - Low bytes of Z pointer.
+; R20 - NVM Command code.
+;
+; Returns:
+; Nothing.
+.section .spmhelper
+FlashCommonSPM:
+ movw ZL, r24 ; Load R25:R24 into Z.
+ sts NVM_CMD, r20 ; Load prepared command into NVM Command register.
+ ldi r18, CCP_SPM_gc ; Prepare Protect SPM signature in R18
+ sts CCP, r18 ; Enable SPM operation (this disables interrupts for 4 cycles).
+ spm ; Self-program.
+ clr r1 ; Clear R1 for GCC _zero_reg_ to function properly.
+ out RAMPZ, r19 ; Restore RAMPZ register.
+ ret
+
+/* Reserve memory for data */
+.section .flashdata
+.align 1
+.skip MEMORY_SIZE, MEMORY_INIT_VALUE
diff --git a/RevE-light/Firmware/Chameleon-Mini/ProgramViaBootloader.bat b/RevE-light/Firmware/Chameleon-Mini/ProgramViaBootloader.bat
new file mode 100644
index 0000000..77329d3
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/ProgramViaBootloader.bat
@@ -0,0 +1,21 @@
+@ECHO OFF
+
+REM This script programs the Chameleon using batchisp (Atmel Flip) and DFU (device firmware upgrade via USB)
+REM You need to install Flip, otherwise it does not work
+REM Make sure to adjust the COMPORT variable to the actual com port the CDC Device enumerates as
+REM This is necessary to send the upgrade command and thus set the chameleon into DFU mode
+
+SET COMPORT=COM5
+SET TIMEOUT=5
+SET COMMAND=UPGRADE
+
+ECHO Trying to set bootloader mode on Chameleon-Mini on %COMPORT%
+@MODE %COMPORT% baud=11 parity=n data=8 stop=1 to=off xon=off odsr=off octs=off dtr=off rts=off idsr=off > nul
+@ECHO. > \\.\%COMPORT%
+@ECHO %COMMAND% > \\.\%COMPORT%
+
+ECHO Waiting for DFU Bootloader
+ping 127.0.0.1 -n %TIMEOUT% -w 1000 > nul
+
+ECHO Start Programming
+make dfu-flip
diff --git a/RevE-light/Firmware/Chameleon-Mini/README.txt b/RevE-light/Firmware/Chameleon-Mini/README.txt
new file mode 100644
index 0000000..e84da10
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/README.txt
@@ -0,0 +1,9 @@
+== Compiling the firmware ==
+For compiling under windows you need to do the following:
+1. Install AVR GNU Toolchain from Atmel
+2. Install Cygwin for sh.exe (base installation is sufficient)
+3. Add the bin path of cygwin (containing sh.exe) to the PATH environment variable for MAKE to find it
+
+Then you should be good to go to build the firmware by typing in the following:
+> make
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Random.c b/RevE-light/Firmware/Chameleon-Mini/Random.c
new file mode 100644
index 0000000..fb1a592
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Random.c
@@ -0,0 +1,30 @@
+#include "Random.h"
+
+#include
+
+void RandomInit(void)
+{
+
+}
+
+uint8_t RandomGetByte(void)
+{
+ return rand() & 0xFF;
+}
+
+void RandomGetBuffer(void* Buffer, uint8_t ByteCount)
+{
+ uint8_t* BufferPtr = (uint8_t*) Buffer;
+
+ while(ByteCount--) {
+ *BufferPtr++ = RandomGetByte();
+ }
+}
+
+void RandomTick(void)
+{
+ rand();
+ rand();
+ rand();
+ rand();
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Random.h b/RevE-light/Firmware/Chameleon-Mini/Random.h
new file mode 100644
index 0000000..c6609ed
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Random.h
@@ -0,0 +1,18 @@
+/*
+ * Random.h
+ *
+ * Created on: 22.03.2013
+ * Author: skuser
+ */
+
+#ifndef RANDOM_H_
+#define RANDOM_H_
+
+#include "Common.h"
+
+void RandomInit(void);
+uint8_t RandomGetByte(void);
+void RandomGetBuffer(void* Buffer, uint8_t ByteCount);
+void RandomTick(void);
+
+#endif /* RANDOM_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Settings.c b/RevE-light/Firmware/Chameleon-Mini/Settings.c
new file mode 100644
index 0000000..22c7183
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Settings.c
@@ -0,0 +1,101 @@
+#include "Settings.h"
+#include
+#include "Configuration.h"
+#include "Log.h"
+#include "Memory.h"
+#include "LEDHook.h"
+
+#define SETTING_TO_INDEX(S) (S - SETTINGS_FIRST)
+#define INDEX_TO_SETTING(I) (I + SETTINGS_FIRST)
+
+SettingsType GlobalSettings;
+SettingsType EEMEM StoredSettings = {
+ .ActiveSettingIdx = SETTING_TO_INDEX(DEFAULT_SETTING),
+ .ActiveSettingPtr = &GlobalSettings.Settings[SETTING_TO_INDEX(DEFAULT_SETTING)],
+
+ .Settings = { [0 ... (SETTINGS_COUNT-1)] = {
+ .Configuration = DEFAULT_CONFIGURATION,
+ .ButtonActions = {
+ [BUTTON_L_PRESS_SHORT] = DEFAULT_LBUTTON_ACTION, [BUTTON_R_PRESS_SHORT] = DEFAULT_RBUTTON_ACTION,
+ [BUTTON_L_PRESS_LONG] = DEFAULT_LBUTTON_ACTION, [BUTTON_R_PRESS_LONG] = DEFAULT_RBUTTON_ACTION
+ },
+ .LogMode = DEFAULT_LOG_MODE,
+ .LEDRedFunction = DEFAULT_RED_LED_ACTION,
+ .LEDGreenFunction = DEFAULT_GREEN_LED_ACTION
+ }}
+};
+
+void SettingsLoad(void) {
+ eeprom_read_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType));
+}
+
+void SettingsSave(void) {
+#if ENABLE_EEPROM_SETTINGS
+ eeprom_write_block(&GlobalSettings, &StoredSettings, sizeof(SettingsType));
+#endif
+}
+
+
+void SettingsCycle(void) {
+ uint8_t i = SETTINGS_COUNT;
+ uint8_t SettingIdx = GlobalSettings.ActiveSettingIdx;
+
+ while (i-- > 0) {
+ /* Try to set one of the SETTINGS_COUNT following settings.
+ * But only set if it is not CONFIG_NONE. */
+ SettingIdx = (SettingIdx + 1) % SETTINGS_COUNT;
+
+ if (GlobalSettings.Settings[SettingIdx].Configuration != CONFIG_NONE) {
+ SettingsSetActiveById(INDEX_TO_SETTING(SettingIdx));
+ break;
+ }
+ }
+}
+
+bool SettingsSetActiveById(uint8_t Setting) {
+ if ( (Setting >= SETTINGS_FIRST) && (Setting <= SETTINGS_LAST) ) {
+ uint8_t SettingIdx = SETTING_TO_INDEX(Setting);
+
+ /* Store current memory contents permanently */
+ MemoryStore();
+
+ GlobalSettings.ActiveSettingIdx = SettingIdx;
+ GlobalSettings.ActiveSettingPtr =
+ &GlobalSettings.Settings[SettingIdx];
+
+ /* Settings have changed. Progress changes through system */
+ ConfigurationSetById(GlobalSettings.ActiveSettingPtr->Configuration);
+ LogSetModeById(GlobalSettings.ActiveSettingPtr->LogMode);
+
+ /* Recall new memory contents */
+ MemoryRecall();
+
+ /* Notify LED. blink according to current setting */
+ LEDHook(LED_SETTING_CHANGE, LED_BLINK + SettingIdx);
+
+ return true;
+ } else {
+ return false;
+ }
+}
+
+uint8_t SettingsGetActiveById(void) {
+ return INDEX_TO_SETTING(GlobalSettings.ActiveSettingIdx);
+}
+
+void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize) {
+ SettingOut[0] = SettingsGetActiveById() + '0';
+ SettingOut[1] = '\0';
+}
+
+bool SettingsSetActiveByName(const char* Setting) {
+ uint8_t SettingNr = Setting[0] - '0';
+
+ if (Setting[1] == '\0') {
+ LogEntry(LOG_INFO_SETTING_SET, Setting, 1);
+ return SettingsSetActiveById(SettingNr);
+ } else {
+ return false;
+ }
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Settings.h b/RevE-light/Firmware/Chameleon-Mini/Settings.h
new file mode 100644
index 0000000..1f841fe
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Settings.h
@@ -0,0 +1,47 @@
+/*
+ * Settings.h
+ *
+ * Created on: 21.12.2013
+ * Author: skuser
+ */
+
+#ifndef SETTINGS_H_
+#define SETTINGS_H_
+
+#include "Button.h"
+#include "Configuration.h"
+#include "Log.h"
+#include "LED.h"
+#include "Memory.h"
+
+#define SETTINGS_COUNT (MEMORY_SIZE / MEMORY_SIZE_PER_SETTING)
+#define SETTINGS_FIRST 1
+#define SETTINGS_LAST (SETTINGS_FIRST + SETTINGS_COUNT - 1)
+
+
+typedef struct {
+ ButtonActionEnum ButtonActions[BUTTON_TYPE_COUNT];
+ LogModeEnum LogMode;
+ ConfigurationEnum Configuration;
+ LEDHookEnum LEDRedFunction;
+ LEDHookEnum LEDGreenFunction;
+} SettingsEntryType;
+
+typedef struct {
+ uint8_t ActiveSettingIdx;
+ SettingsEntryType* ActiveSettingPtr;
+ SettingsEntryType Settings[SETTINGS_COUNT];
+} SettingsType;
+
+extern SettingsType GlobalSettings;
+
+void SettingsLoad(void);
+void SettingsSave(void);
+
+void SettingsCycle(void);
+bool SettingsSetActiveById(uint8_t Setting);
+uint8_t SettingsGetActiveById(void);
+void SettingsGetActiveByName(char* SettingOut, uint16_t BufferSize);
+bool SettingsSetActiveByName(const char* Setting);
+
+#endif /* SETTINGS_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/System.c b/RevE-light/Firmware/Chameleon-Mini/System.c
new file mode 100644
index 0000000..23ba199
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/System.c
@@ -0,0 +1,119 @@
+/*
+ * System.c
+ *
+ * Created on: 10.02.2013
+ * Author: skuser
+ */
+
+#include "System.h"
+#include "LED.h"
+#include
+
+/* AVR Toolchain 3.4.5 changed defines */
+#ifndef WDT_PER_500CLK_gc
+#define WDT_PER_500CLK_gc WDT_PER_512CLK_gc
+#endif
+
+
+ISR(BADISR_vect)
+{
+ while(1);
+}
+
+ISR(RTC_OVF_vect)
+{
+ SYSTEM_TICK_REGISTER += SYSTEM_TICK_PERIOD;
+}
+
+void SystemInit(void)
+{
+ if (RST.STATUS & RST_WDRF_bm) {
+ /* On Watchdog reset clear WDRF bit, disable watchdog
+ * and jump into bootloader */
+ RST.STATUS = RST_WDRF_bm;
+
+ CCP = CCP_IOREG_gc;
+ WDT.CTRL = WDT_CEN_bm;
+
+ asm volatile ("jmp %0"::"i" (BOOT_SECTION_START + 0x1FC));
+ }
+
+ /* 32MHz system clock using internal RC and 32K DFLL*/
+ OSC.CTRL |= OSC_RC32MEN_bm | OSC_RC32KEN_bm;
+ while(!(OSC.STATUS & OSC_RC32MRDY_bm))
+ ;
+ while(!(OSC.STATUS & OSC_RC32KRDY_bm))
+ ;
+
+ OSC.DFLLCTRL = OSC_RC32MCREF_RC32K_gc;
+ DFLLRC32M.CTRL = DFLL_ENABLE_bm;
+
+ CCP = CCP_IOREG_gc;
+ CLK.CTRL = CLK_SCLKSEL_RC32M_gc;
+
+ /* Use TCE0 as system tick */
+ TCE0.PER = F_CPU / 256 / SYSTEM_TICK_FREQ - 1;
+ TCE0.CTRLA = TC_CLKSEL_DIV256_gc;
+
+ /* Enable RTC with roughly 1kHz clock for system tick
+ * and to wake up while sleeping. */
+ CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm;
+ RTC.PER = 1000 / SYSTEM_TICK_FREQ - 1;
+ RTC.COMP = 1000 / SYSTEM_TICK_FREQ - 1;
+ RTC.CTRL = RTC_PRESCALER_DIV1_gc;
+ RTC.INTCTRL = RTC_OVFINTLVL_LO_gc;
+
+
+ /* Enable EEPROM data memory mapping */
+ NVM.CTRLB |= NVM_EEMAPEN_bm;
+}
+
+void SystemReset(void)
+{
+ CCP = CCP_IOREG_gc;
+ RST.CTRL = RST_SWRST_bm;
+
+}
+
+void SystemEnterBootloader(void)
+{
+ /* Use Watchdog timer to reset into bootloader. */
+ CCP = CCP_IOREG_gc;
+ WDT.CTRL = WDT_PER_500CLK_gc | WDT_ENABLE_bm | WDT_CEN_bm;
+}
+
+
+void SystemStartUSBClock(void)
+{
+ SystemSleepDisable();
+
+ /* 48MHz USB Clock using 12MHz XTAL */
+ OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
+ OSC.CTRL |= OSC_XOSCEN_bm;
+ while(!(OSC.STATUS & OSC_XOSCRDY_bm))
+ ;
+
+ OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (4 << OSC_PLLFAC_gp);
+
+ OSC.CTRL |= OSC_PLLEN_bm;
+ while(!(OSC.STATUS & OSC_PLLRDY_bm))
+ ;
+}
+
+void SystemStopUSBClock(void)
+{
+ SystemSleepEnable();
+
+ /* Disable USB Clock to minimize power consumption */
+ CLK.USBCTRL &= ~CLK_USBSEN_bm;
+ OSC.CTRL &= ~OSC_PLLEN_bm;
+ OSC.CTRL &= ~OSC_XOSCEN_bm;
+}
+
+void SystemInterruptInit(void)
+{
+ /* Enable all interrupt levels */
+ PMIC.CTRL = PMIC_LOLVLEN_bm | PMIC_MEDLVLEN_bm | PMIC_HILVLEN_bm;
+ sei();
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/System.h b/RevE-light/Firmware/Chameleon-Mini/System.h
new file mode 100644
index 0000000..65fe539
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/System.h
@@ -0,0 +1,84 @@
+/*
+ * System.h
+ *
+ * Created on: 10.02.2013
+ * Author: skuser
+ */
+
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+#include
+#include
+#include
+#include
+#include
+#include "Common.h"
+
+typedef uint16_t SystemRTCType;
+
+#define F_RTC 1000
+#define SYSTEM_MILLISECONDS_TO_RTC_CYCLES(x) \
+ ( (uint16_t) ( (double) F_RTC * x / 1E3 + 0.5) )
+
+#define SYSTEM_TICK_WIDTH 7 /* Bits */
+#define SYSTEM_TICK_PERIOD (1<<7)
+#define SYSTEM_TICK_FREQ 10
+#define SYSTEM_TICK_MS (1000/SYSTEM_TICK_FREQ)
+
+#define SYSTEM_SMODE_PSAVE SLEEP_SMODE_PSAVE_gc
+#define SYSTEM_SMODE_IDLE SLEEP_SMODE_IDLE_gc
+
+/* Use GPIORE and GPIORF as global tick register */
+#define SYSTEM_TICK_REGISTER (*((volatile uint16_t*) &GPIORE))
+
+void SystemInit(void);
+void SystemReset(void);
+void SystemEnterBootloader(void);
+void SystemStartUSBClock(void);
+void SystemStopUSBClock(void);
+void SystemInterruptInit(void);
+INLINE bool SystemTick100ms(void);
+INLINE void SystemSleep(void);
+INLINE void SystemSleepEnable(void);
+INLINE void SystemSleepDisable(void);
+INLINE void SystemSleepSetMode(uint8_t SleepMode);
+
+INLINE bool SystemTick100ms(void)
+{
+ if (RTC.INTFLAGS & RTC_COMPIF_bm) {
+ while(RTC.STATUS & RTC_SYNCBUSY_bm)
+ ;
+
+ RTC.INTFLAGS = RTC_COMPIF_bm;
+ return true;
+ }
+
+ return false;
+}
+
+INLINE uint16_t SystemGetSysTick(void) {
+ return SYSTEM_TICK_REGISTER | RTC.CNT;
+}
+
+INLINE void SystemSleep(void)
+{
+ asm volatile("sleep");
+}
+
+INLINE void SystemSleepEnable(void)
+{
+ SLEEP.CTRL |= SLEEP_SEN_bm;
+}
+
+INLINE void SystemSleepDisable(void)
+{
+ SLEEP.CTRL &= ~SLEEP_SEN_bm;
+}
+
+INLINE void SystemSleepSetMode(uint8_t SleepMode)
+{
+ SLEEP.CTRL = (SLEEP.CTRL & ~SLEEP_SMODE_gm) | SleepMode;
+}
+
+#endif /* SYSTEM_H */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/CommandLine.c b/RevE-light/Firmware/Chameleon-Mini/Terminal/CommandLine.c
new file mode 100644
index 0000000..e7ad8ca
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/CommandLine.c
@@ -0,0 +1,412 @@
+/*
+ * CommandLine.c
+ *
+ * Created on: 04.05.2013
+ * Author: skuser
+ */
+
+#include "CommandLine.h"
+
+#define CHAR_GET_MODE '?' /* ? */
+#define CHAR_SET_MODE '=' /* = */
+#define CHAR_EXEC_MODE '\0' /* */
+#define CHAR_EXEC_MODE_PARAM ' ' /* ... */
+
+#define IS_COMMAND_DELIMITER(c) ( \
+ ((c) == CHAR_EXEC_MODE) || ((c) == CHAR_GET_MODE) || ((c) == CHAR_SET_MODE) || ((c) == CHAR_EXEC_MODE_PARAM) \
+)
+
+#define IS_CHARACTER(c) ( \
+ ( ((c) >= 'A') && ((c) <= 'Z') ) || \
+ ( ((c) >= 'a') && ((c) <= 'z') ) || \
+ ( ((c) >= '0') && ((c) <= '9') ) || \
+ ( ((c) == '_') ) || \
+ ( ((c) == CHAR_GET_MODE) || ((c) == CHAR_SET_MODE) || ((c) == CHAR_EXEC_MODE_PARAM) ) \
+)
+
+#define IS_LOWERCASE(c) ( ((c) >= 'a') && ((c) <= 'z') )
+#define TO_UPPERCASE(c) ( (c) - 'a' + 'A' )
+
+#define IS_WHITESPACE(c) ( ((c) == ' ') || ((c) == '\t') )
+
+#define NO_FUNCTION ((void*) 0)
+
+#define STATUS_MESSAGE_TRAILER "\r\n"
+#define OPTIONAL_ANSWER_TRAILER "\r\n"
+
+/* Include all command functions */
+#include "Commands.h"
+
+const PROGMEM CommandEntryType CommandTable[] = {
+ {
+ .Command = COMMAND_VERSION,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetVersion,
+ },
+ {
+ .Command = COMMAND_CONFIG,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetConfig,
+ .GetFunc = CommandGetConfig
+ },
+ {
+ .Command = COMMAND_UID,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetUid,
+ .GetFunc = CommandGetUid
+ },
+ {
+ .Command = COMMAND_READONLY,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .GetFunc = CommandGetReadOnly,
+ .SetFunc = CommandSetReadOnly
+
+ },
+ {
+ .Command = COMMAND_UPLOAD,
+ .ExecFunc = CommandExecUpload,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_DOWNLOAD,
+ .ExecFunc = CommandExecDownload,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_RESET,
+ .ExecFunc = CommandExecReset,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+#ifdef SUPPORT_FIRMWARE_UPGRADE
+ {
+ .Command = COMMAND_UPGRADE,
+ .ExecFunc = CommandExecUpgrade,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+#endif
+ {
+ .Command = COMMAND_MEMSIZE,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetMemSize
+ },
+ {
+ .Command = COMMAND_UIDSIZE,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetUidSize
+ },
+ {
+ .Command = COMMAND_RBUTTON,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetRButton,
+ .GetFunc = CommandGetRButton
+ },
+ {
+ .Command = COMMAND_RBUTTON_LONG,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetRButtonLong,
+ .GetFunc = CommandGetRButtonLong
+ },
+ {
+ .Command = COMMAND_LBUTTON,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetLButton,
+ .GetFunc = CommandGetLButton
+ },
+ {
+ .Command = COMMAND_LBUTTON_LONG,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetLButtonLong,
+ .GetFunc = CommandGetLButtonLong
+ },
+ {
+ .Command = COMMAND_LEDGREEN,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetLedGreen,
+ .GetFunc = CommandGetLedGreen
+ },
+ {
+ .Command = COMMAND_LEDRED,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetLedRed,
+ .GetFunc = CommandGetLedRed
+ },
+ {
+ .Command = COMMAND_LOGMODE,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetLogMode,
+ .GetFunc = CommandGetLogMode
+ },
+ {
+ .Command = COMMAND_LOGMEM,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetLogMem
+ },
+ {
+ .Command = COMMAND_LOGDOWNLOAD,
+ .ExecFunc = CommandExecLogDownload,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_LOGCLEAR,
+ .ExecFunc = CommandExecLogClear,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_SETTING,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = CommandSetSetting,
+ .GetFunc = CommandGetSetting
+ },
+ {
+ .Command = COMMAND_CLEAR,
+ .ExecFunc = CommandExecClear,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_STORE,
+ .ExecFunc = CommandExecStore,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_RECALL,
+ .ExecFunc = CommandExecRecall,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_CHARGING,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetCharging
+ },
+ {
+ .Command = COMMAND_HELP,
+ .ExecFunc = CommandExecHelp,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ },
+ {
+ .Command = COMMAND_RSSI,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetRssi
+ },
+ {
+ .Command = COMMAND_SYSTICK,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = CommandGetSysTick
+ },
+ { /* This has to be last element */
+ .Command = COMMAND_LIST_END,
+ .ExecFunc = NO_FUNCTION,
+ .ExecParamFunc = NO_FUNCTION,
+ .SetFunc = NO_FUNCTION,
+ .GetFunc = NO_FUNCTION
+ }
+};
+
+#define STATUS_TABLE_ENTRY(Id, Text) \
+ { Id, STRINGIFY(Id) ":" Text }
+
+typedef struct {
+ CommandStatusIdType Id;
+ CommandStatusMessageType Message;
+} CommandStatusType;
+
+static const CommandStatusType PROGMEM StatusTable[] = {
+ STATUS_TABLE_ENTRY(COMMAND_INFO_OK_ID, COMMAND_INFO_OK),
+ STATUS_TABLE_ENTRY(COMMAND_INFO_OK_WITH_TEXT_ID, COMMAND_INFO_OK_WITH_TEXT),
+ STATUS_TABLE_ENTRY(COMMAND_INFO_XMODEM_WAIT_ID, COMMAND_INFO_XMODEM_WAIT),
+ STATUS_TABLE_ENTRY(COMMAND_ERR_UNKNOWN_CMD_ID, COMMAND_ERR_UNKNOWN_CMD),
+ STATUS_TABLE_ENTRY(COMMAND_ERR_INVALID_USAGE_ID, COMMAND_ERR_INVALID_USAGE),
+ STATUS_TABLE_ENTRY(COMMAND_ERR_INVALID_PARAM_ID, COMMAND_ERR_INVALID_PARAM),
+ STATUS_TABLE_ENTRY(COMMAND_INFO_FALSE_ID, COMMAND_INFO_FALSE),
+ STATUS_TABLE_ENTRY(COMMAND_INFO_TRUE_ID, COMMAND_INFO_TRUE),
+};
+
+static uint16_t BufferIdx;
+
+static const char* GetStatusMessageP(CommandStatusIdType StatusId)
+{
+ uint8_t i;
+
+ for (i=0; i<(sizeof(StatusTable)/sizeof(*StatusTable)); i++) {
+ if (pgm_read_byte(&StatusTable[i].Id) == StatusId)
+ return StatusTable[i].Message;
+ }
+
+ return (void*) 0;
+}
+
+static CommandStatusIdType CallCommandFunc(
+ const CommandEntryType* CommandEntry, char CommandDelimiter, char* pParam) {
+ char* pTerminalBuffer = (char*) TerminalBuffer;
+
+ /* Call appropriate function depending on CommandDelimiter */
+ if (CommandDelimiter == CHAR_GET_MODE) {
+ CommandGetFuncType GetFunc = pgm_read_ptr(&CommandEntry->GetFunc);
+ if (GetFunc != NO_FUNCTION) {
+ return GetFunc(pTerminalBuffer);
+ }
+ } else if (CommandDelimiter == CHAR_SET_MODE) {
+ CommandSetFuncType SetFunc = pgm_read_ptr(&CommandEntry->SetFunc);
+ if (SetFunc != NO_FUNCTION) {
+ return SetFunc(pTerminalBuffer, pParam);
+ }
+ } else if (CommandDelimiter == CHAR_EXEC_MODE) {
+ CommandExecFuncType ExecFunc = pgm_read_ptr(&CommandEntry->ExecFunc);
+ if (ExecFunc != NO_FUNCTION) {
+ return ExecFunc(pTerminalBuffer);
+ }
+ } else if (CommandDelimiter == CHAR_EXEC_MODE_PARAM) {
+ CommandExecParamFuncType ExecParamFunc = pgm_read_ptr(&CommandEntry->ExecParamFunc);
+ if (ExecParamFunc != NO_FUNCTION) {
+ return ExecParamFunc(pTerminalBuffer, pParam);
+ }
+ } else {
+ /* This should not happen (TM) */
+ }
+
+ /* This delimiter has not been registered with this command */
+ return COMMAND_ERR_INVALID_USAGE_ID;
+}
+
+static void DecodeCommand(void)
+{
+ uint8_t i;
+ bool CommandFound = false;
+ CommandStatusIdType StatusId = COMMAND_ERR_UNKNOWN_CMD_ID;
+ char* pTerminalBuffer = (char*) TerminalBuffer;
+
+ /* Do some sanity check first */
+ if (!IS_COMMAND_DELIMITER(pTerminalBuffer[0])) {
+ char* pCommandDelimiter = pTerminalBuffer;
+ char CommandDelimiter = '\0';
+
+ /* Search for command delimiter, store it and replace with '\0' */
+ while(!(IS_COMMAND_DELIMITER(*pCommandDelimiter)))
+ pCommandDelimiter++;
+
+ CommandDelimiter = *pCommandDelimiter;
+ *pCommandDelimiter = '\0';
+
+ /* Search in command table */
+ for (i=0; i<(sizeof(CommandTable) / sizeof(*CommandTable)); i++) {
+ if (strcmp_P(pTerminalBuffer, CommandTable[i].Command) == 0) {
+ /* Command found. Clear buffer, and call appropriate function */
+ char* pParam = ++pCommandDelimiter;
+
+ pTerminalBuffer[0] = '\0';
+ CommandFound = true;
+
+ StatusId = CallCommandFunc(&CommandTable[i], CommandDelimiter, pParam);
+
+ break;
+ }
+ }
+ }
+
+ /* Send command status message */
+ TerminalSendStringP(GetStatusMessageP(StatusId));
+ TerminalSendStringP(PSTR(STATUS_MESSAGE_TRAILER));
+
+ if (CommandFound && (pTerminalBuffer[0] != '\0') ) {
+ /* Send optional answer */
+ TerminalSendString(pTerminalBuffer);
+ TerminalSendStringP(PSTR(OPTIONAL_ANSWER_TRAILER));
+ }
+}
+
+void CommandLineInit(void)
+{
+ BufferIdx = 0;
+}
+
+bool CommandLineProcessByte(uint8_t Byte) {
+ if (IS_CHARACTER(Byte)) {
+ /* Store uppercase character */
+ if (IS_LOWERCASE(Byte)) {
+ Byte = TO_UPPERCASE(Byte);
+ }
+
+ /* Prevent buffer overflow and account for '\0' */
+ if (BufferIdx
+ < (sizeof(TerminalBuffer) / sizeof(*TerminalBuffer) - 1)) {
+ TerminalBuffer[BufferIdx++] = Byte;
+ }
+ } else if (Byte == '\r') {
+ /* Process on \r. Terminate string and decode. */
+ TerminalBuffer[BufferIdx] = '\0';
+ BufferIdx = 0;
+
+ DecodeCommand();
+ } else if (Byte == '\b') {
+ /* Backspace. Delete last character in buffer. */
+ if (BufferIdx > 0) {
+ BufferIdx--;
+ }
+ } else if (Byte == 0x1B) {
+ /* Drop buffer on escape */
+ BufferIdx = 0;
+ } else {
+ /* Ignore other chars */
+ }
+
+ return true;
+}
+
+void CommandLineTick(void)
+{
+
+}
+
+void CommandLineAppendData(void* Buffer, uint16_t Bytes)
+{
+ char* pTerminalBuffer = (char*) TerminalBuffer;
+
+ BufferToHexString(pTerminalBuffer, sizeof(TerminalBuffer), Buffer, Bytes);
+
+ TerminalSendString(pTerminalBuffer);
+ TerminalSendStringP(PSTR(OPTIONAL_ANSWER_TRAILER));
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/CommandLine.h b/RevE-light/Firmware/Chameleon-Mini/Terminal/CommandLine.h
new file mode 100644
index 0000000..bb6b627
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/CommandLine.h
@@ -0,0 +1,19 @@
+/*
+ * CommandLine.h
+ *
+ * Created on: 04.05.2013
+ * Author: skuser
+ */
+
+#ifndef COMMANDLINE_H_
+#define COMMANDLINE_H_
+
+#include "Terminal.h"
+
+void CommandLineInit(void);
+bool CommandLineProcessByte(uint8_t Byte);
+void CommandLineTick(void);
+
+void CommandLineAppendData(void* Buffer, uint16_t Bytes);
+
+#endif /* COMMANDLINE_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/Commands.c b/RevE-light/Firmware/Chameleon-Mini/Terminal/Commands.c
new file mode 100644
index 0000000..e693991
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/Commands.c
@@ -0,0 +1,418 @@
+
+#include "Commands.h"
+#include
+#include
+#include "XModem.h"
+#include "../Settings.h"
+#include "../Chameleon-Mini.h"
+#include "../LUFA/Version.h"
+#include "../Configuration.h"
+#include "../Random.h"
+#include "../Memory.h"
+#include "../System.h"
+#include "../Button.h"
+#include "../AntennaLevel.h"
+#include "../Battery.h"
+
+extern const PROGMEM CommandEntryType CommandTable[];
+
+CommandStatusIdType CommandGetVersion(char* OutParam)
+{
+ snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR(
+ "Chameleon-Mini %S using LUFA %S compiled with AVR-GCC %S"
+ ), PSTR(CHAMELEON_MINI_VERSION_STRING), PSTR(LUFA_VERSION_STRING), PSTR(__VERSION__)
+ );
+
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+}
+
+CommandStatusIdType CommandGetConfig(char* OutParam)
+{
+ ConfigurationGetByName(OutParam, TERMINAL_BUFFER_SIZE);
+
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+}
+
+CommandStatusIdType CommandSetConfig(char* OutMessage, const char* InParam)
+{
+ if (COMMAND_IS_SUGGEST_STRING(InParam)) {
+ ConfigurationGetList(OutMessage, TERMINAL_BUFFER_SIZE);
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+ } else if (ConfigurationSetByName(InParam)) {
+ SettingsSave();
+ return COMMAND_INFO_OK_ID;
+ } else {
+ return COMMAND_ERR_INVALID_PARAM_ID;
+ }
+}
+
+CommandStatusIdType CommandGetUid(char* OutParam)
+{
+ uint8_t UidBuffer[COMMAND_UID_BUFSIZE];
+ uint16_t UidSize = ActiveConfiguration.UidSize;
+
+ ApplicationGetUid(UidBuffer);
+
+ BufferToHexString(OutParam, TERMINAL_BUFFER_SIZE,
+ UidBuffer, UidSize);
+
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+}
+
+CommandStatusIdType CommandSetUid(char* OutMessage, const char* InParam)
+{
+ uint8_t UidBuffer[COMMAND_UID_BUFSIZE];
+ uint16_t UidSize = ActiveConfiguration.UidSize;
+
+ if (strcmp_P(InParam, PSTR(COMMAND_UID_RANDOM)) == 0) {
+ /* Load with random bytes */
+ for (uint8_t i=0; iCommand) != 0) {
+ const char* CommandName = EntryPtr->Command;
+ char c;
+
+ while( (c = pgm_read_byte(CommandName)) != '\0' && ByteCount > 32) {
+ *OutMessage++ = c;
+ CommandName++;
+ ByteCount--;
+ }
+
+ *OutMessage++ = ',';
+ ByteCount--;
+
+ EntryPtr++;
+ }
+
+ *--OutMessage = '\0';
+
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+}
+
+CommandStatusIdType CommandGetRssi(char* OutParam)
+{
+ snprintf_P(OutParam, TERMINAL_BUFFER_SIZE,
+ PSTR("%5u mV"), AntennaLevelGet());
+
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+}
+
+CommandStatusIdType CommandGetSysTick(char* OutParam)
+{
+ snprintf_P(OutParam, TERMINAL_BUFFER_SIZE, PSTR("%4.4X"), SystemGetSysTick());
+
+ return COMMAND_INFO_OK_WITH_TEXT_ID;
+}
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/Commands.h b/RevE-light/Firmware/Chameleon-Mini/Terminal/Commands.h
new file mode 100644
index 0000000..a481130
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/Commands.h
@@ -0,0 +1,154 @@
+
+
+#ifndef COMMANDS_H_
+#define COMMANDS_H_
+
+#include "../Common.h"
+
+#define MAX_COMMAND_LENGTH 16
+#define MAX_STATUS_LENGTH 32
+
+
+#define COMMAND_INFO_OK_ID 100
+#define COMMAND_INFO_OK "OK"
+#define COMMAND_INFO_OK_WITH_TEXT_ID 101
+#define COMMAND_INFO_OK_WITH_TEXT "OK WITH TEXT"
+#define COMMAND_INFO_XMODEM_WAIT_ID 110
+#define COMMAND_INFO_XMODEM_WAIT "WAITING FOR XMODEM"
+#define COMMAND_INFO_FALSE_ID 120
+#define COMMAND_INFO_FALSE "FALSE"
+#define COMMAND_INFO_TRUE_ID 121
+#define COMMAND_INFO_TRUE "TRUE"
+#define COMMAND_ERR_UNKNOWN_CMD_ID 200
+#define COMMAND_ERR_UNKNOWN_CMD "UNKNOWN COMMAND"
+#define COMMAND_ERR_INVALID_USAGE_ID 201
+#define COMMAND_ERR_INVALID_USAGE "INVALID COMMAND USAGE"
+#define COMMAND_ERR_INVALID_PARAM_ID 202
+#define COMMAND_ERR_INVALID_PARAM "INVALID PARAMETER"
+
+
+#define COMMAND_CHAR_TRUE '1'
+#define COMMAND_CHAR_FALSE '0'
+#define COMMAND_CHAR_SUGGEST '?' /* =? for help */
+
+#define COMMAND_UID_BUFSIZE 32
+
+#define COMMAND_IS_SUGGEST_STRING(x) ( ((x)[0] == COMMAND_CHAR_SUGGEST) && ((x)[1] == '\0') )
+
+typedef uint8_t CommandStatusIdType;
+typedef const char CommandStatusMessageType[MAX_STATUS_LENGTH];
+
+typedef CommandStatusIdType (*CommandExecFuncType) (char* OutMessage);
+typedef CommandStatusIdType (*CommandExecParamFuncType) (char* OutMessage, const char* InParams);
+typedef CommandStatusIdType (*CommandSetFuncType) (char* OutMessage, const char* InParam);
+typedef CommandStatusIdType (*CommandGetFuncType) (char* OutParam);
+
+typedef struct {
+ char Command[MAX_COMMAND_LENGTH];
+ CommandExecFuncType ExecFunc;
+ CommandExecParamFuncType ExecParamFunc;
+ CommandSetFuncType SetFunc;
+ CommandGetFuncType GetFunc;
+} CommandEntryType;
+
+#define COMMAND_VERSION "VERSION"
+CommandStatusIdType CommandGetVersion(char* OutParam);
+
+#define COMMAND_CONFIG "CONFIG"
+CommandStatusIdType CommandGetConfig(char* OutParam);
+CommandStatusIdType CommandSetConfig(char* OutMessage, const char* InParam);
+
+#define COMMAND_UID "UID"
+#define COMMAND_UID_RANDOM "RANDOM"
+CommandStatusIdType CommandGetUid(char* OutParam);
+CommandStatusIdType CommandSetUid(char* OutMessage, const char* InParam);
+
+#define COMMAND_READONLY "READONLY"
+CommandStatusIdType CommandGetReadOnly(char* OutParam);
+CommandStatusIdType CommandSetReadOnly(char* OutMessage, const char* InParam);
+
+#define COMMAND_UPLOAD "UPLOAD"
+CommandStatusIdType CommandExecUpload(char* OutMessage);
+
+#define COMMAND_DOWNLOAD "DOWNLOAD"
+CommandStatusIdType CommandExecDownload(char* OutMessage);
+
+#define COMMAND_RESET "RESET"
+CommandStatusIdType CommandExecReset(char* OutMessage);
+
+#define COMMAND_UPGRADE "UPGRADE"
+CommandStatusIdType CommandExecUpgrade(char* OutMessage);
+
+#define COMMAND_MEMSIZE "MEMSIZE"
+CommandStatusIdType CommandGetMemSize(char* OutParam);
+
+#define COMMAND_UIDSIZE "UIDSIZE"
+CommandStatusIdType CommandGetUidSize(char* OutParam);
+
+#define COMMAND_RBUTTON "RBUTTON"
+CommandStatusIdType CommandGetRButton(char* OutParam);
+CommandStatusIdType CommandSetRButton(char* OutMessage, const char* InParam);
+
+#define COMMAND_RBUTTON_LONG "RBUTTON_LONG"
+CommandStatusIdType CommandGetRButtonLong(char* OutParam);
+CommandStatusIdType CommandSetRButtonLong(char* OutMessage, const char* InParam);
+
+#define COMMAND_LBUTTON "LBUTTON"
+CommandStatusIdType CommandGetLButton(char* OutParam);
+CommandStatusIdType CommandSetLButton(char* OutMessage, const char* InParam);
+
+#define COMMAND_LBUTTON_LONG "LBUTTON_LONG"
+CommandStatusIdType CommandGetLButtonLong(char* OutParam);
+CommandStatusIdType CommandSetLButtonLong(char* OutMessage, const char* InParam);
+
+
+#define COMMAND_LEDGREEN "LEDGREEN"
+CommandStatusIdType CommandGetLedGreen(char* OutParam);
+CommandStatusIdType CommandSetLedGreen(char* OutMessage, const char* InParam);
+
+#define COMMAND_LEDRED "LEDRED"
+CommandStatusIdType CommandGetLedRed(char* OutParam);
+CommandStatusIdType CommandSetLedRed(char* OutMessage, const char* InParam);
+
+#define COMMAND_LOGMODE "LOGMODE"
+CommandStatusIdType CommandGetLogMode(char* OutParam);
+CommandStatusIdType CommandSetLogMode(char* OutMessage, const char* InParam);
+
+#define COMMAND_LOGMEM "LOGMEM"
+CommandStatusIdType CommandGetLogMem(char* OutParam);
+
+#define COMMAND_LOGDOWNLOAD "LOGDOWNLOAD"
+CommandStatusIdType CommandExecLogDownload(char* OutMessage);
+
+#define COMMAND_LOGCLEAR "LOGCLEAR"
+CommandStatusIdType CommandExecLogClear(char* OutMessage);
+
+#define COMMAND_SETTING "SETTING"
+CommandStatusIdType CommandGetSetting(char* OutParam);
+CommandStatusIdType CommandSetSetting(char* OutMessage, const char* InParam);
+
+#define COMMAND_CLEAR "CLEAR"
+CommandStatusIdType CommandExecClear(char* OutMessage);
+
+#define COMMAND_STORE "STORE"
+CommandStatusIdType CommandExecStore(char* OutMessage);
+
+#define COMMAND_RECALL "RECALL"
+CommandStatusIdType CommandExecRecall(char* OutMessage);
+
+#define COMMAND_CHARGING "CHARGING"
+CommandStatusIdType CommandGetCharging(char* OutParam);
+
+#define COMMAND_HELP "HELP"
+CommandStatusIdType CommandExecHelp(char* OutMessage);
+
+#define COMMAND_RSSI "RSSI"
+CommandStatusIdType CommandGetRssi(char* OutParam);
+
+#define COMMAND_SYSTICK "SYSTICK"
+CommandStatusIdType CommandGetSysTick(char* OutParam);
+
+#define COMMAND_LIST_END ""
+/* Defines the end of command list. This is no actual command */
+
+#endif /* COMMANDS_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/Terminal.c b/RevE-light/Firmware/Chameleon-Mini/Terminal/Terminal.c
new file mode 100644
index 0000000..6867047
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/Terminal.c
@@ -0,0 +1,170 @@
+
+#include "Terminal.h"
+#include "../System.h"
+#include "../LEDHook.h"
+
+#include "../LUFADescriptors.h"
+
+#define INIT_DELAY (2000 / SYSTEM_TICK_MS)
+
+
+USB_ClassInfo_CDC_Device_t TerminalHandle = {
+ .Config = {
+ .ControlInterfaceNumber = 0,
+ .DataINEndpoint = {
+ .Address = CDC_TX_EPADDR,
+ .Size = CDC_TXRX_EPSIZE,
+ .Banks = 1,
+ }, .DataOUTEndpoint = {
+ .Address = CDC_RX_EPADDR,
+ .Size = CDC_TXRX_EPSIZE,
+ .Banks = 1,
+ }, .NotificationEndpoint = {
+ .Address = CDC_NOTIFICATION_EPADDR,
+ .Size = CDC_NOTIFICATION_EPSIZE,
+ .Banks = 1,
+ },
+ }
+};
+
+uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE];
+TerminalStateEnum TerminalState = TERMINAL_UNINITIALIZED;
+static uint8_t TerminalInitDelay = INIT_DELAY;
+
+void TerminalSendString(const char* s) {
+ CDC_Device_SendString(&TerminalHandle, s);
+}
+
+void TerminalSendStringP(const char* s) {
+ char c;
+
+ while( (c = pgm_read_byte(s++)) != '\0' ) {
+ TerminalSendChar(c);
+ }
+}
+
+/*
+void TerminalSendHex(void* Buffer, uint16_t ByteCount)
+{
+ char* pTerminalBuffer = (char*) TerminalBuffer;
+
+ BufferToHexString(pTerminalBuffer, sizeof(TerminalBuffer), Buffer, ByteCount);
+
+ TerminalSendString(pTerminalBuffer);
+}
+
+*/
+
+
+void TerminalSendBlock(const void* Buffer, uint16_t ByteCount)
+{
+ CDC_Device_SendData(&TerminalHandle, Buffer, ByteCount);
+}
+
+
+static void ProcessByte(void) {
+ int16_t Byte = CDC_Device_ReceiveByte(&TerminalHandle);
+
+ if (Byte >= 0) {
+ /* Byte received */
+ LEDHook(LED_TERMINAL_RXTX, LED_PULSE);
+
+ if (XModemProcessByte(Byte)) {
+ /* XModem handled the byte */
+ } else if (CommandLineProcessByte(Byte)) {
+ /* CommandLine handled the byte */
+ }
+ }
+}
+
+static void SenseVBus(void)
+{
+ switch(TerminalState) {
+ case TERMINAL_UNINITIALIZED:
+ if (TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK) {
+ /* Not initialized and VBUS sense high */
+ TerminalInitDelay = INIT_DELAY;
+ TerminalState = TERMINAL_INITIALIZING;
+ }
+ break;
+
+ case TERMINAL_INITIALIZING:
+ if (--TerminalInitDelay == 0) {
+ SystemStartUSBClock();
+ USB_Init();
+ TerminalState = TERMINAL_INITIALIZED;
+ }
+ break;
+
+ case TERMINAL_INITIALIZED:
+ if (!(TERMINAL_VBUS_PORT.IN & TERMINAL_VBUS_MASK)) {
+ /* Initialized and VBUS sense low */
+ TerminalInitDelay = INIT_DELAY;
+ TerminalState = TERMINAL_UNITIALIZING;
+ }
+ break;
+
+ case TERMINAL_UNITIALIZING:
+ if (--TerminalInitDelay == 0) {
+ USB_Disable();
+ SystemStopUSBClock();
+ TerminalState = TERMINAL_UNINITIALIZED;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+void TerminalInit(void)
+{
+ TERMINAL_VBUS_PORT.DIRCLR = TERMINAL_VBUS_MASK;
+}
+
+void TerminalTask(void)
+{
+ if (TerminalState == TERMINAL_INITIALIZED) {
+ CDC_Device_USBTask(&TerminalHandle);
+ USB_USBTask();
+
+ ProcessByte();
+ }
+}
+
+void TerminalTick(void)
+{
+ SenseVBus();
+
+ if (TerminalState == TERMINAL_INITIALIZED) {
+ XModemTick();
+ CommandLineTick();
+ }
+}
+
+/** Event handler for the library USB Connection event. */
+void EVENT_USB_Device_Connect(void)
+{
+ LEDHook(LED_TERMINAL_CONN, LED_ON);
+}
+
+/** Event handler for the library USB Disconnection event. */
+void EVENT_USB_Device_Disconnect(void)
+{
+ LEDHook(LED_TERMINAL_CONN, LED_OFF);
+}
+
+
+/** Event handler for the library USB Configuration Changed event. */
+void EVENT_USB_Device_ConfigurationChanged(void)
+{
+ CDC_Device_ConfigureEndpoints(&TerminalHandle);
+}
+
+/** Event handler for the library USB Control Request reception event. */
+void EVENT_USB_Device_ControlRequest(void)
+{
+ CDC_Device_ProcessControlRequest(&TerminalHandle);
+}
+
+
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/Terminal.h b/RevE-light/Firmware/Chameleon-Mini/Terminal/Terminal.h
new file mode 100644
index 0000000..aea0c1c
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/Terminal.h
@@ -0,0 +1,52 @@
+/*
+ * CommandLine.h
+ *
+ * Created on: 10.02.2013
+ * Author: skuser
+ */
+
+#ifndef TERMINAL_H_
+#define TERMINAL_H_
+
+#include "../Common.h"
+#include
+#include "XModem.h"
+#include "CommandLine.h"
+
+#define TERMINAL_VBUS_PORT PORTD
+#define TERMINAL_VBUS_MASK PIN5_bm
+
+#define TERMINAL_BUFFER_SIZE 256
+
+typedef enum {
+ TERMINAL_UNINITIALIZED,
+ TERMINAL_INITIALIZING,
+ TERMINAL_INITIALIZED,
+ TERMINAL_UNITIALIZING
+} TerminalStateEnum;
+
+extern uint8_t TerminalBuffer[TERMINAL_BUFFER_SIZE];
+extern USB_ClassInfo_CDC_Device_t TerminalHandle;
+extern TerminalStateEnum TerminalState;
+
+void TerminalInit(void);
+void TerminalTask(void);
+void TerminalTick(void);
+
+/*void TerminalSendHex(void* Buffer, uint16_t ByteCount);*/
+INLINE void TerminalSendByte(uint8_t Byte);
+void TerminalSendBlock(const void* Buffer, uint16_t ByteCount);
+
+INLINE void TerminalSendChar(char c);
+void TerminalSendString(const char* s);
+void TerminalSendStringP(const char* s);
+
+void EVENT_USB_Device_Connect(void);
+void EVENT_USB_Device_Disconnect(void);
+void EVENT_USB_Device_ConfigurationChanged(void);
+void EVENT_USB_Device_ControlRequest(void);
+
+INLINE void TerminalSendChar(char c) { CDC_Device_SendByte(&TerminalHandle, c); }
+INLINE void TerminalSendByte(uint8_t Byte) { CDC_Device_SendByte(&TerminalHandle, Byte); }
+
+#endif /* TERMINAL_H_ */
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/XModem.c b/RevE-light/Firmware/Chameleon-Mini/Terminal/XModem.c
new file mode 100644
index 0000000..6ea379f
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/XModem.c
@@ -0,0 +1,248 @@
+#include "XModem.h"
+#include "Terminal.h"
+
+#define BYTE_NAK 0x15
+#define BYTE_SOH 0x01
+#define BYTE_ACK 0x06
+#define BYTE_CAN 0x18
+#define BYTE_EOF 0x1A
+#define BYTE_EOT 0x04
+#define BYTE_ESC 0x1B
+
+#define XMODEM_BLOCK_SIZE 128
+
+#define RECV_INIT_TIMEOUT 5 /* #Ticks between sending of NAKs to the sender */
+#define RECV_INIT_COUNT 60 /* #Timeouts until receive failure */
+#define SEND_INIT_TIMEOUT 300 /* #Ticks waiting for NAKs from the receiver before failure */
+
+#define FIRST_FRAME_NUMBER 1
+#define CHECKSUM_INIT_VALUE 0
+
+static enum {
+ STATE_OFF,
+ STATE_RECEIVE_INIT,
+ STATE_RECEIVE_WAIT,
+ STATE_RECEIVE_FRAMENUM1,
+ STATE_RECEIVE_FRAMENUM2,
+ STATE_RECEIVE_DATA,
+ STATE_RECEIVE_PROCESS,
+ STATE_SEND_INIT,
+ STATE_SEND_WAIT,
+ STATE_SEND_EOT
+} State = STATE_OFF;
+
+static uint8_t CurrentFrameNumber;
+static uint8_t ReceivedFrameNumber;
+static uint8_t Checksum;
+static uint8_t RetryCount;
+static uint16_t RetryTimeout;
+static uint16_t BufferIdx;
+static uint32_t BlockAddress;
+
+static XModemCallbackType CallbackFunc;
+
+static uint8_t CalcChecksum(const void* Buffer, uint16_t ByteCount) {
+ uint8_t Checksum = CHECKSUM_INIT_VALUE;
+ uint8_t* DataPtr = (uint8_t*) Buffer;
+
+ while(ByteCount--) {
+ Checksum += *DataPtr++;
+ }
+
+ return Checksum;
+}
+
+void XModemReceive(XModemCallbackType TheCallbackFunc)
+{
+ State = STATE_RECEIVE_INIT;
+ CurrentFrameNumber = FIRST_FRAME_NUMBER;
+ RetryCount = RECV_INIT_COUNT;
+ RetryTimeout = RECV_INIT_TIMEOUT;
+ BlockAddress = 0;
+
+ CallbackFunc = TheCallbackFunc;
+}
+
+void XModemSend(XModemCallbackType TheCallbackFunc)
+{
+ State = STATE_SEND_INIT;
+ RetryTimeout = SEND_INIT_TIMEOUT;
+ BlockAddress = 0;
+
+ CallbackFunc = TheCallbackFunc;
+}
+
+bool XModemProcessByte(uint8_t Byte)
+{
+ switch(State) {
+ case STATE_RECEIVE_INIT:
+ case STATE_RECEIVE_WAIT:
+ if (Byte == BYTE_SOH) {
+ /* Next frame incoming */
+ BufferIdx = 0;
+ Checksum = CHECKSUM_INIT_VALUE;
+ State = STATE_RECEIVE_FRAMENUM1;
+ } else if (Byte == BYTE_EOT) {
+ /* Transmission finished */
+ TerminalSendByte(BYTE_ACK);
+ State = STATE_OFF;
+ } else if ( (Byte == BYTE_CAN) || (Byte == BYTE_ESC) ) {
+ /* Cancel transmission */
+ State = STATE_OFF;
+ } else {
+ /* Ignore other bytes */
+ }
+
+ break;
+
+ case STATE_RECEIVE_FRAMENUM1:
+ /* Store frame number */
+ ReceivedFrameNumber = Byte;
+ State = STATE_RECEIVE_FRAMENUM2;
+ break;
+
+ case STATE_RECEIVE_FRAMENUM2:
+ if (Byte == (255 - ReceivedFrameNumber)) {
+ /* frame-number check passed. */
+ State = STATE_RECEIVE_DATA;
+ } else {
+ /* Something went wrong. Try to recover by sending NAK */
+ TerminalSendByte(BYTE_NAK);
+ State = STATE_RECEIVE_WAIT;
+ }
+
+ break;
+
+ case STATE_RECEIVE_DATA:
+ /* Process byte and update checksum */
+ TerminalBuffer[BufferIdx++] = Byte;
+
+ if (BufferIdx == XMODEM_BLOCK_SIZE) {
+ /* Block full */
+ State = STATE_RECEIVE_PROCESS;
+ }
+
+ break;
+
+ case STATE_RECEIVE_PROCESS:
+ if (ReceivedFrameNumber == CurrentFrameNumber) {
+ /* This is the expected frame. Calculate and verify checksum */
+
+ if (CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE) == Byte) {
+ /* Checksum is valid. Pass received data to callback function */
+ if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) {
+ /* Proceed to next frame and send ACK */
+ CurrentFrameNumber++;
+ BlockAddress += XMODEM_BLOCK_SIZE;
+ TerminalSendChar(BYTE_ACK);
+ State = STATE_RECEIVE_WAIT;
+ } else {
+ /* Application signals to cancel the transmission */
+ TerminalSendByte(BYTE_CAN);
+ TerminalSendByte(BYTE_CAN);
+ State = STATE_OFF;
+ }
+ } else {
+ /* Data seems to be damaged */
+ TerminalSendByte(BYTE_NAK);
+ State = STATE_RECEIVE_WAIT;
+ }
+ } else if (ReceivedFrameNumber == (CurrentFrameNumber - 1)) {
+ /* This is a retransmission */
+ TerminalSendByte(BYTE_ACK);
+ State = STATE_RECEIVE_WAIT;
+ } else {
+ /* This frame is completely out of order. Just cancel */
+ TerminalSendByte(BYTE_CAN);
+ State = STATE_OFF;
+ }
+
+ break;
+
+ case STATE_SEND_INIT:
+ /* Start sending on NAK */
+ if (Byte == BYTE_NAK) {
+ CurrentFrameNumber = FIRST_FRAME_NUMBER - 1;
+ Byte = BYTE_ACK;
+ } else if (Byte == BYTE_ESC) {
+ State = STATE_OFF;
+ }
+
+ /* Fallthrough */
+
+ case STATE_SEND_WAIT:
+ if (Byte == BYTE_CAN) {
+ /* Cancel */
+ TerminalSendByte(BYTE_ACK);
+ State = STATE_OFF;
+ } else if (Byte == BYTE_ACK) {
+ /* Acknowledge. Proceed to next frame, get data and calc checksum */
+ CurrentFrameNumber++;
+
+ if (CallbackFunc(TerminalBuffer, BlockAddress, XMODEM_BLOCK_SIZE)) {
+ TerminalSendByte(BYTE_SOH);
+ TerminalSendByte(CurrentFrameNumber);
+ TerminalSendByte(255 - CurrentFrameNumber);
+ TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE);
+ TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE));
+
+ BlockAddress += XMODEM_BLOCK_SIZE;
+ } else {
+ TerminalSendByte(BYTE_EOT);
+ State = STATE_SEND_EOT;
+ }
+ } else if (Byte == BYTE_NAK){
+ /* Resend frame */
+ TerminalSendByte(BYTE_SOH);
+ TerminalSendByte(CurrentFrameNumber);
+ TerminalSendByte(255 - CurrentFrameNumber);
+ TerminalSendBlock(TerminalBuffer, XMODEM_BLOCK_SIZE);
+ TerminalSendByte(CalcChecksum(TerminalBuffer, XMODEM_BLOCK_SIZE));
+ } else {
+ /* Ignore other chars */
+ }
+
+ break;
+
+ case STATE_SEND_EOT:
+ /* Receive Ack */
+ State = STATE_OFF;
+ break;
+
+ default:
+ return false;
+ break;
+ }
+
+ return true;
+}
+
+void XModemTick(void)
+{
+ /* Timeouts go here */
+ switch(State) {
+ case STATE_RECEIVE_INIT:
+ if (RetryTimeout-- == 0) {
+ if (RetryCount-- > 0) {
+ /* Put out communication request */
+ TerminalSendChar(BYTE_NAK);
+ } else {
+ /* Just shut off after some time. */
+ State = STATE_OFF;
+ }
+
+ RetryTimeout = RECV_INIT_TIMEOUT;
+ }
+ break;
+
+ case STATE_SEND_INIT:
+ if (RetryTimeout-- == 0) {
+ /* Abort */
+ State = STATE_OFF;
+ }
+ break;
+
+ default:
+ break;
+ }
+}
diff --git a/RevE-light/Firmware/Chameleon-Mini/Terminal/XModem.h b/RevE-light/Firmware/Chameleon-Mini/Terminal/XModem.h
new file mode 100644
index 0000000..ac839b4
--- /dev/null
+++ b/RevE-light/Firmware/Chameleon-Mini/Terminal/XModem.h
@@ -0,0 +1,21 @@
+/*
+ * TerminalXModem.h
+ *
+ * Created on: 22.03.2013
+ * Author: skuser
+ */
+
+#ifndef XMODEM_H_
+#define XMODEM_H_
+
+#include "../Common.h"
+
+typedef bool (*XModemCallbackType) (void* ByteBuffer, uint32_t BlockAddress, uint16_t ByteCount);
+
+void XModemReceive(XModemCallbackType CallbackFunc);
+void XModemSend(XModemCallbackType CallbackFunc);
+
+bool XModemProcessByte(uint8_t Byte);
+void XModemTick(void);
+
+#endif /* TERMINALXMODEM_H_ */
diff --git a/RevE-light/Firmware/WARNING.txt b/RevE-light/Firmware/WARNING.txt
new file mode 100644
index 0000000..ae131bf
--- /dev/null
+++ b/RevE-light/Firmware/WARNING.txt
@@ -0,0 +1 @@
+WARNING: The files in this folder are our current development version. The hardware and software is not functional yet - so do not use it. We will not answer any support inquiry regarding this version at the moment.
\ No newline at end of file
diff --git a/RevE-light/README.md b/RevE-light/README.md
new file mode 100644
index 0000000..b665887
--- /dev/null
+++ b/RevE-light/README.md
@@ -0,0 +1,14 @@
+Chameleon-Mini RevE-light
+==============
+
+**WARNING:** The files in this folder are our current development version. *The hardware and software is not functional yet* - so do not use it. We will not answer any support inquiry regarding this version at the moment.
+
+Structure
+--------------------
+This part of the code repository contains
+
+* Doc: A doxygen documentation
+* Drivers: Chameleon drivers for Windows and Linux
+* Dumps: Dumps of different smartcards
+* Hardware: The layout and schematics of the RevE-light - *NOT FUNCTIONAL*
+* Firmware: The RevE-light firmware - *NOT FUNCTIONAL*
\ No newline at end of file
diff --git a/RevE-light/WARNING.txt b/RevE-light/WARNING.txt
new file mode 100644
index 0000000..ae131bf
--- /dev/null
+++ b/RevE-light/WARNING.txt
@@ -0,0 +1 @@
+WARNING: The files in this folder are our current development version. The hardware and software is not functional yet - so do not use it. We will not answer any support inquiry regarding this version at the moment.
\ No newline at end of file