📄 sc16is752.c
字号:
}
return ERROR;
}
/******************************************************************************
*
* sc16is752_write - write data to a gpio or AD
*
* INPUTS:
int sc16is752DevId :serial descriptor from which to write
int data :pointer to buffer to receive bytes
*
* RETURNS:
* STATUS: if succeed return OK, else return ERROR;
*
******************************************************************************/
extern STATUS sc16is752_write (int sc16is752DevId, int data)
{
uchar regValue;
if (data > 1) return ERROR;
if (sc16is752DevId - SC16IS752_IO_PA0 > MAX_IN_IO_NUM) return ERROR;
if (BITS(sc16is752Reg.IoDir, sc16is752DevId - SC16IS752_IO_PA0) == IO_OUT) {
regValue = readReg(IOState, CHANNEL_TYPE_A);
SETBITS(regValue, (sc16is752DevId - SC16IS752_IO_PA0), data);
writeReg(IOState, CHANNEL_TYPE_A, regValue);
return OK;
}
return ERROR;
}
/******************************************************************************
*
* sc16is752_event - 配置指定IO状态变化时触发的事件处理函数,只对输入IO有效
*
* INPUTS:
* int f_iIoNo : IO编号
* FUNCPTR f_pUpFun : 指定IO发生上升延变化时执行的函数指针
* int f_iUpArg : 指定IO发生上升延变化时执行的函数指针参数
* FUNCPTR f_pDownFun : 指定IO发生下降延变化时执行的函数指针
* int f_iDownArg : 指定IO发生下降延变化时执行的函数指针参数
*
* RETURNS:
* STATUS: 配置成功,返回OK;指定的IO不存在,返回ERROR
*
******************************************************************************/
extern STATUS sc16is752_event (int f_iIoNo,VOIDFUNCPTR f_pUpFun, int f_iUpArg,
VOIDFUNCPTR f_pDownFun, int f_iDownArg)
{
if (f_iIoNo - SC16IS752_IO_PA0 > MAX_IN_IO_NUM) return ERROR;
if ((NULL == f_pUpFun) && (NULL == f_pDownFun)){
return ERROR;
}
s_sc16is752IoEvent[f_iIoNo - SC16IS752_IO_PA0].nInNo = f_iIoNo;
s_sc16is752IoEvent[f_iIoNo - SC16IS752_IO_PA0].pUpFunc = f_pUpFun;
s_sc16is752IoEvent[f_iIoNo - SC16IS752_IO_PA0].pDownFunc = f_pDownFun;
s_sc16is752IoEvent[f_iIoNo - SC16IS752_IO_PA0].iUpArg = f_iUpArg;
s_sc16is752IoEvent[f_iIoNo - SC16IS752_IO_PA0].iDownArg = f_iDownArg;
return OK;
}
/******************************************************************************
*
* sc16is752_ioctl -perform an I/O control function
*
* INPUTS:
* int sc16is752DevId : file descriptor
int function : function code
int arg : arbitrary argument
*
* RETURNS:
* The return value of the driver, or ERROR if the file descriptor does not exist.
*
******************************************************************************/
extern int sc16is752_ioctl(int sc16is752DevId, int function, int arg)
{
STATUS status = ERROR;
switch (function){
case FIODIRSET:
if (sc16is752DevId - SC16IS752_IO_PA0 > MAX_IN_IO_NUM) return ERROR;
if ((arg == IO_IN) || (arg == IO_OUT)) {
SETBITS(sc16is752Reg.IoDir, sc16is752DevId - SC16IS752_IO_PA0, arg);
writeReg(IODir, CHANNEL_TYPE_A, sc16is752Reg.IoDir);
status = OK;
}
break;
case FIOAUTO485:
if (sc16is752DevId > SC16IS752_PORTB) break;
if ((IO_AUTO485_OFF == arg) || (IO_AUTO485_ON == arg)) {
SETBITS(sc16is752Dev[sc16is752DevId].efcrReg, 4, arg);
writeReg(EFCR, sc16is752DevId, sc16is752Dev[sc16is752DevId].efcrReg);
status = OK;
}
break;
default:
break;
}
return (status);
}
/******************************************************************************
*
* sc16is752Open - open serial port.
*
* INPUTS:
SC16IS752_DEV * pSc16is752Dev :the point of the serial port equipment.
char *name :name of the equipment.
int mode :mode of file to create (UNIX chmod style)
* RETURNS:
* The equipment descriptor number, or ERROR if a equipment name is not specified,
* the device does not exist, no equipment descriptors are available, or the driver
returns ERROR.
*
******************************************************************************/
static int sc16is752Open (SC16IS752_DEV * pSc16is752Dev,char *name,int mode)
{
/* Check whether the equipment open */
if (pSc16is752Dev->opened){
return ERROR;
}
pSc16is752Dev->opened = TRUE;
return ((int)pSc16is752Dev);
}
/******************************************************************************
*
* sc16is752Close - close serial port.
*
* INPUTS:
int sc16is752DevId :serial descriptor from which to close
*
* RETURNS:
* The status of the driver close routine, or ERROR if the file descriptor is invalid.
*
******************************************************************************/
static int sc16is752Close (int sc16is752DevId)
{
SC16IS752_DEV * pSc16is752dev = (SC16IS752_DEV *)sc16is752DevId;
if ((SC16IS752_DEV *)NULL == pSc16is752dev){
return ERROR;
}
pSc16is752dev->opened = FALSE;
return OK;
}
/******************************************************************************
*
* sc16is752Read - read bytes from a serial
*
* INPUTS:
int sc16is752DevId :serial descriptor from which to read
char * buffer :pointer to buffer to receive bytes
size_t maxbytes :max no. of bytes to read into buffer
* RETURNS:
* int: the length of returns data.
*
******************************************************************************/
static int sc16is752Read (int sc16is752DevId,char * buffer,size_t maxbytes)
{
SC16IS752_DEV * pSc16is752dev = (SC16IS752_DEV *)sc16is752DevId;
if ((SC16IS752_DEV *)NULL == pSc16is752dev){
return ERROR;
}
/* if the buffer is empty then pend the read task by the semaphore */
if (FALSE == rngIsEmpty(pSc16is752dev->rngRxBuf)){
semGive(pSc16is752dev->syncSem);
}
semTake(pSc16is752dev->syncSem, WAIT_FOREVER);
return rngBufGet(pSc16is752dev->rngRxBuf, buffer, maxbytes);
}
/******************************************************************************
*
* sc16is752Write -write bytes to a serial
*
* INPUTS:
int sc16is752DevId :serial descriptor from which to write
char * buffer : buffer containing bytes to be written
size_t nbytes :number of bytes to write
* RETURNS:
* int: the length of buffer.
*
******************************************************************************/
static int sc16is752Write(int sc16is752DevId, char * buffer, size_t nbytes)
{
SC16IS752_DEV * pSc16is752dev = (SC16IS752_DEV *)sc16is752DevId;
char *p;
int j, count = 0;
if ((SC16IS752_DEV *)NULL == pSc16is752dev){
return ERROR;
}
p = buffer;
count = (nbytes / SC16IS752_FIFO_NUM) + ((nbytes % SC16IS752_FIFO_NUM) ? 1 : 0);
for (j = 0; j < count; j++){
if (j == count - 1){
writeData(THR, pSc16is752dev->devId, p, nbytes % SC16IS752_FIFO_NUM);
p += nbytes % SC16IS752_FIFO_NUM;
} else {
writeData(THR, pSc16is752dev->devId, p, SC16IS752_FIFO_NUM);
p += SC16IS752_FIFO_NUM;
}
while(readReg(TXLVL, pSc16is752dev->devId) != SC16IS752_FIFO_NUM){
taskDelay(1);
}
}
return nbytes;
}
/******************************************************************************
*
* sc16is752Ioctl -perform an I/O control function
* #define CSIZE 0xc bits 3 and 4 encode the character size
* #define CS5 0x0 5 bits
* #define CS6 0x4 6 bits
* #define CS7 0x8 7 bits
* #define CS8 0xc 8 bits
* #define HUPCL 0x10 hang up on last close
* #define STOPB 0x20 send two stop bits (else one)
* #define PARENB 0x40 parity detection enabled (else disabled)
* #define PARODD 0x80 odd parity (else even)
*
* INPUTS:
* int sc16is752DevId : file descriptor
int function : function code
int arg : arbitrary argument
*
* RETURNS:
* The return value of the driver, or ERROR if the file descriptor does not exist.
*
******************************************************************************/
static int sc16is752Ioctl(int sc16is752DevId, int function, int arg)
{
STATUS status = EIO;
uchar moder = 0;
SC16IS752_DEV * pSc16is752dev = (SC16IS752_DEV *)sc16is752DevId;
unsigned short dl;
switch (function){
case FIOWAKEUP:
semGive(pSc16is752dev->syncSem);
status = OK;
break;
case FIOSELECT:
selNodeAdd(&pSc16is752dev->selWakeupList, (SEL_WAKEUP_NODE *)arg);
selWakeup((SEL_WAKEUP_NODE *)arg);
status = OK;
break;
case FIOUNSELECT:
selNodeDelete(&pSc16is752dev->selWakeupList, (SEL_WAKEUP_NODE *)arg);
status = OK;
break;
case FIONREAD:
*(int *)arg = rngNBytes(pSc16is752dev->rngRxBuf);
status = OK;
break;
case FIOFLUSH:
case FIORFLUSH:
rngFlush(pSc16is752dev->rngRxBuf);
status = OK;
break;
case SIO_BAUD_SET:
case FIOBAUDRATE:
dl = SC16IS752_FREQ / (arg * 16);
pSc16is752dev->moder_DLL = (uchar)dl;
pSc16is752dev->moder_DLH = (uchar)(dl >> 8);
/* first enable the LCR[7] */
writeReg(LCR, pSc16is752dev->devId, 0x80);
writeReg(DLL, pSc16is752dev->devId, pSc16is752dev->moder_DLL);
writeReg(DLH, pSc16is752dev->devId, pSc16is752dev->moder_DLH);
writeReg(LCR, pSc16is752dev->devId, pSc16is752dev->moder_LCR & 0x7F);
status = OK;
break;
case SIO_BAUD_GET:
dl = pSc16is752dev->moder_DLL + (pSc16is752dev->moder_DLH << 8);
*(int *)arg = SC16IS752_FREQ / (dl * 16);
status = OK;
break;
/* configure serial line for PSMR modified (extended) options,see page 22-16(mpc860um.dbf)
* using ioctl (TCSETS)
* see "ppc860sccsio.c" ppc860SccIoctl() for details.
*/
case SIO_HW_OPTS_SET:
moder = moder & 0xFC;/* Character length. */
moder |= ((uchar)((arg & 0x3000) >> 12) & 0x03);
moder = moder & 0xFB;/* Stop length. */
moder |= ((uchar)((arg & 0x4000) >> 12) & 0x04);
moder = moder & 0xF7;/* Parity enable. */
moder |= ((uchar)((arg & 0x0010) >> 1) & 0x08);
moder = moder & 0xEF;/* Parity mode. */
if (0x0000 == (arg & 0x0003)){
moder |= 0x00;
} else if (0x0002 == (arg & 0x0003)){
moder |= 0x10;
}
pSc16is752dev->moder_LCR = moder;
writeReg(LCR, pSc16is752dev->devId, pSc16is752dev->moder_LCR);
status = OK;
break;
default:
errnoSet (S_ioLib_UNKNOWN_REQUEST);
status = ENOSYS;
break;
}
return (status);
}
/******************************************************************************
*
* sc16is752IrqSR - handle an interrupt.
*
* INPUTS:
* void.
*
* RETURNS:
* void.
*
******************************************************************************/
static void sc16is752IrqSR(void)
{
clearIrq(SC16IS752_IRQ_ID);
semGive(s_semSc16is752irqTask);
}
/******************************************************************************
*
* sc16is752irqTask - interrupt serivxe task.
*
* INPUTS:
* void.
*
* RETURNS:
* void.
*
******************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -