Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers mx_helpers.h Source File

mx_helpers.h

00001 /**
00002  * File:      mx_helpers.h
00003  *
00004  * Author:    Modtronix Engineering - www.modtronix.com
00005  *
00006  * Description:
00007  *
00008  * Software License Agreement:
00009  * This software has been written or modified by Modtronix Engineering. The code
00010  * may be modified and can be used free of charge for commercial and non commercial
00011  * applications. If this is modified software, any license conditions from original
00012  * software also apply. Any redistribution must include reference to 'Modtronix
00013  * Engineering' and web link(www.modtronix.com) in the file header.
00014  *
00015  * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS,
00016  * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
00017  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE
00018  * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
00019  * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
00020  */
00021 #ifndef MX_HELPERS_H_
00022 #define MX_HELPERS_H_
00023 
00024 #include "nz32s_default_config.h"
00025 
00026 // Debugging //////////////////////////////////////////////////////////////////
00027 // To enable debug output from this file, define MX_DEBUG and DEBUG_ENABLE_MX_HELPERS before
00028 // including this file.
00029 //
00030 //Defines for MXH_DEBUG - debugging for include file
00031 #if !defined(DEBUG_ENABLE_MX_HELPERS)
00032     #define DEBUG_ENABLE_MX_HELPERS          0
00033 #endif
00034 #if !defined(DEBUG_ENABLE_INFO_MX_HELPERS)
00035     #define DEBUG_ENABLE_INFO_MX_HELPERS     0
00036 #endif
00037 
00038 #if !defined(MXH_DEBUG)
00039     #if defined(MX_DEBUG) && (DEBUG_ENABLE_MX_HELPERS==1)
00040         #define MXH_DEBUG MX_DEBUG
00041     #else
00042         #define MXH_DEBUG(format, args...) ((void)0)
00043     #endif
00044 #endif
00045 
00046 #if !defined(MXH_DEBUG_INFO)
00047     #if defined(MX_DEBUG) && (DEBUG_ENABLE_MX_HELPERS==1) && (DEBUG_ENABLE_INFO_MX_HELPERS==1)
00048         #define MXH_DEBUG_INFO MX_DEBUG
00049     #else
00050         #define MXH_DEBUG_INFO(format, args...) ((void)0)
00051     #endif
00052 #endif
00053 
00054 
00055 typedef union
00056 {
00057     uint16_t    Val;
00058     uint8_t     v[2] __packed;
00059     struct
00060     {
00061         uint8_t LB;
00062         uint8_t HB;
00063     } byte;
00064 } WORD_VAL;
00065 
00066 
00067 #define GET_U8_AT0(val)  MxHelpers::get_u8_at0(val)
00068 #define GET_U8_AT1(val)  MxHelpers::get_u8_at1(val)
00069 #define GET_U8_AT2(val)  MxHelpers::get_u8_at2(val)
00070 #define GET_U8_AT3(val)  MxHelpers::get_u8_at3(val)
00071 
00072 #define SET_U8_AT0(val)  MxHelpers::set_u8_at0(val)
00073 #define SET_U8_AT1(val)  MxHelpers::set_u8_at1(val)
00074 #define SET_U8_AT2(val)  MxHelpers::set_u8_at2(val)
00075 #define SET_U8_AT3(val)  MxHelpers::set_u8_at3(val)
00076 
00077 
00078 class MxHelpers {
00079 public:
00080     /** Get first(LSB) 8-bit byte(uint8_t) of given 16-bit Word
00081      * @return Returns the lower(LSB) byte of given value
00082      */
00083     static inline uint8_t get_u8_at0(uint16_t val) {
00084         return ((uint8_t)((val)&0xFF));
00085     }
00086 
00087 
00088     /** Get second(MSB) 8-bit byte(uint8_t) of given 16-bit Word.
00089      * @return Returns the upper(MSB) byte of given value
00090      */
00091     static inline uint8_t get_u8_at1(uint16_t val) {
00092         return ((uint8_t)(((val)>>8)&0xFF));
00093     }
00094 
00095 
00096     /** Get first(LSB) 8-bit byte(uint8_t) of given 32-bit Word
00097      * @return Returns the lower(LSB) byte of given value = byte at bit offset 0 to 7
00098      */
00099     static inline uint8_t get_u8_at0(uint32_t val) {
00100         return ((uint8_t)((val)&0xFF));
00101     }
00102 
00103 
00104     /** Get second 8-bit byte(uint8_t) of given 32-bit Word
00105      * @return Returns the second byte of given value = byte at bit offset 8 to 15
00106      */
00107     static inline uint8_t get_u8_at1(uint32_t val) {
00108         return ((uint8_t)(((val)>>8)&0xFF));
00109     }
00110 
00111 
00112     /** Get third 8-bit byte(uint8_t) of given 32-bit Word
00113      * @return Returns the third byte of given value = byte at bit offset 16 to 23
00114      */
00115     static inline uint8_t get_u8_at2(uint32_t val) {
00116         return ((uint8_t)(((val)>>16)&0xFF));
00117     }
00118 
00119 
00120     /** Get forth(MSB) 8-bit byte(uint8_t) of given 32-bit Word
00121      * @return Returns the MSB byte of given value = byte at bit offset 24 to 31
00122      */
00123     static inline uint8_t get_u8_at3(uint32_t val) {
00124         return ((uint8_t)(((val)>>24)&0xFF));
00125     }
00126 
00127 
00128     /** Write given byte to first(LSB) 8-bit byte(uint8_t) of given 16-bit Word
00129      * @param src Source 8-bit byte to write to destination
00130      * @param dest Destination
00131      */
00132     static inline void set_u8_at0(uint8_t src, uint16_t dest) {
00133         ((uint8_t*)&dest)[0] = src;
00134     }
00135 
00136 
00137     /** Write given byte to MSB 8-bit byte(uint8_t) of given 16-bit Word
00138      * @param src Source 8-bit byte to write to destination
00139      * @param dest Destination
00140      */
00141     static inline void set_u8_at1(uint8_t src, uint16_t dest) {
00142         ((uint8_t*)&dest)[1] = src;
00143     }
00144 
00145 
00146     /** Write given byte to first(LSB) 8-bit byte(uint8_t) of given 32-bit Word
00147      * @param src Source 8-bit byte to write to destination
00148      * @param dest Destination
00149      */
00150     static inline void set_u8_at0(uint8_t src, uint32_t dest) {
00151         ((uint8_t*)&dest)[0] = src;
00152     }
00153 
00154 
00155     /** Write given byte to second 8-bit byte(uint8_t) of given 32-bit Word
00156      * @param src Source 8-bit byte to write to destination
00157      * @param dest Destination
00158      */
00159     static inline void set_u8_at1(uint8_t src, uint32_t dest) {
00160         ((uint8_t*)&dest)[1] = src;
00161     }
00162 
00163 
00164     /** Write given byte to third 8-bit byte(uint8_t) of given 32-bit Word
00165      * @param src Source 8-bit byte to write to destination
00166      * @param dest Destination
00167      */
00168     static inline void set_u8_at2(uint8_t src, uint32_t dest) {
00169         ((uint8_t*)&dest)[2] = src;
00170     }
00171 
00172 
00173     /** Write given byte to last(MSB) 8-bit byte(uint8_t) of given 32-bit Word
00174      * @param src Source 8-bit byte to write to destination
00175      * @param dest Destination
00176      */
00177     static inline void set_u8_at3(uint8_t src, uint32_t dest) {
00178         ((uint8_t*)&dest)[3] = src;
00179     }
00180 
00181 
00182     /** Get the first fractional part of float. For example, will return 5 for 123.56
00183      * @return Returns first fractional part of float. For example, will return 5 for 123.56
00184      */
00185     static inline uint8_t get_frac1(float val) {
00186         return (uint8_t)(( val - ((float)((uint32_t)val)) )*10);
00187     }
00188 
00189 
00190     /**
00191      * Converts a "2 character ASCII hex" string to a single packed byte.
00192      *
00193      * @param asciiChars - WORD_VAL where
00194      *          asciiChars.v[0] is the ASCII value for the lower nibble and
00195      *          asciiChars.v[1] is the ASCII value for the upper nibble.
00196      *          Each must range from '0'-'9', 'A'-'F', or 'a'-'f'.
00197      *
00198      * @return Returns byte representation of given "2 character ASCII byte"
00199      */
00200     static uint8_t ascii_hex_to_byte(WORD_VAL asciiChars);
00201 
00202 
00203     /**
00204      * Get the hex value for the given hex encoded character (0-9, a-f).
00205      * The returned value will be from 0 - 15. If the given byte is not a hex encoded
00206      * character, 0xff is returned!
00207      *
00208      * @param c A hex encoded character, value values are 0-9, A-F and a-f
00209      *
00210      * @return Returns a value from 0 to 15 representing the hex value of given parameter. Or, 0xff if error.
00211      */
00212     static uint8_t ascii_hex_nibble_to_byte(uint8_t c);
00213 
00214     /**
00215      * Converts a byte to a "2-character uppercase ASCII hex" value. The 2 bytes
00216      * are returned in the bytes of the returned WORD_VAL.
00217      * For example, nzByteToAsciiHex(0xAE) will return 'E' in the LSB, and 'A' in
00218      * the MSB of the returned uint16_t.
00219      *
00220      * @param b The byte containing the nibble to convert
00221      *
00222      * @return The LSB of the returned word contains the ASCII value for the lower nibble.
00223      *         The MSB of the returned word contains the ASCII value for the upper nibble.
00224      */
00225     static inline uint16_t byte_to_ascii_hex(uint8_t b) {
00226         WORD_VAL w;
00227         w.byte.LB = low_nibble_to_ascii_hex(b);
00228         w.byte.HB = high_nibble_to_ascii_hex(b);
00229         return w.Val;
00230     }
00231 
00232     /**
00233      * Converts a byte to a "2-character uppercase ASCII hex" string.
00234      * For example, nzByteToAsciiHex(0xAE) will return the string "AE" (LSB='E').
00235      * Will always return 2 characters, for example 0x5 will return "05".
00236      * A NULL termination is NOT added to the back of the returned 2 characters.
00237      *
00238      * @param b The byte containing the nibble to convert
00239      *
00240      * @param dst Pointer to buffer to write the result to. Will always write 2
00241      *      characters, without a NULL termination.
00242      */
00243     static inline void byte_to_ascii_hex_str(uint8_t b, char* dst) {
00244         dst[0] = high_nibble_to_ascii_hex(b);
00245         dst[1] = low_nibble_to_ascii_hex(b);
00246     }
00247 
00248     /**
00249      * Converts the upper nibble of a binary value to a hexadecimal ASCII byte.
00250      * For example, nzHighNibbleToAsciiHex(0xAE) will return 'A'.
00251      * Same as Microchip "btohexa_high()" function
00252      *
00253      * @param b The byte containing the nibble to convert
00254      *
00255      * @return The converted ASCII hex character for the given nibble
00256      */
00257     static inline uint8_t high_nibble_to_ascii_hex(uint8_t b) {
00258         b >>= 4;
00259         return (b > 0x9u) ? b + 'A' - 10 : b + '0';
00260     }
00261 
00262     /**
00263      * Converts the lower nibble of a binary value to a hexadecimal ASCII byte.
00264      * For example, nzLowNibbleToAsciiHex(0xAE) will return 'E'.
00265      * Same as Microchip "btohexa_low()" function
00266      *
00267      * @param b The byte containing the nibble to convert
00268      *
00269      * @return The converted ASCII hex character for the given nibble
00270      */
00271     static inline uint8_t low_nibble_to_ascii_hex(uint8_t b) {
00272         b &= 0x0F;
00273         return (b > 9u) ? b + 'A' - 10 : b + '0';
00274     }
00275 
00276 
00277     /** Counts number of set bits
00278      *
00279      * @param val: Given parameter to count bit's that are 1
00280      * @return Number of set bits
00281      */
00282     static inline uint8_t count_ones(uint32_t val) {
00283         return __builtin_popcount(val);     //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
00284     }
00285 
00286     /**
00287      * Counts number of bits in given array that are set to 1
00288      *
00289      * @param p: Pointer to array whos bits we must count
00290      * @param size: Number of bytes in array we must count bits of
00291      */
00292     static inline uint8_t count_ones_arr(uint8_t* p, uint8_t size) {
00293         uint8_t offset;
00294         uint8_t x;
00295         uint8_t count = 0;
00296 
00297         for (offset = 0; offset < size; offset++) {
00298             x = *p++;
00299             for (count = 0; x != 0; x >>= 1) {
00300                 if (x & 0x01)
00301                     count++;
00302             }
00303         }
00304         return count;
00305     }
00306 
00307 
00308     /** Count leading zeros
00309      * This function counts the number of leading zeros of a data value.
00310      *
00311      * @param val Value to count the leading zeros
00312      * @return number of leading zeros in value
00313      */
00314     static inline uint8_t count_leading_zeros(uint32_t val) {
00315         return __CLZ(val);
00316         //return  __builtin_clz(val);     //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
00317     }
00318 
00319     /** Count trailing zeros
00320      * This function counts the number of trailing zeros of a data value.
00321      * See https://en.wikipedia.org/wiki/Find_first_set
00322      *
00323      * @param val Value to count the trailing zeros
00324      * @return number of trailing zeros in value
00325      */
00326     static inline uint8_t count_trailing_zeros(uint32_t val) {
00327         //return  __builtin_ctz(val);     //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
00328         return (__CLZ(__RBIT(val)));
00329     }
00330 
00331     /** Count leading ones
00332      * This function counts the number of leading ones of a data value.
00333      * See https://en.wikipedia.org/wiki/Find_first_set
00334      *
00335      * @param val Value to count the leading ones
00336      * @return number of leading ones in value
00337      */
00338     static inline uint8_t count_leading_ones(uint32_t val) {
00339         return __CLZ(~val);
00340         //return  __builtin_clz(~val);     //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
00341     }
00342 
00343     /** Count trailing ones
00344      * This function counts the number of trailing ones of a data value.
00345      * See https://en.wikipedia.org/wiki/Find_first_set
00346      *
00347      * @param val Value to count the leading ones
00348      * @return number of leading ones in value
00349      */
00350     static inline uint8_t count_trailing_ones(uint32_t val) {
00351         //return  __builtin_ctz(~val);     //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
00352         return (__CLZ(__RBIT(~val)));
00353     }
00354 
00355     /** Reverse bit order of value
00356      * This function reverses the bit order of the given value.
00357      *
00358      * @param val Value to reverse bits of
00359      * @return Reversed value
00360      */
00361     static inline uint32_t reverse_bits(uint32_t val) {
00362         return __RBIT(val);
00363     }
00364 
00365 
00366     /**
00367      * Get the value of the given decimal string. String value can have
00368      * leading 0s. Maximum value is 65,535. Following possible leading format specifiers are
00369      * checked for:
00370      * - x = Upper Case Hex value to follow
00371      *
00372      * Some examples:
00373      * "255" will return 0x00FF
00374      * "x010" will return 0x0010
00375      *
00376      * @param str String containing hex value
00377      *
00378      * @param retFlags A value returned from this function.
00379      *        - bit 0-3 is the number of bytes parsed by this function
00380      *        - bits 4-7 are reserved for flags, like if the parsed value is a byte
00381      *          or word for example.
00382      *
00383      * @return Parsed word value
00384      */
00385     static uint16_t cvt_ascii_dec_to_uint16(const char* str, uint8_t* retFlags);
00386 
00387 
00388     /**
00389      * Get the value of the given Upper Case Hex, or decimal string. String value can have
00390      * leading 0s. Maximum value is 0xFFFF. Following possible leading format specifiers are
00391      * checked for:
00392      * - d = Decimal value to follow
00393      *
00394      * Some examples:
00395      * "A100" will return 0xA100
00396      * "d010" will return 0xA
00397      *
00398      * @param str String containing hex value
00399      *
00400      * @param retFlags A value returned from this function.
00401      *        - bit 0-3 is the number of bytes parsed by this function
00402      *        - bits 4-7 are reserved for flags, like if the parsed value is a byte
00403      *          or word for example.
00404      *
00405      * @return Parsed word value
00406      */
00407     static uint16_t cvt_ascii_hex_to_uint16(const char* str, uint8_t* retFlags);
00408 
00409 
00410     /**
00411      * Converts a 16-bit unsigned integer to a null-terminated decimal string.
00412      *
00413      * @param val - The number to be converted
00414      *
00415      * @param buf - Pointer in which to store the converted string
00416      *
00417      * @param ret - Returns length of string written to buf. Does NOT include NULL terminator added
00418      */
00419     static uint8_t cvt_uint16_to_ascii_str(uint16_t val, uint8_t* buf);
00420 
00421 
00422     /**
00423      * Converts a 16-bit signed integer to a null-terminated decimal string.
00424      *
00425      * @param val - The number to be converted
00426      *
00427      * @param buf - Pointer in which to store the converted string
00428      *
00429      * @param ret - Returns length of string written to buf. Does NOT include NULL terminator added
00430      */
00431     static inline uint8_t cvt_int16_to_ascii_str(int16_t val, uint8_t* buf) {
00432         uint8_t retVal = 0;
00433         if(val < 0) {
00434             *buf = '-';
00435             buf++;
00436             retVal++;
00437         }
00438         return retVal + cvt_uint16_to_ascii_str(abs(val), buf);
00439     }
00440 
00441 
00442     /** Rotate Right with Extend (32 bit)
00443      * This function moves each bit of a bitstring right by one bit. The carry input is shifted
00444      * in at the left end of the bitstring.
00445      *
00446      * @param value  Value to rotate
00447      * @return Rotated value
00448      */
00449     static inline uint32_t rotate_right(int32_t val) {
00450         return __RRX(val);
00451     }
00452 
00453     //Protected Data
00454 protected:
00455 
00456 };
00457 
00458 #if defined(MXH_DEBUG)
00459     #undef MXH_DEBUG
00460 #endif
00461 #if defined(MXH_DEBUG_INFO)
00462     #undef MXH_DEBUG_INFO
00463 #endif
00464 
00465 #endif /* MX_HELPERS_H_ */