Library for Modtronix NZ32 STM32 boards, like the NZ32-SC151, NZ32-SB072, NZ32-SE411 and others
mx_helpers.h
- Committer:
- modtronix
- Date:
- 2015-08-30
- Revision:
- 5:e1297df8ee0d
- Parent:
- 3:99cb87ee1792
- Child:
- 6:33d25ef353f6
File content as of revision 5:e1297df8ee0d:
/** * 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; #define GET_U8_AT0(val) MxHelpers::read_uint8_at_0(val) #define GET_U8_AT1(val) MxHelpers::read_uint8_at_1(val) #define GET_U8_AT2(val) MxHelpers::read_uint8_at_2(val) #define GET_U8_AT3(val) MxHelpers::read_uint8_at_3(val) #define SET_U8_AT0(val) MxHelpers::write_uint8_at_0(val) #define SET_U8_AT1(val) MxHelpers::write_uint8_at_1(val) #define SET_U8_AT2(val) MxHelpers::write_uint8_at_2(val) #define SET_U8_AT3(val) MxHelpers::write_uint8_at_3(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_ */