A demo application for HXC900 LoRaWAN module using Nucleo-L053R8.

Dependencies:   mbed

Committer:
fahadmirza
Date:
Thu Jan 24 23:45:12 2019 +0000
Revision:
39:cb0e5a76ab15
Parent:
32:2d0678039a09
Doxygen style header

Who changed what in which revision?

UserRevisionLine numberNew contents of line
fahadmirza 0:a0c5877bd360 1 /*
fahadmirza 0:a0c5877bd360 2 _ _ _____ _______
fahadmirza 0:a0c5877bd360 3 | | | | |_ _| |__ __|
fahadmirza 0:a0c5877bd360 4 | |__| | __ ___ __ | | ___ | |
fahadmirza 0:a0c5877bd360 5 | __ |/ _` \ \/ / | | / _ \| |
fahadmirza 0:a0c5877bd360 6 | | | | (_| |> < _| || (_) | |
fahadmirza 0:a0c5877bd360 7 |_| |_|\__,_/_/\_\_____\___/|_|
fahadmirza 0:a0c5877bd360 8 (C)2017 HaxIoT
fahadmirza 0:a0c5877bd360 9 */
fahadmirza 0:a0c5877bd360 10 /*******************************************************************************
fahadmirza 0:a0c5877bd360 11 * @File : lora_driver.c
fahadmirza 0:a0c5877bd360 12 * @Author : Fahad Mirza (Haxiot)
fahadmirza 0:a0c5877bd360 13 * @Version : V1.0.0
fahadmirza 24:f3b987589609 14 * @Modified: 18 October, 2018
fahadmirza 0:a0c5877bd360 15 * @Brief : LoRa Driver
fahadmirza 0:a0c5877bd360 16 ******************************************************************************
fahadmirza 0:a0c5877bd360 17 * @attention
fahadmirza 0:a0c5877bd360 18 *
fahadmirza 0:a0c5877bd360 19 * <h2><center>&copy; COPYRIGHT(c) 2017 Haxiot</center></h2>
fahadmirza 0:a0c5877bd360 20 *
fahadmirza 0:a0c5877bd360 21 * Redistribution and use in source and binary forms, with or without modification,
fahadmirza 0:a0c5877bd360 22 * are permitted provided that the following conditions are met:
fahadmirza 0:a0c5877bd360 23 * 1. Redistributions of source code must retain the above copyright notice,
fahadmirza 0:a0c5877bd360 24 * this list of conditions and the following disclaimer.
fahadmirza 0:a0c5877bd360 25 * 2. Redistributions in binary form must reproduce the above copyright notice,
fahadmirza 0:a0c5877bd360 26 * this list of conditions and the following disclaimer in the documentation
fahadmirza 0:a0c5877bd360 27 * and/or other materials provided with the distribution.
fahadmirza 0:a0c5877bd360 28 * 3. Neither the name of Haxiot nor the names of its contributors
fahadmirza 0:a0c5877bd360 29 * may be used to endorse or promote products derived from this software
fahadmirza 0:a0c5877bd360 30 * without specific prior written permission.
fahadmirza 0:a0c5877bd360 31 *
fahadmirza 0:a0c5877bd360 32 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
fahadmirza 0:a0c5877bd360 33 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
fahadmirza 0:a0c5877bd360 34 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
fahadmirza 0:a0c5877bd360 35 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
fahadmirza 0:a0c5877bd360 36 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
fahadmirza 0:a0c5877bd360 37 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
fahadmirza 0:a0c5877bd360 38 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
fahadmirza 0:a0c5877bd360 39 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
fahadmirza 0:a0c5877bd360 40 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
fahadmirza 0:a0c5877bd360 41 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
fahadmirza 0:a0c5877bd360 42 *
fahadmirza 0:a0c5877bd360 43 ******************************************************************************
fahadmirza 0:a0c5877bd360 44 */
fahadmirza 0:a0c5877bd360 45 /* Includes ------------------------------------------------------------------*/
fahadmirza 0:a0c5877bd360 46 #include <stdio.h>
fahadmirza 0:a0c5877bd360 47 #include "hxc_client.h"
fahadmirza 0:a0c5877bd360 48 #include "debug.h"
fahadmirza 0:a0c5877bd360 49 #include "stm32l0xx_nucleo.h"
fahadmirza 0:a0c5877bd360 50 #include "time_server.h"
fahadmirza 0:a0c5877bd360 51 #include "lora_driver.h"
fahadmirza 0:a0c5877bd360 52 #include "tiny_sscanf.h"
fahadmirza 0:a0c5877bd360 53 #include "utilities.h"
fahadmirza 32:2d0678039a09 54 #include "hxcclient_bsp.h"
fahadmirza 0:a0c5877bd360 55
fahadmirza 0:a0c5877bd360 56 /* Private Macros ------------------------------------------------------------*/
fahadmirza 0:a0c5877bd360 57 #define JOIN_SEND_DELAY_MAX (10000U) // Randomization range - 10s
fahadmirza 0:a0c5877bd360 58 #define JOIN_STATUS_REQ_DELAY (7000U) // milliseconds. Join req takes 6s.
fahadmirza 0:a0c5877bd360 59
fahadmirza 17:e682a18c3914 60 // Re Authenticate every REJOIN_TIME
fahadmirza 25:50414f44a431 61 #define REJOIN_TIME (1 * 60 * 60 * 1000U) // 1 hour
fahadmirza 17:e682a18c3914 62
fahadmirza 0:a0c5877bd360 63 /* Private global variables --------------------------------------------------*/
fahadmirza 0:a0c5877bd360 64 static sLoraConfig_t *LoraConfigParam;
fahadmirza 0:a0c5877bd360 65 static sLoraDriverParam_t *LoraDriverParam;
fahadmirza 26:176e648c03f6 66 static volatile eDeviceState_t DeviceState = CLIENT_INIT;
fahadmirza 0:a0c5877bd360 67
fahadmirza 0:a0c5877bd360 68 static TimerEvent_t JoinRequestTimer;
fahadmirza 17:e682a18c3914 69 static TimerEvent_t RejoinTimer;
fahadmirza 0:a0c5877bd360 70 static TimerEvent_t SensorMeasureTimer;
fahadmirza 32:2d0678039a09 71 static TimerEvent_t JoinStatusReqTimer;
fahadmirza 0:a0c5877bd360 72
fahadmirza 0:a0c5877bd360 73 // Object definition for data to be sent to loRa application server
fahadmirza 27:517ca3a30ad7 74 static uint8_t DataBinaryBuff[MAX_PAYLOAD_SIZE];
fahadmirza 0:a0c5877bd360 75 static sSendDataBinary_t SendDataBinary = {DataBinaryBuff, 0 , 0, 0};
fahadmirza 0:a0c5877bd360 76
fahadmirza 0:a0c5877bd360 77 // RNG handler declaration
fahadmirza 0:a0c5877bd360 78 RNG_HandleTypeDef RngHandle = {.Instance = RNG};
fahadmirza 0:a0c5877bd360 79
fahadmirza 0:a0c5877bd360 80 /* Private functions ---------------------------------------------------------*/
fahadmirza 17:e682a18c3914 81 static void OnRejoinTimerEvent(void);
fahadmirza 10:19da323c2bc0 82 static void OnJoinRequestTimerEvt(void);
fahadmirza 32:2d0678039a09 83 static void OnJoinStatusReqTimerEvt(void);
fahadmirza 10:19da323c2bc0 84 static void OnSensorMeasureTimerEvt(void);
fahadmirza 0:a0c5877bd360 85 static void setJoinRequestTimer(void);
fahadmirza 0:a0c5877bd360 86
fahadmirza 0:a0c5877bd360 87
fahadmirza 0:a0c5877bd360 88 /* Function definitions ------------------------------------------------------*/
fahadmirza 0:a0c5877bd360 89 /******************************************************************************
fahadmirza 0:a0c5877bd360 90 * @Brief : Initialize LoRa Modem
fahadmirza 0:a0c5877bd360 91 * @Param : sLoraConfig_t
fahadmirza 16:2179ec24dff8 92 * @Return : None
fahadmirza 0:a0c5877bd360 93 ******************************************************************************/
fahadmirza 0:a0c5877bd360 94 void Lora_init(sLoraConfig_t *loraConfig, sLoraDriverParam_t *loraDriverParam)
fahadmirza 0:a0c5877bd360 95 {
fahadmirza 0:a0c5877bd360 96
fahadmirza 0:a0c5877bd360 97 LoraConfigParam = loraConfig;
fahadmirza 0:a0c5877bd360 98 LoraDriverParam = loraDriverParam;
fahadmirza 0:a0c5877bd360 99
fahadmirza 0:a0c5877bd360 100 if(Modem_Init() != AT_OK)
fahadmirza 0:a0c5877bd360 101 {
fahadmirza 0:a0c5877bd360 102 DBG_PRINTF("Modem_Init failed\r\n");
fahadmirza 0:a0c5877bd360 103 }
fahadmirza 0:a0c5877bd360 104
fahadmirza 0:a0c5877bd360 105 // Initialize RNG for join request send randomization
fahadmirza 0:a0c5877bd360 106 HAL_RNG_Init(&RngHandle);
fahadmirza 0:a0c5877bd360 107
fahadmirza 0:a0c5877bd360 108
fahadmirza 0:a0c5877bd360 109 // Timer for join request send
fahadmirza 10:19da323c2bc0 110 TimerInit(&JoinRequestTimer, OnJoinRequestTimerEvt);
fahadmirza 0:a0c5877bd360 111 // Timer for join status check
fahadmirza 32:2d0678039a09 112 TimerInit(&JoinStatusReqTimer, OnJoinStatusReqTimerEvt);
fahadmirza 32:2d0678039a09 113 TimerSetValue(&JoinStatusReqTimer, JOIN_STATUS_REQ_DELAY);
fahadmirza 0:a0c5877bd360 114 // Timer for sensor occurrence measure
fahadmirza 10:19da323c2bc0 115 TimerInit(&SensorMeasureTimer, OnSensorMeasureTimerEvt);
fahadmirza 32:2d0678039a09 116 TimerSetValue(&SensorMeasureTimer, LoraDriverParam->UplinkCycle);
fahadmirza 32:2d0678039a09 117 // Timer for Re-Authenticate / Re-Join
fahadmirza 17:e682a18c3914 118 TimerInit(&RejoinTimer, OnRejoinTimerEvent);
fahadmirza 32:2d0678039a09 119 TimerSetValue(&RejoinTimer, REJOIN_TIME);
fahadmirza 0:a0c5877bd360 120 }
fahadmirza 0:a0c5877bd360 121
fahadmirza 0:a0c5877bd360 122 /******************************************************************************
fahadmirza 0:a0c5877bd360 123 * @Brief : Check if the modem responds
fahadmirza 0:a0c5877bd360 124 * @Param : void
fahadmirza 0:a0c5877bd360 125 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 126 ******************************************************************************/
fahadmirza 0:a0c5877bd360 127 static eAtStatus_t is_modem_working(void)
fahadmirza 0:a0c5877bd360 128 {
fahadmirza 0:a0c5877bd360 129 return Modem_AT_Cmd(AT_CTRL, AT, NULL);
fahadmirza 0:a0c5877bd360 130 }
fahadmirza 0:a0c5877bd360 131
fahadmirza 0:a0c5877bd360 132 /******************************************************************************
fahadmirza 0:a0c5877bd360 133 * @Brief : Set Device EUI
fahadmirza 0:a0c5877bd360 134 * @Param : Pointer to Device EUI
fahadmirza 0:a0c5877bd360 135 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 136 ******************************************************************************/
fahadmirza 10:19da323c2bc0 137 static eAtStatus_t Lora_setDevEui(char *devEui)
fahadmirza 0:a0c5877bd360 138 {
fahadmirza 0:a0c5877bd360 139 return Modem_AT_Cmd(AT_SET, AT_DEVEUI, devEui);
fahadmirza 0:a0c5877bd360 140 }
fahadmirza 0:a0c5877bd360 141
fahadmirza 0:a0c5877bd360 142 /******************************************************************************
fahadmirza 27:517ca3a30ad7 143 * @Brief : Print Device EUI
fahadmirza 27:517ca3a30ad7 144 * @Param : None
fahadmirza 27:517ca3a30ad7 145 * @Retval : AT_OK or other eAtStatus_t
fahadmirza 27:517ca3a30ad7 146 ******************************************************************************/
fahadmirza 27:517ca3a30ad7 147 static void Lora_printDevEui(void)
fahadmirza 27:517ca3a30ad7 148 {
fahadmirza 27:517ca3a30ad7 149 char deveui_str[25];
fahadmirza 27:517ca3a30ad7 150
fahadmirza 27:517ca3a30ad7 151 Modem_AT_Cmd(AT_GET, AT_DEVEUI, deveui_str);
fahadmirza 27:517ca3a30ad7 152
fahadmirza 27:517ca3a30ad7 153 DBG_PRINTF("DevEui: %s\n", deveui_str);
fahadmirza 27:517ca3a30ad7 154 }
fahadmirza 27:517ca3a30ad7 155
fahadmirza 27:517ca3a30ad7 156 /******************************************************************************
fahadmirza 32:2d0678039a09 157 * @Brief : Print Device Address
fahadmirza 32:2d0678039a09 158 * @Param : None
fahadmirza 32:2d0678039a09 159 * @Retval : AT_OK or other eAtStatus_t
fahadmirza 32:2d0678039a09 160 ******************************************************************************/
fahadmirza 32:2d0678039a09 161 static void Lora_printDevAdr(void)
fahadmirza 32:2d0678039a09 162 {
fahadmirza 32:2d0678039a09 163 char devadr_str[15];
fahadmirza 32:2d0678039a09 164
fahadmirza 32:2d0678039a09 165 Modem_AT_Cmd(AT_GET, AT_DEVADR, devadr_str);
fahadmirza 32:2d0678039a09 166
fahadmirza 32:2d0678039a09 167 DBG_PRINTF("DevAdr: %s\n", devadr_str);
fahadmirza 32:2d0678039a09 168 }
fahadmirza 32:2d0678039a09 169
fahadmirza 32:2d0678039a09 170 /******************************************************************************
fahadmirza 2:1ef859bc5cd2 171 * @Brief : Turn on or off ADR
fahadmirza 2:1ef859bc5cd2 172 * @Param : ADR_ON or ADR_OFF
fahadmirza 2:1ef859bc5cd2 173 * @Return : AT_OK or other eAtStatus_t
fahadmirza 2:1ef859bc5cd2 174 ******************************************************************************/
fahadmirza 10:19da323c2bc0 175 static eAtStatus_t Lora_setAdr(eAdrStatus_t adrStatus)
fahadmirza 2:1ef859bc5cd2 176 {
fahadmirza 2:1ef859bc5cd2 177 //char adr = (adrStatus == ADR_ON ? '1' : '0');
fahadmirza 2:1ef859bc5cd2 178 return Modem_AT_Cmd(AT_SET, AT_ADR, (uint8_t *)(&adrStatus));
fahadmirza 2:1ef859bc5cd2 179 }
fahadmirza 2:1ef859bc5cd2 180
fahadmirza 2:1ef859bc5cd2 181 /******************************************************************************
fahadmirza 0:a0c5877bd360 182 * @Brief : Set Application EUI
fahadmirza 0:a0c5877bd360 183 * @Param : Pointer to Application EUI
fahadmirza 0:a0c5877bd360 184 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 185 ******************************************************************************/
fahadmirza 10:19da323c2bc0 186 static eAtStatus_t Lora_setAppEui(char *appEui)
fahadmirza 0:a0c5877bd360 187 {
fahadmirza 0:a0c5877bd360 188 return Modem_AT_Cmd(AT_SET, AT_APPEUI, appEui);
fahadmirza 0:a0c5877bd360 189 }
fahadmirza 0:a0c5877bd360 190
fahadmirza 0:a0c5877bd360 191 /******************************************************************************
fahadmirza 0:a0c5877bd360 192 * @Brief : Set Application Key
fahadmirza 0:a0c5877bd360 193 * @Param : Pointer to Application Key
fahadmirza 0:a0c5877bd360 194 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 195 ******************************************************************************/
fahadmirza 10:19da323c2bc0 196 static eAtStatus_t Lora_setAppKey(char *appKey)
fahadmirza 0:a0c5877bd360 197 {
fahadmirza 0:a0c5877bd360 198 return Modem_AT_Cmd(AT_SET, AT_APPKEY, appKey);
fahadmirza 0:a0c5877bd360 199 }
fahadmirza 0:a0c5877bd360 200
fahadmirza 0:a0c5877bd360 201 /******************************************************************************
fahadmirza 0:a0c5877bd360 202 * @Brief : Set join mode
fahadmirza 0:a0c5877bd360 203 * @Param : OTAA or ABP
fahadmirza 0:a0c5877bd360 204 * @Retval : AT_OK if successful, otherwise other eAtStatus_t
fahadmirza 0:a0c5877bd360 205 ******************************************************************************/
fahadmirza 10:19da323c2bc0 206 static eAtStatus_t Lora_setJoinMode(eJoinMode_t joinMode)
fahadmirza 0:a0c5877bd360 207 {
fahadmirza 0:a0c5877bd360 208 if(joinMode == OTAA)
fahadmirza 0:a0c5877bd360 209 {
fahadmirza 0:a0c5877bd360 210 return Modem_AT_Cmd(AT_SET, AT_NJM, "OTAA");
fahadmirza 0:a0c5877bd360 211 }
fahadmirza 0:a0c5877bd360 212
fahadmirza 0:a0c5877bd360 213 return Modem_AT_Cmd(AT_SET, AT_NJM, "ABP");
fahadmirza 0:a0c5877bd360 214 }
fahadmirza 0:a0c5877bd360 215
fahadmirza 0:a0c5877bd360 216 /******************************************************************************
fahadmirza 0:a0c5877bd360 217 * @Brief : Set Class
fahadmirza 0:a0c5877bd360 218 * @Param : CLASS_A or CLASS_C
fahadmirza 0:a0c5877bd360 219 * @Retval : AT_OK if successful, otherwise other eAtStatus_t
fahadmirza 0:a0c5877bd360 220 ******************************************************************************/
fahadmirza 10:19da323c2bc0 221 static eAtStatus_t Lora_setClass(char class)
fahadmirza 0:a0c5877bd360 222 {
fahadmirza 0:a0c5877bd360 223 return Modem_AT_Cmd(AT_SET, AT_CLASS, &class);
fahadmirza 0:a0c5877bd360 224 }
fahadmirza 0:a0c5877bd360 225
fahadmirza 0:a0c5877bd360 226 /******************************************************************************
fahadmirza 0:a0c5877bd360 227 * @Brief : Join network and initiate join sleep transition timer
fahadmirza 0:a0c5877bd360 228 * @Param : None
fahadmirza 0:a0c5877bd360 229 * @Retval : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 230 ******************************************************************************/
fahadmirza 0:a0c5877bd360 231 static eAtStatus_t Lora_Join(void)
fahadmirza 0:a0c5877bd360 232 {
fahadmirza 0:a0c5877bd360 233 return Modem_AT_Cmd(AT_CTRL, AT_JOIN, NULL);
fahadmirza 0:a0c5877bd360 234 }
fahadmirza 0:a0c5877bd360 235
fahadmirza 0:a0c5877bd360 236 /******************************************************************************
fahadmirza 0:a0c5877bd360 237 * @Brief : Check JOIN status
fahadmirza 0:a0c5877bd360 238 * @Param : None
fahadmirza 0:a0c5877bd360 239 * @Retval : JOINED or NOT_JOINED
fahadmirza 0:a0c5877bd360 240 ******************************************************************************/
fahadmirza 0:a0c5877bd360 241 static eJoinStatus_t Lora_getJoinStatus(void)
fahadmirza 0:a0c5877bd360 242 {
fahadmirza 0:a0c5877bd360 243 char joinStatus[12]; // "NOT JOINED" is 10 characters + 1 Null char
fahadmirza 0:a0c5877bd360 244
fahadmirza 0:a0c5877bd360 245 Modem_AT_Cmd(AT_GET, AT_NJS, joinStatus);
fahadmirza 0:a0c5877bd360 246
fahadmirza 0:a0c5877bd360 247 if(strncmp("JOINED", joinStatus, 6) == 0)
fahadmirza 0:a0c5877bd360 248 {
fahadmirza 0:a0c5877bd360 249 return JOINED;
fahadmirza 0:a0c5877bd360 250 }
fahadmirza 0:a0c5877bd360 251
fahadmirza 0:a0c5877bd360 252 return NOT_JOINED;
fahadmirza 0:a0c5877bd360 253 }
fahadmirza 0:a0c5877bd360 254
fahadmirza 0:a0c5877bd360 255 /******************************************************************************
fahadmirza 28:c777d977b252 256 * @Brief : Get firmware version
fahadmirza 28:c777d977b252 257 * @Param : None
fahadmirza 28:c777d977b252 258 * @Retval : Integer firmware version
fahadmirza 28:c777d977b252 259 ******************************************************************************/
fahadmirza 32:2d0678039a09 260 uint16_t Lora_getFwVersion(void)
fahadmirza 28:c777d977b252 261 {
fahadmirza 28:c777d977b252 262 char fwVersion_str[5];
fahadmirza 32:2d0678039a09 263 uint16_t fwVer_int;
fahadmirza 28:c777d977b252 264
fahadmirza 28:c777d977b252 265 eAtStatus_t status = Modem_AT_Cmd(AT_GET, AT_VER, fwVersion_str);
fahadmirza 28:c777d977b252 266
fahadmirza 28:c777d977b252 267 if(status != AT_OK)
fahadmirza 28:c777d977b252 268 {
fahadmirza 28:c777d977b252 269 return 0;
fahadmirza 28:c777d977b252 270 }
fahadmirza 28:c777d977b252 271
fahadmirza 32:2d0678039a09 272 // FW version is a decimal number e.g. 1.18
fahadmirza 32:2d0678039a09 273 // Convert the float number into integer.
fahadmirza 32:2d0678039a09 274 uint8_t i = 0;
fahadmirza 32:2d0678039a09 275 while(fwVersion_str[++i] != '.');
fahadmirza 32:2d0678039a09 276
fahadmirza 32:2d0678039a09 277 while(fwVersion_str[i] != '\0')
fahadmirza 32:2d0678039a09 278 {
fahadmirza 32:2d0678039a09 279 fwVersion_str[i] = fwVersion_str[i + 1];
fahadmirza 32:2d0678039a09 280 i++;
fahadmirza 32:2d0678039a09 281 }
fahadmirza 32:2d0678039a09 282
fahadmirza 32:2d0678039a09 283 tiny_sscanf(fwVersion_str, "%hu", &fwVer_int);
fahadmirza 28:c777d977b252 284
fahadmirza 28:c777d977b252 285 return fwVer_int;
fahadmirza 28:c777d977b252 286 }
fahadmirza 28:c777d977b252 287
fahadmirza 28:c777d977b252 288 /******************************************************************************
fahadmirza 29:b48f6176c2cd 289 * @Brief : Get battery level
fahadmirza 29:b48f6176c2cd 290 * @Param : None
fahadmirza 29:b48f6176c2cd 291 * @Retval : Battery level
fahadmirza 29:b48f6176c2cd 292 ******************************************************************************/
fahadmirza 31:174c745f921c 293 uint8_t Lora_getBatteryLevel(void)
fahadmirza 29:b48f6176c2cd 294 {
fahadmirza 29:b48f6176c2cd 295 char batteryLevel_str[5];
fahadmirza 29:b48f6176c2cd 296 uint8_t batteryLevel = 0;
fahadmirza 29:b48f6176c2cd 297
fahadmirza 29:b48f6176c2cd 298 eAtStatus_t status = Modem_AT_Cmd(AT_GET, AT_BAT, batteryLevel_str);
fahadmirza 29:b48f6176c2cd 299
fahadmirza 29:b48f6176c2cd 300 if(status == AT_OK)
fahadmirza 29:b48f6176c2cd 301 {
fahadmirza 32:2d0678039a09 302 tiny_sscanf(batteryLevel_str, "%hhu", &batteryLevel);
fahadmirza 29:b48f6176c2cd 303 }
fahadmirza 29:b48f6176c2cd 304
fahadmirza 29:b48f6176c2cd 305 return batteryLevel;
fahadmirza 29:b48f6176c2cd 306 }
fahadmirza 29:b48f6176c2cd 307
fahadmirza 29:b48f6176c2cd 308 /******************************************************************************
fahadmirza 32:2d0678039a09 309 * @Brief : Update the uplink rate
fahadmirza 32:2d0678039a09 310 * @Param : time_s seconds
fahadmirza 32:2d0678039a09 311 * @Retval : None
fahadmirza 32:2d0678039a09 312 ******************************************************************************/
fahadmirza 32:2d0678039a09 313 void Lora_updateUplinkRate(uint32_t time_s)
fahadmirza 32:2d0678039a09 314 {
fahadmirza 32:2d0678039a09 315 TimerSetValue(&SensorMeasureTimer, (time_s * 1000));
fahadmirza 32:2d0678039a09 316 TimerReset(&SensorMeasureTimer);
fahadmirza 32:2d0678039a09 317 }
fahadmirza 32:2d0678039a09 318
fahadmirza 32:2d0678039a09 319 /******************************************************************************
fahadmirza 0:a0c5877bd360 320 * @Brief : Send uplink packet using binary payload
fahadmirza 0:a0c5877bd360 321 * @Param : Pointer of sSendDataBinary_t variable
fahadmirza 0:a0c5877bd360 322 * @Retval : AT_OK or other eAtStatus_t statuses
fahadmirza 0:a0c5877bd360 323 ******************************************************************************/
fahadmirza 0:a0c5877bd360 324 static eAtStatus_t Lora_SendDataBinary(sSendDataBinary_t *binaryData)
fahadmirza 0:a0c5877bd360 325 {
fahadmirza 0:a0c5877bd360 326 return Modem_AT_Cmd(AT_SET, AT_SENDB, binaryData);
fahadmirza 0:a0c5877bd360 327 }
fahadmirza 0:a0c5877bd360 328
fahadmirza 0:a0c5877bd360 329 /******************************************************************************
fahadmirza 10:19da323c2bc0 330 * @Brief : Read the received downlink packet
fahadmirza 10:19da323c2bc0 331 * @Param : Pointer to sRecvDataBinary_t variable
fahadmirza 32:2d0678039a09 332 * @Return : AT_OK or other eAtStatus_t statuses
fahadmirza 10:19da323c2bc0 333 ******************************************************************************/
fahadmirza 32:2d0678039a09 334 static eAtStatus_t Lora_ReadData(sRecvDataBinary_t *rxData)
fahadmirza 10:19da323c2bc0 335 {
fahadmirza 32:2d0678039a09 336 char *rxString = Modem_GetResponseBuffer();
fahadmirza 32:2d0678039a09 337
fahadmirza 32:2d0678039a09 338 // Find the position after :
fahadmirza 32:2d0678039a09 339 // e.g. rxdata:0,1,86GF25
fahadmirza 32:2d0678039a09 340 rxString = (strchr(rxString,':') + 1);
fahadmirza 10:19da323c2bc0 341
fahadmirza 32:2d0678039a09 342 if(rxString == NULL)
fahadmirza 32:2d0678039a09 343 {
fahadmirza 32:2d0678039a09 344 return AT_ERROR;
fahadmirza 32:2d0678039a09 345 }
fahadmirza 10:19da323c2bc0 346
fahadmirza 32:2d0678039a09 347 if(tiny_sscanf(rxString, "%hhu,%hhu", &(rxData->Ack), &(rxData->Port)) != 2)
fahadmirza 32:2d0678039a09 348 {
fahadmirza 32:2d0678039a09 349 return AT_ERROR;
fahadmirza 32:2d0678039a09 350 }
fahadmirza 10:19da323c2bc0 351
fahadmirza 10:19da323c2bc0 352 // Find the position after the second comma
fahadmirza 32:2d0678039a09 353 rxString = strchr((strchr(rxString,',') + 1),',') + 1;
fahadmirza 32:2d0678039a09 354 if(rxString == NULL)
fahadmirza 32:2d0678039a09 355 {
fahadmirza 32:2d0678039a09 356 return AT_ERROR;
fahadmirza 32:2d0678039a09 357 }
fahadmirza 10:19da323c2bc0 358
fahadmirza 32:2d0678039a09 359 rxData->DataSize = stringHexToByteArray(rxString, rxData->Buffer, MAX_PAYLOAD_SIZE);
fahadmirza 32:2d0678039a09 360
fahadmirza 32:2d0678039a09 361 return AT_OK;
fahadmirza 10:19da323c2bc0 362 }
fahadmirza 10:19da323c2bc0 363
fahadmirza 10:19da323c2bc0 364 /******************************************************************************
fahadmirza 0:a0c5877bd360 365 * @Brief : LoRa Modem state machine
fahadmirza 0:a0c5877bd360 366 * @Param : Void
fahadmirza 0:a0c5877bd360 367 * @Return : None
fahadmirza 0:a0c5877bd360 368 ******************************************************************************/
fahadmirza 0:a0c5877bd360 369 void Lora_fsm(void)
fahadmirza 0:a0c5877bd360 370 {
fahadmirza 0:a0c5877bd360 371 switch(DeviceState)
fahadmirza 0:a0c5877bd360 372 {
fahadmirza 26:176e648c03f6 373 case CLIENT_INIT:
fahadmirza 0:a0c5877bd360 374 {
fahadmirza 0:a0c5877bd360 375 if(is_modem_working() != AT_OK)
fahadmirza 0:a0c5877bd360 376 {
fahadmirza 1:168a6afffbff 377 DBG_PRINTF("AT failed. Resetting HW...\r\n");
fahadmirza 0:a0c5877bd360 378 // Modem isn't responding. Execute hard reset.
fahadmirza 0:a0c5877bd360 379 Modem_HardReset();
fahadmirza 27:517ca3a30ad7 380 // We stay in CLIENT_INIT state and try again.
fahadmirza 0:a0c5877bd360 381 }
fahadmirza 0:a0c5877bd360 382 else
fahadmirza 0:a0c5877bd360 383 {
fahadmirza 26:176e648c03f6 384 DeviceState = CLIENT_CONFIG;
fahadmirza 0:a0c5877bd360 385 }
fahadmirza 0:a0c5877bd360 386
fahadmirza 0:a0c5877bd360 387 break;
fahadmirza 0:a0c5877bd360 388 }
fahadmirza 26:176e648c03f6 389 case CLIENT_CONFIG:
fahadmirza 0:a0c5877bd360 390 {
fahadmirza 24:f3b987589609 391 eAtStatus_t loraModemRetCode = Lora_setDevEui(LoraConfigParam->DevEui);
fahadmirza 24:f3b987589609 392 loraModemRetCode |= Lora_setAppEui(LoraConfigParam->AppEui);
fahadmirza 24:f3b987589609 393 loraModemRetCode |= Lora_setAppKey(LoraConfigParam->AppKey);
fahadmirza 24:f3b987589609 394 loraModemRetCode |= Lora_setJoinMode(LoraConfigParam->JoinMode);
fahadmirza 24:f3b987589609 395 loraModemRetCode |= Lora_setClass(LoraConfigParam->Class);
fahadmirza 28:c777d977b252 396 loraModemRetCode |= Lora_setAdr(LoraConfigParam->AdrStatus);
fahadmirza 0:a0c5877bd360 397
fahadmirza 0:a0c5877bd360 398 if(loraModemRetCode == AT_OK)
fahadmirza 0:a0c5877bd360 399 {
fahadmirza 28:c777d977b252 400 // If users use AUTO as Device EUI, print the DevEUI
fahadmirza 28:c777d977b252 401 // so that they can add that on X-ON
fahadmirza 28:c777d977b252 402 Lora_printDevEui();
fahadmirza 28:c777d977b252 403
fahadmirza 0:a0c5877bd360 404 setJoinRequestTimer();
fahadmirza 26:176e648c03f6 405 DeviceState = CLIENT_SLEEP;
fahadmirza 0:a0c5877bd360 406 }
fahadmirza 0:a0c5877bd360 407 else if(loraModemRetCode == AT_TIMEOUT)
fahadmirza 0:a0c5877bd360 408 {
fahadmirza 26:176e648c03f6 409 DeviceState = CLIENT_INIT;
fahadmirza 0:a0c5877bd360 410 }
fahadmirza 0:a0c5877bd360 411 else
fahadmirza 0:a0c5877bd360 412 {
fahadmirza 0:a0c5877bd360 413 DBG_PRINTF("Check your keys\r\n");
fahadmirza 27:517ca3a30ad7 414 while(1);
fahadmirza 0:a0c5877bd360 415 }
fahadmirza 0:a0c5877bd360 416
fahadmirza 0:a0c5877bd360 417 break;
fahadmirza 0:a0c5877bd360 418 }
fahadmirza 26:176e648c03f6 419 case CLIENT_JOIN:
fahadmirza 0:a0c5877bd360 420 {
fahadmirza 1:168a6afffbff 421 DBG_PRINTF("Joining...\r\n");
fahadmirza 32:2d0678039a09 422 HXC_BSP_RGB_Off();
fahadmirza 0:a0c5877bd360 423
fahadmirza 0:a0c5877bd360 424 switch(Lora_Join())
fahadmirza 0:a0c5877bd360 425 {
fahadmirza 0:a0c5877bd360 426 case AT_OK:
fahadmirza 0:a0c5877bd360 427 {
fahadmirza 0:a0c5877bd360 428 // Start the Join status request timer and go to sleep
fahadmirza 32:2d0678039a09 429 TimerStart(&JoinStatusReqTimer);
fahadmirza 26:176e648c03f6 430 DeviceState = CLIENT_SLEEP;
fahadmirza 0:a0c5877bd360 431 break;
fahadmirza 0:a0c5877bd360 432 }
fahadmirza 0:a0c5877bd360 433 case AT_TIMEOUT:
fahadmirza 0:a0c5877bd360 434 {
fahadmirza 21:f1d561ed31a1 435 // The modem isn't responding. Execute hard reset
fahadmirza 26:176e648c03f6 436 DeviceState = CLIENT_INIT;
fahadmirza 0:a0c5877bd360 437 break;
fahadmirza 0:a0c5877bd360 438 }
fahadmirza 0:a0c5877bd360 439 default:
fahadmirza 0:a0c5877bd360 440 {
fahadmirza 0:a0c5877bd360 441 DBG_PRINTF("Join cmd failed\n");
fahadmirza 27:517ca3a30ad7 442 // We stay in CLIENT_JOIN state and redo Lora_Join()
fahadmirza 0:a0c5877bd360 443 break;
fahadmirza 0:a0c5877bd360 444 }
fahadmirza 0:a0c5877bd360 445 }
fahadmirza 0:a0c5877bd360 446
fahadmirza 0:a0c5877bd360 447 break;
fahadmirza 0:a0c5877bd360 448 }
fahadmirza 26:176e648c03f6 449 case CLIENT_JOIN_STATUS_CHECK:
fahadmirza 0:a0c5877bd360 450 {
fahadmirza 0:a0c5877bd360 451 if(Lora_getJoinStatus() == JOINED)
fahadmirza 0:a0c5877bd360 452 {
fahadmirza 32:2d0678039a09 453 // Indicate Join status using LED
fahadmirza 32:2d0678039a09 454 HXC_BSP_RGB_On(PINK);
fahadmirza 0:a0c5877bd360 455 DBG_PRINTF("Nwk Joined\n");
fahadmirza 32:2d0678039a09 456 Lora_printDevAdr();
fahadmirza 17:e682a18c3914 457
fahadmirza 17:e682a18c3914 458 // Start timer for Re-Authentication
fahadmirza 32:2d0678039a09 459 TimerStart(&RejoinTimer);
fahadmirza 17:e682a18c3914 460
fahadmirza 0:a0c5877bd360 461 // Start timer for uplink transmission for sensor-data
fahadmirza 32:2d0678039a09 462 TimerStart(&SensorMeasureTimer);
fahadmirza 26:176e648c03f6 463 DeviceState = CLIENT_SLEEP;
fahadmirza 0:a0c5877bd360 464 }
fahadmirza 0:a0c5877bd360 465 else
fahadmirza 0:a0c5877bd360 466 {
fahadmirza 0:a0c5877bd360 467 // Try joining again
fahadmirza 0:a0c5877bd360 468 setJoinRequestTimer();
fahadmirza 26:176e648c03f6 469 DeviceState = CLIENT_SLEEP;
fahadmirza 0:a0c5877bd360 470 }
fahadmirza 0:a0c5877bd360 471 break;
fahadmirza 0:a0c5877bd360 472 }
fahadmirza 26:176e648c03f6 473 case CLIENT_SLEEP:
fahadmirza 0:a0c5877bd360 474 {
fahadmirza 0:a0c5877bd360 475 /* Wake up through RTC events or asynchronous event coming from HXC modem*/
fahadmirza 0:a0c5877bd360 476 if(Modem_IsNewDataReceived() == true)
fahadmirza 0:a0c5877bd360 477 {
fahadmirza 26:176e648c03f6 478 DeviceState = CLIENT_DATA_RECEIVED;
fahadmirza 0:a0c5877bd360 479 }
fahadmirza 0:a0c5877bd360 480 break;
fahadmirza 0:a0c5877bd360 481 }
fahadmirza 26:176e648c03f6 482 case CLIENT_SEND:
fahadmirza 0:a0c5877bd360 483 {
fahadmirza 0:a0c5877bd360 484 // Read sensor data and populate payload
fahadmirza 32:2d0678039a09 485 SendDataBinary.DataSize = LoraDriverParam->UplinkHandler(\
fahadmirza 32:2d0678039a09 486 SendDataBinary.Buffer ,\
fahadmirza 32:2d0678039a09 487 MAX_PAYLOAD_SIZE ,\
fahadmirza 32:2d0678039a09 488 &SendDataBinary.Ack ,\
fahadmirza 32:2d0678039a09 489 &SendDataBinary.Port );
fahadmirza 28:c777d977b252 490
fahadmirza 0:a0c5877bd360 491 // Initiate uplink transmission
fahadmirza 0:a0c5877bd360 492 eAtStatus_t status = Lora_SendDataBinary(&SendDataBinary);
fahadmirza 28:c777d977b252 493
fahadmirza 0:a0c5877bd360 494 if (status == AT_OK)
fahadmirza 0:a0c5877bd360 495 {
fahadmirza 25:50414f44a431 496 DBG_PRINTF("Uplink sent\n");
fahadmirza 0:a0c5877bd360 497 // Schedule the next packet
fahadmirza 32:2d0678039a09 498 TimerStart(&SensorMeasureTimer);
fahadmirza 26:176e648c03f6 499 DeviceState = CLIENT_SLEEP;
fahadmirza 0:a0c5877bd360 500 }
fahadmirza 0:a0c5877bd360 501 else if(status == AT_TIMEOUT)
fahadmirza 0:a0c5877bd360 502 {
fahadmirza 0:a0c5877bd360 503 // Device isn't responding. Go to init.
fahadmirza 26:176e648c03f6 504 DeviceState = CLIENT_INIT;
fahadmirza 0:a0c5877bd360 505 }
fahadmirza 32:2d0678039a09 506 else if(status == AT_NO_NET_JOINED)
fahadmirza 32:2d0678039a09 507 {
fahadmirza 32:2d0678039a09 508 DeviceState = CLIENT_JOIN;
fahadmirza 32:2d0678039a09 509 }
fahadmirza 25:50414f44a431 510 else
fahadmirza 25:50414f44a431 511 {
fahadmirza 25:50414f44a431 512 DBG_PRINTF("Uplink Failed (Error: %d)\n", (uint8_t)status);
fahadmirza 25:50414f44a431 513 }
fahadmirza 0:a0c5877bd360 514 break;
fahadmirza 0:a0c5877bd360 515 }
fahadmirza 26:176e648c03f6 516 case CLIENT_DATA_RECEIVED:
fahadmirza 0:a0c5877bd360 517 {
fahadmirza 0:a0c5877bd360 518 uint8_t rBuffer[64];
fahadmirza 0:a0c5877bd360 519 sRecvDataBinary_t rxPacket = {.Buffer = rBuffer};
fahadmirza 0:a0c5877bd360 520
fahadmirza 32:2d0678039a09 521 if(Lora_ReadData(&rxPacket) == AT_OK)
fahadmirza 32:2d0678039a09 522 {
fahadmirza 32:2d0678039a09 523 // Execute users ReceivedPacketHandler function
fahadmirza 32:2d0678039a09 524 LoraDriverParam->DownlinkHandler(rxPacket.Buffer, rxPacket.DataSize, rxPacket.Ack, rxPacket.Port);
fahadmirza 32:2d0678039a09 525 }
fahadmirza 32:2d0678039a09 526 else
fahadmirza 32:2d0678039a09 527 {
fahadmirza 32:2d0678039a09 528 DBG_PRINTF("Dwlink read failed\n");
fahadmirza 32:2d0678039a09 529 }
fahadmirza 0:a0c5877bd360 530
fahadmirza 26:176e648c03f6 531 DeviceState = CLIENT_SLEEP;
fahadmirza 0:a0c5877bd360 532 break;
fahadmirza 0:a0c5877bd360 533 }
fahadmirza 0:a0c5877bd360 534 default:
fahadmirza 0:a0c5877bd360 535 {
fahadmirza 26:176e648c03f6 536 DeviceState = CLIENT_INIT;
fahadmirza 0:a0c5877bd360 537 break;
fahadmirza 0:a0c5877bd360 538 }
fahadmirza 0:a0c5877bd360 539 }
fahadmirza 0:a0c5877bd360 540 }
fahadmirza 0:a0c5877bd360 541
fahadmirza 16:2179ec24dff8 542 /******************************************************************************
fahadmirza 16:2179ec24dff8 543 * @Brief : Set Join request timer
fahadmirza 16:2179ec24dff8 544 * @Param : none
fahadmirza 16:2179ec24dff8 545 * @Return : none
fahadmirza 16:2179ec24dff8 546 ******************************************************************************/
fahadmirza 0:a0c5877bd360 547 static void setJoinRequestTimer(void)
fahadmirza 0:a0c5877bd360 548 {
fahadmirza 0:a0c5877bd360 549 // Use a random delay to avoid synchronized join request from all LoRa node after power up
fahadmirza 0:a0c5877bd360 550 uint32_t joinDelay = (HAL_RNG_GetRandomNumber(&RngHandle) % JOIN_SEND_DELAY_MAX) + 1;
fahadmirza 19:0c90e38fc9c5 551
fahadmirza 32:2d0678039a09 552 TimerSetValue(&JoinRequestTimer, joinDelay);
fahadmirza 32:2d0678039a09 553 TimerStart(&JoinRequestTimer);
fahadmirza 0:a0c5877bd360 554 }
fahadmirza 0:a0c5877bd360 555
fahadmirza 0:a0c5877bd360 556 /******************************************************************************
fahadmirza 0:a0c5877bd360 557 * @Brief : Function executed on JoinStatusDelayTimer Timeout event
fahadmirza 0:a0c5877bd360 558 * @Param : none
fahadmirza 0:a0c5877bd360 559 * @Return : none
fahadmirza 0:a0c5877bd360 560 ******************************************************************************/
fahadmirza 10:19da323c2bc0 561 static void OnJoinRequestTimerEvt(void)
fahadmirza 0:a0c5877bd360 562 {
fahadmirza 0:a0c5877bd360 563 TimerStop(&JoinRequestTimer);
fahadmirza 27:517ca3a30ad7 564 // If this is a re-join SensorMeasureTimer is active
fahadmirza 27:517ca3a30ad7 565 TimerStop(&SensorMeasureTimer);
fahadmirza 27:517ca3a30ad7 566
fahadmirza 26:176e648c03f6 567 DeviceState = CLIENT_JOIN;
fahadmirza 0:a0c5877bd360 568 }
fahadmirza 0:a0c5877bd360 569
fahadmirza 0:a0c5877bd360 570 /******************************************************************************
fahadmirza 0:a0c5877bd360 571 * @Brief : Function executed on JoinStatusDelayTimer Timeout event
fahadmirza 0:a0c5877bd360 572 * @Param : none
fahadmirza 0:a0c5877bd360 573 * @Return : none
fahadmirza 0:a0c5877bd360 574 ******************************************************************************/
fahadmirza 32:2d0678039a09 575 static void OnJoinStatusReqTimerEvt(void)
fahadmirza 0:a0c5877bd360 576 {
fahadmirza 32:2d0678039a09 577 TimerStop(&JoinStatusReqTimer);
fahadmirza 26:176e648c03f6 578 DeviceState = CLIENT_JOIN_STATUS_CHECK;
fahadmirza 0:a0c5877bd360 579 }
fahadmirza 0:a0c5877bd360 580
fahadmirza 0:a0c5877bd360 581 /******************************************************************************
fahadmirza 0:a0c5877bd360 582 * @Brief : Function executed on SensorMeasureTimer Timeout event
fahadmirza 0:a0c5877bd360 583 * @Param : none
fahadmirza 0:a0c5877bd360 584 * @Return : none
fahadmirza 0:a0c5877bd360 585 ******************************************************************************/
fahadmirza 10:19da323c2bc0 586 static void OnSensorMeasureTimerEvt(void)
fahadmirza 0:a0c5877bd360 587 {
fahadmirza 25:50414f44a431 588 TimerStop(&SensorMeasureTimer);
fahadmirza 26:176e648c03f6 589 DeviceState = CLIENT_SEND;
fahadmirza 0:a0c5877bd360 590 }
fahadmirza 0:a0c5877bd360 591
fahadmirza 0:a0c5877bd360 592 /******************************************************************************
fahadmirza 17:e682a18c3914 593 * @Brief : Function executed on RejoinTimer Timeout event
fahadmirza 17:e682a18c3914 594 * @Param : none
fahadmirza 17:e682a18c3914 595 * @Return : none
fahadmirza 17:e682a18c3914 596 ******************************************************************************/
fahadmirza 17:e682a18c3914 597 static void OnRejoinTimerEvent(void)
fahadmirza 17:e682a18c3914 598 {
fahadmirza 27:517ca3a30ad7 599 TimerStop(&RejoinTimer);
fahadmirza 17:e682a18c3914 600 setJoinRequestTimer();
fahadmirza 17:e682a18c3914 601 }
fahadmirza 17:e682a18c3914 602
fahadmirza 17:e682a18c3914 603 /******************************************************************************
fahadmirza 0:a0c5877bd360 604 * @brief RNG MSP Initialization
fahadmirza 0:a0c5877bd360 605 * This function configures the hardware resources used in this example:
fahadmirza 0:a0c5877bd360 606 * - Peripheral's clock enable
fahadmirza 0:a0c5877bd360 607 * @param hrng: RNG handle pointer
fahadmirza 0:a0c5877bd360 608 * @retval None
fahadmirza 0:a0c5877bd360 609 ******************************************************************************/
fahadmirza 0:a0c5877bd360 610 void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
fahadmirza 0:a0c5877bd360 611 {
fahadmirza 0:a0c5877bd360 612 /* RNG Peripheral clock enable */
fahadmirza 0:a0c5877bd360 613 __HAL_RCC_RNG_CLK_ENABLE();
fahadmirza 0:a0c5877bd360 614 }
fahadmirza 0:a0c5877bd360 615
fahadmirza 0:a0c5877bd360 616