/************************************************************************* ; 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*/ } /*************************************************************************/