Modules SFP – EEPROM et DDM

 

pisfp_cvr_v1Modules SFP pour fibre optique : Communication avec l’EEPROM et lecture des paramètres de diagnostique (DDM – Digital Diagnostic Monitoring).

Montage et applications autour de la Raspberry Pi et de l’Arduino.

Les modules SFP correspondent à un standard de communication par fibre optique (Wikipedia/SFP).

Ils simplifient grandement l’utilisation de fibres optiques car ils sont standardisé. Il est possible de sélectionner un module SFP selon sa connectique avec la fibre optique, sa longueur d’onde, sa puissance, son débit, ses performances, sa robustesse, etc…

De plus, ils s’occupent de toutes la gestion analogique de l’électronique pour le laser et la photodiode, filtrage et remise en forme des signaux et présentent directement des signaux numériques sur paires différentielles pour le circuit qui les accueille.

sfp-modules-20km-203-213-f
Exemple de module SFP pour fibres optiques (Société Exoligent)
[Eoin] a utilisé une Raspberry Pi et un Arduino pour communiquer avec des modules SFP via leur interface de communication I2C normalisée et je voulais vous partager ses conclusions.

Connecteurs des modules SFP :

sfp_20_pinsToutes les pins VeeT ou VeeR sont à la masse.
Les Pin 15 et Pin 16 nécessitent du +3.3V.
Pin 4: MOD-Def(2) – ligne de données SDA de l’interface i2c.
Pin 5: MOD-Def(1) – ligne d’horloge SCL de l’interface i2c.
Pin 6: MOD-Def(0) correspond à un signal de présence du module dans le système (les modules SFP sont hot-pluggable). Ce signal est connecté à la masse en interne dans le module et doit être scruté par le circuit de gestion du module SFP§. Une résistance de pull-up est nécessaire.

 Accès de l’EEPROM avec la Raspberry Pi

Selon les spécifications INF-8074, les modules SFP contiennent une EEPROM permettant de stocker diverses informations sur leurs caractéristiques techniques et peuvent présenter des paramètres de diagnostique si cette fonctionnalité est implémentée dans le module (SFF-8472). On accède donc à deux adresses de périphériques esclaves sur le bus I²C : l’adresse 0xA0, correspondant à l’EEPROM, qui contient les caractéristiques du module et du vendeur, et l’adresse 0xA2 qui permet d’accéder aux paramètres de diagnostiques.

[Eoin] a utilisé l’interface I2C d’une Raspberry Pi pour lire et écrire dans les paramètres de l’EEPROM des modules SFP. Il est ainsi en mesure de voir les caractéristiques du module ou de le personnaliser afin de le faire passer pour un autre module, par exemple pour rendre un module no name compatible avec un routeur Cisco. À condition que l’EEPROM ne soit pas verrouillée en écriture comme je l’ai déjà vu sur certains modules SFP.

Lecture/écriture de l’EEPROM avec une Raspberry Pi

Il faut d’abord raccorder les lignes I2C du module SFP à la Raspberry Pi. Pour simplifier, [Eoin] a utilisé un circuit Cisco TwinGig acheté sur ebay. Il s’agit d’une carte fille permettant de raccorder 2 modules SFPs sur un appareil Cisco de type routeur. Ne reste plus qu’à repiquer les lignes I2C sur les résistances R57 (SDA) and R54(SCL), et à alimenter la carte en 3,3V.

cvr-x2-pin

Sur la Raspberry Pi, il a connecté les 4 fils suivants sur le port GPIO :

  • GPIO Pin 1: 3.3V
  • GPIO Pin 6: 0V
  • GPIO Pin 3: SDA
  • GPIO Pin 5: SCL

Ci-dessous, l’ensemble raccordé :

pisfp_cvr_v1

Tester le fonctionnement

Il faut maintenant configurer la Raspberry Pi pour être en mesure de dialoguer avec le module SFP via le port I²C.

1) Installer i2c-tools :

sudo apt-get install i2c-tools

2) Assurez-vous que le module soit bien installé et pas blacklisté :

pi@raspberrypi ~ $ cat /etc/modprobe.d/raspi-blacklist.conf

Si c’est le cas, supprimer le ‘#’ devant “blacklist i2c-bcm2708”

# blacklist spi and i2c by default (many users don't need them)
blacklist spi-bcm2708
#blacklist i2c-bcm2708

3) Testez la connexion. Vous devez voir l’adresse du SFP (0x50) sur le bus I²C. Si vous ne voyez pas cette adresse, il doit y avoir un problème dans le câblage. Pourquoi l’adresse 0x50 sachant qu’on a parlé de 0xA0 juste avant ? Et bien parce-que ça dépends de si on tient compte ou pas du bit0 (RW) spécifiant un accès en lecture ou écriture. Si on décale les bits de 0xA0 d’un cran vers la droite, onn obtient bien 0x50. Normalement l’adresse devrait être sur 7 bits et donc bien 0x50, mais personnellement, je suis plus partisan de lire l’octet normalement avec le bit RW et donc dire 0xA0. Ça respecte la position des différents bits…

pi@raspberrypi ~ $ i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: 50 -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --
pi@raspberrypi ~ $

Si vous voyez l’adresse 0x51 (0xA2 décalé vers la droite comme précédemment), cela signifie que votre module SFP supporte aussi le diagnostique digitale (DOM-Digital Optical Monitoring).

4) Lecture de l’EEPROM à l’adresse 0x50 en utilisant I2Cdump.

pi@raspberrypi ~ $ i2cdump -y 1 0x50
No size specified (using byte-data access)
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
00: 03 04 07 00 00 00 01 00 00 00 00 01 0d 00 00 00 ???...?....??...
10: 37 1b 00 00 52 61 73 70 62 65 72 72 79 20 50 69 7?..Raspberry Pi
20: 20 20 20 20 00 00 30 d3 51 46 42 52 2d 35 37 36 ..0?QFBR-576
30: 36 4c 50 20 20 20 20 20 20 20 20 20 03 52 00 c6 6LP ?R.?
40: 00 1a 00 00 31 32 33 34 35 36 37 38 39 4a 4b 20 .?..123456789JK
50: 20 20 20 20 30 35 30 33 31 30 20 20 00 00 00 95 050310 ...?
60: 00 00 02 ab 89 12 ea 3e 00 04 1c 5f 6a 0a de 10 ..?????>.??_j???
70: 74 11 3b 00 00 00 00 00 00 00 00 00 ef 19 f8 08 t?;.........????
80: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
90: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
a0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
b0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
c0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
d0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
e0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
f0: ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ................
pi@raspberrypi ~ $

Pour comprendre le détail de l’EEPROM, il faut se référer aux dernières spécifications SFP MSA.To understand the details of the EEPROM refer to the latest SFP MSA.

Note : les adresses dans la documentation SFP MSA sont en décimal alors que les adresses ci-dessus sont en hexadécimal.
5) Comment lire/écrire dans l’EEPROM de  votr emodule SFP ou SFP+

[Eoin] a trouvé que le plus simple était d’utiliser la librairie WiringPi de Gordon Henderson. Voir http://wiringpi.com/ pour les détails.

Pour lire tous les octets de l’EEPROM et les stocker dans un tableau appelé A50 :

int xio;
int fd1;
unsigned char A50[128];
printf ("Read SFP EEPROM\n");

xio = wiringPiI2CSetup (0x50);
if (xio < 0){
fprintf (stderr, "xio: Unable to initialise I2C: %s\n", strerror (errno));
return 1;
}
/*Read in the first 128 bytes 0 to 127*/
for(i=0; i <128; i++){
fd1 = wiringPiI2CReadReg8 (xio,i);
A50[i] = fd1;
}

//print vendor id bytes 20 to 35
memcpy(&vendor, &A50[20],16);
vendor[16] = '\0';
printf("\nVendor = %s",vendor);

Vous pouvez écrire un octet ou un tableau contenant les valeurs souhaitées en utilisant la fonction wiringPiI2CWriteReg8 :

unsigned char mybytes[] = {0xff};
wiringPiI2CWriteReg8(xio, counter, mybytes[0]);

Pour vérifier si le Cheksum correspond à celui écrit sur l’EEPROM :

sum = 0;
for (counter = 0; counter <0x3f; counter++)
sum = (A50[counter] + sum);
sum = sum & 0xff;
cc_base = A50[0x3f]; //sum stored in address 63.
printf("value of cc_base = %x and sum= %x\n",cc_base,sum);
printf ("\n");

Pour lire la valeur de la longueur d’onde du transceiver :

int wave; //3 bytes. 60 high order, 61 low order. 62 is the mantissa
wave = ((int) A50[60]<<8) | ((int) A50[61]);
printf("\nWavelength = %d.%d",wave,A50[62]);

Le dump de l’EEPROM du module SFP ci-dessous à le VendorID “Raspberry Pi”. Il est aisé de lire et afficher des valeurs. Par exemple :

Transceiver is 1000Base SX
 Wavelength = 850.0
 Vendor = Raspberry Pi
 Serial = 123456789JK
 cc_base = c6 and cc_ext = 95

Pour rendre un moduel SFP compatible avec les systèmes Cisco, il faut rendre les deux Cheksums valides (cc_base et cc_ext), il faut également calculer des octets particuliers aux adresses 0x60 à 0x7F du champs Vendor Specific.
Vous pouvez trouver les détails ici : http://forum.nag.ru/

Le code développé par [Eoin]est disponible ici : https://github.com/sonicepk/sfppi

Accès aux informations de diagnostique

Maintenant que nous avons vu comment communiquer avec le module SFP, nous allons maintenant voir comment lire les données de diagnostique, à savoir la tension d’alimentation, de polarisation du laser, la température et les puissances optiques en émission et en réception.

[Eoin] a utilisé un Arduino pour lire les données de diagnostique du module SFP qui sont ensuite affichées sur un écran LCD, réalisant ainsi un puissance-mètre optique “low-cost”, simple à réaliser.

Le système se compose du module SPF, d’un Arduino UNO et d’un écran LCD alphanumérique 16×2 caractères. Le module SFP est alimenté en 3V par l’arduino alors que le module LCD est alimenté directement en 5V par l’adaptateur secteur. La librairie “Liquidcrystal” d’Arduino contrôle l’affichage. Voir ici pour le câblage de l’afficheur : http://arduino.cc/en/Tutorial/LiquidCrystal
Pour la communication I2C avec le module SFP, la librairie “Wire” est utilisée : http://arduino.cc/en/reference/wire
Le module SFP est un modèle low-cost sans marque en 1310 nm. Il est branché dans un connecteur SFP Samtec monté sur une plaque à trous de prototypage pour faciliter le montage.
Le code d’exemple ci-dessous affiche la température et la puissance optique reçue. Il peut être intéressant de faire un puissance-mètre optique compact alimenté sur batterie avec un afficheur où tout ce que vous avez à faire est d’introduire le module SFP de votre choix tant qu’il intègre la fonction de diagnostique (DDM ou DOM).
La spécification SFF-8472 stipule que la précision de la mesure de la puissance optique reçue soit meilleure que +/-3dB. [Eoin] a réalisé quelques tests avec des sources lasers pour les longueurs d’ondes de 1310nm et 1550nm, et différents atténuateurs, et a comparé les résultats avec ceux d’un véritable puissance-mètre optique calibré. Il a été plutôt surpris de découvrir que les mesures faites avec ses modules SFP étaient typiquement à 0,2dB seulement d’écart !
Code d’exemple de l’Arduino :
#include <Wire.h>
#include <math.h>
#include <LiquidCrystal.h>
// LCD interface pins
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
const byte EEPROM_ID = 0x51;
int A51[128];

void setup()
{
 Wire.begin();
 Serial.begin(9600);
 // set up the LCD's number of columns and rows:
 lcd.begin(16, 2);
}

byte I2CEEPROM_Read (unsigned int address)
{
 byte data;
 Wire.beginTransmission(EEPROM_ID);
 Wire.write(address);
 Wire.endTransmission();
 Wire.requestFrom(EEPROM_ID,(byte)1);
 while(Wire.available() == 0); data = Wire.read();
 return data;
}

void loop()
{
 for (int i = 96; i <106; i++)
 {
 A51[i] = I2CEEPROM_Read(i);
 }
 float temp = A51[96] + (float) A51[97]/256;
 float optical_rx = 10 * log10((float)(A51[104]<<8 | A51[105]) * 0.0001);
 lcd.setCursor(0, 0);
 lcd.print ("Temp = ");
 lcd.print (temp);
 lcd.print ((char)223); //degree symbol
 lcd.print ("C");</div> <div>  lcd.setCursor (0, 1);
 lcd.print ("RX = ");</div> <div>  lcd.print (optical_rx);
 lcd.print (" dBm");

 delay(1000);
}

Code également disponible sur https://github.com/sonicepk/sfpduino

From SFF-8472
Measured TX output power in mW. Represented as a 16 bit unsigned integer with the power defined as the full 16 bit value (0-65535) with LSB equal to 0.1 uW, yielding a total range of 0 to 6.5535 mW (~ -40 to +8.2 dBm).
Internally measured transceiver temperature. Represented as a 16 bit signed twos complement value in increments of 1/256 degrees Celsius, yielding a total range of -128C to +128C.

 

Sources :

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *