/* * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2011-2016 Jean-Pierre Charras jp.charras at wanadoo.fr * Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors. * * 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; either version 2 * of the License, or (at your option) any later version. * * 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, you may find one here: * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * or you may search the http://www.gnu.org website for the version 2 license, * or you may write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ #ifndef EXCELLON_IMAGE_H #define EXCELLON_IMAGE_H struct EXCELLON_DEFAULTS; enum drill_M_code_t { DRILL_M_UNKNOWN, DRILL_M_END, DRILL_M_TOOL_DOWN, // tool down (starting a routed hole) DRILL_M_TOOL_UP, // tool up (ending a routed hole) DRILL_M_ENDFILE, DRILL_M_MESSAGE, DRILL_M_LONGMESSAGE, DRILL_M_HEADER, DRILL_M_ENDHEADER, DRILL_M_BEGINPATTERN, DRILL_M_ENDPATTERN, DRILL_M_CANNEDTEXT, DRILL_M_TIPCHECK, DRILL_M_METRIC, DRILL_M_IMPERIAL, DRILL_METRIC_HEADER, DRILL_IMPERIAL_HEADER, DRILL_DETECT_BROKEN, DRILL_INCREMENTALHEADER, DRILL_REWIND_STOP, DRILL_TOOL_CHANGE_STOP, DRILL_AUTOMATIC_SPEED, DRILL_AXIS_VERSION, DRILL_RESET_CMD, DRILL_AUTOMATIC_TOOL_CHANGE, DRILL_FMT, DRILL_FORMAT_ALTIUM, DRILL_HEADER_SKIP, DRILL_SKIP, DRILL_TOOL_INFORMATION, DRILL_M_END_LIST // not used: sentinel }; enum drill_G_code_t { DRILL_G_UNKNOWN = DRILL_M_END_LIST+1, // Use next available value DRILL_G_ABSOLUTE, DRILL_G_INCREMENTAL, DRILL_G_ZEROSET, DRILL_G_ROUT, DRILL_G_DRILL, DRILL_G_SLOT, DRILL_G_ZERO_SET, DRILL_G_LINEARMOVE, DRILL_G_CWMOVE, DRILL_G_CCWMOVE }; // Helper struct to analyze Excellon commands struct EXCELLON_CMD { std::string m_Name; // key string int m_Code; // internal code, used as id in functions int m_asParams; // 0 = no param, -1 = skip params, 1 = read params }; // Helper struct to store Excellon points in routing mode #define ROUTE_CCW 1 #define ROUTE_CW -1 struct EXCELLON_ROUTE_COORD { int m_x; // X coordinate int m_y; // y coordinate int m_cx; // center X coordinate in circular routing mode // (when the IJ command is used) int m_cy; // center y coordinate in circular routing mode // (when the IJ command is used) int m_radius; // radius in circular routing mode (when the A## command is used) int m_rmode; // routing mode: 0 = circular, ROUTE_CCW (1) = ccw, ROUTE_CW (-1) = cw int m_arc_type_info; // arc using radius or center coordinates EXCELLON_ROUTE_COORD(): m_x( 0 ), m_y( 0 ), m_cx( 0 ), m_cy( 0 ), m_radius( 0 ), m_rmode( 0 ), m_arc_type_info( 0 ) {} EXCELLON_ROUTE_COORD( const VECTOR2I& aPos ) : m_x( aPos.x ), m_y( aPos.y ), m_cx( 0 ), m_cy( 0 ), m_radius( 0 ), m_rmode( 0 ), m_arc_type_info( ARC_INFO_TYPE_NONE ) {} EXCELLON_ROUTE_COORD( const VECTOR2I& aPos, const VECTOR2I& aCenter, int aMode ) : m_x( aPos.x ), m_y( aPos.y ), m_cx( aCenter.x ), m_cy( aCenter.y ), m_radius( 0 ), m_rmode( aMode ), m_arc_type_info( ARC_INFO_TYPE_CENTER ) {} EXCELLON_ROUTE_COORD( const VECTOR2I& aPos, int aRadius, int aMode ) : m_x( aPos.x ), m_y( aPos.y ), m_cx( 0 ), m_cy( 0 ), m_radius( aRadius ), m_rmode( aMode ), m_arc_type_info( ARC_INFO_TYPE_RADIUS ) {} VECTOR2I GetPos() { return VECTOR2I( m_x, m_y ); } }; /** * Handle a drill image. * * It is derived from #GERBER_FILE_IMAGE because there is a lot of likeness between EXCELLON * files and GERBER files. * DCode apertures are also similar to T Codes. */ class EXCELLON_IMAGE : public GERBER_FILE_IMAGE { public: EXCELLON_IMAGE( int layer ) : GERBER_FILE_IMAGE( layer ) { m_State = READ_HEADER_STATE; m_SlotOn = false; m_RouteModeOn = false; m_hasFormat = false; } ~EXCELLON_IMAGE() {}; /** * Set all parameters to a default value, before reading a file */ virtual void ResetDefaultValues() override; /** * @brief Performs a heuristics-based check of whether the file is an Excellon drill file. * * Does not invoke the full parser. * * @param aFullFileName aFullFileName is the full filename of the Excellon file. * @return True if drill file, false otherwise */ static bool TestFileIsExcellon( const wxString& aFullFileName ); /** * Read and load a drill (EXCELLON format) file. * * When the file cannot be loaded, warning and info messages are stored in m_Messages. * * @param aFullFileName is the full filename of the Excellon file. * @param aDefaults is the default values when not found in file. * @return true if OK, false if the gerber file was not loaded. */ bool LoadFile( const wxString& aFullFileName, EXCELLON_DEFAULTS* aDefaults ); private: bool Execute_HEADER_And_M_Command( char*& text ); bool Select_Tool( char*& text ); bool Execute_EXCELLON_G_Command( char*& text ); bool Execute_Drill_Command( char*& text ); /** * Read an Altium-specific FILE_FORMAT=X:X attribute that specifies the length * and mantissa of the numbers in the gerber file * * @param aText Text containing format and mantissa */ void readFileFormat( char*& aText ); /** * Read a tool definition like T1C0.02 or T1F00S00C0.02 or T1C0.02F00S00 * and enter params in TCODE list. */ bool readToolInformation( char*& aText ); /** * End a route command started by M15 ot G01, G02 or G03 command. */ void FinishRouteCommand(); /** * Switch unit selection, and the coordinate format (nn:mm) if not yet set */ void SelectUnits( bool aMetric, EXCELLON_DEFAULTS* aDefaults ); private: enum EXCELLON_STATE { READ_HEADER_STATE, // When we are in this state, we are reading header READ_PROGRAM_STATE // When we are in this state, we are reading drill data }; EXCELLON_STATE m_State; // state of excellon file analysis bool m_SlotOn; // true during an oblong drill definition // by G85 (canned slot) command bool m_RouteModeOn; // true during a route mode (for instance a oval hole) or // a cutout. std::vector m_RoutePositions; // The list of points in a route mode /// Excellon file do not have a format statement to specify the coordinate format /// like nn:mm. /// However Altium files have a comment to specify it (";FILE_FORMET_" /// m_hasFormat is set to true if this comment is found, and coordinate format is known. bool m_hasFormat; }; /* * EXCELLON commands are given here. * Pcbnew uses only few excellon commands */ /* * see http://www.excellon.com/manuals/program.htm */ /* coordinates units: * Coordinates are measured either in inch or metric (millimeters). * Inch coordinates are in six digits (00.0000) with increments as small as 0.0001 (1/10,000). * Metric coordinates can be measured in microns (thousandths of a millimeter) * in one of the following three ways: * Five digit 10 micron resolution (000.00) * Six digit 10 micron resolution (0000.00) * Six digit micron resolution (000.000) * * Leading and trailing zeros: * Excellon (CNC-7) uses inches in six digits and metric in five or six digits. * The zeros to the left of the coordinate are called leading zeros (LZ). * The zeros to right of the coordinate are called trailing zeros (TZ). * The CNC-7 uses leading zeros unless you specify otherwise through a part program. * You can do so with the INCH/METRIC command. * With leading zeros, the leading zeros must always be included. * Trailing zeros are unneeded and may be left off. * For trailing zeros, the reverse of the above is true. */ /* * EXCELLON Commands Used in a Header * The following table provides you with a list of commands which * are the most used in a part program header. * COMMAND DESCRIPTION * AFS Automatic Feeds and Speeds * ATC Automatic Tool Change * BLKD Delete all Blocks starting with a slash (/) * CCW Clockwise or Counter-clockwise Routing * CP Cutter Compensation * DETECT Broken Tool Detection * DN Down Limit Set * DTMDIST Maximum Rout Distance Before Toolchange * EXDA Extended Drill Area * FMAT Format 1 or 2 * FSB Turns the Feed/Speed Buttons off * HPCK Home Pulse Check * ICI Incremental Input of Part Program Coordinates * INCH Measure Everything in Inches * METRIC Measure Everything in Metric * M48 Beginning of Part Program Header * M95 End of Header * NCSL NC Slope Enable/Disable * OM48 Override Part Program Header * OSTOP Optional Stop Switch * OTCLMP Override Table Clamp * PCKPARAM Set up pecking tool,depth,infeed and retract parameters * PF Floating Pressure Foot Switch * PPR Programmable Plunge Rate Enable * PVS Pre-vacuum Shut-off Switch * R,C Reset Clocks * R,CP Reset Program Clocks * R,CR Reset Run Clocks * R,D Reset All Cutter Distances * R,H Reset All Hit Counters * R,T Reset Tool Data * SBK Single Block Mode Switch * SG Spindle Group Mode * SIXM Input From External Source * T Tool Information * TCST Tool Change Stop * UP Upper Limit Set * VER Selection of X and Y Axis Version * Z Zero Set * ZA Auxiliary Zero * ZC Zero Correction * ZS Zero Preset * Z+# or Z-# Set Depth Offset * % Rewind Stop * #/#/# Link Tool for Automatic Tool Change * / Clear Tool Linking */ /* * Beyond The Header: The Part Program Body * COMMAND DESCRIPTION * A# Arc Radius * B# Retract Rate * C# Tool Diameter * F# Table Feed Rate;Z Axis Infeed Rate * G00X#Y# Route Mode; XY is the starting point * G01X#Y# Linear (Straight Line) Route Mode YX is the ending point * G02X#Y#... Circular CW Mode. Radius value (A#) or Center position (I#J#) follows * G03X#Y#... Circular CCW Mode. Radius value (A#) or Center position (I#J#) follows * G04X# Variable Dwell * G05 Drill Mode * G07 Override current tool feed or speed * G32X#Y#A# Routed Circle Canned Cycle * CW G33X#Y#A# Routed Circle Canned Cycle * CCW G34,#(,#) Select Vision Tool * G35(X#Y#) Single Point Vision Offset (Relative to Work Zero) * G36(X#Y#) Multipoint Vision Translation (Relative to Work Zero) * G37 Cancel Vision Translation or Offset (From G35 or G36) * G38(X#Y#) Vision Corrected Single Hole Drilling (Relative to Work Zero) * G39(X#Y#) Vision System Autocalibration * G40 Cutter Compensation Off * G41 Cutter Compensation Left * G42 Cutter Compensation Right * G45(X#Y#) Single Point Vision Offset (Relative to G35 or G36) * G46(X#Y#) Multipoint Vision Translation (Relative to G35 or G36) * G47 Cancel Vision Translation or Offset (From G45 or G46) * G48(X#Y#) Vision Corrected Single Hole Drilling (Relative to G35 or G36) * G82(G81) Dual In Line Package * G83 Eight Pin L Pack * G84 Circle * G85 Slot * G87 Routed Step Slot Canned Cycle * G90 Absolute Mode * G91 Incremental Input Mode * G93X#Y# Zero Set * H# Maximum hit count * I#J# Arc Center Offset * M00(X#Y#) End of Program - No Rewind * M01 End of Pattern * M02X#Y# Repeat Pattern Offset * M06(X#Y#) Optional Stop * M08 End of Step and Repeat * M09(X#Y#) Stop for Inspection * M14 Z Axis Route Position With Depth Controlled Contouring * M15 Z Axis Route Position * M16 Retract With Clamping * M17 Retract Without Clamping * M18 Command tool tip check * M25 Beginning of Pattern * M30(X#Y#) End of Program Rewind * M45,long message\ Long Operator message on multiple\ part program lines * M47,text Operator Message * M50,# Vision Step and Repeat Pattern Start * M51,# Vision Step and Repeat Rewind * M52(#) Vision Step and Repeat Offset Counter Control * M02XYM70 Swap Axes * M60 Reference Scaling enable * M61 Reference Scaling disable * M62 Turn on peck drilling * M63 Turn off peck drilling * M71 Metric Measuring Mode * M72 Inch Measuring Mode * M02XYM80 Mirror Image X Axis * M02XYM90 Mirror Image Y Axis * M97,text Canned Text * M98,text Canned Text * M99,subprogram User Defined Stored Pattern * P#X#(Y#) Repeat Stored Pattern * R#M02X#Y# Repeat Pattern (S&R) * R#(X#Y#) Repeat Hole * S# Spindle RPM * T# Tool Selection; Cutter Index * Z+# or Z-# Depth Offset * % Beginning of Pattern (see M25 command) * / Block Delete */ /* * Example of a Header * COMMAND PURPOSE * M48 The beginning of a header * INCH,LZ Use the inch measuring system with leading zeros * VER,1 Use Version 1 X and Y axis layout * FMAT,2 Use Format 2 commands * 1/2/3 Link tools 1, 2, and 3 * T1C.04F200S65 Set Tool 1 for 0.040" with infeed rate of 200 inch/min Speed of 65,000 RPM * DETECT,ON Detect broken tools * M95 End of the header */ #endif // EXCELLON_IMAGE_H