diff --git a/.github/workflows/check-astyle.yml b/.github/workflows/check-astyle.yml index 25314bf..d58e214 100644 --- a/.github/workflows/check-astyle.yml +++ b/.github/workflows/check-astyle.yml @@ -13,6 +13,6 @@ jobs: steps: - run: sudo apt install astyle - uses: actions/checkout@v3 - - run: astyle --project=.astylerc --recursive '*.c' '*.h' '*.ino' + - run: astyle --project=.astylerc --recursive '*.c' '*.h' # If anything changed, this will fail and show the needed changes - run: git diff --exit-code diff --git a/docs/overview.md b/docs/overview.md index 0f1df2e..8c4db90 100644 --- a/docs/overview.md +++ b/docs/overview.md @@ -243,12 +243,8 @@ This library makes use of: - The radio module, obviously. The library handles enabling the module and the associated SPI block, so nothing is needed in the sketch. - - The RTC for timing. This library currently completely configures the - RTC and defines the interrupt handler, making it impossible to use - the RTC for anything else. In the future, this library could be - modified to co-exist with e.g. the STM32RTC library or use - a (low-power) timer instead of the RTC, but this is not possible - right now. + - The RTC for timing (Since v0.2.0). This library uses the + [STM32RTC library](https://github.com/stm32duino/STM32RTC). - A number of GPIO pins that are connected to external RF circuitry on the board. This just uses the Arduino `digitalWrite()` functions. diff --git a/examples/Basic/Basic.ino b/examples/Basic/Basic.ino index 4092116..1a5dbe2 100644 --- a/examples/Basic/Basic.ino +++ b/examples/Basic/Basic.ino @@ -2,6 +2,7 @@ * This is a very basic example that demonstrates how to configure the * library, join the network, send regular packets and print any * downlink packets received. + * This example is using the RTC in MIX (binary and BCD) mode * * Revised BSD License - https://spdx.org/licenses/BSD-3-Clause.html */ @@ -12,8 +13,10 @@ STM32LoRaWAN modem; static const unsigned long TX_INTERVAL = 60000; /* ms */ unsigned long last_tx = 0; -void setup() -{ +/* Get the rtc object */ +STM32RTC& rtc = STM32RTC::getInstance(); + +void setup() { Serial.begin(115200); Serial.println("Start"); modem.begin(EU868); @@ -27,17 +30,25 @@ void setup() Serial.println("Joined"); } else { Serial.println("Join failed"); - while (true) /* infinite loop */; + while (true) /* infinite loop */ + ; } + + /* set the calendar */ + rtc.setTime(15, 30, 58); + rtc.setDate(04, 07, 23); } -void send_packet() -{ - uint8_t payload[] = {0xde, 0xad, 0xbe, 0xef}; +void send_packet() { + char payload[27] = { 0 }; /* packet to be sent */ + /* prepare the Tx packet : get date and format string */ + sprintf(payload, "%02d/%02d/%04d - %02d:%02d:%02d", + rtc.getMonth(), rtc.getDay(), 2000 + rtc.getYear(), + rtc.getHours(), rtc.getMinutes(), rtc.getSeconds()); modem.setPort(10); modem.beginPacket(); - modem.write(payload, sizeof(payload)); - if (modem.endPacket() == sizeof(payload)) { + modem.write(payload, strlen(payload)); + if (modem.endPacket() == (int)strlen(payload)) { Serial.println("Sent packet"); } else { Serial.println("Failed to send packet"); @@ -57,8 +68,7 @@ void send_packet() } } -void loop() -{ +void loop() { if (!last_tx || millis() - last_tx > TX_INTERVAL) { send_packet(); last_tx = millis(); diff --git a/examples/ScheduledAsync/ScheduledAsync.ino b/examples/ScheduledAsync/ScheduledAsync.ino index a2347e1..d215eef 100644 --- a/examples/ScheduledAsync/ScheduledAsync.ino +++ b/examples/ScheduledAsync/ScheduledAsync.ino @@ -72,8 +72,8 @@ void do_blink() } /********************************************************************* - * This part of the sketch defines the lora work task, which iniates new - * work and the lora_done() function that processes the results. + * This part of the sketch defines the lora work task, which initiates + * new work and the lora_done() function that processes the results. *********************************************************************/ static const unsigned long TX_INTERVAL = 60000; /* ms */ diff --git a/library.properties b/library.properties index 5e99252..5d2668b 100644 --- a/library.properties +++ b/library.properties @@ -7,3 +7,4 @@ paragraph=Provides APIs to communicate with LoRa® and LoraWAN® networks category=Communication url=https://github.com/stm32duino/STM32LoRaWAN architectures=stm32 +depends=STM32duino RTC diff --git a/src/BSP/main.h b/src/BSP/main.h deleted file mode 100644 index cdf7dd0..0000000 --- a/src/BSP/main.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -/** - ****************************************************************************** - * @file main.h - * @author Matthijs Kooijman - * @brief Header to supply RTC settings for timer_if.c and rtc.c. - * - * Originally supplied other things as well, but to allow using other - * files without changes, the filename (which is no longer really - * appropriate) is kept as-is. - * - ****************************************************************************** - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * Revised BSD License - https://spdx.org/licenses/BSD-3-Clause.html - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the copyright holder nor the names of its - * contributors may be used to endorse or promote products derived from this - * software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Includes ------------------------------------------------------------------*/ -#include - -/* Private defines -----------------------------------------------------------*/ -#define RTC_N_PREDIV_S 10 -#define RTC_PREDIV_S ((1<Instance==RTC) - { - /* USER CODE BEGIN RTC_MspInit 0 */ - - /* USER CODE END RTC_MspInit 0 */ - - /** Initializes the peripherals clocks - */ - PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_RTC; - PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE; - - if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) - { - Error_Handler(); - } - - /* RTC clock enable */ - __HAL_RCC_RTC_ENABLE(); - __HAL_RCC_RTCAPB_CLK_ENABLE(); - - /* RTC interrupt Init */ - HAL_NVIC_SetPriority(TAMP_STAMP_LSECSS_SSRU_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); - HAL_NVIC_SetPriority(RTC_Alarm_IRQn, 0, 0); - HAL_NVIC_EnableIRQ(RTC_Alarm_IRQn); - /* USER CODE BEGIN RTC_MspInit 1 */ - - /* USER CODE END RTC_MspInit 1 */ - } -} - -void HAL_RTC_MspDeInit(RTC_HandleTypeDef* rtcHandle) -{ - - if(rtcHandle->Instance==RTC) - { - /* USER CODE BEGIN RTC_MspDeInit 0 */ - - /* USER CODE END RTC_MspDeInit 0 */ - /* Peripheral clock disable */ - __HAL_RCC_RTC_DISABLE(); - __HAL_RCC_RTCAPB_CLK_DISABLE(); - - /* RTC interrupt Deinit */ - HAL_NVIC_DisableIRQ(TAMP_STAMP_LSECSS_SSRU_IRQn); - HAL_NVIC_DisableIRQ(RTC_Alarm_IRQn); - /* USER CODE BEGIN RTC_MspDeInit 1 */ - - /* USER CODE END RTC_MspDeInit 1 */ - } -} - -void RTC_Alarm_IRQHandler(void) -{ - /* USER CODE BEGIN RTC_Alarm_IRQn 0 */ - - /* USER CODE END RTC_Alarm_IRQn 0 */ - HAL_RTC_AlarmIRQHandler(&hrtc); - /* USER CODE BEGIN RTC_Alarm_IRQn 1 */ - - /* USER CODE END RTC_Alarm_IRQn 1 */ -} - -/* USER CODE BEGIN 1 */ - -/* USER CODE END 1 */ diff --git a/src/BSP/rtc.h b/src/BSP/rtc.h deleted file mode 100644 index a3c5be7..0000000 --- a/src/BSP/rtc.h +++ /dev/null @@ -1,53 +0,0 @@ -/* USER CODE BEGIN Header */ -/** - ****************************************************************************** - * @file rtc.h - * @brief This file contains all the function prototypes for - * the rtc.c file - ****************************************************************************** - * @attention - * - * Copyright (c) 2022 STMicroelectronics. - * All rights reserved. - * - * This software component is licensed by ST under BSD 3-Clause license, - * the "License"; You may not use this file except in compliance with the - * License. You may obtain a copy of the License at: - * opensource.org/licenses/BSD-3-Clause - * - ****************************************************************************** - */ -/* USER CODE END Header */ -/* Define to prevent recursive inclusion -------------------------------------*/ -#ifndef __RTC_H__ -#define __RTC_H__ - -#ifdef __cplusplus -extern "C" { -#endif - -/* Includes ------------------------------------------------------------------*/ -#include "main.h" - -/* USER CODE BEGIN Includes */ - -/* USER CODE END Includes */ - -extern RTC_HandleTypeDef hrtc; - -/* USER CODE BEGIN Private defines */ - -/* USER CODE END Private defines */ - -void MX_RTC_Init(void); - -/* USER CODE BEGIN Prototypes */ - -/* USER CODE END Prototypes */ - -#ifdef __cplusplus -} -#endif - -#endif /* __RTC_H__ */ - diff --git a/src/BSP/timer_if.c b/src/BSP/timer_if.c index e3497ea..d364fe1 100644 --- a/src/BSP/timer_if.c +++ b/src/BSP/timer_if.c @@ -3,7 +3,7 @@ ****************************************************************************** * @file timer_if.c * @author MCD Application Team - * @brief Configure RTC Alarm, Tick and Calendar manager + * @brief Configure RTC Alarm (B), Tick and Calendar manager ****************************************************************************** * @attention * @@ -22,11 +22,9 @@ /* Includes ------------------------------------------------------------------*/ #include #include "timer_if.h" -#include "main.h" /*for STM32CubeMX generated RTC_N_PREDIV_S and RTC_N_PREDIV_A*/ #include "rtc.h" // #include "stm32_lpm.h" // #include "utilities_def.h" -#include "stm32wlxx_ll_rtc.h" /* USER CODE BEGIN Includes */ @@ -36,7 +34,7 @@ /** * @brief RTC handle */ -extern RTC_HandleTypeDef hrtc; +static RTC_HandleTypeDef *hrtc = NULL; /** * @brief Timer driver callbacks handler @@ -111,9 +109,16 @@ const UTIL_SYSTIM_Driver_s UTIL_SYSTIMDriver = #define UTIL_TIMER_IRQ_MAP_INIT() #endif /* UTIL_TIMER_IRQ_MAP_INIT */ -#ifndef UTIL_TIMER_IRQ_MAP_PROCESS -#define UTIL_TIMER_IRQ_MAP_PROCESS() UTIL_TIMER_IRQ_Handler() -#endif /* UTIL_TIMER_IRQ_MAP_PROCESS */ +/* + * With RTC (RtcHandle.Instance) clocked by LSE, the APRE freq is 256Hz (default) + * (1 tick is 3.9ms (when APREDIV = 0x7F) + * for other RTC clock freq, the formula is ck_apre = RTC_clock / (prediv_A +1) + */ +#define MS_TO_TICK \ + (uint32_t)(LL_RCC_GetRTCClockFreq() / (LL_RTC_GetAsynchPrescaler(hrtc->Instance) + 1)) + +/* Give one more (to adjust to x3.9 factor) */ +#define TICK_TO_MS ((1000/MS_TO_TICK) + 1) /* USER CODE BEGIN PD */ @@ -177,29 +182,29 @@ static uint32_t TIMER_IF_BkUp_Read_MSBticks(void); /* USER CODE BEGIN PFP */ +/* Function to attach to the RTC IRQ as a callback */ +WEAK void UTIL_TIMER_IRQ_MAP_PROCESS(void *data) +{ + UNUSED(data); + + UTIL_TIMER_IRQ_Handler(); +} + /* USER CODE END PFP */ /* Exported functions ---------------------------------------------------------*/ -UTIL_TIMER_Status_t TIMER_IF_Init(void) +UTIL_TIMER_Status_t TIMER_IF_Init(RTC_HandleTypeDef *RtcHandle) { UTIL_TIMER_Status_t ret = UTIL_TIMER_OK; + hrtc = RtcHandle; /* USER CODE BEGIN TIMER_IF_Init */ /* USER CODE END TIMER_IF_Init */ if (RTC_Initialized == false) { - hrtc.IsEnabled.RtcFeatures = UINT32_MAX; - /*Init RTC*/ - MX_RTC_Init(); - /*Stop Timer */ - TIMER_IF_StopTimer(); - /** DeActivate the Alarm A enabled by STM32CubeMX during MX_RTC_Init() */ - HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A); - /*overload RTC feature enable*/ - hrtc.IsEnabled.RtcFeatures = UINT32_MAX; - - /*Enable Direct Read of the calendar registers (not through Shadow) */ - HAL_RTCEx_EnableBypassShadow(&hrtc); + /*Stop Timer : Disable the Alarm B interrupt */ + RTC_StopAlarm(RTC_ALARM_B); + /*Initialize MSB ticks*/ TIMER_IF_BkUp_Write_MSBticks(0); @@ -223,22 +228,17 @@ UTIL_TIMER_Status_t TIMER_IF_StartTimer(uint32_t timeout) /* USER CODE BEGIN TIMER_IF_StartTimer */ /* USER CODE END TIMER_IF_StartTimer */ - RTC_AlarmTypeDef sAlarm = {0}; + /*Stop timer if one is already started*/ - TIMER_IF_StopTimer(); + RTC_StopAlarm(RTC_ALARM_B); + timeout += RtcTimerContext; - TIMER_IF_DBG_PRINTF("Start timer: time=%d, alarm=%d\n\r", GetTimerTicks(), timeout); - /* starts timer*/ - sAlarm.BinaryAutoClr = RTC_ALARMSUBSECONDBIN_AUTOCLR_NO; - sAlarm.AlarmTime.SubSeconds = UINT32_MAX - timeout; - sAlarm.AlarmMask = RTC_ALARMMASK_NONE; - sAlarm.AlarmSubSecondMask = RTC_ALARMSUBSECONDBINMASK_NONE; - sAlarm.Alarm = RTC_ALARM_A; - if (HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, RTC_FORMAT_BCD) != HAL_OK) - { - Error_Handler(); - } + TIMER_IF_DBG_PRINTF("Start timer: time=%d, alarm=%d\n\r", GetTimerTicks(), timeout); + + /* Program ALARM B on timeout ticks converted in ms (one more for uncertainty, mask is 31 */ + RTC_StartAlarm(RTC_ALARM_B, 0, 0, 0, 0, (timeout * 1000 / MS_TO_TICK + 1), RTC_HOURFORMAT12_PM, 31UL); + /* USER CODE BEGIN TIMER_IF_StartTimer_Last */ /* USER CODE END TIMER_IF_StartTimer_Last */ @@ -251,12 +251,10 @@ UTIL_TIMER_Status_t TIMER_IF_StopTimer(void) /* USER CODE BEGIN TIMER_IF_StopTimer */ /* USER CODE END TIMER_IF_StopTimer */ - /* Clear RTC Alarm Flag */ - __HAL_RTC_ALARM_CLEAR_FLAG(&hrtc, RTC_FLAG_ALRAF); - /* Disable the Alarm A interrupt */ - HAL_RTC_DeactivateAlarm(&hrtc, RTC_ALARM_A); - /*overload RTC feature enable*/ - hrtc.IsEnabled.RtcFeatures = UINT32_MAX; + + /* Disable the Alarm B interrupt */ + RTC_StopAlarm(RTC_ALARM_B); + /* USER CODE BEGIN TIMER_IF_StopTimer_Last */ /* USER CODE END TIMER_IF_StopTimer_Last */ @@ -336,7 +334,7 @@ uint32_t TIMER_IF_Convert_ms2Tick(uint32_t timeMilliSec) /* USER CODE BEGIN TIMER_IF_Convert_ms2Tick */ /* USER CODE END TIMER_IF_Convert_ms2Tick */ - ret = ((uint32_t)((((uint64_t) timeMilliSec) << RTC_N_PREDIV_S) / 1000)); + ret = ((uint32_t)(((uint64_t)timeMilliSec * MS_TO_TICK) / 1000)); /* USER CODE BEGIN TIMER_IF_Convert_ms2Tick_Last */ /* USER CODE END TIMER_IF_Convert_ms2Tick_Last */ @@ -349,7 +347,7 @@ uint32_t TIMER_IF_Convert_Tick2ms(uint32_t tick) /* USER CODE BEGIN TIMER_IF_Convert_Tick2ms */ /* USER CODE END TIMER_IF_Convert_Tick2ms */ - ret = ((uint32_t)((((uint64_t)(tick)) * 1000) >> RTC_N_PREDIV_S)); + ret = tick * TICK_TO_MS; /* USER CODE BEGIN TIMER_IF_Convert_Tick2ms_Last */ /* USER CODE END TIMER_IF_Convert_Tick2ms_Last */ @@ -374,35 +372,17 @@ void TIMER_IF_DelayMs(uint32_t delay) /* USER CODE END TIMER_IF_DelayMs_Last */ } -void HAL_RTC_AlarmAEventCallback(RTC_HandleTypeDef *hrtc) -{ - (void)hrtc; // unused - /* USER CODE BEGIN HAL_RTC_AlarmAEventCallback */ - - /* USER CODE END HAL_RTC_AlarmAEventCallback */ - UTIL_TIMER_IRQ_MAP_PROCESS(); - /* USER CODE BEGIN HAL_RTC_AlarmAEventCallback_Last */ - - /* USER CODE END HAL_RTC_AlarmAEventCallback_Last */ -} - -void HAL_RTCEx_SSRUEventCallback(RTC_HandleTypeDef *hrtc) +WEAK void TIMER_IF_SSRUCallback(void *data) { - (void)hrtc; // unused - /* USER CODE BEGIN HAL_RTCEx_SSRUEventCallback */ - - /* USER CODE END HAL_RTCEx_SSRUEventCallback */ - /*called every 48 days with 1024 ticks per seconds*/ + (void)data; + /* called every 48 days with 1024 ticks per seconds */ TIMER_IF_DBG_PRINTF(">>Handler SSRUnderflow at %d\n\r", GetTimerTicks()); - /*Increment MSBticks*/ + /* Increment MSBticks */ uint32_t MSB_ticks = TIMER_IF_BkUp_Read_MSBticks(); TIMER_IF_BkUp_Write_MSBticks(MSB_ticks + 1); - /* USER CODE BEGIN HAL_RTCEx_SSRUEventCallback_Last */ - - /* USER CODE END HAL_RTCEx_SSRUEventCallback_Last */ } -uint32_t TIMER_IF_GetTime(uint16_t *mSeconds) +uint32_t TIMER_IF_GetTime(uint32_t *mSeconds) { uint32_t seconds = 0; /* USER CODE BEGIN TIMER_IF_GetTime */ @@ -414,12 +394,8 @@ uint32_t TIMER_IF_GetTime(uint16_t *mSeconds) ticks = (((uint64_t) timerValueMSB) << 32) + timerValueLsb; - seconds = (uint32_t)(ticks >> RTC_N_PREDIV_S); - - ticks = (uint32_t) ticks & RTC_PREDIV_S; - - *mSeconds = TIMER_IF_Convert_Tick2ms(ticks); - + seconds = ticks / MS_TO_TICK; + *mSeconds = (ticks * 1000) / MS_TO_TICK; /* USER CODE BEGIN TIMER_IF_GetTime_Last */ /* USER CODE END TIMER_IF_GetTime_Last */ @@ -431,7 +407,7 @@ void TIMER_IF_BkUp_Write_Seconds(uint32_t Seconds) /* USER CODE BEGIN TIMER_IF_BkUp_Write_Seconds */ /* USER CODE END TIMER_IF_BkUp_Write_Seconds */ - HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_SECONDS, Seconds); + HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_SECONDS, Seconds); /* USER CODE BEGIN TIMER_IF_BkUp_Write_Seconds_Last */ /* USER CODE END TIMER_IF_BkUp_Write_Seconds_Last */ @@ -442,7 +418,7 @@ void TIMER_IF_BkUp_Write_SubSeconds(uint32_t SubSeconds) /* USER CODE BEGIN TIMER_IF_BkUp_Write_SubSeconds */ /* USER CODE END TIMER_IF_BkUp_Write_SubSeconds */ - HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_SUBSECONDS, SubSeconds); + HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_SUBSECONDS, SubSeconds); /* USER CODE BEGIN TIMER_IF_BkUp_Write_SubSeconds_Last */ /* USER CODE END TIMER_IF_BkUp_Write_SubSeconds_Last */ @@ -454,7 +430,7 @@ uint32_t TIMER_IF_BkUp_Read_Seconds(void) /* USER CODE BEGIN TIMER_IF_BkUp_Read_Seconds */ /* USER CODE END TIMER_IF_BkUp_Read_Seconds */ - ret = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_SECONDS); + ret = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_SECONDS); /* USER CODE BEGIN TIMER_IF_BkUp_Read_Seconds_Last */ /* USER CODE END TIMER_IF_BkUp_Read_Seconds_Last */ @@ -467,7 +443,7 @@ uint32_t TIMER_IF_BkUp_Read_SubSeconds(void) /* USER CODE BEGIN TIMER_IF_BkUp_Read_SubSeconds */ /* USER CODE END TIMER_IF_BkUp_Read_SubSeconds */ - ret = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_SUBSECONDS); + ret = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_SUBSECONDS); /* USER CODE BEGIN TIMER_IF_BkUp_Read_SubSeconds_Last */ /* USER CODE END TIMER_IF_BkUp_Read_SubSeconds_Last */ @@ -484,7 +460,7 @@ static void TIMER_IF_BkUp_Write_MSBticks(uint32_t MSBticks) /* USER CODE BEGIN TIMER_IF_BkUp_Write_MSBticks */ /* USER CODE END TIMER_IF_BkUp_Write_MSBticks */ - HAL_RTCEx_BKUPWrite(&hrtc, RTC_BKP_MSBTICKS, MSBticks); + HAL_RTCEx_BKUPWrite(hrtc, RTC_BKP_MSBTICKS, MSBticks); /* USER CODE BEGIN TIMER_IF_BkUp_Write_MSBticks_Last */ /* USER CODE END TIMER_IF_BkUp_Write_MSBticks_Last */ @@ -496,7 +472,7 @@ static uint32_t TIMER_IF_BkUp_Read_MSBticks(void) /* USER CODE END TIMER_IF_BkUp_Read_MSBticks */ uint32_t MSBticks; - MSBticks = HAL_RTCEx_BKUPRead(&hrtc, RTC_BKP_MSBTICKS); + MSBticks = HAL_RTCEx_BKUPRead(hrtc, RTC_BKP_MSBTICKS); return MSBticks; /* USER CODE BEGIN TIMER_IF_BkUp_Read_MSBticks_Last */ @@ -508,11 +484,11 @@ static inline uint32_t GetTimerTicks(void) /* USER CODE BEGIN GetTimerTicks */ /* USER CODE END GetTimerTicks */ - uint32_t ssr = LL_RTC_TIME_GetSubSecond(RTC); + uint32_t ssr = LL_RTC_TIME_GetSubSecond(hrtc->Instance); /* read twice to make sure value it valid*/ - while (ssr != LL_RTC_TIME_GetSubSecond(RTC)) + while (ssr != LL_RTC_TIME_GetSubSecond(hrtc->Instance)) { - ssr = LL_RTC_TIME_GetSubSecond(RTC); + ssr = LL_RTC_TIME_GetSubSecond(hrtc->Instance); } return UINT32_MAX - ssr; /* USER CODE BEGIN GetTimerTicks_Last */ diff --git a/src/BSP/timer_if.h b/src/BSP/timer_if.h index a60ed36..b6de6a0 100644 --- a/src/BSP/timer_if.h +++ b/src/BSP/timer_if.h @@ -33,11 +33,14 @@ extern "C" { /* USER CODE BEGIN Includes */ +void UTIL_TIMER_IRQ_MAP_PROCESS(void *data); + /* USER CODE END Includes */ /* Exported types ------------------------------------------------------------*/ /* USER CODE BEGIN ET */ + /* USER CODE END ET */ /* Exported constants --------------------------------------------------------*/ @@ -58,9 +61,10 @@ extern "C" { /* Exported functions prototypes ---------------------------------------------*/ /** * @brief Init RTC hardware + * @param RtcHandle RTC_HandleTypeDef * @return Status based on @ref UTIL_TIMER_Status_t */ -UTIL_TIMER_Status_t TIMER_IF_Init(void); +UTIL_TIMER_Status_t TIMER_IF_Init(RTC_HandleTypeDef *RtcHandle); /** * @brief Set the alarm @@ -126,12 +130,18 @@ uint32_t TIMER_IF_Convert_ms2Tick(uint32_t timeMilliSec); */ uint32_t TIMER_IF_Convert_Tick2ms(uint32_t tick); +/** + * @brief rtc SSRU Event Callback + * @param[in] data not used + */ +void TIMER_IF_SSRUCallback(void *data); + /** * @brief Get rtc time * @param[out] subSeconds in ticks * @return time seconds */ -uint32_t TIMER_IF_GetTime(uint16_t *subSeconds); +uint32_t TIMER_IF_GetTime(uint32_t *subSeconds); /** * @brief write seconds in backUp register diff --git a/src/STM32CubeWL/Utilities/misc/stm32_systime.c b/src/STM32CubeWL/Utilities/misc/stm32_systime.c index 4a7a1e5..0f2b5d0 100644 --- a/src/STM32CubeWL/Utilities/misc/stm32_systime.c +++ b/src/STM32CubeWL/Utilities/misc/stm32_systime.c @@ -233,7 +233,7 @@ void SysTimeSet( SysTime_t sysTime ) SysTime_t calendarTime = { .Seconds = 0, .SubSeconds = 0 }; - calendarTime.Seconds = UTIL_SYSTIMDriver.GetCalendarTime( ( uint16_t* )&calendarTime.SubSeconds ); + calendarTime.Seconds = UTIL_SYSTIMDriver.GetCalendarTime( ( uint32_t* )&calendarTime.SubSeconds ); // sysTime is UNIX epoch DeltaTime = SysTimeSub( sysTime, calendarTime ); @@ -248,9 +248,9 @@ SysTime_t SysTimeGet( void ) SysTime_t sysTime = { .Seconds = 0, .SubSeconds = 0 }; SysTime_t DeltaTime; - calendarTime.Seconds = UTIL_SYSTIMDriver.GetCalendarTime( ( uint16_t* )&calendarTime.SubSeconds ); + calendarTime.Seconds = UTIL_SYSTIMDriver.GetCalendarTime( ( uint32_t* )&calendarTime.SubSeconds ); - DeltaTime.SubSeconds = (int16_t)UTIL_SYSTIMDriver.BKUPRead_SubSeconds(); + DeltaTime.SubSeconds = (int32_t)UTIL_SYSTIMDriver.BKUPRead_SubSeconds(); DeltaTime.Seconds = UTIL_SYSTIMDriver.BKUPRead_Seconds(); sysTime = SysTimeAdd( DeltaTime, calendarTime ); @@ -263,7 +263,7 @@ SysTime_t SysTimeGetMcuTime( void ) { SysTime_t calendarTime = { .Seconds = 0, .SubSeconds = 0 }; - calendarTime.Seconds = UTIL_SYSTIMDriver.GetCalendarTime( ( uint16_t* )&calendarTime.SubSeconds ); + calendarTime.Seconds = UTIL_SYSTIMDriver.GetCalendarTime( ( uint32_t* )&calendarTime.SubSeconds ); return calendarTime; } @@ -284,7 +284,7 @@ SysTime_t SysTimeFromMs( uint32_t timeMs ) SysTime_t sysTime = { .Seconds = seconds, .SubSeconds = timeMs - seconds * 1000 }; SysTime_t DeltaTime = { 0 }; - DeltaTime.SubSeconds = (int16_t)UTIL_SYSTIMDriver.BKUPRead_SubSeconds(); + DeltaTime.SubSeconds = (int32_t)UTIL_SYSTIMDriver.BKUPRead_SubSeconds(); DeltaTime.Seconds = UTIL_SYSTIMDriver.BKUPRead_Seconds(); return SysTimeAdd( sysTime, DeltaTime ); } diff --git a/src/STM32CubeWL/Utilities/misc/stm32_systime.h b/src/STM32CubeWL/Utilities/misc/stm32_systime.h index 5e219d3..78b033f 100644 --- a/src/STM32CubeWL/Utilities/misc/stm32_systime.h +++ b/src/STM32CubeWL/Utilities/misc/stm32_systime.h @@ -133,7 +133,7 @@ typedef struct uint32_t (*BKUPRead_Seconds) ( void ); /*!< Get the timer differencebetween real time and rtc time */ void (*BKUPWrite_SubSeconds) ( uint32_t SubSeconds); /*!< Set the timer differencebetween real time and rtc time */ uint32_t (*BKUPRead_SubSeconds) ( void ); /*!< Get the timer differencebetween real time and rtc time */ - uint32_t (*GetCalendarTime)( uint16_t* SubSeconds ); /*!< Set the rtc time */ + uint32_t (*GetCalendarTime)( uint32_t* SubSeconds ); /*!< Set the rtc time */ } UTIL_SYSTIM_Driver_s; /** diff --git a/src/STM32CubeWL/Utilities/timer/stm32_timer.c b/src/STM32CubeWL/Utilities/timer/stm32_timer.c index d924e39..01fbcd8 100644 --- a/src/STM32CubeWL/Utilities/timer/stm32_timer.c +++ b/src/STM32CubeWL/Utilities/timer/stm32_timer.c @@ -116,11 +116,11 @@ bool TimerExists( UTIL_TIMER_Object_t *TimerObject ); * @{ */ -UTIL_TIMER_Status_t UTIL_TIMER_Init(void) +UTIL_TIMER_Status_t UTIL_TIMER_Init(RTC_HandleTypeDef *RtcHandle) { UTIL_TIMER_INIT_CRITICAL_SECTION(); TimerListHead = NULL; - return UTIL_TimerDriver.InitTimer(); + return UTIL_TimerDriver.InitTimer(RtcHandle); } UTIL_TIMER_Status_t UTIL_TIMER_DeInit(void) diff --git a/src/STM32CubeWL/Utilities/timer/stm32_timer.h b/src/STM32CubeWL/Utilities/timer/stm32_timer.h index d18e935..0b17fad 100644 --- a/src/STM32CubeWL/Utilities/timer/stm32_timer.h +++ b/src/STM32CubeWL/Utilities/timer/stm32_timer.h @@ -57,7 +57,8 @@ #include #include #include "../../../BSP/utilities_conf.h" - +#include "rtc.h" + /* Exported types ------------------------------------------------------------*/ /** @defgroup TIMER_SERVER_exported_TypeDef TIMER_SERVER exported Typedef * @{ @@ -103,7 +104,7 @@ typedef struct TimerEvent_s */ typedef struct { - UTIL_TIMER_Status_t (* InitTimer )( void ); /*!< Initialisation of the low layer timer */ + UTIL_TIMER_Status_t (* InitTimer )( RTC_HandleTypeDef * ); /*!< Initialisation of the low layer timer */ UTIL_TIMER_Status_t (* DeInitTimer )( void ); /*!< Un-Initialisation of the low layer timer */ UTIL_TIMER_Status_t (* StartTimerEvt )( uint32_t timeout ); /*!< Start the low layer timer */ @@ -156,9 +157,10 @@ extern const UTIL_TIMER_Driver_s UTIL_TimerDriver; /** * @brief Initialize the timer server * + * @param RtcHandle RTC_HandleTypeDef * @retval Status based on @ref UTIL_TIMER_Status_t */ -UTIL_TIMER_Status_t UTIL_TIMER_Init(void); +UTIL_TIMER_Status_t UTIL_TIMER_Init(RTC_HandleTypeDef *RtcHandle); /** * @brief Un-Initialize the timer server diff --git a/src/STM32LoRaWAN.cpp b/src/STM32LoRaWAN.cpp index ecf506a..83b408e 100644 --- a/src/STM32LoRaWAN.cpp +++ b/src/STM32LoRaWAN.cpp @@ -54,6 +54,9 @@ #error "Unexpected txpower constants" #endif +/* Get the RTC object for init */ +STM32RTC& _rtc = STM32RTC::getInstance(); + STM32LoRaWAN* STM32LoRaWAN::instance; bool STM32LoRaWAN::begin(_lora_band band) @@ -62,7 +65,20 @@ bool STM32LoRaWAN::begin(_lora_band band) return failure("Only one STM32LoRaWAN instance can be used"); instance = this; - UTIL_TIMER_Init(); + /* + * Init RTC as an object : + * use the MIX mode = free running BCD calendar + binary mode for + * the sub-second counter RTC_SSR on 32 bit + */ + _rtc.setClockSource(STM32RTC::LSE_CLOCK); + _rtc.setBinaryMode(STM32RTC::MODE_MIX); + _rtc.begin(true, STM32RTC::HOUR_24); + /* Attach the callback function before enabling Interrupt */ + _rtc.attachInterrupt(UTIL_TIMER_IRQ_MAP_PROCESS, STM32RTC::ALARM_B); + _rtc.attachSecondsInterrupt(TIMER_IF_SSRUCallback); + /* The subsecond alarm B is set during the StartTimerEvent */ + + UTIL_TIMER_Init(_rtc.getHandle()); LoRaMacStatus_t res = LoRaMacInitialization(&LoRaMacPrimitives, &LoRaMacCallbacks, (LoRaMacRegion_t)band); if (res != LORAMAC_STATUS_OK) { diff --git a/src/STM32LoRaWAN.h b/src/STM32LoRaWAN.h index 2db73a5..30408dc 100644 --- a/src/STM32LoRaWAN.h +++ b/src/STM32LoRaWAN.h @@ -41,8 +41,9 @@ #include "Arduino.h" #include "STM32CubeWL/LoRaWAN/Mac/LoRaMac.h" -#include "STM32CubeWL/Utilities/timer/stm32_timer.h" #include "BSP/mw_log_conf.h" +#include "BSP/timer_if.h" +#include "STM32RTC.h" /**