KiCad PCB EDA Suite
Loading...
Searching...
No Matches
panel_regulator.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KICAD, a free EDA CAD application.
3 *
4 * Copyright (C) 1992-2011 jean-pierre.charras
5 * Copyright (C) 1992-2024 Kicad Developers, see AUTHORS.txt for contributors.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21#include <wx/choicdlg.h>
22#include <wx/filedlg.h>
23#include <wx/msgdlg.h>
24#include <wx/clipbrd.h>
25
26#include <bitmaps.h>
31
32extern double DoubleFromString( const wxString& TextValue );
33
34// extension of pcb_calculator data filename:
35static const wxString DataFileNameExt( wxT( "pcbcalc" ) );
36
37
38PANEL_REGULATOR::PANEL_REGULATOR( wxWindow* parent, wxWindowID id, const wxPoint& pos,
39 const wxSize& size, long style, const wxString& name ) :
40 PANEL_REGULATOR_BASE( parent, id, pos, size, style, name ),
41 m_RegulatorListChanged( false )
42{
43 m_bitmapRegul3pins->SetBitmap( KiBitmapBundle( BITMAPS::regul_3pins ) );
44 m_bitmapRegul4pins->SetBitmap( KiBitmapBundle( BITMAPS::regul ) );
45
48
49 // Needed on wxWidgets 3.0 to ensure sizers are correctly set
50 GetSizer()->SetSizeHints( this );
51}
52
54{
55}
56
57
59{
60 // Update the bitmaps
61 m_bitmapRegul3pins->SetBitmap( KiBitmapBundle( BITMAPS::regul_3pins ) );
62 m_bitmapRegul4pins->SetBitmap( KiBitmapBundle( BITMAPS::regul ) );
63}
64
65
67{
69}
70
71
73{
74 m_resTolVal->SetValue( wxT( DEFAULT_REGULATOR_RESTOL ) );
75
76 m_r1MinVal->SetValue( wxT( "" ) );
77 m_r1TypVal->SetValue( wxT( DEFAULT_REGULATOR_R1 ) );
78 m_r1MaxVal->SetValue( wxT( "" ) );
79
80 m_r2MinVal->SetValue( wxT( "" ) );
81 m_r2TypVal->SetValue( wxT( DEFAULT_REGULATOR_R2 ) );
82 m_r2MaxVal->SetValue( wxT( "" ) );
83
84 m_vrefMinVal->SetValue( wxT( DEFAULT_REGULATOR_VREF_MIN ) );
85 m_vrefTypVal->SetValue( wxT( DEFAULT_REGULATOR_VREF_TYP ) );
86 m_vrefMaxVal->SetValue( wxT( DEFAULT_REGULATOR_VREF_MAX ) );
87
88 m_voutMinVal->SetValue( wxT( "" ) );
89 m_voutTypVal->SetValue( wxT( DEFAULT_REGULATOR_VOUT_TYP ) );
90 m_voutMaxVal->SetValue( wxT( "" ) );
91
92 m_iadjTypVal->SetValue( wxT( DEFAULT_REGULATOR_IADJ_TYP ) );
93 m_iadjMaxVal->SetValue( wxT( DEFAULT_REGULATOR_IADJ_MAX ) );
94
95 m_tolTotalMin->SetValue( wxT( "" ) );
96 m_TolTotalMax->SetValue( wxT( "" ) );
97
98 m_choiceRegType->SetSelection( 1 );
99 m_rbRegulR1->SetValue( false );
100 m_rbRegulR2->SetValue( false );
101 m_rbRegulVout->SetValue( true );
103}
104
105
107{
108 switch( m_choiceRegType->GetSelection() )
109 {
110 default:
111 case 0:
112 m_bitmapRegul4pins->Show( true );
113 m_bitmapRegul3pins->Show( false );
114
115 m_RegulIadjTitle->Show( false );
116 m_iadjTypVal->Show( false );
117 m_iadjMaxVal->Show( false );
118 m_labelUnitsIadj->Show( false );
119
120 m_RegulFormula->SetLabel( wxT( "Vout = Vref * (R1 + R2) / R2" ) );
121 break;
122
123 case 1:
124 m_bitmapRegul4pins->Show( false );
125 m_bitmapRegul3pins->Show( true );
126
127 m_RegulIadjTitle->Show( true );
128 m_iadjTypVal->Show( true );
129 m_iadjMaxVal->Show( true );
130 m_labelUnitsIadj->Show( true );
131
132 m_RegulFormula->SetLabel( wxT( "Vout = Vref * (R1 + R2) / R1 + Iadj * R2" ) );
133 break;
134 }
135
136 // The new icon size must be taken in account
137 GetSizer()->Layout();
138
139 // Enable/disable buttons:
140 bool enbl = m_choiceRegulatorSelector->GetCount() > 0;
141 m_buttonEditItem->Enable( enbl );
142 m_buttonRemoveItem->Enable( enbl );
143
144 Refresh();
145}
146
147
148void PANEL_REGULATOR::OnRegulTypeSelection( wxCommandEvent& event )
149{
151}
152
153
154void PANEL_REGULATOR::OnRegulatorSelection( wxCommandEvent& event )
155{
156 wxString name = m_choiceRegulatorSelector->GetStringSelection();
158
159 if( item )
160 {
162 m_choiceRegType->SetSelection( item->m_Type );
163 wxString value;
164
165 value.Printf( wxT( "%g" ), item->m_VrefMin );
166 m_vrefMinVal->SetValue( value );
167 value.Printf( wxT( "%g" ), item->m_VrefTyp );
168 m_vrefTypVal->SetValue( value );
169 value.Printf( wxT( "%g" ), item->m_VrefMax );
170 m_vrefMaxVal->SetValue( value );
171
172 value.Printf( wxT( "%g" ), item->m_IadjTyp );
173 m_iadjTypVal->SetValue( value );
174
175 value.Printf( wxT( "%g" ), item->m_IadjMax );
176 m_iadjMaxVal->SetValue( value );
177 }
178
179 // Call RegulatorPageUpdate to enable/disable tools,
180 // even if no item selected
182}
183
184
185void PANEL_REGULATOR::OnDataFileSelection( wxCommandEvent& event )
186{
187 wxString fullfilename = GetDataFilename();
188
189 wxString wildcard;
190 wildcard.Printf( _( "PCB Calculator data file" ) + wxT( " (*.%s)|*.%s" ),
192
193 wxWindow* topLevelParent = wxGetTopLevelParent( this );
194
195 // Must be wxFD_SAVE, otherwise you cannot assign a file name
196 wxFileDialog dlg( topLevelParent, _( "Select PCB Calculator Data File" ), wxEmptyString,
197 fullfilename, wildcard, wxFD_SAVE );
198
199 if( dlg.ShowModal() == wxID_CANCEL )
200 return;
201
202 fullfilename = dlg.GetPath();
203
204 if( fullfilename == GetDataFilename() )
205 return;
206
207 SetDataFilename( fullfilename );
208
209 if( wxFileExists( fullfilename ) && m_RegulatorList.GetCount() > 0 ) // Read file
210 {
211 if( wxMessageBox( _( "Do you want to load this file and replace current regulator list?" ),
212 wxASCII_STR( wxMessageBoxCaptionStr ), wxOK | wxCANCEL | wxCENTER, this )
213 != wxOK )
214 {
215 return;
216 }
217 }
218
219 if( ReadDataFile() )
220 {
225 }
226 else
227 {
228 wxString msg;
229 msg.Printf( _( "Unable to read data file '%s'." ), fullfilename );
230 wxMessageBox( msg );
231 }
232}
233
234
235void PANEL_REGULATOR::OnAddRegulator( wxCommandEvent& event )
236{
237 DIALOG_REGULATOR_FORM dlg( wxGetTopLevelParent( this ), wxEmptyString );
238
239 if( dlg.ShowModal() != wxID_OK )
240 return;
241
242 REGULATOR_DATA* new_item = dlg.BuildRegulatorFromData();
243
244 // Add new item, if not existing
245 if( m_RegulatorList.GetReg( new_item->m_Name ) == nullptr )
246 {
247 // Add item in list
248 m_RegulatorList.Add( new_item );
254 }
255 else
256 {
257 wxMessageBox( _( "This regulator is already in list. Aborted" ) );
258 delete new_item;
259 }
260}
261
262
263void PANEL_REGULATOR::OnEditRegulator( wxCommandEvent& event )
264{
265 wxString name = m_choiceRegulatorSelector->GetStringSelection();
267
268 if( item == nullptr )
269 return;
270
271 DIALOG_REGULATOR_FORM dlg( wxGetTopLevelParent( this ), name );
272
273 dlg.CopyRegulatorDataToDialog( item );
274
275 if( dlg.ShowModal() != wxID_OK )
276 return;
277
278 REGULATOR_DATA* new_item = dlg.BuildRegulatorFromData();
279 m_RegulatorList.Replace( new_item );
280
282
284}
285
286
287void PANEL_REGULATOR::OnRemoveRegulator( wxCommandEvent& event )
288{
289 wxString name = wxGetSingleChoice( _( "Remove Regulator" ), wxEmptyString,
291 if( name.IsEmpty() )
292 return;
293
298
301
303}
304
305
307{
308 // Find last selected in regulator list:
309 int idx = -1;
310
311 if( !m_lastSelectedRegulatorName.IsEmpty() )
312 {
313 for( unsigned ii = 0; ii < m_RegulatorList.GetCount(); ii++ )
314 {
316 {
317 idx = ii;
318 break;
319 }
320 }
321 }
322
323 m_choiceRegulatorSelector->SetSelection( idx );
324 wxCommandEvent event;
325 OnRegulatorSelection( event );
326}
327
328
329void PANEL_REGULATOR::OnCopyCB( wxCommandEvent& event )
330{
331 if( wxTheClipboard->Open() )
332 {
333 // This data objects are held by the clipboard,
334 // so do not delete them in the app.
335 wxTheClipboard->SetData( new wxTextDataObject( m_textPowerComment->GetValue() ) );
336 wxTheClipboard->Close();
337 }
338}
339
340
342{
343 int id;
344
345 if( m_rbRegulR1->GetValue() )
346 {
347 id = 0; // for R1 calculation
348 }
349 else if( m_rbRegulR2->GetValue() )
350 {
351 id = 1; // for R2 calculation
352 }
353 else if( m_rbRegulVout->GetValue() )
354 {
355 id = 2; // for Vout calculation
356 }
357 else
358 {
359 wxMessageBox( wxT("Selection error" ) );
360 return;
361 }
362
363 double restol;
364 double r1min, r1typ, r1max;
365 double r2min, r2typ, r2max;
366 double vrefmin, vreftyp, vrefmax;
367 double voutmin, vouttyp, voutmax;
368 double toltotalmin, toltotalmax;
369
370 wxString txt;
371
372 m_RegulMessage->SetLabel( wxEmptyString);
373
374 // Convert r1 and r2 in ohms
375 int r1scale = 1000;
376 int r2scale = 1000;
377
378 // Read values from panel:
379 txt = m_resTolVal->GetValue();
380 restol = DoubleFromString( txt ) / 100;
381
382 txt = m_r1TypVal->GetValue();
383 r1typ = DoubleFromString( txt ) * r1scale;
384
385 txt = m_r2TypVal->GetValue();
386 r2typ = DoubleFromString( txt ) * r2scale;
387
388 txt = m_vrefMinVal->GetValue();
389 vrefmin = DoubleFromString( txt );
390 txt = m_vrefTypVal->GetValue();
391 vreftyp = DoubleFromString( txt );
392 txt = m_vrefMaxVal->GetValue();
393 vrefmax = DoubleFromString( txt );
394
395 txt = m_voutTypVal->GetValue();
396 vouttyp = DoubleFromString( txt );
397
398 // Some tests:
399 if( ( vouttyp < vrefmin || vouttyp < vreftyp || vouttyp < vrefmax ) && id != 2 )
400 {
401 m_RegulMessage->SetLabel( _( "Vout must be greater than vref" ) );
402 return;
403 }
404
405 if( vrefmin == 0.0 || vreftyp == 0.0 || vrefmax == 0.0 )
406 {
407 m_RegulMessage->SetLabel( _( "Vref set to 0 !" ) );
408 return;
409 }
410
411 if( vrefmin > vreftyp || vreftyp > vrefmax )
412 {
413 m_RegulMessage->SetLabel( _( "Vref must VrefMin < VrefTyp < VrefMax" ) );
414 return;
415 }
416
417 if( ( r1typ < 0 && id != 0 ) || ( r2typ <= 0 && id != 1 ) )
418 {
419 m_RegulMessage->SetLabel( _( "Incorrect value for R1 R2" ) );
420 return;
421 }
422
423 // Calculate
424 if( m_choiceRegType->GetSelection() == 1)
425 {
426 // 3 terminal regulator
427 txt = m_iadjTypVal->GetValue();
428 double iadjtyp = DoubleFromString( txt );
429 txt = m_iadjMaxVal->GetValue();
430 double iadjmax = DoubleFromString( txt );
431
432 if( iadjtyp > iadjmax )
433 {
434 m_RegulMessage->SetLabel( _( "Iadj must IadjTyp < IadjMax" ) );
435 return;
436 }
437
438 // iadj is given in micro amp, so convert it in amp.
439 iadjtyp /= 1000000;
440 iadjmax /= 1000000;
441
442 switch( id )
443 {
444 case 0:
445 // typical formula
446 r1typ = vreftyp * r2typ / ( vouttyp - vreftyp - ( r2typ * iadjtyp ) );
447 break;
448
449 case 1:
450 // typical formula
451 r2typ = ( vouttyp - vreftyp ) / ( iadjtyp + ( vreftyp / r1typ ) );
452 break;
453
454 case 2:
455 // typical formula
456 vouttyp = vreftyp * ( r1typ + r2typ ) / r1typ;
457 vouttyp += r2typ * iadjtyp;
458 break;
459 }
460
461 r1min = r1typ - r1typ * restol;
462 r1max = r1typ + r1typ * restol;
463
464 r2min = r2typ - r2typ * restol;
465 r2max = r2typ + r2typ * restol;
466
467 voutmin = vrefmin * ( r1max + r2min ) / r1max;
468 voutmin += r2min * iadjtyp;
469
470 voutmax = vrefmax * ( r1min + r2max ) / r1min;
471 voutmax += r2max * iadjmax;
472 }
473 else
474 { // Standard 4 terminal regulator
475 switch( id )
476 {
477 case 0:
478 // typical formula
479 r1typ = ( vouttyp / vreftyp - 1 ) * r2typ;
480 break;
481
482 case 1:
483 // typical formula
484 r2typ = r1typ / ( vouttyp / vreftyp - 1 );
485 break;
486
487 case 2:
488 // typical formula
489 vouttyp = vreftyp * ( r1typ + r2typ ) / r2typ;
490 break;
491 }
492
493 r1min = r1typ - r1typ * restol;
494 r1max = r1typ + r1typ * restol;
495
496 r2min = r2typ - r2typ * restol;
497 r2max = r2typ + r2typ * restol;
498
499 voutmin = vrefmin * ( r1min + r2max ) / r2max;
500 voutmax = vrefmax * ( r1max + r2min ) / r2min;
501 }
502
503 toltotalmin = ( voutmin - vouttyp ) / vouttyp * 100.0;
504 toltotalmax = ( voutmax - vouttyp ) / voutmax * 100.0;
505
506 // write values to panel:
507 txt.Printf( wxT( "%g" ), round_to( r1min / r1scale ) );
508 m_r1MinVal->SetValue( txt );
509 txt.Printf( wxT( "%g" ), round_to( r1typ / r1scale ) );
510 m_r1TypVal->SetValue( txt );
511 txt.Printf( wxT( "%g" ), round_to( r1max / r1scale ) );
512 m_r1MaxVal->SetValue( txt );
513
514 txt.Printf( wxT( "%g" ), round_to( r2min / r2scale ) );
515 m_r2MinVal->SetValue( txt );
516 txt.Printf( wxT( "%g" ), round_to( r2typ / r2scale ) );
517 m_r2TypVal->SetValue( txt );
518 txt.Printf( wxT( "%g" ), round_to( r2max / r2scale ) );
519 m_r2MaxVal->SetValue( txt );
520
521 txt.Printf( wxT( "%g" ), round_to( voutmin ) );
522 m_voutMinVal->SetValue( txt );
523 txt.Printf( wxT( "%g" ), round_to( vouttyp ) );
524 m_voutTypVal->SetValue( txt );
525 txt.Printf( wxT( "%g" ), round_to( voutmax ) );
526 m_voutMaxVal->SetValue( txt );
527
528 txt.Printf( wxT( "%g" ), round_to( toltotalmin, 0.01 ) );
529 m_tolTotalMin->SetValue( txt );
530 txt.Printf( wxT( "%g" ), round_to( toltotalmax, 0.01 ) );
531 m_TolTotalMax->SetValue( txt );
532
533 txt = wxString::Format( "%gV [%gV ... %gV]", round_to( vouttyp, 0.01 ),
534 round_to( voutmin, 0.01 ), round_to( voutmax, 0.01 ) );
535 m_textPowerComment->SetValue( txt );
536}
537
538
540{
541 m_resTolVal->SetValue( aCfg->m_Regulators.resTol );
542
543 m_r1TypVal->SetValue( aCfg->m_Regulators.r1 );
544 m_r2TypVal->SetValue( aCfg->m_Regulators.r2 );
545
546 m_vrefMinVal->SetValue( aCfg->m_Regulators.vrefMin );
547 m_vrefTypVal->SetValue( aCfg->m_Regulators.vrefTyp );
548 m_vrefMaxVal->SetValue( aCfg->m_Regulators.vrefMax );
549
550 m_voutTypVal->SetValue( aCfg->m_Regulators.voutTyp );
551
552 m_iadjTypVal->SetValue( aCfg->m_Regulators.iadjTyp );
553 m_iadjMaxVal->SetValue( aCfg->m_Regulators.iadjMax );
554
557 m_choiceRegType->SetSelection( aCfg->m_Regulators.type );
558
559 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
560
561 if( aCfg->m_Regulators.last_param >= 3 )
562 aCfg->m_Regulators.last_param = 0;
563
564 for( int ii = 0; ii < 3; ii++ )
565 regprms[ii]->SetValue( aCfg->m_Regulators.last_param == ii );
566
568}
569
570
572{
573 aCfg->m_Regulators.resTol = m_resTolVal->GetValue();
574
575 aCfg->m_Regulators.r1 = m_r1TypVal->GetValue();
576 aCfg->m_Regulators.r2 = m_r2TypVal->GetValue();
577
578 aCfg->m_Regulators.vrefMin = m_vrefMinVal->GetValue();
579 aCfg->m_Regulators.vrefTyp = m_vrefTypVal->GetValue();
580 aCfg->m_Regulators.vrefMax = m_vrefMaxVal->GetValue();
581
582 m_voutTypVal->SetValue( aCfg->m_Regulators.voutTyp );
583
584 aCfg->m_Regulators.iadjTyp = m_iadjTypVal->GetValue();
585 aCfg->m_Regulators.iadjMax = m_iadjMaxVal->GetValue();
586
589 aCfg->m_Regulators.type = m_choiceRegType->GetSelection();
590
591 wxRadioButton* regprms[3] = { m_rbRegulR1, m_rbRegulR2, m_rbRegulVout };
592
593 aCfg->m_Regulators.last_param = 0;
594
595 for( int ii = 0; ii < 3; ii++ )
596 {
597 if( regprms[ii]->GetValue() )
598 {
599 aCfg->m_Regulators.last_param = ii;
600 break;
601 }
602 }
603}
604
605
607{
608 if( m_regulators_fileNameCtrl->GetValue().IsEmpty() )
609 return wxEmptyString;
610
611 wxFileName fn( m_regulators_fileNameCtrl->GetValue() );
612 fn.SetExt( DataFileNameExt );
613 return fn.GetFullPath();
614}
615
616
617void PANEL_REGULATOR::SetDataFilename( const wxString& aFilename )
618{
619 if( aFilename.IsEmpty() )
620 {
621 m_regulators_fileNameCtrl->SetValue( wxEmptyString );
622 }
623 else
624 {
625 wxFileName fn( aFilename );
626 fn.SetExt( DataFileNameExt );
627 m_regulators_fileNameCtrl->SetValue( fn.GetFullPath() );
628 }
629}
630
631double PANEL_REGULATOR::round_to( double value, double precision )
632{
633 return std::round( value / precision ) * precision;
634}
const char * name
Definition: DXF_plotter.cpp:57
wxBitmapBundle KiBitmapBundle(BITMAPS aBitmap)
Definition: bitmap.cpp:110
Subclass of DIALOG_REGULATOR_FORM_BASE, which is generated by wxFormBuilder.
REGULATOR_DATA * BuildRegulatorFromData()
Create a new REGULATOR_DATA from dialog data.
void CopyRegulatorDataToDialog(REGULATOR_DATA *aItem)
Transfer data from dialog to aItem.
int ShowModal() override
Class PANEL_REGULATOR_BASE.
wxStaticText * m_RegulFormula
wxStaticText * m_RegulMessage
wxStaticText * m_RegulIadjTitle
wxTextCtrl * m_regulators_fileNameCtrl
wxRadioButton * m_rbRegulVout
wxStaticBitmap * m_bitmapRegul4pins
wxChoice * m_choiceRegulatorSelector
wxStaticBitmap * m_bitmapRegul3pins
wxStaticText * m_labelUnitsIadj
wxRadioButton * m_rbRegulR2
wxRadioButton * m_rbRegulR1
void OnEditRegulator(wxCommandEvent &event) override
void OnRegulatorSelection(wxCommandEvent &event) override
static double round_to(double value, double precision=0.001)
void OnRegulatorResetButtonClick(wxCommandEvent &event) override
REGULATOR_LIST m_RegulatorList
void ThemeChanged() override
Update UI elements of the panel when the theme changes to ensure the images and fonts/colors are appr...
const wxString GetDataFilename()
void OnRegulatorCalcButtonClick(wxCommandEvent &event) override
void OnDataFileSelection(wxCommandEvent &event) override
void SetDataFilename(const wxString &aFilename)
Initialize the full filename of the selected pcb_calculator data file force the standard extension of...
void SelectLastSelectedRegulator()
If m_lastSelectedRegulatorName is empty, just calls RegulatorPageUpdate()
void OnRegulTypeSelection(wxCommandEvent &event) override
void OnCopyCB(wxCommandEvent &event) override
void SaveSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Save the settings from the panel.
void OnRemoveRegulator(wxCommandEvent &event) override
wxString m_lastSelectedRegulatorName
void OnAddRegulator(wxCommandEvent &event) override
PANEL_REGULATOR(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=wxTAB_TRAVERSAL, const wxString &name=wxEmptyString)
void LoadSettings(PCB_CALCULATOR_SETTINGS *aCfg) override
Load the settings into the panel.
void RegulatorPageUpdate()
Update the regulator page dialog display.
void Remove(const wxString &aRegName)
wxArrayString GetRegList() const
void Replace(REGULATOR_DATA *aItem)
Replace an old REGULATOR_DATA by a new one The old one is deleted the 2 items must have the same name...
void Add(REGULATOR_DATA *aItem)
REGULATOR_DATA * GetReg(const wxString &aName)
unsigned int GetCount()
std::vector< REGULATOR_DATA * > m_List
Contains structures for storage of regulator data.
#define _(s)
double DoubleFromString(const wxString &TextValue)
double DoubleFromString(const wxString &TextValue)
const wxString DataFileNameExt
#define DEFAULT_REGULATOR_RESTOL
#define DEFAULT_REGULATOR_IADJ_MAX
#define DEFAULT_REGULATOR_IADJ_TYP
#define DEFAULT_REGULATOR_R2
#define DEFAULT_REGULATOR_R1
#define DEFAULT_REGULATOR_VREF_TYP
#define DEFAULT_REGULATOR_VREF_MIN
#define DEFAULT_REGULATOR_VREF_MAX
#define DEFAULT_REGULATOR_VOUT_TYP
void Refresh()
Update the board display after modifying it by a python script (note: it is automatically called by a...
#define wxASCII_STR(s)
Definition: util.cpp:41