📄 uartfax.c
字号:
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 + -