avr-fw-modules/core/src/outputs.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;
};