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

VxWorks

开发平台:

C/C++

  1. /*
  2.  * $Id: m48t59y.c,v 1.1 Broadcom SDK $
  3.  *
  4.  * SGS M48-T59Y TOD/NVRAM Driver
  5.  *
  6.  * The SGS M48 an 8K NVRAM starting at offset M48_BASE_ADDR and
  7.  * continuing for 8176 bytes. After that starts the Time-Of-Day (TOD)
  8.  * registers which are used to set/get the internal date/time functions.
  9.  *
  10.  * This module implements Y2K compliance by taking full year numbers
  11.  * and translating back and forth from the TOD 2-digit year.
  12.  *
  13.  * NOTE: for proper interaction with an operating system, the TOD should
  14.  * be used to store Universal Coordinated Time (GMT) and timezone
  15.  * conversions should be used.
  16.  *
  17.  * Here is a diagram of the memory layout:
  18.  *
  19.  * +---------------------------------------------+ 0xffe0a000
  20.  * | Non-volatile memory                         | .
  21.  * |                                             | .
  22.  * | (8176 bytes of Non-volatile memory)         | .
  23.  * |                                             | .
  24.  * +---------------------------------------------+ 0xffe0bff0
  25.  * | Flags                                       |
  26.  * +---------------------------------------------+ 0xffe0bff1
  27.  * | Unused                                      |
  28.  * +---------------------------------------------+ 0xffe0bff2
  29.  * | Alarm Seconds                               |
  30.  * +---------------------------------------------+ 0xffe0bff3
  31.  * | Alarm Minutes                               |
  32.  * +---------------------------------------------+ 0xffe0bff4
  33.  * | Alarm Date                                  |
  34.  * +---------------------------------------------+ 0xffe0bff5
  35.  * | Interrupts                                  |
  36.  * +---------------------------------------------+ 0xffe0bff6
  37.  * | WatchDog                                    |
  38.  * +---------------------------------------------+ 0xffe0bff7
  39.  * | Calibration                                 |
  40.  * +---------------------------------------------+ 0xffe0bff8
  41.  * | Seconds                                     |
  42.  * +---------------------------------------------+ 0xffe0bff9
  43.  * | Minutes                                     |
  44.  * +---------------------------------------------+ 0xffe0bffa
  45.  * | Hours                                       |
  46.  * +---------------------------------------------+ 0xffe0bffb
  47.  * | Day                                         |
  48.  * +---------------------------------------------+ 0xffe0bffc
  49.  * | Date                                        |
  50.  * +---------------------------------------------+ 0xffe0bffd
  51.  * | Month                                       |
  52.  * +---------------------------------------------+ 0xffe0bffe
  53.  * | Year (2 digits only)                        |
  54.  * +---------------------------------------------+ 0xffe0bfff
  55.  */
  56. #include "vxWorks.h"
  57. #include "mbz.h"
  58. /*
  59.  * Imported from mbz.h:
  60.  *
  61.  *   TOD_REG_BASE Base of m48t59y TOD registers
  62.  *   SYS_TOD_UNPROTECT() Disable NVRAM write protect
  63.  *   SYS_TOD_PROTECT() Re-enable NVRAM write protect
  64.  */
  65. #define YEAR (0xf^0x3)
  66. #define MONTH (0xe^0x3)
  67. #define DAY (0xd^0x3)
  68. #define DAY_OF_WEEK (0xc^0x3)
  69. #define HOUR (0xb^0x3)
  70. #define MINUTE (0xa^0x3)
  71. #define SECOND (0x9^0x3)
  72. #define CONTROL (0x8^0x3)
  73. #define WATCH (0x7^0x3)
  74. #define INTCTL (0x6^0x3)
  75. #define WD_DATE (0x5^0x3)
  76. #define WD_HOUR (0x4^0x3)
  77. #define WD_MIN (0x3^0x3)
  78. #define WD_SEC (0x2^0x3)
  79. #define _UNUSED (0x1^0x3)
  80. #define FLAGS (0x0^0x3)
  81. static UINT8 *m48BaseAddr;
  82. #define M48_ADDR     ((volatile UINT8 *) (m48BaseAddr + 8*1024 - 16))
  83. STATUS m48_tod_init(UINT8 *addr)
  84. {
  85.     m48BaseAddr = addr;
  86.     SYS_TOD_UNPROTECT();
  87.     M48_ADDR[CONTROL] = 0;
  88.     M48_ADDR[WATCH] = 0;
  89.     M48_ADDR[INTCTL] = 0;
  90.     /*
  91.      * If the oscillator is currently stopped (as on a new part shipped
  92.      * from the factory), start it running.
  93.      *
  94.      * Here is an example of the TOD bytes on a brand new M48T59Y part:
  95.      * 00 00 00 00 00 00 00 00 00 88 8c c3 bf c8 f5 01
  96.      */
  97.     if (M48_ADDR[SECOND] & 0x80)
  98. M48_ADDR[SECOND] = 0;
  99.     SYS_TOD_PROTECT();
  100.     return OK;
  101. }
  102. /*
  103.  * m48_tod_set
  104.  */
  105. static int to_bcd(int value)
  106. {
  107.     return value / 10 * 16 + value % 10;
  108. }
  109. static int from_bcd(int value)
  110. {
  111.     return value / 16 * 10 + value % 16;
  112. }
  113. static int day_of_week(int y, int m, int d) /* 0-6 ==> Sun-Sat */
  114. {       
  115.     static int t[] = {0, 3, 2, 5, 0, 3, 5, 1, 4, 6, 2, 4}; 
  116.     y -= m < 3;
  117.     return (y + y/4 - y/100 + y/400 + t[m-1] + d) % 7;
  118. }       
  119. /*
  120.  * Note: the TOD should store the current GMT
  121.  */
  122. STATUS m48_tod_set(int year, /* 1980-2079 */
  123.    int month, /* 01-12 */
  124.    int day, /* 01-31 */
  125.    int hour, /* 00-23 */
  126.    int minute, /* 00-59 */
  127.    int second) /* 00-59 */
  128.   
  129. {
  130.     SYS_TOD_UNPROTECT();
  131.     M48_ADDR[CONTROL] |= 0x80; /* Set WRITE bit */
  132.     M48_ADDR[YEAR] = to_bcd(year % 100);
  133.     M48_ADDR[MONTH] = to_bcd(month);
  134.     M48_ADDR[DAY] = to_bcd(day);
  135.     M48_ADDR[DAY_OF_WEEK] = day_of_week(year, month, day) + 1;
  136.     M48_ADDR[HOUR] = to_bcd(hour);
  137.     M48_ADDR[MINUTE] = to_bcd(minute);
  138.     M48_ADDR[SECOND] = to_bcd(second);
  139.     M48_ADDR[CONTROL] &= ~0x80; /* Clear WRITE bit */
  140.     SYS_TOD_PROTECT();
  141.     return OK;
  142. }
  143. /*
  144.  * Note: the TOD should store the current GMT
  145.  */
  146. STATUS m48_tod_get(int *year, /* 1980-2079 */
  147.    int *month, /* 01-12 */
  148.    int *day, /* 01-31 */
  149.    int *hour, /* 00-23 */
  150.    int *minute, /* 00-59 */
  151.    int *second) /* 00-59 */
  152. {
  153.     int y;
  154.     SYS_TOD_UNPROTECT();
  155.     M48_ADDR[CONTROL] |= 0x40; /* Set READ bit */
  156.     y = from_bcd(M48_ADDR[YEAR]);
  157.     *year = y < 80 ? 2000 + y : 1900 + y;
  158.     *month = from_bcd(M48_ADDR[MONTH]);
  159.     *day = from_bcd(M48_ADDR[DAY]);
  160.     /* day_of_week = M48_ADDR[DAY_OF_WEEK] & 0xf; */
  161.     *hour = from_bcd(M48_ADDR[HOUR]);
  162.     *minute = from_bcd(M48_ADDR[MINUTE]);
  163.     *second = from_bcd(M48_ADDR[SECOND] & 0x7f);
  164.     M48_ADDR[CONTROL] &= ~0x40; /* Clear READ bit */
  165.     SYS_TOD_PROTECT();
  166.     return OK;
  167. }
  168. int m48_tod_get_second(void)
  169. {
  170.     return from_bcd(M48_ADDR[SECOND] & 0x7f);
  171. }
  172. /*
  173.  * Watchdog function
  174.  *
  175.  *  If usec is 0, the watchdog timer is disarmed.
  176.  *
  177.  *  If usec is non-zero, the watchdog timer is armed (or re-armed) for
  178.  *    approximately usec microseconds (if the exact requested usec is
  179.  *    not supported by the chip, the next higher available value is used).
  180.  *
  181.  *  Minimum watchdog timeout = 62500 usec
  182.  *  Maximum watchdog timeout = 124 sec (124000000 usec)
  183.  */
  184. void m48_watchdog_arm(int usec)
  185. {
  186.     int mpy, res;
  187.     SYS_TOD_UNPROTECT();
  188.     if (usec == 0) {
  189. res = 0;
  190. mpy = 0;
  191.     } else if (usec < 2000000) { /* Resolution: 1/16s if below 2s */
  192. res = 0;
  193. mpy = (usec + 62499) / 62500;
  194.     } else if (usec < 8000000) { /* Resolution: 1/4s if below 8s */
  195. res = 1;
  196. mpy = (usec + 249999) / 250000;
  197.     } else if (usec < 32000000) { /* Resolution: 1s if below 32s */
  198. res = 2;
  199. mpy = (usec + 999999) / 1000000;
  200.     } else { /* Resolution: 4s up to 124s */
  201. res = 3;
  202. mpy = (usec + 3999999) / 4000000;
  203. if (mpy > 31)
  204.     mpy = 31;
  205.     }
  206.     M48_ADDR[WATCH] = (0x80 | /* Steer to RST signal (IRQ = N/C) */
  207.        mpy << 2 |
  208.        res);
  209.     SYS_TOD_PROTECT();
  210. }