diff --git a/__pycache__/device_commands.cpython-312.pyc b/__pycache__/device_commands.cpython-312.pyc index 3f7dcec..1ebe2d2 100644 Binary files a/__pycache__/device_commands.cpython-312.pyc and b/__pycache__/device_commands.cpython-312.pyc differ diff --git a/__pycache__/device_interaction.cpython-312.pyc b/__pycache__/device_interaction.cpython-312.pyc index 708036d..9703250 100644 Binary files a/__pycache__/device_interaction.cpython-312.pyc and b/__pycache__/device_interaction.cpython-312.pyc differ diff --git a/__pycache__/gui.cpython-312.pyc b/__pycache__/gui.cpython-312.pyc index d94c7f2..85b6872 100644 Binary files a/__pycache__/gui.cpython-312.pyc and b/__pycache__/gui.cpython-312.pyc differ diff --git a/_device_main.py b/_device_main.py index 05dc422..814cc0b 100644 --- a/_device_main.py +++ b/_device_main.py @@ -105,6 +105,8 @@ def set_initial_params(): params['RampPatBase'] = 2 params['RampDacClk'] = '' params['RampTriangle'] = True + params['RampSramMode'] = False + params['RampSramSamples'] = '' return params def update_data_lists(): @@ -469,9 +471,12 @@ if __name__ == "__main__": dac_clk_mhz = parse_optional_float(values.get('-RampDacClk-')) dac_clk_hz = dac_clk_mhz * 1e6 if dac_clk_mhz is not None else None triangle = values.get('-RampTriangle-', True) + sram_mode = values.get('-RampSramMode-', False) + sram_samples = parse_optional_int(values.get('-RampSramSamples-')) dev.start_ramp_max(prt, freq_hz=freq_hz, duty=duty, saw_step=saw_step, pat_period=pat_period, pat_period_base=pat_period_base, - dac_clk_hz=dac_clk_hz, triangle=triangle) + dac_clk_hz=dac_clk_hz, triangle=triangle, + sram_mode=sram_mode, sram_samples=sram_samples) elif event == '-StopCycle-': window['-StopCycle-'].update(disabled = True) current_and_temperature_settings_available = True diff --git a/device_commands.py b/device_commands.py index ef71d54..f17eba5 100644 --- a/device_commands.py +++ b/device_commands.py @@ -16,6 +16,9 @@ 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_SRAM_SAMPLES_DEFAULT = 16 +AD9102_SRAM_HOLD_DEFAULT = 1 class TaskType(IntEnum): Manual = 0x00 @@ -307,44 +310,77 @@ def calc_pat_period_for_duty(saw_step: int, duty: float, pat_period_base: int, t pat_period = 0xFFFF return pat_period +def calc_sram_samples_for_freq(freq_hz: float, dac_clk_hz: float, hold: int = None): + if hold is None or hold <= 0: + hold = AD9102_SRAM_HOLD_DEFAULT + if freq_hz is None or freq_hz <= 0 or dac_clk_hz is None or dac_clk_hz <= 0: + return AD9102_SRAM_SAMPLES_DEFAULT + samples = int(round(dac_clk_hz / (freq_hz * hold))) + if samples < 2: + samples = 2 + if samples > 4096: + samples = 4096 + return samples + + def create_AD9833_ramp_command(saw_step: int = None, pat_period: int = None, pat_period_base: int = None, enable: bool = True, - triangle: bool = True): - if saw_step is None: - saw_step = AD9102_SAW_STEP_DEFAULT - if pat_period is None: - pat_period = AD9102_PAT_PERIOD_DEFAULT - if pat_period_base is None: - pat_period_base = AD9102_PAT_PERIOD_BASE_DEFAULT - if saw_step < 1: - saw_step = 1 - if saw_step > 63: - saw_step = 63 - if pat_period < 0: - pat_period = 0 - if pat_period > 0xFFFF: - pat_period = 0xFFFF - if pat_period_base < 0: - pat_period_base = 0 - if pat_period_base > 0x0F: - pat_period_base = 0x0F - + triangle: bool = True, + sram_mode: bool = False, + sram_samples: int = None, + sram_hold: int = None): flags = 0 if enable: flags |= 0x0001 if triangle: flags |= 0x0002 + if sram_mode: + flags |= AD9102_FLAG_SRAM - param0 = ((pat_period_base & 0x0F) << 8) | (saw_step & 0xFF) - crc_word = flags ^ param0 ^ pat_period + if sram_mode: + 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 + else: + if saw_step is None: + saw_step = AD9102_SAW_STEP_DEFAULT + if pat_period is None: + pat_period = AD9102_PAT_PERIOD_DEFAULT + if pat_period_base is None: + pat_period_base = AD9102_PAT_PERIOD_BASE_DEFAULT + if saw_step < 1: + saw_step = 1 + if saw_step > 63: + saw_step = 63 + if pat_period < 0: + pat_period = 0 + if pat_period > 0xFFFF: + pat_period = 0xFFFF + if pat_period_base < 0: + pat_period_base = 0 + if pat_period_base > 0x0F: + pat_period_base = 0x0F + param0 = ((pat_period_base & 0x0F) << 8) | (saw_step & 0xFF) + param1 = pat_period + + crc_word = flags ^ param0 ^ param1 data = flipfour(AD9833_CMD_HEADER) # Word 0 (header) data += flipfour(int_to_hex(flags)) data += flipfour(int_to_hex(param0)) - data += flipfour(int_to_hex(pat_period)) + data += flipfour(int_to_hex(param1)) data += flipfour(int_to_hex(crc_word)) return bytearray.fromhex(data) diff --git a/device_interaction.py b/device_interaction.py index 80f603b..e7877e8 100644 --- a/device_interaction.py +++ b/device_interaction.py @@ -112,21 +112,32 @@ def send_task_command(prt, sending_param): -def start_ramp_max(prt, freq_hz=None, duty=None, saw_step=None, pat_period=None, pat_period_base=None, dac_clk_hz=None, triangle=True): - # Start AD9102 sawtooth with configurable frequency/duty (via SAW_STEP and PAT_PERIOD) - if pat_period_base is None: - pat_period_base = cmd.AD9102_PAT_PERIOD_BASE_DEFAULT - if saw_step is None and freq_hz is not None: - if dac_clk_hz is None: - dac_clk_hz = cmd.AD9102_DAC_CLK_HZ - saw_step = cmd.calc_saw_step_for_freq(freq_hz, dac_clk_hz, triangle) - if saw_step is None: - saw_step = cmd.AD9102_SAW_STEP_DEFAULT - if pat_period is None and duty is not None: - pat_period = cmd.calc_pat_period_for_duty(saw_step, duty, pat_period_base, triangle) - if pat_period is None: - pat_period = cmd.AD9102_PAT_PERIOD_DEFAULT - hexstring = cmd.create_AD9833_ramp_command(saw_step, pat_period, pat_period_base, enable=True, triangle=triangle) +def start_ramp_max(prt, freq_hz=None, duty=None, saw_step=None, pat_period=None, pat_period_base=None, dac_clk_hz=None, triangle=True, sram_mode=False, sram_samples=None, sram_hold=None): + # Start AD9102 sawtooth with configurable frequency/duty or SRAM ramp mode + if sram_mode: + if sram_hold is None: + sram_hold = cmd.AD9102_SRAM_HOLD_DEFAULT + if sram_samples is None and freq_hz is not None: + if dac_clk_hz is None: + dac_clk_hz = cmd.AD9102_DAC_CLK_HZ + sram_samples = cmd.calc_sram_samples_for_freq(freq_hz, dac_clk_hz, sram_hold) + hexstring = cmd.create_AD9833_ramp_command(enable=True, triangle=triangle, sram_mode=True, + sram_samples=sram_samples, sram_hold=sram_hold) + else: + if pat_period_base is None: + pat_period_base = cmd.AD9102_PAT_PERIOD_BASE_DEFAULT + if saw_step is None and freq_hz is not None: + if dac_clk_hz is None: + dac_clk_hz = cmd.AD9102_DAC_CLK_HZ + saw_step = cmd.calc_saw_step_for_freq(freq_hz, dac_clk_hz, triangle) + if saw_step is None: + saw_step = cmd.AD9102_SAW_STEP_DEFAULT + if pat_period is None and duty is not None: + pat_period = cmd.calc_pat_period_for_duty(saw_step, duty, pat_period_base, triangle) + if pat_period is None: + pat_period = cmd.AD9102_PAT_PERIOD_DEFAULT + hexstring = cmd.create_AD9833_ramp_command(saw_step, pat_period, pat_period_base, + enable=True, triangle=triangle) cmd.send_AD9833(prt, hexstring) time.sleep(WAIT_AFTER_SEND) status = cmd.get_STATE(prt).hex() diff --git a/gui.py b/gui.py index c0e1056..8ac9c2b 100644 --- a/gui.py +++ b/gui.py @@ -47,6 +47,8 @@ SET_RAMP_PATPERIOD_TEXT = 'PAT_PERIOD (1-65535):' SET_RAMP_PATBASE_TEXT = 'PAT_PERIOD_BASE (0-15):' SET_RAMP_DACCLK_TEXT = 'DAC clk (МГц):' SET_RAMP_TRI_TEXT = 'Треугольник' +SET_RAMP_SRAM_MODE_TEXT = 'SRAM режим' +SET_RAMP_SRAM_SAMPLES_TEXT = 'SRAM точки (samples):' GRAPH_POINTS_NUMBER = 100 # Number of most recent data points shown on charts @@ -228,6 +230,12 @@ def setup_gui(params): [sg.Text(SET_RAMP_TRI_TEXT, size=(SET_TEXT_WIDTH_NEW,1)), sg.Checkbox('', default=bool(params.get('RampTriangle', True)), key='-RampTriangle-')], + [sg.Text(SET_RAMP_SRAM_MODE_TEXT, size=(SET_TEXT_WIDTH_NEW,1)), + sg.Checkbox('', default=bool(params.get('RampSramMode', False)), key='-RampSramMode-')], + + [sg.Text(SET_RAMP_SRAM_SAMPLES_TEXT, size=(SET_TEXT_WIDTH_NEW,1)), + sg.Input(params.get('RampSramSamples', ''), size=(SET_INPUT_WIDTH,1), key='-RampSramSamples-')], + [sg.HSeparator(pad=H_SEPARATOR_PAD)], [sg.Button(SET_START_BUTTON_TEXT, key='-StartCycle-', disabled_button_color=("Gray22", "Blue"), disabled=True), sg.Button(SET_STOP_BUTTON_TEXT, disabled_button_color=("Gray22", "Blue"), key='-StopCycle-', disabled=True), sg.Button(SET_RAMP_BUTTON_TEXT, key='-StartRamp-', disabled_button_color=("Gray22", "Blue"))]]