Skip to content

SSRU management #103

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,14 @@ by the RTC. Thus the getEpoch function is only to be called to get the subsecond
(returned time_t is not valid). The setAlarmEpoch only uses the sub-second [0..0xFFFFFFFF]
(time_t value is useless).

_SubSeconds underflow_

Only dor STM32WLxx. Manage interrupt (SSRU) when SubSeconds register
underflow. Used by STM32LoRaWAN.

* **`void attachSubSecondsUnderflowInterrupt(voidFuncPtr callback);`**
* **`void detachSubSecondsUnderflowInterrupt(void);`**

Refer to the Arduino RTC documentation for the other functions
http://arduino.cc/en/Reference/RTC

Expand Down
2 changes: 2 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ attachInterrupt KEYWORD2
detachInterrupt KEYWORD2
attachSecondsInterrupt KEYWORD2
detachSecondsInterrupt KEYWORD2
attachSubSecondsUnderflowInterrupt KEYWORD2
detachSubSecondsUnderflowInterrupt KEYWORD2

getClockSource KEYWORD2
setClockSource KEYWORD2
Expand Down
36 changes: 26 additions & 10 deletions src/STM32RTC.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,31 @@ void STM32RTC::detachSecondsInterrupt(void)
}

#endif /* ONESECOND_IRQn */

#ifdef STM32WLxx
/**
* @brief attach a callback to the RTC SubSeconds underflow interrupt.
* @note only for STM32WLxx
* @param callback: pointer to the callback
* @retval None
*/
void STM32RTC::attachSubSecondsUnderflowInterrupt(voidFuncPtr callback)
{
attachSubSecondsUnderflowIrqCallback(callback);
}

/**
* @brief detach the RTC SubSeconds underflow callback.
* @retval None
*/
void STM32RTC::detachSubSecondsUnderflowInterrupt(void)
{
detachSubSecondsUnderflowIrqCallback();
}

#endif /* STM32WLxx */


// Kept for compatibility. Use STM32LowPower library.
void STM32RTC::standbyMode(void)
{
Expand Down Expand Up @@ -851,16 +876,7 @@ void STM32RTC::setAlarmSubSeconds(uint32_t subSeconds, Alarm name)
#ifndef RTC_ALARM_B
UNUSED(name);
#endif
if (_mode == MODE_BIN) {
#ifdef RTC_ALARM_B
if (name == ALARM_B) {
_alarmBSubSeconds = subSeconds;
} else
#endif
{
_alarmSubSeconds = subSeconds;
}
} else if (subSeconds < 1000) {
if ((_mode == MODE_BIN) || (subSeconds < 1000)) {
#ifdef RTC_ALARM_B
if (name == ALARM_B) {
_alarmBSubSeconds = subSeconds;
Expand Down
5 changes: 5 additions & 0 deletions src/STM32RTC.h
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,11 @@ class STM32RTC {
void detachSecondsInterrupt(void);

#endif /* ONESECOND_IRQn */
#ifdef STM32WLxx
// STM32WLxx has a dedicated IRQ
void attachSubSecondsUnderflowInterrupt(voidFuncPtr callback);
void detachSubSecondsUnderflowInterrupt(void);
#endif /* STM32WLxx */
// Kept for compatibility: use STM32LowPower library.
void standbyMode();

Expand Down
114 changes: 64 additions & 50 deletions src/rtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,12 @@ static void *callbackUserData = NULL;
static voidCallbackPtr RTCUserCallbackB = NULL;
static void *callbackUserDataB = NULL;
#endif
#ifdef ONESECOND_IRQn
static voidCallbackPtr RTCSecondsIrqCallback = NULL;

#endif
#ifdef STM32WLxx
static voidCallbackPtr RTCSubSecondsUnderflowIrqCallback = NULL;
#endif
static sourceClock_t clkSrc = LSI_CLOCK;
static uint32_t clkVal = LSI_VALUE;
static uint8_t HSEDiv = 0;
Expand Down Expand Up @@ -97,55 +101,6 @@ static inline int _log2(int x)
}

/* Exported functions --------------------------------------------------------*/

/* HAL MSP function used for RTC_Init */
void HAL_RTC_MspInit(RTC_HandleTypeDef *rtcHandle)
{
#if defined(RTC_SCR_CSSRUF)
if (rtcHandle->Instance == RTC) {
/* In BINARY mode (MIX or ONLY), set the SSR Underflow interrupt */
if (rtcHandle->Init.BinMode != RTC_BINARY_NONE) {
#if defined(STM32WLxx)
/* Only the STM32WLxx series has a TAMP_STAMP_LSECSS_SSRU_IRQn */
if (HAL_RTCEx_SetSSRU_IT(rtcHandle) != HAL_OK) {
Error_Handler();
}
/* Give init value for the RtcFeatures enable */
rtcHandle->IsEnabled.RtcFeatures = 0;

/* RTC interrupt Init */
HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn);
#else
/* The STM32U5, STM32H5, STM32L4plus have common RTC interrupt and a SSRU flag */
__HAL_RTC_SSRU_ENABLE_IT(rtcHandle, RTC_IT_SSRU);
#endif /* STM32WLxx */
}
}
#else /* RTC_SCR_CSSRUF */
UNUSED(rtcHandle);
#endif /* RTC_SCR_CSSRUF */
/* RTC_Alarm_IRQn is enabled when enabling Alarm */
}

void HAL_RTC_MspDeInit(RTC_HandleTypeDef *rtcHandle)
{

if (rtcHandle->Instance == RTC) {
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
#ifdef __HAL_RCC_RTCAPB_CLK_DISABLE
__HAL_RCC_RTCAPB_CLK_DISABLE();
#endif
/* RTC interrupt Deinit */
#if defined(STM32WLxx)
/* Only the STM32WLxx series has a TAMP_STAMP_LSECSS_SSRU_IRQn */
HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn);
#endif /* STM32WLxx */
HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
}
}

/**
* @brief Get pointer to RTC_HandleTypeDef
* @param None
Expand Down Expand Up @@ -635,14 +590,31 @@ bool RTC_init(hourFormat_t format, binaryMode_t mode, sourceClock_t source, bool
void RTC_DeInit(bool reset_cb)
{
HAL_RTC_DeInit(&RtcHandle);
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
#ifdef __HAL_RCC_RTCAPB_CLK_DISABLE
__HAL_RCC_RTCAPB_CLK_DISABLE();
#endif
HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn);
#ifdef ONESECOND_IRQn
HAL_NVIC_DisableIRQ(ONESECOND_IRQn);
#endif
#ifdef STM32WLxx
HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn);
#endif
if (reset_cb) {
RTCUserCallback = NULL;
callbackUserData = NULL;
#ifdef RTC_ALARM_B
RTCUserCallbackB = NULL;
callbackUserDataB = NULL;
#endif
#ifdef ONESECOND_IRQn
RTCSecondsIrqCallback = NULL;
#endif
#ifdef STM32WLxx
RTCSubSecondsUnderflowIrqCallback = NULL;
#endif
}
}

Expand Down Expand Up @@ -1260,6 +1232,48 @@ void RTC_WKUP_IRQHandler(void)
#endif /* STM32F1xx */
#endif /* ONESECOND_IRQn */

#ifdef STM32WLxx
/**
* @brief Attach SubSeconds underflow interrupt callback.
* @param func: pointer to the callback
* @retval None
*/
void attachSubSecondsUnderflowIrqCallback(voidCallbackPtr func)
{
/* Callback called on SSRU interrupt */
RTCSubSecondsUnderflowIrqCallback = func;

/* Enable the IRQ that will trig the one-second interrupt */
if (HAL_RTCEx_SetSSRU_IT(&RtcHandle) != HAL_OK) {
Error_Handler();
}
HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, RTC_IRQ_SSRU_PRIO, RTC_IRQ_SSRU_SUBPRIO);
HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn);
}

/**
* @brief Detach SubSeconds underflow interrupt callback.
* @param None
* @retval None
*/
void detachSubSecondsUnderflowIrqCallback(void)
{
RTCSubSecondsUnderflowIrqCallback = NULL;
if (HAL_RTCEx_DeactivateSSRU(&RtcHandle) != HAL_OK) {
Error_Handler();
}
HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn);
}

void HAL_RTCEx_SSRUEventCallback(RTC_HandleTypeDef *hrtc)
{
(void)hrtc;
if (RTCSubSecondsUnderflowIrqCallback != NULL) {
RTCSubSecondsUnderflowIrqCallback(NULL);
}
}
#endif /* STM32WLxx */

#if defined(STM32F1xx)
void RTC_StoreDate(void)
{
Expand Down
13 changes: 10 additions & 3 deletions src/rtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,12 @@ typedef void(*voidCallbackPtr)(void *);
#ifndef RTC_IRQ_SUBPRIO
#define RTC_IRQ_SUBPRIO 0
#endif


#ifndef RTC_IRQ_SSRU_PRIO
#define RTC_IRQ_SSRU_PRIO 0
#endif
#ifndef RTC_IRQ_SSRU_SUBPRIO
#define RTC_IRQ_SSRU_SUBPRIO 0
#endif
#define HSE_RTC_MAX 1000000U

#if !defined(STM32F1xx)
Expand Down Expand Up @@ -198,7 +202,10 @@ void detachAlarmCallback(alarm_t name);
void attachSecondsIrqCallback(voidCallbackPtr func);
void detachSecondsIrqCallback(void);
#endif /* ONESECOND_IRQn */

#ifdef STM32WLxx
void attachSubSecondsUnderflowIrqCallback(voidCallbackPtr func);
void detachSubSecondsUnderflowIrqCallback(void);
#endif /* STM32WLxx */
#if defined(STM32F1xx)
void RTC_StoreDate(void);
#endif
Expand Down