' ' ds1305.bas 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. ' There are also the ReadByte and WriteByte 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. ' ' Created: 4/30/2000 kevinro@kevinro.com ' ' See the companion article for this code at ' www.seattlerobotics.org/encoder/200005/ds1305.html ' ' ' ds1305_spi_select raises the chip select line, and also ' sets the SPI control register to operate the SPI port in ' CPOL = 0 CPHA = 1 mode ' ' The Chip Select is set to be on PORTB:0 and is active high ' for the DS1305. ' ds1305_spi_select: pokeb SPCR, peekb(SPCR) OR $04 pokeb PORTB, peekb(PORTB) OR $01 return ds1305_spi_deselect: pokeb PORTB, peekb(PORTB) AND $FE return ' ' ds1305_Init sets up the SPI port, and makes sure the part is ' deselected. ' ds1305_Init: ' Setup PORTB:0 to be low. Going high selects the DS1305 gosub ds1305_spi_deselect ' Set the DDRD5 bit so that SS is an output pin. This is an ' important step because it disables the mode fault detection ' feature of the SPI port. ' pokeb PORTD, peekb(PORTD) OR $38 pokeb DDRD, peek(DDRD) OR $38 ' Setup the SPI register to be MASTER, CPOL=0, CPHA=1 pokeb SPCR, $54 ' On a 68HC11, ECLOCK is 2mhz (assume 8mhz clock) which is OK ' On a 68HC12, ECLOCK is 8mhz, which is too fast. A prescale ' may be required on a 68HC12 return ' ' This routine exchanges bytes with the SPI port. This both sends and ' receives one byte at a time. ' ds1305_spi_xfer: pokeb SPDR, pop() do while (peekb(SPSR) AND $80) = 0 loop return peekb(SPDR) ' ' ds1305_Read_Block ' ' invoke using gosub ds1305_Read_Block ,

, ' ' Reads N bytes from address A into buffer P ' ds1305_Read_Block: ' Select the ds1305 for data operations gosub ds1305_spi_select ' Set the starting address on the ds1305. It is always ' the first byte sent gosub ds1305_spi_xfer,pick(2) ' Loop through the buffer reading the data in do while pick(0) <> 0 pokeb pick(1), usr(ds1305_spi_xfer,0) place 1, pick(1) + 1 place 0, pick(0) - 1 loop ' We are now done with the ds1305 gosub ds1305_spi_deselect ' In SBASIC, we remove our own arguments from the stack drop 3 return ' ' ds1305_Write_Block ' invoke using gosub ds1305_Write_Block ,

, ' ' Writes N bytes from buffer P to address A ' ds1305_Write_Block: ' Select the ds1305 for data operations gosub ds1305_spi_select ' An address with the high bit on is considered a ' write operation on the ds1305. gosub ds1305_spi_xfer,pick(2)+$80 ' Once the address has been sent, it will be automatically ' incremented after each operation ' Loop through the buffer sending the data to the chip do while pick(0) <> 0 gosub ds1305_spi_xfer,peekb(pick(1)) place 1,pick(1)+1 place 0,pick(0)-1 loop ' We are now done with the ds1305 gosub ds1305_spi_deselect ' In SBASIC, we remove our own arguments from the stack drop 3 return