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

📄 uart.c

📁 手机GSM TI 平台 串口 uart 驱动 源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
     * Select UART mode.     */         WRITE_UART_REGISTER (uart, MDR1, UART_MODE);    /*     * Clear Interrupt and check that Rx FIFO is empty.     */    dummy = READ_UART_REGISTER (uart, IIR);    while (READ_UART_REGISTER (uart, LSR) & DR)        dummy = READ_UART_REGISTER (uart, RHR);#if ((CHIPSET != 5) && (CHIPSET != 6))    /*     * Enable sleep mode.     */    WRITE_UART_REGISTER (uart, IER, IER_SLEEP);#endif}/******************************************************************************* * *                               UA_Init *  * Purpose  : Initializes the module and the UART. * * Arguments: In : uart_id : UART id. *                 baudrate: baud rate selected. *                 callback: user's function called characters are received. *            Out: none * * Returns: none * * Warning: Parameters are not verified. * ******************************************************************************/voidUA_Init (T_tr_UartId uart_id,         T_tr_Baudrate baudrate,         void (callback_function (void))){    t_uart *uart;    int    index;#ifdef UART_RX_BUFFER_DUMP    uart_rx_buffer_dump.rx_in = uart_rx_buffer_dump.rx_buffer;#endif    for (index = 0; index < NUMBER_OF_TR_UART; index++)        uart_parameter[index].base_address = base_address[index];            uart = &(uart_parameter[uart_id]);    uart->rx_in  = &(uart->rx_buffer[0]);    uart->rx_out = &(uart->rx_buffer[0]);    uart->callback_function = callback_function;    uart->framing_error = 0;    uart->parity_error  = 0;    uart->overrun_error = 0;    uart->dle_detected = 0;    uart->inframe = 0;    uart->encapsulation_flag = 0;    uart->frame_length = 0;    /*     * 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   |                                     IR_SLEEP_DISABLED     |                                     SIR_TX_WITHOUT_ACREG2 |                                     FRAME_LENGTH_METHOD);    /*     * FIFO configuration.     * EFR[4] = 1 to allow to program FCR[5:4] and MCR[7:5].     */         WRITE_UART_REGISTER (uart, LCR, 0xBF);    SET_BIT (uart, EFR, ENHANCED_FEATURE_BIT);    /*     * Select the word length, the number of stop bits , the parity and set     * LCR[7] (DLAB) to allow to program FCR, DLL and DLM.     */    WRITE_UART_REGISTER (uart, LCR, WLS_8 | DLAB);    /*     * Program the trigger levels.     * MCR[6] must be set to 1.     */    SET_BIT (uart, MCR, TCR_TLR_BIT);    WRITE_UART_REGISTER (uart, TCR, 0x0F);    WRITE_UART_REGISTER (        uart, TLR, RX_FIFO_TRIGGER_LEVEL);        /*     * Program the FIFO control register. Bit 0 must be set when other FCR bits     * are written to or they are not programmed.     * FCR is a write-only register. It will not be modified.     */    WRITE_UART_REGISTER (uart, FCR, FIFO_ENABLE   |                                    RX_FIFO_RESET | /* self cleared */                                    TX_FIFO_RESET); /* self cleared */    /*     * Program the baud generator.     */    WRITE_UART_REGISTER (uart, DLL, dll[baudrate]);    WRITE_UART_REGISTER (uart, DLM, dlh[baudrate]);        /*     * Reset LCR[7] (DLAB) to have access to the RBR, THR and IER registers.     */    WRITE_UART_REGISTER (uart, LCR, READ_UART_REGISTER (uart, LCR) & ~DLAB);    /*     * Select UART mode.     */         WRITE_UART_REGISTER (uart, MDR1, UART_MODE             |                                     IR_SLEEP_DISABLED     |                                     SIR_TX_WITHOUT_ACREG2 |                                     FRAME_LENGTH_METHOD);#if ((CHIPSET == 5) || (CHIPSET == 6))    /*     * Unmask RX interrupt     */    WRITE_UART_REGISTER (uart, IER, ERBI);#else    /*     * Unmask RX interrupt and allow sleep mode.     */    WRITE_UART_REGISTER (uart, IER, ERBI | IER_SLEEP);#endif}/******************************************************************************* * *                           UA_ReadNChars *  * Purpose  : Reads N characters from the RX buffer. * * Arguments: In : uart_id      : UART id. *                 buffer       : buffer address where the characters are *                                copied. *                 chars_to_read: number of characters to read. *            Out: none * * Returns  : The number of characters read. * * Warning: Parameters are not verified. * ******************************************************************************/SYS_UWORD32UA_ReadNChars (T_tr_UartId uart_id,               char *buffer,               SYS_UWORD32 chars_to_read){    SYS_UWORD32 chars_in_rx_buffer;    SYS_UWORD32 chars_to_copy;    SYS_UWORD32 chars_written;    char        *rx_in;    t_uart      *uart;    uart = &(uart_parameter[uart_id]);    /*     * A copy of the rx_in pointer is used because it may be updated by     * the interrupt handler.     * Get the number of bytes available in the RX buffer.     */    rx_in = uart->rx_in;    if (uart->rx_out <= rx_in)        chars_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out);    else        chars_in_rx_buffer = (SYS_UWORD32) (rx_in - uart->rx_out + BUFFER_SIZE + 1);    /*     * No more bytes than those received may be written in the output buffer.     */    if (chars_in_rx_buffer >= chars_to_read)        chars_to_copy = chars_to_read;    else        chars_to_copy = chars_in_rx_buffer;    chars_written = chars_to_copy;    /*     * Write the received bytes in the output buffer.     */    while (chars_to_copy) {        *(buffer++) = *(uart->rx_out++);        chars_to_copy--;        if (uart->rx_out == &(uart->rx_buffer[0]) + BUFFER_SIZE + 1)            uart->rx_out = &(uart->rx_buffer[0]);    }    return (chars_written);}/******************************************************************************* * *                           UA_ReadNBytes *  * Purpose  : Reads and destuff N bytes from the RX buffer. * * Arguments: In : uart_id      : UART id. *                 buffer       : buffer address where the bytes are copied. *                 chars_to_read: number of bytes to read. *            Out: eof_detected : indicates if an EOF has been detected. Possible *                                values are: *                                 - 0: EOF not detected, *                                 - 1: EOF detected and no more bytes left, *                                 - 2: EOF not detected and more bytes left. *                                      Users must invoke this function one more *                                      time in order to get those remaining *                                      bytes, *                                 - 3: EOF detected and more bytes left. Users *                                      must invoke this function one more time *                                      in order to get those remaining bytes. * * Returns  : The number of bytes read. * * Warning: Parameters are not verified. * ******************************************************************************/SYS_UWORD32UA_ReadNBytes (T_tr_UartId uart_id,               char *buffer_p,               SYS_UWORD32 bytes_to_read,               SYS_BOOL *eof_detected_p){    SYS_UWORD32 bytes_written;    SYS_UWORD32 bytes_in_rx_buffer;    SYS_UWORD32 bytes_to_process;    t_uart      *uart_p;    char        *rx_in_p;    bytes_written = 0;    uart_p = &(uart_parameter[uart_id]);    /*     * A copy of the rx_in pointer is used because it may be updated by     * the interrupt handler.     * Get the number of bytes available in the RX buffer.    */    rx_in_p = uart_p->rx_in;    if (uart_p->rx_out <= rx_in_p)        bytes_in_rx_buffer = (SYS_UWORD32) (rx_in_p - uart_p->rx_out);    else        bytes_in_rx_buffer = (SYS_UWORD32) (rx_in_p - uart_p->rx_out + BUFFER_SIZE + 1);    /*     * No more bytes than those received may be processed and then written     * in the output buffer.     */    if (bytes_in_rx_buffer > bytes_to_read) {        bytes_to_process = bytes_to_read;        /*         * More bytes left. Users must invoke this function one more time         * in order to get those remaining bytes.         */        *eof_detected_p  = 2;    }    else {        bytes_to_process = bytes_in_rx_buffer;        /*         * No more bytes left.         */        *eof_detected_p  = 0;    }    /*     * Perform the byte destuffing and then write the "valid" received bytes in     * the output buffer.     */    while ((bytes_to_process) && !(*eof_detected_p & 0x01)) {        switch (*(uart_p->rx_out)) {            /*             * Current byte is DLE.             */            case DLE:                if (!uart_p->dle_detected) {                    /*                     * No DLE previously detected =>                      * Skip the current byte and set the flag.                     */                    uart_p->dle_detected = 1;                    uart_p->rx_out++;                }                else { /* if (uart_p->dle_detected) */                    if (uart_p->inframe) {                        /*                         * DLE previously detected AND currently inside of a frame =>                         * Copy the current byte in the output buffer, reset the flag                         * and increase the frame length.                         */                        uart_p->dle_detected = 0;                        uart_p->frame_length++;                        *(buffer_p++) = *(uart_p->rx_out++);                        bytes_written++;                    }                    else { /* if (!uart_p->inframe) */                        /*                         * DLE previously detected AND currently outside of a frame =>                         * Skip the current byte.                         */                        uart_p->rx_out++;                    }                }            break; /* case DLE */            /*             * Current byte is STX.             */            case STX:                if ((!uart_p->dle_detected) && (uart_p->inframe)) {                    /*                     * No DLE previously detected AND currently inside of a frame.                     */                    if (uart_p->frame_length) {                        /*                         * Frame length is not zero (End of Frame) =>                          * Skip the current byte and set the flags (EOF).                         */                        uart_p->inframe = 0;                        uart_p->frame_length = 0;                        uart_p->rx_out++;                        /*                         * More bytes left.                         */                        if ((*eof_detected_p == 0) && (bytes_to_process))                            *eof_detected_p = 2;                        /*                         * EOF detected.                         */                        (*eof_detected_p)++;                    }                    else { /* if (!uart_p->frame_length) */                        /*                         * Frame length is zero (STX followed by another STX =                         * Synchro lost but start of a new frame) =>                         * Skip the current byte and keep the flag set.                         */                        uart_p->rx_out++;                    }                }                else if ((!uart_p->dle_detected) && (!uart_p->inframe)) {                    /*                     * No DLE previously detected AND currently outside of a                     * frame (Start of Frame) =>                     * Skip the current byte and set the flag.                     */                    uart_p->inframe = 1;                    uart_p->rx_out++;                }                else if ((uart_p->dle_detected) && (uart_p->inframe)) {                    /*                     * DLE previously detected AND currently inside of a frame =>                     * Copy the current byte in the output buffer, reset the flag                     * and increase the frame length.                     */                    uart_p->dle_detected = 0;                    uart_p->frame_length++;                    *(buffer_p++) = *(uart_p->rx_out++);                    bytes_written++;                }                else if ((uart_p->dle_detected) && (!uart_p->inframe)) {                    /*                     * DLE previously detected AND currently outside of a frame =>                     * Skip the current byte and reset the flag.                     */                    uart_p->dle_detected = 0;                    uart_p->rx_out++;                }            break; /* case STX */            /*             * Current byte is neither DLE nor STX.             */            default:                if (uart_p->inframe) {                    /*                     * Currently inside of a frame =>                     * Copy the current byte in the output buffer and increase                     * the frame length.                     */                    uart_p->frame_length++;                    *(buffer_p++) = *(uart_p->rx_out++);                    bytes_written++;                }                else { /* if (!uart_p->inframe) */                    /*                     * Currently outside of a frame =>                     * Skip the current byte.                     */                    uart_p->rx_out++;                }            break; /* default */        }        if (uart_p->rx_out == &(uart_p->rx_buffer[0]) + BUFFER_SIZE + 1)            uart_p->rx_out = &(uart_p->rx_buffer[0]);        bytes_to_process--;    }    return (bytes_written);}/*******************************************************************************

⌨️ 快捷键说明

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