/********************************************************************************************/
/*                                                                                          */
/*     Programm:          Cynetik                                                           */
/*                                                                                          */
/*                                                                                          */
/*     Autor:             Constantin Alexandru Mauro                                        */
/*                                                                                          */
/*     Zielsystem:        Cynetik Mainboard, Prozessor: Atmega8535                          */
/*     IDE/C-Compiler:    AVR Studio 4                                                      */
/*                                                                                          */
/*     Letzte Änderung:   01.11.2015                                                        */
/*                                                                                          */
/*     Datei:             Cynetik.c                                                         */
/*                                                                                          */
/********************************************************************************************/

// Defines

#define F_CPU 4096000L
#define F_PWM         100L               // PWM-Frequenz in Hz
#define PWM_PRESCALER 8                  // Vorteiler für den Timer
#define PWM_STEPS     256                // PWM-Schritte pro Zyklus(1..256)
#define PWM_PORT      PORTD              // Port für PWM
#define PWM_DDR       DDRD               // Datenrichtungsregister für PWM
#define PWM_CHANNELS  8                  // Anzahl der PWM-Kanäle
#define T_PWM (F_CPU/(PWM_PRESCALER*F_PWM*PWM_STEPS)) // Systemtakte pro PWM-Takt
#define max7219_PORT PORTB
#define max7219_DDR DDRB
#define max7219_CLK PB7
#define max7219_LOAD PB6
#define max7219_DIN PB5
#define PD3 3

#if ((T_PWM*PWM_PRESCALER)<(111+5))
    #error T_PWM zu klein, F_CPU muss vergrössert werden oder F_PWM oder PWM_STEPS verkleinert werden
#endif
 
#if ((T_PWM*PWM_STEPS)>65535)
    #error Periodendauer der PWM zu gross! F_PWM oder PWM_PRESCALER erhöhen.   
#endif

// Includes

#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <avr/interrupt.h>

// globale Variablen

uint8_t out;

uint16_t pwm_timing[PWM_CHANNELS+1];          // Zeitdifferenzen der PWM Werte
uint16_t pwm_timing_tmp[PWM_CHANNELS+1];      
 
uint8_t  pwm_mask[PWM_CHANNELS+1];            // Bitmaske für PWM Bits, welche gelöscht werden sollen
uint8_t  pwm_mask_tmp[PWM_CHANNELS+1];        // ändern uint16_t oder uint32_t für mehr Kanäle
 
uint8_t  pwm_setting[PWM_CHANNELS];           // Einstellungen für die einzelnen PWM-Kanäle
uint8_t  pwm_setting_tmp[PWM_CHANNELS+1];     // Einstellungen der PWM Werte, sortiert
                                              // ändern auf uint16_t für mehr als 8 Bit Auflösung   
volatile uint8_t pwm_cnt_max=1;               // Zählergrenze, Initialisierung mit 1 ist wichtig!
volatile uint8_t pwm_sync;                    // Update jetzt möglich

// Pointer
 
uint16_t *isr_ptr_time  = pwm_timing;
uint16_t *main_ptr_time = pwm_timing_tmp;
 
uint8_t *isr_ptr_mask  = pwm_mask;              // Bitmasken fuer PWM-Kanäle
uint8_t *main_ptr_mask = pwm_mask_tmp;          // ändern uint16_t oder uint32_t für mehr Kanäle

// Funktionen

void long_delay (uint8_t ms) 
{
    for (; ms>0; ms--) _delay_ms (10);
}

void tausche_zeiger(void) 
{
    uint16_t *tmp_ptr16;
    uint8_t *tmp_ptr8;                          // ändern uint16_t oder uint32_t für mehr Kanäle 
    tmp_ptr16 = isr_ptr_time;
    isr_ptr_time = main_ptr_time;
    main_ptr_time = tmp_ptr16;
    tmp_ptr8 = isr_ptr_mask;
    isr_ptr_mask = main_ptr_mask;
    main_ptr_mask = tmp_ptr8;
}

void pwm_update(void) 
{ 
    uint8_t i, j, k;
    uint8_t m1, m2, tmp_mask;                   // ändern uint16_t oder uint32_t für mehr Kanäle    
    uint8_t min, tmp_set;                       // ändern auf uint16_t für mehr als 8 Bit Auflösung
 
    // PWM Maske für Start berechnen
    // gleichzeitig die Bitmasken generieren und PWM Werte kopieren
 
    m1 = 1;
    m2 = 0;

    for(i=1; i<=(PWM_CHANNELS); i++) 
	{
        main_ptr_mask[i]=~m1;                       // Maske zum Löschen der PWM Ausgänge
        pwm_setting_tmp[i] = pwm_setting[i-1];
        if (pwm_setting_tmp[i]!=0) m2 |= m1;        // Maske zum setzen der IOs am PWM Start
        m1 <<= 1;
    }

    main_ptr_mask[0]=m2;                            // PWM Start Daten 
 
    // PWM settings sortieren; Einfügesortieren
 
    for(i=1; i<=PWM_CHANNELS; i++) 
	{
        min=PWM_STEPS-1;
        k=i;

        for(j=i; j<=PWM_CHANNELS; j++) 
		{
            if (pwm_setting_tmp[j]<min) 
			{
                k=j;                                // Index und PWM-setting merken
                min = pwm_setting_tmp[j];
            }
        }

        if (k!=i) 
		{
            // ermitteltes Minimum mit aktueller Sortiertstelle tauschen
            tmp_set = pwm_setting_tmp[k];
            pwm_setting_tmp[k] = pwm_setting_tmp[i];
            pwm_setting_tmp[i] = tmp_set;
            tmp_mask = main_ptr_mask[k];
            main_ptr_mask[k] = main_ptr_mask[i];
            main_ptr_mask[i] = tmp_mask;
        }
    }
 
    // Gleiche PWM-Werte vereinigen, ebenso den PWM-Wert 0 löschen falls vorhanden
 
    k=PWM_CHANNELS;             // PWM_CHANNELS Datensätze
    i=1;                        // Startindex
 
    while(k>i) 
	{
        while ( ((pwm_setting_tmp[i]==pwm_setting_tmp[i+1]) || (pwm_setting_tmp[i]==0))  && (k>i) ) 
		{
            // aufeinanderfolgende Werte sind gleich und können vereinigt werden
            // oder PWM Wert ist Null

            if (pwm_setting_tmp[i]!=0)
                main_ptr_mask[i+1] &= main_ptr_mask[i];        // Masken vereinigen
 
            // Datensatz entfernen,
            // Nachfolger alle eine Stufe hochschieben

            for(j=i; j<k; j++) 
			{
                pwm_setting_tmp[j] = pwm_setting_tmp[j+1];
                main_ptr_mask[j] = main_ptr_mask[j+1];
            }
            k--;
        }
        i++;
    }
 
    // letzten Datensatz extra behandeln
    // Vergleich mit dem Nachfolger nicht möglich, nur löschen
    // gilt nur im Sonderfall, wenn alle Kanäle 0 sind
    if (pwm_setting_tmp[i]==0) k--;
 
    // Zeitdifferenzen berechnen
 
    if (k==0) { // Sonderfall, wenn alle Kanäle 0 sind
        main_ptr_time[0]=(uint16_t)T_PWM*PWM_STEPS/2;
        main_ptr_time[1]=(uint16_t)T_PWM*PWM_STEPS/2;
        k=1;
    }
    else {
        i=k;
        main_ptr_time[i]=(uint16_t)T_PWM*(PWM_STEPS-pwm_setting_tmp[i]);
        tmp_set=pwm_setting_tmp[i];
        i--;
        for (; i>0; i--) {
            main_ptr_time[i]=(uint16_t)T_PWM*(tmp_set-pwm_setting_tmp[i]);
            tmp_set=pwm_setting_tmp[i];
        }
        main_ptr_time[0]=(uint16_t)T_PWM*tmp_set;
    }
 
    // auf Sync warten
 
    pwm_sync=0;             // Sync wird im Interrupt gesetzt
    while(pwm_sync==0);
 
    // Zeiger tauschen
    cli();
    tausche_zeiger();
    pwm_cnt_max = k;
    sei();
}

void max7219_clock_out(unsigned char Data)
{
	char i;	
	for(i=0;i<8;i++) {	
		if(Data & (1<<7)) {
			max7219_PORT |= (1<<max7219_DIN);
		} else{
			max7219_PORT &= ~(1<<max7219_DIN);
		}
		Data <<= 1;
		max7219_PORT |= (1<<max7219_CLK); //Clock auf High, Daten werden übernommen
		max7219_PORT &= ~(1<<max7219_CLK); //Clock auf Low
	}
	return;
}

void max7219_send(unsigned char Data, unsigned char Register)
{
	//Register &= 0x0F; //Obere 4 Bits der Adresse werden nciht gelesen.
	max7219_PORT &= ~(1<<max7219_LOAD); // LOAD auf Low (Chip aktivieren)
	max7219_clock_out(Register); //Adresse senden
	max7219_clock_out(Data); //Daten senden
	max7219_PORT |= (1<<max7219_LOAD); // LOAD auf High. Steigende Flanke an High übernimmt Daten in Adressiertes Register.
}

void max7219_set_decodemode(unsigned char Decodemode) {max7219_send(Decodemode, 0x09);}
void max7219_intensity(unsigned char Intensity) {max7219_send(Intensity, 0x0A);}
void max7219_set_scanlimit(unsigned char Scanlimit) {max7219_send(Scanlimit, 0x0B);} 

void max7219_shutdown(void) {max7219_send(0x00, 0x0C);} 
void max7219_wakeup(void) {max7219_send(0x01, 0x0C);} 

void max7219_displaytest_on(void) {max7219_send(0x01, 0x0F);} 
void max7219_displaytest_off(void) {max7219_send(0x00, 0x0F);} 

void max7219_nop(void) {max7219_send(0x00, 0x00);}

void max7219_clear(void)
{
	for(char i=1;i<9;i++){
		max7219_send(0b00000000, i);
	}
}

void max7219_init(void)
{
	max7219_DDR |= (1<<max7219_DIN) | (1<<max7219_LOAD) | (1<<max7219_CLK); // Die 3 Steurpins zu Ausgängen machen
	max7219_PORT &= ~( (1<<max7219_DIN) | (1<<max7219_CLK) ); // Clock und DIN auf Low Level
	max7219_PORT |= (1<<max7219_LOAD); //LOAD (CS bei 7221) auf High
	max7219_set_decodemode(0); //Keine BCD Wandler. Aller Segmente können individuell angesprochen werden.
	max7219_set_scanlimit(2); //Alle zeichen aktivieren
	max7219_intensity(15);	//Helligkeitsstufe 8 ist ein gutes Mittelmaß
	max7219_displaytest_on();
    long_delay (200); 
    max7219_displaytest_off();
	max7219_clear(); //Display zunächst leeren.
	max7219_wakeup();
}

//Tabelle für Hexadezimalzaheln
static const unsigned char Symbol[] = {0b01111110,0b00110000,0b01101101,0b01111001,0b00110011,0b01011011,0b01011111,0b01110000,0b01111111,0b01111011,0b01110111,0b00011111,0b01001110,0b00111101,0b01001111,0b01000111};

void max7219_hex(unsigned char Number, unsigned char Position)
{
	unsigned char Segments;

	if(Number > 15) {Segments = 0x00;}
	else {Segments = Symbol[Number];}

	max7219_send(Segments, Position);
}

void max7219_disp_uint8(uint8_t Number)
{
	char Digits = 3; //Maximal 3 Stellen (255)
		 if(Number<10)   {Digits = 1;}
	else if(Number<100)  {Digits = 2;}
	
	char i;
	
	for(i=1;i<=Digits;i++)
	{	
		max7219_hex(Number%10,i);
		Number/=10;
	}
	for(;i<=3;i++){max7219_send(0b00000000, i);} //Führende Nullen nicht anzeigen
}

void cap_button (void) 
{
    if (PIND & 0x04) 
	{
	    long_delay (40);
        if (!(PINC & 0x04)) 
		{
		    PORTC = 0xF7;
			out = 0;
		} 
		else if (!(PINC & 0x08)) 
		{
            PORTC = 0xEF;
			out = 1;
        }
		else if (!(PINC & 0x10)) 
		{
            PORTC = 0xDF;
			out = 2;
        } 
		else if (!(PINC & 0x20)) 
		{
		    PORTC = 0xBF;
			out = 3;
        }  
		else if (!(PINC & 0x40)) 
		{
		    PORTC = 0x7F;
			out = 4;
        } 
		else if (!(PINC & 0x80)) 
		{
		    PORTC = 0xFB;
			out = 5;
        }       
    }
}

void ADC_Init (void) 
{
    ADMUX = (1<<REFS0)|(1<<ADLAR);
	ADCSRA = (1<<ADPS2)|(1<<ADPS0);
	ADCSRA |= (1<<ADEN);
	ADCSRA |= (1<<ADSC);
	while (ADCSRA & (1<<ADSC)) { }
	(void) ADCW;
}

uint8_t ADC_Read (uint8_t channel)
{
    ADMUX = (ADMUX & ~(0x0F))|(channel & 0x0F);
	ADCSRA |= (1<<ADSC);
	while (ADCSRA & (1<<ADSC)) { }
	return ADCH;
}

ISR (TIMER0_COMP_vect)
{
    PORTD ^= (1<<PD3);
}

ISR(TIMER1_COMPA_vect) 
{
    static uint8_t pwm_cnt;                     // ändern auf uint16_t für mehr als 8 Bit Auflösung
    uint8_t tmp;                                // ändern uint16_t oder uint32_t für mehr Kanäle
 
    OCR1A += isr_ptr_time[pwm_cnt];
    tmp    = isr_ptr_mask[pwm_cnt];
 
    if (pwm_cnt == 0) 
	{
        PWM_PORT = tmp;                         // Ports setzen zu Begin der PWM
                                                // zusätzliche PWM-Ports hier setzen
        pwm_cnt++;
    }
    else 
	{
        PWM_PORT &= tmp;                        // Ports löschen
                                                // zusätzliche PWM-Ports hier setzen
        if (pwm_cnt == pwm_cnt_max) 
		{
            pwm_sync = 1;                       // Update jetzt möglich
            pwm_cnt  = 0;
        }
        else pwm_cnt++;
    }
}

/********************************************************************************************/
/*** Start des Hauptprogramms ***************************************************************/
/********************************************************************************************/

int main (void) 
{
   DDRA  = 0x00;
   DDRB  = 0xE0;
   DDRC  = 0xFF;
   PWM_DDR = 0xFB;         // Port als Ausgang
   
   PORTC = 0xFB;

   // Timer 0 konfigurieren
   TCCR0 = (1<<WGM01); // CTC Modus
   TCCR0 |= (1<<CS00); // Prescaler 1
   // (1/80000)/(1/(4096000/1)) = 51
   OCR0 = 51-1;
 
   // Compare Interrupt erlauben
   TIMSK |= (1<<OCIE0);

   // Timer 1 OCRA1, als variablen Timer nutzen
 
   TCCR1B = 2;             // Timer läuft mit Prescaler 8
   TIMSK |= (1<<OCIE1A);   // Interrupt freischalten
 
   sei();                  // Interrupts global einschalten

   uint8_t adc0, adc1, adc2, temp=0, f0=0, f1=0, f2=0, reset=0, old_value=0, t1[8];
   uint8_t result0=0, result1=0, result2=0, result3=0, result4=0, result5=0;
   uint16_t count=0;
   volatile uint8_t tmp;


   max7219_init ();
   ADC_Init ();
   
   while(1) 
   {
	   cap_button();

	   adc0 = ADC_Read (0);
       adc1 = ADC_Read (1);
	   adc2 = ADC_Read (2);

	   if (out==0)
	   {
	       temp = result0;
       }
	   else if (out==1)
	   {
	       temp = result1;
       }
	   else if (out==2)
	   {
	       temp = result2;
       }
	   else if (out==3)
	   {
	       temp = result3;
       }
	   else if (out==4)
	   {
	       temp = result4;
       }
	   else if (out==5)
	   {
	       temp = result5;
       }

       if (reset==0)
	   {
	       if (adc0<230)
	       {
		       f0 = 0;
		       f1 = 0;
		       f2 = 0;
           }
	       else if (adc2<230)
	       {
		       f0 = 1;
		       f1 = 1;
		       f2 = 1;
           } 

	       if (adc0<50)
	       {
		       if (f0==0)
			   {
			       f0=1;
               }
			   else 
			   {
			       f0=0;
               }
           }
	       else if ((adc1<50) && (f0==1))
	       {
	           if (f1==0)
			   {
			       f1=1;
               }
			   else 
			   {
			       f1=0;
               }
           }
           else if ((adc2<50) && (f0==1) && (f1==1))
           {
	           if (f2==0)
			   {
			       f2=1;
               }
			   else 
			   {
			       f2=0;
               }
           }

           if ((230>adc0) && (adc0>180) && (temp==0 || temp==26))
	       {
	           temp = 0;
           }
	       else if ((180>adc0) && (adc0>110) && (f0==0) && (temp==0 || temp==26 || temp==51))
	       {
	           temp = 26;
           }
           else if ((adc0<110) && (temp==26 || temp==51 || temp==77))
           {
	           temp = 51;
           }
           else if ((230>adc0) && (adc0>110) && (f0==1) && (temp==51 || temp==77 || temp==102))
	       {
	           temp = 77;
           }
           else if ((230>adc1) && (adc1>110) && (f1==0) && (temp==77 || temp==102 || temp==128)) 
	       {
               temp = 102;
           } 
	       else if ((adc1<110) && (temp==102 || temp==128 || temp==153)) 
	       {
               temp = 128;
           } 
	       else if ((230>adc1) && (adc1>110) && (f1==1) && (temp==128 || temp==153 || temp==179)) 
	       {
               temp = 153;
           } 
	       else if ((230>adc2) && (adc2>110) && (f2==0) && (temp==153 || temp==179 || temp==204)) 
	       {
               temp = 179;
           } 
	       else if ((adc2<110) && (temp==179 || temp==204 || temp==230)) 
	       {
               temp = 204;
           } 
	       else if ((180>adc2) && (adc2>110) && (f2==1) && (temp==204 || temp==230 || temp==255)) 
	       {
               temp = 230;
           } 
	       else if ((230>adc2) && (adc2>180) && (temp==230 || temp==255)) 
	       {
               temp = 255;
           }
       
	       if ((old_value==temp) && (adc0<230 || adc1<230 || adc2<230))
	       {
	           _delay_ms (10);
		       count++;
           }
	       else
	       {
	           count = 0;
           }
       } 

	   if ((count==300) || (reset==1))
	   {
	       reset=1;
		   _delay_ms (10);
		   count++;
       }

	   if (count==600)
	   {
	       reset=0;
		   count=0;
       }

	   old_value=temp;

	   if (temp==0)
	   {
           max7219_send(0b11111111, 1);  // 7-Segment-Anzeige: 0%
	       max7219_send(0b10000000, 2);
	       max7219_send(0b11111111, 3);
	   }
	   else if (temp==26)
	   {
           max7219_send(0b11001111, 1);  // 7-Segment-Anzeige: 10%
	       max7219_send(0b10110000, 2);
	       max7219_send(0b11111111, 3);
	   }
	   else if (temp==51)
	   {
           max7219_send(0b10010011, 1);  // 7-Segment-Anzeige: 20%
	       max7219_send(0b11101101, 2);
           max7219_send(0b11111110, 3);
	   }
	   else if (temp==77)
	   {
           max7219_send(0b10000111, 1);  // 7-Segment-Anzeige: 30%
	       max7219_send(0b11111001, 2);
	       max7219_send(0b11111110, 3);
	   }
	   else if (temp==102)
	   {
           max7219_send(0b11001101, 1);  // 7-Segment-Anzeige: 40%
	       max7219_send(0b10110011, 2);
	       max7219_send(0b11111110, 3);
	   }
	   else if (temp==128)
	   {
           max7219_send(0b10100101, 1);  // 7-Segment-Anzeige: 50%
	       max7219_send(0b11011011, 2);
	       max7219_send(0b11111110, 3);
	   }
	   else if (temp==153)
	   {
           max7219_send(0b10100001, 1);  // 7-Segment-Anzeige: 60%
	       max7219_send(0b11011111, 2);
	       max7219_send(0b11111110, 3);
	   }
	   else if (temp==179)
	   {
           max7219_send(0b10001111, 1);  // 7-Segment-Anzeige: 70%
	       max7219_send(0b11110000, 2);
	       max7219_send(0b11111111, 3);
	   }
	   else if (temp==204)
	   {
           max7219_send(0b10000001, 1);  // 7-Segment-Anzeige: 80%
	       max7219_send(0b11111111, 2);
	       max7219_send(0b11111110, 3);
	   }
	   else if (temp==230)
	   {
           max7219_send(0b10000101, 1);  // 7-Segment-Anzeige: 90%
	       max7219_send(0b11111011, 2);
	       max7219_send(0b11111110, 3);
	   }
	   else if (temp==255)
	   {
           max7219_send(0b10000001, 1);  // 7-Segment-Anzeige: 100%
	       max7219_send(0b11001111, 2);
           max7219_send(0b11001111, 3);
	   }

       if (out==0)
	   {
	       result0 = temp;
		   t1[0] = result0;
       }
	   else if (out==1)
	   {
	       result1 = temp;
		   t1[1] = result1;
       }
	   else if (out==2)
	   {
	       result2 = temp;
		   t1[4] = result2;
       }
	   else if (out==3)
	   {
	       result3 = temp;
           t1[5] = result3;
       }
       else if (out==4)
	   {
	       result4 = temp;
		   t1[6] = result4;
       }
	   else if (out==5)
	   {
	       result5 = temp;
		   t1[7] = result5;
       }

	   t1[2] = 0;
	   t1[3] = 0;

	   // Messung der Interruptdauer

       tmp =1;
       tmp =2;
       tmp =3;
 
       // Debug 
 
       memcpy(pwm_setting, t1, 8);
       pwm_update();

/*     
       max7219_send(0b11111111, 1);  // 7-Segment-Anzeige: 0%
	   max7219_send(0b10000000, 2);
	   max7219_send(0b11111111, 3);
	   long_delay (100);
       max7219_send(0b11001111, 1);  // 7-Segment-Anzeige: 10%
	   max7219_send(0b10110000, 2);
	   max7219_send(0b11111111, 3);
	   long_delay (100);
       max7219_send(0b10010011, 1);  // 7-Segment-Anzeige: 20%
	   max7219_send(0b11101101, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b10000111, 1);  // 7-Segment-Anzeige: 30%
	   max7219_send(0b11111001, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b11001101, 1);  // 7-Segment-Anzeige: 40%
	   max7219_send(0b10110011, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b10100101, 1);  // 7-Segment-Anzeige: 50%
	   max7219_send(0b11011011, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b10100001, 1);  // 7-Segment-Anzeige: 60%
	   max7219_send(0b11011111, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b10001111, 1);  // 7-Segment-Anzeige: 70%
	   max7219_send(0b11110000, 2);
	   max7219_send(0b11111111, 3);
	   long_delay (100);
	   max7219_send(0b10000001, 1);  // 7-Segment-Anzeige: 80%
	   max7219_send(0b11111111, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b10000101, 1);  // 7-Segment-Anzeige: 90%
	   max7219_send(0b11111011, 2);
	   max7219_send(0b11111110, 3);
	   long_delay (100);
       max7219_send(0b10000001, 1);  // 7-Segment-Anzeige: 100%
	   max7219_send(0b11001111, 2);
	   max7219_send(0b11001111, 3);
	   long_delay (100);
*/ 
/*
       max7219_hex (16, 1);
	   max7219_hex (16, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (1, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (2, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (3, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (4, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (5, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (6, 2);
       max7219_hex (0, 3);
	   long_delay (100);
	   max7219_hex (16, 1);
	   max7219_hex (7, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (8, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (16, 1);
	   max7219_hex (9, 2);
       max7219_hex (0, 3);
	   long_delay (100);
       max7219_hex (1, 1);
	   max7219_hex (0, 2);
       max7219_hex (0, 3);
	   long_delay (100);
*/
   }
   return 0;                
}

/********************************************************************************************/
/*** Ende des Hauptprogramms, d.h. Ende des gesamten Programms! *****************************/
/********************************************************************************************/
