Обновить логгер УМП и исправить запуск UART и EEPROM
Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты.
This commit is contained in:
@@ -51,13 +51,15 @@ unsigned int period_dac, time_dac;
|
||||
#define LOAD_RELOAD 2U
|
||||
/* Задаёт LOAD_FAULT = 3U; состояние остановки после исчерпания попыток. */
|
||||
#define LOAD_FAULT 3U
|
||||
/* Задаёт LOAD_MAX_ATTEMPTS = 5U; предел повторных пусков нагрузки — пять. */
|
||||
#define LOAD_MAX_ATTEMPTS 5U
|
||||
/* Задаёт LOAD_VOLTAGE_MIN = 30U; минимальное разрешённое напряжение нагрузки — 30 В. */
|
||||
#define LOAD_VOLTAGE_MIN 30U
|
||||
/* Задаёт LOAD_PULSE_MS = 1000U; длительность удержания импульса START/STOP — 1000 мс. */
|
||||
#define LOAD_PULSE_MS 1000U
|
||||
/* Объявляет load_state — текущее состояние автомата нагрузки; load_attempts — накопленное число пусков в текущем цикле, максимум пять; load_inhibit — признак запрета повторного запуска до требуемого перехода входов. */
|
||||
/* Стартовая выдержка 3 секунды выбрана для реакции УМП и обновления ЗПТ; при DAC_FREQ=200 Гц это 600 отправок задания 6 мА. */
|
||||
#define LOAD_START_WAIT_STEPS (3U * DAC_FREQ)
|
||||
/* load_start_remaining хранит остаток 600 стартовых отправок 6 мА; ноль означает конец выдержки или подтверждённые 30 В. */
|
||||
static unsigned int load_start_remaining;
|
||||
/* Хранит состояние автомата, число выданных START в текущем сеансе и запрет повторного пуска; лимит берётся отдельно из регистра 0x7D. */
|
||||
static unsigned int load_state, load_attempts, load_inhibit;
|
||||
/* Объявляет load_count_dac — load число ЦАП; load_count_ramp — load число ramp; load_init_count — load init число. */
|
||||
static unsigned int load_count_dac, load_count_ramp, load_init_count;
|
||||
@@ -78,6 +80,8 @@ void Load_control_init(void)
|
||||
{
|
||||
/* Записывает load_state значением LOAD_IDLE; load_attempts = 0; load_inhibit = 0; текущее состояние автомата нагрузки. */
|
||||
load_state = LOAD_IDLE; load_attempts = 0; load_inhibit = 0;
|
||||
/* Начинает первую попытку без накопленной выдержки и подтверждённого роста ЗПТ; COFF требует явной инициализации статических полей. */
|
||||
load_start_remaining = 0;
|
||||
/* Записывает load_count_dac значением 0; load_count_ramp = 0; load_init_count = 1; load число ЦАП. */
|
||||
load_count_dac = 0; load_count_ramp = 0; load_init_count = 1;
|
||||
/* Записывает load_zero_sent значением 0; load_stop_asserted = 0; load_initialized = 0; данные load_zero_sent. */
|
||||
@@ -178,10 +182,8 @@ static void load_start(void)
|
||||
if (load_end > 16) load_end = 16;
|
||||
/* Проверяет if (load_end <= load_go) load_end = load_go + 1; последующий оператор выполняется только при истинном условии. */
|
||||
if (load_end <= load_go) load_end = load_go + 1;
|
||||
/* Записывает ump_dac_go10 значением (unsigned int)((load_go + 4.0) * 10.0); ump ЦАП go 10. */
|
||||
ump_dac_go10 = (unsigned int)((load_go + 4.0) * 10.0);
|
||||
/* Записывает ump_dac_stop10 значением (unsigned int)((load_end + 4.0) * 10.0); ump ЦАП stop 10. */
|
||||
ump_dac_stop10 = (unsigned int)((load_end + 4.0) * 10.0);
|
||||
/* Каждая попытка получает 600 токовых тактов, то есть 3 секунды при 200 Гц; остаток уменьшается только после отправки 6 мА. */
|
||||
load_start_remaining = LOAD_START_WAIT_STEPS;
|
||||
/* Записывает load_count_ramp значением 0; load число ramp. */
|
||||
load_count_ramp = 0;
|
||||
/* Изменяет счётчик в выражении load_attempts++; на один для следующего шага. */
|
||||
@@ -220,8 +222,10 @@ void Setup_DAC_time(void)
|
||||
if ((unsigned int)LOAD_CAN_TIMEOUT == 0U ||
|
||||
/* Записывает LOAD_CAN_TIMEOUT значением 600; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */
|
||||
(unsigned int)LOAD_CAN_TIMEOUT > 60000U) LOAD_CAN_TIMEOUT = 600;
|
||||
/* Записывает LOAD_STATUS значением 0; LOAD_ATTEMPTS = 0; слово состояния защиты нагрузки для чтения, регистр 0x7C. */
|
||||
LOAD_STATUS = 0; LOAD_ATTEMPTS = 0;
|
||||
/* Старый нулевой счётчик в EEPROM заменяется заводским лимитом пяти пусков; ненулевую сохранённую настройку 0x7D не стираем. */
|
||||
if (!(unsigned int)LOAD_MAX_ATTEMPTS) LOAD_MAX_ATTEMPTS = LOAD_DEFAULT_MAX_ATTEMPTS;
|
||||
/* Сбрасывает диагностическое слово 0x7C при подготовке автомата; сохраняемый лимит не является текущим счётчиком. */
|
||||
LOAD_STATUS = 0;
|
||||
/* Записывает load_initialized значением 1; данные load_initialized. */
|
||||
load_initialized = 1;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
@@ -297,16 +301,16 @@ static void anal_output(long vrot, long maxx, int calibration)
|
||||
/* Объявляет x — данные x. */
|
||||
static int x;
|
||||
|
||||
/* Записывает out значением DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ; данные out. */
|
||||
/* Линейно переводит долю рампы vrot/maxx в код между DAC_min() и DAC_max(); целочисленное деление каждого слагаемого задаёт округление. */
|
||||
out = DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ;
|
||||
|
||||
/* Записывает x значением 0; данные x. */
|
||||
/* Фиксирует выбор нижней ветви передачи: при x=0 далее используется управляющее слово out|0x8000. */
|
||||
x=0;// !x; тщетно бытие
|
||||
|
||||
/* Проверяет if(calibration и cCalibrDac) out=DAC_cal(); последующий оператор выполняется только при истинном условии. */
|
||||
if(calibration && cCalibrDac) out=DAC_cal();
|
||||
|
||||
/* Записывает out значением out & 0xFFF; данные out. */
|
||||
/* Оставляет младшие 12 бит кода ЦАП. Это усечение битов, а не насыщение на границах 0..4095. */
|
||||
out = out & 0xFFF;
|
||||
|
||||
/* Проверяет if(x) dSEND(out|0x0000|0x0000); последующий оператор выполняется только при истинном условии. */
|
||||
@@ -314,10 +318,10 @@ static void anal_output(long vrot, long maxx, int calibration)
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
else dSEND(out|0x8000|0x0000);
|
||||
|
||||
/* Записывает modbus[123] значением out; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
/* Публикует фактически отправляемый 12-битный код ЦАП в технологическом регистре 0x7B для диагностики и регистрации. */
|
||||
modbus[123] = out;
|
||||
|
||||
/* Записывает modbus[0x1C] значением 40L + vrot * 200 / maxx - vrot * 40 / maxx ; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
/* Публикует расчётный выход 4..20 мА в масштабе 0,1 мА на единицу: при доле рампы 0 значение 40, при доле 1 значение 200. */
|
||||
modbus[0x1C] = 40L + vrot * 200 / maxx - vrot * 40 / maxx ;
|
||||
|
||||
/*
|
||||
@@ -352,10 +356,10 @@ void Anal_output(long vrot, long maxx)
|
||||
void Load_runner(void)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет saved — данные saved; commands — данные commands; voltage — данные voltage; fresh — данные fresh; timeout — данные timeout. */
|
||||
unsigned int saved, commands, voltage, fresh, timeout;
|
||||
/* Объявляет start — данные start; reset — сброс; active — данные active. Начальное значение задаётся справа от знака равенства. */
|
||||
unsigned int start, reset, active = 0;
|
||||
/* Хранит состояние IRQ, снимки команд и напряжения, свежесть CAN, тайм-аут в мс и лимит пусков; 16-битный лимит читается один раз за такт. */
|
||||
unsigned int saved, commands, voltage, fresh, timeout, attempt_limit;
|
||||
/* start/reset хранят командные биты; active отмечает работу; voltage_wait отмечает вывод 6 мА; ramp_before позволяет заморозить положение рампы. */
|
||||
unsigned int start, reset, active = 0, voltage_wait = 0, ramp_before;
|
||||
/* Объявляет sinus — данные sinus. Начальное значение задаётся справа от знака равенства. */
|
||||
float sinus = 0;
|
||||
|
||||
@@ -371,6 +375,10 @@ void Load_runner(void)
|
||||
voltage = (load_simulation & 2U) ? 0U : load_voltage;
|
||||
/* Записывает timeout значением (unsigned int)LOAD_CAN_TIMEOUT; данные timeout. */
|
||||
timeout = (unsigned int)LOAD_CAN_TIMEOUT;
|
||||
/* Читает 0x7D как беззнаковое 16-битное число, чтобы значения 32768..65535 сохраняли положительный смысл лимита. */
|
||||
attempt_limit = (unsigned int)LOAD_MAX_ATTEMPTS;
|
||||
/* При нештатном нуле в RAM оставляет прежний предел пяти пусков; штатные обработчики записи ноль отклоняют. */
|
||||
if (!attempt_limit) attempt_limit = LOAD_DEFAULT_MAX_ATTEMPTS;
|
||||
/* Проверяет if (!timeout или timeout > 60000U) timeout = 600U; последующий оператор выполняется только при истинном условии. */
|
||||
if (!timeout || timeout > 60000U) timeout = 600U;
|
||||
/* До первого пакета значение 0 не считается свежим измерением.
|
||||
@@ -393,7 +401,7 @@ void Load_runner(void)
|
||||
if (!start) {
|
||||
/* Проверяет if (load_state != LOAD_IDLE) load_stop(LOAD_IDLE); последующий оператор выполняется только при истинном условии. */
|
||||
if (load_state != LOAD_IDLE) load_stop(LOAD_IDLE);
|
||||
/* Записывает load_attempts значением 0; load_inhibit = 0; накопленное число пусков в текущем цикле, максимум пять. */
|
||||
/* Снятие START обнуляет счётчик текущего сеанса и запрет повторного пуска, сохраняя настроенный лимит в 0x7D. */
|
||||
load_attempts = 0; load_inhibit = 0;
|
||||
/* Проверяет else if (reset); последующий оператор выполняется только при истинном условии. */
|
||||
} else if (reset) {
|
||||
@@ -408,13 +416,15 @@ void Load_runner(void)
|
||||
/* Проверяет if (reset и !load_stop_asserted) load_stop(LOAD_IDLE); последующий оператор выполняется только при истинном условии. */
|
||||
if (reset && !load_stop_asserted) load_stop(LOAD_IDLE);
|
||||
|
||||
/* LOAD_RELOAD уже удерживает STOP, 4 мА и снятое разрешение; уменьшение лимита только фиксирует ошибку, не перезапуская секундную выдержку. */
|
||||
if (load_state == LOAD_RELOAD && load_attempts >= attempt_limit) load_state = LOAD_FAULT;
|
||||
/* Повторный START допускается после сброса ЦАП, окончания STOP и
|
||||
* восстановления нужного CAN-напряжения. Таймаут сам не тратит попытку. */
|
||||
/* Проверяет if (start и !reset и !load_inhibit и !WAKEpowse и fresh и; последующий оператор выполняется только при истинном условии. */
|
||||
/* Команда START без RESET и запрета должна дождаться окончания инициализации, свежего ЗПТ и подтверждённого задания 4 мА. */
|
||||
if (start && !reset && !load_inhibit && !WAKEpowse && fresh &&
|
||||
/* Продолжает список аргументов, полей или выражение load_zero_sent && !IMPowse &&; порядок элементов сохраняется. */
|
||||
/* Секундный STOP заканчивается только после передачи исходного кода ЦАП; обе выдержки обязательны перед пуском. */
|
||||
load_zero_sent && !IMPowse &&
|
||||
/* Продолжает список аргументов, полей или выражение (load_state == LOAD_IDLE || load_state == LOAD_RELOAD)) load_start();; порядок элементов сохраняется. */
|
||||
/* LOAD_IDLE начинает сеанс с нулевым счётчиком, а LOAD_RELOAD проверен на оставшиеся попытки выше; ошибка не разрешает START. */
|
||||
(load_state == LOAD_IDLE || load_state == LOAD_RELOAD)) load_start();
|
||||
/* Проверяет if (load_state == LOAD_RUN и !IMPowse) clear_START_DPTB(); последующий оператор выполняется только при истинном условии. */
|
||||
if (load_state == LOAD_RUN && !IMPowse) clear_START_DPTB();
|
||||
@@ -439,34 +449,43 @@ void Load_runner(void)
|
||||
active = load_state == LOAD_RUN;
|
||||
/* Проверяет if (active); последующий оператор выполняется только при истинном условии. */
|
||||
if (active) {
|
||||
/* При таймауте сохраняем положение И отправленное задание,
|
||||
* не делаем STOP и не продолжаем разгон без обратной связи. */
|
||||
/* Проверяет if (fresh); последующий оператор выполняется только при истинном условии. */
|
||||
/* В паузе CAN не вычисляет следующий шаг: положение, код и остаток стартовой выдержки сохраняются. */
|
||||
if (fresh) {
|
||||
/* Проверяет if (load_count_ramp > time_dac / 2) load_count_ramp++; последующий оператор выполняется только при истинном условии. */
|
||||
/* Сохраняет положение до шага, чтобы отменить рост на время начального ожидания при 6 мА. */
|
||||
ramp_before = load_count_ramp;
|
||||
/* Во второй половине штатной рампы сохраняет прежнее ускорение на два отсчёта за токовый такт. */
|
||||
if (load_count_ramp > time_dac / 2) load_count_ramp++;
|
||||
/* Проверяет if (++load_count_ramp > time_dac) load_count_ramp = time_dac; последующий оператор выполняется только при истинном условии. */
|
||||
/* Продвигает рампу на один отсчёт и ограничивает её концом, заданным LOAD_TIME и DAC_FREQ. */
|
||||
if (++load_count_ramp > time_dac) load_count_ramp = time_dac;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Записывает sinus значением ((load_end - load_go) / 16.0 * load_count_ramp) +; данные sinus. */
|
||||
sinus = ((load_end - load_go) / 16.0 * load_count_ramp) +
|
||||
/* Продолжает список аргументов, полей или выражение (load_go / 16.0 * time_dac);; порядок элементов сохраняется. */
|
||||
(load_go / 16.0 * time_dac);
|
||||
/* Проверяем следующий шаг ДО передачи ЦАП. 6 мА допустимы,
|
||||
* строго >6 мА и <30 В требуют немедленного STOP.
|
||||
* Первая попытка входит в лимит 5; шестого START не будет. */
|
||||
/* Проверяет if (fresh и voltage < LOAD_VOLTAGE_MIN и; последующий оператор выполняется только при истинном условии. */
|
||||
if (fresh && voltage < LOAD_VOLTAGE_MIN &&
|
||||
/* Продолжает список аргументов, полей или выражение sinus * 16.0 > 2.0 * time_dac) {; порядок элементов сохраняется. */
|
||||
sinus * 16.0 > 2.0 * time_dac) {
|
||||
/* Вызывает load_stop. Снимает START и разрешение нагрузки, удерживает STOP 1000 мс и сбрасывает состояние нарастания тока. */
|
||||
load_stop(load_attempts >= LOAD_MAX_ATTEMPTS ?
|
||||
/* Продолжает список аргументов, полей или выражение LOAD_FAULT : LOAD_RELOAD);; порядок элементов сохраняется. */
|
||||
LOAD_FAULT : LOAD_RELOAD);
|
||||
/* Записывает active значением 0; sinus = 0; данные active. */
|
||||
active = 0; sinus = 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
/* Преобразует продвижение рампы в долю полного токового диапазона 16 мА с учётом начальной уставки. */
|
||||
sinus = ((load_end - load_go) / 16.0 * load_count_ramp) +
|
||||
/* Добавляет начальную уставку относительно базовых 4 мА в тех же единицах положения рампы. */
|
||||
(load_go / 16.0 * time_dac);
|
||||
/* Подтверждённые 30 В завершают стартовое ожидание; последующее падение ЗПТ не получает новую выдержку. */
|
||||
if (voltage >= LOAD_VOLTAGE_MIN) load_start_remaining = 0;
|
||||
/* При меньшем ЗПТ внутренние 2 мА поверх базовых 4 мА ограничивают следующее задание суммарными 6 мА. */
|
||||
else if (sinus * 16.0 > 2.0 * time_dac) {
|
||||
/* До подтверждения порога даёт попытке остаток выбранных 3 секунд, не отправляя повышенный ток. */
|
||||
if (load_start_remaining) {
|
||||
/* Отменяет шаг рампы во время ожидания, чтобы после роста ЗПТ продолжить с прежнего положения. */
|
||||
load_count_ramp = ramp_before;
|
||||
/* Доля 1/8 диапазона 16 мА добавляет 2 мА к базовым 4 мА; time_dac=6000 даёт положение 750. */
|
||||
sinus = time_dac / 8.0;
|
||||
/* Отсчитывает выдержку только после отправки задания; служебная инициализация ЦАП не расходует её. */
|
||||
voltage_wait = 1;
|
||||
/* Исчерпанная выдержка или падение напряжения после успешного роста требуют немедленного STOP. */
|
||||
} else {
|
||||
/* Возвращает 4 мА и снимает разрешение; исчерпание сохранённого лимита попыток запрещает следующий пуск. */
|
||||
load_stop(load_attempts >= attempt_limit ?
|
||||
/* Использует согласованный снимок лимита текущего такта; заводские пять пусков сохраняют прежний предел. */
|
||||
LOAD_FAULT : LOAD_RELOAD);
|
||||
/* Исключает отправку рабочего задания в такте защитной остановки. */
|
||||
active = 0; sinus = 0;
|
||||
/* Закрывает выбор между ожиданием и защитным сбросом. */
|
||||
}
|
||||
/* Завершает проверку следующего токового задания при низком ЗПТ. */
|
||||
}
|
||||
/* Завершает обработку активной рампы при свежем выбранном напряжении CAN. */
|
||||
}
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
} else {
|
||||
@@ -479,12 +498,6 @@ void Load_runner(void)
|
||||
/* Во время защиты и пуска ручной код калибровки запрещён.
|
||||
* Калибровка сохранена только при снятом START и свободном STOP.
|
||||
* Нулевой код задания здесь означает ток 4 мА по DAC_min(). */
|
||||
/* Записывает ump_dac_ramp значением load_count_ramp; ump ЦАП ramp. */
|
||||
ump_dac_ramp = load_count_ramp;
|
||||
/* Записывает ump_dac_duration значением time_dac; ump ЦАП duration. */
|
||||
ump_dac_duration = time_dac;
|
||||
/* Записывает ump_dac_position значением (unsigned int)sinus; ump ЦАП position. */
|
||||
ump_dac_position = (unsigned int)sinus;
|
||||
/* Проверяет if (active и !fresh); последующий оператор выполняется только при истинном условии. */
|
||||
if (active && !fresh) {
|
||||
/* Удерживаем ЦАП. Даже cInitDac не меняет ток в паузе CAN. */
|
||||
@@ -498,6 +511,8 @@ void Load_runner(void)
|
||||
anal_output((int)sinus, time_dac,
|
||||
/* Продолжает список аргументов, полей или выражение !start && !load_stop_asserted);; порядок элементов сохраняется. */
|
||||
!start && !load_stop_asserted);
|
||||
/* Уменьшает остаток только после отправки 6 мА: тайм-аут CAN, инициализация ЦАП и STOP не расходуют выдержку. */
|
||||
if (voltage_wait) load_start_remaining--;
|
||||
/* A manual calibration frame is not a confirmed 4 mA reload.
|
||||
* START must wait for a forced baseline frame after it. */
|
||||
/* Проверяет if (!active) load_zero_sent = !(!start и !load_stop_asserted и cCalibrDac); последующий оператор выполняется только при истинном условии. */
|
||||
@@ -522,8 +537,6 @@ void Load_runner(void)
|
||||
(load_state == LOAD_RUN ? 8U : 0U) |
|
||||
/* Продолжает список аргументов, полей или выражение (load_simulation << 4);; порядок элементов сохраняется. */
|
||||
(load_simulation << 4);
|
||||
/* Записывает LOAD_ATTEMPTS значением load_attempts; число попыток пуска для чтения, регистр 0x7D. */
|
||||
LOAD_ATTEMPTS = load_attempts;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
|
||||
@@ -59,16 +59,14 @@ void clear_mem();
|
||||
#define UMP_LOG_BASE 0x1000U
|
||||
/* Задаёт UMP_LOG_DATA = 0x1010U; UMP LOG данные. */
|
||||
#define UMP_LOG_DATA 0x1010U
|
||||
/* Задаёт UMP_LOG_WORDS = 42U; UMP LOG слова. */
|
||||
#define UMP_LOG_WORDS 42U
|
||||
/* Запись v4 содержит 12 слов: время, событие, дискреты, ток, уставки, два ЗПТ и нулевой резерв для пар CAN. */
|
||||
#define UMP_LOG_WORDS 12U
|
||||
/* Задаёт UMP_LOG_CAPACITY = 760U; данные UMP_LOG_CAPACITY. */
|
||||
#define UMP_LOG_CAPACITY 760U
|
||||
/* Задаёт UMP_LOG_LIVE_RECORDS = (120U / UMP_LOG_WORDS); данные UMP_LOG_LIVE_RECORDS. */
|
||||
#define UMP_LOG_LIVE_RECORDS (120U / UMP_LOG_WORDS)
|
||||
/* Задаёт UMP_LOG_LIVE = 0x1100U; данные UMP_LOG_LIVE. */
|
||||
#define UMP_LOG_LIVE 0x1100U
|
||||
/* Объявляет ump_dac_ramp — ump ЦАП ramp; ump_dac_duration — ump ЦАП duration; ump_dac_go10 — ump ЦАП go 10; ump_dac_stop10 — ump ЦАП stop 10; ump_dac_position — ump ЦАП position. Память определена в другом модуле. */
|
||||
extern unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
/* Явно инициализирует оба банка регистратора до включения IRQ; повторный старт записи архив не стирает. */
|
||||
void ump_log_init(void);
|
||||
/* Продвигает время регистратора в Timer1 и снимает записи с заданным периодом. */
|
||||
|
||||
@@ -68,7 +68,7 @@ void ReceiveAnswerModbus4(RS_DATA *rs_arr);
|
||||
void Save_params(void);
|
||||
/* Читает сохранённые регистры из области параметров EEPROM и применяет настройки платы. */
|
||||
void Load_params(void);
|
||||
/* Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */
|
||||
/* Объявляет восстановление заводских параметров; для LOAD функция задаёт тайм-аут свежести CAN 2000 мс. */
|
||||
void Default_params(void);
|
||||
|
||||
/* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */
|
||||
|
||||
@@ -171,13 +171,15 @@
|
||||
/* Задаёт DAC_stop = modbus[0x51]; конечный ток нагрузки в мА, технологический регистр 0x51. */
|
||||
#define DAC_stop modbus[0x51] // конец зарада
|
||||
|
||||
/* LOAD-only persistent CAN timeout (ms), read-only status and attempts. */
|
||||
/* На плате LOAD тайм-аут и лимит попыток сохраняются штатной командой Save; состояние защиты доступно только для чтения. */
|
||||
/* Задаёт LOAD_CAN_TIMEOUT = modbus[0x52]; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */
|
||||
#define LOAD_CAN_TIMEOUT modbus[0x52]
|
||||
/* Задаёт LOAD_STATUS = modbus[0x7C]; слово состояния защиты нагрузки для чтения, регистр 0x7C. */
|
||||
#define LOAD_STATUS modbus[0x7C]
|
||||
/* Задаёт LOAD_ATTEMPTS = modbus[0x7D]; число попыток пуска для чтения, регистр 0x7D. */
|
||||
#define LOAD_ATTEMPTS modbus[0x7D]
|
||||
/* Задаёт записываемый лимит общего числа пусков в регистре 0x7D; допустимы 1..65535 попыток, включая первый START. */
|
||||
#define LOAD_MAX_ATTEMPTS modbus[0x7D]
|
||||
/* Сохраняет прежний заводской предел пяти пусков для сброса настроек и замены нуля из старой EEPROM. */
|
||||
#define LOAD_DEFAULT_MAX_ATTEMPTS 5U
|
||||
|
||||
/* Задаёт Cancount = (modbus+0x60); данные Cancount. */
|
||||
#define Cancount (modbus+0x60) // пауза между I посылками CAN
|
||||
|
||||
@@ -93,9 +93,9 @@ typedef unsigned int SE2P_SIZE;
|
||||
/* Message declaration */
|
||||
/* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */
|
||||
typedef struct {
|
||||
unsigned int *dataPtr; /* Data pointer */ /* Объявляет dataPtr — данные Ptr. Хранит указатель на данные. */
|
||||
unsigned long nrData; /* number of data */ /* Объявляет nrData — nr данные. */
|
||||
unsigned long se2pAddr; /* se2pAddr */ /* Объявляет se2pAddr — данные se2pAddr. */
|
||||
unsigned int * volatile dataPtr; /* Указатель буфера публикуется до csr: volatile запрещает перенос его записи за ожидание Timer2. */
|
||||
volatile unsigned long nrData; /* Число 16-битных слов записывается до флага запуска; Timer2 использует его для завершения передачи. */
|
||||
volatile unsigned long se2pAddr; /* Байтовый адрес EEPROM публикуется до csr; прерывание должно получить адрес текущего задания. */
|
||||
/* Продолжает список аргументов, полей или выражение }SE2P_DATA;; порядок элементов сохраняется. */
|
||||
}SE2P_DATA;
|
||||
|
||||
@@ -103,8 +103,8 @@ typedef struct {
|
||||
/* Object declaration */
|
||||
/* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */
|
||||
typedef struct {
|
||||
/* Main loop publishes the descriptor before setting csr; Timer2 consumes it.
|
||||
* Both accesses are volatile so optimization cannot publish the request first. */
|
||||
/* Главный цикл заполняет volatile-поля задания, затем msgPtr и csr; Timer2 читает их после запроса.
|
||||
* Одного volatile у msgPtr недостаточно: он защищает указатель, но не содержимое задания. */
|
||||
/* Продолжает список аргументов, полей или выражение SE2P_DATA * volatile msgPtr;; порядок элементов сохраняется. */
|
||||
SE2P_DATA * volatile msgPtr;
|
||||
volatile unsigned int csr; /* control/status register */ /* Объявляет csr — данные csr. volatile требует фактического чтения или записи при каждом доступе. */
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
|
||||
/* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */
|
||||
#include "RS485.h"
|
||||
#include <string.h> /* Объявляет memset для явного сброса UART: загрузчик COFF не гарантирует очистку .ebss. */
|
||||
/* Подключает "bios_dsp.h": коды и объявления команд последовательного загрузчика. */
|
||||
#include "bios_dsp.h"
|
||||
/* Подключает "cntrl_adr.h": собственный и универсальный адрес устройства. */
|
||||
@@ -730,6 +731,7 @@ void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
|
||||
rs_arr->SciRegs->SCIHBAUD = HIBYTE((int)SciBaud);
|
||||
/* Записывает rs_arr->SciRegs->SCILBAUD значением LOBYTE((int)SciBaud); rs arr SCI Regs SCILBAUD. */
|
||||
rs_arr->SciRegs->SCILBAUD = LOBYTE((int)SciBaud);
|
||||
rs_arr->curr_baud = speed; /* Сохраняет установленную скорость в бодах для последующих команд переключения линии и диагностики CCS. */
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -741,6 +743,8 @@ void create_uart_vars(char size_cmd15_set)
|
||||
{
|
||||
/* Записывает size_cmd15 значением size_cmd15_set; размер cmd 15. */
|
||||
size_cmd15=size_cmd15_set;
|
||||
memset(&rs_a, 0, sizeof(rs_a)); /* Сбрасывает указатели, длины, буферы и флаги SCI-A до настройки порта; исключает остатки RAM после JTAG. */
|
||||
memset(&rs_b, 0, sizeof(rs_b)); /* Независимо сбрасывает состояние SCI-B до назначения номера и аппаратных регистров. */
|
||||
/* Записывает rs_a.commnumber значением COM_1; данные commnumber. */
|
||||
rs_a.commnumber=COM_1;
|
||||
/* Записывает rs_b.commnumber значением COM_2; данные commnumber. */
|
||||
|
||||
@@ -335,10 +335,8 @@ void CAN_send(int Port, int data[], int Addr)
|
||||
void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Объявляет adr — данные adr. */
|
||||
unsigned int adr;
|
||||
/* Объявляет bit — представление регистра отдельными битовыми полями. */
|
||||
unsigned int bit[3];
|
||||
/* adr адресует очередное технологическое слово, slot выбирает одно из трёх слов кадра, mask хранит их биты достоверности 15..13. */
|
||||
unsigned int adr, slot, mask;
|
||||
/* Объявляет hiword — данные hiword; loword — данные loword. */
|
||||
unsigned long hiword,loword;
|
||||
/* Объявляет Data — данные. */
|
||||
@@ -376,12 +374,8 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
|
||||
/* Записывает adr значением (hiword >> 16); данные adr. */
|
||||
adr = (hiword >> 16);
|
||||
|
||||
/* Записывает bit[0] значением adr & 0x8000; представление регистра отдельными битовыми полями. */
|
||||
bit[0] = adr & 0x8000;
|
||||
/* Записывает bit[1] значением adr & 0x4000; представление регистра отдельными битовыми полями. */
|
||||
bit[1] = adr & 0x4000;
|
||||
/* Записывает bit[2] значением adr & 0x2000; представление регистра отдельными битовыми полями. */
|
||||
bit[2] = adr & 0x2000;
|
||||
/* Маска 0xE000 объединяет биты достоверности трёх слов CAN; сдвиг в цикле последовательно выводит каждый из них в бит 15. */
|
||||
mask = adr & 0xE000U;
|
||||
|
||||
/* Оставляет биты маски adr значением 0x1fff; данные adr. */
|
||||
adr &= 0x1fff;
|
||||
@@ -393,18 +387,12 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
|
||||
/* Записывает Data[2] значением (loword ) & 0xffff; данные. */
|
||||
Data[2] = (loword ) & 0xffff;
|
||||
|
||||
/* Проверяет if(bit[0]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */
|
||||
if(bit[0]) if(adr < ANSWER_LEN &&
|
||||
/* Записывает modbus[adr] значением Data[0]; adr++; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
!(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[0]; adr++;
|
||||
/* Проверяет if(bit[1]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */
|
||||
if(bit[1]) if(adr < ANSWER_LEN &&
|
||||
/* Записывает modbus[adr] значением Data[1]; adr++; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
!(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[1]; adr++;
|
||||
/* Проверяет if(bit[2]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */
|
||||
if(bit[2]) if(adr < ANSWER_LEN &&
|
||||
/* Записывает modbus[adr] значением Data[2]; массив технологических регистров; слово int на C28x занимает 16 бит. */
|
||||
!(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[2];
|
||||
/* Обрабатывает ровно три слова CAN; адрес растёт независимо от маски, а её сдвиг выбирает достоверность следующего слова. */
|
||||
for (slot = 0; slot < 3; slot++, adr++, mask <<= 1)
|
||||
/* Бит 15 текущей маски разрешает запись только в опубликованные 128 регистров, исключая выход за массив. */
|
||||
if ((mask & 0x8000U) && adr < ANSWER_LEN &&
|
||||
/* Для LOAD сохраняет статус 0x7C и отклоняет ноль в лимите 0x7D; остальные значения сохраняются как исходное 16-битное слово. */
|
||||
!(Desk == dsk_LOAD && (adr == 0x7CU || (adr == 0x7DU && !(unsigned int)Data[slot])))) modbus[adr] = Data[slot];
|
||||
|
||||
/* Фиксируем применённую команду до выхода из обработчика CAN. */
|
||||
/* A short frame cannot confirm voltage freshness. Service frames
|
||||
|
||||
@@ -17,7 +17,7 @@ extern void ump_log_rs(void);
|
||||
static const uint16_t gas167_info[GAS167_INFO_WORDS] = {
|
||||
/* Слова 0..3: сигнатура GA/S1, версия профиля и номер проекта 167. */
|
||||
0x4741U, 0x5331U, GAS167_PROFILE_VERSION, 167U,
|
||||
/* Слова 4..7: начало 0x5000, длина 128 слов, возможности RTU/CAN/FC06 и размер адресной единицы в словах. */
|
||||
/* Слова 4..7: база технологических регистров, число слов, маска RTU/CAN/FC06 и признак EEPROM M95M02 = 1; последний элемент описывает аппаратный профиль. */
|
||||
GAS167_REG_BASE, GAS167_REG_COUNT, GAS167_CAPABILITIES, 1U
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
};
|
||||
@@ -39,8 +39,10 @@ static unsigned gas167_write(uint16_t offset, uint16_t value)
|
||||
{
|
||||
/* Правила записи совпадают со штатным Modbus: статусы защиты нельзя
|
||||
* перезаписать, а недопустимый тайм-аут не позволяет обойти защиту. */
|
||||
/* На плате LOAD состояния 0x7C/0x7D принадлежат защите; запись отклоняется кодом неверного адреса 2. */
|
||||
if (Desk == dsk_LOAD && (offset == 0x7CU || offset == 0x7DU)) return 2;
|
||||
/* Состояние защиты 0x7C остаётся только для чтения; GAS-псевдоним лимита 0x507D допускает запись. */
|
||||
if (Desk == dsk_LOAD && offset == 0x7CU) return 2;
|
||||
/* Отклоняет нулевой лимит кодом Modbus 3 одинаково для RTU и служебного CAN; uint16_t ограничивает верхнюю границу 65535. */
|
||||
if (Desk == dsk_LOAD && offset == 0x7DU && value == 0U) return 3;
|
||||
/* Для сохраняемого тайм-аута CAN нагрузки применяется проверка диапазона независимо от транспорта. */
|
||||
if (Desk == dsk_LOAD && offset == 0x52U &&
|
||||
/* Значение 0 или больше 60000 мс недопустимо и возвращает код 3; защиту нельзя отключить такой записью. */
|
||||
|
||||
@@ -75,19 +75,11 @@ static unsigned int ump_source, ump_post;
|
||||
#define UMP_POST_POINTS (UMP_LOG_CAPACITY / 10U)
|
||||
/* Замораживает заполненный банк и переключает рабочий банк, сохраняя доступный архив. */
|
||||
static void ump_freeze(void);
|
||||
/* Объявляет ump_can_header — ump CAN header; ump_can_data — ump CAN данные; ump_can_count — ump CAN число. */
|
||||
static unsigned int ump_can_header, ump_can_data[3], ump_can_count;
|
||||
/* Latest PM67 sums: register 306 (index 305), register 9 (index 8). */
|
||||
/* Объявляет ump_pm67_voltage — данные ump_pm67_voltage. */
|
||||
static unsigned int ump_pm67_voltage[2];
|
||||
/* Объявляет ump_prev_commands — данные ump_prev_commands; ump_prev_inputs — данные ump_prev_inputs; ump_prev_outputs — данные ump_prev_outputs. */
|
||||
static unsigned int ump_prev_commands, ump_prev_inputs, ump_prev_outputs;
|
||||
/* Объявляет CanTimeOutErrorTR — CAN Time Out ошибка TR. Память определена в другом модуле. */
|
||||
extern int CanTimeOutErrorTR;
|
||||
/* Диагностика внутренних переменных разгона. Обновляется самим Load_runner,
|
||||
* не пересчитывает и не изменяет управляющий алгоритм. */
|
||||
/* Объявляет ump_dac_ramp — ump ЦАП ramp; ump_dac_duration — ump ЦАП duration; ump_dac_go10 — ump ЦАП go 10; ump_dac_stop10 — ump ЦАП stop 10; ump_dac_position — ump ЦАП position. */
|
||||
unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
|
||||
/* Called once at boot, before enabling interrupts. TI COFF startup does
|
||||
* not clear uninitialized globals in .ebss. Do not use for record restart:
|
||||
@@ -110,18 +102,10 @@ void ump_log_init(void)
|
||||
ump_archive_count = 0; ump_archive_next = 0; ump_generation = 0;
|
||||
/* Записывает ump_source значением 0; ump_post = 0; данные ump_source. */
|
||||
ump_source = 0; ump_post = 0;
|
||||
/* Записывает ump_can_header значением 0; ump_can_count = 0; ump CAN header. */
|
||||
ump_can_header = 0; ump_can_count = 0;
|
||||
/* Цикл for (i = 0; i < 3; i++) ump_can_data[i] = 0;; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 3; i++) ump_can_data[i] = 0;
|
||||
/* Цикл for (i = 0; i < 2; i++) ump_pm67_voltage[i] = 0;; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 2; i++) ump_pm67_voltage[i] = 0;
|
||||
/* Записывает ump_prev_commands значением 0; ump_prev_inputs = 0; ump_prev_outputs = 0; данные ump_prev_commands. */
|
||||
ump_prev_commands = 0; ump_prev_inputs = 0; ump_prev_outputs = 0;
|
||||
/* Записывает ump_dac_ramp значением 0; ump_dac_duration = 0; ump_dac_go10 = 0; ump ЦАП ramp. */
|
||||
ump_dac_ramp = 0; ump_dac_duration = 0; ump_dac_go10 = 0;
|
||||
/* Записывает ump_dac_stop10 значением 0; ump_dac_position = 0; ump ЦАП stop 10. */
|
||||
ump_dac_stop10 = 0; ump_dac_position = 0;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -164,8 +148,8 @@ static void ump_capture(unsigned int reason)
|
||||
{
|
||||
/* Объявляет p — данные p. Хранит указатель на данные. volatile требует фактического чтения или записи при каждом доступе. */
|
||||
volatile unsigned int *p;
|
||||
/* Объявляет i — данные i; commands — данные commands; inputs — данные inputs; outputs — данные outputs. */
|
||||
unsigned int i, commands, inputs, outputs;
|
||||
/* Объявляет commands — данные commands; inputs — данные inputs; outputs — данные outputs. */
|
||||
unsigned int commands, inputs, outputs;
|
||||
/* Проверяет if (ump_state != 1 или Desk != dsk_LOAD или !READY) return; последующий оператор выполняется только при истинном условии. */
|
||||
if (ump_state != 1 || Desk != dsk_LOAD || !READY) return;
|
||||
/* Проверяет if (no_write или never_write); последующий оператор выполняется только при истинном условии. */
|
||||
@@ -200,40 +184,20 @@ static void ump_capture(unsigned int reason)
|
||||
if (ump_post && !(reason & 0x100) && --ump_post == 0) reason = 5;
|
||||
/* Записывает p значением logs_block + ((unsigned long)ump_bank * UMP_LOG_CAPACITY + ump_next) * UMP_LOG_WORDS; данные p. */
|
||||
p = logs_block + ((unsigned long)ump_bank * UMP_LOG_CAPACITY + ump_next) * UMP_LOG_WORDS;
|
||||
/* Записывает p[0] значением (unsigned int)ump_time; p[1] = (unsigned int)(ump_time >> 16); данные p. */
|
||||
/* Сохраняет 32-битное миллисекундное время младшим словом вперёд; это первые два слова записи v4. */
|
||||
p[0] = (unsigned int)ump_time; p[1] = (unsigned int)(ump_time >> 16);
|
||||
/* Записывает p[2] значением reason; p[3] = commands; данные p. */
|
||||
p[2] = reason; p[3] = commands;
|
||||
/* Записывает p[4] значением inputs; p[5] = outputs; данные p. */
|
||||
/* Событие сохраняет причину и метку отключения; от команд остаются только нужные дискретные пуск и сброс, биты 7/6. */
|
||||
p[2] = reason; p[3] = commands & 0xC0U;
|
||||
/* Оставляет логические уровни входов и выходов для графиков START, STOP, OMEGA и разрешения нагрузки. */
|
||||
p[4] = inputs; p[5] = outputs;
|
||||
/* Записывает p[6] значением (unsigned int)IMPowse; p[7] = (unsigned int)WAKEpowse; данные p. */
|
||||
p[6] = (unsigned int)IMPowse; p[7] = (unsigned int)WAKEpowse;
|
||||
/* Записывает p[8] значением modbus[0x7B]; p[9] = modbus[0x1C]; данные p. */
|
||||
p[8] = modbus[0x7B]; p[9] = modbus[0x1C];
|
||||
/* Цикл for (i = 0; i < 4; i++) ; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 4; i++) { p[10+i] = sens_data[i]; p[14+i] = modbus[i]; }
|
||||
/* Записывает p[18] значением ump_can_header; данные p. */
|
||||
p[18] = ump_can_header;
|
||||
/* Записывает p[19] значением ump_can_data[0]; p[20] = ump_can_data[1]; p[21] = ump_can_data[2]; данные p. */
|
||||
p[19] = ump_can_data[0]; p[20] = ump_can_data[1]; p[21] = ump_can_data[2];
|
||||
/* Записывает p[22] значением ump_can_count; p[23] = CanTimeOutErrorTR; данные p. */
|
||||
p[22] = ump_can_count; p[23] = CanTimeOutErrorTR;
|
||||
/* Исходные уставки — мА; эффективные уставки после ограничений — 0.1 мА.
|
||||
* p[8] — отправленный код, а p[9] — расчётное задание, НЕ измерение тока. */
|
||||
/* Записывает p[24] значением DAC_go; p[25] = DAC_stop; данные p. */
|
||||
p[24] = DAC_go; p[25] = DAC_stop;
|
||||
/* Записывает p[26] значением DAC_min(); p[27] = DAC_max(); p[28] = DAC_cal(); данные p. */
|
||||
p[26] = DAC_min(); p[27] = DAC_max(); p[28] = DAC_cal();
|
||||
/* Записывает p[29] значением DAC_04; p[30] = DAC_20; данные p. */
|
||||
p[29] = DAC_04; p[30] = DAC_20;
|
||||
/* Записывает p[31] значением ump_dac_ramp; p[32] = ump_dac_duration; данные p. */
|
||||
p[31] = ump_dac_ramp; p[32] = ump_dac_duration;
|
||||
/* Записывает p[33] значением ump_dac_go10; p[34] = ump_dac_stop10; p[35] = ump_dac_position; данные p. */
|
||||
p[33] = ump_dac_go10; p[34] = ump_dac_stop10; p[35] = ump_dac_position;
|
||||
/* Цикл for (i = 0; i < 4; i++) p[36+i] = ADC_table[i];; задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
for (i = 0; i < 4; i++) p[36+i] = ADC_table[i];
|
||||
/* Записывает p[40] значением ump_pm67_voltage[0]; p[41] = ump_pm67_voltage[1]; данные p. */
|
||||
p[40] = ump_pm67_voltage[0]; p[41] = ump_pm67_voltage[1];
|
||||
/* Задание тока берётся из регистра 0x1C в единицах 0,1 мА; это расчётная величина, а не измерение физического тока. */
|
||||
p[6] = modbus[0x1C];
|
||||
/* Сохраняет оставшиеся выбранные начальную и конечную уставки в целых мА. */
|
||||
p[7] = DAC_go; p[8] = DAC_stop;
|
||||
/* Оставляет оба ЗПТ в вольтах: CAN-индекс 305 относится к ЗПТ1, индекс 8 — к ЗПТ2. */
|
||||
p[9] = ump_pm67_voltage[0]; p[10] = ump_pm67_voltage[1];
|
||||
/* Резервное нулевое слово делает длину записи чётной: служебный CAN передаёт по два 16-битных слова за фрагмент. */
|
||||
p[11] = 0;
|
||||
/* Изменяет счётчик в выражении ump_next++; на один для следующего шага. */
|
||||
ump_next++;
|
||||
/* Проверяет if (ump_next == UMP_LOG_CAPACITY) ump_next = 0; последующий оператор выполняется только при истинном условии. */
|
||||
@@ -338,12 +302,6 @@ void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned i
|
||||
}
|
||||
/* Проверяет if (ump_state != 1); последующий оператор выполняется только при истинном условии. */
|
||||
if (ump_state != 1) { __restore_interrupts(saved); return; }
|
||||
/* Записывает ump_can_header значением header; ump CAN header. */
|
||||
ump_can_header = header;
|
||||
/* Записывает ump_can_data[0] значением a; ump_can_data[1] = b; ump_can_data[2] = c; ump CAN данные. */
|
||||
ump_can_data[0] = a; ump_can_data[1] = b; ump_can_data[2] = c;
|
||||
/* Изменяет счётчик в выражении ump_can_count++; на один для следующего шага. */
|
||||
ump_can_count++;
|
||||
/* Вызывает ump_capture. Создаёт одну запись состояния: входы, выходы, команды, напряжения и параметры тока нагрузки. */
|
||||
ump_capture(2);
|
||||
/* Вызывает __restore_interrupts с аргументами (saved) в текущей последовательности операций. */
|
||||
@@ -456,7 +414,7 @@ unsigned int ump_log_read(unsigned int address)
|
||||
/* Ветвь выбора для UMP_LOG_BASE; выполняется при совпадении селектора switch. */
|
||||
case UMP_LOG_BASE: return 0x554D;
|
||||
/* Ветвь выбора для UMP_LOG_BASE+1; выполняется при совпадении селектора switch. */
|
||||
case UMP_LOG_BASE+1: return 3;
|
||||
case UMP_LOG_BASE+1: return 4;
|
||||
/* Ветвь выбора для UMP_LOG_BASE+2; выполняется при совпадении селектора switch. */
|
||||
case UMP_LOG_BASE+2: return ump_source ? 3 : ump_state;
|
||||
/* Ветвь выбора для UMP_LOG_BASE+3; выполняется при совпадении селектора switch. */
|
||||
@@ -501,7 +459,7 @@ unsigned int ump_log_read(unsigned int address)
|
||||
return ump_word(ump_source, ump_cursor + offset / UMP_LOG_WORDS, offset % UMP_LOG_WORDS);
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Последние три записи для онлайн-графика, без остановки и без
|
||||
/* Последние UMP_LOG_LIVE_RECORDS записей для онлайн-графика, без остановки и без
|
||||
* изменения курсора архивного чтения. Первые два слова — их номер. */
|
||||
/* Проверяет if (address >= UMP_LOG_LIVE и address < UMP_LOG_LIVE+124); последующий оператор выполняется только при истинном условии. */
|
||||
if (address >= UMP_LOG_LIVE && address < UMP_LOG_LIVE+124) {
|
||||
|
||||
@@ -109,7 +109,7 @@ void main()
|
||||
setup_uart(COM_1,115200);
|
||||
|
||||
/* Проверяет if(Owen)setup_uart(COM_2,57600); последующий оператор выполняется только при истинном условии. */
|
||||
if(Owen)setup_uart(COM_2,57600);
|
||||
if(Owen)setup_uart(COM_2,115200);
|
||||
/* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */
|
||||
else setup_uart(COM_2,115200);
|
||||
|
||||
@@ -266,7 +266,7 @@ void main()
|
||||
{
|
||||
/* Записывает cDefParam значением 0; данные cDefParam. */
|
||||
cDefParam=0;
|
||||
/* Вызывает Default_params. Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */
|
||||
/* По команде восстановления записывает заводские параметры; для LOAD тайм-аут свежести CAN становится 2000 мс. */
|
||||
Default_params();
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
|
||||
@@ -746,7 +746,7 @@ void Init_packMask()
|
||||
{ Maska[m_SLOW][7]|= 0x0030; // Калибровка ЦАП
|
||||
/* Устанавливает биты Maska[m_SLOW][5] значением 0x0003; данные Maska. */
|
||||
Maska[m_SLOW][5]|= 0x0003; // Начало и конец зарада
|
||||
Maska[m_FAST][7]|= 0xF000; /* Protection status 0x7C + attempts 0x7D. */ // Дублировать команды /* Устанавливает биты Maska[m_FAST][7] значением 0xF000; данные Maska. */
|
||||
Maska[m_FAST][7]|= 0xF000; /* Быстрый CAN публикует статус 0x7C и настроенный лимит пусков 0x7D; биты 12..15 маски соответствуют адресам 0x7C..0x7F. */ // Дублировать команды /* Устанавливает биты Maska[m_FAST][7] значением 0xF000; данные Maska. */
|
||||
/* Устанавливает биты Maska[m_FAST][1] значением 0x3000; данные Maska. */
|
||||
Maska[m_FAST][1]|= 0x3000; // Управлающий ток СИФУ
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
|
||||
@@ -59,7 +59,7 @@ int modbus[ANSWER_LEN+1];
|
||||
/* Объявляет param — данные param. */
|
||||
unsigned int param[ANSWER_LEN+1];
|
||||
|
||||
/* Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */
|
||||
/* Заполняет регистры заводскими значениями; для LOAD задаёт тайм-аут свежести CAN 2000 мс. Значение 600 мс применяется отдельно при восстановлении недопустимого параметра. */
|
||||
void Default_params()
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
@@ -248,6 +248,8 @@ void Default_params()
|
||||
/* Записывает DAC_go значением 6; начальный ток нагрузки в мА, технологический регистр 0x50. */
|
||||
DAC_go = 6; // начало зарада
|
||||
LOAD_CAN_TIMEOUT = 2000; /* ms without fresh ZPT: freeze ramp. */ /* Записывает LOAD_CAN_TIMEOUT значением 2000; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */
|
||||
/* Устанавливает прежний заводской лимит пяти пусков, включая первый START; настройка хранится в сохраняемом регистре 0x7D. */
|
||||
LOAD_MAX_ATTEMPTS = LOAD_DEFAULT_MAX_ATTEMPTS;
|
||||
/* Записывает DAC_stop значением 16; конечный ток нагрузки в мА, технологический регистр 0x51. */
|
||||
DAC_stop= 16; // конец зарада
|
||||
|
||||
@@ -295,7 +297,7 @@ void Load_params()
|
||||
else
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Вызывает Default_params. Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */
|
||||
/* Восстанавливает заводские параметры после неверного CRC или несоответствия режима платы; LOAD_CAN_TIMEOUT получает 2000 мс. */
|
||||
Default_params();
|
||||
/* Записывает Commands значением 0; слово команд, технологический регистр 127. */
|
||||
Commands=0;
|
||||
@@ -373,7 +375,7 @@ static void modbus_exception(RS_DATA *rs_arr, unsigned int function, unsigned in
|
||||
}
|
||||
|
||||
/* UART parser has already validated CRC and accepted the device address. */
|
||||
/* Выбирает GAS либо существующее адресное пространство УМП и снимает согласованный ответ под краткой блокировкой IRQ. */
|
||||
/* Маршрутизирует расширенные адреса: RAM УМП/GAS захватывается под краткой блокировкой IRQ, а чтение EEPROM выполняется с разрешёнными IRQ, поскольку SPI продвигается из Timer2. */
|
||||
static int receive_ump(RS_DATA *rs_arr)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
@@ -381,7 +383,7 @@ static int receive_ump(RS_DATA *rs_arr)
|
||||
unsigned int address, value, saved, length, count, error;
|
||||
/* Main-loop only; encoded into the UART buffer before the next request.
|
||||
* Keep the 124-word snapshot off the shared interrupt stack. */
|
||||
/* Объявляет words — слова. */
|
||||
/* Статический буфер хранит до 124 слов снимка вне общего стека прерываний; главный цикл сериализует его до обработки следующего запроса. */
|
||||
static uint16_t words[UMP_MAX_WORDS];
|
||||
/* Записывает address значением (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3]; адрес. */
|
||||
address = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3];
|
||||
@@ -503,17 +505,18 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
/* Записывает rs_arr->buffer[2] значением Length_MB*2; rs arr буфер. */
|
||||
rs_arr->buffer[2] = Length_MB*2;
|
||||
|
||||
/* Защищаем целостность одного снимка/блока; передача UART идёт уже
|
||||
* с разрешёнными прерываниями и не задерживает измерение/управление. */
|
||||
/* Цикл for (i=0;i<Length_MB;i++); задаёт начальное значение, условие продолжения и шаг перебора. */
|
||||
/* Штатные регистры копируются последовательно без блокировки IRQ вокруг всего блока.
|
||||
* Измерительные ISR могут обновить соседние слова между чтениями; этот путь не гарантирует
|
||||
* единый момент захвата всех значений. RAM-расширения захватываются отдельно в receive_ump. */
|
||||
/* Формирует payload из запрошенного числа 16-битных слов; для каждого слова в ответе нужны два байта. */
|
||||
for (i=0;i<Length_MB;i++)
|
||||
/* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */
|
||||
{
|
||||
/* Записывает value значением modbus[Address_MB+i]; данные value. */
|
||||
/* Читает очередное слово один раз, чтобы старший и младший байты ответа относились к одному считанному значению. */
|
||||
value = modbus[Address_MB+i];
|
||||
/* Записывает rs_arr->buffer[3+i*2] значением (value >> 8) & 0xFF; rs arr буфер. */
|
||||
/* Помещает старший байт слова после трёхбайтного заголовка; данные регистра передаются старшим байтом вперёд. */
|
||||
rs_arr->buffer[3+i*2] = (value >> 8) & 0xFF;
|
||||
/* Записывает rs_arr->buffer[3+i*2+1] значением value & 0xFF; rs arr буфер. */
|
||||
/* Помещает младший байт непосредственно за старшим, сохраняя исходный 16-битный рисунок регистра. */
|
||||
rs_arr->buffer[3+i*2+1] = value & 0xFF;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
@@ -528,13 +531,13 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
/* Записывает rs_arr->buffer[Length_MB*2+4] значением HIBYTE(crc); rs arr буфер. */
|
||||
rs_arr->buffer[Length_MB*2+4] = HIBYTE(crc);
|
||||
|
||||
/* Записывает rs_arr->buffer[Length_MB*2+5] значением 0; rs arr буфер. */
|
||||
/* Первый исторический нулевой байт после CRC; входит в увеличенную длину штатного ответа. */
|
||||
rs_arr->buffer[Length_MB*2+5] = 0;
|
||||
/* Записывает rs_arr->buffer[Length_MB*2+6] значением 0; rs arr буфер. */
|
||||
/* Второй исторический нулевой байт после CRC; сохраняет прежний формат низких технологических адресов. */
|
||||
rs_arr->buffer[Length_MB*2+6] = 0;
|
||||
/* Записывает rs_arr->buffer[Length_MB*2+7] значением 0; rs arr буфер. */
|
||||
/* Третий исторический нулевой байт после CRC; это последний элемент передаваемого буфера при длине 2*N+8. */
|
||||
rs_arr->buffer[Length_MB*2+7] = 0;
|
||||
/* Записывает rs_arr->buffer[Length_MB*2+8] значением 0; rs arr буфер. */
|
||||
/* Дополнительный ноль находится за длиной, переданной в RS_Send; в текущий ответ это слово не отправляется. */
|
||||
rs_arr->buffer[Length_MB*2+8] = 0;
|
||||
|
||||
/* Записывает rs_arr->flag_TIMEOUT_to_Send значением true; rs arr флаг TIMEOUT to Send. */
|
||||
@@ -577,12 +580,18 @@ void ReceiveCommandModbus6(RS_DATA *rs_arr)
|
||||
/* Записывает Data_MB значением (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5]; данные MB. */
|
||||
Data_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5];
|
||||
|
||||
/* Проверяет if (Desk == dsk_LOAD и (Address_MB == 0x7CU или Address_MB == 0x7DU)); последующий оператор выполняется только при истинном условии. */
|
||||
if (Desk == dsk_LOAD && (Address_MB == 0x7CU || Address_MB == 0x7DU)) {
|
||||
/* На плате LOAD запрещает запись только состояния защиты 0x7C; регистр лимита 0x7D принимает настройку. */
|
||||
if (Desk == dsk_LOAD && Address_MB == 0x7CU) {
|
||||
/* Вызывает modbus_exception. Формирует ответ Modbus с установленным старшим битом функции и кодом исключения. */
|
||||
modbus_exception(rs_arr, CMD_MODBUS_6, 2); return;
|
||||
/* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */
|
||||
}
|
||||
/* Ноль в лимите 0x7D недопустим: первый пуск должен входить в разрешённые 1..65535 попыток. */
|
||||
if (Desk == dsk_LOAD && Address_MB == 0x7DU && Data_MB == 0U) {
|
||||
/* Возвращает код Modbus 3 для недопустимого значения, сохраняя прежний лимит и состояние автомата. */
|
||||
modbus_exception(rs_arr, CMD_MODBUS_6, 3); return;
|
||||
/* Завершает проверку ненулевого лимита перед общей записью технологического слова. */
|
||||
}
|
||||
/* Проверяет if (Desk == dsk_LOAD и Address_MB == 0x52U и; последующий оператор выполняется только при истинном условии. */
|
||||
if (Desk == dsk_LOAD && Address_MB == 0x52U &&
|
||||
/* Продолжает список аргументов, полей или выражение (Data_MB == 0U || Data_MB > 60000U)) {; порядок элементов сохраняется. */
|
||||
|
||||
Reference in New Issue
Block a user