/*
 * Copyright (c) 2022, Shenzhen CVA Innovation CO.,LTD
 * All rights reserved.
 *
 * Shenzhen CVA Innovation CO.,LTD (CVA chip) is supplying this file for use
 * exclusively with CVA's microcontroller products. This file can be freely
 * distributed within development tools that are supporting such microcontroller
 * products.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES, WHETHER EXPRESS, IMPLIED
 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
 * CVA SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL,
 * OR CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 */

#ifndef _FAST_H_
#define _FAST_H_

/*! \brief Contains public interface to various functions related
 *         to the Flux, Angle, Speed, Torque estimation (FAST) modules
 */

/*******************************************************************************
 * the includes
 ******************************************************************************/

#include <stdint.h>
#include "common/iqmath/iqmath.h"
#include "common/pid/pid.h"
#include "common/filter/iir_fo.h"
#include "md_lib/clarke/clarke.h"
#include "md_lib/park/park.h"

#ifdef __cplusplus
extern "C" {
#endif

/*******************************************************************************
 * the defines
 ******************************************************************************/

/*******************************************************************************
 * the typedefs
 ******************************************************************************/

/*! \brief Fast prototype definition
 */
typedef struct _Fast_ParamsType_
{
    uint32_t polePairs;          /*!< Pole pairs of the motor */
    float    runFreq_kHz;        /*!< Frequency to run the process */
    float    Rs_Ohm;             /*!< Stationary resistance in Ohm */
    float    Ld_mH;              /*!< d-axis inductance in mH */
    float    Lq_mH;              /*!< q-axis inductance in mH */
    float    fBase_Hz;           /*!< Base value of frequency used for P.U. */
    float    VBase_V;            /*!< Base value of voltage used for P.U. */
    float    IBase_A;            /*!< Base value of current used for P.U. */
    float    torqueBase_Nm;      /*!< Base value of torque used for P.U. */
    float    spdFilterPole_rps;  /*!< Pole value of speed filter calculation */
    float    dirFilterPole_rps;  /*!< Pole value of speed direction filter calculation */
    float    fluxFilterPole_rps; /*!< Pole value of flux filter calculation */
    float    ratedVdc_V;         /*!< The rated phase-to-ground voltage */
    float    fstCalcFreq_kHz;    /*!< The calculation frequency of flux, speed and torque */
    float    minElecFreq_Hz;     /*!< The min speed supported in Hz */
    float    fluxBase_Wb;        /*!< Base value of current used for P.U. */
    float    defaultFlux_Wb;     /*!< The default value of flux in Wb */
    float    gain;               /*!< Controller Gain (0.0 to 0.9999) */
    float    linearError;        /*!< Controller Max allowed linear error (0.0 to 0.9999) */
    float    dampingFactor;      /*!< Damping factor of controller */
} Fast_ParamsType;

/*! \brief Defines the dynamic parameters used to update Fast object
 */
typedef struct _Fast_DynamicParamsType_
{
    float runFreq_kHz; /*!< Frequency to run the process */
    float Rs_Ohm;      /*!< Stationary resistance in Ohm */
    float Ld_mH;       /*!< d-axis inductance in mH */
    float Lq_mH;       /*!< q-axis inductance in mH */
    float fBase_Hz;    /*!< Base value of frequency used for P.U. */
    float VBase_V;     /*!< Base value of voltage used for P.U. */
    float IBase_A;     /*!< Base value of current used for P.U. */
} Fast_DynamicParamsType;

/*! \brief  Defines the Fast type
 */
typedef struct _FastType_
{
    _iq Ia_pu; /*!< Input: The Stationary current of phase A */
    _iq Ib_pu; /*!< Input: The Stationary current of phase B */
    _iq Ic_pu; /*!< Input: The Stationary current of phase C */
    _iq Va_pu; /*!< Input: The Stationary voltage of phase A */
    _iq Vb_pu; /*!< Input: The Stationary voltage of phase B */
    _iq Vc_pu; /*!< Input: The Stationary voltage of phase C */

    _iq Fdsmo;          /*!< Parameter: Motor dependent control gain */
    _iq Fqsmo;          /*!< Parameter: Motor dependent control gain */
    _iq Gdsmo;          /*!< Parameter: Motor dependent control gain */
    _iq Gqsmo;          /*!< Parameter: Motor dependent control gain */
    _iq Kdsmo;          /*!< Parameter: Motor dependent control gain */
    _iq Kqsmo;          /*!< Parameter: Motor dependent control gain */
    _iq Kslide;         /*!< Parameter: Sliding control gain */
    _iq maxError;       /*!< Parameter: Maximum current error for linear SMC */
    _iq angleFactor;    /*!< Parameter: Factor to calculate angle from speed */
    _iq fluxFactor;     /*!< Parameter: Factor to calculate flux */
    _iq torqueFactor_I; /*!< Parameter: Current factor to calculate torque */
    _iq torqueFactor_F; /*!< Parameter: Flux factor to calculate torque */
    _iq minSpd_pu;      /*!< Parameter: Min electric speed in P.U. */
    _iq defaultFlux_pu; /*!< Parameter: The default value of flux in P.U. */

    _iq        Vd;              /*!< Internal Variable: The d-axis voltage */
    _iq        Vq;              /*!< Internal Variable: The q-axis voltage */
    _iq        Zd;              /*!< Internal Variable: Stationary d-axis sliding control */
    _iq        Zq;              /*!< Internal Variable: Stationary q-axis sliding control */
    _iq        Eq;              /*!< Internal Variable: Stationary q-axis back EMF */
    ClarkeType clarkeI;         /*!< Internal Variable: The clarke transform for current */
    ClarkeType clarkeV;         /*!< Internal Variable: The clarke transform for current */
    ParkType   parkI;           /*!< Internal Variable: The park transform for current */
    ParkType   parkV;           /*!< Internal Variable: The park transform for current */
    PidType    pidPLL;          /*!< Internal Variable: The PLL PID */
    _iq        Id;              /*!< Internal Variable: The d-axis current */
    _iq        Iq;              /*!< Internal Variable: The q-axis current */
    _iq        IdEst;           /*!< Internal Variable: Estimated d-axis current */
    _iq        IqEst;           /*!< Internal Variable: Estimated q-axis current */
    _iq        IdError;         /*!< Internal Variable: The d-axis current error */
    _iq        IqError;         /*!< Internal Variable: The q-axis current error */
    IirFoType  filterSpd;       /*!< Internal Variable: The filter for electric speed calculation */
    IirFoType  filterDir;       /*!< Internal Variable: The filter for speed direction detection */
    IirFoType  filterFlux;      /*!< Internal Variable: The filter for flux calculation */
    int16_t    spdDir;          /*!< Internal Variable: The actual speed direction; 1:forward, -1:backward */
    _iq        rawSpeed_pu;     /*!< Internal variable: The raw speed before filter in P.U. */
    _iq        currentAngle_pu; /*!< Internal variable: The angle for this control loop */
    _iq        nextAngle_pu;    /*!< Internal variable: The angle for next control loop */

    _iq angle_pu;  /*!< Output: The electric angle */
    _iq speed_pu;  /*!< Output: The filtered electric speed updated every electric period */
    _iq flux_pu;   /*!< Output: The flux of PM in P.U. */
    _iq torque_pu; /*!< Output: The electrical torque in P.U. */
} FastType;

/*******************************************************************************
 * the globals
 ******************************************************************************/

/*******************************************************************************
 * the function prototypes
 ******************************************************************************/

/*! \brief Initialize the FAST object
 *
 * This function initalizes Fast by setting configuration parameters
 *
 * \param[in] obj : pointer to Fast instance
 * \param[in] pParams : pointer to Fast configuration parameters
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Fast_Init(FastType *obj, const Fast_ParamsType *pParams);

/*! \brief Run the FAST
 *
 * This function runs Fast function, calculates Fast relevant value
 *
 * \param[in] obj : pointer to Fast instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Fast_Run(FastType *obj);

/*! \brief Calculates current motor speed
 *
 * This function calculates current motor speed based on Fast estimation parameters
 *
 * \param[in] obj : pointer to Fast instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Fast_CalcSpeed(FastType *obj);

/*! \brief Calculates current motor parameters
 *
 * This function calculates current motor flux and torque
 * based on Fast estimation parameters
 *
 * \param[in] obj : pointer to Fast instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Fast_CalcFluxAndTorque(FastType *obj);

/*! \brief Updates configuration parameters
 *
 * This function updates configuration parameters dynamically
 *
 * \param[in] obj : pointer to Fast instance
 * \param[in] pParams : pointer to Fast configuration parameters
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Fast_UpdateParams(FastType *obj, const Fast_DynamicParamsType *pParams);

/*! \brief Reset the Fast object
 *
 * This function resets the Fast relevant calculation parameters
 *
 * \param[in] obj : pointer to Fast instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Fast_Reset(FastType *obj);

#ifdef __cplusplus
}
#endif /* extern "C" */

#endif /* _FAST_H_ */
