/**
******************************************************************************
* @file pwm_thyristors.h
* @brief Модуль для управления тиристорами (объединённый 6-канальный)
******************************************************************************
*/
#ifndef _PWM_THYRISTORS_H
#define _PWM_THYRISTORS_H
#include "main.h"



  

#define PWM_TIM1_FREQ_MHZ 180
#define PWM_TIM3_FREQ_MHZ 90

#define PWM_ENABLE    TIM_OCMODE_PWM1
#define PWM_DISABLE   TIM_OCMODE_FORCED_ACTIVE


#define PWM_SetFrequency(_hpwm_, _freq_) \
do {  _hpwm_->Config.Frequency = _freq_; \
  __HAL_TIM_SET_AUTORELOAD(&hpwm1, TIM_FreqToTick(_freq_, PWM_TIM1_FREQ_MHZ)); \
  __HAL_TIM_SET_AUTORELOAD(&hpwm2, TIM_FreqToTick(_freq_, PWM_TIM3_FREQ_MHZ)); \
  __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_1, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
  __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_2, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
  __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_3, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
  __HAL_TIM_SET_COMPARE(&hpwm1, PWM_CHANNEL_4, __HAL_TIM_GET_AUTORELOAD(&hpwm1)/2); \
  __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_5, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2); \
  __HAL_TIM_SET_COMPARE(&hpwm2, PWM_CHANNEL_6, __HAL_TIM_GET_AUTORELOAD(&hpwm2)/2); }while(0);


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


/** 
  * @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

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

/** 
  * @brief Канал PWM (один тиристор) 
  */
typedef struct {
  union
  {
    uint8_t all;
    struct
    {
      uint8_t phA:1;
      uint8_t phB:1;
      uint8_t phC:1;
    };
    }PhaseMask;           ///< Какими каналами управлять
  uint8_t   PulseNumber;  ///< Сколько импульсов отправить в пакете для открытия тиристоров
  uint32_t  Frequency;    ///< Частота импульсов
} 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     : 1;   ///< true если оба таймера запущены
  } f;
} PWM_Handle_t;

/* ---- API ---- */
/* Инициализация ШИМ тиристоров. */
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);
/* Установка полуволны для слежения. */
HAL_StatusTypeDef PWM_SetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase, UPP_HalfWave_t halfwave);
/* Установка полуволны для слежения. */
UPP_HalfWave_t PWM_GetHalfWave(PWM_Handle_t *hpwm, UPP_Phase_t Phase);

/* Хендл ШИМ тиристоров. */
HAL_StatusTypeDef PWM_Handle(PWM_Handle_t *hpwm);
#endif /* _PWM_THYRISTORS_H */
