123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135 |
- #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);
- }
|