ds1743.c
上传用户:yuanda199
上传日期:2022-06-26
资源大小:412k
文件大小:5k
源码类别:

VxWorks

开发平台:

C/C++

  1. /*
  2.  *
  3.  * DS1743 TOD Driver
  4.  *
  5.  * The DS1743 is an 8K NVRAM starting at offset DS1743_BASE_ADDR and
  6.  * continuing for 8184 bytes. After that starts the Time-Of-Day (TOD)
  7.  * registers which are used to set/get the internal date/time functions.
  8.  *
  9.  * This module implements Y2K compliance by taking full year numbers
  10.  * and translating back and forth from the TOD 2-digit year.
  11.  *
  12.  * NOTE: for proper interaction with an operating system, the TOD should
  13.  * be used to store Universal Coordinated Time (GMT) and timezone
  14.  * conversions should be used.
  15.  *
  16.  * Here is a diagram of the memory layout:
  17.  *
  18.  * +---------------------------------------------+ BASE
  19.  * | Non-volatile memory                         | .
  20.  * |                                             | .
  21.  * | (8184 bytes of Non-volatile memory)         | .
  22.  * |                                             | .
  23.  * +---------------------------------------------+ BASE + 8K - 8
  24.  * | Control                                     |
  25.  * +---------------------------------------------+ BASE + 8K - 7
  26.  * | Seconds                                     |
  27.  * +---------------------------------------------+ BASE + 8K - 6
  28.  * | Minutes                                     |
  29.  * +---------------------------------------------+ BASE + 8K - 5
  30.  * | Hours                                       |
  31.  * +---------------------------------------------+ BASE + 8k - 4
  32.  * | Day                                         |
  33.  * +---------------------------------------------+ BASE + 8K - 3
  34.  * | Date                                        |
  35.  * +---------------------------------------------+ BASE + 8K - 2
  36.  * | Month                                       |
  37.  * +---------------------------------------------+ BASE + 8K - 1
  38.  * | Year                                        |
  39.  * +---------------------------------------------+ 
  40.  */
  41. #include "vxWorks.h"
  42. #include "mbz.h"
  43. #include "ds1743.h"
  44. #define YEAR (0x7^0x03)
  45. #define MONTH (0x6^0x03)
  46. #define DAY (0x5^0x03)
  47. #define DAY_OF_WEEK (0x4^0x03)
  48. #define HOUR (0x3^0x03)
  49. #define MINUTE (0x2^0x03)
  50. #define SECOND (0x1^0x03)
  51. #define CONTROL (0x0^0x03)
  52. static UINT8 *ds1743BaseAddr;
  53. /* FIXME */
  54. #define DS1743_ADDR ((volatile UINT8 *) (ds1743BaseAddr + 8*1024 - 8))
  55. STATUS ds1743_tod_init(UINT8 *addr)
  56. {
  57.   ds1743BaseAddr = addr;
  58.   SYS_TOD_UNPROTECT();
  59.   DS1743_ADDR[CONTROL] = 0;
  60.   SYS_TOD_PROTECT();
  61.   /* Start the clock if the oscillator is not running */
  62.   if(DS1743_ADDR[SECOND] & 0x80)
  63.     return ds1743_tod_set(2000, 1, 1, 0, 0, 0);
  64.   else
  65.     return 0;
  66. }
  67. /*
  68.  * ds1743_tod_set
  69.  */
  70. static int to_bcd(int value)
  71. {
  72.   return value / 10 * 16 + value % 10;
  73. }
  74. static int from_bcd(int value)
  75. {
  76.   return value / 16 * 10 + value % 16;
  77. }
  78. static int day_of_week(int y, int m, int d) /* 0-6 ==> Sun-Sat */
  79. {       
  80.   static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; 
  81.   y -= m < 3;
  82.   return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
  83. }       
  84. /*
  85.  * Note: the TOD should store the current GMT
  86.  */
  87. STATUS ds1743_tod_set(int year, /* 1980-2079 */
  88.       int month, /* 01-12 */
  89.       int day, /* 01-31 */
  90.       int hour, /* 00-23 */
  91.       int minute, /* 00-59 */
  92.       int second) /* 00-59 */
  93.      
  94. {
  95.   SYS_TOD_UNPROTECT();
  96.   DS1743_ADDR[CONTROL] |= 0x80; /* Set WRITE bit */
  97.   DS1743_ADDR[YEAR] = to_bcd(year % 100);
  98.   DS1743_ADDR[MONTH] = to_bcd(month);
  99.   DS1743_ADDR[DAY] = to_bcd(day);
  100.   DS1743_ADDR[DAY_OF_WEEK] = day_of_week(year, month, day) + 1;
  101.   DS1743_ADDR[HOUR] = to_bcd(hour);
  102.   DS1743_ADDR[MINUTE] = to_bcd(minute);
  103.   DS1743_ADDR[SECOND] = to_bcd(second);
  104.   DS1743_ADDR[CONTROL] &= ~0x80; /* Clear WRITE bit */
  105.   SYS_TOD_PROTECT();
  106.   return OK;
  107. }
  108. /*
  109.  * Note: the TOD should store the current GMT
  110.  */
  111. STATUS ds1743_tod_get(int *year, /* 1980-2079 */
  112.       int *month, /* 01-12 */
  113.       int *day,         /* 01-31 */
  114.       int *hour, /* 00-23 */
  115.       int *minute, /* 00-59 */
  116.       int *second) /* 00-59 */
  117. {
  118.   int y;
  119.   
  120.   SYS_TOD_UNPROTECT();
  121.   DS1743_ADDR[CONTROL] |= 0x40; /* Set READ bit */
  122.   SYS_TOD_PROTECT();
  123.   y = from_bcd(DS1743_ADDR[YEAR]);
  124.   *year = y < 80 ? 2000 + y : 1900 + y;
  125.   *month = from_bcd(DS1743_ADDR[MONTH]);
  126.   *day = from_bcd(DS1743_ADDR[DAY]);
  127.   /* 
  128.    * Note: MSB of day-of-week reg contains battery-life bit.  It
  129.    * should always be '1'.  If it's zero, either the battery is dead
  130.    * or we're not really reading the chip.
  131.    */
  132.   /* day_of_week = DS1743_ADDR[DAY_OF_WEEK] & 0xf; */
  133.   *hour = from_bcd(DS1743_ADDR[HOUR]);
  134.   *minute = from_bcd(DS1743_ADDR[MINUTE]);
  135.   *second = from_bcd(DS1743_ADDR[SECOND] & 0x7f);
  136.   
  137.   DS1743_ADDR[CONTROL] &= ~0x40; /* Clear READ bit */
  138.   
  139.   return OK;
  140. }
  141. int ds1743_tod_get_second(void)
  142. {
  143.     return from_bcd(DS1743_ADDR[SECOND] & 0x7f);
  144. }
  145. STATUS
  146. ds1743_tod_print()
  147. {
  148.   int year, month, day, hour, minute, second;
  149.   ds1743_tod_get(&year, /* 1980-2079 */
  150.  &month, /* 01-12 */
  151.  &day,         /* 01-31 */
  152.  &hour, /* 00-23 */
  153.  &minute, /* 00-59 */
  154.  &second); /* 00-59 */  
  155.   
  156.   printf("%d/%d/%d, %d:%.2d:%.2dn", 
  157.  month, day, year, 
  158.  hour, minute, second);
  159.   return 0;
  160. }