CFILES += ses_step_topo.c
CFILES += ses_step_jr.c
-CFILES += ses_step_va.c
CFILES += ses_step_open.c
CFILES += ses_step_va_nodes.c
LDFLAGS += -lm
LDFLAGS += -lcairo
-LDFLAGS += -lgsl -lgslcblas
+LDFLAGS += -lgsl #-lgslcblas
all:
gcc $(CFLAGS) $(CFILES) $(LDFLAGS) -o ses
- 20uA, 20mV, 150
- 60uA, 60mV, 150
-120uA, 120mV, 150
-160uA, 160mV, 150
-220uA, 220mV, 150
-380uA, 380mV, 150
-0.5mA, 500mV, 150
-1.2mA, 700mV, 150
+ 20uA, 20mV, 0.03V
+ 60uA, 60mV, 0.09V
+120uA, 120mV, 0.18V
+160uA, 160mV, 0.24V
+220uA, 220mV, 0.33V
+380uA, 380mV, 0.5V
+0.5mA, 500mV, 0.85V
+1.2mA, 700mV, 2.01V
- 20uA, 20mV, 150
- 60uA, 60mV, 150
-120uA, 120mV, 150
-160uA, 160mV, 150
-220uA, 220mV, 150
-380uA, 380mV, 150
-0.5mA, 500mV, 150
-1.2mA, 700mV, 150
+ 20uA, 20mV, 0.03V
+ 60uA, 60mV, 0.09V
+120uA, 120mV, 0.18V
+160uA, 160mV, 0.24V
+220uA, 220mV, 0.33V
+380uA, 380mV, 0.5V
+0.5mA, 500mV, 0.85V
+1.2mA, 700mV, 2.01V
#CFILES += jk_gate2.c
#CFILES += rs_gate.c
#CFILES += ttl_dff_test.c
-CFILES += for_test.c
+#CFILES += for_test.c
#CFILES += add_gate.c
#CFILES += adc_gate.c
#CFILES += op_amp_741.c
+CFILES += op_amp_f007.c
#CFILES += op_amp_test.c
CFILES += ../scf_eda_pack.c
CFILES += ../pack/scf_pack.c
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"ses_core.h"
+
+int main(int argc, char* argv[])
+{
+ ScfEcomponent* T1;
+ ScfEcomponent* T2;
+ ScfEcomponent* T3;
+ ScfEcomponent* T4;
+
+ ScfEcomponent* T5;
+ ScfEcomponent* T6;
+ ScfEcomponent* T7;
+ ScfEcomponent* R1;
+ ScfEcomponent* R2;
+ ScfEcomponent* R3;
+
+ ScfEcomponent* T8;
+ ScfEcomponent* T9;
+
+ ScfEcomponent* T10;
+ ScfEcomponent* T11;
+ ScfEcomponent* R4;
+
+ ScfEcomponent* T12;
+ ScfEcomponent* T13;
+ ScfEcomponent* R5;
+
+ ScfEcomponent* T14;
+
+ ScfEcomponent* T15;
+ ScfEcomponent* R7;
+ ScfEcomponent* R8;
+
+ ScfEcomponent* T16;
+ ScfEcomponent* T17;
+
+ ScfEcomponent* T18;
+ ScfEcomponent* T19;
+ ScfEcomponent* R9;
+ ScfEcomponent* R10;
+
+ ScfEcomponent* D1;
+ ScfEcomponent* D2;
+ ScfEcomponent* C1;
+
+ ScfEfunction* f = scf_efunction__alloc("op_amp_f007.cpk");
+
+ EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R5, SCF_EDA_Resistor);
+
+ EDA_INST_ADD_COMPONENT(f, R7, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R8, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R9, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R10, SCF_EDA_Resistor);
+
+ EDA_INST_ADD_COMPONENT(f, C1, SCF_EDA_Capacitor);
+ EDA_INST_ADD_COMPONENT(f, D1, SCF_EDA_Diode);
+ EDA_INST_ADD_COMPONENT(f, D2, SCF_EDA_Diode);
+
+ EDA_INST_ADD_COMPONENT(f, T1, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T2, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T3, SCF_EDA_PNP);
+ EDA_INST_ADD_COMPONENT(f, T4, SCF_EDA_PNP);
+
+ EDA_INST_ADD_COMPONENT(f, T5, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T6, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T7, SCF_EDA_NPN);
+
+ EDA_INST_ADD_COMPONENT(f, T8, SCF_EDA_PNP);
+ EDA_INST_ADD_COMPONENT(f, T9, SCF_EDA_PNP);
+
+ EDA_INST_ADD_COMPONENT(f, T10, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T11, SCF_EDA_NPN);
+
+ EDA_INST_ADD_COMPONENT(f, T12, SCF_EDA_PNP);
+ EDA_INST_ADD_COMPONENT(f, T13, SCF_EDA_PNP);
+
+ EDA_INST_ADD_COMPONENT(f, T14, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T15, SCF_EDA_NPN);
+
+ EDA_INST_ADD_COMPONENT(f, T16, SCF_EDA_NPN);
+ EDA_INST_ADD_COMPONENT(f, T17, SCF_EDA_NPN);
+
+ EDA_INST_ADD_COMPONENT(f, T18, SCF_EDA_PNP);
+ EDA_INST_ADD_COMPONENT(f, T19, SCF_EDA_NPN);
+
+ EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_E, T9, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_B, T9, SCF_EDA_PNP_B);
+ EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_C, T8, SCF_EDA_PNP_B);
+
+ EDA_PIN_ADD_PIN(T1, SCF_EDA_NPN_C, T2, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T1, SCF_EDA_NPN_E, T3, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T2, SCF_EDA_NPN_E, T4, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T3, SCF_EDA_PNP_B, T4, SCF_EDA_PNP_B);
+
+ EDA_PIN_ADD_PIN(T8, SCF_EDA_PNP_C, T1, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T9, SCF_EDA_PNP_C, T3, SCF_EDA_NPN_B);
+
+ EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, T6, SCF_EDA_NPN_B);
+ EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_E, R1, 1);
+ EDA_PIN_ADD_PIN(T6, SCF_EDA_NPN_E, R3, 1);
+ EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, R2, 1);
+ EDA_PIN_ADD_PIN(R1, 0, R2, 0);
+ EDA_PIN_ADD_PIN(R1, 0, R3, 0);
+ EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_C, T3, SCF_EDA_PNP_C);
+ EDA_PIN_ADD_PIN(T6, SCF_EDA_NPN_C, T4, SCF_EDA_PNP_C);
+
+ EDA_PIN_ADD_PIN(T7, SCF_EDA_NPN_C, T8, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T7, SCF_EDA_NPN_B, T3, SCF_EDA_PNP_C);
+ EDA_PIN_ADD_PIN(T7, SCF_EDA_NPN_E, T5, SCF_EDA_NPN_B);
+
+ EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_C, T9, SCF_EDA_PNP_C);
+ EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_B, T11, SCF_EDA_NPN_B);
+ EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_B, T11, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T10, SCF_EDA_NPN_E, R4, 1);
+ EDA_PIN_ADD_PIN(R4, 0, R1, 0);
+ EDA_PIN_ADD_PIN(T11, SCF_EDA_NPN_E, R1, 0);
+
+ EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_E, T8, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_E, T13, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_B, T13, SCF_EDA_PNP_B);
+ EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_C, T12, SCF_EDA_PNP_B);
+ EDA_PIN_ADD_PIN(T12, SCF_EDA_PNP_C, R5, 1);
+ EDA_PIN_ADD_PIN(R5, 0, T11, SCF_EDA_NPN_C);
+
+ EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_B, T6, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_C, T17, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_E, T17, SCF_EDA_NPN_B);
+ EDA_PIN_ADD_PIN(T17, SCF_EDA_NPN_E, R1, 0);
+
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_C, R7, 1);
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_B, R7, 0);
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_B, R8, 1);
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_E, R8, 0);
+
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_E, T16, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_C, T13, SCF_EDA_PNP_C);
+
+ EDA_PIN_ADD_PIN(T15, SCF_EDA_NPN_C, C1, 1);
+ EDA_PIN_ADD_PIN(T16, SCF_EDA_NPN_B, C1, 0);
+
+ EDA_PIN_ADD_PIN(T14, SCF_EDA_NPN_B, T15, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T14, SCF_EDA_NPN_C, T8, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(T14, SCF_EDA_NPN_E, R9, 1);
+ EDA_PIN_ADD_PIN(R9, 0, R10, 1);
+ EDA_PIN_ADD_PIN(R10, 0, T18, SCF_EDA_PNP_E);
+ EDA_PIN_ADD_PIN(R10, 0, T19, SCF_EDA_NPN_C);
+ EDA_PIN_ADD_PIN(T19, SCF_EDA_NPN_E, R1, 0);
+
+ EDA_PIN_ADD_PIN(T18, SCF_EDA_PNP_C, T19, SCF_EDA_NPN_B);
+ EDA_PIN_ADD_PIN(T18, SCF_EDA_PNP_B, T16, SCF_EDA_NPN_C);
+
+ EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_POS, D2, SCF_EDA_Diode_NEG);
+ EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_NEG, D2, SCF_EDA_Diode_POS);
+ EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_POS, R7, 0);
+ EDA_PIN_ADD_PIN(D1, SCF_EDA_Diode_NEG, R9, 0);
+
+ EDA_SET_MIRROR(T1, T2);
+ EDA_SET_MIRROR(T3, T4);
+ EDA_SET_MIRROR(T5, T6);
+ EDA_SET_MIRROR(T8, T9);
+ EDA_SET_MIRROR(T12, T13);
+ EDA_SET_MIRROR(T16, T17);
+ EDA_SET_MIRROR(T18, T19);
+
+ C1->uf = 30e-6;
+ R1->r = 1000;
+ R2->r = 1000 * 50;
+ R3->r = 1000;
+ R4->r = 3000;
+ R5->r = 1000 * 39;
+ R7->r = 4500;
+ R8->r = 7500;
+ R9->r = 25;
+ R10->r = 50;
+
+ T8->pins[SCF_EDA_PNP_E]->flags = SCF_EDA_PIN_POS;
+ R1->pins[0]->flags = SCF_EDA_PIN_NEG;
+
+ T8->pins[SCF_EDA_PNP_E]->ic_lid = SCF_EDA_OP_AMP_POS;
+ R1->pins[0]->ic_lid = SCF_EDA_OP_AMP_NEG;
+
+ T1->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
+ T2->pins[SCF_EDA_NPN_B]->flags = SCF_EDA_PIN_IN;
+ R9->pins[0]->flags = SCF_EDA_PIN_OUT;
+ R1->pins[1]->flags = SCF_EDA_PIN_CF;
+ R2->pins[1]->flags = SCF_EDA_PIN_CF;
+
+ T1->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_OP_AMP_IN;
+ T2->pins[SCF_EDA_NPN_B]->ic_lid = SCF_EDA_OP_AMP_INVERT;
+ R9->pins[0]->ic_lid = SCF_EDA_OP_AMP_OUT;
+
+ int ret = ses_layout_function(f, 100);
+ if (ret < 0)
+ return ret;
+
+ ses_draw(f, "op_amp_f007.png", f->x, f->y, f->w, f->h, 0, -1);
+
+ long len = 0;
+ uint8_t* buf = NULL;
+
+ ScfEfunction_pack(f, &buf, &len);
+ ScfEfunction_free(f);
+ f = NULL;
+
+ FILE* fp = fopen("./op_amp_f007.cpk", "wb");
+ if (!fp)
+ return -EINVAL;
+
+ fwrite(buf, len, 1, fp);
+ fclose(fp);
+ return 0;
+}
+++ /dev/null
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#include"ses_core.h"
-
-int main(int argc, char* argv[])
-{
- ScfEcomponent* B;
-
- ScfEcomponent* NAND;
- ScfEcomponent* R;
- ScfEfunction* f;
- ScfEboard* b;
-
- b = scf_eboard__alloc();
- f = scf_efunction__alloc("ttl_nand_gate");
-
- EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery);
- EDA_INST_ADD_COMPONENT(f, R, SCF_EDA_Resistor);
- EDA_INST_ADD_COMPONENT(f, NAND, SCF_EDA_NAND);
-
- NAND->model = SCF_EDA_NAND_TTL;
-
- B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
- B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS;
-
- EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_POS, NAND, SCF_EDA_NAND_POS);
- EDA_PIN_ADD_PIN(B, SCF_EDA_Battery_NEG, NAND, SCF_EDA_NAND_NEG);
- EDA_PIN_ADD_PIN(R, 1, NAND, SCF_EDA_NAND_OUT);
- EDA_PIN_ADD_PIN(R, 0, B, SCF_EDA_Battery_NEG);
-
- NAND->pins[SCF_EDA_NAND_IN0]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
- NAND->pins[SCF_EDA_NAND_IN1]->flags = SCF_EDA_PIN_IN;
-
- NAND->pins[SCF_EDA_NAND_OUT]->flags = SCF_EDA_PIN_OUT;
-
- scf_eboard__add_function(b, f);
-
- long len = 0;
- uint8_t* buf = NULL;
-
- ScfEboard_pack(b, &buf, &len);
- ScfEboard_free(b);
- b = NULL;
-
- FILE* fp = fopen("./ttl_nand_gate.cpk", "wb");
- if (!fp)
- return -EINVAL;
-
- fwrite(buf, len, 1, fp);
- fclose(fp);
- return 0;
-}
+++ /dev/null
-#include<stdio.h>
-#include<stdlib.h>
-#include<string.h>
-#include"ses_core.h"
-
-int main(int argc, char* argv[])
-{
- ScfEcomponent* R1;
- ScfEcomponent* R2;
- ScfEcomponent* R3;
- ScfEcomponent* R4;
-
- ScfEcomponent* D10;
- ScfEcomponent* D11;
- ScfEcomponent* D12;
- ScfEcomponent* T2;
- ScfEcomponent* D3;
- ScfEcomponent* T4;
- ScfEcomponent* T5;
- ScfEcomponent* C5;
-
- ScfEboard* b = scf_eboard__alloc();
- ScfEfunction* f = scf_efunction__alloc("ttl_nand.cpk");
- ScfEcomponent* B;
- ScfEcomponent* RL;
-
- EDA_INST_ADD_COMPONENT(f, B, SCF_EDA_Battery);
- EDA_INST_ADD_COMPONENT(f, RL, SCF_EDA_Resistor);
-
- EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor);
- EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor);
- EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor);
- EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor);
-
- EDA_INST_ADD_COMPONENT(f, D10, SCF_EDA_Diode);
- EDA_INST_ADD_COMPONENT(f, D11, SCF_EDA_Diode);
- EDA_INST_ADD_COMPONENT(f, D12, SCF_EDA_Diode);
- EDA_INST_ADD_COMPONENT(f, D3, SCF_EDA_Diode);
-
- EDA_INST_ADD_COMPONENT(f, T2, SCF_EDA_NPN);
- EDA_INST_ADD_COMPONENT(f, T4, SCF_EDA_NPN);
- EDA_INST_ADD_COMPONENT(f, T5, SCF_EDA_NPN);
- EDA_INST_ADD_COMPONENT(f, C5, SCF_EDA_Capacitor);
-
- EDA_PIN_ADD_PIN(R1, 1, R2, 1);
- EDA_PIN_ADD_PIN(R1, 1, R4, 1);
-
- EDA_PIN_ADD_PIN(R1, 0, D10, SCF_EDA_Diode_POS);
- EDA_PIN_ADD_PIN(R1, 0, D11, SCF_EDA_Diode_POS);
- EDA_PIN_ADD_PIN(R1, 0, D12, SCF_EDA_Diode_POS);
-
- EDA_PIN_ADD_PIN(D12, SCF_EDA_Diode_NEG, T2, SCF_EDA_NPN_B);
- EDA_PIN_ADD_PIN(R2, 0, T2, SCF_EDA_NPN_C);
- EDA_PIN_ADD_PIN(R3, 1, T2, SCF_EDA_NPN_E);
- EDA_PIN_ADD_PIN(R3, 0, T5, SCF_EDA_NPN_E);
-
- EDA_PIN_ADD_PIN(R4, 0, T4, SCF_EDA_NPN_C);
- EDA_PIN_ADD_PIN(T4, SCF_EDA_NPN_E, D3, SCF_EDA_Diode_POS);
- EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_C, D3, SCF_EDA_Diode_NEG);
- EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, R3, 1);
- EDA_PIN_ADD_PIN(T4, SCF_EDA_NPN_B, R2, 0);
-
- EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_B, C5, 1);
- EDA_PIN_ADD_PIN(T5, SCF_EDA_NPN_E, C5, 0);
-
- R1->r = 4000;
- R2->r = 1600;
- R3->r = 10 * 1000;
- R4->r = 130;
- C5->uf = 5e-6;
-
- EDA_PIN_ADD_PIN(R1, 1, B, SCF_EDA_Battery_POS);
- EDA_PIN_ADD_PIN(R3, 0, B, SCF_EDA_Battery_NEG);
-
- EDA_PIN_ADD_PIN(RL, 1, D3, SCF_EDA_Diode_NEG);
- EDA_PIN_ADD_PIN(RL, 0, B, SCF_EDA_Battery_NEG);
-
- D10->pins[SCF_EDA_Diode_NEG]->flags = SCF_EDA_PIN_IN | SCF_EDA_PIN_IN0;
- D11->pins[SCF_EDA_Diode_NEG]->flags = SCF_EDA_PIN_IN;
- D3 ->pins[SCF_EDA_Diode_NEG]->flags = SCF_EDA_PIN_OUT;
-
- B->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
- B->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS;
-
- scf_eboard__add_function(b, f);
-
- long len = 0;
- uint8_t* buf = NULL;
-
- ScfEboard_pack(b, &buf, &len);
- ScfEboard_free(b);
- b = NULL;
-
- FILE* fp = fopen("./ttl_nand_gate2.cpk", "wb");
- if (!fp)
- return -EINVAL;
-
- fwrite(buf, len, 1, fp);
- fclose(fp);
- return 0;
-}
if (!fp)
return -EINVAL;
- double d = 0.0;
- double v = 0.0;
- double a = 0.0;
+ double v[2] = {0.0};
+ double a = 0.0;
+ double d = 0.0;
double base = 0.1;
- int dot = 0;
+ int dot = 0;
+ int i = 0;
while (1) {
int ch = fgetc(fp);
return ret;
}
- curve->v = v;
- curve->a = a;
- curve->hfe = d;
+ curve->Vb = v[0];
+ curve->Ib = a;
+ curve->Vc = v[1];
- scf_logd("curve v: %lg, a: %lg, hfe: %lg, R: %lg\n", v, a, d, v / a);
+ scf_logd("curve Vb: %lg, Ia: %lg, Vc: %lg, R: %lg\n", v[0], a, v[1], v[0] / a);
+ i = 0;
d = 0.0;
dot = 0;
base = 0.1;
break;
case 'V':
- v = d;
+ v[i] = d;
d = 0.0;
+ i = (i + 1) & 0x1;
break;
case 'A':
f = b->functions[i];
printf("f: %s\n", f->name);
- ses_steps_analyse(f, 100LL, 1);
+ ses_steps_analyse(f, 1000LL * 1000LL, 1);
}
ScfEboard_free(b);
{SCF_EDA_NOT, SCF_EDA_TTL_DELAY, 0, 0, 0, 0, 0, 0, 0, &__ttl_not_ops, "./cpk/ttl_not_delay.cpk", NULL},
- {SCF_EDA_OP_AMP, 0, 0, 0, 0, 0, 0, 0, 0, &__741_op_amp_ops, "./cpk/op_amp_741.cpk", NULL},
+ {SCF_EDA_OP_AMP, 0, 0, 0, 0, 0, 0, 0, 0, &__741_op_amp_ops, "./cpk/op_amp_f007.cpk", NULL},
};
static ScfEdata pin_datas[] =
{SCF_EDA_Diode, 0, SCF_EDA_Diode_NEG, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL},
{SCF_EDA_NPN, 0, SCF_EDA_NPN_B, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL},
- {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 150, NULL, NULL, NULL},
+ {SCF_EDA_NPN, 0, SCF_EDA_NPN_C, 0, 0, 3, 0, 0, 200, NULL, NULL, NULL},
{SCF_EDA_PNP, 0, SCF_EDA_PNP_B, 0, 0, 750, 0, 0, 0, NULL, NULL, NULL},
- {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 150, NULL, NULL, NULL},
+ {SCF_EDA_PNP, 0, SCF_EDA_PNP_C, 0, 0, 3, 0, 0, 200, NULL, NULL, NULL},
};
static ScfEdata* _pin_find_data(const uint64_t type, const uint64_t model, const uint64_t pid)
if (!c)
return NULL;
- c->type = type;
+ c->type = type;
+ c->mirror_id = -1;
ed = scf_ecomponent__find_data(c->type, c->model);
if (ed) {
SCF_PACK_END(ScfLine)
typedef struct {
- SCF_PACK_DEF_VAR(double, v);
- SCF_PACK_DEF_VAR(double, a);
- SCF_PACK_DEF_VAR(double, hfe);
+ SCF_PACK_DEF_VAR(double, Vb);
+ SCF_PACK_DEF_VAR(double, Ib);
+ SCF_PACK_DEF_VAR(double, Vc);
} ScfEcurve;
SCF_PACK_TYPE(ScfEcurve)
-SCF_PACK_INFO_VAR(ScfEcurve, v),
-SCF_PACK_INFO_VAR(ScfEcurve, a),
-SCF_PACK_INFO_VAR(ScfEcurve, hfe),
+SCF_PACK_INFO_VAR(ScfEcurve, Vb),
+SCF_PACK_INFO_VAR(ScfEcurve, Ib),
+SCF_PACK_INFO_VAR(ScfEcurve, Vc),
SCF_PACK_END(ScfEcurve)
typedef struct scf_eops_s ScfEops;
SCF_PACK_DEF_VAR(double, uf);
SCF_PACK_DEF_VAR(double, uh);
+ SCF_PACK_DEF_VAR(int64_t, mirror_id);
SCF_PACK_DEF_VAR(int64_t, count);
SCF_PACK_DEF_VAR(int64_t, color);
SCF_PACK_INFO_VAR(ScfEcomponent, uf),
SCF_PACK_INFO_VAR(ScfEcomponent, uh),
+SCF_PACK_INFO_VAR(ScfEcomponent, mirror_id),
+
SCF_PACK_INFO_VAR(ScfEcomponent, count),
SCF_PACK_INFO_VAR(ScfEcomponent, color),
SCF_PACK_INFO_VAR(ScfEcomponent, status),
#define EDA_PIN_ADD_PIN_EF(_ef, _p0, _p1) \
EDA_PIN_ADD_PIN((_ef)->components[(_p0)->cid], (_p0)->id, (_ef)->components[(_p1)->cid], (_p1)->id)
+#define EDA_SET_MIRROR(_c0, _c1) \
+ do { \
+ (_c0)->mirror_id = (_c1)->id; \
+ (_c1)->mirror_id = (_c0)->id; \
+ } while (0)
static char* component_types[SCF_EDA_Components_NB] =
{
ses_node_t* node1;
ses_edge_t* edge_b;
+ ses_edge_t* edge_c;
+ ses_edge_t* mirror;
double hfe;
double cv;
int index;
uint8_t bflag:1;
+ uint8_t vflag:1;
+ uint8_t cut_off_flag:1;
uint8_t amplify_flag:1;
+ uint8_t update_flag:1;
};
struct ses_node_s
static int __ses_edges_path(ses_path_t* path, int vip_m, int vip_n, scf_vector_t* edges)
{
- ses_edge_t* edge = NULL;
- ses_edge_t* edge2 = NULL;
+ ses_edge_t* edge = NULL;
+ ses_edge_t* edge2 = NULL;
+ ses_edge_t* mirror = NULL;
ScfEcomponent* c;
ScfEcomponent* c2;
bflag = 1;
edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_C]);
- } else if (SCF_EDA_NPN_C == p->id)
+ } else if (SCF_EDA_NPN_C == p->id) {
edge2 = ses_edges_find_edge_by_pin(edges, c->pins[SCF_EDA_NPN_B]);
+ if (c->mirror_id >= 0) {
+ c2 = c->pf->components[c->mirror_id];
+
+ mirror = ses_edges_find_edge_by_pin(edges, c2->pins[SCF_EDA_NPN_C]);
+ }
+ }
case SCF_EDA_Diode:
if (SCF_EDA_Diode == c->type)
bflag = 1;
node_flag = 1;
break;
default:
- if (i - 1 >= vip_m) {
- p2 = path->pins->data[i - 1];
- c2 = p2->c;
-
- switch (c2->type) {
- case SCF_EDA_Diode:
- case SCF_EDA_Capacitor:
- case SCF_EDA_Inductor:
- node_flag = 1;
- break;
- default:
- break;
- };
- }
+ if (i - 1 >= vip_m)
+ node_flag = 1;
break;
};
if (edge2) {
if (edge ->bflag) {
+ edge ->edge_c = edge2;
edge2->edge_b = edge;
edge2->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
} else {
assert(edge2->bflag);
- edge->edge_b = edge2;
- edge->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
+ edge2->edge_c = edge;
+ edge ->edge_b = edge2;
+ edge ->hfe = c->pins[SCF_EDA_NPN_C]->hfe;
}
edge2 = NULL;
}
+ if (mirror) {
+ edge ->mirror = mirror;
+ mirror->mirror = edge;
+ mirror = NULL;
+ }
+
node_flag = 0;
j = i - 1;
{
int i;
for (i = 0; i < c->n_curves; i++) {
- if (Ib < c->curves[i]->a)
+ if (Ib < c->curves[i]->Ib)
break;
}
double R;
if (0 == i) {
- V1 = c->curves[i]->v;
- A1 = c->curves[i]->a;
+ V1 = c->curves[i]->Vb;
+ A1 = c->curves[i]->Ib;
R = V1 / Ib;
*V = V1;
} else if (i >= c->n_curves) {
assert(2 <= c->n_curves);
- V1 = c->curves[c->n_curves - 1]->v;
- A1 = c->curves[c->n_curves - 1]->a;
+ V1 = c->curves[c->n_curves - 1]->Vb;
+ A1 = c->curves[c->n_curves - 1]->Ib;
R = V1 / Ib;
*V = V1;
} else {
- V0 = c->curves[i - 1]->v;
- A0 = c->curves[i - 1]->a;
- V1 = c->curves[i]->v;
- A1 = c->curves[i]->a;
+ V0 = c->curves[i - 1]->Vb;
+ A0 = c->curves[i - 1]->Ib;
+ V1 = c->curves[i]->Vb;
+ A1 = c->curves[i]->Ib;
R = (V1 - V0) / (A1 - A0);
*V = V0 + R * (Ib - A0);
}
scf_logd("i: %d, n_curves: %ld, Ib: %lg, R: %lg, V: %lg\n", i, c->n_curves, Ib, R, *V);
}
+static int __ses_edges_inverse_off(ScfEfunction* f, scf_vector_t* edges, double* A, double* b, double* X, int N)
+{
+ ses_edge_t* edge;
+
+ ScfEcomponent* c;
+ ScfEpin* p0;
+ ScfEpin* p1;
+
+ int n = N - edges->size;
+ int k = 0;
+ int i;
+ int j;
+
+ for (j = 0; j < edges->size; j++) {
+ edge = edges->data[j];
+
+ if (!edge->bflag)
+ continue;
+
+ p0 = edge->path->pins->data[edge->vip_m];
+ p1 = edge->path->pins->data[edge->vip_n];
+ c = p0->c;
+
+ if (SCF_EDA_Diode != c->type)
+ continue;
+
+ double Vb;
+ double Ve;
+ if (edge->node1 && !edge->node1->el->vconst)
+ Vb = X[edge->node1->index];
+ else
+ Vb = ses_top_pline(p0)->v;
+
+ if (edge->node0 && !edge->node0->el->vconst)
+ Ve = X[edge->node0->index];
+ else
+ Ve = ses_top_pline(p1)->v;
+
+ double dV = Vb - Ve;
+ double Ib = X[n + edge->index];
+
+ if (dV < -SCF_EDA_V_Diode_OFF / 2) {
+ if (!edge->cut_off_flag) {
+ edge->cut_off_flag = 1;
+
+ c->status = SCF_EDA_Status_OFF;
+
+ for (i = 0; i < N; i++)
+ A[(n + edge->index) * N + i] = 0;
+
+ A[(n + edge->index) * N + n + edge->index] = -1;
+ b[ n + edge->index] = 0;
+ k++;
+#if 1
+ scf_logi("\033[31medge: [%d], ", edge->index);
+ ses_pin_print(p0);
+ printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, Ib: %lg\033[0m\n", c->status, dV, Vb, Ve, Ib);
+#endif
+ }
+ } else if (dV > SCF_EDA_V_Diode_OFF) {
+ if (edge->cut_off_flag) {
+ edge->cut_off_flag = 0;
+
+ c->status = SCF_EDA_Status_ON;
+
+ b[ n + edge->index] = 0;
+ A[(n + edge->index) * N + n + edge->index] = -edge->r;
+
+ if (edge->node0 && !edge->node0->el->vconst)
+ A[(n + edge->index) * N + edge->node0->index] = -1;
+ else
+ b[n + edge->index] += ses_top_pline(p1)->v;
+
+ if (edge->node1 && !edge->node1->el->vconst)
+ A[(n + edge->index) * N + edge->node1->index] = 1;
+ else
+ b[n + edge->index] -= ses_top_pline(p0)->v;
+#if 1
+ scf_logi("\033[32medge: [%d], ", edge->index);
+ ses_pin_print(p0);
+ printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, Ib: %lg\033[0m\n", c->status, dV, Vb, Ve, Ib);
+#endif
+ k++;
+ }
+ }
+ }
+
+ return k;
+}
+
static int __ses_edges_update_Ab(ScfEfunction* f, scf_vector_t* edges, double* A, double* b, double* X, int N, int* n_offs)
{
ses_edge_t* edge;
ScfEcomponent* c;
- ScfEcomponent* B = f->components[0];
- ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS];
+ ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS);
+ ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG);
+ ScfEline* L0 = ses_find_line_by_flag(f, SCF_EDA_PIN_GND);
+ ScfEline* el;
ScfEpin* p0;
ScfEpin* p1;
ScfEpin* p;
}
#endif
if (-1e8 < Rb && Rb < 1e8) {
- if (dV < V * 0.99 || dV > V * 1.01) {
-#if 0
+ if ((dV < V * 0.98 || dV > V * 1.02) && SCF_EDA_Status_ON == c->status) {
+#if 1
scf_logi("edge: [%d], ", edge->index);
ses_pin_print(p0);
printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, V: %lg, Ib: %lg, Rb: %lg\n", c->status, dV, Vb, Ve, V, Ib, Rb);
#endif
}
} else {
- if (dV < SCF_EDA_V_NPN_OFF && Ve < Bp->v - SCF_EDA_V_NPN_OFF) {
+ if (dV < SCF_EDA_V_NPN_OFF
+ && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)
+ && (Ve < LP->v - SCF_EDA_V_NPN_OFF && Vb > LN->v + SCF_EDA_V_NPN_OFF)) {
c->status = SCF_EDA_Status_OFF;
c->lock = 2;
(*n_offs)++;
}
-#if 1
+#if 0
scf_logi("\033[34medge: [%d], ", edge->index);
ses_pin_print(p0);
printf("status: %d, dV: %lg, Vb: %lg, Ve: %lg, V: %lg, Ib: %lg, Rb: %lg\033[0m\n", c->status, dV, Vb, Ve, V, Ib, Rb);
if (dI < -1e-10 && -1e8 < Rb && Rb < 1e8) {
if (!edge->amplify_flag) {
edge->amplify_flag = 1;
-#if 0
- scf_logi("edge: [%d], ", edge->index);
- ses_pin_print(p0);
- ses_pin_print(p1);
- printf("[b%d], Ic: %lg, Ib: %lg, dI: %lg, Vbe: %lg, Vce: %lg, Vc: %lg, Ve: %lg, Rb: %lg\n", edge->edge_b->index, Ic, Ib, dI, Vb - Ve, Vc - Ve, Vc, Ve, Rb);
-#endif
+
for (i = 0; i < N; i++)
A[(n + edge->index) * N + i] = 0;
return k;
}
-static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* edges, int* changed, int64_t ps, int64_t count)
+static void ses_edge_hfe_print(ses_edge_t* edge, double hfe, double* X, int n, double alpha)
+{
+ ScfEpin* p0 = edge->path->pins->data[edge->vip_m];
+ ScfEpin* p1 = edge->path->pins->data[edge->vip_n];
+
+ double Ic = X[n + edge->index];
+ double Vc;
+ double Ve;
+ if (edge->node1 && !edge->node1->el->vconst)
+ Vc = X[edge->node1->index];
+ else
+ Vc = ses_top_pline(p0)->v;
+
+ if (edge->node0 && !edge->node0->el->vconst)
+ Ve = X[edge->node0->index];
+ else
+ Ve = ses_top_pline(p1)->v;
+
+ scf_logi("\033[33medge: [%d], ", edge->index);
+ ses_pin_print(p0);
+ ses_pin_print(p1);
+ printf("Vc: %lg, Ve: %lg, Vce: %lg, Ic: %lg, hfe: %lg, alpha: %lg\033[0m\n", Vc, Ve, Vc - Ve, Ic, hfe, alpha);
+}
+
+static int __edge_update_hfe(ses_edge_t* edge, double* A, double* X, int N, int n, double alpha)
+{
+ assert(edge->edge_b);
+
+ int k = 0;
+ double hfe = A[(n + edge->index) * N + n + edge->edge_b->index] * alpha;
+
+ if (hfe > 1e-4 && hfe < 250) {
+ if (!edge->update_flag) {
+ edge ->update_flag = 1;
+
+ A[(n + edge->index) * N + n + edge->edge_b->index] = hfe;
+
+ ses_edge_hfe_print(edge, hfe, X, n, alpha);
+ k++;
+ }
+
+ if (edge->mirror && edge->mirror->amplify_flag && !edge->mirror->update_flag) {
+ edge->mirror->update_flag = 1;
+
+ A[(n + edge->mirror->index) * N + n + edge->mirror->edge_b->index] = hfe;
+
+ ses_edge_hfe_print(edge->mirror, hfe, X, n, alpha);
+ k++;
+ }
+
+ if (k > 0)
+ printf("\n");
+ }
+ return k;
+}
+
+static int __edge_update_hfe_in(ses_edge_t* edge, double* A, double* X, int N, int n)
+{
+ if (!edge->node1)
+ return 0;
+
+ ses_edge_t* in;
+ int i;
+ int k = 0;
+
+ for (i = 0; i < edge->node1->edges->size; i++) {
+ in = edge->node1->edges->data[i];
+
+ if (in->node0 != edge->node1)
+ continue;
+
+ if (in->vflag)
+ continue;
+ in->vflag = 1;
+
+ if (in->edge_b && in->amplify_flag && !in->update_flag)
+ k += __edge_update_hfe(in, A, X, N, n, 0.95);
+
+ if (in->node1)
+ k += __edge_update_hfe_in(in, A, X, N, n);
+ }
+ return k;
+}
+
+static int __edge_update_hfe_out(ses_edge_t* edge, double* A, double* X, int N, int n)
+{
+ if (!edge->node0)
+ return 0;
+
+ ses_edge_t* out;
+ int i;
+ int k = 0;
+
+ for (i = 0; i < edge->node0->edges->size; i++) {
+ out = edge->node0->edges->data[i];
+
+ if (out->node1 != edge->node0)
+ continue;
+
+ if (out->vflag)
+ continue;
+ out->vflag = 1;
+
+ if (out->edge_b && out->amplify_flag && !out->update_flag)
+ k += __edge_update_hfe(out, A, X, N, n, 0.95);
+
+ if (out->node0)
+ k += __edge_update_hfe_out(out, A, X, N, n);
+ }
+ return k;
+}
+
+static int __ses_edges_update_hfe(ScfEfunction* f, scf_vector_t* edges, double* A, double* b, double* X, int N)
{
- ses_node_t* node;
ses_edge_t* edge;
ScfEcomponent* c;
+ ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS);
+ ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG);
+ ScfEline* L0 = ses_find_line_by_flag(f, SCF_EDA_PIN_GND);
ScfEpin* p0;
ScfEpin* p1;
- ScfEline* el;
- int ret = 0;
- int i;
+ int n = N - edges->size;
+ int k = 0;
int j;
- int m = edges->size;
- int n = nodes->size;
- int N = n + m;
+ for (j = 0; j < edges->size; j++) {
+ edge = edges->data[j];
- double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double));
- if (!A)
- return -ENOMEM;
+ edge->update_flag = 0;
+ edge->vflag = 0;
+ }
+
+ for (j = 0; j < edges->size; j++) {
+ edge = edges->data[j];
+
+ if (!edge->edge_b)
+ continue;
+
+ p0 = edge->path->pins->data[edge->vip_m];
+ p1 = edge->path->pins->data[edge->vip_n];
+ c = p0->c;
+
+ double Ib = X[n + edge->edge_b->index];
+ double Ic = X[n + edge->index];
+ double Vc;
+ double Ve;
+ if (edge->node1 && !edge->node1->el->vconst)
+ Vc = X[edge->node1->index];
+ else
+ Vc = ses_top_pline(p0)->v;
+
+ if (edge->node0 && !edge->node0->el->vconst)
+ Ve = X[edge->node0->index];
+ else
+ Ve = ses_top_pline(p1)->v;
+
+ if (edge->amplify_flag) {
+ if (Vc < Ve)
+ k += __edge_update_hfe(edge, A, X, N, n, 0.95);
+ if (Vc > LP->v || Vc < LN->v)
+ k += __edge_update_hfe(edge, A, X, N, n, 0.95);
+
+ if (Ve > LP->v || Ve < LN->v)
+ k += __edge_update_hfe(edge, A, X, N, n, 1.02);
+
+ } else if (Ic > Ib * edge->hfe) {
+ edge->amplify_flag = 1;
+
+ int i;
+ for (i = 0; i < N; i++)
+ A[(n + edge->index) * N + i] = 0;
+
+ A[(n + edge->index) * N + n + edge->index] = -1;
+ A[(n + edge->index) * N + n + edge->edge_b->index] = edge->hfe;
+ b[ n + edge->index] = 0;
+ k++;
+ }
+ }
+
+ return k;
+}
+
+static int __ses_try_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* edges, int* changed, double* A, int N, int n)
+{
double* b = A + N * N;
double* X = b + N;
double* W = X + N;
double* V = S + N;
double* U = V + N * N;
- __ses_nodes_set_Ab(f, nodes, edges, ps, A, b, N);
-
gsl_matrix_view _A = gsl_matrix_view_array(U, N, N);
gsl_vector_view _b = gsl_vector_view_array(b, N);
gsl_vector_view _X = gsl_vector_view_array(X, N);
gsl_vector_view _S = gsl_vector_view_array(S, N);
gsl_matrix_view _V = gsl_matrix_view_array(V, N, N);
- int n_offs = 0;
+ int ret = 0;
+ int j;
-#define MAX_TRYS 10000
- int try = 0;
- do {
- n_offs = 0;
+ for (j = 0; j < 20; j++) {
+ int n_offs = 0;
memcpy(U, A, sizeof(double) * N * N);
gsl_linalg_SV_solve (&_A.matrix, &_V.matrix, &_S.vector, &_b.vector, &_X.vector);
ret = __ses_edges_update_Ab(f, edges, A, b, X, N, &n_offs);
- try++;
- scf_logi("ret: %d, try: %d, n_offs: %d\n\n", ret, try, n_offs);
+ scf_logi("j: %d, ret: %d, n_offs: %d\n\n", j, ret, n_offs);
+ ses_node_t* node;
+ ScfEline* el;
+
+ int i;
for (i = 0; i < n; i++) {
node = nodes->data[i];
el = node->el;
if (n_offs > 0) {
*changed += n_offs;
- break;
+// break;
}
- } while (ret > 0 && try < MAX_TRYS);
- if (try >= MAX_TRYS) {
- free(A);
- return -1;
+ if (0 == ret)
+ break;
}
+ return ret;
+}
+
+static int __ses_nodes_solve(ScfEfunction* f, scf_vector_t* nodes, scf_vector_t* edges, int* changed, int64_t ps, int64_t count)
+{
+ ses_node_t* node;
+ ses_edge_t* edge;
+
+ ScfEcomponent* c;
+ ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS);
+ ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG);
+ ScfEline* L0 = ses_find_line_by_flag(f, SCF_EDA_PIN_GND);
+ ScfEline* el;
+ ScfEpin* p0;
+ ScfEpin* p1;
+
+ int ret = 0;
+ int i;
+ int j;
+
+ int m = edges->size;
+ int n = nodes->size;
+ int N = n + m;
+
+ double* A = calloc(N * N + N + N + (N + N + N * N + N * N), sizeof(double));
+ if (!A)
+ return -ENOMEM;
+
+ double* b = A + N * N;
+ double* X = b + N;
+
+ __ses_nodes_set_Ab(f, nodes, edges, ps, A, b, N);
+
+#define MAX_TRYS 500
+ int try = 0;
+ do {
+ ret = __ses_try_solve(f, nodes, edges, changed, A, N, n);
+
+ i = __ses_edges_update_hfe(f, edges, A, b, X, N);
+
+ if (0 == i)
+ j = __ses_edges_inverse_off(f, edges, A, b, X, N);
+
+ scf_logi("try: %d, ret: %d, i: %d, j: %d\n", try, ret, i, j);
+
+ ret += i;
+ ret += j;
+ try++;
+
+ } while (ret > 0 && try < MAX_TRYS);
+
+ if (try >= MAX_TRYS)
+ scf_loge("try: %d\n", try);
+ else
+ scf_logi("try: %d\n", try);
// ses_AbX_print(A, b, X, N);
for (j = 0; j < edges->size; j++) {
printf(", v: %lg, %lg, a: %lg, edge->index: %d\n", p0->v, p1->v, edge->a, edge->index);
#endif
if (SCF_EDA_NPN == c->type) {
- if (SCF_EDA_NPN_B == p0->id && edge->a < -1e-4) {
+ if (SCF_EDA_NPN_B == p0->id
+ && edge->a < -1e-4
+ && ses_top_pline(p0) != L0
+ && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)) {
c->status = SCF_EDA_Status_OFF;
c->lock = 2;
(*changed)++;
continue;
} else if (SCF_EDA_PNP == c->type) {
- if (SCF_EDA_PNP_B == p1->id && edge->a < -1e-4) {
+ if (SCF_EDA_PNP_B == p1->id
+ && edge->a < -1e-4
+ && ses_top_pline(p1) != L0
+ && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)) {
c->status = SCF_EDA_Status_OFF;
c->lock = 2;
(*changed)++;
continue;
} else if (SCF_EDA_Diode == c->type) {
- if (edge->a < -1e-4) {
+ if (edge->a < -1e-4
+ && (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)) {
c->status = SCF_EDA_Status_OFF;
c->lock = 2;
(*changed)++;
c->a = edge->a;
continue;
+ }
- } else if (SCF_EDA_Inductor == c->type) {
- int sign = p0->id - !p0->id;
+ int sign = p0->id - !p0->id;
+
+ if (SCF_EDA_Inductor == c->type) {
c->v = (edge->a * sign - c->a) * c->uh * 1000000.0 / ps;
- c->a = edge->a * sign;
- p0->a = edge->a;
- p1->a = edge->a;
- continue;
} else if (SCF_EDA_Capacitor == c->type) {
- int sign = p0->id - !p0->id;
- c->v += edge->a * sign * ps / 1000000.0 / c->uf;
- c->a = edge->a * sign;
- p0->a = edge->a;
- p1->a = edge->a;
- continue;
+ if (!c->pf->IC || SCF_EDA_OP_AMP != c->pf->IC->type)
+ c->v += edge->a * sign * ps / 1000000.0 / c->uf;
}
- ret = __ses_path_va_branch(f, edge->path, edge->vip_m, edge->vip_n, edge->r, changed, ps, count);
- if (ret < 0)
- goto error;
+ c->a = edge->a * sign;
+ p0->a = edge->a;
+ p1->a = edge->a;
}
-error:
free(A);
return ret;
}
for (j = 0; j < node->edges->size; j++) {
edge = node->edges->data[j];
-
- if (edge->node1 && !scf_vector_find(g->nodes, edge->node1)) {
- edge->node1->index = g->nodes->size;
-
- ret = scf_vector_add(g->nodes, edge->node1);
- if (ret < 0) {
- ses_group_free(g);
- return ret;
- }
-
- assert(0 == scf_vector_del(nodes, edge->node1));
- }
-
- if (edge->node0 && !scf_vector_find(g->nodes, edge->node0)) {
- edge->node0->index = g->nodes->size;
-
- ret = scf_vector_add_unique(g->nodes, edge->node0);
- if (ret < 0) {
- ses_group_free(g);
- return ret;
- }
-
- assert(0 == scf_vector_del(nodes, edge->node0));
- }
+#define SPLIT_ADD_NODE(_node) \
+ do { \
+ if ((_node) && !scf_vector_find(g->nodes, (_node))) { \
+ (_node)->index = g->nodes->size; \
+ \
+ ret = scf_vector_add(g->nodes, (_node)); \
+ if (ret < 0) { \
+ ses_group_free(g); \
+ return ret; \
+ } \
+ assert(0 == scf_vector_del(nodes, (_node))); \
+ } \
+ } while (0)
+
+ SPLIT_ADD_NODE(edge->node1);
+ SPLIT_ADD_NODE(edge->node0);
if (!scf_vector_find(g->edges, edge)) {
edge->index = g->edges->size;
}
assert(0 == scf_vector_del(edges, edge));
+
+ if (edge->edge_b) {
+ SPLIT_ADD_NODE(edge->edge_b->node1);
+ SPLIT_ADD_NODE(edge->edge_b->node0);
+
+ } else if (edge->edge_c) {
+ SPLIT_ADD_NODE(edge->edge_c->node1);
+ SPLIT_ADD_NODE(edge->edge_c->node0);
+ }
}
}
}
if (SCF_EDA_Battery != c->type)
continue;
- c->v = 5;
+
+ if (c->v <= 0)
+ c->v = 5;
Bp = c->pins[SCF_EDA_Battery_POS];
Bn = c->pins[SCF_EDA_Battery_NEG];
LN->vconst = 1;
+ LP->flags |= SCF_EDA_PIN_GND;
+
} else if (LP->v - LN->v != c->v) {
scf_loge("Battery '%lgV' connected between line '%lgV' and '%lgV', diff: %lgV\n",
c->v, LP->v, LN->v, LP->v - LN->v);
#include"ses_core.h"
-static void __dc_dfs_init(ScfEfunction* f, ScfEcomponent* IC)
-{
- ScfEcomponent* c;
- ScfEline* el;
- ScfEline* parent;
- ScfEpin* p;
-
- long i;
- for (i = 0; i < f->n_elines; i++) {
- el = f->elines[i];
-
- if (!IC) {
- if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG))
- continue;
-
- } else if (i < IC->n_pins) {
- p = IC->pins[i];
- parent = IC->pf->elines[p->lid];
- continue;
- }
- }
-
- for (i = 0; i < f->n_components; i++) {
- c = f->components[i];
-
- if (c->f)
- __dc_dfs_init(c->f, c);
- }
-}
-
static int __dc_diode_status(ScfEfunction* root, ScfEfunction* f, ScfEline* LP, ScfEline* LN)
{
ScfEcomponent* c;
if (neg && !pos) {
c->status = SCF_EDA_Status_OFF;
-
- scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock);
- ses_pin_print(pb);
- printf("\n");
- continue;
+ goto check;
}
- if (!neg && pos && SCF_EDA_Status_ON == c->status) {
- // c->status = SCF_EDA_Status_OFF;
-
- scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock);
- ses_pin_print(pb);
- printf("\n");
- continue;
- }
+ if (!neg && pos && SCF_EDA_Status_ON == c->status)
+ goto check;
- if (c->lock) {
- scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock);
- ses_pin_print(pb);
- printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_Diode_OFF);
- continue;
- }
+ if (c->lock)
+ goto check;
if (lb->v < SCF_EDA_V_MIN) {
if (le->v < SCF_EDA_V_MIN)
// c->status = SCF_EDA_Status_OFF;
}
+check:
+ if ((c->pf->IC && SCF_EDA_OP_AMP == c->pf->IC->type)
+ || pe->v >= LP->v - SCF_EDA_V_NPN_OFF
+ || pb->v <= LN->v + SCF_EDA_V_NPN_OFF) {
+ c->lock = 0;
+ c->status = SCF_EDA_Status_ON;
+ }
+
scf_logi("\033[34m status: %d, lock: %d, ", c->status, c->lock);
ses_pin_print(pb);
printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_Diode_OFF);
ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS);
ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG);
- __dc_dfs_init(f, NULL);
-
return __dc_diode_status(f, f, LP, LN);
}
long j;
int k;
- int x[] = {0, 0, 0, 0, 0};
+ int x[] = {1, 1, 0, 0, 0};
int y[] = {0, 1, 0, 1, 0};
B = f->components[0];
continue;
}
#endif
- if (c->lock) {
- scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock);
- ses_pin_print(pb);
- printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF);
- continue;
- }
+ if (c->lock)
+ goto check;
if (lb->v < SCF_EDA_V_MIN) {
if (le->v < SCF_EDA_V_MIN)
// c->status = SCF_EDA_Status_OFF;
}
+check:
+ if ((c->pf->IC && SCF_EDA_OP_AMP == c->pf->IC->type)
+ || pe->v >= LP->v - SCF_EDA_V_NPN_OFF
+ || pb->v <= LN->v + SCF_EDA_V_NPN_OFF) {
+ c->lock = 0;
+ c->status = SCF_EDA_Status_ON;
+ }
+
scf_logi("\033[34m status: %d, lock: %d, ", c->status, c->lock);
ses_pin_print(pb);
printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", pb->v, pe->v, pb->v - pe->v, SCF_EDA_V_NPN_OFF);
int neg = __ses_path_neg(root, lb, LP, LN);
int pos = __ses_path_pos(root, lb, LP, LN);
- if (c->lock) {
- scf_logi("\033[34m status: %d, lock: %d, \033[0m", c->status, c->lock);
- ses_pin_print(pb);
- printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\n", pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF);
- continue;
- }
+ if (c->lock)
+ goto check;
if (lb->v < SCF_EDA_V_MIN) {
if (le->v < SCF_EDA_V_MIN)
// c->status = SCF_EDA_Status_OFF;
}
+check:
+ if ((c->pf->IC && SCF_EDA_OP_AMP == c->pf->IC->type)
+ || pb->v >= LP->v - SCF_EDA_V_NPN_OFF
+ || pe->v <= LN->v + SCF_EDA_V_NPN_OFF) {
+ c->lock = 0;
+ c->status = SCF_EDA_Status_ON;
+ }
+
scf_logi("\033[34m status: %d, lock: %d, ", c->status, c->lock);
ses_pin_print(pb);
printf("pb->v: %lg, pe->v: %lg, diff: %lg, off: %lg\033[0m\n", pb->v, pe->v, pe->v - pb->v, SCF_EDA_V_PNP_OFF);
} else if (a > 1e-9 || a < -1e-9) {
snprintf(text, sizeof(text) - 1, "%lguA", (int64_t)(a * 1000000.0 * SHOW_BITS) / SHOW_BITS);
+ cairo_move_to (cr, x, y);
+ cairo_show_text(cr, text);
+
+ } else if (a > 1e-13 || a < -1e-13) {
+ snprintf(text, sizeof(text) - 1, "%lgnA", (int64_t)(a * 1e9 * SHOW_BITS) / SHOW_BITS);
+
cairo_move_to (cr, x, y);
cairo_show_text(cr, text);
}
SHOW_COLOR(cr, 0.0, 0.0, 0.0);
if (c->r + c->dr > 1e6)
- snprintf(text, sizeof(text) - 1, "%lgMΩ", (int64_t)(c->r + c->dr) / 1000.0);
+ snprintf(text, sizeof(text) - 1, "%lgMΩ", (int64_t)(c->r + c->dr) / 1000000.0);
else if (c->r + c->dr > 999)
snprintf(text, sizeof(text) - 1, "%lgkΩ", (int64_t)((c->r + c->dr) * 1000.0) / 1000000.0);
else
#endif
if (1 || count % 10 == 0) {
-#if 0
+#if 1
static FILE* fp = NULL;
if (!fp)
fp = fopen("v.txt", "w");
- if (fp)
- fprintf(fp, "%ld, %lg, %lg, %lg\n", i, f->elines[2]->v, f->elines[9]->v, f->elines[8]->v);
+ if (fp) {
+ fprintf(fp, "%ld, %lg\n", i, f->elines[4]->v);
+ fflush(fp);
+ }
#endif
int j = count % 400;
- if (j > 396 || j < 20) {
+// if (j > 396 || j < 20) {
ses_draw(f, file, f->x, f->y, f->w, f->h, ps, count);
-// __draw_IC(f, ps, count, i);
- }
+ __draw_IC(f, ps, count, i);
+// }
i++;
}
scf_logd("path: %d, pr: %lg, sr: %lg\n\n", path->index, path->pr, path->sr);
return 0;
}
+
+void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la)
+{
+ ScfEcomponent* c;
+ ScfEpin* p;
+
+ int i;
+
+ if (cv)
+ *cv = 0;
+
+ if (lv)
+ *lv = 0;
+
+ if (uf)
+ *uf = 0;
+
+ if (uh)
+ *uh = 0;
+
+ if (la)
+ *la = 0;
+
+ for (i = m; i <= n; i++) {
+ p = path->pins->data[i];
+ c = p->c;
+
+ if (i & 0x1) {
+ int sign = !p->id - p->id;
+
+ if (SCF_EDA_Capacitor == c->type) {
+ if (cv)
+ *cv += c->v * sign;
+
+ if (uf)
+ *uf += c->uf;
+
+ } else if (SCF_EDA_Inductor == c->type) {
+ if (la)
+ *la = c->a * sign;
+
+ if (lv)
+ *lv += c->v * sign;
+
+ if (uh)
+ *uh += c->uh;
+ }
+ }
+ }
+}
if (__ses_path_pos(f, el, LP, LN)) {
if (__ses_path_neg(f, el, LP, LN))
return;
- el->v = LP->v;
- } else if (__ses_path_neg(f, el, LP, LN))
- el->v = LN->v;
- else
- el->v = SCF_EDA_V_NPN_ON / 2;
+ if (!ses_top_line(el)->vconst)
+ el->v = LP->v;
+
+ } else if (__ses_path_neg(f, el, LP, LN)) {
+ if (!ses_top_line(el)->vconst)
+ el->v = LN->v;
+
+ } else {
+ if (!ses_top_line(el)->vconst)
+ el->v = SCF_EDA_V_NPN_ON / 2;
+ }
// scf_logw("");
// ses_eline_print(el);
static int _open_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_t* ctx)
{
ScfEcomponent* c;
- ScfEcomponent* B = f->components[0];
- ScfEpin* Bp = B->pins[SCF_EDA_Battery_POS];
- ScfEpin* Bn = B->pins[SCF_EDA_Battery_NEG];
- ScfEline* LP = ses_top_pline(Bp);
- ScfEline* LN = ses_top_pline(Bn);
+ ScfEline* LP = ses_find_line_by_flag(f, SCF_EDA_PIN_POS);
+ ScfEline* LN = ses_find_line_by_flag(f, SCF_EDA_PIN_NEG);
ScfEline* el;
long i;
for (i = 0; i < f->n_elines; i++) {
el = f->elines[i];
- if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG))
+ if (el->flags & (SCF_EDA_PIN_IN | SCF_EDA_PIN_POS | SCF_EDA_PIN_NEG | SCF_EDA_PIN_GND))
continue;
__open_status_line(f, el, LP, LN);
#if 0
scf_loge("off: ");
ses_pin_print(rp);
- printf("l%ld, vflag: %d, pflag: %d\n", rp->lid, rp->vflag, rp->pflag);
+ printf("l%ld, vflag: %d, pflag: %d\n\n", rp->lid, rp->vflag, rp->pflag);
#endif
}
}
if (SCF_EDA_Capacitor == c1->type)
return 1;
+ if (SCF_EDA_Resistor == c0->type)
+ return 1;
+ if (SCF_EDA_Resistor == c1->type)
+ return -1;
return 0;
}
static int _topo_handler(ScfEfunction* f, int64_t ps, int64_t count, ses_ctx_t* ctx)
{
ses_path_t* path;
- ScfEcomponent* B;
+ ScfEcomponent* c;
ScfEline* el;
_topo_clear(f);
scf_vector_clear(ctx->paths, ( void (*)(void*) )ses_path_free);
- B = f->components[0];
- el = f->elines[B->pins[SCF_EDA_Battery_POS]->lid];
+ long i;
+ for (i = 0; i < f->n_components; i++) {
+ c = f->components[i];
- int ret = _topo_paths(el, ctx->paths, 1);
- if (ret < 0)
- return ret;
+ if (SCF_EDA_Battery == c->type) {
+ el = f->elines[c->pins[SCF_EDA_Battery_POS]->lid];
+ int ret = _topo_paths(el, ctx->paths, 1);
+ if (ret < 0)
+ return ret;
+ }
+ }
// scf_logi("\n");
// ses_paths_print(ctx->paths);
// scf_logi("\n\n");
- el = f->elines[B->pins[SCF_EDA_Battery_NEG]->lid];
-
- if (el->flags & SCF_EDA_PIN_GND) {
- ret = _topo_paths(el, ctx->paths, 1);
- if (ret < 0)
- return ret;
- }
-
- ret = _topo_paths_lc(f, f, ctx->paths);
+ int ret = _topo_paths_lc(f, f, ctx->paths);
if (ret < 0)
return ret;
#if 0
+++ /dev/null
-#include"ses_core.h"
-
-static void __ses_path_split_v(ScfEfunction* f, ses_path_t* path, int i0, int i, double a)
-{
- ScfEpin* p0 = path->pins->data[i0];
- ScfEpin* p = path->pins->data[i];
- ScfEcomponent* c = p->c;
-
- double v;
- double r;
-
- __ses_path_sr(f, path, i0, i, &r);
-
- ses_ir_u(&v, NULL, a, 0, r, 0);
-
- p->v = p0->v - v;
-
- if ((SCF_EDA_Capacitor == c->type || SCF_EDA_Inductor == c->type) && (i & 0x1)) {
- int sign = !p->id - p->id;
-
- p->v -= c->v * sign;
- }
-
- scf_logd("c%ldp%ld, c%ldp%ld, a: %lg, r: %lg, v: %lg, p0->v: %lg, p->v: %lg\n", p0->cid, p0->id, p->cid, p->id, a, r, v, p0->v, p->v);
-}
-
-void __ses_path_lc(ScfEfunction* f, ses_path_t* path, int m, int n, double* cv, double* lv, double* uf, double* uh, double* la)
-{
- ScfEcomponent* c;
- ScfEpin* p;
-
- int i;
-
- if (cv)
- *cv = 0;
-
- if (lv)
- *lv = 0;
-
- if (uf)
- *uf = 0;
-
- if (uh)
- *uh = 0;
-
- if (la)
- *la = 0;
-
- for (i = m; i <= n; i++) {
- p = path->pins->data[i];
- c = p->c;
-
- if (i & 0x1) {
- int sign = !p->id - p->id;
-
- if (SCF_EDA_Capacitor == c->type) {
- if (cv)
- *cv += c->v * sign;
-
- if (uf)
- *uf += c->uf;
-
- } else if (SCF_EDA_Inductor == c->type) {
- if (la)
- *la = c->a * sign;
-
- if (lv)
- *lv += c->v * sign;
-
- if (uh)
- *uh += c->uh;
- }
- }
- }
-}
-
-int __ses_path_va_branch(ScfEfunction* f, ses_path_t* path, int m, int n, double pr, int* changed, int64_t ps, int64_t count)
-{
- if (!path)
- return -EINVAL;
- if (path->pins->size < 2)
- return -EINVAL;
-
- if (n - m < 1)
- return 0;
-
- ScfEcomponent* c;
- ScfEpin* p0 = path->pins->data[m];
- ScfEpin* p1 = path->pins->data[n];
- ScfEline* el;
- ScfEpin* p;
- ScfEpin* p2;
-
- double _sr0 = p0->sr;
- double _pr0 = p0->pr;
- double _sr1 = p1->sr;
- double _pr1 = p1->pr;
-
- if (0 == m) {
- p0->sr = 0;
- p0->pr = 0;
- }
-
- if (path->pins->size - 1 == n) {
- p1->sr = path->sr;
- p1->pr = path->pr;
- }
-
- double cv = 0;
- double lv = 0;
- double a = 0;
- double v = p0->v - p1->v;
-
- __ses_path_lc(f, path, m, n, &cv, &lv, NULL, NULL, NULL);
- v -= cv + lv;
-
- ses_ur_i(&a, NULL, v, 0, pr, 0);
-
- if (0 == m && path->pins->size - 1 == n)
- path->a = a;
-
- scf_logd("path: %d, c%ldp%ld-c%ldp%ld, p0->v: %lg, p1->v: %lg, v: %lg, cv: %lg, lv: %lg, pr: %lg, path->pr: %lg, a: %lg\n\n",
- path->index, p0->cid, p0->id, p1->cid, p1->id, p0->v, p1->v, v, cv, lv, pr, path->pr, a);
-
- double r = 0;
- double dv = 0;
-
- int i0 = m;
- int i;
-
- for (i = m; i <= n; i++) {
- p = path->pins->data[i];
- c = p->c;
- el = ses_top_pline(p);
-
- scf_logd("c%ldp%ld, p->r: %lg, dr: %lg, sr: %lg, pr: %lg\n", p->cid, p->id, p->r, p->dr, p->sr, p->pr);
-
- __ses_path_split_v(f, path, i0, i, a);
-
- p->a = a;
-
- if (!el->vconst) {
- el->v = p->v;
- ses_line_set_v(c->pf->elines[p->lid], p->v);
- }
-
- r += p->r + p->dr;
-
- if (i & 0x1) {
- p2 = path->pins->data[i - 1];
- dv -= p->v;
- r += c->r + c->dr;
-
- int sign = !p->id - p->id;
-
- p2->a = a;
- c->a = a * sign;
- c->count = count;
-
- scf_logd("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, r: %lg, p->a: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n\n",
- path->index, i, p->cid, p->id, p->v, dv, r, p->a, a, p->pr, el->id, el->v);
-
- r = 0;
- } else {
- dv = p->v;
- scf_logd("path: %d, i: %d, c%ldp%ld, p->v: %lg, dv: %lg, a: %lg, p->pr: %lg, e%ld->v: %lg\n",
- path->index, i, p->cid, p->id, p->v, dv, a, p->pr, el->id, el->v);
- }
- }
-// printf("\n");
-
- if (0 == m) {
- p0->sr = _sr0;
- p0->pr = _pr0;
- }
-
- if (path->pins->size - 1 == n) {
- p1->sr = _sr1;
- p1->pr = _pr1;
- }
-
- path->vflag = 1;
- return 0;
-}
if (edge->edge_b)
printf(" b[%d]", edge->edge_b->index);
+
+ if (edge->mirror)
+ printf(" m[%d]", edge->mirror->index);
printf("; ");
}
#CFILES += pnp.c
#CFILES += colpitts.c
#CFILES += astable_multivibrator.c
-CFILES += two_battery.c
+#CFILES += two_battery.c
+CFILES += opa_rc.c
#CFILES += draw_timing.c
CFILES += ../scf_eda_pack.c
--- /dev/null
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+#include"ses_core.h"
+
+int main(int argc, char* argv[])
+{
+ ScfEcomponent* B0;
+ ScfEcomponent* B1;
+
+ ScfEcomponent* R0;
+ ScfEcomponent* R1;
+ ScfEcomponent* R2;
+ ScfEcomponent* C0;
+ ScfEcomponent* C1;
+ ScfEcomponent* C2;
+
+ ScfEcomponent* R3;
+ ScfEcomponent* R4;
+ ScfEcomponent* OP_AMP;
+
+ ScfEfunction* f;
+ ScfEboard* b;
+
+ b = scf_eboard__alloc();
+ f = scf_efunction__alloc("opa_rc");
+
+ EDA_INST_ADD_COMPONENT(f, B0, SCF_EDA_Battery);
+ EDA_INST_ADD_COMPONENT(f, B1, SCF_EDA_Battery);
+
+ EDA_INST_ADD_COMPONENT(f, R0, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R1, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R2, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, C0, SCF_EDA_Capacitor);
+ EDA_INST_ADD_COMPONENT(f, C1, SCF_EDA_Capacitor);
+ EDA_INST_ADD_COMPONENT(f, C2, SCF_EDA_Capacitor);
+
+ EDA_INST_ADD_COMPONENT(f, R3, SCF_EDA_Resistor);
+ EDA_INST_ADD_COMPONENT(f, R4, SCF_EDA_Resistor);
+
+ EDA_INST_ADD_COMPONENT(f, OP_AMP, SCF_EDA_OP_AMP);
+
+// B1->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
+ B0->pins[SCF_EDA_Battery_POS]->flags = SCF_EDA_PIN_POS;
+ B0->pins[SCF_EDA_Battery_NEG]->flags = SCF_EDA_PIN_NEG;
+
+ EDA_PIN_ADD_PIN(B0, SCF_EDA_Battery_NEG, B1, SCF_EDA_Battery_NEG);
+
+ EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_POS, B0, SCF_EDA_Battery_POS);
+ EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_NEG, B0, SCF_EDA_Battery_NEG);
+
+ EDA_PIN_ADD_PIN(R0, 0, R1, 1);
+ EDA_PIN_ADD_PIN(R1, 0, R2, 1);
+
+ EDA_PIN_ADD_PIN(C0, 1, R0, 0);
+ EDA_PIN_ADD_PIN(C1, 1, R1, 0);
+ EDA_PIN_ADD_PIN(C2, 1, R2, 0);
+ EDA_PIN_ADD_PIN(C0, 0, B0, SCF_EDA_Battery_NEG);
+ EDA_PIN_ADD_PIN(C1, 0, B0, SCF_EDA_Battery_NEG);
+ EDA_PIN_ADD_PIN(C2, 0, B0, SCF_EDA_Battery_NEG);
+
+ EDA_PIN_ADD_PIN(R3, 0, R4, 1);
+ EDA_PIN_ADD_PIN(R2, 0, R4, 0);
+
+ EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_IN, B1, SCF_EDA_Battery_POS);
+ EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_INVERT, R3, 0);
+ EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_OUT, R3, 1);
+ EDA_PIN_ADD_PIN(OP_AMP, SCF_EDA_OP_AMP_OUT, R0, 1);
+
+ OP_AMP->pins[SCF_EDA_OP_AMP_OUT]->flags = SCF_EDA_PIN_OUT;
+
+ B0->v = 5;
+ B1->v = 2.5;
+
+ R0->r = 10 * 1000;
+ R1->r = 10 * 1000;
+ R2->r = 10 * 1000;
+ C0->uf = 0.01;
+ C1->uf = 0.01;
+ C2->uf = 0.01;
+
+ R3->r = 1500 * 1000;
+ R4->r = 55.2 * 1000;
+
+ scf_eboard__add_function(b, f);
+
+ long len = 0;
+ uint8_t* buf = NULL;
+
+ ScfEboard_pack(b, &buf, &len);
+ ScfEboard_free(b);
+ b = NULL;
+
+ FILE* fp = fopen("./opa_rc.cpk", "wb");
+ if (!fp)
+ return -EINVAL;
+
+ fwrite(buf, len, 1, fp);
+ fclose(fp);
+ return 0;
+}