nidas v1.2.3
|
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/version.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/poll.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/syscalls.h>
#include <linux/time.h>
#include <linux/unistd.h>
#include <linux/wait.h>
#include <linux/interrupt.h>
#include <linux/workqueue.h>
#include <linux/sched.h>
#include <linux/slab.h>
#include <asm/atomic.h>
#include <asm/io.h>
#include <linux/uaccess.h>
#include <nidas/linux/ver_macros.h>
#include <nidas/linux/irigclock.h>
#include <nidas/linux/isa_bus.h>
#include <nidas/linux/Revision.h>
#include <nidas/linux/klog.h>
#include "pc104sg.h"
Classes | |
struct | clockSnapShot |
One a second, or when clockAction == RESET_COUNTERS, the interrupt service routine grabs a snapshot of the following values. More... | |
struct | irig_device |
Device structure used in the file operations of the character device which provides IRIG samples. More... | |
struct | pc104sg_board |
Everything needed to access the board. More... | |
Macros | |
#define | REPO_REVISION "unknown" |
#define | IRQF_SHARED SA_SHIRQ |
#define | INTERRUPT_RATE 100 |
#define | MSEC_PER_INTERRUPT (MSECS_PER_SEC / INTERRUPT_RATE) |
number of milliseconds per interrupt | |
#define | TMSEC_PER_INTERRUPT (TMSECS_PER_SEC / INTERRUPT_RATE) |
number of 1/10ths of milliseconds per interrupt | |
#define | INTERRUPTS_PER_TASKLET 1 |
We schedule the bottom-half tasklet after every INTERRUPTS_PER_TASKLET interrupts. | |
#define | TMSEC_PER_SOFT_TIC |
Increment of the software clock on each schedule of the tasklet. | |
#define | MAX_TASKLET_COUNTER (10 * INTERRUPT_RATE * INTERRUPTS_PER_TASKLET) |
Allow for counting up to 10 seconds, so that we can do 0.1hz callbacks. | |
#define | CALLBACK_POOL_SIZE 64 /* number of callbacks we can support */ |
#define | PC104SG_SAMPLE_QUEUE_SIZE 16 |
Length of the circular buffer of output samples. | |
#define | MAX_TMSEC_SINCE_LAST_SYNC (5 * TMSECS_PER_SEC) |
Values that are used to detect whether the bottom half tasklet has gotten out of sync with real-time. | |
#define | SECS_PER_HOUR (60 * 60) |
macros borrowed from glibc/time functions | |
#define | SECS_PER_DAY (SECS_PER_HOUR * 24) |
#define | my_isleap(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) |
#define | DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) |
#define | LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400)) |
Enumerations | |
enum | clockAction { RESET_COUNTERS , NO_ACTION } |
What to do with the with the software clock and loop counter in the bottom-half tasklet. More... | |
enum | clockState { SYNCD_SET , UNSYNCD_SET } |
Enumeration of the state of the software clock. More... | |
enum | notifyClients { NO_NOTIFY , NOTIFY_CLIENTS } |
Whether to notify callback clients if clockAction is RESET_COUNTERS. More... | |
Functions | |
MODULE_AUTHOR ("Gordon Maclean <maclean@ucar.edu>") | |
MODULE_DESCRIPTION ("PC104-SG IRIG Card Driver") | |
MODULE_LICENSE ("GPL") | |
MODULE_VERSION (REPO_REVISION) | |
module_param (Irq, int, 0) | |
module_param (IoPort, int, 0) | |
module_param (A2DClockFreq, int, 0) | |
EXPORT_SYMBOL (TMsecClock) | |
EXPORT_SYMBOL (ReadClock) | |
static const char * | clockStateString (void) |
struct irig_callback * | register_irig_callback (irig_callback_func *callback, irig_callback_func *resync, enum irigClockRates rate, void *privateData, int *errp) |
Module function that allows other modules to register their callback function to be called at the given rate. | |
EXPORT_SYMBOL (register_irig_callback) | |
int | unregister_irig_callback (struct irig_callback *cb) |
Modules call this function to dequeue their callbacks. | |
EXPORT_SYMBOL (unregister_irig_callback) | |
int | flush_irig_callbacks (void) |
EXPORT_SYMBOL (flush_irig_callbacks) | |
static void | handlePendingCallbacks (void) |
Handle pending adds and removes of callbacks from the active list for the appropriate rate. | |
static void | free_callbacks (void) |
Cleanup function that un-registers all callbacks. | |
static void | resetHeartBeatLatch (void) |
After receiving a heartbeat interrupt, one must reset the heartbeat latch in the handler. | |
static void | enableHeartBeatInt (void) |
Enable heart beat interrupts. | |
static void | resetMatchLatch (void) |
After receiving a match interrupt, one must reset the match flag in order to receive further interrupts. | |
static void | disableAllInts (void) |
static int | readDPRAM (unsigned char addr, unsigned char *val) |
Read dual port RAM. | |
static void | requestDPRAM (unsigned char addr) |
The requestDPRAM()/getRequestedDPRAM() pair allow us to break a dual-port read into two parts. | |
static void | getRequestedDPRAM (unsigned char *val) |
static int | writeDPRAM (unsigned char addr, unsigned char value) |
Set a value in dual port RAM. | |
static int | setHeartBeatOutput (int rate) |
static int | setPrimarySyncReference (unsigned char val) |
Set the primary time reference. | |
static int | setTimeCodeInputSelect (unsigned char val) |
int | setRate2Output (int rate) |
static int | counterRejam (void) |
static void | getTimeRegisters (struct irigTime *ti, int offset) |
Read time from the registers. | |
int | getTimeUsec () |
Read sub-second time fields from the card, return microseconds. | |
static void | timespecToirig (const thiskernel_timespec_t *ts, struct irigTime *ti) |
Break a timespec into the fields of a struct irigTime. | |
static void | irigTotimespec (const struct irigTime *ti, thiskernel_timespec_t *ts) |
Convert a struct irigTime into a thiskernel_timespec_t. | |
static int64_t | irigTousec (const struct irigTime *ti) |
Convert a struct irigTime to a int64_t time in microseconds. | |
static void | irigTotimeval32 (const struct irigTime *ti, struct timeval32 *tv) |
Convert a struct irigTime into a struct timeval32. | |
static void | get_irig_time_nolock (struct irigTime *ti) |
Get value of on-board clock. | |
static void | get_irig_timespec_nolock (thiskernel_timespec_t *ts) |
void | irig_clock_gettime (thiskernel_timespec_t *tp) |
This function is available for use by external modules. | |
EXPORT_SYMBOL (irig_clock_gettime) | |
int | get_msec_clock_resolution () |
static int | setYear (int val) |
set the year fields in Dual Port RAM. | |
static int | setMajorTime (struct irigTime *ti) |
The major time consists of the day-of-year, hour, minute and second fields. | |
static int | setSoftTickers (const thiskernel_timespec_t *ts, int round) |
Set the software clock and the tasklet loop counter based on a clock value in a timespec struct. | |
static void | checkSoftTicker (int newClock, int currClock, int scale, int notify) |
Try to determine if our software clock and client callbacks are keeping up with real-time. | |
static void | doCallbacklist (int rate) |
Invoke the callback functions for a given rate. | |
static void | doResyncCallbacks (void) |
Invoke all resync callback functions. | |
static void | pc104sg_bh_100Hz (unsigned long dev) |
Tasklet called 100 times/second in softare interrupt context. | |
static void | oneHzFunction (void *ptr) |
static void | requestExtendedStatus (void) |
static irqreturn_t | pc104sg_isr (int irq, void *callbackPtr) |
static int | pc104sg_open (struct inode *inode, struct file *filp) |
static int | pc104sg_release (struct inode *inode, struct file *filp) |
static unsigned int | pc104sg_poll (struct file *filp, poll_table *wait) |
static ssize_t | pc104sg_read (struct file *filp, char __user *buf, size_t count, loff_t *f_pos) |
static long | setIRIGclock (int64_t usec) |
Set the IRIG hardware clock fields in DPRAM. | |
static long | pc104sg_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) |
static void | pc104sg_cleanup (void) |
static int __init | pc104sg_init (void) |
module_init (pc104sg_init) | |
module_exit (pc104sg_cleanup) | |
Variables | |
static char * | driver_name = "pc104sg" |
static unsigned int | A2DClockFreq = 10000 |
static unsigned int | Irq = 10 |
static unsigned int | IoPort = 0x2a0 |
int | TMsecClock [2] = { 0, 0 } |
A toggle buffer containing the current clock value in tenths of milliseconds since UTC midnight. | |
int | ReadClock = 0 |
Index into TMsecClock of the value to be read. | |
static struct pc104sg_board | board |
static int | StaticYear |
The year field in the pc104sg time registers ranges from 0-99, so we keep track of the century. | |
static struct file_operations | pc104sg_fops |
#define CALLBACK_POOL_SIZE 64 /* number of callbacks we can support */ |
Referenced by init_gpio_timer(), and pc104sg_init().
#define DIV | ( | a, | |
b ) ((a) / (b) - ((a) % (b) < 0)) |
#define INTERRUPT_RATE 100 |
Referenced by pc104sg_init().
#define INTERRUPTS_PER_TASKLET 1 |
We schedule the bottom-half tasklet after every INTERRUPTS_PER_TASKLET interrupts.
#define IRQF_SHARED SA_SHIRQ |
Referenced by irigTotimespec(), irigTousec(), and timespecToirig().
#define MAX_TASKLET_COUNTER (10 * INTERRUPT_RATE * INTERRUPTS_PER_TASKLET) |
Allow for counting up to 10 seconds, so that we can do 0.1hz callbacks.
Referenced by pc104sg_bh_100Hz(), and setSoftTickers().
#define MAX_TMSEC_SINCE_LAST_SYNC (5 * TMSECS_PER_SEC) |
Values that are used to detect whether the bottom half tasklet has gotten out of sync with real-time.
Referenced by oneHzFunction().
#define MSEC_PER_INTERRUPT (MSECS_PER_SEC / INTERRUPT_RATE) |
number of milliseconds per interrupt
Referenced by get_msec_clock_resolution().
#define my_isleap | ( | year | ) | ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) |
Referenced by timespecToirig().
#define PC104SG_SAMPLE_QUEUE_SIZE 16 |
Length of the circular buffer of output samples.
Referenced by oneHzFunction(), and pc104sg_open().
#define REPO_REVISION "unknown" |
Referenced by pc104sg_init().
#define SECS_PER_DAY (SECS_PER_HOUR * 24) |
#define SECS_PER_HOUR (60 * 60) |
macros borrowed from glibc/time functions
Referenced by timespecToirig().
#define TMSEC_PER_INTERRUPT (TMSECS_PER_SEC / INTERRUPT_RATE) |
number of 1/10ths of milliseconds per interrupt
#define TMSEC_PER_SOFT_TIC |
Increment of the software clock on each schedule of the tasklet.
Referenced by checkSoftTicker(), pc104sg_bh_100Hz(), and setSoftTickers().
enum clockAction |
enum clockState |
enum notifyClients |
|
static |
Try to determine if our software clock and client callbacks are keeping up with real-time.
Other pc104 cards are receiving clock signals from this pc104sg card. If they want to do polling, or other periodic things, they register with this module for their callbacks to be called at a given rate by the 100Hz tasklet. We want to avoid missing a callback if at all possible.
It seems to happen, especially on vulcans, that a CPU card can miss one or more IRIG interrupts. When that happens, then one or more schedules of the bottom half tasklet are missed, which means that the software clock and the callbacks get behind.
This function compares the difference between the newClock value which was calculated from either the irig or unix clock, and currClock, which is the current software clock we provide to other modules. The difference is calculated as a number of 0.01 second delta-Ts.
This dT check is performed once a second.
If the clock difference is within limits of (IRIG_MAX_DT_DIFF / scale : IRIG_MIN_DT_DIFF / scale) then the pendingH100Hz counter is adjusted by the difference, so that the tasklet will be either scheduled more or less rapidly than 100 Hz for a period.
If the difference is negative, it is likely that a previous positive result was in error, or that spurious interrupts occurred. The latter doesn't seem to happen.
The hope is that in either case the software clock and callback loop counter get back in sync with the clock signals that were sent from the IRIG card to the other cards.
If the difference is outside those limits, then set clockAction is set to RESET_COUNTERS, so that the tasklet will reset the loop counter and the software clock the next time it is scheduled, and also call the resync callbacks of the clients, so that they could possibly resync their processing.
If the out-of-sync condition is caused by missed interrupts, or a temporary glitch in the irig clock, where it later recovers to be in sync with the output signals, this method should fix the problem.
Since we don't have any other details about the clock signals that were sent to other cards, we only have the value of the irig clock and unix clock to try to re-synchronize.
Another side issue arises when we are running without an IRIG source. This should only happen when bench testing. The pc104sg card still generates signals and interrupts, but they are based on an internal oscillator, which slowly drifts relative to the unix clock. In that case is is harder to determine what to do if a disagreement dTs is seen.
References board, clockStateString(), IRIG_MAX_DT_DIFF, IRIG_MIN_DT_DIFF, RESET_COUNTERS, TMSEC_PER_SOFT_TIC, and TMSECS_PER_DAY.
Referenced by oneHzFunction().
|
static |
References board, SYNCD_SET, and UNSYNCD_SET.
Referenced by checkSoftTicker().
|
static |
References writeDPRAM().
Referenced by pc104sg_init().
|
static |
References board.
Referenced by pc104sg_cleanup(), and pc104sg_init().
|
inlinestatic |
Invoke the callback functions for a given rate.
Referenced by pc104sg_bh_100Hz().
|
static |
Invoke all resync callback functions.
References board, IRIG_NUM_RATES, and rate.
Referenced by pc104sg_bh_100Hz().
|
static |
Enable heart beat interrupts.
References board, and resetHeartBeatLatch().
Referenced by pc104sg_init().
EXPORT_SYMBOL | ( | flush_irig_callbacks | ) |
EXPORT_SYMBOL | ( | irig_clock_gettime | ) |
EXPORT_SYMBOL | ( | ReadClock | ) |
EXPORT_SYMBOL | ( | register_irig_callback | ) |
EXPORT_SYMBOL | ( | TMsecClock | ) |
EXPORT_SYMBOL | ( | unregister_irig_callback | ) |
int flush_irig_callbacks | ( | void | ) |
References board.
Referenced by close_ports(), ncar_a2d_cleanup(), resetBoard(), and stopBoard().
|
static |
Cleanup function that un-registers all callbacks.
References board, handlePendingCallbacks(), and IRIG_NUM_RATES.
Referenced by pc104sg_cleanup().
|
static |
Get value of on-board clock.
References board, getTimeRegisters(), irigTotimespec(), NSECS_PER_TMSEC, SECS_PER_DAY, and TMSECS_PER_SEC.
Referenced by get_irig_timespec_nolock(), irig_clock_gettime(), and pc104sg_ioctl().
|
static |
References get_irig_time_nolock(), and irigTotimespec().
Referenced by pc104sg_init(), and pc104sg_isr().
int get_msec_clock_resolution | ( | ) |
References MSEC_PER_INTERRUPT.
|
inlinestatic |
References board.
Referenced by requestExtendedStatus().
|
static |
Read time from the registers.
Set offset to 0 to read main clock. Set offset to 0x10 to read time of external pulse.
Data are stored in BCD form as 4 byte niblets, containing ones, tens or hundreds value for the respective time fields.
Called by: get_irig_time_nolock(&ti) from the ISR ioctls, from user space irig_clock_gettime(struct timespec* tp) other modules
Since reading the Usec1_Nsec100 value latches the other digits, all these calls hold a spin_lock before calling getTimeRegisters().
References board, and StaticYear.
Referenced by get_irig_time_nolock().
int getTimeUsec | ( | ) |
Read sub-second time fields from the card, return microseconds.
May be useful for watching-the-clock when debugging.
References board, and USECS_PER_MSEC.
|
static |
Handle pending adds and removes of callbacks from the active list for the appropriate rate.
References board.
Referenced by free_callbacks(), gpio_mm_timer_bottom_half(), and pc104sg_bh_100Hz().
void irig_clock_gettime | ( | thiskernel_timespec_t * | tp | ) |
This function is available for use by external modules.
Note that it disables interrupts.
References board, get_irig_time_nolock(), and irigTotimespec().
|
static |
Convert a struct irigTime into a thiskernel_timespec_t.
References LEAPS_THRU_END_OF, NSECS_PER_MSEC, NSECS_PER_USEC, and SECS_PER_DAY.
Referenced by get_irig_time_nolock(), get_irig_timespec_nolock(), irig_clock_gettime(), and irigTotimeval32().
|
static |
Convert a struct irigTime into a struct timeval32.
Not 2038 compatible.
References irigTotimespec(), and NSECS_PER_USEC.
Referenced by pc104sg_ioctl().
|
static |
Convert a struct irigTime to a int64_t time in microseconds.
References LEAPS_THRU_END_OF, SECS_PER_DAY, USECS_PER_MSEC, and USECS_PER_SEC.
Referenced by pc104sg_ioctl().
MODULE_AUTHOR | ( | "Gordon Maclean <maclean@ucar.edu>" | ) |
MODULE_DESCRIPTION | ( | "PC104-SG IRIG Card Driver" | ) |
module_exit | ( | pc104sg_cleanup | ) |
module_init | ( | pc104sg_init | ) |
MODULE_LICENSE | ( | "GPL" | ) |
module_param | ( | A2DClockFreq | , |
int | , | ||
0 | ) |
module_param | ( | IoPort | , |
int | , | ||
0 | ) |
module_param | ( | Irq | , |
int | , | ||
0 | ) |
MODULE_VERSION | ( | REPO_REVISION | ) |
|
static |
References board, checkSoftTicker(), CLOCK_STATUS_NOSYNC, CLOCK_SYNC_NOT_OK, MAX_TMSEC_SINCE_LAST_SYNC, NO_NOTIFY, NOTIFY_CLIENTS, NSECS_PER_TMSEC, NSECS_PER_USEC, PC104SG_SAMPLE_QUEUE_SIZE, RESET_COUNTERS, irig_device::rwaitq, irig_device::samples, SECS_PER_DAY, irig_device::seqnum, irig_device::skippedSamples, SYNCD_SET, TMSECS_PER_DAY, TMSECS_PER_SEC, UNSYNCD_SET, and USECS_PER_SEC.
Referenced by pc104sg_init().
|
static |
Tasklet called 100 times/second in softare interrupt context.
This tasklet maintains the software clock and performs requested regular callbacks.
References board, CLOCK_STATUS_NOSYNC, CLOCK_SYNC_NOT_OK, doCallbacklist(), doResyncCallbacks(), handlePendingCallbacks(), IRIG_0_1_HZ, IRIG_100_HZ, IRIG_10_HZ, IRIG_1_HZ, IRIG_20_HZ, IRIG_25_HZ, IRIG_2_HZ, IRIG_4_HZ, IRIG_50_HZ, IRIG_5_HZ, MAX_TASKLET_COUNTER, NO_ACTION, NO_NOTIFY, NOTIFY_CLIENTS, ReadClock, RESET_COUNTERS, setSoftTickers(), SYNCD_SET, TMSEC_PER_SOFT_TIC, TMsecClock, TMSECS_PER_DAY, and UNSYNCD_SET.
Referenced by pc104sg_init().
|
static |
References board, disableAllInts(), free_callbacks(), and unregister_irig_callback().
Referenced by pc104sg_init().
|
static |
References A2DClockFreq, board, CALLBACK_POOL_SIZE, CLOCK_STATUS_NOSYNC, CLOCK_SYNC_NOT_OK, counterRejam(), disableAllInts(), driver_name, enableHeartBeatInt(), get_irig_timespec_nolock(), INTERRUPT_RATE, IoPort, IRIG_1_HZ, IRIG_NUM_RATES, Irq, MSECS_PER_SEC, NO_NOTIFY, NSECS_PER_MSEC, oneHzFunction(), pc104sg_bh_100Hz(), pc104sg_cleanup(), pc104sg_fops, pc104sg_isr(), ReadClock, register_irig_callback(), REPO_REVISION, requestDPRAM(), RESET_COUNTERS, setHeartBeatOutput(), setMajorTime(), setPrimarySyncReference(), setRate2Output(), setTimeCodeInputSelect(), timespecToirig(), TMsecClock, and UNSYNCD_SET.
|
static |
|
static |
References board, CLOCK_SYNC_NOT_OK, get_irig_timespec_nolock(), requestExtendedStatus(), RESET_COUNTERS, and resetHeartBeatLatch().
Referenced by pc104sg_init().
|
static |
References board, PC104SG_SAMPLE_QUEUE_SIZE, realloc_dsm_circ_buf(), irig_device::rwaitq, and irig_device::samples.
|
static |
References irig_device::read_state, irig_device::rwaitq, and irig_device::samples.
|
static |
References nidas_circbuf_read(), irig_device::read_state, irig_device::rwaitq, and irig_device::samples.
|
static |
References board, free_dsm_circ_buf(), and irig_device::samples.
|
static |
Read dual port RAM.
addr | dual-port RAM address to read |
Called by (all by module init) setHeartBeatOutput(int rate) setPrimarySyncReference(unsigned char val) setRate2Output(int rate) init
References board.
Referenced by setHeartBeatOutput(), setPrimarySyncReference(), and setRate2Output().
struct irig_callback * register_irig_callback | ( | irig_callback_func * | callback, |
irig_callback_func * | resync, | ||
enum irigClockRates | rate, | ||
void * | privateData, | ||
int * | errp ) |
Module function that allows other modules to register their callback function to be called at the given rate.
register_irig_callback can be called at anytime. Note that register_irig_callback and unregister_irig_callback do not alter the active callback lists but instead add requests to a group of pending requests. The loop function, pc104sg_bh_100Hz, does not do any locking on the active list. Once on each pass through the loop it acts on the pending requests.
References board, IRIG_NUM_RATES, and rate.
Referenced by mesa_ioctl(), pc104sg_init(), resetBoard(), and waitFor1PPS().
|
inlinestatic |
The requestDPRAM()/getRequestedDPRAM() pair allow us to break a dual-port read into two parts.
This is used by the interrupt service routine. Each entry into the ISR reads the value ready from the previous request, then issues another request. In this way, the necessary delay between requesting dual-port RAM and actually getting the value happens between interrupts, rather than by a busy wait.
If non ISR code wants to access dual ported RAM, it should do the following, which prevents the ISR from accessing it, without disabling interrupts while accessing the DP ram: spin_lock_irqsave(&board.lock, flags); board.DP_RamExtStatusEnabled = 0; board.DP_RamExtStatusRequested = 0; spin_unlock_irqrestore(&board.lock, flags); Then access the RAM, for example: setYear(n); ... Then re-enable access by the ISR spin_lock_irqsave(&board.lock, flags); board.DP_RamExtStatusEnabled = 1; spin_unlock_irqrestore(&board.lock, flags);
References board.
Referenced by pc104sg_init(), and requestExtendedStatus().
|
inlinestatic |
References board, getRequestedDPRAM(), and requestDPRAM().
Referenced by pc104sg_isr().
|
inlinestatic |
After receiving a heartbeat interrupt, one must reset the heartbeat latch in the handler.
Otherwise either of two bad things will happen, depending on how the system is configured to handle interrupt levels:
References board.
Referenced by enableHeartBeatInt(), and pc104sg_isr().
|
inlinestatic |
After receiving a match interrupt, one must reset the match flag in order to receive further interrupts.
References board.
|
static |
References rate, readDPRAM(), and writeDPRAM().
Referenced by pc104sg_init().
|
static |
Set the IRIG hardware clock fields in DPRAM.
Interrupts are disabled when writing to DPRAM.
References board, NSECS_PER_USEC, RESET_COUNTERS, setMajorTime(), setYear(), timespecToirig(), and USECS_PER_SEC.
Referenced by pc104sg_ioctl().
|
static |
The major time consists of the day-of-year, hour, minute and second fields.
Ideally they are set via the time-code input, but this function can be used if there is no time-code.
The sub-second values are determined from the PPS input, and I see no way to change them if there is no PPS or time-code.
References board, setYear(), and writeDPRAM().
Referenced by pc104sg_init(), and setIRIGclock().
|
static |
Set the primary time reference.
val | 0=PPS is primary time reference, 1=time code is primary |
References readDPRAM(), and writeDPRAM().
Referenced by pc104sg_init().
int setRate2Output | ( | int | rate | ) |
References rate, readDPRAM(), and writeDPRAM().
Referenced by pc104sg_init().
|
static |
Set the software clock and the tasklet loop counter based on a clock value in a timespec struct.
This function is called by the bottom half tasklet if clockAction==RESET_COUNTERS.
Note: we are seeing sub-millisecond agreement between the IRIG register clocks and the system clock (conditioned by NTP), with a GPS-conditioned timeserver providing the IRIG and NTP references.
This function sets TMsecClockTicker from the timespec.
References board, MAX_TASKLET_COUNTER, NSECS_PER_TMSEC, SECS_PER_DAY, TMSEC_PER_SOFT_TIC, TMSECS_PER_DAY, and TMSECS_PER_SEC.
Referenced by pc104sg_bh_100Hz().
|
static |
References writeDPRAM().
Referenced by pc104sg_init().
|
static |
set the year fields in Dual Port RAM.
References StaticYear, and writeDPRAM().
Referenced by setIRIGclock(), and setMajorTime().
|
static |
Break a timespec into the fields of a struct irigTime.
This uses some code from glibc/time routines.
References LEAPS_THRU_END_OF, my_isleap, NSECS_PER_MSEC, NSECS_PER_USEC, SECS_PER_DAY, and SECS_PER_HOUR.
Referenced by pc104sg_init(), and setIRIGclock().
int unregister_irig_callback | ( | struct irig_callback * | cb | ) |
Modules call this function to dequeue their callbacks.
A callback function can cancel itself, or any other callback function.
References board, and IRIG_NUM_RATES.
Referenced by close_ports(), mesa_ioctl(), ncar_a2d_cleanup(), pc104sg_cleanup(), resetBoard(), stopBoard(), and waitFor1PPS().
|
static |
Set a value in dual port RAM.
addr | dual-port RAM address to write Note that it disables interrupts. |
Called by: setHeartBeatOutput(int rate) setPrimarySyncReference(unsigned char val) setTimeCodeInputSelect(unsigned char val) setRate2Output(int rate) counterRejam(void) module init setYear(int val) setMajorTime(struct irigTime* ti) ioctl
References board.
Referenced by counterRejam(), setHeartBeatOutput(), setMajorTime(), setPrimarySyncReference(), setRate2Output(), setTimeCodeInputSelect(), and setYear().
|
static |
Referenced by pc104sg_init().
|
static |
Referenced by checkSoftTicker(), clockStateString(), disableAllInts(), doCallbacklist(), doResyncCallbacks(), enableHeartBeatInt(), flush_irig_callbacks(), free_callbacks(), get_irig_time_nolock(), getRequestedDPRAM(), getTimeRegisters(), getTimeUsec(), handlePendingCallbacks(), irig_clock_gettime(), oneHzFunction(), pc104sg_bh_100Hz(), pc104sg_cleanup(), pc104sg_init(), pc104sg_ioctl(), pc104sg_isr(), pc104sg_open(), pc104sg_release(), readDPRAM(), register_irig_callback(), requestDPRAM(), requestExtendedStatus(), resetHeartBeatLatch(), resetMatchLatch(), setIRIGclock(), setMajorTime(), setSoftTickers(), unregister_irig_callback(), and writeDPRAM().
|
static |
Referenced by pc104sg_init().
|
static |
Referenced by pc104sg_init().
|
static |
Referenced by pc104sg_init().
|
static |
Referenced by pc104sg_init().
int ReadClock = 0 |
Index into TMsecClock of the value to be read.
Referenced by pc104sg_bh_100Hz(), and pc104sg_init().
|
static |
The year field in the pc104sg time registers ranges from 0-99, so we keep track of the century.
Referenced by getTimeRegisters(), and setYear().
int TMsecClock[2] = { 0, 0 } |
A toggle buffer containing the current clock value in tenths of milliseconds since UTC midnight.
Referenced by pc104sg_bh_100Hz(), and pc104sg_init().