Commit 22affc67 authored by CHARRAS's avatar CHARRAS

Better support for micro vias. infos in changelog

parent 48dc3d06
......@@ -9,7 +9,18 @@ email address.
2008-Jan-25 UPDATE Jean-Pierre Charras <jean-pierre.charras@inpg.fr>
================================================================================
+pcbnew:
void Change_Side_Module( MODULE* Module, wxDC* DC ) is now member of class BOARD.
- void Change_Side_Module( MODULE* Module, wxDC* DC ) is now member of class BOARD.
- Better support for micro vias and buried vias (drill files now are useable for board manufacturers)
But not yet tested by a board manufacturer. Be carefull.
Todo: tools to conversion between via through and buried via and buried viad optimisation.
But must works for micro vias (needed for my next board)
(in pcbnew micro vias are blind vias between 2 adjacent layers: micro vias must be enabled
in Dimensions/track and via menu, and placed by ctrl v.
They are intended to connect small pitch BGA pins to the inner layer, and can be drilled by laser
if the hole diameter is small < 0.2mm. A laser can only drill a hole between 2 adjacent layers ).
** Currently use buried via for tests only, not for production **.
2008-Jan-24 UPDATE Dick Hollenbeck <dick@softplc.com>
......
......@@ -153,7 +153,7 @@ private:
void UpdatePrecisionOptions( wxCommandEvent& event );
void UpdateConfig();
void Write_Excellon_Header( FILE * aFile);
void GenDrillReport( const wxString aFileName, std::vector<DRILL_TOOL> & buffer );
void GenDrillReport( const wxString aFileName );
int Create_Drill_File_EXCELLON( std::vector<HOLE_INFO> & aHoleListBuffer,
std::vector<DRILL_TOOL> & aToolListBuffer );
int Gen_Liste_Tools( std::vector<DRILL_TOOL> & buffer, bool print_header );
......
......@@ -285,8 +285,8 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, w
fputs( line, aFile );
// Now list how many holes and ovals are associated with each drill.
if( ( aToolListBuffer[ii].m_TotalCount == 1 ) &&
( aToolListBuffer[ii].m_OvalCount == 0 ) )
if( ( aToolListBuffer[ii].m_TotalCount == 1 )
&& ( aToolListBuffer[ii].m_OvalCount == 0 ) )
sprintf( line, "(1 hole)\n" );
else if( aToolListBuffer[ii].m_TotalCount == 1 ) // && ( buffer[ii]m_OvalCount == 1 )
sprintf( line, "(1 hole) (with 1 oblong)\n" );
......@@ -319,8 +319,8 @@ void GenDrillMapFile( BOARD* aPcb, FILE* aFile, const wxString& aFullFileName, w
msg = CONV_FROM_UTF8( line );
// Now list how many holes and ovals are associated with each drill.
if( ( aToolListBuffer[ii].m_TotalCount == 1 ) &&
( aToolListBuffer[ii].m_OvalCount == 0 ) )
if( ( aToolListBuffer[ii].m_TotalCount == 1 )
&& ( aToolListBuffer[ii].m_OvalCount == 0 ) )
sprintf( line, "(1 hole)" );
else if( aToolListBuffer[ii].m_TotalCount == 1 ) // && ( aToolListBuffer[ii]m_OvalCount == 1 )
sprintf( line, "(1 hole) (with 1 oblong)" );
......@@ -610,8 +610,11 @@ void PlotOvalDrillSymbol( const wxPoint& position, const wxSize& size, int orien
/**************************************************************************************************/
void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
std::vector<DRILL_TOOL>& aToolListBuffer, bool aUnit_Drill_is_Inch )
void GenDrillReportFile( FILE* aFile, BOARD* aPcb, const wxString& aBoardFilename,
bool aUnit_Drill_is_Inch,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer
)
/*************************************************************************************************/
/*
......@@ -620,6 +623,10 @@ void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
{
unsigned TotalHoleCount;
char line[1024];
int layer1 = COPPER_LAYER_N;
int layer2 = LAYER_CMP_N;
bool gen_through_holes = true;
fprintf( aFile, "Drill report for %s\n", CONV_TO_UTF8( aBoardFilename ) );
fprintf( aFile, "Created on %s\n", DateAndTime( line ) );
......@@ -630,8 +637,41 @@ void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
else
fputs( "Selected Drill Unit: Metric (mm)\n\n", aFile );
/* build hole lists:
* 1 - through holes
* 2 - for partial holes only: by layer pair
*/
for( ; ; )
{
Build_Holes_List( aPcb,
aHoleListBuffer,
aToolListBuffer,
layer1,
layer2,
gen_through_holes ? false : true );
TotalHoleCount = 0;
if( gen_through_holes )
{
sprintf( line, "Drill report for through holes :\n" );
}
else
{
if ( layer1 == COPPER_LAYER_N ) // First partial hole list
{
sprintf( line, "Drill report for buried and blind vias :\n\n");
fputs( line, aFile );
}
sprintf( line, "Drill report for holes from layer %s to layer %s\n",
CONV_TO_UTF8 (aPcb->GetLayerName(layer1) ),
CONV_TO_UTF8 (aPcb->GetLayerName(layer2) ) );
}
fputs( line, aFile );
for( unsigned ii = 0; ii < aToolListBuffer.size(); ii++ )
{
// List the tool number assigned to each drill,
......@@ -650,7 +690,8 @@ void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
fputs( line, aFile );
// Now list how many holes and ovals are associated with each drill.
if( ( aToolListBuffer[ii].m_TotalCount == 1 ) && ( aToolListBuffer[ii].m_OvalCount == 0 ) )
if( ( aToolListBuffer[ii].m_TotalCount == 1 )
&& ( aToolListBuffer[ii].m_OvalCount == 0 ) )
sprintf( line, "(1 hole)\n" );
else if( aToolListBuffer[ii].m_TotalCount == 1 )
sprintf( line, "(1 hole) (with 1 oblong)\n" );
......@@ -669,8 +710,24 @@ void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
TotalHoleCount += aToolListBuffer[ii].m_TotalCount;
}
sprintf( line, "\ntotal holes count %d\n", TotalHoleCount );
sprintf( line, "\ntotal holes count %d\n\n\n", TotalHoleCount );
fputs( line, aFile );
if( g_DesignSettings.m_CopperLayerCount <= 2 )
break;
if( gen_through_holes )
layer2 = layer1 + 1;
else
{
if( layer2 >= LAYER_CMP_N ) // no more layer pair to consider
break;
layer1++; layer2++; // use next layer pair
if( layer2 == g_DesignSettings.m_CopperLayerCount - 1 ) // The last layer is reached
layer2 = LAYER_CMP_N; // the last layer is always the component layer
}
gen_through_holes = false;
}
fclose( aFile );
}
......@@ -17,14 +17,15 @@ using namespace std;
/* Local Functions */
/* Compare function used for sorting holes by increasing diameter value
* and X value
*/
*/
static bool CmpHoleDiameterValue( const HOLE_INFO& a, const HOLE_INFO& b )
{
if ( a.m_Hole_Diameter != b.m_Hole_Diameter )
if( a.m_Hole_Diameter != b.m_Hole_Diameter )
return a.m_Hole_Diameter < b.m_Hole_Diameter;
if ( a.m_Hole_Pos_X != b.m_Hole_Pos_X )
if( a.m_Hole_Pos_X != b.m_Hole_Pos_X )
return a.m_Hole_Pos_X < b.m_Hole_Pos_X;
return a.m_Hole_Pos_Y < b.m_Hole_Pos_Y;
}
......@@ -33,18 +34,20 @@ static bool CmpHoleDiameterValue( const HOLE_INFO& a, const HOLE_INFO& b )
/**
* Function BuildHolesList
* Create the list of holes and tools for a given board
* The list is sorted by incraesin drill values
* The list is sorted by increasing drill values
* Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because pad holes are always through holes)
* @param Pcb : the given board
* @param aHoleListBuffer : the std::vector<HOLE_INFO> to fill with pcb holes info
* @param aToolListBuffer : the std::vector<DRILL_TOOL> to fill with tools to use
* @param aFirstLayer = first layer to consider
* @param aLastLayer = last layer to consider
* @param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored (used to creates report file)
* @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored
* @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored
* @param aExcludeThroughHoles : if true, exclude through holes ( pads and vias through )
*/
void Build_Holes_List( BOARD* aPcb,
std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int aFirstLayer, int aLastLayer )
int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles )
{
HOLE_INFO new_hole;
int hole_value;
......@@ -52,8 +55,11 @@ void Build_Holes_List( BOARD* aPcb,
aHoleListBuffer.clear();
aToolListBuffer.clear();
if( (aFirstLayer >= 0) && (aLastLayer >= 0) )
{
if( aFirstLayer > aLastLayer )
EXCHG( aFirstLayer, aLastLayer );
}
/* build hole list for vias */
TRACK* track = aPcb->m_Track;
......@@ -73,15 +79,23 @@ void Build_Holes_List( BOARD* aPcb,
new_hole.m_Hole_Pos_X = via->m_Start.x;
new_hole.m_Hole_Pos_Y = via->m_Start.y; // hole position
via->ReturnLayerPair( &new_hole.m_Hole_Top_Layer, &new_hole.m_Hole_Bottom_Layer );
// ReturnLayerPair return params with m_Hole_Bottom_Layer < m_Hole_Top_Layer
if( new_hole.m_Hole_Bottom_Layer > aFirstLayer )
if( (new_hole.m_Hole_Bottom_Layer > aFirstLayer) && (aFirstLayer >= 0) )
continue;
if( new_hole.m_Hole_Top_Layer < aLastLayer )
if( (new_hole.m_Hole_Top_Layer < aLastLayer) && (aLastLayer >= 0) )
continue;
if( aExcludeThroughHoles && (new_hole.m_Hole_Bottom_Layer == COPPER_LAYER_N)
&& (new_hole.m_Hole_Top_Layer == LAYER_CMP_N) )
continue;
aHoleListBuffer.push_back( new_hole );
}
/* build hole list for pads */
/* build hole list for pads (assumed always through holes) */
if( !aExcludeThroughHoles )
{
MODULE* Module = aPcb->m_Modules;
for( ; Module != NULL; Module = Module->Next() )
{
......@@ -107,6 +121,7 @@ void Build_Holes_List( BOARD* aPcb,
aHoleListBuffer.push_back( new_hole );
}
}
}
// Sort holes per increasing diameter value
sort( aHoleListBuffer.begin(), aHoleListBuffer.end(), CmpHoleDiameterValue );
......
......@@ -251,14 +251,23 @@ void WinEDA_DrillFrame::UpdateConfig()
void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
/*************************************************************/
/* Calls the functions to create EXCELLON drill files and/od drill map files
/**
* Function GenDrillFiles
* Calls the functions to create EXCELLON drill files and/od drill map files
* When all holes are through, one excellon file is created
* when there are some partial holes (some blind or buried vias:
* One excellon file is created, for all through holes.
* And one file per layer pair, which have one or more holes, excluding through holes, already in the first file.
*/
{
wxString FullFileName, Mask( wxT( "*" ) ), Ext( wxT( ".drl" ) );
wxString BaseFileName;
wxString layer_extend; // added to the Board FileName to create FullFileName (= Board FileName + layer pair names)
wxString msg;
bool ExistsBuriedVias = false; // If true, driil files are created layer pair by layer pair
bool ExistsBuriedVias = false; // If true, drill files are created layer pair by layer pair for buried vias
int layer1 = COPPER_LAYER_N;
int layer2 = LAYER_CMP_N;
bool gen_through_holes = true;
UpdateConfig(); /* set params and Save drill options */
......@@ -272,16 +281,17 @@ void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
if( m_MicroViasCount || m_BlindOrBuriedViasCount )
ExistsBuriedVias = true;
if( ExistsBuriedVias )
layer2 = layer1 + 1;;
/* Get the file name */
Mask += Ext;
for( ; ; )
{
Build_Holes_List( m_Parent->m_Pcb, s_HoleListBuffer, s_ToolListBuffer,
layer1, layer2, gen_through_holes ? false : true );
if( s_ToolListBuffer.size() == 0 ) // No holes !
continue;
FullFileName = m_Parent->m_CurrentScreen->m_FileName;
wxString layer_extend;
layer_extend.Empty();
if( ExistsBuriedVias )
if( !gen_through_holes )
{
if( layer1 == COPPER_LAYER_N )
layer_extend << wxT( "-copper" );
......@@ -305,9 +315,6 @@ void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
TRUE
);
Build_Holes_List( m_Parent->m_Pcb, s_HoleListBuffer, s_ToolListBuffer,
layer1, layer2 );
if( FullFileName != wxEmptyString )
{
dest = wxFopen( FullFileName, wxT( "w" ) );
......@@ -328,32 +335,35 @@ void WinEDA_DrillFrame::GenDrillFiles( wxCommandEvent& event )
break;
case 1:
GenDrillMap( FullFileName,
s_HoleListBuffer,
s_ToolListBuffer,
PLOT_FORMAT_HPGL );
GenDrillMap( FullFileName, s_HoleListBuffer, s_ToolListBuffer, PLOT_FORMAT_HPGL );
break;
case 2:
GenDrillMap( FullFileName,
s_HoleListBuffer,
s_ToolListBuffer,
PLOT_FORMAT_POST );
GenDrillMap( FullFileName, s_HoleListBuffer, s_ToolListBuffer, PLOT_FORMAT_POST );
break;
}
if( m_Choice_Drill_Report->GetSelection() > 0 )
GenDrillReport( FullFileName, s_ToolListBuffer );
if( !ExistsBuriedVias )
break;
if( gen_through_holes )
layer2 = layer1 + 1;
else
{
if( layer2 >= LAYER_CMP_N ) // no more layer pair to consider
break;
layer1++; layer2++; // use next layer pair
if( layer2 == g_DesignSettings.m_CopperLayerCount - 1 ) // The last layer is reached
layer2 = LAYER_CMP_N; // the last layer is always the component layer
}
gen_through_holes = false;
}
if( m_Choice_Drill_Report->GetSelection() > 0 )
{
FullFileName = m_Parent->m_CurrentScreen->m_FileName;
GenDrillReport( FullFileName );
}
EndModal( 0 );
}
......@@ -747,7 +757,7 @@ void WinEDA_DrillFrame::GenDrillMap( const wxString aFileName,
/**************************************************************************************************/
void WinEDA_DrillFrame::GenDrillReport( const wxString aFileName, std::vector<DRILL_TOOL>& buffer )
void WinEDA_DrillFrame::GenDrillReport( const wxString aFileName )
/**************************************************************************************************/
/*
......@@ -780,6 +790,9 @@ void WinEDA_DrillFrame::GenDrillReport( const wxString aFileName, std::vector<DR
DisplayError( this, msg );
return;
}
GenDrillReportFile( dest, m_Parent->m_CurrentScreen->m_FileName, buffer, s_Unit_Drill_is_Inch );
GenDrillReportFile( dest, m_Parent->m_Pcb,
m_Parent->m_CurrentScreen->m_FileName,
s_Unit_Drill_is_Inch,
s_HoleListBuffer,
s_ToolListBuffer );
}
/*******************************************************************************/
/* classes and functions declaration unsed in drill file and report generation */
/*******************************************************************************/
/******************************************************************************/
/* classes and functions declaration used in drill file and report generation */
/******************************************************************************/
#ifndef GENDRILL_H
#define GENDRILL_H
/* the DRILL_TOOL class handle tools used in the excellon drill file */
/* the DRILL_TOOL class handles tools used in the excellon drill file */
class DRILL_TOOL
{
public:
......@@ -62,13 +62,18 @@ enum zeros_fmt {
/**
* Function BuildHolesList
* Create the list of holes and tools for a given board
* The list is sorted by incraesin drill values
* Only holes from aFirstLayer to aLastLayer copper layers are listed (for vias, because pad holes are always through holes)
* @param Pcb : the given board
* @param aHoleListBuffer : the std::vector<HOLE_INFO> to fill with pcb info
* @param aHoleListBuffer : the std::vector<HOLE_INFO> to fill with pcb holes info
* @param aToolListBuffer : the std::vector<DRILL_TOOL> to fill with tools to use
* @param aFirstLayer = first layer to consider. if < 0 aFirstLayer is ignored
* @param aLastLayer = last layer to consider. if < 0 aLastLayer is ignored
* @param aExcludeThroughHoles : if true, exclude through holes ( pads and vias through )
*/
void Build_Holes_List( BOARD* Pcb, std::vector<HOLE_INFO>& aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer,
int aFirstLayer, int aLastLayer );
int aFirstLayer, int aLastLayer, bool aExcludeThroughHoles );
void GenDrillMapFile( BOARD* aPcb,
......@@ -87,8 +92,12 @@ void Gen_Drill_PcbMap( BOARD* aPcb, FILE* aFile,
/*
* Create a list of drill values and drill count
* there is only one report for all drill files even when buried or blinds vias exist
*/
void GenDrillReportFile( FILE* aFile, const wxString& aBoardFilename,
std::vector<DRILL_TOOL>& aToolListBuffer, bool aUnit_Drill_is_Inch );
void GenDrillReportFile( FILE* aFile, BOARD * aPcb, const wxString& aBoardFilename,
bool aUnit_Drill_is_Inch,
std::vector<HOLE_INFO> & aHoleListBuffer,
std::vector<DRILL_TOOL>& aToolListBuffer
);
#endif // #ifndef GENDRILL_H
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment