/** * @file ALGO_AlgorithmBase_ATY.h * * @param Project ALGO_Algorithm_ATY_LIB * * @author ATY * * @copyright * - Copyright 2017 - 2025 MZ-ATY * - This code follows: * - MZ-ATY Various Contents Joint Statement - * * https://mengze.top/MZ-ATY_VCJS * - CC 4.0 BY-NC-SA - * * https://creativecommons.org/licenses/by-nc-sa/4.0/ * - Your use will be deemed to have accepted the terms of this statement. * * @brief Familiar functions of base algorithm * * @version * - 1_01_220601 > ATY * -# Preliminary version, first Release ******************************************************************************** */ #ifndef __ALGO_AlgorithmBase_ATY_H #define __ALGO_AlgorithmBase_ATY_H #include "INCLUDE_ATY.h" /******************************* For user *************************************/ // #define __DEBUG_ALGO_AlgorithmBase_ATY /******************************************************************************/ /* | **Type** | **16 bit platform** | **32 bit platform** | **64 bit platform** | |:---------------------:|:-------------------:|:-------------------:|:-------------------:| | **char** | 1 byte | 1 byte | 1 byte | | **short** | 2 byte | 2 byte | 2 byte | | **int** | 2 byte | 4 byte | 4 byte | | **unsigned int** | 2 byte | 4 byte | 4 byte | | **float** | 4 byte | 4 byte | 4 byte | | **double** | 8 byte | 8 byte | 8 byte | | **long** | 4 byte | 4 byte | 8 byte | | **long long** | 8 byte | 8 byte | 8 byte | | **unsigned long** | 4 byte | 4 byte | 8 byte | | **Pointer** | 2 byte | 4 byte | 8 byte | | **Max storage space** | 2^16 | 2^32 | 2^64 | */ /** * @brief Change num to str * @param num number to change */ #define ALGO_STR_DEF(num) #num #define ALGO_NUM_TO_STR(num) ALGO_STR_DEF(num) /** * @brief Allocate memory space * @param name variate name * @param type variate type */ #define ALGO_MALLOC(name, type) ((type *) malloc((name) * sizeof(type))) /** * @brief Get a byte at the specified address * @param addr address */ #define ALGO_MEM_BYTE(addr) (*((byte *)(addr))) /** * @brief Gets the number of specified bits * @param n bit position */ #define ALGO_BITMASK(n) ((uint32_t)1 << n) /** * @brief Get absolute value * @param x value to deal */ #define ALGO_ABS(x) ((x) > 0 ? (x) : -(x)) /** * @brief Get the max between 2 numbers * @param x value to deal * @param y value to deal */ #define ALGO_MAX(x, y) (((x) > (y)) ? (x) : (y)) /** * @brief Get the min between 2 numbers * @param x value to deal * @param y value to deal */ #define ALGO_MIN(x, y) (((x) < (y)) ? (x) : (y)) /** * @brief Converts a character to uppercase * @param c character to deal */ #define ALGO_UPCASE(c) (((c) >= 'a' && (c) <= 'z') ? ((c) - 0x20) : (c)) /** * @brief Determines if the character is a decimalism number * @param c character to deal */ #define ALGO_DECCHK(c) ((c) >= '0' && (c) <= '9') /** * @brief Determines if the character is a hexadecimal number * @param c character to deal */ #define ALGO_HEXCHK(c) \ (((c) >= '0' && (c) <= '9') \ || ((c) >= 'A' && (c) <= 'F') \ || ((c) >= 'a' && (c) <= 'f')) /** * @brief Returns the number of array elements * @param a array to deal */ #define ALGO_ARR_SIZE(a) (sizeof((a)) / sizeof((a[0]))) /** * @brief Combine two uint8 to one uint16 in LSB format * @param a high bit of uint16 * @param b low bit of uint16 */ #define ALGO_COMB16(a, b) ((((uint16_t)(a)) << 8) + (b)) /** * @brief Combine four uint8 to one uint32 in LSB format * @param a high bit of uint32 * @param b mid high bit of uint32 * @param c mid low bit of uint32 * @param d low bit of uint32 */ #define ALGO_COMB32(a, b, c, d) \ ((((uint32_t)(a)) << 24) \ + (((uint32_t)(b)) << 16)) \ + ((((uint32_t)(c)) << 8) + (d)) /** * @brief Get the low byte of a uint16 * @param x value to deal */ #define ALGO_UINT16_L(x) ((uint8_t)((uint16_t)(x) & 0xFF)) /** * @brief Get the high byte of a uint16 * @param x value to deal */ #define ALGO_UINT16_H(x) ((uint8_t)((uint16_t)(x) >> 8)) /** * @brief Change to a character * @param a value to deal * @note equal to add '', accept less than 3 characters */ #define ALGO_CHAR(a) @#a /** * @brief Change to string * @param a value to deal * @note equal to add "" */ #define _ALGO_STR(a) #a #define ALGO_STR(a) ALGO_STR(a) /** * @brief Combine two value or characters to string * @param a value to deal * @param b value to deal */ #define _ALGO_CAT(a, b) a##b #define ALGO_CAT(a, b) _ALGO_CAT(a, b) /** * @brief Change value to bool * @param x value to deal */ #define ALGO_BOOL(x) (x) ? 1 : 0 /** * @brief Invert value truth-value * @param x value to deal */ #define ALGO_NOT(x) (x) ? 0 : 1 /** * @brief AND two value * @param x value to deal * @param y value to deal */ #define ALGO_AND(x, y) ((x) && (y)) ? 1 : 0 /** * @brief OR two value * @param x value to deal * @param y value to deal */ #define ALGO_OR(x, y) ((x) || (y)) ? 1 : 0 /** * @brief ROL rotate shift left * @param x value to deal * @param n shift bits * @todo X&0X00FF or etc */ #define ALGO_ROTATE_LEFT(x, n) ((x) << (n)) | ((x) >> ((sizeof(x)) - (n))) /** * @brief ROR rotate shift right * @param x value to deal * @param n shift bits * @todo X&0X00FF or etc */ #define ALGO_ROTATE_RIGHT(x, n) ((x) >> (n)) | ((x) << ((sizeof(x)) - (n))) /** * @brief Invert little-endian and big-endian * @param x value to deal */ #define ALGO_INVERT_BELE(x) \ { \ if(sizeof(x) == sizeof(uint8_t)) {} \ else if(sizeof(x) == sizeof(uint16_t)) \ {x = (uint16_t)((((uint16_t)(x) & 0x00FF) << 8) | (((uint16_t)(x) & 0xFF00) >> 8));} \ else if(sizeof(x) == sizeof(uint32_t)) \ {x = (uint32_t)((((uint32_t)(x) & 0xFF000000) >> 24) | (((uint32_t)(x) & 0x00FF0000) >> 8) \ | (((uint32_t)(x) & 0x0000FF00) << 8) | (((uint32_t)(x) & 0x000000FF) << 24));} \ } /** * @brief Invert value every bit(LSB <-> MSB) * @param x value to deal */ #define ALGO_INVERT_BITS(x) \ { \ x = ((x & 0xAAAAAAAAAAAAAAAA) >> 1) | ((x & 0x5555555555555555) << 1); \ x = ((x & 0xCCCCCCCCCCCCCCCC) >> 2) | ((x & 0x3333333333333333) << 2); \ x = ((x & 0xF0F0F0F0F0F0F0F0) >> 4) | ((x & 0x0F0F0F0F0F0F0F0F) << 4); \ ALGO_SWAP_BELE(x); \ } /** * @brief Invert uint8 value every bit(LSB <-> MSB) * @param x value to deal */ #define ALGO_INVERT_BITS_BYTE(x) \ { \ x = ((x & 0xAA) >> 1) | ((x & 0x55) << 1); \ x = ((x & 0xCC) >> 2) | ((x & 0x33) << 2); \ x = ((x & 0xF0) >> 4) | ((x & 0x0F) << 4); \ } #define ALGO_Uint8ToBin(n) \ ( \ ((n >> 21) & 0x80) | \ ((n >> 18) & 0x40) | \ ((n >> 15) & 0x20) | \ ((n >> 12) & 0x10) | \ ((n >> 9) & 0x08) | \ ((n >> 6) & 0x04) | \ ((n >> 3) & 0x02) | \ ((n ) & 0x01) \ ) #define ALGO_Bin(n) ALGO_Uint8ToBin(0x##n##l) /* Easy way to implement Invert ***********************************************/ void ALGO_InvertUint8_Group(uint8_t* genBuf, uint8_t* srcBuf); void ALGO_InvertUint16_Group(uint16_t* genBuf, uint16_t* srcBuf); void ALGO_InvertUint32_Group(uint32_t* genBuf, uint32_t* srcBuf); void ALGO_InvertBitsN_Group(uint32_t* genBuf, uint32_t* srcBuf, uint8_t len); /* End of Easy way to implement Invert ****************************************/ /** * @brief Swap numbers in easy way * @param x value to deal * @param y value to deal */ #define ALGO_SWAP_EASY(x, y)\ x = x + y;\ y = x - y;\ x = x - y; /** * @brief Swap numbers * @param dataType x & y data type * @param vN variableNum is set to deal with multiple calls in one scope * @param x value to deal * @param y value to deal * @note x & y must be the same type */ #define ALGO_SWAP(dataType, vN, x, y)\ {\ dataType swap_t##vN = x;\ x = y;\ y = swap_t##vN;\ } /** * @brief Swap numbers in addr (not tested) * @param vN variableNum is set to deal with multiple calls in one scope * @param x value to deal * @param y value to deal * @note x & y must be the same type */ #define ALGO_SWAP_ADDR(vN, x, y)\ {\ uint32_t swapAddr_t##vN = x; \ x = y; \ y = swapAddr_t##vN; \ } /** * @brief Sort numbers in group with low first * @param dataType dataInGroup data type * @param vN variableNum is set to deal with multiple calls in one scope * @param dataInGroup data group which need to sort */ #define ALGO_Sort(dataType, vN, dataInGroup) \ { \ uint32_t as_i##vN, as_j##vN, dataInGroupSize##vN; \ dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \ for(as_i##vN = 0; as_i##vN < dataInGroupSize##vN; as_i##vN++) \ { \ for(as_j##vN = as_i##vN + 1; as_j##vN < dataInGroupSize##vN; as_j##vN++) \ { \ if(dataInGroup[as_i##vN] > dataInGroup[as_j##vN]) \ { \ ALGO_SWAP(dataType, _as_0, dataInGroup[as_i##vN], dataInGroup[as_j##vN]); \ } \ } \ } \ } /** * @brief Sort numbers in group with high first * @param dataType dataInGroup data type * @param vN variableNum is set to deal with multiple calls in one scope * @param dataInGroup data group which need to sort */ #define ALGO_Sort_High(dataType, vN, dataInGroup) \ { \ uint32_t as_i##vN, as_j##vN, dataInGroupSize##vN; \ dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \ for(as_i##vN = 0; as_i##vN < dataInGroupSize##vN; as_i##vN++) \ { \ for(as_j##vN = as_i##vN + 1; as_j##vN < dataInGroupSize##vN; as_j##vN++) \ { \ if(dataInGroup[as_i##vN] < dataInGroup[as_j##vN]) \ { \ ALGO_SWAP(dataType, _as_0, dataInGroup[as_i##vN], dataInGroup[as_j##vN]); \ } \ } \ } \ } /** * @brief Calculate averange with delete extremum * @param dataType x & y data type * @param vN variableNum is set to deal with multiple calls in one scope * @param dataInGroup data group which need to deel * @param dataOut output number after deel * @note dataOut & dataInGroup must be the same type */ #define ALGO_AverageInDelExtremum(dataType, vN, dataInGroup, dataOut) \ { \ uint32_t aaide_i##vN, dataInGroupSize##vN; \ dataInGroupSize##vN = sizeof(dataInGroup)/sizeof(dataType); \ ALGO_Sort(dataType, _aaide_0, dataInGroup); \ dataOut = 0; \ for(aaide_i##vN = 1; aaide_i##vN < dataInGroupSize##vN - 1; aaide_i##vN++) \ dataOut += dataInGroup[aaide_i##vN]; \ dataOut /= dataInGroupSize##vN - 2; \ } //Sr-sampling rate, times/second),f-stop freq(Hz),Pi-(3.14...) //k=(2*Pi*f)/Sr typedef struct rcPara { double k; // filter series double lVal; // last calc value }rcPara_t; // #define SIGMOID(x) (1.0 / (1.0 + exp(-x))) float ALGO_MATH_POW_EASY(float x, uint8_t n); int ALGO_MATH_POW_QUICK(int x, int n); float ALGO_MATH_POW(float x, int n); int ALGO_MATH_SQRT(int x); float ALGO_MATH_LogLn(float num); float ALGO_Sqrt_NewtonNumber(float x); float ALGO_NumberSuitScop(float valueIn, float scopMin, float scopMax, float step); double rcLpFilter(rcPara_t* rcPara, double val); double rcHpFilter(rcPara_t* rcPara, double val); uint16_t binarySearch(const double* arr, uint16_t size, double target); #ifdef __DEBUG_ALGO_AlgorithmBase_ATY void ALGO_Swap_Test(void); void ALGO_Sort_Test(void); void ALGO_AverageInDelExtremum_Test(void); void ALGO_INVERT_Test(void); void ALGO_Test_Whole(void); #endif /* __DEBUG_ALGO_AlgorithmBase_ATY */ #endif /* __ALGO_AlgorithmBase_ATY_H */ /******************************** End Of File *********************************/