From: <tr...@ff...> - 2013-03-22 12:43:04
|
Author: jwoithe Date: 2013-03-22 05:42:51 -0700 (Fri, 22 Mar 2013) New Revision: 2280 Modified: trunk/libffado/doc/rme_notes/rme_config_register_map.txt trunk/libffado/src/rme/fireface_def.h trunk/libffado/src/rme/fireface_flash.cpp trunk/libffado/src/rme/rme_avdevice.h Log: rme: first cut at writing to the mixer flash. Compile tested only at this stage. Modified: trunk/libffado/doc/rme_notes/rme_config_register_map.txt =================================================================== --- trunk/libffado/doc/rme_notes/rme_config_register_map.txt 2013-03-22 11:47:43 UTC (rev 2279) +++ trunk/libffado/doc/rme_notes/rme_config_register_map.txt 2013-03-22 12:42:51 UTC (rev 2280) @@ -1,9 +1,9 @@ RME Fireface-400 / Fireface-800 register map ============================================ -Version: 0.23 +Version: 0.24 Author: Jonathan Woithe -Date: 21 March 2013 +Date: 22 March 2013 Definitions @@ -506,7 +506,7 @@ V = V0 + V1 - Pf = 0x100 * V1 / (V0 + V1) + Pf = V1 / (V0 + V1) P = 0x0100 * Pf Modified: trunk/libffado/src/rme/fireface_def.h =================================================================== --- trunk/libffado/src/rme/fireface_def.h 2013-03-22 11:47:43 UTC (rev 2279) +++ trunk/libffado/src/rme/fireface_def.h 2013-03-22 12:42:51 UTC (rev 2280) @@ -110,6 +110,7 @@ #define RME_FF400_FLASH_MIXER_PAN_ADDR 0x00070800 #define RME_FF400_FLASH_MIXER_HW_ADDR 0x00071000 /* Hardware volume settings, MIDI enable, submix */ #define RME_FF800_FLASH_MIXER_SHADOW_ADDR 0x3000e0000LL +#define RME_FF800_FLASH_MIXER_SHADOW_SIZE 0x00002000 #define RME_FF800_FLASH_MIXER_VOLUME_ADDR 0x3000e2000LL #define RME_FF800_FLASH_MIXER_PAN_ADDR 0x3000e2800LL #define RME_FF800_FLASH_MIXER_HW_ADDR 0x3000e3000LL /* H/w volume settings, MIDI enable, submix */ Modified: trunk/libffado/src/rme/fireface_flash.cpp =================================================================== --- trunk/libffado/src/rme/fireface_flash.cpp 2013-03-22 11:47:43 UTC (rev 2279) +++ trunk/libffado/src/rme/fireface_flash.cpp 2013-03-22 12:42:51 UTC (rev 2280) @@ -546,7 +546,10 @@ addr += RME_FF_FLASH_MIXER_ARRAY_SIZE; i = read_flash(addr, (quadlet_t *)obuf, RME_FF_FLASH_SECTOR_SIZE_QUADS); + debugOutput(DEBUG_LEVEL_VERBOSE, "read_flash(%lld) returned %d\n", addr, i); + // TODO: byteswap flash values if machine is not little endian + for (out=0; out<nch/2; out++) { for (in=0; in<nch; in++) { unsigned int flashvol = vbuf[in+out*nch*2]; @@ -558,8 +561,8 @@ } for (out=0; out<nch/2; out++) { for (in=0; in<nch; in++) { - unsigned int flashvol = vbuf[in+out*nch*2+1]; - unsigned int flashpan = pbuf[in+out*nch*2+1]; + unsigned int flashvol = vbuf[in+out*(nch*2+1)]; + unsigned int flashpan = pbuf[in+out*(nch*2+1)]; v = 0x10000 * (exp(3.0*flashvol/1023.0)-1) / (exp(3)-1.0); settings->playback_faders[getMixerGainIndex(in,out*2)] = v * (flashpan/256.0); settings->playback_faders[getMixerGainIndex(in,out*2+1)] = v * (1 - flashpan/256.0); @@ -579,4 +582,96 @@ return 0; } +signed int +Device::write_device_mixer_settings(FF_software_settings_t *settings) +{ + quadlet_t shadow[RME_FF800_FLASH_MIXER_SHADOW_SIZE/4]; + unsigned short int vbuf[RME_FF_FLASH_MIXER_ARRAY_SIZE/2]; + unsigned short int pbuf[RME_FF_FLASH_MIXER_ARRAY_SIZE/2]; + unsigned short int obuf[RME_FF_FLASH_SECTOR_SIZE/2]; + fb_nodeaddr_t addr = 0; + signed int i, in, out; + signed int nch = 0; + + if (m_rme_model == RME_MODEL_FIREFACE400) { + addr = RME_FF400_FLASH_MIXER_VOLUME_ADDR; + nch = 18; + } else + if (m_rme_model == RME_MODEL_FIREFACE800) { + addr = RME_FF800_FLASH_MIXER_SHADOW_ADDR; + nch = 32; + } + if (addr == 0) + return -1; + + // The mixer flash block must be erased before we can write to it + i = erase_flash(RME_FF_FLASH_ERASE_VOLUME) != 0; + if (i) { + debugOutput(DEBUG_LEVEL_VERBOSE, "erase_flash() failed\n"); + return -1; + } + + // TODO: byteswap flash values if machine is not little endian + + /* Write the shadow mixer array if the device is a ff800 */ + if (m_rme_model == RME_MODEL_FIREFACE800) { + memset(shadow, 0, sizeof(shadow)); + for (out=0; out<nch; out++) { + for (in=0; in<nch; in++) { + shadow[in+out*0x40] = settings->input_faders[getMixerGainIndex(in,out)]; + shadow[in+out*0x40+0x20] = settings->playback_faders[getMixerGainIndex(in,out)]; + } + } + for (out=0; out<nch; out++) { + shadow[0x1f80+out] = settings->output_faders[out]; + } + i = write_flash(addr, shadow, RME_FF800_FLASH_MIXER_SHADOW_SIZE/4); + debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%lld) returned %d\n", addr, i); + addr = RME_FF800_FLASH_MIXER_VOLUME_ADDR; + } + + for (out=0; out<nch/2; out++) { + for (in=0; in<nch; in++) { + signed int v0 = settings->input_faders[getMixerGainIndex(in,out*2)]; + signed int v1 = settings->input_faders[getMixerGainIndex(in,out*2+1)]; + signed int v = v0 + v1; + pbuf[in+out*nch*2] = 256.0 * v1 / (v0 + v1); + vbuf[in+out*nch*2] = (1023/3) * log(v*(exp(3.0)-1.0)/0x10000 + 1); + } + } + for (out=0; out<nch/2; out++) { + for (in=0; in<nch; in++) { + signed int v0 = settings->playback_faders[getMixerGainIndex(in,out*2)]; + signed int v1 = settings->playback_faders[getMixerGainIndex(in,out*2+1)]; + signed int v = v0 + v1; + pbuf[in+out*(nch*2+1)] = 256.0 * v1 / (v0 + v1); + vbuf[in+out*(nch*2+1)] = (1023/3) * log(v*(exp(3.0)-1.0)/0x10000 + 1); + } + } + + // Elements 30 and 31 of obuf[] are not output fader values: [30] + // indicates MIDI control is active while [31] is a submix number. + // It's suspected that neither of these are used by the device directly, + // and that these elements are just a convenient place for computer + // control applications to store things. For now we'll just leave them + // set to zero. + memset(obuf, 0, sizeof(obuf)); + for (out=0; out<30; out++) { + obuf[out] = (1023.0/3) * log(settings->output_faders[out]*(exp(3.0)-1.0)/0x10000 + 1); + } + + i = write_flash(addr, (quadlet_t *)(vbuf), RME_FF_FLASH_MIXER_ARRAY_SIZE/4); + debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%lld) returned %d\n", addr, i); + + addr += RME_FF_FLASH_MIXER_ARRAY_SIZE; + i = write_flash(addr, (quadlet_t *)(pbuf), RME_FF_FLASH_MIXER_ARRAY_SIZE/4); + debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%lld) returned %d\n", addr, i); + + addr += RME_FF_FLASH_MIXER_ARRAY_SIZE; + i = write_flash(addr, (quadlet_t *)obuf, RME_FF_FLASH_SECTOR_SIZE_QUADS); + debugOutput(DEBUG_LEVEL_VERBOSE, "write_flash(%lld) returned %d\n", addr, i); + + return 0; } + +} Modified: trunk/libffado/src/rme/rme_avdevice.h =================================================================== --- trunk/libffado/src/rme/rme_avdevice.h 2013-03-22 11:47:43 UTC (rev 2279) +++ trunk/libffado/src/rme/rme_avdevice.h 2013-03-22 12:42:51 UTC (rev 2280) @@ -190,6 +190,7 @@ signed int read_device_flash_settings(FF_software_settings_t *settings); signed int write_device_flash_settings(FF_software_settings_t *settings); signed int read_device_mixer_settings(FF_software_settings_t *settings); + signed int write_device_mixer_settings(FF_software_settings_t *settings); /* Low-level hardware functions */ unsigned int multiplier_of_freq(unsigned int freq); |