Extend the RTC framework with an alarm read ioctl (RTC_RD_ALARM). Through it consumer could get configuration settings about previously scheduled hardware alarms (active status, hours, minutes, seconds).
This commit is contained in:
parent
daac3bd7f8
commit
b1eceb838b
@ -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 */
|
||||
|
||||
/****************************************************************************
|
||||
|
@ -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
|
||||
|
||||
/****************************************************************************
|
||||
@ -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,
|
||||
@ -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
|
||||
****************************************************************************/
|
||||
|
@ -1479,4 +1479,98 @@ errout_with_wprunlock:
|
||||
}
|
||||
#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 */
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
*
|
||||
@ -185,7 +192,8 @@
|
||||
* etc.
|
||||
*/
|
||||
|
||||
#define RTC_USER_IOCBASE 0x0007
|
||||
#define RTC_USER_IOCBASE 0x0008
|
||||
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -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
|
||||
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user