📄 sngks32csio.c
字号:
*/
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);
intDisable (pChan->intLevelTx);
intDisable (pChan->intLevelRx);
}
return (OK);
}
/*******************************************************************************
*
* sngks32cHup - hang up the modem control lines
*
* Resets the RTS and DTR signals.
*
* RETURNS: OK
*/
LOCAL STATUS sngks32cHup
(
SNGKS32C_CHAN * pChan /* pointer to channel */
)
{
FAST int oldlevel; /* current interrupt level mask */
oldlevel = intLock ();
/* set RTS and DTR low */
/* SNGKS32C_SIO_REG_WRITE(pChan, SNGKS32C_USTAT, USTAT_DTR_LOW); */
intUnlock (oldlevel);
return (OK);
}
/*******************************************************************************
*
* sngks32cOpen - Set the modem control lines
*
* Set the modem control lines(RTS, DTR) TRUE if not already set.
*
* RETURNS: OK
*/
LOCAL STATUS sngks32cOpen
(
SNGKS32C_CHAN * pChan /* pointer to channel */
)
{
FAST int oldlevel; /* current interrupt level mask */
oldlevel = intLock ();
/* set RTS and DTR active */
/* SNGKS32C_SIO_REG_WRITE(pChan, SNGKS32C_USTAT, USTAT_DTR_HIGH); */
intUnlock (oldlevel);
return (OK);
}
/******************************************************************************
*
* sngks32cOptSet - set hardware options
*
* This routine sets up the hardware according to the specified option
* argument. If the hardware cannot support a particular option value, then
* it should ignore that portion of the request.
*
* RETURNS: OK upon success, or EIO for invalid arguments.
*/
LOCAL int sngks32cOptSet
(
SNGKS32C_CHAN * pChan, /* channel */
uint_t newOpts /* new options */
)
{
UINT8 dataBits = 0x03;
UINT8 stopBits = 0x00;
BOOL hdweFlowCtrl=TRUE;
BOOL rcvrEnable = TRUE;
int lvl;
UINT8 temp=PARITY_NONE;
UINT32 result;
if (pChan == NULL || newOpts & 0xffffff00)
return EIO;
/* do nothing if options already set */
if (pChan->options == newOpts)
return OK;
/* ignore requests for unsupported options */
/* decode individual request elements */
switch (newOpts & CSIZE)
{
case CS5:
dataBits = 0x00; break;
case CS6:
dataBits = 0x01; break;
case CS7:
dataBits = 0x02; break;
default:
case CS8:
dataBits = 0x03; break;
}
if (newOpts & STOPB)
stopBits = 0x04;
else
stopBits = 0x00;
switch (newOpts & (PARENB|PARODD))
{
case PARENB|PARODD:
/* enable odd parity */
temp=PARITY_ODD;
break;
case PARENB:
/* enable even parity */
temp=PARITY_EVEN;
break;
case PARODD:
/* invalid mode, not normally used. */
break;
default:
case 0:
temp=PARITY_NONE ;/* no parity */
break;
}
if (newOpts & CLOCAL)
{
/* clocal disables hardware flow control */
hdweFlowCtrl = FALSE;
}
if ((newOpts & CREAD) == 0)
rcvrEnable = FALSE;
lvl = intLock ();
/*
* Reset the device according to dataBits, stopBits, hdweFlowCtrl,
* rcvrEnable, and parity selections.
*/
SNGKS32C_SIO_REG_READ(pChan, SNGKS32C_ULCON, result);
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_ULCON,(result|dataBits|temp|stopBits));
intUnlock (lvl);
pChan->options = newOpts;
return (OK);
}
/*******************************************************************************
*
* sngks32cIoctl - special device control
*
* This routine handles the IOCTL messages from the user. It supports commands
* to get/set baud rate, mode(INT,POLL), hardware options(parity, number of
* data bits) and modem control(RTS/CTS and DTR/DSR handshakes).
* The ioctl commands SIO_HUP and SIO_OPEN are used to implement the HUPCL(hang
* up on last close) function.
*
* As on a UNIX system, requesting a baud rate of zero is translated into
* a hangup request. The DTR and RTS lines are dropped. This should cause
* a connected modem to drop the connection. The SIO_HUP command will only
* hangup if the HUPCL option is active. The SIO_OPEN function will raise
* DTR and RTS lines whenever it is called. Use the BAUD_RATE=0 function
* to hangup when HUPCL is not active.
*
* The CLOCAL option will disable hardware flow control. When selected,
* hardware flow control is not used. When not selected hardware flow control
* is based on the RTS/CTS signals. CTS is the clear to send input
* from the other end. It must be true for this end to begin sending new
* characters. In most drivers, the RTS signal will be assumed to be connected
* to the opposite end's CTS signal and can be used to control output from
* the other end. Raising RTS asserts CTS at the other end and the other end
* can send data. Lowering RTS de-asserts CTS and the other end will stop
* sending data. (This is non-EIA defined use of RTS).
*
* RETURNS: OK on success, ENOSYS on unsupported request, EIO on failed
* request.
*/
LOCAL int sngks32cIoctl
(
SIO_CHAN * pSioChan, /* device to control */
int request, /* request code */
void * someArg /* some argument */
)
{
SNGKS32C_CHAN *pChan = (SNGKS32C_CHAN *) pSioChan;
int oldlevel; /* current interrupt level mask */
int arg = (int)someArg;
switch (request)
{
case SIO_BAUD_SET:
/*
* like unix, a baud request for 0 is really a request to
* hangup.
*/
if (arg == 0)
return sngks32cHup (pChan);
/*
* Set the baud rate. Return EIO for an invalid baud rate, or
* OK on success.
*/
if (arg < SNGKS32C_BAUD_MIN || arg > SNGKS32C_BAUD_MAX)
{
return (EIO);
}
/* Calculate the baud rate constant for the new baud rate */
switch(arg)
{
case 1200:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_1200|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 2400:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_2400|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 4800:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_4800|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 9600:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_9600|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 19200:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_19200|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 38400:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_38400|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 57600:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_57600|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
case 115200:
/* disable interrupts during chip access */
oldlevel = intLock ();
SNGKS32C_SIO_REG_WRITE(pChan,SNGKS32C_UBRDIV,SNGKS32C_CNT0_115200|SNGKS32C_CNT1_VAL);
intUnlock (oldlevel);
pChan->baudRate=arg;
return (OK);
default:
return(EIO);
}
break;
case SIO_BAUD_GET:
/* Get the baud rate and return OK */
*(int *)arg = pChan->baudRate;
break;
case SIO_MODE_SET:
/*
* Set the mode (e.g., to interrupt or polled). Return OK
* or EIO for an unknown or unsupported mode.
*/
return (sngks32cModeSet (pChan, arg));
case SIO_MODE_GET:
/* Get the current mode and return OK. */
*(int *)arg = pChan->mode;
return (OK);
case SIO_AVAIL_MODES_GET:
/* Get the available modes and return OK. */
*(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
return (OK);
case SIO_HW_OPTS_SET:
/*
* Optional command to set the hardware options (as defined
* in sioLib.h).
* Return OK, or ENOSYS if this command is not implemented.
* Note: several hardware options are specified at once.
* This routine should set as many as it can and then return
* OK. The SIO_HW_OPTS_GET is used to find out which options
* were actually set.
*/
return (sngks32cOptSet (pChan, arg));
case SIO_HW_OPTS_GET:
/*
* Optional command to get the hardware options (as defined
* in sioLib.h). Return OK or ENOSYS if this command is not
* implemented. Note: if this command is unimplemented, it
* will be assumed that the driver options are CREAD | CS8
* (e.g., eight data bits, one stop bit, no parity, ints enabled).
*/
*(int *)arg = pChan->options;
return (OK);
case SIO_HUP:
/* check if hupcl option is enabled */
if (pChan->options & HUPCL)
return (sngks32cHup (pChan));
return (OK);
case SIO_OPEN:
return (sngks32cOpen (pChan)); /* always open */
default:
return (ENOSYS);
}
return (ENOSYS);
}
/*******************************************************************************
*
* dummyCallback - dummy callback routine
*
* RETURNS: ERROR.
*/
LOCAL STATUS dummyCallback (void)
{
return (ERROR);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -