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

📄 m48t37.c

📁 LoPEC Early Access VxWorks BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
/* m48t37.c - M48T37 library *//* Copyright 2000-2001 Motorola, Inc. All Rights Reserved *//*modification history--------------------01a,13feb01,cak  Created from m48tWdt.c(01c-MV5100) and sysRtc.c(01b-CPV5000).*//*DESCRIPTIONThis library provides support routines for the real-time clock, alarm clock,and Watchdog Timer sub-functions of the M48T37 "Timekeeper" RTC chip.  .IP "Alarm Clock"The alarm clock sub-function of the M48T37 can be configured to go off oncea month on a predetermined day, hour, minute, and second, to go off once a day at a predetermined hour, minute, and second, to go off once an hour at apredetermined minute and second, to go off once a minute at a predeterminedsecond, or to go off once a second. When the clock information matches the alarm clock settings an interrupt isgenerated.To disable the alarm clock, you write "0" to the alarm date registers.  Analarm clock interrupt is cleared by a read to the FLAGS register.A call to m48t37AlarmShow() will display the current alarm clock configuration values..IP "Real-Time Clock"The real-time clock sub-function of the M48T37 consists of 8 registers tostore the date and time.  The 8 values are as follows:.CS	Year			00-99	Month			01-12	Date ( day of month )	01-31	Day ( day of week )	01-07	Hour			00-23	Min			00-59	Sec 			00-59	Century			00-99.CEAll values in the RTC registers are stored in BCD ( binary coded decimal ).Since the RTC_DATE_TIME and ALARM_DATE_TIME structures contain integers twomacros have been defined in m48t37.h which convert from binary to BCD andvice-versa.  The macros are BIN_TO_BCD (bin) and BCD_TO_BIN (bcd).	.IP "Failsafe Timer"The Failsafe sub-function is disabled at power-up and after a reset. The first call to m48t37FailsafeSet() arms the failsafe and subsequent calls tom48t37FailsafeSet() will extend the failsafe timer and prevent it from expiring.If m48t37FailsafeSet() is called with a timeout of zero, the failsafe timerwill be disabled.  The timer can also be disabled with a call to m48t37FailsafeCancel(). Failsafe expiration can be annunciated as either a maskable interrupt (IRQ 15) or as a board reset event. The selection is made by the "reset" parameter passed to m48t37FailsafeSet(). If "reset" is TRUE, a board reset event occurs when the failsafe expires. If "reset" is FALSE, an interrupt is generated.A call to m48t37FailsafeCausedReset() will return a boolean indicatingwhether the failsafe timer caused the last board reset.  To determineif the failsafe timer caused the last reset you must call this routinebefore setting an alarm, since setting the alarm will clear the failsafe timer flag.When failsafe expiration is annunciated using an interrupt, an interrupt handler must be attached to the proper vector using intConnect() and the interrupt must be enabled using intEnable() before calling m48t37FailsafeSet() to arm the failsafe timer. If recovery from the interruptis desired, the interrupt service routine must call m48t37FailsafeSet() with "seconds" set to 0, or m48t37FailsafeCancel(). This operation disables the failsafe timer and clears the timer interrupt. If desired, the failsafe timer can be re-enabled by calling m48t37FailsafeSet() with the "seconds" parameter set non-zero.A two-stage failsafe can be implemented by initially configuring the failsafe timer for interrupt generation and re-configuring it for reset generation during the failsafe service interrupt. The second occurrence of the failsafe will trigger a board reset.The m48t37FailsafeGet() function returns the current failsafe configuration (not the amount of time remaining until timer expiration). Failsafe service code can use this function to extend the failsafe timeout without knowing the initial setting as follows:.CS UCHAR seconds; BOOL  reset; m48t37FailsafeGet (&seconds, &reset); m48t37FailsafeSet (seconds,  reset);.CEA call to m48t37FailsafeShow() will display the current configuration of the failsafe timer.  m48t37FailsafeShow() simply displays the results of a call to m48t37FailsafeGet().INCLUDE FILES: m48t37.h*//* includes */#include "m48t37.h"/* forward declarations */IMPORT void sysAlarmIntr (void);IMPORT void sysFailsafeIntr (void);STATUS m48t37RtcSet (RTC_DATE_TIME *rtc_time);STATUS m48t37RtcShow (void);STATUS m48t37RtcGet (RTC_DATE_TIME *rtc_time);void   m48t37DateTimeHook (DOS_DATE_TIME *pDateTime);STATUS m48t37AlarmSet (UCHAR method, ALARM_DATE_TIME *alarm_time);STATUS m48t37AlarmCancel (void);STATUS m48t37AlarmGet (UCHAR *method, ALARM_DATE_TIME *alarm_time);STATUS m48t37AlarmShow (void);STATUS m48t37FailsafeSet (UCHAR seconds, BOOL reset);STATUS m48t37FailsafeGet (UCHAR *seconds, BOOL *reset);STATUS m48t37FailsafeCancel (void);STATUS m48t37Init (void);STATUS m48t37FailsafeShow (void);BOOL m48t37FailsafeCausedReset (void);#if  ((defined INCLUDE_RTC) || (defined INCLUDE_FAILSAFE))LOCAL STATUS m48t37RtcDateTest (RTC_DATE_TIME *rtc_time);LOCAL STATUS m48t37AlarmDateTest (ALARM_DATE_TIME *alarm_time);LOCAL void m48t37Intr (void);/********************************************************************************* m48t37RtcDateTest - test whether date/time values are valid* * This routine tests the validity of the values in the RTC_DATE_TIME* structure.** RETURNS: OK, or ERROR if any values are invalid*/LOCAL STATUS m48t37RtcDateTest    (    RTC_DATE_TIME * rtc_time    /* pointer to time keeping structure */    )    {    /* Check validity of seconds value */    if (rtc_time->second < 0 || rtc_time->second > 59)        {	return (ERROR);        }        /* Check validity of minutes value */    if (rtc_time->minute < 0 || rtc_time->minute > 59)        {	return (ERROR);        }    /* Check validity of hours value */    if (rtc_time->hour < 0 || rtc_time->hour > 23)        {	return (ERROR);        }    /* Check validity of day of week value */    if (rtc_time->day_of_week < 1 || rtc_time->day_of_week > 7)        {	return (ERROR);        }    /* Check validity of day of month value */    if (rtc_time->day_of_month < 1 || rtc_time->day_of_month > 31)        {	return (ERROR);        }    /* Check validity of month value */    if (rtc_time->month < 1 || rtc_time->month > 12)        {	return (ERROR);        }    /* Check validity of year value */    if (rtc_time->year < 0 || rtc_time->year > 99)        {	return (ERROR);        }    /* Check validity of century value */    if (rtc_time->century < 0 || rtc_time->century > 99)        {	return (ERROR);        }       return (OK);     }/********************************************************************************* m48t37AlarmDateTest - test whether alarm date/time values are valid* * This routine tests the validity of the values in the ALARM_DATE_TIME* structure.** RETURNS: OK, or ERROR if any values are invalid.*/LOCAL STATUS m48t37AlarmDateTest    (    ALARM_DATE_TIME * alarm_time    /* pointer to time keeping structure */    )    {    /* Check validity of seconds value */    if (alarm_time->second < 0 || alarm_time->second > 59)        {	return (ERROR);        }        /* Check validity of minutes value */    if (alarm_time->minute < 0 || alarm_time->minute > 59)        {	return (ERROR);        }    /* Check validity of hours value */    if (alarm_time->hour < 0 || alarm_time->hour > 23)        {	return (ERROR);        }    /* Check validity of day of month value */    if (alarm_time->day_of_month < 1 || alarm_time->day_of_month > 31)        {	return (ERROR);        }    return (OK);     }/********************************************************************************* m48t37RtcSet - set the RTC's date/time per caller's values.** This routine allows the caller to set the RTC time and date.  The caller* must allocate space for an RTC_DATE_TIME structure, fill the structure* with the desired time and date, and call this routine.** RETURNS: OK, or ERROR if date/time values are invalid.*/STATUS m48t37RtcSet    (    RTC_DATE_TIME * rtc_time   /* pointer to time keeping structure */    )    {    UCHAR m48t37_control_values;	/* M48T37_CONTROL reg. */        /* Determine whether date/time values are valid */           if (m48t37RtcDateTest(rtc_time) == ERROR)            {            return (ERROR);            }        /* Set the write bit in the control register */        m48t37_control_values = NV_RAM_READ((ULONG)M48T37_CONTROL);        NV_RAM_WRITE((ULONG)M48T37_CONTROL, m48t37_control_values | M48T37_WRITE);        /* Set the date/time in the chip's registers */        NV_RAM_WRITE((ULONG)M48T37_SECOND, BIN_TO_BCD (rtc_time->second));        NV_RAM_WRITE((ULONG)M48T37_MINUTE, BIN_TO_BCD (rtc_time->minute));        NV_RAM_WRITE((ULONG)M48T37_HOUR, BIN_TO_BCD (rtc_time->hour));        NV_RAM_WRITE((ULONG)M48T37_DAY_OF_WEEK, BIN_TO_BCD (rtc_time->day_of_week));        NV_RAM_WRITE((ULONG)M48T37_DAY_OF_MONTH, BIN_TO_BCD (rtc_time->day_of_month));        NV_RAM_WRITE((ULONG)M48T37_MONTH, BIN_TO_BCD (rtc_time->month));        NV_RAM_WRITE((ULONG)M48T37_YEAR, BIN_TO_BCD (rtc_time->year));        NV_RAM_WRITE((ULONG)M48T37_CENTURY, BIN_TO_BCD (rtc_time->century));        /* Turn write bit in control register off */          NV_RAM_WRITE((ULONG)M48T37_CONTROL, m48t37_control_values);        return (OK);    }/********************************************************************************* m48t37RtcShow - Show the date/time on the user's display.** This routine retrieves the current RTC date and time and sends it in a * user-readable fashion to the user's display.** RETURNS: OK, or ERROR if unable to retrieve or print the current RTC* date and time. */STATUS m48t37RtcShow (void)    {    RTC_DATE_TIME * rtc_time = 0;	/* RTC date and time */    /* Retrieve the current RTC date and time */    if (m48t37RtcGet(rtc_time) == ERROR)       {       return (ERROR);       }    /* Send the date and time to the user's display */    if (rtc_time->year < 10)       {       printf ("\n\r            Time: %d:%d:%d  Date: %d/%d/%d0%d\n\r",               rtc_time->hour, rtc_time->minute, rtc_time->second,               rtc_time->month, rtc_time->day_of_month, rtc_time->century,               rtc_time->year);       }    else       {       printf ("\n\r            Time: %d:%d:%d  Date: %d/%d/%d%d\n\r",               rtc_time->hour, rtc_time->minute, rtc_time->second,               rtc_time->month, rtc_time->day_of_month, rtc_time->century,               rtc_time->year);       }    return (OK);    }/***************************************************************************** m48t37RtcGet - Get current RTC date/time. ** This routine allows the caller to obtain the current RTC time and date.* The caller must allocate space for an RTC_DATE_TIME structure, then call* this routine.  ** RETURNS: OK, or ERROR if unable to retrieve the current RTC date and time. */STATUS m48t37RtcGet    (    RTC_DATE_TIME * rtc_time      /* pointer to time keeping structure */    )    {    UCHAR m48t37_control_values; 	/* M48T37_CONTROL reg. */    /* Set read bit in the control register */    m48t37_control_values = NV_RAM_READ((ULONG)M48T37_CONTROL);    NV_RAM_WRITE((ULONG)M48T37_CONTROL, m48t37_control_values | M48T37_READ);    /* Read the values from the RTC into the rtc_time structure */    rtc_time->second = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_SECOND));     rtc_time->minute = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_MINUTE));     rtc_time->hour = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_HOUR));     rtc_time->day_of_week = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_DAY_OF_WEEK));    rtc_time->day_of_month = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_DAY_OF_MONTH));    rtc_time->month = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_MONTH));     rtc_time->year = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_YEAR));    rtc_time->century = BCD_TO_BIN (NV_RAM_READ((ULONG)M48T37_CENTURY));    /* Turn off the read bit in the control register */    NV_RAM_WRITE((ULONG)M48T37_CONTROL, m48t37_control_values);    return (OK);    }/********************************************************************************* m48t37DateTimeHook - This is a hook routine for the dosFsLib.** This routine fills in a DOS_DATE_TIME structure with the current date* and time.  This is used by the standard VxWorks dosFsLib as a way to update * the date/time values used for file timestamps.  This is "hooked" into the* dosFsLib during board initialization if both the dosFsLib and the RTC support* is included in the BSP.** RETURNS: void.** SEE ALSO: dosFsDateTimeInstall(), and the dosFsLib documentation.*/void m48t37DateTimeHook    (    DOS_DATE_TIME * pDateTime    /* pointer to time keeping structure */    )    {    RTC_DATE_TIME * rtc_time = 0;	/* RTC date and time */    int dos_year = 0;			/* Current year */     m48t37RtcGet(rtc_time);    /* Convert century and year to a form suitable for DOS_DATE_TIME */    dos_year = ((rtc_time->century * 100) + rtc_time->year);    /* Populate DOS_DATE_TIME structure within current RTC time and date */        pDateTime->dosdt_year = dos_year;    pDateTime->dosdt_month = rtc_time->month;    pDateTime->dosdt_day = rtc_time->day_of_month;    pDateTime->dosdt_hour = rtc_time->hour;    pDateTime->dosdt_minute = rtc_time->minute;    pDateTime->dosdt_second = rtc_time->second;     }/********************************************************************************* m48t37AlarmSet - Set an alarm clock per the caller's settings.** This routine sets an alarm clock. The alarm can be programmed to go off* once a month at a predetermined day, hour, minute, and second, to go off* once a day at a predetermined hour, minute, and second, to go off once an* hour at a predetermined minute and second, to go off once a minute at a* predetermined second, or to go off once a second. ** method can have the following values:** .CS** ALARM_EVERY_MONTH  = once a month* ALARM_EVERY_DAY    = once a day* ALARM_EVERY_HOUR   = once an hour* ALARM_EVERY_MINUTE = once a minute* ALARM_EVERY_SECOND = once a second** .CE** The alarm values for second, minute, hour, and day_of_month must be* passed to the function in an ALARM_DATE_TIME structure. ** RETURNS: OK, or ERROR if the settings are invalid.*/STATUS m48t37AlarmSet    (    UCHAR method,               	/* ALARM_EVERY_XXXX */    ALARM_DATE_TIME * alarm_time     	/* pointer to time keeping structure */    )    {    UCHAR alarm_clock_rpt1;		/* M48T37_ALARM_SECOND reg. */    UCHAR alarm_clock_rpt2;		/* M48T37_ALARM_MINUTE reg. */    UCHAR alarm_clock_rpt3;		/* M48T37_ALARM_HOUR reg. */    UCHAR alarm_clock_rpt4;		/* M48T37_ALARM_DATE reg. */    UCHAR m48t37_interrupts;		/* M48T37_INTERRUPTS reg. */    /* Determine whether date/time values are valid */       if (m48t37AlarmDateTest(alarm_time) == ERROR)        {        return (ERROR);        }    /* Clear the Flags register */    m48t37FailsafeCausedReset();    /* Set the Alarm Flag Enable Flag */    m48t37_interrupts = NV_RAM_READ((ULONG)M48T37_INTERRUPTS);    NV_RAM_WRITE((ULONG)M48T37_INTERRUPTS, m48t37_interrupts | M48T37_ALARM_ENABLE);    /* Set the values for the alarm clock */    NV_RAM_WRITE((ULONG)M48T37_ALARM_SECOND, BIN_TO_BCD (alarm_time->second));

⌨️ 快捷键说明

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