📄 uartfax.c
字号:
//==================================================================================
#include "main_system.h"
#include "faxdata.h"
#include "USB_VSP.h"
#include "uartfax.h"
#include "dev_uart.h"
#include "bspusart.h"
#include "nucleus.h"
#include "bspVote.h"
#define UAF_UART_1 2
/*
* Maximal value for an unsigned 32 bits.
*/
/*`
* 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.
*/
#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 BREAK_CONTROL (0x40) /* Enable a break condition */
#define IIR_BITS_USED (0x07)
#define IT_PENDING (0x01)
#define RX_DATA (0x04)
#define TX_EMPTY (0x02)
#define RX_TIMEOUT (0x04)
#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 */
#define MAX_UNSIGNED_32 (4294967295)
#define FIFO_SIZE (64) /* In bytes. */
#define UAF_USB_PORT_ID 2
T_tr_UartType UAF_GetPortType(T_tr_UartId uart_id);
/*
* 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 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.
*/
/*
* Macros to get minimum and maximum between 2 numbers.
*/
#define Min(a,b) ((a)<(b)?(a):(b))
#define Max(a,b) ((a)<(b)?(b):(a))
/*
* Macro to get minimum between 3 numbers.
*/
#define Min3(a,b,c) (Min(Min(a,b),c))
#ifndef USB_MCCI
unsigned
COSTENOtoUSB_Write(
unsigned iPort,
unsigned char *pBuffer,
unsigned nBuffer
){}
unsigned
COSTENOtoUSB_Read(
unsigned iPort,
unsigned char *pBuffer,
unsigned nBuffer
){}
unsigned
COSTENOtoUSB_IsPortReady(
unsigned iPort
){}
unsigned
COSTENOtoUSB_GetBufferSizeToRead(
unsigned iPort
){}
#endif
static const UNSIGNED baudrate_value[] =
{
9600,
14400,
28800,
38400,
57600,
115200,
230400,
500000,
750000,
1000000
};
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;
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;
SYS_UWORD16 guard_period;
SYS_UWORD16 current_time;
SYS_UWORD16 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;
SYS_UWORD16 baudrate;
SYS_UWORD16 bits_per_char; /* Including start, stop and parity bits. */
SYS_UWORD16 break_length; /* In bytes. */
SYS_UWORD16 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). */
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;
t_uart uart_parameters;
#define RXBUFSIZE 64 /* RX Buffer Length */
#define TXBUFSIZE 64 /* TX Buffer Length */
#define RXTHRESH 01 /* RX Thresh-Hold */
#define TXTHRESH 01 /* TX Thresh-Hold */
static BspUsart_BufferData Rx_buffer[RXBUFSIZE];
static BspUsart_BufferData Tx_buffer[TXBUFSIZE];
static BspUtil_CircBuf_Handle Scb;
static Uint16 NumBytesFree;
static NU_TIMER CTShigh_Timer;
BspVote_Handle UART3_CTSlow_vote_for_PM;
extern unsigned long receive_counter1,receive_counter2,receive_counter3;
extern unsigned long send_counter1,send_counter2,send_counter3;
/*******************************************************************************
*
* stop_break
*
* Purpose : The timer is activated to expire when a time corresponding to the
* sending time of 2 characters at least has elapsed. After a break,
* no character may be sent during this period.
*
* Arguments: In : id: parameter not used.
* Out: none
*
* Returns : none
*
******************************************************************************/
static VOID
stop_break (UNSIGNED id)
{
t_uart *uart;
uart = &uart_parameters;
uart->break_to_send = 0;
uart->break_in_progress = 0;
/*
* Unmask Tx interrupt.
*/
if(UAF_GetPortType(id) == UA_TYPE_UART)
{
dev_Uart_setInterruptEnableRegister(UAF_UART_1,dev_Uart_getInterruptEnableRegister(UAF_UART_1)|ETBEI);
}
else if(UAF_GetPortType(id) == UA_TYPE_USB) /* USB virtual serial ports */
{
/*
if(pUSBDeviceObject)
{
USB_SetClearModemStatus(
pUSBDeviceObject,
USBSERI_MODEM_STATE_BREAK,
0
);
}
*/
}
}
/*******************************************************************************
*
* 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
*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -