diff --git a/common/gbr_metadata.cpp b/common/gbr_metadata.cpp
index 7ffc2cfb41..cde69921bd 100644
--- a/common/gbr_metadata.cpp
+++ b/common/gbr_metadata.cpp
@@ -269,6 +269,11 @@ std::string GBR_APERTURE_METADATA::FormatAttribute( GBR_APERTURE_ATTRIB aAttribu
attribute_string = "TA.AperFunction,ComponentDrill";
break;
+ case GBR_APERTURE_ATTRIB_PRESSFITDRILL:
+ // print info associated to a flashed component pad with pressfit option in drill files
+ attribute_string = "TA.AperFunction,ComponentDrill,PressFit";
+ break;
+
// print info associated to a component oblong pad hole in drill files
// Same as a round pad hole, but is a specific aperture in drill file and
// a G04 comment is added to the aperture function
diff --git a/common/pcb.keywords b/common/pcb.keywords
index ad278590d2..b9a9b6aa0e 100644
--- a/common/pcb.keywords
+++ b/common/pcb.keywords
@@ -263,6 +263,7 @@ pad_prop_castellated
pad_prop_testpoint
pad_prop_heatsink
pad_prop_mechanical
+pad_prop_pressfit
padstack
padvia
prefer_zone_connections
diff --git a/include/gbr_metadata.h b/include/gbr_metadata.h
index a3e90a8203..42ad7936a2 100644
--- a/include/gbr_metadata.h
+++ b/include/gbr_metadata.h
@@ -137,6 +137,10 @@ public:
/// Aperture used for castellated pads in drill files.
GBR_APERTURE_ATTRIB_CASTELLATEDDRILL,
+ /// Aperture used for pressfit pads in drill files.
+ /// this is similar to GBR_APERTURE_ATTRIB_COMPONENTPAD with optional PressFit field
+ GBR_APERTURE_ATTRIB_PRESSFITDRILL,
+
GBR_APERTURE_ATTRIB_VIADRILL, ///< Aperture used for via holes in drill files.
GBR_APERTURE_ATTRIB_CMP_DRILL, ///< Aperture used for pad holes in drill files.
diff --git a/pcbnew/dialogs/dialog_gendrill.cpp b/pcbnew/dialogs/dialog_gendrill.cpp
index 164d8d5abe..417d77e648 100644
--- a/pcbnew/dialogs/dialog_gendrill.cpp
+++ b/pcbnew/dialogs/dialog_gendrill.cpp
@@ -110,6 +110,8 @@ DIALOG_GENDRILL::DIALOG_GENDRILL( PCB_EDIT_FRAME* aPcbEditFrame, JOB_EXPORT_PCB_
bool DIALOG_GENDRILL::TransferDataToWindow()
{
+ m_messagesBox->Clear();
+
if( !m_job )
{
updatePrecisionOptions();
@@ -292,6 +294,7 @@ void DIALOG_GENDRILL::genDrillAndMapFiles( bool aGenDrill, bool aGenMap, bool aG
updateConfig(); // set params and Save drill options
m_pcbEditFrame->ClearMsgPanel();
+ m_messagesBox->Clear();
WX_TEXT_CTRL_REPORTER reporter( m_messagesBox );
const PLOT_FORMAT filefmt[] = {
@@ -395,6 +398,7 @@ void DIALOG_GENDRILL::onGenReportFile( wxCommandEvent& event )
if( dlg.ShowModal() == wxID_CANCEL )
return;
+ m_messagesBox->Clear();
bool success;
// Info is slightly different between Excellon and Gerber
diff --git a/pcbnew/dialogs/dialog_pad_properties.cpp b/pcbnew/dialogs/dialog_pad_properties.cpp
index ae459da7a7..45c082c4a8 100644
--- a/pcbnew/dialogs/dialog_pad_properties.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties.cpp
@@ -805,6 +805,7 @@ void DIALOG_PAD_PROPERTIES::initValues()
case PAD_PROP::HEATSINK: m_choiceFabProperty->SetSelection( 5 ); break;
case PAD_PROP::CASTELLATED: m_choiceFabProperty->SetSelection( 6 ); break;
case PAD_PROP::MECHANICAL: m_choiceFabProperty->SetSelection( 7 ); break;
+ case PAD_PROP::PRESSFIT: m_choiceFabProperty->SetSelection( 8 ); break;
}
// Ensure the pad property is compatible with the pad type
@@ -1700,6 +1701,7 @@ PAD_PROP DIALOG_PAD_PROPERTIES::getSelectedProperty()
case 5: prop = PAD_PROP::HEATSINK; break;
case 6: prop = PAD_PROP::CASTELLATED; break;
case 7: prop = PAD_PROP::MECHANICAL; break;
+ case 8: prop = PAD_PROP::PRESSFIT; break;
}
return prop;
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.cpp b/pcbnew/dialogs/dialog_pad_properties_base.cpp
index 9575879c5b..2f9724dea9 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.cpp
+++ b/pcbnew/dialogs/dialog_pad_properties_base.cpp
@@ -613,7 +613,7 @@ DIALOG_PAD_PROPERTIES_BASE::DIALOG_PAD_PROPERTIES_BASE( wxWindow* parent, wxWind
m_middleBoxSizer->Add( 0, 2, 0, wxEXPAND, 5 );
- wxString m_choiceFabPropertyChoices[] = { _("None"), _("BGA pad"), _("Fiducial, local to footprint"), _("Fiducial, global to board"), _("Test point pad"), _("Heatsink pad"), _("Castellated pad (through hole only)"), _("Mechanical") };
+ wxString m_choiceFabPropertyChoices[] = { _("None"), _("BGA pad"), _("Fiducial, local to footprint"), _("Fiducial, global to board"), _("Test point pad"), _("Heatsink pad"), _("Castellated pad (through hole only)"), _("Mechanical"), _("Press-fit (through hole only)") };
int m_choiceFabPropertyNChoices = sizeof( m_choiceFabPropertyChoices ) / sizeof( wxString );
m_choiceFabProperty = new wxChoice( m_panelGeneral, wxID_ANY, wxDefaultPosition, wxDefaultSize, m_choiceFabPropertyNChoices, m_choiceFabPropertyChoices, 0 );
m_choiceFabProperty->SetSelection( 0 );
diff --git a/pcbnew/dialogs/dialog_pad_properties_base.fbp b/pcbnew/dialogs/dialog_pad_properties_base.fbp
index f7158dd9df..1bffcb03bf 100644
--- a/pcbnew/dialogs/dialog_pad_properties_base.fbp
+++ b/pcbnew/dialogs/dialog_pad_properties_base.fbp
@@ -7477,7 +7477,7 @@
1
0
- "None" "BGA pad" "Fiducial, local to footprint" "Fiducial, global to board" "Test point pad" "Heatsink pad" "Castellated pad (through hole only)" "Mechanical"
+ "None" "BGA pad" "Fiducial, local to footprint" "Fiducial, global to board" "Test point pad" "Heatsink pad" "Castellated pad (through hole only)" "Mechanical" "Press-fit (through hole only)"
1
1
diff --git a/pcbnew/exporters/gen_drill_report_files.cpp b/pcbnew/exporters/gen_drill_report_files.cpp
index 318c2c9adc..b95d8290ff 100644
--- a/pcbnew/exporters/gen_drill_report_files.cpp
+++ b/pcbnew/exporters/gen_drill_report_files.cpp
@@ -362,19 +362,29 @@ bool GENDRILL_WRITER_BASE::genDrillMapFile( const wxString& aFullFileName, PLOT_
diameter_in_inches( tool.m_Diameter ) );
msg = From_UTF8( line );
+ const char* extra_info;
+
+ // Add more info for holes with specific constraints (castelleted, pressfit)
+ // note: only PTH pads have this option
+ if( tool.m_HoleAttribute == HOLE_ATTRIBUTE::HOLE_PAD_CASTELLATED )
+ extra_info = ", castellated";
+ else if( tool.m_HoleAttribute == HOLE_ATTRIBUTE::HOLE_PAD_PRESSFIT )
+ extra_info = ", press-fit";
+ else
+ extra_info = "";
// Now list how many holes and ovals are associated with each drill.
if( ( tool.m_TotalCount == 1 ) && ( tool.m_OvalCount == 0 ) )
- snprintf( line, sizeof(line), "(1 hole)" );
+ snprintf( line, sizeof(line), "(1 hole%s)", extra_info );
else if( tool.m_TotalCount == 1 ) // && ( toolm_OvalCount == 1 )
- snprintf( line, sizeof(line), "(1 slot)" );
+ snprintf( line, sizeof(line), "(1 slot%s)", extra_info );
else if( tool.m_OvalCount == 0 )
- snprintf( line, sizeof(line), "(%d holes)", tool.m_TotalCount );
+ snprintf( line, sizeof(line), "(%d holes%s)", tool.m_TotalCount, extra_info );
else if( tool.m_OvalCount == 1 )
- snprintf( line, sizeof(line), "(%d holes + 1 slot)", tool.m_TotalCount - 1 );
+ snprintf( line, sizeof(line), "(%d holes + 1 slot%s)", tool.m_TotalCount - 1, extra_info );
else // if ( toolm_OvalCount > 1 )
- snprintf( line, sizeof(line), "(%d holes + %d slots)", tool.m_TotalCount - tool.m_OvalCount,
- tool.m_OvalCount );
+ snprintf( line, sizeof(line), "(%d holes + %d slots%s)", tool.m_TotalCount - tool.m_OvalCount,
+ tool.m_OvalCount, extra_info );
msg += From_UTF8( line );
@@ -550,15 +560,23 @@ unsigned GENDRILL_WRITER_BASE::printToolSummary( OUTPUTFORMATTER& out, bool aSum
// Now list how many holes and ovals are associated with each drill.
if( ( tool.m_TotalCount == 1 ) && ( tool.m_OvalCount == 0 ) )
- out.Print( 0, "(1 hole)\n" );
+ out.Print( 0, "(1 hole" );
else if( tool.m_TotalCount == 1 )
- out.Print( 0, "(1 hole) (with 1 slot)\n" );
+ out.Print( 0, "(1 hole) (with 1 slot" );
else if( tool.m_OvalCount == 0 )
- out.Print( 0, "(%d holes)\n", tool.m_TotalCount );
+ out.Print( 0, "(%d holes)", tool.m_TotalCount );
else if( tool.m_OvalCount == 1 )
- out.Print( 0, "(%d holes) (with 1 slot)\n", tool.m_TotalCount );
+ out.Print( 0, "(%d holes) (with 1 slot", tool.m_TotalCount );
else // tool.m_OvalCount > 1
- out.Print( 0, "(%d holes) (with %d slots)\n", tool.m_TotalCount, tool.m_OvalCount );
+ out.Print( 0, "(%d holes) (with %d slots", tool.m_TotalCount, tool.m_OvalCount );
+
+ if( tool.m_HoleAttribute == HOLE_ATTRIBUTE::HOLE_PAD_CASTELLATED )
+ out.Print( 0, ", castellated" );
+
+ if( tool.m_HoleAttribute == HOLE_ATTRIBUTE::HOLE_PAD_PRESSFIT )
+ out.Print( 0, ", press-fit" );
+
+ out.Print( 0, ")\n");
totalHoleCount += tool.m_TotalCount;
}
diff --git a/pcbnew/exporters/gendrill_Excellon_writer.cpp b/pcbnew/exporters/gendrill_Excellon_writer.cpp
index f90261648c..dc851985e9 100644
--- a/pcbnew/exporters/gendrill_Excellon_writer.cpp
+++ b/pcbnew/exporters/gendrill_Excellon_writer.cpp
@@ -176,9 +176,18 @@ void EXCELLON_WRITER::writeHoleAttribute( HOLE_ATTRIBUTE aAttribute )
break;
case HOLE_ATTRIBUTE::HOLE_PAD:
+ //case HOLE_ATTRIBUTE::HOLE_PAD_CASTELLATED:
fprintf( m_file, "; #@! TA.AperFunction,Plated,PTH,ComponentDrill\n" );
break;
+ case HOLE_ATTRIBUTE::HOLE_PAD_CASTELLATED:
+ fprintf( m_file, "; #@! TA.AperFunction,Plated,PTH,CastelletedDrill\n" );
+ break;
+
+ case HOLE_ATTRIBUTE::HOLE_PAD_PRESSFIT:
+ fprintf( m_file, "; #@! TA.AperFunction,Plated,PTH,ComponentDrill,PressFit\n" );
+ break;
+
case HOLE_ATTRIBUTE::HOLE_MECHANICAL:
fprintf( m_file, "; #@! TA.AperFunction,NonPlated,NPTH,ComponentDrill\n" );
break;
diff --git a/pcbnew/exporters/gendrill_file_writer_base.cpp b/pcbnew/exporters/gendrill_file_writer_base.cpp
index 7a46369c2b..852fe1fc33 100644
--- a/pcbnew/exporters/gendrill_file_writer_base.cpp
+++ b/pcbnew/exporters/gendrill_file_writer_base.cpp
@@ -147,9 +147,20 @@ void GENDRILL_WRITER_BASE::buildHolesList( DRILL_LAYER_PAIR aLayerPair, bool aGe
continue;
new_hole.m_ItemParent = pad;
- new_hole.m_Hole_NotPlated = (pad->GetAttribute() == PAD_ATTRIB::NPTH);
- new_hole.m_HoleAttribute = new_hole.m_Hole_NotPlated ? HOLE_ATTRIBUTE::HOLE_MECHANICAL
- : HOLE_ATTRIBUTE::HOLE_PAD;
+ new_hole.m_Hole_NotPlated = ( pad->GetAttribute() == PAD_ATTRIB::NPTH );
+
+ if( new_hole.m_Hole_NotPlated )
+ new_hole.m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_MECHANICAL;
+ else
+ {
+ if( pad->GetProperty() == PAD_PROP::CASTELLATED )
+ new_hole.m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_PAD_CASTELLATED;
+ else if( pad->GetProperty() == PAD_PROP::PRESSFIT )
+ new_hole.m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_PAD_PRESSFIT;
+ else
+ new_hole.m_HoleAttribute = HOLE_ATTRIBUTE::HOLE_PAD;
+ }
+
new_hole.m_Tool_Reference = -1; // Flag is: Not initialized
new_hole.m_Hole_Orient = pad->GetOrientation();
new_hole.m_Hole_Shape = 0; // hole shape: round
diff --git a/pcbnew/exporters/gendrill_file_writer_base.h b/pcbnew/exporters/gendrill_file_writer_base.h
index b93a095e4f..2efa5d9c83 100644
--- a/pcbnew/exporters/gendrill_file_writer_base.h
+++ b/pcbnew/exporters/gendrill_file_writer_base.h
@@ -43,11 +43,13 @@ class BOARD_ITEM;
// in NC drill files
enum class HOLE_ATTRIBUTE
{
- HOLE_UNKNOWN, // uninitialized type
- HOLE_VIA_THROUGH, // a via hole (always plated) from top to bottom
- HOLE_VIA_BURIED, // a via hole (always plated) not through hole
- HOLE_PAD, // a plated or not plated pad hole
- HOLE_MECHANICAL // a mechanical pad (provided, not used)
+ HOLE_UNKNOWN, // uninitialized type
+ HOLE_VIA_THROUGH, // a via hole (always plated) from top to bottom
+ HOLE_VIA_BURIED, // a via hole (always plated) not through hole
+ HOLE_PAD, // a plated or not plated pad hole
+ HOLE_PAD_CASTELLATED, // a plated castelleted pad hole
+ HOLE_PAD_PRESSFIT, // a plated press-fit pad hole
+ HOLE_MECHANICAL // a mechanical pad (provided, not used)
};
// Via Protection features according to IPC-4761.
diff --git a/pcbnew/exporters/gendrill_gerber_writer.cpp b/pcbnew/exporters/gendrill_gerber_writer.cpp
index d53d5dd45d..1b78df61bb 100644
--- a/pcbnew/exporters/gendrill_gerber_writer.cpp
+++ b/pcbnew/exporters/gendrill_gerber_writer.cpp
@@ -390,6 +390,11 @@ int GERBER_WRITER::createDrillFile( wxString& aFullFilename, bool aIsNpth,
gbr_metadata.SetApertureAttrib(
GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CASTELLATEDDRILL );
}
+ else if( pad->GetProperty() == PAD_PROP::PRESSFIT )
+ {
+ gbr_metadata.SetApertureAttrib(
+ GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_PRESSFITDRILL );
+ }
else
{
// Good practice of oblong pad holes (slots) is to use a specific aperture for
diff --git a/pcbnew/pad.cpp b/pcbnew/pad.cpp
index 0d108523d6..8ff2a0a2e7 100644
--- a/pcbnew/pad.cpp
+++ b/pcbnew/pad.cpp
@@ -1400,6 +1400,7 @@ void PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector&
case PAD_PROP::HEATSINK: props += _( "Heat sink" ); break;
case PAD_PROP::CASTELLATED: props += _( "Castellated" ); break;
case PAD_PROP::MECHANICAL: props += _( "Mechanical" ); break;
+ case PAD_PROP::PRESSFIT: props += _( "Press-fit" ); break;
}
// TODO(JE) How to show complex padstack info in the message panel
@@ -2309,6 +2310,10 @@ void PAD::CheckPad( UNITS_PROVIDER* aUnitsProvider, bool aForPadProperties,
if( GetProperty() == PAD_PROP::MECHANICAL && GetAttribute() != PAD_ATTRIB::PTH )
aErrorHandler( DRCE_PADSTACK, _( "('mechanical' property is for PTH pads)" ) );
+ if( GetProperty() == PAD_PROP::PRESSFIT
+ && ( GetAttribute() != PAD_ATTRIB::PTH || !HasDrilledHole() ) )
+ aErrorHandler( DRCE_PADSTACK, _( "('press-fit' property is for PTH pads with round holes)" ) );
+
switch( GetAttribute() )
{
case PAD_ATTRIB::NPTH: // Not plated, but through hole, a hole is expected
@@ -2745,7 +2750,8 @@ static struct PAD_DESC
.Map( PAD_PROP::TESTPOINT, _HKI( "Test point pad" ) )
.Map( PAD_PROP::HEATSINK, _HKI( "Heatsink pad" ) )
.Map( PAD_PROP::CASTELLATED, _HKI( "Castellated pad" ) )
- .Map( PAD_PROP::MECHANICAL, _HKI( "Mechanical pad" ) );
+ .Map( PAD_PROP::MECHANICAL, _HKI( "Mechanical pad" ) )
+ .Map( PAD_PROP::PRESSFIT, _HKI( "Press-fit pad" ) );
ENUM_MAP::Instance()
.Map( PAD_DRILL_SHAPE::CIRCLE, _HKI( "Round" ) )
diff --git a/pcbnew/padstack.h b/pcbnew/padstack.h
index e182fa68f5..983499e183 100644
--- a/pcbnew/padstack.h
+++ b/pcbnew/padstack.h
@@ -104,6 +104,7 @@ enum class PAD_PROP
HEATSINK, ///< a pad used as heat sink, usually in SMD footprints
CASTELLATED, ///< a pad with a castellated through hole
MECHANICAL, ///< a pad used for mechanical support
+ PRESSFIT ///< a PTH with a hole diameter with tight tolerances for press fit pin
};
diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
index 243faebc6d..6f91d61c66 100644
--- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
+++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr.cpp
@@ -1526,6 +1526,7 @@ void PCB_IO_KICAD_SEXPR::format( const PAD* aPad ) const
case PAD_PROP::HEATSINK: property = "pad_prop_heatsink"; break;
case PAD_PROP::CASTELLATED: property = "pad_prop_castellated"; break;
case PAD_PROP::MECHANICAL: property = "pad_prop_mechanical"; break;
+ case PAD_PROP::PRESSFIT: property = "pad_prop_pressfit"; break;
default:
THROW_IO_ERROR( wxString::Format( wxT( "unknown pad property: %d" ),
diff --git a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
index a8af826560..145bc0adf1 100644
--- a/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
+++ b/pcbnew/pcb_io/kicad_sexpr/pcb_io_kicad_sexpr_parser.cpp
@@ -5506,6 +5506,7 @@ PAD* PCB_IO_KICAD_SEXPR_PARSER::parsePAD( FOOTPRINT* aParent )
case T_pad_prop_castellated: pad->SetProperty( PAD_PROP::CASTELLATED ); break;
case T_pad_prop_heatsink: pad->SetProperty( PAD_PROP::HEATSINK ); break;
case T_pad_prop_mechanical: pad->SetProperty( PAD_PROP::MECHANICAL ); break;
+ case T_pad_prop_pressfit: pad->SetProperty( PAD_PROP::PRESSFIT ); break;
case T_none: pad->SetProperty( PAD_PROP::NONE ); break;
case T_RIGHT: break;
diff --git a/pcbnew/plot_brditems_plotter.cpp b/pcbnew/plot_brditems_plotter.cpp
index ba235db9ea..6d8e96bc14 100644
--- a/pcbnew/plot_brditems_plotter.cpp
+++ b/pcbnew/plot_brditems_plotter.cpp
@@ -258,6 +258,7 @@ void BRDITEMS_PLOTTER::PlotPad( const PAD* aPad, PCB_LAYER_ID aLayer, const COLO
metadata.SetApertureAttrib( GBR_APERTURE_METADATA::GBR_APERTURE_ATTRIB_CASTELLATEDPAD );
break;
+ case PAD_PROP::PRESSFIT: // used only in drill files
case PAD_PROP::NONE:
case PAD_PROP::MECHANICAL:
break;