data.py
409 lines
| 9.9 KiB
| text/x-python
|
PythonLexer
|
r51 | ''' | |
Created on Feb 15, 2016 | |||
@author: Miguel Urco | |||
''' | |||
import struct | |||
|
r57 | import string | |
|
r51 | ||
DDS_NBITS = 48 | |||
|
r57 | FILE_STRUCTURE = """Phase Adjust Register 1 | |
----------------------- | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Phase Adjust Register 2 | |||
----------------------- | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Frequency Tuning Word 1 | |||
----------------------- | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Frequency Tuning Word 2 | |||
----------------------- | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Delta Frequency Word | |||
----------------------- | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Update Clock | |||
----------------------- | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Ramp Rate Clock | |||
----------------------- | |||
00000000 | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Control Register | |||
----------------------- | |||
00000000 | |||
00000000 | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Output Shaped Keying I | |||
Multiplier | |||
----------------------- | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Output Shaped Keying Q | |||
Multiplier | |||
----------------------- | |||
00000000 | |||
00000000 | |||
----------------------- | |||
Output Shaped Keying | |||
Ramp Rate | |||
----------------------- | |||
00000000 | |||
----------------------- | |||
QDAC | |||
----------------------- | |||
00000000 | |||
00000000 | |||
----------------------- | |||
CLOCK INPUT | |||
----------------------- | |||
10.00000000""" | |||
|
r51 | def freq_to_binary(freq, mclock): | |
|
r57 | if not mclock: | |
return None | |||
try: | |||
binary = int((float(freq)/mclock)*(2**DDS_NBITS)) | |||
except: | |||
return 0 | |||
|
r51 | ||
return binary | |||
def binary_to_freq(binary, mclock): | |||
|
r57 | if not mclock: | |
return None | |||
try: | |||
freq = (float(binary)/(2**DDS_NBITS))*mclock | |||
except: | |||
return 0 | |||
|
r51 | ||
return freq | |||
def phase_to_binary(phase): | |||
|
r57 | try: | |
binary = int(float(phase)*8192/180.0) | |||
except: | |||
return 0 | |||
|
r51 | ||
return binary | |||
def binary_to_phase(binary): | |||
|
r57 | try: | |
phase = float(binary)*180.0/8192 | |||
except: | |||
return 0 | |||
|
r51 | ||
return phase | |||
|
r57 | def __fill_dds_dict(parms): | |
my_dict = {'clock' : None, | |||
'multiplier' : 1, | |||
'frequencyA' : 0, | |||
'frequencyB' : 0, | |||
'frequencyA_Mhz' : 0, | |||
'frequencyB_Mhz' : 0, | |||
'phaseA_degress' : 0, | |||
'phaseB_degress' : 0, | |||
'modulation' : 0, | |||
'amplitudeI' : 0, | |||
'amplitudeQ' : 0, | |||
'amplitude_enabled' : 0, | |||
'delta_frequency' : 0, | |||
'update_clock' : 0, | |||
'ramp_rate_clock' : 0, | |||
'amplitude_ramp_rate' : 0, | |||
'qdac' : 0 | |||
} | |||
my_dict.update(parms) | |||
my_dict['phaseA'] = phase_to_binary(my_dict['phaseA_degrees']) | |||
my_dict['phaseB'] = phase_to_binary(my_dict['phaseB_degrees']) | |||
pll_range = 0 | |||
if my_dict['clock'] >= 200: | |||
pll_range = 1 | |||
pll_bypass = 0 | |||
if my_dict['multiplier'] < 4: | |||
pll_bypass = 1 | |||
control_register = (1 << 28) + \ | |||
(pll_range << 22) + (pll_bypass << 21) + \ | |||
(my_dict['multiplier'] << 16) + \ | |||
(my_dict['modulation'] << 9) + \ | |||
(my_dict['amplitude_enabled'] << 5) | |||
my_dict['control_register'] = control_register | |||
return my_dict | |||
def dds_str_to_dict(registers, clock=None): | |||
|
r51 | ||
""" | |||
Output: | |||
parms : Dictionary with keys | |||
multiplier : | |||
frequencyA : | |||
frequencyB : | |||
frequencyA_Mhz : | |||
frequencyB_Mhz : | |||
modulation : | |||
phaseA_degrees : | |||
phaseB_degrees : | |||
amplitudeI : | |||
amplitudeQ : | |||
""" | |||
if not registers: | |||
return {} | |||
if len(registers) != 0x28: | |||
return {} | |||
phaseA = struct.unpack('>H', registers[0x0:0x2])[0] | |||
phaseB = struct.unpack('>H', registers[0x2:0x4])[0] | |||
frequencyA = struct.unpack('>Q', '\x00\x00' + registers[0x04:0x0A])[0] | |||
frequencyB = struct.unpack('>Q', '\x00\x00' + registers[0x0A:0x10])[0] | |||
delta_frequency = struct.unpack('>Q', '\x00\x00' + registers[0x10:0x16])[0] | |||
update_clock = struct.unpack('>I', registers[0x16:0x1A])[0] | |||
ramp_rate_clock = struct.unpack('>I', '\x00' + registers[0x1A:0x1D])[0] | |||
control_register = struct.unpack('>I', registers[0x1D:0x21])[0] | |||
amplitudeI = struct.unpack('>H', registers[0x21:0x23])[0] | |||
amplitudeQ = struct.unpack('>H', registers[0x23:0x25])[0] | |||
amp_ramp_rate = ord(registers[0x25]) | |||
qdac = struct.unpack('>H', registers[0x26:0x28])[0] | |||
multiplier = (control_register & 0x001F0000) >> 16 | |||
modulation = (control_register & 0x00000E00) >> 9 | |||
amplitude_enabled = (control_register & 0x00000020) >> 5 | |||
|
r57 | frequencyA_Mhz = None | |
frequencyB_Mhz = None | |||
if clock: | |||
mclock = clock*multiplier | |||
frequencyA_Mhz = binary_to_freq(frequencyA, mclock) | |||
frequencyB_Mhz = binary_to_freq(frequencyB, mclock) | |||
parms = {'clock' : clock, | |||
|
r51 | 'multiplier' : multiplier, | |
'frequencyA' : frequencyA, | |||
'frequencyB' : frequencyB, | |||
|
r57 | 'frequencyA_Mhz' : frequencyA_Mhz, | |
'frequencyB_Mhz' : frequencyB_Mhz, | |||
|
r51 | 'phaseA' : phaseA, | |
'phaseB' : phaseB, | |||
'phaseA_degrees' : binary_to_phase(phaseA), | |||
'phaseB_degrees' : binary_to_phase(phaseB), | |||
'modulation' : modulation, | |||
'amplitudeI' : amplitudeI, | |||
'amplitudeQ' : amplitudeQ, | |||
'amplitude_enabled' : amplitude_enabled, | |||
'delta_frequency' : delta_frequency, | |||
'update_clock' : update_clock, | |||
'ramp_rate_clock' : ramp_rate_clock, | |||
'amp_ramp_rate' : amp_ramp_rate, | |||
'qdac' : qdac | |||
} | |||
return parms | |||
def dict_to_dds_str(parms): | |||
""" | |||
Input: | |||
parms : Dictionary with keys | |||
multiplier : 4 to 20 | |||
frequencyA : 0 to (2**48-1) equivalent to: 0 - "Master clock" | |||
frequencyB : 0 to (2**48-1) equivalent to: 0 - "Master clock" | |||
modulation : 0 to 3 | |||
phaseA_degrees : 0 - 360 degrees | |||
phaseB_degrees : 0 - 360 degrees | |||
amplitudeI : 0 to (2**12-1) equivalent to: 0 - 100% | |||
amplitudeQ : 0 to (2**12-1) equivalent to: 0 - 100% | |||
""" | |||
|
r57 | my_dict = __fill_dds_dict(parms) | |
|
r51 | ||
registers = "" | |||
registers += struct.pack(">H", my_dict['phaseA']) | |||
registers += struct.pack(">H", my_dict['phaseB']) | |||
registers += struct.pack(">Q", my_dict['frequencyA'])[2:] | |||
registers += struct.pack(">Q", my_dict['frequencyB'])[2:] | |||
registers += struct.pack(">Q", my_dict['delta_frequency'])[2:] | |||
registers += struct.pack(">I", my_dict['update_clock']) | |||
registers += struct.pack(">I", my_dict['ramp_rate_clock'])[1:] | |||
|
r57 | registers += struct.pack(">I", my_dict['control_register']) | |
|
r51 | ||
registers += struct.pack(">H", my_dict['amplitudeI']) | |||
registers += struct.pack(">H", my_dict['amplitudeQ']) | |||
registers += chr(my_dict['amplitude_ramp_rate']) | |||
registers += struct.pack(">H", my_dict['qdac']) | |||
|
r57 | return registers | |
def text_to_dict(lines): | |||
registers = "" | |||
registers_v2 = [] | |||
for this_line in lines: | |||
this_line = str.strip(this_line) | |||
if str.isalpha(this_line): | |||
continue | |||
if not str.isdigit(this_line): | |||
try: | |||
value = float(this_line) | |||
except: | |||
continue | |||
registers_v2.append(value) | |||
continue | |||
if len(this_line) != 8: | |||
continue | |||
registers += chr(string.atoi(this_line,2)) | |||
mclock = None | |||
if len(registers_v2) > 0: | |||
mclock = registers_v2[0] | |||
my_dict = dds_str_to_dict(registers, mclock) | |||
return my_dict | |||
def dict_to_text(parms): | |||
""" | |||
It creates formatted DDS text using dictionary values. | |||
""" | |||
my_dict = __fill_dds_dict(parms) | |||
lines = FILE_STRUCTURE.split('\n') | |||
cad = '{0:016b}'.format(my_dict['phaseA']) | |||
lines[2] = cad[0:8] | |||
lines[3] = cad[8:16] | |||
cad = '{0:016b}'.format(my_dict['phaseB']) | |||
lines[7] = cad[0:8] | |||
lines[8] = cad[8:16] | |||
cad = '{0:048b}'.format(my_dict['frequencyA']) | |||
lines[12] = cad[0:8] | |||
lines[13] = cad[8:16] | |||
lines[14] = cad[16:24] | |||
lines[15] = cad[24:32] | |||
lines[16] = cad[32:40] | |||
lines[17] = cad[40:48] | |||
cad = '{0:048b}'.format(my_dict['frequencyB']) | |||
lines[21] = cad[0:8] | |||
lines[22] = cad[8:16] | |||
lines[23] = cad[16:24] | |||
lines[24] = cad[24:32] | |||
lines[25] = cad[32:40] | |||
lines[26] = cad[40:48] | |||
cad = '{0:048b}'.format(my_dict['delta_frequency']) | |||
lines[30] = cad[0:8] | |||
lines[31] = cad[8:16] | |||
lines[32] = cad[16:24] | |||
lines[33] = cad[24:32] | |||
lines[34] = cad[32:40] | |||
lines[35] = cad[40:48] | |||
cad = '{0:032b}'.format(my_dict['update_clock']) | |||
lines[39] = cad[0:8] | |||
lines[40] = cad[8:16] | |||
lines[41] = cad[16:24] | |||
lines[42] = cad[24:32] | |||
cad = '{0:024b}'.format(my_dict['ramp_rate_clock']) | |||
lines[46] = cad[0:8] | |||
lines[47] = cad[8:16] | |||
lines[48] = cad[16:24] | |||
cad = '{0:032b}'.format(my_dict['control_register']) | |||
lines[52] = cad[0:8] | |||
lines[53] = cad[8:16] | |||
lines[54] = cad[16:24] | |||
lines[55] = cad[24:32] | |||
cad = '{0:016b}'.format(my_dict['amplitudeI']) | |||
lines[60] = cad[0:8] | |||
lines[61] = cad[8:16] | |||
cad = '{0:016b}'.format(my_dict['amplitudeQ']) | |||
lines[66] = cad[0:8] | |||
lines[67] = cad[8:16] | |||
cad = '{0:08b}'.format(my_dict['amplitude_ramp_rate']) | |||
lines[72] = cad[0:8] | |||
cad = '{0:016b}'.format(my_dict['qdac']) | |||
lines[76] = cad[0:8] | |||
lines[77] = cad[8:16] | |||
lines[81] = '%10.8f' %my_dict['clock'] | |||
text = '\n'.join(lines) | |||
return text |