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

📄 uart.c

📁 手机GSM TI 平台 串口 uart 驱动 源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************************* * * UART.C * * This module allows to use the UARTs of chipset 1.5 in interrupt mode for * the Receive side and in polling mode for the Transmit side. * The driver calls a user's function when characters are received. * * (C) Texas Instruments 1999 * ******************************************************************************/#include "chipset.cfg" #include "board.cfg"#include "sys_types.h"#include "uart/traceswitch.h"#include "uart/uart.h"#include <string.h>#include "memif/mem.h"/* * Needed to reset and restart the sleep timer in case of incoming characters. */#if (OP_L1_STANDALONE == 1)  #include "uart/serialswitch_core.h"#else  #include "uart/serialswitch.h" #endifextern SYS_BOOL uart_sleep_timer_enabled;#define BUFFER_SIZE (512) /* In bytes. */#define FIFO_SIZE    (64) /* In bytes. */#define STX                  0x02#define DLE                  0x10/* * TLR is used to program the RX FIFO trigger levels. FCR[7:4] are  not used. */ #define RX_FIFO_TRIGGER_LEVEL (12 << 4)/* * 16750 addresses. Registers accessed when LCR[7] = 0. */#define RHR (0x00) /* Rx buffer register - Read access   */#define THR (0x00) /* Tx holding register - Write access */#define IER (0x01) /* Interrupt enable register          *//* * 16750 addresses. Registers accessed when LCR[7] = 1. */#define DLL (0x00) /* Divisor latch (LSB) */#define DLM (0x01) /* Divisor latch (MSB) *//* * EFR is accessed when LCR[7:0] = 0xBF. */#define EFR (0x02) /* Enhanced feature register *//* * 16750 addresses. Bit 5 of the FCR register is accessed when LCR[7] = 1. */#define IIR  (0x02) /* Interrupt ident. register - Read only */#define FCR  (0x02) /* FIFO control register - Write only    */#define LCR  (0x03) /* Line control register                 */#define MCR  (0x04) /* Modem control register                */#define LSR  (0x05) /* Line status register                  */#define MSR  (0x06) /* Modem status register                 */#define TCR  (0x06) /* Transmission control register         */#define TLR  (0x07) /* Trigger level register                */#define MDR1 (0x08) /* Mode definition register 1            */#define SCR  (0x10) /* Supplementary Control register        */#define SSR  (0x11) /* Supplementary Status register         *//* * Supplementary control register. */#define TX_EMPTY_CTL_IT (0x08)#define RX_CTS_WAKE_UP_ENABLE_BIT (4) /* Use RESET_BIT and SET_BIT macros. *//* * Enhanced feature register. */ #define ENHANCED_FEATURE_BIT (4) /* Use RESET_BIT and SET_BIT macros. *//* * Mode definition register 1. */#define UART_MODE             (0x00)#define SIR_MODE              (0x01)#define UART_MODE_AUTOBAUDING (0x02) /* Reserved in UART/IrDA. */#define RESET_DEFAULT_STATE   (0x07)#define IR_SLEEP_DISABLED     (0x00)#define IR_SLEEP_ENABLED      (0x08)#define SIR_TX_WITHOUT_ACREG2 (0x00) /* Reserved in UART/modem. */#define SIR_TX_WITH_ACREG2    (0x20) /* Reserved in UART/modem. */#define FRAME_LENGTH_METHOD   (0x00) /* Reserved in UART/modem. */#define EOT_BIT_METHOD        (0x80) /* Reserved in UART/modem. *//* * Supplementary Status Register */#define TX_FIFO_FULL (0x01)/* * Interrupt enable register. */#define ERBI  (0x01) /* Enable received data available interrupt            */#define ETBEI (0x02) /* Enable transmitter holding register empty interrupt */#define ELSI  (0x04) /* Enable receiver line status interrupt               */#define EDSSI (0x08) /* Enable modem status interrupt                       */#define IER_SLEEP (0x10)  /* Enable sleep mode                              *//* * Modem control register. */#define MDTR (0x01) /* Data terminal ready. */#define MRTS (0x02) /* Request to send.     */#define TCR_TLR_BIT (6)/* * Line status register. */#define DR   (0x01) /* Data ready                                  */#define OE   (0x02) /* Overrun error                               */#define PE   (0x04) /* Parity error                                */#define FE   (0x08) /* Framing error                               */#define BI   (0x10) /* Break interrupt                             */#define THRE (0x20) /* Transmitter holding register (FIFO empty)   */#define TEMT (0x40) /* Transmitter empty (FIFO and TSR both empty) *//* * Interrupt identification register. * Bit 0 is set to 0 if an IT is pending. * Bits 1 and 2 are used to identify the IT. */#define IIR_BITS_USED  (0x07)#define IT_NOT_PENDING (0x01)#define RX_DATA        (0x04)#define TX_EMPTY       (0x02)#define MODEM_STATUS   (0x00)/* * Line control register. */#define WLS_5         (0x00) /* Word length: 5 bits                    */#define WLS_6         (0x01) /* Word length: 6 bits                    */#define WLS_7         (0x02) /* Word length: 7 bits                    */#define WLS_8         (0x03) /* Word length: 8 bits                    */#define STB           (0x04) /* Number of stop bits: 0: 1, 1: 1,5 or 2 */#define PEN           (0x08) /* Parity enable                          */#define EPS           (0x10) /* Even parity select                     */#define BREAK_CONTROL (0x40) /* Enable a break condition               */#define DLAB          (0x80) /* Divisor latch access bit               */#define DIV_EN_BIT    (7)/* * FIFO control register. */#define FIFO_ENABLE   (0x01)#define RX_FIFO_RESET (0x02)#define TX_FIFO_RESET (0x04)/* * These macros allow to read and write a UART register. */#define READ_UART_REGISTER(UART,REG) \            *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))#define WRITE_UART_REGISTER(UART,REG,VALUE) \            *((volatile SYS_UWORD8 *) ((UART)->base_address + (REG))) = (VALUE)#define RESET_BIT(UART,REG,BIT)    \            (WRITE_UART_REGISTER ( \                 UART, REG, READ_UART_REGISTER (UART, REG) & ~(1 << (BIT))))#define SET_BIT(UART,REG,BIT)      \            (WRITE_UART_REGISTER ( \                 UART, REG, READ_UART_REGISTER (UART, REG) | (1 << (BIT))))/*  * These macros allow to enable or disable the wake-up interrupt. */#define ENABLE_WAKEUP_INTERRUPT(UART)   \    SET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);#define DISABLE_WAKEUP_INTERRUPT(UART)   \    RESET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);/*  * This macro allows to know if the RX buffer is full. It must be called only * from the RX interrupt handler. If it is called from the application, the * rx_in pointer may be updated if a RX interrupt occurs. */#define RX_BUFFER_FULL(UART)                                      \            (((UART)->rx_in == (UART)->rx_out - 1) ||             \             ((UART)->rx_in == (UART)->rx_out + BUFFER_SIZE - 1))/*  * This allows monitor the last 32 inbound buffers gotten from the RX FIFO. *///#define UART_RX_BUFFER_DUMP#ifdef UART_RX_BUFFER_DUMPstruct {    char rx_buffer[(BUFFER_SIZE + 1) << 5];    char *rx_in;    int  errors_count;    int  wrong_interrupt_status;} uart_rx_buffer_dump = {0};#endiftypedef struct s_uart {    SYS_UWORD32 base_address;    /*     * Buffers management.     */        char rx_buffer[BUFFER_SIZE + 1];    char *rx_in;    char *rx_out;    void (*callback_function) (void);    /*     * Errors counters.     */    SYS_UWORD32 framing_error;    SYS_UWORD32 parity_error;    SYS_UWORD32 overrun_error;    /*     * Framing flags.     */    SYS_BOOL dle_detected;    SYS_BOOL inframe;    SYS_BOOL encapsulation_flag;    unsigned char frame_length;} t_uart;static t_uart uart_parameter[NUMBER_OF_TR_UART];static const SYS_UWORD32 base_address[NUMBER_OF_TR_UART] ={#if (((BOARD != 35) && (BOARD != 46)) || (GSM_IDLE_RAM == 0))  MEM_UART_IRDA,#endif  MEM_UART_MODEM#if (CHIPSET == 12)  , MEM_UART_MODEM2#endif};/* * DLL (LSB) and DLH (MSB) registers values using the 13 MHz clock. */static const SYS_UWORD8 dll[] ={      2, /* 406250 baud. */      7, /* 115200 baud. */     14, /*  57600 baud. */     21, /*  38400 baud. */     24, /*  33900 baud. */     28, /*  28800 baud. */     42, /*  19200 baud. */     56, /*  14400 baud. */     84, /*   9600 baud. */    169, /*   4800 baud. */     83, /*   2400 baud. */    165, /*   1200 baud. */     74, /*    600 baud. */    148, /*    300 baud. */     40, /*    150 baud. */     81  /*     75 baud. */};static const SYS_UWORD8 dlh[] ={     0, /* 406250 baud. */     0, /* 115200 baud. */     0, /*  57600 baud. */     0, /*  38400 baud. */     0, /*  33900 baud. */     0, /*  28800 baud. */     0, /*  19200 baud. */     0, /*  14400 baud. */     0, /*   9600 baud. */     0, /*   4800 baud. */     1, /*   2400 baud. */     2, /*   1200 baud. */     5, /*    600 baud. */    10, /*    300 baud. */    21, /*    150 baud. */    42  /*     75 baud. */};/******************************************************************************* * *                              read_rx_fifo *  * Purpose  : Check the bytes written into the RX FIFO. Characters are not *            written in the RX buffer if it is full. The HISR is called if *            enough characters are received. * * Arguments: In : uart: pointer on UART structure. *            Out: none * * Returns  : none * ******************************************************************************/static voidread_rx_fifo (t_uart *uart){    volatile SYS_UWORD8 status;    int                 error_detected;    SYS_UWORD8          char_received;    /*     * Since new characters have been received, the sleep timer is reset then     * restarted preventing the system to enter deep-sleep for a new period of     * time.     */    SER_activate_timer_hisr ();    uart_sleep_timer_enabled = 1;        status = READ_UART_REGISTER (uart, LSR);    while (status & DR) { /* While RX FIFO is not empty... */        error_detected = 0;        char_received = READ_UART_REGISTER (uart, RHR);        /*         * Check if an error (overrun, parity, framing or break) is associated with the         * received data. If there is an error the byte is not copied into the         * RX buffer.         */        if (status & (OE | PE | FE | BI)) {            if (status & PE)                uart->parity_error++;            if (status & FE)                uart->framing_error++;            if (status & OE)                uart->overrun_error++;            error_detected = 1;        }        /*         * If there is no error the byte is copied into the RX         * buffer if it is not full.         */        if (!error_detected && !RX_BUFFER_FULL (uart)) {            *(uart->rx_in++) = char_received;            if (uart->rx_in == &(uart->rx_buffer[0]) + BUFFER_SIZE + 1)                uart->rx_in = &(uart->rx_buffer[0]);#ifdef UART_RX_BUFFER_DUMP            *(uart_rx_buffer_dump.rx_in)++ = char_received;            if (uart_rx_buffer_dump.rx_in == uart_rx_buffer_dump.rx_buffer + sizeof (uart_rx_buffer_dump.rx_buffer))                uart_rx_buffer_dump.rx_in = uart_rx_buffer_dump.rx_buffer;        }        else {            uart_rx_buffer_dump.errors_count++;#endif        }        status = READ_UART_REGISTER (uart, LSR);    }    /*     * Call the user's function.     */    if (uart->callback_function != NULL)        (*(uart->callback_function)) ();}/******************************************************************************* * *                           initialize_uart_sleep *  * Purpose  : Performs basic UART hardware initialization including sleep mode. * * Arguments: In : uart_id : UART id. *            Out: none * * Returns: none * * Warning: Parameters are not verified. * ******************************************************************************/voidinitialize_uart_sleep (T_tr_UartId uart_id){    t_uart     *uart;    int        index;    SYS_UWORD8 dummy;    for (index = 0; index < NUMBER_OF_TR_UART; index++)        uart_parameter[index].base_address = base_address[index];    uart = &(uart_parameter[uart_id]);    /*     * Mask all interrupts causes and disable sleep mode.     */    WRITE_UART_REGISTER (uart, IER, 0x00);    /*     * Reset UART mode configuration.     */    WRITE_UART_REGISTER (uart, MDR1, RESET_DEFAULT_STATE);    /*     * LCR[7:0] = 0xBF to allow to access EFR      * EFR[4] = 1 to allow to program IER[4].     */         WRITE_UART_REGISTER (uart, LCR, 0xBF);    SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);    WRITE_UART_REGISTER (uart, LCR, 0x83);    /*     * Enable FIFO and reset them.     */    WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE   |                                    RX_FIFO_RESET |                                    TX_FIFO_RESET);    /*     * Program the baud generator (dummy 115200).     */    WRITE_UART_REGISTER (uart, DLL, 0x07);    WRITE_UART_REGISTER (uart, DLM, 0x00);    /*     * LCR[7] = 0 to allow to access IER and RHR - normal mode.     */         RESET_BIT (uart, LCR, DIV_EN_BIT);    /*

⌨️ 快捷键说明

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