From: csibtfr!tims@apple.com (Tim Seaman)
Newsgroups: comp.os.vxworks
Subject: re:  MK48T08 TIme-of-Day Chip Interface Code
Date: Fri, 4 Sep 92 14:32:33 PDT
Organization: Lawrence Berkeley Laboratory, Berkeley CA
NNTP-Posting-Host: 128.3.112.16
Originator: daemon@vxw.ee.lbl.gov


----- Begin Included Message -----

shaffer@stef.crd.ge.com writes...

Has anyone written interface code for the MK48T08 (or MK48T02 or MK48T12)
Timekeeper RAM chip? This chip provides time-of-day (seconds through
year) as well as non-volatile RAM, and is widely used on processor
cards.  In particular, I would be interested in C functions to:
 - set or display the time and date, e.g. as in the Unix date command;
 - read the time, e.g. as in the Unix time() or ftime() functions;
 - a version of calendarHostInit() to start the Ada calendar from the
   MK48Txx, rather than from a Unix host (for VADSworks).

I would think this code would be of wide interest because of the
frequency of use of this chip. I didn't seen anything that looked likely
in the vxWorks archive.

Thanks in advance for any help.

     Phillip L. Shaffer                  shaffer_phillip@ae.ge.com
     GE Aircraft Engines, MS A320
     1 Neumann Way
     Cincinnati, OH 45215

----- End Included Message -----

We have some simple code here which we use to program and
retrieve time/date information using the MK48T02 on a Tadpole
TP32V CPU Board. 


/* %W%	%G%                              -*- Mode: C -*- 
 * 
 * Copyright (c) Condor Systems Inc.
 * 
 * mk48t02.c
 * 
 * Description     : 
 * 
 * Author          : Tim Seaman
 * Created On      : Fri Sep  4 14:30:13 1992
 * Last Modified By: Tim Seaman
 * Last Modified On: Fri Sep  4 14:31:13 1992
 * 
 * VERSION   SPR   MODIFIER   DATE AND TIME
 * 
 */

#include "vxWorks.h"

typedef struct
	{
	int	hour;			/* 0 - 23 */
	int	minute;			/* 0 - 59 */
	int	second;			/* 0 - 59 */
	int	hundredthSec;		/* 0 - 99 */
	} SYS_TIME;

typedef struct
	{
	int	year;			/* 1990 - 2089 */
	int	month;			/* 1 - 12 */
	int	day;			/* 1 - 31 */
	int	dayOfWeek;		/* 1 - 7, Sun = 1 */
	} SYS_DATE;

/* MK48T02 RTC stuff for Tadpole TP32V */

#define RTC_ADDR_0	((char *) 0x004007f8)	/* RTC Register 0 - Control & Cal */
#define RTC_ADDR_1	((char *) 0x004007f9)	/* RTC Register 1 - Seconds + ST */
#define RTC_ADDR_2	((char *) 0x004007fa)	/* RTC Register 2 - Minutes */
#define RTC_ADDR_3	((char *) 0x004007fb)	/* RTC Register 3 - Hour + KS */
#define RTC_ADDR_4	((char *) 0x004007fc)	/* RTC Register 4 - Day-of-Week + FT */
#define RTC_ADDR_5	((char *) 0x004007fd)	/* RTC Register 5 - Day-of-Month */
#define RTC_ADDR_6	((char *) 0x004007fe)	/* RTC Register 6 - Month */
#define RTC_ADDR_7	((char *) 0x004007ff)	/* RTC Register 7 - Year */

#define RTC_WR_BIT	0x80				/* write bit */
#define RTC_RD_BIT	0x40				/* read bit */
#define RTC_CONTROL_CAL_VALUE	0x00	/* current calibration value */

/* forward references */

static void writeTpRtc();
static void readTpRtc();
static void intToBcd();
static int bcdToInt();


/*******************************************************************************
 *
 * timeDateSet - set time and date
 *
 * Returns:  OK if success, else ERROR
 *
 */
STATUS
timeDateSet(pTime, pDate)
    SYS_TIME *pTime;			/* ptr to time data */
    SYS_DATE *pDate;			/* ptr to date data*/
{
	unsigned char bcdData[7];
	
	/* Convert SYS_TIME and SYS_DATE info to bcd for RTC */

	/* hundredthSec ignored, since TP32V doesn't support it */

	intToBcd(pTime->second, &bcdData[0], 2);
	bcdData[0] &= 0x7f;
	intToBcd(pTime->minute, &bcdData[1], 2);
	bcdData[1] &= 0x7f;
	intToBcd(pTime->hour, &bcdData[2], 2);
	bcdData[2] &= 0x3f;
	intToBcd(pDate->dayOfWeek, &bcdData[3], 2);
	bcdData[3] &= 0x07;
	intToBcd(pDate->day, &bcdData[4], 2);
	bcdData[4] &= 0x3f;
	intToBcd(pDate->month, &bcdData[5], 2);
	bcdData[5] &= 0x1f;
	intToBcd((pDate->year % 100), &bcdData[6], 2);
	bcdData[6] &= 0xff;

	writeTpRtc(bcdData);
	
    return (OK);
}


/*******************************************************************************
 *
 * timeDateGet - get time and date
 *
 * Returns: OK if success, else ERROR
 *
 */
STATUS
timeDateGet(pTime, pDate)
    register SYS_TIME *pTime;		/* ptr to where time is returned */
    register SYS_DATE *pDate;		/* ptr to where date is returned */
{
	unsigned char bcdData[7];

	readTpRtc(bcdData);

    pTime->hundredthSec = 0;
    pTime->second       = bcdToInt(bcdData[0] & 0x7f);
    pTime->minute       = bcdToInt(bcdData[1] & 0x7f);
    pTime->hour 		= bcdToInt(bcdData[2] & 0x3f);
    pDate->dayOfWeek 	= bcdToInt(bcdData[3] & 0x07);
    pDate->day 			= bcdToInt(bcdData[4] & 0x3f);
    pDate->month 		= bcdToInt(bcdData[5] & 0x1f);
    pDate->year 		= bcdToInt(bcdData[6] & 0xff);

    if (pDate->year > 89)			/* then 20th century */
	pDate->year += 1900;
    else
	pDate->year += 2000;

    return (OK);
}


/*******************************************************************************
 *
 * writeTpRtc - Write time & date to TadPole TP32V RTC (real-time-clock)
 *
 * Returns: none
 *
 */
static void 
writeTpRtc(timeData)
unsigned char timeData[];
{
    int oldlevel;			/* current interrupt level mask */

	/* Perform write sequence to MK48T02 Device */
	/* Set WR (write) bit */
	/* Set all time/date values */
	/* Reset WR bit to set new time into RTC */

    oldlevel = intLock();		/* disable interrupts */

	*RTC_ADDR_0 = RTC_CONTROL_CAL_VALUE | RTC_WR_BIT;

	*RTC_ADDR_1 = timeData[0];	/* seconds */
	*RTC_ADDR_2 = timeData[1];	/* minutes */
	*RTC_ADDR_3 = timeData[2];	/* hours */
	*RTC_ADDR_4 = timeData[3];	/* day-of-week */
	*RTC_ADDR_5 = timeData[4];	/* day */
	*RTC_ADDR_6 = timeData[5];	/* month */
	*RTC_ADDR_7 = timeData[6];	/* year */
	
	*RTC_ADDR_0 = RTC_CONTROL_CAL_VALUE;
	
    intUnlock(oldlevel);		/* enable interrupts */
	
}


/*******************************************************************************
 *
 * readTpRtc - Read time & date from TadPole TP32V RTC (real-time-clock)
 *
 * Returns: none
 *
 */
static void 
readTpRtc(timeData)
unsigned char timeData[];
{
    int oldlevel;			/* current interrupt level mask */

	/* Perform read sequence from MK48T02 Device */
	/* Set RD (read) bit to latch current time/date */
	/* Read all time/date values */
	/* Reset RD bit */

    oldlevel = intLock();		/* disable interrupts */

	*RTC_ADDR_0 = RTC_CONTROL_CAL_VALUE | RTC_RD_BIT;

	timeData[0] = *RTC_ADDR_1;	/* seconds */
	timeData[1] = *RTC_ADDR_2;	/* minutes */
	timeData[2] = *RTC_ADDR_3;	/* hours */
	timeData[3] = *RTC_ADDR_4;	/* day-of-week */
	timeData[4] = *RTC_ADDR_5;	/* day */
	timeData[5] = *RTC_ADDR_6;	/* month */
	timeData[6] = *RTC_ADDR_7;	/* year */
	
	*RTC_ADDR_0 = RTC_CONTROL_CAL_VALUE;

    intUnlock(oldlevel);		/* enable interrupts */
	
}


/*************************************************************
*
* intToBcd - convert an integer to binary-coded decimal.
*
* This procedure will convert the integer parameter to
* binary-coded decimal.
*
* RETURNS:
*	pointer to BCD value
*
*/
static void 
intToBcd(intValue, bcdPtr, nbrDigits)
    long intValue;	/* value to be encoded */
    unsigned char bcdPtr[];	/* ptr to BCD results */
    int  nbrDigits;	/* nbr of BCD digits */
    {

	register ii;		/* loop counter */
	register jj;		/* loop counter */
	unsigned char bcdText[10];

	if (nbrDigits == 6)
	    sprintf (bcdText, "%06ld", intValue);
	else if (nbrDigits == 4)
	    sprintf (bcdText, "%03ld", intValue);
	else if (nbrDigits == 2)
	    sprintf (bcdText, "%02ld", intValue);

	/*  encode a maximum of 3 BCD bytes */

	jj = 0;
	for (ii = 0; ii < nbrDigits/2; ii++)
	{
	    if (bcdText[jj] == 0)
		break;

	    bcdPtr[ii] = (bcdText[jj] - 0x30);
	    jj++;
	    bcdPtr[ii] = bcdPtr[ii] << 4;

	    if (bcdText[jj] == 0)
		break;

	    bcdPtr[ii] |= (bcdText[jj] - 0x30);
	    jj++;
	}

    }  /* end intToBcd */


/*************************************************************
*
* bcdToInt - convert a 1-byte BCD value to an integer value.
*
* This procedure will convert a 1-byte binary-coded decimal
* value to an integer value.
*
* RETURNS:
*	integer value
*
*/
static int
bcdToInt (bcdVal)
    unsigned char bcdVal;	/* BCD value */
    {

	int totalVal = 0;	/* converted value */

	/*  convert the BCD digits to int */

	totalVal = (((bcdVal & 0xf0)>>4)*10) + (bcdVal & 0x0f);

	return (totalVal);

    }  /* bcdToInt */



Newsgroups: comp.os.vxworks