From d4ebb76c16c1271f628f57eff702149f135e5adc Mon Sep 17 00:00:00 2001 From: SPRESENSE <41312067+SPRESENSE@users.noreply.github.com> Date: Thu, 30 Jun 2022 09:13:42 +0900 Subject: [PATCH] examples/eltres_lpwa: Import LPWA_sample_app Import LPWA_sample_app version 3.0.3. --- examples/eltres_lpwa/LPWA_sample_app.ioc | 250 ++++ examples/eltres_lpwa/LPWA_sample_app.patch | 91 ++ .../Sample_App_version_information.txt | 19 + examples/eltres_lpwa/main_LPWA_sample_app.c | 1332 +++++++++++++++++ examples/eltres_lpwa/main_LPWA_sample_app.h | 49 + 5 files changed, 1741 insertions(+) create mode 100644 examples/eltres_lpwa/LPWA_sample_app.ioc create mode 100644 examples/eltres_lpwa/LPWA_sample_app.patch create mode 100644 examples/eltres_lpwa/Sample_App_version_information.txt create mode 100644 examples/eltres_lpwa/main_LPWA_sample_app.c create mode 100644 examples/eltres_lpwa/main_LPWA_sample_app.h diff --git a/examples/eltres_lpwa/LPWA_sample_app.ioc b/examples/eltres_lpwa/LPWA_sample_app.ioc new file mode 100644 index 000000000..ea406b977 --- /dev/null +++ b/examples/eltres_lpwa/LPWA_sample_app.ioc @@ -0,0 +1,250 @@ +#MicroXplorer Configuration settings - do not modify +File.Version=6 +KeepUserPlacement=false +Mcu.Family=STM32L0 +Mcu.IP0=NVIC +Mcu.IP1=RCC +Mcu.IP2=RTC +Mcu.IP3=SYS +Mcu.IP4=USART1 +Mcu.IP5=USART2 +Mcu.IPNb=6 +Mcu.Name=STM32L073R(B-Z)Tx +Mcu.Package=LQFP64 +Mcu.Pin0=PC13 +Mcu.Pin1=PC14-OSC32_IN +Mcu.Pin10=PA4 +Mcu.Pin11=PA5 +Mcu.Pin12=PA6 +Mcu.Pin13=PA7 +Mcu.Pin14=PB0 +Mcu.Pin15=PB10 +Mcu.Pin16=PC7 +Mcu.Pin17=PA9 +Mcu.Pin18=PA10 +Mcu.Pin19=PA13 +Mcu.Pin2=PC15-OSC32_OUT +Mcu.Pin20=PA14 +Mcu.Pin21=PB3 +Mcu.Pin22=PB4 +Mcu.Pin23=PB5 +Mcu.Pin24=PB6 +Mcu.Pin25=PB8 +Mcu.Pin26=PB9 +Mcu.Pin27=VP_RTC_VS_RTC_Activate +Mcu.Pin28=VP_RTC_VS_RTC_Calendar +Mcu.Pin29=VP_RTC_VS_RTC_Alarm_A_Intern +Mcu.Pin3=PH0-OSC_IN +Mcu.Pin30=VP_SYS_VS_Systick +Mcu.Pin4=PC0 +Mcu.Pin5=PC1 +Mcu.Pin6=PA0 +Mcu.Pin7=PA1 +Mcu.Pin8=PA2 +Mcu.Pin9=PA3 +Mcu.PinsNb=31 +Mcu.ThirdPartyNb=0 +Mcu.UserConstants= +Mcu.UserName=STM32L073RZTx +MxCube.Version=6.0.1 +MxDb.Version=DB.6.0.0 +NVIC.EXTI0_1_IRQn=true\:2\:0\:true\:false\:true\:true\:true +NVIC.EXTI4_15_IRQn=true\:2\:0\:true\:false\:true\:true\:true +NVIC.ForceEnableDMAVector=true +NVIC.HardFault_IRQn=true\:0\:0\:false\:false\:true\:true\:false +NVIC.NonMaskableInt_IRQn=true\:0\:0\:false\:false\:true\:true\:false +NVIC.PendSV_IRQn=true\:0\:0\:false\:false\:true\:true\:false +NVIC.RTC_IRQn=true\:2\:0\:true\:false\:true\:true\:true +NVIC.SVC_IRQn=true\:0\:0\:false\:false\:true\:true\:false +NVIC.SysTick_IRQn=true\:0\:0\:false\:false\:true\:true\:true +NVIC.USART1_IRQn=true\:1\:0\:true\:false\:true\:true\:true +PA0.GPIOParameters=GPIO_Label +PA0.GPIO_Label=A0_HIZ_NOT_USED +PA0.Locked=true +PA0.Signal=GPIO_Input +PA1.GPIOParameters=GPIO_Label +PA1.GPIO_Label=A1_HIZ_NOT_USED +PA1.Locked=true +PA1.Signal=GPIO_Input +PA10.Locked=true +PA10.Mode=Asynchronous +PA10.Signal=USART1_RX +PA13.Mode=Serial_Wire +PA13.Signal=SYS_SWDIO +PA14.Mode=Serial_Wire +PA14.Signal=SYS_SWCLK +PA2.Mode=Asynchronous +PA2.Signal=USART2_TX +PA3.Mode=Asynchronous +PA3.Signal=USART2_RX +PA4.GPIOParameters=GPIO_Label +PA4.GPIO_Label=A2_HIZ_NOT_USED +PA4.Locked=true +PA4.Signal=GPIO_Input +PA5.GPIOParameters=GPIO_Label +PA5.GPIO_Label=D13_HIZ_NOT_USED +PA5.Locked=true +PA5.Signal=GPIO_Input +PA6.GPIOParameters=GPIO_Label +PA6.GPIO_Label=D12_WAKEUP +PA6.Locked=true +PA6.Signal=GPIO_Output +PA7.GPIOParameters=GPIO_Label +PA7.GPIO_Label=D11_HIZ_NOT_USED +PA7.Locked=true +PA7.Signal=GPIO_Input +PA9.Locked=true +PA9.Mode=Asynchronous +PA9.Signal=USART1_TX +PB0.GPIOParameters=GPIO_Label +PB0.GPIO_Label=A3_HIZ_NOT_USED +PB0.Locked=true +PB0.Signal=GPIO_Input +PB10.GPIOParameters=GPIO_PuPd,GPIO_Label +PB10.GPIO_Label=D6_GPI_WKUP +PB10.GPIO_PuPd=GPIO_PULLDOWN +PB10.Locked=true +PB10.Signal=GPXTI10 +PB3.Locked=true +PB3.Mode=CTS_RTS +PB3.Signal=USART1_RTS +PB4.Locked=true +PB4.Mode=CTS_RTS +PB4.Signal=USART1_CTS +PB5.GPIOParameters=GPIO_Label +PB5.GPIO_Label=D4_HIZ_NOT_USED +PB5.Locked=true +PB5.Signal=GPIO_Input +PB6.GPIOParameters=GPIO_Label +PB6.GPIO_Label=D10_HIZ_NOT_USED +PB6.Locked=true +PB6.Signal=GPIO_Input +PB8.GPIOParameters=GPIO_Label +PB8.GPIO_Label=D15_HIZ_NOT_USED +PB8.Locked=true +PB8.Signal=GPIO_Input +PB9.GPIOParameters=GPIO_Label +PB9.GPIO_Label=D14_HIZ_NOT_USED +PB9.Locked=true +PB9.Signal=GPIO_Input +PC0.GPIOParameters=GPIO_PuPd,GPIO_ModeDefaultEXTI +PC0.GPIO_ModeDefaultEXTI=GPIO_MODE_IT_RISING +PC0.GPIO_PuPd=GPIO_PULLDOWN +PC0.Locked=true +PC0.Signal=GPXTI0 +PC1.GPIOParameters=GPIO_Label +PC1.GPIO_Label=A4_HIZ_NOT_USED +PC1.Locked=true +PC1.Signal=GPIO_Input +PC13.GPIOParameters=GPIO_Label +PC13.GPIO_Label=USER_Btn[B1] +PC13.Locked=true +PC13.Signal=GPXTI13 +PC14-OSC32_IN.Mode=LSE-External-Oscillator +PC14-OSC32_IN.Signal=RCC_OSC32_IN +PC15-OSC32_OUT.Mode=LSE-External-Oscillator +PC15-OSC32_OUT.Signal=RCC_OSC32_OUT +PC7.GPIOParameters=GPIO_Speed,GPIO_PuPd,GPIO_Label +PC7.GPIO_Label=D9_GPO_RST +PC7.GPIO_PuPd=GPIO_NOPULL +PC7.GPIO_Speed=GPIO_SPEED_FREQ_LOW +PC7.Locked=true +PC7.Signal=GPIO_Output +PH0-OSC_IN.Mode=HSE-External-Clock-Source +PH0-OSC_IN.Signal=RCC_OSC_IN +PinOutPanel.RotationAngle=0 +ProjectManager.AskForMigrate=true +ProjectManager.BackupPrevious=false +ProjectManager.CompilerOptimize=2 +ProjectManager.ComputerToolchain=false +ProjectManager.CoupleFile=true +ProjectManager.CustomerFirmwarePackage= +ProjectManager.DefaultFWLocation=true +ProjectManager.DeletePrevious=false +ProjectManager.DeviceId=STM32L073RZTx +ProjectManager.FirmwarePackage=STM32Cube FW_L0 V1.11.3 +ProjectManager.FreePins=false +ProjectManager.HalAssertFull=true +ProjectManager.HeapSize=0x200 +ProjectManager.KeepUserCode=true +ProjectManager.LastFirmware=true +ProjectManager.LibraryCopy=0 +ProjectManager.MainLocation=Src +ProjectManager.NoMain=false +ProjectManager.PreviousToolchain= +ProjectManager.ProjectBuild=false +ProjectManager.ProjectFileName=LPWA_sample_app.ioc +ProjectManager.ProjectName=LPWA_sample_app +ProjectManager.RegisterCallBack= +ProjectManager.StackSize=0xC00 +ProjectManager.TargetToolchain=MDK-ARM V5 +ProjectManager.ToolChainLocation= +ProjectManager.UnderRoot=false +ProjectManager.functionlistsort=1-MX_GPIO_Init-GPIO-false-HAL-true,2-SystemClock_Config-RCC-false-HAL-true,3-MX_USART1_UART_Init-USART1-false-HAL-true,4-MX_USART2_UART_Init-USART2-false-HAL-true,5-MX_RTC_Init-RTC-false-HAL-true +RCC.48CLKFreq_Value=32000000 +RCC.48RNGFreq_Value=32000000 +RCC.48USBFreq_Value=32000000 +RCC.AHBFreq_Value=32000000 +RCC.APB1Freq_Value=32000000 +RCC.APB1TimFreq_Value=32000000 +RCC.APB2Freq_Value=32000000 +RCC.APB2TimFreq_Value=32000000 +RCC.EnbaleCSS=false +RCC.FCLKCortexFreq_Value=32000000 +RCC.FamilyName=M +RCC.HCLKFreq_Value=32000000 +RCC.HSE_VALUE=8000000 +RCC.HSI16_VALUE=16000000 +RCC.HSI48_VALUE=48000000 +RCC.HSI_VALUE=16000000 +RCC.I2C1Freq_Value=32000000 +RCC.I2C3Freq_Value=32000000 +RCC.IPParameters=48CLKFreq_Value,48RNGFreq_Value,48USBFreq_Value,AHBFreq_Value,APB1Freq_Value,APB1TimFreq_Value,APB2Freq_Value,APB2TimFreq_Value,EnbaleCSS,FCLKCortexFreq_Value,FamilyName,HCLKFreq_Value,HSE_VALUE,HSI16_VALUE,HSI48_VALUE,HSI_VALUE,I2C1Freq_Value,I2C3Freq_Value,LCDFreq_Value,LPTIMFreq_Value,LPUARTFreq_Value,LSI_VALUE,MCOPinFreq_Value,MSI_VALUE,PLLCLKFreq_Value,PLLMUL,PLLSourceVirtual,PWRFreq_Value,RTCClockSelection,RTCClockSelectionVirtual,RTCFreq_Value,RTCHSEDivFreq_Value,SYSCLKFreq_VALUE,SYSCLKSource,TIMFreq_Value,TimerFreq_Value,USART1Freq_Value,USART2Freq_Value,VCOInputFreq_Value,VCOOutputFreq_Value,WatchDogFreq_Value +RCC.LCDFreq_Value=32768 +RCC.LPTIMFreq_Value=32000000 +RCC.LPUARTFreq_Value=32000000 +RCC.LSI_VALUE=37000 +RCC.MCOPinFreq_Value=32000000 +RCC.MSI_VALUE=2097000 +RCC.PLLCLKFreq_Value=32000000 +RCC.PLLMUL=RCC_PLLMUL_8 +RCC.PLLSourceVirtual=RCC_PLLSOURCE_HSE +RCC.PWRFreq_Value=32000000 +RCC.RTCClockSelection=RCC_RTCCLKSOURCE_LSE +RCC.RTCClockSelectionVirtual=RCC_RTCCLKSOURCE_LSE +RCC.RTCFreq_Value=32768 +RCC.RTCHSEDivFreq_Value=4000000 +RCC.SYSCLKFreq_VALUE=32000000 +RCC.SYSCLKSource=RCC_SYSCLKSOURCE_PLLCLK +RCC.TIMFreq_Value=32000000 +RCC.TimerFreq_Value=32000000 +RCC.USART1Freq_Value=32000000 +RCC.USART2Freq_Value=32000000 +RCC.VCOInputFreq_Value=8000000 +RCC.VCOOutputFreq_Value=64000000 +RCC.WatchDogFreq_Value=37000 +RTC.Alarm-Alarm\ A=RTC_ALARM_A +RTC.IPParameters=Alarm-Alarm A +SH.GPXTI0.0=GPIO_EXTI0 +SH.GPXTI0.ConfNb=1 +SH.GPXTI10.0=GPIO_EXTI10 +SH.GPXTI10.ConfNb=1 +SH.GPXTI13.0=GPIO_EXTI13 +SH.GPXTI13.ConfNb=1 +USART1.BaudRate=115200 +USART1.IPParameters=BaudRate,WordLength,VirtualMode-Asynchronous +USART1.VirtualMode-Asynchronous=VM_ASYNC +USART1.WordLength=WORDLENGTH_8B +USART2.BaudRate=115200 +USART2.IPParameters=VirtualMode-Asynchronous,BaudRate,WordLength +USART2.VirtualMode-Asynchronous=VM_ASYNC +USART2.WordLength=WORDLENGTH_8B +VP_RTC_VS_RTC_Activate.Mode=RTC_Enabled +VP_RTC_VS_RTC_Activate.Signal=RTC_VS_RTC_Activate +VP_RTC_VS_RTC_Alarm_A_Intern.Mode=Alarm A +VP_RTC_VS_RTC_Alarm_A_Intern.Signal=RTC_VS_RTC_Alarm_A_Intern +VP_RTC_VS_RTC_Calendar.Mode=RTC_Calendar +VP_RTC_VS_RTC_Calendar.Signal=RTC_VS_RTC_Calendar +VP_SYS_VS_Systick.Mode=SysTick +VP_SYS_VS_Systick.Signal=SYS_VS_Systick +board=single_profile_sample_app diff --git a/examples/eltres_lpwa/LPWA_sample_app.patch b/examples/eltres_lpwa/LPWA_sample_app.patch new file mode 100644 index 000000000..53115c547 --- /dev/null +++ b/examples/eltres_lpwa/LPWA_sample_app.patch @@ -0,0 +1,91 @@ +diff -upr Src/main.c Src/main.c +--- Src/main.c 2021-04-27 11:20:28.299280000 +0900 ++++ Src/main.c 2021-04-20 11:09:22.000000000 +0900 +@@ -25,7 +25,7 @@ + + /* Private includes ----------------------------------------------------------*/ + /* USER CODE BEGIN Includes */ +- ++#include "main_LPWA_sample_app.h" + /* USER CODE END Includes */ + + /* Private typedef -----------------------------------------------------------*/ +@@ -91,7 +91,7 @@ int main(void) + MX_USART2_UART_Init(); + MX_RTC_Init(); + /* USER CODE BEGIN 2 */ +- ++ main_LPWA_sample_app(); + /* USER CODE END 2 */ + + /* Infinite loop */ +Only in Src: main_LPWA_sample_app.c +diff -upr Src/stm32l0xx_it.c Src/stm32l0xx_it.c +--- Src/stm32l0xx_it.c 2021-04-27 11:20:27.862447400 +0900 ++++ Src/stm32l0xx_it.c 2021-04-20 11:09:22.000000000 +0900 +@@ -52,7 +52,8 @@ + + /* Private user code ---------------------------------------------------------*/ + /* USER CODE BEGIN 0 */ +- ++#include "CXM150x_Port.h" ++#include "main_LPWA_sample_app.h" + /* USER CODE END 0 */ + + /* External variables --------------------------------------------------------*/ +@@ -146,7 +147,7 @@ void SysTick_Handler(void) + void RTC_IRQHandler(void) + { + /* USER CODE BEGIN RTC_IRQn 0 */ +- ++ rtc_callback(); + /* USER CODE END RTC_IRQn 0 */ + HAL_RTC_AlarmIRQHandler(&hrtc); + /* USER CODE BEGIN RTC_IRQn 1 */ +@@ -160,7 +161,7 @@ void RTC_IRQHandler(void) + void EXTI0_1_IRQHandler(void) + { + /* USER CODE BEGIN EXTI0_1_IRQn 0 */ +- ++ wrapper_CXM150x_int_out1(); + /* USER CODE END EXTI0_1_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); + /* USER CODE BEGIN EXTI0_1_IRQn 1 */ +@@ -174,7 +175,12 @@ void EXTI0_1_IRQHandler(void) + void EXTI4_15_IRQHandler(void) + { + /* USER CODE BEGIN EXTI4_15_IRQn 0 */ +- ++ if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_10) != RESET){ ++ wrapper_CXM150x_int_out2(); ++ } ++ if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_13) != RESET){ ++ push_btn_CXM150x(); ++ } + /* USER CODE END EXTI4_15_IRQn 0 */ + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10); + HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13); +diff -upr Src/usart.c Src/usart.c +--- Src/usart.c 2021-04-27 11:20:27.743765600 +0900 ++++ Src/usart.c 2021-04-20 11:09:22.000000000 +0900 +@@ -21,7 +21,7 @@ + #include "usart.h" + + /* USER CODE BEGIN 0 */ +- ++extern void wrapper_CXM150x_uart_rx_callback(void); + /* USER CODE END 0 */ + + UART_HandleTypeDef huart1; +@@ -185,6 +185,11 @@ void HAL_UART_MspDeInit(UART_HandleTypeD + } + + /* USER CODE BEGIN 1 */ ++void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle){ ++ if(UartHandle->Instance==USART1){ ++ wrapper_CXM150x_uart_rx_callback(); ++ } ++} + + /* USER CODE END 1 */ + diff --git a/examples/eltres_lpwa/Sample_App_version_information.txt b/examples/eltres_lpwa/Sample_App_version_information.txt new file mode 100644 index 000000000..d7d4f6991 --- /dev/null +++ b/examples/eltres_lpwa/Sample_App_version_information.txt @@ -0,0 +1,19 @@ +================================================================================ + + CXM1500GE LPWA_sample_app code version information + +================================================================================ +2021/12/24 version 3.0.3 + Add EU Duty function + Change files + main_LPWA_sample_app.c +2021/08/16 version 3.0.2 + Addition of license terms + Change files + main_LPWA_sample_app.c,main_LPWA_sample_app.h +2020/12/15 version 3.0.1 + Bug fix of PoC Enable callback function + Change files + main_LPWA_sample_app.c +2020/07/09 version 3.0.0 + Preliminary(first release version) diff --git a/examples/eltres_lpwa/main_LPWA_sample_app.c b/examples/eltres_lpwa/main_LPWA_sample_app.c new file mode 100644 index 000000000..706308f6d --- /dev/null +++ b/examples/eltres_lpwa/main_LPWA_sample_app.c @@ -0,0 +1,1332 @@ +// ========================================================================== +/*! +* @file main_LPWA_sample_app.c +* @brief LPWA sample application +* @date 2021/12/24 +* +* Copyright 2021 Sony Semiconductor Solutions Corporation +* +* 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 Sony Semiconductor Solutions Corporation 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 OWNER 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 ------------------------------------------------------------------*/ +/*Host Microcomputer dependence include BEGIN */ +#include "main.h" +#include "stm32l0xx_hal.h" +#include "rtc.h" +#include "usart.h" +#include "gpio.h" +/*Host Microcomputer dependence include END */ + +#include +#include +#include +#include "CXM150x_APITypeDef.h" +#include "CXM150x_GNSS.h" +#include "CXM150x_SYS.h" +#include "CXM150x_TIME.h" +#include "CXM150x_TX.h" +#include "CXM150x_LIB.h" +#include "CXM150x_Utility.h" +#include "CXM150x_Port.h" +#include "main_LPWA_sample_app.h" + +// Sample application name definition +#define SAMPLE_APP_NAME "main_LPWA_sample_app" +// Sample application version definition +#define SAMPLE_APP_VER "3.0.3" + +// Set to a value other than 0 to enable the GNSS backup function +#define GNSS_BACKUP_USE (1) + +// Set to a value other than 0 to enable PoC format send(unencrypted message) +#define TX_POC_USE (0) + +// Set to a value other than 0 to enable TX Duty event +#define TX_DUTY_USE (0) + +// If the transmission interval is longer than CXM150x_POWER_OFF_INTERVAL_SEC, power off CXM150x (unit is sec) +#define CXM150x_POWER_OFF_INTERVAL_SEC (5*60) // 5 min + +// Calculate remaining time until next CXM150x power on Offset value +#define EEPROM_POW_ENABLE_REMAIN_OFFSET (0x0218) +// Periodic1 valid flag +#define EEPROM_DF1_ENABLE (0x0400) +// Periodic2 valid flag +#define EEPROM_DF2_ENABLE (0x0500) +// Event transmission valid flag +#define EEPROM_EF_ENABLE (0x0600) +// AR frame transmission delay time +#define AR_FRAME_DELAY (40) +// GGA positioning quality status invalid +#define GGA_FIX_QUALITY_INVALID (0) + +#if GNSS_BACKUP_USE +// Define GNSS backup interval (unit is seconds) +// Skip backup command issue if elapsed time since last backup is less than defined seconds +#define GNSS_BACKUP_INTERVAL_SEC (60*60) + +// Length of time character string set in GNSS (14 bytes in YYYYMMDDhhmmss format) +#define GNSS_DATETIME_LEN (14) + +// Last backup time +time_t g_last_gnss_backup_time = 0; + +// Timeout for waiting for backup command (unit is msec) +#define WAIT_BACKUP_DONE_MAX_TICK_COUNT (30000) + +// Leap second correction (Leap second as of May 2019) +#define GNSS_DATETIME_ADJUST_LEAP_SECOND (18) + +#endif + +// Difference between the base date in the RTC and struct tm +#define RTC_STRUCT_TM_BASE_TIME_DIFF_YEAR (100) // RTC is based on 2000, struct tm is based on 1900, so the difference is 100 years +#define RTC_STRUCT_TM_BASE_TIME_DIFF_MONTH (1) // RTC starts in month 1, struct tm starts in month 0 +#define RTC_STRUCT_TM_BASE_TIME_DIFF_WEEK (1) // week of RTC starts at 1, week of struct tm starts at 0 + +// Flag ON / OFF definition +typedef enum { + FLAG_OFF = 0, + FLAG_ON +}FlagOnOff; + +uint32_t get_current_tm(void); +void set_rtc_alarm(int32_t hh,int32_t mm,int32_t ss); +void wait_gps_data(void); +void wait_profile_change(void); +void get_current_gga_data(void); +void set_rtc_time(void); +#if GNSS_BACKUP_USE +time_t get_rtc_time(void); +void set_GNSS_backup_info(void); +void GNSS_backup_exec(void); +#endif + +// buffer for event information +CXM150xSysState g_sys_stt_info; +CXM150xNMEAGGAInfo g_nmea_gga_info_buf; +CXM150xFATALMessage g_fatalmessage_info; +CXM150xEventBufferOverflow g_buffer_overflow_info; +CXM150xTxPoCEnableMessage g_tx_poc_enable_message_info; +CXM150xTxDutyEventInfo g_duty_event_info; + +// Payload buffer for LPWA transmission +uint8_t g_payload_data_all0[CXM150x_PAYLOAD_LEN] = {0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30}; +// Push button interrupt flag +uint8_t g_push_btn_flag = FLAG_ON; + +// Event transmission completion flag +uint8_t g_ev_tx_complete_flag = FLAG_OFF; +// INT_OUT1 interrupt flag +uint8_t g_int1_callback_flg = FLAG_OFF; + +// transmission completion flag +uint8_t g_tx_comlete_flg = FLAG_OFF; + +// profile change completion flag +uint8_t g_profile_change_comlete_flg = FLAG_OFF; + +// CXM150x power ON offset time +uint32_t g_pow_enable_remain_offset = 0; + +// Event transmission valid flag +uint32_t g_profile_event_enable = FLAG_OFF; + +// periodec valid flag +uint32_t g_periodec_enable = FLAG_OFF; + +// RTC interrupt flag +uint32_t g_rtc_callback_flg = FLAG_OFF; + +// GNSS is avairable if CXM150x status is "EPM_FILL" or later state +uint32_t g_gnss_ready_flg = FLAG_OFF; + +#if GNSS_BACKUP_USE +// GNSS backup completion wait flag +uint32_t g_gnss_backup_done_flag = FLAG_OFF; +#endif + +// GNSS operation state event information buffer +CXM150xGNSSState g_gnss_stt_info; +// GNSS acquisition timeout flag +uint8_t g_gnss_timeout_flag = FLAG_OFF; +// GNSS Sleep flag +uint8_t g_gnss_sleep_flag = FLAG_OFF; +// GGA event information reception flag +uint8_t g_gga_event_callback_flg = FLAG_OFF; + +// =========================================================================== +//! Push button interrupt callback function +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] g_push_btn_flag: Push button interrupt flag + * + * @return none +*/ +// =========================================================================== +void push_btn_CXM150x(void){ + if(g_push_btn_flag == FLAG_OFF){ + printf("push_btn_callback!\r\n"); + g_push_btn_flag = FLAG_ON; + } +} + +// =========================================================================== +//! Callback function when a system state event occurs +/*! + * + * @param [in] info: Response data structure + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] g_sys_stt_info: Response data structure + * [out] g_gnss_ready_flg: GNSS ready flag + * [out] g_tx_comlete_flg: transmission completion flag + * [out] g_ev_tx_complete_flag: Event transmission completion flag + * [out] g_gnss_timeout_flag: GNSS acquisition timeout flag + * [out] g_gnss_backup_done_flag: GNSS backup completion wait flag + * @return none +*/ +// =========================================================================== +void sys_stt_event_callback(void *info,uint32_t id){ + + if(g_sys_stt_info == SYS_STT_IDLE){ + printf("sys_stt_event_callback:code=%d(IDLE)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_FETCHING_TIME){ + printf("sys_stt_event_callback:code=%d(FETCHING_TIME)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_WAIT_FETCHING_TIME){ + printf("sys_stt_event_callback:code=%d(WAIT_FETCHING_TIME)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_EPM_FILL){ + printf("sys_stt_event_callback:code=%d(EPM_FILL)\r\n",g_sys_stt_info); + // Turn on GNSS ready flag and transmission completion flag + g_gnss_ready_flg = FLAG_ON; + g_tx_comlete_flg = FLAG_ON; + } else if(g_sys_stt_info == SYS_STT_WAIT_TX_PREPARE){ + printf("sys_stt_event_callback:code=%d(WAIT_TX_PREPARE)\r\n",g_sys_stt_info); + g_profile_change_comlete_flg = FLAG_ON; + } else if(g_sys_stt_info == SYS_STT_AF_TX_PREPARE){ + printf("sys_stt_event_callback:code=%d(AF_TX_PREPARE)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_AF_WAIT_TX_START){ + printf("sys_stt_event_callback:code=%d(AF_WAIT_TX_START)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_AF_TX_PROGRESS){ + printf("sys_stt_event_callback:code=%d(AF_TX_PROGRESS)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_DF_TX_PREPARE){ + printf("sys_stt_event_callback:code=%d(DF_TX_PREPARE)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_DF_WAIT_TX_START){ + printf("sys_stt_event_callback:code=%d(DF_WAIT_TX_START)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_DF_TX_PROGRESS){ + printf("sys_stt_event_callback:code=%d(DF_TX_PROGRESS)\r\n",g_sys_stt_info); + printf("*** START LPWA TX: Stop get GNSS! ***\r\n"); + // Turn on GNSS acquisition timeout flag + g_gnss_timeout_flag = FLAG_ON; + } else if(g_sys_stt_info == SYS_STT_EV_TX_COMPLETE){ + printf("sys_stt_event_callback:code=%d(SYS_STT_EV_TX_COMPLETE)\r\n",g_sys_stt_info); + // Turn on the event transmission completion flag + g_ev_tx_complete_flag = FLAG_ON; + } else if(g_sys_stt_info == SYS_STT_GNSS_BACKUP){ + printf("sys_stt_event_callback:code=%d(SYS_STT_GNSS_BACKUP)\r\n",g_sys_stt_info); + } else if(g_sys_stt_info == SYS_STT_GNSS_BACKUP_DONE){ + printf("sys_stt_event_callback:code=%d(SYS_STT_GNSS_BACKUP_DONE)\r\n",g_sys_stt_info); +#if GNSS_BACKUP_USE + // Turn on the GNSS backup completion wait flag + g_gnss_backup_done_flag = FLAG_ON; +#endif + } else{ + printf("sys_stt_event_callback:code=%d(PURSE_ERROR)\r\n",g_sys_stt_info); + } + +} + +// =========================================================================== +//! Callback function when a GNSS operation state event occurs +/*! + * + * @param [in] info: GNSS operation state event information + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] g_gnss_stt_info: GNSS operation state event information buffer + * [out] g_gnss_sleep_flag: GNSS Sleep flag + * @return none +*/ +// =========================================================================== +void gnss_stt_event_callback(void *info,uint32_t id){ + + if(g_gnss_stt_info & 0x80){ // Sleeping + g_gnss_sleep_flag = FLAG_ON; + printf("*** GNSS_SLEEP ***\r\n"); + } else { + g_gnss_sleep_flag = FLAG_OFF; + } +} + +// =========================================================================== +//! Callback function when a GGA event occurs +/*! + * + * @param [in] info: GGA information + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] g_gga_event_callback_flg: GGA event information reception flag + * @return none +*/ +// =========================================================================== +void nmea_gga_event_callback(void *info,uint32_t id){ + CXM150xNMEAGGAInfo *gga_inf = (CXM150xNMEAGGAInfo*)info; + if(gga_inf->m_utc[0] == '\0'){ + printf("GGA: not ready\r\n"); + } else { + printf("GGA: time[%s] lat[%s %s] lng[%s %s] cs_correct[%d]\r\n",gga_inf->m_utc,gga_inf->m_n_s,gga_inf->m_lat,gga_inf->m_e_w,gga_inf->m_lon,g_nmea_gga_info_buf.m_cs_correct); + g_gga_event_callback_flg = FLAG_ON; + } + +} + +// =========================================================================== +//! Callback function for INT_OUT1 interrupt +/*! + * + * @param [in] msg: NULL fixed + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] g_int1_callback_flg: INT_OUT1 callback flag + * + * @return none +*/ +// =========================================================================== +void int1_callback(void* msg,uint32_t id){ + printf("int1_callback\r\n"); + g_int1_callback_flg = FLAG_ON; +} + +// =========================================================================== +//! Callback function for INT_OUT2 interrupt +/*! + * + * @param [in] msg: NULL fixed + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * + * @return none +*/ +// =========================================================================== +void int2_callback(void* msg,uint32_t id){ + printf("int2_callback\r\n"); +} + +// =========================================================================== +//! Callback function when FATAL message event occurs +/*! + * + * @param [in] info: Abnormal event information + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void fatal_message_event_callback(void *info,uint32_t id){ + CXM150xFATALMessage *fatal_info = (CXM150xFATALMessage*)info; + printf("FATAL Message Event: %s\r\n",fatal_info->m_str); +} + +// =========================================================================== +//! Sleep Nucleo +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void sleep_nucleo(void){ + printf("Go Sleep Nucleo!\r\n"); + HAL_SuspendTick(); + __HAL_RCC_PWR_CLK_ENABLE(); + HAL_PWR_EnterSLEEPMode(PWR_MAINREGULATOR_ON, PWR_SLEEPENTRY_WFI); +} + +// =========================================================================== +//! resume NUCLEO +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void resume_nucleo(void){ + HAL_ResumeTick(); + printf("Resume Nucleo!\r\n"); +} + +// =========================================================================== +//! resume CXM150x +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] g_gnss_ready_flg: GNSS ready flag + * [out] g_rtc_callback_flg: RTC interrupt flag + * @return none +*/ +// =========================================================================== +void resume_CXM150x(void){ + + // Get power supply status + CmdResGetCXM150xPower pwstate; + get_CXM150x_power(NULL,&pwstate,NULL); + + // resume if the power is off + if(pwstate.m_num == CXM150x_POWER_OFF){ + // Power ON and set normal mode + g_gnss_ready_flg = FLAG_OFF; + EXTI->IMR |= GPIO_PIN_0; // Unmask INT1 + CmdResSetCXM150xPower res_set_power; + memset(&res_set_power,0,sizeof(res_set_power)); + set_CXM150x_power(CXM150x_POWER_ON,&res_set_power,NULL); +#if GNSS_BACKUP_USE + // Set information for GNSS assist function (BUP) + set_GNSS_backup_info(); +#endif +#if TX_POC_USE + CmdResSetCXM150xTxPoCEnable res_set_tx_poc_enable; + memset(&res_set_tx_poc_enable,0,sizeof(res_set_tx_poc_enable)); + set_CXM150x_tx_PoC_enable(NULL,&res_set_tx_poc_enable,NULL); +#endif +#if TX_DUTY_USE + CmdResSetCXM150xTxDutyEvent res_set_tx_duty_event; + memset(&res_set_tx_duty_event,0,sizeof(res_set_tx_duty_event)); + set_CXM150x_tx_duty_event(EVENT_ON,&res_set_tx_duty_event,NULL); +#endif + CmdResSetCXM150xMode res_set_mode; + memset(&res_set_mode,0,sizeof(res_set_mode)); + set_CXM150x_mode(CXM150x_MODE_NORMAL,&res_set_mode,NULL); + if(g_push_btn_flag == FLAG_OFF){ + // GPS data acquisition + wait_gps_data(); + + g_rtc_callback_flg = FLAG_OFF; + } + } else { + while(get_CXM150x_Rx_message_count()>0){ + analyse_CXM150x_Rx(); + } + } +} + +// =========================================================================== +//! Change transmission profile, execute sleep process +/*! + * + * @param [in] next_time: Next transmission profile + * @param [out] none + * @par Global variable + * [in] g_pow_enable_remain_offset: CXM150x power ON offset time + * [out] g_gnss_ready_flg: GNSS ready flag + * [out] g_int1_callback_flg: INT_OUT1 interrupt flag + * [out] g_nmea_gga_info_buf: GGA information buffer + * @return none +*/ +// =========================================================================== +void power_off_check(void){ + uint32_t c_time = 0; + uint32_t next_time = 0; + struct tm c_tm; + struct tm n_tm; + CmdResGetCXM150xNextLPWATxTerm res_next_term; + CmdResGetCXM150xTxProfile res_profile; + TxProfileType current_profile_type; + + // If Periodic is invalid, judgment is unnecessary because only event transmission is performed + if(g_periodec_enable == FLAG_OFF){ + printf("+++++time check start+++++\r\n"); + set_rtc_time(); +#if GNSS_BACKUP_USE + GNSS_backup_exec(); +#endif + printf("event only mode\r\n"); + printf("CXM150x power off\r\n"); + EXTI->IMR &= ~ GPIO_PIN_0; // mask INT1 + CmdResSetCXM150xPower res_set_power; + memset(&res_set_power,0,sizeof(res_set_power)); + set_CXM150x_power(CXM150x_POWER_OFF,&res_set_power,NULL); + g_gnss_ready_flg = FLAG_OFF; + g_int1_callback_flg = FLAG_OFF; + printf("+++++time check end +++++\r\n"); + + return; + } + + // get current profile + if(get_CXM150x_tx_profile(NULL,&res_profile,NULL) == RETURN_OK){ + current_profile_type = (TxProfileType)res_profile.m_num; + } else { + current_profile_type = TX_CUR_FRM_TYPE_EVENT; + } + + if(current_profile_type == TX_CUR_FRM_TYPE_EVENT){ + // If profile switching is required + CmdResSetCXM150xTxProfile res_tx_profile; + memset(&res_tx_profile,0,sizeof(res_tx_profile)); + set_CXM150x_tx_profile(TX_CUR_FRM_TYPE_PERIODIC,&res_tx_profile,NULL); + + // After changing profiles, wait for transition to EPM_FILL or WAIT_TX_PREPARE + g_profile_change_comlete_flg = FLAG_OFF; + g_gnss_ready_flg = FLAG_OFF; + wait_profile_change(); + } + + // get current time + c_time = get_current_tm(); + (void)localtime_r(&c_time,&c_tm); + + printf("+++++time check start+++++\r\n"); + get_CXM150x_next_LPWA_tx_term(NULL,&res_next_term,NULL); + next_time = c_time + res_next_term.m_num; + (void)localtime_r(&next_time,&n_tm); + printf("current time:%02d:%02d.%02d(utc) next time:%02d:%02d.%02d(utc)\r\n",c_tm.tm_hour,c_tm.tm_min,c_tm.tm_sec,n_tm.tm_hour,n_tm.tm_min,n_tm.tm_sec); + + // Judge whether to turn off the power of CXM150x (Calculate the time it takes to turn off the power and return to normal) + int32_t interval = next_time - c_time - g_pow_enable_remain_offset; + printf("next interval:%d sec\r\n",interval); + if(interval > CXM150x_POWER_OFF_INTERVAL_SEC){ + printf("CXM150x power off\r\n"); + set_rtc_time(); +#if GNSS_BACKUP_USE + GNSS_backup_exec(); +#endif + EXTI->IMR &= ~ GPIO_PIN_0; // mask INT1 + CmdResSetCXM150xPower res_set_power; + memset(&res_set_power,0,sizeof(res_set_power)); + set_CXM150x_power(CXM150x_POWER_OFF,&res_set_power,NULL); + g_gnss_ready_flg = FLAG_OFF; + g_int1_callback_flg = FLAG_OFF; + HAL_Delay(1000); + uint32_t power_on_time = next_time - g_pow_enable_remain_offset; + struct tm p_tm; + (void)localtime_r(&power_on_time,&p_tm); + set_rtc_alarm(p_tm.tm_hour,p_tm.tm_min,p_tm.tm_sec); + memset(&g_nmea_gga_info_buf,0,sizeof(g_nmea_gga_info_buf)); + } else { + printf("CXM150x power not change\r\n"); + } + + printf("+++++time check end +++++\r\n"); +} + +// =========================================================================== +//! Wait until GNSS is available +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] g_gnss_ready_flg: GNSS ready flag + * [out] none + * @return none +*/ +// =========================================================================== +void wait_gps_data(void){ + if(g_gnss_ready_flg == FLAG_OFF){ + printf("-wait GNSS ready-\r\n"); + // Set system state event to ON + register_CXM150x_sys_state_event(&g_sys_stt_info,sys_stt_event_callback); + CmdResSetCXM150xSysStateEvent res_sys_stt; + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_ON,&res_sys_stt,NULL); + + while(g_gnss_ready_flg == FLAG_OFF){ + analyse_CXM150x_Rx(); + } + + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_OFF,&res_sys_stt,NULL); + printf("-GNSS ready-\r\n"); + } +} + +// =========================================================================== +//! Wait profile change +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] g_profile_change_comlete_flg: profile change completion flag + * [out] none + * @return none +*/ +// =========================================================================== +void wait_profile_change(void){ + if(g_profile_change_comlete_flg == FLAG_OFF && g_gnss_ready_flg == FLAG_OFF){ + printf("-wait profile change-\r\n"); + // Set system state event to ON + register_CXM150x_sys_state_event(&g_sys_stt_info,sys_stt_event_callback); + CmdResSetCXM150xSysStateEvent res_sys_stt; + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_ON,&res_sys_stt,NULL); + + while(g_profile_change_comlete_flg == FLAG_OFF && g_gnss_ready_flg == FLAG_OFF){ + analyse_CXM150x_Rx(); + } + + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_OFF,&res_sys_stt,NULL); + printf("-profile change complete-\r\n"); + } +} + +// =========================================================================== +//! Set payload data and wait for transmission completion +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] g_payload_data_all0: Default payload data + * [in] g_tx_comlete_flg: transmission completion flag + * [in] g_ev_tx_complete_flag: Event transmission completion flag + * [in] g_gnss_timeout_flag: GNSS acquisition timeout flag + * [in] g_gnss_sleep_flag: GNSSSleep flag + * [out] g_nmea_gga_info_buf: GGA information event buffer + * [out] g_gnss_stt_info: GNSS operation state event information buffer + * @return none +*/ +// =========================================================================== +void data_send(void){ + g_tx_comlete_flg = FLAG_OFF; + + // Payload settings + uint8_t payload_data[CXM150x_PAYLOAD_LEN]; + memset(payload_data,0,sizeof(payload_data)); + CmdResSetCXM150xLPWAPayload res_LPWAPayload; + memset(&res_LPWAPayload,0,sizeof(res_LPWAPayload)); + + // GGA information Event ON + memset(&g_nmea_gga_info_buf,'\0',sizeof(g_nmea_gga_info_buf)); + register_CXM150x_NMEAGGA_event(&g_nmea_gga_info_buf,nmea_gga_event_callback); + CmdResSetCXM150xNMEAEvent res_set_gnss; + memset(&res_set_gnss,0,sizeof(res_set_gnss)); + set_CXM150x_NMEA_event(NMEA_EVENT_GGA,&res_set_gnss,NULL); + + //GNSS EVENT ON + memset(&g_gnss_stt_info,'\0',sizeof(g_gnss_stt_info)); + register_CXM150x_GNSS_state_event(&g_gnss_stt_info, gnss_stt_event_callback); + CmdResSetCXM150xGNSSStateEvent res_set_gnss_stt; + memset(&res_set_gnss_stt,0,sizeof(res_set_gnss_stt)); + set_CXM150x_GNSS_state_event(EVENT_ON,&res_set_gnss_stt, NULL); + + g_gnss_timeout_flag = FLAG_OFF; + //wait GNSS wakeup + while((g_gnss_timeout_flag == FLAG_OFF) && (g_gnss_sleep_flag == FLAG_ON)){ + analyse_CXM150x_Rx(); + } + + // Keep updating the payload until the LPWA transmission starts or GNSS module goes to sleep + // The payload is updated each time a GGA is received, to increase the accuracy of the location information by repetition of positioning. + // If you don't need location accuracy, you only need to set the payload once. + while((g_gnss_timeout_flag == FLAG_OFF) && (g_gnss_sleep_flag == FLAG_OFF)){ + g_gga_event_callback_flg = FLAG_OFF; + + // Wait for GGA information reception + while((g_gga_event_callback_flg == FLAG_OFF) && (g_gnss_sleep_flag == FLAG_OFF)){ + analyse_CXM150x_Rx(); + } + if(g_gnss_sleep_flag == FLAG_OFF){ + if(g_gnss_timeout_flag == FLAG_OFF){ + // payload setting + if((g_nmea_gga_info_buf.m_pos_status != GGA_FIX_QUALITY_INVALID) && (g_nmea_gga_info_buf.m_cs_correct == NMEA_CS_OK)){ + // If the GPS is in the positioning state, set the latitude to the first 8 digits of 16 bytes and the longitude to the remaining 8 digits in ASCII + strncpy((char*)payload_data,(char*)g_nmea_gga_info_buf.m_lat,8); + strncpy((char*)&payload_data[8],(char*)g_nmea_gga_info_buf.m_lon,8); + set_CXM150x_LPWA_payload(payload_data,&res_LPWAPayload,NULL); + }else{ + // If GGA data has not been received, set a fixed message + set_CXM150x_LPWA_payload(g_payload_data_all0,&res_LPWAPayload,NULL); + } + }else{ + // Because update time limit for next LPWA transmit data has passed, do not set the payload here + } + } + } + + set_CXM150x_GNSS_state_event(EVENT_OFF,&res_set_gnss_stt, NULL); + set_CXM150x_NMEA_event(NMEA_EVENT_ALL_OFF,&res_set_gnss,NULL); + + // Wait for transmission completion + while(g_tx_comlete_flg == FLAG_OFF && g_ev_tx_complete_flag == FLAG_OFF){ + analyse_CXM150x_Rx(); + } +} + +// =========================================================================== +//! RTC timer set function +/*! + * + * @param [in] hh: RTC wakeup time (hour) + * @param [in] mm: RTC wakeup time (minutes) + * @param [in] ss: RTC wakeup time (seconds) + * @param [out] none + * @par Global variable + * [in] g_rtc_callback_flg: RTC interrupt flag + * [out] none + * @return none +*/ +// =========================================================================== +void set_rtc_alarm(int32_t hh,int32_t mm,int32_t ss){ + g_rtc_callback_flg = FLAG_OFF; + RTC_AlarmTypeDef sAlarm; + sAlarm.AlarmTime.Hours = hh; + sAlarm.AlarmTime.Minutes = mm; + sAlarm.AlarmTime.Seconds = ss; + sAlarm.AlarmTime.TimeFormat = RTC_HOURFORMAT_24; + sAlarm.AlarmTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + sAlarm.AlarmTime.StoreOperation = RTC_STOREOPERATION_RESET; + sAlarm.AlarmMask = RTC_ALARMMASK_DATEWEEKDAY; + sAlarm.AlarmDateWeekDaySel = RTC_ALARMDATEWEEKDAYSEL_DATE; + sAlarm.AlarmDateWeekDay = RTC_WEEKDAY_WEDNESDAY; + sAlarm.Alarm = RTC_ALARM_A; + HAL_RTC_SetAlarm_IT(&hrtc, &sAlarm, FORMAT_BIN); + + printf("set_rtc_alarm %02d:%02d.%02d(utc)\r\n",sAlarm.AlarmTime.Hours,sAlarm.AlarmTime.Minutes,sAlarm.AlarmTime.Seconds); +} + +// =========================================================================== +//! Current time acquisition function +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return current time +*/ +// =========================================================================== +uint32_t get_current_tm(void){ + // Get current time + CmdResGetCXM150xCurrentGNSSTime res; + while(1){ + get_CXM150x_current_GNSS_time(NULL,&res,NULL); + if(res.m_str[0] != '\0'){ + break; + } else { + HAL_Delay(1000); + } + } + + uint32_t sec = 0; + conv_CXM150x_GNSSTime_to_second(res.m_str,&sec); + + return sec; +} + +// =========================================================================== +//! Set RTC timer +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return current time +*/ +// =========================================================================== +void set_rtc_time(void){ + RTC_TimeTypeDef sTime; + uint32_t sec = get_current_tm(); + // Convert the number of seconds elapsed since GPS reference date and time obtained by get_current_tm to the number of seconds elapsed since 00:00:00 on January 1, 1900 + // Convert by adding the number of seconds elapsed from 00:00:00 on January 1, 1900 to 00:00:00 on January 6, 1980, which is the base date of GPS time + struct tm base_time; + base_time.tm_sec = GPS_FORMAT_BASE_TIME_SEC; + base_time.tm_min = GPS_FORMAT_BASE_TIME_MIN; + base_time.tm_hour = GPS_FORMAT_BASE_TIME_HOUR; + base_time.tm_mday = GPS_FORMAT_BASE_TIME_MDAY; + base_time.tm_mon = GPS_FORMAT_BASE_TIME_MON; + base_time.tm_year = GPS_FORMAT_BASE_TIME_YEAR; + base_time.tm_wday = GPS_FORMAT_BASE_TIME_WDAY; + base_time.tm_yday = GPS_FORMAT_BASE_TIME_YDAY; + base_time.tm_isdst = GPS_FORMAT_BASE_TIME_ISDST; + sec += mktime(&base_time); + + struct tm s_tm; + (void)localtime_r(&sec,&s_tm); + printf("local time:%02d:%02d.%02d(utc)\r\n",s_tm.tm_hour,s_tm.tm_min,s_tm.tm_sec); + + // Set time (hour, minute, second) in RTC + sTime.Hours = s_tm.tm_hour; + sTime.Minutes = s_tm.tm_min; + sTime.Seconds = s_tm.tm_sec; + sTime.TimeFormat = RTC_HOURFORMAT_24; + sTime.DayLightSaving = RTC_DAYLIGHTSAVING_NONE; + sTime.StoreOperation = RTC_STOREOPERATION_RESET; + HAL_RTC_SetTime(&hrtc, &sTime, FORMAT_BIN); + + // Set time (year / month / day) in RTC + // The year of RTC_DateTypeDef needs to be set in years since 2000, but the base year of struct tm is the year since 1900, so subtract 100 years + // Also, the month and week of RTC_DateTypeDef are counted from 1, whereas struct tm counts from 0, so you need to add 1 + RTC_DateTypeDef sdatestructure; + sdatestructure.Year = s_tm.tm_year - RTC_STRUCT_TM_BASE_TIME_DIFF_YEAR; + sdatestructure.Month = s_tm.tm_mon + RTC_STRUCT_TM_BASE_TIME_DIFF_MONTH; + sdatestructure.Date = s_tm.tm_mday; + sdatestructure.WeekDay = s_tm.tm_wday + RTC_STRUCT_TM_BASE_TIME_DIFF_WEEK; + + HAL_RTC_SetDate(&hrtc,&sdatestructure,FORMAT_BIN); + + printf("RTC init:%04d-%02d-%02d %02d:%02d:%02d\r\n",sdatestructure.Year+2000,sdatestructure.Month,sdatestructure.Date,sTime.Hours,sTime.Minutes,sTime.Seconds); + +} + +#if GNSS_BACKUP_USE +// =========================================================================== +//! Get the time set in RTC in time_t format +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return current time (time_t format) +*/ +// =========================================================================== +time_t get_rtc_time(void){ + // Get the time set in RTC + RTC_DateTypeDef sdatestructureget; + memset(&sdatestructureget,0,sizeof(sdatestructureget)); + RTC_TimeTypeDef stimestructureget; + memset(&stimestructureget,0,sizeof(stimestructureget)); + HAL_RTC_GetTime(&hrtc, &stimestructureget, RTC_FORMAT_BIN); + HAL_RTC_GetDate(&hrtc, &sdatestructureget, RTC_FORMAT_BIN); + + if(sdatestructureget.Year > 0){ + // The year of RTC_DateTypeDef is counted by the number of years since 2000, but add 100 years to struct tm since it is necessary to set the year since 1900 + // In addition, the month of RTC_DateTypeDef starts in January, whereas struct tm starts in January, so -1 + struct tm s_tm; + s_tm.tm_year = sdatestructureget.Year + RTC_STRUCT_TM_BASE_TIME_DIFF_YEAR; + s_tm.tm_mon = sdatestructureget.Month - RTC_STRUCT_TM_BASE_TIME_DIFF_MONTH; + s_tm.tm_mday = sdatestructureget.Date; + s_tm.tm_wday = sdatestructureget.WeekDay - RTC_STRUCT_TM_BASE_TIME_DIFF_WEEK; + s_tm.tm_hour = stimestructureget.Hours; + s_tm.tm_min = stimestructureget.Minutes; + s_tm.tm_sec = stimestructureget.Seconds; + + // Convert to time_t format + time_t c_sec = mktime(&s_tm); + + printf("get_rtc_time:%04d-%02d-%02d %02d:%02d:%02d\r\n",s_tm.tm_year+1900,s_tm.tm_mon+1,s_tm.tm_mday,s_tm.tm_hour,s_tm.tm_min,s_tm.tm_sec); + + return c_sec; + } else { + //Acquisition failure + printf("get_rtc_time invalid.\r\n"); + return 0; + } +} + +// =========================================================================== +//! Convert the time set in RTC to UTC and get it in character string format +/*! + * + * @param [in] none + * @param [out] Current time character string (YYYYMMDDhhmmss format) + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void get_utc_time_str(uint8_t *str){ + time_t rtc_time = get_rtc_time(); + if(rtc_time > 0){ + // Successful acquisition + // RTC time format is GNSS time so substract leap second to convert it to UTC time format, and return it as character string. + rtc_time -= GNSS_DATETIME_ADJUST_LEAP_SECOND; + struct tm utc_tm; + (void)localtime_r(&rtc_time,&utc_tm); + snprintf((char*)str,GNSS_DATETIME_LEN+1,"%04d%02d%02d%02d%02d%02d",utc_tm.tm_year+1900, utc_tm.tm_mon+1, utc_tm.tm_mday, utc_tm.tm_hour, utc_tm.tm_min, utc_tm.tm_sec); + } else { + //Acquisition failure + str[0] = '\0'; + printf("get_utc_time_str invalid.\r\n"); + } +} + +// =========================================================================== +//! When CXM150x is powered on, set time information and location information to enable hot start using the backup data of GNSS(BUP) +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void set_GNSS_backup_info(void){ +/* + // Set location information + // After GNSS BACKUP, if you move a long distance before starting, the effect of hot start may not be obtained + // In that case, get the location information by another way and set it to the GNSS by following method + + CmdResSetCXM150xGNSSPosition res_set_position; + memset(&res_set_position,0,sizeof(res_set_position)); + CXM150xGNSSPositionSetData pos_data; + strncpy((char*)pos_data.m_lat,"3525.6911",NMEA_LAT_SIZE); + pos_data.m_lat[NMEA_LAT_SIZE] = '\0'; + strncpy((char*)pos_data.m_n_s,"N",NMEA_N_S_SIZE); + pos_data.m_n_s[NMEA_N_S_SIZE] = '\0'; + strncpy((char*)pos_data.m_lon,"13922.2240",NMEA_LON_SIZE); + pos_data.m_lon[NMEA_LON_SIZE] = '\0'; + strncpy((char*)pos_data.m_e_w,"E",NMEA_E_W_SIZE); + pos_data.m_e_w[NMEA_E_W_SIZE] = '\0'; + set_CXM150x_GNSS_position(&pos_data,&res_set_position,NULL); +*/ + + // Set GNSS time information + CmdResSetCXM150xGNSSDateTime res_gnss_datetime; + memset(&res_gnss_datetime,0,sizeof(res_gnss_datetime)); + uint8_t rtc_time_str[GNSS_DATETIME_LEN+1] = ""; + get_utc_time_str(rtc_time_str); + + if(rtc_time_str[0] != '\0'){ + // Set time (with leap second) for CXM150x + set_CXM150x_GNSS_datetime(rtc_time_str,&res_gnss_datetime,NULL); + } +} + +// =========================================================================== +//! Execute GNSS information backup +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] g_gnss_backup_done_flag: GNSS information backup completion wait flag + * [out] g_last_gnss_backup_time: Last GNSS information backup time + * @return none +*/ +// =========================================================================== +void GNSS_backup_exec(void){ + + // Do not backup if GNSS_BACKUP_INTERVAL_SEC seconds have not elapsed since last backup time + time_t c_tm = get_rtc_time(); + if(c_tm != 0 && c_tm - g_last_gnss_backup_time >= GNSS_BACKUP_INTERVAL_SEC){ + // Execute backup processing + printf("-GNSS_backup_exec start-\r\n"); + + // Start waiting for GNSS backup completion + CmdResSetCXM150xSysStateEvent res_sys_stt; + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + register_CXM150x_sys_state_event(&g_sys_stt_info,sys_stt_event_callback); + set_CXM150x_sys_state_event(EVENT_ON,&res_sys_stt,NULL); + + // Issue GNSS backup command + g_gnss_backup_done_flag = FLAG_OFF; + CmdResSetCXM150xGNSSBackup res_gnss_backup; + memset(&res_gnss_backup,0,sizeof(res_gnss_backup)); + set_CXM150x_GNSS_backup(NULL,&res_gnss_backup,NULL); + + uint32_t wait_start_tick_count = wrapper_CXM150x_get_tick(); + while(g_gnss_backup_done_flag == FLAG_OFF){ + analyse_CXM150x_Rx(); + // timeout check + uint32_t current_tick_count = wrapper_CXM150x_get_tick(); + if(current_tick_count - wait_start_tick_count > WAIT_BACKUP_DONE_MAX_TICK_COUNT){ + printf("wait backup done timeout.\r\n"); + break; + } + } + + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_OFF,&res_sys_stt,NULL); + printf("-GNSS_backup_exec end-\r\n"); + + if(g_gnss_backup_done_flag == FLAG_ON){ + // Update the previous backup time only when a backup completion event is received + g_last_gnss_backup_time = get_rtc_time(); + struct tm s_tm; + (void)localtime_r(&g_last_gnss_backup_time,&s_tm); + printf("GNSS backup time renew:%04d-%02d-%02d %02d:%02d:%02d\r\n",s_tm.tm_year+1900,s_tm.tm_mon+1,s_tm.tm_mday,s_tm.tm_hour,s_tm.tm_min,s_tm.tm_sec); + } + } else { + // Skip backup processing because it is less than the specified interval + printf("GNSS_backup_exec skip(%dsec/%dsec)\r\n",(c_tm - g_last_gnss_backup_time),GNSS_BACKUP_INTERVAL_SEC); + } +} +#endif + +// =========================================================================== +//! check message count +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return FLAG_ON if message exist +*/ +// =========================================================================== +uint32_t check_message_count(void){ + // Get power supply status + CmdResGetCXM150xPower pwstate; + get_CXM150x_power(NULL,&pwstate,NULL); + + // resume if the power is off + if(pwstate.m_num == CXM150x_POWER_OFF){ + return FLAG_OFF; + } else { + if(get_CXM150x_Rx_message_count()>0){ + return FLAG_ON; + } else { + return FLAG_OFF; + } + } +} + +// =========================================================================== +//! RTC wakeup callback function +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] g_rtc_callback_flg: RTC interrupt flag + * @return none +*/ +// =========================================================================== +void rtc_callback(void){ + printf("rtc_callback\r\n"); + g_rtc_callback_flg = FLAG_ON; +} + +// =========================================================================== +//! Event buffer overflow callback function +/*! + * + * @param [in] info: Event data information + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void event_buffer_overflow_callback(void *info,uint32_t id){ + printf("event buffer overflow\r\n"); +} + +// =========================================================================== +//! tx PoC enable message callback function +/*! + * + * @param [in] info: Event data information + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void tx_poc_enable_message_callback(void *info,uint32_t id){ +#if TX_POC_USE + printf("TX PoC enable message callback\r\n"); +#else + //If TX PoC enable message callback occurs when TX PoC is disable, turn off the power due to a fatal error. + printf("FATAL errot :An unencrypted message\r\n"); + NVIC_SystemReset(); +#endif +} + +// =========================================================================== +//! tx Duty event callback function +/*! + * + * @param [in] info: Event data information + * @param [in] id: Callback ID + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void tx_duty_event_callback(void *info,uint32_t id){ + CXM150xTxDutyEventInfo *tx_duty_event_info = (CXM150xTxDutyEventInfo*)info; + if(tx_duty_event_info->m_result == CXM150x_RESPONSE_OK){ + printf("TX DUTY EVENT OK,%s\r\n",tx_duty_event_info->m_str); + }else{ + printf("TX DUTY EVENT NG,%s\r\n",tx_duty_event_info->m_str); + } +} + +// =========================================================================== +//! Display sample app and API version +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] none + * [out] none + * @return none +*/ +// =========================================================================== +void disp_version(void){ + CmdResGetCXM150xAPIVersion api_ver_inf; + get_CXM150x_api_version(NULL,&api_ver_inf,NULL); + printf("%s:Ver.%s, API:Ver.%s\r\n",SAMPLE_APP_NAME,SAMPLE_APP_VER,api_ver_inf.m_version); +} + +// =========================================================================== +//! LPWA sample application main function +/*! + * + * @param [in] none + * @param [out] none + * @par Global variable + * [in] g_push_btn_flag: Push button interrupt flag + * [in] g_int1_callback_flg: INT_OUT1 interrupt flag + * [in] g_ev_tx_complete_flag: Event transmission completion flag + * [in] g_sys_stt_info: system state event information + * [in] g_buffer_overflow_info: Response data structure + * [out] g_pow_enable_remain_offset: CXM150x power ON offset time + * [out] g_periodec_enable: Periodic enable flag + * [out] g_profile_event_enable: Event transmission enable flag + * @return exit code +*/ +// =========================================================================== +int main_LPWA_sample_app(void){ + // Display version information + disp_version(); + /////////////////////////////////////////////////////////// + // mask the INT2 interrupt + EXTI->IMR &= ~ D6_GPI_WKUP_Pin; + /////////////////////////////////////////////////////////// + + // FATAL message event callback setting + register_CXM150x_FATAL_message_event(&g_fatalmessage_info,fatal_message_event_callback); + register_CXM150x_event_buffer_overflow(&g_buffer_overflow_info,event_buffer_overflow_callback); + register_CXM150x_tx_PoC_enable_message_event(&g_tx_poc_enable_message_info,tx_poc_enable_message_callback); + + // Power ON and set normal mode + EXTI->IMR |= GPIO_PIN_0; // Unmask INT1 + CmdResSetCXM150xPower res_set_power; + memset(&res_set_power,0,sizeof(res_set_power)); + set_CXM150x_power(CXM150x_POWER_ON,&res_set_power,NULL); +#if TX_POC_USE + CmdResSetCXM150xTxPoCEnable res_set_tx_poc_enable; + memset(&res_set_tx_poc_enable,0,sizeof(res_set_tx_poc_enable)); + set_CXM150x_tx_PoC_enable(NULL,&res_set_tx_poc_enable,NULL); +#endif +#if TX_DUTY_USE + CmdResSetCXM150xTxDutyEvent res_set_tx_duty_event; + memset(&res_set_tx_duty_event,0,sizeof(res_set_tx_duty_event)); + set_CXM150x_tx_duty_event(EVENT_ON,&res_set_tx_duty_event,NULL); + + // tx duty callback setting + register_CXM150x_tx_duty_event(&g_duty_event_info,tx_duty_event_callback); +#endif + + CmdResSetCXM150xMode res_set_mode; + memset(&res_set_mode,0,sizeof(res_set_mode)); + set_CXM150x_mode(CXM150x_MODE_NORMAL,&res_set_mode,NULL); + + // Get various EEPROM settings + CmdResGetCXM150xEEPROMData eep_data; + + // CXM150x power ON offset time + get_CXM150x_EEPROM_data(EEPROM_POW_ENABLE_REMAIN_OFFSET,&eep_data,NULL); + g_pow_enable_remain_offset = eep_data.m_num + AR_FRAME_DELAY; + + // Periodi 1 and 2 valid setting + uint32_t periodic1_eanable; + uint32_t periodic2_eanable; + get_CXM150x_EEPROM_data(EEPROM_DF1_ENABLE,&eep_data,NULL); + periodic1_eanable = eep_data.m_num; + + get_CXM150x_EEPROM_data(EEPROM_DF2_ENABLE,&eep_data,NULL); + periodic2_eanable = eep_data.m_num; + + // If both Periodic1 and Periodic2 are set to disabled, then Periodic is disabled + if(periodic1_eanable == FLAG_OFF && periodic2_eanable == FLAG_OFF){ + g_periodec_enable = FLAG_OFF; + } else { + g_periodec_enable = FLAG_ON; + } + + // event transmission enable setting + get_CXM150x_EEPROM_data(EEPROM_EF_ENABLE,&eep_data,NULL); + g_profile_event_enable = eep_data.m_num; + + printf("*** pow_enable_remain_offset:%d\r\n",g_pow_enable_remain_offset); + printf("*** periodic1_eanable:%d periodic2_eanable:%d\r\n",periodic1_eanable,periodic2_eanable); + printf("*** periodic enable:%d\r\n",g_periodec_enable); + printf("*** event enable:%d\r\n",g_profile_event_enable); + + // int2 interrupt callback setting + register_CXM150x_uart_start_interrupt(NULL,int2_callback); + + // GPS data acquisition + wait_gps_data(); + + // RTC settings + set_rtc_time(); + + // Register INT_OUT1 interrupt function + register_CXM150x_LPWA_start_interrupt(NULL,int1_callback); + + // Power off judgment + power_off_check(); + + g_push_btn_flag = FLAG_OFF; + + printf("*** push button to event send ***\r\n"); + + /* Infinite loop */ + while(1){ + // Sleep processing if no interrupt + if(g_int1_callback_flg == FLAG_OFF && g_push_btn_flag == FLAG_OFF && check_message_count() == FLAG_OFF){ + // sleep start + sleep_nucleo(); + + // wake from sleep + resume_nucleo(); + } + + // resume CXM150x + resume_CXM150x(); + + if(g_push_btn_flag == FLAG_ON){ + if(g_profile_event_enable == FLAG_OFF){ + printf("Event profile disable\r\n"); + g_push_btn_flag = FLAG_OFF; + // GPS data acquisition + wait_gps_data(); + // Power off judgment + power_off_check(); + + continue; + } + printf("*** event send start! ***\r\n"); + g_ev_tx_complete_flag = FLAG_OFF; + + // profile change (event) + CmdResSetCXM150xTxProfile res_tx_profile; + set_CXM150x_tx_profile(TX_CUR_FRM_TYPE_EVENT,&res_tx_profile,NULL); + + // After changing profiles, wait for transition to EPM_FILL or WAIT_TX_PREPARE + g_profile_change_comlete_flg = FLAG_OFF; + g_gnss_ready_flg = FLAG_OFF; + wait_profile_change(); + + // Set system state event to ON + register_CXM150x_sys_state_event(&g_sys_stt_info,sys_stt_event_callback); + CmdResSetCXM150xSysStateEvent res_sys_stt; + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_ON,&res_sys_stt,NULL); + + while(1){ + analyse_CXM150x_Rx(); + if(g_ev_tx_complete_flag == FLAG_OFF && g_int1_callback_flg == FLAG_ON){ + g_int1_callback_flg = FLAG_OFF; + + // Send data + data_send(); + }else if(g_ev_tx_complete_flag == FLAG_ON){ + break; + } + } + + // Set system state event to OFF + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_OFF,&res_sys_stt,NULL); + + // Power off judgment + power_off_check(); + + g_push_btn_flag = FLAG_OFF; + g_int1_callback_flg = FLAG_OFF; + printf("*** event send end! ***\r\n"); + } else if(g_int1_callback_flg == FLAG_ON){ + printf("*** normal send start! ***\r\n"); + g_ev_tx_complete_flag = FLAG_OFF; + + // Set system state event to ON + register_CXM150x_sys_state_event(&g_sys_stt_info,sys_stt_event_callback); + CmdResSetCXM150xSysStateEvent res_sys_stt; + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_ON,&res_sys_stt,NULL); + + // Send data + data_send(); + + // Set system state event to OFF + memset(&res_sys_stt,0,sizeof(res_sys_stt)); + set_CXM150x_sys_state_event(EVENT_OFF,&res_sys_stt,NULL); + + // If there is an event transmission interrupt, do not judge the power OFF here + if(g_push_btn_flag == FLAG_OFF){ + power_off_check(); + } + + g_int1_callback_flg = FLAG_OFF; + printf("*** normal send end! ***\r\n"); + } + } +} + diff --git a/examples/eltres_lpwa/main_LPWA_sample_app.h b/examples/eltres_lpwa/main_LPWA_sample_app.h new file mode 100644 index 000000000..963094fc8 --- /dev/null +++ b/examples/eltres_lpwa/main_LPWA_sample_app.h @@ -0,0 +1,49 @@ +// ========================================================================== +/*! +* @file main_LPWA_sample_app.h +* @brief header file of main_LPWA_sample_app.c +* @date 2021/08/16 +* +* Copyright 2021 Sony Semiconductor Solutions Corporation +* +* 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 Sony Semiconductor Solutions Corporation 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 OWNER 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. +* +*/ +// ========================================================================= +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __MAIN_LPWA_SAMPLE_APP_H +#define __MAIN_LPWA_SAMPLE_APP_H + /* Includes ------------------------------------------------------------------*/ +#include "stm32l0xx_hal.h" + +/* Includes ------------------------------------------------------------------*/ +int main_LPWA_sample_app(void); +void push_btn_CXM150x(void); +void rtc_callback(void); + +/* Private define ------------------------------------------------------------*/ + +#endif /* __MAIN_LPWA_SAMPLE_APP_H */