parent
7992fd9888
commit
be59ee397e
|
|
@ -56,7 +56,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
- Position files now can include virtual components. (#106)
|
||||
- Support for variants on KiCost output. (#106)
|
||||
- `--cli-order` option to generate outputs in arbitrary order. (#106)
|
||||
- QR codes generation: symbols and footprints. (#93)
|
||||
- QR codes generation and update: symbols and footprints. (#93)
|
||||
|
||||
### Changed
|
||||
- Internal BoM: now components with different Tolerance, Voltage, Current
|
||||
|
|
|
|||
|
|
@ -1678,6 +1678,11 @@ Next time you need this list just use an alias, like this:
|
|||
* Type: `qr_lib`
|
||||
* Description: Generates a QR code symbol and footprint.
|
||||
This output creates a library containing a symbol and footprint for a QR code.
|
||||
To refresh the generated symbols and footprints use the `update_qr` preflight.
|
||||
The workflow is as follows:
|
||||
- Create the symbol and footprints using this output.
|
||||
- Use them in your schematic and PCB.
|
||||
- To keep them updated add the `update_qr` preflight
|
||||
* Valid keys:
|
||||
- `comment`: [string=''] A comment for documentation purposes.
|
||||
- `dir`: [string='./'] Output directory for the generated files. If it starts with `+` the rest is concatenated to the default dir.
|
||||
|
|
|
|||
|
|
@ -1133,6 +1133,11 @@ outputs:
|
|||
|
||||
# QR_Lib:
|
||||
# This output creates a library containing a symbol and footprint for a QR code.
|
||||
# To refresh the generated symbols and footprints use the `update_qr` preflight.
|
||||
# The workflow is as follows:
|
||||
# - Create the symbol and footprints using this output.
|
||||
# - Use them in your schematic and PCB.
|
||||
# - To keep them updated add the `update_qr` preflight
|
||||
- name: 'qr_lib_example'
|
||||
comment: 'Generates a QR code symbol and footprint.'
|
||||
type: 'qr_lib'
|
||||
|
|
|
|||
|
|
@ -41,6 +41,11 @@ See the source code for more information.
|
|||
# Copyright (c) 2012 Takafumi Arakaki
|
||||
# All rights reserved.
|
||||
|
||||
# Copyright (c) 2022 Salvador E. Tropea
|
||||
# Copyright (c) 2022 Instituto Nacional de Tecnología Industrial
|
||||
# - Adapted to KiCad
|
||||
# - Added sexp_iter
|
||||
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
|
|
@ -250,7 +255,7 @@ def loads(string, **kwds):
|
|||
obj = parse(string, **kwds)
|
||||
if len(obj) != 1:
|
||||
raise SExpData("Not an s-expression file")
|
||||
return obj[0]
|
||||
return obj
|
||||
|
||||
|
||||
def dump(obj, filelike, **kwds):
|
||||
|
|
@ -707,3 +712,18 @@ def parse(string, **kwds):
|
|||
|
||||
"""
|
||||
return Parser(string, **kwds).parse()
|
||||
|
||||
|
||||
def sexp_iter(vect, path):
|
||||
"""
|
||||
Returns an iterator to filter all the elements described in the path.
|
||||
"""
|
||||
elems = path.split('/')
|
||||
total = len(elems)
|
||||
for i, e in enumerate(elems):
|
||||
iter = filter(lambda x: isinstance(x, list) and isinstance(x[0], Symbol) and x[0].value() == e, vect)
|
||||
if i == total-1:
|
||||
return iter
|
||||
vect = next(iter, None)
|
||||
if vect is None:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -1604,7 +1604,7 @@ class SchematicV6(Schematic):
|
|||
with open(fname, 'rt') as fh:
|
||||
error = None
|
||||
try:
|
||||
sch = load(fh)
|
||||
sch = load(fh)[0]
|
||||
except SExpData as e:
|
||||
error = str(e)
|
||||
if error:
|
||||
|
|
|
|||
|
|
@ -5,17 +5,13 @@
|
|||
# Project: KiBot (formerly KiPlot)
|
||||
import os
|
||||
from qrcodegen import QrCode
|
||||
from tempfile import NamedTemporaryFile
|
||||
from .gs import GS
|
||||
if GS.ki6(): # pragma: no cover (Ki6)
|
||||
from pcbnew import IU_PER_MM, S_POLYGON, wxPoint, ADD_MODE_APPEND
|
||||
ADD_APPEND = ADD_MODE_APPEND
|
||||
else:
|
||||
from pcbnew import IU_PER_MM, S_POLYGON, wxPoint, ADD_APPEND
|
||||
from .optionable import BaseOptions, Optionable
|
||||
from .out_base import VariantOptions
|
||||
from .error import KiPlotConfigurationError
|
||||
from .kicad.sexpdata import Symbol, dumps, Sep, load, SExpData
|
||||
from .kicad.sexpdata import Symbol, dumps, Sep, load, SExpData, sexp_iter
|
||||
from .kicad.v6_sch import DrawRectangleV6, PointXY, Stroke, Fill, SchematicFieldV6, FontEffects
|
||||
from .kiplot import load_board
|
||||
from .macros import macros, document, output_class # noqa: F401
|
||||
from . import log
|
||||
|
||||
|
|
@ -24,6 +20,46 @@ QR_ECCS = {'low': QrCode.Ecc.LOW,
|
|||
'quartile': QrCode.Ecc.QUARTILE,
|
||||
'high': QrCode.Ecc.HIGH}
|
||||
logger = log.get_logger()
|
||||
TO_SEPARATE = set(['kicad_pcb', 'general', 'title_block', 'layers', 'setup', 'pcbplotparams', 'net_class', 'module',
|
||||
'kicad_sch', 'lib_symbols', 'symbol', 'sheet', 'sheet_instances', 'symbol_instances'])
|
||||
|
||||
|
||||
def is_symbol(name, sexp):
|
||||
return isinstance(sexp, list) and len(sexp) >= 1 and isinstance(sexp[0], Symbol) and sexp[0].value() == name
|
||||
|
||||
|
||||
def make_separated(sexp):
|
||||
if not isinstance(sexp, list):
|
||||
return sexp
|
||||
if not isinstance(sexp[0], Symbol) or sexp[0].value() not in TO_SEPARATE:
|
||||
return sexp
|
||||
separated = []
|
||||
for s in sexp:
|
||||
separated.append(make_separated(s))
|
||||
if isinstance(s, list):
|
||||
separated.append(Sep())
|
||||
return separated
|
||||
|
||||
|
||||
def compute_size(qr, is_sch=True, use_mm=True):
|
||||
if is_sch:
|
||||
qrc = qr._code_sch
|
||||
full_size = qr.size_sch
|
||||
else:
|
||||
qrc = qr._code_pcb
|
||||
full_size = qr.size_pcb
|
||||
size = qrc.get_size()
|
||||
if not is_sch and qr.pcb_negative:
|
||||
size += 2
|
||||
if use_mm:
|
||||
full_size *= 1 if qr.size_units == 'millimeters' else 25.4
|
||||
center = round(full_size/2, 2)
|
||||
size_rect = round(full_size/size, 2)
|
||||
else:
|
||||
full_size *= 39.37007874 if qr.size_units == 'millimeters' else 1000
|
||||
center = round(full_size/2)
|
||||
size_rect = full_size/size
|
||||
return qrc, size, full_size, center, size_rect
|
||||
|
||||
|
||||
class QRCodeOptions(Optionable):
|
||||
|
|
@ -85,11 +121,7 @@ class QR_LibOptions(BaseOptions):
|
|||
|
||||
def symbol_k5(self, f, qr):
|
||||
# Compute the size
|
||||
qrc = qr._code_sch
|
||||
size = qrc.get_size()
|
||||
full_size = qr.size_sch * (39.37007874 if qr.size_units == 'millimeters' else 1000)
|
||||
center = round(full_size/2)
|
||||
size_rect = full_size/size
|
||||
qrc, size, full_size, center, size_rect = compute_size(qr, use_mm=False)
|
||||
# Generate the symbol
|
||||
f.write("#\n# {}\n#\n".format(qr.name))
|
||||
f.write("DEF {} {} 0 {} N N 1 F N\n".format(qr.name, '#'+self.reference, 0))
|
||||
|
|
@ -136,7 +168,7 @@ class QR_LibOptions(BaseOptions):
|
|||
fld.append(Sep())
|
||||
return fld
|
||||
|
||||
def qr_draw_fp(self, size, size_rect, center, qrc, negative, layer):
|
||||
def qr_draw_fp(self, size, size_rect, center, qrc, negative, layer, do_sep=True):
|
||||
mod = []
|
||||
for y in range(size):
|
||||
for x in range(size):
|
||||
|
|
@ -156,38 +188,11 @@ class QR_LibOptions(BaseOptions):
|
|||
rect.append([Symbol('layer'), Symbol(layer)])
|
||||
rect.append([Symbol('width'), 0])
|
||||
mod.append(rect)
|
||||
mod.append(Sep())
|
||||
if do_sep:
|
||||
mod.append(Sep())
|
||||
return mod
|
||||
|
||||
def qr_draw_fp_memory(self, m, size, size_rect, center, qrc, negative, layer):
|
||||
""" Create the QR drawings for the board in memory """
|
||||
for y in range(size):
|
||||
for x in range(size):
|
||||
if qrc.get_module(x-negative, y-negative) ^ negative:
|
||||
x_pos = round(x*size_rect-center, 2)
|
||||
y_pos = round(y*size_rect-center, 2)
|
||||
x_pos2 = round(x_pos+size_rect, 2)
|
||||
y_pos2 = round(y_pos+size_rect, 2)
|
||||
# Convert to Internal Units
|
||||
x_pos *= IU_PER_MM
|
||||
y_pos *= IU_PER_MM
|
||||
x_pos2 *= IU_PER_MM
|
||||
y_pos2 *= IU_PER_MM
|
||||
# Create a PCB polygon
|
||||
poly = VariantOptions.create_module_element(m)
|
||||
poly.SetShape(S_POLYGON)
|
||||
points = []
|
||||
points.append(wxPoint(x_pos, y_pos))
|
||||
points.append(wxPoint(x_pos, y_pos2))
|
||||
points.append(wxPoint(x_pos2, y_pos2))
|
||||
points.append(wxPoint(x_pos2, y_pos))
|
||||
poly.SetPolyPoints(points)
|
||||
poly.SetLayer(layer)
|
||||
poly.SetWidth(0)
|
||||
poly.thisown = 0
|
||||
m.AddNative(poly, ADD_APPEND)
|
||||
|
||||
def qr_draw_sym(self, size, size_rect, center, qrc):
|
||||
def qr_draw_sym(self, size, size_rect, center, qrc, do_sep=True):
|
||||
mod = []
|
||||
for y in range(size):
|
||||
for x in range(size):
|
||||
|
|
@ -202,18 +207,13 @@ class QR_LibOptions(BaseOptions):
|
|||
rect.fill = Fill()
|
||||
rect.fill.type = 'outline'
|
||||
mod.append(rect.write())
|
||||
mod.append(Sep())
|
||||
if do_sep:
|
||||
mod.append(Sep())
|
||||
return mod
|
||||
|
||||
def footprint(self, dir, qr):
|
||||
# Compute the size
|
||||
qrc = qr._code_pcb
|
||||
size = qrc.get_size()
|
||||
if qr.pcb_negative:
|
||||
size += 2
|
||||
full_size = qr.size_pcb * (1 if qr.size_units == 'millimeters' else 25.4)
|
||||
center = round(full_size/2, 2)
|
||||
size_rect = round(full_size/size, 2)
|
||||
qrc, size, full_size, center, size_rect = compute_size(qr, is_sch=False)
|
||||
# Generate the footprint
|
||||
fname = os.path.join(dir, qr.name+'.kicad_mod')
|
||||
mod = [Symbol('module'), Symbol(qr.name)]
|
||||
|
|
@ -276,11 +276,7 @@ class QR_LibOptions(BaseOptions):
|
|||
for qr in self.qrs:
|
||||
logger.debug('Adding symbol: '+qr.name)
|
||||
# Compute the size
|
||||
qrc = qr._code_sch
|
||||
size = qrc.get_size()
|
||||
full_size = qr.size_sch * (1 if qr.size_units == 'millimeters' else 25.4)
|
||||
center = round(full_size/2, 2)
|
||||
size_rect = round(full_size/size, 2)
|
||||
qrc, size, full_size, center, size_rect = compute_size(qr)
|
||||
# Symbol main attributes
|
||||
sym = [Symbol('symbol'), qr.name]
|
||||
sym.append([Symbol('pin_numbers'), Symbol('hide')])
|
||||
|
|
@ -315,52 +311,129 @@ class QR_LibOptions(BaseOptions):
|
|||
f.write(dumps(lib))
|
||||
f.write('\n')
|
||||
|
||||
def update_footprint(self, name, qr):
|
||||
logger.debug('Updating QR footprint: '+name)
|
||||
def update_footprint(self, name, sexp, qr):
|
||||
logger.debug('- Updating QR footprint: '+name)
|
||||
# Compute the size
|
||||
# TODO: don't repeat
|
||||
qrc = qr._code_pcb
|
||||
size = qrc.get_size()
|
||||
if qr.pcb_negative:
|
||||
size += 2
|
||||
full_size = qr.size_pcb * (1 if qr.size_units == 'millimeters' else 25.4)
|
||||
center = round(full_size/2, 2)
|
||||
size_rect = round(full_size/size, 2)
|
||||
# Replace any instance
|
||||
name = name.lower()
|
||||
for m in GS.get_modules():
|
||||
id = m.GetFPID()
|
||||
m_name = ('{}:{}'.format(id.GetLibNickname(), id.GetLibItemName())).lower()
|
||||
if name == m_name:
|
||||
ref = m.GetReference()
|
||||
logger.debug('- Updating '+ref)
|
||||
# Remove all the drawings
|
||||
for gi in m.GraphicalItems():
|
||||
if gi.GetClass() == 'MGRAPHIC':
|
||||
m.Remove(gi)
|
||||
# Add the updated version
|
||||
self.qr_draw_fp_memory(m, size, size_rect, center, qrc, qr.pcb_negative, GS.board.GetLayerID(qr.layer))
|
||||
qrc, size, full_size, center, size_rect = compute_size(qr, is_sch=False)
|
||||
# Remove old drawing
|
||||
sexp[:] = list(filter(lambda s: not is_symbol('fp_poly', s), sexp))
|
||||
# Add the new drawings
|
||||
sexp.extend(self.qr_draw_fp(size, size_rect, center, qrc, qr.pcb_negative, qr.layer, do_sep=False))
|
||||
|
||||
def load_k6_sheet(self, fname):
|
||||
def update_footprints(self, known_qrs):
|
||||
# Replace known QRs in the PCB
|
||||
updated = False
|
||||
pcb = self.load_sexp_file(GS.pcb_file)
|
||||
for iter in [sexp_iter(pcb, 'kicad_pcb/module'), sexp_iter(pcb, 'kicad_pcb/footprint')]:
|
||||
for s in iter:
|
||||
if len(s) < 2:
|
||||
continue
|
||||
if isinstance(s[1], Symbol):
|
||||
name = s[1].value().lower()
|
||||
else:
|
||||
name = s[1].lower()
|
||||
if name in known_qrs:
|
||||
updated = True
|
||||
self.update_footprint(name, s, known_qrs[name])
|
||||
# Save the resulting PCB
|
||||
if updated:
|
||||
# Make it readable
|
||||
separated = make_separated(pcb[0])
|
||||
# Save it to a temporal
|
||||
with NamedTemporaryFile(mode='wt', suffix='.kicad_pcb', delete=False) as f:
|
||||
logger.debug('- Saving updated PCB to: '+f.name)
|
||||
f.write(dumps(separated))
|
||||
f.write('\n')
|
||||
tmp_pcb = f.name
|
||||
# Reload it
|
||||
GS.board = None
|
||||
logger.debug('- Loading the temporal PCB')
|
||||
load_board(tmp_pcb)
|
||||
# Create a back-up and save it in the original place
|
||||
logger.debug('- Replacing the old PCB')
|
||||
os.remove(tmp_pcb)
|
||||
bkp = GS.pcb_file+'-bak'
|
||||
if os.path.isfile(bkp):
|
||||
os.remove(bkp)
|
||||
os.rename(GS.pcb_file, bkp)
|
||||
prl = None
|
||||
if GS.ki6():
|
||||
# KiCad 6 is destroying the PRL ...
|
||||
prl_name = GS.pcb_no_ext+'.kicad_prl'
|
||||
if os.path.isfile(prl_name):
|
||||
with open(prl_name, 'rt') as f:
|
||||
prl = f.read()
|
||||
GS.board.Save(GS.pcb_file)
|
||||
if prl:
|
||||
with open(prl_name, 'wt') as f:
|
||||
f.write(prl)
|
||||
|
||||
def update_symbol(self, name, c_name, sexp, qr):
|
||||
logger.debug('- Updating QR symbol: '+name)
|
||||
# Compute the size
|
||||
qrc, size, full_size, center, size_rect = compute_size(qr)
|
||||
# Create the new drawings
|
||||
sub_unit_name = c_name+"_1_1"
|
||||
sub_unit_sexp = [Symbol('symbol'), sub_unit_name]
|
||||
sub_unit_sexp.extend(self.qr_draw_sym(size, size_rect, center, qrc, do_sep=False))
|
||||
# Replace the old one
|
||||
for s in sexp_iter(sexp, 'symbol'):
|
||||
if len(s) >= 2 and isinstance(s[1], str) and s[1] == sub_unit_name:
|
||||
s[:] = list(sub_unit_sexp)
|
||||
|
||||
def update_symbols(self, fname, sexp, known_qrs):
|
||||
# Replace known QRs in the Schematic
|
||||
updated = False
|
||||
for s in sexp_iter(sexp, 'kicad_sch/lib_symbols/symbol'):
|
||||
if len(s) < 2 or not isinstance(s[1], str):
|
||||
continue
|
||||
name = s[1].lower()
|
||||
c_name = s[1].split(':')[1]
|
||||
if name in known_qrs:
|
||||
updated = True
|
||||
self.update_symbol(name, c_name, s, known_qrs[name])
|
||||
# Save the resulting Schematic
|
||||
if updated:
|
||||
# Make it readable
|
||||
separated = make_separated(sexp[0])
|
||||
# Create a back-up and save it in the original place
|
||||
logger.debug('- Replacing the old SCH')
|
||||
bkp = fname+'-bak'
|
||||
if os.path.isfile(bkp):
|
||||
os.remove(bkp)
|
||||
os.rename(fname, bkp)
|
||||
with open(fname, 'wt') as f:
|
||||
f.write(dumps(separated))
|
||||
f.write('\n')
|
||||
|
||||
def load_sexp_file(self, fname):
|
||||
with open(fname, 'rt') as fh:
|
||||
error = None
|
||||
try:
|
||||
sch = load(fh)
|
||||
ki_file = load(fh)
|
||||
except SExpData as e:
|
||||
error = str(e)
|
||||
if error:
|
||||
raise KiPlotConfigurationError(error)
|
||||
return sch
|
||||
return ki_file
|
||||
|
||||
def load_k6_sheets(self, fname, sheets={}):
|
||||
assert GS.sch_file is not None
|
||||
sheet = self.load_k6_sheet(fname)
|
||||
logger.debug('- Loading '+fname)
|
||||
sheet = self.load_sexp_file(fname)
|
||||
sheets[fname] = sheet
|
||||
if not isinstance(sheet, list) or sheet[0].value() != 'kicad_sch':
|
||||
if not is_symbol('kicad_sch', sheet[0]):
|
||||
raise KiPlotConfigurationError('No kicad_sch signature in '+fname)
|
||||
for e in sheet[1:]:
|
||||
if isinstance(e, list) and isinstance(e[0], Symbol) and e[0].value == 'sheet':
|
||||
logger.error(e)
|
||||
path = os.path.dirname(fname)
|
||||
for s in sexp_iter(sheet, 'kicad_sch/sheet'):
|
||||
sub_name = None
|
||||
for prop in sexp_iter(s, 'property'):
|
||||
if len(prop) > 2 and isinstance(prop[1], str) and isinstance(prop[2], str) and prop[1] == 'Sheet file':
|
||||
sub_name = prop[2]
|
||||
if sub_name is not None:
|
||||
sub_name = os.path.abspath(os.path.join(path, sub_name))
|
||||
if sub_name not in sheets:
|
||||
self.load_k6_sheets(os.path.join(path, sub_name), sheets)
|
||||
return sheets
|
||||
|
||||
def run(self, output):
|
||||
if self.use_sch_dir:
|
||||
|
|
@ -389,28 +462,34 @@ class QR_LibOptions(BaseOptions):
|
|||
self.footprint(dir_pretty, qr)
|
||||
# Update the files
|
||||
if self._parent._update_mode:
|
||||
# PCB
|
||||
assert GS.board is not None
|
||||
logger.debug('Updating the PCB and schematic')
|
||||
# Create a dict with the known QRs
|
||||
known_qrs = {}
|
||||
for qr in self.qrs:
|
||||
self.update_footprint(self.lib+':'+qr.name, qr)
|
||||
bkp = GS.pcb_file+'-bak'
|
||||
if os.path.isfile(bkp):
|
||||
os.remove(bkp)
|
||||
os.rename(GS.pcb_file, bkp)
|
||||
GS.board.Save(GS.pcb_file)
|
||||
name = self.lib+':'+qr.name
|
||||
known_qrs[name.lower()] = qr
|
||||
# TODO: Update fields
|
||||
# PCB
|
||||
self.update_footprints(known_qrs)
|
||||
# Schematic
|
||||
if GS.ki6():
|
||||
# KiCad 5 reads the lib, but KiCad 6 is more like the PCB
|
||||
# sheets = self.load_k6_sheets(GS.sch_file)
|
||||
pass
|
||||
# TODO: KiCad 6 is crashing when we delete the graphics
|
||||
assert GS.sch_file is not None
|
||||
sheets = self.load_k6_sheets(GS.sch_file)
|
||||
for k, v in sheets.items():
|
||||
self.update_symbols(k, v, known_qrs)
|
||||
|
||||
|
||||
@output_class
|
||||
class QR_Lib(BaseOutput): # noqa: F821
|
||||
""" QR_Lib
|
||||
Generates a QR code symbol and footprint.
|
||||
This output creates a library containing a symbol and footprint for a QR code. """
|
||||
This output creates a library containing a symbol and footprint for a QR code.
|
||||
To refresh the generated symbols and footprints use the `update_qr` preflight.
|
||||
The workflow is as follows:
|
||||
- Create the symbol and footprints using this output.
|
||||
- Use them in your schematic and PCB.
|
||||
- To keep them updated add the `update_qr` preflight """
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
with document:
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"board": {
|
||||
"active_layer": 0,
|
||||
"active_layer_preset": "",
|
||||
"active_layer_preset": "All Layers",
|
||||
"auto_track_width": true,
|
||||
"hidden_nets": [],
|
||||
"high_contrast_mode": 0,
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
35,
|
||||
36
|
||||
],
|
||||
"visible_layers": "003ffff_80000001",
|
||||
"visible_layers": "fffffff_ffffffff",
|
||||
"zone_display_mode": 0
|
||||
},
|
||||
"meta": {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
"board": {
|
||||
"design_settings": {
|
||||
"defaults": {
|
||||
"board_outline_line_width": 0.09999999999999999,
|
||||
"board_outline_line_width": 0.049999999999999996,
|
||||
"copper_line_width": 0.19999999999999998,
|
||||
"copper_text_italic": false,
|
||||
"copper_text_size_h": 1.5,
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
"height": 1.524,
|
||||
"width": 1.524
|
||||
},
|
||||
"silk_line_width": 0.15,
|
||||
"silk_line_width": 0.12,
|
||||
"silk_text_italic": false,
|
||||
"silk_text_size_h": 1.0,
|
||||
"silk_text_size_v": 1.0,
|
||||
|
|
@ -51,7 +51,6 @@
|
|||
"diff_pair_dimensions": [],
|
||||
"drc_exclusions": [],
|
||||
"meta": {
|
||||
"filename": "board_design_settings.json",
|
||||
"version": 2
|
||||
},
|
||||
"rule_severities": {
|
||||
|
|
@ -99,7 +98,7 @@
|
|||
"allow_microvias": false,
|
||||
"max_error": 0.005,
|
||||
"min_clearance": 0.0,
|
||||
"min_copper_edge_clearance": 0.0,
|
||||
"min_copper_edge_clearance": 0.01,
|
||||
"min_hole_clearance": 0.25,
|
||||
"min_hole_to_hole": 0.25,
|
||||
"min_microvia_diameter": 0.19999999999999998,
|
||||
|
|
@ -122,211 +121,6 @@
|
|||
"cvpcb": {
|
||||
"equivalence_files": []
|
||||
},
|
||||
"erc": {
|
||||
"erc_exclusions": [],
|
||||
"meta": {
|
||||
"version": 0
|
||||
},
|
||||
"pin_map": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
1,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
0,
|
||||
2,
|
||||
1,
|
||||
1,
|
||||
0,
|
||||
0,
|
||||
1,
|
||||
0,
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
2
|
||||
],
|
||||
[
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2,
|
||||
2
|
||||
]
|
||||
],
|
||||
"rule_severities": {
|
||||
"bus_definition_conflict": "error",
|
||||
"bus_entry_needed": "error",
|
||||
"bus_label_syntax": "error",
|
||||
"bus_to_bus_conflict": "error",
|
||||
"bus_to_net_conflict": "error",
|
||||
"different_unit_footprint": "error",
|
||||
"different_unit_net": "error",
|
||||
"duplicate_reference": "error",
|
||||
"duplicate_sheet_names": "error",
|
||||
"extra_units": "error",
|
||||
"global_label_dangling": "warning",
|
||||
"hier_label_mismatch": "error",
|
||||
"label_dangling": "error",
|
||||
"lib_symbol_issues": "warning",
|
||||
"multiple_net_names": "warning",
|
||||
"net_not_bus_member": "warning",
|
||||
"no_connect_connected": "warning",
|
||||
"no_connect_dangling": "warning",
|
||||
"pin_not_connected": "error",
|
||||
"pin_not_driven": "error",
|
||||
"pin_to_pin": "warning",
|
||||
"power_pin_not_driven": "error",
|
||||
"similar_labels": "warning",
|
||||
"unannotated": "error",
|
||||
"unit_value_mismatch": "error",
|
||||
"unresolved_variable": "error",
|
||||
"wire_dangling": "error"
|
||||
}
|
||||
},
|
||||
"libraries": {
|
||||
"pinned_footprint_libs": [],
|
||||
"pinned_symbol_libs": []
|
||||
|
|
@ -372,43 +166,9 @@
|
|||
"page_layout_descr_file": ""
|
||||
},
|
||||
"schematic": {
|
||||
"annotate_start_num": 0,
|
||||
"drawing": {
|
||||
"default_line_thickness": 6.0,
|
||||
"default_text_size": 50.0,
|
||||
"field_names": [],
|
||||
"intersheets_ref_own_page": false,
|
||||
"intersheets_ref_prefix": "",
|
||||
"intersheets_ref_short": false,
|
||||
"intersheets_ref_show": false,
|
||||
"intersheets_ref_suffix": "",
|
||||
"junction_size_choice": 3,
|
||||
"label_size_ratio": 0.25,
|
||||
"pin_symbol_size": 25.0,
|
||||
"text_offset_ratio": 0.08
|
||||
},
|
||||
"legacy_lib_dir": "",
|
||||
"legacy_lib_list": [],
|
||||
"meta": {
|
||||
"version": 1
|
||||
},
|
||||
"net_format_name": "",
|
||||
"page_layout_descr_file": "",
|
||||
"plot_directory": "",
|
||||
"spice_adjust_passive_values": false,
|
||||
"spice_external_command": "spice \"%I\"",
|
||||
"subpart_first_id": 65,
|
||||
"subpart_id_separator": 0
|
||||
"legacy_lib_list": []
|
||||
},
|
||||
"sheets": [
|
||||
[
|
||||
"8efee08b-b92e-4ba6-8722-c058e18114fe",
|
||||
""
|
||||
],
|
||||
[
|
||||
"00000000-0000-0000-0000-000061d2163a",
|
||||
"Subsheet"
|
||||
]
|
||||
],
|
||||
"sheets": [],
|
||||
"text_variables": {}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -980,5 +980,12 @@ def test_qr_lib_1(test_dir):
|
|||
bogus = os.path.join(bd, 'qr_test/'+f+'.bogus')
|
||||
if os.path.isfile(bogus):
|
||||
shutil.copy2(bogus, os.path.join(bd, 'qr_test/'+f))
|
||||
os.remove(os.path.join(bd, 'qr_test/qr_test.kicad_pcb-bak'))
|
||||
os.remove(os.path.join(bd, 'qr_test/qr_test.pro-bak'))
|
||||
if context.ki5():
|
||||
os.remove(os.path.join(bd, 'qr_test/qr_test.pro-bak'))
|
||||
else:
|
||||
os.remove(os.path.join(bd, 'qr_test/qr_test.kicad_sch-bak'))
|
||||
os.remove(os.path.join(bd, 'qr_test/sub_1.kicad_sch-bak'))
|
||||
bkp = os.path.join(bd, 'qr_test/qr_test.kicad_pcb-bak')
|
||||
if os.path.isfile(bkp):
|
||||
# Not always there, pcbnew_do can remove it
|
||||
os.remove(bkp)
|
||||
|
|
|
|||
Loading…
Reference in New Issue