blob: c7d8433eeccf399510a1e3e9af7988e6be4eb51b [file] [log] [blame]
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#define ADK_INTERNAL
#include "fwk.h"
#include "coop.h"
#include "RTC.h"
static volatile uint16_t gYear = 2012;
static volatile uint8_t gMonth = 2, gDay = 27, gHour = 19, gMinute = 8, gSecond = 8;
void rtcInit(void){
SUPC->SUPC_CR = SUPC_CR_KEY(0xA5) | SUPC_CR_XTALSEL_CRYSTAL_SEL; //enable oscillator
RTC->RTC_IDR = 0x1f;
RTC->RTC_IER = RTC_IER_SECEN; //enable interrupt
NVIC_EnableIRQ(RTC_IRQn);
}
void RTC_Handler(void){
static const uint8_t days_per_month[2][12] = {
{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
};
RTC->RTC_SCCR = RTC_SCCR_SECCLR;
if(++gSecond < 60) return;
gSecond = 0;
if(++gMinute < 60) return;
gMinute = 0;
if(++gHour < 24) return;
gHour = 0;
if(++gDay < days_per_month[!(gYear & 3)][gMonth]) return;
gDay = 0;
if(gMonth++ < 12) return;
gMonth = 0;
gYear++;
}
void rtcGet(uint16_t* yearP, uint8_t* monthP, uint8_t* dayP, uint8_t* hourP, uint8_t* minuteP, uint8_t* secondP){
uint16_t mYear;
uint8_t mMonth, mDay, mHour, mMinute, mSecond;
//read
do{
mSecond = gSecond;
mMinute = gMinute;
mHour = gHour;
mDay = gDay;
mMonth = gMonth;
mYear = gYear;
}while(mSecond != gSecond);
if(yearP) *yearP = mYear;
if(monthP) *monthP = mMonth + 1;
if(dayP) *dayP = mDay + 1;
if(hourP) *hourP = mHour;
if(minuteP) *minuteP = mMinute;
if(secondP) *secondP = mSecond;
}
void rtcSet(uint16_t year, uint8_t month, uint8_t day, uint8_t hour, uint8_t minute, uint8_t second){
//disable hardware update
RTC->RTC_IDR = RTC_IDR_SECDIS;
//write
gYear = year;
gMonth = month - 1;
gDay = day - 1;
gHour = hour;
gMinute = minute;
gSecond = second;
//re-enable hardware RTC counting
RTC->RTC_IER = RTC_IER_SECEN;
}