Index:
[thread]
[date]
[subject]
[author]
From: Thomas Tanner <tanner@gmx.de>
To : GGI mailing list <ggi-develop@eskimo.com>
Date: Fri, 07 Aug 1998 19:44:28 +0000
ANNOUNCE: vertical retrace sync via RT-Linux
HI
I've written a simple RT-Linux module that does
vertical retrace synchronisation on VGA compatible cards.
A RT-Linux task is called on every vertical retrace and will call a
function of the KGI-driver, which itself may, for example, set the palette
and switch the displayed frame.
You can download the module and the instructions how to use it from
my home page: http://home.pages.de/~tanner/ggi.html#vsync
Special thanks go to Bernhard Kuhn who wrote the initial code and helped me a lot.
RT-Linux is a pico-OS that runs Linux as its idle task and
allows special tasks to run in realtime (even under heavy load).
The good thing about RT-Linux is that you do not notice any difference
to a normal Linux system unless you start a RT-Linux task.
That's the reason why RT-Linux will get into Linux 2.3 and
will be enabled by default in Linux 2.4
Attached is the source of the module.
RT-Linux: http://www.rtlinux.org
--
Thomas Tanner -----------------------------
email: tanner@gmx.de tanner@ggi-project.org
web: http://home.pages.de/~tanner
GGI: http://www.ggi-project.org
/*
* Vertical retrace synchronisation with RT-Linux (VGA)
*
* Copyright (C) 1998 by Thomas Tanner <tanner@ggi-project.org>
* Copyright (C) 1998 by Bernhard Kuhn <kuhn@lpr.e-technik.tu-muenchen.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
*
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/version.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <rtl_sched.h>
#include <rtl_fifo.h>
/* VGA vrt bit */
#define VRT_BIT() (inb(0x3DA) & 8)
/* ticks per µs */
#define TICKS(us) (RT_TICKS_PER_SEC * us) / 1000000L
void print_time(int fifo, RTIME time)
{
char *hex="0123456789ABCDEF\n";
int i;
#ifdef BIG_ENDIAN
for(i = 0; i < sizeof(RTIME); i++) {
#else
for(i = sizeof(RTIME)-1; i >= 0; i--) {
#endif
rtf_put(fifo, &hex[(char) (time >> (i * 4)) & 0xF], 1);
}
rtf_put(fifo, &hex[16], 1);
}
RTIME period;
void vrt_handler(void)
{
/* write to first FIFO */
/* rtf_put(1, ".\n", 2);*/
print_time(1, period);
}
/* the realtime task */
RT_TASK vsync_task;
void periodic_vsync_task(int t)
{
RTIME time, last;
/* vsync calibration */
period = 0;
do {
last = period;
/* wait for low->high transition and then get the time */
while(VRT_BIT());
while(!VRT_BIT());
time = rt_get_time();
/* wait for high->low transition and then get the time */
while(VRT_BIT());
while(!VRT_BIT());
period = rt_get_time();
/* calculate difference */
period -= time;
} while (abs(period - last) > 2);
/* wait for high->low to start the periodic task */
while(VRT_BIT());
/* start */
for(;;) {
/* wait for low->high (max. 20µs) */
while(!VRT_BIT());
/* ok. prepare for next time */
/* substract 20µs to be able to wait for the vrt */
rt_task_make_periodic(&vsync_task,
rt_get_time(), period - TICKS(20));
/* call the vrt handler */
vrt_handler();
/* wait for next vrt */
rt_task_wait();
}
}
void init_vsync_handler(void)
{
/* create output FIFO */
rtf_create(1, 4096);
/* create realtime task for vertical retrace synchronisation */
rt_task_init(&vsync_task, periodic_vsync_task, 0, 2048, 1);
/* now start the task */
rt_task_make_periodic(&vsync_task, rt_get_time(), TICKS(1000000));
}
void cleanup_vsync_handler(void)
{
/* delete the realtime task */
rt_task_delete(&vsync_task);
/* destroy the output FIFO */
rtf_destroy(1);
}
int init_module(void)
{
init_vsync_handler();
return 0;
}
void cleanup_module(void)
{
cleanup_vsync_handler();
}
Index:
[thread]
[date]
[subject]
[author]