Index: /firmware/FSC/readme.txt
===================================================================
--- /firmware/FSC/readme.txt	(revision 10094)
+++ /firmware/FSC/readme.txt	(revision 10094)
@@ -0,0 +1,18 @@
+FSC firmware:
+
+how to build.
+
+At the moment we work with AVR Studio 4 and WinAVR-20100110 under windows.
+
+c-sources in src/ should be added to a new gcc-avr project in AVR studio.
+
+as the target device choose: ATmega32
+as the CPU_frequency choose: 8000000
+
+the JTAG interface on the ATmega is not used as JTAG but normal I/O
+to the JTAG_EN fuse needs to be (un-)programmed.
+
+an external 8MHz quarz is used. programm the external clock fuse apropriately.
+
+
+DN 11.01.2011
Index: /firmware/FSC/src/FSC.c
===================================================================
--- /firmware/FSC/src/FSC.c	(revision 10094)
+++ /firmware/FSC/src/FSC.c	(revision 10094)
@@ -0,0 +1,174 @@
+//-----------------------------------------------------------------------------
+#include "typedefs.h"
+#include "application.h"
+#include "spare_outs.h"
+#include "spi_master.h"
+#include "ad7719_adc.h"    
+#include "usart.h"
+#include "macros.h"
+#include "interpol.h"
+#include "w5100_spi_interface.h"
+#include <avr/interrupt.h>
+#include <avr/wdt.h>
+#include <stdlib.h>
+
+#include "tests.h"
+//-----------------------------------------------------------------------------
+
+int main(void)
+{
+// U08 IDN_STR[] = "16ch Pt1000 logger; firmware version of 07.11.10. DN"; // Identity string
+
+	spare_outs_init(); //set spare out pin I/O modes
+  app_init();		  // Setup software modules
+  usart_init();		// Initialize serial interface   
+	spi_init(); 		// Initialize SPI interface as master
+	adc_init(); 		// Initialize AD7719 ADC as SPI slave 
+	//  usart_write_crlf();
+	//  usart_writeln_flash_str(IDN_STR); // Write string to USART interface
+	//  usart_write_crlf();
+
+  //  Enable interrupts
+  sei();              
+ 
+
+	// temperature muxer pins init:
+	// SA - pins
+	DDRA |= 0x3F; // set all SA-pins as outputs
+	
+
+	// voltage, current, humidity - muxer pins:
+	// SB - pins
+	DDRB |= 0x7F; // set all SB - pins as outputs
+	
+	// SB - muxer test
+	DDRA |= 1<<PA6 ; // set D0-0 lina as output. for tests only !!!
+	PORTA |= 1<<PA6; // set D0-0 line high. for tests only !!!
+
+
+
+// Main loop
+//float temperature;
+float resistance;
+BOOL heartbeat_enable = TRUE;
+
+U08 SA_mux_val = 0;
+//U08 SB_mx_val = 0;
+while (TRUE)
+	 {
+	 	// this heartbeat shows how long one single run of this while loop takes
+		// measure with a scope.
+		if (heartbeat_enable) PORTB ^= (1<<PB3); // toggle Out2_spare --> heartbeat
+
+		// if USART data arrives. i.e. data via USB
+		// the usart_rx_ready flag is set TRUE
+		// now process the incoming data which is stored in 
+		// U08 usart_rx_buffer[USART_RX_BUFFER_SIZE]
+		// and tell the USART interface, it may receive new data
+		// by setting the usart_rx_ready flag FALSE again
+		++SA_mux_val;
+		PORTA |= (SA_mux_val & 0x3F); 
+		
+		usart_write_str((pU08)"\tSA:");
+		usart_write_U08(SA_mux_val,2);
+		usart_write_str((pU08)"\t");
+		_delay_us(200);
+		
+				
+				if(ADC_IS_READY()) 
+	    	{		
+		   		startconv();							//Start a new A/D Conversion
+		    	//temp = 	readandsendtemp();
+					//adcword = getadc();
+					resistance = getresistance();
+					//temperature = gettemp();
+					usart_write_str((pU08)"R:");
+					usart_write_float(resistance,3,4);
+					usart_write_str((pU08)"\t");	
+				}
+				if(ADC_IS_READY()) 
+	    	{		
+		   		startconv();							//Start a new A/D Conversion
+		    	//temp = 	readandsendtemp();
+					//adcword = getadc();
+					resistance = getresistance();
+					//temperature = gettemp();
+					usart_write_str((pU08)"R:");
+					usart_write_float(resistance,3,4);
+					usart_write_str((pU08)"\n");	
+				}
+
+		
+	/*	
+		if ( usart_rx_ready == TRUE )
+		{
+			//understand what it means and react
+			
+			switch (usart_rx_buffer[0])
+			{
+				
+				case 'h':
+				{
+					// toggle the heartbeat mode on or off.
+					heartbeat_enable = !heartbeat_enable;
+					break;
+				}
+				case 'a':
+				{
+					// conduct adc - AD7719 SPI interface test
+					
+					break;
+				}
+				case 'e':
+				{
+					// conduct ethernet module SPI interface test
+					strtol((char*) usart_rx_buffer+1, NULL, 0);
+					break;
+				}
+
+				default:
+				{
+					usart_write_str((pU08)"? you wrote: ");
+					usart_write_str((pU08)usart_rx_buffer);
+					usart_write_str((pU08)"\n");
+					break;
+				}
+			}
+			
+			heartbeat_enable = !heartbeat_enable;
+			usart_rx_ready = FALSE;
+		}
+*/
+// das ist ein paar schritte zu früh.
+// erstmal müssen die interfaces getestet werden.
+/*
+
+		for (U08 i = 0; i<16; i++)
+	  	{ 
+			
+	   		if((~PIND) & 0x08)  // PD4 is #ADC_RDY input. Inverted logic! if PD4=0 this evaluates to true					
+	    	{		
+				PORTA = (PORTA & 0xF0) | ((i) & 0x0F); 	// switch muxer
+		   		startconv();							//Start a new A/D Conversion
+		    	//temp = 	readandsendtemp();
+				//adcword = getadc();
+				//resistance = getresistance();
+				temperature = gettemp();
+				usart_write_float(temperature,2,4);
+				usart_write_str((pU08)"\t");
+
+			} // end of if adc ready
+			else
+			{
+			i--;
+			}
+		} // end of for loop over 16 channels
+		usart_write_crlf();
+
+*/
+
+ 	}	// end of infinite while loop
+} // end of main()
+
+
+
Index: /firmware/FSC/src/ad7719_adc.c
===================================================================
--- /firmware/FSC/src/ad7719_adc.c	(revision 10094)
+++ /firmware/FSC/src/ad7719_adc.c	(revision 10094)
@@ -0,0 +1,122 @@
+//-----------------------------------------------------------------------------
+
+#include "ad7719_adc.h"       
+#include "spi_master.h"    
+
+//-----------------------------------------------------------------------------
+
+void adc_init(void)
+{
+
+  SET_BIT(ADC_DDR,DDD4);		// ADC_RST is uP Output
+  CLR_BIT(ADC_PRT,ADC_RST);		// Reset ADC (active low) 	
+  SET_BIT(ADC_PRT,ADC_RST);		// Stop Reset ADC
+
+
+	//Init Configure and Initialize AD7719
+	//http://designtools.analog.com/dt/adc/codegen/ad7719.html 
+
+  U8  IOCON1 = 0xC3;	// power switches P1 and P2 switch to PWRGND. I-sources I1 and I2 are switched on.
+  U8  IOCON2 = 0x08;	// 0x08 makes no sense... P4 is set HIGH, but is no output.
+//  U8  FILTER = 0x45;	//0x45 global use 50Hz = -66dB and 60Hz = -117dB Rejectjon
+  U8  FILTER = 0x52;	//0x52 euro use 50Hz = -171dB and 60Hz = -58dB Rejectjon Updaterate = 4Hz
+
+  U8  AD1CON = 0x51;	
+	// ARN bit is set->AUS ADC range is: +-REFIN2
+	// ACHo and ACH2 are set --> not defined. ???
+	// AD1EN is not set. so aux ADC is not enabled anyway.
+
+  U8  AD0CON = 0x8E;
+  	// AD0EN is set. main ADC operates according to content of mode register
+	// U/#B is set. unipolar encoding. zero is 0x000000. both full scales will be 0xFFFFFF
+	// RN2..0 = 1 ,1 ,0 --> multiplication factor 8, maybe ??
+
+  U8  MODE   = 0x02;	// single conversion
+
+	// ADC communiaction works like this:
+	// a write operation to the COM register takes place - telling the device what up next.
+	// a write or read operation to another register takes place
+	// COM register bits have the following meaning:
+	//
+	// |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  0  |
+	// |#WEN |R/#W | zero| zero|  A3 |  A2 |  A1 |  A0 |
+	//
+	// #WEN (inversed write enable) must be zero inorder to clock more bits into the SPI interface.
+	// R/#W (read / not write) must be zero if the next operation will be a WRITE. one if the next is READ.
+	// A3-A0 denote the address of the next register.
+
+  const U8 WR_TO_IOCON = 0x07;
+  const U8 WR_TO_FILTER = 0x04;
+  const U8 WR_TO_AD1CON = 0x03;
+  const U8 WR_TO_AD0CON = 0x02;
+  const U8 WR_TO_MODE = 0x01;
+
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(WR_TO_IOCON);     	// Next Operation is write to IOCON1 and IOCON2  Start SPI
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(IOCON1);  	// Write to IOCON1 
+  spi_transfer_byte(IOCON2);  	// Write to IOCON2 
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(WR_TO_FILTER);     	// Next Operation is write to FILTER  Start SPI
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+ 
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(FILTER);  	// Write to FILTER 
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(WR_TO_AD1CON);     	// Next Operation is write to AD1CON  Start SPI
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+ 
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(AD1CON);  	// Write to AD1CON
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(WR_TO_AD0CON);     	// Next Operation is write to AD0CON  Start SPI
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+ 
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(AD0CON);  	// Write to AD0CON
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(WR_TO_MODE);     	// Next Operation is write to MODE Start SPI
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+ 
+  CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+  spi_transfer_byte(MODE);  	// Write to MODE
+  SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+} 
+          
+ void startconv(void)
+  {
+    U8 COM = 0x01;
+	U8 SERIAL = 0x02;
+  		  CLR_BIT(PORTD,SPI_AD_CS);       // Set CS low
+    	  spi_transfer_byte(COM);        // Next Operation is write to Mode Register
+  		  spi_transfer_byte(SERIAL);	 // Start new A/D conversion
+		  SET_BIT(PORTD,SPI_AD_CS);  
+		  COM = 0x45;
+  		  CLR_BIT(PORTD,SPI_AD_CS);       // Set CS low
+    	  spi_transfer_byte(COM);        // Next Operation is read from Main ADC Data Register
+  		  SET_BIT(PORTD,SPI_AD_CS);        // Set CS high
+  }
+
+ U32 read_adc(void)
+ { CLR_BIT(PORTD,SPI_AD_CS);  	// Set CS low
+   U32 value=0; 					// actually a 24bit value is returned
+   value |= spi_transfer_byte(0) ;
+   value =value<<8;
+   value |= spi_transfer_byte(0) ;
+   value =value<<8;
+   value |= spi_transfer_byte(0) ;
+   SET_BIT(PORTD,SPI_AD_CS);	// Set CS high
+   return value;                                                                                                 
+ }   
+  
+  
Index: /firmware/FSC/src/ad7719_adc.h
===================================================================
--- /firmware/FSC/src/ad7719_adc.h	(revision 10094)
+++ /firmware/FSC/src/ad7719_adc.h	(revision 10094)
@@ -0,0 +1,23 @@
+#ifndef __AD7719_ADC_H
+#define __AD7719_ADC_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "application.h"
+#include "num_conversion.h"
+//-----------------------------------------------------------------------------
+// Bit Definitions
+#define ADC_RDY PD6
+#define ADC_RST PD7
+#define ADC_IS_READY() !(PIND & PD6) // TRUE if PD6=0 AD_RDY is inverted logic.
+
+// Port Definitions
+#define ADC_PRT PORTD
+#define ADC_DDR DDRD
+#define ADC_PIN PIND
+
+void adc_init(void);
+void startconv(void);
+U32 read_adc(void);
+//-----------------------------------------------------------------------------
+#endif
Index: /firmware/FSC/src/application.c
===================================================================
--- /firmware/FSC/src/application.c	(revision 10094)
+++ /firmware/FSC/src/application.c	(revision 10094)
@@ -0,0 +1,155 @@
+//-----------------------------------------------------------------------------
+
+#include "application.h"
+ #include <avr/wdt.h> 
+
+
+//-----------------------------------------------------------------------------
+
+volatile U08 app_reset_source;
+//-----------------------------------------------------------------------------
+
+void app_init(void)
+{
+  app_reset_source = MCUSR; // Save last reset source
+  MCUSR = 0x00; // Clear reset source for next reset cycle
+
+  // The watchdog timer is disabled by default ("startup.asm")
+#ifdef USE_WATCHDOG
+ WDTCSR = WDTOE | (1 << WDE); // Enable watchdog reset (~16ms)
+#endif
+  
+#ifndef F_CPU
+#define F_CPU 8000000UL	//cpu frequency
+#endif
+
+//#ifdef (F_CPU == 16000000UL)
+/*#else
+  #warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz
+  #error *** Invalid clock selected! ***
+#endif*/
+ // Tell the user the operating frequency
+//#warning *** Compiling for DF_CPU Hz
+/*
+  // Set selected CPU clock
+#if (_MCU_CLOCK_FREQUENCY_ == 16000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 0; // Set clock prescaler to division by 1 (16MHz clock with 16MHz crystal)
+#elif (_MCU_CLOCK_FREQUENCY_ == 8000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 1; // Set clock prescaler to division by 2 (8MHz clock with 16MHz crystal)
+#elif (_MCU_CLOCK_FREQUENCY_ == 4000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 2; // Set clock prescaler to division by 4 (4MHz clock with 16MHz crystal)
+#elif (_MCU_CLOCK_FREQUENCY_ == 2000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 3; // Set clock prescaler to division by 8 (2MHz clock with 16MHz crystal)
+#elif (_MCU_CLOCK_FREQUENCY_ == 1000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 4; // Set clock prescaler to division by 16 (1MHz clock with 16MHz crystal)
+#else
+  #warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz
+  #error *** Invalid clock selected! ***
+#endif
+
+  // Tell the user the operating frequency
+#warning *** Compiling for _MCU_CLOCK_FREQUENCY_ Hz
+
+*/ 
+
+/* (ATmega32 has no prescaler)
+  // Set selected CPU clock
+#if (F_CPU == 16000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 0; // Set clock prescaler to division by 1 (16MHz clock with 16MHz crystal)
+#elif (F_CPU == 8000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 1; // Set clock prescaler to division by 2 (8MHz clock with 16MHz crystal)
+#elif (F_CPU == 4000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 2; // Set clock prescaler to division by 4 (4MHz clock with 16MHz crystal)
+#elif (F_CPU == 2000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 3; // Set clock prescaler to division by 8 (2MHz clock with 16MHz crystal)
+#elif (F_CPU == 1000000)
+  CLKPR = CLKPCE; // Enable clock prescaler by writing 0x80 to CLKPR
+  CLKPR = 4; // Set clock prescaler to division by 16 (1MHz clock with 16MHz crystal)
+#else
+  #warning *** Compiling for F_CPU Hz
+  #error *** Invalid clock selected! ***
+#endif
+
+
+
+  // Tell the user the operating frequency
+#warning *** Compiling for F_CPU Hz
+
+ 
+  // Turn off unused modules for this application
+  PRR =
+  (
+#ifndef USE_TWI
+    TWEN // I2C module
+  #warning *** Module "TWI" not enabled!
+#endif
+
+ (ATmega32 Can't disable TIMER modules)
+#ifndef USE_TIMER2
+    | PRTIM2 // Timer2
+  #warning *** Module "TIMER2" not enabled!
+#endif
+#ifndef USE_TIMER1
+    | PRTIM1 // Timer1
+  #warning *** Module "TIMER1" not enabled!
+#endif
+#ifndef USE_TIMER0
+    | PRTIM0 // Timer0
+  #warning *** Module "TIMER0" not enabled!
+#endif
+
+#ifndef USE_USART0
+    | PRUSART0 // USART0
+  #warning *** Module "USART0" not enabled!
+#endif
+
+#ifndef USE_SPI
+    | SPE // SPI
+  #warning *** Module "SPI" not enabled!
+#endif
+
+#ifndef USE_ADC
+    | ADEN // ADC
+  #warning *** Module "ADC" not enabled!
+#endif
+  );
+
+#ifndef USE_ACO // Analog comparator
+  ACSR = ACME;
+  #warning *** Module "ACO" not enabled!
+#endif
+
+  PORTC |= PC6; // Enable pullup for PC6_RESET
+
+  // Initialize switches S1, S2 and S3
+  //S1_INIT(); // Set S1 pin to input
+  //S2_INIT(); // Set S2 pin to input
+  //S3_INIT(); // Set S3 pin to input
+*/
+}
+
+
+
+//-----------------------------------------------------------------------------
+
+void app_set_watchdog_prescaler(tWDT_PRESCALE wdt_prescale) // Set watchdog prescale
+{
+  U08 sreg_backup = SREG; // Copy status register to variable
+  U08 wdtcsr_value = WDE + wdt_prescale; // Set new prescale value to variable
+
+  cli(); // Disable interrups
+  wdt_reset(); // Reset watchdog
+
+  WDTCR |= (1 << WDTOE) | (1 << WDE); // Unlock register access, 4 cycles to store new value
+  WDTCR = wdtcsr_value; // Set new watchdog prescaler
+  SREG = sreg_backup; // Restore status register
+}
Index: /firmware/FSC/src/application.h
===================================================================
--- /firmware/FSC/src/application.h	(revision 10094)
+++ /firmware/FSC/src/application.h	(revision 10094)
@@ -0,0 +1,45 @@
+#ifndef __APPLICATION_H
+#define __APPLICATION_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+//-----------------------------------------------------------------------------
+
+//#define F_CPU (_MCU_CLOCK_FREQUENCY_)
+#define F_CPU_KHZ (F_CPU / 1000)
+#define F_CPU_MHZ (F_CPU_KHZ / 1000)
+//-----------------------------------------------------------------------------
+
+// Definitions of hardware modules used by application
+// Comment out all unused hardware modules
+
+//#define USE_TWI // I2C module used?
+//#define USE_TIMER2 // Timer2 used?
+//#define USE_TIMER1 // Timer1 used?
+//#define USE_TIMER0 // Timer0 used?
+//#define USE_SPI // SPI used?
+//#define USE_USART // USART0 used?
+//#define USE_ADC // ADC used?
+//#define USE_ACO // Analog Comparator used?
+//#define USE_WATCHDOG // Comment out to disable watchdog timer
+//-----------------------------------------------------------------------------
+
+// USART0 definitions
+#define USART_RX_BUFFER_SIZE 64 // Receive buffer size
+
+#define USART_BAUDRATE 38400 // USART baudrate original
+
+#define USART_USE_TX // Transmitter used?
+#define USART_USE_RX // Receiver used?
+#define USART_USE_RX_IRQ // RX interrupt used?
+#define USART_USE_UPPERCASE // Convert received chars to uppercase?
+//-----------------------------------------------------------------------------
+
+extern volatile U08 app_reset_source;
+//-----------------------------------------------------------------------------
+
+void app_init(void); // Initialize application
+void app_set_watchdog_prescaler(tWDT_PRESCALE wdt_prescale); // Set watchdog prescale
+//-----------------------------------------------------------------------------
+
+#endif
Index: /firmware/FSC/src/interpol.c
===================================================================
--- /firmware/FSC/src/interpol.c	(revision 10094)
+++ /firmware/FSC/src/interpol.c	(revision 10094)
@@ -0,0 +1,303 @@
+//-----------------------------------------------------------------------------
+
+#include "interpol.h"
+#include "usart.h"
+#include "ad7719_adc.h" 
+//#include "typedefs.h"
+//#include "application.h"
+#include "num_conversion.h"
+//-----------------------------------------------------------------------------
+/*
+Temperatur Sensoren von IST nach DIN60751, Kl.B 
+Messfehler +/- 0.30+0.005*|t|
+
+R(t) = R0(1 + At + Bt^2 + C(t-100)t^3)  t = [-200, 0]°C
+R(t) = R0(1 + At + Bt^2)				t = [0, 850]°C
+
+A = 3.9083*10^-3[°C^-1]
+B = -5.775*10^-7[°C^-2]
+C = -4.183*10^-12[°C^-4]
+
+Strom durch R ist konstant 400uA
+Intervallweise lineare Interpolation der Funktion R(t) mit MATLAB polyfit
+adcword = 13107200 * u(temperatur)
+*/
+ U08 space_STR[] = "  |";
+ U08 OoR_STR[] = "  OoR  |";
+
+
+
+ float gettemp(void)
+ {
+
+  
+  U8  temprange = 17;
+  U32 adcword=0;
+  float temp=-3.14; // should be initialized in a proper way, but I dont know how :-)
+  const U32 min = 0x404054;
+  const U32 max = 0x8CAF50;
+  const U32 s	= 0x4C6F0;		//(max-min)/16 = s(lice)
+  	
+  adcword = read_adc();
+
+ if  (adcword >= (min + 8*s))
+   {
+     if  (adcword >= (min + 12*s))
+	   {
+	     if  (adcword >= (min + 14*s))
+		   {
+			 if   (adcword >= (min + 15*s)) 
+			   { 
+			     if (adcword < max)
+				   {
+		            temprange = 16;
+				   }
+			   }
+			 else
+			   {
+				 temprange = 15;
+			   }
+		   }
+		 else
+		   {
+		      if  (adcword >= (min + 13*s))
+			    {
+				  temprange = 14;
+				}
+			  else
+			    {
+				  temprange = 13;
+				}
+		   }   
+	   }
+	 else
+	   {
+	     if  (adcword >= (min + 10*s))
+		   {
+			 if  (adcword >= (min + 11*s))
+			   {
+				 temprange = 12;
+			   }
+			 else
+			   {
+				 temprange = 11;
+			   }
+		   }
+		 else
+		   {
+		      if  (adcword >= (min + 9*s))
+			    {
+				  temprange = 10;
+				}
+			  else
+			    {
+				  temprange = 9;
+				}
+		   }   
+	   }
+   } 
+ else
+ {
+     if  (adcword >= (min + 4*s))
+	   {
+	     if  (adcword >= (min + 6*s))
+		   {
+			 if  (adcword >= (min + 7*s))
+			   {
+				 temprange = 8;
+			   }
+			 else
+			   {
+				 temprange = 7;
+			   }
+		   }
+		 else
+		   {
+		      if  (adcword >= (min + 5*s))
+			    {
+				  temprange = 6;
+				}
+			  else
+			    {
+				  temprange = 5;
+				}
+		   }   
+	   }
+	 else
+	   {
+	     if  (adcword >= (min + 2*s))
+		   {
+			 if  (adcword >= (min + 3*s))
+			   {
+				 temprange = 4;
+			   }
+			 else
+			   {
+				 temprange = 3;
+			   }
+		   }
+		 else
+		   {
+		      if  (adcword >= (min + s))
+			    {
+				  temprange = 2;
+				}
+			  else
+			    { 
+				  if  (adcword > min)
+				    {
+				      temprange = 1;
+ 					}
+				}
+		   }   
+	   }
+   } 
+
+
+ switch (temprange)
+  {
+    case 1:{ // Temp. Range [-50°C , -34.375°C[
+      temp = ((float)adcword / 20764.727846 - 252.7721); 		//20764.727846 - 252.7721
+	  }
+    break;
+
+    case 2:{ // Temp. Range [-34.375°C , -18.75°C[
+      temp = ((float)adcword / 20658.049789 - 253.8995);		//20658.049789 - 253.8995
+	  }
+    break;
+
+    case 3:{ // Temp. Range [-18.75°C , -3.125°C[		
+      temp = ((float)adcword / 20557.997603 - 255.0436);		//20557.997603 - 255.0436
+	  }
+    break;
+
+    case 4:{ // Temp. Range [-3.125°C , 12.5°C]
+      temp = ((float)adcword / 20462.362624 - 256.2209); 		//20462.362624 - 256.2209
+	  }
+    break;
+
+    case 5:{ // Temp. Range [12.5°C , 28.125°C]
+      temp = ((float)adcword / 20367.745024 - 257.4692);		//20367.745024 - 257.4692
+	  }
+    break;
+	
+    case 6:{ // Temp. Range [28.125°C , 43.75°C]
+      temp = ((float)adcword / 20273.127424 - 258.8021);		//20273.127424 - 258.8021
+	  }
+    break;
+	
+    case 7:{ // Temp. Range [43.75°C , 59.375°C]
+      temp = ((float)adcword / 20178.509824 - 260.2208);		//20178.509824 - 260.2208
+	  }
+    break;
+	
+    case 8:{ // Temp. Range [59.375°C , 75°C]
+      temp = ((float)adcword / 20083.892224 - 261.7265);		//20083.892224 - 261.7265
+	  }
+    break;
+	
+    case 9:{ // Temp. Range [75°C , 90.625°C]
+      temp = ((float)adcword / 19989.274624 - 263.3203);		//19989.274624 - 263.3203
+	  }
+    break;
+	
+    case 10:{ // Temp. Range [90.625°C , 106.25°C]
+      temp = ((float)adcword / 19894.657024 - 265.0037);		//19894.657024 - 265.0037
+	  }
+    break;
+	
+    case 11:{ // Temp. Range [106.25°C , 121.875°C]
+      temp = ((float)adcword / 19800.039424 - 266.7778);		//19800.039424 - 266.7778
+	  }
+    break;
+	
+    case 12:{ // Temp. Range [121.875°C , 137.5°C]
+      temp = ((float)adcword / 19705.421824 - 268.6439);		//19705.421824 - 268.6439
+	  }
+    break;
+	
+    case 13:{ // Temp. Range [137.5°C , 153.125°C]
+      temp = ((float)adcword / 19610.804224 - 270.6035);		//19610.804224 - 270.6035
+	  }
+    break;
+	
+    case 14:{ // Temp. Range [153.125°C , 168.75°C]
+      temp = ((float)adcword / 19516.186624 - 272.6578);		//19516.186624 - 272.6578
+	  }
+    break;
+	
+    case 15:{ // Temp. Range [168.75°C , 184.375°C]
+      temp = ((float)adcword / 19421.569024 - 274.8082);		//19421.569024 - 274.8082
+	  }
+    break;
+	
+    case 16:{ // Temp. Range [184.375°C , 200°C]
+      temp = ((float)adcword / 19326.951424 - 277.0562);		//19326.951424 - 277.0562
+	  }
+    break;
+    default:{ // Temp. Range beyond [-50C , 200C]
+	  PORTC = (PORTC | 0x04);
+	  }
+  }// end of switch case statement
+  return temp;
+
+ }
+
+ void readandsendpress(void)
+ {
+  U32 adcword=0;
+  float press;
+
+  adcword = read_adc();
+
+ if ( (adcword > 0x253332) && (adcword < 0xF80000) ) // Press. Range is [0Bar , 250Bar]
+   {
+    press = ((float)adcword / (62 * 836.658790402)) - 63.0091; // 62 Ohm
+	usart_write_float(press,2,5);
+	usart_write_flash_str(space_STR);
+   } 
+ else
+   {
+	usart_write_flash_str(OoR_STR);  // Press. is beyond [0Bar , 250Bar]
+    PORTC = (PORTC | 0x04);
+   }
+
+ }
+
+
+/*
+Temperatur Sensoren von IST nach DIN60751, Kl.B 
+Messfehler +/- 0.30+0.005*|t|
+
+R(t) = R0(1 + At + Bt^2 + C(t-100)t^3)  t = [-200, 0]°C
+R(t) = R0(1 + At + Bt^2)				t = [0, 850]°C
+
+A = 3.9083*10^-3[°C^-1]
+B = -5.775*10^-7[°C^-2]
+C = -4.183*10^-12[°C^-4]
+
+Strom durch R ist konstant 400uA
+Messung ist ratiometrisch bezogen auf Referenzwiderstand an ADC Pin5 (REFIN-) und Pin6 (REFIN+)
+Referenzwiderstand ist ca. 6.28kOhm.
+ADC hat internes gain von 2.
+
+*/
+
+float getresistance(void)
+{
+  
+  U32 adcword=0;
+  float resistance;
+  const float R_REF=6.28; // kilo-ohms	
+  adcword = read_adc();
+  U32 fullscale = 16777215L; //2^24 -1
+  
+  resistance = ((float)adcword / (float)fullscale) /2.0 * R_REF; // divide through 2.0 because of PGA in ADC.
+
+  return resistance; // in kilo-ohms
+}
+
+U32 getadc(void) 
+{
+return read_adc();
+}
Index: /firmware/FSC/src/interpol.h
===================================================================
--- /firmware/FSC/src/interpol.h	(revision 10094)
+++ /firmware/FSC/src/interpol.h	(revision 10094)
@@ -0,0 +1,18 @@
+#ifndef __INTERPOL_H
+#define __INTERPOL_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "application.h"
+#include "num_conversion.h"
+//-----------------------------------------------------------------------------
+
+// function prototype
+
+
+ float gettemp(void);
+ void readandsendpress(void);
+ float getresistance(void);
+ U32 getadc(void);
+//-----------------------------------------------------------------------------
+#endif
Index: /firmware/FSC/src/macros.h
===================================================================
--- /firmware/FSC/src/macros.h	(revision 10094)
+++ /firmware/FSC/src/macros.h	(revision 10094)
@@ -0,0 +1,21 @@
+#ifndef __MACROS_H
+#define __MACROS_H
+//-----------------------------------------------------------------------------
+
+#define SET_BIT(byte,bit) (byte |= (1 << bit)) // Set bit in byte
+#define CLR_BIT(byte,bit) (byte &= ~(1 << bit)) // Clear bit in byte
+#define TGL_BIT(byte,bit) (byte ^= (1 << bit)) // Toggle bit in byte
+
+#define IS_SET(reg,bit) (reg & bit) // TRUE if bit = 1
+#define IS_CLR(reg,bit) !(reg & bit) // TRUE if bit = 0
+
+#define BIT(x) (1 << (x)) // Define bit value
+#define HI(x) ((x) >> 8) // Highbyte of 16-bit value
+
+#define ABS(x) ((x >= 0) ? x : -x) // Absolute value of x
+
+#define HI_HEX(x) ("0123456789ABCDEF" [x >> 4]) // Create hex of high nibble
+#define LO_HEX(x) ("0123456789ABCDEF" [x & 0x0F]) // Create hex of low nibble
+//-----------------------------------------------------------------------------
+
+#endif
Index: /firmware/FSC/src/num_conversion.c
===================================================================
--- /firmware/FSC/src/num_conversion.c	(revision 10094)
+++ /firmware/FSC/src/num_conversion.c	(revision 10094)
@@ -0,0 +1,371 @@
+//-----------------------------------------------------------------------------
+
+#include "num_conversion.h"
+//-----------------------------------------------------------------------------
+
+//__flash U08 NC_HEX_ARRAY[] = "0123456789ABCDEF";
+U08 NC_HEX_ARRAY[] = "0123456789ABCDEF";
+//-----------------------------------------------------------------------------
+
+U08 nc_buffer[NC_BUFFER_LENGTH]; // Conversion buffer
+U08 nc_format_buffer[NC_BUFFER_LENGTH]; // Format buffer
+
+static U08 nc_int_digits[8];
+static U08 nc_dec_digits[6];
+//-----------------------------------------------------------------------------
+
+pU08 nc_format(pU08 source_ptr,U08 digits)
+{
+  U08 len = strlen((const char *)source_ptr);
+  pU08 dest_ptr = (pU08)&nc_format_buffer;
+
+  // Fillup loop
+  while (digits-- > len)
+  {
+    *dest_ptr++ = NC_FILL_CHAR;
+  }
+
+  // Copy loop
+  while (len--)
+  {
+    *dest_ptr++ = *source_ptr++;
+  }
+
+  *dest_ptr = 0; // Terminate format string
+
+  return (pU08)&nc_format_buffer;
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U08_to_str(U08 value,U08 digits)
+{
+  pU08 pstr = nc_buffer;
+
+  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
+  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
+  *pstr++ = ('0' + (value % 10));
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_S08_to_str(S08 signed_value,U08 digits)
+{
+  pU08 pstr = nc_buffer;
+  U08 value;
+
+  if (signed_value < 0)
+  {
+    *pstr++ = '-';
+    value = -signed_value;
+  }
+  else
+  {
+    value = signed_value;
+  }
+
+  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
+  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
+  *pstr++ = ('0' + (value % 10));
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U08_to_hex(U08 value)
+{
+  pU08 pstr = nc_buffer;
+
+  *pstr++ = NC_HEX_ARRAY[value >> 4];
+  *pstr++ = NC_HEX_ARRAY[value & 0x0F];
+  *pstr = 0;
+
+  return (nc_buffer);
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U08_to_bin(U08 value)
+{
+  pU08 pstr = nc_buffer;
+  U08 n;
+
+  for (n = 7; n < 8; n--)
+  {
+    if (value & (1 << n))
+    {
+      *pstr++ = '1';
+    }
+    else
+    {
+      *pstr++ = '0';
+    }
+  }
+
+  *pstr = 0;
+
+  return (nc_buffer);
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U16_to_str(U16 value,U08 digits)
+{
+  pU08 pstr = nc_buffer;
+
+  if (value >= 10000) *pstr++ = ('0' + (value / 10000));
+  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
+  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
+  if (value >= 10)*pstr++ = ('0' + (value % 100 / 10));
+  *pstr++ = ('0' + (value % 10));
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_S16_to_str(S16 signed_value,U08 digits)
+{
+  pU08 pstr = nc_buffer;
+  U16 value;
+
+  if (signed_value < 0)
+  {
+    *pstr++ = '-';
+    value = -signed_value;
+  }
+  else
+  {
+    value = signed_value;
+  }
+
+  if (value >= 10000) *pstr++ = ('0' + (value / 10000));
+  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
+  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
+  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
+  *pstr++ = ('0' + (value % 10));
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U16_to_hex(U16 value)
+{
+  pU08 pstr = nc_buffer;
+  tMEM16 data;
+
+  data.word = value;
+
+  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) >> 4];
+  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) & 0x0F];
+
+  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) >> 4];
+  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) & 0x0F];
+
+  *pstr = 0;
+
+  return (nc_buffer);
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U32_to_str(U32 value,U08 digits)
+{
+  pU08 pstr = nc_buffer;
+
+  if (value >= 1000000000) *pstr++ = ('0' + (value / 1000000000));
+  if (value >= 100000000) *pstr++ = ('0' + (value % 1000000000 / 100000000));
+  if (value >= 10000000) *pstr++ = ('0' + (value % 100000000 / 10000000));
+  if (value >= 1000000) *pstr++ = ('0' + (value % 10000000 / 1000000));
+  if (value >= 100000) *pstr++ = ('0' + (value % 1000000 / 100000));
+  if (value >= 10000) *pstr++ = ('0' + (value % 100000 / 10000));
+  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
+  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
+  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
+
+  *pstr++ = ('0' + (value % 10));
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_S32_to_str(S32 signed_value,U08 digits)
+{
+  pU08 pstr = nc_buffer;
+  U32 value;
+
+  if (signed_value < 0)
+  {
+    *pstr++ = '-';
+    value = -signed_value;
+  }
+  else
+  {
+    value = signed_value;
+  }
+
+  if (value >= 1000000000) *pstr++ = ('0' + (value / 1000000000));
+  if (value >= 100000000) *pstr++ = ('0' + (value % 1000000000 / 100000000));
+  if (value >= 10000000) *pstr++ = ('0' + (value % 100000000 / 10000000));
+  if (value >= 1000000) *pstr++ = ('0' + (value % 10000000 / 1000000));
+  if (value >= 100000) *pstr++ = ('0' + (value % 1000000 / 100000));
+  if (value >= 10000) *pstr++ = ('0' + (value % 100000 / 10000));
+  if (value >= 1000) *pstr++ = ('0' + (value % 10000 / 1000));
+  if (value >= 100) *pstr++ = ('0' + (value % 1000 / 100));
+  if (value >= 10) *pstr++ = ('0' + (value % 100 / 10));
+
+  *pstr++ = ('0' + (value % 10));
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_U32_to_hex(U32 value)
+{
+  pU08 pstr = nc_buffer;
+  tMEM32 data;
+
+  data.dword = value;
+
+  *pstr++ = NC_HEX_ARRAY[(data.byte[3]) >> 4];
+  *pstr++ = NC_HEX_ARRAY[(data.byte[3]) & 0x0F];
+
+  *pstr++ = NC_HEX_ARRAY[(data.byte[2]) >> 4];
+  *pstr++ = NC_HEX_ARRAY[(data.byte[2]) & 0x0F];
+
+  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) >> 4];
+  *pstr++ = NC_HEX_ARRAY[(data.byte[1]) & 0x0F];
+
+  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) >> 4];
+  *pstr++ = NC_HEX_ARRAY[(data.byte[0]) & 0x0F];
+
+  *pstr = 0;
+
+  return (nc_buffer);
+}
+//-----------------------------------------------------------------------------
+
+pU08 nc_float_to_str(float value,U08 decimals,U08 digits)
+{
+  S08 n;
+  U08 int_count;
+  U08 dec_count;
+  float dec_part;
+  U32 int_part;
+  pU08 pstr = nc_buffer;
+
+  if (decimals > 5)
+  {
+    decimals = 5;
+  }
+
+  if (value < 0.0)
+  {
+    *pstr++ = '-';
+    value = -value;
+  }
+
+  int_part = value;
+  dec_part = value - int_part;
+  int_count = 0;
+  dec_count = 0;
+
+  if (int_part == 0)
+  {
+    *pstr++ = '0';
+  }
+
+  while (int_part > 0)
+  {
+    nc_int_digits[int_count] = int_part % 10;
+    int_part = int_part - nc_int_digits[int_count];
+
+    if (int_part > 0)
+    {
+      int_part = int_part / 10;
+    }
+
+    int_count++; // go to the next digit
+  }
+
+  while (dec_count < decimals)
+  {
+    dec_part = dec_part * 10.0;
+    nc_dec_digits[dec_count] = dec_part;
+
+    if (nc_dec_digits[dec_count] > 0)
+    {
+      dec_part = dec_part - nc_dec_digits[dec_count];
+    }
+
+    dec_count++;
+  }
+
+  for (n = int_count - 1; n > -1; n--)
+  {
+    *pstr++ = 48 + nc_int_digits[n];
+  }
+
+  *pstr++ = '.';
+
+  for (n = 0; n < dec_count; n++)
+  {
+    *pstr++ = 48 + nc_dec_digits[n];
+  }
+
+  // Terminate string
+  *pstr = 0;
+
+  if (!digits) // If digits = 0, then return buffer start
+  {
+    return nc_buffer;
+  }
+  else // Do formatted output
+  {
+    return nc_format(nc_buffer,digits);
+  }
+}
Index: /firmware/FSC/src/num_conversion.h
===================================================================
--- /firmware/FSC/src/num_conversion.h	(revision 10094)
+++ /firmware/FSC/src/num_conversion.h	(revision 10094)
@@ -0,0 +1,29 @@
+#ifndef __NUM_CONVERSION_H
+#define __NUM_CONVERSION_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+//-----------------------------------------------------------------------------
+
+#define NC_BUFFER_LENGTH 16 // Conversion buffer size
+#define NC_FILL_CHAR 32 // Character for post digits
+//-----------------------------------------------------------------------------
+
+extern U08 nc_buffer[];
+//-----------------------------------------------------------------------------
+
+pU08 nc_format(pU08 source_ptr,U08 digits);
+pU08 nc_U08_to_str(U8 value,U08 digits);
+pU08 nc_S08_to_str(S08 signed_value,U08 digits);
+pU08 nc_U08_to_hex(U08 value);
+pU08 nc_U08_to_bin(U08 value);
+pU08 nc_U16_to_str(U16 value,U08 digits);
+pU08 nc_S16_to_str(S16 signed_value,U08 digits);
+pU08 nc_U16_to_hex(U16 value);
+pU08 nc_U32_to_str(U32 value,U08 digits);
+pU08 nc_S32_to_str(S32 signed_value,U08 digits);
+pU08 nc_U32_to_hex(U32 value);
+pU08 nc_float_to_str(float value,U08 decimals,U08 digits);
+//-----------------------------------------------------------------------------
+
+#endif
Index: /firmware/FSC/src/spare_outs.c
===================================================================
--- /firmware/FSC/src/spare_outs.c	(revision 10094)
+++ /firmware/FSC/src/spare_outs.c	(revision 10094)
@@ -0,0 +1,13 @@
+#include "spare_outs.h"
+#include <avr/io.h>
+
+void spare_outs_init(void)
+{
+	DDRB |= (1<<PB2) | (1<<PB3); 	// set Out1_spare & out2_spare as outputs
+
+	DDRA &= ~(1<<PA7);				// set In1_spare as input
+	DDRC &= ~(1<<PC7);				// set In2_spare as input
+	PORTA |= (1<<PA7); 				// swtich on pullup on In1_spare
+	PORTC |= (1<<PC7); 				// swtich on pullup on In2_spare
+
+}
Index: /firmware/FSC/src/spare_outs.h
===================================================================
--- /firmware/FSC/src/spare_outs.h	(revision 10094)
+++ /firmware/FSC/src/spare_outs.h	(revision 10094)
@@ -0,0 +1,6 @@
+#ifndef __SPARE_OUTS_H
+#define __SPARE_OUTS_H
+
+void spare_outs_init(void);
+
+#endif //__SPARE_OUTS_H
Index: /firmware/FSC/src/spi_master.c
===================================================================
--- /firmware/FSC/src/spi_master.c	(revision 10094)
+++ /firmware/FSC/src/spi_master.c	(revision 10094)
@@ -0,0 +1,267 @@
+//-----------------------------------------------------------------------------
+#include "spi_master.h"
+
+//-----------------------------------------------------------------------------
+volatile U08 spi_clock_index;
+volatile U08 spi_cpol;
+volatile U08 spi_cpha;
+volatile U08 spi_dord;
+volatile BOOL spi_ss_active_high;
+volatile U08 spi_read_buffer[SPI_READ_BUFFER_SIZE];
+volatile U08 spi_write_buffer[SPI_WRITE_BUFFER_SIZE];
+
+volatile U08 SPI_DEVICE_SS[4]={SPI_E_CS ,SPI_AD_CS ,SPI_M_CS ,SPI_A_CS };
+volatile BOOL SPI_DEVICE_ACTIVE_HIGH[4]={false ,false ,false ,false };
+//-----------------------------------------------------------------------------
+
+
+
+
+void spi_init(void)
+{
+
+// set all CS's: output
+DDRB |= (1 << SPI_E_CS);
+DDRD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS);
+
+// set all Chips selects HIGH
+PORTB |= (1 << SPI_E_CS);
+PORTD |= (1 << SPI_AD_CS) |(1 << SPI_M_CS) |(1 << SPI_A_CS);
+
+// set MOSI and SCK: output & // set MISO: input
+SPI_DDR |= (1 << SPI_MOSI);
+SPI_DDR |= (1 << SPI_SCLK);
+SPI_DDR &= ~(1 << SPI_MISO);
+
+// set MOSI, SCK: HIGH. MISO leave alone.
+SPI_PRT |= (1 << SPI_MOSI);
+SPI_PRT |= (1 << SPI_SCLK);
+//SPI_PRT |= (1 << SPI_MISO);
+
+
+
+  spi_clock_index = 4;  // Set Clockindex for lowest clock speed (F_CPU / 128)
+  spi_dord = 0;					// Data Order MSB first dord = 0
+  spi_cpol = 1;			
+  spi_cpha = 1;					// mode=3 needed by ADC ... lets see whats next.
+  spi_setup(); 					// Setup SPI bits and clock speed
+
+}
+//-----------------------------------------------------------------------------
+void spi_setup(void)
+{
+  // Disable SPI, clear all flags
+  SPCR = 0;
+
+  // Set/Clear bits DORD, CPOL and CPHA in SPI Control Register
+  spi_dord & 0x01 ? (SPCR |= (1 << DORD)) : (SPCR &= ~(1 << DORD));
+  spi_cpol & 0x01 ? (SPCR |= (1 << CPOL)) : (SPCR &= ~(1 << CPOL));
+  spi_cpha & 0x01 ? (SPCR |= (1 << CPHA)) : (SPCR &= ~(1 << CPHA));
+
+  switch (spi_clock_index)
+  {
+    case 0:{ // F_CPU / 128
+      SPCR |= (1 << SPR1) | (1 << SPR0);
+      SPSR &= ~(1 <<SPI2X);
+	  }
+    break;
+
+    case 1:{ // F_CPU / 64
+      SPCR |= (1 << SPR1);
+      SPSR &= ~(1 << SPI2X);
+	  }
+    break;
+
+    case 2:{ // F_CPU / 32
+      SPCR |= (1 << SPR1);
+      SPSR |= (1 << SPI2X);
+	  }
+    break;
+
+    case 3:{ // F_CPU / 16
+      SPCR |= (1 << SPR0);
+      SPSR &= ~(1 << SPI2X);
+	  }
+    break;
+
+    case 4:{ // F_CPU / 8
+      SPCR |= (1 << SPR0);
+      SPSR |= (1 << SPI2X);
+	  }
+    break;
+
+    case 5: // F_CPU / 4
+      SPSR &= ~(1 << SPI2X);
+    break;
+
+    case 6: // F_CPU / 2
+      SPSR |= (1 << SPI2X);
+    break;
+
+    default:{ // F_CPU / 128
+      SPCR |= (1 << SPR1) | (1 << SPR0);
+      SPSR &= ~(1 << SPI2X);
+	  }
+  }
+
+  // Enable SPI in Master Mode
+  SPCR |= (1 << SPE) | (1 << MSTR);
+}
+
+//-----------------------------------------------------------------------------
+
+void spi_set_clock_index(U08 clock_index)
+{
+  if (clock_index > SPI_MAX_CLOCK_INDEX)
+  {
+    clock_index = SPI_MAX_CLOCK_INDEX;
+  }
+
+  spi_clock_index = clock_index;
+
+  spi_setup(); // Setup SPI bits and clock speed
+}
+//-----------------------------------------------------------------------------
+
+void spi_set_dord(U08 dord)
+{
+  if (dord > 1)
+  {
+    dord = 1;
+  }
+
+  spi_dord = dord;
+
+  spi_setup(); // Setup SPI bits and clock speed
+}
+//-----------------------------------------------------------------------------
+
+void spi_set_cpol(U08 cpol)
+{
+  if (cpol > 1)
+  {
+    cpol = 1;
+  }
+
+  spi_cpol = cpol;
+
+  spi_setup(); // Setup SPI bits and clock speed
+}
+//-----------------------------------------------------------------------------
+
+void spi_set_cpha(U08 cpha)
+{
+  if (cpha > 1)
+  {
+    cpha = 1;
+  }
+
+  spi_cpha = cpha;
+
+  spi_setup(); // Setup SPI bits and clock speed
+}
+
+//-----------------------------------------------------------------------------
+
+void spi_transfer(U08 bytes, U08 device)
+{
+/*
+#define SPI_E_CS PB4 		//device 0
+#define SPI_AD_CS PD3 		//device 1
+#define SPI_M_CS PD4		//device 2
+#define SPI_A_CS PD5		//device 3
+*/
+  U08 n;
+  
+  // Check for active slave select level
+  if (SPI_DEVICE_ACTIVE_HIGH[device])
+  {
+		if (device == 0) {
+    	PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
+		} else {
+			PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
+		}
+  }
+  else
+  {
+		if (device == 0) {
+    	PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
+		} else {
+			PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
+		}
+  }
+
+  // Transfer requested bytes
+  for (n = 0; n < bytes; n++)
+  {
+    spi_read_buffer[n] = spi_transfer_byte(spi_write_buffer[n]);
+  }
+
+  // Check for inactive slave select level
+  if (SPI_DEVICE_ACTIVE_HIGH[device])
+  {
+		if (device == 0) {
+    	PORTB &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
+		} else {
+			PORTD &= ~(1 << SPI_DEVICE_SS[device]); // Set Slave Select low
+		}
+  }
+  else
+  {
+		if (device == 0) {
+    	PORTB |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
+		} else {
+			PORTD |= (1 << SPI_DEVICE_SS[device]); // Set Slave Select high
+		}
+  }
+}
+//-----------------------------------------------------------------------------
+
+U08 spi_transfer_byte(U08 data)
+{
+  // Start SPI Transfer
+  SPDR = data;
+
+  // Wait for transfer completed
+  while (!(SPSR & (1 << SPIF)))
+  {
+  }
+
+  // Return result of transfer
+  return SPDR;
+}
+
+//-----------------------------------------------------------------------------
+void spi_transfer_string(U08 length, U08* addr, U08 device)
+{
+/*
+#define SPI_E_CS PB4 		//device 0
+#define SPI_AD_CS PD3 	//device 1
+#define SPI_M_CS PD4		//device 2
+#define SPI_A_CS PD5		//device 3
+*/
+  U08 n;
+  
+  // I assume the CS line is in "not enable"-state;
+	if ( device == 0 ){
+  	TGL_BIT(PORTB, SPI_DEVICE_SS[device]);  // I toggle the line
+	} else {
+		TGL_BIT(PORTD, SPI_DEVICE_SS[device]);  // I toggle the line
+	}
+  // now the line is in "enable"-state
+  
+
+  // Transfer requested bytes
+  for (n = 0; n < length; n++)
+  {
+    spi_transfer_byte(addr[n]);
+  }
+	
+		if ( device == 0 ){
+  	TGL_BIT(PORTB, SPI_DEVICE_SS[device]);  // I toggle the line
+	} else {
+		TGL_BIT(PORTD, SPI_DEVICE_SS[device]);  // I toggle the line
+	}
+
+}
+//-----------------------------------------------------------------------------
Index: /firmware/FSC/src/spi_master.h
===================================================================
--- /firmware/FSC/src/spi_master.h	(revision 10094)
+++ /firmware/FSC/src/spi_master.h	(revision 10094)
@@ -0,0 +1,54 @@
+#ifndef __SPI_MASTER_H
+#define __SPI_MASTER_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "application.h"
+#include "usart.h"
+//-----------------------------------------------------------------------------
+
+// Port Definitions
+#define SPI_PRT PORTB
+#define SPI_DDR DDRB
+
+// Bit Definitions
+#define SPI_SCLK PB7
+#define SPI_MOSI PB5
+#define SPI_MISO PB6
+// #define SPI_SS 	 PB4  // not in this application!!! danger
+#define SPI_E_CS PD2 		//device 0
+#define SPI_AD_CS PD3 		//device 1
+#define SPI_M_CS PD4		//device 2
+#define SPI_A_CS PD5		//device 3
+
+#define SPI_READ_BUFFER_SIZE 16
+#define SPI_WRITE_BUFFER_SIZE 16
+
+#define SPI_MAX_SLAVE_INDEX 2
+#define SPI_MAX_CLOCK_INDEX 6
+
+//-----------------------------------------------------------------------------
+
+extern volatile U08 spi_clock_index;
+extern volatile U08 spi_cpol;
+extern volatile U08 spi_cpha;
+extern volatile U08 spi_dord;
+extern volatile U08 SPI_DEVICE_SS[4];
+extern volatile BOOL SPI_DEVICE_ACTIVE_HIGH[4];
+
+extern volatile U08 spi_read_buffer[SPI_READ_BUFFER_SIZE];
+extern volatile U08 spi_write_buffer[SPI_WRITE_BUFFER_SIZE];
+//-----------------------------------------------------------------------------
+
+void spi_init(void);
+void spi_transfer(U08 bytes, U08 device);
+U08 spi_transfer_byte(U08 data);
+void spi_set_clock_index(U08 clock_index);
+void spi_set_dord(U08 dord);
+void spi_set_cpol(U08 cpol);
+void spi_set_cpha(U08 cpha);
+void spi_setup(void);
+void spi_transfer_string(U08 length, U08* addr, U08 device);
+//-----------------------------------------------------------------------------
+
+#endif
Index: /firmware/FSC/src/tests.c
===================================================================
--- /firmware/FSC/src/tests.c	(revision 10094)
+++ /firmware/FSC/src/tests.c	(revision 10094)
@@ -0,0 +1,47 @@
+#include "tests.h"
+
+#include "typedefs.h"
+
+void test_out_spare_pins(void)
+{
+
+	// set everything as inputs -- high Z
+	DDRA = 0x00;
+	DDRB = 0x00;
+	DDRC = 0x00;
+	DDRD = 0x00;
+
+	DDRB |= 1<<PB2; // set spare out1 as output
+	DDRB |= 1<<PB3; // set spare out2 as output
+
+	DDRB |= 1<<PB4; 
+
+	PORTC |= 1<<PC7; // switch PC7 pullup on
+	PORTA |= 1<<PA7; // switch PA7 pullup on
+
+	while (true)
+	{
+		 
+		if ( (PINC & (1<<PC7)) == 0 )
+		{
+			PORTB |= 1 << PB2;
+		} else {
+			PORTB &= ~(1<<PB2);
+		}
+
+		/*
+		if ( (PINA & (1<<PA7)) == 0 )
+		{
+			PORTB |= 1 << PB3;
+		} else {
+			PORTB &= ~(1<<PB3);
+		}
+*/
+
+		PORTB ^= 1<<PB3;
+		PORTB ^= 1<<PB4;
+	}
+
+
+
+}
Index: /firmware/FSC/src/tests.h
===================================================================
--- /firmware/FSC/src/tests.h	(revision 10094)
+++ /firmware/FSC/src/tests.h	(revision 10094)
@@ -0,0 +1,1 @@
+void test_out_spare_pins(void) ;
Index: /firmware/FSC/src/typedefs.h
===================================================================
--- /firmware/FSC/src/typedefs.h	(revision 10094)
+++ /firmware/FSC/src/typedefs.h	(revision 10094)
@@ -0,0 +1,140 @@
+#ifndef __TYPEDEFS_H
+#define __TYPEDEFS_H
+//-----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <limits.h>
+#include <util/delay.h>
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include "macros.h"
+#include <avr/pgmspace.h>
+
+//-----------------------------------------------------------------------------
+
+#define true 1
+#define TRUE 1
+#define ON 1
+#define on 1
+#define SET 1
+#define set 1
+
+#define false 0
+#define FALSE 0
+#define OFF 0
+#define off 0
+#define CLEAR 0
+#define clear 0
+
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+#define BIT8 0x0100
+#define BIT9 0x0200
+#define BIT10 0x0400
+#define BIT11 0x0800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x010000
+#define BIT17 0x020000
+#define BIT18 0x040000
+#define BIT19 0x080000
+#define BIT20 0x100000
+#define BIT21 0x200000
+#define BIT22 0x400000
+#define BIT23 0x800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+//-----------------------------------------------------------------------------
+
+// Typendeklarationen
+typedef signed char S8;
+typedef signed char S08;
+typedef signed char tS08;
+typedef unsigned char U8;
+typedef unsigned char U08;
+typedef unsigned char tU08;
+
+typedef signed int S16;
+typedef signed int tS16;
+typedef unsigned int U16;
+typedef unsigned int tU16;
+typedef signed long S32;
+typedef signed long tS32;
+typedef unsigned long U32;
+typedef unsigned long tU32;
+
+typedef S08 *pS8;
+typedef S08 *pS08;
+typedef U08 *pU8;
+typedef U08 *pU08;
+typedef S16 *pS16;
+typedef U16 *pU16;
+typedef S32 *pS32;
+typedef U32 *pU32;
+typedef float *pfloat;
+
+typedef U08 BOOL;
+typedef BOOL *pBOOL;
+
+//typedef U08 __flash *fpU08; //geht nicht mit gcc
+//typedef U08 PROGMEM prog_U08;
+//typedef prog_U08 *fpU08;
+typedef U08 *fpU08;
+
+typedef union uMEM16 // Word and Byte access to 16-Bit data
+{
+  U16 word; // Word
+  pU16 pword; // Pointer to Word
+  U08 byte[2]; // Byte
+  pU08 pbyte; // Pointer to Byte
+} tMEM16;
+
+typedef union uMEM32 // DWord, Word and Byte access to 32-Bit data
+{
+  U32 dword; // DWORD
+  pU32 pdword[2]; // Pointer to U32
+
+  float fp; // Float
+  pfloat pfp[2]; // Pointer to float
+
+  U16 word[2]; // Word
+  pU16 pword[2]; // Pointer to U16
+
+  U08 byte[4]; // Byte
+  pU08 pbyte[2]; // Pointer to U08
+
+} tMEM32;
+
+typedef enum // Enumeration of watchdog prescale values
+{
+  WDT_PS_2K, // 2048 cycles (16ms)
+  WDT_PS_4K, // 40968 cycles (32ms)
+  WDT_PS_8K, // 8192 cycles (64ms)
+  WDT_PS_16K, // 16384 cycles (0.125s)
+  WDT_PS_32K, // 32768 cycles (0.25s)
+  WDT_PS_64K, // 65536 cycles (0.5s)
+  WDT_PS_128K, // 131072 cycles (1.0s)
+  WDT_PS_256K, // 262144 cycles (2.0s)
+  WDT_PS_512K, // 524288 cycles (4.0s)
+  WDT_PS_1024K // 1048576 cycles (8.0s)
+} tWDT_PRESCALE;
+//-----------------------------------------------------------------------------
+
+#endif
Index: /firmware/FSC/src/usart.c
===================================================================
--- /firmware/FSC/src/usart.c	(revision 10094)
+++ /firmware/FSC/src/usart.c	(revision 10094)
@@ -0,0 +1,264 @@
+//-----------------------------------------------------------------------------
+
+#include "usart.h"
+
+#include <avr/interrupt.h>
+//-----------------------------------------------------------------------------
+
+#ifdef USART_USE_RX_IRQ
+  U08 usart_rx_buffer[USART_RX_BUFFER_SIZE];
+  //U08 *usart_rx_buffer_ptr = &usart_rx_buffer[0];
+  U08 usart_received_chars;
+  volatile BOOL usart_rx_ready = false;
+  static U08 usart_rx_buffer_index = 0;
+  static U08 usart_receive_char;
+  static BOOL usart_receive_suspended = false;
+  volatile BOOL ISR_toggle_out = false;
+#endif
+//-----------------------------------------------------------------------------
+
+void usart_init(void)
+{
+  USART_SET_BAUDRATE(USART_BAUDRATE);
+
+  UCSRA = 0x00;
+
+  UCSRB = 0x00; // Disable receiver and transmitter and interrupts
+
+#ifdef USART_USE_RX
+  UCSRB |= (1 << RXEN);			// Turn on receiver
+	DDRD &= ~(1<<PD0);				// PD0 is RXD
+#endif
+
+#ifdef USART_USE_RX_IRQ
+  UCSRB |= (1 << RXCIE);		// Enable rx interrupt
+#endif
+
+#ifdef USART_USE_TX
+  UCSRB |= (1 << TXEN);			// Turn on transmitter
+	DDRD |= 1<<PD1; 					// PD1 is TXD
+#endif
+
+  UCSRC = (1 << URSEL) | (1 << UCSZ1) | (1 << UCSZ0); // 8-Bit character length
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_char(U08 data)
+{
+  while (!(UCSRA & (1 << UDRE))) ; // Wait until tx register is empty
+
+  UDR = data;
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_crlf(void)
+{
+  usart_write_char(USART_CHAR_CR);
+  usart_write_char(USART_CHAR_LF);
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_str(pU08 str)
+{
+  while (*str)
+  {
+    usart_write_char(*str++);
+  }
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_flash_str(fpU08 str)
+{
+  while (*str)
+  {
+    usart_write_char(*str++);
+  }
+}
+//-----------------------------------------------------------------------------
+
+void usart_writeln_flash_str(fpU08 str)
+{
+  while (*str)
+  {
+    usart_write_char(*str++);
+  }
+
+  usart_write_char(USART_CHAR_CR);
+  usart_write_char(USART_CHAR_LF);
+}
+//-----------------------------------------------------------------------------
+
+void usart_writeln_str(pU08 str)
+{
+  usart_write_str(str);
+  usart_write_char(USART_CHAR_CR);
+  usart_write_char(USART_CHAR_LF);
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U08(U08 value,U08 digits)
+{
+  usart_write_str(nc_U08_to_str(value,digits));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_S08(S08 value,U08 digits)
+{
+  usart_write_str(nc_S08_to_str(value,digits));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U08_hex(U08 value)
+{
+  usart_write_str(nc_U08_to_hex(value));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U08_bin(U08 value)
+{
+  usart_write_str(nc_U08_to_bin(value));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U16(U16 value,U08 digits)
+{
+  usart_write_str(nc_U16_to_str(value,digits));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_S16(S16 value,U08 digits)
+{
+  usart_write_str(nc_S16_to_str(value,digits));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U16_hex(U16 value)
+{
+  usart_write_str(nc_U16_to_hex(value));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U32(U32 value,U08 digits)
+{
+  usart_write_str(nc_U32_to_str(value,digits));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_S32(S32 value,U08 digits)
+{
+  usart_write_str(nc_S32_to_str(value,digits));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_U32_hex(U32 value)
+{
+  usart_write_str(nc_U32_to_hex(value));
+}
+//-----------------------------------------------------------------------------
+
+void usart_write_float(float value,U08 decimals,U08 digits)
+{
+  usart_write_str(nc_float_to_str(value,decimals,digits));
+}
+//-----------------------------------------------------------------------------
+
+#ifdef USART_USE_RX_IRQ
+
+ISR(SIG_USART_RECV)
+{
+	if (ISR_toggle_out) PORTB ^= (1<<PB3); // toggle Out2_spare when starting ISR
+
+  usart_receive_char = UDR;
+
+  if (usart_rx_ready) // Exit if ready flag is still set 
+  {
+    return;
+  }
+
+  // If CR received, then set ready flag
+  if (usart_receive_char == USART_CHAR_CR)
+  {
+    usart_rx_buffer[usart_rx_buffer_index] = 0; // Terminate input string
+    usart_received_chars = usart_rx_buffer_index;
+    usart_rx_buffer_index = 0;
+    usart_receive_suspended = false;
+    usart_rx_ready = TRUE;
+    return;
+  }
+
+  // Ignore all characters till next CR
+  if (usart_receive_suspended)
+  {
+    return;
+  }
+
+  // Check for underscore or comment
+  if (usart_receive_char == '_' || usart_receive_char == ';')
+  {
+    usart_receive_suspended = true;
+
+    return;
+  }
+
+  // If Backspace received, then delete last character
+  if (usart_receive_char == USART_CHAR_BS && usart_rx_buffer_index)
+  {
+    usart_rx_buffer_index--;
+
+    return;
+  }
+
+  // Ignore invalid characters
+  if (usart_receive_char < USART_CHAR_SPC)
+  {
+    return;
+  }
+
+#ifdef USART_USE_UPPERCASE
+  if (usart_receive_char >= 'a' && usart_receive_char <= 'z')
+  {
+    usart_receive_char -= 32;
+  }
+#endif
+
+  if (usart_rx_buffer_index < USART_RX_BUFFER_SIZE - 1) // Store character
+  {
+    usart_rx_buffer[usart_rx_buffer_index++] = usart_receive_char;
+    usart_writeln_str(usart_rx_buffer);
+  }
+#endif 
+  //usart_write_char(usart_rx_buffer[usart_rx_buffer_index]);
+ //usart_writeln_str(usart_rx_buffer);
+ //usart_write_char(usart_rx_buffer[1,2]);
+ //usart_write_char(usart_rx_buffer[usart_rx_buffer_index]);
+ //usart_writeln_flash_str(*usart_rx_buffer);
+ //usart_write_char(usart_rx_buffer);
+}  
+
+/*
+#define uart_maxstrlen 64
+ 
+volatile U8 uart_str_complete=0;
+volatile U8 uart_str_count=0;
+volatile U8 uart_string[uart_maxstrlen+1]="";
+
+ISR(USART_RXC_vect)
+{
+    unsigned char buffer = 64;
+    // Daten aus dem Puffer lesen
+    buffer = UDR;
+	UDR = buffer;
+	if ( uart_str_complete==0 ){	// wenn uart_string gerade in Verwendung, neues Zeichen verwerfen
+		// Daten werden erst in string geschrieben, wenn nicht String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
+	  	if (buffer!='\n' && buffer!='\r' && uart_str_count<uart_maxstrlen-1){
+			uart_string[uart_str_count]=buffer;
+			uart_str_count++;
+		} else {
+			uart_string[uart_str_count]='\0';
+			uart_str_count=0;
+			uart_str_complete=1;
+		}
+	}
+}
+
+*/
Index: /firmware/FSC/src/usart.h
===================================================================
--- /firmware/FSC/src/usart.h	(revision 10094)
+++ /firmware/FSC/src/usart.h	(revision 10094)
@@ -0,0 +1,49 @@
+#ifndef __USART_H
+#define __USART_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "application.h"
+#include "num_conversion.h"
+//-----------------------------------------------------------------------------
+
+#define USART_CHAR_BS 8
+#define USART_CHAR_LF 10
+#define USART_CHAR_CR 13
+#define USART_CHAR_ESC 27
+#define USART_CHAR_SPC 32
+//-----------------------------------------------------------------------------
+
+#define USART_SET_BAUDRATE(br) (UBRRH = (U08)((((U32)F_CPU) /\
+                                ((U32)br * 16) - 1) >> 8),\
+                                UBRRL = (U08)(((U32)F_CPU) /\
+                                ((U32)br * 16) - 1))
+//-----------------------------------------------------------------------------
+
+extern U08 usart_rx_buffer[];
+extern volatile BOOL usart_rx_ready;
+extern volatile BOOL ISR_toggle_out;
+extern U08 usart_received_chars;
+//-----------------------------------------------------------------------------
+
+void usart_init(void);
+void usart_write_char(U08 data);
+void usart_write_crlf(void);
+void usart_write_str(pU08 str);
+void usart_writeln_str(pU08 str);
+void usart_write_flash_str(fpU08 str);
+void usart_writeln_flash_str(fpU08 str);
+void usart_write_U08(U08 value,U08 digits);
+void usart_write_S08(S08 value,U08 digits);
+void usart_write_U08_hex(U08 value);
+void usart_write_U08_bin(U08 value);
+void usart_write_U16(U16 value,U08 digits);
+void usart_write_S16(S16 value,U08 digits);
+void usart_write_U16_hex(U16 value);
+void usart_write_U32(U32 value,U08 digits);
+void usart_write_S32(S32 value,U08 digits);
+void usart_write_U32_hex(U32 value);
+void usart_write_float(float value,U08 decimals,U08 digits);
+//-----------------------------------------------------------------------------
+
+#endif
Index: /firmware/FSC/src/w5100_spi_interface.c
===================================================================
--- /firmware/FSC/src/w5100_spi_interface.c	(revision 10094)
+++ /firmware/FSC/src/w5100_spi_interface.c	(revision 10094)
@@ -0,0 +1,308 @@
+//-----------------------------------------------------------------------------
+
+#include "w5100_spi_interface.h"       
+#include "spi_master.h"    
+volatile BOOL sock0_connection_established = false;
+volatile U08 eth_read_buffer[ETH_READ_BUFFER_SIZE];
+volatile U08 eth_write_buffer[ETH_WRITE_BUFFER_SIZE];
+
+//-----------------------------------------------------------------------------
+
+void w5100_write( U16 addr, U08 data)
+{
+
+spi_write_buffer[0]=0xF0;
+spi_write_buffer[1]=(U08)(addr);
+spi_write_buffer[2]=(U08)(addr>>8);
+spi_write_buffer[3]=data;
+
+spi_transfer(4, 0); 
+// spi_read_buffer should contain 0x00 0x01 0x02 and 0x03 ... nice check!
+}
+
+U08 w5100_read( U16 addr)
+{
+
+spi_write_buffer[0]=0x0F;
+spi_write_buffer[1]=(U08)(addr);
+spi_write_buffer[2]=(U08)(addr>>8);
+spi_write_buffer[3]=0x00;
+
+spi_transfer(4, 0); 
+return spi_read_buffer[3]; 
+// spi_read_buffer should contain 0x00 0x01 0x02 and data ... nice check!
+}
+
+U08 w5100_init (void) 
+{
+U08 sock0_status;
+
+	// set FSCs MAC Address to value defined in w5100_spi_interface.h
+	w5100_write( CM_SHAR0, FSC_MAC_ADDRESS0 );
+	w5100_write( CM_SHAR1, FSC_MAC_ADDRESS1 );
+	w5100_write( CM_SHAR2, FSC_MAC_ADDRESS2 );
+	w5100_write( CM_SHAR3, FSC_MAC_ADDRESS3 );
+	w5100_write( CM_SHAR4, FSC_MAC_ADDRESS4 );
+	w5100_write( CM_SHAR5, FSC_MAC_ADDRESS5 );
+
+	//set IP
+	w5100_write( CM_SIPR0, FSC_IP_ADDRESS0 );
+	w5100_write( CM_SIPR1, FSC_IP_ADDRESS1 );
+	w5100_write( CM_SIPR2, FSC_IP_ADDRESS2 );
+	w5100_write( CM_SIPR3, FSC_IP_ADDRESS3 );
+
+	// set subnet mask
+	w5100_write( CM_SUBR0, FSC_SUBNET_MASK0 );
+	w5100_write( CM_SUBR1, FSC_SUBNET_MASK1 );
+	w5100_write( CM_SUBR2, FSC_SUBNET_MASK2 );
+	w5100_write( CM_SUBR3, FSC_SUBNET_MASK3 );
+
+	// set IP of Gateway used by FSC
+	w5100_write( CM_GAR0, FSC_GATEWAY_ADDRESS0 );
+	w5100_write( CM_GAR1, FSC_GATEWAY_ADDRESS1 );
+	w5100_write( CM_GAR2, FSC_GATEWAY_ADDRESS2 );
+	w5100_write( CM_GAR3, FSC_GATEWAY_ADDRESS3 );
+
+	//set socket read and write fifo sizes
+	w5100_write( CM_RMSR, 0x0A); // --> 4k for socket 0 and 1
+	w5100_write( CM_TMSR, 0x0A); // --> 4k for socket 0 and 1
+
+
+	w5100_write ( S0_MR, 0x01); 		// set Socket 0 as TCP
+	w5100_write ( S0_PORT0, 0x13 ); 	// Port 5000 -> 0x1388 
+	w5100_write ( S0_PORT1, 0x88 ); 
+	w5100_write ( S0_CR, CR_OPEN );		// issue Socket open command
+	sock0_status = w5100_read(S0_SR); // request socket 0 status
+	if ( sock0_status != SR_SOCK_INIT)
+	{
+		return sock0_status;
+	}
+
+	w5100_write ( S0_CR, CR_LISTEN );		// issue Socket listen command
+	sock0_status = w5100_read(S0_SR); // request socket 0 status
+	if ( sock0_status != SR_SOCK_LISTEN)
+	{
+		return sock0_status;
+	}
+
+	return sock0_status;
+}
+
+
+BOOL w5100_is_established()
+{
+	if ( w5100_read(S0_SR) == SR_SOCK_ESTABLISHED )
+	{
+		sock0_connection_established = true;
+	}
+	else
+	{
+		sock0_connection_established = false;
+	}
+	return sock0_connection_established;
+
+}
+
+U08 w5100_sock_status()
+{
+	return w5100_read(S0_SR);
+}
+
+
+// getters of TX and RX registers
+// 		S0_TX_FSR
+U16 get_S0_TX_FSR()
+{
+U16 freesize;
+freesize=w5100_read(S0_TX_FSR1);
+freesize = freesize << 8;
+freesize += w5100_read(S0_TX_FSR0);
+return freesize;
+}
+
+//		S0_TX_RD
+U16 get_S0_TX_RD()
+{
+U16 readpointer;
+readpointer=w5100_read(S0_TX_RD1);
+readpointer = readpointer << 8;
+readpointer += w5100_read(S0_TX_RD0);
+return readpointer;
+}
+
+//		S0_TX_WR
+U16 get_S0_TX_WR()
+{
+U16 writepointer;
+writepointer=w5100_read(S0_TX_WR1);
+writepointer = writepointer << 8;
+writepointer += w5100_read(S0_TX_WR0);
+return writepointer;
+}
+
+//		S0_RX_RSR
+U16 get_S0_RX_RSR()
+{
+U16 received_size;
+received_size=w5100_read(S0_RX_RSR1);
+received_size = received_size << 8;
+received_size += w5100_read(S0_RX_RSR0);
+return received_size;
+}
+
+//		S0_RX_RD
+U16 get_S0_RX_RD()
+{
+U16 readpointer;
+readpointer=w5100_read(S0_RX_RD1);
+readpointer = readpointer << 8;
+readpointer += w5100_read(S0_RX_RD0);
+return readpointer;
+}
+
+// setters for some RX and TX registers
+//		S0_TX_WR
+void set_S0_TX_WR(U16 value)
+{
+U08 high_byte = (value>>8);
+U08 low_byte = (value<<8)>>8;
+w5100_write(S0_TX_WR1, high_byte);
+w5100_write(S0_TX_WR0, low_byte);
+}
+
+//		S0_TX_RD
+void set_S0_RX_RD(U16 value)
+{
+U08 high_byte = (value>>8);
+U08 low_byte = (value<<8)>>8;
+w5100_write(S0_TX_RD1, high_byte);
+w5100_write(S0_TX_RD0, low_byte);
+}
+
+U08 w5100_get_RX(U08 NumBytes, BOOL send_ACK)
+{
+	U16 size = get_S0_RX_RSR();
+	U16 upper_size, lower_size;
+	if (NumBytes > ETH_READ_BUFFER_SIZE)
+	{
+		NumBytes = ETH_READ_BUFFER_SIZE;
+	}
+	if (size == 0)
+	{
+		return 0;
+	}
+	else if ( size < NumBytes )
+	{
+		NumBytes = size;
+	}
+
+	// now calculate the offset address
+	// calculated according to W5100 datasheet page: 43
+	U16 last_RX_read_pointer = get_S0_RX_RD();
+	U16 offset = last_RX_read_pointer & S0_RX_MASK;
+	U16 start_address =  S0_RX_BASE + offset;
+
+	if ((offset + NumBytes) > (S0_RX_MASK + 1) )  // if data is turned over in RX-mem
+	{
+		upper_size = (S0_RX_MASK + 1) - offset;
+		lower_size = NumBytes - upper_size;
+		for (U08 i = 0; i < upper_size; ++i)
+		{
+			eth_read_buffer[i] = w5100_read(start_address + i);
+		}
+		for (U08 i = 0; i < lower_size; ++i)
+		{
+			eth_read_buffer[upper_size + i] = w5100_read(S0_RX_BASE + i);
+		}
+	}
+	else // if not data turn over in RX-mem
+	{
+		for (U08 i = 0; i < NumBytes; ++i)
+		{
+			eth_read_buffer[i] = w5100_read(start_address + i);
+		}
+	}
+
+	// inform W5100 about how much data was read out.
+	set_S0_RX_RD(last_RX_read_pointer + NumBytes);
+
+	// if user wishes, W5100 may inform peer about receiption.
+	// this should be done quickly, otherwise timeout may occur on 
+	// peer side, and peer retransmitts or so ... 
+	// 
+	// maybe it is necessary to acknowledge receiption very early.
+	// I think there is an option in Socket mode register for this.
+	if (send_ACK)
+	{
+		w5100_write ( S0_CR, CR_RECV );
+	}
+
+	return NumBytes;
+}
+
+// returns number of words, transmitted into TX - buffer.
+U08 w5100_set_TX(U08 NumBytes)
+{
+	U16 freesize = get_S0_TX_FSR();
+	if (freesize == 0)
+	{
+		return 0;
+	}
+	if (freesize < NumBytes)
+	{
+		NumBytes = freesize;
+	}
+	
+	U16 last_TX_write_pointer = get_S0_TX_WR();
+	U16 offset = last_TX_write_pointer & S0_TX_MASK;
+	U16 start_address =  S0_TX_BASE + offset;
+
+
+	U16 upper_size, lower_size;
+	if (NumBytes > ETH_READ_BUFFER_SIZE)
+	{
+		NumBytes = ETH_READ_BUFFER_SIZE;
+	}
+	if (freesize == 0)
+	{
+		return 0;
+	}
+	else if ( freesize < NumBytes )
+	{
+		NumBytes = freesize;
+	}
+
+	// now calculate the offset address
+	// calculated according to W5100 datasheet page: 43
+
+	if ((offset + NumBytes) > (S0_RX_MASK + 1) )  // if data is turned over in RX-mem
+	{
+		upper_size = (S0_RX_MASK + 1) - offset;
+		lower_size = NumBytes - upper_size;
+		for (U08 i = 0; i < upper_size; ++i)
+		{
+			eth_read_buffer[i] = w5100_read(start_address + i);
+		}
+		for (U08 i = 0; i < lower_size; ++i)
+		{
+			eth_read_buffer[upper_size + i] = w5100_read(S0_RX_BASE + i);
+		}
+	}
+	else // if not data turn over in RX-mem
+	{
+		for (U08 i = 0; i < NumBytes; ++i)
+		{
+			eth_read_buffer[i] = w5100_read(start_address + i);
+		}
+	}
+
+	// inform W5100 about how much data was read out.
+	set_S0_RX_RD(last_TX_write_pointer + NumBytes);
+
+
+	return NumBytes;
+}
+
+
+
+
Index: /firmware/FSC/src/w5100_spi_interface.h
===================================================================
--- /firmware/FSC/src/w5100_spi_interface.h	(revision 10094)
+++ /firmware/FSC/src/w5100_spi_interface.h	(revision 10094)
@@ -0,0 +1,197 @@
+#ifndef __W5100_SPI_INTERFACE_H
+#define __W5100_SPI_INTERFACE_H
+//-----------------------------------------------------------------------------
+
+#include "typedefs.h"
+#include "application.h"
+#include "num_conversion.h"
+
+extern volatile BOOL sock0_connection_established;
+
+
+#define ETH_READ_BUFFER_SIZE 16
+#define ETH_WRITE_BUFFER_SIZE 16
+extern volatile U08 eth_read_buffer[ETH_READ_BUFFER_SIZE];
+extern volatile U08 eth_write_buffer[ETH_WRITE_BUFFER_SIZE];
+//-----------------------------------------------------------------------------
+// Port Definitions
+// Pin Definitions
+// W5100 is SPI device 0
+// -- so there is no need to define special pins.
+// -- refer to the device by using the global buffers:
+// 	volatile U08 spi_read_buffer[SPI_READ_BUFFER_SIZE];
+//	volatile U08 spi_write_buffer[SPI_WRITE_BUFFER_SIZE];
+//
+//	and the spi function:
+// 	void spi_transfer(U08 bytes, U08 device)
+// 
+//	when only sending one byte, you can do:
+//	U08 returnvalue;
+//	CLR_BIT(SPI_DEVICE_SS_PRT[0], SPI_DEVICE_SS[0]);  	// Set CS low
+//	returnvalue = spi_transfer_byte(0xFF);     	
+//  SET_BIT(SPI_DEVICE_SS_PRT[0], SPI_DEVICE_SS[0]);	// Set CS high
+//
+//	W5100 supports SPI modes 0 and 3  --> cpol/cpha= 0/0 or 1/1
+
+// we only use socket 0 in this application. So only a few of W5100 adresses are mentioned here
+// W5100 MEM Addresses
+// Common registers:
+#define CM_MR    0x0000		// mode register
+#define CM_GAR0  0x0001		// Gateway adress 
+#define CM_GAR1  0x0002		// Gateway adress 
+#define CM_GAR2  0x0003		// Gateway adress 
+#define CM_GAR3  0x0004		// Gateway adress 
+#define CM_SUBR0 0x0005		// Subnetmask adress 
+#define CM_SUBR1 0x0006		// Subnetmask adress 
+#define CM_SUBR2 0x0007		// Subnetmask adress 
+#define CM_SUBR3 0x0008		// Subnetmask adress 
+#define CM_SHAR0 0x0009		// Source Hardware adress: MAC
+#define CM_SHAR1 0x000A		// Source Hardware adress: MAC
+#define CM_SHAR2 0x000B		// Source Hardware adress: MAC
+#define CM_SHAR3 0x000C		// Source Hardware adress: MAC
+#define CM_SHAR4 0x000D		// Source Hardware adress: MAC
+#define CM_SHAR5 0x000E		// Source Hardware adress: MAC
+#define CM_SIPR0 0x000F		// Source IP adress
+#define CM_SIPR1 0x0010		// Source IP adress
+#define CM_SIPR2 0x0011		// Source IP adress
+#define CM_SIPR3 0x0012		// Source IP adress
+#define CM_IR    0x0015		// Interrupt
+#define CM_IMR   0x0016		// Source IP adress
+#define CM_RTR0  0x0017		// retry time register
+#define CM_RTR1  0x0018		// retry time register
+#define CM_RCR   0x0019		// Retry count 
+#define CM_RMSR  0x001A		// RX mem size					-- full mem size for sock0 --> value=0x03
+#define CM_TMSR  0x001B		// TX mem size					-- full mem size for sock0 --> value=0x03
+
+// Socket 0 registers
+#define S0_MR 		0x0400		// Socket 0 mode			-- for TCP value = 0x01 (set bit 5 for no delay ACK)
+#define S0_CR		0x0401		// socket 0 command			-- for commands see below
+#define S0_IR		0x0402		// socket 0 interrupt		-- see bit description below
+#define S0_SR		0x0403		// socket 0 status			-- see below
+#define S0_PORT0	0x0404		// socket 0 Port			-- FSC might get port number 0x1F5C = 8028, since we have only one FSC in cam
+#define S0_PORT1	0x0405		// socket 0 Port 			-- 0xF5C1= 62913 is okay as well ... 
+#define S0_MSSR0	0x0412		// max segment size			--
+#define S0_MSSR1	0x0413		// max segment size			-- reset value is 0xFFFF; is set to other party value, if in TCP passive mode
+#define S0_TX_FSR0	0x0420		// socket 0 TX free size
+#define S0_TX_FSR1	0x0421		// socket 0 TX free size
+#define S0_TX_RD0	0x0422		// socket 0 TX read pointer	-- read only:
+#define S0_TX_RD1	0x0423		// socket 0 TX read pointer
+#define S0_TX_WR0	0x0424		// socket 0 TX write pointer
+#define S0_TX_WR1	0x0425		// socket 0 TX write pointer
+#define S0_RX_RSR0	0x0426		// socket 0 RX received size 
+#define S0_RX_RSR1	0x0427		// socket 0 RX received size 
+#define S0_RX_RD0	0x0428		// socket 0 RX read pointer
+#define S0_RX_RD1	0x0429		// socket 0 RX read pointer 
+
+
+
+// some register values:
+#define MR_TCP			0
+#define MR_NOACKDELAY	5
+
+#define CR_OPEN			0x01
+#define CR_LISTEN		0x02
+#define CR_CONECT		0x04
+#define CR_DISCON		0x08
+#define CR_CLOSE		0x10
+#define CR_SEND			0x20
+#define CR_RECV			0x40
+#define CR_SEND_MAC		0x21
+#define CR_SEND_KEEP	0x22
+
+#define IR_SEND_OK		4
+#define IR_TIMEOUT		3
+#define IR_RECV			2
+#define IR_DISCON		1
+#define IR_CON			0
+
+#define SR_SOCK_CLOSED			0x00
+#define SR_SOCK_INIT			0x13
+#define SR_SOCK_LISTEN			0x14
+#define SR_SOCK_ESTABLISHED		0x17
+#define SR_SOCK_CLOSE_WAIT		0x1C
+#define SR_SOCK_UDP				0x22
+#define SR_SOCK_IPRAW			0x32
+#define SR_SOCK_MACRAW			0x42
+#define SR_SOCK_PPPOE			0x5F
+//changing
+#define SR_SOCK_SYNSENT			0x15
+#define SR_SOCK_SYNRECV			0x16
+#define SR_SOCK_FIN_WAIT		0x18
+#define SR_SOCK_CLOSING			0x1A
+#define SR_SOCK_TIME_WAIT		0x1B
+#define SR_SOCK_LAST_ACK		0x1D
+#define SR_SOCK_ARP0			0x11
+#define SR_SOCK_ARP1			0x21
+#define SR_SOCK_ARP2			0x31
+
+// low level functions
+void w5100_write( U16 addr, U08 data);
+U08 w5100_read( U16 addr);
+
+//------------------------------------------------------------------------------
+// Description of w5100_init() function:
+//------------------------------------------------------------------------------
+//------------------------------------------------------------------------------
+// BASIC SETTINGS:
+//------------------------------------------------------------------------------
+// leave common MR in default state: 0x00
+// leave IMR in default state: 0x00 no interrupt will occur, since #INT line is not routed
+// leave RTR in default state: 0x07D0  --> 200ms
+// leave RCR in default state: 0x08, after 8 re-transmissionsm, the TIMEOUT bit in Sn_IR is set '1'
+//------------------------------------------------------------------------------
+// NETWORK SETTING:
+// set GAR to FSC_GATEWAY_ADDRESS
+#define FSC_GATEWAY_ADDRESS0 0xC0		// 192.168.0.1
+#define FSC_GATEWAY_ADDRESS1 0xA8
+#define FSC_GATEWAY_ADDRESS2 0x00
+#define FSC_GATEWAY_ADDRESS3 0x01
+// set SHAR to FSC_MAC_ADDRESS
+#define FSC_MAC_ADDRESS0 0x1F	//looks like: 1F.SC.1F.SC.1F.SC
+#define FSC_MAC_ADDRESS1 0x5C
+#define FSC_MAC_ADDRESS2 0x1F 
+#define FSC_MAC_ADDRESS3 0x5C
+#define FSC_MAC_ADDRESS4 0x1F
+#define FSC_MAC_ADDRESS5 0x5C
+// set SUBR to FSC_SUBNET_MASK
+#define FSC_SUBNET_MASK0 0xFF	//255.255.255.0
+#define FSC_SUBNET_MASK1 0xFF
+#define FSC_SUBNET_MASK2 0xFF
+#define FSC_SUBNET_MASK3 0x00
+// set SIPR to FSC_IP_ADDRESS
+#define FSC_IP_ADDRESS0 0xC0	// 192.168.0.17
+#define FSC_IP_ADDRESS1 0xA8
+#define FSC_IP_ADDRESS2 0x00
+#define FSC_IP_ADDRESS3 0x11
+//------------------------------------------------------------------------------
+// MEM SETTINGS:
+// we plan the possible use of 2 Sockets:
+// Socket 0 for command input and requested data output
+// Socket 1 as a Webserver
+//
+// set RMSR=0x0A --> 4k memory for Socket 0 and 1 
+#define RX_MEM_BASE 0x6000
+#define S0_RX_BASE  0x6000 			// since it is the first socket its base adress is just the RX MEM SPACE BASE
+#define S0_RX_MASK  0x0FFF			// this is 4k - 1
+#define S1_RX_BASE  0x7000			// 2nd socket start, right after first socket
+#define S1_RX_MASK  0x0FFF			// again: 4k - 1
+// set TMSR=0x0A --> 4k mem for each socket
+#define TX_MEM_BASE 0x4000
+#define S0_TX_BASE  0x4000 			// since it is the first socket its base adress is just the RX MEM SPACE BASE
+#define S0_TX_MASK  0x0FFF			// this is 4k - 1
+#define S1_TX_BASE  0x5000			// 2nd socket start, right after first socket
+#define S1_TX_MASK  0x0FFF			// again: 4k - 1
+//------------------------------------------------------------------------------
+U08 w5100_init();
+
+
+// -- returns: TRUE if socket status is == SR_SOCK_ESTABLISHED
+BOOL w5100_is_established();
+// request socket status info:
+U08 w5100_sock_status();
+
+
+U16 w5100_get_received_size();
+U16 w5100_get_start_address();
+//-----------------------------------------------------------------------------
+#endif //__W5100_SPI_INTERFACE_H
