mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
drivers/ds3231: add alarm support
tests/driver_ds3231 drivers/ds3231: add alarm support with IRQ drivers/ds3231: alarm support and documentation drivers/ds3231: alarm interrupt with mutex drivers/ds3231: alarm, _unlock function fixup! drivers/ds3231: add alarm support
This commit is contained in:
parent
010ba56174
commit
c710aff9c6
@ -1 +1,5 @@
|
|||||||
FEATURES_REQUIRED += periph_i2c
|
FEATURES_REQUIRED += periph_i2c
|
||||||
|
|
||||||
|
ifneq (,$(filter ds3231_int,$(USEMODULE)))
|
||||||
|
FEATURES_REQUIRED += periph_gpio_irq
|
||||||
|
endif
|
@ -21,6 +21,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include "bcd.h"
|
#include "bcd.h"
|
||||||
|
#include "mutex.h"
|
||||||
#include "ds3231.h"
|
#include "ds3231.h"
|
||||||
|
|
||||||
#define ENABLE_DEBUG 0
|
#define ENABLE_DEBUG 0
|
||||||
@ -75,11 +76,11 @@
|
|||||||
#define CTRL_BBSQW 0x40
|
#define CTRL_BBSQW 0x40
|
||||||
#define CTRL_CONV 0x20
|
#define CTRL_CONV 0x20
|
||||||
#define CTRL_RS2 0x10
|
#define CTRL_RS2 0x10
|
||||||
#define CTRL_RS1 0x80
|
#define CTRL_RS1 0x08
|
||||||
#define CTRL_RS (CTRL_RS2 | CTRL_RS1)
|
#define CTRL_RS (CTRL_RS2 | CTRL_RS1)
|
||||||
#define CTRL_INTCN 0x40
|
#define CTRL_INTCN 0x04
|
||||||
#define CTRL_A2IE 0x20
|
#define CTRL_A2IE 0x02
|
||||||
#define CTRL_A1IE 0x10
|
#define CTRL_A1IE 0x01
|
||||||
#define CTRL_AIE (CTRL_A2IE | CTRL_A1IE)
|
#define CTRL_AIE (CTRL_A2IE | CTRL_A1IE)
|
||||||
|
|
||||||
/* status register bitmaps */
|
/* status register bitmaps */
|
||||||
@ -141,6 +142,13 @@ static int _clrset(const ds3231_t *dev, uint8_t reg,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
static void _unlock(void *m)
|
||||||
|
{
|
||||||
|
mutex_unlock(m);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int ds3231_init(ds3231_t *dev, const ds3231_params_t *params)
|
int ds3231_init(ds3231_t *dev, const ds3231_params_t *params)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
@ -149,8 +157,13 @@ int ds3231_init(ds3231_t *dev, const ds3231_params_t *params)
|
|||||||
memset(dev, 0, sizeof(ds3231_t));
|
memset(dev, 0, sizeof(ds3231_t));
|
||||||
dev->bus = params->bus;
|
dev->bus = params->bus;
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
/* write interrupt pin configuration */
|
||||||
|
dev->int_pin = params->int_pin;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* en or disable 32KHz output */
|
/* en or disable 32KHz output */
|
||||||
if (params->opt & DS2321_OPT_32KHZ_ENABLE) {
|
if (params->opt & DS3221_OPT_32KHZ_ENABLE) {
|
||||||
res = _clrset(dev, REG_STATUS, 0, STAT_EN32KHZ, 1, 0);
|
res = _clrset(dev, REG_STATUS, 0, STAT_EN32KHZ, 1, 0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -160,8 +173,8 @@ int ds3231_init(ds3231_t *dev, const ds3231_params_t *params)
|
|||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* disable interrupts and configure backup battery */
|
/* Configure backup battery */
|
||||||
uint8_t clr = (CTRL_A1IE | CTRL_A2IE);
|
uint8_t clr = 0;
|
||||||
uint8_t set = 0;
|
uint8_t set = 0;
|
||||||
/* if configured, start the oscillator */
|
/* if configured, start the oscillator */
|
||||||
if (params->opt & DS3231_OPT_BAT_ENABLE) {
|
if (params->opt & DS3231_OPT_BAT_ENABLE) {
|
||||||
@ -171,6 +184,14 @@ int ds3231_init(ds3231_t *dev, const ds3231_params_t *params)
|
|||||||
set = CTRL_EOSC;
|
set = CTRL_EOSC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* if configured, enable the interrupts (no SQW output) */
|
||||||
|
if (params->opt & DS3231_OPT_INTER_ENABLE) {
|
||||||
|
set |= CTRL_INTCN;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
clr |= CTRL_INTCN;
|
||||||
|
}
|
||||||
|
|
||||||
return _clrset(dev, REG_CTRL, clr, set, 0, 1);
|
return _clrset(dev, REG_CTRL, clr, set, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -236,6 +257,160 @@ int ds3231_set_time(const ds3231_t *dev, const struct tm *time)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
int ds3231_await_alarm(ds3231_t *dev)
|
||||||
|
{
|
||||||
|
mutex_t mutex = MUTEX_INIT_LOCKED;
|
||||||
|
|
||||||
|
assert(dev != NULL);
|
||||||
|
assert(gpio_is_valid(dev->int_pin));
|
||||||
|
|
||||||
|
if (gpio_init_int(dev->int_pin, GPIO_IN, GPIO_FALLING, _unlock, &mutex) < 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* wait for alarm */
|
||||||
|
mutex_lock(&mutex);
|
||||||
|
|
||||||
|
gpio_irq_disable(dev->int_pin);
|
||||||
|
|
||||||
|
uint8_t status, tmp;
|
||||||
|
_read(dev, REG_STATUS, &status, 1, 1, 0);
|
||||||
|
|
||||||
|
/* clear interrupt flags */
|
||||||
|
tmp = status & ~(STAT_A1F | STAT_A2F);
|
||||||
|
if (_write(dev, REG_STATUS, &tmp, 1, 0, 1) < 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status & (STAT_A1F | STAT_A2F);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int ds3231_set_alarm_1(const ds3231_t *dev, struct tm *time,
|
||||||
|
ds3231_alm_1_mode_t trigger)
|
||||||
|
{
|
||||||
|
uint8_t raw[A1_REG_NUMOF];
|
||||||
|
uint8_t a1mx_mask[A1_REG_NUMOF];
|
||||||
|
|
||||||
|
/* A1M1, A1M2, A1M3 and A1M4 are set accordingly to the trigger type */
|
||||||
|
a1mx_mask[0] = (trigger & 0x01) << 7;
|
||||||
|
a1mx_mask[1] = (trigger & 0x02) << 6;
|
||||||
|
a1mx_mask[2] = (trigger & 0x04) << 5;
|
||||||
|
a1mx_mask[3] = (trigger & 0x08) << 4;
|
||||||
|
|
||||||
|
raw[0] = ((bcd_from_byte(time->tm_sec) & (MASK_SEC10 | MASK_SEC))
|
||||||
|
| a1mx_mask[0]);
|
||||||
|
raw[1] = ((bcd_from_byte(time->tm_min) & (MASK_MIN10 | MASK_MIN))
|
||||||
|
| a1mx_mask[1]);
|
||||||
|
/* note: we always set the hours in 24-hour format */
|
||||||
|
raw[2] = ((bcd_from_byte(time->tm_hour) & (MASK_H20H10 | MASK_HOUR))
|
||||||
|
| a1mx_mask[2]);
|
||||||
|
raw[3] = ((bcd_from_byte(time->tm_wday + 1) & (MASK_DATE10 | MASK_DATE))
|
||||||
|
| a1mx_mask[3]);
|
||||||
|
|
||||||
|
/* write alarm configuration to device */
|
||||||
|
if (_write(dev, REG_A1_SEC, raw, A1_REG_NUMOF, 1, 1) < 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* activate alarm 1 in case it was not */
|
||||||
|
if (_clrset(dev, REG_CTRL, 0, CTRL_A1IE, 1, 1) < 0){
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_set_alarm_2(const ds3231_t *dev, struct tm *time,
|
||||||
|
ds3231_alm_2_mode_t trigger)
|
||||||
|
{
|
||||||
|
uint8_t raw[A2_REG_NUMOF];
|
||||||
|
uint8_t a2mx_mask[A2_REG_NUMOF];
|
||||||
|
|
||||||
|
/*A2M2, A2M3 and A2M4 are set accordingly to the trigger type */
|
||||||
|
a2mx_mask[0] = (trigger & 0x01) << 7;
|
||||||
|
a2mx_mask[1] = (trigger & 0x02) << 6;
|
||||||
|
a2mx_mask[2] = (trigger & 0x04) << 5;
|
||||||
|
|
||||||
|
raw[0] = ((bcd_from_byte(time->tm_min) & (MASK_MIN10 | MASK_MIN))
|
||||||
|
| a2mx_mask[0]);
|
||||||
|
/* note: we always set the hours in 24-hour format */
|
||||||
|
raw[1] = ((bcd_from_byte(time->tm_hour) & (MASK_H20H10 | MASK_HOUR))
|
||||||
|
| a2mx_mask[1]);
|
||||||
|
raw[2] = ((bcd_from_byte(time->tm_wday + 1) & (MASK_DATE10 | MASK_DATE))
|
||||||
|
| a2mx_mask[2]);
|
||||||
|
|
||||||
|
/* write alarm configuration to device */
|
||||||
|
if (_write(dev, REG_A2_MIN, raw, A2_REG_NUMOF, 1, 1) < 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* activate alarm 2 in case it was not */
|
||||||
|
if (_clrset(dev, REG_CTRL, 0, CTRL_A2IE, 1, 1) < 0){
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_toggle_alarm_1(const ds3231_t *dev, bool enable)
|
||||||
|
{
|
||||||
|
if (enable){
|
||||||
|
return _clrset(dev, REG_CTRL, 0, CTRL_A1IE, 1, 1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return _clrset(dev, REG_CTRL, CTRL_A1IE, 0, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_toggle_alarm_2(const ds3231_t *dev, bool enable)
|
||||||
|
{
|
||||||
|
if (enable){
|
||||||
|
return _clrset(dev, REG_CTRL, 0, CTRL_A2IE, 1, 1);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return _clrset(dev, REG_CTRL, CTRL_A2IE, 0, 1, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_clear_alarm_1_flag(const ds3231_t *dev)
|
||||||
|
{
|
||||||
|
return _clrset(dev, REG_STATUS, STAT_A1F, 0, 1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_clear_alarm_2_flag(const ds3231_t *dev)
|
||||||
|
{
|
||||||
|
return _clrset(dev, REG_STATUS, STAT_A2F, 0, 1, 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_get_alarm_1_flag(const ds3231_t *dev, bool *flag)
|
||||||
|
{
|
||||||
|
uint8_t raw;
|
||||||
|
int res = _read(dev, REG_STATUS, &raw, 1, 1, 1);
|
||||||
|
if (res != 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
*flag = (raw & STAT_A1F);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ds3231_get_alarm_2_flag(const ds3231_t *dev, bool *flag)
|
||||||
|
{
|
||||||
|
uint8_t raw;
|
||||||
|
int res = _read(dev, REG_STATUS, &raw, 1, 1, 1);
|
||||||
|
if (res != 0) {
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
*flag = (raw & STAT_A2F) >> 1;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
int ds3231_get_aging_offset(const ds3231_t *dev, int8_t *offset)
|
int ds3231_get_aging_offset(const ds3231_t *dev, int8_t *offset)
|
||||||
{
|
{
|
||||||
return _read(dev, REG_AGING_OFFSET, (uint8_t *)offset, 1, 1, 1);
|
return _read(dev, REG_AGING_OFFSET, (uint8_t *)offset, 1, 1, 1);
|
||||||
|
@ -32,11 +32,20 @@ extern "C" {
|
|||||||
#ifndef DS3231_PARAM_OPT
|
#ifndef DS3231_PARAM_OPT
|
||||||
#define DS3231_PARAM_OPT (DS3231_OPT_BAT_ENABLE)
|
#define DS3231_PARAM_OPT (DS3231_OPT_BAT_ENABLE)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef DS3231_PARAM_INT_PIN
|
||||||
|
#define DS3231_PARAM_INT_PIN (GPIO_UNDEF)
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DS3231_PARAMS
|
#ifndef DS3231_PARAMS
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
#define DS3231_PARAMS { .bus = DS3231_PARAM_I2C, \
|
#define DS3231_PARAMS { .bus = DS3231_PARAM_I2C, \
|
||||||
.opt = DS3231_PARAM_OPT, }
|
.opt = DS3231_PARAM_OPT, \
|
||||||
#endif
|
.int_pin = DS3231_PARAM_INT_PIN}
|
||||||
|
#else /* MODULE_DS3231_INT */
|
||||||
|
#define DS3231_PARAMS { .bus = DS3231_PARAM_I2C, \
|
||||||
|
.opt = DS3231_PARAM_OPT}
|
||||||
|
#endif /* MODULE_DS3231_INT */
|
||||||
|
#endif /* DS3231_PARAMS */
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "periph/gpio.h"
|
||||||
#include "periph/i2c.h"
|
#include "periph/i2c.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@ -45,19 +46,52 @@ extern "C" {
|
|||||||
*/
|
*/
|
||||||
#define DS3231_I2C_ADDR 0x68
|
#define DS3231_I2C_ADDR 0x68
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alarm flags returned by the ds3231_await_alarm function
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
#define DS3231_FLAG_ALARM_1 0x01
|
||||||
|
#define DS3231_FLAG_ALARM_2 0x02
|
||||||
|
/** @} */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configuration options
|
* @brief Configuration options
|
||||||
*/
|
*/
|
||||||
enum {
|
enum {
|
||||||
DS3231_OPT_BAT_ENABLE = 0x01, /* enable backup battery on startup */
|
DS3231_OPT_BAT_ENABLE = 0x01, /**< enable backup battery on startup */
|
||||||
DS2321_OPT_32KHZ_ENABLE = 0x02, /* enable 32KHz output */
|
DS3221_OPT_32KHZ_ENABLE = 0x02, /**< enable 32KHz output */
|
||||||
|
DS3231_OPT_INTER_ENABLE = 0x04, /**< enable the interrupt control */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alarm trigger type of alarm 1 for DS3231 devices
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
DS3231_AL1_TRIG_PER_S = 0x0F, /**< alarm once per second */
|
||||||
|
DS3231_AL1_TRIG_S = 0x0E, /**< alarm when seconds match */
|
||||||
|
DS3231_AL1_TRIG_M_S = 0x0C, /**< alarm when minutes and seconds match */
|
||||||
|
DS3231_AL1_TRIG_H_M_S = 0x08, /**< alarm when H/M/S match */
|
||||||
|
DS3231_AL1_TRIG_D_H_M_S = 0x00, /**< alarm when D/H/M/S match */
|
||||||
|
} ds3231_alm_1_mode_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Alarm trigger type of alarm 2 for DS3231 devices
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
DS3231_AL2_TRIG_PER_M = 0x07, /**< alarm once per minute */
|
||||||
|
DS3231_AL2_TRIG_M = 0x06, /**< alarm when minutes match */
|
||||||
|
DS3231_AL2_TRIG_H_M = 0x04, /**< alarm when hours and minutes match */
|
||||||
|
DS3231_AL2_TRIG_D_H_M_S = 0x00, /**< alarm when D/H/M match */
|
||||||
|
} ds3231_alm_2_mode_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Device descriptor for DS3231 devices
|
* @brief Device descriptor for DS3231 devices
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
i2c_t bus; /**< I2C bus the device is connected to */
|
i2c_t bus; /**< I2C bus the device is connected to */
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
gpio_t int_pin; /**< alarm interrupt pin */
|
||||||
|
#endif /* MODULE_DS3231_INT */
|
||||||
} ds3231_t;
|
} ds3231_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -66,8 +100,16 @@ typedef struct {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
i2c_t bus; /**< I2C bus the device is connected to */
|
i2c_t bus; /**< I2C bus the device is connected to */
|
||||||
uint8_t opt; /**< additional options */
|
uint8_t opt; /**< additional options */
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
gpio_t int_pin; /**< alarm interrupt pin */
|
||||||
|
#endif /* MODULE_DS3231_INT */
|
||||||
} ds3231_params_t;
|
} ds3231_params_t;
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
typedef void (*ds3231_alarm_cb_t)(void *);
|
||||||
|
|
||||||
|
#endif /* MODULE_DS3231_INT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Initialize the given DS3231 device
|
* @brief Initialize the given DS3231 device
|
||||||
*
|
*
|
||||||
@ -79,6 +121,24 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
int ds3231_init(ds3231_t *dev, const ds3231_params_t *params);
|
int ds3231_init(ds3231_t *dev, const ds3231_params_t *params);
|
||||||
|
|
||||||
|
#if IS_USED(MODULE_DS3231_INT)
|
||||||
|
/**
|
||||||
|
* @brief Initialize the GPIO alarm interrupt
|
||||||
|
*
|
||||||
|
* This function initializes the pin defined as the interrupt pin in the
|
||||||
|
* initialization parameters of the device then blocks until an alarm is
|
||||||
|
* triggered.
|
||||||
|
*
|
||||||
|
* @note This function is only available when module `ds3231_int` is enabled.
|
||||||
|
*
|
||||||
|
* @param[in] dev device descriptor of DS3231 device
|
||||||
|
*
|
||||||
|
* @return status of A1F and A2F on success
|
||||||
|
* @return -EIO if unable to initialize GPIO interrupt
|
||||||
|
*/
|
||||||
|
int ds3231_await_alarm(ds3231_t *dev);
|
||||||
|
#endif /* MODULE_DS3231_INT */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get date and time from the device
|
* @brief Get date and time from the device
|
||||||
*
|
*
|
||||||
@ -101,6 +161,100 @@ int ds3231_get_time(const ds3231_t *dev, struct tm *time);
|
|||||||
*/
|
*/
|
||||||
int ds3231_set_time(const ds3231_t *dev, const struct tm *time);
|
int ds3231_set_time(const ds3231_t *dev, const struct tm *time);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set alarm 1 of the device
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
* @param[in] time target date and time
|
||||||
|
* @param[in] trigger alarm 1 trigger type
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_set_alarm_1(const ds3231_t *dev, struct tm *time,
|
||||||
|
ds3231_alm_1_mode_t trigger);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Set alarm 2 of the device
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
* @param[in] time target date and time
|
||||||
|
* @param[in] trigger alarm 2 trigger type
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_set_alarm_2(const ds3231_t *dev, struct tm *time,
|
||||||
|
ds3231_alm_2_mode_t trigger);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clear alarm 1 flag (A1F)
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_clear_alarm_1_flag(const ds3231_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clear alarm 2 flag (A2F)
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_clear_alarm_2_flag(const ds3231_t *dev);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of alarm 1 flag (A1F)
|
||||||
|
*
|
||||||
|
* @note This function is not needed when ds3231_await_alarm is used
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
* @param[out] flag Current value of the flag
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_get_alarm_1_flag(const ds3231_t *dev, bool *flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Get the state of alarm 2 flag (A2F)
|
||||||
|
*
|
||||||
|
* @note This function is not needed when ds3231_await_alarm is used
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
* @param[out] flag Current value of the flag
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_get_alarm_2_flag(const ds3231_t *dev, bool *flag);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable/Disable alarm 1 interrupt on the device
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
* @param[in] enable True to enable alarm, false to disable it
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_toggle_alarm_1(const ds3231_t *dev, bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Enable/Disable alarm 2 interrupt on the device
|
||||||
|
*
|
||||||
|
* @param[in] dev DS3231 device descriptor
|
||||||
|
* @param[in] enable True to enable alarm, false to disable it
|
||||||
|
*
|
||||||
|
* @return 0 on success
|
||||||
|
* @return -EIO on I2C communication error
|
||||||
|
*/
|
||||||
|
int ds3231_toggle_alarm_2(const ds3231_t *dev, bool enable);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the configured aging offset (see datasheet for more information)
|
* @brief Get the configured aging offset (see datasheet for more information)
|
||||||
*
|
*
|
||||||
|
@ -205,6 +205,9 @@ PSEUDOMODULES += cc1100
|
|||||||
PSEUDOMODULES += cc1100e
|
PSEUDOMODULES += cc1100e
|
||||||
PSEUDOMODULES += cc1101
|
PSEUDOMODULES += cc1101
|
||||||
|
|
||||||
|
# include variants of ds3231 drivers as pseudo modules
|
||||||
|
PSEUDOMODULES += ds3231_int
|
||||||
|
|
||||||
# interrupt variant of the HMC5883L driver
|
# interrupt variant of the HMC5883L driver
|
||||||
PSEUDOMODULES += hmc5883l_int
|
PSEUDOMODULES += hmc5883l_int
|
||||||
|
|
||||||
|
@ -4,4 +4,7 @@ USEMODULE += ds3231
|
|||||||
USEMODULE += xtimer
|
USEMODULE += xtimer
|
||||||
USEMODULE += shell
|
USEMODULE += shell
|
||||||
|
|
||||||
|
#USEMODULE += ds3231_int
|
||||||
|
#CFLAGS +="-DDS3231_PARAM_INT_PIN=(GPIO_PIN(1,2))"
|
||||||
|
|
||||||
include $(RIOTBASE)/Makefile.include
|
include $(RIOTBASE)/Makefile.include
|
||||||
|
@ -258,8 +258,74 @@ static int _cmd_test(int argc, char **argv)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* clear all existing alarm flag */
|
||||||
|
res = ds3231_clear_alarm_1_flag(&_dev);
|
||||||
|
if (res != 0) {
|
||||||
|
puts("error: unable to clear alarm flag");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get time to set up next alarm*/
|
||||||
|
res = ds3231_get_time(&_dev, &time);
|
||||||
|
if (res != 0) {
|
||||||
|
puts("error: unable to read time");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
time.tm_sec += TEST_DELAY;
|
||||||
|
mktime(&time);
|
||||||
|
|
||||||
|
/* set alarm */
|
||||||
|
res = ds3231_set_alarm_1(&_dev, &time, DS3231_AL1_TRIG_H_M_S);
|
||||||
|
if (res != 0) {
|
||||||
|
puts("error: unable to program alarm");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef MODULE_DS3231_INT
|
||||||
|
|
||||||
|
/* wait for an alarm with GPIO interrupt */
|
||||||
|
res = ds3231_await_alarm(&_dev);
|
||||||
|
if (res < 0){
|
||||||
|
puts("error: unable to program GPIO interrupt or to clear alarm flag");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(res & DS3231_FLAG_ALARM_1)){
|
||||||
|
puts("error: alarm was not triggered");
|
||||||
|
}
|
||||||
|
|
||||||
puts("OK");
|
puts("OK");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* wait for the alarm to trigger */
|
||||||
|
xtimer_sleep(TEST_DELAY);
|
||||||
|
|
||||||
|
bool alarm;
|
||||||
|
|
||||||
|
/* check if alarm flag is on */
|
||||||
|
res = ds3231_get_alarm_1_flag(&_dev, &alarm);
|
||||||
|
if (res != 0) {
|
||||||
|
puts("error: unable to get alarm flag");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (alarm != true){
|
||||||
|
puts("error: alarm was not triggered");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* clear alarm flag */
|
||||||
|
res = ds3231_clear_alarm_1_flag(&_dev);
|
||||||
|
if (res != 0) {
|
||||||
|
puts("error: unable to clear alarm flag");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
puts("OK");
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static const shell_command_t shell_commands[] = {
|
static const shell_command_t shell_commands[] = {
|
||||||
@ -279,7 +345,10 @@ int main(void)
|
|||||||
puts("DS3231 RTC test\n");
|
puts("DS3231 RTC test\n");
|
||||||
|
|
||||||
/* initialize the device */
|
/* initialize the device */
|
||||||
res = ds3231_init(&_dev, &ds3231_params[0]);
|
ds3231_params_t params= ds3231_params[0];
|
||||||
|
params.opt = DS3231_OPT_BAT_ENABLE;
|
||||||
|
params.opt |= DS3231_OPT_INTER_ENABLE;
|
||||||
|
res = ds3231_init(&_dev, ¶ms);
|
||||||
if (res != 0) {
|
if (res != 0) {
|
||||||
puts("error: unable to initialize DS3231 [I2C initialization error]");
|
puts("error: unable to initialize DS3231 [I2C initialization error]");
|
||||||
return 1;
|
return 1;
|
||||||
|
Loading…
Reference in New Issue
Block a user