|
|
|
@ -19,7 +19,7 @@ MODIFICATIONS |
|
|
|
|
|
|
|
23 Aug 1991 Jeffrey P. Murray |
|
|
|
30 Sep 1991 Jeffrey P. Murray |
|
|
|
|
|
|
|
06 Oct 2022 Holger Vogt |
|
|
|
|
|
|
|
SUMMARY |
|
|
|
|
|
|
|
@ -69,7 +69,10 @@ NON-STANDARD FEATURES |
|
|
|
|
|
|
|
/*=== LOCAL VARIABLES & TYPEDEFS =======*/ |
|
|
|
|
|
|
|
|
|
|
|
typedef struct { |
|
|
|
double *x; |
|
|
|
double *y; |
|
|
|
} Local_Data_t; |
|
|
|
|
|
|
|
|
|
|
|
/*=== FUNCTION PROTOTYPE DEFINITIONS ===*/ |
|
|
|
@ -120,6 +123,27 @@ NON-STANDARD FEATURES |
|
|
|
|
|
|
|
==============================================================================*/ |
|
|
|
|
|
|
|
static void cm_d_pwm_callback(ARGS, |
|
|
|
Mif_Callback_Reason_t reason) |
|
|
|
{ |
|
|
|
switch (reason) { |
|
|
|
case MIF_CB_DESTROY: { |
|
|
|
Local_Data_t *loc = STATIC_VAR(locdata); |
|
|
|
if (loc) { |
|
|
|
if (loc->x) |
|
|
|
free(loc->x); |
|
|
|
if(loc->y) |
|
|
|
free(loc->y); |
|
|
|
free(loc); |
|
|
|
STATIC_VAR(locdata) = loc = NULL; |
|
|
|
} |
|
|
|
break; |
|
|
|
} /* end of case MIF_CB_DESTROY */ |
|
|
|
} /* end of switch over reason being called */ |
|
|
|
} /* end of function cm_d_pwm_callback */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*=== CM_D_PWM ROUTINE ===*/ |
|
|
|
|
|
|
|
/************************************************************* |
|
|
|
@ -179,15 +203,12 @@ void cm_d_pwm(ARGS) |
|
|
|
slope; /* slope value...used to extrapolate |
|
|
|
freq values past endpoints. */ |
|
|
|
|
|
|
|
|
|
|
|
int i, /* generic loop counter index */ |
|
|
|
cntl_size, /* control array size */ |
|
|
|
dc_size; /* duty cycle array size */ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Local_Data_t *loc; /* Pointer to local static data, not to be included |
|
|
|
in the state vector (save memory!) */ |
|
|
|
|
|
|
|
/**** Retrieve frequently used parameters... ****/ |
|
|
|
|
|
|
|
@ -195,7 +216,6 @@ void cm_d_pwm(ARGS) |
|
|
|
dc_size = PARAM_SIZE(dc_array); |
|
|
|
frequency = PARAM(frequency); |
|
|
|
|
|
|
|
|
|
|
|
/* check and make sure that the control array is the |
|
|
|
same size as the frequency array */ |
|
|
|
|
|
|
|
@ -204,10 +224,8 @@ void cm_d_pwm(ARGS) |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/ |
|
|
|
|
|
|
|
|
|
|
|
/* Allocate storage for internal variables */ |
|
|
|
cm_analog_alloc(0, sizeof(double)); |
|
|
|
cm_analog_alloc(1, sizeof(double)); |
|
|
|
@ -220,15 +238,35 @@ void cm_d_pwm(ARGS) |
|
|
|
|
|
|
|
t3 = (double *) cm_analog_get_ptr(2,0); |
|
|
|
|
|
|
|
/*** allocate static storage for *loc ***/ |
|
|
|
STATIC_VAR (locdata) = calloc (1 , sizeof ( Local_Data_t )); |
|
|
|
loc = STATIC_VAR (locdata); |
|
|
|
CALLBACK = cm_d_pwm_callback; |
|
|
|
|
|
|
|
x = loc->x = (double *) calloc((size_t) cntl_size, sizeof(double)); |
|
|
|
if (!x) { |
|
|
|
cm_message_send(d_pwm_allocation_error); |
|
|
|
return; |
|
|
|
} |
|
|
|
y = loc->y = (double *) calloc((size_t) cntl_size, sizeof(double)); |
|
|
|
if (!y) { |
|
|
|
cm_message_send(d_pwm_allocation_error); |
|
|
|
if(x) |
|
|
|
free(x); |
|
|
|
return; |
|
|
|
} |
|
|
|
/* Retrieve x and y values. */ |
|
|
|
for (i=0; i<cntl_size; i++) { |
|
|
|
x[i] = PARAM(cntl_array[i]); |
|
|
|
y[i] = PARAM(dc_array[i]); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
else { /*** This is not an initialization pass...retrieve storage |
|
|
|
addresses and calculate new outputs, if required. ***/ |
|
|
|
|
|
|
|
|
|
|
|
/** Retrieve previous values... **/ |
|
|
|
|
|
|
|
|
|
|
|
/* assign internal variables */ |
|
|
|
phase = (double *) cm_analog_get_ptr(0,0); |
|
|
|
phase_old = (double *) cm_analog_get_ptr(0,1); |
|
|
|
@ -239,9 +277,6 @@ void cm_d_pwm(ARGS) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch (CALL_TYPE) { |
|
|
|
|
|
|
|
case ANALOG: /** analog call **/ |
|
|
|
@ -250,9 +285,7 @@ void cm_d_pwm(ARGS) |
|
|
|
|
|
|
|
if ( AC == ANALYSIS ) { /* this model does not function |
|
|
|
in AC analysis mode. */ |
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
else { |
|
|
|
|
|
|
|
@ -265,38 +298,17 @@ void cm_d_pwm(ARGS) |
|
|
|
} |
|
|
|
*phase = *phase / 360.0; |
|
|
|
|
|
|
|
|
|
|
|
/* set phase value to init_phase */ |
|
|
|
*phase_old = *phase; |
|
|
|
|
|
|
|
/* preset time values to harmless values... */ |
|
|
|
*t1 = -1; |
|
|
|
*t3 = -1; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Allocate storage for breakpoint domain & duty cycle range values */ |
|
|
|
|
|
|
|
x = (double *) calloc((size_t) cntl_size, sizeof(double)); |
|
|
|
if (!x) { |
|
|
|
cm_message_send(d_pwm_allocation_error); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
y = (double *) calloc((size_t) dc_size, sizeof(double)); |
|
|
|
if (!y) { |
|
|
|
cm_message_send(d_pwm_allocation_error); |
|
|
|
if(x) free(x); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
/* Retrieve x and y values. */ |
|
|
|
for (i=0; i<cntl_size; i++) { |
|
|
|
x[i] = PARAM(cntl_array[i]); |
|
|
|
y[i] = PARAM(dc_array[i]); |
|
|
|
} |
|
|
|
loc = STATIC_VAR (locdata); |
|
|
|
x = loc->x; |
|
|
|
y = loc->y; |
|
|
|
|
|
|
|
/* Retrieve cntl_input value. */ |
|
|
|
cntl_input = INPUT(cntl_in); |
|
|
|
@ -346,7 +358,6 @@ void cm_d_pwm(ARGS) |
|
|
|
// cm_message_send(d_pwm_positive_dc_error); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* calculate the instantaneous phase */ |
|
|
|
*phase = *phase_old + frequency * (TIME - T(1)); |
|
|
|
|
|
|
|
@ -354,7 +365,6 @@ void cm_d_pwm(ARGS) |
|
|
|
the period */ |
|
|
|
dphase = *phase_old - floor(*phase_old); |
|
|
|
|
|
|
|
|
|
|
|
/* Calculate the time variables and the output value |
|
|
|
for this iteration */ |
|
|
|
|
|
|
|
@ -365,8 +375,6 @@ void cm_d_pwm(ARGS) |
|
|
|
if(TIME < *t3) { |
|
|
|
cm_event_queue(*t3); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
|
|
|
|
@ -380,7 +388,6 @@ void cm_d_pwm(ARGS) |
|
|
|
if(TIME < *t1) { |
|
|
|
|
|
|
|
cm_event_queue(*t1); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
else { |
|
|
|
@ -395,23 +402,12 @@ void cm_d_pwm(ARGS) |
|
|
|
} |
|
|
|
|
|
|
|
*t3 = T(1) + (1 - dphase)/frequency; |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if(x) free(x); |
|
|
|
if(y) free(y); |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
case EVENT: /** discrete call...lots to do **/ |
|
|
|
|
|
|
|
|
|
|
|
test_double = TIME; |
|
|
|
|
|
|
|
if ( 0.0 == TIME ) { /* DC analysis...preset values, |
|
|
|
@ -424,7 +420,6 @@ void cm_d_pwm(ARGS) |
|
|
|
} |
|
|
|
*phase = *phase / 360.0; |
|
|
|
|
|
|
|
|
|
|
|
/* set phase value to init_phase */ |
|
|
|
*phase_old = *phase; |
|
|
|
|
|
|
|
@ -433,16 +428,12 @@ void cm_d_pwm(ARGS) |
|
|
|
*t3 = -1; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Calculate the time variables and the output value |
|
|
|
for this iteration */ |
|
|
|
|
|
|
|
/* Output is always set to STRONG */ |
|
|
|
OUTPUT_STRENGTH(out) = STRONG; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( *t1 == TIME ) { /* rising edge */ |
|
|
|
|
|
|
|
OUTPUT_STATE(out) = ONE; |
|
|
|
@ -471,9 +462,7 @@ void cm_d_pwm(ARGS) |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|