Communication arduino avec un TMP82c79P

Bonjour à tous,
Nouveau sur le forum arduino, je me permet de venir vous demander de l'aide. Nous essayons de communiquer avec un TMP. Nous arrivons bien à le sélectionner, mais il n'y pas de retour du status.

Un projet github a été fait et il est consultable à l'adresse suivante : GitHub - DPCLive/pupitre: Interface pupitre Sony DVS-8000

En faisant les différents tests avec le code suivant, nous arrivons bien à sélectionner et à communiquer avec le TMP82c79P (IC80 sur le schéma attaché du topic).

/////////////////////////////////////////////////////////////////////////////////////
// D0-D7 Port A (0-7)
// A1-A8 Port C (0-7)
// A9-A11 Port L (0-2)
// CLK PWM 11
// WR Port G (0)
// RD Port G (1)
// Reset Port B (0)
/////////////////////////////////////////////////////////////////////////////////////
 
 
int blinkPin = 11;
int wr_pin = 41;
int rd_pin = 40;
int reset_pin = 53;
 
int test_input_pin = 7;
 
void TimerOne_setPeriod(long OCRValue)
{
 TCCR1B = (1 << WGM12) | (1 << CS10); 
 
 TCCR1A = bit(COM1A0);                      //  or use TCCR1A = 0x40;            // Toggle mode 0C1A  
 OCR1A = OCRValue;                          // set the counter
}
 
void TMP_Select(uint8_t a0)
{
  delayMicroseconds(100);
    PORTL = 0x00; // A9..A11
 
/*
 * Sélection du TMP IC80
 
Bus adresse sur la nappe
 
  A7..A11  : 0
  A6: 1
  A5: 0
  A4: 1 (C)74 HC138 numéro IC6
  A3: 1 (B)74 HC138 numéro IC6
  A2: 1 (A)74 HC138 numéro IC6
  A1: a0 du TMP (sélection du registre)
 
  */  
    if (a0)
    {
      //  A8  ... A1
      PORTC = B00101111;
    }
    else
    {
      //  A8  ... A1
      PORTC = B00101110;
    }
    delayMicroseconds(100);
}
 
 
 
void TMP_WriteCommand(uint8_t data)
{
  digitalWrite(rd_pin, HIGH);
  digitalWrite(wr_pin, LOW);
 
  delayMicroseconds(1000);
 
  TMP_Select(1);
 
  PORTA = data;
 
  delayMicroseconds(1000);
 
  digitalWrite(wr_pin, HIGH);
 
  delayMicroseconds(1000);
}
 
 
void TMP_WriteData(uint8_t data)
{
  digitalWrite(rd_pin, HIGH);
  digitalWrite(wr_pin, LOW);
 
  delayMicroseconds(1000);
 
  TMP_Select(0);
 
  PORTA = data;
 
  delayMicroseconds(1000);
 
  digitalWrite(wr_pin, HIGH);
 
  delayMicroseconds(1000);
}
 
uint8_t TMP_ReadData()
{
  digitalWrite(rd_pin, LOW);
  digitalWrite(wr_pin, HIGH);
 
  delayMicroseconds(1000);
 
  uint8_t data = PINA;
 
  delayMicroseconds(1000);
  digitalWrite(rd_pin, HIGH);
 
  delayMicroseconds(1000);
 
  return data;
}
 
void setup() {
  // put your setup code here, to run once:
 
  DDRC = B11111111;  // 1 == outputs, 0 == input
  DDRL = B11111111;  // 1 == outputs, 0 == input
 
// Bus de données
  DDRA = 0;  // 1 == outputs, 0 == input
 
// Configuration du bus de contrôle
  pinMode(wr_pin, OUTPUT); 
  pinMode(rd_pin, OUTPUT); 
  pinMode(reset_pin, OUTPUT);
  pinMode(test_input_pin, INPUT);
 
  // On place le bus de contrôle à un état stable
  digitalWrite(rd_pin, HIGH);
  digitalWrite(wr_pin, HIGH);
  digitalWrite(reset_pin, HIGH);
 
   delayMicroseconds(1000);
 
   TMP_WriteCommand(B00000100); // Configure TMP en mode "Encoded Scan Sensor matrix", le reste par défaut
 
   TMP_WriteCommand(B00100101); // clock divided by 5
 
  // PARAMETRAGE HORLOGE 
   pinMode(blinkPin, OUTPUT);                 // alternately use DDRB = 0xa0;      // turn on the timer ouput pin;
  TimerOne_setPeriod(6);                 // set up and start Timer1 to blink at the same rate as the blink sketch
 
    // open the serial port at 9600 bps:
  Serial.begin(9600);
}
 
void loop() {
  uint8_t data = 0;
 
  TMP_Select(1); // status 
  /*data = TMP_ReadData();
  Serial.println("STATUS");
  Serial.println(data, BIN);  // print as an ASCII-encoded binary*/
 
/*
  TMP_WriteData(B01000000);
  TMP_Select(0); // data
  data = TMP_ReadData();
   Serial.println("DATA");
  Serial.println(data, BIN);  // print as an ASCII-encoded binary
*/
 
  delay(200);
 
}

Avec :

TMP_Select(1);

Le TMP (IC80), nous retour "0" en permanence en console quand on appuie sur un bouton rien ne change pas.

Avec :

TMP_Select(0);

Le TMP (IC80), nous retour "101000" en permanence en console quand on appuie sur un bouton rien ne change pas.

Voici la doc du TMP en question : https://static6.arrow.com/aropdfconv...0/tmp82c79.pdf

Nous avons vérifié les différents câblages et ils sont bon.

Nous aimerions savoir si les informations envoyées au TMP sont bien juste?

Dans l'attente de votre expertise.

Cordialement,

Vincent.

Bonjour

ça demande réflexion ... les circuits intégrés de gestion de clavier/afficheur de ce type sont d'une autre époque(Intel 8080 et compagnie) et il faut se plonger dans le chronogramme à reproduire pour accéder au composant...

ce n'est pas une mince affaire....!!!
A l'époque des bus série divers la communication avec un composant monté sur un bus parallèle de ce type a été perdue de vue....

Voici un lien vers le pdf du composant, votre lien n'est pas fonctionnel

-le 82c79 est-il totalement libre , sous contrôle exclusif de votre application ou est-il utilisé en parallèle par d'autres composants de la carte d'origine ?

-que cherchez vous à faire avec ce circuit ? juste récupérer l'info clavier ?

Bonjour,

Merci de votre réponse.

Le 82C79 est sur une carte électronique d'origine. nous avons connecté une nappe sur le arduino.

Cette nappe contient

  • 11 pins d'adresse
  • 8 pins de données
  • 2 pin clock en différentiel
  • 2 pin reset en différentiel
  • 1 pin write
  • 1 pin read

et 30 pins de masse

Nous arrivons à sélectionner le TMP et lui envoyer le mode lecture ou écriture.

Nous avons paramétré les timing diagram selon la documentation du TMP.

Après le TMP il y a des composants présents sur l'image ci-joint.

Pour l'instant, nous essayons de lire le status du TMP pour être sur que les informations envoyées sont bonnes en appuyant sur le clavier.

Merci d'avance.

Cordialement,

Vincent.

ne craignez vous pas les conflits hardware en accédant au 82c79 en concurrence avec d'autres composants ?
(Imaginez que vous écriviez une donnée dans le CI alors qu'au même moment celui-ci est accédé en lecture par ailleurs...)

Pour l'instant, nous essayons de lire le status du TMP pour être sur que les informations envoyées sont bonnes en appuyant sur le clavier.

Je comprend l'objectif immédiat mais au delà quelle est la finalité de ces accès au 82c79 ? qu'en attendez vous ?

Les autres composants sont des SN74HC

Voici une image du plan plus net:

Voici le plan de la nappe au TMP : Communication arduino avec un TMP82c79P - Français - Arduino Forum

Cordialement,

Vincent.

on voit la la 'glue logic' qui permet à un micro-processeur ou un micro controlleur de piloter le 82c79

mais s'il ya un 82c79 c'est qu'il ya quelque part un micro processeur qui orchestre tout ça !!
Le 82c79 n'est qu'un périphérique de gestion de gestion de clavier et d'affichage.

Mes questions des messages #1 et #3 tiennent toujours

Le micro processeur de base ne peut pas nous servir. Donc on souhaite le remplacer par un arduino.

OK je comprend mieux la problématique,
82c79, avec sa logique d'accompagnement, sous contôle exclusif d'une carte Arduino

Ce qui est bon signe, c'est que nous arrivons à sélectionner le TMP en question.

Il y a plusieurs TMp sur la Carte, et après vérification, les autres TMP ne sont pas sélectionné.

Nous avons vérifier également les pin du TMp et on a bien ehn lecture :

CS et RD = 0
A0 = WR = 1

Le micro processeur de base ne peut pas nous servir. Donc on souhaite le remplacer par un arduino.

Pouvez vous au moins faitre travailler temporairement la carte avec ce processeur et avec un analyseur logique bien repérer les échanges processeur<->82c79 avec le signalement des actions sur le clavier ?

ça complèterait la data sheet pour bien préparer votre hacking.

Nous pouvons envisager, mais je n'ai pas d'analyseur de logique.

Est-il obligatoire?

Merci beaucoup pour les réponses.

82c79 pétard cela ne nous rajeunit pas ...

...ou ça rejeunit ... tout dépend comment on prend la chose !! :wink:
En cherchant bien on doit trouver du code assembleur 8080/8085 pour gérer ce périphérique !
Içi la doc d'origine d'Intel (8279)

pour comprendre ce qui se passe dans ce genre de situation l'analyseur logique me parait vite indispensable
il permettrait de mieux comprendre l'écart entre les chonogrammes qui vont bien et les autres ainsi que des subtilité s de protocole qui ne sautaient pas aux yeux à la lecture de la doc

vu le nombre de traces à observer mieux vaudrait içi un modèle 16 bits

Merci beaucoup pour ces informations.

Une personne à déjà mis en place un projet pour le même modèle que le mien.

Mais n'utilisant pas un arduino :

Dans le code, il y a une partie i8279. Mais je n'arrive pas à le comprendre. Peut-être qu'il pourrait vous aider à m'aiguiller.

Une remarque

en balayant superficiellement le code du projet abouti, essentiellement bus.h, bus.c, i8279.h et i8279.c on remarque tout de suite une évidence : le port du microcontroleur relié au bus bidirectionnel 8 bits du 8279 doit être tantôt en sortie pour les écritures de données , tantôt en entrée pour les lectures.

je ne vois pas cette oparation dans votre code : le PORTA ne subit pas de permutation de sens (Entrée/Sortie) du Port en fonction de l'opération à faire (Lecture/Ecriture).

Ecrire :

PORTA = data;
OU
uint8_t data = PINA;

ne suffit pas à assurer le transfert voulu entre Arduino et 8279, il faut préalablement gérer DDRA pour établir le sens.

Le code du projet fait appel à des opérations simples et la seule difficulté pour un novice est l'utilisation des masques pour positionner divers bits.
En se documentant sur les masques en C et les opérations logiques bit à bit ça devarit devenir compréhensible

Prenons par exemple la fonction read() du projet abouti

void read(uint8_t * dest){
 _delay_us(0.2);
 DDRA = 0; //le bus A est configuré en ENTREE
 PORTD &= ~(1 << 3); // RD (PORTD.3)  est mis à l'état bas

 _delay_us(0.5); // tempo
 *dest = PINA; // l'état du Port A et copié dans la variable dest (pointée)
 PORTD |= (1 << 3); //RD est mis à l'état haut

 // Bus direction to output
 PORTA = 0xFF; // 
 DDRA = 0xFF; // le port A est remis en SORTIES
}

Bonjour,

Je me permet de revenir avec mon code modifié avec les éléments du projet abouti :

Sauf qu'avec le code suivant :

int blinkPin = 11;
int wr_pin = 41;
int rd_pin = 40;
int reset_pin = 53;

void TimerOne_setPeriod(long OCRValue)
{
 TCCR1B = (1 << WGM12) | (1 << CS10); 

 TCCR1A = bit(COM1A0);                      //  or use TCCR1A = 0x40;            // Toggle mode 0C1A  
 OCR1A = OCRValue;                          // set the counter
}

void setup() {

    DDRC = B11111111;  // 1 == outputs, 0 == input
  DDRL = B11111111;  // 1 == outputs, 0 == input
  PORTL = 0x00; // A9..A11
  
  PORTC = B00101110;
  PORTL = B00000000;
  //PORTC = (1 << 1);

  
  // put your setup code here, to run once:
    pinMode(wr_pin, OUTPUT); 
   pinMode(rd_pin, OUTPUT); 
     pinMode(reset_pin, OUTPUT);
  digitalWrite(rd_pin, HIGH);
  digitalWrite(wr_pin, HIGH);
  digitalWrite(reset_pin, HIGH);
  write_cmd(B00000100);// Configure TMP en mode "Encoded Scan Sensor matrix", le reste par défaut
  write_cmd(B00100101);// clock divided by 5
   
  // PARAMETRAGE HORLOGE 
   pinMode(blinkPin, OUTPUT);                 // alternately use DDRB = 0xa0;      // turn on the timer ouput pin;
  TimerOne_setPeriod(6);                 // set up and start Timer1 to blink at the same rate as the blink sketch

  
  Serial.begin(9600);
}

void loop() {
      uint8_t row;
    uint8_t key;

  //addr_select(4);
    
int val = get_keys(&row, &key);
delay(1000);
 Serial.print("KEYS : ");
 Serial.println(val);

 
  Serial.print("PIN C : ");
  Serial.print(PINC, BIN);
  Serial.print("      -       PIN L : ");
  Serial.println(PINL, BIN);

  
   Serial.print("PIN A : ");
  Serial.println(PINA, BIN);
  //test_pin();
}

void status(){
    uint8_t status;
    read_status(&status);
    //check_errors(&status);
     Serial.print("STATUS : ");
    Serial.println(status);
}

void read_status(uint8_t *dest){
    unsigned char _sreg = SREG;
    cli();
    PORTC |= (1<<0);//A0
    read(dest);
    Serial.print("STATUS READ : ");
    Serial.println((uint8_t)dest);
    SREG = _sreg;
}

void read(uint8_t * dest){
    _delay_us(0.2);
    DDRA = 0; //Bus direction: input
    digitalWrite(wr_pin, HIGH);
    digitalWrite(rd_pin, LOW);
  /*  Serial.print("PIN G : ");
  Serial.println(PING, BIN);*/
    _delay_us(0.5);
    *dest = PINA;
    
    digitalWrite(wr_pin, HIGH);
      digitalWrite(rd_pin, HIGH);
  /*  Serial.print("PIN G : ");
  Serial.println(PING, BIN);*/
    // Bus direction to output
    PORTA = 0xFF;
    DDRA = 0xFF;
}

void write(uint8_t data){
    DDRA = 0xFF; // bus direction: output
    PORTA = data;
    digitalWrite(rd_pin, HIGH);
      digitalWrite(wr_pin, LOW);
    _delay_us(1);
    digitalWrite(rd_pin, HIGH);
    digitalWrite(wr_pin, HIGH);

    DDRA = 0;
    PORTA = 0;
}


void write_cmd(uint8_t data){
    unsigned char _sreg = SREG;
    cli();
    PORTC |= (1<<0);//A0
    write(data);
    SREG = _sreg;
}

int check_errors(uint8_t *status){
    // TODO using prints for debug and lazyness reasons
    if(*status & 0x08){
        Serial.println("FIFO full!");
        return 1;
    }
    else if(*status & 0x10){
        Serial.println("FIFO Underrun!");
        return 2;
    }
    else if(*status & 0x20){
        Serial.println("FIFO Overrun!");
        return 3;
    }
    else if(*status & 0x40){
        Serial.println("Multiple Closures");
        write_cmd( (6 << 5) | (1 << 1) );
        return 4;
    }
    else if(*status & 0x80){
        Serial.println("Display unavailable");
        return 5;
    }
    return 0;
}

int get_keys(uint8_t *row, uint8_t *key){
    uint8_t status;
    uint8_t data;
    read_status(&status);
    check_errors(&status);
    if( (status & 0x07) && !check_errors(&status) ){
      Serial.println("Ok");
        write_cmd(2 << 5);
        read_data(&data);
        *row = (data>>3)&0x7;
        *key = (data)&0x7;
        return 1;
    }
    return 0;
}

void read_data(uint8_t *dest){
    unsigned char _sreg = SREG;
    cli();
    PORTC &= ~(1<<0);//A0
    read(dest);
    SREG = _sreg;
}

void addr_select(int addr){
    PORTC &= ~(0x1 << 3);  // PORT B
    PORTC |= (addr & 0x1) << 3; // PORT B

    PORTC &= ~0x7;// PORT B
    PORTC |= (addr & 0xe)>>1;// PORT B

    PORTL = (addr & 0x1F0)>>4;
}

Il ne rentre jamais dans le if de cette partie :

int get_keys(uint8_t *row, uint8_t *key){
    uint8_t status;
    uint8_t data;
    read_status(&status);
    check_errors(&status);
    if( (status & 0x07) && !check_errors(&status) ){
      Serial.println("Ok");
        write_cmd(2 << 5);
        read_data(&data);
        *row = (data>>3)&0x7;
        *key = (data)&0x7;
        return 1;
    }
    return 0;
}

La console me retourne :

KEYS : 0
PIN C : 101111      -       PIN L : 0
PIN A : 11111111
STATUS READ : 250
FIFO Underrun!

Est-ce des éléments concluant ou cela ne veut rien dire?

Dans l'attente.

Cordialement,

Vincent.

Bonjour,

Nous essayons toujours de pouvoir communiquer avec notre TMP.

L'ancien processeur envoyait une clock à 100hz.

Avec notre code avec une clock à 100khz et un analyseur logique, nous obtenons ce graphe (je ne sais pas si cela peut aider, mais on sait jamais)

Est-ce que la fréquence est trop rapide?

Je suis preneur de toute réponse pour espérer avance avec ce TMP.

Merci d'avance de votre aide précieux.

Cordialement,

Vincent.

En sortie ( avec l'attestation !) je n'ai pas acces a la notice des 8279. Le signal /RD m'intrigue, je m'attendais comme pour /WR a des impulsions a l'état bas.

Bonjour al1fch,

Merci de votre réponse. Voici la doc du TMp en question :

Merci d'avance de votre aide.

Cordialement,

Vincent

Avec mon petit téléphone jen ne regarde pas les data sheet !

Avec cette doc sous les yeux suivez pas a pas, intervalle de temos par ibtervalle de temos les chronogrammes enregistrés, mettez vous 'a la place' du
8279 et demandez vous ce qu'il comprend et fait.
Ces chronogrammes s'épluchent en etudiant des bandes verticales successives.