54ea235273dae5a5f79c0104a3a69389125761ac
[SCSI2SD-V6.git] / src / scsi2sd-util6 / BoardPanel.cc
1 //      Copyright (C) 2015 Michael McMaster <michael@codesrc.com>
2 //
3 //      This file is part of SCSI2SD.
4 //
5 //      SCSI2SD is free software: you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation, either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      SCSI2SD is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with SCSI2SD.  If not, see <http://www.gnu.org/licenses/>.
17
18 // For compilers that support precompilation, includes "wx/wx.h".
19 #include <wx/wxprec.h>
20 #ifndef WX_PRECOMP
21 #include <wx/wx.h>
22 #endif
23
24 #include <wx/wrapsizer.h>
25
26 #include "ConfigUtil.hh"
27 #include "BoardPanel.hh"
28
29 #include <limits>
30 #include <sstream>
31
32 #include <math.h>
33 #include <string.h>
34
35 using namespace SCSI2SD;
36
37 namespace
38 {
39         template<typename IntType, class WXCTRL> std::pair<IntType, bool>
40         CtrlGetValue(WXCTRL* ctrl)
41         {
42                 IntType value;
43                 std::stringstream conv;
44                 conv << ctrl->GetValue();
45                 conv >> value;
46                 return std::make_pair(value, static_cast<bool>(conv));
47         }
48
49 }
50
51 BoardPanel::BoardPanel(wxWindow* parent, const S2S_BoardCfg& initialConfig) :
52         wxPanel(parent),
53         myParent(parent),
54         myDelayValidator(new wxIntegerValidator<uint8_t>)
55 {
56         wxFlexGridSizer *fgs = new wxFlexGridSizer(11, 2, 9, 25);
57
58         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
59         myTermCtrl =
60                 new wxCheckBox(
61                         this,
62                         ID_termCtrl,
63                         _("Enable SCSI terminator"));
64         myTermCtrl->SetToolTip(_("Enable active terminator. Both ends of the SCSI chain must be terminated."));
65         fgs->Add(myTermCtrl);
66
67         fgs->Add(new wxStaticText(this, wxID_ANY, _("Startup Delay (seconds)")));
68         myStartDelayCtrl =
69                 new wxTextCtrl(
70                         this,
71                         ID_startDelayCtrl,
72                         "0",
73                         wxDefaultPosition,
74                         wxDefaultSize,
75                         0,
76                         *myDelayValidator);
77         myStartDelayCtrl->SetToolTip(_("Extra delay on power on, normally set to 0"));
78         fgs->Add(myStartDelayCtrl);
79
80
81         fgs->Add(new wxStaticText(this, wxID_ANY, _("SCSI Selection Delay (ms, 255 = auto)")));
82         mySelDelayCtrl =
83                 new wxTextCtrl(
84                         this,
85                         ID_selDelayCtrl,
86                         "255",
87                         wxDefaultPosition,
88                         wxDefaultSize,
89                         0,
90                         *myDelayValidator);
91         mySelDelayCtrl->SetToolTip(_("Delay before responding to SCSI selection. SCSI1 hosts usually require 1ms delay, however some require no delay"));
92         fgs->Add(mySelDelayCtrl);
93
94         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
95         myParityCtrl =
96                 new wxCheckBox(
97                         this,
98                         ID_parityCtrl,
99                         _("Enable Parity"));
100         myParityCtrl->SetToolTip(_("Enable to require valid SCSI parity bits when receiving data. Some hosts don't provide parity. SCSI2SD always outputs valid parity bits."));
101         fgs->Add(myParityCtrl);
102
103         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
104         myUnitAttCtrl =
105                 new wxCheckBox(
106                         this,
107                         ID_unitAttCtrl,
108                         _("Enable Unit Attention"));
109         myUnitAttCtrl->SetToolTip(_("Enable this to inform the host of changes after hot-swapping SD cards. Causes problems with Mac Plus."));
110         fgs->Add(myUnitAttCtrl);
111
112         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
113         myScsi2Ctrl =
114                 new wxCheckBox(
115                         this,
116                         ID_scsi2Ctrl,
117                         _("Enable SCSI2 Mode"));
118         myScsi2Ctrl->SetToolTip(_("Enable high-performance mode. May cause problems with SASI/SCSI1 hosts."));
119         fgs->Add(myScsi2Ctrl);
120
121         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
122         myGlitchCtrl =
123                 new wxCheckBox(
124                         this,
125                         ID_glitchCtrl,
126                         _("Disable glitch filter"));
127         myGlitchCtrl->SetToolTip(_("Improve performance at the cost of noise immunity. Only use with short cables."));
128         fgs->Add(myGlitchCtrl);
129
130         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
131         myCacheCtrl =
132                 new wxCheckBox(
133                         this,
134                         ID_cacheCtrl,
135                         _("Enable disk cache (experimental)"));
136         myCacheCtrl->SetToolTip(_("SD IO commands aren't completed when SCSI commands complete"));
137         fgs->Add(myCacheCtrl);
138
139         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
140         myDisconnectCtrl =
141                 new wxCheckBox(
142                         this,
143                         ID_disconnectCtrl,
144                         _("Enable SCSI Disconnect"));
145         myDisconnectCtrl->SetToolTip(_("Release the SCSI bus while waiting for SD card writes to complete. Must also be enabled in host OS."));
146         fgs->Add(myDisconnectCtrl);
147
148         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
149         mySelLatchCtrl =
150                 new wxCheckBox(
151                         this,
152                         ID_selLatchCtrl,
153                         _("Respond to short SCSI selection pulses"));
154         mySelLatchCtrl->SetToolTip(_("Respond to very short duration selection attempts. This supports non-standard hardware, but is generally safe to enable.  Required for Philips P2000C."));
155         fgs->Add(mySelLatchCtrl);
156
157         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
158         myMapLunsCtrl =
159                 new wxCheckBox(
160                         this,
161                         ID_mapLunsCtrl,
162                         _("Map LUNS to SCSI IDs"));
163         myMapLunsCtrl->SetToolTip(_("Treat LUNS as IDs instead. Supports multiple drives on XEBEC S1410 SASI Bridge"));
164         fgs->Add(myMapLunsCtrl);
165
166         wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL);
167         hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);
168         this->SetSizer(hbox);
169         Centre();
170
171         setConfig(initialConfig);
172 }
173
174
175 S2S_BoardCfg
176 BoardPanel::getConfig() const
177 {
178         S2S_BoardCfg config;
179
180         // Try and keep unknown/unused fields as-is to support newer firmware
181         // versions.
182         memcpy(&config, &myConfig, sizeof(config));
183
184         config.flags =
185                 (myParityCtrl->IsChecked() ? S2S_CFG_ENABLE_PARITY : 0) |
186                 (myUnitAttCtrl->IsChecked() ? S2S_CFG_ENABLE_UNIT_ATTENTION : 0) |
187                 (myScsi2Ctrl->IsChecked() ? S2S_CFG_ENABLE_SCSI2 : 0) |
188                 (myGlitchCtrl->IsChecked() ? S2S_CFG_DISABLE_GLITCH : 0) |
189                 (myCacheCtrl->IsChecked() ? S2S_CFG_ENABLE_CACHE: 0) |
190                 (myDisconnectCtrl->IsChecked() ? S2S_CFG_ENABLE_DISCONNECT: 0) |
191                 (mySelLatchCtrl->IsChecked() ? S2S_CFG_ENABLE_SEL_LATCH : 0) |
192                 (myMapLunsCtrl->IsChecked() ? S2S_CFG_MAP_LUNS_TO_IDS : 0);
193
194         config.flags6 = (myTermCtrl->IsChecked() ? S2S_CFG_ENABLE_TERMINATOR : 0);
195
196         config.startupDelay = CtrlGetValue<unsigned int>(myStartDelayCtrl).first;
197         config.selectionDelay = CtrlGetValue<unsigned int>(mySelDelayCtrl).first;
198         return config;
199 }
200
201 void
202 BoardPanel::setConfig(const S2S_BoardCfg& config)
203 {
204         memcpy(&myConfig, &config, sizeof(config));
205
206         myParityCtrl->SetValue(config.flags & S2S_CFG_ENABLE_PARITY);
207         myUnitAttCtrl->SetValue(config.flags & S2S_CFG_ENABLE_UNIT_ATTENTION);
208         myScsi2Ctrl->SetValue(config.flags & S2S_CFG_ENABLE_SCSI2);
209         myGlitchCtrl->SetValue(config.flags & S2S_CFG_DISABLE_GLITCH);
210         myTermCtrl->SetValue(config.flags6 & S2S_CFG_ENABLE_TERMINATOR);
211         myCacheCtrl->SetValue(config.flags & S2S_CFG_ENABLE_CACHE);
212         myDisconnectCtrl->SetValue(config.flags & S2S_CFG_ENABLE_DISCONNECT);
213         mySelLatchCtrl->SetValue(config.flags & S2S_CFG_ENABLE_SEL_LATCH);
214         myMapLunsCtrl->SetValue(config.flags & S2S_CFG_MAP_LUNS_TO_IDS);
215
216         {
217                 std::stringstream conv;
218                 conv << static_cast<unsigned int>(config.startupDelay);
219                 myStartDelayCtrl->ChangeValue(conv.str());
220         }
221         {
222                 std::stringstream conv;
223                 conv << static_cast<unsigned int>(config.selectionDelay);
224                 mySelDelayCtrl->ChangeValue(conv.str());
225         }
226 }
227
228