#pragma once

#include "main.h"
#include "charger_config.h"

void PSU_Init();
void PSU_Enable(uint8_t addr, uint8_t enable);
void PSU_ReadWrite(void);

// --- Состояние силового модуля (DC30, один PSU) ---

typedef enum{
	PSU_UNREADY,           // отключен, не готов к использованию
	PSU_INITIALIZING,      // инициализация модуля
	PSU_READY,             // отключен, готов к использованию
	PSU_WAIT_ACK_ON,       // ждём подтверждение включения модуля (напряжение выше порога)
	PSU_CONT_WAIT_ACK_ON,  // включаем DC-контактор и ждём подтверждение
	PSU_CONNECTED,         // модуль включён, DC-контактор замкнут
	PSU_CURRENT_DROP,      // снижение тока перед отключением
	PSU_WAIT_ACK_OFF,      // ждём подтверждение выключения модуля (напряжение ниже порога)
	PSU_CONT_WAIT_ACK_OFF, // выключаем DC-контактор и ждём подтверждение
	PSU_OFF_PAUSE,         // пауза после выключения модуля
} PSU_State_t;

/* Status0 (состояние модуля N, таблица 0 — modularForm0) */
typedef struct{
	/* Bit0 */ uint8_t shortCircuitFault:1;              /* 1: короткое замыкание на выходе */
	/* Bit1 */ uint8_t unevenFlowAlarm:1;               /* 1: перекос/неравномерность распределения тока между модулями */
	/* Bit2 */ uint8_t internalCommunicationFault:1;    /* 1: внутренняя ошибка связи модуля */
	/* Bit3 */ uint8_t inputBusLineFault:1;             /* 1: авария по входу или по шине постоянного тока */
	/* Bit4 */ uint8_t lockProtection:1;                /* 1: защита с защёлкой (латч, блокировка до сброса) */
	/* Bit5 */ uint8_t dischargeFault:1;                /* 1: неисправность цепи разряда (bleeder/разрядный резистор) */
	/* Bit6 */ uint8_t eepromFault:1;                   /* 1: ошибка/неисправность EEPROM */
	/* Bit7 */ uint8_t rsvd_s0:1;                       /* зарезервировано */
} PSU_Status0_t;

/* Status1 (состояние модуля N, таблица 1 — modularForm1) */
typedef struct{
	/* Bit0 */ uint8_t dcSideOffStatus:1;               /* 1: отключена сторона постоянного тока (DC-выход) */
	/* Bit1 */ uint8_t moduleFaultAlarm:1;              /* 1: общая авария модуля */
	/* Bit2 */ uint8_t moduleProtectionAlarm:1;         /* 1: сработала защита модуля */
	/* Bit3 */ uint8_t fanFaultAlarm:1;                 /* 1: авария вентилятора */
	/* Bit4 */ uint8_t overTempAlarm:1;                 /* 1: перегрев модуля */
	/* Bit5 */ uint8_t outputOverVoltageAlarm:1;        /* 1: перенапряжение на выходе */
	/* Bit6 */ uint8_t outputOverCurrentAlarm:1;        /* 1: сверхток на выходе */
	/* Bit7 */ uint8_t canCommunicationInterruptAlarm:1; /* 1: нарушение связи по CAN */
} PSU_Status1_t;

/* Status2 (состояние модуля N, таблица 2 — modularForm2) */
typedef struct{
	/* Bit0 */ uint8_t powerLimitStatus:1;             /* 1: активен режим ограничения мощности */
	/* Bit1 */ uint8_t moduleAddressDuplicate:1;        /* 1: дублирование адреса модуля */
	/* Bit2 */ uint8_t severeUnevenFlowFault:1;         /* 1: сильный перекос токораспределения между модулями */
	/* Bit3 */ uint8_t threePhaseInputPhaseLossAlarm:1; /* 1: авария по пропаданию фазы трёхфазного входа */
	/* Bit4 */ uint8_t threePhaseInputUnbalanceAlarm:1; /* 1: авария по разбалансу трёхфазного входа */
	/* Bit5 */ uint8_t inputUnderVoltageAlarm:1;        /* 1: пониженное напряжение на входе */
	/* Bit6 */ uint8_t inputOverVoltageAlarm:1;         /* 1: повышенное напряжение на входе */
	/* Bit7 */ uint8_t pfcSideOffStatus:1;              /* 1: отключена сторона PFC */
} PSU_Status2_t;

typedef struct {
	uint8_t  enableAC;       // состояние AC-контактора (желание)
	uint8_t  enableOutput;   // разрешение выхода модуля (желание)
	uint16_t outputVoltage;  // измеренное выходное напряжение [В]
	int16_t  outputCurrent;  // измеренный выходной ток [0.1 А]
	uint8_t  temperature;    // температура модуля

	PSU_State_t state;       // состояние силового модуля и контакторов

	uint8_t  online;         // модуль в сети (есть телеметрия)
	uint8_t  ready;          // модуль готов к работе (online && нет ошибок)
	uint8_t  PSU_enabled;    // на выходе есть напряжение (> порога)
	uint8_t  CONT_enabled;   // DC-контактор замкнут (по обратной связи)
	uint8_t  cont_fault;          // внутренняя ошибка контакторов
	uint8_t  psu_fault;          // внутренняя ошибка силового модуля

	uint32_t statetick;      // время входа в состояние

	// Дополнительные параметры для одного модуля DC30
	uint32_t power_limit;    // лимит мощности [кВт]
	uint8_t  hv_mode;        // HV-режим (ограничение напряжения)
	uint32_t hv_tick;        // таймер для задержки входа в HV-режим

	uint32_t tempAmbient;    // температура окружающего воздуха (из PSU_04)
	union { uint8_t raw; PSU_Status0_t bits; } status0;  // modularForm0
	union { uint8_t raw; PSU_Status1_t bits; } status1;  // modularForm1
	union { uint8_t raw; PSU_Status2_t bits; } status2;  // modularForm2
} PSU_t;

extern PSU_t PSU0;

void PSU_Task(void);

#pragma pack(push, 1)

typedef struct{
	uint8_t source:8;
	uint8_t destination:8;
	uint8_t command:6;
	uint8_t device:4;
	uint8_t error:3;

}CanId_t;

typedef struct{
	uint8_t rsvd0[2];
	uint16_t moduleNumber;
	uint8_t rsvd1[5];
}PSU_02_t;

typedef struct{
	uint8_t rsvd0[2];
	uint16_t moduleGroupNumber;
	uint8_t moduleTemperature;
	uint8_t rsvd1;
	uint8_t modularForm2;
	uint8_t modularForm1;
	uint8_t modularForm0;
}PSU_04_t;

typedef struct{
	uint8_t VABHi;
	uint8_t VABLo;
	uint8_t VBCHi;
	uint8_t VBCLo;
	uint8_t VCAHi;
	uint8_t VCALo;
	uint8_t rsvd1[2];

	uint32_t VAB;
	uint32_t VBC;
	uint32_t VCA;
}PSU_06_t;

typedef struct{
	uint32_t totalSystemVoltage;
	uint32_t totalSystemCurrent;
}PSU_08_t;

typedef struct{
	uint8_t moduleNVoltage_[4];
	uint8_t moduleNCurrent_[4];
	uint32_t moduleNVoltage;
	uint32_t moduleNCurrent;
}PSU_09_t;

// setup

typedef struct{
	uint8_t enable;
	uint8_t rsvd1[7];
}PSU_1A_t;

typedef struct{
	uint8_t moduleVoltage[4];
	uint8_t moduleCurrentTotal[4];
}PSU_1B_t;

//typedef struct{
//	uint32_t moduleVoltage;
//	uint32_t moduleCurrentTotal;
//}PSU_1B_t;

typedef struct{
	uint8_t moduleVoltage[4];
	uint8_t moduleCurrentTotal[4];
}PSU_1C_t;

typedef struct{
	uint8_t enable;
	uint8_t rsvd1[7];
}PSU_1D_t;

extern PSU_02_t PSU_02;
extern PSU_04_t PSU_04;
extern PSU_06_t PSU_06;
extern PSU_08_t PSU_08;
extern PSU_09_t PSU_09;

extern PSU_1A_t PSU_1A;
extern PSU_1B_t PSU_1B;
extern PSU_1C_t PSU_1C;

#pragma pack(pop)
