aboutsummaryrefslogblamecommitdiff
path: root/set-footprints-from-pcb.py
blob: 578b9cec27468109a39d5e1483f2ab2b74f981f2 (plain) (tree)






















                                                                               
           






                                                  




                                                               









                                                                                 













                                                                                                         













                                                                                           
                               





















                                                                                      
#!/usr/bin/env python

"""
Set all schematic footprints from the PCB file, where the components footprints
are known. The footprints were exported once from the PCB using the menu option

  File -> Archive Footprints -> Create New Library and Archive Footprints

and the fp-lib-table was set up to map the name 'Cryptech_Alpha_Footprints' to
the archive directory (rev03-KiCad/footprints.pretty).
"""

import os
import sys
import pprint

import pcbnew

def add_footprints(fn_in, fn_out, comp):
    in_ = open(fn_in)
    out = open(fn_out, 'w')
    curr = None
    c = 0
    f0 = ''
    print('Adding footprints to {}'.format(fn_in))
    for line in in_.readlines():
        c += 1
        if line.startswith('L '):
            curr = line.split(' ')[-1]
            while curr[-1] == '\n':
                curr = curr[:-1]
            # Special case handling of chips divided into parts
            if '_' in curr and curr not in comp:
                curr = curr.split('_')[0]
        if line.startswith('F 0 '):
            f0 = line
        if line.startswith('F 2 ""'):
            if curr in comp:
                fp = comp[curr]
                line = 'F 2 "Cryptech_Alpha_Footprints:{}{}'.format(fp, line[5:])
                if line.endswith('0000 C CNN\n'):
                    # don't show the footprint in the schematics
                    line = line[:-8] + '1' + line[-7:]
                #print('{}: line {} {} fp {}'.format(fn_in, c, curr, fp))
            else:
                if not curr.startswith('#PWR'):
                    sys.stderr.write('{}: line {} footprint for {} not known\n'.format(fn_in, c, curr))
            curr = None
            f0 = ''
        if line.startswith('$EndComp') and curr is not None:
            #sys.stderr.write('{}: line {} footprint for {} not written\n'.format(fn_in, c, curr))
            if curr in comp:
                # Component without F 2 line. Construct one roughly from F 0.
                f = f0.split(' ')
                coord = f[4] + ' ' + f[5]
                f2 = 'F 2 "Cryptech_Alpha_Footprints:{}" H {} 60  0001 C CNN\n'.format(comp[curr], coord)
                out.write(f2)
            else:
                if not curr.startswith('#PWR'):
                    sys.stderr.write('{}: line {} footprint for {} not known\n'.format(fn_in, c, curr))
        out.write(line)
    return True

def main(pcb, schemas):
    print("Loading PCB '{}'".format(pcb))
    board = pcbnew.LoadBoard(pcb)
    comp = {}
    for mod in board.GetModules():
        ref = mod.GetReference()
        fp = mod.GetFPID().GetLibItemName()
        if ref in comp:
            sys.stderr.write('{} already in comp ({} -> {})!\n'.format(ref, comp[ref], fp))
        comp[ref] = str(fp)

    #print(sorted(comp.keys()))
    #print(pprint.pformat(comp))

    for this in schemas:
        if add_footprints(this, this + '.tmp', comp):
            os.rename(this + '.tmp', this)

    return True


if __name__ == '__main__':
    try:
        if len(sys.argv) == 0:
            sys.stderr.write('Syntax: set-footprints-from-pcb.py *.kicad_pcb *.sch\n')
            sys.exit(1)
        pcb = [x for x in sys.argv if x.endswith('.kicad_pcb')][0]
        schemas = [x for x in sys.argv if x.endswith('.sch')]
        res = main(pcb, schemas)
        if res:
            sys.exit(0)
        sys.exit(1)
    except KeyboardInterrupt:
        pass