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

Revision 1690, 26.2 kB (checked in by jwoithe, 14 years ago)

RME:
* work on streaming setup continues
* some whitespace cleanups
* update documentation

Line 
1 /*
2  * Copyright (C) 2009 by Jonathan Woithe
3  *
4  * This file is part of FFADO
5  * FFADO = Free Firewire (pro-)audio drivers for linux
6  *
7  * FFADO is based upon FreeBoB.
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 2 of the License, or
12  * (at your option) version 3 of the License.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
21  *
22  */
23
24 /* This file implements miscellaneous lower-level hardware functions for the Fireface */
25
26 #include "rme/rme_avdevice.h"
27 #include "rme/fireface_def.h"
28
29 #include "debugmodule/debugmodule.h"
30
31 namespace Rme {
32
33 unsigned int
34 Device::multiplier_of_freq(unsigned int freq)
35 {
36     if (freq > MIN_QUAD_SPEED)
37       return 4;
38     if (freq > MIN_DOUBLE_SPEED)
39       return 2;
40     return 1;
41 }
42
43 void
44 Device::config_lock(void) {
45     rme_shm_lock(dev_config);
46 }
47
48 void
49 Device::config_unlock(void) {
50     rme_shm_unlock(dev_config);
51 }
52
53 signed int
54 Device::init_hardware(void)
55 {
56     signed int ret = 0;
57
58     // Initialises the device's settings structure to a known state and then
59     // sets the hardware to reflect this state.
60
61     config_lock();
62
63     // In time this function may read a cached device setup and initialise
64     // based on that.  It may also read the device configuration from the
65     // device flash and adopt that.  For now (for initial testing purposes)
66     // we'll go with a static state.
67     if (dev_config->settings_valid==0) {
68         memset(settings, 0, sizeof(*settings));
69         settings->spdif_input_mode = FF_SWPARAM_SPDIF_INPUT_COAX;
70         settings->spdif_output_mode = FF_SWPARAM_SPDIF_OUTPUT_COAX;
71         settings->clock_mode = FF_SWPARAM_CLOCK_MODE_MASTER;
72         settings->sync_ref = FF_SWPARAM_SYNCREF_WORDCLOCK;
73         settings->input_level = FF_SWPARAM_ILEVEL_LOGAIN;
74         settings->output_level = FF_SWPARAM_OLEVEL_HIGAIN;
75         settings->phones_level = FF_SWPARAM_PHONESLEVEL_HIGAIN;
76         settings->limit_bandwidth = FF_SWPARAM_BWLIMIT_SEND_ALL_CHANNELS;
77
78         // Set amplifier gains
79         if (m_rme_model == RME_MODEL_FIREFACE400) {
80             signed int i;
81             for (i=0; i<FF400_AMPGAIN_NUM; i++) {
82                 set_hardware_ampgain(i, settings->amp_gains[i]);
83             }
84         }
85
86         dev_config->settings_valid = 1;
87     }
88
89     // A default sampling rate.  An explicit DDS frequency is not enabled
90     // by default.
91     dev_config->software_freq = 44100;
92     dev_config->dds_freq = 0;
93
94     if (set_hardware_params(settings) != 0)
95         ret = -1;
96
97     // Also configure the TCO (Time Code Option) settings for those devices
98     // which have a TCO.
99     if (ret==0 && dev_config->tco_settings_valid==0) {
100         if (dev_config->tco_present) {
101             memset(tco_settings, 0, sizeof(*tco_settings));
102             write_tco_settings(tco_settings);
103         }
104         dev_config->tco_settings_valid = 1;
105     }
106
107     config_unlock();
108
109     return ret;
110 }
111
112 signed int
113 Device::get_hardware_status(unsigned int *stat0, unsigned int *stat1)
114 {
115     unsigned int buf[2];
116     if (readBlock(RME_FF_STATUS_REG0, buf, 2) != 0)
117         return -1;
118     *stat0 = buf[0];
119     *stat1 = buf[1];
120     return 0;
121 }
122
123 signed int
124 Device::get_hardware_streaming_status(unsigned int *stat, unsigned int n)
125 {
126     // Get the hardware status as it applies to the streaming system.  This
127     // involves a request of 4 quadlets from the status register.  It
128     // appears that the first register's definition is slightly different in
129     // this situation compared to when only 2 quadlets are requested as is
130     // done in get_hardware_status().
131     //
132     // "n" is the size of the passed-in stat array.  It must be >= 4.
133     if (n < 4)
134         return -1;
135     if (readBlock(RME_FF_STATUS_REG0, stat, 4) != 0)
136         return -1;
137     return 0;
138 }
139
140 signed int
141 Device::get_hardware_state(FF_state_t *state)
142 {
143     // Retrieve the hardware status and deduce the device state.  Return
144     // -1 on error, 0 on success.  The given state structure will be
145     // cleared by this call.
146     unsigned int stat0, stat1;
147     memset(state, 0, sizeof(*state));
148     if (get_hardware_status(&stat0, &stat1) != 0)
149         return -1;
150
151     state->is_streaming = dev_config->is_streaming;
152
153     state->clock_mode = (settings->clock_mode == FF_SWPARAM_CLOCK_MODE_MASTER)?FF_STATE_CLOCKMODE_MASTER:FF_STATE_CLOCKMODE_AUTOSYNC;
154
155     switch (stat0 & SR0_AUTOSYNC_SRC_MASK) {
156         case SR0_AUTOSYNC_SRC_ADAT1:
157             state->autosync_source = FF_STATE_AUTOSYNC_SRC_ADAT1;
158             break;
159         case SR0_AUTOSYNC_SRC_ADAT2:
160             state->autosync_source = FF_STATE_AUTOSYNC_SRC_ADAT2;
161             break;
162         case SR0_AUTOSYNC_SRC_SPDIF:
163             state->autosync_source = FF_STATE_AUTOSYNC_SRC_SPDIF;
164             break;
165         case SR0_AUTOSYNC_SRC_WCLK:
166             state->autosync_source = FF_STATE_AUTOSYNC_SRC_WCLK;
167             break;
168         case SR0_AUTOSYNC_SRC_TCO:
169             state->autosync_source = FF_STATE_AUTOSYNC_SRC_TCO;
170             break;
171         default: state->autosync_source = FF_STATE_AUTOSYNC_SRC_NOLOCK;
172     }
173
174     switch (stat0 & SR0_AUTOSYNC_FREQ_MASK) {
175         case SR0_AUTOSYNC_FREQ_32k:  state->autosync_freq = 32000; break;
176         case SR0_AUTOSYNC_FREQ_44k1: state->autosync_freq = 44100; break;
177         case SR0_AUTOSYNC_FREQ_48k:  state->autosync_freq = 48000; break;
178         case SR0_AUTOSYNC_FREQ_64k:  state->autosync_freq = 64000; break;
179         case SR0_AUTOSYNC_FREQ_88k2: state->autosync_freq = 88200; break;
180         case SR0_AUTOSYNC_FREQ_96k:  state->autosync_freq = 96000; break;
181         case SR0_AUTOSYNC_FREQ_128k: state->autosync_freq = 128000; break;
182         case SR0_AUTOSYNC_FREQ_176k4:state->autosync_freq = 176400; break;
183         case SR0_AUTOSYNC_FREQ_192k: state->autosync_freq = 192000; break;
184     }
185
186     switch (stat0 & SR0_SPDIF_FREQ_MASK) {
187         case SR0_SPDIF_FREQ_32k:  state->spdif_freq = 32000; break;
188         case SR0_SPDIF_FREQ_44k1: state->spdif_freq = 41000; break;
189         case SR0_SPDIF_FREQ_48k:  state->spdif_freq = 48000; break;
190         case SR0_SPDIF_FREQ_64k:  state->spdif_freq = 64000; break;
191         case SR0_SPDIF_FREQ_88k2: state->spdif_freq = 88200; break;
192         case SR0_SPDIF_FREQ_96k:  state->spdif_freq = 96000; break;
193         case SR0_SPDIF_FREQ_128k: state->spdif_freq = 128000; break;
194         case SR0_SPDIF_FREQ_176k4:state->spdif_freq = 176400; break;
195         case SR0_SPDIF_FREQ_192k: state->spdif_freq = 192000; break;
196     }
197
198     switch (stat0 & SR0_ADAT1_STATUS_MASK) {
199         case SR0_ADAT1_STATUS_NOLOCK:
200             state->adat1_sync_status = FF_STATE_SYNC_NOLOCK; break;
201         case SR0_ADAT1_STATUS_LOCK:
202             state->adat1_sync_status = FF_STATE_SYNC_LOCKED; break;
203         case SR0_ADAT1_STATUS_SYNC:
204             state->adat1_sync_status = FF_STATE_SYNC_SYNCED; break;
205     }
206     switch (stat0 & SR0_ADAT2_STATUS_MASK) {
207         case SR0_ADAT2_STATUS_NOLOCK:
208             state->adat2_sync_status = FF_STATE_SYNC_NOLOCK; break;
209         case SR0_ADAT2_STATUS_LOCK:
210             state->adat2_sync_status = FF_STATE_SYNC_LOCKED; break;
211         case SR0_ADAT2_STATUS_SYNC:
212             state->adat2_sync_status = FF_STATE_SYNC_SYNCED; break;
213     }
214     switch (stat0 & SR0_SPDIF_STATUS_MASK) {
215         case SR0_SPDIF_STATUS_NOLOCK:
216             state->spdif_sync_status = FF_STATE_SYNC_NOLOCK; break;
217         case SR0_SPDIF_STATUS_LOCK:
218             state->spdif_sync_status = FF_STATE_SYNC_LOCKED; break;
219         case SR0_SPDIF_STATUS_SYNC:
220             state->spdif_sync_status = FF_STATE_SYNC_SYNCED; break;
221     }
222     switch (stat0 & SR0_WCLK_STATUS_MASK) {
223         case SR0_WCLK_STATUS_NOLOCK:
224             state->wclk_sync_status = FF_STATE_SYNC_NOLOCK; break;
225         case SR0_WCLK_STATUS_LOCK:
226             state->wclk_sync_status = FF_STATE_SYNC_LOCKED; break;
227         case SR0_WCLK_STATUS_SYNC:
228             state->wclk_sync_status = FF_STATE_SYNC_SYNCED; break;
229     }
230     switch (stat1 & SR1_TCO_STATUS_MASK) {
231        case SR1_TCO_STATUS_NOLOCK:
232            state->tco_sync_status = FF_STATE_SYNC_NOLOCK; break;
233        case SR1_TCO_STATUS_LOCK:
234            state->tco_sync_status = FF_STATE_SYNC_LOCKED; break;
235        case SR1_TCO_STATUS_SYNC:
236            state->tco_sync_status = FF_STATE_SYNC_SYNCED; break;
237     }
238
239     return 0;
240 }
241
242 signed int
243 Device::set_hardware_params(FF_software_settings_t *use_settings)
244 {
245     // Initialises the hardware to the state defined by the supplied
246     // software settings structure (which will usually be the device's
247     // "settings" structure).  This has the side effect of extinguishing the
248     // "Host" LED on the FF400 when done for the first time after the
249     // interface has been powered up.
250     //
251     // If use_settings is NULL, the device's current settings structure will
252     // be used to source the configuration information.
253
254     FF_software_settings_t *sw_settings;
255     quadlet_t data[3] = {0, 0, 0};
256     unsigned int conf_reg;
257
258     if (use_settings == NULL)
259       sw_settings = settings;
260     else
261       sw_settings = use_settings;
262
263     if (sw_settings->mic_phantom[0])
264       data[0] |= CR0_PHANTOM_MIC0;
265     if (sw_settings->mic_phantom[1])
266       data[0] |= CR0_PHANTOM_MIC1;
267     if (m_rme_model == RME_MODEL_FIREFACE800) {
268         if (sw_settings->mic_phantom[2])
269             data[0] |= CR0_FF800_PHANTOM_MIC9;
270         if (sw_settings->mic_phantom[3])
271             data[0] |= CR0_FF800_PHANTOM_MIC10;
272     } else {
273         if (sw_settings->ff400_input_pad[0])
274             data[0] |= CR0_FF400_CH3_PAD;
275         if (sw_settings->ff400_input_pad[1])
276             data[0] |= CR0_FF400_CH4_PAD;
277     }
278
279     /* Phones level */
280     switch (sw_settings->phones_level) {
281         case FF_SWPARAM_PHONESLEVEL_HIGAIN:
282             data[0] |= CRO_PHLEVEL_HIGAIN;
283             break;
284         case FF_SWPARAM_PHONESLEVEL_4dBU:
285             data[0] |= CR0_PHLEVEL_4dBU;
286             break;
287         case FF_SWPARAM_PHONESLEVEL_m10dBV:
288             data[0] |= CRO_PHLEVEL_m10dBV;
289             break;
290     }
291
292     /* Input level */
293     switch (sw_settings->input_level) {
294         case FF_SWPARAM_ILEVEL_LOGAIN: // Low gain
295             data[1] |= CR1_ILEVEL_CPLD_LOGAIN;    // CPLD
296             data[0] |= CR0_ILEVEL_FPGA_LOGAIN;    // LED control (used on FF800 only)
297             break;
298         case FF_SWPARAM_ILEVEL_4dBU:   // +4 dBu
299             data[1] |= CR1_ILEVEL_CPLD_4dBU;
300             data[0] |= CR0_ILEVEL_FPGA_4dBU;
301             break;
302         case FF_SWPARAM_ILEVEL_m10dBV: // -10 dBV
303             data[1] |= CR1_ILEVEL_CPLD_m10dBV;
304             data[0] |= CR0_ILEVEL_FPGA_m10dBV;
305             break;
306     }
307
308     /* Output level */
309     switch (sw_settings->output_level) {
310         case FF_SWPARAM_OLEVEL_HIGAIN: // High gain
311             data[1] |= CR1_OLEVEL_CPLD_HIGAIN;   // CPLD
312             data[0] |= CR0_OLEVEL_FPGA_HIGAIN;   // LED control (used on FF800 only)
313             break;
314         case FF_SWPARAM_OLEVEL_4dBU:   // +4 dBu
315             data[1] |= CR1_OLEVEL_CPLD_4dBU;
316             data[0] |= CR0_OLEVEL_FPGA_4dBU;
317             break;
318         case FF_SWPARAM_OLEVEL_m10dBV: // -10 dBV
319             data[1] |= CR1_OLEVEL_CPLD_m10dBV;
320             data[0] |= CR0_OLEVEL_FPGA_m10dBV;
321             break;
322     }
323
324     /* Set input options.  The meaning of the options differs between
325      * devices, so we use the generic identifiers here.
326      */
327     data[1] |= (sw_settings->input_opt[1] & FF_SWPARAM_INPUT_OPT_A) ? CR1_INPUT_OPT1_A : 0;
328     data[1] |= (sw_settings->input_opt[1] & FF_SWPARAM_INPUT_OPT_B) ? CR1_INPUT_OPT1_B : 0;
329     data[1] |= (sw_settings->input_opt[2] & FF_SWPARAM_INPUT_OPT_A) ? CR1_INPUT_OPT2_A : 0;
330     data[1] |= (sw_settings->input_opt[2] & FF_SWPARAM_INPUT_OPT_B) ? CR1_INPUT_OPT2_B : 0;
331
332     // Drive the speaker emulation / filter LED via FPGA in FF800.  In FF400
333     // the same bit controls the channel 4 "instrument" option.
334     if (m_rme_model == RME_MODEL_FIREFACE800) {
335         data[0] |= (sw_settings->filter) ? CR0_FF800_FILTER_FPGA : 0;
336     } else {
337         data[0] |= (sw_settings->ff400_instr_input[1]) ? CR0_FF400_CH4_INSTR : 0;
338     }
339
340     // Set the "rear" option for input 0 if selected
341     data[1] |= (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_REAR) ? CR1_FF800_INPUT1_REAR : 0;
342
343     // The input 0 "front" option is activated using one of two bits
344     // depending on whether the filter (aka "speaker emulation") setting is
345     // active.
346     if (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_FRONT) {
347         data[1] |= (sw_settings->filter) ? CR1_FF800_INPUT1_FRONT_WITH_FILTER : CR1_FF800_INPUT1_FRONT;
348     }
349
350     data[2] |= (sw_settings->spdif_output_emphasis==FF_SWPARAM_SPDIF_OUTPUT_EMPHASIS_ON) ? CR2_SPDIF_OUT_EMP : 0;
351     data[2] |= (sw_settings->spdif_output_pro==FF_SWPARAM_SPDIF_OUTPUT_PRO_ON) ? CR2_SPDIF_OUT_PRO : 0;
352     data[2] |= (sw_settings->spdif_output_nonaudio==FF_SWPARAM_SPDIF_OUTPUT_NONAUDIO_ON) ? CR2_SPDIF_OUT_NONAUDIO : 0;
353     data[2] |= (sw_settings->spdif_output_mode==FF_SWPARAM_SPDIF_OUTPUT_OPTICAL) ? CR2_SPDIF_OUT_ADAT2 : 0;
354     data[2] |= (sw_settings->clock_mode==FF_SWPARAM_CLOCK_MODE_AUTOSYNC) ? CR2_CLOCKMODE_AUTOSYNC : CR2_CLOCKMODE_MASTER;
355     data[2] |= (sw_settings->spdif_input_mode==FF_SWPARAM_SPDIF_INPUT_COAX) ? CR2_SPDIF_IN_COAX : CR2_SPDIF_IN_ADAT2;
356     data[2] |= (sw_settings->word_clock_single_speed=FF_SWPARAM_WORD_CLOCK_1x) ? CR2_WORD_CLOCK_1x : 0;
357
358     /* TMS / TCO toggle bits in CR2 are not set by other drivers */
359
360     /* Drive / fuzz in FF800.  In FF400, the CR0 bit used by "Drive" controls
361      * the channel 3 "instrument" option.
362      */
363     if (m_rme_model == RME_MODEL_FIREFACE800) {
364         if (sw_settings->fuzz)
365             data[0] |= CR0_FF800_DRIVE_FPGA; // FPGA LED control
366         else
367             data[1] |= CR1_INSTR_DRIVE;      // CPLD
368     } else {
369         data[0] |= (sw_settings->ff400_instr_input[0]) ? CR0_FF400_CH3_INSTR : 0;
370     }
371
372     /* Drop-and-stop is hardwired on in other drivers */
373     data[2] |= CR2_DROP_AND_STOP;
374
375     if (m_rme_model == RME_MODEL_FIREFACE400) {
376         data[2] |= CR2_FF400_BIT;
377     }
378
379     switch (sw_settings->sync_ref) {
380         case FF_SWPARAM_SYNCREF_WORDCLOCK:
381             data[2] |= CR2_SYNC_WORDCLOCK;
382             break;
383         case FF_SWPARAM_SYNCREF_ADAT1:
384             data[2] |= CR2_SYNC_ADAT1;
385             break;
386         case FF_SWPARAM_SYNCREF_ADAT2:
387             data[2] |= CR2_SYNC_ADAT2;
388             break;
389         case FF_SWPARAM_SYNCREF_SPDIF:
390             data[2] |= CR2_SYNC_SPDIF;
391             break;
392         case FF_SWPARAM_SYNCREC_TCO:
393             data[2] |= CR2_SYNC_TCO;
394             break;
395     }
396
397     // This is hardwired in other drivers
398     data[2] |= (CR2_FREQ0 + CR2_FREQ1 + CR2_DSPEED + CR2_QSSPEED);
399
400     // The FF800 limiter applies to the front panel instrument input, so it
401     // only makes sense that it is disabled when that input is in use.
402     data[2] |= (sw_settings->limiter_disable &&
403                 (sw_settings->input_opt[0] & FF_SWPARAM_FF800_INPUT_OPT_FRONT)) ?
404                 CR2_DISABLE_LIMITER : 0;
405
406 //This is just for testing - it's a known consistent configuration
407 //data[0] = 0x00020810;      // Phantom off
408 //data[0] = 0x00020811;      // Phantom on
409 //data[1] = 0x0000031e;
410 //data[2] = 0xc400101f;
411     debugOutput(DEBUG_LEVEL_VERBOSE, "set hardware registers: 0x%08x 0x%08x 0x%08x\n",
412       data[0], data[1], data[2]);
413
414     conf_reg = (m_rme_model==RME_MODEL_FIREFACE800)?RME_FF800_CONF_REG:RME_FF400_CONF_REG;
415     if (writeBlock(conf_reg, data, 3) != 0)
416         return -1;
417
418     return 0;
419 }
420
421 signed int
422 Device::read_tco(quadlet_t *tco_data, signed int size)
423 {
424     // Read the TCO registers and return the respective values in *tco_data.
425     // Return value is 0 on success, or -1 if there is no TCO present.
426     // "size" is the size (in quadlets) of the array pointed to by tco_data.
427     // To obtain all TCO data "size" should be at least 4.  If the caller
428     // doesn't care about the data returned by the TCO, tco_data can be
429     // NULL.
430     quadlet_t buf[4];
431     signed int i;
432
433     // The Fireface 400 can't have the TCO fitted
434     if (m_rme_model==RME_MODEL_FIREFACE400)
435         return -1;
436
437     if (readBlock(RME_FF_TCO_READ_REG, buf, 4) != 0)
438         return -1;
439
440     if (tco_data != NULL) {
441         for (i=0; i<(size<4)?size:4; i++)
442             tco_data[i] = buf[i];
443     }
444
445     if ( (buf[0] & 0x80808080) == 0x80808080 &&
446          (buf[1] & 0x80808080) == 0x80808080 &&
447          (buf[2] & 0x80808080) == 0x80808080 &&
448          (buf[3] & 0x8000FFFF) == 0x80008000) {
449         // A TCO is present
450         return 0;
451     }
452
453     return -1;
454 }
455
456 signed int
457 Device::write_tco(quadlet_t *tco_data, signed int size)
458 {
459     // Writes data to the TCO.  No check is made as to whether a TCO is
460     // present in the current device.  Return value is 0 on success or -1 on
461     // error.  "size" is the size (in quadlets) of the data pointed to by
462     // "tco_data".  The first 4 quadlets of tco_data are significant; all
463     // others are ignored.  If fewer than 4 quadlets are supplied (as
464     // indicated by the "size" parameter, -1 will be returned.
465     if (size < 4)
466         return -1;
467
468     // Don't bother trying to write if the device is a FF400 since the TCO
469     // can't be fitted to this device.
470     if (m_rme_model==RME_MODEL_FIREFACE400)
471         return -1;
472
473     if (writeBlock(RME_FF_TCO_WRITE_REG, tco_data, 4) != 0)
474         return -1;
475
476     return 0;
477 }
478
479 signed int
480 Device::hardware_is_streaming(void)
481 {
482     // Return 1 if the hardware is streaming, 0 if not.
483     return dev_config->is_streaming;
484 }
485
486 signed int
487 Device::read_tco_state(FF_TCO_state_t *tco_state)
488 {
489     // Reads the current TCO state into the supplied state structure
490
491     quadlet_t tc[4];
492     unsigned int PLL_phase;
493
494     if (read_tco(tc, 4) != 0)
495       return -1;
496
497     // The timecode is stored in BCD (binary coded decimal) in register 0.
498     tco_state->frames = (tc[0] & 0xf) + ((tc[0] & 0x30) >> 4)*10;
499     tco_state->seconds = ((tc[0] & 0xf00) >> 8) + ((tc[0] & 0x7000) >> 12)*10;
500     tco_state->minutes = ((tc[0] & 0xf0000) >> 16) + ((tc[0] & 0x700000) >> 20)*10;
501     tco_state->hours = ((tc[0] & 0xf000000) >> 24) + ((tc[0] & 0x30000000) >> 28)*10;
502
503     tco_state->locked = (tc[1] & FF_TCO1_TCO_lock) != 0;
504     tco_state->ltc_valid = (tc[1] & FF_TCO1_LTC_INPUT_VALID) != 0;
505
506     switch (tc[1] & FF_TCO1_LTC_FORMAT_MASK) {
507         case FF_TC01_LTC_FORMAT_24fps:
508           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_24fps; break;
509         case FF_TCO1_LTC_FORMAT_25fps:
510           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_25fps; break;
511         case FF_TC01_LTC_FORMAT_29_97fps:
512           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_29_97fps; break;
513         case FF_TCO1_LTC_FORMAT_30fps:
514           tco_state->frame_rate = FF_TCOSTATE_FRAMERATE_30fps; break;
515     }
516
517     tco_state->drop_frame = (tc[1] & FF_TCO1_SET_DROPFRAME) != 0;
518
519     switch (tc[1] & FF_TCO1_VIDEO_INPUT_MASK) {
520         case FF_TCO1_VIDEO_INPUT_NTSC:
521             tco_state->video_input = FF_TCOSTATE_VIDEO_NTSC; break;
522         case FF_TCO1_VIDEO_INPUT_PAL:
523             tco_state->video_input = FF_TCOSTATE_VIDEO_PAL; break;
524         default:
525             tco_state->video_input = FF_TCOSTATE_VIDEO_NONE;
526     }
527
528     if ((tc[1] & FF_TCO1_WORD_CLOCK_INPUT_VALID) == 0) {
529         tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_NONE;
530     } else {
531         switch (tc[1] & FF_TCO1_WORD_CLOCK_INPUT_MASK) {
532             case FF_TCO1_WORD_CLOCK_INPUT_1x:
533                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_1x; break;
534             case FF_TCO1_WORD_CLOCK_INPUT_2x:
535                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_2x; break;
536             case FF_TCO1_WORD_CLOCK_INPUT_4x:
537                 tco_state->word_clock_state = FF_TCOSTATE_WORDCLOCK_4x; break;
538         }
539     }
540
541     PLL_phase = (tc[2] & 0x7f) + ((tc[2] & 0x7f00) >> 1);
542     tco_state->sample_rate = (25000000.0 * 16.0)/PLL_phase;
543
544     return 0;
545 }
546
547 signed int
548 Device::write_tco_settings(FF_TCO_settings_t *tco_settings)
549 {
550     // Writes the supplied application-level settings to the device's TCO
551     // (Time Code Option).  Don't bother doing anything if the device doesn't
552     // have a TCO fitted.  Returns 0 on success, -1 on error.
553
554     quadlet_t tc[4] = {0, 0, 0, 0};
555
556     if (!dev_config->tco_present) {
557         return -1;
558     }
559
560     if (tco_settings->MTC)
561         tc[0] |= FF_TCO0_MTC;
562
563     switch (tco_settings->input) {
564         case FF_TCOPARAM_INPUT_LTC:
565             tc[2] |= FF_TCO2_INPUT_LTC; break;
566         case FF_TCOPARAM_INPUT_VIDEO:
567             tc[2] |= FF_TCO2_INPUT_VIDEO; break;
568         case FF_TCOPARAM_INPUT_WCK:
569             tc[2] |= FF_TCO2_INPUT_WORD_CLOCK; break;
570     }
571
572     switch (tco_settings->frame_rate) {
573         case FF_TCOPARAM_FRAMERATE_24fps:
574             tc[1] |= FF_TC01_LTC_FORMAT_24fps; break;
575         case FF_TCOPARAM_FRAMERATE_25fps:
576             tc[1] |= FF_TCO1_LTC_FORMAT_25fps; break;
577         case FF_TCOPARAM_FRAMERATE_29_97fps:
578             tc[1] |= FF_TC01_LTC_FORMAT_29_97fps; break;
579         case FF_TCOPARAM_FRAMERATE_29_97dfps:
580             tc[1] |= FF_TCO1_LTC_FORMAT_29_97dpfs; break;
581         case FF_TCOPARAM_FRAMERATE_30fps:
582             tc[1] |= FF_TCO1_LTC_FORMAT_30fps; break;
583         case FF_TCOPARAM_FRAMERATE_30dfps:
584             tc[1] |= FF_TCO1_LTC_FORMAT_30dfps; break;
585     }
586
587     switch (tco_settings->word_clock) {
588         case FF_TCOPARAM_WORD_CLOCK_CONV_1_1:
589             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_1_1; break;
590         case FF_TCOPARAM_WORD_CLOCK_CONV_44_48:
591             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_44_48; break;
592         case FF_TCOPARAM_WORD_CLOCK_CONV_48_44:
593             tc[2] |= FF_TCO2_WORD_CLOCK_CONV_48_44; break;
594     }
595
596     switch (tco_settings->sample_rate) {
597         case FF_TCOPARAM_SRATE_44_1:
598             tc[2] |= FF_TCO2_SRATE_44_1; break;
599         case FF_TCOPARAM_SRATE_48:
600             tc[2] |= FF_TCO2_SRATE_48; break;
601         case FF_TCOPARAM_SRATE_FROM_APP:
602             tc[2] |= FF_TCO2_SRATE_FROM_APP; break;
603     }
604
605     switch (tco_settings->pull) {
606         case FF_TCPPARAM_PULL_NONE:
607             tc[2] |= FF_TCO2_PULL_0; break;
608         case FF_TCOPARAM_PULL_UP_01:
609             tc[2] |= FF_TCO2_PULL_UP_01; break;
610         case FF_TCOPARAM_PULL_DOWN_01:
611             tc[2] |= FF_TCO2_PULL_DOWN_01; break;
612         case FF_TCOPARAM_PULL_UP_40:
613             tc[2] |= FF_TCO2_PULL_UP_40; break;
614         case FF_TCOPARAM_PULL_DOWN_40:
615             tc[2] |= FF_TCO2_PULL_DOWN_40; break;
616     }
617
618     if (tco_settings->termination == FF_TCOPARAM_TERMINATION_ON)
619         tc[2] |= FF_TCO2_SET_TERMINATION;
620
621     return write_tco(tc, 4);
622 }
623
624 signed int
625 Device::set_hardware_dds_freq(signed int freq)
626 {
627     // Set the device's DDS to the given frequency (which in turn determines
628     // the sampling frequency).  Returns 0 on success, -1 on error.
629
630     unsigned int ret = 0;
631
632     if (freq < MIN_SPEED || freq > MAX_SPEED)
633         return -1;
634
635     if (m_rme_model == RME_MODEL_FIREFACE400)
636         ret = writeRegister(RME_FF400_STREAM_SRATE, freq);
637     else
638         ret = writeRegister(RME_FF800_STREAM_SRATE, freq);
639
640     if (ret == 0)
641         dev_config->hardware_freq = freq;
642
643     return ret;
644 }
645
646 signed int
647 Device::hardware_init_streaming(unsigned int sample_rate,
648     unsigned int tx_channel)
649 {
650     // tx_channel is the ISO channel the PC will transmit on.
651     quadlet_t buf[5];
652     fb_nodeaddr_t addr;
653     unsigned int size;
654
655 debugOutput(DEBUG_LEVEL_VERBOSE, "*** stream init: %d, %d, %d\n",
656   sample_rate, num_channels, tx_channel);
657
658     buf[0] = sample_rate;
659     buf[1] = (num_channels << 11) + tx_channel;
660     buf[2] = num_channels;
661     buf[3] = 0;
662     buf[4] = 0;
663     if (speed800) {
664         buf[2] |= RME_FF800_STREAMING_SPEED_800;
665     }
666
667     if (m_rme_model == RME_MODEL_FIREFACE400) {
668         addr = RME_FF400_STREAM_INIT_REG;
669         size = RME_FF400_STREAM_INIT_SIZE;
670     } else {
671         addr = RME_FF800_STREAM_INIT_REG;
672         size = RME_FF800_STREAM_INIT_SIZE;
673     }
674
675 {signed int i;
676   printf("addr %016llx\n", addr);
677   for (i=0; i<5; i++)
678     printf("0x%08x ", buf[i]);
679   printf("\n");
680 }
681
682     return writeBlock(addr, buf, size);
683 }
684
685 signed int
686 Device::hardware_start_streaming(unsigned int listen_channel)
687 {
688     signed int ret = 0;
689     // Listen_channel is the ISO channel the PC will listen on for data sent
690     // by the Fireface.
691     fb_nodeaddr_t addr;
692     quadlet_t data = num_channels;
693
694     config_lock();
695     if (not(hardware_is_streaming())) {
696 debugOutput(DEBUG_LEVEL_VERBOSE,"*** starting: listen=%d, num_ch=%d\n", listen_channel, num_channels);
697         if (m_rme_model == RME_MODEL_FIREFACE400) {
698             addr = RME_FF400_STREAM_START_REG;
699             data |= (listen_channel << 5);
700         } else {
701             addr = RME_FF800_STREAM_START_REG;
702             if (speed800)
703                 data |= RME_FF800_STREAMING_SPEED_800; // Flag 800 Mbps speed
704         }
705
706 printf("start 0x%016llx data: %08x\n", addr, data);
707         ret = writeRegister(addr, data);
708         if (ret == 0) {
709             dev_config->is_streaming = 1;
710         }
711     } else
712         ret = -1;
713     config_unlock();
714
715     return ret;
716 }
717
718 signed int
719 Device::hardware_stop_streaming(void)
720 {
721     fb_nodeaddr_t addr;
722     quadlet_t buf[4] = {0, 0, 0, 1};
723     unsigned int size, ret = 0;
724
725     config_lock();
726     if (hardware_is_streaming()) {
727         if (m_rme_model == RME_MODEL_FIREFACE400) {
728             addr = RME_FF400_STREAM_END_REG;
729             size = RME_FF400_STREAM_END_SIZE;
730         } else {
731             addr = RME_FF800_STREAM_END_REG;
732             size = RME_FF800_STREAM_END_SIZE;
733         }
734
735         ret = writeBlock(addr, buf, size);
736         if (ret == 0) {
737             dev_config->is_streaming = 0;
738         }
739     } else
740         ret = -1;
741     config_unlock();
742
743     return ret;
744 }
745
746 signed int
747 Device::set_hardware_ampgain(unsigned int index, signed int val) {
748 // "val" is in dB except for inputs 3/4 where it's in units of 0.5 dB. This
749 // function is responsible for converting to/from the scale used by the
750 // device.
751     quadlet_t regval = 0;
752     signed int devval = 0;
753     if (index <= FF400_AMPGAIN_MIC2) {
754         if (val >= 10)
755             devval = val;
756         else
757             devval = 0;
758     } else
759     if (index <= FF400_AMPGAIN_INPUT4) {
760         devval = val;
761     } else {
762         devval = 6 - val;
763         if (devval > 53)
764             devval = 0x3f;  // Mute
765     }
766     regval |= devval;
767     regval |= (index << 16);
768     return writeRegister(RME_FF400_GAIN_REG, regval);
769 }
770
771 }
Note: See TracBrowser for help on using the browser.