replacing crystal with TCXO

jboyton:
Multi-byte SPI works like this:

  1. CS is asserted
  2. The address + R/W bit are sent
  3. N bytes are read or written (the address auto-increments)
  4. CS is deasserted

You can't do multi-byte access in reverse order. Only the first address you send matters. If you start at address 6 the next byte you read will be address 7, which is one of the alarm registers.

I don't understand your code: x << 8 will always be zero if x is uint8_t.

OK, I finally have it figured out and it's working!

// read 7 bytes of raw clock data to buffer
void DS3234::_read_time (void)
{
    uint8_t x;
    *_SS_PORT &= ~_SS_BIT;
    _spi_transfer (0x00);
    for (x = 0; x < 7; x++) {
        *(_buffer + x) = _spi_transfer (x);
    }
    *_SS_PORT |= _SS_BIT;
}

First of all (now it's so obvious) I have to read up from 0 to 6, not down from 6 to 0. What I need to do is send one byte of 0x00 which means "read register 0" then the next 7 reads actually get register 0 through 6 all during the CS low period.

Two mistakes I made before were:
(1) Reading backwards from 6 to 0
(2) Sending TWO bytes per read (i.e. register address x, read register x) when I should have just read all 7 in one shot.

Lastly, there's nothing wrong with "x << 8" if x is uint8_t because the DESTINATION needs to be of the proper size i.e.:

uint16_t result = (uint8_t data << 8);

I don't know if the compiler "promotes" data to 16 bits to make it work or if it copies the 8 bit value "data" to "result" and then shifts it, but in any case it works.......