/*******************************************************************************
*
*
* File:        tau_common.h
* Description  通用数据类型相关定义头文件
* Version      V0.1
* Date         2020-09-07
* Author       lzy
 *******************************************************************************/

#ifndef __TAU_COMMON_H
#define __TAU_COMMON_H

/*******************************************************************************
* 1.Included files
*******************************************************************************/
#include "stdint.h"
#include "math.h"

/*******************************************************************************
* 2.Global constant and macro definitions using #define
*******************************************************************************/
/**
 * \name 通用常量定义
 * @{
 */
//#define ENABLE 1
//#define DISABLE 0

#define ON 1
#define OFF 0

#define NONE 0
#define EOS '\0'

/*
#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif
*/

#ifndef __cplusplus
#define true    1
#define false   0
#define bool    _Bool
#endif /* ifndef __cplusplus */

#ifndef NULL
#define NULL ((void *)0)
#endif

#define TAU_LITTLE_ENDIAN 1234    /**< \brief 小端模式     */
#define TAU_BIG_ENDIAN    3412    /**< \brief 大端模式         */

/** @} */

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

/**
 * \name 常用宏定义
 * @{
 */

#ifdef __cplusplus
#define __I  volatile         /*!< Defines 'read only' permissions */
#else
#define __I  volatile const   /*!< Defines 'read only' permissions */
#endif
#define __O  volatile         /*!< Defines 'write only' permissions */
#define __IO volatile         /*!< Defines 'read / write' permissions */

#define TAU_INLINE inline
#define TAU_STATIC_INLINE static inline
#define TAU_STATIC static
#define TAU_CONST const
#define TAU_EXTERN extern

#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))

/**
 * \brief 求结构体成员的偏移
 * \attention 不同平台上，由于成员大小和内存对齐等原因，
 *            同一结构体成员的偏移可能是不一样的
 *
 * \par 示例
 * \code
 *  struct my_struct {
 *      int  m1;
 *      char m2;
 *  };
 *  int offset_m2;
 *
 *  offset_m2 = TAU_OFFSET(struct my_struct, m2);
 * \endcode
 */
#define TAU_OFFSET(structure, member) ((uint32_t)(&(((structure *)0)->member)))

/** @} */

/**
 * \brief 通过结构体成员指针获取包含该结构体成员的结构体
 *
 * \param ptr    指向结构体成员的指针
 * \param type   结构体类型
 * \param member 结构体中该成员的名称
 *
 * \par 示例
 * \code
 *  struct my_struct = {
 *      int  m1;
 *      char m2;
 *  };
 *  struct my_struct  my_st;
 *  char             *p_m2 = &my_st.m2;
 *  struct my_struct *p_st = TAU_CONTAINER_OF(p_m2, struct my_struct, m2);
 * \endcode
 */
#define TAU_CONTAINER_OF(ptr, type, member)                                    \
    ((type *)((char *)(ptr)-TAU_OFFSET(type, member)))

/**
 * \brief 计算结构体成员的大小
 *
 * \code
 *  struct a = {
 *      uint32_t m1;
 *      uint32_t m2;
 *  };
 *  int size_m2;
 *
 *  size_m2 = TAU_MEMBER_SIZE(a, m2);   //size_m2 = 4
 * \endcode
 */
#define TAU_MEMBER_SIZE(structure, member) (sizeof(((structure *)0)->member))

/**
 * \brief 计算数组元素个数
 *
 * \code
 *  int a[] = {0, 1, 2, 3};
 *  int element_a = TAU_NELEMENTS(a);    // element_a = 4
 * \endcode
 */
#define TAU_NELEMENTS(array) (sizeof(array) / sizeof((array)[0]))

/**
 * \brief 向上舍入
 *
 * \param x     被运算的数
 * \param align 对齐因素
 *
 * \code
 * int size = TAU_ROUND_UP(15, 4);   // size = 16
 * \endcode
 */
#define TAU_ROUND_UP(x, align) (((int)(x)/(align))*(align) + (((int)(x)%(align)) ? (align) : 0))

/**
 * \brief 向下舍入
 *
 * \param x     被运算的数
 * \param align 对齐因素
 *
 * \code
 * int size = TAU_ROUND_DOWN(15, 4);   // size = 12
 * \endcode
 */
#define TAU_ROUND_DOWN(x, align) (((int)(x)/(align))*(align))

/** \brief 倍数向上舍入 */
#define TAU_DIV_ROUND_UP(n, d) (((n) + (d)-1) / (d))

/**
 * \brief 测试是否对齐
 *
 * \param x     被运算的数
 * \param align 对齐因素，必须为2的乘方
 *
 * \code
 * if (TAU_ALIGNED(x, 4) {
 *     ; // x对齐
 * } else {
 *     ; // x不对齐
 * }
 * \endcode
 */
#define TAU_ALIGNED(x, align) (((int)(x) & (align - 1)) == 0)

/** \brief 将1字节BCD数据转换为16进制数据 */
#define TAU_BCD_TO_HEX(val) (((val)&0x0f) + ((val) >> 4) * 10)

/** \brief 将1字节16进制数据转换为BCD数据 */
#define TAU_HEX_TO_BCD(val) ((((val) / 10) << 4) + (val) % 10)

/**
 * \brief 向上取整
 */
#define TAU_CEIL(val) ceil(val)


/*! @brief Construct the version number for drivers. */
#define MAKE_VERSION(major, minor, bugfix) (((major) << 16) | ((minor) << 8) | (bugfix))


/*******************************************************************************
* 3.Global structures, unions and enumerations using typedef
*******************************************************************************/
/*!< @brief 用于返回状态和错误 */
typedef uint32_t status_t;

/* \brief 通用回调函数指针定义 */
typedef void (*fcb_type)(void *data);

typedef void (*uart_trans_cb)(status_t status, void *user_data);

typedef void (*flash_trans_cb)(status_t status, void *user_data);
#endif /* __TAU_COMMON_H */
