/**
  ******************************************************************************
  * @file    kpm32xx_ddl_tmu.c
  * @author  Kiwi Software Team
  * @brief   TMU DDL module driver.
  *          This file provides firmware functions to manage the following
  *          functionalities of the internal TMU calculate:
  *          + sin calculate functions
  *          + cos calculate functions
  *          + arctan calculate functions
  * @note
  *          V1.0.0, 2024/12/20.
  *
  * Copyright (c) 2024, Kiwi Instruments Co,. Ltd.
  *
  * Redistribution and use in source and binary forms, with or without modification,
  * are permitted provided that the following conditions are met:
  *
  *   1. Redistributions of source code must retain the above copyright notice,
  *      this list of conditions and the following disclaimer.
  *
  *   2. Redistributions in binary form must reproduce the above copyright notice,
  *      this list of conditions and the following disclaimer in the documentation
  *      and/or other materials provided with the distribution.
  *
  *   3. Neither the name of the copyright holder nor the names of its contributors
  *      may be used to endorse or promote products derived from this software without
  *      specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
  * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  * THE POSSIBILITY OF SUCH DAMAGE.
  ******************************************************************************
  */
#include "kpm32xx_ddl.h"

#ifdef DDL_TMU_MODULE_ENABLED


/**
  * @brief  initialize TMU peripheral.
  * @param  htmu  pointer to TMU_Type structure.
  *
  * @retval none
  */
void DDL_TMU_Init(TMU_Type *htmu)
{
	/* Enable TMU */
	htmu->CTRL |= TMU_CTRL_EN;
}


/**
  * @brief  Deinitialize TMU peripheral.
  * @param  htmu  pointer to TMU_Type structure.
  *
  * @retval none
  */
void DDL_TMU_DeInit(TMU_Type *htmu)
{
	/* Disable TMU */
	htmu->CTRL &= ~(TMU_CTRL_EN);
}


/**
  * @brief  get both Cosine value in float format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  fltAngle  Angle in float.
  * @param  fltSinVal pointer to the Sine value in float.
  * @param  fltCosVal pointer to the Cosine value in float.
  *
  * @retval none
  */
void DDL_TMU_Cosin_Sine_Flt(TMU_Type *htmu, float fltAngle, float *fltCosVal, float *fltSinVal)
{
	htmu->AGLF = *(volatile uint32_t *)((uint32_t)(&fltAngle));
	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*fltCosVal = *(volatile float *)(&(htmu->COSF));
	*fltSinVal = *(volatile float *)(&(htmu->SINF));
}


/**
  * @brief  get both Cosine value in float format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  fltAngle  Angle in float.
  * @param  fltSinVal pointer to the Sine value in float.
  *
  * @retval none
  */
void DDL_TMU_Sine_Flt(TMU_Type *htmu, float fltAngle, float *fltSinVal)
{
	htmu->AGLF =  *(volatile uint32_t *)((uint32_t)(&fltAngle));
	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*fltSinVal = *(volatile float *)(&(htmu->SINF));
}


/**
  * @brief  get both Cosine value in float format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  fltAngle  Angle in float.
  * @param  fltCosVal pointer to the Cosine value in float.
  *
  * @retval none
  */
void DDL_TMU_Cosin_Flt(TMU_Type *htmu, float fltAngle, float *fltCosVal)
{
	htmu->AGLF =  *(volatile uint32_t *)((uint32_t)(&fltAngle));
	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*fltCosVal = *(volatile float *)(&(htmu->COSF));
}


/**
  * @brief  get both Sine & Cosine value in Q24 Fixed format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  q24Angle  Angle in Q24.
  * @param  q24CosVal pointer to the Cosine value in Q24.
  * @param  q24SinVal pointer to the Sine value in Q24.
  *
  * @retval none
  */
void DDL_TMU_Cosin_Sine_Q24Fix(TMU_Type *htmu, uint32_t q24Angle, uint32_t *q24CosVal, uint32_t *q24SinVal)
{
	htmu->AGLB = q24Angle;
	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*q24CosVal = htmu->COSB;
	*q24SinVal = htmu->SINB;
}


/**
  * @brief  get the Sine value in Q24 Fixed format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  q24Angle  Angle in Q24.
  * @param  q24CosVal pointer to the Sine value in Q24.
  *
  * @retval none
  */
void DDL_TMU_Sine_Q24Fix(TMU_Type *htmu, uint32_t q24Angle, uint32_t *q24SinVal)
{
	htmu->AGLB = q24Angle;
	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*q24SinVal = htmu->SINB;
}


/**
  * @brief  get the Cosine value in Q24 Fixed format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  q24Angle  Angle in Q24.
  * @param  q24CosVal pointer to the cosine value in Q24.
  *
  * @retval none
  */
void DDL_TMU_Cosin_Q24Fix(TMU_Type *htmu, uint32_t q24Angle, uint32_t *q24CosVal)
{
	htmu->AGLB = q24Angle;
	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*q24CosVal = htmu->COSB;
}


/**
  * @brief  get the ArcTan value in float format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  fltx   x in float ranging from -65536 ~ 65535.999969482
  * @param  flty   y in float ranging from -65536 ~ 65535.999969482
  * @param  q16Angle  pointer to the angle in float.
  *
  * @retval none
  */
void DDL_TMU_ArcTan_Flt(TMU_Type *htmu, float *fltAngle, float fltx, float flty)
{
	htmu->COSF =  *(volatile uint32_t *)((uint32_t)(&fltx));
	htmu->SINF =  *(volatile uint32_t *)((uint32_t)(&flty));

	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*fltAngle = *(volatile float *)(&(htmu->AGLF));
}


/**
  * @brief  get the ArcTan value in Q24 Fixed format.
  * @param  htmu   pointer to TMU_Type structure.
  * @param  x   x in Qx (x = 0 ~ 30).
  * @param  y   y in Qx (x = 0 ~ 30).
  * @param  q24Angle  pointer to the angle in Q24.
  *
  * @retval none
  */
void DDL_TMU_ArcTan_Fix(TMU_Type *htmu, uint32_t *q24Angle, uint32_t x, uint32_t y)
{
	htmu->COSB = x;
	htmu->SINB = y;

	/* Wait Calculation done */
	while(htmu->ST & TMU_ST_BUSY);

	*q24Angle = htmu->AGLB;
}

#endif /* DDL_TMU_MODULE_ENABLED */

