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
|
* Private Function Prototypes
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Prototypes for static methods in struct rtc_ops_s */
|
/* Prototypes for static methods in struct rtc_ops_s */
|
||||||
|
|
||||||
static int max326_rdtime(FAR struct rtc_lowerhalf_s *lower,
|
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
|
#ifdef CONFIG_RTC_ALARM
|
||||||
static int max326_setalarm(FAR struct rtc_lowerhalf_s *lower,
|
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_lowerhalf_s *priv;
|
||||||
FAR struct max326_cbinfo_s *cbinfo;
|
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,
|
static int max326_rdalarm(FAR struct rtc_lowerhalf_s *lower,
|
||||||
FAR struct lower_rdalarm_s *alarminfo)
|
FAR struct lower_rdalarm_s *alarminfo)
|
||||||
{
|
{
|
||||||
struct alm_rdalarm_s lowerinfo;
|
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
DEBUGASSERT(lower != NULL && alarminfo != NULL && alarminfo->time != NULL);
|
DEBUGASSERT(lower != NULL && alarminfo != NULL);
|
||||||
DEBUGASSERT(alarminfo->id < RTC_NALARMS);
|
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
|
/* Disable pre-emption while we do this so that we don't have to worry
|
||||||
* about being suspended and working on an old time.
|
* about being suspended and working on an old time.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sched_lock();
|
ret = max326_rtc_rdalarm(&ftime);
|
||||||
lowerinfo.ar_time = alarminfo->time;
|
if (ret >= 0)
|
||||||
ret = max326_rtc_rdalarm(&lowerinfo);
|
{
|
||||||
sched_unlock();
|
/* 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;
|
return ret;
|
||||||
|
@ -96,7 +96,7 @@ static FAR void *g_alarmarg;
|
|||||||
* Public Data
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/* Indicates that the RTC has be initialized */
|
/* Indicates that the RTC has been initialized */
|
||||||
|
|
||||||
volatile bool g_rtc_enabled = false;
|
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;
|
irqstate_t flags;
|
||||||
b32_t ftime;
|
b32_t ftime;
|
||||||
|
uint64_t rssa;
|
||||||
uint32_t regval;
|
uint32_t regval;
|
||||||
uint32_t sec;
|
|
||||||
uint32_t ssec;
|
|
||||||
uint32_t verify;
|
|
||||||
int ret = -EBUSY;
|
int ret = -EBUSY;
|
||||||
|
|
||||||
DEBUGASSERT(alminfo != NULL && alminfo->as_cb != NULL);
|
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_alarmcb = cb;
|
||||||
g_alarmarg = arg;
|
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);
|
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
|
/* Convert to RSSA value.
|
||||||
* registers.
|
*
|
||||||
|
* 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();
|
flags = spin_lock_irqsave();
|
||||||
|
|
||||||
regval = getreg32(MAX326_RTC_CTRL);
|
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);
|
putreg32(regval, MAX326_RTC_CTRL);
|
||||||
max326_rtc_waitbusy();
|
max326_rtc_waitbusy();
|
||||||
|
|
||||||
/* Then write the time values to the RAS and RSSA registers. */
|
/* Then write the RSSA values. */
|
||||||
|
|
||||||
do
|
putreg32(rssa, MAX326_RTC_RSSA);
|
||||||
{
|
|
||||||
putreg32(sec, MAX326_RTC_RAS);
|
|
||||||
putreg32(ssec, MAX326_RTC_RSSA);
|
|
||||||
verify = getreg32(MAX326_RTC_RAS);
|
|
||||||
}
|
|
||||||
while (verify != sec);
|
|
||||||
|
|
||||||
/* Enable sub-second alarm */
|
/* Enable sub-second alarm */
|
||||||
|
|
||||||
@ -582,6 +603,70 @@ int max326_rtc_setalarm(FAR struct timespec *ts, alm_callback_t cb, FAR void *ar
|
|||||||
}
|
}
|
||||||
#endif
|
#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
|
* Name: max326_rtc_cancelalarm
|
||||||
*
|
*
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
#include <nuttx/config.h>
|
#include <nuttx/config.h>
|
||||||
|
#include <fixedmath.h>
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Public Types
|
* Public Types
|
||||||
@ -52,13 +53,6 @@
|
|||||||
|
|
||||||
typedef CODE void (*alm_callback_t)(FAR void *arg, unsigned int alarmid);
|
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
|
* Public Data
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -84,6 +78,7 @@ extern "C"
|
|||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* ts - Alarm time
|
* ts - Alarm time
|
||||||
|
* id - A
|
||||||
* cb - Callback invoked when alarm expires
|
* cb - Callback invoked when alarm expires
|
||||||
* arg - Argument passed with the alarm
|
* 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.
|
* Query an alarm configured in hardware.
|
||||||
*
|
*
|
||||||
* Input Parameters:
|
* Input Parameters:
|
||||||
* alminfo - Information about the alarm configuration.
|
* ftime - Location to return the current alarm setting.
|
||||||
*
|
*
|
||||||
* Returned Value:
|
* Returned Value:
|
||||||
* Zero (OK) on success; a negated errno on failure
|
* 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
|
#ifdef CONFIG_RTC_ALARM
|
||||||
int max326_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo);
|
int max326_rtc_rdalarm(FAR b32_t *ftime);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
Loading…
Reference in New Issue
Block a user