⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sc16is752.c

📁 此文件为在vxworks系统下关于串口扩展芯片16IS752驱动的BSP开发
💻 C
📖 第 1 页 / 共 3 页
字号:
    }
    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 + -