/* * refclock_transmit - simulate the transmit procedure * * This routine implements the NTP transmit procedure for a reference * clock. This provides a mechanism to call the driver at the NTP poll * interval, as well as provides a reachability mechanism to detect a * broken radio or other madness. */ void refclock_transmit( struct peer *peer /* peer structure pointer */ ) { u_char clktype; int unit; clktype = peer->refclktype; unit = peer->refclkunit; peer->sent++; get_systime(&peer->xmt); /* * This is a ripoff of the peer transmit routine, but * specialized for reference clocks. We do a little less * protocol here and call the driver-specific transmit routine. */ if (peer->burst == 0) { u_char oreach; #ifdef DEBUG if (debug) printf("refclock_transmit: at %ld %s\n", current_time, stoa(&(peer->srcadr))); #endif /* * Update reachability and poll variables like the * network code. */ oreach = peer->reach; peer->reach <<= 1; peer->outdate = current_time; if (!peer->reach) { if (oreach) { report_event(EVNT_UNREACH, peer); peer->timereachable = current_time; } } else { if (!(oreach & 0x07)) { clock_filter(peer, 0., 0., MAXDISPERSE); clock_select(); } if (peer->flags & FLAG_BURST) peer->burst = NSTAGE; } } else { peer->burst--; } if (refclock_conf[clktype]->clock_poll != noentry) (refclock_conf[clktype]->clock_poll)(unit, peer); poll_update(peer, peer->hpoll); }
/* * refclock_receive - simulate the receive and packet procedures * * This routine simulates the NTP receive and packet procedures for a * reference clock. This provides a mechanism in which the ordinary NTP * filter, selection and combining algorithms can be used to suppress * misbehaving radios and to mitigate between them when more than one is * available for backup. */ void refclock_receive( struct peer *peer /* peer structure pointer */ ) { struct refclockproc *pp; #ifdef DEBUG if (debug) printf("refclock_receive: at %lu %s\n", current_time, ntoa(&peer->srcadr)); #endif /* * Do a little sanity dance and update the peer structure. Groom * the median filter samples and give the data to the clock * filter. */ peer->received++; pp = peer->procptr; peer->processed++; peer->timereceived = current_time; peer->leap = pp->leap; if (peer->leap == LEAP_NOTINSYNC) { refclock_report(peer, CEVNT_FAULT); return; } if (!peer->reach) report_event(EVNT_REACH, peer); peer->reach |= 1; peer->reftime = peer->org = pp->lastrec; peer->rootdispersion = pp->disp + SQRT(pp->jitter); get_systime(&peer->rec); if (!refclock_sample(pp)) return; clock_filter(peer, pp->offset, 0., pp->jitter); clock_select(); record_peer_stats(&peer->srcadr, ctlpeerstatus(peer), peer->offset, peer->delay, clock_phi * (current_time - peer->epoch), SQRT(peer->jitter)); if (cal_enable && last_offset < MINDISPERSE) { #ifdef KERNEL_PLL if (peer != sys_peer || pll_status & STA_PPSTIME) #else if (peer != sys_peer) #endif /* KERNEL_PLL */ pp->fudgetime1 -= pp->offset * FUDGEFAC; else pp->fudgetime1 -= pp->fudgetime1 * FUDGEFAC; } }
void stem_cache_stem(struct stem_cache *cache, char *term) { struct stem_entry *target; void **find; unsigned int len; cache->stemmed++; /* lookup term in stem cache */ if (chash_ptr_ptr_find(cache->lookup, term, &find) == CHASH_OK) { /* found it, copy term in and return */ target = *find; assert(str_len(target->dst) <= str_len(term)); str_cpy(term, target->dst); cache->cached++; return; } else { /* didn't find it, find a stem_entry to use */ if (cache->size < cache->capacity) { len = str_len(term) + 1; if ((target = malloc(sizeof(*target))) && (target->src = malloc(len)) && (target->dst = malloc(len))) { target->count = LRU_DEFAULT; target->length = len; memcpy(target->src, term, len); memcpy(target->dst, term, len); cache->stem(cache->opaque, target->dst); str_cpy(term, target->dst); if (chash_ptr_ptr_insert(cache->lookup, target->src, target) == CHASH_OK) { /* finished inserting new entry */ cache->arr[cache->size++] = target; return; } else { /* couldn't insert entry */ free(target->src); free(target->dst); free(target); } } else { if (target) { if (target->src) { free(target->src); } free(target); } } } /* couldn't allocate another entry for whatever reason. Remove an existing one using clock algorithm and reuse it */ if (cache->size) { void *ptr_one, *ptr_two; target = clock_select(cache); assert(target); len = str_len(term) + 1; /* obtained suitable entry, remove it under old string */ if (chash_ptr_ptr_remove(cache->lookup, target->src, &ptr_one) == CHASH_OK) { assert(ptr_one == target); if (target->length < len) { if ((ptr_one = realloc(target->src, len)) && (ptr_two = realloc(target->dst, len))) { target->src = ptr_one; target->dst = ptr_two; target->length = len; } else { unsigned int i; if (ptr_one) { target->src = ptr_one; } /* remove it from the array (by linear search) */ cache->size--; for (i = 0; i <= cache->size; i++) { if (target == cache->arr[i]) { memcpy(cache->arr[i], cache->arr[i + 1], sizeof(cache->arr[0]) * (cache->size - i)); break; } } free(target->src); free(target->dst); free(target); target = NULL; cache->stem(cache->opaque, term); return; } } memcpy(target->src, term, len); memcpy(target->dst, term, len); cache->stem(cache->opaque, target->dst); target->count = LRU_DEFAULT; assert(str_len(target->dst) < len); str_cpy(term, target->dst); /* insert new entry back into hashtable */ if (chash_ptr_ptr_insert(cache->lookup, target->src, target) == CHASH_OK) { /* our work here is done... */ return; } else { /* removed an entry, but couldn't put it back (?) */ unsigned int i; /* remove it from the array (by linear search) */ cache->size--; for (i = 0; i <= cache->size; i++) { if (target == cache->arr[i]) { memcpy(cache->arr[i], cache->arr[i + 1], sizeof(cache->arr[0]) * (cache->size - i)); break; } } free(target->src); free(target->dst); free(target); target = NULL; } } } /* couldn't do anything efficient, just stem the term and send it * back */ cache->stem(cache->opaque, term); return; } }
int main(int argc, char *argv[] ) { unsigned char reg = 0; unsigned char bit = 0; char temp = 0; int ret = 0; int clock = 0; sem_t * sem_id; if(argc != 3){ printf("usage: ux400setclk LA/LB/LC/RA/RB/RC 1/2/3\n"); printf(" 1:ATOMIC_10M\n"); printf(" 2:ATOMIC_1PPS\n"); printf(" 3:GPS_1PPS\n"); exit(1); } if((ret = sys_init())<0) { printf("LIBFTDI init failed, exit\n"); } temp = cpldver(); if(temp < 0 ) { printf("Read CPLD version failed, exit\n"); exit(1); } DEBUG("CONT_REG1 = %d", CONT_REG1); DEBUG("CONT_REG2 = %d", CONT_REG2); DEBUG("CONT_REG3 = %d", CONT_REG3); DEBUG("CONT_REG4 = %d", CONT_REG4); DEBUG("CONT_REG5 = %d", CONT_REG5); DEBUG("STATUS_REG1 = %d", STATUS_REG1); DEBUG("STATUS_REG2 = %d", STATUS_REG2); DEBUG("ATOMIC_10M = %d", ATOMIC_10M); DEBUG("ATOMIC_1PPS = %d", ATOMIC_1PPS); DEBUG("GPS_1PPS = %d", GPS_1PPS); DEBUG("argv[1] = %s", argv[1]); if (strcmp(argv[1], "LA") == 0) { /*1g-ge*/ reg = CONT_REG5; bit = 4; } else if (strcmp(argv[1], "LB") == 0) { /*10g*/ reg = CONT_REG5; bit = 2; } else if (strcmp(argv[1], "LC") == 0) { /*40g*/ reg = CONT_REG5; bit = 0; } else if (strcmp(argv[1], "RA") == 0) { /*Memory*/ reg = CONT_REG3; bit = 6; } else if (strcmp(argv[1], "RB") == 0) { /*SDH*/ reg = CONT_REG5; bit = 6; } else if (strcmp(argv[1], "RC") == 0) { /*Spare*/ reg = CONT_REG3; bit = 2; } else { printf("Unknow slot, usage: ux400setclk LA/LB/LC/RA/RB/RC 1/2/3\n", temp); exit(1); } clock = atoi(argv[2]); DEBUG("clock = 0x%x", clock); sem_id = sem_open(UX400_SEM_CPLD, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, 1); if(sem_id == SEM_FAILED) { perror("UX400 OPM sem_open"); exit(1); } if(sem_wait(sem_id) < 0) { perror("UX400 OPM sem_wait"); exit(1); } if ((ret = clock_select(reg, bit, clock)) < 0 ) { printf("Clock select error\n"); if(sem_post(sem_id) < 0) { perror("UX400 OPM sem_post"); } exit(1); } if(sem_post(sem_id) < 0) { perror("UX400 OPM sem_post"); exit(1); } ftdi_usb_close(&ux400_ftdic); ftdi_deinit(&ux400_ftdic); return 0; }