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

📄 commdrv.c

📁 MMURTL(tm) Computer Operating System Ver x0.8, source code.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  RS232 Device Driver (2 channel v0.6) 	*/
/*  Copyright 1991, 1992, R.A. Burgess	*/
/*  Copyright 1993, The D-Group & R.A. Burgess */


#define U32 unsigned long
#define S32 long
#define U16 unsigned int
#define S16 int
#define U8 unsigned char
#define S8 char
#define TRUE   1
#define FALSE  0

#include "commdrv.h"

/* MMURTL OS Prototypes */

extern far U32 AllocExch(U32 *pExchRet);

extern far U32 InitDevDr(U32 dDevNum,
				    	  S8  *pDCBs,
					  	  U32 nDevices,
					  	  U32 dfReplace);

extern far U32 AllocOSPage(U32 nPages, U8 **ppMemRet);
extern far U32 DeAllocPage(U8 *pOrigMem, U32 nPages);

extern far U32 UnMaskIRQ(U32 IRQNum);
extern far U32 MaskIRQ(U32 IRQNum);
extern far U32 SetIRQVector(U32 IRQNum, S8  *pIRQ);
extern far U32 EndOfIRQ(U32 IRQNum);
extern far U32 SendMsg(U32 Exch, U32 msg1, U32 msg2);
extern far U32 ISendMsg(U32 Exch, U32 msg1, U32 msg2);
extern far U32 WaitMsg(U32 Exch, S8  *pMsgRet);
extern far U32 CheckMsg(U32 Exch, S8  *pMsgRet);
extern far U32 GetTimerTick(U32 *pTickRet);
extern far U32 Alarm(U32 Exch, U32 count);
extern far U32 KillAlarm(U32 Exch);
extern far U32 Sleep(U32 count);
extern far void MicroDelay(U32 us15count);
extern far void OutByte(U8 Byte, U16 wPort);
extern far U8 InByte(U16 wPort);
extern far void CopyData(U8 *pSource, U8 *pDestination, U32 dBytes);

extern far long GetJobNum(long *pJobNumRet);

/* local prototypes */

U32 comdev_stat(U32  dDevice,
			  S8  *pStatRet,
			  U32 dStatusMax,
			  U32 *pdStatusRet);

S32 comdev_init(U32  dDevice,
			 S8  *pInitData,
			 U32  sdInitData);

U32 comdev_op(U32 dDevice,
 		    U32 dOpNum,
		    U32 dLBA,
		    U32 dnBlocks,
		    U8  *pData);


#define CmdReadRec   1				/* Read one or more bytes */
#define CmdWriteRec  2				/* Write one or more bytes */

#define CmdOpenC    10				/* Open Comm Channel */
#define CmdCloseC   11				/* Close Comm Channel */
#define CmdDiscardRcv 12
#define CmdSetRTO	13
#define CmdSetXTO	14
#define CmdSetDTR   15				/* Set DTR (On) */
#define CmdSetRTS	16				/* Set CTS (On) */
#define CmdReSetDTR 17				/* Set DTR (On) */
#define CmdReSetRTS 18				/* Set CTS (On) */
#define CmdBreak	19
#define CmdGetDC	20
#define CmdGetDSR	21
#define CmdGetCTS	22
#define CmdGetRI	23

#define CmdReadB	31
#define CmdWriteB	32

/* The following definitions are used to identify, set
   and reset signal line condition and functions.
*/

#define CTS         0x10		/* Clear To Send       */
#define DSR         0x20		/* Data Set Ready      */
#define RI          0x40		/* Ring Indicator      */
#define CD          0x80		/* Carrier Detect      */

#define DTR         0x01		/* Data Terminal Ready */
#define RTS         0x02		/* Request To Send     */
#define OUT2		0x08		/* Not used */

/* values from IIR register */

#define MDMSTAT		0x00
#define NOINT		0x01
#define TXEMPTY 	0x02
#define RVCDATA 	0x04
#define RCVSTAT		0x06


/* For errors returned from Comms calls see COMMDRV.H */

#define SSENDBUF 4096		/* 1 Page Send Buf Default */
#define SRECVBUF 4096		/* 1 Page Recv Buf Default */

U32  recv_timeout[2] = 1;	/* 10ms intervals */
U32  xmit_timeout[2] = 10;	/* 10ms intervals */

/* variables for ISRs */

U8 	stat_byte[2];
U8 	mstat_byte[2];
U8	int_id[2];

U8	fExpectInt[2];

U32 recv_error[2]; 	/* NON-ZERO = an error has occurred */

U8   *pSendBuf[2];	/* pointers to Xmit bufs */
U32  head_send[2];	/* Next char to send */
U32  tail_send[2];	/* Where next char goes in buf */
U32  cSendBuf[2];	/* Count of bytes in buf */
U32  sSendBuf[2];	/* Size of buffer (allocated) */

U8   *pRecvBuf[2];	/* pointers to Recv bufs */
U32  head_recv[2];	/* Next char from chip */
U32  tail_recv[2];	/* Next char to read for caller */
U32  cRecvBuf[2];	/* Count of bytes in buf */
U32  sRecvBuf[2];	/* Size of buffer (allocated) */

U8   control_byte[2] = 0;

 /* array of registers from port base for each channel */

U16      THR[2];		/* Transmitter Holding Register */
U16      IER[2];		/* Interrupt Enable Register */
U16      IIR[2];		/* Interrupt Id Register */
U16      LCR[2];		/* Line Control Register */
U16      MCR[2];		/* Modem Control Register */
U16      LSR[2];		/* Line Status Register */
U16      MSR[2];		/* Modem Status Register */
U16      DLAB_LO[2];	/* same address as THR  */
U16      DLAB_HI[2];   /* same address as IER  */

/* Complete description of Register bits follows:

	THR -- TX data, RX data, Divisor Latch LSB

	IER -- Interrupt Enable, Divisor Latch MSB

			    7 6 5 4 3 2 1 0
			    | | | | | | |  \_ Data Available
			    | | | | | |  \___ Xmit Holding Reg Empty
			    | | | | |  \_____ Receiver Line Status
			    | | | |  \_______ Modem Status
			    \ _ _ _\_________ = Always 0

	IIR -- Interrupt Identification Register

			    7 6 5 4 3 2 1 0
			    | | | | |  \_\_\___ 001 = no interrupt
			    | | | | |			110 = rcvr status
			    | | | | |			100 = rcvd data
			    | | | | |			010 = THR empty
			    | | | | |			000 = Modem status
			    \ _ _ _ _\_______ = Always 0

	LCR --  Line Control Register

			    7 6 5 4 3 2 1 0
			    | | | | | | |  \_ Word Length Select Bit 0.
			    | | | | | |  \___ Word Length Select Bit 1.
			    | | | | |  \_____ Number Stop Bits (0=1, 1=2)
			    | | | |  \_______ Parity Enable
			    | | |  \_________ Even Parity Select
			    | |  \___________ Stick Parity
			    |  \_____________ Set Break
			     \_______________ Divisor Latch Access Bit

	MCR -- Modem Control Register

			    7 6 5 4 3 2 1 0
			    | | | | | | |  \_ Data Terminal Ready
			    | | | | | |  \___ Request to Send
			    | | | | |  \_____ Out 1
			    | | | |  \_______ Out 2  (= 1 to enable ints.)
			    | | |  \_________ Loop
			    \ _ _\___________ = Always 0

	LSR -- Line Status Register

			    7 6 5 4 3 2 1 0
			    | | | | | | |  \_ Data Ready
			    | | | | | |  \___ Overrun Error
			    | | | | |  \_____ Parity Error
			    | | | |  \_______ Framing Error
			    | | |  \_________ Break interrupt
			    | |  \___________ Transmitter Holding Reg Empty
			    |  \_____________ Transmitter Shift Reg Empty
			     \_______________ = 0

	MSR -- Modem Status Register

			    7 6 5 4 3 2 1 0
			    | | | | | | |  \_ Delta Clear to Send
			    | | | | | |  \___ Delta Data Set Ready
			    | | | | |  \_____ Trailing Edge Ring Indicator
			    | | | |  \_______ Delta Rx Line Signal Detect
			    | | |  \_________ Clear to Send
			    | |  \___________ Data Set Ready
			    |  \_____________ Ring Indicator
			     \_______________ Receive Line Signal Detect

*/


/* Record for 64 byte status and init record */
/* This structure is peculiar to the comms driver */

#define sStatus 64

struct statRecC comstat[2];
struct statRecC *pCS;

struct dcbtype {
	S8   Name[12];
	S8   sbName;
	S8   type;
	S16  nBPB;
	U32  last_erc;
	U32  nBlocks;
	S8  *pDevOp;
	S8  *pDevInit;
	S8  *pDevSt;
	S8   fDevReent;
	S8   fSingleUser;
	S16  wJob;
	U32  OS1;
	U32  OS2;
	U32  OS3;
	U32  OS4;
	U32  OS5;
	U32  OS6;
	};

struct dcbtype comdcb[2];		/* Two RS-232 ports */


/* THE COMMS INTERRUPT FUNCTION PROTOTYPES */

void interrupt comISR0(void);
void interrupt comISR1(void);

/* -------------------------------------------------- */
/* -------------------------------------------------- */
/* -------------------------------------------------- */

/*********************************************************
    This is called ONCE to initialize the 2 default
    coms channels with the OS device driver interface.
    It sets up defaults for both channels to 9600, 8N1.
*********************************************************/

U32  coms_setup(void)
{
U32  erc;

  /* first we set up the 2 DCBs in anticipation of calling InitDevDr */

 comdcb[0].Name[0]  = 'C';
 comdcb[0].Name[1]  = 'O';
 comdcb[0].Name[2]  = 'M';
 comdcb[0].Name[2]  = '1';
 comdcb[0].sbName   = 4;
 comdcb[0].type     = 2;			/* Sequential */
 comdcb[0].nBPB     = 1;			/* 1 byte per block */
 comdcb[0].nBlocks  = 0;			/* 0 for Sequential devices */
 comdcb[0].pDevOp   = &comdev_op;
 comdcb[0].pDevInit = &comdev_init;
 comdcb[0].pDevSt   = &comdev_stat;

 comdcb[1].Name[0]  = 'C';
 comdcb[1].Name[1]  = 'O';
 comdcb[1].Name[2]  = 'M';
 comdcb[1].Name[2]  = '2';
 comdcb[1].sbName   = 4;
 comdcb[1].type     = 2;			/* Sequential */
 comdcb[1].nBPB     = 1;			/* 1 byte per block */
 comdcb[1].nBlocks  = 0;			/* 0 for Sequential devices */
 comdcb[1].pDevOp   = &comdev_op;
 comdcb[1].pDevInit = &comdev_init;
 comdcb[1].pDevSt   = &comdev_stat;

 /* Set default comms params in stat records */

comstat[0].Baudrate = 9600;
comstat[0].parity   = 0;	/* none */
comstat[0].databits = 8;
comstat[0].stopbits = 1;
comstat[0].XTimeOut = 100;
comstat[0].RTimeOut = 2;
comstat[0].IOBase = 0x3F8;
comstat[0].IRQNum = 4;
comstat[0].XBufSize = 4096;
comstat[0].RBufSize = 4096;
sSendBuf[0] = 4096;
sRecvBuf[0] = 4096;

comstat[1].Baudrate = 9600;
comstat[1].parity   = 0;	/* none */
comstat[1].databits = 8;
comstat[1].stopbits = 1;
comstat[1].XTimeOut = 100;
comstat[1].RTimeOut = 2;
comstat[1].IOBase = 0x2F8;
comstat[1].IRQNum = 3;
comstat[1].XBufSize = 4096;
comstat[1].RBufSize = 4096;
sSendBuf[1] = 4096;
sRecvBuf[1] = 4096;

 MaskIRQ(4);
 MaskIRQ(3);

 SetIRQVector(4, &comISR0);	/* COM1 */
 SetIRQVector(3, &comISR1);	/* COM2 */

 return(erc = InitDevDr(5, &comdcb, 2, 1));

}

/*********************************************************
  This does the grunt work for each of the two ISRs
*********************************************************/

void handleISR(U32 i)		/* i is the device */
{
U8 *pRBuf, *pXBuf;

pRBuf = pRecvBuf[i];
pXBuf = pSendBuf[i];

while (TRUE) {
	int_id[i] = InByte (IIR[i]);		/* Get ID Byte from IIR */
	switch (int_id[i]) {
		case RCVSTAT:
		    stat_byte[i] = InByte(LSR[i]);  /* clear error conditions */
			break;

		case RVCDATA:
	       	if (cRecvBuf[i] == sRecvBuf[i]) {		/* Overflow!! */
				recv_error[i] = ErcRcvBufOvr;		/* Do not put in buf */
	    	    InByte (THR[i]);					/* trash the byte */
			}
			else {
#asm
	CLI
#endasm
		        pRBuf[head_recv[i]] =
		        	InByte (THR[i]);	/* Get the byte */
				++cRecvBuf[i];
    	    	if (++head_recv[i] == SRECVBUF)
	        	    head_recv[i] = 0;
#asm
	STI
#endasm
				recv_error[i] = 0;
		    }
    	    break;

		case TXEMPTY:
#asm
	CLI
#endasm
	        if (cSendBuf[i]) {
    		    OutByte(pXBuf[tail_send[i]], THR[i]);  /* Send the byte */
	    	    if (++tail_send[i] == sSendBuf[i])
	        		tail_send[i] = 0;
		        --cSendBuf[i];
				fExpectInt[i] = TRUE;
			}
			else
				fExpectInt[i] = FALSE;
#asm
	STI
#endasm
		break;

		case MDMSTAT:
	    mstat_byte[i] = InByte (MSR[i]);   /* Get Modem Status */
		break;

		case NOINT:
	    stat_byte[i] = InByte(LSR[i]);  /* clear error conditions */
		default:
    	return;
	}
}
}


void interrupt comISR0(void)
{
;		/* ; needed if asm is first in function */
#asm
	STI
#endasm
	handleISR(0);
	EndOfIRQ(4);
	return;
}


void interrupt comISR1(void)
{
;		/* ; needed if asm is first in function */
#asm
	STI
#endasm
	handleISR(1);
	EndOfIRQ(3);
	return;
}

/********************************************/


long ReadByteC(U32 device, unsigned char *pByteRet)
{
U32 counter;
U8 *pRBuf;

	pRBuf = pRecvBuf[device];
	if (recv_error[device]) return (recv_error[device]);

	if (cRecvBuf[device]) {
        *pByteRet = pRBuf[tail_recv[device]];
        if (++tail_recv[device] == sRecvBuf[device])
        	tail_recv[device] = 0;
       	--cRecvBuf[device];
		return (0);
	}

	counter = comstat[device].RTimeOut;		/* set up for timeout */
	while (counter--) {
		Sleep(1);
		if (cRecvBuf[device]) {
	        *pByteRet = pRBuf[tail_recv[device]];
	        if (++tail_recv[device] == sRecvBuf[device])
	        	tail_recv[device] = 0;
        	--cRecvBuf[device];
			return (0);
		}
	}
	return (ErcRecvTimeout);
}

/********************************************/


long ReadRecordC(U32 device,
				unsigned char *pDataRet,
                unsigned int  sDataMax,
                unsigned int *pcbRet)
{
int  erc, cb;

	erc = 0;
	cb = 0;
	while ((cb < sDataMax) && (!erc)) {
		erc = ReadByteC(device, pDataRet++);
		if (!erc) ++cb;
		}
	*pcbRet = cb;		/* tell em how many bytes */
    return (erc);
}



/********************************************/

⌨️ 快捷键说明

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