?? sdc.c
字號:
/*************************************************************************
*
* Copyright Mentor Graphics Corporation 2003
* All Rights Reserved.
*
* THIS WORK CONTAINS TRADE SECRET AND PROPRIETARY INFORMATION WHICH IS
* THE PROPERTY OF MENTOR GRAPHICS CORPORATION OR ITS LICENSORS AND IS
* SUBJECT TO LICENSE TERMS.
*
*************************************************************************/
/*************************************************************************
*
* FILE NAME VERSION
*
* sdc.c Nucleus PLUS\S3C2410X\ADS
*
* DESCRIPTION
*
* This file contains the Serial Driver specific functions.
*
* DATA STRUCTURES
*
* SD_PORT * : An array of pointers to serial port structures.
*
* FUNCTIONS
*
* SDC_Init_Port
* SDC_Date_Ready
* SDC_Put_String
* SDC_LISR
* SDC_Get_Char
* SDC_Put_Char
* SDC_Set_Baud_Rate
*
* DEPENDENCIES
*
* nucleus.h
* sd_defs.h
* sd_extr.h
* target.h
* protocol.h
* externs.h
* ppp.h
*
*************************************************************************/
#include "sd_defs.h"
#include "sd_extr.h"
#include "def.h"
/* Define a small array to hold pointers to the two UART data
structures. This is used by the LISR to find the correct
data structure for the interrupt being handled. */
SD_PORT *SDC_Port_List[SD_MAX_UARTS];
/* Define prototypes for functions local to this module. */
static VOID SDC_Set_Baud_Rate(UNSIGNED, SD_PORT *);
/************** Begin Board Specific Section ****************/
/************** End Board Specific Section **************/
/****************************************************************************
* FUNCTION
*
* SDC_Init_Port
*
* DESCRIPTION
*
* This function intializes the COM port that will be used for PPP
* communications.
*
* CALLED BY
*
* Application
*
* CALLS
*
* NU_Local_Control_Interrupts
* SDC_Set_Baud_Rate
*
* INPUTS
*
* SD_PORT * : device initialization structure.
*
* OUTPUTS
*
* STATUS : Returns NU_SUCCESS if successful initialization,
* else a negative value is returned.
*
****************************************************************************/
STATUS SDC_Init_Port(SD_PORT *uart)
{
STATUS status = NU_SUCCESS;
UINT32 temp32;
UINT32 mode;
UINT32 submsk;
static INT num_ports = 0;
if (uart->communication_mode == SERIAL_MODE)
{
/* Check for max allowed UARTS. */
if (num_ports >= SD_MAX_UARTS)
/* We have already initialized the max allowed UARTS. */
status = NU_UART_LIST_FULL;
}
if (status == NU_SUCCESS)
{
/* Check the supplied parity */
if ((uart->parity != SD_PARITY_NONE) &&
(uart->parity != SD_PARITY_EVEN) &&
(uart->parity != SD_PARITY_ODD))
/* The supplied parity is not valid */
status = NU_INVALID_PARITY;
/* Check the supplied number of data bits */
else if ((uart->data_bits != SD_DATA_BITS_5) &&
(uart->data_bits != SD_DATA_BITS_6) &&
(uart->data_bits != SD_DATA_BITS_7) &&
(uart->data_bits != SD_DATA_BITS_8))
/* The supplied data bits value is not valid */
status = NU_INVALID_DATA_BITS;
/* Check the supplied number of stop bits */
else if ((uart->stop_bits != SD_STOP_BITS_1) &&
(uart->stop_bits != SD_STOP_BITS_2))
/* The supplied stop bits value is not valid */
status = NU_INVALID_STOP_BITS;
/* Verify the baud rate is within acceptable range */
else if ((uart->baud_rate < 1200) || (uart->baud_rate > 115200))
/* The baud rate is out of range */
status = NU_INVALID_BAUD;
/************** Begin Board Specific Section ****************/
/* Validate the com port. */
else if ((uart->com_port == SD_UART0) ||
(uart->com_port == SD_UART1) ||
(uart->com_port == SD_UART2))
{
/* Handle UART0 */
if (uart->com_port == SD_UART0)
{
/* Set the vector inside this structure */
uart->vector = SD_UART0_VECTOR;
/* Set the base address for this UART. */
uart->base_address = SD_UART0_BASE;
}
/* Handle UART1. */
else if (uart->com_port == SD_UART1)
{
/* Set the vector inside this structure */
uart->vector = SD_UART1_VECTOR;
/* Set the base address for this UART. */
uart->base_address = SD_UART1_BASE;
}
/* Handle UART2. */
else
{
/* Set the vector inside this structure */
uart->vector = SD_UART2_VECTOR;
/* Set the base address for this UART. */
uart->base_address = SD_UART2_BASE;
}
}
else
/************** End Board Specific Section **************/
/* Not a supported port. */
status = NU_INVALID_COM_PORT;
}
if (uart->communication_mode == SERIAL_MODE)
{
/* Make sure all the above was completed. Then store off this
UART stucture and initialize the chip. */
if (status == NU_SUCCESS)
{
SDC_Port_List[num_ports++] = uart;
}
}
if (status == NU_SUCCESS)
{
/* Allocate memory for the data buffers. PPP only requires a TX
buffer so the allocation will be a little different for PPP mode. */
if (status == NU_SUCCESS)
{
/* Setup the RX SD buffer */
uart->rx_buffer_read = uart->rx_buffer_write = 0;
uart->rx_buffer_status = NU_BUFFER_EMPTY;
}
}
if (status == NU_SUCCESS)
{
/* Disable interrupts */
// int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
/************** Begin Board Specific Section *************/
/* Clear Control registers */
SD_OUTDWORD (uart->base_address + SD_ULCON_OFFSET, 0);
SD_OUTDWORD (uart->base_address + SD_UCON_OFFSET, 0);
SD_OUTDWORD (uart->base_address + SD_UFCON_OFFSET, 0x00000000);
SD_OUTDWORD (uart->base_address + SD_UMCON_OFFSET, 0x00000000);
/* Setup baud rate */
SDC_Set_Baud_Rate(uart->baud_rate, uart);
/* Setup Mode, Parity, Stop Bits and Data Size in ULCON Reg. */
SD_OUTBYTE (uart->base_address + SD_ULCON_OFFSET,
(uart->parity | uart->data_bits | uart->stop_bits));
/* Enable Rx and Tx in UCON register. */
SD_OUTWORD (uart->base_address + SD_UCON_OFFSET,
(SD_UCON_RX_ENABLE | SD_UCON_RX_INT_LEVEL | SD_UCON_TX_INT_LEVEL|SD_UCON_TX_ENABLE));
/* Get characters from receiver until Receive Ready bit not set */
do
{
temp32 = SD_INDWORD(uart->base_address + SD_URXH_OFFSET);
/* Keep looping until RX ready bit not set */
} while (SD_INDWORD(uart->base_address + SD_UTRSTAT_OFFSET) & SD_USTAT_RX_RDY);
/* Get current interrupt controller mask register value */
temp32 = SD_INDWORD (SD_INT_BASE + SD_INT_MSK_OFFSET);
/* Get current interrupt controller mode register value */
mode = SD_INDWORD (SD_INT_BASE + SD_INT_MOD_OFFSET);
/* Get current interrupt sub mask register value */
submsk = SD_INDWORD (SD_INT_BASE + SD_INT_SUBMSK_OFFSET);
/* Unmask / set mode in interrupt controller */
if (uart->com_port == SD_UART0)
{
/* Unmask UART0 interrupts (mask and submask) */
temp32 &= ~SD_INT_UART0;
submsk &=( ~(SD_INT_RXD0)|SD_INT_TXD0);
/* Ensure mode bits are cleared first */
mode &= ~SD_INT_UART0;
/* Set mode bits based on define in SD_DEFS.H */
mode |= (SD_INT_UART0 * SD_UART0_INT_MODE);
}
else if (uart->com_port == SD_UART1) /* Otherwise handle UART1. */
{
/* Unmask UART1 interrupts */
temp32 &= ~SD_INT_UART1;
submsk &= (~(SD_INT_RXD1 )|SD_INT_TXD1);
/* Ensure mode bits are cleared first */
mode &= ~SD_INT_UART1;
/* Set mode bits based on define in SD_DEFS.H */
mode |= (SD_INT_UART1 * SD_UART1_INT_MODE);
}
else /* Otherwise handle UART2. */
{
/* Unmask Console UART interrupts */
temp32 &= ~SD_INT_UART2;
submsk &= (~(SD_INT_RXD2 )|SD_INT_TXD2);
/* Ensure mode bits are cleared first */
mode &= ~SD_INT_UART2;
/* Set mode bits based on define in SD_DEFS.H */
mode |= (SD_INT_UART2 * SD_UART2_INT_MODE);
}
/* Write updated mask register value back to interrupt controller */
SD_OUTDWORD (SD_INT_BASE + SD_INT_MSK_OFFSET, temp32);
/* Write updated mode register value back to interrupt controller */
SD_OUTDWORD (SD_INT_BASE + SD_INT_MOD_OFFSET, mode);
/* Write updated interrupt sub mask register value */
SD_OUTDWORD (SD_INT_BASE + SD_INT_SUBMSK_OFFSET, submsk);
/************** End Board Specific Section *************/
/* Initialize the error counters. */
SDC_Reset(uart);
}
/* Return status of initialization */
return (status);
}
/****************************************************************************
* FUNCTION
*
* SDC_Put_Char
*
* DESCRIPTION
*
* This writes a character out to the serial port.
*
* CALLED BY
*
* UART_Put_String
* Application
*
* CALLS
*
* Serial port macros
*
* INPUTS
*
* UNSIGNED_CHAR : Character to to be written to the serial port.
* SD_PORT * : Serial port to send the char to.
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID SDC_Put_Char(UINT8 ch, SD_PORT *uart)
{
/* Transmit the character */
volatile int status;
SD_OUTDWORD (uart->base_address + SD_UTXH_OFFSET, ch);
status = SD_INDWORD(uart->base_address + SD_UTRSTAT_OFFSET);
while(!(status&0x4))
{
status = SD_INDWORD(uart->base_address + SD_UTRSTAT_OFFSET);
}
}
/****************************************************************************
* FUNCTION
*
* SDC_LISR
*
* DESCRIPTION
*
* This is the entry function for the ISR that services the UART.
*
* CALLED BY
*
* none
*
* CALLS
*
* Serial port macros
*
* INPUTS
*
* INT : Interrupt vector
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID SDC_LISR(INT vector)
{
SD_PORT *uart;
CHAR receive;
UINT32 status;
INT vector_found = NU_FALSE;
for(receive = 0 ; (SDC_Port_List[receive] != 0) &&
(receive < SD_MAX_UARTS) && !vector_found ; receive++)
{
/* See if we found one. Better have since we got an interrupt
from one. */
if (SDC_Port_List[receive] -> vector == vector)
{
/* Point our local structure to it. */
uart = SDC_Port_List[receive];
vector_found =TRUE;
}
}
/* Ensure vector was found */
if (vector_found == TRUE)
{
/**************** Begin Board Specific Section **************/
/* Get the uart status */
status = SD_INDWORD(uart->base_address + SD_UTRSTAT_OFFSET);
/* Check if receiver is ready - characters received */
if (status & SD_USTAT_RX_RDY)
{
/* Get UART error status */
status = SD_INDWORD (uart->base_address + SD_UERSTAT_OFFSET);
/* Process every character in the receive FIFO */
do
{
/* Clear any error bits */
SD_OUTDWORD(uart->base_address + SD_UERSTAT_OFFSET,status);
/* Get the received character from the receive holding register */
receive = (UINT8)SD_INDWORD(uart->base_address + SD_URXH_OFFSET);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -