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