added AD9833 and DS1809 support

This commit is contained in:
Ayzen
2026-02-09 10:29:52 +03:00
parent 0d6a73d835
commit 1252bcbdbf
9 changed files with 218 additions and 24 deletions

View File

@ -10,15 +10,27 @@ GET_DATA_TOTAL_LENGTH = 30 # Total number of bytes when getting DATA
SEND_PARAMS_TOTAL_LENGTH = 30 # Total number of bytes when sending parameters
TASK_ENABLE_COMMAND_LENGTH = 32 # Total number of bytes when sending TASK_ENABLE command
AD9833_CMD_TOTAL_LENGTH = 10 # Total bytes when sending AD9102 saw command
AD9833_CMD_HEADER = "8888"
AD9102_CMD_TOTAL_LENGTH = 10 # Total bytes when sending AD9102 saw command
AD9102_CMD_HEADER = "8888"
AD9833_CMD_TOTAL_LENGTH = 10 # Total bytes when sending AD9833 command
AD9833_CMD_HEADER = "9999"
DS1809_CMD_TOTAL_LENGTH = 10 # Total bytes when sending DS1809 UC/DC pulse command
DS1809_CMD_HEADER = "AAAA"
AD9102_SAW_STEP_DEFAULT = 1
AD9102_PAT_PERIOD_DEFAULT = 0xFFFF
AD9102_PAT_PERIOD_BASE_DEFAULT = 0x02
AD9102_DAC_CLK_HZ = None # set to actual DAC clock if you want freq->SAW_STEP conversion
AD9102_FLAG_SRAM = 0x0004
AD9102_FLAG_SRAM_FMT = 0x0008
AD9102_SRAM_SAMPLES_DEFAULT = 16
AD9102_SRAM_HOLD_DEFAULT = 1
AD9102_SRAM_AMP_DEFAULT = 8191
AD9833_FLAG_ENABLE = 0x0001
AD9833_FLAG_TRIANGLE = 0x0002
AD9833_MCLK_HZ_DEFAULT = 25_000_000
DS1809_FLAG_UC = 0x0001
DS1809_FLAG_DC = 0x0002
DS1809_PULSE_MS_DEFAULT = 2
class TaskType(IntEnum):
Manual = 0x00
@ -158,8 +170,19 @@ def send_STATE(prt):
pass
def send_AD9102(prt, bytestring):
''' Start/stop AD9102 output with saw/triangle (0x8888 + ...).
Expected device answer: STATE.
'''
if len(bytestring) != AD9102_CMD_TOTAL_LENGTH:
print("Error. Wrong parameter string for AD9102 command.")
return None
prt.write(bytestring)
print("Sent: AD9102 ramp command.")
def send_AD9833(prt, bytestring):
''' Start/stop AD9833 output with triangle (ramp) mode (0x8888 + ...).
''' Start/stop AD9833 output with triangle (0x9999 + ...).
Expected device answer: STATE.
'''
if len(bytestring) != AD9833_CMD_TOTAL_LENGTH:
@ -169,6 +192,17 @@ def send_AD9833(prt, bytestring):
print("Sent: AD9833 ramp command.")
def send_DS1809(prt, bytestring):
''' Pulse DS1809 UC/DC control lines (0xAAAA + ...).
Expected device answer: STATE.
'''
if len(bytestring) != DS1809_CMD_TOTAL_LENGTH:
print("Error. Wrong parameter string for DS1809 command.")
return None
prt.write(bytestring)
print("Sent: DS1809 pulse command.")
# ---- Getting data
@ -324,14 +358,15 @@ def calc_sram_samples_for_freq(freq_hz: float, dac_clk_hz: float, hold: int = No
def create_AD9833_ramp_command(saw_step: int = None,
def create_AD9102_ramp_command(saw_step: int = None,
pat_period: int = None,
pat_period_base: int = None,
enable: bool = True,
triangle: bool = True,
sram_mode: bool = False,
sram_samples: int = None,
sram_hold: int = None):
sram_hold: int = None,
sram_amplitude: int = None):
flags = 0
if enable:
flags |= 0x0001
@ -341,18 +376,21 @@ def create_AD9833_ramp_command(saw_step: int = None,
flags |= AD9102_FLAG_SRAM
if sram_mode:
flags |= AD9102_FLAG_SRAM_FMT
if sram_samples is None:
sram_samples = AD9102_SRAM_SAMPLES_DEFAULT
if sram_samples < 2:
sram_samples = 2
if sram_samples > 4096:
sram_samples = 4096
if sram_hold is None or sram_hold <= 0:
sram_hold = AD9102_SRAM_HOLD_DEFAULT
if sram_hold > 0x0F:
sram_hold = 0x0F
param0 = sram_samples & 0xFFFF
param1 = sram_hold & 0x000F
if sram_amplitude is None:
sram_amplitude = AD9102_SRAM_AMP_DEFAULT
if sram_amplitude < 0:
sram_amplitude = 0
if sram_amplitude > AD9102_SRAM_AMP_DEFAULT:
sram_amplitude = AD9102_SRAM_AMP_DEFAULT
param0 = int(sram_amplitude) & 0xFFFF
param1 = int(sram_samples) & 0xFFFF
else:
if saw_step is None:
saw_step = AD9102_SAW_STEP_DEFAULT
@ -377,8 +415,78 @@ def create_AD9833_ramp_command(saw_step: int = None,
crc_word = flags ^ param0 ^ param1
data = flipfour(AD9102_CMD_HEADER) # Word 0 (header)
data += flipfour(int_to_hex(flags))
data += flipfour(int_to_hex(param0))
data += flipfour(int_to_hex(param1))
data += flipfour(int_to_hex(crc_word))
return bytearray.fromhex(data)
def create_AD9833_ramp_command(freq_hz: float,
mclk_hz: float = None,
enable: bool = True,
triangle: bool = True):
if mclk_hz is None or mclk_hz <= 0:
mclk_hz = AD9833_MCLK_HZ_DEFAULT
if mclk_hz is None or mclk_hz <= 0 or freq_hz is None or freq_hz < 0:
freq_word = 0
else:
freq_word = int(round((freq_hz * (1 << 28)) / float(mclk_hz)))
if freq_word < 0:
freq_word = 0
if freq_word > 0x0FFFFFFF:
freq_word = 0x0FFFFFFF
lsw = freq_word & 0x3FFF
msw = (freq_word >> 14) & 0x3FFF
flags = 0
if enable:
flags |= AD9833_FLAG_ENABLE
if triangle:
flags |= AD9833_FLAG_TRIANGLE
crc_word = flags ^ lsw ^ msw
data = flipfour(AD9833_CMD_HEADER) # Word 0 (header)
data += flipfour(int_to_hex(flags))
data += flipfour(int_to_hex(lsw))
data += flipfour(int_to_hex(msw))
data += flipfour(int_to_hex(crc_word))
return bytearray.fromhex(data)
def create_DS1809_pulse_command(uc: bool = False,
dc: bool = False,
count: int = 1,
pulse_ms: int = None):
flags = 0
if uc:
flags |= DS1809_FLAG_UC
if dc:
flags |= DS1809_FLAG_DC
if count is None or count <= 0:
count = 1
if count > 64:
count = 64
if pulse_ms is None:
pulse_ms = DS1809_PULSE_MS_DEFAULT
if pulse_ms < 1:
pulse_ms = 1
if pulse_ms > 500:
pulse_ms = 500
param0 = int(count) & 0xFFFF
param1 = int(pulse_ms) & 0xFFFF
crc_word = flags ^ param0 ^ param1
data = flipfour(DS1809_CMD_HEADER) # Word 0 (header)
data += flipfour(int_to_hex(flags))
data += flipfour(int_to_hex(param0))
data += flipfour(int_to_hex(param1))
data += flipfour(int_to_hex(crc_word))
@ -463,8 +571,12 @@ def decode_DATA(dh):
data = {}
data['datetime'] = datetime.now()
data['Header'] = get_word(dh, 0)
data['I1'] = cnv.conv_I_N_to_mA(get_int_word(dh, 1)) #LD1_param.POWER
data['I2'] = cnv.conv_I_N_to_mA(get_int_word(dh, 2)) #LD2_param.POWER
i1_raw = get_int_word(dh, 1)
i2_raw = get_int_word(dh, 2)
data['I1_raw'] = i1_raw
data['I2_raw'] = i2_raw
data['I1'] = cnv.conv_I_N_to_mA(i1_raw) #LD1_param.POWER
data['I2'] = cnv.conv_I_N_to_mA(i2_raw) #LD2_param.POWER
data['TO_LSB'] = get_int_word(dh, 3) #TO6_counter_LSB
data['TO_MSB'] = get_int_word(dh, 4) #TO6_counter_MSB
data['Temp_1'] = cnv.conv_T_N_to_C(get_int_word(dh, 5)) #LD1_param.LD_CURR_TEMP
@ -479,4 +591,3 @@ def decode_DATA(dh):
data['CRC'] = get_word(dh, 14)
return data