rtc.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. #include <stdio.h>
  2. #include "FreeRTOS.h"
  3. #include "chip.h"
  4. #include "errno.h"
  5. #include "access_module.h"
  6. /* RTC registers */
  7. #define RTC_CTL 0x00 /*control register*/
  8. #define RTC_ANAWEN 0x04 /*analog block write enable register*/
  9. #define RTC_ANACTL 0x08 /*analog block control register*/
  10. #define RTC_IM 0x0c /*interrupt mode register*/
  11. #define RTC_STA 0x10 /*rtc status register*/
  12. #define RTC_ALMDAT 0x14 /*alarm data register*/
  13. #define RTC_DONT 0x18 /*delay on timer register*/
  14. #define RTC_RAM 0x1c /*ram bit register*/
  15. #define RTC_CNTL 0x20 /*rtc counter register*/
  16. #define RTC_CNTH 0x24 /*rtc sec counter register*/
  17. //RTC_CTL register fields defination
  18. #define CTL_CTL3_VALUE(x) (x<<23)
  19. #define CTL_CTL2_VALUE(x) (x<<22)
  20. #define CTL_BIAS_TRM_VALUE(x) (x<<21)
  21. #define CTL_SOFT_SEL_VALUE(x) (x<<20)
  22. #define CTL_CTL1_VALUE(x) (x<<19)
  23. #define CTL_CTL0_VALUE(x) (x<<18)
  24. #define CTL_SOFT_STR_VALUE(x) (x<<17)
  25. #define CTL_OSC_EN_VALUE(x) (x<<16)
  26. #define CTL_CTL3_SET (1<<15)
  27. #define CTL_CTL2_SET (1<<14)
  28. #define CTL_BIAS_TRM_SET (1<<13)
  29. #define CTL_SOFT_SEL_SET (1<<12)
  30. #define CTL_CTL1_SET (1<<11)
  31. #define CTL_CTL0_SET (1<<10)
  32. #define CTL_SOFT_STR_SET (1<<9)
  33. #define CTL_OSC_EN_SET (1<<8)
  34. #define CTL_ALM_DATA_WEN (1<<3)
  35. #define CTL_PERIOD_INT_EN (1<<2)
  36. #define CTL_ALARM_INT_EN (1<<1)
  37. #define CTL_RESET (1<<0)
  38. //RTC_ANAWEN register fields defination
  39. #define ANA_CNT_WEN (1<<7)
  40. #define ANA_RAM_WEN (1<<6)
  41. #define ANA_DELAY_TIMER_WEN (1<<5)
  42. #define ANA_CLR_PWR_DET_WEN (1<<4)
  43. #define ANA_DELAY_POWER_ON_WEN (1<<3)
  44. #define ANA_FORCE_POWER_OFF_WEN (1<<2)
  45. #define ANA_FORCE_POWER_ON_WEN (1<<1)
  46. #define ANA_RTC_WEN (1<<0)
  47. //RTC_ANACTL register fields defination
  48. #define ANACTL_CLR_PWR (1<<4)
  49. #define ANACTL_DELAY_POWER_ON (1<<3)
  50. #define ANACTL_FORCE_POWER_OFF (1<<2)
  51. #define ANACTL_FORCE_POWER_ON (1<<1)
  52. #define ANACTL_COUNTER_EN (1<<0)
  53. /* STATUS_REG */
  54. #define STA_PWR_DET (1<<6)
  55. #define STA_DELAY_ON (1<<5)
  56. #define STA_FORCE_OFF (1<<4)
  57. #define STA_FORCE_ON (1<<3)
  58. #define STA_RCT_BUSY (1<<2)
  59. #define STA_PERIOD_INT (1<<1)
  60. #define STA_ALARM_INT (1<<0)
  61. /* 2020-01-01 Wednesday */
  62. static struct rtc_time default_tm = {
  63. .tm_sec = 0,
  64. .tm_min = 0,
  65. .tm_hour = 0,
  66. .tm_mday = 1,
  67. .tm_mon = 0,
  68. .tm_year = 120,
  69. .tm_wday = 3,
  70. .tm_yday = 1,
  71. };
  72. static const unsigned char rtc_days_in_month[] = {
  73. 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  74. };
  75. static const unsigned short rtc_ydays[2][13] = {
  76. /* Normal years */
  77. { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
  78. /* Leap years */
  79. { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
  80. };
  81. #define LEAPS_THRU_END_OF(y) ((y)/4 - (y)/100 + (y)/400)
  82. /*
  83. * The number of days in the month.
  84. */
  85. int rtc_month_days(unsigned int month, unsigned int year)
  86. {
  87. return rtc_days_in_month[month] + (is_leap_year(year) && month == 1);
  88. }
  89. /*
  90. * The number of days since January 1. (0 to 365)
  91. */
  92. int rtc_year_days(unsigned int day, unsigned int month, unsigned int year)
  93. {
  94. return rtc_ydays[is_leap_year(year)][month] + day-1;
  95. }
  96. /*
  97. * rtc_time_to_tm - Converts time to rtc_time.
  98. * Convert seconds since 01-01-1970 00:00:00 to Gregorian date.
  99. */
  100. void rtc_time_to_tm(uint32_t time, struct rtc_time *tm)
  101. {
  102. unsigned int month, year;
  103. unsigned long secs;
  104. int days;
  105. /* time must be positive */
  106. days = time / 86400;
  107. secs = time - (unsigned int) days * 86400;
  108. /* day of the week, 1970-01-01 was a Thursday */
  109. tm->tm_wday = (days + 4) % 7;
  110. year = 1970 + days / 365;
  111. days -= (year - 1970) * 365
  112. + LEAPS_THRU_END_OF(year - 1)
  113. - LEAPS_THRU_END_OF(1970 - 1);
  114. if (days < 0) {
  115. year -= 1;
  116. days += 365 + is_leap_year(year);
  117. }
  118. tm->tm_year = year - 1900;
  119. tm->tm_yday = days + 1;
  120. for (month = 0; month < 11; month++) {
  121. int newdays;
  122. newdays = days - rtc_month_days(month, year);
  123. if (newdays < 0)
  124. break;
  125. days = newdays;
  126. }
  127. tm->tm_mon = month;
  128. tm->tm_mday = days + 1;
  129. tm->tm_hour = secs / 3600;
  130. secs -= tm->tm_hour * 3600;
  131. tm->tm_min = secs / 60;
  132. tm->tm_sec = secs - tm->tm_min * 60;
  133. }
  134. /*
  135. * Does the rtc_time represent a valid date/time?
  136. */
  137. int rtc_valid_tm(struct rtc_time *tm)
  138. {
  139. if (tm->tm_year < 70
  140. || ((unsigned)tm->tm_mon) >= 12
  141. || tm->tm_mday < 1
  142. || tm->tm_mday > rtc_month_days(tm->tm_mon, tm->tm_year + 1900)
  143. || ((unsigned)tm->tm_hour) >= 24
  144. || ((unsigned)tm->tm_min) >= 60
  145. || ((unsigned)tm->tm_sec) >= 60)
  146. return -EINVAL;
  147. return 0;
  148. }
  149. /*
  150. * mktime - Converts date to seconds.
  151. * Converts Gregorian date to seconds since 1970-01-01 00:00:00.
  152. * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
  153. * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
  154. *
  155. * [For the Julian calendar (which was used in Russia before 1917,
  156. * Britain & colonies before 1752, anywhere else before 1582,
  157. * and is still in use by some communities) leave out the
  158. * -year/100+year/400 terms, and add 10.]
  159. *
  160. * This algorithm was first published by Gauss (I think).
  161. *
  162. * A leap second can be indicated by calling this function with sec as
  163. * 60 (allowable under ISO 8601). The leap second is treated the same
  164. * as the following second since they don't exist in UNIX time.
  165. *
  166. * An encoding of midnight at the end of the day as 24:00:00 - ie. midnight
  167. * tomorrow - (allowable under ISO 8601) is supported.
  168. */
  169. uint32_t mktime(const unsigned int year0, const unsigned int mon0,
  170. const unsigned int day, const unsigned int hour,
  171. const unsigned int min, const unsigned int sec)
  172. {
  173. unsigned int mon = mon0, year = year0;
  174. /* 1..12 -> 11,12,1..10 */
  175. if (0 >= (int) (mon -= 2)) {
  176. mon += 12; /* Puts Feb last since it has leap day */
  177. year -= 1;
  178. }
  179. return ((((uint32_t)
  180. (year/4 - year/100 + year/400 + 367*mon/12 + day) +
  181. year*365 - 719499
  182. )*24 + hour /* now have hours - midnight tomorrow handled here */
  183. )*60 + min /* now have minutes */
  184. )*60 + sec; /* finally seconds */
  185. }
  186. /*
  187. * rtc_tm_to_time - Converts rtc_time to time.
  188. * Convert Gregorian date to seconds since 01-01-1970 00:00:00.
  189. */
  190. uint32_t rtc_tm_to_time(struct rtc_time *tm)
  191. {
  192. return mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
  193. tm->tm_hour, tm->tm_min, tm->tm_sec);
  194. }
  195. static __INLINE void rtc_clear_interrupt(void)
  196. {
  197. unsigned int val;
  198. val = readl(REGS_RTC_BASE + RTC_STA);
  199. val &= ~CTL_ALARM_INT_EN;
  200. writel(val, REGS_RTC_BASE + RTC_STA);
  201. }
  202. static __INLINE void rtc_enable_interrupt(void)
  203. {
  204. unsigned int val;
  205. val = readl(REGS_RTC_BASE + RTC_CTL);
  206. if (!(val & CTL_ALARM_INT_EN)) {
  207. rtc_clear_interrupt();
  208. val |= CTL_ALARM_INT_EN;
  209. writel(val, REGS_RTC_BASE + RTC_CTL);
  210. }
  211. }
  212. static __INLINE void rtc_disable_interrupt(void)
  213. {
  214. unsigned int val;
  215. val = readl(REGS_RTC_BASE + RTC_CTL);
  216. if (val & CTL_ALARM_INT_EN) {
  217. val &= ~CTL_ALARM_INT_EN;
  218. writel(val, REGS_RTC_BASE + RTC_CTL);
  219. }
  220. }
  221. static void rtc_wait_not_busy(void)
  222. {
  223. int status, count = 0;
  224. /* Assuming BUSY may stay active for 80 msec) */
  225. for (count = 0; count < 0x1000; count++) {
  226. status = readl(REGS_RTC_BASE + RTC_STA);
  227. if ((status & STA_RCT_BUSY) == 0)
  228. break;
  229. /* check status busy, after each msec */
  230. vTaskDelay(pdMS_TO_TICKS(1));
  231. }
  232. }
  233. static void rtc_isr(void *para)
  234. {
  235. unsigned int irq_data;
  236. irq_data = readl(REGS_RTC_BASE + RTC_STA);
  237. if ((irq_data & CTL_ALARM_INT_EN)) {
  238. rtc_clear_interrupt();
  239. return;
  240. } else
  241. return;
  242. }
  243. static void rtc_update_time(unsigned int time)
  244. {
  245. unsigned int val;
  246. int timeout = 100000;
  247. val = readl(REGS_RTC_BASE + RTC_ANAWEN);
  248. writel(val | ANA_RTC_WEN, REGS_RTC_BASE + RTC_ANAWEN);
  249. val = readl(REGS_RTC_BASE + RTC_ANACTL);
  250. writel(val | ANACTL_COUNTER_EN, REGS_RTC_BASE + RTC_ANACTL);
  251. //wait rtc_busy;
  252. rtc_wait_not_busy();
  253. val = readl(REGS_RTC_BASE + RTC_ANAWEN);
  254. writel(val | ANA_CNT_WEN, REGS_RTC_BASE + RTC_ANAWEN);
  255. writel(time, REGS_RTC_BASE + RTC_CNTH);
  256. //wait rtc_busy;
  257. rtc_wait_not_busy();
  258. while(readl(REGS_RTC_BASE + RTC_CNTH) != time) {
  259. if (timeout-- == 0)
  260. break;
  261. taskYIELD();
  262. }
  263. }
  264. /*
  265. * rtc_read_time - set the time
  266. * @tm: holds date and time
  267. *
  268. * This function read time and date. On success it will return 0
  269. * otherwise -ve error is returned.
  270. */
  271. static int rtc_read_time(struct rtc_time *tm)
  272. {
  273. unsigned int time;
  274. #ifdef ACCESS_RTC_SUPPORT
  275. AccessRTC(ART_GET_TIME, &time);
  276. #else
  277. /* we don't report wday/yday/isdst ... */
  278. rtc_wait_not_busy();
  279. time = readl(REGS_RTC_BASE + RTC_CNTH);
  280. #endif
  281. rtc_time_to_tm(time, tm);
  282. return 0;
  283. }
  284. /*
  285. * rtc_set_time - set the time
  286. * @tm: holds date and time
  287. *
  288. * This function set time and date. On success it will return 0
  289. * otherwise -ve error is returned.
  290. */
  291. static int rtc_set_time(struct rtc_time *tm)
  292. {
  293. unsigned int time;
  294. if (rtc_valid_tm(tm) < 0)
  295. return -EINVAL;
  296. /* convert tm to seconds. */
  297. time = rtc_tm_to_time(tm);
  298. #ifdef ACCESS_RTC_SUPPORT
  299. return AccessRTC(ART_SET_TIME, &time);
  300. #else
  301. rtc_update_time(time);
  302. #endif
  303. return 0;
  304. }
  305. #if 0
  306. static void rtc_update_alarm_time(unsigned int time)
  307. {
  308. unsigned int val;
  309. int timeout = 100000;
  310. val = readl(REGS_RTC_BASE + RTC_CTL);
  311. writel(val | CTL_ALM_DATA_WEN, REGS_RTC_BASE + RTC_CTL);
  312. writel(time, REGS_RTC_BASE + RTC_ALMDAT);
  313. //wait rtc_busy;
  314. rtc_wait_not_busy();
  315. while(readl(REGS_RTC_BASE + RTC_ALMDAT) != time) {
  316. if (timeout-- == 0)
  317. break;
  318. taskYIELD();
  319. }
  320. }
  321. /*
  322. * rtc_read_alarm - read the alarm time
  323. * @alm: holds alarm date and time
  324. *
  325. * This function read alarm time and date. On success it will return 0
  326. * otherwise -ve error is returned.
  327. */
  328. static int rtc_read_alarm(struct rtc_wkalrm *alm)
  329. {
  330. unsigned int time;
  331. rtc_wait_not_busy();
  332. time = readl(REGS_RTC_BASE + RTC_ALMDAT);
  333. rtc_time_to_tm(time, &alm->time);
  334. alm->enabled = readl(REGS_RTC_BASE + RTC_CTL) & CTL_ALARM_INT_EN;
  335. return 0;
  336. }
  337. /*
  338. * rtc_set_alarm - set the alarm time
  339. * @alm: holds alarm date and time
  340. *
  341. * This function set alarm time and date. On success it will return 0
  342. * otherwise -ve error is returned.
  343. */
  344. static int rtc_set_alarm(struct rtc_wkalrm *alm)
  345. {
  346. long unsigned int time;
  347. if (rtc_valid_tm(&alm->time) < 0)
  348. return -EINVAL;
  349. /* convert tm to seconds. */
  350. time = rtc_tm_to_time(&alm->time);
  351. rtc_update_alarm_time(time);
  352. if (alm->enabled)
  353. rtc_enable_interrupt();
  354. else
  355. rtc_disable_interrupt();
  356. return 0;
  357. }
  358. #endif
  359. static int alarm_irq_enable(unsigned int enabled)
  360. {
  361. int ret = 0;
  362. rtc_clear_interrupt();
  363. switch (enabled) {
  364. case 0:
  365. /* alarm off */
  366. rtc_disable_interrupt();
  367. break;
  368. case 1:
  369. /* alarm on */
  370. rtc_enable_interrupt();
  371. break;
  372. default:
  373. ret = -EINVAL;
  374. break;
  375. }
  376. return ret;
  377. }
  378. int rtc_init(void)
  379. {
  380. struct rtc_time tm;
  381. writel(0, REGS_RTC_BASE + RTC_CTL);
  382. writel(CTL_SOFT_STR_SET|CTL_SOFT_STR_VALUE(1), REGS_RTC_BASE + RTC_CTL);
  383. writel(CTL_OSC_EN_SET|CTL_OSC_EN_VALUE(0), REGS_RTC_BASE + RTC_CTL);
  384. writel(CTL_CTL0_SET|CTL_CTL0_VALUE(0), REGS_RTC_BASE + RTC_CTL);
  385. writel(CTL_CTL1_SET|CTL_CTL1_VALUE(0), REGS_RTC_BASE + RTC_CTL);
  386. writel(CTL_CTL2_SET|CTL_CTL2_VALUE(0), REGS_RTC_BASE + RTC_CTL);
  387. writel(CTL_CTL3_SET|CTL_CTL3_VALUE(0), REGS_RTC_BASE + RTC_CTL);
  388. writel(CTL_BIAS_TRM_SET|CTL_BIAS_TRM_VALUE(1)|CTL_CTL3_VALUE(0), REGS_RTC_BASE + RTC_CTL);
  389. udelay(1000);
  390. writel(CTL_OSC_EN_SET|CTL_OSC_EN_VALUE(1), REGS_RTC_BASE + RTC_CTL);
  391. udelay(1000);
  392. request_irq(RTC_PRD_IRQn, 0, rtc_isr, NULL);
  393. alarm_irq_enable(0);
  394. rtc_read_time(&tm);
  395. if (tm.tm_year == 70) {
  396. rtc_set_time(&default_tm);
  397. }
  398. return 0;
  399. }
  400. int iGetLocalTime(SystemTime_t *tm)
  401. {
  402. if(tm == NULL)
  403. return -1;
  404. rtc_read_time(tm);
  405. tm->tm_year += 1900;
  406. tm->tm_mon += 1;
  407. return 0;
  408. }
  409. int iSetLocalTime(SystemTime_t *tm)
  410. {
  411. if(tm == NULL)
  412. return -1;
  413. tm->tm_year -= 1900;
  414. tm->tm_mon -= 1;
  415. rtc_set_time(tm);
  416. return 0;
  417. }