coldfire5206芯片的boot程序
源代码在线查看: uart2.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:
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( );
}
}
}