Changeset 433
- Timestamp:
- 03/11/07 06:15:41 (16 years ago)
- Files:
-
- branches/streaming-rework/src/dice/dice_avdevice.cpp (modified) (11 diffs)
- branches/streaming-rework/src/dice/dice_avdevice.h (modified) (4 diffs)
- branches/streaming-rework/src/dice/dice_defines.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/streaming-rework/src/dice/dice_avdevice.cpp
r426 r433 18 18 * MA 02111-1307 USA. 19 19 */ 20 #warning DICE support is currently u seless20 #warning DICE support is currently untested 21 21 22 22 #include "dice/dice_avdevice.h" … … 36 36 #include <libraw1394/csr.h> 37 37 38 #include <iostream> 39 #include <sstream> 40 38 41 39 42 namespace Dice { … … 48 51 Ieee1394Service& ieee1394service, 49 52 int nodeId ) 50 : 53 : IAvDevice( configRom, ieee1394service, nodeId ) 51 54 , 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) 54 70 { 55 71 debugOutput( DEBUG_LEVEL_VERBOSE, "Created Dice::DiceAvDevice (NodeID %d)\n", … … 60 76 DiceAvDevice::~DiceAvDevice() 61 77 { 62 78 // FIXME: clean up m_receiveProcessors & xmit 79 80 if (m_notifier) { 81 unlock(); 82 } 63 83 } 64 84 … … 87 107 DiceAvDevice::discover() 88 108 { 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(); 91 111 92 112 for ( unsigned int i = 0; … … 102 122 } 103 123 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; 111 138 } 112 139 113 140 int 114 141 DiceAvDevice::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); 116 168 } 117 169 … … 119 171 DiceAvDevice::setSamplingFrequency( ESamplingFrequency samplingFrequency ) 120 172 { 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; 123 250 } 124 251 … … 131 258 } 132 259 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. 133 276 bool 134 277 DiceAvDevice::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 } 136 452 return true; 137 453 } 138 454 139 455 bool 456 DiceAvDevice::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 509 bool 140 510 DiceAvDevice::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 } 141 561 142 562 return true; … … 146 566 bool 147 567 DiceAvDevice::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; 148 597 149 598 return true; 150 599 } 151 600 152 int 601 int 153 602 DiceAvDevice::getStreamCount() { 154 return 0; // one receive, one transmit603 return m_receiveProcessors.size() + m_transmitProcessors.size(); 155 604 } 156 605 … … 158 607 DiceAvDevice::getStreamProcessorByIndex(int i) { 159 608 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 169 615 return NULL; 170 616 } … … 173 619 DiceAvDevice::startStreamByIndex(int i) { 174 620 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, ®_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, ®_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 708 bool 709 DiceAvDevice::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, ®_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, ®_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 790 int 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 801 bool DiceAvDevice::deallocateIsoChannel(int channel) { 802 debugOutput(DEBUG_LEVEL_VERBOSE, "freeing channel %d\n",channel); 803 return m_p1394Service->freeIsoChannel(channel); 804 } 805 806 bool 807 DiceAvDevice::enableIsoStreaming() { 808 return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_ENABLE); 809 } 810 811 bool 812 DiceAvDevice::disableIsoStreaming() { 813 return writeGlobalReg(DICE_REGISTER_GLOBAL_ENABLE, DICE_ISOSTREAMING_DISABLE); 814 } 815 816 bool 817 DiceAvDevice::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 */ 829 bool 830 DiceAvDevice::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 */ 839 bool 840 DiceAvDevice::maskedCheckNotZeroGlobalReg(fb_nodeaddr_t offset, fb_quadlet_t mask) { 841 return !maskedCheckZeroGlobalReg(offset, mask); 842 } 843 844 DiceAvDevice::diceNameVector 845 DiceAvDevice::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 859 DiceAvDevice::diceNameVector 860 DiceAvDevice::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 874 DiceAvDevice::diceNameVector 875 DiceAvDevice::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 889 std::string 890 DiceAvDevice::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 903 DiceAvDevice::diceNameVector 904 DiceAvDevice::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 927 bool 928 DiceAvDevice::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 200 988 return true; 201 989 } 202 990 203 991 bool 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 992 DiceAvDevice::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 220 1009 return true; 221 1010 } 222 1011 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 } 1012 bool 1013 DiceAvDevice::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 1032 bool 1033 DiceAvDevice::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 1052 bool 1053 DiceAvDevice::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 1072 bool 1073 DiceAvDevice::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 1080 bool 1081 DiceAvDevice::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 1089 bool 1090 DiceAvDevice::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 1098 bool 1099 DiceAvDevice::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 1107 fb_nodeaddr_t 1108 DiceAvDevice::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 1125 bool 1126 DiceAvDevice::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 1133 bool 1134 DiceAvDevice::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 1142 bool 1143 DiceAvDevice::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 1151 bool 1152 DiceAvDevice::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 1160 fb_nodeaddr_t 1161 DiceAvDevice::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 1192 bool 1193 DiceAvDevice::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 1200 bool 1201 DiceAvDevice::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 1209 bool 1210 DiceAvDevice::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 1218 bool 1219 DiceAvDevice::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 1227 fb_nodeaddr_t 1228 DiceAvDevice::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 1261 DiceAvDevice::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 1270 DiceAvDevice::DiceNotifier::~DiceNotifier() 1271 { 1272 1273 } 1274 1275 } branches/streaming-rework/src/dice/dice_avdevice.h
r426 r433 25 25 #include "debugmodule/debugmodule.h" 26 26 #include "libavc/avc_definitions.h" 27 #include "libfreebob/xmlparser.h"28 27 29 28 #include "libstreaming/AmdtpStreamProcessor.h" 29 #include "libstreaming/AmdtpPort.h" 30 #include "libieee1394/ARMHandler.h" 31 32 #include <string> 33 #include <vector> 30 34 31 35 class ConfigRom; … … 33 37 34 38 namespace Dice { 39 40 class DiceNotifier; 35 41 36 42 // struct to define the supported devices … … 43 49 44 50 class DiceAvDevice : public IAvDevice { 51 private: 52 class DiceNotifier; 45 53 public: 46 54 DiceAvDevice( std::auto_ptr<ConfigRom>( configRom ), 47 48 55 Ieee1394Service& ieee1394Service, 56 int nodeId); 49 57 ~DiceAvDevice(); 50 58 … … 67 75 bool startStreamByIndex(int i); 68 76 bool stopStreamByIndex(int i); 69 70 signed int getIsoRecvChannel(void);71 signed int getIsoSendChannel(void);72 77 73 78 protected: 79 std::auto_ptr<ConfigRom>( m_configRom ); 80 Ieee1394Service* m_p1394Service; 81 74 82 struct VendorModelEntry *m_model; 75 83 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; 77 88 78 Streaming::AmdtpReceiveStreamProcessor *m_receiveProcessor; 79 Streaming::AmdtpTransmitStreamProcessor *m_transmitProcessor; 89 private: // 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 109 private: // 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 124 private: // 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 166 private: 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 }; 80 185 81 186 }; 82 187 83 188 } 84 85 189 #endif branches/streaming-rework/src/dice/dice_defines.h
r412 r433 21 21 #define DICEDEFINES_H 22 22 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 23 280 #endif // DICEDEFINES_H