/*************************************************************************
; Ds1302Spi.c - Demonstrates the use of the 68HC12 SPI for the DS1302 RTC.
;
; MCU: 68HC912B32, MicroC/OS-II
;
; 03/09/01 Todd Morton
;
; Revised 4/26/03 Reuben Brown
; 1. Changed SCK speed to 500 KHz
; Revised 5/10/03 Reuben Brown
; 1. Added Store32BitNum
; Store16BitNum
; Get16BitNum
; Get32BitNum
; RamRetrieve
; RamStore
; Revised 5/27/03 Reuben Brown
; 1. Added WriteTime Function
;
;
**************************************************************************
* Master header file
*************************************************************************/
#include "includes.h"
OS_EVENT *SpiKey;
/*************************************************************************
* Function prototypes (Public)
*************************************************************************/
void DS1302SpiInit(void);
void RTCBurstRd(RTCCLK *rtcbuf);
void RamRetrieve(void);
void RamStore(void);
void WriteTime(INT8U hr, INT8U min);
/*************************************************************************
* Function prototypes (Private)
*************************************************************************/
INT8U DS1302SpiRd(INT8U raddr);
void DS1302SpiWr(INT8U waddr, INT8U wdata);
void Store32BitNum(INT32U number, INT8U *arrayptr, INT8U address);
void Store16BitNum(INT16U number, INT8U *arrayptr, INT8U address);
INT16U Get16BitNum(INT8U *arrayptr, INT8U address);
INT32U Get32BitNum(INT8U *arrayptr, INT8U address);
/*************************************************************************
*Global Variables
*************************************************************************/
INT8U TwoByteArray[2];
INT8U *TwoByteArrayPtr = TwoByteArray;
INT8U FourByteArray[4];
INT8U *FourByteArrayPtr = FourByteArray;
/*************************************************************************
* Ds1302SpiInit - Initialize SPI for the Ds1302
*************************************************************************/
void DS1302SpiInit(void){
PORTS &= ~SS;
DDRS |= (SS|SCK|MOMI);
SP0BR = 0x03; /*set bit rate to 1MHz */
SP0CR1 = 0x71; /* Enable,Mstr,WireOR,CPOL:CPHA=00,LSB First*/
SP0CR2 = 0x01; /* Bidirectional SPI (MIMO) */
}
/*************************************************************************
* DS1302SpiRd - Read DS1302. Returns the RTC register contents addressed
* by raddr.
*************************************************************************/
INT8U DS1302SpiRd(INT8U raddr){
INT8U err;
OSMutexPend(SpiKey,0,&err);
PORTS |= SS;
DDRS |= MOMI;
SP0DR = raddr;
while((SP0SR & SPIF) == 0){}
DDRS &= ~MOMI;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
PORTS &= ~SS;
OSMutexPost(SpiKey);
return SP0DR;
}
/*************************************************************************
* DS1302SpiWr - Write to DS1302. waddr is the command/address word and
* wdata is the write data.
*************************************************************************/
void DS1302SpiWr(INT8U waddr, INT8U wdata){
INT8U err;
OSMutexPend(SpiKey,0,&err);
PORTS |= SS;
DDRS |= MOMI;
SP0DR = waddr;
while((SP0SR & SPIF) == 0){}
SP0DR = wdata;
while((SP0SR & SPIF) == 0){}
PORTS &= ~SS;
OSMutexPost(SpiKey);
}
/*************************************************************************
* RTCBurstRd - Burst read of DS1302 RTC clock registers.
* rtcbuf is the address of a RTCCLK structure to place the
* copy of the RTC registers.
*************************************************************************/
void RTCBurstRd(RTCCLK *rtcbuf){
INT8U err;
OSMutexPend(SpiKey,0,&err);
PORTS |= SS;
DDRS |= MOMI;
SP0DR = CBRSTRD;
while((SP0SR & SPIF) == 0){}
DDRS &= ~MOMI;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->sec = SP0DR;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->min = SP0DR;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->hr = SP0DR;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->dom = SP0DR;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->month = SP0DR;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->dow = SP0DR;
SP0DR = 0xFF;
while((SP0SR & SPIF) == 0){}
rtcbuf->year = SP0DR;
PORTS &= ~SS;
OSMutexPost(SpiKey);
}
/*******************************************************************************
*RamRetrieve
* Restores all variables to MotoVars structure from
* DS1302 battery backed RAM. Should be called at startup
* Reuben Brown 5/10/03
*******************************************************************************/
void RamRetrieve(void){
INT8U err;
MotoVars.TrpTimeSecs = DS1302SpiRd(TRIPTIMESECRD);
MotoVars.TrpTimeMins = DS1302SpiRd(TRIPTIMEMINRD);
MotoVars.TrpTimeHrs = DS1302SpiRd(TRIPTIMEHRRD);
MotoVars.TrpSpeed = DS1302SpiRd(TRIPSPEEDRD);
MotoVars.Mpg = DS1302SpiRd(MPGRD);
MotoVars.Wheel = Get16BitNum(TwoByteArrayPtr, WHEELRD);
MotoVars.Tank = Get16BitNum(TwoByteArrayPtr, TANKRD);
MotoVars.Odo = Get32BitNum(FourByteArrayPtr, ODORD);
MotoVars.TrpOdo = Get32BitNum(FourByteArrayPtr, TRIPODORD);
MotoVars.MpgOdo = Get32BitNum(FourByteArrayPtr, MPGODORD);
}
/*******************************************************************************
*Store16BitNum
* Stores a 16 bit number to the DS1302 Battery Backed Ram
* a pointer the number, a pointer to a 2 byte array and the
* beginning address to store to are passed
*
* Resources Used: Ds1302Spi.c - DS1302SpiWr(waddr, wdata)
* Reuben Brown 5/12/03
*******************************************************************************/
void Store16BitNum(INT16U number, INT8U *arrayptr, INT8U address){
arrayptr[0] = (INT8U)(number >> 8); /* MSB */
arrayptr[1] = (INT8U)number; /* LSB */
DS1302SpiWr(address, arrayptr[0]);
DS1302SpiWr(address + 2, arrayptr[1]);
}
/*******************************************************************************
*Get16BitNum
* Retrieves a 16 bit number from the DS1302 battery backed RAM
* 2 byte array and beginning address to read from are passed
* Returns 16 bit number
*
* Resources Used: Ds1302Spi.c - DS1302SpiRd()
* Reuben Brown 5/12/03
*******************************************************************************/
INT16U Get16BitNum(INT8U *arrayptr, INT8U address){
INT16U buffer;
arrayptr[0] = DS1302SpiRd(address); //MSB
arrayptr[1] = DS1302SpiRd(address + 2); //LSB
buffer = arrayptr[0];
buffer = buffer * 0x100;
buffer += arrayptr[1];
return buffer;
}
/*******************************************************************************
*Store32BitNum
* Stores a 32 bit number to the DS1302 Battery Backed Ram
* a pointer the number, a pointer to a 4 byte array and the
* beginning address to store to are passed
*
* Resources Used: Ds1302Spi.c
* Reuben Brown 5/12/03
*******************************************************************************/
void Store32BitNum(INT32U number, INT8U *arrayptr, INT8U address){
INT8U count = 0;
arrayptr[0] = (INT8U)(number >> 24); //MSB
arrayptr[1] = (INT8U)(number >> 16);
arrayptr[2] = (INT8U)(number >> 8);
arrayptr[3] = (INT8U)number; //LSB
DS1302SpiWr(address, arrayptr[0]);
DS1302SpiWr(address + 2, arrayptr[1]);
DS1302SpiWr(address + 4, arrayptr[2]);
DS1302SpiWr(address + 6, arrayptr[3]);
}
/*******************************************************************************
*Get32BitNum
* Retrieves a 32 bit number from the DS1302
* a pointer the number, a pointer to a 4 byte array and the
* beginning address to store to are passed
*
* Resources Used: Ds1302Spi.c
* Reuben Brown 5/12/03
*******************************************************************************/
INT32U Get32BitNum(INT8U *arrayptr, INT8U address){
INT32U buffer;
arrayptr[0] = DS1302SpiRd(address);
arrayptr[1] = DS1302SpiRd(address + 2);
arrayptr[2] = DS1302SpiRd(address + 4);
arrayptr[3] = DS1302SpiRd(address + 6);
buffer = arrayptr[0];
buffer *= 0x100;
buffer += arrayptr[1];
buffer *= 0x100; // Shift Right one byte
buffer += arrayptr[2];
buffer *= 0x100;
buffer += arrayptr[3];
return buffer;
}
/****************************************************************************
* RamStore()
*
* Stores all vital members of MotoVars Structure to DS1302 Ram
*
* Reuben Brown 5/24/03
*****************************************************************************/
void RamStore(void){
INT8U err;
DS1302SpiWr(TRIPTIMESECWR, MotoVars.TrpTimeSecs);
DS1302SpiWr(TRIPTIMEMINWR, MotoVars.TrpTimeMins);
DS1302SpiWr(TRIPTIMEHRWR, MotoVars.TrpTimeHrs);
DS1302SpiWr(TRIPSPEEDWR, MotoVars.TrpSpeed);
DS1302SpiWr(MPGWR, MotoVars.Mpg);
Store16BitNum(MotoVars.Wheel, TwoByteArrayPtr, WHEELWR);
Store16BitNum(MotoVars.Tank, TwoByteArrayPtr, TANKWR);
Store32BitNum(MotoVars.Odo, FourByteArrayPtr, ODOWR);
Store32BitNum(MotoVars.TrpOdo, FourByteArrayPtr, TRIPODOWR);
Store32BitNum(MotoVars.MpgOdo, FourByteArrayPtr, MPGODOWR);
}
/****************************************************************************
* WriteTime
*
* Parameters: hr, min
* writes hr and min to the DS1302 RTC
*
* Reuben Brown 5/24/03
*****************************************************************************/
void WriteTime(INT8U hr, INT8U min){
DS1302SpiWr(SECWR, 0); /* Set seconds equal to 0 */
DS1302SpiWr(MINWR, min); /* Write user entered minutes to clock*/
DS1302SpiWr(HRWR, (hr | AM));/* Write user entered hours to clock in AM/PM format*/
}
/*************************************************************************/