Chinaunix首页 | 论坛 | 博客
  • 博客访问: 396674
  • 博文数量: 118
  • 博客积分: 294
  • 博客等级: 二等列兵
  • 技术积分: 667
  • 用 户 组: 普通用户
  • 注册时间: 2010-09-16 20:31
文章分类

全部博文(118)

文章存档

2014年(3)

2012年(25)

2011年(90)

分类:

2011-08-23 15:00:53

由于产品板中没有PCF8563驱动,需要写驱动程序。

PCF8563驱动其实并不多,主要就是两个函数。
pcf8563_get_datetime 和 pcf8563_set_datetime。 写完这两个也是基本完成了。
参考rtc_pcf8563.c rtc_pcf8563.rar   代码改写。

改写后部分内容如下:

pcf8563.h内容:
  1. #ifndef _PCF8563_H
  2. #define _PCF8563_H    



  3. #define RTC_RD_TIME 0
  4. #define RTC_SET_TIME 1


  5. typedef struct
  6. {
  7.     int tm_sec;
  8.     int tm_min;
  9.     int tm_hour;
  10.     int tm_mday;
  11.     int tm_wday;
  12.     int tm_mon;
  13.     int tm_year;
  14. }rtc_time_t;

  15. #endif



pcf8563.c内容:

主要也就是pcf8563_get_datetime 和 pcf8563_set_datetime两个函数和一个控制调用函数(pcf8563_rtc_ioctl),现就列这几个吧,其他就不贴出来了。
一些宏定义:
  1. #define PCF8563_REG_ST1 0x00 /* status */
  2. #define PCF8563_REG_ST2 0x01

  3. #define PCF8563_REG_SC 0x02 /* datetime */
  4. #define PCF8563_REG_MN 0x03
  5. #define PCF8563_REG_HR 0x04
  6. #define PCF8563_REG_DM 0x05
  7. #define PCF8563_REG_DW 0x06
  8. #define PCF8563_REG_MO 0x07
  9. #define PCF8563_REG_YR 0x08

  10. #define PCF8563_REG_AMN 0x09 /* alarm */
  11. #define PCF8563_REG_AHR 0x0A
  12. #define PCF8563_REG_ADM 0x0B
  13. #define PCF8563_REG_ADW 0x0C

  14. #define PCF8563_REG_CLKO 0x0D /* clock out */
  15. #define PCF8563_REG_TMRC 0x0E /* timer control */
  16. #define PCF8563_REG_TMR 0x0F /* timer */

  17. #define PCF8563_SC_LV 0x80 /* low voltage */
  18. #define PCF8563_MO_C 0x80 /* century */

  19. #define I2C_PCF8563 0xA2

static inline
int bin2bcd (int x)
{
return (x%10) | ((x/10) << 4);
}


static inline
int bcd2bin (int x)
{
return (x >> 4) * 10 + (x & 0x0f);
}


读RTC pcf8563数据:
  1. static int pcf8563_get_datetime(int i2c_devaddress , rtc_time_t *tm)
  2. {
  3.         unsigned char buf[PCF8563_REG_YR+1] = { PCF8563_REG_ST1 };
  4.         /* status */
  5.         //buf[PCF8563_REG_ST1] = hi_i2c_read(i2c_devaddress, PCF8563_REG_ST1);
  6.         //buf[PCF8563_REG_ST2] = hi_i2c_read(i2c_devaddress, PCF8563_REG_ST2);
  7.          
  8.         /* datetime */
  9.         buf[PCF8563_REG_SC] = hi_i2c_read(i2c_devaddress, PCF8563_REG_SC);
  10.         buf[PCF8563_REG_MN] = hi_i2c_read(i2c_devaddress, PCF8563_REG_MN);
  11.         buf[PCF8563_REG_HR] = hi_i2c_read(i2c_devaddress, PCF8563_REG_HR);
  12.         buf[PCF8563_REG_DM] = hi_i2c_read(i2c_devaddress, PCF8563_REG_DM);
  13.         buf[PCF8563_REG_DW] = hi_i2c_read(i2c_devaddress, PCF8563_REG_DW);
  14.         buf[PCF8563_REG_MO] = hi_i2c_read(i2c_devaddress, PCF8563_REG_MO);
  15.         buf[PCF8563_REG_YR] = hi_i2c_read(i2c_devaddress, PCF8563_REG_YR);
  16.         buf[PCF8563_REG_ST1] = hi_i2c_read(i2c_devaddress, PCF8563_REG_ST1);
  17.         
  18.         tm->tm_sec = bcd2bin(buf[PCF8563_REG_SC] & 0x7F);
  19.         tm->tm_min = bcd2bin(buf[PCF8563_REG_MN] & 0x7F);
  20.         tm->tm_hour = bcd2bin(buf[PCF8563_REG_HR] & 0x3F); /* rtc hr 0-23 */
  21.         tm->tm_mday = bcd2bin(buf[PCF8563_REG_DM] & 0x3F);
  22.         tm->tm_wday = buf[PCF8563_REG_DW] & 0x07;
  23.         tm->tm_mon = bcd2bin(buf[PCF8563_REG_MO] & 0x1F) - 1; /* rtc mn 1-12 */
  24.         tm->tm_year = bcd2bin(buf[PCF8563_REG_YR]);

  25.       #if 0
  26.         printk("%s: secs=%d, mins=%d, hours=%d, "
  27.                 "mday=%d, mon=%d, year=%d, wday=%d\n",
  28.                 __func__,
  29.                 tm->tm_sec, tm->tm_min, tm->tm_hour,
  30.                 tm->tm_mday, tm->tm_mon, tm->tm_year, tm->tm_wday);
  31.       #endif
  32.         
  33.         // Century bit. C = 0; indicates the century is 20xx.
  34.      // C = 1; indicates the century is 19xx.
  35.         if(buf[PCF8563_REG_MO] & PCF8563_MO_C)
  36.             tm->tm_year += 1900;
  37.         else
  38.             tm->tm_year += 2000;
  39.         return 0;
  40. }

写RTC pcf8563数据:
  1. static int pcf8563_set_datetime(int i2c_devaddress , rtc_time_t tm)
  2. {
  3.         unsigned char buf[9];
  4.         int Centurybit;
  5. #if 0
  6.         printk("%s: secs=%d, mins=%d, hours=%d, "
  7.                 "mday=%d, mon=%d, year=%d, wday=%d\n",
  8.                 __func__,
  9.                 tm.tm_sec, tm.tm_min, tm.tm_hour,
  10.                 tm.tm_mday, tm.tm_mon, tm.tm_year, tm.tm_wday);
  11. #endif

  12.         /* hours, minutes and seconds */
  13.         buf[PCF8563_REG_SC] = bin2bcd(tm.tm_sec);
  14.         buf[PCF8563_REG_MN] = bin2bcd(tm.tm_min);
  15.         buf[PCF8563_REG_HR] = bin2bcd(tm.tm_hour);

  16.         buf[PCF8563_REG_DM] = bin2bcd(tm.tm_mday);

  17.         /* month, 1 - 12 */
  18.         buf[PCF8563_REG_MO] = bin2bcd(tm.tm_mon + 1);

  19.         /* year and century */
  20.         buf[PCF8563_REG_YR] = bin2bcd(tm.tm_year % 100);
  21.         
  22.         if (tm.tm_year >= 1900 && tm.tm_year < 2000)
  23.             Centurybit = PCF8563_MO_C;
  24.         else if (tm.tm_year >= 2000 && tm.tm_year < 3000)
  25.             Centurybit = 0;
  26.         else
  27.             return -1;
  28.         
  29.         // Century bit. C = 0; indicates the century is 20xx.
  30.      // C = 1; indicates the century is 19xx.    
  31.         buf[PCF8563_REG_MO] |= Centurybit; //add Century bit    

  32.         buf[PCF8563_REG_DW] = tm.tm_wday & 0x07;

  33.         /* write register's data */
  34.         hi_i2c_write(i2c_devaddress, PCF8563_REG_SC, buf[PCF8563_REG_SC]);
  35.         hi_i2c_write(i2c_devaddress, PCF8563_REG_MN, buf[PCF8563_REG_MN]);
  36.         hi_i2c_write(i2c_devaddress, PCF8563_REG_HR, buf[PCF8563_REG_HR]);
  37.         hi_i2c_write(i2c_devaddress, PCF8563_REG_DM, buf[PCF8563_REG_DM]);
  38.         hi_i2c_write(i2c_devaddress, PCF8563_REG_MO, buf[PCF8563_REG_MO]);
  39.         hi_i2c_write(i2c_devaddress, PCF8563_REG_YR, buf[PCF8563_REG_YR]);
  40.         hi_i2c_write(i2c_devaddress, PCF8563_REG_DW, buf[PCF8563_REG_DW]);

  41.         return 0;
  42. }

相关控制调用函数:
  1. static int pcf8563_rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  2. {
  3. rtc_time_t tm;
  4. switch (cmd)
  5. {
  6. case RTC_RD_TIME:
  7. pcf8563_get_datetime(i2c_pcf8563, &tm);
  8. return copy_to_user((void *)arg, &tm, sizeof(tm)) ? -EFAULT : 0;
  9. case RTC_SET_TIME:
  10. if (copy_from_user(&tm, (struct rtc_time_t *) arg, sizeof(tm)))
  11. return -EFAULT;
  12. return pcf8563_set_datetime(i2c_pcf8563, tm);
  13. }
  14. return 0;
  15. }
  16. static struct file_operations pcf8563_fops = {
  17. .owner = THIS_MODULE,
  18. .ioctl = pcf8563_rtc_ioctl,
  19. .open = pcf8563_open,
  20. .release = pcf8563_close
  21. };
  22. static struct miscdevice pcf8563_dev = {
  23. MISC_DYNAMIC_MINOR,
  24. "pcf8563",
  25. &pcf8563_fops,
  26. };

阅读(2838) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~