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

📄 s7026.cpp

📁 DOS下使用PCI扩展串口的程序希望对大家有用
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include    "incldef.h"
#include    "deftyp.h"
#include    "extfun.h"

#define   SIZE      4096
#define   SSIZE     28
#define   OK        0
#define   ComError  0x100
#define   BufFull   0x101
#define   UserBreak 0x102
#define   PORTSUM   4
enum   {rb_size=90};
enum   {SIZEb=4096};

char   bautrat[8];
char   strings[rb_size];
char   CRTBuffer[4096];
int    SaveScreen=1;
struct text_info CRTtextinfo;
void   SaveCRT();
void   RestoreCRT();

int       intvet;
unsigned  char portsend;
unsigned  int  gstep,gstepn;
unsigned  int  tcr30ccpb;
unsigned  int  fcr54titl;
unsigned  int  fcr76rtl;
unsigned  int  lcr10dl;
unsigned  int  lcr2nos;
unsigned  int  lcr53pt;
unsigned  int  loopbackb;
unsigned  int  titl950;
unsigned  int  titl650;
unsigned  int  rtl950;
unsigned  int  rtl650;
unsigned  int  BaseAdr;
unsigned  char modevar;
unsigned  int  tralevel;
unsigned  int  reclevel;
unsigned  char transf,receivf;
unsigned  char display,re_rec;
unsigned  int   recport;
unsigned  int   traport;
unsigned  int   Port1,Port2;
unsigned  int   ErrorCode;
unsigned  int   ErrDetected;
unsigned  char  BBuffer[PORTSUM][SIZEb];
unsigned  char  txbuf1[rb_size];
unsigned  char  txbuf2[rb_size];
int    head1,head2,tail1,tail2;


void  confLCRegs(unsigned int baseadd);  /*BAR2 0xd4000,0xdc000*/
int   UartsRegsset(unsigned int baseadd,unsigned int portoffset,char *bautrate);
void  DLMandDLLwrite(unsigned int  baseadd,int portoffset, int dlm, int dll);
void  IndecontrolReg(unsigned int baseadd,unsigned int  portoffset,unsigned int SPRoffset,unsigned int controlvalue); /**/
unsigned int ReadIndeConReg(unsigned int baseadd,unsigned int  portoffset,unsigned int SPRoffset); /**/
extern DWORD inpd(int portnum) ;
static DWORD inpd(int portnum);
static void outpd(int portnum, DWORD val);
static int read_DWORD_register(int bus, int device, int func, int reg,
							   WORD *lo, WORD *hi);
extern PCIcfg *read_PCI_config(int bus, int device, int func);
int  Intertxrx();
void  showmsg(unsigned char Detected, unsigned int errorcode);
void  interrupt (* oldvect) (...);
void  interrupt comtxrx(...);
void  Inter_txrx(int intnum);
void  Close_txrx(int intnum);
void  querytest(unsigned int gstep, unsigned int gstepn);
void  sendarrary(unsigned int baseadd,unsigned int portoffset,char *buffer, int len);
void  sendchar(unsigned int baseadd,unsigned int portoffset,char chard);
void  getcha(unsigned int baseadd,unsigned int portoffset);
void  helpini();
void  more(char *str);

/************************************************************************/
/*      The local configuration registers                              */
/************************************************************************/
void  confLCRegs(unsigned int baseadd)  /*BAR2 0xd400,0xdc00*/
{
	//local configuration and Control register
	outportb(baseadd+0,0x04);
	/*ourportb(BAR2+1,0x00);
	ourportb(BAR2+2,0x00);*///lcc[23:8] read only
	outportb(baseadd+3,0x18);
	//Multi-purpose i/o congiguration register  reset value 00000000
	outportb(baseadd+4,0x00);
	outportb(baseadd+5,0x00);
	outportb(baseadd+6,0x00);
	outportb(baseadd+7,0x00);
	//local Bus Timeing parameter register1 reset value 20302030
	outportb(baseadd+8,0x30);
	outportb(baseadd+9,0x20);
	outportb(baseadd+10,0x30);
	outportb(baseadd+11,0x20);
	//local Bus Timeing parameter register2  reset value 00c004f0
	outportb(baseadd+12,0xf0);
	outportb(baseadd+13,0x04);
	outportb(baseadd+14,0xc0);
	outportb(baseadd+15,0x00);
	//UART Receiver FIFO levels  read-only

	//UART Transmitter FIFO levels read-only

	//UART Interrupt Source Register  Read-only

	//Global Interrupt Status  and control register   reset value ffff0000h
	/*GIS[15:0] read-only*/
	outportb(baseadd+30,0xff);
	outportb(baseadd+31,0xff);
}

void  DLMandDLLwrite(unsigned int  baseadd,int portoffset, int dlm, int dll)
{
	outportb(baseadd+portoffset+LCR,0x80);
	  /*set LCR[7] for access DLM and DLL register*/
	outportb(baseadd+portoffset+0x01,dlm);
	outportb(baseadd+portoffset+0x00,dll);
}
/***********************Index control register***************************/
void  IndecontrolReg(unsigned int baseadd,unsigned int  portoffset,unsigned int SPRoffset,unsigned int controlvalue) /**/
{
	outportb(baseadd+portoffset+LCR,0x03);/*LCR[7]=0*/
	outportb(baseadd+portoffset+0x07,SPRoffset);/* is CPR SPR offset*/
	outportb(baseadd+portoffset+0x05,controlvalue);/*0x05 is ICR oofset*/
}
unsigned int ReadIndeConReg(unsigned int baseadd,unsigned int  portoffset,unsigned int SPRoffset) /**/
{
	unsigned int value;
	outportb(baseadd+portoffset+LCR,0x03);/*LCR[7]=0*/
	outportb(baseadd+portoffset+0x07,ACR);/* is CPR SPR offset*/
	outportb(baseadd+portoffset+0x05,0x40);/*0x05 is ICR oofset*/
	outportb(baseadd+portoffset+0x07,SPRoffset);/* is CPR SPR offset*/
	value=inportb(baseadd+portoffset+0x05);
	outportb(baseadd+portoffset+0x07,ACR);/* is CPR SPR offset*/
	outportb(baseadd+portoffset+0x05,0x00);/*0x05 is ICR oofset*/
	return value;
}

int  UartsRegsset(unsigned int baseadd,unsigned int portoffset,char *bautrate)
{
	//Interrupt Enable Register----requred //LCR[7]=0,ACR[7]=0
	outportb(baseadd+portoffset+LCR,0x03);//LCR[7]=0
	outportb(baseadd+portoffset+0x07,0x00);//to write ACR
	outportb(baseadd+portoffset+0x05,0x00); //ACR[7]=0
	outportb(baseadd+portoffset+IER,0x00);

	//FIFO control Register ----requred LCR!=0xBF
	if (modevar == 1)
		outportb(baseadd+portoffset+FCR,0x0e);// tempval.bit.bit0=0;
	else if((modevar == 2)||(modevar == 5))
	{
		outportb(baseadd+portoffset+LCR,0xbf);
		outportb(baseadd+portoffset+FCR,0x2f|fcr76rtl);
		outportb(baseadd+portoffset+LCR,0x03);
		//setLCR[7] for FCR[5] is writable in 750 mode
	}
	else outportb(baseadd+portoffset+FCR,0x0f|fcr54titl|fcr76rtl);

	//Modem control  Register --requred LCR!=0xbf,to read ACR[7]=0
	outportb(baseadd+portoffset+MCR,0x0b|loopbackb);


	//UART baud rate set
	if (strchr("/B", *(bautrate) ))
	{
		switch (strlen(bautrate))
		{
			 case 3:
				  if (!strcmp("B50",bautrate))
					 ;
				  else printf("baut rate value needed adjust\n");
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[0].DLM,StandBRDiv[0].DLL);
				  break;
			 case 4:
				  if (!strcmp("B110",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[1].DLM,StandBRDiv[1].DLL);
				  else if(!strcmp("B300",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[2].DLM,StandBRDiv[2].DLL);
				  else if(!strcmp("B600",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[3].DLM,StandBRDiv[3].DLL);
				  else
				  {
					 printf("baut rate value needed adjust\n");
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[1].DLM,StandBRDiv[1].DLL);
				   }
				   break;
			  case 5:
				   if(!strcmp("B1200",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[4].DLM,StandBRDiv[4].DLL);
				   else if(!strcmp("B2400",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[5].DLM,StandBRDiv[5].DLL);
				   else if(!strcmp("B4800",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[6].DLM,StandBRDiv[6].DLL);
				   else if(!strcmp("B9600",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[7].DLM,StandBRDiv[7].DLL);
				   else
				   {
					   printf("baut rate value needed adjust\n");
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[4].DLM,StandBRDiv[4].DLL);
				    }
					break;
			   case 6:
					if (!strcmp("B19200",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[8].DLM,StandBRDiv[8].DLL);
					else if(!strcmp("B28800",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[9].DLM,StandBRDiv[9].DLL);
					else if(!strcmp("B38400",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[10].DLM,StandBRDiv[10].DLL);
					else if(!strcmp("B57600",bautrate))
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[11].DLM,StandBRDiv[11].DLL);
					else
					{
						printf("baut rate value needed adjust\n");
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[8].DLM,StandBRDiv[8].DLL);
					 }
					 break;
				case 7:
					if (!strcmp("B115200",bautrate))
					   ;
					else printf("baut rate value needed adjust\n");
		DLMandDLLwrite(baseadd,portoffset,StandBRDiv[12].DLM,StandBRDiv[12].DLL);
					break;
			 default:
					break;

			}
	}
	else printf("please set baut rate if needed\n");


	if ((modevar==4)||(modevar==6)) //650 950 enhance mode
	  //Enhanced Feature  Register address 010 --requred LCR==0xbf
	  // and so other enhanced mode register
	{
		outportb(baseadd+portoffset+LCR,0xbf);//LCR==0xbf
		outportb(baseadd+portoffset+EFR,0x10);//receive XON1 XOFF1 Trans X..2
		outportb(baseadd+portoffset+LCR,0x03);
	}
	IndecontrolReg(baseadd,portoffset,TCR,tcr30ccpb);


	 if (modevar==6)   /*950 configuration*/
	 {
		 // clock prescale register
		 //outportb(baseadd+portoffset+EFR, 0x10);
		 IndecontrolReg(baseadd,portoffset,ACR,0x30);  //only bits 0, 1 can readable
		 IndecontrolReg(baseadd,portoffset,CPR,0x08);  //EFR[4]=1,MCR[7] as enable-bit
		 IndecontrolReg(baseadd,portoffset,TTL,titl950);
		 IndecontrolReg(baseadd,portoffset,RTL,rtl950);
		 IndecontrolReg(baseadd,portoffset,FCL,0x10);
		 IndecontrolReg(baseadd,portoffset,FCH,0xa2);
		 IndecontrolReg(baseadd,portoffset,CKS,0x00);        //CKS 0x03
		 IndecontrolReg(baseadd,portoffset,NMR,0x00); //NMR 0x0d SPR offset
		 IndecontrolReg(baseadd,portoffset,MDM,0x00); //MDM 0x0d SPR offset
	 }

	//line control Register ---to read ACR[7]=0
	 //8-bits 2-stop ....
	outportb(baseadd+portoffset+LCR, lcr10dl|lcr2nos|lcr53pt);

   return 0;

}

struct t_BQue
{
   int       size;
   int       count;
   int       head;
   int       tail;
   unsigned char * buf;
   unsigned long       constructed;
};

typedef struct t_BQue BQue;

void            BQueInit ( BQue* que, int size, unsigned char* buf );
void            BQueDestroy( BQue* que );
void            BQueClear( BQue* que );
int             BQuePut( BQue* que, unsigned char element );
unsigned char   BQueGet( BQue* que );

/*********************************************************/
/* These macros can be used on all of the CQ types*/
#define QueSize(q)        ((int)((q)->size))
#define QueRoom(q)        ((q)->size - (q)->count)
#define isQueEmpty(q)    ((q)->count == 0 )
#define isQueFull(q)     ((q)->count >= (q)->size)
#define isNotQueFull(q) ((q)->count < (q)->size)
#define HasQueData(q)    ((q)->count > 0 )
#define QueDataNumber(q)     ( (q)->count )
#define isQueVaid(q)    ( isQueBuild(q) && (q)->buf != NULL)
#define ADVANCE(p)              ((p+1)%que->size)

void    BQueInit ( BQue* que, int tsize, unsigned char* buf )
{
   int i;
   que->size			=tsize;
   que->count          =     0;
   que->head           =     0;
   que->tail           =     0;
   que->buf            =   buf;
}


void    BQueDestroy( BQue* que )
{
   int i;
   for(i=0;i<sizeof( BQue );i++)
		*((char *)(que+i))=0;
}


void    BQueClear( BQue* que )
{

   que->count = 0;
   que->head  = 0;
   que->tail  = 0;
}

int  BQuePut( BQue* que, unsigned char element )
{
   if ( que->count >= que->size )
	return 0;
   que->buf[ que->head ] = element;
   que->head = ADVANCE( que->head );
   que->count++;
   return 1;
}

unsigned char  BQueGet( BQue* que )
{
   unsigned char element;
   element = que->buf[ que->tail ];
   que->tail = ADVANCE( que->tail );
   disable();
   que->count--;
   enable();
   return element;
}

disinter[8]={0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
vectadr[17]={0x00, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
			 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78};
/***  Disable interrupt  ***/
void   Close_txrx(int intnum)
{
	 disable();
	 setvect(vectadr[intnum],oldvect);
	 if (intnum  < 8)
		outportb(mainMIR,inportb(mainMIR) | disinter[intnum]);
	 else
	 {
		 outportb(mainMIR,inportb(mainMIR) | 0x04);
		 outportb(seconMIR,inportb(seconMIR) | disinter[intnum-8]);
	 }
	 enable();
}

/**************************************Get string com******************************/
void  sendarrary(unsigned int baseadd,unsigned int portoffset,char *buffer, int len)
{
	int charn;

	outportb(baseadd+portoffset+LCR,0x3f);/*LCR[7]=0 for write THR*/
	for (charn=0;charn<=len;charn++)
		outportb(baseadd+portoffset+THR,*(buffer+charn));
	printf("%s",buffer);

}

void  sendchar(unsigned int baseadd,unsigned int portoffset,char chard)
{
	sendarrary(baseadd,portoffset,&chard,1);

}

void  getcha(unsigned int baseadd,unsigned int portoffset)
{
	char ch;

	outportb(baseadd+portoffset+LCR,0x3f);/*LCR[7]=0*/
	ch=inportb(baseadd+portoffset+0x00);
	printf("%c",ch);

}


/***Save the screen before run this program ***/
void  SaveCRT()
{
	 gettextinfo(&CRTtextinfo);
	 if (!gettext(1,1,80,25,CRTBuffer))
	 {
	    SaveScreen=0;
	    printf("Fail to copy screen\n");
	 }
}

/***restore the screen after closing this program ***/
void   RestoreCRT()
{
	if (SaveScreen)
	{
	   puttext(1,1,80,25,CRTBuffer);
	}
	window( CRTtextinfo.winleft,CRTtextinfo.wintop,
		CRTtextinfo.winright,CRTtextinfo.winbottom);
	textattr(CRTtextinfo.attribute);
	gotoxy(CRTtextinfo.curx,CRTtextinfo.cury);
}

void  more(char *str)
{
	int  n;
	char  *p, *pp, c;

	p= str;

	while (p)
	{
		pp= p;
		for (n= 0; n< 20 && p; n++)
		{
			 p= strchr(p, '\n');
			 if (p)
			 {
				 if (p[1]) p++;
				 else p= NULL;
			 }
		}
		if (p)
		{
		   c= *p;
		   *p= 0;
		   printf("%s", pp);
		   *p= c;
		   fprintf(stderr, ">>> More?");
		   switch ( getch() )
		   {
				 case 'n': case 'N': case 'q': case 'Q': case 0x1b:
				 exit(0);
				 break;
		   }

		   fprintf(stderr, "\r%9s\r", "");
		}
		else
		{
			printf("%s", pp);
		}
	  }
}

void  helpini()
{
	char *help_string=
	"\n"
	"This kit could be used  in three manners depending the connecting between port:\n"
	"   1. eight ports. connect port1/8,2/7,3/6,4/5 for sem7513\n"
	"   2. two  ports. connect specified two ports.\n"
	"   3. communite to other device port.connect specified port and other port\n"
	"\n"
	"Useage:sem7513 [W] [Ux-y] [Bb] [Mm] [Ss] [Dd] [Pp] [Nn] [Tt] [Rr]\n"
	"       x={1,...,8},y={1,...,8},b={19200,38400,...},m={4,5,6,7,9},s={0,...,15}\n"
	"       p={n,o,e,1,0},d={5,6,7,8},n={0,1,2},t={1,...,127},r={1,...,127}\n"
	"       such as :sem7513\n"
	"                sem7513 U1-8 B19200 D8\n"
	"                sem7513 W B19200 U4\n"
	"       W:data transmitting between a sem7513 port and other device serial port\n"
	"       Ux:specify one port, Ux-y:specify two  ports\n"
	"       Bb:designate baut rate\n"
	"       Dd,Pp,Nn:specify data length,parity manner,stop bits number respectively\n"
	"       Tt,Rt:specify the Transmitte interrupt tragger level\n"
	"			  recieve interrupt level for 950 mode\n"
	"\n"
	"The hardware physical connection referre to SysExtendModule 7513 manual\n"
	;

	more(help_string);

}


#if defined(__WATCOMC__) && defined(__386__)
extern DWORD inpd(int portnum) ;
#pragma aux inpd = \
   "in eax,dx" \
   parm [edx] \
   value [eax] \
   modify exact [eax] ;

#else
static DWORD inpd(int portnum)
{
   static DWORD value ;
   asm mov dx,portnum ;
   asm lea bx,value ;
#if defined(__BORLANDC__)
   __emit__(0x66,0x50,                  // push EAX
			0x66,0xED,                  // in EAX,DX
			0x66,0x89,0x07,             // mov [BX],EAX
			0x66,0x58) ;                // pop EAX

⌨️ 快捷键说明

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