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

/*! \brief  Contains the public interface to the hall abstract class.
 */

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

#include <stdint.h>
#include <stdbool.h>
#include "common/iqmath/iqmath.h"
#include "common/filter/iir_fo.h"
#include "../fag/fag.h"
#ifdef __cplusplus
extern "C" {
#endif

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

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

/*! \brief  Defines the hall parameters
 */
typedef struct _Hall_ParamsType_
{
    float    phaseCalcFreq_kHz; /*!< Frequency to run phase calculation */
    float    spdCalcFreq_kHz;   /*!< Frequency to run speed calculation */
    float    fBase_Hz;          /*!< Base value of frequency used for P.U. */
    float    spdFilterPole_rps; /*!< Pole value of speed filter calculation */
    float    stamptimerFreq_Hz; /*!< Base clock source frequency */
    uint8_t*  pForwardHalSqe;   /*!< Hall value order */
    float    timeOutFreq_Hz;    /*!< Timeout detection frequency */
} Hall_ParamsType;

/*! \brief Defines the hall object
 */
typedef struct _HallType_
{
    uint8_t   halValue;           /*!< Input: Current hall value */
    uint32_t  timerCntDiff;       /*!< Input: Time of change hall value */
    uint32_t  dirRef;             /*!< Input: Desired direction at startup */

    _iq       hallAngleBuf_pu[7]; /*!< Parameter: Hall Angle value used for P.U */
    uint16_t  cntInCycle;         /*!< Parameter: Mechanical commutation threshold value */
    uint32_t  timerOutCnt;        /*!< Parameter: Time out count threshold value */
    float     spdCalCoef;         /*!< Parameter: Coefficient of speed calculation*/
    float     spdCalFastCoef;     /*!< Parameter: Coefficient of fast speed calculation*/

    _iq       halCalibAngle_pu;   /*!< Internal variable: Current hall value angle used for P.U */
    uint32_t  timerCntDiffCycle;  /*!< Internal variable: The time count after one turn of the electric angle */
    uint8_t   halValuePre;        /*!< Internal variable: previous hall value */
    bool      reStartFlag;        /*!< Internal variable: Start flag */
    int16_t   reStartCnt;         /*!< Internal variable: Start flag */
    uint16_t  commutationCnt;     /*!< Internal variable: Commutation count */
    FagType   hallEstObj;         /*!< Internal variable: Angle estimation object */
    FagType   startAngleObj;      /*!< Internal variable: Start Angle calculate object */
    uint32_t  timerCnt;           /*!< Internal variable: Running time counter */
    uint32_t  reStartTimerCnt;    /*!< Internal variable: Running time counter */
    _iq       rawSpeed_pu;        /*!< Internal variable: The raw speed before filter in P.U. */
    _iq       rawSpeedFast_pu;    /*!< Internal variable: The raw fast speed in P.U. */
    IirFoType filterSpd;          /*!< Internal Variable: The filter for electric speed calculation */

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

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

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

/*! \brief Calculate the angle for PARK and IPARK module
 *
 *  \note   Must run in the same frequency with current control loop
 *
 * \param[in] obj : pointer to hall instance
 * \return the MCUs authorized evaluation
 *         - -1 : Functions not available
 *         -  0 : Functions available
 */
extern int32_t Hall_EstAngle(HallType *obj);

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


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

#endif /* _HALL_H_ */
