/*
 * 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 _RESOLVER_H_
#define _RESOLVER_H_

/*! \brief  Contains the public interface to the resolver
 *          abstract class. This would also cover the usage of
 *          MagnetoResistance position sensor
 */

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

#include <stdint.h>
#include <stdbool.h>
#include "common/iqmath/iqmath.h"
#include "common/pid/pid.h"
#include "common/filter/iir_fo.h"

#ifdef __cplusplus
extern "C" {
#endif

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

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

/*! \brief  Defines the Resolver parameters
 *  \note   The pole pair scale should not > 128
 */
typedef struct _Resolver_ParamsType_
{
    float    polePairScale;     /*!< Pole pair of the motor / Pole pair of the resolver */
    uint16_t reverseDir;        /*!< Set this value other than 0 will reverse the positive direction, default to use 0 */
    float    phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */
    float    spdCalcFreq_kHz;   /*!< Frequency to run phase calculation */
    float    fBase_Hz;          /*!< Base value of frequency used for P.U. */
    float    responseSpeed_rps; /*!< The response speed in rad/s */
    float    spdFilterPole_rps; /*!< Pole value of speed filter calculation */
} Resolver_ParamsType;

/*! \brief  Defines the dynamic parameters used to update RESOLVER object
 */
typedef struct _Resolver_DynamicParamsType_
{
    float phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */
    float spdCalcFreq_kHz;   /*!< Frequency to run phase calculation */
} Resolver_DynamicParamsType;

/*! \brief Defines the Resolver object
 */
typedef struct _ResolverType_
{
    _iq sin_pu; /*!< Input: The sin value in P.U. */
    _iq cos_pu; /*!< Input: The cos value in P.U. */

    _iq      error;             /*!< Parameter: error to calculate angle from speed */
    _iq      angleFactor;       /*!< Parameter: Factor to calculate angle from speed */
    _iq      polePairScale;     /*!< Parameter: Pole pair of the motor / Pole pair of the resolver */
    uint16_t reverseDir;        /*!< Parameter: Set this value other than 0 will reverse the positive direction, default to use 0 */
    float    phaseCalcFreq_kHz; /*!< Parameter: Frequency to run phase calculation */
    float    spdCalcFreq_kHz;   /*!< Parameter: Frequency to run phase calculation */

    uint16_t  polePairScaleFactor; /*!< Internal variable: The factor for pole pair scale */
    bool      firstCalcStatus;     /*!< Internal variable: The PLL PID first calculate status */
    PidType   pidPLL;              /*!< Internal variable: The PLL PID */
    IirFoType filterSpd;           /*!< Internal Variable: The filter for electric speed calculation */
    _iq       rawSpeed_pu;         /*!< Internal variable: The raw speed before filter in P.U. */
    _iq       currentAngle_pu;     /*!< Internal variable: The angle represented by input */
    _iq       nextAngle_pu;        /*!< Internal variable: The angle represented by input */

    _iq angle_pu; /*!< Output: The electrical angle in P.U. */
    _iq speed_pu; /*!< Output: The speed in P.U. */
} ResolverType;

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

/*! \brief Initialize resolver
 *
 * This function initalizes resolver by setting configuration parameters
 *
 * \param[in] obj : pointer to Resolver instance
 * \param[in] pParams : pointer to Resolver configuration parameters
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Resolver_Init(ResolverType *obj, const Resolver_ParamsType *pParams);

/*! \brief Run the resolver the calculate the phase
 *         for PARK and IPARK module
 *  \note   Must run in the same frequency with current control loop
 *
 * \param[in] obj : pointer to Resolver instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Resolver_CalcPhase(ResolverType *obj);

/*! \brief  Calculate the speed
 *  \note   Might run slower than current control frequency
 *
 *
 * \param[in] obj : pointer to Resolver instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Resolver_CalcSpeed(ResolverType *obj);

/*! \brief Update the parameters of Resolver
 *
 * This function updates the Resolver function configuration parameters
 *
 * \param[in] obj : pointer to Resolver instance
 * \param[in] pParams : pointer to control configuration paramter
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Resolver_UpdateParams(ResolverType *obj, const Resolver_DynamicParamsType *pParams);

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

#endif /* _RESOLVER_H_ */
