/**
******************************************************************************
* @file pwm_thyristors.h
* @brief Модуль для управления тиристорами
******************************************************************************
*/
#ifndef _PWM_THYRISTORS_H
#define _PWM_THYRISTORS_H
#include "main.h"


/**
  * @brief Вкоючить хардварный способ формирования пачки импульсов
  * @note При отключении сильно возрастет нагрузка на контроллер из-за прерываний ШИМ!
  * Они поак работают всегда, независимо от того есть импулсь или нет
  */
#define PWM_HARDWARE_IMPULSES_CONTROL 


#define PWM_ENABLE    TIM_OCMODE_PWM2
#define PWM_DISABLE   TIM_OCMODE_FORCED_INACTIVE




// Индексы для структур каналов @ref PWM_Handle_t
#define PHASE_A_POS   0
#define PHASE_C_POS   1
#define PHASE_B_POS   2
#define PHASE_A_NEG   3
#define PHASE_C_NEG   4
#define PHASE_B_NEG   5
#define PHASE_UNKNOWN 6


#define PWM_PulseLengthToCnt(_length_, _period_) ((_length_)*(_period_)/

/** 
  * @brief Состояния канала
  */
typedef enum {
  PWM_THYR_DISABLED = 0,    ///< Канал отключен
  PWM_THYR_TIM_WAIT,        ///< Таймер ждет команды
  PWM_THYR_TIM_START,       ///< Запуск таймера для ШИМ
  PWM_THYR_TIM_ACTIVE,      ///< Таймер активен и формирует ШИМ
  PWM_THYR_TIM_DONE         ///< Таймер закончил свою работу в полупериоде
} PWM_State_t;

/** 
  * @brief Канал PWM (один тиристор) 
  */
typedef struct {
  PWM_State_t       State;    ///< Состояние тиристора  
  TIM_HandleTypeDef *htim;    ///< указатель на соответствующий TIM (hpwm1 или hpwm2)
  uint32_t          PulseCnt; ///< Счетчик кол-ва импульсов. Инициализируется из структуры @ref PWM_ThyrConfig_t
  uint32_t          ChMask;   ///< TIM_CHANNEL_x
  uint32_t          CurrentMode;   ///< Текущий режим канала

  struct {
    unsigned Ready:1;   ///< Флаг готовности тиристора к работе
  } f;
} PWM_Channel_t;

/** 
  * @brief Параметры ШИМ
  */
typedef struct {
  union
  {
    uint8_t all;
    struct
    {
      uint8_t phA:1;
      uint8_t phB:1;
      uint8_t phC:1;
    };
    }PhaseMask;           ///< Какими каналами управлять
  float     PulseLength;  ///< Длина импульса в о.е. от 180 градусов
  uint16_t  Frequency;    ///< Частота импульсов
  float     Duty;         ///< Скважность импульсов
} PWM_ThyrConfig_t;

/** 
  * @brief Хендл управляюзщий тиристорами */
typedef struct {  
  PWM_ThyrConfig_t Config;      ///< Конфигурации ШИМ
  PWM_Channel_t   *Phase[3];    ///< Каналы для активной в данный момент фазы
  PWM_Channel_t   AllPhases[7]; ///< Все каналы для фаз (+1 для деинициализированного канала)
  
  struct {
    unsigned Initialized : 1;
    unsigned Running     : 3;   ///< Сколько каналов запущено сейчас
  } f;
} PWM_Handle_t;


// ====== ИНИЦИАЛИЗАЦИЯ ==========
/* Инициализация ШИМ тиристоров. */
HAL_StatusTypeDef PWM_Init(PWM_Handle_t *hpwm);

// ====== УПРАВЛЕНИЕ ==========
/* Запуск ШИМ. */
HAL_StatusTypeDef PWM_Start(PWM_Handle_t *hpwm, UPP_Phase_t Phase);
/* Остановить ШИМ. */
HAL_StatusTypeDef PWM_Stop(PWM_Handle_t *hpwm, UPP_Phase_t Phase, uint8_t force_stop_all);
/* Установка частоты ШИМ. */
HAL_StatusTypeDef PWM_SetConfig(PWM_Handle_t *hpwm, uint8_t PhaseMask, uint16_t Frequency, float Duty, float PulseLength);
/* Установка полуволны для слежения. */
HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave);
/* Установка полярности шим. */
HAL_StatusTypeDef PWM_SetPolarity(PWM_Handle_t *hpwm, int polarity);
// ====== СЕРВИС ==========
/* Хендл ШИМ тиристоров. */
HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm, float PeriodMs);
#endif /* _PWM_THYRISTORS_H */
