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

📄 uartfax.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
        *(uart->state) |= (1 << ESC);
        
        break;
    }
    
    uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
    
    /*
     * 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,
     *      - an escape sequence 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) ||
            uart->break_received ||
            uart->esc_seq_received) {

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

            uart->reading_suspended = 0;
            uart->break_received = 0;
            uart->esc_seq_received = 0;
        }
    }
}

/*******************************************************************************
 *
 *                          stop_guard_period_timer
 * 
 * Purpose  : Stops the timer used to detect the guard period expiration.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : none 
 *
 ******************************************************************************/

static void
stop_guard_period_timer (t_uart *uart)
{
    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
                             NU_DISABLE_TIMER);
}

/*******************************************************************************
 *
 *                          start_guard_period_timer
 * 
 * Purpose  : Starts a timer which expires if the guard period has ellapsed.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : none 
 *
 ******************************************************************************/

static void
start_guard_period_timer (t_uart *uart)
{
    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
                             NU_DISABLE_TIMER);

    (void) NU_Reset_Timer (&(uart->guard_period_timer_ctrl_block),
                           analyze_guard_period_timer_expiration,
                           uart->guard_period,
                           0, /* The timer expires once. */
                           NU_DISABLE_TIMER);

    (void) NU_Control_Timer (&(uart->guard_period_timer_ctrl_block),
                             NU_ENABLE_TIMER);
}

/*******************************************************************************
 *
 *                          detect_escape_sequence
 * 
 * Purpose  : The state machine used to detect an escape sequence is updated
 *            according to the array of bytes to analyse. If the state machine
 *            goes to the initial state due to a break in the sequence
 *            detection, the previous characters are put into the RX buffer.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : 0: Break in detection or a sequence has been detected. 
 *            1: A sequence may be detected.
 *
 ******************************************************************************/

static int
detect_escape_sequence (t_uart *uart)
{
    int      detection_result;
    SYS_UWORD8    *rx_fifo_byte;
    SYS_UWORD16   bytes_in_rx_buffer;
    UNSIGNED elapsed_time;

    detection_result = 0;

    rx_fifo_byte = uart->rx_buffer_used_by_rx_hisr;
    if (rx_fifo_byte == &(uart->rx_fifo_byte_1[0]))
        bytes_in_rx_buffer = uart->bytes_in_rx_buffer_1;
    else
        bytes_in_rx_buffer = uart->bytes_in_rx_buffer_2;

    if (uart->current_time > uart->previous_time)
        elapsed_time = uart->current_time - uart->previous_time;
    else
        elapsed_time =
            MAX_UNSIGNED_32 - uart->previous_time + uart->current_time;

    switch (uart->esc_seq_detection_state) {

    case INITIALIZATION:

        /*
         * It is the first character received. It may be the first character
         * of an escape sequence. The elapsed_time variable is set to the
         * guard period value to consider this character as the first character
         * of an escape sequence.
         */

        if (!uart->esc_seq_modified) {

            elapsed_time = uart->guard_period;
            uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
        }

        /* No break! */

    case NO_ESCAPE_SEQUENCE:

        /*
         * To go to the next state (one, two or three characters detected):
         *      - a guard period must have elapsed since the last receipt,
         *      - the characters must belong to the escape sequence.
         */

        if ((elapsed_time >= uart->guard_period) &&
            (!uart->esc_seq_modified)) {

            switch (bytes_in_rx_buffer) {

            case 1:

                if (*rx_fifo_byte++ == uart->esc_seq_character) {
                
                    uart->esc_seq_detection_state = ONE_CHAR_DETECTED;
                    start_guard_period_timer (uart);
                    detection_result = 1;
                }

                break;

            case 2:

                if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
                    (*rx_fifo_byte++ == uart->esc_seq_character)) {
                    
                    uart->esc_seq_detection_state = TWO_CHARS_DETECTED;
                    start_guard_period_timer (uart);
                    detection_result = 1;
                }
                                    
                break;

            case 3:

                if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
                    (*rx_fifo_byte++ == uart->esc_seq_character) &&
                    (*rx_fifo_byte++ == uart->esc_seq_character)) {
                        
                    uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
                    start_guard_period_timer (uart);
                    detection_result = 1;
                }
                    
                break;

            default:
            
                /*
                 * No action.
                 */

                break;
            }
        }

        uart->previous_time = uart->current_time;

        break;

    case ONE_CHAR_DETECTED:

        /*
         * To go to the next state (two or three characters detected):
         *      - the difference between the current time and the previous time
         *        must be less than the guard period,
         *      - the characters must belong to the escape sequence.
         * Otherwise, an escape sequence character is written in the RX buffer.
         */

        if (!uart->esc_seq_modified) {

            switch (bytes_in_rx_buffer) {

            case 1:

                if (*rx_fifo_byte++ == uart->esc_seq_character) {
                
                    uart->esc_seq_detection_state = TWO_CHARS_DETECTED;
                    detection_result = 1;                
                }

                break;

            case 2:

                if ((*rx_fifo_byte++ == uart->esc_seq_character) &&
                    (*rx_fifo_byte++ == uart->esc_seq_character)) {
                
                    start_guard_period_timer (uart); /* Reset the timer. */
                       
                    uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
                    detection_result = 1;                    
                }
                    
                break;

            default:

                /*
                 * No action.
                 */

                break;
            }
        }

        if (!detection_result) {

            add_esc_seq_char_in_rx_buffer (uart);

            uart->previous_time = uart->current_time;
            uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
        }

        break;

    case TWO_CHARS_DETECTED:

        /*
         * To go to the next state (three chars detected):
         *      - the difference between the current time and the previous time
         *        must be less than the guard period,
         *      - the character must belong to the escape sequence.
         * Otherwise, 2 escape sequence characters are written in the RX buffer.
         */

        if (!uart->esc_seq_modified) {

            switch (bytes_in_rx_buffer) {

            case 1:

                if (*rx_fifo_byte++ == uart->esc_seq_character) {

                    start_guard_period_timer (uart); /* Reset the timer. */
                    
                    uart->esc_seq_detection_state = THREE_CHARS_DETECTED;
                    detection_result = 1;
                }
                
                break;

            default:

                /*
                 * No action.
                 */

                break;
            }
        }

        if (!detection_result) {

            add_esc_seq_char_in_rx_buffer (uart);
            add_esc_seq_char_in_rx_buffer (uart);

            uart->previous_time = uart->current_time;
            uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;
        }

        break;

    case THREE_CHARS_DETECTED:

        /*
         * An escape sequence is detected if a guard period has elapsed since
         * the last receipt. Otherwise, 3 escape sequence characters are
         * written in the RX buffer.
         */

        stop_guard_period_timer (uart);

        add_esc_seq_char_in_rx_buffer (uart);
        add_esc_seq_char_in_rx_buffer (uart);
        add_esc_seq_char_in_rx_buffer (uart);

        uart->previous_time = uart->current_time;
        uart->esc_seq_detection_state = NO_ESCAPE_SEQUENCE;

        break;
    }

    return (detection_result);
}

/*******************************************************************************
 *
 *                              send_break
 * 
 * Purpose  : This function may only called if the TX FIFO is empty.
 *            Null characters are written in the TX FIFO. The number of bytes to
 *            write has been defined with UAF_SetLineState. Enables the break
 *            condition.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : Number of bytes sent.
 *
 ******************************************************************************/

static SYS_UWORD16
send_break (t_uart *uart)
{
    SYS_UWORD16 bytes_in_tx_fifo;

    bytes_in_tx_fifo = 0;
    uart->break_in_progress = 1;

#if ((CHIPSET != 5) && (CHIPSET != 6))
    /*
     * Disable sleep mode.
     */

    WRITE_UART_REGISTER (
        uart, IER, READ_UART_REGISTER (uart, IER) & ~IER_SLEEP);
#endif

    WRITE_UART_REGISTER (
        uart, LCR, READ_UART_REGISTER (uart, LCR) | BREAK_CONTROL);
      
#if ((CHIPSET != 5) && (CHIPSET != 6))
    /*
     * Re-enable sleep mode.
     */

    WRITE_UART_REGISTER (
        uart, IER, READ_UART_REGISTER (uart, IER) | IER_SLEEP);
#endif

    while (uart->break_length) {

        WRITE_UART_REGISTER (uart, THR, 0x00);
        uart->break_length--;
        bytes_in_tx_fifo++;
    }

    return (bytes_in_tx_fifo);
}

/*******************************************************************************
 *
 *                              build_rx_fifo_array
 * 
 * Purpose  : Reads the RX FIFO to build an array with bytes read.
 *            A byte is written in this array if no error is detected. 
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : The number of bytes in RX FIFO.
 *
 ******************************************************************************/

static SYS_UWORD16

⌨️ 快捷键说明

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