OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [freertos-6.1.1/] [Demo/] [Common/] [drivers/] [Atmel/] [at91lib/] [peripherals/] [rtc/] [rtc.c] - Rev 608

Compare with Previous | Blame | View Log

/* ----------------------------------------------------------------------------
 *         ATMEL Microcontroller Software Support 
 * ----------------------------------------------------------------------------
 * Copyright (c) 2008, Atmel Corporation
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the disclaimer below.
 *
 * Atmel's name may not be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
 * DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * ----------------------------------------------------------------------------
 */
 
#ifndef trace_LEVEL
	#define trace_LEVEL trace_INFO
#endif
 
//------------------------------------------------------------------------------
//         Headers
//------------------------------------------------------------------------------
 
#include "rtc.h"
#include <board.h>
#include <utility/assert.h>
#include <utility/trace.h>
 
//------------------------------------------------------------------------------
//         Exported functions
//------------------------------------------------------------------------------
 
//------------------------------------------------------------------------------
/// Sets the RTC in either 12- or 24-hour mode.
/// \param mode  Hour mode.
//------------------------------------------------------------------------------
void RTC_SetHourMode(unsigned int mode)
{
	SANITY_CHECK((mode & 0xFFFFFFFE) == 0);
 
    trace_LOG(trace_DEBUG, "-D- RTC_SetHourMode()\n\r");
 
	AT91C_BASE_RTC->RTC_MR = mode;
}
 
//------------------------------------------------------------------------------
/// Enables the selected interrupt sources of the RTC.
/// \param sources  Interrupt sources to enable.
//------------------------------------------------------------------------------
void RTC_EnableIt(unsigned int sources)
{
    SANITY_CHECK((sources & ~0x1F) == 0);
 
    trace_LOG(trace_DEBUG, "-D- RTC_EnableIt()\n\r");
 
    AT91C_BASE_RTC->RTC_IER = sources;
}
 
//------------------------------------------------------------------------------
/// Disables the selected interrupt sources of the RTC.
/// \param sources  Interrupt sources to disable.
//------------------------------------------------------------------------------
void RTC_DisableIt(unsigned int sources)
{
    SANITY_CHECK((sources & ~0x1F) == 0);
 
    trace_LOG(trace_DEBUG, "-D- RTC_DisableIt()\n\r");
 
    AT91C_BASE_RTC->RTC_IDR = sources;
}
 
//------------------------------------------------------------------------------
/// Sets the current time in the RTC.
/// \param hour  Current hour.
/// \param minute  Current minute.
/// \param second  Current second.
//------------------------------------------------------------------------------
void RTC_SetTime(unsigned char hour, unsigned char minute, unsigned char second)
{
	unsigned int time;
 
	SANITY_CHECK(hour < 24);
	SANITY_CHECK(minute < 60);
	SANITY_CHECK(second < 60);
 
    trace_LOG(trace_DEBUG, "-D- RTC_SetTime(%02d:%02d:%02d)\n\r", hour, minute, second);
 
	time = (second % 10) | ((second / 10) << 4)
		   | ((minute % 10) << 8) | ((minute / 10) << 12);
 
	// 12-hour mode
	if ((AT91C_BASE_RTC->RTC_MR & AT91C_RTC_HRMOD) == AT91C_RTC_HRMOD) {
 
		if (hour > 12) {
 
			hour -= 12;
			time |= AT91C_RTC_AMPM;
		}
	}
 
	time |= ((hour % 10) << 16) | ((hour / 10) << 20);
 
	// Set time
	AT91C_BASE_RTC->RTC_CR |= AT91C_RTC_UPDTIM;
	while ((AT91C_BASE_RTC->RTC_SR & AT91C_RTC_ACKUPD) != AT91C_RTC_ACKUPD);
	AT91C_BASE_RTC->RTC_SCCR = AT91C_RTC_ACKUPD;
	AT91C_BASE_RTC->RTC_TIMR = time;
	AT91C_BASE_RTC->RTC_CR &= ~AT91C_RTC_UPDTIM;
	SANITY_CHECK((AT91C_BASE_RTC->RTC_CR & AT91C_RTC_UPDTIM) != AT91C_RTC_UPDTIM);
}
 
//------------------------------------------------------------------------------
/// Retrieves the current time as stored in the RTC in several variables.
/// \param pHour  If not null, current hour is stored in this variable.
/// \param pMinute  If not null, current minute is stored in this variable.
/// \param pSecond  If not null, current second is stored in this variable.
//------------------------------------------------------------------------------
void RTC_GetTime(
	unsigned char *pHour,
	unsigned char *pMinute,
	unsigned char *pSecond)
{
	unsigned int time;
 
	SANITY_CHECK(pHour || pMinute || pSecond);
 
    trace_LOG(trace_DEBUG, "-D- RTC_GetTime()\n\r");
 
	// Get current RTC time
	time = AT91C_BASE_RTC->RTC_TIMR;
	while (time != AT91C_BASE_RTC->RTC_TIMR) {
 
		time = AT91C_BASE_RTC->RTC_TIMR;
	}
 
	// Hour
	if (pHour) {
 
		*pHour = ((time & 0x00300000) >> 20) * 10
				 + ((time & 0x000F0000) >> 16);
		if ((time & AT91C_RTC_AMPM) == AT91C_RTC_AMPM) {
 
			*pHour += 12;
		}
	}
 
	// Minute
	if (pMinute) {
 
		*pMinute = ((time & 0x00007000) >> 12) * 10
				   + ((time & 0x00000F00) >> 8);
	}
 
	// Second
	if (pSecond) {
 
		*pSecond = ((time & 0x00000070) >> 4) * 10
				   + (time & 0x0000000F);
	}
}
 
//------------------------------------------------------------------------------
/// Sets a time alarm on the RTC. The match is performed only on the provided
/// variables; setting all pointers to 0 disables the time alarm.
/// Note: in AM/PM mode, the hour value must have bit #7 set for PM, cleared for
/// AM (as expected in the time registers).
/// \param pHour  If not null, the time alarm will hour-match this value.
/// \param pMinute  If not null, the time alarm will minute-match this value.
/// \param pSecond  If not null, the time alarm will second-match this value.
//------------------------------------------------------------------------------
void RTC_SetTimeAlarm(
	unsigned char *pHour,
	unsigned char *pMinute,
	unsigned char *pSecond)
{
	unsigned int alarm = 0;
 
    SANITY_CHECK(!pHour || ((*pHour & 0x80) == 0));
    SANITY_CHECK(!pMinute || (*pMinute < 60));
    SANITY_CHECK(!pSecond || (*pSecond < 60));
 
	trace_LOG(trace_DEBUG, "-D- RTC_SetTimeAlarm()\n\r");
 
	// Hour
	if (pHour) {
 
		alarm |= AT91C_RTC_HOUREN | ((*pHour / 10) << 20) | ((*pHour % 10) << 16);
	}
 
	// Minute
	if (pMinute) {
 
		alarm |= AT91C_RTC_MINEN | ((*pMinute / 10) << 12) | ((*pMinute % 10) << 8);
	}
 
	// Second
	if (pSecond) {
 
		alarm |= AT91C_RTC_SECEN | ((*pSecond / 10) << 4) | (*pSecond % 10);
	}
 
	AT91C_BASE_RTC->RTC_TIMALR = alarm;
}
 
//------------------------------------------------------------------------------
/// Retrieves the current year, month and day from the RTC. Month, day and week
/// values are numbered starting at 1.
/// \param pYear  Current year (optional).
/// \param pMonth  Current month (optional).
/// \param pDay  Current day (optional).
/// \param pWeek  Current day in current week (optional).
//------------------------------------------------------------------------------
void RTC_GetDate(
    unsigned short *pYear,
    unsigned char *pMonth,
    unsigned char *pDay,
    unsigned char *pWeek)
{
    unsigned int date;
 
    // Get current date (multiple reads are necessary to insure a stable value)
    do {
 
        date = AT91C_BASE_RTC->RTC_CALR;
    }
    while (date != AT91C_BASE_RTC->RTC_CALR);
 
    // Retrieve year
    if (pYear) {
 
        *pYear = (((date  >> 4) & 0x7) * 1000)
                 + ((date & 0xF) * 100)
                 + (((date >> 12) & 0xF) * 10)
                 + ((date >> 8) & 0xF);
    }
 
    // Retrieve month
    if (pMonth) {
 
        *pMonth = (((date >> 20) & 1) * 10) + ((date >> 16) & 0xF);
    }
 
    // Retrieve day
    if (pDay) {
 
        *pDay = (((date >> 28) & 0x3) * 10) + ((date >> 24) & 0xF);
    }
 
    // Retrieve week
    if (pWeek) {
 
        *pWeek = ((date >> 21) & 0x7);
    }
}
 
//------------------------------------------------------------------------------
/// Sets the current year, month and day in the RTC. Month, day and week values
/// must be numbered starting from 1.
/// \param year  Current year.
/// \param month  Current month.
/// \param day  Current day.
/// \param week  Day number in current week.
//------------------------------------------------------------------------------
void RTC_SetDate(
    unsigned short year,
    unsigned char month,
    unsigned char day,
    unsigned char week)
{
    unsigned int date;
 
    SANITY_CHECK((year >= 1900) && (year <= 2099));
    SANITY_CHECK((month >= 1) && (month <= 12));
    SANITY_CHECK((day >= 1) && (day <= 31));
    SANITY_CHECK((week >= 1) && (week <= 7));
 
    // Convert values to date register value
    date = ((year / 100) % 10)
           | ((year / 1000) << 4)
           | ((year % 10) << 8)
           | (((year / 10) % 10) << 12)
           | ((month % 10) << 16)
           | ((month / 10) << 20)
           | (week << 21)
           | ((day % 10) << 24)
           | ((day / 10) << 28);
 
    // Update calendar register
    AT91C_BASE_RTC->RTC_CR |= AT91C_RTC_UPDCAL;
    while ((AT91C_BASE_RTC->RTC_SR & AT91C_RTC_ACKUPD) != AT91C_RTC_ACKUPD);
    AT91C_BASE_RTC->RTC_SCCR = AT91C_RTC_ACKUPD;
    AT91C_BASE_RTC->RTC_CALR = date;
    AT91C_BASE_RTC->RTC_CR &= ~AT91C_RTC_UPDCAL;
}
 
//------------------------------------------------------------------------------
/// Sets a date alarm in the RTC. The alarm will match only the provided values;
/// passing a null-pointer disables the corresponding field match.
/// \param pMonth  If not null, the RTC alarm will month-match this value.
/// \param pDay  If not null, the RTC alarm will day-match this value.
//------------------------------------------------------------------------------
void RTC_SetDateAlarm(unsigned char *pMonth, unsigned char *pDay)
{
    unsigned int alarm = 0;
 
    SANITY_CHECK(!pMonth || ((*pMonth >= 1) && (*pMonth <= 12)));
    SANITY_CHECK(!pDay || ((*pDay >= 1) && (*pDay <= 31)));
 
    trace_LOG(trace_DEBUG, "-D- RTC_SetDateAlarm()\n\r");
 
    // Compute alarm field value
    if (pMonth) {
 
        alarm |= AT91C_RTC_MONTHEN | ((*pMonth / 10) << 20) | ((*pMonth % 10) << 16);
    }
    if (pDay) {
 
        alarm |= AT91C_RTC_DATEEN | ((*pDay / 10) << 28) | ((*pDay % 10) << 24);
    }
 
    // Set alarm
    AT91C_BASE_RTC->RTC_CALALR = alarm;
}
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.