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

📄 uartfax.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
build_rx_fifo_array (t_uart *uart)
{
    SYS_UWORD8  status;
    SYS_UWORD8  *first_byte;
    SYS_UWORD8  *current_byte;
    SYS_UWORD16 *bytes_in_rx_buffer;
    SYS_UWORD16 bytes_received;

    bytes_received = 0;
    
    /*
     * Switch to the other buffer.
     */
     
    first_byte = uart->rx_buffer_used_by_rx_lisr;
    if (first_byte == &(uart->rx_fifo_byte_1[0])) {
    
        first_byte = &(uart->rx_fifo_byte_2[0]);
        bytes_in_rx_buffer = &(uart->bytes_in_rx_buffer_2);
    
    } else {
    
        first_byte = &(uart->rx_fifo_byte_1[0]);
        bytes_in_rx_buffer = &(uart->bytes_in_rx_buffer_1);
    }

    current_byte = first_byte;
    uart->rx_buffer_used_by_rx_lisr = first_byte;
    
    status = READ_UART_REGISTER (uart, LSR);

    /*
     * Build an array with the bytes contained in the RX FIFO.
     */

    while (status & DR) { /* While RX FIFO is not empty... */

        *current_byte = READ_UART_REGISTER (uart, RHR);

        /*
         * Check if a parity error or a framing error is associated with the
         * received data. If there is an error the byte is not copied into the
         * bytes array.
         */

        if (status & BYTE_ERROR) {

            if (status & OE)
                uart->overrun_error++;

            if (status & PE)
                uart->parity_error++;

            if (status & FE)
                uart->framing_error++;

            /*
             * Check break detection.
             */

            if (status & BI) {
            
                uart->break_received = 1;
                *(uart->state) |=
                    ((1 << BRK) | (MINIMAL_BREAK_LENGTH << BRKLEN));
            }

        } else /* No error */ 
            current_byte++;

        status = READ_UART_REGISTER (uart, LSR);
    }

    bytes_received = (SYS_UWORD16) (current_byte - first_byte);
    *bytes_in_rx_buffer = bytes_received;

    /*
     * Re-switch to the other buffer if no valid character has been received.
     */

    if (!bytes_received) {
         
        if (uart->rx_buffer_used_by_rx_lisr == &(uart->rx_fifo_byte_1[0]))
            uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_2[0]);
        
        else
            uart->rx_buffer_used_by_rx_lisr = &(uart->rx_fifo_byte_1[0]);
    }

    if (bytes_received > uart->max_rx_fifo_level)
        uart->max_rx_fifo_level = bytes_received;
        
    return (bytes_received);
}

/*******************************************************************************
 *
 *                              empty_rx_fifo
 * 
 * Purpose  : Read the RX FIFO.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : none
 *
 ******************************************************************************/

static void
empty_rx_fifo (t_uart *uart)
{
    SYS_UWORD16 bytes_in_rx_fifo;
    volatile SYS_UWORD8 dummy_byte;

    bytes_in_rx_fifo = 0;

    while (READ_UART_REGISTER (uart, LSR) & DR) {

        dummy_byte = READ_UART_REGISTER (uart, RHR);
        bytes_in_rx_fifo++;
    }

    if (bytes_in_rx_fifo > uart->max_rx_fifo_level)
        uart->max_rx_fifo_level = bytes_in_rx_fifo;
}

/*******************************************************************************
 *
 *                          hisr_execute_rx_operations
 * 
 * Purpose  : If an escape sequence is detected or if a break in the detection
 *            has occured RX FIFO bytes are written in the RX buffer. 
 *            If the software flow control is used bytes are analyzed to know
 *            if a XON or a XOFF character is received to stop or start the
 *            transmitter. 
 *            If a flow control is used and if the high watermark of the RX
 *            buffer is reached the receiver is stopped.
 *            If the RX threshold level is reached the callback mechanism is
 *            activated.
 *
 * Arguments: In : none
 *            Out: none
 *
 * Returns  : none
 *
 ******************************************************************************/

static VOID
hisr_execute_rx_operations (VOID)
{
    SYS_UWORD16 bytes_free_in_rx_buffer;
    SYS_UWORD16 wrap_around_counter;
    SYS_UWORD16 bytes_in_rx_buffer;
    SYS_UWORD16 bytes_read;
    SYS_UWORD16 bytes_to_copy;
    SYS_UWORD8  *current_byte;
    SYS_UWORD8  xon_xoff_detected;
    t_uart *uart;

    /*
     * 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_restart_uart_sleep_timer ();
    uart_sleep_timer_enabled = 1;

#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (BOARD == 43) || (BOARD == 45))
    uart->index_hisr = (uart->index_hisr + 1) & 0x01; /* 0 or 1 */
#endif

    xon_xoff_detected = 0;
    
    uart = &uart_parameters;
    
    /*
     * Switch to the other buffer.
     */
     
    current_byte = uart->rx_buffer_used_by_rx_hisr;
    if (current_byte == &(uart->rx_fifo_byte_1[0])) {
    
        current_byte = &(uart->rx_fifo_byte_2[0]);
        bytes_read = uart->bytes_in_rx_buffer_2;
    
    } else {
    
        current_byte = &(uart->rx_fifo_byte_1[0]);
        bytes_read = uart->bytes_in_rx_buffer_1;
    }

    uart->rx_buffer_used_by_rx_hisr = current_byte;

    /*
     * All bytes are copied into the RX buffer only if an escape sequence has
     * been detected or a break in the detection has occured.
     */

    if (!detect_escape_sequence (uart)) {

        if (uart->rx_out > uart->rx_in)
            bytes_free_in_rx_buffer = (SYS_UWORD16) (uart->rx_out - uart->rx_in - 1);
        else
            bytes_free_in_rx_buffer =
                (SYS_UWORD16) (uart->buffer_size + uart->rx_out - uart->rx_in);

        wrap_around_counter = uart->buffer_size + 1 -
                              (SYS_UWORD16) (uart->rx_in - &(uart->rx_buffer[0]));
        
        if (uart->flow_control_mode == fc_xoff) {
        
            /*
             * For SW Flow Control, need to further investigate the processing
             * in order to improve the performance of the driver, and in order
             * to avoid managing the wrap around of the circular buffer each
             * time a character is copied.
             */
        
            while (bytes_read && bytes_free_in_rx_buffer) {

                /*
                 * If the data received is XON or XOFF, the transmitter is
                 * enabled (XON) or disabled (XOFF).
                 */

                if (*current_byte == uart->xoff_character) {

                    uart->tx_stopped_by_driver = 1;
                    xon_xoff_detected = 1;

                } else if (*current_byte == uart->xon_character) {

                    uart->tx_stopped_by_driver = 0;
                    xon_xoff_detected = 1;

#if ((CHIPSET != 5) && (CHIPSET != 6))
                    /*
                     * Disable sleep mode.
                     */
          
                    WRITE_UART_REGISTER (
                        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
#endif

                    /*
                     * Unmask Tx interrupt.
                     */
          
                    WRITE_UART_REGISTER (
                        uart, IER, READ_UART_REGISTER (uart, IER) | ETBEI);

                } else {
    
                    *(uart->rx_in++) = *current_byte;

                    wrap_around_counter--;
                    if (!wrap_around_counter) {
                    
                        uart->rx_in = &(uart->rx_buffer[0]);
                        wrap_around_counter = uart->buffer_size + 1;
                    }
                    
                    bytes_free_in_rx_buffer--;
                }

                current_byte++;
                bytes_read--;
            }
        } else { /* No Flow Control or HW Flow Control */
                
            /*
             * Figure out the most restricting condition.
             */

            bytes_to_copy =
                Min3 (bytes_free_in_rx_buffer, wrap_around_counter, bytes_read);
                          
            /*
             * Copy characters into the circular Rx buffer.
             */
        
            memcpy (uart->rx_in, current_byte, bytes_to_copy);

            /*
             * Update first the variables associated to blocking conditions:
             * if (bytes_read = 0) OR
             *    (bytes_free_in_rx_buffer = 0) => No more characters to copy.
             */
                
            bytes_free_in_rx_buffer	-= bytes_to_copy;
            bytes_read -= bytes_to_copy;
                
            wrap_around_counter -= bytes_to_copy;
            if (!wrap_around_counter)
                    uart->rx_in = &(uart->rx_buffer[0]);
            else
                uart->rx_in += bytes_to_copy;

            /*
             * Check if there are still some characters to copy.
             */

            if (bytes_read && bytes_free_in_rx_buffer) {

                /*
                 * Update the remaining variables and figure out again the
                 * most restricting condition. Since (bytes_read = 0) and
                 * (bytes_free_in_rx_buffer = 0) are blocking conditions, if
                 * we reach that point it means that the wrap around condition
                 * has just occurred and it is not needed to manage it again.
                 */

                current_byte += bytes_to_copy;
                bytes_to_copy = Min (bytes_read, bytes_free_in_rx_buffer);

                /*
                 * Copy characters into the circular Rx buffer and update
                 * current pointer.
                 */

                memcpy (uart->rx_in, current_byte, bytes_to_copy);

                uart->rx_in += bytes_to_copy;
                
                /*
                 * bytes_free_in_rx_buffer not updated since not used anymore.
                 */
            }
        } /* end if (uart->flow_control_mode == fc_xoff) */

        /*
         * If the high watermark is reached, RTS is activated or XOFF is
         * sent according to the flow control mode.
         */

        bytes_in_rx_buffer = get_bytes_in_rx_buffer (uart);

        if ((uart->flow_control_mode != fc_none) &&
            (bytes_in_rx_buffer >= RX_HIGH_WATERMARK (uart->buffer_size))) {

            /*
             * Check if receipt must be stopped.
             */

            if (!uart->rx_stopped_by_driver) {

                uart->rx_stopped_by_driver = 1;
                if (!uart->rx_stopped_by_application)
                    stop_receiver (uart);
            }
        }

        /*
         * If a reading was suspended or if the callback function is installed,
         * it is called if one of these conditions is fulfiled:
         *      - the RX threshold level is reached,
         *      - a break has been detected,
         */

        if ((!uart->rd_call_from_hisr_in_progress) &&
            (uart->reading_suspended ||
             (uart->rd_call_setup == rm_reInstall))) {

            if ((bytes_in_rx_buffer >= uart->rx_threshold_level) ||
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (BOARD == 43) || (BOARD == 45))
                uart->dtr_change_detected[uart->index_hisr] ||
#endif
                uart->break_received ||
                xon_xoff_detected) {

                uart->rd_call_from_hisr_in_progress = 1;
                update_reading_callback (uart, 3); /* 3: call from Rx HISR. */

                uart->reading_suspended = 0;
                uart->break_received = 0;
                uart->esc_seq_received = 0;
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (BOARD == 43) || (BOARD == 45))
                uart->dtr_change_detected[uart->index_hisr] = 0;
#endif
            }
        }
    }
}

/*******************************************************************************
 *
 *                          hisr_execute_v24_operations
 * 
 * Purpose  : The user's function is called if all conditions to call it are
 *            fulfiled.
 *
 * Arguments: In : none
 *            Out: none
 *
 * Returns  : none
 *
 ******************************************************************************/

static VOID
hisr_execute_v24_operations (VOID)
{
    t_uart *uart;

    uart = &uart_parameters;

    /*
     * If a reading was suspended or if the callback function is installed,
     * it is called.
     */

    if ((!DRIVER_DISABLED (uart)) &&
        (!uart->rd_call_from_hisr_in_progress) &&
        (uart->reading_suspended || (uart->rd_call_setup == rm_reInstall))) {

        uart->rd_call_from_hisr_in_progress = 1;
        update_reading_callback (uart, 1); /* 1: call from HISR. */

        uart->reading_susp

⌨️ 快捷键说明

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