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

📄 sdc.c

📁 S3C2410上RS485驱动源码,用ADS1.2编译工程,已测试通过.内附文档.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************
*
*               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"
#include "2410addr.h"
#include "lcdlib.h"
#include "string.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;
    volatile 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 = (volatile)SD_INDWORD(uart->base_address + SD_URXH_OFFSET);

        /* Keep looping until RX ready bit not set */
        } while ((volatile)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 __irq SDC_LISR0(void)
{
	SD_PORT         *uart;
	char            receive,ch,Str[2];
	UINT32          status;
	//INT             vector_found = NU_FALSE;
	int temp;
    
    memset(Str,0,sizeof(Str));	
   

	uart = SDC_Port_List[0];
	/* Ensure vector was found */


	/**************** 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 = SD_INWORD(uart->base_address + SD_URXH_OFFSET);

			/* Check for parity / framing error */
			if (status & (SD_UERSTAT_FRAME | SD_UERSTAT_OVERRUN))
			{
				/* Update error counts as necessary */
				uart->frame_errors+=((status & SD_UERSTAT_FRAME)==SD_UERSTAT_FRAME);
				uart->parity_errors+=((status & SD_UERSTAT_PARITY)==SD_UERSTAT_PARITY);
			}
			else
			{
				/* Update overrun error count as necessary */
				uart->overrun_errors+=((status & SD_UERSTAT_OVERRUN)==SD_UERSTAT_OVERRUN);

				/* Execute based on mode */
				switch(uart->communication_mode)
				{
					case SERIAL_MODE:

						/* Check if the receive buffer is full */
						if (uart->rx_buffer_status != NU_BUFFER_FULL)
						{
							if(receive == 0x0D)
							{
								PrintTextEdit("$",RGB(255,255,0),5,g_yMax-90,g_xMax-5,30,1);
								SDC_Put_String("\n\rThe received data: ",uart);
								do{
									// Store the character to be returned 
									ch = uart->rx_buffer[uart->rx_buffer_read++];

									SDC_Put_Char(ch,uart);

									// If read pointer is at end, wrap it around 
									if (uart->rx_buffer_read == uart->sd_buffer_size)
										uart->rx_buffer_read = 0;

								} while (uart->rx_buffer_write != uart->rx_buffer_read);
									
								SDC_Put_String("\n\n\rPlease Input the data: ", uart);
							}
							else
							{
								/* Put the character into the buffer */
								uart->rx_buffer[uart->rx_buffer_write++] = receive;

								/*显示字符*/
								Str[0] = receive;
								//Str[1] = 0;
								SDC_Put_Char(receive,uart);
#ifdef	STN
								PrintTextEdit(Str,RGB(255,255,0),5,385,640,30,1);
#else								
								//PrintTextEdit(Str,RGB(255,255,0),5,150,320,30,1);
								PrintTextEdit(Str,RGB(255,255,0),5,g_yMax-90,g_xMax-5,30,1);
#endif								

								/* Check for wrap of buffer. */
								if(uart->rx_buffer_write == uart->sd_buffer_size)
									uart->rx_buffer_write = 0;

								/* Set status field based on latest character */
								if (uart->rx_buffer_write == uart->rx_buffer_read)
									uart->rx_buffer_status = NU_BUFFER_FULL;
								else
									uart->rx_buffer_status = NU_BUFFER_DATA;
							}
						}
						else
							/* buffer is full, increment busy errors */
							uart->busy_errors++;
						break;

				}

			}

			/* Get UART status */
			status = SD_INDWORD (uart->base_address + SD_UTRSTAT_OFFSET);

			/* Keep looping while receive data ready */
		} while (status& SD_USTAT_RX_RDY);//

	/**************** End Board Specific Section **************/
	}

	temp = rSUBSRCPND;
	rSUBSRCPND=temp;
	temp = rSRCPND;
	rSRCPND = temp;
	temp = rINTPND;
	rINTPND = temp;
 }

void __irq SDC_LISR1(void)
{
    SD_PORT         *uart;
    CHAR            receive;
    UINT32          status;
    INT             vector_found,temp;
    	
   
    vector_found = TRUE;
    uart = SDC_Port_List[1];
    /* 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 */

⌨️ 快捷键说明

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