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

Dependencies:   mbed

Committer:
fahadmirza
Date:
Tue Jul 24 02:15:45 2018 +0000
Revision:
12:f1fd61aa85e0
Parent:
10:19da323c2bc0
Child:
16:2179ec24dff8
RGB LED will indicate join status;

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 0:a0c5877bd360 14 * @Modified: 12-Apr-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 0:a0c5877bd360 54
fahadmirza 0:a0c5877bd360 55 /* Private Macros ------------------------------------------------------------*/
fahadmirza 0:a0c5877bd360 56 #define JOIN_SEND_DELAY_MAX (10000U) // Randomization range - 10s
fahadmirza 0:a0c5877bd360 57 #define JOIN_STATUS_REQ_DELAY (7000U) // milliseconds. Join req takes 6s.
fahadmirza 0:a0c5877bd360 58
fahadmirza 0:a0c5877bd360 59 /* Private global variables --------------------------------------------------*/
fahadmirza 0:a0c5877bd360 60 static sLoraConfig_t *LoraConfigParam;
fahadmirza 0:a0c5877bd360 61 static sLoraDriverParam_t *LoraDriverParam;
fahadmirza 0:a0c5877bd360 62 static volatile eDeviceState_t DeviceState = DEVICE_INIT;
fahadmirza 0:a0c5877bd360 63
fahadmirza 0:a0c5877bd360 64 static TimerEvent_t JoinRequestTimer;
fahadmirza 0:a0c5877bd360 65 static TimerEvent_t SensorMeasureTimer;
fahadmirza 0:a0c5877bd360 66 static TimerEvent_t NucleoLedTimer;
fahadmirza 0:a0c5877bd360 67 static TimerEvent_t JoinStatusDelayTimer;
fahadmirza 0:a0c5877bd360 68
fahadmirza 0:a0c5877bd360 69 // Object definition for data to be sent to loRa application server
fahadmirza 0:a0c5877bd360 70 static uint8_t DataBinaryBuff[64];
fahadmirza 0:a0c5877bd360 71 static sSendDataBinary_t SendDataBinary = {DataBinaryBuff, 0 , 0, 0};
fahadmirza 0:a0c5877bd360 72
fahadmirza 0:a0c5877bd360 73 // RNG handler declaration
fahadmirza 0:a0c5877bd360 74 RNG_HandleTypeDef RngHandle = {.Instance = RNG};
fahadmirza 0:a0c5877bd360 75
fahadmirza 0:a0c5877bd360 76 /* Private functions ---------------------------------------------------------*/
fahadmirza 10:19da323c2bc0 77 static void OnLedTimerEvent(void);
fahadmirza 10:19da323c2bc0 78 static void OnJoinRequestTimerEvt(void);
fahadmirza 10:19da323c2bc0 79 static void OnJoinStatusDelayTimerEvt(void);
fahadmirza 10:19da323c2bc0 80 static void OnSensorMeasureTimerEvt(void);
fahadmirza 0:a0c5877bd360 81 static void setJoinRequestTimer(void);
fahadmirza 0:a0c5877bd360 82
fahadmirza 0:a0c5877bd360 83
fahadmirza 0:a0c5877bd360 84 /* Function definitions ------------------------------------------------------*/
fahadmirza 0:a0c5877bd360 85 /******************************************************************************
fahadmirza 0:a0c5877bd360 86 * @Brief : Initialize LoRa Modem
fahadmirza 0:a0c5877bd360 87 * @Param : sLoraConfig_t
fahadmirza 0:a0c5877bd360 88 * @Return : none
fahadmirza 0:a0c5877bd360 89 ******************************************************************************/
fahadmirza 0:a0c5877bd360 90 void Lora_init(sLoraConfig_t *loraConfig, sLoraDriverParam_t *loraDriverParam)
fahadmirza 0:a0c5877bd360 91 {
fahadmirza 0:a0c5877bd360 92
fahadmirza 0:a0c5877bd360 93 LoraConfigParam = loraConfig;
fahadmirza 0:a0c5877bd360 94 LoraDriverParam = loraDriverParam;
fahadmirza 0:a0c5877bd360 95
fahadmirza 0:a0c5877bd360 96 if(Modem_Init() != AT_OK)
fahadmirza 0:a0c5877bd360 97 {
fahadmirza 0:a0c5877bd360 98 DBG_PRINTF("Modem_Init failed\r\n");
fahadmirza 0:a0c5877bd360 99 }
fahadmirza 0:a0c5877bd360 100
fahadmirza 0:a0c5877bd360 101 // Initialize RNG for join request send randomization
fahadmirza 0:a0c5877bd360 102 HAL_RNG_Init(&RngHandle);
fahadmirza 0:a0c5877bd360 103
fahadmirza 0:a0c5877bd360 104
fahadmirza 0:a0c5877bd360 105 // Timer for join request send
fahadmirza 10:19da323c2bc0 106 TimerInit(&JoinRequestTimer, OnJoinRequestTimerEvt);
fahadmirza 0:a0c5877bd360 107 // Timer for join status check
fahadmirza 10:19da323c2bc0 108 TimerInit(&JoinStatusDelayTimer, OnJoinStatusDelayTimerEvt);
fahadmirza 0:a0c5877bd360 109 // Timer for sensor occurrence measure
fahadmirza 10:19da323c2bc0 110 TimerInit(&SensorMeasureTimer, OnSensorMeasureTimerEvt);
fahadmirza 0:a0c5877bd360 111 // Timer for Nucleo LED
fahadmirza 10:19da323c2bc0 112 TimerInit(&NucleoLedTimer, OnLedTimerEvent);
fahadmirza 0:a0c5877bd360 113 }
fahadmirza 0:a0c5877bd360 114
fahadmirza 0:a0c5877bd360 115 /******************************************************************************
fahadmirza 0:a0c5877bd360 116 * @Brief : Check if the modem responds
fahadmirza 0:a0c5877bd360 117 * @Param : void
fahadmirza 0:a0c5877bd360 118 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 119 ******************************************************************************/
fahadmirza 0:a0c5877bd360 120 static eAtStatus_t is_modem_working(void)
fahadmirza 0:a0c5877bd360 121 {
fahadmirza 0:a0c5877bd360 122 return Modem_AT_Cmd(AT_CTRL, AT, NULL);
fahadmirza 0:a0c5877bd360 123 }
fahadmirza 0:a0c5877bd360 124
fahadmirza 0:a0c5877bd360 125 /******************************************************************************
fahadmirza 0:a0c5877bd360 126 * @Brief : Set Device EUI
fahadmirza 0:a0c5877bd360 127 * @Param : Pointer to Device EUI
fahadmirza 0:a0c5877bd360 128 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 129 ******************************************************************************/
fahadmirza 10:19da323c2bc0 130 static eAtStatus_t Lora_setDevEui(char *devEui)
fahadmirza 0:a0c5877bd360 131 {
fahadmirza 0:a0c5877bd360 132 return Modem_AT_Cmd(AT_SET, AT_DEVEUI, devEui);
fahadmirza 0:a0c5877bd360 133 }
fahadmirza 0:a0c5877bd360 134
fahadmirza 0:a0c5877bd360 135 /******************************************************************************
fahadmirza 2:1ef859bc5cd2 136 * @Brief : Turn on or off ADR
fahadmirza 2:1ef859bc5cd2 137 * @Param : ADR_ON or ADR_OFF
fahadmirza 2:1ef859bc5cd2 138 * @Return : AT_OK or other eAtStatus_t
fahadmirza 2:1ef859bc5cd2 139 ******************************************************************************/
fahadmirza 10:19da323c2bc0 140 static eAtStatus_t Lora_setAdr(eAdrStatus_t adrStatus)
fahadmirza 2:1ef859bc5cd2 141 {
fahadmirza 2:1ef859bc5cd2 142 //char adr = (adrStatus == ADR_ON ? '1' : '0');
fahadmirza 2:1ef859bc5cd2 143 return Modem_AT_Cmd(AT_SET, AT_ADR, (uint8_t *)(&adrStatus));
fahadmirza 2:1ef859bc5cd2 144 }
fahadmirza 2:1ef859bc5cd2 145
fahadmirza 2:1ef859bc5cd2 146 /******************************************************************************
fahadmirza 0:a0c5877bd360 147 * @Brief : Set Application EUI
fahadmirza 0:a0c5877bd360 148 * @Param : Pointer to Application EUI
fahadmirza 0:a0c5877bd360 149 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 150 ******************************************************************************/
fahadmirza 10:19da323c2bc0 151 static eAtStatus_t Lora_setAppEui(char *appEui)
fahadmirza 0:a0c5877bd360 152 {
fahadmirza 0:a0c5877bd360 153 return Modem_AT_Cmd(AT_SET, AT_APPEUI, appEui);
fahadmirza 0:a0c5877bd360 154 }
fahadmirza 0:a0c5877bd360 155
fahadmirza 0:a0c5877bd360 156 /******************************************************************************
fahadmirza 0:a0c5877bd360 157 * @Brief : Set Application Key
fahadmirza 0:a0c5877bd360 158 * @Param : Pointer to Application Key
fahadmirza 0:a0c5877bd360 159 * @Return : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 160 ******************************************************************************/
fahadmirza 10:19da323c2bc0 161 static eAtStatus_t Lora_setAppKey(char *appKey)
fahadmirza 0:a0c5877bd360 162 {
fahadmirza 0:a0c5877bd360 163 return Modem_AT_Cmd(AT_SET, AT_APPKEY, appKey);
fahadmirza 0:a0c5877bd360 164 }
fahadmirza 0:a0c5877bd360 165
fahadmirza 0:a0c5877bd360 166 /******************************************************************************
fahadmirza 0:a0c5877bd360 167 * @Brief : Set join mode
fahadmirza 0:a0c5877bd360 168 * @Param : OTAA or ABP
fahadmirza 0:a0c5877bd360 169 * @Retval : AT_OK if successful, otherwise other eAtStatus_t
fahadmirza 0:a0c5877bd360 170 ******************************************************************************/
fahadmirza 10:19da323c2bc0 171 static eAtStatus_t Lora_setJoinMode(eJoinMode_t joinMode)
fahadmirza 0:a0c5877bd360 172 {
fahadmirza 0:a0c5877bd360 173 if(joinMode == OTAA)
fahadmirza 0:a0c5877bd360 174 {
fahadmirza 0:a0c5877bd360 175 return Modem_AT_Cmd(AT_SET, AT_NJM, "OTAA");
fahadmirza 0:a0c5877bd360 176 }
fahadmirza 0:a0c5877bd360 177
fahadmirza 0:a0c5877bd360 178 return Modem_AT_Cmd(AT_SET, AT_NJM, "ABP");
fahadmirza 0:a0c5877bd360 179 }
fahadmirza 0:a0c5877bd360 180
fahadmirza 0:a0c5877bd360 181 /******************************************************************************
fahadmirza 0:a0c5877bd360 182 * @Brief : Set Class
fahadmirza 0:a0c5877bd360 183 * @Param : CLASS_A or CLASS_C
fahadmirza 0:a0c5877bd360 184 * @Retval : AT_OK if successful, otherwise other eAtStatus_t
fahadmirza 0:a0c5877bd360 185 ******************************************************************************/
fahadmirza 10:19da323c2bc0 186 static eAtStatus_t Lora_setClass(char class)
fahadmirza 0:a0c5877bd360 187 {
fahadmirza 0:a0c5877bd360 188 return Modem_AT_Cmd(AT_SET, AT_CLASS, &class);
fahadmirza 0:a0c5877bd360 189 }
fahadmirza 0:a0c5877bd360 190
fahadmirza 0:a0c5877bd360 191 /******************************************************************************
fahadmirza 0:a0c5877bd360 192 * @Brief : Join network and initiate join sleep transition timer
fahadmirza 0:a0c5877bd360 193 * @Param : None
fahadmirza 0:a0c5877bd360 194 * @Retval : AT_OK or other eAtStatus_t
fahadmirza 0:a0c5877bd360 195 ******************************************************************************/
fahadmirza 0:a0c5877bd360 196 static eAtStatus_t Lora_Join(void)
fahadmirza 0:a0c5877bd360 197 {
fahadmirza 0:a0c5877bd360 198 return Modem_AT_Cmd(AT_CTRL, AT_JOIN, NULL);
fahadmirza 0:a0c5877bd360 199 }
fahadmirza 0:a0c5877bd360 200
fahadmirza 0:a0c5877bd360 201 /******************************************************************************
fahadmirza 0:a0c5877bd360 202 * @Brief : Check JOIN status
fahadmirza 0:a0c5877bd360 203 * @Param : None
fahadmirza 0:a0c5877bd360 204 * @Retval : JOINED or NOT_JOINED
fahadmirza 0:a0c5877bd360 205 ******************************************************************************/
fahadmirza 0:a0c5877bd360 206 static eJoinStatus_t Lora_getJoinStatus(void)
fahadmirza 0:a0c5877bd360 207 {
fahadmirza 0:a0c5877bd360 208 char joinStatus[12]; // "NOT JOINED" is 10 characters + 1 Null char
fahadmirza 0:a0c5877bd360 209
fahadmirza 0:a0c5877bd360 210 Modem_AT_Cmd(AT_GET, AT_NJS, joinStatus);
fahadmirza 0:a0c5877bd360 211
fahadmirza 0:a0c5877bd360 212 if(strncmp("JOINED", joinStatus, 6) == 0)
fahadmirza 0:a0c5877bd360 213 {
fahadmirza 0:a0c5877bd360 214 return JOINED;
fahadmirza 0:a0c5877bd360 215 }
fahadmirza 0:a0c5877bd360 216
fahadmirza 0:a0c5877bd360 217 return NOT_JOINED;
fahadmirza 0:a0c5877bd360 218 }
fahadmirza 0:a0c5877bd360 219
fahadmirza 0:a0c5877bd360 220 /******************************************************************************
fahadmirza 0:a0c5877bd360 221 * @Brief : Send uplink packet using binary payload
fahadmirza 0:a0c5877bd360 222 * @Param : Pointer of sSendDataBinary_t variable
fahadmirza 0:a0c5877bd360 223 * @Retval : AT_OK or other eAtStatus_t statuses
fahadmirza 0:a0c5877bd360 224 ******************************************************************************/
fahadmirza 0:a0c5877bd360 225 static eAtStatus_t Lora_SendDataBinary(sSendDataBinary_t *binaryData)
fahadmirza 0:a0c5877bd360 226 {
fahadmirza 0:a0c5877bd360 227 return Modem_AT_Cmd(AT_SET, AT_SENDB, binaryData);
fahadmirza 0:a0c5877bd360 228 }
fahadmirza 0:a0c5877bd360 229
fahadmirza 0:a0c5877bd360 230 /******************************************************************************
fahadmirza 10:19da323c2bc0 231 * @Brief : Read the received downlink packet
fahadmirza 10:19da323c2bc0 232 * @Param : Pointer to sRecvDataBinary_t variable
fahadmirza 10:19da323c2bc0 233 * @Return : none
fahadmirza 10:19da323c2bc0 234 ******************************************************************************/
fahadmirza 10:19da323c2bc0 235 static void Lora_ReadData(sRecvDataBinary_t *receivedData)
fahadmirza 10:19da323c2bc0 236 {
fahadmirza 10:19da323c2bc0 237 char receiveString[64];
fahadmirza 10:19da323c2bc0 238
fahadmirza 10:19da323c2bc0 239 Modem_AT_Cmd(AT_GET, AT_RECVB, receiveString);
fahadmirza 10:19da323c2bc0 240
fahadmirza 10:19da323c2bc0 241 tiny_sscanf(receiveString, "%hhu,%hhu", &(receivedData->Ack), &(receivedData->Port));
fahadmirza 10:19da323c2bc0 242
fahadmirza 10:19da323c2bc0 243 // Find the position after the second comma
fahadmirza 10:19da323c2bc0 244 char *hexString = strchr((strchr(receiveString,',') + 1),',') + 1;
fahadmirza 10:19da323c2bc0 245
fahadmirza 10:19da323c2bc0 246 receivedData->DataSize = stringHexToByteArray(hexString, receivedData->Buffer, 64);
fahadmirza 10:19da323c2bc0 247 }
fahadmirza 10:19da323c2bc0 248
fahadmirza 10:19da323c2bc0 249 /******************************************************************************
fahadmirza 10:19da323c2bc0 250 * @Brief : Change Lora_fsm() DeviceState
fahadmirza 10:19da323c2bc0 251 * @Param : Any of eDeviceState_t type
fahadmirza 10:19da323c2bc0 252 * @Return : None
fahadmirza 10:19da323c2bc0 253 ******************************************************************************/
fahadmirza 10:19da323c2bc0 254 void Lora_ChangeDeviceState(eDeviceState_t newDeviceState)
fahadmirza 10:19da323c2bc0 255 {
fahadmirza 10:19da323c2bc0 256 //ToDo: Check for valid eDeviceState_t states
fahadmirza 10:19da323c2bc0 257 DeviceState = newDeviceState;
fahadmirza 10:19da323c2bc0 258 }
fahadmirza 10:19da323c2bc0 259
fahadmirza 10:19da323c2bc0 260 /******************************************************************************
fahadmirza 0:a0c5877bd360 261 * @Brief : LoRa Modem state machine
fahadmirza 0:a0c5877bd360 262 * @Param : Void
fahadmirza 0:a0c5877bd360 263 * @Return : None
fahadmirza 0:a0c5877bd360 264 ******************************************************************************/
fahadmirza 0:a0c5877bd360 265 void Lora_fsm(void)
fahadmirza 0:a0c5877bd360 266 {
fahadmirza 0:a0c5877bd360 267 switch(DeviceState)
fahadmirza 0:a0c5877bd360 268 {
fahadmirza 0:a0c5877bd360 269 case DEVICE_INIT:
fahadmirza 0:a0c5877bd360 270 {
fahadmirza 0:a0c5877bd360 271 if(is_modem_working() != AT_OK)
fahadmirza 0:a0c5877bd360 272 {
fahadmirza 1:168a6afffbff 273 DBG_PRINTF("AT failed. Resetting HW...\r\n");
fahadmirza 0:a0c5877bd360 274 // Modem isn't responding. Execute hard reset.
fahadmirza 0:a0c5877bd360 275 Modem_HardReset();
fahadmirza 0:a0c5877bd360 276 // We stay in DEVICE_INIT state and try again.
fahadmirza 0:a0c5877bd360 277 }
fahadmirza 0:a0c5877bd360 278 else
fahadmirza 0:a0c5877bd360 279 {
fahadmirza 0:a0c5877bd360 280 DeviceState = DEVICE_CONFIG;
fahadmirza 0:a0c5877bd360 281 }
fahadmirza 0:a0c5877bd360 282
fahadmirza 0:a0c5877bd360 283 break;
fahadmirza 0:a0c5877bd360 284 }
fahadmirza 0:a0c5877bd360 285 case DEVICE_CONFIG:
fahadmirza 0:a0c5877bd360 286 {
fahadmirza 0:a0c5877bd360 287 eAtStatus_t loraModemRetCode = Lora_setDevEui(LoraConfigParam->devEui);
fahadmirza 0:a0c5877bd360 288 loraModemRetCode |= Lora_setAppEui(LoraConfigParam->appEui);
fahadmirza 0:a0c5877bd360 289 loraModemRetCode |= Lora_setAppKey(LoraConfigParam->appKey);
fahadmirza 0:a0c5877bd360 290 loraModemRetCode |= Lora_setJoinMode(LoraConfigParam->joinMode);
fahadmirza 0:a0c5877bd360 291 loraModemRetCode |= Lora_setClass(LoraConfigParam->class_);
fahadmirza 10:19da323c2bc0 292 loraModemRetCode |= Lora_setAdr(LoraConfigParam->adrStatus);
fahadmirza 0:a0c5877bd360 293 // ToDo: Maybe add FW version checking
fahadmirza 0:a0c5877bd360 294
fahadmirza 0:a0c5877bd360 295 if(loraModemRetCode == AT_OK)
fahadmirza 0:a0c5877bd360 296 {
fahadmirza 0:a0c5877bd360 297 setJoinRequestTimer();
fahadmirza 0:a0c5877bd360 298 DeviceState = SLEEP_DEVICE;
fahadmirza 0:a0c5877bd360 299 }
fahadmirza 0:a0c5877bd360 300 else if(loraModemRetCode == AT_TIMEOUT)
fahadmirza 0:a0c5877bd360 301 {
fahadmirza 0:a0c5877bd360 302 DeviceState = DEVICE_INIT;
fahadmirza 0:a0c5877bd360 303 }
fahadmirza 0:a0c5877bd360 304 else
fahadmirza 0:a0c5877bd360 305 {
fahadmirza 0:a0c5877bd360 306 DBG_PRINTF("Check your keys\r\n");
fahadmirza 0:a0c5877bd360 307 // We stay in DEVICE_CONFIG and try again
fahadmirza 0:a0c5877bd360 308 }
fahadmirza 0:a0c5877bd360 309
fahadmirza 0:a0c5877bd360 310 break;
fahadmirza 0:a0c5877bd360 311 }
fahadmirza 0:a0c5877bd360 312 case DEVICE_JOIN:
fahadmirza 0:a0c5877bd360 313 {
fahadmirza 1:168a6afffbff 314 DBG_PRINTF("Joining...\r\n");
fahadmirza 0:a0c5877bd360 315 // Indicate a Join request using Nucleo LED
fahadmirza 0:a0c5877bd360 316 BSP_LED_On(LED_GREEN);
fahadmirza 0:a0c5877bd360 317 TimerStart(&NucleoLedTimer, 200);
fahadmirza 0:a0c5877bd360 318
fahadmirza 0:a0c5877bd360 319 switch(Lora_Join())
fahadmirza 0:a0c5877bd360 320 {
fahadmirza 0:a0c5877bd360 321 case AT_OK:
fahadmirza 0:a0c5877bd360 322 {
fahadmirza 0:a0c5877bd360 323 // Start the Join status request timer and go to sleep
fahadmirza 0:a0c5877bd360 324 TimerStart(&JoinStatusDelayTimer, JOIN_STATUS_REQ_DELAY);
fahadmirza 0:a0c5877bd360 325 DeviceState = SLEEP_DEVICE;
fahadmirza 0:a0c5877bd360 326 break;
fahadmirza 0:a0c5877bd360 327 }
fahadmirza 0:a0c5877bd360 328 case AT_TIMEOUT:
fahadmirza 0:a0c5877bd360 329 {
fahadmirza 0:a0c5877bd360 330 // The modem isn't responding. Check if it is working
fahadmirza 0:a0c5877bd360 331 DeviceState = DEVICE_INIT;
fahadmirza 0:a0c5877bd360 332 break;
fahadmirza 0:a0c5877bd360 333 }
fahadmirza 0:a0c5877bd360 334 default:
fahadmirza 0:a0c5877bd360 335 {
fahadmirza 0:a0c5877bd360 336 DBG_PRINTF("Join cmd failed\n");
fahadmirza 0:a0c5877bd360 337 // We stay in DEVICE_JOIN state and redo Lora_Join()
fahadmirza 0:a0c5877bd360 338 break;
fahadmirza 0:a0c5877bd360 339 }
fahadmirza 0:a0c5877bd360 340 }
fahadmirza 0:a0c5877bd360 341
fahadmirza 0:a0c5877bd360 342 break;
fahadmirza 0:a0c5877bd360 343 }
fahadmirza 0:a0c5877bd360 344 case DEVICE_JOIN_STATUS_CHECK:
fahadmirza 0:a0c5877bd360 345 {
fahadmirza 0:a0c5877bd360 346 if(Lora_getJoinStatus() == JOINED)
fahadmirza 0:a0c5877bd360 347 {
fahadmirza 12:f1fd61aa85e0 348 // Inidicate Join status using LED
fahadmirza 12:f1fd61aa85e0 349 GPIO_InitTypeDef GPIO_InitStruct;
fahadmirza 12:f1fd61aa85e0 350
fahadmirza 12:f1fd61aa85e0 351 GPIO_InitStruct.Pin = GPIO_PIN_7;
fahadmirza 12:f1fd61aa85e0 352 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
fahadmirza 12:f1fd61aa85e0 353 GPIO_InitStruct.Pull = GPIO_NOPULL;
fahadmirza 12:f1fd61aa85e0 354 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
fahadmirza 12:f1fd61aa85e0 355
fahadmirza 12:f1fd61aa85e0 356 GPIO_InitStruct.Pin = GPIO_PIN_6;
fahadmirza 12:f1fd61aa85e0 357 GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
fahadmirza 12:f1fd61aa85e0 358 GPIO_InitStruct.Pull = GPIO_NOPULL;
fahadmirza 12:f1fd61aa85e0 359 HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
fahadmirza 12:f1fd61aa85e0 360
fahadmirza 12:f1fd61aa85e0 361 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_7, GPIO_PIN_SET);
fahadmirza 12:f1fd61aa85e0 362 HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
fahadmirza 12:f1fd61aa85e0 363
fahadmirza 0:a0c5877bd360 364 DBG_PRINTF("Nwk Joined\n");
fahadmirza 0:a0c5877bd360 365 // Start timer for uplink transmission for sensor-data
fahadmirza 0:a0c5877bd360 366 TimerStart( &SensorMeasureTimer, LoraDriverParam->SensorMeasureTime);
fahadmirza 0:a0c5877bd360 367 DeviceState = SLEEP_DEVICE;
fahadmirza 0:a0c5877bd360 368 }
fahadmirza 0:a0c5877bd360 369 else
fahadmirza 0:a0c5877bd360 370 {
fahadmirza 0:a0c5877bd360 371 // Try joining again
fahadmirza 0:a0c5877bd360 372 setJoinRequestTimer();
fahadmirza 0:a0c5877bd360 373 DeviceState = SLEEP_DEVICE;
fahadmirza 0:a0c5877bd360 374 }
fahadmirza 0:a0c5877bd360 375 break;
fahadmirza 0:a0c5877bd360 376 }
fahadmirza 0:a0c5877bd360 377 case SLEEP_DEVICE:
fahadmirza 0:a0c5877bd360 378 {
fahadmirza 0:a0c5877bd360 379 /* Wake up through RTC events or asynchronous event coming from HXC modem*/
fahadmirza 0:a0c5877bd360 380 if(Modem_IsNewDataReceived() == true)
fahadmirza 0:a0c5877bd360 381 {
fahadmirza 0:a0c5877bd360 382 DeviceState = DEVICE_DATA_RECEIVED;
fahadmirza 0:a0c5877bd360 383 }
fahadmirza 0:a0c5877bd360 384 break;
fahadmirza 0:a0c5877bd360 385 }
fahadmirza 0:a0c5877bd360 386 case DEVICE_SEND:
fahadmirza 0:a0c5877bd360 387 {
fahadmirza 0:a0c5877bd360 388 // Read sensor data and populate payload
fahadmirza 0:a0c5877bd360 389 LoraDriverParam->SendDataHandler(SendDataBinary.Buffer, &SendDataBinary.DataSize, &SendDataBinary.Ack, &SendDataBinary.Port);
fahadmirza 0:a0c5877bd360 390
fahadmirza 0:a0c5877bd360 391 // Initiate uplink transmission
fahadmirza 0:a0c5877bd360 392 eAtStatus_t status = Lora_SendDataBinary(&SendDataBinary);
fahadmirza 0:a0c5877bd360 393 if (status == AT_OK)
fahadmirza 0:a0c5877bd360 394 {
fahadmirza 0:a0c5877bd360 395 // Schedule the next packet
fahadmirza 0:a0c5877bd360 396 TimerStart( &SensorMeasureTimer, LoraDriverParam->SensorMeasureTime );
fahadmirza 0:a0c5877bd360 397 DeviceState = SLEEP_DEVICE;
fahadmirza 0:a0c5877bd360 398 }
fahadmirza 0:a0c5877bd360 399 else if(status == AT_TIMEOUT)
fahadmirza 0:a0c5877bd360 400 {
fahadmirza 0:a0c5877bd360 401 // Device isn't responding. Go to init.
fahadmirza 0:a0c5877bd360 402 DeviceState = DEVICE_INIT;
fahadmirza 0:a0c5877bd360 403 }
fahadmirza 0:a0c5877bd360 404
fahadmirza 0:a0c5877bd360 405 break;
fahadmirza 0:a0c5877bd360 406 }
fahadmirza 0:a0c5877bd360 407 case DEVICE_DATA_RECEIVED:
fahadmirza 0:a0c5877bd360 408 {
fahadmirza 0:a0c5877bd360 409 uint8_t rBuffer[64];
fahadmirza 0:a0c5877bd360 410 sRecvDataBinary_t rxPacket = {.Buffer = rBuffer};
fahadmirza 0:a0c5877bd360 411
fahadmirza 0:a0c5877bd360 412 Lora_ReadData(&rxPacket);
fahadmirza 0:a0c5877bd360 413
fahadmirza 0:a0c5877bd360 414 // Execute users ReceivedPacketHandler function
fahadmirza 0:a0c5877bd360 415 LoraDriverParam->ReceiveDataHandler(rxPacket.Buffer, rxPacket.DataSize, rxPacket.Ack, rxPacket.Port);
fahadmirza 0:a0c5877bd360 416
fahadmirza 0:a0c5877bd360 417 DeviceState = SLEEP_DEVICE;
fahadmirza 0:a0c5877bd360 418 break;
fahadmirza 0:a0c5877bd360 419 }
fahadmirza 0:a0c5877bd360 420 default:
fahadmirza 0:a0c5877bd360 421 {
fahadmirza 0:a0c5877bd360 422 DeviceState = DEVICE_INIT;
fahadmirza 0:a0c5877bd360 423 break;
fahadmirza 0:a0c5877bd360 424 }
fahadmirza 0:a0c5877bd360 425 }
fahadmirza 0:a0c5877bd360 426 }
fahadmirza 0:a0c5877bd360 427
fahadmirza 0:a0c5877bd360 428 static void setJoinRequestTimer(void)
fahadmirza 0:a0c5877bd360 429 {
fahadmirza 0:a0c5877bd360 430 // Use a random delay to avoid synchronized join request from all LoRa node after power up
fahadmirza 0:a0c5877bd360 431 uint32_t joinDelay = (HAL_RNG_GetRandomNumber(&RngHandle) % JOIN_SEND_DELAY_MAX) + 1;
fahadmirza 0:a0c5877bd360 432 TimerStart( &JoinRequestTimer, joinDelay);
fahadmirza 0:a0c5877bd360 433 }
fahadmirza 0:a0c5877bd360 434
fahadmirza 0:a0c5877bd360 435 /******************************************************************************
fahadmirza 0:a0c5877bd360 436 * @Brief : Function executed on JoinStatusDelayTimer Timeout event
fahadmirza 0:a0c5877bd360 437 * @Param : none
fahadmirza 0:a0c5877bd360 438 * @Return : none
fahadmirza 0:a0c5877bd360 439 ******************************************************************************/
fahadmirza 10:19da323c2bc0 440 static void OnJoinRequestTimerEvt(void)
fahadmirza 0:a0c5877bd360 441 {
fahadmirza 0:a0c5877bd360 442 TimerStop(&JoinRequestTimer);
fahadmirza 0:a0c5877bd360 443 DeviceState = DEVICE_JOIN;
fahadmirza 0:a0c5877bd360 444 }
fahadmirza 0:a0c5877bd360 445
fahadmirza 0:a0c5877bd360 446 /******************************************************************************
fahadmirza 0:a0c5877bd360 447 * @Brief : Function executed on NucleoLedTimer Timeout event
fahadmirza 0:a0c5877bd360 448 * @Param : none
fahadmirza 0:a0c5877bd360 449 * @Return : none
fahadmirza 0:a0c5877bd360 450 ******************************************************************************/
fahadmirza 10:19da323c2bc0 451 static void OnLedTimerEvent(void)
fahadmirza 0:a0c5877bd360 452 {
fahadmirza 0:a0c5877bd360 453 TimerStop(&NucleoLedTimer);
fahadmirza 0:a0c5877bd360 454 BSP_LED_Off(LED_GREEN);
fahadmirza 0:a0c5877bd360 455 }
fahadmirza 0:a0c5877bd360 456
fahadmirza 0:a0c5877bd360 457 /******************************************************************************
fahadmirza 0:a0c5877bd360 458 * @Brief : Function executed on JoinStatusDelayTimer Timeout event
fahadmirza 0:a0c5877bd360 459 * @Param : none
fahadmirza 0:a0c5877bd360 460 * @Return : none
fahadmirza 0:a0c5877bd360 461 ******************************************************************************/
fahadmirza 10:19da323c2bc0 462 static void OnJoinStatusDelayTimerEvt(void)
fahadmirza 0:a0c5877bd360 463 {
fahadmirza 0:a0c5877bd360 464 TimerStop( &JoinStatusDelayTimer );
fahadmirza 0:a0c5877bd360 465 DeviceState = DEVICE_JOIN_STATUS_CHECK;
fahadmirza 0:a0c5877bd360 466 }
fahadmirza 0:a0c5877bd360 467
fahadmirza 0:a0c5877bd360 468 /******************************************************************************
fahadmirza 0:a0c5877bd360 469 * @Brief : Function executed on SensorMeasureTimer Timeout event
fahadmirza 0:a0c5877bd360 470 * @Param : none
fahadmirza 0:a0c5877bd360 471 * @Return : none
fahadmirza 0:a0c5877bd360 472 ******************************************************************************/
fahadmirza 10:19da323c2bc0 473 static void OnSensorMeasureTimerEvt(void)
fahadmirza 0:a0c5877bd360 474 {
fahadmirza 0:a0c5877bd360 475 TimerStop( &SensorMeasureTimer );
fahadmirza 0:a0c5877bd360 476 DeviceState = DEVICE_SEND;
fahadmirza 0:a0c5877bd360 477 }
fahadmirza 0:a0c5877bd360 478
fahadmirza 0:a0c5877bd360 479 /******************************************************************************
fahadmirza 0:a0c5877bd360 480 * @brief RNG MSP Initialization
fahadmirza 0:a0c5877bd360 481 * This function configures the hardware resources used in this example:
fahadmirza 0:a0c5877bd360 482 * - Peripheral's clock enable
fahadmirza 0:a0c5877bd360 483 * @param hrng: RNG handle pointer
fahadmirza 0:a0c5877bd360 484 * @retval None
fahadmirza 0:a0c5877bd360 485 ******************************************************************************/
fahadmirza 0:a0c5877bd360 486 void HAL_RNG_MspInit(RNG_HandleTypeDef *hrng)
fahadmirza 0:a0c5877bd360 487 {
fahadmirza 0:a0c5877bd360 488 /* RNG Peripheral clock enable */
fahadmirza 0:a0c5877bd360 489 __HAL_RCC_RNG_CLK_ENABLE();
fahadmirza 0:a0c5877bd360 490 }
fahadmirza 0:a0c5877bd360 491
fahadmirza 0:a0c5877bd360 492