Add new capabilities to the adc/dac_bridge XSPICE code models.
If either bridge has a single analog connection and two or more digital connections it will act as a conventional multi-bit ADC or DAC. When the low threshold is higher than the high threshold, adc_bridge acts as a Schmitt trigger.
This commit is contained in:
parent
5a53a2ecd2
commit
b649ab78b9
|
|
@ -96,10 +96,21 @@ NON-STANDARD FEATURES
|
|||
|
||||
static Digital_State_t get_out_value(double in, double low, double high)
|
||||
{
|
||||
if (in >= high)
|
||||
return ONE;
|
||||
else if (in <= low)
|
||||
return ZERO;
|
||||
if (low <= high) {
|
||||
/* Normal operation. */
|
||||
|
||||
if (in >= high)
|
||||
return ONE;
|
||||
else if (in <= low)
|
||||
return ZERO;
|
||||
} else {
|
||||
/* (low > high)! Schmitt triger. */
|
||||
|
||||
if (in >= low)
|
||||
return ONE;
|
||||
else if (in <= high)
|
||||
return ZERO;
|
||||
}
|
||||
return UNKNOWN;
|
||||
}
|
||||
|
||||
|
|
@ -110,22 +121,34 @@ void cm_adc_bridge(ARGS)
|
|||
in_high; /* analog output value corresponding to '1'
|
||||
digital input */
|
||||
int i, /* generic loop counter index */
|
||||
size; /* number of input & output ports */
|
||||
size_in, /* number of input ports */
|
||||
size_out; /* number of output ports */
|
||||
|
||||
Digital_State_t *out, /* base address of array holding all output
|
||||
values plus their previous values */
|
||||
test; /* temp holding variable for digital states */
|
||||
|
||||
/* determine "width" of the node bridge... */
|
||||
|
||||
size = PORT_SIZE(in);
|
||||
in_high = PARAM(in_high);
|
||||
in_low = PARAM(in_low);
|
||||
|
||||
/* determine "width" of the node bridge... */
|
||||
|
||||
size_in = PORT_SIZE(in);
|
||||
size_out = PORT_SIZE(out);
|
||||
|
||||
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/
|
||||
if (size_in != size_out) {
|
||||
if (size_in != 1) {
|
||||
cm_message_printf("Error: %d input ports with %d outputs",
|
||||
size_in, size_out);
|
||||
} else if (in_low >= in_high) {
|
||||
cm_message_printf("Error: bad threshold values (low > high)");
|
||||
}
|
||||
}
|
||||
|
||||
/* Allocate storage for outputs */
|
||||
|
||||
cm_event_alloc(0, size * (int) sizeof(Digital_State_t));
|
||||
cm_event_alloc(0, size_out * (int) sizeof(Digital_State_t));
|
||||
|
||||
/* Get discrete addresses */
|
||||
|
||||
|
|
@ -133,7 +156,7 @@ void cm_adc_bridge(ARGS)
|
|||
|
||||
/* Ensure output on first call. */
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
for (i = 0; i < size_out; i++)
|
||||
out[i] = UNKNOWN + 1;
|
||||
return;
|
||||
}
|
||||
|
|
@ -143,13 +166,75 @@ void cm_adc_bridge(ARGS)
|
|||
|
||||
out = (Digital_State_t *) cm_event_get_ptr(0, 0);
|
||||
|
||||
if (size_in != size_out) {
|
||||
if (size_in != 1) {
|
||||
if (size_in < size_out)
|
||||
size_out = size_in;
|
||||
else
|
||||
size_in = size_out;
|
||||
} else {
|
||||
double in;
|
||||
|
||||
/* Single-input, multi-bit output option. */
|
||||
|
||||
in = (INPUT(in[0]) - in_low) / (in_high - in_low);
|
||||
switch (CALL_TYPE) {
|
||||
case ANALOG:
|
||||
for (i = 0; i < size_out; i++) {
|
||||
test = (in >= 0.5);
|
||||
if (test != out[i]) {
|
||||
/* call for event breakpoint... */
|
||||
|
||||
cm_event_queue(TIME);
|
||||
break;
|
||||
}
|
||||
if (test)
|
||||
in -= 0.5;
|
||||
in *= 2.0;
|
||||
}
|
||||
break;
|
||||
|
||||
case EVENT: /** discrete call...lots to do **/
|
||||
for (i = 0; i < size_out; i++) {
|
||||
test = (in >= 0.5);
|
||||
if (test != out[i]) {
|
||||
switch (test) {
|
||||
case ZERO:
|
||||
OUTPUT_DELAY(out[i]) = PARAM(fall_delay);
|
||||
break;
|
||||
case ONE:
|
||||
OUTPUT_DELAY(out[i]) = PARAM(rise_delay);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
out[i] = test;
|
||||
OUTPUT_STATE(out[i]) = test;
|
||||
OUTPUT_STRENGTH(out[i]) = STRONG;
|
||||
} else {
|
||||
OUTPUT_CHANGED(out[i]) = FALSE;
|
||||
}
|
||||
if (test)
|
||||
in -= 0.5;
|
||||
in *= 2.0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Normal, multiple single-bit conversion output option. */
|
||||
|
||||
switch (CALL_TYPE) {
|
||||
case ANALOG: /** analog call...check for breakpoint calls. **/
|
||||
/* loop through all inputs... */
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
for (i = 0; i < size_out; i++) {
|
||||
test = get_out_value(INPUT(in[i]), in_low, in_high);
|
||||
if (test != out[i]) {
|
||||
if (test != out[i]) {
|
||||
/* call for event breakpoint... */
|
||||
|
||||
cm_event_queue(TIME);
|
||||
|
|
@ -161,9 +246,9 @@ void cm_adc_bridge(ARGS)
|
|||
case EVENT: /** discrete call...lots to do **/
|
||||
/* loop through all inputs... */
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
for (i = 0; i < size_out; i++) {
|
||||
test = get_out_value(INPUT(in[i]), in_low, in_high);
|
||||
if (test != out[i]) {
|
||||
if (test != out[i]) {
|
||||
/* Post changed value. */
|
||||
|
||||
OUTPUT_STATE(out[i]) = test;
|
||||
|
|
@ -175,6 +260,12 @@ void cm_adc_bridge(ARGS)
|
|||
OUTPUT_DELAY(out[i]) = PARAM(rise_delay);
|
||||
break;
|
||||
default:
|
||||
if (in_low > in_high) {
|
||||
/* Input is in hysteresis band. */
|
||||
|
||||
OUTPUT_CHANGED(out[i]) = FALSE;
|
||||
continue;
|
||||
}
|
||||
if (out[i] == ZERO)
|
||||
OUTPUT_DELAY(out[i]) = PARAM(rise_delay);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -24,6 +24,11 @@ Spice_Model_Name: adc_bridge
|
|||
C_Function_Name: cm_adc_bridge
|
||||
Description: "analog-to-digital converter node bridge"
|
||||
|
||||
/* Input and output are vector ports. If port numbers are equal the
|
||||
* device acts as a set of individual comparators (use %vd or %id for
|
||||
* differential inputs. With a single input and multiple outputs,
|
||||
* it is a single ADC with multi-bit output.
|
||||
*/
|
||||
|
||||
PORT_TABLE:
|
||||
|
||||
|
|
@ -32,11 +37,12 @@ Description: "input" "output"
|
|||
Direction: in out
|
||||
Default_Type: v d
|
||||
Allowed_Types: [v,vd,i,id,vnam] [d]
|
||||
Vector: yes yes
|
||||
Vector_Bounds: - -
|
||||
Vector: yes yes
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: no no
|
||||
|
||||
|
||||
/* If in_low > in_high the adc_bridge has hysteresis - a Schmitt trigger. */
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
|
|
@ -72,3 +78,15 @@ Limits: [1e-12 -] [1e-12 -]
|
|||
Vector: no no
|
||||
Vector_Bounds: - -
|
||||
Null_Allowed: yes yes
|
||||
|
||||
|
||||
PARAMETER_TABLE:
|
||||
|
||||
Parameter_Name: family
|
||||
Description: "Logic family for bridging"
|
||||
Data_Type: string
|
||||
Default_Value: -
|
||||
Limits: -
|
||||
Vector: no
|
||||
Vector_Bounds: -
|
||||
Null_Allowed: yes
|
||||
|
|
|
|||
|
|
@ -14,19 +14,16 @@ AUTHORS
|
|||
|
||||
3 Jun 1991 Jeffrey P. Murray
|
||||
|
||||
|
||||
MODIFICATIONS
|
||||
|
||||
16 Aug 1991 Jeffrey P. Murray
|
||||
2 Oct 1991 Jeffrey P. Murray
|
||||
|
||||
|
||||
SUMMARY
|
||||
|
||||
This file contains the model-specific routines used to
|
||||
functionally describe the dac_bridge code model.
|
||||
|
||||
|
||||
INTERFACES
|
||||
|
||||
FILE ROUTINE CALLED
|
||||
|
|
@ -38,11 +35,9 @@ INTERFACES
|
|||
CMevt.c void *cm_event_alloc()
|
||||
void *cm_event_get_ptr()
|
||||
|
||||
|
||||
REFERENCED FILES
|
||||
|
||||
Inputs from and outputs to ARGS structure.
|
||||
|
||||
|
||||
NON-STANDARD FEATURES
|
||||
|
||||
|
|
@ -115,8 +110,7 @@ NON-STANDARD FEATURES
|
|||
|
||||
NONE
|
||||
|
||||
==============================================================================*/
|
||||
|
||||
=============================================================================*/
|
||||
|
||||
/* Instances of this structure track digital input changes. */
|
||||
|
||||
|
|
@ -125,6 +119,29 @@ struct d_data {
|
|||
double i_changed; // Time of input change.
|
||||
};
|
||||
|
||||
/* Relative output value for multi-bit input. */
|
||||
|
||||
static double get_out_val(struct d_data *dp, int size)
|
||||
{
|
||||
double v;
|
||||
int i;
|
||||
|
||||
for (i = size - 1, v = 0.0; i >= 0; --i) {
|
||||
v /= 2.0;
|
||||
switch (dp[i].i) {
|
||||
case ONE:
|
||||
v += 0.5;
|
||||
break;
|
||||
case UNKNOWN:
|
||||
v += 0.25;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
/*=== CM_DAC_BRIDGE ROUTINE ===*/
|
||||
|
||||
/************************************************
|
||||
|
|
@ -135,9 +152,7 @@ struct d_data {
|
|||
* Created 6/3/91 J.P.Murray *
|
||||
************************************************/
|
||||
|
||||
|
||||
void cm_dac_bridge(ARGS)
|
||||
|
||||
{
|
||||
double out_low, /* analog output value corresponding to '0'
|
||||
digital input */
|
||||
|
|
@ -157,18 +172,16 @@ void cm_dac_bridge(ARGS)
|
|||
time_inc; /* time increment since last analog call */
|
||||
|
||||
int i, /* generic loop counter index */
|
||||
size; /* number of input & output ports */
|
||||
multi, /* Multi-bit in, single real out. */
|
||||
size_in, /* number of input ports */
|
||||
size_out; /* number of output ports */
|
||||
|
||||
struct d_data *in, /* base address of array holding all input
|
||||
struct d_data *in, /* base address of array holding all input
|
||||
values */
|
||||
*in_old; /* array holding previous input values */
|
||||
*in_old; /* array holding previous input values */
|
||||
|
||||
|
||||
/* determine "width" of the node bridge... */
|
||||
|
||||
size = PORT_SIZE(in);
|
||||
|
||||
/** Read in remaining model parameters **/
|
||||
/* Read in model parameters. **/
|
||||
|
||||
out_low = PARAM(out_low);
|
||||
out_high = PARAM(out_high);
|
||||
|
|
@ -180,20 +193,38 @@ void cm_dac_bridge(ARGS)
|
|||
/* if so, take out_undef as mean of out_high and out_low. */
|
||||
|
||||
if (!PARAM_NULL(out_low) && !PARAM_NULL(out_high) &&
|
||||
PARAM_NULL(out_undef) ) {
|
||||
PARAM_NULL(out_undef)) {
|
||||
out_undef = out_low + (out_high - out_low) / 2.0;
|
||||
} else {
|
||||
out_undef = PARAM(out_undef);
|
||||
}
|
||||
|
||||
/* determine "width" of the node bridge... */
|
||||
|
||||
size_in = PORT_SIZE(in);
|
||||
size_out = PORT_SIZE(out);
|
||||
multi = (size_in != size_out && size_out == 1);
|
||||
if (!multi) {
|
||||
if (size_in < size_out)
|
||||
size_out = size_in;
|
||||
else
|
||||
size_in = size_out;
|
||||
}
|
||||
|
||||
|
||||
if (INIT) { /*** Test for INIT == TRUE. If so, allocate storage, etc. ***/
|
||||
if (size_in != size_out && size_out != 1) {
|
||||
cm_message_printf("Error: %d input ports with %d outputs",
|
||||
size_in, size_out);
|
||||
}
|
||||
|
||||
/* Allocate storage for inputs */
|
||||
|
||||
cm_event_alloc(0, size * (int) sizeof(struct d_data));
|
||||
cm_event_alloc(0, size_in * (int)sizeof(struct d_data));
|
||||
|
||||
/* Allocate storage for outputs */
|
||||
|
||||
cm_analog_alloc(0, size * (int) sizeof(double));
|
||||
cm_analog_alloc(0, size_out * (int)sizeof(double));
|
||||
|
||||
/* Retrieve allocated addresses. */
|
||||
|
||||
|
|
@ -201,88 +232,202 @@ void cm_dac_bridge(ARGS)
|
|||
out = (double *) cm_analog_get_ptr(0, 0);
|
||||
|
||||
/* read current input values */
|
||||
for (i=0; i<size; i++) {
|
||||
for (i = 0; i < size_in; i++) {
|
||||
in[i].i = INPUT_STATE(in[i]);
|
||||
}
|
||||
|
||||
/* Output initial analog levels based on input values */
|
||||
|
||||
for (i=0; i<size; i++) { /* assign addresses */
|
||||
switch (in[i].i) {
|
||||
if (multi) {
|
||||
/* Multi-bit input, single_output. */
|
||||
|
||||
OUTPUT(out[0]) = *out =
|
||||
get_out_val(in, size_in) * (out_high - out_low) + out_low;
|
||||
} else {
|
||||
for (i = 0; i < size_in; i++) { /* assign addresses */
|
||||
switch (in[i].i) {
|
||||
case ZERO: out[i] = out_low;
|
||||
break;
|
||||
break;
|
||||
|
||||
case UNKNOWN: out[i] = out_undef;
|
||||
break;
|
||||
break;
|
||||
|
||||
case ONE: out[i] = out_high;
|
||||
break;
|
||||
break;
|
||||
}
|
||||
OUTPUT(out[i]) = out[i];
|
||||
}
|
||||
OUTPUT(out[i]) = out[i];
|
||||
}
|
||||
for (i = 0; i < size_in; i++)
|
||||
LOAD(in[i]) = PARAM(input_load);
|
||||
}
|
||||
return;
|
||||
} else { /*** This is not an initialization pass...read in parameters,
|
||||
retrieve storage addresses and calculate new outputs,
|
||||
if required. ***/
|
||||
|
||||
/** Retrieve previous values... **/
|
||||
|
||||
/* assign discrete addresses */
|
||||
|
||||
in = (struct d_data *) cm_event_get_ptr(0, 0);
|
||||
in_old= (struct d_data *) cm_event_get_ptr(0, 1);
|
||||
|
||||
/* assign analog addresses */
|
||||
out = (double *) cm_analog_get_ptr(0, 0);
|
||||
out_old = (double *) cm_analog_get_ptr(0, 1);
|
||||
|
||||
/* read current input values */
|
||||
for (i=0; i<size; i++) {
|
||||
in[i].i = INPUT_STATE(in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* This is not an initialization pass...read in parameters,
|
||||
retrieve storage addresses and calculate new outputs, if required.
|
||||
*/
|
||||
|
||||
/** Retrieve previous values... **/
|
||||
|
||||
in = (struct d_data *) cm_event_get_ptr(0, 0);
|
||||
in_old= (struct d_data *) cm_event_get_ptr(0, 1);
|
||||
|
||||
/* assign analog addresses */
|
||||
out = (double *) cm_analog_get_ptr(0, 0);
|
||||
out_old = (double *) cm_analog_get_ptr(0, 1);
|
||||
|
||||
/* read current input values */
|
||||
for (i = 0; i < size_in; i++) {
|
||||
in[i].i = INPUT_STATE(in[i]);
|
||||
}
|
||||
|
||||
switch (CALL_TYPE) {
|
||||
double when, iota, vout, interval[2];
|
||||
int step, step_count;
|
||||
|
||||
case EVENT: /** discrete call... **/
|
||||
/* Test to see if any change has occurred in an input */
|
||||
/* since the last digital call... */
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
for (i = 0; i < size_in; i++) {
|
||||
if (in[i].i != in_old[i].i) { /* if there has been a change... */
|
||||
in[i].i_changed = TIME;
|
||||
|
||||
/* post current time as a breakpoint */
|
||||
|
||||
cm_analog_set_perm_bkpt(TIME);
|
||||
|
||||
if (multi) {
|
||||
in[0].i_changed = TIME;
|
||||
break;
|
||||
} else {
|
||||
in[i].i_changed = TIME;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ANALOG: /** analog call... **/
|
||||
|
||||
level_inc = out_high - out_low;
|
||||
rise_slope = level_inc / t_rise;
|
||||
fall_slope = level_inc / t_fall;
|
||||
|
||||
time_inc = TIME - T(1);
|
||||
time_inc = T(0) - T(1);
|
||||
|
||||
for (i=0; i<size; i++) {
|
||||
if (multi) {
|
||||
double v, target;
|
||||
int changed;
|
||||
|
||||
/* Multi-bit input, single_output. */
|
||||
|
||||
v = get_out_val(in, size_in);
|
||||
if (TIME == 0.0) {
|
||||
OUTPUT(out[0]) = *out = v * level_inc + out_low;;
|
||||
return;
|
||||
}
|
||||
vout = (out_old[0] - out_low) / level_inc; // Normalise.
|
||||
|
||||
for (i = 0, changed = 0; i < size_in; i++) {
|
||||
if (in_old[i].i != in[i].i) {
|
||||
changed = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!changed) {
|
||||
if (vout < v) {
|
||||
/* Continue rising. */
|
||||
|
||||
vout += time_inc / t_rise;
|
||||
if (vout > v)
|
||||
vout = v;
|
||||
} else {
|
||||
/* Continue falling. */
|
||||
|
||||
vout -= time_inc / t_fall;
|
||||
if (vout < v)
|
||||
vout = v;
|
||||
}
|
||||
} else {
|
||||
/* There has been a change in input since the last
|
||||
analog access. Determine when the change occurred
|
||||
and calculate the current output, then set a breakpoint
|
||||
for completion of the current transition.
|
||||
*/
|
||||
|
||||
iota = time_inc * 1e-7; // Ignorable
|
||||
if (T(0) - in[0].i_changed < iota) {
|
||||
/* Previous input value in force for whole step. */
|
||||
|
||||
step_count = 1;
|
||||
step = 0;
|
||||
interval[0] = time_inc;
|
||||
} else if (in[0].i_changed - T(1) < iota) {
|
||||
/* New input value in force for whole step.
|
||||
* Includes common no-change case where new == old.
|
||||
*/
|
||||
|
||||
step_count = 2;
|
||||
step = 1;
|
||||
interval[1] = time_inc;
|
||||
} else {
|
||||
/* Calculate both sides of change. */
|
||||
|
||||
step_count = 2;
|
||||
step = 0;
|
||||
interval[0] = in[0].i_changed - T(1);
|
||||
interval[1] = T(0) - in[0].i_changed;
|
||||
}
|
||||
|
||||
when = -1.0;
|
||||
for (; step < step_count; ++step) {
|
||||
int last_step = (step == step_count - 1);
|
||||
|
||||
if (step == 0)
|
||||
target = get_out_val(in_old, size_in);
|
||||
else
|
||||
target = v;
|
||||
|
||||
if (target > vout) {
|
||||
/* Rising. */
|
||||
|
||||
vout += interval[step] / t_rise;
|
||||
if (vout > v)
|
||||
vout = v;
|
||||
else if (last_step)
|
||||
when = (v - vout) * t_rise;
|
||||
} else if (target < vout) {
|
||||
/* Falling. */
|
||||
|
||||
vout -= interval[step] / t_fall;
|
||||
if (vout < v)
|
||||
vout = v;
|
||||
else if (last_step)
|
||||
when = (vout - v) * t_fall;
|
||||
}
|
||||
}
|
||||
if (when > 0.0)
|
||||
cm_analog_set_perm_bkpt(when + TIME);
|
||||
}
|
||||
out[0] = vout * level_inc + out_low;
|
||||
OUTPUT(out[0]) = out[0];
|
||||
return;
|
||||
}
|
||||
|
||||
/* Multiple single-bit conversions. */
|
||||
|
||||
for (i = 0; i < size_in; i++) {
|
||||
if ( 0.0 == TIME ) { /*** DC analysis ***/
|
||||
switch (in[i].i) {
|
||||
|
||||
case ONE:
|
||||
out[i] = out_high;
|
||||
vout = out_high;
|
||||
break;
|
||||
|
||||
case ZERO:
|
||||
out[i] = out_low;
|
||||
vout = out_low;
|
||||
break;
|
||||
|
||||
case UNKNOWN:
|
||||
out[i] = out_undef;
|
||||
vout = out_undef;
|
||||
break;
|
||||
}
|
||||
} else if ( in_old[i].i == in[i].i ) {
|
||||
|
|
@ -295,44 +440,41 @@ void cm_dac_bridge(ARGS)
|
|||
switch (in[i].i) {
|
||||
case ZERO:
|
||||
if (out_old[i] > out_low) { /* output still dropping */
|
||||
out[i] = out_old[i] - fall_slope * time_inc;
|
||||
if ( out_low > out[i])
|
||||
out[i] = out_low;
|
||||
vout = out_old[i] - fall_slope * time_inc;
|
||||
if (out_low > vout)
|
||||
vout = out_low;
|
||||
} else { /* output at out_low */
|
||||
out[i] = out_low;
|
||||
vout = out_low;
|
||||
}
|
||||
break;
|
||||
|
||||
case ONE:
|
||||
if (out_old[i] < out_high) { /* output still rising */
|
||||
out[i] = out_old[i] + rise_slope * time_inc;
|
||||
if ( out_high < out[i])
|
||||
out[i] = out_high;
|
||||
vout = out_old[i] + rise_slope * time_inc;
|
||||
if (out_high < vout)
|
||||
vout = out_high;
|
||||
} else { /* output at out_high */
|
||||
out[i] = out_high;
|
||||
vout = out_high;
|
||||
}
|
||||
break;
|
||||
|
||||
case UNKNOWN:
|
||||
if (out_old[i] < out_undef) { /* output still rising */
|
||||
out[i] = out_old[i] + rise_slope * time_inc;
|
||||
if ( out_undef < out[i])
|
||||
out[i] = out_undef;
|
||||
vout = out_old[i] + rise_slope * time_inc;
|
||||
if (out_undef < vout)
|
||||
vout = out_undef;
|
||||
} else {
|
||||
if (out_old[i] > out_undef) { /* output still falling */
|
||||
out[i] = out_old[i] - fall_slope * time_inc;
|
||||
if ( out_undef > out[i])
|
||||
out[i] = out_undef;
|
||||
vout = out_old[i] - fall_slope * time_inc;
|
||||
if (out_undef > vout)
|
||||
vout = out_undef;
|
||||
} else { /* output at out_undef */
|
||||
out[i] = out_undef;
|
||||
vout = out_undef;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
double when, iota, vout, interval[2];
|
||||
int step, step_count;
|
||||
|
||||
/* There HAS been a change in this digital input
|
||||
since the last analog access. Determine when the change
|
||||
occurred and calculate the current output, then
|
||||
|
|
@ -412,9 +554,8 @@ void cm_dac_bridge(ARGS)
|
|||
}
|
||||
if (when > 0.0)
|
||||
cm_analog_set_perm_bkpt(when + TIME);
|
||||
out[i] = vout;
|
||||
}
|
||||
OUTPUT(out[i]) = out[i];
|
||||
OUTPUT(out[i]) = out[i] = vout;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue