Reference OIF tunable laser MSA
Overview
The module uses a 2-wire (+GND) serial connection based on a handshake model. The host initiates the communication with a 32-bit (4 bytes) command over the Rx line and receives 4 bytes back from the module over the Tx line.
Each interaction needs to complete these 8 byte sequence before starting a new interaction. If, for some reason, the sequence is not completed a communication reset is required.
Each 32 bit command contains management information in the first byte. Register information in the second byte and data in the third and fourth byte.
The serial communication configuration is 8 bit, no parity, 1 stop bit (high), 1 start bit (low), no echo, no flow control. The lowest significant bit is transmitted first (within each byte).
On this page
The packet of 32 bits to be sent to the module is configured as below.
The more detailed breakdown is in the below image
The first byte contains the checksum (first 4 bits) and a toggle between read and write operation. The second byte contains the register address and the third and fourth byte contains the data to be written (if appropriate toggle is set) to the register.
The packet of 32 bits to be received from the module is configured as below:
The more detailed breakdown is in the below image
The first byte contains the checksum (first 4 bits) and status information. The second byte contains the register address and the third and fourth byte contains the data read.
In case of a loss of synchronised communication, the host can send a sequence of individual 0 bytes (0x00). When the module responds with a 4 byte sequence, synchronisation is realized. If more than 4 bytes are sent, without a response, then a fatal error has occurred (possibly due to communicating at the wrong baud rate) and a device reset is needed.
The BIP-4 checksum is computed by xor’ing all the bytes in the packet together and then xor’ing the left nibble of the result with the right nibble of the result.
The checksum provides a basic level of consistency check for the communications transfer.
BIP8= (byte0 & 0x0f) ^ byte2 ^ byte3 ^ byte4
BIP4= ((BIP8 & 0xf0) >> 4) ^ (BIP8 & 0x0f)
For each command the module provides 2 bytes of return value. To output more information, such as multiple values or strings, the AEA mechanism is used.
The register provides the number of bytes that should be downloaded and then the host can collect that number of bytes in increments of 2.
See the sample code at the bottom of the page for more details.
The host and module need to operate at the same baudrate to be able to communicate. The module is typically set to a baudrate of 9600, but it can be increased to 115200 baudrate. Also, this baudrate can be saved so that the module is in a different baudrate upon start-up.
Read only
Provides error information and pending bits.
MRDY is always set to 1.
Read only / AEA register
Provides device type
Read only / AEA register
Provide manufacturer information
Read only / AEA register
Provides model information
Read only / AEA register
Provides serial number.
Read only / AEA register
Provides manufacturing date in DD-MMM-YYYY format.
Read only / AEA register
Provides release string, with information groups separated by semi-colon. E.g. PV:2.0.0:FW 1.0.1:HW 3.2.1:AS A1;TS 030.033.0 with PV stands for protocol version, FW stands for firmware ID, HW stands for hardware version; AS stands for application space; TS stands for timestamp. The timestamp variable is most relevant for determining the firmware version.
Read only / AEA register
Provides release backwards compatibility string, with information groups separated by semi-colon, similar to the register 0x06. Note that this is not maintained by Pure Photonics.
Write only
Saves the non-volatile parameters to permanent memory. Only allowed when the laser is not operating.
Read only
Provides configuration for AEA reading
Read only
Provides location where AEA data can be downloaded
Read only
Provides next 2 bytes for AEA read
Read / write
Provides the current and maximum baudrate for the module. Allows setting of the baudrate. After changing the baudrate of the module the module return packet is at the old baudrate. After that the baudrate of the host communication interface also needs to change accordingly.
For the baudrate field:
0: 9600 baud
1: 19200 baud
2: 38400 baud
3: 57600 baud
4: 115200 baud
The RMS bit controls the response to a change in the MS line. If set to 0 the baudrate will reset as well as clearing of the communication buffers. If set to 1 only the communication buffers are cleared.
Read/write
Provides ability to upload a new firmware version. Details to be found in the MSA.
Read only
Provides ability to upload a new firmware version. Details to be found in the MSA.
Write only
Provides ability to upload a new firmware version. Details to be found in the MSA.
Read only
Resends the last response packet
Read / write
Provides ability to upload a new firmware version. Details to be found in the MSA.
Read only
Provides status of firmware download. Details to be found in the MSA.
Read / write
Provides status of fatal flags and allows for clearing of latching flags.
Further detail
Read / write
Provides status of warning flags and allows for clearing of latching flags.
Detailed description
Read / write
Provides the power error in 0.01dB where the Fatal alarm is raised. Allows writing of the power error criterion in 0.01dB units.
Read / write
Provides the power error in 0.01dB where the Warning alarm is raised. Allows writing of the power error criterion in 0.01dB units.
Read / write
Provides the frequency error in 0.1GHz where the Fatal alarm is raised. Allows writing of the frequency error criterion in 0.1GHz
Read / write
Provides the frequency error in MHz where the Fatal alarm is raised. Allows writing of the frequency error criterion in 1MHz
Read / write
Provides the frequency error in 0.1GHz where the Warning alarm is raised. Allows writing of the frequency error criterion in 0.1GHz
Read / write
Provides the frequency error in MHz where the Warning alarm is raised. Allows writing of the frequency error criterion in 1MHz
Read / write
Provides the temperature error in 0.01C where the Fatal alarm is raised. Allows writing of the temperature error criterion in 0.01C
Read / write
Provides the temperature error in 0.01C where the Warning alarm is raised. Allows writing of the temperature error criterion in 0.01C
Read / write
Provides the elements in the status registers that trigger the SRQ line. Allows writing the triggers.
Read / write
Provides the elements in the status registers that trigger the FATAL flag Allows writing the triggers.
Read / write
Provides the elements in the status registers that trigger the alarm flag. Allows writing the triggers.
Read / write
Provides the channel information and allows to select the channel.
Note that this feature is mostly relevant for a device operating on a preset grid. The Pure Photonics tunable laser is grid agnostic and can be set to any frequency. Therefore we recommend to set the channel to 1 and set the First Channel Frequency fields to the desired frequency.
Read / write
Provides the channel information and allows to select the channel.
Note that this feature is mostly relevant for a device operating on a preset grid. The Pure Photonics tunable laser is grid agnostic and can be set to any frequency. Therefore we recommend to set the channel to 1 and set the First Channel Frequency fields to the desired frequency.
Since MSA1.3 this is the upper nibble of the 32 bit channel number.
Read / write
Provides optical power setting in 0.01dB units. Allows setting of the target power.
Read / write
Provides on/off status of device and allows to turn the device on/off as well as start resets.
SENA is to activate the optical output
MR is module reset
SR is soft reset
Read / write
Provides the behavior of the module and allows to change the behavior of the module.
Read / write
Provides the 0.1GHz portion of the grid spacing and allow to set it.
Read / write
Provides the 1MHz portion of the grid spacing and allow to set it.
Read / write
Provides 1 THz portion of the frequency associated with channel 1. Allows to set it.
Read / write
Provides 0.1GHz portion of the frequency associated with channel 1. Allows to set it.
Read / write
Provides 1MHz portion of the frequency associated with channel 1. Allows to set it.
Read / write
Provides the in-operation frequency offset (Fine Tune Frequency). Allows for setting the frequency offset in units of MHz.
Read / write
Provides the low noise mode in operation and allows for setting the mode. 0 for dither mode; 2 for whispermode; (on PPCL700) 6 for enhanced whispermode.
Read only
Provides operating frequency of the laser (including FTF offsets). THz part.
Read only
Provides operating frequency of the laser (including FTF offsets). 0.1GHz part.
Read only
Provides operating frequency of the laser (including FTF offsets). MHz part.
Read only
Provides laser output power in units of 0.01dBm
Read only
Provices laser temperature in 0.01C (should always be 50C for PPCL600/PPCL700 laser generation)
Read only / AEA register
Provides laser current data in units of 0.1mA. First value is TEC current. Second value is gain current.
Read only / AEA register
Provides laser temperature data in units of 0.01C. First value is laser temperature. Second value is ambient temperature.
Not used by Pure Photonics modules.
Not used by Pure Photonics modules.
Not used by Pure Photonics modules.
Not used by Pure Photonics modules.
Not used by Pure Photonics modules.
Not used by Pure Photonics modules.
Read / write
Provides age threshold for fatal flag in %. Allows setting the criterion.
Read / write
Provides age threshold for warning flag in %. Allows setting the criterion.
Read only
Provides laser aging value
Read only
Provides FTF capabiliy in MHz
Read only
Provides minimum power value in 0.01dBm units
Read only
Provides maximum power value in 0.01dBm units
Read only
Provides lower frequency level. THz part
Read only
Provides lower frequency level. 0.1GHz part
Read only
Provides lower frequency level. MHz part
Read only
Provides upper frequency. THz part
Read only
Provides upper frequency. 0.1GHz part
Read only
Provides upper frequency. MHz part
Read only
Provides minimum grid spacing. 0.1GHz part. Always 0 for Pure Photonics
Read only
Provides minimum grid spacing. MHz part. Always 1 for Pure Photonics
Read / Write
Provides the currently active channel and status of the Clean Jump. Allows to select the target channel and to enable/disable the Clean Jump.
Write 0 to disable Clean Jump. Write 1 to start Clean Jump. If value is higher than 1 the channel is set as value & 0x1f. So to set channel 0 and 1 write channel + 0x20.
Read only
Provides frequency error estimate in units of 0.1GHz
Read / write
Provides calibration status. The MSB (x8000) shows if the calibration is active. Value & 0x7fff shows the channel that currently is being calibrated. To start the calibration write the number of channels to calibrate. The unit will automatically start calibrating at the frequencies FCF + (channel-1) * Grid_spacing.
Read / write
Provides the Clean Sweep range in GHz. Allows writing the target clean sweep range to the module. To find out the device capabilities, incrementally write higher values to this register until an error is returned.
Read / write
Provides on / off status of Clean Sweep. Allows Clean Sweep to be started (1) and stopped (0)
Read only
Provides the Clean Sweep Offset in 0.1 GHz.
Read / write
Provides the speed of the Clean Sweep in MHz / sec. Allows to set the speed of the Clean Sweep in MHz / sec.
Read only
Provides reading of the Clean Measurement input (ADC). 0 – 65535 for 0-2.5V. If data field is 0 CM1 is returned. If datafield is 1 CM2 is returned.
Read / write
Provides the current setting of Analog Output (DAC). 0 – 65535 for 0 – 2.5V. Allows for setting the output
Set FTF range for analog FTF.
Input: Range in MHz. E.g. 500 is for -500 – + 500MHz analog FTF range
Output: Range in MHz
Description: default set to 0. Requires Clean Measurement (Analog input). If set to non-zero value, then the analog input voltage is measured every 5ms. The voltage is converted to an FTF setting. E.g. for PPCL700 the range 0-2.5V is converted to -RANGE – +RANGE MHz. For PPCL300 the range 0-6V is converted to -RANGE – +RANGE MHz.
Internal use only.
Use of debug register may be communicated on an as-needed basis.
The below code can be used as a python module (e.g. import ITLA as it) to start and maintain communication with the ITLA. It contains the checksum calculation, package composition, package sending and error recovery.
#example on how to use ITLA_reference.py
import ITLA_reference as itla
sercon=itla.ITLAConnect('com1',9600)
print('Serial connection %s' %sercon)
print('NOP %d; Flags %d' %(itla.ITLA(sercon,0x00,0,0),itla.ITLA(sercon,0x00,0,0)>>8))
print('Serial %s' %(itla.ITLA(sercon,0x04,0,0)))
print('Power setpoint %d *0.01dBm' %(itla.ITLA(sercon,0x31,0,0)))
itla.ITLA(sercon,0x31,itla.ITLA(sercon,0x31,0,0)-75,1)
print('New power setpoint %d * 0.01dBm' %(itla.ITLA(sercon,0x31,0,0)))
print('Laser temcperature %d * 0.01C' %(itla.ITLASplitDual(itla.ITLA(sercon,0x58,0,0),0)))
print('Ambient temcperature %d * 0.01C' %(itla.ITLASplitDual(itla.ITLA(sercon,0x58,0,0),1)))
sercon.close()
#save as ITLA_reference.py to use with sample code
import serial
import time
import struct
import threading
ITLA_NOERROR=0x00
ITLA_EXERROR=0x01
ITLA_AEERROR=0x02
ITLA_CPERROR=0x03
ITLA_NRERROR=0x04
ITLA_CSERROR=0x05
ITLA_ERROR_SERPORT=0x01
ITLA_ERROR_SERBAUD=0x02
READ=0
WRITE=1
latestregister=0
tempport=0
raybin=0
queue=[]
maxrowticket=0
AEA_reference=[]
_error=ITLA_NOERROR
seriallock=0
def byteconv(number):
#Converts a number to a byte for serial communications
if number>127: number=number-256
if number>127 or number <-128: return(struct.pack('b',0))
return(struct.pack('b',number))
def ITLALastError():
#returns the error status from the last communication
return(_error)
def SerialLock():
#returns status of serial communications
global seriallock
return seriallock
def SerialLockSet():
#locks serial communications until a response is received (for multi-thread applications)
global seriallock
seriallock=1
def SerialLockUnSet():
#releases serial communications until a response is received (for multi-thread applications)
global seriallock,queue
seriallock=0
queue.pop(0)
def checksum(byte0,byte1,byte2,byte3):
#calculates checksum
bip8=(byte0&0x0f)^byte1^byte2^byte3
bip4=((bip8&0xf0)>>4)^(bip8&0x0f)
return bip4
def Send_command(sercon,byte0,byte1,byte2,byte3):
#sends command on serial interface
global CoBrite
sercon.write(byteconv(byte0))
sercon.write(byteconv(byte1))
sercon.write(byteconv(byte2))
#double check that the module has not sent any response after 3 bytes. If it did we are out of sync and we need to fix
if sercon.inWaiting()>0:
sercon.flushInput()
counter=0
while sercon.inWaiting()<4 and counter<8:
sercon.write(byteconv(0)) #send 0 command (NOP)
time.sleep(0.02)
counter=counter+1
if counter<8: #if counter is 8 we have not recovered
sercon.flushInput()
Send_command(sercon,byte0,byte1,byte2,byte3)
return
sercon.write(byteconv(byte3))
def Receive_response(sercon):
#receive response on serial interface
global _error,queue,CoBrite,CoBrite_AEA,commlog
reftime=time.perf_counter()
while sercon.inWaiting()<4:
if time.perf_counter()>reftime+0.25: #timeout
_error=ITLA_NRERROR
return(0xFF,0xFF,0xFF,0xFF) #default response; indicates error
time.sleep(0.001)
try:
byte0=ord(sercon.read(1))
byte1=ord(sercon.read(1))
byte2=ord(sercon.read(1))
byte3=ord(sercon.read(1))
except:
byte0=0xFF
byte1=0xFF
byte2=0xFF
byte3=0xFF
if checksum(byte0,byte1,byte2,byte3)==byte0>>4: #verify checksum
_error=byte0&0x03
return(byte0,byte1,byte2,byte3)
else:
_error=ITLA_CSERROR
return(byte0,byte1,byte2,byte3)
def ITLAConnect(port,baudrate=9600):
#connects to the unit, checks for communication and returns handle to serial interface; alternatively user can make own serial connection
try:
conn = serial.Serial('\\\\.\\'+str(port),baudrate , timeout=1)
except serial.SerialException:
return(ITLA_ERROR_SERPORT)
#try out different baudrates until it works
baudrate2=4800
while baudrate2<=115200:
ITLA(conn,0x00,0,READ) #check if we get a response on NOP command
if ITLALastError()!=ITLA_NOERROR:
#go to next baudrate
if baudrate2==4800:baudrate2=9600
elif baudrate2==9600: baudrate2=19200
elif baudrate2==19200: baudrate2=38400
elif baudrate2==38400:baudrate2=57600
elif baudrate2==57600:baudrate2=115200
elif baudrate2==115200: #not workng
conn.close()
return(ITLA_ERROR_SERBAUD)
conn.close()
conn = serial.Serial('\\\\.\\'+str(port),baudrate2 , timeout=1)
teller3=0
while teller3<5 and conn.inWaiting()<4:
conn.write(chr(0).encode())
time.sleep(0.01)
teller3=teller3+1
conn.read(conn.inWaiting())
else:
return(conn)
conn.close()
return(ITLA_ERROR_SERBAUD)
def ITLA(sercon,register,data,rw):
#main routine to communicate with the unit
global latestregister,commlog,AEA_reference,queue,maxrowticket
lock=threading.Lock()
lock.acquire() #execution halted while other thread is being queue'ed (allows for timeout)
rowticket=maxrowticket+1
starttime=time.perf_counter()
maxrowticket=rowticket
queue.append(rowticket)
lock.release() #queue updated, now release for next thread
while queue[0]!=rowticket: #only start communication if previous communication has finished
if time.perf_counter()-starttime>5: #timeout
teller=0
while teller100): #mostly to capture errors, e.g. where the response is 65535
print('Excessive AEA number encountered')
return(outp)
while bytes>0:
Send_command(sercon,int(checksum(0,0x0B,0,0))*16,0x0B,0,0)
test=Receive_response(sercon)
outp=outp+chr(test[2])
if bytes>1:outp=outp+chr(test[3]) #to catch case of odd number of bytes
bytes=bytes-2
return outp
def ITLASplitDual(input,rank):
#For currenst and temps registers sequences of 16 bit integers are output as AEA; allows to extract the desired element
teller=rank*2
try:
return(ord(input[teller])*256+ord(input[teller+1]))
except:
return(0)