Changeset 398

Show
Ignore:
Timestamp:
02/17/07 01:57:53 (17 years ago)
Author:
pieterpalmers
Message:

remove cycle timer prediction & DLL code from the IsoHandler?, as it is replaced by a raw1394 API call

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp

    r397 r398  
    368368    int64_t until_next=substractTicks(time_at_period,cycle_timer); 
    369369     
    370     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld, TPUS=%f\n", 
    371         time_at_period, cycle_timer, until_next, m_handler->getTicksPerUsec() 
     370    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld\n", 
     371        time_at_period, cycle_timer, until_next 
    372372        ); 
    373373     
     
    376376    // for absolute times, not the relative time we are 
    377377    // using here (which can also be negative). 
    378     return (int64_t)(((float)until_next) / m_handler->getTicksPerUsec()); 
     378    return (int64_t)(((float)until_next) / TICKS_PER_USEC); 
    379379} 
    380380 
    381381uint64_t AmdtpTransmitStreamProcessor::getTimeAtPeriodUsecs() { 
    382382    // then we should convert this into usecs 
    383     // FIXME: we assume that the TimeSource of the IsoHandler is 
    384     //        in usecs. 
    385     return m_handler->mapToTimeSource(getTimeAtPeriod()); 
     383    return (uint64_t)((float)getTimeAtPeriod() * TICKS_PER_USEC); 
    386384} 
    387385 
     
    10981096    int64_t until_next=substractTicks(time_at_period,cycle_timer); 
    10991097     
    1100     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld, TPUS=%f\n", 
    1101         time_at_period, cycle_timer, until_next, m_handler->getTicksPerUsec() 
     1098    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld\n", 
     1099        time_at_period, cycle_timer, until_next 
    11021100        ); 
    11031101     
     
    11061104    // for absolute times, not the relative time we are 
    11071105    // using here (which can also be negative). 
    1108     return (int64_t)(((float)until_next) / m_handler->getTicksPerUsec()); 
     1106    return (int64_t)(((float)until_next) / TICKS_PER_USEC); 
    11091107} 
    11101108 
    11111109uint64_t AmdtpReceiveStreamProcessor::getTimeAtPeriodUsecs() { 
    11121110    // then we should convert this into usecs 
    1113     // FIXME: we assume that the TimeSource of the IsoHandler is 
    1114     //        in usecs. 
    1115     return m_handler->mapToTimeSource(getTimeAtPeriod()); 
     1111    return (uint64_t)((float)getTimeAtPeriod()*TICKS_PER_USEC); 
    11161112} 
    11171113 
  • branches/streaming-rework/src/libstreaming/IsoHandler.cpp

    r397 r398  
    9393/* Base class implementation */ 
    9494IsoHandler::IsoHandler(int port) 
    95    : TimeSource(), m_handle(0), m_handle_util(0), m_port(port),  
     95   : m_handle(0), m_handle_util(0), m_port(port),  
    9696   m_buf_packets(400), m_max_packet_size(1024), m_irq_interval(-1), 
    97    m_cycletimer_ticks(0), m_lastmeas_usecs(0), m_ticks_per_usec(24.576),  
    98    m_ticks_per_usec_dll_err2(0), 
    9997   m_packetcount(0), m_dropped(0), m_Client(0), 
    100    m_State(E_Created), m_TimeSource_LastSecs(0),m_TimeSource_NbCycleWraps(0) 
    101 
    102     m_TimeSource=new FreebobUtil::SystemTimeSource(); 
     98   m_State(E_Created) 
     99
    103100} 
    104101 
    105102IsoHandler::IsoHandler(int port, unsigned int buf_packets, unsigned int max_packet_size, int irq) 
    106    : TimeSource(), m_handle(0), m_port(port),  
     103   : m_handle(0), m_port(port),  
    107104   m_buf_packets(buf_packets), m_max_packet_size( max_packet_size),  
    108105   m_irq_interval(irq),  
    109    m_cycletimer_ticks(0), m_lastmeas_usecs(0), m_ticks_per_usec(24.576), 
    110    m_ticks_per_usec_dll_err2(0), 
    111106   m_packetcount(0), m_dropped(0), m_Client(0), 
    112    m_State(E_Created), m_TimeSource_LastSecs(0),m_TimeSource_NbCycleWraps(0) 
    113 
    114     m_TimeSource=new FreebobUtil::SystemTimeSource(); 
     107   m_State(E_Created) 
     108
    115109} 
    116110 
     
    132126     
    133127    if(m_handle_util) raw1394_destroy_handle(m_handle_util); 
    134      
    135     if (m_TimeSource) delete m_TimeSource; 
     128 
    136129} 
    137130 
     
    202195    } 
    203196 
    204     // initialize the local timesource 
    205     m_TimeSource_NbCycleWraps=0; 
    206     unsigned int new_timer; 
    207      
    208 #ifdef LIBRAW1394_USE_CTRREAD_API 
    209     struct raw1394_cycle_timer ctr; 
     197    // test the cycle timer read function 
    210198    int err; 
    211     err=raw1394_read_cycle_timer(m_handle_util, &ctr); 
     199    uint32_t cycle_timer; 
     200    uint64_t local_time; 
     201    err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time); 
    212202    if(err) { 
    213203        debugError("raw1394_read_cycle_timer failed.\n"); 
     
    216206        return false; 
    217207    } 
    218     new_timer=ctr.cycle_timer; 
    219 #else 
    220     // normally we should be able to use the same handle 
    221     // because it is not iterated on by any other stuff 
    222     // but I'm not sure 
    223     quadlet_t buf=0; 
    224     raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util),  
    225         CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
    226     new_timer= ntohl(buf) & 0xFFFFFFFF; 
    227 #endif 
    228  
    229     m_TimeSource_LastSecs=CYCLE_TIMER_GET_SECS(new_timer); 
    230  
    231     // update the cycle timer value for initial value 
    232     initCycleTimer(); 
    233208 
    234209    // update the internal state 
     
    292267     
    293268    m_State=E_Prepared; 
    294      
    295     return true; 
    296 } 
    297  
    298 bool 
    299 IsoHandler::setSyncMaster(FreebobUtil::TimeSource *t) 
    300 { 
    301     m_TimeSource=t; 
    302      
    303     // update the cycle timer value for initial value 
    304     initCycleTimer(); 
    305269     
    306270    return true; 
     
    316280    debugOutput( DEBUG_LEVEL_VERBOSE, "bus reset...\n"); 
    317281     
    318     // as busreset can elect a new cycle master, 
    319     // we need to re-initialize our timing code 
    320     initCycleTimer(); 
    321282     
    322283    return 0; 
     
    330291 
    331292unsigned int IsoHandler::getCycleTimerTicks() { 
    332  
    333 #ifdef LIBRAW1394_USE_CTRREAD_API 
    334293    // the new api should be realtime safe. 
    335294    // it might cause a reschedule when turning preemption, 
    336295    // back on but that won't hurt us if we have sufficient  
    337296    // priority  
    338     struct raw1394_cycle_timer ctr; 
    339297    int err; 
    340     err=raw1394_read_cycle_timer(m_handle_util, &ctr); 
     298    uint32_t cycle_timer; 
     299    uint64_t local_time; 
     300    err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time); 
    341301    if(err) { 
    342302        debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 
    343303    } 
    344     return CYCLE_TIMER_TO_TICKS((uint32_t)ctr.cycle_timer); 
    345  
    346 #else 
    347     // use the estimated version 
    348     freebob_microsecs_t now; 
    349     now=m_TimeSource->getCurrentTimeAsUsecs(); 
    350     return mapToCycleTimer(now); 
    351 #endif  
    352  
     304    return CYCLE_TIMER_TO_TICKS(cycle_timer); 
    353305} 
    354306 
     
    360312 
    361313unsigned int IsoHandler::getCycleTimer() { 
    362  
    363 #ifdef LIBRAW1394_USE_CTRREAD_API 
    364314    // the new api should be realtime safe. 
    365315    // it might cause a reschedule when turning preemption, 
    366316    // back on but that won't hurt us if we have sufficient  
    367317    // priority  
    368     struct raw1394_cycle_timer ctr; 
    369318    int err; 
    370     err=raw1394_read_cycle_timer(m_handle_util, &ctr); 
     319    uint32_t cycle_timer; 
     320    uint64_t local_time; 
     321    err=raw1394_read_cycle_timer(m_handle_util, &cycle_timer, &local_time); 
    371322    if(err) { 
    372323        debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 
    373324    } 
    374     return ctr.cycle_timer; 
    375  
    376 #else 
    377     // use the estimated version 
    378     freebob_microsecs_t now; 
    379     now=m_TimeSource->getCurrentTimeAsUsecs(); 
    380     return TICKS_TO_CYCLE_TIMER(mapToCycleTimer(now)); 
    381 #endif  
    382  
    383 
    384 /** 
    385  * Maps a value of the active TimeSource to a Cycle Timer value. 
    386  * 
    387  * This is usefull if you know a time value and want the corresponding 
    388  * Cycle Timer value. Note that the value shouldn't be too far off 
    389  * the current time, because then the mapping can be bad. 
    390  * 
    391  * @return the value of the cycle timer (in ticks) 
    392  */ 
    393  
    394 unsigned int IsoHandler::mapToCycleTimer(freebob_microsecs_t now) { 
    395  
    396     // linear interpolation 
    397     int delta_usecs=now-m_lastmeas_usecs; 
    398  
    399     float offset=m_ticks_per_usec * ((float)delta_usecs); 
    400  
    401     int64_t pred_ticks=(int64_t)m_cycletimer_ticks+(int64_t)offset; 
    402  
    403     if (pred_ticks < 0) { 
    404         debugWarning("Predicted ticks < 0\n"); 
    405     } 
    406     debugOutput(DEBUG_LEVEL_VERBOSE,"now=%llu, m_lastmeas_usec=%llu, delta_usec=%d\n", 
    407             now, m_lastmeas_usecs, delta_usecs); 
    408     debugOutput(DEBUG_LEVEL_VERBOSE,"t/usec=%f, offset=%f, m_cc_t=%llu, pred_ticks=%lld\n", 
    409             m_ticks_per_usec, offset, m_cycletimer_ticks, pred_ticks); 
    410  
    411     // if we need to wrap, do it 
    412     if (pred_ticks > TICKS_PER_SECOND * 128L) { 
    413         pred_ticks -= TICKS_PER_SECOND * 128L; 
    414     } 
    415      
    416     return pred_ticks; 
    417 
    418  
    419 /** 
    420  * Maps a Cycle Timer value (in ticks) of the active TimeSource's unit. 
    421  * 
    422  * This is usefull if you know a Cycle Timer value and want the corresponding 
    423  * timesource value. Note that the value shouldn't be too far off 
    424  * the current cycle timer, because then the mapping can be bad. 
    425  * 
    426  * @return the mapped value  
    427  */ 
    428  
    429 freebob_microsecs_t IsoHandler::mapToTimeSource(unsigned int cc) { 
    430  
    431     // linear interpolation 
    432     int delta_cc=cc-m_cycletimer_ticks; 
    433  
    434     float offset= ((float)delta_cc) / m_ticks_per_usec; 
    435  
    436     int64_t pred_time=(int64_t)m_lastmeas_usecs+(int64_t)offset; 
    437  
    438     if (pred_time < 0) { 
    439         debugWarning("Predicted time < 0\n"); 
    440         debugOutput(DEBUG_LEVEL_VERBOSE,"cc=%u, m_cycletimer_ticks=%llu, delta_cc=%d\n", 
    441                 cc, m_cycletimer_ticks, delta_cc); 
    442         debugOutput(DEBUG_LEVEL_VERBOSE,"t/usec=%f, offset=%f, m_lastmeas_usecs=%llu, pred_time=%lld\n", 
    443                 m_ticks_per_usec, offset, m_lastmeas_usecs, pred_time);     
    444     } 
    445  
    446  
    447     return pred_time; 
    448 
    449  
    450 bool IsoHandler::updateCycleTimer() { 
    451     freebob_microsecs_t prev_usecs=m_lastmeas_usecs; 
    452     uint64_t prev_ticks=m_cycletimer_ticks; 
    453      
    454     freebob_microsecs_t new_usecs; 
    455     uint64_t new_ticks; 
    456     unsigned int new_timer; 
    457      
    458     /* To estimate the cycle timer, we implement a  
    459        DLL based routine, that maps the cycle timer 
    460        on the system clock. 
    461         
    462        For more info, refer to: 
    463         "Using a DLL to filter time" 
    464         Fons Adriaensen 
    465          
    466         Can be found at: 
    467         http://users.skynet.be/solaris/linuxaudio/downloads/usingdll.pdf 
    468         or maybe at: 
    469         http://www.kokkinizita.net/linuxaudio 
    470      
    471         Basically what we do is estimate the next point (T1,CC1_est) 
    472         based upon the previous point (T0, CC0) and the estimated rate (R). 
    473         Then we compare our estimation with the measured cycle timer 
    474         at T1 (=CC1_meas). We then calculate the estimation error on R: 
    475         err=(CC1_meas-CC0)/(T1-T2) - (CC1_est-CC0)/(T1-T2) 
    476         and try to minimize this on average (DLL) 
    477          
    478         Note that in order to have a contignous mapping, we should 
    479         update CC0<=CC1_est instead of CC0<=CC1_meas. The measurement  
    480         serves only to correct the error 'on average'. 
    481          
    482         In the code, the following variable names are used: 
    483         T0=prev_usecs 
    484         T1=next_usecs 
    485          
    486         CC0=prev_ticks 
    487         CC1_est=est_ticks 
    488         CC1_meas=meas_ticks 
    489          
    490      */ 
    491 #ifdef LIBRAW1394_USE_CTRREAD_API 
    492     struct raw1394_cycle_timer ctr; 
    493     int err; 
    494     err=raw1394_read_cycle_timer(m_handle_util, &ctr); 
    495     if(err) { 
    496         debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 
    497     } 
    498     new_usecs=(freebob_microsecs_t)ctr.local_time; 
    499     new_timer=ctr.cycle_timer; 
    500 #else 
    501     // normally we should be able to use the same handle 
    502     // because it is not iterated on by any other stuff 
    503     // but I'm not sure 
    504     quadlet_t buf=0; 
    505     raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util),  
    506         CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
    507     new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 
    508     new_timer= ntohl(buf) & 0xFFFFFFFF; 
    509 #endif     
    510  
    511     new_ticks=CYCLE_TIMER_TO_TICKS(new_timer); 
    512  
    513     // the difference in system time 
    514     int64_t delta_usecs=new_usecs-prev_usecs; 
    515     // this cannot be 0, because m_TimeSource->getCurrentTimeAsUsecs should  
    516     // never return the same value (maybe in future terrahz processors?) 
    517     assert(delta_usecs); 
    518      
    519     // the measured cycle timer difference 
    520     int64_t delta_ticks_meas; 
    521     if (new_ticks >= prev_ticks) { 
    522         delta_ticks_meas=new_ticks - prev_ticks; 
    523     } else { // wraparound 
    524         delta_ticks_meas=CYCLE_TIMER_UNWRAP_TICKS(new_ticks) - prev_ticks; 
    525     } 
    526      
    527     // the estimated cycle timer difference 
    528     int64_t delta_ticks_est=(int64_t)(m_ticks_per_usec * ((float)delta_usecs)); 
    529      
    530     // the measured & estimated rate 
    531     float rate_meas=((double)delta_ticks_meas/(double)delta_usecs); 
    532     float rate_est=((float)m_ticks_per_usec); 
    533      
    534     // these make sure we don't update when the measurement is 
    535     // bad. We know the nominal rate, and it can't be that far 
    536     // off. The thing is that there is a problem in measuring 
    537     // both usecs and ticks at the same time (no provision in 
    538     // the kernel. 
    539     // We know that there are some tolerances on both 
    540     // the system clock and the firewire clock such that the  
    541     // actual difference is rather small. So we discard values  
    542     // that are too far from the nominal rate.  
    543     // Otherwise the DLL has to have a very low bandwidth, in  
    544     // order not to be desturbed too much by these bad measurements 
    545     // resulting in very slow locking. 
    546      
    547     if (   (rate_meas < 24.576*(1.0+CC_MAX_RATE_ERROR))  
    548         && (rate_meas > 24.576*(1.0-CC_MAX_RATE_ERROR))) { 
    549  
    550 #ifdef DEBUG 
    551  
    552         int64_t diff=(int64_t)delta_ticks_est; 
    553          
    554         // calculate the difference in predicted ticks and 
    555         // measured ticks 
    556         diff -= delta_ticks_meas; 
    557          
    558          
    559         if (diff > 24000L || diff < -24000L) { // approx +/-1 msec error 
    560             debugOutput(DEBUG_LEVEL_VERBOSE,"Bad pred (%p): diff=%lld, dt_est=%lld, dt_meas=%lld, d=%lldus, err=%fus\n", this, 
    561                 diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((float)diff)/24.576) 
    562                 ); 
    563         } else { 
    564             debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Good pred: diff=%lld, dt_est=%lld, dt_meas=%lld, d=%lldus, err=%fus\n", 
    565                 diff, delta_ticks_est, delta_ticks_meas, delta_usecs, (((float)diff)/24.576) 
    566                 ); 
    567         } 
    568 #endif 
    569         // DLL the error to obtain the rate. 
    570         // (note: the DLL makes the error=0) 
    571         // only update the DLL if the rate is within 10% of the expected 
    572         // rate 
    573         float err=rate_meas-rate_est; 
    574          
    575         // 2nd order DLL update 
    576 //         const float w=6.28*0.0001; 
    577 //         const float b=w*1.45; 
    578 //         const float c=w*w; 
    579 //          
    580 //         m_ticks_per_usec += b*err + m_ticks_per_usec_dll_err2; 
    581 //         m_ticks_per_usec_dll_err2 += c * err; 
    582  
    583         // first order DLL update 
    584          m_ticks_per_usec += CC_DLL_COEFF*err; 
    585      
    586         if (   (m_ticks_per_usec > 24.576*(1.0+CC_MAX_RATE_ERROR))  
    587             || (m_ticks_per_usec < 24.576*(1.0-CC_MAX_RATE_ERROR))) { 
    588             debugOutput(DEBUG_LEVEL_VERBOSE, "Warning: DLL ticks/usec near clipping (%8.4f)\n", 
    589                         m_ticks_per_usec); 
    590         } 
    591          
    592         // update the internal values 
    593         // note: the next cycletimer point is 
    594         //       the estimated one, not the measured one! 
    595         m_cycletimer_ticks += delta_ticks_est; 
    596         // if we need to wrap, do it 
    597         if (m_cycletimer_ticks > TICKS_PER_SECOND * 128L) { 
    598             m_cycletimer_ticks -= TICKS_PER_SECOND * 128L; 
    599         } 
    600  
    601         m_lastmeas_usecs = new_usecs; 
    602  
    603         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"U TS: %10llu -> %10llu, d=%7lldus, dt_est=%7lld,  dt_meas=%7lld, erate=%6.4f, mrate=%6f\n", 
    604               prev_ticks, m_cycletimer_ticks, delta_usecs, 
    605               delta_ticks_est, delta_ticks_meas, m_ticks_per_usec, rate_meas 
    606               ); 
    607  
    608         // the estimate is good 
    609         return true; 
    610     } else { 
    611         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"U TS: Not updating, rate out of range (%6.4f)\n", 
    612               rate_meas 
    613               ); 
    614         return false; 
    615  
    616     } 
    617 
    618  
    619 void IsoHandler::initCycleTimer() { 
    620     freebob_microsecs_t prev_usecs; 
    621     unsigned int prev_ticks; 
    622     unsigned int prev_timer; 
    623      
    624     freebob_microsecs_t new_usecs; 
    625     unsigned int new_ticks; 
    626     unsigned int new_timer; 
    627      
    628     float rate=0.0; 
    629      
    630     unsigned int try_cnt=0; 
    631      
    632     // make sure that we start with a decent rate, 
    633     // meaning that we want two successive (usecs,ticks) 
    634     // points that make sense. 
    635      
    636     while ( (try_cnt++ < CC_INIT_MAX_TRIES) && 
    637            (   (rate > 24.576*(1.0+CC_MAX_RATE_ERROR))  
    638            || (rate < 24.576*(1.0-CC_MAX_RATE_ERROR)))) { 
    639             
    640 #ifdef LIBRAW1394_USE_CTRREAD_API 
    641         struct raw1394_cycle_timer ctr; 
    642         int err; 
    643         err=raw1394_read_cycle_timer(m_handle_util, &ctr); 
    644         if(err) { 
    645             debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 
    646         } 
    647         prev_usecs=(freebob_microsecs_t)ctr.local_time; 
    648         prev_timer=ctr.cycle_timer; 
    649 #else 
    650         // normally we should be able to use the same handle 
    651         // because it is not iterated on by any other stuff 
    652         // but I'm not sure 
    653         quadlet_t buf=0; 
    654         raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util),  
    655             CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
    656         prev_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 
    657         prev_timer= ntohl(buf) & 0xFFFFFFFF; 
    658 #endif                
    659         prev_ticks=CYCLE_TIMER_TO_TICKS(prev_timer); 
    660          
    661         usleep(CC_SLEEP_TIME_AFTER_UPDATE); 
    662          
    663          
    664 #ifdef LIBRAW1394_USE_CTRREAD_API 
    665         err=raw1394_read_cycle_timer(m_handle_util, &ctr); 
    666         if(err) { 
    667             debugWarning("raw1394_read_cycle_timer: %s\n", strerror(err)); 
    668         } 
    669         new_usecs=(freebob_microsecs_t)ctr.local_time; 
    670         new_timer=ctr.cycle_timer; 
    671 #else 
    672         // normally we should be able to use the same handle 
    673         // because it is not iterated on by any other stuff 
    674         // but I'm not sure 
    675         raw1394_read(m_handle_util, raw1394_get_local_id(m_handle_util),  
    676             CSR_REGISTER_BASE | CSR_CYCLE_TIME, 4, &buf); 
    677         new_usecs=m_TimeSource->getCurrentTimeAsUsecs(); 
    678         new_timer= ntohl(buf) & 0xFFFFFFFF; 
    679 #endif     
    680  
    681         new_ticks=CYCLE_TIMER_TO_TICKS(new_timer); 
    682          
    683         unsigned int delta_ticks; 
    684          
    685         if (new_ticks > prev_ticks) { 
    686             delta_ticks=new_ticks - prev_ticks; 
    687         } else { // wraparound 
    688             delta_ticks=CYCLE_TIMER_UNWRAP_TICKS(new_ticks) - prev_ticks; 
    689         } 
    690          
    691         int delta_usecs=new_usecs-prev_usecs; 
    692          
    693         // this cannot be 0, because m_TimeSource->getCurrentTimeAsUsecs should  
    694         // never return the same value (maybe in future terrahz processors?) 
    695         assert(delta_usecs); 
    696          
    697         rate=((float)delta_ticks/(float)delta_usecs); 
    698          
    699         // update the internal values 
    700         m_cycletimer_ticks=new_ticks; 
    701         m_lastmeas_usecs=new_usecs; 
    702          
    703         debugOutput(DEBUG_LEVEL_VERBOSE,"Try %d: rate=%6.4f\n", 
    704             try_cnt,rate 
    705             ); 
    706  
    707     } 
    708      
    709     // this is not fatal, the DLL will eventually correct this 
    710     if(try_cnt == CC_INIT_MAX_TRIES) { 
    711         debugWarning("Failed to properly initialize cycle timer...\n"); 
    712     } 
    713      
    714     // initialize this to the nominal value 
    715     m_ticks_per_usec = 24.576; 
    716     m_ticks_per_usec_dll_err2 = 0; 
    717      
     325    return cycle_timer; 
    718326} 
    719327 
     
    730338    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Packet count    : %10d (%5d dropped)\n", 
    731339            this->getPacketCount(), this->getDroppedCount()); 
    732              
    733     #ifdef DEBUG 
    734     unsigned int cc=this->getCycleTimerTicks(); 
    735     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Cycle timer     : %10lu (%03us, %04ucycles, %04uticks)\n", 
    736             cc,TICKS_TO_SECS(cc),TICKS_TO_CYCLES(cc),TICKS_TO_OFFSET(cc)); 
    737               
    738 /*  freebob_microsecs_t now=m_TimeSource->getCurrentTimeAsUsecs(); 
    739     cc=mapToCycleTimer(now); 
    740     freebob_microsecs_t now_mapped=mapToTimeSource(cc); 
    741      
    742     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Mapping test   : now: %14llu, cc: %10lu, mapped now: %14llu\n", 
    743             now,cc,now_mapped);*/ 
    744     #endif 
    745     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Ticks/usec      : %8.6f (dll2: %8.6e)\n\n", 
    746             this->getTicksPerUsec(), m_ticks_per_usec_dll_err2); 
    747  
    748 }; 
     340
    749341 
    750342void IsoHandler::setVerboseLevel(int l) 
     
    787379 
    788380} 
    789  
    790 /* The timesource interface */ 
    791 freebob_microsecs_t IsoHandler::getCurrentTime() { 
    792     unsigned int new_timer; 
    793      
    794     new_timer= getCycleTimerTicks(); 
    795          
    796     // this assumes that it never happens that there are more than 2 
    797     // minutes between calls 
    798     if (CYCLE_TIMER_GET_SECS(new_timer) < m_TimeSource_LastSecs) { 
    799         m_TimeSource_NbCycleWraps++; 
    800     } 
    801      
    802     freebob_microsecs_t ticks=m_TimeSource_NbCycleWraps * 128L * TICKS_PER_SECOND 
    803             + CYCLE_TIMER_TO_TICKS(new_timer); 
    804      
    805     m_TimeSource_LastSecs=CYCLE_TIMER_GET_SECS(new_timer); 
    806      
    807     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Wraps=%4u, LastSecs=%3u, nowSecs=%3u, ticks=%10u\n", 
    808               m_TimeSource_NbCycleWraps, m_TimeSource_LastSecs, 
    809               CYCLE_TIMER_GET_SECS(new_timer), ticks 
    810               ); 
    811                
    812     return  ticks; 
    813 } 
    814  
    815 freebob_microsecs_t IsoHandler::unWrapTime(freebob_microsecs_t t) { 
    816     return CYCLE_TIMER_UNWRAP_TICKS(t); 
    817 } 
    818  
    819 freebob_microsecs_t IsoHandler::wrapTime(freebob_microsecs_t t) { 
    820     return CYCLE_TIMER_WRAP_TICKS(t); 
    821 } 
    822  
    823 freebob_microsecs_t IsoHandler::getCurrentTimeAsUsecs() { 
    824     float tmp=getCurrentTime(); 
    825     float tmp2 = tmp * USECS_PER_TICK; 
    826     freebob_microsecs_t retval=(freebob_microsecs_t)tmp2; 
    827      
    828     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"tmp=%f, tmp2=%f, retval=%u\n", 
    829               tmp, tmp2,retval 
    830               ); 
    831      
    832     return retval; 
    833 } 
    834  
    835  
    836381 
    837382/* Child class implementations */ 
  • branches/streaming-rework/src/libstreaming/IsoHandler.h

    r391 r398  
    3131#include "../debugmodule/debugmodule.h" 
    3232 
    33 #include "libutil/TimeSource.h" 
    34  
    3533#include <libraw1394/raw1394.h> 
    3634 
     
    5048*/ 
    5149 
    52 class IsoHandler : public FreebobUtil::TimeSource 
     50class IsoHandler 
    5351{ 
    5452    protected: 
     
    106104        /// get the most recent cycle timer value (as is) 
    107105        unsigned int getCycleTimer(); 
    108         /// Maps a value of the active TimeSource to a Cycle Timer value. 
    109         unsigned int mapToCycleTimer(freebob_microsecs_t now); 
    110         /// Maps a Cycle Timer value to the active TimeSource's unit. 
    111         freebob_microsecs_t mapToTimeSource(unsigned int cc); 
    112         /// update the cycle timer cache 
    113         bool updateCycleTimer(); 
    114         float getTicksPerUsec() {return m_ticks_per_usec;}; 
    115  
    116         // register a master timing source 
    117         bool setSyncMaster(FreebobUtil::TimeSource *t); 
    118      
     106 
    119107    protected: 
    120108        raw1394handle_t m_handle; 
     
    125113        int             m_irq_interval; 
    126114         
    127         uint64_t        m_cycletimer_ticks; 
    128         uint64_t m_lastmeas_usecs; 
    129         float               m_ticks_per_usec; 
    130         float               m_ticks_per_usec_dll_err2; 
    131          
    132115        int m_packetcount; 
    133116        int m_dropped; 
     
    135118        IsoStream *m_Client; 
    136119 
    137         FreebobUtil::TimeSource *m_TimeSource; 
    138  
    139120        virtual int handleBusReset(unsigned int generation); 
    140121 
     
    144125    private: 
    145126        static int busreset_handler(raw1394handle_t handle, unsigned int generation); 
    146  
    147         void initCycleTimer(); 
    148127 
    149128    // the state machine 
     
    158137         
    159138        enum EHandlerStates m_State; 
    160  
    161     // implement the TimeSource interface 
    162     public: 
    163         freebob_microsecs_t getCurrentTime(); 
    164         freebob_microsecs_t getCurrentTimeAsUsecs(); 
    165         inline freebob_microsecs_t unWrapTime(freebob_microsecs_t t); 
    166         inline freebob_microsecs_t wrapTime(freebob_microsecs_t t); 
    167          
    168     private: 
    169         // to cope with wraparound 
    170         unsigned int m_TimeSource_LastSecs; 
    171         unsigned int m_TimeSource_NbCycleWraps; 
    172139 
    173140}; 
  • branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp

    r397 r398  
    161161        return true; 
    162162 
    163 } 
    164  
    165 // updates the internal cycle timer caches of the handlers 
    166 void IsoHandlerManager::updateCycleTimers() { 
    167     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 
    168      
    169     for ( IsoHandlerVectorIterator it = m_IsoHandlers.begin(); 
    170           it != m_IsoHandlers.end(); 
    171           ++it ) 
    172     { 
    173         int cnt=0; 
    174         while (!(*it)->updateCycleTimer() && (cnt++ < MAX_UPDATE_TRIES)) { 
    175             usleep(USLEEP_AFTER_UPDATE_FAILURE); 
    176         } 
    177     } 
    178      
    179163} 
    180164 
  • branches/streaming-rework/src/libstreaming/IsoHandlerManager.h

    r390 r398  
    121121        /// iterate all child handlers 
    122122        bool iterate(); 
    123     public: // FIXME: just so that SPM can do this (temp solution) 
    124         /// updates the cycle timer caches of all child handlers 
    125         void updateCycleTimers(); 
     123 
    126124    private: 
    127125        // note: there is a disctinction between streams and handlers 
  • branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp

    r396 r398  
    3333#include <assert.h> 
    3434 
    35 #include "../libutil/PosixThread.h" 
    36  
    3735#include "libstreaming/cycletimer.h" 
    3836 
    3937#define CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL 50 
     38 
     39#define RUNNING_TIMEOUT_MSEC 4000 
     40#define PREPARE_TIMEOUT_MSEC 4000 
     41#define ENABLE_TIMEOUT_MSEC 4000 
    4042 
    4143namespace FreebobStreaming { 
     
    165167        debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    166168 
    167         // the tread that runs the StreamProcessor 
    168         // checking the period boundaries 
    169         int prio=m_thread_priority+5; 
    170         if (prio>98) prio=98; 
    171          
    172         m_streamingThread=new FreebobUtil::PosixThread(this, 
    173            m_thread_realtime, prio,  
    174            PTHREAD_CANCEL_DEFERRED); 
    175             
    176         if(!m_streamingThread) { 
    177                 debugFatal("Could not create streaming thread\n"); 
    178                 return false; 
    179         } 
    180          
    181169        m_isoManager=new IsoHandlerManager(m_thread_realtime, m_thread_priority); 
    182170         
     
    197185         
    198186        return true; 
    199 } 
    200  
    201 bool StreamProcessorManager::Init() 
    202 { 
    203     debugOutput( DEBUG_LEVEL_VERBOSE, "Initializing runner...\n"); 
    204  
    205     // no xrun has occurred (yet) 
    206  
    207     return true; 
    208187} 
    209188 
     
    275254} 
    276255 
    277 // FIXME: this can be removed 
    278 bool StreamProcessorManager::Execute() 
    279 { 
    280         // temp measure, polling 
    281         usleep(1000); 
    282  
    283         // FIXME: move this to an IsoHandlerManager sub-thread 
    284         // and make this private again in IHM 
    285         m_isoManager->updateCycleTimers(); 
    286          
    287         return true; 
    288 } 
    289256 
    290257bool StreamProcessorManager::syncStartAll() { 
     
    293260    // we have to wait until all streamprocessors indicate that they are running 
    294261    // i.e. that there is actually some data stream flowing 
    295     int wait_cycles=2000; // two seconds 
     262    int wait_cycles=RUNNING_TIMEOUT_MSEC; // two seconds 
    296263    bool notRunning=true; 
    297264    while (notRunning && wait_cycles) { 
     
    453420                return false; 
    454421        } 
    455          
    456         debugOutput( DEBUG_LEVEL_VERBOSE, "Starting streaming threads...\n"); 
    457  
    458         // start the runner thread 
    459         // FIXME: not used anymore (for updatecycletimers ATM, but that's not good) 
    460         m_streamingThread->Start(); 
    461422 
    462423        // start all SP's synchonized 
     
    478439        debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping...\n"); 
    479440        assert(m_isoManager); 
    480         assert(m_streamingThread); 
    481441 
    482442        debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to prepare to stop...\n"); 
     
    484444        // (like the MOTU) need to do a few things before it's safe to turn off the iso 
    485445        // handling. 
    486         int wait_cycles=2000; // two seconds ought to be sufficient 
     446        int wait_cycles=PREPARE_TIMEOUT_MSEC; // two seconds ought to be sufficient 
    487447        bool allReady = false; 
    488448        while (!allReady && wait_cycles) { 
     
    504464        } 
    505465 
    506  
    507         debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping threads...\n"); 
    508          
    509         m_streamingThread->Stop(); 
    510466         
    511467        debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handlers...\n"); 
     
    604560    // we have to wait until all streamprocessors indicate that they are running 
    605561    // i.e. that there is actually some data stream flowing 
    606     int wait_cycles=2000; // two seconds 
     562    int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 
    607563    bool notEnabled=true; 
    608564    while (notEnabled && wait_cycles) { 
     
    689645    // we have to wait until all streamprocessors indicate that they are running 
    690646    // i.e. that there is actually some data stream flowing 
    691     int wait_cycles=2000; // two seconds 
     647    int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 
    692648    bool enabled=true; 
    693649    while (enabled && wait_cycles) { 
  • branches/streaming-rework/src/libstreaming/StreamProcessorManager.h

    r396 r398  
    5050  
    5151*/ 
    52 class StreamProcessorManager : 
    53                         public FreebobUtil::RunnableInterface { 
     52class StreamProcessorManager { 
    5453 
    5554public: 
     
    121120     
    122121protected: 
    123     int signalWaiters(); // call this to signal a period boundary 
    124     // RunnableInterface interface 
    125     bool Execute(); // note that this is called in we while(running) loop 
    126     bool Init(); 
    127  
    128122    // thread sync primitives 
    129     sem_t m_period_semaphore; 
    130  
    131123    bool m_xrun_happened;  
    132124 
     
    144136    IsoHandlerManager *m_isoManager; 
    145137 
    146     FreebobUtil::PosixThread *m_streamingThread; 
    147  
    148138    unsigned int m_nbperiods; 
    149139 
  • branches/streaming-rework/tests/test-sytmonitor.cpp

    r393 r398  
    241241                goto finish; 
    242242            } 
    243              
    244             if (!masterTimeSource.registerSlave(monitors[i]->getHandler())) { 
    245                 debugOutput(DEBUG_LEVEL_NORMAL, "Could not register SytMonitor %d's IsoHandler with masterTimeSource\n", i); 
    246                 goto finish; 
    247                  
    248             } 
     243 
    249244        } 
    250245