LwUTIL

group LWUTIL

Lightweight utility.

Defines

LWUTIL_ARRAYSIZE(x)

Get size of statically allocated array Array must be declared in a form of type var_name[element_count]

Parameters
  • x – [in] Object to get array size of

Returns

Number of elements in array (element_count)

LWUTIL_ASZ(x)

Get size of statically allocated array Array must be declared in a form of type var_name[element_count]

Note

This is an alias of LWUTIL_ARRAYSIZE

Parameters
  • x – [in] Object to get array size of

Returns

Number of elements in array (element_count)

LWUTIL_MAX(x, y)

Get larger value out of 2 different inputs.

Warning

x and y may each be evaluated more than once. Do not pass expressions with side effects (eg. i++, *p++, function calls with side effects).

Parameters
  • x – [in] First input

  • y – [in] Second input

Returns

Larger of both inputs

LWUTIL_MIN(x, y)

Get smaller value out of 2 different inputs.

Warning

x and y may each be evaluated more than once. Do not pass expressions with side effects (eg. i++, *p++, function calls with side effects).

Parameters
  • x – [in] First input

  • y – [in] Second input

Returns

Smaller of both inputs

LWUTIL_CONSTRAIN(x, a, b)

Constrains an input number within a range.

Note

Function does not check if a < b. This must be handled by the user.

Note

This is implemented as macro and return data type depends on the input number types.

Warning

x may be evaluated up to twice (it expands to nested LWUTIL_MIN / LWUTIL_MAX calls). Do not pass expressions with side effects.

Parameters
  • x – [in] Number to constrain

  • a – [in] Minimum allowed number

  • b – [in] Maximum allowed number

Returns

x if a < x < b

Returns

a if x <= a

Returns

b if x >= b

LWUTIL_MAP(x, in_min, in_max, out_min, out_max)

Maps the input number with the min and max range to the map of the output min and max range.

             Mathematical calculation is:

                  (x - in_min) * (out_max - out_min)
             y = ------------------------------------ + out_min
                           (in_max - in_min)

Note

Data types depend on the user inputs. If high precision is required, user can cast the input variables to appropriate type (double or float), or use integer types if decimal precision is not required.

Note

Input data is not constrained between out min and out max values. This may sometimes be useful for the application. Use LWUTIL_CONSTRAIN macro to constrain the value

Warning

Every argument may be evaluated more than once. Do not pass expressions with side effects.

Parameters
  • x – [in] Input value to map

  • in_min – [in] Minimum value to map from (input boundary)

  • in_max – [in] Maximum value to map from (input boundary)

  • out_min – [in] Minimum value to map to (output boundary)

  • out_max – [in] Maximum value to map to (output boundary)

Returns

Mapped value

LWUTIL_ABS(x)

Get absolute value of the input Returns always-positive value of the input.

Making absolute value of such input means longer output data type requirement.

Consider writing result of this function to unsigned type of same integer width. For example, minimum signed char value is -128 while its absolute value (128) requires variable type of either unsigned char or minimum signed 16-bit (or more).

Note

Special care must be taken when input variable holds minimum value available for given signed integer type (char, int, long, …).

Warning

x may be evaluated twice. Do not pass expressions with side effects.

Parameters
  • x – [in] Input value

Returns

Absolute value of the input value

LWUTIL_UNUSED(x)

Unused variable to avoid compilation warning if declared but not used.

Parameters
  • x – [in] Input variable to declare unused

LWUTIL_SET_VALUE_IF_PTR_NOT_NULL(ptr, value)

Dereference the pointer and assign the value to it, but only if ptr is not NULL.

Note

It is fully up to user to handle to correct variable and data types

Parameters
  • ptr – [in] Pointer to check and assign to

  • value – [in] Value to assign

LWUTIL_CONCAT_BASE(x, y)
LWUTIL_CONCAT(s0, s1)
LWUTIL_COMPILE_TIME_ASSERT(exp, random_variable_name)

Compile time assert to validate specific expression. Compilation will fail if expression evaluated to zero.

Note

Can only be used with the integer types

Parameters
  • exp – [in] Expression to test. It must be compile-time evaluation

  • random_variable_name – [in] Meaningful variable name to be used. Can be whatever until it is valid variable name

lwutil_bits_is_set_all(val, bit_mask)

Check if all bits in the bit_mask are set in the input value.

Note

Can only be used with the integer types

Parameters
  • val – [in] Value to check for bits in

  • bit_mask – [in] Bit mask to check in value

Returns

1 if all bits are set, 0 otherwise

lwutil_bits_is_set_any(val, bit_mask)

Check if any of the bit_mask bits is set in the input value.

Note

Can only be used with the integer types

Parameters
  • val – [in] Value to check for bits in

  • bit_mask – [in] Bit mask to check in value

Returns

1 if any bit is set, 0 otherwise

lwutil_bits_set(val, bit_mask)

Set bit mask in the input value.

Note

Can only be used with the integer types

Parameters
  • val – [in] Value to set bits in. Original input is not modified. It is pass-by-value.

  • bit_mask – [in] Bit mask indicating which bits to set

Returns

New value with bitwise OR between input value and bit mask

lwutil_bits_clear(val, bit_mask)

Clear bit mask in the input value.

Note

Can only be used with the integer types

Parameters
  • val – [in] Value to clear bits in. Original input is not modified. It is pass-by-value.

  • bit_mask – [in] Bit mask indicating which bits to clear

Returns

New value with bitwise AND and negated bit_mask between input value and bit mask Value has bits cleared in the bit_mask set

lwutil_bits_toggle(val, bit_mask)

Toggle bit mask in the input value.

Note

Can only be used with the integer types

Parameters
  • val – [in] Value to toggle bits in. Original input is not modified. It is pass-by-value.

  • bit_mask – [in] Bit mask indicating which bits to toggle

Returns

New value with bitwise AND and negated bit_mask between input value and bit mask Value has bits cleared in the bit_mask set

Functions

static inline void lwutil_st_u16_le(uint16_t val, void *ptr)

Store 16-bit value to bytes array in little-endian format.

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 2-bytes long output array to write value to

static inline void lwutil_st_u32_le(uint32_t val, void *ptr)

Store 32-bit value to bytes array in little-endian format.

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 4-bytes long output array to write value to

static inline uint16_t lwutil_ld_u16_le(const void *ptr)

Load 16-bit value from bytes array in little-endian format.

Parameters

ptr – [in] Minimum 2-bytes long input array to extract bytes from

Returns

16-bit value extracted from input array

static inline uint32_t lwutil_ld_u32_le(const void *ptr)

Load 32-bit value from bytes array in little-endian format.

Parameters

ptr – [in] Minimum 4-bytes long input array to extract bytes from

Returns

32-bit value extracted from input array

static inline void lwutil_st_u16_be(uint16_t val, void *ptr)

Store 16-bit value to bytes array in big-endian format.

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 2-bytes long output array to write value to

static inline void lwutil_st_u32_be(uint32_t val, void *ptr)

Store 32-bit value to bytes array in big-endian format.

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 4-bytes long output array to write value to

static inline uint16_t lwutil_ld_u16_be(const void *ptr)

Load 16-bit value from bytes array in big-endian format.

Parameters

ptr – [in] Minimum 2-bytes long input array to extract bytes from

Returns

16-bit value extracted from input array

static inline uint32_t lwutil_ld_u32_be(const void *ptr)

Load 32-bit value from bytes array in big-endian format.

Parameters

ptr – [in] Minimum 4-bytes long input array to extract bytes from

Returns

32-bit value extracted from input array

static inline void lwutil_st_u16_le_ex(uint16_t val, void **ptr)

Store 16-bit value to bytes array in little-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 2-bytes long output array to write value to

static inline void lwutil_st_u32_le_ex(uint32_t val, void **ptr)

Store 32-bit value to bytes array in little-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 4-bytes long output array to write value to

static inline uint16_t lwutil_ld_u16_le_ex(const void **ptr)

Load 16-bit value from bytes array in little-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters

ptr – [in] Minimum 2-bytes long input array to extract bytes from

Returns

16-bit value extracted from input array

static inline uint32_t lwutil_ld_u32_le_ex(const void **ptr)

Load 32-bit value from bytes array in little-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters

ptr – [in] Minimum 4-bytes long input array to extract bytes from

Returns

32-bit value extracted from input array

static inline void lwutil_st_u16_be_ex(uint16_t val, void **ptr)

Store 16-bit value to bytes array in big-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 2-bytes long output array to write value to

static inline void lwutil_st_u32_be_ex(uint32_t val, void **ptr)

Store 32-bit value to bytes array in big-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters
  • val – [in] Value to write to output array

  • ptr – [out] Minimum 4-bytes long output array to write value to

static inline uint16_t lwutil_ld_u16_be_ex(const void **ptr)

Load 16-bit value from bytes array in big-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters

ptr – [in] Minimum 2-bytes long input array to extract bytes from

Returns

16-bit value extracted from input array

static inline uint32_t lwutil_ld_u32_be_ex(const void **ptr)

Load 32-bit value from bytes array in big-endian format.

Note

Extended version, accepts the pointer to pointer and modifies the address pointer points to. Input pointer will point after the used bytes

Parameters

ptr – [in] Minimum 4-bytes long input array to extract bytes from

Returns

32-bit value extracted from input array

void lwutil_u8_to_2asciis(uint8_t hex, char *ascii)

Makes ascii char array from unsigned 8-bit value.

Parameters
  • hex – [in] Hexadecimal data to be converted

  • ascii – [out] Minimum 3-bytes long array to write value to

void lwutil_u16_to_4asciis(uint16_t hex, char *ascii)

Makes ascii char array from unsigned 16-bit value.

Parameters
  • hex – [in] Hexadecimal data to be converted

  • ascii – [out] Minimum 5-bytes long array to write value to

void lwutil_u32_to_8asciis(uint32_t hex, char *ascii)

Makes ascii char array from unsigned 32-bit value.

Parameters
  • hex – [in] Hexadecimal data to be converted

  • ascii – [out] Minimum 9-bytes long array to write value to

uint8_t lwutil_ld_u32_varint(const void *ptr, size_t ptr_len, uint32_t *val_out)

Load variable length integer from the byte stream to the variable.

Variable length integers (short varints) are stored with continuation bit (bit 7, 0x80), which tells us if there is a next byte to be used as part of the number sequence.

32-bit integer can be stored with anything between 1 and 5 bytes.

Parameters
  • ptr – Array pointer to load data from

  • ptr_len – Input array length

  • val_out – Pointer to variable to write result value

Returns

Number of bytes used to load the full number. Set to 0 in case of an error.

uint8_t lwutil_st_u32_varint(uint32_t val, void *ptr, size_t ptr_len)

Store an integer into variable length byte sequence array.

Variable length integers (short varints) are stored with continuation bit (bit 7, 0x80), which tells us if there is a next byte to be used as part of the number sequence.

32-bit integer can be stored with anything between 1 and 5 bytes.

Parameters
  • val – Value to encode into byte sequence

  • ptr – Array to write output result

  • ptr_len – Length of an input array

Returns

Number of bytes written (stored) in the memory. Set to 0 in case of an error.

uint8_t lwutil_tutil_has_elapsed(uint32_t time_now, uint32_t *time_variable, uint32_t time_period)

Check the the time between time now and time variable is greater than the defined time_period.

When it is, the time_variable is updated accordingly, following the 2 possible scenarios:

  • Delta time is less than 2x period, the time variable is increased by period, to keep the drift-free updates

  • Delta time is more than 2x period, the time variable is set to current time, to resync the drift

The check if: (time_now - *time_variable) >= time_period

The function can be used as follows:

//At the top somewhere
static uint32_t time_last;

//Later periodically in the function calls
if (lwutil_tutil_has_elapsed(time_now, &time_last, 500)) {
 // Do something if time_now - time_last is at least 500 units apart
 // will also update the time_last to either +500, or to the time_now, depending on the delta
}

Note

This is the 32-bit time variant

Parameters
  • time_now – Current time. It can be in ms or any other unit, as long as all variables hold same unit

  • time_variable – Time variable to check against. It is a pointer to the variable

  • time_period – Time period to check against

Returns

1 is time elapsed, 0 otherwise

uint8_t lwutil_rregslope_init(lwutil_rregslope_t *rrs, int32_t *buffer, size_t buffer_len)

Initialize the rolling regression slope instance.

Parameters
  • rrs – Instance to initialize

  • buffer – External buffer used to store the rolling window of values. Must remain valid for the lifetime of rrs

  • buffer_len – Number of elements in buffer, the window size. Must be at least 2, since a slope needs at least 2 points

Returns

1 on success, 0 on failure

uint8_t lwutil_rregslope_add_value(lwutil_rregslope_t *rrs, int32_t value)

Add a new value to the rolling window.

Parameters
  • rrs – Instance to work with

  • value – New value to add

Returns

1 on success

uint8_t lwutil_rregslope_compute_slope(const lwutil_rregslope_t *rrs, int32_t *slope)

Compute the least-squares slope of the current window.

The window must be full before a slope is meaningful, since the precomputed sum_x / denom constants assume capacity samples.

Parameters
  • rrs – Instance to work with

  • slope – [out] Pointer to store the computed slope. Can be set to NULL to only check if the slope is available

Returns

1 if the window is full and slope was computed, 0 otherwise

uint8_t lwutil_rregslope_reset(lwutil_rregslope_t *rrs)

Reset the rolling regression window, clear the history and all rolling sums to zero.

Parameters

rrs – Rolling regression instance to work with

Returns

1 on success, 0 otherwise

static inline size_t lwutil_rregslope_get_capacity(const lwutil_rregslope_t *rrs)

Get the capacity for number of samples the buffer can hold.

Note

Buffer is full when count is equal to capacity

Parameters

rrs – Regression slope instance

Returns

Number of samples the buffer can hold

static inline size_t lwutil_rregslope_get_count(const lwutil_rregslope_t *rrs)

Get the current samples counter in the buffer.

Note

Buffer is full when count is equal to capacity

Parameters

rrs – Regression slope instance

Returns

Number of samples in the buffer currently

struct lwutil_rregslope_t
#include <lwutil.h>

Rolling regression slope instance.

Public Members

size_t index

Next write index

size_t count

Number of entries in the buffer

size_t capacity

Capacity in the buffer when it is full

int32_t *buffer

Pointer to the array of values

int32_t sum_Y

Sum of all values currently in the buffer

int64_t sum_xY

Sum of all the multiplies of the counter and Y values

int64_t sum_x

Sum of x sample positions for a full window, precomputed by lwutil_rregslope_init

int64_t denom

Denominator of the least-squares slope formula for a full window, precomputed by lwutil_rregslope_init