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

📄 uart2.cpp

📁 coldfire5206芯片的boot程序
💻 CPP
字号:
/*
FileName:      uart2.cpp
Description:   The MCF5206's UART2 driver.
Version:       v1.0
Function List:
               CF5206Uart2SetConfig
               CF5206Uart2InitializeBuffer
               CF5206Uart2Reset
               CF5206Uart2WriteString
               CF5206Uart2WriteByte
               CF5206Uart2ReadString
               CF5206Uart2ReadByte
               CF5206Uart2ReceiveControl
               CF5206Uart2TransmitControl
               CF5206Uart2ISR

History:
   <author>           <time>                <desc>
  Li Linghua        2001/5/25            The file was created today.
*/

#include  "bastype.h"
#include  "mcf5206.h"
#include  "uartdrv.h"
#include  "Uart2.h"


/**
 *  constant define: UART2 registers' address
 */
#define UMR1  (MCF5206::UART2_BASE + 0)    // Mode register, read/write
#define UMR2  (UMR1)                       // Mode register, read/write (after UMR1)
#define USR   (MCF5206::UART2_BASE + 4)    // Status register, read
#define UCSR  (USR)                        // clock select register, write
#define UCR   (MCF5206::UART2_BASE + 8)    // Command register, write
#define URB   (MCF5206::UART2_BASE + 0xc)  // Receiver buffer, read
#define UTB   (URB)                        // Transmitter buffer, write
#define UIPCR (MCF5206::UART2_BASE + 0x10) // Input port change register, read
#define UACR  (UIPCR)                      // Auxiliary control register, write
#define UISR  (MCF5206::UART2_BASE + 0x14) // Interrupt status register, read
#define UIMR  (UISR)                       // Interrupt mask register, write
#define UBG1  (MCF5206::UART2_BASE + 0x18) // Baud rate generator prescale MSB, read/write
#define UBG2  (MCF5206::UART2_BASE + 0x1c) // Baud rate generator prescale LSB, read/write
#define UIVR  (MCF5206::UART2_BASE + 0x30) // Interrupt vector register, read/write
#define UIP   (MCF5206::UART2_BASE + 0x34) // Input port register, read
#define UOP1  (MCF5206::UART2_BASE + 0x38) // Output portbit set CMD, write
#define UOP0  (MCF5206::UART2_BASE + 0x3c) // Output portbit set CMD, write


#define RxEnable( )   { *(UCHAR*)UCR = 0x01;}
#define RxDisable( )  { *(UCHAR*)UCR = 0x02;}
#define TxEnable( )   { *(UCHAR*)UCR = 0x04;}
#define TxDisable( )  { *(UCHAR*)UCR = 0x08;}


UARTINFO  gCF5206Uart2Info;

/**
 *  static variables define.
 */
static    UCHAR   sReceiveBuffer[RECEIVE_BUF_LENGTH];
static    UCHAR*  sReceiveOutPtr;
static    UCHAR*  sReceiveInPtr;
static    UCHAR*  sReceiveBufHead;
static    UCHAR*  sReceiveBufTail;
static    UCHAR   sTransmitBuffer[TRANSMIT_BUF_LENGTH];
static    UCHAR*  sTransmitOutPtr;
static    UCHAR*  sTransmitInPtr;
static    UCHAR*  sTransmitBufHead;
static    UCHAR*  sTransmitBufTail;

// Error counter.
// @initialize to 0.
static UINT32  sParityError;
static UINT32  sFrameError;
static UINT32  sOverRunError;

// Receive interrupt source: RxRDY or FFULL
// this value will be set according to interrupt mode.
static UCHAR  sRxIrqSource;

// cpu's uart config setting const, defined in uartdrv.cpp
extern const UCHAR sUBG1Const[BR_MAX];
extern const UCHAR sUBG2Const[BR_MAX];
extern const UCHAR sUBG1Const[BR_MAX];
extern const UCHAR sUBG2Const[BR_MAX];
extern const UCHAR sParityConst[PARITY_MAX];
extern const UCHAR sDataBitsConst[DATABITS_MAX];
extern const UCHAR sStopBitsConst[STOPBITS_MAX];

// UART status constant define
#define  STATUS_RXRDY        0x01
#define  STATUS_FFULL        0x02
#define  STATUS_TXRDY        0x04
#define  STATUS_OVERRUN_ERR  0x10
#define  STATUS_PARITY_ERR   0x20
#define  STATUS_FRAME_ERR    0x40

#define  IRQ_SOURCE_FFULL  STATUS_FFULL
#define  IRQ_SOURCE_RXRDY  STATUS_RXRDY

#define  MULTIDROP_DATA_CHAR  0x00
#define  MULTIDROP_ADDR_CHAR  0x04

/*
 Function Name:  CF5206Uart2SetConfig
 Description:    Using given configuration to initialize UART2
 Parameters:     config -- configuration data
 Return:         Nothing
 Output:         Nothing
 Test&Revision:  Not yet
*/
VOID  CF5206Uart2SetConfig( const UARTCONFIG* config )
{
   // reset receiver and transmitter
   *(UCHAR*)UCR = 0x20;
   *(UCHAR*)UCR = 0x30;

   // reset error status and break-change interrupt
   *(UCHAR*)UCR = 0x40;
   *(UCHAR*)UCR = 0x50;

   // interrupt vector number
   *(UCHAR*)UIVR = MCF5206::IV_UART2;

   // interrupt source: TxRDY and RxRDY
   *(UCHAR*)UIMR = 0x03;

   // interrupt auxiliary
   *(UCHAR*)UACR = 0x00;

   // clock select: Receiver and Transmitter are all select interval clock
   *(UCHAR*)UCSR = 0xdd;

   // baud rate set
   *(UCHAR*)UBG1 = sUBG1Const[config->baudRate];
   *(UCHAR*)UBG2 = sUBG2Const[config->baudRate];

   // select UMR1
   *(UCHAR*)UCR  = 0x10;

   // mode set: Parity, data bits and IRQ source
   if ( TRUE == config->useBufferedReceive )
   {
      sRxIrqSource = IRQ_SOURCE_FFULL;
      *(UCHAR*)UMR1 =   sParityConst[config->parity]
                      | sDataBitsConst[config->dataBits]
                      | 0x60; // IRQ source: FFULL, Error mode: Block mode
   }
   else
   {
      sRxIrqSource = IRQ_SOURCE_RXRDY;
      *(UCHAR*)UMR1 =   sParityConst[config->parity]
                      | sDataBitsConst[config->dataBits]
                      | 0x00; // IRQ source: RxRDY, Error mode: Character mode
   }

   // mode set: Normal mode, stop-bits
   *(UCHAR*)UMR2 = sStopBitsConst[config->stopBits];
   
   CF5206Uart2Reset( );
}


/*
 Function Name:  CF5206Uart2InitializeBuffer
 Description:    Initialize UART's variables
 Parameters:     No
 Return:         Nothing
 Output:         Nothing
 Test&Revision:  Not yet
*/
VOID  CF5206Uart2InitializeBuffer( VOID )
{
   sReceiveBufHead = sReceiveBuffer;
   sReceiveBufTail = sReceiveBuffer + RECEIVE_BUF_LENGTH - 1;

   sTransmitBufHead = sTransmitBuffer;
   sTransmitBufTail = sTransmitBuffer + TRANSMIT_BUF_LENGTH - 1;

   sReceiveInPtr   = sReceiveBufHead;
   sReceiveOutPtr  = sReceiveBufHead;
   sTransmitInPtr  = sTransmitBufHead;
   sTransmitOutPtr = sTransmitBufHead;

   gCF5206Uart2Info.receiveErrorInfo = 0;
   gCF5206Uart2Info.receivedBytes    = 0;
   gCF5206Uart2Info.isTxBufferEmpty  = TRUE;
}


/*
 Function Name:  CF5206Uart2Reset
 Description:    reset UART2's buffer and status
 Parameters:     No
 Return:         Nothing
 Output:         Nothing
 Test&Revision:  Not yet
*/
VOID  CF5206Uart2Reset( VOID )
{
   CF5206Uart2InitializeBuffer( );

   sFrameError   = 0;
   sParityError  = 0;
   sOverRunError = 0;
}


/*
 Function Name:  CF5206Uart2WriteString
 Description:    Transmit a string from UART2 of MCF5206
 Parameters:     string  --  the characters to be transmited
                 str_len --  the number of characters of the string
 Return:         bytes transmitted
 Output:         Nothing
 Test&Revision:  Not yet
                 1. 2001.7.27: if no enough buffer, no byte will be transmitted,
                    so, the value returned must be str_len or 0
*/
INT16  CF5206Uart2WriteString(UCHAR* string, UINT16 str_len)
{
   INT   bytes_to_be_written;
   INT   bytes_be_written;

   UCHAR *transmit_out_ptr = sTransmitOutPtr;
   
   // return immediately if no bytes to be transmitted
   if (0 >= str_len)
      return 0;

   // Calculate the free buffer number
   if (sTransmitInPtr >= transmit_out_ptr)
      bytes_to_be_written =   (sTransmitBufTail - sTransmitBufHead)
                            - (sTransmitInPtr - transmit_out_ptr);
   else
      bytes_to_be_written = transmit_out_ptr - sTransmitInPtr - 1;
   // return if buffer is not enough.
   if (bytes_to_be_written < str_len)
      return 0;

   bytes_to_be_written = str_len;

   bytes_be_written = bytes_to_be_written;

   // Copy string to transmitter buffer
   while (0 < bytes_to_be_written)
   {
      *sTransmitInPtr ++ = *string ++;

      if (sTransmitInPtr > sTransmitBufTail)
         sTransmitInPtr = sTransmitBufHead;

      bytes_to_be_written --;
   }

   gCF5206Uart2Info.isTxBufferEmpty = FALSE;

   TxEnable( );

   return bytes_be_written;
}

/*
 Function Name:  CF5206Uart2WriteByte
 Description:    Transmit one byte from UART2 of MCF5206
 Parameters:     byte  --  the character to be transmited
 Return:         TRUE if the byte has been transmitted,
                 FALSE if failed becasue of full buffer
 Output:         Nothing
 Test&Revision:  Not yet
*/
BOOL  CF5206Uart2WriteByte(UCHAR byte)
{
   INT   result;
   UCHAR* transmit_in_ptr_next;

   transmit_in_ptr_next = sTransmitInPtr + 1;
   if (transmit_in_ptr_next > sTransmitBufTail)
      transmit_in_ptr_next = sTransmitBufHead;

   // transmit it if transmit buffer is not full
   if ( transmit_in_ptr_next != sTransmitOutPtr)
   {
      *sTransmitInPtr = byte;
      sTransmitInPtr = transmit_in_ptr_next;

      gCF5206Uart2Info.isTxBufferEmpty = FALSE;
      TxEnable( );

      return TRUE;
   }
   else
      return FALSE;
}


/*
 Function Name:  CF5206Uart2ReadString
 Description:    Read datas in UART2's receive buffer.
 Parameters:     length -- How many bytes you want to read
                 data   -- Where to save the data been read
 Return:         actual bytes been read
 Output:         Nothing
 Note:           The data buffer must has a length of not less than length
                 you given, if not, something you hate to see may happen.
 Test&Revision:  Not yet
*/
INT16  CF5206Uart2ReadString(UCHAR* data, UINT16 length)
{
   INT   bytes_to_be_read;
   INT   bytes_be_read;

   UCHAR* receive_in_ptr = sReceiveInPtr;
   
   // Calculate how many bytes can be read
   if (receive_in_ptr >= sReceiveOutPtr)
      bytes_to_be_read = receive_in_ptr - sReceiveOutPtr;
   else
      bytes_to_be_read =  (sReceiveBufTail - sReceiveBufHead + 1)
                        - (sReceiveOutPtr - receive_in_ptr);

   // The number of bytes can be read is the minimal of
   // bytes_to_be_read and length
   if (bytes_to_be_read > length)
      bytes_to_be_read = length;

   bytes_be_read = bytes_to_be_read;

   while (0 < bytes_to_be_read)
   {
      *data ++ = *sReceiveOutPtr ++;
      
      if (sReceiveOutPtr > sReceiveBufTail)
         sReceiveOutPtr = sReceiveBufHead;

      bytes_to_be_read --;
   }

   return bytes_be_read;
}


/*
 Function Name:  CF5206Uart2ReadByte
 Description:    Read datas in UART2's receive buffer.
 Parameters:     data  -- Where to save the data been read
 Return:         TRUE if read succeed,
                 FALSE if no data can be read
 Output:         Nothing
 Test&Revision:  Not yet
*/
BOOL  CF5206Uart2ReadByte( UCHAR* data )
{
   if (sReceiveOutPtr != sReceiveInPtr)
   {
      *data = *sReceiveOutPtr;

      sReceiveOutPtr ++;
      if (sReceiveOutPtr > sReceiveBufTail)
         sReceiveOutPtr = sReceiveBufHead;

      return TRUE;
   }
   else
      return FALSE;
}


/*
 Function Name:  CF5206Uart2ReceiveControl
 Description:    Provide an interface to disable or enable receive interrupt
 Parameters:     Operation: disable or enable interrupt 
 Return:         Nothing
 Output:         Nothing
 Test&Revision:  Not yet
*/
VOID  CF5206Uart2ReceiveControl( UCHAR operation )
{
   if (UART_DISABLE == operation)
      RxDisable( );
   if (UART_ENABLE == operation)
			RxEnable( );
}

/*
 Function Name:  CF5206Uart2TransmitControl
 Description:    Provide an interface to disable or enable transmit interrupt
 Parameters:     Operation: disable or enable interrupt
 Return:         Nothing
 Output:         Nothing
 Test&Revision:  Not yet
*/
VOID  CF5206Uart2TransmitControl( UCHAR operation )
{
   if (UART_DISABLE == operation)
   {
      TxDisable( );
   }
   else
   {
			TxEnable( );
   }   
}


/*
 Function Name:  CF5206Uart2ISR
 Description:    MCF5206 UART2 interrupt service routine
 Parameters:     No
 Return:         Nothing
 Output:         Nothing
 Test&Revision:  Not yet
*/
extern "C" VOID  CF5206Uart2ISR( VOID )
{
   UCHAR status, data;
   UCHAR* receive_in_ptr_next;

   status = *(UCHAR*)USR;

   // even in FFULL interrupt mode, we must do the following
   if (STATUS_RXRDY == (status&STATUS_RXRDY))
   {
      data = *(UCHAR*)URB;

      gCF5206Uart2Info.receivedBytes ++;

      // Check whether a error occured.
      if ( 0 == (status&(STATUS_OVERRUN_ERR|STATUS_PARITY_ERR|STATUS_FRAME_ERR)) )
      {
         receive_in_ptr_next = sReceiveInPtr + 1;
         if (receive_in_ptr_next > sReceiveBufTail)
            receive_in_ptr_next = sReceiveBufHead;

         // No error found, save character.
         if (sReceiveOutPtr != receive_in_ptr_next)
         {
            *sReceiveInPtr = data;

            sReceiveInPtr = receive_in_ptr_next;
         }
      }
      else
      {
         // report OverRun error if
         if (STATUS_OVERRUN_ERR == (status&STATUS_OVERRUN_ERR) )
         {
            gCF5206Uart2Info.receiveErrorInfo ++;
            sOverRunError ++;
         }

         // report parity error if occurred
         if (STATUS_PARITY_ERR == (status&STATUS_PARITY_ERR))
         {
            gCF5206Uart2Info.receiveErrorInfo ++;
            sParityError ++;
         }

         // report frame error if occurred
         if (STATUS_FRAME_ERR == (status&STATUS_FRAME_ERR))
         {
            gCF5206Uart2Info.receiveErrorInfo ++;
            sFrameError ++;
         }   
      }

      // clear error status
      *(UCHAR*)UCR = 0x40;
   }

   // if transmit interrupt occurred, call the transmit ISR
   if (STATUS_TXRDY == (status&STATUS_TXRDY))
   {
      if (sTransmitOutPtr != sTransmitInPtr)
      {
         // transmit a byte
         *(UCHAR*)UTB = *sTransmitOutPtr;

         sTransmitOutPtr ++;
         if (sTransmitOutPtr > sTransmitBufTail)
            sTransmitOutPtr = sTransmitBufHead;
      }
      else
      {
         gCF5206Uart2Info.isTxBufferEmpty = TRUE;
         TxDisable( );
      }
   }
}

⌨️ 快捷键说明

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