arch/arm/src/max326xx: Add missing function to get the alarm time.
This commit is contained in:
parent
bd5d079c02
commit
c7cb4fa594
@ -106,6 +106,7 @@ struct max326_lowerhalf_s
|
||||
/****************************************************************************
|
||||
* Private Function Prototypes
|
||||
****************************************************************************/
|
||||
|
||||
/* Prototypes for static methods in struct rtc_ops_s */
|
||||
|
||||
static int max326_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
||||
@ -374,7 +375,7 @@ static bool max326_havesettime(FAR struct rtc_lowerhalf_s *lower)
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
static int max326_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR const struct lower_setalarm_s *alarminfo)
|
||||
FAR const struct lower_setalarm_s *alarminfo)
|
||||
{
|
||||
FAR struct max326_lowerhalf_s *priv;
|
||||
FAR struct max326_cbinfo_s *cbinfo;
|
||||
@ -579,22 +580,35 @@ static int max326_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
|
||||
static int max326_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||
FAR struct lower_rdalarm_s *alarminfo)
|
||||
{
|
||||
struct alm_rdalarm_s lowerinfo;
|
||||
int ret = -EINVAL;
|
||||
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->time != NULL);
|
||||
DEBUGASSERT(alarminfo->id < RTC_NALARMS);
|
||||
DEBUGASSERT(lower != NULL && alarminfo != NULL);
|
||||
DEBUGASSERT(alarminfo->id == 0 && alarminfo->time != NULL);
|
||||
|
||||
if (alarminfo->id < RTC_NALARMS)
|
||||
if (alarminfo->id == 0)
|
||||
{
|
||||
b32_t ftime;
|
||||
|
||||
/* 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.ar_time = alarminfo->time;
|
||||
ret = max326_rtc_rdalarm(&lowerinfo);
|
||||
sched_unlock();
|
||||
ret = max326_rtc_rdalarm(&ftime);
|
||||
if (ret >= 0)
|
||||
{
|
||||
/* Extract integer seconds from the b32_t value */
|
||||
|
||||
time_t sec = (time_t)(b32toi(ftime));
|
||||
|
||||
/* Convert to struct rtc_time (aka struct tm) */
|
||||
|
||||
#ifdef CONFIG_LIBC_LOCALTIME
|
||||
(void)localtime_r(&sec, (FAR struct tm *)alarminfo->time);
|
||||
#else
|
||||
(void)gmtime_r(&sec, (FAR struct tm *)alarminfo->time);
|
||||
#endif
|
||||
ret = OK;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -96,7 +96,7 @@ static FAR void *g_alarmarg;
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
|
||||
/* Indicates that the RTC has be initialized */
|
||||
/* Indicates that the RTC has been initialized */
|
||||
|
||||
volatile bool g_rtc_enabled = false;
|
||||
|
||||
@ -519,10 +519,8 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb, FAR void *ar
|
||||
{
|
||||
irqstate_t flags;
|
||||
b32_t ftime;
|
||||
uint64_t rssa;
|
||||
uint32_t regval;
|
||||
uint32_t sec;
|
||||
uint32_t ssec;
|
||||
uint32_t verify;
|
||||
int ret = -EBUSY;
|
||||
|
||||
DEBUGASSERT(alminfo != NULL && alminfo->as_cb != NULL);
|
||||
@ -538,16 +536,45 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb, FAR void *ar
|
||||
g_alarmcb = cb;
|
||||
g_alarmarg = arg;
|
||||
|
||||
/* Get the time as a fixed precision number. */
|
||||
/* Get the time as a fixed precision number.
|
||||
* Form: ssssssss ssssssss ffffffff ffffff
|
||||
* | `- 32-bits of fraction
|
||||
* `- 32-bits of integer seconds
|
||||
*/
|
||||
|
||||
ftime = max326_rtc_tm2b32(ts);
|
||||
sec = b32toi(ftime);
|
||||
ssec = (uint32_t)(b32frac(ftime) >> (32 - 8));
|
||||
|
||||
/* We need to disable ALARMs in order to write to the RAS and RSSA
|
||||
* registers.
|
||||
/* Convert to RSSA value.
|
||||
*
|
||||
* Writing RSSA sets the starting value for the sub-second alarm
|
||||
* counter. Writing the SSEN enables the sub-second alarm. Once
|
||||
* enabled, the sub-second alarm begins up-counting from the RSSA
|
||||
* value. When the counter rolls over from 0xffffffff to 0x00000000.
|
||||
* A 256Hz clock drives the sub-second alarm allowing a maximum
|
||||
* interval of 16,777,216 seconds with a resolution of approximately
|
||||
* 3.9 msec.
|
||||
*
|
||||
* The delay is ssss ssff Where ssssss is the ls 24 bits of seconds
|
||||
* and ff is the 8bit fractional value. To get the RSSA, that value
|
||||
* has to be subtracted from 1 << 32.
|
||||
*/
|
||||
|
||||
if (b32toi(ftime) >16777216)
|
||||
{
|
||||
rssa = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
rssa = 0x0000000100000000 -
|
||||
((ftime >> (32 - 8)) & 0x00000000ffffffff);
|
||||
if (rssa > UINT32_MAX)
|
||||
{
|
||||
rssa = UINT32_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
/* We need to disable ALARMs in order to write to the RSSA registers. */
|
||||
|
||||
flags = spin_lock_irqsave();
|
||||
|
||||
regval = getreg32(MAX326_RTC_CTRL);
|
||||
@ -555,15 +582,9 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb, FAR void *ar
|
||||
putreg32(regval, MAX326_RTC_CTRL);
|
||||
max326_rtc_waitbusy();
|
||||
|
||||
/* Then write the time values to the RAS and RSSA registers. */
|
||||
/* Then write the RSSA values. */
|
||||
|
||||
do
|
||||
{
|
||||
putreg32(sec, MAX326_RTC_RAS);
|
||||
putreg32(ssec, MAX326_RTC_RSSA);
|
||||
verify = getreg32(MAX326_RTC_RAS);
|
||||
}
|
||||
while (verify != sec);
|
||||
putreg32(rssa, MAX326_RTC_RSSA);
|
||||
|
||||
/* Enable sub-second alarm */
|
||||
|
||||
@ -582,6 +603,70 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb, FAR void *ar
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: max326_rtc_rdalarm
|
||||
*
|
||||
* Description:
|
||||
* Query an alarm configured in hardware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* ftime - Location to return the current alarm setting.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
int max326_rtc_rdalarm(FAR b32_t *ftime)
|
||||
{
|
||||
uint64_t b32val;
|
||||
uint64_t b32rssa;
|
||||
uint32_t sec;
|
||||
uint32_t rssa;
|
||||
uint32_t verify;
|
||||
uint32_t regval;
|
||||
|
||||
DEBUGASSERT(ftime != NULL);
|
||||
|
||||
/* Read the SEC and the RSSA registers */
|
||||
|
||||
do
|
||||
{
|
||||
rssa = getreg32(MAX326_RTC_RSSA);
|
||||
sec = getreg32(MAX326_RTC_SEC);
|
||||
verify = getreg32(MAX326_RTC_RSSA);
|
||||
}
|
||||
while (verify != rssa);
|
||||
|
||||
/* Check if the alarm is enabled */
|
||||
|
||||
regval = getreg32(MAX326_RTC_CTRL);
|
||||
if ((regval & RTC_CTRL_ALARM_SSEN) == 0)
|
||||
{
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Convert the RSA value to b32_t time
|
||||
*
|
||||
* Form: SSssssssff00000
|
||||
*
|
||||
* Where SS is the MS 8-bits of seconds from the SEC register
|
||||
* ssssss is the LS 24 bits of seconds from the RRSA register.
|
||||
* ff is the MS 8-bit of the fractional value.
|
||||
*
|
||||
* Where the sssssff value is (1 << 32) - RRSA, that is, the time
|
||||
* remaining until the rollover.
|
||||
*/
|
||||
|
||||
b32val = (uint64_t)(sec & 0xff000000) << 32;
|
||||
b32rssa = 0x0000000100000000 - (uint64_t)rssa;
|
||||
b32rssa = (b32rssa & 0x00000000ffffffff) << (32 - 8);
|
||||
*ftime = (b32_t)(b32val | b32rssa);
|
||||
return OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* Name: max326_rtc_cancelalarm
|
||||
*
|
||||
|
@ -41,6 +41,7 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
#include <fixedmath.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Public Types
|
||||
@ -52,13 +53,6 @@
|
||||
|
||||
typedef CODE void (*alm_callback_t)(FAR void *arg, unsigned int alarmid);
|
||||
|
||||
/* Structure used to pass parameters to query an alarm */
|
||||
|
||||
struct alm_rdalarm_s
|
||||
{
|
||||
FAR struct rtc_time *ar_time; /* Argument for storing ALARM RTC time */
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Public Data
|
||||
****************************************************************************/
|
||||
@ -84,6 +78,7 @@ extern "C"
|
||||
*
|
||||
* Input Parameters:
|
||||
* ts - Alarm time
|
||||
* id - A
|
||||
* cb - Callback invoked when alarm expires
|
||||
* arg - Argument passed with the alarm
|
||||
*
|
||||
@ -104,7 +99,7 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb,
|
||||
* Query an alarm configured in hardware.
|
||||
*
|
||||
* Input Parameters:
|
||||
* alminfo - Information about the alarm configuration.
|
||||
* ftime - Location to return the current alarm setting.
|
||||
*
|
||||
* Returned Value:
|
||||
* Zero (OK) on success; a negated errno on failure
|
||||
@ -112,7 +107,7 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb,
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_RTC_ALARM
|
||||
int max326_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo);
|
||||
int max326_rtc_rdalarm(FAR b32_t *ftime);
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
|
Loading…
Reference in New Issue
Block a user