#include "segel.h"
#include <avr/io.h>
#include "signalgast.h"

/*
Winde 1 : Großpiek, INT-Gruppe 2, Timer 4A (Pin 6)
Winde 2 : Großklau, INT-Gruppe 0, Timer 4C (Pin 7)
Winde 3 : Fock (H-Brücke 4), INT-Gruppe 1
*/




segel::segel()
{
    segelstellung = 3;      //Segel unklar
    setcounter=0;
    state_setzen = 1;
    state_bergen = 1;
    state_referenz = 1;
    endwertspeicher[0]=0;   //Inkrement Windengruppe 0 = 0
    endwertspeicher[1]=0;   //Inkrement Windengruppe 1 = 0
    endwertspeicher[2]=0;   //Inkrement Windengruppe 2 = 0



}

void segel::setzen()
//segelnummer : Fock=1, Gross=2, Besan=3
{
    if (segelnummer == 1)       //Fockablauf
    {
        switch (state_setzen)
        {
        case 1 :
            FallInkrement = 0;
            fall_hoch(3,80,180);   //windennummer, drehzahl, endwert
            state_setzen=2;
            break;

        case 2:
            fertig_numerisch();          //testet, ob alle Winden fetig
            if (winde1_running==0 and winde2_running==0 and winde3_running==0)
            {
                state_setzen=3;
            }
            break;

        case 3:
            segelstellung = 1;          //melde: Segel(n) ist oben !
            state_setzen = 1;           //Ablauf von vorne
            break;
        }//ende switch
    }//ende if


    if (segelnummer == 2)       //Ablauf gross
    {
        switch (state_setzen)
        {
            case 1 :
                KlauInkrement = 0;
                PiekInkrement = 0;
                fall_hoch(1,100,6);   //windennummer, drehzahl, endwert
                state_setzen=2;
                break;

            case 2:
                fertig_numerisch();          //testet, ob alle Winden fetig
                if (winde1_running==0 and winde2_running==0 and winde3_running==0)
                {
                    state_setzen=3;
                }
                break;

            case 3 :
                KlauInkrement = 0;
                PiekInkrement = 0;
                fall_hoch(2,100,5);        //windennummer, drehzahl, endwert
                state_setzen=4;
                break;

            case 4:
                fertig_numerisch();          //testet, ob alle Winden fetig
                if (winde1_running==0 and winde2_running==0 and winde3_running==0)
                {
                    setcounter++;
                    if (setcounter > 22)
                    {
                        state_setzen=5;
                    }
                    else
                    {
                        state_setzen=1;
                    }
                 }
                 break;

             case 5 :
                KlauInkrement = 0;
                PiekInkrement = 0;
                fall_hoch(1,100,50);        //windennummer, drehzahl, endwert
                state_setzen=6;
                break;

            case 6:
                fertig_numerisch();          //testet, ob alle Winden fetig
                if (winde1_running==0 and winde2_running==0 and winde3_running==0)
                {
                    state_setzen=7;
                }
                break;

            case 7:
                segelstellung = 1;          //melde: Segel(n) ist oben !
                state_setzen = 1;           //Ablauf von vorne
                setcounter = 0;
                break;
        }//ende switch
    }//ende if
}//ende setzen

void segel::referenz()
{
    switch(state_referenz)
    {
        case 1:
            if (segelnummer == 1)       //Fockablauf (Fock = Segelnummer 1)
            {
                fall_runter(3,100,0);   //windennummer (Fockwinde = Windennmmer 3 ;-), drehzahl
                state_referenz = 2;
            }
            if (segelnummer == 2)       //Grossablauf
            {
                fall_runter(1,110,0);   //windennummer, drehzahl  1*******
                fall_runter(2,110,0);   //windennummer, drehzahl
                state_referenz = 2;
            }
            break;

        case 2 :
            if (segelnummer == 1)       //Fock
            {
                fertig_mechanisch(3);   //Fockfall im Anschlag ?
                if (winde3_running==0)
                {
                    state_referenz = 3;
                }
            }
            if (segelnummer == 2)       //Gross
            {
                fertig_mechanisch(1);   //Grosspiek im Anschlag ?
                fertig_mechanisch(2);   //Grosspiek im Anschlag ?
                if (winde1_running==0 and winde2_running==0)
                {
                    state_referenz = 3;
                }
            }
            break;

        case 3 :
            if (segelnummer == 1)      //Fockablauf
            {
                FallInkrement = 0;
                fall_hoch(3,100,20);   //windennummer, drehzahl, endwert
                state_referenz=4;
            }
            if (segelnummer == 2)      //Ablauf gross
            {
                KlauInkrement = 0;
                PiekInkrement = 0;
                fall_hoch(2,100,3);   //windennummer, drehzahl, endwert
                fall_hoch(1,100,15);   //1 = Piek, 2 = Klau
                state_referenz=4;
            }
            break;

        case 4:
            fertig_numerisch();             //testet, ob alle Winden fertig
            if (winde1_running==0 and winde2_running==0 and winde3_running==0)
            {
                segelstellung = 0;          //melde: Segel(n) ist unten !
                state_referenz = 1;           //Ablauf von vorne
            }
            break;
    }
}

void segel::bergen()
{
     switch (state_bergen)
    {
        case 1:
            if (segelnummer == 1)       //Fockablauf (Fock = Segelnummer 1)
            {
                FallInkrement=0;
                fall_runter(3,80,100);   //windennummer (Fockwinde = Windennmmer 3 ;-), drehzahl
                state_bergen = 2;
            }
            if (segelnummer == 2)       //Grossablauf
            {
                PiekInkrement=0;
                fall_runter(1,100,50);   //windennummer, drehzahl
                state_bergen = 2;
            }
            break;

        case 2 :
            if (segelnummer == 1)       //Fock
            {
                fertig_numerisch();   //Fockfall im Anschlag ?
                if (winde3_running==0)
                {
                    state_bergen = 3;
                }
            }
            if (segelnummer == 2)       //Gross
            {
                fertig_numerisch();   //Grosspiek im Anschlag ?
                if (winde1_running==0 and winde2_running==0)
                {
                    state_bergen = 3;
                }
            }
            break;

        case 3 :
            if (segelnummer == 1)      //Fockablauf
            {
                fall_runter(3,80,0);   //windennummer, drehzahl, endwert
                state_bergen=4;
            }
            if (segelnummer == 2)      //Ablauf gross
            {
                fall_runter(1,110,0);   //windennummer, drehzahl  1*******
                fall_runter(2,110,0);   //windennummer, drehzahl
                state_bergen=4;
            }
            break;

        case 4 :
            if (segelnummer == 1)       //Fock
            {
                fertig_mechanisch(3);   //Fockfall im Anschlag ?
                if (winde3_running==0)
                {
                    state_bergen = 5;
                }
            }
            if (segelnummer == 2)       //Gross
            {
                fertig_mechanisch(1);   //Grosspiek im Anschlag ?
                fertig_mechanisch(2);   //Grosspiek im Anschlag ?
                if (winde1_running==0 and winde2_running==0)
                {
                    state_bergen = 5;
                }
            }
            break;

        case 5 :
            if (segelnummer == 1)      //Fockablauf
            {
                FallInkrement = 0;
                fall_hoch(3,100,10);   //windennummer, drehzahl, endwert
                state_bergen=6;
            }
            if (segelnummer == 2)      //Ablauf gross
            {
                KlauInkrement = 0;
                PiekInkrement = 0;
                fall_hoch(2,100,3);   //windennummer, drehzahl, endwert
                fall_hoch(1,100,15);   //1 = Piek, 2 = Klau
                state_bergen=6;
            }
            break;

        case 6:
            fertig_numerisch();             //testet, ob alle Winden fertig
            if (winde1_running==0 and winde2_running==0 and winde3_running==0)
            {
                segelstellung = 0;          //melde: Segel(n) ist unten !
                state_bergen = 1;           //Ablauf von vorne
            }
            break;
    }
}

void segel::fall_hoch(unsigned char windennummer,unsigned char speed,int endwert)
{
    PCICR = 7;              //Interrupt enable für alle Gruppen
    if (windennummer==1)    //winde_nr = 1, Großpiek, Gruppe 2
    {
        endwertspeicher[2]=endwert;     // die GrossPiek-Winde 1 in Gruppe 2 (Winde1, INT16)
        PCMSK2 = 1;                     // aktiviert PCINT16
        OCR4CL = speed;                 // PWM an Zähler 4c
        PORTA = PORTA | 8;              // PA4 / Pin 25 / IN1 = 1   : Steuerpins der H-Brücke 1
        PORTA = PORTA & (255-16);       // PA3 / Pin 26 / IN2 = 0
        //winde_gr2=1;                    // Meldung : Winde läuft !
        winde1_running = 1;
    }
    if (windennummer==2)    //winde_nr = 2, Großklau, Gruppe 0
    {
        endwertspeicher[0]=endwert;     // die GrossKlau-Winde 2 in Gruppe 0 (Winde2, INT3)
        PCMSK0 = 8;                     // aktiviert PCINT3
        OCR4AL = speed;                 // PWM an Zähler 4a
        PORTA = PORTA | 64;             // PA6 / Pin 28 / IN3 = 1   : Steuerpins der H-Brücke 2
        PORTA = PORTA & (255-128);      // PA7 / Pin 29 / IN4 = 0
        //winde_gr0=1;                    // Meldung : Winde läuft !
        winde2_running = 1;
    }
    if (windennummer==3)    //winde_nr = 3, Fock, Gruppe 1
    {
        endwertspeicher[1]=endwert;     // die Fockfall in Gruppe 1 (Winde3, INT9)
        PCMSK1 = 2;                     // aktiviert PCINT9
        OCR4BL = speed;                 // PWM an Zähler 4b, PH4, Pin PWM7
        PORTC = PORTC | 4;              // PC3 / Pin 34 / IN1 = 0   : Steuerpins der H-Brücke 4
        PORTC = PORTC & (255-8);        // PC2 / Pin 35 / IN2 = 1
        //winde_gr1=1;                    // Meldung : Winde läuft !
        winde3_running = 1;
    }
}

void segel::fall_runter(unsigned char windennummer,unsigned char speed,int endwert)
{
    PCICR = 7;              //Interrupt enable für alle Gruppen
    if (windennummer==1)    //winde_nr = 1, Großpiek, Gruppe 2
    {
        endwertspeicher[2]=endwert;     // die GrossPiek-Winde 1 in Gruppe 2 (Winde1, INT16)
        PCMSK2 = 1;                     // aktiviert PCINT16
        OCR4CL = speed;                 // PWM an Zähler 4c
        PORTA = PORTA | 16;             // PA4 / Pin 25 / IN1 = 1   : Steuerpins der H-Brücke 1
        PORTA = PORTA & (255-8);        // PA3 / Pin 26 / IN2 = 0
        //winde_gr2=1;                    // Meldung : Winde läuft !
        winde1_running = 1;
    }
    if (windennummer==2)    //winde_nr = 2, Großklau, Gruppe 0
    {
        endwertspeicher[0]=endwert;     // die GrossKlau-Winde 2 in Gruppe 0 (Winde2, INT3)
        PCMSK0 = 8;                     // aktiviert PCINT3
        OCR4AL = speed;                 // PWM an Zähler 4a
        PORTA = PORTA | 128;            // PA6 / Pin 28 / IN3 = 1   : Steuerpins der H-Brücke 2
        PORTA = PORTA & (255-64);       // PA7 / Pin 29 / IN4 = 0
        //winde_gr0=1;                    // Meldung : Winde läuft !
        winde2_running = 1;
    }
    if (windennummer==3)    //winde_nr = 3, Fock, Gruppe 1
    {
        endwertspeicher[1]=endwert;     // die Fockfall in Gruppe 1 (Winde4, INT9)
        PCMSK1 = 2;                     // aktiviert PCINT9
        OCR4BL = speed;                 // PWM an Zähler 4b, PH4, Pin PWM7
        PORTC = PORTC | 8;              // PC3 / Pin 34 / IN1 = 0   : Steuerpins der H-Brücke 4
        PORTC = PORTC & (255-4);        // PC2 / Pin 35 / IN2 = 1
        //winde_gr1=1;                    // Meldung : Winde läuft !
        winde3_running = 1;
    }
}

void segel::fertig_numerisch()
//testet für alle windengruppen, ob endwert überschritten
//stoppt die entsprechende winde und meldet vollzug (winde_grx=0)
{

    if (KlauInkrement>endwertspeicher[0] and endwertspeicher[0]!=0)
    {
        PORTA = PORTA & (255-64);                //ende, falls Grosspiek hoch
        PORTA = PORTA & (255-128);               //ende, falls Grosspiek runter
        //winde_gr0=0;
        winde2_running = 0;
    }

    //if (FallInkrement>endwertspeicher[1] and endwertspeicher[1]!=0)
    if (FallInkrement>endwertspeicher[1] and endwertspeicher[1]!=0)
    {
        PORTC = PORTC & (255-4);
        PORTC = PORTC & (255-8);
        //winde_gr1=0;
        winde3_running = 0;
    }
    if (PiekInkrement>endwertspeicher[2] and endwertspeicher[2]!=0)
    {
        PORTA = PORTA & (255-8);
        PORTA = PORTA & (255-16);
        //winde_gr2=0;
        winde1_running = 0;
    }
}


void segel::fertig_mechanisch(unsigned char windennummer)
//testet für alle winden, ob Endschalter erreicht
//stoppt die entsprechende winde und meldet vollzug (winde_grx=0)
//Leider etwas durcheinander :
//Segel 1 (Fock) = Winde 3 -> Gruppe 1
//Segel 2 (Groß) = Winde 1(Piek)-> Gruppe 2 und Winde 2(Klau)-> Gruppe 0
{
    switch (windennummer)
    {
        case 1:

            if (!(PINB & (1 << PINB6)))
            {
                PORTA = PORTA & (255-8);        //Grosspiek am Anschlag : Winde 1 aus
                winde1_running = 0;             //Melde : Winde steht !

            }
            break;


        case 2:

            if (!(PINB & (1 << PINB5)))
            {
                PORTA = PORTA & (255-128);  //Grossklau am Anschlag : Winde 2 aus
                winde2_running = 0;
            }
            break;


        case 3:

            if (!(PINH & (1 << PINH6)))
            {
                PORTC = PORTC & (255-8);    //Anschlag an Fock erreicht : Wind 3 aus
                //winde_gr1=0;
                winde3_running = 0;
            }
            break;
    }
}






