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

📄 uartfax.c

📁 是一个手机功能的模拟程序
💻 C
📖 第 1 页 / 共 5 页
字号:
/*******************************************************************************
 *
 * 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 + -