mirror of
https://github.com/rbtsco/cubemx2kicad.git
synced 2025-04-02 18:46:23 +03:00
Initial commit
This commit is contained in:
parent
fffcaf6729
commit
a4b66c3df7
157
cubemx2kicad.js
Executable file
157
cubemx2kicad.js
Executable file
@ -0,0 +1,157 @@
|
|||||||
|
#!/usr/bin/node
|
||||||
|
|
||||||
|
const fs = require('fs');
|
||||||
|
const util = require('util');
|
||||||
|
|
||||||
|
const print_log = true; // TODO: Make configurable
|
||||||
|
const save_backup = true; // TODO: Make configurable
|
||||||
|
|
||||||
|
const ioc_fn = process.argv[2];
|
||||||
|
const schematic_fn = process.argv[3];
|
||||||
|
|
||||||
|
if (process.argv.length < 4 || !fs.existsSync(ioc_fn) || !fs.existsSync(schematic_fn)) {
|
||||||
|
console.error(`
|
||||||
|
Usage:
|
||||||
|
|
||||||
|
${process.argv[1]} STM32CubeMX_file.ioc KiCad_schematic_file.kicad_sch
|
||||||
|
`);
|
||||||
|
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const schematic_file = fs.readFileSync(schematic_fn, 'utf-8')
|
||||||
|
const cube_file = fs.readFileSync(ioc_fn, 'utf-8')
|
||||||
|
|
||||||
|
// Stores CubeMX pin configurations
|
||||||
|
const pin_map = {};
|
||||||
|
|
||||||
|
const pin_re = /(^P[A-Z][0-9]+)(-[^.]+)?\.([^=]+)=(.*)$/
|
||||||
|
const name_re = /Mcu.UserName=(.*)/
|
||||||
|
const sym_re = /\(symbol "(?:([^:]*):)?([^"]+)"/
|
||||||
|
const ki_pin_name_re = /(\s*\(name\s+")([^"]*)(".*)/
|
||||||
|
|
||||||
|
// Used for matching up to the right KiCad symbol
|
||||||
|
let mcu_name = ""
|
||||||
|
|
||||||
|
cube_file.split(/[\r\n]+/).forEach(function(line) {
|
||||||
|
// First find anything that looks like a pin property
|
||||||
|
const match = line.match(pin_re);
|
||||||
|
if (match) {
|
||||||
|
// console.log(`${line} => ${util.inspect(match, {colors: true})}`);
|
||||||
|
|
||||||
|
const name = match[1];
|
||||||
|
|
||||||
|
if (!pin_map[name]) pin_map[name] = {
|
||||||
|
base_name: name,
|
||||||
|
name_suffix: match[2]
|
||||||
|
};
|
||||||
|
|
||||||
|
const pd = pin_map[name];
|
||||||
|
|
||||||
|
pd[match[3]] = match[4]
|
||||||
|
} else {
|
||||||
|
// If we don't have a pin, check for an MCU name
|
||||||
|
const mu = line.match(name_re);
|
||||||
|
if (mu) {
|
||||||
|
// console.log(`${line} => ${util.inspect(mu, {colors: true})}`);
|
||||||
|
mcu_name = mu[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// STM32 MCU names use 'x' as wildcard
|
||||||
|
const mcu_re = new RegExp(`^${mcu_name.replace(/x/, '.*')}.*`);
|
||||||
|
|
||||||
|
// Create pin names. Spaces are converted to underscore by KiCad. Leaving these spaces for when they finally address that issue.
|
||||||
|
for (const pn of Object.keys(pin_map)) {
|
||||||
|
const pin = pin_map[pn];
|
||||||
|
let name;
|
||||||
|
if (pin.GPIO_Label) {
|
||||||
|
if (pin.Signal) {
|
||||||
|
name = `${pin.GPIO_Label} (${pin.Signal} / ${pin.base_name}${pin.name_suffix || ''})`
|
||||||
|
} else {
|
||||||
|
name = `${pin.GPIO_Label} (${pin.base_name}${pin.name_suffix || ''})`
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (pin.Signal) {
|
||||||
|
name = `${pin.Signal} (${pin.base_name}${pin.name_suffix || ''})`;
|
||||||
|
} else {
|
||||||
|
name = `${pin.base_name}${pin.name_suffix || ''}`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pin.user_name = name;
|
||||||
|
// console.log(`${pin.base_name} => ${name}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The current 'active' symbol
|
||||||
|
let sym;
|
||||||
|
// The current active pin
|
||||||
|
let ap;
|
||||||
|
|
||||||
|
const output = [];
|
||||||
|
const log = [];
|
||||||
|
|
||||||
|
schematic_file.split(/[\r\n]+/).forEach(function(line) {
|
||||||
|
const sm = line.match(sym_re);
|
||||||
|
if (sm) {
|
||||||
|
// console.log(util.inspect(sm ))
|
||||||
|
sym = sm[2];
|
||||||
|
} else if (sym && mcu_re.test(sym)) {
|
||||||
|
const m = line.match(ki_pin_name_re);
|
||||||
|
if (m) {
|
||||||
|
// console.log(util.inspect(m, {colors:true}));
|
||||||
|
|
||||||
|
const m2 = m[2].match(/^(P[A-Z][0-9]+)(-.+)?$/) || m[2].match(/.*[ _(](P[A-Z][0-9]+)(-.+)?\)$/);
|
||||||
|
|
||||||
|
if (m2) {
|
||||||
|
// console.log(m2);
|
||||||
|
|
||||||
|
const n = m2[1];
|
||||||
|
|
||||||
|
let replacement;
|
||||||
|
|
||||||
|
if (pin_map[n]) {
|
||||||
|
replacement = pin_map[n].user_name;
|
||||||
|
} else {
|
||||||
|
replacement = `${m2[1]}${m2[2]||''}`;
|
||||||
|
}
|
||||||
|
if (print_log) {
|
||||||
|
log.push(`${n} => ${replacement}`)
|
||||||
|
}
|
||||||
|
output.push(`${m[1]}${replacement}${m[3]}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push(line);
|
||||||
|
});
|
||||||
|
|
||||||
|
function write_and_backup(fn, data, mode = 'utf-8') {
|
||||||
|
if (save_backup) {
|
||||||
|
if (fs.existsSync(fn)) {
|
||||||
|
let bfn;
|
||||||
|
let i = 0;
|
||||||
|
do {
|
||||||
|
bfn = `${fn}.${++i}`
|
||||||
|
} while (fs.existsSync(bfn));
|
||||||
|
fs.renameSync(fn, bfn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fs.writeFileSync(fn, data, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
write_and_backup(schematic_fn, output.join('\n'));
|
||||||
|
|
||||||
|
if (print_log) {
|
||||||
|
// Prints the list of pin modifications done, nicely sorted
|
||||||
|
console.log(log.sort(function(a, b) {
|
||||||
|
return a.localeCompare(b, undefined, {
|
||||||
|
numeric: true,
|
||||||
|
sensitivity: 'base'
|
||||||
|
});
|
||||||
|
} ).join('\n'))
|
||||||
|
}
|
11
package.json
Normal file
11
package.json
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"name": "cubemx2kicad",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Export STM32 CubeMX pin assignments to matching symbols in a KiCad schematic",
|
||||||
|
"main": "cubemx2kicad.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"author": "Stefan Hamminga",
|
||||||
|
"license": "apache-2.0"
|
||||||
|
}
|
32
readme.md
Normal file
32
readme.md
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# Export STM32 CubeMX pin assignments to matching symbols in a KiCad schematic
|
||||||
|
|
||||||
|
This tool reads a CubeMX `.ioc` file, constructs pin labels and applies those to matching MCU symbols in the given KiCad schematic file.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```shell
|
||||||
|
./cubemx2kicad.js STM32CubeMX_file.ioc KiCad_schematic_file.kicad_sch
|
||||||
|
```
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
Just clone the repo, beyond Node.JS no dependencies.
|
||||||
|
|
||||||
|
## Some points of attention
|
||||||
|
|
||||||
|
- CubeMX can stay open during this, but the KiCad schematic editor should be closed and re-opened after
|
||||||
|
- Use 'user label' in CubeMX for best experience
|
||||||
|
- The backup and log functions need to be disbled in the source
|
||||||
|
- This messes up / does not work with alternate pin functions in KiCad, beware.
|
||||||
|
- The KiCad ERC will complain that the MCU symbol will no longer match the library.
|
||||||
|
- The KiCad 'parser' is extremely simplistic and doesn't respect the s-expression scoping. It works for what KiCad saves, but is probably fragile when using other exporters.
|
||||||
|
|
||||||
|
## Repository & License
|
||||||
|
|
||||||
|
Written by Stefan Hamminga <stefan@rbts.co>.
|
||||||
|
|
||||||
|
This tool can be downloaded from
|
||||||
|
|
||||||
|
https://github.com/rbtsco/cubemx2kicad
|
||||||
|
|
||||||
|
and freely distributed under the terms of the Apache 2.0 license.
|
Loading…
x
Reference in New Issue
Block a user