PGA2311 daisy chained

Bonsoir,

je suis nouveau par ici. une micro expérience en programmation et une assez bonne en électronique de grand père.

j'ai fait un tour sur le forum anglais aussi, mais je n'ai pas trouvé la réponse à mon problème.

j'ai réalisé un ampli 5+1 simple à l'aide de modules tout faits.

Il y a un décodeur qui me convertit 4 entrées num et une entrée analogique en 6 sorties, derrière j'ai inséré un groupe de 3 pga 2311 commandé par un arduino, avec un encoder et une télécommande IR pour régler le niveau.
En fait tout roule très bien pour les deux premiers canaux, mais la ou je bloque c'est sur la programation des deux autres pga, je les ai bien cablés comme prévu sur la doc. et je ne pense pas qu'il ai de soucis à ce niveau.

Mais j'avoue mon incompétence totale sur comment rajouter au programme l'envoie des infos aux derniers pga. La doc précise qu'il faut que l'entrée CS doit rester niveau bas pendant 16XN (N=nb de pga) SCLK periodes. La je ne sais pas faire la chose.
Il est précisé dans la doc que le daisy chaining des PGA forme un shift register de 16X N bits ou N est le nombre de pga.

Je me tourne vers vos lumières.

Le code de base pour le premier pga est le suivant, enfin juste la partie pour l'ajustement du gain.

 // char cGain[17];
String gain;
char icGain[6];
float iGain = 95.5;
int nGain;

void setGain(int nGain) 

{
  digitalWrite(Mute_Pin,HIGH);
  digitalWrite(PGA2311_CS_Pin,LOW);
  SPI.transfer(nGain);  // right channel
  SPI.transfer(nGain);  // left channel
  digitalWrite(PGA2311_CS_Pin,HIGH);
}

.

Merci, si vous pouvez m'aider.

Ce qui m'étonne : dans ce code on transfère deux fois nGain : alors que le gain est censé être sur 8 bits par canal.

Ce que je vois dans la datasheet :

As shownin Figure12, the SDOpin fromPGA2311#1 is connectedto the SDI inputof PGA2311#2, and isrepeatedfor additionaldevices.Thisconfigurationin turn formsa largeshift register,in whichgaindatacan bewrittenfor all PGA2311sconnectedto the serialbus.The lengthof the shift registeris 16 × N bits, whereN isequalto the numberof PGA2311devicesincludedin the chain.The CS inputmustremainLOWfor 16 × NSCLKperiods,whereN is the numberof devicesconnectedin the chain,to allowenoughSCLKcyclesto load alldevices

Donc il vaudrait mieux utiliser la méthode SPI.transfer(buffer, size) en lui passant l'adresse d'un tableau de 3 variables 16 bits (ou 6 variables 8 bits, étant donné que chaque PGA2311 comporte deux canaux).

#define PGA2311_CHANNELS      6

void setGain(uint8_t *gain)
{
  digitalWrite(Mute_Pin,HIGH);
  digitalWrite(PGA2311_CS_Pin,LOW);
  SPI.transfer(gain, PGA2311_CHANNELS);
  SPI.transfer(gain, PGA2311_CHANNELS);
  digitalWrite(PGA2311_CS_Pin,HIGH);
}

// utilisation :
// les six gains (dont un inutile puisque 5.1)
uint8_t gain[6] = {10, 10, 20, 20, 30, 30};
setGain(gain);

Ce qui m'étonne : dans ce code on transfère deux fois nGain : alors que le gain est censé être sur 8 bits par canal.

J'ai compris. SPI.transfer(uint8_t) transfère 8 bits uniquement.

  SPI.transfer(nGain);  // right channel
  SPI.transfer(nGain);  // left channel

Donc ce code transfère deux fois les 8 bits de poids faible de nGain. Il n'y a donc pas de balance ?

Bonsoir,

merci de cette réponse.
Effectivement je n'avais moi non plus pas compris au départ les deux transfert, en fait c'est gauche puis droite.
Il n'y a pas besoin, en tout cas pour mon application de balance.

Les 6 canaux, L,R, Ls,Rs, C, et Sub, tout doit être contrôlé.
Je vais tester le code ce soir.

Ce qui me titille, bien que je ne maitrise pas vraiment et c'est peut-être une question débile, c'est pourquoi on ne transfert pas 6 fois?

Je reviens avec des nouvelles.

Du coup ça me donne l'idée de faire une balance! en plus

Ce qui me titille, bien que je ne maitrise pas vraiment et c'est peut-être une question débile, c'est pourquoi on ne transfert pas 6 fois?

Dans ta version on transfère deux variables integer (16 bits) mais comme SPI.transfer() accepte un argument uint8_t seuls les 8 bits de poids faible sont transmis.
On appelle cela un cast implicite.

Dans la version que je te propose on utilise la méthode SPI.transfer(buffer, size) qui permet de transférer un certain nombre d'octets en précisant la taille, ici 6 octets.
Transférer 6 fois 1 octet serait équivalent mais moins efficace.
Sur les 6 octets, un octet sera non utilisé car le canal grave est mono, mais ce n'est pas un problème.

Je suppose que les six volumes sont différents bien sûr, au moins par paire canal gauche / droit.
Si le volume est identique pour les 3 PGA2311 tu peux bien sûr transférer 6 octets identiques.

Ah merci, je serai un peu moins bête ce soir!

Les 6 canaux sont monos, donc on a bien un octet par canal, effectivement ils seront identiques dans un puisque j'aurai réglé définitivement en hard les rapports de niveau.

J'ai hâte de tester ce soir.

Tu peux donc sans problème répéter 3 fois :

 SPI.transfer(nGain);  // right channel
 SPI.transfer(nGain);  // left channel

Si cela ne marche pas, c'est un problème de chaînage.

Bonsoir,

bon voila mon retour.

Et ben ça marche. Dans un premier temps je me suis aperçu que c'est ce que j'avais fait, c'est à dire
6 fois la commande transfert

SPI.transfer(nGain);

mais ça ne marchait pas.
J'ai essayé l'autre solution en transférant les 6 niveaux comme tu m'as indiqué en premier, mais toujours rien de bon, alors j'ai retesté le câblage...il y avait une coupure de liaison des mutes. (!) du coup 2 pga restait en mute.
Et ça marche.
Et les deux solutions sont valables.

Merci de m'avoir fait douter de mon cablâge, pourtant j'avais vérifié plusieurs fois. Comme quoi

Et les deux solutions sont valables.

Ce qui ne m’étonne pas.