Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others
Diff: mx_helpers.h
- Revision:
- 3:99cb87ee1792
- Child:
- 5:e1297df8ee0d
diff -r cd263c5e86f2 -r 99cb87ee1792 mx_helpers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mx_helpers.h Sun Aug 30 09:23:05 2015 +1000 @@ -0,0 +1,426 @@ +/** + * File: mx_helpers.h + * + * Author: Modtronix Engineering - www.modtronix.com + * + * Description: + * + * Software License Agreement: + * This software has been written or modified by Modtronix Engineering. The code + * may be modified and can be used free of charge for commercial and non commercial + * applications. If this is modified software, any license conditions from original + * software also apply. Any redistribution must include reference to 'Modtronix + * Engineering' and web link(www.modtronix.com) in the file header. + * + * THIS SOFTWARE IS PROVIDED IN AN 'AS IS' CONDITION. NO WARRANTIES, WHETHER EXPRESS, + * IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE + * COMPANY SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR + * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER. + */ +#ifndef MX_HELPERS_H_ +#define MX_HELPERS_H_ + +//Defines for MXH_DEBUG - debugging for include file +#define DEBUG_ENABLE_MX_HELPERS 1 +#define DEBUG_ENABLE_INFO_MX_HELPERS 0 + +#if !defined(MXH_DEBUG) +#if (DEBUG_ENABLE_MX_HELPERS == 1) + #define MXH_DEBUG MX_DEBUG + #if (DEBUG_ENABLE_INFO_MX_HELPERS == 1) + #define MXH_DEBUG_INFO MX_DEBUG + #else + #define MXH_DEBUG_INFO(format, args...) ((void)0) + #endif +#else + #define MXH_DEBUG(format, args...) ((void)0) + #define MXH_DEBUG_INFO(format, args...) ((void)0) +#endif // #if (DEBUG_ENABLE_MX_HELPERS == 1) +#endif // #if !defined(MXH_DEBUG) + +typedef union +{ + uint16_t Val; + uint8_t v[2] __packed; + struct + { + uint8_t LB; + uint8_t HB; + } byte; +} WORD_VAL; + + +class MxHelpers { +public: + /** Get first(LSB) 8-bit byte(uint8_t) of given 16-bit Word + * @return Returns the lower(LSB) byte of given value + */ + static inline uint8_t read_uint8_at_0(uint16_t val) { + return ((uint8_t)((val)&0xFF)); + } + + + /** Get second(MSB) 8-bit byte(uint8_t) of given 16-bit Word. + * @return Returns the upper(MSB) byte of given value + */ + static inline uint8_t read_uint8_at_1(uint16_t val) { + return ((uint8_t)(((val)>>8)&0xFF)); + } + + + /** Get first(LSB) 8-bit byte(uint8_t) of given 32-bit Word + * @return Returns the lower(LSB) byte of given value = byte at bit offset 0 to 7 + */ + static inline uint8_t read_uint8_at_0(uint32_t val) { + return ((uint8_t)((val)&0xFF)); + } + + + /** Get second 8-bit byte(uint8_t) of given 32-bit Word + * @return Returns the second byte of given value = byte at bit offset 8 to 15 + */ + static inline uint8_t read_uint8_at_1(uint32_t val) { + return ((uint8_t)(((val)>>8)&0xFF)); + } + + + /** Get third 8-bit byte(uint8_t) of given 32-bit Word + * @return Returns the third byte of given value = byte at bit offset 16 to 23 + */ + static inline uint8_t read_uint8_at_2(uint32_t val) { + return ((uint8_t)(((val)>>16)&0xFF)); + } + + + /** Get forth(MSB) 8-bit byte(uint8_t) of given 32-bit Word + * @return Returns the MSB byte of given value = byte at bit offset 24 to 31 + */ + static inline uint8_t read_uint8_at_3(uint32_t val) { + return ((uint8_t)(((val)>>24)&0xFF)); + } + + + /** Write given byte to first(LSB) 8-bit byte(uint8_t) of given 16-bit Word + * @param src Source 8-bit byte to write to destination + * @param dest Destination + */ + static inline void write_uint8_at_0(uint8_t src, uint16_t dest) { + ((uint8_t*)&dest)[0] = src; + } + + + /** Write given byte to MSB 8-bit byte(uint8_t) of given 16-bit Word + * @param src Source 8-bit byte to write to destination + * @param dest Destination + */ + static inline void write_uint8_at_1(uint8_t src, uint16_t dest) { + ((uint8_t*)&dest)[1] = src; + } + + + /** Write given byte to first(LSB) 8-bit byte(uint8_t) of given 32-bit Word + * @param src Source 8-bit byte to write to destination + * @param dest Destination + */ + static inline void write_uint8_at_0(uint8_t src, uint32_t dest) { + ((uint8_t*)&dest)[0] = src; + } + + + /** Write given byte to second 8-bit byte(uint8_t) of given 32-bit Word + * @param src Source 8-bit byte to write to destination + * @param dest Destination + */ + static inline void write_uint8_at_1(uint8_t src, uint32_t dest) { + ((uint8_t*)&dest)[1] = src; + } + + + /** Write given byte to third 8-bit byte(uint8_t) of given 32-bit Word + * @param src Source 8-bit byte to write to destination + * @param dest Destination + */ + static inline void write_uint8_at_2(uint8_t src, uint32_t dest) { + ((uint8_t*)&dest)[2] = src; + } + + + /** Write given byte to last(MSB) 8-bit byte(uint8_t) of given 32-bit Word + * @param src Source 8-bit byte to write to destination + * @param dest Destination + */ + static inline void write_uint8_at_3(uint8_t src, uint32_t dest) { + ((uint8_t*)&dest)[3] = src; + } + + + /** + * Converts a "2 character ASCII hex" string to a single packed byte. + * + * @param asciiChars - WORD_VAL where + * asciiChars.v[0] is the ASCII value for the lower nibble and + * asciiChars.v[1] is the ASCII value for the upper nibble. + * Each must range from '0'-'9', 'A'-'F', or 'a'-'f'. + * + * @return Returns byte representation of given "2 character ASCII byte" + */ + static uint8_t ascii_hex_to_byte(WORD_VAL asciiChars); + + + /** + * Get the hex value for the given hex encoded character (0-9, a-f). + * The returned value will be from 0 - 15. If the given byte is not a hex encoded + * character, 0xff is returned! + * + * @param c A hex encoded character, value values are 0-9, A-F and a-f + * + * @return Returns a value from 0 to 15 representing the hex value of given parameter. Or, 0xff if error. + */ + static uint8_t ascii_hex_nibble_to_byte(uint8_t c); + + /** + * Converts a byte to a "2-character uppercase ASCII hex" value. The 2 bytes + * are returned in the bytes of the returned WORD_VAL. + * For example, nzByteToAsciiHex(0xAE) will return 'E' in the LSB, and 'A' in + * the MSB of the returned uint16_t. + * + * @param b The byte containing the nibble to convert + * + * @return The LSB of the returned word contains the ASCII value for the lower nibble. + * The MSB of the returned word contains the ASCII value for the upper nibble. + */ + static inline uint16_t byte_to_ascii_hex(uint8_t b) { + WORD_VAL w; + w.byte.LB = low_nibble_to_ascii_hex(b); + w.byte.HB = high_nibble_to_ascii_hex(b); + return w.Val; + } + + /** + * Converts a byte to a "2-character uppercase ASCII hex" string. + * For example, nzByteToAsciiHex(0xAE) will return the string "AE" (LSB='E'). + * Will always return 2 characters, for example 0x5 will return "05". + * A NULL termination is NOT added to the back of the returned 2 characters. + * + * @param b The byte containing the nibble to convert + * + * @param dst Pointer to buffer to write the result to. Will always write 2 + * characters, without a NULL termination. + */ + static inline void byte_to_ascii_hex_str(uint8_t b, char* dst) { + dst[0] = high_nibble_to_ascii_hex(b); + dst[1] = low_nibble_to_ascii_hex(b); + } + + /** + * Converts the upper nibble of a binary value to a hexadecimal ASCII byte. + * For example, nzHighNibbleToAsciiHex(0xAE) will return 'A'. + * Same as Microchip "btohexa_high()" function + * + * @param b The byte containing the nibble to convert + * + * @return The converted ASCII hex character for the given nibble + */ + static inline uint8_t high_nibble_to_ascii_hex(uint8_t b) { + b >>= 4; + return (b > 0x9u) ? b + 'A' - 10 : b + '0'; + } + + /** + * Converts the lower nibble of a binary value to a hexadecimal ASCII byte. + * For example, nzLowNibbleToAsciiHex(0xAE) will return 'E'. + * Same as Microchip "btohexa_low()" function + * + * @param b The byte containing the nibble to convert + * + * @return The converted ASCII hex character for the given nibble + */ + static inline uint8_t low_nibble_to_ascii_hex(uint8_t b) { + b &= 0x0F; + return (b > 9u) ? b + 'A' - 10 : b + '0'; + } + + + /** Counts number of set bits + * + * @param val: Given parameter to count bit's that are 1 + * @return Number of set bits + */ + static inline uint8_t count_ones(uint32_t val) { + return __builtin_popcount(val); //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html + } + + /** + * Counts number of bits in given array that are set to 1 + * + * @param p: Pointer to array whos bits we must count + * @param size: Number of bytes in array we must count bits of + */ + static inline uint8_t count_ones_arr(uint8_t* p, uint8_t size) { + uint8_t offset; + uint8_t x; + uint8_t count = 0; + + for (offset = 0; offset < size; offset++) { + x = *p++; + for (count = 0; x != 0; x >>= 1) { + if (x & 0x01) + count++; + } + } + return count; + } + + + /** Count leading zeros + * This function counts the number of leading zeros of a data value. + * + * @param val Value to count the leading zeros + * @return number of leading zeros in value + */ + static inline uint8_t count_leading_zeros(uint32_t val) { + return __CLZ(val); + //return __builtin_clz(val); //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html + } + + /** Count trailing zeros + * This function counts the number of trailing zeros of a data value. + * See https://en.wikipedia.org/wiki/Find_first_set + * + * @param val Value to count the trailing zeros + * @return number of trailing zeros in value + */ + static inline uint8_t count_trailing_zeros(uint32_t val) { + //return __builtin_ctz(val); //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html + return (__CLZ(__RBIT(val))); + } + + /** Count leading ones + * This function counts the number of leading ones of a data value. + * See https://en.wikipedia.org/wiki/Find_first_set + * + * @param val Value to count the leading ones + * @return number of leading ones in value + */ + static inline uint8_t count_leading_ones(uint32_t val) { + return __CLZ(~val); + //return __builtin_clz(~val); //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html + } + + /** Count trailing ones + * This function counts the number of trailing ones of a data value. + * See https://en.wikipedia.org/wiki/Find_first_set + * + * @param val Value to count the leading ones + * @return number of leading ones in value + */ + static inline uint8_t count_trailing_ones(uint32_t val) { + //return __builtin_ctz(~val); //Use GCC built in functions, see http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html + return (__CLZ(__RBIT(~val))); + } + + /** Reverse bit order of value + * This function reverses the bit order of the given value. + * + * @param val Value to reverse bits of + * @return Reversed value + */ + static inline uint32_t reverse_bits(uint32_t val) { + return __RBIT(val); + } + + + /** + * Get the value of the given decimal string. String value can have + * leading 0s. Maximum value is 65,535. Following possible leading format specifiers are + * checked for: + * - x = Upper Case Hex value to follow + * + * Some examples: + * "255" will return 0x00FF + * "x010" will return 0x0010 + * + * @param str String containing hex value + * + * @param retFlags A value returned from this function. + * - bit 0-3 is the number of bytes parsed by this function + * - bits 4-7 are reserved for flags, like if the parsed value is a byte + * or word for example. + * + * @return Parsed word value + */ + static uint16_t cvt_ascii_dec_to_uint16(const char* str, uint8_t* retFlags); + + + /** + * Get the value of the given Upper Case Hex, or decimal string. String value can have + * leading 0s. Maximum value is 0xFFFF. Following possible leading format specifiers are + * checked for: + * - d = Decimal value to follow + * + * Some examples: + * "A100" will return 0xA100 + * "d010" will return 0xA + * + * @param str String containing hex value + * + * @param retFlags A value returned from this function. + * - bit 0-3 is the number of bytes parsed by this function + * - bits 4-7 are reserved for flags, like if the parsed value is a byte + * or word for example. + * + * @return Parsed word value + */ + static uint16_t cvt_ascii_hex_to_uint16(const char* str, uint8_t* retFlags); + + + /** + * Converts a 16-bit unsigned integer to a null-terminated decimal string. + * + * @param val - The number to be converted + * + * @param buf - Pointer in which to store the converted string + * + * @param ret - Returns length of string written to buf. Does NOT include NULL terminator added + */ + static uint8_t cvt_uint16_to_ascii_str(uint16_t val, uint8_t* buf); + + + /** + * Converts a 16-bit signed integer to a null-terminated decimal string. + * + * @param val - The number to be converted + * + * @param buf - Pointer in which to store the converted string + * + * @param ret - Returns length of string written to buf. Does NOT include NULL terminator added + */ + static inline uint8_t cvt_int16_to_ascii_str(int16_t val, uint8_t* buf) { + uint8_t retVal = 0; + if(val < 0) { + *buf = '-'; + buf++; + retVal++; + } + return retVal + cvt_uint16_to_ascii_str(abs(val), buf); + } + + + /** Rotate Right with Extend (32 bit) + * This function moves each bit of a bitstring right by one bit. The carry input is shifted + * in at the left end of the bitstring. + * + * @param value Value to rotate + * @return Rotated value + */ + static inline uint32_t rotate_right(int32_t val) { + return __RRX(val); + } + + //Protected Data +protected: + +}; + +#endif /* MX_HELPERS_H_ */