Пример #1
0
/***************************************************************************
Function: sFlushTxFIFO
Purpose:  Flush the Tx FIFO
Call:	  sFlushTxFIFO(ChP)
	  CHANNEL_T *ChP; Ptr to channel structure
Return:   void
Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
	  while it is being flushed the receive processor is stopped
	  and the transmitter is disabled.  After these operations a
	  4 uS delay is done before clearing the pointers to allow
	  the receive processor to stop.  These items are handled inside
	  this function.
Warnings: No context switches are allowed while executing this function.
*/
void sFlushTxFIFO(CHANNEL_T *ChP)
{
   int i;
   Byte_t Ch;			/* channel number within AIOP */
   int TxEnabled;		       /* TRUE if transmitter enabled */

   if(sGetTxCnt(ChP) == 0)	       /* Tx FIFO empty */
      return;			       /* don't need to flush */

   TxEnabled = FALSE;
   if(ChP->TxControl[3] & TX_ENABLE)
   {
      TxEnabled = TRUE;
      sDisTransmit(ChP);	       /* disable transmitter */
   }
   sStopRxProcessor(ChP);	       /* stop Rx processor */
   for(i = 0; i < 4000/200; i++)	 /* delay 4 uS to allow proc to stop */
      rp_readch1(ChP,_INT_CHAN);	/* depends on bus i/o timing */
   Ch = (Byte_t)sGetChanNum(ChP);
   rp_writech1(ChP,_CMD_REG,Ch | RESTXFCNT);     /* apply reset Tx FIFO count */
   rp_writech1(ChP,_CMD_REG,Ch);		       /* remove reset Tx FIFO count */
   rp_writech2(ChP,_INDX_ADDR,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
   rp_writech2(ChP,_INDX_DATA,0);
   if(TxEnabled)
      sEnTransmit(ChP); 	       /* enable transmitter */
   sStartRxProcessor(ChP);	       /* restart Rx processor */
}
Пример #2
0
/***************************************************************************
Function: sFlushRxFIFO
Purpose:  Flush the Rx FIFO
Call:	  sFlushRxFIFO(ChP)
	  CHANNEL_T *ChP; Ptr to channel structure
Return:   void
Comments: To prevent data from being enqueued or dequeued in the Tx FIFO
	  while it is being flushed the receive processor is stopped
	  and the transmitter is disabled.  After these operations a
	  4 uS delay is done before clearing the pointers to allow
	  the receive processor to stop.  These items are handled inside
	  this function.
Warnings: No context switches are allowed while executing this function.
*/
void sFlushRxFIFO(CHANNEL_T *ChP)
{
   int i;
   Byte_t Ch;			/* channel number within AIOP */
   int RxFIFOEnabled;		       /* TRUE if Rx FIFO enabled */

   if(sGetRxCnt(ChP) == 0)	       /* Rx FIFO empty */
      return;			       /* don't need to flush */

   RxFIFOEnabled = FALSE;
   if(ChP->R[0x32] == 0x08) /* Rx FIFO is enabled */
   {
      RxFIFOEnabled = TRUE;
      sDisRxFIFO(ChP);		       /* disable it */
      for(i=0; i < 2000/200; i++)	/* delay 2 uS to allow proc to disable FIFO*/
	 rp_readch1(ChP,_INT_CHAN);		/* depends on bus i/o timing */
   }
   sGetChanStatus(ChP); 	 /* clear any pending Rx errors in chan stat */
   Ch = (Byte_t)sGetChanNum(ChP);
   rp_writech1(ChP,_CMD_REG,Ch | RESRXFCNT);     /* apply reset Rx FIFO count */
   rp_writech1(ChP,_CMD_REG,Ch);		       /* remove reset Rx FIFO count */
   rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */
   rp_writech2(ChP,_INDX_DATA,0);
   rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
   rp_writech2(ChP,_INDX_DATA,0);
   if(RxFIFOEnabled)
      sEnRxFIFO(ChP);		       /* enable Rx FIFO */
}
Пример #3
0
/***************************************************************************
Function: sDisInterrupts
Purpose:  Disable one or more interrupts for a channel
Call:	  sDisInterrupts(ChP,Flags)
	  CHANNEL_T *ChP; Ptr to channel structure
	  Word_t Flags: Interrupt flags, can be any combination
	     of the following flags:
		TXINT_EN:   Interrupt on Tx FIFO empty
		RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
			    sSetRxTrigger())
		SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
		MCINT_EN:   Interrupt on modem input change
		CHANINT_EN: Disable channel interrupt signal to the
			    AIOP's Interrupt Channel Register.
Return:   void
Comments: If an interrupt flag is set in Flags, that interrupt will be
	  disabled.  If an interrupt flag is not set in Flags, that
	  interrupt will not be changed.  Interrupts can be enabled with
	  function sEnInterrupts().

	  This function clears the appropriate bit for the channel in the AIOP's
	  Interrupt Mask Register if the CHANINT_EN flag is set.  This blocks
	  this channel's bit from being set in the AIOP's Interrupt Channel
	  Register.
*/
void sDisInterrupts(CHANNEL_T *ChP,Word_t Flags)
{
   Byte_t Mask; 		/* Interrupt Mask Register */

   ChP->RxControl[2] &=
	 ~((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->RxControl));
   ChP->TxControl[2] &= ~((Byte_t)Flags & TXINT_EN);
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxControl));

   if(Flags & CHANINT_EN)
   {
      Mask = rp_readch1(ChP,_INT_MASK) & rp_sBitMapClrTbl[ChP->ChanNum];
      rp_writech1(ChP,_INT_MASK,Mask);
   }
}
Пример #4
0
/***************************************************************************
Function: sEnInterrupts
Purpose:  Enable one or more interrupts for a channel
Call:	  sEnInterrupts(ChP,Flags)
	  CHANNEL_T *ChP; Ptr to channel structure
	  Word_t Flags: Interrupt enable flags, can be any combination
	     of the following flags:
		TXINT_EN:   Interrupt on Tx FIFO empty
		RXINT_EN:   Interrupt on Rx FIFO at trigger level (see
			    sSetRxTrigger())
		SRCINT_EN:  Interrupt on SRC (Special Rx Condition)
		MCINT_EN:   Interrupt on modem input change
		CHANINT_EN: Allow channel interrupt signal to the AIOP's
			    Interrupt Channel Register.
Return:   void
Comments: If an interrupt enable flag is set in Flags, that interrupt will be
	  enabled.  If an interrupt enable flag is not set in Flags, that
	  interrupt will not be changed.  Interrupts can be disabled with
	  function sDisInterrupts().

	  This function sets the appropriate bit for the channel in the AIOP's
	  Interrupt Mask Register if the CHANINT_EN flag is set.  This allows
	  this channel's bit to be set in the AIOP's Interrupt Channel Register.

	  Interrupts must also be globally enabled before channel interrupts
	  will be passed on to the host.  This is done with function
	  sEnGlobalInt().

	  In some cases it may be desirable to disable interrupts globally but
	  enable channel interrupts.  This would allow the global interrupt
	  status register to be used to determine which AIOPs need service.
*/
void sEnInterrupts(CHANNEL_T *ChP,Word_t Flags)
{
   Byte_t Mask; 		/* Interrupt Mask Register */

   ChP->RxControl[2] |=
      ((Byte_t)Flags & (RXINT_EN | SRCINT_EN | MCINT_EN));

   rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->RxControl[0]);

   ChP->TxControl[2] |= ((Byte_t)Flags & TXINT_EN);

   rp_writech4(ChP,_INDX_ADDR,*(DWord_t *)&ChP->TxControl[0]);

   if(Flags & CHANINT_EN)
   {
      Mask = rp_readch1(ChP,_INT_MASK) | rp_sBitMapSetTbl[ChP->ChanNum];
      rp_writech1(ChP,_INT_MASK,Mask);
   }
}
Пример #5
0
/***************************************************************************
Function: sInitChan
Purpose:  Initialization of a channel and channel structure
Call:	  sInitChan(CtlP,ChP,AiopNum,ChanNum)
	  CONTROLLER_T *CtlP; Ptr to controller structure
	  CHANNEL_T *ChP; Ptr to channel structure
	  int AiopNum; AIOP number within controller
	  int ChanNum; Channel number within AIOP
Return:   int: TRUE if initialization succeeded, FALSE if it fails because channel
	       number exceeds number of channels available in AIOP.
Comments: This function must be called before a channel can be used.
Warnings: No range checking on any of the parameters is done.

	  No context switches are allowed while executing this function.
*/
int sInitChan(	CONTROLLER_T *CtlP,
		CHANNEL_T *ChP,
		int AiopNum,
		int ChanNum)
{
   int i, ChOff;
   Byte_t *ChR;
   static Byte_t R[4];

   if(ChanNum >= CtlP->AiopNumChan[AiopNum])
      return(FALSE);		       /* exceeds num chans in AIOP */

   /* Channel, AIOP, and controller identifiers */
   ChP->CtlP = CtlP;
   ChP->ChanID = CtlP->AiopID[AiopNum];
   ChP->AiopNum = AiopNum;
   ChP->ChanNum = ChanNum;

   /* Initialize the channel from the RData array */
   for(i=0; i < RDATASIZE; i+=4)
   {
      R[0] = RData[i];
      R[1] = RData[i+1] + 0x10 * ChanNum;
      R[2] = RData[i+2];
      R[3] = RData[i+3];
      rp_writech4(ChP,_INDX_ADDR,le32dec(R));
   }

   ChR = ChP->R;
   for(i=0; i < RREGDATASIZE; i+=4)
   {
      ChR[i] = RRegData[i];
      ChR[i+1] = RRegData[i+1] + 0x10 * ChanNum;
      ChR[i+2] = RRegData[i+2];
      ChR[i+3] = RRegData[i+3];
   }

   /* Indexed registers */
   ChOff = (Word_t)ChanNum * 0x1000;

   ChP->BaudDiv[0] = (Byte_t)(ChOff + _BAUD);
   ChP->BaudDiv[1] = (Byte_t)((ChOff + _BAUD) >> 8);
   ChP->BaudDiv[2] = (Byte_t)BRD9600;
   ChP->BaudDiv[3] = (Byte_t)(BRD9600 >> 8);
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->BaudDiv));

   ChP->TxControl[0] = (Byte_t)(ChOff + _TX_CTRL);
   ChP->TxControl[1] = (Byte_t)((ChOff + _TX_CTRL) >> 8);
   ChP->TxControl[2] = 0;
   ChP->TxControl[3] = 0;
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxControl));

   ChP->RxControl[0] = (Byte_t)(ChOff + _RX_CTRL);
   ChP->RxControl[1] = (Byte_t)((ChOff + _RX_CTRL) >> 8);
   ChP->RxControl[2] = 0;
   ChP->RxControl[3] = 0;
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->RxControl));

   ChP->TxEnables[0] = (Byte_t)(ChOff + _TX_ENBLS);
   ChP->TxEnables[1] = (Byte_t)((ChOff + _TX_ENBLS) >> 8);
   ChP->TxEnables[2] = 0;
   ChP->TxEnables[3] = 0;
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxEnables));

   ChP->TxCompare[0] = (Byte_t)(ChOff + _TXCMP1);
   ChP->TxCompare[1] = (Byte_t)((ChOff + _TXCMP1) >> 8);
   ChP->TxCompare[2] = 0;
   ChP->TxCompare[3] = 0;
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxCompare));

   ChP->TxReplace1[0] = (Byte_t)(ChOff + _TXREP1B1);
   ChP->TxReplace1[1] = (Byte_t)((ChOff + _TXREP1B1) >> 8);
   ChP->TxReplace1[2] = 0;
   ChP->TxReplace1[3] = 0;
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxReplace1));

   ChP->TxReplace2[0] = (Byte_t)(ChOff + _TXREP2);
   ChP->TxReplace2[1] = (Byte_t)((ChOff + _TXREP2) >> 8);
   ChP->TxReplace2[2] = 0;
   ChP->TxReplace2[3] = 0;
   rp_writech4(ChP,_INDX_ADDR,le32dec(ChP->TxReplace2));

   ChP->TxFIFOPtrs = ChOff + _TXF_OUTP;
   ChP->TxFIFO = ChOff + _TX_FIFO;

   rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum | RESTXFCNT); /* apply reset Tx FIFO count */
   rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum);  /* remove reset Tx FIFO count */
   rp_writech2(ChP,_INDX_ADDR,ChP->TxFIFOPtrs); /* clear Tx in/out ptrs */
   rp_writech2(ChP,_INDX_DATA,0);
   ChP->RxFIFOPtrs = ChOff + _RXF_OUTP;
   ChP->RxFIFO = ChOff + _RX_FIFO;

   rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum | RESRXFCNT); /* apply reset Rx FIFO count */
   rp_writech1(ChP,_CMD_REG,(Byte_t)ChanNum);  /* remove reset Rx FIFO count */
   rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs); /* clear Rx out ptr */
   rp_writech2(ChP,_INDX_DATA,0);
   rp_writech2(ChP,_INDX_ADDR,ChP->RxFIFOPtrs + 2); /* clear Rx in ptr */
   rp_writech2(ChP,_INDX_DATA,0);
   ChP->TxPrioCnt = ChOff + _TXP_CNT;
   rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioCnt);
   rp_writech1(ChP,_INDX_DATA,0);
   ChP->TxPrioPtr = ChOff + _TXP_PNTR;
   rp_writech2(ChP,_INDX_ADDR,ChP->TxPrioPtr);
   rp_writech1(ChP,_INDX_DATA,0);
   ChP->TxPrioBuf = ChOff + _TXP_BUF;
   sEnRxProcessor(ChP); 	       /* start the Rx processor */

   return(TRUE);
}