mirror of https://github.com/arendst/Tasmota.git
124 lines
4.0 KiB
Python
124 lines
4.0 KiB
Python
|
#!env python3
|
||
|
|
||
|
import json
|
||
|
import sys
|
||
|
import argparse
|
||
|
from modenames import mode_names
|
||
|
|
||
|
parser = argparse.ArgumentParser()
|
||
|
parser.add_argument("--list-modes", help="list the available modes for tis file.", action = "store_true");
|
||
|
parser.add_argument("--temperature-range", help="only export waveforms in the temperature range of min,max °C.");
|
||
|
parser.add_argument("--export-modes", help="comma-separated list of waveform mode IDs to export.");
|
||
|
parser.add_argument("name", help="name of the waveform object.");
|
||
|
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
waveforms = json.load(sys.stdin);
|
||
|
|
||
|
|
||
|
total_size = 0
|
||
|
|
||
|
def phase_to_c(phase):
|
||
|
"""
|
||
|
Convert a 5 bit phase to a 4 bit C LUT.
|
||
|
"""
|
||
|
global total_size
|
||
|
|
||
|
targets = []
|
||
|
for t in range(0, 32, 2):
|
||
|
chunk = 0
|
||
|
line = []
|
||
|
for f in range(0, 32, 2):
|
||
|
fr = phase[t][f]
|
||
|
chunk = (chunk << 2) | fr
|
||
|
if f and f % 8 == 6:
|
||
|
line.append(chunk)
|
||
|
chunk = 0
|
||
|
targets.append(line)
|
||
|
total_size += len(line)
|
||
|
|
||
|
return targets
|
||
|
|
||
|
def list_to_c(l):
|
||
|
if isinstance(l, list):
|
||
|
children = [list_to_c(c) for c in l]
|
||
|
return "{" + ",".join(children) + "}"
|
||
|
elif isinstance(l, int):
|
||
|
return f"0x{l:02x}"
|
||
|
else:
|
||
|
assert(false)
|
||
|
|
||
|
if args.list_modes:
|
||
|
for mode in waveforms["modes"]:
|
||
|
print(f"""{mode["mode"]}: {mode_names[mode["mode"]]}""" )
|
||
|
sys.exit(0)
|
||
|
|
||
|
tmin = -100
|
||
|
tmax = 1000
|
||
|
|
||
|
if args.temperature_range:
|
||
|
tmin, tmax = map(int, args.temperature_range.split(","))
|
||
|
|
||
|
modes = []
|
||
|
|
||
|
mode_filter = list(range(len(waveforms["modes"])))
|
||
|
|
||
|
if args.export_modes:
|
||
|
mode_filter = list(map(int, args.export_modes.split(",")))
|
||
|
|
||
|
mode_filter = [m for m in mode_filter if any([wm["mode"] == m for wm in waveforms["modes"]])]
|
||
|
|
||
|
num_modes = len(mode_filter)
|
||
|
|
||
|
temp_intervals = []
|
||
|
for bounds in waveforms["temperature_ranges"]["range_bounds"]:
|
||
|
temp_intervals.append(f"{{ .min = {bounds['from']}, .max = {bounds['to']} }}")
|
||
|
|
||
|
modes = []
|
||
|
num_ranges = -1
|
||
|
for m_index, mode in enumerate(waveforms["modes"]):
|
||
|
|
||
|
if not mode["mode"] in mode_filter:
|
||
|
continue
|
||
|
|
||
|
ranges = []
|
||
|
for i, r in enumerate(mode["ranges"]):
|
||
|
bounds = waveforms["temperature_ranges"]["range_bounds"][i]
|
||
|
if bounds["from"] < tmin or bounds["from"] > tmax:
|
||
|
continue
|
||
|
|
||
|
phases = []
|
||
|
phase_count = len(r["phases"])
|
||
|
prev_phase = None
|
||
|
for phase in r["phases"]:
|
||
|
phases.append(phase_to_c(phase))
|
||
|
|
||
|
name = f"epd_wp_{args.name}_{mode['mode']}_{r['index']}"
|
||
|
|
||
|
phase_times= None
|
||
|
if r.get("phase_times"):
|
||
|
phase_times = [str(int(t * 10)) for t in r["phase_times"]]
|
||
|
print(f"const int {name}_times[{len(phase_times)}] = {{ {','.join(phase_times) } }};")
|
||
|
|
||
|
|
||
|
phase_times_str = f"&{name}_times[0]" if phase_times else "NULL"
|
||
|
print(f"const uint8_t {name}_data[{phase_count}][16][4] = {list_to_c(phases)};")
|
||
|
print(f"const EpdWaveformPhases {name} = {{ .phases = {phase_count}, .phase_times = {phase_times_str}, .luts = (const uint8_t*)&{name}_data[0] }};")
|
||
|
ranges.append(name)
|
||
|
|
||
|
assert(num_ranges < 0 or num_ranges == len(ranges))
|
||
|
|
||
|
num_ranges = len(ranges)
|
||
|
name = f"epd_wm_{args.name}_{mode['mode']}"
|
||
|
range_pointers = ','.join(['&' + n for n in ranges])
|
||
|
print(f"const EpdWaveformPhases* {name}_ranges[{len(ranges)}] = {{ {range_pointers} }};")
|
||
|
print(f"const EpdWaveformMode {name} = {{ .type = {mode['mode']}, .temp_ranges = {len(ranges)}, .range_data = &{name}_ranges[0] }};");
|
||
|
modes.append(name)
|
||
|
|
||
|
mode_pointers = ','.join(['&' + n for n in modes])
|
||
|
range_data = ",".join(temp_intervals)
|
||
|
|
||
|
print(f"const EpdWaveformTempInterval {args.name}_intervals[{len(temp_intervals)}] = {{ {range_data} }};");
|
||
|
print(f"const EpdWaveformMode* {args.name}_modes[{num_modes}] = {{ {mode_pointers} }};");
|
||
|
print(f"const EpdWaveform {args.name} = {{ .num_modes = {num_modes}, .num_temp_ranges = {num_ranges}, .mode_data = &{args.name}_modes[0], .temp_intervals = &{args.name}_intervals[0] }};");
|