[RISOLTO]Problema compatibilità libreria VGA con PS2Keyboard.

:cold_sweat:
Un saluto a tutti.
Sto provando la DUE, con VGA out e keboard PS2.

Qualcuno sà indicarmi come risolvere il problema "credo di interrupt" tra le librerie che uso ?

La stampa e la lettura del carattere sono corretti, ma durante la pressione del tasto, la visualizzazione sul display balla e alle volte il monitor perde la sincronizzazione con la VGA out, rinfrescando il display "sfarfallio e perdita allineamento dal 5 carattere in poi".

Continuando a premere altri tasti, il problema si presenta in modo random e poi si sistema da solo.

Qui sotto lo sketch che ho usato.

Un Grazie anticipato.

Giuseppe G.

#include <VGA.h>
#include <PS2Keyboard.h>

const int DataPin = 8;
const int IRQpin =  5;
PS2Keyboard keyboard;

char c;    //tasto premuto

int col=-1;  //posizione colonna
int lin=0;   //posizione riga
int colore=-1; //colore carattere

void setup() {
  //attivazione VGA out
  VGA.begin(320,240,VGA_COLOUR);
  
  //attivazione PS2
  keyboard.begin(DataPin, IRQpin);

  //cancella schermata
  VGA.setPrintWindow(0, 0, 40, 32);
  VGA.clearPrintWindow();  //cancella schermo
  VGA.drawText("TEST Due VGA Library & PS2 keyboard",24,112,0,-1,0);

  delay(5000);

  VGA.clearPrintWindow();
  VGA.fillRect(0,0,320,240,-1);
  VGA.drawRect(1,1,319,239,-240);

  //azzera posizione
  lin=1; col=1; 

  //imposta colore
  colore=240;
}


void loop() {
  
  if (keyboard.available()) {
        // read the next key
          
    c = keyboard.read();

    if (c == PS2_ENTER) {lin++;col=-1;}
    col++;
    if (col > 38) {col=1;lin++;}
    if (lin > 28) {
        VGA.clearPrintWindow();
        VGA.fillRect(0,0,320,240,-1);
        VGA.drawRect(1,1,319,239,-240);
        col=1;lin=1;
      }
    }
  
  // text colour
  VGA.setInk(colore);
  // text background colour
  VGA.setPaper(0);  

  VGA.moveCursor(col, lin);
  VGA.println(c);  
  VGA.waitSync();
}

Non hai messo il link alla lib VGA.h però immagino che se è un problema di interrupt, c'è un problema di tempistiche.
Le lib che generano il segnale video hanno delle tempistiche molto precise da rispettare perché l'informazione video deve essere spedita al monitor ad intervalli e con tempi perfettamente calibrati, altrimenti il segnale va appunto fuori sincronia.

Se la lib PS2keyboard usa anch'essa gli interrupt per leggere i tasti, allora il problema sta lì, perché se viene chiamata una ISR, ti saltano i tempi del segnale video. Una ISR è atomica, significa che non può essere interrotta da un altro interrupt. Quindi quando esegue la ISR per la lettura della tastiera, il micro non può eseguire quella per generare il segnale video: l'interrupt viene salvato e la relativa ISR viene eseguita non appena termina la precedente.

Una soluzione da provare, non so se risolve, è quella di aprire la lib PS2 e vedere se trovi una ISR.
Se la trovi, prova a cambiarla da così:
ISR(vettore)
a
ISR(vettore, ISR_NOBLOCK)
Il secondo parametro istruisce il compilare per rendere la ISR non atomica, quindi può essere interrotta da una ISR che abbia una priorità maggiore. Anche qui poi va visto se la ISR della lib VGA ha una priorità maggiore di quella usata dalla PS2, però, sennò sei punto e a capo e non hai risolto nulla.

=(
Ciao leo72, grazie per il consiglio, ma credo non funzioni, o probabilmente non ho inserito il "_NOBLOCK" nel punto giusto.

Non cambia nulla.

La modifica che ho eseguito è stata aprire la lib <PS2Keyboard.cpp> con "Dev-C++ 4.9.9.2" ed alla riga

// The ISR for the external interrupt
void ps2interrupt(void)

farla diventare
void ps2interrupt(void,VGA.startinterrupts_NOBLOCK)

Ho poi inserito "#include <VGA.h>" nella libreria PS2Keyboard.cpp.

Naturalmente ho salvato, ho chiuso l'IDE 1.5.5 e l'ho riaperto, compilando e trasferendo il nuovo codice.

Mi sono perso qualcosa? (SORRY!!! :* non sono esperto di librerie)

Il monitor, alla pressione di un tasto (anche lo SHIFT) blinka e genera sfarfallii ed alcune volte il disallineamento delle scritte.
Cosa però strana, è che se rilasciato il tasto, alle volte l'allineamento nella stampa torna, altre no.
Il fatto che sfarfalli alla pressione del tasto potrebbe anche passare, ma il disallineamento e la perdita di qualche carattere che ritorna alla pressione di un'altro tasto, non è molto bello.
Strano che nessuno non abbia ancora evidenziato il problema con la DUE!
Nel senso che nessuno abbia usato la libreria PS2 e la VGA nello stesso sketch che ho utilizzato io.
Ho cercato su internet, ma non ho trovato nulla.

Cosa mi consigli di fare? Postare eventuale problema nel forum della DUE o direttamente a chi ha "inventato" la libreria VGA ,(un certo "stimmer" che trovi sul forum VGA library - now with TV output - Arduino Due - Arduino Forum )?

Il link delle librerie, sono i seguenti:

http://www.pjrc.com/teensy/td_libs_PS2Keyboard.html
https://github.com/stimmer/DueVGA/archive/0.512.zip

Grazie ancora.
Un saluto a tutti.

Non funziona perché vedendo il codice la PS2keyboard attacca un interrupt usando la funzione attachInterrupt.
Prova in alternativa a fare così..

  1. aggiungi questo al file PS2keyboard:
#include <avr/interrupt.h>
#include <util/atomic.h>
  1. edita il codice della funzione così:
void ps2interrupt(void)
{
  NONATOMIC_BLOCK(NONATOMIC_RESTORESTATE)
  {
      ....
      codice originale
      ....
  }
}

Non so se funziona, però.
In questo modo dovresti creare un blocco non atomico all'interno di un blocco atomico del codice.
Forse andrebbe modificato il core di Arduino aprendo il codice di attachInterrupt ed andando a modificare dove effettivamente viene creata la ISR. Però credo che il lavoro diventi impegnativo e non è detto che alla fina tu riesca a risolvere. Anche vedendo poi la lib VGA.... :sweat_smile:

Forse contattare l'autore dela VGA potrebbe essere il primo passo da fare, magari qualcun altro gli ha scritto sottoponendogli lo stesso problema.

:stuck_out_tongue:
Più semplice di quanto si possa immaginare.
In questo caso è indispensabile l'ordine di inserimento delle librerie ed attivazione con il begin.
Dopo aver contattato stimmer , il quale mi ha confermato il conflitto di interrupt e consigliato di dare precedenza alla libreria più lenta (PS2keyboard), il problema è scomparso.

Occorre tener presente quindi che la precedenza di apertura ed attivazione delle librerie, diventa fondamentale in questo caso.

Ecco il codice corretto che non presenta alcun problema.

#include <PS2Keyboard.h>
#include <VGA.h>

const int DataPin = 8;
const int IRQpin =  5;
PS2Keyboard keyboard;

char c;    //tasto premuto

int col=-1;  //posizione colonna
int lin=0;   //posizione riga
int colore=-1; //colore carattere

void setup() {
  //attivazione PS2
  keyboard.begin(DataPin, IRQpin);

  //attivazione VGA out
  VGA.begin(320,240,VGA_COLOUR);
 
  //cancella schermata
  VGA.setPrintWindow(0, 0, 40, 32);
  VGA.clearPrintWindow();  //cancella schermo
  VGA.drawText("TEST Due VGA Library & PS2 keyboard",24,112,0,-1,0);

  delay(5000);

  VGA.clearPrintWindow();
  VGA.fillRect(0,0,320,240,-1);
  VGA.drawRect(1,1,319,239,-240);

  //azzera posizione
  lin=1; col=1; 

  //imposta colore
  colore=240;
}


void loop() {
  
  if (keyboard.available()) {
        // read the next key
          
    c = keyboard.read();

    if (c == PS2_ENTER) {lin++;col=-1;}
    col++;
    if (col > 38) {col=1;lin++;}
    if (lin > 28) {
        VGA.clearPrintWindow();
        VGA.fillRect(0,0,320,240,-1);
        VGA.drawRect(1,1,319,239,-240);
        col=1;lin=1;
      }
    }
  
  // text colour
  VGA.setInk(colore);
  // text background colour
  VGA.setPaper(0);  

  VGA.moveCursor(col, lin);
  VGA.println(c);  
  VGA.waitSync();
}

Un ringraziamento particolare a stimmer (l'ideatore della libreria DueVGA) e a leo72 per l'interessamento.

Giuseppe G.

Vuoi dire che, rispetto a prima, hai solo invertito l'ordine di inclusione/inizializzazione delle lib nello sketch?
A me suona tanto di sciamanesimo! :wink:

:astonished: :stuck_out_tongue: :sweat_smile: :roll_eyes: !!!!!

Provare per credere !!!!

Il problema è cercare di comprendere il motivo, cosa che da parte mia è impossibile, quindi verificandolo con lo sketch in pratica, non mi resta che accettare la soluzione degli esperti.

Comunque ribadisco che così funziona, anzi aggiungo che nel mio sketch ho aggiunto anche la comunicazione seriale la quale non mi dà alcun problema.

Se parlassimo di un chip AVR8 potrei dirti che è veramente sciamanesimo :stuck_out_tongue_closed_eyes:
Il compilatore lo conosco e so anche come sono le avr-lib e cosa c'è scritto sugli interrupt. Le priorità degli interrupt sono poi fisse quindi che tu includa prima A e poi B o viceversa non cambia, perché nel momento in cui viene sollevato un interrupt, viene eseguito prima quello con priorità maggiore.

Ma qui si parla di Due, ed io sinceramente del chip della Due ho pochissime conoscenze. Non saprei dirti se ha una gestione delle ISR differenti, per cui mi fido se mi dici che a te funziona :wink:
Sarà una cosa da studiare sulle 1400 pagine del datasheet del Sam3X :stuck_out_tongue_closed_eyes: