hal_uart.c

来自「最新版IAR FOR ARM(EWARM)5.11中的代码例子」· C语言 代码 · 共 282 行

C
282
字号

/**************************************************************************/
/*                                                                        */
/*     Copyright (C) 2006 Oki Electric Industry Co., LTD.                 */
/*                                                                        */
/*     System Name  :  uPLAT7D series                                     */
/*     Module Name  :  uPLAT7D uart HAL program                           */
/*     File   Name  :  hal_uart.c                                         */
/*     Revision     :  01.00                                              */
/*     Date         :  2005/12/15 initial version                         */
/*                                                                        */
/**************************************************************************/

#include "common.h"
#if defined(__arm)
#include "ml675050.h"
#else
#include "ml675050sim.h"
#endif
#include "hal_common.h"
#include "hal_interrupt.h"
#include "hal_uart.h"

/******************************/
/*     Private defines        */
/******************************/
/*--------- variable ---------*/
static volatile int16_t trans_status;                /* transmit status */
static volatile uint8_t uart_rw_buf[UART_BUF_SIZE];  /* ring buffer */
static volatile uint16_t uart_rw_in; 
static volatile uint16_t uart_rw_out;  
static volatile uint16_t uart_rw_size; 

/*--------- function ---------*/
static void _uart_handler(void);        /* The handler of system timer. */

/******************************/
/*     Public defines         */
/******************************/
FP uart_handler = _uart_handler;


/************************************************************************/
/*                                                                      */
/*  Function Name   : HalUart_UartInit                                  */
/*  Input           : struct uPLAT_UartParam *param                     */
/*  Output          : int16_t HAL_OK(1)                                 */
/*                            HAL_PARAM_ERROR(-2)                       */
/*                                                                      */
/*  Note : Initialize uart.                                             */
/*                                                                      */
/************************************************************************/
int16_t HalUart_UartInit(struct uPLAT_UartParam *param)
{
    int16_t rtnVal = HAL_OK;
    uint32_t uartdll0=0;     /* UARTDLL0 register tmp buffer */

    if (param->baudrate == 0) {
        rtnVal = HAL_PARAM_ERROR;
    }

    if(rtnVal == HAL_OK){
        trans_status = HAL_OK;

        /* H/W control */
        OkiCLib_set8bit(UARTLCR0, UARTLCR_DLAB);       /* set DLAB */
        
        uartdll0 = CLKUART / (16 * param->baudrate);
        /* set baudrate (115200bps) */
        OkiCLib_write8(UARTDLL0, (uint8_t)(uartdll0 & 0x000000FF));
        OkiCLib_write8(UARTDLM0, (uint8_t)((uartdll0 >> 8) & 0x000000FF));
        OkiCLib_write8(UARTDLH0, (uint8_t)((uartdll0 >> 16) & 0x000000FF));
        
        OkiCLib_clr8bit(UARTLCR0, UARTLCR_DLAB);       /* clear DLAB */

        OkiCLib_write8(UARTLCR0, (UARTLCR_LEN8         /* data length : 8bit */
                                  | UARTLCR_STB1));    /* stop bit : 1 */

        OkiCLib_write8(UARTFCR0, (UARTFCR0_FIFOE       /* FIFO enable */
                                  | UARTFCR0_RFR       /* Receiver FIFO reset */
                                  | UARTFCR0_TFR       /* Transmitter FIFO reset */
                                  | UARTFCR_RFLV4));   /* RCVR FIFO interrupt trigger level : 4byte */

        OkiCLib_write8(UARTIER0, (UARTIER0_ERBFI       /* Enable Received Data Available Interruption */
                                  | UARTIER0_ETBEI     /* Enable Transmitter Holding Register Empty Interruption */
                                  | UARTIER0_ELSI));   /* Enable Receiver Line Status Interruption */
        OkiCLib_write8(UARTMCR0, 0x0);
    }

    return rtnVal;
}


/************************************************************************/
/*                                                                      */
/*  Function Name   : HalUart_UartRxData                                */
/*  Input           : int8_t *buff                                      */
/*  Output          : int16_t HAL_OK(1)                                 */
/*                            HAL_PARAM_ERROR(-2)                       */
/*                                                                      */
/*  Note :  uart receive data.                                          */
/*                                                                      */
/************************************************************************/
int16_t HalUart_UartRxData(int8_t *buff)
{
    int16_t rtnVal = HAL_OK;
    int16_t i;

    /* Disable uart interrupt. */
    OkiCLib_write8(UARTIER0, 0x0);

    for (i = 0; i < UART_FIFO_MAX; i++) {
        if (uart_rw_size > 0) {
            buff[i] = (int8_t)uart_rw_buf[uart_rw_out];
            uart_rw_out++;
            uart_rw_size--;
            if (uart_rw_out >= UART_BUF_SIZE) {
                uart_rw_out = 0;
            }
        }
        else {
            buff[i] = '\0';
        }
    }
    buff[UART_FIFO_MAX] = '\0';

 /* Enable uart interrupt. */
    OkiCLib_write8(UARTIER0, (UARTIER0_ERBFI       /* Enable Received Data Available Interruption */
                                | UARTIER0_ETBEI     /* Enable Transmitter Holding Register Empty Interruption */
                                | UARTIER0_ELSI));   /* Enable Receiver Line Status Interruption */

    return rtnVal;
}

/************************************************************************/
/*                                                                      */
/*  Function Name   : HalUart_UartTxData                                */
/*  Input           : int8_t *buff                                      */
/*  Output          : int16_t HAL_OK(1)                                 */
/*                            HAL_PARAM_ERROR(-2)                       */
/*                                                                      */
/*  Note :  uart transmit data.                                         */
/*                                                                      */
/************************************************************************/
int16_t HalUart_UartTxData(int8_t *buff) 
{
    int16_t rtnVal = HAL_OK;

    while ((OkiCLib_read8(UARTLSR0) & UARTLSR1_THRE) != UARTLSR1_THRE) {
        ;
    }
    OkiCLib_write8(UARTTHR0, (uint8_t)(*buff));

    return rtnVal;
}


/************************************************************************/
/*                                                                      */
/*  Function Name   : HalUart_UartReadStatus                            */
/*  Input           : uint16_t *status                                  */
/*  Output          : int16_t HAL_OK(1)                                 */
/*                            HAL_PARAM_ERROR(-2)                       */
/*                                                                      */
/*  Note :  uart read status.                                           */
/*                                                                      */
/************************************************************************/
int16_t HalUart_UartReadStatus( int16_t *status )
{
    int16_t rtnVal = HAL_OK;
    
    if (status == NULL) {
        rtnVal = HAL_PARAM_ERROR;
    }
    else {
        *status = trans_status;    /* State of TxD/RxD result  */
    }

    return rtnVal;
}

/************************************************************************/
/*                                                                      */
/*  Function Name   : _uart_handler                                     */
/*  Input           : void                                              */
/*  Output          : void                                              */
/*                                                                      */
/*  Note :  uart handler.                                               */
/*                                                                      */
/************************************************************************/
static void _uart_handler(void)
{
    uint16_t i;
    uint8_t uartiir0 = (uint8_t)(OkiCLib_read8(UARTIIR0) & UART_IIR0_MASK);  
    uint8_t uartlsr0 = OkiCLib_read8(UARTLSR0);
    uint8_t rx_temp;

    /* Received data error interrupt. */
    if (uartiir0 == UARTIIR0_INTID4) {

        /* Clear interrupt state. */
        rx_temp = OkiCLib_read8(UARTRBR0);

        trans_status = 0;
        /* overrun error */
        if ((uartlsr0 & UARTLSR0_OE) == UARTLSR0_OE) {
            trans_status |= HAL_UART_OVR_ERROR;
        }
        /* parity error */
        if ((uartlsr0 & UARTLSR0_PE) == UARTLSR0_PE) {
            trans_status |= HAL_UART_PRT_ERROR;
        }
        /* framing error */
        if ((uartlsr0 & UARTLSR0_FE) == UARTLSR0_FE) {
            trans_status |= HAL_UART_FRM_ERROR;
        }
        if (trans_status == 0) {
            trans_status = HAL_OK;
        }

        /*  Notice receive completion interruption */
        CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_RXD);
    }

    /* received data interrupt */
    if (uartiir0 == UARTIIR0_INTID3) {
        for (i = 0; (i < UART_FIFO_MAX) && (trans_status == HAL_OK); i++) {
            if (uart_rw_size > UART_BUF_SIZE) {
                /* Receiver FIFO reset */
                OkiCLib_set8bit(UARTFCR0, UARTFCR0_RFR);
                /* overflow error */
                if (trans_status == HAL_OK) {
                    trans_status = 0;
                }
                trans_status |= HAL_UART_OVF_ERROR;
            }
            else {
                uart_rw_buf[uart_rw_in] = OkiCLib_read8(UARTRBR0);
                uart_rw_size++;
                uart_rw_in++;
                if (uart_rw_in >= UART_BUF_SIZE) {
                    uart_rw_in = 0;
                }
            }
        }
        /*  Notice receive completion interruption */
        CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_RXD);
    }

    /* Time out interrupt */
    else if (uartiir0 == (UARTIIR0_TOI | UARTIIR0_INTID3)) {
        while (((OkiCLib_read8(UARTLSR0) & UARTLSR1_DR) == UARTLSR1_DR)
               && (trans_status == HAL_OK)) {
            if (uart_rw_size > UART_BUF_SIZE) {
                /* Receiver FIFO reset */
                OkiCLib_set8bit(UARTFCR0, UARTFCR0_RFR);
                /* overflow error */
                if (trans_status == HAL_OK) {
                    trans_status = 0;
                }
                trans_status |= HAL_UART_OVF_ERROR;
            }
            else {
                uart_rw_buf[uart_rw_in] = OkiCLib_read8(UARTRBR0);
                uart_rw_size++;
                uart_rw_in++;
                if (uart_rw_in >= UART_BUF_SIZE) {
                    uart_rw_in = 0;
                }
            }
        }
        /*  Notice receive completion interruption */
        CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_TOI);
    }

    /* Send data interrupt */
    if (uartiir0 == UARTIIR0_INTID2) {
        /* Notice transmit completion interruption */
        CALL_BACK_TABLE[INT_UART0](CALLBACK_STATE_UART_TXD);
    }
}

⌨️ 快捷键说明

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