sdc.c

来自「基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7」· C语言 代码 · 共 1,112 行 · 第 1/4 页

C
1,112
字号
		/* Disable interrupts */
        int_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);

        /* Initialize the UART */

        /************** Begin Port Specific Section *************/

        /* Disable the receiver & transmiter */
        SD_OUTBYTE (uart->base_address + SD_UCON_OFFSET, SD_UCON_DISABLE);

        /* 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));

        /* Setup baud rate */
        SDC_Set_Baud_Rate(uart->baud_rate, uart);

        /* Setup vector number to be generated by UART1 */
        if (uart->com_port == SD_UART1)
        {
            /* Enable the UART1 interrupt. */

            imr_val = SD_INDWORD(INTMSK);
            imr_val &= ~(SD_IMR_UART1_RX_MASK);
            //imr_val &= ~(SD_IMR_UART1_TX_MASK);
            imr_val &= ~(SD_IMR_MASTER_MASK);
            SD_OUTDWORD (INTMSK, imr_val);
            /* clear pending bit befor enable interrupt */
            SD_OUTDWORD(I_ISPC, SD_IMR_UART1_TX_MASK);
              
            
        }
        else
        {
            /* Setup interrupt level of UART2, also diable autovector. */

            imr_val = SD_INDWORD(INTMSK);
            imr_val &= ~(SD_IMR_UART2_RX_MASK);
            imr_val &= ~(SD_IMR_UART2_TX_MASK);
            imr_val &= ~(SD_IMR_MASTER_MASK);  

            SD_OUTDWORD (INTMSK, imr_val);
        }

        /* Enable Tx & Rx in UCON register. */
        SD_OUTBYTE (uart->base_address + SD_UCON_OFFSET, 
                    (SD_UCON_TX_MODE_IRQ | SD_UCON_RX_MODE_IRQ));

        /* Reset to IRQ mode in UFCON register (Disables FIFO Mode) */
        SD_OUTBYTE (uart->base_address + SD_UFCON_OFFSET, SD_UFCON_DISABLE);

        /************** End Port Specific Section *************/

        /* Initialize the error counters. */
        uart->parity_errors   = 0;
        uart->frame_errors    = 0;
        uart->overrun_errors  = 0;
        uart->busy_errors     = 0;
        uart->general_errors  = 0;

		/* Restore interrupts to previous level */
        NU_Local_Control_Interrupts(int_level);

    }

    return (status);

} /* END SDC_Init_Port(SD_PORT *uart) */



/****************************************************************************/
/* 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(UNSIGNED_CHAR ch, SD_PORT *uart)
{

UNSIGNED    imr_val;             /* IRQ Mask register value */

    if (uart->communication_mode == SERIAL_MODE)
    {
        /* Check the transmit buffer status. If it has data already
           just add this byte to the buffer. */
        if (( uart->tx_buffer_status == NU_BUFFER_DATA) ||
            ( uart->tx_buffer_status == NU_BUFFER_FULL) )
        {
            /* If the buffer is full wait for it to empty a little. */
            while (uart->tx_buffer_status == NU_BUFFER_FULL)
				NU_Sleep (1);   /* Wait for one tick */

            /* Add byte to buffer. */
			uart->tx_buffer[uart->tx_buffer_write++] = ch;

            /* Check for wrap of buffer. */
            uart->tx_buffer_write %= uart->sd_buffer_size;
          
            /* Check for full buffer. */
            if (uart->tx_buffer_write == uart->tx_buffer_read)
			    uart->tx_buffer_status = NU_BUFFER_FULL;
		}
		else /* Otherwise send the data! */
        {   /* This should be the case when Buffer_Status = Empty! */
            /* Add byte to buffer. */
            uart->tx_buffer[uart->tx_buffer_write++] = ch;

            /* Check for wrap of buffer. */
             uart->tx_buffer_write %= uart->sd_buffer_size;
             
            /* Set status */
            uart->tx_buffer_status = NU_BUFFER_DATA;

            /**************** Begin Port Specific Section **************/

            /* Wait until the transmitter buffer is empty by polling USTAT
            ** until Tx Holding Reg bit is set */
            while (! (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET)
                      & SD_USTAT_TX_EMPTY));

	        /* Unmask the TX interrupt in INT MASK register.
            **
            ** NOTE: On the KS32C41000 - It appears that Tx IRQ must be enabled
            **       prior to stuffing the char to the Tx holding Reg or no IRQ
            **       is generated!
            **********************************************************************/
            imr_val = SD_INDWORD(INTMSK);
            
            /* This is one of the places were we must specify which UART!   */
            if (uart->com_port == SD_UART1)
            {
                imr_val &= ~(SD_IMR_UART1_TX_MASK);
                SD_OUTDWORD (INTMSK, imr_val);
            }
            else if (uart->com_port == SD_UART2)
            {
                imr_val &= ~(SD_IMR_UART2_TX_MASK);
                SD_OUTDWORD (INTMSK, imr_val);
            }

            /* Transmit the character */
            SD_OUTBYTE (uart->base_address + SD_UTXH_OFFSET, ch);
		}

    }  /* END if (uart->communication_mode == SERIAL_MODE)  */
    else /* 'else' is NOT Used for SERIAL_MODE !)   */ 
    {       
        /* Wait until the transmitter buffer is empty by polling USTAT
            ** until Tx Holding Reg bit is set */
        while (! (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET)
                   & SD_USTAT_TX_EMPTY));

        /* Transmit the character */
        SD_OUTBYTE (uart->base_address + SD_UTXH_OFFSET, ch);

/* Not required with the KS32C41000 !
#ifndef PPP_POLLED_TX
     SD_OUTBYTE (uart->base_address + SD_UIMR_OFFSET, SD_UIMR_TX_ENABLE);
#endif
*/
    }
       /***************** End Port Specific Section ***************/

}  /* END SDC_Put_Char(UNSIGNED_CHAR ch, SD_PORT *uart)  */




/****************************************************************************/
/* 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                                               */
/*                                                                          */
/***** NOTE: In the ARM ports Input will be the IRQ Pending Reg value       */
/*           instead an interrupt Vector.                                   */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*    none                                                                  */
/*                                                                          */
/****************************************************************************/
/* This is for processors that have multiple vectors:
** static VOID  SDC_LISR(INT vector)
*/
VOID  SDC_LISR(void)
{
/* NOTE: For the ARM Processors there is no input Vector used to determine
**       which UART is interrupting!  Instead the external variable
**       "INTERRUPTING_DEVICE", captured in INT_IRQ, may be used to set the
**       structure pointer if more than 1 UART is initialized!
**
**       For the Version 1.11.1 Plus release we will use only UART 1 so the
**       *uart is initialized at entry to SDC_Port_List[0].
**
**       The reference code that searches the SDC_Port_List[] for a matching 
**       Vector has been commented out for this ARM port!
*****************************************************************************/
    SD_PORT         *uart = SDC_Port_List[0];

/* For multiple UARTs  
**  SD_PORT         *uart; */

    UNSIGNED        imr_val;                    
    CHAR            receive;
    unsigned char   rx_status;

    /* Default vector_found to NU_TRUE in THIS ARM Port! */
    INT             vector_found = NU_TRUE;

#ifdef PPP
    DV_DEVICE_ENTRY *device;
#endif

		/* Find the port stucture for this vector. */
/*** NOT for ARM!
        receive = 0;
        while ((SDC_Port_List[receive] != NU_NULL)             &&
               (SDC_Port_List[receive] -> vector != vector)    &&
               (receive < SD_MAX_UARTS) )
            receive++;
***/       	
	    /* See if we found one and point our local structure to it.
        ** (Better have since we got an interrupt from one) */
/***
        if (SDC_Port_List[receive] -> vector == vector)
        {
            uart = SDC_Port_List[receive];
            vector_found = NU_TRUE;
	    }
***/

#ifdef  PPP        
        else
        { 
	        /* Find the device for this interrupt */
            if ( (device = DEV_Get_Dev_For_Vector(vector)) != NU_NULL)
            {
                /* Get the address of the uart structure for this device. */ 
                uart = &((PPP_LAYER *) device->ppp_layer)->uart;

⌨️ 快捷键说明

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