📄 sc28l198serial.c
字号:
/*
* sc28l198Serial.c -- driver for octarts on Axcelis Carrier Board.
*/
#include "vxWorks.h"
#include "iv.h"
#include "ioLib.h"
#include "iosLib.h"
#include "tyLib.h"
#include "config.h"
#include "intLib.h"
#include "errnoLib.h"
#include "sc28l198.h"
#include "logLib.h"
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "logLib.h"
/* Size of Tx and Rx buffers in bytes */
#define BUFFER_SIZE 512
/******************************************************************************
Configuration information for the physical interface to the SC28L198 devices
*******************************************************************************/
struct
{
char *baseAddr; /* base address of the register set */
int numChannels; /* number of channels to use */
int inum; /* interrupt number */
} sc28l198Cfg[SC28L198_MAX_UARTS] =
{
{ (char*)SC28L198_UART0_ADDR, SC28L198_UART0_CHANS, SC28L198_UART0_INUM},
{ (char*)SC28L198_UART1_ADDR, 0 /*dynamic, set below*/, SC28L198_UART1_INUM}
};
/* Base address of a given device */
#define SC28L198_UART_ADDR(uart) (sc28l198Cfg[uart].baseAddr)
/* Register mapping for control registers that are specific to a
* given UART channel
*/
#define SC28L198_CHANNEL_REG(uart,chan,offset) \
(volatile char *)(SC28L198_UART_ADDR(uart) + ((chan<<4)&0x70) + offset)
/* Register maps for control registers that configure the entire chip */
#define SC28L198_GLOBAL_REG(uart,offset) \
(volatile char *)(SC28L198_UART_ADDR(uart) + offset)
/* Phillips SC28L198 Register Map
*
* Note that some of the registers are controlling the entire chip while
* others are for controlling just a channel in the chip. For the registers
* that control the entire uart, we have dropped the channel parameter in
* the register macro since it is static.
*/
#define SC28L198_MR0(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x00) /* Mode Reg 0 */
#define SC28L198_MR1(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x01) /* Mode Reg 1 */
#define SC28L198_IOPCR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x02) /* I/O Port Config Reg */
#define SC28L198_BCRBRK(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x03) /* Bid Ctrl, Break Change */
#define SC28L198_BCRCOS(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x04) /* Bid Ctrl, Change of State */
#define SC28L198_BCRX(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x06) /* Bid Ctrl, Xon/Xoff */
#define SC28L198_BCRA(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x07) /* Bid Ctrl, Address Recongnition */
#define SC28L198_XONCR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x08) /* Xon Char */
#define SC28L198_XOFFCR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x09) /* Xoff Char */
#define SC28L198_ARCR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x0a) /* Addr Recognition Char */
#define SC28L198_RXCSR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x0c) /* Rcvr Clk Select */
#define SC28L198_TEST(uart) SC28L198_GLOBAL_REG(uart,0x0d) /* Reserved */
#define SC28L198_TXCSR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x0e) /* Reserved */
#define SC28L198_GCCR(uart) SC28L198_GLOBAL_REG(uart,0x0f) /* Global Chip Config */
#define SC28L198_ICR(uart) SC28L198_GLOBAL_REG(uart,0x1b) /* Interrupt Control */
#define SC28L198_WDTRCR(uart) SC28L198_GLOBAL_REG(uart,0x1d) /* Watch Dog Timer Run Crtl */
#define SC28L198_IVR(uart) SC28L198_GLOBAL_REG(uart,0x1f) /* Interrupt Vector */
#define SC28L198_MR2(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x80) /* Mode Reg 2 */
#define SC28L198_SR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x81) /* Status */
#define SC28L198_CR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x81) /* Command */
#define SC28L198_ISR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x82) /* Interrupt Status */
#define SC28L198_IMR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x82) /* Interrupt Mask */
#define SC28L198_TXFIFO(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x83) /* Tx FIFO */
#define SC28L198_RXFIFO(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x83) /* Rx FIFO */
#define SC28L198_IPR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x84) /* Input Port Reg*/
#define SC28L198_BRGTRUA(uart) SC28L198_GLOBAL_REG(uart,0x84) /* BRG Timer Reg Upper a */
#define SC28L198_IOPIOR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x85) /* I/O Port Int and Output */
#define SC28L198_XISR(uart,chan) SC28L198_CHANNEL_REG(uart,chan,0x86) /* Xon/Xoff Int Stat */
#define SC28L198_GPOSR(uart) SC28L198_GLOBAL_REG(uart,0x87) /* GP Out Sel */
#define SC28L198_GPOC(uart) SC28L198_GLOBAL_REG(uart,0x8b) /* GP Out Clk */
#define SC28L198_UCIR(uart) SC28L198_GLOBAL_REG(uart,0x8c) /* Update Current Int */
#define SC28L198_CIR(uart) SC28L198_GLOBAL_REG(uart,0x8c) /* Current Int */
#define SC28L198_BRGTRUB(uart) SC28L198_GLOBAL_REG(uart,0x8d) /* BRG Timer Reg Upper b */
#define SC28L198_GRXFIFO(uart) SC28L198_GLOBAL_REG(uart,0x8e) /* Global Rcv FIFO */
#define SC28L198_GTXFIFO(uart) SC28L198_GLOBAL_REG(uart,0x8e) /* Global Tx FIFO */
#define SC28L198_BRGTRLA(uart) SC28L198_GLOBAL_REG(uart,0x94) /* BRG Timer Reg Lower a */
#define SC28L198_GPOR(uart) SC28L198_GLOBAL_REG(uart,0x97) /* GP Output Reg */
#define SC28L198_GPOD(uart) SC28L198_GLOBAL_REG(uart,0x9b) /* GP Out Data Reg */
#define SC28L198_BRGTCR(uart) SC28L198_GLOBAL_REG(uart,0x9c) /* BRG Timer Ctrl Reg */
#define SC28L198_GICR(uart) SC28L198_GLOBAL_REG(uart,0x9c) /* Global Int Chan Reg */
#define SC28L198_BRGTRLB(uart) SC28L198_GLOBAL_REG(uart,0x9d) /* BRG Timer Reg Lower a */
#define SC28L198_GIBCR(uart) SC28L198_GLOBAL_REG(uart,0x9d) /* Global Int Byte Count */
#define SC28L198_GITR(uart) SC28L198_GLOBAL_REG(uart,0x9f) /* Global Int Type Reg */
/* GCCR - Global Configuration Control Register */
#define ASYNC_BUS 0x00
#define SYNC_BUS 0x40
#define IVC_MASK 0x06
#define IVC_NONE 0x00
#define IVR 0x02
#define IVR_CHAN 0x04
#define IVR_CHAN_TYPE 0x06
#define PWR_ON 0x00
#define PWR_OFF 0x01
/* MR0 - Mode Register 0 */
#define XON_XOFF_TRANS_OFF 0x00
#define XON_XOFF_TRANS_ON 0x80
#define ADDR_TRANS_OFF 0x00
#define ADDR_TRANS_ON 0x40
#define TXINT_MASK 0x30
#define TXINT_MT 0x00
#define TXINT_3_4_MT 0x10
#define TXINT_1_2_MT 0x20
#define TXINT_NOT_FULL 0x30
#define FLOW_CTRL_MASK 0x0c
#define FLOW_CTRL_HOST 0x00
#define FLOW_CTRL_TX 0x04
#define FLOW_CTRL_RX 0x08
#define FLOW_CTRL_TX_RX 0x0c
#define ADDR_CTRL_MASK 0x03
#define ADDR_CTRL_NONE 0x00
#define ADDR_CTRL_WAKE 0x01
#define ADDR_CTRL_DOZE 0x02
#define ADDR_CTRL_WAKE_DOZE 0x03
/* MR1 - Mode Register 1 */
#define RXRTS_CTRL_OFF 0x00
#define RXRTS_CTRL_ON 0x80
#define ISR_RD_UNMASKED 0x00
#define ISR_RD_MASKED 0x40
#define ERR_MODE_CHAR 0x00
#define ERR_MODE_BLOCK 0x20
#define PARITY_MASK 0x18
#define PARITY_WITH 0x00
#define PARITY_FORCE 0x08
#define PARITY_NONE 0x10
#define PARITY_SPECIAL 0x18
#define PARITY_EVEN 0x00
#define PARITY_ODD 0x04
#define BPC_MASK 0x03
#define BPC_CS5 0x00
#define BPC_CS6 0x01
#define BPC_CS7 0x02
#define BPC_CS8 0x03
/* MR2 - Mode Register 2 */
#define CHAN_MODE_MASK 0xc0
#define NORMAL_MODE 0x00
#define AUTO_ECHO 0x40
#define LOCAL_LOOP 0x80
#define REMOTE_LOOP 0xc0
#define TXRTS_CTRL_OFF 0x00
#define TXRTS_CTRL_ON 0x20
#define CTSN_CTRL_TX_OFF 0x00
#define CTSN_CTRL_TX_ON 0x10
#define RXINT_MASK 0xc0
#define RXINT_RRDY 0x00
#define RXINT_1_2_FULL 0x40
#define RXINT_3_4_FULL 0x80
#define RXINT_FULL 0xc0
#define STOP_LEN_MASK 0x03
#define STOP_BIT_1 0x00
#define STOP_BIT_1_1_2 0x01
#define STOP_BIT_2 0x02
#define STOP_BIT_9_16 0x03
/* RxCSR and TxCSR - Receiver and transmitter Clock Select Registers
*
* Note that all of these values are based on the X1 crystal frequency
* of 3.6864MHz. If the X1 changes, then these values must also be changed.
*/
#define B50 0x00 /* 50 baud */
#define B75 0x01 /* 75 baud */
#define B150 0x02 /* 150 baud */
#define B200 0x03 /* 200 baud */
#define B300 0x04 /* 300 baud */
#define B450 0x05 /* 450 baud */
#define B600 0x06 /* 600 baud */
#define B900 0x07 /* 900 baud */
#define B1200 0x08 /* 1200 baud */
#define B1800 0x09 /* 1800 baud */
#define B2400 0x0a /* 2400 baud */
#define B3600 0x0b /* 3600 baud */
#define B4800 0x0c /* 4800 baud */
#define B7200 0x0d /* 7200 baud */
#define B9600 0x0e /* 9600 baud */
#define B14400 0x0f /* 14.4k baud */
#define B19200 0x10 /* 19.2k baud */
#define B28800 0x11 /* 28.8k baud */
#define B38400 0x12 /* 38.4k baud */
#define B57600 0x13 /* 57.6k baud */
#define B115200 0x14 /* 115.2k baud */
#define B230400 0x15 /* 230.4k baud */
#define BGIN0 0x16 /* Gin0 */
#define BGIN1 0x17 /* Gin1 */
#define BRG_CT0 0x18 /* BRG C/T 0 */
#define BRG_CT1 0x19 /* BRG C/T 1 */
#define IO2_IO3_16X 0x1b /* I/O 2 rcvr, I/O 3 xmit - 16x */
#define IO2_IO3_1X 0x1c /* I/O 2 rcvr, I/O 3 xmit - 1x */
/* CR - Command Register */
#define CMD_REG_MASK 0xf8
#define LOCK_ENABLES 0x04
#define CR_ENABLES_MASK 0x03
#define TX_ENABLE 0x02
#define TX_DISABLE 0x00
#define RX_ENABLE 0x01
#define RX_DISABLE 0x00
/* Note, as per the spec, writes to the upper bits of the CR (as in a
* command) would usually have a CR[2] at 1 to maintain the condition
* of the receiver and transmitter.
*
* To make this easier on the developer, we will include this bit in
* all of the commands.
*/
#define CMD_REG_CODE( command ) (((command<<3)&CMD_REG_MASK)|LOCK_ENABLES)
/* Command Register Codes */
#define NO_COMMAND CMD_REG_CODE(0x00)
#define RST_RCVR CMD_REG_CODE(0x02)
#define RST_XMIT CMD_REG_CODE(0x03)
#define RST_ERR CMD_REG_CODE(0x04)
#define RST_BCI CMD_REG_CODE(0x05)
#define BEG_XMIT_BRK CMD_REG_CODE(0x06)
#define END_XMIT_BRK CMD_REG_CODE(0x07)
#define ASSERT_RTSN CMD_REG_CODE(0x08)
#define NEGATE_RTSN CMD_REG_CODE(0x09)
#define SET_TIMEOUT_ON CMD_REG_CODE(0x0a)
#define SET_TIMEOUT_OFF CMD_REG_CODE(0x0c)
#define BLK_ERR_CFG CMD_REG_CODE(0x0d)
#define XMIT_XON CMD_REG_CODE(0x10)
#define XMIT_XOFF CMD_REG_CODE(0x11)
#define GWR_XON CMD_REG_CODE(0x12)
#define GWR_XOFF CMD_REG_CODE(0x13)
#define GWR_XON_DC1 CMD_REG_CODE(0x14)
#define GWR_XOFF_DC3 CMD_REG_CODE(0x15)
#define XOFF_RESUME CMD_REG_CODE(0x16)
#define XOFF_HOST CMD_REG_CODE(0x17)
#define CANCEL_XMIT CMD_REG_CODE(0x18)
#define RST_ADDR_REC CMD_REG_CODE(0x1b)
#define RST_CHIP CMD_REG_CODE(0x1e)
/* SR - Channel Status Channel */
#define RCVD_BRK 0x80
#define FRAME_ERR 0x40
#define PARITY_ERR 0x20
#define OVERRUN_ERR 0x10
#define TXEMPT 0x08
#define TXRDY 0x04
#define RXFULL 0x02
#define RXRDY 0x01
/* ISR - Interrupt Status Register */
/* IMR - Interrupt Mask Register */
#define IO_PORT_CHG_INT 0x80
#define RCVR_WDTO_INT 0x40
#define ADDR_REC_INT 0x20
#define XON_XOFF_INT 0x10
#define BRK_CHG_INT 0x04
#define RXRDY_INT 0x02
#define TXRDY_INT 0x01
/* CIR - Current Interrupt Register
*
* These defintions are not as straightforward since they are context
* specific. For instance CIR[6] can mean either transmit interrupt
* or qualify the receive interrupt error condition.
*/
#define INT_TYPE_MASK 0xc0
#define OTHER_INT 0x00
#define XMIT_INT 0x40
#define RCV_INT 0x80
#define RCV_W_ERR_INT 0xc0
#define CUR_CNT_MASK 0x38
#define OTHER_TYPE_MASK 0x38
#define CUR_CHAN_MASK 0x07
/* This is an Axcelis Carrier Board-specific macro used to convert a
* channel pointer to a pointer to the same channel (by channel index) in
* the other octart. This allows us to access the Tx part of the channel in
* "this octart" and the Rx part of the same channel index in the other
* octart.
*/
#define SAME_PCHANNEL_IN_OTHER_OCTART(pChan) \
((SC28L198_DEV_CHAN *) \
(&(sc28l198Uart[(((pChan)->uart)?0:1)].channel[(pChan)->chan].devHdr)))
/******* Channel Control Structure *****************************************
*
* This structure describes a single channel on the UART.
* Consequently, there will be N of these for each uart.
*/
typedef struct
{
DEV_HDR devHdr; /* vxWorks I/O device header */
int uart; /* Uart number for this channel */
int chan; /* Channel number in the UART */
BOOL created; /* TRUE if device has been created */
BOOL chanOpen; /* TRUE if device is currently open */
int baudRate; /* Baud rate for this channel */
int dataBits; /* Data Bits for this channel */
int stopBits; /* Stop Bits for this channel */
int parity; /* Parity for this channel */
RING_ID rdBuf; /* ring buffer for read */
RING_ID wrtBuf; /* ring buffer for write */
SEM_ID mutexSem; /* Mutual exclusion semaphore */
BOOL wrtStateBusy; /* Transmitter busy flag for TxStartUp */
volatile char *uartCommandReg; /* UART Command Register Address */
volatile char *uartRxDataReg; /* UART Rx/Tx Data Register Address */
volatile char *uartTxDataReg; /* UART Rx/Tx Data Register Address */
volatile char *uartIntStatusReg; /* UART Interrupt Status Reg. Address */
char lastCR; /* CR is a write-only reg. Track the */
/* last value written to the CR here. */
char lastIMR; /* IMR is a write-only reg. Track the */
/* last value written to the IMR here. */
} SC28L198_DEV_CHAN;
/* ******* UART Control Structure ******* */
static struct
{
BOOL exists; /* Flags presence of UART */
int drvNum; /* Device number */
SC28L198_DEV_CHAN *channel; /* Pointers to each channel data */
/* structure. */
} sc28l198Uart[SC28L198_MAX_UARTS]; /* One structure needed for each */
/* possible device. */
/* Define BAUD type, used to setup baudTable below. */
typedef struct
{
int baudRate; /* User specified baud rate */
int baudValue; /* Value to write to Clock Select Register */
} BAUD;
LOCAL BAUD baudTable[] = {
{ 50, B50},
{ 75, B75},
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -