home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C!T ROM 5
/
ctrom5b.zip
/
ctrom5b
/
CT
/
CT9404
/
TTDEMO
/
SOURCE.ZIP
/
TUNEFUNC.C
< prev
next >
Wrap
C/C++ Source or Header
|
1994-02-01
|
7KB
|
241 lines
/***********************************************
* tunefunc.c *
* Copyright (c) 1993 QQS - All rights reserved *
* This file is donated to the public domain *
* *
* version 1.0 May 31, 1993 *
* functions for tuning *
* last update: 1.3 September 29, 1993 *
***********************************************/
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector.h>
#include <tunefunc.h>
extern unsigned int hardaddr; // address of card
#define TRUE 1
#define FALSE 0
// i2c clock out (hardaddr + 2) & 8 -> 0 = +5V, 1 = 0V, default & reset 0 = +5V
// i2c clock in (hardaddr + 2) & 8 -> 0 = +5V, 1 = 0V, default & reset 0 = +5V
// i2c data out (hardaddr + 2) & 4 -> 0 = +5V, 1 = 0V, default & reset 0 = +5V
// i2c data in (hardaddr + 2) & 4 -> 0 = 0V, 1 = +5V
/* defines for calls to SetI2C, ON -> +5V, OFF -> 0 V */
#define CLKON 0
#define CLKOFF 0x8
#define DATON 0
#define DATOFF 0x4
extern void interrupt MyTimer(void); // at end of file
void (far* far Timer)(void); // Pointer to real timer interrupt function
unsigned long LoopCount, MaxLoopCount; // Counters for timing
int tunerinitialized = FALSE; // Boolean for timer loop control
/* after WaitI2CInit() is finished, waits approx. 1/9100th second. In
WaitI2CInit() this loop waits until a timer tick occurs. */
static void WaitI2C(void)
{
for (LoopCount = 0L; LoopCount < MaxLoopCount; LoopCount++)
if (!tunerinitialized) /* can only break when called from WaitI2CInit() */
break;
}
static void WaitI2CInit(void)
/* initialize LoopCount for timing */
{
if(tunerinitialized)
return;
tunerinitialized = FALSE;
MaxLoopCount = 0xffffffffL;
Timer = GetInterruptVector(8); // get timer interrupt
SetInterruptVector(8, MyTimer); // hook MyTimer
while (!tunerinitialized) // wait for first timer tick
;
WaitI2C(); /* we will be in the loop for 1 tick */
SetInterruptVector(8, Timer); // unhook MyTimer
// LoopCount times 1/55th second -> LoopCount / 1450 times 1/80000th second
MaxLoopCount = LoopCount / 1450;
if (MaxLoopCount == 0) // this might be too small
MaxLoopCount = 1;
tunerinitialized = TRUE; // remains TRUE for rest of program
}
static void SetI2C(unsigned char Clock, unsigned char Data)
/* set Clock and Data values */
{
unsigned char remain;
remain = inportb(hardaddr + 2) & 0x3; // keep tuner & tt selection
asm db 0ebh, 0 ; /* jmp short $+2, short wait */
outportb(hardaddr + 2, Clock | Data | remain);
asm db 0ebh, 0 ; /* jmp short $+2, short wait */
}
static int GetI2C(void)
/* return whether data is ON */
{
return (inportb(hardaddr + 2) & 0x4) != 0;
}
static void StartI2C(void)
/* set I2C to start condition */
{
SetI2C(CLKON, DATOFF);
SetI2C(CLKOFF, DATOFF);
}
static void StopI2C(void)
/* (re)set I2C to stop condition */
{
SetI2C(CLKON, DATOFF);
SetI2C(CLKON, DATON);
}
static int SendByteI2C(unsigned char Byte)
/* send byte to I2C, I2C must be in startcondition (clk = 0), return whether
success */
{
unsigned char bit;
int result;
for (bit = 0x80; bit; bit >>= 1)
{
// send a bit
SetI2C(CLKOFF, (Byte & bit) ? DATON : DATOFF);
SetI2C(CLKON, (Byte & bit) ? DATON : DATOFF);
WaitI2C();
SetI2C(CLKOFF, (Byte & bit) ? DATON : DATOFF);
}
// get acknowledge
SetI2C(CLKOFF, DATON);
SetI2C(CLKON, DATON);
WaitI2C();
result = !GetI2C(); // must return FALSE, tuner has set DATOFF
SetI2C(CLKOFF, DATOFF);
return result;
}
static void RecByteI2C(unsigned char* Byte)
/* receive Byte from I2C, I2C must be in startcondition (clk = OFF) */
{
unsigned char bit;
*Byte = 0;
for (bit = 0x80; bit; bit >>= 1)
{
// receive a bit
SetI2C(CLKOFF, DATON);
SetI2C(CLKON, DATON);
WaitI2C();
if (GetI2C())
*Byte |= bit;
}
SetI2C(CLKOFF, DATON);
}
static int WriteI2C(int Count, unsigned char far* Buffer)
/* write Buffer[0..Count-1] to I2C, return whether success */
{
StartI2C();
while (Count-- > 0)
if (!SendByteI2C(*Buffer++))
break; // not acknowledged
StopI2C();
return Count < 0;
}
int InitTune(void)
/* return whether I2C functions correctly. if TRUE tuner is initialized. */
{
int result;
WaitI2CInit();
SetI2C(CLKON, DATON);
WaitI2C();
if (!GetI2C())
return FALSE;
SetI2C(CLKON, DATOFF);
WaitI2C();
result = !GetI2C();
StopI2C();
return result;
}
int GetStatus(unsigned char* Status)
/* get status from tuner, return whether success */
{
int result = TRUE;
StartI2C();
if ((result = SendByteI2C(0xc3)) == TRUE)
RecByteI2C(Status);
StopI2C();
return result;
}
int SetFreq(unsigned long Freq)
/* set tuner to given frequency Freq in Hz, return whether success.
InitTune() must have been called before use. */
{
unsigned char band, buffer[5];
unsigned int divider;
if (Freq < 46000000L || Freq > 870000000L)
return FALSE;
if (Freq < 175250000L)
band = 0xa0; // low band
else
if (Freq < 455250000L)
band = 0x90; // mid band
else
band = 0x30; // high band
divider = (unsigned int)((Freq + 38900000L) / 62500L);
buffer[0] = 0xc2;
buffer[1] = (unsigned char)(divider >> 8);
buffer[2] = (unsigned char)(divider & 0xff);
buffer[3] = 0x8e; // CP -> moderate tuning speed with quality
buffer[4] = band;
return WriteI2C(5, buffer);
}
int SelectChannel(unsigned long freq)
/* freq == 0 -> direct video,
freq != 0 -> tune frequency freq on tuner.
initializes tuner if neccesary, return whether success */
{
unsigned char remain;
remain = inportb(hardaddr + 2) & 1; // keep tt interrupt on/off selection
if (freq == 0)
{
outportb(hardaddr + 2, remain); /* select video */
return TRUE;
}
if(!tunerinitialized)
if(!InitTune())
return FALSE;
outportb(hardaddr + 2, 0x02 | remain); /* select tuner */
return SetFreq(freq);
}
/* Timer interrupt handler */
#pragma option -N- // no stack check
#pragma option -r- // no register vars
void interrupt MyTimer(void)
/* Timer interrupt */
{
tunerinitialized = !tunerinitialized; // control loop timing
asm pushf
(*Timer)(); // call regular timer interrupt
}