-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom output/custom command #109
Comments
Is a good idea, but needs changes in some classes, so it can be applied to schematic, PCB and 3D variants. I'll look into it after finishing some KiCost plug-ins. |
Ok, no hurry ;-). I was thinking this could even be a base class with common options and build (refactor) the other tools on it. |
I'd be very interested in this feature too. Since I am using KiBot to generate my final fabiration datapacks I need the ability to execute a custom script or two during the process to perform a little extra processing of generated files before they get compressed into a zip. Having the ability to have a 'custom command' output would work perfectly. For reference, the extra processing I am looking to perform right now is to create a single assembly PDF by combining/merging multiple PDFs (not just concatenate pages like the 'pdfunite' output does). |
Can you comment more about it? May be we can add more stuff to the |
So the thing I am trying to achieve at the moment is to generate a single PDF that has two pages (one front and one back) on each page I would like to have the F.Fab layer + a couple of other layers visible (all overlayed). Unfortunately, the two mechanisms that KiCAD has at the moment (print and plot) have different features/limitations that means it is not possible to do this. The Ultimately, this requires changes/improvements in KiCAD, which is no bad thing. However, this will not be quick and I must have a mechanism to enable me to work-around problems like this until the 'proper' solution is implemented in KiCAD/KiBot. My desire with the custom command functionality is to allow me to implement short-term workarounds and I would always strive to get the functionality implemented into KiCAD/KiBot in parallel. |
Hi @richardbarlow ! |
With the new |
I would like a "runner" output as well, for running a script/executable/whatever.. |
Hi @matthiesenj ! |
The footprint in question is a Raspberry Pi Compute Module.. It is a single KiCad footprint, but has 4 mounting holes and two identical connectors. The reason it is designed as a single footprint is so it is easy to place and move on the pcb, I suppose. |
Hi @matthiesenj !
I know that moving it in the PCB isn't simple, but the solution will be consistent with KiCad workflow. |
Your suggestion could work for the spacers, but not the connectors, I think - how would they get associated with the schematic symbol pins (the symbol has 200 pins, 100 for each connector) ? |
Why not? Just use 2 connectors, lets name them A and B, both with pin numbers 1 to 100. |
BTW: KiCad 6 can make footprint groups, so you should be able to align the parts, create a group and then move the whole group. Avoiding misalignments. |
This would require using two distinct 100 pin schematic symbols, which would be a massive step backwards, considering the symbol I'm using has 10 functional units covering all 200 pins, and not something I would consider changing at this stage of the design.
Interesting - might come in handy when I switch to KiCad 6 at some point. |
We use a script to generate these symbols, is now outdated, but I'll add support to KiCad 6 next time I need to use it. #!/usr/bin/perl
##############################################################################
#
# Copyright (c) 2014 David M. Caruso <daviud en inti gov ar>
# Copyright (c) 2015-2019 Salvador E. Tropea <salvador en inti gov ar>
# Copyright (c) 2014-2019 Instituto Nacional de Tecnología Industrial
#
##############################################################################
#
# Target: Any
# Language: Perl
# Interpreter used: v5.6.1/v5.8.4
# Text editor: SETEdit 0.5.5
#
##############################################################################
#
# 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; version 2.
#
# 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA
#
##############################################################################
#
# Description: Component Schematic Generator for Kicad
#
##############################################################################
#Usar una hash, para barrer los datos
#para el footprint barrer bolita por bolita.
use POSIX qw(strftime);
use Sort::Versions;
use Getopt::Long;
use Locale::TextDomain('kicad_tools');
$version='1.1.1';
ParseCommandLine();
#use constant AGE => 2;
$fecha = strftime "%e/%m/%Y-%H:%M:%S", localtime;
%kicadel = ('Input/Output','B',
'Power Input','W',
'Power Output','w',
'NC','N',
'Input','I',
'Output','O',
'Input Clock','I C',
'Input Clock Negated','I IC',
'Input Negated','I I',
'Output Negated','O I',
'Input/Output Negated','B I',
'Output Clock','O C',
'Output Clock Negated','O IC',
'Tri-state Negated','T I',
'Tri-state','T',
'Passive','P'
);
#-----------------------------------------------------------------------------
# Read File and order data
#-----------------------------------------------------------------------------
open(F,"$filein") || die "Can't open $filein";
$pinnum=0;
$ind_field=0;
@exfield;
@namexfield;
%hGrupo=();
# %hBall=();
# %hBalldie=();
$NumGroup=0;
while ($line=<F>)
{
if ($line=~/\"?([^\"]*)\"?,\"?([^\"]*)\"?,,,,,,/)
{
$exfield[$ind_field]=$2;
$namexfield[$ind_field]=$1;
print "$1: $2\n";
$ind_field++;
}
elsif ($line=~/\"?([^\"]*)\"?,\"?([^\"]*)\"?,\"?([^\"]*)\"?,\"?([^\"]*)\"?,\"?([^\"]*)\"?,\"?([^\"]*)\"?,\"?([^\"]*)\"?,\"?([^\"]*)\"?/)
{#Pin,Pin Name,Description,Input/Output,Sub-Grupo,Grupo,Dominio de Alimentacion,L die
# 1 2 3 4 5 6
#print "<$1>: <$2>\n";
if (($1 ne "Pin") && ($2 ne "Pin Name"))
{# Descarta la línea separadora de los nombres
$pinnum++;
push(@Ll,"$6;-;$5;-;$2;-;$1;-;$4"); # array a ordenar para el esquemático
$Grupo=$6;
$Grupo=~s/ /_/g; # Quita espacios del Nombre del Grupo
unless ($hGrupo{$Grupo}) # Se fija si el grupo existe
{
if (($Grupo ne 'NC') || $withnc)
{
$hGrupo{$Grupo}=1;
$NumGroup++;
}
}
else {$hGrupo{$Grupo}++;}
}
}
else
{
print "** line = \"$line\"\n";
die "** Error de parseo en el CSV\n";
}
}
close $F;
print "Reading: $pinnum pins\n";
if ($NumGroup>26)
{
die "** Error: The maximum number of groups is 26, not $NumGroup\n";
}
print "There are: $NumGroup groups of pins\n";
#Orden de los datos parseados
$pin_grp=0;
$pin_sgrp=1;
$pin_name=2;
$pin_ord=3;
$pin_io=4;
#-----------------------------------------------------------------------------
# Schematic .lib
#-----------------------------------------------------------------------------
# Config Constants:
$sep = 50; # Separation pin
$rsizex=$cwidth; # Component width
$txtsig=40; # Text Size for signal
$txtcmp=60; # Text Size for component
$txtgroup=70; # Text Size for group
$pinlarge=$pinl; # Pin Large
# Ordeno por grupo de señal, luego por subgrupo, luego por nombre de señal
#@Ll = sort {$a cmp $b} @Ll;
@Ll = sort {versioncmp($a,$b)} @Ll;
@colm=split(";-;",$Ll[0]); # Divide las columnas con el nuevo orden.
$colm[$pin_grp] =~s/ /_/g; # Quita espacios del Nombre del Grupo
$colm[$pin_sgrp] =~s/ /_/g; # Quita espacios del Nombre del Sub-Grupo
unless ($parted){$rsizey = int(3+$pinnum/2) * $sep}
else {$rsizey = int(3+$hGrupo{$colm[pin_grp]}/2) * $sep;}
$pinxpos=$pinlarge+$rsizex;
$part=1;
$yauxr=$rsizey; # Indice derecho
$yauxl=$rsizey; # Indice izquierdo
$yaux =$rsizey; # Arranca por el lado derecho
$sidetxt = "$pinlarge L";
$xside= $pinxpos;
$newGroup= $colm[$pin_grp];
$newSGroup= $colm[$pin_sgrp];
$indg=1;
open(S,">$outdir\/$lib\.lib") || die "Can't create $outdir\/$lib\.lib";
print S "EESchema-LIBRARY Version 2.3 Date: $fecha\n".
"#\n# $lib\n#\n";
unless ($parted){print S "DEF $lib U 0 40 Y Y 1 F N\n";}
else {print S "DEF $lib U 0 40 Y Y $NumGroup L N\n";}
print S "F0 \"U\" 0 100 $txtcmp H V C CNN\n";
print S "F1 \"$lib\" 0 0 $txtcmp H V C CNN\n"; #Nombre
if ($withexfield)
{
print S "F2 \"$exfield[0]\" 0 -100 $txtcmp H I C CNN\n". # Footprint
"F3 \"$exfield[4]\" 0 -100 $txtcmp H I C CNN\n". # Hoja de datos
"F4 \"$exfield[1]\" 0 -100 $txtcmp H I C CNN \"$namexfield[1]\"\n". # Descripción
"F5 \"$exfield[2]\" 0 -100 $txtcmp H I C CNN \"$namexfield[2]\"\n". # Fabricante
"F6 \"$exfield[3]\" 0 -100 $txtcmp H I C CNN \"$namexfield[3]\"\n". # Numero de Parte
"F7 \"$exfield[5]\" 0 -100 $txtcmp H I C CNN \"$namexfield[5]\"\n"; # Codigo
if (scalar(@exfield)>6)
{# Otros
my ($i, $c);
$c=scalar(@exfield);
for ($i=6; $i<$c; $i++)
{
print S "F".($i+2)." \"".$exfield[$i]."\" 0 -100 $txtcmp H I C CNN \"".$namexfield[$i]."\"\n";
}
}
}
print S "DRAW\n";
for ($ind=0;$ind<=$#Ll;$ind++)
{
@colm=split(";-;",$Ll[$ind]); # Divide las columnas con el nuevo orden.
$colm[$pin_grp] =~s/ /_/g; # Quita espacios del Nombre del Grupo
$colm[$pin_sgrp] =~s/ /_/g; # Quita espacios del Nombre del Sub-Grupo
unless($kicadel{$colm[$pin_io]})
{
die "** Error: Incorrect I/O specification for Pin: $colm[$pin_ord], name $colm[$pin_name], I/O: $colm[$pin_io]\n";
}
if (($colm[$pin_grp] ne 'NC') || $withnc)
{
if ($newSGroup ne $colm[$pin_sgrp])
{
$newSGroup = $colm[$pin_sgrp];
if ($xside<0){$yauxl=$yaux- ($sep * 2);}
else {$yauxr=$yaux- ($sep * 2);}
if ($yauxr<$yauxl)
{
$sidetxt = "$pinlarge R";
$xside=-$pinxpos;
$yaux = $yauxl;
}
else
{
$sidetxt = "$pinlarge L";
$xside=$pinxpos;
$yaux = $yauxr;
}
}
if ($parted)
{
if ($newGroup ne $colm[$pin_grp])
{
$yaux=$yauxr<$yauxl ? $yauxr : $yauxl;
if ($xside==$pinxpos)
{# Estábamos de la izquierda
$yaux-=$sep if $yauxl>yauxr;
}
else
{# Estábamos de la derecha
$yaux-=$sep if $yauxr>yauxl;
}
print S "S -$rsizex $rsizey $rsizex $yaux $part 0 0 N\n"; # Dibuja la caja
$yaux-=2*$sep;
print S "T 0 0 $yaux $txtgroup 0 $part 0 $newGroup Normal 0 C C\n";
$newGroup = $colm[$pin_grp];
$rsizey = int(3+$hGrupo{$newGroup}/2) * $sep;
$yauxr=$rsizey; # Indice derecho
$yauxl=$rsizey; # Indice izquierdo
$yaux =$rsizey; # Arranca por el lado derecho
$sidetxt = "$pinlarge L";
$xside=$pinxpos;
$part++;
$indg = 1;
}
}
$yaux=$yaux-2*$sep;
$indg++;
print S "X $colm[$pin_name] $colm[$pin_ord] $xside $yaux $sidetxt $txtsig $txtsig $part 1 $kicadel{$colm[$pin_io]}\n";
}
}
$yaux=$yauxr if $yauxr<$yaux;
$yaux=$yauxl if $yauxl<$yaux;
$yaux-=2*$sep;
print S "S -$rsizex $rsizey $rsizex $yaux $part 0 0 N\n"; # Dibuja la caja
$yaux-=2*$sep;
if ($parted){print S "T 0 0 $yaux $txtgroup 0 $part 0 $newGroup Normal 0 C C\n";}
else {print S "T 0 0 $yaux $txtgroup 0 $part 0 $lib Normal 0 C C\n";}
print S "ENDDRAW\n".
"ENDDEF\n";
print S "#\n#End Library";
close S;
#-----------------------------------------------------------------------------
# ParseCommandLine:
# Parser
#-----------------------------------------------------------------------------
sub ParseCommandLine
{
GetOptions("verbose|v=i" => \$verbosity,
"version" => \$showVersion,
"part" => \$parted,
"input=s" => \$filein,
"dir=s" => \$outdir,
"wdcomp=i" => \$cwidth,
"pinl=i" => \$pinl,
"withnc" => \$withnc,
"withexfield" => \$withexfield,
"docfile=s" => \$docfile,
"lib=s" => \$lib,
"help|?" => \$help) or ShowHelp();
if ($showVersion)
{
print "comp_gen.pl (kicad_tools) $version\n".
"Copyright (c) 2014-2015 David M. Caruso/Salvador E. Tropea/INTI\n".
"License GPLv2: GNU GPL version 2 <http://gnu.org/licenses/gpl.html>\n".
__("This is free software: you are free to change and redistribute it.\n".
"There is NO WARRANTY, to the extent permitted by law.\n\n").
__("Written by")." David M. Caruso.\n";
exit(0);
}
print "Component Schematic Generator for Kicad v$version Copyright (c) 2014-2015 David M. Caruso/SET/INTI\n";
ShowHelp() if $help;
unless($filein)
{
print "You must specify an input file name.\n";
ShowHelp();
}
unless($lib)
{
print "You must specify an library name.\n";
ShowHelp();
}
if ($outdir && !(-e "$outdir"))
{
system "mkdir $outdir";
}
unless ($outdir)
{
$outdir='.'; # Si no se especifica el directorio, asigna el actual
}
unless ($docfile)
{
$docfile=$filein;
}
unless ($cwidth)
{
$cwidth=900;
}
unless ($pinl)
{
$pinl=400;
}
}
sub ShowHelp
{
print __"Usage: bga_gen.pl [options]\n";
print __"\nAvailable options:\n";
print __"--version Outputs version information and exit.\n";
print __"--input=name Input File with ball description\n";
print __"--dir=name Output Directory for component, Default=Current\n";
print __"--lib=name Library Name\n";
print __"--wdcomp=value Width Schematic Component\n";
print __"--pinl=value Pin length\n";
print __"--part Component Schematic in parts\n";
print __"--withnc Include NC pins\n";
print __"--help Prints this text.\n\n";
exit 1;
} It takes a CSV like this:
Then you call it like this: $ perl comp_gen.pl -input iCE40HX1-4K.csv -lib iCE40HX1-4K -dir . -part -wdcomp 1200 -withexfield -pinl 150
Component Schematic Generator for Kicad v1.1.1 Copyright (c) 2014-2015 David M. Caruso/SET/INTI
Footprint: TQFP-144
Descripcion: iCE40 High Speed FPGA
Fabricante: Lattice
Numero de parte: iCE40HX1K
Hoja de datos: -
Codigo: iCE40HX1K
Reading: 144 pins
There are: 6 groups of pins And you get the 6 defined groups: Generating big components, and maintaining them, is much more easy this way. |
That's very nice - I think many of the original KiCad symbols are created in a similar fashion. My schematic is finished by now, so I'm not going to rip it all up by changing it to two separate 100 pin symbols. |
In this case, when you realize you need 2 footprints, you just split the CSV in 2, adjust the pin numbers (can be done with a script or just a spreadsheet) and generate 2 symbols. Each symbols with N sub-symbols. The number will be automatically computed according to the groups you defined. |
I'd be really interested in this feature too. This would open basically infinite possibilities on what to automate. I don't know if you're familiar with Vivado workflows, in which there are so-called "hooks" between each FPGA implementation step (executed sequentially):
So for example Executing custom scripts would be extremely useful for variable replacing, text manipulation outside of KiCad, file copy, etc. |
Hi @Unichord !
Which of these operations can't be currently done?
Panelizing is in my TODO list. In general: why not writing a new output, and perhaps contribute it? |
Maybe I just don't know KiBot deeply enough and all these features are already there.
That is really good news. |
The goal of custom output is to run a custom executable command.
This could allow making a copy of a file to the output directory, parse a template, run a script under development, etc.
I thought of this while thinking of a way to execute the "3D Viewer" image export script that I created.
The text was updated successfully, but these errors were encountered: