📄 user_if.c
字号:
dirstat = _dos_findnext(&source_files);
}
if (n==0) return (char *) 0;
/* determine spacing */
ncols = 1 + (n / 20);
nrows = (n > 20) ? 20 : n;
/* display the list */
clrscr();
NORMAL_VIDEO;
gotoxy(8,2); cprintf("%s",prompt);
for (i=sel=0; i<ncols; i++) {
for (j=0; j<nrows && sel < n; j++) {
x = 4 + 12 * i;
y = 4 + j;
gotoxy(x,y);
if (sel == 0) {
REVERSE_VIDEO;
cprintf("%-10s\n",files[sel++]);
NORMAL_VIDEO;
lastx = x;
lasty = y;
}
else {
cprintf("%-10s\n",files[sel++]);
}
}
}
/* get user input */
cur_row = cur_col = sel = 0;
while ((c=getch()) != 0xd && c != 0x1b) {
if (c == 0) c = getch();
switch (c) {
case 0x48 : if (cur_row > 0 ) cur_row--; break;
case 0x50 : if (cur_row < nrows-1) cur_row++; break;
case 0x4b : if (cur_col > 0 ) cur_col--; break;
case 0x4d : if (cur_col < ncols-1) cur_col++; break;
}
/* reprint previous selection in normal video */
gotoxy(lastx,lasty);
cprintf("%-10s\n",(sel < n) ? files[sel] : " ");
/* print the new selection in reverse video */
sel = nrows * cur_col + cur_row;
REVERSE_VIDEO;
lastx = x = 4 + 12 * (sel / nrows);
lasty = y = 4 + (sel % nrows);
gotoxy(x,y);
cprintf("%-10s\n",(sel < n) ? files[sel] : " ");
NORMAL_VIDEO;
}
/* return the selected file */
if (c == 0xd && sel < n) {
strcpy(name,files[sel]);
return name;
}
else
return (char *) 0;
}
/****************************************************************
* parse - parse 'bufp' breaking it into tokens. The first token
* is the function selector. The rest of the tokens are function
* arguments. Place arguments into 'arg', set 'nargs' and
* return the selected function. If the comment identifier '#' is seen,
* the line is ignored.
****************************************************************/
enum ShellCmdType parse(char *bufp, int *nargs, char **arg)
{
int i,n;
char *cp;
/* skip blanks */
while (*bufp != '\0' && (*bufp == ' ' || *bufp == '\t' ||
*bufp == ',' || *bufp == '(' || *bufp==')' || *bufp==';')) bufp++;
if (*bufp == '\0' || *bufp == '#' || *bufp == '\n') return SHELL_NOOP;
/* break into individual strings */
for (n=0; *bufp != '\0' && *bufp != '\n' && *bufp != '#'; arg[n++]=cp) {
cp = bufp;
if (*bufp == '\'') {
*bufp++ = ' ';
cp++;
while (*bufp != '\'' && *bufp != '\0') bufp++;
if (*bufp == '\'') *bufp = ' ';
}
else {
while (*bufp != ' ' && *bufp != ',' && *bufp != '\0' &&
*bufp != '(' && *bufp != ')' && *bufp != '\n') bufp++;
}
if (*bufp != '\0') *bufp++ = '\0';
/* skip blanks */
while (*bufp != '\0' && (*bufp == ' ' || *bufp == '\t' ||
*bufp == ',' || *bufp == '(' || *bufp==')' || *bufp==';')) bufp++;
}
*nargs = n;
/* lookup function */
for (i=0; ShellKeyword[i].keyword > (char *)0; i++) {
if (strcmp(ShellKeyword[i].keyword,arg[0]) == 0)
return ShellKeyword[i].keyval;
}
return SHELL_UNKNOWN;
}
/********************************************************************
* eval_acq_script - this routine is used to evaluate the performance
* of the specified acquisition script. All scripts are executed from the
* SCRIPT directory. The program then loops for the specified
* number of passes. Each pass, the script is executed, and after the specified
* wait time, the qam_status is read to determine if the channel has locked.
* Two conditions must be met for the channel to be in lock.
* 1. The RMS Equalizer Error < LOCK_THRESHOLD (programmed in the script)
* 2. The Main Equalizer Tap > 1/2 Full Scale (for QAM channel only)
*********************************************************************/
int eval_acq_script(char *fname, int npasses, int wait_time)
{
int i,x,y,c,i_val,q_val;
int npass,nfail,tavg,rstat;
struct dostime_t time;
unsigned long t1,t2,delta,tsum;
FILE *fp;
char foo[80];
if (npasses == 0) return 0;
/* clear the menu display */
clrscr();
x = 10;
y = 10;
gotoxy(x,y++);
cprintf("--- Acquisition Script Evaluation ---");
gotoxy(x,y++);
cprintf("Script File : %s",fname);
gotoxy(x,y++);
cprintf("Attempt : ");
gotoxy(x,y++);
cprintf("# Passed : ");
gotoxy(x,y++);
cprintf("# Failed : ");
gotoxy(x,y++);
cprintf("Mean Acq Time: ");
/* loop through npasses */
for (i=npass=nfail=tsum=0; i<npasses; i++) {
/* get start time */
_dos_gettime(&time);
t1 = (unsigned long) 360000uL*time.hour + 6000uL*time.minute + 100uL*time.second + time.hsecond;
/* reacquire signal */
rstat = qam_init(fname);
if (rstat == QAM_ERROR) {
clrscr();
gotoxy(10,10);
cprintf("Error in execution of '%s' ... hit rtn", fname);
fflush(stdin);
gets(foo);
return QAM_ERROR;
}
/* delay wait_time */
delay(wait_time);
/* get stop time */
_dos_gettime(&time);
t2 = (unsigned long) 360000uL*time.hour + 6000uL*time.minute + 100uL*time.second + time.hsecond;
delta = 10uL * (t2 - t1); /* compute elapsed time in ms */
/* determine if in lock */
qam_read_status();
if (QAM_IN_LOCK && FEC_IN_LOCK) {
npass++;
tsum += delta;
} else {
/* If fail the first time try a second time
*
//ADDING ACQUSITION //PAPI 99.09.28
* if (QAM_IN_LOCK && FEC_IN_LOCK) {
* npass++;
* tsum += delta;
* } else {
* nfail++;
* gotoxy(10,3); cprintf("esc to abort . . .");
* c = getch();
* if (c == 0x1b) break;
* } */
nfail++;
}
tavg = (int) ((long) ((npass == 0) ? 0 : tsum / (long) npass));
/* display results */
x = 25;
y = 12;
gotoxy(x,y++); cprintf("%3d of %3d",1+i,npasses);
gotoxy(x,y++); cprintf("%3d",npass);
gotoxy(x,y++); cprintf("%3d",nfail);
gotoxy(x,y++); cprintf("%3d mSec",tavg);
/* if esc key pressed abort test */
if (kbhit()) {
c = getch();
if (c == 0x1b) break;
if (c == 0) getch();
}
/* Toggle reset control bit port D0
* outportb(glb_port_data, TOGGLE_RST);
* delay(50);
* outportb(glb_port_data, 0);*/
}
/* wait for user input */
t1 = 100uL * (unsigned long) npass / (unsigned long) npasses;
x = 10;
y = 17;
gotoxy(x,y++); cprintf("--- Test Complete ---");
gotoxy(x,y++); cprintf("%3d%% Success Rate",(int) t1);
gotoxy(x,y++); cprintf("Mean Acq Time = %d mSec",tavg);
fflush(stdin);
gets(foo);
return QAM_OK;
}
/********************************************************************
* show_menu - this routine prints the menu string prompt info
* provided and waits for a user selection. The function keys (F1-F10)
* are used to select menu options. The 'menu' list must be null
* terminated. The screen must be cleared before this routine is called.
* In the background, the status information is printed to the screen.
* If <ctrl> Z is pressed, a value of 0x1b is returned.
*********************************************************************/
int show_menu(char *menu[]) {
int i, y, pass = 0;
/* display menu */
y = STATUS_YPOS;
REVERSE_VIDEO;
gotoxy(15,y-4); cprintf("--- %s (Ver. %s) ---",SW_TITLE,VERSION);
gotoxy(10,y-2); cprintf("--- Menu Info ---");
NORMAL_VIDEO;
for (i=0; menu[i] != (char *) 0; i++) {
gotoxy(10,y+i);
cprintf("F%-2d : %s",1+i,menu[i]);
}
/* wait for function key to be pressed */
while (1) {
if (kbhit()) {
i = getch();
switch (i) {
case 0x00: return getch();
case 0x1a: return 0x1a;
default : break; /* ignore character */
}
}
else {
if (pass++ > 1000) {
show_status(0);
pass = 0;
}
}
}
}
void domisol()
{
sound(10000); //1kHz
delay(100);
sound(80000);
delay(200);
sound(16000);
delay(1000);
nosound();
//getch();
}
/********************************************************************
* show_status - this routine prints the QAMLink status information
* to the right half of the menu screen. The status is read and
* displayed about every 100 mSeconds once a menu is displayed.
* If the refresh=1, the entire screen will be repainted.
* Otherwise, only the new data values are printed.
*adding tuner_read(int tuner_status)
*********************************************************************/
void show_status(int refresh)
{
int x=STATUS_XPOS,y=STATUS_YPOS-1;
int sp5659_lock ;
int ival ,qval;
qam_read_status();
if (refresh) {
gotoxy(x,y-1);
REVERSE_VIDEO;
cprintf("--- QAM Channel Status ---");
NORMAL_VIDEO;
gotoxy(x,y++); cprintf("Bus Type :");
gotoxy(x,y++); cprintf("Tuner Type:");
gotoxy(x,y++); cprintf("Ref Freq :");
gotoxy(x,y++); cprintf("Rx SymRate:");
gotoxy(x,y++); cprintf("LO Freq :");
gotoxy(x,y++); cprintf("QAM Mode :");
gotoxy(x,y++); cprintf("Acq Mode :");
gotoxy(x,y++); cprintf("Acq Script:");
gotoxy(x,y++); cprintf("QAM is :");
gotoxy(x,y++); cprintf("FEC is :");
gotoxy(x,y++); cprintf("SNR Est. :");
gotoxy(x,y++); cprintf("LockThresh:");
gotoxy(x,y++); cprintf("Tuner Freq:");
gotoxy(x,y++); cprintf("Error Stat:");
gotoxy(x,y++); cprintf("BCM3118 REV:");
}
/* display data */
x = STATUS_XPOS + 12;
y = STATUS_YPOS - 1;
gotoxy(x,y++);
if (qam_status.status & SPI_SELECT) cprintf("SPI_BUS");
else cprintf("I2C_BUS");
gotoxy(x,y++);
switch (qam_status.tuner_used) {
case SINGLE:
cprintf("SAMSUNG:(Single)");
break;
case DOUBLE:
cprintf("SAMSUNG:(Double)");
break;
case TEMIC:
cprintf("TEMIC");
break;
default:
cprintf("SAMSUNG");
break;
}
gotoxy(x,y++); cprintf("%6.3f MHz",qam_status.ref_freq);
gotoxy(x,y++); cprintf("%5.3f MHz",qam_status.symbol_rate);
gotoxy(x,y++); cprintf("%6.3f MHz",qam_status.lo_freq);
gotoxy(x,y++);
switch (QAM_MODE) {
case QAM_4 : cprintf("QAM-4 "); break;
case QAM_16 : cprintf("QAM-16 "); break;
case QAM_32 : cprintf("QAM-32 "); break;
case QAM_64 : cprintf("QAM-64 "); break;
case QAM_128: cprintf("QAM-128"); break;
case QAM_256: cprintf("QAM-256"); break;
default : cprintf("ERROR!!");
}
gotoxy(x,y++); cprintf("%s",(qam_status.status & ACQUISITION_MODE) ? "Auto " : "Manual ");
gotoxy(x,y++); cprintf("%s",qam_status.acq_script);
gotoxy(x,y++); cprintf("%s",(QAM_IN_LOCK) ? "In Lock " : "Out of Lock");
gotoxy(x,y++); cprintf("%s",(FEC_IN_LOCK) ? "In Lock " : "Out of Lock");
gotoxy(x,y++); cprintf("%4.2f dB",qam_status.snr_estimate);
#if 0
if(qam_status.snr_estimate <26.0)
{
domisol();
}
#endif
gotoxy(x,y++); cprintf("%4.2f dB",qam_status.lock_thresh);
gotoxy(x,y++); cprintf("%8.4f MHz",qam_status.tnr_freq);
// gotoxy(10,10);
// printf(" AGC : %d ",T_AGC);
qam_read(MB_R,MB_LDAI,&ival,&qval);
gotoxy(10,12);
printf("LDAI : %d T_AGC: %d ",ival,T_AGC);
// gotoxy(10,13);
// printf("Level : %d ",Level);
gotoxy(10,14);
printf("HOT KEY: 'F'->Freq, 'S'->SR ");
gotoxy(10,15);
printf(" 'C'->Monitor, 'R'->Read Reg.");
gotoxy(10,16);
printf(" 'Q'-> Quit, X'->change Cons. #");
if (qam_status.errno < MAX_ERRNO) {
gotoxy(x,y++); cprintf("%s",errno_status[qam_status.errno]);
} else {
gotoxy(x,y++); cprintf("????");
}
}
/********************************************************************
* compute_pll_div - this routine will compute the best pll divider
* values to achieve the desired local oscillator freq (fval in MHz)
*********************************************************************/
int compute_pll_div(float fval, int *pll1_div, int *pll2_div)
{
int i,j,mini,minj;
float freq,err,min_err;
min_err = 1.0e6;
for (i=0; i<32; i++) {
for (j=0; j<32; j++) {
freq = 2.0 * qam_status.ref_freq * (1+j) / (1+i);
err = fabs(fval - freq);
if (err < min_err) {
mini = i;
minj = j;
min_err = err;
}
}
}
*pll1_div = mini;
*pll2_div = minj;
return QAM_OK;
}
/********************************************************************
* dump_bcm3118 - this routine reads and displays all of the BCM3118
* registers. This routine will refresh the display about every 1 second.
*********************************************************************/
#define N_DUMP 10 /* number of data sets to store */
#define DUMP_RAW 0 /* raw data dump of all registers */
#define DUMP_CONFIG 1 /* mode info in readible format */
#define DUMP_LOOPS 2 /* show loop status in real time */
void dump_bcm3118(void)
{
struct dosdate_t today;
struct dostime_t time;
static int dump_to_file = 0,mode=DUMP_RAW;
uchar sb_data[256],mb_data[256][4];
char buf[32],*cp,*cp2;
int i,j,n,x,y,ival,qval,*ip,*ip2;
float snr,ber,volts;
/* paint the screen template */
dump_refresh: /* goto's not pretty but ok for now */
clrscr();
if (mode == DUMP_RAW) {
REVERSE_VIDEO;
gotoxy(15,1); cprintf("--------- Single Byte Registers (Raw Format) ---------");
NORMAL_VIDEO;
for (i=n=0; qam_keyword[i].keyword != (char *) 0; i++) {
if (((qam_keyword[i].r_w & 0x04) == 0) && (qam_keyword[i].r_w & 0x01)) {
x = 5 + 12 * (n / 11);
y = 2 + (n % 11);
for (cp=buf,cp2=qam_keyword[i].keyword; *cp2 != '\0'; ) *cp++ = toupper(*cp2++);
*cp = '\0';
gotoxy(x,y); cprintf("%-7s=",buf);
n++;
}
}
REVERSE_VIDEO;
gotoxy(15,13); cprintf("--------- Multi Byte Registers (Raw Format) ---------");
NORMAL_VIDEO;
for (i=n=0; qam_keyword[i].keyword != (char *) 0; i++) {
if ((qam_keyword[i].r_w & 0x04) && (qam_keyword[i].r_w & 0x01)) {
x = 4 + 19 * (n / 10);
y = 14 + (n % 10);
for (cp=buf,cp2=qam_keyword[i].keyword; *cp2 != '\0'; ) *cp++ = toupper(*cp2++);
*cp = '\0';
gotoxy(x,y); cprintf("%-6s=",buf);
n++;
}
}
}
else if (mode == DUMP_CONFIG) {
REVERSE_VIDEO;
gotoxy(15,2); cprintf("--------- Current BCM3118 Chip Configuration ---------");
NORMAL_VIDEO;
/* add code later */
} else if (mode == DUMP_LOOPS) {
REVERSE_VIDEO;
gotoxy(15,2); cprintf("--------- BCM3118 Control Loops Monitor ---------");
NORMAL_VIDEO;
/* add code later */
}
gotoxy(5,24); cprintf("Hit TAB to change display format, <ctrl>F1-F10 to file data, RTN to exit");
/* refresh the screen until a key is pressed */
while (1) {
/* read all BCM3118 registers */
for (i=0; qam_keyword[i].keyword != (char *) 0; i++) {
if (qam_keyword[i].r_w & 0x01) { /* read register */
qam_read(qam_keyword[i].r_w,qam_keyword[i].keyval,&ival,&qval);
if ((qam_keyword[i].r_w & 0x04) == 0) { /* single byte */
sb_data[0xff & qam_keyword[i].keyval] = (uchar) ival;
}
else { /* multi byte */
ip = (int *) &mb_data[0xff & qam_keyword[i].keyval][0];
*ip = ival;
ip = (int *) &mb_data[0xff & qam_keyword[i].keyval][2];
*ip = qval;
}
}
}
/* display the data */
if (mode == DUMP_RAW) {
/* single byte registers */
for (i=n=0; qam_keyword[i].keyword != (char *) 0; i++) {
if (((qam_keyword[i].r_w & 0x04) == 0) && (qam_keyword[i].r_w & 0x01)) {
x = 13 + 12 * (n / 11);
y = 2 + (n % 11);
gotoxy(x,y); cprintf("%02x",sb_data[0xff & qam_keyword[i].keyval]);
n++;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -