1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

drivers/ds3234: Minimal driver for DS3234 extremely accurate RTC

This driver currently only supports the SPI connected DS3234, and only
for initializing 1 Hz square wave output on the SQW pin, nothing else.
This commit is contained in:
Joakim Nohlgård 2018-08-23 22:58:39 +02:00 committed by Leandro Lanzieri
parent a4549f089f
commit a6f430b4b5
10 changed files with 397 additions and 0 deletions

View File

@ -124,6 +124,10 @@ ifneq (,$(filter ds1307,$(USEMODULE)))
FEATURES_REQUIRED += periph_i2c
endif
ifneq (,$(filter ds3234,$(USEMODULE)))
FEATURES_REQUIRED += periph_spi
endif
ifneq (,$(filter dsp0401,$(USEMODULE)))
USEMODULE += xtimer
FEATURES_REQUIRED += periph_gpio

View File

@ -66,6 +66,10 @@ ifneq (,$(filter ds1307,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ds1307/include
endif
ifneq (,$(filter ds3234,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/ds3234/include
endif
ifneq (,$(filter dsp0401,$(USEMODULE)))
USEMODULE_INCLUDES += $(RIOTBASE)/drivers/dsp0401/include
endif

1
drivers/ds3234/Makefile Normal file
View File

@ -0,0 +1 @@
include $(RIOTBASE)/Makefile.base

113
drivers/ds3234/ds3234.c Normal file
View File

@ -0,0 +1,113 @@
/*
* Copyright (C) 2018 Eistec AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*
*/
/**
* @ingroup drivers_ds3234
* @{
*
* @file
* @brief Driver for the DS3234 Extremely Accurate SPI Bus RTC with
* Integrated Crystal and SRAM, from Maxim
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
* @}
*/
#include <stdint.h>
#include <errno.h>
#include "ds3234.h"
#include "ds3234_regs.h"
#define ENABLE_DEBUG (0)
#include "debug.h"
/* SPI command byte parameters */
#define DS3234_CMD_READ (0x00)
#define DS3234_CMD_WRITE (0x80)
/**
* @brief Read one or more registers from the sensor
*
* @param[in] dev device descriptor
* @param[in] addr register address
* @param[in] len number of bytes to read
* @param[out] buf destination buffer
*/
static void ds3234_read_reg(const ds3234_params_t *dev, uint8_t addr, size_t len, uint8_t *buf)
{
uint8_t command = DS3234_CMD_READ | addr;
/* Acquire exclusive access to the bus. */
spi_acquire(dev->spi, dev->cs, SPI_MODE_3, dev->clk);
/* Perform the transaction */
spi_transfer_regs(dev->spi, dev->cs, command, NULL, buf, len);
/* Release the bus for other threads. */
spi_release(dev->spi);
}
/**
* @brief Write a register value to the sensor
*
* @param[in] dev device descriptor
* @param[in] addr register address
* @param[in] len register size
* @param[in] buf source buffer
*/
static void ds3234_write_reg(const ds3234_params_t *dev, uint8_t addr, size_t len, const uint8_t *buf)
{
uint8_t command = DS3234_CMD_WRITE | addr;
/* Acquire exclusive access to the bus. */
spi_acquire(dev->spi, dev->cs, SPI_MODE_3, dev->clk);
/* Perform the transaction */
spi_transfer_regs(dev->spi, dev->cs, command, buf, NULL, len);
/* Release the bus for other threads. */
spi_release(dev->spi);
}
int ds3234_pps_init(const ds3234_params_t *dev)
{
/* initialize CS pin */
int res = spi_init_cs(dev->spi, dev->cs);
if (res < 0) {
return DS3234_NO_SPI;
}
DEBUG("ds3234: init on SPI_DEV(%u)\n", dev->spi);
if (ENABLE_DEBUG) {
for (int k = 0; k <= 0x19; ++k) {
uint8_t dbg_reg = 0;
ds3234_read_reg(dev, k, 1, &dbg_reg);
DEBUG("%2x: %2x\n", k, dbg_reg);
}
}
uint8_t reg = 0;
ds3234_read_reg(dev, DS323X_REG_CONTROL, 1, &reg);
/* set reg to a non-zero known value to check if device is present */
reg |= DS323X_REG_CONTROL_RS1_MASK;
ds3234_write_reg(dev, DS323X_REG_CONTROL, 1, &reg);
uint8_t readback = 0;
ds3234_read_reg(dev, DS323X_REG_CONTROL, 1, &readback);
if (reg != readback) {
DEBUG("ds3234: readback mismatch: expected %u, actual %u\n", (unsigned)reg, (unsigned)readback);
return DS3234_NO_DEV;
}
/* The control register is configured to:
* - Enable the oscillator
* - Enable an square wave output on the SQW pin
* - Sets the square wave frequency to 1 Hz
*/
reg &= ~(DS323X_REG_CONTROL_EOSC_MASK | DS323X_REG_CONTROL_INTCN_MASK |
DS323X_REG_CONTROL_RS1_MASK | DS323X_REG_CONTROL_RS2_MASK);
ds3234_write_reg(dev, DS323X_REG_CONTROL, 1, &reg);
return DS3234_OK;
}

View File

@ -0,0 +1,65 @@
/*
* Copyright (C) 2018 SKF AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_ds3234
*
* @{
* @file
* @brief Default configuration for DS3234 devices
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef DS3234_PARAMS_H
#define DS3234_PARAMS_H
#include "board.h"
#include "ds3234.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Set default configuration parameters for the DS3234 devices
* @{
*/
#ifndef DS3234_PARAM_SPI
#define DS3234_PARAM_SPI (SPI_DEV(0))
#endif
#ifndef DS3234_PARAM_CS
#define DS3234_PARAM_CS (GPIO_PIN(0, 0))
#endif
#ifndef DS3234_PARAM_CLK
#define DS3234_PARAM_CLK (SPI_CLK_1MHZ)
#endif
#ifndef DS3234_PARAMS
#define DS3234_PARAMS \
{ \
.spi = DS3234_PARAM_SPI, \
.cs = DS3234_PARAM_CS, \
.clk = DS3234_PARAM_CLK, \
}
#endif
/**@}*/
/**
* @brief Configure DS3234 devices
*/
static const ds3234_params_t ds3234_params[] =
{
DS3234_PARAMS
};
#ifdef __cplusplus
}
#endif
#endif /* DS3234_PARAMS_H */
/** @} */

View File

@ -0,0 +1,75 @@
/*
* Copyright 2018 SKF AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup drivers_ds3234
* @{
*
* @file
* @brief Register map for the DS323x driver
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef DS3234_REGS_H
#define DS3234_REGS_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @name Register addresses
* @{
*/
enum {
DS323X_REG_TIME_SECONDS = (0x00),
DS323X_REG_TIME_MINUTES = (0x01),
DS323X_REG_TIME_HOURS = (0x02),
DS323X_REG_TIME_WEEKDAY = (0x03),
DS323X_REG_TIME_DATE = (0x04),
DS323X_REG_TIME_MONTH = (0x05),
DS323X_REG_TIME_YEAR = (0x06),
DS323X_REG_ALARM1_SECONDS = (0x07),
DS323X_REG_ALARM1_MINUTES = (0x08),
DS323X_REG_ALARM1_HOURS = (0x09),
DS323X_REG_ALARM1_DAYDATE = (0x0A),
DS323X_REG_ALARM2_MINUTES = (0x0B),
DS323X_REG_ALARM2_HOURS = (0x0C),
DS323X_REG_ALARM2_DAYDATE = (0x0D),
DS323X_REG_CONTROL = (0x0E),
DS323X_REG_CONTROL_STATUS = (0x0F),
DS323X_REG_XTAL_AGING = (0x10),
DS323X_REG_TEMP_MSB = (0x11),
DS323X_REG_TEMP_LSB = (0x12),
DS323X_REG_TEMP_DISABLE = (0x13),
DS323X_REG_SRAM_ADDR = (0x18),
DS323X_REG_SRAM_DATA = (0x19),
};
/** @} */
/**
* @name Control register bits
* @{
*/
#define DS323X_REG_CONTROL_EOSC_MASK (0x80) /**< Enable oscillator */
#define DS323X_REG_CONTROL_BBSQW_MASK (0x40) /**< Battery-Backed Square-Wave Enable */
#define DS323X_REG_CONTROL_CONV_MASK (0x20) /**< Convert Temperature */
#define DS323X_REG_CONTROL_RS2_MASK (0x10) /**< Rate Select 2 */
#define DS323X_REG_CONTROL_RS1_MASK (0x08) /**< Rate Select 1 */
#define DS323X_REG_CONTROL_INTCN_MASK (0x04) /**< Interrupt Control */
#define DS323X_REG_CONTROL_A2IE_MASK (0x02) /**< Alarm 2 Interrupt Enable */
#define DS323X_REG_CONTROL_A1IE_MASK (0x01) /**< Alarm 1 Interrupt Enable */
/** @} */
#ifdef __cplusplus
}
#endif
#endif /* DS3234_REGS_H */
/** @} */

69
drivers/include/ds3234.h Normal file
View File

@ -0,0 +1,69 @@
/*
* Copyright 2018 SKF AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup drivers_ds3234 DS3234 Extremely Accurate SPI RTC
* @brief Driver for Maxim DS3234 Extremely Accurate SPI Bus RTC with
* Integrated Crystal and SRAM
* @{
*
* @file
* @brief DS3234 device driver
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se>
*/
#ifndef DS3234_H
#define DS3234_H
#include <periph/gpio.h>
#include <periph/spi.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Parameters for the DS3234 device driver
*/
typedef struct {
spi_t spi; /**< SPI bus the sensor is connected to */
spi_clk_t clk; /**< SPI bus clock speed */
gpio_t cs; /**< CS pin GPIO handle */
} ds3234_params_t;
/**
* @brief Return codes for the DS3234 device driver
*/
enum ds3234_return_codes {
DS3234_OK = 0,
DS3234_NO_DEV = 1,
DS3234_NO_SPI = 2
};
/**
* @brief Initialize the DS3234 RTC as a PPS device
*
* This will enable square wave output on the SQW pin at 1 Hz
*
* @param params DS3234 circuit parameters
*
* @return DS3234_OK on success
* @return DS3234_NO_SPI if cannot initiate SPI
* @return DS3234_NO_DEV if the device is not found on the bus
*/
int ds3234_pps_init(const ds3234_params_t *params);
#ifdef __cplusplus
}
#endif
#endif /* DS3234_H */
/** @} */

View File

@ -0,0 +1,5 @@
include ../Makefile.tests_common
USEMODULE += ds3234
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,10 @@
# About
This is a simple test application for the DS3234 SPI RTC driver PPS output.
# Usage
This test application will initialize the RTC with the following parameters:
- Oscillator enabled
- Square wave output enabled
- Square wave frequency: 1 Hz

View File

@ -0,0 +1,51 @@
/*
* Copyright (C) 2018 SKF AB
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
*
* @file
* @brief Test application for the DS3234 RTC driver
*
* @author Joakim Nohlgård <joakim.nohlgard@eistec.se
*
* @}
*/
#include <stdio.h>
#include "board.h"
#include "ds3234.h"
#include "ds3234_params.h"
int main(void)
{
puts("DS3234 RTC PPS test application\n");
for (unsigned k = 0; k < (sizeof(ds3234_params) / sizeof(ds3234_params[0])); ++k) {
printf("Init #%u... ", k);
int res = ds3234_pps_init(&ds3234_params[k]);
if (res == 0) {
puts("[OK]");
}
else {
puts("[Failed]\n");
return 1;
}
}
puts("DS3234 init done.\n");
puts("Check SQW pin on all connected DS3234 for a 1 Hz square wave signal\n");
while (1) {
/* Spin */
}
return 0;
}