From faac22aebbb4dd384f73f297108b015ac53780f1 Mon Sep 17 00:00:00 2001
From: "yu.dongliang" <18588496441@163.com>
Date: Thu, 7 Sep 2023 21:31:23 +0800
Subject: [PATCH] ses_step_va_transistor.c

---
 ses_step_dc_input.c      |   2 +-
 ses_step_dc_transistor.c |  66 ++++++++++----
 ses_step_va_transistor.c | 189 ++++++++++++++++++++++++++++++---------
 3 files changed, 197 insertions(+), 60 deletions(-)

diff --git a/ses_step_dc_input.c b/ses_step_dc_input.c
index bef68ea..212beb3 100644
--- a/ses_step_dc_input.c
+++ b/ses_step_dc_input.c
@@ -17,7 +17,7 @@ static int _dc_input_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx
 
 		if (SCF_EDA_PIN_IN & el->flags) {
 
-			el->v = (i & 0x1) * B->v;
+			el->v = (0x1) * B->v;
 			el->vconst = 1;
 
 			scf_logw("IN el: %ld, V: %lg\n", el->id, el->v);
diff --git a/ses_step_dc_transistor.c b/ses_step_dc_transistor.c
index cfed3ef..d8200bc 100644
--- a/ses_step_dc_transistor.c
+++ b/ses_step_dc_transistor.c
@@ -4,16 +4,21 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se
 {
 	ScfEcomponent*   c;
 	ScfEcomponent*   B;
-	ScfEline*        el;
+	ScfEline*        lb;
+	ScfEline*        le;
 	ScfEpin*         pb;
 	ScfEpin*         pc;
 	ScfEpin*         pe;
+	ScfEpin*         Bp;
+	ScfEpin*         Bn;
 
 	size_t i;
 	size_t j;
 	size_t k;
 
-	B = f->components[0];
+	B  = f->components[0];
+	Bp = B->pins[SCF_EDA_Battery_POS];
+	Bn = B->pins[SCF_EDA_Battery_NEG];
 
 	for (i = 0; i < f->n_components; i++) {
 		c  =        f->components[i];
@@ -25,23 +30,54 @@ static int _dc_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se
 		pc = c->pins[SCF_EDA_Transistor_C];
 		pe = c->pins[SCF_EDA_Transistor_E];
 
-		el = f->elines[pe->lid];
-		if (el->v < SCF_EDA_V_MIN)
-			continue;
-		pe->v = el->v;
+		lb = f->elines[pb->lid];
+		le = f->elines[pe->lid];
 
-		el = f->elines[pb->lid];
-		if (el->v < SCF_EDA_V_MIN)
-			continue;
-		pb->v = el->v;
+		if (lb->v < SCF_EDA_V_MIN) {
+
+			if (le->v < SCF_EDA_V_MIN)
+				continue;
+
+			pe->v = le->v;
+			pb->v = le->v + 0.7;
+			lb->v = pb->v;
+
+			if (le->v == Bn->v)
+				lb->vconst = 1;
+
+			c->status = SCF_EDA_Status_ON;
+
+		} else if (le->v < SCF_EDA_V_MIN) {
+
+			pb->v = lb->v;
+			pe->v = lb->v - 0.7;
+			le->v = pe->v;
+
+			if (lb->v == Bp->v)
+				le->vconst = 1;
 
-		if (pb->v > pe->v + 0.7) {
-			pb->v = pe->v + 0.7;
-			el->v = pb->v;
-			el->vconst = 1;
 			c->status  = SCF_EDA_Status_ON;
+
+		} else if (lb->v >= le->v + 0.7) {
+
+			if (le->v == Bn->v) {
+				if (lb->v == Bp->v) {
+					scf_loge("Transistor c%ld, short connected\n", c->id);
+					return -EINVAL;
+				}
+
+				lb->vconst = 1;
+
+			} else if (lb->v == Bp->v)
+				le->vconst = 1;
+
+			lb->v = le->v + 0.7;
+			pb->v = lb->v;
+			pe->v = le->v;
+
+			c->status = SCF_EDA_Status_ON;
 		} else
-			c->status  = SCF_EDA_Status_OFF;
+			c->status = SCF_EDA_Status_OFF;
 
 		scf_loge("Transistor c%ld, status: %d\n", c->id, c->status);
 	}
diff --git a/ses_step_va_transistor.c b/ses_step_va_transistor.c
index 38118ed..bfd93df 100644
--- a/ses_step_va_transistor.c
+++ b/ses_step_va_transistor.c
@@ -1,15 +1,69 @@
 #include"ses_core.h"
 
-static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
+static void __ses_path_split_i(ses_path_t* path, ScfEpin* p0, ScfEpin* p1, ScfEline* el, double* a, double* ja)
 {
-	if (!path)
-		return -EINVAL;
+	ses_path_t*    child;
+	ScfEpin*       cp0;
+	ScfEpin*       cp1;
 
-	if (path->pins->size < 2) {
-		scf_loge("\n");
-		return -EINVAL;
+	double v  = p0->v   - p1->v;
+	double jv = p0->jv  - p1->jv;
+
+	double r  = p1->pr  - p0->pr;
+	double jr = p1->jpr - p0->jpr;
+
+	int j;
+	for (j    = 0; j < path->childs->size; j++) {
+		child =        path->childs->data[j];
+
+		cp0 = child->pins->data[0];
+		cp1 = child->pins->data[child->pins->size - 1];
+
+		if (cp0->lid != p0->lid || cp1->lid != p1->lid)
+			continue;
+
+		ses_split_i(&child->a, &child->ja, el->a, el->ja, child->r, child->jr, r, jr);
+
+		*a  -= child->a;
+		*ja -= child->ja;
+
+		cp0->a  = child->a;
+		cp0->ja = child->ja;
+		cp1->a  = child->a;
+		cp1->ja = child->ja;
+
+		double cr;
+		double jcr;
+
+		ses_ui_r(&cp1->dr, &cp1->jdr, v, jv, child->a, child->ja);
+
+		cp1->dr  -= child->r;
+		cp1->jdr -= child->jr;
+
+		scf_loge("j: %d, c%ldp%ld--c%ldp%ld, v: %lg + j%lg, child->r: %lg + j%lg, child->a: %lg + j%lg, el->a: %lg + j%lg, cp1->dr: %lg + j%lg\n",
+				j, cp0->cid, cp0->id, cp1->cid, cp1->id, v, jv, child->r, child->jr, child->a, child->ja, el->a, el->ja, cp1->dr, cp1->jdr);
 	}
+}
+
+static void __ses_path_dr(ScfEpin* p0, ScfEpin* p1, ScfEpin* p)
+{
+	double v  = p0->v   - p1->v;
+	double jv = p0->jv  - p1->jv;
+
+	double r  = p1->sr  - p0->sr;
+	double jr = p1->jsr - p0->jsr;
 
+	ses_ui_r(&p->dr, &p->jdr, v, jv, p->a, p->ja);
+
+	scf_logd("c%ldp%ld, v: %lg + j%lg, r: %lg + j%lg, p->a: %lg + j%lg, p->dr: %lg + j%lg\n", p->cid, p->id,
+			v, jv, r, jr, p->a, p->ja, p->dr, p->jdr);
+
+	p->dr  -= r;
+	p->jdr -= jr;
+}
+
+static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
+{
 	ses_path_t*    child;
 	ScfEcomponent* c;
 	ScfEline*      el;
@@ -17,8 +71,6 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
 	ScfEpin*       p0;
 	ScfEpin*       p1;
 	ScfEpin*       p2;
-	ScfEpin*       cp0;
-	ScfEpin*       cp1;
 
 	int i;
 	int j;
@@ -35,34 +87,59 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
 	p1->v  = el->v;
 	p1->jv = el->jv;
 
-	double v  = p0->v  - p1->v;
-	double jv = p0->jv - p1->jv;
-	double a  = 0;
-	double ja = 0;
+	double v;
+	double jv;
 
-	ses_ur_i(&a, &ja, v, jv, path->r, path->jr);
+	double pr;
+	double jpr;
+	double sr;
+	double jsr;
 
-	scf_loge("path: %d, v: %lg + j%lg, r: %lg + j%lg, a: %lg + j%lg\n", path->index, v, jv, path->r, path->jr, a, ja);
+	for (i = 1; i < path->pins->size - 1; i++) {
+		p  =        path->pins->data[i];
 
-	double r   = 0;
-	double jr  = 0;
-	double dv  = 0;
-	double jdv = 0;
+		el = f->elines    [p->lid];
+		c  = f->components[p->cid];
 
-	for (i = 0; i < path->pins->size; i++) {
-		p  =        path->pins->data[i];
+		if (!el->vconst)
+			continue;
+
+		if (SCF_EDA_Transistor != c->type)
+			continue;
+
+		p->v  = el->v;
+		p->jv = el->jv;
+
+		if (SCF_EDA_Transistor_B == p->id) {
 
-		if (path->childs) {
-			for (j    = 0; j < path->childs->size; j++) {
-				child =        path->childs->data[j];
+			v   = p0->v  - p->v;
+			jv  = p0->jv - p->jv;
 
-				cp0 = child->pins->data[0];
-				cp1 = child->pins->data[child->pins->size - 1];
+			pr  = p->pr  - p0->pr;
+			jpr = p->jpr - p0->jpr;
+
+			sr  = p->sr  - p0->sr;
+			jsr = p->jsr - p0->jsr;
+
+			ses_ur_i(&el->a, &el->ja, v, jv, pr, jpr);
+
+			p->a       = el->a;
+			p->ja      = el->ja;
+			el->aconst = 1;
+
+			if (path->childs)
+				__ses_path_split_i(path, p, p1, el, &p->a, &p->ja);
+
+			__ses_path_dr(p, p1, p);
+
+			scf_loge("i: %d, c%ldp%ld--c%ldp%ld, v: %lg + j%lg, p->v: %lg + j%lg, p->a: %lg + j%lg, pr: %lg + j%lg, sr: %lg + j%lg, p->dr: %lg + j%lg\n",
+					i, p->cid, p->id, p1->cid, p1->id, v, jv, p->v, p->jv, p->a, p->ja, pr, jpr, sr, jsr, p->dr, p->jdr);
+
+
+		} else if (SCF_EDA_Transistor_C == p->id) {
+
+		} else {
 
-				int ret = __ses_path_va_transistor(f, child);
-				if (ret < 0)
-					return ret;
-			}
 		}
 	}
 	printf("\n");
@@ -70,9 +147,8 @@ static int __ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
 	return 0;
 }
 
-static int _va_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+static int ses_path_va_transistor(ScfEfunction* f, ses_path_t* path)
 {
-	ses_path_t*    path;
 	ScfEcomponent* B;
 	ScfEpin*       p0;
 	ScfEpin*       p1;
@@ -83,33 +159,58 @@ static int _va_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, se
 	size_t j;
 	size_t k;
 
+	if (!path)
+		return -EINVAL;
+
+	if (path->pins->size < 2) {
+		scf_loge("\n");
+		return -EINVAL;
+	}
+
 	B  = f->components[0];
 	Bp = B->pins[SCF_EDA_Battery_POS];
 	Bn = B->pins[SCF_EDA_Battery_NEG];
-#if 0
-	for (i = 0; i < ctx->paths->size; i++) {
-		path      = ctx->paths->data[i];
 
-		scf_logi("i: %ld, path->type: %d\n", i, path->type);
+	p0 = path->pins->data[0];
+	p1 = path->pins->data[path->pins->size - 1];
+
+	if (p0->lid != Bp->lid || p1->lid != Bn->lid)
+		return 0;
+
+	int ret = __ses_path_va_transistor(f, path);
+	if (ret < 0)
+		return ret;
 
-		if (path->pins->size < 2) {
-			scf_loge("\n");
-			return -EINVAL;
+	if (path->childs) {
+		for (j = 0; j < path->childs->size; j++) {
+
+			ret = ses_path_va_transistor(f, path->childs->data[j]);
+			if (ret < 0)
+				return ret;
 		}
+	}
 
-		p0 = path->pins->data[0];
-		p1 = path->pins->data[path->pins->size - 1];
+	return 0;
+}
 
-		if (p0->lid != Bp->lid || p1->lid != Bn->lid)
-			continue;
+static int _va_transistor_handler(ScfEfunction* f, int64_t ns, int64_t count, ses_ctx_t* ctx)
+{
+	ses_path_t* path;
+
+	size_t i;
+
+	for (i = 0; i < ctx->paths->size; i++) {
+		path      = ctx->paths->data[i];
 
-		int ret = __ses_path_va_transistor(f, path);
+		scf_logi("i: %ld, path->type: %d\n", i, path->type);
+
+		int ret = ses_path_va_transistor(f, path);
 		if (ret < 0)
 			return ret;
 
 		printf("\n");
 	}
-#endif
+
 	return 0;
 }
 
-- 
2.25.1