STM32 RTC: Add implementation of logic to set the alarm relative to the current time

This commit is contained in:
Gregory Nutt 2016-04-02 18:17:46 -06:00
parent a609880839
commit e904d98915
2 changed files with 93 additions and 36 deletions

View File

@ -113,6 +113,8 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower, static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
FAR const struct lower_setalarm_s *alarminfo); FAR const struct lower_setalarm_s *alarminfo);
static int stm32_setrelative(FAR struct rtc_lowerhalf_s *lower,
FAR const struct lower_setrelative_s *alarminfo);
static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower,
int alarmid); int alarmid);
#endif #endif
@ -128,6 +130,7 @@ static const struct rtc_ops_s g_rtc_ops =
.settime = stm32_settime, .settime = stm32_settime,
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
.setalarm = stm32_setalarm, .setalarm = stm32_setalarm,
.setrelative = stm32_setrelative,
.cancelalarm = stm32_cancelalarm, .cancelalarm = stm32_cancelalarm,
#endif #endif
#ifdef CONFIG_RTC_IOCTL #ifdef CONFIG_RTC_IOCTL
@ -363,8 +366,8 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
{ {
#ifdef CONFIG_STM32_STM32F40XX #ifdef CONFIG_STM32_STM32F40XX
FAR struct stm32_lowerhalf_s *priv; FAR struct stm32_lowerhalf_s *priv;
FAR struct stm32_cbinfo_s *cbinfo;
struct alm_setalarm_s lowerinfo; struct alm_setalarm_s lowerinfo;
struct stm32_cbinfo_s *cbinfo;
int ret = -EINVAL; int ret = -EINVAL;
/* ID0-> Alarm A; ID1 -> Alarm B */ /* ID0-> Alarm A; ID1 -> Alarm B */
@ -386,6 +389,7 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
lowerinfo.as_id = alarminfo->id; lowerinfo.as_id = alarminfo->id;
lowerinfo.as_cb = stm32_alarm_callback; lowerinfo.as_cb = stm32_alarm_callback;
lowerinfo.as_arg = priv;
memcpy(&lowerinfo.as_time, &alarminfo->time, sizeof(struct tm)); memcpy(&lowerinfo.as_time, &alarminfo->time, sizeof(struct tm));
/* And set the alarm */ /* And set the alarm */
@ -401,6 +405,7 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
return ret; return ret;
#else #else
FAR struct stm32_cbinfo_s *cbinfo;
int ret = -EINVAL; int ret = -EINVAL;
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0); DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->id == 0);
@ -416,16 +421,17 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
/* Remember the callback information */ /* Remember the callback information */
lower->cb = alarminfo->cb; cbinfo = &priv->cbinfo[0];
lower->priv = alarminfo->priv; cbinfo->cb = alarminfo->cb;
cbinfo->priv = alarminfo->priv;
/* And set the alarm */ /* And set the alarm */
ret = stm32_rtc_setalarm(&ts, stm32_alarm_callback); ret = stm32_rtc_setalarm(&ts, stm32_alarm_callback);
if (ret < 0) if (ret < 0)
{ {
lower->cb = NULL; cbinfo->cb = NULL;
lower->priv = NULL; cbinfo->priv = NULL;
} }
} }
@ -434,6 +440,74 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
} }
#endif #endif
/****************************************************************************
* Name: stm32_setrelative
*
* Description:
* Set a new alarm relative to the current time. This function implements
* the setrelative() method of the RTC driver interface
*
* Input Parameters:
* lower - A reference to RTC lower half driver state structure
* alarminfo - Provided information needed to set the alarm
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned
* on any failure.
*
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
static int stm32_setrelative(FAR struct rtc_lowerhalf_s *lower,
FAR const struct lower_setrelative_s *alarminfo)
{
#ifdef CONFIG_STM32_STM32F40XX
FAR struct stm32_lowerhalf_s *priv;
struct alm_setrelative_s lowerinfo;
struct stm32_cbinfo_s *cbinfo;
int ret = -EINVAL;
/* ID0-> Alarm A; ID1 -> Alarm B */
DEBUGASSERT(lower != NULL && alarminfo != NULL);
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);
priv = (FAR struct stm32_lowerhalf_s *)lower;
if (alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB)
{
/* Remember the callback information */
cbinfo = &priv->cbinfo[alarminfo->id];
cbinfo->cb = alarminfo->cb;
cbinfo->priv = alarminfo->priv;
cbinfo->id = alarminfo->id;
/* Set the alarm */
lowerinfo.asr_id = alarminfo->id;
lowerinfo.asr_minutes = alarminfo->reltime / 60;
lowerinfo.asr_cb = stm32_alarm_callback;
lowerinfo.asr_arg = priv;
/* And set the alarm */
ret = stm32_rtc_setalarm_rel(&lowerinfo);
if (ret < 0)
{
cbinfo->cb = NULL;
cbinfo->priv = NULL;
}
}
return ret;
#else
# warning Missing logic
return -ENOSYS;
#endif
}
#endif
/**************************************************************************** /****************************************************************************
* Name: stm32_cancelalarm * Name: stm32_cancelalarm
* *
@ -464,13 +538,16 @@ static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
return -ENOSYS; return -ENOSYS;
#else #else
FAR struct stm32_cbinfo_s *cbinfo;
DEBUGASSERT(lower != NULL); DEBUGASSERT(lower != NULL);
DEBUGASSERT(alarmid == 0); DEBUGASSERT(alarmid == 0);
/* Nullify callback information to reduce window for race conditions */ /* Nullify callback information to reduce window for race conditions */
lower->cb = NULL; cbinfo = &priv->cbinfo[0];
lower->priv = NULL; cbinfo->cb = alarminfo->cb;
cbinfo->priv = alarminfo->priv;
return stm32_rtc_cancelalarm(); return stm32_rtc_cancelalarm();

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
* arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c * arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c
* *
* Copyright (C) 2015 Gregory Nutt. All rights reserved. * Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org> * Author: Gregory Nutt <gnutt@nuttx.org>
* dev@ziggurat29.com (adaptations for stm32l4) * dev@ziggurat29.com (adaptations for stm32l4)
* *
@ -91,38 +91,18 @@ static int stm32l4_settime(FAR struct rtc_lowerhalf_s *lower,
static const struct rtc_ops_s g_rtc_ops = static const struct rtc_ops_s g_rtc_ops =
{ {
.rdtime = stm32l4_rdtime, .rdtime = stm32l4_rdtime,
.settime = stm32l4_settime, .settime = stm32l4_settime,
#ifdef CONFIG_RTC_ALARM #ifdef CONFIG_RTC_ALARM
.almread = NULL, .setalarm = NULL,
.almset = NULL, .setrelative = NULL,
#endif .cancelalarm = NULL,
#ifdef CONFIG_RTC_PERIODIC
.irqpread = NULL,
.irqpset = NULL,
#endif
#ifdef CONFIG_RTC_ALARM
.aie = NULL,
#endif
#ifdef CONFIG_RTC_ONESEC
.uie = NULL,
#endif
#ifdef CONFIG_RTC_PERIODIC
.pie = NULL,
#endif
#ifdef CONFIG_RTC_EPOCHYEAR
.rdepoch = NULL,
.setepoch = NULL,
#endif
#ifdef CONFIG_RTC_ALARM
.rdwkalm = NULL,
.setwkalm = NULL,
#endif #endif
#ifdef CONFIG_RTC_IOCTL #ifdef CONFIG_RTC_IOCTL
.ioctl = NULL, .ioctl = NULL,
#endif #endif
#ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS #ifndef CONFIG_DISABLE_PSEUDOFS_OPERATIONS
.destroy = NULL, .destroy = NULL,
#endif #endif
}; };
@ -130,7 +110,7 @@ static const struct rtc_ops_s g_rtc_ops =
static struct stm32l4_lowerhalf_s g_rtc_lowerhalf = static struct stm32l4_lowerhalf_s g_rtc_lowerhalf =
{ {
.ops = &g_rtc_ops, .ops = &g_rtc_ops,
}; };
/**************************************************************************** /****************************************************************************