# Ограниченная проверка питания и отказных режимов

Проверено по бинарнику `fw_128k.bin`, исходным инструкциям и исправленной декомпиляции. Это узкое дополнение, не полный анализ всех неисправностей платы.

## Оценка аккумулятора

`0x1F04` читает 16-битное значение `0x200011F8` и возвращает `3*x + 200`. Из отдельного анализа ADC этот канал соответствует VBAT/3. Масштаб результата согласуется с милливольтами, но абсолютную точность измерения прибора кодом не подтвердить.

`0x1A8C` выполняет проверку каждые десять своих вызовов: счётчик `0x200000F2`, результат фильтра `0xFF20(0, converted_value)` записывается в `0x200000C0`. Состояние предупреждения хранится в byte `0x200000E8`.

| Условие | Действие | Адреса |
|---|---|---|
| Оценка >3650 | Сброс состояния предупреждения в 0 | `0x1ABC–0x1AC6` |
| Оценка <3555 и состояние 0 | Переход интерфейса в режим 7, очистка экрана; состояние аккумулятора пока остаётся 0 | `0x1AC8–0x1AF0` |
| Оценка <3455 и состояние 1 | Состояние 2; сброс PC6 и PC0; вызов `0xE82C`, затем бесконечный цикл | `0x1AF4–0x1B2A` |

Равенство 3555 не вызывает предупреждение, равенство 3455 не вызывает отключение. Значение строго выше 3650 позволяет снова выдать предупреждение после восстановления заряда. Эти пороги относятся к вычисленной и фильтрованной величине, а не непосредственно к отсчёту ADC.

Режим 7 обслуживается `0x2504`: показывает сообщения и проходит повторяющуюся индикацию со счётчиками, после чего устанавливает `0x200000E8=1` и возвращает интерфейс в режим 10 (`0x2594–0x25AE`). Поэтому низкое напряжение при состоянии 0 сначала даёт предупреждение; немедленное попадание ниже 3455 само по себе не проходит ветку выключения до получения состояния 1.

`0xE82C` вызывает `0xC950`, который передаёт нулевые параметры в драйвер периферии `0x40011400` (IWDT по локальному SDK). После этого вызывающая функция крутится в бесконечном цикле. Фактическое снятие питания и поведение watchdog зависят от схемы и конфигурации; проверено именно выполнение этих команд, а не физическое выключение аппарата.

## Привязка к основному циклу

В `0x1056C` при режиме интерфейса >=10 вызываются проверка батареи `0x1A8C`, температура `0x11478` и обработка измерений/тревог `0xAEC4` (`0x1058E–0x1059E`). В режиме 7 эта ветка пропускается, вместо неё вызывается другая индикация `0xE51C`, затем обработчик предупреждения. Значит, данная ветка обработки измерений/газовых тревог во время предупреждения батареи не вызывается. Работа ADC и других задач при этом отдельный вопрос.

Для собственной прошивки полезно разделить интерфейс предупреждения и непрерывную обработку опасных газовых концентраций. Сам экран низкого заряда не должен неявно управлять допуском к измерительному алгоритму.

## Зарядное состояние и короткие импульсы

`0x1CF0` читает PA15, а при активном входе читает PA8 и управляет PA7/PA6. Обновление одного входного состояния делается через счётчик с границей 21; при неактивном PA15 несколько счётчиков сбрасываются. В этой ветке при одном состоянии обновляется оценка батареи прямым вызовом `0x1F04`. Связь с наличием зарядного питания весьма вероятна, но точные значения PA8 «заряд / завершён / ошибка» без схемы пока не присвоены.

`0x1924` формирует импульс PC4: включает при счётчике 2 и выключает при 5, снимая флаг запроса. `0x1BC4` аналогично управляет PC1 с границами 2 и 50. Это исполнители импульсов; сами по себе они не доказывают диагностику датчиков. Частоту вызова ещё нельзя автоматически считать миллисекундами.

Позднее установлен программный номинал главной задачи 100 мс и проверки батареи примерно раз в секунду в нормальных режимах; условия расчёта — в [timing.md](../timing.md). Реальные длительности при задержке кооперативных задач отдельно не измерялись.

## Проверка исходного кода

`verify_power.py` прошёл **5 адресных эмуляционных проверок** на оригинальном ARM-коде `0x1A8C–0x1B2C` и `0x1F04–0x1F12` в WSL/Unicorn 2.1.4. В каждом случае исполнялось преобразование `1000*3+200=3200`; затем подставлялся контролируемый выход фильтра. Внешние GPIO, экран и завершающий сервис подменены наблюдаемыми вызовами. Проверены 3651, 3555, 3554, 3455 и 3454 с соответствующими начальными состояниями. Результаты — `power_results.json`.

Это проверка переходов и границ. Она не измеряет батарею, не проверяет зарядный контроллер, фактический звук/свет и отключение питания. В рамках этой узкой проверки отдельные алгоритмы обрыва/короткого замыкания газового датчика и самостоятельный журнал неисправностей не восстановлены; отсутствие таких функций не утверждается.

## Требования к новой реализации

- Разделить «ниже нормы», «предупреждение подтверждено» и «критическое питание», задать пороги восстановления и порядок действий.
- Сохранять обработку газа и приоритет опасной тревоги во время предупреждений питания.
- Перед завершением работы определённо обработать незавершённую запись памяти и защитить калибровки от обрыва питания.
- Тестировать просадку при включении вибромотора/зуммера, зарядный кабель, восстановление напряжения и граничные равенства.
- Не заменять диагностические ошибки газового датчика нулевой концентрацией; политику отказа задать отдельно после исследования соответствующих веток.
