Skip to content

Conversation

@jnohlgard
Copy link
Member

Contribution description

A simple device driver for enabling the square wave output on the DS3234 SPI RTC from Maxim.
This driver currently only supports the SPI connected DS3234, and only for initializing 1 Hz square wave output on the SQW pin, nothing else.

The intended use case is to use this for calibrating internal oscillators on different boards by connecting the square wave output to a GPIO interrupt pin, and through those measurements achieve better accuracy from cheaper timers.

The register map is the same for all DS323x, but only the DS3234 is implemented here.

Testing procedure

External hardware: https://www.sparkfun.com/products/10160
Required tools: Oscilloscope or logic analyzer

Configure the device parameters in ds3234_params.h, build and flash tests/driver_ds3234. Examine the SQW pin on the RTC using an oscilloscope or logic analyzer, see a 1 Hz square wave.

Issues/PRs references

nothing yet.

@jnohlgard jnohlgard added Type: new feature The issue requests / The PR implemements a new feature for RIOT Impact: minor The PR is small in size and might only require a quick look of a knowledgeable reviewer Area: drivers Area: Device drivers CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Area: timers Area: timer subsystems labels Aug 24, 2018
@jnohlgard jnohlgard added this to the Release 2018.10 milestone Aug 24, 2018
@jnohlgard jnohlgard requested a review from aabadie August 25, 2018 12:33
Copy link
Member

@PeterKietzmann PeterKietzmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gebart code-wise I'm not convinced how/why the ds3233 and ds3234are separated like this. Is there reason why some files are common but the params files, headers and the test are not?
Besides that, the code looks good to me. I just ordered a device and can provide test after it arrived.


ifneq (,$(filter ds3234,$(USEMODULE)))
USEMODULE += ds323x
USEMODULE += ds323x_ds3234
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This name seems a bit weird to me. Is it even generated or used somewhere?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's just to get the right file compiled without special tricks to get it recognized as a file from the ds323x directory

@@ -0,0 +1,4 @@
# enable submodules
SUBMODULES := 1
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So far you just implemented ds3234.c. Do we actually need the SUBMODULES now?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented this way makes it easy to add a ds3231.c later on

return -EIO;
}

if (ENABLE_DEBUG) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not #ifdef?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To let the compiler syntax check the part even when enable debug is off

}
uint8_t reg = 0;
ds3234_read_reg(dev, DS323X_REG_CONTROL, 1, &reg);
reg &= ~(DS323X_REG_CONTROL_EOSC_MASK | DS323X_REG_CONTROL_INTCN_MASK |
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you mind to spend a note which options you (un)set here? Is this a form of device reset?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll add a comment. The bits rs1 rs2 select which frequency the sqw pin will output. The intcn bit selects whether the sqw pin is an interrupt output or a square wave signal output. The eosc bit enables the oscillator when it is cleared.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment

@@ -0,0 +1,65 @@
/*
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it is necessary to have separate params files?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since ds3234 is spi connected and the others are i2c, I figured the configuration should be separate

@jnohlgard
Copy link
Member Author

jnohlgard commented Aug 28, 2018

Only the ds3234 is spi connected, the others are i2c (ds3231, ds3232). There is no ds3233 AFAIK.
Here's the manufacturer product list
https://para.maximintegrated.com/en/search.mvp?fam=rtc&270=TCXO

@PeterKietzmann
Copy link
Member

@gebart thanks for the immediate feedback. It wasn't clear to me that the other device is I2C based. Then I'm fine with the file-wise isolation. Let's wait until the device arrives.

@jnohlgard
Copy link
Member Author

Sounds good 👍

@leandrolanzieri
Copy link
Contributor

I just tested this on a Nucleo F030R8 and on a SAM R21 (after rebasing to apply #9885), and can confirm it works as intended.

Here you can se the 1Hz square wave:
sqw_ds3234

Going through the device datasheet I saw there is no ID register or something like that to evaluate if device is actually present on the bus or not during initialization. Would it be worth it to add a function that writes and reads a byte from the SRAM present on the device? Maybe something like:

bool ds3234_is_present(const ds3234_params_t *dev)
{
    uint8_t value = 0x55, address = 0x0A, reg = 0;
    ds3234_write_reg(dev, DS323X_REG_SRAM_ADDR, 1, &address);
    ds3234_write_reg(dev, DS323X_REG_SRAM_DATA, 1, &value);
    ds3234_write_reg(dev, DS323X_REG_SRAM_ADDR, 1, &address);
    ds3234_read_reg(dev, DS323X_REG_SRAM_DATA, 1, &reg);
    
    if (ENABLE_DEBUG) {
        print_str("Expected: 0x");
        print_byte_hex(value);
        print_str(" - Read: 0x");
        print_byte_hex(reg);
        print_str("\n");
    }

    return value == reg;
}

@jnohlgard
Copy link
Member Author

@leandrolanzieri I would prefer to not touch the SRAM portion of the chip. What we could do instead is read back the written register and see that it matches what we expect, if you would like some more feedback to the application.

@leandrolanzieri
Copy link
Contributor

@gebart yes, we could do that. The problem is that, with the current configuration, the control register is always 0.

@leandrolanzieri
Copy link
Contributor

Maybe we could go without checking if the device is present for now?

@PeterKietzmann
Copy link
Member

Can't you just write ones to RS1 and RS2 in the Control register, read it out, check, and reset again afterwards? We could leave this feature out, sure, but now that it's on the table I think it would be nice to implement it at once.

@leandrolanzieri
Copy link
Contributor

leandrolanzieri commented Oct 15, 2018

Can't you just write ones to RS1 and RS2 in the Control register, read it out, check, and reset again afterwards? We could leave this feature out, sure, but now that it's on the table I think it would be nice to implement it at once.

Yes, I think this could be easily done, and having the feature would be nice.

@PeterKietzmann
Copy link
Member

ping @gebart.

@PeterKietzmann
Copy link
Member

@leandrolanzieri how about you take over this PR? You base your changes on @gebart's commit and I'll test/review then. @gebart do you agree?

@jnohlgard
Copy link
Member Author

@PeterKietzmann sounds good! I will not be able to work any more on this PR

@leandrolanzieri
Copy link
Contributor

@PeterKietzmann I rebased and applied the suggested changes.

Copy link
Member

@PeterKietzmann PeterKietzmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leandrolanzieri I left a few comments, please address them. Furthermore, what is your opinion about the pseudo-module preparation in this PR?

Other than that I ran the test on a nucleo-f103rb and got the expected 1Hz output

#include "ds323x_regs.h"
#include "fmt.h"

#define ENABLE_DEBUG (1)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please disable by default

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

for (int k = 0; k <= 0x19; ++k) {
uint8_t dbg_reg = 0;
ds3234_read_reg(dev, k, 1, &dbg_reg);
print_byte_hex(k);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has a dependency to the fmt module.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed that

#define DS3234_PARAM_SPI (SPI_DEV(0))
#endif
#ifndef DS3234_PARAM_CS
#define DS3234_PARAM_CS (SPI_HWCS(0))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think GPIO_PIN(0, 0) would be the more common way here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed

@leandrolanzieri leandrolanzieri removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 18, 2019
@leandrolanzieri
Copy link
Contributor

Furthermore, what is your opinion about the pseudo-module preparation in this PR?

@PeterKietzmann I think it might be confusing to see that the DS323X family is there but actually only one device is supported. I believe for now we can skip that and just keep this minimal driver as DS3234 until an implementation of another device of the family is implemented.

Copy link
Member

@PeterKietzmann PeterKietzmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@leandrolanzieri thanks for addressing. Code looks good and still works. Please squash all commits to a single one!

This driver currently only supports the SPI connected DS3234, and only
for initializing 1 Hz square wave output on the SQW pin, nothing else.
@leandrolanzieri leandrolanzieri added the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label Feb 19, 2019
@leandrolanzieri leandrolanzieri merged commit 5d481c2 into RIOT-OS:master Feb 19, 2019
*/

/**
* @defgroup drivers_ds3234 DS3234 Extremely Accurate SPI RTC
Copy link
Member

@maribu maribu Mar 13, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gebart: I think the @ingroup is missing here. As a result the documentation is shown directly in modues in the doxygen doc. Care to make a follow up PR to address this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: drivers Area: Device drivers Area: timers Area: timer subsystems CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Impact: minor The PR is small in size and might only require a quick look of a knowledgeable reviewer Type: new feature The issue requests / The PR implemements a new feature for RIOT

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants