/* Copyright 2018 Miklos Marton This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #usage "ULP to sync the nets from a CubeMX to the EAGLE schematic.\n" "

RUN CubeMX2EAGLE

" "

It will generate nets around the selected part and place XREF labels on the nets according to the User labels in the CubeMX project

" "

" "Author: Miklos Marton (martonmiklosqdev -at- gmail.com)" string ULP_KEY = "CubeMX2EAGLE"; #include "IniFile.ulp" #include "config_utils.ulp" /** * str_replace * * Replaces all occurrences of a substring found within a string. */ string str_replace(string search, string replace, string subject) { int lastpos = 0; while(strstr(subject, search, lastpos) >= 0) { int pos = strstr(subject, search, lastpos); string before = strsub(subject, 0, pos); string after = strsub(subject, pos + strlen(search)); subject = before + replace + after; lastpos = pos + strlen(replace); } return subject; } string generateNetAddCommand(UL_PIN pin, string netName) { string command = ""; real pinX = u2inch(pin.x); real pinY = u2inch(pin.y); switch (int(pin.angle)) { case 0: sprintf(command, "net %s (%finch %finch) (%finch %finch);", netName, pinX, pinY, pinX - 0.1, pinY); sprintf(command, "%sLABEL XREF R180 (%finch %finch) (%finch %finch);\n", command, pinX - 0.1, pinY, pinX - 0.1, pinY); break; case 270: sprintf(command, "net %s (%finch %finch) (%finch %finch);", netName, pinX, pinY, pinX, pinY + 0.1); sprintf(command, "%sLABEL XREF R90 (%finch %finch) (%finch %finch);\n", command, pinX, pinY + 0.1, pinX, pinY + 0.1); break; case 180: sprintf(command, "NET %s (%finch %finch) (%finch %finch);\n", netName, pinX, pinY, pinX + 0.1, pinY); sprintf(command, "%sLABEL XREF R0 (%finch %finch) (%finch %finch);\n", command, pinX + 0.1, pinY, pinX + 0.1, pinY); break; case 90: sprintf(command, "net %s (%finch %finch) (%finch %finch);", netName, pinX, pinY, pinX, pinY - 0.1); sprintf(command, "%sLABEL XREF R270 (%finch %finch) (%finch %finch);\n", command, pinX, pinY - 0.1, pinX, pinY - 0.1); break; } return command; } string ret = ""; string partNames[]; string iocFilePath = cfgget_string("iocFilePath", EAGLE_HOME); string mcuRefDes = cfgget_string("mcuRefDes", ""); string cubeMXPath = cfgget_string("cubeMXPath", ""); schematic(SCH) { int i = 0; SCH.parts(PART) { // list only devices with 8 pin or more int pinCount = 0; PART.instances(INST) { INST.gate.symbol.pins(PIN) { pinCount++; if (pinCount >= 8) break; } } // filter out devices > with 8 pins if (pinCount >= 8) { partNames[i] = PART.name; i++; } } } if (argc < 4) { int selectedPartNameIndex = 0; int result = dlgDialog("Choose the part") { dlgComboBox(partNames, selectedPartNameIndex); dlgHBoxLayout { dlgLabel("CubeMX project file:"); dlgStringEdit(iocFilePath); dlgPushButton("...") { iocFilePath = dlgFileOpen("Please select the CubeMX project file", iocFilePath, "STM32CubeMX Project files (*.ioc);;STM8CubeMX Project files (*.ioc8)"); } } dlgHBoxLayout { dlgLabel("CubeMX installation path:"); dlgStringEdit(cubeMXPath); dlgPushButton("...") { cubeMXPath = dlgDirectory("Please select the CubeMX installation path", cubeMXPath); } } dlgPushButton("Generate nets") { dlgAccept(0); } }; if (result != 0) exit(0); mcuRefDes = partNames[selectedPartNameIndex]; } else { mcuRefDes = argv[1]; iocFilePath = argv[2]; } string MCUName = INI_GetString("", "Mcu.Name", "", iocFilePath); string pinsXML = ""; string pinXMLTags[]; int XMLPinCount = 0; if (MCUName != "") { string XML; if (fileread(XML, cubeMXPath + "/db/mcu/" + MCUName + ".xml") != 0) { XMLPinCount = xmlelements(pinXMLTags, XML, "Mcu/Pin"); } else { string btnLabel = ""; sprintf(btnLabel, "Unable to read the %s XML file!\nCheck the CubeMX installation folder", cubeMXPath + "db/mcu/" + MCUName + ".xml"); dlgMessageBox(btnLabel); exit(0); } } string pinNumberStr = INI_GetString("", "Mcu.PinsNb", "0", iocFilePath); if (pinNumberStr != "0") { string netNames[]; string pinNumbers[]; string pinNames[]; int pinCount = strtol(pinNumberStr); // do a loop on all the Mcu.Pin23=PA11 type entries of the IOC file for (int pinIndex = 0; pinIndex quit break; } // if (PART.name == mcuRefDes) } // SCH.parts } // SCH } else { dlgMessageBox("Unable to find Mcu.PinsNb in the ioc file!\nMaybe it is malformed?"); exit(0); } cfgset_string("iocFilePath", iocFilePath); cfgset_string("mcuRefDes", mcuRefDes); cfgset_string("cubeMXPath", cubeMXPath); exit(ret);