Context
I am working on a Free Space Optical Communication (FSOC) project. Compute nodes will connect through ethernet to a media converter which will have a custom Small Form-factor Pluggable (SFP). This bidirectional SFP will send 1550nm wavelength data through free space to a receiving custom SFP. The receiving SFP will interface with a media converter that is connected by ethernet to another compute node. The compute nodes should be able to communicate as if they were connected by ethernet. End target is communication at 1km at 1gb/s with total cost of bidirectional communication node under $1000 and under 1 kg. Constraints may turn out to be impossible and need tuning. Goal is to put these on drones to make a mesh network.

Week 3 Goals
- Prove ability to read from the I2C SFP breakout board. Need to actually start touching hardware even if trivial.
Work out I2C muscle as it will be needed for prototyping.
Materials

Adafruit FT232H Breakout – General Purpose USB to GPIO, SPI, I2C
Osmocom SFPexperimenter board v2 kit
10Gtek 1.25G SFP 1000Base-SX Multimode LC Fiber Transceiver
TRENDnet SFP to RJ45 100Base-FX Single-Mode LC Module
EDGELEC 120pcs 10cm Breadboard Jumper Wires Assorted Kit,
And soldering materials that turned out to be unnecssary.
Results
Using the femail to mail connectors connected the ground, SDA and SDC pins to the GRND, D0 and D1 connections on the adafruit.
Turns out that the adafruit does not light up when plugged in. Did a lot of troubleshooting on power issues until I realized it can communicate with the LEDs not turning on.

I created a python script to communicate with the adafruit and asked Gemini to set it up and communicate with known address locations from the SFP MSA.
(venv) adam@adam-MS-7B94:~/dev/i2c$ python read_sfp.py
Error configuring FT232H: The device has no langid (permission issue, no string descriptors supported or device error)
Good start. The computer saw the FT232H board, but Linux is protecting it (security) so the script wasn’t allowed to talk to it yet.
Running lsusb to see connectios when the adafruit is disconnected:
(venv) adam@adam-MS-7B94:~/dev/i2c$ lsusb
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 032: ID 04f2:4141 Chicony Electronics Co., Ltd HP 320M USB Optical Mouse
Bus 001 Device 028: ID 1462:7b94 Micro Star International MYSTIC LIGHT
Bus 001 Device 004: ID 13d3:3610 IMC Networks
Bus 001 Device 034: ID 03f0:2a4a HP, Inc
Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Then with the device connected:
(venv) adam@adam-MS-7B94:~/dev/i2c$ lsusb
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 008: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 032: ID 04f2:4141 Chicony Electronics Co., Ltd HP 320M USB Optical Mouse
Bus 001 Device 028: ID 1462:7b94 Micro Star International MYSTIC LIGHT
Bus 001 Device 004: ID 13d3:3610 IMC Networks
Bus 001 Device 034: ID 03f0:2a4a HP, Inc
Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
You can see the new one: Bus 005 Device 008: ID 0403:6014 Future Technology Devices International, Ltd FT232H Single HS USB-UART/FIFO IC
So I need to add to rules that we can communicate with the vendor “0403” and the product “6014” which is
0403is the code for FTDI (Future Technology Devices International). They are the company that manufactures the black chip on the Adafruit board6014is the code specifically for the FT232H model of that chip
(venv) adam@adam-MS-7B94:~/dev/i2c$ echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6014", MODE="0666"' | sudo tee /etc/udev/rules.d/11-ftdi.rules
[sudo] password for adam:
SUBSYSTEM=="usb", ATTR{idVendor}=="0403", ATTR{idProduct}=="6014", MODE="0666"
(venv) adam@adam-MS-7B94:~/dev/i2c$ sudo udevadm control --reload-rules
rigger(venv) adam@adam-MS-7B94:~/dev/i2c$ sudo udevadm trigger
Now that we reviewed the rules we reload:
(venv) adam@adam-MS-7B94:~/dev/i2c$ sudo udevadm control --reload-rules
rigger(venv) adam@adam-MS-7B94:~/dev/i2c$ sudo udevadm trigger
And when running the same script:
(venv) adam@adam-MS-7B94:~/dev/i2c$ python read_sfp.py
Reading from SFP at address 0x50...
Error communicating with SFP at address 0x50: NACK from slave
Reading from SFP at address 0x51...
Error communicating with SFP at address 0x51: NACK from slave
There was no SFP plugged in! So this output makes sense. We send a command to adafruit, which uses the processor to change it into signals on D0 and D1 and communicates with the breakout board, but if there is no address to talk to, you cannot pull from those addresses.
So now after plugging in the TRENDnet SFP to RJ45 100Base-FX Single-Mode LC Module:
(venv) adam@adam-MS-7B94:~/dev/i2c$ python read_sfp.py
Reading from SFP at address 0x50...
SFP A0 Raw Data:
bytearray(b'\x03\x04\x07\x00\x10\x02\x10\x00\x00\x00\x00\x00\x02\x00\x14\xc8\x00\x00\x00\x00TRENDnet \x00\x00\x00\x00TE100-MGBS20 V2.0\x05\x1e\x00=\x00\x1a\x00\x00RA4K202050021 241210 \x00\x00\x03\xb5\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
============================================================
SFP MODULE INFORMATION (A0h)
============================================================
Identifier: SFP/SFP+/SFP28
Connector: LC
Transceiver Compliance:
Encoding: Unknown (0x00)
Nominal Bit Rate: 200 Mbps
Link Lengths:
SMF: 20 km
Vendor: TRENDnet
Vendor OUI: 00:00:00
Part Number: TE100-MGBS20
Revision: V2.0
Wavelength: 1310 nm
Serial Number: RA4K202050021
Date Code: 2024-12-10
Reading from SFP at address 0x51...
SFP A2 Raw Data:
bytearray(b'\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff')
============================================================
SFP DIAGNOSTICS (A2h)
============================================================
Diagnostic Monitoring: Not supported or not available
It works!
Then I switched to 10Gtek 1.25G SFP 1000Base-SX Multimode LC Fiber Transceiver:
(venv) adam@adam-MS-7B94:~/dev/i2c$ python read_sfp.py
Reading from SFP at address 0x50...
SFP A0 Raw Data:
bytearray(b'\x03\x04\x07\x00\x00\x00\x01\x00\x00\x00\x00\x01\r\x00\x00\x007\x1b\x00\x00OEM \x00\x00\x90eGLC-SX-MMD \x90e \x03R\x00\xe8\x00\x12\x00\x00CSYGE3O18795 240105 h\x00\x03t\x00\x00\x11Y\xf1\x97\xa0\xf14\x01\xde\xa3\x9b\xda5,Q]\xdd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0ed\xa3\x8a')
============================================================
SFP MODULE INFORMATION (A0h)
============================================================
Identifier: SFP/SFP+/SFP28
Connector: LC
Transceiver Compliance:
- 1000BASE-SX
Encoding: 8B/10B
Nominal Bit Rate: 1300 Mbps
Link Lengths:
50um MMF: 550 m
62.5um MMF: 270 m
Vendor: OEM
Vendor OUI: 00:90:65
Part Number: GLC-SX-MMD
Revision: e
Wavelength: 850 nm
Serial Number: CSYGE3O18795
Date Code: 2024-01-05
Reading from SFP at address 0x51...
SFP A2 Raw Data:
bytearray(b'WOTRB9VBAA10-2626-01V01 \x89\xfbU\x00\x00\x00\x00}\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00b\xa4d\x00i\x9cu\x1b\x81\xf1\x0f\xe6\x0b\xf0\r\x0c\x0f\x89\x00\x00\xaa\xb6GLC-SX-MMD \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf9\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xff\x00\x00\x00\x00')
============================================================
SFP DIAGNOSTICS (A2h)
============================================================
Diagnostic Monitoring Data:
Additional Info: WOTRB9VBAA10-2626-01V01 U}
Mission accomplished! Interesting the part number seems to output Part Number: “GLC-SX-MMD” which from the amazon product description is from: Compatible with Cisco GLC-SX-MMD. Odd that it described what it is compatible with as part of the I2C.
This is a trivial exercise but now have a better intuition of how the systems work.
Next Week
The goal of the project is to send data over free space using the SFP ecosystem. Need to stop goofing around and actually start making process to that goal rather than “preparing”. Goal is to come up with the bill of materials to send and receive data over free space for the lowest component costs.
Want to send signal possibly through Tx pins on one breakout board and receive on Rx pins on the other. Not sure how to do that or if that is the right next step but something to start sending data. This way step after is to put a beam expander in the middle and hopefully we can have our first free space transmission.
Goal: Manually trigger sending data through SFP components and recovering that exact data.

Leave a Reply