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

📄 uart.c

📁 三星mcu S3C4510B评估板的原码
💻 C
字号:
/*************************************************************************/
/*                                                                       */
/* FILE NAME                                      VERSION                */
/*                                                                       */
/* source\uart.c                                   1.0                   */
/*                                                                       */
/* DESCRIPTION                                                           */
/*                                                                       */
/*     UART LIB CODE for S3C4510B0                                       */
/*                                                                       */
/*                                                                       */
/* DATA STRUCTURES                                                       */
/*                                                                       */
/* FUNCTIONS : UART initialization and library                           */
/*                                                                       */
/* DEPENDENCIES                                                          */
/*                                                                       */
/*                                                                       */
/* NAME:    Nicolas Park           					 */
/* The last Modification date:  18-April-2002                            */
/* REMARKS:  Created initial version 1.0                                 */
/*                                                                       */
/*                                Copyright (C) 2002 AIJISYSTEM CO.,LTD  */
/*************************************************************************/

#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "apdialog.h"
#include "s3c4510b0.h"
#include "uart.h"
#include "isr.h"
#include "pollio.h"
#include "sysconf.h"

/* Define references to external structures */
SERIAL_DEV   uart_dev_init;
UART_BUFFER  RxQ[NUM_OF_SERIAL_DEV],TxQ[NUM_OF_SERIAL_DEV]; 


BaudTable U_BaudRate[BAUD_TABLE] = {
/* for 50MHz/2 UART clock */
           9600,  0x00a20,
          19200,  0x00500,
          38400,  0x00280,
          57600,  0x001a0,
          115200, 0x000d0,
          230400, 0x00060,
          460800, 0x00020   // not available 
};


uint32  UART_Initialize()
{

    Disable_Int(nGLOBAL_INT);  /* Global interrupt disabled */

    /*****************************/
    /* Initialize UART channel 0 */
    /*****************************/
    uart_dev_init.com_port  = SERIAL_DEV0;    /* com 0 */
    uart_dev_init.baud_rate = baudrate;
    uart_dev_init.data_mode = (UCON_RXM_INTREQ|UCON_TXM_INTREQ|UCON_RXSTAT_INT);
    uart_dev_init.parity    = ULCON_PMD_NO;   /* No parity */
    uart_dev_init.stop_bits = 0;              /* one bit */
    uart_dev_init.data_bits = ULCON_WL8;      /* 8bits */
    uart_dev_init.clk_sel = 0;                /* internal clock */
    UART_Init(&uart_dev_init);             

    /*****************************/
    /* Initialize UART channel 1 */
    /*****************************/
    uart_dev_init.com_port = SERIAL_DEV1;     /* com 0 */
    UART_Init(&uart_dev_init);

    Enable_Int(nGLOBAL_INT);  /* Global interrupt disabled */

    return(SUCCESS);
}

/***************************/
/* Uart main Init function */
/***************************/
uint32 UART_Init(SERIAL_DEV *s) 
{
     uint32    rUARTBRD;

     /* UART interrupt off */
     UARTRxIntOff(s->com_port);
     UARTTxIntOff(s->com_port);

     /* Initialize UART transmit & receive Queue */
     TxQInit(s->com_port);
     RxQInit(s->com_port);

     /* default baud rate will be set. sysconf.h */

     rUARTBRD = 0x1a0;   //57600bps  or 0x280-38400bps


     if(s->com_port) 
     {   
          /* Interrupt service routine setup */
        SysSetInterrupt(nUART1_TX_INT, Uart1TxLisr);
        SysSetInterrupt(nUART1_RX_ERR_INT, Uart1RxErrLisr);

        UARTLCON1 = s->data_bits|s->stop_bits|s->parity|s->clk_sel;
        UARTCONT1 = s->data_mode;
        UARTBRD1  = rUARTBRD;
     } 
     else 
     {
        /* Interrupt service routine setup */
        SysSetInterrupt(nUART0_TX_INT, Uart0TxLisr);
        SysSetInterrupt(nUART0_RX_ERR_INT, Uart0RxErrLisr);

          /* UART mode, default baud rate setup */
        UARTLCON0 = s->data_bits|s->stop_bits|s->parity|s->clk_sel;
        UARTCONT0 = s->data_mode;
        UARTBRD0  = rUARTBRD; 
     }

     return(SUCCESS);
}


/* Transmit Que initialize */
void TxQInit(uint32 channel)
{
    int i;

    for(i=0; i < MAXEVENT; i++)  
    {
          TxQ[channel].buff[i] = '\0';
    }

    TxQ[channel].wptr = 0;
    TxQ[channel].rptr = 0;
}

/* Receive Que initialize */
void RxQInit(uint32 channel)
{
    int i;

    for(i=0; i < MAXEVENT; i++) 
    {
         RxQ[channel].buff[i] = '\0';
    }

    RxQ[channel].wptr = 0;
    RxQ[channel].rptr = 0;

}


void Uart0TxLisr(void)
{

    if(UARTSTAT0 & USTAT_TXB_EMPTY) 
    {
          if(TxQ[0].rptr == MAXEVENT)
                 TxQ[0].rptr=0; /*loop back*/

          if(TxQ[0].rptr != TxQ[0].wptr) 
          {
             UARTTXH0 = TxQ[0].buff[TxQ[0].rptr++];
          }
    }

    UARTTxIntOff(0);
}


/* Rcv, Error Interrupt Service Routine */
void Uart0RxErrLisr(void)
{
	if(!(UARTSTAT0 & USTAT_ERROR)) 
	{
             if(RxQ[0].wptr+1 != RxQ[0].rptr)
             {
                   RxQ[0].buff[RxQ[0].wptr++] = UARTRXB0;
                   if(RxQ[0].wptr == MAXEVENT)
                           RxQ[0].wptr = 0; /*loop back*/
             }
	}

        UARTRxIntOff(0);
}


void Uart1TxLisr(void)
{
    if(UARTSTAT1 & USTAT_TXB_EMPTY) 
    {
          if(++TxQ[1].rptr == MAXEVENT)
                 TxQ[1].rptr=0; /*loop back*/

          if(TxQ[1].rptr != TxQ[1].wptr) 
          {
             UARTTXH0 = TxQ[1].buff[TxQ[1].rptr];
          }
    }

    UARTTxIntOff(1);
}

void Uart1RxErrLisr(void)
{
	if(!(UARTSTAT1 & USTAT_ERROR)) 
	{
             if(RxQ[1].wptr+1 != RxQ[1].rptr)
             {
                   RxQ[1].buff[RxQ[1].wptr++] = UARTRXB1;
                   if(RxQ[1].wptr == MAXEVENT)
                           RxQ[1].wptr = 0; /*loop back*/
             }
	}

        UARTRxIntOff(1);
}



void UARTTxIntOn(uint32 channel)
{
    if(channel) {
	/* Enable Interrupt */
	Enable_Int(nUART1_TX_INT);
	SetPendingBit(nUART1_TX_INT);
    }
    else {
	/* Enable Interrupt */
	Enable_Int(nUART0_TX_INT);
	SetPendingBit(nUART0_TX_INT);
    }
}

void UARTRxIntOn(uint32 channel)
{
     if(channel) {
	/* Enable Interrupt */

	Enable_Int(nUART1_RX_ERR_INT);
     }
     else {
	/* Enable Interrupt */

	Enable_Int(nUART0_RX_ERR_INT);
     }
}


void UARTTxIntOff(uint32 channel)
{
     if(channel) {
	/* Enable Interrupt */
	Disable_Int(nUART1_TX_INT);
        Clear_PendingBit(nUART1_TX_INT) ;
     }
     else {
	/* Disable Interrupt */
	Disable_Int(nUART0_TX_INT);
        Clear_PendingBit(nUART0_TX_INT) ;
     }
}

void UARTRxIntOff(uint32 channel)
{
     if(channel) {
	/* Disable Interrupt */
	Disable_Int(nUART1_RX_ERR_INT);
      }
     else {
        /* Disable Interrupt */
	Disable_Int(nUART0_RX_ERR_INT);
     }
}




/* Transmit Que write function */
uint32 TxQWr(uint32 channel,uint8 data)
{
        if(TxQ[channel].wptr+1 == TxQ[channel].rptr) 
        {
            return(ERROR); /* ring buffer full state */
        }

        TxQ[channel].buff[TxQ[channel].wptr++] = data;

        if(TxQ[channel].wptr == MAXEVENT) 
        {
            TxQ[channel].wptr=0;
        }
        return(SUCCESS);
}


/* Receive Que read function */
uint8 RxQRd(uint32 channel)
{
     if(RxQ[channel].rptr == MAXEVENT) 
           RxQ[channel].rptr=0; /*loop back*/

     if(RxQ[channel].rptr == RxQ[channel].wptr) 
           return('\0');

     return(RxQ[channel].buff[RxQ[channel].rptr++]);
}


uint8 i_getc(uint32 channel)
{
    UARTRxIntOn(channel);

    return(RxQRd(channel));
}

/* Interrupt get string */
uint32 i_gets(uint32 channel, uint8 *s)
{
     uint32   count;
     uint8    c;

     count = 0; 

     while((c = (uint8)i_getc(channel)) != CR)
     {
            count++;
            *s++ = c;
     }

     *s = (uint8)NULL; 

     return(count);
}



uint32  i_putc(uint32 channel, uint8 ch)
{
    if(U_TX_COMPLETE(channel))               /* check transmit complet */
    {
           if(TxQWr(channel, ch))            /* write data to tx que */
           {
               UARTTxIntOn(channel);         /* Transmit interrupt on */
               while(!U_BUFF_EMPTY(channel)); /* wait for tx buffer empty */

               return(SUCCESS);
           }
    }

    return(ERROR);                 
}

/* UART Interrupt put string */
uint32  i_puts(uint32 channel, uint8 *str)
{    
       uint32     i;      /* Working variable         */
       uint32     sz;    

       sz = strlen((const char *)str); 

        /* Loop to print out all characters.  */
        for(i=0; i < sz ; i++) 
        {
                /* Call i_putc to print each character.  */
                while(!i_putc(channel, *(str + i)));
        }
 
        return(SUCCESS);
}

/* formatted output string */
void i_printf(char *fmt, ...)
{
    va_list argptr;
    char temp_buf[256];

    va_start(argptr, fmt);
    vsprintf(temp_buf, fmt, argptr);
    sputs((uint8 *)temp_buf);
    va_end(argptr);
}



void put_char(uint32 channel,char ch) 
{
    if(channel) {
        WaitXmitter(UARTSTAT1);
        UARTTXH1 = ch;
    }
    else {
        WaitXmitter(UARTSTAT0);
        UARTTXH0 = ch;
    }
}


char get_char(uint32 channel) 
{ 
  char ch;
 
    if(channel) { WaitRcver(UARTSTAT1);
                  ch = UARTRXB1;
    }
    else { WaitRcver(UARTSTAT0);
           ch = UARTRXB0;
    }
    return ch;
}


void put_string(char *ptr ) 
{
    while(*ptr )  
    {
         put_byte(*ptr++ );
    }
}


void dbg_out(char *fmt, ...)
{
    va_list argptr;
    char temp_buf[256];

    va_start(argptr, fmt);
    vsprintf(temp_buf, fmt, argptr);
    put_string(temp_buf);
    va_end(argptr);
}


uint32 gethex2dec(uint32 digitcnt)
{
    uint32   decimal = 0;
    uint8    hex;
    uint32   i;

    put_string("0x");

    hex = get_byte();

    for(i=0;(i<digitcnt)&&(!is_control(hex));i++) {
         hex = to_upper(hex);

         if(is_xdigit(hex)) {

              if(is_digit(hex))  /* '0' - '9' */
                   decimal = decimal * 16 + hex - '0';
              else               /* 'A' - 'F' */
                   decimal = decimal * 16 + 10 + hex - 'A';
         }
         else {
                Print("\r[ERROR] Re-enter %d hexdigit\r",digitcnt);
                i = 0; // clear character counter
                decimal = 0;
                put_string("0x");
         }

         hex = get_byte(); //get next character
    }

    put_byte('\r');
    return(decimal);
}



uint32 get_num(void)
{
	char RcvData[10] ;
	unsigned RcvNum=0 ;
	int i = 0 ;

	while ( (RcvData[i] = get_byte() ) != CR )
	{
		if ( (RcvData[i] >= '0') && (RcvData[i] <= '9') )
			RcvNum=(RcvNum<<4) + (RcvData[i]-'0') ;
		else if ( (RcvData[i] >= 'A') && (RcvData[i] <= 'F') )
			RcvNum=(RcvNum<<4) + (RcvData[i]-'A'+ 10) ;
		else if ( (RcvData[i] >= 'a') && (RcvData[i] <= 'f') )
			RcvNum=(RcvNum<<4) + (RcvData[i]-'a'+ 10) ;
		i++ ;
	}

	return RcvNum ;
}



uint32  get_digit(void)
{
	uint8     RcvData[10] ;
	int       RcvNum=0 ;
	int       RcvDataSize=0 ;
	int       i ;

	while ((RcvData[RcvDataSize] = get_byte()) != CR) RcvDataSize++ ;

	for (i=0;i < RcvDataSize ; i++)
		RcvNum = RcvNum*10 + (RcvData[i]-'0') ; 

	return RcvNum ;
}



uint32 kbd_hit(void) 
{
    uint32 KbdHit ;
    int8   ch ;

    #ifdef PORT1
	if (UARTSTAT1 & USTAT_RCV_READY) 
		{
		KbdHit = 1 ;
        	ch = UARTRXB1;
		}
	else KbdHit = 0 ;
    #else
	if (UARTSTAT0 & USTAT_RCV_READY) 
		{
		KbdHit = 1 ;
        	ch = UARTRXB0;
		}
	else KbdHit = 0 ;
    #endif

    return KbdHit ;
}


uint32 BaudRateVal(uint32 baud)
{
     uint32 index;

     for(index = 0; index < BAUD_TABLE; index++) 
     {
           if(U_BaudRate[index].baud == baud) return(index);          
     }

     return(0); /* baudrate data doesn't in table */
}


uint32 BaudRate(uint32 div)
{
     uint32 index;

     for(index = 0; index < BAUD_TABLE; index++) 
     {
           if(U_BaudRate[index].div == div) return(index);          
     }

     return(0); /* baudrate data doesn't in table */
}

⌨️ 快捷键说明

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