2 * Copyright (C) 2009 by Pieter Palmers
3 * Copyright (C) 2009 by Arnold Krille
5 * This file is part of FFADO
6 * FFADO = Free Firewire (pro-)audio drivers for linux
8 * FFADO is based upon FreeBoB.
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 2 of the License, or
13 * (at your option) version 3 of the License.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include "saffire_pro24.h"
26 #include "focusrite_eap.h"
28 #include "libutil/ByteSwap.h"
33 void SaffirePro24::SaffirePro24EAP::setupSources_low() {
34 addSource("SPDIF/In", 6, 2, eRS_AES
, 1);
35 addSource("ADAT/In", 0, 8, eRS_ADAT
, 1);
36 addSource("Anlg/In", 0, 4, eRS_InS0
, 1);
37 addSource("Mixer/Out", 0, 16, eRS_Mixer
, 1);
38 addSource("1394/In", 0, 8, eRS_ARX0
, 1);
39 addSource("Mute", 0, 1, eRS_Muted
);
41 void SaffirePro24::SaffirePro24EAP::setupDestinations_low() {
42 addDestination("SPDIF/Out", 6, 2, eRD_AES
, 1);
43 addDestination("Line/Out", 0, 6, eRD_InS0
, 1);
44 addDestination("Mixer/In", 0, 16, eRD_Mixer0
, 1);
45 addDestination("Mixer/In", 0, 2, eRD_Mixer1
, 17);
46 addDestination("1394/Out", 0, 16, eRD_ATX0
, 1);
47 // Is a Mute destination useful ?
48 // addDestination("Mute", 0, 1, eRD_Muted);
51 void SaffirePro24::SaffirePro24EAP::setupSources_mid() {
52 addSource("SPDIF/In", 6, 2, eRS_AES
, 1);
53 addSource("ADAT/In", 0, 4, eRS_ADAT
, 1);
54 addSource("Anlg/In", 0, 4, eRS_InS0
, 1);
55 addSource("Mixer/Out", 0, 16, eRS_Mixer
, 1);
56 addSource("1394/In", 0, 8, eRS_ARX0
, 1);
57 addSource("Mute", 0, 1, eRS_Muted
);
59 void SaffirePro24::SaffirePro24EAP::setupDestinations_mid() {
60 addDestination("SPDIF/Out", 6, 2, eRD_AES
, 1);
61 addDestination("Line/Out", 0, 6, eRD_InS0
, 1);
62 addDestination("Mixer/In", 0, 16, eRD_Mixer0
, 1);
63 addDestination("Mixer/In", 0, 2, eRD_Mixer1
, 17);
64 addDestination("1394/Out", 0, 12, eRD_ATX0
, 1);
65 // Is a Mute destination useful ?
66 // addDestination("Mute", 0, 1, eRD_Muted);
69 void SaffirePro24::SaffirePro24EAP::setupSources_high() {
70 printMessage("High (192 kHz) sample rate not supported by Saffire Pro 24\n");
73 void SaffirePro24::SaffirePro24EAP::setupDestinations_high() {
74 printMessage("High (192 kHz) sample rate not supported by Saffire Pro 24\n");
78 * The default configurations for the Saffire Pro 24 router.
79 * For coherence with hardware, destinations must follow a specific ordering
80 * There must be 44 destinations at low samplerate
81 * Front LEDs are connected to the first four router entries
84 SaffirePro24::SaffirePro24EAP::setupDefaultRouterConfig_low() {
86 // the 1394 stream receivers except the two "loops" one
87 // Looks like analogic inputs are curiously ordered
88 // (required for coherent front LEDs)
90 addRoute(eRS_InS0
, i
+2, eRD_ATX0
, i
);
93 addRoute(eRS_InS0
, i
, eRD_ATX0
, i
+2);
96 addRoute(eRS_AES
, i
+6, eRD_ATX0
, i
+4);
99 addRoute(eRS_ADAT
, i
, eRD_ATX0
, i
+6);
102 // Ensure that audio port are not muted
103 for (i
=0; i
<6; i
++) {
104 addRoute(eRS_ARX0
, i
%2, eRD_InS0
, i
);
106 // the SPDIF receiver
107 for (i
=0; i
<2; i
++) {
108 addRoute(eRS_Muted
, 0, eRD_AES
, i
+6);
110 // the "loops" 1394 stream receivers
111 for (i
=0; i
<2; i
++) {
112 addRoute(eRS_Muted
, 0, eRD_ATX0
, i
+14);
115 for (i
=0; i
<4; i
++) {
116 addRoute(eRS_InS0
, i
, eRD_Mixer0
, i
);
118 for (i
=0; i
<2; i
++) {
119 addRoute(eRS_AES
, i
+6, eRD_Mixer0
, i
+4);
121 for (i
=0; i
<8; i
++) {
122 addRoute(eRS_ADAT
, i
, eRD_Mixer0
, i
+6);
124 for (i
=0; i
<2; i
++) {
125 addRoute(eRS_ARX0
, i
, eRD_Mixer0
, i
+14);
127 for (i
=0; i
<2; i
++) {
128 addRoute(eRS_Muted
, 0, eRD_Mixer1
, i
);
130 // The two mute destinations
131 for (i
=0; i
<2; i
++) {
132 addRoute(eRS_Mixer
, i
, eRD_Muted
, 0);
137 * There must be 40 (?) destinations at mid samplerate
138 * Front LEDs are connected to the first four router entries
141 SaffirePro24::SaffirePro24EAP::setupDefaultRouterConfig_mid() {
143 // the 1394 stream receivers except the two "loops" one
144 // Looks like analogic inputs are curiously ordered
145 // (required for coherent front LEDs)
146 for (i
=0; i
<2; i
++) {
147 addRoute(eRS_InS0
, i
+2, eRD_ATX0
, i
);
149 for (i
=0; i
<2; i
++) {
150 addRoute(eRS_InS0
, i
, eRD_ATX0
, i
+2);
152 for (i
=0; i
<2; i
++) {
153 addRoute(eRS_AES
, i
+6, eRD_ATX0
, i
+4);
155 for (i
=0; i
<4; i
++) {
156 addRoute(eRS_ADAT
, i
, eRD_ATX0
, i
+6);
159 // Ensure that audio port are not muted
160 for (i
=0; i
<6; i
++) {
161 addRoute(eRS_ARX0
, i
%2, eRD_InS0
, i
);
163 // the SPDIF receiver
164 for (i
=0; i
<2; i
++) {
165 addRoute(eRS_Muted
, 0, eRD_AES
, i
+6);
167 // the "loops" 1394 stream receivers
168 for (i
=0; i
<2; i
++) {
169 addRoute(eRS_Muted
, 0, eRD_ATX0
, i
+10);
172 for (i
=0; i
<4; i
++) {
173 addRoute(eRS_InS0
, i
, eRD_Mixer0
, i
);
175 for (i
=0; i
<2; i
++) {
176 addRoute(eRS_AES
, i
+6, eRD_Mixer0
, i
+4);
178 for (i
=0; i
<4; i
++) {
179 addRoute(eRS_ADAT
, i
, eRD_Mixer0
, i
+6);
181 for (i
=0; i
<2; i
++) {
182 addRoute(eRS_ARX0
, i
, eRD_Mixer0
, i
+10);
184 for (i
=0; i
<4; i
++) {
185 addRoute(eRS_Muted
, 0, eRD_Mixer0
, i
+12);
187 for (i
=0; i
<2; i
++) {
188 addRoute(eRS_Muted
, 0, eRD_Mixer1
, i
);
190 // The two mute destinations
191 for (i
=0; i
<2; i
++) {
192 addRoute(eRS_Mixer
, i
, eRD_Muted
, 0);
197 * High rate not supported
200 SaffirePro24::SaffirePro24EAP::setupDefaultRouterConfig_high() {
201 printMessage("High (192 kHz) sample rate not supported by Saffire Pro 40\n");
205 * Pro 24 Monitor section
207 SaffirePro24::SaffirePro24EAP::MonitorSection::MonitorSection(Dice::Focusrite::FocusriteEAP
* eap
,
208 std::string name
) : Control::Container(eap
, name
)
211 // Global Mute control
212 Control::Container
* grp_globalmute
= new Control::Container(m_eap
, "GlobalMute");
213 addElement(grp_globalmute
);
214 FocusriteEAP::Switch
* mute
=
215 new FocusriteEAP::Switch(m_eap
, "State",
216 SAFFIRE_PRO24_REGISTER_APP_GLOBAL_MUTE_SWITCH
,
217 FOCUSRITE_EAP_GLOBAL_MUTE_SWITCH_VALUE
,
218 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
219 SAFFIRE_PRO24_MESSAGE_SET_GLOBAL_DIM_MUTE_SWITCH
);
220 grp_globalmute
->addElement(mute
);
222 // Global Dim control
223 Control::Container
* grp_globaldim
= new Control::Container(m_eap
, "GlobalDim");
224 addElement(grp_globaldim
);
225 FocusriteEAP::Switch
* dim
=
226 new FocusriteEAP::Switch(m_eap
, "State",
227 SAFFIRE_PRO24_REGISTER_APP_GLOBAL_DIM_SWITCH
,
228 FOCUSRITE_EAP_GLOBAL_DIM_SWITCH_VALUE
,
229 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
230 SAFFIRE_PRO24_MESSAGE_SET_GLOBAL_DIM_MUTE_SWITCH
);
231 grp_globaldim
->addElement(dim
);
232 FocusriteEAP::Poti
* dimlevel
=
233 new FocusriteEAP::Poti(m_eap
, "Level",
234 SAFFIRE_PRO24_REGISTER_APP_GLOBAL_DIM_VOLUME
,
235 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
236 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
237 grp_globaldim
->addElement(dimlevel
);
239 FocusriteEAP::Switch
* s
;
240 // Mono/stereo switch
241 Control::Container
* grp_mono
= new Control::Container(m_eap
, "Mono");
242 addElement(grp_mono
);
243 for (unsigned int i
=0; i
<SAFFIRE_PRO24_APP_STEREO_LINEOUT_SIZE
; ++i
) {
244 std::stringstream stream
;
245 stream
<< "Line" << i
*2+1 << "Line" << i
*2+2;
247 new FocusriteEAP::Switch(m_eap
, stream
.str(),
248 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_SWITCH_CONTROL
,
249 FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
250 <<(FOCUSRITE_EAP_SWITCH_CONTROL_MONO_SHIFT
+i
),
251 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
252 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_SWITCH_CONTROL
);
253 grp_mono
->addElement(s
);
256 // Independent control of each line/out
257 Control::Container
* grp_perchannel
= new Control::Container(m_eap
, "LineOut");
258 addElement(grp_perchannel
);
259 FocusriteEAP::VolumeControl
* vol
;
261 // per Line/Out monitoring
262 for (unsigned int i
=0; i
<SAFFIRE_PRO24_APP_STEREO_LINEOUT_SIZE
; ++i
) {
263 std::stringstream stream
;
265 // Activate/Unactivate per Line/Out volume monitoring
266 stream
.str(std::string());
267 stream
<< "UnActivate" << i
*2+1;
269 new FocusriteEAP::Switch(m_eap
, stream
.str(),
270 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_MONITOR_SWITCH
+i
*sizeof(quadlet_t
),
271 FOCUSRITE_EAP_SWITCH_BIT_1
,
272 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
273 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
274 grp_perchannel
->addElement(s
);
275 stream
.str(std::string());
276 stream
<< "UnActivate" << i
*2+2;
278 new FocusriteEAP::Switch(m_eap
, stream
.str(),
279 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_MONITOR_SWITCH
+i
*sizeof(quadlet_t
),
280 FOCUSRITE_EAP_SWITCH_BIT_2
,
281 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
282 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
283 grp_perchannel
->addElement(s
);
285 // per Line/Out mute/unmute
286 stream
.str(std::string());
287 stream
<< "Mute" << i
*2+1;
289 new FocusriteEAP::Switch(m_eap
, stream
.str(),
290 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_MONITOR_SWITCH
+i
*sizeof(quadlet_t
),
291 FOCUSRITE_EAP_SWITCH_BIT_3
,
292 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
293 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
294 grp_perchannel
->addElement(s
);
295 stream
.str(std::string());
296 stream
<< "Mute" << i
*2+2;
298 new FocusriteEAP::Switch(m_eap
, stream
.str(),
299 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_MONITOR_SWITCH
+i
*sizeof(quadlet_t
),
300 FOCUSRITE_EAP_SWITCH_BIT_4
,
301 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
302 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
303 grp_perchannel
->addElement(s
);
305 // per Line/Out global mute activation/unactivation
306 stream
.str(std::string());
307 stream
<< "GMute" << 2*i
+1;
309 new FocusriteEAP::Switch(m_eap
, stream
.str(),
310 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_SWITCH_CONTROL
,
311 FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
312 <<(FOCUSRITE_EAP_SWITCH_CONTROL_MUTE_SHIFT
+2*i
),
313 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
314 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_SWITCH_CONTROL
);
315 grp_perchannel
->addElement(s
);
317 stream
.str(std::string());
318 stream
<< "GMute" << 2*i
+2;
320 new FocusriteEAP::Switch(m_eap
, stream
.str(),
321 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_SWITCH_CONTROL
,
322 FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
323 <<(FOCUSRITE_EAP_SWITCH_CONTROL_MUTE_SHIFT
+2*i
+1),
324 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
325 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_SWITCH_CONTROL
);
326 grp_perchannel
->addElement(s
);
328 // per Line/Out global dim activation/unactivation
329 stream
.str(std::string());
330 stream
<< "GDim" << 2*i
+1;
332 new FocusriteEAP::Switch(m_eap
, stream
.str(),
333 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_SWITCH_CONTROL
,
334 FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
335 <<(FOCUSRITE_EAP_SWITCH_CONTROL_DIM_SHIFT
+2*i
),
336 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
337 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_SWITCH_CONTROL
);
338 grp_perchannel
->addElement(s
);
340 stream
.str(std::string());
341 stream
<< "GDim" << 2*i
+2;
343 new FocusriteEAP::Switch(m_eap
, stream
.str(),
344 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_SWITCH_CONTROL
,
345 FOCUSRITE_EAP_SWITCH_CONTROL_VALUE
346 <<(FOCUSRITE_EAP_SWITCH_CONTROL_DIM_SHIFT
+2*i
+1),
347 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
348 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_SWITCH_CONTROL
);
349 grp_perchannel
->addElement(s
);
351 // per Line/Out volume control
352 stream
.str(std::string());
353 stream
<< "Volume" << i
*2+1;
355 new FocusriteEAP::VolumeControl(m_eap
, stream
.str(),
356 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_MONITOR_VOLUME
357 +i
*sizeof(quadlet_t
),
358 FOCUSRITE_EAP_LINEOUT_VOLUME_SET_1
,
359 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
360 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
361 grp_perchannel
->addElement(vol
);
362 stream
.str(std::string());
363 stream
<< "Volume" << i
*2+2;
365 new FocusriteEAP::VolumeControl(m_eap
, stream
.str(),
366 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_MONITOR_VOLUME
367 +i
*sizeof(quadlet_t
),
368 FOCUSRITE_EAP_LINEOUT_VOLUME_SET_2
,
369 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
370 SAFFIRE_PRO24_MESSAGE_SET_LINEOUT_MONITOR_VOLUME
);
371 grp_perchannel
->addElement(vol
);
374 Control::Container
* grp_LineInstGain
= new Control::Container(m_eap
, "LineInstGain");
375 addElement(grp_LineInstGain
);
376 FocusriteEAP::Switch
* lineinst
=
377 new FocusriteEAP::Switch(m_eap
, "LineInst1",
378 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_INST_SWITCH
,
379 SAFFIRE_PRO24_LINEOUT_SWITCH_INST_VALUE
,
380 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
381 SAFFIRE_PRO24_MESSAGE_SET_INSTLINE
);
382 grp_LineInstGain
->addElement(lineinst
);
384 new FocusriteEAP::Switch(m_eap
, "LineInst2",
385 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_INST_SWITCH
,
386 SAFFIRE_PRO24_LINEOUT_SWITCH_INST_VALUE
387 <<FOCUSRITE_EAP_LINEOUT_SWITCH_INST_SHIFT
,
388 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
389 SAFFIRE_PRO24_MESSAGE_SET_INSTLINE
);
390 grp_LineInstGain
->addElement(lineinst
);
392 new FocusriteEAP::Switch(m_eap
, "LineGain3",
393 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_GAIN_SWITCH
,
394 SAFFIRE_PRO24_LINEOUT_SWITCH_GAIN_VALUE
,
395 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
396 SAFFIRE_PRO24_MESSAGE_SET_INSTLINE
);
397 grp_LineInstGain
->addElement(lineinst
);
399 new FocusriteEAP::Switch(m_eap
, "LineGain4",
400 SAFFIRE_PRO24_REGISTER_APP_LINEOUT_GAIN_SWITCH
,
401 SAFFIRE_PRO24_LINEOUT_SWITCH_GAIN_VALUE
402 <<FOCUSRITE_EAP_LINEOUT_SWITCH_GAIN_SHIFT
,
403 SAFFIRE_PRO24_REGISTER_APP_MESSAGE_SET
,
404 SAFFIRE_PRO24_MESSAGE_SET_INSTLINE
);
405 grp_LineInstGain
->addElement(lineinst
);
408 SaffirePro24::SaffirePro24( DeviceManager
& d
,
409 std::auto_ptr
<ConfigRom
>( configRom
))
410 : Dice::Device(d
, configRom
)
412 debugOutput(DEBUG_LEVEL_VERBOSE
, "Created Dice::Focusrite::SaffirePro24 (NodeID %d)\n",
413 getConfigRom().getNodeId());
416 SaffirePro24::~SaffirePro24()
418 //debugOutput(DEBUG_LEVEL_VERBOSE, "Deleting the saffirePro24\n");
419 /// I wonder whether we should really save only on clean exits or also each time a setting is
420 // changed. Or should we provide a function (and thus gui-button) to save the state of the
422 getEAP()->storeFlashConfig();
425 bool SaffirePro24::discover() {
426 if (Dice::Device::discover()) {
427 fb_quadlet_t
* version
= (fb_quadlet_t
*)calloc(2, sizeof(fb_quadlet_t
));
428 getEAP()->readRegBlock(Dice::EAP::eRT_Application
, SAFFIRE_PRO24_REGISTER_APP_VERSION
, version
, 1*sizeof(fb_quadlet_t
));
429 // On August 2013, Focusrite released a new firmware.
430 // Version numbering 2.0 (0x00020000) seems common to all Saffire
432 // Note: 0x00010004 and 0x00010008 stands for a firmware version
433 // not for a device identity. 0x00010004 is a pro24, 0x00010008
435 if (version
[0] != 0x00010004 && version
[0] != 0x00010008 && version
[0] != 0x00020000) {
436 debugError("This is a Focusrite Saffire Pro24 but not the right firmware. Better stop here before something goes wrong.\n");
437 debugError("This device has firmware 0x%x while we only know about versions 0x%x, 0x%x and 0x%x.\n", version
[0], 0x10004, 0x10008, 0x00020000);
441 // FIXME: What is the purpose of the following commented lines at this point ?
442 //getEAP()->readRegBlock(Dice::EAP::eRT_Command, 0x00, tmp, 2*sizeof(fb_quadlet_t)); // DEBUG
443 //hexDumpQuadlets(tmp, 2); // DEBUG
445 FocusriteEAP
* eap
= dynamic_cast<FocusriteEAP
*>(getEAP());
446 SaffirePro24EAP::MonitorSection
* monitor
= new SaffirePro24EAP::MonitorSection(eap
, "Monitoring");
447 getEAP()->addElement(monitor
);
453 void SaffirePro24::showDevice()
455 debugOutput(DEBUG_LEVEL_VERBOSE
, "This is a Dice::Focusrite::SaffirePro24\n");
456 Dice::Device::showDevice();
458 Dice::EAP
* SaffirePro24::createEAP() {
459 return new SaffirePro24EAP(*this);
462 bool SaffirePro24::setNickname( std::string name
) {
463 char nickname
[SAFFIRE_PRO24_APP_NICK_NAME_SIZE
+1];
465 // The device has room for SAFFIRE_PRO24_APP_NICK_NAME_SIZE characters.
466 // Erase supplementary characters or fill-in with NULL character if necessary
467 strncpy(nickname
, name
.c_str(), SAFFIRE_PRO24_APP_NICK_NAME_SIZE
);
469 // Strings from the device are always little-endian,
470 // so byteswap for big-endian machines
471 #if __BYTE_ORDER == __BIG_ENDIAN
472 byteSwapBlock((quadlet_t
*)nickname
, SAFFIRE_PRO24_APP_NICK_NAME_SIZE
/4);
475 if (!getEAP()->writeRegBlock(Dice::EAP::eRT_Application
, SAFFIRE_PRO24_REGISTER_APP_NICK_NAME
,
476 (quadlet_t
*)nickname
, SAFFIRE_PRO24_APP_NICK_NAME_SIZE
)) {
477 debugError("Could not write nickname string \n");
483 std::string
SaffirePro24::getNickname() {
484 char nickname
[SAFFIRE_PRO24_APP_NICK_NAME_SIZE
+1];
485 if (!getEAP()->readRegBlock(Dice::EAP::eRT_Application
, SAFFIRE_PRO24_REGISTER_APP_NICK_NAME
,
486 (quadlet_t
*)nickname
, SAFFIRE_PRO24_APP_NICK_NAME_SIZE
)){
487 debugError("Could not read nickname string \n");
488 return std::string("(unknown)");
491 // Strings from the device are always little-endian,
492 // so byteswap for big-endian machines
493 #if __BYTE_ORDER == __BIG_ENDIAN
494 byteSwapBlock((quadlet_t
*)nickname
, SAFFIRE_PRO24_APP_NICK_NAME_SIZE
/4);
497 // The device supplies at most SAFFIRE_PRO24_APP_NICK_NAME_SIZE characters. Ensure the string is
499 nickname
[SAFFIRE_PRO24_APP_NICK_NAME_SIZE
] = 0;
500 return std::string(nickname
);