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

📄 sc16is752.c

📁 此文件为在vxworks系统下关于串口扩展芯片16IS752驱动的BSP开发
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************
 *
 * Copyrigth(C), 2002-2005,Sanxing Tech,Co.,Ltd.
 * Filename: sc16is752.c
 * Version: V1.0
 * Description: sc16is752 drive.
 *
modification history
---------------------
* $Log: sc16is752.c,v $
* Revision 1.1  2006/10/13 04:23:54  zlm
* 增加F16R16的bsp
*
* Revision 1.1  2006/10/13 04:13:18  zlm
* 增加F8R16的bsp
*
* Revision 1.11  2006/09/18 12:32:51  zlm
* 将常用函数接口分开(extern)
*
* Revision 1.10  2006/09/13 13:27:54  zlm
* 增加taskUnlock() 和tasklock() 来保护spi对各个芯片寄存器的读写
*
* Revision 1.9  2006/09/09 01:58:35  zlm
* 根据最新硬件修改
*
* Revision 1.8  2006/09/06 06:56:31  zlm
* 修改sc16is752中断序号
*
* Revision 1.7  2006/09/05 05:03:38  zlm
* 整理对io的设置
*
* Revision 1.6  2006/09/04 14:01:40  zlm
* 修改一个bug!
*
* Revision 1.5  2006/09/04 06:23:42  zlm
* 修改一个warning!
*
* Revision 1.4  2006/09/01 09:27:54  zlm
* 全面调试通过
*
* Revision 1.3  2006/08/31 02:56:00  zlm
* sc16is752的spi模式修改
*
* Revision 1.2  2006/08/31 02:46:37  zlm
* 修改sc16is752驱动
*
* Revision 1.1  2006/08/24 09:02:26  zlm
* 添加sc16is752驱动
*
*
*******************************************************************************/
/*------------------------------------------------------------------------------
Section: Includes
------------------------------------------------------------------------------*/
#include <vxworks.h>
#include <taskLib.h>
#include <semLib.h>
#include <rngLib.h>
#include <sioLib.h>
#include <ioLib.h>
#include <timers.h>
#include "sc16is752.h"
#include "ppc860spi.h"

/*------------------------------------------------------------------------------
Section: Constant Definitions
------------------------------------------------------------------------------*/
/* Register Address */
/* -----------  Special register ------------- */                                 
#define THR       0x00             /* Transmit Holding Register */
#define RHR       0x00             /* Receive Holding Register */
#define IER       0x01             /* Interrupt Enable Register */
#define FCR       0x02             /* FIFO Control Register */
#define IIR       0x02             /* Interrupt Identification Register */
#define LCR       0x03             /* Line Control Register */

#define S_MCR     0x04             /* Modem Control Register */
#define LSR       0x05             /* Line Status Register */
#define MSR       0x06             /* Modem Status Register */
#define SPR       0x07             /* Scratchpad Register */

#define TCR       0x06             /* Transmission Control Register */
#define TLR       0x07             /* Trigger Level Register */
#define TXLVL     0x08             /* Transmit FIFO Level Register */
#define RXLVL     0x09             /* Receive FIFO Level Register */

#define IODir     0x0A             /* I/O pin Direction Register */
#define IOState   0x0B             /* I/O pin States Register */
#define IOIntEna  0x0C             /* I/O Interrupt Enable Register */
#define IOControl 0x0D             /* I/O Interrupt Enable Register */

#define EFCR      0x0F             /* Extra Features Control Register (EFCR) */

/* -----------  Special register ------------- */
#define DLL       0x00             /* Divisor Latch LSB */
#define DLH       0x01             /* Divisor Latch MSB */

/* -----------  Special register ------------- */
#define EFR       0x02             /* Enhanced Feature Register */
#define Xon1      0x04             /* Xon1 word */
#define Xon2      0x05             /* Xon2 word */
#define Xoff1     0x06             /* Xoff1 word */
#define Xoff2     0x07             /* Xoff2 word */

#define SC16IS752_FIFO_NUM     64  /* FIFO length */

#define SPI_EN_SC16IS752 spi_cs(CS_SC16IS752, CS_ON)     /* 片选SX2132 */
#define SPI_UNEN_SC16IS752 spi_cs(CS_SC16IS752, CS_OFF)  /* 取消片选SX2132 */

#define TASK_PRIORITY_SC16IS752 51       

#ifndef SETBITS
#define SETBITS(x,y,n) (x) = (n) ? ((x)|(1 << (y))) : ((x) &(~(1 << (y))))/* 设置某一位为n */
#endif

#ifndef BITS
#define BITS(x,y) (((x)>>(y))&0x01) /* 判断某位是否为1 */
#endif

#ifndef BCD2HEX
#define BCD2HEX(x) (((x) >> 4) * 10 + ((x) & 0x0F))       /*20H -> 20*/
#endif

#ifndef HEX2BCD
#define HEX2BCD(x) (((x) % 10) + ((((x) / 10) % 10) << 4))  /*20 -> 20H*/
#endif

#define SC16IS752_IRQ_ID           3/*5*/             /* Spi interrupt number */

#define MAX_IN_IO_NUM              8             /* in io count */

/* Channel Type */
#define CHANNEL_TYPE_A        0x00
#define CHANNEL_TYPE_B        0x01
#define CHANNEL_TYPE_NULL     0x02

#ifndef IO_LOW
#define IO_LOW 0
#endif

#ifndef IO_HIGH
#define IO_HIGH 1
#endif

/*------------------------------------------------------------------------------
Section: Type Definitions
------------------------------------------------------------------------------*/
typedef struct sc16is752Dev {       /* sc16is752_DEV */
        
    DEV_HDR	devHdr;                 /* equipment header struct */
    int     devId;                  /* equipment id */
    BOOL	created;                /* TRUE if this device has been created */
    BOOL	opened;                 /* TRUE if this device has been opened */
	uchar   moder_LCR;              /* uart moder register[LCR] */
	uchar   moder_DLL;              /* uart moder register[DLL] */
	uchar   moder_DLH;              /* uart moder register[DLH] */
	uchar   efcrReg;                /* Extra Features Control Register (EFCR) */ 
    uchar   fcrReg;                 /* trigger register */
    SEM_ID	syncSem;	            /* use binary semaphore to block the read serila task */
    RING_ID rngRxBuf;               /* receive buffer ring */    
    SEL_WAKEUP_LIST selWakeupList;  /* select functions */
} SC16IS752_DEV;

/* 寄存器定义 */
typedef struct sc16is752_REG {           
    unsigned char IoDir;            /* gpio direction */
    unsigned char IoState;          /* gpio pin state */
}T_SC16IS752_REG;

typedef struct sc16is752_io_event { /* T_SC16IS752_IO_EVENT */
	int nInNo;                      /* IO编号 */
	VOIDFUNCPTR pUpFunc;            /* 指定IO发生上升延变化时执行的函数指针 */
	VOIDFUNCPTR pDownFunc;          /* 指定IO发生下降延变化时执行的函数指针 */	
	int iUpArg;                     /* 事件函数的参数*/
	int iDownArg;                   /* 事件函数的参数*/
}T_SC16IS752_IO_EVENT;

/*------------------------------------------------------------------------------
Section: Local Variable
------------------------------------------------------------------------------*/
LOCAL SEM_ID s_semSc16is752irqTask;

LOCAL int sc16is752DrvNum[2]={0,0};	         /* driver number assigned to this driver */

LOCAL SC16IS752_DEV sc16is752Dev [2]; /* char equipment array */

LOCAL T_SC16IS752_REG sc16is752Reg;                      /* sc16is752 io registe */

LOCAL T_SC16IS752_IO_EVENT s_sc16is752IoEvent[MAX_IN_IO_NUM];

/*------------------------------------------------------------------------------
Section: Local Function Prototypes
------------------------------------------------------------------------------*/
LOCAL int sc16is752Open (SC16IS752_DEV * pSc16is752Dev,char *name,int mode);

LOCAL int sc16is752Close (int  sc16is752DevId);

LOCAL int sc16is752Read (int  sc16is752DevId,char * buffer,size_t maxbytes);

LOCAL int sc16is752Write(int sc16is752DevId, char * buffer, size_t nbytes);

LOCAL int sc16is752Ioctl(int sc16is752DevId, int function, int arg);

LOCAL void sc16is752IrqSR(void);

LOCAL void sc16is752irqTask(void);

LOCAL void disposeGpioEvent(void);

LOCAL void readSerialData(uchar channel);

 void writeReg(uchar regAddr, uchar channel, uchar regValue);

 uchar readReg(uchar regAddr, uchar channel);

 void writeData(uchar regAddr, uchar channel, uchar *buf, int len);

LOCAL void sc16isInit(void);

/*------------------------------------------------------------------------------
Section: Function Definitions
------------------------------------------------------------------------------*/
/*******************************************************************************
*
* sc16is752Drv - initialize the sc16is752 serial ports driver
*
* This routine initializes the sc16is752 serial ports driver, 
* performs hardware initialization of the sc16is752 serial ports.
*
* This routine should be called exactly once, before any reads, writes,
* or calls to sc16is752DevCreate().  Normally, it is called by usrRoot()
* in usrConfig.c.
*
* RETURNS: OK, or ERROR if the driver cannot be installed.
*
* SEE ALSO: sc16is752DevCreate()
*/
extern STATUS sc16is752Drv(void)
{
    int ix;
    
    s_semSc16is752irqTask = semBCreate(SEM_Q_FIFO, SEM_EMPTY);/* synchronization semaphore */
	irqEnable(SC16IS752_IRQ_ID, 1, sc16is752IrqSR, (int)NULL);
    
    /* IN IO EVENT */
	for (ix = 0; ix < MAX_IN_IO_NUM; ix++){
		s_sc16is752IoEvent[ix].pDownFunc = s_sc16is752IoEvent[ix].pUpFunc = NULL;
	}
            
    for (ix = 0; ix < 2; ix++){
        
		/* check if driver already installed */
		if (sc16is752DrvNum[ix] > 0) 
			return (OK);

        sc16is752Dev[ix].created    = FALSE;
        sc16is752Dev[ix].opened     = FALSE;
        sc16is752Dev[ix].devId      = ix;
        sc16is752Dev[ix].moder_LCR  = 0x03;
        sc16is752Dev[ix].moder_DLL  = 0x48;/* 9600 */
        sc16is752Dev[ix].moder_DLH  = 0x00;
        sc16is752Dev[ix].fcrReg     = 0x81;
        sc16is752Dev[ix].efcrReg    = 0x10;
        
    	sc16is752Dev[ix].syncSem  = semBCreate (SEM_Q_FIFO, SEM_EMPTY);

    	sc16is752Dev[ix].rngRxBuf = rngCreate(MAX_FIFO_SIZE);
    	
    	sc16is752DrvNum[ix] = iosDrvInstall (sc16is752Open, (FUNCPTR) NULL, sc16is752Open,
			       sc16is752Close, sc16is752Read, sc16is752Write, sc16is752Ioctl);
        if (ERROR == sc16is752DrvNum[ix]) return ERROR;
	}
	
	/* initiallize the sc16is752 chip */
    sc16isInit();
    
    if (taskSpawn("sc16is752irqTask", TASK_PRIORITY_SC16IS752, VX_FP_TASK,
            1024*20,(FUNCPTR)sc16is752irqTask,0,0,0,0,0,0,0,0,0,0) == ERROR){        
        return ERROR;
    }
    
	return OK;
}
/*******************************************************************************
*
* sc16is752DevCreate - create a device for an sc16is752 serial port
*
* This routine creates a device for a specified serial port.  Each port
* to be used should have exactly one device associated with it by calling
* this routine.
*
* For instance, to create the device `/Ser/0', the proper call would be:
* .CS
*     sc16is752DevCreate ("/Ser/0");
* .CE
*
* RETURNS: OK, or ERROR if the driver is not installed, the channel is
* invalid, or the device already exists.
*
* SEE ALSO: sc16is752Drv()
*/
extern STATUS sc16is752DevCreate
    (
    char *name		/* name to use for this device */    
    )
    {
    int i, rst = ERROR;
    char devName[20];
    
    for (i = 0; i < 2; i++){
        if (sc16is752DrvNum[i] <= 0){
            errnoSet (S_ioLib_NO_DRIVER);
            return (ERROR);
        }
    
        /* if this device already exists, don't create it */
        if (sc16is752Dev[i].created) 
            return (ERROR);
        
        /* initialize a select() wake-up list for sc16is752Dev */
        selWakeupListInit(&sc16is752Dev[i].selWakeupList);
        
        /* mark the device as created, and add the device to the I/O system */
        sc16is752Dev[i].created = TRUE;
        
        sprintf(devName, "%s/%d", name, i);
        
        rst = iosDevAdd (&sc16is752Dev[i].devHdr, devName, sc16is752DrvNum[i]);
        if (ERROR == rst) {
            return ERROR;
        }
    }
	return OK;
    }
/******************************************************************************
*
* sc16is752_read - read data from a gpio.
*
* INPUTS:
    int    sc16is752DevId :serial descriptor from which to read
    char * buffer         :pointer to buffer to receive bytes    
*
* RETURNS:
*  STATUS: if succeed return OK, else return ERROR;
*
******************************************************************************/
extern STATUS sc16is752_read (int sc16is752DevId,char * buffer)
{
    if (sc16is752DevId - SC16IS752_IO_PA0 > MAX_IN_IO_NUM) return ERROR;
    
    if (BITS(sc16is752Reg.IoDir, sc16is752DevId - SC16IS752_IO_PA0) == IO_IN) {
        *buffer = BITS(sc16is752Reg.IoState, sc16is752DevId - SC16IS752_IO_PA0);
        return OK;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -