61 m_name->GetTextExtent(
"XXXXXXXXXXXXXXXXXXXXX", &x, &y );
62 m_name->SetMinSize( wxSize( x, -1 ) );
89 std::vector<int> trackColIds;
102 wxGridCellAttr* attr =
new wxGridCellAttr;
105 [
this](
int row,
int col )
107 calculateTrackParametersForCell( row, col );
112 attr =
new wxGridCellAttr;
115 [
this](
int row,
int col )
117 calculateTrackParametersForCell( row, col );
122 attr =
new wxGridCellAttr;
125 [
this](
int row,
int col )
127 calculateTrackParametersForCell( row, col );
142 std::vector<int> viaColIds;
163 m_type->SetSelection(
static_cast<int>( aProfile.
m_Type ) );
186 board->
GetLayerName( entry.GetBottomReferenceLayer() ) );
218 double targetImpedance;
233 m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
242 if( wxString bottomReferenceLayerName =
244 m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
275 std::swap( signalLayerIdFrom, signalLayerIdTo );
278 std::swap( viaLayerIdFrom, viaLayerIdTo );
298 wxArrayString layerNames, layerNamesWithNone;
299 layerNamesWithNone.push_back(
"<None>" );
301 [&layerNames, &layerNamesWithNone](
const wxString& aLayerName )
303 layerNames.push_back( aLayerName );
304 layerNamesWithNone.push_back( aLayerName );
309 std::vector<wxString> currentSignalLayer;
310 std::vector<wxString> currentTopReferenceLayer;
311 std::vector<wxString> currentBottomReferenceLayer;
317 currentBottomReferenceLayer.emplace_back(
322 std::vector<wxString> currentSignalLayersFrom;
323 std::vector<wxString> currentSignalLayersTo;
324 std::vector<wxString> currentViaLayersFrom;
325 std::vector<wxString> currentViaLayersTo;
336 wxGridCellAttr* attr =
new wxGridCellAttr;
337 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
340 attr =
new wxGridCellAttr;
341 attr->SetEditor(
new wxGridCellChoiceEditor( layerNamesWithNone,
false ) );
344 attr =
new wxGridCellAttr;
345 attr->SetEditor(
new wxGridCellChoiceEditor( layerNamesWithNone,
false ) );
348 attr =
new wxGridCellAttr;
349 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
352 attr =
new wxGridCellAttr;
353 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
356 attr =
new wxGridCellAttr;
357 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
360 attr =
new wxGridCellAttr;
361 attr->SetEditor(
new wxGridCellChoiceEditor( layerNames,
false ) );
367 if(
m_parentPanel->m_prevLayerNamesToIDs.contains( currentSignalLayer[row] ) )
371 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalId ) )
383 if(
m_parentPanel->m_prevLayerNamesToIDs.contains( currentTopReferenceLayer[row] ) )
387 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastTopReferenceId ) )
389 m_parentPanel->m_board->GetLayerName( lastTopReferenceId ) );
398 if(
m_parentPanel->m_prevLayerNamesToIDs.contains( currentBottomReferenceLayer[row] ) )
401 m_parentPanel->m_prevLayerNamesToIDs[currentBottomReferenceLayer[row]];
403 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastBottomReferenceId ) )
405 m_parentPanel->m_board->GetLayerName( lastBottomReferenceId ) );
419 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalFromId ) )
427 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastSignalToId ) )
435 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastViaFromId ) )
443 if(
m_parentPanel->m_copperLayerIdsToIndex.contains( lastViaToId ) )
468 const int titleSize = GetTextExtent(
m_viaOverrides->GetColLabelValue( i ) ).x;
470 m_viaOverrides->SetColSize( i, std::max( titleSize, minValueWidth ) );
475 const int impedanceWidth =
m_targetImpedance->GetTextExtent( wxT(
"0000.00" ) ).x;
484 const wxString newName =
event.GetString();
491 if( event.GetSelection() == 0 )
515 auto setFrontRowLayers = [&](
const int row )
532 auto setRowLayers = [&]()
536 setFrontRowLayers( 0 );
540 const wxString lastSignalLayerName =
543 lastSignalLayerName );
550 setFrontRowLayers( numRows );
581 if( selRows.size() == 1 )
603 if( selRows.size() == 1 )
610 return m_name->GetValue();
615 const double aSigma )
624 bool layerFound =
false;
625 int layerStackupId = 0;
627 while( layerStackupId <
static_cast<int>( aLayerList.size() ) && !layerFound )
629 if( aLayerList.at( layerStackupId )->GetBrdLayerId() != aPcbLayerId )
638 return layerStackupId;
647 if( !zStr.ToDouble( &z ) )
655 const std::vector<BOARD_STACKUP_ITEM*>& aStackupLayerList,
const std::vector<int>& dielectricLayerStackupIds,
658 double totalHeight = 0.0;
660 double lossTangent = 0.0;
662 for(
int i : dielectricLayerStackupIds )
666 for(
int subLayerIdx = 0; subLayerIdx < layer->
GetSublayersCount(); ++subLayerIdx )
674 e_r = e_r / totalHeight;
675 lossTangent = lossTangent / totalHeight;
676 totalHeight /= 1000.0;
678 return { totalHeight, e_r, lossTangent };
683 const int aSignalLayerId,
const int aReferenceLayerId,
684 std::vector<int>& aDielectricLayerStackupIds )
686 for(
int i = std::min( aSignalLayerId, aReferenceLayerId ) + 1; i < std::max( aSignalLayerId, aReferenceLayerId );
697 aDielectricLayerStackupIds.push_back( i );
707 if( !
m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
727 int calculatedWidth = 0;
728 int calculatedGap = 0;
729 int calculatedDelay = 0;
744 calculatedWidth =
result.Width;
745 calculatedGap =
result.DiffPairGap;
746 calculatedDelay =
result.Delay;
748 const bool widthOk = calculatedWidth > 0;
749 const bool gapOk = calculatedGap > 0;
750 const bool delayOk = calculatedDelay > 0;
781 int calculatedWidth = 0;
782 int calculatedDelay = 0;
797 calculatedWidth =
result.Width;
798 calculatedDelay =
result.Delay;
800 const bool widthOk = calculatedWidth > 0;
801 const bool delayOk = calculatedDelay > 0;
826 if(
m_name->GetValue() == wxEmptyString )
830 const wxString msg =
_(
"Tuning profile must have a name" );
835 std::set<wxString> layerNames;
841 if( layerNames.contains( layerName ) )
845 const wxString msg =
_(
"Duplicated signal layer configuration in tuning profile" );
851 layerNames.insert( layerName );
868 const std::vector<BOARD_STACKUP_ITEM*>& stackupLayerList = stackup.
GetList();
872 if( !
m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
878 if( signalLayer !=
F_Cu && signalLayer !=
B_Cu )
879 return { {},
CALCULATION_RESULT{
_(
"Internal error: Microstrip can only be on an outer copper layer" ) } };
881 const int signalLayerStackupId =
getStackupLayerId( stackupLayerList, signalLayer );
883 if( signalLayerStackupId == -1 )
886 const double signalLayerThickness =
887 aScale.
IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
889 if( signalLayerThickness <= 0 )
893 wxString referenceLayerName;
895 if( signalLayer ==
F_Cu )
900 if( !
m_parentPanel->m_layerNamesToIDs.contains( referenceLayerName ) )
904 const int referenceLayerStackupId =
getStackupLayerId( stackupLayerList, referenceLayer );
906 if( signalLayerStackupId == referenceLayerStackupId )
907 return { {},
CALCULATION_RESULT{
_(
"Reference layer must be different to signal layer" ) } };
910 std::vector<int> dielectricLayerStackupIds;
911 getDielectricLayers( stackupLayerList, signalLayerStackupId, referenceLayerStackupId, dielectricLayerStackupIds );
917 if( dielectricInfo.
Height <= 0.0 )
925 return { boardParameters,
result };
935 const std::vector<BOARD_STACKUP_ITEM*>& stackupLayerList = stackup.
GetList();
939 if( !
m_parentPanel->m_layerNamesToIDs.contains( signalLayerName ) )
943 const int signalLayerStackupId =
getStackupLayerId( stackupLayerList, signalLayer );
945 if( signalLayerStackupId == -1 )
948 const double signalLayerThickness =
949 aScale.
IUTomm( stackupLayerList.at( signalLayerStackupId )->GetThickness() ) / 1000.0;
951 if( signalLayerThickness <= 0 )
957 if( !
m_parentPanel->m_layerNamesToIDs.contains( topReferenceLayerName ) )
961 const int topReferenceLayerStackupId =
getStackupLayerId( stackupLayerList, topReferenceLayer );
964 return { {},
CALCULATION_RESULT{
_(
"Top reference layer must be above signal layer in board stackup" ) } };
969 if( !
m_parentPanel->m_layerNamesToIDs.contains( bottomReferenceLayerName ) )
973 const int bottomReferenceLayerStackupId =
getStackupLayerId( stackupLayerList, bottomReferenceLayer );
976 return { {},
CALCULATION_RESULT{
_(
"Bottom reference layer must be below signal layer in board stackup" ) } };
979 std::vector<int> topDielectricLayerStackupIds, bottomDielectricLayerStackupIds;
982 topDielectricLayerStackupIds );
983 getDielectricLayers( stackupLayerList, signalLayerStackupId, bottomReferenceLayerStackupId,
984 bottomDielectricLayerStackupIds );
987 std::vector<int> allDielectricLayerStackupIds( topDielectricLayerStackupIds );
988 allDielectricLayerStackupIds.insert( allDielectricLayerStackupIds.end(), bottomDielectricLayerStackupIds.begin(),
989 bottomDielectricLayerStackupIds.end() );
998 if( topDielectricInfo.
Height <= 0.0 && bottomDielectricInfo.
Height <= 0.0 )
1002 bottomDielectricInfo.
Height, signalLayerThickness,
1007 return { boardParameters,
result };
1037 const double width = iuScale.
IUTomm( widthInt ) / 1000.0;
1063 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
1064 [
this, aCalculationType]() ->
decltype(
m_microstripCalc.GetSynthesisResults() )
1113 const double width = iuScale.
IUTomm( widthInt ) / 1000.0;
1123 + boardParameters.SignalLayerThickness
1124 + boardParameters.BottomDielectricLayerThickness );
1138 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
1139 [
this, aCalculationType]() ->
decltype(
m_striplineCalc.GetSynthesisResults() )
1188 if( !gapOpt || *gapOpt <= 0 )
1189 return CALCULATION_RESULT{
_(
"Diff pair gap must be greater than 0 to calculate width" ) };
1191 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1195 if( !widthOpt || *widthOpt <= 0 )
1196 return CALCULATION_RESULT{
_(
"Width must be greater than 0 to calculate diff pair gap" ) };
1198 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1202 if( !widthOpt || !gapOpt || *widthOpt <= 0 || *gapOpt <= 0 )
1203 return CALCULATION_RESULT{
_(
"Width and diff pair gap must be greater than 0 to calculate delay" ) };
1205 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1206 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1228 switch( aCalculationType )
1235 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
1236 [
this, aCalculationType]() ->
decltype(
m_microstripCalc.GetSynthesisResults() )
1290 if( !gapOpt || *gapOpt <= 0 )
1291 return CALCULATION_RESULT{
_(
"Diff pair gap must be greater than 0 to calculate width" ) };
1293 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1297 if( !widthOpt || *widthOpt <= 0 )
1298 return CALCULATION_RESULT{
_(
"Width must be greater than 0 to calculate diff pair gap" ) };
1300 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1304 if( !widthOpt || !gapOpt || *widthOpt <= 0 || *gapOpt <= 0 )
1305 return CALCULATION_RESULT{
_(
"Width and diff pair gap must be greater than 0 to calculate delay" ) };
1307 width = iuScale.
IUTomm( widthOpt.value() ) / 1000.0;
1308 gap = iuScale.
IUTomm( gapOpt.value() ) / 1000.0;
1320 + boardParameters.BottomDielectricLayerThickness );
1329 switch( aCalculationType )
1336 std::unordered_map<TRANSLINE_PARAMETERS, std::pair<double, TRANSLINE_STATUS>>& results =
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap, int aMinHeight)
@ BS_ITEM_TYPE_DIELECTRIC
Manage one layer needed to make a physical board.
int GetSublayersCount() const
double GetEpsilonR(int aDielectricSubLayer=0) const
bool HasEpsilonRValue() const
int GetThickness(int aDielectricSubLayer=0) const
BOARD_STACKUP_ITEM_TYPE GetType() const
double GetLossTangent(int aDielectricSubLayer=0) const
Manage layers needed to make a physical board.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
Information pertinent to a Pcbnew printed circuit board.
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
Represents a single line in a time domain profile track propagation setup.
void SetWidth(const int aWidth)
void SetEnableTimeDomainTuning(bool aEnable)
void SetDiffPairGap(const int aDiffPairGap)
void SetTopReferenceLayer(const PCB_LAYER_ID aLayer)
void SetSignalLayer(const PCB_LAYER_ID aLayer)
void SetDelay(const int aDelay)
void SetBottomReferenceLayer(const PCB_LAYER_ID aLayer)
PCB_LAYER_ID GetSignalLayer() const
A cell editor which runs a provided function when the grid cell button is clicked.
Add mouse and command handling (such as cut, copy, and paste) to a WX_GRID instance.
static PAGED_DIALOG * GetDialog(wxWindow *aWindow)
void SetError(const wxString &aMessage, const wxString &aPageName, int aCtrlId, int aRow=-1, int aCol=-1)
WX_GRID * m_trackPropagationGrid
PANEL_SETUP_TUNING_PROFILE_INFO_BASE(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxSize(719, 506), long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
wxStaticText * m_viaPropSpeedUnits
STD_BITMAP_BUTTON * m_deleteTrackPropogationLayer
STD_BITMAP_BUTTON * m_addViaPropagationOverride
STD_BITMAP_BUTTON * m_addTrackPropogationLayer
wxTextCtrl * m_viaPropagationSpeed
wxCheckBox * m_enableDelayTuning
STD_BITMAP_BUTTON * m_removeViaPropagationOverride
wxStaticText * m_viaPropagationSpeedLabel
wxTextCtrl * m_targetImpedance
void OnAddViaOverride(wxCommandEvent &event) override
Adds a via override row.
static constexpr double RHO
MICROSTRIP m_microstripCalc
Calculator for single microstrip parameters.
COUPLED_STRIPLINE m_coupledStriplineCalc
Calculator for coupled (differential) stripline parameters.
void initPanel()
Initialises all controls on the panel.
void calculateTrackParametersForCell(int aRow, int aCol)
Calculates the required track parameters for the given track parameters grid row and col.
@ TRACK_GRID_BOTTOM_REFERENCE
@ TRACK_GRID_TOP_REFERENCE
@ TRACK_GRID_SIGNAL_LAYER
CALCULATION_RESULT calculateSingleStripline(const int aRow, CalculationType aCalculationType)
Calculates the track width or delay for the given propagation grid row.
double getTargetImpedance() const
Gets the target impedance for the profile.
CALCULATION_RESULT calculateSingleMicrostrip(const int aRow, CalculationType aCalculationType)
Calculates the track width or delay for the given propagation grid row.
STRIPLINE m_striplineCalc
Calculator for single stripline parameters.
static double calculateSkinDepth(double aFreq, double aMurc, double aSigma)
Calculate the effective skin depth for the given parameters.
bool ValidateProfile(size_t aPageIndex)
Validate this panel's data.
void UpdateLayerNames()
Updates the displayed layer names in all grids.
static int getStackupLayerId(const std::vector< BOARD_STACKUP_ITEM * > &aLayerList, PCB_LAYER_ID aPcbLayerId)
Gets the index in to the layer list for the given layer.
UNIT_BINDER m_viaPropagationUnits
Units for global via propagation unit delay.
CALCULATION_RESULT calculateDifferentialMicrostrip(int aRow, CalculationType aCalculationType)
Calculates the track width, pair gap, or delay for the given propagation grid row.
std::pair< CALCULATION_BOARD_PARAMETERS, CALCULATION_RESULT > getMicrostripBoardParameters(int aRow, const EDA_IU_SCALE &aScale)
Gets the board parameters for microstrip calculations @parameter aRow The grid row to calculate board...
PANEL_SETUP_TUNING_PROFILE_INFO(wxWindow *aParentWindow, PANEL_SETUP_TUNING_PROFILES *parentPanel)
static DIELECTRIC_INFO calculateAverageDielectricConstants(const std::vector< BOARD_STACKUP_ITEM * > &aStackupLayerList, const std::vector< int > &dielectricLayerStackupIds, const EDA_IU_SCALE &aIuScale)
Calculates the geometric average of the dielectric material properties.
void LoadProfile(const TUNING_PROFILE &aProfile)
Loads the given profile in to the panel.
TUNING_PROFILE GetProfile() const
Saves the panel to the given profile.
~PANEL_SETUP_TUNING_PROFILE_INFO() override
PANEL_SETUP_TUNING_PROFILES * m_parentPanel
The parent setup panel.
void OnChangeProfileType(wxCommandEvent &event) override
Changes between Single and Differential profiles.
std::pair< CALCULATION_BOARD_PARAMETERS, CALCULATION_RESULT > getStriplineBoardParameters(int aRow, const EDA_IU_SCALE &aScale)
Gets the board parameters for stripline calculations @parameter aRow The grid row to calculate board ...
void getDielectricLayers(const std::vector< BOARD_STACKUP_ITEM * > &aStackupLayerList, int aSignalLayerId, int aReferenceLayerId, std::vector< int > &aDielectricLayerStackupIds)
Gets the dielectric layers for dielectrics between the two given copper layer IDs.
void OnRemoveTrackRow(wxCommandEvent &event) override
Removes a row from the track propagation grid.
@ VIA_GRID_SIGNAL_LAYER_TO
@ VIA_GRID_SIGNAL_LAYER_FROM
@ VIA_GRID_VIA_LAYER_FROM
wxString GetProfileName() const
Gets the name of this profile.
COUPLED_MICROSTRIP m_coupledMicrostripCalc
Calculator for coupled (differential) microstrip parameters.
CALCULATION_RESULT calculateDifferentialStripline(int aRow, CalculationType aCalculationType)
Calculates the track width, pair gap, or delay for the given propagation grid row.
void onChangeProfileType(TUNING_PROFILE::PROFILE_TYPE aType) const
Sets the panel display for the given tuning type.
void OnRemoveViaOverride(wxCommandEvent &event) override
Removes a via override row.
void OnAddTrackRow(wxCommandEvent &event) override
Adds a row to the track propagation grid.
void setColumnWidths()
Set up the widths of all grid columns.
void OnProfileNameChanged(wxCommandEvent &event) override
Updates the parent notebook control.
EDA_UNITS GetUnitsFromType(EDA_DATA_TYPE aType) const
Gets the units to use in the conversion based on the underlying user units.
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
This file is part of the common library.
bool IsCopperLayerLowerThan(PCB_LAYER_ID aLayerA, PCB_LAYER_ID aLayerB)
Return true if copper aLayerA is placed lower than aLayerB, false otherwise.
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
PCB_LAYER_ID
A quick note on layer IDs:
KICOMMON_API double FromUserUnit(const EDA_IU_SCALE &aIuScale, EDA_UNITS aUnit, double aValue)
Return in internal units the value aValue given in a real unit such as "in", "mm",...
KICOMMON_API bool IsImperialUnit(EDA_UNITS aUnit)
Represents a single line in the time domain configuration via overrides configuration grid.
constexpr double IUTomm(int iu) const
Represents a single line in the tuning profile configuration grid.
bool m_EnableTimeDomainTuning
std::map< PCB_LAYER_ID, DELAY_PROFILE_TRACK_PROPAGATION_ENTRY > m_TrackPropagationEntriesMap
std::vector< DELAY_PROFILE_VIA_OVERRIDE_ENTRY > m_ViaOverrides
int m_ViaPropagationDelay
std::vector< DELAY_PROFILE_TRACK_PROPAGATION_ENTRY > m_TrackPropagationEntries
wxString result
Test unit parsing edge cases and error handling.