move files

move scripts
This commit is contained in:
Lucas Vivohost committed 2026-09-14 12:43:38 +02:00
1 parent 5cdbf51c1e
commit 408566b6ea
21 files changed
+53

No files matched your search

+280
View File
@@ -0,0 +1,280 @@
import re
import pprint
import re
from collections import defaultdict
# =====================================================================
# Unified DynamicObject (replaces DynamicMObject + DynamicCppObject)
# =====================================================================
class DynamicObject(dict):
"""
A unified dynamic object that:
- Behaves like a dict
- Supports attribute access
- Auto-creates nested fields on demand
"""
def __getattr__(self, name):
if name not in self:
self[name] = DynamicObject()
return self[name]
def __setattr__(self, name, value):
self[name] = value
def ensure_path(self, path_parts):
obj = self
for part in path_parts:
if part not in obj:
obj[part] = DynamicObject()
obj = obj[part]
return obj
def __repr__(self):
return dict.__repr__(self)
# =====================================================================
# MATLAB FRD REG PARSER
# =====================================================================
def parse_oFRDReg_from_mfile(filename):
oFRDReg = DynamicObject()
# Regex to capture: oFRDReg.<path> = <value>;
pattern = re.compile(r"oFRDReg\.([A-Za-z0-9_.]+)\s*=\s*([^;]+);")
with open(filename, "r") as f:
for line in f:
match = pattern.search(line)
if match:
full_path = match.group(1)
value_raw = match.group(2).strip()
# Convert numeric/string values when possible
try:
value = eval(value_raw)
except:
value = value_raw
# Split path: e.g. MSI.vcm_sel → ["MSI", "vcm_sel"]
parts = full_path.split(".")
parts = [ p.upper() for p in parts ]
attr_name = parts[-1]
parent_path = parts[:-1]
# Create nested path
parent = oFRDReg.ensure_path(parent_path)
setattr(parent, attr_name, value)
return oFRDReg
# =====================================================================
# Macro expansion helper
# =====================================================================
def expand_macro_pattern(pattern, **kwargs):
"""
Expand a macro pattern containing tokens like:
CH1##_##address##_OFFSET
into the final register string.
kwargs maps token names → values, e.g. address="CFG".
"""
s = pattern
# Replace tokens inside patterns like address##_XYZ
for key, value in kwargs.items():
s = s.replace(key, value)
# Resolve concatenation '##'
s = s.replace("##", "")
# Clean up double underscores
while "__" in s:
s = s.replace("__", "_")
return s
# =====================================================================
# C MACRO PARSER
# =====================================================================
def remove_cpp_comments(text):
"""
Remove /* block comments */ and // line comments.
"""
# Remove multiline comments
text = re.sub(r"/\*.*?\*/", "", text, flags=re.DOTALL)
# Removedefines
text = re.sub(r"#define.*", "", text)
# Remove single-line comments
text = re.sub(r"//.*", "", text)
return text
def parse_c_macros(filename):
registers = DynamicObject()
# Macro → register expansion patterns
macro_definitions = {
# 3-argument write (slow/fast)
"SLOW_WRITE_FIELD": (
"CH1_##address##",
"CH1_##address##_##field##",
),
"FAST_WRITE_FIELD": (
"CH0_##address##",
"CH0_##address##_##field##",
),
# Read field, 2 arguments
"SLOW_READ_FIELD": (
"CH1_##address##",
"CH1_##address##_##field##",
),
"FAST_READ_FIELD": (
"CH0_##address##",
"CH0_##address##_##field##",
),
# Register read/write (1 or 2 arguments)
"SLOW_READ_REGISTER": (
"CH1_##address##",
),
"FAST_READ_REGISTER": (
"CH0_##address##",
),
"SLOW_WRITE_REGISTER": (
"CH1_##address##",
),
"FAST_WRITE_REGISTER": (
"CH0_##address##",
),
"FAST_WRITE_INHIBIT": (
"CH0##_##address1##_CH0_##address2##",
),
"SLOW_WRITE_INHIBIT": (
"CH1##_##address1##_CH0_##address2##",
)
}
# Generic regex for ALL macro calls (1–4 args)
call_regex = re.compile(
r"([A-Z_]+)\s*\(\s*([A-Za-z0-9_]+)" # FUN and arg1: address1
r"(?:\s*,\s*([A-Za-z0-9_]+))?" # arg2: field, address2
r"(?:\s*,\s*([A-Za-z0-9_+\-*/() ]+))?" # arg3: field, data
r"(?:\s*,\s*([A-Za-z0-9_+\-*/() ]+))?" # arg4: data (expression allowed)
r"\s*\)"
)
with open(filename, "r") as f:
text = f.read()
text = remove_cpp_comments(text)
for match in call_regex.finditer(text):
macro, a1, a2, a3, a4 = match.groups()
text = text.replace(match.group(0), "") # remove after processing
if macro not in macro_definitions or "READ" in macro:
continue
patterns = macro_definitions[macro]
# Build the macro variable map
kwargs = {}
if a4 == None:
if a1: kwargs["address"] = a1
if a2: kwargs["field"] = a2
if a3: kwargs["data"] = a3
else:
if a1: kwargs["address1"] = a1
if a2: kwargs["address2"] = a2
if a3: kwargs["field"] = a3
if a4: kwargs["data"] = a4
# Expand patterns into real register names
expanded = [expand_macro_pattern(p, **kwargs) for p in patterns]
# Store results
if a2 and a3: # WRITE_FIELD
registers[expanded[0].upper()] = {a2.upper(): a3}
else: # REGISTER read/write
registers[expanded[0].upper()] = a3
return registers
def upper_keys_recursive(d):
new_dict = {}
for k, v in d.items():
key_up = str(k).upper()
if isinstance(v, dict):
new_dict[key_up] = upper_keys_recursive(v)
else:
new_dict[key_up] = v
return new_dict
def diff_dicts(d1, d2, path="",dictnames = ["M","CPP"]):
"""
Recursively compare two dictionaries and print differences.
Shows:
- Keys only in d1
- Keys only in d2
- Keys in both where values differ
"""
# Keys present in both dictionaries
common_keys = d1.keys() & d2.keys()
# Keys only in first dict
only_d1 = d1.keys() - d2.keys()
for key in sorted(only_d1):
print(f"{path}{key}: only in {dictnames[0]}")
# Keys only in second dict
only_d2 = d2.keys() - d1.keys()
for key in sorted(only_d2):
print(f"{path}{key}: only in {dictnames[1]}")
# Compare common keys
for key in sorted(common_keys):
v1 = d1[key]
v2 = d2[key]
new_path = f"{path}{key}."
# If both values are dictionaries → recurse
if isinstance(v1, dict) and isinstance(v2, dict):
diff_dicts(v1, v2, new_path)
continue
# If values differ → print
if v1 != v2:
print(f"{path}{key}:")
print(f" {dictnames[0]} = {v1}")
print(f" {dictnames[1]} = {v2}")
# =====================================================================
# Example usage
# =====================================================================
# Example usage:
if __name__ == "__main__":
obj = parse_oFRDReg_from_mfile("startTau_generic_Generated.m")
pprint.pprint(obj)
regs = parse_c_macros("/home/lucas/git/mems_stable/trixel3_software/tic/source/trixel3_tic_mems_model_lbd001rrxab11.cpp")
pprint.pprint(regs)
diff_dicts(regs,obj)
print("Fin")
+172
View File
@@ -0,0 +1,172 @@
import pandas as pd
import pprint
from datetime import datetime
import json
# Create a PrettyPrinter with custom settings
pp = pprint.PrettyPrinter(
indent=2,
width=100000, # large line width to avoid wrapping
compact=False, # don't compress structures
depth=None, # don't limit nesting depth
sort_dicts=False
)
# load data
absences = pd.read_excel("Activity Timeoff 2025_01_01 - 2026_02_28.xlsx")
# Load Excel (or CSV) file
# For Excel: timesheet = pd.read_excel("timesheet.xlsx", engine="openpyxl")
timesheets = pd.read_excel("[ALL] Template_Time_Sheets_FFG - Unified.xlsx", sheet_name=None)
df_timesheet = timesheets["2025"]
## Sort RATES
df_rates = timesheets["Stundensätze"]
# Remove all non-numeric characters (keep digits and dot)
hourlyRateKey = "Hourly Rate for Application €/h"
df_rates = df_rates.rename(columns={hourlyRateKey: 'rate'})
hourlyRateKey = 'rate'
df_rates[hourlyRateKey] = df_rates[hourlyRateKey].astype(str).str.replace(r'[^0-9.]', '', regex=True)
# Ensure the Hourly Rate column is numeric
df_rates[hourlyRateKey] = pd.to_numeric(df_rates[hourlyRateKey], errors='coerce')
## FORMAT timesheet data frame
# Fill missing Activity for earlier rows if necessary
df_timesheet['Activity'] = df_timesheet['Activity'].ffill() # forward-fill the activity for blank cells
# Convert 'Date' to datetime
df_timesheet['Date'] = pd.to_datetime(df_timesheet['Date'], errors='coerce')
# Forward-fill missing dates and activities
df_timesheet['Date'] = df_timesheet['Date'].ffill()
df_timesheet['Activity'] = df_timesheet['Activity'].ffill()
# Filter out rows where 'Person' is missing
df_timesheet_filtered = df_timesheet.dropna(subset=['Person']).copy()
# #FILETER ABSECES
absences['Start date'] = pd.to_datetime(absences['Start date'], errors='coerce')
absences['End date'] = pd.to_datetime(absences['End date'], errors='coerce')
df_absences_filtered = absences
df_absences_by_year = {}
for year in df_absences_filtered['Start date'].dt.year.unique():
# Filter for the year
df_year = df_absences_filtered[df_absences_filtered['Start date'].dt.year == year].copy()
# Combine first and last name into a new column 'Person'
df_year['Person'] = df_year['Last name'].astype(str) + ", " + df_year['First name'].astype(str)
# Select and reorder columns
df_year = df_year[['Person', 'Start date', 'End date']]
# Reset index
df_year = df_year.reset_index(drop=True)
# Store in dictionary
df_absences_by_year[year] = df_year
for year, df in df_absences_by_year.items():
# Function to find matching full name(s) for a person
def get_short_name(person):
# Remove spaces from person
person_clean = str(person).replace(" ", "")
# Remove spaces from df_rates['Name'] and check for match
matches = df_rates[df_rates['Name'].str.replace(" ", "", regex=False)
.str.contains(person_clean, case=False, na=False)]
if not matches.empty:
# Return only the first match
return str(matches['Short'].iloc[0])
return "" # no match found
# Apply the function row-wise to create a new column
df['Short'] = df['Person'].apply(get_short_name)
# Keep only the row with the highest Hourly Rate per Name
df_rates = df_rates.loc[df_rates.groupby('Short')[hourlyRateKey].idxmax()].reset_index(drop=True)
# Sort By Year
# Create dictionary of DataFrames for each year
df_timesheet_by_year = {}
for year in df_timesheet_filtered['Date'].dt.year.unique():
# Filter for the year
df_year = df_timesheet_filtered[df_timesheet_filtered['Date'].dt.year == year].copy()
# Convert 'Workpackage' to integer (nullable Int64 to handle NaN safely)
df_year['Workpackage'] = pd.to_numeric(df_year['Workpackage'], errors='coerce').astype('Int64')
# Select and reorder columns
df_year = df_year[['Person', 'Date', 'Workpackage', 'Time (in hours)', 'Activity']]
# Reset index
df_year = df_year.reset_index(drop=True)
# Store in dictionary
df_timesheet_by_year[year] = df_year
for year, df in df_timesheet_by_year.items():
# Function to find matching full name(s) for a person
def get_full_name(person):
matches = df_rates[df_rates['Short'].str.contains(str(person), case=False, na=False)]
if not matches.empty:
return str(matches['Name'].iloc[0])
return "" # no match found
# Apply the function row-wise to create a new column
df['FullName'] = df['Person'].apply(get_full_name)
# Build nested dictionary
data = {}
for year in df_timesheet_by_year.keys():
for _, row in df_timesheet_by_year[year].iterrows():
person = row['Person']
date = row['Date']
date_str = date.strftime("%Y-%m-%d")
# Skip rows without a person
if pd.isna(person):
continue
data.setdefault(year, {}).setdefault(person, {}).setdefault("absences", [])
data.setdefault(year, {}).setdefault(person, {}).setdefault("workingdays", {})
data[year][person]["workingdays"][date_str] = {
"workpackage": row['Workpackage'],
"time": row['Time (in hours)'],
"activity": row['Activity']
}
# Group by Person and Workpackage and sum hours
summary = df_timesheet_by_year[year].groupby(['FullName', 'Workpackage'])['Time (in hours)'].sum().reset_index()
# Merge hourly rate into summary using the full name
summary = summary.merge(
df_rates[['Name', hourlyRateKey]],
left_on='FullName',
right_on='Name',
how='left'
)
# Compute costs
summary['costs'] = summary['Time (in hours)'] * summary[hourlyRateKey]
# Show all columns and rows
print(summary.to_string(index=False)) # index=False hides row numbers
for year in df_absences_by_year.keys():
for _, row in df_absences_by_year[year].iterrows():
person = row['Short']
start_date = row['Start date']
end_date = row['End date']
# Ensure nested structure exists
data.setdefault(year, {}).setdefault(person, {}).setdefault("absences", [])
data.setdefault(year, {}).setdefault(person, {}).setdefault("workingdays", {})
data[year][person]["absences"].append({"start": start_date, "end": end_date})
for year in data.keys():
for person in data[year].keys():
for absence in data[year][person]["absences"]:
# Generate all dates between start and end
all_dates = pd.date_range(start=absence["start"], end=absence["end"], freq='B') # 'B' = business days (Mon-Fri)
# Create a dict with dates as keys and empty dict as value
workdays_dict = set(data[year][person]['workingdays'].keys())
absence_dict = {date.strftime("%Y-%m-%d"): {} for date in all_dates}
# Get sets of dates
absence_dates = set(absence_dict)
working_dates = set(data[year][person]['workingdays'].keys())
# Find intersection
overlap = absence_dates & working_dates
sorted_overlap = sorted(overlap, key=lambda x: datetime.strptime(x, "%Y-%m-%d"))
if overlap and absence["start"] != absence["end"]:
print(f"Dates overlapping for {person}: {overlap} - Vac: {absence["start"].strftime("%Y-%m-%d")} - {absence["end"].strftime("%Y-%m-%d")}")
elif overlap:
print(f"Dates overlapping for {person}: {overlap} - Vac: {absence["start"].strftime("%Y-%m-%d")}")
print("fin")
+1
View File
@@ -0,0 +1 @@
for file in *; do [ -f "$file" ] || continue; dir="${file%.*}"; mkdir -p "$dir"; mv -- "$file" "$dir/"; done
+264
View File
@@ -0,0 +1,264 @@
import pandas as pd
import matplotlib.pyplot as plt
import os
import socket
def interpolate_daily(df):
df = df.copy()
df["Datum"] = pd.to_datetime(df["Datum"], errors="coerce")
df = df.sort_values("Datum").set_index("Datum")
daily_index = pd.date_range(df.index.min(), df.index.max(), freq="D")
return (
df.reindex(daily_index)
.interpolate(method="time")
.reset_index()
.rename(columns={"index": "Datum"})
)
def plot_percentiles(ax, x, data_dict, p_keys, colors=None, linewidths=None, labels=None,
linestyle=None, fill=True, fill_color="lightcoral", fill_alpha=0.25):
"""
Plot multiple percentile curves from a dictionary like who_head_daily.
Parameters
----------
ax : matplotlib axis
x : array-like (x values)
data_dict : dict-like, e.g. who_head_daily
p_keys : list of keys, e.g. ["P3", "P50", "P97"]
colors : list of colors (optional)
linewidths : list of linewidths (optional)
fill : whether to fill between min and max percentile
:param labels:
"""
n = len(x)
if colors is None:
colors = [None] * len(p_keys)
if linewidths is None:
linewidths = [1.5] * len(p_keys)
# Plot lines
for i, key in enumerate(p_keys):
ax.plot(
x,
data_dict[key][:n],
color=colors[i],
linewidth=linewidths[i],
label=labels[i],
linestyle=linestyle[i]
)
# Fill between min and max percentile
if fill and len(p_keys) >= 2:
lower = data_dict[p_keys[0]][:n]
upper = data_dict[p_keys[-1]][:n]
ax.fill_between(
x,
lower,
upper,
color=fill_color,
alpha=fill_alpha
)
return ax
hostname = socket.gethostname()
if hostname == "quiethost":
# Build output path from ods_path
ods_path = "/data/Nextcloud/Documents/Dokumente/Shared/Alina/Wachstum/WachstumsDatenWHO.ods"
csv_path = "/data/Nextcloud/Documents/Dokumente/Shared/Alina/Wachstum/WachstumAlina.csv"
elif hostname == "serverhost":
print("Serverhost Mode")
import subprocess
subprocess.run(["bash", "/home/lucas/scripts/serverhost/syncNC.sh", "-al"])
ods_path = "/home/lucas/Documents/Dokumente/Shared/Alina/Wachstum/WachstumsDatenWHO.ods"
csv_path = "/home/lucas/Documents/Dokumente/Shared/Alina/Wachstum/WachstumAlina.csv"
output_dir = os.path.dirname(ods_path)
output_path = os.path.join(output_dir, "WachstumAlina.png")
# Load specific sheets into data structures (DataFrames)
alina_df = pd.read_csv(csv_path)
who_weight_df = pd.read_excel(ods_path,sheet_name="WHO Gewicht",engine="odf")
who_height_df = pd.read_excel(ods_path,sheet_name="WHO Größe",engine="odf")
who_head_df = pd.read_excel(ods_path,sheet_name="WHO Kopfumfang",engine="odf")
def calculateDateFromBrithday(df, birthday ):
new_df = pd.DataFrame(columns=["Datum"])
for idx, (val1, val2) in enumerate(zip(df["Month"], df["Week"])):
if not pd.isna(val1):
new_df.loc[idx, "Datum"] = (birthday + pd.DateOffset(months=val1))
if not pd.isna(val2):
new_df.loc[idx, "Datum"] = (birthday + pd.DateOffset(weeks=val2))
return pd.to_datetime(new_df["Datum"], format="%d.%m.%Y", errors="coerce")
alina_df["Datum"] = pd.to_datetime(alina_df["Datum"],format="%d.%m.%Y",errors="coerce")
# Ensure Datum is datetime (safe to run even if already converted)
who_weight_df["Datum"] = calculateDateFromBrithday(who_weight_df,alina_df["Datum"][0] )
who_height_df["Datum"] = calculateDateFromBrithday(who_height_df,alina_df["Datum"][0] )
who_head_df["Datum"] = calculateDateFromBrithday(who_head_df,alina_df["Datum"][0] )
who_weight_daily = interpolate_daily(who_weight_df)
who_height_daily = interpolate_daily(who_height_df)
who_head_daily = interpolate_daily(who_head_df)
print(alina_df["Datum"])
# Plot
last_alina_date = alina_df["Datum"].max() + pd.DateOffset(months=2)
x = who_weight_daily["Datum"][who_weight_daily["Datum"] <= last_alina_date]
fig, axes = plt.subplots(
nrows=3,
ncols=1,
figsize=(12, 10),
sharex=True
)
percentile_list = ['P1', 'P3', 'P10', 'P25',
'P50', 'P75', 'P90', 'P97', 'P99']
colors_list = ["lightcoral" if p != "P50" else "darkred" for p in percentile_list]
linewidths_list = [1.5 if p != "P50" else 2.5 for p in percentile_list]
label_list = [p if p == "P50" or p == "P3" or p == "P97" else "" for p in percentile_list]
linestyle_list = ["--" if p == "P3" or p == "P97" else "-" for p in percentile_list]
# ---------- 1. WEIGHT ----------
ax = axes[0]
plot_percentiles(
ax,
x,
who_weight_daily,
percentile_list,
colors=colors_list,
linewidths=linewidths_list,
labels=label_list,
linestyle=linestyle_list
)
ax.plot(alina_df["Datum"], alina_df["Gewicht"].interpolate(limit_area="inside"),
color="green", linewidth=1.5, marker="o", label="Alina")
last_idx = alina_df["Gewicht"].last_valid_index()
who_row = who_weight_daily.loc[who_weight_daily["Datum"] == alina_df["Datum"][last_idx]].iloc[0]
perzentil = (alina_df["Gewicht"][last_idx]-who_row["P50"])/((who_row["P97"]-who_row["P50"])/47)+50
ax.text(alina_df["Datum"].iloc[-1]+pd.DateOffset(days=1), alina_df["Gewicht"].iloc[-1]+0.5,f"{perzentil:.2f} %",
fontsize=10,
ha="left",
va="bottom",
color="green")
ax.set_ylabel("Gewicht [kg]")
ax.set_title("Wachstum")
# Enable minor ticks
ax.minorticks_on()
# Configure major grid (e.g., solid, darker)
ax.grid(which='major', color='black', linestyle='-', linewidth=0.8)
# Configure minor grid (e.g., dashed, lighter, thinner)
ax.grid(which='minor', color='gray', linestyle='--', linewidth=0.4, alpha=0.5)
ax.legend()
# ---------- 2. HEIGHT ----------
ax = axes[1]
plot_percentiles(
ax,
x,
who_height_daily,
percentile_list,
colors=colors_list,
linewidths=linewidths_list,
labels=label_list,
linestyle=linestyle_list
)
ax.plot(alina_df["Datum"], alina_df["Größe"].interpolate(limit_area="inside"),color="green", linewidth=1.5, marker="o")
last_idx = alina_df["Größe"].last_valid_index()
who_row = who_height_daily.loc[who_height_daily["Datum"] == alina_df["Datum"][last_idx]].iloc[0]
perzentil = (alina_df["Größe"][last_idx]-who_row["P50"])/((who_row["P97"]-who_row["P50"])/47)+50
ax.text(alina_df["Datum"].iloc[-1]+pd.DateOffset(days=1), alina_df["Größe"].iloc[-1]+0.5,f"{perzentil:.2f} %",
fontsize=10,
ha="left",
va="bottom",
color="green")
ax.set_ylabel("Größe [cm]")
# Enable minor ticks
ax.minorticks_on()
# Configure major grid (e.g., solid, darker)
ax.grid(which='major', color='black', linestyle='-', linewidth=0.8)
# Configure minor grid (e.g., dashed, lighter, thinner)
ax.grid(which='minor', color='gray', linestyle='--', linewidth=0.4, alpha=0.5)
# ---------- 3. HEAD CIRCUMFERENCE ----------
ax = axes[2]
plot_percentiles(
ax,
x,
who_head_daily,
percentile_list,
colors=colors_list,
linewidths=linewidths_list,
labels=label_list,
linestyle=linestyle_list
)
ax.plot(alina_df["Datum"], alina_df["Kopfumfang"].interpolate(limit_area="inside"),color="green", linewidth=1.5, marker="o")
last_idx = alina_df["Kopfumfang"].last_valid_index()
who_row = who_head_daily.loc[who_head_daily["Datum"] == alina_df["Datum"][last_idx]].iloc[0]
perzentil = (alina_df["Kopfumfang"][last_idx]-who_row["P50"])/((who_row["P97"]-who_row["P50"])/47)+50
ax.text(alina_df["Datum"].iloc[-1]+pd.DateOffset(days=1), alina_df["Kopfumfang"].iloc[-1]+0.5,f"{perzentil:.2f} %",
fontsize=10,
ha="left",
va="bottom",
color="green")
ax.set_ylabel("Kopfumfang [cm]")
# Enable minor ticks
ax.minorticks_on()
# Configure major grid (e.g., solid, darker)
ax.grid(which='major', color='black', linestyle='-', linewidth=0.8)
# Configure minor grid (e.g., dashed, lighter, thinner)
ax.grid(which='minor', color='gray', linestyle='--', linewidth=0.4, alpha=0.5)
# ---------- X‑AXIS ----------
axes[-1].set_xlabel("Datum")
N = 7 # label every Nth tick
axes[-1].set_xticks(x[::N])
axes[-1].set_xticklabels(
x.iloc[::N].dt.strftime("%d.%m.%Y"),
rotation=45,
ha="right"
)
plt.tight_layout()
plt.savefig(output_path, dpi=150)
plt.close()
if hostname == "serverhost":
print("Serverhost Mode")
import subprocess
subprocess.run(["bash", "/home/lucas/scripts/serverhost/syncNC.sh", "-al"])
print("Fin")
+461
View File
@@ -0,0 +1,461 @@
function startTau_generic_Generated.m(oFRDReg, options)
arguments
oFRDReg
options.sTimeOut (1,1) double = 10.0
end
% Generated from sequence: LBDB11_Start_Tau_generic_Copy
% Sequence ID: 1722837829
% ------ reset DUT and put into IDLE ------
% Unsupported command type: DisplayController_Command_SetResetNPinState
% Unsupported command type: DisplayController_Command_SetClkMirror
% valid for 10MHz input-clock
oFRDReg.CLK_PLL.CLK_PLL = 3857; % 0x0F11
% Wait for driver entering IDLE...
sTimeOut = options.sTimeOut;
sStart = tic;
while(oFRDReg.OP_STATUS.opmode ~= 1)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for OP_STATUS.opmode to equal 1');
end
end
% ------ MSI config ------
oFRDReg.MSI.vcm_sel = 2;
oFRDReg.MSI.cmp_clk_provision = 1;
oFRDReg.MSI.ib_sel = 4;
oFRDReg.MSI.ib_source_sel = 1;
% ------ Slow/Fast MSI config ------
oFRDReg.CH1_MSI1.peak_det_source = 0;
oFRDReg.CH1_MSI1.peak_det_pol = 0;
oFRDReg.CH1_MSI1.tia_res_sel = 15;
oFRDReg.CH1_MSI1.tia_cap_sel = 15;
oFRDReg.CH1_MSI1.sah_tc = 2;
oFRDReg.CH1_MSI1.swap_polarity = 0;
oFRDReg.CH1_MSI2.sah_refdac_sel = 1;
oFRDReg.CH1_MSI2.sah_en = 0;
oFRDReg.CH1_MSI2.refdac_en = 1;
oFRDReg.CH1_MSI2.refdac_sel = 4;
oFRDReg.CH1_MSI2.ref_div_trim = 5;
oFRDReg.CH0_MSI1.peak_det_source = 0;
oFRDReg.CH0_MSI1.peak_det_pol = 0;
oFRDReg.CH0_MSI1.tia_res_sel = 15;
oFRDReg.CH0_MSI1.tia_cap_sel = 15;
oFRDReg.CH0_MSI1.sah_tc = 2;
oFRDReg.CH0_MSI1.swap_polarity = 0;
oFRDReg.CH0_MSI2.sah_refdac_sel = 1;
oFRDReg.CH0_MSI2.sah_en = 0;
oFRDReg.CH0_MSI2.refdac_en = 1;
oFRDReg.CH0_MSI2.refdac_sel = 0;
oFRDReg.CH0_MSI2.ref_div_trim = 0;
% ------ Slow/Fast subtiming config ------
oFRDReg.CH1_ST_MODULO.cnt_value = 7000;
oFRDReg.CH1_ST_POS.cnt_value = 0;
oFRDReg.CH1_ST_MOV.cnt_value = 3500;
oFRDReg.CH1_ST_DRIVE_ON.cnt_value = 3500;
oFRDReg.CH1_ST_DRIVE_OFF_MIN.cnt_value = 262;
oFRDReg.CH1_ST_DRIVE_OFF.cnt_value = 263;
oFRDReg.CH1_ST_DRIVE_OFF_MAX.cnt_value = 2188;
oFRDReg.CH0_ST_MODULO.cnt_value = 1700;
oFRDReg.CH0_ST_POS.cnt_value = 0;
oFRDReg.CH0_ST_MOV.cnt_value = 850;
oFRDReg.CH0_ST_DRIVE_ON.cnt_value = 850;
oFRDReg.CH0_ST_DRIVE_OFF_MIN.cnt_value = 54;
oFRDReg.CH0_ST_DRIVE_OFF.cnt_value = 55;
oFRDReg.CH0_ST_DRIVE_OFF_MAX.cnt_value = 805;
% ------ Slow/Fast ADC config ------
oFRDReg.CH1_ST_ADC_VTEMP.cnt_value = 1;
oFRDReg.CH1_ST_ADC_MIRRCURR.cnt_value = 88;
% currently disabled by setting to MODULO+1
oFRDReg.CH1_ST_ADC_HVD.cnt_value = 7001;
oFRDReg.CH1_ADC_SCHED1.angle_amplitude = 2;
oFRDReg.CH1_ADC_SCHED2.hv = 200;
oFRDReg.CH1_ADC_SCHED3.temperature = 100;
oFRDReg.CH0_ST_ADC_VTEMP.cnt_value = 1;
oFRDReg.CH0_ST_ADC_MIRRCURR.cnt_value = 45;
% currently disabled by setting to MODULO+1
oFRDReg.CH0_ST_ADC_HVD.cnt_value = 1701;
oFRDReg.CH0_ADC_SCHED1.angle_amplitude = 2;
oFRDReg.CH0_ADC_SCHED2.hv = 200;
oFRDReg.CH0_ADC_SCHED3.temperature = 100;
% ------ Slow/Fast Amp.-Sense + control config ------
% slow - amplitude detection
oFRDReg.CH1_AMPL_SENSE1.method = 0;
oFRDReg.CH1_AMPL_SENSE1.diff_comp_pol = 0;
oFRDReg.CH1_AMPL_SENSE1.asym_comp_en = 1;
oFRDReg.CH1_AMPL_SENSE1.alpha_filter = 5;
oFRDReg.CH1_AMPL_SENSE1.filter_en = 1;
oFRDReg.CH1_MSI2.sah_refdac_sel = 1;
oFRDReg.CH1_MSI2.sah_en = 0;
oFRDReg.CH1_MSI2.refdac_en = 1;
oFRDReg.CH1_MSI2.refdac_sel = 0;
oFRDReg.CH1_MSI2.ref_div_trim = 0;
oFRDReg.CH1_ST_AMPL_DET_START.cnt_value = 6193;
oFRDReg.CH1_ST_AMPL_DET_STOP.cnt_value = 6543;
oFRDReg.CH1_ST_AMPL_CTRL_SETPOINT.cnt_value = 6368;
oFRDReg.CH1_ST_CMP_DIFF_EN_START.cnt_value = 3500;
oFRDReg.CH1_ST_CMP_DIFF_EN_STOP.cnt_value = 175;
% slow - amplitude control
oFRDReg.CH1_AMPL_CTRL1.means_of_control = 0;
oFRDReg.CH1_AMPL_CTRL1.i_gain = 2;
oFRDReg.CH1_AMPL_CTRL2.p_gain = 20;
oFRDReg.CH1_AMPL_CTRL1.source_pid = 1;
oFRDReg.CH1_ST_CONTROL_ACTION.cnt_value = 262;
oFRDReg.CH1_ST_CONTROL_ACTION.en = 1;
oFRDReg.CH1_AMPL_CTRL1.phase_comp_en = 1;
oFRDReg.CH1_AMPL_CTRL1.phase_comp_op = 1;
% slow - enable amplitude sensing
oFRDReg.CH1_CFG.ampl_sense_en = 1;
% fast - peak sensing
% for anti phase drive the tracking period needs to be very narrow otherwise inhibiting happens
oFRDReg.CH0_ST_MIRRCURR_PEAK_START.cnt_value = 1029;
oFRDReg.CH0_ST_MIRRCURR_PEAK_STOP.cnt_value = 54;
oFRDReg.CH0_ST_MIRRCURR_PEAK_RESET.cnt_value = 828;
oFRDReg.CH0_ST_MIRRCURR_PEAK_URESET.cnt_value = 939;
% fast - amplitude detection
oFRDReg.CH0_AMPL_SENSE1.method = 0;
oFRDReg.CH0_AMPL_SENSE1.diff_comp_pol = 0;
oFRDReg.CH0_AMPL_SENSE1.asym_comp_en = 1;
oFRDReg.CH0_AMPL_SENSE1.alpha_filter = 7;
oFRDReg.CH0_AMPL_SENSE1.filter_en = 0;
oFRDReg.CH0_MSI2.sah_refdac_sel = 1;
oFRDReg.CH0_MSI2.sah_en = 0;
oFRDReg.CH0_MSI2.refdac_en = 1;
oFRDReg.CH0_MSI2.refdac_sel = 0;
oFRDReg.CH0_MSI2.ref_div_trim = 0;
oFRDReg.CH0_ST_AMPL_DET_START.cnt_value = 1188;
oFRDReg.CH0_ST_AMPL_DET_STOP.cnt_value = 1366;
oFRDReg.CH0_ST_AMPL_CTRL_SETPOINT.cnt_value = 1277;
oFRDReg.CH0_ST_CMP_DIFF_EN_START.cnt_value = 850;
oFRDReg.CH0_ST_CMP_DIFF_EN_STOP.cnt_value = 89;
oFRDReg.CH0_ST_AMPL_SH_START.cnt_value = 1342;
oFRDReg.CH0_ST_AMPL_SH_STOP.cnt_value = 1432;
% fast - amplitude control
oFRDReg.CH0_AMPL_CTRL1.means_of_control = 0;
oFRDReg.CH0_AMPL_CTRL1.i_gain = 100;
oFRDReg.CH0_AMPL_CTRL2.p_gain = 100;
oFRDReg.CH0_AMPL_CTRL1.source_pid = 1;
oFRDReg.CH0_ST_CONTROL_ACTION.cnt_value = 54;
oFRDReg.CH0_ST_CONTROL_ACTION.en = 1;
oFRDReg.CH0_AMPL_CTRL1.phase_comp_en = 1;
oFRDReg.CH0_AMPL_CTRL1.phase_comp_op = 1;
% fast - enable amplitude sensing
oFRDReg.CH0_CFG.ampl_sense_en = 1;
% ------ Slow/Fast Phase-control config ------
% slow
oFRDReg.CH1_ST_PHASEDET_START.cnt_value = 6825;
oFRDReg.CH1_ST_PHASEDET_STOP.cnt_value = 175;
oFRDReg.CH1_ST_ZCREF_RESET.cnt_value = 3500;
oFRDReg.CH1_ST_CMP_SUM_EN_START.cnt_value = 6781;
oFRDReg.CH1_ST_CMP_SUM_EN_STOP.cnt_value = 175;
oFRDReg.CH1_ST_CONTROL_ACTION.cnt_value = 176;
oFRDReg.CH1_ST_CONTROL_ACTION.en = 1;
oFRDReg.CH1_PHASE_CTRL1.i_gain = 255;
oFRDReg.CH1_PHASE_CTRL2.p_gain = 600;
oFRDReg.CH1_PHASE_CTRL1.asym_comp_en = 1;
oFRDReg.CH1_PHASE_CTRL1.means_of_control = 0;
oFRDReg.CH1_PHASE_CTRL3.delay = 3;
% fast
oFRDReg.CH0_ST_PHASEDET_START.cnt_value = 1655;
oFRDReg.CH0_ST_PHASEDET_STOP.cnt_value = 45;
oFRDReg.CH0_ST_ZCREF_RESET.cnt_value = 850;
oFRDReg.CH0_ST_CMP_SUM_EN_START.cnt_value = 1610;
oFRDReg.CH0_ST_CMP_SUM_EN_STOP.cnt_value = 45;
oFRDReg.CH0_ST_CONTROL_ACTION.cnt_value = 49;
oFRDReg.CH0_ST_CONTROL_ACTION.en = 1;
oFRDReg.CH0_PHASE_CTRL1.i_gain = 255;
oFRDReg.CH0_PHASE_CTRL2.p_gain = 600;
oFRDReg.CH0_PHASE_CTRL1.asym_comp_en = 1;
oFRDReg.CH0_PHASE_CTRL1.means_of_control = 0;
oFRDReg.CH0_PHASE_CTRL3.delay = 1;
% ------ Slow/Fast HV config ------
% approximately HV= 0,72 * lead -> 72V
oFRDReg.CH1_HVD1.lead = 100;
oFRDReg.CH1_HVD3.lag = 100;
oFRDReg.CH1_HVD2.disch_trim = 7;
oFRDReg.CH1_HVD1.en = 1;
oFRDReg.CH1_HVD1.peak_det_res_zcs = 10;
oFRDReg.CH1_HVD2.pol = 1;
oFRDReg.CH1_HVD2.en_vmax_hv_adc = 1;
oFRDReg.CH1_ST_HVD_PEAK_START.cnt_value = 0;
oFRDReg.CH1_ST_HVD_PEAK_STOP.cnt_value = 1750;
oFRDReg.CH1_ST_HVD_PEAK_RESET.cnt_value = 3500;
oFRDReg.CH1_ST_HVD_PEAK_URESET.cnt_value = 7000;
% approximately HV= 0,72 * lead -> 72V
oFRDReg.CH0_HVD1.lead = 100;
oFRDReg.CH0_HVD3.lag = 100;
oFRDReg.CH0_HVD2.disch_trim = 7;
oFRDReg.CH0_HVD1.en = 1;
oFRDReg.CH0_HVD1.peak_det_res_zcs = 10;
oFRDReg.CH0_HVD2.pol = 1;
oFRDReg.CH0_HVD2.en_vmax_hv_adc = 1;
oFRDReg.CH0_ST_HVD_PEAK_START.cnt_value = 0;
oFRDReg.CH0_ST_HVD_PEAK_STOP.cnt_value = 716;
oFRDReg.CH0_ST_HVD_PEAK_RESET.cnt_value = 850;
oFRDReg.CH0_ST_HVD_PEAK_URESET.cnt_value = 1611;
% ------ Fref Master-Slave config ------
% Ratio: a=718, b=179, a/b=4.0112, k=2, LJRate=39.2, Tau_generic on B11
oFRDReg.FREF_MOD1_INT.mod1_int_part = 13645;
oFRDReg.FREF_MOD1_FRACT1.mod1_fract_part_msb = 732;
oFRDReg.FREF_MOD1_FRACT2.mod1_fract_part_lsb = 125;
oFRDReg.CH1_CFG.pos_source = 1;
oFRDReg.FREF1.fref1 = 1;
oFRDReg.FREF1.mode_axis0 = 3;
oFRDReg.FREF1.mode_axis1 = 0;
oFRDReg.FREF1.period_axis = 1;
oFRDReg.FREF1.periodic_sd_output_en = 1;
oFRDReg.FREF1.synch_at_lj_fs_en = 1;
oFRDReg.FREF_SMART_START.threshold = 10;
oFRDReg.FREF_SMART_START.en = 0;
oFRDReg.CH1_FREQ_CTRL1.means_of_control = 1;
oFRDReg.CH1_FREQ_CTRL1.phase_comp_en = 0;
oFRDReg.FREF_WINDOW.window_width = 20;
oFRDReg.LJ_LOCK1.liss_f_s_duration = 15;
oFRDReg.FREF_DELAY_CH1.delay = 0;
oFRDReg.FREF1.delay_axis1_en = 0;
oFRDReg.FREF_LJ_PERIOD1.lj_period_lsb = 178;
oFRDReg.FREF1.en = 1;
% ------ Slow Freq.-control config ------
oFRDReg.CH1_FREQ_CTRL1.i_gain = 40;
oFRDReg.CH1_FREQ_CTRL2.p_gain = 30;
oFRDReg.CH1_FREQ_CTRL3.d_gain = 0;
oFRDReg.CH1_FREQ_CTRL1.source_pid = 1;
oFRDReg.CH1_FREQ_CTRL3.alpha_f = 5;
oFRDReg.CH1_FREQ_CTRL5.d_limit_f = 3000;
oFRDReg.CH1_FREQ_CTRL6.f_limit_top = 2;
oFRDReg.CH1_FREQ_CTRL7.f_limit_bottom = 0;
% ------ Inhibiting config ------
oFRDReg.HVD_INHIBIT1.inhibit_ctrl_en = 1;
oFRDReg.HVD_INHIBIT2.inhibit_time_switch_hv_off = 123;
oFRDReg.HVD_INHIBIT2.inhibit_time_switch_hv_on = 123;
oFRDReg.CH1_ST_INHIBIT1_HV_CH0_START.cnt_value = 6589;
oFRDReg.CH1_ST_INHIBIT1_HV_CH0_STOP.cnt_value = 175;
oFRDReg.CH1_ST_INHIBIT2_HV_CH0_START.cnt_value = 5957;
oFRDReg.CH1_ST_INHIBIT2_HV_CH0_STOP.cnt_value = 6543;
oFRDReg.CH0_ST_INHIBIT1_HV_CH1_START.cnt_value = 1546;
oFRDReg.CH0_ST_INHIBIT1_HV_CH1_STOP.cnt_value = 45;
oFRDReg.CH0_ST_INHIBIT2_HV_CH1_START.cnt_value = 1079;
oFRDReg.CH0_ST_INHIBIT2_HV_CH1_STOP.cnt_value = 1366;
% Go into operation mode
oFRDReg.OP_CFG.op_en = 1;
% ------ configure anti phase drive ------
% slow
oFRDReg.CH1_SU_SWEEP_START_FREQ1.msb = 64234;
oFRDReg.CH1_SU_SWEEP_START_FREQ2.lsb = 233;
oFRDReg.CH1_SU_SWEEP_STOP_FREQ1.msb = 55058;
oFRDReg.CH1_SU_SWEEP_STOP_FREQ2.lsb = 53;
oFRDReg.CH1_SU_SWEEP_FREQ_STEP1.msb = 2;
oFRDReg.CH1_SU_SWEEP_FREQ_STEP2.lsb = 0;
oFRDReg.CH1_SU.stop_condition_peak_en = 1;
oFRDReg.CH1_SU.stop_condition_zc_en = 0;
oFRDReg.CH1_ST_MIRRCURR_PEAK_START.cnt_value = 3822;
oFRDReg.CH1_ST_MIRRCURR_PEAK_STOP.cnt_value = 3005;
oFRDReg.CH1_ST_MIRRCURR_PEAK_RESET.cnt_value = 3613;
oFRDReg.CH1_ST_MIRRCURR_PEAK_URESET.cnt_value = 3811;
oFRDReg.CH1_ST_ADC_MIRRCURR.cnt_value = 3006;
oFRDReg.CH1_ADC_SCHED1.angle_amplitude = 1;
oFRDReg.CH1_SU_STOP_COND_PEAK.peak_adc_th = 2120;
oFRDReg.CH1_SU_SWEEP.nr_of_zcs_per_f_step = 15;
oFRDReg.CH1_SU.nr_of_good_zc_for_stop = 4;
oFRDReg.CH1_HVD1.drive_method = 1;
% fast
oFRDReg.CH0_SU_SWEEP_START_FREQ1.msb = 64656;
oFRDReg.CH0_SU_SWEEP_START_FREQ2.lsb = 260;
oFRDReg.CH0_SU_SWEEP_STOP_FREQ1.msb = 62426;
oFRDReg.CH0_SU_SWEEP_STOP_FREQ2.lsb = 498;
oFRDReg.CH0_SU_SWEEP_FREQ_STEP1.msb = 0;
oFRDReg.CH0_SU_SWEEP_FREQ_STEP2.lsb = 50;
oFRDReg.CH0_SU.stop_condition_peak_en = 1;
oFRDReg.CH0_SU.stop_condition_zc_en = 0;
oFRDReg.CH0_ST_MIRRCURR_PEAK_START.cnt_value = 1174;
oFRDReg.CH0_ST_MIRRCURR_PEAK_STOP.cnt_value = 352;
oFRDReg.CH0_ST_MIRRCURR_PEAK_RESET.cnt_value = 964;
oFRDReg.CH0_ST_MIRRCURR_PEAK_URESET.cnt_value = 1163;
oFRDReg.CH0_ST_ADC_MIRRCURR.cnt_value = 353;
oFRDReg.CH0_ADC_SCHED1.angle_amplitude = 1;
oFRDReg.CH0_SU_STOP_COND_PEAK.peak_adc_th = 2120;
oFRDReg.CH0_SU_SWEEP.nr_of_zcs_per_f_step = 15;
oFRDReg.CH0_SU.nr_of_good_zc_for_stop = 4;
oFRDReg.CH0_HVD1.drive_method = 1;
% ------ Start slow-axis via peak-detector and wait ------
oFRDReg.CH1_PHASE_CTRL1.bypass = 1;
oFRDReg.CH1_CFG.CH1_CFG = 1354; % 0x054A
oFRDReg.CH1_CFG.CH1_CFG = 1370; % 0x055A
% wait until slow has jumped...
% Wait for slow axis to finish sweep
sTimeOut = options.sTimeOut;
sStart = tic;
while(oFRDReg.CH1_SU.sweep_done ~= 1)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for CH1_SU.sweep_done to equal 1');
end
end
% ------ Start fast-axis via peak-detector and wait ------
oFRDReg.CH0_PHASE_CTRL1.bypass = 1;
oFRDReg.CH0_CFG.CH0_CFG = 330; % 0x014A
oFRDReg.CH0_CFG.CH0_CFG = 346; % 0x015A
% wait until fast has jumped...
% Wait for fast axis to finish sweep
sTimeOut = options.sTimeOut;
sStart = tic;
while(oFRDReg.CH0_SU.sweep_done ~= 1)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for CH0_SU.sweep_done to equal 1');
end
end
% ------ Both axes finished sweep at this point. Change peak-detector-timings
% Change peak-detector-timings of slow-axis.
% =slow_st_phasedet_start
oFRDReg.CH1_ST_MIRRCURR_PEAK_START.cnt_value = 6825;
% =slow_st_inhibit1_hv_fast_stop
oFRDReg.CH1_ST_MIRRCURR_PEAK_STOP.cnt_value = 175;
% =slow_st_inhibit1_hv_fast_stop + 1
oFRDReg.CH1_ST_ADC_MIRRCURR.cnt_value = 176;
% =slow_st_phasedet_start - peak-detector-unreset-time [us]
oFRDReg.CH1_ST_MIRRCURR_PEAK_URESET.cnt_value = 6814;
% =slow_st_mirrcurr_peak_urset - peak-detector-reset-time [us]
oFRDReg.CH1_ST_MIRRCURR_PEAK_RESET.cnt_value = 6616;
oFRDReg.CH1_MSI1.peak_det_source = 1;
% Change peak-detector-timings of fast-axis.
% =fast_st_drive_on + t_in_hv_off
oFRDReg.CH0_ST_MIRRCURR_PEAK_START.cnt_value = 974;
% =fast_st_drive_off_min + t_lead
oFRDReg.CH0_ST_MIRRCURR_PEAK_STOP.cnt_value = 152;
% =fast_st_mirrcurr_peak_stop_value + 1
oFRDReg.CH0_ST_ADC_MIRRCURR.cnt_value = 153;
% =fast_st_mirrcurr_peak_start_value - peak-detector-unreset-time [us]
oFRDReg.CH0_ST_MIRRCURR_PEAK_URESET.cnt_value = 963;
% =fast_st_mirrcurr_peak_ureset_value - peak-detector-reset-time [us]
oFRDReg.CH0_ST_MIRRCURR_PEAK_RESET.cnt_value = 764;
oFRDReg.CH0_MSI1.peak_det_source = 1;
% ------ Now switch to parametric-drive (if not done befeore), then set first fast-aixs to Amp-Ctrl-mode, then slow.
oFRDReg.CH0_ST_INHIBIT1_HV_CH1_START.en = 0;
oFRDReg.CH0_ST_INHIBIT2_HV_CH1_START.en = 0;
% switch to parametric drive
oFRDReg.CH0_HVD1.drive_method = 0;
oFRDReg.CH0_PHASE_CTRL1.bypass = 0;
oFRDReg.CH0_CFG.startup_en = 0;
% enable amplitude control of the fast axis
oFRDReg.CH0_CFG.ampl_ctrl_en = 1;
oFRDReg.CH0_CFG.sfr_drive_off_en = 0;
oFRDReg.CH1_ST_INHIBIT1_HV_CH0_START.en = 1;
oFRDReg.CH1_ST_INHIBIT2_HV_CH0_START.en = 1;
% switch to parametric drive
oFRDReg.CH1_HVD1.drive_method = 0;
oFRDReg.CH1_PHASE_CTRL1.bypass = 0;
oFRDReg.CH1_CFG.startup_en = 0;
% enable amplitude control of the slow axis
oFRDReg.CH1_CFG.ampl_ctrl_en = 1;
oFRDReg.CH1_CFG.sfr_drive_off_en = 0;
% Wait until fast-axis is started (phase-error below 25)!
sTimeOut = options.sTimeOut;
sStart = tic;
while(abs(oFRDReg.CH0_STATUS_PHASE_COMP_ERR.value) > 25)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for CH0_STATUS_PHASE_COMP_ERR compensated phase error to be below 25');
end
end
oFRDReg.OPR_OK2.ch0_phase_ctrl_en = 0;
% -------- Reduce TIA gains to avoid signal overdrive
oFRDReg.CH1_MSI1.tia_cap_sel = 5;
oFRDReg.CH1_MSI1.tia_res_sel = 5;
oFRDReg.CH0_MSI1.tia_cap_sel = 5;
oFRDReg.CH0_MSI1.tia_res_sel = 5;
% fast (master) axis is started, from now on it possible to lock to it
oFRDReg.LJ_LOCK1.en = 1;
% ------ Enable frequ.-control ------
% from here FREF has to be set correctly!!
oFRDReg.CH1_CFG.freq_ctrl_en = 1;
% ------ Steer towards the final frequency via frequency control ------
% Wait to reach final frequency...
sTimeOut = options.sTimeOut;
sStart = tic;
while(oFRDReg.CH1_FREQ_CTRL1.f_limit_reached ~= 1)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for CH1_FREQ_CTRL1.f_limit_reached to equal 1');
end
end
% ------ Restart fref with smart start ------
oFRDReg.FREF1.en = 0;
oFRDReg.FREF_SMART_START.en = 1;
oFRDReg.FREF1.en = 1;
% Wait for smart-start to start up...
sTimeOut = options.sTimeOut;
sStart = tic;
while(oFRDReg.FREF_SMART_START.started ~= 1)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for FREF_SMART_START.started to equal 1');
end
end
% ------ Do phase&frequency control for lj synch, then wait for LJ-lock ------
oFRDReg.CH1_PHASE_CTRL1.i_gain = 118;
oFRDReg.CH1_PHASE_CTRL2.p_gain = 395;
oFRDReg.CH1_FREQ_CTRL1.i_gain = 3;
oFRDReg.CH1_FREQ_CTRL2.p_gain = 2;
oFRDReg.CH1_FREQ_CTRL3.d_gain = 8;
oFRDReg.CH1_FREQ_CTRL3.alpha_pf = 13;
oFRDReg.CH1_FREQ_CTRL4.d_limit_pf = 3000;
oFRDReg.CH1_FREQ_CTRL1.source_pid = 0;
% Wait for LJ-lock...
sTimeOut = options.sTimeOut;
sStart = tic;
while(oFRDReg.LJ_LOCK1.lock ~= 1)
if toc(sStart) > sTimeOut
error('ifx:runtime_error', 'Timeout waiting for LJ_LOCK1.lock to equal 1');
end
end
% ------ Set gains for low jitter ------
oFRDReg.CH1_FREQ_CTRL3.d_gain = 1;
oFRDReg.CH1_FREQ_CTRL3.alpha_pf = 5;
oFRDReg.CH0_PHASE_CTRL1.i_gain = 6;
oFRDReg.CH0_PHASE_CTRL2.p_gain = 60;
oFRDReg.CH0_AMPL_CTRL1.i_gain = 1;
oFRDReg.CH0_AMPL_CTRL2.p_gain = 20;
end