/*! \file sketch.cpp
    \brief Emulation sketch Arduino pour le CESI.
    \author Bertrand Vandeportaele IUT GEII
    \date  14/02/2022
*/
#include "sketch.h"
#include "cstatemachine.h"
#include "lib_io_tp.h"
 
////////////////////////////////////////////////////////////////////
//! fonction d'affichage d'un message de debug bien pratique,
//! qui affiche un message texte, le nom du fichier et le numéro de la ligne
//! depuis où la fonction a été appelée
void debugMessage(const char * chaineMsg,const char * chaineFile,const unsigned int line){
printf("DEBUG %s : l %d : %s\n",chaineFile,line,chaineMsg);
flush(std::cout);
}
//programme de test
void programmeDeTest1(){
//! Le composant à tester
CStateMachine mae;
printf("\nTest lancé le ");
printf("%s",__DATE__ );
printf(" à ");
printf("%s",__TIME__ );
printf("\nFonction de test: ");
printf(__func__);
//boucle pour gérer les différents cas à tester
int ntest=1;
printf("\ndébut du test numéro: ");
printf("%d\n",ntest);

mae.reset();
mae.setEntree(0xF);
mae.clock(); //ici on teste la mae sans considération de timing, donc clock() n'est pas conditionné à un timer
mae.clock();
printf("etat = %d\n",mae.getEtat());

//Compléter le test ici:

// Seq etat 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 0

// test etat 0
// 2 coups de clock pour le maintien de l'etat
mae.clock();
mae.clock();
if (mae.getEtat()!=0)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);            // verification qu'on soit bien a l'état 0
if (mae.getSortieBit()!=1)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie moteur = %d\n",mae.getSortieBit(0)); 
// test du passage etat 0 à etat 1
mae.setEntree(0xB); // piece presente et piece nn noire pour passer à l'etat 1
mae.clock();
if (mae.getEtat()!=1)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: Sortie non attendue, __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie moteur = %d\n",mae.getSortieBit(0)); 

// test etat 1
//test passage de etat 1 à 2
mae.setEntree(0xD) // piece presente et piece metal pour passer à l'etat 2
mae.clock();
if (mae.getEtat()!=2)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie moteur = %d\n",mae.getSortieBit(0));

// test etat 2
//test passage etat 2 à 3
mae.setEntreeBit(0,0); // piece presente pour passer à l'etat 3
mae.clock();
if (mae.getEtat()!=3)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie moteur = %d\n",mae.getSortieBit(0));

// test etat 3
mae.setEntree(0x7);//si glissière pleine on reste en 3
mae.clock();
if (mae.getEtat()!=3)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
// test passage etat 3 à 4
mae.setEntree(0xF); // glissière non pleine pour passer à l'etat 4
mae.clock();
if (mae.getEtat()!=4)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(2)!=1)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie switch 2 = %d\n",mae.getSortieBit(3)); // Sortie switch 2

// test etat 4
// test passage etat 4 à 5
mae.setEntree(0x7); // glissière pleine pour passer à l'etat 5
mae.clock();
if (mae.getEtat()!=5)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(2)!=0)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortieBit(2));

// test etat 5
// test passage etat 5 à 0
mae.setEntree(0xF); // glissière non pleine pour passer à l'etat 0
mae.clock();
if (mae.getEtat()!=0)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(2)!=1)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortieBit(2));

// Seq etat 0 -> 9 -> 10 -> 11 -> 0

//test passage 0 à 9
mae.setEntree(0xE);// pièce présente
mae.clock();
if (mae.getEtat()!=9)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=0)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortie());

// test etat 9
// test passage de 9 à 10
mae.setEntree(0xF); // glissière non pleine
mae.clock();
if (mae.getEtat()!=10)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortie());

// test etat 10
//test passage etat 10 à 11
mae.setEntree(0x7); // glissière pleine
mae.clock();
if (mae.getEtat()!=11)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=0)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortie());

// test etat 11
// test passage 11 à 0
mae.setEntree(0xF);// glissière non pleine
mae.clock();
if (mae.getEtat()!=0)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: La sortie pas dans l\'état prévu", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortie());

//Seq etat 0 -> 1 -> 6 -> 7 -> 8 -> 0

// test du passage etat 0 à etat 1
mae.setEntree(0xB); // piece presente et piece nn noire pour passer à l'etat 1
mae.clock();
if (mae.getEtat()!=1)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: Sortie non attendue, __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie moteur = %d\n",mae.getSortieBit(0)); 

//passage etat 1 à 6
mae.setEntreeBit(0,0);
mae.clock();
if (mae.getEtat()!=6)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=0)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortie());

// test etat 6
// test passage 6 à 7
mae.setEntree(0xF);// glissière non pleine
mae.clock();
if (mae.getEtat()!=7)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortie()!=1)  debugMessage("Erreur: Sortie non attendue", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie switch 1 = %d\n",mae.getSortieBit(1)); // Sortie switch 2

// test etat 7
// test passage de 7 à 8 
mae.setEntree(0x7); // glissière pleine
mae.clock();
if (mae.getEtat()!=8)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(0)!=1)  debugMessage("Erreur: La sortie n'est pas dans l\'état prévu", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());
printf("sortie = %d\n",mae.getSortie());

// test etat 8
// test passage etat 8 à 0
mae.setEntree(0xF); // glissière pleine
mae.clock();
if (mae.getEtat()!=0)  debugMessage("Erreur: La MAE n'est pas dans l\'état prévu", __FILE__,  __LINE__);
if (mae.getSortieBit(3)!=1)  debugMessage("Erreur: La sortie n'est pas dans l\'état prévu", __FILE__,  __LINE__);
printf("etat = %d\n",mae.getEtat());

//fin du test
debugMessage("\nFin du test\n", __FILE__,  __LINE__);
exit(0);  //commenter cette ligne pour ne pas quitter le programme après la fin du test
}

void setup(){
    char nom[]="Abate & Perez";
    //adresse ip de la boucle locale pour simulation
    char ip[]="127.0.0.1";
    //adresse ip de la maquette arduino réelle sur le réseau iut gomette bleue
    char ip[]="172.16.6.60";
    char port[]="4242";
    init_millis();    
    int r=setupES(strdup((std::string(ip).data())),strdup((std::string(port).data())));
    setName(strdup((std::string(nom).data())));
    if (r!=0)
        printf("erreur ouverture socket\n");
    printf("Elapsed time: %ld milliseconds\n", millis());
   
    mae.reset();
    programmeDeTest1();
}

void loop(){
    unsigned int periodiciteTache1=10;
    static unsigned long timerTache1 = millis();
    if (millis() - timerTache1 >= periodiciteTache1) {
        timerTache1 += periodiciteTache1;
        
	mae.setEntree(readPort());
    mae.clock();
    writePort(mae.getSortie());
    char chaine[100];
    sprintf(chaine,"etat=%d",mae.getEtat()); 
    printf("%s",chaine);
    setMsg(chaine);

    }
    unsigned int periodiciteTache2=1000;
    static unsigned long timerTache2 = millis();
    if (millis() - timerTache2 >= periodiciteTache2) {
        timerTache2 += periodiciteTache2;
        static unsigned int cpt=0;
        cpt++;

    }
}

74HC165
74HC595