SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Placez ici vos trucs et astuces, étalez sans retenue votre savoir-faire et votre science qui va nous permettre de redonner une apparence neuve et fonctionnelle à nos bouzes.

Modérateurs : Papy.G, fneck, Carl

nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

Salut amiral-_-sega ! Avant d'essayer (comme suggéré précédemment) un autre écran ou d'autres librairies, question de bon sens : tu pourrais commencer par tester les exemples (dans le menu fichier de l'IDE Arduino) fournis avec la librairie MCUFRIEND, voir ce que ça donne.

Autre chose (qui ne te mènera peut-être pas beaucoup plus loin, mais sait-on jamais) pour avancer dans le diagnostic : en faisant quelques recherches à propos des problèmes d'écran blanc avec cette librairie, dans les discussions à ce sujet sur les forums Arduino, j'ai vu parfois son auteur y évoquer des soucis de reconnaissance de chipset (puce de l'écran), suspectant de possibles clones qui feraient de l'usurpation d'identité... :mrgreen: :)
(même si c'est peu probable pour une carte apparemment identique, et pas forcément le cas ici, ça n'aurait rien de surprenant pour ce genre de chinoiseries, et pourrait éventuellement nécessiter de forcer dans le code un autre modèle compatible, mais lequel ??)

Pour en savoir plus, il a concocté deux programmes (qui font plus ou moins la même chose et se trouvent également dans les exemples) capables d'interroger la puce de l'écran et de lui faire lister ses différents registres internes : LCD_ID_readreg et LCD_ID_readnew.

Donc tu pourrais déjà poster tout ce que tu obtiens dans le moniteur série avec ces tests (un copié-collé du texte obtenu, pas d'images), et rjiji pourrait peut-être ensuite comparer avec ce qu'il obtient de son côté ? Enfin ça ne coûterait rien de confirmer ainsi qu'ils ont bien la même chose dans le ventre, et au moins je trouve que ce serait aussi une approche plus précise et technique.
aotta
Messages : 66
Inscription : 09 janv. 2019 14:26
Localisation : Pesaro, Italie

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par aotta »

Je sais que je suis un peu hors sujet, mais pour éviter de convertir les fichiers ".p" en ".lep", j'ai créé un hybride de tzxduino sdlepe: voici une version initiale de tzxtft pour les personnes intéressées. Sur mon zx81 cela fonctionne, les fichiers .tzx et .tap ont été testés sur le zx spectrum aussi.
J'ai ajouté un module d'amplificateur LM386 entre l'arduino et le câble audio mono (2 euro sur eBay).
TZXTFT.zip
(12.39 Kio) Téléchargé 148 fois
tzxtft2.jpg
tzxtft2.jpg (40.88 Kio) Consulté 5126 fois
tzxtft1.jpg
tzxtft1.jpg (38.9 Kio) Consulté 5126 fois
amiral-_-sega
Messages : 23
Inscription : 11 sept. 2019 16:02
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par amiral-_-sega »

J'obtient ce rapport avec LCD_ID_readnew (désolé pour la capture d'ecran , j'ai été imcapable de faire un copié collé du rapport bizarrement )
Image
nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

OK merci, je suppose que si tu ne nous en parles pas, c'est que les exemples de base de la librairie ne fonctionnent pas non plus ? Enfin, en recopiant (à la main, celle de votre serviteur :mrgreen:) certaines valeurs signifiantes, ça permet déjà de retrouver des rapports identiques postés par des personnes rencontrant des soucis avec le même écran.

Déjà, tu pourrais simplement essayer de forcer la librairie en mode ILI9341 en remplaçant cette ligne dans sdlep-tft :

Code : Tout sélectionner

  tft.begin(identifier);     // initialisation de l'ecran
par ceci :

Code : Tout sélectionner

  tft.begin(0x9341);         // force la librairie tft en mode ILI9341
Tu peux aussi tester avec la valeur 0x9340, même si, à priori, ça reviendrait au même que la détection normale.

Autre chose éventuellement : supprimer le dossier MCUFRIEND_kbv déjà présent dans ton dossier de librairies (sur windows, ça se trouve dans Documents->Arduino->libraries) et mettre à la place celui de la dernière version dispo sur Github (j'ai vu qu'une modif toute récente corrigeait un paramétrage spécifique au 9340 qui n'était pas correctement pris en compte), puis recompiler. Voici le lien direct pour télécharger le zip :
https://codeload.github.com/prenticedav ... zip/master
Dernière modification par nicolho le 26 oct. 2019 09:22, modifié 2 fois.
Avatar de l’utilisateur
fneck
Site Admin
Messages : 17488
Inscription : 01 avr. 2007 12:03
Localisation : Drôme Provençale (26)
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par fneck »

amiral-_-sega a écrit : 26 oct. 2019 08:17 (...) j'ai été incapable de faire un copié collé du rapport bizarrement
Pour conserver la mise ne page particulière il faut coller entre les balises "code" du message "</>"
Fabien https://www.system-cfg.com
Les bonnes pratiques de l'utilisateur du forum viewtopic.php?f=14&t=3
amiral-_-sega
Messages : 23
Inscription : 11 sept. 2019 16:02
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par amiral-_-sega »

Bon malgré toutes votre aides . J'ai toujours un problème d’écran blanc en modifiant la bibliothèque MCUFRIEND et en forçant la librairie en mode ILI9341 ; même la bibliothèque d'exemples graphictest_kbv ne fonctionne pas .
Par contre j'avais déjà tater du Arduino en réalisant un cadre photo dans une de cartouche de NES https://www.instagram.com/p/B15qlUzokmk ... _copy_link et la l’écran démarre en jaune avec un message :Didtnt find BMP image , donc je pense que l’écran fonctionne . J'en ai ma claque de cet écran et de polluer le post ,si quelqu'un a un lien pour un écran avec lequel un fichier INO fonctionne "plug n'play" je suis preneur ?
Ou si une âme charitable veut bien me faire fonctionner cet écran de malheur je suis prêt a lui expédier AR , qu'il me contact en MP .
nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

Laisser tomber dès que ça se corse un peu pour trouver la solution ?.. du classique ! :D Et tu as essayé de mettre la dernière mouture de la librairie avec le lien que j'avais spécialement donné dès potron-minet :) ? Enfin tu aurais dû commencer par là, nous dire que ça marchait avec un autre programme Arduino !

Peu importe si ça donnait un message d'erreur, l'important c'est que ce dernier s'affichait correctement, donc 2 bonnes nouvelles (qui j'espère te redonneront un peu de courage) :
- l'écran n'est pas HS, contrairement à ce qu'on pouvait supposer précédemment
- ton programme de cadre photo utilise une librairie qui sait contrôler comme il faut cet écran, donc en étudiant rapidement le code (stp copie nous déjà les #include que tu as au début), on pourrait trouver laquelle et même peut-être l'utiliser à la place dans ton croquis sdlep-tft.
Dernière modification par nicolho le 26 oct. 2019 18:10, modifié 1 fois.
Daniel
Messages : 17404
Inscription : 01 mai 2007 18:30
Localisation : Vaucluse
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par Daniel »

Je suis entièrement d'accord avec nicolho. Si le programme du cadre photo fonctionne, il faut utiliser les mêmes bibliothèques et les mêmes paramètres avec SDLEP-READER et ça devrait résoudre le problème.
Daniel
L'obstacle augmente mon ardeur.
amiral-_-sega
Messages : 23
Inscription : 11 sept. 2019 16:02
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par amiral-_-sega »

Oui j'ai bien mis la dernière mouture de la librairie MCUFRIEND dans la librairie .
Voici le programme cadre photo NES qui fait "fonctionner" l'ecran

Code : Tout sélectionner

[code]
// IMPORTANT: Adafruit_TFTLCD LIBRARY MUST BE SPECIFICALLY
// CONFIGURED FOR EITHER THE TFT SHIELD OR THE BREAKOUT BOARD.
// SEE RELEVANT COMMENTS IN Adafruit_TFTLCD.h FOR SETUP.
//Technical support:goodtft@163.com

#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_TFTLCD.h> // Hardware-specific library
#include <SD.h>
#include <SPI.h>


// The control pins for the LCD can be assigned to any digital or
// analog pins...but we'll use the analog pins as this allows us to
// double up the pins with the touch screen (see the TFT paint example).
#define LCD_CS A3 // Chip Select goes to Analog 3
#define LCD_CD A2 // Command/Data goes to Analog 2
#define LCD_WR A1 // LCD Write goes to Analog 1
#define LCD_RD A0 // LCD Read goes to Analog 0
#define PIN_SD_CS 10 // Adafruit SD shields and modules: pin 10

#define LCD_RESET A4 // Can alternately just connect to Arduino's reset pin

// When using the BREAKOUT BOARD only, use these 8 data lines to the LCD:
// For the Arduino Uno, Duemilanove, Diecimila, etc.:
//   D0 connects to digital pin 8  (Notice these are
//   D1 connects to digital pin 9   NOT in order!)
//   D2 connects to digital pin 2
//   D3 connects to digital pin 3
//   D4 connects to digital pin 4
//   D5 connects to digital pin 5
//   D6 connects to digital pin 6
//   D7 connects to digital pin 7
// For the Arduino Mega, use digital pins 22 through 29
// (on the 2-row header at the end of the board).

// Assign human-readable names to some common 16-bit color values:
#define	BLACK   0x0000
#define	BLUE    0x001F
#define	RED     0xF800
#define	GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF
#include <MCUFRIEND_kbv.h>
MCUFRIEND_kbv tft;
//Adafruit_TFTLCD tft(LCD_CS, LCD_CD, LCD_WR, LCD_RD, LCD_RESET);
// If using the shield, all control and data lines are fixed, and
// a simpler declaration can optionally be used:
// Adafruit_TFTLCD tft;

#define MAX_BMP         10                      // bmp file num
#define FILENAME_LEN    20                      // max file name length

//A variable to hold pseudo random non-consecutive integers.
int randomInt = 5;
 
//A variable to hold the previously assigned pseudo random non-consecutive integers.
int previousRandomInt = 0;

const int __Gnbmp_height = 480;                 // 320 bmp hight
const int __Gnbmp_width  = 320;                 // 240 bmp width

unsigned char __Gnbmp_image_offset  = 0;        // offset

int __Gnfile_num = 234;                           // num of file

int max =__Gnfile_num + 1;

char __Gsbmp_files[10][FILENAME_LEN] =           // add file name here
{
"1.bmp",
};

File bmpFile;

/*********************************************/
// This procedure reads a bitmap and draws it to the screen
// its sped up by reading many pixels worth of data at a time
// instead of just one pixel at a time. increading the buffer takes
// more RAM but makes the drawing a little faster. 20 pixels' worth
// is probably a good place

#define BUFFPIXEL       80                      // must be a divisor of 320 
#define BUFFPIXEL_X3    240                     // BUFFPIXELx3

void bmpdraw(File f, int x, int y)
{

    bmpFile.seek(__Gnbmp_image_offset);

    uint32_t time = millis();

    uint8_t sdbuffer[BUFFPIXEL_X3];                 // 3 * pixels to buffer

    for (int i=0; i< __Gnbmp_height; i++) {
        for(int j=0; j<(320/BUFFPIXEL); j++) {
            bmpFile.read(sdbuffer, BUFFPIXEL_X3);
            
            uint8_t buffidx = 0;
            int offset_x = j*BUFFPIXEL;
            unsigned int __color[BUFFPIXEL];
            
            for(int k=0; k<BUFFPIXEL; k++) {
                __color[k] = sdbuffer[buffidx+2]>>3;                        // read
                __color[k] = __color[k]<<6 | (sdbuffer[buffidx+1]>>2);      // green
                __color[k] = __color[k]<<5 | (sdbuffer[buffidx+0]>>3);      // blue
                
                buffidx += 3;
            }

	    for (int m = 0; m < BUFFPIXEL; m ++) {
              tft.drawPixel(m+offset_x, i,__color[m]);
	    }
        }
    }
    
    Serial.print(millis() - time, DEC);
    Serial.println(" ms");
}

boolean bmpReadHeader(File f) 
{
    // read header
    uint32_t tmp;
    uint8_t bmpDepth;
    
    if (read16(f) != 0x4D42) {
        // magic bytes missing
        return false;
    }

    // read file size
    tmp = read32(f);
    Serial.print("size 0x");
    Serial.println(tmp, HEX);

    // read and ignore creator bytes
    read32(f);

    __Gnbmp_image_offset = read32(f);
    Serial.print("offset ");
    Serial.println(__Gnbmp_image_offset, DEC);

    // read DIB header
    tmp = read32(f);
    Serial.print("header size ");
    Serial.println(tmp, DEC);
    
    int bmp_width = read32(f);
    int bmp_height = read32(f);
    
    if(bmp_width != __Gnbmp_width || bmp_height != __Gnbmp_height)  {    // if image is not 320x240, return false
        return false;
    }

    if (read16(f) != 1)
    return false;

    bmpDepth = read16(f);
    Serial.print("bitdepth ");
    Serial.println(bmpDepth, DEC);

    if (read32(f) != 0) {
        // compression not supported!
        return false;
    }

    Serial.print("compression ");
    Serial.println(tmp, DEC);

    return true;
}

/*********************************************/
// These read data from the SD card file and convert them to big endian
// (the data is stored in little endian format!)

// LITTLE ENDIAN!
uint16_t read16(File f)
{
    uint16_t d;
    uint8_t b;
    b = f.read();
    d = f.read();
    d <<= 8;
    d |= b;
    return d;
}

// LITTLE ENDIAN!
uint32_t read32(File f)
{
    uint32_t d;
    uint16_t b;

    b = read16(f);
    d = read16(f);
    d <<= 16;
    d |= b;
    return d;
}



void setup(void) {
  Serial.begin(9600);
  Serial.println(F("TFT LCD test"));

  tft.reset();

  uint16_t identifier = tft.readID();
  if(identifier == 0x9325) {
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if(identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if(identifier == 0x4535) {
    Serial.println(F("Found LGDP4535 LCD driver"));
  }else if(identifier == 0x7575) {
    Serial.println(F("Found HX8347G LCD driver"));
  } else if(identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
  }else if(identifier == 0x7783) {
    Serial.println(F("Found ST7781 LCD driver"));
  }else if(identifier == 0x8230) {
    Serial.println(F("Found UC8230 LCD driver"));  
  }
  else if(identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
  } else if(identifier==0x0101)
  {     
      identifier=0x9341;
       Serial.println(F("Found 0x9341 LCD driver"));
  }else if(identifier==0x9481)
  {     
       Serial.println(F("Found 0x9481 LCD driver"));
  }
  else if(identifier==0x9486)
  {     
       Serial.println(F("Found 0x9486 LCD driver"));
  }
  else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    identifier=0x9486;
    
  }
  tft.begin(identifier);
  Serial.print("TFT size is "); Serial.print(tft.width()); Serial.print("x"); Serial.println(tft.height());
  tft.fillScreen(BLUE);
  
  
  //Init SD_Card
  pinMode(10, OUTPUT);
   
  if (!SD.begin(10)) {
    Serial.println("initialization failed!");
    tft.setCursor(0, 0);
    tft.setTextColor(WHITE);    
    tft.setTextSize(1);
    tft.println("SD Card Init fail.");   
  }else
  Serial.println("initialization done."); 
}

void loop(void) {
  
     for(unsigned char i=0; i<__Gnfile_num; i++) {
       // bmpFile = SD.open(__Gsbmp_files[randomInt]);    

        // char randimage[] =randomInt,".bmp";

        // randimage = randomInt+".bmp"; 

        char fileName[13]; // Room for an 8.3 name with a NULL terminator
        
        int randomNumber = random(1, max);
        
        sprintf(fileName, "%d.bmp", randomNumber);        

        Serial.println("image :");
        Serial.println(fileName);

        bmpFile = SD.open(fileName);      
        
        if (! bmpFile) {
            Serial.println("didnt find image");
            tft.setTextColor(WHITE);    tft.setTextSize(1);
            tft.println("didnt find BMPimage");
            while (1);
        }
   
        if(! bmpReadHeader(bmpFile)) {
            Serial.println("bad bmp");
            tft.setTextColor(WHITE);    tft.setTextSize(1);
            tft.println("bad bmp");
            return;
        }

        bmpdraw(bmpFile, 0, 0);
        bmpFile.close();
        delay(5000);        
    }
    
}


[/code]
nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

Et bah voilà ! Ton croquis utilise la même librairie MCUFRIEND_kvb, mais en forçant un modèle ILI9486.
Donc tu peux déjà essayer la même modif proposée ce matin pour forcer ce modèle spécifique dans sdlep-tft :

Code : Tout sélectionner

  tft.begin(0x9486); 
EDIT : oui, ça doit bien être ça finalement.... :mrgreen:
Dernière modification par nicolho le 26 oct. 2019 18:52, modifié 2 fois.
amiral-_-sega
Messages : 23
Inscription : 11 sept. 2019 16:02
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par amiral-_-sega »

j'ai fais ceci je sais pas si c'est la ou il faut ?

Code : Tout sélectionner

[code]
#endif
  
  tft.begin(0x9486);         // force la librairie tft en mode ILI9486

[/code]
nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

Oui, c'est ça, dans la partie de sdlep-tft où il y a :

Code : Tout sélectionner

  tft.begin(identifier);     // initialisation de l'ecran
  tft.setRotation(1);        // mode paysage
  LoadMenu();                //affichage des fichiers et selection
tu remplaces la première ligne par ce que je viens de t'indiquer. (explications à suivre)

Dans le code du cadre photo, on retrouve la même séquence d'affichage du modèle détecté que tu avais avec le DEBUG, sauf que quand le modèle est affiché comme "Unknown LCD driver chip: 0x9340" dans le moniteur série, toi ou quelqu'un d'autre (un petit malin en tout cas :wink: ) a ajouté ceci lorsque ça se produit : "identifier=0x9486;", ce qui force cet autre modèle dans la librairie. Ca ressemble fort à un ajout fait après coup...
Dernière modification par nicolho le 26 oct. 2019 19:00, modifié 1 fois.
amiral-_-sega
Messages : 23
Inscription : 11 sept. 2019 16:02
Contact :

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par amiral-_-sega »

Vérifier et téléverser mais toujour écran blanc , on d'accord que j'utilise le SDLEP_TFT-JC-2.4 de rjiji

Code : Tout sélectionner

[code]

/**************************************************\
*               S D L E P - T F T                  * 
*           (c) 2019 - Daniel Coulom               *  
*           http://dcmoto.free.fr/                 *
*           http://forum.system-cfg.com/           *
*           Versione per TFT 2,8" shield           *
*           modificata da Andrea Ottaviani         * 
*--------------------------------------------------*
* Ce code est distribue gratuitement dans l'espoir *
* qu'il sera utile, mais sans aucune  garantie  et *
* sans  engager  la  responsabilité  de  l'auteur. *
* Vous  pouvez  l' utiliser,  le  modifier  et  le *
* diffuser librement, en conservant cette  licence *
* et les références de l'auteur dans   toutes  les *
* copies. L'exploitation commerciale est interdite.*
\**************************************************/

/***************************************************
*                Version 2019.10.13                *
****************************************************
Historique
2019.10.13 Inversion X et Y pour TFT 2.4" id:9340 - JC
2019.03.27 MOTOROFF: sortie haute immediate pour
           eviter l'erreur de detection du LEP 
2019.03.24 parametres touchscreen dans fichier .h
2019.03.20 ajout ecran 2.8" smart electronics HX8347
2019.03.14 ajout ecran 2.8" mcufriend ILI9325
2019.03.06 utilisation bibliotheque MCUFRIEND_kvb
2019.03.04 reset en cas d'echec de sd.begin()
2019.02.24 ameliorations de details by DC
2019.02.23 adaptation à un écran 2.4" different
2019.02.10 added TFT support by AO
2017.04.16 optimisations des acces a la carte SD
2017.03.13 integration des acces a la carte SD
2017.01.17 bit data a 1 pendant l'arret moteur
2016.12.30 unite du delai definie en parametre
2016.12.29 noms de fichiers .lep sur 7 caracteres
2016.12.19 quelques optimisations mineures
2016.12.18 clignotement LED si fichier non trouve
2016.12.18 nom de fichier choisi par switches
2016.12.17 choix de broches different pour les I/O
2016.12.17 delai en dixiemes de ms dans sd.lep
2016.12.16 ajout LED d'activite
2016.12.16 reste de count/127 ecrit avant les zeros
2016.12.14 premiere version du programme

Emulation d'un lecteur de cassette Thomson TO ou MO
Lecture des donnees sur carte SD dans un fichier au
format .lep (image de cassette Thomson).

Connexions vers module Catalex pour carte micro SD
 GND --> GND
 D13 --> SCK
 D12 --> MISO
 D11 --> MOSI
 D10 --> CS 
 VCC --> VCC (5V)

Connexions vers DIN magnetophone
GND --> DIN 2
 D0 --> DIN 1  (MOTOR)
 D1 --> DIN 4  (READ DATA) 
   
Connexion vers DIN crayon optique
VCC --> DIN 5  (+5V)
   
Connexion LED d'activite SDLEP
 D2 --> LED d'activite + resistance 1.5K
 Modifie en A5 pour SDLEP-TFT

*****************************************************************
SD card management is adapted from SimpleSDAudio library.
Visit SimpleSDAudio website for more information:
http://www.hackerspace-ffm.de/wiki/index.php?title=SimpleSDAudio
*****************************************************************

Les bibliotheques Adafruit_GFX, Sdfat, TouchScreen
et MCUFRIEND_kbv doivent être installees. 

*/

#define DEBUG

#include <avr/wdt.h>         //Watchdog
#include <Adafruit_GFX.h>    //Core graphics library
#include <SdFat.h>           //Acces aux fichiers de la carte SD
SdFat sd;
SdFile file;
SdFile root;
#define SD_CS 10     //Set the chip select line to whatever you use (10 doesnt conflict with the library)
#define SDLEP_LED A5 //LED d'activite de SDLEP-READER
#define UNITE 50     //Unite du delai en microsecondes

//TFT display hardware-specific library
#include <MCUFRIEND_kbv.h>            
MCUFRIEND_kbv tft;

//Dalle tactile
//Le fichier touchscreen-param.h definit
//- le brochage de la dalle tactile
//- la pression minimum et maximum pour la prise en compte d'un appui
//- le calibrage dans l'axe des X et dans l'axe des Y
//- la résistance de la dalle entre XP et XM
//Plusieurs exemples sont fournis, il faut les adapter a chaque ecran.
#include "TouchScreen.h"
#include "touchscreen-param.h" 
TouchScreen ts = TouchScreen(XP, YP, XM, YM, OHMS);

// Assign human-readable names to some common 16-bit color values:
#define BLACK   0x0000
#define BLUE    0x001F
#define RED     0xF800
#define GREEN   0x07E0
#define CYAN    0x07FF
#define MAGENTA 0xF81F
#define YELLOW  0xFFE0
#define WHITE   0xFFFF

// SD card constants
#define SD_CARD_TYPE_SD1        1 /** Standard capacity V1 SD card */
#define SD_CARD_TYPE_SD2        2 /** Standard capacity V2 SD card */
#define SD_CARD_TYPE_SDHC       3 /** High Capacity SD card */
#define SD_PARTTYPE_UNKNOWN     0
#define SD_PARTTYPE_SUPERFLOPPY 1
#define SD_PARTTYPE_FAT16       2
#define SD_PARTTYPE_FAT32       3
#define SD_INIT_TIMEOUT      2000 /** temps maxi pour l'initialisation */
#define SD_READ_TIMEOUT       300 /** temps maxi pour le debut de la lecture d'un bloc */
#define SD_COMMAND_TIMEOUT    300 /** temps maxi pour repondre a une commande */
#define SD_READY_STATE       0x00 /** status for card in the ready state */
#define SD_IDLE_STATE        0x01 /** status for card in the idle state */
#define SD_ILLEGAL_COMMAND   0x04 /** status bit for illegal command */
#define SD_DATA_START_BLOCK  0xFE /** start data token for read or write single block*/

// SD card commands
#define SD_CMD0   0x00  /** GO_IDLE_STATE - init card in spi mode if CS low */
#define SD_CMD8   0x08  /** SEND_IF_COND - verify SD Memory Card interface operating condition.*/
#define SD_CMD9   0x09  /** SEND_CSD - read the Card Specific Data (CSD register), response R1 */
#define SD_CMD10  0x0A  /** SEND_CID - read the card identification information (CID register), response R1 */
#define SD_CMD12  0x0C  /** STOP_TRANSMISSION - end multiple block read sequence, response R1b */
#define SD_CMD13  0x0D  /** SEND_STATUS - read the card status register, response R2 */
#define SD_CMD16  0x10  /** SET_BLOCKLEN arg0[31:0]: block length, response R1 */
#define SD_CMD17  0x11  /** READ_SINGLE_BLOCK - read a single data block from the card, response R1 */
#define SD_CMD18  0x12  /** READ_MULTIPLE_BLOCK - read a multiple data blocks from the card, response R1 */
#define SD_CMD55  0x37  /** APP_CMD - escape for application specific command */
#define SD_CMD58  0x3A  /** READ_OCR - read the OCR register of a card */
#define SD_CMD59  0x3B  /** CRC_ON_OFF - Turns CRC option on or off, response R1 */
#define SD_ACMD41 0x29  /** SD_SEND_OP_COMD - Sends host capacity support information and activates the card's initialization process */

// SD card error codes
#define SD_ERROR_CMD0           0x01 /** timeout error for command CMD0 (initialize card in SPI mode), signal problem */
#define SD_ERROR_CMD8           0x02 /** CMD8 was not accepted - not a valid SD card */
#define SD_ERROR_ACMD41         0x03 /** ACMD41 initialization process timeout */
#define SD_ERROR_CMD58          0x04 /** card returned an error response for CMD58 (read OCR) */
#define SD_ERROR_CMD16          0x05 /** card returned an error response for CMD16 (set block len) */
#define SD_ERROR_VOLTMATCH      0x06 /** card operation voltage range doesn't match (2.7V - 3.6V) */
#define SD_ERROR_READ_TIMEOUT   0x07 /** timeout while waiting for start of read data */
#define SD_ERROR_READ           0x08 /** card returned error token when tried to read data */
#define SD_ERROR_CMD17          0x09 /** card returned an error response for CMD17 (read single block) */
#define SD_ERROR_CMD9           0x0e /** card returned an error response for CMD9  (read CSD) */
#define SD_ERROR_CMD10          0x0f /** card returned an error response for CMD10 (read CID) */
#define SD_ERROR_CMD18          0x10 /** card returned an error response for CMD18 (read multi block) */
#define SD_ERROR_INVAL_SECT0    0x30 /** No valid MBR/FAT-BS signature found in sector 0 */
#define SD_ERROR_INVAL_BS       0x31 /** Malformed FAT boot sector */
#define SD_ERROR_FAT12          0x32 /** FAT12 is not supported */
#define SD_ERROR_FAT_NOT_INIT   0x33 /** FAT not initialized properly */
#define SD_ERROR_DIR_EOC        0x34 /** End of cluster reached (not a real error, just information) */
#define SD_ERROR_FILE_NOT_FOUND 0x35 /** File not found after reaching end of directory */
#define SD_ERROR_EOF            0x38 /** End of file reached */

// SD card variables
typedef struct {
  uint8_t     Attributes;
  uint32_t    Size;           // in bytes
  uint32_t    FirstCluster;   // First cluster
  uint32_t    ActSector;      // 0 to (SD_FAT.SecPerClus - 1)
  uint32_t    ActBytePos;     // 0 to Size
} SD_File_t;

SD_File_t LepFileInfo;  

typedef struct  {
  uint8_t     PartType;           // Use this to test whether it is FAT16 or FAT32 or not initialized
  // Stuff from FAT boot sector
  uint8_t     SecPerClus;
  uint16_t    RsvdSecCnt;
  uint8_t     NumFATs;
  uint16_t    RootEntryCount;
  uint32_t    TotalSec;
  uint32_t    SecPerFAT;
  uint32_t    RootClus;
  // For cluster calculations
  uint8_t     ClusterSizeShift;
  uint32_t    ClusterCount;
  // Start addresses (all in blocks / sector addresses)
  uint32_t    BootSectorStart;    // Address of boot sector from FAT
  uint32_t    FatStart;           // First file allocation table starts here
  uint32_t    RootDirStart;       // Root directory starts here
  uint32_t    DataStart;          // Cluster 0 starts here
  uint32_t    ClusterEndMarker;   // if Cluster >= this then end of file reached.
} SD_FAT_t;

SD_FAT_t SD_FAT;

uint8_t  SD_type;        // type de la carte SD
uint8_t  SD_buffer[513]; // SD buffer must hold 512 bytes + 1

char shortname[13]; //nom court du fichier choisi


////////////////////////////////////////////////////////////////////
// Selection du fichier .lep
////////////////////////////////////////////////////////////////////
char* LoadMenu()
{
 int i; 
 byte numentry;        //numero de l'entree de repertoire
 byte numfiles;        //nombres de fichiers affiches
 boolean dirEnd;       //indicateur de fin de repertoire de la carte SD
 boolean prev;         //indicateur d'existence d'un ecran precedent
 char suf[10];         //extension du nom de fichier
 char longfilename[25];     //nom long (tronque) d'un fichier
 char shortfilename[8][13]; //noms courts des fichiers affiches
 int  numchoosen;      //numero du fichier choisi
 SdFile entry;         //entree de repertoire

 //affichage du titre
 tft.fillScreen(BLACK);      
 tft.fillRect(0,0,320,22,YELLOW);
 tft.setCursor(10,4);
 tft.setTextSize(2);
 tft.setTextColor(BLACK); tft.print("SDLEP-READER ");
 tft.setTextColor(RED); tft.print("T");
 tft.setTextColor(GREEN);tft.print("F");
 tft.setTextColor(BLUE);tft.print("T");
 tft.setTextColor(BLACK);tft.println(" 2.4 inch");
 tft.setTextColor(BLACK);

 //initialisation de la carte SD 
 //retry en cas d'erreur 
 if (!sd.begin(SD_CS))
 {
  tft.setCursor(16, 40);
  tft.setTextColor(WHITE);
  tft.println(F("SD init..."));
  wdt_enable(WDTO_1S);
  while(1);
 } 

 //affichage bouton FIRST
 tft.fillRect(0,217,100,22,YELLOW);
 tft.setCursor(20,221);
 tft.print("DEBUT");

 //affichage bouton OK
 tft.fillRect(110,217,100,22,YELLOW);
 tft.setCursor(150,221);
 tft.print("OK");

 //affichage bouton NEXT
 tft.fillRect(220,217,100,22,YELLOW);
 tft.setCursor(240,221);
 tft.print("SUITE");

////////////////////////////////////////////////////////////////////
// Choix du fichier a charger
////////////////////////////////////////////////////////////////////

 //initialisations
 dirEnd = false;           //fin de directory pas atteinte
 prev = false;             //pas d'ecran precedent
 shortname[0] = 0;         //initialisation du nom du fichier choisi
 tft.setTextColor(YELLOW); //ecriture en jaune

 //boucle de choix du fichier
 while (1)
 {
  numentry=0;
  numfiles=0;
  numchoosen = -1;

  //affichage de huit lignes au maximum
  tft.fillRect(0,25,320,180,BLUE);
  while (1)
  {
   if(numfiles > 0) entry.close();  //fermer la derniere entree lue
   if(numentry >= 8) break;         //fin quand 8 lignes sont affichees
   //lecture de l'entree suivante du repertoire
   //en fin de repertoire sortir de la boucle
   if (!entry.openNext(sd.vwd(), O_READ))
   {entry.close(); dirEnd=true; break;}
   numfiles++;
   if(entry.isDir()) continue; //ne pas traiter les sous-repertoires

   //recherche du point dans le nom court du fichier  
   entry.getSFN(shortfilename[numentry]);
   for(i=0; i<10; i++) if (shortfilename[numentry][i]=='.') break;  //point trouve
   if(i==10) continue; //point pas trouve, entree de repertoire suivante
   
   //test du suffixe
   suf[0]=shortfilename[numentry][i+1];
   suf[1]=shortfilename[numentry][i+2];
   suf[2]=shortfilename[numentry][i+3];
   suf[3]=0;
   if (strcmp(suf,"LEP")!=0)
   if (strcmp(suf,"lep")!=0)
   continue; //ne pas traiter si ce n'est pas un fichier .lep 
   
   //affichage d'un fichier d'extension .lep
   entry.getName(longfilename,24);
   tft.setCursor(35,30+22*numentry);
   tft.print(longfilename);
   tft.drawCircle(15,35+22*numentry,8,WHITE);
   numentry++;
  }
  
  //test de l'action de l'utilisateur
  while (1)
  {
   int x, y;

   //Lire le Touch Screen
   TSPoint p = ts.getPoint();

   //Retablir le sens pour les boches partagees avec l'ecran LCD
   //A3=Chip Select et A2=Command/Data
   pinMode(XM, OUTPUT);
   pinMode(YP, OUTPUT);
  
   if ((p.z < MINPRESSURE) || (p.z > MAXPRESSURE)) continue;

   //calcul des coordonnées pointees
   //x est defini de la gauche vers la droite de l'affichage   
   //y est defini du haut vers le bas de l'affichage   
   x = map(p.y, TS_MINY, TS_MAXY, 0, tft.width());
   y = map(p.x, TS_MINX, TS_MAXX, 0, tft.height());      

   //selection d'un nom de fichier
   if((y > 35) && (y < 205))
   {
    //annuler si necessaire l'ancienne selection
    if(numchoosen >= 0) tft.fillCircle(15,35+22*(numchoosen),5,BLUE);        
    //nouvelle selection
    numchoosen=((y-35)/22);
    if(numchoosen >= numentry) numchoosen = -1;
    if(numchoosen >= 0) tft.fillCircle(15,35+22*(numchoosen),5,RED);
   }

   //action du bouton FIRST
   if(y > 216)              //si appui en bas de l'ecran
   if(x < 115)              //si appui sur le bouton NEXT
   if(prev)                 //s'il y a un ecran precedent
   {
    sd.vwd()->rewind();     //revenir au debut de la carte SD
    dirEnd=false;           //remettre a zero l'indicateur de fin
    prev=false;             //remettre a zero l'indicateur d'ecran precedent 
    break;                  //afficher le premier ecran
   }

   //action du bouton OK
   if(y > 216)              //si appui en bas de l'ecran
   if((x > 114)&&(x < 215)) //si appui sur le bouton OK
   if(numchoosen >= 0)      //si le fichier est choisi, terminer
   {
    strcpy(shortname, shortfilename[numchoosen]); 
    break;
   }
   
   //action du bouton NEXT
   if(y > 216)              //si appui en bas de l'ecran
   if(x > 214)              //si appui sur le bouton FIRST
   if(!dirEnd)              //il y a d'autres fichiers
   {
    prev=true;              //positionner indicateur d'ecran precedent 
    break;                  //afficher l'ecran suivant 
   }
   
  } //fin du test de l'action de l'utilisateur (on en sort par le break des boutons FIRST, OK et NEXT)
  if(shortname[0] != 0) break; //le fichier a été choisi par le bouton OK
  
 } //fin de la boucle de choix du fichier (on en sort si le fichier a ete choisi)
 
 root.close();
}

/**************************************************************************\
 * Initialize the SD memory card.
 * Power up the card, set SPI mode.
 * Detects the card version (V1, V2, SDHC), sets sector length to 512.
 * \return Zero if successfull, errorcode otherwise
\**************************************************************************/
uint8_t SD_Init()
{
 uint8_t status;
 uint16_t t0 = ((uint16_t)millis());
 uint32_t arg;

 /* Setup ports */
 pinMode(SD_CS, OUTPUT);
 digitalWrite(SD_CS, HIGH);
 pinMode(MISO, INPUT);
 pinMode(SCK, OUTPUT);
 pinMode(MOSI, OUTPUT);
 pinMode(SS, OUTPUT);
  
 digitalWrite(SCK, LOW);
 digitalWrite(MOSI, LOW);
 digitalWrite(SS, HIGH);

 /*
 * SPI configuration: 
 * - enable uC for SPI master
 * - typical no interrupts are used for SPI
 * - data order: MSB is transmitted first
 * - clock polarity: CLK is low when idle
 * - clock phase: 1-0 > Sample, 0-1 > Setup
 * - clock frequency: less than 400kHz 
 *   (will be switched to higher value after initialization)
 */
 /* initialize SPI with lowest frequency; max. 400kHz during identification mode of card */
 SPCR = (0 << SPIE) | /* SPI Interrupt Enable */
        (1 << SPE)  | /* SPI Enable */
        (0 << DORD) | /* Data Order: MSB first */
        (1 << MSTR) | /* Master mode */
        (0 << CPOL) | /* Clock Polarity: SCK low when idle */
        (0 << CPHA) | /* Clock Phase: sample on rising SCK edge */
        (1 << SPR1) | /* Clock Frequency: f_OSC / 128 */
        (1 << SPR0);
 SPSR &= ~(1 << SPI2X); /* No doubled clock frequency */
  
 // must supply min of 74 clock cycles with CS high.
 SD_SetCSHigh();
 for (uint8_t i = 0; i < 10; i++) SD_SpiSendByte(0xFF);

 // command to go idle in SPI mode
 while ((SD_CardCommand(SD_CMD0, 0)) != SD_IDLE_STATE)
  if ((((uint16_t)millis()) - t0) > SD_INIT_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_CMD0);}
  
 // check SD version ( 2.7V - 3.6V + test pattern )
 SD_type = 0;
 if ((SD_CardCommand(SD_CMD8, 0x1AA) & SD_ILLEGAL_COMMAND)) SD_type = SD_CARD_TYPE_SD1;
    // Not done here: Test if SD or MMC card here using CMD55 + CMD1
 else
 {
  // only need last byte of r7 response
  SD_SpiReadByte();
  SD_SpiReadByte();
  status = SD_SpiReadByte();
  if ((status & 0x01) == 0) // card operation voltage range doesn't match
  {SD_SetCSHigh(); return(SD_ERROR_VOLTMATCH);}
  if (SD_SpiReadByte() != 0xAA) {SD_SetCSHigh(); return(SD_ERROR_CMD8);}
  SD_type = SD_CARD_TYPE_SD2;
 }
  
 // Turn CRC option off
 SD_CardCommand(SD_CMD59, 0);
  
 // initialize card and send host supports SDHC if SD2
 arg = (SD_type == SD_CARD_TYPE_SD2) ? 0X40000000 : 0;
 while ((SD_CardACommand(SD_ACMD41, arg)) != SD_READY_STATE) // check for timeout
  if ((((uint16_t)millis()) - t0) > SD_INIT_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_ACMD41);}
  
 // if SD2 read OCR register to check for SDHC card
 if (SD_type == SD_CARD_TYPE_SD2)
 {
  if (SD_CardCommand(SD_CMD58, 0)) {SD_SetCSHigh(); return(SD_ERROR_CMD58);}
  // other implementation test only against 0x40 for SDHC detection...
  if ((SD_SpiReadByte() & 0xC0) == 0xC0) SD_type = SD_CARD_TYPE_SDHC;
  // discard rest of ocr - contains allowed voltage range
  SD_SpiReadByte();
  SD_SpiReadByte();
  SD_SpiReadByte();
 }

 // set block size to 512 bytes
 if(SD_CardCommand(SD_CMD16, 512)) {SD_SetCSHigh(); return(SD_ERROR_CMD16);}
 SD_SetCSHigh();
 SD_SpiSetHighSpeed();
 return 0;
}

/**************************************************************************\
* Set SPI for full operation speed (up to 25 MHz).
* Will be called after first part of card 
* initialization was successful.
\**************************************************************************/
void SD_SpiSetHighSpeed(void)
{
 SPCR &= ~((1 << SPR1) | (1 << SPR0)); /* Clock Frequency: f_OSC / 4 */
 SPSR |= (1 << SPI2X);         /* Doubled Clock Frequency: f_OSC / 2 */
}

/**************************************************************************\
* Receives a raw byte from the SPI.
* \returns The byte which should be read.
\**************************************************************************/
uint8_t SD_SpiReadByte()
{
 SPDR = 0xff; /* send dummy data for receiving some */
 while(!(SPSR & (1 << SPIF)));
 SPSR &= ~(1 << SPIF);
 return SPDR;
}

/**************************************************************************\
* Read a 512 byte block from an SD card.
* \param[in] blockNumber Logical block to be read.
* \param[out] dst Pointer to the location that will receive the data.
* \return 0 is returned for success, error code otherwise
\**************************************************************************/
uint8_t SD_ReadBlock(uint32_t blockNumber) 
{
  uint8_t status;
  uint16_t t0;

 // use address if not SDHC card
 if (SD_type != SD_CARD_TYPE_SDHC) blockNumber <<= 9;
 if (SD_CardCommand(SD_CMD17, blockNumber)) {SD_SetCSHigh(); return(SD_ERROR_CMD17);}

 // wait for start block token
 t0 = ((uint16_t)millis());
 while ((status = SD_SpiReadByte()) == 0xFF)
  if ((((uint16_t)millis()) - t0) > SD_READ_TIMEOUT) {SD_SetCSHigh(); return(SD_ERROR_READ_TIMEOUT);}
 if (status != SD_DATA_START_BLOCK) {SD_SetCSHigh(); return(SD_ERROR_READ);}
  
 // transfer data
 SPDR = 0xFF;
 for (uint16_t i = 0; i < 512; i++)
 {
  while (!(SPSR & (1 << SPIF)));
  SD_buffer[i] = SPDR;
  SPDR = 0xFF;
 }
 while (!(SPSR & (1 << SPIF)));
 SD_buffer[512] = SPDR;

 // discard CRC
 SD_SpiReadByte();
 SD_SpiReadByte();
 SD_SetCSHigh();

return 0;
}



/**************************************************************************\
* Set CS High 
* Sends also one dummy byte to ensure MISO goes high impedance
\**************************************************************************/
void SD_SetCSHigh()
{
 digitalWrite(SD_CS, HIGH);
 SD_SpiSendByte(0xff);
}

/**************************************************************************\
* Sends a raw byte to the SPI - \param[in] b The byte to sent.
\**************************************************************************/
void SD_SpiSendByte(uint8_t b)
{
 SPDR = b;
 while(!(SPSR & (1 << SPIF))); /* wait for byte to be shifted out */
 SPSR &= ~(1 << SPIF);
}

/**************************************************************************\
* Send a command to the memory card which responses with a R1 response 
* (and possibly others).
* \param[in] command The command to send.
* \param[in] arg The argument for command.
* \returns The command answer.
\**************************************************************************/
uint8_t SD_CardCommand(uint8_t cmd, uint32_t arg) 
{
 uint8_t response;
 uint8_t crc;
 uint16_t t0;
      
 // select card
 digitalWrite(SD_CS, LOW);

 // wait up to timeout if busy
 t0 = ((uint16_t)millis());
 while (SD_SpiReadByte() != 0xFF)
  if ((((uint16_t)millis()) - t0) >= SD_COMMAND_TIMEOUT) break;

 // send command
 SD_SpiSendByte(cmd | 0x40);

 // send argument
 SD_SpiSendByte((arg >> 24) & 0xff);
 SD_SpiSendByte((arg >> 16) & 0xff);
 SD_SpiSendByte((arg >>  8) & 0xff);
 SD_SpiSendByte((arg >>  0) & 0xff);
  
 // send CRC, only required for commands 0 and 8
 crc = 0xFF;
 if (cmd == SD_CMD0) crc = 0x95;  // correct crc for CMD0 with arg 0
 if (cmd == SD_CMD8) crc = 0x87;  // correct crc for CMD8 with arg 0X1AA
 SD_SpiSendByte(crc);

 // skip stuff byte for stop read
 if (cmd == SD_CMD12) SD_SpiReadByte();

 // wait for response
 for(uint8_t i = 0; i < 100; ++i)
 {
  response = SD_SpiReadByte();
  if(response != 0xff) break;
 }
 return response;
}

/**************************************************************************\
* Send an application specific command which responses with a R1 response 
* (and possibly others).
* \param[in] command The command to send.
* \param[in] arg The argument for command.
* \returns The command answer.
\**************************************************************************/
uint8_t SD_CardACommand(uint8_t cmd, uint32_t arg)
{
 SD_CardCommand(SD_CMD55, 0);
 return SD_CardCommand(cmd, arg);
}

/**************************************************************************\
* Returns the first sector of a given cluster
\**************************************************************************/
uint32_t SD_Cluster2Sector(uint32_t cluster)
{
 return((cluster << SD_FAT.ClusterSizeShift) + SD_FAT.DataStart);
}

/**************************************************************************\
* Initialize the file system .
* Does the lower level initialization and * tries to find the boot sector 
* of the first FAT16 or FAT32 partition and parse it.
* Workbuf must hold at least 512 bytes.
* Workbuf will be used later also for following functions:
* - SD_SearchFile
* - SD_Dir
* \return Zero if successful, error code otherwise
\**************************************************************************/
uint8_t SD_Init_FileSystem()
{
 uint8_t  retval;
 uint8_t  PartType;
 uint16_t temp16;
 uint32_t temp32;

   
 SD_FAT.PartType = SD_PARTTYPE_UNKNOWN;
    
 // Try init SD-Card
 retval = SD_Init();
 if(retval) {
#ifdef DEBUG
    Serial.print("Init ");
    Serial.println(retval);
#endif
    return(retval);
 } 

 // ==== MBR (partition table) access here =====
    
 // Read sector 0 
 retval = SD_ReadBlock(0);
 if(retval) return(retval);

 // Test for signature (valid not only for MBR, but FAT Boot Sector as well!)
 if((SD_buffer[0x1fe] != 0x55) || (SD_buffer[0x1ff] != 0xaa)) return(SD_ERROR_INVAL_SECT0);
    
 // Store most important MBR values for first partition
 PartType = SD_buffer[0x1be + 0x04];
 SD_FAT.BootSectorStart =  (uint32_t)SD_buffer[0x1be + 0x08] 
                        | ((uint32_t)SD_buffer[0x1be + 0x09] << 8UL)
                        | ((uint32_t)SD_buffer[0x1be + 0x0a] << 16UL)
                        | ((uint32_t)SD_buffer[0x1be + 0x0b] << 24UL);
    
    // Check MBR values for plausibility
    if(  ((SD_buffer[0x1be] & 0x7f) == 0)
      && ((PartType == 0x04) || (PartType == 0x06) || (PartType == 0x0B) 
           || (PartType == 0x0C) || (PartType == 0x0E)) )  
    {
        // MBR seems to contain valid FAT16/FAT32 partition entry
        SD_FAT.PartType = ((PartType == 0x0B) || (PartType == 0x0C)) ? SD_PARTTYPE_FAT32 : SD_PARTTYPE_FAT16;
    }
    else
    {
        // MBR seems to contain not an valid entry, so try for super-floppy now
        SD_FAT.BootSectorStart = 0UL;
        SD_FAT.PartType = SD_PARTTYPE_SUPERFLOPPY;
    }
    
    // ====== FAT access here ======
    
    // Read Boot-Sector and test for signature
    retval = SD_ReadBlock(SD_FAT.BootSectorStart);
    if(retval) return(retval);  

    // Test for signature (valid not only for MBR, but FAT Boot Sector as well!)
    if((SD_buffer[0x1fe] != 0x55) || (SD_buffer[0x1ff] != 0xaa)) return(SD_ERROR_INVAL_BS);
    
    // Plausibility checks for FAT
    if((SD_buffer[0x0b] != 0x00) || (SD_buffer[0x0c] != 0x02) || (SD_buffer[0x15] != 0xf8)) return(SD_ERROR_INVAL_BS);

    // Read fields that are same for FAT16 and FAT32
    SD_FAT.SecPerClus = SD_buffer[0x0d];
    SD_FAT.RsvdSecCnt = (uint16_t)SD_buffer[0x0e] | ((uint16_t)SD_buffer[0x0f]<<8U);
    if((SD_FAT.SecPerClus == 0) || (SD_FAT.RsvdSecCnt == 0)) return(SD_ERROR_INVAL_BS);
    SD_FAT.NumFATs = SD_buffer[0x10];
    SD_FAT.RootEntryCount = (uint16_t)SD_buffer[0x11] | ((uint16_t)SD_buffer[0x12]<<8U);
    
    temp16 = (uint16_t)SD_buffer[0x13] | ((uint16_t)SD_buffer[0x14]<<8U);
    temp32 = (uint32_t)SD_buffer[0x20] | ((uint32_t)SD_buffer[0x21]<<8U) | ((uint32_t)SD_buffer[0x22]<<16U) | ((uint32_t)SD_buffer[0x23]<<24U);
    SD_FAT.TotalSec  = temp16 ? temp16 : temp32;
    
    temp16 = (uint16_t)SD_buffer[0x16] | ((uint16_t)SD_buffer[0x17]<<8U);
    temp32 = (uint32_t)SD_buffer[0x24] | ((uint32_t)SD_buffer[0x25]<<8U) | ((uint32_t)SD_buffer[0x26]<<16U) | ((uint32_t)SD_buffer[0x27]<<24U);
    SD_FAT.SecPerFAT  = temp16 ? temp16 : temp32;
    
    // Calculate start sectors
    SD_FAT.FatStart = SD_FAT.BootSectorStart + (uint32_t)SD_FAT.RsvdSecCnt;
    SD_FAT.RootDirStart = SD_FAT.FatStart + SD_FAT.NumFATs * (uint32_t)SD_FAT.SecPerFAT;
    
    // Data area starts at cluster #2
    SD_FAT.DataStart = SD_FAT.RootDirStart+ ((32 * (uint32_t)SD_FAT.RootEntryCount + 511)/512) - (2 * SD_FAT.SecPerClus);
    
    // determine shift that is same as multiply by SD_FAT.SecPerClus
    SD_FAT.ClusterSizeShift = 0;
    while (SD_FAT.SecPerClus != (1 << SD_FAT.ClusterSizeShift)) {
      // error if not power of 2
      if (SD_FAT.ClusterSizeShift++ > 7) return(SD_ERROR_INVAL_BS);
    }  
    
     // Calculate number and shifting of clusters
    // total data blocks
    SD_FAT.ClusterCount = SD_FAT.TotalSec - (SD_FAT.DataStart - SD_FAT.BootSectorStart);
    // divide by cluster size to get cluster count
    SD_FAT.ClusterCount >>= SD_FAT.ClusterSizeShift;  
    
    // determine if FAT16 or FAT32 (only by cluster count as done by M$)
    if (SD_FAT.ClusterCount < 4085) {
        // this would be FAT12, which is not supported
        SD_FAT.PartType = SD_PARTTYPE_UNKNOWN;
        return(SD_ERROR_FAT12);
    } else if (SD_FAT.ClusterCount < 65525) {
        SD_FAT.PartType = SD_PARTTYPE_FAT16;
        SD_FAT.ClusterEndMarker = 0xfff8UL;
    } else {
        temp32 = (uint32_t)SD_buffer[0x2c] | ((uint32_t)SD_buffer[0x2d]<<8U) | ((uint32_t)SD_buffer[0x2e]<<16U) | ((uint32_t)SD_buffer[0x2f]<<24U);
        SD_FAT.RootDirStart = SD_Cluster2Sector(temp32);
        SD_FAT.PartType = SD_PARTTYPE_FAT32;
        SD_FAT.ClusterEndMarker = 0xffffff8UL;
    }
      
    return 0;
}


void loop()
{
 //la lecture est arrivee en fin de fichier
 //clignotement lent de la diode d'activite
 digitalWrite(SDLEP_LED,HIGH); // allumer led activite 
 delay(100);                   // temporisation
 digitalWrite(SDLEP_LED,LOW);  // eteindre led activite 
 delay(1900);                  // temporisation
}

/**************************************************************************\
* Search a file in the directory.
* Filename must be 8.3 format, terminated by \0 (can not access ".." now...)
* Works only over one cluster of directory information. 
* If SD_ERROR_DIR_EOC is returned call function again with next cluster number. 
* Set cluster to 0 to access root directory.
* Deleted files and long name entries are not shown generally.
* Only files are printed that has their attributes set/unset regarding maskSet/maskUnset.
* Examples for maskSet, maskUnset:
*  Ouput everything:           0x00, 0x00
*  Shortname files only:       0x00, 0x18
*  Shortname files and dirs:   0x00, 0x08
*  Shortname dirs:             0x10, 0x08
*  Volume name:                0x08, 0x10
* Mask bits: B7 = 0, B6 = 0, B5 = archive, B4 = directory, 
*            B3 = volume name, B2 = system, B1 = hidden, B0 = read only
* If file is found, fileinfo gets filled with file attributes, 
* file size in bytes and first cluster.
*  return Zero if successfully, error code otherwise
\**************************************************************************/
uint8_t SD_SearchFile(uint8_t *filename, const uint32_t cluster, const uint8_t maskSet, const uint8_t maskUnset, SD_File_t *fileinfo)
{
 uint16_t maxsect = SD_FAT.SecPerClus;
 uint32_t startsect = SD_Cluster2Sector(cluster);
 char     fnentry[12];

 if((SD_FAT.PartType != SD_PARTTYPE_FAT16) && (SD_FAT.PartType != SD_PARTTYPE_FAT32)) return(SD_ERROR_FAT_NOT_INIT);
 
 if(cluster == 0)
 {
  startsect = SD_FAT.RootDirStart; // Set root dir sector
  if(SD_FAT.PartType == SD_PARTTYPE_FAT16) maxsect = (uint16_t)((32 * (uint32_t)SD_FAT.RootEntryCount + 511)/512);
 }
    
 // convert filename to space-filled uppercase format
 for(uint8_t i = 0; i < 11; i++) fnentry[i] = ' ';
 for(uint8_t i = 0; i < 9; i++)
 {
  uint8_t c = *filename++;
  if((c < 0x20) || (c == '.')) break;
  if((c>='a') && (c<='z')) c -= 0x20;  // to upper case
  fnentry[i] = c;
 }

 for(uint8_t i = 8; i < 11; i++)
 {
  uint8_t c = *filename++;
  if(c < 0x20) break;
  if((c>='a') && (c<='z')) c -= 0x20;  // to upper case
  fnentry[i] = c;
 }
 fnentry[11] = 0;

#ifdef DEBUG
  //Serial.println(fnentry);
#endif
    
 // go through sectors
 for(uint16_t i = 0; i<maxsect; i++)
 {
  uint8_t retval = SD_ReadBlock(startsect + i);
  if(retval) return(retval);
         
  for(uint16_t j = 0; j<512; j+=32)
  {
   uint8_t attrib;
   if(SD_buffer[j] == 0) return(SD_ERROR_FILE_NOT_FOUND);    // Last entry when first character of filename == 0
   if(SD_buffer[j] == 0xe5) continue;  // Skip deleted files
   if(SD_buffer[j] == 0x05) SD_buffer[j] = 0xE5;
            
   attrib = SD_buffer[j+0x0b];
            
   // Test masks (skip long file name entries also)
   if(((attrib & maskSet) == maskSet) && ((attrib & maskUnset) == 0) && (attrib != 0x0f))
   {
    uint16_t k;
                
    // compare filename
    for(k = 0; k < 11; k++) if(SD_buffer[j+k] != fnentry[k]) break;
    if(k >= 11)
    {
     // found it
     fileinfo->Attributes = attrib;
     fileinfo->Size = (uint32_t)SD_buffer[j+0x1c] | (((uint32_t)SD_buffer[j+0x1d])<<8) 
                  | (((uint32_t)SD_buffer[j+0x1e])<<16) | (((uint32_t)SD_buffer[j+0x1f])<<24);
     if(SD_FAT.PartType == SD_PARTTYPE_FAT16)
      {fileinfo->FirstCluster = (uint32_t)SD_buffer[j+0x1a] | (((uint32_t)SD_buffer[j+0x1b])<<8);}
     else
      {fileinfo->FirstCluster = (uint32_t)SD_buffer[j+0x1a] | (((uint32_t)SD_buffer[j+0x1b])<<8) 
                            | (((uint32_t)SD_buffer[j+0x14])<<16) | (((uint32_t)SD_buffer[j+0x15])<<24);} 
                    
     // Initialize some things
     fileinfo->ActSector = SD_Cluster2Sector(fileinfo->FirstCluster);
     fileinfo->ActBytePos = 0;
     return(0);
    }
   }
  }
 }
 if(SD_FAT.PartType == SD_PARTTYPE_FAT16) return(SD_ERROR_FILE_NOT_FOUND);
 return(SD_ERROR_DIR_EOC);
}

void TFTLed(byte onoff) {
  //digital
  if (onoff == HIGH) {
    tft.drawCircle(10, 10, 1, RED);
    } else {
    tft.drawCircle(10, 10, 1, BLUE);  
    }
 }

void setup() {
 
 int i;                      // compteur de boucle
 int delai;                  // delai en microsecondes 
 bool niveau;                // niveau du signal en sortie
 bool activite;              // niveau diode d'activite
 char octet;                 // zone de stockage d'un octet
 uint32_t count;             // compteur d'octets
 uint32_t offset;            // bloc de depart
 uint16_t identifier;        // identifiant de l'ecran
  
  // Open serial communications and wait for port to open:
  tft.reset();
  identifier = tft.readID(); // lecture de l'identifiant

#ifdef DEBUG
  Serial.begin(9600);
  Serial.println(F("TFT"));
  if(identifier == 0x9325) {
    Serial.println(F("Found ILI9325 LCD driver"));
  } else if(identifier == 0x9327) {
    Serial.println(F("Found ILI9327 LCD driver"));
  } else if(identifier == 0x9328) {
    Serial.println(F("Found ILI9328 LCD driver"));
  } else if(identifier == 0x7575) {
    Serial.println(F("Found HX8347G LCD driver"));
  } else if(identifier == 0x9341) {
    Serial.println(F("Found ILI9341 LCD driver"));
  } else if(identifier == 0x8357) {
    Serial.println(F("Found HX8357D LCD driver"));
  } else if(identifier == 0x0154) {
    Serial.println(F("Found S6D0154 LCD driver"));
  } else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    return;
  }
#endif
  
  tft.begin(0x9486);         // force la librairie tft en mode ILI9486
  tft.setRotation(1);        // mode paysage
  LoadMenu();                //affichage des fichiers et selection

#ifdef DEBUG
  Serial.println(shortname);
#endif

 //Initialisations
 pinMode(0, INPUT_PULLUP);   // configurer pin0(RX) en entree (commande moteur)
 pinMode(1, OUTPUT);         // configurer pin1(TX) en sortie (donnees lues)
 pinMode(SDLEP_LED, OUTPUT); // configurer pin SDLEP_LED en sortie (led activite)
   
 SD_Init_FileSystem();       // initialiser la carte SD
 SD_SpiSetHighSpeed();       // frequence d'horloge maxi 
 
 // Search for file SD_FILE in Rootdir (=cluster 0),
 // search shortname files only (0x00,0x18)
 i = SD_SearchFile((uint8_t *)shortname, 0UL, 0x00, 0x18, &LepFileInfo);

#ifdef DEBUG
 Serial.print("R=");
 Serial.println(i);
 //Serial.println(LepFileInfo.Size);
 //Serial.println(LepFileInfo.FirstCluster);
#endif
 
 //Si le fichier est trouve alors i est nul et on passe le while sans rien faire.
 //Si le fichier n'est pas trouve alors i n'est pas nul et on boucle indefiniment.
 //Remarque : La fonction delai necessite d'avoir les interruptions actives.
 //           On peut les desactiver apres, mais pas avant.
 while(i)                        //clignotement rapide de la diode d'activite
 {                               //pour signaler un fichier non trouve
  digitalWrite(SDLEP_LED, HIGH); // allumer led activite 
  delay(5);                      // temporisation
  digitalWrite(SDLEP_LED, LOW);  // eteindre led activite 
  delay(50);                     // temporisation
 }

 //Affichage compte-rendu
 tft.fillScreen(BLACK);
 tft.setCursor(0, 20);
 tft.setTextSize(2);
 tft.setTextColor(WHITE);
 tft.print("Fichier: ");
 tft.println(shortname);
 tft.print("Taille : ");
 tft.print(LepFileInfo.Size);
 tft.println(" Octets");
  
 // send CMD18 (multiblock read)
 noInterrupts();                    // desactiver les interruptions
 offset = LepFileInfo.ActSector;    // offset = secteur de debut
 count = 0;                         // nombre d'octets lus
 if (SD_type != SD_CARD_TYPE_SDHC)  // si carte non SDHC
     offset <<= 9;                  // offset = octet
 SD_CardCommand(18, offset);        // lance CMD18
 niveau = HIGH;                     // signal a 1 pour detection lep
 digitalWrite(1, niveau);           // initialisation sortie
 activite = LOW;                    // signal a 0 pour led d'activite
 digitalWrite(SDLEP_LED,activite);  // eteindre led activite
 
 tft.println("Pret");                 // afficher message
 
 
 while(count < LepFileInfo.Size)    // tant qu'il reste des octets
 {
  // attente octet 0xfe de debut de bloc
  while(SD_SpiReadByte() != 0xfe); 
  //l'affichage d'un point provoque des erreurs de lecture
  //if((count & 4095) == 0)         // tous les huit blocs
  //tft.print('.');                 // afficher un point

  //traitement d'un bloc de 512 octets lus sur la carte SD 
  for(i = 0; i < 512; i++)
  {
   //lecture d'un octet et sortie du signal
   count++;                        // nombre d'octets lus 
   octet = SD_SpiReadByte();       // lecture d'un octet
   delai = abs(octet);             // initialisation delai
   if(octet == 0) delai = 127;     // absence de signal (127 unites)
   delai *= UNITE;                 // conversion en microsecondes
   if(octet > 0) niveau = HIGH;    // creneau positif
   if(octet < 0) niveau = LOW;     // creneau negatif
   digitalWrite(1, niveau);        // signal en sortie

   //Test MOTOR ON (a desactiver pour les essais sans cable) 
   //if(0) //pour desactiver
   if(digitalRead(0) == HIGH)        // si le moteur est arrete
   {                                 
    digitalWrite(1, HIGH);           // sortie haute pour detection LEP
    tft.fillRect(0,70,300,15,BLACK); // effacement zone ecran
    tft.setCursor(0, 70);            // positionner le curseur
    tft.println("Moteur OFF");        // afficher message
    digitalWrite(SDLEP_LED,LOW);     // eteindre la led d'activite
    while(digitalRead(0) == HIGH);   // attendre le MOTOR ON
    tft.setCursor(0, 70);            // positionner le curseur
    tft.fillRect(0,70,300,15,BLACK); // effacement zone ecran
    tft.println("Moteur ON");         // afficher message
   }

   //temporisation avant lecture de l'octet suivant
   //if(i == 511) delai -= 49;       // compensation temps chgt bloc 
   delayMicroseconds(delai);       // temporisation

  }

  //lecture des deux octets de CRC
  SD_SpiReadByte();                // lecture octet CRC1
  SD_SpiReadByte();                // lecture octet CRC2
  
  //clignotement diode d'activite
  activite = (activite == LOW) ? HIGH : LOW;
  digitalWrite(SDLEP_LED,activite);     
 }
 digitalWrite(SDLEP_LED,0);        // eteindre led activite 
 interrupts();                     //activer les interruptions
 tft.println("END OF TAPE");       //message de fin de fichier
}
[/code]
nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

Oui, il doit y avoir autre chose, il faut regarder ça de plus près...
En attendant, voici ce dont je parlais dans le code du cadre photo (la dernière ligne...) :

Code : Tout sélectionner

  else {
    Serial.print(F("Unknown LCD driver chip: "));
    Serial.println(identifier, HEX);
    Serial.println(F("If using the Adafruit 2.8\" TFT Arduino shield, the line:"));
    Serial.println(F("  #define USE_ADAFRUIT_SHIELD_PINOUT"));
    Serial.println(F("should appear in the library header (Adafruit_TFT.h)."));
    Serial.println(F("If using the breakout board, it should NOT be #defined!"));
    Serial.println(F("Also if using the breakout, double-check that all wiring"));
    Serial.println(F("matches the tutorial."));
    identifier=0x9486;
    
  }
nicolho
Messages : 409
Inscription : 10 nov. 2016 16:53

Re: SDLEP-READER remplace tous les magnétophones d'ordinateurs.

Message par nicolho »

S'il te plaît, tu pourrais essayer de recompiler et transférer le code du cadre photo, et :
- voir si ça fonctionne toujours (et nous faire une photo de ce qui s'affiche sur l'écran, histoire de convaincre tout le monde :D)
- nous montrer ce que tu obtiens avec dans le moniteur série, même si c'est comme pour le DEBUG
(si ça t'affiche un autre numéro de modèle de "LCD Driver", essaye le dans sdlep-tft, bien précédé de 0x, toujours pour tft.begin)
Répondre