← Back to team overview

kicad-developers team mailing list archive

eeschema patch, ngspice simulation bjt carac use case

 

Hi all,

i have a first version of several patch for an simulation use case : view bjt caracteristics.

You can found in attachment schematics, result and patch.

Now i would like create patch to create improvment in plot (legend and scale)

--
Ludovic Léau-Mercier

Attachment: carac_bjt.sch
Description: application/kicad-schematic

Attachment: carac_bjt.svg
Description: image/svg

Attachment: bjt_carac2.png
Description: PNG image

>From 3a3aa9479171cdb0fd1dd87d828ced822dcf281f Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Tue, 23 Jan 2018 14:42:36 +0100
Subject: [PATCH 01/11] add current source

---
 eeschema/dialogs/dialog_sim_settings.cpp      | 2 +-
 eeschema/dialogs/dialog_sim_settings_base.cpp | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/eeschema/dialogs/dialog_sim_settings.cpp b/eeschema/dialogs/dialog_sim_settings.cpp
index ef00a4fdc..731001054 100644
--- a/eeschema/dialogs/dialog_sim_settings.cpp
+++ b/eeschema/dialogs/dialog_sim_settings.cpp
@@ -277,7 +277,7 @@ int DIALOG_SIM_SETTINGS::ShowModal()
 
     for( auto item : m_exporter->GetSpiceItems() )
     {
-        if( item.m_primitive == 'V' )
+        if( item.m_primitive == 'V' || item.m_primitive == 'I' )
         {
             for( auto c : cmbSrc )
                 c.first->Append( item.m_refName );
diff --git a/eeschema/dialogs/dialog_sim_settings_base.cpp b/eeschema/dialogs/dialog_sim_settings_base.cpp
index fdf45ab7d..a18801867 100644
--- a/eeschema/dialogs/dialog_sim_settings_base.cpp
+++ b/eeschema/dialogs/dialog_sim_settings_base.cpp
@@ -96,21 +96,21 @@ DIALOG_SIM_SETTINGS_BASE::DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID
 	m_dcSource1 = new wxComboBox( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); 
 	fgSizer21->Add( m_dcSource1, 0, wxALL, 5 );
 	
-	m_staticText51 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Starting voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText51 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Starting voltage or current [V,A]"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticText51->Wrap( -1 );
 	fgSizer21->Add( m_staticText51, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 	
 	m_dcStart1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer21->Add( m_dcStart1, 0, wxALL, 5 );
 	
-	m_staticText61 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Final voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText61 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Final voltage or current [V,A]"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticText61->Wrap( -1 );
 	fgSizer21->Add( m_staticText61, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 	
 	m_dcStop1 = new wxTextCtrl( sbSizer21->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer21->Add( m_dcStop1, 0, wxALL, 5 );
 	
-	m_staticText71 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Increment step [V]"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText71 = new wxStaticText( sbSizer21->GetStaticBox(), wxID_ANY, _("Increment step [V,A]"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticText71->Wrap( -1 );
 	fgSizer21->Add( m_staticText71, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 	
-- 
2.11.0

>From 46a0e43ab05c19b37bfb2cc3df7f97575a550e0a Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Mon, 29 Jan 2018 16:31:33 +0100
Subject: [PATCH 02/11] modify simulator to append isource parsing. Append
 primitive to transform dc name in correct value for simulator

---
 eeschema/dialogs/dialog_sim_settings.cpp | 41 ++++++++++++++++++++++++++------
 1 file changed, 34 insertions(+), 7 deletions(-)

diff --git a/eeschema/dialogs/dialog_sim_settings.cpp b/eeschema/dialogs/dialog_sim_settings.cpp
index 731001054..352e2fe95 100644
--- a/eeschema/dialogs/dialog_sim_settings.cpp
+++ b/eeschema/dialogs/dialog_sim_settings.cpp
@@ -25,7 +25,7 @@
 #include "dialog_sim_settings.h"
 #include <sim/netlist_exporter_pspice_sim.h>
 #include <confirm.h>
-
+#include <wx/regex.h>
 #include <wx/tokenzr.h>
 
 /// @todo ngspice offers more types of analysis,
@@ -37,6 +37,22 @@ static bool empty( const wxTextEntryBase* aCtrl )
     return aCtrl->GetValue().IsEmpty();
 }
 
+// Helper function to parse DC combobox value
+static void parseDCValue( const wxString wxComboBoxEntry, wxChar & primitive, wxString & name )
+{
+	wxRegEx reg( wxT("\\(([a-zA-Z])\\) (\\w+)"), wxRE_ADVANCED );
+	if( reg.IsValid() )
+	{
+		if(reg.Matches(wxComboBoxEntry))
+		{
+			primitive = reg.GetMatch( wxComboBoxEntry, 1 ).GetChar(0);
+			name = reg.GetMatch( wxComboBoxEntry, 2);
+		}else{
+			// no matches
+			name = wxComboBoxEntry;	
+		}
+	}
+}
 
 DIALOG_SIM_SETTINGS::DIALOG_SIM_SETTINGS( wxWindow* aParent )
     : DIALOG_SIM_SETTINGS_BASE( aParent ), m_exporter( nullptr ), m_spiceEmptyValidator( true )
@@ -117,8 +133,12 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
 
             try
             {
-                simCmd += wxString::Format( "v%s %s %s %s",
-                    m_dcSource1->GetValue(),
+            	wxChar dc1Primitive = 'v';
+            	wxString dc1Name;
+            	parseDCValue(wxString::Format("%s", m_dcSource1->GetValue()), dc1Primitive, dc1Name);
+                simCmd += wxString::Format( "%c%s %s %s %s ",
+                    dc1Primitive,
+                    dc1Name,
                     SPICE_VALUE( m_dcStart1->GetValue() ).ToSpiceString(),
                     SPICE_VALUE( m_dcStop1->GetValue() ).ToSpiceString(),
                     SPICE_VALUE( m_dcIncr1->GetValue() ).ToSpiceString() );
@@ -145,8 +165,12 @@ bool DIALOG_SIM_SETTINGS::TransferDataFromWindow()
 
             try
             {
-                simCmd += wxString::Format( "v%s %s %s %s",
-                    m_dcSource2->GetValue(),
+            	wxChar dc2Primitive = 'v';
+            	wxString dc2Name;
+            	parseDCValue(wxString::Format("%s", m_dcSource2->GetValue()), dc2Primitive, dc2Name);
+                simCmd += wxString::Format( "%c%s %s %s %s ",
+                    dc2Primitive,
+                    dc2Name,
                     SPICE_VALUE( m_dcStart2->GetValue() ).ToSpiceString(),
                     SPICE_VALUE( m_dcStop2->GetValue() ).ToSpiceString(),
                     SPICE_VALUE( m_dcIncr2->GetValue() ).ToSpiceString() );
@@ -279,8 +303,11 @@ int DIALOG_SIM_SETTINGS::ShowModal()
     {
         if( item.m_primitive == 'V' || item.m_primitive == 'I' )
         {
-            for( auto c : cmbSrc )
-                c.first->Append( item.m_refName );
+        	wxString nameSrc;
+            for( auto c : cmbSrc ){
+            	nameSrc = wxString::Format( "(%c) %s", item.m_primitive, item.m_refName);
+            	c.first->Append( nameSrc );
+            }
         }
     }
 
-- 
2.11.0

>From 8c922db1cf4cd504b1608086ae57ff22d11d7225 Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Wed, 7 Feb 2018 09:19:29 +0100
Subject: [PATCH 03/11] replace simulation type ST_DC by new type to manage
 i-sweep and v-sweep

---
 eeschema/sim/sim_plot_frame.cpp | 7 ++++---
 eeschema/sim/sim_plot_panel.cpp | 6 ++++--
 eeschema/sim/sim_types.h        | 2 +-
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp
index ba0134d7e..bf429f62f 100644
--- a/eeschema/sim/sim_plot_frame.cpp
+++ b/eeschema/sim/sim_plot_frame.cpp
@@ -397,7 +397,6 @@ SIM_PLOT_PANEL* SIM_PLOT_FRAME::CurrentPlot() const
 void SIM_PLOT_FRAME::addPlot( const wxString& aName, SIM_PLOT_TYPE aType, const wxString& aParam )
 {
     SIM_TYPE simType = m_exporter->GetSimType();
-
     if( !SIM_PLOT_PANEL::IsPlottable( simType ) )
         return; // TODO else write out in console?
 
@@ -512,7 +511,8 @@ bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL*
         break;
 
         case ST_NOISE:
-        case ST_DC:
+        case ST_DC_VSWEEP:
+        case ST_DC_ISWEEP:
         case ST_TRANSIENT:
         {
             data_y = m_simulator->GetMagPlot( (const char*) spiceVector.c_str() );
@@ -762,7 +762,8 @@ SIM_PLOT_TYPE SIM_PLOT_FRAME::GetXAxisType( SIM_TYPE aType ) const
             return SPT_LIN_FREQUENCY;
             /// @todo SPT_LOG_FREQUENCY
 
-        case ST_DC:
+        case ST_DC_VSWEEP:
+        case ST_DC_ISWEEP:
             return SPT_SWEEP;
 
         case ST_TRANSIENT:
diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp
index f66d4e71d..66c8b2f15 100644
--- a/eeschema/sim/sim_plot_panel.cpp
+++ b/eeschema/sim/sim_plot_panel.cpp
@@ -383,7 +383,8 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
             m_axis_y2->SetMasterScale( m_axis_y1 );
             break;
 
-        case ST_DC:
+        case ST_DC_VSWEEP:
+        case ST_DC_ISWEEP:
             m_axis_x = new VOLTAGE_SCALE_X( wxT( "Voltage (sweeped)" ), mpALIGN_BOTTOM );
             m_axis_y1 = new VOLTAGE_SCALE_Y( wxT( "Voltage (measured)" ), mpALIGN_LEFT );
             break;
@@ -449,7 +450,8 @@ bool SIM_PLOT_PANEL::IsPlottable( SIM_TYPE aSimType )
     switch( aSimType )
     {
         case ST_AC:
-        case ST_DC:
+        case ST_DC_VSWEEP:
+        case ST_DC_ISWEEP:
         case ST_TRANSIENT:
             return true;
 
diff --git a/eeschema/sim/sim_types.h b/eeschema/sim/sim_types.h
index fe36f9ac7..3f7f3f58f 100644
--- a/eeschema/sim/sim_types.h
+++ b/eeschema/sim/sim_types.h
@@ -27,7 +27,7 @@
 
 ///> Possible simulation types
 enum SIM_TYPE {
-    ST_UNKNOWN, ST_AC, ST_DC, ST_DISTORTION, ST_NOISE, ST_OP,
+    ST_UNKNOWN, ST_AC, ST_DC_VSWEEP, ST_DC_ISWEEP, ST_DISTORTION, ST_NOISE, ST_OP,
     ST_POLE_ZERO, ST_SENSITIVITY, ST_TRANS_FUNC, ST_TRANSIENT
 };
 
-- 
2.11.0

>From ca4e45608e6df6e797e5530e5c8d7cb149619eaa Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Wed, 7 Feb 2018 09:24:54 +0100
Subject: [PATCH 04/11] add i-sweep xaxis management modify old simulation type
 dc to dc_isweep or dc_vsweep

---
 eeschema/dialogs/dialog_sim_settings.cpp     |  3 ++-
 eeschema/sim/netlist_exporter_pspice_sim.cpp | 30 ++++++++++++++++++++++++++--
 eeschema/sim/ngspice.cpp                     |  7 +++++--
 3 files changed, 35 insertions(+), 5 deletions(-)

diff --git a/eeschema/dialogs/dialog_sim_settings.cpp b/eeschema/dialogs/dialog_sim_settings.cpp
index 352e2fe95..d93883e3a 100644
--- a/eeschema/dialogs/dialog_sim_settings.cpp
+++ b/eeschema/dialogs/dialog_sim_settings.cpp
@@ -362,7 +362,8 @@ bool DIALOG_SIM_SETTINGS::parseCommand( const wxString& aCommand )
 
             if( !tkn.IsEmpty() )
             {
-                m_dcSource1->SetValue( tkn );
+            	wxString srcName = tkn.SubString(1, tkn.Len());
+            	m_dcSource1->SetValue( wxString::Format( "(%c) %s", tkn[0], srcName ) );
                 m_dcStart1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
                 m_dcStop1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
                 m_dcIncr1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
diff --git a/eeschema/sim/netlist_exporter_pspice_sim.cpp b/eeschema/sim/netlist_exporter_pspice_sim.cpp
index c65e1f558..ff4af88f2 100644
--- a/eeschema/sim/netlist_exporter_pspice_sim.cpp
+++ b/eeschema/sim/netlist_exporter_pspice_sim.cpp
@@ -23,12 +23,13 @@
  */
 
 #include "netlist_exporter_pspice_sim.h"
+#include <wx/regex.h>
+#include <confirm.h>
 
 wxString NETLIST_EXPORTER_PSPICE_SIM::GetSpiceVector( const wxString& aName, SIM_PLOT_TYPE aType,
         const wxString& aParam ) const
 {
     wxString res;
-
     // Some of the flags should exclude mutually
     assert( ( ( aType & SPT_VOLTAGE ) == 0 ) != ( ( aType & SPT_CURRENT ) == 0 ) );
     assert( ( ( aType & SPT_AC_PHASE ) == 0 ) || ( ( aType & SPT_AC_MAG ) == 0 ) );
@@ -125,12 +126,37 @@ SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimType()
 SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
 {
     const std::map<wxString, SIM_TYPE> simCmds = {
-        { ".ac", ST_AC }, { ".dc", ST_DC }, { ".disto", ST_DISTORTION }, { ".noise", ST_NOISE },
+        { ".ac", ST_AC }, { ".disto", ST_DISTORTION }, { ".noise", ST_NOISE },
         { ".op", ST_OP }, { ".pz", ST_POLE_ZERO }, { ".sens", ST_SENSITIVITY }, { ".tf", ST_TRANS_FUNC },
         { ".tran", ST_TRANSIENT }
     };
     wxString lcaseCmd = aCmd.Lower();
 
+    if( lcaseCmd.StartsWith( ".dc") ){
+    	wxRegEx reg( wxT(".dc\\s+(\\w+\\s+\\w+\\s+\\w+\\s+\\w+)?\\s*(\\w+\\s+\\w+\\s+\\w+\\s+\\w+)"), wxRE_ADVANCED );
+    	if( reg.IsValid() )
+    	{
+    		if(reg.Matches(lcaseCmd))
+    		{
+    			int index = reg.GetMatchCount();
+    			if(index > 1)
+    			{
+    				// get last sweep definition
+    				wxString sweep1 = reg.GetMatch( lcaseCmd, index -2 );
+    				wxString sweep = reg.GetMatch( lcaseCmd, index - 1);
+    				if(sweep[0] == 'i'){
+    					return ST_DC_ISWEEP;
+    				}
+    				if(sweep[0] == 'v'){
+    					return ST_DC_VSWEEP;
+    				}
+    			}
+    		}
+    	}
+    	DisplayErrorMessage( NULL, _( "Could not find sweep type" ) );
+    	return ST_UNKNOWN;
+    }
+
     for( const auto& c : simCmds )
     {
         if( lcaseCmd.StartsWith( c.first ) )
diff --git a/eeschema/sim/ngspice.cpp b/eeschema/sim/ngspice.cpp
index fb8d03206..163172e6f 100644
--- a/eeschema/sim/ngspice.cpp
+++ b/eeschema/sim/ngspice.cpp
@@ -237,7 +237,6 @@ bool NGSPICE::Command( const string& aCmd )
 {
     LOCALE_IO c_locale;               // ngspice works correctly only with C locale
     ngSpice_Command( (char*) aCmd.c_str() );
-
     return true;
 }
 
@@ -251,10 +250,14 @@ string NGSPICE::GetXAxis( SIM_TYPE aType ) const
             return string( "frequency" );
             break;
 
-        case ST_DC:
+        case ST_DC_VSWEEP:
             return string( "v-sweep" );
             break;
 
+        case ST_DC_ISWEEP:
+            return string( "i-sweep" );
+            break;
+
         case ST_TRANSIENT:
             return string( "time" );
             break;
-- 
2.11.0

>From 2d4f0174a18fa01e6a0fea256a88a41e8bd1710c Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 15 Feb 2018 09:12:39 +0100
Subject: [PATCH 05/11] modifiy simulation type to manage i-sweep in second dc
 source

---
 eeschema/dialogs/dialog_signal_list.cpp | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/eeschema/dialogs/dialog_signal_list.cpp b/eeschema/dialogs/dialog_signal_list.cpp
index bd2eaaf9b..6618e0137 100644
--- a/eeschema/dialogs/dialog_signal_list.cpp
+++ b/eeschema/dialogs/dialog_signal_list.cpp
@@ -58,8 +58,7 @@ bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
                 m_signals->Append( wxString::Format( "V(%s)", net.first ) );
         }
 
-        // For some reason, it is not possible to plot currents in any but transient analysis
-        if( m_exporter->GetSimType() == ST_TRANSIENT )
+        if( m_exporter->GetSimMainType() == ST_TRANSIENT || m_exporter->GetSimMainType() == ST_DC )
         {
             for( const auto& item : m_exporter->GetSpiceItems() )
             {
-- 
2.11.0

>From 0699f7bb2185ac0fab9161dc746db20dd20bc8e1 Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 15 Feb 2018 09:14:57 +0100
Subject: [PATCH 06/11] modify source name view to manage i source and v source

---
 eeschema/dialogs/dialog_sim_settings.cpp | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/eeschema/dialogs/dialog_sim_settings.cpp b/eeschema/dialogs/dialog_sim_settings.cpp
index d93883e3a..6e2fa1341 100644
--- a/eeschema/dialogs/dialog_sim_settings.cpp
+++ b/eeschema/dialogs/dialog_sim_settings.cpp
@@ -362,8 +362,10 @@ bool DIALOG_SIM_SETTINGS::parseCommand( const wxString& aCommand )
 
             if( !tkn.IsEmpty() )
             {
+            	// keeping source type with value is not good idea, in the futur
+            	// better is to create a derivated class of  wxComboBox with a user data field
             	wxString srcName = tkn.SubString(1, tkn.Len());
-            	m_dcSource1->SetValue( wxString::Format( "(%c) %s", tkn[0], srcName ) );
+            	m_dcSource1->SetValue( wxString::Format( "(%c) %s", tkn[0], srcName ).Upper() );
                 m_dcStart1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
                 m_dcStop1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
                 m_dcIncr1->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
@@ -377,7 +379,8 @@ bool DIALOG_SIM_SETTINGS::parseCommand( const wxString& aCommand )
 
             if( !tkn.IsEmpty() )
             {
-                m_dcSource2->SetValue( tkn );
+            	wxString srcName = tkn.SubString(1, tkn.Len());
+                m_dcSource2->SetValue( wxString::Format( "(%c) %s", tkn[0], srcName ).Upper() );
                 m_dcStart2->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
                 m_dcStop2->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
                 m_dcIncr2->SetValue( SPICE_VALUE( tokenizer.GetNextToken() ).ToSpiceString() );
-- 
2.11.0

>From 5e823666932a385f2b78890f35542c76ed96b85a Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 15 Feb 2018 09:27:37 +0100
Subject: [PATCH 07/11] modify label for dc sweep settings, now we cna select
 i-sweep

---
 eeschema/dialogs/dialog_sim_settings_base.cpp | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/eeschema/dialogs/dialog_sim_settings_base.cpp b/eeschema/dialogs/dialog_sim_settings_base.cpp
index a18801867..a950c9a5d 100644
--- a/eeschema/dialogs/dialog_sim_settings_base.cpp
+++ b/eeschema/dialogs/dialog_sim_settings_base.cpp
@@ -141,21 +141,21 @@ DIALOG_SIM_SETTINGS_BASE::DIALOG_SIM_SETTINGS_BASE( wxWindow* parent, wxWindowID
 	m_dcSource2 = new wxComboBox( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0, NULL, 0 ); 
 	fgSizer2->Add( m_dcSource2, 0, wxALL, 5 );
 	
-	m_staticText5 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Starting voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText5 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Starting voltage or current [V,A]"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticText5->Wrap( -1 );
 	fgSizer2->Add( m_staticText5, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 	
 	m_dcStart2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer2->Add( m_dcStart2, 0, wxALL, 5 );
 	
-	m_staticText6 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Final voltage [V]"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText6 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Final voltage or current [V,A]"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticText6->Wrap( -1 );
 	fgSizer2->Add( m_staticText6, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 	
 	m_dcStop2 = new wxTextCtrl( sbSizer2->GetStaticBox(), wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, 0 );
 	fgSizer2->Add( m_dcStop2, 0, wxALL, 5 );
 	
-	m_staticText7 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Increment step [V]"), wxDefaultPosition, wxDefaultSize, 0 );
+	m_staticText7 = new wxStaticText( sbSizer2->GetStaticBox(), wxID_ANY, _("Increment step [V,A]"), wxDefaultPosition, wxDefaultSize, 0 );
 	m_staticText7->Wrap( -1 );
 	fgSizer2->Add( m_staticText7, 0, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
 	
-- 
2.11.0

>From 684dd84297d4ee78cf9cd4e08a052f900b4864ba Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 15 Feb 2018 10:23:20 +0100
Subject: [PATCH 08/11] manage new simulation type dc i-sweep

---
 eeschema/sim/netlist_exporter_pspice_sim.cpp | 35 ++++++++++++++++++++--------
 eeschema/sim/netlist_exporter_pspice_sim.h   | 13 +++++++++++
 eeschema/sim/ngspice.cpp                     | 20 ++++++++++------
 eeschema/sim/sim_plot_frame.cpp              | 12 ++++------
 4 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/eeschema/sim/netlist_exporter_pspice_sim.cpp b/eeschema/sim/netlist_exporter_pspice_sim.cpp
index ff4af88f2..911a68432 100644
--- a/eeschema/sim/netlist_exporter_pspice_sim.cpp
+++ b/eeschema/sim/netlist_exporter_pspice_sim.cpp
@@ -122,6 +122,10 @@ SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimType()
     return CommandToSimType( m_simCommand.IsEmpty() ? GetSheetSimCommand() : m_simCommand );
 }
 
+SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimMainType()
+{
+	return GetSimType() & ST_MAIN_TYPE_MASK;
+}
 
 SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
 {
@@ -133,23 +137,34 @@ SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
     wxString lcaseCmd = aCmd.Lower();
 
     if( lcaseCmd.StartsWith( ".dc") ){
-    	wxRegEx reg( wxT(".dc\\s+(\\w+\\s+\\w+\\s+\\w+\\s+\\w+)?\\s*(\\w+\\s+\\w+\\s+\\w+\\s+\\w+)"), wxRE_ADVANCED );
+    	wxRegEx reg( wxT(".dc\\s+(\\w+\\s+\\w+\\s+\\w+\\s+\\w+)\\s*(\\w+\\s+\\w+\\s+\\w+\\s+\\w+)?"), wxRE_ADVANCED );
     	if( reg.IsValid() )
     	{
     		if(reg.Matches(lcaseCmd))
     		{
     			int index = reg.GetMatchCount();
-    			if(index > 1)
+    			if( index > 1 )
     			{
-    				// get last sweep definition
-    				wxString sweep1 = reg.GetMatch( lcaseCmd, index -2 );
-    				wxString sweep = reg.GetMatch( lcaseCmd, index - 1);
-    				if(sweep[0] == 'i'){
-    					return ST_DC_ISWEEP;
-    				}
-    				if(sweep[0] == 'v'){
-    					return ST_DC_VSWEEP;
+    				SIM_TYPE stype;
+    				// get first sweep definition, get match begin to 0 for the overall regex match
+    				wxString firstSweep = reg.GetMatch( lcaseCmd, 1);
+    				if( firstSweep[0] == 'i' ) // last sweep is same than first
+    					stype = ST_DC_I_I;
+    				if( firstSweep[0] == 'v' )
+    					stype = ST_DC_V_V;
+    				if( index == 3 )
+    				{
+    					wxString lastSweep = reg.GetMatch( lcaseCmd, 2);
+    					if( firstSweep[0] == 'v' && lastSweep[0] == 'i' )
+    						stype = ST_DC_V_I;
+    					if( firstSweep[0] == 'v' && lastSweep[0] == 'v' )
+    						stype = ST_DC_V_V;
+    					if( firstSweep[0] == 'i' && lastSweep[0] == 'i' )
+    						stype = ST_DC_I_I;
+    					if( firstSweep[0] == 'i' && lastSweep[0] == 'v' )
+    						stype = ST_DC_I_V;
     				}
+    				return stype;
     			}
     		}
     	}
diff --git a/eeschema/sim/netlist_exporter_pspice_sim.h b/eeschema/sim/netlist_exporter_pspice_sim.h
index e93e88a2c..80c0d209b 100644
--- a/eeschema/sim/netlist_exporter_pspice_sim.h
+++ b/eeschema/sim/netlist_exporter_pspice_sim.h
@@ -96,6 +96,19 @@ public:
      */
     SIM_TYPE GetSimType();
 
+
+    /**
+     * @brief Returns simulation main type basing on the simulation command directives.
+     */
+    SIM_TYPE GetSimMainType();
+
+    /**
+	 * @brief Returns simulation complementary type basing on the simulation command directives.
+	 * Simulation directives set using SetSimCommand() have priority over the ones placed in
+	 * schematic sheets.
+	 */
+    SIM_TYPE GetComplementarySimType();
+
     /**
      * @brief Returns simulation command directives placed in schematic sheets (if any).
      */
diff --git a/eeschema/sim/ngspice.cpp b/eeschema/sim/ngspice.cpp
index 163172e6f..9df677a1a 100644
--- a/eeschema/sim/ngspice.cpp
+++ b/eeschema/sim/ngspice.cpp
@@ -243,19 +243,25 @@ bool NGSPICE::Command( const string& aCmd )
 
 string NGSPICE::GetXAxis( SIM_TYPE aType ) const
 {
-    switch( aType )
+    switch( aType & ST_MAIN_TYPE_MASK )
     {
         case ST_AC:
         case ST_NOISE:
             return string( "frequency" );
             break;
 
-        case ST_DC_VSWEEP:
-            return string( "v-sweep" );
-            break;
-
-        case ST_DC_ISWEEP:
-            return string( "i-sweep" );
+        case ST_DC:
+            switch( ( aType & SDCT_DC_LAST_MASK ) >> SDCT_DC_LAST_SHIFT )
+	    {
+        	case SDCT_VSWEEP:
+        	    return string( "v-sweep" );
+        	    break;
+        	case SDCT_ISWEEP:
+        	    return string( "i-sweep" );
+        	    break;
+        	default:
+        	    break;
+	    }
             break;
 
         case ST_TRANSIENT:
diff --git a/eeschema/sim/sim_plot_frame.cpp b/eeschema/sim/sim_plot_frame.cpp
index bf429f62f..5cf5b5f3a 100644
--- a/eeschema/sim/sim_plot_frame.cpp
+++ b/eeschema/sim/sim_plot_frame.cpp
@@ -260,7 +260,6 @@ void SIM_PLOT_FRAME::setSubWindowsSashSize()
         m_splitterTuneValues->SetSashPosition( m_splitterTuneValuesSashPosition );
 }
 
-
 void SIM_PLOT_FRAME::StartSimulation()
 {
     STRING_FORMATTER formatter;
@@ -494,7 +493,7 @@ bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL*
     std::vector<double> data_y;
 
     // Now, Y axis data
-    switch( m_exporter->GetSimType() )
+    switch( m_exporter->GetSimType() & ST_MAIN_TYPE_MASK )
     {
         case ST_AC:
         {
@@ -511,8 +510,7 @@ bool SIM_PLOT_FRAME::updatePlot( const TRACE_DESC& aDescriptor, SIM_PLOT_PANEL*
         break;
 
         case ST_NOISE:
-        case ST_DC_VSWEEP:
-        case ST_DC_ISWEEP:
+        case ST_DC:
         case ST_TRANSIENT:
         {
             data_y = m_simulator->GetMagPlot( (const char*) spiceVector.c_str() );
@@ -756,14 +754,13 @@ bool SIM_PLOT_FRAME::saveWorkbook( const wxString& aPath )
 
 SIM_PLOT_TYPE SIM_PLOT_FRAME::GetXAxisType( SIM_TYPE aType ) const
 {
-    switch( aType )
+    switch( aType & ST_MAIN_TYPE_MASK )
     {
         case ST_AC:
             return SPT_LIN_FREQUENCY;
             /// @todo SPT_LOG_FREQUENCY
 
-        case ST_DC_VSWEEP:
-        case ST_DC_ISWEEP:
+        case ST_DC:
             return SPT_SWEEP;
 
         case ST_TRANSIENT:
@@ -1181,7 +1178,6 @@ void SIM_PLOT_FRAME::onSimFinished( wxCommandEvent& aEvent )
         for( const auto& net : m_exporter->GetNetIndexMap() )
         {
             int node = net.second;
-
             if( node > 0 )
                 m_simulator->Command( wxString::Format( "print v(%d)", node ).ToStdString() );
         }
-- 
2.11.0

>From ca466bfa786a6a5a05a1a4ba021d70ad78fbfbf5 Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 15 Feb 2018 10:28:06 +0100
Subject: [PATCH 09/11] Add new types for dc i-sweep

---
 eeschema/sim/sim_types.h | 36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)

diff --git a/eeschema/sim/sim_types.h b/eeschema/sim/sim_types.h
index 3f7f3f58f..b0ceb4668 100644
--- a/eeschema/sim/sim_types.h
+++ b/eeschema/sim/sim_types.h
@@ -26,11 +26,43 @@
 #define SIM_TYPES_H
 
 ///> Possible simulation types
+
+// 4 least significant bits is use for main type
+// 4 most significant bits is use for complementary data link to main type (see DC_TYPE)
+#define ST_MAIN_TYPE_MASK 0x0F
+#define ST_COMP_TYPE_MASK 0xF0
+// we use SIM_TYPE bits for keeping dc type information
+#define SDCT_DC_FIRST_MASK 0xC0
+#define SDCT_DC_FIRST_SHIFT 6
+#define SDCT_DC_LAST_MASK 0x30
+#define SDCT_DC_LAST_SHIFT 4
+
+enum SIM_DC_TYPE {
+	SDCT_NONE = 0x0,
+	SDCT_VSWEEP = 0x1,
+	SDCT_ISWEEP = 0x2
+};
+
 enum SIM_TYPE {
-    ST_UNKNOWN, ST_AC, ST_DC_VSWEEP, ST_DC_ISWEEP, ST_DISTORTION, ST_NOISE, ST_OP,
-    ST_POLE_ZERO, ST_SENSITIVITY, ST_TRANS_FUNC, ST_TRANSIENT
+	ST_UNKNOWN = 0x00,
+	ST_AC = 0x01,
+	ST_DISTORTION = 0x02,
+	ST_NOISE = 0x03,
+	ST_OP = 0x04,
+	ST_POLE_ZERO = 0x05,
+	ST_SENSITIVITY = 0x06,
+	ST_TRANS_FUNC = 0x07,
+	ST_TRANSIENT = 0x08,
+	ST_DC = 0x0F, // generic dc type
+	ST_DC_V_V = 0x5F, // 01011111 First source is voltage, last source is voltage
+	ST_DC_V_I = 0x6F, // 01101111 First source is voltage, last source is current
+	ST_DC_I_I = 0xAF, // 10101111 First source is current, last source is current
+	ST_DC_I_V = 0x9F  // 10011111 First source is current, last source is voltage
 };
 
+
+
+
 ///> Possible plot types
 enum SIM_PLOT_TYPE {
     // Y axis
-- 
2.11.0

>From 474558bb23e8edd025b7f4f78e79cd59a02067bd Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 15 Feb 2018 10:30:36 +0100
Subject: [PATCH 10/11] modify plot construction for new graph i-sweep for dc
 simulation

---
 eeschema/sim/sim_plot_panel.cpp | 51 ++++++++++++++++++++++++++++++-----------
 1 file changed, 38 insertions(+), 13 deletions(-)

diff --git a/eeschema/sim/sim_plot_panel.cpp b/eeschema/sim/sim_plot_panel.cpp
index 66c8b2f15..b3529f710 100644
--- a/eeschema/sim/sim_plot_panel.cpp
+++ b/eeschema/sim/sim_plot_panel.cpp
@@ -208,6 +208,17 @@ public:
     }
 };
 
+class CURRENT_SCALE_X : public mpScaleX
+{
+public:
+    CURRENT_SCALE_X( wxString name, int flags ) :
+        mpScaleX( name, flags, false, 0 ) {};
+
+    void formatLabels() override
+    {
+        formatSILabels( this, wxT( "I" ), 3 );
+    }
+};
 
 class GAIN_SCALE : public mpScaleY
 {
@@ -249,10 +260,10 @@ public:
 };
 
 
-class CURRENT_SCALE : public mpScaleY
+class CURRENT_SCALE_Y : public mpScaleY
 {
 public:
-    CURRENT_SCALE( wxString name, int flags ) :
+    CURRENT_SCALE_Y( wxString name, int flags ) :
         mpScaleY( name, flags, false ) {};
 
     void formatLabels() override
@@ -374,7 +385,7 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
     EnableDoubleBuffer( true );
     UpdateAll();
 
-    switch( m_type )
+    switch( m_type & ST_MAIN_TYPE_MASK )
     {
         case ST_AC:
             m_axis_x = new FREQUENCY_LOG_SCALE( wxT( "Frequency" ), mpALIGN_BOTTOM );
@@ -383,10 +394,24 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
             m_axis_y2->SetMasterScale( m_axis_y1 );
             break;
 
-        case ST_DC_VSWEEP:
-        case ST_DC_ISWEEP:
-            m_axis_x = new VOLTAGE_SCALE_X( wxT( "Voltage (sweeped)" ), mpALIGN_BOTTOM );
-            m_axis_y1 = new VOLTAGE_SCALE_Y( wxT( "Voltage (measured)" ), mpALIGN_LEFT );
+        case ST_DC:
+        	switch( ( m_type & SDCT_DC_FIRST_MASK ) >> SDCT_DC_FIRST_SHIFT )
+        	{
+        		case SDCT_VSWEEP:
+        			m_axis_x = new VOLTAGE_SCALE_X( wxT( "Voltage (sweeped)" ), mpALIGN_BOTTOM );
+        			break;
+
+        		case SDCT_ISWEEP:
+        			m_axis_x = new CURRENT_SCALE_X( wxT( "Current (sweeped)" ), mpALIGN_BOTTOM );
+        			break;
+
+        		default:
+        			break;
+        	}
+            m_axis_y1 = new VOLTAGE_SCALE_Y( wxT( "Voltage" ), mpALIGN_LEFT );
+            m_axis_y2 = new CURRENT_SCALE_Y( wxT( "Current" ), mpALIGN_RIGHT );
+            // set master scale useless ? set in add trace
+            m_axis_y2->SetMasterScale( m_axis_y1 );
             break;
 
         case ST_NOISE:
@@ -397,7 +422,8 @@ SIM_PLOT_PANEL::SIM_PLOT_PANEL( SIM_TYPE aType, wxWindow* parent, wxWindowID id,
         case ST_TRANSIENT:
             m_axis_x = new TIME_SCALE( wxT( "Time" ), mpALIGN_BOTTOM );
             m_axis_y1 = new VOLTAGE_SCALE_Y( wxT( "Voltage" ), mpALIGN_LEFT );
-            m_axis_y2 = new CURRENT_SCALE( wxT( "Current" ), mpALIGN_RIGHT );
+            m_axis_y2 = new CURRENT_SCALE_Y( wxT( "Current" ), mpALIGN_RIGHT );
+            // set master scale useless ? set in add trace
             m_axis_y2->SetMasterScale( m_axis_y1 );
             break;
 
@@ -447,11 +473,10 @@ SIM_PLOT_PANEL::~SIM_PLOT_PANEL()
 
 bool SIM_PLOT_PANEL::IsPlottable( SIM_TYPE aSimType )
 {
-    switch( aSimType )
+    switch( aSimType & ST_MAIN_TYPE_MASK )
     {
         case ST_AC:
-        case ST_DC_VSWEEP:
-        case ST_DC_ISWEEP:
+        case ST_DC:
         case ST_TRANSIENT:
             return true;
 
@@ -472,7 +497,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
 
     if( addedNewEntry )
     {
-        if( m_type == ST_TRANSIENT )
+        if( m_type == ST_TRANSIENT || (m_type & ST_MAIN_TYPE_MASK) == ST_DC )
         {
             bool hasVoltageTraces = false;
 
@@ -529,7 +554,7 @@ bool SIM_PLOT_PANEL::AddTrace( const wxString& aName, int aPoints,
 
     trace->SetData( std::vector<double>( aX, aX + aPoints ), tmp );
 
-    if( aFlags & SPT_AC_PHASE || aFlags & SPT_CURRENT )
+    if( (aFlags & SPT_AC_PHASE) || (aFlags & SPT_CURRENT) )
         trace->SetScale( m_axis_x, m_axis_y2 );
     else
         trace->SetScale( m_axis_x, m_axis_y1 );
-- 
2.11.0

>From 80938920471e70049b534b66b56cf29cc71c1ea2 Mon Sep 17 00:00:00 2001
From: leau-mercier <lmercier@xxxxxxxxxxxxx>
Date: Thu, 22 Feb 2018 09:26:00 +0100
Subject: [PATCH 11/11] correction of getting main simulation type

---
 eeschema/dialogs/dialog_signal_list.cpp      | 4 ++--
 eeschema/sim/netlist_exporter_pspice_sim.cpp | 5 -----
 eeschema/sim/netlist_exporter_pspice_sim.h   | 6 ------
 3 files changed, 2 insertions(+), 13 deletions(-)

diff --git a/eeschema/dialogs/dialog_signal_list.cpp b/eeschema/dialogs/dialog_signal_list.cpp
index 6618e0137..92365d966 100644
--- a/eeschema/dialogs/dialog_signal_list.cpp
+++ b/eeschema/dialogs/dialog_signal_list.cpp
@@ -57,8 +57,8 @@ bool DIALOG_SIGNAL_LIST::TransferDataToWindow()
             if( net.first != "GND" )
                 m_signals->Append( wxString::Format( "V(%s)", net.first ) );
         }
-
-        if( m_exporter->GetSimMainType() == ST_TRANSIENT || m_exporter->GetSimMainType() == ST_DC )
+        int mainType = m_exporter->GetSimType() & ST_MAIN_TYPE_MASK;
+        if( mainType == ST_TRANSIENT || mainType == ST_DC )
         {
             for( const auto& item : m_exporter->GetSpiceItems() )
             {
diff --git a/eeschema/sim/netlist_exporter_pspice_sim.cpp b/eeschema/sim/netlist_exporter_pspice_sim.cpp
index 911a68432..6c5b430c4 100644
--- a/eeschema/sim/netlist_exporter_pspice_sim.cpp
+++ b/eeschema/sim/netlist_exporter_pspice_sim.cpp
@@ -122,11 +122,6 @@ SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimType()
     return CommandToSimType( m_simCommand.IsEmpty() ? GetSheetSimCommand() : m_simCommand );
 }
 
-SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::GetSimMainType()
-{
-	return GetSimType() & ST_MAIN_TYPE_MASK;
-}
-
 SIM_TYPE NETLIST_EXPORTER_PSPICE_SIM::CommandToSimType( const wxString& aCmd )
 {
     const std::map<wxString, SIM_TYPE> simCmds = {
diff --git a/eeschema/sim/netlist_exporter_pspice_sim.h b/eeschema/sim/netlist_exporter_pspice_sim.h
index 80c0d209b..6ea49a263 100644
--- a/eeschema/sim/netlist_exporter_pspice_sim.h
+++ b/eeschema/sim/netlist_exporter_pspice_sim.h
@@ -96,12 +96,6 @@ public:
      */
     SIM_TYPE GetSimType();
 
-
-    /**
-     * @brief Returns simulation main type basing on the simulation command directives.
-     */
-    SIM_TYPE GetSimMainType();
-
     /**
 	 * @brief Returns simulation complementary type basing on the simulation command directives.
 	 * Simulation directives set using SetSimCommand() have priority over the ones placed in
-- 
2.11.0


Follow ups