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.
214 lines
4.9 KiB
214 lines
4.9 KiB
4 months ago
|
#ifndef PROTECTION_H
|
||
|
#define PROTECTION_H
|
||
|
|
||
|
#include <stdint.h>
|
||
|
#include <stdbool.h>
|
||
|
|
||
|
/*
|
||
|
* Predefined Fault Types
|
||
|
*/
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
FAULT_HW_BEGIN = 0,
|
||
|
FAULT_HW_VOUT_UVP = FAULT_HW_BEGIN,
|
||
|
FAULT_HW_DP_OVP,
|
||
|
FAULT_HW_DM_OVP,
|
||
|
FAULT_HW_OTP,
|
||
|
FAULT_HW_IOUT_OCP,
|
||
|
FAULT_HW_VOUT_OVP,
|
||
|
FAULT_HW_VBUS_SCP,
|
||
|
FAULT_HW_GATE_UVP,
|
||
|
FAULT_HW_VIN_OVP,
|
||
|
FAULT_HW_VIN_UVP,
|
||
|
FAULT_HW_CC_OV,
|
||
|
FAULT_HW_VCONN_OC,
|
||
|
FAULT_HW_V2_OC,
|
||
|
FAULT_HW_END,
|
||
|
};
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
FAULT_SW_BEGIN = FAULT_HW_END,
|
||
|
FAULT_SW_VOUT_UVP = FAULT_SW_BEGIN,
|
||
|
FAULT_SW_DP_OVP,
|
||
|
FAULT_SW_DM_OVP,
|
||
|
FAULT_SW_OTP,
|
||
|
FAULT_SW_IOUT_OCP,
|
||
|
FAULT_SW_VOUT_OVP,
|
||
|
FAULT_SW_VBUS_SCP,
|
||
|
FAULT_SW_VIN_OVP,
|
||
|
FAULT_SW_VIN_UVP,
|
||
|
FAULT_SW_SYS_ERROR,
|
||
|
FAULT_SW_END,
|
||
|
};
|
||
|
|
||
|
#define FALUT_CODE_END FAULT_SW_END
|
||
|
#define FAULT_ALL_MASK (BIT(FAULT_SW_END) - 1)
|
||
|
|
||
|
#define FAULT_RANGE_MASK(begin, end) ((BIT(end) - 1) & ~(BIT(begin) - 1))
|
||
|
|
||
|
#define FAULT_HW_ALL_MASK FAULT_RANGE_MASK(FAULT_HW_BEGIN, FAULT_HW_END)
|
||
|
#define FAULT_SW_ALL_MASK FAULT_RANGE_MASK(FAULT_SW_BEGIN, FAULT_SW_END)
|
||
|
|
||
|
/*
|
||
|
* Fault Status
|
||
|
*/
|
||
|
typedef struct
|
||
|
{
|
||
|
uint32_t flag;
|
||
|
uint32_t status;
|
||
|
uint32_t mask;
|
||
|
} fault_info_s;
|
||
|
|
||
|
void update_fault_status(fault_info_s *status,
|
||
|
uint32_t fault_num, bool in_fault);
|
||
|
void mask_update_fault_status(fault_info_s *status, uint32_t fault_mask, uint32_t mask);
|
||
|
|
||
|
void set_fault_status(fault_info_s *status, uint32_t fault_mask);
|
||
|
void clear_fault_status(fault_info_s *status, uint32_t fault_mask);
|
||
|
|
||
|
static inline void mask_fault(fault_info_s *status, uint32_t fault_num)
|
||
|
{
|
||
|
status->mask |= BIT(fault_num);
|
||
|
}
|
||
|
|
||
|
static inline void unmask_fault(fault_info_s *status, uint32_t fault_num)
|
||
|
{
|
||
|
status->mask &= ~BIT(fault_num);
|
||
|
}
|
||
|
|
||
|
void clear_all_fault_flag(fault_info_s *status);
|
||
|
|
||
|
/*
|
||
|
* Faults detected through software
|
||
|
*/
|
||
|
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;
|
||
|
|
||
|
typedef struct schmitt_trigger
|
||
|
{
|
||
|
uint16_t high_thresh;
|
||
|
uint16_t low_thresh;
|
||
|
} schmitt_trigger_s;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
debouncer_s deb;
|
||
|
} soft_fault_s;
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
debouncer_param_s debouncer_param;
|
||
|
schmitt_trigger_s schmitt;
|
||
|
uint8_t trigger_type;
|
||
|
uint8_t fault_name;
|
||
|
} soft_fault_param_s;
|
||
|
|
||
|
#define TRIGGER_HIGH 0
|
||
|
#define TRIGGER_LOW 1
|
||
|
#define DEBOUNCER_INIT(initial_cnt, initial_output) \
|
||
|
{ \
|
||
|
.cnt = (initial_cnt), .out = (initial_output), \
|
||
|
}
|
||
|
|
||
|
#define SCHMITT_TRIGGER_INIT(high, low) \
|
||
|
{ \
|
||
|
.high_thresh = (high), \
|
||
|
.low_thresh = (low), \
|
||
|
}
|
||
|
|
||
|
#define SOFT_FAULT_PARAM_INIT(_high_thresh, _low_thresh, _trigger_time, _recover_time, _trigger_type, name) \
|
||
|
{ \
|
||
|
.debouncer_param = \
|
||
|
{ \
|
||
|
.up_time = (_trigger_time), \
|
||
|
.down_time = (_recover_time), \
|
||
|
}, \
|
||
|
.schmitt = SCHMITT_TRIGGER_INIT(_high_thresh, _low_thresh), \
|
||
|
.trigger_type = (_trigger_type), \
|
||
|
.fault_name = (name), \
|
||
|
}
|
||
|
|
||
|
bool soft_fault_check(soft_fault_s *fault, uint16_t input,
|
||
|
const soft_fault_param_s *param,
|
||
|
fault_info_s *status);
|
||
|
|
||
|
static inline void update_soft_fault_thresholds(soft_fault_param_s *param,
|
||
|
uint16_t high, uint16_t low)
|
||
|
{
|
||
|
param->schmitt.high_thresh = high;
|
||
|
param->schmitt.low_thresh = low;
|
||
|
}
|
||
|
|
||
|
typedef struct
|
||
|
{
|
||
|
soft_fault_s fault;
|
||
|
soft_fault_param_s param;
|
||
|
} soft_fault_ext_s;
|
||
|
|
||
|
#define SOFT_FAULT_EXT_INIT(_high_thresh, _low_thresh, _trigger_time, _recover_time, _trigger_type, name) \
|
||
|
{ \
|
||
|
.fault = { .deb = DEBOUNCER_INIT((_trigger_time), (0)), }, \
|
||
|
.param = SOFT_FAULT_PARAM_INIT(_high_thresh, _low_thresh, _trigger_time, _recover_time, _trigger_type, name), \
|
||
|
}
|
||
|
|
||
|
void soft_abn_check(soft_fault_ext_s *fault, uint16_t input, fault_info_s *status);
|
||
|
|
||
|
static inline void update_soft_fault_ext_thresholds(soft_fault_ext_s *fault_ext,
|
||
|
uint16_t high, uint16_t low)
|
||
|
{
|
||
|
update_soft_fault_thresholds(&fault_ext->param, high, low);
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
* Fault Manager
|
||
|
*/
|
||
|
struct fault_mgr;
|
||
|
typedef struct fault_mgr fault_mgr_s;
|
||
|
|
||
|
typedef struct fault_mgr_ops
|
||
|
{
|
||
|
bool (*protect)(fault_mgr_s *mgr, uint32_t new_faults);
|
||
|
void (*recover)(fault_mgr_s *mgr);
|
||
|
} fault_mgr_ops_s;
|
||
|
|
||
|
#define FAULT_MGR_STATE_NORMAL 0
|
||
|
#define FAULT_MGR_STATE_FAULT 1
|
||
|
|
||
|
struct fault_mgr
|
||
|
{
|
||
|
fault_info_s fault_info;
|
||
|
uint32_t last_faults;
|
||
|
uint32_t recover_time;
|
||
|
const fault_mgr_ops_s *ops;
|
||
|
uint8_t state;
|
||
|
uint8_t name;
|
||
|
};
|
||
|
|
||
|
void fault_mgr_set_hiccup_time(fault_mgr_s *mgr, uint16_t hiccup_time);
|
||
|
|
||
|
static inline void regiser_fault_mgr_ops(fault_mgr_s *mgr,
|
||
|
const fault_mgr_ops_s *ops)
|
||
|
{
|
||
|
mgr->ops = ops;
|
||
|
}
|
||
|
|
||
|
void fault_manager_work(fault_mgr_s *mgr);
|
||
|
|
||
|
static inline bool fault_mgr_is_in_fault(fault_mgr_s *mgr)
|
||
|
{
|
||
|
return mgr->state != FAULT_MGR_STATE_NORMAL;
|
||
|
}
|
||
|
|
||
|
#endif /* PROTECTION_H */
|