Skip to content

Commit 6356d57

Browse files
authored
IoT fan + led driver combo, new parts, I2C controller bridge (#518)
Refactors the IoT fan driver example to be a combination fan driver / 12v-capable neopixel driver. Changes it to a two-level board, adds sensors and the choice of USB PD input. Layout to be completed as a separate PR, which may also require changing the pinning and circuit split between levels. Removes IoT knob example, which is now redundant. Component library changes: - Add optional resistance to I2cPullup - Add I2cController bridge, allow I2cController to have addresses (mostly to encode inner devices), with tests - Add OE pin to 74xx1g125 - Add VL53L5CX Core / compiler changes: - Add array concatenation operation to compiler, using addition op - Add tolerance-shrinking subtract to compiler, though not plumbed through to frontend yet - Regenerate proto
1 parent 8377742 commit 6356d57

30 files changed

Lines changed: 16890 additions & 133321 deletions

compiler/src/main/scala/edg/compiler/Compiler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ class AssignNamer() {
117117
}
118118

119119
object Compiler {
120-
final val kExpectedProtoVersion = 12
120+
final val kExpectedProtoVersion = 13
121121
}
122122

123123
/** Compiler for a particular design, with an associated library to elaborate references from.

compiler/src/main/scala/edg/compiler/ExprEvaluate.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,23 @@ object ExprEvaluate {
3737
case (FloatPromotable(lhs), FloatValue(rhs)) => FloatValue(lhs + rhs)
3838
case (IntValue(lhs), IntValue(rhs)) => IntValue(lhs + rhs)
3939
case (TextValue(lhs), TextValue(rhs)) => TextValue(lhs + rhs)
40+
case (ArrayValue(lhss), ArrayValue(rhss)) =>
41+
if ((lhss.map(_.getClass) ++ rhss.map(_.getClass)).distinct.size > 1) {
42+
throw new ExprEvaluateException(s"Attempt to concat array of differing types $lhss, $rhss")
43+
}
44+
ArrayValue(lhss ++ rhss)
45+
case _ =>
46+
throw new ExprEvaluateException(s"Unknown binary operand types in $lhs ${binary.op} $rhs from $binary")
47+
}
48+
case Op.SHRINK_SUB => (lhs, rhs) match {
49+
case (RangeValue(lhsMin, lhsMax), RangeValue(rhsMin, rhsMax)) => RangeValue(lhsMin - rhsMin, lhsMax - rhsMax)
50+
case (RangeEmpty, RangeEmpty) => RangeEmpty
51+
case (lhs: RangeValue, RangeEmpty) => RangeEmpty
52+
case (RangeEmpty, rhs: RangeValue) => RangeEmpty
4053
case _ =>
4154
throw new ExprEvaluateException(s"Unknown binary operand types in $lhs ${binary.op} $rhs from $binary")
4255
}
56+
4357
case Op.MULT => (lhs, rhs) match {
4458
case (RangeValue(lhsMin, lhsMax), RangeValue(rhsMin, rhsMax)) =>
4559
val all = Seq(lhsMin * rhsMin, lhsMin * rhsMax, lhsMax * rhsMin, lhsMax * rhsMax)

compiler/src/main/scala/edg/compiler/ExprToString.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class ExprToString() extends ValueExprMap[String] {
3939
object InfixOp {
4040
def unapply(op: Op): Option[String] = op match {
4141
case Op.ADD => Some("+")
42+
case Op.SHRINK_SUB => Some("↓-")
4243
case Op.MULT => Some("×")
4344
case Op.SHRINK_MULT => Some("↓×")
4445
case Op.AND => Some("&&")
@@ -61,7 +62,7 @@ class ExprToString() extends ValueExprMap[String] {
6162
}
6263
object PrefixOp {
6364
def unapply(op: Op): Option[String] = op match {
64-
case Op.ADD | Op.MULT | Op.SHRINK_MULT => None
65+
case Op.ADD | Op.SHRINK_SUB | Op.MULT | Op.SHRINK_MULT => None
6566
case Op.AND | Op.OR | Op.XOR | Op.IMPLIES | Op.EQ | Op.NEQ => None
6667
case Op.GT | Op.GTE | Op.LT | Op.LTE => None
6768
case Op.MAX => Some("max")

compiler/src/test/scala/edg/compiler/ExprEvaluateTest.scala

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,22 @@ class ExprEvaluateTest extends AnyFlatSpec {
5252
) should equal(FloatValue(2.0))
5353
}
5454

55-
it should "handle shrink multiply" in {
55+
it should "handle shrink range ops" in {
5656
import edgir.expr.expr.BinaryExpr.Op
57+
58+
evalTest.map( // test x - x = 0 property
59+
ValueExpr.BinOp(
60+
Op.SHRINK_SUB,
61+
ValueExpr.Literal(10.0, 20.0),
62+
ValueExpr.Literal(10.0, 20.0)
63+
)) should equal(RangeValue(0.0, 0.0))
64+
evalTest.map( // ... and with negative numbers
65+
ValueExpr.BinOp(
66+
Op.SHRINK_SUB,
67+
ValueExpr.Literal(-20.0, -10.0),
68+
ValueExpr.Literal(-20.0, -10.0)
69+
)) should equal(RangeValue(0.0, 0.0))
70+
5771
evalTest.map( // test x * 1/x = 1 property
5872
ValueExpr.BinOp(
5973
Op.SHRINK_MULT,
@@ -297,17 +311,56 @@ class ExprEvaluateTest extends AnyFlatSpec {
297311
) should equal(IntValue(3))
298312
}
299313

314+
it should "handle array binary ops" in {
315+
import edgir.expr.expr.BinaryExpr.Op
316+
evalTest.map(
317+
ValueExpr.BinOp(
318+
Op.ADD,
319+
ValueExpr.Literal(Seq()),
320+
ValueExpr.Literal(Seq())
321+
)
322+
) should equal(ArrayValue(Seq()))
323+
324+
evalTest.map(
325+
ValueExpr.BinOp(
326+
Op.ADD,
327+
ValueExpr.Literal(Seq(Literal.Integer(0), Literal.Integer(1))),
328+
ValueExpr.Literal(Seq())
329+
)
330+
) should equal(ArrayValue(Seq(IntValue(0), IntValue(1))))
331+
332+
evalTest.map(
333+
ValueExpr.BinOp(
334+
Op.ADD,
335+
ValueExpr.Literal(Seq(Literal.Integer(0), Literal.Integer(1))),
336+
ValueExpr.Literal(Seq(Literal.Integer(3), Literal.Integer(4), Literal.Integer(5)))
337+
)
338+
) should equal(ArrayValue(Seq(IntValue(0), IntValue(1), IntValue(3), IntValue(4), IntValue(5))))
339+
340+
evalTest.map(
341+
ValueExpr.BinOp(
342+
Op.ADD,
343+
ValueExpr.Literal(Seq(Literal.Text("A"), Literal.Text("B"))),
344+
ValueExpr.Literal(Seq(Literal.Text("D"), Literal.Text("E"), Literal.Text("F")))
345+
)
346+
) should equal(ArrayValue(Seq(TextValue("A"), TextValue("B"), TextValue("D"), TextValue("E"), TextValue("F"))))
347+
348+
assertThrows[ExprEvaluateException] { // can't mix and match types
349+
evalTest.map(ValueExpr.BinOp(
350+
Op.ADD,
351+
ValueExpr.Literal(Seq(Literal.Text("A"))),
352+
ValueExpr.Literal(Seq(Literal.Integer(0)))
353+
))
354+
}
355+
}
356+
300357
it should "handle array unary set ops" in {
301358
import edg.ExprBuilder.Literal
302359
import edgir.expr.expr.UnarySetExpr.Op
303360
evalTest.map(
304361
ValueExpr.UnarySetOp(
305362
Op.NEGATE,
306-
ValueExpr.Literal(Seq(
307-
Literal.Boolean(false),
308-
Literal.Boolean(true),
309-
Literal.Boolean(false),
310-
)),
363+
ValueExpr.Literal(Seq(Literal.Boolean(false), Literal.Boolean(true), Literal.Boolean(false))),
311364
ValueExpr.Array(Seq())
312365
)
313366
) should equal(ArrayValue(Seq(BooleanValue(true), BooleanValue(false), BooleanValue(true))))

edg/circuits/I2cBitBang.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class I2cControllerBitBang(BitBangAdapter, Block):
88

99
def __init__(self) -> None:
1010
super().__init__()
11-
self.i2c = self.Port(I2cController.empty(), [Output])
11+
self.i2c = self.Port(I2cController(DigitalBidir.empty()), [Output])
1212
self.scl = self.Port(DigitalBidir.empty())
1313
self.sda = self.Port(DigitalBidir.empty())
1414

edg/circuits/I2cPullup.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44

55

66
class I2cPullup(Interface, Block):
7-
def __init__(self) -> None:
7+
def __init__(self, resistance: RangeLike = 4.7 * kOhm(tol=0.05)) -> None:
88
super().__init__()
9-
9+
self.resistance = self.ArgParameter(resistance)
1010
# TODO restrictions on I2C voltage, current draw modeling
1111
self.pwr = self.Port(VoltageSink.empty(), [Power])
1212
self.i2c = self.Port(I2cPullupPort.empty(), [InOut])
@@ -15,6 +15,6 @@ def __init__(self) -> None:
1515
def contents(self) -> None:
1616
super().contents()
1717

18-
res_model = PullupResistor(4.7 * kOhm(tol=0.05))
18+
res_model = PullupResistor(self.resistance)
1919
self.scl_res = self.Block(res_model).connected(self.pwr, self.i2c.scl)
2020
self.sda_res = self.Block(res_model).connected(self.pwr, self.i2c.sda)

edg/core/ArrayExpr.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from typing_extensions import TypeVar, override
66

7-
from .Binding import EqOp, ArrayBinding, UnarySetOpBinding, BinarySetOpBinding
7+
from .Binding import EqOp, ArrayBinding, UnarySetOpBinding, BinarySetOpBinding, BinaryOpBinding
88
from .ConstraintExpr import (
99
ConstraintExpr,
1010
IntLike,
@@ -110,6 +110,9 @@ def all_unique(self) -> BoolExpr:
110110
def all_equal(self) -> BoolExpr:
111111
return BoolExpr()._new_bind(UnarySetOpBinding(self, EqOp.all_equal, BoolExpr._to_expr_type(True)))
112112

113+
def concat(self: SelfType, other: ArrayCastableType) -> SelfType:
114+
return self._new_bind(BinaryOpBinding(self, self._to_expr_type(other), NumericOp.add))
115+
113116

114117
ArrayBoolLike = Union["ArrayBoolExpr", Sequence[BoolLike]]
115118

2.29 KB
Binary file not shown.

0 commit comments

Comments
 (0)