#include "rtapi.h"
#include "rtapi_app.h"
#include "rtapi_errno.h"
#include "hal.h"
#include "classicladder.h"
#include "global.h"
#include "calc.h"
#include "vars_access.h"
MODULE_LICENSE("LGPL");
MODULE_AUTHOR("Marc Le Douarain");
MODULE_DESCRIPTION("ClassicLadder HAL module");
int comedi_to_open_mask;
#ifdef DYNAMIC_PLCSIZE
int numRungs=NBR_RUNGS_DEF, numBits=NBR_BITS_DEF,numWords=NBR_WORDS_DEF, numTimers=NBR_TIMERS_DEF, numMonostables=NBR_MONOSTABLES_DEF;
int numCounters=NBR_COUNTERS_DEF,numTimersIec=NBR_TIMERS_IEC_DEF,numPhysInputs=NBR_PHYS_INPUTS_DEF, numPhysOutputs=NBR_PHYS_OUTPUTS_DEF, numArithmExpr=NBR_ARITHM_EXPR_DEF, numSections=NBR_SECTIONS_DEF;
int numSymbols=NBR_SYMBOLS_DEF,numS32in=NBR_PHYS_WORDS_INPUTS_DEF,numS32out=NBR_PHYS_WORDS_OUTPUTS_DEF;
int numFloatIn=NBR_PHYS_FLOAT_INPUTS_DEF,numFloatOut=NBR_PHYS_FLOAT_OUTPUTS_DEF;
RTAPI_MP_INT(numRungs, "i");
RTAPI_MP_INT(numBits, "i");
RTAPI_MP_INT(numWords, "i");
RTAPI_MP_INT(numTimers, "i");
RTAPI_MP_INT(numMonostables, "i");
RTAPI_MP_INT(numCounters, "i");
RTAPI_MP_INT(numTimersIec, "i");
RTAPI_MP_INT(numPhysInputs, "i");
RTAPI_MP_INT(numPhysOutputs, "i");
RTAPI_MP_INT(numArithmExpr, "i");
RTAPI_MP_INT(numSections, "i");
RTAPI_MP_INT(numSymbols, "i");
RTAPI_MP_INT(numS32in, "i");
RTAPI_MP_INT(numS32out, "i");
RTAPI_MP_INT(numFloatIn,"i");
RTAPI_MP_INT(numFloatOut,"i");
#else
#define numPhysInputs InfosGene->SizesInfos.nbr_phys_inputs
#define numPhysOutputs InfosGene->SizesInfos.nbr_phys_outputs
#define numWords InfosGene->SizesInfos.nbr_words
#endif
hal_bit_t **hal_inputs;
hal_bit_t **hide_gui;
hal_bit_t **hal_outputs;
hal_s32_t **hal_s32_inputs;
hal_s32_t **hal_s32_outputs;
hal_s32_t *hal_state;
hal_float_t **hal_float_inputs;
hal_float_t **hal_float_outputs;
extern StrGeneralParams GeneralParamsMirror;
#define TIME_REFRESH_RUNG_NS (1000 * 1000 * (TIME_REFRESH_RUNG_MS))
void HalReadPhysicalInputs(void) {
int i;
for( i=0; i<InfosGene->GeneralParams.SizesInfos.nbr_phys_inputs; i++) {
WriteVar(VAR_PHYS_INPUT, i, *hal_inputs[i]);
}
}
void HalWritePhysicalOutputs(void) {
int i;
for( i=0; i<InfosGene->GeneralParams.SizesInfos.nbr_phys_outputs; i++) {
*(hal_outputs[i]) = ReadVar(VAR_PHYS_OUTPUT, i);
}
}
void HalReads32Inputs(void) {
int i;
for( i=0; i<InfosGene->GeneralParams.SizesInfos.nbr_phys_words_inputs; i++) {
WriteVar(VAR_PHYS_WORD_INPUT, i, *hal_s32_inputs[i]);
}
}
void HalWrites32Outputs(void) {
int i;
for( i=0; i<InfosGene->GeneralParams.SizesInfos.nbr_phys_words_outputs; i++) {
*(hal_s32_outputs[i]) = ReadVar(VAR_PHYS_WORD_OUTPUT, i);
}
}
void HalReadFloatInputs(void) {
int i;
for( i=0; i<InfosGene->GeneralParams.SizesInfos.nbr_phys_float_inputs; i++) {
WriteVar(VAR_PHYS_FLOAT_INPUT, i, *hal_float_inputs[i]);
}
}
void HalWriteFloatOutputs(void) {
int i;
for( i=0; i<InfosGene->GeneralParams.SizesInfos.nbr_phys_float_outputs; i++) {
*(hal_float_outputs[i]) = ReadVar(VAR_PHYS_FLOAT_OUTPUT, i);
}
}
static void hal_task(void *arg, long period) {
unsigned long t0, t1,milliseconds;
static unsigned long leftover=0;
leftover += period;
milliseconds= leftover / 1000000;
leftover %= 1000000;
if (milliseconds >= 1) {
InfosGene->GeneralParams.PeriodicRefreshMilliSecs=milliseconds;
*hal_state = InfosGene->LadderState;
t0 = rtapi_get_time();
if (InfosGene->LadderState==STATE_RUN)
{
HalReadPhysicalInputs();
HalReads32Inputs();
HalReadFloatInputs();
InfosGene->HideGuiState = *hide_gui[0];
ClassicLadder_RefreshAllSections();
HalWritePhysicalOutputs();
HalWrites32Outputs();
HalWriteFloatOutputs();
}
t1 = rtapi_get_time();
InfosGene->DurationOfLastScan = t1 - t0;
}
}
extern void CopySizesInfosFromModuleParams( void );
int rtapi_app_main(void) {
int result, i;
CopySizesInfosFromModuleParams();
compId = hal_init("classicladder_rt");
if(compId < 0) return compId;
rtapi_print("creating ladder-state\n");
result = hal_export_funct("classicladder.0.refresh",hal_task,0,1, 0, compId);
if(result < 0) {
error:
hal_exit(compId);
return result;
}
hal_state = hal_malloc(sizeof(hal_s32_t));
result = hal_param_s32_new("classicladder.ladder-state", HAL_RO, hal_state, compId);
if(result < 0) {
hal_exit(compId);
return result;
}
hal_inputs = hal_malloc(sizeof(hal_bit_t*) * numPhysInputs);
if(!hal_inputs) { result = -ENOMEM; goto error; }
hide_gui = hal_malloc(sizeof(hal_bit_t*));
if(!hide_gui) { result = -ENOMEM; goto error; }
hal_s32_inputs = hal_malloc(sizeof(hal_s32_t*) * numS32in);
if(!hal_s32_inputs) { result = -ENOMEM; goto error; }
hal_float_inputs = hal_malloc(sizeof(hal_float_t*) * numFloatIn);
if(!hal_float_inputs) { result = -ENOMEM; goto error; }
hal_outputs = hal_malloc(sizeof(hal_bit_t*) * numPhysOutputs);
if(!hal_outputs) { result = -ENOMEM; goto error; }
hal_s32_outputs = hal_malloc(sizeof(hal_s32_t*) * numS32out);
if(!hal_s32_outputs) { result = -ENOMEM; goto error; }
hal_float_outputs = hal_malloc(sizeof(hal_float_t*) * numFloatOut);
if(!hal_float_outputs) { result = -ENOMEM; goto error; }
for(i=0; i<numPhysInputs; i++) {
result = hal_pin_bit_newf(HAL_IN, &hal_inputs[i], compId,
"classicladder.0.in-%02d", i);
if(result < 0) goto error;
}
result = hal_pin_bit_newf(HAL_IN, &hide_gui[0], compId,
"classicladder.0.hide_gui");
if(result < 0) goto error;
for(i=0; i<numS32in; i++) {
result = hal_pin_s32_newf(HAL_IN, &hal_s32_inputs[i], compId,
"classicladder.0.s32in-%02d", i);
if(result < 0) goto error;
}
for(i=0; i<numFloatIn; i++) {
result = hal_pin_float_newf(HAL_IN, &hal_float_inputs[i], compId,
"classicladder.0.floatin-%02d", i);
if(result < 0) goto error;
}
for(i=0; i<numPhysOutputs; i++) {
result = hal_pin_bit_newf(HAL_OUT, &hal_outputs[i], compId,
"classicladder.0.out-%02d", i);
if(result < 0) goto error;
}
for(i=0; i<numS32out; i++) {
result = hal_pin_s32_newf(HAL_OUT, &hal_s32_outputs[i], compId,
"classicladder.0.s32out-%02d", i);
if(result < 0) goto error;
}
for(i=0; i<numFloatOut; i++) {
result = hal_pin_float_newf(HAL_OUT, &hal_float_outputs[i], compId,
"classicladder.0.floatout-%02d", i);
if(result < 0) goto error;
}
hal_ready(compId);
ClassicLadder_AllocAll( );
return 0;
}
void rtapi_app_exit(void) {
ClassicLadder_FreeAll( FALSE);
hal_exit(compId);
}
void CopySizesInfosFromModuleParams( void ) {
plc_sizeinfo_s *pSizesInfos;
pSizesInfos = &GeneralParamsMirror.SizesInfos;
#ifdef DYNAMIC_PLCSIZE
if ( numRungs>0 )
GeneralParamsMirror.SizesInfos.nbr_rungs = numRungs;
if ( numBits>0 )
GeneralParamsMirror.SizesInfos.nbr_bits = numBits;
if ( numWords>0 )
GeneralParamsMirror.SizesInfos.nbr_words = numWords;
if ( numTimers>0 )
GeneralParamsMirror.SizesInfos.nbr_timers = numTimers;
if ( numMonostables>0 )
GeneralParamsMirror.SizesInfos.nbr_monostables = numMonostables;
if ( numCounters>0 )
GeneralParamsMirror.SizesInfos.nbr_counters = numCounters;
if ( numTimersIec>0 )
GeneralParamsMirror.SizesInfos.nbr_timers_iec = numTimersIec;
if ( numPhysInputs>0 )
GeneralParamsMirror.SizesInfos.nbr_phys_inputs = numPhysInputs;
if ( numPhysOutputs>0 )
GeneralParamsMirror.SizesInfos.nbr_phys_outputs = numPhysOutputs;
if ( numArithmExpr>0 )
GeneralParamsMirror.SizesInfos.nbr_arithm_expr = numArithmExpr;
if ( numSections>0 )
GeneralParamsMirror.SizesInfos.nbr_sections = numSections;
if ( numS32in>0 )
GeneralParamsMirror.SizesInfos.nbr_phys_words_inputs = numS32in;
if ( numS32out>0 )
GeneralParamsMirror.SizesInfos.nbr_phys_words_outputs = numS32out;
if ( numFloatIn>0 )
GeneralParamsMirror.SizesInfos.nbr_phys_float_inputs = numFloatIn;
if ( numFloatOut>0 )
GeneralParamsMirror.SizesInfos.nbr_phys_float_outputs = numFloatOut;
GeneralParamsMirror.SizesInfos.nbr_symbols = pSizesInfos->nbr_bits + pSizesInfos->nbr_words ;
GeneralParamsMirror.SizesInfos.nbr_symbols += pSizesInfos->nbr_timers + pSizesInfos->nbr_monostables ;
GeneralParamsMirror.SizesInfos.nbr_symbols += pSizesInfos->nbr_counters + pSizesInfos->nbr_timers_iec ;
GeneralParamsMirror.SizesInfos.nbr_symbols += pSizesInfos->nbr_phys_inputs + pSizesInfos->nbr_phys_outputs ;
GeneralParamsMirror.SizesInfos.nbr_symbols += pSizesInfos->nbr_phys_words_inputs + pSizesInfos->nbr_phys_words_outputs;
GeneralParamsMirror.SizesInfos.nbr_symbols += pSizesInfos->nbr_phys_float_inputs + pSizesInfos->nbr_phys_float_outputs + NBR_ERROR_BITS_DEF ;
if (numSymbols < GeneralParamsMirror.SizesInfos.nbr_symbols ) { GeneralParamsMirror.SizesInfos.nbr_symbols = numSymbols; }
#endif
}