home *** CD-ROM | disk | FTP | other *** search
/ C!T ROM 5 / ctrom5b.zip / ctrom5b / CT / CT9404 / TTDEMO / SOURCE.ZIP / TUNEFUNC.C < prev    next >
C/C++ Source or Header  |  1994-02-01  |  7KB  |  241 lines

  1. /***********************************************
  2. * tunefunc.c                                   *
  3. * Copyright (c) 1993 QQS - All rights reserved *
  4. * This file is donated to the public domain    *
  5. *                                              *
  6. * version 1.0 May 31, 1993                     *
  7. * functions for tuning                         *
  8. * last update: 1.3 September 29, 1993          *
  9. ***********************************************/
  10.  
  11. #include <dos.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14.  
  15. #include <vector.h>
  16.  
  17. #include <tunefunc.h>
  18.  
  19. extern unsigned int hardaddr; // address of card
  20.  
  21. #define TRUE  1
  22. #define FALSE 0
  23.  
  24. // i2c clock out (hardaddr + 2) & 8 -> 0 = +5V, 1 = 0V, default & reset 0 = +5V
  25. // i2c clock in (hardaddr + 2) & 8 -> 0 = +5V, 1 = 0V, default & reset 0 = +5V
  26. // i2c data out (hardaddr + 2) & 4 -> 0 = +5V, 1 = 0V, default & reset 0 = +5V
  27. // i2c data in  (hardaddr + 2) & 4 -> 0 = 0V, 1 = +5V
  28.  
  29. /* defines for calls to SetI2C, ON -> +5V, OFF -> 0 V */
  30. #define CLKON      0
  31. #define CLKOFF     0x8
  32. #define DATON      0
  33. #define DATOFF     0x4
  34.  
  35. extern void interrupt MyTimer(void); // at end of file
  36.  
  37. void (far* far Timer)(void); // Pointer to real timer interrupt function
  38. unsigned long LoopCount, MaxLoopCount; // Counters for timing
  39. int tunerinitialized = FALSE; // Boolean for timer loop control
  40.  
  41. /* after WaitI2CInit() is finished, waits approx. 1/9100th second. In
  42.    WaitI2CInit() this loop waits until a timer tick occurs. */
  43. static void WaitI2C(void)
  44. {
  45.   for (LoopCount = 0L; LoopCount < MaxLoopCount; LoopCount++)
  46.     if (!tunerinitialized) /* can only break when called from WaitI2CInit() */
  47.       break;
  48. }
  49.  
  50. static void WaitI2CInit(void)
  51. /* initialize LoopCount for timing */
  52. {
  53.   if(tunerinitialized)
  54.     return;
  55.   tunerinitialized = FALSE;
  56.   MaxLoopCount = 0xffffffffL;
  57.   Timer = GetInterruptVector(8); // get timer interrupt
  58.   SetInterruptVector(8, MyTimer); // hook MyTimer
  59.   while (!tunerinitialized) // wait for first timer tick
  60.     ;
  61.   WaitI2C(); /* we will be in the loop for 1 tick */
  62.   SetInterruptVector(8, Timer); // unhook MyTimer
  63.   // LoopCount times 1/55th second -> LoopCount / 1450 times 1/80000th second
  64.   MaxLoopCount = LoopCount / 1450;
  65.   if (MaxLoopCount == 0) // this might be too small
  66.     MaxLoopCount = 1;
  67.   tunerinitialized = TRUE; // remains TRUE for rest of program
  68. }
  69.  
  70. static void SetI2C(unsigned char Clock, unsigned char Data)
  71. /* set Clock and Data values */
  72. {
  73.   unsigned char remain;
  74.  
  75.   remain = inportb(hardaddr + 2) & 0x3; // keep tuner & tt selection
  76.   asm db 0ebh, 0 ; /* jmp short $+2, short wait */
  77.   outportb(hardaddr + 2, Clock | Data | remain);
  78.   asm db 0ebh, 0 ; /* jmp short $+2, short wait */
  79. }
  80.  
  81. static int GetI2C(void)
  82. /* return whether data is ON */
  83. {
  84.   return (inportb(hardaddr + 2) & 0x4) != 0;
  85. }
  86.  
  87. static void StartI2C(void)
  88. /* set I2C to start condition */
  89. {
  90.   SetI2C(CLKON, DATOFF);
  91.   SetI2C(CLKOFF, DATOFF);
  92. }
  93.  
  94. static void StopI2C(void)
  95. /* (re)set I2C to stop condition */
  96. {
  97.   SetI2C(CLKON, DATOFF);
  98.   SetI2C(CLKON, DATON);
  99. }
  100.  
  101. static int SendByteI2C(unsigned char Byte)
  102. /* send byte to I2C, I2C must be in startcondition (clk = 0), return whether 
  103.    success */
  104. {
  105.   unsigned char bit;
  106.   int result;
  107.  
  108.   for (bit = 0x80; bit; bit >>= 1)
  109.   {
  110.     // send a bit
  111.     SetI2C(CLKOFF, (Byte & bit) ? DATON : DATOFF);
  112.     SetI2C(CLKON, (Byte & bit) ? DATON : DATOFF);
  113.     WaitI2C();
  114.     SetI2C(CLKOFF, (Byte & bit) ? DATON : DATOFF);
  115.   }
  116.   // get acknowledge
  117.   SetI2C(CLKOFF, DATON);
  118.   SetI2C(CLKON, DATON);
  119.   WaitI2C();
  120.   result = !GetI2C();  // must return FALSE, tuner has set DATOFF
  121.   SetI2C(CLKOFF, DATOFF);
  122.   return result;
  123.  
  124. static void RecByteI2C(unsigned char* Byte)
  125. /* receive Byte from I2C, I2C must be in startcondition (clk = OFF) */
  126. {
  127.   unsigned char bit;
  128.  
  129.   *Byte = 0;
  130.   for (bit = 0x80; bit; bit >>= 1)
  131.   {
  132.     // receive a bit
  133.     SetI2C(CLKOFF, DATON);
  134.     SetI2C(CLKON, DATON);
  135.     WaitI2C();
  136.     if (GetI2C())
  137.       *Byte |= bit;
  138.   }
  139.   SetI2C(CLKOFF, DATON);
  140.  
  141. static int WriteI2C(int Count, unsigned char far* Buffer)
  142. /* write Buffer[0..Count-1] to I2C, return whether success */
  143. {
  144.   StartI2C();
  145.   while (Count-- > 0)
  146.     if (!SendByteI2C(*Buffer++))
  147.       break; // not acknowledged
  148.   StopI2C();
  149.   return Count < 0;
  150. }
  151.  
  152. int InitTune(void)
  153. /* return whether I2C functions correctly. if TRUE tuner is initialized. */
  154. {
  155.   int result;
  156.  
  157.   WaitI2CInit();
  158.   SetI2C(CLKON, DATON);
  159.   WaitI2C();
  160.   if (!GetI2C())
  161.     return FALSE;
  162.   SetI2C(CLKON, DATOFF);
  163.   WaitI2C();
  164.   result = !GetI2C();
  165.   StopI2C();
  166.   return result;
  167. }
  168.  
  169. int GetStatus(unsigned char* Status)
  170. /* get status from tuner, return whether success */
  171. {
  172.   int result = TRUE;
  173.  
  174.   StartI2C();
  175.   if ((result = SendByteI2C(0xc3)) == TRUE)
  176.     RecByteI2C(Status);
  177.   StopI2C();
  178.   return result;
  179. }
  180.  
  181. int SetFreq(unsigned long Freq)
  182. /* set tuner to given frequency Freq in Hz, return whether success.
  183.    InitTune() must have been called before use. */
  184. {
  185.   unsigned char band, buffer[5];
  186.   unsigned int divider;
  187.  
  188.   if (Freq < 46000000L || Freq > 870000000L)
  189.     return FALSE;
  190.   if (Freq < 175250000L)
  191.     band = 0xa0;  // low band
  192.   else
  193.   if (Freq < 455250000L)
  194.     band = 0x90;  // mid band
  195.   else
  196.     band = 0x30;  // high band
  197.   divider = (unsigned int)((Freq + 38900000L) / 62500L);
  198.   buffer[0] = 0xc2;
  199.   buffer[1] = (unsigned char)(divider >> 8);
  200.   buffer[2] = (unsigned char)(divider & 0xff);
  201.   buffer[3] = 0x8e; // CP -> moderate tuning speed with quality
  202.   buffer[4] = band;
  203.   return WriteI2C(5, buffer);
  204. }
  205.  
  206. int SelectChannel(unsigned long freq)
  207. /* freq == 0 -> direct video,
  208.    freq != 0 -> tune frequency freq on tuner.
  209.    initializes tuner if neccesary, return whether success */
  210. {
  211.   unsigned char remain;
  212.  
  213.   remain = inportb(hardaddr + 2) & 1; // keep tt interrupt on/off selection
  214.   if (freq == 0)
  215.   {
  216.     outportb(hardaddr + 2, remain); /* select video */
  217.     return TRUE;
  218.   }
  219.   if(!tunerinitialized)
  220.     if(!InitTune())
  221.       return FALSE;
  222.   outportb(hardaddr + 2, 0x02 | remain); /* select tuner */
  223.   return SetFreq(freq);
  224. }
  225.  
  226. /* Timer interrupt handler */
  227.  
  228. #pragma option -N-  // no stack check
  229. #pragma option -r-  // no register vars
  230.  
  231. void interrupt MyTimer(void)
  232. /* Timer interrupt */
  233. {
  234.   tunerinitialized = !tunerinitialized; // control loop timing
  235.   asm pushf
  236.   (*Timer)(); // call regular timer interrupt
  237. }
  238.  
  239.