You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
4.4 KiB

2 months ago
/*
******************************************************************************
* @copyright Copyright (C), 2023-2023, ConvenientPower. Co., Ltd.
* @file util.h
* @brief Utility Macros and Functions
******************************************************************************
*/
#ifndef UTIL_H
#define UTIL_H
#include <stdint.h>
#include <stdbool.h>
#ifndef ARRAY_LEN
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
#endif
#ifndef BIT
#define BIT(n) (1ul << (n))
#endif
#ifndef MIN
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
#endif
#ifndef MAX
#define MAX(a, b) (((a) > (b)) ? (a) : (b))
#endif
#define time_diff(_a, _b) ((int32_t)((uint32_t)(_a) - (uint32_t)(_b)))
#define time_after(_a, _b) (time_diff((_a), (_b)) > 0)
#define time_after_eq(_a, _b) (time_diff((_a), (_b)) >= 0)
#define time_before(_a, _b) time_after(_b, _a)
#define time_before_eq(_a, _b) time_after_eq(_b, _a)
#define CLAMP(value, min, max) ((value) < (min) ? (min) : ((value) > (max) ? (max) : (value)))
#define CLAMP_HIGH(value, max) ((value) > (max) ? (max) : (value))
#define CLAMP_LOW(value, min) ((value) < (min) ? (min) : (value))
#define FLOAT_TO_INT_MUL(x, float_y, shift_bit) \
(((x) * ((int32_t)((float_y) * (1 << (shift_bit))))) >> (shift_bit))
static inline uint32_t get_sys_time(void)
{
extern volatile uint32_t g_systick_cnt;
return g_systick_cnt;
}
static inline void register_mask_set(volatile uint32_t *reg, uint32_t mask,
uint32_t val)
{
uint32_t reg_val;
reg_val = *reg;
reg_val &= ~mask;
reg_val |= (val) & mask;
*reg = reg_val;
}
/*
* Debouncer
*/
typedef struct debouncer
{
uint16_t cnt;
uint16_t out;
} debouncer_s;
typedef struct debouncer_param
{
uint16_t up_time;
uint16_t down_time;
} debouncer_param_s;
bool __debounce(debouncer_s *obj, bool in, uint16_t up_time, uint16_t down_time);
static inline bool debounce(debouncer_s *obj, bool in, const debouncer_param_s *param)
{
return __debounce(obj, in, param->up_time, param->down_time);
}
static inline bool debouncer_out(debouncer_s *obj)
{
return obj->out;
}
static inline void __init_debouncer(debouncer_s *obj, uint16_t initial_cnt, bool initial_output)
{
obj->cnt = initial_cnt;
obj->out = initial_output;
}
void init_debouncer(debouncer_s *obj, bool initial_output, const debouncer_param_s *param);
#define DEBOUNCER_INIT(initial_cnt, initial_output) \
{ \
.cnt = (initial_cnt), .out = (initial_output), \
}
typedef struct debouncer_ext
{
debouncer_s base;
debouncer_param_s param;
} debouncer_ext_s;
bool debounce_ext(debouncer_ext_s*obj, bool in);
static inline bool debouncer_ext_out(debouncer_ext_s *obj)
{
return obj->base.out;
}
#define DEBOUNCER_EXT_INIT(initial_output, _up_time, _down_time) \
{ \
.base = DEBOUNCER_INIT((initial_output) ? (_down_time) : (_up_time), initial_output), \
.param = \
{ \
.down_time = (_down_time), \
.up_time = (_up_time), \
}, \
}
static inline void debouncer_ext_force_set_out(debouncer_ext_s *obj, bool out)
{
obj->base.out = out;
obj->base.cnt = out ? obj->param.down_time : obj->param.up_time;
}
/*
* Schmitt trigger
*/
typedef struct schmitt_trigger
{
uint16_t high_thresh;
uint16_t low_thresh;
} schmitt_trigger_s;
#define SCHMITT_TRIGGER_INIT(high, low) \
{ \
.high_thresh = (high), \
.low_thresh = (low), \
}
static inline bool schmitt_process(const schmitt_trigger_s *obj, uint16_t input, bool prev_state)
{
return prev_state ? input > obj->low_thresh : input >= obj->high_thresh;
}
static inline bool schmitt_process_inverse(const schmitt_trigger_s *obj, uint16_t input, bool prev_state)
{
return prev_state ? input < obj->high_thresh : input <= obj->low_thresh;
}
/*
* RAMP
*/
#define RAMP(var, target, max_step) \
((target) > (var) ? \
(((var) + (max_step) > (target)) ? (target) : (var) + (max_step)) : \
(((var) < (target) + (max_step))? (target) : (var) - (max_step)))
/*
* Bitwise Operations
*/
uint8_t count_set_bits(uint32_t n);
#define FOREACH_BIT_U32(value, pos) \
for(uint32_t temp = (value), pos = __builtin_ffs(temp) - 1; temp != 0; temp &= (temp - 1), pos = __builtin_ffs(temp) - 1)
void enter_critical_section(void);
void exit_critical_section(void);
#endif /* UTIL_H */