📄 uartfax.c
字号:
/*******************************************************************************
*
* UARTFAX.C
*
* This driver allows to control the UARTs of chipset 1.5 for fax and data
* services. It performs flow control: RTS/CTS, XON/XOFF.
*
* On C-Sample, DCD and DTR signals are supported on UART modem only with 2 I/O.
* On Calypso, RTS and CTS are supported on both UARTs.
*
* (C) Texas Instruments 1999 - 2001
*
******************************************************************************/
/*
* C-Sample
*
* UART Modem UART Irda
*
* DB9 Calypso DB9 Calypso
*
* 1 DCD I/O 2 output 1 1, 6 and 4 are connected together on DB9
* 2 RX TX output 2 RX TX2 output
* 3 TX RX input 3 TX RX2 input
* 4 DTR I/O 3 input 4
* 5 GND 5 GND
* 6 NC 6
* 7 RTS CTS input 7 RTS CTS2 input
* 8 CTS RTS output 8 CTS RTS2 output
* 9 NC 9 NC
*
*/
/*
* B-Sample
*
* UART Modem UART Irda
*
* DB9 Ulysse DB9 Ulysse
*
* 1 1, 6 and 4 are connected together on DB9 (Modem and Irda)
* 2 RX TX 2 RX TX
* 3 TX RX 3 TX RX
* 4 4
* 5 GND 5 GND
* 6 6
* 7 RTS CTS 7 7 and 8 are connected together on DB9
* 8 CTS RTS 8
* 9 NC 9 NC
*
*/
#include "board.cfg"
#include "chipset.cfg"
#include <string.h>
#include "nucleus.h"
#include "sys_types.h"
#include "faxdata.h"
#include "uartfax.h"
/*
* Needed to reset and restart the sleep timer in case of incoming characters.
*/
#include "serialswitch.h"
extern SYS_BOOL uart_sleep_timer_enabled;
/*
* rv_general.h is needed for macros Min & Min3.
*/
#include "rv_general.h"
#include "mem.h"
#if ((BOARD == 8) || (BOARD == 9) || (BOARD == 40) || (BOARD == 41) || (BOARD == 43) || (BOARD == 45))
#include "armio.h"
#endif
/*
* Maximal value for an unsigned 32 bits.
*/
#define MAX_UNSIGNED_32 (4294967295)
#define FIFO_SIZE (64) /* In bytes. */
/*
* TLR is used to program the RX FIFO trigger levels. FCR[7:4] are not used.
* No trigger level used for TX FIFO. THR_IT generated on TX FIFO empty.
*/
#define RX_FIFO_TRIGGER_LEVEL (12 << 4)
/*
* 16750 addresses. Registers accessed when LCR[7] = 0.
*/
#define RHR (0x00) /* Rx buffer register - Read access */
#define THR (0x00) /* Tx holding register - Write access */
#define IER (0x01) /* Interrupt enable register */
/*
* 16750 addresses. Registers accessed when LCR[7] = 1.
*/
#define DLL (0x00) /* Divisor latch (LSB) */
#define DLM (0x01) /* Divisor latch (MSB) */
/*
* EFR is accessed when LCR[7:0] = 0xBF.
*/
#define EFR (0x02) /* Enhanced feature register */
/*
* 16750 addresses. Bit 5 of the FCR register is accessed when LCR[7] = 1.
*/
#define IIR (0x02) /* Interrupt ident. register - Read only */
#define FCR (0x02) /* FIFO control register - Write only */
#define LCR (0x03) /* Line control register */
#define MCR (0x04) /* Modem control register */
#define LSR (0x05) /* Line status register */
#define MSR (0x06) /* Modem status register */
#define TCR (0x06) /* Transmission control register */
#define TLR (0x07) /* Trigger level register */
#define MDR1 (0x08) /* Mode definition register 1 */
#define SCR (0x10) /* Supplementary Control register */
#define SSR (0x11) /* Supplementary Status register */
/*
* Supplementary control register.
*/
#define TX_EMPTY_CTL_IT (0x08)
#define RX_CTS_WAKE_UP_ENABLE_BIT (4) /* Use RESET_BIT and SET_BIT macros. */
/*
* Enhanced feature register.
*/
#define ENHANCED_FEATURE_BIT (4) /* Use RESET_BIT and SET_BIT macros. */
/*
* Mode definition register 1.
*/
#define UART_MODE (0x00)
#define SIR_MODE (0x01)
#define UART_MODE_AUTOBAUDING (0x02) /* Reserved in UART/IrDA. */
#define RESET_DEFAULT_STATE (0x07)
#define IR_SLEEP_DISABLED (0x00)
#define IR_SLEEP_ENABLED (0x08)
#define SIR_TX_WITHOUT_ACREG2 (0x00) /* Reserved in UART/modem. */
#define SIR_TX_WITH_ACREG2 (0x20) /* Reserved in UART/modem. */
#define FRAME_LENGTH_METHOD (0x00) /* Reserved in UART/modem. */
#define EOT_BIT_METHOD (0x80) /* Reserved in UART/modem. */
/*
* Supplementary Status Register
*/
#define TX_FIFO_FULL (0x01)
/*
* Interrupt enable register.
*/
#define ERBI (0x01) /* Enable received data available interrupt */
#define ETBEI (0x02) /* Enable transmitter holding register empty interrupt */
#define ELSI (0x04) /* Enable receiver line status interrupt */
#define EDSSI (0x08) /* Enable modem status interrupt */
#define IER_SLEEP (0x10) /* Enable sleep mode */
/*
* Modem control register.
*/
#if (CHIPSET == 12)
#define MDCD_LOW (0x01)
#endif
#define MDTR (0x01) /* Data terminal ready. */
#define MRTS (0x02) /* Request to send. */
#define TCR_TLR_BIT (6)
/*
* Line status register.
*/
#define DR (0x01) /* Data ready */
#define OE (0x02) /* Overrun error */
#define PE (0x04) /* Parity error */
#define FE (0x08) /* Framing error */
#define BI (0x10) /* Break interrupt */
#define THRE (0x20) /* Transmitter holding register (FIFO empty) */
#define TEMT (0x40) /* Transmitter empty (FIFO and TSR both empty) */
#define BYTE_ERROR (OE | PE | FE | BI)
/*
* Interrupt identification register.
* Bit 0 is set to 0 if an IT is pending.
* Bits 1 and 2 are used to identify the IT.
*/
#define IIR_BITS_USED (0x07)
#define IT_PENDING (0x01)
#define RX_DATA (0x04)
#define TX_EMPTY (0x02)
#define MODEM_STATUS (0x00)
/*
* Modem status register.
*/
#define DELTA_CTS (0x01)
#define DELTA_DSR (0x02)
#define MCTS (0x10) /* Clear to send */
#define MDSR (0x20) /* Data set ready */
/*
* Line control register.
*/
#define WLS_5 (0x00) /* Word length: 5 bits */
#define WLS_6 (0x01) /* Word length: 6 bits */
#define WLS_7 (0x02) /* Word length: 7 bits */
#define WLS_8 (0x03) /* Word length: 8 bits */
#define STB (0x04) /* Number of stop bits: 0: 1, 1: 1,5 or 2 */
#define PEN (0x08) /* Parity enable */
#define EPS (0x10) /* Even parity select */
#define BREAK_CONTROL (0x40) /* Enable a break condition */
#define DLAB (0x80) /* Divisor latch access bit */
/*
* FIFO control register.
*/
#define FIFO_ENABLE (0x01)
#define RX_FIFO_RESET (0x02)
#define TX_FIFO_RESET (0x04)
/*
* These constants define the states of the escape sequence detection.
*/
#define INITIALIZATION (0)
#define NO_ESCAPE_SEQUENCE (1)
#define ONE_CHAR_DETECTED (2)
#define TWO_CHARS_DETECTED (3)
#define THREE_CHARS_DETECTED (4)
#define CHARACTERS_IN_ESC_SEQ (3)
#define DEFAULT_ESC_SEQ_CHARACTER '+'
#define DEFAULT_GUARD_PERIOD (1000) /* 1 second. */
/*
* 3 HISR are used to avoid to execute operations from the LISR.
*/
#define RX_HISR_PRIORITY (2)
#define RX_HISR_STACK_SIZE (512) /* Bytes. */
#define TX_HISR_PRIORITY (2)
#define TX_HISR_STACK_SIZE (512) /* Bytes. */
#define V24_HISR_PRIORITY (2)
#define V24_HISR_STACK_SIZE (512) /* Bytes. */
/*
* When the break interrupt indicator (BI) is set in the line status register
* (LSR), it indicates that the received data input was held in the low state
* for longer than a full-word transmission time. In the FIFO mode, when a break
* occurs, only one 0 character is loaded into the FIFO. The next character
* transfer is enabled after SIN goes to the marking state for at least two RCLK
* samples and then receives the next valid start bit.
* This constant defined a defined break length returned by the US_GetLineState
* function.
*/
#define MINIMAL_BREAK_LENGTH (2)
#define BREAK_HISR_PRIORITY (2)
#define BREAK_HISR_STACK_SIZE (512) /* Bytes. */
/*
* These macros allow to read and write a UART register.
*/
#define READ_UART_REGISTER(UART,REG) \
*((volatile SYS_UWORD8 *) ((UART)->base_address + (REG)))
#define WRITE_UART_REGISTER(UART,REG,VALUE) \
*((volatile SYS_UWORD8 *) ((UART)->base_address + (REG))) = (VALUE)
#define RESET_BIT(UART,REG,BIT) \
(WRITE_UART_REGISTER ( \
UART, REG, READ_UART_REGISTER (UART, REG) & ~(1 << (BIT))))
#define SET_BIT(UART,REG,BIT) \
(WRITE_UART_REGISTER ( \
UART, REG, READ_UART_REGISTER (UART, REG) | (1 << (BIT))))
/*
* These macros allow to enable or disable the wake-up interrupt.
*/
#define ENABLE_WAKEUP_INTERRUPT(UART) \
SET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);
#define DISABLE_WAKEUP_INTERRUPT(UART) \
RESET_BIT(UART, SCR, RX_CTS_WAKE_UP_ENABLE_BIT);
/*
* The transmitter is disabled only when the application disables the driver.
* To disable the driver, the receiver and the transmitter are disabled by the
* application. The transmitter is disabled first to test if the driver is
* disabled.
*/
#define DRIVER_DISABLED(UART) ((UART)->tx_stopped_by_application)
#define DISABLE_DRIVER(UART) \
{ \
(UART)->tx_stopped_by_application = 1; \
(UART)->rx_stopped_by_application = 1; \
}
#define ENABLE_DRIVER(UART) \
{ \
(UART)->rx_stopped_by_application = 0; \
(UART)->tx_stopped_by_application = 0; \
}
/*
* Low and high watermarks for the RX buffer. If it is enabled, the flow
* control is activated or deactivated according to these values.
* The high watermark value allows to copy an array filled with the RX FIFO
* into the RX buffer.
*/
#define RX_LOW_WATERMARK(RX_BUFFER_SIZE) (FIFO_SIZE)
#define RX_HIGH_WATERMARK(RX_BUFFER_SIZE) ((RX_BUFFER_SIZE) - 2 * FIFO_SIZE)
/*
* This macro allows to know if the RX buffer is full. It must be called only
* from the RX HISR. If it is called from the application, the rx_in and
* rx_fifo_in pointers may be updated if a RX interrupt occurs or if the
* RX HISR is activated.
*/
#define RX_BUFFER_FULL(UART) \
(((UART)->rx_in == (UART)->rx_out - 1) || \
((UART)->rx_in == (UART)->rx_out + (UART)->buffer_size))
/*
* This macro allows to know if the TX buffer is empty.
*/
#define TX_BUFFER_EMPTY(UART) \
((UART)->tx_in == (UART)->tx_out)
/*
* This macro is used to convert a time (unit: ms) into a number of TDMA.
* 1 TDMA = 4.6 ms (23/5).
*/
#define CONVERT_TIME_IN_TDMA(TIME) (((TIME) * 5) / 23)
/*
* This structure describes an UART compatible with the UART 16750 and
* contains some fields to manage this UART.
*/
typedef struct s_uart {
SYS_UWORD32 base_address;
/*
* HISR executed from the RX/TX interrupt handler.
*/
NU_HISR rx_hisr_ctrl_block;
NU_HISR tx_hisr_ctrl_block;
NU_HISR v24_hisr_ctrl_block;
char rx_hisr_stack[RX_HISR_STACK_SIZE];
char tx_hisr_stack[TX_HISR_STACK_SIZE];
char v24_hisr_stack[V24_HISR_STACK_SIZE];
/*
* 2 arrays are used to store bytes read in RX FIFO. A UART RX interrupt
* may occur while executing RX operations in RX HISR. To avoid overwriting
* the array in which received bytes are stored, a second array is used.
*/
SYS_UWORD8 *rx_buffer_used_by_rx_lisr;
SYS_UWORD8 *rx_buffer_used_by_rx_hisr;
SYS_UWORD8 rx_fifo_byte_1[FIFO_SIZE];
SYS_UWORD8 rx_fifo_byte_2[FIFO_SIZE];
SYS_UWORD16 bytes_in_rx_buffer_1;
SYS_UWORD16 bytes_in_rx_buffer_2;
/*
* RX and TX buffers.
* One character is not used in each buffer to allow to know if the buffer
* is empty or not (See macro RX_BUFFER_FULL). If buffers are empty,
* rx_in = rx_out and tx_in = tx_out. It is impossible to use fields to
* count the number of bytes in each buffer because these fields may be
* updated from the application and from the interrupt handlers. That avoids
* to have conflicts.
*/
SYS_UWORD16 buffer_size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -