From 1e911e5250c04d38f455108495e701d80d5f2e4f Mon Sep 17 00:00:00 2001 From: Andrey Date: Mon, 12 Oct 2026 12:25:41 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=B8=D1=82?= =?UTF-8?q?=D1=8C=20=D0=BB=D0=BE=D0=B3=D0=B3=D0=B5=D1=80=20=D0=A3=D0=9C?= =?UTF-8?q?=D0=9F=20=D0=B8=20=D0=B8=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D1=82=D1=8C=20=D0=B7=D0=B0=D0=BF=D1=83=D1=81=D0=BA=20UART=20?= =?UTF-8?q?=D0=B8=20EEPROM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Перейти на компактные 12-словные записи v4 и сохранять 10 процентов банка после отключения. Добавить трёхсекундное ожидание роста ЗПТ и настраиваемый лимит пусков. Явно инициализировать состояние UART и гарантировать публикацию параметров EEPROM перед запуском Timer2. Сохранить воспроизводимые сборки, регрессионные проверки, документацию и обновлённые результаты сборки; исключить временные артефакты. --- .gitignore | 34 + Bin/EepromPublishFix/rebuild.py | 41 + Bin/StartupWait3s/rebuild.py | 41 + Bin/UKSSTMS320F28335.hex | Bin 77264 -> 32074 bytes Bin/UKSSTMS320F28335.map | 14 +- Bin/UartColdStart/rebuild.py | 41 + Doc/COMMENT_AUDIT.md | 46 +- Doc/GAS_167_M95M02.md | 5 +- Doc/GAS_ADDRESS_ALLOCATION.md | 2 +- Doc/GAS_MODBUS_MAP.md | 13 +- Doc/SOURCE_GUIDE.md | 16 +- Doc/UMP_LOGGER.md | 206 +- Doc/UMP_VOLTAGE_PROTECTION.md | 55 +- Source/Internal/DAC.c | 123 +- Source/Internal/Include/log_to_mem.h | 6 +- Source/Internal/Include/message.h | 2 +- Source/Internal/Include/package.h | 8 +- Source/Internal/Include/spise2p.h | 10 +- Source/Internal/RS485.c | 4 + Source/Internal/ecan.c | 32 +- Source/Internal/gas167.c | 8 +- Source/Internal/log_to_mem.c | 74 +- Source/Internal/main.c | 4 +- Source/Internal/measure.c | 2 +- Source/Internal/message.c | 41 +- UKSSTMS320F28335.map | 2329 +++++++++++--------- UKSSTMS320F28335/.cproject | 6 +- UKSSTMS320F28335/README.md | 4 + tests/comments/run_test.py | 18 +- tests/eeprom_profiles/check_publication.py | 18 + tests/gas167/gas167_test.c | 48 +- tests/gas167/run_test.py | 15 + tests/load_control/load_control_test.c | 210 +- tests/load_control/stubs/package.h | 6 +- tests/rs232_fifo/model.inc | 10 + tests/rs232_fifo/run_test.py | 4 +- tests/ump_logger/init_test.c | 24 +- tests/ump_logger/recorder_test.c | 54 +- 38 files changed, 2089 insertions(+), 1485 deletions(-) create mode 100644 Bin/EepromPublishFix/rebuild.py create mode 100644 Bin/StartupWait3s/rebuild.py create mode 100644 Bin/UartColdStart/rebuild.py create mode 100644 tests/eeprom_profiles/check_publication.py diff --git a/.gitignore b/.gitignore index dfa3c52..c36d6e1 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,37 @@ /Bin/*.bin.manifest.json # Исключает из Git артефакты по шаблону ниже. /Bin/*.bin.sha256 +# Кэш Python восстанавливается автоматически и не относится к исходникам прошивки. +**/__pycache__/ +# Загруженные локальные инструменты документации не нужны для хранения изменений проекта. +/Doc/.tools/ +# HTML-документация и диагностические журналы Doxygen создаются из исходных документов. +/Doc/build/ +# Объекты компиляции восстанавливаются скриптами сборки и зависят от локальных инструментов TI. +/Bin/**/obj/ +# Паспорт и заголовок конкретной сборки генерируются перед компиляцией из версии и состояния Git. +/Bin/**/generated/ +# Исполняемые образы TI в экспериментальных каталогах являются результатом компиляции. +/Bin/**/*.out +# Карты новых сборок воспроизводятся линкером; ранее отслеживаемые карты остаются в Git. +/Bin/**/*.map +# HEX новых сборок дублирует локальные OUT/BIN; уже отслеживаемые образы сохраняются в истории. +/Bin/**/*.hex +# Листинги TI создаются из OUT для проверки порядка машинных инструкций EEPROM. +/Bin/**/*disassembly*.txt +# Кандидат SCI8 предназначен для проверки перед выпуском окончательного образа. +/Bin/**/*.candidate +# Локальные загрузочные образы пересоздаются из исходников и скриптов соответствующей сборки. +/Bin/**/*.bin +# Манифест конкретного образа содержит время и состояние локальной сборки. +/Bin/**/*.bin.manifest.json +# Контрольная сумма создаётся вместе с локальным загрузочным образом. +/Bin/**/*.bin.sha256 +# Журналы компиляции и диагностики зависят от локального запуска инструментов. +/Bin/**/*.log +# Копии паспорта в каталогах с отметкой времени дублируют генерируемые метаданные сборки. +/Bin/**/firmware_identity.json +# Снимки интерфейса, использованные для проверки состава каналов, являются локальными артефактами. +/Bin/**/logger_channels.png +# Снимки предпросмотра защиты используются только при визуальной проверке интерфейса. +/Bin/**/gui_preview.png diff --git a/Bin/EepromPublishFix/rebuild.py b/Bin/EepromPublishFix/rebuild.py new file mode 100644 index 0000000..c65f869 --- /dev/null +++ b/Bin/EepromPublishFix/rebuild.py @@ -0,0 +1,41 @@ +from pathlib import Path # Формирует абсолютные пути сборки и установленных инструментов TI. +import subprocess # Выполняет компиляцию и проверку без shell-подстановок. +import json # Читает фактический идентификатор текущей сборки из её паспорта. +import sys # Использует текущий Python для подготовки паспорта и образа. +root = Path.cwd().resolve() # Фиксирует разрешённый корень проекта. +out = root / 'Bin/EepromPublishFix' # Изолирует исправление публикации задания EEPROM от предыдущих образов. +obj = out / 'obj' # Хранит объекты полной текущей пересборки. +gen = out / 'generated' # Хранит паспорт текущих исходников. +for directory in (out, obj, gen): # Создаёт только подкаталоги этой сборки. + directory.mkdir(parents=True, exist_ok=True) # Не удаляет старые файлы проекта. +ti = Path('C:/ti/ccs1230/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS') # Повторяет установленный компилятор CCS. +templates = root.parent / 'newProject/templates' # Использует штатную общую библиотеку проекта. +protocol = templates / 'c/set-protocol' # Задаёт интерфейсы и карту памяти УМП. +name = 'UKSSTMS320F28335_eeprom_fix' # Обозначает исправление обмена заданием EEPROM между главным циклом и Timer2. +log = (out / 'build.log').open('w', encoding='utf-8') # Записывает диагностику в UTF-8. +def run(args): # Останавливает сборку при ошибке любого шага. + result = subprocess.run([str(arg) for arg in args], cwd=root, capture_output=True) # Передаёт параметры инструменту напрямую. + output = (result.stdout + result.stderr).decode('utf-8', errors='replace') # Декодирует диагностический вывод. + log.write(output); log.flush() # Сохраняет текущий результат до следующего шага. + if result.returncode: # Запрещает формирование готового BIN после ошибки. + print(output); raise SystemExit(result.returncode) # Показывает причину незавершённой сборки. + return output # Возвращает отчёт успешно выполненного шага. +run([sys.executable, root / 'UKSSTMS320F28335/prepare_identity.py', '--project', root / 'UKSSTMS320F28335', '--templates', templates, '--output', gen]) # Обновляет паспорт перед полной компиляцией. +includes = [root / 'UKSSTMS320F28335', root / 'Source/Internal/Include', root / 'Source/External/v120/DSP2833x_headers/include', root / 'Source/External/v120/DSP2833x_common/include', protocol, protocol / 'ports/tms320f28335', templates / 'c/firmware-info/include', gen, ti / 'include'] # Повторяет каталоги CCS с локальным паспортом сборки. +flags = ['-v28', '-ml', '-mt', '--float_support=fpu32', '-O3', '--opt_for_speed=0', '--define=EEPROM_M95M02=0', '--define=_DEBUG', '--define=LARGE_MODEL', '-g', '--diag_warning=225', '--display_error_number', '--gen_func_subsections=on', '--abi=coffabi'] # Проверяет исправление при оптимизации O3 проекта CCS; EEPROM_M95M02=0 явно выбирает AT25256B. +flags += ['--include_path=' + str(path) for path in includes] # Передаёт каждый каталог отдельным аргументом. +common = root / 'Source/External/v120/DSP2833x_common/source' # Задаёт уже используемый комплект TI. +external = ['DSP2833x_ADC_cal.asm', 'DSP2833x_Adc.c', 'DSP2833x_CpuTimers.c', 'DSP2833x_PieCtrl.c', 'DSP2833x_SWPrioritizedDefaultIsr.c', 'DSP2833x_SWPrioritizedPieVect.c', 'DSP2833x_SysCtrl.c', 'DSP2833x_Xintf.c', 'DSP2833x_usDelay.asm'] # Повторяет штатный список внешних исходников. +sources = [common / item for item in external] + [root / 'Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c'] + sorted((root / 'Source/Internal').glob('*.c')) # Пересобирает все модули после окончательной правки. +for source in sources: # Последовательно компилирует каждый модуль. + run([ti / 'bin/cl2000.exe', *flags, '--obj_directory=' + str(obj), source]) # Проверяет настоящий C28x-код и создаёт новый объект. +objects = [obj / (source.stem + '.obj') for source in sources] # Использует только объекты завершённой текущей компиляции. +run([ti / 'bin/cl2000.exe', '-v28', '-ml', '-mt', '--float_support=fpu32', '--abi=coffabi', '-z', '--map_file=' + str(out / (name + '.map')), '--stack_size=0x3f0', '--warn_sections', '-i' + str(ti / 'lib'), '-i' + str(root), '-i' + str(protocol), '-i' + str(ti / 'include'), '--reread_libs', '--display_error_number', '--entry_point=_c_int00', '--rom_model', '--output_file=' + str(out / (name + '.out')), root / 'F28335.cmd', root / 'Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd', *objects, root / 'Libraries/rts2800_fpu32.lib', '-lrts2800_fpu32.lib', '-llibc.a']) # Линкует со штатной картой памяти и библиотеками времени выполнения. +run([ti / 'bin/hex2000.exe', '--diag_wrap=off', '--boot', '--sci8', '--binary', '-o', out / (name + '.candidate'), out / (name + '.out')]) # Создаёт кандидат загрузочного образа для обязательной проверки размера. +print(run([sys.executable, root / 'tests/gas167/check_image.py', out / (name + '.candidate'), '--eeprom', 'AT25256B']).strip()) # Проверяет EEPROM, RAM-блоки и точку входа до выдачи прошивки. +print(run([sys.executable, templates / 'c/firmware-info/tools/c2000_postbuild.py', '--compiler', ti, '--build-dir', out, '--artifact', name, '--metadata', gen / 'firmware_identity.json', '--output', out]).strip()) # Создаёт штатный BIN, манифест и SHA-256 без экспорта в другие проекты. +bin_path = out / (name + '_' + json.loads((gen / 'firmware_identity.json').read_text(encoding='utf-8'))['build_id'] + '.bin') # Выбирает именно текущую сборку, даже если в каталоге остаются прежние BIN. +print(run([sys.executable, root / 'tests/gas167/check_image.py', bin_path, '--eeprom', 'AT25256B']).strip()) # Повторяет проверку на самом выдаваемом BIN после штатной упаковки. +assert bin_path.read_bytes() == (out / (name + '.candidate')).read_bytes() # Подтверждает совпадение проверенного кандидата и итоговой прошивки. +log.close() # Завершает полный лог успешно проверенной сборки. +print('READY:', bin_path) # Указывает пользователю точный готовый результат. diff --git a/Bin/StartupWait3s/rebuild.py b/Bin/StartupWait3s/rebuild.py new file mode 100644 index 0000000..f356e7a --- /dev/null +++ b/Bin/StartupWait3s/rebuild.py @@ -0,0 +1,41 @@ +from pathlib import Path # Формирует абсолютные пути сборки и установленных инструментов TI. +import subprocess # Выполняет компиляцию и проверку без shell-подстановок. +import json # Читает фактический идентификатор текущей сборки из её паспорта. +import sys # Использует текущий Python для подготовки паспорта и образа. +root = Path.cwd().resolve() # Фиксирует разрешённый корень проекта. +out = root / 'Bin/StartupWait3s' # Изолирует результаты исправленного пуска от прежних прошивок. +obj = out / 'obj' # Хранит объекты полной текущей пересборки. +gen = out / 'generated' # Хранит паспорт текущих исходников. +for directory in (out, obj, gen): # Создаёт только подкаталоги этой сборки. + directory.mkdir(parents=True, exist_ok=True) # Не удаляет старые файлы проекта. +ti = Path('C:/ti/ccs1230/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS') # Повторяет установленный компилятор CCS. +templates = root.parent / 'newProject/templates' # Использует штатную общую библиотеку проекта. +protocol = templates / 'c/set-protocol' # Задаёт интерфейсы и карту памяти УМП. +name = 'UKSSTMS320F28335_startup_3s' # Различает новую прошивку по смыслу исправления. +log = (out / 'build.log').open('w', encoding='utf-8') # Записывает диагностику в UTF-8. +def run(args): # Останавливает сборку при ошибке любого шага. + result = subprocess.run([str(arg) for arg in args], cwd=root, capture_output=True) # Передаёт параметры инструменту напрямую. + output = (result.stdout + result.stderr).decode('utf-8', errors='replace') # Декодирует диагностический вывод. + log.write(output); log.flush() # Сохраняет текущий результат до следующего шага. + if result.returncode: # Запрещает формирование готового BIN после ошибки. + print(output); raise SystemExit(result.returncode) # Показывает причину незавершённой сборки. + return output # Возвращает отчёт успешно выполненного шага. +run([sys.executable, root / 'UKSSTMS320F28335/prepare_identity.py', '--project', root / 'UKSSTMS320F28335', '--templates', templates, '--output', gen]) # Обновляет паспорт перед полной компиляцией. +includes = [root / 'UKSSTMS320F28335', root / 'Source/Internal/Include', root / 'Source/External/v120/DSP2833x_headers/include', root / 'Source/External/v120/DSP2833x_common/include', protocol, protocol / 'ports/tms320f28335', templates / 'c/firmware-info/include', gen, ti / 'include'] # Повторяет каталоги CCS с локальным паспортом сборки. +flags = ['-v28', '-ml', '-mt', '--float_support=fpu32', '-O2', '--opt_for_speed=0', '--define=_DEBUG', '--define=LARGE_MODEL', '-g', '--diag_warning=225', '--display_error_number', '--gen_func_subsections=on', '--abi=coffabi'] # Сохраняет ABI, FPU и существующую оптимизацию размера проекта. +flags += ['--include_path=' + str(path) for path in includes] # Передаёт каждый каталог отдельным аргументом. +common = root / 'Source/External/v120/DSP2833x_common/source' # Задаёт уже используемый комплект TI. +external = ['DSP2833x_ADC_cal.asm', 'DSP2833x_Adc.c', 'DSP2833x_CpuTimers.c', 'DSP2833x_PieCtrl.c', 'DSP2833x_SWPrioritizedDefaultIsr.c', 'DSP2833x_SWPrioritizedPieVect.c', 'DSP2833x_SysCtrl.c', 'DSP2833x_Xintf.c', 'DSP2833x_usDelay.asm'] # Повторяет штатный список внешних исходников. +sources = [common / item for item in external] + [root / 'Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c'] + sorted((root / 'Source/Internal').glob('*.c')) # Пересобирает все модули после окончательной правки. +for source in sources: # Последовательно компилирует каждый модуль. + run([ti / 'bin/cl2000.exe', *flags, '--obj_directory=' + str(obj), source]) # Проверяет настоящий C28x-код и создаёт новый объект. +objects = [obj / (source.stem + '.obj') for source in sources] # Использует только объекты завершённой текущей компиляции. +run([ti / 'bin/cl2000.exe', '-v28', '-ml', '-mt', '--float_support=fpu32', '--abi=coffabi', '-z', '--map_file=' + str(out / (name + '.map')), '--stack_size=0x3f0', '--warn_sections', '-i' + str(ti / 'lib'), '-i' + str(root), '-i' + str(protocol), '-i' + str(ti / 'include'), '--reread_libs', '--display_error_number', '--entry_point=_c_int00', '--rom_model', '--output_file=' + str(out / (name + '.out')), root / 'F28335.cmd', root / 'Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd', *objects, root / 'Libraries/rts2800_fpu32.lib', '-lrts2800_fpu32.lib', '-llibc.a']) # Линкует со штатной картой памяти и библиотеками времени выполнения. +run([ti / 'bin/hex2000.exe', '--diag_wrap=off', '--boot', '--sci8', '--binary', '-o', out / (name + '.candidate'), out / (name + '.out')]) # Создаёт кандидат загрузочного образа для обязательной проверки размера. +print(run([sys.executable, root / 'tests/gas167/check_image.py', out / (name + '.candidate'), '--eeprom', 'AT25256B']).strip()) # Проверяет EEPROM, RAM-блоки и точку входа до выдачи прошивки. +print(run([sys.executable, templates / 'c/firmware-info/tools/c2000_postbuild.py', '--compiler', ti, '--build-dir', out, '--artifact', name, '--metadata', gen / 'firmware_identity.json', '--output', out]).strip()) # Создаёт штатный BIN, манифест и SHA-256 без экспорта в другие проекты. +bin_path = out / (name + '_' + json.loads((gen / 'firmware_identity.json').read_text(encoding='utf-8'))['build_id'] + '.bin') # Выбирает именно текущую сборку, даже если в каталоге остаются прежние BIN. +print(run([sys.executable, root / 'tests/gas167/check_image.py', bin_path, '--eeprom', 'AT25256B']).strip()) # Повторяет проверку на самом выдаваемом BIN после штатной упаковки. +assert bin_path.read_bytes() == (out / (name + '.candidate')).read_bytes() # Подтверждает совпадение проверенного кандидата и итоговой прошивки. +log.close() # Завершает полный лог успешно проверенной сборки. +print('READY:', bin_path) # Указывает пользователю точный готовый результат. diff --git a/Bin/UKSSTMS320F28335.hex b/Bin/UKSSTMS320F28335.hex index 6a392e499c39e343635cc95ff223092c8a28f621..924ecc255b0a714c1d6b5bdc40741d204a1e0b23 100644 GIT binary patch literal 32074 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 literal 77264 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%0A0=_bI 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 diff --git a/Bin/UKSSTMS320F28335.map b/Bin/UKSSTMS320F28335.map index 6c9945c..1755165 100644 --- a/Bin/UKSSTMS320F28335.map +++ b/Bin/UKSSTMS320F28335.map @@ -12,20 +12,20 @@ PHYSICAL MEMORY PARAMETERS BOOT LOADER PARAMETERS Table Type: SERIAL PORT (SCI 8 bit Mode) - Entry Point: 0x0000b9b5 + Entry Point: 0x0000a8d1 OUTPUT TRANSLATION MAP -------------------------------------------------------------------------------- 00000000..003fffff Page=0 Memory Width=8 ROM Width=8 -------------------------------------------------------------------------------- - OUTPUT FILES: UKSSTMS320F28335_34a95bc5.bin [b0..b7] + OUTPUT FILES: UKSSTMS320F28335_c6c91282.bin.pending [b0..b7] - CONTENTS: 00000000..00007f05 BOOT TABLE - .cinit : dest=0000c000 size=0000028b width=00000002 - .text : dest=00008000 size=00003b73 width=00000002 - .econst : dest=0000c28c size=00000125 width=00000002 - .switch : dest=0000c3b2 size=00000048 width=00000002 + CONTENTS: 00000000..00007ffb BOOT TABLE + .cinit : dest=0000c000 size=00000273 width=00000002 + .text : dest=00008000 size=00003bfc width=00000002 + .econst : dest=0000c274 size=0000012b width=00000002 + .switch : dest=0000c3a0 size=0000004c width=00000002 -------------------------------------------------------------------------------- 00000000..003fffff Page=1 Memory Width=8 ROM Width=8 "*DEFAULT PAGE 1*" diff --git a/Bin/UartColdStart/rebuild.py b/Bin/UartColdStart/rebuild.py new file mode 100644 index 0000000..7398f9c --- /dev/null +++ b/Bin/UartColdStart/rebuild.py @@ -0,0 +1,41 @@ +from pathlib import Path # Формирует абсолютные пути сборки и установленных инструментов TI. +import subprocess # Выполняет компиляцию и проверку без shell-подстановок. +import json # Читает фактический идентификатор текущей сборки из её паспорта. +import sys # Использует текущий Python для подготовки паспорта и образа. +root = Path.cwd().resolve() # Фиксирует разрешённый корень проекта. +out = root / 'Bin/UartColdStart' # Изолирует результаты исправления холодного запуска UART от прежней прошивки. +obj = out / 'obj' # Хранит объекты полной текущей пересборки. +gen = out / 'generated' # Хранит паспорт текущих исходников. +for directory in (out, obj, gen): # Создаёт только подкаталоги этой сборки. + directory.mkdir(parents=True, exist_ok=True) # Не удаляет старые файлы проекта. +ti = Path('C:/ti/ccs1230/ccs/tools/compiler/ti-cgt-c2000_22.6.0.LTS') # Повторяет установленный компилятор CCS. +templates = root.parent / 'newProject/templates' # Использует штатную общую библиотеку проекта. +protocol = templates / 'c/set-protocol' # Задаёт интерфейсы и карту памяти УМП. +name = 'UKSSTMS320F28335_uart_init' # Различает прошивку с явной инициализацией UART при холодном запуске. +log = (out / 'build.log').open('w', encoding='utf-8') # Записывает диагностику в UTF-8. +def run(args): # Останавливает сборку при ошибке любого шага. + result = subprocess.run([str(arg) for arg in args], cwd=root, capture_output=True) # Передаёт параметры инструменту напрямую. + output = (result.stdout + result.stderr).decode('utf-8', errors='replace') # Декодирует диагностический вывод. + log.write(output); log.flush() # Сохраняет текущий результат до следующего шага. + if result.returncode: # Запрещает формирование готового BIN после ошибки. + print(output); raise SystemExit(result.returncode) # Показывает причину незавершённой сборки. + return output # Возвращает отчёт успешно выполненного шага. +run([sys.executable, root / 'UKSSTMS320F28335/prepare_identity.py', '--project', root / 'UKSSTMS320F28335', '--templates', templates, '--output', gen]) # Обновляет паспорт перед полной компиляцией. +includes = [root / 'UKSSTMS320F28335', root / 'Source/Internal/Include', root / 'Source/External/v120/DSP2833x_headers/include', root / 'Source/External/v120/DSP2833x_common/include', protocol, protocol / 'ports/tms320f28335', templates / 'c/firmware-info/include', gen, ti / 'include'] # Повторяет каталоги CCS с локальным паспортом сборки. +flags = ['-v28', '-ml', '-mt', '--float_support=fpu32', '-O2', '--opt_for_speed=0', '--define=_DEBUG', '--define=LARGE_MODEL', '-g', '--diag_warning=225', '--display_error_number', '--gen_func_subsections=on', '--abi=coffabi'] # Сохраняет ABI, FPU и существующую оптимизацию размера проекта. +flags += ['--include_path=' + str(path) for path in includes] # Передаёт каждый каталог отдельным аргументом. +common = root / 'Source/External/v120/DSP2833x_common/source' # Задаёт уже используемый комплект TI. +external = ['DSP2833x_ADC_cal.asm', 'DSP2833x_Adc.c', 'DSP2833x_CpuTimers.c', 'DSP2833x_PieCtrl.c', 'DSP2833x_SWPrioritizedDefaultIsr.c', 'DSP2833x_SWPrioritizedPieVect.c', 'DSP2833x_SysCtrl.c', 'DSP2833x_Xintf.c', 'DSP2833x_usDelay.asm'] # Повторяет штатный список внешних исходников. +sources = [common / item for item in external] + [root / 'Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c'] + sorted((root / 'Source/Internal').glob('*.c')) # Пересобирает все модули после окончательной правки. +for source in sources: # Последовательно компилирует каждый модуль. + run([ti / 'bin/cl2000.exe', *flags, '--obj_directory=' + str(obj), source]) # Проверяет настоящий C28x-код и создаёт новый объект. +objects = [obj / (source.stem + '.obj') for source in sources] # Использует только объекты завершённой текущей компиляции. +run([ti / 'bin/cl2000.exe', '-v28', '-ml', '-mt', '--float_support=fpu32', '--abi=coffabi', '-z', '--map_file=' + str(out / (name + '.map')), '--stack_size=0x3f0', '--warn_sections', '-i' + str(ti / 'lib'), '-i' + str(root), '-i' + str(protocol), '-i' + str(ti / 'include'), '--reread_libs', '--display_error_number', '--entry_point=_c_int00', '--rom_model', '--output_file=' + str(out / (name + '.out')), root / 'F28335.cmd', root / 'Source/External/v120/DSP2833x_headers/cmd/DSP2833x_Headers_nonBIOS.cmd', *objects, root / 'Libraries/rts2800_fpu32.lib', '-lrts2800_fpu32.lib', '-llibc.a']) # Линкует со штатной картой памяти и библиотеками времени выполнения. +run([ti / 'bin/hex2000.exe', '--diag_wrap=off', '--boot', '--sci8', '--binary', '-o', out / (name + '.candidate'), out / (name + '.out')]) # Создаёт кандидат загрузочного образа для обязательной проверки размера. +print(run([sys.executable, root / 'tests/gas167/check_image.py', out / (name + '.candidate'), '--eeprom', 'AT25256B']).strip()) # Проверяет EEPROM, RAM-блоки и точку входа до выдачи прошивки. +print(run([sys.executable, templates / 'c/firmware-info/tools/c2000_postbuild.py', '--compiler', ti, '--build-dir', out, '--artifact', name, '--metadata', gen / 'firmware_identity.json', '--output', out]).strip()) # Создаёт штатный BIN, манифест и SHA-256 без экспорта в другие проекты. +bin_path = out / (name + '_' + json.loads((gen / 'firmware_identity.json').read_text(encoding='utf-8'))['build_id'] + '.bin') # Выбирает именно текущую сборку, даже если в каталоге остаются прежние BIN. +print(run([sys.executable, root / 'tests/gas167/check_image.py', bin_path, '--eeprom', 'AT25256B']).strip()) # Повторяет проверку на самом выдаваемом BIN после штатной упаковки. +assert bin_path.read_bytes() == (out / (name + '.candidate')).read_bytes() # Подтверждает совпадение проверенного кандидата и итоговой прошивки. +log.close() # Завершает полный лог успешно проверенной сборки. +print('READY:', bin_path) # Указывает пользователю точный готовый результат. diff --git a/Doc/COMMENT_AUDIT.md b/Doc/COMMENT_AUDIT.md index a68f3e0..d5f701c 100644 --- a/Doc/COMMENT_AUDIT.md +++ b/Doc/COMMENT_AUDIT.md @@ -1,15 +1,20 @@ # Проверка комментариев и кодировки Проверка относится к редактируемым исходникам C/H, ASM, CMD, тестовым INC и Python. -Каждая непустая строка кода имеет русское пояснение перед ней или на ней. Пустые строки, -текст существующих комментариев и содержимое многострочных строк данных не считаются кодом. +Для каждой непустой строки кода проверяется русский текст на ней или непосредственно перед ней. +Пустые строки, текст комментариев и содержимое многострочных строк данных не считаются кодом. +Качество и достоверность пояснений этой проверкой не устанавливаются; совпадение возможно и в строковом литерале. +Охват: исходники из Git-индекса. Сгенерированные файлы и подключённые соседние библиотеки проверяются отдельно. Исходные уведомления TI сохранены. JSON-паспорта, индексы IDE, таблицы XLS и двоичные результаты сборки не допускают исходных комментариев; их назначение описано в документации. -UTF-8 проверен в 151 текстовых файлах. Строк кода: 18624. +UTF-8 проверен в 157 текстовых файлах. Строк кода: 18866. -| Файл | Строк кода | С русским пояснением | +| Файл | Строк кода | С русским текстом рядом | | --- | ---: | ---: | +| Bin/EepromPublishFix/rebuild.py | 41 | 41 | +| Bin/StartupWait3s/rebuild.py | 41 | 41 | +| Bin/UartColdStart/rebuild.py | 41 | 41 | | F28335.cmd | 69 | 69 | | Source/External/v120/DSP2833x_common/include/DSP2833x_DefaultIsr.h | 89 | 89 | | Source/External/v120/DSP2833x_common/include/DSP2833x_Dma_defines.h | 44 | 44 | @@ -52,7 +57,7 @@ UTF-8 проверен в 151 текстовых файлах. Строк код | Source/External/v120/DSP2833x_headers/include/DSP2833x_Xintf.h | 77 | 77 | | Source/External/v120/DSP2833x_headers/source/DSP2833x_GlobalVariableDefs.c | 301 | 301 | | Source/Internal/ADC.c | 244 | 244 | -| Source/Internal/DAC.c | 244 | 244 | +| Source/Internal/DAC.c | 253 | 253 | | Source/Internal/Include/ADC.h | 4 | 4 | | Source/Internal/Include/DAC.h | 11 | 11 | | Source/Internal/Include/GPIO_table.h | 329 | 329 | @@ -66,27 +71,27 @@ UTF-8 проверен в 151 текстовых файлах. Строк код | Source/Internal/Include/filter_bat2.h | 36 | 36 | | Source/Internal/Include/gas167.h | 17 | 17 | | Source/Internal/Include/kanal.h | 1 | 1 | -| Source/Internal/Include/log_to_mem.h | 37 | 37 | +| Source/Internal/Include/log_to_mem.h | 36 | 36 | | Source/Internal/Include/measure.h | 90 | 90 | | Source/Internal/Include/message.h | 32 | 32 | -| Source/Internal/Include/package.h | 127 | 127 | +| Source/Internal/Include/package.h | 128 | 128 | | Source/Internal/Include/peripher.h | 128 | 128 | | Source/Internal/Include/pulto.h | 1 | 1 | | Source/Internal/Include/spise2p.h | 74 | 74 | | Source/Internal/Include/tools.h | 5 | 5 | | Source/Internal/Include/ump_can_protocol.h | 8 | 8 | -| Source/Internal/RS485.c | 530 | 530 | +| Source/Internal/RS485.c | 534 | 534 | | Source/Internal/bios.c | 236 | 236 | | Source/Internal/cntrl_adr.c | 17 | 17 | | Source/Internal/crc16.c | 158 | 158 | -| Source/Internal/ecan.c | 242 | 242 | +| Source/Internal/ecan.c | 236 | 236 | | Source/Internal/filter_bat2.c | 12 | 12 | -| Source/Internal/gas167.c | 53 | 53 | +| Source/Internal/gas167.c | 54 | 54 | | Source/Internal/kanal.c | 153 | 153 | -| Source/Internal/log_to_mem.c | 236 | 236 | +| Source/Internal/log_to_mem.c | 217 | 217 | | Source/Internal/main.c | 167 | 167 | | Source/Internal/measure.c | 625 | 625 | -| Source/Internal/message.c | 289 | 289 | +| Source/Internal/message.c | 293 | 293 | | Source/Internal/peripher.c | 227 | 227 | | Source/Internal/pulto.c | 88 | 88 | | Source/Internal/shared_ump.c | 4 | 4 | @@ -95,16 +100,17 @@ UTF-8 проверен в 151 текстовых файлах. Строк код | UKSSTMS320F28335/28335_RAM_lnk.cmd | 58 | 58 | | UKSSTMS320F28335/firmware_version.h | 6 | 6 | | UKSSTMS320F28335/prepare_identity.py | 41 | 41 | -| tests/comments/run_test.py | 127 | 127 | +| tests/comments/run_test.py | 129 | 129 | +| tests/eeprom_profiles/check_publication.py | 18 | 18 | | tests/eeprom_profiles/run_test.py | 20 | 20 | | tests/eeprom_profiles/spi_test.c | 46 | 46 | | tests/eeprom_profiles/stubs/DSP2833x_Device.h | 22 | 22 | | tests/firmware_identity/check_build.py | 35 | 35 | | tests/firmware_identity/port_test.c | 29 | 29 | | tests/gas167/check_image.py | 44 | 44 | -| tests/gas167/gas167_test.c | 191 | 191 | -| tests/gas167/run_test.py | 45 | 45 | -| tests/load_control/load_control_test.c | 93 | 93 | +| tests/gas167/gas167_test.c | 213 | 213 | +| tests/gas167/run_test.py | 49 | 49 | +| tests/load_control/load_control_test.c | 170 | 170 | | tests/load_control/run_test.py | 15 | 15 | | tests/load_control/stubs/DSP2833x_Device.h | 9 | 9 | | tests/load_control/stubs/DSP2833x_SWPrioritizedIsrLevels.h | 0 | 0 | @@ -112,13 +118,13 @@ UTF-8 проверен в 151 текстовых файлах. Строк код | tests/load_control/stubs/filter_bat2.h | 0 | 0 | | tests/load_control/stubs/measure.h | 4 | 4 | | tests/load_control/stubs/message.h | 1 | 1 | -| tests/load_control/stubs/package.h | 17 | 17 | +| tests/load_control/stubs/package.h | 18 | 18 | | tests/load_control/stubs/peripher.h | 14 | 14 | | tests/load_control/stubs/tools.h | 0 | 0 | -| tests/rs232_fifo/model.inc | 113 | 113 | +| tests/rs232_fifo/model.inc | 122 | 122 | | tests/rs232_fifo/run_test.py | 53 | 53 | -| tests/ump_logger/init_test.c | 52 | 52 | -| tests/ump_logger/recorder_test.c | 151 | 151 | +| tests/ump_logger/init_test.c | 44 | 44 | +| tests/ump_logger/recorder_test.c | 152 | 152 | | tests/ump_logger/run_init_test.py | 30 | 30 | | tests/ump_logger/run_test.py | 34 | 34 | | tests/ump_logger/stubs/ADC.h | 1 | 1 | diff --git a/Doc/GAS_167_M95M02.md b/Doc/GAS_167_M95M02.md index 6395f40..2b1ad06 100644 --- a/Doc/GAS_167_M95M02.md +++ b/Doc/GAS_167_M95M02.md @@ -21,7 +21,7 @@ CLI define EEPROM_M95M02 должен передаваться и компиля | 0x5051 | 0x0051 | Штатный регистр останова | RW | | 0x5052 | 0x0052 | CAN timeout LOAD, мс | RW; для LOAD 1…60000 | | 0x507C | 0x007C | LOAD_STATUS | Только чтение для LOAD | -| 0x507D | 0x007D | LOAD_ATTEMPTS | Только чтение для LOAD | +| 0x507D | 0x007D | LOAD_MAX_ATTEMPTS, лимит пусков | RW; для LOAD 1…65535, по умолчанию 5 | | 0x507E | 0x007E | LastMode | Как штатный регистр | | 0x507F | 0x007F | Commands, битовая маска | RW; штатная фиксация команды | | 0x5F00…0x5F07 | Константы GAS-профиля | Сигнатура, версия, возможности | Только чтение | @@ -66,7 +66,8 @@ CLI define EEPROM_M95M02 должен передаваться и компиля | Функция отличается от 3/6 | Код 1, illegal function | | Адрес вне региона; блок пересекает границу; запись паспорта GAS | Код 2, illegal address | | FC03 quantity = 0 или >124; нечётное количество CAN | Код 3, illegal value | -| LOAD: запись 0x507C или 0x507D | Код 2; значения не меняются | +| LOAD: запись 0x507C | Код 2; статус не меняется | +| LOAD: запись нуля в 0x507D | Код 3; прежний лимит не меняется | | LOAD: запись timeout 0 или >60000 в 0x5052 | Код 3; значение не меняется | | Запись 0x507F | Штатная запись Commands и вызов ump_log_rs, как при FC06(0x007F) | diff --git a/Doc/GAS_ADDRESS_ALLOCATION.md b/Doc/GAS_ADDRESS_ALLOCATION.md index da59606..dd4e5d5 100644 --- a/Doc/GAS_ADDRESS_ALLOCATION.md +++ b/Doc/GAS_ADDRESS_ALLOCATION.md @@ -80,7 +80,7 @@ GAS_ID = номер_узла × 1000 + смещение | `DAC_stop` | `0x0051` | 5081 | 6081 | | `LOAD_CAN_TIMEOUT` | `0x0052` | 5082 | 6082 | | `LOAD_STATUS` | `0x007C` | 5124 | 6124 | -| `LOAD_ATTEMPTS` | `0x007D` | 5125 | 6125 | +| `LOAD_MAX_ATTEMPTS` | `0x007D` | 5125 | 6125 | | `LastMode` | `0x007E` | 5126 | 6126 | | `Commands` | `0x007F` | 5127 | 6127 | diff --git a/Doc/GAS_MODBUS_MAP.md b/Doc/GAS_MODBUS_MAP.md index ca9a56a..21d1cc0 100644 --- a/Doc/GAS_MODBUS_MAP.md +++ b/Doc/GAS_MODBUS_MAP.md @@ -167,7 +167,7 @@ GAS предоставляет доступ к тем же значениям `m | `0x007A` | 122 | `0x507A` | 20602 | 5122 | 6122 | `Caliber[6]` / `TCaliber[2]`; LOAD: `DAC_cal()` | RW | | `0x007B` | 123 | `0x507B` | 20603 | 5123 | 6123 | `Caliber[7]` / `TCaliber[3]`; LOAD: текущий 12-битный код ЦАП | RW | | `0x007C` | 124 | `0x507C` | 20604 | 5124 | 6124 | `NormaU` = `Caliber[8]`; LOAD: `LOAD_STATUS` | RO для LOAD; иначе RW | -| `0x007D` | 125 | `0x507D` | 20605 | 5125 | 6125 | `DeltaU` = `Caliber[9]`; LOAD: `LOAD_ATTEMPTS` | RO для LOAD; иначе RW | +| `0x007D` | 125 | `0x507D` | 20605 | 5125 | 6125 | `DeltaU` = `Caliber[9]`; LOAD: `LOAD_MAX_ATTEMPTS`, лимит пусков | RW; для LOAD 1…65535 | | `0x007E` | 126 | `0x507E` | 20606 | 5126 | 6126 | `LastMode` | RW | | `0x007F` | 127 | `0x507F` | 20607 | 5127 | 6127 | `Commands` — битовая маска команд | RW | @@ -217,14 +217,14 @@ GAS предоставляет доступ к тем же значениям `m | Бит | Маска | Смысл | |---:|---|---| -| 0 | `0x0001` | Состояние `LOAD_FAULT`: ошибка после пяти попыток пуска | +| 0 | `0x0001` | Состояние `LOAD_FAULT`: ошибка после исчерпания настроенного лимита пусков | | 1 | `0x0002` | Нет свежего напряжения ЗПТ | | 2 | `0x0004` | Состояние `LOAD_RELOAD`: сброс перед повторным пуском | | 3 | `0x0008` | Состояние `LOAD_RUN`: работа рампы | | 4 | `0x0010` | Имитация потери ЗПТ: приём напряжения из CAN игнорируется | | 5 | `0x0020` | Имитация 0 В для защиты; реальные значения CAN в логгере сохраняются | -`LOAD_ATTEMPTS` (`0x007D` / `0x507D`) содержит число попыток пуска. Оба слова доступны только для чтения на LOAD. +`LOAD_MAX_ATTEMPTS` (`0x007D` / `0x507D`) содержит записываемый лимит общего числа пусков: 1…65535, по умолчанию 5. Первый START входит в лимит. Ноль отклоняется кодом 3; изменение сохраняется штатной командой Save. Текущий счётчик читается в слове 5 диагностического блока `FC03(0x1300, 8)`. Только `LOAD_STATUS` остаётся RO для LOAD. ## Запросы и ограничения @@ -233,7 +233,8 @@ GAS предоставляет доступ к тем же значениям `m | FC03 | 1…125 слов в пределах 128 регистров | 1…124 слова; весь блок внутри одного GAS-региона | | FC06 | Одно 16-битное слово | Одно 16-битное слово; ответ сохраняет GAS-адрес | | FC04 / FC16 | Не используются этими обработчиками для данной карты | GAS-provider поддерживает функции 3 и 6 | -| LOAD: запись `LOAD_STATUS`, `LOAD_ATTEMPTS` | Код 2 | Код 2 | +| LOAD: запись `LOAD_STATUS` | Код 2 | Код 2 | +| LOAD: запись нуля в `LOAD_MAX_ATTEMPTS` | Код 3 | Код 3 | | LOAD: запись `LOAD_CAN_TIMEOUT` вне 1…60000 мс | Код 3 | Код 3 | GAS-provider возвращает код 1 для неподдерживаемой функции, код 2 для недопустимого адреса, пересечения границы или записи RO-блока; код 3 — для количества слов 0 или >124 и недопустимого LOAD-timeout. В RTU запросы к этой карте маршрутизируются обработчиками FC03/FC06. @@ -249,7 +250,9 @@ GAS-provider возвращает код 1 для неподдерживаемо | Прочитать все 128 слов | `FC03(0x0000, 125)` + `FC03(0x007D, 3)` | `FC03(0x5000, 124)` + `FC03(0x507C, 4)` | | Прочитать timeout LOAD | `FC03(0x0052, 1)` | `FC03(0x5052, 1)` | | Задать timeout LOAD = 1000 мс | `FC06(0x0052, 1000)` | `FC06(0x5052, 1000)` | -| Прочитать статус и попытки LOAD | `FC03(0x007C, 2)` | `FC03(0x507C, 2)` | +| Прочитать статус и лимит пусков LOAD | `FC03(0x007C, 2)` | `FC03(0x507C, 2)` | +| Задать лимит LOAD = 5 пусков | `FC06(0x007D, 5)` | `FC06(0x507D, 5)` | +| Прочитать защиту и текущий счётчик LOAD | `FC03(0x1300, 8)` | Штатный диагностический блок | Два запроса на чтение всей карты дают два отдельных снимка. FC06 меняет RAM; сохранение параметров в EEPROM выполняется штатным механизмом прошивки. diff --git a/Doc/SOURCE_GUIDE.md b/Doc/SOURCE_GUIDE.md index 3b77994..9f4db2f 100644 --- a/Doc/SOURCE_GUIDE.md +++ b/Doc/SOURCE_GUIDE.md @@ -1,9 +1,10 @@ # Назначение исходников Бальзам-167 Все редактируемые исходники C/H, ASM, CMD и Python используют UTF-8 без BOM. -Каждая строка кода снабжена русским пояснением. Существующие уведомления TI -и сведения о поставляемых файлах сохранены. Таблица покрытия и воспроизводимая -проверка находятся в [COMMENT_AUDIT.md](COMMENT_AUDIT.md) и +Русский текст найден рядом с каждой строкой исходников из Git-индекса, однако +часть пояснений шаблонная и требует содержательной доработки. Существующие уведомления TI +и сведения о поставляемых файлах сохранены. Таблица формального покрытия, +ограничения проверки и результаты проверки качества находятся в [COMMENT_AUDIT.md](COMMENT_AUDIT.md) и ../tests/comments/run_test.py. ## Порядок работы @@ -29,7 +30,7 @@ Timer1 задаёт основную частоту READY_FREQ=1000 Гц. Для | ADC.c | Настройка каналов АЦП, обработка преобразований и обновление фильтров. | | measure.c | Типы датчиков, температурные/токовые/мощностные расчёты, диагностика, периодический такт. | | filter_bat2.c | Накопительный фильтр; история и сумма обновляются вместе с новым отсчётом. | -| DAC.c | Передача слов ЦАП и автомат нагрузки: свежесть CAN, напряжение, STOP и максимум пять пусков. | +| DAC.c | Передача слов ЦАП и автомат нагрузки: свежесть CAN, напряжение, STOP и настраиваемый лимит пусков. | | ecan.c | Штатные CAN-кадры и отдельный служебный обмен УМП/GAS; ISR принимает, главный цикл передаёт ответ. | | RS485.c | SCI-A/SCI-B, разбор кадров и упаковка слов; FIFO используется только первым портом. | | message.c | FC03/FC06, маршрутизация УМП/GAS, заводские и сохраняемые параметры. | @@ -49,10 +50,13 @@ Timer1 задаёт основную частоту READY_FREQ=1000 Гц. Для package.h определяет аппаратные адреса и псевдонимы modbus. Стартовый ток находится в 0x50, конечный — в 0x51. Сохраняемый LOAD_CAN_TIMEOUT занимает 0x52: -разрешено 1..60000 мс; заводское значение 600 мс устанавливается Default_params. +разрешено 1..60000 мс; заводское значение 2000 мс устанавливается Default_params. Setup_DAC_time исправляет недопустимое сохранённое значение на 600 мс. Load_runner дополнительно использует 600 мс для локальной страховки при -недопустимом значении. LOAD_STATUS=0x7C и LOAD_ATTEMPTS=0x7D доступны для чтения. +недопустимом значении. LOAD_STATUS=0x7C доступен только для чтения. +LOAD_MAX_ATTEMPTS=0x7D — сохраняемый лимит 1..65535 пусков, по умолчанию 5; +ноль при записи отклоняется. Текущий счётчик остаётся в слове 5 блока +FC03(0x1300, 8), а подготовка тактов ЦАП не обнуляет настроенный лимит. eeprom_config.h выбирает физическую микросхему при сборке. spise2p.h задаёт ширину адреса, длину страницы и типы задания SPI. gas167.h описывает границы diff --git a/Doc/UMP_LOGGER.md b/Doc/UMP_LOGGER.md index 9a9283a..41b9445 100644 --- a/Doc/UMP_LOGGER.md +++ b/Doc/UMP_LOGGER.md @@ -3,29 +3,33 @@ ## Назначение и работа оператора В SetGUI открыть ПМ35 → Настройки, выбрать COM, скорость (обычно 115200) -и адрес контроллера (обычно 16). Затем открыть вкладку **Логгер УМП**. +и адрес контроллера (для рассматриваемого УМП — 5). Затем открыть вкладку **Логгер УМП**. Подключение используется существующее: прямой RS232/RS485 Modbus RTU. CAN-команды от управляющего контроллера фиксируются самой платой нагрузки. 1. **Начать запись** включает только регистратор, не пуск УМП. Период снимков по умолчанию 20 мс, диапазон 1–1000 мс. -2. Флажки выбирают отображаемые сигналы. Аналоги рисуются линиями, +2. Левые флажки выбирают отображаемые сигналы. Аналоги рисуются линиями, дискретные сигналы — отдельными дорожками. Выбор не меняет состав записи на плате: скрытую кривую можно включить после захвата. 3. **Онлайн** подключает график к уже идущей записи, в том числе после восстановления соединения. Тайм-аут не посылает плате команду останова. -4. Фронт `cUMPreset` (бит 6 команды 0x7F) или спад `cUMPstart` (бит 7) - запускает фиксацию отключения. Ещё через 1000 тиков таймера / 1 секунду - банк становится архивом. Повторные команды внутри этой секунды - не продлевают интервал. Другие изменения команд не служат триггером. +4. Фактическое включение STOP при переходе работающей нагрузки к снятому + разрешению запускает фиксацию отключения. Постинтервал содержит 10% + банка — 76 последующих точек, включая события CAN и I/O. Повторные + STOP при уже остановленной нагрузке архив не заменяют. 5. **Прочитать отключение** загружает архив, не останавливая запись на плате. На время чтения и просмотра архива онлайн-график приостанавливается; вернуться к нему можно кнопкой **Онлайн**. 6. **Остановить и прочитать** останавливает только регистратор и читает текущий банк. При этом существующий архив отключения остаётся доступным. -7. **Сохранить CSV** сохраняет все поля загруженного/онлайн-буфера, - включая невидимые кривые, время и код события. История GUI ограничена - 800 последними точками; это не непрерывная запись на диск. +7. **Сохранить CSV** сохраняет поля загруженного/онлайн-буфера, выбранные + правыми флажками «Запись в лог», а также время и код события. Выбор + не зависит от видимости кривой. Множители графика не изменяют значения CSV. + **Буфер GUI** задаёт число последних точек: от 800 до 100000, по умолчанию + 10000. Это отдельный буфер ПК, не ёмкость банка платы и не непрерывная + запись на диск. **Сохранить график из GUI** позволяет выгрузить накопленную + онлайн-историю после чтения архива платы. При разрыве связи журнал на плате продолжает работать. Архив хранится в ОЗУ до следующей фиксации отключения либо перезагрузки/пропадания питания. @@ -35,23 +39,21 @@ EEPROM не используется: под отключением в этой ## Память и точность Использована существующая секция `.logg` по адресу 0x200000: 64000 -16-битных слов. Два банка по 760 записей × 42 слова занимают 63840 слов (160 слов свободны). -Текущий банк кольцевой. При триггере сохраняются последние до 379 записей, -добавляется событие отключения, оставшаяся половина банка отведена -постинтервалу. При 20 мс это до примерно 7.6 секунды до отключения и 1 секунды -после. Дополнительные события CAN и дискретов сокращают временную глубину. - -При интенсивном потоке событий или периоде 1 мс постинтервал может заполнить -свои места раньше секунды. Последнее место зарезервировано под конечный -снимок; он помечается `event & 0x200`, и GUI сообщает об усечении. -Событие отключения и предыстория при этом не вытесняются. +16-битных слов. Два банка по 760 записей × 12 слов занимают 18240 слов. +Ёмкость в точках сохранена; сокращённая запись освобождает оставшуюся часть +выделенного массива. При триггере сохраняются до 683 предыдущих точек, +событие отключения и 76 последующих точек. При периоде 20 мс и отсутствии +дополнительных событий постинтервал составляет примерно 1,52 секунды. +События CAN и дискретов сокращают его временную длительность, но не число +зарезервированных точек. Архив после заполнения постинтервала фиксируется, +а запись продолжается в другом банке. Время — 32-битный счётчик миллисекунд записи. Он идёт только при включённом регистраторе и не является абсолютным временем. События в одном тике имеют одинаковую отметку; порядок сохраняется порядком записей. На перезапуске регистратора счётчик продолжает прежнюю шкалу, при перезагрузке платы — 0. -Онлайн-опрос возвращает две последние записи каждые 40 мс. Он не гарантирует +Онлайн-опрос возвращает до десяти последних записей каждые 40 мс. Он не гарантирует передачу каждого события при высоком CAN-трафике, медленном UART или паузах GUI. Номера записей позволяют убрать дубликаты и явно показать пропуски. Полный сохранившийся фрагмент следует читать кнопкой архива. Частота 20 мс @@ -63,55 +65,55 @@ GUI. Номера записей позволяют убрать дублика EEPROM, выделения памяти или копирования целого банка. Реальную задержку прерываний и длительность критических секций нужно измерить на F28335. -## Состав записи v3: 42 слова +## Состав записи v4: 12 слов + +Из прошивки и списка графиков удалены 32 неотмеченных канала с двух +скриншотов: остатки импульса/инициализации, код и калибровки ЦАП, +измерения, ошибки, сырые CAN-слова/счётчики, маска команд, параметры +разгона и каналы АЦП. Рабочие калибровочные регистры и сами измерения +для управления платой продолжают использоваться по назначению. + +В интерфейсе осталось 15 каналов: + +| Группа | Каналы | +|---|---| +| Ток и уставки | Расчётное задание тока, начальная уставка, конечная уставка — мА | +| Напряжения | ЗПТ1: U1 + U2 (ПМ67, рег. 306); ЗПТ2: U3 + U4 (ПМ67, рег. 9) — В | +| Команды | Пуск УМП, сброс УМП | +| Входы | OMEGA, Start_1, Res_in | +| Выходы | START_DPTB, STOP_DPTB, RES_OUT_2 | +| События | Событие отключения, усечение постинтервала | + +«Усечение постинтервала» оставлено для чтения прежних журналов; текущая +прошивка v4 бит 9 события не устанавливает. Расчётное задание тока — +команда аналоговому выходу, а не измеренный физический ток петли. +Для отображения физических единиц у пяти аналоговых каналов нужен +множитель ×1,000. Сохранённые пользовательские множители восстанавливаются +при запуске GUI; например, ×94,000 меняет только высоту кривой, не ток платы. | Слова | Данные | Единицы/смысл | |---|---|---| | 0–1 | Время, младшее/старшее слово | мс записи | -| 2 | Событие | 1 период, 2 CAN RX, 3 изменение I/O, 4 RS-команда, 5 конец постинтервала | -| 2, бит 8 | Триггер отключения | флаг поверх причины события | -| 2, бит 9 | Усечён постинтервал | установлен в конечном снимке | -| 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 | 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 | DAC_go, DAC_stop | исходные начальная/конечная уставки, мА | -| 26–28 | DAC_min(), DAC_max(), DAC_cal() | коды калибровки и ручного задания ЦАП | -| 29–30 | DAC_04, DAC_20 | значения соответствующих регистров | -| 31–32 | count_load, time_dac | положение и длительность разгона в тиках | -| 33–34 | эффективные dac_go/dac_stop + 4 | 0.1 мА после ограничений алгоритма; GUI переводит в мА | -| 35 | kod | целочисленное положение, используемое Anal_output | -| 36–39 | ADC_table[0..3] | значения таблицы АЦП в исходном масштабе прошивки | -| 40 | ЗПТ1: U1 + U2, ПМ67 регистр 306 / индекс 305 | исходное 16-битное слово без пересчёта | -| 41 | ЗПТ2: U3 + U4, ПМ67 регистр 9 / индекс 8 | исходное 16-битное слово без пересчёта | +| 2 | Событие | 1 — период, 2 — CAN, 3 — I/O, 4 — RS, 5 — конец постинтервала | +| 2, бит 8 | Событие отключения | флаг поверх причины | +| 2, бит 9 | Усечение постинтервала | совместимость со старыми журналами; в текущем v4 равен 0 | +| 3 | Команды пуска и сброса | только биты 7 и 6; отдельной кривой маски команд больше нет | +| 4 | Входы OMEGA, Start_1, Res_in | биты 0, 1, 2 | +| 5 | Выходы START_DPTB, STOP_DPTB, RES_OUT_2 | биты 0, 1, 2 | +| 6 | Расчётное задание тока | 0,1 мА; GUI/CSV показывает мА | +| 7–8 | Начальная/конечная уставки | целые мА | +| 9–10 | ЗПТ1/ЗПТ2 | беззнаковые слова, масштаб 1 В/ед. | +| 11 | Нулевой резерв | чётная длина для передачи CAN парами слов | Напряжения принимаются из технологических CAN-кадров с нулевыми индексами 305 и 8. Учитываются все три позиции и биты маски 0x8000/0x4000/0x2000. Они хранятся отдельно от массива modbus[0..127], обновляются и при выключенном логгере. Запись содержит последние принятые значения; до первого приёма — 0. При потере связи остаётся последнее значение: отдельного признака свежести нет. -Масштаб и знаковость физического напряжения не заданы исходной таблицей; -SetGUI показывает исходное беззнаковое слово, коэффициент задаётся в интерфейсе. - -**Отправленный код ЦАП не является измеренным током выхода.** В этом проекте -не установлено, какой вход аппаратно измеряет ток ЦАП. При включённом -`cCalibrDac` отправляется `DAC_cal()`, а расчётное задание 0x1C остаётся -результатом алгоритма разгона. Для диагностики это различие сохранено. -ADC_table также уже обрабатывается существующим измерительным кодом; -это не обязательно необработанный регистр ADCRESULT. - -Управляющая логика не исправлялась. Например, существующая строка -`if(dac_stop>16) dac_go=16;` в Load_runner сохранена; журнал показывает -фактически получившиеся эффективные уставки, чтобы выявить такое поведение. +Клиент не преобразует напряжения в знаковые измерения. Свежесть выбранного +ЗПТ и защита роста напряжения описаны отдельно в `UMP_VOLTAGE_PROTECTION.md`. +При штатных 6 мА пуск сначала передаёт это задание и получает 3 секунды +на рост ЗПТ до 30 В; после этого работает прежняя защита и лимит попыток. ## Протокол расширения Modbus @@ -126,16 +128,16 @@ FC03, 0x1000, 16 слов: | Смещение | Значение | |---|---| -| 0,1 | 0x554D, версия 3 | +| 0,1 | 0x554D, версия 4 | | 2,3 | состояние и число записей выбранного источника | -| 4,5 | 42 слова в записи, 760 записей в банке | +| 4,5 | 12 слов в записи, 760 записей в банке | | 6 | период периодических снимков, мс | | 7,8 | счётчик времени, младшее/старшее слово | | 9,10 | Desk (требуется 6 / dsk_LOAD), Mode | | 11 | частота временной базы, 1000 Гц | | 12 | поколение архива, mod 65536 | | 13 | число записей архива | -| 14 | оставшиеся миллисекунды постинтервала | +| 14 | верхняя оценка оставшихся миллисекунд: число точек × период, до 65535 | | 15 | состояние текущего регистратора независимо от выбора источника | Состояния: 0 — ещё не запущен, 1 — запись, 3 — остановлен/архив. @@ -146,40 +148,45 @@ FC06: - 0x1002: хронологический индекс первой записи окна 0..759; - 0x1003: источник окна, 0 — текущий остановленный банк, 1 — архив отключения. -FC03, 0x1010, до 120 слов: окно от установленного индекса; для целых записей v3 читать 42 или 84 слова. -CAN допускает 42/84 и прежние размеры 40/80/120; RTU допускает 1..120 слов. +FC03, 0x1010, до 120 слов: окно от установленного индекса; для целых записей v4 читать 12, 24, …, 120 слов. +CAN допускает кратные 12 до 120 слов и прежние размеры v2/v3; RTU допускает 1..120 слов. Чтение текущего банка этим окном во время записи не выдаёт изменяющиеся данные. GUI сначала останавливает его; архив можно читать при работающем текущем банке. После всех блоков GUI повторно проверяет поколение архива; при замене во время чтения результат не подменяет предыдущий график. FC03, 0x1100, ровно 124 слова: онлайн-блок. Слова 0,1 — 32-битный номер -первой записи, 2 — число записей 0..2, 3 — поколение архива, далее до двух -записей по 42 слова. Неиспользованные слова равны нулю. Окно онлайн не +первой записи, 2 — число записей 0..10, 3 — поколение архива, далее до десяти +записей по 12 слов. Неиспользованные слова равны нулю. Окно онлайн не зависит от курсора/выбора архива. Разделение 0x1010 и 0x1100 предотвращает пересечение двух окон. Недопустимые диапазоны и значения возвращают исключения Modbus 2/3. CRC и разбор стандартного ответа GUI используют существующее общее ядро. -SetGUI распознаёт v2 (40 слов, 800 записей) и v3 (42 слова, 760 записей). -Для v2 новые напряжения недоступны (NaN), для v3 доступны графики и CSV. -CAN-валидация общей библиотеки расширена размерами 42/84 слова. +SetGUI распознаёт v2 (40 слов, 800 записей), v3 (42 слова, 760 записей) +и v4 (12 слов, 760 записей). Для v2 ЗПТ недоступны (NaN). Старые архивы +декодируются по прежним индексам, но удалённые каналы в панели и CSV больше +не создаются. Валидаторы RTU/CAN поддерживают компактные размеры записи. Исходники протокола подключаются к прошивке из templates/c/set-protocol. ## Проверка и запуск -Полная сборка исправления: `./build_logger.ps1`. По умолчанию используется -`../newProject/SETGUI/third_party/templates`; другую копию можно указать -параметром `-TemplatesRoot`. В ней нужны `c/set-protocol/src/ump_protocol.c` -и `c/set-protocol/ports/tms320f28335/ump_tms28335.c` (порт УМП v3). -Само наличие папки templates не гарантирует наличие этого порта. -Результат — `Bin/LoggerFix/UKSSTMS320F28335_logger_fix.bin` (SCI8 boot), -рядом OUT и MAP. Старые образы в Bin не заменяются. -Скрипт использует TI C2000 22.6 COFF, оптимизацию размера и секции функций; -таблица `.cinit` размещена в RAML4 вместе с константами, код — в RAML0. -Для сборки из CCS добавьте `Source/Internal/shared_ump.c` в проект и каталоги -`/c/set-protocol`, `/c/set-protocol/ports/tms320f28335` -в include path; используйте параметры оптимизации из скрипта. +Текущая проверенная сборка с пуском 3 секунды и сокращённым журналом: +`Bin/StartupWait3s/UKSSTMS320F28335_startup_3s_378e06a+.bin`. +Размер — 32180 байт; для AT25256B допустимы 32508 байт, запас — 328 байт. +Рядом находятся OUT, MAP, манифест и SHA-256. Для чтения v4 используйте +обновлённый SETGUI и перезапустите приложение после изменения исходников. + + +Воспроизводимая сборка из корня проекта: `python Bin/StartupWait3s/rebuild.py`. +Скрипт использует установленный TI C2000 22.6, ABI COFF, `-O2`, +`--opt_for_speed=0` и секции функций. Все модули пересобираются в отдельный +каталог; до формирования готового BIN проверяются профиль AT25256B, +граница 32508 байт, блоки RAM и точка входа SCI8. Сохраняются паспорт и SHA-256. +Из CCS используется та же карта памяти и настройки проекта. В include-path +нужны каталоги общего `c/set-protocol`, его порта `ports/tms320f28335` +и сгенерированного паспорта. Обе используемые копии библиотеки поддерживают v4: +`../newProject/templates` и `../newProject/SETGUI/third_party/templates`. При загрузке `main()` вызывает `ump_log_init()` до включения прерываний. Это обязательно для TI COFF: стартовый код не обнуляет неинициализированные @@ -191,29 +198,31 @@ FC06 не вызывает загрузочную инициализацию и запуск с ненулевой RAM и отрицательный контроль без инициализации; внешняя библиотека `templates/c/set-protocol` для этого теста не нужна. -Изменены исходники прошивки и SetGUI. Готовый образ в Bin не обновлялся. -Для платы необходима сборка штатным TI C2000/CCS, проверка размещения .text, -.stack, .ebss и .logg по MAP, прошивка и испытание на стенде. +Изменены исходники прошивки и SetGUI; новый образ собран в отдельном каталоге. +Проверены TI-компиляция, линковка и формат SCI8 для AT25256B. Физические +уровни GPIO и ток после загрузки образа проверяются на плате. Автотест C в tests/ump_logger компилирует непосредственно log_to_mem.c с подменой GPIO/IRQ. Проверяет кольцо, граничные адреса, обе команды отключения, защиту триггера от переполнения, переключение банков, -сохранность архива во время дальнейшей записи и контрольные поля CAN/ЦАП. +сохранность архива во время дальнейшей записи, токовое задание и оба ЗПТ. Это проверка алгоритма на компьютере, не проверка таймингов и 16-битной ABI TI. Отдельно выполнена синтаксическая проверка изменённых C-файлов Clang с исходными заголовками и декларациями TI-интринсиков. -Тесты SetGUI: tests/test_ump_logger.py и tests/test_periph28335_tab.py. +Проверенный набор SetGUI: `tests/test_ump_logger.py`, +`tests/test_ump_logger_can.py`, `tests/test_ump_voltage_protection.py` — 93 теста. Они проверяют единицы мА, битовые сигналы, временные метки, несовместимую прошивку, порядок команд, архив при активной записи, замену поколения, дубликаты/пропуски онлайн, потерю связи и флажки графиков. Проверка на стенде: включить запись → подать CAN-пуск → изменить уставку → -подать откл. → через секунду прочитать архив → сверить код ЦАП, ток внешним -измерителем и физические входы/выходы; затем повторить с разрывом RS. +подать откл. → дождаться заполнения 76 точек постинтервала → прочитать +архив и сверить задание, внешний ток и дискретные уровни; затем повторить +с разрывом RS. Период 1 мс проверить отдельно под максимальной CAN-нагрузкой. -Для сборки v3 нужен templates/main начиная с коммита c0ee7c4 +Исторически для сборки v3 требовался templates/main начиная с коммита c0ee7c4 (поддержка CAN-чтения 42/84 слов и порт TMS320F28335). ## Пересечение образа 34a95bc5 с параметрами EEPROM @@ -239,3 +248,22 @@ TI. Отдельно выполнена синтаксическая прове При превышении границы остаётся только файл `.pending`; готовый BIN не публикуется. Проверка: `python tests/ump_logger/test_firmware_image.py`. После перепрошивки требуется проверка на плате; проверка на ПК её не заменяет. + +## Исправление ожидания EEPROM при запуске через CCS + +В сборке CCS с O3 подтверждён перенос записей полей `readData` и `writeData` +за цикл ожидания `spiSe2pFree()`. Указатель `msgPtr` и флаг `csr` были volatile, +но содержимое дескриптора — нет. Timer2 получал запрос с незаполненными +адресом, длиной и указателем буфера, поэтому `Load_params()` мог не завершиться, +хотя UART уже принял команду. Все три поля `SE2P_DATA` теперь volatile. +В дизассемблере исправленного OUT записи всех полей предшествуют флагу запроса. + +Для проверки старой AT25256B подготовлен +`Bin/EepromPublishFix/UKSSTMS320F28335_eeprom_fix.out` и одноимённый BIN с build_id. +Сборка `python Bin/EepromPublishFix/rebuild.py` явно задаёт `EEPROM_M95M02=0` +и O3; размер проверенного BIN — 32074 байта, запас до параметров — 434 байта. +Проверка порядка инструкций: +`python tests/eeprom_profiles/check_publication.py Bin/EepromPublishFix/disassembly.txt`. +На листинге прежнего OUT эта проверка падает, на исправленном проходит для чтения +и записи. Пройдены модели обоих профилей EEPROM и UART. Запуск на плате +после загрузки исправленного OUT ещё требует подтверждения. diff --git a/Doc/UMP_VOLTAGE_PROTECTION.md b/Doc/UMP_VOLTAGE_PROTECTION.md index 327c992..b1a4395 100644 --- a/Doc/UMP_VOLTAGE_PROTECTION.md +++ b/Doc/UMP_VOLTAGE_PROTECTION.md @@ -13,7 +13,21 @@ или удерживаемом STOP. Если очередной шаг рампы требует **строго больше 6 мА**, а свежее -CAN-напряжение меньше 30 В, шаг не передаётся в ЦАП. Вместо него: +CAN-напряжение меньше 30 В и в текущей попытке ещё не достигало порога, +в ЦАП сначала передаётся задание **6 мА**. Положение рампы удерживается. +УМП получает **3 секунды** на рост ЗПТ до 30 В: это 600 отправленных +токовых кадров при 200 Гц. Отсчёт начинается с первой отправки 6 мА; +команда инициализации ЦАП не расходует выдержку. До достижения порога +даже начальная уставка выше 6 мА ограничивается этим током. Уставки +ниже 6 мА сначала проходят обычный разгон до указанной границы. + +При свежем ЗПТ **не меньше 30 В** разгон продолжается с сохранённого +положения без нового START. После подтверждённого роста напряжения +рабочая защита снова действует сразу: шаг выше 6 мА при ЗПТ ниже 30 В +не передаётся в ЦАП и не получает повторной стартовой выдержки. + +Если за 3 секунды свежего обмена ЗПТ не достигло 30 В либо напряжение +упало после успешного пуска, вместо повышенного задания выполняется: 1. Снимается START, включается STOP, снимается разрешение RES_OUT_2. 2. Положение рампы обнуляется, передаётся код 4 мА без подмены калибровкой. @@ -21,12 +35,23 @@ CAN-напряжение меньше 30 В, шаг не передаётся в 4. Когда код 4 мА отправлен, прошла секунда и есть свежее ЗПТ, снимается STOP, сразу выставляется START, затем разрешение. 5. Новая рампа начинается с нулевого положения с исходными уставками - `DAC_go`/`DAC_stop` (штатные значения могут начинать рост с 6 мА). + `DAC_go`/`DAC_stop`; новая попытка получает собственные 3 секунды + ожидания при 6 мА, если ЗПТ ещё не достигло 30 В. -Первый START входит в лимит: **всего 5 попыток**, не 5 дополнительных. -После пятой неудачной попытки удерживаются STOP и 4 мА, разрешение снято, -шестой START не выдаётся. Ошибка снимается командой `cUMPstart=0`; -затем можно подать новый пуск. Команда RESET имеет приоритет перед START. +Первый START входит в настраиваемый лимит регистра **0x7D**: по умолчанию +**всего 5 попыток**, не 5 дополнительных. Через FC06 или штатный CAN можно +записать **1…65535**; ноль отклоняется без изменения предыдущей настройки. +После последней разрешённой неудачи удерживаются STOP и 4 мА, разрешение +снято, дополнительный START не выдаётся. Ошибка снимается командой `cUMPstart=0`; +затем можно подать новый пуск. Изменение лимита само по себе не снимает +ошибку и не выдаёт START. Уменьшение лимита во время STOP проверяется перед +следующей попыткой. Команда RESET имеет приоритет перед START. + +Для задания пяти пусков используйте `FC06(0x007D, 5)` либо `FC06(0x507D, 5)` +в GAS-профиле M95M02. Чтение `0x7D` возвращает лимит; текущий счётчик остаётся +в слове 5 диагностического блока `FC03(0x1300, 8)`. Настройка сохраняется +штатной командой **Save**. Ноль из старой EEPROM заменяется на 5 при запуске; +ненулевое сохранённое значение трактуется как лимит. Отпускание RESET с оставшимся START=1 само по себе не перезапускает УМП. Выходами и рампой управляет один обработчик Timer1 (1 мс). Основной цикл @@ -36,14 +61,16 @@ CAN-напряжение меньше 30 В, шаг не передаётся в ## Отсутствие CAN -Таймаут по умолчанию **600 мс**, диапазон настройки **1…60000 мс**. +Заводской таймаут из `Default_params` — **2000 мс**, диапазон настройки **1…60000 мс**. Если сохранённый параметр недопустим, `Setup_DAC_time` применяет **600 мс**; такой же запасной таймаут используется локально в `Load_runner`. Свежесть подтверждается только получением нужного ЗПТ в полном технологическом CAN-кадре с соответствующим битом маски. Другое напряжение, сервисные запросы, команды и произвольные CAN-пакеты таймаут не сбрасывают. До первого значения напряжение считается неизвестным. При таймауте работающая рампа удерживает последнее положение и отправленный -код. Попытка не считается неудачной, STOP по одному таймауту не включается. +код. Стартовая выдержка при 6 мА также приостанавливается и возобновляется +после нового выбранного ЗПТ. Попытка не считается неудачной, STOP по одному +таймауту не включается. После свежего ЗПТ рост продолжается; если оно меньше 30 В при задании больше 6 мА, выполняется защитный STOP. Если обмен исчез во время сброса, STOP держится и после секунды — до свежего напряжения. @@ -76,9 +103,9 @@ CAN-напряжение меньше 30 В, шаг не передаётся в Старые прошивки без блока защиты продолжают обычное онлайн-чтение; эмуляция для них недоступна. -Технологические регистры только для чтения: `0x7C` — статус, -`0x7D` — число попыток. Оба включены в быстрый CAN-цикл. -Статус: бит 0 — ошибка пяти попыток, бит 1 — нет свежего ЗПТ, +Технологический регистр `0x7C` — статус только для чтения; +`0x7D` — записываемый сохраняемый лимит попыток. Оба включены в быстрый CAN-цикл. +Статус: бит 0 — ошибка исчерпания настроенного лимита, бит 1 — нет свежего ЗПТ, бит 2 — сброс перед повтором, бит 3 — работа рампы, биты 4/5 — активная эмуляция отсутствия CAN/роста ЗПТ. @@ -103,7 +130,11 @@ FC06 допускает запись только `0x1302` (0…3) и `0x1303` ( `python tests/load_control/run_test.py` компилирует непосредственно `DAC.c` с подменой GPIO/IRQ. Проверяются выбор ЗПТ, маски CAN, таймаут, удержание кода, граница 30 В, порядок STOP/START, точная пауза 1000 мс, -лимит пяти пусков, RESET, эмуляция и невозможность подмены 4 мА калибровкой. +лимиты 1, 2, 5, 7 и 65535 пусков, изменение лимита во время STOP, RESET, эмуляция и невозможность подмены 4 мА калибровкой. +Стартовые регрессии для адресов 5 и 6 проверяют отправку 6 мА вместо +мгновенного сброса, границу выдержки 3000 мс, успешный рост ЗПТ во время +ожидания, немедленную защиту после успешного пуска, повышенную начальную +уставку, паузу CAN и пропуск отсчёта при инициализации ЦАП. GUI: `tests/test_ump_voltage_protection.py` в SETGUI плюс регрессии логгера. Сборка: `build_logger.ps1 -OutputDirectory Bin/VoltageProtection diff --git a/Source/Internal/DAC.c b/Source/Internal/DAC.c index eef8d63..7274f3d 100644 --- a/Source/Internal/DAC.c +++ b/Source/Internal/DAC.c @@ -51,13 +51,15 @@ unsigned int period_dac, time_dac; #define LOAD_RELOAD 2U /* Задаёт LOAD_FAULT = 3U; состояние остановки после исчерпания попыток. */ #define LOAD_FAULT 3U -/* Задаёт LOAD_MAX_ATTEMPTS = 5U; предел повторных пусков нагрузки — пять. */ -#define LOAD_MAX_ATTEMPTS 5U /* Задаёт LOAD_VOLTAGE_MIN = 30U; минимальное разрешённое напряжение нагрузки — 30 В. */ #define LOAD_VOLTAGE_MIN 30U /* Задаёт LOAD_PULSE_MS = 1000U; длительность удержания импульса START/STOP — 1000 мс. */ #define LOAD_PULSE_MS 1000U -/* Объявляет load_state — текущее состояние автомата нагрузки; load_attempts — накопленное число пусков в текущем цикле, максимум пять; load_inhibit — признак запрета повторного запуска до требуемого перехода входов. */ +/* Стартовая выдержка 3 секунды выбрана для реакции УМП и обновления ЗПТ; при DAC_FREQ=200 Гц это 600 отправок задания 6 мА. */ +#define LOAD_START_WAIT_STEPS (3U * DAC_FREQ) +/* load_start_remaining хранит остаток 600 стартовых отправок 6 мА; ноль означает конец выдержки или подтверждённые 30 В. */ +static unsigned int load_start_remaining; +/* Хранит состояние автомата, число выданных START в текущем сеансе и запрет повторного пуска; лимит берётся отдельно из регистра 0x7D. */ static unsigned int load_state, load_attempts, load_inhibit; /* Объявляет load_count_dac — load число ЦАП; load_count_ramp — load число ramp; load_init_count — load init число. */ static unsigned int load_count_dac, load_count_ramp, load_init_count; @@ -78,6 +80,8 @@ void Load_control_init(void) { /* Записывает load_state значением LOAD_IDLE; load_attempts = 0; load_inhibit = 0; текущее состояние автомата нагрузки. */ load_state = LOAD_IDLE; load_attempts = 0; load_inhibit = 0; + /* Начинает первую попытку без накопленной выдержки и подтверждённого роста ЗПТ; COFF требует явной инициализации статических полей. */ + load_start_remaining = 0; /* Записывает load_count_dac значением 0; load_count_ramp = 0; load_init_count = 1; load число ЦАП. */ load_count_dac = 0; load_count_ramp = 0; load_init_count = 1; /* Записывает load_zero_sent значением 0; load_stop_asserted = 0; load_initialized = 0; данные load_zero_sent. */ @@ -178,10 +182,8 @@ static void load_start(void) if (load_end > 16) load_end = 16; /* Проверяет if (load_end <= load_go) load_end = load_go + 1; последующий оператор выполняется только при истинном условии. */ if (load_end <= load_go) load_end = load_go + 1; - /* Записывает ump_dac_go10 значением (unsigned int)((load_go + 4.0) * 10.0); ump ЦАП go 10. */ - ump_dac_go10 = (unsigned int)((load_go + 4.0) * 10.0); - /* Записывает ump_dac_stop10 значением (unsigned int)((load_end + 4.0) * 10.0); ump ЦАП stop 10. */ - ump_dac_stop10 = (unsigned int)((load_end + 4.0) * 10.0); + /* Каждая попытка получает 600 токовых тактов, то есть 3 секунды при 200 Гц; остаток уменьшается только после отправки 6 мА. */ + load_start_remaining = LOAD_START_WAIT_STEPS; /* Записывает load_count_ramp значением 0; load число ramp. */ load_count_ramp = 0; /* Изменяет счётчик в выражении load_attempts++; на один для следующего шага. */ @@ -220,8 +222,10 @@ void Setup_DAC_time(void) if ((unsigned int)LOAD_CAN_TIMEOUT == 0U || /* Записывает LOAD_CAN_TIMEOUT значением 600; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */ (unsigned int)LOAD_CAN_TIMEOUT > 60000U) LOAD_CAN_TIMEOUT = 600; - /* Записывает LOAD_STATUS значением 0; LOAD_ATTEMPTS = 0; слово состояния защиты нагрузки для чтения, регистр 0x7C. */ - LOAD_STATUS = 0; LOAD_ATTEMPTS = 0; + /* Старый нулевой счётчик в EEPROM заменяется заводским лимитом пяти пусков; ненулевую сохранённую настройку 0x7D не стираем. */ + if (!(unsigned int)LOAD_MAX_ATTEMPTS) LOAD_MAX_ATTEMPTS = LOAD_DEFAULT_MAX_ATTEMPTS; + /* Сбрасывает диагностическое слово 0x7C при подготовке автомата; сохраняемый лимит не является текущим счётчиком. */ + LOAD_STATUS = 0; /* Записывает load_initialized значением 1; данные load_initialized. */ load_initialized = 1; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ @@ -297,16 +301,16 @@ static void anal_output(long vrot, long maxx, int calibration) /* Объявляет x — данные x. */ static int x; - /* Записывает out значением DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ; данные out. */ + /* Линейно переводит долю рампы vrot/maxx в код между DAC_min() и DAC_max(); целочисленное деление каждого слагаемого задаёт округление. */ out = DAC_min() + vrot * DAC_max() / maxx - vrot * DAC_min() / maxx ; - /* Записывает x значением 0; данные x. */ + /* Фиксирует выбор нижней ветви передачи: при x=0 далее используется управляющее слово out|0x8000. */ x=0;// !x; тщетно бытие /* Проверяет if(calibration и cCalibrDac) out=DAC_cal(); последующий оператор выполняется только при истинном условии. */ if(calibration && cCalibrDac) out=DAC_cal(); - /* Записывает out значением out & 0xFFF; данные out. */ + /* Оставляет младшие 12 бит кода ЦАП. Это усечение битов, а не насыщение на границах 0..4095. */ out = out & 0xFFF; /* Проверяет if(x) dSEND(out|0x0000|0x0000); последующий оператор выполняется только при истинном условии. */ @@ -314,10 +318,10 @@ static void anal_output(long vrot, long maxx, int calibration) /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else dSEND(out|0x8000|0x0000); - /* Записывает modbus[123] значением out; массив технологических регистров; слово int на C28x занимает 16 бит. */ + /* Публикует фактически отправляемый 12-битный код ЦАП в технологическом регистре 0x7B для диагностики и регистрации. */ modbus[123] = out; - /* Записывает modbus[0x1C] значением 40L + vrot * 200 / maxx - vrot * 40 / maxx ; массив технологических регистров; слово int на C28x занимает 16 бит. */ + /* Публикует расчётный выход 4..20 мА в масштабе 0,1 мА на единицу: при доле рампы 0 значение 40, при доле 1 значение 200. */ modbus[0x1C] = 40L + vrot * 200 / maxx - vrot * 40 / maxx ; /* @@ -352,10 +356,10 @@ void Anal_output(long vrot, long maxx) void Load_runner(void) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { - /* Объявляет saved — данные saved; commands — данные commands; voltage — данные voltage; fresh — данные fresh; timeout — данные timeout. */ - unsigned int saved, commands, voltage, fresh, timeout; - /* Объявляет start — данные start; reset — сброс; active — данные active. Начальное значение задаётся справа от знака равенства. */ - unsigned int start, reset, active = 0; + /* Хранит состояние IRQ, снимки команд и напряжения, свежесть CAN, тайм-аут в мс и лимит пусков; 16-битный лимит читается один раз за такт. */ + unsigned int saved, commands, voltage, fresh, timeout, attempt_limit; + /* start/reset хранят командные биты; active отмечает работу; voltage_wait отмечает вывод 6 мА; ramp_before позволяет заморозить положение рампы. */ + unsigned int start, reset, active = 0, voltage_wait = 0, ramp_before; /* Объявляет sinus — данные sinus. Начальное значение задаётся справа от знака равенства. */ float sinus = 0; @@ -371,6 +375,10 @@ void Load_runner(void) voltage = (load_simulation & 2U) ? 0U : load_voltage; /* Записывает timeout значением (unsigned int)LOAD_CAN_TIMEOUT; данные timeout. */ timeout = (unsigned int)LOAD_CAN_TIMEOUT; + /* Читает 0x7D как беззнаковое 16-битное число, чтобы значения 32768..65535 сохраняли положительный смысл лимита. */ + attempt_limit = (unsigned int)LOAD_MAX_ATTEMPTS; + /* При нештатном нуле в RAM оставляет прежний предел пяти пусков; штатные обработчики записи ноль отклоняют. */ + if (!attempt_limit) attempt_limit = LOAD_DEFAULT_MAX_ATTEMPTS; /* Проверяет if (!timeout или timeout > 60000U) timeout = 600U; последующий оператор выполняется только при истинном условии. */ if (!timeout || timeout > 60000U) timeout = 600U; /* До первого пакета значение 0 не считается свежим измерением. @@ -393,7 +401,7 @@ void Load_runner(void) if (!start) { /* Проверяет if (load_state != LOAD_IDLE) load_stop(LOAD_IDLE); последующий оператор выполняется только при истинном условии. */ if (load_state != LOAD_IDLE) load_stop(LOAD_IDLE); - /* Записывает load_attempts значением 0; load_inhibit = 0; накопленное число пусков в текущем цикле, максимум пять. */ + /* Снятие START обнуляет счётчик текущего сеанса и запрет повторного пуска, сохраняя настроенный лимит в 0x7D. */ load_attempts = 0; load_inhibit = 0; /* Проверяет else if (reset); последующий оператор выполняется только при истинном условии. */ } else if (reset) { @@ -408,13 +416,15 @@ void Load_runner(void) /* Проверяет if (reset и !load_stop_asserted) load_stop(LOAD_IDLE); последующий оператор выполняется только при истинном условии. */ if (reset && !load_stop_asserted) load_stop(LOAD_IDLE); + /* LOAD_RELOAD уже удерживает STOP, 4 мА и снятое разрешение; уменьшение лимита только фиксирует ошибку, не перезапуская секундную выдержку. */ + if (load_state == LOAD_RELOAD && load_attempts >= attempt_limit) load_state = LOAD_FAULT; /* Повторный START допускается после сброса ЦАП, окончания STOP и * восстановления нужного CAN-напряжения. Таймаут сам не тратит попытку. */ - /* Проверяет if (start и !reset и !load_inhibit и !WAKEpowse и fresh и; последующий оператор выполняется только при истинном условии. */ + /* Команда START без RESET и запрета должна дождаться окончания инициализации, свежего ЗПТ и подтверждённого задания 4 мА. */ if (start && !reset && !load_inhibit && !WAKEpowse && fresh && - /* Продолжает список аргументов, полей или выражение load_zero_sent && !IMPowse &&; порядок элементов сохраняется. */ + /* Секундный STOP заканчивается только после передачи исходного кода ЦАП; обе выдержки обязательны перед пуском. */ load_zero_sent && !IMPowse && - /* Продолжает список аргументов, полей или выражение (load_state == LOAD_IDLE || load_state == LOAD_RELOAD)) load_start();; порядок элементов сохраняется. */ + /* LOAD_IDLE начинает сеанс с нулевым счётчиком, а LOAD_RELOAD проверен на оставшиеся попытки выше; ошибка не разрешает START. */ (load_state == LOAD_IDLE || load_state == LOAD_RELOAD)) load_start(); /* Проверяет if (load_state == LOAD_RUN и !IMPowse) clear_START_DPTB(); последующий оператор выполняется только при истинном условии. */ if (load_state == LOAD_RUN && !IMPowse) clear_START_DPTB(); @@ -439,34 +449,43 @@ void Load_runner(void) active = load_state == LOAD_RUN; /* Проверяет if (active); последующий оператор выполняется только при истинном условии. */ if (active) { - /* При таймауте сохраняем положение И отправленное задание, - * не делаем STOP и не продолжаем разгон без обратной связи. */ - /* Проверяет if (fresh); последующий оператор выполняется только при истинном условии. */ + /* В паузе CAN не вычисляет следующий шаг: положение, код и остаток стартовой выдержки сохраняются. */ if (fresh) { - /* Проверяет if (load_count_ramp > time_dac / 2) load_count_ramp++; последующий оператор выполняется только при истинном условии. */ + /* Сохраняет положение до шага, чтобы отменить рост на время начального ожидания при 6 мА. */ + ramp_before = load_count_ramp; + /* Во второй половине штатной рампы сохраняет прежнее ускорение на два отсчёта за токовый такт. */ if (load_count_ramp > time_dac / 2) load_count_ramp++; - /* Проверяет if (++load_count_ramp > time_dac) load_count_ramp = time_dac; последующий оператор выполняется только при истинном условии. */ + /* Продвигает рампу на один отсчёт и ограничивает её концом, заданным LOAD_TIME и DAC_FREQ. */ if (++load_count_ramp > time_dac) load_count_ramp = time_dac; - /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ - } - /* Записывает sinus значением ((load_end - load_go) / 16.0 * load_count_ramp) +; данные sinus. */ - sinus = ((load_end - load_go) / 16.0 * load_count_ramp) + - /* Продолжает список аргументов, полей или выражение (load_go / 16.0 * time_dac);; порядок элементов сохраняется. */ - (load_go / 16.0 * time_dac); - /* Проверяем следующий шаг ДО передачи ЦАП. 6 мА допустимы, - * строго >6 мА и <30 В требуют немедленного STOP. - * Первая попытка входит в лимит 5; шестого START не будет. */ - /* Проверяет if (fresh и voltage < LOAD_VOLTAGE_MIN и; последующий оператор выполняется только при истинном условии. */ - if (fresh && voltage < LOAD_VOLTAGE_MIN && - /* Продолжает список аргументов, полей или выражение sinus * 16.0 > 2.0 * time_dac) {; порядок элементов сохраняется. */ - sinus * 16.0 > 2.0 * time_dac) { - /* Вызывает load_stop. Снимает START и разрешение нагрузки, удерживает STOP 1000 мс и сбрасывает состояние нарастания тока. */ - load_stop(load_attempts >= LOAD_MAX_ATTEMPTS ? - /* Продолжает список аргументов, полей или выражение LOAD_FAULT : LOAD_RELOAD);; порядок элементов сохраняется. */ - LOAD_FAULT : LOAD_RELOAD); - /* Записывает active значением 0; sinus = 0; данные active. */ - active = 0; sinus = 0; - /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ + /* Преобразует продвижение рампы в долю полного токового диапазона 16 мА с учётом начальной уставки. */ + sinus = ((load_end - load_go) / 16.0 * load_count_ramp) + + /* Добавляет начальную уставку относительно базовых 4 мА в тех же единицах положения рампы. */ + (load_go / 16.0 * time_dac); + /* Подтверждённые 30 В завершают стартовое ожидание; последующее падение ЗПТ не получает новую выдержку. */ + if (voltage >= LOAD_VOLTAGE_MIN) load_start_remaining = 0; + /* При меньшем ЗПТ внутренние 2 мА поверх базовых 4 мА ограничивают следующее задание суммарными 6 мА. */ + else if (sinus * 16.0 > 2.0 * time_dac) { + /* До подтверждения порога даёт попытке остаток выбранных 3 секунд, не отправляя повышенный ток. */ + if (load_start_remaining) { + /* Отменяет шаг рампы во время ожидания, чтобы после роста ЗПТ продолжить с прежнего положения. */ + load_count_ramp = ramp_before; + /* Доля 1/8 диапазона 16 мА добавляет 2 мА к базовым 4 мА; time_dac=6000 даёт положение 750. */ + sinus = time_dac / 8.0; + /* Отсчитывает выдержку только после отправки задания; служебная инициализация ЦАП не расходует её. */ + voltage_wait = 1; + /* Исчерпанная выдержка или падение напряжения после успешного роста требуют немедленного STOP. */ + } else { + /* Возвращает 4 мА и снимает разрешение; исчерпание сохранённого лимита попыток запрещает следующий пуск. */ + load_stop(load_attempts >= attempt_limit ? + /* Использует согласованный снимок лимита текущего такта; заводские пять пусков сохраняют прежний предел. */ + LOAD_FAULT : LOAD_RELOAD); + /* Исключает отправку рабочего задания в такте защитной остановки. */ + active = 0; sinus = 0; + /* Закрывает выбор между ожиданием и защитным сбросом. */ + } + /* Завершает проверку следующего токового задания при низком ЗПТ. */ + } + /* Завершает обработку активной рампы при свежем выбранном напряжении CAN. */ } /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ } else { @@ -479,12 +498,6 @@ void Load_runner(void) /* Во время защиты и пуска ручной код калибровки запрещён. * Калибровка сохранена только при снятом START и свободном STOP. * Нулевой код задания здесь означает ток 4 мА по DAC_min(). */ - /* Записывает ump_dac_ramp значением load_count_ramp; ump ЦАП ramp. */ - ump_dac_ramp = load_count_ramp; - /* Записывает ump_dac_duration значением time_dac; ump ЦАП duration. */ - ump_dac_duration = time_dac; - /* Записывает ump_dac_position значением (unsigned int)sinus; ump ЦАП position. */ - ump_dac_position = (unsigned int)sinus; /* Проверяет if (active и !fresh); последующий оператор выполняется только при истинном условии. */ if (active && !fresh) { /* Удерживаем ЦАП. Даже cInitDac не меняет ток в паузе CAN. */ @@ -498,6 +511,8 @@ void Load_runner(void) anal_output((int)sinus, time_dac, /* Продолжает список аргументов, полей или выражение !start && !load_stop_asserted);; порядок элементов сохраняется. */ !start && !load_stop_asserted); + /* Уменьшает остаток только после отправки 6 мА: тайм-аут CAN, инициализация ЦАП и STOP не расходуют выдержку. */ + if (voltage_wait) load_start_remaining--; /* A manual calibration frame is not a confirmed 4 mA reload. * START must wait for a forced baseline frame after it. */ /* Проверяет if (!active) load_zero_sent = !(!start и !load_stop_asserted и cCalibrDac); последующий оператор выполняется только при истинном условии. */ @@ -522,8 +537,6 @@ void Load_runner(void) (load_state == LOAD_RUN ? 8U : 0U) | /* Продолжает список аргументов, полей или выражение (load_simulation << 4);; порядок элементов сохраняется. */ (load_simulation << 4); - /* Записывает LOAD_ATTEMPTS значением load_attempts; число попыток пуска для чтения, регистр 0x7D. */ - LOAD_ATTEMPTS = load_attempts; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } diff --git a/Source/Internal/Include/log_to_mem.h b/Source/Internal/Include/log_to_mem.h index 8afd526..a3aafed 100644 --- a/Source/Internal/Include/log_to_mem.h +++ b/Source/Internal/Include/log_to_mem.h @@ -59,16 +59,14 @@ void clear_mem(); #define UMP_LOG_BASE 0x1000U /* Задаёт UMP_LOG_DATA = 0x1010U; UMP LOG данные. */ #define UMP_LOG_DATA 0x1010U -/* Задаёт UMP_LOG_WORDS = 42U; UMP LOG слова. */ -#define UMP_LOG_WORDS 42U +/* Запись v4 содержит 12 слов: время, событие, дискреты, ток, уставки, два ЗПТ и нулевой резерв для пар CAN. */ +#define UMP_LOG_WORDS 12U /* Задаёт UMP_LOG_CAPACITY = 760U; данные UMP_LOG_CAPACITY. */ #define UMP_LOG_CAPACITY 760U /* Задаёт UMP_LOG_LIVE_RECORDS = (120U / UMP_LOG_WORDS); данные UMP_LOG_LIVE_RECORDS. */ #define UMP_LOG_LIVE_RECORDS (120U / UMP_LOG_WORDS) /* Задаёт UMP_LOG_LIVE = 0x1100U; данные UMP_LOG_LIVE. */ #define UMP_LOG_LIVE 0x1100U -/* Объявляет ump_dac_ramp — ump ЦАП ramp; ump_dac_duration — ump ЦАП duration; ump_dac_go10 — ump ЦАП go 10; ump_dac_stop10 — ump ЦАП stop 10; ump_dac_position — ump ЦАП position. Память определена в другом модуле. */ -extern unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position; /* Явно инициализирует оба банка регистратора до включения IRQ; повторный старт записи архив не стирает. */ void ump_log_init(void); /* Продвигает время регистратора в Timer1 и снимает записи с заданным периодом. */ diff --git a/Source/Internal/Include/message.h b/Source/Internal/Include/message.h index 3a16c27..b461a42 100644 --- a/Source/Internal/Include/message.h +++ b/Source/Internal/Include/message.h @@ -68,7 +68,7 @@ void ReceiveAnswerModbus4(RS_DATA *rs_arr); void Save_params(void); /* Читает сохранённые регистры из области параметров EEPROM и применяет настройки платы. */ void Load_params(void); -/* Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */ +/* Объявляет восстановление заводских параметров; для LOAD функция задаёт тайм-аут свежести CAN 2000 мс. */ void Default_params(void); /* Закрывает условный блок препроцессора; дальнейшие строки относятся к внешнему уровню. */ diff --git a/Source/Internal/Include/package.h b/Source/Internal/Include/package.h index 01ec6f3..b397393 100644 --- a/Source/Internal/Include/package.h +++ b/Source/Internal/Include/package.h @@ -171,13 +171,15 @@ /* Задаёт DAC_stop = modbus[0x51]; конечный ток нагрузки в мА, технологический регистр 0x51. */ #define DAC_stop modbus[0x51] // конец зарада -/* LOAD-only persistent CAN timeout (ms), read-only status and attempts. */ +/* На плате LOAD тайм-аут и лимит попыток сохраняются штатной командой Save; состояние защиты доступно только для чтения. */ /* Задаёт LOAD_CAN_TIMEOUT = modbus[0x52]; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */ #define LOAD_CAN_TIMEOUT modbus[0x52] /* Задаёт LOAD_STATUS = modbus[0x7C]; слово состояния защиты нагрузки для чтения, регистр 0x7C. */ #define LOAD_STATUS modbus[0x7C] -/* Задаёт LOAD_ATTEMPTS = modbus[0x7D]; число попыток пуска для чтения, регистр 0x7D. */ -#define LOAD_ATTEMPTS modbus[0x7D] +/* Задаёт записываемый лимит общего числа пусков в регистре 0x7D; допустимы 1..65535 попыток, включая первый START. */ +#define LOAD_MAX_ATTEMPTS modbus[0x7D] +/* Сохраняет прежний заводской предел пяти пусков для сброса настроек и замены нуля из старой EEPROM. */ +#define LOAD_DEFAULT_MAX_ATTEMPTS 5U /* Задаёт Cancount = (modbus+0x60); данные Cancount. */ #define Cancount (modbus+0x60) // пауза между I посылками CAN diff --git a/Source/Internal/Include/spise2p.h b/Source/Internal/Include/spise2p.h index 07c3380..ce1a02f 100644 --- a/Source/Internal/Include/spise2p.h +++ b/Source/Internal/Include/spise2p.h @@ -93,9 +93,9 @@ typedef unsigned int SE2P_SIZE; /* Message declaration */ /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef struct { - unsigned int *dataPtr; /* Data pointer */ /* Объявляет dataPtr — данные Ptr. Хранит указатель на данные. */ - unsigned long nrData; /* number of data */ /* Объявляет nrData — nr данные. */ - unsigned long se2pAddr; /* se2pAddr */ /* Объявляет se2pAddr — данные se2pAddr. */ + unsigned int * volatile dataPtr; /* Указатель буфера публикуется до csr: volatile запрещает перенос его записи за ожидание Timer2. */ + volatile unsigned long nrData; /* Число 16-битных слов записывается до флага запуска; Timer2 использует его для завершения передачи. */ + volatile unsigned long se2pAddr; /* Байтовый адрес EEPROM публикуется до csr; прерывание должно получить адрес текущего задания. */ /* Продолжает список аргументов, полей или выражение }SE2P_DATA;; порядок элементов сохраняется. */ }SE2P_DATA; @@ -103,8 +103,8 @@ typedef struct { /* Object declaration */ /* Начинает объявление типа, используемого структурами и интерфейсами этого модуля. */ typedef struct { -/* Main loop publishes the descriptor before setting csr; Timer2 consumes it. - * Both accesses are volatile so optimization cannot publish the request first. */ +/* Главный цикл заполняет volatile-поля задания, затем msgPtr и csr; Timer2 читает их после запроса. + * Одного volatile у msgPtr недостаточно: он защищает указатель, но не содержимое задания. */ /* Продолжает список аргументов, полей или выражение SE2P_DATA * volatile msgPtr;; порядок элементов сохраняется. */ SE2P_DATA * volatile msgPtr; volatile unsigned int csr; /* control/status register */ /* Объявляет csr — данные csr. volatile требует фактического чтения или записи при каждом доступе. */ diff --git a/Source/Internal/RS485.c b/Source/Internal/RS485.c index 58944c3..8b0cfc4 100644 --- a/Source/Internal/RS485.c +++ b/Source/Internal/RS485.c @@ -9,6 +9,7 @@ /* Подключает "RS485.h": приём и передача SCI-A/SCI-B, упаковка команд и FIFO первого порта. */ #include "RS485.h" +#include /* Объявляет memset для явного сброса UART: загрузчик COFF не гарантирует очистку .ebss. */ /* Подключает "bios_dsp.h": коды и объявления команд последовательного загрузчика. */ #include "bios_dsp.h" /* Подключает "cntrl_adr.h": собственный и универсальный адрес устройства. */ @@ -730,6 +731,7 @@ void RS_SetLineSpeed(RS_DATA *rs_arr,unsigned long speed) rs_arr->SciRegs->SCIHBAUD = HIBYTE((int)SciBaud); /* Записывает rs_arr->SciRegs->SCILBAUD значением LOBYTE((int)SciBaud); rs arr SCI Regs SCILBAUD. */ rs_arr->SciRegs->SCILBAUD = LOBYTE((int)SciBaud); + rs_arr->curr_baud = speed; /* Сохраняет установленную скорость в бодах для последующих команд переключения линии и диагностики CCS. */ /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } @@ -741,6 +743,8 @@ void create_uart_vars(char size_cmd15_set) { /* Записывает size_cmd15 значением size_cmd15_set; размер cmd 15. */ size_cmd15=size_cmd15_set; + memset(&rs_a, 0, sizeof(rs_a)); /* Сбрасывает указатели, длины, буферы и флаги SCI-A до настройки порта; исключает остатки RAM после JTAG. */ + memset(&rs_b, 0, sizeof(rs_b)); /* Независимо сбрасывает состояние SCI-B до назначения номера и аппаратных регистров. */ /* Записывает rs_a.commnumber значением COM_1; данные commnumber. */ rs_a.commnumber=COM_1; /* Записывает rs_b.commnumber значением COM_2; данные commnumber. */ diff --git a/Source/Internal/ecan.c b/Source/Internal/ecan.c index f61ba4f..d79fd3f 100644 --- a/Source/Internal/ecan.c +++ b/Source/Internal/ecan.c @@ -335,10 +335,8 @@ void CAN_send(int Port, int data[], int Addr) void Handlai(volatile struct ECAN_MBOXES * ECanMboxes) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { - /* Объявляет adr — данные adr. */ - unsigned int adr; - /* Объявляет bit — представление регистра отдельными битовыми полями. */ - unsigned int bit[3]; + /* adr адресует очередное технологическое слово, slot выбирает одно из трёх слов кадра, mask хранит их биты достоверности 15..13. */ + unsigned int adr, slot, mask; /* Объявляет hiword — данные hiword; loword — данные loword. */ unsigned long hiword,loword; /* Объявляет Data — данные. */ @@ -376,12 +374,8 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes) /* Записывает adr значением (hiword >> 16); данные adr. */ adr = (hiword >> 16); - /* Записывает bit[0] значением adr & 0x8000; представление регистра отдельными битовыми полями. */ - bit[0] = adr & 0x8000; - /* Записывает bit[1] значением adr & 0x4000; представление регистра отдельными битовыми полями. */ - bit[1] = adr & 0x4000; - /* Записывает bit[2] значением adr & 0x2000; представление регистра отдельными битовыми полями. */ - bit[2] = adr & 0x2000; + /* Маска 0xE000 объединяет биты достоверности трёх слов CAN; сдвиг в цикле последовательно выводит каждый из них в бит 15. */ + mask = adr & 0xE000U; /* Оставляет биты маски adr значением 0x1fff; данные adr. */ adr &= 0x1fff; @@ -393,18 +387,12 @@ void Handlai(volatile struct ECAN_MBOXES * ECanMboxes) /* Записывает Data[2] значением (loword ) & 0xffff; данные. */ Data[2] = (loword ) & 0xffff; - /* Проверяет if(bit[0]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */ - if(bit[0]) if(adr < ANSWER_LEN && - /* Записывает modbus[adr] значением Data[0]; adr++; массив технологических регистров; слово int на C28x занимает 16 бит. */ - !(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[0]; adr++; - /* Проверяет if(bit[1]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */ - if(bit[1]) if(adr < ANSWER_LEN && - /* Записывает modbus[adr] значением Data[1]; adr++; массив технологических регистров; слово int на C28x занимает 16 бит. */ - !(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[1]; adr++; - /* Проверяет if(bit[2]) if(adr < ANSWER_LEN и; последующий оператор выполняется только при истинном условии. */ - if(bit[2]) if(adr < ANSWER_LEN && - /* Записывает modbus[adr] значением Data[2]; массив технологических регистров; слово int на C28x занимает 16 бит. */ - !(Desk == dsk_LOAD && (adr == 0x7CU || adr == 0x7DU))) modbus[adr] = Data[2]; + /* Обрабатывает ровно три слова CAN; адрес растёт независимо от маски, а её сдвиг выбирает достоверность следующего слова. */ + for (slot = 0; slot < 3; slot++, adr++, mask <<= 1) + /* Бит 15 текущей маски разрешает запись только в опубликованные 128 регистров, исключая выход за массив. */ + if ((mask & 0x8000U) && adr < ANSWER_LEN && + /* Для LOAD сохраняет статус 0x7C и отклоняет ноль в лимите 0x7D; остальные значения сохраняются как исходное 16-битное слово. */ + !(Desk == dsk_LOAD && (adr == 0x7CU || (adr == 0x7DU && !(unsigned int)Data[slot])))) modbus[adr] = Data[slot]; /* Фиксируем применённую команду до выхода из обработчика CAN. */ /* A short frame cannot confirm voltage freshness. Service frames diff --git a/Source/Internal/gas167.c b/Source/Internal/gas167.c index f9b4846..2e2050a 100644 --- a/Source/Internal/gas167.c +++ b/Source/Internal/gas167.c @@ -17,7 +17,7 @@ extern void ump_log_rs(void); static const uint16_t gas167_info[GAS167_INFO_WORDS] = { /* Слова 0..3: сигнатура GA/S1, версия профиля и номер проекта 167. */ 0x4741U, 0x5331U, GAS167_PROFILE_VERSION, 167U, - /* Слова 4..7: начало 0x5000, длина 128 слов, возможности RTU/CAN/FC06 и размер адресной единицы в словах. */ + /* Слова 4..7: база технологических регистров, число слов, маска RTU/CAN/FC06 и признак EEPROM M95M02 = 1; последний элемент описывает аппаратный профиль. */ GAS167_REG_BASE, GAS167_REG_COUNT, GAS167_CAPABILITIES, 1U /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ }; @@ -39,8 +39,10 @@ static unsigned gas167_write(uint16_t offset, uint16_t value) { /* Правила записи совпадают со штатным Modbus: статусы защиты нельзя * перезаписать, а недопустимый тайм-аут не позволяет обойти защиту. */ - /* На плате LOAD состояния 0x7C/0x7D принадлежат защите; запись отклоняется кодом неверного адреса 2. */ - if (Desk == dsk_LOAD && (offset == 0x7CU || offset == 0x7DU)) return 2; + /* Состояние защиты 0x7C остаётся только для чтения; GAS-псевдоним лимита 0x507D допускает запись. */ + if (Desk == dsk_LOAD && offset == 0x7CU) return 2; + /* Отклоняет нулевой лимит кодом Modbus 3 одинаково для RTU и служебного CAN; uint16_t ограничивает верхнюю границу 65535. */ + if (Desk == dsk_LOAD && offset == 0x7DU && value == 0U) return 3; /* Для сохраняемого тайм-аута CAN нагрузки применяется проверка диапазона независимо от транспорта. */ if (Desk == dsk_LOAD && offset == 0x52U && /* Значение 0 или больше 60000 мс недопустимо и возвращает код 3; защиту нельзя отключить такой записью. */ diff --git a/Source/Internal/log_to_mem.c b/Source/Internal/log_to_mem.c index f03268a..08be189 100644 --- a/Source/Internal/log_to_mem.c +++ b/Source/Internal/log_to_mem.c @@ -75,19 +75,11 @@ static unsigned int ump_source, ump_post; #define UMP_POST_POINTS (UMP_LOG_CAPACITY / 10U) /* Замораживает заполненный банк и переключает рабочий банк, сохраняя доступный архив. */ static void ump_freeze(void); -/* Объявляет ump_can_header — ump CAN header; ump_can_data — ump CAN данные; ump_can_count — ump CAN число. */ -static unsigned int ump_can_header, ump_can_data[3], ump_can_count; /* Latest PM67 sums: register 306 (index 305), register 9 (index 8). */ /* Объявляет ump_pm67_voltage — данные ump_pm67_voltage. */ static unsigned int ump_pm67_voltage[2]; /* Объявляет ump_prev_commands — данные ump_prev_commands; ump_prev_inputs — данные ump_prev_inputs; ump_prev_outputs — данные ump_prev_outputs. */ static unsigned int ump_prev_commands, ump_prev_inputs, ump_prev_outputs; -/* Объявляет CanTimeOutErrorTR — CAN Time Out ошибка TR. Память определена в другом модуле. */ -extern int CanTimeOutErrorTR; -/* Диагностика внутренних переменных разгона. Обновляется самим Load_runner, - * не пересчитывает и не изменяет управляющий алгоритм. */ -/* Объявляет ump_dac_ramp — ump ЦАП ramp; ump_dac_duration — ump ЦАП duration; ump_dac_go10 — ump ЦАП go 10; ump_dac_stop10 — ump ЦАП stop 10; ump_dac_position — ump ЦАП position. */ -unsigned int ump_dac_ramp, ump_dac_duration, ump_dac_go10, ump_dac_stop10, ump_dac_position; /* Called once at boot, before enabling interrupts. TI COFF startup does * not clear uninitialized globals in .ebss. Do not use for record restart: @@ -110,18 +102,10 @@ void ump_log_init(void) ump_archive_count = 0; ump_archive_next = 0; ump_generation = 0; /* Записывает ump_source значением 0; ump_post = 0; данные ump_source. */ ump_source = 0; ump_post = 0; - /* Записывает ump_can_header значением 0; ump_can_count = 0; ump CAN header. */ - ump_can_header = 0; ump_can_count = 0; - /* Цикл for (i = 0; i < 3; i++) ump_can_data[i] = 0;; задаёт начальное значение, условие продолжения и шаг перебора. */ - for (i = 0; i < 3; i++) ump_can_data[i] = 0; /* Цикл for (i = 0; i < 2; i++) ump_pm67_voltage[i] = 0;; задаёт начальное значение, условие продолжения и шаг перебора. */ for (i = 0; i < 2; i++) ump_pm67_voltage[i] = 0; /* Записывает ump_prev_commands значением 0; ump_prev_inputs = 0; ump_prev_outputs = 0; данные ump_prev_commands. */ ump_prev_commands = 0; ump_prev_inputs = 0; ump_prev_outputs = 0; - /* Записывает ump_dac_ramp значением 0; ump_dac_duration = 0; ump_dac_go10 = 0; ump ЦАП ramp. */ - ump_dac_ramp = 0; ump_dac_duration = 0; ump_dac_go10 = 0; - /* Записывает ump_dac_stop10 значением 0; ump_dac_position = 0; ump ЦАП stop 10. */ - ump_dac_stop10 = 0; ump_dac_position = 0; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } @@ -164,8 +148,8 @@ static void ump_capture(unsigned int reason) { /* Объявляет p — данные p. Хранит указатель на данные. volatile требует фактического чтения или записи при каждом доступе. */ volatile unsigned int *p; - /* Объявляет i — данные i; commands — данные commands; inputs — данные inputs; outputs — данные outputs. */ - unsigned int i, commands, inputs, outputs; + /* Объявляет commands — данные commands; inputs — данные inputs; outputs — данные outputs. */ + unsigned int commands, inputs, outputs; /* Проверяет if (ump_state != 1 или Desk != dsk_LOAD или !READY) return; последующий оператор выполняется только при истинном условии. */ if (ump_state != 1 || Desk != dsk_LOAD || !READY) return; /* Проверяет if (no_write или never_write); последующий оператор выполняется только при истинном условии. */ @@ -200,40 +184,20 @@ static void ump_capture(unsigned int reason) if (ump_post && !(reason & 0x100) && --ump_post == 0) reason = 5; /* Записывает p значением logs_block + ((unsigned long)ump_bank * UMP_LOG_CAPACITY + ump_next) * UMP_LOG_WORDS; данные p. */ p = logs_block + ((unsigned long)ump_bank * UMP_LOG_CAPACITY + ump_next) * UMP_LOG_WORDS; - /* Записывает p[0] значением (unsigned int)ump_time; p[1] = (unsigned int)(ump_time >> 16); данные p. */ + /* Сохраняет 32-битное миллисекундное время младшим словом вперёд; это первые два слова записи v4. */ p[0] = (unsigned int)ump_time; p[1] = (unsigned int)(ump_time >> 16); - /* Записывает p[2] значением reason; p[3] = commands; данные p. */ - p[2] = reason; p[3] = commands; - /* Записывает p[4] значением inputs; p[5] = outputs; данные p. */ + /* Событие сохраняет причину и метку отключения; от команд остаются только нужные дискретные пуск и сброс, биты 7/6. */ + p[2] = reason; p[3] = commands & 0xC0U; + /* Оставляет логические уровни входов и выходов для графиков START, STOP, OMEGA и разрешения нагрузки. */ p[4] = inputs; p[5] = outputs; - /* Записывает p[6] значением (unsigned int)IMPowse; p[7] = (unsigned int)WAKEpowse; данные p. */ - p[6] = (unsigned int)IMPowse; p[7] = (unsigned int)WAKEpowse; - /* Записывает p[8] значением modbus[0x7B]; p[9] = modbus[0x1C]; данные p. */ - p[8] = modbus[0x7B]; p[9] = modbus[0x1C]; - /* Цикл for (i = 0; i < 4; i++) ; задаёт начальное значение, условие продолжения и шаг перебора. */ - for (i = 0; i < 4; i++) { p[10+i] = sens_data[i]; p[14+i] = modbus[i]; } - /* Записывает p[18] значением ump_can_header; данные p. */ - p[18] = ump_can_header; - /* Записывает p[19] значением ump_can_data[0]; p[20] = ump_can_data[1]; p[21] = ump_can_data[2]; данные p. */ - p[19] = ump_can_data[0]; p[20] = ump_can_data[1]; p[21] = ump_can_data[2]; - /* Записывает p[22] значением ump_can_count; p[23] = CanTimeOutErrorTR; данные p. */ - p[22] = ump_can_count; p[23] = CanTimeOutErrorTR; - /* Исходные уставки — мА; эффективные уставки после ограничений — 0.1 мА. - * p[8] — отправленный код, а p[9] — расчётное задание, НЕ измерение тока. */ - /* Записывает p[24] значением DAC_go; p[25] = DAC_stop; данные p. */ - p[24] = DAC_go; p[25] = DAC_stop; - /* Записывает p[26] значением DAC_min(); p[27] = DAC_max(); p[28] = DAC_cal(); данные p. */ - p[26] = DAC_min(); p[27] = DAC_max(); p[28] = DAC_cal(); - /* Записывает p[29] значением DAC_04; p[30] = DAC_20; данные p. */ - p[29] = DAC_04; p[30] = DAC_20; - /* Записывает p[31] значением ump_dac_ramp; p[32] = ump_dac_duration; данные p. */ - p[31] = ump_dac_ramp; p[32] = ump_dac_duration; - /* Записывает p[33] значением ump_dac_go10; p[34] = ump_dac_stop10; p[35] = ump_dac_position; данные p. */ - p[33] = ump_dac_go10; p[34] = ump_dac_stop10; p[35] = ump_dac_position; - /* Цикл for (i = 0; i < 4; i++) p[36+i] = ADC_table[i];; задаёт начальное значение, условие продолжения и шаг перебора. */ - for (i = 0; i < 4; i++) p[36+i] = ADC_table[i]; - /* Записывает p[40] значением ump_pm67_voltage[0]; p[41] = ump_pm67_voltage[1]; данные p. */ - p[40] = ump_pm67_voltage[0]; p[41] = ump_pm67_voltage[1]; + /* Задание тока берётся из регистра 0x1C в единицах 0,1 мА; это расчётная величина, а не измерение физического тока. */ + p[6] = modbus[0x1C]; + /* Сохраняет оставшиеся выбранные начальную и конечную уставки в целых мА. */ + p[7] = DAC_go; p[8] = DAC_stop; + /* Оставляет оба ЗПТ в вольтах: CAN-индекс 305 относится к ЗПТ1, индекс 8 — к ЗПТ2. */ + p[9] = ump_pm67_voltage[0]; p[10] = ump_pm67_voltage[1]; + /* Резервное нулевое слово делает длину записи чётной: служебный CAN передаёт по два 16-битных слова за фрагмент. */ + p[11] = 0; /* Изменяет счётчик в выражении ump_next++; на один для следующего шага. */ ump_next++; /* Проверяет if (ump_next == UMP_LOG_CAPACITY) ump_next = 0; последующий оператор выполняется только при истинном условии. */ @@ -338,12 +302,6 @@ void ump_log_can(unsigned int header, unsigned int a, unsigned int b, unsigned i } /* Проверяет if (ump_state != 1); последующий оператор выполняется только при истинном условии. */ if (ump_state != 1) { __restore_interrupts(saved); return; } - /* Записывает ump_can_header значением header; ump CAN header. */ - ump_can_header = header; - /* Записывает ump_can_data[0] значением a; ump_can_data[1] = b; ump_can_data[2] = c; ump CAN данные. */ - ump_can_data[0] = a; ump_can_data[1] = b; ump_can_data[2] = c; - /* Изменяет счётчик в выражении ump_can_count++; на один для следующего шага. */ - ump_can_count++; /* Вызывает ump_capture. Создаёт одну запись состояния: входы, выходы, команды, напряжения и параметры тока нагрузки. */ ump_capture(2); /* Вызывает __restore_interrupts с аргументами (saved) в текущей последовательности операций. */ @@ -456,7 +414,7 @@ unsigned int ump_log_read(unsigned int address) /* Ветвь выбора для UMP_LOG_BASE; выполняется при совпадении селектора switch. */ case UMP_LOG_BASE: return 0x554D; /* Ветвь выбора для UMP_LOG_BASE+1; выполняется при совпадении селектора switch. */ - case UMP_LOG_BASE+1: return 3; + case UMP_LOG_BASE+1: return 4; /* Ветвь выбора для UMP_LOG_BASE+2; выполняется при совпадении селектора switch. */ case UMP_LOG_BASE+2: return ump_source ? 3 : ump_state; /* Ветвь выбора для UMP_LOG_BASE+3; выполняется при совпадении селектора switch. */ @@ -501,7 +459,7 @@ unsigned int ump_log_read(unsigned int address) return ump_word(ump_source, ump_cursor + offset / UMP_LOG_WORDS, offset % UMP_LOG_WORDS); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } - /* Последние три записи для онлайн-графика, без остановки и без + /* Последние UMP_LOG_LIVE_RECORDS записей для онлайн-графика, без остановки и без * изменения курсора архивного чтения. Первые два слова — их номер. */ /* Проверяет if (address >= UMP_LOG_LIVE и address < UMP_LOG_LIVE+124); последующий оператор выполняется только при истинном условии. */ if (address >= UMP_LOG_LIVE && address < UMP_LOG_LIVE+124) { diff --git a/Source/Internal/main.c b/Source/Internal/main.c index 261f77e..47fcdec 100644 --- a/Source/Internal/main.c +++ b/Source/Internal/main.c @@ -109,7 +109,7 @@ void main() setup_uart(COM_1,115200); /* Проверяет if(Owen)setup_uart(COM_2,57600); последующий оператор выполняется только при истинном условии. */ - if(Owen)setup_uart(COM_2,57600); + if(Owen)setup_uart(COM_2,115200); /* Выполняет альтернативу, если предыдущее условие if оказалось ложным. */ else setup_uart(COM_2,115200); @@ -266,7 +266,7 @@ void main() { /* Записывает cDefParam значением 0; данные cDefParam. */ cDefParam=0; - /* Вызывает Default_params. Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */ + /* По команде восстановления записывает заводские параметры; для LOAD тайм-аут свежести CAN становится 2000 мс. */ Default_params(); /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } diff --git a/Source/Internal/measure.c b/Source/Internal/measure.c index c8a41f1..781907c 100644 --- a/Source/Internal/measure.c +++ b/Source/Internal/measure.c @@ -746,7 +746,7 @@ void Init_packMask() { Maska[m_SLOW][7]|= 0x0030; // Калибровка ЦАП /* Устанавливает биты Maska[m_SLOW][5] значением 0x0003; данные Maska. */ Maska[m_SLOW][5]|= 0x0003; // Начало и конец зарада - Maska[m_FAST][7]|= 0xF000; /* Protection status 0x7C + attempts 0x7D. */ // Дублировать команды /* Устанавливает биты Maska[m_FAST][7] значением 0xF000; данные Maska. */ + Maska[m_FAST][7]|= 0xF000; /* Быстрый CAN публикует статус 0x7C и настроенный лимит пусков 0x7D; биты 12..15 маски соответствуют адресам 0x7C..0x7F. */ // Дублировать команды /* Устанавливает биты Maska[m_FAST][7] значением 0xF000; данные Maska. */ /* Устанавливает биты Maska[m_FAST][1] значением 0x3000; данные Maska. */ Maska[m_FAST][1]|= 0x3000; // Управлающий ток СИФУ /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ diff --git a/Source/Internal/message.c b/Source/Internal/message.c index fff2907..be1bf8e 100644 --- a/Source/Internal/message.c +++ b/Source/Internal/message.c @@ -59,7 +59,7 @@ int modbus[ANSWER_LEN+1]; /* Объявляет param — данные param. */ unsigned int param[ANSWER_LEN+1]; -/* Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */ +/* Заполняет регистры заводскими значениями; для LOAD задаёт тайм-аут свежести CAN 2000 мс. Значение 600 мс применяется отдельно при восстановлении недопустимого параметра. */ void Default_params() /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { @@ -248,6 +248,8 @@ void Default_params() /* Записывает DAC_go значением 6; начальный ток нагрузки в мА, технологический регистр 0x50. */ DAC_go = 6; // начало зарада LOAD_CAN_TIMEOUT = 2000; /* ms without fresh ZPT: freeze ramp. */ /* Записывает LOAD_CAN_TIMEOUT значением 2000; сохраняемый тайм-аут свежести напряжения CAN в миллисекундах, регистр 0x52. */ + /* Устанавливает прежний заводской лимит пяти пусков, включая первый START; настройка хранится в сохраняемом регистре 0x7D. */ + LOAD_MAX_ATTEMPTS = LOAD_DEFAULT_MAX_ATTEMPTS; /* Записывает DAC_stop значением 16; конечный ток нагрузки в мА, технологический регистр 0x51. */ DAC_stop= 16; // конец зарада @@ -295,7 +297,7 @@ void Load_params() else /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { - /* Вызывает Default_params. Заполняет регистры заводскими значениями; тайм-аут CAN нагрузки по умолчанию равен 600 мс. */ + /* Восстанавливает заводские параметры после неверного CRC или несоответствия режима платы; LOAD_CAN_TIMEOUT получает 2000 мс. */ Default_params(); /* Записывает Commands значением 0; слово команд, технологический регистр 127. */ Commands=0; @@ -373,7 +375,7 @@ static void modbus_exception(RS_DATA *rs_arr, unsigned int function, unsigned in } /* UART parser has already validated CRC and accepted the device address. */ -/* Выбирает GAS либо существующее адресное пространство УМП и снимает согласованный ответ под краткой блокировкой IRQ. */ +/* Маршрутизирует расширенные адреса: RAM УМП/GAS захватывается под краткой блокировкой IRQ, а чтение EEPROM выполняется с разрешёнными IRQ, поскольку SPI продвигается из Timer2. */ static int receive_ump(RS_DATA *rs_arr) /* Открывает составной блок или описание полей; следующие строки принадлежат этому уровню вложенности. */ { @@ -381,7 +383,7 @@ static int receive_ump(RS_DATA *rs_arr) unsigned int address, value, saved, length, count, error; /* Main-loop only; encoded into the UART buffer before the next request. * Keep the 124-word snapshot off the shared interrupt stack. */ - /* Объявляет words — слова. */ + /* Статический буфер хранит до 124 слов снимка вне общего стека прерываний; главный цикл сериализует его до обработки следующего запроса. */ static uint16_t words[UMP_MAX_WORDS]; /* Записывает address значением (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3]; адрес. */ address = (rs_arr->RS_Header[2] << 8) | rs_arr->RS_Header[3]; @@ -503,17 +505,18 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr) /* Записывает rs_arr->buffer[2] значением Length_MB*2; rs arr буфер. */ rs_arr->buffer[2] = Length_MB*2; - /* Защищаем целостность одного снимка/блока; передача UART идёт уже - * с разрешёнными прерываниями и не задерживает измерение/управление. */ - /* Цикл for (i=0;ibuffer[3+i*2] значением (value >> 8) & 0xFF; rs arr буфер. */ + /* Помещает старший байт слова после трёхбайтного заголовка; данные регистра передаются старшим байтом вперёд. */ rs_arr->buffer[3+i*2] = (value >> 8) & 0xFF; - /* Записывает rs_arr->buffer[3+i*2+1] значением value & 0xFF; rs arr буфер. */ + /* Помещает младший байт непосредственно за старшим, сохраняя исходный 16-битный рисунок регистра. */ rs_arr->buffer[3+i*2+1] = value & 0xFF; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } @@ -528,13 +531,13 @@ void ReceiveCommandModbus3(RS_DATA *rs_arr) /* Записывает rs_arr->buffer[Length_MB*2+4] значением HIBYTE(crc); rs arr буфер. */ rs_arr->buffer[Length_MB*2+4] = HIBYTE(crc); - /* Записывает rs_arr->buffer[Length_MB*2+5] значением 0; rs arr буфер. */ + /* Первый исторический нулевой байт после CRC; входит в увеличенную длину штатного ответа. */ rs_arr->buffer[Length_MB*2+5] = 0; - /* Записывает rs_arr->buffer[Length_MB*2+6] значением 0; rs arr буфер. */ + /* Второй исторический нулевой байт после CRC; сохраняет прежний формат низких технологических адресов. */ rs_arr->buffer[Length_MB*2+6] = 0; - /* Записывает rs_arr->buffer[Length_MB*2+7] значением 0; rs arr буфер. */ + /* Третий исторический нулевой байт после CRC; это последний элемент передаваемого буфера при длине 2*N+8. */ rs_arr->buffer[Length_MB*2+7] = 0; - /* Записывает rs_arr->buffer[Length_MB*2+8] значением 0; rs arr буфер. */ + /* Дополнительный ноль находится за длиной, переданной в RS_Send; в текущий ответ это слово не отправляется. */ rs_arr->buffer[Length_MB*2+8] = 0; /* Записывает rs_arr->flag_TIMEOUT_to_Send значением true; rs arr флаг TIMEOUT to Send. */ @@ -577,12 +580,18 @@ void ReceiveCommandModbus6(RS_DATA *rs_arr) /* Записывает Data_MB значением (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5]; данные MB. */ Data_MB = (rs_arr->RS_Header[4] << 8) | rs_arr->RS_Header[5]; - /* Проверяет if (Desk == dsk_LOAD и (Address_MB == 0x7CU или Address_MB == 0x7DU)); последующий оператор выполняется только при истинном условии. */ - if (Desk == dsk_LOAD && (Address_MB == 0x7CU || Address_MB == 0x7DU)) { + /* На плате LOAD запрещает запись только состояния защиты 0x7C; регистр лимита 0x7D принимает настройку. */ + if (Desk == dsk_LOAD && Address_MB == 0x7CU) { /* Вызывает modbus_exception. Формирует ответ Modbus с установленным старшим битом функции и кодом исключения. */ modbus_exception(rs_arr, CMD_MODBUS_6, 2); return; /* Закрывает текущий блок или список полей; следующие операторы относятся к внешнему уровню. */ } + /* Ноль в лимите 0x7D недопустим: первый пуск должен входить в разрешённые 1..65535 попыток. */ + if (Desk == dsk_LOAD && Address_MB == 0x7DU && Data_MB == 0U) { + /* Возвращает код Modbus 3 для недопустимого значения, сохраняя прежний лимит и состояние автомата. */ + modbus_exception(rs_arr, CMD_MODBUS_6, 3); return; + /* Завершает проверку ненулевого лимита перед общей записью технологического слова. */ + } /* Проверяет if (Desk == dsk_LOAD и Address_MB == 0x52U и; последующий оператор выполняется только при истинном условии. */ if (Desk == dsk_LOAD && Address_MB == 0x52U && /* Продолжает список аргументов, полей или выражение (Data_MB == 0U || Data_MB > 60000U)) {; порядок элементов сохраняется. */ diff --git a/UKSSTMS320F28335.map b/UKSSTMS320F28335.map index 8ca14f5..f96bf6e 100644 --- a/UKSSTMS320F28335.map +++ b/UKSSTMS320F28335.map @@ -1,10 +1,10 @@ ****************************************************************************** TMS320C2000 Linker PC v22.6.0 ****************************************************************************** ->> Linked Thu Oct 1 18:01:50 2026 +>> Linked Mon Oct 12 12:22:39 2026 OUTPUT FILE NAME: -ENTRY POINT SYMBOL: "_c_int00" address: 0000b9b5 +ENTRY POINT SYMBOL: "_c_int00" address: 0000a855 MEMORY CONFIGURATION @@ -13,8 +13,8 @@ MEMORY CONFIGURATION ---------------------- -------- --------- -------- -------- ---- -------- PAGE 0: ZONE0 00004000 00001000 00000000 00001000 RWIX - RAML0 00008000 00004000 00003b73 0000048d RWIX - RAML4 0000c000 00001000 000003f8 00000c08 RWIX + RAML0 00008000 00004000 00003aa7 00000559 RWIX + RAML4 0000c000 00001000 000003e6 00000c1a RWIX ZONE6 00100000 00100000 00000000 00100000 RWIX FLASHH 00300000 00008000 00000000 00008000 RWIX FLASHG 00308000 00008000 00000000 00008000 RWIX @@ -87,7 +87,7 @@ PAGE 1: SCIB 00007750 00000010 00000010 00000000 RWIX SCIC 00007770 00000010 00000010 00000000 RWIX I2CA 00007900 00000040 00000022 0000001e RWIX - RAML5 0000d000 00003000 00000fdf 00002021 RWIX + RAML5 0000d000 00003000 0000105e 00001fa2 RWIX ZONE7A 00200000 0000fc00 0000fa00 00000200 RWIX ZONE7B 0020fc00 00000400 00000000 00000400 RWIX FLASHB 00330000 00008000 00000000 00008000 RWIX @@ -100,7 +100,7 @@ SECTION ALLOCATION MAP output attributes/ section page origin length input sections -------- ---- ---------- ---------- ---------------- -.cinit 0 0000c000 0000028b +.cinit 0 0000c000 00000273 0000c000 00000103 crc16.obj (.cinit:_crc_16_tab) 0000c103 00000043 message.obj (.cinit:_def_cal) 0000c146 0000003d measure.obj (.cinit) @@ -111,88 +111,269 @@ section page origin length input sections 0000c1f3 00000014 log_to_mem.obj (.cinit) 0000c207 00000013 kanal.obj (.cinit:_digits) 0000c21a 00000011 pulto.obj (.cinit) - 0000c22b 00000010 DAC.obj (.cinit) - 0000c23b 0000000a rts2800_fpu32.lib : _lock.obj (.cinit) - 0000c245 0000000a : exit.obj (.cinit) - 0000c24f 00000008 ADC.obj (.cinit) - 0000c257 00000008 kanal.obj (.cinit:_readr) - 0000c25f 00000008 cntrl_adr.obj (.cinit) - 0000c267 00000008 main.obj (.cinit) - 0000c26f 00000005 ADC.obj (.cinit:_cwnt_ok$4) - 0000c274 00000005 measure.obj (.cinit:_low_count) - 0000c279 00000004 RS485.obj (.cinit) - 0000c27d 00000004 RS485.obj (.cinit:_RS_Len) - 0000c281 00000004 bios.obj (.cinit) - 0000c285 00000004 rts2800_fpu32.lib : errno.obj (.cinit) - 0000c289 00000002 --HOLE-- [fill = 0] + 0000c22b 0000000a rts2800_fpu32.lib : _lock.obj (.cinit) + 0000c235 0000000a : exit.obj (.cinit) + 0000c23f 00000008 ADC.obj (.cinit) + 0000c247 00000008 kanal.obj (.cinit:_readr) + 0000c24f 00000008 cntrl_adr.obj (.cinit) + 0000c257 00000005 ADC.obj (.cinit:_cwnt_ok$4) + 0000c25c 00000005 measure.obj (.cinit:_low_count) + 0000c261 00000004 RS485.obj (.cinit) + 0000c265 00000004 RS485.obj (.cinit:_RS_Len) + 0000c269 00000004 bios.obj (.cinit) + 0000c26d 00000004 rts2800_fpu32.lib : errno.obj (.cinit) + 0000c271 00000002 --HOLE-- [fill = 0] .pinit 0 00008000 00000000 UNINITIALIZED -.text 0 00008000 00003b73 - 00008000 000008e6 measure.obj (.text) - 000088e6 00000711 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:retain) - 00008ff7 000003c3 peripher.obj (.text) - 000093ba 000003bd RS485.obj (.text) - 00009777 0000037f log_to_mem.obj (.text) - 00009af6 00000325 message.obj (.text) - 00009e1b 00000309 shared_ump.obj (.text) - 0000a124 000002bf bios.obj (.text) - 0000a3e3 0000025b spise2p.obj (.text) - 0000a63e 0000024d main.obj (.text) - 0000a88b 000001f9 ecan.obj (.text) - 0000aa84 000001f3 ADC.obj (.text:retain) - 0000ac77 000001c5 measure.obj (.text:retain) - 0000ae3c 00000196 ADC.obj (.text) - 0000afd2 0000018a DAC.obj (.text) - 0000b15c 0000016c kanal.obj (.text) - 0000b2c8 0000015d DSP2833x_SysCtrl.obj (.text) - 0000b425 00000151 pulto.obj (.text:retain) - 0000b576 00000114 RS485.obj (.text:retain) - 0000b68a 0000010c DSP2833x_Xintf.obj (.text) - 0000b796 00000088 rts2800_fpu32.lib : fs_div.obj (.text) - 0000b81e 00000075 crc16.obj (.text) - 0000b893 00000075 ecan.obj (.text:retain) - 0000b908 0000005e DSP2833x_CpuTimers.obj (.text) - 0000b966 0000004f tools.obj (.text) - 0000b9b5 00000046 rts2800_fpu32.lib : boot.obj (.text) - 0000b9fb 00000039 spise2p.obj (.text:retain) - 0000ba34 00000037 filter_bat2.obj (.text) - 0000ba6b 0000002a rts2800_fpu32.lib : l_div.obj (.text) - 0000ba95 00000028 DSP2833x_PieCtrl.obj (.text) - 0000babd 00000001 --HOLE-- [fill = 0] - 0000babe 00000020 rts2800_fpu32.lib : sqrt.obj (.text) - 0000bade 0000001d pulto.obj (.text) - 0000bafb 0000001b rts2800_fpu32.lib : args_main.obj (.text) - 0000bb16 00000019 DSP2833x_Adc.obj (.text) - 0000bb2f 00000019 rts2800_fpu32.lib : exit.obj (.text) - 0000bb48 0000000e DSP2833x_SWPrioritizedPieVect.obj (.text) - 0000bb56 0000000b rts2800_fpu32.lib : u_div.obj (.text) - 0000bb61 00000009 : _lock.obj (.text) - 0000bb6a 00000005 cntrl_adr.obj (.text) - 0000bb6f 00000004 DSP2833x_usDelay.obj (.text) +.text 0 00008000 00003aa7 + 00008000 0000025a measure.obj (.text:_Current_count) + 0000825a 000001dd ADC.obj (.text:_adc_isr) + 00008437 000001a7 measure.obj (.text:_Temper_count) + 000085de 000001a3 peripher.obj (.text:_get_Buttons) + 00008781 0000019f main.obj (.text:_main) + 00008920 0000018d ADC.obj (.text:_setup_adc) + 00008aad 00000184 measure.obj (.text:_cpu_timer1_isr_SENS) + 00008c31 0000015c DAC.obj (.text:_Load_runner) + 00008d8d 00000152 RS485.obj (.text:_RS_RX_Handler) + 00008edf 00000143 pulto.obj (.text:_cpu_timer1_isr_PULT) + 00009022 00000129 measure.obj (.text:_Init_sensors) + 0000914b 00000122 spise2p.obj (.text:_SPISE2P_DRV_tick) + 0000926d 00000115 peripher.obj (.text:_get_Mode) + 00009382 0000010b kanal.obj (.text:_kanal_Send) + 0000948d 000000f9 measure.obj (.text:_Power_count) + 00009586 000000ec message.obj (.text:_Default_params) + 00009672 000000ce RS485.obj (.text:_setup_uart) + 00009740 000000b3 log_to_mem.obj (.text:_ump_log_read) + 000097f3 000000ae measure.obj (.text:_calc_sensor_koef) + 000098a1 000000ac ecan.obj (.text:_InitCan) + 0000994d 000000a8 ecan.obj (.text:_UMP_CAN_service) + 000099f5 00000001 bios.obj (.text:_init) + 000099f6 0000009d message.obj (.text:_ReceiveCommandModbus3) + 00009a93 0000009c peripher.obj (.text:_select_tpl_canal) + 00009b2f 00000097 bios.obj (.text:_upload) + 00009bc6 00000094 measure.obj (.text:_Init_packMask) + 00009c5a 00000090 RS485.obj (.text:_RS_FifoTx) + 00009cea 0000008c message.obj (.text:_receive_ump) + 00009d76 0000008a log_to_mem.obj (.text:_ump_capture) + 00009e00 00000088 rts2800_fpu32.lib : fs_div.obj (.text) + 00009e88 00000085 DSP2833x_SysCtrl.obj (.text:_InitPeripheralClocks) + 00009f0d 00000084 bios.obj (.text:_extendbios) + 00009f91 00000001 bios.obj (.text:_run) + 00009f92 00000083 shared_ump.obj (.text:_ump_rtu_encode) + 0000a015 00000082 DSP2833x_SysCtrl.obj (.text:_InitPll) + 0000a097 00000078 bios.obj (.text:_peek) + 0000a10f 00000072 ecan.obj (.text:_Handlai) + 0000a181 00000071 shared_ump.obj (.text:_ump_validate) + 0000a1f2 00000070 log_to_mem.obj (.text:_ump_log_write) + 0000a262 0000006e RS485.obj (.text:_RS_TX_Handler) + 0000a2d0 00000069 DAC.obj (.text:_Load_protection_prepare) + 0000a339 00000062 measure.obj (.text:_Init_sensors_more) + 0000a39b 00000059 DSP2833x_Xintf.obj (.text:_InitXintf16Gpio) + 0000a3f4 00000057 bios.obj (.text:_get_command) + 0000a44b 00000050 message.obj (.text:_ReceiveCommandModbus6) + 0000a49b 0000004e DAC.obj (.text:_anal_output) + 0000a4e9 0000004e DAC.obj (.text:_load_start) + 0000a537 0000004d shared_ump.obj (.text:_ump_prepare) + 0000a584 0000004c RS485.obj (.text:_RS_FifoStart) + 0000a5d0 0000004b RS485.obj (.text:_RS_Send) + 0000a61b 0000004a ecan.obj (.text:_CANa_handler) + 0000a665 00000049 bios.obj (.text:_load) + 0000a6ae 00000048 ecan.obj (.text:_CAN_send) + 0000a6f6 00000047 bios.obj (.text:_initload) + 0000a73d 00000046 RS485.obj (.text:_RSA_RX_Handler) + 0000a783 00000046 RS485.obj (.text:_RSA_TX_Handler) + 0000a7c9 00000046 RS485.obj (.text:_RSB_RX_Handler) + 0000a80f 00000046 RS485.obj (.text:_RSB_TX_Handler) + 0000a855 00000046 rts2800_fpu32.lib : boot.obj (.text) + 0000a89b 00000042 log_to_mem.obj (.text:_ump_log_can) + 0000a8dd 00000041 RS485.obj (.text:_RS_FifoAbort) + 0000a91e 00000041 spise2p.obj (.text:_Seeprom_read) + 0000a95f 00000041 spise2p.obj (.text:_Seeprom_write) + 0000a9a0 00000041 RS485.obj (.text:_setup_arr_cmd_length) + 0000a9e1 00000040 message.obj (.text:_Load_params) + 0000aa21 0000003e tools.obj (.text:_init_zone7) + 0000aa5f 0000003b DSP2833x_CpuTimers.obj (.text:_InitCpuTimers) + 0000aa9a 0000003b DAC.obj (.text:_Load_voltage_can) + 0000aad5 0000003b shared_ump.obj (.text:_ump_can_fragment) + 0000ab10 0000003a bios.obj (.text:_poke) + 0000ab4a 00000039 spise2p.obj (.text:_cpu_timer2_isr) + 0000ab83 00000038 message.obj (.text:_SendCommandModbus4) + 0000abbb 00000038 shared_ump.obj (.text:_ump_tms28335_fragment) + 0000abf3 00000037 RS485.obj (.text:_RS_BSend) + 0000ac2a 00000037 message.obj (.text:_ReceiveAnswerModbus4) + 0000ac61 00000033 bios.obj (.text:_Answer) + 0000ac94 00000033 message.obj (.text:_modbus_exception) + 0000acc7 00000033 log_to_mem.obj (.text:_ump_word) + 0000acfa 00000032 spise2p.obj (.text:_SPISE2P_DRV_init) + 0000ad2c 00000032 peripher.obj (.text:_unsetup_leds_line) + 0000ad5e 00000031 DAC.obj (.text:_dSEND) + 0000ad8f 0000002f RS485.obj (.text:_RS_FifoTick1ms) + 0000adbe 0000002e filter_bat2.obj (.text:_filterbat) + 0000adec 0000002e log_to_mem.obj (.text:_ump_log_io) + 0000ae1a 0000002d RS485.obj (.text:_RS_SetLineMode) + 0000ae47 0000002d main.obj (.text:_timer_Init) + 0000ae74 0000002c crc16.obj (.text:_get_crc_16b) + 0000aea0 0000002b ecan.obj (.text:_CANa_reset_err) + 0000aecb 0000002a rts2800_fpu32.lib : l_div.obj (.text) + 0000aef5 00000029 spise2p.obj (.text:_InitSeeprom) + 0000af1e 00000027 crc16.obj (.text:_get_crc16) + 0000af45 00000026 RS485.obj (.text:_RS_SetLineSpeed) + 0000af6b 00000024 message.obj (.text:_Save_params) + 0000af8f 00000024 DAC.obj (.text:_load_stop) + 0000afb3 00000024 peripher.obj (.text:_select_tpl_255) + 0000afd7 00000022 peripher.obj (.text:_setup_leds_line) + 0000aff9 00000021 DSP2833x_CpuTimers.obj (.text:_ConfigCpuTimer) + 0000b01a 00000020 DAC.obj (.text:_Setup_DAC_time) + 0000b03a 00000020 rts2800_fpu32.lib : sqrt.obj (.text) + 0000b05a 0000001f DSP2833x_PieCtrl.obj (.text:_InitPieCtrl) + 0000b079 0000001f measure.obj (.text:_reset_errs) + 0000b098 0000001e DAC.obj (.text:_Load_control_init) + 0000b0b6 0000001e kanal.obj (.text:_SENDBIT) + 0000b0d4 0000001d log_to_mem.obj (.text:_ump_log_init) + 0000b0f1 0000001d shared_ump.obj (.text:_ump_tms28335_prepare) + 0000b10e 0000001d pulto.obj (.text:_what_is) + 0000b12b 0000001c DAC.obj (.text:_Init_DAC) + 0000b147 0000001c measure.obj (.text:_im_calc) + 0000b163 0000001c shared_ump.obj (.text:_ump_crc) + 0000b17f 0000001c shared_ump.obj (.text:_ump_tms28335_capture) + 0000b19b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ADCINT_ISR) + 0000b1b6 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH1_ISR) + 0000b1d1 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH2_ISR) + 0000b1ec 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH3_ISR) + 0000b207 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH4_ISR) + 0000b222 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH5_ISR) + 0000b23d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DINTCH6_ISR) + 0000b258 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN0INTA_ISR) + 0000b273 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN0INTB_ISR) + 0000b28e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN1INTA_ISR) + 0000b2a9 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAN1INTB_ISR) + 0000b2c4 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP1_INT_ISR) + 0000b2df 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP2_INT_ISR) + 0000b2fa 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP3_INT_ISR) + 0000b315 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP4_INT_ISR) + 0000b330 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP5_INT_ISR) + 0000b34b 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ECAP6_INT_ISR) + 0000b366 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM1_INT_ISR) + 0000b381 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM1_TZINT_ISR) + 0000b39c 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM2_INT_ISR) + 0000b3b7 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM2_TZINT_ISR) + 0000b3d2 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM3_INT_ISR) + 0000b3ed 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM3_TZINT_ISR) + 0000b408 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM4_INT_ISR) + 0000b423 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM4_TZINT_ISR) + 0000b43e 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM5_INT_ISR) + 0000b459 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM5_TZINT_ISR) + 0000b474 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM6_INT_ISR) + 0000b48f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EPWM6_TZINT_ISR) + 0000b4aa 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EQEP1_INT_ISR) + 0000b4c5 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EQEP2_INT_ISR) + 0000b4e0 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_I2CINT1A_ISR) + 0000b4fb 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_I2CINT2A_ISR) + 0000b516 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_LUF_ISR) + 0000b531 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_LVF_ISR) + 0000b54c 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MRINTA_ISR) + 0000b567 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MRINTB_ISR) + 0000b582 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MXINTA_ISR) + 0000b59d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_MXINTB_ISR) + 0000b5b8 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTA_ISR) + 0000b5d3 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTB_ISR) + 0000b5ee 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCIRXINTC_ISR) + 0000b609 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTA_ISR) + 0000b624 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTB_ISR) + 0000b63f 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SCITXINTC_ISR) + 0000b65a 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SEQ1INT_ISR) + 0000b675 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SEQ2INT_ISR) + 0000b690 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SPIRXINTA_ISR) + 0000b6ab 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_SPITXINTA_ISR) + 0000b6c6 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_TINT0_ISR) + 0000b6e1 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_WAKEINT_ISR) + 0000b6fc 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT3_ISR) + 0000b717 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT4_ISR) + 0000b732 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT5_ISR) + 0000b74d 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT6_ISR) + 0000b768 0000001b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT7_ISR) + 0000b783 0000001b rts2800_fpu32.lib : args_main.obj (.text) + 0000b79e 0000001a RS485.obj (.text:_RS_SetBitMode) + 0000b7b8 0000001a RS485.obj (.text:_create_uart_vars) + 0000b7d2 00000019 DSP2833x_Adc.obj (.text:_InitAdc) + 0000b7eb 00000019 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT1_ISR) + 0000b804 00000019 DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_XINT2_ISR) + 0000b81d 00000019 rts2800_fpu32.lib : exit.obj (.text) + 0000b836 00000019 : prolog.obj (.text) + 0000b84f 00000018 kanal.obj (.text:_RESET) + 0000b867 00000018 log_to_mem.obj (.text:_ump_log_tick) + 0000b87f 00000017 log_to_mem.obj (.text:_clear_mem) + 0000b896 00000016 DSP2833x_SysCtrl.obj (.text:_ServiceDog) + 0000b8ac 00000014 bios.obj (.text:__getbyte) + 0000b8c0 00000014 measure.obj (.text:_er_anal) + 0000b8d4 00000014 log_to_mem.obj (.text:_ump_outputs) + 0000b8e8 00000013 RS485.obj (.text:_RS_FifoWait) + 0000b8fb 00000013 log_to_mem.obj (.text:_ump_inputs) + 0000b90e 00000012 crc16.obj (.text:_get_crc_16) + 0000b920 00000010 tools.obj (.text:_pause_us) + 0000b930 00000010 shared_ump.obj (.text:_read_word) + 0000b940 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_DATALOG_ISR) + 0000b94d 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT13_ISR) + 0000b95a 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT14_ISR) + 0000b967 0000000d DSP2833x_SWPrioritizedPieVect.obj (.text:_InitPieVectTable) + 0000b974 0000000d DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_RTOSINT_ISR) + 0000b981 0000000c rts2800_fpu32.lib : epilog.obj (.text) + 0000b98d 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_EMUINT_ISR) + 0000b998 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_ILLEGAL_ISR) + 0000b9a3 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_NMI_ISR) + 0000b9ae 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER10_ISR) + 0000b9b9 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER11_ISR) + 0000b9c4 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER12_ISR) + 0000b9cf 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER1_ISR) + 0000b9da 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER2_ISR) + 0000b9e5 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER3_ISR) + 0000b9f0 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER4_ISR) + 0000b9fb 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER5_ISR) + 0000ba06 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER6_ISR) + 0000ba11 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER7_ISR) + 0000ba1c 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER8_ISR) + 0000ba27 0000000b DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_USER9_ISR) + 0000ba32 0000000b log_to_mem.obj (.text:_ump_log_rs) + 0000ba3d 0000000b rts2800_fpu32.lib : u_div.obj (.text) + 0000ba48 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_INT_NOTUSED_ISR) + 0000ba52 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_PIE_RESERVED) + 0000ba5c 0000000a DSP2833x_SWPrioritizedDefaultIsr.obj (.text:_rsvd_ISR) + 0000ba66 00000009 DSP2833x_PieCtrl.obj (.text:_EnableInterrupts) + 0000ba6f 00000009 DSP2833x_SysCtrl.obj (.text:_InitSysCtrl) + 0000ba78 00000009 rts2800_fpu32.lib : _lock.obj (.text) + 0000ba81 00000008 DSP2833x_SysCtrl.obj (.text:_DisableDog) + 0000ba89 00000007 rts2800_fpu32.lib : memset.obj (.text) + 0000ba90 00000005 spise2p.obj (.text:_SPISE2P_DRV_csclr) + 0000ba95 00000005 spise2p.obj (.text:_SPISE2P_DRV_csset) + 0000ba9a 00000005 cntrl_adr.obj (.text:_set_cntrl_addr) + 0000ba9f 00000004 DSP2833x_usDelay.obj (.text) + 0000baa3 00000003 shared_ump.obj (.text:_write_word) + 0000baa6 00000001 bios.obj (.text:_tflash) ramfuncs 0 0000c000 00000000 UNINITIALIZED -.econst 0 0000c28c 00000125 - 0000c28c 00000100 DSP2833x_SWPrioritizedPieVect.obj (.econst:_PieVectTableInit) - 0000c38c 00000009 message.obj (.econst:_$P$T0$1) - 0000c395 00000001 --HOLE-- [fill = 0] - 0000c396 00000006 shared_ump.obj (.econst:_$P$T0$1) - 0000c39c 00000006 message.obj (.econst:_$P$T1$2) - 0000c3a2 00000006 shared_ump.obj (.econst:_$P$T1$2) - 0000c3a8 00000006 shared_ump.obj (.econst:_$P$T2$3) - 0000c3ae 00000003 cntrl_adr.obj (.econst) +.econst 0 0000c274 0000012b + 0000c274 00000100 DSP2833x_SWPrioritizedPieVect.obj (.econst:_PieVectTableInit) + 0000c374 0000000c shared_ump.obj (.econst:_firmware_identity_words) + 0000c380 00000009 message.obj (.econst:_$P$T0$1) + 0000c389 00000001 --HOLE-- [fill = 0] + 0000c38a 00000006 shared_ump.obj (.econst:_$P$T0$1) + 0000c390 00000006 message.obj (.econst:_$P$T1$2) + 0000c396 00000006 shared_ump.obj (.econst:_$P$T2$3) + 0000c39c 00000003 cntrl_adr.obj (.econst) -.switch 0 0000c3b2 00000048 - 0000c3b2 00000028 spise2p.obj (.switch:_SPISE2P_DRV_tick) - 0000c3da 00000020 log_to_mem.obj (.switch:_ump_log_read) +.switch 0 0000c3a0 00000048 + 0000c3a0 00000028 spise2p.obj (.switch:_SPISE2P_DRV_tick) + 0000c3c8 00000020 log_to_mem.obj (.switch:_ump_log_read) .stack 1 00000400 000003f0 UNINITIALIZED 00000400 000003f0 --HOLE-- -.ebss 1 0000d000 00000fdf UNINITIALIZED - 0000d000 00000704 RS485.obj (.ebss) - 0000d704 00000038 measure.obj (.ebss:_sens_count) +.ebss 1 0000d000 0000105e UNINITIALIZED + 0000d000 0000070a RS485.obj (.ebss) + 0000d70a 00000020 measure.obj (.ebss:_din_count) + 0000d72a 00000012 measure.obj (.ebss:_powK) 0000d73c 00000004 ADC.obj (.ebss:_adc_table_lem) 0000d740 000001b0 measure.obj (.ebss:_adc_filter) 0000d8f0 00000010 measure.obj (.ebss:_Maska) @@ -201,45 +382,44 @@ ramfuncs 0 0000c000 00000000 UNINITIALIZED 0000dac0 00000100 crc16.obj (.ebss:_crc_16_tab) 0000dbc0 00000081 message.obj (.ebss:_modbus) 0000dc41 00000001 bios.obj (.ebss) - 0000dc42 00000038 measure.obj (.ebss) + 0000dc42 00000038 measure.obj (.ebss:_sens_count) 0000dc7a 00000006 DSP2833x_SysCtrl.obj (.ebss) 0000dc80 00000081 message.obj (.ebss:_param) - 0000dd01 00000001 rts2800_fpu32.lib : errno.obj (.ebss) - 0000dd02 00000028 log_to_mem.obj (.ebss) - 0000dd2a 00000012 measure.obj (.ebss:_powK) - 0000dd3c 00000004 cntrl_adr.obj (.ebss) + 0000dd01 00000001 main.obj (.ebss) + 0000dd02 00000038 measure.obj (.ebss) + 0000dd3a 00000006 measure.obj (.ebss:_err_count) 0000dd40 0000007c ecan.obj (.ebss:_ump_can_reply) - 0000ddbc 00000004 rts2800_fpu32.lib : _lock.obj (.ebss) - 0000ddc0 00000048 measure.obj (.ebss:_zer_filter) - 0000de08 00000020 measure.obj (.ebss:_din_count) - 0000de28 00000018 DSP2833x_CpuTimers.obj (.ebss) - 0000de40 00000046 RS485.obj (.ebss:_RS_Len) - 0000de86 0000001c ADC.obj (.ebss:_ADC_table) - 0000dea2 0000001c ADC.obj (.ebss:_prev_ok) - 0000debe 00000002 main.obj (.ebss:_cancell$2) - 0000dec0 00000040 message.obj (.ebss:_def_cal) - 0000df00 0000001c spise2p.obj (.ebss) - 0000df1c 00000018 measure.obj (.ebss:_sens_pair) - 0000df34 0000000c ADC.obj (.ebss) - 0000df40 00000018 measure.obj (.ebss:_sens_type) - 0000df58 00000018 ecan.obj (.ebss) - 0000df70 00000010 peripher.obj (.ebss) - 0000df80 0000000e DAC.obj (.ebss) - 0000df8e 0000000c measure.obj (.ebss:_lev_quadr) - 0000df9a 0000000a pulto.obj (.ebss) - 0000dfa4 00000008 measure.obj (.ebss:_ext_diag) - 0000dfac 00000008 measure.obj (.ebss:_ext_temp) - 0000dfb4 00000008 measure.obj (.ebss:_zer_count) - 0000dfbc 00000004 rts2800_fpu32.lib : exit.obj (.ebss) - 0000dfc0 00000006 measure.obj (.ebss:_err_count) - 0000dfc6 00000006 measure.obj (.ebss:_lev_count) - 0000dfcc 00000005 kanal.obj (.ebss:_readr) - 0000dfd1 00000003 log_to_mem.obj (.ebss:_ump_can_data) - 0000dfd4 00000003 main.obj (.ebss) - 0000dfd7 00000002 main.obj (.ebss:_cancount$1) - 0000dfd9 00000002 ADC.obj (.ebss:_cwnt_ok$4) - 0000dfdb 00000002 measure.obj (.ebss:_low_count) - 0000dfdd 00000002 log_to_mem.obj (.ebss:_ump_pm67_voltage) + 0000ddbc 00000004 cntrl_adr.obj (.ebss) + 0000ddc0 0000007c message.obj (.ebss:_words$3) + 0000de3c 00000004 rts2800_fpu32.lib : _lock.obj (.ebss) + 0000de40 00000048 measure.obj (.ebss:_zer_filter) + 0000de88 00000020 log_to_mem.obj (.ebss) + 0000dea8 00000018 DAC.obj (.ebss) + 0000dec0 00000046 RS485.obj (.ebss:_RS_Len) + 0000df06 0000001c ADC.obj (.ebss:_ADC_table) + 0000df22 0000001c ADC.obj (.ebss:_prev_ok) + 0000df3e 00000002 main.obj (.ebss:_cancell$2) + 0000df40 00000040 message.obj (.ebss:_def_cal) + 0000df80 0000001c spise2p.obj (.ebss) + 0000df9c 00000018 DSP2833x_CpuTimers.obj (.ebss) + 0000dfb4 0000000c ADC.obj (.ebss) + 0000dfc0 00000018 measure.obj (.ebss:_sens_pair) + 0000dfd8 00000018 measure.obj (.ebss:_sens_type) + 0000dff0 00000010 peripher.obj (.ebss) + 0000e000 00000018 ecan.obj (.ebss) + 0000e018 0000000c measure.obj (.ebss:_lev_quadr) + 0000e024 0000000a pulto.obj (.ebss) + 0000e02e 00000008 measure.obj (.ebss:_ext_diag) + 0000e036 00000008 measure.obj (.ebss:_ext_temp) + 0000e03e 00000002 main.obj (.ebss:_cancount$1) + 0000e040 00000008 measure.obj (.ebss:_zer_count) + 0000e048 00000006 measure.obj (.ebss:_lev_count) + 0000e04e 00000005 kanal.obj (.ebss:_readr) + 0000e053 00000001 rts2800_fpu32.lib : errno.obj (.ebss) + 0000e054 00000004 : exit.obj (.ebss) + 0000e058 00000002 ADC.obj (.ebss:_cwnt_ok$4) + 0000e05a 00000002 measure.obj (.ebss:_low_count) + 0000e05c 00000002 log_to_mem.obj (.ebss:_ump_pm67_voltage) .logg 1 00200000 0000fa00 UNINITIALIZED 00200000 0000fa00 log_to_mem.obj (.logg) @@ -458,16 +638,16 @@ MODULE SUMMARY ------ ---- ---------------- ------------------ K:\git_project\Balsam_167_periph\Debug\Source\External\v120\DSP2833x_common\source\ DSP2833x_SWPrioritizedDefaultIsr.obj 1809 0 0 - DSP2833x_SysCtrl.obj 349 0 6 - DSP2833x_SWPrioritizedPieVect.obj 14 256 0 - DSP2833x_Xintf.obj 268 0 0 - DSP2833x_CpuTimers.obj 94 0 24 + DSP2833x_SysCtrl.obj 302 0 6 + DSP2833x_SWPrioritizedPieVect.obj 13 256 0 + DSP2833x_CpuTimers.obj 92 0 24 + DSP2833x_Xintf.obj 89 0 0 DSP2833x_PieCtrl.obj 40 0 0 DSP2833x_Adc.obj 25 0 0 DSP2833x_ADC_cal.obj 7 0 0 DSP2833x_usDelay.obj 4 0 0 +--+--------------------------------------+-------+------------------+--------------------+ - Total: 2610 256 30 + Total: 2381 256 30 K:\git_project\Balsam_167_periph\Debug\Source\External\v120\DSP2833x_headers\source\ DSP2833x_GlobalVariableDefs.obj 0 0 2679 @@ -475,26 +655,26 @@ MODULE SUMMARY Total: 0 0 2679 K:\git_project\Balsam_167_periph\Debug\Source\Internal\ - log_to_mem.obj 895 52 64045 - measure.obj 2731 87 1212 - RS485.obj 1233 8 1866 - message.obj 805 82 322 - peripher.obj 963 32 16 - ADC.obj 905 13 74 - ecan.obj 622 28 148 - shared_ump.obj 777 18 0 - spise2p.obj 660 71 28 - bios.obj 703 4 1 - crc16.obj 117 259 256 - main.obj 589 8 7 - DAC.obj 394 16 14 - kanal.obj 364 27 21 - pulto.obj 366 17 10 - tools.obj 79 0 0 - filter_bat2.obj 55 0 0 + log_to_mem.obj 718 52 64034 + measure.obj 2458 87 1212 + RS485.obj 1615 8 1872 + message.obj 875 82 446 + peripher.obj 972 32 16 + ADC.obj 874 13 74 + DAC.obj 843 0 24 + ecan.obj 643 28 148 + bios.obj 766 4 1 + spise2p.obj 578 71 28 + crc16.obj 101 259 256 + shared_ump.obj 540 24 0 + main.obj 460 0 5 + pulto.obj 352 17 10 + kanal.obj 321 27 21 + tools.obj 78 0 0 + filter_bat2.obj 46 0 0 cntrl_adr.obj 5 11 4 +--+--------------------------------------+-------+------------------+--------------------+ - Total: 12263 733 68024 + Total: 12245 715 68151 K:/git_project/Balsam_167_periph/Libraries/rts2800_fpu32.lib fs_div.obj 136 0 0 @@ -503,15 +683,18 @@ MODULE SUMMARY exit.obj 25 10 4 sqrt.obj 32 0 0 args_main.obj 27 0 0 + prolog.obj 25 0 0 _lock.obj 9 10 4 + epilog.obj 12 0 0 u_div.obj 11 0 0 + memset.obj 7 0 0 errno.obj 0 4 1 +--+--------------------------------------+-------+------------------+--------------------+ - Total: 352 24 9 + Total: 396 24 9 Stack: 0 0 1008 +--+--------------------------------------+-------+------------------+--------------------+ - Grand Total: 15225 1013 71750 + Grand Total: 15022 995 71877 GLOBAL DATA SYMBOLS: SORTED BY DATA PAGE @@ -606,17 +789,18 @@ address data page name 00007900 1e4 (00007900) _I2caRegs -0000c28c 30a (0000c280) _PieVectTableInit +0000c274 309 (0000c240) _PieVectTableInit -0000c3ae 30e (0000c380) _ADDR_ANSWER -0000c3af 30e (0000c380) _ADDR_TERMINAL -0000c3b0 30e (0000c380) _CNTRL_ADDR_UNIVERSAL +0000c39c 30e (0000c380) _ADDR_ANSWER +0000c39d 30e (0000c380) _ADDR_TERMINAL +0000c39e 30e (0000c380) _CNTRL_ADDR_UNIVERSAL 0000d040 341 (0000d040) _rs_a 0000d3c0 34f (0000d3c0) _rs_b -0000d704 35c (0000d700) _sens_count +0000d70a 35c (0000d700) _din_count +0000d72a 35c (0000d700) _powK 0000d73c 35c (0000d700) _adc_table_lem 0000d740 35d (0000d740) _adc_filter @@ -632,121 +816,116 @@ address data page name 0000dbc0 36f (0000dbc0) _modbus 0000dc41 371 (0000dc40) _flag_DEBUG -0000dc42 371 (0000dc40) _CanPowse -0000dc43 371 (0000dc40) _CanGO -0000dc44 371 (0000dc40) _READY -0000dc45 371 (0000dc40) _TPL_CANS -0000dc46 371 (0000dc40) _tpl_cans -0000dc47 371 (0000dc40) _cal_addr -0000dc48 371 (0000dc40) _pow_addr -0000dc49 371 (0000dc40) _period_ready -0000dc4a 371 (0000dc40) _period_blink -0000dc4b 371 (0000dc40) _chk -0000dc4c 371 (0000dc40) _sig -0000dc4d 371 (0000dc40) _time_1_5sec -0000dc4e 371 (0000dc40) _time_5msec -0000dc4f 371 (0000dc40) _time_3sec -0000dc50 371 (0000dc40) _time_5sec -0000dc51 371 (0000dc40) _Caliber_time -0000dc52 371 (0000dc40) _Curr_Edge -0000dc53 371 (0000dc40) _okay -0000dc5e 371 (0000dc40) _K100 -0000dc60 371 (0000dc40) _K_50 -0000dc62 371 (0000dc40) _K_T1 -0000dc64 371 (0000dc40) _K_T2 -0000dc68 371 (0000dc40) _def_FILTERBAT +0000dc42 371 (0000dc40) _sens_count 0000dc7a 371 (0000dc40) _SYSCLKOUT 0000dc7c 371 (0000dc40) _LSPCLK 0000dc7e 371 (0000dc40) _HSPCLK 0000dc80 372 (0000dc80) _param -0000dd01 374 (0000dd00) _errno -0000dd02 374 (0000dd00) _no_write -0000dd03 374 (0000dd00) _never_write -0000dd04 374 (0000dd00) _flog -0000dd18 374 (0000dd00) _ump_dac_ramp -0000dd19 374 (0000dd00) _ump_dac_duration -0000dd1a 374 (0000dd00) _ump_dac_go10 -0000dd1b 374 (0000dd00) _ump_dac_stop10 -0000dd1c 374 (0000dd00) _ump_dac_position -0000dd22 374 (0000dd00) _Log -0000dd2a 374 (0000dd00) _powK -0000dd3c 374 (0000dd00) _ADDR_FOR_ALL -0000dd3d 374 (0000dd00) _CNTRL_ADDR -0000dd3e 374 (0000dd00) _cntr_addr_c -0000dd3f 374 (0000dd00) _cntr_addr_c_all +0000dd02 374 (0000dd00) _CanPowse +0000dd03 374 (0000dd00) _CanGO +0000dd04 374 (0000dd00) _READY +0000dd05 374 (0000dd00) _TPL_CANS +0000dd06 374 (0000dd00) _tpl_cans +0000dd07 374 (0000dd00) _cal_addr +0000dd08 374 (0000dd00) _pow_addr +0000dd09 374 (0000dd00) _period_ready +0000dd0a 374 (0000dd00) _period_blink +0000dd0b 374 (0000dd00) _chk +0000dd0c 374 (0000dd00) _sig +0000dd0d 374 (0000dd00) _time_1_5sec +0000dd0e 374 (0000dd00) _time_5msec +0000dd0f 374 (0000dd00) _time_3sec +0000dd10 374 (0000dd00) _time_5sec +0000dd11 374 (0000dd00) _Caliber_time +0000dd12 374 (0000dd00) _Curr_Edge +0000dd13 374 (0000dd00) _okay +0000dd1e 374 (0000dd00) _K100 +0000dd20 374 (0000dd00) _K_50 +0000dd22 374 (0000dd00) _K_T1 +0000dd24 374 (0000dd00) _K_T2 +0000dd28 374 (0000dd00) _def_FILTERBAT +0000dd3a 374 (0000dd00) _err_count -0000ddbc 376 (0000dd80) __unlock -0000ddbe 376 (0000dd80) __lock +0000ddbc 376 (0000dd80) _ADDR_FOR_ALL +0000ddbd 376 (0000dd80) _CNTRL_ADDR +0000ddbe 376 (0000dd80) _cntr_addr_c +0000ddbf 376 (0000dd80) _cntr_addr_c_all -0000ddc0 377 (0000ddc0) _zer_filter +0000de3c 378 (0000de00) __unlock +0000de3e 378 (0000de00) __lock -0000de08 378 (0000de00) _din_count -0000de28 378 (0000de00) _CpuTimer0 -0000de30 378 (0000de00) _CpuTimer1 -0000de38 378 (0000de00) _CpuTimer2 +0000de40 379 (0000de40) _zer_filter -0000de40 379 (0000de40) _RS_Len +0000de88 37a (0000de80) _no_write +0000de89 37a (0000de80) _never_write +0000de8a 37a (0000de80) _flog +0000dea0 37a (0000de80) _Log +0000dea8 37a (0000de80) _period_dac +0000dea9 37a (0000de80) _time_dac +0000deb8 37a (0000de80) _WAKEpowse +0000deba 37a (0000de80) _IMPowse -0000de86 37a (0000de80) _ADC_table -0000dea2 37a (0000de80) _prev_ok +0000dec0 37b (0000dec0) _RS_Len -0000dec0 37b (0000dec0) _def_cal +0000df06 37c (0000df00) _ADC_table +0000df22 37c (0000df00) _prev_ok -0000df00 37c (0000df00) _ccc -0000df1c 37c (0000df00) _sens_pair -0000df34 37c (0000df00) _COUNT_ONE_CANAL -0000df35 37c (0000df00) _COUNT_DISCHARGE -0000df36 37c (0000df00) _COUNT_TRANSICIA -0000df37 37c (0000df00) _FILTER_CLIP -0000df3c 37c (0000df00) _WAKE -0000df3e 37c (0000df00) _WAKE_TIME +0000df40 37d (0000df40) _def_cal -0000df40 37d (0000df40) _sens_type -0000df58 37d (0000df40) _CanTimeOutErrorTR -0000df59 37d (0000df40) _wait -0000df62 37d (0000df40) _ErrorCount -0000df64 37d (0000df40) _MessageReceivedCount -0000df66 37d (0000df40) _MessageTransivedCount -0000df68 37d (0000df40) _TestMbox1 -0000df6a 37d (0000df40) _TestMbox2 -0000df6c 37d (0000df40) _TestMbox3 -0000df70 37d (0000df40) _Mode -0000df71 37d (0000df40) _Desk -0000df72 37d (0000df40) _TermoAD -0000df73 37d (0000df40) _TermoRS -0000df74 37d (0000df40) _TermoSW -0000df75 37d (0000df40) _Kurrent -0000df76 37d (0000df40) _Kalibro -0000df77 37d (0000df40) _Owen -0000df78 37d (0000df40) _INcount0 -0000df79 37d (0000df40) _INcount1 -0000df7a 37d (0000df40) _MUX_GPIO32 -0000df7b 37d (0000df40) _MUX_GPIO48 -0000df7c 37d (0000df40) _DIR_GPIO32 -0000df7d 37d (0000df40) _DIR_GPIO48 -0000df7e 37d (0000df40) _DigErr +0000df80 37e (0000df80) _ccc +0000df9c 37e (0000df80) _CpuTimer0 +0000dfa4 37e (0000df80) _CpuTimer1 +0000dfac 37e (0000df80) _CpuTimer2 +0000dfb4 37e (0000df80) _COUNT_ONE_CANAL +0000dfb5 37e (0000df80) _COUNT_DISCHARGE +0000dfb6 37e (0000df80) _COUNT_TRANSICIA +0000dfb7 37e (0000df80) _FILTER_CLIP +0000dfbc 37e (0000df80) _WAKE +0000dfbe 37e (0000df80) _WAKE_TIME -0000df80 37e (0000df80) _period_dac -0000df81 37e (0000df80) _time_dac -0000df86 37e (0000df80) _WAKEpowse -0000df88 37e (0000df80) _IMPowse -0000df8e 37e (0000df80) _lev_quadr -0000df9a 37e (0000df80) _isNumb -0000df9b 37e (0000df80) _quaLamp -0000dfa0 37e (0000df80) _isMask -0000dfa2 37e (0000df80) _Lonely -0000dfa4 37e (0000df80) _ext_diag -0000dfac 37e (0000df80) _ext_temp -0000dfb4 37e (0000df80) _zer_count -0000dfbc 37e (0000df80) __cleanup_ptr -0000dfbe 37e (0000df80) __dtors_ptr +0000dfc0 37f (0000dfc0) _sens_pair +0000dfd8 37f (0000dfc0) _sens_type +0000dff0 37f (0000dfc0) _Mode +0000dff1 37f (0000dfc0) _Desk +0000dff2 37f (0000dfc0) _TermoAD +0000dff3 37f (0000dfc0) _TermoRS +0000dff4 37f (0000dfc0) _TermoSW +0000dff5 37f (0000dfc0) _Kurrent +0000dff6 37f (0000dfc0) _Kalibro +0000dff7 37f (0000dfc0) _Owen +0000dff8 37f (0000dfc0) _INcount0 +0000dff9 37f (0000dfc0) _INcount1 +0000dffa 37f (0000dfc0) _MUX_GPIO32 +0000dffb 37f (0000dfc0) _MUX_GPIO48 +0000dffc 37f (0000dfc0) _DIR_GPIO32 +0000dffd 37f (0000dfc0) _DIR_GPIO48 +0000dffe 37f (0000dfc0) _DigErr -0000dfc0 37f (0000dfc0) _err_count -0000dfc6 37f (0000dfc0) _lev_count -0000dfcc 37f (0000dfc0) _readr -0000dfdb 37f (0000dfc0) _low_count +0000e000 380 (0000e000) _CanTimeOutErrorTR +0000e001 380 (0000e000) _wait +0000e00a 380 (0000e000) _ErrorCount +0000e00c 380 (0000e000) _MessageReceivedCount +0000e00e 380 (0000e000) _MessageTransivedCount +0000e010 380 (0000e000) _TestMbox1 +0000e012 380 (0000e000) _TestMbox2 +0000e014 380 (0000e000) _TestMbox3 +0000e018 380 (0000e000) _lev_quadr +0000e024 380 (0000e000) _isNumb +0000e025 380 (0000e000) _quaLamp +0000e02a 380 (0000e000) _isMask +0000e02c 380 (0000e000) _Lonely +0000e02e 380 (0000e000) _ext_diag +0000e036 380 (0000e000) _ext_temp + +0000e040 381 (0000e040) _zer_count +0000e048 381 (0000e040) _lev_count +0000e04e 381 (0000e040) _readr +0000e053 381 (0000e040) _errno +0000e054 381 (0000e040) __cleanup_ptr +0000e056 381 (0000e040) __dtors_ptr +0000e05a 381 (0000e040) _low_count 00200000 8000 (00200000) _logs_block @@ -757,851 +936,831 @@ address data page name GLOBAL SYMBOLS: SORTED ALPHABETICALLY BY Name -page address name ----- ------- ---- -0 00008000 .text -0 0000bb2f C$$EXIT -0 0000b796 FS$$DIV -0 0000ba6b L$$DIV -0 0000ba7a L$$MOD -0 0000bb56 U$$DIV -0 0000bb5b U$$MOD -0 0000ba88 UL$$DIV -0 0000ba8f UL$$MOD -0 00008fdc _ADCINT_ISR -0 00380080 _ADC_cal -1 0000de86 _ADC_table -0 0000c3ae _ADDR_ANSWER -1 0000dd3c _ADDR_FOR_ALL -0 0000c3af _ADDR_TERMINAL -1 00000b00 _AdcMirror -1 00007100 _AdcRegs -0 0000b01b _Anal_output -0 0000a1b2 _Answer -0 0000aa38 _CAN_send -0 0000b8be _CANa_handler -0 0000b893 _CANa_reset_err -1 0000dd3d _CNTRL_ADDR -0 0000c3b0 _CNTRL_ADDR_UNIVERSAL -1 0000df35 _COUNT_DISCHARGE -1 0000df34 _COUNT_ONE_CANAL -1 0000df36 _COUNT_TRANSICIA -1 0000dc51 _Caliber_time -1 0000dc43 _CanGO -1 0000dc42 _CanPowse -1 0000df58 _CanTimeOutErrorTR -0 0000b947 _ConfigCpuTimer -1 0000de28 _CpuTimer0 -1 00000c00 _CpuTimer0Regs -1 0000de30 _CpuTimer1 -1 00000c08 _CpuTimer1Regs -1 0000de38 _CpuTimer2 -1 00000c10 _CpuTimer2Regs -1 0033fff8 _CsmPwl -1 00000ae0 _CsmRegs -0 0000b3f6 _CsmUnlock -1 0000dc52 _Curr_Edge -0 00008656 _Current_count -0 00008fcf _DATALOG_ISR -0 0000b168 _DCLK -0 00008fb4 _DINTCH1_ISR -0 00008f99 _DINTCH2_ISR -0 00008f7e _DINTCH3_ISR -0 00008f63 _DINTCH4_ISR -0 00008f48 _DINTCH5_ISR -0 00008f2d _DINTCH6_ISR -1 0000df7c _DIR_GPIO32 -1 0000df7d _DIR_GPIO48 -0 0000b15c _DOUT -0 0000bb6f _DSP28x_usDelay -0 00009cba _Default_params -1 0000df71 _Desk -1 00000880 _DevEmuRegs -1 0000df7e _DigErr -0 0000b2de _DisableDog -1 00001000 _DmaRegs -0 00008f12 _ECAN0INTA_ISR -0 00008ef7 _ECAN0INTB_ISR -0 00008edc _ECAN1INTA_ISR -0 00008ec1 _ECAN1INTB_ISR -0 00008ea6 _ECAP1_INT_ISR -0 00008e8b _ECAP2_INT_ISR -0 00008e70 _ECAP3_INT_ISR -0 00008e55 _ECAP4_INT_ISR -0 00008e3a _ECAP5_INT_ISR -0 00008e1f _ECAP6_INT_ISR -1 00006040 _ECanaLAMRegs -1 000060c0 _ECanaMOTORegs -1 00006080 _ECanaMOTSRegs -1 00006100 _ECanaMboxes -1 00006000 _ECanaRegs -1 00006240 _ECanbLAMRegs -1 000062c0 _ECanbMOTORegs -1 00006280 _ECanbMOTSRegs -1 00006300 _ECanbMboxes -1 00006200 _ECanbRegs -1 00006a00 _ECap1Regs -1 00006a20 _ECap2Regs -1 00006a40 _ECap3Regs -1 00006a60 _ECap4Regs -1 00006a80 _ECap5Regs -1 00006aa0 _ECap6Regs -0 00008e14 _EMUINT_ISR -0 00008df9 _EPWM1_INT_ISR -0 00008dde _EPWM1_TZINT_ISR -0 00008dc3 _EPWM2_INT_ISR -0 00008da8 _EPWM2_TZINT_ISR -0 00008d8d _EPWM3_INT_ISR -0 00008d72 _EPWM3_TZINT_ISR -0 00008d57 _EPWM4_INT_ISR -0 00008d3c _EPWM4_TZINT_ISR -0 00008d21 _EPWM5_INT_ISR -0 00008d06 _EPWM5_TZINT_ISR -0 00008ceb _EPWM6_INT_ISR -0 00008cd0 _EPWM6_TZINT_ISR -1 00006800 _EPwm1Regs -1 00006840 _EPwm2Regs -1 00006880 _EPwm3Regs -1 000068c0 _EPwm4Regs -1 00006900 _EPwm5Regs -1 00006940 _EPwm6Regs -0 00008cb5 _EQEP1_INT_ISR -0 00008c9a _EQEP2_INT_ISR -1 00006b00 _EQep1Regs -1 00006b40 _EQep2Regs -0 0000bab4 _EnableInterrupts -1 0000df62 _ErrorCount -1 0000df37 _FILTER_CLIP -1 00000a80 _FlashRegs -1 00006f80 _GpioCtrlRegs -1 00006fc0 _GpioDataRegs -1 00006fe0 _GpioIntRegs -1 0000dc7e _HSPCLK -0 0000a9d9 _Handlai -0 00008c7f _I2CINT1A_ISR -0 00008c64 _I2CINT2A_ISR -1 00007900 _I2caRegs -0 00008c59 _ILLEGAL_ISR -1 0000df88 _IMPowse -0 00008c4c _INT13_ISR -0 00008c3f _INT14_ISR -0 00008c35 _INT_NOTUSED_ISR -1 0000df78 _INcount0 -1 0000df79 _INcount1 -0 0000bb16 _InitAdc -0 0000a920 _InitCan -0 0000b908 _InitCpuTimers -0 0000b368 _InitPeripheralClocks -0 0000ba95 _InitPieCtrl -0 0000bb48 _InitPieVectTable -0 0000b2e6 _InitPll -0 0000a615 _InitSeeprom -0 0000b3ed _InitSysCtrl -0 0000b733 _InitXintf -0 0000b68a _InitXintf16Gpio -0 0000b6e3 _InitXintf32Gpio -0 0000b064 _Init_DAC -0 000085ae _Init_packMask -0 00008438 _Init_sensors -0 000083d8 _Init_sensors_more -1 0000dc5e _K100 -1 0000dc60 _K_50 -1 0000dc62 _K_T1 -1 0000dc64 _K_T2 -1 0000df76 _Kalibro -1 0000df75 _Kurrent -1 0000dc7c _LSPCLK -0 00008c1a _LUF_ISR -0 00008bff _LVF_ISR -0 00009dd6 _Load_params -0 0000b080 _Load_runner -1 0000dd22 _Log -1 0000dfa2 _Lonely -0 00008be4 _MRINTA_ISR -0 00008bc9 _MRINTB_ISR -1 0000df7a _MUX_GPIO32 -1 0000df7b _MUX_GPIO48 -0 00008bae _MXINTA_ISR -0 00008b93 _MXINTB_ISR -1 0000d8f0 _Maska -1 00005000 _McbspaRegs -1 00005040 _McbspbRegs -1 0000df64 _MessageReceivedCount -1 0000df66 _MessageTransivedCount -1 0000df70 _Mode -0 00008b88 _NMI_ISR -1 0000df77 _Owen -0 00008b7e _PIE_RESERVED -1 00380090 _PartIdRegs -1 00000ce0 _PieCtrlRegs -1 00000d00 _PieVectTable -0 0000c28c _PieVectTableInit -0 000082ee _Power_count -1 0000dc44 _READY -0 0000b186 _RESET -0 0000b645 _RSA_RX_Handler -0 0000b600 _RSA_TX_Handler -0 0000b5bb _RSB_RX_Handler -0 0000b576 _RSB_TX_Handler -0 00009746 _RS_BSend -1 0000de40 _RS_Len -0 000095fc _RS_RX_Handler -0 000095a4 _RS_Send -0 0000944f _RS_SetBitMode -0 000093bb _RS_SetLineMode -0 0000942f _RS_SetLineSpeed -0 0000952b _RS_TX_Handler -0 00008b71 _RTOSINT_ISR -0 0000c000 _RamfuncsLoadEnd -0 0000c000 _RamfuncsLoadStart -0 0000c000 _RamfuncsRunStart -0 00009c90 _ReceiveAnswerModbus4 -0 00009c05 _ReceiveCommandModbus3 -0 00009bc7 _ReceiveCommandModbus6 -0 00008b56 _SCIRXINTA_ISR -0 00008b3b _SCIRXINTB_ISR -0 00008b20 _SCIRXINTC_ISR -0 00008b05 _SCITXINTA_ISR -0 00008aea _SCITXINTB_ISR -0 00008acf _SCITXINTC_ISR -0 0000b174 _SENDBIT -0 00008ab4 _SEQ1INT_ISR -0 00008a99 _SEQ2INT_ISR -0 00008a7e _SPIRXINTA_ISR -0 0000a3f2 _SPISE2P_DRV_csclr -0 0000a3f7 _SPISE2P_DRV_csset -0 0000a3fc _SPISE2P_DRV_init -0 0000a42e _SPISE2P_DRV_tick -0 00008a63 _SPITXINTA_ISR -1 0000dc7a _SYSCLKOUT -0 00009b1e _Save_params -1 00007050 _SciaRegs -1 00007750 _ScibRegs -1 00007770 _ScicRegs -0 0000a5d2 _Seeprom_read -0 0000a58f _Seeprom_write -0 00009af6 _SendCommandModbus4 -0 0000b2c8 _ServiceDog -0 0000b011 _Setup_DAC_time -1 00007040 _SpiaRegs -1 00007010 _SysCtrlRegs -0 00008a48 _TINT0_ISR -1 0000dc45 _TPL_CANS -0 00008111 _Temper_count -1 0000df72 _TermoAD -1 0000df73 _TermoRS -1 0000df74 _TermoSW -1 0000df68 _TestMbox1 -1 0000df6a _TestMbox2 -1 0000df6c _TestMbox3 -0 0000a88b _UMP_CAN_service -0 00008a3d _USER10_ISR -0 00008a32 _USER11_ISR -0 00008a27 _USER12_ISR -0 00008a1c _USER1_ISR -0 00008a11 _USER2_ISR -0 00008a06 _USER3_ISR -0 000089fb _USER4_ISR -0 000089f0 _USER5_ISR -0 000089e5 _USER6_ISR -0 000089da _USER7_ISR -0 000089cf _USER8_ISR -0 000089c4 _USER9_ISR -1 0000df3c _WAKE -0 000089a9 _WAKEINT_ISR -1 0000df3e _WAKE_TIME -1 0000df86 _WAKEpowse -0 00008990 _XINT1_ISR -0 00008977 _XINT2_ISR -0 0000895c _XINT3_ISR -0 00008941 _XINT4_ISR -0 00008926 _XINT5_ISR -0 0000890b _XINT6_ISR -0 000088f0 _XINT7_ISR -1 00007070 _XIntruptRegs -1 00000b20 _XintfRegs -1 000007f0 __STACK_END -abs 000003f0 __STACK_SIZE -abs ffffffff ___TI_pprof_out_hndl -abs ffffffff ___TI_prof_data_size -abs ffffffff ___TI_prof_data_start -abs ffffffff ___binit__ -abs ffffffff ___c_args__ -0 0000c000 ___cinit__ -0 0000bb73 ___etext__ -abs ffffffff ___pinit__ -0 00008000 ___text__ -0 0000bafb __args_main -1 0000dfbc __cleanup_ptr -1 0000dfbe __dtors_ptr -1 0000ddbe __lock -0 0000bb69 __nop -0 0000bb65 __register_lock -0 0000bb61 __register_unlock -1 00000400 __stack -1 0000ddbc __unlock -0 0000bb2f _abort -1 0000d740 _adc_filter -0 0000aa84 _adc_isr -1 0000d73c _adc_table_lem -0 0000b9b5 _c_int00 -1 0000dc47 _cal_addr -0 00008053 _calc_sensor_koef -1 0000df00 _ccc -1 0000dc4b _chk -0 00009ae1 _clear_mem -0 00009526 _clear_timer_rs_live -1 0000dd3e _cntr_addr_c -1 0000dd3f _cntr_addr_c_all -0 0000b425 _cpu_timer1_isr_PULT -0 0000ac77 _cpu_timer1_isr_SENS -0 0000b9fb _cpu_timer2_isr -1 0000dac0 _crc_16_tab -0 0000951a _create_uart_vars -0 0000afd7 _dOUT -0 0000afe3 _dSEND -1 0000dc68 _def_FILTERBAT -1 0000dec0 _def_cal -1 0000dab0 _digits -1 0000de08 _din_count -0 0000803e _er_anal -1 0000dfc0 _err_count -1 0000dd01 _errno -0 0000bb31 _exit -1 0000dfa4 _ext_diag -1 0000dfac _ext_temp -0 0000a373 _extendbios -0 0000ba34 _filterbat -1 0000dc41 _flag_DEBUG -1 0000dd04 _flog -0 0000921c _get_Buttons -0 000090ff _get_Mode -0 0000a31b _get_command -0 0000b859 _get_crc16 -0 0000b848 _get_crc_16 -0 0000b81e _get_crc_16b -0 00008022 _im_calc -0 0000a31a _init -0 0000b977 _init_zone7 -0 0000a2d7 _initload -1 0000dfa0 _isMask -1 0000df9a _isNumb -0 0000b199 _kanal_Send -1 0000dfc6 _lev_count -1 0000df8e _lev_quadr -0 0000a28f _load -1 00200000 _logs_block -1 0000dfdb _low_count -0 0000a66b _main -1 0000dbc0 _modbus -1 0000dd03 _never_write -1 0000dd02 _no_write -1 0000dc53 _okay -1 0000d900 _out_filter -1 0000dc80 _param -0 0000b966 _pause_us -0 0000a216 _peek -1 0000dc4a _period_blink -1 0000df80 _period_dac -1 0000dc49 _period_ready -0 0000a1da _poke -1 0000dd2a _powK -1 0000dc48 _pow_addr -1 0000dea2 _prev_ok -1 0000df9b _quaLamp -0 0000a1af _read_memory -1 0000dfcc _readr -0 00008000 _reset_errs -1 0000d040 _rs_a -1 0000d3c0 _rs_b -0 000088e6 _rsvd_ISR -0 0000a1ae _run -0 000090db _select_tpl_255 -0 0000904b _select_tpl_canal -1 0000d704 _sens_count -1 0000df1c _sens_pair -1 0000df40 _sens_type -0 0000bb6a _set_cntrl_addr -0 0000ae3c _setup_adc -0 000093e8 _setup_arr_cmd_length -0 00009029 _setup_leds_line -0 00009469 _setup_uart -1 0000dc4c _sig -0 0000a3eb _spiSe2pFree -0 0000a3e7 _spiSe2pRead -0 0000a3e3 _spiSe2pWrite -0 0000babe _sqrt -0 000093ba _test_rs_live -0 0000a1ad _tflash -1 0000dc4d _time_1_5sec -1 0000dc4f _time_3sec -1 0000dc4e _time_5msec -1 0000dc50 _time_5sec -1 0000df81 _time_dac -0 0000a63e _timer_Init -1 0000dc46 _tpl_cans -0 00009ff0 _ump_can_fragment -0 0000a110 _ump_can_id -0 0000a0c8 _ump_can_request -0 00009ec3 _ump_crc -1 0000dd19 _ump_dac_duration -1 0000dd1a _ump_dac_go10 -1 0000dd1c _ump_dac_position -1 0000dd18 _ump_dac_ramp -1 0000dd1b _ump_dac_stop10 -0 00009a92 _ump_log_can -0 00009a5e _ump_log_init -0 00009a30 _ump_log_io -0 00009982 _ump_log_read -0 00009944 _ump_log_rs -0 00009920 _ump_log_tick -0 000098a5 _ump_log_write -0 00009e70 _ump_prepare -0 0000a083 _ump_rtu -0 00009ede _ump_rtu_encode -0 00009f69 _ump_rtu_response -0 0000a063 _ump_tms28335_capture -0 0000a028 _ump_tms28335_fragment -0 00009fd3 _ump_tms28335_prepare -0 00009fb2 _ump_tms28335_rtu -0 00009e1e _ump_validate -0 00008ff7 _unsetup_leds_line -0 0000a128 _upload -1 0000df59 _wait -0 0000afd2 _wast -0 0000bade _what_is -0 0000a125 _write_memory -0 0000a124 _xflash -1 0000dfb4 _zer_count -1 0000ddc0 _zer_filter -abs ffffffff binit -0 0000c000 cinit -0 0000bb73 etext -abs ffffffff pinit +page address name +---- ------- ---- +0 00008000 .text +0 0000b81d C$$EXIT +0 00009e00 FS$$DIV +0 0000aecb L$$DIV +0 0000aeda L$$MOD +0 0000ba3d U$$DIV +0 0000ba42 U$$MOD +0 0000aee8 UL$$DIV +0 0000aeef UL$$MOD +0 0000b19b _ADCINT_ISR +0 00380080 _ADC_cal +1 0000df06 _ADC_table +0 0000c39c _ADDR_ANSWER +1 0000ddbc _ADDR_FOR_ALL +0 0000c39d _ADDR_TERMINAL +1 00000b00 _AdcMirror +1 00007100 _AdcRegs +0 0000ac61 _Answer +0 0000a6ae _CAN_send +0 0000a61b _CANa_handler +0 0000aea0 _CANa_reset_err +1 0000ddbd _CNTRL_ADDR +0 0000c39e _CNTRL_ADDR_UNIVERSAL +1 0000dfb5 _COUNT_DISCHARGE +1 0000dfb4 _COUNT_ONE_CANAL +1 0000dfb6 _COUNT_TRANSICIA +1 0000dd11 _Caliber_time +1 0000dd03 _CanGO +1 0000dd02 _CanPowse +1 0000e000 _CanTimeOutErrorTR +0 0000aff9 _ConfigCpuTimer +1 0000df9c _CpuTimer0 +1 00000c00 _CpuTimer0Regs +1 0000dfa4 _CpuTimer1 +1 00000c08 _CpuTimer1Regs +1 0000dfac _CpuTimer2 +1 00000c10 _CpuTimer2Regs +1 0033fff8 _CsmPwl +1 00000ae0 _CsmRegs +1 0000dd12 _Curr_Edge +0 00008000 _Current_count +0 0000b940 _DATALOG_ISR +0 0000b1b6 _DINTCH1_ISR +0 0000b1d1 _DINTCH2_ISR +0 0000b1ec _DINTCH3_ISR +0 0000b207 _DINTCH4_ISR +0 0000b222 _DINTCH5_ISR +0 0000b23d _DINTCH6_ISR +1 0000dffc _DIR_GPIO32 +1 0000dffd _DIR_GPIO48 +0 0000ba9f _DSP28x_usDelay +0 00009586 _Default_params +1 0000dff1 _Desk +1 00000880 _DevEmuRegs +1 0000dffe _DigErr +0 0000ba81 _DisableDog +1 00001000 _DmaRegs +0 0000b258 _ECAN0INTA_ISR +0 0000b273 _ECAN0INTB_ISR +0 0000b28e _ECAN1INTA_ISR +0 0000b2a9 _ECAN1INTB_ISR +0 0000b2c4 _ECAP1_INT_ISR +0 0000b2df _ECAP2_INT_ISR +0 0000b2fa _ECAP3_INT_ISR +0 0000b315 _ECAP4_INT_ISR +0 0000b330 _ECAP5_INT_ISR +0 0000b34b _ECAP6_INT_ISR +1 00006040 _ECanaLAMRegs +1 000060c0 _ECanaMOTORegs +1 00006080 _ECanaMOTSRegs +1 00006100 _ECanaMboxes +1 00006000 _ECanaRegs +1 00006240 _ECanbLAMRegs +1 000062c0 _ECanbMOTORegs +1 00006280 _ECanbMOTSRegs +1 00006300 _ECanbMboxes +1 00006200 _ECanbRegs +1 00006a00 _ECap1Regs +1 00006a20 _ECap2Regs +1 00006a40 _ECap3Regs +1 00006a60 _ECap4Regs +1 00006a80 _ECap5Regs +1 00006aa0 _ECap6Regs +abs 00007efc _EEPROM_FIRMWARE_LIMIT_BYTES +abs 00007ffe _EEPROM_PARAMS_END_BYTE +abs 00007efc _EEPROM_PARAMS_START_BYTE +abs 00003f7e _EEPROM_PARAMS_START_WORD +abs 00008000 _EEPROM_TOTAL_BYTES +0 0000b98d _EMUINT_ISR +0 0000b366 _EPWM1_INT_ISR +0 0000b381 _EPWM1_TZINT_ISR +0 0000b39c _EPWM2_INT_ISR +0 0000b3b7 _EPWM2_TZINT_ISR +0 0000b3d2 _EPWM3_INT_ISR +0 0000b3ed _EPWM3_TZINT_ISR +0 0000b408 _EPWM4_INT_ISR +0 0000b423 _EPWM4_TZINT_ISR +0 0000b43e _EPWM5_INT_ISR +0 0000b459 _EPWM5_TZINT_ISR +0 0000b474 _EPWM6_INT_ISR +0 0000b48f _EPWM6_TZINT_ISR +1 00006800 _EPwm1Regs +1 00006840 _EPwm2Regs +1 00006880 _EPwm3Regs +1 000068c0 _EPwm4Regs +1 00006900 _EPwm5Regs +1 00006940 _EPwm6Regs +0 0000b4aa _EQEP1_INT_ISR +0 0000b4c5 _EQEP2_INT_ISR +1 00006b00 _EQep1Regs +1 00006b40 _EQep2Regs +0 0000ba66 _EnableInterrupts +1 0000e00a _ErrorCount +1 0000dfb7 _FILTER_CLIP +1 00000a80 _FlashRegs +1 00006f80 _GpioCtrlRegs +1 00006fc0 _GpioDataRegs +1 00006fe0 _GpioIntRegs +1 0000dc7e _HSPCLK +0 0000a10f _Handlai +0 0000b4e0 _I2CINT1A_ISR +0 0000b4fb _I2CINT2A_ISR +1 00007900 _I2caRegs +0 0000b998 _ILLEGAL_ISR +1 0000deba _IMPowse +0 0000b94d _INT13_ISR +0 0000b95a _INT14_ISR +0 0000ba48 _INT_NOTUSED_ISR +1 0000dff8 _INcount0 +1 0000dff9 _INcount1 +0 0000b7d2 _InitAdc +0 000098a1 _InitCan +0 0000aa5f _InitCpuTimers +0 00009e88 _InitPeripheralClocks +0 0000b05a _InitPieCtrl +0 0000b967 _InitPieVectTable +0 0000a015 _InitPll +0 0000aef5 _InitSeeprom +0 0000ba6f _InitSysCtrl +0 0000a39b _InitXintf16Gpio +0 0000b12b _Init_DAC +0 00009bc6 _Init_packMask +0 00009022 _Init_sensors +0 0000a339 _Init_sensors_more +1 0000dd1e _K100 +1 0000dd20 _K_50 +1 0000dd22 _K_T1 +1 0000dd24 _K_T2 +1 0000dff6 _Kalibro +1 0000dff5 _Kurrent +1 0000dc7c _LSPCLK +0 0000b516 _LUF_ISR +0 0000b531 _LVF_ISR +0 0000b098 _Load_control_init +0 0000a9e1 _Load_params +0 0000a2d0 _Load_protection_prepare +0 00008c31 _Load_runner +0 0000aa9a _Load_voltage_can +1 0000dea0 _Log +1 0000e02c _Lonely +0 0000b54c _MRINTA_ISR +0 0000b567 _MRINTB_ISR +1 0000dffa _MUX_GPIO32 +1 0000dffb _MUX_GPIO48 +0 0000b582 _MXINTA_ISR +0 0000b59d _MXINTB_ISR +1 0000d8f0 _Maska +1 00005000 _McbspaRegs +1 00005040 _McbspbRegs +1 0000e00c _MessageReceivedCount +1 0000e00e _MessageTransivedCount +1 0000dff0 _Mode +0 0000b9a3 _NMI_ISR +1 0000dff7 _Owen +0 0000ba52 _PIE_RESERVED +1 00380090 _PartIdRegs +1 00000ce0 _PieCtrlRegs +1 00000d00 _PieVectTable +0 0000c274 _PieVectTableInit +0 0000948d _Power_count +1 0000dd04 _READY +0 0000b84f _RESET +0 0000a73d _RSA_RX_Handler +0 0000a783 _RSA_TX_Handler +0 0000a7c9 _RSB_RX_Handler +0 0000a80f _RSB_TX_Handler +0 0000abf3 _RS_BSend +0 0000ad8f _RS_FifoTick1ms +0 0000b8e8 _RS_FifoWait +1 0000dec0 _RS_Len +0 00008d8d _RS_RX_Handler +0 0000a5d0 _RS_Send +0 0000b79e _RS_SetBitMode +0 0000ae1a _RS_SetLineMode +0 0000af45 _RS_SetLineSpeed +0 0000a262 _RS_TX_Handler +0 0000b974 _RTOSINT_ISR +0 0000c000 _RamfuncsLoadEnd +0 0000c000 _RamfuncsLoadStart +0 0000c000 _RamfuncsRunStart +0 0000ac2a _ReceiveAnswerModbus4 +0 000099f6 _ReceiveCommandModbus3 +0 0000a44b _ReceiveCommandModbus6 +0 0000b5b8 _SCIRXINTA_ISR +0 0000b5d3 _SCIRXINTB_ISR +0 0000b5ee _SCIRXINTC_ISR +0 0000b609 _SCITXINTA_ISR +0 0000b624 _SCITXINTB_ISR +0 0000b63f _SCITXINTC_ISR +0 0000b0b6 _SENDBIT +0 0000b65a _SEQ1INT_ISR +0 0000b675 _SEQ2INT_ISR +0 0000b690 _SPIRXINTA_ISR +0 0000ba90 _SPISE2P_DRV_csclr +0 0000ba95 _SPISE2P_DRV_csset +0 0000acfa _SPISE2P_DRV_init +0 0000914b _SPISE2P_DRV_tick +0 0000b6ab _SPITXINTA_ISR +1 0000dc7a _SYSCLKOUT +0 0000af6b _Save_params +1 00007050 _SciaRegs +1 00007750 _ScibRegs +1 00007770 _ScicRegs +0 0000a91e _Seeprom_read +0 0000a95f _Seeprom_write +0 0000ab83 _SendCommandModbus4 +0 0000b896 _ServiceDog +0 0000b01a _Setup_DAC_time +1 00007040 _SpiaRegs +1 00007010 _SysCtrlRegs +0 0000b6c6 _TINT0_ISR +1 0000dd05 _TPL_CANS +0 00008437 _Temper_count +1 0000dff2 _TermoAD +1 0000dff3 _TermoRS +1 0000dff4 _TermoSW +1 0000e010 _TestMbox1 +1 0000e012 _TestMbox2 +1 0000e014 _TestMbox3 +0 0000994d _UMP_CAN_service +0 0000b9ae _USER10_ISR +0 0000b9b9 _USER11_ISR +0 0000b9c4 _USER12_ISR +0 0000b9cf _USER1_ISR +0 0000b9da _USER2_ISR +0 0000b9e5 _USER3_ISR +0 0000b9f0 _USER4_ISR +0 0000b9fb _USER5_ISR +0 0000ba06 _USER6_ISR +0 0000ba11 _USER7_ISR +0 0000ba1c _USER8_ISR +0 0000ba27 _USER9_ISR +1 0000dfbc _WAKE +0 0000b6e1 _WAKEINT_ISR +1 0000dfbe _WAKE_TIME +1 0000deb8 _WAKEpowse +0 0000b7eb _XINT1_ISR +0 0000b804 _XINT2_ISR +0 0000b6fc _XINT3_ISR +0 0000b717 _XINT4_ISR +0 0000b732 _XINT5_ISR +0 0000b74d _XINT6_ISR +0 0000b768 _XINT7_ISR +1 00007070 _XIntruptRegs +1 00000b20 _XintfRegs +1 000007f0 __STACK_END +abs 000003f0 __STACK_SIZE +abs ffffffff ___TI_pprof_out_hndl +abs ffffffff ___TI_prof_data_size +abs ffffffff ___TI_prof_data_start +abs ffffffff ___binit__ +abs ffffffff ___c_args__ +0 0000c000 ___cinit__ +0 0000baa7 ___etext__ +abs ffffffff ___pinit__ +0 00008000 ___text__ +0 0000b783 __args_main +1 0000e054 __cleanup_ptr +1 0000e056 __dtors_ptr +1 0000de3e __lock +0 0000ba80 __nop +0 0000ba7c __register_lock +0 0000ba78 __register_unlock +1 00000400 __stack +1 0000de3c __unlock +0 0000b81d _abort +1 0000d740 _adc_filter +0 0000825a _adc_isr +1 0000d73c _adc_table_lem +0 0000a855 _c_int00 +1 0000dd07 _cal_addr +0 000097f3 _calc_sensor_koef +1 0000df80 _ccc +1 0000dd0b _chk +0 0000b87f _clear_mem +1 0000ddbe _cntr_addr_c +1 0000ddbf _cntr_addr_c_all +0 00008edf _cpu_timer1_isr_PULT +0 00008aad _cpu_timer1_isr_SENS +0 0000ab4a _cpu_timer2_isr +1 0000dac0 _crc_16_tab +0 0000b7b8 _create_uart_vars +0 0000ad5e _dSEND +1 0000dd28 _def_FILTERBAT +1 0000df40 _def_cal +1 0000dab0 _digits +1 0000d70a _din_count +0 0000b981 _epilog_c28x_1 +0 0000b985 _epilog_c28x_2 +0 0000b8c0 _er_anal +1 0000dd3a _err_count +1 0000e053 _errno +0 0000b81f _exit +1 0000e02e _ext_diag +1 0000e036 _ext_temp +0 00009f0d _extendbios +0 0000adbe _filterbat +1 0000dc41 _flag_DEBUG +1 0000de8a _flog +0 000085de _get_Buttons +0 0000926d _get_Mode +0 0000a3f4 _get_command +0 0000af1e _get_crc16 +0 0000b90e _get_crc_16 +0 0000ae74 _get_crc_16b +0 0000b147 _im_calc +0 000099f5 _init +0 0000aa21 _init_zone7 +0 0000a6f6 _initload +1 0000e02a _isMask +1 0000e024 _isNumb +0 00009382 _kanal_Send +1 0000e048 _lev_count +1 0000e018 _lev_quadr +0 0000a665 _load +1 00200000 _logs_block +1 0000e05a _low_count +0 00008781 _main +0 0000ba89 _memset +1 0000dbc0 _modbus +1 0000de89 _never_write +1 0000de88 _no_write +1 0000dd13 _okay +1 0000d900 _out_filter +1 0000dc80 _param +0 0000b920 _pause_us +0 0000a097 _peek +1 0000dd0a _period_blink +1 0000dea8 _period_dac +1 0000dd09 _period_ready +0 0000ab10 _poke +1 0000d72a _powK +1 0000dd08 _pow_addr +1 0000df22 _prev_ok +0 0000b836 _prolog_c28x_1 +0 0000b83a _prolog_c28x_2 +0 0000b842 _prolog_c28x_3 +1 0000e025 _quaLamp +1 0000e04e _readr +0 0000b079 _reset_errs +1 0000d040 _rs_a +1 0000d3c0 _rs_b +0 0000ba5c _rsvd_ISR +0 00009f91 _run +0 0000afb3 _select_tpl_255 +0 00009a93 _select_tpl_canal +1 0000dc42 _sens_count +1 0000dfc0 _sens_pair +1 0000dfd8 _sens_type +0 0000ba9a _set_cntrl_addr +0 00008920 _setup_adc +0 0000a9a0 _setup_arr_cmd_length +0 0000afd7 _setup_leds_line +0 00009672 _setup_uart +1 0000dd0c _sig +0 0000b03a _sqrt +0 0000baa6 _tflash +1 0000dd0d _time_1_5sec +1 0000dd0f _time_3sec +1 0000dd0e _time_5msec +1 0000dd10 _time_5sec +1 0000dea9 _time_dac +0 0000ae47 _timer_Init +1 0000dd06 _tpl_cans +0 0000aad5 _ump_can_fragment +0 0000b163 _ump_crc +0 0000a89b _ump_log_can +0 0000b0d4 _ump_log_init +0 0000adec _ump_log_io +0 00009740 _ump_log_read +0 0000ba32 _ump_log_rs +0 0000b867 _ump_log_tick +0 0000a1f2 _ump_log_write +0 0000a537 _ump_prepare +0 00009f92 _ump_rtu_encode +0 0000b17f _ump_tms28335_capture +0 0000abbb _ump_tms28335_fragment +0 0000b0f1 _ump_tms28335_prepare +0 0000a181 _ump_validate +0 0000ad2c _unsetup_leds_line +0 00009b2f _upload +1 0000e001 _wait +0 0000b10e _what_is +1 0000e040 _zer_count +1 0000de40 _zer_filter +abs ffffffff binit +0 0000c000 cinit +0 0000baa7 etext +abs ffffffff pinit GLOBAL SYMBOLS: SORTED BY Symbol Address -page address name ----- ------- ---- -0 00008000 .text -0 00008000 ___text__ -0 00008000 _reset_errs -0 00008022 _im_calc -0 0000803e _er_anal -0 00008053 _calc_sensor_koef -0 00008111 _Temper_count -0 000082ee _Power_count -0 000083d8 _Init_sensors_more -0 00008438 _Init_sensors -0 000085ae _Init_packMask -0 00008656 _Current_count -0 000088e6 _rsvd_ISR -0 000088f0 _XINT7_ISR -0 0000890b _XINT6_ISR -0 00008926 _XINT5_ISR -0 00008941 _XINT4_ISR -0 0000895c _XINT3_ISR -0 00008977 _XINT2_ISR -0 00008990 _XINT1_ISR -0 000089a9 _WAKEINT_ISR -0 000089c4 _USER9_ISR -0 000089cf _USER8_ISR -0 000089da _USER7_ISR -0 000089e5 _USER6_ISR -0 000089f0 _USER5_ISR -0 000089fb _USER4_ISR -0 00008a06 _USER3_ISR -0 00008a11 _USER2_ISR -0 00008a1c _USER1_ISR -0 00008a27 _USER12_ISR -0 00008a32 _USER11_ISR -0 00008a3d _USER10_ISR -0 00008a48 _TINT0_ISR -0 00008a63 _SPITXINTA_ISR -0 00008a7e _SPIRXINTA_ISR -0 00008a99 _SEQ2INT_ISR -0 00008ab4 _SEQ1INT_ISR -0 00008acf _SCITXINTC_ISR -0 00008aea _SCITXINTB_ISR -0 00008b05 _SCITXINTA_ISR -0 00008b20 _SCIRXINTC_ISR -0 00008b3b _SCIRXINTB_ISR -0 00008b56 _SCIRXINTA_ISR -0 00008b71 _RTOSINT_ISR -0 00008b7e _PIE_RESERVED -0 00008b88 _NMI_ISR -0 00008b93 _MXINTB_ISR -0 00008bae _MXINTA_ISR -0 00008bc9 _MRINTB_ISR -0 00008be4 _MRINTA_ISR -0 00008bff _LVF_ISR -0 00008c1a _LUF_ISR -0 00008c35 _INT_NOTUSED_ISR -0 00008c3f _INT14_ISR -0 00008c4c _INT13_ISR -0 00008c59 _ILLEGAL_ISR -0 00008c64 _I2CINT2A_ISR -0 00008c7f _I2CINT1A_ISR -0 00008c9a _EQEP2_INT_ISR -0 00008cb5 _EQEP1_INT_ISR -0 00008cd0 _EPWM6_TZINT_ISR -0 00008ceb _EPWM6_INT_ISR -0 00008d06 _EPWM5_TZINT_ISR -0 00008d21 _EPWM5_INT_ISR -0 00008d3c _EPWM4_TZINT_ISR -0 00008d57 _EPWM4_INT_ISR -0 00008d72 _EPWM3_TZINT_ISR -0 00008d8d _EPWM3_INT_ISR -0 00008da8 _EPWM2_TZINT_ISR -0 00008dc3 _EPWM2_INT_ISR -0 00008dde _EPWM1_TZINT_ISR -0 00008df9 _EPWM1_INT_ISR -0 00008e14 _EMUINT_ISR -0 00008e1f _ECAP6_INT_ISR -0 00008e3a _ECAP5_INT_ISR -0 00008e55 _ECAP4_INT_ISR -0 00008e70 _ECAP3_INT_ISR -0 00008e8b _ECAP2_INT_ISR -0 00008ea6 _ECAP1_INT_ISR -0 00008ec1 _ECAN1INTB_ISR -0 00008edc _ECAN1INTA_ISR -0 00008ef7 _ECAN0INTB_ISR -0 00008f12 _ECAN0INTA_ISR -0 00008f2d _DINTCH6_ISR -0 00008f48 _DINTCH5_ISR -0 00008f63 _DINTCH4_ISR -0 00008f7e _DINTCH3_ISR -0 00008f99 _DINTCH2_ISR -0 00008fb4 _DINTCH1_ISR -0 00008fcf _DATALOG_ISR -0 00008fdc _ADCINT_ISR -0 00008ff7 _unsetup_leds_line -0 00009029 _setup_leds_line -0 0000904b _select_tpl_canal -0 000090db _select_tpl_255 -0 000090ff _get_Mode -0 0000921c _get_Buttons -0 000093ba _test_rs_live -0 000093bb _RS_SetLineMode -0 000093e8 _setup_arr_cmd_length -0 0000942f _RS_SetLineSpeed -0 0000944f _RS_SetBitMode -0 00009469 _setup_uart -0 0000951a _create_uart_vars -0 00009526 _clear_timer_rs_live -0 0000952b _RS_TX_Handler -0 000095a4 _RS_Send -0 000095fc _RS_RX_Handler -0 00009746 _RS_BSend -0 000098a5 _ump_log_write -0 00009920 _ump_log_tick -0 00009944 _ump_log_rs -0 00009982 _ump_log_read -0 00009a30 _ump_log_io -0 00009a5e _ump_log_init -0 00009a92 _ump_log_can -0 00009ae1 _clear_mem -0 00009af6 _SendCommandModbus4 -0 00009b1e _Save_params -0 00009bc7 _ReceiveCommandModbus6 -0 00009c05 _ReceiveCommandModbus3 -0 00009c90 _ReceiveAnswerModbus4 -0 00009cba _Default_params -0 00009dd6 _Load_params -0 00009e1e _ump_validate -0 00009e70 _ump_prepare -0 00009ec3 _ump_crc -0 00009ede _ump_rtu_encode -0 00009f69 _ump_rtu_response -0 00009fb2 _ump_tms28335_rtu -0 00009fd3 _ump_tms28335_prepare -0 00009ff0 _ump_can_fragment -0 0000a028 _ump_tms28335_fragment -0 0000a063 _ump_tms28335_capture -0 0000a083 _ump_rtu -0 0000a0c8 _ump_can_request -0 0000a110 _ump_can_id -0 0000a124 _xflash -0 0000a125 _write_memory -0 0000a128 _upload -0 0000a1ad _tflash -0 0000a1ae _run -0 0000a1af _read_memory -0 0000a1b2 _Answer -0 0000a1da _poke -0 0000a216 _peek -0 0000a28f _load -0 0000a2d7 _initload -0 0000a31a _init -0 0000a31b _get_command -0 0000a373 _extendbios -0 0000a3e3 _spiSe2pWrite -0 0000a3e7 _spiSe2pRead -0 0000a3eb _spiSe2pFree -0 0000a3f2 _SPISE2P_DRV_csclr -0 0000a3f7 _SPISE2P_DRV_csset -0 0000a3fc _SPISE2P_DRV_init -0 0000a42e _SPISE2P_DRV_tick -0 0000a58f _Seeprom_write -0 0000a5d2 _Seeprom_read -0 0000a615 _InitSeeprom -0 0000a63e _timer_Init -0 0000a66b _main -0 0000a88b _UMP_CAN_service -0 0000a920 _InitCan -0 0000a9d9 _Handlai -0 0000aa38 _CAN_send -0 0000aa84 _adc_isr -0 0000ac77 _cpu_timer1_isr_SENS -0 0000ae3c _setup_adc -0 0000afd2 _wast -0 0000afd7 _dOUT -0 0000afe3 _dSEND -0 0000b011 _Setup_DAC_time -0 0000b01b _Anal_output -0 0000b064 _Init_DAC -0 0000b080 _Load_runner -0 0000b15c _DOUT -0 0000b168 _DCLK -0 0000b174 _SENDBIT -0 0000b186 _RESET -0 0000b199 _kanal_Send -0 0000b2c8 _ServiceDog -0 0000b2de _DisableDog -0 0000b2e6 _InitPll -0 0000b368 _InitPeripheralClocks -0 0000b3ed _InitSysCtrl -0 0000b3f6 _CsmUnlock -0 0000b425 _cpu_timer1_isr_PULT -0 0000b576 _RSB_TX_Handler -0 0000b5bb _RSB_RX_Handler -0 0000b600 _RSA_TX_Handler -0 0000b645 _RSA_RX_Handler -0 0000b68a _InitXintf16Gpio -0 0000b6e3 _InitXintf32Gpio -0 0000b733 _InitXintf -0 0000b796 FS$$DIV -0 0000b81e _get_crc_16b -0 0000b848 _get_crc_16 -0 0000b859 _get_crc16 -0 0000b893 _CANa_reset_err -0 0000b8be _CANa_handler -0 0000b908 _InitCpuTimers -0 0000b947 _ConfigCpuTimer -0 0000b966 _pause_us -0 0000b977 _init_zone7 -0 0000b9b5 _c_int00 -0 0000b9fb _cpu_timer2_isr -0 0000ba34 _filterbat -0 0000ba6b L$$DIV -0 0000ba7a L$$MOD -0 0000ba88 UL$$DIV -0 0000ba8f UL$$MOD -0 0000ba95 _InitPieCtrl -0 0000bab4 _EnableInterrupts -0 0000babe _sqrt -0 0000bade _what_is -0 0000bafb __args_main -0 0000bb16 _InitAdc -0 0000bb2f C$$EXIT -0 0000bb2f _abort -0 0000bb31 _exit -0 0000bb48 _InitPieVectTable -0 0000bb56 U$$DIV -0 0000bb5b U$$MOD -0 0000bb61 __register_unlock -0 0000bb65 __register_lock -0 0000bb69 __nop -0 0000bb6a _set_cntrl_addr -0 0000bb6f _DSP28x_usDelay -0 0000bb73 ___etext__ -0 0000bb73 etext -0 0000c000 _RamfuncsLoadEnd -0 0000c000 _RamfuncsLoadStart -0 0000c000 _RamfuncsRunStart -0 0000c000 ___cinit__ -0 0000c000 cinit -0 0000c28c _PieVectTableInit -0 0000c3ae _ADDR_ANSWER -0 0000c3af _ADDR_TERMINAL -0 0000c3b0 _CNTRL_ADDR_UNIVERSAL -0 00380080 _ADC_cal -1 00000400 __stack -1 000007f0 __STACK_END -1 00000880 _DevEmuRegs -1 00000a80 _FlashRegs -1 00000ae0 _CsmRegs -1 00000b00 _AdcMirror -1 00000b20 _XintfRegs -1 00000c00 _CpuTimer0Regs -1 00000c08 _CpuTimer1Regs -1 00000c10 _CpuTimer2Regs -1 00000ce0 _PieCtrlRegs -1 00000d00 _PieVectTable -1 00001000 _DmaRegs -1 00005000 _McbspaRegs -1 00005040 _McbspbRegs -1 00006000 _ECanaRegs -1 00006040 _ECanaLAMRegs -1 00006080 _ECanaMOTSRegs -1 000060c0 _ECanaMOTORegs -1 00006100 _ECanaMboxes -1 00006200 _ECanbRegs -1 00006240 _ECanbLAMRegs -1 00006280 _ECanbMOTSRegs -1 000062c0 _ECanbMOTORegs -1 00006300 _ECanbMboxes -1 00006800 _EPwm1Regs -1 00006840 _EPwm2Regs -1 00006880 _EPwm3Regs -1 000068c0 _EPwm4Regs -1 00006900 _EPwm5Regs -1 00006940 _EPwm6Regs -1 00006a00 _ECap1Regs -1 00006a20 _ECap2Regs -1 00006a40 _ECap3Regs -1 00006a60 _ECap4Regs -1 00006a80 _ECap5Regs -1 00006aa0 _ECap6Regs -1 00006b00 _EQep1Regs -1 00006b40 _EQep2Regs -1 00006f80 _GpioCtrlRegs -1 00006fc0 _GpioDataRegs -1 00006fe0 _GpioIntRegs -1 00007010 _SysCtrlRegs -1 00007040 _SpiaRegs -1 00007050 _SciaRegs -1 00007070 _XIntruptRegs -1 00007100 _AdcRegs -1 00007750 _ScibRegs -1 00007770 _ScicRegs -1 00007900 _I2caRegs -1 0000d040 _rs_a -1 0000d3c0 _rs_b -1 0000d704 _sens_count -1 0000d73c _adc_table_lem -1 0000d740 _adc_filter -1 0000d8f0 _Maska -1 0000d900 _out_filter -1 0000dab0 _digits -1 0000dac0 _crc_16_tab -1 0000dbc0 _modbus -1 0000dc41 _flag_DEBUG -1 0000dc42 _CanPowse -1 0000dc43 _CanGO -1 0000dc44 _READY -1 0000dc45 _TPL_CANS -1 0000dc46 _tpl_cans -1 0000dc47 _cal_addr -1 0000dc48 _pow_addr -1 0000dc49 _period_ready -1 0000dc4a _period_blink -1 0000dc4b _chk -1 0000dc4c _sig -1 0000dc4d _time_1_5sec -1 0000dc4e _time_5msec -1 0000dc4f _time_3sec -1 0000dc50 _time_5sec -1 0000dc51 _Caliber_time -1 0000dc52 _Curr_Edge -1 0000dc53 _okay -1 0000dc5e _K100 -1 0000dc60 _K_50 -1 0000dc62 _K_T1 -1 0000dc64 _K_T2 -1 0000dc68 _def_FILTERBAT -1 0000dc7a _SYSCLKOUT -1 0000dc7c _LSPCLK -1 0000dc7e _HSPCLK -1 0000dc80 _param -1 0000dd01 _errno -1 0000dd02 _no_write -1 0000dd03 _never_write -1 0000dd04 _flog -1 0000dd18 _ump_dac_ramp -1 0000dd19 _ump_dac_duration -1 0000dd1a _ump_dac_go10 -1 0000dd1b _ump_dac_stop10 -1 0000dd1c _ump_dac_position -1 0000dd22 _Log -1 0000dd2a _powK -1 0000dd3c _ADDR_FOR_ALL -1 0000dd3d _CNTRL_ADDR -1 0000dd3e _cntr_addr_c -1 0000dd3f _cntr_addr_c_all -1 0000ddbc __unlock -1 0000ddbe __lock -1 0000ddc0 _zer_filter -1 0000de08 _din_count -1 0000de28 _CpuTimer0 -1 0000de30 _CpuTimer1 -1 0000de38 _CpuTimer2 -1 0000de40 _RS_Len -1 0000de86 _ADC_table -1 0000dea2 _prev_ok -1 0000dec0 _def_cal -1 0000df00 _ccc -1 0000df1c _sens_pair -1 0000df34 _COUNT_ONE_CANAL -1 0000df35 _COUNT_DISCHARGE -1 0000df36 _COUNT_TRANSICIA -1 0000df37 _FILTER_CLIP -1 0000df3c _WAKE -1 0000df3e _WAKE_TIME -1 0000df40 _sens_type -1 0000df58 _CanTimeOutErrorTR -1 0000df59 _wait -1 0000df62 _ErrorCount -1 0000df64 _MessageReceivedCount -1 0000df66 _MessageTransivedCount -1 0000df68 _TestMbox1 -1 0000df6a _TestMbox2 -1 0000df6c _TestMbox3 -1 0000df70 _Mode -1 0000df71 _Desk -1 0000df72 _TermoAD -1 0000df73 _TermoRS -1 0000df74 _TermoSW -1 0000df75 _Kurrent -1 0000df76 _Kalibro -1 0000df77 _Owen -1 0000df78 _INcount0 -1 0000df79 _INcount1 -1 0000df7a _MUX_GPIO32 -1 0000df7b _MUX_GPIO48 -1 0000df7c _DIR_GPIO32 -1 0000df7d _DIR_GPIO48 -1 0000df7e _DigErr -1 0000df80 _period_dac -1 0000df81 _time_dac -1 0000df86 _WAKEpowse -1 0000df88 _IMPowse -1 0000df8e _lev_quadr -1 0000df9a _isNumb -1 0000df9b _quaLamp -1 0000dfa0 _isMask -1 0000dfa2 _Lonely -1 0000dfa4 _ext_diag -1 0000dfac _ext_temp -1 0000dfb4 _zer_count -1 0000dfbc __cleanup_ptr -1 0000dfbe __dtors_ptr -1 0000dfc0 _err_count -1 0000dfc6 _lev_count -1 0000dfcc _readr -1 0000dfdb _low_count -1 00200000 _logs_block -1 0033fff8 _CsmPwl -1 00380090 _PartIdRegs -abs 000003f0 __STACK_SIZE -abs ffffffff ___TI_pprof_out_hndl -abs ffffffff ___TI_prof_data_size -abs ffffffff ___TI_prof_data_start -abs ffffffff ___binit__ -abs ffffffff ___c_args__ -abs ffffffff ___pinit__ -abs ffffffff binit -abs ffffffff pinit +page address name +---- ------- ---- +0 00008000 .text +0 00008000 _Current_count +0 00008000 ___text__ +0 0000825a _adc_isr +0 00008437 _Temper_count +0 000085de _get_Buttons +0 00008781 _main +0 00008920 _setup_adc +0 00008aad _cpu_timer1_isr_SENS +0 00008c31 _Load_runner +0 00008d8d _RS_RX_Handler +0 00008edf _cpu_timer1_isr_PULT +0 00009022 _Init_sensors +0 0000914b _SPISE2P_DRV_tick +0 0000926d _get_Mode +0 00009382 _kanal_Send +0 0000948d _Power_count +0 00009586 _Default_params +0 00009672 _setup_uart +0 00009740 _ump_log_read +0 000097f3 _calc_sensor_koef +0 000098a1 _InitCan +0 0000994d _UMP_CAN_service +0 000099f5 _init +0 000099f6 _ReceiveCommandModbus3 +0 00009a93 _select_tpl_canal +0 00009b2f _upload +0 00009bc6 _Init_packMask +0 00009e00 FS$$DIV +0 00009e88 _InitPeripheralClocks +0 00009f0d _extendbios +0 00009f91 _run +0 00009f92 _ump_rtu_encode +0 0000a015 _InitPll +0 0000a097 _peek +0 0000a10f _Handlai +0 0000a181 _ump_validate +0 0000a1f2 _ump_log_write +0 0000a262 _RS_TX_Handler +0 0000a2d0 _Load_protection_prepare +0 0000a339 _Init_sensors_more +0 0000a39b _InitXintf16Gpio +0 0000a3f4 _get_command +0 0000a44b _ReceiveCommandModbus6 +0 0000a537 _ump_prepare +0 0000a5d0 _RS_Send +0 0000a61b _CANa_handler +0 0000a665 _load +0 0000a6ae _CAN_send +0 0000a6f6 _initload +0 0000a73d _RSA_RX_Handler +0 0000a783 _RSA_TX_Handler +0 0000a7c9 _RSB_RX_Handler +0 0000a80f _RSB_TX_Handler +0 0000a855 _c_int00 +0 0000a89b _ump_log_can +0 0000a91e _Seeprom_read +0 0000a95f _Seeprom_write +0 0000a9a0 _setup_arr_cmd_length +0 0000a9e1 _Load_params +0 0000aa21 _init_zone7 +0 0000aa5f _InitCpuTimers +0 0000aa9a _Load_voltage_can +0 0000aad5 _ump_can_fragment +0 0000ab10 _poke +0 0000ab4a _cpu_timer2_isr +0 0000ab83 _SendCommandModbus4 +0 0000abbb _ump_tms28335_fragment +0 0000abf3 _RS_BSend +0 0000ac2a _ReceiveAnswerModbus4 +0 0000ac61 _Answer +0 0000acfa _SPISE2P_DRV_init +0 0000ad2c _unsetup_leds_line +0 0000ad5e _dSEND +0 0000ad8f _RS_FifoTick1ms +0 0000adbe _filterbat +0 0000adec _ump_log_io +0 0000ae1a _RS_SetLineMode +0 0000ae47 _timer_Init +0 0000ae74 _get_crc_16b +0 0000aea0 _CANa_reset_err +0 0000aecb L$$DIV +0 0000aeda L$$MOD +0 0000aee8 UL$$DIV +0 0000aeef UL$$MOD +0 0000aef5 _InitSeeprom +0 0000af1e _get_crc16 +0 0000af45 _RS_SetLineSpeed +0 0000af6b _Save_params +0 0000afb3 _select_tpl_255 +0 0000afd7 _setup_leds_line +0 0000aff9 _ConfigCpuTimer +0 0000b01a _Setup_DAC_time +0 0000b03a _sqrt +0 0000b05a _InitPieCtrl +0 0000b079 _reset_errs +0 0000b098 _Load_control_init +0 0000b0b6 _SENDBIT +0 0000b0d4 _ump_log_init +0 0000b0f1 _ump_tms28335_prepare +0 0000b10e _what_is +0 0000b12b _Init_DAC +0 0000b147 _im_calc +0 0000b163 _ump_crc +0 0000b17f _ump_tms28335_capture +0 0000b19b _ADCINT_ISR +0 0000b1b6 _DINTCH1_ISR +0 0000b1d1 _DINTCH2_ISR +0 0000b1ec _DINTCH3_ISR +0 0000b207 _DINTCH4_ISR +0 0000b222 _DINTCH5_ISR +0 0000b23d _DINTCH6_ISR +0 0000b258 _ECAN0INTA_ISR +0 0000b273 _ECAN0INTB_ISR +0 0000b28e _ECAN1INTA_ISR +0 0000b2a9 _ECAN1INTB_ISR +0 0000b2c4 _ECAP1_INT_ISR +0 0000b2df _ECAP2_INT_ISR +0 0000b2fa _ECAP3_INT_ISR +0 0000b315 _ECAP4_INT_ISR +0 0000b330 _ECAP5_INT_ISR +0 0000b34b _ECAP6_INT_ISR +0 0000b366 _EPWM1_INT_ISR +0 0000b381 _EPWM1_TZINT_ISR +0 0000b39c _EPWM2_INT_ISR +0 0000b3b7 _EPWM2_TZINT_ISR +0 0000b3d2 _EPWM3_INT_ISR +0 0000b3ed _EPWM3_TZINT_ISR +0 0000b408 _EPWM4_INT_ISR +0 0000b423 _EPWM4_TZINT_ISR +0 0000b43e _EPWM5_INT_ISR +0 0000b459 _EPWM5_TZINT_ISR +0 0000b474 _EPWM6_INT_ISR +0 0000b48f _EPWM6_TZINT_ISR +0 0000b4aa _EQEP1_INT_ISR +0 0000b4c5 _EQEP2_INT_ISR +0 0000b4e0 _I2CINT1A_ISR +0 0000b4fb _I2CINT2A_ISR +0 0000b516 _LUF_ISR +0 0000b531 _LVF_ISR +0 0000b54c _MRINTA_ISR +0 0000b567 _MRINTB_ISR +0 0000b582 _MXINTA_ISR +0 0000b59d _MXINTB_ISR +0 0000b5b8 _SCIRXINTA_ISR +0 0000b5d3 _SCIRXINTB_ISR +0 0000b5ee _SCIRXINTC_ISR +0 0000b609 _SCITXINTA_ISR +0 0000b624 _SCITXINTB_ISR +0 0000b63f _SCITXINTC_ISR +0 0000b65a _SEQ1INT_ISR +0 0000b675 _SEQ2INT_ISR +0 0000b690 _SPIRXINTA_ISR +0 0000b6ab _SPITXINTA_ISR +0 0000b6c6 _TINT0_ISR +0 0000b6e1 _WAKEINT_ISR +0 0000b6fc _XINT3_ISR +0 0000b717 _XINT4_ISR +0 0000b732 _XINT5_ISR +0 0000b74d _XINT6_ISR +0 0000b768 _XINT7_ISR +0 0000b783 __args_main +0 0000b79e _RS_SetBitMode +0 0000b7b8 _create_uart_vars +0 0000b7d2 _InitAdc +0 0000b7eb _XINT1_ISR +0 0000b804 _XINT2_ISR +0 0000b81d C$$EXIT +0 0000b81d _abort +0 0000b81f _exit +0 0000b836 _prolog_c28x_1 +0 0000b83a _prolog_c28x_2 +0 0000b842 _prolog_c28x_3 +0 0000b84f _RESET +0 0000b867 _ump_log_tick +0 0000b87f _clear_mem +0 0000b896 _ServiceDog +0 0000b8c0 _er_anal +0 0000b8e8 _RS_FifoWait +0 0000b90e _get_crc_16 +0 0000b920 _pause_us +0 0000b940 _DATALOG_ISR +0 0000b94d _INT13_ISR +0 0000b95a _INT14_ISR +0 0000b967 _InitPieVectTable +0 0000b974 _RTOSINT_ISR +0 0000b981 _epilog_c28x_1 +0 0000b985 _epilog_c28x_2 +0 0000b98d _EMUINT_ISR +0 0000b998 _ILLEGAL_ISR +0 0000b9a3 _NMI_ISR +0 0000b9ae _USER10_ISR +0 0000b9b9 _USER11_ISR +0 0000b9c4 _USER12_ISR +0 0000b9cf _USER1_ISR +0 0000b9da _USER2_ISR +0 0000b9e5 _USER3_ISR +0 0000b9f0 _USER4_ISR +0 0000b9fb _USER5_ISR +0 0000ba06 _USER6_ISR +0 0000ba11 _USER7_ISR +0 0000ba1c _USER8_ISR +0 0000ba27 _USER9_ISR +0 0000ba32 _ump_log_rs +0 0000ba3d U$$DIV +0 0000ba42 U$$MOD +0 0000ba48 _INT_NOTUSED_ISR +0 0000ba52 _PIE_RESERVED +0 0000ba5c _rsvd_ISR +0 0000ba66 _EnableInterrupts +0 0000ba6f _InitSysCtrl +0 0000ba78 __register_unlock +0 0000ba7c __register_lock +0 0000ba80 __nop +0 0000ba81 _DisableDog +0 0000ba89 _memset +0 0000ba90 _SPISE2P_DRV_csclr +0 0000ba95 _SPISE2P_DRV_csset +0 0000ba9a _set_cntrl_addr +0 0000ba9f _DSP28x_usDelay +0 0000baa6 _tflash +0 0000baa7 ___etext__ +0 0000baa7 etext +0 0000c000 _RamfuncsLoadEnd +0 0000c000 _RamfuncsLoadStart +0 0000c000 _RamfuncsRunStart +0 0000c000 ___cinit__ +0 0000c000 cinit +0 0000c274 _PieVectTableInit +0 0000c39c _ADDR_ANSWER +0 0000c39d _ADDR_TERMINAL +0 0000c39e _CNTRL_ADDR_UNIVERSAL +0 00380080 _ADC_cal +1 00000400 __stack +1 000007f0 __STACK_END +1 00000880 _DevEmuRegs +1 00000a80 _FlashRegs +1 00000ae0 _CsmRegs +1 00000b00 _AdcMirror +1 00000b20 _XintfRegs +1 00000c00 _CpuTimer0Regs +1 00000c08 _CpuTimer1Regs +1 00000c10 _CpuTimer2Regs +1 00000ce0 _PieCtrlRegs +1 00000d00 _PieVectTable +1 00001000 _DmaRegs +1 00005000 _McbspaRegs +1 00005040 _McbspbRegs +1 00006000 _ECanaRegs +1 00006040 _ECanaLAMRegs +1 00006080 _ECanaMOTSRegs +1 000060c0 _ECanaMOTORegs +1 00006100 _ECanaMboxes +1 00006200 _ECanbRegs +1 00006240 _ECanbLAMRegs +1 00006280 _ECanbMOTSRegs +1 000062c0 _ECanbMOTORegs +1 00006300 _ECanbMboxes +1 00006800 _EPwm1Regs +1 00006840 _EPwm2Regs +1 00006880 _EPwm3Regs +1 000068c0 _EPwm4Regs +1 00006900 _EPwm5Regs +1 00006940 _EPwm6Regs +1 00006a00 _ECap1Regs +1 00006a20 _ECap2Regs +1 00006a40 _ECap3Regs +1 00006a60 _ECap4Regs +1 00006a80 _ECap5Regs +1 00006aa0 _ECap6Regs +1 00006b00 _EQep1Regs +1 00006b40 _EQep2Regs +1 00006f80 _GpioCtrlRegs +1 00006fc0 _GpioDataRegs +1 00006fe0 _GpioIntRegs +1 00007010 _SysCtrlRegs +1 00007040 _SpiaRegs +1 00007050 _SciaRegs +1 00007070 _XIntruptRegs +1 00007100 _AdcRegs +1 00007750 _ScibRegs +1 00007770 _ScicRegs +1 00007900 _I2caRegs +1 0000d040 _rs_a +1 0000d3c0 _rs_b +1 0000d70a _din_count +1 0000d72a _powK +1 0000d73c _adc_table_lem +1 0000d740 _adc_filter +1 0000d8f0 _Maska +1 0000d900 _out_filter +1 0000dab0 _digits +1 0000dac0 _crc_16_tab +1 0000dbc0 _modbus +1 0000dc41 _flag_DEBUG +1 0000dc42 _sens_count +1 0000dc7a _SYSCLKOUT +1 0000dc7c _LSPCLK +1 0000dc7e _HSPCLK +1 0000dc80 _param +1 0000dd02 _CanPowse +1 0000dd03 _CanGO +1 0000dd04 _READY +1 0000dd05 _TPL_CANS +1 0000dd06 _tpl_cans +1 0000dd07 _cal_addr +1 0000dd08 _pow_addr +1 0000dd09 _period_ready +1 0000dd0a _period_blink +1 0000dd0b _chk +1 0000dd0c _sig +1 0000dd0d _time_1_5sec +1 0000dd0e _time_5msec +1 0000dd0f _time_3sec +1 0000dd10 _time_5sec +1 0000dd11 _Caliber_time +1 0000dd12 _Curr_Edge +1 0000dd13 _okay +1 0000dd1e _K100 +1 0000dd20 _K_50 +1 0000dd22 _K_T1 +1 0000dd24 _K_T2 +1 0000dd28 _def_FILTERBAT +1 0000dd3a _err_count +1 0000ddbc _ADDR_FOR_ALL +1 0000ddbd _CNTRL_ADDR +1 0000ddbe _cntr_addr_c +1 0000ddbf _cntr_addr_c_all +1 0000de3c __unlock +1 0000de3e __lock +1 0000de40 _zer_filter +1 0000de88 _no_write +1 0000de89 _never_write +1 0000de8a _flog +1 0000dea0 _Log +1 0000dea8 _period_dac +1 0000dea9 _time_dac +1 0000deb8 _WAKEpowse +1 0000deba _IMPowse +1 0000dec0 _RS_Len +1 0000df06 _ADC_table +1 0000df22 _prev_ok +1 0000df40 _def_cal +1 0000df80 _ccc +1 0000df9c _CpuTimer0 +1 0000dfa4 _CpuTimer1 +1 0000dfac _CpuTimer2 +1 0000dfb4 _COUNT_ONE_CANAL +1 0000dfb5 _COUNT_DISCHARGE +1 0000dfb6 _COUNT_TRANSICIA +1 0000dfb7 _FILTER_CLIP +1 0000dfbc _WAKE +1 0000dfbe _WAKE_TIME +1 0000dfc0 _sens_pair +1 0000dfd8 _sens_type +1 0000dff0 _Mode +1 0000dff1 _Desk +1 0000dff2 _TermoAD +1 0000dff3 _TermoRS +1 0000dff4 _TermoSW +1 0000dff5 _Kurrent +1 0000dff6 _Kalibro +1 0000dff7 _Owen +1 0000dff8 _INcount0 +1 0000dff9 _INcount1 +1 0000dffa _MUX_GPIO32 +1 0000dffb _MUX_GPIO48 +1 0000dffc _DIR_GPIO32 +1 0000dffd _DIR_GPIO48 +1 0000dffe _DigErr +1 0000e000 _CanTimeOutErrorTR +1 0000e001 _wait +1 0000e00a _ErrorCount +1 0000e00c _MessageReceivedCount +1 0000e00e _MessageTransivedCount +1 0000e010 _TestMbox1 +1 0000e012 _TestMbox2 +1 0000e014 _TestMbox3 +1 0000e018 _lev_quadr +1 0000e024 _isNumb +1 0000e025 _quaLamp +1 0000e02a _isMask +1 0000e02c _Lonely +1 0000e02e _ext_diag +1 0000e036 _ext_temp +1 0000e040 _zer_count +1 0000e048 _lev_count +1 0000e04e _readr +1 0000e053 _errno +1 0000e054 __cleanup_ptr +1 0000e056 __dtors_ptr +1 0000e05a _low_count +1 00200000 _logs_block +1 0033fff8 _CsmPwl +1 00380090 _PartIdRegs +abs 000003f0 __STACK_SIZE +abs 00003f7e _EEPROM_PARAMS_START_WORD +abs 00007efc _EEPROM_FIRMWARE_LIMIT_BYTES +abs 00007efc _EEPROM_PARAMS_START_BYTE +abs 00007ffe _EEPROM_PARAMS_END_BYTE +abs 00008000 _EEPROM_TOTAL_BYTES +abs ffffffff ___TI_pprof_out_hndl +abs ffffffff ___TI_prof_data_size +abs ffffffff ___TI_prof_data_start +abs ffffffff ___binit__ +abs ffffffff ___c_args__ +abs ffffffff ___pinit__ +abs ffffffff binit +abs ffffffff pinit -[419 symbols] +[409 symbols] diff --git a/UKSSTMS320F28335/.cproject b/UKSSTMS320F28335/.cproject index 3e21595..958b36a 100644 --- a/UKSSTMS320F28335/.cproject +++ b/UKSSTMS320F28335/.cproject @@ -76,8 +76,8 @@