Version avec sortie ABCD sur même connecteur

Dependencies:   SDFileSystemDMA mbed

Fork of DmdFullRGB_0_1 by Christophe Girardot

SD.h

Committer:
Aganyte
Date:
2017-12-02
Revision:
0:d5f38b9d7c7a
Child:
1:353c1902483f

File content as of revision 0:d5f38b9d7c7a:

/*  Librairie de gestion de la carte SD d'un DMD RGB 128x32 pixels
*   - 256 Couleurs mode RGB332 et Monochrome -
*   decembre 2017 par Christophe Girardot Aka Aganyte
*/

#define SPI_CLOCK_HZ    ( 25 * 1000000 ) // Vitesse de communication SPI 25 MHz

SDFileSystem sd(MOSI, MISO, SCLK, CS, "sd", SPI_CLOCK_HZ); // Ouverture de la liaison SPI

FileHandle* file;   // Création d'un objet pour la gestion du fichier de donnée
FileHandle* Index;  // Création d'un objet pour la gestion du fichier d'index

char FileName[13];      // Stockage du nom du fichier actuellement en cours de lecture 8 Caractères + ".BIN" + "\0"
char Character[1];      // Stockage d'un caractère (doit être un tableau)
char Line_Buffer[17];   // Stockage d'une ligne de 16 caractères + "\0"

/* Fonction qui vide une chaine de caractère
*
*/
void Flush_ascii_buffer(char *buffer)
{
    unsigned int count = 0;
    while(buffer[count] != 0)
    {
        buffer[count]=0;
        count++;
    }
}

/* Fonction de lecture d'un fichier de donnée (les données lues son placées dans le buffer de lecture) 
*  Renvois le nombre de caractères lu, 0 si rien à lire
*/
unsigned int read4KB()
{
    unsigned int readed = 0;
    
    if (file != NULL) 
        readed = file->read(Display_Ram, 4096);
    else
        pc.printf("Impossible de lire le fichier\n");
            
    return(readed);
}

/* Fonction de lecture d'un fichier de donnée de scrolling (les données lues son placées dans le buffer du scrolling) 
*  Renvois le nombre de caractères lu, 0 si rien à lire
*/
unsigned int read40KB()
{
    unsigned int readed = 0;
    
    if (file != NULL) 
        readed = file->read(Scrolling_Buffer, 40960);
    else
        pc.printf("Impossible de lire le fichier\n");
            
    return(readed);
}

/* Fonction qui recherche un caractère dans le fichier index.txt
*  ou revient au début si fin du fichier
*/
void Search_Char(char ThisChar)
{
    char Char[1];
    if(Index==NULL)
        Index = sd.open("index.TXT", O_RDONLY); // Si besoin, première ouverture du fichier index
    while( Char[0] != ThisChar ) // Chercher le signe =
    {
        Index->read(Char, 1); // lire un caractère
        if(Char[0] == '#')// si fin de fichier
        {
            pc.printf("Fin du fichier index.txt\n");
            delete Index; // Fermer le fichier
            Index = sd.open("index.TXT", O_RDONLY); // ré-ouvrir le fichier index
        }
    }
}

/* Fonction qui lit le fichier timestamp.txt
*/
void Read_Timestamp()
{
    unsigned char try_read = 0;
    FileHandle* Timestamp;
    while(1)
    {
        delete Timestamp;
        Timestamp = sd.open("time.TXT", O_RDONLY); // ouverture du fichier timestamp.TXT
        if(Timestamp != NULL)
        {
            pc.printf("Fichier time.txt ouvert\n");
            break; // Si le fichier est bien ouvert, quitter
        }
        try_read++;
        if(try_read > 10) { // Si le fichier n'est pas ouvert après 10 tentative quitter
            pc.printf("Plus de 10 tentatives de lecture du fichier -> probleme sur le fichier time.txt\n");
            break;
        }
    }

    Timestamp->read(Line_Buffer, 10); // lire 16 caractères
    Actual_timestamp = atol(Line_Buffer) + 3600; // Convertion de la valeur de Ascii vers un entier et rajouter une heure pour la France
    pc.printf("lecture de %d dans le fichier time.TXT\n",Actual_timestamp);
    Flush_ascii_buffer(Line_Buffer); // Vider le tampon
    delete Timestamp; // Fermer le fichier
}

/* Fonction d'ouverture d'un fichier sur la carte SD
*  avec 10 tentatives de lecture avant de déclarer un problème
*/
void Try_Open_File()
{
    unsigned char try_read = 0;
    while(1) 
    {
        delete file; // effacer l'objet file
        file = sd.open(FileName, O_RDONLY);
        if(file != NULL)
            break; // Si le fichier est bien ouvert, quitter
        try_read++;
        if(try_read > 10) // Si le fichier n'est pas ouvert après 10 tentative quitter
        {
            pc.printf("Plus de 10 tentatives de lecture du fichier -> probleme sur le fichier\n");
            break;
        }
    }
}

/* Fonction de lecture d'une animation présente sur la carte SD
*  Attention, le nom du fichier à lire doit déjà être en mémoire
*/
void Animation_SD()
{   
    for(unsigned char count = 0; count < Replay; count++) // Jouer l'animation en fonction du nombre de répétition
    {
        Try_Open_File();    // Essayer d'ouvrir le fichier
        int readed = 0;
        unsigned int image = 0;
        while(1) 
        {
            // Charger une trame dans la mémoire vidéo
            readed = read4KB();
            // détection de la fin de l'animation
            if(readed == 0) 
                break;
            // détection d'un problème de lecture
            if(readed == -1) 
            {
                pc.printf("Erreur de lecture du fichier %s apres %d image(s)\n",FileName,image);
                break;
            }
            // Affichage de la trame avec gestion de la vitesse
            for(unsigned char count = 0; count < (10-Speed); count++)
                refresh();
            // Incrémenter le compteur d'image
            image++;
        }
    }
    pc.printf("fin de l'animation %s\n\n",FileName);
}

/* Fonction de lecture d'une commande d'animation dans le fichier Index.txt
*
*  Exemple d'utilisation:
*
*  >Animation FileName=test0000.BIN Repeat=2 Speed=8
*/
void Read_Animation()
{
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(FileName, 12); // lire le nom de fichier

    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Replay = Character[0]-'0'; // Stocker le nombre de lecture à effectuer

    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire la vitesse de lecture
    Speed = Character[0]-'0';  // stocker la vitesse de lecture
    
    // affichage dans la console
    pc.printf("Lecture de %s\n",FileName);
    pc.printf("Nombre de repetition du fichier : %d\n",Replay);
    pc.printf("Vitesse de lecture : %d\n",Speed);
    
    Animation_SD(); // Lancer l'animation
}

/* Fonction de lecture d'une commande Image dans le fichier Index.txt
*
*  Exemple d'utilisation:
*
*  >Animation FileName=test0000.BIN time=2
*/
void Image_SD()
{
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(FileName, 12); // lire le nom de fichier

    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Sleep = Character[0]-'0'; // Stocker le temps de lecture

    // affichage dans la console
    pc.printf("Affichage de l'image %s pendant %d secondes\n\n",FileName,Sleep);
 
    Try_Open_File();    // Essayer d'ouvrir le fichier
    
    read4KB(); // Charger une trame dans la mémoire vidéo RGB
    
    Image(Sleep); // Afficher l'image
}

/* Fonction de lecture d'une commande de texte dans le fichier Index.txt
*
*  Exemple d'utilisation:
*
*  >Write Temp=5 L1=XXXXXXXXXXXXXXXX L2=XXXXXXXXXXXXXXXX L3=XXXXXXXXXXXXXXXX L4=XXXXXXXXXXXXXXXX
*/
void Read_Text()
{
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Sleep = Character[0]-'0'; // Stocker le temps d'affichage
 
    pc.printf("Affichage d'un texte pendant %d secondes\n",Sleep); // affichage dans la console
 
    // Placer les 4 lignes dans le buffer vidéo monochrome
    for(unsigned char count = 1; count<5; count++)
    {
        Search_Char('='); // lire jusqu'au prochain =
        Index->read(Line_Buffer, 16); // lire la ligne
        print_4_16(Line_Buffer,count); // Ecrire la ligne dans le buffer vidéo monochrome
        pc.printf("Ligne %d = %s\n",count,Line_Buffer); // affichage dans la console
    }
    pc.printf("\n");
    Refresh_in_seconds();  // Rafraichir l'écran pendant x secondes
}

/* Fonction de lecture d'une commande qui superpose une image et du texte dans le fichier Index.txt
*
*  Exemple d'utilisation:
*
*  >Score FileName=test0000.BIN Temp=5 L1=XXXXXXXXXXXXXXXX L2=XXXXXXXXXXXXXXXX L3=XXXXXXXXXXXXXXXX L4=XXXXXXXXXXXXXXXX
*/
void Score_SD()
{
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(FileName, 12); // lire le nom de fichier
    
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Sleep = Character[0]-'0'; // Stocker le temps d'affichage
 
    pc.printf("Affichage d'un score pendant %d secondes\n",Sleep); // affichage dans la console
 
    // Placer les 4 lignes dans le buffer vidéo monochrome
    for(unsigned char count = 1; count<5; count++)
    {
        Search_Char('='); // lire jusqu'au prochain =
        Index->read(Line_Buffer, 16); // lire la ligne
        print_4_16(Line_Buffer,count); // Ecrire la ligne dans le buffer vidéo monochrome
        pc.printf("Ligne %d = %s\n",count,Line_Buffer); // affichage dans la console
    }
    pc.printf("\n");
    Try_Open_File();    // Essayer d'ouvrir le fichier
    
    read4KB(); // Charger une trame dans la mémoire vidéo RGB
    
    Convert_Mono_To_RGB(); // Convertir le buffer mono avec superposition dans le buffer couleur
    
    Image(Sleep); // Afficher l'image
    
    //Refresh_in_seconds();
}

/* Fonction de lecture d'une commande de réglage des couleurs
*
*  Exemple d'utilisation:
*
*  >SetColor R=1 G=0 B=0
*/
void Set_Color()
{
    unsigned char CR;
    unsigned char CG;
    unsigned char CB;
    
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    CR = Character[0]-'0';  // stocker la valeur de la couleur rouge
    
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    CG = Character[0]-'0';  // stocker la valeur de la couleur vert
    
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    CB = Character[0]-'0';  // stocker la valeur de la couleur bleu
    
    pc.printf("Reglages des couleurs du mode monochrome avec R=%d,G=%d,B=%d\n\n",CR,CG,CB); // affichage dans la console
    Color_R = CR;
    Color_B = CB;
    Color_G = CG;
}

/* Fonction de lecture d'une commande horloge
*
*  Exemple d'utilisation:
*
*  >Clock Temp=5
*/
void Read_Clock()
{
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Sleep = Character[0]-'0'; // Stocker le temps d'affichage
    
    pc.printf("Affichage de l'heure pendant %d secondes\n\n",Sleep); // affichage dans la console
    
    Clock();
}

/* Fonction de lecture d'une commande temperature
*
*  Exemple d'utilisation:
*
*  >Temperature Temp=5
*/
void Read_Temperature()
{
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Sleep = Character[0]-'0'; // Stocker le temps d'affichage
    
    pc.printf("Affichage de la temperature pendant %d secondes\n\n",Sleep); // affichage dans la console
    
    Temperature();
}


/* Fonction de lecture d'une commande lecture de la pile de backup
*
*  Exemple d'utilisation:
*
*  >Battery Temp=5
*/
void Read_Backup()
{
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le nombre de répétition
    Sleep = Character[0]-'0'; // Stocker le temps d'affichage
    
    pc.printf("Affichage de la tension de la batterie pendant %d secondes\n\n",Sleep); // affichage dans la console
    
    Backup();
}
    
/* Fonction de lecture d'une commande de scrolling vertical dans le fichier Index.txt
*  ATTENTION => La hauteur est à remplir sur 3 digits (max 320 pixels de haut)
*  Exemple d'utilisation:
*
*  >Vertical FileName=test0000.BIN height=128 Speed=8 Up=1
*/
void Vertical_Scrolling_SD()
{
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(FileName, 12); // lire le nom de fichier
    
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(Line_Buffer, 3); // lire 16 caractères
    unsigned int height = atoi(Line_Buffer); // Convertion de la valeur de Ascii vers un entier

    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire la vitesse de lecture
    Speed = Character[0]-'0';  // stocker la vitesse de lecture
    
    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le sens de lecture
    Up = Character[0]-'0';  // stocker le sens de lecture
    
    Try_Open_File(); // Ouvrir le fichier
    
    read40KB(); // Charger le scrolling dans la mémoire
    
    pc.printf("Affichage du scrolling vertical %s de 128x%d pixels depuis la carte SD a la vitesse de %d avec Up=%d\n\n",FileName,height,Speed,Up);
    
    if(Up!=1)
    {
        for(unsigned char decal = 0; decal<(height-32); decal++) {
            // Remplir la mémoire vidéo avec une image
            for(unsigned int count = 0; count<4096; count++)
                Display_Ram[count] = Scrolling_Buffer[(decal*128)+count];
            // Affichage de la trame avec gestion de la vitesse
            for(unsigned char count = 0; count < (10-Speed); count++)
                refresh();
        }
    }
    else
    {

        for(unsigned char decal = (height-32); decal!=0; decal--) {
            // Remplir la mémoire vidéo avec une image
            for(unsigned int count = 0; count<4096; count++)
                Display_Ram[count] = Scrolling_Buffer[(decal*128)+count];
            // Affichage de la trame avec gestion de la vitesse
            for(unsigned char count = 0; count < (10-Speed); count++)
                refresh();
        }
    }
    Flush_ascii_buffer(Line_Buffer);
}

/* Fonction de lecture d'une commande de scrolling horizontal dans le fichier Index.txt
*  ATTENTION => La hauteur est à remplir sur 4 digits (max 1280 pixels de large)
*  Exemple d'utilisation:
*
*  >Horizontal FileName=test0000.BIN height=0128 Speed=8
*/
void Horizontal_Scrolling_SD()
{
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(FileName, 12); // lire le nom de fichier
    
    Search_Char('='); // lire jusqu'au prochain =
    Index->read(Line_Buffer, 4); // lire 16 caractères
    unsigned int width = atoi(Line_Buffer); // Convertion de la valeur de Ascii vers un entier

    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire la vitesse de lecture
    Speed = Character[0]-'0';  // stocker la vitesse de lecture

    Search_Char('=');  // lire jusqu'au prochain =
    Index->read(Character, 1); // Lire le sens de lecture
    Left = Character[0]-'0';  // stocker le sens de lecture
    
    Try_Open_File(); // Ouvrir le fichier
    
    read40KB(); // Charger le scrolling dans la mémoire
    
    pc.printf("Affichage du scrolling horizontal %s de %dx32 pixels depuis la carte SD a la vitesse de %d avec Left=%d\n\n",FileName,width,Speed,Left);
    
    if(Left==1)
    {
        for(unsigned int image = 0 ; image < width-128; image++) {
            // Remplir la mémoire vidéo avec une ligne
            for(unsigned char ligne = 0; ligne<32; ligne++) {
                for(unsigned char count = 0 ; count<128 ; count++)
                    Display_Ram[count+(ligne*128)] = Scrolling_Buffer[image+count+(width*ligne)];
            }
            // Affichage de la trame avec gestion de la vitesse
            for(unsigned char count = 0; count < (10-Speed); count++)
                refresh();
        }
    }
    else
    {
        for(unsigned int image = width-128 ; image !=0 ; image--) {
            // Remplir la mémoire vidéo avec une ligne
            for(unsigned char ligne = 0; ligne<32; ligne++) {
                for(unsigned char count = 0 ; count<128 ; count++)
                    Display_Ram[count+(ligne*128)] = Scrolling_Buffer[image+count+(width*ligne)];
            }
            // Affichage de la trame avec gestion de la vitesse
            for(unsigned char count = 0; count < (10-Speed); count++)
                refresh();
        }
    }
    Flush_ascii_buffer(Line_Buffer);
}

/* Lire et effectuer la prochaine commade du fichier index.txt */
void Read_Next_Command()
{
    Search_Char('>'); // Chercher le prochain début de commande
    Index->read(Command, 5); // lire la commande

    if( strcmp("Anima", Command) == 0)      // A => Animation
        Read_Animation();
    else if(strcmp("Write", Command) == 0) // W => Write
        Read_Text();
    else if(strcmp("Clock", Command) == 0)
        Read_Clock();       // C => Clock
    else if(strcmp("Tempe", Command) == 0)
        Read_Temperature(); // T => Temperature
    else if(strcmp("Backu", Command) == 0)
        Read_Backup();      // B => pile de Backup
    else if(strcmp("Setco", Command) == 0)
        Set_Color();        // S => changement des couleurs du mode monochrome
    else if(strcmp("Verti", Command) == 0)
        Vertical_Scrolling_SD(); // V => Scrolling vertical depuis la SD
    else if(strcmp("Horiz", Command) == 0)
        Horizontal_Scrolling_SD(); // H => Scrolling Horizontal depuis la SD
    else if(strcmp("Image", Command) == 0)
        Image_SD(); // I => Image depuis la SD
    else if(strcmp("Score", Command) == 0)
        Score_SD(); // I => Superposer une Image avec du texte depuis la SD (scores)
    else
        pc.printf("Aucune Commande dans le fichier index.ini\n");
}