/******************************************************************
 * @file  nr_common_fuc.c
 * @brief:    [file description] 
 * @author: xuekun.zhang
 * @Date 2021年1月26日
 * COPYRIGHT NOTICE: (c) smartlogictech. All rights reserved. 
 * Change_date         Owner         Change_content
 * 2021年1月26日        xuekun.zhang       create file

*****************************************************************/

/**************************include******************************/
#include "common.h"
#include <malloc.h>
#include "mem_def.h"

/**************************function******************************/

 /*!   
 * @brief:  
 * @author:  bo.liu
 * @Date:  2021年2月3日
 * @param: a_numerator :      [param description ]
 * @param: a_denominator :    [param description ]
 */
int ceil_fix(int a_numerator, int a_denominator)
{
	int quo, rem;
	quo = a_numerator / a_denominator;
	rem = a_numerator - quo * a_denominator;
  if((rem != 0) && (a_numerator > 0))
  {
    return (quo + 1);
  }
  else
  {
  	return quo;
  }
}

/*!   
* @brief:  
* @author:  yufei.wang
* @Date:  2022年11月9日
* @param: a_numerator :      [param description ]
* @param: a_denominator :    [param description ]
*/
int64_t floor_long_fix(int64_t a_numerator, int64_t a_denominator)
{
    int64_t quo, rem;
    if((0 == a_numerator) || (0 == a_denominator))
    {
        return 0;
    }
    quo = a_numerator / a_denominator;
    rem = a_numerator - quo * a_denominator;
    if((rem != 0) && (((a_numerator < 0) && (a_denominator > 0))|| ((a_numerator > 0) && (a_denominator < 0))))
    {
        return (quo - 1);
    }
    else
    {
        return quo;
    }
}

/*!   
 * @brief:  
 * @author:  yufei.wang
 * @Date:	2022年2月11日
 * @param: a_numerator :	   [param description ]
 * @param: a_denominator :    [param description ]
 */
uint64_t ceil_long_fix(uint64_t a_numerator, uint64_t a_denominator)
{
    uint64_t quo = 0;
    uint64_t rem = 0;

    quo = a_numerator / a_denominator;
    rem = a_numerator - quo * a_denominator;

    if(rem != 0)
    {
        return (quo + 1);
    }
    else
    {
        return quo;
    }
}
 
 /*!   
 * @brief:  
 * @author:  bo.liu
 * @Date:  2021年2月3日
 * @param: a_numerator :      [param description ]
 * @param: a_denominator :    [param description ]
 */
int floor_fix(int a_numerator, int a_denominator)
{
    int quo, rem;
    quo = a_numerator / a_denominator;
    rem = a_numerator - quo * a_denominator;
    if((rem != 0) && (a_numerator < 0))
    {
        return (quo - 1);
    }
    else
    {
        return quo;
    }
} 

/*!   
  * @brief: 就近取整
  * @author:  yufei.wang
  * @Date:	2023年3月3日
  * @param: a_numerator :	   [param description ]
  * @param: a_denominator :    [param description ]
  */
 int round_fix(int a_numerator, int a_denominator)
 {
	 int abs_a = 0;
	 int abs_a_d = 0;
	 int quo = 0;
	 int rem = 0;
 
	 if (0 == a_denominator)
	 {
		 return 0;
	 }
 
	 abs_a = __ucps2_abs(a_numerator);
	 abs_a_d = __ucps2_abs(a_denominator);
 
	 //统一到正值进行处理
	 quo = abs_a / abs_a_d; //默认向下取整
	 rem = abs_a - (quo*abs_a_d);
	 if ((rem<<1) > abs_a_d) //余数大于被除数的一半
	 {
		 //向上取整
		 quo += 1;
	 }
	 else //余数小于被除数的一半,向下取整
	 {
	 }
 
	 //确定符号位
	 if (((a_numerator < 0) && (a_denominator < 0)) 
		  || ((a_numerator > 0) && (a_denominator > 0)))
	 {
		 return quo;
	 }
	 else
	 {
		 return (-quo);
	 }
 }


/*! 
  * @brief:  CRC6Check
  * 		 CRC6校验计算
  * @author:  chunmeng.li
  * @Date:	2022年1月27日
  * @param: *dataIn :		   [input data, bit sequence form lsb to msb ]
  * @param: *crc6Lut :		   [crc lut 256 bytes ]
  * @param: bitLen :		   [number of valid bits in dataIn, include crc, 18~25 ]
  * Performance:
  * 	44 + 71 * nPath
 */
 uint8_t CRC6Check(uint32_t *dataIn, uint8_t *crc6Lut, uint8_t bitLen, uint32_t **dataOut)
 {
	 uint32_t byteIn, scCnt;
	 uint32_t *dataInPtr = dataIn;
	 uint32_t nbitPad = 32 - bitLen;
	 uint8_t crcRes, divend;
 
	 for (scCnt = 0; scCnt < 8; scCnt++)
	 {
		 byteIn = (*dataInPtr) << nbitPad;
		 divend = byteIn;
		 crcRes = crc6Lut[divend];
		 divend = (byteIn >> 8) ^ crcRes;
		 crcRes = crc6Lut[divend];
		 divend = (byteIn >> 16) ^ crcRes;
		 crcRes = crc6Lut[divend];
		 divend = (byteIn >> 24) ^ crcRes;
		 if (crc6Lut[divend] == 0)
		 {
			 *dataInPtr = byteIn >> nbitPad;
			 *dataOut = dataInPtr;
			 return 1;
		 }
		 dataInPtr += 48; //data length for one path is 192 Bytes
	 }
	 *dataOut = dataIn;
	 return 0;
 }

 /*!   
 * @brief: 通过泰勒拟合求10*log10(value)， 上行信道公用函数
 * @author:  yufei.wang
 * @Date:  2022年5月30日
 * @param: real_value :       [带有标值的功率输入，可以是16位或者32位 ]
 * @param: Q_in :             [输入功率的标值 ]
 * @param: Q_out :            [输出标值]
 */
int16_t Calc_10Log10(int32_t real_value, uint8_t Q_in, uint8_t Q_out)
{
    uint32_t index;
    int32_t log2_real_value;
    int16_t dB_value;
    int32_t real_value_DQ;
    int32_t deltax;
    int32_t mul;
    uint8_t Q_delta;
    int32_t dB_value_tmp;
    int32_t Value_Comp;

    //求取real_value的first1
    log2_real_value = (31 - 14) - __builtin_clz(real_value);//-14~16

    //将输入的real_value移到16位
    real_value_DQ = (int16_t)(real_value >> log2_real_value);//16384~32767
    //计算出x0,k0,k1在查找表的index
    index = ((real_value_DQ - 16384)  >> 9) & 0x1F;//0~31
    deltax = real_value_DQ - c_tb_dB[index][0];
    mul = (deltax * c_tb_dB[index][1]) >> 13;
    dB_value_tmp = (mul + c_tb_dB[index][2]) << (Q_out-13);
    //Q_delta的取值范围为8~69,作为value_comp_table的索引
    Q_delta = Q_in - log2_real_value + (38 - 14);//8~69, 0<= Q_in <= 31
    Value_Comp = (int32_t)c_dBcal_value_comp_table[Q_delta] << (Q_out-8);
    dB_value = dB_value_tmp - Value_Comp;
    return real_value ? dB_value : -32768; //标值为Q(16, Q_out)
}


 /*!   
 * @brief:  
 * @author:  bo.liu
 * @Date:  2021年2月3日
 * @param: len :              [数据长度 ]
 * @param: dm_index :         [DM 空间]
 */
int * dmalloc_unit(uint32_t len, uint8_t dm_index)
{
	//int dmalloced,freeSpace;
	int *val_ptr = NULLPTR;
	int  have_allocated_byte = 0;

	__ucps2_IntEn(f_Disable);
	val_ptr = (int *)dmalloc(len, dm_index);
	__ucps2_IntEn(f_Enable);
	if(val_ptr)
	{
	}
	else 
	{
        have_allocated_byte = getMemoryMalloced(dm_index);

	}
	return val_ptr;
}


 /*!   
 * @brief:  
 * @author:  bo.liu
 * @Date:  2021年2月3日
 * @param: align_addr :       [字节对齐数 ]
 * @param: len :              [数据长度 ]
 * @param: dm_index :         [DM 空间 ]
 */
int * dmemalign_unit(uint32_t align_addr, uint32_t len, uint8_t dm_index)
{
	int dmalloced,freeSpace;
	int *val_ptr;
	int  have_allocated_byte = getMemoryMalloced(dm_index);

    __ucps2_IntEn(f_Disable);
	val_ptr = (int *)dmemalign(align_addr, len, dm_index);
	__ucps2_IntEn(f_Enable);


	return val_ptr;
}


/*!   
* @brief:	
* @author:  bo.liu
* @Date:  2021年2月3日
* @param: *val_ptr :		  [数据指针]
* @param: dm_index :		  [DM 空间 ]
*/
void dfree_unit(int *val_ptr, uint8_t dm_index)
{
	int dmalloced,freeSpace;
	
    __ucps2_IntEn(f_Disable);
	dfree(val_ptr);
	__ucps2_IntEn(f_Enable);

}


