⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tod.c

📁 RTEMS (Real-Time Executive for Multiprocessor Systems) is a free open source real-time operating sys
💻 C
字号:
/* *  COPYRIGHT (c) 1998 by Radstone Technology * * * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU. * * You are hereby granted permission to use, copy, modify, and distribute * this file, provided that this notice, plus the above copyright notice * and disclaimer, appears in all copies. Radstone Technology will provide * no support for this code. * */#define MIN_YEAR 1996#include <stdlib.h>#include "bsp.h"#include "cmos.h"#include "../nvram/mk48t18.h"#define Bin2BCD(Value) (((Value / 10) << 4) | (Value % 10))#define BCD2Bin(BcdValue) ((BcdValue >> 4) * 10 + (BcdValue & 0x0f))/* * Private types */typedefvoid(*PTIMESET)(	rtems_time_of_day *pTOD);typedefboolean(*PTIMEGET)(	rtems_time_of_day *pTOD);typedef struct _TIME_ENTRY_TABLE{    PTIMESET	SetTime;    PTIMEGET	GetTime;} TIME_ENTRY_TABLE, *PTIME_ENTRY_TABLE;/* * Private routines *//* * DS1385 specific routines */static void timeDsSet(rtems_time_of_day *pTOD);static boolean timeDsGet(rtems_time_of_day *pTOD);/* * MK48T18 specific routines */static void timeMkSet(rtems_time_of_day *pTOD);static boolean timeMkGet(rtems_time_of_day *pTOD);TIME_ENTRY_TABLE timeDsTable ={	timeDsSet,	timeDsGet};TIME_ENTRY_TABLE timeMkTable ={	timeMkSet,	timeMkGet};/* * Private variables */static PTIME_ENTRY_TABLE pTimeFunc;/* * Mutual-exclusion semaphore */static rtems_id	semRTC;/* * This only works for the Gregorian calendar - i.e. after 1752 (in the UK) */rtems_unsigned8 GregorianDay(rtems_time_of_day *pTOD){	boolean isLeap;	unsigned long leapsToDate;	unsigned long lastYear;	unsigned long day;	unsigned long MonthOffset[] = { 0, 31, 59, 90, 120, 151,					181, 212, 243, 273, 304, 334 };	lastYear=pTOD->year-1;	/*	 * Number of leap corrections to apply up to end of last year	 */	leapsToDate = lastYear/4 - lastYear/100 + lastYear/400;	/*	 * This year is a leap year if it is divisible by 4 except when it is	 * divisible by 100 unless it is divisible by 400	 *	 * e.g. 1904 was a leap year, 1900 was not, 1996 is, and 2000 will be	 */	isLeap = (pTOD->year%4==0) &&			 ((pTOD->year%100!=0) || (pTOD->year%400==0));	if(isLeap && (pTOD->month>2))	{		day=1;	}	else	{		day=0;	}	day += lastYear*365 + leapsToDate + MonthOffset[pTOD->month-1] +		   pTOD->day;	return((rtems_unsigned8)(day%7));}voidDsWriteRawClockRegister (	rtems_unsigned8 Register,	rtems_unsigned8 Value)/*++Routine Description:    This routine reads the specified realtime clock register.    This function was added to bridge the BCD format of the IBM roms    and the binary formate of NTArguments:    Register - Supplies the number of the register whose value is read.Return Value:    The value of the register is returned as the function value.--*/{	outport_byte((rtems_unsigned8 *)RTC_PORT, Register & 0x7f);	/* Read the realtime clock register value. */	outport_byte((rtems_unsigned8 *)(RTC_PORT + 1), Value);	return;}rtems_unsigned8DsReadRawClockRegister (	rtems_unsigned8 Register)/*++Routine Description:    This routine reads the specified realtime clock register.    This function was added to bridge the BCD format of the IBM roms    and the binary formate of NTArguments:    Register - Supplies the number of the register whose value is read.Return Value:    The value of the register is returned as the function value.--*/{	rtems_unsigned8 ucDataByte;	outport_byte((rtems_unsigned8 *)RTC_PORT, Register & 0x7f);	/* Read the realtime clock register value. */	inport_byte((rtems_unsigned8 *)(RTC_PORT + 1), ucDataByte);	return ucDataByte;}voidDsWriteClockRegister (	rtems_unsigned8 Register,	rtems_unsigned8 Value)/*++Routine Description:    This routine writes the specified value to the specified realtime    clock register.Arguments:    Register - Supplies the number of the register whose value is written.    Value - Supplies the value that is written to the specified register.Return Value:    The value of the register is returned as the function value.--*/{	rtems_unsigned8 BcdValue;	BcdValue = Bin2BCD(Value);	DsWriteRawClockRegister(Register, BcdValue);	return;}rtems_unsigned8DsReadClockRegister (	rtems_unsigned8 Register)/*++Routine Description:    This routine reads the specified realtime clock register.Arguments:    Register - Supplies the number of the register whose value is read.Return Value:    The value of the register is returned as the function value.--*/{	rtems_unsigned8 BcdValue;	BcdValue =  DsReadRawClockRegister(Register);	return BCD2Bin(BcdValue);}voidtimeDsSet (    rtems_time_of_day *pTOD    )/*++Routine Description:    This routine sets the realtime clock.    N.B. This routine assumes that the caller has provided any required        synchronization to set the realtime clock information.Arguments:    pTOD - Supplies a pointer to a time structure that specifies the        realtime clock information.Return Value:    If the power to the realtime clock has not failed, then the time    values are written to the realtime clock and a value of TRUE is    returned. Otherwise, a value of FALSE is returned.--*/{	rtems_unsigned8 ucDataByte;	PCMOS_MAP pCMOS = (PCMOS_MAP)0;	/* If the realtime clock battery is still functioning, then write */	/* the realtime clock values, and return a function value of TRUE. */	/* Otherwise, return a function value of FALSE. */	ucDataByte = DsReadRawClockRegister(RTC_CONTROL_REGISTERD);	if (ucDataByte&DS1385_REGD_VALID)	{		/* Set the realtime clock control to set the time. */		ucDataByte = DS1385_REGB_HOURS_FMT | DS1385_REGB_SET_TIME;		DsWriteRawClockRegister(RTC_CONTROL_REGISTERB, ucDataByte);		/* Write the realtime clock values. */		DsWriteClockRegister(RTC_YEAR,				     (rtems_unsigned8)(pTOD->year%100));		if(pTOD->year>=100)		{			DsWriteClockRegister((rtems_unsigned8)					     ((unsigned long)&pCMOS->Century),					     pTOD->year/100);		}		DsWriteClockRegister(RTC_MONTH,				     (rtems_unsigned8)pTOD->month);		DsWriteClockRegister(RTC_DAY_OF_MONTH,				     (rtems_unsigned8)pTOD->day);		DsWriteClockRegister(RTC_DAY_OF_WEEK,				     (rtems_unsigned8)				     (GregorianDay(pTOD) + 1));		DsWriteClockRegister(RTC_HOUR,				     (rtems_unsigned8)pTOD->hour);		DsWriteClockRegister(RTC_MINUTE,				     (rtems_unsigned8)pTOD->minute);		DsWriteClockRegister(RTC_SECOND,				     (rtems_unsigned8)pTOD->second);		/* Set the realtime clock control to update the time. */		ucDataByte &= ~DS1385_REGB_SET_TIME;		DsWriteRawClockRegister(RTC_CONTROL_REGISTERB, ucDataByte);		return;	}	else	{		return;	}}booleantimeDsGet (    rtems_time_of_day *pTOD    )/*++Routine Description:    This routine queries the realtime clock.Arguments:    pTOD - Supplies a pointer to a time structure that receives        the realtime clock information.Return Value:    If the power to the realtime clock has not failed, then the time    values are read from the realtime clock and a value of TRUE is    returned. Otherwise, a value of FALSE is returned.--*/{	rtems_unsigned8 ucDataByte;	PCMOS_MAP pCMOS = (PCMOS_MAP)0;	/* If the realtime clock battery is still functioning, then read */	/* the realtime clock values, and return a function value of TRUE. */	/* Otherwise, return a function value of FALSE. */	ucDataByte = DsReadRawClockRegister(RTC_CONTROL_REGISTERD);	if(ucDataByte&DS1385_REGD_VALID)	{		/* Wait until the realtime clock is not being updated. */		do		{			ucDataByte=DsReadRawClockRegister(RTC_CONTROL_REGISTERA);		} while (ucDataByte&DS1385_REGA_UIP);		/* Read the realtime clock values. */		pTOD->year=(rtems_unsigned16)				  (DsReadClockRegister(				   (rtems_unsigned8)				   (unsigned long)&pCMOS->Century)				  *100 + DsReadClockRegister(RTC_YEAR));		pTOD->month=DsReadClockRegister(RTC_MONTH);		pTOD->day=DsReadClockRegister(RTC_DAY_OF_MONTH);		pTOD->hour=DsReadClockRegister(RTC_HOUR);		pTOD->minute=DsReadClockRegister(RTC_MINUTE);		pTOD->second=DsReadClockRegister(RTC_SECOND);		return TRUE;	}	else	{		return FALSE;	}}voidtimeMkSet (    rtems_time_of_day *pTOD    )/*++Routine Description:    This routine sets the realtime clock.    N.B. This routine assumes that the caller has provided any required        synchronization to set the realtime clock information.Arguments:    pTOD - Supplies a pointer to a time structure that specifies the        realtime clock information.Return Value:    If the power to the realtime clock has not failed, then the time    values are written to the realtime clock and a value of TRUE is    returned. Otherwise, a value of FALSE is returned.--*/{	PMK48T18_NVRAM_MAP pNvRAM = MK48T18_BASE;	/*	 * Set the RTC into write mode	 */	pNvRAM->CMOS.Control|=MK48T18_CTRL_WRITE;	EIEIO;	/*	 * Write the realtime clock values.	 */	pNvRAM->CMOS.Year = (rtems_unsigned8)Bin2BCD(pTOD->year%100);	if(pTOD->year>=100)	{	    pNvRAM->CMOS.Century=(rtems_unsigned8)	    			 Bin2BCD(pTOD->year/100);	}	pNvRAM->CMOS.Month  = (rtems_unsigned8)Bin2BCD(pTOD->month);	pNvRAM->CMOS.Date   = (rtems_unsigned8)Bin2BCD(pTOD->day);	pNvRAM->CMOS.Day    = (rtems_unsigned8)(GregorianDay(pTOD) + 1);	pNvRAM->CMOS.Hour   = (rtems_unsigned8)Bin2BCD(pTOD->hour);	pNvRAM->CMOS.Minute = (rtems_unsigned8)Bin2BCD(pTOD->minute);	pNvRAM->CMOS.Second = (rtems_unsigned8)Bin2BCD(pTOD->second);	/*	 * Set the realtime clock control to update the time.	 */	EIEIO;	pNvRAM->CMOS.Control&=~MK48T18_CTRL_WRITE;}booleantimeMkGet (    rtems_time_of_day *pTOD    )/*++Routine Description:    This routine queries the realtime clock.    N.B. This routine is required to provide any synchronization necessary         to query the realtime clock information.Arguments:    pTOD - Supplies a pointer to a time structure that receives        the realtime clock information.Return Value:    If the power to the realtime clock has not failed, then the time    values are read from the realtime clock and a value of TRUE is    returned. Otherwise, a value of FALSE is returned.--*/{	PMK48T18_NVRAM_MAP pNvRAM = MK48T18_BASE;	/*	 * Set the RTC into read mode	 */	pNvRAM->CMOS.Control|=MK48T18_CTRL_READ;	EIEIO;	/*	 * Read the realtime clock values.	 */	pTOD->year = (rtems_unsigned16)(100*BCD2Bin(pNvRAM->CMOS.Century)+					      BCD2Bin(pNvRAM->CMOS.Year));	pTOD->month = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Month);	pTOD->day = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Date);	pTOD->hour = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Hour);	pTOD->minute = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Minute);	pTOD->second = (rtems_unsigned8)BCD2Bin(pNvRAM->CMOS.Second);	/*	 * Set the realtime clock control to normal mode.	 */	EIEIO;	pNvRAM->CMOS.Control&=~MK48T18_CTRL_READ;	return TRUE;}/* * Set up entry table */voidInitializeRTC(void){	rtems_status_code sc;	switch(ucSystemType)	{		case SYS_TYPE_PPC1:		{			if(ucBoardRevMaj<5)			{				pTimeFunc=&timeDsTable;				break;			}			/*			 * For the 005 and later drop through to the PPC1a support			 */		}		case SYS_TYPE_PPC1a:		{			pTimeFunc=&timeMkTable;			break;		}		default:		{			pTimeFunc=&timeDsTable;			break;		}	}	/*	 * Set up mutex semaphore	 */	sc = rtems_semaphore_create (		rtems_build_name ('R', 'T', 'C', 's'),		1,		RTEMS_BINARY_SEMAPHORE |		RTEMS_INHERIT_PRIORITY |		RTEMS_PRIORITY,		RTEMS_NO_PRIORITY,		&semRTC);	if (sc != RTEMS_SUCCESSFUL)	{		rtems_fatal_error_occurred (sc);	}}void setRealTimeToRTEMS(){	rtems_time_of_day rtc_tod;	rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT);	(pTimeFunc->GetTime)(&rtc_tod);	rtems_semaphore_release(semRTC);	/*	 * Millenium fix...	 *	 * If year is earlier than MIN_YEAR then assume the clock has wrapped from	 * 1999 to 1900 so advance by a century	 */	if(rtc_tod.year<MIN_YEAR)	{		rtc_tod.year+=100;		rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT);		(pTimeFunc->SetTime)(&rtc_tod);		rtems_semaphore_release(semRTC);	}	rtc_tod.ticks=0;	rtems_clock_set( &rtc_tod );}void setRealTimeFromRTEMS(){	rtems_time_of_day rtems_tod;	rtems_clock_get( RTEMS_CLOCK_GET_TOD, &rtems_tod );	rtems_semaphore_obtain(semRTC, RTEMS_WAIT, RTEMS_NO_TIMEOUT);	(pTimeFunc->SetTime)(&rtems_tod);	rtems_semaphore_release(semRTC);}int checkRealTime(){  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -