Skip to content

Commit 5d481c2

Browse files
Merge pull request #9838 from gebart/pr/ds3234-pps
ds323x: Minimal driver for DS323x extremely accurate RTC
2 parents dd664a8 + a6f430b commit 5d481c2

File tree

10 files changed

+397
-0
lines changed

10 files changed

+397
-0
lines changed

drivers/Makefile.dep

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,10 @@ ifneq (,$(filter ds1307,$(USEMODULE)))
124124
FEATURES_REQUIRED += periph_i2c
125125
endif
126126

127+
ifneq (,$(filter ds3234,$(USEMODULE)))
128+
FEATURES_REQUIRED += periph_spi
129+
endif
130+
127131
ifneq (,$(filter dsp0401,$(USEMODULE)))
128132
USEMODULE += xtimer
129133
FEATURES_REQUIRED += periph_gpio

drivers/Makefile.include

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ ifneq (,$(filter ds1307,$(USEMODULE)))
6666
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ds1307/include
6767
endif
6868

69+
ifneq (,$(filter ds3234,$(USEMODULE)))
70+
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ds3234/include
71+
endif
72+
6973
ifneq (,$(filter dsp0401,$(USEMODULE)))
7074
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/dsp0401/include
7175
endif

drivers/ds3234/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
include $(RIOTBASE)/Makefile.base

drivers/ds3234/ds3234.c

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright (C) 2018 Eistec AB
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*
8+
*/
9+
10+
/**
11+
* @ingroup drivers_ds3234
12+
* @{
13+
*
14+
* @file
15+
* @brief Driver for the DS3234 Extremely Accurate SPI Bus RTC with
16+
* Integrated Crystal and SRAM, from Maxim
17+
*
18+
* @author Joakim Nohlgård <[email protected]>
19+
* @}
20+
*/
21+
22+
#include <stdint.h>
23+
#include <errno.h>
24+
#include "ds3234.h"
25+
#include "ds3234_regs.h"
26+
27+
#define ENABLE_DEBUG (0)
28+
#include "debug.h"
29+
30+
/* SPI command byte parameters */
31+
#define DS3234_CMD_READ (0x00)
32+
#define DS3234_CMD_WRITE (0x80)
33+
34+
35+
/**
36+
* @brief Read one or more registers from the sensor
37+
*
38+
* @param[in] dev device descriptor
39+
* @param[in] addr register address
40+
* @param[in] len number of bytes to read
41+
* @param[out] buf destination buffer
42+
*/
43+
static void ds3234_read_reg(const ds3234_params_t *dev, uint8_t addr, size_t len, uint8_t *buf)
44+
{
45+
uint8_t command = DS3234_CMD_READ | addr;
46+
/* Acquire exclusive access to the bus. */
47+
spi_acquire(dev->spi, dev->cs, SPI_MODE_3, dev->clk);
48+
/* Perform the transaction */
49+
spi_transfer_regs(dev->spi, dev->cs, command, NULL, buf, len);
50+
/* Release the bus for other threads. */
51+
spi_release(dev->spi);
52+
}
53+
54+
/**
55+
* @brief Write a register value to the sensor
56+
*
57+
* @param[in] dev device descriptor
58+
* @param[in] addr register address
59+
* @param[in] len register size
60+
* @param[in] buf source buffer
61+
*/
62+
static void ds3234_write_reg(const ds3234_params_t *dev, uint8_t addr, size_t len, const uint8_t *buf)
63+
{
64+
uint8_t command = DS3234_CMD_WRITE | addr;
65+
/* Acquire exclusive access to the bus. */
66+
spi_acquire(dev->spi, dev->cs, SPI_MODE_3, dev->clk);
67+
/* Perform the transaction */
68+
spi_transfer_regs(dev->spi, dev->cs, command, buf, NULL, len);
69+
/* Release the bus for other threads. */
70+
spi_release(dev->spi);
71+
}
72+
73+
int ds3234_pps_init(const ds3234_params_t *dev)
74+
{
75+
/* initialize CS pin */
76+
int res = spi_init_cs(dev->spi, dev->cs);
77+
if (res < 0) {
78+
return DS3234_NO_SPI;
79+
}
80+
DEBUG("ds3234: init on SPI_DEV(%u)\n", dev->spi);
81+
82+
if (ENABLE_DEBUG) {
83+
for (int k = 0; k <= 0x19; ++k) {
84+
uint8_t dbg_reg = 0;
85+
ds3234_read_reg(dev, k, 1, &dbg_reg);
86+
DEBUG("%2x: %2x\n", k, dbg_reg);
87+
}
88+
}
89+
uint8_t reg = 0;
90+
ds3234_read_reg(dev, DS323X_REG_CONTROL, 1, &reg);
91+
92+
/* set reg to a non-zero known value to check if device is present */
93+
reg |= DS323X_REG_CONTROL_RS1_MASK;
94+
95+
ds3234_write_reg(dev, DS323X_REG_CONTROL, 1, &reg);
96+
uint8_t readback = 0;
97+
ds3234_read_reg(dev, DS323X_REG_CONTROL, 1, &readback);
98+
if (reg != readback) {
99+
DEBUG("ds3234: readback mismatch: expected %u, actual %u\n", (unsigned)reg, (unsigned)readback);
100+
return DS3234_NO_DEV;
101+
}
102+
103+
/* The control register is configured to:
104+
* - Enable the oscillator
105+
* - Enable an square wave output on the SQW pin
106+
* - Sets the square wave frequency to 1 Hz
107+
*/
108+
reg &= ~(DS323X_REG_CONTROL_EOSC_MASK | DS323X_REG_CONTROL_INTCN_MASK |
109+
DS323X_REG_CONTROL_RS1_MASK | DS323X_REG_CONTROL_RS2_MASK);
110+
ds3234_write_reg(dev, DS323X_REG_CONTROL, 1, &reg);
111+
112+
return DS3234_OK;
113+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
/*
2+
* Copyright (C) 2018 SKF AB
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @ingroup drivers_ds3234
11+
*
12+
* @{
13+
* @file
14+
* @brief Default configuration for DS3234 devices
15+
*
16+
* @author Joakim Nohlgård <[email protected]>
17+
*/
18+
19+
#ifndef DS3234_PARAMS_H
20+
#define DS3234_PARAMS_H
21+
22+
#include "board.h"
23+
#include "ds3234.h"
24+
25+
#ifdef __cplusplus
26+
extern "C" {
27+
#endif
28+
29+
/**
30+
* @name Set default configuration parameters for the DS3234 devices
31+
* @{
32+
*/
33+
#ifndef DS3234_PARAM_SPI
34+
#define DS3234_PARAM_SPI (SPI_DEV(0))
35+
#endif
36+
#ifndef DS3234_PARAM_CS
37+
#define DS3234_PARAM_CS (GPIO_PIN(0, 0))
38+
#endif
39+
#ifndef DS3234_PARAM_CLK
40+
#define DS3234_PARAM_CLK (SPI_CLK_1MHZ)
41+
#endif
42+
#ifndef DS3234_PARAMS
43+
#define DS3234_PARAMS \
44+
{ \
45+
.spi = DS3234_PARAM_SPI, \
46+
.cs = DS3234_PARAM_CS, \
47+
.clk = DS3234_PARAM_CLK, \
48+
}
49+
#endif
50+
/**@}*/
51+
52+
/**
53+
* @brief Configure DS3234 devices
54+
*/
55+
static const ds3234_params_t ds3234_params[] =
56+
{
57+
DS3234_PARAMS
58+
};
59+
60+
#ifdef __cplusplus
61+
}
62+
#endif
63+
64+
#endif /* DS3234_PARAMS_H */
65+
/** @} */
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright 2018 SKF AB
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @ingroup drivers_ds3234
11+
* @{
12+
*
13+
* @file
14+
* @brief Register map for the DS323x driver
15+
*
16+
* @author Joakim Nohlgård <[email protected]>
17+
*/
18+
19+
#ifndef DS3234_REGS_H
20+
#define DS3234_REGS_H
21+
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
/**
27+
* @name Register addresses
28+
* @{
29+
*/
30+
enum {
31+
DS323X_REG_TIME_SECONDS = (0x00),
32+
DS323X_REG_TIME_MINUTES = (0x01),
33+
DS323X_REG_TIME_HOURS = (0x02),
34+
DS323X_REG_TIME_WEEKDAY = (0x03),
35+
DS323X_REG_TIME_DATE = (0x04),
36+
DS323X_REG_TIME_MONTH = (0x05),
37+
DS323X_REG_TIME_YEAR = (0x06),
38+
DS323X_REG_ALARM1_SECONDS = (0x07),
39+
DS323X_REG_ALARM1_MINUTES = (0x08),
40+
DS323X_REG_ALARM1_HOURS = (0x09),
41+
DS323X_REG_ALARM1_DAYDATE = (0x0A),
42+
DS323X_REG_ALARM2_MINUTES = (0x0B),
43+
DS323X_REG_ALARM2_HOURS = (0x0C),
44+
DS323X_REG_ALARM2_DAYDATE = (0x0D),
45+
DS323X_REG_CONTROL = (0x0E),
46+
DS323X_REG_CONTROL_STATUS = (0x0F),
47+
DS323X_REG_XTAL_AGING = (0x10),
48+
DS323X_REG_TEMP_MSB = (0x11),
49+
DS323X_REG_TEMP_LSB = (0x12),
50+
DS323X_REG_TEMP_DISABLE = (0x13),
51+
DS323X_REG_SRAM_ADDR = (0x18),
52+
DS323X_REG_SRAM_DATA = (0x19),
53+
};
54+
/** @} */
55+
56+
/**
57+
* @name Control register bits
58+
* @{
59+
*/
60+
#define DS323X_REG_CONTROL_EOSC_MASK (0x80) /**< Enable oscillator */
61+
#define DS323X_REG_CONTROL_BBSQW_MASK (0x40) /**< Battery-Backed Square-Wave Enable */
62+
#define DS323X_REG_CONTROL_CONV_MASK (0x20) /**< Convert Temperature */
63+
#define DS323X_REG_CONTROL_RS2_MASK (0x10) /**< Rate Select 2 */
64+
#define DS323X_REG_CONTROL_RS1_MASK (0x08) /**< Rate Select 1 */
65+
#define DS323X_REG_CONTROL_INTCN_MASK (0x04) /**< Interrupt Control */
66+
#define DS323X_REG_CONTROL_A2IE_MASK (0x02) /**< Alarm 2 Interrupt Enable */
67+
#define DS323X_REG_CONTROL_A1IE_MASK (0x01) /**< Alarm 1 Interrupt Enable */
68+
/** @} */
69+
70+
#ifdef __cplusplus
71+
}
72+
#endif
73+
74+
#endif /* DS3234_REGS_H */
75+
/** @} */

drivers/include/ds3234.h

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright 2018 SKF AB
3+
*
4+
* This file is subject to the terms and conditions of the GNU Lesser
5+
* General Public License v2.1. See the file LICENSE in the top level
6+
* directory for more details.
7+
*/
8+
9+
/**
10+
* @defgroup drivers_ds3234 DS3234 Extremely Accurate SPI RTC
11+
12+
* @brief Driver for Maxim DS3234 Extremely Accurate SPI Bus RTC with
13+
* Integrated Crystal and SRAM
14+
15+
* @{
16+
*
17+
* @file
18+
* @brief DS3234 device driver
19+
*
20+
* @author Joakim Nohlgård <[email protected]>
21+
*/
22+
23+
#ifndef DS3234_H
24+
#define DS3234_H
25+
26+
#include <periph/gpio.h>
27+
#include <periph/spi.h>
28+
29+
#ifdef __cplusplus
30+
extern "C" {
31+
#endif
32+
33+
/**
34+
* @brief Parameters for the DS3234 device driver
35+
*/
36+
typedef struct {
37+
spi_t spi; /**< SPI bus the sensor is connected to */
38+
spi_clk_t clk; /**< SPI bus clock speed */
39+
gpio_t cs; /**< CS pin GPIO handle */
40+
} ds3234_params_t;
41+
42+
/**
43+
* @brief Return codes for the DS3234 device driver
44+
*/
45+
enum ds3234_return_codes {
46+
DS3234_OK = 0,
47+
DS3234_NO_DEV = 1,
48+
DS3234_NO_SPI = 2
49+
};
50+
51+
/**
52+
* @brief Initialize the DS3234 RTC as a PPS device
53+
*
54+
* This will enable square wave output on the SQW pin at 1 Hz
55+
*
56+
* @param params DS3234 circuit parameters
57+
*
58+
* @return DS3234_OK on success
59+
* @return DS3234_NO_SPI if cannot initiate SPI
60+
* @return DS3234_NO_DEV if the device is not found on the bus
61+
*/
62+
int ds3234_pps_init(const ds3234_params_t *params);
63+
64+
#ifdef __cplusplus
65+
}
66+
#endif
67+
68+
#endif /* DS3234_H */
69+
/** @} */

tests/driver_ds3234/Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
include ../Makefile.tests_common
2+
3+
USEMODULE += ds3234
4+
5+
include $(RIOTBASE)/Makefile.include

tests/driver_ds3234/README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# About
2+
3+
This is a simple test application for the DS3234 SPI RTC driver PPS output.
4+
5+
# Usage
6+
7+
This test application will initialize the RTC with the following parameters:
8+
- Oscillator enabled
9+
- Square wave output enabled
10+
- Square wave frequency: 1 Hz

0 commit comments

Comments
 (0)