📄 8025.c
字号:
//*----------------------------------------------------------------------------
//* 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 + -