Fahad Mirza / Mbed 2 deprecated Nucleo_HXC900

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
fahadmirza
Date:
Thu Jan 24 21:57:23 2019 +0000
Parent:
31:174c745f921c
Child:
33:83cd24bbb17a
Commit message:
Updated code;

Changed in this revision

Driver/hw_rtc.c Show annotated file Show diff for this revision Revisions of this file
Driver/hxcclient_bsp.cpp Show annotated file Show diff for this revision Revisions of this file
Driver/hxcclient_bsp.h Show annotated file Show diff for this revision Revisions of this file
LoRa/hxc_client.c Show annotated file Show diff for this revision Revisions of this file
LoRa/hxc_client.h Show annotated file Show diff for this revision Revisions of this file
LoRa/lora_driver.c Show annotated file Show diff for this revision Revisions of this file
LoRa/lora_driver.h Show annotated file Show diff for this revision Revisions of this file
Utilities/time_server.c Show annotated file Show diff for this revision Revisions of this file
Utilities/time_server.h Show annotated file Show diff for this revision Revisions of this file
Utilities/utilities.c Show annotated file Show diff for this revision Revisions of this file
Utilities/utilities.h Show annotated file Show diff for this revision Revisions of this file
lora_conf.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
main.h Show diff for this revision Revisions of this file
--- a/Driver/hw_rtc.c	Mon Dec 10 19:54:23 2018 +0000
+++ b/Driver/hw_rtc.c	Thu Jan 24 21:57:23 2019 +0000
@@ -76,10 +76,10 @@
 /* Private define ------------------------------------------------------------*/
 
 /* MCU Wake Up Time */
-#define MIN_ALARM_DELAY               3 /* in ticks */
+#define MIN_ALARM_DELAY            3U /* in ticks */
 
 /* subsecond number of bits */
-#define N_PREDIV_S                 10
+#define N_PREDIV_S                10U
 
 /* Synchronous prediv  */
 #define PREDIV_S                  ((1<<N_PREDIV_S)-1)
@@ -95,11 +95,11 @@
 #endif
 
 /* RTC Time base in us */
-#define USEC_NUMBER               1000000
+#define USEC_NUMBER               1000000U
 #define MSEC_NUMBER               (USEC_NUMBER/1000)
 #define RTC_ALARM_TIME_BASE       (USEC_NUMBER>>N_PREDIV_S)
 
-#define COMMON_FACTOR        3
+#define COMMON_FACTOR             3U
 #define CONV_NUMER                (MSEC_NUMBER>>COMMON_FACTOR)
 #define CONV_DENOM                (1<<(N_PREDIV_S-COMMON_FACTOR))
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Driver/hxcclient_bsp.cpp	Thu Jan 24 21:57:23 2019 +0000
@@ -0,0 +1,94 @@
+/*
+  _    _            _____   _______
+ | |  | |          |_   _| |__   __|
+ | |__| | __ ___  __ | |  ___ | |
+ |  __  |/ _` \ \/ / | | / _ \| |
+ | |  | | (_| |>  < _| || (_) | |
+ |_|  |_|\__,_/_/\_\_____\___/|_|
+    (C)2019 HaxIoT
+*/
+/*******************************************************************************
+  * File    : hxcclient_bsp.c
+  * Author  : Fahad (Haxiot)
+  * Version : V1.0.0
+  * Modified: 22-January-2019
+  * Brief   : HXC Client Expansion Board LED, Slide Switch & Temperature sensor
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2019 Haxiot</center></h2>
+  *
+  * 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 Haxiot nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include "hxcclient_bsp.h"
+
+// Mbed specific declaration
+AnalogIn temperatureSensor(A0);
+DigitalIn slideSwitch(D12);
+DigitalOut greenLED(D11);
+DigitalOut redLED(D10);
+DigitalOut blueLED(D9);
+
+
+void HXC_BSP_Init(void)
+{
+  slideSwitch.mode(PullDown);
+}
+
+uint16_t HXC_BSP_GetTemperature(void)
+{
+    // Converts and read the analog input value (value from 0.0 to 1.0)
+    float tempFloat = temperatureSensor.read();
+    // Change the value to be in the 0 to 3300 range
+    uint16_t tempInt = tempFloat * 3300;
+    // Checkout our user manual to convert tempInt into degree Celcius
+
+    return tempInt;
+}
+
+uint8_t HXC_BSP_GetSlideSwitchStatus(void)
+{
+    return slideSwitch;
+}
+
+void HXC_BSP_RGB_On(eLedColor_t ledColor)
+{
+    redLED   = (ledColor & RED) ? 1 : 0;
+    greenLED = (ledColor & GREEN) ? 1 : 0;
+    blueLED  = (ledColor & BLUE) ? 1 : 0;
+}
+
+void HXC_BSP_RGB_Off(void)
+{
+    HXC_BSP_RGB_On(OFF);
+}
+
+void HXC_BSP_RGB_AllOn(void)
+{
+    HXC_BSP_RGB_On(WHITE);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Driver/hxcclient_bsp.h	Thu Jan 24 21:57:23 2019 +0000
@@ -0,0 +1,81 @@
+/*
+  _    _            _____   _______
+ | |  | |          |_   _| |__   __|
+ | |__| | __ ___  __ | |  ___ | |
+ |  __  |/ _` \ \/ / | | / _ \| |
+ | |  | | (_| |>  < _| || (_) | |
+ |_|  |_|\__,_/_/\_\_____\___/|_|
+    (C)2019 HaxIoT
+*/
+/*******************************************************************************
+  * File    : hxcclient_bsp.h
+  * Author  : Fahad (Haxiot)
+  * Version : V1.0.0
+  * Modified: 22-January-2019
+  * Brief   : Header file for hxcclient_bsp.c
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; COPYRIGHT(c) 2019 Haxiot</center></h2>
+  *
+  * 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 Haxiot nor the names of its contributors
+  *      may be used to endorse or promote products derived from this software
+  *      without specific prior written permission.
+  *
+  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef HXCCLIENT_BSP_H_
+#define HXCCLIENT_BSP_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Colors are arranged in chronological order: RGB
+typedef enum eLedColor
+{
+    OFF = 0,
+    BLUE,
+    GREEN,
+    CYAN,   // Green and Blue
+    RED,
+    PINK,   // Red and Blue
+    YELLOW, // Red and Green
+    WHITE   // Red, Green and Blue
+}eLedColor_t;
+
+void HXC_BSP_Init(void);
+void HXC_BSP_RGB_AllOn(void);
+void HXC_BSP_RGB_Off(void);
+void HXC_BSP_RGB_On(eLedColor_t);
+uint16_t HXC_BSP_GetTemperature(void);
+uint8_t HXC_BSP_GetSlideSwitchStatus(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* HXCCLIENT_BSP_H_ */
+
+/************************ (C) COPYRIGHT Haxiot *****END OF FILE****/
--- a/LoRa/hxc_client.c	Mon Dec 10 19:54:23 2018 +0000
+++ b/LoRa/hxc_client.c	Thu Jan 24 21:57:23 2019 +0000
@@ -57,13 +57,36 @@
 #include "time_server.h"
 #include "hw_gpio.h"
 
+
+/* Private macro -------------------------------------------------------------*/
+#define AT_VPRINTF(...)         at_cmd_vprintf(__VA_ARGS__)
+#define AT_VSSCANF(...)         tiny_sscanf(__VA_ARGS__)
+
+#define BAUD_RATE               9600U
+#define ARRAY_SIZE(a)           (sizeof(a) / sizeof(a[0]))
+
+#define AT_RESPONSE_BUFF_SIZE   64U    // Max size of the received buffer.
+#define DATA_TX_MAX_BUFF_SIZE   78U    // Max size of the transmit buffer
+#define HXC_TIMEOUT             2000U  // 2 seconds
+
+
+// These strings will be used to compare the responses return from HXC modem.
+// In direct relation with sAtRetCode_t
+#define OK                 "OK"
+#define ERROR              "AT_ERROR"
+#define PARAM_ERROR        "AT_PARAM_ERROR"
+#define BUSY_ERROR         "AT_BUSY_ERROR"
+#define PARAM_OVERFLOW     "AT_PARAM_OVERFLOW"
+#define INVALID_MODE       "AT_INVALID_MODE"
+#define NO_NETWORK_JOINED  "AT_NO_NETWORK_JOINED"
+#define PAYLOAD_SIZE_ERROR "AT_PAYLOAD_SIZE_ERROR"
+
+
 /* Private typedef -----------------------------------------------------------*/
 // Type definition for return code analysis
-typedef  char* AtErrorStr_t;
-
 typedef struct sAtRetCode
 {
-	AtErrorStr_t RetCodeStr;
+    char* RetCodeStr;
 	uint8_t SizeRetCodeStr;
 	eAtStatus_t RetCode;
 }sAtRetCode_t;
@@ -74,47 +97,22 @@
 static uint16_t at_set_cmd_format(ATCmd_t Cmd, const void *ptr);
 static eAtStatus_t at_cmd_send(uint16_t len);
 static eAtStatus_t at_cmd_receive(void *pdata);
-static eAtStatus_t at_cmd_responseAnalysing(const char *ReturnResp);
+static eAtStatus_t at_cmd_analyzeResponse(const char *ReturnResp);
 static uint16_t at_cmd_vprintf(const char *format, ...);
 
 
-/* Private macro -------------------------------------------------------------*/
-#define AT_VPRINTF(...)         at_cmd_vprintf(__VA_ARGS__)
-#define AT_VSSCANF(...)         tiny_sscanf(__VA_ARGS__)
-
-#define BAUD_RATE               9600
-#define ARRAY_SIZE(a)           (sizeof(a) / sizeof(a[0]))
-
-#define DATA_RX_MAX_BUFF_SIZE   64       /* Max size of the received buffer.
-                                          * To optimize we can match with device key sizeof */
-
-#define DATA_TX_MAX_BUFF_SIZE   78       // Max size of the transmit buffer
-#define HXC_TIMEOUT				2000     // 2 seconds
-
-/*
- * RetCode used to compare the return code from HXC modem.
- * In direct relation with sAtRetCode_t
- */
-#define RET_OK                 "OK"
-#define RET_ERROR              "AT_ERROR"
-#define RET_PARAM_ERROR        "AT_PARAM_ERROR"
-#define RET_BUSY_ERROR         "AT_BUSY_ERROR"
-#define RET_PARAM_OVERFLOW     "AT_PARAM_OVERFLOW"
-#define RET_INVALID_MODE       "AT_INVALID_MODE"
-#define RET_NO_NETWORK_JOINED  "AT_NO_NETWORK_JOINED"
-#define RET_PAYLOAD_SIZE_ERROR "AT_PAYLOAD_SIZE_ERROR"
-
-
 /* Private Variables --------------------------------------------------------*/
+// NOTE: sizeof of a string take account of the NULL character too, unlike
+//       strlen(). Hence subtract one from the sizeof.
 static const sAtRetCode_t AT_RetCode[] = {
-{RET_OK,                 sizeof(RET_OK),                 AT_OK},
-{RET_ERROR,              sizeof(RET_ERROR),              AT_ERROR},
-{RET_PARAM_ERROR,        sizeof(RET_PARAM_ERROR),        AT_PARAM_ERROR},
-{RET_NO_NETWORK_JOINED,  sizeof(RET_NO_NETWORK_JOINED),  AT_NO_NET_JOINED},
-{RET_BUSY_ERROR,         sizeof(RET_BUSY_ERROR),         AT_BUSY_ERROR},
-{RET_PARAM_OVERFLOW,     sizeof(RET_PARAM_OVERFLOW),     AT_PARAM_OVERFLOW},
-{RET_INVALID_MODE,       sizeof(RET_INVALID_MODE),       AT_INVALID_MODE},
-{RET_PAYLOAD_SIZE_ERROR, sizeof(RET_PAYLOAD_SIZE_ERROR), AT_PAYLOAD_SIZE_ERROR}};
+{OK,                 sizeof(OK) - 1,                 AT_OK},
+{ERROR,              sizeof(ERROR) - 1,              AT_ERROR},
+{PARAM_ERROR,        sizeof(PARAM_ERROR) - 1,        AT_PARAM_ERROR},
+{NO_NETWORK_JOINED,  sizeof(NO_NETWORK_JOINED) - 1,  AT_NO_NET_JOINED},
+{BUSY_ERROR,         sizeof(BUSY_ERROR) - 1,         AT_BUSY_ERROR},
+{PARAM_OVERFLOW,     sizeof(PARAM_OVERFLOW) - 1,     AT_PARAM_OVERFLOW},
+{INVALID_MODE,       sizeof(INVALID_MODE) - 1,       AT_INVALID_MODE},
+{PAYLOAD_SIZE_ERROR, sizeof(PAYLOAD_SIZE_ERROR) - 1, AT_PAYLOAD_SIZE_ERROR}};
 
 
 /*
@@ -161,20 +159,17 @@
 	"+TXCW",       // Continuous Tx
 	"+TX",         // Send LoRa only data in raw format
 	"+RX",         // Continuous Rx
-	"+BAT",        /// Battery level
+	"+BAT",        // Battery level
 	"+VER",        // Firmware version of the HXC Client
 };
 
 
-char LoRa_AT_Cmd_Buff[DATA_TX_MAX_BUFF_SIZE];// Buffer used for AT cmd transmission
-
-static uint16_t Offset = 0;                  // Write position needed for LoRa_AT_Cmd_Buff[] during AT_SET
+static char AtCmdBuff[DATA_TX_MAX_BUFF_SIZE];
+// Write position needed for AtCmdBuff[] during AT_SET
+static uint16_t Offset = 0;
 
-/* Has to be the largest of the response.
- * Not only for return code but also for
- * return value e.g. APPKEY.
- */
-static char response[DATA_RX_MAX_BUFF_SIZE];
+// Has to be the largest of the response e.g. APPKEY.
+static char AtResponseBuff[AT_RESPONSE_BUFF_SIZE];
 
 
 /* Exported functions ------------------------------------------------------- */
@@ -228,27 +223,24 @@
 	uint16_t atCmdLen;
 
 	// Reset At_cmd buffer for each transmission
-	memset1((uint8_t *)LoRa_AT_Cmd_Buff, 0x00, sizeof(LoRa_AT_Cmd_Buff));
+	memset1((uint8_t *)AtCmdBuff, 0x00, DATA_TX_MAX_BUFF_SIZE);
 	
-	/* Reset the UART circular buffer for each transmission to make sure
-	 * the responses we will get are for the current AT cmd. */
+	// Reset the UART circular buffer for each transmission to make sure
+	// the responses we will get are for the current AT cmd.
 	HW_UART_ResetBuffer();
 
 	// Format AT cmd
 	atCmdLen = at_cmd_format(at_group, atCmd, pdata);
 	if(atCmdLen == 0)
 	{
-		/*
-		 * You are trying to use a command behavior that HXC Client doesn't
-		 * support. Check manual for possible AT command behaviors.
-		 */
+		// You are trying to use a command behavior that HXC Client doesn't
+		// support. Check manual for possible AT command behaviors.
 		return AT_CMD_ERROR;
 	}
 
 	// Send AT cmd string
 	if(at_cmd_send(atCmdLen) != AT_OK)
 	{
-        // Problem on UART transmission
 	    return AT_UART_LINK_ERROR;
 	}
 
@@ -407,7 +399,7 @@
 static eAtStatus_t at_cmd_send(uint16_t len)
 {
   /*transmit the command from master to slave*/
-  if( HW_UART_Modem_SendBytes(LoRa_AT_Cmd_Buff, len) == false)
+  if( HW_UART_Modem_SendBytes(AtCmdBuff, len) == false)
   {
 	  return AT_UART_LINK_ERROR;
   }
@@ -428,7 +420,7 @@
 	eAtStatus_t RetCode = AT_END_ERROR;
   
 	// Cleanup the response buffer
-	memset1((uint8_t *)response, 0x00, sizeof(response));
+	memset1((uint8_t *)AtResponseBuff, 0x00, AT_RESPONSE_BUFF_SIZE);
 
 	uint32_t currentTime = TimerGetCurrentTime();
     while(ResponseComplete != true)
@@ -443,22 +435,18 @@
         }
     	else
     	{
-    		// Process the response
-            response[i++] = HW_UART_Modem_GetNewChar();
+    	    AtResponseBuff[i++] = HW_UART_Modem_GetNewChar();
    
             // Wait up to line feed marker
-            if (response[i - 1] == '\n')
+            if (AtResponseBuff[i - 1] == '\n')
             {
             	// Last two bytes are <CR><LF>, set CR as NULL byte.
-    	        response[i - 2] = '\0';
-    	        // Reset index
+                AtResponseBuff[i - 2] = '\0';
     	        i = 0;
 
-    	        // Compare response with AT statuses
-		        RetCode = at_cmd_responseAnalysing(response);
+		        RetCode = at_cmd_analyzeResponse(AtResponseBuff);
 		        if(RetCode != AT_END_ERROR)
 		        {
-			        // We received a status. Response complete.
 			        ResponseComplete = true;
 		        }
                 else if(pdata != NULL)
@@ -466,14 +454,14 @@
         	        // If pdata isn't null that means we are using GET cmd to get
         	        // return value. Copy the return value into pdata.
 
-			        strcpy(pdata, response);
-			        memset1((uint8_t *)response, 0x00, 16);
+			        strcpy(pdata, AtResponseBuff);
+			        memset1((uint8_t *)AtResponseBuff, 0x00, AT_RESPONSE_BUFF_SIZE);
 			        // Now, let's get the status
 		        }
             }
             else
             {
-                if (i ==  (DATA_RX_MAX_BUFF_SIZE-1))
+                if (i == (AT_RESPONSE_BUFF_SIZE - 1))
                 {
         	        // Frame overflow. Reset index and stop reading.
                 	i = 0;
@@ -494,13 +482,13 @@
   * @Param : response: pointer to the received response
   * @Return: eAtStatus_t error type
 *******************************************************************************/
-static eAtStatus_t at_cmd_responseAnalysing(const char *ReturnResp)
+static eAtStatus_t at_cmd_analyzeResponse(const char *ReturnResp)
 {
-	int i;
+	uint8_t i;
 
     for (i = 0; i < ARRAY_SIZE(AT_RetCode); i++)
     {   
-		if (strncmp(ReturnResp, AT_RetCode[i].RetCodeStr, (AT_RetCode[i].SizeRetCodeStr-1)) == 0)
+		if (strncmp(ReturnResp, AT_RetCode[i].RetCodeStr, (AT_RetCode[i].SizeRetCodeStr)) == 0)
 		{
 			/* Command has been found */
 			return AT_RetCode[i].RetCode;
@@ -515,14 +503,14 @@
   * @Param : Pointer to the format string
   * @Return: Length of the string to be sent
 *******************************************************************************/
-uint16_t at_cmd_vprintf(const char *format, ...)
+static uint16_t at_cmd_vprintf(const char *format, ...)
 {
 	va_list args;
     uint16_t len;
    
     va_start(args, format);
   
-    len = tiny_vsnprintf_like(LoRa_AT_Cmd_Buff+Offset, sizeof(LoRa_AT_Cmd_Buff)-Offset, format, args);
+    len = tiny_vsnprintf_like(AtCmdBuff + Offset, DATA_TX_MAX_BUFF_SIZE - Offset, format, args);
   
     va_end(args);
   
@@ -556,13 +544,20 @@
 		return false;
 	}
 	// Cleanup the response buffer
-	memset1((uint8_t *)response, 0x00, sizeof(response));
-	HW_UART_Modem_GetCharactersUntilNewLine(response, sizeof(response), HXC_TIMEOUT);
-	if(strncmp("rxdata", response, 6) == 0)
+	memset1((uint8_t *)AtResponseBuff, 0x00, AT_RESPONSE_BUFF_SIZE);
+
+	HW_UART_Modem_GetCharactersUntilNewLine(AtResponseBuff, AT_RESPONSE_BUFF_SIZE, HXC_TIMEOUT);
+
+	if(strncmp("rxdata", AtResponseBuff, 6) == 0)
 	{
 		return true;
 	}
 	return false;
 }
+
+char* Modem_GetResponseBuffer(void)
+{
+	return AtResponseBuff;
+}
 /************************ (C) COPYRIGHT Haxiot *****END OF FILE*****/
 
--- a/LoRa/hxc_client.h	Mon Dec 10 19:54:23 2018 +0000
+++ b/LoRa/hxc_client.h	Thu Jan 24 21:57:23 2019 +0000
@@ -201,6 +201,7 @@
  ********************************************************************/
 bool Modem_IsNewDataReceived(void);
 
+char* Modem_GetResponseBuffer(void);
 
 
 #ifdef __cplusplus
--- a/LoRa/lora_driver.c	Mon Dec 10 19:54:23 2018 +0000
+++ b/LoRa/lora_driver.c	Thu Jan 24 21:57:23 2019 +0000
@@ -51,6 +51,7 @@
 #include "lora_driver.h"
 #include "tiny_sscanf.h"
 #include "utilities.h"
+#include "hxcclient_bsp.h"
 
 /* Private Macros ------------------------------------------------------------*/
 #define JOIN_SEND_DELAY_MAX   (10000U) // Randomization range - 10s
@@ -67,8 +68,7 @@
 static TimerEvent_t JoinRequestTimer;
 static TimerEvent_t RejoinTimer;
 static TimerEvent_t SensorMeasureTimer;
-static TimerEvent_t NucleoLedTimer;
-static TimerEvent_t JoinStatusDelayTimer;
+static TimerEvent_t JoinStatusReqTimer;
 
 // Object definition for data to be sent to loRa application server
 static uint8_t DataBinaryBuff[MAX_PAYLOAD_SIZE];
@@ -79,9 +79,8 @@
 
 /* Private functions ---------------------------------------------------------*/
 static void OnRejoinTimerEvent(void);
-static void OnLedTimerEvent(void);
 static void OnJoinRequestTimerEvt(void);
-static void OnJoinStatusDelayTimerEvt(void);
+static void OnJoinStatusReqTimerEvt(void);
 static void OnSensorMeasureTimerEvt(void);
 static void setJoinRequestTimer(void);
 
@@ -110,13 +109,14 @@
 	// Timer for join request send
 	TimerInit(&JoinRequestTimer, OnJoinRequestTimerEvt);
 	// Timer for join status check
-	TimerInit(&JoinStatusDelayTimer, OnJoinStatusDelayTimerEvt);
+	TimerInit(&JoinStatusReqTimer, OnJoinStatusReqTimerEvt);
+	TimerSetValue(&JoinStatusReqTimer, JOIN_STATUS_REQ_DELAY);
 	// Timer for sensor occurrence measure
 	TimerInit(&SensorMeasureTimer, OnSensorMeasureTimerEvt);
-	// Timer for Nucleo LED
-	TimerInit(&NucleoLedTimer, OnLedTimerEvent);
-	// Timer for Re Authenticate / Join
+	TimerSetValue(&SensorMeasureTimer, LoraDriverParam->UplinkCycle);
+	// Timer for Re-Authenticate / Re-Join
 	TimerInit(&RejoinTimer, OnRejoinTimerEvent);
+	TimerSetValue(&RejoinTimer, REJOIN_TIME);
 }
 
 /******************************************************************************
@@ -154,6 +154,20 @@
 }
 
 /******************************************************************************
+  * @Brief  : Print Device Address
+  * @Param  : None
+  * @Retval : AT_OK or other eAtStatus_t
+******************************************************************************/
+static void Lora_printDevAdr(void)
+{
+    char devadr_str[15];
+
+    Modem_AT_Cmd(AT_GET, AT_DEVADR, devadr_str);
+
+    DBG_PRINTF("DevAdr: %s\n", devadr_str);
+}
+
+/******************************************************************************
   * @Brief  : Turn on or off ADR
   * @Param  : ADR_ON or ADR_OFF
   * @Return : AT_OK or other eAtStatus_t
@@ -243,10 +257,10 @@
   * @Param  : None
   * @Retval : Integer firmware version
 ******************************************************************************/
-uint8_t Lora_getFwVersion(void)
+uint16_t Lora_getFwVersion(void)
 {
 	char fwVersion_str[5];
-	float fwVer_float;
+	uint16_t fwVer_int;
 
 	eAtStatus_t status = Modem_AT_Cmd(AT_GET, AT_VER, fwVersion_str);
 	
@@ -255,10 +269,18 @@
 		return 0;
 	}
 	
-	sscanf(fwVersion_str, "%f", &fwVer_float);
-	// This weird division was needed. Otherwise, because of 
-	// the floating point calculation the result was rounded.
-	uint8_t fwVer_int = (uint8_t)(fwVer_float * 1000/10); 
+	// FW version is a decimal number e.g. 1.18
+	// Convert the float number into integer.
+	uint8_t i = 0;
+	while(fwVersion_str[++i] != '.');
+
+	while(fwVersion_str[i] != '\0')
+	{
+		fwVersion_str[i] = fwVersion_str[i + 1];
+		i++;
+	}
+
+	tiny_sscanf(fwVersion_str, "%hu", &fwVer_int);
 
 	return fwVer_int;
 }
@@ -277,13 +299,24 @@
 	
 	if(status == AT_OK)
 	{
-		sscanf(batteryLevel_str, "%hhu", &batteryLevel);
+	    tiny_sscanf(batteryLevel_str, "%hhu", &batteryLevel);
 	}
 
 	return batteryLevel;
 }
 
 /******************************************************************************
+  * @Brief  : Update the uplink rate
+  * @Param  : time_s seconds
+  * @Retval : None
+******************************************************************************/
+void Lora_updateUplinkRate(uint32_t time_s)
+{
+    TimerSetValue(&SensorMeasureTimer, (time_s * 1000));
+    TimerReset(&SensorMeasureTimer);
+}
+
+/******************************************************************************
   * @Brief  : Send uplink packet using binary payload
   * @Param  : Pointer of sSendDataBinary_t variable
   * @Retval : AT_OK or other eAtStatus_t statuses
@@ -296,31 +329,36 @@
 /******************************************************************************
  * @Brief  : Read the received downlink packet
  * @Param  : Pointer to sRecvDataBinary_t variable
- * @Return : None
+ * @Return : AT_OK or other eAtStatus_t statuses
 ******************************************************************************/
-static void Lora_ReadData(sRecvDataBinary_t *receivedData)
+static eAtStatus_t Lora_ReadData(sRecvDataBinary_t *rxData)
 {
-	char receiveString[MAX_PAYLOAD_SIZE];
+	char *rxString = Modem_GetResponseBuffer();
+
+	// Find the position after :
+	// e.g. rxdata:0,1,86GF25
+	rxString = (strchr(rxString,':') + 1);
 
-	Modem_AT_Cmd(AT_GET, AT_RECVB, receiveString);
+	if(rxString == NULL)
+	{
+		return AT_ERROR;
+	}
 
-	tiny_sscanf(receiveString, "%hhu,%hhu", &(receivedData->Ack), &(receivedData->Port));
+	if(tiny_sscanf(rxString, "%hhu,%hhu", &(rxData->Ack), &(rxData->Port)) != 2)
+	{
+		return AT_ERROR;
+	}
 
 	// Find the position after the second comma
-	char *hexString = strchr((strchr(receiveString,',') + 1),',') + 1;
-
-	receivedData->DataSize = stringHexToByteArray(hexString, receivedData->Buffer, MAX_PAYLOAD_SIZE);
-}
+	rxString = strchr((strchr(rxString,',') + 1),',') + 1;
+	if(rxString == NULL)
+	{
+		return AT_ERROR;
+	}
 
-/******************************************************************************
-  * @Brief  : Change Lora_fsm() DeviceState
-  * @Param  : Any of eDeviceState_t type
-  * @Return : None
-******************************************************************************/
-static void Lora_ChangeDeviceState(eDeviceState_t newDeviceState)
-{
-	//ToDo: Check for valid eDeviceState_t states
-	DeviceState = newDeviceState;
+	rxData->DataSize = stringHexToByteArray(rxString, rxData->Buffer, MAX_PAYLOAD_SIZE);
+
+	return AT_OK;
 }
 
 /******************************************************************************
@@ -381,16 +419,14 @@
         case CLIENT_JOIN:
         {
             DBG_PRINTF("Joining...\r\n");
-            // Indicate a Join request using Nucleo LED
-            BSP_LED_On(LED_GREEN);
-            TimerStart(&NucleoLedTimer, 200);
+            HXC_BSP_RGB_Off();
 
             switch(Lora_Join())
             {
                 case AT_OK:
                 {
                 	// Start the Join status request timer and go to sleep
-                	TimerStart(&JoinStatusDelayTimer, JOIN_STATUS_REQ_DELAY);
+                	TimerStart(&JoinStatusReqTimer);
                     DeviceState = CLIENT_SLEEP;
                     break;
                 }
@@ -414,29 +450,16 @@
         {
         	if(Lora_getJoinStatus() == JOINED)
         	{
-        		// Inidicate Join status using LED
-				GPIO_InitTypeDef GPIO_InitStruct;
-    			
-    			GPIO_InitStruct.Pin = GPIO_PIN_6;
-    			GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-    			GPIO_InitStruct.Pull = GPIO_NOPULL;
-    			HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
-    			
-    			GPIO_InitStruct.Pin = GPIO_PIN_7;
-    			GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
-    			GPIO_InitStruct.Pull = GPIO_NOPULL;
-    			HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
-    			
-    			HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
-    			HAL_GPIO_WritePin(GPIOC, GPIO_PIN_7, GPIO_PIN_SET);
-    			 
+        		// Indicate Join status using LED
+    			HXC_BSP_RGB_On(PINK);
         		DBG_PRINTF("Nwk Joined\n");
+        		Lora_printDevAdr();
         		
         		// Start timer for Re-Authentication
-        		TimerStart(&RejoinTimer, REJOIN_TIME);
+        		TimerStart(&RejoinTimer);
         		
 				// Start timer for uplink transmission for sensor-data
-				TimerStart(&SensorMeasureTimer, LoraDriverParam->SensorMeasureTime);
+				TimerStart(&SensorMeasureTimer);
 				DeviceState = CLIENT_SLEEP;
         	}
         	else
@@ -459,11 +482,11 @@
 		case CLIENT_SEND:
 		{
 			// Read sensor data and populate payload
-			SendDataBinary.DataSize = LoraDriverParam->SendDataHandler(\
-			                          SendDataBinary.Buffer           ,\
-			                          MAX_PAYLOAD_SIZE                ,\
-			                          &SendDataBinary.Ack             ,\
-			                          &SendDataBinary.Port            );
+			SendDataBinary.DataSize = LoraDriverParam->UplinkHandler(\
+			                          SendDataBinary.Buffer         ,\
+			                          MAX_PAYLOAD_SIZE              ,\
+			                          &SendDataBinary.Ack           ,\
+			                          &SendDataBinary.Port          );
 			
 			// Initiate uplink transmission
 			eAtStatus_t status = Lora_SendDataBinary(&SendDataBinary);
@@ -472,7 +495,7 @@
 			{
 				DBG_PRINTF("Uplink sent\n");
 				// Schedule the next packet
-				TimerStart(&SensorMeasureTimer, LoraDriverParam->SensorMeasureTime);
+				TimerStart(&SensorMeasureTimer);
 				DeviceState = CLIENT_SLEEP;
 			}
 			else if(status == AT_TIMEOUT)
@@ -480,11 +503,14 @@
 				// Device isn't responding. Go to init.
 				DeviceState = CLIENT_INIT;
 			}
+			else if(status == AT_NO_NET_JOINED)
+            {
+                DeviceState = CLIENT_JOIN;
+            }
 			else
 			{
 				DBG_PRINTF("Uplink Failed (Error: %d)\n", (uint8_t)status);
 			}
-
 		    break;
 		}
 		case CLIENT_DATA_RECEIVED:
@@ -492,10 +518,15 @@
 			uint8_t rBuffer[64];
 			sRecvDataBinary_t rxPacket = {.Buffer = rBuffer};
 
-			Lora_ReadData(&rxPacket);
-
-			// Execute users ReceivedPacketHandler function
-			LoraDriverParam->ReceiveDataHandler(rxPacket.Buffer, rxPacket.DataSize, rxPacket.Ack, rxPacket.Port);
+			if(Lora_ReadData(&rxPacket) == AT_OK)
+			{
+				// Execute users ReceivedPacketHandler function
+				LoraDriverParam->DownlinkHandler(rxPacket.Buffer, rxPacket.DataSize, rxPacket.Ack, rxPacket.Port);
+			}
+			else
+			{
+				DBG_PRINTF("Dwlink read failed\n");
+			}
 
 			DeviceState = CLIENT_SLEEP;
 			break;
@@ -518,7 +549,8 @@
 	// Use a random delay to avoid synchronized join request from all LoRa node after power up
 	uint32_t joinDelay = (HAL_RNG_GetRandomNumber(&RngHandle) % JOIN_SEND_DELAY_MAX) + 1;
 	
-	TimerStart(&JoinRequestTimer, joinDelay);
+	TimerSetValue(&JoinRequestTimer, joinDelay);
+	TimerStart(&JoinRequestTimer);
 }
 
 /******************************************************************************
@@ -529,7 +561,6 @@
 static void OnJoinRequestTimerEvt(void)
 {
 	TimerStop(&JoinRequestTimer);
-	
 	// If this is a re-join SensorMeasureTimer is active
 	TimerStop(&SensorMeasureTimer);
 	
@@ -537,24 +568,13 @@
 }
 
 /******************************************************************************
- * @Brief  : Function executed on NucleoLedTimer Timeout event
- * @Param  : none
- * @Return : none
-******************************************************************************/
-static void OnLedTimerEvent(void)
-{
-	TimerStop(&NucleoLedTimer);
-	BSP_LED_Off(LED_GREEN);
-}
-
-/******************************************************************************
  * @Brief  : Function executed on JoinStatusDelayTimer Timeout event
  * @Param  : none
  * @Return : none
 ******************************************************************************/
-static void OnJoinStatusDelayTimerEvt(void)
+static void OnJoinStatusReqTimerEvt(void)
 {
-	TimerStop(&JoinStatusDelayTimer);
+	TimerStop(&JoinStatusReqTimer);
 	DeviceState = CLIENT_JOIN_STATUS_CHECK;
 }
 
--- a/LoRa/lora_driver.h	Mon Dec 10 19:54:23 2018 +0000
+++ b/LoRa/lora_driver.h	Thu Jan 24 21:57:23 2019 +0000
@@ -51,7 +51,7 @@
 #endif 
 
 /* Exported define -----------------------------------------------------------*/
-#define MAX_PAYLOAD_SIZE   64
+#define MAX_PAYLOAD_SIZE   64U
 
 /* Exported types ------------------------------------------------------------*/
 typedef enum eJoinMode
@@ -102,20 +102,21 @@
 
 typedef struct sLoraDriverParam
 {
-	uint32_t SensorMeasureTime;
+	uint32_t UplinkCycle;
 	// Callbacks
-	uint8_t (*SendDataHandler)(uint8_t *buffer, uint8_t bufSize, uint8_t *ack, uint8_t *port);
-	void (*ReceiveDataHandler)(uint8_t *buffer, uint8_t dataSize, uint8_t ack, uint8_t port);
+	uint8_t (*UplinkHandler)(uint8_t *buffer, uint8_t bufSize, uint8_t *ack, uint8_t *port);
+	void (*DownlinkHandler)(uint8_t *buffer, uint8_t dataSize, uint8_t ack, uint8_t port);
 }sLoraDriverParam_t;
 
 /* Public functions ----------------------------------------------------------*/
 void Lora_init(sLoraConfig_t *loraConfig, sLoraDriverParam_t *loraDriverParam);
 void Lora_fsm(void);
-uint8_t Lora_getFwVersion(void);
+uint16_t Lora_getFwVersion(void);
 uint8_t Lora_getBatteryLevel(void);
+void Lora_updateUplinkRate(uint32_t time_s);
 
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif
\ No newline at end of file
+#endif
--- a/Utilities/time_server.c	Mon Dec 10 19:54:23 2018 +0000
+++ b/Utilities/time_server.c	Thu Jan 24 21:57:23 2019 +0000
@@ -112,14 +112,6 @@
 static void TimerSetTimeout( TimerEvent_t *obj );
 
 /*!
- * \brief Set timer new timeout value
- *
- * \param [IN] obj   Structure containing the timer object parameters
- * \param [IN] value New timer timeout value
- */
-static void TimerSetValue( TimerEvent_t *obj, uint32_t value );
-
-/*!
  * \brief Check if the Object to be added is not already in the list
  * 
  * \param [IN] timestamp Delay duration
@@ -140,9 +132,8 @@
   obj->Next = NULL;
 }
 
-void TimerStart( TimerEvent_t *obj, uint32_t timeoutMs )
+void TimerStart( TimerEvent_t *obj)
 {
-  TimerSetValue(obj, timeoutMs);
   uint32_t elapsedTime = 0;
   
   BACKUP_PRIMASK();
@@ -377,11 +368,11 @@
   return false;
 }
 
-//void TimerReset( TimerEvent_t *obj )
-//{
-//  TimerStop( obj );
-//  TimerStart( obj );
-//}
+void TimerReset( TimerEvent_t *obj )
+{
+  TimerStop( obj );
+  TimerStart( obj );
+}
 
 /******************************************************************************
   * @Brief  : Set timer new timeout value
@@ -389,7 +380,7 @@
   *           value - timeout value
   * @Return : None
 ******************************************************************************/
-static void TimerSetValue( TimerEvent_t *obj, uint32_t timeoutMs )
+void TimerSetValue( TimerEvent_t *obj, uint32_t timeoutMs )
 {
   uint32_t minValue = 0;
   uint32_t ticks = HW_RTC_ms2Tick( timeoutMs );
--- a/Utilities/time_server.h	Mon Dec 10 19:54:23 2018 +0000
+++ b/Utilities/time_server.h	Thu Jan 24 21:57:23 2019 +0000
@@ -98,32 +98,36 @@
  * \param [IN] obj          Structure containing the timer object parameters
  * \param [IN] callback     Function callback called at the end of the timeout
  */
-void TimerInit( TimerEvent_t *obj, void ( *callback )( void ) );
+void TimerInit(TimerEvent_t *obj, void ( *callback )( void ));
 
-
+/*!
+ * \brief Set timer new timeout value
+ *
+ * \param [IN] obj   Structure containing the timer object parameters
+ * \param [IN] value New timer timeout value
+ */
+void TimerSetValue( TimerEvent_t *obj, uint32_t value );
 
 /*!
  * \brief Starts and adds the timer object to the list of timer events
  *
  * \param [IN] obj Structure containing the timer object parameters
- * \param [IN] timeoutMs timeout value in millisecond
  */
-void TimerStart( TimerEvent_t *obj, uint32_t timeoutMs );
+void TimerStart(TimerEvent_t *obj);
 
 /*!
  * \brief Stops and removes the timer object from the list of timer events
  *
  * \param [IN] obj Structure containing the timer object parameters
  */
-void TimerStop( TimerEvent_t *obj );
+void TimerStop(TimerEvent_t *obj);
 
 /*!
  * \brief Resets the timer object
  *
  * \param [IN] obj Structure containing the timer object parameters
  */
-//void TimerReset( TimerEvent_t *obj );
-
+void TimerReset( TimerEvent_t *obj );
 
 /*!
  * \brief Read the current time
@@ -138,7 +142,7 @@
  * \param [IN] savedTime    fix moment in Time
  * \retval time             returns elapsed time in ms
  */
-uint32_t TimerGetElapsedTime( uint32_t savedTime );
+uint32_t TimerGetElapsedTime(uint32_t savedTime);
 
 #ifdef __cplusplus
 }
--- a/Utilities/utilities.c	Mon Dec 10 19:54:23 2018 +0000
+++ b/Utilities/utilities.c	Thu Jan 24 21:57:23 2019 +0000
@@ -94,7 +94,7 @@
     }
 }
 
-uint8_t stringHexToByteArray(const char *hexString, uint8_t *buffer, int8_t bufSize)
+uint8_t stringHexToByteArray(const char *hexString, uint8_t *buffer, uint8_t bufSize)
 {
     uint8_t count = 0;
     char hex[3];
@@ -112,7 +112,7 @@
             break;
         }
         count++;
-        if (count == bufSize)
+        if (count == (bufSize - 1))
         {
           // We are out of space
           break;
@@ -121,7 +121,7 @@
         hexString += 2;
     }
 	
-	buffer[count] = NULL;
+	buffer[count] = '\0';
 	
     return count;
 }
--- a/Utilities/utilities.h	Mon Dec 10 19:54:23 2018 +0000
+++ b/Utilities/utilities.h	Thu Jan 24 21:57:23 2019 +0000
@@ -114,8 +114,8 @@
 
 /*!
  * \brief  Find First Set
- *         This function identifies the least significant index or position of the
- *         bits set to one in the word
+ *         This function identifies the least significant index or position of
+ *         the bits set to one in the word
  *
  * \param [in]  value  Value to find least significant index
  * \retval bitIndex    Index of least significat bit at one
@@ -144,7 +144,8 @@
 /*!
  * \brief Copies size elements of src array to dst array
  *
- * \remark STM32 Standard memcpy function only works on pointers that are aligned
+ * \remark STM32 Standard memcpy function only works on pointers that are
+ *         aligned
  *
  * \param [OUT] dst  Destination array
  * \param [IN]  src  Source array
@@ -153,7 +154,8 @@
 void memcpy1( uint8_t *dst, const uint8_t *src, uint16_t size );
 
 /*!
- * \brief Copies size elements of src array to dst array reversing the byte order
+ * \brief Copies size elements of src array to dst array reversing the byte
+ *        order
  *
  * \param [OUT] dst  Destination array
  * \param [IN]  src  Source array
@@ -164,7 +166,8 @@
 /*!
  * \brief Set size elements of dst array with value
  *
- * \remark STM32 Standard memset function only works on pointers that are aligned
+ * \remark STM32 Standard memset function only works on pointers that are
+ *         aligned
  *
  * \param [OUT] dst   Destination array
  * \param [IN]  value Default value
@@ -180,7 +183,19 @@
  */
 int8_t Nibble2HexChar( uint8_t a );
 
-uint8_t stringHexToByteArray(const char *hexString, uint8_t *buffer, int8_t bufSize);
+/*!
+ * \brief Converts an array of character hex digits
+ *        into an array of byte-hex
+ *
+ * \param [IN]  hexString Hex string to be converted
+ *        [IN]  buffer    Container to save the conversion
+ *        [IN]  bufSize   Size of the container
+ *
+ * \retval [OUT] uint8_t  Size of the buffer after conversion
+ *
+ * \note   It is assumed that the bufSize won't be larger than 256
+ */
+uint8_t stringHexToByteArray(const char *hexString, uint8_t *buffer, uint8_t bufSize);
 
 #endif // __UTILITIES_H__
 
--- a/lora_conf.h	Mon Dec 10 19:54:23 2018 +0000
+++ b/lora_conf.h	Thu Jan 24 21:57:23 2019 +0000
@@ -53,16 +53,28 @@
 #include <ctype.h>
 #include <string.h>
 #include "lora_driver.h"
+#include "hxcclient_bsp.h"
+
 
 /* Macros --------------------------------------------------------------------*/
-#define SENSORS_MEASURE_CYCLE  (15000U)      // Send packet every 15s
+#define UPLINK_CYCLE  (15000U)      // Send packet every 15s
+
 
 /* Private function declaration ----------------------------------------------*/
 static uint8_t GetSensorData(uint8_t *buffer, uint8_t bufSize, uint8_t *ack, uint8_t *port);
-static void LedControl(uint8_t *buffer, uint8_t dataSize, uint8_t ack, uint8_t port);
-static void tolower_array(char *array, uint8_t arraySize);
+static void LedControl(uint8_t *buffer, uint8_t dataSize);
+static void UpdateUplinkRate(uint8_t *buffer, uint8_t dataSize);
+static void ParseDownlink(uint8_t *buffer, uint8_t dataSize, uint8_t ack, uint8_t port);
+static void TolowerArray(char *array, uint8_t arraySize);
+
 
 /* Private variables ---------------------------------------------------------*/
+enum DownlinkType
+{
+    DW_LED = 1,
+    DW_UPLINK_RATE,
+}eDownlinkType;
+
 static sLoraConfig_t LoraConfigParam =
 {
     .JoinMode  = OTAA,
@@ -75,9 +87,9 @@
 
 static sLoraDriverParam_t LoraDriverParam =
 {
-    .SensorMeasureTime  = SENSORS_MEASURE_CYCLE,
-    .SendDataHandler    = GetSensorData,
-    .ReceiveDataHandler = LedControl
+    .UplinkCycle     = UPLINK_CYCLE,
+    .UplinkHandler   = GetSensorData,
+    .DownlinkHandler = ParseDownlink
 };
 
 /* Private function definitions ----------------------------------------------*/
@@ -91,18 +103,15 @@
     /* Prepare an unconfirmed uplink packet for port 2 */   
     uint8_t size = 0;
     
-    // Converts and read the analog input value (value from 0.0 to 1.0)
-    float temperatureValue = temperatureSensor.read();   
-    // Change the value to be in the 0 to 3300 range   
-    uint16_t temperatureValueInt = temperatureValue * 3300; 
-    // Checkout our user manual to convert temperatureValueInt into degree Celcius
+    uint16_t tempInt = HXC_BSP_GetTemperature();
+    // Checkout our user manual to convert tempInt into degree Celcius
     
     
-    buffer[size++] = Lora_getFwVersion();
+    buffer[size++] = (uint8_t)Lora_getFwVersion(); // This function returns uint16_t
     buffer[size++] = Lora_getBatteryLevel();
-    buffer[size++] = (temperatureValueInt >> 8) & 0xFF;
-    buffer[size++] = temperatureValueInt & 0xFF;
-    buffer[size++] = slideSwitch;
+    buffer[size++] = (tempInt >> 8) & 0xFF;
+    buffer[size++] = tempInt & 0xFF;
+    buffer[size++] = HXC_BSP_GetSlideSwitchStatus();
     
     *ack = (uint8_t)UNCONFIRMED;
     *port = 2;
@@ -117,43 +126,67 @@
  * @Param : Payload buffer, data size, ack configuration and port
  * @Return: None
 ******************************************************************************/
-static void LedControl(uint8_t *buffer, uint8_t dataSize, uint8_t ack, uint8_t port)
+static void ParseDownlink(uint8_t *buffer, uint8_t dataSize, uint8_t ack, uint8_t port)
 {
-    tolower_array((char *)buffer, dataSize);
+    switch(port)
+    {
+        case DW_LED:
+        {
+            LedControl(buffer, dataSize);
+            break;
+        }
+        case DW_UPLINK_RATE:
+        {
+            UpdateUplinkRate(buffer, dataSize);
+            break;
+        }
+        default:
+        {
+            break;
+        }
+    }
+}
+static void LedControl(uint8_t *buffer, uint8_t dataSize)
+{
+    TolowerArray((char *)buffer, dataSize);
     
     if(strncmp("red", (const char *)buffer, 3) == 0)
     {
-        redLED   = 1;
-        greenLED = 0;
-        blueLED  = 0;   
+        HXC_BSP_RGB_On(RED);
     }
     else if(strncmp("green", (const char *)buffer, 5) == 0)
     {
-        redLED   = 0;
-        greenLED = 1;
-        blueLED  = 0;
+        HXC_BSP_RGB_On(GREEN);
     }
     else if(strncmp("blue", (const char *)buffer, 4) == 0)
     {
-        redLED   = 0;
-        greenLED = 0;
-        blueLED  = 1;
+        HXC_BSP_RGB_On(BLUE);
+    }
+    else if(strncmp("off", (const char *)buffer, 3) == 0)
+    {
+        HXC_BSP_RGB_Off();
     }
-    else if(strncmp("off", (const char *)buffer, 4) == 0)
+    else
     {
-        redLED   = 0;
-        greenLED = 0;
-        blueLED  = 0;
+        // Users can send any combinations of the RGB
+        // using last 3bits. eLedColor_t is arranged
+        // in chronological order.
+        HXC_BSP_RGB_On((eLedColor_t)(buffer[0] & 0x07));
     }
 }
 
+static void UpdateUplinkRate(uint8_t *buffer, uint8_t dataSize)
+{
+  //Lora_updateUplinkRate();
+}
+
 
 /******************************************************************************
  * @Brief : Upper case to lower case for an array
  * @Param : Pointer to array containing characters and array size
  * @Return: None
 ******************************************************************************/
-static void tolower_array(char *array, uint8_t arraySize)
+static void TolowerArray(char *array, uint8_t arraySize)
 {
     for(uint8_t i = 0; i < arraySize; i++)
     {
@@ -165,4 +198,4 @@
 }
 #endif /* __cplusplus */
 
-#endif
\ No newline at end of file
+#endif
--- a/main.cpp	Mon Dec 10 19:54:23 2018 +0000
+++ b/main.cpp	Thu Jan 24 21:57:23 2019 +0000
@@ -43,9 +43,17 @@
   ******************************************************************************
   */
 #include "mbed.h"
-#include "main.h"
+#include "hw.h"
+#include "hxcclient_bsp.h"
 #include "lora_conf.h"
 
+/* Variables -----------------------------------------------------------------*/
+//Flag to indicate if the MCU is Initialized
+static bool McuInitialized = false;
+
+/* Function Declarations -----------------------------------------------------*/
+void SystemClock_Config(void);
+void HW_Init(void);
 
 int main()
 {
@@ -60,5 +68,125 @@
     }
 }
 
+/******************************************************************************
+  * @Brief : This function initializes the hardware
+  * @Param : None
+  * @Return: None
+******************************************************************************/
+void HW_Init(void)
+{
+  if(McuInitialized == false)
+  {
+    // Reset of all peripherals, Initializes the Flash interface and the Systick.
+    HAL_Init();
+    SystemClock_Config();
+    Debug_UART_Init();
+    HW_RTC_Init();
+    BSP_LED_Init(LED_GREEN);// LED on Nucleo board
+    HXC_BSP_Init();
+    McuInitialized = true;
+  }
+}
+
+/******************************************************************************
+  * @Brief :  System Clock Configuration
+  * The system Clock is configured as follow :
+  *      System Clock source            = PLL (HSI)
+  *      SYSCLK(Hz)                     = 32000000
+  *      HCLK(Hz)                       = 32000000
+  *      AHB Prescaler                  = 1
+  *      APB1 Prescaler                 = 1
+  *      APB2 Prescaler                 = 1
+  *      HSI Frequency(Hz)              = 16000000
+  *      PLLMUL                         = 6
+  *      PLLDIV                         = 3
+  *      Flash Latency(WS)              = 1
+  * @Return: None
+  * @Note  : This function enables all the clock necessary for the demo
+  *          including UARTs
+******************************************************************************/
+void SystemClock_Config(void)
+{
+    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
+    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
+
+    // Enable HSI48 Oscillator for RNG analog part
+    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
+    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
+    RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
+    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
+    {
+      // Initialization Error
+      Error_Handler();
+    }
+
+    // Set Voltage scale1 as MCU will run at 32MHz
+    __HAL_RCC_PWR_CLK_ENABLE();
+    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
+
+    // Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0
+    while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};
+
+    // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
+    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
+    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
+    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
+    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
+    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
+    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
+    {
+        Error_Handler();
+    }
+
+    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
+    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
+
+    // SysTick_IRQn interrupt configuration
+    HAL_NVIC_SetPriority(SysTick_IRQn, 1, 0);
+}
+
+/******************************************************************************
+  * @Brief : Initializes the MSP.
+  * @Param : None
+  * @Return: None
+******************************************************************************/
+void HAL_MspInit(void)
+{
+    __HAL_RCC_PWR_CLK_ENABLE();
+
+    // Disable the Power Voltage Detector
+    HAL_PWR_DisablePVD();
+
+    // Enables the Ultra Low Power mode
+    HAL_PWREx_EnableUltraLowPower();
+
+    __HAL_FLASH_SLEEP_POWERDOWN_ENABLE();
+
+    /* In debug mode, e.g. when DBGMCU is activated, Arm core has always clocks
+     * And will not wait that the FLACH is ready to be read. It can miss in this
+     * case the first instruction. To overcome this issue, the flash remain clocked during sleep mode
+     */
+    DBG( __HAL_FLASH_SLEEP_POWERDOWN_DISABLE(); );
+    /*Enable fast wakeUp*/
+    HAL_PWREx_EnableFastWakeUp( );
+}
+
+#ifdef USE_FULL_ASSERT
+
+/******************************************************************************
+   * @Brief : Reports the name of the source file and the source line number
+   *          where the assert_param error has occurred.
+   * @Param : file: pointer to the source file name
+   *          line: assert_param error line source number
+   * @Return: None
+******************************************************************************/
+void assert_failed(uint8_t* file, uint32_t line)
+{
+  /* User can add his own implementation to report the file name and line number,
+    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
+}
+
+#endif
+
 /************************ (C) COPYRIGHT Haxiot ***** END OF FILE ****/
 
--- a/main.h	Mon Dec 10 19:54:23 2018 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,204 +0,0 @@
-/*
-  _    _            _____   _______
- | |  | |          |_   _| |__   __|
- | |__| | __ ___  __ | |  ___ | |
- |  __  |/ _` \ \/ / | | / _ \| |
- | |  | | (_| |>  < _| || (_) | |
- |_|  |_|\__,_/_/\_\_____\___/|_|
-    (C)2017 HaxIoT
-
-Description: contains hardware configuration Macros and Constants
-License: Revised BSD License, see LICENSE.TXT file include in the project
-*/
-/*******************************************************************************
-  * @File Name    : main.h
-  * @Author       : Fahad Mirza (Haxiot)
-  * @Version 	  : V1.0.0
-  * @Modified     : 18 October, 2018
-  * @Description  : Header file for main.c
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; COPYRIGHT(c) 2017 Haxiot</center></h2>
-  *
-  * 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 Haxiot nor the names of its contributors
-  *      may be used to endorse or promote products derived from this software
-  *      without specific prior written permission.
-  *
-  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-  *
-  ******************************************************************************
-  */
-  
-#ifndef MAIN_H_
-#define MAIN_H_
-
-#ifdef __cplusplus
- extern "C" {
-#endif 
-
-#include "hw.h"
-#include "debug.h"
-#include "delay.h"
-#include "low_power_manager.h"
-
-/* Variables -----------------------------------------------------------------*/
-//Flag to indicate if the MCU is Initialized
-static bool McuInitialized = false;
-
-// Mbed specific declaration
-AnalogIn temperatureSensor(A0);
-DigitalOut nucleoLED(LED1);
-DigitalIn slideSwitch(D12);
-DigitalOut greenLED(D11);
-DigitalOut redLED(D10);
-DigitalOut blueLED(D9);
-
-
-/* Function Declarations -----------------------------------------------------*/
-void SystemClock_Config(void);
-
-
-/******************************************************************************
-  * @Brief : This function initializes the hardware
-  * @Param : None
-  * @Return: None
-******************************************************************************/
-void HW_Init(void)
-{
-  if(McuInitialized == false)
-  {
-  	// Reset of all peripherals, Initializes the Flash interface and the Systick.
-    HAL_Init();
-    SystemClock_Config();
-    Debug_UART_Init();
-    HW_RTC_Init();
-    BSP_LED_Init(LED_GREEN);// LED on Nucleo board
-    slideSwitch.mode(PullDown);
-    McuInitialized = true;
-  }
-}
-
-/******************************************************************************
-  * @Brief :  System Clock Configuration
-  * The system Clock is configured as follow :
-  *      System Clock source            = PLL (HSI)
-  *      SYSCLK(Hz)                     = 32000000
-  *      HCLK(Hz)                       = 32000000
-  *      AHB Prescaler                  = 1
-  *      APB1 Prescaler                 = 1
-  *      APB2 Prescaler                 = 1
-  *      HSI Frequency(Hz)              = 16000000
-  *      PLLMUL                         = 6
-  *      PLLDIV                         = 3
-  *      Flash Latency(WS)              = 1
-  * @Return: None
-  * @Note  : This function enables all the clock necessary for the demo
-  *          including UARTs
-******************************************************************************/
-void SystemClock_Config(void)
-{
-	RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
-    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
-
-    // Enable HSI48 Oscillator for RNG analog part
-    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48;
-    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
-    RCC_OscInitStruct.HSI48State = RCC_HSI48_ON;
-    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
-    {
-      // Initialization Error
-      Error_Handler();
-    }
-
-    // Set Voltage scale1 as MCU will run at 32MHz
-    __HAL_RCC_PWR_CLK_ENABLE();
-    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
-
-    // Poll VOSF bit of in PWR_CSR. Wait until it is reset to 0
-    while (__HAL_PWR_GET_FLAG(PWR_FLAG_VOS) != RESET) {};
-
-    // Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 clocks dividers
-    RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
-    RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
-    RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
-    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
-    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
-    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
-    {
-    	Error_Handler();
-    }
-
-    HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
-    HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
-
-    // SysTick_IRQn interrupt configuration
-    HAL_NVIC_SetPriority(SysTick_IRQn, 1, 0);
-}
-
-/******************************************************************************
-  * @Brief : Initializes the MSP.
-  * @Param : None
-  * @Return: None
-******************************************************************************/
-void HAL_MspInit(void)
-{
-	__HAL_RCC_PWR_CLK_ENABLE();
-
-	// Disable the Power Voltage Detector
-	HAL_PWR_DisablePVD();
-
-	// Enables the Ultra Low Power mode
-	HAL_PWREx_EnableUltraLowPower();
-
-	__HAL_FLASH_SLEEP_POWERDOWN_ENABLE();
-
-	/* In debug mode, e.g. when DBGMCU is activated, Arm core has always clocks
-	 * And will not wait that the FLACH is ready to be read. It can miss in this
-	 * case the first instruction. To overcome this issue, the flash remain clocked during sleep mode
-	 */
-	DBG( __HAL_FLASH_SLEEP_POWERDOWN_DISABLE(); );
-	/*Enable fast wakeUp*/
-	HAL_PWREx_EnableFastWakeUp( );
-}
-
-
-#ifdef USE_FULL_ASSERT
-
-/******************************************************************************
-   * @Brief : Reports the name of the source file and the source line number
-   *          where the assert_param error has occurred.
-   * @Param : file: pointer to the source file name
-   *          line: assert_param error line source number
-   * @Return: None
-******************************************************************************/
-void assert_failed(uint8_t* file, uint32_t line)
-{
-  /* User can add his own implementation to report the file name and line number,
-    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
-}
-
-#endif
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* MAIN_H_ */
-