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

📄 uart_sample.c

📁 oki67500系列arm工程例程源代码
💻 C
字号:
/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2003 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  ML675001 series                                    */
/*     Module Name  :  ML675001 uart sample program                       */
/*     File   Name  :  uart_sample.c                                      */
/*     Revision     :  01.00                                              */
/*     Date         :  2003/08/18                                         */
/*                                                                        */
/**************************************************************************/
#include   "ML675001.h"
#include   "common.h"
#include   "irq.h"
#include   "cache.h"

/* constants */
#define    TRIGGER_LEVEL        14
#define    BUFF_SIZE            256
#define    FIFO_SIZE            16

#define    DLM_BAUD             0x00  /* baud = 115,200 */
#define    DLL_BAUD             0x21  /* baud = 115,200 */
/* DL = (CCLK / Baud Rate) / 16  */
/* === setting baud rate value(33MHz) === */
/*     baud  | DLM_BAUD | DLL_BAUD */
/*     1,200 |   0x06   |   0xB7   */
/*     2,400 |   0x03   |   0x5B   */
/*     4,800 |   0x01   |   0xAE   */
/*     9,600 |   0x00   |   0xD7   */
/*    19,200 |   0x00   |   0x6B   */
/*    38,400 |   0x00   |   0x36   */
/*    57,600 |   0x00   |   0x24   */
/*   115,200 |   0x00   |   0x12   */
/* === setting baud rate value(60MHz) === */
/*     9,600 |   0x01   |   0x86   */
/*    56,000 |   0x00   |   0x42   */
/*   115,200 |   0x00   |   0x21   */


/* functions */
int     main(void);             /* main routine */
void    init_uart(void);        /* initialize UART */
void    uart_handler(void);     /* UART interrupt handler */
void    reg_irq_handler(void);  /* registration of IRQ handler */
void    led_on(UHWORD);         /* LED on */
/* global variables */
volatile  unsigned  char  rw_buff[BUFF_SIZE];  /* ring buffer */
volatile  int  write_pointer;
volatile  int  rec_data_counter;
volatile  int  error_flag;  /* 0:no error, 1:overrun error, 2:parity error,
                               3:framing error, 4:overflow error */
/******************************************************************/
/*  Entry point                                                   */
/*  Function : main                                               */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  0                                           */
/******************************************************************/
int main(void)
{
    unsigned char temporary_area;
    int  read_pointer;
    int  end_flag;             /* escape code flag */
    int  trans_count;


    init_cache();  /* Initialize CACHE memory */
    cache_on(CACHE_BANK0);  /* Bank0 : Cache enable */

    init_irq();                /* initialize IRQ */

    reg_irq_handler();         /* registration of IRQ handler */

    /* setting of PORT */
    set_hbit(GPCTL,0x0001);    /* selection of a secondary function (GPCTL 0bit)*/

    init_uart();               /* initialize UART */

    init_led();    /* initialize LED */

    led_on(LED_START_PATTERN); /* turn on upper square LED */
    
    /* initialize variables */
    end_flag    =  0;
    trans_count =  0;
    error_flag  =  0;
    write_pointer  =  0;
    read_pointer   =  0;
    rec_data_counter  = 0;

    irq_en();                   /* enable IRQ */

    while (end_flag == 0){

        /* transmission FIFO empty ? */
        while ((get_value(UARTLSR) & UARTLSR_THRE) != UARTLSR_THRE)
            ;

        trans_count = 0;

        do {
            if (error_flag != 0){  /* error ? */

                /* transmission FIFO empty ? */
                while ((get_value(UARTLSR) & UARTLSR_THRE) != UARTLSR_THRE)
                    ;

                switch (error_flag){
                    case 1 :    /* overrun error */
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line feed */
                            put_value(UARTTHR,'O');   /* overrun error */
                            put_value(UARTTHR,'E');
                            put_value(UARTTHR,'E');
                            put_value(UARTTHR,'R');
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line feed */
                            break;

                    case 2 :    /* parity error */
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line Feed */
                            put_value(UARTTHR,'P');   /* parity error */
                            put_value(UARTTHR,'E');
                            put_value(UARTTHR,'E');
                            put_value(UARTTHR,'R');
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line feed */
                            break;

                    case 3 :    /* framing error */
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line feed */
                            put_value(UARTTHR,'F');   /* framing error */
                            put_value(UARTTHR,'E');
                            put_value(UARTTHR,'E');
                            put_value(UARTTHR,'R');
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line feed */
                            break;

                    case 4 :    /* overflow error */
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* fine feed */
                            put_value(UARTTHR,'O');   /* overflow error */
                            put_value(UARTTHR,'V');
                            put_value(UARTTHR,'F');
                            put_value(UARTTHR,'D');
                            put_value(UARTTHR,0x0D);  /* carriage return */
                            put_value(UARTTHR,0x0A);  /* line feed */
                            break;

                    default : break;
                }
                error_flag = 0;
            }

            /* exist data ? */
            else if ( rec_data_counter > 0){

                temporary_area = rw_buff[read_pointer];

                /* update read pointer */
                read_pointer++;
                if (read_pointer >= BUFF_SIZE){ 
                    read_pointer = 0;
                }

                irq_dis();           /* disable IRQ */
                rec_data_counter--;            
                irq_en();            /* enable IRQ */
                    
                /* Esc */
                if (temporary_area == 0x1B){
                    end_flag = 1;
                    break;
                }

                /* Enter */
                else if (temporary_area == 0x0D){
                    put_value(UARTTHR,0x0D);    /* carriage return */
                    put_value(UARTTHR,0x0A);    /* line feed */
                    trans_count += 2;
                }
                  
                /* printable character */
                else if (0x20 <= temporary_area && temporary_area<= 0x7E){
                    put_value(UARTTHR,temporary_area);
                    trans_count++;
                }
                
                else
                    continue;
            }
        }while (trans_count < (FIFO_SIZE - 1)); 
    }                        

    put_value(UARTIER,0x0);          /* disable UART interrupt */
    irq_dis();                       /* disable IRQ */
    
    led_on(LED_NORMAL_END_PATTERN);       /* turn on lower square LED */
    
    return 0;
}

/******************************************************************/
/*  Initialize UART                                               */
/*  Function : init_uart                                          */
/*      Parameters                                                */
/*          Input  :  Nothing                                     */
/*          Output :  Nothing                                     */
/******************************************************************/
void init_uart()
{

    /***********************************************************
        The value of a baud rate is set as 115,200 bps
    ***********************************************************/
    set_bit(UARTLCR,UARTLCR_DLAB);
    
    put_value(UARTDLL,DLL_BAUD);   /* DLL of divider latch register */
    put_value(UARTDLM,DLM_BAUD);   /* DLM of divider latch register */

    clr_bit(UARTLCR,UARTLCR_DLAB);

    /***********************************************************
        Setup of FIFO
        FCR_FE       corresponds to transmit/receive FIFO enable
        FCR_RFCRL    corresponds to receiving FIFO clear
        FCR_TFCLR    corresponds to transmission FIFO clear
        FCR_RF_LV14 corresponds to trigger level size :14
    ***********************************************************/
    put_value(UARTFCR, UARTFCR_FE | UARTFCR_RFCLR | UARTFCR_TFCLR | UARTFCR_RFLV14);

    /***********************************************************
        Setup of LCR
        LCR_LN8   corresponds to character length :8
        LCR_STB1S corresponds to stop bit   : 1
        LCR_PDIS  corresponds to parity bit : none
    ***********************************************************/
    put_value(UARTLCR,UARTLCR_LEN8 | UARTLCR_STB1 | UARTLCR_PDIS);

    /*******************************************************
        A setup of a modem control register
            == This function is not used ==
    *******************************************************/
    put_value(UARTMCR,0x0);

    /*******************************************************
        Enable uart interrupt 
        IER_ERBF  corresponds  to receiving data effective
        IER_ETBEF corresponds  to transmission data empty
        IER_ELSI  corresponds  to receiving line status
    *******************************************************/
    put_value(UARTIER,UARTIER_ERBF | UARTIER_ETBEF | UARTIER_ELSI);

    return;
}

/********************************************************************/
/*  UART Interruption processing                                    */
/*  Function : uart_handler                                         */
/*        Parameters                                                */
/*            Input  :  Nothing                                     */
/*            Output :  Nothing                                     */
/********************************************************************/
void uart_handler()
{
    int  i;
    int  uart_interrupt_kind;
    int  error_status;
    unsigned  char  tmp;

    uart_interrupt_kind =  get_value(UARTIIR);
    uart_interrupt_kind &= 0x0f;

    switch (uart_interrupt_kind){

        case UARTIIR_LINE :            /* receiving line status interrupt */

            tmp = get_value(UARTRBR);       /* read error data */

            error_status = get_value(UARTLSR);
                             
            if(error_status & UARTLSR_OE){      /* overrun error ? */
                error_flag = 1;
            }

            else if(error_status & UARTLSR_PE){ /* parity error ? */
                error_flag = 2;
            }

            else if(error_status & UARTLSR_FE){ /* framing error ? */
                error_flag = 3;
            }
            
            else
                ;
            
            break;


        case  UARTIIR_RCV : /* receiving data effective interrupt */

            for(i = 0; i < TRIGGER_LEVEL; i++){

                if ( rec_data_counter > BUFF_SIZE ){   /* overflow error ? */
                    /* clear receiving FIFO */
                    put_value(UARTFCR,UARTFCR_FE | UARTFCR_RFCLR | UARTFCR_RFLV14);
                    error_flag = 4;
                    break;
                }

                rw_buff[write_pointer] = get_value(UARTRBR);
                rec_data_counter++;
                
                /* update write pointer */
                write_pointer++;
                if(write_pointer >= BUFF_SIZE){
                    write_pointer = 0;
                }
            }
            break;


        case UARTIIR_TO : /* time out interrupt */

            /* exist receiving data? */
            while ((get_value(UARTLSR) & UARTLSR_DR) == UARTLSR_DR){

                if ( rec_data_counter > BUFF_SIZE ){    /* overflow error ? */
                   /* clear receiving FIFO */
                   put_value(UARTFCR,UARTFCR_FE | UARTFCR_RFCLR | UARTFCR_RFLV14); 
                   error_flag = 4;
                   break;
                }
                
                rw_buff[write_pointer] = get_value(UARTRBR);
                rec_data_counter++;
                
                /* update write pointer */
                write_pointer++;
                if (write_pointer >= BUFF_SIZE){
                    write_pointer = 0;
                }
            }
            break;


        case UARTIIR_TRA : /* transmission empty interrupt */
            break;


        default   : break;
    }
}

/****************************************************************************/
/*  Registration of IRQ Handler                                             */
/*  Function : reg_irq_handler                                              */
/*      Parameters                                                          */
/*          Input   :   Nothing                                             */
/*          Output  :   Nothing                                             */
/*  Note : Initialize IRQ needs to be performed before this process.        */
/****************************************************************************/
void reg_irq_handler(void)
{
    /* register IRQ handler into IRQ handler table */
    IRQ_HANDLER_TABLE[INT_UART] = uart_handler;  /* UART interrupt number 9 */

    set_wbit(ILC1, ILC1_ILR9 & ILC1_INT_LV7 ); /* interrupt level of
                       ||          ||             IRQ number 9 is set as 7
                   IRQ number   interrupt level  */
    return;
}

⌨️ 快捷键说明

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