# Последовательность инициализации проекта

Основная точка входа находится в:

```text
AD_Keil_Project/Core/Src/main.c
```

После сброса выполняется такая последовательность:

```c
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_TIM1_Init();
AD_Project_Init();
```

В основном цикле выполняется:

```c
AD_Project_Loop();
```

## Что инициализируется

| Шаг | Функция | Что делает |
|---|---|---|
| 1 | `HAL_Init()` | Сбрасывает периферию HAL, запускает SysTick и базовое состояние HAL |
| 2 | `SystemClock_Config()` | Настраивает тактирование STM32G4 на 170 МГц от HSI/PLL |
| 3 | `MX_GPIO_Init()` | Включает тактирование GPIO, настраивает кнопку `B1` и прерывание `EXTI15_10`; `PA5/LD2` не используется по умолчанию |
| 4 | `MX_TIM1_Init()` | Настраивает `TIM1` для шести PWM-линий IHM08M1 `UH/UL`, `VH/VL`, `WH/WL`, dead-time и `PA6/TIM1_BKIN`; PWM не запускается автоматически |
| 5 | `AD_Project_Init()` | Общий старт прикладного слоя проекта |

## Что делает `AD_Project_Init()`

`AD_Project_Init()` находится в:

```text
AD_Keil_Project/Core/Src/ad_project.c
```

Внутри вызывается `AD_Board_Init()`, а она поднимает прикладные подсистемы:

| Подсистема | Функция | Состояние после запуска |
|---|---|---|
| Плата | `AD_Board_Init()` | Сбрасывает флаги кнопки, режим логирования и индикацию |
| ADC измерений | внутренний `board_adc_init()` | Настраивает `PA0`, `PA1`, `PC0`, `PC1` как аналоговые входы по схеме IHM08M1 и запускает `ADC1` |
| Ключи инвертора | `AD_Inverter_Init()` | Ставит duty в ноль, останавливает PWM, помечает слой как инициализированный |
| Интерфейс модели | `SimulinkInterface_Init()` | Сбрасывает входные и выходные шины, телеметрию и команду |
| Идентификация | `AD_ParamID_Init()` | Сбрасывает параметры, измерения, защиты, режимы и ошибки |
| Команда по умолчанию | внутренний вызов `board_apply_command(0, AD_PARAM_ID_MODE_IDLE)` | Проект стартует в выключенном режиме |

## Инициализация ключей

Слой ключей находится в:

```text
AD_Keil_Project/Core/Inc/ad_inverter.h
AD_Keil_Project/Core/Src/ad_inverter.c
```

Доступные функции:

| Функция | Назначение |
|---|---|
| `AD_Inverter_Init()` | Инициализирует программное состояние инвертора и гарантированно выключает PWM |
| `AD_Inverter_Disable()` | Ставит duty в ноль и останавливает основной и комплементарный PWM на подтвержденном канале |
| `AD_Inverter_SetDuty()` | Записывает duty A/B/C в состояние; сейчас в регистр TIM1 попадает только подтвержденный канал A |
| `AD_Inverter_Enable()` | Пытается запустить PWM, но только если разрешены все программные защиты |
| `AD_Inverter_ApplyCommand()` | Применяет команду включения и duty |
| `AD_Inverter_GetState()` | Возвращает состояние слоя инвертора для отладки |

Сейчас для IHM08M1 заведены:

```text
PA8 / TIM1_CH1   -> UH
PA7 / TIM1_CH1N  -> UL
PA9 / TIM1_CH2   -> VH
PB0 / TIM1_CH2N  -> VL
PA10 / TIM1_CH3  -> WH
PB1 / TIM1_CH3N  -> WL
PA6 / TIM1_BKIN  -> BKIN
```

Полный трехфазный драйвер требует аппаратной проверки полярностей, dead-time, `BKIN` и каналов измерения перед разрешением силовых макросов.

## Защитные условия включения PWM

В стандартной сборке ключи не включатся, даже если вызвать `AD_Inverter_Enable()`.

Нужно одновременно выполнить условия:

- в настройках компиляции задан `AD_PARAM_ID_ENABLE_POWER_TESTS=1`;
- в настройках компиляции задан `AD_INVERTER_ENABLE_OUTPUTS=1`;
- нет защелкнутой аварии;
- заданы пределы тока и напряжения;
- текущий режим действительно требует силового теста;
- для режима locked-rotor отдельно вызван `AD_ParamID_SetLockedRotorAllowed(1)`;
- подтверждена аппаратная распиновка и проверены защиты.

Если хотя бы одно условие не выполнено, `AD_Inverter_Enable()` выключает PWM и возвращает `0`.

## Состояние проекта для отладки

Для отладки добавлен:

```c
const AD_ProjectState_t* AD_Project_GetState(void);
```

Структура показывает:

| Поле | Смысл |
|---|---|
| `initialized` | Общий прикладной слой запущен |
| `board_initialized` | Инициализация платы выполнена |
| `inverter_initialized` | Слой инвертора прошел init |
| `simulink_initialized` | Интерфейс модели прошел init |
| `outputs_allowed_by_build` | Макрос `AD_INVERTER_ENABLE_OUTPUTS` разрешает физические выходы |
| `param_id_status` | Текущий статус идентификации |
| `param_id_faults` | Текущие ошибки идентификации |
