sdc.c

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

C
1,112
字号
                vector_found = NU_TRUE;    
            }
        } 
#endif
    if (vector_found == NU_TRUE)
    {
        /**************** Begin Port Specific Section **************/

        /* For multiple UARTs  
        ** uart = SDC_Port_List[INTERRUPTING_DEVICE];
        */

        /* Test for Rx characters first ! */
        if (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET) & SD_USTAT_RXRDY)
        {
            /* Process every Rx character! */
            do 
            {
                rx_status = (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET));
            
                /* Check for a damaged or incorrectly received character */
                if (rx_status & (SD_USTAT_FRAME_ERR | SD_USTAT_PARITY_ERR))
                {
                    if (rx_status & SD_USTAT_FRAME_ERR)
                    {
                        uart->frame_errors++;
                    }
                    
                    if (rx_status & SD_USTAT_PARITY_ERR)
                    {
		                uart->parity_errors++;
		            }	

                    /* Consume the character to clear the error bits */
                    receive = SD_INBYTE (uart->base_address + SD_URXH_OFFSET);
                }
			    else
                {
                    /* If an overrun has occured, log it */
                    if (rx_status & SD_USTAT_OVERRUN_ERR)
                    {
                        uart->overrun_errors++;
        		    }
    				
                    /* Process RX character ! */
				    switch(uart->communication_mode)
                    {
                        case SERIAL_MODE: 
		                    /* Put char into buffer */
                            receive = SD_INBYTE (uart->base_address + SD_URXH_OFFSET);

                            if (uart->rx_buffer_status != NU_BUFFER_FULL)
                            {
                                /* Put the character into the buffer */
                                uart->rx_buffer[uart->rx_buffer_write++] = receive;
				
                                /* If write pointer is at end, wrap it around */
                                uart->rx_buffer_write %= uart->sd_buffer_size;
                                
                                /* 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;
                            }
                            break;
#ifdef PPP				        
                            /* call PPP processing functions */

                            case MDM_NETWORK_COMMUNICATION:
                                 /* Call this devices receive routine */
							    device->dev_receive(device);
                                break;

                            case MDM_TERMINAL_COMMUNICATION:
                            default:
		                        MDM_Receive(device);
                                break;
#endif 
                    
                    } /* END switch(uart->communication_mode)  */ 

                } /* END else (no Rx Errors) */

            /* END do (while........)  */
            } while (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET) & SD_USTAT_RXRDY);

        /* END if (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET) & SD_USTAT_RXRDY) */
        } 
        /* TX --->>> Rx processing done......Now check for a transmit interrupt. */
        else if (SD_INBYTE (uart->base_address + SD_USTAT_OFFSET) & SD_USTAT_TX_EMPTY)
        {
            if (uart->communication_mode == SERIAL_MODE)
            {    
                /* Bump the read pointer past the byte that was just transmitted.*/
                ++(uart->tx_buffer_read);
                
			    /* Check for wrap of buffer. */
                uart->tx_buffer_read %= uart->sd_buffer_size;

                /* Update the status. */
                if (uart->tx_buffer_write == uart->tx_buffer_read)
                {
                    uart->tx_buffer_status = NU_BUFFER_EMPTY;

                    /* Since it is now empty disable the TX interrupt! */
                    if (uart->com_port == SD_UART1)
                    {
                        imr_val = SD_INDWORD(INTMSK);
                        imr_val |= SD_IMR_UART1_TX_MASK;
                        SD_OUTDWORD (INTMSK, imr_val);
                        /* attention! interrupt pending must be cleared after changing mask */
                        /* see S3C44B0X user manual */
                        //SD_OUTDWORD(I_ISPC, SD_IMR_UART1_TX_MASK);
                    }
                    else if (uart->com_port == SD_UART2)
                    {
                        imr_val = SD_INDWORD(INTMSK);
                        imr_val |= SD_IMR_UART2_TX_MASK;
                        SD_OUTDWORD (INTMSK, imr_val);
                    }
                }
		        else
                {   /* Send the next byte in the queue. */
                    SD_OUTBYTE (uart->base_address + SD_UTXH_OFFSET,
                                 uart->tx_buffer[uart->tx_buffer_read]);
						
                    /* Update the status. */
                    uart->tx_buffer_status = NU_BUFFER_DATA;
                }

            } /* END if (uart->communication_mode == SERIAL_MODE) */
#ifdef PPP
            else
            {
#ifndef PPP_POLLED_TX   /* This is NOT defined, so this code is included! */
                /* Check for a transmit interrupt. */
                /* Is there another byte in the TX buffer to send? */
                if (uart->tx_buffer_read != uart->tx_buffer_write)
                {
                    /* Send the next byte in the queue. */
                    SD_OUTBYTE (uart->base_address + SD_UTXH_OFFSET,
                                 uart->tx_buffer[uart->tx_buffer_read++]); 
                        
			        /* Check for wrap of ring buffer. */
				    uart->tx_buffer_read %= uart->sd_buffer_size;
                }
			    else /* We are doing Polled PPP Tx ! */
                {
				    /* Only activate the HISR if we are tranmitting network data. */
                    if (uart->communication_mode == MDM_NETWORK_COMMUNICATION)
                    {
                        /* Add this device to the list of PPP devices that have finished
                           sending a packet. */
                        _ppp_tx_dev_ptr_queue [_ppp_tx_dev_ptr_queue_write++] = device;

                        /* Activate the HISR that will take care of processing the
                            next packet in queue, if one is ready. */
                        NU_Activate_HISR (&PPP_TX_HISR);

                        /* Check for wrap of ring buffer. */
                        _ppp_tx_dev_ptr_queue_write %= PPP_MAX_TX_QUEUE_PTRS;
                    }
                }
#endif
            }
#endif
        }
          /**************** End Port Specific Section **************/

    } /* END if (vector_found == NU_TRUE)  */

} /* END SDC_LISR(INT vector) */


/****************************************************************************/
/* FUNCTION                                                                 */
/*                                                                          */
/*    SDC_Set_Baud_Rate                                                     */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*    This function sets the UART buad rate.                                */
/*                                                                          */
/* CALLED BY                                                                */
/*                                                                          */
/*    SDC_Init_Port                                                         */
/*                                                                          */
/* CALLS                                                                    */
/*                                                                          */
/*    Serial port macros                                                    */
/*    NU_Local_Control_Interrupts                                           */
/*                                                                          */
/* INPUTS                                                                   */
/*                                                                          */
/*    UNSIGNED      :  The new baud rate.                                   */
/*    SD_PORT *     :  Serial port to set the baud rate.                    */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*    none                                                                  */
/*                                                                          */
/****************************************************************************/
static VOID  SDC_Set_Baud_Rate(UNSIGNED baud_rate, SD_PORT *uart)
{

unsigned short    baud_div;           /* baud rate divisor */

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

    /* Calculate the the Baud Rate Divisor value and write it to UBRDIV     ** 
    ** See page 10-15 in KS32C41000 User's Manual                           */
    baud_div = ( (int)(SYSTEM_CLOCK / 16. / baud_rate + 0.5) -1 );
        
       SD_OUTWORD (uart->base_address + SD_UBRDIV_OFFSET, baud_div);
   
    /**************** End Port Specific Section ****************/

}


/****************************************************************************/
/* FUNCTION                                                                 */
/*                                                                          */
/*    SDC_Get_Char                                                          */
/*                                                                          */
/* DESCRIPTION                                                              */
/*                                                                          */
/*    This function reads the last received character from the UART.        */
/*                                                                          */
/* CALLED BY                                                                */
/*                                                                          */
/*    Application                                                           */
/*                                                                          */
/* CALLS                                                                    */
/*                                                                          */
/*    none                                                                  */
/*                                                                          */
/* INPUTS                                                                   */
/*                                                                          */
/*    SD_PORT *      :   Serial port to get the char from.                  */
/*                                                                          */
/* OUTPUTS                                                                  */
/*                                                                          */
/*    CHAR  :  Character read                                               */
/*                                                                          */
/****************************************************************************/
CHAR  SDC_Get_Char(SD_PORT *uart)
{

CHAR    ch = NU_NULL;

	if (uart->communication_mode == SERIAL_MODE)
	{
	    if ((uart->rx_buffer_status == NU_BUFFER_FULL) ||
            (uart->rx_buffer_status == NU_BUFFER_DATA))
        {
            /* Store the character to be returned */
            ch = uart->rx_buffer[uart->rx_buffer_read++]; 

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

            /* Set the status to reflect removal of the character */
            if (uart->rx_buffer_write == uart->rx_buffer_read)
                uart->rx_buffer_status = NU_BUFFER_EMPTY;
            else
                uart->rx_buffer_status = NU_BUFFER_DATA;
        }

        return (ch);
    } /* endif mode */

#ifdef PPP	
	else if (uart->communication_mode == MDM_TERMINAL_COMMUNICATION || 
             uart->communication_mode == MDM_NETWORK_COMMUNICATION)

⌨️ 快捷键说明

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