Files
Balsam_167/Doc/index.html

118 lines
21 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!doctype html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="description" content="Архитектура и API прошивки периферийного контроллера Balsam 167 на TMS320F28335.">
<title>Balsam 167 · Документация прошивки</title>
<style>
:root{color-scheme:dark;--bg:#07111f;--panel:#0d1b2c;--panel2:#12243a;--line:#263b54;--text:#e8f0f8;--muted:#9eb0c4;--mint:#55d6be;--blue:#8bc5ff;--amber:#fbbf24;--red:#ff8278;--code:#071521;--radius:16px}
*{box-sizing:border-box}html{scroll-behavior:smooth}body{margin:0;min-height:100vh;color:var(--text);background:radial-gradient(circle at 85% 0,#143354 0,transparent 31rem),var(--bg);font:15px/1.65 Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}a{color:var(--blue);text-decoration:none}a:hover{text-decoration:underline}code,pre{font-family:Consolas,"Courier New",monospace}:not(pre)>code{padding:2px 6px;border-radius:5px;color:#c4f8ec;background:#15283a}.wrap{width:min(1180px,calc(100% - 32px));margin:auto}header{padding:58px 0 32px}.eyebrow{color:var(--mint);font:800 12px/1.2 Consolas,monospace;letter-spacing:.14em;text-transform:uppercase}h1{max-width:900px;margin:12px 0;font-size:clamp(38px,7vw,72px);line-height:1;letter-spacing:-.05em}h2{margin:0 0 8px;font-size:clamp(27px,4vw,38px);letter-spacing:-.03em}h3{margin:0 0 8px;font-size:19px}.lead,.intro,.card p,.card li{color:var(--muted)}.lead{max-width:850px;font-size:18px}.stats{display:flex;flex-wrap:wrap;gap:10px;margin-top:26px}.stat{padding:8px 12px;border:1px solid var(--line);border-radius:999px;background:#0d1b2ccc;color:var(--muted);font-size:13px}.stat b{color:var(--text)}.tabbar{position:sticky;top:0;z-index:10;border-block:1px solid var(--line);background:#07111fe8;backdrop-filter:blur(14px)}.tabs{display:flex;gap:6px;padding:10px 0;overflow-x:auto}.tab{border:0;border-radius:9px;padding:10px 15px;color:var(--muted);background:transparent;font:inherit;font-weight:700;white-space:nowrap;cursor:pointer}.tab:hover{color:var(--text);background:var(--panel)}.tab[aria-selected=true]{color:#07111f;background:var(--mint)}main{padding:34px 0 70px}.pane[hidden]{display:none}.intro{max-width:820px;margin:0 0 24px}.grid{display:grid;grid-template-columns:repeat(12,1fr);gap:14px}.card{grid-column:span 4;min-width:0;padding:21px;border:1px solid var(--line);border-radius:var(--radius);background:linear-gradient(145deg,#12243af0,#0d1b2ceb);box-shadow:0 18px 55px #0003}.card.half{grid-column:span 6}.card.wide{grid-column:span 8}.card.full{grid-column:1/-1}.tag{display:inline-block;margin-bottom:13px;padding:3px 8px;border-radius:6px;color:var(--mint);background:#153d39;font:700 11px/1.5 Consolas,monospace;text-transform:uppercase}.tag.blue{color:var(--blue);background:#15334a}.tag.amber{color:#ffda84;background:#3a2d16}.tag.red{color:#ffaaa3;background:#3b211f}.flow{display:grid;grid-template-columns:repeat(5,1fr);gap:8px;margin:20px 0}.step{padding:16px;border:1px solid var(--line);border-radius:12px;background:var(--panel)}.step b{display:block;color:var(--mint);font-size:13px}.step span{color:var(--muted);font-size:13px}.filetree,pre{overflow:auto;margin:14px 0 0;padding:17px;border:1px solid var(--line);border-radius:12px;background:var(--code);color:#d6e5f3;font:13px/1.65 Consolas,monospace;white-space:pre}.table-scroll{overflow-x:auto}table{width:100%;min-width:760px;border-collapse:collapse}th,td{padding:11px 13px;border-bottom:1px solid var(--line);text-align:left;vertical-align:top}th{color:var(--muted);font-size:12px;text-transform:uppercase;letter-spacing:.06em}td:first-child{color:var(--mint);font-family:Consolas,monospace}.callout{margin-top:16px;padding:15px 17px;border-left:3px solid var(--amber);border-radius:4px 12px 12px 4px;color:#dfd2b4;background:#251f14}.links{display:flex;flex-wrap:wrap;gap:10px;margin-top:20px}.button{display:inline-flex;align-items:center;padding:10px 14px;border:1px solid #39708a;border-radius:10px;color:var(--text);background:#123047}.button.primary{border-color:var(--mint);color:#061511;background:var(--mint);font-weight:800}.check{list-style:none;padding:0}.check li{position:relative;padding-left:26px}.check li:before{content:'✓';position:absolute;left:0;color:var(--mint);font-weight:900}footer{padding:24px 0 42px;border-top:1px solid var(--line);color:var(--muted);font-size:13px}@media(max-width:900px){.card,.card.half,.card.wide{grid-column:1/-1}.flow{grid-template-columns:1fr 1fr}}@media(max-width:540px){.wrap{width:min(100% - 20px,1180px)}header{padding-top:36px}.flow{grid-template-columns:1fr}}
</style>
<style>
.analysis-layout{display:grid;grid-template-columns:310px minmax(0,1fr);gap:14px;align-items:start}.analysis-nav{display:grid;gap:9px}.analysis-link{display:block;padding:13px 14px;border:1px solid var(--line);border-radius:11px;color:var(--text);background:var(--panel);font-weight:700}.analysis-link:hover,.analysis-link.active{border-color:var(--mint);color:var(--mint);text-decoration:none;background:#12302f}.analysis-link small{display:block;margin-top:3px;color:var(--muted);font-weight:400}.analysis-frame{width:100%;height:72vh;min-height:620px;border:1px solid var(--line);border-radius:14px;background:#fff}@media(max-width:850px){.analysis-layout{grid-template-columns:1fr}.analysis-nav{grid-template-columns:1fr 1fr}.analysis-frame{height:68vh;min-height:520px}}@media(max-width:540px){.analysis-nav{grid-template-columns:1fr}}
</style>
</head>
<body>
<header class="wrap">
<div class="eyebrow">TMS320F28335 · C2000 · Balsam 167</div>
<h1>Периферийный контроллер<br>карта прошивки</h1>
<p class="lead">Архитектура измерений, диагностики и обмена для многоролевого контроллера Balsam 167. Страница служит точкой входа, а Doxygen содержит навигацию по исходникам и полное API.</p>
<div class="stats"><span class="stat"><b>17</b> внутренних C-модулей</span><span class="stat"><b>6</b> ролей платы</span><span class="stat"><b>2× SCI</b> + eCAN-A</span><span class="stat"><b>CCS 3 / 12</b></span></div>
<div class="links"><a class="button primary" href="api/html/index.html">Открыть Doxygen API</a><a class="button" href="../README_CCS12.md">Сборка CCS 12</a></div>
</header>
<nav class="tabbar"><div class="wrap tabs" role="tablist" aria-label="Разделы">
<button class="tab" role="tab" aria-selected="true" aria-controls="overview">Обзор</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="architecture">Архитектура</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="modules">Модули</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="data">Данные</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="analysis">Анализ кода</button>
<button class="tab" role="tab" aria-selected="false" aria-controls="build">Сборка</button>
</div></nav>
<main class="wrap">
<section class="pane" id="overview" role="tabpanel">
<h2>Что делает проект</h2><p class="intro">Прошивка объединяет измерительный тракт, диагностику, управление выходами и два транспортных интерфейса. Аппаратная роль определяется при старте, поэтому один код работает на нескольких платах комплекса.</p>
<div class="grid">
<article class="card wide"><span class="tag">Поток запуска</span><h3>От сброса до рабочего цикла</h3><div class="filetree">InitSysCtrl → PIE / XINTF → get_Mode
↓
eCAN-A + SCI-A/SCI-B + SPI EEPROM
↓
GPIO / ADC / Timer1 / параметры / маски CAN
↓
главный цикл: CAN → команды → кнопки → RS-485</div></article>
<article class="card"><span class="tag blue">Платформа</span><h3>Texas Instruments C2000</h3><p>TMS320F28335, COFF ABI, large memory model и аппаратные модули ADC, eCAN, SCI, SPI, CPU Timer и XINTF.</p></article>
<article class="card"><span class="tag amber">Конфигурация</span><h3>BALSAM = 167</h3><p><code>package.h</code> выбирает направление, RS-калибровку, OWEN и раскладку общих регистров.</p></article>
<article class="card"><span class="tag">Главная модель</span><h3>128 Modbus-регистров</h3><p>Измерения, уставки, ошибки, калибровка и команды представлены через массив <code>modbus</code> и макросы доступа.</p></article>
<article class="card"><span class="tag red">Реальное время</span><h3>Три контура</h3><p>ADC ISR собирает выборки, Timer1 ведёт измерение или пульт, главный цикл выполняет связь и команды.</p></article>
</div>
</section>
<section class="pane" id="architecture" role="tabpanel" hidden>
<h2>Как связаны подсистемы</h2><p class="intro">Быстрые обработчики обновляют состояние, а главный цикл публикует его и принимает управляющие команды. Общая модель связывает подсистемы без динамического выделения памяти.</p>
<div class="flow"><div class="step"><b>01 · Входы</b><span>ADC, GPIO, SCI, eCAN</span></div><div class="step"><b>02 · Обработка</b><span>фильтры, физические величины</span></div><div class="step"><b>03 · Диагностика</b><span>таймеры, пороги, ERROR</span></div><div class="step"><b>04 · Модель</b><span>modbus и команды</span></div><div class="step"><b>05 · Выходы</b><span>CAN, RS-485, DAC, GPIO</span></div></div>
<div class="grid">
<article class="card half"><span class="tag">Измерительная плата</span><h3>ADC ISR + Timer1 SENS</h3><ol><li>ADC ISR накапливает и фильтрует выборки.</li><li><code>cpu_timer1_isr_SENS</code> выбирает канал и планирует пересчёт.</li><li><code>Temper_count</code>, <code>Current_count</code> и <code>Power_count</code> обновляют значения.</li><li><code>er_anal</code> подтверждает ошибки с выдержкой времени.</li></ol></article>
<article class="card half"><span class="tag blue">Пульт EPLT</span><h3>Timer1 PULT</h3><p>Для роли <code>dsk_EPLT</code> Timer1 направляется в <code>cpu_timer1_isr_PULT</code>. Обработчик ведёт внешнюю индикацию и дискретный интерфейс, не запуская обычный измерительный контур.</p></article>
<article class="card full"><span class="tag amber">Конкурентный доступ</span><h3>Главный цикл и прерывания используют общие переменные</h3><p>При изменениях учитывайте атомарность доступа C28x, порядок обновления <code>modbus</code>, флаги <code>CanGO</code>/<code>READY</code> и время выполнения ISR. В прерываниях нельзя добавлять блокирующий обмен с EEPROM или UART.</p></article>
</div>
</section>
<section class="pane" id="modules" role="tabpanel" hidden>
<h2>Внутренние модули</h2><p class="intro">Таблица показывает назначение каждого слоя и его основные точки входа.</p>
<article class="card full"><div class="table-scroll"><table><thead><tr><th>Модуль</th><th>Назначение</th><th>Основные API</th></tr></thead><tbody>
<tr><td>main.c</td><td>Старт платформы и кооперативный главный цикл</td><td><code>main</code>, <code>timer_Init</code></td></tr>
<tr><td>ADC.c</td><td>Секвенсор ADC, накопление и ISR</td><td><code>setup_adc</code>, <code>adc_isr</code></td></tr>
<tr><td>measure.c</td><td>Температура, ток, напряжение, мощность и диагностика</td><td><code>Init_sensors</code>, <code>Current_count</code>, <code>Temper_count</code>, <code>Power_count</code></td></tr>
<tr><td>filter_bat2.c</td><td>IIR-фильтр Баттерворта второго порядка</td><td><code>filterbat</code></td></tr>
<tr><td>RS485.c</td><td>Два SCI-канала, RX/TX автоматы и тайм-ауты</td><td><code>setup_uart</code>, <code>RS_Send</code>, <code>RS_BSend</code></td></tr>
<tr><td>bios.c</td><td>Сервисный/загрузочный протокол контроллера</td><td><code>get_command</code>, <code>peek</code>, <code>poke</code>, <code>load</code>, <code>run</code></td></tr>
<tr><td>message.c</td><td>Modbus, параметры и обмен с OWEN</td><td><code>ReceiveCommandModbus3</code>, <code>Save_params</code>, <code>Load_params</code></td></tr>
<tr><td>ecan.c</td><td>eCAN-A mailboxes и телеметрия</td><td><code>InitCan</code>, <code>CAN_send</code>, <code>CANa_handler</code></td></tr>
<tr><td>spise2p.c</td><td>SPI-драйвер последовательной EEPROM</td><td><code>InitSeeprom</code>, <code>Seeprom_read</code>, <code>Seeprom_write</code></td></tr>
<tr><td>peripher.c</td><td>Распознавание платы, GPIO и мультиплексоры</td><td><code>get_Mode</code>, <code>get_Buttons</code>, <code>select_tpl_canal</code></td></tr>
<tr><td>DAC.c</td><td>Аналоговый выход платы нагрузки</td><td><code>Init_DAC</code>, <code>Anal_output</code>, <code>Load_runner</code></td></tr>
<tr><td>pulto.c / kanal.c</td><td>Пульт и последовательная индикация</td><td><code>cpu_timer1_isr_PULT</code>, <code>kanal_Send</code></td></tr>
<tr><td>crc16.c / tools.c</td><td>CRC, XINTF zone 7 и задержки</td><td><code>get_crc_16</code>, <code>init_zone7</code>, <code>pause_us</code></td></tr>
</tbody></table></div></article>
</section>
<section class="pane" id="data" role="tabpanel" hidden>
<h2>Данные и конфигурация</h2><p class="intro">Система построена вокруг статических массивов и битовых слов. Это подходит для C28x, но требует строго сохранять индексы и размеры.</p>
<div class="grid">
<article class="card half"><span class="tag">modbus[]</span><h3>Карта регистров</h3><ul><li><code>0x00</code> — слова ошибок каналов.</li><li><code>0x18</code> — текущие измерения.</li><li><code>0x30</code> — верхние уставки.</li><li><code>0x48</code> — нижние уставки.</li><li><code>0x60+</code> — периоды, яркость и служебные параметры.</li><li><code>0x7F</code> — команды.</li></ul></article>
<article class="card half"><span class="tag blue">ERROR</span><h3>Слово диагностики</h3><p>Биты описывают обрыв, неправильный сигнал, выход за диапазон, перегрев, стоп, готовность, дискретные входы, игнорирование и bypass. Поле <code>all</code> позволяет передавать слово целиком.</p></article>
<article class="card"><span class="tag amber">caliber.h</span><h3>Заводские таблицы</h3><p>Калибровки зависят от значения <code>BALSAM</code>. Файл содержит определения данных и должен включаться только там, где формируются значения по умолчанию.</p></article>
<article class="card"><span class="tag">GPIO_table.h</span><h3>Роли платы</h3><p>Направления и начальные уровни GPIO заданы отдельными наборами для COMM, BKSD, BKST, EPLT, SHKF и LOAD.</p></article>
<article class="card"><span class="tag red">CP1251</span><h3>Кодировка legacy-кода</h3><p>Старые комментарии исходников записаны в Windows-1251. Doxygen настроен декодировать <code>*.c</code> и <code>*.h</code> как CP1251; новые документы — UTF-8.</p></article>
</div>
</section>
<section class="pane" id="analysis" role="tabpanel" hidden>
<h2>Анализ кода</h2><p class="intro">Markdown-отчёты из каталога <code>Doc</code> включаются в Doxygen при каждой сборке. Выберите документ — его HTML откроется справа без ухода с этой вкладки.</p>
<div class="analysis-layout">
<nav class="analysis-nav" aria-label="Отчёты анализа кода">
<a class="analysis-link active" href="api/html/phase_break_error_flow.html" target="analysisFrame">Ошибка обрыва фаз<small>Детектирование и передача ошибки</small></a>
<a class="analysis-link" href="api/html/phase_comparison_balsam.html" target="analysisFrame">Balsam 165 ↔ 167<small>Сравнение фазовой части</small></a>
<a class="analysis-link" href="api/html/phase_voltage_calculation.html" target="analysisFrame">Расчёт фаз<small>Диагностика и уровни напряжения</small></a>
<a class="analysis-link" href="api/html/phase_voltage_weak_points.html" target="analysisFrame">Слабые места<small>Риски расчёта и контроля</small></a>
</nav>
<iframe class="analysis-frame" name="analysisFrame" title="Выбранный отчёт анализа кода" src="api/html/phase_break_error_flow.html"></iframe>
</div>
</section>
<section class="pane" id="build" role="tabpanel" hidden>
<h2>Как собрать документацию</h2><p class="intro">Скрипт повторяет схему эталонных HTML-документов: формирует автономную точку входа и дополнительно запускает Doxygen, если он установлен.</p>
<div class="grid">
<article class="card wide"><span class="tag">Команда</span><h3>Запуск из корня репозитория</h3><pre>Doc\build.bat</pre><p>Готовый обзор: <code>Doc\build\index.html</code><br>API: <code>Doc\build\api\html\index.html</code><br>Предупреждения: <code>Doc\build\doxygen-warnings.log</code></p></article>
<article class="card"><span class="tag blue">Зависимость</span><h3>Doxygen в PATH</h3><p>Без Doxygen обзор всё равно собирается, а скрипт печатает предупреждение. После установки повторный запуск добавит API-справочник.</p></article>
<article class="card full"><span class="tag amber">Проверка изменений</span><h3>Перед публикацией</h3><ul class="check"><li>Открывается <code>build/index.html</code>.</li><li>Ссылка «Открыть Doxygen API» ведёт на созданный индекс.</li><li>В журнале нет неизвестных команд и неверных ссылок.</li><li>Новые публичные функции описаны в заголовке или <code>api.dox</code>.</li><li>Разметка <code>modbus</code> согласована с внешним описанием данных.</li></ul></article>
</div>
</section>
</main>
<footer><div class="wrap">Balsam 167 Peripheral · источник истины по поведению — код, по API — Doxygen-комментарии и заголовки.</div></footer>
<script>
const tabs=[...document.querySelectorAll('[role=tab]')],panes=[...document.querySelectorAll('[role=tabpanel]')];function show(id,hash=true){const tab=tabs.find(x=>x.getAttribute('aria-controls')===id)||tabs[0];tabs.forEach(x=>x.setAttribute('aria-selected',x===tab));panes.forEach(x=>x.hidden=x.id!==tab.getAttribute('aria-controls'));if(hash)history.replaceState(null,'','#'+tab.getAttribute('aria-controls'))}tabs.forEach((tab,i)=>{tab.onclick=()=>show(tab.getAttribute('aria-controls'));tab.onkeydown=e=>{if(e.key==='ArrowRight')show(tabs[(i+1)%tabs.length].getAttribute('aria-controls'));if(e.key==='ArrowLeft')show(tabs[(i-1+tabs.length)%tabs.length].getAttribute('aria-controls'))}});if(location.hash)show(location.hash.slice(1),false);document.querySelectorAll('.analysis-link').forEach(link=>link.addEventListener('click',()=>{document.querySelectorAll('.analysis-link').forEach(item=>item.classList.remove('active'));link.classList.add('active')}));
</script>
</body>
</html>