root/trunk/libffado/src/rme/rme_avdevice.cpp

Revision 1689, 24.9 kB (checked in by jwoithe, 14 years ago)

RME: more streaming control tweaks.

Line 
1 /*
2  * Copyright (C) 2005-2009 by Jonathan Woithe
3  * Copyright (C) 2005-2008 by Pieter Palmers
4  *
5  * This file is part of FFADO
6  * FFADO = Free Firewire (pro-)audio drivers for linux
7  *
8  * FFADO is based upon FreeBoB.
9  *
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.
14  *
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.
19  *
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/>.
22  *
23  */
24
25 #warning RME support is at an early development stage and is not functional
26
27 #include "config.h"
28
29 #include "rme/rme_avdevice.h"
30 #include "rme/fireface_def.h"
31 #include "rme/fireface_settings_ctrls.h"
32
33 #include "libieee1394/configrom.h"
34 #include "libieee1394/ieee1394service.h"
35
36 #include "debugmodule/debugmodule.h"
37
38 #include "devicemanager.h"
39
40 #include <string>
41 #include <stdint.h>
42 #include <assert.h>
43 #include "libutil/ByteSwap.h"
44
45 #include <iostream>
46 #include <sstream>
47
48 #include <libraw1394/csr.h>
49
50 // Known values for the unit version of RME devices
51 #define RME_UNITVERSION_FF800  0x0001
52 #define RME_UNITVERSION_FF400  0x0002
53
54 namespace Rme {
55
56 // The RME devices expect async packet data in little endian format (as
57 // opposed to bus order, which is big endian).  Therefore define our own
58 // 32-bit byteswap function to do this.
59 #if __BYTE_ORDER == __BIG_ENDIAN
60 static inline uint32_t
61 ByteSwapToDevice32(uint32_t d)
62 {
63     return byteswap_32(d);
64 }
65 ByteSwapFromDevice32(uint32_t d)
66 {
67     return byteswap_32(d);
68 }
69 #else
70 static inline uint32_t
71 ByteSwapToDevice32(uint32_t d)
72 {
73     return d;
74 }
75 static inline uint32_t
76 ByteSwapFromDevice32(uint32_t d)
77 {
78     return d;
79 }
80 #endif
81
82 Device::Device( DeviceManager& d,
83                       std::auto_ptr<ConfigRom>( configRom ))
84     : FFADODevice( d, configRom )
85     , m_rme_model( RME_MODEL_NONE )
86     , num_channels( 0 )
87     , frames_per_packet( 0 )
88     , speed800( 0 )
89     , iso_tx_channel( -1 )
90     , iso_rx_channel( -1 )
91     , m_receiveProcessor( NULL )
92     , m_transmitProcessor( NULL )
93     , m_MixerContainer( NULL )
94     , m_ControlContainer( NULL )
95 {
96     debugOutput( DEBUG_LEVEL_VERBOSE, "Created Rme::Device (NodeID %d)\n",
97                  getConfigRom().getNodeId() );
98 }
99
100 Device::~Device()
101 {
102     if (iso_tx_channel>=0 && !get1394Service().freeIsoChannel(iso_tx_channel)) {
103         debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free tx iso channel %d\n", iso_tx_channel);
104     }
105     if (iso_rx_channel>=0 && !get1394Service().freeIsoChannel(iso_rx_channel)) {
106         debugOutput(DEBUG_LEVEL_VERBOSE, "Could not free rx iso channel %d\n", iso_rx_channel);
107     }
108
109     destroyMixer();
110
111     if (dev_config != NULL) {
112         switch (rme_shm_close(dev_config)) {
113             case RSO_CLOSE:
114                 debugOutput( DEBUG_LEVEL_VERBOSE, "Configuration shared data object closed\n");
115                 break;
116             case RSO_CLOSE_DELETE:
117                 debugOutput( DEBUG_LEVEL_VERBOSE, "Configuration shared data object closed and deleted (no other users)\n");
118                 break;
119         }
120     }
121 }
122
123 bool
124 Device::buildMixer() {
125     signed int i;
126     bool result = true;
127
128     destroyMixer();
129     debugOutput(DEBUG_LEVEL_VERBOSE, "Building an RME mixer...\n");
130
131
132     // Non-mixer device controls
133     m_ControlContainer = new Control::Container(this, "Control");
134     if (!m_ControlContainer) {
135         debugError("Could not create control container\n");
136         destroyMixer();
137         return false;
138     }
139
140     result &= m_ControlContainer->addElement(
141         new RmeSettingsCtrl(*this, RME_CTRL_INFO_MODEL, 0,
142             "Model", "Model ID", ""));
143     result &= m_ControlContainer->addElement(
144         new RmeSettingsCtrl(*this, RME_CTRL_INFO_TCO_PRESENT, 0,
145             "TCO_present", "TCO is present", ""));
146
147     result &= m_ControlContainer->addElement(
148         new RmeSettingsCtrl(*this, RME_CTRL_PHANTOM_SW, 0,
149             "Phantom", "Phantom switches", ""));
150     result &= m_ControlContainer->addElement(
151         new RmeSettingsCtrl(*this, RME_CTRL_INPUT_LEVEL, 0,
152             "Input_level", "Input level", ""));
153     result &= m_ControlContainer->addElement(
154         new RmeSettingsCtrl(*this, RME_CTRL_OUTPUT_LEVEL, 0,
155             "Output_level", "Output level", ""));
156     result &= m_ControlContainer->addElement(
157         new RmeSettingsCtrl(*this, RME_CTRL_PHONES_LEVEL, 0,
158             "Phones_level", "Phones level", ""));
159
160     if (m_rme_model == RME_MODEL_FIREFACE400) {
161         // Instrument input options
162         for (i=3; i<=4; i++) {
163             char path[32], desc[64];
164             snprintf(path, sizeof(path), "Chan%d_opt_instr", i);
165             snprintf(desc, sizeof(desc), "Chan%d instrument option", i);
166             result &= m_ControlContainer->addElement(
167                 new RmeSettingsCtrl(*this, RME_CTRL_FF400_INSTR_SW, i,
168                     path, desc, ""));
169             snprintf(path, sizeof(path), "Chan%d_opt_pad", i);
170             snprintf(desc, sizeof(desc), "Chan%d pad option", i);
171             result &= m_ControlContainer->addElement(
172                 new RmeSettingsCtrl(*this, RME_CTRL_FF400_PAD_SW, i,
173                     path, desc, ""));
174         }
175
176         // Input/output gains
177         result &= m_ControlContainer->addElement(
178             new RmeSettingsMatrixCtrl(*this, RME_MATRIXCTRL_GAINS, "Gains"));
179     }
180
181     if (!result) {
182         debugWarning("One or more device control elements could not be created\n");
183         destroyMixer();
184         return false;
185     }
186
187     if (!addElement(m_ControlContainer)) {
188         debugWarning("Could not register mixer to device\n");
189         // clean up
190         destroyMixer();
191         return false;
192     }
193
194     return true;
195 }
196
197 bool
198 Device::destroyMixer() {
199     bool ret = true;
200     debugOutput(DEBUG_LEVEL_VERBOSE, "destroy mixer...\n");
201
202     if (m_MixerContainer == NULL) {
203         debugOutput(DEBUG_LEVEL_VERBOSE, "no mixer to destroy...\n");
204     } else
205     if (!deleteElement(m_MixerContainer)) {
206         debugError("Mixer present but not registered to the avdevice\n");
207         ret = false;
208     } else {
209         // remove and delete (as in free) child control elements
210         m_MixerContainer->clearElements(true);
211         delete m_MixerContainer;
212         m_MixerContainer = NULL;
213     }
214
215     // remove control container
216     if (m_ControlContainer == NULL) {
217         debugOutput(DEBUG_LEVEL_VERBOSE, "no controls to destroy...\n");
218     } else
219     if (!deleteElement(m_ControlContainer)) {
220         debugError("Controls present but not registered to the avdevice\n");
221         ret = false;
222     } else {
223         // remove and delete (as in free) child control elements
224         m_ControlContainer->clearElements(true);
225         delete m_ControlContainer;
226         m_ControlContainer = NULL;
227     }
228
229     return false;
230 }
231
232 bool
233 Device::probe( Util::Configuration& c, ConfigRom& configRom, bool generic )
234 {
235     if (generic) {
236         return false;
237     } else {
238         // check if device is in supported devices list.  Note that the RME
239         // devices use the unit version to identify the individual devices.
240         // To avoid having to extend the configuration file syntax to
241         // include this at this point, we'll use the configuration file
242         // model ID to test against the device unit version.  This can be
243         // tidied up if the configuration file is extended at some point to
244         // include the unit version.
245         unsigned int vendorId = configRom.getNodeVendorId();
246         unsigned int unitVersion = configRom.getUnitVersion();
247
248         Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion );
249         return c.isValid(vme) && vme.driver == Util::Configuration::eD_RME;
250     }
251 }
252
253 FFADODevice *
254 Device::createDevice(DeviceManager& d, std::auto_ptr<ConfigRom>( configRom ))
255 {
256     return new Device(d, configRom );
257 }
258
259 bool
260 Device::discover()
261 {
262     signed int i;
263     unsigned int vendorId = getConfigRom().getNodeVendorId();
264     // See note in Device::probe() about why we use the unit version here.
265     unsigned int unitVersion = getConfigRom().getUnitVersion();
266
267     Util::Configuration &c = getDeviceManager().getConfiguration();
268     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, unitVersion );
269
270     if (c.isValid(vme) && vme.driver == Util::Configuration::eD_RME) {
271         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n",
272                      vme.vendor_name.c_str(),
273                      vme.model_name.c_str());
274     } else {
275         debugWarning("Device '%s %s' unsupported by RME driver (no generic RME support)\n",
276                      getConfigRom().getVendorName().c_str(), getConfigRom().getModelName().c_str());
277     }
278
279     if (unitVersion == RME_UNITVERSION_FF800) {
280         m_rme_model = RME_MODEL_FIREFACE800;
281     } else
282     if (unitVersion == RME_MODEL_FIREFACE400) {
283         m_rme_model = RME_MODEL_FIREFACE400;
284     } else {
285         debugError("Unsupported model\n");
286         return false;
287     }
288
289     // Set up the shared data object for configuration data
290     i = rme_shm_open(&dev_config);
291     if (i == RSO_OPEN_CREATED) {
292         debugOutput( DEBUG_LEVEL_VERBOSE, "New configuration shared data object created\n");
293     } else
294     if (i == RSO_OPEN_ATTACHED) {
295         debugOutput( DEBUG_LEVEL_VERBOSE, "Attached to existing configuration shared data object\n");
296     }
297     if (dev_config == NULL) {
298         debugOutput( DEBUG_LEVEL_WARNING, "Could not create/access shared configuration memory object, using process-local storage\n");
299         memset(&local_dev_config_obj, 0, sizeof(local_dev_config_obj));
300         dev_config = &local_dev_config_obj;
301     }
302     settings = &dev_config->settings;
303     tco_settings = &dev_config->tco_settings;
304
305     // If device is FF800, check to see if the TCO is fitted
306     if (m_rme_model == RME_MODEL_FIREFACE800) {
307         dev_config->tco_present = (read_tco(NULL, 0) == 0);
308     }
309     debugOutput(DEBUG_LEVEL_VERBOSE, "TCO present: %s\n",
310       dev_config->tco_present?"yes":"no");
311
312     init_hardware();
313
314     if (!buildMixer()) {
315         debugWarning("Could not build mixer\n");
316     }
317
318     // This is just for testing
319     read_device_flash_settings(NULL);
320
321     return true;
322 }
323
324 int
325 Device::getSamplingFrequency( ) {
326
327     // Retrieve the current sample rate.  For practical purposes this
328     // is the software rate currently in use.
329     return dev_config->software_freq;
330 }
331
332 int
333 Device::getConfigurationId()
334 {
335     return 0;
336 }
337
338 bool
339 Device::setDDSFrequency( int dds_freq )
340 {
341     // Set a fixed DDS frequency.  If the device is the clock master this
342     // will immediately be copied to the hardware DDS register.  Otherwise
343     // it will take effect as required at the time the sampling rate is
344     // changed or streaming is started.
345
346     // If the device is streaming, the new DDS rate must have the same
347     // multiplier as the software sample rate
348     if (hardware_is_streaming()) {
349         if (multiplier_of_freq(dds_freq) != multiplier_of_freq(dev_config->software_freq))
350             return false;
351     }
352
353     dev_config->dds_freq = dds_freq;
354     if (settings->clock_mode == FF_STATE_CLOCKMODE_MASTER) {
355         if (set_hardware_dds_freq(dds_freq) != 0)
356             return false;
357     }
358
359     return true;
360 }
361
362 bool
363 Device::setSamplingFrequency( int samplingFrequency )
364 {
365     // Request a sampling rate on behalf of software.  Software is limited
366     // to sample rates of 32k, 44.1k, 48k and the 2x/4x multiples of these.
367     // The user may lock the device to a much wider range of frequencies via
368     // the explicit DDS controls in the control panel.  If the explicit DDS
369     // control is active the software is limited to the "standard" speeds
370     // corresponding to the multiplier in use by the DDS.
371     //
372     // Similarly, if the device is externally clocked the software is
373     // limited to the external clock frequency.
374     //
375     // Otherwise the software has free choice of the software speeds noted
376     // above.
377
378     bool ret = -1;
379     signed int i, j;
380     signed int mult[3] = {1, 2, 4};
381     signed int base_freq[3] = {32000, 44100, 48000};
382     signed int freq = samplingFrequency;
383     FF_state_t state;
384     signed int fixed_freq = 0;
385
386     get_hardware_state(&state);
387
388     // If device is locked to a frequency via external clock, explicit
389     // setting of the DDS or by virtue of streaming being active, get that
390     // frequency.
391     if (state.clock_mode == FF_STATE_CLOCKMODE_AUTOSYNC) {
392         // FIXME: if synced to TCO, is autosync_freq valid?
393         fixed_freq = state.autosync_freq;
394     } else
395     if (dev_config->dds_freq > 0) {
396         fixed_freq = dev_config->dds_freq;
397     } else
398     if (hardware_is_streaming()) {
399         fixed_freq = dev_config->software_freq;
400     }
401
402     // If the device is running to a fixed frequency, software can only
403     // request frequencies with the same multiplier.  Similarly, the
404     // multiplier is locked in "master" clock mode if the device is
405     // streaming.
406     if (fixed_freq > 0) {
407         signed int fixed_mult = multiplier_of_freq(fixed_freq);
408         if (multiplier_of_freq(freq) != multiplier_of_freq(fixed_freq))
409             return -1;
410         for (j=0; j<3; j++) {
411             if (freq == base_freq[j]*fixed_mult) {
412                 ret = 0;
413                 break;
414             }
415         }
416     } else {
417         for (i=0; i<3; i++) {
418             for (j=0; j<3; j++) {
419                 if (freq == base_freq[j]*mult[i]) {
420                     ret = 0;
421                     break;
422                 }
423             }
424         }
425     }
426     // If requested frequency is unavailable, return -1
427     if (ret == -1)
428         return false;
429
430     // If a DDS frequency has been explicitly requested this is always
431     // used to programm the hardware DDS regardless of the rate requested
432     // by the software.  Otherwise we use the requested sampling rate.
433     if (dev_config->dds_freq > 0)
434         freq = dev_config->dds_freq;
435     if (set_hardware_dds_freq(freq) != 0)
436         return false;
437
438     dev_config->software_freq = samplingFrequency;
439     return true;
440 }
441
442 std::vector<int>
443 Device::getSupportedSamplingFrequencies()
444 {
445     std::vector<int> frequencies;
446     signed int i, j;
447     signed int mult[3] = {1, 2, 4};
448     signed int freq[3] = {32000, 44100, 48000};
449     FF_state_t state;
450
451     get_hardware_state(&state);
452
453     // Generate the list of supported frequencies.  If the device is
454     // externally clocked the frequency is limited to the external clock
455     // frequency.  If the device is running the multiplier is fixed.
456     if (state.clock_mode == FF_STATE_CLOCKMODE_AUTOSYNC) {
457         // FIXME: if synced to TCO, is autosync_freq valid?
458         frequencies.push_back(state.autosync_freq);
459     } else
460     if (state.is_streaming) {
461         unsigned int fixed_mult = multiplier_of_freq(dev_config->software_freq);
462         for (j=0; j<3; j++) {
463             frequencies.push_back(freq[j]*fixed_mult);
464         }
465     } else {
466         for (i=0; i<3; i++) {
467             for (j=0; j<3; j++) {
468                 frequencies.push_back(freq[j]*mult[i]);
469             }
470         }
471     }
472     return frequencies;
473 }
474
475 FFADODevice::ClockSourceVector
476 Device::getSupportedClockSources() {
477     FFADODevice::ClockSourceVector r;
478     return r;
479 }
480
481 bool
482 Device::setActiveClockSource(ClockSource s) {
483     return false;
484 }
485
486 FFADODevice::ClockSource
487 Device::getActiveClockSource() {
488     ClockSource s;
489     return s;
490 }
491
492 bool
493 Device::lock() {
494
495     return true;
496 }
497
498
499 bool
500 Device::unlock() {
501
502     return true;
503 }
504
505 void
506 Device::showDevice()
507 {
508     unsigned int vendorId = getConfigRom().getNodeVendorId();
509     unsigned int modelId = getConfigRom().getModelId();
510
511     Util::Configuration &c = getDeviceManager().getConfiguration();
512     Util::Configuration::VendorModelEntry vme = c.findDeviceVME( vendorId, modelId );
513
514     debugOutput(DEBUG_LEVEL_VERBOSE,
515         "%s %s at node %d\n", vme.vendor_name.c_str(), vme.model_name.c_str(), getNodeId());
516 }
517
518 bool
519 Device::prepare() {
520
521     signed int mult, bandwidth;
522     signed int freq, init_samplerate;
523     signed int err = 0;
524     unsigned int stat[4];
525
526     debugOutput(DEBUG_LEVEL_NORMAL, "Preparing Device...\n" );
527
528     freq = getSamplingFrequency();
529     if (freq <= 0) {
530         debugOutput(DEBUG_LEVEL_ERROR, "Can't continue: sampling frequency not set\n");
531         return false;
532     }
533
534     // The number of frames transmitted in a single packet is solely
535     // determined by the sample rate.
536     mult = multiplier_of_freq(freq);
537     switch (mult) {
538         case 2: frames_per_packet = 15; break;
539         case 4: frames_per_packet = 25; break;
540     default:
541         frames_per_packet = 7;
542     }
543
544     // The number of active channels depends on sample rate and whether
545     // bandwidth limitation is active.  First set up the number of analog
546     // channels (which differs between devices), then add SPDIF channels if
547     // relevant.  Finally, the number of channels available from each ADAT
548     // interface depends on sample rate: 0 at 4x, 4 at 2x and 8 at 1x.
549     if (m_rme_model == RME_MODEL_FIREFACE800)
550         num_channels = 10;
551     else
552         num_channels = 8;
553     if (settings->limit_bandwidth != FF_SWPARAM_BWLIMIT_ANALOG_ONLY)
554         num_channels += 2;
555     if (settings->limit_bandwidth==FF_SWPARAM_BWLIMIT_NO_ADAT2 ||
556         settings->limit_bandwidth==FF_SWPARAM_BWLIMIT_SEND_ALL_CHANNELS)
557         num_channels += (mult==4?0:(mult==2?4:8));
558     if (settings->limit_bandwidth==FF_SWPARAM_BWLIMIT_SEND_ALL_CHANNELS)
559         num_channels += (mult==4?0:(mult==2?4:8));
560
561     // Bandwidth is calculated here.  For the moment we assume the device
562     // is connected at S400, so 1 allocation unit is 1 transmitted byte.
563     // There is 25 allocation units of protocol overhead per packet.  Each
564     // channel of audio data is sent/received as a 32 bit integer.
565     bandwidth = 25 + num_channels*4*frames_per_packet;
566
567     // Both the FF400 and FF800 require we allocate a tx iso channel and
568     // then initialise the device.  Device status is then read at least once
569     // regardless of which interface is in use.  The rx channel is then
570     // allocated for the FF400 or acquired from the device in the case of
571     // the FF800.  Even though the FF800 chooses the rx channel it does not
572     // handle the bus-level channel/bandwidth allocation so we must do that
573     // here.
574     if (iso_tx_channel < 0) {
575         iso_tx_channel = get1394Service().allocateIsoChannelGeneric(bandwidth);
576     }
577     if (iso_tx_channel < 0) {
578         debugFatal("Could not allocate iso tx channel\n");
579         return false;
580     }
581
582     err = hardware_init_streaming(dev_config->hardware_freq, iso_tx_channel) != 0;
583     if (err) {
584         debugFatal("Could not intialise device streaming system\n");
585     }
586
587     if (err == 0) {
588         signed int i;
589         for (i=0; i<100; i++) {
590             err = (get_hardware_streaming_status(stat, 4) != 0);
591             if (err) {
592                 debugFatal("error reading status register\n");
593                 break;
594             }
595             if (m_rme_model == RME_MODEL_FIREFACE400) {
596                 iso_rx_channel = get1394Service().allocateIsoChannelGeneric(bandwidth);
597                 break;
598             }
599             // The Fireface-800 chooses its tx channel (our rx channel).
600             if (stat[2] == -1) {
601                 // Device not ready; wait 5 ms and try again
602                 usleep(5000);
603             } else {
604                 iso_rx_channel = stat[2] & 63;
605                 iso_rx_channel = get1394Service().allocateFixedIsoChannelGeneric(iso_rx_channel, bandwidth);
606             }
607         }
608         if (iso_rx_channel < 0) {
609             debugFatal("Could not allocate/determine iso rx channel\n");
610             err = 1;
611         }
612     }
613  
614     if (err) {
615         if (iso_tx_channel >= 0)
616             get1394Service().freeIsoChannel(iso_tx_channel);
617         if (iso_rx_channel >= 0)
618             get1394Service().freeIsoChannel(iso_rx_channel);
619         return false;
620     }
621
622     if ((stat[1] & SR1_CLOCK_MODE_MASTER) ||
623         (stat[0] & SR0_AUTOSYNC_FREQ_MASK)==0 ||
624         (stat[0] & SR0_AUTOSYNC_SRC_MASK)==SR0_AUTOSYNC_SRC_NONE) {
625         init_samplerate = dev_config->hardware_freq;
626     } else {
627         init_samplerate = (stat[0] & SR0_STREAMING_FREQ_MASK) * 250;
628     }
629
630     debugOutput(DEBUG_LEVEL_VERBOSE, "sample rate on start: %d\n",
631         init_samplerate);
632
633     // get the device specific and/or global SP configuration
634     Util::Configuration &config = getDeviceManager().getConfiguration();
635     // base value is the config.h value
636     float recv_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ;
637     float xmit_sp_dll_bw = STREAMPROCESSOR_DLL_BW_HZ;
638
639     // we can override that globally
640     config.getValueForSetting("streaming.spm.recv_sp_dll_bw", recv_sp_dll_bw);
641     config.getValueForSetting("streaming.spm.xmit_sp_dll_bw", xmit_sp_dll_bw);
642
643     // or override in the device section
644     config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "recv_sp_dll_bw", recv_sp_dll_bw);
645     config.getValueForDeviceSetting(getConfigRom().getNodeVendorId(), getConfigRom().getModelId(), "xmit_sp_dll_bw", xmit_sp_dll_bw);
646
647     // Set up receive stream processor, initialise it and set DLL bw
648     // TODO: set event_size properly; the value below is just a placeholder.
649     signed int event_size = 0x1000;
650     #warning event_size needs setting up
651     m_receiveProcessor = new Streaming::RmeReceiveStreamProcessor(*this,
652       m_rme_model, event_size);
653     m_receiveProcessor->setVerboseLevel(getDebugLevel());
654     if (!m_receiveProcessor->init()) {
655         debugFatal("Could not initialize receive processor!\n");
656         return false;
657     }
658     if (!m_receiveProcessor->setDllBandwidth(recv_sp_dll_bw)) {
659         debugFatal("Could not set DLL bandwidth\n");
660         delete m_receiveProcessor;
661         m_receiveProcessor = NULL;
662         return false;
663     }
664
665
666     // Add ports to the processor - TODO
667     std::string id=std::string("dev?");
668     if (!getOption("id", id)) {
669         debugWarning("Could not retrieve id parameter, defaulting to 'dev?'\n");
670     }
671
672     // Other things to be done:
673     //  * create a transmit stream processor, set DLL bandwidth, add ports
674
675     return true;
676 }
677
678 int
679 Device::getStreamCount() {
680 // Only rx implemented at present
681         return 1; // one receive, one transmit
682 }
683
684 Streaming::StreamProcessor *
685 Device::getStreamProcessorByIndex(int i) {
686     switch (i) {
687         case 0:
688             return m_receiveProcessor;
689         case 1:
690             return m_transmitProcessor;
691         default:
692             debugWarning("Invalid stream index %d\n", i);
693     }
694     return NULL;
695 }
696
697 bool
698 Device::startStreamByIndex(int i) {
699     // The RME does not allow separate enabling of the transmit and receive
700     // streams.  Therefore we start all streaming when index 0 is referenced
701     // and silently ignore the start requests for other streams
702     // (unconditionally flagging them as being successful).
703     if (i == 0) {
704         m_receiveProcessor->setChannel(iso_rx_channel);
705         // m_transmitProcessor->setChannel(iso_tx_channel);
706         if (hardware_start_streaming(iso_rx_channel) != 0)
707             return false;
708     }
709     return true;
710 }
711
712 bool
713 Device::stopStreamByIndex(int i) {
714     // See comments in startStreamByIndex() as to why we act only when stream
715     // 0 is requested.
716     if (i == 0) {
717         if (hardware_stop_streaming() != 0)
718             return false;
719     }
720     return true;
721 }
722
723 unsigned int
724 Device::readRegister(fb_nodeaddr_t reg) {
725
726     quadlet_t quadlet;
727    
728     quadlet = 0;
729     if (get1394Service().read(0xffc0 | getNodeId(), reg, 1, &quadlet) <= 0) {
730         debugError("Error doing RME read from register 0x%06x\n",reg);
731     }
732     return ByteSwapFromDevice32(quadlet);
733 }
734
735 signed int
736 Device::readBlock(fb_nodeaddr_t reg, quadlet_t *buf, unsigned int n_quads) {
737
738     unsigned int i;
739
740     if (get1394Service().read(0xffc0 | getNodeId(), reg, n_quads, buf) <= 0) {
741         debugError("Error doing RME block read of %d quadlets from register 0x%06x\n",
742             n_quads, reg);
743         return -1;
744     }
745     for (i=0; i<n_quads; i++) {
746        buf[i] = ByteSwapFromDevice32(buf[i]);
747     }
748
749     return 0;
750 }
751
752 signed int
753 Device::writeRegister(fb_nodeaddr_t reg, quadlet_t data) {
754
755     unsigned int err = 0;
756     data = ByteSwapToDevice32(data);
757     if (get1394Service().write(0xffc0 | getNodeId(), reg, 1, &data) <= 0) {
758         err = 1;
759         debugError("Error doing RME write to register 0x%06x\n",reg);
760     }
761     return (err==0)?0:-1;
762 }
763
764 signed int
765 Device::writeBlock(fb_nodeaddr_t reg, quadlet_t *data, unsigned int n_quads) {
766 //
767 // Write a block of data to the device starting at address "reg".  Note that
768 // the conditional byteswap is done "in place" on data, so the contents of
769 // data may be modified by calling this function.
770 //
771     unsigned int err = 0;
772     unsigned int i;
773
774     for (i=0; i<n_quads; i++) {
775       data[i] = ByteSwapToDevice32(data[i]);
776     }
777     if (get1394Service().write(0xffc0 | getNodeId(), reg, n_quads, data) <= 0) {
778         err = 1;
779         debugError("Error doing RME block write of %d quadlets to register 0x%06x\n",
780           n_quads, reg);
781     }
782     return (err==0)?0:-1;
783 }
784                  
785 }
Note: See TracBrowser for help on using the browser.