123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #include <arm/NXP/LPC17xx/LPC17xx.h>
- #include <arm/bits.h>
- #include "config.h"
- #include "rtc.h"
- #include "uart.h"
- #include "timer.h"
- #include "power.h"
- rtcstate_t rtc_state;
- #define CLKEN 0
- #define CTCRST 1
- uint8_t rtc_isvalid( void )
- {
- if ( LPC_RTC->GPREG0 == RTC_MAGIC )
- {
- return RTC_OK;
- }
- return RTC_INVALID;
- }
- void rtc_init( void )
- {
- if ( LPC_RTC->CCR & BV( CLKEN ) )
- {
- rtc_state = RTC_OK;
- }
- else
- {
- rtc_state = RTC_INVALID;
- }
- }
- void read_rtc( struct tm *time )
- {
- do
- {
- time->tm_sec = LPC_RTC->SEC;
- time->tm_min = LPC_RTC->MIN;
- time->tm_hour = LPC_RTC->HOUR;
- time->tm_mday = LPC_RTC->DOM;
- time->tm_mon = LPC_RTC->MONTH;
- time->tm_year = LPC_RTC->YEAR;
- time->tm_wday = LPC_RTC->DOW;
- }
- while ( time->tm_sec != LPC_RTC->SEC );
- }
- uint8_t calc_weekday( struct tm *time )
- {
- int month = time->tm_mon;
- int year = time->tm_year;
- int day = time->tm_mday;
- /* Variation of Sillke for the Gregorian calendar.
- * http://www.mathematik.uni-bielefeld.de/~sillke/ALGORITHMS/calendar/weekday.c */
- if ( month <= 2 )
- {
- month += 10;
- year--;
- }
- else
- {
- month -= 2;
- }
- return ( 83 * month / 32 + day + year + year / 4 - year / 100 + year / 400 ) % 7;
- }
- void set_rtc( struct tm *time )
- {
- LPC_RTC->CCR = BV( CTCRST );
- LPC_RTC->SEC = time->tm_sec;
- LPC_RTC->MIN = time->tm_min;
- LPC_RTC->HOUR = time->tm_hour;
- LPC_RTC->DOM = time->tm_mday;
- LPC_RTC->MONTH = time->tm_mon;
- LPC_RTC->YEAR = time->tm_year;
- LPC_RTC->DOW = calc_weekday( time );
- LPC_RTC->CCR = BV( CLKEN );
- LPC_RTC->GPREG0 = RTC_MAGIC;
- }
- void invalidate_rtc()
- {
- LPC_RTC->GPREG0 = 0;
- }
- uint32_t get_fattime( void )
- {
- struct tm time;
- read_rtc( &time );
- return ( ( uint32_t )time.tm_year - 1980 ) << 25 |
- ( ( uint32_t )time.tm_mon ) << 21 |
- ( ( uint32_t )time.tm_mday ) << 16 |
- ( ( uint32_t )time.tm_hour ) << 11 |
- ( ( uint32_t )time.tm_min ) << 5 |
- ( ( uint32_t )time.tm_sec ) >> 1;
- }
- uint64_t get_bcdtime( void )
- {
- struct tm time;
- read_rtc( &time );
- uint16_t year = time.tm_year;
- return ( ( uint64_t )( time.tm_wday % 7 ) << 56 )
- | ( ( uint64_t )( ( year / 1000 ) % 10 ) << 52 )
- | ( ( uint64_t )( ( year / 100 ) % 10 ) << 48 )
- | ( ( uint64_t )( ( year / 10 ) % 10 ) << 44 )
- | ( ( uint64_t )( year % 10 ) << 40 )
- | ( ( uint64_t )( time.tm_mon / 10 ) << 36 )
- | ( ( uint64_t )( time.tm_mon % 10 ) << 32 )
- | ( ( time.tm_mday / 10 ) << 28 )
- | ( ( time.tm_mday % 10 ) << 24 )
- | ( ( time.tm_hour / 10 ) << 20 )
- | ( ( time.tm_hour % 10 ) << 16 )
- | ( ( time.tm_min / 10 ) << 12 )
- | ( ( time.tm_min % 10 ) << 8 )
- | ( ( time.tm_sec / 10 ) << 4 )
- | ( time.tm_sec % 10 );
- }
- void set_bcdtime( uint64_t btime )
- {
- struct tm time;
- time.tm_sec = ( btime & 0xf ) + ( ( btime >> 4 ) & 0xf ) * 10;
- time.tm_min = ( ( btime >> 8 ) & 0xf ) + ( ( btime >> 12 ) & 0xf ) * 10;
- time.tm_hour = ( ( btime >> 16 ) & 0xf ) + ( ( btime >> 20 ) & 0xf ) * 10;
- time.tm_mday = ( ( btime >> 24 ) & 0xf ) + ( ( btime >> 28 ) & 0xf ) * 10;
- time.tm_mon = ( ( btime >> 32 ) & 0xf ) + ( ( btime >> 36 ) & 0xf ) * 10;
- time.tm_year = ( ( btime >> 40 ) & 0xf ) + ( ( btime >> 44 ) & 0xf ) * 10
- + ( ( btime >> 48 ) & 0xf ) * 100 + ( ( btime >> 52 ) & 0xf ) * 1000;
- printtime( &time );
- set_rtc( &time );
- }
- void printtime( struct tm *time )
- {
- printf( "%04d-%02d-%02d %02d:%02d:%02d\n", time->tm_year, time->tm_mon,
- time->tm_mday, time->tm_hour, time->tm_min, time->tm_sec );
- }
- void testbattery()
- {
- printf( "%lx\n", LPC_RTC->GPREG0 );
- LPC_RTC->GPREG0 = RTC_MAGIC;
- printf( "%lx\n", LPC_RTC->GPREG0 );
- LPC_RTC->CCR = 0;
- BITBAND( LPC_SC->PCONP, PCRTC ) = 0;
- delay_ms( 20000 );
- BITBAND( LPC_SC->PCONP, PCRTC ) = 1;
- printf( "%lx\n", LPC_RTC->GPREG0 );
- delay_ms( 20 );
- LPC_RTC->CCR = BV( CLKEN );
- }
|