Pilotage d’un SI570 par Arduino ou Energia.

Bonjour à tous,

Toujours difficile pour moi de concilier mon boulot, mes paramètres familiaux préférés, mes bidouillages et mon blog. bref… à défaut de post régulier, j’essaie de faire dans le truc rigolo.
Cet article a pour but d’expliquer comment prendre le contrôle d’un SDR Softrock Ensemble RX/TX (juste prendre le contrôle de l’oscillateur local) par le biais d’une platine Launchpad de Texas Instrument, programmable en Energia, un clone d’ Arduino. évidement, n’importe quel Arduino 3v3 avec une sortie I2C doit/peut faire pareil.
Cet article vas être découpé en plusieurs morceaux, je vais commencer par expliquer rapidement mon branchement (provisoire) sur mon EnsembleRxTx. puis l’explication de la datasheet du SI570, et enfin, une pseudo implémentation, non totalement fonctionnelle, mais suffisamment aboutie pour bien comprendre le concept.

1) Branchement du Softrock

La launchpad dispose d’une sortie I2C sur ces pattes P1_6 et P1_7. il suffit donc de connecter ces pins + la masse au softrock.
Pour cela, j’ai retiré le attiny85, et j’ai utilisé le support tulipe pour insérer mes fils.

voici le lien du schéma de l’oscillateur, il doit être commun à tous les softrocks :

 

Il suffit maintenant de connecter SDA (P1_7) ; SCL (P1_6) et GND au pattes 6, 2 et 4 du support. il reste à alimenter les 2 montages,  l’oscillateur s’alimente par le port USB, (le PC vous dira qu’un périphérique n’est pas reconnu.. comme c’est étrange ! lol ) et la Launchpad s’alimente par son propre port USB.

C’est tout ! plus qu’a jouer avec la Launchpad. comme elle est directement en 3v, pas de problème. attention toute fois aux Arduino, certain sont 5v.

 

 2) SI570 : mode de fonctionnement.

Connaitre son SI570 et sa fréquence de démarrage :

Téléchargez le datasheet suivant : SILABS SI570 DATASHEET rev 1.4

Le SI570 se pilote par I2C. il dispose d’une adresse (0x55) et d’un certain nombre de registres 8 bits. Ces registres contiennent les valeurs des 2 diviseurs, et le nécessaire de programmation/lecture de la fréquence en cours.

1ere étape, comprendre à quel SI570 on a affaire (rdv page 27-28).
la référence inscrite sur le SI570 nous donne des éléments important de compréhension. pour le mien : CAC 000-141 G
après analyse : cela me donne : 3,3v ; 50ppm ; 10-160 Mhz ; et surtout 56.320 Mhz

Il s’agit de la fréquence de démarrage. cette fréquence est ultra importante, car chaque SI570 dispose d’une fréquence interne différente (FXTAL). Cette fréquence doit se calculer en lisant les registres, et en connaissant la fréquence de sortie.

Comprendre l’architecture interne, pour comprendre les registres :

si570 block diagram

 

Ce schéma, provenant du datasheet page 4 est d’une remarquable clarté. on constate que la fréquence intermédiaire FDCO et issue de la multiplication de  FxTAL et de RFREQ (contenue dans la ROM au démarrage). Cette fréquence Intermédiaire et divisée par HSDIV puis par N1 avant de produire le signal de sortie.

Donc :

FXTAL = ( fOUT  x HSDIV x N1 ) / RFREQ

Du coup, si  FOUT = 56.320, il suffit de lire les registres pour connaitre les autres valeurs et ainsi déterminer Fxtal.
Une fois FXTAL connue, on applique la formule : FOUT = (FXTAL x RFREQ) / ( HSDIV x N1)

3) Les Registres :

Les registres commence à 7 ou à 13 en fonction de la version de SI570. je prend l’exemple de 7, mais cela ne change rien.

registres

Le principal problème de ces registres est le stockage sous forme de 8 bits. cela nous oblige à un petit peut de gymnastique.

HSDIV :

Le registre 7 contient 2 éléments : HSDIV et une partie de N1.

Donc HSDIV = Reg7 >> 5 ( je décale de 5 bits vers la gauche.)
Par contre, il y a table de correspondance… on voit que lorsque HSDIV = 0000, la valeur = 4 et ainsi de suite.

Donc HSDIV = (Reg7 >> 5) + 4 ;

N1 :

Le Registre 7 et le 8 contiennent les 2 morceaux de N1.

on extrait le 1er morceau de Reg7 :  N1_reg7 = reg7 & 0x1F
Exemple en binaire : reg7 = 10101001 & 00011111 = 00001001

Reg8.bit6 et Reg8.bit7  sont le poids faible de N1. donc je décale Reg8 de 6 bits vers la droite,  et je décale le reg7 de 2 bit vers la gauche puis je concatène les 2 :

N1 = ((reg7 & 0x1F) << 2 OR (Reg8 >> 6) + 1 )

En binaire :

Reg7 = 10101001
Reg8 = 11000010
Reg7 & 0x1F = 00001001
Reg7 << 2 = 00100100
Reg8 = 11000010
Reg8 >> 6 = 00000011

Je fais un OU logique entre Reg7 et Reg8 :

00100100
00000011
————
00100111 = N1 = 0x27 = 39.

je lui rajoute + 1 comme la datasheet l’indique cela fait dans notre cas une division par 40.

Datasheet P19 :

”N1 = […] For example, to divide by 10, write 0001001 (9 decimal) to the N1 registers.”

RFREQ :

Le calcul de RFREQ et du même genre, entre les registres 8,9,10,11 et 12.
Attention toutefois, on est sur 48 bit, donc sur du calcul 64bit… de type unsigned long long ou uint64_t.

RFRE = R08& 0x3F<<32 :si R8= 0xFF = 00111111000000000000000000000000000000
RFRE = RFRE or R09<<24: R9 = 0x0F = 00111111000011110000000000000000000000
RFRE = RFRE or R10<<16: R10=0x22 = 00111111000011110010010000000000000000
RFRE = RFRE or R11<<8: R11= 0xFF =  00111111000011110010011111111100000000
RFRE = RFRE or R12: R12 = 0x01 =      00111111000011110010011111111100000001

Et voila ! du coup   RFREQ = 0x3F0F22FF01
Pour trouver la fréquence en Mhz = RFREQ / 2^28 = 0x3F0F22FF01 / 268435456 = 1008.9460 Mhz

(cette valeur ne veut rien dire, j’ai pris des valeurs de registres farfelue, juste pour les voir correctement en binaire.).

FXTAL

Maintenant que nous savons lire HSDIV, N1 et RFREQ on peut connaitre FXTAL.
En effet, on sait que au démarrage, la fréquence de sortie (FOUT) est de 56.320 Mhz.

Donc FXTAL =  ( 56.320 * HS_DIV_INIT * N1_DIV_INIT ) / RFREQ_MHZ;

On doit avoir une valeur proche de 114 Mhz pour ma version de SI570.
(114,271304842871 Mhz dans mon cas).

4) Changement de fréquence

Pour changer de fréquence, la P14 de notre livre de chevet favoris nous explique qu’il y a 2 modes, le small Change, et le larges changes.

La différence des 2 et simple, si on ne doit pas modifier RFREQ, et que l’on peut agir que sur N1 et HSDIV, on peut faire une variation de fréquence facilement, sans interruption du service. je vois bien un ajustement “fin” de la fréquence comme sur nos postes.
Maintenant, si on doit changer RFREQ, on doit “geler” le VCO un instant, pour faire le paramétrage de RFREQ, puis le dégeler.

Je n’ai travaillé que sur le large_change. c’est le principe que je vais évoquer maintenant dans mon code.

Donc en résumé, pour changer de fréquence (larges_mode):

    La méthode officiel consiste à lire les registres pour déterminer la fréquence actuelle grâce a FXTAL. puis a calculer la valeur du saut… c’est chiant et cela complique le code. le plus simple est de toujours calculer la nouvelle valeur à partir de la fréquence d’initialisation, et en plus on gagne le temps d’une lecture de registre, puisque celle ci devient inutile.

Résumez des actions :

1) connaitre le FXTAL et Fréquence d’initialisation (voir méthode précédente.

2) calcul des nouveau diviseurs, HSDIV et N1. (je n’ai pas encore fait cette partie)

3) connaissant FXTAL, FOUT_ORIGINE, HSDIV, N1 on calcul RFREQ_NEW :

RFREQ_NEW_MHZ = (FOUT_NEW * HS_DIV_NEW * N1_DIV_NEW)/ FXTAL;
RFREQ_NEW = RFREQ_NEW_MHZ * 268435456;

Je transforme en registre (R7 à R12) ; c’est l’opération quasi inverse de la précédente :

R7 = ((HS_DIV_NEW-4) << 5) & (N1_DIV_NEW >> 3);
R8 = N1_DIV_NEW << 6;
R8 = (RFREQ_NEW & 0xFF00000000) >> 32;
R9 =  (RFREQ_NEW & 0x00FF000000) >> 24;
R10 =  (RFREQ_NEW & 0x0000FF0000) >> 16;
R11 =  (RFREQ_NEW & 0x000000FF00) >> 8;
R12 =  (RFREQ_NEW & 0x00000000FF);

et avant d’appliquer ces modifications je “freeze” le VCO par le registre 135 et je libère ensuite par le registre 137.

Conclusion

Et voila. pour la mise en pratique je vous laisse lire mon fichier source, je pense avoir démystifié une bonne partie du fonctionnement.
Actuellement, mon programme ne fonctionne pas comme il devrait, je rencontre plusieurs difficulté. La première et le non fonctionnement du uint64_t . je pense que c’est un bug du compilateur que j’utilise (Energia E09). L’autre problème provient d’un manque de précision sur les division par 2^28.
Du coup, je n’ai pas le matériel nécessaire pour faire le calcul de N1 et HSDIV pour le changement de fréquence. bien sur, si j’ai des corrections je vous tiens au courant.
Pourquoi c’et article si rien ne marche ? bien, en fait, tout marche presque :

  1.  lecture écriture des registres en I2C
  2.  la logique des modes de calcul est bon.
  3.  cela m’a permis de calculer mon fxtal manuellement.
  4.  cela m’a permis de faire des routines avec des valeurs de fréquences pré-enregistré.

J’ai utilisé ce programme incomplet pour la mise au point de filtre sur 14Mhz. je le terminerai un jour, mais pour l’instant, j’ai besoins de temps sur les FPGA.
J’ai suffisamment avancé pour que d’autre qui en on besoin puisse l’utiliser.

Donc, oui cela ne marche pas comme cela  devrait, mais cela marche assez pour moi pour l’instant. donc si vous en avez besoin, ce peut être un bon départ !

à bientôt,

72,
Jean-Yves
F4DTR

téléchargement du code : CLIQUEZ ICI.

3 thoughts on “Pilotage d’un SI570 par Arduino ou Energia.

  1. Bonjour, j’aimerai connaître si possible les modifications à faire pour Energia car je ne les ai pas trouvées sur le site mentionné. Merci par avance.

  2. Bonjour,
    désolé pour cette réponse tardive, mais les vacances… 😉
    d’ailleurs, meilleur vœux !

    pour les modifs, pas d’inquiétude si vous utilisez la nouvelle version d’Energia (ver 0101E0011).
    les modifications/corrections apportées au fil de l’eau sont systématiquement incluse dans la nouvelle version.
    j’avoue que je n’ai pas re-testé avec cette version, mais j’ai confiance !

    je vous laisse le lien aussi du post en rapport sur http://forum.43oh.com/topic/4380-change-frequency-to-si570-dxo-on-i2c-not-fully-fonctionnal/
    certain problèmes/Bug soulevés dans mon article pourrais être corrigé. pas eut le temps de tester.

    les problèmes en questions sont surtout le uint64 qui ne fonctionne pas certainement a cause d’un mauvais cast.
    et aussi un petit bug au niveau du freeze du VCO. le fonctionnement est correcte mais pas conforme au datasheet. :honte:

    tenez moi au courant de vos expérimentations !
    espérant vous avoir aidé,

    Amicalement,
    Jean-Yves
    F4DTR

  3. Bonsoir,

    merci pour votre réponse. En fait j’étais à la recherche d’infos pour faire fonctionner une nunchuk sur le bus I2C. Le problème que j’avais, c’est que le programme scanner ne fonctionnait pas. J’ai utilisé un oscillo et j’ai remarqué qu’il ne suffit pas d’envoyer une adresse pour déterminer si un composant I2C est présent. Merci.

Comments are closed.