export board-specific macro for stm32 pins based on board yaml #3298

This commit is contained in:
Andrey 2023-09-04 19:16:53 -04:00
parent 769c579889
commit 9fe1e42c3e
4 changed files with 95 additions and 20 deletions

View File

@ -12,7 +12,9 @@ public interface BoardInputs {
List<String> getInputFiles();
Writer getWriter() throws IOException;
Writer getBoardNamesWriter() throws IOException;
Writer getOutputsWriter() throws IOException;
List<String> getBoardMeta(String boardMetaFileName);
}

View File

@ -59,10 +59,15 @@ public class FileSystemBoardInputsImpl implements BoardInputs {
}
@Override
public Writer getWriter() throws IOException {
public Writer getBoardNamesWriter() throws IOException {
return new FileWriter(boardName + PinoutLogic.CONNECTORS + File.separator + "generated_ts_name_by_pin.cpp");
}
@Override
public Writer getOutputsWriter() throws IOException {
return new FileWriter(boardName + PinoutLogic.CONNECTORS + File.separator + "generated_outputs.h");
}
@Override
public List<String> getBoardMeta(String boardMetaFileName) {
try {

View File

@ -30,6 +30,8 @@ public class PinoutLogic {
private final Map</*id*/String, /*tsName*/String> tsNameById = new TreeMap<>();
private final StringBuilder header = new StringBuilder("//DO NOT EDIT MANUALLY, let automation work hard.\n\n");
private final BoardInputs boardInputs;
private final List<String> lowSideOutputs = new ArrayList<>();
private final List<String> highSideOutputs = new ArrayList<>();
public PinoutLogic(BoardInputs boardInputs) {
this.boardInputs = boardInputs;
@ -67,12 +69,12 @@ public class PinoutLogic {
throw new IllegalStateException(boardName + ": Not found " + id + " in " + className);
}
int index = kv.getValue().getIntValue();
classList.ensureCapacity(index + 1);
for (int ii = classList.size(); ii <= index; ii++) {
classList.add(null);
}
classList.set(index, listPin.getPinTsName());
int index = kv.getValue().getIntValue();
classList.ensureCapacity(index + 1);
for (int ii = classList.size(); ii <= index; ii++) {
classList.add(null);
}
classList.set(index, listPin.getPinTsName());
}
for (Map.Entry<String, ArrayList<String>> kv : names.entrySet()) {
PinType namePinType = PinType.find(kv.getKey());
@ -140,7 +142,7 @@ public class PinoutLogic {
SystemOut.println("Null yaml for " + yamlFile);
return;
}
log.info("Got from " + yamlFile + ": " + data);
log.info("Got from " + yamlFile + ": " + data);
Objects.requireNonNull(data, "data");
for (Map<String, Object> pin : data) {
Object pinId = pin.get("id");
@ -148,17 +150,22 @@ public class PinoutLogic {
if (meta != null && pinId != null) {
throw new IllegalStateException(pinId + " not expected with meta=" + meta);
}
String headerValue;
if (meta != null) {
headerValue = meta;
pinId = metaMapping.get(meta);
if (pinId == null) {
if (metaMapping.isEmpty())
throw new IllegalStateException("Empty meta mapping");
throw new IllegalStateException("Failing to resolve [" + meta + "]");
}
} else {
headerValue = (pinId instanceof String) ? (String) pinId : null;
}
Object pinClass = pin.get("class");
Object pinName = pin.get("pin");
Object pinTsName = pin.get("ts_name");
Object pinType = pin.get("type");
if (pinId == null || pinClass == null || pinTsName == null) {
log.info("Skipping " + pinId + "/" + pinClass + "/" + pinTsName);
continue;
@ -175,21 +182,24 @@ public class PinoutLogic {
throw new IllegalStateException(pinName + ": id array length should match class array length: " + pinId + " vs " + pinClassArray);
for (int i = 0; i < pinIds.size(); i++) {
String id = pinIds.get(i);
String originalValue = id;
// we are a bit inconsistent between single-function and array syntax:
// for array syntax we just apply mapping on the fly while for single we use 'meta' keyword instead of 'pin' keyword
id = applyMetaMapping(metaMapping, id);
addPinToList(id, (String) pinTsName, pinClassArray.get(i));
addPinToList(id, originalValue, null, (String) pinTsName, pinClassArray.get(i));
}
} else if (pinId instanceof String) {
String pinIdString = (String) pinId;
if (pinIdString.length() == 0) {
throw new IllegalStateException("Unexpected empty ID field");
}
// array type is allowed even for pins with non-array class
String stringPinType = pinType instanceof String ? (String) pinType : null;
if (!(pinTsName instanceof String))
throw new IllegalStateException("Wrong type: " + pinTsName.getClass() + " while " + pinIdString);
throw new IllegalStateException("Wrong TsName: " + pinTsName + " while " + pinIdString);
if (!(pinClass instanceof String))
throw new IllegalStateException("Wrong type: " + pinClass.getClass() + " while " + pinIdString);
addPinToList(pinIdString, (String) pinTsName, (String) pinClass);
throw new IllegalStateException("Wrong class: " + pinClass + " while " + pinIdString);
addPinToList(pinIdString, headerValue, stringPinType, (String) pinTsName, (String) pinClass);
} else {
throw new IllegalStateException("Unexpected type of ID field: " + pinId.getClass().getSimpleName());
}
@ -231,11 +241,20 @@ public class PinoutLogic {
return map;
}
private void addPinToList(String id, String pinTsName, String pinClass) {
private void addPinToList(String id, String headerValue,
String pinType,
String pinTsName, String pinClass) {
String existingTsName = tsNameById.get(id);
if (existingTsName != null && !existingTsName.equals(pinTsName))
throw new IllegalStateException("ID used multiple times with different ts_name: " + id);
tsNameById.put(id, pinTsName);
if ("outputs".equalsIgnoreCase(pinClass)) {
if ("ls".equalsIgnoreCase(pinType) || "inj".equalsIgnoreCase(pinType)) {
lowSideOutputs.add(headerValue);
} else {
highSideOutputs.add(headerValue);
}
}
PinState thisPin = new PinState(id, pinTsName, pinClass);
globalList.add(thisPin);
}
@ -253,7 +272,7 @@ public class PinoutLogic {
readFiles();
registerPins(boardInputs.getName(), globalList, registry, parseState, enumsReader);
try (Writer getTsNameByIdFile = boardInputs.getWriter()) {
try (Writer getTsNameByIdFile = boardInputs.getBoardNamesWriter()) {
getTsNameByIdFile.append(header);
getTsNameByIdFile.append("#include \"pch.h\"\n\n");
@ -272,6 +291,22 @@ public class PinoutLogic {
getTsNameByIdFile.append("\treturn nullptr;\n}\n");
}
try (Writer outputs = boardInputs.getOutputsWriter()) {
outputs.append(header);
outputs.write("#pragma once\n\n");
outputs.write("Gpio GENERATED_OUTPUTS = {\n");
for (String output : lowSideOutputs)
outputs.write("\tGpio::" + output + ",\n");
for (String output : highSideOutputs)
outputs.write("\tGpio::" + output + ",\n");
outputs.write("}\n");
}
}
private void readFiles() throws IOException {

View File

@ -53,6 +53,13 @@ public class PinoutLogicIntegratedTest {
"\t\tdefault: return nullptr;\n" +
"\t}\n" +
"\treturn nullptr;\n" +
"}\n",
"//DO NOT EDIT MANUALLY, let automation work hard.\n" +
"\n" +
"// auto-generated by PinoutLogic.java based on key\n" +
"#pragma once\n" +
"\n" +
"Gpio GENERATED_OUTPUTS = {\n" +
"}\n");
}
@ -61,9 +68,15 @@ public class PinoutLogicIntegratedTest {
public void testTemplate() throws IOException {
runPinoutTest("meta: meta.h\n" +
"pins:\n" +
" - pin: 3\n" +
" id: A9\n" +
" class: outputs\n" +
" function: Digital trigger/switch input for instance Hall type CAM\n" +
" ts_name: ___ - Digital 1\n" +
" - pin: 2\n" +
" meta: H144_LS_2\n" +
" class: outputs\n" +
" type: ls\n" +
" function: Digital trigger/switch input for instance Hall type CAM\n" +
" ts_name: ___ - Digital 1\n" +
" - pin: 1\n" +
@ -80,17 +93,30 @@ public class PinoutLogicIntegratedTest {
"// see comments at declaration in pin_repository.h\n" +
"const char * getBoardSpecificPinName(brain_pin_e brainPin) {\n" +
"\tswitch(brainPin) {\n" +
"\t\tcase Gpio::A9: return \"3 - Digital 1\";\n" +
"\t\tcase Gpio::E11: return \"1 - Digital 2\";\n" +
"\t\tcase Gpio::G8: return \"2 - Digital 1\";\n" +
"\t\tdefault: return nullptr;\n" +
"\t}\n" +
"\treturn nullptr;\n" +
"}\n",
"//DO NOT EDIT MANUALLY, let automation work hard.\n" +
"\n" +
"// auto-generated by PinoutLogic.java based on key\n" +
"#pragma once\n" +
"\n" +
"Gpio GENERATED_OUTPUTS = {\n" +
"\tGpio::H144_LS_2,\n" +
"\tGpio::A9,\n" +
"}\n");
}
private static void runPinoutTest(String inputYaml, String expected) throws IOException {
StringWriter testWriter = new StringWriter();
private static void runPinoutTest(String inputYaml, String expectedPinNames,
String expectedOutputs) throws IOException {
StringWriter boardNamesTestWriter = new StringWriter();
StringWriter outputsTestWriter = new StringWriter();
Reader input = new StringReader(inputYaml);
@ -116,8 +142,13 @@ public class PinoutLogicIntegratedTest {
}
@Override
public Writer getWriter() {
return testWriter;
public Writer getBoardNamesWriter() {
return boardNamesTestWriter;
}
@Override
public Writer getOutputsWriter() throws IOException {
return outputsTestWriter;
}
@Override
@ -131,6 +162,7 @@ public class PinoutLogicIntegratedTest {
state.getEnumsReader().read(new StringReader("enum class Gpio : uint16_t {\n" +
"Unassigned = 0,\n" +
"Invalid = 0x01,\n" +
"A9 = 4,\n" +
"G8 = 5,\n" +
"E11 = 0x0B,\n" +
"};"));
@ -141,7 +173,8 @@ public class PinoutLogicIntegratedTest {
logic.registerBoardSpecificPinNames(state.getVariableRegistry(), definitionState, state.getEnumsReader());
assertEquals(expected, testWriter.getBuffer().toString());
assertEquals(expectedPinNames, boardNamesTestWriter.getBuffer().toString());
assertEquals(expectedOutputs, outputsTestWriter.getBuffer().toString());
}
@Test