Skip to content

Commit

Permalink
Extend the RTC framework with an alarm read ioctl (RTC_RD_ALARM). Thr…
Browse files Browse the repository at this point in the history
…ough it consumer could get configuration settings about previously scheduled hardware alarms (active status, hours, minutes, seconds).
  • Loading branch information
bpastardzhiev authored and gregory-nutt committed Sep 3, 2017
1 parent daac3bd commit b1eceb8
Show file tree
Hide file tree
Showing 5 changed files with 208 additions and 1 deletion.
8 changes: 8 additions & 0 deletions arch/arm/src/stm32l4/stm32l4_rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ struct alm_setalarm_s
FAR void *as_arg; /* Argument for callback */
};

/* Structure used to pass parameters to query an alarm */

struct alm_rdalarm_s
{
int as_id; /* enum alm_id_e */
FAR struct rtc_time *as_time;/* Argument for storing ALARM RTC time */
};

#endif /* CONFIG_RTC_ALARM */

/****************************************************************************
Expand Down
49 changes: 49 additions & 0 deletions arch/arm/src/stm32l4/stm32l4_rtc_lowerhalf.c
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,8 @@ static int stm32l4_setrelative(FAR struct rtc_lowerhalf_s *lower,
FAR const struct lower_setrelative_s *alarminfo);
static int stm32l4_cancelalarm(FAR struct rtc_lowerhalf_s *lower,
int alarmid);
static int stm32l4_rdalarm(FAR struct rtc_lowerhalf_s *lower,
FAR struct lower_rdalarm_s *alarminfo);
#endif

/****************************************************************************
Expand All @@ -133,6 +135,7 @@ static const struct rtc_ops_s g_rtc_ops =
.setalarm = stm32l4_setalarm,
.setrelative = stm32l4_setrelative,
.cancelalarm = stm32l4_cancelalarm,
.rdalarm = stm32l4_rdalarm,
#endif
#ifdef CONFIG_RTC_IOCTL
.ioctl = NULL,
Expand Down Expand Up @@ -496,6 +499,52 @@ static int stm32l4_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
}
#endif

/****************************************************************************
* Name: stm32l4_rdalarm
*
* Description:
* Query the RTC alarm.
*
* Input Parameters:
* lower - A reference to RTC lower half driver state structure
* alarminfo - Provided information needed to query 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 stm32l4_rdalarm(FAR struct rtc_lowerhalf_s *lower,
FAR struct lower_rdalarm_s *alarminfo)
{
struct alm_rdalarm_s lowerinfo;
int ret = -EINVAL;

ASSERT(lower != NULL && alarminfo != NULL && alarminfo->time != NULL);
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);

if (alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB)
{
/* Disable pre-emption while we do this so that we don't have to worry
* about being suspended and working on an old time.
*/

sched_lock();

lowerinfo.as_id = alarminfo->id;
lowerinfo.as_time = alarminfo->time;

ret = stm32l4_rtc_rdalarm(&lowerinfo);

sched_unlock();
}

return ret;
}
#endif

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down
94 changes: 94 additions & 0 deletions arch/arm/src/stm32l4/stm32l4_rtcc.c
Original file line number Diff line number Diff line change
Expand Up @@ -1479,4 +1479,98 @@ int stm32l4_rtc_cancelalarm(enum alm_id_e alarmid)
}
#endif

#ifdef CONFIG_RTC_ALARM
/************************************************************************************
* Name: stm32l4_rtc_getalarmdatetime
*
* Description:
* Get the current date and time for a RTC alarm.
*
* Input Parameters:
* reg - RTC alarm register
* tp - The location to return the high resolution time value.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/

int stm32l4_rtc_getalarmdatetime(rtc_alarmreg_t reg, FAR struct tm *tp)
{
uint32_t data, tmp;

ASSERT(tp != NULL);

/* Sample the data time register. */

data = getreg32(reg);

/* Convert the RTC time to fields in struct tm format. All of the STM32
* All of the ranges of values correspond between struct tm and the time
* register.
*/

tmp = (data & (RTC_ALRMR_SU_MASK | RTC_ALRMR_ST_MASK)) >> RTC_ALRMR_SU_SHIFT;
tp->tm_sec = rtc_bcd2bin(tmp);

tmp = (data & (RTC_ALRMR_MNU_MASK | RTC_ALRMR_MNT_MASK)) >> RTC_ALRMR_MNU_SHIFT;
tp->tm_min = rtc_bcd2bin(tmp);

tmp = (data & (RTC_ALRMR_HU_MASK | RTC_ALRMR_HT_MASK)) >> RTC_ALRMR_HU_SHIFT;
tp->tm_hour = rtc_bcd2bin(tmp);

return OK;
}
#endif

/************************************************************************************
* Name: stm32l4_rtc_rdalarm
*
* Description:
* Query an alarm configured in hardware.
*
* Input Parameters:
* alminfo - Information about the alarm configuration.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/

#ifdef CONFIG_RTC_ALARM
int stm32l4_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo)
{
rtc_alarmreg_t alarmreg;
int ret = -EINVAL;

ASSERT(alminfo != NULL);
DEBUGASSERT(RTC_ALARM_LAST > alminfo->as_id);

switch (alminfo->as_id)
{
case RTC_ALARMA:
{
alarmreg = STM32L4_RTC_ALRMAR;
ret = stm32l4_rtc_getalarmdatetime(alarmreg,
(struct tm *)alminfo->as_time);
}
break;

case RTC_ALARMB:
{
alarmreg = STM32L4_RTC_ALRMBR;
ret = stm32l4_rtc_getalarmdatetime(alarmreg,
(struct tm *)alminfo->as_time);
}
break;

default:
rtcerr("ERROR: Invalid ALARM%d\n", alminfo->as_id);
break;
}

return ret;
}
#endif

#endif /* CONFIG_RTC */
34 changes: 34 additions & 0 deletions drivers/timers/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,40 @@ static int rtc_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
}
break;

/* RTC_RD_ALARM query the alarm.
*
* Argument: A writable reference to the queried alarm.
*
*/

case RTC_RD_ALARM:
{
FAR struct rtc_rdalarm_s *alarmquery =
(FAR struct rtc_rdalarm_s *)((uintptr_t)arg);
FAR struct rtc_alarminfo_s *upperinfo;
struct lower_rdalarm_s lowerinfo;
int alarmid;

DEBUGASSERT(alarmquery != NULL);
alarmid = alarmquery->id;
DEBUGASSERT(alarmid >= 0 && alarmid < CONFIG_RTC_NALARMS);

/* Is the alarm active? */

upperinfo = &upper->alarminfo[alarmid];
alarmquery->active = upperinfo->active;

lowerinfo.id = alarmid;
lowerinfo.priv = (FAR void *)upper;
lowerinfo.time = (FAR struct rtc_time *)&alarmquery->time;

if (ops->rdalarm)
{
ret = ops->rdalarm(upper->lower, &lowerinfo);
}
}
break;
#endif /* CONFIG_RTC_ALARM */

/* Forward any unrecognized IOCTLs to the lower half driver... they
Expand Down
24 changes: 23 additions & 1 deletion include/nuttx/timers/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,13 @@

#define RTC_CANCEL_ALARM _RTCIOC(0x0006)

/* RTC_RD_ALARM query the alarm.
*
* Argument: An ALARM ID value that indicates which alarm should be queried.
*/

#define RTC_RD_ALARM _RTCIOC(0x0007)

/* Architecture-specific RTC IOCTLS should begin at RTC_USER_IOCBASE. For
* example:
*
Expand All @@ -185,7 +192,8 @@
* etc.
*/

#define RTC_USER_IOCBASE 0x0007
#define RTC_USER_IOCBASE 0x0008


/****************************************************************************
* Public Types
Expand Down Expand Up @@ -273,6 +281,15 @@ struct lower_setrelative_s
FAR void *priv; /* Private argurment to accompany callback */
time_t reltime; /* Relative time in seconds */
};

/* Structure used with the rdalarm method */

struct lower_rdalarm_s
{
uint8_t id; /* Indicates the alarm to be set */
FAR void *priv; /* Private argurment to accompany callback */
FAR struct rtc_time *time;/* Queried RTC time pointer */
};
#endif

/* The RTC driver is implemented as a common, upper-half character driver
Expand Down Expand Up @@ -318,6 +335,11 @@ struct rtc_ops_s
/* cancelalarm cancels the current alarm. */

CODE int (*cancelalarm)(FAR struct rtc_lowerhalf_s *lower, int alarmid);

/* rdalarm query the current alarm. */

CODE int (*rdalarm)(FAR struct rtc_lowerhalf_s *lower,
FAR struct lower_rdalarm_s *alarminfo);
#endif

#ifdef CONFIG_RTC_IOCTL
Expand Down

0 comments on commit b1eceb8

Please sign in to comment.