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

Revision 2651, 28.2 kB (checked in by jwoithe, 7 years ago)

Fix some warnings emitted by recent versions of gcc. These are mostly connected with printf format strings: spaces are now required between string literals and PR* format macros. Patch from Xavier Forestier.

Line 
1 /*
2  * Copyright (C) 2009-2013 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 the flash memory methods of the Device object */
25
26 #include <unistd.h>
27 #include <math.h>
28 #include "rme/rme_avdevice.h"
29 #include "rme/fireface_def.h"
30
31 #include "debugmodule/debugmodule.h"
32
33 #define MAX_FLASH_BUSY_RETRIES    25
34
35 namespace Rme {
36
37 signed int
38 Device::wait_while_busy(unsigned int init_delay_ms)
39 {
40     signed int i;
41     quadlet_t status;
42
43     // Wait for the device to become available for a new command.  A delay
44     // of init_delay_ms is executed prior to each test of the device status.
45     for (i=0; i<MAX_FLASH_BUSY_RETRIES; i++) {
46         usleep(init_delay_ms*1000);
47         if (m_rme_model == RME_MODEL_FIREFACE400) {
48             status = readRegister(RME_FF400_FLASH_STAT_REG);
49             if (status == 0)
50                 break;
51         } else
52         if (m_rme_model == RME_MODEL_FIREFACE800) {
53             status = readRegister(RME_FF_STATUS_REG1);
54             if (status & 0x40000000)
55                 break;
56         } else {
57             debugOutput(DEBUG_LEVEL_ERROR, "unimplemented model %d\n", m_rme_model);
58             return -1;
59         }
60     }
61
62     if (i == MAX_FLASH_BUSY_RETRIES)
63         return -1;
64     return 0;
65 }
66
67 signed int
68 Device::get_revision(unsigned int *revision)
69 {
70     signed int err = 0;
71
72     if (m_rme_model == RME_MODEL_FIREFACE800) {
73         *revision = readRegister(RME_FF800_REVISION_REG);
74         return 0;
75     }
76
77     err = writeRegister(RME_FF400_FLASH_CMD_REG, RME_FF400_FLASH_CMD_GET_REVISION);
78     err |= wait_while_busy(2);
79     if (!err)
80       *revision = readRegister(RME_FF400_FLASH_READ_BUFFER);
81
82     return err?-1:0;
83 }
84
85 signed int
86 Device::read_flash(fb_nodeaddr_t addr, quadlet_t *buf, unsigned int n_quads)
87 {
88     // Read "n_quads" quadlets from the Fireface Flash starting at address
89     // addr.  The result is written to "buf" which is assumed big enough to
90     // hold the result.  Return 0 on success, -1 on error.  The caller must ensure
91     // that the flash source address makes sense for the device in use.
92
93     unsigned int xfer_size;
94     unsigned int err = 0;
95     quadlet_t block_desc[2];
96     quadlet_t ff400_addr = (addr & 0xffffffff);
97
98     if (m_rme_model == RME_MODEL_FIREFACE800) {
99         do {
100             xfer_size = (n_quads > RME_FF_FLASH_SECTOR_SIZE_QUADS)?RME_FF_FLASH_SECTOR_SIZE_QUADS:n_quads;
101             err |= readBlock(addr, buf, xfer_size);
102             n_quads -= xfer_size;
103             buf += xfer_size;
104             addr += xfer_size*sizeof(quadlet_t);
105         } while (n_quads>0 && !err);
106     } else {
107         // FF400 case follows
108         do {
109             xfer_size = (n_quads > 32)?32:n_quads;
110             block_desc[0] = ff400_addr;
111             block_desc[1] = xfer_size * sizeof(quadlet_t);
112             // Program the read address and size
113             err |= writeBlock(RME_FF400_FLASH_BLOCK_ADDR_REG, block_desc, 2);
114             // Execute the read and wait for its completion
115             err |= writeRegister(RME_FF400_FLASH_CMD_REG, RME_FF400_FLASH_CMD_READ);
116            if (!err)
117                wait_while_busy(2);
118             // Read from bounce buffer into final destination
119             err |= readBlock(RME_FF400_FLASH_READ_BUFFER, buf, xfer_size);
120
121             n_quads -= xfer_size;
122             ff400_addr += xfer_size*sizeof(quadlet_t);
123             buf += xfer_size;
124         } while (n_quads>0 && !err);
125     }
126
127     return err?-1:0;
128 }
129
130 signed int
131 Device::erase_flash(unsigned int flags)
132 {
133     // Erase the requested flash block.  "flags" should be one of the
134     // RME_FF_FLASH_ERASE_* flags.  Return 0 on success, -1 on error.
135
136     fb_nodeaddr_t addr;
137     quadlet_t data;
138     unsigned int err = 0;
139
140     if (m_rme_model == RME_MODEL_FIREFACE800) {
141         switch (flags) {
142             case RME_FF_FLASH_ERASE_VOLUME:
143                 addr = RME_FF800_FLASH_ERASE_VOLUME_REG; break;
144             case RME_FF_FLASH_ERASE_SETTINGS:
145                 addr = RME_FF800_FLASH_ERASE_SETTINGS_REG; break;
146             case RME_FF_FLASH_ERASE_CONFIG:
147                 addr = RME_FF800_FLASH_ERASE_CONFIG_REG; break;
148             default:
149                 debugOutput(DEBUG_LEVEL_WARNING, "unknown flag %d\n", flags);
150                 return -1;
151         }
152         data = 0;
153     } else
154     if (m_rme_model == RME_MODEL_FIREFACE400) {
155         addr = RME_FF400_FLASH_CMD_REG;
156         switch (flags) {
157             case RME_FF_FLASH_ERASE_VOLUME:
158                 data = RME_FF400_FLASH_CMD_ERASE_VOLUME; break;
159             case RME_FF_FLASH_ERASE_SETTINGS:
160                 data = RME_FF400_FLASH_CMD_ERASE_SETTINGS; break;
161             case RME_FF_FLASH_ERASE_CONFIG:
162                 data = RME_FF400_FLASH_CMD_ERASE_CONFIG; break;
163             default:
164                 debugOutput(DEBUG_LEVEL_WARNING, "unknown flag %d\n", flags);
165                 return -1;
166         }
167     } else {
168         debugOutput(DEBUG_LEVEL_ERROR, "unimplemented model %d\n", m_rme_model);
169         return -1;
170     }
171
172     err |= writeRegister(addr, data);
173     if (!err) {
174         wait_while_busy(500);
175         // After the device is ready, wait a further 20 milliseconds.  The purpose
176         // of this is unclear.  Drivers from other OSes do it, so we should too.
177         usleep(20000);
178     }
179
180     return err?-1:0;
181 }
182
183 signed int
184 Device::write_flash(fb_nodeaddr_t addr, quadlet_t *buf, unsigned int n_quads)
185 {
186     // Write "n_quads" quadlets to the Fireface Flash starting at address
187     // addr.  Return 0 on success, -1 on error.  The caller must ensure the
188     // supplied address is appropriate for the device in use.
189
190     unsigned int xfer_size;
191     unsigned int err = 0;
192     quadlet_t block_desc[2];
193     quadlet_t ff400_addr = (addr & 0xffffffff);
194
195     if (m_rme_model == RME_MODEL_FIREFACE800) {
196         do {
197             xfer_size = (n_quads > RME_FF_FLASH_SECTOR_SIZE_QUADS)?RME_FF_FLASH_SECTOR_SIZE_QUADS:n_quads;
198             err |= writeBlock(addr, buf, xfer_size);
199             if (!err) {
200                 err = wait_while_busy(5) != 0;
201                 if (err)
202                     debugOutput(DEBUG_LEVEL_WARNING, "device still busy after flash write\n");
203             } else
204                 debugOutput(DEBUG_LEVEL_WARNING, "flash writeBlock() failed\n");
205             n_quads -= xfer_size;
206             buf += xfer_size;
207             addr += xfer_size*sizeof(quadlet_t);
208         } while (n_quads>0 && !err);
209         return err?-1:0;
210     }
211
212     // FF400 case follows
213     do {
214         xfer_size = (n_quads > 32)?32:n_quads;
215         // Send data to flash buffer
216         err |= writeBlock(RME_FF400_FLASH_WRITE_BUFFER, buf, xfer_size);
217         // Program the destination address and size
218         block_desc[0] = ff400_addr;
219         block_desc[1] = xfer_size * sizeof(quadlet_t);
220         err |= writeBlock(RME_FF400_FLASH_BLOCK_ADDR_REG, block_desc, 2);
221         // Execute the write and wait for its completion
222         err |= writeRegister(RME_FF400_FLASH_CMD_REG, RME_FF400_FLASH_CMD_WRITE);
223         if (!err)
224             wait_while_busy(2);
225
226         n_quads -= xfer_size;
227         ff400_addr += xfer_size*sizeof(quadlet_t);
228         buf += xfer_size;
229     } while (n_quads>0 && !err);
230
231     return err?-1:0;
232 }
233
234
235 signed int
236 Device::read_device_flash_settings(FF_software_settings_t *dsettings)
237 {
238     // Note: this function does NOT copy the newly read settings into
239     // the hardware registers even if reading into the device's master
240     // settings structure (ie: when dsettings is NULL).  If the settings
241     // read from flash are to be made active the caller must take
242     // care of this (by calling set_hardware_params() for instance).
243
244     if (dsettings == NULL)
245         dsettings = settings;
246
247     // Read the device's configuration flash RAM and use this to set up
248     // the given settings structure.
249
250     FF_device_flash_settings_t hw_settings;
251     signed int i, err = 0;
252     unsigned int rev;
253     long long int addr;
254     quadlet_t status_buf[4];
255
256     i = get_revision(&rev);
257     if (i != 0) {
258         debugOutput(DEBUG_LEVEL_WARNING, "Error reading hardware revision: %d\n", i);
259     } else {
260         debugOutput(DEBUG_LEVEL_VERBOSE, "Hardware revision: 0x%08x\n", rev);
261     }
262
263     // Read settings flash ram block
264     if (m_rme_model == RME_MODEL_FIREFACE800)
265         addr = RME_FF800_FLASH_SETTINGS_ADDR;
266     else
267     if (m_rme_model == RME_MODEL_FIREFACE400)
268         addr = RME_FF400_FLASH_SETTINGS_ADDR;
269     else {
270         debugOutput(DEBUG_LEVEL_ERROR, "unimplemented model %d\n", m_rme_model);
271         return -1;
272     }
273     err = read_flash(addr,
274             (quadlet_t *)&hw_settings, sizeof(hw_settings)/sizeof(uint32_t));
275
276     if (err != 0) {
277         debugOutput(DEBUG_LEVEL_WARNING, "Error reading device flash settings: %d\n", i);
278         return -1;
279     }
280
281     debugOutput(DEBUG_LEVEL_VERBOSE, "Device flash settings:\n");
282     if (hw_settings.clock_mode == FF_DEV_FLASH_INVALID) {
283         debugOutput(DEBUG_LEVEL_VERBOSE, "  Clock mode: not set in device flash\n");
284     } else {
285         debugOutput(DEBUG_LEVEL_VERBOSE, "  Clock mode: %s\n",
286           hw_settings.clock_mode==FF_DEV_FLASH_CLOCK_MODE_MASTER?"Master":"Slave");
287     }
288     if (hw_settings.sample_rate == FF_DEV_FLASH_INVALID) {
289         debugOutput(DEBUG_LEVEL_VERBOSE, "  Sample rate: not set in device flash\n");
290     } else
291     if (hw_settings.sample_rate == FF_DEV_FLASH_SRATE_DDS_INACTIVE) {
292         debugOutput(DEBUG_LEVEL_VERBOSE, "  Sample rate: DDS not active\n");
293     } else {
294         debugOutput(DEBUG_LEVEL_VERBOSE, "  Sample rate: %d Hz (DDS active)\n", hw_settings.sample_rate);
295     }
296
297     // Sanity check the "limit_bandwidth" setting since it has been observed
298     // to take on bogus values for some users.  The reason behind the
299     // unexpected values is currently unknown.  Note that limit_bandwidth is
300     // unsigned, so there's no need to check for values less than 0.
301     if (hw_settings.limit_bandwidth > FF_DEV_FLASH_BWLIMIT_ANALOG_ONLY) {
302         debugOutput(DEBUG_LEVEL_WARNING, "bogus firewire bandwidth limit flag 0x%08x reset to 0 (send all channels)\n",
303           hw_settings.limit_bandwidth);
304         hw_settings.limit_bandwidth = FF_DEV_FLASH_BWLIMIT_SEND_ALL_CHANNELS;
305     }
306
307     if (dsettings != NULL) {
308         memset(dsettings, 0, sizeof(*dsettings));
309         // Copy hardware details to the software settings structure as
310         // appropriate.
311         for (i=0; i<2; i++)
312             dsettings->mic_phantom[i] = hw_settings.mic_phantom[i];
313
314         if (m_rme_model == RME_MODEL_FIREFACE800) {
315             for (i=2; i<4; i++)
316                 dsettings->mic_phantom[i] = hw_settings.mic_phantom[i];
317         } else
318         if (m_rme_model == RME_MODEL_FIREFACE400) {
319             // TODO: confirm this is true
320             for (i=2; i<4; i++)
321                 dsettings->ff400_input_pad[i-2] = hw_settings.mic_phantom[i];
322         } else {
323             debugOutput(DEBUG_LEVEL_ERROR, "unimplemented model %d\n", m_rme_model);
324             return -1;
325         }
326
327         dsettings->spdif_input_mode = hw_settings.spdif_input_mode;
328         dsettings->spdif_output_emphasis = hw_settings.spdif_output_emphasis;
329         dsettings->spdif_output_pro = hw_settings.spdif_output_pro;
330         dsettings->spdif_output_nonaudio = hw_settings.spdif_output_nonaudio;
331         dsettings->spdif_output_mode = hw_settings.spdif_output_mode;
332         dsettings->clock_mode = hw_settings.clock_mode;
333         dsettings->sync_ref = hw_settings.sync_ref;
334         dsettings->tms = hw_settings.tms;
335         dsettings->limit_bandwidth = hw_settings.limit_bandwidth;
336         dsettings->stop_on_dropout = hw_settings.stop_on_dropout;
337         dsettings->input_level = hw_settings.input_level;
338         dsettings->output_level = hw_settings.output_level;
339         if (m_rme_model == RME_MODEL_FIREFACE800) {
340             dsettings->filter = hw_settings.filter;
341             dsettings->fuzz = hw_settings.fuzz;
342         } else
343         if (m_rme_model == RME_MODEL_FIREFACE400) {
344             // TODO: confirm this is true
345             dsettings->ff400_instr_input[0] = hw_settings.fuzz;
346             dsettings->ff400_instr_input[1] = hw_settings.filter;
347         }
348         dsettings->limiter = (hw_settings.p12db_an[0] == 0)?1:0;
349         dsettings->sample_rate = hw_settings.sample_rate;
350         dsettings->word_clock_single_speed = hw_settings.word_clock_single_speed;
351
352         // The FF800 has front/rear selectors for the "instrument" input
353         // (aka channel 1) and the two "mic" channels (aka channels 7 and 8).
354         // The FF400 does not.  The FF400 borrows the mic0 selector field
355         // in the flash configuration structure to use for the "phones"
356         // level which the FF800 doesn't have.
357         if (m_rme_model == RME_MODEL_FIREFACE400)
358             dsettings->phones_level = hw_settings.mic_plug_select[0];
359         else
360         if (m_rme_model == RME_MODEL_FIREFACE800) {
361             // The value for the front/rear selectors coming from the flash
362             // is an indexed value: 0=rear, 1=front, 2=front and rear.  By
363             // adding one to this we can treat input_opt as a bitmask with
364             // bit 0 being "rear" and bit 1 being "front".  This follows the
365             // approach used in drivers for other operating systems and
366             // simplifies certain logic expressions within the driver.
367             dsettings->input_opt[0] = hw_settings.instrument_plug_select + 1;
368             dsettings->input_opt[1] = hw_settings.mic_plug_select[0] + 1;
369             dsettings->input_opt[2] = hw_settings.mic_plug_select[1] + 1;
370         }
371
372         /* If debug is enabled, show what's been read from the flash */
373         debugOutput(DEBUG_LEVEL_VERBOSE, "Settings acquired from flash:\n");
374         if (m_rme_model == RME_MODEL_FIREFACE800) {
375             debugOutput(DEBUG_LEVEL_VERBOSE, "  Phantom: %d %d %d %d\n",
376                 dsettings->mic_phantom[0], dsettings->mic_phantom[1],
377                 dsettings->mic_phantom[2], dsettings->mic_phantom[2]);
378
379         } else
380         if (m_rme_model == RME_MODEL_FIREFACE400) {
381             debugOutput(DEBUG_LEVEL_VERBOSE, "  Phantom: %d %d\n",
382                 dsettings->mic_phantom[0], dsettings->mic_phantom[1]);
383             debugOutput(DEBUG_LEVEL_VERBOSE, "  Input pad: %d %d\n",
384                 dsettings->ff400_input_pad[0], dsettings->ff400_input_pad[1]);
385         }
386         debugOutput(DEBUG_LEVEL_VERBOSE, "  spdif input mode: %d\n", dsettings->spdif_input_mode);
387         debugOutput(DEBUG_LEVEL_VERBOSE, "  spdif output emphasis: %d\n", dsettings->spdif_output_emphasis);
388         debugOutput(DEBUG_LEVEL_VERBOSE, "  spdif output pro: %d\n", dsettings->spdif_output_pro);
389         debugOutput(DEBUG_LEVEL_VERBOSE, "  spdif output nonaudio: %d\n", dsettings->spdif_output_nonaudio);
390         debugOutput(DEBUG_LEVEL_VERBOSE, "  spdif output mode: %d\n", dsettings->spdif_output_mode);
391         debugOutput(DEBUG_LEVEL_VERBOSE, "  clock mode: %d\n", dsettings->clock_mode);
392         debugOutput(DEBUG_LEVEL_VERBOSE, "  sync ref: %d\n", dsettings->sync_ref);
393         debugOutput(DEBUG_LEVEL_VERBOSE, "  tms: %d\n", dsettings->tms);
394         debugOutput(DEBUG_LEVEL_VERBOSE, "  limit firewire bandwidth: %d\n", dsettings->limit_bandwidth);
395         debugOutput(DEBUG_LEVEL_VERBOSE, "  stop on dropout: %d\n", dsettings->stop_on_dropout);
396         debugOutput(DEBUG_LEVEL_VERBOSE, "  input level: %d\n", dsettings->input_level);
397         debugOutput(DEBUG_LEVEL_VERBOSE, "  output level: %d\n", dsettings->output_level);
398         if (m_rme_model == RME_MODEL_FIREFACE800) {
399             debugOutput(DEBUG_LEVEL_VERBOSE, "  filter: %d\n", dsettings->filter);
400             debugOutput(DEBUG_LEVEL_VERBOSE, "  fuzz: %d\n", dsettings->fuzz);
401         } else
402         if (m_rme_model == RME_MODEL_FIREFACE400) {
403             debugOutput(DEBUG_LEVEL_VERBOSE, "  instr input 0: %d\n", dsettings->ff400_instr_input[0]);
404             debugOutput(DEBUG_LEVEL_VERBOSE, "  instr input 1: %d\n", dsettings->ff400_instr_input[1]);
405         }
406         debugOutput(DEBUG_LEVEL_VERBOSE, "  limiter: %d\n", dsettings->limiter);
407         debugOutput(DEBUG_LEVEL_VERBOSE, "  sample rate: %d\n", dsettings->sample_rate);
408         debugOutput(DEBUG_LEVEL_VERBOSE, "  word clock single speed: %d\n", dsettings->word_clock_single_speed);
409         if (m_rme_model == RME_MODEL_FIREFACE400) {
410             debugOutput(DEBUG_LEVEL_VERBOSE, "  phones level: %d\n", dsettings->phones_level);
411         } else
412         if (m_rme_model == RME_MODEL_FIREFACE800) {
413             debugOutput(DEBUG_LEVEL_VERBOSE, "  input opts: %d %d %d\n",
414                 dsettings->input_opt[0], dsettings->input_opt[1],
415                 dsettings->input_opt[2]);
416         }
417     }
418
419     i = readBlock(RME_FF_STATUS_REG0, status_buf, 4);
420     debugOutput(DEBUG_LEVEL_VERBOSE, "Status read: %d: 0x%08x 0x%08x 0x%08x 0x%08x\n", i,
421         status_buf[0], status_buf[1], status_buf[2], status_buf[3]);
422
423     return err!=0?-1:0;
424 }
425
426 signed int
427 Device::write_device_flash_settings(FF_software_settings_t *dsettings)
428 {
429     if (dsettings == NULL)
430         dsettings = settings;
431
432     // Write the given device settings to the device's configuration flash.
433
434     FF_device_flash_settings_t hw_settings;
435     signed int i, err = 0;
436
437     if (dsettings == NULL) {
438         debugOutput(DEBUG_LEVEL_WARNING, "NULL settings parameter\n");
439         return -1;
440     }
441
442     memset(&hw_settings, 0, sizeof(hw_settings));
443
444     // Copy software settings to the hardware structure as appropriate.
445     for (i=0; i<4; i++)
446         hw_settings.mic_phantom[i] = dsettings->mic_phantom[i];
447     hw_settings.spdif_input_mode = dsettings->spdif_input_mode;
448     hw_settings.spdif_output_emphasis = dsettings->spdif_output_emphasis;
449     hw_settings.spdif_output_pro = dsettings->spdif_output_pro;
450     hw_settings.spdif_output_nonaudio = dsettings->spdif_output_nonaudio;
451     hw_settings.spdif_output_mode = dsettings->spdif_output_mode;
452     hw_settings.clock_mode = dsettings->clock_mode;
453     hw_settings.sync_ref = dsettings->sync_ref;
454     hw_settings.tms = dsettings->tms;
455     hw_settings.limit_bandwidth = dsettings->limit_bandwidth;
456     hw_settings.stop_on_dropout = dsettings->stop_on_dropout;
457     hw_settings.input_level = dsettings->input_level;
458     hw_settings.output_level = dsettings->output_level;
459     hw_settings.filter = dsettings->filter;
460     hw_settings.fuzz = dsettings->fuzz;
461     // The limiter can only be disabled if channel 1 uses the "front" input.
462     // Note that p12db_an (as passed to the flash) seems to be a "limiter
463     // disabled" flag.
464     if (m_rme_model==RME_MODEL_FIREFACE800 && dsettings->limiter==0 &&
465             dsettings->input_opt[0]==FF_SWPARAM_FF800_INPUT_OPT_FRONT)
466         hw_settings.p12db_an[0] = 1;
467     else
468         hw_settings.p12db_an[0] = 0;
469     hw_settings.sample_rate = dsettings->sample_rate;
470     hw_settings.word_clock_single_speed = dsettings->word_clock_single_speed;
471
472     // The FF800 has front/rear selectors for the "instrument" input
473     // (aka channel 1) and the two "mic" channels (aka channels 7 and 8).
474     // The FF400 does not.  The FF400 borrows the mic0 selector field
475     // in the flash configuration structure to use for the "phones"
476     // level which the FF800 doesn't have.
477     if (m_rme_model == RME_MODEL_FIREFACE400)
478         hw_settings.mic_plug_select[0] = dsettings->phones_level;
479     else
480     if (m_rme_model == RME_MODEL_FIREFACE800) {
481         // The offset of 1 follows the convention used internally in drivers
482         // for other operating systems.  It permits input_opt to be treated
483         // as a bitmask with bit 0 being "rear" and bit 1 being "front".
484         // In the flash, the corresponding value is the index of the active
485         // option in the list rear, front, front and rear.  See also the
486         // related section of read_device_flash_settings().
487         hw_settings.instrument_plug_select = dsettings->input_opt[0] - 1;
488         hw_settings.mic_plug_select[0] = dsettings->input_opt[1] - 1;
489         hw_settings.mic_plug_select[1] = dsettings->input_opt[2] - 1;
490     }
491
492     // The configuration flash block must be erased before we can write to it
493     err = erase_flash(RME_FF_FLASH_ERASE_SETTINGS) != 0;
494     if (err != 0)
495         debugOutput(DEBUG_LEVEL_WARNING, "Error erasing settings flash block: %d\n", i);
496     else {
497         long long int addr;
498         if (m_rme_model == RME_MODEL_FIREFACE800)
499             addr = RME_FF800_FLASH_SETTINGS_ADDR;
500         else
501         if (m_rme_model == RME_MODEL_FIREFACE400)
502             addr = RME_FF400_FLASH_SETTINGS_ADDR;
503         else {
504             debugOutput(DEBUG_LEVEL_ERROR, "unimplemented model %d\n", m_rme_model);
505             return -1;
506         }
507         err = write_flash(addr,
508                   (quadlet_t *)&hw_settings, sizeof(hw_settings)/sizeof(uint32_t));
509
510         if (err != 0)
511             debugOutput(DEBUG_LEVEL_WARNING, "Error writing device flash settings: %d\n", i);
512     }
513
514     return err!=0?-1:0;
515 }
516
517 static float
518 fader2flashvol(signed int fader)
519 {
520     return (1023.0/3) * log(fader*(exp(3.0)-1.0)/0x10000 + 1);
521 }
522
523 static float
524 flashvol2fader(signed int flash_vol)
525 {
526     // Map the 0 dB flash volume value explicitly to the corresponding
527     // fader value to avoid round-off effects.
528     if (flash_vol == RME_FF_FLASH_0DB_VOL_VALUE)
529       return 0x8000;
530     return 0x10000 * (exp(3.0*flash_vol/1023.0)-1) / (exp(3)-1.0);
531 }
532
533 static void
534 faders2flash(signed int fader0, signed int fader1, unsigned short int *flash_vol, unsigned short int *flash_pan)
535 {
536     signed int v = fader0 + fader1;
537     *flash_pan = 256.0 * fader1 / v;
538     *flash_vol = fader2flashvol(v);
539 }
540
541 static void
542 flash2faders(signed int flash_vol, signed int flash_pan, signed int *fader0, signed int *fader1)
543 {
544     float v = flashvol2fader(flash_vol);
545     *fader0 = v * (1 - flash_pan/256.0);
546     *fader1 = v * (flash_pan/256.0);
547 }
548
549 signed int
550 Device::read_device_mixer_settings(FF_software_settings_t *dsettings)
551 {
552     // Note: this function does NOT send the mixer configuration read from
553     // flash to the mixer control registers.  If the newly read state is
554     // to become active, the caller must arrange for this to happen (perhaps
555     // by calling set_hardware_mixergain(), or relying on "changed" widget
556     // callbacks like the rme.py ffado-mixer module does).
557
558     unsigned short int vbuf[RME_FF_FLASH_MIXER_ARRAY_SIZE/2];
559     unsigned short int pbuf[RME_FF_FLASH_MIXER_ARRAY_SIZE/2];
560     unsigned short int obuf[RME_FF_FLASH_SECTOR_SIZE/2];
561     fb_nodeaddr_t addr = 0;
562     signed int i, in, out;
563     signed int nch = 0;
564     signed int flash_row_size = 0;
565
566     if (dsettings == NULL)
567         dsettings = settings;
568
569     if (m_rme_model == RME_MODEL_FIREFACE400) {
570         addr = RME_FF400_FLASH_MIXER_VOLUME_ADDR;
571         nch = RME_FF400_MAX_CHANNELS;
572         flash_row_size = 18;
573     } else
574     if (m_rme_model == RME_MODEL_FIREFACE800) {
575         addr = RME_FF800_FLASH_MIXER_VOLUME_ADDR;
576         nch = RME_FF800_MAX_CHANNELS;
577         flash_row_size = 32;
578     }
579     if (addr == 0)
580         return -1;
581
582     i = read_flash(addr, (quadlet_t *)(vbuf), RME_FF_FLASH_MIXER_ARRAY_SIZE/4);
583     debugOutput(DEBUG_LEVEL_VERBOSE, "read_flash(%" PRId64 ") returned %d\n", addr, i);
584
585     addr += RME_FF_FLASH_MIXER_ARRAY_SIZE;
586     i = read_flash(addr, (quadlet_t *)(pbuf), RME_FF_FLASH_MIXER_ARRAY_SIZE/4);
587     debugOutput(DEBUG_LEVEL_VERBOSE, "read_flash(%" PRId64 ") returned %d\n", addr, i);
588
589     addr += RME_FF_FLASH_MIXER_ARRAY_SIZE;
590     i = read_flash(addr, (quadlet_t *)obuf, RME_FF_FLASH_SECTOR_SIZE_QUADS);
591     debugOutput(DEBUG_LEVEL_VERBOSE, "read_flash(%" PRId64 ") returned %d\n", addr, i);
592
593     for (out=0; out<nch/2; out++) {
594         for (in=0; in<nch; in++) {
595             flash2faders(vbuf[in+out*2*flash_row_size], pbuf[in+out*2*flash_row_size],
596               &dsettings->input_faders[getMixerGainIndex(in,out*2)],
597               &dsettings->input_faders[getMixerGainIndex(in,out*2+1)]);
598         }
599     }
600     for (out=0; out<nch/2; out++) {
601         for (in=0; in<nch; in++) {
602             flash2faders(vbuf[in+flash_row_size*(out*2+1)], pbuf[in+flash_row_size*(out*2+1)],
603               &dsettings->playback_faders[getMixerGainIndex(in,out*2)],
604               &dsettings->playback_faders[getMixerGainIndex(in,out*2+1)]);
605         }
606     }
607     // Elements 30 and 31 of obuf[] are not output fader values: [30]
608     // indicates MIDI control is active while [31] is a submix number.
609     // It's suspected that neither of these are used by the device directly,
610     // and that these elements are just a convenient place for computer
611     // control applications to store things.
612     for (out=0; out<30; out++) {
613       dsettings->output_faders[out] = flashvol2fader(obuf[out]);
614     }
615
616     return 0;
617 }
618
619 signed int
620 Device::write_device_mixer_settings(FF_software_settings_t *dsettings)
621 {
622     quadlet_t shadow[RME_FF800_FLASH_MIXER_SHADOW_SIZE/4];
623     unsigned short int vbuf[RME_FF_FLASH_MIXER_ARRAY_SIZE/2];
624     unsigned short int pbuf[RME_FF_FLASH_MIXER_ARRAY_SIZE/2];
625     unsigned short int obuf[RME_FF_FLASH_SECTOR_SIZE/2];
626     fb_nodeaddr_t addr = 0;
627     signed int i, in, out;
628     signed int nch = 0;
629     signed int flash_row_size = 0;
630
631     if (dsettings == NULL)
632         dsettings = settings;
633
634     if (m_rme_model == RME_MODEL_FIREFACE400) {
635         addr = RME_FF400_FLASH_MIXER_VOLUME_ADDR;
636         nch = RME_FF400_MAX_CHANNELS;
637         flash_row_size = 18;
638     } else
639     if (m_rme_model == RME_MODEL_FIREFACE800) {
640         addr = RME_FF800_FLASH_MIXER_SHADOW_ADDR;
641         nch = RME_FF800_MAX_CHANNELS;
642         flash_row_size = 32;
643     }
644     if (addr == 0)
645         return -1;
646
647     // The mixer flash block must be erased before we can write to it
648     i = erase_flash(RME_FF_FLASH_ERASE_VOLUME) != 0;
649     if (i) {
650         debugOutput(DEBUG_LEVEL_VERBOSE, "erase_flash() failed\n");
651         return -1;
652     }
653
654     /* Write the shadow mixer array if the device is a ff800 */
655     if (m_rme_model == RME_MODEL_FIREFACE800) {
656         memset(shadow, 0, sizeof(shadow));
657         for (out=0; out<nch; out++) {
658             for (in=0; in<nch; in++) {
659                 shadow[in+out*0x40] = dsettings->input_faders[getMixerGainIndex(in,out)];
660                 shadow[in+out*0x40+0x20] = dsettings->playback_faders[getMixerGainIndex(in,out)];
661             }
662         }
663         for (out=0; out<nch; out++) {
664             shadow[0x1f80/4+out] = dsettings->output_faders[out];
665         }
666         i = write_flash(addr, shadow, RME_FF800_FLASH_MIXER_SHADOW_SIZE/4);
667         debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%" PRId64 ") returned %d\n", addr, i);
668         addr = RME_FF800_FLASH_MIXER_VOLUME_ADDR;
669     }
670
671     memset(vbuf, 0, sizeof(vbuf));
672     memset(pbuf, 0, sizeof(pbuf));
673     for (out=0; out<nch/2; out++) {
674         for (in=0; in<nch; in++) {
675             faders2flash(dsettings->input_faders[getMixerGainIndex(in,out*2)],
676               dsettings->input_faders[getMixerGainIndex(in,out*2+1)],
677               &vbuf[in+out*2*flash_row_size], &pbuf[in+out*2*flash_row_size]);
678         }
679     }
680     for (out=0; out<nch/2; out++) {
681         for (in=0; in<nch; in++) {
682             faders2flash(dsettings->playback_faders[getMixerGainIndex(in,out*2)],
683               dsettings->playback_faders[getMixerGainIndex(in,out*2+1)],
684               &vbuf[in+flash_row_size*(out*2+1)], &pbuf[in+flash_row_size*(out*2+1)]);
685         }
686     }
687
688     // Elements 30 and 31 of obuf[] are not output fader values.  See
689     // comments in read_device_mixer_settings().
690     memset(obuf, 0, sizeof(obuf));
691     for (out=0; out<30; out++) {
692       obuf[out] = fader2flashvol(dsettings->output_faders[out]);
693     }
694
695     i = write_flash(addr, (quadlet_t *)(vbuf), RME_FF_FLASH_MIXER_ARRAY_SIZE/4);
696     debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%" PRId64 ") returned %d\n", addr, i);
697
698     addr += RME_FF_FLASH_MIXER_ARRAY_SIZE;
699     i = write_flash(addr, (quadlet_t *)(pbuf), RME_FF_FLASH_MIXER_ARRAY_SIZE/4);
700     debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%" PRId64 ") returned %d\n", addr, i);
701
702     addr += RME_FF_FLASH_MIXER_ARRAY_SIZE;
703     i = write_flash(addr, (quadlet_t *)obuf, RME_FF_FLASH_SECTOR_SIZE_QUADS);
704     debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%" PRId64 ") returned %d\n", addr, i);
705
706     return 0;
707 }
708
709 }
Note: See TracBrowser for help on using the browser.