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

📄 8025.c

📁 RX8025 linux 驱动程序 RX8025 linux 驱动程序
💻 C
📖 第 1 页 / 共 2 页
字号:
//*----------------------------------------------------------------------------
//*         ATMEL Microcontroller Software Support  -  ROUSSET  -
//*----------------------------------------------------------------------------
//* The software is delivered "AS IS" without warranty or condition of any
//* kind, either express, implied or statutory. This includes without
//* limitation any warranty or condition with respect to merchantability or
//* fitness for any particular purpose, or against the infringements of
//* intellectual property rights of others.
//*----------------------------------------------------------------------------
//* File Name           : main.c
//* Object              : main application written in C
//* Creation            : GGi
//*----------------------------------------------------------------------------

// Include Standard filesR8025_MAJOR, DEVICENAME
#include <linux/clk.h>#include <asm/arch/at91_twi.h>#include <asm/hardware.h>#include <linux/kernel.h>	    /* We're doing kernel work */#include <linux/module.h>	    /* Specifically, a module */#include <linux/sched.h>#include <linux/init.h>		/* Needed for the macros */#include <linux/fs.h>#include <linux/interrupt.h>	/* We want an interrupt */#include <linux/cdev.h>#include <asm/io.h>#include <linux/delay.h>      /*Needed for udelay(),mdelay()*/#include <linux/keyboard.h>#include <linux/irq.h>#include <linux/time.h>#include <linux/unistd.h>#include <asm/system.h>#include <asm/uaccess.h>#include <asm/arch/gpio.h>#include <asm/arch/at91_pmc.h>#include <asm/arch/at91_twi.h>
#define R8025_MAJOR 239#define DEVICENAME "R8025"#define AT91_R8025_ADDRESS  (0x32<<16) #define AT91_PIOA_BASE		AT91_PIOA + AT91_BASE_SYS#define AT91_PIOC_BASE		AT91_PIOC + AT91_BASE_SYS#define AT91_PIOB_BASE          AT91_PIOB + AT91_BASE_SYS#define AT91_PMC_BASE		AT91_PMC + AT91_BASE_SYS#define AT91_PA7_TWD		(unsigned int) (0x1 << 7)#define AT91_PA8_TWCK		(unsigned int) (0x1 << 8)#define TWI_NULL		0xff#define TWI_READ		0x1#define TWI_WRITE		0x0/************************设置时间标志*************************/#define Hour24 1 				//24小时制#define Hour12 0 				//12小时制#define Settime 1				//单独设置时间#define Setweek 2				//单独设置星期#define Setdate 3				//单独设置年月日#define Setall  0				//全部设置#define R8025_DEBUG1//#define R8025_DEBUG//#undef R8025_DEBUGtypedef struct times{	unsigned int sec;	unsigned int min;	unsigned int hour;	unsigned int week;	unsigned int day;	unsigned int month;	unsigned int year;	}TIME;// TWI 初始化void AT9_TWI_init (void);// 使能 TWI 时钟void AT91_PMC_EnableTWIClock(void);// 重启 TWIvoid AT91_TWI_Reset(void);// 配置 TWIvoid AT91_TWI_Configure(void);//设置 TWI 时钟void AT91_TWI_SetClock (void);static void __iomem *twi_base;static void __iomem *aic_base;static void __iomem *pmc_base;
#define at91_pmc_read(reg)		__raw_readl(pmc_base + (reg))#define at91_pmc_write(reg, val)	__raw_writel((val), pmc_base + (reg))#define at91_twi_read(reg)		__raw_readl(twi_base + (reg))#define at91_twi_write(reg, val)	__raw_writel((val), twi_base + (reg))/* 读取 时间 */int get_8025_data(TIME *times);
/* 设置时间 */
int settime(TIME *times);
/* 设置星期 */
int setweek(TIME *times);/* 设置年月日 */
int setdate(TIME *times);unsigned int flag = 0;			//设置时间选择标志unsigned int hourmode = 0;		//时间格式标志

/*******************************************************************************
 *函数:时钟芯片读,用来读出时间,日期,星期
 *参数:char *data :用来存放读到的寄存器的直 *功能:该函数是R8025芯片IIC读的第三种方法,不指定寄存器地址,直接读。 *      读出的值存放在调用函数传来的data中 *
 *返回直:没有意义
********************************************************************************/
int T11_TWI_ReadSingle(char *data)
{
    unsigned int status=0;
	int i;	unsigned int error = 0, ready = 0;	//AT9_TWI_init();
#ifdef R8025_DEBUG
	printk(KERN_ALERT "In: ReadSingle\n");
#endif	mdelay(2);
    /* 使能主机模式  */	at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);

    /* 设置模式寄存器 = 从级地址   |   读写位 */
	at91_twi_write(AT91_TWI_MMR, AT91_R8025_ADDRESS  | AT91_TWI_MREAD);
	/* 开始接收 */
	at91_twi_write(AT91_TWI_CR, AT91_TWI_START);

	for(i=0;i<16;i++)	
	{
#if 1	/* 等待应答 */		status = at91_twi_read(AT91_TWI_SR);
    	while ((status & AT91_TWI_NACK) == AT91_TWI_NACK)
    	{			error++;			status = at91_twi_read(AT91_TWI_SR);	
		}    		
    	/*  等待接收ready 位 被置  */
  		 status = at91_twi_read(AT91_TWI_SR);
   		 while ((status & AT91_TWI_RXRDY) != AT91_TWI_RXRDY)
    	{
    		status = at91_twi_read(AT91_TWI_SR);		}		if (++ready > 10000)		{    		return 2;		}				
   		
#endif	/* 接收数据 */
    	data[i] = at91_twi_read(AT91_TWI_RHR);

  	}  
    /* 接收完毕 置停止位 */
 	at91_twi_write(AT91_TWI_CR, AT91_TWI_STOP);

  /*  等待发送结束  */
 	status = at91_twi_read(AT91_TWI_SR);
   	while (!(status & AT91_TWI_TXCOMP))
   	{
     	status = at91_twi_read(AT91_TWI_SR);		if (++ready > 10000)		{    		return 2;		}
   	}   
	mdelay(4);#ifdef R8025_DEBUG		printk(KERN_ALERT "Out: ReadSingle\n");
#endif
    return error;
}
/*******************************************************************************
 *函数:时钟芯片写寄存器函数,用来设置时间 日期 星期
 *参数:char *data :用来存放将要设置的寄存器的直,NumOfBytes:表示要写的字节数 *功能:这个函数使用来设置R8025的寄存器,主要是0-6寄存器,于时间相关。     *
 *返回直:没有意义
********************************************************************************/

int T11_TWI_WriteMultiple(char *data,unsigned int NumOfBytes)
{
    unsigned int status=0 ,Count,end = 0 ;	unsigned int error = 0, ready = 0;	//AT9_TWI_init();#ifdef R8025_DEBUG
	printk(KERN_ALERT "In: Write the 8025 regs\n");	#endif

    /* 使能主机模式 */
  	at91_twi_write(AT91_TWI_CR, AT91_TWI_MSEN);

    /* 设置模式寄存器 =  从级地址 | 读写位 */
    at91_twi_write(AT91_TWI_MMR, AT91_R8025_ADDRESS & ~AT91_TWI_MREAD);

    /*开始发送*/
	at91_twi_write(AT91_TWI_CR, AT91_TWI_START);	
   /* 发送数据 */
   for ( Count=0; Count < NumOfBytes ;Count++ )
   {
       /* 写 发送保持寄存器  */	
	   	at91_twi_write(AT91_TWI_THR, *data++);
		while (!end)
		{
       		/*等待应答 */
           	status = at91_twi_read(AT91_TWI_SR);
			if ((status & AT91_TWI_NACK) == AT91_TWI_NACK)
           	{					error++;
           	    end=1;
           	}
		
           /*  等待发送 ready  */
			if ((status & AT91_TWI_TXRDY) == AT91_TWI_TXRDY)
			{				end = 1;			}			if (++ready > 10000)			{    			return 2;			}					}
	}	
    /* 等待发送完成  */

 	status = at91_twi_read(AT91_TWI_SR);
   	while (!(status & AT91_TWI_TXCOMP))
   	{
     	status = at91_twi_read(AT91_TWI_SR);		if (++ready > 10000)		{    		return 2;		}
   	}  	mdelay(4);
#ifdef R8025_DEBUG    printk(KERN_ALERT "0ut: Write the 8025 regs\n");	
#endif    	return error;
}/********************************************************* *	进制转换函数: *	参数:unsigned int n *	功能:被时间设置函数所调用,将TIME 的成员由 整形 变为 16进制的 字符形, *		然后把字符型的数据赋值给8025的8位寄存器。 *	返回值:字符型数据 **********************************************************/unsigned char rec(unsigned int n){	unsigned int count=0;	int flag = 0;		// 十位数	int flag1 = 0;	//个位数  	/* 数据要小于100 */	flag = (n&0xf0)>>4;	flag1 = n&0x0f;	count = (16*flag+flag1);    return (unsigned char) count;}/********************************************************* *	写入寄存器后:读出比较函数: *	参数:	char ch:写进寄存器的值 *			int kind	:寄存器编号 *	功能:当写入寄存器后,把寄存器的值读取出来,查看是否写入正确 *		正确,返回0,不正确:返回1  调用函数通过其返回直,判断 *		要重新写寄存器。 *	返回值:0表示写入正确,1表示写入错误 **********************************************************/int compile(char ch,int kind){	char regs[16];		/* 读出寄存器的直 */	T11_TWI_ReadSingle(regs);	mdelay(4);		return (ch == regs[kind]) ? 0 : 1;} /********************************************************* *	写控制寄存器E: *	参数:void *	功能:	在设置R8025的时间寄存器之前,必须先写该寄存器, *			然后在设置时间,hourmode是全局变量,由用户ioctl() *			传递值,表示时间显示是:24小时制、12小时制。 *	返回值:无意义 **********************************************************/int setEreg(void){	char ch[2];		ch[0] = 0xe0;
	if(hourmode == Hour24)	{		ch[1] = 0x20;	}	else{		ch[1] = 0x10;		}	/*	调用写入函数,把值写到E寄存器 */
	while(T11_TWI_WriteMultiple(ch,2) != 0);		return 0;}	/*******************************************************************************
 *函数:读出时间日期星期的函数
 *参数:TIME *times :用来存放时间日期星期的结构体 *功能:调用8025芯片读寄存器的直存放在regs中:把对应的   *		时间 日子 星期存放在结构体中对应的位置上,每次都读取两次, *		比较值是否相同,相同:返回,不相同:继续读,直到相同为止
 *返回直:h返回给被掉函数,判断读取成功与否。
********************************************************************************/int  get_8025_data(TIME *times){
	char regs[16] = "";	char regs1[16] ="";	int i;	int flag1 = 0;	
	do{		/* 第一次读出寄存器的直 */		T11_TWI_ReadSingle(regs1);		/* 判断 读取的数据是否正确,不正确 */		if(regs1[2] > 0x59 || regs1[3] >0x59 || regs1[4] > 0x24 || regs1[5] > 0x6 || 				regs1[6] > 0x31 || regs1[7] > 0x12 || regs1[8] > 0x99)		{			flag1 = 1;			//AT9_TWI_init();		}		/* 第二次读出寄存器的直 */		T11_TWI_ReadSingle(regs);					/* 比较两次读取的值是否相同 */		for(i=3;i<8;i++)		{			if(regs[i] == regs1[i])			{				flag1 = 0;				}			else{			//不相同,继续读取				flag1 = 1;				//AT9_TWI_init();				break;							}		}				/* 判断 读取的数据是否正确 */		if(regs[2] > 0x59 || regs[3] >0x59 || regs[4] > 0x24 || regs[5] > 0x6 || 				regs[6] > 0x31 || regs[7] > 0x12 || regs[8] > 0x99)		{			flag1 = 1;			//AT9_TWI_init();		}			}while(flag1);	flag1 = 0;	/* 对应位置存放 时间 */	times->hour = regs[4];	times->min = regs[3];	times->sec = regs[2];
	/* 对应位置存放 日期 */	times->year = regs[8];	times->month = regs[7];	times->day = regs[6];	/* 对应位置存放 星期 */	times->week = regs[5];#ifdef R8025_DEBUG	printk("The time is %2x:%2x:%2x\n",times->hour,times->min,times->sec);	printk("The date is %2x:%2x:%2x\n",times->year,times->month,times->day);	printk("The week is %2x\n",times->week);#endif	return 0;	
 }/*******************************************************************************
 *函数:设置时间的函数

⌨️ 快捷键说明

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