ss_time_lib.c

00001 
00002 #include "edtinc.h"
00003 #include "edt_ss_vco.h"
00004 #include "edt_bitload.h"
00005 #include "edt_threads.h"
00006 
00007 #include <sys/timeb.h>
00008 
00009 #ifdef WIN32
00010 #include <process.h>
00011 #endif
00012 
00013 
00014 #include <math.h>
00015 
00016 #include "ss_time_lib.h"
00017 
00018 
00019 
00020 #define USECS_FACTOR  (1000000.0 / (double) (1 << 20))
00021 
00022 /*
00023 * return the microseconds value for the current second 
00024 *
00025 */
00026 
00027 #ifdef WIN32
00028 
00029 int usecs_difference = 0;
00030 int usecs_calibrated = 0;
00031 double realtime_diff = 0.0;
00032 double mean_trend = 0.0;
00033 
00034 #define POLL_MARGIN 975
00035 void edt_calibrate_usecs(int test_loops)
00036 
00037 {
00038     int i;
00039     int loops = 1;
00040     double sum = 0.0, whole, msec, diff = 0, t, testms, last_diff;
00041 
00042 
00043     FILETIME ft;
00044     uint64_t dt;
00045     SYSTEMTIME tm;
00046     uint64_t dt_1970;
00047 
00048     if (test_loops > 1)
00049         loops = test_loops;
00050 
00051     /* compute 1970 time */
00052     tm.wYear = 1970;
00053     tm.wMonth = 1;
00054     tm.wHour = 0;
00055     tm.wMinute = 0;
00056     tm.wSecond = 0;
00057     tm.wMilliseconds = 0;
00058     tm.wDay = 1;
00059     tm.wDayOfWeek = 1;
00060 
00061     SystemTimeToFileTime(&tm, &ft);
00062 
00063     dt_1970 = (uint64_t) ft.dwHighDateTime << 32 | (uint64_t)ft.dwLowDateTime;
00064 
00065 
00066     /* look for zero-crossing */
00067 
00068 
00069     /*  uses edt_timestamp() */
00070     mean_trend = 0;
00071 
00072 
00073     for (i=0;i<loops;i++)
00074     {
00075         Sleep(10);
00076 
00077         t = edt_timestamp();
00078 
00079         msec = 1000000.0 * modf(t, &whole);
00080 
00081         GetSystemTimeAsFileTime(&ft);
00082         dt = (uint64_t) ft.dwHighDateTime << 32 | (uint64_t)ft.dwLowDateTime;
00083 
00084         dt -= dt_1970;
00085 
00086         testms = dt * 0.0000001;
00087 
00088         diff = t - testms;
00089 
00090         sum += diff;
00091 
00092         if (i>0)
00093             mean_trend += diff - last_diff;
00094 
00095         last_diff = diff;
00096 
00097     }
00098 
00099     realtime_diff = (sum / (double) loops);
00100     if (loops > 1)
00101         mean_trend /= (loops - 1);
00102 
00103     usecs_calibrated = 1;
00104 
00105 }
00106 
00107 void old_edt_calibrate_usecs()
00108 
00109 {
00110     int i;
00111     int loops = 1;
00112     time_t t, t1;
00113     struct timeb tb1;
00114     double sum = 0.0, dtsum = 0.0, whole, frac, last_frac = 0,
00115         trend = 0, dt;
00116     /* look for zero-crossing */
00117 
00118 
00119     /*  uses edt_timestamp() */
00120 
00121     for (i=0;i<loops;i++)
00122     {
00123         ftime(&tb1);
00124 
00125         if (tb1.millitm < POLL_MARGIN)
00126             Sleep(POLL_MARGIN - tb1.millitm);
00127 
00128         t1 = time(&t);
00129 
00130         do {
00131             t = time(&t);
00132             dt = edt_timestamp();
00133         } while (t == t1);
00134 
00135         frac = modf(dt, &whole);
00136         trend = frac - last_frac;
00137         last_frac = frac;
00138         printf("frac = %f trend= %f\n", frac, trend);
00139         sum += frac;
00140         dtsum += (dt - t);
00141 
00142     }
00143 
00144     usecs_difference = (u_int) ((sum / (double) loops) * 1000000.0);
00145     realtime_diff = (dtsum / (double) loops);
00146     printf("usecs_difference = %d realtime_diff = %f\n", usecs_difference, realtime_diff);
00147     usecs_calibrated = 1;
00148 
00149 }
00150 
00151 
00152 double
00153 edt_sys_timestamp()
00154 
00155 {
00156 
00157 
00158     double t;
00159 
00160     if (!usecs_calibrated)
00161         edt_calibrate_usecs(0);
00162 
00163 
00164     t = edt_timestamp();
00165 
00166     return t - realtime_diff;
00167 
00168 }
00169 
00170 
00171 
00172 #else
00173 
00174 #define edt_sys_timestamp edt_timestamp
00175 
00176 #endif
00177 
00185 int 
00186 edt_usecs()
00187 
00188 {
00189 
00190 #ifdef WIN32
00191 
00192     double t;
00193 
00194     if (!usecs_calibrated)
00195         edt_calibrate_usecs(0);
00196 
00197     t = (edt_sys_timestamp() * 1000000.0);
00198     t = fmod(t, 1000000.0);
00199 
00200     return (int) t;
00201 
00202 #elif defined(VXWORKS)
00203 
00204     struct timespec     endtime ;
00205     clock_gettime(CLOCK_REALTIME,&endtime);
00206     return endtime.tv_nsec / 1000;
00207 
00208 #else                           /* _NT_ */
00209     struct timeval endtime;
00210 
00211     gettimeofday(&endtime, (struct timezone *) NULL);
00212 
00213     return endtime.tv_usec;
00214 
00215 #endif                          /* _NT_ */
00216 
00217 }
00218 
00219 /* used to compensate for time between end of wait and 
00220 actual zero-crossing */
00221 
00222 static int wait_zero_offset = 0;
00223 static int wait_zero_calibrated = 0;
00224 
00225 /*
00226 *
00227 * Wait for system time zero-crossing 
00228 * margin is #of microseconds before zero to satisfy wait
00229 * (normally wait_zero_offset)
00230 *
00231 */
00232 
00233 
00234 static void
00235 edt_wait_for_zero(int margin)
00236 
00237 {
00238     int usec;
00239     int lastusec = 0;
00240 
00241     int test = 1000000 - margin;
00242 
00243     usec = edt_usecs();
00244 
00245     edt_usleep(1000 - (usec/1000) - 100);
00246     while (usec < test && usec >= lastusec)
00247     {
00248         lastusec = usec;
00249 
00250         usec = edt_usecs();
00251     }
00252 }
00253 
00262 void 
00263 edt_sstm_setup(EdtTimeController *tm, char *bitfile)
00264 
00265 {
00266 
00267     if (bitfile)
00268         edt_bitload(tm->dev_p, ".", bitfile, 0, 0);
00269     else 
00270         edt_bitload(tm->dev_p, ".", "c3_demux.bit", 0, 0);
00271 }
00272 
00292 void edt_sstm_strobe(EdtTimeController *tm, unsigned int bits)
00293 
00294 {
00295     int cmd;
00296     int count = 0;
00297 
00298     do
00299     {
00300         cmd = edt_reg_read(tm->dev_p, tm->cmd);
00301         if (cmd & EDT_SSTM_CMD_LOCK)
00302             edt_msleep(0);
00303     } while (cmd & EDT_SSTM_CMD_LOCK && (count++ < 5));
00304 
00305 
00306     cmd &= 0x70;
00307 
00308     edt_reg_write(tm->dev_p, tm->cmd, cmd | EDT_SSTM_CMD_LOCK);
00309 
00310     edt_reg_write(tm->dev_p, tm->cmd, cmd | bits);
00311 }
00312 
00313 /*
00314 *
00315 * attempt to find the delta between the zero crossing and setting the 
00316 * strobe register value, to offset the wait to be as close to 
00317 * zero as possible 
00318 * uses ZERO_OFFSET_MAX check to avoid occasional snoozes
00319 *
00320 */
00321 
00322 static void
00323 edt_sstm_calibrate_wait(EdtTimeController *tm)
00324 
00325 {
00326 
00327     int i1, i2;
00328 
00329     if (wait_zero_calibrated)
00330         return;
00331 
00332     do 
00333     {
00334         edt_wait_for_zero(0);
00335 
00336         i1 = edt_usecs();
00337 
00338         edt_sstm_strobe(tm, 0);
00339 
00340         i2  = edt_usecs();
00341 
00342         wait_zero_offset = (i1+i2)/2;
00343         printf("wait_zero_offset = (%d + %d) / 2 = %d\n", 
00344             i1, i2, wait_zero_offset);
00345 
00346     } while (wait_zero_offset > EDT_SSTM_ZERO_OFFSET_MAX);
00347 
00348 }
00349 
00355 void edt_sstm_latch_time(EdtTimeController *tm)
00356 
00357 {
00358     edt_sstm_strobe(tm, EDT_SSTM_LATCH);
00359 }
00360 
00367 int edt_sstm_get_adjust_enabled(EdtTimeController *tm)
00368 
00369 {
00370     int cfg = edt_reg_read(tm->dev_p, tm->cmd);
00371 
00372     if (cfg & EDT_SSTM_ADJ_EN)
00373         return 1;
00374     else
00375         return 0;
00376 
00377 }
00378 
00386 int edt_sstm_get_adjust_sign(EdtTimeController *tm)
00387 
00388 {
00389     int cfg = edt_reg_read(tm->dev_p, tm->cmd);
00390 
00391     if (cfg & EDT_SSTM_ADJ_PLUS)
00392         return 1;
00393     else
00394         return -1;
00395 
00396 }
00397 
00403 u_int edt_sstm_get_adjust_ticks(EdtTimeController *tm)
00404 
00405 {
00406 
00407     return edt_sstm_get_adjust_sign(tm) *
00408         edt_reg_read(tm->dev_p, tm->adj_value);
00409 }
00410 
00411 
00417 u_int edt_sstm_get_seconds(EdtTimeController *tm)
00418 
00419 {
00420     return edt_reg_read(tm->dev_p, tm->secs);
00421 }
00422 
00429 u_int edt_sstm_get_counts(EdtTimeController *tm)
00430 
00431 {
00432     return edt_reg_read(tm->dev_p, tm->counts) >> 12;
00433 }
00434 
00445 u_int 
00446 edt_sstm_get_usecs(EdtTimeController *tm)
00447 
00448 {
00449     u_int count = edt_sstm_get_counts(tm);
00450 
00451     return (u_int) (count * USECS_FACTOR);
00452 
00453 }
00454 
00466 void 
00467 edt_sstm_get_time_parts(EdtTimeController *tm, u_int *seconds, u_int *usecs)
00468 
00469 {
00470     edt_sstm_latch_time(tm);
00471 
00472     *seconds = edt_sstm_get_seconds(tm);
00473     *usecs = edt_sstm_get_usecs(tm);
00474 }
00475 
00483 double 
00484 edt_sstm_timestamp(EdtTimeController *tm)
00485 
00486 {
00487 
00488     edt_sstm_latch_time(tm);
00489 
00490     return (double) edt_sstm_get_seconds(tm) + 
00491         (0.000001) * (USECS_FACTOR) * edt_sstm_get_counts(tm);
00492 }
00493 
00504 void edt_sstm_set_secs(EdtTimeController *tm, unsigned int second)
00505 
00506 {
00507     edt_reg_write(tm->dev_p, tm->set, second);
00508     edt_sstm_strobe(tm, EDT_SSTM_COPY);
00509 }
00510 
00511 
00521 void edt_sstm_set(EdtTimeController *tm, unsigned int second)
00522 
00523 {
00524     printf("Setting seconds to %d\n", second);
00525 
00526     edt_reg_write(tm->dev_p, tm->set, second+1);
00527     edt_wait_for_zero(wait_zero_offset);
00528     edt_sstm_strobe(tm, EDT_SSTM_COPY);
00529 }
00530 
00538 void edt_sstm_set_to_sys(EdtTimeController *tm)
00539 
00540 {
00541     time_t t;
00542     edt_sstm_calibrate_wait(tm);
00543     edt_wait_for_zero(0);
00544     edt_msleep(500);
00545     t = time(&t);
00546     edt_sstm_set(tm, (u_int) t);
00547 }
00548 
00557 void edt_sstm_set_to_sys_error(EdtTimeController *tm, int error)
00558 
00559 {
00560     time_t t;
00561     edt_sstm_calibrate_wait(tm);
00562     edt_wait_for_zero(0);
00563     edt_msleep(500);
00564     t = time(&t);
00565     if (error < 0)
00566     {
00567         edt_reg_write(tm->dev_p, tm->set, (uint_t) (t + ( error / 1000 )) );
00568         edt_wait_for_zero(wait_zero_offset);
00569 
00570         edt_msleep(1000 - (abs(error) % 1000));
00571         edt_sstm_strobe(tm, EDT_SSTM_COPY);
00572 
00573     }
00574     else
00575     {
00576 
00577         edt_reg_write(tm->dev_p, tm->set, (uint_t) (t + 1 + error / 1000));
00578         edt_wait_for_zero(wait_zero_offset);
00579 
00580         edt_msleep(error % 1000);
00581 
00582         edt_sstm_strobe(tm, EDT_SSTM_COPY);
00583 
00584     }
00585 }
00586 
00593 void edt_sstm_disable_adjust(EdtTimeController *tm)
00594 
00595 {
00596     edt_reg_and(tm->dev_p, tm->cmd, ~EDT_SSTM_ADJ_EN);
00597 }
00598 
00605 void edt_sstm_enable_adjust(EdtTimeController *tm)
00606 
00607 {
00608     edt_reg_or(tm->dev_p, tm->cmd,  EDT_SSTM_ADJ_EN );
00609 }
00610 
00618 void edt_sstm_set_adj_sign(EdtTimeController *tm, int positive)
00619 
00620 {
00621     edt_reg_and(tm->dev_p, tm->cmd, ~EDT_SSTM_ADJ_PLUS);
00622     edt_reg_or(tm->dev_p, tm->cmd,  ((positive)?EDT_SSTM_ADJ_PLUS:0));
00623 }
00624 
00632 int edt_sstm_get_adj_sign(EdtTimeController *tm)
00633 
00634 {
00635     edt_reg_and(tm->dev_p, tm->cmd, ~EDT_SSTM_ADJ_PLUS);
00636     return edt_reg_read(tm->dev_p, tm->cmd) & EDT_SSTM_ADJ_PLUS;
00637 }
00638 
00652 void edt_sstm_set_adj_ticks(EdtTimeController *tm, int ticks, int positive)
00653 
00654 {
00655     edt_reg_write(tm->dev_p, tm->set, abs(ticks));
00656 
00657     edt_sstm_disable_adjust(tm);
00658     edt_sstm_strobe(tm, EDT_SSTM_COPY_ADJ );
00659     edt_sstm_set_adj_sign(tm, positive);
00660     edt_sstm_enable_adjust(tm);
00661 
00662     tm->ticks = ticks;
00663 
00664     printf("set adj to %d\n", ticks);
00665 }
00666 
00679 double edt_sstm_sys_error(EdtTimeController *tm)
00680 
00681 {
00682     double t1, t2, st1;
00683     t1 = edt_sstm_timestamp(tm);
00684     st1 = edt_sys_timestamp();
00685     t2 = edt_sstm_timestamp(tm);
00686     return ((t1 + t2) * 0.5) - st1;
00687 }
00688 
00698 char *
00699 edt_printable_time(double sys_t, char *buf)
00700 
00701 {
00702     time_t t;
00703     struct tm *ltime;
00704     int usecs;
00705     double whole;
00706     static char sbuf[17];
00707     char *cp = buf;
00708 
00709     if (!cp)
00710         cp = sbuf;
00711 
00712     t = (time_t) sys_t;
00713 
00714     ltime = localtime(&t);
00715 
00716     if (!ltime)
00717         return buf;
00718 
00719     usecs = (int) (modf(sys_t,&whole) * 1000000.0);
00720 
00721     sprintf(cp, "%02d:%02d:%02d.%06d",
00722         ltime->tm_hour, ltime->tm_min, ltime->tm_sec, usecs);
00723 
00724     return cp;
00725 }
00726 
00727 
00736 double
00737 edt_sstm_print(EdtTimeController *tm)
00738 
00739 {
00740     double error, sys_t;
00741     char printbuf[32];
00742 
00743     sys_t = edt_sys_timestamp();
00744 
00745     error = edt_sstm_sys_error(tm);     
00746 
00747     printf("%s    %.6f\n", edt_printable_time(sys_t, printbuf),error);
00748 
00749     return error;
00750 
00751 }
00752 
00753 
00754 static double
00755 double_mean(double *v, int n)
00756 
00757 {
00758     double sum = 0.0;
00759     int i;
00760 
00761     for (i=0;i<n;i++)
00762         sum += v[i];
00763 
00764     return (sum / (double) n);
00765 }
00766 
00767 static int
00768 double_compare(const void *p1, const void *p2)
00769 
00770 {
00771     double d1 = *(double *) p1;
00772     double d2 = *(double *) p2;
00773 
00774     return (d1 > d2)?1:((d1 == d2)?0:-1);
00775 }
00776 
00777 
00778 
00779 static int adj_sample_seconds = 3;
00780 static int adj_samples = 10;
00781 
00789 void edt_sstm_set_drift_sampling(int seconds, int samples)
00790 
00791 {
00792     adj_sample_seconds = seconds;
00793     adj_samples = samples;
00794 }
00795 
00804 int edt_sstm_get_adj_sample_secs()
00805 
00806 {
00807     return adj_sample_seconds;
00808 }
00809 
00818 int edt_sstm_get_adj_samples()
00819 
00820 {
00821     return adj_samples;
00822 }
00823 
00824 
00825 
00832 int edt_sstm_ticks_from_drift(double drift)
00833 
00834 {
00835     double t;
00836 
00837     if (drift == 0.0)
00838         return 0;
00839 
00840     t = USECS_FACTOR;
00841 
00842     t = (int) (1000000.0 / drift);
00843 
00844     return (int) t;
00845 }
00846 
00855 void edt_sstm_set_adj_from_drift(EdtTimeController *tm, double drift)
00856 
00857 {
00858     int ticks = (int) edt_sstm_ticks_from_drift(drift);
00859 
00860     edt_sstm_set_adj_ticks(tm, ticks, (drift >= 0.0));
00861 
00862 
00863 }
00864 
00875 double edt_sstm_measure_drift(EdtTimeController *tm)
00876 
00877 {
00878 
00879     double t1 = 0, t2 = 0, st1 = 0, st2 = 0;
00880 
00881     double *d1_v = NULL, *d2_v = NULL, *st1_v = NULL, *st2_v = NULL;
00882 
00883     double d1, d2;
00884     double drift;
00885     double extraticks;
00886 
00887     int i;
00888     int count;
00889     int adj_state = edt_reg_read(tm->dev_p, tm->cmd) & EDT_SSTM_ADJ_EN;
00890     int sleep_interval = adj_sample_seconds * 1000000;
00891 
00892     edt_sstm_timestamp(tm);
00893 
00894     edt_sstm_disable_adjust(tm);
00895 
00896 
00897     d1_v = (double *) calloc(2*adj_samples +1 , sizeof(double));
00898     d2_v = (double *) calloc(2*adj_samples +1 , sizeof(double));
00899     st1_v = (double *) calloc(2*adj_samples +1 , sizeof(double));
00900     st2_v = (double *) calloc(2*adj_samples +1 , sizeof(double));
00901 
00902 
00903     printf("Sampling basic error rate ...\n");
00904     edt_usleep(100);
00905 
00906     t1 = 0;
00907     st1 = 0;
00908     t2 = 0;
00909     st2 = 0;
00910     d1 = 0;
00911     d2 = 0;
00912 
00913 
00914     for (i=0;i<adj_samples;i++)
00915     {     
00916         t1 = edt_sstm_timestamp(tm);
00917         st1 = edt_sys_timestamp();
00918         t2 = edt_sstm_timestamp(tm);
00919         d1_v[i] =  st1 - ((t1 + t2) * 0.5);
00920         st1_v[i] = st1;
00921     }
00922 
00923     edt_usleep(sleep_interval);
00924 
00925 
00926     count = 0;
00927 
00928     for (i=0;i<adj_samples;i++)
00929     {
00930         t1 = edt_sstm_timestamp(tm);
00931         st1 = edt_sys_timestamp();
00932         t2 = edt_sstm_timestamp(tm);
00933         d2_v[i] =  st1 - ((t1 + t2) * 0.5);
00934         st2_v[i] = st1;
00935     }
00936 
00937     /* calc means, remove outliers, then recalc */
00938     /* first sort arrays */
00939     qsort(d1_v, adj_samples, sizeof(double), double_compare);
00940     qsort(d2_v, adj_samples, sizeof(double), double_compare);
00941     qsort(st1_v, adj_samples, sizeof(double), double_compare);
00942     qsort(st2_v, adj_samples, sizeof(double), double_compare);
00943 
00944     /* find mean of each array */
00945     /* toss out high and low */
00946 
00947     d1 = double_mean(d1_v + 1, (adj_samples-2));
00948     d2 = double_mean(d2_v + 1, (adj_samples-2));
00949     st1 = double_mean(st1_v + 1, adj_samples-2);
00950     st2 = double_mean(st2_v + 1, adj_samples-2);
00951 
00952 
00953     d1 *= 1000000.0;
00954     d2 *= 1000000.0;
00955 
00956     drift = (d2 - d1) / (st2 - st1);
00957 
00958 
00959 #ifdef VERBOSE
00960 
00961     printf("d1 = %.6f d2 = %.6f\n",     d1, d2);
00962     printf("st1 = %.6f st2 = %.6f\n",   st1, st2);
00963 
00964     for (i=0;i<adj_samples*2;i++)
00965     {
00966         printf("d1_v[%d] = %.5f d2_v[%d] = %.6f\n",
00967             i, d1_v[i], i, d2_v[i]);
00968     }
00969 
00970     for (i=0;i<adj_samples;i++)
00971     {
00972         printf("st1_v[%d] = %.5f st2_v[%d] = %.6f\n",
00973             i, st1_v[i], i, st2_v[i]);
00974     }
00975 #endif
00976 
00977     extraticks = edt_sstm_ticks_from_drift(drift);
00978 
00979     printf("drift in %.0f secs = %.1f ticks = %.0f\n", 
00980         (st2 - st1), 
00981         drift, 
00982         extraticks);
00983 
00984     /* turn asjust back to start value */
00985     if (adj_state)
00986         edt_reg_or(tm->dev_p, tm->cmd, EDT_SSTM_ADJ_EN);
00987 
00988     free(d1_v);
00989     free(d2_v);
00990     free(st1_v);
00991     free(st2_v);
00992 
00993     return drift;
00994 }
00995 
00996 THREAD_FUNC_DECLARE 
00997 edt_sstm_adjust_thread(void *p)
00998 
00999 {
01000     EdtTimeController *tm = (EdtTimeController *) p;
01001 
01002     double max_err;
01003     int ticks;
01004     int sign;
01005     int delta;
01006     
01007     double last_error;
01008     double drift_values[5];
01009     int nvalues = 0;
01010     int start_ticks;
01011 
01012     if (tm == NULL)
01013         return (THREAD_RETURN) -1;
01014 
01015     max_err = tm->max_error * 0.000001;
01016 
01017     tm->done = 0;
01018 
01019     tm->err = edt_sstm_sys_error(tm);
01020 
01021     /* we assume we're close to the right adjustment */
01022 
01023     start_ticks = edt_sstm_get_adjust_ticks(tm);
01024 
01025     while (tm->active)
01026     {
01027 
01028         last_error = tm->err;
01029 
01030 
01031         tm->err = edt_sstm_sys_error(tm);
01032 
01033         drift_values[nvalues % 5] = tm->err - last_error;
01034         nvalues++;
01035         
01036         tm->adjust_drift =  double_mean(drift_values, (nvalues > 5)?5:nvalues);
01037 
01038         ticks = edt_sstm_get_adjust_ticks(tm);
01039         sign = (edt_sstm_get_adjust_sign(tm) > 0);
01040 
01041         delta = (int)(-tm->err * 1000000 * tm->adjustment_scalar);
01042 
01043 
01044         if (sign)
01045             ticks = start_ticks + delta;
01046         else
01047             ticks = start_ticks - delta;
01048         printf("adjusting drift = %f err = %f delta = %d\n", tm->adjust_drift, tm->err, delta);
01049 
01050         edt_sstm_set_adj_ticks(tm, ticks, sign);
01051         edt_sstm_enable_adjust(tm);
01052 
01053         
01054         edt_msleep(tm->adjust_sample);
01055 
01056     }
01057 
01058     tm->done = 1;
01059 
01060     return (THREAD_RETURN) 0;
01061 }
01062 
01063 
01072 EdtTimeController *
01073 edt_sstm_launch_adjuster(EdtTimeController *tm)
01074 
01075 {
01076 
01077 #ifdef __APPLE__
01078     mac_thread_t thread;
01079 #else
01080     thread_t thread;
01081 #endif
01082 
01083     LaunchThread(thread, edt_sstm_adjust_thread, (void *) tm);
01084     tm->thread = thread;
01085 
01086     return tm;
01087 
01088 }
01089 
01099 void
01100 edt_sstm_adjuster_stop(EdtTimeController *tm)
01101 
01102 {
01103     if (!tm->active)
01104         return;
01105 
01106     tm->active = 0;
01107     while (!tm->done)
01108         edt_msleep(100);
01109 }
01110 
01119 void
01120 edt_sstm_adjuster_start(EdtTimeController *tm)
01121 {
01122 #ifdef __APPLE__
01123     mac_thread_t thread;
01124 #else
01125     thread_t thread;
01126 #endif
01127     int ticks;
01128 
01129     if (tm->active)
01130         return;
01131 
01132     /* flags for terminatting sample thread */
01133 
01134     tm->done = 0;
01135     tm->active = TRUE;
01136 
01137    /* calculate drift */
01138 
01139     tm->drift = edt_sstm_measure_drift(tm);
01140     ticks = edt_sstm_ticks_from_drift(tm->drift);
01141     edt_sstm_set_adj_ticks(tm, ticks, (ticks >= 0.0));
01142     
01143     /* set to system time */
01144         
01145     edt_sstm_set_to_sys(tm);
01146 
01147     LaunchThread(thread, edt_sstm_adjust_thread, (void *) tm);
01148     tm->thread = thread;
01149 
01150 }
01151 
01152 EDTAPI void edt_init_time_controller(EdtTimeController *tm,
01153                                      EdtDev *edt_p,
01154                                      u_int address_base)
01155 
01156 {
01157     tm->dev_p = edt_p;
01158     tm->counts = address_base + (EDT_SSTM_COUNTS & 0xf0000ff);
01159     tm->secs = address_base + (EDT_SSTM_SECS & 0xf0000ff);
01160     tm->set = address_base + (EDT_SSTM_SET & 0xf0000ff);
01161     tm->adj_value = address_base + (EDT_SSTM_ADJ_VALUE & 0xf0000ff);
01162     tm->cmd = address_base + (EDT_SSTM_CMD & 0xf0000ff);
01163 }
01164 
01165 

Generated on 19 Jun 2015 by  doxygen 1.4.7