← Back to team overview

kicad-developers team mailing list archive

[PATCH] Three new source types added to DIALOG_SPICE_MODEL

 

Hi,

Here is a patch with three additional source models implemented: SFFM, AM and Random.

I hope this looks ok, cause I had troubles with configuring clang-format on Windows. If no, I can correct.

Best regards,
Sylwester
From 5eb344844c7c246e973b312d0e4413afadbb8977 Mon Sep 17 00:00:00 2001
From: Sylwester Kocjan <s.kocjan@xxxxx>
Date: Sun, 20 Oct 2019 17:30:43 +0200
Subject: [PATCH] Eeschema: Adding new source types in SPICE model

NEW: Adds support in eeschema for three new source types
used in .TRAN simulation: single frequency FM, AM, and random.
---
 eeschema/dialogs/dialog_spice_model.cpp      |   166 +-
 eeschema/dialogs/dialog_spice_model.h        |     5 +-
 eeschema/dialogs/dialog_spice_model_base.cpp |   650 +-
 eeschema/dialogs/dialog_spice_model_base.fbp | 24945 ++++++++---------
 eeschema/dialogs/dialog_spice_model_base.h   |    73 +-
 5 files changed, 12611 insertions(+), 13228 deletions(-)

diff --git a/eeschema/dialogs/dialog_spice_model.cpp b/eeschema/dialogs/dialog_spice_model.cpp
index fa3441040..c14ef1783 100644
--- a/eeschema/dialogs/dialog_spice_model.cpp
+++ b/eeschema/dialogs/dialog_spice_model.cpp
@@ -148,14 +148,39 @@ void DIALOG_SPICE_MODEL::Init()
     m_expRiseConst->SetValidator( m_spiceEmptyValidator );
     m_expFallDelay->SetValidator( m_spiceEmptyValidator );
     m_expFallConst->SetValidator( m_spiceEmptyValidator );
+
+    m_fmOffset->SetValidator( m_spiceEmptyValidator );
+    m_fmAmplitude->SetValidator( m_spiceEmptyValidator );
+    m_fmFcarrier->SetValidator( m_spiceEmptyValidator );
+    m_fmModIndex->SetValidator( m_spiceEmptyValidator );
+    m_fmFsignal->SetValidator( m_spiceEmptyValidator );
+    m_fmPhaseC->SetValidator( m_spiceEmptyValidator );
+    m_fmPhaseS->SetValidator( m_spiceEmptyValidator );
+
+    m_amAmplitude->SetValidator( m_spiceEmptyValidator );
+    m_amOffset->SetValidator( m_spiceEmptyValidator );
+    m_amModulatingFreq->SetValidator( m_spiceEmptyValidator );
+    m_amCarrierFreq->SetValidator( m_spiceEmptyValidator );
+    m_amSignalDelay->SetValidator( m_spiceEmptyValidator );
+    m_amPhase->SetValidator( m_spiceEmptyValidator );
+
+    m_rnTS->SetValidator( m_spiceEmptyValidator );
+    m_rnTD->SetValidator( m_spiceEmptyValidator );
+    m_rnParam1->SetValidator( m_spiceEmptyValidator );
+    m_rnParam2->SetValidator( m_spiceEmptyValidator );
 
     m_pwlTimeCol = m_pwlValList->AppendColumn( "Time [s]", wxLIST_FORMAT_LEFT, 100 );
     m_pwlValueCol = m_pwlValList->AppendColumn( "Value [V/A]", wxLIST_FORMAT_LEFT, 100 );
 
-    m_sdbSizerOK->SetDefault();
-}
-
-
+    m_sdbSizerOK->SetDefault();
+
+    // Hide pages that aren't fully implemented yet
+    // wxPanel::Hide() isn't enough on some platforms
+    m_powerNotebook->RemovePage( m_powerNotebook->FindPage( m_pwrTransNoise ) );
+    m_powerNotebook->RemovePage( m_powerNotebook->FindPage( m_pwrExtData ) );
+}
+
+
 bool DIALOG_SPICE_MODEL::TransferDataFromWindow()
 {
     if( !DIALOG_SPICE_MODEL_BASE::TransferDataFromWindow() )
@@ -466,6 +491,52 @@ bool DIALOG_SPICE_MODEL::parsePowerSource( const wxString& aModel )
             }
         }
 
+
+        else if( tkn == "sffm" )
+        {
+            m_powerNotebook->SetSelection( m_powerNotebook->FindPage( m_pwrFm ) );
+
+            genericProcessing = true;
+            genericReqParamsCount = 4;
+            genericControls = { m_fmOffset, m_fmAmplitude,
+                m_fmFcarrier, m_fmModIndex, m_fmFsignal, m_fmFsignal, m_fmPhaseC, m_fmPhaseS };
+        }
+
+
+        else if( tkn == "am" )
+        {
+            m_powerNotebook->SetSelection( m_powerNotebook->FindPage( m_pwrAm ) );
+
+            genericProcessing = true;
+            genericReqParamsCount = 5;
+            genericControls = { m_amAmplitude, m_amOffset,
+                m_amModulatingFreq, m_amCarrierFreq, m_amSignalDelay, m_amPhase };
+        }
+
+
+        else if( tkn == "trrandom" )
+        {
+            m_powerNotebook->SetSelection( m_powerNotebook->FindPage( m_pwrRandom ) );
+
+            // first token will configure drop-down list
+            if( !tokenizer.HasMoreTokens() )
+                return false;
+
+            tkn = tokenizer.GetNextToken().Lower();
+            long type;
+            if( !tkn.ToLong( &type ) )
+                return false;
+
+            m_rnType->SetSelection( type - 1 );
+            wxCommandEvent dummy;
+            onRandomSourceType( dummy );
+
+            // remaining parameters can be handled in generic way
+            genericProcessing = true;
+            genericReqParamsCount = 4;
+            genericControls = { m_rnTS, m_rnTD, m_rnParam1, m_rnParam2 };
+        }
+
 
         else
         {
@@ -551,7 +622,7 @@ bool DIALOG_SPICE_MODEL::generatePowerSource( wxString& aTarget ) const
             return false;
 
         genericProcessing = true;
-        trans += "pulse";
+        trans += "pulse(";
         genericReqParamsCount = 2;
         genericControls = { m_pulseInit, m_pulseNominal, m_pulseDelay,
             m_pulseRise, m_pulseFall, m_pulseWidth, m_pulsePeriod };
@@ -564,7 +635,7 @@ bool DIALOG_SPICE_MODEL::generatePowerSource( wxString& aTarget ) const
             return false;
 
         genericProcessing = true;
-        trans += "sin";
+        trans += "sin(";
         genericReqParamsCount = 2;
         genericControls = { m_sinOffset, m_sinAmplitude, m_sinFreq, m_sinDelay, m_sinDampFactor };
     }
@@ -576,7 +647,7 @@ bool DIALOG_SPICE_MODEL::generatePowerSource( wxString& aTarget ) const
             return false;
 
         genericProcessing = true;
-        trans += "exp";
+        trans += "exp(";
         genericReqParamsCount = 2;
         genericControls = { m_expInit, m_expPulsed,
             m_expRiseDelay, m_expRiseConst, m_expFallDelay, m_expFallConst };
@@ -598,12 +669,52 @@ bool DIALOG_SPICE_MODEL::generatePowerSource( wxString& aTarget ) const
             trans.Trim();
             trans += ")";
         }
-    }
+    }
 
-    if( genericProcessing )
+
+    else if( page == m_pwrFm )
     {
-        trans += "(";
+        if( !m_pwrFm->Validate() )
+            return false;
+
+        genericProcessing = true;
+        trans += "sffm(";
+        genericReqParamsCount = 4;
+        genericControls = { m_fmOffset, m_fmAmplitude,
+            m_fmFcarrier, m_fmModIndex, m_fmFsignal, m_fmFsignal, m_fmPhaseC, m_fmPhaseS };
+    }
+
+
+    else if( page == m_pwrAm )
+    {
+        if( !m_pwrAm->Validate() )
+            return false;
 
+        genericProcessing = true;
+        trans += "am(";
+        genericReqParamsCount = 5;
+        genericControls = { m_amAmplitude, m_amOffset,
+            m_amModulatingFreq, m_amCarrierFreq, m_amSignalDelay, m_amPhase };
+    }
+
+
+    else if( page == m_pwrRandom )
+    {
+        if( !m_pwrRandom->Validate() )
+            return false;
+
+        // first parameter must be retrieved from drop-down list selection
+        trans += "trrandom(";
+        trans.Append( wxString::Format( wxT( "%i " ), (m_rnType->GetSelection() + 1 ) ) );
+
+        genericProcessing = true;
+        genericReqParamsCount = 4;
+        genericControls = { m_rnTS, m_rnTD, m_rnParam1, m_rnParam2 };
+    }
+
+
+    if( genericProcessing )
+    {
         auto first_empty = std::find_if( genericControls.begin(), genericControls.end(), empty );
         auto first_not_empty = std::find_if( genericControls.begin(), genericControls.end(),
                 []( const wxTextCtrl* c ){ return !empty( c ); } );
@@ -876,6 +987,41 @@ void DIALOG_SPICE_MODEL::onPwlRemove( wxCommandEvent& event )
���q�^u���b�

Follow ups