Changeset 433 for branches

Show
Ignore:
Timestamp:
03/11/07 06:15:41 (17 years ago)
Author:
pieterpalmers
Message:

- dice support

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/streaming-rework/src/dice/dice_avdevice.cpp

    r426 r433  
    1818 * MA 02111-1307 USA. 
    1919 */ 
    20 #warning DICE support is currently useless 
     20#warning DICE support is currently untested 
    2121 
    2222#include "dice/dice_avdevice.h" 
     
    3636#include <libraw1394/csr.h> 
    3737 
     38#include <iostream> 
     39#include <sstream> 
     40 
    3841 
    3942namespace Dice { 
     
    4851                    Ieee1394Service& ieee1394service, 
    4952                    int nodeId ) 
    50     : IAvDevice( configRom, ieee1394service, nodeId ) 
     53    : IAvDevice( configRom, ieee1394service, nodeId ) 
    5154    , m_model( NULL ) 
    52     , m_iso_recv_channel ( -1 ) 
    53     , m_iso_send_channel ( -1 ) 
     55    , m_global_reg_offset (0xFFFFFFFFLU) 
     56    , m_global_reg_size (0xFFFFFFFFLU) 
     57    , m_tx_reg_offset (0xFFFFFFFFLU) 
     58    , m_tx_reg_size (0xFFFFFFFFLU) 
     59    , m_rx_reg_offset (0xFFFFFFFFLU) 
     60    , m_rx_reg_size (0xFFFFFFFFLU) 
     61    , m_unused1_reg_offset (0xFFFFFFFFLU) 
     62    , m_unused1_reg_size (0xFFFFFFFFLU) 
     63    , m_unused2_reg_offset (0xFFFFFFFFLU) 
     64    , m_unused2_reg_size (0xFFFFFFFFLU) 
     65    , m_nb_tx (0xFFFFFFFFLU) 
     66    , m_tx_size (0xFFFFFFFFLU) 
     67    , m_nb_rx (0xFFFFFFFFLU) 
     68    , m_rx_size (0xFFFFFFFFLU) 
     69    , m_notifier (NULL) 
    5470{ 
    5571    debugOutput( DEBUG_LEVEL_VERBOSE, "Created Dice::DiceAvDevice (NodeID %d)\n", 
     
    6076DiceAvDevice::~DiceAvDevice() 
    6177{ 
    62  
     78    // FIXME: clean up m_receiveProcessors & xmit 
     79 
     80    if (m_notifier) { 
     81        unlock(); 
     82    } 
    6383} 
    6484 
     
    87107DiceAvDevice::discover() 
    88108{ 
    89     unsigned int vendorId = m_pConfigRom->getNodeVendorId(); 
    90     unsigned int modelId = m_pConfigRom->getModelId(); 
     109    unsigned int vendorId = m_configRom->getNodeVendorId(); 
     110    unsigned int modelId = m_configRom->getModelId(); 
    91111 
    92112    for ( unsigned int i = 0; 
     
    102122    } 
    103123 
    104     if (m_model != NULL) { 
    105         debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s\n", 
    106                 m_model->vendor_name, m_model->model_name); 
    107         return true; 
    108     } 
    109  
    110     return false; 
     124    if (m_model == NULL) { 
     125        debugWarning("DiceAvDevice::discover() called for a non-dice device"); 
     126        return false; 
     127    } 
     128     
     129    if ( !initIoFunctions() ) { 
     130        debugError("Could not initialize I/O functions\n"); 
     131        return false; 
     132    } 
     133 
     134    debugOutput( DEBUG_LEVEL_VERBOSE, "found %s %s (nick: %s)\n", 
     135                m_model->vendor_name, m_model->model_name, getDeviceNickName().c_str()); 
     136 
     137    return true; 
    111138} 
    112139 
    113140int  
    114141DiceAvDevice::getSamplingFrequency( ) { 
    115     return 0; 
     142    ESamplingFrequency samplingFrequency; 
     143     
     144    fb_quadlet_t clockreg; 
     145    if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg)) { 
     146        debugError("Could not read CLOCK_SELECT register\n"); 
     147        return false; 
     148    } 
     149     
     150    clockreg = DICE_GET_RATE(clockreg); 
     151 
     152    switch (clockreg) { 
     153        case DICE_RATE_32K:      samplingFrequency = eSF_32000Hz;  break; 
     154        case DICE_RATE_44K1:     samplingFrequency = eSF_44100Hz;  break; 
     155        case DICE_RATE_48K:      samplingFrequency = eSF_48000Hz;  break; 
     156        case DICE_RATE_88K2:     samplingFrequency = eSF_88200Hz;  break; 
     157        case DICE_RATE_96K:      samplingFrequency = eSF_96000Hz;  break; 
     158        case DICE_RATE_176K4:    samplingFrequency = eSF_176400Hz; break; 
     159        case DICE_RATE_192K:     samplingFrequency = eSF_192000Hz; break; 
     160        case DICE_RATE_ANY_LOW:  samplingFrequency = eSF_AnyLow;   break; 
     161        case DICE_RATE_ANY_MID:  samplingFrequency = eSF_AnyMid;   break; 
     162        case DICE_RATE_ANY_HIGH: samplingFrequency = eSF_AnyHigh;  break; 
     163        case DICE_RATE_NONE:     samplingFrequency = eSF_None;     break; 
     164        default:                 samplingFrequency = eSF_DontCare; break; 
     165    } 
     166     
     167    return convertESamplingFrequency(samplingFrequency); 
    116168} 
    117169 
     
    119171DiceAvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) 
    120172{ 
    121  
    122     return false; 
     173    bool supported=false; 
     174    fb_quadlet_t select=0x0; 
     175     
     176    switch ( samplingFrequency ) { 
     177    default: 
     178    case eSF_22050Hz: 
     179    case eSF_24000Hz: 
     180        supported=false; 
     181        break; 
     182    case eSF_32000Hz: 
     183        supported=maskedCheckNotZeroGlobalReg( 
     184                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     185                    DICE_CLOCKCAP_RATE_32K); 
     186        select=DICE_RATE_32K; 
     187        break; 
     188    case eSF_44100Hz: 
     189        supported=maskedCheckNotZeroGlobalReg( 
     190                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     191                    DICE_CLOCKCAP_RATE_44K1); 
     192        select=DICE_RATE_44K1; 
     193        break; 
     194    case eSF_48000Hz: 
     195        supported=maskedCheckNotZeroGlobalReg( 
     196                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     197                    DICE_CLOCKCAP_RATE_48K); 
     198        select=DICE_RATE_48K; 
     199        break; 
     200    case eSF_88200Hz: 
     201        supported=maskedCheckNotZeroGlobalReg( 
     202                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     203                    DICE_CLOCKCAP_RATE_88K2); 
     204        select=DICE_RATE_88K2; 
     205        break; 
     206    case eSF_96000Hz: 
     207        supported=maskedCheckNotZeroGlobalReg( 
     208                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     209                    DICE_CLOCKCAP_RATE_96K); 
     210        select=DICE_RATE_96K; 
     211        break; 
     212    case eSF_176400Hz: 
     213        supported=maskedCheckNotZeroGlobalReg( 
     214                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     215                    DICE_CLOCKCAP_RATE_176K4); 
     216        select=DICE_RATE_176K4; 
     217        break; 
     218    case eSF_192000Hz: 
     219        supported=maskedCheckNotZeroGlobalReg( 
     220                    DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES, 
     221                    DICE_CLOCKCAP_RATE_192K); 
     222        select=DICE_RATE_192K; 
     223        break; 
     224    } 
     225 
     226    if (!supported) { 
     227        debugWarning("Unsupported sample rate: %d\n", convertESamplingFrequency(samplingFrequency)); 
     228        return false; 
     229    } 
     230 
     231    if (isIsoStreamingEnabled()) { 
     232        debugError("Cannot change samplerate while streaming is enabled\n"); 
     233        return false; 
     234    } 
     235     
     236    fb_quadlet_t clockreg; 
     237    if (!readGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, &clockreg)) { 
     238        debugError("Could not read CLOCK_SELECT register\n"); 
     239        return false; 
     240    } 
     241     
     242    clockreg = DICE_SET_RATE(clockreg, select); 
     243     
     244    if (!writeGlobalReg(DICE_REGISTER_GLOBAL_CLOCK_SELECT, clockreg)) { 
     245        debugError("Could not write CLOCK_SELECT register\n"); 
     246        return false; 
     247    } 
     248 
     249    return true; 
    123250} 
    124251 
     
    131258} 
    132259 
     260// NOTE on bandwidth calculation 
     261// FIXME: The bandwidth allocation calculation can probably be 
     262// refined somewhat since this is currently based on a rudimentary 
     263// understanding of the iso protocol. 
     264// Currently we assume the following. 
     265//   * Ack/iso gap = 0.05 us 
     266//   * DATA_PREFIX = 0.16 us 
     267//   * DATA_END    = 0.26 us 
     268// These numbers are the worst-case figures given in the ieee1394 
     269// standard.  This gives approximately 0.5 us of overheads per 
     270// packet - around 25 bandwidth allocation units (from the ieee1394 
     271// standard 1 bandwidth allocation unit is 125/6144 us).  We further 
     272// assume the device is running at S400 (which it should be) so one 
     273// allocation unit is equivalent to 1 transmitted byte; thus the 
     274// bandwidth allocation required for the packets themselves is just 
     275// the size of the packet. 
    133276bool 
    134277DiceAvDevice::prepare() { 
    135  
     278    int samplerate=getSamplingFrequency(); 
     279 
     280    // prepare receive SP's 
     281    for (unsigned int i=0;i<m_nb_tx;i++) { 
     282        fb_quadlet_t nb_audio; 
     283        fb_quadlet_t nb_midi; 
     284        unsigned int nb_channels=0; 
     285         
     286        if(!readTxReg(i, DICE_REGISTER_TX_NB_AUDIO_BASE, &nb_audio)) { 
     287            debugError("Could not read DICE_REGISTER_TX_NB_AUDIO_BASE register for ATX%u",i); 
     288            continue; 
     289        } 
     290        if(!readTxReg(i, DICE_REGISTER_TX_MIDI_BASE, &nb_midi)) { 
     291            debugError("Could not read DICE_REGISTER_TX_MIDI_BASE register for ATX%u",i); 
     292            continue; 
     293        } 
     294         
     295        // request the channel names 
     296        diceNameVector names_audio=getTxNameString(i); 
     297         
     298        if (names_audio.size() != nb_audio) { 
     299            debugWarning("The audio channel name vector is incorrect, using default names\n"); 
     300            names_audio.clear(); 
     301             
     302            for (unsigned int j=0;j<nb_audio;j++) { 
     303                std::ostringstream newname; 
     304                newname << "input_" << j; 
     305                names_audio.push_back(newname.str()); 
     306            } 
     307        } 
     308         
     309        nb_channels=nb_audio; 
     310        if(nb_midi) nb_channels += 1; // midi-muxed counts as one 
     311         
     312        // construct the MIDI names 
     313        diceNameVector names_midi; 
     314        for (unsigned int j=0;j<nb_midi;j++) { 
     315            std::ostringstream newname; 
     316            newname << "midi_in_" << j; 
     317            names_midi.push_back(newname.str()); 
     318        } 
     319         
     320        // construct the streamprocessor 
     321        Streaming::AmdtpReceiveStreamProcessor *p; 
     322        p=new Streaming::AmdtpReceiveStreamProcessor( 
     323                             m_p1394Service->getPort(), 
     324                             samplerate, 
     325                             nb_channels); 
     326 
     327        if(!p->init()) { 
     328            debugFatal("Could not initialize receive processor!\n"); 
     329            delete p; 
     330            continue; 
     331        } 
     332 
     333        // add audio ports to the processor 
     334        for (unsigned int j=0;j<nb_audio;j++) { 
     335            diceChannelInfo channelInfo; 
     336            channelInfo.name=names_audio.at(i); 
     337            channelInfo.portType=ePT_Analog; 
     338            channelInfo.streamPosition=j; 
     339            channelInfo.streamLocation=0; 
     340 
     341            if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Capture)) { 
     342                debugError("Could not add channel %s to StreamProcessor\n",  
     343                    channelInfo.name.c_str()); 
     344                continue; 
     345            } 
     346        } 
     347         
     348        // add midi ports to the processor 
     349        for (unsigned int j=0;j<nb_midi;j++) { 
     350            diceChannelInfo channelInfo; 
     351            channelInfo.name=names_midi.at(i); 
     352            channelInfo.portType=ePT_MIDI; 
     353            channelInfo.streamPosition=nb_audio; 
     354            channelInfo.streamLocation=j; 
     355 
     356            if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Capture)) { 
     357                debugError("Could not add channel %s to StreamProcessor\n",  
     358                    channelInfo.name.c_str()); 
     359                continue; 
     360            } 
     361        } 
     362         
     363        // add the SP to the vector 
     364        m_receiveProcessors.push_back(p); 
     365    } 
     366     
     367    // prepare transmit SP's 
     368    for (unsigned int i=0;i<m_nb_rx;i++) { 
     369        fb_quadlet_t nb_audio; 
     370        fb_quadlet_t nb_midi; 
     371        unsigned int nb_channels=0; 
     372         
     373        if(!readTxReg(i, DICE_REGISTER_RX_NB_AUDIO_BASE, &nb_audio)) { 
     374            debugError("Could not read DICE_REGISTER_RX_NB_AUDIO_BASE register for ARX%u",i); 
     375            continue; 
     376        } 
     377        if(!readTxReg(i, DICE_REGISTER_RX_MIDI_BASE, &nb_midi)) { 
     378            debugError("Could not read DICE_REGISTER_RX_MIDI_BASE register for ARX%u",i); 
     379            continue; 
     380        } 
     381         
     382        // request the channel names 
     383        diceNameVector names_audio=getRxNameString(i); 
     384         
     385        if (names_audio.size() != nb_audio) { 
     386            debugWarning("The audio channel name vector is incorrect, using default names\n"); 
     387            names_audio.clear(); 
     388             
     389            for (unsigned int j=0;j<nb_audio;j++) { 
     390                std::ostringstream newname; 
     391                newname << "output_" << j; 
     392                names_audio.push_back(newname.str()); 
     393            } 
     394        } 
     395         
     396        nb_channels=nb_audio; 
     397        if(nb_midi) nb_channels += 1; // midi-muxed counts as one 
     398         
     399        // construct the MIDI names 
     400        diceNameVector names_midi; 
     401        for (unsigned int j=0;j<nb_midi;j++) { 
     402            std::ostringstream newname; 
     403            newname << "midi_out_" << j; 
     404            names_midi.push_back(newname.str()); 
     405        } 
     406         
     407        // construct the streamprocessor 
     408        Streaming::AmdtpTransmitStreamProcessor *p; 
     409        p=new Streaming::AmdtpTransmitStreamProcessor( 
     410                             m_p1394Service->getPort(), 
     411                             samplerate, 
     412                             nb_channels); 
     413 
     414        if(!p->init()) { 
     415            debugFatal("Could not initialize transmit processor!\n"); 
     416            delete p; 
     417            continue; 
     418        } 
     419 
     420        // add audio ports to the processor 
     421        for (unsigned int j=0;j<nb_audio;j++) { 
     422            diceChannelInfo channelInfo; 
     423            channelInfo.name=names_audio.at(i); 
     424            channelInfo.portType=ePT_Analog; 
     425            channelInfo.streamPosition=j; 
     426            channelInfo.streamLocation=0; 
     427 
     428            if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Playback)) { 
     429                debugError("Could not add channel %s to StreamProcessor\n",  
     430                    channelInfo.name.c_str()); 
     431                continue; 
     432            } 
     433        } 
     434         
     435        // add midi ports to the processor 
     436        for (unsigned int j=0;j<nb_midi;j++) { 
     437            diceChannelInfo channelInfo; 
     438            channelInfo.name=names_midi.at(i); 
     439            channelInfo.portType=ePT_MIDI; 
     440            channelInfo.streamPosition=nb_audio; 
     441            channelInfo.streamLocation=j; 
     442 
     443            if (!addChannelToProcessor(&channelInfo, p, Streaming::Port::E_Playback)) { 
     444                debugError("Could not add channel %s to StreamProcessor\n",  
     445                    channelInfo.name.c_str()); 
     446                continue; 
     447            } 
     448        } 
     449         
     450        m_transmitProcessors.push_back(p); 
     451    } 
    136452    return true; 
    137453} 
    138454 
    139455bool 
     456DiceAvDevice::addChannelToProcessor( 
     457    diceChannelInfo *channelInfo, 
     458    Streaming::StreamProcessor *processor, 
     459    Streaming::Port::E_Direction direction) { 
     460     
     461    std::string id=std::string("dev?"); 
     462    if(!getOption("id", id)) { 
     463        debugWarning("Could not retrieve id parameter, defauling to 'dev?'\n"); 
     464    } 
     465 
     466    std::ostringstream portname; 
     467    portname << id << "_" << channelInfo->name; 
     468 
     469    Streaming::Port *p=NULL; 
     470    switch(channelInfo->portType) { 
     471    case ePT_Analog: 
     472        p=new Streaming::AmdtpAudioPort( 
     473                portname.str(), 
     474                direction, 
     475                channelInfo->streamPosition, 
     476                channelInfo->streamLocation, 
     477                Streaming::AmdtpPortInfo::E_MBLA 
     478        ); 
     479        break; 
     480 
     481    case ePT_MIDI: 
     482        p=new Streaming::AmdtpMidiPort( 
     483                portname.str(), 
     484                direction, 
     485                channelInfo->streamPosition, 
     486                channelInfo->streamLocation, 
     487                Streaming::AmdtpPortInfo::E_Midi 
     488        ); 
     489 
     490        break; 
     491    default: 
     492    // unsupported 
     493        break; 
     494    } 
     495 
     496    if (!p) { 
     497        debugOutput(DEBUG_LEVEL_VERBOSE, "Skipped port %s\n",channelInfo->name.c_str()); 
     498    } else { 
     499 
     500        if (!processor->addPort(p)) { 
     501            debugWarning("Could not register port with stream processor\n"); 
     502            return false; 
     503        } 
     504    } 
     505 
     506    return true; 
     507} 
     508 
     509bool 
    140510DiceAvDevice::lock() { 
     511    fb_octlet_t result; 
     512     
     513    debugOutput(DEBUG_LEVEL_VERBOSE, "Locking %s %s at node %d\n",  
     514        m_model->vendor_name, m_model->model_name, m_nodeId); 
     515         
     516    // get a notifier to handle device notifications 
     517    nodeaddr_t notify_address; 
     518    notify_address = m_p1394Service->findFreeARMBlock( 
     519                        DICE_NOTIFIER_BASE_ADDRESS, 
     520                        DICE_NOTIFIER_BLOCK_LENGTH, 
     521                        DICE_NOTIFIER_BLOCK_LENGTH); 
     522     
     523    if (notify_address == 0xFFFFFFFFFFFFFFFFLLU) { 
     524        debugError("Could not find free ARM block for notification\n"); 
     525        return false; 
     526    } 
     527     
     528    m_notifier=new DiceAvDevice::DiceNotifier(this, notify_address); 
     529     
     530    if(!m_notifier) { 
     531        debugError("Could not allocate notifier\n"); 
     532        return false; 
     533    } 
     534     
     535    if (!m_p1394Service->registerARMHandler(m_notifier)) { 
     536        debugError("Could not register notifier\n"); 
     537        delete m_notifier; 
     538        m_notifier=NULL; 
     539        return false; 
     540    } 
     541 
     542    // register this notifier 
     543    fb_nodeaddr_t addr = DICE_REGISTER_BASE  
     544                       + m_global_reg_offset 
     545                       + DICE_REGISTER_GLOBAL_OWNER; 
     546 
     547    // registry offsets should always be smaller than 0x7FFFFFFF 
     548    // because otherwise base + offset > 64bit 
     549    if(m_global_reg_offset & 0x80000000) { 
     550        debugError("register offset not initialized yet\n"); 
     551        return false; 
     552    } 
     553     
     554    fb_nodeaddr_t swap_value = ((0xFFC0) | m_p1394Service->getLocalNodeId()) << 24; 
     555    swap_value |= m_notifier->getStart(); 
     556     
     557    if (!m_p1394Service->lockCompareSwap64(  m_nodeId, addr, DICE_OWNER_NO_OWNER,  
     558                                       swap_value, &result )) { 
     559        debugWarning("Could not register ourselves as device owner\n"); 
     560    } 
    141561 
    142562    return true; 
     
    146566bool 
    147567DiceAvDevice::unlock() { 
     568    fb_octlet_t result; 
     569     
     570    if(!m_notifier) { 
     571        debugWarning("Request to unlock, but no notifier present!\n"); 
     572        return false; 
     573    } 
     574     
     575    fb_nodeaddr_t addr = DICE_REGISTER_BASE  
     576                       + m_global_reg_offset 
     577                       + DICE_REGISTER_GLOBAL_OWNER; 
     578 
     579    // registry offsets should always be smaller than 0x7FFFFFFF 
     580    // because otherwise base + offset > 64bit 
     581    if(m_global_reg_offset & 0x80000000) { 
     582        debugError("register offset not initialized yet\n"); 
     583        return false; 
     584    } 
     585     
     586    fb_nodeaddr_t compare_value = ((0xFFC0) | m_p1394Service->getLocalNodeId()) << 24; 
     587    compare_value |= m_notifier->getStart(); 
     588     
     589    if (!m_p1394Service->lockCompareSwap64(  m_nodeId, addr, compare_value,  
     590                                       DICE_OWNER_NO_OWNER, &result )) { 
     591        debugWarning("Could not unregister ourselves as device owner\n"); 
     592    } 
     593     
     594    m_p1394Service->unregisterARMHandler(m_notifier); 
     595    delete m_notifier; 
     596    m_notifier=NULL; 
    148597 
    149598    return true; 
    150599} 
    151600 
    152 int  
     601int 
    153602DiceAvDevice::getStreamCount() { 
    154     return 0; // one receive, one transmit 
     603    return m_receiveProcessors.size() + m_transmitProcessors.size(); 
    155604} 
    156605 
     
    158607DiceAvDevice::getStreamProcessorByIndex(int i) { 
    159608 
    160 //    switch (i) { 
    161 //    case 0: 
    162 //        return m_receiveProcessor; 
    163 //    case 1: 
    164 //        return m_transmitProcessor; 
    165 //    default: 
    166 //        return NULL; 
    167 //    } 
    168 //    return 0; 
     609    if (i<(int)m_receiveProcessors.size()) { 
     610        return m_receiveProcessors.at(i); 
     611    } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { 
     612        return m_transmitProcessors.at(i-m_receiveProcessors.size()); 
     613    } 
     614 
    169615    return NULL; 
    170616} 
     
    173619DiceAvDevice::startStreamByIndex(int i) { 
    174620 
    175     // NOTE: this assumes that you have two streams 
    176     switch (i) { 
    177     case 0: 
    178         // TODO: do the stuff that is nescessary to make the device 
    179         // transmit a stream 
    180  
    181         // Set the streamprocessor channel to the one obtained by  
    182         // the connection management 
    183 //        m_receiveProcessor->setChannel(m_iso_recv_channel); 
    184  
    185         break; 
    186     case 1: 
    187         // TODO: do the stuff that is nescessary to make the device 
    188         // receive a stream 
    189  
    190         // Set the streamprocessor channel to the one obtained by  
    191         // the connection management 
    192 //        m_transmitProcessor->setChannel(m_iso_send_channel); 
    193  
    194         break; 
    195          
    196     default: // Invalid stream index 
    197         return false; 
    198     } 
    199  
     621    if (isIsoStreamingEnabled()) { 
     622        debugError("Cannot start streams while streaming is enabled\n"); 
     623        return false; 
     624    } 
     625 
     626    if (i<(int)m_receiveProcessors.size()) { 
     627        int n=i; 
     628        Streaming::StreamProcessor *p=m_receiveProcessors.at(n); 
     629         
     630        // allocate ISO channel 
     631        int isochannel=allocateIsoChannel(p->getMaxPacketSize()); 
     632        if(isochannel<0) { 
     633            debugError("Could not allocate iso channel for SP %d (ATX %d)\n",i,n); 
     634            return false; 
     635        } 
     636        p->setChannel(isochannel); 
     637         
     638        fb_quadlet_t reg_isoch; 
     639        // check value of ISO_CHANNEL register 
     640        if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) { 
     641            debugError("Could not read ISO_CHANNEL register for ATX %d\n", n); 
     642            p->setChannel(-1); 
     643            deallocateIsoChannel(isochannel); 
     644            return false; 
     645        } 
     646        if(reg_isoch != 0xFFFFFFFFUL) { 
     647            debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08X) for ATX %d\n", reg_isoch, n); 
     648            p->setChannel(-1); 
     649            deallocateIsoChannel(isochannel); 
     650            return false; 
     651        } 
     652         
     653        // write value of ISO_CHANNEL register 
     654        reg_isoch=isochannel; 
     655        if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) { 
     656            debugError("Could not write ISO_CHANNEL register for ATX %d\n", n); 
     657            p->setChannel(-1); 
     658            deallocateIsoChannel(isochannel); 
     659            return false; 
     660        } 
     661         
     662        return true; 
     663         
     664    } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { 
     665        int n=i-m_receiveProcessors.size(); 
     666        Streaming::StreamProcessor *p=m_transmitProcessors.at(n); 
     667         
     668        // allocate ISO channel 
     669        int isochannel=allocateIsoChannel(p->getMaxPacketSize()); 
     670        if(isochannel<0) { 
     671            debugError("Could not allocate iso channel for SP %d (ATX %d)\n",i,n); 
     672            return false; 
     673        } 
     674        p->setChannel(isochannel); 
     675         
     676        fb_quadlet_t reg_isoch; 
     677        // check value of ISO_CHANNEL register 
     678        if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) { 
     679            debugError("Could not read ISO_CHANNEL register for ARX %d\n", n); 
     680            p->setChannel(-1); 
     681            deallocateIsoChannel(isochannel); 
     682            return false; 
     683        } 
     684        if(reg_isoch != 0xFFFFFFFFUL) { 
     685            debugError("ISO_CHANNEL register != 0xFFFFFFFF (=0x%08X) for ARX %d\n", reg_isoch, n); 
     686            p->setChannel(-1); 
     687            deallocateIsoChannel(isochannel); 
     688            return false; 
     689        } 
     690         
     691        // write value of ISO_CHANNEL register 
     692        reg_isoch=isochannel; 
     693        if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) { 
     694            debugError("Could not write ISO_CHANNEL register for ARX %d\n", n); 
     695            p->setChannel(-1); 
     696            deallocateIsoChannel(isochannel); 
     697            return false; 
     698        } 
     699         
     700        return true; 
     701    } 
     702     
     703    debugError("SP index %d out of range!\n",i); 
     704     
     705    return false; 
     706
     707 
     708bool 
     709DiceAvDevice::stopStreamByIndex(int i) { 
     710 
     711    if (isIsoStreamingEnabled()) { 
     712        debugError("Cannot stop streams while streaming is enabled\n"); 
     713        return false; 
     714    } 
     715 
     716    if (i<(int)m_receiveProcessors.size()) { 
     717        int n=i; 
     718        Streaming::StreamProcessor *p=m_receiveProcessors.at(n); 
     719        unsigned int isochannel=p->getChannel(); 
     720         
     721        fb_quadlet_t reg_isoch; 
     722        // check value of ISO_CHANNEL register 
     723        if(!readTxReg(n, DICE_REGISTER_TX_ISOC_BASE, &reg_isoch)) { 
     724            debugError("Could not read ISO_CHANNEL register for ATX %d\n", n); 
     725            return false; 
     726        } 
     727        if(reg_isoch != isochannel) { 
     728            debugError("ISO_CHANNEL register != 0x%08X (=0x%08X) for ATX %d\n", isochannel, reg_isoch, n); 
     729            return false; 
     730        } 
     731         
     732        // write value of ISO_CHANNEL register 
     733        reg_isoch=0xFFFFFFFFUL; 
     734        if(!writeTxReg(n, DICE_REGISTER_TX_ISOC_BASE, reg_isoch)) { 
     735            debugError("Could not write ISO_CHANNEL register for ATX %d\n", n); 
     736            return false; 
     737        } 
     738         
     739        // deallocate ISO channel 
     740        if(!deallocateIsoChannel(isochannel)) { 
     741            debugError("Could not deallocate iso channel for SP %d (ATX %d)\n",i,n); 
     742            return false; 
     743        } 
     744         
     745        p->setChannel(-1); 
     746        return true; 
     747         
     748    } else if (i<(int)m_receiveProcessors.size() + (int)m_transmitProcessors.size()) { 
     749        int n=i-m_receiveProcessors.size(); 
     750        Streaming::StreamProcessor *p=m_transmitProcessors.at(n); 
     751         
     752        unsigned int isochannel=p->getChannel(); 
     753         
     754        fb_quadlet_t reg_isoch; 
     755        // check value of ISO_CHANNEL register 
     756        if(!readRxReg(n, DICE_REGISTER_RX_ISOC_BASE, &reg_isoch)) { 
     757            debugError("Could not read ISO_CHANNEL register for ARX %d\n", n); 
     758            return false; 
     759        } 
     760        if(reg_isoch != isochannel) { 
     761            debugError("ISO_CHANNEL register != 0x%08X (=0x%08X) for ARX %d\n", isochannel, reg_isoch, n); 
     762            return false; 
     763        } 
     764         
     765        // write value of ISO_CHANNEL register 
     766        reg_isoch=0xFFFFFFFFUL; 
     767        if(!writeRxReg(n, DICE_REGISTER_RX_ISOC_BASE, reg_isoch)) { 
     768            debugError("Could not write ISO_CHANNEL register for ARX %d\n", n); 
     769            return false; 
     770        } 
     771         
     772        // deallocate ISO channel 
     773        if(!deallocateIsoChannel(isochannel)) { 
     774            debugError("Could not deallocate iso channel for SP %d (ARX %d)\n",i,n); 
     775            return false; 
     776        } 
     777         
     778        p->setChannel(-1); 
     779        return true; 
     780    } 
     781     
     782    debugError("SP index %d out of range!\n",i); 
     783     
     784    return false; 
     785
     786 
     787// helper routines 
     788 
     789// allocate ISO resources for the SP's 
     790int DiceAvDevice::allocateIsoChannel(unsigned int packet_size) { 
     791    unsigned int bandwidth=8+packet_size; 
     792     
     793    int ch=m_p1394Service->allocateIsoChannelGeneric(bandwidth); 
     794         
     795    debugOutput(DEBUG_LEVEL_VERBOSE, "allocated channel %d, bandwidth %d\n", 
     796        ch, bandwidth); 
     797     
     798    return ch; 
     799
     800// deallocate ISO resources 
     801bool DiceAvDevice::deallocateIsoChannel(int channel) { 
     802    debugOutput(DEBUG_LEVEL_VERBOSE, "freeing channel %d\n",channel); 
     803    return m_p1394Service->freeIsoChannel(channel); 
     804
     805 
     806bool 
     807DiceAvDevice::enableIsoStreaming() { 
     808    return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_ENABLE); 
     809
     810 
     811bool 
     812DiceAvDevice::disableIsoStreaming() { 
     813    return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_DISABLE); 
     814
     815 
     816bool 
     817DiceAvDevice::isIsoStreamingEnabled() { 
     818    fb_quadlet_t result; 
     819    readGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, &result); 
     820    // I don't know what exactly is 'enable',  
     821    // but disable is definately == 0 
     822    return (result != DICE_ISOSTREAMING_DISABLE); 
     823
     824 
     825/** 
     826 * @brief performs a masked bit register equals 0 check on the global parameter space 
     827 * @return true if readGlobalReg(offset) & mask == 0 
     828 */ 
     829bool 
     830DiceAvDevice::maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) { 
     831    fb_quadlet_t result; 
     832    readGlobalReg(offset, &result); 
     833    return ((result & mask) == 0); 
     834
     835/** 
     836 * @brief performs a masked bit register not equal to 0 check on the global parameter space 
     837 * @return true if readGlobalReg(offset) & mask != 0 
     838 */ 
     839bool 
     840DiceAvDevice::maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) { 
     841    return !maskedCheckZeroGlobalReg(offset, mask); 
     842
     843 
     844DiceAvDevice::diceNameVector 
     845DiceAvDevice::getTxNameString(unsigned int i) { 
     846    diceNameVector names; 
     847    char namestring[DICE_TX_NAMES_SIZE*4+1]; 
     848     
     849    if (!readTxRegBlock(i, DICE_REGISTER_TX_NAMES_BASE,  
     850                        (fb_quadlet_t *)namestring, DICE_TX_NAMES_SIZE*4)) { 
     851        debugError("Could not read TX name string \n"); 
     852        return names; 
     853    } 
     854     
     855    namestring[DICE_TX_NAMES_SIZE*4]='\0'; 
     856    return splitNameString(std::string(namestring)); 
     857
     858 
     859DiceAvDevice::diceNameVector 
     860DiceAvDevice::getRxNameString(unsigned int i) { 
     861    diceNameVector names; 
     862    char namestring[DICE_RX_NAMES_SIZE*4+1]; 
     863     
     864    if (!readRxRegBlock(i, DICE_REGISTER_RX_NAMES_BASE,  
     865                        (fb_quadlet_t *)namestring, DICE_RX_NAMES_SIZE*4)) { 
     866        debugError("Could not read RX name string \n"); 
     867        return names; 
     868    } 
     869     
     870    namestring[DICE_RX_NAMES_SIZE*4]='\0'; 
     871    return splitNameString(std::string(namestring)); 
     872
     873 
     874DiceAvDevice::diceNameVector 
     875DiceAvDevice::getClockSourceNameString() { 
     876    diceNameVector names; 
     877    char namestring[DICE_CLOCKSOURCENAMES_SIZE*4+1]; 
     878     
     879    if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_CLOCKSOURCENAMES,  
     880                        (fb_quadlet_t *)namestring, DICE_CLOCKSOURCENAMES_SIZE*4)) { 
     881        debugError("Could not read CLOCKSOURCE name string \n"); 
     882        return names; 
     883    } 
     884     
     885    namestring[DICE_CLOCKSOURCENAMES_SIZE*4]='\0'; 
     886    return splitNameString(std::string(namestring)); 
     887
     888 
     889std::string 
     890DiceAvDevice::getDeviceNickName() { 
     891    char namestring[DICE_NICK_NAME_SIZE*4+1]; 
     892     
     893    if (!readGlobalRegBlock(DICE_REGISTER_GLOBAL_NICK_NAME,  
     894                        (fb_quadlet_t *)namestring, DICE_NICK_NAME_SIZE*4)) { 
     895        debugError("Could not read nickname string \n"); 
     896        return std::string("(unknown)"); 
     897    } 
     898     
     899    namestring[DICE_NICK_NAME_SIZE*4]='\0'; 
     900    return std::string(namestring); 
     901
     902 
     903DiceAvDevice::diceNameVector 
     904DiceAvDevice::splitNameString(std::string in) { 
     905    diceNameVector names; 
     906 
     907    // find the end of the string 
     908    unsigned int end=in.find_first_of("\\\\"); 
     909    // cut the end 
     910    in=in.substr(0,end-2); 
     911 
     912    unsigned int cut; 
     913    while( (cut = in.find_first_of("\\")) != in.npos ) { 
     914        if(cut > 0) { 
     915            names.push_back(in.substr(0,cut)); 
     916        } 
     917        in = in.substr(cut+1); 
     918    } 
     919    if(in.length() > 0) { 
     920        names.push_back(in); 
     921    } 
     922    return names; 
     923
     924 
     925 
     926// I/O routines 
     927bool 
     928DiceAvDevice::initIoFunctions() { 
     929 
     930    if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_OFF, &m_global_reg_offset)) { 
     931        debugError("Could not initialize m_global_reg_offset\n"); 
     932        return false; 
     933    } 
     934    if(!readReg(DICE_REGISTER_GLOBAL_PAR_SPACE_SZ, &m_global_reg_size)) { 
     935        debugError("Could not initialize m_global_reg_size\n"); 
     936        return false; 
     937    } 
     938    if(!readReg(DICE_REGISTER_TX_PAR_SPACE_OFF, &m_tx_reg_offset)) { 
     939        debugError("Could not initialize m_tx_reg_offset\n"); 
     940        return false; 
     941    } 
     942    if(!readReg(DICE_REGISTER_TX_PAR_SPACE_SZ, &m_tx_reg_size)) { 
     943        debugError("Could not initialize m_tx_reg_size\n"); 
     944        return false; 
     945    } 
     946    if(!readReg(DICE_REGISTER_RX_PAR_SPACE_OFF, &m_rx_reg_offset)) { 
     947        debugError("Could not initialize m_rx_reg_offset\n"); 
     948        return false; 
     949    } 
     950    if(!readReg(DICE_REGISTER_RX_PAR_SPACE_SZ, &m_rx_reg_size)) { 
     951        debugError("Could not initialize m_rx_reg_size\n"); 
     952        return false; 
     953    } 
     954    if(!readReg(DICE_REGISTER_UNUSED1_SPACE_OFF, &m_unused1_reg_offset)) { 
     955        debugError("Could not initialize m_unused1_reg_offset\n"); 
     956        return false; 
     957    } 
     958    if(!readReg(DICE_REGISTER_UNUSED1_SPACE_SZ, &m_unused1_reg_size)) { 
     959        debugError("Could not initialize m_unused1_reg_size\n"); 
     960        return false; 
     961    } 
     962    if(!readReg(DICE_REGISTER_UNUSED2_SPACE_OFF, &m_unused2_reg_offset)) { 
     963        debugError("Could not initialize m_unused2_reg_offset\n"); 
     964        return false; 
     965    } 
     966    if(!readReg(DICE_REGISTER_UNUSED2_SPACE_SZ, &m_unused2_reg_size)) { 
     967        debugError("Could not initialize m_unused2_reg_size\n"); 
     968        return false; 
     969    } 
     970 
     971    if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_NB_TX, &m_nb_tx)) { 
     972        debugError("Could not initialize m_nb_tx\n"); 
     973        return false; 
     974    } 
     975    if(!readReg(m_tx_reg_offset + DICE_REGISTER_TX_SZ_TX, &m_tx_size)) { 
     976        debugError("Could not initialize m_tx_size\n"); 
     977        return false; 
     978    } 
     979    if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_NB_RX, &m_nb_rx)) { 
     980        debugError("Could not initialize m_nb_rx\n"); 
     981        return false; 
     982    } 
     983    if(!readReg(m_tx_reg_offset + DICE_REGISTER_RX_SZ_RX, &m_rx_size)) { 
     984        debugError("Could not initialize m_rx_size\n"); 
     985        return false; 
     986    } 
     987     
    200988    return true; 
    201989} 
    202990 
    203991bool 
    204 DiceAvDevice::stopStreamByIndex(int i) { 
    205  
    206     // TODO: connection management: break connection 
    207     // cfr the start function 
    208  
    209     // NOTE: this assumes that you have two streams 
    210     switch (i) { 
    211     case 0: 
    212         break; 
    213     case 1: 
    214         break; 
    215          
    216     default: // Invalid stream index 
    217         return false; 
    218     } 
    219  
     992DiceAvDevice::readReg(fb_nodeaddr_t offset, fb_quadlet_t *result) { 
     993    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading base register offset 0x%08llX\n", offset); 
     994     
     995    if(offset >= DICE_INVALID_OFFSET) { 
     996        debugError("invalid offset: 0x%016llX\n", offset); 
     997        return false; 
     998    } 
     999     
     1000    fb_nodeaddr_t addr=DICE_REGISTER_BASE + offset; 
     1001    fb_nodeid_t nodeId=m_nodeId | 0xFFC0; 
     1002     
     1003    if(!m_p1394Service->read_quadlet( nodeId, addr, result ) ) { 
     1004        debugError("Could not read from node 0x%04X addr 0x%012X\n", nodeId, addr); 
     1005        return false; 
     1006    } 
     1007    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Read result: 0x%08X\n", *result); 
     1008    
    2201009    return true; 
    2211010} 
    2221011 
    223 signed int DiceAvDevice::getIsoRecvChannel(void) { 
    224     return m_iso_recv_channel; 
    225 
    226  
    227 signed int DiceAvDevice::getIsoSendChannel(void) { 
    228     return m_iso_send_channel; 
    229 
    230  
    231 
     1012bool 
     1013DiceAvDevice::writeReg(fb_nodeaddr_t offset, fb_quadlet_t data) { 
     1014    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08llX, data: 0x%08X\n",   
     1015        offset, data); 
     1016     
     1017    if(offset >= DICE_INVALID_OFFSET) { 
     1018        debugError("invalid offset: 0x%016llX\n", offset); 
     1019        return false; 
     1020    } 
     1021     
     1022    fb_nodeaddr_t addr=DICE_REGISTER_BASE + offset; 
     1023    fb_nodeid_t nodeId=m_nodeId | 0xFFC0; 
     1024     
     1025    if(!m_p1394Service->write_quadlet( nodeId, addr, data ) ) { 
     1026        debugError("Could not write to node 0x%04X addr 0x%012X\n", nodeId, addr); 
     1027        return false; 
     1028    } 
     1029    return true; 
     1030
     1031 
     1032bool  
     1033DiceAvDevice::readRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1034    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading base register offset 0x%08llX, length %u\n",  
     1035        offset, length); 
     1036     
     1037    if(offset >= DICE_INVALID_OFFSET) { 
     1038        debugError("invalid offset: 0x%016llX\n", offset); 
     1039        return false; 
     1040    } 
     1041     
     1042    fb_nodeaddr_t addr=DICE_REGISTER_BASE + offset; 
     1043    fb_nodeid_t nodeId=m_nodeId | 0xFFC0; 
     1044     
     1045    if(!m_p1394Service->read( nodeId, addr, length, data ) ) { 
     1046        debugError("Could not read from node 0x%04X addr 0x%012llX\n", nodeId, addr); 
     1047        return false; 
     1048    } 
     1049    return true; 
     1050
     1051 
     1052bool  
     1053DiceAvDevice::writeRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1054    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing base register offset 0x%08llX, length: %u\n",   
     1055        offset, length); 
     1056     
     1057    if(offset >= DICE_INVALID_OFFSET) { 
     1058        debugError("invalid offset: 0x%016llX\n", offset); 
     1059        return false; 
     1060    } 
     1061     
     1062    fb_nodeaddr_t addr=DICE_REGISTER_BASE + offset; 
     1063    fb_nodeid_t nodeId=m_nodeId | 0xFFC0; 
     1064 
     1065    if(!m_p1394Service->write( nodeId, addr, length, data ) ) { 
     1066        debugError("Could not write to node 0x%04X addr 0x%012llX\n", nodeId, addr); 
     1067        return false; 
     1068    } 
     1069    return true; 
     1070
     1071 
     1072bool 
     1073DiceAvDevice::readGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t *result) { 
     1074    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register offset 0x%04llX\n", offset); 
     1075 
     1076    fb_nodeaddr_t offset_gl=globalOffsetGen(offset, sizeof(fb_quadlet_t)); 
     1077    return readReg(m_global_reg_offset + offset_gl, result); 
     1078
     1079 
     1080bool 
     1081DiceAvDevice::writeGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t data) { 
     1082    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register offset 0x%08llX, data: 0x%08X\n",   
     1083        offset, data); 
     1084 
     1085    fb_nodeaddr_t offset_gl=globalOffsetGen(offset, sizeof(fb_quadlet_t)); 
     1086    return writeReg(m_global_reg_offset + offset_gl, data); 
     1087
     1088 
     1089bool  
     1090DiceAvDevice::readGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1091    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading global register block offset 0x%04llX, length %u bytes\n",  
     1092        offset, length); 
     1093 
     1094    fb_nodeaddr_t offset_gl=globalOffsetGen(offset, length); 
     1095    return readRegBlock(m_global_reg_offset + offset_gl, data, length); 
     1096
     1097 
     1098bool  
     1099DiceAvDevice::writeGlobalRegBlock(fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1100    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing global register block offset 0x%04llX, length %u bytes\n",  
     1101        offset, length); 
     1102 
     1103    fb_nodeaddr_t offset_gl=globalOffsetGen(offset, length); 
     1104    return writeRegBlock(m_global_reg_offset + offset_gl, data, length); 
     1105
     1106 
     1107fb_nodeaddr_t  
     1108DiceAvDevice::globalOffsetGen(fb_nodeaddr_t offset, size_t length) { 
     1109 
     1110    // registry offsets should always be smaller than 0x7FFFFFFF 
     1111    // because otherwise base + offset > 64bit 
     1112    if(m_global_reg_offset & 0x80000000) { 
     1113        debugError("register offset not initialized yet\n"); 
     1114        return DICE_INVALID_OFFSET; 
     1115    } 
     1116    // out-of-range check 
     1117    if(offset + length > m_global_reg_size) { 
     1118        debugError("register offset+length too large: 0x%0llX\n", offset + length); 
     1119        return DICE_INVALID_OFFSET; 
     1120    } 
     1121     
     1122    return offset; 
     1123
     1124 
     1125bool 
     1126DiceAvDevice::readTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) { 
     1127    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading tx %d register offset 0x%04llX\n", i, offset); 
     1128     
     1129    fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, sizeof(fb_quadlet_t)); 
     1130    return readReg(m_tx_reg_offset + offset_tx, result); 
     1131
     1132 
     1133bool 
     1134DiceAvDevice::writeTxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) { 
     1135    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing tx %d register offset 0x%08llX, data: 0x%08X\n", 
     1136        i, offset, data); 
     1137 
     1138    fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, sizeof(fb_quadlet_t)); 
     1139    return writeReg(m_tx_reg_offset + offset_tx, data); 
     1140
     1141 
     1142bool  
     1143DiceAvDevice::readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1144    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04llX, length %u bytes\n",  
     1145        offset, length); 
     1146     
     1147    fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length); 
     1148    return readRegBlock(m_tx_reg_offset + offset_tx, data, length); 
     1149
     1150 
     1151bool  
     1152DiceAvDevice::writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1153    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04llX, length %u bytes\n",  
     1154        offset, length); 
     1155 
     1156    fb_nodeaddr_t offset_tx=txOffsetGen(i, offset, length); 
     1157    return writeRegBlock(m_tx_reg_offset + offset_tx, data, length); 
     1158
     1159 
     1160fb_nodeaddr_t  
     1161DiceAvDevice::txOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) { 
     1162    // registry offsets should always be smaller than 0x7FFFFFFF 
     1163    // because otherwise base + offset > 64bit 
     1164    if(m_tx_reg_offset & 0x80000000) { 
     1165        debugError("register offset not initialized yet\n"); 
     1166        return DICE_INVALID_OFFSET; 
     1167    } 
     1168    if(m_nb_tx & 0x80000000) { 
     1169        debugError("m_nb_tx not initialized yet\n"); 
     1170        return DICE_INVALID_OFFSET; 
     1171    } 
     1172    if(m_tx_size & 0x80000000) { 
     1173        debugError("m_tx_size not initialized yet\n"); 
     1174        return DICE_INVALID_OFFSET; 
     1175    } 
     1176    if(i >= m_nb_rx) { 
     1177        debugError("TX index out of range\n"); 
     1178        return DICE_INVALID_OFFSET; 
     1179    } 
     1180 
     1181    fb_nodeaddr_t offset_tx = DICE_REGISTER_TX_PARAM(m_tx_size, i, offset); 
     1182 
     1183    // out-of-range check 
     1184    if(offset_tx + length > m_tx_reg_size) { 
     1185        debugError("register offset+length too large: 0x%0llX\n", offset_tx + length); 
     1186        return DICE_INVALID_OFFSET; 
     1187    } 
     1188 
     1189    return offset_tx; 
     1190
     1191 
     1192bool 
     1193DiceAvDevice::readRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *result) { 
     1194    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx %d register offset 0x%04llX\n", i, offset); 
     1195     
     1196    fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t)); 
     1197    return readReg(m_rx_reg_offset + offset_rx, result); 
     1198
     1199 
     1200bool 
     1201DiceAvDevice::writeRxReg(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t data) { 
     1202    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register offset 0x%08llX, data: 0x%08X\n",   
     1203        offset, data); 
     1204         
     1205    fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, sizeof(fb_quadlet_t)); 
     1206    return writeReg(m_rx_reg_offset + offset_rx, data); 
     1207
     1208 
     1209bool  
     1210DiceAvDevice::readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1211    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Reading rx register block offset 0x%04llX, length %u bytes\n",  
     1212        offset, length); 
     1213     
     1214    fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length); 
     1215    return readRegBlock(m_rx_reg_offset + offset_rx, data, length); 
     1216
     1217 
     1218bool  
     1219DiceAvDevice::writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length) { 
     1220    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Writing rx register block offset 0x%04llX, length %u bytes\n",  
     1221        offset, length); 
     1222 
     1223    fb_nodeaddr_t offset_rx=rxOffsetGen(i, offset, length); 
     1224    return writeRegBlock(m_rx_reg_offset + offset_rx, data, length); 
     1225
     1226 
     1227fb_nodeaddr_t  
     1228DiceAvDevice::rxOffsetGen(unsigned int i, fb_nodeaddr_t offset, size_t length) { 
     1229    // registry offsets should always be smaller than 0x7FFFFFFF 
     1230    // because otherwise base + offset > 64bit 
     1231    if(m_rx_reg_offset & 0x80000000) { 
     1232        debugError("register offset not initialized yet\n"); 
     1233        return DICE_INVALID_OFFSET; 
     1234    } 
     1235    if(m_nb_rx & 0x80000000) { 
     1236        debugError("m_nb_rx not initialized yet\n"); 
     1237        return DICE_INVALID_OFFSET; 
     1238    } 
     1239    if(m_rx_size & 0x80000000) { 
     1240        debugError("m_rx_size not initialized yet\n"); 
     1241        return DICE_INVALID_OFFSET; 
     1242    } 
     1243    if(i >= m_nb_rx) { 
     1244        debugError("RX index out of range\n"); 
     1245        return DICE_INVALID_OFFSET; 
     1246    } 
     1247 
     1248    fb_nodeaddr_t offset_rx = DICE_REGISTER_RX_PARAM(m_rx_size, i, offset); 
     1249 
     1250    // out-of-range check 
     1251    if(offset_rx + length > m_rx_reg_size) { 
     1252        debugError("register offset+length too large: 0x%0llX\n", offset_rx + length); 
     1253        return DICE_INVALID_OFFSET; 
     1254    } 
     1255    return offset_rx; 
     1256
     1257 
     1258 
     1259// the notifier 
     1260 
     1261DiceAvDevice::DiceNotifier::DiceNotifier(DiceAvDevice *d, nodeaddr_t start) 
     1262 : ARMHandler(start, DICE_NOTIFIER_BLOCK_LENGTH,  
     1263              RAW1394_ARM_READ | RAW1394_ARM_WRITE | RAW1394_ARM_LOCK, 
     1264              RAW1394_ARM_WRITE, 0) 
     1265 , m_dicedevice(d) 
     1266
     1267 
     1268
     1269 
     1270DiceAvDevice::DiceNotifier::~DiceNotifier()  
     1271
     1272 
     1273
     1274 
     1275
  • branches/streaming-rework/src/dice/dice_avdevice.h

    r426 r433  
    2525#include "debugmodule/debugmodule.h" 
    2626#include "libavc/avc_definitions.h" 
    27 #include "libfreebob/xmlparser.h" 
    2827 
    2928#include "libstreaming/AmdtpStreamProcessor.h" 
     29#include "libstreaming/AmdtpPort.h" 
     30#include "libieee1394/ARMHandler.h" 
     31 
     32#include <string> 
     33#include <vector> 
    3034 
    3135class ConfigRom; 
     
    3337 
    3438namespace Dice { 
     39 
     40class DiceNotifier; 
    3541 
    3642// struct to define the supported devices 
     
    4349 
    4450class DiceAvDevice : public IAvDevice { 
     51private: 
     52    class DiceNotifier; 
    4553public: 
    4654    DiceAvDevice( std::auto_ptr<ConfigRom>( configRom ), 
    47              Ieee1394Service& ieee1394Service, 
    48                  int nodeId); 
     55                  Ieee1394Service& ieee1394Service, 
     56                  int nodeId); 
    4957    ~DiceAvDevice(); 
    5058 
     
    6775    bool startStreamByIndex(int i); 
    6876    bool stopStreamByIndex(int i); 
    69  
    70     signed int getIsoRecvChannel(void); 
    71     signed int getIsoSendChannel(void); 
    7277   
    7378protected: 
     79    std::auto_ptr<ConfigRom>( m_configRom ); 
     80    Ieee1394Service* m_p1394Service; 
     81     
    7482    struct VendorModelEntry *m_model; 
    7583     
    76     signed int m_iso_recv_channel, m_iso_send_channel; 
     84    // streaming stuff 
     85    typedef std::vector< Streaming::StreamProcessor * > StreamProcessorVector; 
     86    StreamProcessorVector m_receiveProcessors; 
     87    StreamProcessorVector m_transmitProcessors; 
    7788     
    78         Streaming::AmdtpReceiveStreamProcessor *m_receiveProcessor; 
    79         Streaming::AmdtpTransmitStreamProcessor *m_transmitProcessor; 
     89private: // streaming & port helpers 
     90    enum EPortTypes { 
     91        ePT_Analog, 
     92        ePT_MIDI, 
     93    }; 
     94     
     95    typedef struct { 
     96        std::string name; 
     97        enum EPortTypes portType; 
     98        unsigned int streamPosition; 
     99        unsigned int streamLocation; 
     100    } diceChannelInfo;  
     101     
     102    bool addChannelToProcessor( diceChannelInfo *,  
     103                              Streaming::StreamProcessor *,  
     104                              Streaming::Port::E_Direction direction); 
     105     
     106    int allocateIsoChannel(unsigned int packet_size); 
     107    bool deallocateIsoChannel(int channel); 
     108     
     109private: // helper functions 
     110    bool enableIsoStreaming(); 
     111    bool disableIsoStreaming(); 
     112    bool isIsoStreamingEnabled(); 
     113     
     114    bool maskedCheckZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 
     115    bool maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask); 
     116     
     117    typedef std::vector< std::string > diceNameVector; 
     118    diceNameVector splitNameString(std::string in); 
     119    diceNameVector getTxNameString(unsigned int i); 
     120    diceNameVector getRxNameString(unsigned int i); 
     121    diceNameVector getClockSourceNameString(); 
     122    std::string getDeviceNickName(); 
     123     
     124private: // register I/O routines 
     125    bool initIoFunctions(); 
     126    // quadlet read/write routines 
     127    bool readReg(fb_nodeaddr_t, fb_quadlet_t *); 
     128    bool writeReg(fb_nodeaddr_t, fb_quadlet_t); 
     129    bool readRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     130    bool writeRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     131     
     132    bool readGlobalReg(fb_nodeaddr_t, fb_quadlet_t *); 
     133    bool writeGlobalReg(fb_nodeaddr_t, fb_quadlet_t); 
     134    bool readGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     135    bool writeGlobalRegBlock(fb_nodeaddr_t, fb_quadlet_t *, size_t); 
     136    fb_nodeaddr_t globalOffsetGen(fb_nodeaddr_t, size_t); 
     137     
     138    bool readTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 
     139    bool writeTxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 
     140    bool readTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     141    bool writeTxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     142    fb_nodeaddr_t txOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 
     143     
     144    bool readRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t *); 
     145    bool writeRxReg(unsigned int i, fb_nodeaddr_t, fb_quadlet_t); 
     146    bool readRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     147    bool writeRxRegBlock(unsigned int i, fb_nodeaddr_t offset, fb_quadlet_t *data, size_t length); 
     148    fb_nodeaddr_t rxOffsetGen(unsigned int, fb_nodeaddr_t, size_t); 
     149     
     150    fb_quadlet_t m_global_reg_offset; 
     151    fb_quadlet_t m_global_reg_size; 
     152    fb_quadlet_t m_tx_reg_offset; 
     153    fb_quadlet_t m_tx_reg_size; 
     154    fb_quadlet_t m_rx_reg_offset; 
     155    fb_quadlet_t m_rx_reg_size; 
     156    fb_quadlet_t m_unused1_reg_offset; 
     157    fb_quadlet_t m_unused1_reg_size; 
     158    fb_quadlet_t m_unused2_reg_offset; 
     159    fb_quadlet_t m_unused2_reg_size; 
     160     
     161    fb_quadlet_t m_nb_tx; 
     162    fb_quadlet_t m_tx_size; 
     163    fb_quadlet_t m_nb_rx; 
     164    fb_quadlet_t m_rx_size; 
     165     
     166private: 
     167    // notification 
     168    DiceNotifier *m_notifier; 
     169     
     170    /** 
     171     * this class reacts on the DICE device writing to the  
     172     * hosts notify address 
     173     */ 
     174    #define DICE_NOTIFIER_BASE_ADDRESS 0x0000FFFFE0000000ULL 
     175    #define DICE_NOTIFIER_BLOCK_LENGTH 4 
     176    class DiceNotifier : public ARMHandler 
     177    { 
     178    public: 
     179        DiceNotifier(DiceAvDevice *, nodeaddr_t start); 
     180        virtual ~DiceNotifier(); 
     181         
     182    private: 
     183        DiceAvDevice *m_dicedevice; 
     184    }; 
    80185 
    81186}; 
    82187 
    83188} 
    84  
    85189#endif 
  • branches/streaming-rework/src/dice/dice_defines.h

    r412 r433  
    2121#define DICEDEFINES_H 
    2222 
     23#define DICE_INVALID_OFFSET                  0xFFFFF00000000000ULL 
     24 
     25/* 
     26 * This header is based upon the DICE II driver specification 
     27 * version 1.0.7.0 and: 
     28 *  dicedriverExtStatus.h,v 1.2 2006/09/27 20:35:45 
     29 *  dicedriverInterface.h,v 1.1.1.1 2006/08/10 20:00:57 
     30 * 
     31 */ 
     32 
     33// Register addresses & offsets 
     34//  DICE_PRIVATE_SPACE registers 
     35#define DICE_REGISTER_BASE                  0x0000FFFFE0000000ULL 
     36 
     37#define DICE_REGISTER_GLOBAL_PAR_SPACE_OFF  0x0000 
     38#define DICE_REGISTER_GLOBAL_PAR_SPACE_SZ   0x0004 
     39#define DICE_REGISTER_TX_PAR_SPACE_OFF      0x0008 
     40#define DICE_REGISTER_TX_PAR_SPACE_SZ       0x000C 
     41#define DICE_REGISTER_RX_PAR_SPACE_OFF      0x0010 
     42#define DICE_REGISTER_RX_PAR_SPACE_SZ       0x0014 
     43#define DICE_REGISTER_UNUSED1_SPACE_OFF     0x0018 
     44#define DICE_REGISTER_UNUSED1_SPACE_SZ      0x001C 
     45#define DICE_REGISTER_UNUSED2_SPACE_OFF     0x0020 
     46#define DICE_REGISTER_UNUSED2_SPACE_SZ      0x0024 
     47 
     48//  GLOBAL_PAR_SPACE registers 
     49#define DICE_REGISTER_GLOBAL_OWNER              0x0000 
     50#define DICE_REGISTER_GLOBAL_NOTIFICATION       0x0008 
     51#define DICE_REGISTER_GLOBAL_NICK_NAME          0x000C 
     52#define DICE_REGISTER_GLOBAL_CLOCK_SELECT       0x004C 
     53#define DICE_REGISTER_GLOBAL_ENABLE             0x0050 
     54#define DICE_REGISTER_GLOBAL_STATUS             0x0054 
     55#define DICE_REGISTER_GLOBAL_EXTENDED_STATUS    0x0058 
     56#define DICE_REGISTER_GLOBAL_SAMPLE_RATE        0x005C 
     57#define DICE_REGISTER_GLOBAL_VERSION            0x0060 
     58#define DICE_REGISTER_GLOBAL_CLOCKCAPABILITIES  0x0064 
     59#define DICE_REGISTER_GLOBAL_CLOCKSOURCENAMES   0x0068 
     60 
     61//  TX_PAR_SPACE registers 
     62#define DICE_REGISTER_TX_NB_TX                  0x0000 
     63#define DICE_REGISTER_TX_SZ_TX                  0x0004 
     64 
     65#define DICE_REGISTER_TX_ISOC_BASE              0x0008 
     66#define DICE_REGISTER_TX_NB_AUDIO_BASE          0x000C 
     67#define DICE_REGISTER_TX_MIDI_BASE              0x0010 
     68#define DICE_REGISTER_TX_SPEED_BASE             0x0014 
     69#define DICE_REGISTER_TX_NAMES_BASE             0x0018 
     70#define DICE_REGISTER_TX_AC3_CAPABILITIES_BASE  0x0118 
     71#define DICE_REGISTER_TX_AC3_ENABLE_BASE        0x011C 
     72 
     73#define DICE_REGISTER_TX_PARAM(size, i, offset) \ 
     74            ( ((i) * (size) * 4ULL) + (offset) ) 
     75 
     76//  RX_PAR_SPACE registers 
     77#define DICE_REGISTER_RX_NB_RX                  0x0000 
     78#define DICE_REGISTER_RX_SZ_RX                  0x0004 
     79 
     80#define DICE_REGISTER_RX_ISOC_BASE              0x0008 
     81#define DICE_REGISTER_RX_SEQ_START_BASE         0x000C 
     82#define DICE_REGISTER_RX_NB_AUDIO_BASE          0x0010 
     83#define DICE_REGISTER_RX_MIDI_BASE              0x0014 
     84#define DICE_REGISTER_RX_NAMES_BASE             0x0018 
     85#define DICE_REGISTER_RX_AC3_CAPABILITIES_BASE  0x0118 
     86#define DICE_REGISTER_RX_AC3_ENABLE_BASE        0x011C 
     87 
     88#define DICE_REGISTER_RX_PARAM(size, i, offset) \ 
     89            ( ((i) * (size) * 4ULL) + (offset) ) 
     90 
     91// Register Bitfields 
     92//  GLOBAL_PAR_SPACE registers 
     93//   OWNER register defines 
     94#define DICE_OWNER_NO_OWNER 0xFFFF000000000000LLU 
     95 
     96//   NOTIFICATION register defines 
     97#define DICE_NOTIFY_RX_CFG_CHG_BIT      (1UL << 0) 
     98#define DICE_NOTIFY_TX_CFG_CHG_BIT      (1UL << 1) 
     99#define DICE_NOTIFY_DUP_ISOC_BIT        (1UL << 2) 
     100#define DICE_NOTIFY_BW_ERR_BIT          (1UL << 3) 
     101#define DICE_NOTIFY_LOCK_CHG_BIT        (1UL << 4) 
     102#define DICE_NOTIFY_CLOCK_ACCEPTED      (1UL << 5) 
     103 
     104// bits 6..15 are RESERVED 
     105 
     106// FIXME: 
     107// diceDriverInterface.h defines the following bitfield 
     108// that is undocumented by spec 1.0.7.0 
     109#define DICE_INTERFACE_CHG_BIT          (1UL << 6) 
     110 
     111// FIXME: 
     112// The spec 1.0.7.0 defines these as USER notifications 
     113// however diceDriverInterface.h defines these as 
     114// 'reserved bits for future system wide use'. 
     115#define DICE_NOTIFY_RESERVED1           (1UL << 16) 
     116#define DICE_NOTIFY_RESERVED2           (1UL << 17) 
     117#define DICE_NOTIFY_RESERVED3           (1UL << 18) 
     118#define DICE_NOTIFY_RESERVED4           (1UL << 19) 
     119 
     120// FIXME: 
     121// The spec 1.0.7.0 does not specify anything about 
     122// the format of the user messages 
     123// however diceDriverInterface.h indicates: 
     124// "When DD_NOTIFY_MESSAGE is set DD_NOTIFY_USER4 through  
     125//  DD_NOTIFY_USER11 are defined as an 8 bit message so  
     126//  you can have 256 seperate messages (like gray encoder  
     127//  movements)." 
     128 
     129#define DICE_NOTIFY_MESSAGE             (1UL << 20) 
     130#define DICE_NOTIFY_USER1               (1UL << 21) 
     131#define DICE_NOTIFY_USER2               (1UL << 22) 
     132#define DICE_NOTIFY_USER3               (1UL << 23) 
     133#define DICE_NOTIFY_USER4               (1UL << 24) 
     134#define DICE_NOTIFY_USER5               (1UL << 25) 
     135#define DICE_NOTIFY_USER6               (1UL << 26) 
     136#define DICE_NOTIFY_USER7               (1UL << 27) 
     137#define DICE_NOTIFY_USER8               (1UL << 28) 
     138#define DICE_NOTIFY_USER9               (1UL << 29) 
     139#define DICE_NOTIFY_USER10              (1UL << 30) 
     140#define DICE_NOTIFY_USER11              (1UL << 31) 
     141 
     142#define DICE_NOTIFY_USER_IS_MESSAGE(x) \ 
     143                ( ((x) & DICE_NOTIFY_MESSAGE) != 0 ) 
     144 
     145#define DICE_NOTIFY_USER_GET_MESSAGE(x) \ 
     146                ( ((x) >> 24 ) & 0xFF ) 
     147                 
     148//   NICK_NAME register 
     149 
     150// NOTE: in bytes 
     151#define DICE_NICK_NAME_SIZE             64 
     152 
     153//   CLOCK_SELECT register 
     154// Clock sources supported 
     155#define DICE_CLOCKSOURCE_AES1           0x00 
     156#define DICE_CLOCKSOURCE_AES2           0x01 
     157#define DICE_CLOCKSOURCE_AES3           0x02 
     158#define DICE_CLOCKSOURCE_AES4           0x03 
     159#define DICE_CLOCKSOURCE_AES_ANY        0x04 
     160#define DICE_CLOCKSOURCE_ADAT           0x05 
     161#define DICE_CLOCKSOURCE_TDIF           0x06 
     162#define DICE_CLOCKSOURCE_WC             0x07 
     163#define DICE_CLOCKSOURCE_ARX1           0x08 
     164#define DICE_CLOCKSOURCE_ARX2           0x09 
     165#define DICE_CLOCKSOURCE_ARX3           0x0A 
     166#define DICE_CLOCKSOURCE_ARX4           0x0B 
     167#define DICE_CLOCKSOURCE_INTERNAL       0x0C 
     168 
     169#define DICE_CLOCKSOURCE_MASK           0x0000FFFFLU 
     170#define DICE_GET_CLOCKSOURCE(reg)       (((reg) & DICE_CLOCKSOURCE_MASK)) 
     171#define DICE_SET_CLOCKSOURCE(reg,clk)   (((reg) & ~DICE_CLOCKSOURCE_MASK) | ((clk) & DICE_CLOCKSOURCE_MASK)) 
     172 
     173// Supported rates 
     174#define DICE_RATE_32K                   0x00 
     175#define DICE_RATE_44K1                  0x01 
     176#define DICE_RATE_48K                   0x02 
     177#define DICE_RATE_88K2                  0x03 
     178#define DICE_RATE_96K                   0x04 
     179#define DICE_RATE_176K4                 0x05 
     180#define DICE_RATE_192K                  0x06 
     181#define DICE_RATE_ANY_LOW               0x07 
     182#define DICE_RATE_ANY_MID               0x08 
     183#define DICE_RATE_ANY_HIGH              0x09 
     184#define DICE_RATE_NONE                  0x0A 
     185 
     186#define DICE_RATE_MASK                  0xFFFF0000LU 
     187#define DICE_GET_RATE(reg)              (((reg) & DICE_RATE_MASK) >> 8) 
     188#define DICE_SET_RATE(reg,rate)         (((reg) & ~DICE_RATE_MASK) | (((rate) << 8) & DICE_RATE_MASK) ) 
     189 
     190//   ENABLE register 
     191#define DICE_ISOSTREAMING_ENABLE        (1UL << 0) 
     192#define DICE_ISOSTREAMING_DISABLE       (0) 
     193 
     194 
     195//   CLOCK_STATUS register 
     196#define DICE_STATUS_SOURCE_LOCKED       (1UL << 0) 
     197#define DICE_STATUS_RATE_CONFLICT       (1UL << 1) 
     198 
     199#define DICE_STATUS_GET_NOMINAL_RATE(x) ( ((x) >> 8 ) & 0xFF ) 
     200 
     201//   EXTENDED_STATUS register 
     202#define DICE_EXT_STATUS_AES0_LOCKED         (1UL << 0) 
     203#define DICE_EXT_STATUS_AES1_LOCKED         (1UL << 1) 
     204#define DICE_EXT_STATUS_AES2_LOCKED         (1UL << 2) 
     205#define DICE_EXT_STATUS_AES3_LOCKED         (1UL << 3) 
     206#define DICE_EXT_STATUS_ADAT_LOCKED         (1UL << 4) 
     207#define DICE_EXT_STATUS_TDIF_LOCKED         (1UL << 5) 
     208#define DICE_EXT_STATUS_ARX1_LOCKED         (1UL << 6) 
     209#define DICE_EXT_STATUS_ARX2_LOCKED         (1UL << 7) 
     210#define DICE_EXT_STATUS_ARX3_LOCKED         (1UL << 8) 
     211#define DICE_EXT_STATUS_ARX4_LOCKED         (1UL << 9) 
     212 
     213// FIXME: this one is missing in dicedriverExtStatus.h 
     214#define DICE_EXT_STATUS_WORDCLOCK_LOCKED    (1UL << 10) 
     215 
     216#define DICE_EXT_STATUS_AES0_SLIP           (1UL << 16) 
     217#define DICE_EXT_STATUS_AES1_SLIP           (1UL << 17) 
     218#define DICE_EXT_STATUS_AES2_SLIP           (1UL << 18) 
     219#define DICE_EXT_STATUS_AES3_SLIP           (1UL << 19) 
     220#define DICE_EXT_STATUS_ADAT_SLIP           (1UL << 20) 
     221#define DICE_EXT_STATUS_TDIF_SLIP           (1UL << 21) 
     222#define DICE_EXT_STATUS_ARX1_SLIP           (1UL << 22) 
     223#define DICE_EXT_STATUS_ARX2_SLIP           (1UL << 23) 
     224#define DICE_EXT_STATUS_ARX3_SLIP           (1UL << 24) 
     225#define DICE_EXT_STATUS_ARX4_SLIP           (1UL << 25) 
     226 
     227//   SAMPLE_RATE register 
     228// nothing here 
     229 
     230//   VERSION register 
     231#define DICE_DRIVER_SPEC_VERSION_NUMBER_GET(x,y) \ 
     232            ( ( (x) >> (y)) & 0xFF ) 
     233 
     234#define DICE_DRIVER_SPEC_VERSION_NUMBER_GET_A(x) \ 
     235            DICE_DRIVER_SPEC_VERSION_NUMBER_GET(x,24) 
     236 
     237#define DICE_DRIVER_SPEC_VERSION_NUMBER_GET_B(x) \ 
     238            DICE_DRIVER_SPEC_VERSION_NUMBER_GET(x,16) 
     239 
     240#define DICE_DRIVER_SPEC_VERSION_NUMBER_GET_C(x) \ 
     241            DICE_DRIVER_SPEC_VERSION_NUMBER_GET(x,8) 
     242 
     243#define DICE_DRIVER_SPEC_VERSION_NUMBER_GET_D(x) \ 
     244            DICE_DRIVER_SPEC_VERSION_NUMBER_GET(x,0) 
     245 
     246//   CLOCKCAPABILITIES register 
     247#define DICE_CLOCKCAP_RATE_32K          (1UL << 0) 
     248#define DICE_CLOCKCAP_RATE_44K1         (1UL << 1) 
     249#define DICE_CLOCKCAP_RATE_48K          (1UL << 2) 
     250#define DICE_CLOCKCAP_RATE_88K2         (1UL << 3) 
     251#define DICE_CLOCKCAP_RATE_96K          (1UL << 4) 
     252#define DICE_CLOCKCAP_RATE_176K4        (1UL << 5) 
     253#define DICE_CLOCKCAP_RATE_192K         (1UL << 6) 
     254#define DICE_CLOCKCAP_SOURCE_AES1       (1UL << 16) 
     255#define DICE_CLOCKCAP_SOURCE_AES2       (1UL << 17) 
     256#define DICE_CLOCKCAP_SOURCE_AES3       (1UL << 18) 
     257#define DICE_CLOCKCAP_SOURCE_AES4       (1UL << 19) 
     258#define DICE_CLOCKCAP_SOURCE_AES_ANY    (1UL << 20) 
     259#define DICE_CLOCKCAP_SOURCE_ADAT       (1UL << 21) 
     260#define DICE_CLOCKCAP_SOURCE_TDIF       (1UL << 22) 
     261#define DICE_CLOCKCAP_SOURCE_WORDCLOCK  (1UL << 23) 
     262#define DICE_CLOCKCAP_SOURCE_ARX1       (1UL << 24) 
     263#define DICE_CLOCKCAP_SOURCE_ARX2       (1UL << 25) 
     264#define DICE_CLOCKCAP_SOURCE_ARX3       (1UL << 26) 
     265#define DICE_CLOCKCAP_SOURCE_ARX4       (1UL << 27) 
     266#define DICE_CLOCKCAP_SOURCE_INTERNAL   (1UL << 28) 
     267 
     268//   CLOCKSOURCENAMES 
     269// note: in bytes 
     270#define DICE_CLOCKSOURCENAMES_SIZE      256 
     271 
     272//  TX_PAR_SPACE registers 
     273// note: in bytes 
     274#define DICE_TX_NAMES_SIZE              256 
     275 
     276//  RX_PAR_SPACE registers 
     277// note: in bytes 
     278#define DICE_RX_NAMES_SIZE              256 
     279 
    23280#endif // DICEDEFINES_H