/****************************************************************************** * COPYRIGHT (c) MOTOROLA 2002 * FILE NAME: sci.c REVISION 1.0 * * PURPOSE: SCI Source File * ******************************************************************************* * * DESCRIPTION: SCI Source File * * NOTE: * * AUTHOR: rat579 LOCATION: OHT LAST EDIT DATE: 08/08/02 * * UPDATE HISTORY * REV AUTHOR DATE DESCRIPTION OF CHANGE * --- ------ --------- --------------------- * 1.0 r9aabe 08/08/02 - Original coding * ******************************************************************************/ #include "sci.h" /* Local Variable Declarations */ uchar RxBuff[RxBufSize]; /* receive queue */ uchar TxBuff[TxBufSize]; /* transmit queue */ uchar RxIn; /* next available location in the Rx queue */ uchar RxOut; /* next character to be removed from the Rx queue */ uchar TxIn; /* next available location in the Tx queue */ uchar TxOut; /* next character to be sent from the Tx queue */ volatile uchar RxBAvail; /* number of bytes left in the Rx queue */ volatile uchar TxBAvail; /* number of bytes left in the Tx queue */ uchar XOffSent; /* flag indicating that an XOff character was sent */ uchar XOffRcvd; /* flag indicating that an XOff character was received (== 1, XOff was received) */ uchar SendXOff; /* flag indicating that the TxISR should send an XOff the next time it's called */ uchar SendXOn; /*Local Prototypes*/ uchar SCIcharAvail(void); int TERMIO_GetChar(void); int TERMIO_PutChar(uchar); uchar InitSCI(ulong); void RxISR(void); void TxISR(void); void sci0_handler(void); void sci_tos(void); /*************************************************************************************/ uchar SCIcharAvail(void) { /* Variable Declarations */ /* Begin Function SCIcharAvail() */ if (RxBAvail != RxBufSize) /* if a character is available in the Receive Data buffer */ return(TRUE); /* return true */ else return(FALSE); } /* end SCIcharAvail */ /*************************************************************************************/ int TERMIO_PutChar (uchar c) { /* Variable Declarations */ /* Begin Function putchar() */ while (TxBAvail == 0) /* if there's no room in the xmit queue */ ; /* wait here */ TxBuff[TxIn++] = c; /* put the char in the buffer, inc buffer index */ if (TxIn == TxBufSize) /* buffer index go past the end of the buffer? */ TxIn = 0; /* yes. wrap around to the start */ TxBAvail--; /* one less character available in the buffer */ if (XOffRcvd == 0) /* if an XOff has not been received... */ Sci0.scicr2.byte |= TIE; /* enable SCI transmit interrupts */ return(c); /* return the character we sent */ } /* end putchar */ /*************************************************************************************/ int TERMIO_GetChar (void) { /* Variable Declarations */ uchar c; /* holds the character we'll return */ /* Begin Function getchar() */ while (RxBAvail == RxBufSize) /* if there's no characters in the Rx buffer */ ; /* just wait here */ c = RxBuff[RxOut++]; /* get a character from the Rx buffer & advance the Rx index */ if (RxOut == RxBufSize) /* index go past the physical end of the buffer? */ RxOut = 0; /* yes wrap around to the start */ RxBAvail++; /* 1 more byte available in the receive buffer */ if ((XOffSent != 0) && (RxBAvail >= XOnCount)) /* if an XOff was previously sent & the Rx buffer has more than XOnCount bytes available */ { SendXOn = 1; Sci0.scicr2.byte |= TIE; /* enable SCI transmit interrupts */ } return(c); /* return the character retrieved from receive buffer */ } /* end getchar */ /*************************************************************************************/ uchar InitSCI(ulong baud) { /* Variable Declarations */ /* Begin Function InitSCI() */ RxIn = RxOut = TxIn = TxOut = 0; /* set the Rx & Tx queue indexes to zero */ RxBAvail = RxBufSize; /* the receive buffer is empty */ TxBAvail = TxBufSize; /* the transmit buffer is empty */ XOffSent = 0; XOffRcvd = 0; Sci0.scibd.word = (uint)((((busclk/16)*1000)/baud)); /* initialize the Baud register */ Sci0.scicr2.byte = TE + RE + RIE; /* enable both the transmitter & receiver */ return(1); /* return */ } /* end InitSCI */ /*************************************************************************************/ void RxISR(void) { /* Variable Declarations */ uchar c; /* Begin Function RxISR() */ // clear RDRF interrupt flag c = Sci0.scisr1.byte; c = Sci0.scidrl.byte; // if (c == XOff) /* host want us to stop sending data? */ // { // Sci0.scicr2.byte &= ~TIE; /* yes. disable transmit interrupts */ // XOffRcvd = 1; /* let putchar know that it may continue to place */ // return; /* characters in the buffer but not enable Xmit interrupts */ // } // else if (c == XOn) /* host want us to start sending data? */ // { // if (TxBAvail != TxBufSize) /* anything left in the Tx buffer? */ // Sci0.scicr2.byte |= TIE; /* yes. enable transmit interrupts */ // XOffRcvd = 0; // return; // } // if ((RxBAvail <= XOffCount) && (XOffSent == 0)) /* if the number of bytes available in the Rx buff is < XOffCount & an XOff hasn't been sent */ // { // SendXOff = 1; /* set flag to send an XOff, stoping the host from sending data */ // XOffSent = 1; /* set the flag showing that we've queued up to send an XOff */ // Sci0.scicr2.byte |= TIE; /* enable transmit interrupts, so the TxISR will be called next time the TDRE bit is set */ // } if (RxBAvail != 0) /* if there are bytes available in the Rx buffer */ { RxBAvail--; /* reduce the count by 1 */ RxBuff[RxIn++] = c; /* place the received byte in the buffer */ if (RxIn == RxBufSize) /* reached the physical end of the buffer? */ RxIn = 0; /* yes. wrap around to the start */ } } /* end RxISR */ /*************************************************************************************/ void TxISR(void) { /* Variable Declarations */ /* Begin Function TxISR() */ if (SendXOn != 0) /* request to send an XOn to the host? */ { SendXOn = 0; XOffSent = 0; /* reset the XOff flag */ Sci0.scidrl.byte = XOn; /* send the character */ if (TxBAvail == TxBufSize) /* anything in the Tx buffer? */ Sci0.scicr2.byte &= ~TIE; /* no. disable transmit interrupts */ } else if (SendXOff != 0) /* request to send an XOff to the host? */ { SendXOff = 0; /* yes, clear the request */ Sci0.scidrl.byte = XOff; /* send the character */ if (TxBAvail == TxBufSize) /* anything in the Tx buffer? */ Sci0.scicr2.byte &= ~TIE; /* no. disable transmit interrupts */ } else { Sci0.scidrl.byte = TxBuff[TxOut++]; /* remove a character from the buffer & send it */ if (TxOut == TxBufSize) /* reached the physical end of the buffer? */ TxOut = 0; /* yes. wrap around to the start */ if (++TxBAvail == TxBufSize) /* anything left in the Tx buffer? */ Sci0.scicr2.byte &= ~TIE; /* no. disable transmit interrupts */ } } /* end TxISR */ /************************************************************************** * Name: SCI0 handler * Updates: **************************************************************************/ void sci0_handler(void) { /* Variable Declarations */ /* Begin Function SCIISR() */ if (Sci0.scisr1.byte & (RDRF + ORF)) RxISR(); if ((Sci0.scicr2.byte & TIE) && (Sci0.scisr1.byte & TDRE)) TxISR(); } /* end SCIISR */ /************************************************************************** * Name: SCI_clear screen * returns cursor to top of screen * Updates: **************************************************************************/ void sci_tos(void) { int x; for (x=0;x<25;x++) { (void) putchar (0x1b); (void) putchar (0x5b); (void) putchar (0x41); } }