#include <rtl.h>
#include <rtl_time.h>
#include <rtl_fifo.h>
#include <asm/rt_irq.h>
#include <asm/rt_time.h>
#include <rtl_sched.h>
#include <asm/io.h>
#include <linux/cons.h>
#include <pthread.h>
#include <time.h>
#include <rtl_sched.h>
#include <rtl_sync.h>
#include <unistd.h>
#include <rtl_debug.h>
#include <errno.h>
#define LPT 0x378
#define LPT_IRQ 7
#define RTC_IRQ 8
struct sample {
hrtime_t min;
hrtime_t max;
};
/* all time values in nano-seconds */
#define TIMEOUT 10000000
#define SAMPLES 10
pthread_t thread;
hrtime_t min_response;
hrtime_t max_response;
struct sample samp;
int samples;
void * irq_gen(void *arg) {
/* putting these in registers prevents
* additional delays due to load and
* store to memory during the timing loop
*/
register int i;
register int orig;
int old_interrupts;
hrtime_t before, after, response;
struct sched_param p;
p . sched_priority = 1;
pthread_setschedparam (pthread_self(),
SCHED_FIFO, &p);
pthread_make_periodic_np (pthread_self(),
gethrtime(), 100000000);
while (1) {
min_response = 2000000000;
max_response = 0;
for (samples = 0;samples < SAMPLES;samples++){
/* turn off interrupts so we really get the */
/* round-trip time by the busy-wait loop */
rtl_no_interrupts(old_interrupts);
outb_p(0xf, LPT); /* ACK is 1 for logic 0 */
orig = inb_p(LPT + 1);
outb(0x0, LPT); /* trigger an interrupt */
before = gethrtime();
i = 0;
/* the busy wait loop,poling the interrupt */
/* pin of the parallel port .*/
while ((inb(LPT + 1) == orig) && i++ < TIMEOUT);
after = gethrtime();
/* if this loop were not present the system */
/* would wait for ever until an interrupt is */
/* polled on ACK of the parport. */
if (i >= TIMEOUT) {
rtl_printf("timeout!!!\n");
return 0;
}
response = after - before;
if (response < min_response) {
min_response = response;
}
if (response > max_response) {
max_response = response;
}
/* restore interrupts before sending */
/* the thread to sleep */
rtl_restore_interrupts(old_interrupts);
pthread_wait_np();
}
samp.min = min_response;
samp.max = max_response;
rtf_put(0, &samp, sizeof(samp));
}
return 0;
}
int init_module(void)
{
rtf_destroy(0);
rtf_create(0, 4000);
return pthread_create (&thread,NULL,irq_gen,0);
}
void cleanup_module(void)
{
rtl\_printf ("Removing rt_gen_irq on CPU %d
and clearing ACK on %d\n",rtl_getcpuid(),LPT);
outb_p(0xf, LPT); /* clear ACK on parport */
pthread_delete_np (thread);
rtf_destroy(0);
}