📄 s3c2410sio.c
字号:
/* 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.
*/
if ((arg != SIO_MODE_POLL) && (arg != SIO_MODE_INT))
{
status = EIO;
break;
}
oldlevel = intLock ();
if (arg == SIO_MODE_INT)
{
/* Enable appropriate interrupt */
intEnable (pChan->level);
if(pChan==&s2410SioChan[0])
{
rINTSUBMSK=(rINTSUBMSK|0x7)&0x7FA;
}else if(pChan==&s2410SioChan[1])
{
rINTSUBMSK=(rINTSUBMSK|0x38)&0x7D7;
}else
status=EIO;
}
else
{
/* Disable the interrupt */
intDisable (pChan->level);
}
pChan->channelMode = arg;
intUnlock (oldlevel);
break;
case SIO_MODE_GET:
/* Get the current mode and return OK */
*(int *)arg = pChan->channelMode;
break;
case SIO_AVAIL_MODES_GET:
/* Get the available modes and return OK */
*(int *)arg = SIO_MODE_INT | SIO_MODE_POLL;
break;
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.
*/
break;
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).
*/
break;
default:
status = ENOSYS;
}
return status;
}
/*******************************************************************************
*
* s2410SioInt - handle an interrupt
*
* This routine handles interrupts from the USART.
*
* RETURNS: N/A
*/
void s2410SioInt
(
)
{
UINT32 ch; /* Possible char to be in/output */
UINT32 errStatus,rxtxStatus,temp,chNO;
S2410_SIO_CHAN * pChan;
/*find the which channel cause the interrupt*/
temp = rINTOFFSET;
/* Uart_Printf("rINTOFFSET=%x\n",rINTOFFSET);*/
switch(temp)
{
case INT_LVL_UART0:
chNO = 0;
pChan = &s2410SioChan[0];/* ptr to S2410_SIO_CHAN describing this chan */
break;
case INT_LVL_UART1:
chNO = 1;
pChan = &s2410SioChan[1];/* ptr to S2410_SIO_CHAN describing this chan */
break;
default:
return;
}
/* read error status register */
S2410_UART_REG_READ(pChan, S2410_UERSTAT, errStatus);
/* Uart_Printf("errStatus=%d\n",errStatus);*/
if (errStatus & (UERSTAT_FMR_ERR| UERSTAT_OVERRUN_ERR))
{
s2410SioIntErrs++;
if(errStatus & UERSTAT_OVERRUN_ERR)
{
/* S2410_UART_REG_READ(pChan, S2410_URXH, ch);read character */
if( chNO==0)
{
ch=RdURXH0();
}else if(chNO==1)
{
ch=RdURXH1();
}
}
if( chNO==0)
{
rSUBSRCPND = 1<<2;
}else if(chNO==1)
{
rSUBSRCPND = 1<<5;
}
}
/*read rx tx status register*/
S2410_UART_REG_READ(pChan,S2410_UTRSTAT,rxtxStatus);
/* Uart_Printf("rxtxStatus=%d\n",rxtxStatus);*/
if(rxtxStatus&UTRSTAT_RXBUFFER_DATA_RDY)
{
if( chNO==0)
{
rSUBSRCPND=1<<0;
ch=RdURXH0();
}else if(chNO==1)
{
rSUBSRCPND=1<<3;
ch=RdURXH1();
}
/*S2410_UART_REG_READ(pChan, S2410_URXH, ch); read character */
(*pChan->putRcvChar) (pChan->putRcvArg, (char)ch); /* pass it on */
}
if(rxtxStatus&UTRSTAT_TXBUFFER_EMPTY)
{
/* Uart_Printf("in TxBuffer Empty interrupt\n");*/
if ((*pChan->getTxChar) (pChan->getTxArg, &ch) != ERROR)
{
if( chNO==0)
{
rSUBSRCPND=1<<1;
WrUTXH0(ch);
}else if(chNO==1)
{
rSUBSRCPND=1<<4;
WrUTXH1(ch);
}
/*S2410_UART_REG_WRITE(pChan, S2410_UTXH, ch); tx char */
}
else
{
/*Uart_Printf("no more chars to send\n");*/
/* no more chars to send - disable transmitter interrupts */
if( chNO==0)
{
rINTSUBMSK=(rINTSUBMSK|(1<<1));
}else if(chNO==1)
{
rINTSUBMSK=(rINTSUBMSK|(1<<4));
}
}
}
}
/*******************************************************************************
*
* s2410SioTxStartup - transmitter startup routine
*
* Call interrupt level char output routine and enable interrupt
*
* RETURNS: OK on success, ENOSYS if the device is polled-only, or
* EIO on hardware error.
*/
LOCAL int s2410SioTxStartup
(
SIO_CHAN * pSioChan /* ptr to SIO_CHAN describing this channel */
)
{
S2410_SIO_CHAN * pChan = (S2410_SIO_CHAN *)pSioChan;
if (pChan->channelMode == SIO_MODE_INT)
{
/* Enable Transmitter interrupts */
if(pChan==&s2410SioChan[0])
{
rINTSUBMSK=(rINTSUBMSK&(~((UINT32)1<<1)));
}else if(pChan==&s2410SioChan[1])
{
rINTSUBMSK=(rINTSUBMSK&(~((UINT32)1<<4)));
}else
return ENOSYS;
return OK;
}
return ENOSYS;
}
/******************************************************************************
*
* s2410SioPollOutput - output a character in polled mode.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the output buffer is full, ENOSYS if the device is interrupt-only.
*/
LOCAL int s2410SioPollOutput
(
SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
char outChar /* char to output */
)
{
S2410_SIO_CHAN * pChan = (S2410_SIO_CHAN *)pSioChan;
UINT32 pollStatus;
S2410_UART_REG_READ (pChan, S2410_UTRSTAT, pollStatus);
/* is the transmitter ready to accept a character? */
if ((pollStatus & UTRSTAT_TXBUFFER_EMPTY) == 0)
return EAGAIN;
/* write out the character */
WrUTXH0(outChar);
/*S2410_UART_REG_WRITE(pChan, S2410_UTXH, outChar); transmit character */
return OK;
}
/******************************************************************************
*
* s2410SioPollInput - poll the device for input.
*
* RETURNS: OK if a character arrived, EIO on device error, EAGAIN
* if the input buffer is empty, ENOSYS if the device is interrupt-only.
*/
LOCAL int s2410SioPollInput
(
SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
char * thisChar /* pointer to where to return character */
)
{
S2410_SIO_CHAN * pChan = (S2410_SIO_CHAN *)pSioChan;
UINT32 pollStatus;
S2410_UART_REG_READ (pChan, S2410_UTRSTAT, pollStatus);
if ((pollStatus & UTRSTAT_RXBUFFER_DATA_RDY) == 0)
return EAGAIN;
/* got a character */
*thisChar=RdURXH0();
/*S2410_UART_REG_READ (pChan, S2410_URXH, *thisChar);*/
return OK;
}
/******************************************************************************
*
* s2410SioCallbackInstall - install ISR callbacks to get/put chars.
*
* This routine installs interrupt callbacks for transmitting characters
* and receiving characters.
*
* RETURNS: OK on success, or ENOSYS for an unsupported callback type.
*
*/
LOCAL int s2410SioCallbackInstall
(
SIO_CHAN * pSioChan, /* ptr to SIO_CHAN describing this channel */
int callbackType, /* type of callback */
STATUS (*callback)(), /* callback */
void * callbackArg /* parameter to callback */
)
{
S2410_SIO_CHAN * pChan = (S2410_SIO_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;
}
}
#endif /* INCLUDE_SERIAL */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -