Расширить DEIF, загрузку CAN и общую обработку сигналов
Добавить общее ядро DEIF, эмуляцию приборов и переносимые панели Python/Qt. Расширить загрузчики F2812 и F28335, обновление Flash и профиль STM Invertor. Добавить альтернативный МНК Eigen, модели неисправностей и диагностику сигналов. Обновить справочники устройств, проекты CCS и регрессионные проверки.
This commit is contained in:
@@ -8,6 +8,7 @@ import io
|
||||
import math
|
||||
import json
|
||||
from datetime import datetime
|
||||
from functools import lru_cache # Таблица достижимых частот строится один раз для каждого аппаратного таймера MCU.
|
||||
from set_devices.waveform import Waveform, generate as interpolate, load_recipe as load_interpolated_recipe
|
||||
from set_devices.signal_reconstruction import dac12
|
||||
|
||||
@@ -15,13 +16,14 @@ from set_devices.signal_reconstruction import dac12
|
||||
# TIM6 clock of the supported STM32F407 emulator firmware. The device protocol
|
||||
# does not currently expose its timer clock; keep this hardware profile explicit.
|
||||
F407_TIMER_HZ = 72_000_000
|
||||
F407_SAMPLE_RATES = tuple(sorted({
|
||||
rate
|
||||
for divisor in range(1, math.isqrt(F407_TIMER_HZ) + 1)
|
||||
if F407_TIMER_HZ % divisor == 0
|
||||
for rate in (divisor, F407_TIMER_HZ // divisor)
|
||||
if 1 <= rate <= 1_000_000
|
||||
}))
|
||||
@lru_cache(maxsize=16) # Небольшой кэш хранит аппаратные профили без повторного перебора делителей при построении сигнала.
|
||||
def timer_sample_rates(timer_hz, sample_max=1_000_000): # Частоты задаются целочисленным делением TIM6 выбранного MCU, единицы обоих параметров — Гц.
|
||||
if timer_hz <= 0 or sample_max <= 0: # Нулевые и отрицательные аппаратные параметры не описывают рабочий таймер.
|
||||
raise ValueError("Частота таймера и предел выборок должны быть положительными") # Ошибка профиля выявляется до формирования таблицы DAC.
|
||||
return tuple(sorted({rate for divisor in range(1, math.isqrt(timer_hz) + 1) if timer_hz % divisor == 0 for rate in (divisor, timer_hz // divisor) if 1 <= rate <= sample_max})) # Парные делители охватывают все точные частоты без перебора каждого значения до тактовой частоты.
|
||||
|
||||
|
||||
F407_SAMPLE_RATES = timer_sample_rates(F407_TIMER_HZ) # Старый публичный экспорт сохраняет прежние результаты для профиля F407 72 МГц.
|
||||
|
||||
|
||||
def nearest_f407_sample_rate(rate):
|
||||
@@ -29,9 +31,9 @@ def nearest_f407_sample_rate(rate):
|
||||
return min(F407_SAMPLE_RATES, key=lambda candidate: (abs(candidate - rate), candidate))
|
||||
|
||||
|
||||
def generate(points, sample_rate=1000, vref=3.3, method="pchip", degree=2):
|
||||
def generate(points, sample_rate=1000, vref=3.3, method="pchip", degree=2, *, backend="native"): # Прозрачно передаём выбранный настольный решатель общему генератору.
|
||||
if method != "samples":
|
||||
return interpolate(points, sample_rate, vref, method, degree)
|
||||
return interpolate(points, sample_rate, vref, method, degree, backend=backend) # Расчёт остаётся в нативном порте; обработчик готовых отсчётов не требует МНК.
|
||||
if type(sample_rate) is not int or not 1 <= sample_rate <= 1000000:
|
||||
raise ValueError("Частота отсчётов должна быть 1…1000000 Гц")
|
||||
if not math.isfinite(vref) or not 0 < vref <= 3.6:
|
||||
|
||||
Reference in New Issue
Block a user