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

📄 externrtcdriver.c

📁 在uClinux下的外部实时时钟读写驱动
💻 C
字号:
/*================================================================================
 Module Name:   externrtcdriver.c 
 General Description:     
==================================================================================
                        Honeywell Confidential Proprietary             
                  ACS - Security (Asia Pacific) R&D Software Operations             
                  (c) Copyright Honeywell 2006, All Rights Reserved             
 Revision History:          
                   Modification     Tracking    
 Author                 Date        Ver Number     Description of Changes
 ----------------   ------------    ----------   ------------------------- 
 Chen Kang      Date: 2006-7-13   Version: ver 1.0.0  

 
 Portability: Indicate if this module is portable to other compilers or 
 platforms. If not, indicate specific reasons why is it not portable.
 ==================================================================================
                                     INCLUDE FILES                   
 ==================================================================================*/

#include "externrtcdriver.h"
#include "LPC2294.h"

/* ==================================================================================
                                     GLOBAL VARIABLES                   
 ==================================================================================*/

volatile uint8  I2C_sla;           // 从机地址
volatile uint8  I2C_suba;          // 子地址
volatile uint8  *I2C_buf;          // 数据缓冲区指针 (读操作时会被更改)
volatile uint8  I2C_num;           // 操作数据个数 (会被更改)
volatile uint8  I2C_end;           // 操作结束标志,为1时表示操作结束,为0xFF时表示操作失败 (会被设置)
volatile uint8  I2C_suba_en;       // 子地址使能控制,读操作时请设置为1,写操作时请设置为2 (会被更改)

/* ==================================================================================
                                     LOCAL FUNCTIONS DECLARATIONS                   
 ==================================================================================*/


/* =======================================================
 Function Name:***** RTC_init() *****
 Description:     ***** RTC_init() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    ***** NONE *****
 pointer para:   ***** NONE *****
 Return type:  ***** int *****
 Others:         ***** NONE *****
 ==========================================================*/
static int RTC_init();

/* =======================================================
 Function Name:***** RTC_read() *****
 Description:     ***** RTC_read() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    *****  size_t count; *****
 pointer para:   ***** struct file *filp; char *buf;loff_t *f_pos; *****
 Return type:  ***** ssize_t *****
 Others:         ***** NONE *****
 ==========================================================*/
static ssize_t RTC_read(struct file *filp, char *buf, size_t count,loff_t *f_pos);


/* =======================================================
 Function Name:***** RTC_write() *****
 Description:     ***** RTC_write() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    *****  size_t count; *****
 pointer para:   ***** struct file *filp; char *buf;loff_t *f_pos; *****
 Return type:  ***** ssize_t *****
 Others:         ***** NONE *****
 ==========================================================*/
static ssize_t RTC_write(struct file *filp, char *buf, size_t count,loff_t *f_pos);


/* =======================================================
 Function Name:***** RTC_open() *****
 Description:     ***** RTC_open() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    ***** NONE *****
 pointer para:   ***** struct inode *inode; struct file *filp; *****
 Return type:  ***** int *****
 Others:         ***** NONE *****
 ==========================================================*/
static int RTC_open(struct inode *inode, struct file *filp);


/* =======================================================
 Function Name:***** RTC_irq_handle() *****
 Description:     ***** RTC_irq_handle() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    ***** void; *****
 pointer para:   ***** NONE *****
 Return type:  ***** int *****
 Others:         ***** NONE *****
 ==========================================================*/
static int RTC_irq_handle(void);

static struct file_operations RTC_fops =        /* driver info  */
{    
      owner:      THIS_MODULE,
      open:      RTC_open,
      read:      RTC_read,    
      write:      RTC_write,
};

/* =======================================================
 Function Name:***** RTC_init() *****
 Description:     ***** RTC_init() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    ***** NONE *****
 pointer para:   ***** NONE *****
 Return type:  ***** int *****
 Others:         ***** NONE *****
 ==========================================================*/
static int RTC_init()
{
   int ret;	
   I2SCLH = I2SCLL = 55;            // 晶振为11.0592MHz,Fpclk = 2.7648MHz
   
   /* 设置I2C中断允许 */
   //VICIntSelect = 0x00000000;		// 设置所有通道为IRQ中断
   //VICVectCntl0 = 0x29;				// I2C通道分配到IRQ slot 0,即优先级最高
   //VICVectAddr0 = (int)IRQ_I2C;	    // 设置I2C中断向量地址	
   //VICIntEnable |= 0x0200;           // 使能I2C中断 
   PINSEL0 &= 0xffffff0f; //set to 0000
   PINSEL0 |= 0x00000050;//set to 0101

   ret = register_chrdev(MAJOR_NR,  DEVICE_NAME,  &RTC_fops);    	
   if (ret < 0)
   {	    	
   	printk(KERN_ERR DEVICE_NAME ":init failed. %d\n", MAJOR_NR);	    	
	return ret;	
   }	    	
   printk(KERN_WARNING DEVICE_NAME ": init OK.\n");
   
   ret = request_irq(LPC22xx_INTERRUPT_I2C,RTC_irq_handle,SA_INTERRUPT,DEVICE_NAME,NULL);    	
   if (ret< 0)    	
   {    				
	printk(KERN_ERR DEVICE_NAME ":request irq failed. \n");    		
	return ret;    	 
   }    	
   printk(KERN_WARNING DEVICE_NAME ": register irq OK.\n");    	
   
   return 0;
}

/* =======================================================
 Function Name:***** RTC_open() *****
 Description:     ***** RTC_open() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    ***** NONE *****
 pointer para:   ***** struct inode *inode; struct file *filp; *****
 Return type:  ***** int *****
 Others:         ***** NONE *****
 ==========================================================*/
static int RTC_open(struct inode *inode, struct file *filp)
{
    return 0;
}


/* =======================================================
 Function Name:***** RTC_irq_handle() *****
 Description:     ***** RTC_irq_handle() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    ***** void; *****
 pointer para:   ***** NONE *****
 Return type:  ***** int *****
 Others:         ***** NONE *****
 ==========================================================*/
static int RTC_irq_handle(void)
{
   uint8  sta;
   sta = I2STAT;                    // 读出I2C状态字
   
   switch(sta)
   {  
      case  0x08:                   // 己发送起始条件
           if(1==I2C_suba_en)
           {
		    I2DAT = I2C_sla&0xFE;    // 指定子地址读时,先写入地址
           }
	     else 
	     {
		 	I2DAT = I2C_sla;                     // 否则直接发送从机地址
	     }
	     I2CONCLR = 0x28;        // SI=0
            break;
            
      case  0x10:
            I2DAT = I2C_sla;        // 重启动总线后,发送从地址
            I2CONCLR = 0x28;        // SI=0
            break;
   
      case  0x18:                   // 已发送SLA+W,并已接收应答
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  
               if(I2C_num>0)
               {  
                  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28; 
                  I2C_num--;
               }
               else
               {  
                  I2CONSET = 0x10;  // 无数据发送,结束总线
                  I2CONCLR = 0x28;
                  I2C_end = 1;      // 设置总线操作结束标志
               }
               break;
            }
            if(1==I2C_suba_en)      // 发送子地址
            {  
               I2DAT = I2C_suba;
               I2CONCLR = 0x28;
            }
            if(2==I2C_suba_en)
            {  
               I2DAT = I2C_suba;
               I2CONCLR = 0x28;
               I2C_suba_en = 0;     // 子地址己处理
            }
            break;
            
      case  0x28:                   // 已发送I2C数据,并接收到应答
            if(0==I2C_suba_en)      // 无子地址,则直接发送数据
            {  
               if(I2C_num>0)
               {  
                  I2DAT = *I2C_buf++;
                  I2CONCLR = 0x28; 
                  I2C_num--;
               }
               else
               {  
                  I2CONSET = 0x10;  // 无数据发送,结束总线
                  I2CONCLR = 0x28;
                  I2C_end = 1; 
               }
               break;
            }
            if(1==I2C_suba_en)      // 若是指定地址读,则重新启动总线
            {  
               I2CONSET = 0x20;
               I2CONCLR = 0x08;
               I2C_suba_en = 0;     // 子地址己处理
            }
            break;
   
   
      case  0x20:
      case  0x30:
      case  0x38:
            I2CONCLR = 0x28;        // 总线进入不可寻址从模式
            I2C_end = 0xFF;         // 总线出错,设置标志
            break;
   
   
      case  0x40:                   // 己发送SLA+R,并已接收到应答
            if(1==I2C_num)          // 最后一字节,接收数据后发送非应答信号
            {  
                I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else                    // 接收数据并发送应答信号
            {  
               I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
               I2CONCLR = 0x28;
            }
            break;
            
      case  0x50:
            *I2C_buf++ = I2DAT;     // 读取数据
            I2C_num--;
            if(1==I2C_num)
            {  
                I2CONCLR = 0x2C;     // AA=0,接收到数据后产生非应答
            }
            else
            {   
                I2CONSET = 0x04;     // AA=1,接收到数据后产生应答
                I2CONCLR = 0x28;
            }
            break;
      
      case  0x58:
            *I2C_buf++ = I2DAT;     // 读取最后一字节数据
            I2CONSET = 0x10;        // 结束总线
            I2CONCLR = 0x28;
            I2C_end = 1; 
            break;
      
      case  0x48:
            I2CONCLR = 0x28;        // 总线进入不可寻址从模式
            I2C_end = 0xFF; 
            break;
            
      default: 
            break;
   }
   VICVectAddr = 0x00;              // 中断处理结束
  
   return(1);
}


/* =======================================================
 Function Name:***** RTC_read() *****
 Description:     ***** RTC_read() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    *****  size_t count; *****
 pointer para:   ***** struct file *filp; char *buf;loff_t *f_pos; *****
 Return type:  ***** ssize_t *****
 Others:         ***** NONE *****
 ==========================================================*/
static ssize_t RTC_read(struct file *filp, char *buf, size_t count,loff_t *f_pos)
{ 
   /* 参数设置 */
   
   I2C_sla = CSI24WC02+1;
   I2C_suba = 0x02;
   I2C_buf = buf;
   I2C_num = count;
   I2C_suba_en = 1;
   I2C_end = 0;
   
   I2CONCLR = 0x2C;
   I2CONSET = 0x60;             // 设置为主机,并启动总线
   
   while(1)
   {
       if(1==I2C_end)
       { 
           return(0);
       }
   }    
}


/* =======================================================
 Function Name:***** RTC_write() *****
 Description:     ***** RTC_write() entry func *****
 Created By:     ***** Chen Kang *****
 Created Date:  ***** 2006-7-13 *****
 Calls:             ***** NONE *****
 Called By:       ***** NONE *****
 normal para:    *****  size_t count; *****
 pointer para:   ***** struct file *filp; char *buf;loff_t *f_pos; *****
 Return type:  ***** ssize_t *****
 Others:         ***** NONE *****
 ==========================================================*/
static ssize_t RTC_write(struct file *filp, char *buf, size_t count,loff_t *f_pos)
{
   I2C_sla = CSI24WC02;
   I2C_suba = 0x02;
   I2C_buf = buf;
   I2C_num = count;
   I2C_suba_en = 2;
   I2C_end = 0;
   
   I2CONCLR = 0x2C;
   I2CONSET = 0x60;             // 设置为主机,并启动总线
   
   while(1)
   {
       if(1==I2C_end)
       { 
           return(0);
       }
   }    
}

module_init(RTC_init);

⌨️ 快捷键说明

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