Compare commits
3 Commits
current_fi
...
166
| Author | SHA1 | Date | |
|---|---|---|---|
| ee79c7a376 | |||
| 9ddea2d99a | |||
| b25e026dec |
2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
# Windows cmd.exe должен получать BAT с CRLF: русские комментарии в UTF-8 при одних LF могут нарушать разбор строк команд.
|
||||
*.bat text eol=crlf
|
||||
20
.gitignore
vendored
20
.gitignore
vendored
@@ -6,23 +6,3 @@
|
||||
/UKSSTMS320F28335.paf2
|
||||
/UKSSTMS320F28335.sbl
|
||||
/Bin/UKSSTMS320F28335_*.bin
|
||||
# Локальные разовые проверки, резервные копии и экспериментальные результаты сохраняются вне истории исходников.
|
||||
/.ui_patch/
|
||||
# Кэш pytest создаётся повторно при запуске тестов и не является частью прошивки.
|
||||
/.pytest_cache/
|
||||
# Загруженные исполняемые файлы и зависимости Doxygen остаются локальными инструментами.
|
||||
/Doc/.tools/
|
||||
# HTML, JavaScript и журналы генерации документации восстанавливаются из исходников.
|
||||
/Doc/build/
|
||||
# Каталог Release этого CCS-проекта содержит генерируемые make-файлы и объектные файлы.
|
||||
/UKSSTMS320F28335/Release/
|
||||
# Скомпилированный кэш Python восстанавливается автоматически и не содержит самостоятельных исходников.
|
||||
__pycache__/
|
||||
# Новые карты памяти формируются линкером; уже отслеживаемые карты остаются в истории.
|
||||
/Bin/*.map
|
||||
# Паспорт сопровождает генерируемый BIN и сохраняется рядом с ним в локальном выпуске.
|
||||
/Bin/*.bin.manifest.json
|
||||
# Контрольная сумма относится к конкретному генерируемому BIN и не является исходным файлом.
|
||||
/Bin/*.bin.sha256
|
||||
# Именованные экспериментальные Flash-варианты сохраняются локально; основные отслеживаемые OUT остаются в истории.
|
||||
/Bin/UKSSTMS320F28335_flash_*.out
|
||||
|
||||
Binary file not shown.
@@ -1,9 +1,9 @@
|
||||
********************************************************************************
|
||||
TMS320C2000 Hex Converter v22.6.0
|
||||
TMS320C2000 Hex Converter v5.2.7
|
||||
********************************************************************************
|
||||
|
||||
INPUT FILE NAME: <K:\git_project\28335_periph\Bin\UKSSTMS320F28335.out>
|
||||
OUTPUT FORMAT: Intel
|
||||
INPUT FILE NAME: <c:\Temp\166-sifu-build-vq3o6iha\UKSSTMS320F28335.out>
|
||||
OUTPUT FORMAT: Binary
|
||||
|
||||
PHYSICAL MEMORY PARAMETERS
|
||||
Default data width : 16
|
||||
@@ -12,22 +12,22 @@ PHYSICAL MEMORY PARAMETERS
|
||||
|
||||
BOOT LOADER PARAMETERS
|
||||
Table Type: SERIAL PORT (SCI 8 bit Mode)
|
||||
Entry Point: 0x0000b7bc
|
||||
Entry Point: 0x0000b56a
|
||||
|
||||
|
||||
OUTPUT TRANSLATION MAP
|
||||
--------------------------------------------------------------------------------
|
||||
00000000..ffffffff Page=0 Memory Width=8 ROM Width=8
|
||||
00000000..003fffff Page=0 Memory Width=8 ROM Width=8
|
||||
--------------------------------------------------------------------------------
|
||||
OUTPUT FILES: K:\git_project\28335_periph\UKSSTMS320F28335\Debug\.identity-release-018w5cqu\.firmware-7iwzourf\UKSSTMS320F28335.hex [b0..b7]
|
||||
OUTPUT FILES: c:\Temp\166-sifu-build-vq3o6iha\UKSSTMS320F28335.bin [b0..b7]
|
||||
|
||||
CONTENTS: 00000000..00007aa3 BOOT TABLE
|
||||
.cinit : dest=0000b969 size=0x26b width=00000002
|
||||
.text : dest=00008000 size=0x3969 width=00000002
|
||||
.econst : dest=0000c000 size=0x11e width=00000002
|
||||
.switch : dest=0000c11e size=0x48 width=00000002
|
||||
CONTENTS: 00000000..000075d5 BOOT TABLE
|
||||
.cinit : dest=0000b717 size=00000262 width=00000002
|
||||
.text : dest=00008000 size=00003717 width=00000002
|
||||
.econst : dest=0000c000 size=00000112 width=00000002
|
||||
.switch : dest=0000c112 size=00000048 width=00000002
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
00000000..ffffffff Page=1 Memory Width=8 ROM Width=8 "*DEFAULT PAGE 1*"
|
||||
00000000..003fffff Page=1 Memory Width=8 ROM Width=8 "*DEFAULT PAGE 1*"
|
||||
--------------------------------------------------------------------------------
|
||||
NO CONTENTS
|
||||
|
||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
||||
|
||||
Текущая логика дискретов описана в [SIFU_START_STOP.md](SIFU_START_STOP.md):
|
||||
CAN-фронты обрабатываются при приёме, импульсы снимаются таймером, STOP
|
||||
имеет приоритет. Компактный формат записи v4 совпадает с исполнением 167.
|
||||
имеет приоритет. Формат записи v2 и интерфейс SetGUI сохранены.
|
||||
|
||||
## Назначение и работа оператора
|
||||
|
||||
@@ -13,9 +13,8 @@ CAN-фронты обрабатываются при приёме, импуль
|
||||
Общий RS-адрес 16 здесь не рекомендуется: ответ содержит собственный адрес,
|
||||
и SetGUI проверяет совпадение адресов. CAN-настройки: [PERIPH28335_CAN.md](PERIPH28335_CAN.md).
|
||||
|
||||
Используется формат v4 из 167: 12 слов на запись вместо прежних 40;
|
||||
ёмкость исполнения 166 сохранена — два банка по 800 записей.
|
||||
Для чтения нужен SetGUI с поддержкой компактного формата v4, как для 167.
|
||||
Перенесён протокол v2 из 167: 40 слов на запись, два банка по 800 записей.
|
||||
Существующий SetGUI понимает эту прошивку без изменений программы.
|
||||
Кнопки записи управляют регистратором; команду запуска УМП подаёт контроллер.
|
||||
|
||||
1. **Начать запись** включает только регистратор, не пуск УМП.
|
||||
@@ -46,8 +45,7 @@ EEPROM не используется: под отключением в этой
|
||||
## Память и точность
|
||||
|
||||
Использована существующая секция `.logg` по адресу 0x200000: 64000
|
||||
16-битных слов. Два банка по 800 записей × 12 слов используют 19200 слов;
|
||||
размер выделенной секции сохранён. Одна запись занимает 24 байта вместо 80.
|
||||
16-битных слов. Два банка по 800 записей × 40 слов занимают её целиком.
|
||||
Текущий банк кольцевой. При триггере сохраняются последние до 399 записей,
|
||||
добавляется событие отключения, оставшаяся половина банка отведена
|
||||
постинтервалу. При 20 мс это до примерно 8 секунд до отключения и 1 секунды
|
||||
@@ -63,7 +61,7 @@ EEPROM не используется: под отключением в этой
|
||||
одинаковую отметку; порядок сохраняется порядком записей. На перезапуске
|
||||
регистратора счётчик продолжает прежнюю шкалу, при перезагрузке платы — 0.
|
||||
|
||||
Онлайн-опрос возвращает до десяти последних записей каждые 40 мс. Он не гарантирует
|
||||
Онлайн-опрос возвращает три последних записи каждые 40 мс. Он не гарантирует
|
||||
передачу каждого события при высоком CAN-трафике, медленном UART или паузах
|
||||
GUI. Номера записей позволяют убрать дубликаты и явно показать пропуски.
|
||||
Полный сохранившийся фрагмент следует читать кнопкой архива. Частота 20 мс
|
||||
@@ -75,12 +73,7 @@ GUI. Номера записей позволяют убрать дублика
|
||||
EEPROM, выделения памяти или копирования целого банка. Реальную задержку
|
||||
прерываний и длительность критических секций нужно измерить на F28335.
|
||||
|
||||
## Состав записи v4: 12 слов
|
||||
|
||||
Состав и позиции полей совпадают с компактным логгером 167. Убраны сырые
|
||||
данные АЦП и CAN, ошибки, счётчики, код и калибровки ЦАП, состояние разгона
|
||||
и прочие дополнительные диагностические поля. Управление нагрузкой 166,
|
||||
ёмкость банка и секундный постинтервал отключения сохранены.
|
||||
## Состав записи: 40 слов
|
||||
|
||||
| Слова | Данные | Единицы/смысл |
|
||||
|---|---|---|
|
||||
@@ -88,21 +81,33 @@ EEPROM, выделения памяти или копирования целог
|
||||
| 2 | Событие | 1 период, 2 CAN RX, 3 изменение I/O, 4 RS-команда, 5 конец постинтервала |
|
||||
| 2, бит 8 | Триггер отключения | флаг поверх причины события |
|
||||
| 2, бит 9 | Усечён постинтервал | установлен в конечном снимке |
|
||||
| 3 | Commands & 0xC0 | только пуск УМП (бит 7) и сброс УМП (бит 6) |
|
||||
| 3 | Commands / modbus[0x7F] | все 16 бит, в том числе пуск, сброс, инициализация и калибровка ЦАП |
|
||||
| 4 | Входы OMEGA, Start_1, Res_in | биты 0,1,2, активный уровень приведён к 1 |
|
||||
| 5 | START_DPTB, STOP_DPTB, RES_OUT_2 | биты 0,1,2, активный уровень приведён к 1 |
|
||||
| 6 | modbus[0x1C] | расчётное задание в 0.1 мА; GUI/CSV переводит в мА |
|
||||
| 7–8 | Фиксированные начальная и конечная уставки 166 | 6 и 16 мА; это не регистры настройки |
|
||||
| 9 | ЗПТ1: U1 + U2 | ПМ67, регистр 306 / нулевой CAN-индекс 305, В |
|
||||
| 10 | ЗПТ2: U3 + U4 | ПМ67, регистр 9 / нулевой CAN-индекс 8, В |
|
||||
| 11 | Резерв | всегда ноль; чётная длина нужна для парной передачи CAN |
|
||||
| 6 | IMPowse | остаток импульса, мс |
|
||||
| 7 | WAKEpowse | остаток инициализации, тики DAC_FREQ |
|
||||
| 8 | modbus[0x7B] | 12-битный код, переданный функцией dSEND в ЦАП |
|
||||
| 9 | modbus[0x1C] | расчётное задание в 0.1 мА; GUI/CSV переводит в мА |
|
||||
| 10–13 | sens_data[0..3] | измеренные сигналы, знаковое 16-битное значение в исходном масштабе |
|
||||
| 14–17 | modbus[0..3] | маски ошибок измерений |
|
||||
| 18 | CAN заголовок | адрес регистра в младших 13 битах и маска трёх слов в старших |
|
||||
| 19–21 | Три слова последнего принятого CAN-кадра | без преобразования |
|
||||
| 22 | Счётчик записанных CAN RX | младшие 16 бит |
|
||||
| 23 | CanTimeOutErrorTR | младшие 16 бит счётчика тайм-аутов CAN TX |
|
||||
| 24–25 | Фиксированные границы разгона 166 | 6 и 16 мА; это не регистры настройки |
|
||||
| 26–28 | DAC_min(), DAC_max(), DAC_cal() | коды калибровки и ручного задания ЦАП |
|
||||
| 29–30 | DAC_04, DAC_20 | значения соответствующих регистров |
|
||||
| 31–32 | count_load, time_dac | положение и длительность разгона в тиках |
|
||||
| 33–34 | Эффективные границы разгона 166 | 60 и 160 в 0.1 мА; GUI показывает 6 и 16 мА |
|
||||
| 35 | kod | целочисленное положение, используемое Anal_output |
|
||||
| 36–39 | adc_table_lem[0..3] | ADCRESULT2..5 после сдвига на 4, диапазон 0..4095 |
|
||||
|
||||
**Расчётное задание тока не является измеренным током выхода.** При включённом
|
||||
**Отправленный код ЦАП не является измеренным током выхода.** В этом проекте
|
||||
не установлено, какой вход аппаратно измеряет ток ЦАП. При включённом
|
||||
`cCalibrDac` отправляется `DAC_cal()`, а расчётное задание 0x1C остаётся
|
||||
результатом алгоритма разгона. Сырой код ЦАП и каналы АЦП в запись v4 не входят.
|
||||
Напряжения обновляются по подтверждённым маской словам CAN даже при остановленной
|
||||
записи: первый снимок содержит последние принятые значения. До первого приёма
|
||||
они равны нулю; отдельного флага свежести в формате v4 нет.
|
||||
результатом алгоритма разгона. Для диагностики это различие сохранено.
|
||||
В 166 каналы «АЦП 0..3» берутся из `adc_table_lem`, обновляемой в режиме
|
||||
нагрузки. Таблица `adc_table_tpl` в этом режиме не обновляется и не используется.
|
||||
|
||||
Управляющая формула 166 сохранена: `sinus = 10/16 * count_load + 2/16 * time_dac`.
|
||||
Регулируемый разгон и ограничители 167 не переносились. Поля границ показывают
|
||||
@@ -123,9 +128,9 @@ FC03, 0x1000, 16 слов:
|
||||
|
||||
| Смещение | Значение |
|
||||
|---|---|
|
||||
| 0,1 | 0x554D, версия 4 |
|
||||
| 0,1 | 0x554D, версия 2 |
|
||||
| 2,3 | состояние и число записей выбранного источника |
|
||||
| 4,5 | 12 слов в записи, 800 записей в банке |
|
||||
| 4,5 | 40 слов в записи, 800 записей в банке |
|
||||
| 6 | период периодических снимков, мс |
|
||||
| 7,8 | счётчик времени, младшее/старшее слово |
|
||||
| 9,10 | Desk (требуется 6 / dsk_LOAD), Mode |
|
||||
@@ -143,17 +148,15 @@ FC06:
|
||||
- 0x1002: хронологический индекс первой записи окна 0..799;
|
||||
- 0x1003: источник окна, 0 — текущий остановленный банк, 1 — архив отключения.
|
||||
|
||||
FC03, 0x1010, до 120 слов: окно до десяти записей от установленного индекса.
|
||||
Для CAN длина должна быть кратна 12 словам: 12, 24, ..., 120; прежние
|
||||
блоки v2 по 40 или 80 слов отклоняются как обрывающие компактную запись.
|
||||
FC03, 0x1010, до 120 слов: окно до трёх записей от установленного индекса.
|
||||
Чтение текущего банка этим окном во время записи не выдаёт изменяющиеся
|
||||
данные. GUI сначала останавливает его; архив можно читать при работающем
|
||||
текущем банке. После всех блоков GUI повторно проверяет поколение архива;
|
||||
при замене во время чтения результат не подменяет предыдущий график.
|
||||
|
||||
FC03, 0x1100, ровно 124 слова: онлайн-блок. Слова 0,1 — 32-битный номер
|
||||
первой записи, 2 — число записей 0..10, 3 — поколение архива, далее до десяти
|
||||
записей по 12 слов. Неиспользованные слова равны нулю. Окно онлайн не
|
||||
первой записи, 2 — число записей 0..3, 3 — поколение архива, далее до трёх
|
||||
записей по 40 слов. Неиспользованные слова равны нулю. Окно онлайн не
|
||||
зависит от курсора/выбора архива. Разделение 0x1010 и 0x1100 предотвращает
|
||||
пересечение двух окон.
|
||||
|
||||
@@ -164,19 +167,7 @@ CRC и разбор стандартного ответа GUI использую
|
||||
|
||||
## Проверка и запуск
|
||||
|
||||
Для компактного формата v4 пройден host-тест настоящего `log_to_mem.c`
|
||||
с MSVC 14.30.30705. Модули `log_to_mem.c`, `ecan.c` и `message.c`
|
||||
скомпилированы TI C2000 22.6.0.LTS с COFF, FPU32 и O1 без ошибок.
|
||||
После выбора исполнения 166 и периода CAN пульта 200 мс выполнена независимая
|
||||
компиляция всех 27 C/ASM-модулей и линковка TI C2000 22.6.0.LTS с COFF,
|
||||
FPU32 и O1. Загрузочный SCI8-образ занимает 30036 байт и побайтно совпадает
|
||||
с образом, полученным из сохранённого `Bin/UKSSTMS320F28335.out`.
|
||||
Проверено соответствие сохранённого HEX этому OUT. Сохранились пять
|
||||
предупреждений в существующих `measure.c` и `peripher.c`; на плате не проверено.
|
||||
|
||||
Первоначально регистратор и RS/CAN-доступ перенесены из коммитов 167
|
||||
`df71922` и `a3633d8`. Приведённые ниже результаты полной сборки относятся
|
||||
к исходному формату v2 до сокращения полей.
|
||||
Перенесены регистратор и RS/CAN-доступ из коммитов 167 `df71922` и `a3633d8`.
|
||||
Сборка всех 27 C/ASM-файлов и линковка TI C2000 22.6.1.LTS (Debug, COFF,
|
||||
FPU32, O1) прошли. Остались шесть прежних предупреждений в measure.c/peripher.c.
|
||||
В MAP: RAML0 занято 0x38D1 из 0x4000 слов, .ebss — 0xFA9 из 0x3000,
|
||||
@@ -185,10 +176,8 @@ FPU32, O1) прошли. Остались шесть прежних предуп
|
||||
Сборка проверки лежит вне репозитория, штатные файлы Bin не заменены.
|
||||
|
||||
Host-тест компилирует настоящий log_to_mem.c с подменой GPIO/IRQ.
|
||||
Проверяет кольцо, архив, переполнение постинтервала, онлайн-окно из десяти
|
||||
12-словных записей, CAN-протокол v4, готовность именно 166, фиксированные
|
||||
уставки 6/16 мА, маску команд и получение ЗПТ из трёх позиций CAN-кадра.
|
||||
Сторожевые значения контролируют границу записи и разделение банков.
|
||||
Проверяет кольцо, архив, переполнение постинтервала, онлайн-окно, CAN-протокол,
|
||||
готовность именно 166, фиксированные границы и четыре канала АЦП.
|
||||
Запуск из корня 166: `py -3 tests/ump_logger/run_test.py` (Clang/lld или MSVC
|
||||
в PATH); при необходимости передать `--compiler "полный путь к cl.exe"`.
|
||||
Тест не проверяет физические GPIO, тайминги прерываний и 16-битную ABI TI.
|
||||
@@ -197,7 +186,7 @@ Host-тест компилирует настоящий log_to_mem.c с подм
|
||||
начать запись → подать CAN-пуск → подать отключение → через секунду прочитать
|
||||
архив. Сверить START/STOP с физическими выходами и измерениями, повторить с
|
||||
разрывом RS/CAN. Проверить период 1 мс и задержки IRQ под нагрузкой.
|
||||
Для первоначального формата v2 тесты SetGUI (`test_ump_logger.py`, `test_ump_logger_can.py`,
|
||||
Тесты существующего SetGUI (`test_ump_logger.py`, `test_ump_logger_can.py`,
|
||||
`test_periph28335_tab.py`) в окружении Qt 5: **47 passed**. Проверены протокол,
|
||||
онлайн/архив, CAN-фрагменты, графики, курсоры и CSV.
|
||||
Проверка на устройстве не выполнялась.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Настройка АЦП и обработка аналоговых выборок. adc_isr обновляет
|
||||
* adc_table_lem[0..3] из ADCRESULT2..5 >> 4 и вызывает расчёт измерений.
|
||||
* READY в 166 является счётчиком до нуля, не флагом готовности.
|
||||
* WAKE задаёт отдельное время установления измерительных цепей.
|
||||
* Не добавлять ожидания EEPROM/UART в обработчик выборок.
|
||||
/* Íàñòðîéêà ÀÖÏ è îáðàáîòêà àíàëîãîâûõ âûáîðîê. adc_isr îáíîâëÿåò
|
||||
* adc_table_lem[0..3] èç ADCRESULT2..5 >> 4 è âûçûâàåò ðàñ÷¸ò èçìåðåíèé.
|
||||
* READY â 166 ÿâëÿåòñÿ ñ÷¸ò÷èêîì äî íóëÿ, íå ôëàãîì ãîòîâíîñòè.
|
||||
* WAKE çàäà¸ò îòäåëüíîå âðåìÿ óñòàíîâëåíèÿ èçìåðèòåëüíûõ öåïåé.
|
||||
* Íå äîáàâëÿòü îæèäàíèÿ EEPROM/UART â îáðàáîò÷èê âûáîðîê.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
|
||||
#include "DSP2833x_Examples.h" // DSP281x Examples Include File
|
||||
@@ -21,7 +21,7 @@
|
||||
#include "peripher.h"
|
||||
|
||||
Uint16 adc_table_lem[4];
|
||||
Uint16 adc_table_tpl[28]; // Потому что +4 калибр
|
||||
Uint16 adc_table_tpl[28]; // Ïîòîìó ÷òî +4 êàëèáð
|
||||
|
||||
unsigned long COUNT_WAIT_ONE_CANAL;
|
||||
|
||||
@@ -63,12 +63,12 @@ void setup_adc()
|
||||
{
|
||||
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0005; // Setup 2 conv's on SEQ1
|
||||
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // температура (которой нет)
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // омега
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5; // напруга 1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4; // напруга 2
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // ток 1
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2; // ток 2
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x3; // òåìïåðàòóðà (êîòîðîé íåò)
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x1; // îìåãà
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x5; // íàïðóãà 1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x4; // íàïðóãà 2
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0x7; // òîê 1
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0x2; // òîê 2
|
||||
}
|
||||
|
||||
if(Desk==dsk_BKST)
|
||||
@@ -82,7 +82,7 @@ void setup_adc()
|
||||
if(Desk==dsk_COMM)
|
||||
{
|
||||
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0006; // Setup 2 conv's on SEQ1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // сначала тоже будут температуры
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x5; // ñíà÷àëà òîæå áóäóò òåìïåðàòóðû
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x4; // Setup ADCINA2 as 2nd SEQ1 conv.
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x7; // Setup ADCINA2 as 2nd SEQ1 conv.
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0x2; // Setup ADCINA2 as 2nd SEQ1 conv.
|
||||
@@ -100,23 +100,23 @@ void setup_adc()
|
||||
if(Desk==dsk_SHKF)
|
||||
{
|
||||
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x000F; // Setup 2 conv's on SEQ1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // 380В Ф1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // 380В Ф2
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6; // 31В Ф1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC; // 31В Ф2 ?
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA; // 31В UC1
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB; // 31В UC2
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 24В ПУ
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4; // 24В ПУ
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x2; // 380Â Ô1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV01 = 0x3; // 380Â Ô2
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV02 = 0x6; // 31Â Ô1
|
||||
AdcRegs.ADCCHSELSEQ1.bit.CONV03 = 0xC; // 31Â Ô2 ?
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV04 = 0xA; // 31Â UC1
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV05 = 0xB; // 31Â UC2
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV06 = 0x7; // 24Â ÏÓ
|
||||
AdcRegs.ADCCHSELSEQ2.bit.CONV07 = 0x4; // 24Â ÏÓ
|
||||
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5; // 24В ПК было 5
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1; // 15В Др
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE; // +24В Дт
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0; // +24В Дт
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8; // -24В Дт было 8
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV08 = 0x5; // 24Â ÏÊ áûëî 5
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV09 = 0x1; // 15Â Äð
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV10 = 0xE; // +24Â Äò
|
||||
AdcRegs.ADCCHSELSEQ3.bit.CONV11 = 0x0; // +24Â Äò
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV12 = 0x8; // -24Â Äò áûëî 8
|
||||
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;//0xF; // ДТ° 1
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;//0xD; // ДТ° 2
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV13 = 0xF;//0xF; // ÄÒ° 1
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV14 = 0xD;//0xD; // ÄÒ° 2
|
||||
AdcRegs.ADCCHSELSEQ4.bit.CONV15 = 0x9;//0x9;
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ interrupt void adc_isr(void)
|
||||
{
|
||||
if (++cownt_cans>=tpl_cans) cownt_cans=0;
|
||||
|
||||
// Именно здесь нет дыр
|
||||
// Èìåííî çäåñü íåò äûð
|
||||
// if(sens_type[cownt_cans])
|
||||
{
|
||||
i++;
|
||||
@@ -244,7 +244,7 @@ interrupt void adc_isr(void)
|
||||
if(TermoAD)
|
||||
{
|
||||
if(cownt_cans == TPL_CANS ) code_tpl_canal = TERMOPAIR-1;
|
||||
if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2; // потому что 300 и 400 наоборот
|
||||
if(cownt_cans == TPL_CANS+1) code_tpl_canal = TERMOPAIR-2; // ïîòîìó ÷òî 300 è 400 íàîáîðîò
|
||||
}
|
||||
|
||||
select_tpl_canal(code_tpl_canal);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
/* ЦАП нагрузки и аппаратная обёртка импульсов СИФУ. Load_runner
|
||||
* вызывается таймером 1 кГц, расчёт ЦАП делится до DAC_FREQ.
|
||||
* Формула 166 задаёт фиксированный разгон 6..16 мА. DAC_min/max
|
||||
* переводят положение в код, cCalibrDac выбирает ручной код.
|
||||
* WAKEpowse относится к ЦАП, не является разрешением дискрета запуска.
|
||||
* Автомат СИФУ подключён в конце файла через ump_control_impl.h.
|
||||
/* ЦАП нагрузки и аппаратная обёртка импульсов СИФУ. Load_runner
|
||||
* вызывается таймером 1 кГц, расчёт ЦАП делится до DAC_FREQ.
|
||||
* Формула 166 задаёт фиксированный разгон 6..16 мА. DAC_min/max
|
||||
* переводят положение в код, cCalibrDac выбирает ручной код.
|
||||
* WAKEpowse относится к ЦАП, не является разрешением дискрета запуска.
|
||||
* Автомат СИФУ подключён в конце файла через ump_control_impl.h.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
|
||||
#include "DSP2833x_SWPrioritizedIsrLevels.h"
|
||||
@@ -29,8 +29,8 @@ unsigned long WAKEpowse;
|
||||
volatile unsigned long IMPowse;
|
||||
unsigned int period_dac, time_dac;
|
||||
|
||||
/* Инициализация, не обработка каждого START. 601 отсчёт при 200 Гц
|
||||
* дают около 3 секунд до рабочего расчёта ЦАП после включения.
|
||||
/* Инициализация, не обработка каждого START. 601 отсчёт при 200 Гц
|
||||
* дают около 3 секунд до рабочего расчёта ЦАП после включения.
|
||||
*/
|
||||
void Setup_DAC_time(void)
|
||||
{
|
||||
@@ -76,9 +76,9 @@ void Init_DAC(void)
|
||||
dSEND(0x9002|0x0000); toggle_RES_OUT_1();
|
||||
}
|
||||
|
||||
/* vrot/maxx — доля диапазона между кодами 4 и 20 мА. Маска 0xFFF
|
||||
* сохраняет 12 бит, но не является насыщением. modbus[0x1C] содержит
|
||||
* расчётное задание, не измеренный ток на выходных клеммах.
|
||||
/* vrot/maxx — доля диапазона между кодами 4 и 20 мА. Маска 0xFFF
|
||||
* сохраняет 12 бит, но не является насыщением. modbus[0x1C] содержит
|
||||
* расчётное задание, не измеренный ток на выходных клеммах.
|
||||
*/
|
||||
void Anal_output(long vrot, long maxx)
|
||||
{
|
||||
@@ -87,7 +87,7 @@ void Anal_output(long vrot, long maxx)
|
||||
|
||||
out = DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ;
|
||||
|
||||
x=0;// !x; тщетно бытие
|
||||
x=0;// !x; тщетно бытие
|
||||
|
||||
if(cCalibrDac) out=DAC_cal();
|
||||
|
||||
@@ -116,9 +116,9 @@ Log_to_mem(modbus[0x1D]);
|
||||
|
||||
}
|
||||
|
||||
/* После половины time_dac счётчик растёт дважды за вызов. Поэтому
|
||||
* LOAD_TIME=30 даёт примерно 22.5 с до конца разгона при 200 Гц.
|
||||
* Существующий профиль 166 исправление импульса СИФУ не меняет.
|
||||
/* После половины time_dac счётчик растёт дважды за вызов. Поэтому
|
||||
* LOAD_TIME=30 даёт примерно 22.5 с до конца разгона при 200 Гц.
|
||||
* Существующий профиль 166 исправление импульса СИФУ не меняет.
|
||||
*/
|
||||
void Load_runner()
|
||||
{
|
||||
@@ -126,7 +126,7 @@ void Load_runner()
|
||||
float sinus=0;
|
||||
int kod;
|
||||
|
||||
/* IMPowse обновляется UMP_pulse_tick(), а не алгоритмом ЦАП. */
|
||||
/* IMPowse обновляется UMP_pulse_tick(), а не алгоритмом ЦАП. */
|
||||
if(++count_dac >= period_dac)
|
||||
{
|
||||
count_dac=0;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Таблицы выборок обновляет ADC ISR. Согласованный снимок нескольких
|
||||
* каналов требует защиты копирования, одного указателя недостаточно.
|
||||
/* Таблицы выборок обновляет ADC ISR. Согласованный снимок нескольких
|
||||
* каналов требует защиты копирования, одного указателя недостаточно.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/* Интерфейс ЦАП и СИФУ. Входящие команды — UMP_commands_write,
|
||||
* окончание импульса — UMP_pulse_tick. IMPowse только для диагностики.
|
||||
/* Интерфейс ЦАП и СИФУ. Входящие команды — UMP_commands_write,
|
||||
* окончание импульса — UMP_pulse_tick. IMPowse только для диагностики.
|
||||
*/
|
||||
void Load_runner(void);
|
||||
void Anal_output(long vrot, long maxx);
|
||||
void Init_DAC(void);
|
||||
void Setup_DAC_time(void);
|
||||
|
||||
/* Счётчик пускового импульса и выдержки инициализации доступны логгеру. */
|
||||
/* Счётчик пускового импульса и выдержки инициализации доступны логгеру. */
|
||||
extern volatile unsigned long IMPowse;
|
||||
extern unsigned long WAKEpowse;
|
||||
extern unsigned int period_dac, time_dac;
|
||||
|
||||
/* Все операции безопасны для вызова из main и обработчиков IRQ. */
|
||||
/* Все операции безопасны для вызова из main и обработчиков IRQ. */
|
||||
void UMP_pulse_init(void);
|
||||
void UMP_commands_write(unsigned int commands);
|
||||
void UMP_pulse_tick(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Направления GPIO для аппаратных исполнений. Единица означает
|
||||
* выход; активную полярность задают peripher.h и схема платы.
|
||||
/* Íàïðàâëåíèÿ GPIO äëÿ àïïàðàòíûõ èñïîëíåíèé. Åäèíèöà îçíà÷àåò
|
||||
* âûõîä; àêòèâíóþ ïîëÿðíîñòü çàäàþò peripher.h è ñõåìà ïëàòû.
|
||||
*/
|
||||
#define COMM_gpio00_dir 0L
|
||||
#define COMM_gpio01_dir 0L
|
||||
@@ -14,7 +14,7 @@
|
||||
#define COMM_gpio10_dir 0L
|
||||
#define COMM_gpio11_dir 0L
|
||||
|
||||
#define COMM_gpio19_dir 1L // 63 — SPI
|
||||
#define COMM_gpio19_dir 1L // 63 — SPI
|
||||
#define COMM_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define COMM_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define COMM_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#define COMM_gpio32_dir 1L // 74 2:10B DIOD green
|
||||
#define COMM_gpio33_dir 0L
|
||||
#define COMM_gpio34_dir 1L // 142 — SCI
|
||||
#define COMM_gpio34_dir 1L // 142 — SCI
|
||||
|
||||
#define COMM_gpio48_dir 1L // 88 2:14C DIOD red
|
||||
#define COMM_gpio49_dir 1L // 89 2:14B select
|
||||
@@ -57,7 +57,7 @@
|
||||
#define BKSD_gpio10_dir 0L // 19 2:6C oil
|
||||
#define BKSD_gpio11_dir 1L // 20 2:3C select
|
||||
|
||||
#define BKSD_gpio19_dir 1L // 63 — SPI
|
||||
#define BKSD_gpio19_dir 1L // 63 — SPI
|
||||
#define BKSD_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define BKSD_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define BKSD_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -69,7 +69,7 @@
|
||||
|
||||
#define BKSD_gpio32_dir 1L // 74 2:10B DIOD green
|
||||
#define BKSD_gpio33_dir 0L
|
||||
#define BKSD_gpio34_dir 1L // 142 — SCI
|
||||
#define BKSD_gpio34_dir 1L // 142 — SCI
|
||||
|
||||
#define BKSD_gpio48_dir 1L // 88 2:14C DIOD red
|
||||
#define BKSD_gpio49_dir 0L // 89 2:14B input 2
|
||||
@@ -100,7 +100,7 @@
|
||||
#define BKST_gpio10_dir 0L
|
||||
#define BKST_gpio11_dir 1L // 20 2:3C select
|
||||
|
||||
#define BKST_gpio19_dir 1L // 63 — SPI
|
||||
#define BKST_gpio19_dir 1L // 63 — SPI
|
||||
#define BKST_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define BKST_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define BKST_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -112,7 +112,7 @@
|
||||
|
||||
#define BKST_gpio32_dir 1L // 74 2:10B DIOD green
|
||||
#define BKST_gpio33_dir 0L
|
||||
#define BKST_gpio34_dir 1L // 142 — SCI
|
||||
#define BKST_gpio34_dir 1L // 142 — SCI
|
||||
|
||||
#define BKST_gpio48_dir 1L // 88 2:14C DIOD red
|
||||
#define BKST_gpio49_dir 0L
|
||||
@@ -143,7 +143,7 @@
|
||||
#define PULT_gpio10_dir 0L
|
||||
#define PULT_gpio11_dir 0L
|
||||
|
||||
#define PULT_gpio19_dir 1L // 63 — SPI
|
||||
#define PULT_gpio19_dir 1L // 63 — SPI
|
||||
#define PULT_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define PULT_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define PULT_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -155,7 +155,7 @@
|
||||
|
||||
#define PULT_gpio32_dir 1L // 74 2:10B DIOD green
|
||||
#define PULT_gpio33_dir 0L
|
||||
#define PULT_gpio34_dir 1L // 142 — SCI
|
||||
#define PULT_gpio34_dir 1L // 142 — SCI
|
||||
|
||||
#define PULT_gpio48_dir 1L // 88 2:14C DIOD red
|
||||
#define PULT_gpio49_dir 0L // 89 2:14B button
|
||||
@@ -186,7 +186,7 @@
|
||||
#define PLT2_gpio10_dir 0L
|
||||
#define PLT2_gpio11_dir 0L
|
||||
|
||||
#define PLT2_gpio19_dir 1L // 63 Ч SPI
|
||||
#define PLT2_gpio19_dir 1L // 63 × SPI
|
||||
#define PLT2_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define PLT2_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define PLT2_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -198,7 +198,7 @@
|
||||
|
||||
#define PLT2_gpio32_dir 1L // 74 2:10B DIOD green
|
||||
#define PLT2_gpio33_dir 0L // 75 2:10C button
|
||||
#define PLT2_gpio34_dir 1L // 142 Ч SCI
|
||||
#define PLT2_gpio34_dir 1L // 142 × SCI
|
||||
|
||||
#define PLT2_gpio48_dir 0L // 88 2:14C button
|
||||
#define PLT2_gpio49_dir 0L // 89 2:14B button
|
||||
@@ -229,7 +229,7 @@
|
||||
#define SHKF_gpio10_dir 0L // 19 2:6C input
|
||||
#define SHKF_gpio11_dir 0L // 20 2:3C input
|
||||
|
||||
#define SHKF_gpio19_dir 1L // 63 — SPI
|
||||
#define SHKF_gpio19_dir 1L // 63 — SPI
|
||||
#define SHKF_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define SHKF_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define SHKF_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -241,7 +241,7 @@
|
||||
|
||||
#define SHKF_gpio32_dir 0L // 74 2:10B input
|
||||
#define SHKF_gpio33_dir 0L // 75 2:10C input
|
||||
#define SHKF_gpio34_dir 1L // 142 — SCI
|
||||
#define SHKF_gpio34_dir 1L // 142 — SCI
|
||||
|
||||
#define SHKF_gpio48_dir 1L // 88 2:14C DIOD red
|
||||
#define SHKF_gpio49_dir 0L // 89 2:14B input
|
||||
@@ -272,7 +272,7 @@
|
||||
#define LOAD_gpio10_dir 0L
|
||||
#define LOAD_gpio11_dir 0L // 20 2:3C res_in 0
|
||||
|
||||
#define LOAD_gpio19_dir 1L // 63 — SPI
|
||||
#define LOAD_gpio19_dir 1L // 63 — SPI
|
||||
#define LOAD_gpio20_dir 0L // 64 2:9B mode 2
|
||||
#define LOAD_gpio21_dir 0L // 65 2:9A mode 4
|
||||
#define LOAD_gpio22_dir 0L // 66 2:12C mode 1
|
||||
@@ -284,7 +284,7 @@
|
||||
|
||||
#define LOAD_gpio32_dir 1L // 74 2:10B DIOD green
|
||||
#define LOAD_gpio33_dir 0L
|
||||
#define LOAD_gpio34_dir 1L // 142 — SCI
|
||||
#define LOAD_gpio34_dir 1L // 142 — SCI
|
||||
|
||||
#define LOAD_gpio48_dir 1L // 88 2:14C DIOD red
|
||||
#define LOAD_gpio49_dir 0L
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Буферы UART разделяются ISR и main. main обрабатывает
|
||||
* законченный RS_Header. Размеры сверять с 16-битной ABI DSP.
|
||||
/* Буферы UART разделяются ISR и main. main обрабатывает
|
||||
* законченный RS_Header. Размеры сверять с 16-битной ABI DSP.
|
||||
*/
|
||||
#ifndef _RS485
|
||||
#define _RS485
|
||||
@@ -32,30 +32,30 @@ typedef struct
|
||||
{
|
||||
volatile struct SCI_REGS *SciRegs;
|
||||
|
||||
unsigned int commnumber; // Номер порта
|
||||
unsigned long RS_Length; // Длина пакета
|
||||
unsigned int commnumber; // Номер порта
|
||||
unsigned long RS_Length; // Длина пакета
|
||||
|
||||
unsigned int *pRS_RecvPtr; // Буфер приема
|
||||
unsigned int *pRS_SendPtr; // Буфер посылки
|
||||
unsigned int *pRS_RecvPtr; // Буфер приема
|
||||
unsigned int *pRS_SendPtr; // Буфер посылки
|
||||
unsigned int *pRecvPtr;
|
||||
|
||||
unsigned int RS_PrevCmd; // Предыдущаа комманда
|
||||
unsigned int RS_Cmd; // Текущаа комманда
|
||||
unsigned int RS_Header[MAX_RECEIVE_LENGTH]; // Заголовок
|
||||
unsigned int flag_TIMEOUT_to_Send; // Флаг ожиданиа таймаута на отсылку
|
||||
unsigned int flag_TIMEOUT_to_Receive; // Флаг ожиданиа таймаута на прием
|
||||
unsigned int RS_DataReady; // Флаг готовности RS данных
|
||||
unsigned int buffer[MAX_SEND_LENGTH]; // Буфер дла отсылки по RS
|
||||
unsigned int RS_PrevCmd; // Предыдущаа комманда
|
||||
unsigned int RS_Cmd; // Текущаа комманда
|
||||
unsigned int RS_Header[MAX_RECEIVE_LENGTH]; // Заголовок
|
||||
unsigned int flag_TIMEOUT_to_Send; // Флаг ожиданиа таймаута на отсылку
|
||||
unsigned int flag_TIMEOUT_to_Receive; // Флаг ожиданиа таймаута на прием
|
||||
unsigned int RS_DataReady; // Флаг готовности RS данных
|
||||
unsigned int buffer[MAX_SEND_LENGTH]; // Буфер дла отсылки по RS
|
||||
|
||||
unsigned int addr_answer; // адрес куда отвечать в режиме ведущего
|
||||
unsigned int addr_recive; // адрес по которому нас запросили
|
||||
unsigned int flag_LEADING; // Флаг режима контроллера (по умолчанию ведомый)
|
||||
unsigned int addr_answer; // адрес куда отвечать в режиме ведущего
|
||||
unsigned int addr_recive; // адрес по которому нас запросили
|
||||
unsigned int flag_LEADING; // Флаг режима контроллера (по умолчанию ведомый)
|
||||
unsigned long RS_RecvLen;
|
||||
unsigned long RS_SLength; // Длина пакета дла посылки
|
||||
unsigned long RS_SendLen; // Количество байт уже передали
|
||||
char RS_SendBlockMode; // Режим передачи
|
||||
char RS_Flag9bit; // дла RS485????????
|
||||
int BS_LoadOK; // Флаг успешности приема блока
|
||||
unsigned long RS_SLength; // Длина пакета дла посылки
|
||||
unsigned long RS_SendLen; // Количество байт уже передали
|
||||
char RS_SendBlockMode; // Режим передачи
|
||||
char RS_Flag9bit; // дла RS485????????
|
||||
int BS_LoadOK; // Флаг успешности приема блока
|
||||
int RS_FlagBegin;
|
||||
int RS_HeaderCnt;
|
||||
int RS_FlagSkiping;
|
||||
@@ -67,39 +67,39 @@ typedef struct
|
||||
extern RS_DATA rs_a,rs_b;
|
||||
|
||||
extern unsigned int
|
||||
RS_Len[70]; /* Действительнаа длина команды (отладочной) + 1 */
|
||||
RS_Len[70]; /* Действительнаа длина команды (отладочной) + 1 */
|
||||
|
||||
interrupt void RSA_RX_Handler(void);
|
||||
interrupt void RSA_TX_Handler(void);
|
||||
interrupt void RSB_RX_Handler(void);
|
||||
interrupt void RSB_TX_Handler(void);
|
||||
|
||||
/* иницилизациа переменных rs_a,rs_b*/
|
||||
/* иницилизациа переменных rs_a,rs_b*/
|
||||
void create_uart_vars(char size_cmd15);
|
||||
|
||||
/** Повторнаа инициализациа последовательного порта, используетса после подвиса */
|
||||
/** Настройка режима приема/передачи */
|
||||
/** Повторнаа инициализациа последовательного порта, используетса после подвиса */
|
||||
/** Настройка режима приема/передачи */
|
||||
void RS_SetBitMode(RS_DATA *rs_arr, int n);
|
||||
|
||||
/** Посылка блока байтов.
|
||||
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
|
||||
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
|
||||
@param buf адрес массива
|
||||
@param len количество байт
|
||||
/** Посылка блока байтов.
|
||||
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
|
||||
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
|
||||
@param buf адрес массива
|
||||
@param len количество байт
|
||||
@see RS_BSend, RS_TRANSMIT_INTR
|
||||
*/
|
||||
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len);
|
||||
|
||||
/** Посылка блока упакованных байтов.
|
||||
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
|
||||
@param buf адрес массива
|
||||
@param len количество 8-битных байт
|
||||
/** Посылка блока упакованных байтов.
|
||||
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
|
||||
@param buf адрес массива
|
||||
@param len количество 8-битных байт
|
||||
@see RS_Send, RS_TRANSMIT_INTR
|
||||
*/
|
||||
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len);
|
||||
|
||||
/** Инициализациа последовательного порта */
|
||||
void setup_uart(char commnumber,unsigned long speed_baud); /* speed_baud - скорость линии в бодах */
|
||||
/** Инициализациа последовательного порта */
|
||||
void setup_uart(char commnumber,unsigned long speed_baud); /* speed_baud - скорость линии в бодах */
|
||||
|
||||
void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop);
|
||||
void RS_SetLineSpeed(RS_DATA *rs_arr, unsigned long speed);
|
||||
@@ -107,17 +107,17 @@ void RS_SetLineSpeed(RS_DATA *rs_arr, unsigned long speed);
|
||||
// Transmit a character from the SCI'
|
||||
#define SCI_send(x,y) x->SciRegs->SCITXBUF=(unsigned char)(y)
|
||||
|
||||
// Ожидание завершениа передачи UART
|
||||
// Ожидание завершениа передачи UART
|
||||
// wait for TRDY =1 for empty state
|
||||
#define RS_Wait4OK(x) while(!(x->SciRegs->SCICTL2.bit.TXEMPTY))
|
||||
|
||||
/** Переключение линии на прием */
|
||||
/** Переключение линии на прием */
|
||||
#define RS_Line_to_receive(x) if(x->commnumber==COM_2) GpioDataRegs.GPBDAT.bit.GPIO34 = 1;
|
||||
|
||||
/** Переключение линии на передачу */
|
||||
/** Переключение линии на передачу */
|
||||
#define RS_Line_to_send(x) if(x->commnumber==COM_2) GpioDataRegs.GPBDAT.bit.GPIO34 = 0;
|
||||
|
||||
/** Разрешение прерываний по получению символа и ошибкам от UART */
|
||||
/** Разрешение прерываний по получению символа и ошибкам от UART */
|
||||
#define enableUARTInt(x) x->SciRegs->SCICTL2.all=2
|
||||
#define enableUARTIntW(x) x->SciRegs->SCICTL2.all=1
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Коды CMD_* являются частью формата обмена с ПК. Новые команды
|
||||
* добавляются без перенумерации существующих значений.
|
||||
/* Коды CMD_* являются частью формата обмена с ПК. Новые команды
|
||||
* добавляются без перенумерации существующих значений.
|
||||
*/
|
||||
#ifndef _BIOS_DSP
|
||||
#define _BIOS_DSP
|
||||
@@ -36,67 +36,67 @@ enum {
|
||||
|
||||
CMD_VECTOR=61,
|
||||
CMD_IMPULSE,
|
||||
/* стандартные команды */
|
||||
/* стандартные команды */
|
||||
CMD_STD=65, CMD_STD_ANS
|
||||
};
|
||||
|
||||
enum {false=0, true};
|
||||
|
||||
|
||||
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
|
||||
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
|
||||
int get_command(RS_DATA *rs_arr);
|
||||
|
||||
/** Стандартный ответ, без параметров */
|
||||
/** Стандартный ответ, без параметров */
|
||||
void Answer(RS_DATA *rs_arr,int n);
|
||||
|
||||
/* начальные установки (не работает)*/
|
||||
/* начальные установки (не работает)*/
|
||||
void init(RS_DATA *rs_arr);
|
||||
|
||||
/**@name Комманды
|
||||
* Комманды, вызываемые через последовательный канал*/
|
||||
/**@name Комманды
|
||||
* Комманды, вызываемые через последовательный канал*/
|
||||
//@{
|
||||
|
||||
/** Инициировать загрузку блока.
|
||||
Настраивает прием блока данных */
|
||||
/** Инициировать загрузку блока.
|
||||
Настраивает прием блока данных */
|
||||
void initload(RS_DATA *rs_arr);
|
||||
|
||||
/** Загрузка блока.
|
||||
Вызываетса после загрузки блока через RS */
|
||||
/** Загрузка блока.
|
||||
Вызываетса после загрузки блока через RS */
|
||||
void load(RS_DATA *rs_arr);
|
||||
|
||||
/** Выполнить программу в формате Serial Boot.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес программы беретса из заголовка и
|
||||
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
|
||||
/** Выполнить программу в формате Serial Boot.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес программы беретса из заголовка и
|
||||
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
|
||||
@see load */
|
||||
void run (RS_DATA *rs_arr);
|
||||
|
||||
/** Прочитать ачейку памати */
|
||||
/** Прочитать ачейку памати */
|
||||
void peek(RS_DATA *rs_arr);
|
||||
|
||||
/** Записать в ачейку памати */
|
||||
/** Записать в ачейку памати */
|
||||
void poke(RS_DATA *rs_arr);
|
||||
|
||||
/** Передать блок памати */
|
||||
/** Передать блок памати */
|
||||
void upload(RS_DATA *rs_arr);
|
||||
|
||||
/** Прошить XILINX.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
|
||||
так же смотрит магическое слово в начале прошивки
|
||||
/** Прошить XILINX.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
|
||||
так же смотрит магическое слово в начале прошивки
|
||||
@see load */
|
||||
void xflash(RS_DATA *rs_arr);
|
||||
|
||||
/** Прошить TMS.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
|
||||
/** Прошить TMS.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
|
||||
@see load */
|
||||
void tflash(RS_DATA *rs_arr);
|
||||
|
||||
|
||||
/* расширенные команды дла биоса */
|
||||
/* расширенные команды дла биоса */
|
||||
void extendbios(RS_DATA *rs_arr);
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
/* Заводские калибровки по версии BALSAM и типу платы. Здесь
|
||||
* определяются массивы, а не только extern; не дублировать подключение.
|
||||
/* Заводские калибровки по версии BALSAM и типу платы. Здесь
|
||||
* определяются массивы, а не только extern; не дублировать подключение.
|
||||
*/
|
||||
#if BALSAM == 166 //-------------------------------------------------------------
|
||||
int def_cal[][8] = {
|
||||
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
4936, 4877, 4972, 4857, 1960, 1920, 2610, 2570, // Борт 0
|
||||
4876, 5005, 4876, 4847, 1950, 1965, 2600, 2615, // Борт 1
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
4936, 4877, 4972, 4857, 1960, 1920, 2610, 2570, // Борт 0
|
||||
4876, 5005, 4876, 4847, 1950, 1965, 2600, 2615, // Борт 1
|
||||
|
||||
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
|
||||
3820, 3790, 3505, 3380, 1718, 673, 854, 14, // Борт 0
|
||||
3835, 3785, 3522, 3332, 1697, 653, 860, 17, // Борт 1
|
||||
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
|
||||
3820, 3790, 3505, 3380, 1718, 673, 854, 14, // Борт 0
|
||||
3835, 3785, 3522, 3332, 1697, 653, 860, 17, // Борт 1
|
||||
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
1281, 1272, 0, 0, 2049, 2050, 2749, 2750 };
|
||||
#endif //---------------------------------------------------------------------
|
||||
|
||||
#if BALSAM == 165 //-------------------------------------------------------------
|
||||
int def_cal[][8] = {
|
||||
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
5130, 4960, 4925, 5070, 1881, 1881, 2506, 2516, // Борт 0
|
||||
5020, 5040, 4950, 5030, 1871, 1879, 2507, 2514, // Борт 1
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
5130, 4960, 4925, 5070, 1881, 1881, 2506, 2516, // Борт 0
|
||||
5020, 5040, 4950, 5030, 1871, 1879, 2507, 2514, // Борт 1
|
||||
|
||||
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
|
||||
3890, 3865, 5100, 4850, 1730, 675, 854, 14, // Борт 0
|
||||
3845, 3800, 3250, 3100, 1044, 0, 860, 17, // Борт 1
|
||||
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
|
||||
3890, 3865, 5100, 4850, 1730, 675, 854, 14, // Борт 0
|
||||
3845, 3800, 3250, 3100, 1044, 0, 860, 17, // Борт 1
|
||||
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
1289, 1280, 0, 0, 2073, 2071, 2773, 2771 };
|
||||
#endif //---------------------------------------------------------------------
|
||||
|
||||
#if BALSAM == 164 //-------------------------------------------------------------
|
||||
int def_cal[][8] = {
|
||||
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
7573, 7573, 7573, 7573, 1979, 1888, 2592, 2513, // Борт 0
|
||||
7573, 7573, 7573, 7573, 1970, 1907, 2584, 2558, // Борт 1
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
7573, 7573, 7573, 7573, 1979, 1888, 2592, 2513, // Борт 0
|
||||
7573, 7573, 7573, 7573, 1970, 1907, 2584, 2558, // Борт 1
|
||||
|
||||
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
|
||||
3920, 3905, 3300, 3220, 1015, 0, 854, 14, // Борт 0
|
||||
3835, 3785, 5100, 4600, 1750, 680, 860, 17, // Борт 1
|
||||
// УМП UA UC IA IC 20mA O 4mA O 20mA I 4mA I
|
||||
3920, 3905, 3300, 3220, 1015, 0, 854, 14, // Борт 0
|
||||
3835, 3785, 5100, 4600, 1750, 680, 860, 17, // Борт 1
|
||||
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
1266, 1267, 0, 0, 2063, 2040, 2678, 2655 };
|
||||
#endif //---------------------------------------------------------------------
|
||||
|
||||
@@ -51,15 +51,15 @@
|
||||
#if PXXXXX == 1 //-------------------------------------------------------------
|
||||
int def_cal[][6] = {
|
||||
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Борт 0
|
||||
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Борт 1
|
||||
// Силовой UA1 UB1 UA2 UB2 300 1 300 2 400 1 400 2
|
||||
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Борт 0
|
||||
0400, 0400, 0400, 0400, 1950, 1950, 2600, 2600, // Борт 1
|
||||
|
||||
// УМП UA UC IA IC 20mA 4mA
|
||||
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Борт 0
|
||||
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Борт 1
|
||||
// УМП UA UC IA IC 20mA 4mA
|
||||
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Борт 0
|
||||
0400, 0400, 4800, 4800, 0, 0, 0, 0, // Борт 1
|
||||
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
// ВЭП 380Ф1 380Ф2 300 1 300 2 400 1 400 2
|
||||
1270, 1270, 0, 0, 1950, 1950, 2600, 2600 };
|
||||
#endif //---------------------------------------------------------------------
|
||||
*/
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
#ifndef CAN_TELEMETRY_IMPL_H /* Реализация включается только в ecan.c после аппаратных типов и переменных штатного передатчика. */
|
||||
#define CAN_TELEMETRY_IMPL_H /* Не допускает повторного определения состояния и функций в одной единице трансляции. */
|
||||
#define CAN_HEARTBEAT_ADDR 0x0100U /* Как в варианте 167, отдельный адрес heartbeat находится вне R0–R127 и служебной области логгера 0x1000. */
|
||||
#define CAN_HEARTBEAT_TICKS ((Uint32)READY_FREQ) /* READY_FREQ задаёт частоту Timer1 в герцах; это ровно одна секунда его тактов. */
|
||||
#define CAN_REFRESH_TICKS ((Uint32)READY_FREQ * 13UL / 10UL) /* Тринадцать десятых секунды дают период повторения данных 1,3 с независимо от числа циклов main. */
|
||||
#define CAN_SCAN_TICKS ((Uint32)READY_FREQ * CANPOWSE / 1000UL) /* Существующие CANPOWSE=20 мс ограничивают задержку обнаружения обновлений, но не скорость выдачи уже готовой очереди. */
|
||||
#define CAN_ACK_TICKS ((Uint32)READY_FREQ / 10UL) /* Программная страховка через 100 мс отменяет зависший TX, если аппаратный timeout IRQ не был обработан. */
|
||||
static Uint32 can_last_hi[ANSWER_LEN], can_last_lo[ANSWER_LEN], can_last_at[ANSWER_LEN]; /* Последний подтверждённый пакет и время ACK хранятся отдельно для каждого начального адреса R0–R127. */
|
||||
static unsigned int can_valid[8], can_cursor[2], can_stream; /* Восемь 16-битных масок покрывают 128 адресов; два курсора и очередность обеспечивают справедливость потоков. */
|
||||
static Uint32 can_tx_at, can_failed_at, can_heartbeat_at, can_scan_at; /* Беззнаковые отметки Timer1 поддерживают вычитание через переполнение 32-битного счётчика. */
|
||||
static unsigned int can_backoff, can_started, can_heartbeat_count, can_heartbeat_due, can_scan_due; /* Отделяет секундную паузу после ошибки, старт часов, heartbeat и незавершённое сканирование масок. */
|
||||
static int can_pending_addr; /* Значение -1 обозначает heartbeat, который не должен индексировать кэш технологических регистров. */
|
||||
static volatile unsigned int can_tx_failed; /* Timeout ISR отмечает ошибку текущего mailbox до обработки ACK в основном цикле. */
|
||||
static Uint32 CAN_millis(void) /* Возвращает согласованный счётчик Timer1; при READY_FREQ=1000 один такт соответствует миллисекунде. */
|
||||
{ /* Чтение 32 бит защищается отдельно на 16-битном C28x без ожидания аппаратуры. */
|
||||
unsigned int saved = __disable_interrupts(); /* Сохраняет исходное состояние IRQ, включая вызовы из уже защищённой отправки. */
|
||||
Uint32 now = CpuTimer1.InterruptCount; /* Счётчик обновляют оба существующих обработчика Timer1 для пульта и измерительной платы. */
|
||||
__restore_interrupts(saved); /* Немедленно возвращает прежнюю маску прерываний. */
|
||||
return now; /* Наружу передаётся один целостный снимок времени. */
|
||||
} /* Длительные расчёты масок выполняются с разрешёнными прерываниями. */
|
||||
static void CAN_telemetry_init(void) /* Сбрасывает программное состояние при каждом InitCan, в том числе после запуска с грязной RAM. */
|
||||
{ /* Крупные массивы не очищаются, потому что их элементы недоступны без valid-бита. */
|
||||
unsigned int i; /* Перебирает восемь масок достоверности кэша. */
|
||||
for (i = 0U; i < 8U; ++i) can_valid[i] = 0U; /* Первый пакет каждого разрешённого адреса обязательно передаётся после запуска. */
|
||||
can_cursor[0] = can_cursor[1] = can_stream = 0U; /* Обе маски начинают обход с R0; далее потоки чередуются после реально поставленного кадра. */
|
||||
can_backoff = can_started = can_heartbeat_count = can_heartbeat_due = 0U; /* Новые часы и секундный heartbeat начинают отсчёт при первом обслуживании main. */
|
||||
can_scan_due = 1U; /* Первый снимок данных выдаётся сразу, без ожидания периода 1,3 с. */
|
||||
can_pending_addr = -1; can_tx_failed = 0U; wait = 0; /* Исключает подтверждение кадра и ошибку из предыдущего запуска программы. */
|
||||
} /* Сброс не меняет аппаратные CAN ID, маски регистров и настройки EEPROM. */
|
||||
static int CAN_tx_ready(Uint32 now) /* Обслуживает завершение штатного mailbox 0; вызывающий код уже запретил IRQ на короткое время. */
|
||||
{ /* Возвращает готовность без ожидания ACK, CANAA или освобождения шины в цикле. */
|
||||
if ((ECanaRegs.CANTRS.all | ECanaRegs.CANTRR.all) & 1UL) { /* Бит 0 относится только к штатному TX; служебный mailbox 2 не перезаписывается. */
|
||||
if (wait && !can_tx_failed && (ECanaRegs.CANTRS.all & 1UL) && now - can_tx_at >= CAN_ACK_TICKS) { /* Программный timeout страхует потерянное аппаратное прерывание спустя 100 мс. */
|
||||
can_tx_failed = 1U; ++CanTimeOutErrorTR; /* Отмечает ошибку ровно один раз, пока этот запрос ещё ожидает завершения отмены. */
|
||||
EALLOW; ECanaRegs.CANTOC.all &= ~1UL; EDIS; /* Снимает источник аппаратного timeout только для mailbox 0, сохраняя остальные биты контроля. */
|
||||
ECanaRegs.CANTRR.all = 1UL; /* Запрашивает аппаратную отмену без блокирующего ожидания CANAA. */
|
||||
} /* Данные занятого mailbox остаются неизменными до аппаратного освобождения. */
|
||||
return 0; /* Текущий адрес и признак готовности сканирования сохраняются для повторного обслуживания. */
|
||||
} /* Только свободный mailbox позволяет обработать завершение предыдущей передачи. */
|
||||
if (wait) { /* ACK или ошибка относятся ровно к одному ранее запущенному кадру. */
|
||||
if ((ECanaRegs.CANTA.all & 1UL) && !can_tx_failed) { /* Только успешный ACK позволяет подавлять повтор неизменившихся данных. */
|
||||
if (can_pending_addr >= 0) { /* Heartbeat не занимает ограниченный технологический кэш. */
|
||||
can_last_hi[can_pending_addr] = ECanaMboxes.MBOX0.MDH.all; /* Запоминает действительно доставленные адрес и первое слово из неизменявшегося mailbox. */
|
||||
can_last_lo[can_pending_addr] = ECanaMboxes.MBOX0.MDL.all; /* Сохраняет второе и третье слова того же подтверждённого кадра. */
|
||||
can_last_at[can_pending_addr] = now; /* Отсчитывает повтор через 1,3 с от последнего подтверждения, а не от неудачной попытки. */
|
||||
can_valid[can_pending_addr >> 4] |= 1U << (can_pending_addr & 15); /* Устанавливает один бит достоверности начального адреса пакета. */
|
||||
} /* Перекрывающиеся пакеты разных масок имеют независимые начальные адреса. */
|
||||
} else { /* Отмена, ошибка или свободный TX без CANAA не подтверждают доставку текущих данных. */
|
||||
can_failed_at = now; can_backoff = 1U; /* Ограничивает новые попытки одной секундой при отсутствии получателя и CAN ACK. */
|
||||
} /* Старый подтверждённый кэш сохраняется, поэтому неудачная передача не теряет обновление. */
|
||||
wait = 0; can_tx_failed = 0U; can_pending_addr = -1; /* Завершение обрабатывается один раз даже без отдельного CANAA после отмены. */
|
||||
} /* Проверяет паузу после ошибки до подготовки следующего кадра. */
|
||||
if (can_backoff && now - can_failed_at < CAN_HEARTBEAT_TICKS) return 0; /* Во время секундной паузы данные и heartbeat остаются ожидающими. */
|
||||
can_backoff = 0U; /* Снятие паузы не требует изменения таймеров технологических данных. */
|
||||
return 1; /* Mailbox свободен и может принять один новый актуальный кадр. */
|
||||
} /* Чужие mailbox, аппаратный CAN ID и получаемые команды не меняются. */
|
||||
int CAN_send(int Port, int data[], int Addr) /* Возвращает 0 при занятости, 1 после запуска TX и 2 при неизменном пакете до срока повторения. */
|
||||
{ /* Снимок данных и запуск mailbox защищаются одним коротким запретом IRQ. */
|
||||
Uint32 hiword, loword, now; /* Ровно два 32-битных поля соответствуют восьми октетам существующего формата BALZAM. */
|
||||
unsigned int saved = __disable_interrupts(); /* Исключает разрыв трёхсловного снимка и гонку запуска с timeout ISR. */
|
||||
(void)Port; now = CAN_millis(); /* Как прежний передатчик, использует eCAN-A; время берётся из общего Timer1. */
|
||||
if (!CAN_tx_ready(now)) { __restore_interrupts(saved); return 0; } /* При занятости ничего не перезаписывает и не подтверждает данные программно. */
|
||||
if (Addr == CAN_HEARTBEAT_ADDR) { /* Отдельный пакет состояния узла не обращается к data=NULL или к R256. */
|
||||
hiword = 0xE0000000UL | ((Uint32)CAN_HEARTBEAT_ADDR << 16) | can_heartbeat_count; /* Сохраняет маркер BALZAM и передаёт циклический 16-битный счётчик секунд. */
|
||||
loword = ((Uint32)(unsigned int)Mode << 16) | (unsigned int)Desk; /* Два следующих слова сообщают аппаратный Mode и тип платы Desk. */
|
||||
can_pending_addr = -1; /* Успешный heartbeat не подтверждает ни один технологический пакет. */
|
||||
} else { /* Первый снимок, изменение любого слова либо истечение периода вызывают одинаковую отправку данных. */
|
||||
if (Addr < 0 || Addr >= ANSWER_LEN) { __restore_interrupts(saved); return 2; } /* Не допускает чтения за картой R0–R127 и позволяет планировщику пропустить неверный адрес. */
|
||||
hiword = 0xE0000000UL | ((Uint32)Addr << 16) | ((Uint32)data[Addr] & 0xFFFFUL); /* Первый регистр занимает младшие шестнадцать бит старшей половины CAN-данных. */
|
||||
loword = Addr + 1 < ANSWER_LEN ? ((Uint32)data[Addr + 1] & 0xFFFFUL) << 16 : 0UL; /* Отсутствующее второе слово у конца карты заменяется нулём. */
|
||||
if (Addr + 2 < ANSWER_LEN) loword |= (Uint32)data[Addr + 2] & 0xFFFFUL; /* Третье слово дополняется только в пределах реального массива регистров. */
|
||||
if ((can_valid[Addr >> 4] & (1U << (Addr & 15))) && can_last_hi[Addr] == hiword && can_last_lo[Addr] == loword && now - can_last_at[Addr] < CAN_REFRESH_TICKS) { /* Совпадение всех слов подавляет передачу только до индивидуального срока 1,3 с. */
|
||||
__restore_interrupts(saved); return 2; /* Не сдвигает время подтверждения: неизменные данные всё равно повторятся по таймеру. */
|
||||
} /* Изменение данных не ждёт окончания периода повторения. */
|
||||
can_pending_addr = Addr; /* Подготовленное состояние попадёт в кэш только после успешного аппаратного ACK. */
|
||||
} /* Для heartbeat и данных используется один и тот же безопасный жизненный цикл TX. */
|
||||
ECanaRegs.CANTA.all = 1UL; ECanaRegs.CANAA.all = 1UL; /* Очищает старые ACK и отмену mailbox 0 записью единиц в соответствующие биты eCAN. */
|
||||
ECanaMboxes.MBOX0.MDH.all = hiword; ECanaMboxes.MBOX0.MDL.all = loword; /* Записывает замороженный трёхсловный снимок без последующей подмены во время ожидания ACK. */
|
||||
EALLOW; ECanaRegs.CANTOC.all &= ~1UL; ECanaRegs.CANTSC = 0UL; ECanaRegs.CANTOC.all |= 1UL; EDIS; /* Перезапускает аппаратный timeout только для нового штатного запроса TX. */
|
||||
can_tx_at = now; can_tx_failed = 0U; wait = 1; /* Сохраняет момент запуска и принадлежность будущего ACK до разрешения прерываний. */
|
||||
ECanaRegs.CANTRS.all = 1UL; /* Однократно запускает аппаратную передачу в штатном mailbox 0. */
|
||||
led1_toggle(); __restore_interrupts(saved); /* Сохраняет индикацию передачи и возвращает исходную маску IRQ без ожидания шины. */
|
||||
return 1; /* Подтверждает только постановку кадра, оставляя окончательную доставку аппаратному ACK. */
|
||||
} /* Формат CAN ID, порядок слов и служебный mailbox логгера остаются прежними. */
|
||||
void CAN_heartbeat_service(void) /* Обслуживает независимый секундный heartbeat и завершение ранее запущенного TX. */
|
||||
{ /* Вызывается из main и не зависит от Cancount, масок данных или признака CanGO. */
|
||||
Uint32 now = CAN_millis(), elapsed, seconds; /* Время Timer1 учитывает задержки main без накопления дрейфа секундной сетки. */
|
||||
unsigned int saved = __disable_interrupts(); /* Короткая обработка ACK синхронизируется с timeout ISR. */
|
||||
CAN_tx_ready(now); __restore_interrupts(saved); /* Сохраняет успешное завершение данных даже тогда, когда новых пакетов пока нет. */
|
||||
if (!can_started) { can_started = 1U; can_heartbeat_at = can_scan_at = now; } /* Первый heartbeat появляется спустя полную секунду от начала обслуживания текущего запуска. */
|
||||
elapsed = now - can_heartbeat_at; /* Беззнаковое вычитание корректно при переполнении 32-битного счётчика. */
|
||||
if (elapsed >= CAN_HEARTBEAT_TICKS) { /* Формирует новую отметку на каждой секундной границе Timer1. */
|
||||
seconds = elapsed / CAN_HEARTBEAT_TICKS; can_heartbeat_at += seconds * CAN_HEARTBEAT_TICKS; /* После паузы main оставляет последнее значение без очереди устаревших кадров. */
|
||||
can_heartbeat_count = (unsigned int)((can_heartbeat_count + seconds) & 0xFFFFUL); can_heartbeat_due = 1U; /* Счётчик heartbeat циклически проходит диапазон 0..65535 секунд. */
|
||||
} /* Занятый передатчик не теряет ожидающий heartbeat. */
|
||||
if (can_heartbeat_due && CAN_send(0, 0, CAN_HEARTBEAT_ADDR) == 1) can_heartbeat_due = 0U; /* Приоритетно ставит один актуальный heartbeat после освобождения mailbox. */
|
||||
} /* Следующий повтор heartbeat планируется секундной сеткой, а не длительностью обхода масок. */
|
||||
void CAN_telemetry_service(void) /* Передаёт изменившиеся данные и повторяет каждый подтверждённый пакет через 1,3 с. */
|
||||
{ /* Фоновое обслуживание не ждёт CAN ACK и выдаёт готовую очередь по мере освобождения mailbox. */
|
||||
Uint32 now; unsigned int attempt, stream, pass, address, cursor; int result; /* Локальные счётчики ограничивают обход двумя потоками и конечной картой из 128 регистров. */
|
||||
CAN_heartbeat_service(); now = CAN_millis(); /* Секундный heartbeat получает приоритет перед обычными данными независимо от настройки потоков. */
|
||||
if (now - can_scan_at >= CAN_SCAN_TICKS) { can_scan_at += (now - can_scan_at) / CAN_SCAN_TICKS * CAN_SCAN_TICKS; can_scan_due = 1U; } /* Сохраняет сетку обнаружения изменений с интервалом 20 мс без накопления дрейфа после задержек main. */
|
||||
if (!can_scan_due) return; /* При неизменных данных main не повторяет полный обход масок на каждой итерации. */
|
||||
for (attempt = 0U; attempt < 2U; ++attempt) { /* После успешной постановки чередует потоки, исключая голодание медленной маски. */
|
||||
stream = (can_stream + attempt) & 1U; cursor = can_cursor[stream]; /* Начинает следующий поиск после последнего принятого кадра данного потока. */
|
||||
if (!Cancount[stream]) continue; /* Ноль сохраняет штатное отключение соответствующего потока; ненулевой период заменяется общим повтором 1,3 с. */
|
||||
for (pass = 0U; pass < 2U; ++pass) { /* Два конечных прохода реализуют циклический обход без зависания на пустой маске. */
|
||||
for (address = 0U; address < ANSWER_LEN;) { /* Формирует те же трёхсловные группы от первого разрешённого адреса маски. */
|
||||
if (!(Maska[stream][address >> 4] & (1U << (address & 15)))) { ++address; continue; } /* Пропускает запрещённые регистры и гарантированно продвигает поиск. */
|
||||
if ((pass == 0U && address >= cursor) || (pass == 1U && address < cursor)) { /* Сначала рассматривает хвост карты после курсора, затем оставшееся начало. */
|
||||
result = CAN_send(0, modbus, address); /* Сравнивает полный снимок с подтверждённым кэшем и индивидуальным временем повтора. */
|
||||
if (result != 2) { /* Только неизменный пакет до срока допускает переход к следующему кандидату в этом же вызове. */
|
||||
if (result == 1) { can_cursor[stream] = address + 3U < ANSWER_LEN ? address + 3U : 0U; can_stream = stream ^ 1U; } /* Продвигает курсор лишь после постановки кадра и отдаёт следующий свободный слот другому потоку. */
|
||||
return; /* При занятости сохраняет адрес; при постановке продолжит готовую очередь следующей итерацией main после ACK. */
|
||||
} /* Пропущенные неизменные пакеты не занимают физическую шину. */
|
||||
} /* Завершает проверку одного допустимого начального адреса. */
|
||||
address += 3U; /* Как прежний протокол, один кадр покрывает три последовательных регистра независимо от разреженности маски. */
|
||||
} /* Максимальный адрес ограничен размером реальной технологической карты. */
|
||||
} /* После обхода обеих частей все пакеты потока рассмотрены ровно один раз. */
|
||||
} /* Ни один разрешённый пакет не требует немедленной передачи. */
|
||||
can_scan_due = 0U; /* Следующее плановое сканирование произойдёт через 20 мс; выдача готовой очереди этим ожиданием не задерживается. */
|
||||
} /* Период 1,3 с относится к каждому пакету, а не к одному кадру всей маски за один период. */
|
||||
#endif /* Закрывает единственную реализацию фоновой телеметрии текущей прошивки 166. */
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Собственный, общий и специальные адреса последовательного обмена.
|
||||
* main задаёт адреса через set_cntrl_addr до начала обмена.
|
||||
/* Собственный, общий и специальные адреса последовательного обмена.
|
||||
* main задаёт адреса через set_cntrl_addr до начала обмена.
|
||||
*/
|
||||
#ifndef _CNTRL_ADR
|
||||
#define _CNTRL_ADR
|
||||
@@ -8,22 +8,22 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** адрес контроллера дла посылки всем АИНам */
|
||||
/** адрес контроллера дла посылки всем АИНам */
|
||||
extern int ADDR_FOR_ALL;
|
||||
|
||||
/** адрес контроллера дла посылки ответа */
|
||||
/** адрес контроллера дла посылки ответа */
|
||||
extern const int ADDR_ANSWER;
|
||||
|
||||
/** адреса терминала дла посылки ответа */
|
||||
/** адреса терминала дла посылки ответа */
|
||||
extern const int ADDR_TERMINAL;
|
||||
|
||||
/* Адрес контроллера */
|
||||
/* Адрес контроллера */
|
||||
extern int CNTRL_ADDR;
|
||||
|
||||
/* Универсальный адрес контроллера */
|
||||
/* Универсальный адрес контроллера */
|
||||
extern const int CNTRL_ADDR_UNIVERSAL;
|
||||
|
||||
/** Установка адреса контроллера дла прошивки */
|
||||
/** Установка адреса контроллера дла прошивки */
|
||||
void set_cntrl_addr (int cntrl_addr,int cntrl_addr_for_all);
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Интерфейсы CRC. Различать буфер кадра и массив слов EEPROM;
|
||||
* результат зависит от порядка обработки байтов.
|
||||
/* Интерфейсы CRC. Различать буфер кадра и массив слов EEPROM;
|
||||
* результат зависит от порядка обработки байтов.
|
||||
*/
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned char byte;
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* Телеметрия eCAN и фоновая выдача ответов логгера.
|
||||
* UMP_CAN_service вызывается из main, не из приёмного IRQ.
|
||||
/* Телеметрия eCAN и фоновая выдача ответов логгера.
|
||||
* UMP_CAN_service вызывается из main, не из приёмного IRQ.
|
||||
*/
|
||||
void InitCan(int Port, int DevNum);
|
||||
int CAN_send(int Port, int data[], int Addr); /* 0: занят, 1: кадр поставлен, 2: подтверждённые данные не изменились и 1,3 с ещё не прошли. */
|
||||
void CAN_heartbeat_service(void); /* Планирует отдельный heartbeat по Timer1 с периодом одна секунда. */
|
||||
void CAN_telemetry_service(void); /* В main обслуживает heartbeat, изменения данных и повтор каждого разрешённого пакета через 1,3 с. */
|
||||
void CAN_send(int Port, int data[], int Addr);
|
||||
extern int CAN_input_data[];
|
||||
|
||||
/* Неблокирующая передача ответов логгера отдельным CAN mailbox. */
|
||||
/* Неблокирующая передача ответов логгера отдельным CAN mailbox. */
|
||||
void UMP_CAN_service(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Коэффициенты и изменяемая история фильтра. Каждый независимый
|
||||
* канал должен иметь отдельный экземпляр FILTERBAT.
|
||||
/* Коэффициенты и изменяемая история фильтра. Каждый независимый
|
||||
* канал должен иметь отдельный экземпляр FILTERBAT.
|
||||
*/
|
||||
#ifndef _FILTER_BAT2
|
||||
#define _FILTER_BAT2
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
#ifndef BALSAM_FIRMWARE_INFO_H /* Исключает повторное объявление адаптера паспорта при совместном подключении RS и CAN. */
|
||||
#define BALSAM_FIRMWARE_INFO_H /* Обозначает единственный интерфейс firmware-info v1 приложения 166. */
|
||||
#include "firmware_info_static.h" /* Использует тот же статический 12-словный контракт общей библиотеки, который подключён в 167. */
|
||||
#define FIRMWARE_INFO_ADDRESS 0x1200U /* Адрес firmware-info v1 из протокола 167 и SetGUI; не пересекается с логгером 0x1000..0x117B. */
|
||||
#define FIRMWARE_INFO_END (FIRMWARE_INFO_ADDRESS + FIRMWARE_INFO_STATIC_COUNT) /* Исключающая верхняя граница 0x120C охватывает ровно двенадцать 16-битных регистров. */
|
||||
static unsigned int firmware_info_range(unsigned int address, unsigned int count) /* Проверяет только чтение внутри паспорта без переполнения 16-битной суммы адреса и длины. */
|
||||
{ /* Вычитание выполняется после проверки адреса, поэтому не переполняется на C28x. */
|
||||
return address >= FIRMWARE_INFO_ADDRESS && address < FIRMWARE_INFO_END && count > 0U && count <= FIRMWARE_INFO_END - address; /* Разрешает полное и частичное чтение, запрещая нулевую длину и пересечение границы паспорта. */
|
||||
} /* Не меняет правила остальных технологических и служебных адресов. */
|
||||
#endif /* Завершает адаптер, не добавляя изменяемое состояние или параметры EEPROM. */
|
||||
@@ -1,4 +1,4 @@
|
||||
/* Интерфейс канала индикации. Он не формирует START_DPTB
|
||||
* и не должен использоваться вместо функций управления нагрузкой.
|
||||
/* Интерфейс канала индикации. Он не формирует START_DPTB
|
||||
* и не должен использоваться вместо функций управления нагрузкой.
|
||||
*/
|
||||
void kanal_Send(int adr, long dat, int dot);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Контракт логгера с SetGUI: размер записи, версия и адреса.
|
||||
* Чтение целого блока защищается от IRQ на стороне RS/CAN обработчика.
|
||||
/* Контракт логгера с SetGUI: размер записи, версия и адреса.
|
||||
* Чтение целого блока защищается от IRQ на стороне RS/CAN обработчика.
|
||||
*/
|
||||
#ifndef _LOG_TO_MEM
|
||||
#define _LOG_TO_MEM
|
||||
@@ -8,11 +8,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Определениa длa работы логгера */
|
||||
/* Определениa длa работы логгера */
|
||||
#define LOG_PAGE_START 0x0200000
|
||||
#define LOG_PAGE_LEN 0xFA00
|
||||
|
||||
extern int no_write, never_write; // Флаги, чтобы не писать (если что)
|
||||
extern int no_write, never_write; // Флаги, чтобы не писать (если что)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@@ -25,25 +25,22 @@ typedef struct
|
||||
|
||||
extern LOG Log;
|
||||
|
||||
/* Запись словa в памать, где логи лежат */
|
||||
/* Запись словa в памать, где логи лежат */
|
||||
#define Log_to_mem(x) *(int *)(Log.Adres++) = x
|
||||
|
||||
/* Проверка границы памати дла логов */
|
||||
/* Проверка границы памати дла логов */
|
||||
#define Test_mem_limit(x) if(Log.Adres > (Log.Finis - (x))) Log.Adres = Log.Start
|
||||
|
||||
/* Очистка памати (обнуление) */
|
||||
/* Очистка памати (обнуление) */
|
||||
void clear_mem();
|
||||
|
||||
/* Логгер УМП: отдельное адресное пространство Modbus, без изменения
|
||||
* 128 технологических регистров. Два банка по 800 записей:
|
||||
* текущий кольцевой журнал и зафиксированный фрагмент отключения. */
|
||||
/* Логгер УМП: отдельное адресное пространство Modbus, без изменения
|
||||
* 128 технологических регистров. Два банка по 800 записей:
|
||||
* текущий кольцевой журнал и зафиксированный фрагмент отключения. */
|
||||
#define UMP_LOG_BASE 0x1000U
|
||||
#define UMP_LOG_DATA 0x1010U
|
||||
/* Формат v4 совпадает с 167: 12 слов по 16 бит содержат выбранные сигналы и нулевой резерв для парной передачи CAN. */
|
||||
#define UMP_LOG_WORDS 12U
|
||||
#define UMP_LOG_WORDS 40U
|
||||
#define UMP_LOG_CAPACITY 800U
|
||||
/* Онлайн-окно вмещает 120 слов полезных данных: при формате v4 это десять полных записей. */
|
||||
#define UMP_LOG_LIVE_RECORDS (120U / UMP_LOG_WORDS)
|
||||
#define UMP_LOG_LIVE 0x1100U
|
||||
extern unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
void ump_log_tick(void);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Частоты и состояния измерений. READY в 166 — счётчик до нуля.
|
||||
* READY_FREQ задаёт таймер СИФУ, DAC_FREQ — расчёт ЦАП.
|
||||
/* ×àñòîòû è ñîñòîÿíèÿ èçìåðåíèé. READY â 166 — ñ÷¸ò÷èê äî íóëÿ.
|
||||
* READY_FREQ çàäà¸ò òàéìåð ÑÈÔÓ, DAC_FREQ — ðàñ÷¸ò ÖÀÏ.
|
||||
*/
|
||||
#ifndef _MEASURE
|
||||
#define _MEASURE
|
||||
@@ -65,14 +65,14 @@ typedef union
|
||||
#define NOER 0xE000//C
|
||||
#define EROR 0x01FF
|
||||
|
||||
#define READY_FREQ (500.0 * 2)// Гц
|
||||
#define BLINK_FREQ 2 // Гц
|
||||
#define READY_FREQ (500.0 * 2)// Ãö
|
||||
#define BLINK_FREQ 2 // Ãö
|
||||
#define BLINK_TIME (READY_FREQ / BLINK_FREQ)
|
||||
|
||||
#define CANPOWSE 20
|
||||
|
||||
#define ADC_FREQ 3750 //3885.0//777//2000//20000 //777 //3885 // Гц (777*5)
|
||||
#define DAC_FREQ 200//5 // Гц
|
||||
#define ADC_FREQ 3750 //3885.0//777//2000//20000 //777 //3885 // Ãö (777*5)
|
||||
#define DAC_FREQ 200//5 // Ãö
|
||||
|
||||
#define LOAD_TIME 30//15 // sec
|
||||
|
||||
@@ -87,23 +87,23 @@ extern unsigned int Caliber_time;
|
||||
|
||||
#define ZERO 27
|
||||
|
||||
#define Cooling 5 // (°С) Гистерезис по снатию перегрева
|
||||
#define Cooling 5 // (°Ñ) Ãèñòåðåçèñ ïî ñíàòèþ ïåðåãðåâà
|
||||
|
||||
#define COSPi6 0.86602540378443864676372317075294
|
||||
|
||||
#define RADIX2 1.4142135623730950488016887242097
|
||||
|
||||
#define POWER_380 0 // питание 380В
|
||||
#define POWER_38O 1 // питание 380В
|
||||
#define POWER_380 0 // ïèòàíèå 380Â
|
||||
#define POWER_38O 1 // ïèòàíèå 380Â
|
||||
|
||||
#define CURRENT 2 // ток
|
||||
#define VOLTAGE 3 // напражение
|
||||
#define CURRENT 2 // òîê
|
||||
#define VOLTAGE 3 // íàïðàæåíèå
|
||||
|
||||
#define POWER_31 4 // питание 31В
|
||||
#define POWER_27 5 // питание 24В
|
||||
#define POWER_24 6 // питание 24В
|
||||
#define POWER_15 7 // питание 15В
|
||||
#define TERMO_AD 8 // термодатчик мелкосхема
|
||||
#define POWER_31 4 // ïèòàíèå 31Â
|
||||
#define POWER_27 5 // ïèòàíèå 24Â
|
||||
#define POWER_24 6 // ïèòàíèå 24Â
|
||||
#define POWER_15 7 // ïèòàíèå 15Â
|
||||
#define TERMO_AD 8 // òåðìîäàò÷èê ìåëêîñõåìà
|
||||
|
||||
extern int TPL_CANS,tpl_cans;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Технологические регистры и Modbus. ANSWER_LEN ограничивает
|
||||
* массив modbus; адресом логгера 0x1000 индексировать его нельзя.
|
||||
/* Технологические регистры и Modbus. ANSWER_LEN ограничивает
|
||||
* массив modbus; адресом логгера 0x1000 индексировать его нельзя.
|
||||
*/
|
||||
#ifndef MESSAGE_H
|
||||
#define MESSAGE_H
|
||||
@@ -14,8 +14,8 @@ typedef unsigned char CHAR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned char Address; // Адрес контроллера
|
||||
unsigned char Number; // Номер команды
|
||||
unsigned char Address; // Адрес контроллера
|
||||
unsigned char Number; // Номер команды
|
||||
|
||||
BAITE byte0;
|
||||
BAITE byte1;
|
||||
|
||||
@@ -1,16 +1,10 @@
|
||||
/* Макросы обращаются к общей карте modbus, не к локальным данным.
|
||||
* START/STOP читаются через volatile. Входящая запись слова 127
|
||||
* должна пройти UMP_commands_write для фиксации фронта.
|
||||
/* Макросы обращаются к общей карте modbus, не к локальным данным.
|
||||
* START/STOP читаются через volatile. Входящая запись слова 127
|
||||
* должна пройти UMP_commands_write для фиксации фронта.
|
||||
*/
|
||||
#ifndef PACKAGE
|
||||
#define PACKAGE
|
||||
|
||||
/* Задаёт числовой код прямого порядка индикаторов, чтобы сравнение OBOROT в препроцессоре не заменяло неопределённое имя нулём. */
|
||||
#define STRAIGHT 0
|
||||
/* Отличающийся код обратного порядка выбирает ветку перестановки двух показаний в pulto.c. */
|
||||
#define REVERSE 1
|
||||
|
||||
/* Выбирает исполнение 166: соответствующие калибровки и обратный порядок индикаторов задаются условными блоками ниже. */
|
||||
#define BALSAM 165
|
||||
|
||||
#if BALSAM == 166
|
||||
@@ -90,13 +84,13 @@
|
||||
#define bSecretBt Buttons.bit.bit1
|
||||
#define bTermoCal Buttons.bit.bit2
|
||||
|
||||
#define Cancount (modbus+0x60) // пауза между I посылками CAN
|
||||
#define Bright (modbus+0x62) // аркость сигнальных лампочек
|
||||
#define Brightness modbus[0x62] // аркость сигнальных лампочек
|
||||
#define Cancount (modbus+0x60) // пауза между I посылками CAN
|
||||
#define Bright (modbus+0x62) // аркость сигнальных лампочек
|
||||
#define Brightness modbus[0x62] // аркость сигнальных лампочек
|
||||
|
||||
/* Не врема!
|
||||
#define DAC_go modbus[0x64] // начало зарада
|
||||
#define DAC_stop modbus[0x65] // конец зарада
|
||||
/* Не врема!
|
||||
#define DAC_go modbus[0x64] // начало зарада
|
||||
#define DAC_stop modbus[0x65] // конец зарада
|
||||
*/
|
||||
|
||||
#define m_FAST 0
|
||||
@@ -141,7 +135,7 @@
|
||||
|
||||
#define LastMode Modbus[126].all
|
||||
|
||||
/* Слово меняется из CAN/RS; чтение команды не должно кешироваться. */
|
||||
/* Слово меняется из CAN/RS; чтение команды не должно кешироваться. */
|
||||
#define Commands (((volatile WORDE *)modbus)[127].all)
|
||||
#define cTestLamp Modbus[127].bit.bit0
|
||||
#define cDefParam Modbus[127].bit.bit1
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/* Физические GPIO с учётом режима и полярности. set означает
|
||||
* активировать функцию, не всегда выставить 1. START/STOP нагрузки
|
||||
* активны единицей, RES_OUT_2 нулём. Дискретами владеет автомат СИФУ.
|
||||
/* Физические GPIO с учётом режима и полярности. set означает
|
||||
* активировать функцию, не всегда выставить 1. START/STOP нагрузки
|
||||
* активны единицей, RES_OUT_2 нулём. Дискретами владеет автомат СИФУ.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Состояния пульта dsk_EPLT. Обработчик таймера нагрузки
|
||||
* определён отдельно в measure.c.
|
||||
/* Состояния пульта dsk_EPLT. Обработчик таймера нагрузки
|
||||
* определён отдельно в measure.c.
|
||||
*/
|
||||
//void what_is(void);
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/* Автомат SPI EEPROM продвигает таймер 2. Синхронное ожидание
|
||||
* требует разрешённых IRQ. PAGE_LEN/WORD_LEN задают адресацию страниц.
|
||||
/* Автомат SPI EEPROM продвигает таймер 2. Синхронное ожидание
|
||||
* требует разрешённых IRQ. PAGE_LEN/WORD_LEN задают адресацию страниц.
|
||||
*/
|
||||
#ifndef __SPISE2P_H__
|
||||
|
||||
#define __SPISE2P_H__
|
||||
|
||||
// Ёмкость памати в байтах
|
||||
// Ёмкость памати в байтах
|
||||
#define SEEPROM_LEN 0x10000
|
||||
|
||||
#define NULL 0
|
||||
@@ -97,25 +97,25 @@ void spiSe2pRead(SPISE2P_DRV *se2p, SE2P_DATA *data);
|
||||
#define WORD_LEN 1
|
||||
#endif
|
||||
|
||||
/* Установка драйвера сериальной EEPROM. **
|
||||
** Инициализациа SPI и проч. Также настройка таймера. **
|
||||
** Драйвер работает на прерываниах от таймера 2! */
|
||||
/* Установка драйвера сериальной EEPROM. **
|
||||
** Инициализациа SPI и проч. Также настройка таймера. **
|
||||
** Драйвер работает на прерываниах от таймера 2! */
|
||||
void InitSeeprom(void);
|
||||
|
||||
/* Запись блока в SEEPROM. Параметры таковы: **
|
||||
** adres - адрес в епромке, куда писать. **
|
||||
** adres = 0..0x8000, если длина слова 8 бит **
|
||||
** adres = 0..0x4000, если длина слова 16 бит **
|
||||
** buf - указатель на памать, откуда писать. **
|
||||
** size - длина блока в байтах. По-любому в байтах! */
|
||||
/* Запись блока в SEEPROM. Параметры таковы: **
|
||||
** adres - адрес в епромке, куда писать. **
|
||||
** adres = 0..0x8000, если длина слова 8 бит **
|
||||
** adres = 0..0x4000, если длина слова 16 бит **
|
||||
** buf - указатель на памать, откуда писать. **
|
||||
** size - длина блока в байтах. По-любому в байтах! */
|
||||
void Seeprom_write(unsigned int adres, unsigned int buf[], unsigned int size);
|
||||
|
||||
/* Чтение блока из SEEPROM. Параметры таковы: **
|
||||
** adres - адрес в епромке, откуда читать. **
|
||||
** adres = 0..0x8000, если длина слова 8 бит **
|
||||
** adres = 0..0x4000, если длина слова 16 бит **
|
||||
** buf - указатель на памать, куда читать. **
|
||||
** size - длина блока в байтах. По-любому в байтах! */
|
||||
/* Чтение блока из SEEPROM. Параметры таковы: **
|
||||
** adres - адрес в епромке, откуда читать. **
|
||||
** adres = 0..0x8000, если длина слова 8 бит **
|
||||
** adres = 0..0x4000, если длина слова 16 бит **
|
||||
** buf - указатель на памать, куда читать. **
|
||||
** size - длина блока в байтах. По-любому в байтах! */
|
||||
void Seeprom_read(unsigned int adres, unsigned int buf[], unsigned int size);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/* Инициализация памяти и задержки. pause_us не использовать
|
||||
* для длительности дискретов; их отсчитывает аппаратный таймер.
|
||||
/* Инициализация памяти и задержки. pause_us не использовать
|
||||
* для длительности дискретов; их отсчитывает аппаратный таймер.
|
||||
*/
|
||||
#ifndef TOOLS_H
|
||||
#define TOOLS_H
|
||||
|
||||
@@ -1,34 +1,28 @@
|
||||
/* Служебный CAN-протокол логгера УМП. Не использует адреса 0..127
|
||||
* технологического обмена. Формат полезных данных совместим с порядком
|
||||
* слов старого CAN: MDL (слова 1,2), затем MDH (маркер, слово 0).
|
||||
* Запрос: маркер 0x1F00, слово 0 = token:8 | function:8,
|
||||
* слова 1,2 = адрес расширения и число слов/записываемое значение.
|
||||
* Ответы: маркер 0x1F00 + номер фрагмента, слово 0 = token:8 | error:8,
|
||||
* слова 1,2 = два слова единого зафиксированного снимка.
|
||||
* Биты маски записи в заголовке запроса равны нулю: старая плата
|
||||
* игнорирует запрос, не изменяя технологические регистры. */
|
||||
/* Служебный CAN-протокол логгера УМП. Не использует адреса 0..127
|
||||
* технологического обмена. Формат полезных данных совместим с порядком
|
||||
* слов старого CAN: MDL (слова 1,2), затем MDH (маркер, слово 0).
|
||||
* Запрос: маркер 0x1F00, слово 0 = token:8 | function:8,
|
||||
* слова 1,2 = адрес расширения и число слов/записываемое значение.
|
||||
* Ответы: маркер 0x1F00 + номер фрагмента, слово 0 = token:8 | error:8,
|
||||
* слова 1,2 = два слова единого зафиксированного снимка.
|
||||
* Биты маски записи в заголовке запроса равны нулю: старая плата
|
||||
* игнорирует запрос, не изменяя технологические регистры. */
|
||||
#ifndef UMP_CAN_PROTOCOL_H
|
||||
#define UMP_CAN_PROTOCOL_H
|
||||
#include "log_to_mem.h"
|
||||
#include "firmware_info.h" /* Использует то же окно firmware-info v1, что FC03, сохраняя остальной служебный CAN-протокол 166. */
|
||||
#define UMP_CAN_MARKER 0x1F00U
|
||||
#define UMP_CAN_MAX_WORDS 124U
|
||||
|
||||
/* Вызывающий код защищает весь снимок от IRQ. Функция не ждёт CAN и
|
||||
* не пишет за пределами reply[124]. Ошибки возвращаются отдельным кадром. */
|
||||
/* Вызывающий код защищает весь снимок от IRQ. Функция не ждёт CAN и
|
||||
* не пишет за пределами reply[124]. Ошибки возвращаются отдельным кадром. */
|
||||
static unsigned int ump_can_prepare(unsigned int function, unsigned int address,
|
||||
unsigned int value, unsigned int *reply, unsigned int *error)
|
||||
{
|
||||
unsigned int i;
|
||||
*error = 0;
|
||||
if (function == 3) {
|
||||
if (firmware_info_range(address, value)) { /* Признаёт только чтение внутри нового двенадцатисловного паспорта. */
|
||||
for (i = 0; i < value; ++i) reply[i] = firmware_info_static_read(address - FIRMWARE_INFO_ADDRESS + i); /* Общий статический упаковщик выдаёт те же слова, что RS, без чтения архива логгера. */
|
||||
return value; /* Передаёт паспорт существующему механизму фрагментов CAN без изменения mailbox, ID и повторов. */
|
||||
} /* Все остальные запросы продолжают проходить прежнюю проверку окон логгера v4. */
|
||||
if (!((address == UMP_LOG_BASE && value == 16) ||
|
||||
/* Разрешает от одной до десяти целых 12-словных записей v4 в пределах 120 слов полезного окна CAN. */
|
||||
(address == UMP_LOG_DATA && value >= UMP_LOG_WORDS && value <= 120U && value % UMP_LOG_WORDS == 0U) ||
|
||||
(address == UMP_LOG_DATA && (value == 40 || value == 80 || value == 120)) ||
|
||||
(address == UMP_LOG_LIVE && value == 124))) *error = 2;
|
||||
else {
|
||||
for (i = 0; i < value; i++) reply[i] = ump_log_read(address+i);
|
||||
@@ -38,7 +32,7 @@ static unsigned int ump_can_prepare(unsigned int function, unsigned int address,
|
||||
if (address < UMP_LOG_BASE || address > UMP_LOG_BASE+3) *error = 2;
|
||||
else if (!ump_log_write(address, value)) *error = 3;
|
||||
} else *error = 1;
|
||||
/* Для записи возвращаем эхо адреса и значения, для ошибки — её контекст. */
|
||||
/* Для записи возвращаем эхо адреса и значения, для ошибки — её контекст. */
|
||||
reply[0] = address; reply[1] = value;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@@ -1,18 +1,18 @@
|
||||
/* Подключается только из DAC.c; в host-тесте — с подменой GPIO/IRQ. */
|
||||
/* Подключается только из DAC.c; в host-тесте — с подменой GPIO/IRQ. */
|
||||
#ifndef UMP_CONTROL_IMPL_H
|
||||
#define UMP_CONTROL_IMPL_H
|
||||
/* Аппаратная обёртка автомата. Храним её в существующем DAC.c, чтобы
|
||||
* старый проект CCS и новый CCS12 собирали одинаковый набор исходников.
|
||||
* Все входы ниже сохраняют прежнюю маску IRQ; нельзя просто делать EINT
|
||||
* при выходе, поскольку вызов возможен из уже защищённого обработчика. */
|
||||
/* Аппаратная обёртка автомата. Храним её в существующем DAC.c, чтобы
|
||||
* старый проект CCS и новый CCS12 собирали одинаковый набор исходников.
|
||||
* Все входы ниже сохраняют прежнюю маску IRQ; нельзя просто делать EINT
|
||||
* при выходе, поскольку вызов возможен из уже защищённого обработчика. */
|
||||
static volatile UMP_PULSE_STATE ump_pulse;
|
||||
static volatile unsigned int ump_pulse_enabled;
|
||||
|
||||
static void UMP_apply_outputs(unsigned int previous_output, unsigned int previous_relay)
|
||||
{
|
||||
if (previous_output != ump_pulse.output) {
|
||||
/* Сначала снимаем старый сигнал, затем выставляем новый.
|
||||
* Промежуточное состояние — оба выключены, а не оба включены. */
|
||||
/* Сначала снимаем старый сигнал, затем выставляем новый.
|
||||
* Промежуточное состояние — оба выключены, а не оба включены. */
|
||||
clear_START_DPTB();
|
||||
clear_STOP_DPTB();
|
||||
if (ump_pulse.output == UMP_PULSE_START) set_START_DPTB();
|
||||
@@ -22,8 +22,8 @@ static void UMP_apply_outputs(unsigned int previous_output, unsigned int previou
|
||||
if (ump_pulse.relay) set_RES_OUT_2();
|
||||
else clear_RES_OUT_2();
|
||||
}
|
||||
/* Старое имя оставлено для протокола логгера. Это теперь отражение
|
||||
* таймера автомата, а не переменная, которую одновременно правит main. */
|
||||
/* Старое имя оставлено для протокола логгера. Это теперь отражение
|
||||
* таймера автомата, а не переменная, которую одновременно правит main. */
|
||||
IMPowse = ump_pulse.remaining;
|
||||
}
|
||||
|
||||
@@ -34,8 +34,8 @@ void UMP_pulse_init(void)
|
||||
ump_pulse_init(&ump_pulse, Commands);
|
||||
clear_START_DPTB(); clear_STOP_DPTB(); clear_RES_OUT_2();
|
||||
IMPowse = 0;
|
||||
/* Разрешаем обработку только после загрузки параметров и настройки
|
||||
* ЦАП. Команды до этой точки не исполняются задним числом. */
|
||||
/* Разрешаем обработку только после загрузки параметров и настройки
|
||||
* ЦАП. Команды до этой точки не исполняются задним числом. */
|
||||
ump_pulse_enabled = 1;
|
||||
}
|
||||
__restore_interrupts(saved);
|
||||
@@ -47,9 +47,9 @@ void UMP_commands_write(unsigned int commands)
|
||||
unsigned int output = ump_pulse.output, relay = ump_pulse.relay;
|
||||
Commands = commands;
|
||||
if (Desk == dsk_LOAD && ump_pulse_enabled) {
|
||||
/* Выполняем фронт в момент принятия слова. Нет очереди, которую
|
||||
* main должен опросить после длительного обращения к EEPROM.
|
||||
* Здесь только несколько операций с памятью/GPIO, без ожиданий. */
|
||||
/* Выполняем фронт в момент принятия слова. Нет очереди, которую
|
||||
* main должен опросить после длительного обращения к EEPROM.
|
||||
* Здесь только несколько операций с памятью/GPIO, без ожиданий. */
|
||||
ump_pulse_accept(&ump_pulse, commands, (unsigned int)READY_FREQ);
|
||||
UMP_apply_outputs(output, relay);
|
||||
}
|
||||
@@ -70,11 +70,11 @@ void UMP_pulse_tick(void)
|
||||
void UMP_reset_parameter_commands(void)
|
||||
{
|
||||
unsigned int saved = __disable_interrupts();
|
||||
/* EEPROM содержит параметры, но не является источником команд пуска.
|
||||
* Сохраняем последние принятые START/STOP и историю фронтов автомата.
|
||||
* Нельзя обнулить их при Load/Default: таймер ЦАП читает тот же уровень,
|
||||
* а следующий повтор пакета с единицей не должен стать ложным фронтом.
|
||||
* Другие режимы платы сохраняют прежнее поведение полного сброса. */
|
||||
/* EEPROM содержит параметры, но не является источником команд пуска.
|
||||
* Сохраняем последние принятые START/STOP и историю фронтов автомата.
|
||||
* Нельзя обнулить их при Load/Default: таймер ЦАП читает тот же уровень,
|
||||
* а следующий повтор пакета с единицей не должен стать ложным фронтом.
|
||||
* Другие режимы платы сохраняют прежнее поведение полного сброса. */
|
||||
if (Desk == dsk_LOAD) Commands &= UMP_START_MASK | UMP_STOP_MASK;
|
||||
else Commands = 0;
|
||||
__restore_interrupts(saved);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Управление импульсами СИФУ. Чистый автомат без доступа к GPIO.
|
||||
* Один и тот же код используется прошивкой и host-тестом.
|
||||
* ВАЖНО: вызывающая сторона сериализует init/accept/tick запретом IRQ.
|
||||
* volatile обеспечивает обращения к общему состоянию, но не заменяет
|
||||
* критическую секцию: обновление нескольких полей не является атомарным.
|
||||
/* Управление импульсами СИФУ. Чистый автомат без доступа к GPIO.
|
||||
* Один и тот же код используется прошивкой и host-тестом.
|
||||
* ВАЖНО: вызывающая сторона сериализует init/accept/tick запретом IRQ.
|
||||
* volatile обеспечивает обращения к общему состоянию, но не заменяет
|
||||
* критическую секцию: обновление нескольких полей не является атомарным.
|
||||
*/
|
||||
#ifndef UMP_PULSE_H
|
||||
#define UMP_PULSE_H
|
||||
@@ -21,10 +21,10 @@ typedef struct {
|
||||
|
||||
static void ump_pulse_init(volatile UMP_PULSE_STATE *s, unsigned int commands)
|
||||
{
|
||||
/* Уже активная команда при окончании загрузки не является новым пуском.
|
||||
* Снимаем физические выходы отдельно в аппаратной обёртке.
|
||||
* Если начальное слово нулевое, первая свежая единица будет принята:
|
||||
* больше не нужен случайный проход main, успевший прочитать ноль. */
|
||||
/* Уже активная команда при окончании загрузки не является новым пуском.
|
||||
* Снимаем физические выходы отдельно в аппаратной обёртке.
|
||||
* Если начальное слово нулевое, первая свежая единица будет принята:
|
||||
* больше не нужен случайный проход main, успевший прочитать ноль. */
|
||||
s->previous = commands;
|
||||
s->remaining = 0;
|
||||
s->output = UMP_PULSE_NONE;
|
||||
@@ -35,23 +35,23 @@ static void ump_pulse_accept(volatile UMP_PULSE_STATE *s,
|
||||
unsigned int commands, unsigned int ticks)
|
||||
{
|
||||
unsigned int rising = commands & ~s->previous;
|
||||
/* История относится к каждому принятому слову CAN/RS, а не к редким
|
||||
* снимкам main. Поэтому даже 1->0->1 между проходами main замечается.
|
||||
* Повторные пакеты с удерживаемой единицей не продлевают импульс. */
|
||||
/* История относится к каждому принятому слову CAN/RS, а не к редким
|
||||
* снимкам main. Поэтому даже 1->0->1 между проходами main замечается.
|
||||
* Повторные пакеты с удерживаемой единицей не продлевают импульс. */
|
||||
s->previous = commands;
|
||||
if (commands & UMP_STOP_MASK) {
|
||||
/* STOP имеет приоритет даже при одновременном фронте START.
|
||||
* Его удержание запрещает новый START. Запрещённый пуск не ставим
|
||||
* в очередь: снятие STOP не должно неожиданно запускать СИФУ. */
|
||||
/* STOP имеет приоритет даже при одновременном фронте START.
|
||||
* Его удержание запрещает новый START. Запрещённый пуск не ставим
|
||||
* в очередь: снятие STOP не должно неожиданно запускать СИФУ. */
|
||||
if (rising & UMP_STOP_MASK) {
|
||||
s->output = UMP_PULSE_STOP;
|
||||
s->remaining = ticks;
|
||||
s->relay = 0;
|
||||
}
|
||||
} else if (rising & UMP_START_MASK) {
|
||||
/* Новый START после снятия команды STOP переключает выходы.
|
||||
* Новый фронт во время START продлевает существующий импульс,
|
||||
* как раньше; отдельный электрический фронт здесь не обещается. */
|
||||
/* Новый START после снятия команды STOP переключает выходы.
|
||||
* Новый фронт во время START продлевает существующий импульс,
|
||||
* как раньше; отдельный электрический фронт здесь не обещается. */
|
||||
s->output = UMP_PULSE_START;
|
||||
s->remaining = ticks;
|
||||
s->relay = 1;
|
||||
@@ -60,9 +60,9 @@ static void ump_pulse_accept(volatile UMP_PULSE_STATE *s,
|
||||
|
||||
static void ump_pulse_tick(volatile UMP_PULSE_STATE *s)
|
||||
{
|
||||
/* Единственный владелец отсчёта — таймер 1 кГц. main не участвует
|
||||
* в завершении импульса, поэтому EEPROM не растягивает его.
|
||||
* RES_OUT_2 сохраняет последнее состояние после конца импульса. */
|
||||
/* Единственный владелец отсчёта — таймер 1 кГц. main не участвует
|
||||
* в завершении импульса, поэтому EEPROM не растягивает его.
|
||||
* RES_OUT_2 сохраняет последнее состояние после конца импульса. */
|
||||
if (s->remaining && --s->remaining == 0)
|
||||
s->output = UMP_PULSE_NONE;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Низкоуровневый UART двух портов. RX ISR собирает RS_Header,
|
||||
* TX ISR продолжает передачу. RS_DataReady передаёт готовый кадр
|
||||
* в main для проверки CRC; приём байтов ещё не означает исполнения.
|
||||
* RS_Send содержит ожидания UART и не относится к быстрому пути СИФУ.
|
||||
* Размеры буферов нужно понимать с учётом 16-битной ABI C2000.
|
||||
/* Низкоуровневый UART двух портов. RX ISR собирает RS_Header,
|
||||
* TX ISR продолжает передачу. RS_DataReady передаёт готовый кадр
|
||||
* в main для проверки CRC; приём байтов ещё не означает исполнения.
|
||||
* RS_Send содержит ожидания UART и не относится к быстрому пути СИФУ.
|
||||
* Размеры буферов нужно понимать с учётом 16-битной ABI C2000.
|
||||
*/
|
||||
//#include "big_dsp_module.h"
|
||||
|
||||
@@ -28,7 +28,7 @@ static char size_cmd15=1;
|
||||
void RS_RX_Handler(RS_DATA *rs_arr);
|
||||
void RS_TX_Handler(RS_DATA *rs_arr);
|
||||
|
||||
/** Обработчик прерываний UART - принато */
|
||||
/** Обработчик прерываний UART - принато */
|
||||
interrupt void RSA_RX_Handler(void)
|
||||
{
|
||||
// Set interrupt priority:
|
||||
@@ -101,7 +101,7 @@ interrupt void RSB_TX_Handler(void)
|
||||
PieCtrlRegs.PIEIER9.all = TempPIEIER;
|
||||
}
|
||||
|
||||
/** Обработчик прерываний UART - принато */
|
||||
/** Обработчик прерываний UART - принато */
|
||||
void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
{
|
||||
char Rc;
|
||||
@@ -109,16 +109,16 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
|
||||
// led1_on();
|
||||
|
||||
for(;;) // 'goto' это не оператор азыка С
|
||||
for(;;) // 'goto' это не оператор азыка С
|
||||
{
|
||||
if(!rs_arr->SciRegs->SCIRXST.bit.RXRDY) // Receiver ready flag
|
||||
{
|
||||
PieCtrlRegs.PIEACK.bit.ACK9 |= 1;
|
||||
rs_arr->SciRegs->SCIFFRX.bit.RXFFINTCLR=1; // Clear INT flag
|
||||
return; // кстати это единственный выход из прерываниа
|
||||
return; // кстати это единственный выход из прерываниа
|
||||
}
|
||||
|
||||
Rc = rs_arr->SciRegs->SCIRXBUF.bit.RXDT; // Читаем символ в любом случае
|
||||
Rc = rs_arr->SciRegs->SCIRXBUF.bit.RXDT; // Читаем символ в любом случае
|
||||
|
||||
if(rs_arr->SciRegs->SCIRXST.bit.RXERROR) // Receiver error flag
|
||||
{
|
||||
@@ -128,110 +128,110 @@ void RS_RX_Handler(RS_DATA *rs_arr)
|
||||
continue;
|
||||
}
|
||||
|
||||
if(rs_arr->RS_DataReady) continue; // Не забрали данные
|
||||
if(rs_arr->RS_DataReady) continue; // Не забрали данные
|
||||
|
||||
if (rs_arr->RS_Flag9bit==1) // дла RS485????????
|
||||
if (rs_arr->RS_Flag9bit==1) // дла RS485????????
|
||||
{
|
||||
// Инициализируем переменные и флаги
|
||||
rs_arr->RS_FlagBegin = true; // Ждем заголовок
|
||||
// Инициализируем переменные и флаги
|
||||
rs_arr->RS_FlagBegin = true; // Ждем заголовок
|
||||
rs_arr->RS_RecvLen = 0;
|
||||
rs_arr->RS_FlagSkiping = false;
|
||||
rs_arr->RS_HeaderCnt = 0;
|
||||
rs_arr->RS_Cmd = 0;
|
||||
}
|
||||
|
||||
if(rs_arr->RS_FlagSkiping) continue; // Не нам
|
||||
if(rs_arr->RS_FlagSkiping) continue; // Не нам
|
||||
|
||||
if (rs_arr->RS_FlagBegin) // Заголовок
|
||||
if (rs_arr->RS_FlagBegin) // Заголовок
|
||||
{
|
||||
if (rs_arr->RS_HeaderCnt==0) // Адрес контроллера или стандартнаа команда
|
||||
if (rs_arr->RS_HeaderCnt==0) // Адрес контроллера или стандартнаа команда
|
||||
{
|
||||
if( (Rc == CNTRL_ADDR_UNIVERSAL) || (Rc == CNTRL_ADDR && CNTRL_ADDR!=0) || ((Rc == rs_arr->addr_answer) && rs_arr->flag_LEADING)
|
||||
|| ((Rc == ADDR_FOR_ALL && ADDR_FOR_ALL!=0) && !rs_arr->flag_LEADING))
|
||||
|
||||
{
|
||||
rs_arr->addr_recive=Rc; // запомнили адрес по которому нас запросили
|
||||
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Первый байт
|
||||
RS_SetBitMode(rs_arr,8); // перестроились в 8-бит режим
|
||||
rs_arr->addr_recive=Rc; // запомнили адрес по которому нас запросили
|
||||
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Первый байт
|
||||
RS_SetBitMode(rs_arr,8); // перестроились в 8-бит режим
|
||||
}
|
||||
else
|
||||
{
|
||||
rs_arr->RS_FlagSkiping = true; // Не нашему контроллеру
|
||||
rs_arr->RS_FlagBegin = false; // остались в 9-бит режиме
|
||||
rs_arr->RS_FlagSkiping = true; // Не нашему контроллеру
|
||||
rs_arr->RS_FlagBegin = false; // остались в 9-бит режиме
|
||||
// led1_off();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Второй байт и т.д.
|
||||
rs_arr->RS_Header[rs_arr->RS_HeaderCnt++] = Rc; // Второй байт и т.д.
|
||||
|
||||
if (rs_arr->RS_HeaderCnt == 7 && rs_arr->RS_Cmd==CMD_MODBUS_16 && !rs_arr->flag_LEADING)
|
||||
{
|
||||
RS_Len[CMD_MODBUS_16] = (10+Rc);
|
||||
}
|
||||
|
||||
// если второй байт - это команда
|
||||
// если второй байт - это команда
|
||||
if (rs_arr->RS_HeaderCnt == 2)
|
||||
{
|
||||
rs_arr->RS_Cmd = Rc;
|
||||
// Проверка длины посылки
|
||||
// CMD_LOAD - младшаа на данный момент
|
||||
// CMD_STD_ANS - старшаа на данный момент
|
||||
// Проверка длины посылки
|
||||
// CMD_LOAD - младшаа на данный момент
|
||||
// CMD_STD_ANS - старшаа на данный момент
|
||||
if ((rs_arr->RS_Cmd < CMD_MODBUS_3) || (rs_arr->RS_Cmd > CMD_STD_ANS) || (RS_Len[rs_arr->RS_Cmd]<3)
|
||||
|| ((rs_arr->RS_Cmd == CMD_LOAD)&&(rs_arr->RS_PrevCmd != CMD_INITLOAD))
|
||||
)
|
||||
{
|
||||
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
|
||||
rs_arr->RS_HeaderCnt = 0; // Потому что команда не та
|
||||
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
|
||||
rs_arr->RS_HeaderCnt = 0; // Потому что команда не та
|
||||
rs_arr->RS_FlagBegin = true;
|
||||
rs_arr->RS_FlagSkiping = false;
|
||||
rs_arr->RS_Cmd=0;
|
||||
// led1_off();
|
||||
continue;
|
||||
}
|
||||
if (rs_arr->RS_Cmd == CMD_LOAD) // Дла этой команды заголовок очень короткий
|
||||
rs_arr->RS_FlagBegin = false;// дальше идут данные
|
||||
if (rs_arr->RS_Cmd == CMD_LOAD) // Дла этой команды заголовок очень короткий
|
||||
rs_arr->RS_FlagBegin = false;// дальше идут данные
|
||||
}
|
||||
|
||||
if( (rs_arr->RS_HeaderCnt >= RS_Len[rs_arr->RS_Cmd]) ||
|
||||
(rs_arr->RS_HeaderCnt >= sizeof(rs_arr->RS_Header)))
|
||||
{ // Получили заголовок
|
||||
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
|
||||
{ // Получили заголовок
|
||||
RS_SetBitMode(rs_arr,9); // Получили все перестроились в 9-бит дла RS485?
|
||||
rs_arr->RS_FlagBegin = false;
|
||||
rs_arr->RS_FlagSkiping = true;
|
||||
rs_arr->RS_DataReady = true;
|
||||
rs_arr->RS_Cmd=0;
|
||||
// led1_off();
|
||||
} } }
|
||||
else // Поток данных
|
||||
else // Поток данных
|
||||
{
|
||||
if(rs_arr->pRS_RecvPtr<(unsigned int *)Rec_Bloc_Begin || rs_arr->pRS_RecvPtr>(unsigned int *)Rec_Bloc_End)
|
||||
{
|
||||
rs_arr->pRS_RecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
|
||||
rs_arr->pRecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
|
||||
rs_arr->pRS_RecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
|
||||
rs_arr->pRecvPtr = (unsigned int *)Rec_Bloc_Begin; // На программу надейса, а сам не плошай
|
||||
}
|
||||
if(rs_arr->RS_PrevCmd != CMD_INITLOAD) continue; // Мы здесь оказались по какой-то чудовищной ошибке
|
||||
if(rs_arr->RS_PrevCmd != CMD_INITLOAD) continue; // Мы здесь оказались по какой-то чудовищной ошибке
|
||||
|
||||
if(rs_arr->RS_DataReady) // Если данные в основном цикле не забраны,
|
||||
{ // то пропускаем следующую посылку
|
||||
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
|
||||
if(rs_arr->RS_DataReady) // Если данные в основном цикле не забраны,
|
||||
{ // то пропускаем следующую посылку
|
||||
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
|
||||
// led1_off();
|
||||
continue;
|
||||
}
|
||||
RS_BytePtr = rs_arr->RS_RecvLen++ % 2;
|
||||
if(RS_BytePtr) *rs_arr->pRS_RecvPtr++ |= Rc; // Получили слово
|
||||
if(RS_BytePtr) *rs_arr->pRS_RecvPtr++ |= Rc; // Получили слово
|
||||
else *rs_arr->pRS_RecvPtr = Rc<<8;
|
||||
|
||||
if(rs_arr->RS_Length <= rs_arr->RS_RecvLen) // Конец посылки
|
||||
if(rs_arr->RS_Length <= rs_arr->RS_RecvLen) // Конец посылки
|
||||
{
|
||||
rs_arr->RS_PrevCmd = rs_arr->RS_Header[1] = CMD_LOAD;
|
||||
RS_SetBitMode(rs_arr,9); // Получили все данные перестроились в 9-бит дла RS485?
|
||||
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
|
||||
rs_arr->RS_DataReady = true; // Флаг в основной цикл - данные получены
|
||||
RS_SetBitMode(rs_arr,9); // Получили все данные перестроились в 9-бит дла RS485?
|
||||
rs_arr->RS_FlagSkiping = true; // Игнорируем до следующего заголовка
|
||||
rs_arr->RS_DataReady = true; // Флаг в основной цикл - данные получены
|
||||
// led1_off();
|
||||
} } } }
|
||||
|
||||
/** Обработчик прерываний UART - послано */
|
||||
/** Обработчик прерываний UART - послано */
|
||||
void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
{
|
||||
char RS_BytePtr;
|
||||
@@ -241,19 +241,19 @@ void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
{
|
||||
if(++rs_arr->RS_SendLen >= rs_arr->RS_SLength)
|
||||
{
|
||||
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
|
||||
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
|
||||
}
|
||||
SCI_send(rs_arr,*(rs_arr->pRS_SendPtr++));
|
||||
|
||||
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
|
||||
{
|
||||
RS_Wait4OK(rs_arr);
|
||||
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
|
||||
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
|
||||
|
||||
RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
|
||||
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
|
||||
RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
|
||||
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
|
||||
|
||||
rs_arr->flag_TIMEOUT_to_Send=false; /* сбросили флаг ожиданиа таймаута */
|
||||
rs_arr->flag_TIMEOUT_to_Send=false; /* сбросили флаг ожиданиа таймаута */
|
||||
}
|
||||
}
|
||||
else /* BM_PACKED */
|
||||
@@ -262,7 +262,7 @@ void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
RS_BytePtr = (rs_arr->RS_SendLen++) % 2;
|
||||
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
|
||||
{
|
||||
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
|
||||
enableUARTInt(rs_arr); /* Запрещаем прерываниа по передаче */
|
||||
}
|
||||
if(RS_BytePtr) SCI_send(rs_arr, LOBYTE( *(rs_arr->pRS_SendPtr++) ));
|
||||
else SCI_send(rs_arr, HIBYTE( *rs_arr->pRS_SendPtr ));
|
||||
@@ -270,9 +270,9 @@ void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
if(rs_arr->RS_SendLen >= rs_arr->RS_SLength)
|
||||
{
|
||||
RS_Wait4OK(rs_arr);
|
||||
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
|
||||
// RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
|
||||
// RS_Line_to_receive(); /* режим приема RS485 */
|
||||
// for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
|
||||
// RS_SetBitMode(rs_arr,9); /* Передали все перестроились в 9-бит дла RS485?*/
|
||||
// RS_Line_to_receive(); /* режим приема RS485 */
|
||||
|
||||
}
|
||||
}
|
||||
@@ -281,7 +281,7 @@ void RS_TX_Handler(RS_DATA *rs_arr)
|
||||
// rs_arr->SciRegs->SCIFFTX.bit.TXINTCLR=1; // Clear INT flag
|
||||
}
|
||||
|
||||
/** Инициализациа массива длин команд */
|
||||
/** Инициализациа массива длин команд */
|
||||
void setup_arr_cmd_length()
|
||||
{
|
||||
int i;
|
||||
@@ -307,89 +307,89 @@ void setup_arr_cmd_length()
|
||||
RS_Len[CMD_EXTEND] = 18;
|
||||
}
|
||||
|
||||
/** Настройка режима приема/передачи */
|
||||
/** Настройка режима приема/передачи */
|
||||
void RS_SetBitMode(RS_DATA *rs_arr,int n)
|
||||
{
|
||||
if(n == 8)
|
||||
{
|
||||
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
|
||||
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
|
||||
rs_arr->RS_Flag9bit=0;
|
||||
}
|
||||
if(n == 9)
|
||||
{
|
||||
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
|
||||
RS_SetLineMode(rs_arr,8,'N',1); /* режим линии */
|
||||
rs_arr->RS_Flag9bit=1;
|
||||
} }
|
||||
|
||||
/** Посылка блока байтов.
|
||||
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
|
||||
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
|
||||
@param buf адрес массива
|
||||
@param len количество байт
|
||||
/** Посылка блока байтов.
|
||||
Посылает массива 32-битных целых чисел старшие биты должны быть 0.
|
||||
@precondition Работа ф-ции зависит от макро RS_TRANSMIT_INTR
|
||||
@param buf адрес массива
|
||||
@param len количество байт
|
||||
@see RS_BSend, RS_TRANSMIT_INTR */
|
||||
/* Передачу продолжает TX ISR. Здесь есть старые программные паузы
|
||||
* и ожидания UART: не вызывать из CAN ISR или секции автомата СИФУ.
|
||||
/* Передачу продолжает TX ISR. Здесь есть старые программные паузы
|
||||
* и ожидания UART: не вызывать из CAN ISR или секции автомата СИФУ.
|
||||
*/
|
||||
int RS_Send(RS_DATA *rs_arr,unsigned int *pBuf,unsigned long len)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i=0; i <= 30000; i++){} /* Пауза дла PC */
|
||||
for (i=0; i <= 30000; i++){} /* Пауза дла PC */
|
||||
|
||||
RS_Line_to_send(rs_arr); /* режим передачи RS485 */
|
||||
RS_Line_to_send(rs_arr); /* режим передачи RS485 */
|
||||
|
||||
for (i=0; i <= 10000; i++){} /* Пауза дла PC */
|
||||
for (i=0; i <= 10000; i++){} /* Пауза дла PC */
|
||||
|
||||
rs_arr->RS_SLength = len; /* Настраиваем переменные */
|
||||
rs_arr->RS_SLength = len; /* Настраиваем переменные */
|
||||
rs_arr->pRS_SendPtr = pBuf + 1;
|
||||
|
||||
rs_arr->RS_SendBlockMode = BM_CHAR32;
|
||||
|
||||
RS_Wait4OK(rs_arr); /* Дожидаемса ухода */
|
||||
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
|
||||
RS_Wait4OK(rs_arr); /* Дожидаемса ухода */
|
||||
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
|
||||
|
||||
rs_arr->RS_SendLen = 1; /* Два байта уже передали */
|
||||
rs_arr->RS_SendLen = 1; /* Два байта уже передали */
|
||||
if(len > 1)
|
||||
{
|
||||
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
|
||||
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
|
||||
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
|
||||
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
|
||||
}
|
||||
else
|
||||
{
|
||||
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
|
||||
RS_Wait4OK(rs_arr); /* Дожидаемса ухода без прерываниа */
|
||||
for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
|
||||
RS_SetBitMode(rs_arr,9); /* Обратно в 9-бит режим */
|
||||
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
|
||||
SCI_send(rs_arr, *pBuf); // Передаем второй байт по прерыванию
|
||||
RS_Wait4OK(rs_arr); /* Дожидаемса ухода без прерываниа */
|
||||
for (i=0; i <= TIME_WAIT_RS_BYTE_OUT; i++){} /* Пауза дла PC */
|
||||
RS_SetBitMode(rs_arr,9); /* Обратно в 9-бит режим */
|
||||
RS_Line_to_receive(rs_arr); /* режим приема RS485 */
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Посылка блока упакованных байтов
|
||||
// Посылка блока упакованных байтов
|
||||
int RS_BSend(RS_DATA *rs_arr,unsigned int *pBuf, unsigned long len)
|
||||
{
|
||||
|
||||
RS_Line_to_send(rs_arr); // режим передачи RS485
|
||||
RS_Line_to_send(rs_arr); // режим передачи RS485
|
||||
|
||||
rs_arr->RS_SLength = len; // Настраиваем переменные
|
||||
rs_arr->RS_SLength = len; // Настраиваем переменные
|
||||
rs_arr->pRS_SendPtr = pBuf;
|
||||
rs_arr->RS_SendBlockMode = BM_PACKED;
|
||||
|
||||
RS_Wait4OK(rs_arr); // Ожидаем очистки и ухода последнего байта
|
||||
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
|
||||
RS_Wait4OK(rs_arr); // Ожидаем очистки и ухода последнего байта
|
||||
RS_SetBitMode(rs_arr,8); /* Остальные в 8-бит режиме */
|
||||
|
||||
rs_arr->RS_SendLen = 1; // Один байт уже передали
|
||||
rs_arr->RS_SendLen = 1; // Один байт уже передали
|
||||
|
||||
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
|
||||
enableUARTIntW(rs_arr); /* Разрешаем прерываниа по передаче */
|
||||
|
||||
SCI_send(rs_arr,HIBYTE(*pBuf));// Передаем первый байт
|
||||
SCI_send(rs_arr,HIBYTE(*pBuf));// Передаем первый байт
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Устанавливает скорость обмена.
|
||||
@param speed скорость RS в бод */
|
||||
/** Устанавливает скорость обмена.
|
||||
@param speed скорость RS в бод */
|
||||
/** Устанавливает скорость обмена.
|
||||
@param speed скорость RS в бод */
|
||||
/** Устанавливает скорость обмена.
|
||||
@param speed скорость RS в бод */
|
||||
void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
|
||||
{
|
||||
long SciBaud;
|
||||
@@ -403,7 +403,7 @@ void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed)
|
||||
}
|
||||
|
||||
|
||||
/** Инициализациа последовательного порта */
|
||||
/** Инициализациа последовательного порта */
|
||||
void create_uart_vars(char size_cmd15_set)
|
||||
{
|
||||
size_cmd15=size_cmd15_set;
|
||||
@@ -413,7 +413,7 @@ void create_uart_vars(char size_cmd15_set)
|
||||
|
||||
|
||||
|
||||
/** Инициализациа последовательного порта */
|
||||
/** Инициализациа последовательного порта */
|
||||
|
||||
void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
{
|
||||
@@ -478,14 +478,14 @@ void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
SciRegs->SCICTL1.bit.RXENA=1;
|
||||
|
||||
SciRegs->SCIFFTX.bit.SCIFFENA=0; // fifo off
|
||||
SciRegs->SCIFFRX.bit.RXFFIL=1; // Длина наименьшей команды
|
||||
SciRegs->SCIFFRX.bit.RXFFIL=1; // Длина наименьшей команды
|
||||
|
||||
setup_arr_cmd_length();
|
||||
RS_SetLineSpeed(rs_arr,speed_baud); // скорость линии
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
enableUARTInt(rs_arr); // разрешение прерываний UART
|
||||
RS_SetLineSpeed(rs_arr,speed_baud); // скорость линии
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
enableUARTInt(rs_arr); // разрешение прерываний UART
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
rs_arr->RS_PrevCmd = 0; // не было никаких команд
|
||||
rs_arr->RS_PrevCmd = 0; // не было никаких команд
|
||||
rs_arr->flag_TIMEOUT_to_Send = 0;
|
||||
rs_arr->flag_LEADING = 0;
|
||||
|
||||
@@ -493,10 +493,10 @@ void setup_uart(char commnumber, unsigned long speed_baud)
|
||||
SciRegs->SCICTL1.bit.SWRESET=1; // Relinquish SCI from Reset
|
||||
}
|
||||
|
||||
/** Настройка режима линии.
|
||||
@param bit количество бит данных
|
||||
@param parity режим четности (N,O,E,M,S)
|
||||
@param stop количество стоповых бит */
|
||||
/** Настройка режима линии.
|
||||
@param bit количество бит данных
|
||||
@param parity режим четности (N,O,E,M,S)
|
||||
@param stop количество стоповых бит */
|
||||
void RS_SetLineMode(RS_DATA *rs_arr, int bit, char parity, int stop)
|
||||
{
|
||||
volatile struct SCI_REGS *SciRegs;
|
||||
@@ -539,7 +539,7 @@ void clear_timer_rs_live(RS_DATA *rs_arr)
|
||||
rs_arr->time_wait_rs_out=0;
|
||||
}
|
||||
|
||||
/* проверка на живучесть RS */
|
||||
/* проверка на живучесть RS */
|
||||
void test_rs_live(RS_DATA *rs_arr)
|
||||
{
|
||||
/* if (rs_arr->time_wait_rs_out < RS_TIME_OUT)
|
||||
@@ -547,6 +547,6 @@ void test_rs_live(RS_DATA *rs_arr)
|
||||
else
|
||||
{
|
||||
rs_arr->time_wait_rs_out=0;
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
}*/ }
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Служебные команды доступа к памяти и загрузки. get_command
|
||||
* проверяет завершённый RS-кадр и CRC перед диспетчеризацией в main.
|
||||
* Произвольная запись памяти сервисной командой не проходит
|
||||
* автомат фронтов СИФУ. Формат CMD_* согласован с загрузчиком ПК;
|
||||
* нельзя перенумеровывать команды при расширении протокола.
|
||||
/* Служебные команды доступа к памяти и загрузки. get_command
|
||||
* проверяет завершённый RS-кадр и CRC перед диспетчеризацией в main.
|
||||
* Произвольная запись памяти сервисной командой не проходит
|
||||
* автомат фронтов СИФУ. Формат CMD_* согласован с загрузчиком ПК;
|
||||
* нельзя перенумеровывать команды при расширении протокола.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
||||
#include "RS485.h"
|
||||
@@ -14,14 +14,14 @@
|
||||
//#include "spartan_tools.h"
|
||||
//#include "big_dsp_module.h"
|
||||
|
||||
int flag_DEBUG = false; /* Флаг отладочного режима */
|
||||
int flag_DEBUG = false; /* Флаг отладочного режима */
|
||||
|
||||
|
||||
//static unsigned int *RecvPtr;
|
||||
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
|
||||
//static int BS_LoadOK = false; /** Флаг успешности приема блока */
|
||||
|
||||
/**********************************************************/
|
||||
/* Прототипы функций, используемых и определенных в файле */
|
||||
/* Прототипы функций, используемых и определенных в файле */
|
||||
/**********************************************************/
|
||||
//static int _getbyte(int *addr, int offs);
|
||||
|
||||
@@ -36,60 +36,60 @@ void write_memory(unsigned long addr, unsigned int data)
|
||||
}
|
||||
|
||||
|
||||
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
|
||||
/** Возвращает номер комманды, если есть или -1 если транзакций не было */
|
||||
int get_command(RS_DATA *rs_arr)
|
||||
{
|
||||
int cmd;
|
||||
unsigned int crc, rcrc;
|
||||
|
||||
if(rs_arr->RS_DataReady) // Данные по RS пришли
|
||||
if(rs_arr->RS_DataReady) // Данные по RS пришли
|
||||
{
|
||||
rs_arr->RS_DataReady = false;
|
||||
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
|
||||
cmd = rs_arr->RS_Header[1]; // Прочитали номер команды
|
||||
|
||||
// Провераем длину команды дла считываниа CRC
|
||||
// Провераем длину команды дла считываниа CRC
|
||||
if((RS_Len[cmd]<3) || (RS_Len[cmd]>MAX_RECEIVE_LENGTH))
|
||||
{
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(cmd == CMD_LOAD) // Если команда загрузки
|
||||
if(cmd == CMD_LOAD) // Если команда загрузки
|
||||
{
|
||||
rs_arr->RS_PrevCmd = cmd;
|
||||
return cmd; // Нет проверки crc
|
||||
return cmd; // Нет проверки crc
|
||||
}
|
||||
else // Все остальные команды
|
||||
else // Все остальные команды
|
||||
{
|
||||
// Считываем crc из посылки
|
||||
// Считываем crc из посылки
|
||||
crc = (rs_arr->RS_Header[RS_Len[cmd]-1] << 8) |
|
||||
(rs_arr->RS_Header[RS_Len[cmd]-2]) ;
|
||||
}
|
||||
// Рассчитываем crc из посылки
|
||||
// Рассчитываем crc из посылки
|
||||
rcrc = 0xffff;
|
||||
rcrc = get_crc_16( rcrc, rs_arr->RS_Header, (RS_Len[cmd]-2) );
|
||||
|
||||
if(crc == rcrc) // Провераем crc
|
||||
if(crc == rcrc) // Провераем crc
|
||||
{
|
||||
rs_arr->RS_PrevCmd = cmd;
|
||||
return cmd;
|
||||
}
|
||||
else
|
||||
{
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
} }
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/** Стандартный ответ, без параметров */
|
||||
/** Стандартный ответ, без параметров */
|
||||
void Answer(RS_DATA *rs_arr,int n)
|
||||
{
|
||||
int crc;
|
||||
|
||||
flag_DEBUG = true; // Флаг отладочного режима
|
||||
flag_DEBUG = true; // Флаг отладочного режима
|
||||
|
||||
rs_arr->buffer[0] = rs_arr->addr_recive; //CNTRL_ADDR;
|
||||
rs_arr->buffer[1] = n;
|
||||
@@ -105,7 +105,7 @@ void Answer(RS_DATA *rs_arr,int n)
|
||||
RS_Send(rs_arr,rs_arr->buffer, 6);
|
||||
}
|
||||
|
||||
/* Внутреннаа ф-циа */
|
||||
/* Внутреннаа ф-циа */
|
||||
static char _getbyte(unsigned int *addr, int32 offs)
|
||||
{
|
||||
unsigned int *address;
|
||||
@@ -118,7 +118,7 @@ static char _getbyte(unsigned int *addr, int32 offs)
|
||||
}
|
||||
|
||||
|
||||
/* начальные установки (не работает)*/
|
||||
/* начальные установки (не работает)*/
|
||||
void init(RS_DATA *rs_arr)
|
||||
{
|
||||
/*
|
||||
@@ -141,13 +141,13 @@ void init(RS_DATA *rs_arr)
|
||||
*/
|
||||
}
|
||||
|
||||
/**@name Комманды
|
||||
* Комманды, вызываемые через последовательный канал
|
||||
/**@name Комманды
|
||||
* Комманды, вызываемые через последовательный канал
|
||||
*/
|
||||
//@{
|
||||
|
||||
/** Инициировать загрузку блока.
|
||||
Настраивает прием блока данных */
|
||||
/** Инициировать загрузку блока.
|
||||
Настраивает прием блока данных */
|
||||
void initload(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned long Address;
|
||||
@@ -171,8 +171,8 @@ void initload(RS_DATA *rs_arr)
|
||||
Answer(rs_arr,CMD_INITLOAD);
|
||||
}
|
||||
|
||||
/** Загрузка блока.
|
||||
Вызываетса после загрузки блока через RS */
|
||||
/** Загрузка блока.
|
||||
Вызываетса после загрузки блока через RS */
|
||||
void load(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned int rcrc, crc;
|
||||
@@ -197,27 +197,27 @@ void load(RS_DATA *rs_arr)
|
||||
else
|
||||
{
|
||||
rs_arr->BS_LoadOK = false;
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
} }
|
||||
|
||||
/** Выполнить программу в формате Serial Boot.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес программы беретса из заголовка и
|
||||
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
|
||||
/** Выполнить программу в формате Serial Boot.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес программы беретса из заголовка и
|
||||
сравниваетса с переменной RecvPtr, заполнаемой в ф-ции load
|
||||
@see load */
|
||||
void run (RS_DATA *rs_arr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/** Прочитать ачейку памати */
|
||||
/** Прочитать ачейку памати */
|
||||
void peek(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned long Address;
|
||||
unsigned int Data, crc;
|
||||
|
||||
flag_DEBUG = true; // Флаг отладочного режима
|
||||
flag_DEBUG = true; // Флаг отладочного режима
|
||||
|
||||
Address = rs_arr->RS_Header[5] & 0xFF;
|
||||
Address = (Address<<8) | (rs_arr->RS_Header[4] & 0xFF);
|
||||
@@ -250,7 +250,7 @@ void peek(RS_DATA *rs_arr)
|
||||
|
||||
}
|
||||
|
||||
/** Записать в ачейку памати */
|
||||
/** Записать в ачейку памати */
|
||||
void poke(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned long Address;
|
||||
@@ -272,12 +272,12 @@ void poke(RS_DATA *rs_arr)
|
||||
Answer(rs_arr,CMD_POKE);
|
||||
}
|
||||
|
||||
/** Передать блок памати */
|
||||
/** Передать блок памати */
|
||||
void upload(RS_DATA *rs_arr)
|
||||
{
|
||||
int32 Address, Length, crc;
|
||||
|
||||
no_write = 1; // Флаг отладочного режима
|
||||
no_write = 1; // Флаг отладочного режима
|
||||
// stopp=1;
|
||||
|
||||
Address = rs_arr->RS_Header[5] & 0xFF;
|
||||
@@ -297,10 +297,10 @@ void upload(RS_DATA *rs_arr)
|
||||
crc = get_crc_16( crc, rs_arr->buffer, 2);
|
||||
crc = get_crc_16b( crc, (unsigned int *)Address, Length);
|
||||
|
||||
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
|
||||
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
|
||||
|
||||
rs_arr->buffer[0] = CMD_UPLOAD;
|
||||
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
|
||||
RS_Send(rs_arr,rs_arr->buffer, 1); // <=2 байт по флагу
|
||||
|
||||
RS_Wait4OK(rs_arr);
|
||||
RS_BSend(rs_arr,(unsigned int*)Address, Length);
|
||||
@@ -314,21 +314,21 @@ void upload(RS_DATA *rs_arr)
|
||||
|
||||
}
|
||||
|
||||
/** Прошить XILINX.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
|
||||
так же смотрит магическое слово в начале прошивки
|
||||
/** Прошить XILINX.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load,
|
||||
так же смотрит магическое слово в начале прошивки
|
||||
@see load */
|
||||
void xflash(RS_DATA *rs_arr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/** Прошить TMS.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
|
||||
/** Прошить TMS.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
|
||||
@see load */
|
||||
void tflash(RS_DATA *rs_arr)
|
||||
{
|
||||
@@ -337,7 +337,7 @@ void tflash(RS_DATA *rs_arr)
|
||||
/*
|
||||
if(!rs_arr->BS_LoadOK)
|
||||
{
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
return;
|
||||
}
|
||||
@@ -362,7 +362,7 @@ void tflash(RS_DATA *rs_arr)
|
||||
|
||||
if( (Address2 < 0x100000) || (Address2 > 0x180000) || ((Address2+LengthW) > 0x180000) )
|
||||
{
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_Line_to_receive(rs_arr); // режим приема RS485
|
||||
RS_SetBitMode(rs_arr,9);
|
||||
return;
|
||||
}
|
||||
@@ -374,10 +374,10 @@ void tflash(RS_DATA *rs_arr)
|
||||
return;
|
||||
}
|
||||
|
||||
/** Прошить TMS.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
|
||||
/** Прошить TMS.
|
||||
@precondition Должна быть произведена загрузка блока
|
||||
Адрес и длина прошивки беретса из заголовка и
|
||||
сравниваетса с переменными RecvPtr и Length, заполнаемыми в ф-ции load
|
||||
@see load */
|
||||
void extendbios(RS_DATA *rs_arr)
|
||||
{
|
||||
@@ -403,10 +403,10 @@ void extendbios(RS_DATA *rs_arr)
|
||||
|
||||
switch ( code )
|
||||
{
|
||||
// Прошиваем EPROM Из RAM
|
||||
// Прошиваем EPROM Из RAM
|
||||
case 4: Seeprom_write(Address1,(unsigned int*)Address2,Length);
|
||||
break;
|
||||
// Читаем из EPROM в RAM
|
||||
// Читаем из EPROM в RAM
|
||||
case 5: Seeprom_read(Address1,(unsigned int*)Address2,Length);
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Адресация последовательного протокола. set_cntrl_addr задаёт
|
||||
* собственный и общий адрес. CAN ID вычисляется отдельно из Mode.
|
||||
* Общий RS-адрес не заменяет собственный во всех ответах: для
|
||||
* логгера SetGUI использовать собственный адрес платы (обычно 5/6).
|
||||
/* Адресация последовательного протокола. set_cntrl_addr задаёт
|
||||
* собственный и общий адрес. CAN ID вычисляется отдельно из Mode.
|
||||
* Общий RS-адрес не заменяет собственный во всех ответах: для
|
||||
* логгера SetGUI использовать собственный адрес платы (обычно 5/6).
|
||||
*/
|
||||
#include "cntrl_adr.h"
|
||||
|
||||
@@ -11,25 +11,25 @@
|
||||
#define ADDR_UNIVERSAL_DEF 10
|
||||
|
||||
|
||||
/** Установка адреса контроллера дла посылки всем АИНам */
|
||||
/** Установка адреса контроллера дла посылки всем АИНам */
|
||||
int ADDR_FOR_ALL = ADDR_FOR_ALL_DEF;
|
||||
|
||||
/** Установка адреса контроллера дла посылки ответа */
|
||||
/** Установка адреса контроллера дла посылки ответа */
|
||||
const int ADDR_ANSWER = ADDR_ANSWER_DEF;
|
||||
|
||||
/** Установка адреса терминала дла посылки ответа */
|
||||
/** Установка адреса терминала дла посылки ответа */
|
||||
const int ADDR_TERMINAL = ADDR_TERMINAL_DEF;
|
||||
|
||||
/* Универсальный адрес контроллера */
|
||||
/* Универсальный адрес контроллера */
|
||||
const int CNTRL_ADDR_UNIVERSAL=ADDR_UNIVERSAL_DEF;
|
||||
|
||||
/* Адрес контроллера */
|
||||
/* Адрес контроллера */
|
||||
int CNTRL_ADDR=1;
|
||||
|
||||
int cntr_addr_c;
|
||||
int cntr_addr_c_all;
|
||||
|
||||
/** Установка адреса контроллера дла прошивки */
|
||||
/** Установка адреса контроллера дла прошивки */
|
||||
void set_cntrl_addr (int cntrl_addr,int cntrl_addr_for_all)
|
||||
{
|
||||
CNTRL_ADDR = cntrl_addr;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* CRC кадров обмена и параметров EEPROM. get_crc_16 работает
|
||||
* с представлением буфера протокола, get_crc16 обрабатывает оба
|
||||
* байта каждого слова параметров. Порядок байтов существенен.
|
||||
* Нельзя заменять эти функции реализацией для ПК без проверки
|
||||
* представления данных и особенностей 16-битной ABI C2000.
|
||||
/* CRC кадров обмена и параметров EEPROM. get_crc_16 работает
|
||||
* с представлением буфера протокола, get_crc16 обрабатывает оба
|
||||
* байта каждого слова параметров. Порядок байтов существенен.
|
||||
* Нельзя заменять эти функции реализацией для ПК без проверки
|
||||
* представления данных и особенностей 16-битной ABI C2000.
|
||||
*/
|
||||
#include "crc16.h"
|
||||
#define MAKE_TABS 0 /* Builds tables below */
|
||||
|
||||
@@ -49,8 +49,6 @@ static unsigned int ump_can_length, ump_can_index, ump_can_reply_tag;
|
||||
static unsigned int ump_can_waiting;
|
||||
static unsigned long ump_can_sent_at;
|
||||
|
||||
#include "can_telemetry_impl.h" /* Определяет heartbeat, подтверждённый кэш и повтор данных через 1,3 с после объявления состояния штатного TX. */
|
||||
|
||||
void InitCan(int Port, int DevNum)
|
||||
{
|
||||
struct ECAN_REGS ECanShadow;
|
||||
@@ -61,7 +59,6 @@ void InitCan(int Port, int DevNum)
|
||||
|
||||
long id = 0x80BA0000;
|
||||
|
||||
CAN_telemetry_init(); /* Сбрасывает кэш, очередь и секундный heartbeat до разрешения аппаратных прерываний. */
|
||||
DevNum--;
|
||||
if(DevNum<0)DevNum=0;
|
||||
if(DevNum>15)DevNum=15;
|
||||
@@ -141,8 +138,8 @@ void InitCan(int Port, int DevNum)
|
||||
ECanMOTORegs->MOTO0 = 550000;
|
||||
ECanMOTORegs->MOTO1 = 550000;
|
||||
|
||||
ECanRegs->CANTOC.all = 1;
|
||||
ECanRegs->CANTOS.all = 0; // clear all time-out flags
|
||||
/* До первой передачи отключает тайм-ауты всех mailbox; по SPRUI07, 13.8.18.3, сброс TOC снимает TOS и MTOF. */
|
||||
ECanRegs->CANTOC.all = 0;
|
||||
ECanRegs->CANTSC = 0; // clear time-out counter
|
||||
|
||||
ECanShadow.CANGIM.all = 0;
|
||||
@@ -175,7 +172,49 @@ void InitCan(int Port, int DevNum)
|
||||
/* При занятом MBOX0 возвращается без ожидания ACK в цикле.
|
||||
* Это отличается от блокирующих UART/EEPROM операций main.
|
||||
*/
|
||||
/* CAN_send определён общим для этой единицы трансляции блоком can_telemetry_impl.h выше. */
|
||||
void CAN_send(int Port, int data[], int Addr)
|
||||
{
|
||||
unsigned long hiword,loword;
|
||||
volatile struct ECAN_REGS * ECanRegs;
|
||||
volatile struct ECAN_MBOXES * ECanMboxes;
|
||||
|
||||
ECanRegs = &ECanaRegs;
|
||||
ECanMboxes = &ECanaMboxes;
|
||||
|
||||
/* Не меняет данные mailbox 0, пока передача либо её аппаратная отмена ещё выполняется; бит 0 соответствует штатному TX. */
|
||||
if ((ECanRegs->CANTRS.all | ECanRegs->CANTRR.all) & 1UL)
|
||||
return; /* Сохраняет текущий кадр до завершения CANTRS/CANTRR, не ожидая аппаратного ответа в главном цикле. */
|
||||
|
||||
if(wait)
|
||||
if(!(ECanRegs->CANTA.all & 1))
|
||||
if(!(ECanRegs->CANAA.all & 1))
|
||||
return;
|
||||
|
||||
ECanRegs->CANTA.all = 1;
|
||||
ECanRegs->CANAA.all = 1;
|
||||
|
||||
hiword= ((((Uint32) Addr ) & 0xffff)<<16)| 0xE0000000 |
|
||||
((((Uint32)data[Addr ]) & 0xffff) );
|
||||
loword= ((((Uint32)data[Addr+1]) & 0xffff)<<16)|
|
||||
((((Uint32)data[Addr+2]) & 0xffff) );
|
||||
|
||||
ECanMboxes->MBOX0.MDH.all = hiword;
|
||||
ECanMboxes->MBOX0.MDL.all = loword;
|
||||
|
||||
EALLOW;
|
||||
/* Отключает старый контроль mailbox 0 перед перезапуском счётчика; остальные mailbox используют собственный контроль. */
|
||||
ECanRegs->CANTOC.all = 0;
|
||||
/* Записывает ECanRegs->CANTSC значением 0; E CAN Regs CANTSC. */
|
||||
ECanRegs->CANTSC = 0; // clear time-out counter
|
||||
/* Заново разрешает тайм-аут штатного TX с порогом MOTO0, установленным в InitCan, только для следующего кадра. */
|
||||
ECanRegs->CANTOC.all = 1UL;
|
||||
EDIS;
|
||||
|
||||
ECanRegs->CANTRS.all = 1; // запустить передачу
|
||||
|
||||
wait=1;
|
||||
led1_toggle();
|
||||
}
|
||||
|
||||
|
||||
void Handlai(volatile struct ECAN_MBOXES * ECanMboxes)
|
||||
@@ -266,11 +305,10 @@ interrupt void CANa_reset_err(void)
|
||||
if (ECanaRegs.CANTOS.all & 1UL)
|
||||
{ /* Обрабатывает только штатный передатчик; служебный mailbox 2 контролируется отдельно в UMP_CAN_service. */
|
||||
EALLOW; /* Разрешает изменение управляющего регистра eCAN перед снятием источника прерывания. */
|
||||
ECanaRegs.CANTOC.all &= ~1UL; /* Снимает timeout только mailbox 0, сохраняя контроль служебных передач. */ /* Сброс TOC снимает TOS и MTOF согласно SPRUI07, 13.8.18.3; одной отмены TX недостаточно. */
|
||||
ECanaRegs.CANTOC.all = 0; /* Сброс TOC снимает TOS и MTOF согласно SPRUI07, 13.8.18.3; одной отмены TX недостаточно. */
|
||||
EDIS; /* Восстанавливает защиту регистров до выхода из ветви обработки тайм-аута. */
|
||||
if (ECanaRegs.CANTRS.all & 1UL) /* Передача могла завершиться между чтением TOS и снятием контроля. */
|
||||
ECanaRegs.CANTRR.all = 1UL; /* Запрашивает отмену только ещё занятого mailbox 0, не задерживая прерывание ожиданием CANAA. */
|
||||
can_tx_failed = 1U; /* Не допускает записи повреждённого или отменённого кадра в подтверждённый кэш телеметрии. */
|
||||
CanTimeOutErrorTR++; /* Считает обнаруженный тайм-аут один раз, исключая фантомные повторные входы PIE. */
|
||||
} /* Следующая штатная передача сама заново включит TOC после сброса временного счётчика. */
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Рекурсивный фильтр. FILTERBAT хранит коэффициенты и историю
|
||||
* двух входов/выходов; каждый вызов изменяет переданный экземпляр.
|
||||
* Независимым каналам нужны отдельные состояния. Синхронизации
|
||||
* здесь нет: смену коэффициентов согласовывает вызывающий код.
|
||||
/* Рекурсивный фильтр. FILTERBAT хранит коэффициенты и историю
|
||||
* двух входов/выходов; каждый вызов изменяет переданный экземпляр.
|
||||
* Независимым каналам нужны отдельные состояния. Синхронизации
|
||||
* здесь нет: смену коэффициентов согласовывает вызывающий код.
|
||||
*/
|
||||
#include "filter_bat2.h"
|
||||
|
||||
|
||||
@@ -20,6 +20,27 @@
|
||||
int digits[16] = {63,6,91,79,102,109,125,7,127,111,64,0,0,0,121,0};
|
||||
int readr[5] = {0x08,0x0C,0x10,0x00,0x04};
|
||||
|
||||
/* Ограничивает настройки таймингов компилятором TI C2000; модель на ПК не использует эти директивы. */
|
||||
#if defined(__TI_COMPILER_VERSION__)
|
||||
/* Сохраняет отдельный вызов переключения CLOCK: встраивание при -O3 сокращало удержание DATA после фронта. */
|
||||
#pragma FUNC_CANNOT_INLINE(DCLK)
|
||||
/* Возвращает генерацию DCLK как в образе от 06.10.2026: уровень 1 и приоритет скорости 3 сохраняют прежнюю последовательность инструкций GPIO. */
|
||||
#pragma FUNCTION_OPTIONS(DCLK, "--opt_level=1 --opt_for_speed=3")
|
||||
/* Сохраняет отдельный вызов переключения DATA, чтобы длительность импульсов не зависела от встраивания в передатчик. */
|
||||
#pragma FUNC_CANNOT_INLINE(DOUT)
|
||||
/* Возвращает генерацию DOUT с прежними параметрами -O1 и --opt_for_speed=3; значения взяты из старой конфигурации CCS. */
|
||||
#pragma FUNCTION_OPTIONS(DOUT, "--opt_level=1 --opt_for_speed=3")
|
||||
/* Не позволяет встроить разделитель пакетов в цикл передачи и изменить интервалы между переключениями линий. */
|
||||
#pragma FUNC_CANNOT_INLINE(RESET)
|
||||
/* Сохраняет прежнюю последовательность вызовов GPIO и задержек разделителя, используя настройки старого образа. */
|
||||
#pragma FUNCTION_OPTIONS(RESET, "--opt_level=1 --opt_for_speed=3")
|
||||
/* Сохраняет отдельный вызов передачи бита; протокол использует порядок и интервалы фронтов CLOCK и DATA. */
|
||||
#pragma FUNC_CANNOT_INLINE(SENDBIT)
|
||||
/* Закрепляет для передачи бита настройки из 167: -O1 и --opt_for_speed=3 сохраняют интервалы GPIO независимо от общего уровня оптимизации проекта. */
|
||||
#pragma FUNCTION_OPTIONS(SENDBIT, "--opt_level=1 --opt_for_speed=3")
|
||||
/* Завершает блок настроек TI, не изменяя формат пакетов и существующие счётчики задержек. */
|
||||
#endif
|
||||
|
||||
void DCLK(int x)
|
||||
{
|
||||
if(x) GpioDataRegs.GPASET.bit.GPIO6=1;
|
||||
@@ -88,7 +109,7 @@ void kanal_Send(int adr, long dat, int dot)
|
||||
long Word,data,aliq_part,dg[4];
|
||||
int i,j,bit,byt,addr,sgn=0,punkt=0,aliq_len=0,full_len, isdot=0;
|
||||
|
||||
if(adr>1) // Лампочки
|
||||
if(adr>1) // Адреса каналов выше 1 передают готовую битовую маску ламп; каналы 0 и 1 требуют преобразования числа в сегменты.
|
||||
{
|
||||
Word =dat;
|
||||
}
|
||||
@@ -139,7 +160,7 @@ void kanal_Send(int adr, long dat, int dot)
|
||||
for(i=3;i>0;i--)
|
||||
{
|
||||
if((dg[i]==0)&&(i!=dot))
|
||||
dg[i]=0xF; // Это значит пусто
|
||||
dg[i]=0xF; // Индекс 0xF таблицы digits задаёт пустой символ, скрывая ведущий ноль вне позиции десятичной точки.
|
||||
else break;
|
||||
}
|
||||
|
||||
@@ -148,7 +169,7 @@ void kanal_Send(int adr, long dat, int dot)
|
||||
{
|
||||
if( (dg[i]==0xF)||(i==3))
|
||||
{
|
||||
dg[i]=0xA; // Это значит минус
|
||||
dg[i]=0xA; // Индекс 0xA таблицы digits задаёт знак минуса в свободном разряде отрицательного числа.
|
||||
break;
|
||||
} }
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Регистратор УМП во внешней памяти .logg: два банка по 800 записей
|
||||
* из 12 слов формата v4 для SetGUI. Архив отключения не мешает дальнейшей записи.
|
||||
* Писатели из main/CAN/таймера защищаются короткими секциями IRQ
|
||||
* с восстановлением прежней маски. Архив не энергонезависимый.
|
||||
* clear_mem выполняется при запуске до включения прерываний.
|
||||
/* Регистратор УМП во внешней памяти .logg: два банка по 800 записей
|
||||
* из 40 слов для SetGUI. Архив отключения не мешает дальнейшей записи.
|
||||
* Писатели из main/CAN/таймера защищаются короткими секциями IRQ
|
||||
* с восстановлением прежней маски. Архив не энергонезависимый.
|
||||
* clear_mem выполняется при запуске до включения прерываний.
|
||||
*/
|
||||
#include "DSP2833x_Device.h"
|
||||
#include "filter_bat2.h"
|
||||
@@ -16,7 +16,7 @@
|
||||
#include "log_to_mem.h"
|
||||
|
||||
int no_write = 0,
|
||||
never_write = 0; // Изначально разрешает запись; установленный флаг прекращает сохранение снимков до следующего запуска регистратора.
|
||||
never_write = 0; // Флаги, чтобы не писать (если что)
|
||||
|
||||
#pragma DATA_SECTION(logs_block,".logg");
|
||||
unsigned int logs_block[0xFA00];
|
||||
@@ -24,7 +24,7 @@ unsigned int logs_block[0xFA00];
|
||||
LOG Log;
|
||||
unsigned int flog=0;
|
||||
|
||||
// Очищение памати, где логи лежат
|
||||
// Очищение памати, где логи лежат
|
||||
void clear_mem()
|
||||
{
|
||||
unsigned long i;
|
||||
@@ -37,27 +37,27 @@ void clear_mem()
|
||||
for (i=Log.Start; i<Log.Finis; i++)
|
||||
*(volatile int *)i = 0;
|
||||
}
|
||||
/* Два банка используют уже выделенную внешнюю RAM .logg (64000 слов).
|
||||
* Активный банк кольцевой. Через 1000 мс после команды отключения он
|
||||
* становится архивом, а запись продолжается во втором банке. Переключение
|
||||
* занимает постоянное время: копирования 30 тысяч слов под запретом IRQ нет.
|
||||
* Архив переживает разрыв RS-связи, но НЕ исчезновение питания платы. */
|
||||
/* Два банка используют уже выделенную внешнюю RAM .logg (64000 слов).
|
||||
* Активный банк кольцевой. Через 1000 мс после команды отключения он
|
||||
* становится архивом, а запись продолжается во втором банке. Переключение
|
||||
* занимает постоянное время: копирования 30 тысяч слов под запретом IRQ нет.
|
||||
* Архив переживает разрыв RS-связи, но НЕ исчезновение питания платы. */
|
||||
static volatile unsigned int ump_state, ump_count, ump_cursor, ump_next;
|
||||
static volatile unsigned int ump_period = 20, ump_divider;
|
||||
static volatile unsigned long ump_time, ump_sequence;
|
||||
static unsigned int ump_bank, ump_archive_bank = 1;
|
||||
static unsigned int ump_archive_count, ump_archive_next, ump_generation;
|
||||
static unsigned int ump_source, ump_post, ump_post_dropped;
|
||||
/* Хранит последние ЗПТ1/ЗПТ2 в вольтах из регистров ПМ67 306/9; явные нули попадают в инициализацию COFF до первого CAN-кадра. */
|
||||
static unsigned int ump_pm67_voltage[2] = {0, 0};
|
||||
static unsigned int ump_can_header, ump_can_data[3], ump_can_count;
|
||||
static unsigned int ump_prev_commands, ump_prev_inputs, ump_prev_outputs;
|
||||
/* Диагностика внутренних переменных разгона. Обновляется самим Load_runner,
|
||||
* не пересчитывает и не изменяет управляющий алгоритм. */
|
||||
extern int CanTimeOutErrorTR;
|
||||
/* Диагностика внутренних переменных разгона. Обновляется самим Load_runner,
|
||||
* не пересчитывает и не изменяет управляющий алгоритм. */
|
||||
unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position;
|
||||
|
||||
/* Логические уровни входов платы нагрузки: физический ноль означает 1.
|
||||
* Чтение GPIO непосредственно здесь позволяет записать вход до следующего
|
||||
* обновления регистра Inputs в основном цикле. */
|
||||
/* Логические уровни входов платы нагрузки: физический ноль означает 1.
|
||||
* Чтение GPIO непосредственно здесь позволяет записать вход до следующего
|
||||
* обновления регистра Inputs в основном цикле. */
|
||||
static unsigned int ump_inputs(void)
|
||||
{
|
||||
return (!GpioDataRegs.GPADAT.bit.GPIO6) |
|
||||
@@ -65,7 +65,7 @@ static unsigned int ump_inputs(void)
|
||||
((!GpioDataRegs.GPADAT.bit.GPIO11) << 2);
|
||||
}
|
||||
|
||||
/* START/STOP активны единицей; RES_OUT_2 активен физическим нулём. */
|
||||
/* START/STOP активны единицей; RES_OUT_2 активен физическим нулём. */
|
||||
static unsigned int ump_outputs(void)
|
||||
{
|
||||
return GpioDataRegs.GPBDAT.bit.GPIO62 |
|
||||
@@ -73,62 +73,62 @@ static unsigned int ump_outputs(void)
|
||||
((!GpioDataRegs.GPADAT.bit.GPIO3) << 2);
|
||||
}
|
||||
|
||||
/* Вызывается только внутри короткой критической секции. Все три источника
|
||||
* записей (main, CAN ISR, timer ISR) используют одну блокировку IRQ с
|
||||
* восстановлением прежнего состояния, включая вызовы из прерывания. */
|
||||
/* Вызывается только внутри короткой критической секции. Все три источника
|
||||
* записей (main, CAN ISR, timer ISR) используют одну блокировку IRQ с
|
||||
* восстановлением прежнего состояния, включая вызовы из прерывания. */
|
||||
static void ump_capture(unsigned int reason)
|
||||
{
|
||||
/* Указывает на начало одной 12-словной записи во внешней RAM; volatile сохраняет фактические обращения к памяти. */
|
||||
volatile unsigned int *record;
|
||||
/* Сохраняет полное слово команд для прежней логики триггера; в запись попадут только биты пуска и сброса. */
|
||||
unsigned int commands;
|
||||
volatile unsigned int *p;
|
||||
unsigned int i, commands;
|
||||
if (ump_state != 1 || Desk != dsk_LOAD || READY) return;
|
||||
if (no_write || never_write) { ump_state = 3; return; }
|
||||
commands = Commands;
|
||||
/* Отключение: фронт cUMPreset (бит 6) либо спад cUMPstart (бит 7).
|
||||
* Повторные команды не сдвигают конец уже начатого постинтервала. */
|
||||
/* Отключение: фронт cUMPreset (бит 6) либо спад cUMPstart (бит 7).
|
||||
* Повторные команды не сдвигают конец уже начатого постинтервала. */
|
||||
if (!ump_post && (((commands & 0x40) && !(ump_prev_commands & 0x40)) ||
|
||||
(!(commands & 0x80) && (ump_prev_commands & 0x80)))) {
|
||||
/* Половину банка резервируем под постинтервал. Даже при периоде
|
||||
* 1 мс или шквале CAN событие отключения не вытесняется кольцом. */
|
||||
/* Половину банка резервируем под постинтервал. Даже при периоде
|
||||
* 1 мс или шквале CAN событие отключения не вытесняется кольцом. */
|
||||
if (ump_count >= UMP_LOG_CAPACITY/2) ump_count = UMP_LOG_CAPACITY/2-1;
|
||||
ump_post_dropped = 0;
|
||||
ump_post = 1000;
|
||||
reason |= 0x100;
|
||||
}
|
||||
/* Последнее место оставляем для снимка конца постинтервала. При
|
||||
* переполнении честно отмечаем усечение битом 0x200 в конечной записи. */
|
||||
/* Последнее место оставляем для снимка конца постинтервала. При
|
||||
* переполнении честно отмечаем усечение битом 0x200 в конечной записи. */
|
||||
if (ump_post && ump_count >= UMP_LOG_CAPACITY-1) {
|
||||
ump_post_dropped = 1;
|
||||
return;
|
||||
}
|
||||
if (reason == 5 && ump_post_dropped) reason |= 0x200;
|
||||
/* Выбирает слот банка по числу 16-битных слов записи; ёмкость 800 записей сохранена для исполнения 166. */
|
||||
record = logs_block + ((unsigned long)ump_bank * UMP_LOG_CAPACITY + ump_next) * UMP_LOG_WORDS;
|
||||
/* Слова 0/1 передают 32-битное время в миллисекундах младшей половиной вперёд, как в формате v4 исполнения 167. */
|
||||
record[0] = (unsigned int)ump_time; record[1] = (unsigned int)(ump_time >> 16);
|
||||
/* Слово 2 содержит событие, а маска 0xC0 оставляет в слове 3 только назначенные протоколом биты 7/6 пуска и сброса УМП. */
|
||||
record[2] = reason; record[3] = commands & 0xC0U;
|
||||
/* Слова 4/5 сохраняют фактические логические входы и выходы нагрузки для дискретных дорожек SetGUI. */
|
||||
record[4] = ump_inputs(); record[5] = ump_outputs();
|
||||
/* Слово 6 содержит расчётное задание тока регистра 0x1C в единицах 0,1 мА; физическое измерение тока здесь не выполняется. */
|
||||
record[6] = modbus[0x1C];
|
||||
/* Слова 7/8 содержат штатные фиксированные уставки разгона 166: начальные 6 мА и конечные 16 мА. */
|
||||
record[7] = 6; record[8] = 16;
|
||||
/* Слова 9/10 передают последние ЗПТ1/ЗПТ2 в вольтах из CAN-индексов 305/8, соответствующих регистрам ПМ67 306/9. */
|
||||
record[9] = ump_pm67_voltage[0]; record[10] = ump_pm67_voltage[1];
|
||||
/* Нулевое слово 11 дополняет запись до чётной длины: служебный CAN передаёт данные парами 16-битных слов. */
|
||||
record[11] = 0;
|
||||
/* Обновляет полные команды и фактические дискреты для обнаружения следующих событий, сохраняя алгоритм триггера 166. */
|
||||
ump_prev_commands = commands; ump_prev_inputs = record[4]; ump_prev_outputs = record[5];
|
||||
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[2] = reason; p[3] = commands;
|
||||
p[4] = ump_inputs(); p[5] = ump_outputs();
|
||||
p[6] = (unsigned int)IMPowse; p[7] = (unsigned int)WAKEpowse;
|
||||
p[8] = modbus[0x7B]; p[9] = modbus[0x1C];
|
||||
for (i = 0; i < 4; i++) { p[10+i] = sens_data[i]; p[14+i] = modbus[i]; }
|
||||
p[18] = ump_can_header;
|
||||
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;
|
||||
/* Исходные уставки — мА; эффективные уставки после ограничений — 0.1 мА.
|
||||
* p[8] — отправленный код, а p[9] — расчётное задание, НЕ измерение тока. */
|
||||
/* 166: fixed ramp endpoints; no configurable DAC_go/DAC_stop. */
|
||||
p[24] = 6; p[25] = 16;
|
||||
p[26] = DAC_min(); p[27] = DAC_max(); p[28] = DAC_cal();
|
||||
p[29] = DAC_04; p[30] = DAC_20;
|
||||
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;
|
||||
for (i = 0; i < 4; i++) p[36+i] = adc_table_lem[i];
|
||||
ump_prev_commands = commands; ump_prev_inputs = p[4]; ump_prev_outputs = p[5];
|
||||
ump_next++;
|
||||
if (ump_next == UMP_LOG_CAPACITY) ump_next = 0;
|
||||
if (ump_count < UMP_LOG_CAPACITY) ump_count++;
|
||||
ump_sequence++;
|
||||
}
|
||||
|
||||
/* Завершённый банк больше не изменяется до следующего отключения.
|
||||
* Номер поколения позволяет GUI обнаружить замену архива во время чтения. */
|
||||
/* Завершённый банк больше не изменяется до следующего отключения.
|
||||
* Номер поколения позволяет GUI обнаружить замену архива во время чтения. */
|
||||
static void ump_freeze(void)
|
||||
{
|
||||
ump_archive_bank = ump_bank;
|
||||
@@ -152,8 +152,8 @@ void ump_log_tick(void)
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
/* Дополнительный снимок только при изменении команд, входов или выходов.
|
||||
* Это не заменяет периодическую запись аналоговых величин в таймере. */
|
||||
/* Дополнительный снимок только при изменении команд, входов или выходов.
|
||||
* Это не заменяет периодическую запись аналоговых величин в таймере. */
|
||||
void ump_log_io(void)
|
||||
{
|
||||
unsigned int saved;
|
||||
@@ -164,34 +164,17 @@ void ump_log_io(void)
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
/* Обновляет напряжения из принятых слов CAN даже до запуска записи;
|
||||
* активный регистратор дополнительно сохраняет событие приёма. */
|
||||
/* Вызывается после применения слов принятого CAN-кадра: снимок содержит
|
||||
* новые команды, а также исходный адрес/маску и все три слова кадра. */
|
||||
void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned int c)
|
||||
{
|
||||
/* Хранит прежнюю маску IRQ, индекс слова, текущий CAN-адрес, маску разрешения и три принятых 16-битных значения. */
|
||||
unsigned int saved, word_index, address, mask, can_words[3];
|
||||
/* Напряжения и журнал принадлежат плате нагрузки; другие аппаратные режимы их не обновляют. */
|
||||
if (Desk != dsk_LOAD) return;
|
||||
/* Исключает смешивание обновления напряжений с периодическим снимком таймера и восстанавливает прежние IRQ в конце. */
|
||||
unsigned int saved;
|
||||
if (ump_state != 1 || Desk != dsk_LOAD) return;
|
||||
saved = __disable_interrupts();
|
||||
/* Располагает три принятых слова в том же порядке, в котором заголовок задаёт их последовательные адреса. */
|
||||
can_words[0] = a; can_words[1] = b; can_words[2] = c;
|
||||
/* Младшие 13 бит заголовка задают нулевой индекс первого регистра CAN; верхние три бита являются масками слов. */
|
||||
address = header & 0x1FFFU;
|
||||
/* Старший бит 0x8000 разрешает первое слово, далее используются биты 0x4000 и 0x2000. */
|
||||
mask = 0x8000U;
|
||||
/* Продвигает адрес и маску для всех трёх позиций, включая пропущенные слова, чтобы не перепутать регистры ПМ67. */
|
||||
for (word_index = 0; word_index < 3; word_index++, address++, mask >>= 1) {
|
||||
/* Не использует содержимое позиции, если соответствующий бит заголовка не подтверждает её передачу. */
|
||||
if (!(header & mask)) continue;
|
||||
/* Индекс 305 соответствует регистру 306 ПМ67: суммарное напряжение ЗПТ1 передаётся в целых вольтах. */
|
||||
if (address == 305U) ump_pm67_voltage[0] = can_words[word_index];
|
||||
/* Индекс 8 соответствует регистру 9 ПМ67: суммарное напряжение ЗПТ2 передаётся в целых вольтах. */
|
||||
if (address == 8U) ump_pm67_voltage[1] = can_words[word_index];
|
||||
} /* Завершает разбор трёх слов CAN после обновления только подтверждённых напряжений. */
|
||||
/* Сохраняет компактный снимок только при активной записи и готовности 166, которые проверяет ump_capture. */
|
||||
ump_can_header = header;
|
||||
ump_can_data[0] = a; ump_can_data[1] = b; ump_can_data[2] = c;
|
||||
ump_can_count++;
|
||||
ump_capture(2);
|
||||
/* Возвращает исходную маску IRQ, в том числе при вызове из обработчика CAN. */
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
@@ -202,8 +185,8 @@ void ump_log_rs(void)
|
||||
__restore_interrupts(saved);
|
||||
}
|
||||
|
||||
/* Управление журналом отделено от технологических команд: начало записи
|
||||
* НЕ запускает УМП. Выбор архива не останавливает текущую запись. */
|
||||
/* Управление журналом отделено от технологических команд: начало записи
|
||||
* НЕ запускает УМП. Выбор архива не останавливает текущую запись. */
|
||||
int ump_log_write(unsigned int address, unsigned int value)
|
||||
{
|
||||
unsigned int saved, valid = 1;
|
||||
@@ -228,8 +211,8 @@ int ump_log_write(unsigned int address, unsigned int value)
|
||||
return valid;
|
||||
}
|
||||
|
||||
/* Преобразование хронологического индекса в физическую позицию кольца.
|
||||
* Для архива сохранены собственные count/next, независимые от живого банка. */
|
||||
/* Преобразование хронологического индекса в физическую позицию кольца.
|
||||
* Для архива сохранены собственные count/next, независимые от живого банка. */
|
||||
static unsigned int ump_word(unsigned int archived, unsigned int record, unsigned int word)
|
||||
{
|
||||
unsigned int count = archived ? ump_archive_count : ump_count;
|
||||
@@ -242,17 +225,16 @@ static unsigned int ump_word(unsigned int archived, unsigned int record, unsigne
|
||||
return logs_block[((unsigned long)bank * UMP_LOG_CAPACITY + slot) * UMP_LOG_WORDS + word];
|
||||
}
|
||||
|
||||
/* Весь Modbus-блок читается вызывающим кодом под одной блокировкой IRQ.
|
||||
* Поэтому timestamp/данные и заголовок онлайн-блока относятся к одному
|
||||
* состоянию кольца, даже если в этот момент приходит новая CAN-команда. */
|
||||
/* Весь Modbus-блок читается вызывающим кодом под одной блокировкой IRQ.
|
||||
* Поэтому timestamp/данные и заголовок онлайн-блока относятся к одному
|
||||
* состоянию кольца, даже если в этот момент приходит новая CAN-команда. */
|
||||
unsigned int ump_log_read(unsigned int address)
|
||||
{
|
||||
unsigned int offset, count;
|
||||
unsigned long first;
|
||||
switch (address) {
|
||||
case UMP_LOG_BASE: return 0x554D;
|
||||
/* Версия 4 сообщает SetGUI о 12-словной записи, исключая её ошибочный разбор как прежних 40 слов v2. */
|
||||
case UMP_LOG_BASE+1: return 4;
|
||||
case UMP_LOG_BASE+1: return 2;
|
||||
case UMP_LOG_BASE+2: return ump_source ? 3 : ump_state;
|
||||
case UMP_LOG_BASE+3: return ump_source ? ump_archive_count : ump_count;
|
||||
case UMP_LOG_BASE+4: return UMP_LOG_WORDS;
|
||||
@@ -272,11 +254,10 @@ unsigned int ump_log_read(unsigned int address)
|
||||
offset = address - UMP_LOG_DATA;
|
||||
return ump_word(ump_source, ump_cursor + offset / UMP_LOG_WORDS, offset % UMP_LOG_WORDS);
|
||||
}
|
||||
/* Последние десять записей для онлайн-графика, без остановки и без
|
||||
* изменения курсора архивного чтения. Первые два слова — их номер. */
|
||||
/* Последние три записи для онлайн-графика, без остановки и без
|
||||
* изменения курсора архивного чтения. Первые два слова — их номер. */
|
||||
if (address >= UMP_LOG_LIVE && address < UMP_LOG_LIVE+124) {
|
||||
/* Ограничивает число целых записей ёмкостью 120-словного окна: формат v4 позволяет передать до десяти снимков. */
|
||||
count = ump_count < UMP_LOG_LIVE_RECORDS ? ump_count : UMP_LOG_LIVE_RECORDS;
|
||||
count = ump_count < 3 ? ump_count : 3;
|
||||
first = ump_sequence - count;
|
||||
offset = address - UMP_LOG_LIVE;
|
||||
if (offset == 0) return (unsigned int)first;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Инициализация и фоновый цикл платы. После настройки GPIO, обмена,
|
||||
* параметров и ЦАП UMP_pulse_init разрешает свежие команды СИФУ.
|
||||
* В main остаются телеметрия, EEPROM и разбор готовых RS-пакетов.
|
||||
* CAN-пуск и окончание импульса работают в IRQ, не ожидая main.
|
||||
* RS-команда ещё должна пройти проверку CRC в get_command из main.
|
||||
/* Инициализация и фоновый цикл платы. После настройки GPIO, обмена,
|
||||
* параметров и ЦАП UMP_pulse_init разрешает свежие команды СИФУ.
|
||||
* В main остаются телеметрия, EEPROM и разбор готовых RS-пакетов.
|
||||
* CAN-пуск и окончание импульса работают в IRQ, не ожидая main.
|
||||
* RS-команда ещё должна пройти проверку CRC в get_command из main.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
||||
|
||||
@@ -43,7 +43,8 @@ void timer_Init()
|
||||
|
||||
void main()
|
||||
{
|
||||
int i,j; /* Счётчики остались для прежних операций main; выбор CAN-пакетов перенесён в независимый сервис. */
|
||||
int i,j,mask;
|
||||
static unsigned int cancount[2], cancell[2];
|
||||
RS_DATA * rs;
|
||||
int presbyt=0;
|
||||
|
||||
@@ -99,7 +100,7 @@ void main()
|
||||
if(Desk==dsk_LOAD)
|
||||
Setup_DAC_time();
|
||||
|
||||
/* Завершена начальная настройка: только теперь разрешаем дискреты. */
|
||||
/* Завершена начальная настройка: только теперь разрешаем дискреты. */
|
||||
UMP_pulse_init();
|
||||
LastMode = Mode;
|
||||
|
||||
@@ -109,9 +110,32 @@ void main()
|
||||
|
||||
while(1)
|
||||
{
|
||||
/* Чтение логгера по CAN не блокирует цикл управления. */
|
||||
/* Чтение логгера по CAN не блокирует цикл управления. */
|
||||
UMP_CAN_service();
|
||||
CAN_telemetry_service(); /* Обслуживает heartbeat 1 Гц, изменения масок данных и индивидуальные повторы 1,3 с без ожидания CAN ACK. */
|
||||
if(CanGO)
|
||||
{
|
||||
CanGO=0;
|
||||
for(i=0;i<2;i++)
|
||||
if(Cancount[i])
|
||||
if(++cancount[i] >= Cancount[i])
|
||||
{
|
||||
cancount[i] = 0;
|
||||
while(1)
|
||||
{
|
||||
if(cancell[i] >= 0x80) cancell[i]=0;
|
||||
mask = Maska[i][cancell[i]/16] >> (cancell[i]%16);
|
||||
if(!mask) cancell[i] = (cancell[i] + 0x10) & 0xFFF0;
|
||||
else
|
||||
{
|
||||
while(!(mask & 1))
|
||||
{
|
||||
cancell[i]++; mask >>= 1;
|
||||
}
|
||||
break;
|
||||
} }
|
||||
CAN_send(0,modbus,cancell[i]);
|
||||
cancell[i]+=3;
|
||||
} }
|
||||
|
||||
if(cDefParam)
|
||||
{
|
||||
@@ -145,10 +169,10 @@ void main()
|
||||
presbyt = bTermoCal;
|
||||
}
|
||||
|
||||
/* START/STOP исполняются при приёме CAN/RS, снимаются таймером.
|
||||
* Здесь больше нет опроса уровня: main может ожидать EEPROM. */
|
||||
/* START/STOP исполняются при приёме CAN/RS, снимаются таймером.
|
||||
* Здесь больше нет опроса уровня: main может ожидать EEPROM. */
|
||||
|
||||
/* Снимок после обновления входов и формирования пусковых выходов. */
|
||||
/* Снимок после обновления входов и формирования пусковых выходов. */
|
||||
ump_log_io();
|
||||
|
||||
for(i=0;i<2;i++)
|
||||
@@ -164,16 +188,16 @@ void main()
|
||||
led2_toggle();
|
||||
switch(j)
|
||||
{
|
||||
case CMD_INIT: init(rs); break; // начальные установки
|
||||
case CMD_INITLOAD: initload(rs); break; // настройка загрузки
|
||||
case CMD_RUN: run(rs); break; // загрузить блок
|
||||
case CMD_LOAD: load(rs); break; // загрузить блок
|
||||
case CMD_PEEK: peek(rs); break; // прочитать ачейку памати
|
||||
case CMD_POKE: poke(rs); break; // записать в ачейку памати
|
||||
case CMD_UPLOAD: upload(rs); break; // передать блок памати
|
||||
case CMD_EXTEND: extendbios(rs); break; // расширенные команды дла биоса
|
||||
case CMD_INIT: init(rs); break; // начальные установки
|
||||
case CMD_INITLOAD: initload(rs); break; // настройка загрузки
|
||||
case CMD_RUN: run(rs); break; // загрузить блок
|
||||
case CMD_LOAD: load(rs); break; // загрузить блок
|
||||
case CMD_PEEK: peek(rs); break; // прочитать ачейку памати
|
||||
case CMD_POKE: poke(rs); break; // записать в ачейку памати
|
||||
case CMD_UPLOAD: upload(rs); break; // передать блок памати
|
||||
case CMD_EXTEND: extendbios(rs); break; // расширенные команды дла биоса
|
||||
|
||||
case CMD_TFLASH: tflash(rs); break; // прошить TMS
|
||||
case CMD_TFLASH: tflash(rs); break; // прошить TMS
|
||||
|
||||
case CMD_MODBUS_3: ReceiveCommandModbus3(rs); break;
|
||||
case CMD_MODBUS_6: ReceiveCommandModbus6(rs); break;
|
||||
|
||||
@@ -26,7 +26,7 @@ unsigned int CanPowse=CANPOWSE,CanGO=0;
|
||||
|
||||
unsigned int Maska[2][8];
|
||||
|
||||
int TPL_CANS=0; // Количество температурных каналов
|
||||
int TPL_CANS=0; // Количество температурных каналов
|
||||
int tpl_cans=0;
|
||||
int cal_addr=0;
|
||||
|
||||
@@ -79,7 +79,7 @@ float K_T1,K_T2;
|
||||
interrupt void cpu_timer1_isr_SENS(void);
|
||||
|
||||
/********************************************************************/
|
||||
/* Расчет модула тока из показаний двух фаз */
|
||||
/* Расчет модула тока из показаний двух фаз */
|
||||
/********************************************************************/
|
||||
float im_calc(float ia,float ib)
|
||||
{
|
||||
@@ -360,7 +360,7 @@ void Init_packMask()
|
||||
switch(Desk)
|
||||
{
|
||||
case dsk_EPLT:
|
||||
Maska[m_FAST][0]|= 0x000F; // Включает R0–R3 в быструю обратную связь VPU для ПМ67; четыре младших бита маски исключают ожидание медленного обхода параметров.
|
||||
Maska[m_FAST][0]|= 0x000F; // Возвращает R0–R3 задатчика в быстром потоке: маска 0x000F выбирает четыре младших регистра, чтобы подтверждение R3 для ПМ67 не ожидало медленного обхода параметров.
|
||||
Maska[m_SLOW][6]|= 0x01FC; // Яркость ламп и одиночество
|
||||
break;
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* Параметры и обработчики Modbus после проверки CRC. Массив modbus
|
||||
* содержит обычные адреса 0..127, область 0x1000 обслуживает логгер.
|
||||
* EEPROM хранит параметры, но не является источником START/STOP:
|
||||
* при загрузке сохраняется последняя живая команда нагрузки.
|
||||
* Функции вызываются из main; EEPROM блокирует этот контекст.
|
||||
/* Параметры и обработчики Modbus после проверки CRC. Массив modbus
|
||||
* содержит обычные адреса 0..127, область 0x1000 обслуживает логгер.
|
||||
* EEPROM хранит параметры, но не является источником START/STOP:
|
||||
* при загрузке сохраняется последняя живая команда нагрузки.
|
||||
* Функции вызываются из main; EEPROM блокирует этот контекст.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
||||
#include "package.h"
|
||||
@@ -21,12 +21,9 @@
|
||||
#include "ecan.h"
|
||||
#include "pulto.h"
|
||||
#include "spise2p.h"
|
||||
#include "include/balsam167_eeprom_block.h" /* Использует общий с 167 контракт FC03: окно 0x8000..0xBFFF, до 120 слов AT25256B за запрос. */
|
||||
|
||||
#include "caliber.h"
|
||||
#include "log_to_mem.h"
|
||||
#include "firmware_info.h" /* Подключает адрес и границы неизменяемого паспорта 0x1200, совместимого с проверкой прошивки в 167. */
|
||||
#include "../src/firmware_info_static.c" /* Собирает общие 12 слов firmware-info через include-путь firmware-info/include; как в 167, копии упаковщика в проекте нет. */
|
||||
#include "DAC.h"
|
||||
|
||||
int modbus[ANSWER_LEN+1];
|
||||
@@ -50,7 +47,7 @@ void Default_params()
|
||||
|
||||
for(i=0;i<ANSWER_LEN;i++)
|
||||
{
|
||||
/* Команда нагрузки не является параметром по умолчанию. */
|
||||
/* Команда нагрузки не является параметром по умолчанию. */
|
||||
if (Desk != dsk_LOAD || i != 127) Modbus[i].all = 0;
|
||||
}
|
||||
|
||||
@@ -59,17 +56,17 @@ void Default_params()
|
||||
|
||||
if(Desk == dsk_EPLT)
|
||||
{
|
||||
Cancount[m_FAST] = 10; // Задаёт для пульта быстрый CAN-пакет раз в 10 базовых интервалов CANPOWSE по 20 мс, то есть примерно 200 мс; это значение по умолчанию, которое могут заменить параметры EEPROM.
|
||||
Cancount[m_FAST] = 2; // пауза между посылками CAN
|
||||
|
||||
for(i=0;i<6;i++) Bright[i] = bright[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
Cancount[m_FAST] = 12; // пауза между посылками CAN
|
||||
Cancount[m_FAST] = 10; // пауза между посылками CAN
|
||||
Brightness = 8;
|
||||
}
|
||||
|
||||
Cancount[m_SLOW] = 50; // Задаёт медленную CAN-рассылку раз в 50 базовых интервалов CANPOWSE по 20 мс, то есть примерно раз в секунду; это значение по умолчанию могут заменить параметры EEPROM.
|
||||
Cancount[m_SLOW] = 101; // пауза между посылками CAN
|
||||
|
||||
if(Kalibro)
|
||||
{
|
||||
@@ -129,9 +126,9 @@ void Default_params()
|
||||
DAC_20 = Caliber[6];
|
||||
DAC_04 = Caliber[7];
|
||||
|
||||
/* Не врема!
|
||||
DAC_go = 6; // начало зарада
|
||||
DAC_stop= 15; // конец зарада
|
||||
/* Не врема!
|
||||
DAC_go = 6; // начало зарада
|
||||
DAC_stop= 15; // конец зарада
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -142,9 +139,9 @@ void Default_params()
|
||||
Init_sensors_more();
|
||||
}
|
||||
|
||||
/* CRC и Mode проверяются до применения EEPROM. Слово 127
|
||||
* нагрузки не копируется даже временно: ISR не должен увидеть
|
||||
* старый START из EEPROM либо потерять текущую CAN-команду.
|
||||
/* CRC и Mode проверяются до применения EEPROM. Слово 127
|
||||
* нагрузки не копируется даже временно: ISR не должен увидеть
|
||||
* старый START из EEPROM либо потерять текущую CAN-команду.
|
||||
*/
|
||||
void Load_params()
|
||||
{
|
||||
@@ -156,7 +153,7 @@ void Load_params()
|
||||
(crc !=0xFFFF) &&
|
||||
(Mode == param[126]))
|
||||
{
|
||||
/* Не восстанавливать START/STOP из EEPROM даже на один тик ISR. */
|
||||
/* Не восстанавливать START/STOP из EEPROM даже на один тик ISR. */
|
||||
for(i=0;i<ANSWER_LEN;i++)
|
||||
if (Desk != dsk_LOAD || i != 127) modbus[i] = param[i];
|
||||
UMP_reset_parameter_commands();
|
||||
@@ -172,9 +169,9 @@ void Load_params()
|
||||
Caliber_time = 0xFFFF;
|
||||
} } }
|
||||
|
||||
/* ISR продолжает менять измерения во время сбора param. CRC
|
||||
* относится к собранному массиву, а не атомарному снимку всей платы.
|
||||
* Не вызывать сохранение из критического пути дискретов.
|
||||
/* ISR продолжает менять измерения во время сбора param. CRC
|
||||
* относится к собранному массиву, а не атомарному снимку всей платы.
|
||||
* Не вызывать сохранение из критического пути дискретов.
|
||||
*/
|
||||
void Save_params()
|
||||
{
|
||||
@@ -194,8 +191,8 @@ void Save_params()
|
||||
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
/* Передача данных по протоколу ModBus - команда 3
|
||||
Чтение ачеек данных */
|
||||
/* Передача данных по протоколу ModBus - команда 3
|
||||
Чтение ачеек данных */
|
||||
/***************************************************************/
|
||||
/***************************************************************/
|
||||
|
||||
@@ -215,63 +212,40 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
{
|
||||
unsigned int crc, Address_MB, Length_MB, i, value, saved = 0;
|
||||
|
||||
// получили начальный адрес чтениа
|
||||
// получили начальный адрес чтениа
|
||||
Address_MB = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3];
|
||||
|
||||
// получили количество слов данных
|
||||
// получили количество слов данных
|
||||
Length_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5];
|
||||
if (Address_MB >= BALSAM167_EEPROM_RTU_BASE) { /* Выделяет только верхнее окно EEPROM; старые регистры, логгер и паспорт обрабатываются прежним кодом ниже. */
|
||||
if (!balsam167_eeprom_block_valid_profile(CMD_MODBUS_3, Address_MB, Length_MB, 0U)) { /* Профиль 0 сохраняет контракт 167 для 32 КиБ: запрещает пустой блок, более 120 слов, M95 и выход за конец окна. */
|
||||
modbus_exception(rs_arr, CMD_MODBUS_3, 2U); /* Возвращает Illegal Data Address с CRC до любого обращения к SPI при неверном диапазоне. */
|
||||
return; /* Не допускает перехода ошибочного запроса EEPROM к backend логгера или обычным регистрам. */
|
||||
} /* Валидатор проверяет конец через вычитание, поэтому переполнение 16-битного адреса не разрешает чтение. */
|
||||
Seeprom_read(Address_MB - BALSAM167_EEPROM_RTU_BASE, &rs_arr->buffer[3], Length_MB * 2U); /* Как в 167, SPI получает адрес в 16-битных словах и длину в октетах; IRQ остаются разрешены для автомата Timer2. */
|
||||
for (i = Length_MB; i > 0U; --i) { /* Разворачивает прочитанные слова с конца в том же UART-буфере без нового массива и перезаписи ещё не обработанных слов. */
|
||||
value = rs_arr->buffer[i + 2U]; /* Временное слово сохраняет оба SPI-октета до расширения одного элемента C28x в два октета RTU. */
|
||||
rs_arr->buffer[i * 2U + 2U] = value & 0xFFU; /* Записывает младший октет слова после старшего, как требует физический дамп EEPROM в SETGUI. */
|
||||
rs_arr->buffer[i * 2U + 1U] = (value >> 8) & 0xFFU; /* Маска 0xFF выделяет восемь бит линии из 16-битного unsigned int C28x. */
|
||||
} /* Обратный обход корректен и для одного слова, и для максимального блока из 120 слов. */
|
||||
rs_arr->buffer[0] = CNTRL_ADDR; /* Отвечает собственным адресом платы, сохраняя поддержку общего адреса 16 существующим приёмником. */
|
||||
rs_arr->buffer[1] = CMD_MODBUS_3; /* Возвращает стандартную команду FC03 без введения отдельной команды BIOS или записи памяти. */
|
||||
rs_arr->buffer[2] = Length_MB * 2U; /* Число полезных октетов находится в диапазоне 2..240 и помещается в одном октете RTU. */
|
||||
crc = get_crc_16(0xFFFFU, rs_arr->buffer, Length_MB * 2U + 3U); /* Проверяет адрес, команду, длину и весь блок тем же Modbus CRC16, что остальные ответы прошивки. */
|
||||
rs_arr->buffer[Length_MB * 2U + 3U] = LOBYTE(crc); /* Передаёт младший октет CRC первым в соответствии с Modbus RTU. */
|
||||
rs_arr->buffer[Length_MB * 2U + 4U] = HIBYTE(crc); /* Завершает кадр старшим октетом CRC без устаревшего нулевого хвоста. */
|
||||
rs_arr->flag_TIMEOUT_to_Send = true; /* Использует штатное управление таймаутом UART при отправке готового ответа из main. */
|
||||
RS_Send(rs_arr, rs_arr->buffer, Length_MB * 2U + 5U); /* Отправляет ровно 5 служебных октетов плюс данные, максимум 245 элементов из существующего буфера на 400. */
|
||||
return; /* Завершает только новый маршрут EEPROM, сохраняя прежние форматы остальных ответов FC03. */
|
||||
} /* Новый маршрут не меняет PEEK, запись EEPROM, адреса параметров или драйвер SPI. */
|
||||
if (!Length_MB || Length_MB > 125 ||
|
||||
!((Address_MB < ANSWER_LEN && Length_MB <= ANSWER_LEN-Address_MB) ||
|
||||
(Address_MB >= UMP_LOG_BASE && Address_MB <= UMP_LOG_BASE+15 &&
|
||||
Length_MB <= UMP_LOG_BASE+16-Address_MB) ||
|
||||
(Address_MB >= UMP_LOG_DATA && Address_MB < UMP_LOG_DATA+120 &&
|
||||
Length_MB <= UMP_LOG_DATA+120-Address_MB) ||
|
||||
(Address_MB == UMP_LOG_LIVE && Length_MB == 124) || /* Сохраняет точное прежнее 124-словное онлайн-окно логгера. */
|
||||
firmware_info_range(Address_MB, Length_MB))) { /* Дополнительно разрешает только полное или частичное чтение двенадцати регистров паспорта. */
|
||||
(Address_MB == UMP_LOG_LIVE && Length_MB == 124))) {
|
||||
modbus_exception(rs_arr, CMD_MODBUS_3, 2); return;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Отсылка
|
||||
/* Посчитали контрольную сумму перед самой посылкой */
|
||||
// Отсылка
|
||||
/* Посчитали контрольную сумму перед самой посылкой */
|
||||
|
||||
rs_arr->buffer[0] = CNTRL_ADDR;
|
||||
rs_arr->buffer[1] = CMD_MODBUS_3;
|
||||
rs_arr->buffer[2] = Length_MB*2;
|
||||
|
||||
/* Защищаем целостность одного снимка/блока; передача UART идёт уже
|
||||
* с разрешёнными прерываниями и не задерживает измерение/управление. */
|
||||
if (Address_MB >= UMP_LOG_BASE && Address_MB < FIRMWARE_INFO_ADDRESS) saved = __disable_interrupts(); /* Неизменяемый паспорт не требует блокировки IRQ; целостность прежних снимков логгера сохраняется. */
|
||||
/* Защищаем целостность одного снимка/блока; передача UART идёт уже
|
||||
* с разрешёнными прерываниями и не задерживает измерение/управление. */
|
||||
if (Address_MB >= UMP_LOG_BASE) saved = __disable_interrupts();
|
||||
for (i=0;i<Length_MB;i++)
|
||||
{
|
||||
if (Address_MB >= FIRMWARE_INFO_ADDRESS) value = firmware_info_static_read(Address_MB - FIRMWARE_INFO_ADDRESS + i); /* После проверки диапазона читает только соответствующее слово статического паспорта, без обращения к логгеру. */
|
||||
else value = Address_MB >= UMP_LOG_BASE ? ump_log_read(Address_MB+i) : (unsigned int)modbus[Address_MB+i]; /* Сохраняет прежнюю маршрутизацию и беззнаковое представление 16-битных слов технологической карты и логгера v4. */
|
||||
value = Address_MB >= UMP_LOG_BASE ? ump_log_read(Address_MB+i) : modbus[Address_MB+i];
|
||||
rs_arr->buffer[3+i*2] = (value >> 8) & 0xFF;
|
||||
rs_arr->buffer[3+i*2+1] = value & 0xFF;
|
||||
}
|
||||
|
||||
if (Address_MB >= UMP_LOG_BASE && Address_MB < FIRMWARE_INFO_ADDRESS) __restore_interrupts(saved); /* Возвращает сохранённую маску только для действительно защищённого снимка логгера. */
|
||||
if (Address_MB >= UMP_LOG_BASE) __restore_interrupts(saved);
|
||||
crc = 0xffff;
|
||||
crc = get_crc_16(crc, rs_arr->buffer, Length_MB*2+3);
|
||||
|
||||
@@ -284,9 +258,9 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr)
|
||||
rs_arr->buffer[Length_MB*2+8] = 0;
|
||||
|
||||
rs_arr->flag_TIMEOUT_to_Send=true;
|
||||
/* Расширение логгера отвечает точным кадром Modbus без хвостовых
|
||||
* нулей: они иначе попали бы в начало ответа следующего блока GUI.
|
||||
* Исторический формат технологических регистров оставлен прежним. */
|
||||
/* Расширение логгера отвечает точным кадром Modbus без хвостовых
|
||||
* нулей: они иначе попали бы в начало ответа следующего блока GUI.
|
||||
* Исторический формат технологических регистров оставлен прежним. */
|
||||
RS_Send(rs_arr, rs_arr->buffer, Length_MB*2+(Address_MB >= UMP_LOG_BASE ? 5 : 8));
|
||||
|
||||
return;
|
||||
@@ -297,27 +271,26 @@ void ReceiveCommandModbus6(RS_DATA *rs_arr)
|
||||
unsigned int Address_MB, Data_MB, i;
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
// Отсылка
|
||||
/* Отправлаем назад то же самое */
|
||||
// Отсылка
|
||||
/* Отправлаем назад то же самое */
|
||||
|
||||
for (i=0;i<8;i++)
|
||||
rs_arr->buffer[i] = rs_arr->RS_Header[i];
|
||||
|
||||
|
||||
// получили начальный адрес записи
|
||||
// получили начальный адрес записи
|
||||
Address_MB = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3];
|
||||
|
||||
// получили слово данных
|
||||
// получили слово данных
|
||||
Data_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5];
|
||||
if (Address_MB >= FIRMWARE_INFO_ADDRESS && Address_MB < FIRMWARE_INFO_END) { modbus_exception(rs_arr, CMD_MODBUS_6, 2); return; } /* Как в контракте 167, запись в паспорт запрещена с Illegal Data Address и не достигает параметров или логгера. */
|
||||
|
||||
if (Address_MB >= UMP_LOG_BASE) {
|
||||
if (!ump_log_write(Address_MB, Data_MB)) {
|
||||
modbus_exception(rs_arr, CMD_MODBUS_6, 3); return;
|
||||
}
|
||||
} else if (Address_MB < ANSWER_LEN) {
|
||||
/* RS и CAN используют одну историю фронтов. Чередование каналов
|
||||
* не создаёт двух независимых повторных запусков. */
|
||||
/* RS и CAN используют одну историю фронтов. Чередование каналов
|
||||
* не создаёт двух независимых повторных запусков. */
|
||||
if (Address_MB == 127) {
|
||||
UMP_commands_write(Data_MB);
|
||||
ump_log_rs();
|
||||
|
||||
@@ -51,10 +51,10 @@ void get_Mode()
|
||||
{
|
||||
EALLOW;
|
||||
|
||||
GpioCtrlRegs.GPAMUX1.all &= 0xFF000000; // 00—11
|
||||
GpioCtrlRegs.GPAMUX2.all &= 0xFF00003F; // 19—27
|
||||
GpioCtrlRegs.GPBMUX1.all &= 0xFFFFFFC0; // 32—34
|
||||
GpioCtrlRegs.GPBMUX2.all &= 0x000FF000; // 48—53, 58—63
|
||||
GpioCtrlRegs.GPAMUX1.all &= 0xFF000000; // Обнуляет двухбитовые поля MUX для GPIO0–11 по карте регистров TMS320F28335, выбирая обычный GPIO и сохраняя назначение GPIO12–15.
|
||||
GpioCtrlRegs.GPAMUX2.all &= 0xFF00003F; // Выбирает обычный GPIO для выводов 19–27: маска сохраняет поля GPIO16–18 и GPIO28–31 в двухбитовой таблице MUX.
|
||||
GpioCtrlRegs.GPBMUX1.all &= 0xFFFFFFC0; // Обнуляет младшие шесть битов MUX, переводя GPIO32–34 в режим обычных входов или выходов без изменения остальных выводов банка.
|
||||
GpioCtrlRegs.GPBMUX2.all &= 0x000FF000; // Сохраняет поля GPIO54–57 и переводит GPIO48–53 и GPIO58–63 в обычный GPIO согласно двухбитовой раскладке GPBMUX2.
|
||||
|
||||
GpioCtrlRegs.GPADIR.bit.GPIO20 = 0;
|
||||
GpioCtrlRegs.GPADIR.bit.GPIO21 = 0;
|
||||
@@ -205,14 +205,15 @@ void get_Buttons()
|
||||
|
||||
if(Desk==dsk_EPLT)
|
||||
{
|
||||
/* Таймер пульта включает местный тест после непрерывного удержания TESTLAMP в течение 2 с; число проходов main не влияет на задержку. */
|
||||
/* Сохраняет TESTLAMP до достижения порога фильтра: 1000 означает число опросов главного цикла, а bTestLamp удерживает прежний режим при кратком провале GPIO26, чтобы рабочие маски не прерывали тест индикации. */
|
||||
bTestLamp = er_anal(GpioDataRegs.GPADAT.bit.GPIO26, &INcount0, 1000, bTestLamp);
|
||||
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO27) butt +=0x0001;
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO24) butt +=0x0002;
|
||||
if(GpioDataRegs.GPBDAT.bit.GPIO53) butt +=0x0004;
|
||||
if(GpioDataRegs.GPBDAT.bit.GPIO50) butt +=0x0008;
|
||||
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO26) butt +=0x0010; // Передаёт исходное состояние TESTLAMP в бите 4 слова Inputs (0x10), по которому основной контроллер вызывает сброс ошибок при коротком нажатии.
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO26) butt +=0x0010;
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO23) butt +=0x0020;
|
||||
if(GpioDataRegs.GPBDAT.bit.GPIO52) butt +=0x0040;
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO4 ) butt +=0x0080;
|
||||
@@ -223,7 +224,7 @@ void get_Buttons()
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO5 ) butt +=0x0800;
|
||||
|
||||
if(GpioDataRegs.GPBDAT.bit.GPIO48) butt +=0x1000;
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO10) butt +=0x2000; // Секретный вход
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO10) butt +=0x2000; // Публикует активный секретный вход GPIO10 в бите 13 слова Inputs; маска 0x2000 задаёт назначенную ему позицию протокола.
|
||||
|
||||
Inputs.all = butt;
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ interrupt void cpu_timer1_isr_PULT(void)
|
||||
static int cownt=0,count_bright;
|
||||
unsigned int light=0, i;
|
||||
unsigned int Alone = 20*READY_FREQ;
|
||||
static unsigned int test_lamp_hold_ticks = 0; // Считает длительность непрерывного нажатия GPIO26 в тиках READY_FREQ; насыщение на пороге исключает переполнение при долгом удержании.
|
||||
|
||||
EALLOW;
|
||||
CpuTimer1.InterruptCount++;
|
||||
IER |= MINT13; // Set "global" priority
|
||||
/* Оставляет только ранее разрешённые источники по таблице приоритетов TI MINT13 и сбрасывает M_INT13 — бит 12 регистра IER, запрещая повторный Timer1 и перемешивание стробов DATA/CLOCK; исходную маску восстановит IRET. */
|
||||
IER &= (MINT13 & ~M_INT13);
|
||||
EINT;
|
||||
EDIS; // This is needed to disable write to EALLOW protected registers
|
||||
|
||||
@@ -61,8 +61,8 @@ interrupt void cpu_timer1_isr_PULT(void)
|
||||
|
||||
toggle_ONLINE();
|
||||
|
||||
toggle_RES_OUT_1(); // Формирует на резервном выходе 1 меандр с частотой READY_FREQ/2 (500 Гц) для контроля работы таймера пульта.
|
||||
toggle_RES_OUT_2(); // Дублирует переключения таймера на резервном выходе 2 с частотой READY_FREQ/2 (500 Гц) для контроля активности пульта.
|
||||
toggle_RES_OUT_1(); // Переключает резервный выход RES_OUT_1 в каждом такте пульта, сохраняя существующую выдачу признака активности обработчика.
|
||||
toggle_RES_OUT_2(); // Переключает второй резервный выход RES_OUT_2 синхронно с тактом пульта, сохраняя существующее поведение этого режима платы.
|
||||
|
||||
if(++Lonely > Alone) Lonely = Alone;
|
||||
|
||||
@@ -75,14 +75,6 @@ interrupt void cpu_timer1_isr_PULT(void)
|
||||
|
||||
if(++cownt>2) cownt=0;
|
||||
|
||||
if(GpioDataRegs.GPADAT.bit.GPIO26) // Единица GPIO26 означает нажатие TESTLAMP, как и бит 4 Inputs; таймер измеряет удержание независимо от загрузки main.
|
||||
{ // Накапливает время текущего нажатия перед включением местного теста ламп.
|
||||
if(test_lamp_hold_ticks < 2U * (unsigned int)READY_FREQ) // Две секунды при частоте READY_FREQ Гц соответствуют 2000 тикам текущего таймера 1000 Гц.
|
||||
test_lamp_hold_ticks++; // Добавляет один период таймера (1 мс); после достижения порога счётчик сохраняет значение до отпускания.
|
||||
} // Завершает обработку удерживаемой кнопки.
|
||||
else test_lamp_hold_ticks = 0; // При отпускании обнуляет время, чтобы отдельные короткие нажатия не складывались в длинное.
|
||||
bTestLamp = (test_lamp_hold_ticks >= 2U * (unsigned int)READY_FREQ); // Включает местный тест после 2 с удержания и выключает при отпускании; короткое нажатие остаётся сигналом сброса для основного контроллера.
|
||||
|
||||
if(cTestLamp|bTestLamp)
|
||||
{
|
||||
what_is();
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
/* SPI EEPROM. Seeprom_read/write разбивают запрос на страницы
|
||||
* и синхронно ждут spiSe2pFree. SPI-автомат продвигает таймер 2
|
||||
* каждые 100 мкс. При запрете этого IRQ ожидание не завершится.
|
||||
* Тайм-аут в старом драйвере отсутствует. Дискреты СИФУ теперь
|
||||
* не зависят от того, завершилось ли это ожидание в main.
|
||||
/* SPI EEPROM. Seeprom_read/write разбивают запрос на страницы
|
||||
* и синхронно ждут spiSe2pFree. SPI-автомат продвигает таймер 2
|
||||
* каждые 100 мкс. При запрете этого IRQ ожидание не завершится.
|
||||
* Тайм-аут в старом драйвере отсутствует. Дискреты СИФУ теперь
|
||||
* не зависят от того, завершилось ли это ожидание в main.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
|
||||
|
||||
@@ -25,8 +25,8 @@ int ccc=0;
|
||||
/******* SPI bus Serial EEPROM driver Initialization routine ********/
|
||||
/********************************************************************/
|
||||
|
||||
/* Блокирует main до завершения страниц. Запрет IRQ остановит
|
||||
* SPI-автомат. CAN и таймер СИФУ должны прерывать это ожидание.
|
||||
/* Блокирует main до завершения страниц. Запрет IRQ остановит
|
||||
* SPI-автомат. CAN и таймер СИФУ должны прерывать это ожидание.
|
||||
*/
|
||||
void Seeprom_write( unsigned int adres,
|
||||
unsigned int buf[],
|
||||
@@ -59,8 +59,8 @@ void Seeprom_write( unsigned int adres,
|
||||
CpuTimer2Regs.TCR.all = 0x4010; // Use write-only instruction to set TSS bit = 1
|
||||
}
|
||||
|
||||
/* Чтение также синхронное для main, тайм-аут не реализован.
|
||||
* При зависании проверить step/SPI и работу таймера 2.
|
||||
/* Чтение также синхронное для main, тайм-аут не реализован.
|
||||
* При зависании проверить step/SPI и работу таймера 2.
|
||||
*/
|
||||
void Seeprom_read( unsigned int adres,
|
||||
unsigned int buf[],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* Внешняя память и программные задержки. init_zone7 готовит XINTF
|
||||
* до первого обращения к .logg; времена шины зависят от частоты DSP
|
||||
* и аппаратной памяти. pause_us занимает CPU циклом и используется
|
||||
* при инициализации. Длительность СИФУ должна задаваться таймером.
|
||||
/* Внешняя память и программные задержки. init_zone7 готовит XINTF
|
||||
* до первого обращения к .logg; времена шины зависят от частоты DSP
|
||||
* и аппаратной памяти. pause_us занимает CPU циклом и используется
|
||||
* при инициализации. Длительность СИФУ должна задаваться таймером.
|
||||
*/
|
||||
#include "DSP2833x_Device.h" // DSP281x Headerfile Include File
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>28335_periph</name>
|
||||
<name>Balsam_166</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
@@ -28,177 +28,162 @@
|
||||
<link>
|
||||
<name>F28335.cmd</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/F28335.cmd</locationURI>
|
||||
<locationURI>SRC_ROOT1/F28335.cmd</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>UKSSTMS320F28335.pjt</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/UKSSTMS320F28335.pjt</locationURI>
|
||||
<locationURI>SRC_ROOT1/UKSSTMS320F28335.pjt</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Debug/UKSSTMS320F28335.out</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Bin/UKSSTMS320F28335.out</locationURI>
|
||||
<locationURI>SRC_ROOT/Bin/UKSSTMS320F28335.out</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Libraries/rts2800_fpu32.lib</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Libraries/rts2800_fpu32.lib</locationURI>
|
||||
<locationURI>SRC_ROOT1/Libraries/rts2800_fpu32.lib</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/ADC.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/ADC.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/ADC.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/DAC.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/DAC.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/Include</name>
|
||||
<type>2</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/Include</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/DAC.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/RS485.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/RS485.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/RS485.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/bios.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/bios.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/bios.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/cntrl_adr.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/cntrl_adr.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/cntrl_adr.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/crc16.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/crc16.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/crc16.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/ecan.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/ecan.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/ecan.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/filter_bat2.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/filter_bat2.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/filter_bat2.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/kanal.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/kanal.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/kanal.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/log_to_mem.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/log_to_mem.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/log_to_mem.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/main.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/main.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/main.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/measure.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/measure.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/measure.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/message.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/message.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/message.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/peripher.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/peripher.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/peripher.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/pulto.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/pulto.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/pulto.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/spise2p.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/spise2p.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/spise2p.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/Internal/tools.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/Internal/tools.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/include</name>
|
||||
<type>2</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/include</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_headers/include</name>
|
||||
<type>2</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_headers/include</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/Internal/tools.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_ADC_cal.asm</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_ADC_cal.asm</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_ADC_cal.asm</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_Adc.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_Adc.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_Adc.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_CpuTimers.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_CpuTimers.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_CpuTimers.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_PieCtrl.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_PieCtrl.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_PieCtrl.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_SWPrioritizedDefaultIsr.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_SWPrioritizedDefaultIsr.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_SWPrioritizedDefaultIsr.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_SWPrioritizedPieVect.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_SWPrioritizedPieVect.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_SWPrioritizedPieVect.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_SysCtrl.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_SysCtrl.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_SysCtrl.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_Xintf.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_Xintf.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_Xintf.c</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_common/source/DSP2833x_usDelay.asm</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_common/source/DSP2833x_usDelay.asm</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_common/source/DSP2833x_usDelay.asm</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd</locationURI>
|
||||
</link>
|
||||
<link>
|
||||
<name>Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c</name>
|
||||
<type>1</type>
|
||||
<locationURI>SRC_ROOT12/Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c</locationURI>
|
||||
<locationURI>SRC_ROOT1/Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c</locationURI>
|
||||
</link>
|
||||
</linkedResources>
|
||||
<variableList>
|
||||
@@ -210,9 +195,5 @@
|
||||
<name>SRC_ROOT1</name>
|
||||
<value>$%7BPARENT-1-PROJECT_LOC%7D</value>
|
||||
</variable>
|
||||
<variable>
|
||||
<name>SRC_ROOT12</name>
|
||||
<value>file:/K:/git_project/28335_periph</value>
|
||||
</variable>
|
||||
</variableList>
|
||||
</projectDescription>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
ccsVersionValidationPolicy=warning
|
||||
compilerVersionValidationPolicy=flexible
|
||||
eclipse.preferences.version=1
|
||||
productVersionsValidationPolicy=flexible
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user