arch/srm/src/stm32f7: Add CONFIG_RTC_PERIODIC support. Also makes the RTC lowerhalf more like in STM32L4.

This commit is contained in:
Juha Niskanen 2018-03-05 07:46:58 -06:00 committed by Gregory Nutt
parent de6b13b3ab
commit 628821fdf4
9 changed files with 578 additions and 70 deletions

View File

@ -101,7 +101,7 @@ struct alm_rdalarm_s
int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
/************************************************************************************
/****************************************************************************
* Name: stm32_rtc_rdalarm
*
* Description:
@ -113,7 +113,7 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
****************************************************************************/
int stm32_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo);

View File

@ -103,7 +103,7 @@ typedef CODE int (*wakeupcb_t)(void);
int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
/************************************************************************************
/****************************************************************************
* Name: stm32_rtc_rdalarm
*
* Description:
@ -115,7 +115,7 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
****************************************************************************/
int stm32_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo);

View File

@ -1,7 +1,7 @@
############################################################################
# arch/arm/src/stm32f7/Make.defs
#
# Copyright (C) 2015 Gregory Nutt. All rights reserved.
# Copyright (C) 2015, 2018 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# Redistribution and use in source and binary forms, with or without
@ -144,6 +144,9 @@ CHIP_CSRCS += stm32_rtc.c
ifeq ($(CONFIG_RTC_ALARM),y)
CHIP_CSRCS += stm32_exti_alarm.c
endif
ifeq ($(CONFIG_RTC_PERIODIC),y)
CHIP_CSRCS += stm32_exti_wakeup.c
endif
ifeq ($(CONFIG_RTC_DRIVER),y)
CHIP_CSRCS += stm32_rtc_lowerhalf.c
endif

View File

@ -1,8 +1,8 @@
/****************************************************************************
* arch/arm/src/include/stm32f7/stm32_alarm.h
*
* Copyright (C) 2016 Gregory Nutt. All rights reserved.
* Authors: Neil hancock - delegated to Gregory Nutt Mar 30, 2016
* Copyright (C) 2016, 2018 Gregory Nutt. All rights reserved.
* Authors: Neil Hancock - delegated to Gregory Nutt Mar 30, 2016
* David Sidrane <david_s5@nscdg.com>
*
* Redistribution and use in source and binary forms, with or without
@ -44,16 +44,14 @@
#include <nuttx/config.h>
#include <time.h>
#ifdef CONFIG_RTC_ALARM
/****************************************************************************
* Public Types
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
typedef CODE void (*alm_callback_t)(FAR void *arg, unsigned int alarmid);
/* These features map to STM32 RTC from stm32F7xx
*/
/* These features map to STM32 RTC from stm32F7xx */
enum alm_id_e
{
@ -79,11 +77,17 @@ struct alm_rdalarm_s
int ar_id; /* enum alm_id_e */
FAR struct rtc_time *ar_time; /* Argument for storing ALARM RTC time */
};
#endif
#ifdef CONFIG_RTC_PERIODIC
typedef CODE int (*wakeupcb_t)(void);
#endif
/****************************************************************************
* Public Function Prototypes
****************************************************************************/
#ifdef CONFIG_RTC_ALARM
/****************************************************************************
* Name: stm32_rtc_setalarm
*
@ -100,7 +104,7 @@ struct alm_rdalarm_s
int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
/************************************************************************************
/****************************************************************************
* Name: stm32_rtc_rdalarm
*
* Description:
@ -112,7 +116,7 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo);
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
************************************************************************************/
****************************************************************************/
int stm32_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo);
@ -131,6 +135,41 @@ int stm32_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo);
****************************************************************************/
int stm32_rtc_cancelalarm(enum alm_id_e alarmid);
#endif /* CONFIG_RTC_ALARM */
#ifdef CONFIG_RTC_PERIODIC
/****************************************************************************
* Name: stm32_rtc_setperiodic
*
* Description:
* Set a periodic RTC wakeup
*
* Input Parameters:
* period - Time to sleep between wakeups
* callback - Function to call when the period expires.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int stm32_rtc_setperiodic(FAR const struct timespec *period,
wakeupcb_t callback);
/****************************************************************************
* Name: stm32_rtc_cancelperiodic
*
* Description:
* Cancel a periodic wakeup
*
* Input Parameters:
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
int stm32_rtc_cancelperiodic(void);
#endif /* CONFIG_RTC_PERIODIC */
#endif /* __ARCH_ARM_SRC_STM32F7_STM32_ALARM_H */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/stm32f7/stm32_exti.h
*
* Copyright (C) 2015, 2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2015, 2017-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
@ -84,7 +84,7 @@ extern "C"
* Zero (OK) on success; a negated errno value on failure indicating the
* nature of the failure.
*
************************************************************************************/
****************************************************************************/
int stm32_gpiosetevent(uint32_t pinset, bool risingedge, bool fallingedge,
bool event, xcpt_t func, void *arg);
@ -113,6 +113,29 @@ int stm32_exti_alarm(bool risingedge, bool fallingedge, bool event,
xcpt_t func, void *arg);
#endif
/****************************************************************************
* Name: stm32_exti_wakeup
*
* Description:
* Sets/clears EXTI wakeup interrupt.
*
* Input Parameters:
* - rising/falling edge: enables interrupt on rising/falling edges
* - event: generate event when set
* - func: when non-NULL, generate interrupt
* - arg: Argument passed to the interrupt callback
*
* Returned Value:
* Zero (OK) on success; a negated errno value on failure indicating the
* nature of the failure.
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
int stm32_exti_wakeup(bool risingedge, bool fallingedge, bool event,
xcpt_t func, void *arg);
#endif
#undef EXTERN
#if defined(__cplusplus)
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/stm32f7/stm32_rtc.c
*
* Copyright (C) 2011, 2015-2017 Gregory Nutt. All rights reserved.
* Copyright (C) 2011, 2015-2018 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david_s5@nscdg.com>
*
@ -137,6 +137,11 @@ struct alm_cbinfo_s
static struct alm_cbinfo_s g_alarmcb[RTC_ALARM_LAST];
#endif
#ifdef CONFIG_RTC_PERIODIC
static wakeupcb_t g_wakeupcb;
static bool g_wakeup_enabled; /* True: Wakeup interrupts are enabled */
#endif
/****************************************************************************
* Public Data
****************************************************************************/
@ -268,8 +273,8 @@ static void rtc_wprunlock(void)
stm32_pwr_enablebkp(true);
/* The following steps are required to unlock the write protection on all the
* RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR).
/* The following steps are required to unlock the write protection on all
* the RTC registers (except for RTC_ISR[13:8], RTC_TAFCR, and RTC_BKPxR).
*
* 1. Write 0xCA into the RTC_WPR register.
* 2. Write 0x53 into the RTC_WPR register.
@ -1551,7 +1556,7 @@ int stm32_rtc_setalarm(FAR struct alm_setalarm_s *alminfo)
* Cancel an alarm.
*
* Input Parameters:
* alarmid - Identifies the alarm to be cancelled
* alarmid - Identifies the alarm to be canceled
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
@ -1700,4 +1705,281 @@ int stm32_rtc_rdalarm(FAR struct alm_rdalarm_s *alminfo)
}
#endif
/****************************************************************************
* Name: stm32_rtc_wakeup_handler
*
* Description:
* RTC WAKEUP interrupt service routine through the EXTI line
*
* Input Parameters:
* irq - The IRQ number that generated the interrupt
*
* Returned Value:
* Zero (OK) on success; A negated errno value on failure.
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
static int stm32_rtc_wakeup_handler(int irq, FAR void *context,
FAR void *arg)
{
uint32_t regval = 0;
stm32_pwr_enablebkp(true);
regval = getreg32(STM32_RTC_ISR);
regval &= ~RTC_ISR_WUTF;
putreg32(regval, STM32_RTC_ISR);
stm32_pwr_enablebkp(false);
if (g_wakeupcb != NULL)
{
g_wakeupcb();
}
return OK;
}
#endif
/****************************************************************************
* Name: rtc_enable_wakeup
*
* Description:
* Enable periodic wakeup interrupts
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
static inline void rtc_enable_wakeup(void)
{
if (!g_wakeup_enabled)
{
(void)stm32_exti_wakeup(true, false, true, stm32_rtc_wakeup_handler,
NULL);
g_wakeup_enabled = true;
}
}
#endif
/************************************************************************************
* Name: rtc_set_wcksel
*
* Description:
* Sets RTC wakeup clock selection value
*
************************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
static inline void rtc_set_wcksel(unsigned int wucksel)
{
uint32_t regval = 0;
regval = getreg32(STM32_RTC_CR);
regval &= ~RTC_CR_WUCKSEL_MASK;
regval |= wucksel;
putreg32(regval, STM32_RTC_CR);
}
#endif
/****************************************************************************
* Name: stm32_rtc_setperiodic
*
* Description:
* Set a periodic RTC wakeup
*
* Input Parameters:
* period - Time to sleep between wakeups
* callback - Function to call when the period expires.
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
int stm32_rtc_setperiodic(FAR const struct timespec *period,
wakeupcb_t callback)
{
unsigned int wutr_val;
int ret;
int timeout;
uint32_t regval;
uint32_t secs;
uint32_t millisecs;
#if defined(CONFIG_STM32F7_RTC_HSECLOCK)
# error "Periodic wakeup not available for HSE"
#elif defined(CONFIG_STM32F7_RTC_LSICLOCK)
# error "Periodic wakeup not available for LSI (and it is too inaccurate!)"
#elif defined(CONFIG_STM32F7_RTC_LSECLOCK)
const uint32_t rtc_div16_max_msecs = 16 * 1000 * 0xffffU / STM32_LSE_FREQUENCY;
#else
# error "No clock for RTC!"
#endif
/* Lets use RTC wake-up with 0.001 sec to ~18 hour range.
*
* TODO: scale to higher periods, with necessary losing some precision.
* We currently go for subseconds accuracy instead of maximum period.
*/
if (period->tv_sec > 0xffffU ||
(period->tv_sec == 0xffffU && period->tv_nsec > 0))
{
/* More than max. */
secs = 0xffffU;
millisecs = secs * 1000;
}
else
{
secs = period->tv_sec;
millisecs = secs * 1000 + period->tv_nsec / NSEC_PER_MSEC;
}
if (millisecs == 0)
{
return -EINVAL;
}
/* Make sure the alarm interrupt is enabled at the NVIC */
rtc_enable_wakeup();
rtc_wprunlock();
/* Clear WUTE in RTC_CR to disable the wakeup timer */
regval = getreg32(STM32_RTC_CR);
regval &= ~RTC_CR_WUTE;
putreg32(regval, STM32_RTC_CR);
/* Poll WUTWF until it is set in RTC_ISR (takes around 2 RTCCLK clock
* cycles)
*/
ret = -ETIMEDOUT;
for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++)
{
regval = getreg32(STM32_RTC_ISR);
if ((regval & RTC_ISR_WUTWF) != 0)
{
/* Synchronized */
ret = OK;
break;
}
}
/* Set callback function pointer. */
g_wakeupcb = callback;
if (millisecs <= rtc_div16_max_msecs)
{
unsigned int ticks;
/* Select wake-up with 32768/16 hz counter. */
rtc_set_wcksel(RTC_CR_WUCKSEL_RTCDIV16);
/* Get number of ticks. */
ticks = millisecs * STM32_LSE_FREQUENCY / (16 * 1000);
/* Wake-up is after WUT+1 ticks. */
wutr_val = ticks - 1;
}
else
{
/* Select wake-up with 1hz counter. */
rtc_set_wcksel(RTC_CR_WUCKSEL_CKSPRE);
/* Wake-up is after WUT+1 ticks. */
wutr_val = secs - 1;
}
/* Program the wakeup auto-reload value WUT[15:0], and the wakeup clock
* selection.
*/
putreg32(wutr_val, STM32_RTC_WUTR);
regval = getreg32(STM32_RTC_CR);
regval |= RTC_CR_WUTIE | RTC_CR_WUTE;
putreg32(regval, STM32_RTC_CR);
/* Just in case resets the WUTF flag in RTC_ISR */
regval = getreg32(STM32_RTC_ISR);
regval &= ~RTC_ISR_WUTF;
putreg32(regval, STM32_RTC_ISR);
rtc_wprlock();
return ret;
}
#endif
/****************************************************************************
* Name: stm32_rtc_cancelperiodic
*
* Description:
* Cancel a periodic wakeup
*
* Input Parameters:
*
* Returned Value:
* Zero (OK) on success; a negated errno on failure
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
int stm32_rtc_cancelperiodic(void)
{
int ret = OK;
int timeout = 0;
uint32_t regval = 0;
rtc_wprunlock();
/* Clear WUTE and WUTIE in RTC_CR to disable the wakeup timer */
regval = getreg32(STM32_RTC_CR);
regval &= ~(RTC_CR_WUTE | RTC_CR_WUTIE);
putreg32(regval, STM32_RTC_CR);
/* Poll WUTWF until it is set in RTC_ISR (takes around 2 RTCCLK clock
* cycles)
*/
ret = -ETIMEDOUT;
for (timeout = 0; timeout < SYNCHRO_TIMEOUT; timeout++)
{
regval = getreg32(STM32_RTC_ISR);
if ((regval & RTC_ISR_WUTWF) != 0)
{
/* Synchronized */
ret = OK;
break;
}
}
/* Clears RTC_WUTR register */
regval = getreg32(STM32_RTC_WUTR);
regval &= ~RTC_WUTR_MASK;
putreg32(regval, STM32_RTC_WUTR);
rtc_wprlock();
return ret;
}
#endif
#endif /* CONFIG_RTC */

View File

@ -1,7 +1,7 @@
/****************************************************************************
* arch/arm/src/stm32f7/stm32_rtc_lowerhalf.c
*
* Copyright (C) 2015-2016 Gregory Nutt. All rights reserved.
* Copyright (C) 2015-2016, 2018 Gregory Nutt. All rights reserved.
* Authors: Gregory Nutt <gnutt@nuttx.org>
* David Sidrane <david_s5@nscdg.com>
*
@ -34,8 +34,6 @@
*
****************************************************************************/
/* REVISIT: This driver is *not* thread-safe! */
/****************************************************************************
* Included Files
****************************************************************************/
@ -71,7 +69,7 @@
struct stm32_cbinfo_s
{
volatile rtc_alarm_callback_t cb; /* Callback when the alarm expires */
volatile FAR void *priv; /* Private argurment to accompany callback */
volatile FAR void *priv; /* Private argument to accompany callback */
uint8_t id; /* Identifies the alarm */
};
#endif
@ -92,16 +90,25 @@ struct stm32_lowerhalf_s
* this file.
*/
sem_t devsem; /* Threads can only exclusively access the RTC */
#ifdef CONFIG_RTC_ALARM
/* Alarm callback information */
struct stm32_cbinfo_s cbinfo[STM32_NALARMS];
#endif
#ifdef CONFIG_RTC_PERIODIC
/* Periodic wakeup information */
struct lower_setperiodic_s periodic;
#endif
};
/****************************************************************************
* Private Function Prototypes
****************************************************************************/
/* Prototypes for static methods in struct rtc_ops_s */
static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower,
@ -121,6 +128,12 @@ static int stm32_rdalarm(FAR struct rtc_lowerhalf_s *lower,
FAR struct lower_rdalarm_s *alarminfo);
#endif
#ifdef CONFIG_RTC_PERIODIC
static int stm32_setperiodic(FAR struct rtc_lowerhalf_s *lower,
FAR const struct lower_setperiodic_s *alarminfo);
static int stm32_cancelperiodic(FAR struct rtc_lowerhalf_s *lower, int id);
#endif
/****************************************************************************
* Private Data
****************************************************************************/
@ -137,6 +150,10 @@ static const struct rtc_ops_s g_rtc_ops =
.cancelalarm = stm32_cancelalarm,
.rdalarm = stm32_rdalarm,
#endif
#ifdef CONFIG_RTC_PERIODIC
.setperiodic = stm32_setperiodic,
.cancelperiodic = stm32_cancelperiodic,
#endif
#ifdef CONFIG_RTC_IOCTL
.ioctl = NULL,
#endif
@ -149,7 +166,7 @@ static const struct rtc_ops_s g_rtc_ops =
static struct stm32_lowerhalf_s g_rtc_lowerhalf =
{
.ops = &g_rtc_ops,
.ops = &g_rtc_ops,
};
/****************************************************************************
@ -179,6 +196,7 @@ static void stm32_alarm_callback(FAR void *arg, unsigned int alarmid)
rtc_alarm_callback_t cb;
FAR void *priv;
DEBUGASSERT(arg != NULL);
DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB);
lower = (struct stm32_lowerhalf_s *)arg;
@ -223,42 +241,23 @@ static void stm32_alarm_callback(FAR void *arg, unsigned int alarmid)
static int stm32_rdtime(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_time *rtctime)
{
FAR struct stm32_lowerhalf_s *priv;
int ret;
priv = (FAR struct stm32_lowerhalf_s *)lower;
ret = nxsem_wait(&priv->devsem);
if (ret < 0)
{
return ret;
}
#if defined(CONFIG_RTC_DATETIME)
/* This operation depends on the fact that struct rtc_time is cast
* compatible with struct tm.
*/
return up_rtc_getdatetime((FAR struct tm *)rtctime);
#elif defined(CONFIG_RTC_HIRES)
FAR struct timespec ts;
int ret;
/* Get the higher resolution time */
ret = up_rtc_gettime(&ts);
if (ret < 0)
{
goto errout_with_errno;
}
/* Convert the one second epoch time to a struct tm. This operation
* depends on the fact that struct rtc_time and struct tm are cast
* compatible.
*/
if (!gmtime_r(&ts.tv_sec, (FAR struct tm *)rtctime))
{
goto errout_with_errno;
}
return OK;
errout_with_errno:
ret = get_errno();
DEBUGASSERT(ret > 0);
return -ret;
ret = up_rtc_getdatetime((FAR struct tm *)rtctime);
#else
time_t timer;
@ -272,11 +271,13 @@ errout_with_errno:
{
int errcode = get_errno();
DEBUGASSERT(errcode > 0);
nxsem_post(&priv->devsem);
return -errcode;
}
return OK;
#endif
nxsem_post(&priv->devsem);
return ret;
}
/****************************************************************************
@ -298,12 +299,23 @@ errout_with_errno:
static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
FAR const struct rtc_time *rtctime)
{
FAR struct stm32_lowerhalf_s *priv;
int ret;
priv = (FAR struct stm32_lowerhalf_s *)lower;
ret = nxsem_wait(&priv->devsem);
if (ret < 0)
{
return ret;
}
#ifdef CONFIG_RTC_DATETIME
/* This operation depends on the fact that struct rtc_time is cast
* compatible with struct tm.
*/
return stm32_rtc_setdatetime((FAR const struct tm *)rtctime);
ret = stm32_rtc_setdatetime((FAR const struct tm *)rtctime);
#else
struct timespec ts;
@ -317,8 +329,11 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
/* Now set the time (to one second accuracy) */
return up_rtc_settime(&ts);
ret = up_rtc_settime(&ts);
#endif
nxsem_post(&priv->devsem);
return ret;
}
/****************************************************************************
@ -337,7 +352,7 @@ static int stm32_settime(FAR struct rtc_lowerhalf_s *lower,
static bool stm32_havesettime(FAR struct rtc_lowerhalf_s *lower)
{
return getreg32(RTC_MAGIC_REG) == RTC_MAGIC_TIME_SET;
return stm32_rtc_havesettime();
}
/****************************************************************************
@ -364,7 +379,7 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
FAR struct stm32_lowerhalf_s *priv;
FAR struct stm32_cbinfo_s *cbinfo;
struct alm_setalarm_s lowerinfo;
int ret = -EINVAL;
int ret;
/* ID0-> Alarm A; ID1 -> Alarm B */
@ -372,6 +387,13 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
DEBUGASSERT(alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB);
priv = (FAR struct stm32_lowerhalf_s *)lower;
ret = nxsem_wait(&priv->devsem);
if (ret < 0)
{
return ret;
}
ret = -EINVAL;
if (alarminfo->id == RTC_ALARMA || alarminfo->id == RTC_ALARMB)
{
/* Remember the callback information */
@ -398,6 +420,8 @@ static int stm32_setalarm(FAR struct rtc_lowerhalf_s *lower,
}
}
nxsem_post(&priv->devsem);
return ret;
}
#endif
@ -483,7 +507,7 @@ static int stm32_setrelative(FAR struct rtc_lowerhalf_s *lower,
* method of the RTC driver interface
*
* Input Parameters:
* lower - A reference to RTC lower half driver state structure
* lower - A reference to RTC lower half driver state structure
* alarminfo - Provided information needed to set the alarm
*
* Returned Value:
@ -497,14 +521,21 @@ static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
{
FAR struct stm32_lowerhalf_s *priv;
FAR struct stm32_cbinfo_s *cbinfo;
int ret = -EINVAL;
int ret;
DEBUGASSERT(lower != NULL);
DEBUGASSERT(alarmid == RTC_ALARMA || alarmid == RTC_ALARMB);
priv = (FAR struct stm32_lowerhalf_s *)lower;
ret = nxsem_wait(&priv->devsem);
if (ret < 0)
{
return ret;
}
/* ID0-> Alarm A; ID1 -> Alarm B */
ret = -EINVAL;
if (alarmid == RTC_ALARMA || alarmid == RTC_ALARMB)
{
/* Nullify callback information to reduce window for race conditions */
@ -518,6 +549,8 @@ static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
ret = stm32_rtc_cancelalarm((enum alm_id_e)alarmid);
}
nxsem_post(&priv->devsem);
return ret;
}
#endif
@ -529,7 +562,7 @@ static int stm32_cancelalarm(FAR struct rtc_lowerhalf_s *lower, int alarmid)
* Query the RTC alarm.
*
* Input Parameters:
* lower - A reference to RTC lower half driver state structure
* lower - A reference to RTC lower half driver state structure
* alarminfo - Provided information needed to query the alarm
*
* Returned Value:
@ -568,6 +601,132 @@ static int stm32_rdalarm(FAR struct rtc_lowerhalf_s *lower,
}
#endif
/****************************************************************************
* Name: stm32_periodic_callback
*
* Description:
* This is the function that is called from the RTC driver when the
* periodic wakeup goes off. It just invokes the upper half driver's
* callback.
*
* Input Parameters:
* None
*
* Returned Value:
* None
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
static int stm32_periodic_callback(void)
{
FAR struct stm32_lowerhalf_s *lower;
struct lower_setperiodic_s *cbinfo;
rtc_wakeup_callback_t cb;
FAR void *priv;
lower = (FAR struct stm32_lowerhalf_s *)&g_rtc_lowerhalf;
cbinfo = &lower->periodic;
cb = (rtc_wakeup_callback_t)cbinfo->cb;
priv = (FAR void *)cbinfo->priv;
/* Perform the callback */
if (cb != NULL)
{
cb(priv, 0);
}
return OK;
}
#endif /* CONFIG_RTC_PERIODIC */
/****************************************************************************
* Name: stm32_setperiodic
*
* Description:
* Set a new periodic wakeup relative to the current time, with a given
* period. This function implements the setperiodic() 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 wakeup activity
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned
* on any failure.
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
static int stm32_setperiodic(FAR struct rtc_lowerhalf_s *lower,
FAR const struct lower_setperiodic_s *alarminfo)
{
FAR struct stm32_lowerhalf_s *priv;
int ret;
ASSERT(lower != NULL && alarminfo != NULL);
priv = (FAR struct stm32_lowerhalf_s *)lower;
ret = nxsem_wait(&priv->devsem);
if (ret < 0)
{
return ret;
}
memcpy(&priv->periodic, alarminfo, sizeof(struct lower_setperiodic_s));
ret = stm32_rtc_setperiodic(&alarminfo->period, stm32_periodic_callback);
nxsem_post(&priv->devsem);
return ret;
}
#endif
/****************************************************************************
* Name: stm32_cancelperiodic
*
* Description:
* Cancel the current periodic wakeup activity. This function implements
* the cancelperiodic() method of the RTC driver interface
*
* Input Parameters:
* lower - A reference to RTC lower half driver state structure
*
* Returned Value:
* Zero (OK) is returned on success; a negated errno value is returned
* on any failure.
*
****************************************************************************/
#ifdef CONFIG_RTC_PERIODIC
static int stm32_cancelperiodic(FAR struct rtc_lowerhalf_s *lower, int id)
{
FAR struct stm32_lowerhalf_s *priv;
int ret;
DEBUGASSERT(lower != NULL);
priv = (FAR struct stm32_lowerhalf_s *)lower;
DEBUGASSERT(id == 0);
ret = nxsem_wait(&priv->devsem);
if (ret < 0)
{
return ret;
}
ret = stm32_rtc_cancelperiodic();
nxsem_post(&priv->devsem);
return ret;
}
#endif
/****************************************************************************
* Public Functions
****************************************************************************/
@ -596,6 +755,8 @@ static int stm32_rdalarm(FAR struct rtc_lowerhalf_s *lower,
FAR struct rtc_lowerhalf_s *stm32_rtc_lowerhalf(void)
{
nxsem_init(&g_rtc_lowerhalf.devsem, 0, 1);
return (FAR struct rtc_lowerhalf_s *)&g_rtc_lowerhalf;
}

View File

@ -102,7 +102,7 @@ static int stm32l4_exti_wakeup_isr(int irq, void *context, FAR void *arg)
* Description:
* Sets/clears EXTI wakeup interrupt.
*
* Parameters:
* Input Parameters:
* - rising/falling edge: enables interrupt on rising/falling edges
* - event: generate event when set
* - func: when non-NULL, generate interrupt

View File

@ -74,17 +74,17 @@ uint8_t g_syslog_mask = LOG_ALL;
* is not modified." In this implementation, the value zero is permitted
* in order to disable all syslog levels.
*
* REVISIT: Per POSIX the syslog mask should be a per-process value but in
* NuttX, the scope of the mask is dependent on the nature of the build:
* REVISIT: Per POSIX the syslog mask should be a per-process value but in
* NuttX, the scope of the mask is dependent on the nature of the build:
*
* Flat Build: There is one, global SYSLOG mask that controls all output.
* Protected Build: There are two SYSLOG masks. One within the kernel
* that controls only kernel output. And one in user-space that controls
* only user SYSLOG output.
* Kernel Build: The kernel build is compliant with the POSIX requirement:
* There will be one mask for for each user process, controlling the
* SYSLOG output only form that process. There will be a separate mask
* accessable only in the kernel code to control kernel SYSLOG output.
* There will be one mask for each user process, controlling the SYSLOG
* output only form that process. There will be a separate mask
* accessible only in the kernel code to control kernel SYSLOG output.
*
****************************************************************************/