replacing crystal with TCXO

I would like to drive the clock of the arduino from a TCXO instead of the 16MHz crystal, in order to get more accuracy (I would use a 0.3 ppm TCXO).
Has anyone done something like this ?
Also, how would this be wired, I see the crystals use pins XTAL1 and XTAL2, and two capacitors. On the other hand, the TCXO, along with VCC and GND has a single OUTPUT. Can I feed the clock output to XTAL1 and forget about XTAL2 ?

edzy:
I would like to drive the clock of the arduino from a TCXO instead of the 16MHz crystal, in order to get more accuracy (I would use a 0.3 ppm TCXO).
Has anyone done something like this ?
Also, how would this be wired, I see the crystals use pins XTAL1 and XTAL2, and two capacitors. On the other hand, the TCXO, along with VCC and GND has a single OUTPUT. Can I feed the clock output to XTAL1 and forget about XTAL2 ?

The 328P Atmel datasheet covers all the clocking options pretty well. And yes your TCXO clock output would wire to XTAL1 and leave XTAL2 as no connection. Note that there is a clock fuse change required from the standard clock fuse setting that the Arduino external crystal used:

Clock Sources
The device has the following clock source options, selectable by Flash Fuse bits as shown
below. The clock from the selected source is input to the AVR clock generator, and routed to the
appropriate modules.
Note: 1. For all fuses “1” means unprogrammed while “0” means programmed.
9.2.1 Default Clock Source
The device is shipped with internal RC oscillator at 8.0MHz and with the fuse CKDIV8 programmed,
resulting in 1.0MHz system clock. The startup time is set to maximum and time-out
period enabled. (CKSEL = "0010", SUT = "10", CKDIV8 = "0"). The default setting ensures that
all users can make their desired clock source setting using any available programming interface.
9.2.2 Clock Startup Sequence
Any clock source needs a sufficient VCC to start oscillating and a minimum number of oscillating
cycles before it can be considered stable.
To ensure sufficient VCC, the device issues an internal reset with a time-out delay (tTOUT) after
the device reset is released by all other reset sources. ”System Control and Reset” on page 48
describes the start conditions for the internal reset. The delay (tTOUT) is timed from the Watchdog
Oscillator and the number of cycles in the delay is set by the SUTx and CKSELx fuse bits. The
Table 9-1. Device Clocking Options Select(1)
Device Clocking Option CKSEL3...0
Low Power Crystal Oscillator 1111 - 1000
Full Swing Crystal Oscillator 0111 - 0110
Low Frequency Crystal Oscillator 0101 - 0100
Internal 128kHz RC Oscillator 0011
Calibrated Internal RC Oscillator 0010
External Clock 0000
Reserved 0001

Lefty

Hi.
My uno using resinator,can i replace it with tcxo.Any changing inside uno boot setup?

See reply #1.

edzy:
I would like to drive the clock of the arduino from a TCXO instead of the 16MHz crystal, in order to get more accuracy (I would use a 0.3 ppm TCXO).
Has anyone done something like this ?
Also, how would this be wired, I see the crystals use pins XTAL1 and XTAL2, and two capacitors. On the other hand, the TCXO, along with VCC and GND has a single OUTPUT. Can I feed the clock output to XTAL1 and forget about XTAL2 ?

The Arduino doesn't even use a crystal... it uses a ceramic resonator.

As far as accurate time, why not just get a good RTC (for example, this):

(click image to go to the page)

It works like a charm, it's temperature compensated and the ones I have keep perfect time within a second or less per month. A lot easier and less expensive than hacking your Arduino to add a TCXO.

(edit to add): Here's a driver I wrote for this RTC: GitHub - krupski/DS3234: Arduino drivers for the Dallas/Maxim DS3234 Real Time Clock

You should, however, give some thought to replacing the resonator with a real crystal, and one that's an integer multiple of common baud rates (like 18.432 MHz or 22.1184 MHz).

Here's a 2 terminal SMD crystal of 22.1184 MHz installed on a MEGA2560 R3:

Works like a charm.

Hi,

The Arduino doesn't even use a crystal... it uses a ceramic resonator.

Looks like a Crystal to me, and when I look at my board, and the bareduino kits I have.

Tom.... :slight_smile:

arduino-uno-schematic.pdf (37.7 KB)

TomGeorge:
Looks like a Crystal to me, and when I look at my board, and the bareduino kits I have.

The stock Uno R3 has both a crystal and a resonator. The Atmega8U2 uses a crystal; the Atmega328 uses a resonator. In addition to being less accurate, the frequency of a resonator is also more temperature sensitive than with a crystal.

Krupski:
As far as accurate time, why not just get a good RTC (for example, this):

(click image to go to the page)

It adds another chip (and kind of a big one). Plus the software interface. You also have the issue of synchronizing to a time base that has a resolution of 1 second. You're either freezing the clock or skipping a second every once in a while. Or you have to read the RTC multiple times quickly to try and assess the drift more precisely. Why not just have a better internal clock? The main point of an RTC is to maintain the time when the processor (or at least its clock) is powered down.

Krupski:
[Here's a driver I wrote for this RTC: GitHub - krupski/DS3234: Arduino drivers for the Dallas/Maxim DS3234 Real Time Clock

I didn't come across your library when I was looking for one for the DS3234 recently. But you appear to have made the same mistake that the other libraries I found also made. In order to ensure data integrity you have to read the time registers in burst mode. If you read them one at a time like in your library there is a small chance that there will be a rollover in the middle of reading them. Take a look at the example code that Maxim provides.

TomGeorge:
Hi,

Looks like a Crystal to me, and when I look at my board, and the bareduino kits I have.

Tom.... :slight_smile:

Well, the schematic symbol for the CPU clock source is that of a crystal, but indeed it is a ceramic resonator. The 16U2 (USB <=> Serial) interface does use an actual crystal (it has to, else the instability and temperature drift characteristics of a resonator would make the serial interface fail).

I've heard an explanation as to why the CPU doesn't use a crystal (something to do with RFI problems) which I think is pure bunk, baloney or BS (whichever you prefer).

jboyton:
It adds another chip (and kind of a big one). Plus the software interface. You also have the issue of synchronizing to a time base that has a resolution of 1 second. You're either freezing the clock or skipping a second every once in a while. Or you have to read the RTC multiple times quickly to try and assess the drift more precisely. Why not just have a better internal clock? The main point of an RTC is to maintain the time when the processor (or at least its clock) is powered down.

I didn't come across your library when I was looking for one for the DS3234 recently. But you appear to have made the same mistake that the other libraries I found also made. In order to ensure data integrity you have to read the time registers in burst mode. If you read them one at a time like in your library there is a small chance that there will be a rollover in the middle of reading them. Take a look at the example code that Maxim provides.

My library does not read the registers one at a time. It reads the whole 7 byte block of registers in one call and then the data is BCD->Decimal converted afterwards from the read buffer, not directly from the RTC (I'm no dummy!) :slight_smile:

I read all 7 registers at once simply because it's the easiest thing to do. I didn't do it for any "data integrity" reason, in fact I never even thought about things like a register rolling over when another one did.

// read 7 bytes of raw clock data to buffer
void DS3234::_read_raw (void)
{
    uint8_t x = 7;
    while (x--) {
        _buffer[x] = _command (x, 0x00);
    }
}

// write 7 bytes of raw clock data to buffer
void DS3234::_write_raw (void)
{
    uint8_t x = 7;
    while (x--) {
        _command ((x | _BV (7)), _buffer[x]);
    }
}

// send command and send or receive data via SPI
uint8_t DS3234::_command (uint8_t cmd, uint8_t data)
{
    *_SS_PORT &= ~_SS_BIT;
    data = _spi_transfer (((cmd << 8) | data), 16);
    *_SS_PORT |= _SS_BIT;
    return data;
}

// soft SPI mode 3 CPOL 1 CPHA 1
uint8_t DS3234::_spi_transfer (uint16_t data, uint8_t bits)
{
    while (bits--) {
        *_SCK_PORT &= ~_SCK_BIT; // sck low
        (data & (1 << bits)) ? *_MOSI_PORT |= _MOSI_BIT : *_MOSI_PORT &= ~_MOSI_BIT; // send bit
        *_SCK_PORT |= _SCK_BIT; // sck high
        *_MISO_PIN &_MISO_BIT ? data |= (1ULL << bits) : data &= ~ (1ULL << bits); // receive bit
    }

    return (data & 0xFF);
}

As you can see from "[b]_command()[/b]", I send both command and data in one long 16 bit burst. But I did this just to avoid doing two 8 bit calls. The idea of "bursting it for data integrity" never crossed my mind and I don't believe that it's necessary anyway.

Also, the RTC is not "frozen" during reads of the registers. Obviously this would make the time drift towards the slow end the more it was read. The DS3234 "snapshots" the registers into a buffer and THAT is what's read (see this from the DS3234 data sheet pg. 11):

When reading or writing the time and date registers,
secondary (user) buffers are used to prevent errors
when the internal registers update. When reading the
time and date registers, the user buffers are synchronized
to the internal registers on the falling edge of CS
or and when the register pointer rolls over to zero. The
time information is read from these secondary registers,
while the clock continues to run. This eliminates the
need to reread the registers in case the main registers
update during a read.

Lastly, where did you find any example code from Maxim? I never saw any (I've only got the chip datasheet PDF). I would like to see their sample code - might give me some good ideas.

Krupski:
My library does not read the registers one at a time. It reads the whole 7 byte block of registers in one call and then the data is BCD->Decimal converted afterwards from the read buffer, not directly from the RTC (I'm no dummy!) :slight_smile:

By "one at a time" I meant that CS is asserted and then deasserted for each byte. In a burst read CS goes active low, multiple bytes are transferred, and then CS goes high. That section of the datasheet you quoted is the reason why this is desirable:

"...the user buffers are synchronized

  • to the internal registers on the falling edge of CS...*

When you assert/deassert CS for each byte you latch the time repeatedly. If there is a rollover while doing this you may get the wrong time/date. For example, suppose the time is 10:59:59. It's possible to read the seconds as "59", the time rolls over to 11:00:00, and then you read minutes and hours ending up with "11:00:59". The odds of seeing this happen aren't very high, but it is a possibility.

If you do a burst read the data is latched only once so you are guaranteed that it will not change.

Krupski:
...where did you find any example code from Maxim? I never saw any (I've only got the chip datasheet PDF). I would like to see their sample code - might give me some good ideas.

http://pdfserv.maximintegrated.com/en/an/AN4005.pdf

jboyton:
The stock Uno R3 has both a crystal and a resonator. The Atmega8U2 uses a crystal; the Atmega328 uses a resonator. In addition to being less accurate, the frequency of a resonator is also more temperature sensitive than with a crystal.

Yes, that's the worst part of a resonator. They drift all over the road like a drunk driver as the temperature changes.

Plus, I wish the Arduino used a clock source that was an integer multiple of standard serial baud rates. The 16.000 clock results in an actual baud rate of 9615 for 9600 (+0.16% error) and 117647 for 115200 (+2.12% error).

jboyton:
By "one at a time" I meant that CS is asserted and then deasserted for each byte. In a burst read CS goes active low, multiple bytes are transferred, and then CS goes high. That section of the datasheet you quoted is the reason why this is desirable:

"...the user buffers are synchronized

  • to the internal registers on the falling edge of CS...*

When you assert/deassert CS for each byte you latch the time repeatedly. If there is a rollover while doing this you may get the wrong time/date. For example, suppose the time is 10:59:59. It's possible to read the seconds as "59", the time rolls over to 11:00:00, and then you read minutes and hours ending up with "11:00:59". The odds of seeing this happen aren't very high, but it is a possibility.

If you do a burst read the data is latched only once so you are guaranteed that it will not change.
http://pdfserv.maximintegrated.com/en/an/AN4005.pdf

Well, I see what you are saying, but I find it hard to believe that Dallas / Maxim would allow a possible read error like that to ever occur.

Yet, the way it's worded and the way you explain it, I see what you are saying and you might be right.

So, what I plan to do is setup a test where I set the time to something like 23:59:59 and then just keep reading it as fast as the Arduino can and see if a misread ever occurs.

Then, I'll run that same test with various small (microsecond sized) delays in between reads to remove the possibility that the Arduino read rate happens to match something in the RTC and mask the problem.

If it does, then I guess my driver will have to do a read, wait "some" amount of time (TBD) then read again and compare the two to prevent that problem from ever happening.

Thanks for pointing it out.

Krupski:
Yes, that's the worst part of a resonator. They drift all over the road like a drunk driver as the temperature changes.

A couple of weeks ago I was looking for a frequency vs temperature graph for a typical ceramic resonator. The only thing I could find was this guy's tests with an Arduino. Here's what he measured:

That more or less matched what I had measured with my Uno -- a linear-looking decline with increasing internal AVR temperature. (I think his internal thermometer was more poorly calibrated than mine, which wasn't very well calibrated either):

So not really too drunken... but still not what you'd be looking for if interested in a stable clock. A crystal will also drift with temperature. Some of the curves are parabolic. Even the DS3234 will drift noticeably if the temperature changes quickly relative to it's default ~1/min conversion rate.

Krupski:
Plus, I wish the Arduino used a clock source that was an integer multiple of standard serial baud rates. The 16.000 clock results in an actual baud rate of 9615 for 9600 (+0.16% error) and 117647 for 115200 (+2.12% error).

It seems like everybody and their dog wants to make a clock out of an Arduino. But how many people run into problems with serial communication because their crystal or resonator is off? I've been transmitting without errors at 57600 on an ATtiny with an uncalibrated internal 8MHz RC oscillator.

It appears that the Zero has a built-in TCXO @ 32.768kHz and accompanying RTC (not too unlike the Teensy). A lot of future Arduino clock builders will no doubt be made happy by this.

Krupski:
Well, I see what you are saying, but I find it hard to believe that Dallas / Maxim would allow a possible read error like that to ever occur.

The old fashioned way to deal with changing values like this is to read everything twice and then compare. Maxim provided another option. I have a pressure sensor that works the same way, requiring a burst read to insure that the data is read atomically. One could imagine ways to latch the data other than on the falling edge of CS.

Krupski:
So, what I plan to do is setup a test where I set the time to something like 23:59:59 and then just keep reading it as fast as the Arduino can and see if a misread ever occurs.

Be wary of the false negative result.

Krupski:
If it does, then I guess my driver will have to do a read, wait "some" amount of time (TBD) then read again and compare the two to prevent that problem from ever happening.

Why would you do that instead of reading the registers all at once?

Quote from: Krupski on Today at 17:54:05

If it does, then I guess my driver will have to do a read, wait "some" amount of time (TBD) then read again and compare the two to prevent that problem from ever happening.

Why would you do that instead of reading the registers all at once?

Not sure. I need to think about the whole thing. This problem never occurred to me (nor did I ever run into it or have any reason to even suspect it) but the way you explain it, it seems like it could be a very remote, but very real problem and if so I need to try and find it, understand it completely then fix it in a bulletproof manner.

(yeah it's just a small Arduino library, but I'm fanatical about code being "right"). :slight_smile:

It's a nice library. And making it more robust, even if the odds of failure are low, isn't going to cost much. In fact a burst read is faster since you don't have to keep toggling the CS line. I was curious why you didn't use hardware SPI as well. Speed when reading an RTC usually isn't an issue, but someone who is already using the SPI bus would have to use additional pins with your library. And since software SPI is slower it increases the small chance of a rollover read error.

I wrote a quick and dirty sketch to see if I could get this error to occur. I was surprised how easy it was. Here's a sketch that caused the glitch almost every time. I was using an Uno. Since the timing is critical it might not show up if you try it. One way to increase the odds is to insert a delay between the two reads (there is a commented out delay there). The sketch is setting the time to 00:59 and waiting for a rollover. It should read 1:00 but I was catching it reporting 1:59.

#define BURST_READ  0    // set to 1 for burst read, 0 for one at a time

#define SS_PIN    10
#define CLK_PIN   13
#define MISO_PIN  12
#define MOSI_PIN  11

void setup()
{
  Serial.begin(115200);
  Serial.println("\nRTC glitch test.\n");

  pinMode(SS_PIN, OUTPUT);
  digitalWrite(SS_PIN, HIGH);
  
  pinMode(CLK_PIN, OUTPUT);
  pinMode(MOSI_PIN, OUTPUT);
  pinMode(MISO_PIN, INPUT);
  
  spi_command(0x8E, 0x04);    // make sure it's running
  spi_command(0x8F, 0x00);
}

void loop()
{
  uint8_t secs, mins;
  
  spi_command(0x80, 0x59);		// write seconds = 59
  spi_command(0x81, 0x00);		// write minutes = 00

  while (1) {
#if BURST_READ
    burst(&secs, &mins);
#else
    secs = spi_command(0x00, 0x00);	// read seconds
//    delay(10);                          // inserting delay increases odds of error
    mins = spi_command(0x01, 0x00);	// read minutes
#endif
    if ((secs == 0x00) || (mins == 0x01)) {    // if rollover
      displayMMSS(mins, secs);   
      break;
    }
  }
}

void displayMMSS(uint8_t mins, uint8_t secs)
{
  twoDigitBCD(mins);
  Serial.print(":");
  twoDigitBCD(secs);
  Serial.println();
}

void twoDigitBCD(uint8_t val) {
  
  Serial.print(val >> 4, HEX);
  Serial.print(val & 0xF, HEX);
}

uint8_t spi_command (uint8_t cmd, uint8_t data)
{
	digitalWrite (SS_PIN, LOW);
	spi_transfer (cmd);
	cmd = spi_transfer (data);
	digitalWrite (SS_PIN, HIGH);
	return cmd;
}

// transfer one byte via SPI Mode 3
uint8_t spi_transfer (uint8_t data)
{
	uint8_t bits;

	bits = 8;

	while (bits--) {
		digitalWrite (CLK_PIN, LOW);
		digitalWrite (MOSI_PIN, data & _BV (bits) ? HIGH : LOW);
		digitalWrite (CLK_PIN, HIGH);
		digitalRead (MISO_PIN) ? data |= _BV (bits) : data &= ~_BV (bits);
	}

	return data;
}

void burst(uint8_t *secs, uint8_t *mins)
{
  digitalWrite(SS_PIN, LOW);
  spi_transfer(0x00);
  *secs = spi_transfer(0x00);
  *mins = spi_transfer(0x00);
  digitalWrite(SS_PIN, HIGH);
}

I'm kind of surprised that Maxim didn't make it clearer in their datasheet. I guess the odds of it causing a problem are pretty low. Here's what is in the datasheet of a sensor I'm using: "To read out data after a conversion, it is strongly recommended to use a burst read and not address every register individually. This will prevent a possible mix-up of bytes belonging to different measurements and reduce interface traffic." Even they aren't adamant about it.

Output of sketch in non-burst mode:

RTC glitch test.

01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:00
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:00
01:59
01:59
01:59
01:59
01:59
01:59
01:00
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:00
01:59
01:59
01:59
01:59
01:59
01:59
01:00
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:00
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59

Very interesting. I ran your test on an Uno board and a Sparkfun "Dead-On" RTC breakout board. I had to make a few changes to run my board (because I plug the RTC board right into pins 8 thru 13).

Here's the result I got:

RTC glitch test.

01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59
01:59

This is the change I made to your sketch to be able to run it here:

#define BURST_READ  0    // set to 1 for burst read, 0 for one at a time

//#define SS_PIN    10
//#define CLK_PIN   13
//#define MISO_PIN  12
//#define MOSI_PIN  11

#define VCC 13
#define SQW 12
#define CLK_PIN   11
#define MISO_PIN  10
#define MOSI_PIN  9
#define SS_PIN    8

void setup()
{
  Serial.begin(115200);
  Serial.println("\nRTC glitch test.\n");

//////////////////////////////////// added /////////////////////////////////////
  pinMode (SQW, INPUT); // prevent possible contention with SQW output
  digitalWrite (VCC, HIGH); // steal power from a pin
  pinMode (VCC, OUTPUT);
  delay (1000); // let it stabilize?
//////////////////////////////////// added /////////////////////////////////////

Everything else was unchanged.

BTW, the reason I wrote my library using bit-bang SPI was so that ANY pins could be used. Plus, I saw no need to tie up a high speed hardware SPI port that something else could make better use of... and as you said reading an RTC doesn't require speed anyway.

Anyway, as you know my code reads or writes all 7 registers at once (and of course the problem is only on the read side).

All I need to do is read the 7 registers once, then do a second read but instead of saving the readings, I would COMPARE the results. Any mismatch would simply trigger another read/compare cycle.

I think that would make the problem go away in a bulletproof manner, what do you think?

I think that would work.

I would choose to do something like this:

void DS3234::_read_raw (void)
{
	uint8_t x = 7;

        digitalWrite (_ss_pin, LOW);
        _spi_transfer(0);			// time registers: addr 0-6
	while (x--) {
		*(_buffer + x) = _spi_transfer(0);
	}
        digitalWrite(_ss_pin, HIGH);
}

jboyton:
I think that would work.

I would choose to do something like this:

void DS3234::_read_raw (void)

{
uint8_t x = 7;

digitalWrite (_ss_pin, LOW);
       _spi_transfer(0); // time registers: addr 0-6
while (x--) {
*(_buffer + x) = _spi_transfer(0);
}
       digitalWrite(_ss_pin, HIGH);
}

OK, I tried something: I modified your test sketch to use my library for reads. Sure enough, it's got the problem. Here's the output from the test sketch using the library for read:

[b]

RTC glitch test using DS3234 Library

01:00
00:00
01:00
00:00
00:00
01:00
00:00
00:00
00:00
01:00
00:00
01:00
00:00
[/b]

Now with the define changed to use the software direct read you did:

[b]

RTC glitch test using Burst read

01:00
01:00
01:00
01:00
01:00
01:00
01:00
01:00
01:00
01:00
01:00
01:00[/b]

Here is the test sketch itself if you want to try it:

#include <DS3234.h>

// DS3234 pin connections
#define __GND 99 // solid gnd
#define __VCC 13
#define __SQW 12
#define __SCK 11
#define __MISO 10
#define __MOSI 9
#define __SS 8

// original defines from the test sketch
#define CLK_PIN 11
#define MISO_PIN 10
#define MOSI_PIN 9
#define SS_PIN 8

#define USE_DRIVER // comment this out to use direct read

uint8_t hour, mins, secs, month, day, dow;
uint16_t year;

char buffer[16];

uint8_t bcd2dec (uint8_t bcd)
{
	return (bcd / 16 * 10) + (bcd % 16);
}

void displayMMSS (uint8_t mins, uint8_t secs)
{
	sprintf (buffer, "%02u:%02u\n", mins, secs);
	Serial.print (buffer);
}

// transfer one byte via SPI Mode 3
uint8_t spi_transfer (uint8_t data)
{
	uint8_t bits;
	bits = 8;

	while (bits--) {
		digitalWrite (CLK_PIN, LOW);
		digitalWrite (MOSI_PIN, data & _BV (bits) ? HIGH : LOW);
		digitalWrite (CLK_PIN, HIGH);
		digitalRead (MISO_PIN) ? data |= _BV (bits) : data &= ~_BV (bits);
	}

	return data;
}

uint8_t spi_command (uint8_t cmd, uint8_t data)
{
	digitalWrite (SS_PIN, LOW);
	spi_transfer (cmd);
	cmd = spi_transfer (data);
	digitalWrite (SS_PIN, HIGH);
	return cmd;
}

void burst (uint8_t *secs, uint8_t *mins)
{
	digitalWrite (SS_PIN, LOW);
	spi_transfer (0x00);
	*secs = spi_transfer (0x00);
	*mins = spi_transfer (0x00);
	digitalWrite (SS_PIN, HIGH);
}

int main (void)
{
	init();
	Serial.begin (115200);

	digitalWrite (__GND, LOW);
	digitalWrite (__VCC, HIGH);

	pinMode (__GND, OUTPUT); // enable gnd first
	pinMode (__VCC, OUTPUT); // turn on power for clock
	pinMode (__SQW, INPUT_PULLUP); // no bus contention with SQW pin

	RTC.init (__SCK, __MISO, __MOSI, __SS); // init the RTC

	Serial.print ("\nRTC glitch test using");
#ifdef USE_DRIVER
	Serial.print (" DS3234 Library\n\n");
#else
	Serial.print (" Burst read\n\n");
#endif

	while (1) {
		spi_command (0x80, 0x59); // write seconds = 59
		spi_command (0x81, 0x00); // write minutes = 00

		while (1) {
#ifdef USE_DRIVER
			dow = RTC.getTime (hour, mins, secs, month, day, year);
#else
			burst (&secs, &mins);
			mins = bcd2dec (mins); // raw read is in BCD so convert it
			secs = bcd2dec (secs);
#endif

			if ((secs == 0x00) || (mins == 0x01)) { // if rollover
				displayMMSS (mins, secs);
				break;
			}
		}
	}
}

Lastly, attached is a ZIP file of the DS3234 library. It's been updated a bit from the one on Github, and you should use the same one as I did for testing...

ds3234.zip (4.4 KB)