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

📄 uartfax.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    SYS_UWORD16 rx_threshold_level;
    SYS_UWORD16 tx_threshold_level;
    SYS_UWORD8  rx_buffer[FD_MAX_BUFFER_SIZE + 1];
    SYS_UWORD8  tx_buffer[FD_MAX_BUFFER_SIZE + 1];
    SYS_UWORD8  *rx_in;
    SYS_UWORD8  *rx_out;
    SYS_UWORD8  *tx_in;
    SYS_UWORD8  *tx_out;

    /*
     * Escape sequence.
     * the field esc_seq_modified may have 2 values:
     *      - 0: No modification.
     *      - 1: Parameters are in the process of modification: The detection
     *           is stopped.
     */

    NU_TIMER      guard_period_timer_ctrl_block;
    SYS_UWORD8    esc_seq_modified;
    SYS_UWORD8    esc_seq_detection_state;
    SYS_UWORD8    esc_seq_character;
    UNSIGNED      guard_period;
    UNSIGNED      current_time;
    UNSIGNED      previous_time;

    /*
     * Flow control.
     */

    T_flowCtrlMode     flow_control_mode;
    SYS_BOOL           send_xon_xoff;
    SYS_UWORD8         xon_xoff_to_send;
    SYS_UWORD8         xon_character;
    SYS_UWORD8         xoff_character;
    SYS_BOOL           rx_stopped_by_application;
    SYS_BOOL           rx_stopped_by_driver;
    SYS_BOOL           tx_stopped_by_application;
    SYS_BOOL           tx_stopped_by_driver;

    /*
     * Break.
     */

    SYS_BOOL     break_received;
    SYS_BOOL     break_to_send;
    SYS_BOOL     break_in_progress;
    NU_HISR      break_hisr_ctrl_block;
    char         break_hisr_stack[BREAK_HISR_STACK_SIZE];
    NU_TIMER     break_timer_ctrl_block;
    UNSIGNED     baudrate;
    UNSIGNED     bits_per_char; /* Including start, stop and parity bits. */
    UNSIGNED     break_length;  /* In bytes. */
    UNSIGNED     time_without_character;

    /*
     * Callback (UAF_ReadData and UAF_WriteData).
     * rd: read, wr: write.
     */

    SYS_BOOL   esc_seq_received;
    SYS_UWORD8 rts_level; /* RTS on RS232 side, CTS on chipset side.
                             1: The RS232 line is deactivated (low). */

#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (BOARD == 43) || (BOARD == 45))
    SYS_UWORD8 dtr_level; /* Controlled with an I/O on C, D & E-Sample.
                             1: The RS232 line is deactivated (low). */
    /*
     * When the DTR interrupt is detected the user's Rx callback function must
     * be called but if the Rx FIFO is not empty the Rx HISR must be activated
     * to read the bytes received in the Rx FIFO and to put them into the Rx
     * buffer before to call the user's Rx callback function.
     * If the Rx HISR is activated due to a Rx interrupt the user's Rx callback
     * function will be called if conditions to call it are fulfilled. If it is
     * activated due to the DTR interrupt the user's Rx callback function must
     * be called without any conditions.
     * Because the Rx HISR may have been activated but not executed before the
     * DTR interrupt we must be sure that the user's Rx callback function will
     * be called for each Rx HISR activation. Call is done for Rx HISR activated
     * on Rx interrupt if conditions are fulfilled.
     * A circular buffer of 2 elements is used to memorize the source of
     * interrupt. Before the activation of the Rx HISR, the source of interrupt
     * is memorized into this array. When the code of the Rx HISR is executed
     * the user's Rx callback function is called if the source of interrupt was
     * the DTR interrupt regardless of the other conditions.
     * The level of DTR is saved to provide the level detected on Rx interrupt
     * or DTR interrupt in the 'state' parameter of the user's Rx callback
     * function.
     */                             

    SYS_BOOL   dtr_change_detected[2];
    SYS_UWORD8 dtr_level_saved[2];
    SYS_UWORD8 index_it;
    SYS_UWORD8 index_hisr;
#endif /* BOARD 8 or 9 or 40 or 41 */                            
    
    SYS_BOOL         reading_suspended;
    SYS_BOOL         writing_suspended;
    SYS_BOOL         rd_call_from_hisr_in_progress;
    SYS_BOOL         wr_call_from_hisr_in_progress;
    T_reInstMode     rd_call_setup;
    T_reInstMode     wr_call_setup;
    SYS_UWORD8       *rd_address[2];
    SYS_UWORD8       *wr_address[2];
    SYS_UWORD16      rd_size_before_call[2];
    SYS_UWORD16      rd_size_after_call[2];
    SYS_UWORD16      wr_size_before_call[2];
    SYS_UWORD16      wr_size_after_call[2];

    void (*readOutFunc) (SYS_BOOL cldFromIrq,
                         T_reInstMode *reInstall,
                         SYS_UWORD8 nsource,
                         SYS_UWORD8 *source[],
                         SYS_UWORD16 size[],
                         SYS_UWORD32 state);

    void (*writeInFunc) (SYS_BOOL cldFromIrq,
                         T_reInstMode *reInstall,
                         SYS_UWORD8 ndest,
                         SYS_UWORD8 *dest[],
                         SYS_UWORD16 size[]);

    /*
     * These fields are used to store the state defined in UAF_GetLineState.The
     * first field is used when UAF_GetLineState and UAF_ReadData are not called.
     * When one of these functions is called the second field is used. That
     * avoids to lose events when UAF_GetLineState or UAF_ReadData resets the
     * first field.
     */

    SYS_UWORD32 state_1;
    SYS_UWORD32 state_2;
    SYS_UWORD32 *state;

    /*
     * Errors counters.
     */

    SYS_UWORD32 framing_error;
    SYS_UWORD32 parity_error;
    SYS_UWORD32 overrun_error;
    SYS_UWORD32 spurious_interrupts;

    SYS_UWORD16 max_rx_fifo_level;

} t_uart;

static t_uart uart_parameters;

static const SYS_UWORD32 base_address[NUMBER_OF_FD_UART] =
{
    MEM_UART_IRDA,
    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[] =
{
      0, /*   Auto baud: not supported. */
     81, /*     75 baud.                */
     40, /*    150 baud.                */
    148, /*    300 baud.                */
     74, /*    600 baud.                */
    165, /*   1200 baud.                */
     83, /*   2400 baud.                */
    169, /*   4800 baud.                */
    113, /*   7200 baud.                */
     84, /*   9600 baud.                */
     56, /*  14400 baud.                */
     42, /*  19200 baud.                */
     28, /*  28800 baud.                */
     24, /*  33900 baud: not supported. */
     21, /*  38400 baud.                */
     14, /*  57600 baud.                */
      7, /* 115200 baud.                */
      0, /* 203125 baud: not supported. */
      0, /* 406250 baud: not supported. */
      0  /* 812500 baud: not supported. */
};

static const SYS_UWORD8 dlh[] = 
{
    0, /*   Auto baud: not supported. */
   42, /*     75 baud.                */
   21, /*    150 baud.                */
   10, /*    300 baud.                */
    5, /*    600 baud.                */
    2, /*   1200 baud.                */
    1, /*   2400 baud.                */
    0, /*   4800 baud.                */
    0, /*   7200 baud.                */
    0, /*   9600 baud.                */
    0, /*  14400 baud.                */
    0, /*  19200 baud.                */
    0, /*  28800 baud.                */
    0, /*  33900 baud: not supported. */
    0, /*  38400 baud.                */
    0, /*  57600 baud.                */
    0, /* 115200 baud.                */
    0, /* 203125 baud: not supported. */
    0, /* 406250 baud: not supported. */
    0  /* 812500 baud: not supported. */
};

static const UNSIGNED baudrate_value[] =
{
         0, /* Not supported. */
        75,
       150,
       300,
       600,
      1200,
      2400,
      4800,
      7200,
      9600,
     14400,
     19200,
     28800,
         0, /* Not supported. */
     38400,
     57600,
    115200,
         0, /* Not supported. */
         0, /* Not supported. */
         0  /* Not supported. */
};

/*******************************************************************************
 *
 *                          get_bytes_in_rx_buffer
 * 
 * Purpose  : Gets the number of bytes in the RX buffer.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : The number of bytes in the RX buffer.
 *
 ******************************************************************************/

static SYS_UWORD16
get_bytes_in_rx_buffer (t_uart *uart)
{
    SYS_UWORD16 bytes_in_rx_buffer;
    volatile SYS_UWORD8 *rx_in;

    rx_in = uart->rx_in;

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

    return (bytes_in_rx_buffer);
}

/*******************************************************************************
 *
 *                          get_bytes_in_tx_buffer
 * 
 * Purpose  : Gets the number of bytes in the TX buffer.
 *
 * Arguments: In : uart: Pointer on the UART structure.
 *            Out: none
 *
 * Returns  : The number of bytes in the TX buffer.
 *
 ******************************************************************************/

static SYS_UWORD16
get_bytes_in_tx_buffer (t_uart *uart)
{
    SYS_UWORD16 bytes_in_tx_buffer;
    volatile SYS_UWORD8 *tx_out;

    tx_out = uart->tx_out;

    if (tx_out <= uart->tx_in)
        bytes_in_tx_buffer = (SYS_UWORD16) (uart->tx_in - tx_out);
    else
        bytes_in_tx_buffer =
            (SYS_UWORD16) (uart->tx_in - tx_out + uart->buffer_size + 1);

    return (bytes_in_tx_buffer);
}

/*******************************************************************************
 *
 *                              compute_break_time
 * 
 * Purpose  : Computes a number of TDMA from 3 parameters:
 *              - baudrate,
 *              - bits per character including start bit, stop bits and parity,
 *              - number of characters.
 *            Due to the TDMA value (4.6 ms), a minimal value is sent: 2 TDMA.
 *
 * Arguments: In : baudrate
 *                 bits_per_char
 *                 number_of_chars
 *            Out: none
 *
 * Returns  : The number of TDMA.
 *
 ******************************************************************************/

static UNSIGNED
compute_break_time (UNSIGNED baudrate,
                    UNSIGNED bits_per_char,
                    UNSIGNED number_of_chars)
{
    UNSIGNED number_of_tdma;

    number_of_tdma = CONVERT_TIME_IN_TDMA (
                         1000 * bits_per_char * number_of_chars / baudrate);

    if (number_of_tdma == 0)
        number_of_tdma = 1;

    number_of_tdma++;

    return (number_of_tdma);
}

/*******************************************************************************
 *
 *                          update_reading_callback
 * 
 * Purpose  : Updates the sizes array and the addresses array and get and builds
 *            the state parameter defined in UAF_GetLineState to call the
 *            readOutFunc function.
 *
 * Arguments: In : uart       : Pointer on the UART structure.
 *                 call_source: 0: application, 1: HISR (Rx or V24), 3: Rx HISR
 *            Out: none
 *
 * Returns  : none
 *
 ******************************************************************************/

static void
update_reading_callback (t_uart *uart,
                         SYS_BOOL call_source)
{
    SYS_UWORD32  state;
    SYS_UWORD8  dtr_level;
    SYS_UWORD8  fragments_number;
    SYS_UWORD16 bytes_in_rx_buffer;
    volatile SYS_UWORD8 *rx_in;

    /*
     * Update the sizes array and the addresses array.
     * A copy of rx_in is used because it may be updated by the interrupt
     * handler if this function is called from the application.
     */

    rx_in = uart->rx_in;
    
    if (uart->rx_out < rx_in) {

        fragments_number = 1;

        uart->rd_address[0] = uart->rx_out;
        uart->rd_size_before_call[0] = (SYS_UWORD16) (rx_in - uart->rx_out);
        uart->rd_size_after_call[0] = uart->rd_size_before_call[0];

        uart->rd_size_before_call[1] = 0;
        uart->rd_size_after_call[1] = 0;

        bytes_in_rx_buffer = uart->rd_size_before_call[0];

    } else if (rx_in == uart->rx_out) { /* RX buffer empty. */
        
        fragments_number = 1;

        uart->rd_address[0] = uart->rx_out;
        uart->rd_size_before_call[0] = 0;
        uart->rd_size_after_call[0] = 0;

        uart->rd_size_before_call[1] = 0;
        uart->rd_size_after_call[1] = 0;

        bytes_in_rx_buffer = 0;
                    
    } else {
    
        fragments_number = 2;

        uart->rd_address[0] = uart->rx_out;
        uart->rd_size_before_call[0] =
            uart->buffer_size + 1 - (SYS_UWORD16) (uart->rx_out -
                                               &(uart->rx_buffer[0]));
        uart->rd_size_after_call[0] = uart->rd_size_before_call[0];

        uart->rd_address[1] = &(uart->rx_buffer[0]);
        uart->rd_size_before_call[1] = (SYS_UWORD16) (rx_in -
                                                  &(uart->rx_buffer[0]));
        uart->rd_size_after_call[1] = uart->rd_size_before_call[1];

        bytes_in_rx_buffer =
            uart->rd_size_before_call[0] + uart->rd_size_before_call[1];

        if (!uart->rd_size_before_call[1])
            fragments_number = 1;
    }

    /*
     * Build the state parameter defined in UAF_GetLineState.
     * The field state_2 is used when state_1 is set to 0 to avoid to
     * lose events detected in the RX interrupt handler.
     */

#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (BOARD == 43) || (BOARD == 45))
    if (call_source == 3) /* Call from Rx HISR */
        dtr_level = uart->dtr_level_saved[uart->index_hisr];

⌨️ 快捷键说明

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