// // ds1305.c is a file that contains functions for dealing with the ds1305 // timekeeping chip from Dallas Semiconductor. The device has a real time // clock calendar, plus about 96 bytes of non-volatile RAM. The device // uses an SPI interface. // // This file contains routines required to read and write the ds1305. // // The major functions in this file are the ReadBlock and WriteBlock routines. // plus an Init routine. // // The original version of this file assumes that the SPI device is connected // to the SPI bus, but the chip select line is found on PORTB pin 0 // // To change the chip select line, you only need to change the two routines // ds1305_spi_select and ds1305_spi_deselect. // // This file is fairly straight forward ANSI C, though it does use the C++ // end of line comment style. It was compiled using the Imagecraft C compiler, // and should be portable between the 68HC11 and the 68HC12 CPU's. // // Created: 4/30/2000 kevinro@kevinro.com // // See the companion article for this code at // www.seattlerobotics.org/encoder/200005/ds1305.html // #include #include "ds1305.h" // // This routine selects the ds1305 device. Must be called // before transferring data to the SPI port // // This assumes the ds1305 is connected to PORTB:0 // // Need to insure that this is CPHA = 1 due to the // timing requirements of the part. If the SPI bus is shared // with other devices, their Select routines should reset these // parameters to their value. // Raising the line enables the part void ds1305_spi_select() { SPCR = SPCR | 0x04; PORTB = PORTB | 0x01; } // // This routine deselects the device by lowering the CE // line. Must be done after the xfer is complete // void ds1305_spi_deselect() { PORTB = PORTB & 0xFE; } // // This INIT routine sets up PORTD:SS to be an output pin // which disables the mode-fault detection circuit. It // also sets up the SPI system for CPOL = 0, CPHA = 1 // void ds1305_Init() { PORTD = PORTD | 0x38; DDRD = DDRD | 0x38; ds1305_spi_deselect(); SPCR = 0x54; } // This routine exchanges 1 byte with the SPI port. unsigned char ds1305_spi_xfer(unsigned char cByte) { SPDR = cByte; while ((SPSR & 0x80) == 0); return SPDR; } // // ReadBlock reads iCount bytes starting at cAddr into the // buffer pBuffer // void ds1305_ReadBlock(unsigned char cAddr, unsigned char *pBuffer, unsigned int iCount) { ds1305_spi_select(); ds1305_spi_xfer(cAddr); while(iCount--) { *pBuffer++ = ds1305_spi_xfer(0); } ds1305_spi_deselect(); } // // WriteBlock sends iCount bytes from the buffer pBuffer // to the device at iAddr + 0x80. The device uses a split // memory map where all write addresses are at address +0x80 // void ds1305_WriteBlock(unsigned char iAddr, unsigned char *pBuffer, unsigned int iCount) { ds1305_spi_select(); ds1305_spi_xfer(iAddr + 0x80); while(iCount--) { ds1305_spi_xfer(*pBuffer++); } ds1305_spi_deselect(); }