rtc.c 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. #include <arm/NXP/LPC17xx/LPC17xx.h>
  2. #include <arm/bits.h>
  3. #include "config.h"
  4. #include "rtc.h"
  5. #include "uart.h"
  6. #include "timer.h"
  7. #include "power.h"
  8. rtcstate_t rtc_state;
  9. #define CLKEN 0
  10. #define CTCRST 1
  11. uint8_t rtc_isvalid( void )
  12. {
  13. if ( LPC_RTC->GPREG0 == RTC_MAGIC )
  14. {
  15. return RTC_OK;
  16. }
  17. return RTC_INVALID;
  18. }
  19. void rtc_init( void )
  20. {
  21. if ( LPC_RTC->CCR & BV( CLKEN ) )
  22. {
  23. rtc_state = RTC_OK;
  24. }
  25. else
  26. {
  27. rtc_state = RTC_INVALID;
  28. }
  29. }
  30. void read_rtc( struct tm *time )
  31. {
  32. do
  33. {
  34. time->tm_sec = LPC_RTC->SEC;
  35. time->tm_min = LPC_RTC->MIN;
  36. time->tm_hour = LPC_RTC->HOUR;
  37. time->tm_mday = LPC_RTC->DOM;
  38. time->tm_mon = LPC_RTC->MONTH;
  39. time->tm_year = LPC_RTC->YEAR;
  40. time->tm_wday = LPC_RTC->DOW;
  41. }
  42. while ( time->tm_sec != LPC_RTC->SEC );
  43. }
  44. uint8_t calc_weekday( struct tm *time )
  45. {
  46. int month = time->tm_mon;
  47. int year = time->tm_year;
  48. int day = time->tm_mday;
  49. /* Variation of Sillke for the Gregorian calendar.
  50. * http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */
  51. if ( month <= 2 )
  52. {
  53. month += 10;
  54. year--;
  55. }
  56. else
  57. {
  58. month -= 2;
  59. }
  60. return ( 83 * month / 32 + day + year + year / 4 - year / 100 + year / 400 ) % 7;
  61. }
  62. void set_rtc( struct tm *time )
  63. {
  64. LPC_RTC->CCR = BV( CTCRST );
  65. LPC_RTC->SEC = time->tm_sec;
  66. LPC_RTC->MIN = time->tm_min;
  67. LPC_RTC->HOUR = time->tm_hour;
  68. LPC_RTC->DOM = time->tm_mday;
  69. LPC_RTC->MONTH = time->tm_mon;
  70. LPC_RTC->YEAR = time->tm_year;
  71. LPC_RTC->DOW = calc_weekday( time );
  72. LPC_RTC->CCR = BV( CLKEN );
  73. LPC_RTC->GPREG0 = RTC_MAGIC;
  74. }
  75. void invalidate_rtc()
  76. {
  77. LPC_RTC->GPREG0 = 0;
  78. }
  79. uint32_t get_fattime( void )
  80. {
  81. struct tm time;
  82. read_rtc( &time );
  83. return ( ( uint32_t )time.tm_year - 1980 ) << 25 |
  84. ( ( uint32_t )time.tm_mon ) << 21 |
  85. ( ( uint32_t )time.tm_mday ) << 16 |
  86. ( ( uint32_t )time.tm_hour ) << 11 |
  87. ( ( uint32_t )time.tm_min ) << 5 |
  88. ( ( uint32_t )time.tm_sec ) >> 1;
  89. }
  90. uint64_t get_bcdtime( void )
  91. {
  92. struct tm time;
  93. read_rtc( &time );
  94. uint16_t year = time.tm_year;
  95. return ( ( uint64_t )( time.tm_wday % 7 ) << 56 )
  96. | ( ( uint64_t )( ( year / 1000 ) % 10 ) << 52 )
  97. | ( ( uint64_t )( ( year / 100 ) % 10 ) << 48 )
  98. | ( ( uint64_t )( ( year / 10 ) % 10 ) << 44 )
  99. | ( ( uint64_t )( year % 10 ) << 40 )
  100. | ( ( uint64_t )( time.tm_mon / 10 ) << 36 )
  101. | ( ( uint64_t )( time.tm_mon % 10 ) << 32 )
  102. | ( ( time.tm_mday / 10 ) << 28 )
  103. | ( ( time.tm_mday % 10 ) << 24 )
  104. | ( ( time.tm_hour / 10 ) << 20 )
  105. | ( ( time.tm_hour % 10 ) << 16 )
  106. | ( ( time.tm_min / 10 ) << 12 )
  107. | ( ( time.tm_min % 10 ) << 8 )
  108. | ( ( time.tm_sec / 10 ) << 4 )
  109. | ( time.tm_sec % 10 );
  110. }
  111. void set_bcdtime( uint64_t btime )
  112. {
  113. struct tm time;
  114. time.tm_sec = ( btime & 0xf ) + ( ( btime >> 4 ) & 0xf ) * 10;
  115. time.tm_min = ( ( btime >> 8 ) & 0xf ) + ( ( btime >> 12 ) & 0xf ) * 10;
  116. time.tm_hour = ( ( btime >> 16 ) & 0xf ) + ( ( btime >> 20 ) & 0xf ) * 10;
  117. time.tm_mday = ( ( btime >> 24 ) & 0xf ) + ( ( btime >> 28 ) & 0xf ) * 10;
  118. time.tm_mon = ( ( btime >> 32 ) & 0xf ) + ( ( btime >> 36 ) & 0xf ) * 10;
  119. time.tm_year = ( ( btime >> 40 ) & 0xf ) + ( ( btime >> 44 ) & 0xf ) * 10
  120. + ( ( btime >> 48 ) & 0xf ) * 100 + ( ( btime >> 52 ) & 0xf ) * 1000;
  121. printtime( &time );
  122. set_rtc( &time );
  123. }
  124. void printtime( struct tm *time )
  125. {
  126. printf( "%04d-%02d-%02d %02d:%02d:%02d\n", time->tm_year, time->tm_mon,
  127. time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec );
  128. }
  129. void testbattery()
  130. {
  131. printf( "%lx\n", LPC_RTC->GPREG0 );
  132. LPC_RTC->GPREG0 = RTC_MAGIC;
  133. printf( "%lx\n", LPC_RTC->GPREG0 );
  134. LPC_RTC->CCR = 0;
  135. BITBAND( LPC_SC->PCONP, PCRTC ) = 0;
  136. delay_ms( 20000 );
  137. BITBAND( LPC_SC->PCONP, PCRTC ) = 1;
  138. printf( "%lx\n", LPC_RTC->GPREG0 );
  139. delay_ms( 20 );
  140. LPC_RTC->CCR = BV( CLKEN );
  141. }