📄 host_api.c
字号:
msg_buf[0] = (glb_slave_addr << 1);
msg_buf[1] = MBYTEOP;
msg_buf[2] = option;
i2c_write(3,msg_buf);
msg_buf[0] = (SPI_MODE) ? 0x50 : (glb_slave_addr << 1);
msg_buf[1] = MBYTE0;
i2c_read(4,msg_buf);
if (option == MB_LDSFT) {
*val1 = msg_buf[2];
*val2 = msg_buf[3];
} else {
*val1 = (msg_buf[2] << 8) + msg_buf[3];
*val2 = (msg_buf[4] << 8) + msg_buf[5];
}
return QAM_OK;
} else {
return QAM_ERROR;
}
}
/************************************************************
* i2c_read - this routine reads data from an I2C bus slave.
* The argument 'nbytes' defines the number of bytes to read.
* The minimum read length is 1 byte. The data read is stored
* in msg_data[2 ... 2+nbytes].
* RETURNS: QAM_OK if the message bytes were acknowledged properly,
* QAM_ERROR otherwise.
*************************************************************/
int i2c_read(int nbytes, int msg_data[])
{
int i,j,n,mask,no_ack=0;
int send_data,rcv_data;
int num_to_write;
/* generate the start bit */
outportb(port+DATAW, SD_1); /* set sda hi */
outportb(port+CLOCK, SC_1);mydelay(); /* set scl hi */
outportb(port+DATAW, SD_0);mydelay(); /* set sda lo */
outportb(port+CLOCK, SC_0);mydelay(); /* set scl lo */
/* write the address you want to read */
for (n=0; n<2; n++) {
switch (n) {
case 0: send_data = 0xfe & msg_data[0]; break;
case 1: send_data = msg_data[1]; break;
}
/* transmit the data */
mask = 0x80;
for (i=0; i<8; i++) {
outportb(port+DATAW,(mask & send_data) ? SD_1 : SD_0);mydelay(); /* set sda bit */
outportb(port+CLOCK, SC_1 );mydelay(); /* set scl hi */
outportb(port+CLOCK, (SC_0));mydelay(); /* set scl lo */
mask = (mask >> 1);
}
/* generate the acknowledge bit */
outportb(port+DATAW,SD_1 );
outportb(port+CLOCK, SC_1 );mydelay(); /* set scl hi */
if (inportb(port+DATAR) & SD_R) no_ack=1;mydelay(); /* verify ack */
outportb(port+CLOCK, (SC_0));mydelay(); /* set scl lo */
}
/* generate a stop/start (or repeated start) */
#ifdef NO_REPEAT_START
outportb(port+DATAW, SD_0);mydelay(); /* sda lo */
outportb(port+CLOCK, SC_1);mydelay(); /* scl hi */
outportb(port+DATAW, SD_1);mydelay(); /* sda hi */
outportb(port+DATAW, SD_0);mydelay(); /* sda lo */
outportb(port+CLOCK, SC_0);mydelay(); /* scl lo */
#else
outportb(port+DATAW, SD_1); /* sda hi */
outportb(port+CLOCK, SC_1);mydelay(); /* scl hi */
outportb(port+DATAW, SD_0);mydelay(); /* sda lo */
outportb(port+CLOCK, SC_0);mydelay(); /* scl lo */
#endif
/* read the requested data */
for (n=0; n<1+nbytes; n++) {
switch (n) {
case 0 : send_data = 0x1 | msg_data[0]; break;
default: send_data = 0xff; break;
}
/* transmit the data */
rcv_data = 0;
mask = 0x80;
for (i=0; i<8; i++) {
outportb(port+DATAW,(mask & send_data) ? SD_1 : SD_0);mydelay(); /* set sda bit */
outportb(port+CLOCK, SC_1 );mydelay(); /* set scl hi */
if (n > 0) { /* sample data */
if (inportb(port+DATAR) & SD_R) rcv_data |= mask;mydelay();
}
outportb(port+CLOCK, (SC_0));mydelay(); /* set SCL lo */
mask = (mask >> 1);
}
/* generate the acknowledge bit */
if ((n == 0) || (n == nbytes)) {outportb(port+DATAW, SD_1 );mydelay();} /* sda hiz */
else {outportb(port+DATAW,SD_0 );mydelay();} /* sda lo */
outportb(port+CLOCK, SC_1 );mydelay(); /* scl hi */
if ((n == 0) && (inportb(port+DATAR) & SD_R)) no_ack=1; /* verify ack */
if ((n == nbytes) && ((inportb(port+DATAR) & SD_R) == 0)) {
/* BCM4200 drove ack low here ... not a good thing ! */
qam_status.status |= RUNTIME_ERROR;
qam_status.errno = I2C_BAD_PROTO;
}
outportb(port+CLOCK, (SC_0));mydelay(); /* scl lo */
/* store the data read */
if (n > 0) msg_data[1+n] = rcv_data;
}
/* generate the stop bit */
outportb(port+DATAW, SD_0);mydelay();
outportb(port+CLOCK, SC_1);mydelay();
outportb(port+DATAW, SD_1);mydelay();
if (no_ack) { /* signal error condition */
qam_status.status |= RUNTIME_ERROR;
qam_status.errno = I2C_NOACK;
return QAM_ERROR;
}
return QAM_OK;
}
/*
Adds an artificial delay to slow down the parallel port I2C bus.
Needed only for the tuner which has problems going as fast as
some PC's we tested with.
*/
void mydelay(void)
{
long i;
for (i=0; i<100; i++) {
i = i;
}
}
/************************************************************
* i2c_write - this routine writes data to an I2C bus slave.
* The argument 'nbytes' defines the number of bytes to write.
* The minimum length message length is 2 bytes.
* RETURNS: QAM_OK if the message bytes were acknowledged properly,
* QAM_ERROR otherwise.
*************************************************************/
int i2c_write(int nbytes, int msg_data[])
{
int i,n,mask;
int data,no_ack=0;
/* generate the start bit */
outportb(port+DATAW, SD_1);mydelay(); /* set sda hi */
outportb(port+CLOCK, SC_1);mydelay(); /* set scl hi */
outportb(port+DATAW, SD_0);mydelay(); /* set sda lo */
outportb(port+CLOCK, SC_0);mydelay(); /* set scl lo */
for (n=0; n<nbytes; n++) {
data = msg_data[n];
/* transmit the data */
mask = 0x80;
for (i=0; i<8; i++) {
outportb(port+DATAW,(mask & data) ? SD_1 : SD_0);
mydelay(); /* set data bit */
outportb(port+CLOCK,SC_1);
mydelay(); /* set clock hi */
outportb(port+CLOCK,SC_0);
mydelay(); /* set clock lo */
mask = (mask >> 1);
}
/* generate the acknowledge bit */
outportb(port+DATAW, SD_1);mydelay();
outportb(port+CLOCK, SC_1 );mydelay(); /* set clock hi */
if (inportb(port+DATAR) & SD_R) no_ack=1;mydelay(); /* test ack */
outportb(port+CLOCK, (SC_0));mydelay(); /* set clock lo */
}
/* generate the stop bit */
outportb(port+DATAW, SD_0);mydelay(); /* set data lo */
outportb(port+CLOCK, SC_1);mydelay(); /* set clock hi */
outportb(port+DATAW, SD_1);mydelay(); /* set data hi */
if (no_ack) { /* signal error condition */
qam_status.status |= RUNTIME_ERROR;
qam_status.errno = I2C_NOACK;
return QAM_ERROR;
}
return QAM_OK;
}
/***********
* tuner_freq - this routine programs the tuner for the desired
* frequency. Note: Review this once tuner samples are available
************/
#define TNR_CLK 0x01
#define TNR_DAT 0x02
int tuner_freq(float freq)
{
uint m_cnt, ival;
float tuner_offset;
int band,rstat;
int i,j,n,mask;
int rfctl[256],tnr[8];
if(NTSC)
tuner_offset = 43.75; /* NTSC MHz */
else
tuner_offset = 36.125; /*PAL MHz */
// printf("babo");
// getch();
switch (qam_status.tuner_used) {
case SINGLE:
#if 1 //TCMU30311PTB
if (freq1 < 171.) tnr[4] = 0x01;//P0 = 1//until 48.25 and 168.25
else if (freq1 < 468.) tnr[4] = 0x02;//P1 = 1 between 175.25 and 463.25
else if (freq1 < 960.) tnr[4] = 0x08;//P3 = 1 between 471.25 and 855.25
else printf("Out of frequency range for tuner\n");
#endif
#if 0 //TCMU30311PSB
if (freq1 < 148.) tnr[4] = 0x01;//P0 = 1//until 48.25 and 147.25
else if (freq1 < 424.) tnr[4] = 0x02;//P1 = 1 between 154.25 and 423.25
else if (freq1 < 960.) tnr[4] = 0x08;//P3 = 1 between 431.25 and 855.25
#endif
break;
case DOUBLE:
default:
// tuner_offset = 36.125; /* MHz */
break;
}
qam_status.tnr_freq = freq;
freq += tuner_offset;
m_cnt = (16.0 * freq);
/* Compute tuner settings */
tnr[0] = (uchar) TNR_I2C_ADDR;
tnr[1] = (uchar) 0x007f & (m_cnt >> 8);
tnr[2] = (uchar) 0x00ff & m_cnt;
// tnr[3] = (uchar) 0xce;
tnr[3] = (uchar) 0xce;
gotoxy(5,20);
printf(" chnl : %3.0f freq is %3.2f osc %4.2f band %x",(freq-51.025-tuner_offset)/7.+1,freq - tuner_offset,freq,tnr[4]);
#if 0
printf("Tunerdata %2.x",tnr[0]);
printf("Tunerdata %2.x",tnr[1]);
printf("Tunerdata %2.x",tnr[2]);
printf("Tunerdata %2.x",tnr[3]);
printf("Tunerdata %2.x",tnr[4]);
//getch();
#endif
{
/* build a message to program the tuner */
n=0;
qam_write(SB_RW,SB_RFCTL,0x03,0x03); /* set scl, sda hi */
rfctl[n++] = TNR_CLK; /* start condition */
rfctl[n++] = 0; /* dat lo...clk lo */
for (i=0; i<5; i++) {
mask = 0x80;
for (j=0; j<8; j++) {
if (mask & tnr[i]) {
rfctl[n++] = TNR_DAT;
rfctl[n++] = TNR_DAT | TNR_CLK;
rfctl[n++] = TNR_DAT;
} else {
rfctl[n++] = 0;
rfctl[n++] = TNR_CLK;
rfctl[n++] = 0;
}
mask = mask >> 1;
}
rfctl[n++] = TNR_DAT; /* ack bit time */
rfctl[n++] = TNR_DAT | TNR_CLK; /* clk.dat hi */
rfctl[n++] = TNR_DAT; /* clk lo */
}
rfctl[n++] = 0;
rfctl[n++] = TNR_CLK;
rfctl[n++] = TNR_DAT | TNR_CLK;
/* send this data */
i2c_write(5, tnr);
for (i=0; i<n; i++) qam_write(SB_RW,SB_RFCTL,rfctl[i],0);
}
getch();
return rstat;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -