?? sngks32csio.c
字號:
/* sngks32cSio.c - Samsung KS32C serial driver *//* Copyright 1984-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01c,30nov01,m_h Save pChan->baudRate when setting baud01b,26apr01,m_h convert tabs to spaces for readability01a,12apr01,m_h created from snds100 template.*//*DESCRIPTIONThis is the serial I/O driver for Samsung's KS32C50100 microprocessor which is anARM based processor with several integrated peripherals. It has an interruptcontroller, two 32-bit timers, one Ethernet controller,two HDLC controllers,one IIC controller, general purpose I/O ports, and a 2 channel DMA controller.The 2 UART channels integrated with the processor are controlled by thisdriver. Both the UARTs can work in interrupt mode as well as DMA mode.This driver supports only the interrupt mode for the UARTs.All the UART registers are accessible as 32-bit integers from the internalsystem registers. The macros SNGKS32C_REG_READ and SNGKS32C_REG_WRITE read and write32-bit integers from and to the given addresses. SNGKS32C_SIO_DEFAULT_BAUD isdefined to 38400 in this file. This is the default baud rate with which the UART channels will be initialized. The channels are also initialized with one start bit, one stop bit, 8 bit data and no parity bits.The driver is typically only called only by the BSP. The directly callableroutines in this module are sngks32cDevInit(), sngks32cDevInit2(), sngks32cIntRcv(), sngks32cIntTx(), and sngks32cIntErr().The BSP calls sngks32cDevInit() to initialize or reset the device.It connects the driver's interrupt handlers (sngks32cIntRcv(), sngks32cIntTx(),and sngks32cIntErr()), using intConnect().After connecting the interrupt handlers, the BSP calls sngks32cDevInit2()to inform the driver that interrupt mode operation is now possible.INCLUDES:sngks32cSio.h sioLib.hSEE ALSO:<Samsung KS32C50100 User's Manual>*/#include "vxWorks.h"#include "sioLib.h"#include "intLib.h"#include "errno.h"#include "sngks32cSio.h"#include "ioLib.h"#define SNGKS32C_BAUD_MIN 1200#define SNGKS32C_BAUD_MAX 460860#define SNGKS32C_SIO_DEFAULT_BAUD 38400/* Hardware abstraction macros *//* local defines */#ifndef SNGKS32C_SIO_REG_READ#define SNGKS32C_SIO_REG_READ(pChan, reg, result) \ ((result) = (*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg))))#endif /*SNGKS32C_SIO_REG_READ*/#ifndef SNGKS32C_SIO_REG_WRITE#define SNGKS32C_SIO_REG_WRITE(pChan, reg, data) \ ((*(volatile UINT32 *)((UINT32)(pChan)->regs + (reg))) = (data))#endif /*SNGKS32C_SIO_REG_WRITE*//* for backward compatibility */#ifndef SIO_HUP# define SIO_OPEN 0x100A /* open channel, raise DTR, RTS */# define SIO_HUP 0x100B /* hang-up, lower DTR, RTS */#endif/* forward static declarations */LOCAL int sngks32cTxStartup (SIO_CHAN * pSioChan);LOCAL int sngks32cCallbackInstall (SIO_CHAN *pSioChan, int callbackType, STATUS (*callback)(), void *callbackArg);LOCAL int sngks32cPollOutput (SIO_CHAN *pSioChan, char outChar);LOCAL int sngks32cPollInput (SIO_CHAN *pSioChan, char *thisChar);LOCAL int sngks32cIoctl (SIO_CHAN *pSioChan, int request, void *arg);LOCAL STATUS dummyCallback (void);/* local variables */LOCAL SIO_DRV_FUNCS sngks32cSioDrvFuncs = { sngks32cIoctl, sngks32cTxStartup, sngks32cCallbackInstall, sngks32cPollInput, sngks32cPollOutput };LOCAL BOOL sngks32cIntrMode = FALSE; /* interrupt mode allowed flag *//******************************************************************************** sngks32cDevInit - initialize a SNGKS32C_DUSART** This routine initializes the driver* function pointers and then resets the chip in a quiescent state.* The BSP must have already initialized all the device addresses and the* baudFreq fields in the SNGKS32C_DUSART structure before passing it to* this routine.** RETURNS: N/A*/void sngks32cDevInit ( SNGKS32C_CHAN * pChan ) { /* initialize each channel's driver function pointers */ pChan->sio.pDrvFuncs = &sngks32cSioDrvFuncs; /* install dummy driver callbacks */ pChan->getTxChar = dummyCallback; pChan->putRcvChar = dummyCallback; /* reset the chip */ SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_ULCON,(INT_CLK | PARITY_NONE | ONE_STOP | WORD_LEN)); /* setting polled mode is one way to make the device quiet */ sngks32cIoctl ((SIO_CHAN *)pChan, SIO_MODE_SET, (void *)SIO_MODE_POLL); sngks32cIoctl ((SIO_CHAN *)pChan, SIO_BAUD_SET, (void *)SNGKS32C_SIO_DEFAULT_BAUD); }/******************************************************************************** sngks32cDevInit2 - initialize a SNGKS32C_DUSART, part 2** This routine is called by the BSP after interrupts have been connected.* The driver can now operate in interrupt mode. Before this routine is* called only polled mode operations should be allowed.** RETURNS: N/A* ARGSUSED*/void sngks32cDevInit2 ( SNGKS32C_CHAN * pChan /* device to initialize */ ) { char outchar = '\0'; UINT32 status; /* * Dummy write to TXBUF to start TX empty interrupt */ SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UTXBUF,outchar); /* Interrupt mode is allowed */ SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UCON,UCON_RX|UCON_TX|UCON_BREAK); SNGKS32C_SIO_REG_READ(pChan,SNGKS32C_USTAT, status); while ((status & USTAT_TX_READY) != USTAT_TX_READY) ; SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UCON,UCON_RX|UCON_TX); sngks32cIntrMode = TRUE; }/******************************************************************************** sngks32cIntRcv - handle a channel's receive-character interrupt** RETURNS: N/A*/ void sngks32cIntRcv ( SNGKS32C_CHAN * pChan /* channel generating the interrupt */ ) { char inChar; UINT32 status; /* * Grab the input character from the chip and hand it off via a * callback. For chips with input FIFO's it is more efficient * to empty the entire FIFO here. */ SNGKS32C_SIO_REG_READ(pChan,SNGKS32C_USTAT, status); if((status & USTAT_RX_READY) == USTAT_RX_READY) { SNGKS32C_SIO_REG_READ(pChan,SNGKS32C_URXBUF, inChar); (*pChan->putRcvChar) (pChan->putRcvArg, inChar); } }/******************************************************************************** sngks32cIntTx - handle a channels transmitter-ready interrupt** RETURNS: N/A*/ void sngks32cIntTx ( SNGKS32C_CHAN * pChan /* channel generating the interrupt */ ) { char outChar; UINT32 status; /* * If there's a character to transmit then write it out, else reset * the transmitter. For chips with output FIFO's it is more efficient * to fill the entire FIFO here. */ SNGKS32C_SIO_REG_READ(pChan,SNGKS32C_USTAT, status); if((status & USTAT_TX_READY) != USTAT_TX_READY) return; if ((*pChan->getTxChar) (pChan->getTxArg, &outChar) != ERROR) SNGKS32C_SIO_REG_WRITE(pChan, SNGKS32C_UTXBUF, outChar); else { intDisable (pChan->intLevelTx); *(UINT32 *) SNGKS32C_INTPEND = (1 << pChan->intLevelTx); } }/******************************************************************************** sngks32cTxStartup - start the interrupt transmitter** RETURNS: OK on success, ENOSYS if the device is polled-only, or* EIO on hardware error.*/LOCAL int sngks32cTxStartup ( SIO_CHAN * pSioChan /* channel to start */ ) { SNGKS32C_CHAN * pChan = (SNGKS32C_CHAN *)pSioChan; *(UINT32 *) SNGKS32C_INTPENDTST |= (1 << pChan->intLevelTx); intEnable (pChan->intLevelTx); return (OK); }/******************************************************************************** sngks32cCallbackInstall - install ISR callbacks to get/put chars** This driver allows interrupt callbacks for transmitting characters* and receiving characters. In general, drivers may support other* types of callbacks too.** RETURNS: OK on success, or ENOSYS for an unsupported callback type.*/ LOCAL int sngks32cCallbackInstall ( SIO_CHAN * pSioChan, /* channel */ int callbackType, /* type of callback */ STATUS (*callback)(), /* callback */ void * callbackArg /* parameter to callback */ ) { SNGKS32C_CHAN * pChan = (SNGKS32C_CHAN *)pSioChan; switch (callbackType) { case SIO_CALLBACK_GET_TX_CHAR: pChan->getTxChar = callback; pChan->getTxArg = callbackArg; return (OK); case SIO_CALLBACK_PUT_RCV_CHAR: pChan->putRcvChar = callback; pChan->putRcvArg = callbackArg; return (OK); default: return (ENOSYS); } }/********************************************************************************* sngks32cPollOutput - output a character in polled mode** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the output buffer if full. ENOSYS if the device is* interrupt-only.*/LOCAL int sngks32cPollOutput ( SIO_CHAN *pSioChan, char outChar ) { SNGKS32C_CHAN * pChan = (SNGKS32C_CHAN *)pSioChan; UINT32 status; /* is the transmitter ready to accept a character? */ SNGKS32C_SIO_REG_READ (pChan, SNGKS32C_USTAT, status); if ((status & USTAT_TX_READY) == 0x00) return (EAGAIN); /* write out the character */ SNGKS32C_SIO_REG_WRITE(pChan, SNGKS32C_UTXBUF, outChar); return (OK); }/******************************************************************************** sngks32cPollInput - poll the device for input** RETURNS: OK if a character arrived, EIO on device error, EAGAIN* if the input buffer if empty, ENOSYS if the device is* interrupt-only.*/LOCAL int sngks32cPollInput ( SIO_CHAN * pSioChan, char * thisChar ) { SNGKS32C_CHAN * pChan = (SNGKS32C_CHAN *)pSioChan; UINT32 status; SNGKS32C_SIO_REG_READ (pChan,SNGKS32C_USTAT, status); if ((status & USTAT_RX_AVAIL) == 0x00) return (EAGAIN); /* no input available at this time */ /* got a character */ SNGKS32C_SIO_REG_READ(pChan, SNGKS32C_URXBUF, *thisChar); return (OK); }/******************************************************************************** sngks32cModeSet - toggle between interrupt and polled mode** RETURNS: OK on success, EIO on unsupported mode.*/LOCAL int sngks32cModeSet ( SNGKS32C_CHAN * pChan, /* channel */ uint_t newMode /* new mode */ ) { UINT32 temp; if ((newMode != SIO_MODE_POLL) && (newMode != SIO_MODE_INT)) return (EIO); /* Don't enter interrupt mode unless it is allowed. */ if ((newMode == SIO_MODE_INT) && (!sngks32cIntrMode)) return (EIO); /* set the new mode */ pChan->mode = newMode; if (pChan->mode == SIO_MODE_INT) { SNGKS32C_SIO_REG_READ(pChan, SNGKS32C_UCON, temp); temp &=UCON_RX_TX_RESET; /**Reset RX and TX mode bits*/ temp |= (UCON_RX|UCON_TX); SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UCON, temp); intEnable(pChan->intLevelRx); } else { SNGKS32C_SIO_REG_READ(pChan, SNGKS32C_UCON, temp); temp &=UCON_RX_TX_RESET; /**Reset RX and TX mode bits*/ temp |= (UCON_RX|UCON_TX); SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UCON, temp);
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -