Advertisement
Guest User

FE5680A interface, Fabio Eboli

a guest
May 24th, 2013
275
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 8.57 KB | None | 0 0
  1. # Fabio Eboli 01-2013
  2. # functions useful for connecting to FE5680A
  3. # tested with python 2.6, should work with all versions
  4. # you need python itself and pyserial module.
  5. # (basic) usage:
  6. # Open pytohn into a shell (in the same directory where is this file, that
  7. # will be FE5680A.py) and import these fuctions: >>> from FE5680A import*
  8. # Then configure the port
  9. # p=SetPort(portnumber)  note the in windows 0 is COM1, 1 is COM2 etc
  10. # if there are no errors get the Offset:
  11. # value=GetOffs(p)
  12. # SetOffsRam(p,1000) 1000 is the new momentary offset
  13. # SetOffsRelRam(p,-30) the new momentary offset s 30 units less than last one i.e. 970
  14. # StoreOffsEE(p) stores the actual momentary offset into EEPROM
  15. # SetOffsEE(p,500) 500 is the new offset, and is permanently saved into EEPROM
  16. # ChangeFreqHz(p,1) move the output frequency 1Hz high
  17. # ChangeFreqP(p,-2.5e-10) move the output frequency -2.5x10^-10
  18. # PrintStatus(p) prints all the info knows to date on the screen
  19. # SendCommandChar(p,0x22,'',True) check and print in readable format the result of 0x2D command
  20. # To use SendCommandChar fully you may need to pack bytes in a string as
  21. # third argument, the simplest way is this: "\x01\x02\x03\x04" packs
  22. # the values 0x01 0x02 0x03 0x04 into a string.
  23. # Send Command Char can be used to for undocumented commands, a pair of examples are provided,
  24. # see GetADC and GetDDS
  25.  
  26. import serial
  27. from struct import *
  28. import time
  29. import math
  30.  
  31. lastcommandtime=0
  32. resolution_parts_per_bit=6.80789e-13 # internal resolution  used by ChangeFreq functions
  33. DDSinputFreq=20000000               # frequency input of the DDS, used by GetDDS()
  34.  
  35. # prepares the communication serial port to the FE5680A
  36. # portno is the port number, in win 0 for COM1 etc
  37. # returns the port that will be passed to the other functions
  38. def SetPort(portno):
  39.     global lastcommandtime
  40.     port=serial.Serial(portno)
  41.     print("Connected to "+port.name)
  42.     port.baudrate=9600
  43.     port.timeout=.1
  44.     port.close()
  45.     lastcommandtime=time.time()
  46.     return port
  47.  
  48. # builds and sends a command to the FE5680A
  49. # port : serial port returned by SetPort()
  50. # ID : command code number
  51. # Data : command data, string
  52. # ReadBack : True if an answer from the FE5680A is expected
  53. # Returns : [rtncode,rtndata,error]
  54. # rtncode: -1 error in answer
  55. #          0 no answer expected
  56. #          1 correct answer received
  57. # rtndata: payload data returned from FE5680A, binary string
  58. # error: error description
  59. def SendCommand(port,ID,Data,ReadBack):
  60.     global lastcommandtime
  61.     IDstring=pack('B',ID)
  62.     datalen=len(Data)
  63.     if datalen>128:
  64.         return -1
  65.     if len(Data)>0:
  66.         totlen=datalen+5 # total message lenght ID+Lenght(2)+Checksum1+Data Lenght+Checksum2
  67.     else:
  68.         totlen=datalen+4
  69.     totlenstr=pack('<H',totlen)
  70.     cs1str=pack('B', (ID ^ (unpack('B',totlenstr[0])[0]) ^ (unpack('B',totlenstr[1])[0])))
  71.     cs2=0
  72.     for chars in Data:
  73.         cs2 ^= unpack('B',chars)[0]
  74.     cs2str=pack('B',cs2)
  75.  
  76.     timefromlastcommand=(time.time())-lastcommandtime
  77.     while timefromlastcommand<2: #wait at least 2s between communications to FE5680A
  78.         timefromlastcommand=(time.time())-lastcommandtime    
  79.     port.open()
  80.     port.write(IDstring+totlenstr+cs1str+Data+cs2str)
  81. #    print(IDstring+totlenstr+cs1str+Data+cs2str)
  82.     ret=[0,'','']
  83.     if ReadBack==True:
  84.         answer=port.readall()
  85. #        answer=input("Answer? ")
  86.         if answer != '' : #answer not empty
  87.             ansID=unpack('B',answer[0])[0]
  88.             anslen=unpack('<H',answer[1:3])[0]
  89.             anscs1=unpack('B',answer[3])[0]
  90.             calccs2=0
  91.             #check command code
  92.             if ansID == ID:
  93.                 #check total lenght
  94.                 if len(answer) == anslen:
  95.                     #check command checksum
  96.                     calccs1=(unpack('B',answer[0])[0]) ^ (unpack('B',answer[1])[0]) ^ (unpack('B',answer[2])[0])
  97.                     if anscs1 == calccs1:
  98.                         anscs2=unpack('B',answer[anslen-1])[0]
  99.                         # calculate data checksum
  100.                         for d in answer[4:anslen-1] :
  101.                             calccs2^=unpack('B',d)[0]
  102.                         #check data checksum
  103.                         if anscs2 == calccs2 :
  104.                             ret=[1,answer[4:anslen-1],"No Errors"]
  105.                         else:
  106.                             ret=[-1,answer[4:anslen-1],"Error: wrong data checksum"]
  107.                     else:
  108.                         ret=[-1,answer[4:anslen-1],"Error: wrong command checksum"]
  109.                 else:
  110.                     ret=[-1,answer[4:anslen-1],"Error: wrong packet lenght"]
  111.             else:
  112.                 ret=[-1,'',"Error: bad command code returned"]
  113.         else:
  114.             ret=[-1,'',"Error: no answer received"]
  115.     port.close()
  116.     lastcommandtime=time.time()
  117.     return  ret
  118.  
  119. # Same as SendCommand but prints the payload in readable string format
  120. def SendCommandChar(port,ID,Data,ReadBack):
  121.     answer=SendCommand(port,ID,Data,ReadBack)
  122. #    answer=input("Answer? ")
  123.     answerstring=''
  124.     for i in answer[1]:
  125.         answerstring+=(hex(unpack('B',i)[0]))+ "\n"
  126.     print(str(len(answer[1]))+" Bytes in answer")
  127.     print(answerstring)
  128.     return answer
  129.  
  130.  
  131. # Returns the Offset from the FE5680A        
  132. def GetOffs(port):
  133.     commandcode=0x2D
  134.     data=''
  135.     ret=SendCommand(port,commandcode,data,True)
  136.     if ret[0]==1:
  137.         return unpack('>i',ret[1])[0]
  138.     else:
  139.         print("Error code "+str(ret[0]))
  140.         print(ret[2])
  141.         return 0
  142.    
  143. # Sets the offset, without saving the value
  144. def SetOffsRam(port,value):
  145.     commandcode=0x2E
  146.     data=pack('>i',value)
  147.     return SendCommand(port,commandcode,data,False)[2]
  148.  
  149. # Sets the offset relative to the value stored in the FE5680A,
  150. # without saving the value, useful for incremental changes
  151. def SetOffsRelRam(port,value):
  152.     refoffs=GetOffs(port)
  153.     newoffs=refoffs+value
  154.     return SetOffsRam(port,newoffs)
  155.  
  156. # Sets the offset, saving the value into the EEPROM of the FE5680A
  157. def SetOffsEE(port,value):
  158.     commandcode=0x2C
  159.     data=pack('>i',value)
  160.     return SendCommand(port,commandcode,data,False)
  161.  
  162. # Reads the offset from internal ram and Stores it to EEPROM
  163. def StoreOffsEE(port):
  164.     value=GetOffs(port)
  165.     return SetOffsEE(port,value)
  166.  
  167. # Change the frequency output of valueHz Hz, not stored
  168. def ChangeFreqHz(port,valueHz):
  169.     Offs=int(float(valueHz)/(resolution_parts_per_bit*1e7))
  170.     print("new offset: "+str(Offs))
  171.     return SetOffsRelRam(port,Offs)
  172.  
  173. # Change the frequency output of valueP parts, not stored
  174. def ChangeFreqP(port,valueP):
  175.     Offs=int(float(valueP)/resolution_parts_per_bit)
  176.     print("Offset: "+str(Offs))
  177.     return SetOffsRelRam(port,Offs)
  178.  
  179. # Read the DDS setting
  180. # returns a list containing DDS values and frequencies
  181. def GetDDS(p):
  182.     global DDSinputFreq
  183.     commandcode=0x22
  184.     answ=SendCommand(p,commandcode,'',True)
  185.     if answ[0] == 1:
  186.         DDS1=(unpack('>I',answ[1][0:4])[0])
  187.         DDS2=(unpack('>I',answ[1][4:8])[0])
  188.         F1=DDS1/(pow(2.0,32))*DDSinputFreq
  189.         F2=DDS2/(pow(2.0,32))*DDSinputFreq
  190.         return [DDS1,DDS2,F1,F2]
  191.     else:
  192.         print("Error")
  193.         return [0,0,0,0]
  194.  
  195. # Read the ADC settings (unsure)
  196. # returns a list containing ADC values
  197. def GetADC(p):
  198.     global DDSinputFreq
  199.     commandcode=0x5A
  200.     answ=SendCommand(p,commandcode,'',True)
  201.     if answ[0] == 1:
  202.         ADC1=(unpack('<H',answ[1][0:2])[0])
  203.         ADC2=(unpack('<H',answ[1][2:4])[0])
  204.         ADC3=(unpack('<H',answ[1][4:6])[0])
  205.         ADC4=(unpack('<H',answ[1][6:8])[0])
  206.         return [ADC1,ADC2,ADC3,ADC4]
  207.     else:
  208.         print("Error")
  209.         return [0,0,0,0]
  210.  
  211. # Prints the status of the device
  212. def PrintStatus(p):
  213.     offs=GetOffs(p)
  214.     dds=GetDDS(p)
  215.     adc=GetADC(p)
  216.     print("Offset word: "+str(offs))
  217.     print("Equivalent shift of "+str(offs*resolution_parts_per_bit))
  218.     print("Equivalent to "+str(offs*resolution_parts_per_bit*(1.0e7))+"Hz")    
  219.     print("Based on an internal resolution of "+str(resolution_parts_per_bit)+" parts per bit")
  220.     print("DDS status:")
  221.     print("DDS Word 1: "+str(dds[0]))
  222.     print("DDS Word 2: "+str(dds[1]))
  223.     print("DDS Frequencies, values based on "+str(DDSinputFreq)+"Hz DDS input Frequency:")
  224.     print("Frequency 1: "+str(dds[2])+"Hz")
  225.     print("Frequency 2: "+str(dds[3])+"Hz")
  226.     print("ADC status:")
  227.     print("ADC Word 1 (trimpot?     ): "+str(adc[0]))
  228.     print("ADC Word 2 (supply V?    ): "+str(adc[1]))
  229.     print("ADC Word 3 (temperature? ): "+str(adc[2]))
  230.     print("ADC Word 4 (VCXO Voltage?): "+str(adc[3]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement