From 12f9143fe25a58dff3e07c1e8f964b6bac9ebb46 Mon Sep 17 00:00:00 2001 From: Frank Delporte Date: Thu, 4 Apr 2024 17:41:33 +0200 Subject: [PATCH 1/5] #340 merging pi4j-board-info into pi4j-core --- pi4j-core/pom.xml | 14 +- .../pi4j/boardinfo/definition/BoardModel.java | 361 ++++++++++++++++++ .../pi4j/boardinfo/definition/BoardType.java | 12 + .../com/pi4j/boardinfo/definition/Cpu.java | 25 ++ .../pi4j/boardinfo/definition/HeaderPins.java | 125 ++++++ .../boardinfo/definition/HeaderVersion.java | 40 ++ .../boardinfo/definition/InstructionSet.java | 22 ++ .../pi4j/boardinfo/definition/PiModel.java | 31 ++ .../boardinfo/definition/PinFunction.java | 30 ++ .../pi4j/boardinfo/definition/PinType.java | 31 ++ .../com/pi4j/boardinfo/definition/Soc.java | 27 ++ .../pi4j/boardinfo/model/DetectedBoard.java | 28 ++ .../com/pi4j/boardinfo/model/HeaderPin.java | 61 +++ .../com/pi4j/boardinfo/model/JavaInfo.java | 40 ++ .../pi4j/boardinfo/model/OperatingSystem.java | 33 ++ .../boardinfo/util/BoardModelDetection.java | 60 +++ .../com/pi4j/boardinfo/util/ExecUtil.java | 68 ++++ .../com/pi4j/runtime/impl/DefaultRuntime.java | 5 + pi4j-core/src/main/java/module-info.java | 4 + .../boardinfo/definition/BoardModelTest.java | 29 ++ .../com/pi4j/boardinfo/model/ModelTest.java | 20 + .../util/BoardModelDetectionTest.java | 28 ++ 22 files changed, 1093 insertions(+), 1 deletion(-) create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/model/JavaInfo.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/model/OperatingSystem.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java create mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java create mode 100644 pi4j-core/test/java/com/pi4j/boardinfo/definition/BoardModelTest.java create mode 100644 pi4j-core/test/java/com/pi4j/boardinfo/model/ModelTest.java create mode 100644 pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java diff --git a/pi4j-core/pom.xml b/pi4j-core/pom.xml index e695f29c..f9a240bc 100644 --- a/pi4j-core/pom.xml +++ b/pi4j-core/pom.xml @@ -7,6 +7,7 @@ Pi4J :: LIBRARY :: Java Library (CORE) Pi4J Java API & Runtime Library jar + com.pi4j pi4j-parent @@ -14,8 +15,19 @@ ../pom.xml - + + + 2.17.0 + + + + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java new file mode 100644 index 00000000..ceddc624 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java @@ -0,0 +1,361 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import static com.pi4j.boardinfo.definition.BoardType.*; + +/** + * Partially based on + * en.wikipedia.org/wiki/Raspberry_Pi + * oastic.com/posts/how-to-know-which-raspberry-do-you-have + * raspberrypi.com/documentation/computers/raspberry-pi.html#new-style-revision-codes-in-use + * raspberrypi-spy.co.uk/2012/09/checking-your-raspberry-pi-board-version/ + */ +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum BoardModel { + MODEL_1_A("Raspberry Pi 1 Model A", SINGLE_BOARD_COMPUTER, + new ArrayList<>(), + PiModel.MODEL_A, + HeaderVersion.TYPE_1, + LocalDate.of(2013, 2, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(700), + Collections.singletonList(256 * 1024)), + MODEL_1_A_PLUS("Raspberry Pi 1 Model A+", SINGLE_BOARD_COMPUTER, + Collections.singletonList("900021"), + PiModel.MODEL_A, + HeaderVersion.TYPE_1, + LocalDate.of(2014, 11, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(700), + Arrays.asList(256 * 1024, 512 * 1024), + Collections.singletonList("Amount of memory changed to 512Mb on 20160810")), + MODEL_3_A_PLUS("Raspberry Pi 3 Model A+", SINGLE_BOARD_COMPUTER, + Collections.singletonList("9020e0"), + PiModel.MODEL_A, + HeaderVersion.TYPE_3, + LocalDate.of(2018, 11, 1), + Soc.BCM2837B0, + Cpu.CORTEX_A53, 4, + Collections.singletonList(1400), + Collections.singletonList(512 * 1024)), + MODEL_1_B("Raspberry Pi 1 Model B", SINGLE_BOARD_COMPUTER, + new ArrayList<>(), + PiModel.MODEL_B, + HeaderVersion.TYPE_1, + LocalDate.of(2012, 4, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(700), + Arrays.asList(256 * 1024, 512 * 1024), + Collections.singletonList("Amount of memory changed to 512Mb on 20121015")), + MODEL_1_B_PLUS("Raspberry Pi 1 Model B+", SINGLE_BOARD_COMPUTER, + Collections.singletonList("900032"), + PiModel.MODEL_B, + HeaderVersion.TYPE_1, + LocalDate.of(2014, 7, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(700), + Collections.singletonList(512 * 1024)), + MODEL_2_B("Raspberry Pi 2 Model B", SINGLE_BOARD_COMPUTER, + Arrays.asList("a01040", "a01041", "a21041"), + PiModel.MODEL_B, + HeaderVersion.TYPE_2, + LocalDate.of(2015, 2, 1), + Soc.BCM2836, + Cpu.CORTEX_A7, 4, + Collections.singletonList(900), + Collections.singletonList(1024 * 1024)), + MODEL_2_B_V1_2("Raspberry Pi 2 Model B V1.2", SINGLE_BOARD_COMPUTER, + Arrays.asList("a02042", "a22042"), + PiModel.MODEL_B, + HeaderVersion.TYPE_2, + LocalDate.of(2016, 10, 1), + Soc.BCM2837, + Cpu.CORTEX_A53, 4, + Collections.singletonList(900), + Collections.singletonList(1024 * 1024)), + MODEL_3_B("Raspberry Pi 3 Model B", SINGLE_BOARD_COMPUTER, + Arrays.asList("a02082", "a22082", "a32082", "a52082", "a22083"), + PiModel.MODEL_B, + HeaderVersion.TYPE_3, + LocalDate.of(2016, 2, 1), + Soc.BCM2837, + Cpu.CORTEX_A53, 4, + Collections.singletonList(1200), + Collections.singletonList(1024 * 1024)), + MODEL_3_B_PLUS("Raspberry Pi 3 Model B+", SINGLE_BOARD_COMPUTER, + Collections.singletonList("a020d3"), + PiModel.MODEL_B, + HeaderVersion.TYPE_3, + LocalDate.of(2018, 3, 14), + Soc.BCM2837B0, + Cpu.CORTEX_A53, 4, + Collections.singletonList(1400), + Collections.singletonList(1024 * 1024)), + MODEL_4_B("Raspberry Pi 4 Model B", SINGLE_BOARD_COMPUTER, + Arrays.asList("a03111", "b03111", "b03112", "b03114", "b03115", "c03111", "c03112", "c03114", "c03115", "d03114", "d03115"), + PiModel.MODEL_B, + HeaderVersion.TYPE_3, + LocalDate.of(2019, 6, 24), + Soc.BCM2711, + Cpu.CORTEX_A72, 4, + Arrays.asList(1500, 1800), + Arrays.asList(1024 * 1024, 2048 * 1024, 4096 * 1024, 8192 * 1024)), + MODEL_400("Raspberry Pi 400", ALL_IN_ONE_COMPUTER, + Collections.singletonList("c03130"), + PiModel.MODEL_B, + HeaderVersion.TYPE_3, + LocalDate.of(2020, 11, 2), + Soc.BCM2711C0, + Cpu.CORTEX_A72, 4, + Collections.singletonList(1800), + Collections.singletonList(4096 * 1024)), + MODEL_5_B("Raspberry Pi 5 Model B", SINGLE_BOARD_COMPUTER, + Arrays.asList("c04170", "d04170"), + PiModel.MODEL_B, + HeaderVersion.TYPE_3, + LocalDate.of(2023, 9, 28), + Soc.BCM2712, + Cpu.CORTEX_A76, 4, + Collections.singletonList(2400), + Arrays.asList(4096 * 1024, 8192 * 1024)), + COMPUTE_1("Compute Module 1", STACK_ON_COMPUTER, + Collections.singletonList("900061"), + PiModel.COMPUTE, + HeaderVersion.COMPUTE, + LocalDate.of(2014, 4, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(700), + Collections.singletonList(512 * 1024)), + COMPUTE_3("Compute Module 3", STACK_ON_COMPUTER, + Arrays.asList("a020a0", "a220a0"), + PiModel.COMPUTE, + HeaderVersion.COMPUTE, + LocalDate.of(2017, 1, 1), + Soc.BCM2837, + Cpu.CORTEX_A53, 4, + Collections.singletonList(1200), + Collections.singletonList(1024 * 1024)), + COMPUTE_3_PLUS("Compute Module 3+", STACK_ON_COMPUTER, + Collections.singletonList("a02100"), + PiModel.COMPUTE, + HeaderVersion.COMPUTE, + LocalDate.of(2019, 1, 1), + Soc.BCM2837B0, + Cpu.CORTEX_A53, 4, + Collections.singletonList(1200), + Collections.singletonList(1024 * 1024)), + COMPUTE_4("Compute Module 4", STACK_ON_COMPUTER, + Arrays.asList("a03140", "b03140", "c03140", "d03140"), + PiModel.COMPUTE, + HeaderVersion.COMPUTE, + LocalDate.of(2020, 10, 1), + Soc.BCM2711, + Cpu.CORTEX_A72, 4, + Collections.singletonList(1500), + Arrays.asList(1024 * 1024, 2048 * 1024, 4096 * 1024, 8192 * 1024)), + ZERO_PCB_1_2("Raspberry Pi Zero PCB V1.2", SINGLE_BOARD_COMPUTER, + Arrays.asList("900092", "920092"), + PiModel.ZERO, + HeaderVersion.TYPE_2, + LocalDate.of(2015, 11, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(1000), + Collections.singletonList(512 * 1024)), + ZERO_PCB_1_3("Raspberry Pi Zero PCB V1.3", SINGLE_BOARD_COMPUTER, + Arrays.asList("900093", "920093"), + PiModel.ZERO, + HeaderVersion.TYPE_3, + LocalDate.of(2016, 5, 1), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(1000), + Collections.singletonList(512 * 1024)), + ZERO_W("Raspberry Pi Zero W", SINGLE_BOARD_COMPUTER, + Collections.singletonList("9000c1"), + PiModel.ZERO, + HeaderVersion.TYPE_3, + LocalDate.of(2017, 2, 28), + Soc.BCM2835, + Cpu.ARM1176JZF_S, 1, + Collections.singletonList(1000), + Collections.singletonList(512 * 1024)), + ZERO_V2("Raspberry Pi Zero V2", SINGLE_BOARD_COMPUTER, + Collections.singletonList("902120"), + PiModel.ZERO, + HeaderVersion.TYPE_3, + LocalDate.of(2021, 10, 28), + Soc.BCM2710A1, + Cpu.CORTEX_A53, 4, + Collections.singletonList(1000), + Collections.singletonList(512 * 1024)), + PICO("Raspberry Pi Pico", MICROCONTROLLER, + new ArrayList<>(), + PiModel.PICO, + HeaderVersion.PICO, + LocalDate.of(2021, 1, 1), + Soc.RP2040, + Cpu.CORTEX_MO_PLUS, 1, + Collections.singletonList(1000), + Collections.singletonList(264 + 2048)), + PICO_W("Raspberry Pi Pico W", MICROCONTROLLER, + new ArrayList<>(), + PiModel.PICO, + HeaderVersion.PICO, + LocalDate.of(2022, 6, 1), + Soc.RP2040, + Cpu.CORTEX_MO_PLUS, 1, + Collections.singletonList(1000), + Collections.singletonList(264 + 2048), + Collections.singletonList("Same form factor as PICO but with Wi-Fi")), + UNKNOWN("Unknown", BoardType.UNKNOWN, + new ArrayList<>(), + PiModel.UNKNOWN, + HeaderVersion.UNKNOWN, + null, + Soc.UNKNOWN, + Cpu.UNKNOWN, 0, + new ArrayList<>(), + new ArrayList<>()); + + private static final Logger logger = LoggerFactory.getLogger(BoardModel.class); + + private final String label; + private final BoardType boardType; + private final List boardCodes; + private final PiModel model; + private final HeaderVersion headerVersion; + private final LocalDate releaseDate; + private final Soc soc; + private final Cpu cpu; + private final Integer numberOfCpu; + private final List versionsProcessorSpeedInMhz; + private final List versionsMemoryInKb; + private final List remarks; + + BoardModel(String label, BoardType boardType, List boardCodes, + PiModel model, HeaderVersion headerVersion, LocalDate releaseDate, + Soc soc, Cpu cpu, Integer numberOfCpu, + List versionsProcessorSpeedInMhz, List versionsMemoryInKb) { + this(label, boardType, boardCodes, model, headerVersion, releaseDate, soc, cpu, numberOfCpu, versionsProcessorSpeedInMhz, + versionsMemoryInKb, new ArrayList<>()); + } + + BoardModel(String label, BoardType boardType, List boardCodes, + PiModel model, HeaderVersion headerVersion, LocalDate releaseDate, + Soc soc, Cpu cpu, Integer numberOfCpu, + List versionsProcessorSpeedInMhz, List versionsMemoryInKb, + List remarks) { + this.label = label; + this.boardType = boardType; + this.boardCodes = boardCodes; + this.model = model; + this.headerVersion = headerVersion; + this.releaseDate = releaseDate; + this.soc = soc; + this.cpu = cpu; + this.numberOfCpu = numberOfCpu; + this.versionsProcessorSpeedInMhz = versionsProcessorSpeedInMhz; + this.versionsMemoryInKb = versionsMemoryInKb; + this.remarks = remarks; + } + + public static BoardModel getByBoardCode(String boardCode) { + var matches = Arrays.stream(BoardModel.values()) + .filter(bm -> bm.boardCodes.contains(boardCode)) + .collect(Collectors.toList()); + if (matches.isEmpty()) { + return BoardModel.UNKNOWN; + } else if (matches.size() > 1) { + logger.error("Too many matching models found for code {}, probably an error in the definitions", boardCode); + } + return matches.get(0); + } + + public static BoardModel getByBoardName(String boardName) { + var matches = Arrays.stream(BoardModel.values()) + .filter(bm -> boardName.toLowerCase().startsWith(bm.label.toLowerCase())) + .collect(Collectors.toList()); + if (matches.isEmpty()) { + return BoardModel.UNKNOWN; + } else if (matches.size() > 1) { + logger.error("Too many matching models found for name {}, the given name is not exclusive enough", boardName); + } + return matches.get(0); + } + + public String getName() { + return name(); + } + + public String getLabel() { + return label; + } + + public BoardType getBoardType() { + return boardType; + } + + public List getBoardCodes() { + return boardCodes; + } + + public PiModel getModel() { + return model; + } + + public HeaderVersion getHeaderVersion() { + return headerVersion; + } + + public LocalDate getReleaseDate() { + return releaseDate; + } + + public Soc getSoc() { + return soc; + } + + public Cpu getCpu() { + return cpu; + } + + public Integer getNumberOfCpu() { + return numberOfCpu; + } + + public List getVersionsProcessorSpeedInMhz() { + return versionsProcessorSpeedInMhz; + } + + public List getVersionsMemoryInKb() { + return versionsMemoryInKb; + } + + public List getVersionsMemoryInMb() { + return versionsMemoryInKb.stream().map(m -> m / 1024F).collect(Collectors.toList()); + } + + public List getVersionsMemoryInGb() { + return versionsMemoryInKb.stream().map(m -> m / 1024F / 1024F).collect(Collectors.toList()); + } + + public List getRemarks() { + return remarks; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java new file mode 100644 index 00000000..0cc9cc41 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java @@ -0,0 +1,12 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum BoardType { + ALL_IN_ONE_COMPUTER, + MICROCONTROLLER, + SINGLE_BOARD_COMPUTER, + STACK_ON_COMPUTER, + UNKNOWN +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java new file mode 100644 index 00000000..be67b144 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java @@ -0,0 +1,25 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum Cpu { + ARM1176JZF_S("ARM1176JZF-S"), + CORTEX_A53("Cortex-A53"), + CORTEX_A7("Cortex-A7"), + CORTEX_A72("Cortex-A72"), + CORTEX_A76("Cortex-A76"), + CORTEX_MO_PLUS("Cortex-M0+"), + UNKNOWN("Unknown"), + ; + + private final String label; + + Cpu(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java new file mode 100644 index 00000000..bb05b973 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java @@ -0,0 +1,125 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.pi4j.boardinfo.model.HeaderPin; + +import java.util.ArrayList; +import java.util.List; + +/** + * List of pins in a Raspberry Pi header. + */ +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum HeaderPins { + HEADER_8("8pin header", get8PinsHeader()), + HEADER_26_TYPE_1("26pin header - type 1", get26PinsHeader(1)), + HEADER_26_TYPE_2("26pin header - type 2", get26PinsHeader(2)), + HEADER_40("40pin header", get40PinsHeader()), + COMPUTE_J5("Compute J5", getComputeJ5()), + COMPUTE_J6("Compute J6", getComputeJ6()); + + private final String label; + private List pins; + + HeaderPins(String label, List pins) { + this.label = label; + this.pins = pins; + } + + public String getLabel() { + return label; + } + + public List getPins() { + return pins; + } + + static List get8PinsHeader() { + List header = new ArrayList<>(); + + header.add(new HeaderPin(1, PinType.POWER, "5.0 VDC")); + header.add(new HeaderPin(2, PinType.POWER, "3.3 VDC")); + header.add(new HeaderPin(3, PinType.DIGITAL, null, 28, 17, "")); + header.add(new HeaderPin(4, PinType.DIGITAL, null, 29, 18, "")); + header.add(new HeaderPin(5, PinType.DIGITAL, null, 30, 19, "")); + header.add(new HeaderPin(6, PinType.DIGITAL, null, 31, 20, "")); + header.add(new HeaderPin(7, PinType.GROUND, "Ground")); + header.add(new HeaderPin(8, PinType.GROUND, "Ground")); + + return header; + } + + static List get26PinsHeader(int type) { + List header = new ArrayList<>(); + + header.add(new HeaderPin(1, PinType.POWER, "3.3 VDC")); + header.add(new HeaderPin(2, PinType.POWER, "5.0 VDC")); + header.add(new HeaderPin(3, PinType.DIGITAL_NO_PULL_DOWN, PinFunction.I2C, (type == 1 ? 0 : 2), 8, "SDA1 (I2C)", "SDA.1 pin has a physical pull-up resistor")); + header.add(new HeaderPin(4, PinType.POWER, "5.0 VDC")); + header.add(new HeaderPin(5, PinType.DIGITAL_NO_PULL_DOWN, PinFunction.I2C, (type == 1 ? 1 : 3), 9, "SCL1 (I2C)", "SCL.1 pin has a physical pull-up resistor")); + header.add(new HeaderPin(6, PinType.GROUND, "Ground")); + header.add(new HeaderPin(7, PinType.DIGITAL, PinFunction.GPCLK, 4, 7, "GPCLK0")); + header.add(new HeaderPin(8, PinType.DIGITAL, PinFunction.UART, 14, 15, "UART TxD")); + header.add(new HeaderPin(9, PinType.GROUND, "Ground")); + header.add(new HeaderPin(10, PinType.DIGITAL, PinFunction.UART, 15, 16, "UART RxD")); + header.add(new HeaderPin(11, PinType.DIGITAL, PinFunction.SPI, 17, 0, "")); + header.add(new HeaderPin(12, PinType.DIGITAL_AND_PWM, PinFunction.SPI, 18, 1, "PCM_CLK/PWM0", "Supports PWM0 [ALT5]")); + header.add(new HeaderPin(13, PinType.DIGITAL, null, (type == 1 ? 21 : 27), 2, "")); + header.add(new HeaderPin(14, PinType.GROUND, "Ground")); + header.add(new HeaderPin(15, PinType.DIGITAL, null, 22, 3, "")); + header.add(new HeaderPin(16, PinType.DIGITAL, null, 23, 4, "")); + header.add(new HeaderPin(17, PinType.POWER, "3.3 VDC")); + header.add(new HeaderPin(18, PinType.DIGITAL, null, 24, 5, "")); + header.add(new HeaderPin(19, PinType.DIGITAL, PinFunction.SPI, 10, 12, "MOSI (SPI)")); + header.add(new HeaderPin(20, PinType.GROUND, "Ground")); + header.add(new HeaderPin(21, PinType.DIGITAL, PinFunction.SPI, 9, 13, "MISO (SPI)")); + header.add(new HeaderPin(22, PinType.DIGITAL, null, 25, 6, "")); + header.add(new HeaderPin(23, PinType.DIGITAL, PinFunction.SPI, 11, 14, "SCLK (SPI)")); + header.add(new HeaderPin(24, PinType.DIGITAL, PinFunction.SPI, 8, 10, "CE0 (SPI)")); + header.add(new HeaderPin(25, PinType.GROUND, "Ground")); + header.add(new HeaderPin(26, PinType.DIGITAL, PinFunction.SPI, 7, 11, "CE1 (SPI)")); + + return header; + } + + static List get40PinsHeader() { + List header = new ArrayList<>(); + + header.addAll(get26PinsHeader(2)); + + header.add(new HeaderPin(27, PinType.DIGITAL_NO_PULL_DOWN, PinFunction.I2C, 0, 30, "SDA0 I2C ID EEPROM", "SDA.0 pin has a physical pull-up resistor")); + header.add(new HeaderPin(28, PinType.DIGITAL_NO_PULL_DOWN, PinFunction.I2C, 1, 31, "SCL0 I2C ID EEPROM", "SDC.0 pin has a physical pull-up resistor")); + header.add(new HeaderPin(29, PinType.DIGITAL, PinFunction.GPCLK, 5, 21, "GPCLK1")); + header.add(new HeaderPin(30, PinType.GROUND, "Ground")); + header.add(new HeaderPin(31, PinType.DIGITAL, PinFunction.GPCLK, 6, 22, "GPCL2")); + header.add(new HeaderPin(32, PinType.DIGITAL_AND_PWM, null, 12, 26, "PWM0", "Supports PWM0 [ALT0]")); + header.add(new HeaderPin(33, PinType.DIGITAL_AND_PWM, null, 13, 23, "PWM1", "Supports PWM1 [ALT0]")); + header.add(new HeaderPin(34, PinType.GROUND, "Ground")); + header.add(new HeaderPin(35, PinType.DIGITAL_AND_PWM, PinFunction.SPI, 19,24, "PCM_FS/PWM1", "Supports PWM1 [ALT5]")); + header.add(new HeaderPin(36, PinType.DIGITAL, PinFunction.SPI, 16, 27, "")); + header.add(new HeaderPin(37, PinType.DIGITAL, null, 26, 25, "")); + header.add(new HeaderPin(38, PinType.DIGITAL, PinFunction.SPI, 20, 28, "PCM_DIN")); + header.add(new HeaderPin(39, PinType.GROUND, "Ground")); + header.add(new HeaderPin(40, PinType.DIGITAL, PinFunction.SPI, 21, 29, "PCM_DOUT")); + + return header; + } + + static List getComputeJ5() { + List header = new ArrayList<>(); + + // TODO + // https://pi4j.com/1.2/pins/model-cm-rev1.html#J5_Pinout_60-pin_Header + + return header; + } + + static List getComputeJ6() { + List header = new ArrayList<>(); + + // TODO + // https://pi4j.com/1.2/pins/model-cm-rev1.html#J6_Pinout_60-pin_Header + + return header; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java new file mode 100644 index 00000000..ce7af2af --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java @@ -0,0 +1,40 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum HeaderVersion { + PICO("Pico", "Used on the Pico microcontroller", new ArrayList<>()), + TYPE_1("Type 1", "Used on original Model B", Collections.singletonList(HeaderPins.HEADER_26_TYPE_1)), + TYPE_2("Type 2", "Used on Model A and Model B (revision 2)", Arrays.asList(HeaderPins.HEADER_26_TYPE_2, HeaderPins.HEADER_8)), + TYPE_3("Type 3", "Used on Model A+, B+, Pi Zero, Pi Zero W, Pi2B, Pi3B, Pi4B", Collections.singletonList(HeaderPins.HEADER_40)), + COMPUTE("Compute Module", "54 GPIO", Arrays.asList(HeaderPins.COMPUTE_J5, HeaderPins.COMPUTE_J6)), + UNKNOWN("Unknown", "", new ArrayList<>()); + + private final String label; + private final String description; + private final List headerPins; + + HeaderVersion(String label, String description, List headerPins) { + this.label = label; + this.description = description; + this.headerPins = headerPins; + } + + public String getLabel() { + return label; + } + + public String getDescription() { + return description; + } + + public List getHeaderPins() { + return headerPins; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java new file mode 100644 index 00000000..12adcfe3 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java @@ -0,0 +1,22 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum InstructionSet { + ARM_V6_M("ARMv6-M"), + ARM_V6("ARMv6"), + ARM_V7("ARMv7"), + ARM_V8("ARMv8"), + UNKNOWN("Unknown"); + + private final String label; + + InstructionSet(String label) { + this.label = label; + } + + public String getLabel() { + return label; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java new file mode 100644 index 00000000..f6b9a697 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java @@ -0,0 +1,31 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum PiModel { + COMPUTE("Compute Module", "Pi on a 200-pin DDR2-memory-like module for integration in embedded devices"), + MODEL_A("Model A", "Without ethernet connector"), + MODEL_B("Model B", "With ethernet connector"), + PICO("Pico", "Microcontroller"), + ZERO("Zero", "Smaller size and reduced GPIO capabilities"), + UNKNOWN("Unknown", ""); + + private final String label; + private final String description; + + PiModel(String label, String description) { + this.label = label; + this.description = description; + + } + + public String getLabel() { + return label; + } + + public String getDescription() { + return description; + } +} + diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java new file mode 100644 index 00000000..e419121d --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java @@ -0,0 +1,30 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * List of pin functions in a header. + */ +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum PinFunction { + UART("Universal Asynchronous Receiver and Transmitter", "Asynchronous serial communication protocol"), + GPCLK("General Purpose Clock", "Output a fixed frequency"), + I2C("Inter Integrated Circuit", "Synchronous serial computer bus"), + SPI("Serial Peripheral Interface", "Four-wire serial bus"); + + private final String label; + private final String description; + + PinFunction(String label, String description) { + this.label = label; + this.description = description; + } + + public String getLabel() { + return label; + } + + public String getDescription() { + return description; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java new file mode 100644 index 00000000..7a8c4669 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java @@ -0,0 +1,31 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +/** + * List of pin types in a header. + */ +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum PinType { + POWER("Power", 0x990000), + GROUND("Ground", 0x000000), + DIGITAL("Digital", 0x009900), + DIGITAL_AND_PWM("Digital and PWM", 0xff7ff00), + DIGITAL_NO_PULL_DOWN("Digital without pulldown", 0x800080); + + private final String label; + private final int color; + + PinType(String label, int color) { + this.label = label; + this.color = color; + } + + public String getLabel() { + return label; + } + + public int getColor() { + return color; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java new file mode 100644 index 00000000..14ae7d5c --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java @@ -0,0 +1,27 @@ +package com.pi4j.boardinfo.definition; + +import com.fasterxml.jackson.annotation.JsonFormat; + +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public enum Soc { + BCM2710A1(InstructionSet.ARM_V8), + BCM2711(InstructionSet.ARM_V8), + BCM2711C0(InstructionSet.ARM_V8), + BCM2712(InstructionSet.ARM_V8), + BCM2835(InstructionSet.ARM_V6), + BCM2836(InstructionSet.ARM_V7), + BCM2837(InstructionSet.ARM_V8), + BCM2837B0(InstructionSet.ARM_V8), + RP2040(InstructionSet.ARM_V6_M), + UNKNOWN(InstructionSet.UNKNOWN); + + private final InstructionSet instructionSet; + + Soc(InstructionSet instructionSet) { + this.instructionSet = instructionSet; + } + + public InstructionSet getInstructionSet() { + return instructionSet; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java new file mode 100644 index 00000000..1ca09732 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java @@ -0,0 +1,28 @@ +package com.pi4j.boardinfo.model; + +import com.pi4j.boardinfo.definition.BoardModel; + +public class DetectedBoard { + + private final BoardModel boardModel; + private final OperatingSystem operatingSystem; + private final JavaInfo javaInfo; + + public DetectedBoard(BoardModel boardModel, OperatingSystem operatingSystem, JavaInfo javaInfo) { + this.boardModel = boardModel; + this.operatingSystem = operatingSystem; + this.javaInfo = javaInfo; + } + + public BoardModel getBoardModel() { + return boardModel; + } + + public OperatingSystem getOperatingSystem() { + return operatingSystem; + } + + public JavaInfo getJavaInfo() { + return javaInfo; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java new file mode 100644 index 00000000..58f1f372 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java @@ -0,0 +1,61 @@ +package com.pi4j.boardinfo.model; + +import com.fasterxml.jackson.annotation.JsonFormat; +import com.pi4j.boardinfo.definition.PinFunction; +import com.pi4j.boardinfo.definition.PinType; + +/** + * Describes a pin in the header. + */ +@JsonFormat(shape = JsonFormat.Shape.OBJECT) +public class HeaderPin { + private final int pinNumber; + private final PinType pinType; + private final PinFunction pinFunction; + private final Integer bcmNumber; + private final Integer wiringPiNumber; + private final String name; + private final String remark; + + public HeaderPin(int pinNumber, PinType pinType, String name) { + this(pinNumber, pinType, null, null, null, name, ""); + } + + public HeaderPin(int pinNumber, PinType pinType, PinFunction pinFunction, Integer bcmNumber, Integer wiringPiNumber, String name) { + this(pinNumber, pinType, pinFunction, bcmNumber, wiringPiNumber, name, ""); + } + + public HeaderPin(int pinNumber, PinType pinType, PinFunction pinFunction, Integer bcmNumber, Integer wiringPiNumber, String name, String remark) { + this.pinNumber = pinNumber; + this.pinType = pinType; + this.pinFunction = pinFunction; + this.bcmNumber = bcmNumber; + this.wiringPiNumber = wiringPiNumber; + this.name = name; + this.remark = remark; + } + + public int getPinNumber() { + return pinNumber; + } + + public PinType getPinType() { + return pinType; + } + + public PinFunction getPinFunction() { return pinFunction; } + + public Integer getBcmNumber() { return bcmNumber; } + + public Integer getWiringPiNumber() { + return wiringPiNumber; + } + + public String getName() { + return name; + } + + public String getRemark() { + return remark; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/JavaInfo.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/JavaInfo.java new file mode 100644 index 00000000..b04a7e91 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/JavaInfo.java @@ -0,0 +1,40 @@ +package com.pi4j.boardinfo.model; + +public class JavaInfo { + + private final String version; + private final String runtime; + private final String vendor; + private final String vendorVersion; + + public JavaInfo(String version, String runtime, String vendor, String vendorVersion) { + this.version = version; + this.runtime = runtime; + this.vendor = vendor; + this.vendorVersion = vendorVersion; + } + + public String getVersion() { + return version; + } + + public String getRuntime() { + return runtime; + } + + public String getVendor() { + return vendor; + } + + public String getVendorVersion() { + return vendorVersion; + } + + @Override + public String toString() { + return "Version: " + version + + ", runtime: " + runtime + + ", vendor: " + vendor + + ", vendor version: " + vendorVersion; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/OperatingSystem.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/OperatingSystem.java new file mode 100644 index 00000000..1489168e --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/OperatingSystem.java @@ -0,0 +1,33 @@ +package com.pi4j.boardinfo.model; + +public class OperatingSystem { + + private final String name; + private final String version; + private final String architecture; + + public OperatingSystem(String name, String version, String architecture) { + this.name = name; + this.version = version; + this.architecture = architecture; + } + + public String getName() { + return name; + } + + public String getVersion() { + return version; + } + + public String getArchitecture() { + return architecture; + } + + @Override + public String toString() { + return "Name: " + name + + ", version: " + version + + ", architecture: " + architecture; + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java new file mode 100644 index 00000000..59a37d25 --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java @@ -0,0 +1,60 @@ +package com.pi4j.boardinfo.util; + +import com.pi4j.boardinfo.definition.BoardModel; +import com.pi4j.boardinfo.model.DetectedBoard; +import com.pi4j.boardinfo.model.JavaInfo; +import com.pi4j.boardinfo.model.OperatingSystem; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BoardModelDetection { + + private static final Logger logger = LoggerFactory.getLogger(BoardModelDetection.class); + + private BoardModelDetection() { + // Hide constructor + } + + public static DetectedBoard getDetectedBoard() { + var os = new OperatingSystem(System.getProperty("os.name"), + System.getProperty("os.version"), + System.getProperty("os.arch")); + logger.info("Detected OS: {}", os); + + var java = new JavaInfo(System.getProperty("java.version"), + System.getProperty("java.runtime.version"), + System.getProperty("java.vendor"), + System.getProperty("java.vendor.version")); + logger.info("Detected Java: {}", java); + + // Example output: c03111 + var boardVersionCode = getCommandOutput("cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}'"); + var boardModelByBoardCode = BoardModel.getByBoardCode(boardVersionCode); + if (boardModelByBoardCode != BoardModel.UNKNOWN) { + logger.info("Detected board type {} by code: {}", boardModelByBoardCode.name(), boardVersionCode); + return new DetectedBoard(boardModelByBoardCode, os, java); + } + + // Example output: Raspberry Pi 4 Model B Rev 1.1 + var boardName = getCommandOutput("cat /proc/device-tree/model"); + boardModelByBoardCode = BoardModel.getByBoardName(boardName); + if (boardModelByBoardCode != BoardModel.UNKNOWN) { + logger.info("Detected board type {} by name: {}", boardModelByBoardCode.name(), boardName); + return new DetectedBoard(boardModelByBoardCode, os, java); + } + + // Maybe there are other ways how a board can be detected? + // If so, this method can be further extended... + logger.warn("Sorry, could not detect the board type"); + return new DetectedBoard(BoardModel.UNKNOWN, os, java); + } + + private static String getCommandOutput(String command) { + ExecUtil execUtil = new ExecUtil(command); + if (!execUtil.isFinished() || !execUtil.getErrorMessage().isEmpty()) { + logger.error("Could not execute '{}' to detect the board model: {}", command, execUtil.getErrorMessage()); + return ""; + } + return execUtil.getOutputMessage(); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java new file mode 100644 index 00000000..ef66c77e --- /dev/null +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java @@ -0,0 +1,68 @@ +package com.pi4j.boardinfo.util; + +import java.io.*; +import java.util.concurrent.TimeUnit; + +public class ExecUtil { + + private boolean finished = false; + private String outputMessage = ""; + private String errorMessage = ""; + + public ExecUtil(String command) { + execute(command); + } + + public boolean isFinished() { + return finished; + } + + public String getOutputMessage() { + return outputMessage; + } + + public String getErrorMessage() { + return errorMessage; + } + + private void execute(String command) { + ProcessBuilder builder = new ProcessBuilder(); + builder.command("sh", "-c", command); + + try { + Process process = builder.start(); + + OutputStream outputStream = process.getOutputStream(); + InputStream inputStream = process.getInputStream(); + InputStream errorStream = process.getErrorStream(); + + outputMessage = readStream(inputStream); + errorMessage = readStream(errorStream); + + finished = process.waitFor(30, TimeUnit.SECONDS); + outputStream.flush(); + outputStream.close(); + + if (!finished) { + process.destroyForcibly(); + } + } catch (IOException ex) { + errorMessage = "IOException: " + ex.getMessage(); + } catch (InterruptedException ex) { + errorMessage = "InterruptedException: " + ex.getMessage(); + } + } + + private String readStream(InputStream inputStream) { + StringBuilder rt = new StringBuilder(); + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + rt.append(line); + } + } catch (Exception ex) { + rt.append("ERROR: ").append(ex.getMessage()); + } + return rt.toString(); + } +} diff --git a/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java b/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java index 1dffb9c0..664d72aa 100644 --- a/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java +++ b/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java @@ -25,6 +25,7 @@ * #L% */ +import com.pi4j.boardinfo.util.BoardModelDetection; import com.pi4j.context.Context; import com.pi4j.context.ContextConfig; import com.pi4j.event.*; @@ -248,6 +249,10 @@ public boolean isShutdown() { public Runtime initialize() throws InitializeException { logger.info("Initializing Pi4J context/runtime..."); try { + // Output the type of board + var model = BoardModelDetection.getDetectedBoard(); + logger.info("detected board model: {}", model.getBoardModel().getLabel()); + // clear plugins container plugins.clear(); diff --git a/pi4j-core/src/main/java/module-info.java b/pi4j-core/src/main/java/module-info.java index 738e308c..f5cc3ef1 100644 --- a/pi4j-core/src/main/java/module-info.java +++ b/pi4j-core/src/main/java/module-info.java @@ -26,10 +26,14 @@ // depends on SLF4J requires org.slf4j; + requires com.fasterxml.jackson.annotation; // exposed interfaces/classes exports com.pi4j; + exports com.pi4j.boardinfo.definition; + exports com.pi4j.boardinfo.model; + exports com.pi4j.boardinfo.util; exports com.pi4j.common; exports com.pi4j.config; exports com.pi4j.config.exception; diff --git a/pi4j-core/test/java/com/pi4j/boardinfo/definition/BoardModelTest.java b/pi4j-core/test/java/com/pi4j/boardinfo/definition/BoardModelTest.java new file mode 100644 index 00000000..9c99dcbf --- /dev/null +++ b/pi4j-core/test/java/com/pi4j/boardinfo/definition/BoardModelTest.java @@ -0,0 +1,29 @@ +package com.pi4j.boardinfo.definition; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BoardModelTest { + + @Test + void testGetBoardModelByBoardCode() { + assertAll( + () -> assertEquals(BoardModel.MODEL_5_B, BoardModel.getByBoardCode("d04170")), + () -> assertEquals(BoardModel.MODEL_400, BoardModel.getByBoardCode("c03130")), + () -> assertEquals(BoardModel.MODEL_4_B, BoardModel.getByBoardCode("a03111")), + () -> assertEquals(BoardModel.MODEL_4_B, BoardModel.getByBoardCode("c03112")), + () -> assertEquals(BoardModel.ZERO_V2, BoardModel.getByBoardCode("902120")), + () -> assertEquals(BoardModel.MODEL_2_B_V1_2, BoardModel.getByBoardCode("a02042")), + () -> assertEquals(BoardModel.MODEL_2_B, BoardModel.getByBoardCode("a21041")) + ); + } + + @Test + void testGetBoardModelByBoardName() { + assertAll( + () -> assertEquals(BoardModel.MODEL_4_B, BoardModel.getByBoardName("Raspberry Pi 4 Model B Rev 1.1")) + ); + } +} diff --git a/pi4j-core/test/java/com/pi4j/boardinfo/model/ModelTest.java b/pi4j-core/test/java/com/pi4j/boardinfo/model/ModelTest.java new file mode 100644 index 00000000..1e6e53f9 --- /dev/null +++ b/pi4j-core/test/java/com/pi4j/boardinfo/model/ModelTest.java @@ -0,0 +1,20 @@ +package com.pi4j.boardinfo.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class ModelTest { + + @Test + void testStringOutputFromOperatingSystem() { + var os = new OperatingSystem("aaa", "bbb", "ccc"); + assertEquals("Name: aaa, version: bbb, architecture: ccc", os.toString()); + } + + @Test + void testStringOutputFromJavaInfo() { + var java = new JavaInfo("aaa", "bbb", "ccc", "ddd"); + assertEquals("Version: aaa, runtime: bbb, vendor: ccc, vendor version: ddd", java.toString()); + } +} diff --git a/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java b/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java new file mode 100644 index 00000000..4882416e --- /dev/null +++ b/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java @@ -0,0 +1,28 @@ +package com.pi4j.boardinfo.util; + +import com.pi4j.boardinfo.definition.PiModel; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertAll; +import static org.junit.jupiter.api.Assertions.assertEquals; + +class BoardModelDetectionTest { + + @Test + void testGetDetectedBoard() { + var detectedBoard = BoardModelDetection.getDetectedBoard(); + + assertAll( + () -> assertEquals(detectedBoard.getOperatingSystem().getName(), System.getProperty("os.name")), + () -> assertEquals(detectedBoard.getOperatingSystem().getVersion(), System.getProperty("os.version")), + () -> assertEquals(detectedBoard.getOperatingSystem().getArchitecture(), System.getProperty("os.arch")), + + () -> assertEquals(detectedBoard.getJavaInfo().getVersion(), System.getProperty("java.version")), + () -> assertEquals(detectedBoard.getJavaInfo().getRuntime(), System.getProperty("java.runtime.version")), + () -> assertEquals(detectedBoard.getJavaInfo().getVendor(), System.getProperty("java.vendor")), + () -> assertEquals(detectedBoard.getJavaInfo().getVendorVersion(), System.getProperty("java.vendor.version")), + + () -> assertEquals(detectedBoard.getBoardModel().getModel(), PiModel.UNKNOWN) // Only valid on PC, macOS or build server + ); + } +} From 264a5a99ead590faff558dafd94b0a87738931b9 Mon Sep 17 00:00:00 2001 From: Frank Delporte Date: Thu, 4 Apr 2024 17:45:21 +0200 Subject: [PATCH 2/5] #340 merging pi4j-board-info into pi4j-core --- pi4j-core/src/main/java/module-info.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pi4j-core/src/main/java/module-info.java b/pi4j-core/src/main/java/module-info.java index f5cc3ef1..f8425262 100644 --- a/pi4j-core/src/main/java/module-info.java +++ b/pi4j-core/src/main/java/module-info.java @@ -26,8 +26,9 @@ // depends on SLF4J requires org.slf4j; - requires com.fasterxml.jackson.annotation; + // board info uses Jackson to be able to output as JSON + requires com.fasterxml.jackson.annotation; // exposed interfaces/classes exports com.pi4j; From 42d9649977f519855255281b88b0347cbb34d14c Mon Sep 17 00:00:00 2001 From: Frank Delporte Date: Fri, 5 Apr 2024 12:00:50 +0200 Subject: [PATCH 3/5] #340 Moving command execution into private method (safer) --- .../{DetectedBoard.java => BoardInfo.java} | 4 +- .../boardinfo/util/BoardModelDetection.java | 114 ++++++++++++++++-- .../com/pi4j/boardinfo/util/ExecUtil.java | 68 ----------- 3 files changed, 103 insertions(+), 83 deletions(-) rename pi4j-core/src/main/java/com/pi4j/boardinfo/model/{DetectedBoard.java => BoardInfo.java} (81%) delete mode 100644 pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/BoardInfo.java similarity index 81% rename from pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java rename to pi4j-core/src/main/java/com/pi4j/boardinfo/model/BoardInfo.java index 1ca09732..2ec8e2dc 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/DetectedBoard.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/BoardInfo.java @@ -2,13 +2,13 @@ import com.pi4j.boardinfo.definition.BoardModel; -public class DetectedBoard { +public class BoardInfo { private final BoardModel boardModel; private final OperatingSystem operatingSystem; private final JavaInfo javaInfo; - public DetectedBoard(BoardModel boardModel, OperatingSystem operatingSystem, JavaInfo javaInfo) { + public BoardInfo(BoardModel boardModel, OperatingSystem operatingSystem, JavaInfo javaInfo) { this.boardModel = boardModel; this.operatingSystem = operatingSystem; this.javaInfo = javaInfo; diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java index 59a37d25..f249d7c5 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/BoardModelDetection.java @@ -1,12 +1,15 @@ package com.pi4j.boardinfo.util; import com.pi4j.boardinfo.definition.BoardModel; -import com.pi4j.boardinfo.model.DetectedBoard; +import com.pi4j.boardinfo.model.BoardInfo; import com.pi4j.boardinfo.model.JavaInfo; import com.pi4j.boardinfo.model.OperatingSystem; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.*; +import java.util.concurrent.TimeUnit; + public class BoardModelDetection { private static final Logger logger = LoggerFactory.getLogger(BoardModelDetection.class); @@ -15,7 +18,7 @@ private BoardModelDetection() { // Hide constructor } - public static DetectedBoard getDetectedBoard() { + public static BoardInfo current() { var os = new OperatingSystem(System.getProperty("os.name"), System.getProperty("os.version"), System.getProperty("os.arch")); @@ -28,33 +31,118 @@ public static DetectedBoard getDetectedBoard() { logger.info("Detected Java: {}", java); // Example output: c03111 - var boardVersionCode = getCommandOutput("cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}'"); + var boardVersionCode = getBoardVersionCode(); var boardModelByBoardCode = BoardModel.getByBoardCode(boardVersionCode); if (boardModelByBoardCode != BoardModel.UNKNOWN) { logger.info("Detected board type {} by code: {}", boardModelByBoardCode.name(), boardVersionCode); - return new DetectedBoard(boardModelByBoardCode, os, java); + return new BoardInfo(boardModelByBoardCode, os, java); } // Example output: Raspberry Pi 4 Model B Rev 1.1 - var boardName = getCommandOutput("cat /proc/device-tree/model"); + var boardName = getBoardName(); boardModelByBoardCode = BoardModel.getByBoardName(boardName); if (boardModelByBoardCode != BoardModel.UNKNOWN) { logger.info("Detected board type {} by name: {}", boardModelByBoardCode.name(), boardName); - return new DetectedBoard(boardModelByBoardCode, os, java); + return new BoardInfo(boardModelByBoardCode, os, java); } // Maybe there are other ways how a board can be detected? // If so, this method can be further extended... logger.warn("Sorry, could not detect the board type"); - return new DetectedBoard(BoardModel.UNKNOWN, os, java); + return new BoardInfo(BoardModel.UNKNOWN, os, java); + } + + public static String getBoardVersionCode() { + var output = getCommandOutput("cat /proc/cpuinfo | grep 'Revision' | awk '{print $3}'"); + if (output.isSuccess()) { + return output.getOutputMessage(); + } + logger.error("Could not get the board version code: {}", output.getErrorMessage()); + return ""; + } + + public static String getBoardName() { + var output = getCommandOutput("cat /proc/device-tree/model"); + if (output.isSuccess()) { + return output.getOutputMessage(); + } + logger.error("Could not get the board name: {}", output.getErrorMessage()); + return ""; + } + + private static class CommandResult { + private final boolean success; + private final String outputMessage; + private final String errorMessage; + + public CommandResult(boolean success, String outputMessage, String errorMessage) { + this.success = success; + this.outputMessage = outputMessage; + this.errorMessage = errorMessage; + } + + public boolean isSuccess() { + return success; + } + + public String getOutputMessage() { + return outputMessage; + } + + public String getErrorMessage() { + return errorMessage; + } + } + + private static CommandResult getCommandOutput(String command) { + boolean finished = false; + String outputMessage = ""; + String errorMessage = ""; + + ProcessBuilder builder = new ProcessBuilder(); + builder.command("sh", "-c", command); + + try { + Process process = builder.start(); + + OutputStream outputStream = process.getOutputStream(); + InputStream inputStream = process.getInputStream(); + InputStream errorStream = process.getErrorStream(); + + outputMessage = readStream(inputStream); + errorMessage = readStream(errorStream); + + finished = process.waitFor(30, TimeUnit.SECONDS); + outputStream.flush(); + outputStream.close(); + + if (!finished) { + process.destroyForcibly(); + } + } catch (IOException ex) { + errorMessage = "IOException: " + ex.getMessage(); + } catch (InterruptedException ex) { + errorMessage = "InterruptedException: " + ex.getMessage(); + } + + if (!finished || !errorMessage.isEmpty()) { + logger.error("Could not execute '{}' to detect the board model: {}", command, errorMessage); + return new CommandResult(false, outputMessage, errorMessage); + } + + return new CommandResult(true, outputMessage, errorMessage); } - private static String getCommandOutput(String command) { - ExecUtil execUtil = new ExecUtil(command); - if (!execUtil.isFinished() || !execUtil.getErrorMessage().isEmpty()) { - logger.error("Could not execute '{}' to detect the board model: {}", command, execUtil.getErrorMessage()); - return ""; + private static String readStream(InputStream inputStream) { + StringBuilder rt = new StringBuilder(); + try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { + String line; + while ((line = bufferedReader.readLine()) != null) { + rt.append(line); + } + } catch (Exception ex) { + rt.append("ERROR: ").append(ex.getMessage()); } - return execUtil.getOutputMessage(); + return rt.toString(); } } diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java deleted file mode 100644 index ef66c77e..00000000 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/util/ExecUtil.java +++ /dev/null @@ -1,68 +0,0 @@ -package com.pi4j.boardinfo.util; - -import java.io.*; -import java.util.concurrent.TimeUnit; - -public class ExecUtil { - - private boolean finished = false; - private String outputMessage = ""; - private String errorMessage = ""; - - public ExecUtil(String command) { - execute(command); - } - - public boolean isFinished() { - return finished; - } - - public String getOutputMessage() { - return outputMessage; - } - - public String getErrorMessage() { - return errorMessage; - } - - private void execute(String command) { - ProcessBuilder builder = new ProcessBuilder(); - builder.command("sh", "-c", command); - - try { - Process process = builder.start(); - - OutputStream outputStream = process.getOutputStream(); - InputStream inputStream = process.getInputStream(); - InputStream errorStream = process.getErrorStream(); - - outputMessage = readStream(inputStream); - errorMessage = readStream(errorStream); - - finished = process.waitFor(30, TimeUnit.SECONDS); - outputStream.flush(); - outputStream.close(); - - if (!finished) { - process.destroyForcibly(); - } - } catch (IOException ex) { - errorMessage = "IOException: " + ex.getMessage(); - } catch (InterruptedException ex) { - errorMessage = "InterruptedException: " + ex.getMessage(); - } - } - - private String readStream(InputStream inputStream) { - StringBuilder rt = new StringBuilder(); - try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream))) { - String line; - while ((line = bufferedReader.readLine()) != null) { - rt.append(line); - } - } catch (Exception ex) { - rt.append("ERROR: ").append(ex.getMessage()); - } - return rt.toString(); - } -} From 6ce99ab5f52d8f4911b4c450d328ffd596f40f47 Mon Sep 17 00:00:00 2001 From: Frank Delporte Date: Fri, 5 Apr 2024 12:01:08 +0200 Subject: [PATCH 4/5] #340 Added BoardInfo to Context --- .../src/main/java/com/pi4j/context/Context.java | 16 ++++++++++++++++ .../com/pi4j/context/impl/DefaultContext.java | 15 ++++++++++++++- .../com/pi4j/runtime/impl/DefaultRuntime.java | 5 ----- .../boardinfo/util/BoardModelDetectionTest.java | 2 +- 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/pi4j-core/src/main/java/com/pi4j/context/Context.java b/pi4j-core/src/main/java/com/pi4j/context/Context.java index c5078779..7ee9b77a 100644 --- a/pi4j-core/src/main/java/com/pi4j/context/Context.java +++ b/pi4j-core/src/main/java/com/pi4j/context/Context.java @@ -25,6 +25,10 @@ * #L% */ +import com.pi4j.boardinfo.definition.BoardModel; +import com.pi4j.boardinfo.model.BoardInfo; +import com.pi4j.boardinfo.model.JavaInfo; +import com.pi4j.boardinfo.model.OperatingSystem; import com.pi4j.common.Describable; import com.pi4j.common.Descriptor; import com.pi4j.config.Config; @@ -305,6 +309,18 @@ default T provider(IOType ioType) throws ProviderNotFoundEx throw new ProviderNotFoundException(ioType); } + // ------------------------------------------------------------------------ + // BOARD INFO ACCESSOR METHODS + // ------------------------------------------------------------------------ + + /** + * Return the BoardInfo containing more info about the + * {@link BoardModel}, {@link OperatingSystem}, and {@link JavaInfo}. + * + * @return {@link BoardInfo} + */ + BoardInfo boardInfo(); + // ------------------------------------------------------------------------ // I/O INSTANCE ACCESSOR/CREATOR METHODS // ------------------------------------------------------------------------ diff --git a/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContext.java b/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContext.java index af74d71f..7f283338 100644 --- a/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContext.java +++ b/pi4j-core/src/main/java/com/pi4j/context/impl/DefaultContext.java @@ -25,6 +25,8 @@ * #L% */ +import com.pi4j.boardinfo.model.BoardInfo; +import com.pi4j.boardinfo.util.BoardModelDetection; import com.pi4j.context.Context; import com.pi4j.context.ContextConfig; import com.pi4j.context.ContextProperties; @@ -62,6 +64,7 @@ public class DefaultContext implements Context { private Providers providers = null; private Platforms platforms = null; private Registry registry = null; + private BoardInfo boardInfo = null; /** *

newInstance.

@@ -78,7 +81,7 @@ private DefaultContext(ContextConfig config) { logger.trace("new Pi4J runtime context initialized [config={}]", config); // validate config object exists - if(config == null){ + if(config == null) { throw new LifecycleException("Unable to create new Pi4J runtime context; missing (ContextConfig) config object."); } @@ -100,6 +103,12 @@ private DefaultContext(ContextConfig config) { // create API accessible platforms instance (READ-ONLY ACCESS OBJECT) this.platforms = DefaultPlatforms.newInstance(this.runtime.platforms()); + // detect the board model + this.boardInfo = BoardModelDetection.current(); + logger.info("Detected board model: {}", boardInfo.getBoardModel().getLabel()); + logger.info("Running on: {}", boardInfo.getOperatingSystem()); + logger.info("With Java version: {}", boardInfo.getJavaInfo()); + // initialize runtime now this.runtime.initialize(); @@ -128,6 +137,10 @@ public ContextProperties properties() { @Override public Platforms platforms() { return this.platforms; } + /** {@inheritDoc} */ + @Override + public BoardInfo boardInfo() { return this.boardInfo; } + /** {@inheritDoc} */ @Override public Future submitTask(Runnable task) { diff --git a/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java b/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java index 664d72aa..1dffb9c0 100644 --- a/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java +++ b/pi4j-core/src/main/java/com/pi4j/runtime/impl/DefaultRuntime.java @@ -25,7 +25,6 @@ * #L% */ -import com.pi4j.boardinfo.util.BoardModelDetection; import com.pi4j.context.Context; import com.pi4j.context.ContextConfig; import com.pi4j.event.*; @@ -249,10 +248,6 @@ public boolean isShutdown() { public Runtime initialize() throws InitializeException { logger.info("Initializing Pi4J context/runtime..."); try { - // Output the type of board - var model = BoardModelDetection.getDetectedBoard(); - logger.info("detected board model: {}", model.getBoardModel().getLabel()); - // clear plugins container plugins.clear(); diff --git a/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java b/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java index 4882416e..b6108f67 100644 --- a/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java +++ b/pi4j-core/test/java/com/pi4j/boardinfo/util/BoardModelDetectionTest.java @@ -10,7 +10,7 @@ class BoardModelDetectionTest { @Test void testGetDetectedBoard() { - var detectedBoard = BoardModelDetection.getDetectedBoard(); + var detectedBoard = BoardModelDetection.current(); assertAll( () -> assertEquals(detectedBoard.getOperatingSystem().getName(), System.getProperty("os.name")), From 33ad68a8e712a790ad38727dc7ce558736c292cf Mon Sep 17 00:00:00 2001 From: Frank Delporte Date: Fri, 5 Apr 2024 14:08:14 +0200 Subject: [PATCH 5/5] #340 Removed JSON library --- pi4j-core/pom.xml | 14 -------------- .../com/pi4j/boardinfo/definition/BoardModel.java | 2 -- .../com/pi4j/boardinfo/definition/BoardType.java | 3 --- .../java/com/pi4j/boardinfo/definition/Cpu.java | 3 --- .../com/pi4j/boardinfo/definition/HeaderPins.java | 2 -- .../pi4j/boardinfo/definition/HeaderVersion.java | 3 --- .../pi4j/boardinfo/definition/InstructionSet.java | 3 --- .../com/pi4j/boardinfo/definition/PiModel.java | 3 --- .../com/pi4j/boardinfo/definition/PinFunction.java | 3 --- .../com/pi4j/boardinfo/definition/PinType.java | 3 --- .../java/com/pi4j/boardinfo/definition/Soc.java | 3 --- .../java/com/pi4j/boardinfo/model/HeaderPin.java | 2 -- pi4j-core/src/main/java/module-info.java | 3 --- 13 files changed, 47 deletions(-) diff --git a/pi4j-core/pom.xml b/pi4j-core/pom.xml index f9a240bc..810a53f5 100644 --- a/pi4j-core/pom.xml +++ b/pi4j-core/pom.xml @@ -15,20 +15,6 @@ ../pom.xml - - - 2.17.0 - - - - - - com.fasterxml.jackson.core - jackson-annotations - ${jackson.version} - - - diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java index ceddc624..f18d49f0 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardModel.java @@ -1,6 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,7 +19,6 @@ * raspberrypi.com/documentation/computers/raspberry-pi.html#new-style-revision-codes-in-use * raspberrypi-spy.co.uk/2012/09/checking-your-raspberry-pi-board-version/ */ -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum BoardModel { MODEL_1_A("Raspberry Pi 1 Model A", SINGLE_BOARD_COMPUTER, new ArrayList<>(), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java index 0cc9cc41..542fe1a7 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/BoardType.java @@ -1,8 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum BoardType { ALL_IN_ONE_COMPUTER, MICROCONTROLLER, diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java index be67b144..7c1da3a9 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Cpu.java @@ -1,8 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum Cpu { ARM1176JZF_S("ARM1176JZF-S"), CORTEX_A53("Cortex-A53"), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java index bb05b973..571dbc7a 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderPins.java @@ -1,6 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; import com.pi4j.boardinfo.model.HeaderPin; import java.util.ArrayList; @@ -9,7 +8,6 @@ /** * List of pins in a Raspberry Pi header. */ -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum HeaderPins { HEADER_8("8pin header", get8PinsHeader()), HEADER_26_TYPE_1("26pin header - type 1", get26PinsHeader(1)), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java index ce7af2af..5d384ea7 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/HeaderVersion.java @@ -1,13 +1,10 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum HeaderVersion { PICO("Pico", "Used on the Pico microcontroller", new ArrayList<>()), TYPE_1("Type 1", "Used on original Model B", Collections.singletonList(HeaderPins.HEADER_26_TYPE_1)), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java index 12adcfe3..f4028338 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/InstructionSet.java @@ -1,8 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum InstructionSet { ARM_V6_M("ARMv6-M"), ARM_V6("ARMv6"), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java index f6b9a697..62775beb 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PiModel.java @@ -1,8 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum PiModel { COMPUTE("Compute Module", "Pi on a 200-pin DDR2-memory-like module for integration in embedded devices"), MODEL_A("Model A", "Without ethernet connector"), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java index e419121d..0b9f64f6 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinFunction.java @@ -1,11 +1,8 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - /** * List of pin functions in a header. */ -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum PinFunction { UART("Universal Asynchronous Receiver and Transmitter", "Asynchronous serial communication protocol"), GPCLK("General Purpose Clock", "Output a fixed frequency"), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java index 7a8c4669..1f7a8386 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/PinType.java @@ -1,11 +1,8 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - /** * List of pin types in a header. */ -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum PinType { POWER("Power", 0x990000), GROUND("Ground", 0x000000), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java index 14ae7d5c..e0710bed 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/definition/Soc.java @@ -1,8 +1,5 @@ package com.pi4j.boardinfo.definition; -import com.fasterxml.jackson.annotation.JsonFormat; - -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public enum Soc { BCM2710A1(InstructionSet.ARM_V8), BCM2711(InstructionSet.ARM_V8), diff --git a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java index 58f1f372..34645a71 100644 --- a/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java +++ b/pi4j-core/src/main/java/com/pi4j/boardinfo/model/HeaderPin.java @@ -1,13 +1,11 @@ package com.pi4j.boardinfo.model; -import com.fasterxml.jackson.annotation.JsonFormat; import com.pi4j.boardinfo.definition.PinFunction; import com.pi4j.boardinfo.definition.PinType; /** * Describes a pin in the header. */ -@JsonFormat(shape = JsonFormat.Shape.OBJECT) public class HeaderPin { private final int pinNumber; private final PinType pinType; diff --git a/pi4j-core/src/main/java/module-info.java b/pi4j-core/src/main/java/module-info.java index f8425262..00706ec1 100644 --- a/pi4j-core/src/main/java/module-info.java +++ b/pi4j-core/src/main/java/module-info.java @@ -27,9 +27,6 @@ // depends on SLF4J requires org.slf4j; - // board info uses Jackson to be able to output as JSON - requires com.fasterxml.jackson.annotation; - // exposed interfaces/classes exports com.pi4j; exports com.pi4j.boardinfo.definition;