Lots of bug fixing, and 4.7 merges
[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(13, 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, _("SCSI Speed Limit")));
68         wxString speeds[] = {
69                 wxT("No limit"),
70                 wxT("Async, 1.5MB/s"),
71                 wxT("Async, 3.3MB/s"),
72                 wxT("Async, 5 MB/s"),
73                 wxT("Sync, 5 MB/s")};
74
75         myScsiSpeedCtrl =
76                 new wxChoice(
77                         this,
78                         ID_scsiSpeedCtrl,
79                         wxDefaultPosition,
80                         wxDefaultSize,
81                         sizeof(speeds) / sizeof(wxString),
82                         speeds
83                         );
84         myScsiSpeedCtrl->SetToolTip(_("Limit SCSI interface speed"));
85         fgs->Add(myScsiSpeedCtrl);
86
87         fgs->Add(new wxStaticText(this, wxID_ANY, _("Startup Delay (seconds)")));
88         myStartDelayCtrl =
89                 new wxTextCtrl(
90                         this,
91                         ID_startDelayCtrl,
92                         "0",
93                         wxDefaultPosition,
94                         wxDefaultSize,
95                         0,
96                         *myDelayValidator);
97         myStartDelayCtrl->SetToolTip(_("Extra delay on power on, normally set to 0"));
98         fgs->Add(myStartDelayCtrl);
99
100
101         fgs->Add(new wxStaticText(this, wxID_ANY, _("SCSI Selection Delay (ms, 255 = auto)")));
102         mySelDelayCtrl =
103                 new wxTextCtrl(
104                         this,
105                         ID_selDelayCtrl,
106                         "255",
107                         wxDefaultPosition,
108                         wxDefaultSize,
109                         0,
110                         *myDelayValidator);
111         mySelDelayCtrl->SetToolTip(_("Delay before responding to SCSI selection. SCSI1 hosts usually require 1ms delay, however some require no delay"));
112         fgs->Add(mySelDelayCtrl);
113
114         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
115         myParityCtrl =
116                 new wxCheckBox(
117                         this,
118                         ID_parityCtrl,
119                         _("Enable Parity"));
120         myParityCtrl->SetToolTip(_("Enable to require valid SCSI parity bits when receiving data. Some hosts don't provide parity. SCSI2SD always outputs valid parity bits."));
121         fgs->Add(myParityCtrl);
122
123         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
124         myUnitAttCtrl =
125                 new wxCheckBox(
126                         this,
127                         ID_unitAttCtrl,
128                         _("Enable Unit Attention"));
129         myUnitAttCtrl->SetToolTip(_("Enable this to inform the host of changes after hot-swapping SD cards. Causes problems with Mac Plus."));
130         fgs->Add(myUnitAttCtrl);
131
132         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
133         myScsi2Ctrl =
134                 new wxCheckBox(
135                         this,
136                         ID_scsi2Ctrl,
137                         _("Enable SCSI2 Mode"));
138         myScsi2Ctrl->SetToolTip(_("Enable high-performance mode. May cause problems with SASI/SCSI1 hosts."));
139         fgs->Add(myScsi2Ctrl);
140
141         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
142         mySelLatchCtrl =
143                 new wxCheckBox(
144                         this,
145                         ID_selLatchCtrl,
146                         _("Respond to short SCSI selection pulses"));
147         mySelLatchCtrl->SetToolTip(_("Respond to very short duration selection attempts. This supports non-standard hardware, but is generally safe to enable.  Required for Philips P2000C."));
148         fgs->Add(mySelLatchCtrl);
149
150         fgs->Add(new wxStaticText(this, wxID_ANY, wxT("")));
151         myMapLunsCtrl =
152                 new wxCheckBox(
153                         this,
154                         ID_mapLunsCtrl,
155                         _("Map LUNS to SCSI IDs"));
156         myMapLunsCtrl->SetToolTip(_("Treat LUNS as IDs instead. Supports multiple drives on XEBEC S1410 SASI Bridge"));
157         fgs->Add(myMapLunsCtrl);
158
159         wxBoxSizer* hbox = new wxBoxSizer(wxHORIZONTAL);
160         hbox->Add(fgs, 1, wxALL | wxEXPAND, 15);
161         this->SetSizer(hbox);
162         Centre();
163
164         setConfig(initialConfig);
165 }
166
167
168 S2S_BoardCfg
169 BoardPanel::getConfig() const
170 {
171         S2S_BoardCfg config;
172
173         // Try and keep unknown/unused fields as-is to support newer firmware
174         // versions.
175         memcpy(&config, &myConfig, sizeof(config));
176
177         config.flags =
178                 (myParityCtrl->IsChecked() ? S2S_CFG_ENABLE_PARITY : 0) |
179                 (myUnitAttCtrl->IsChecked() ? S2S_CFG_ENABLE_UNIT_ATTENTION : 0) |
180                 (myScsi2Ctrl->IsChecked() ? S2S_CFG_ENABLE_SCSI2 : 0) |
181                 (mySelLatchCtrl->IsChecked() ? S2S_CFG_ENABLE_SEL_LATCH : 0) |
182                 (myMapLunsCtrl->IsChecked() ? S2S_CFG_MAP_LUNS_TO_IDS : 0);
183
184         config.flags6 = (myTermCtrl->IsChecked() ? S2S_CFG_ENABLE_TERMINATOR : 0);
185
186         config.startupDelay = CtrlGetValue<unsigned int>(myStartDelayCtrl).first;
187         config.selectionDelay = CtrlGetValue<unsigned int>(mySelDelayCtrl).first;
188         config.scsiSpeed = myScsiSpeedCtrl->GetSelection();
189         return config;
190 }
191
192 void
193 BoardPanel::setConfig(const S2S_BoardCfg& config)
194 {
195         memcpy(&myConfig, &config, sizeof(config));
196
197         myParityCtrl->SetValue(config.flags & S2S_CFG_ENABLE_PARITY);
198         myUnitAttCtrl->SetValue(config.flags & S2S_CFG_ENABLE_UNIT_ATTENTION);
199         myScsi2Ctrl->SetValue(config.flags & S2S_CFG_ENABLE_SCSI2);
200         myTermCtrl->SetValue(config.flags6 & S2S_CFG_ENABLE_TERMINATOR);
201         mySelLatchCtrl->SetValue(config.flags & S2S_CFG_ENABLE_SEL_LATCH);
202         myMapLunsCtrl->SetValue(config.flags & S2S_CFG_MAP_LUNS_TO_IDS);
203
204         {
205                 std::stringstream conv;
206                 conv << static_cast<unsigned int>(config.startupDelay);
207                 myStartDelayCtrl->ChangeValue(conv.str());
208         }
209         {
210                 std::stringstream conv;
211                 conv << static_cast<unsigned int>(config.selectionDelay);
212                 mySelDelayCtrl->ChangeValue(conv.str());
213         }
214         myScsiSpeedCtrl->SetSelection(config.scsiSpeed);
215 }
216
217