⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 host_api.c

📁 三星公司的有线数字高频头资料及源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <bios.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
#include "qam3118.h"
#include "host_api.h"

/* compiler constants */
/* Bit assignments */
#define I2C_SDA             0x08   /* Control for Drive, Status for Sense */
#define I2C_SCL             0x80   /* Printer Port Bit 7 Output           */
#define I2C_WR_TRIG         0x20   /* indicates start of i2c read         */
#define I2C_RD_TRIG         0x10   /* indicates start of i2c read         */
#define SPI_SCK             0x08   /* Printer Port Bit 3 Output           */
#define SPI_SS              0x04   /* Printer Port Bit 2 Output           */
#define SPI_MOSI            0x02   /* Printer Port Bit 1 Output           */
#define SPI_MISO            0x10   /* Status Bit                          */

#define MAX_SNR               50   /* This is the maximum SNR for lock    */
#define CATV_I2C_ADDR  0xc2;
/* Adding New Port...*/
#define SC_0  0x04          // I2C CLOCK Line Reset (bit 3)
#define SC_1  0x0C          // I2C CLOCK Line Set
#define SD_0  0x80          // I2C DATA Line Reset (bit 7)
#define SD_1  0x00          // I2C DATA Line Set
#define SD_R  0x80          // I2C DATA read mask (bit 7)
#define DATAW  0            // LPT DATA Register Offset
#define DATAR  1            // LPT DATA Register Offset
#define CLOCK  2            // LPT CLOCK Regiseter Offset
#define port 0x378          // 278, 378 or 3BC
#define T      20
/********** New End *****************/

/* need to add code to select tuner type */
#define TNR_I2C_ADDR        0xC2  /* tuner addr */

/* global variables */
int                com_initialized = 0;   /* 1 if Printer Port initialized */
extern qamstatus_t qam_status;            /* Receiver Status Information   */
extern int         glb_slave_addr;        /* BCM3118 I2C Bus Slave Address */
extern int         glb_port_data;         /* Printer Port Data    address  */
extern int         glb_port_status;       /* Printer Port Status  address  */
extern int         glb_port_control;      /* Printer Port Control address  */
extern int         glb_stosc1,glb_stosc2; /* used to compute lo_freq       */
extern int NTSC;
/* if selected, include test routines */
#ifdef TEST
#include "test.c"
#endif

/********************************************************************
*********************************************************************/
int  i2c_ping(int addr)
{
  int ack_seen=0,send_data,i,j,mask;

  /* generate the start bit */
  outportb(glb_port_control, 0);
  outportb(glb_port_data, I2C_SCL);

  /* transmit slave address */
  for (i=0; i<2; i++) {
    send_data = (i == 0) ? 2 * addr + 1 : 0xff;   /* read specified address */
    mask = 0x80;
    for (j=0; j<8; j++) {
      outportb(glb_port_control,(mask & send_data) ? I2C_SDA : 0);      /* set data bit */
      outportb(glb_port_data, 0  );                                     /* set clock hi */
      outportb(glb_port_data, I2C_SCL);                                 /* set clock lo */
      mask = (mask >> 1);
    }
    /* test if the ack bit is set */
    if ((i == 0) && ((inportb(glb_port_status) & I2C_SDA) == 0)) ack_seen = 1;
    /* generate the acknowledge bit */
    outportb(glb_port_data, 0  );        /* set clock hi */
    outportb(glb_port_data, I2C_SCL);    /* set clock lo */
  }

  /* generate the stop bit */
  outportb(glb_port_control, 0);
  outportb(glb_port_data, 0);
  outportb(glb_port_control, I2C_SDA);

  if (ack_seen) {
    printf("Addr 0x%02x ... has acknowledged\n",addr);
    return QAM_OK;
  } else {
    printf("Addr 0x%02x ... has not acknowledged\n",addr);
    return QAM_ERROR;
  }
}

int qam_read_status()
{
	float  offset;
  int    i,avg_err,avg_err_lsbs,ival,qval,ib_error_cnt,ob_error_cnt;
  long   lval;
  double dval;

  /* get current QAM Mode setting ... set by acquision script */
  qam_read(SB_RW,SB_QAMCTL,&i,&i);
  SET_QAM_MODE(0x07 & i);

  /* Get SNR Estimate */
  qam_read(MB_R,MB_LDSNRE,&avg_err,&avg_err_lsbs);
  if (avg_err < 8) qam_status.snr_estimate = 0.0;
  else  {
	switch (QAM_MODE) {
      case QAM_4   : offset = OFFSET_QAM_4;     break;
      case QAM_16  : offset = OFFSET_QAM_16;    break;
      case QAM_32  : offset = OFFSET_QAM_32;    break;
      case QAM_64  : offset = OFFSET_QAM_64;    break;
      case QAM_128 : offset = OFFSET_QAM_128;   break;
      case QAM_256 : offset = OFFSET_QAM_256;   break;
	}
    qam_status.snr_estimate = offset - 20.0 * log10(avg_err);
  }

  /* compute the received symbol_rate                */
  /* symbol_rate = LDBROS * ref_freq / 0x1000000 */

  qam_read(MB_R,MB_LDBRFO,&ival,&qval);
  lval = (long) ival;
  lval = (lval << 8) + (qval >> 8);
  dval = ((double) lval) * (double) qam_status.ref_freq / (double)(0x1000000L);
  qam_status.symbol_rate = (float) dval;  /* this value is in MHz */
  /* compute the lo frequency */
  qam_status.lo_freq = 2.0*qam_status.ref_freq*(1+glb_stosc2)/(1+glb_stosc1);

  /* Read FFECTL register to determine who is the main tap */
  qam_read(SB_R, SB_FFECTL, &i, &i);
  switch( i & 0x38 ) {
	case 0x00:  /* position F0 */	 qam_read(MB_R, MB_LDF0, &ival, &qval);	break;
    case 0x08:  /* position F1 */  qam_read(MB_R, MB_LDF1, &ival, &qval); break;
    case 0x10:  /* position F2 */  qam_read(MB_R, MB_LDF2, &ival, &qval);	break;
    case 0x18:  /* position F3 */  qam_read(MB_R, MB_LDF3, &ival, &qval);	break;
    case 0x20:  /* position F4 */  qam_read(MB_R, MB_LDF4, &ival, &qval);	break;
    case 0x28:  /* position F5 */  qam_read(MB_R, MB_LDF5, &ival, &qval);	break;
    case 0x30:  /* position F6 */  qam_read(MB_R, MB_LDF6, &ival, &qval);	break;
    case 0x38:  /* position F7 */  qam_read(MB_R, MB_LDF7, &ival, &qval);	break;
  }
  /* read the FEC error count, accumulate, and compute BER */
  /* (Note: this is done elsewhere) */
  /* set lock flags in status byte */
  if ((ival > 0x2000) && (qam_status.snr_estimate > qam_status.lock_thresh) &&
			 (qam_status.snr_estimate < MAX_SNR)) {
		qam_status.status |= QAM_LOCK_STATUS;
		/* Check for FEC lock only if QAM_LOCK */
		/* Read the IRQ register to see if FEC in lock */
		qam_read(SB_R,SB_IRQCTL,&ival,&qval);
		if ((ival & 0x08) == 0x08) {
		       qam_status.status |= FEC_LOCK_STATUS;
		} else {
		       qam_status.status &= (~FEC_LOCK_STATUS);
		}
  } else {
		qam_status.status &= (~QAM_LOCK_STATUS);
		qam_status.status &= (~FEC_LOCK_STATUS);
  }

  /* if auto lock enabled and out of lock, reacquire */
  if (((qam_status.status & QAM_LOCK_STATUS)  == 0) &&
		 (qam_status.status & ACQUISITION_MODE)) {
		qam_init(qam_status.acq_script);
  }

  return QAM_OK;
}
/********************************************************************
* qam_init - this routine runs the specified acquisition script. The
* script file must be in the binary script format and must be located
* in the SCRIPT directory.
*********************************************************************/
int  qam_init(char *fname)
{
  FILE *fp;
  char buf[80];
  int  i, op, mb_op, n, msg_buf[8], lineno=1;
  int ival, qval, rev=0;

  /* open the file */
  qam_read(MB_R,MB_LDID,&ival,&qval);
  rev = 0x02 & ival;

  if (rev == 2) {
        sprintf(buf,"scriptb\\%s.bin", fname);
  } else {
	sprintf(buf,"script\\%s.bin", fname);
  }
  if ((fp = fopen(buf,"r")) == (FILE *) NULL) {
      return QAM_ERROR;
  }

  /* execute file */
  qam_status.status &= (~RUNTIME_ERROR);   /* reset script error bit */
  while (fscanf(fp,"%x",&op) == 1) {
    switch (op) {
      case MSG_DELAY:   /* delay */
			fscanf(fp,"%x",&n);
			delay(n);
			break;

      case MSG_WR_SB:   /* single byte write */
			#if 1
			fscanf(fp,"%x%x",&msg_buf[1],&msg_buf[2]);

			  msg_buf[0] = (glb_slave_addr << 1);
			  i2c_write(3,msg_buf);
			#endif
			break;

      case MSG_WR_MB:   /* multi-byte write (all 4 multi bytes are always written) */
			fscanf(fp,"%x%x%x%x%x",&mb_op,&msg_buf[2],&msg_buf[3],&msg_buf[4],&msg_buf[5]);
			msg_buf[0] = (glb_slave_addr << 1);
			msg_buf[1] = MBYTE0;
			  i2c_write(6,msg_buf);
			  msg_buf[1] = MBYTEOP;
			  msg_buf[2] = mb_op;
			  i2c_write(3,msg_buf);
			break;

      case 0xff:        fclose(fp);
			return QAM_OK;

      default  :        qam_status.status |= RUNTIME_ERROR;
			qam_status.errno = SCR_ERROR;
			qam_status.scr_lineno = lineno;
			return QAM_ERROR;
	 }
	 lineno++;
 }
	 return QAM_ERROR;
}

/********************************************************************
* qam_write - this routine writes data to the bcm3118 chip.
* The 'access' argument defines (single/multi-byte type and r/w permission)
* The 'option' argument defines the register to be written to.
* The 'val1' and 'val2' arguments define the data. Not all
* options require both values. Either the SPI or I2C bus is used
* to communicate depending on the qam status byte.
* This routine returns QAM_OK for success, QAM_ERROR for failure.
*********************************************************************/
int qam_write(int access, int option, int val1, int val2)
{

  int  msg_buf[8];

  if ((access & 0x06) == 0x02) { /* single byte write-able reg */
		msg_buf[0] = (glb_slave_addr << 1);
		msg_buf[1] = 0xff & option;
		msg_buf[2] = val1;
		i2c_write(3,msg_buf);
		return QAM_OK;
  } else if ((access & 0x04) == 0x04) { /* papi cauttion 0x05..0x06 see head file multi byte write-able reg */
		msg_buf[0] = (glb_slave_addr << 1);
		msg_buf[1] = MBYTE0;
		msg_buf[2] = 0x00ff & (val1 >> 8);
		msg_buf[3] = 0x00ff & val1;
		msg_buf[4] = 0x00ff & (val2 >> 8);
		msg_buf[5] = 0x00ff & val2;
			i2c_write(6,msg_buf);
		/* write to the op code register */
		msg_buf[1] = MBYTEOP;
		msg_buf[2] = option;
		i2c_write(3,msg_buf);
		if (option == MB_STOSC1) glb_stosc1 = 0x00ff & (val1 >> 8);
		if (option == MB_STOSC2) glb_stosc2 = 0x00ff & (val1 >> 8);
		return QAM_OK;

  } else {
		return QAM_ERROR;
  }
}



/********************************************************************
* qam_read - this routine reads data from the bcm3118 chip.
* The 'access' argument defines (single/multi-byte type and r/w permission)
* The 'option' argument defines the register to be read.
* The 'val1' and 'val2' arguments point to where returned data is stored.
* Not all options require both values. For data values wider than 16-bits,
* val1 contains the upper 16-bits, val2 contains the remaining bits.
* This routine returns QAM_OK for success, QAM_ERROR for failure.
*********************************************************************/
int qam_read(int access, int option, int *val1, int *val2)
{
  int msg_buf[8];

  qam_status.errno = 0;
  if ((access & 0x05) == 0x01) { /* single byte read-able reg */
		msg_buf[0] = (SPI_MODE) ? 0x50 : (glb_slave_addr << 1);
		msg_buf[1] = option;
			i2c_read(1,msg_buf);
		*val1 = msg_buf[2];
		return QAM_OK;

  } else if ((access & 0x05) == 0x05) { /* multi byte read-able reg */
		/* read multi-byte registers for selected option */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -