135 lines
2.8 KiB
C
135 lines
2.8 KiB
C
#include <sys/outputs.h>
|
|
|
|
#include <sys/atomic.h>
|
|
#include <sys/adc.h>
|
|
#include <sys/mutex.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <avr/io.h>
|
|
|
|
struct {
|
|
MUTEX mutex;
|
|
int len;
|
|
digout_t* defs;
|
|
} _sys_outputs;
|
|
|
|
void outputs_init(digout_t *outputs,int len){
|
|
ATOMIC
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
|
|
#if 0
|
|
if (len % sizeof(struct _protected_output)){
|
|
_sys_outputs.defs = NULL;
|
|
_sys_outputs.len = 0;
|
|
} else {
|
|
#endif
|
|
_sys_outputs.defs = outputs;
|
|
_sys_outputs.len = len / sizeof(struct _protected_output);
|
|
#if 0
|
|
};
|
|
#endif
|
|
|
|
};
|
|
|
|
int8_t outputs_num(void){
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
return _sys_outputs.len;
|
|
};
|
|
|
|
void output_on(int no){
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
if (no < _sys_outputs.len){
|
|
ATOMIC
|
|
|
|
if (_sys_outputs.defs[no].features & POF_TRIGGER_ON){
|
|
|
|
if (_sys_outputs.defs[no].inverse & POF_TRIGGER_ON){
|
|
trigger_neg( _sys_outputs.defs[no].reg_on, _sys_outputs.defs[no].bit_on);
|
|
} else {
|
|
trigger_pos( _sys_outputs.defs[no].reg_on, _sys_outputs.defs[no].bit_on);
|
|
};
|
|
|
|
} else if (_sys_outputs.defs[no].features & POF_SET_ON){
|
|
|
|
if (_sys_outputs.defs[no].inverse & POF_SET_ON){
|
|
*_sys_outputs.defs[no].reg_on &= ~(1 << _sys_outputs.defs[no].bit_on);
|
|
} else {
|
|
*_sys_outputs.defs[no].reg_on |= (1 << _sys_outputs.defs[no].bit_on);
|
|
};
|
|
|
|
};
|
|
|
|
_sys_outputs.defs[no].status = POS_CTRL_ON;
|
|
};
|
|
};
|
|
|
|
void output_off(int no){
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
if (no < _sys_outputs.len){
|
|
ATOMIC
|
|
|
|
if (_sys_outputs.defs[no].features & POF_TRIGGER_OFF){
|
|
|
|
if (_sys_outputs.defs[no].inverse & POF_TRIGGER_OFF) {
|
|
trigger_neg( _sys_outputs.defs[no].reg_off, _sys_outputs.defs[no].bit_off);
|
|
} else {
|
|
trigger_pos( _sys_outputs.defs[no].reg_off, _sys_outputs.defs[no].bit_off);
|
|
};
|
|
|
|
} else if (_sys_outputs.defs[no].features & POF_SET_OFF) {
|
|
|
|
if (_sys_outputs.defs[no].inverse & POF_SET_OFF){
|
|
*_sys_outputs.defs[no].reg_off |= (1 << _sys_outputs.defs[no].bit_off);
|
|
} else {
|
|
*_sys_outputs.defs[no].reg_off &= ~(1 << _sys_outputs.defs[no].bit_off);
|
|
};
|
|
|
|
};
|
|
_sys_outputs.defs[no].status = POS_CTRL_OFF;
|
|
};
|
|
};
|
|
|
|
int32_t output_read(int no){
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
if (no < _sys_outputs.len){
|
|
return _sys_outputs.defs[no].status;
|
|
};
|
|
return 0;
|
|
};
|
|
|
|
void output_failed_overcurrent(int no){
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
if (no < _sys_outputs.len){
|
|
output_off(no);
|
|
_sys_outputs.defs[no].status |= POS_OVERCURRENT;
|
|
};
|
|
};
|
|
|
|
fp4816_t output_current (int no){
|
|
MUTEXED(&_sys_outputs.mutex);
|
|
if (no < _sys_outputs.len){
|
|
|
|
if (_sys_outputs.defs[no].features & POF_SENS_OC){
|
|
|
|
fp4816_t i = fp4816_mul(
|
|
fp4816_add(
|
|
adc_value( _sys_outputs.defs[no].sens_chan),
|
|
_sys_outputs.defs[no].sens_offset
|
|
),
|
|
_sys_outputs.defs[no].sens_scale
|
|
);
|
|
return i;
|
|
};
|
|
};
|
|
return 0;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|