label improvements

This commit is contained in:
Bane Stojkovic
2026-09-07 12:50:12 +02:00
parent b7c707e68a
commit 3d6241b17e
5 changed files with 301 additions and 217 deletions
@@ -47,6 +47,7 @@ import org.diylc.core.VisibilityPolicy;
import org.diylc.core.annotations.EditableProperty;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.netlist.Node;
import org.diylc.utils.Constants;
/**
@@ -257,22 +258,31 @@ public abstract class AbstractMakerBoard extends AbstractTransparentComponent<Vo
}
/**
* Helper to format a pin name for silkscreen display by omitting any parenthesized content
* and any trailing underscore suffixes (e.g. "3V3_1" -> "3V3", "A0 (ADC0)" -> "A0").
* Helper to format a pin name for silkscreen display (e.g. "3V3_1" -> "3V3", "A0 (ADC0)" -> "A0").
*
* <p>Stripping the parenthesized annotation is the same operation the netlist performs, so it is
* delegated to {@link Node#sanitizeNodeName(String)} rather than duplicated. The silkscreen goes
* one step further and also drops the trailing disambiguator, because a board prints "GND" on
* every ground pin even though the netlist has to tell "GND_1" from "GND_2".
*/
public static String getDisplayPinLabel(String name) {
if (name == null) {
String sanitized = Node.sanitizeNodeName(name);
if (sanitized == null) {
return "";
}
int parenIdx = name.indexOf('(');
if (parenIdx != -1) {
name = name.substring(0, parenIdx);
}
int underscoreIdx = name.indexOf('_');
if (underscoreIdx != -1) {
name = name.substring(0, underscoreIdx);
}
return name.trim();
int underscoreIdx = sanitized.indexOf('_');
return (underscoreIdx == -1 ? sanitized : sanitized.substring(0, underscoreIdx)).trim();
}
/**
* Silkscreen text printed next to a pin. Defaults to the node name with its annotation and
* disambiguator stripped, which is right whenever the node name is the silkscreen name plus
* extra detail. A board whose silkscreen genuinely differs from its node names -- the ESP
* DevKits print bare GPIO numbers while their nodes carry the full function list -- overrides
* this to return its own silkscreen label.
*/
protected String getSilkPinLabel(int index) {
return getDisplayPinLabel(getControlPointNodeName(index));
}
/**
@@ -294,9 +304,8 @@ public abstract class AbstractMakerBoard extends AbstractTransparentComponent<Vo
g2d.setFont(PIN_FONT);
for (int i = 0; i < count; i++) {
String name = getControlPointNodeName(i);
String label = getDisplayPinLabel(name);
if (label.isEmpty()) {
String label = getSilkPinLabel(i);
if (label == null || label.isEmpty()) {
continue;
}
double pinX = x + offsets[i][0];
@@ -116,22 +116,58 @@ public class ESP32DevKit extends AbstractMakerBoard {
public static Size SHIELD_WIDTH_S3 = new Size(16.0d, SizeUnit.mm);
public static Size SHIELD_LENGTH_S3 = new Size(16.0d, SizeUnit.mm);
// Node names follow the convention used by the other boards in this package: the name a pin is
// identified by, followed by its alternate functions in parentheses. The silkscreen prints only
// a bare token, so each variant carries a parallel SILK_NAMES array with what is on the board.
// Function lists come from the Espressif esp-dev-kits user guides for the DevKitC boards; the
// DevKit V1 is a DOIT board with no vendor documentation, so its functions are those of the
// ESP32-WROOM-32 module it carries.
public static final String[] PIN_NAMES_30 = new String[] {
// Left row (pins 0..14, top to bottom)
"EN", "VP", "VN", "D34", "D35", "D32", "D33", "D25", "D26", "D27", "D14", "D12", "GND_3", "GND_1", "VIN",
"EN (CHIP_PU, Reset)", "VP (GPIO36, ADC1_CH0, S_VP)", "VN (GPIO39, ADC1_CH3, S_VN)",
"GPIO34 (ADC1_CH6, VDET_1)", "GPIO35 (ADC1_CH7, VDET_2)",
"GPIO32 (ADC1_CH4, TOUCH_CH9, XTAL_32K_P)", "GPIO33 (ADC1_CH5, TOUCH_CH8, XTAL_32K_N)",
"GPIO25 (ADC2_CH8, DAC_1)", "GPIO26 (ADC2_CH9, DAC_2)", "GPIO27 (ADC2_CH7, TOUCH_CH7)",
"GPIO14 (ADC2_CH6, TOUCH_CH6, MTMS)", "GPIO12 (ADC2_CH5, TOUCH_CH5, MTDI)",
"GPIO13 (ADC2_CH4, TOUCH_CH4, MTCK)", "GND_1", "VIN",
// Right row (pins 15..29, top to bottom)
"D23", "D22", "TXD", "RXD", "D21", "D19", "D18", "D5", "TX2", "RX2", "D4", "D2", "D15", "GND_2", "3V3"
"GPIO23", "GPIO22 (SCL)", "TX0 (GPIO1, U0TXD)", "RX0 (GPIO3, U0RXD)", "GPIO21 (SDA)",
"GPIO19", "GPIO18", "GPIO5", "TX2 (GPIO17, U2TXD)", "RX2 (GPIO16, U2RXD)",
"GPIO4 (ADC2_CH0, TOUCH_CH0)", "GPIO2 (ADC2_CH2, TOUCH_CH2)",
"GPIO15 (ADC2_CH3, TOUCH_CH3, MTDO)", "GND_2", "3V3"
};
public static final String[] SILK_NAMES_30 = new String[] {
// Left row (pins 0..14, top to bottom)
"EN", "VP", "VN", "D34", "D35", "D32", "D33", "D25", "D26", "D27", "D14", "D12", "D13", "GND", "VIN",
// Right row (pins 15..29, top to bottom)
"D23", "D22", "TX0", "RX0", "D21", "D19", "D18", "D5", "TX2", "RX2", "D4", "D2", "D15", "GND", "3V3"
};
public static final String[] PIN_NAMES_38 = new String[] {
// Left row (J2: pins 0..18, top to bottom)
"3V3", "EN", "VP", "VN", "34", "35", "32", "33",
"25", "26", "27", "14", "12", "GND_1", "13",
"D2", "D3", "CMD", "5V",
"3V3", "EN (CHIP_PU, Reset)", "VP (GPIO36, ADC1_CH0, S_VP)", "VN (GPIO39, ADC1_CH3, S_VN)",
"GPIO34 (ADC1_CH6, VDET_1)", "GPIO35 (ADC1_CH7, VDET_2)",
"GPIO32 (ADC1_CH4, TOUCH_CH9, XTAL_32K_P)", "GPIO33 (ADC1_CH5, TOUCH_CH8, XTAL_32K_N)",
"GPIO25 (ADC2_CH8, DAC_1)", "GPIO26 (ADC2_CH9, DAC_2)", "GPIO27 (ADC2_CH7, TOUCH_CH7)",
"GPIO14 (ADC2_CH6, TOUCH_CH6, MTMS)", "GPIO12 (ADC2_CH5, TOUCH_CH5, MTDI)", "GND_1",
"GPIO13 (ADC2_CH4, TOUCH_CH4, MTCK)", "D2 (GPIO9, flash)", "D3 (GPIO10, flash)",
"CMD (GPIO11, flash)", "5V",
// Right row (J3: pins 19..37, top to bottom)
"GND_2", "23", "22", "TX", "RX", "21", "GND_3",
"19", "18", "5", "17", "16", "4", "0", "2",
"15", "D1", "D0", "CLK"
"GND_2", "GPIO23", "GPIO22", "TX (GPIO1, U0TXD)", "RX (GPIO3, U0RXD)", "GPIO21", "GND_3",
"GPIO19", "GPIO18", "GPIO5", "GPIO17", "GPIO16", "GPIO4 (ADC2_CH0, TOUCH_CH0)",
"GPIO0 (ADC2_CH1, TOUCH_CH1, Boot)", "GPIO2 (ADC2_CH2, TOUCH_CH2)",
"GPIO15 (ADC2_CH3, TOUCH_CH3, MTDO)", "D1 (GPIO8, flash)", "D0 (GPIO7, flash)",
"CLK (GPIO6, flash)"
};
public static final String[] SILK_NAMES_38 = new String[] {
// Left row (J2: pins 0..18, top to bottom)
"3V3", "EN", "VP", "VN", "IO34", "IO35", "IO32", "IO33", "IO25", "IO26", "IO27", "IO14",
"IO12", "GND", "IO13", "D2", "D3", "CMD", "5V",
// Right row (J3: pins 19..37, top to bottom)
"GND", "IO23", "IO22", "TX", "RX", "IO21", "GND", "IO19", "IO18", "IO5", "IO17", "IO16",
"IO4", "IO0", "IO2", "IO15", "D1", "D0", "CLK"
};
// ESP32-C3-DevKitM-1 and ESP32-C6-DevKitC-1 share the DevKitC form factor: 25.4 mm wide with
@@ -157,33 +193,76 @@ public class ESP32DevKit extends AbstractMakerBoard {
public static final String[] PIN_NAMES_S3_44 = new String[] {
// Left row (J1: pins 0..21, top to bottom)
"3V3_1", "3V3_2", "RST", "4", "5", "6", "7",
"15", "16", "17", "18", "8", "3",
"46", "9", "10", "11", "12", "13",
"14", "5V", "GND_1",
"3V3_1", "3V3_2", "RST (EN)", "GPIO4 (RTC_GPIO4, TOUCH4, ADC1_CH3)",
"GPIO5 (RTC_GPIO5, TOUCH5, ADC1_CH4)", "GPIO6 (RTC_GPIO6, TOUCH6, ADC1_CH5)",
"GPIO7 (RTC_GPIO7, TOUCH7, ADC1_CH6)", "GPIO15 (U0RTS, ADC2_CH4, XTAL_32K_P)",
"GPIO16 (U0CTS, ADC2_CH5, XTAL_32K_N)", "GPIO17 (U1TXD, ADC2_CH6)",
"GPIO18 (U1RXD, ADC2_CH7, CLK_OUT3)", "GPIO8 (TOUCH8, ADC1_CH7, SUBSPICS1)",
"GPIO3 (RTC_GPIO3, TOUCH3, ADC1_CH2)", "GPIO46",
"GPIO9 (TOUCH9, ADC1_CH8, FSPIHD)", "GPIO10 (TOUCH10, ADC1_CH9, FSPICS0)",
"GPIO11 (TOUCH11, ADC2_CH0, FSPID)", "GPIO12 (TOUCH12, ADC2_CH1, FSPICLK)",
"GPIO13 (TOUCH13, ADC2_CH2, FSPIQ)", "GPIO14 (TOUCH14, ADC2_CH3, FSPIWP)", "5V", "GND_1",
// Right row (J3: pins 22..43, top to bottom)
"GND_2", "TX", "RX", "1", "2",
"42", "41", "40", "39", "38",
"37", "36", "35", "0", "45",
"48", "47", "21", "20", "19",
"GND_3", "GND_4"
"GND_2", "TX (GPIO43, U0TXD, CLK_OUT1)", "RX (GPIO44, U0RXD, CLK_OUT2)",
"GPIO1 (RTC_GPIO1, TOUCH1, ADC1_CH0)", "GPIO2 (RTC_GPIO2, TOUCH2, ADC1_CH1)",
"GPIO42 (MTMS)", "GPIO41 (MTDI, CLK_OUT1)", "GPIO40 (MTDO, CLK_OUT2)",
"GPIO39 (MTCK, CLK_OUT3, SUBSPICS1)", "GPIO38 (FSPIWP, RGB LED)", "GPIO37 (SPIDQS, FSPIQ)",
"GPIO36 (SPIIO7, FSPICLK)", "GPIO35 (SPIIO6, FSPID)", "GPIO0 (RTC_GPIO0, Boot)", "GPIO45",
"GPIO48 (SPICLK_N)", "GPIO47 (SPICLK_P)", "GPIO21 (RTC_GPIO21)",
"GPIO20 (U1CTS, ADC2_CH9, USB_D+)", "GPIO19 (U1RTS, ADC2_CH8, USB_D-)", "GND_3", "GND_4"
};
public static final String[] SILK_NAMES_S3_44 = new String[] {
// Left row (J1: pins 0..21, top to bottom)
"3V3", "3V3", "RST", "4", "5", "6", "7", "15", "16", "17", "18", "8", "3", "46", "9", "10",
"11", "12", "13", "14", "5V", "G",
// Right row (J3: pins 22..43, top to bottom)
"G", "TX", "RX", "1", "2", "42", "41", "40", "39", "38", "37", "36", "35", "0", "45", "48",
"47", "21", "20", "19", "G", "G"
};
public static final String[] PIN_NAMES_C3_30 = new String[] {
// J1 (left row: pins 0..14, top to bottom)
"GND_1", "3V3_1", "3V3_2", "IO2", "IO3", "GND_2", "RST", "GND_3", "IO0", "IO1", "IO10",
"GND_4", "5V_1", "5V_2", "GND_5",
"GND_1", "3V3_1", "3V3_2", "GPIO2 (ADC1_CH2, FSPIQ)", "GPIO3 (ADC1_CH3)", "GND_2",
"RST (CHIP_PU)", "GND_3", "GPIO0 (ADC1_CH0, XTAL_32K_P)", "GPIO1 (ADC1_CH1, XTAL_32K_N)",
"GPIO10 (FSPICS0)", "GND_4", "5V_1", "5V_2", "GND_5",
// J3 (right row: pins 15..29, top to bottom)
"GND_6", "TX", "RX", "GND_7", "IO9", "IO8", "GND_8", "IO7", "IO6", "IO5", "IO4", "GND_9",
"IO18", "IO19", "GND_10"
"GND_6", "TX (GPIO21, U0TXD)", "RX (GPIO20, U0RXD)", "GND_7", "GPIO9", "GPIO8 (RGB LED)",
"GND_8", "GPIO7 (FSPID, MTDO)", "GPIO6 (FSPICLK, MTCK)", "GPIO5 (ADC2_CH0, FSPIWP, MTDI)",
"GPIO4 (ADC1_CH4, FSPIHD, MTMS)", "GND_9", "GPIO18 (USB_D-)", "GPIO19 (USB_D+)", "GND_10"
};
public static final String[] SILK_NAMES_C3_30 = new String[] {
// J1 (left row: pins 0..14, top to bottom)
"GND", "3V3", "3V3", "IO2", "IO3", "GND", "RST", "GND", "IO0", "IO1", "IO10", "GND", "5V",
"5V", "GND",
// J3 (right row: pins 15..29, top to bottom)
"GND", "TX", "RX", "GND", "IO9", "IO8", "GND", "IO7", "IO6", "IO5", "IO4", "GND", "IO18",
"IO19", "GND"
};
public static final String[] PIN_NAMES_C6_32 = new String[] {
// J1 (left row: pins 0..15, top to bottom)
"3V3", "RST", "4", "5", "6", "7", "0", "1", "8", "10", "11", "2", "3", "5V", "GND_1", "NC_1",
"3V3", "RST", "GPIO4 (MTMS, LP_GPIO4, LP_UART_RXD, ADC1_CH4, FSPIHD)",
"GPIO5 (MTDI, LP_GPIO5, LP_UART_TXD, ADC1_CH5, FSPIWP)",
"GPIO6 (MTCK, LP_GPIO6, LP_I2C_SDA, ADC1_CH6, FSPICLK)",
"GPIO7 (MTDO, LP_GPIO7, LP_I2C_SCL, FSPID)",
"GPIO0 (XTAL_32K_P, LP_GPIO0, LP_UART_DTRN, ADC1_CH0)",
"GPIO1 (XTAL_32K_N, LP_GPIO1, LP_UART_DSRN, ADC1_CH1)", "GPIO8 (RGB LED)", "GPIO10",
"GPIO11", "GPIO2 (LP_GPIO2, LP_UART_RTSN, ADC1_CH2, FSPIQ)",
"GPIO3 (LP_GPIO3, LP_UART_CTSN, ADC1_CH3)", "5V", "GND_1", "NC_1",
// J3 (right row: pins 16..31, top to bottom)
"GND_2", "TX", "RX", "15", "23", "22", "21", "20", "19", "18", "9", "GND_3", "13", "12",
"GND_4", "NC_2"
"GND_2", "TX (GPIO16, U0TXD, FSPICS0)", "RX (GPIO17, U0RXD, FSPICS1)", "GPIO15",
"GPIO23 (SDIO_DATA3)", "GPIO22 (SDIO_DATA2)", "GPIO21 (SDIO_DATA1, FSPICS5)",
"GPIO20 (SDIO_DATA0, FSPICS4)", "GPIO19 (SDIO_CLK, FSPICS3)", "GPIO18 (SDIO_CMD, FSPICS2)",
"GPIO9", "GND_3", "GPIO13 (USB_D+)", "GPIO12 (USB_D-)", "GND_4", "NC_2"
};
public static final String[] SILK_NAMES_C6_32 = new String[] {
// J1 (left row: pins 0..15, top to bottom)
"3V3", "RST", "4", "5", "6", "7", "0", "1", "8", "10", "11", "2", "3", "5V", "G", "NC",
// J3 (right row: pins 16..31, top to bottom)
"G", "TX", "RX", "15", "23", "22", "21", "20", "19", "18", "9", "G", "13", "12", "G", "NC"
};
private DevKitVersion version = DevKitVersion.DevKit_V1_30Pin;
@@ -227,6 +306,30 @@ public class ESP32DevKit extends AbstractMakerBoard {
}
}
private String[] getSilkNames() {
switch (getVersion()) {
case DevKitC_V4_38Pin:
return SILK_NAMES_38;
case ESP32_S3_DevKitC_44Pin:
return SILK_NAMES_S3_44;
case ESP32_C3_DevKitM_1:
return SILK_NAMES_C3_30;
case ESP32_C6_DevKitC_1:
return SILK_NAMES_C6_32;
default:
return SILK_NAMES_30;
}
}
@Override
protected String getSilkPinLabel(int index) {
String[] silkNames = getSilkNames();
if (index >= 0 && index < silkNames.length) {
return silkNames[index];
}
return super.getSilkPinLabel(index);
}
private Size getRiscVShieldWidth() {
return getVersion() == DevKitVersion.ESP32_C3_DevKitM_1 ? SHIELD_WIDTH_C3 : SHIELD_WIDTH_C6;
}
@@ -73,11 +73,27 @@ public class ESP8266NodeMCU extends AbstractMakerBoard {
public static Size HOLE_DISTANCE_Y = new Size(44.0d, SizeUnit.mm);
public static Size HOLE_DIAMETER = new Size(3.2d, SizeUnit.mm);
// Node names carry the GPIO number and function, because the NodeMCU's Dn labels are board
// aliases that do not follow the ESP8266's own numbering -- D1 is GPIO5, not GPIO1 -- and that
// mapping is the single thing people most often get wrong on this board. SILK_NAMES holds what
// is actually printed next to each pin.
public static final String[] PIN_NAMES = new String[] {
// Left row (pins 0..14)
"A0", "RSV_1", "RSV_2", "SD3", "SD2", "SD1", "CMD", "SD0", "CLK", "GND_1", "3V3_1", "EN", "RST", "GND_2", "VIN",
"A0 (ADC0)", "RSV_1", "RSV_2", "SD3 (GPIO10, flash)", "SD2 (GPIO9, flash)",
"SD1 (GPIO8, flash)", "CMD (GPIO11, flash)", "SD0 (GPIO7, flash)", "CLK (GPIO6, flash)",
"GND_1", "3V3_1", "EN (CH_PD)", "RST", "GND_2", "VIN",
// Right row (pins 15..29)
"D0", "D1", "D2", "D3", "D4", "3V3_2", "GND_3", "D5", "D6", "D7", "D8", "RX", "TX", "GND_4", "3V3_3"
"D0 (GPIO16, WAKE)", "D1 (GPIO5, SCL)", "D2 (GPIO4, SDA)", "D3 (GPIO0, FLASH)",
"D4 (GPIO2, LED)", "3V3_2", "GND_3", "D5 (GPIO14, HSPI SCLK)", "D6 (GPIO12, HSPI MISO)",
"D7 (GPIO13, HSPI MOSI)", "D8 (GPIO15, HSPI CS)", "RX (GPIO3, U0RXD)", "TX (GPIO1, U0TXD)",
"GND_4", "3V3_3"
};
public static final String[] SILK_NAMES = new String[] {
// Left row (pins 0..14)
"A0", "RSV", "RSV", "SD3", "SD2", "SD1", "CMD", "SD0", "CLK", "GND", "3V3", "EN", "RST", "GND", "VIN",
// Right row (pins 15..29)
"D0", "D1", "D2", "D3", "D4", "3V3", "GND", "D5", "D6", "D7", "D8", "RX", "TX", "GND", "3V3"
};
protected boolean headers = false;
@@ -106,6 +122,14 @@ public class ESP8266NodeMCU extends AbstractMakerBoard {
return "Pin " + (index + 1);
}
@Override
protected String getSilkPinLabel(int index) {
if (index >= 0 && index < SILK_NAMES.length) {
return SILK_NAMES[index];
}
return super.getSilkPinLabel(index);
}
private double[][] getRelativeOffsets() {
double spacing = PIN_SPACING.convertToPixels();
double rowSpacing = ROW_SPACING.convertToPixels(); // 180px
@@ -5,6 +5,7 @@ import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import org.diylc.components.AbstractMakerBoard;
import org.diylc.netlist.Node;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.junit.Assert;
@@ -24,39 +25,40 @@ public class ESP32DevKitTest {
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
}
// Left row (0..14, top to bottom)
Assert.assertEquals("EN", devKit.getControlPointNodeName(0));
Assert.assertEquals("VP", devKit.getControlPointNodeName(1));
Assert.assertEquals("VN", devKit.getControlPointNodeName(2));
Assert.assertEquals("D34", devKit.getControlPointNodeName(3));
Assert.assertEquals("D35", devKit.getControlPointNodeName(4));
Assert.assertEquals("D32", devKit.getControlPointNodeName(5));
Assert.assertEquals("D33", devKit.getControlPointNodeName(6));
Assert.assertEquals("D25", devKit.getControlPointNodeName(7));
Assert.assertEquals("D26", devKit.getControlPointNodeName(8));
Assert.assertEquals("D27", devKit.getControlPointNodeName(9));
Assert.assertEquals("D14", devKit.getControlPointNodeName(10));
Assert.assertEquals("D12", devKit.getControlPointNodeName(11));
Assert.assertEquals("GND_3", devKit.getControlPointNodeName(12));
Assert.assertEquals("GND_1", devKit.getControlPointNodeName(13));
Assert.assertEquals("VIN", devKit.getControlPointNodeName(14));
// Silkscreen, exactly as printed down each side of the board
assertSilk(devKit, 0, "EN", "VP", "VN", "D34", "D35", "D32", "D33", "D25", "D26", "D27",
"D14", "D12", "D13", "GND", "VIN");
assertSilk(devKit, 15, "D23", "D22", "TX0", "RX0", "D21", "D19", "D18", "D5", "TX2", "RX2",
"D4", "D2", "D15", "GND", "3V3");
// Right row (15..29, top to bottom)
Assert.assertEquals("D23", devKit.getControlPointNodeName(15));
Assert.assertEquals("D22", devKit.getControlPointNodeName(16));
Assert.assertEquals("TXD", devKit.getControlPointNodeName(17));
Assert.assertEquals("RXD", devKit.getControlPointNodeName(18));
Assert.assertEquals("D21", devKit.getControlPointNodeName(19));
Assert.assertEquals("D19", devKit.getControlPointNodeName(20));
Assert.assertEquals("D18", devKit.getControlPointNodeName(21));
Assert.assertEquals("D5", devKit.getControlPointNodeName(22));
Assert.assertEquals("TX2", devKit.getControlPointNodeName(23));
Assert.assertEquals("RX2", devKit.getControlPointNodeName(24));
Assert.assertEquals("D4", devKit.getControlPointNodeName(25));
Assert.assertEquals("D2", devKit.getControlPointNodeName(26));
Assert.assertEquals("D15", devKit.getControlPointNodeName(27));
Assert.assertEquals("GND_2", devKit.getControlPointNodeName(28));
Assert.assertEquals("3V3", devKit.getControlPointNodeName(29));
// Netlist identity: the GPIO number for numbered pins, the signal name otherwise
assertNodeIds(devKit, 0, "EN", "VP", "VN", "GPIO34", "GPIO35", "GPIO32", "GPIO33", "GPIO25",
"GPIO26", "GPIO27", "GPIO14", "GPIO12", "GPIO13", "GND_1", "VIN");
assertNodeIds(devKit, 15, "GPIO23", "GPIO22", "TX0", "RX0", "GPIO21", "GPIO19", "GPIO18",
"GPIO5", "TX2", "RX2", "GPIO4", "GPIO2", "GPIO15", "GND_2", "3V3");
// The annotation carries what the silkscreen cannot
Assert.assertEquals("GPIO34 (ADC1_CH6, VDET_1)", devKit.getControlPointNodeName(3));
Assert.assertEquals("TX0 (GPIO1, U0TXD)", devKit.getControlPointNodeName(17));
}
/** Asserts the silkscreen labels printed next to consecutive pins starting at {@code start}. */
private void assertSilk(ESP32DevKit devKit, int start, String... expected) {
for (int i = 0; i < expected.length; i++) {
Assert.assertEquals("Silkscreen for pin " + (start + i), expected[i],
devKit.getSilkPinLabel(start + i));
}
}
/**
* Asserts how consecutive pins appear in a netlist, which is the node name with its parenthesized
* annotation stripped.
*/
private void assertNodeIds(ESP32DevKit devKit, int start, String... expected) {
for (int i = 0; i < expected.length; i++) {
Assert.assertEquals("Node name for pin " + (start + i), expected[i],
Node.sanitizeNodeName(devKit.getControlPointNodeName(start + i)));
}
}
@Test
@@ -72,47 +74,19 @@ public class ESP32DevKitTest {
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
}
// Left row (J2: 0..18, top to bottom)
Assert.assertEquals("3V3", devKit.getControlPointNodeName(0));
Assert.assertEquals("EN", devKit.getControlPointNodeName(1));
Assert.assertEquals("VP", devKit.getControlPointNodeName(2));
Assert.assertEquals("VN", devKit.getControlPointNodeName(3));
Assert.assertEquals("34", devKit.getControlPointNodeName(4));
Assert.assertEquals("35", devKit.getControlPointNodeName(5));
Assert.assertEquals("32", devKit.getControlPointNodeName(6));
Assert.assertEquals("33", devKit.getControlPointNodeName(7));
Assert.assertEquals("25", devKit.getControlPointNodeName(8));
Assert.assertEquals("26", devKit.getControlPointNodeName(9));
Assert.assertEquals("27", devKit.getControlPointNodeName(10));
Assert.assertEquals("14", devKit.getControlPointNodeName(11));
Assert.assertEquals("12", devKit.getControlPointNodeName(12));
Assert.assertEquals("GND_1", devKit.getControlPointNodeName(13));
Assert.assertEquals("13", devKit.getControlPointNodeName(14));
Assert.assertEquals("D2", devKit.getControlPointNodeName(15));
Assert.assertEquals("D3", devKit.getControlPointNodeName(16));
Assert.assertEquals("CMD", devKit.getControlPointNodeName(17));
Assert.assertEquals("5V", devKit.getControlPointNodeName(18));
// Silkscreen (J2 then J3), matching the Espressif user guide's header tables
assertSilk(devKit, 0, "3V3", "EN", "VP", "VN", "IO34", "IO35", "IO32", "IO33", "IO25", "IO26",
"IO27", "IO14", "IO12", "GND", "IO13", "D2", "D3", "CMD", "5V");
assertSilk(devKit, 19, "GND", "IO23", "IO22", "TX", "RX", "IO21", "GND", "IO19", "IO18", "IO5",
"IO17", "IO16", "IO4", "IO0", "IO2", "IO15", "D1", "D0", "CLK");
// Right row (J3: 19..37, top to bottom)
Assert.assertEquals("GND_2", devKit.getControlPointNodeName(19));
Assert.assertEquals("23", devKit.getControlPointNodeName(20));
Assert.assertEquals("22", devKit.getControlPointNodeName(21));
Assert.assertEquals("TX", devKit.getControlPointNodeName(22));
Assert.assertEquals("RX", devKit.getControlPointNodeName(23));
Assert.assertEquals("21", devKit.getControlPointNodeName(24));
Assert.assertEquals("GND_3", devKit.getControlPointNodeName(25));
Assert.assertEquals("19", devKit.getControlPointNodeName(26));
Assert.assertEquals("18", devKit.getControlPointNodeName(27));
Assert.assertEquals("5", devKit.getControlPointNodeName(28));
Assert.assertEquals("17", devKit.getControlPointNodeName(29));
Assert.assertEquals("16", devKit.getControlPointNodeName(30));
Assert.assertEquals("4", devKit.getControlPointNodeName(31));
Assert.assertEquals("0", devKit.getControlPointNodeName(32));
Assert.assertEquals("2", devKit.getControlPointNodeName(33));
Assert.assertEquals("15", devKit.getControlPointNodeName(34));
Assert.assertEquals("D1", devKit.getControlPointNodeName(35));
Assert.assertEquals("D0", devKit.getControlPointNodeName(36));
Assert.assertEquals("CLK", devKit.getControlPointNodeName(37));
assertNodeIds(devKit, 0, "3V3", "EN", "VP", "VN", "GPIO34", "GPIO35", "GPIO32", "GPIO33",
"GPIO25", "GPIO26", "GPIO27", "GPIO14", "GPIO12", "GND_1", "GPIO13", "D2", "D3", "CMD", "5V");
assertNodeIds(devKit, 19, "GND_2", "GPIO23", "GPIO22", "TX", "RX", "GPIO21", "GND_3", "GPIO19",
"GPIO18", "GPIO5", "GPIO17", "GPIO16", "GPIO4", "GPIO0", "GPIO2", "GPIO15", "D1", "D0", "CLK");
Assert.assertEquals("GPIO0 (ADC2_CH1, TOUCH_CH1, Boot)", devKit.getControlPointNodeName(32));
Assert.assertEquals("D0 (GPIO7, flash)", devKit.getControlPointNodeName(36));
}
@Test
@@ -218,53 +192,20 @@ public class ESP32DevKitTest {
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
}
// Left row (J1: 0..21, top to bottom)
Assert.assertEquals("3V3_1", devKit.getControlPointNodeName(0));
Assert.assertEquals("3V3_2", devKit.getControlPointNodeName(1));
Assert.assertEquals("RST", devKit.getControlPointNodeName(2));
Assert.assertEquals("4", devKit.getControlPointNodeName(3));
Assert.assertEquals("5", devKit.getControlPointNodeName(4));
Assert.assertEquals("6", devKit.getControlPointNodeName(5));
Assert.assertEquals("7", devKit.getControlPointNodeName(6));
Assert.assertEquals("15", devKit.getControlPointNodeName(7));
Assert.assertEquals("16", devKit.getControlPointNodeName(8));
Assert.assertEquals("17", devKit.getControlPointNodeName(9));
Assert.assertEquals("18", devKit.getControlPointNodeName(10));
Assert.assertEquals("8", devKit.getControlPointNodeName(11));
Assert.assertEquals("3", devKit.getControlPointNodeName(12));
Assert.assertEquals("46", devKit.getControlPointNodeName(13));
Assert.assertEquals("9", devKit.getControlPointNodeName(14));
Assert.assertEquals("10", devKit.getControlPointNodeName(15));
Assert.assertEquals("11", devKit.getControlPointNodeName(16));
Assert.assertEquals("12", devKit.getControlPointNodeName(17));
Assert.assertEquals("13", devKit.getControlPointNodeName(18));
Assert.assertEquals("14", devKit.getControlPointNodeName(19));
Assert.assertEquals("5V", devKit.getControlPointNodeName(20));
Assert.assertEquals("GND_1", devKit.getControlPointNodeName(21));
// Silkscreen (J1 then J3), matching the Espressif user guide's header tables
assertSilk(devKit, 0, "3V3", "3V3", "RST", "4", "5", "6", "7", "15", "16", "17", "18", "8", "3",
"46", "9", "10", "11", "12", "13", "14", "5V", "G");
assertSilk(devKit, 22, "G", "TX", "RX", "1", "2", "42", "41", "40", "39", "38", "37", "36", "35",
"0", "45", "48", "47", "21", "20", "19", "G", "G");
// Right row (J3: 22..43, top to bottom)
Assert.assertEquals("GND_2", devKit.getControlPointNodeName(22));
Assert.assertEquals("TX", devKit.getControlPointNodeName(23));
Assert.assertEquals("RX", devKit.getControlPointNodeName(24));
Assert.assertEquals("1", devKit.getControlPointNodeName(25));
Assert.assertEquals("2", devKit.getControlPointNodeName(26));
Assert.assertEquals("42", devKit.getControlPointNodeName(27));
Assert.assertEquals("41", devKit.getControlPointNodeName(28));
Assert.assertEquals("40", devKit.getControlPointNodeName(29));
Assert.assertEquals("39", devKit.getControlPointNodeName(30));
Assert.assertEquals("38", devKit.getControlPointNodeName(31));
Assert.assertEquals("37", devKit.getControlPointNodeName(32));
Assert.assertEquals("36", devKit.getControlPointNodeName(33));
Assert.assertEquals("35", devKit.getControlPointNodeName(34));
Assert.assertEquals("0", devKit.getControlPointNodeName(35));
Assert.assertEquals("45", devKit.getControlPointNodeName(36));
Assert.assertEquals("48", devKit.getControlPointNodeName(37));
Assert.assertEquals("47", devKit.getControlPointNodeName(38));
Assert.assertEquals("21", devKit.getControlPointNodeName(39));
Assert.assertEquals("20", devKit.getControlPointNodeName(40));
Assert.assertEquals("19", devKit.getControlPointNodeName(41));
Assert.assertEquals("GND_3", devKit.getControlPointNodeName(42));
Assert.assertEquals("GND_4", devKit.getControlPointNodeName(43));
assertNodeIds(devKit, 0, "3V3_1", "3V3_2", "RST", "GPIO4", "GPIO5", "GPIO6", "GPIO7", "GPIO15",
"GPIO16", "GPIO17", "GPIO18", "GPIO8", "GPIO3", "GPIO46", "GPIO9", "GPIO10", "GPIO11",
"GPIO12", "GPIO13", "GPIO14", "5V", "GND_1");
assertNodeIds(devKit, 22, "GND_2", "TX", "RX", "GPIO1", "GPIO2", "GPIO42", "GPIO41", "GPIO40",
"GPIO39", "GPIO38", "GPIO37", "GPIO36", "GPIO35", "GPIO0", "GPIO45", "GPIO48", "GPIO47",
"GPIO21", "GPIO20", "GPIO19", "GND_3", "GND_4");
Assert.assertEquals("GPIO20 (U1CTS, ADC2_CH9, USB_D+)", devKit.getControlPointNodeName(40));
}
@Test
@@ -321,13 +262,14 @@ public class ESP32DevKitTest {
devKit.setVersion(ESP32DevKit.DevKitVersion.DevKitC_V4_38Pin);
Assert.assertEquals(38, devKit.getControlPointCount());
Assert.assertEquals("5V", devKit.getControlPointNodeName(18));
Assert.assertEquals("CLK", devKit.getControlPointNodeName(37));
Assert.assertEquals("5V", devKit.getSilkPinLabel(18));
Assert.assertEquals("CLK", devKit.getSilkPinLabel(37));
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_S3_DevKitC_44Pin);
Assert.assertEquals(44, devKit.getControlPointCount());
Assert.assertEquals("3V3_1", devKit.getControlPointNodeName(0));
Assert.assertEquals("GND_4", devKit.getControlPointNodeName(43));
Assert.assertEquals("3V3", devKit.getSilkPinLabel(0));
devKit.setVersion(ESP32DevKit.DevKitVersion.ESP32_C3_DevKitM_1);
Assert.assertEquals(30, devKit.getControlPointCount());
@@ -339,6 +281,7 @@ public class ESP32DevKitTest {
Assert.assertEquals(30, devKit.getControlPointCount());
Assert.assertEquals("VIN", devKit.getControlPointNodeName(14));
Assert.assertEquals("3V3", devKit.getControlPointNodeName(29));
Assert.assertEquals("D13", devKit.getSilkPinLabel(12));
}
@Test
@@ -356,21 +299,17 @@ public class ESP32DevKitTest {
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
}
// J1, top to bottom
Assert.assertEquals("GND_1", devKit.getControlPointNodeName(0));
Assert.assertEquals("3V3_1", devKit.getControlPointNodeName(1));
Assert.assertEquals("RST", devKit.getControlPointNodeName(6));
Assert.assertEquals("GND_5", devKit.getControlPointNodeName(14));
// J3, top to bottom
Assert.assertEquals("GND_6", devKit.getControlPointNodeName(15));
Assert.assertEquals("TX", devKit.getControlPointNodeName(16));
Assert.assertEquals("RX", devKit.getControlPointNodeName(17));
Assert.assertEquals("IO19", devKit.getControlPointNodeName(28));
Assert.assertEquals("GND_10", devKit.getControlPointNodeName(29));
assertSilk(devKit, 0, "GND", "3V3", "3V3", "IO2", "IO3", "GND", "RST", "GND", "IO0", "IO1",
"IO10", "GND", "5V", "5V", "GND");
assertSilk(devKit, 15, "GND", "TX", "RX", "GND", "IO9", "IO8", "GND", "IO7", "IO6", "IO5",
"IO4", "GND", "IO18", "IO19", "GND");
// Duplicated power and ground pins collapse to one silkscreen label
Assert.assertEquals("GND", AbstractMakerBoard.getDisplayPinLabel(devKit.getControlPointNodeName(0)));
Assert.assertEquals("3V3", AbstractMakerBoard.getDisplayPinLabel(devKit.getControlPointNodeName(1)));
assertNodeIds(devKit, 0, "GND_1", "3V3_1", "3V3_2", "GPIO2", "GPIO3", "GND_2", "RST", "GND_3",
"GPIO0", "GPIO1", "GPIO10", "GND_4", "5V_1", "5V_2", "GND_5");
assertNodeIds(devKit, 15, "GND_6", "TX", "RX", "GND_7", "GPIO9", "GPIO8", "GND_8", "GPIO7",
"GPIO6", "GPIO5", "GPIO4", "GND_9", "GPIO18", "GPIO19", "GND_10");
Assert.assertEquals("GPIO8 (RGB LED)", devKit.getControlPointNodeName(20));
}
@Test
@@ -388,18 +327,17 @@ public class ESP32DevKitTest {
Assert.assertFalse("Pin " + i + " name should not be empty", name.trim().isEmpty());
}
// J1, top to bottom
Assert.assertEquals("3V3", devKit.getControlPointNodeName(0));
Assert.assertEquals("RST", devKit.getControlPointNodeName(1));
Assert.assertEquals("5V", devKit.getControlPointNodeName(13));
Assert.assertEquals("GND_1", devKit.getControlPointNodeName(14));
Assert.assertEquals("NC_1", devKit.getControlPointNodeName(15));
// J3, top to bottom
Assert.assertEquals("GND_2", devKit.getControlPointNodeName(16));
Assert.assertEquals("TX", devKit.getControlPointNodeName(17));
Assert.assertEquals("RX", devKit.getControlPointNodeName(18));
Assert.assertEquals("12", devKit.getControlPointNodeName(29));
Assert.assertEquals("NC_2", devKit.getControlPointNodeName(31));
assertSilk(devKit, 0, "3V3", "RST", "4", "5", "6", "7", "0", "1", "8", "10", "11", "2", "3",
"5V", "G", "NC");
assertSilk(devKit, 16, "G", "TX", "RX", "15", "23", "22", "21", "20", "19", "18", "9", "G",
"13", "12", "G", "NC");
assertNodeIds(devKit, 0, "3V3", "RST", "GPIO4", "GPIO5", "GPIO6", "GPIO7", "GPIO0", "GPIO1",
"GPIO8", "GPIO10", "GPIO11", "GPIO2", "GPIO3", "5V", "GND_1", "NC_1");
assertNodeIds(devKit, 16, "GND_2", "TX", "RX", "GPIO15", "GPIO23", "GPIO22", "GPIO21", "GPIO20",
"GPIO19", "GPIO18", "GPIO9", "GND_3", "GPIO13", "GPIO12", "GND_4", "NC_2");
Assert.assertEquals("GPIO13 (USB_D+)", devKit.getControlPointNodeName(28));
}
@Test
@@ -6,6 +6,7 @@ import java.awt.geom.Rectangle2D;
import org.diylc.core.measures.Size;
import org.diylc.core.measures.SizeUnit;
import org.diylc.netlist.Node;
import org.junit.Assert;
import org.junit.Test;
@@ -23,38 +24,47 @@ public class ESP8266NodeMCUTest {
}
// Left row (0..14)
Assert.assertEquals("A0", mcu.getControlPointNodeName(0));
Assert.assertEquals("RSV_1", mcu.getControlPointNodeName(1));
Assert.assertEquals("RSV_2", mcu.getControlPointNodeName(2));
Assert.assertEquals("SD3", mcu.getControlPointNodeName(3));
Assert.assertEquals("SD2", mcu.getControlPointNodeName(4));
Assert.assertEquals("SD1", mcu.getControlPointNodeName(5));
Assert.assertEquals("CMD", mcu.getControlPointNodeName(6));
Assert.assertEquals("SD0", mcu.getControlPointNodeName(7));
Assert.assertEquals("CLK", mcu.getControlPointNodeName(8));
Assert.assertEquals("GND_1", mcu.getControlPointNodeName(9));
Assert.assertEquals("3V3_1", mcu.getControlPointNodeName(10));
Assert.assertEquals("EN", mcu.getControlPointNodeName(11));
Assert.assertEquals("RST", mcu.getControlPointNodeName(12));
Assert.assertEquals("GND_2", mcu.getControlPointNodeName(13));
Assert.assertEquals("VIN", mcu.getControlPointNodeName(14));
Assert.assertEquals("A0", Node.sanitizeNodeName(mcu.getControlPointNodeName(0)));
Assert.assertEquals("RSV_1", Node.sanitizeNodeName(mcu.getControlPointNodeName(1)));
Assert.assertEquals("RSV_2", Node.sanitizeNodeName(mcu.getControlPointNodeName(2)));
Assert.assertEquals("SD3", Node.sanitizeNodeName(mcu.getControlPointNodeName(3)));
Assert.assertEquals("SD2", Node.sanitizeNodeName(mcu.getControlPointNodeName(4)));
Assert.assertEquals("SD1", Node.sanitizeNodeName(mcu.getControlPointNodeName(5)));
Assert.assertEquals("CMD", Node.sanitizeNodeName(mcu.getControlPointNodeName(6)));
Assert.assertEquals("SD0", Node.sanitizeNodeName(mcu.getControlPointNodeName(7)));
Assert.assertEquals("CLK", Node.sanitizeNodeName(mcu.getControlPointNodeName(8)));
Assert.assertEquals("GND_1", Node.sanitizeNodeName(mcu.getControlPointNodeName(9)));
Assert.assertEquals("3V3_1", Node.sanitizeNodeName(mcu.getControlPointNodeName(10)));
Assert.assertEquals("EN", Node.sanitizeNodeName(mcu.getControlPointNodeName(11)));
Assert.assertEquals("RST", Node.sanitizeNodeName(mcu.getControlPointNodeName(12)));
Assert.assertEquals("GND_2", Node.sanitizeNodeName(mcu.getControlPointNodeName(13)));
Assert.assertEquals("VIN", Node.sanitizeNodeName(mcu.getControlPointNodeName(14)));
// Right row (15..29)
Assert.assertEquals("D0", mcu.getControlPointNodeName(15));
Assert.assertEquals("D1", mcu.getControlPointNodeName(16));
Assert.assertEquals("D2", mcu.getControlPointNodeName(17));
Assert.assertEquals("D3", mcu.getControlPointNodeName(18));
Assert.assertEquals("D4", mcu.getControlPointNodeName(19));
Assert.assertEquals("3V3_2", mcu.getControlPointNodeName(20));
Assert.assertEquals("GND_3", mcu.getControlPointNodeName(21));
Assert.assertEquals("D5", mcu.getControlPointNodeName(22));
Assert.assertEquals("D6", mcu.getControlPointNodeName(23));
Assert.assertEquals("D7", mcu.getControlPointNodeName(24));
Assert.assertEquals("D8", mcu.getControlPointNodeName(25));
Assert.assertEquals("RX", mcu.getControlPointNodeName(26));
Assert.assertEquals("TX", mcu.getControlPointNodeName(27));
Assert.assertEquals("GND_4", mcu.getControlPointNodeName(28));
Assert.assertEquals("3V3_3", mcu.getControlPointNodeName(29));
Assert.assertEquals("D0", Node.sanitizeNodeName(mcu.getControlPointNodeName(15)));
Assert.assertEquals("D1", Node.sanitizeNodeName(mcu.getControlPointNodeName(16)));
Assert.assertEquals("D2", Node.sanitizeNodeName(mcu.getControlPointNodeName(17)));
Assert.assertEquals("D3", Node.sanitizeNodeName(mcu.getControlPointNodeName(18)));
Assert.assertEquals("D4", Node.sanitizeNodeName(mcu.getControlPointNodeName(19)));
Assert.assertEquals("3V3_2", Node.sanitizeNodeName(mcu.getControlPointNodeName(20)));
Assert.assertEquals("GND_3", Node.sanitizeNodeName(mcu.getControlPointNodeName(21)));
Assert.assertEquals("D5", Node.sanitizeNodeName(mcu.getControlPointNodeName(22)));
Assert.assertEquals("D6", Node.sanitizeNodeName(mcu.getControlPointNodeName(23)));
Assert.assertEquals("D7", Node.sanitizeNodeName(mcu.getControlPointNodeName(24)));
Assert.assertEquals("D8", Node.sanitizeNodeName(mcu.getControlPointNodeName(25)));
Assert.assertEquals("RX", Node.sanitizeNodeName(mcu.getControlPointNodeName(26)));
Assert.assertEquals("TX", Node.sanitizeNodeName(mcu.getControlPointNodeName(27)));
Assert.assertEquals("GND_4", Node.sanitizeNodeName(mcu.getControlPointNodeName(28)));
Assert.assertEquals("3V3_3", Node.sanitizeNodeName(mcu.getControlPointNodeName(29)));
// The silkscreen prints the bare board label; the node name carries the GPIO mapping, which on
// this board is the thing people most often get wrong
Assert.assertEquals("D1", mcu.getSilkPinLabel(16));
Assert.assertEquals("GND", mcu.getSilkPinLabel(9));
Assert.assertEquals("RSV", mcu.getSilkPinLabel(1));
Assert.assertEquals("D1 (GPIO5, SCL)", mcu.getControlPointNodeName(16));
Assert.assertEquals("D2 (GPIO4, SDA)", mcu.getControlPointNodeName(17));
Assert.assertEquals("D7 (GPIO13, HSPI MOSI)", mcu.getControlPointNodeName(24));
}
@Test