Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur l'Assembleur !

Modérateur : mazertoc

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1031
Âge : 67
Enregistré en : juillet 2015
Localisation : 01120
Contact :

#211 Message par paulfjujo » sam. 17 mars 2018 17:39

bonjour,


J'ai opté pour piloter le touch screen en mode bit bang direct
avec d'autres pin MCU , donc completement séparé du pilotage LCD en SPI hardware.

XPT2016_Direct_Drive_schema.jpg


ayant connecté mon SQ50 analyser sur ces pins, j'ai été vraiment surpris du signal observé sur PEN IRQ output
SQA_XPT2046_sequence_lecture_2x8b_XYP.jpg

for heureusement, je desactive l'IRQ RB0 , des l'entree dans l'interrupt ..

J'ai un peu tourné en rond la-dessus , cherchant un probleme hardware.. mais
une lecture plus attentive de la spec sheet , montre que c'est normal ..
la pin PEN IRQ n'est plus activée si on envoi une commande de lecture X,Y,ou Z, avec PD0=1;
elle ne peut se reactiver que si on envoi une commande avec le bit PD0 à 0
.. donc sur la derniere commande 0xC0.

pourquoi ce signal sur cette PIN ?
je verrai plus tard .. une piste : capacité parasite de la bread board ~2pF et pin RB1 (lecture X,Y,Z) juste à coté ..

réecriture lecture X,Y,Z en cours, lancée, activée directement par l'interrupt IRQ PEN (RB0)
à suivre..
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
satinas
Passioné
Passioné
Messages : 285
Enregistré en : novembre 2015

#212 Message par satinas » sam. 17 mars 2018 18:18

Bonjour Paul et à tous,

Ce n'est pas nécessaire de désactiver l'int, le pic le fait par IE=0 avant d'entrer dans la routine d'interruption, et la réactive à sa sortie. Cas particulier pour les 18F à 2 niveaux d'interruption, il désactive l'int basse priorité par GIEL=0, ce qui permet à l'int haute priorité de l'interrompre (car GIEH lui est resté à 1).
Par contre l'instruction IF=0 doit être placée plutôt en fin de routine d'interruption car IF peut repasser à 1 en cours de routine, si la condition d'interruption se reproduit. La routine est exécutée alors plusieurs fois.

Très intéressant ces timings
Etonnant que la broche irq passe à zéro entre chaque octet, elle devrait le faire à la fin des 24 pulses et si PD=0, et si le touchscreen est toujours en cours d'appui. Je vérifierai de mon côté.
On voit qu'à la fin des 48 mesures, la broche irq est high, donc il y a eu relâchement pendant la lecture. Il faudrait être sur que calculer une moyenne est suffisant, peut-être aussi écarter les valeurs trop disparates. Les fonctions de lecture de touchscreen, ça se peaufine ...

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1031
Âge : 67
Enregistré en : juillet 2015
Localisation : 01120
Contact :

#213 Message par paulfjujo » dim. 18 mars 2018 11:11

bonjour,

satinas a écrit :Ce n'est pas nécessaire de désactiver l'int, le pic le fait par IE=0 avant d'entrer dans la routine d'interruption, et la réactive à sa sortie. .


C'est le cas pour GIE mais pas pour le bit INT0IE , il faut le remttre à zero avant d'entrer dans la routine de mesures x,y,z.
Je l'ai verifié en ajoutant
if(INT0IE_bit==1) TXREG1='1'; else TXREG1='0';

Code : Tout sélectionner

if ((INT0IE_bit==1) && (INT0IF_bit==1))
  {   
       
// masquer les interrupt pendant l'envoi des commandes de leture x,y,z
     // INT0IE_bit=0;
      
if(INT0IE_bit==1TXREG1='1';  else  TXREG1='0';
      
Flag_RB0=1;
        
TS_Get_Values_Bit_Bang();
      
INT0IF_bit=0;
  }
 }
 

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
satinas
Passioné
Passioné
Messages : 285
Enregistré en : novembre 2015

#214 Message par satinas » dim. 18 mars 2018 11:49

Bonjour,
A mon avis, mais je me trompe peut-être, les bits interrupt flag sont indépendants des bits interrupt enable.
Ils sont positionnés sur évènement matériel, quel que soit l'enable, et c'est au programmeur de les remettre à zéro.
Dès que tous les bits enable concernés par l'interruption sont à 1 et l'interrupt flag aussi est à 1, la routine ISR s'exécute tant que l'interrupt flag reste à 1. Quand elle s'exécute, rien ne peut l'interrompre car GIE est passé à 0 temporairement par le hardware. Le fait que INT0IE_bit reste à 1 importe peu, GIE a tout inhibé.

Faire INT0IE_bit=0 en plus de INT0IF_bit=0 dans la routine ISR te permet d'inhiber l'interrupt B0 plus longtemps car tu peux la réactiver plus tard hors de la routine. Cela n'empêchera pas INT0IF_bit de remonter, et c'est pourquoi il faut toujours remettre à zéro l'int flag avant de mettre l'int enable à 1.

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
satinas
Passioné
Passioné
Messages : 285
Enregistré en : novembre 2015

#215 Message par satinas » dim. 18 mars 2018 17:16

Quand on fait des lectures spi, la broche PENIRQ du tactile fluctue effectivement beaucoup, il ne faut pas en tenir compte.
Hors lecture, elle fonctionne bien, selon les modes PD1/PD0, elle est soit enabled (active low), soit disabled et toujours à 3,3V.

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1031
Âge : 67
Enregistré en : juillet 2015
Localisation : 01120
Contact :

#216 Message par paulfjujo » dim. 18 mars 2018 17:19

bonjour,

satinas a écrit :...les bits interrupt flag sont indépendants des bits interrupt enable.
Ils sont positionnés sur évènement matériel, quel que soit l'enable, et c'est au programmeur de les remettre à zéro.
Dès que tous les bits enable concernés par l'interruption sont à 1 et l'interrupt flag aussi est à 1, la routine ISR s'exécute tant que l'interrupt flag reste à 1. Quand elle s'exécute, rien ne peut l'interrompre car GIE est passé à 0 temporairement par le hardware. Le fait que INT0IE_bit reste à 1 importe peu, GIE a tout inhibé.


:-D tout à fait d'accord avec ceci..

Faire INT0IE_bit=0 en plus de INT0IF_bit=0 dans la routine ISR te permet d'inhiber l'interrupt B0 plus longtemps car tu peux la réactiver plus tard hors de la routine.


:sifflotte: C'est bien ce je veux.


Cela n'empêchera pas INT0IF_bit de remonter, et c'est pourquoi il faut toujours remettre à zéro l'int flag
avant de mettre l'int enable à 1.


c'est ce que je fais dans ma fonction Arme_Interrupt_RB0()

Code : Tout sélectionner


void Arme_Interrupt_RB0
(void)
  {
    Flag_RB0=0;
    INTEDG0_bit=0;  //IT on falling edge
     RCON.IPEN = 1;
    INT0IF_bit=0;
    INT0IE_bit=1;
    GIE_bit=1;
    }



:mur: par contre, pour l'instant mon code n'est pas satisfaisant, j'obtiens des mesures non repetitives ..
Je me sers de ce chronogramme:
XPT2046_sequence_lecture_24_clock.jpg


et le code qui va avec
.. tres LINEAIRE !

SQA50 est une sortie MCU pour synchroniser la capture analyser logique.
j'utilise de délay de 8µS pour chaque bit .. donc reste < à 125KHz meme si mon FOSC est à 32MHZ.

Code : Tout sélectionner



void Delay_8us
()
{
 Delay_us(5);
 }

void TS_Get_Values_Bit_Bang(void)
{
  Byte Cmd;
  Word i,j,k;
  Word xx,yy;
  xx=0;yy=0;
  Press=0;x=0;y=0;z1=0;z2=0;z0=0;
  T_DIN=0; T_CLK=0;T_CS=0;
  for (i=0;i<12;i++)
  {

    // --- debut mesure xx ------------
      T_CS=0;
      T_DIN=0;
      T_CLK=0;
      Cmd=0xD1;    // Cde mesure xx
      SQA50=1;
      for (j=0;j<8;j++)
      {
        if( (Cmd & 0x80)==0x80)
        {
          T_DIN=1;
          }
           else
          
{
            T_DIN=0;
            }
           T_CLK=1;
         Delay_8us();
          T_CLK=0;
        Cmd=(Cmd<<1);
        }
        T_DIN=0;
       SQA50=0;
       
       xx
=0;
       // laisse passer le 1er bit
        SQA50=1;
        Delay_8us();
        T_CLK=1;
       Delay_8us();
       T_CLK=0;
       k=2048;
       for (j=0;j<11;j++)
       {
         T_CLK=1;
         Delay_8us();
         T_CLK=0;
         _asm NOP;
         _asm NOP;
         if(T_DO==1)
         {
            xx = xx + k;
           }
          k=k>>1;
       }
       T_DO=0;
        //laisse passer les 3 dernier bits à zero
       T_CLK=0;T_CLK=1;Delay_8us();T_CLK=0;
       T_CLK=0;T_CLK=1;Delay_8us();T_CLK=0;
       T_CLK=0;T_CLK=1;Delay_8us();T_CLK=0;
       T_CS=1;
       Delay_8us() ;
       T_DIN=0;
        //------------------ fin de  xx mesure-----

      Cmd=0x91;  // mesure yy
      z1=0;
      T_CS=0;
      SQA50=1;
      for (j=0;j<8;j++)
      { 
        if
( (Cmd & 0x80)==0x80)
        {
          T_DIN=1;
          }
           else
          
{
            T_DIN=0;
            }
         T_CLK=1;
         Delay_8us();
        Cmd=Cmd<<1;
         T_CLK=0;
         Delay_8us();
        }

       T_DIN=0;
       SQA50=0;
       Delay_8us();

       yy=0;
       // laisse passer le 1er bit
       SQA50=1;
       T_CLK=1;
       Delay_8us();
       T_CLK=0;
        Delay_8us();
       k=2048;
       for (j=0;j<11;j++)
       {
         Delay_8us();
          T_CLK=1;
         Delay_8us();
         T_CLK=0;
         _asm NOP;
         if(T_DO==1) yy = yy + k;
         k=k>>1;
       }
       T_DO=0;
        //laisse passer les 3 dernier bits à zero
       T_CLK=1;Delay_8us();T_CLK=0;Delay_8us();
       T_CLK=1;Delay_8us();T_CLK=0;Delay_8us();
       T_CLK=1;Delay_8us();T_CLK=0; Delay_8us();
       T_CS=1;

        //------------------ fin de mesure-----
      Delay_8us();

      T_DIN=0;
      T_CLK=0;
      Cmd=0xB1;   //  mesure z1
      T_CS=0;
      SQA50=1;
      for (j=0;j<8;j++)
      { 
        if
( (Cmd & 0x80)==0x80)
        {
          T_DIN=1;
          }
           else
          
{
            T_DIN=0;
            }
        Delay_8us();
        Cmd=Cmd<<1;
        T_CLK=1;
        Delay_8us();
        T_CLK=0;
        }
       T_DIN=0;
        Delay_8us();
      SQA50=0;

       z1=0;
       // laisse passer le 1er bit
       T_CLK=0;
       Delay_8us();
       T_CLK=1;
       Delay_8us();
       T_CLK=0;
        Delay_8us();
       k=2048;
       for (j=0;j<11;j++)
       {
         Delay_8us();
          T_CLK=1;
         Delay_8us();
         T_CLK=0;
         _asm NOP;
         if(T_DO==1) z1 = z1 + k;
         k=k>>1;
       }
       T_DO=0;
        //laisse passer les 3 dernier bits à zero
      T_CLK=1;Delay_8us();T_CLK=0; Delay_8us();
      T_CLK=1;Delay_8us();T_CLK=0; Delay_8us();
      T_CLK=1;Delay_8us();T_CLK=0; Delay_8us();
       T_CS=1;
        //------------------ fin de mesure-----
      Delay_8us();

      T_DIN=0;
      T_CLK=0;
      Cmd=0xC0;  //  mesure z2
      T_CS=0;
      SQA50=1;
      for (j=0;j<8;j++)
      { 
        if
( (Cmd & 0x80)==0x80)
        {
          T_DIN=1;
          }
           else
          
{
            T_DIN=0;
            }
        Cmd=Cmd<<1;
        T_CLK=1;
         Delay_8us();
        T_CLK=0;
        }
       T_DIN=0;
       Delay_8us();
        SQA50=0;
    
       z2
=0;
       SQA50=1;
       // laisse passer le 1er bit
       T_CLK=1;
       Delay_8us();
       T_CLK=0;
        Delay_8us();
       k=2048;
       for (j=0;j<11;j++)
       { 
        Delay_8us
();
          T_CLK=1;
         Delay_8us();
         T_CLK=0;
         _asm NOP;
         if(T_DO==1) z2 = z2 + k;
         k=k>>1;
       }
       T_DO=0;
        //laisse passer les 3 dernier bits à zero
       T_CLK=1;Delay_8us();T_CLK=0;Delay_8us();
       T_CLK=1;Delay_8us();T_CLK=0;Delay_8us();
       T_CLK=1;Delay_8us();T_CLK=0; Delay_8us();
       T_CS=1;
       Delay_8us();
       SQA50=0;
        //------------------ fin de  mesure-----


     if ((>= 2) && (< 10))
     {
       x = x + xx;      // cumul xx
       y = y+ yy;       // cumul yy
       z0 = z0+(z2-z1);  // cummul ecart z2 -Z1
      }
   // Delay_ms(2);
   }
   x= x >>3;   // moyenne de 8 valeurs
   y= y >>3;   // moyenne de 8 valeurs
   Press= 4095 -(z0>>3);

   T_CS=1;
   SQA50=0;
   T_DIN=0;
   Flag_RB0=2;    // fin de mesures
}



j'ai meme rajouté un bout de code TEST , pour verifier la serialité des bits de commande.. ..OK avec analyser .
par contre coté lecture ..on ne peut que subir ce qu'on recoit .
Je n'ai pas vu dans la datasheet , s'il fallait un delay entre la detection interrupt et le lancement des lectures X,Y,Z
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
satinas
Passioné
Passioné
Messages : 285
Enregistré en : novembre 2015

#217 Message par satinas » dim. 18 mars 2018 17:40

Tu as vu le post que j'ai fait juste avant le tien ?
Tu devrais faire un paint, il permet de voir la précision de saisie. Lorsqu'on se ballade en étant appuyé, le tracé est impeccable. Par contre lors du premier appui ou lors du relâchement des points parasites apparaissent, assez éloignés du point de saisie. C'est pourquoi j'ai écarté les 2 premières et les 2 dernières mesures, mais c'est pas suffisant.
J'ai eu moins de souci avec le tactile spi du tft 16 bits idem celui de JMarc, qui avait un ADS7843, compatible avec le XPT2046.

RCON.IPEN = 1
tu utilises les 2 niveaux d'interruption ?

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1031
Âge : 67
Enregistré en : juillet 2015
Localisation : 01120
Contact :

#218 Message par paulfjujo » dim. 18 mars 2018 18:08

satinas a écrit :Tu as vu le post que j'ai fait juste avant le tien ?
Tu devrais faire un paint, il permet de voir la précision de saisie. Lorsqu'on se ballade en étant appuyé, le tracé est impeccable. Par contre lors du premier appui ou lors du relâchement des points parasites apparaissent, assez éloignés du point de saisie. C'est pourquoi j'ai écarté les 2 premières et les 2 dernières mesures, mais c'est pas suffisant.
J'ai eu moins de souci avec le tactile spi du tft 16 bits idem celui de JMarc, qui avait un ADS7843, compatible avec le XPT2046.


Code : Tout sélectionner

Lorsqu'on se ballade en étant appuyé,

On ne tient donc pas compte de l'IRQ PEN, puisqu'on ne leve pas le stylet ?
paint : en boucle permanente de lecture x,y et affichage pixel correspondant ?

satinas a écrit :RCON.IPEN = 1
tu utilises les 2 niveaux d'interruption ?


Pas dans l'immediat , mais ça va venir .. avec timer1 en Low Level pour lancer des mesures ADC toutes les secondes.
sans etre en mode pooling dans le main programme (avec Delay_1sec())

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
satinas
Passioné
Passioné
Messages : 285
Enregistré en : novembre 2015

#219 Message par satinas » dim. 18 mars 2018 18:35

Le tactile est surveillé en mode polling.

Code : Tout sélectionner

while (1) {
  bool pressed = tsPressed();   // soit lire TS_IRQ, soit lire z0 > 200
  if (pressed) {
    tsRead();                   // lire et moyenner x,y
    convert();                  // conversion coordonnées ts -> lcd
    plot();                     // tracé point
  }
}

Le tsPressed() qui ne fait que lire TS_IRQ bave sur les appuis ponctuels rapides, les tracés en continu sont corrects.
le tsPressed() qui lit z0 marche bien mieux pour les appuis rapides, il est tout à fait utilisable.
Par contre si on ne moyenne pas, le tracé c'est des gros pâtés.
En passant le nombre d'échantillons de 8 à 32, ça marche même en utilisant TS_IRQ.

écran tactile 2.4 TFT LCD 240 x 320 (version ASM)
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1031
Âge : 67
Enregistré en : juillet 2015
Localisation : 01120
Contact :

#220 Message par paulfjujo » mar. 20 mars 2018 16:58

satinas a écrit :En passant le nombre d'échantillons de 8 à 32, ça marche même en utilisant TS_IRQ.


il faut alors utiliser un entier long pour stocker le cumul ?
32 x 4096 > 65535
sinon risque d'overlapping.

Je viens de passer FOSC LCD de 32 à 64MHz (16MHz*PLL)
et l'affichage ecran ne repondait plus ..
J'utilisais SPI1_Init(); de MikroC
en utilisant la fonction (évoluée), qui permet un reglage de SPI clock

Code : Tout sélectionner

SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16_SPI_DATA_SAMPLE_MIDDLE_SPI_CLK_IDLE_LOW_SPI_LOW_2_HIGH);  

C'est BON, l'ecran suit la vitesse du SPI..
J'en conclus que SP1_Init(); est à FOSC/4
la preuve

J'initialise avec

Code : Tout sélectionner

SPI1_Init();
mais je modifie derriere le registre MCU :
SSP1CON1=(SSP1CON1 0xF0) | // FOSC/16   


et l'affichage LCD est OK.

Je vais me repencher sur le Touch Screen en mode SPI ..
en differenciant l'ecriture: commande T_DIN validée sur front montant
et lecture T_DO validée sur front Descendant
avec le bit CKP à modifier apres la commande.
et aussi ralentir le SPI..


Retourner vers « Langage ASM »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 4 invités