/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file lora_app.c
* @author MCD Application Team
* @brief Application of the LRWAN Middleware
******************************************************************************
* @attention
*
* Copyright (c) 2021 STMicroelectronics.
* All rights reserved.
*
* This software is licensed under terms that can be found in the LICENSE file
* in the root directory of this software component.
* If no LICENSE file comes with this software, it is provided AS-IS.
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "platform.h"
#include "sys_app.h"
#include "lora_app.h"
#include "stm32_seq.h"
#include "stm32_timer.h"
#include "utilities_def.h"
#include "app_version.h"
#include "lorawan_version.h"
#include "subghz_phy_version.h"
#include "lora_info.h"
#include "LmHandler.h"
#include "adc_if.h"
#include "CayenneLpp.h"
#include "sys_sensors.h"
#include "flash_if.h"
#include "aplicacao.h"
#include <stdio.h>
unsigned char movimento_uplink=0;
extern UART_HandleTypeDef huart2;
extern char tx_buffer [100];
extern unsigned char join;
extern unsigned int nivel_bateria;
extern long alarme_posicao;
extern unsigned char Get_Bat(void);
extern uint8_t Get_Alarms (unsigned char Val);
extern union UN_ALM un_ALM;
extern union UN_DOWNLINK un_DOWNLINK;
extern void Sinaliza_Joined(void);
extern unsigned char Maq_Est_Status_Join;
extern unsigned char status_monitor;
extern unsigned char trava_send_uplink;
extern unsigned char monitor_alarme;
extern unsigned char histerese_alarme;
extern unsigned int tempo_acorda;
extern float valor_porcento_anterior;
extern float valor_porcento;
uint8_t temperatura_celcius;
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* External variables ---------------------------------------------------------*/
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/* Private typedef -----------------------------------------------------------*/
/**
* @brief LoRa State Machine states
*/
typedef enum TxEventType_e
{
/**
* @brief Appdata Transmission issue based on timer every TxDutyCycleTime
*/
TX_ON_TIMER,
/**
* @brief Appdata Transmission external event plugged on OnSendEvent( )
*/
TX_ON_EVENT
/* USER CODE BEGIN TxEventType_t */
/* USER CODE END TxEventType_t */
} TxEventType_t;
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/**
* LEDs period value of the timer in ms
*/
#define LED_PERIOD_TIME 500
/**
* Join switch period value of the timer in ms
*/
#define JOIN_TIME 2000
/*---------------------------------------------------------------------------*/
/* LoRaWAN NVM configuration */
/*---------------------------------------------------------------------------*/
/**
* @brief LoRaWAN NVM Flash address
* @note last 2 sector of a 128kBytes device
*/
#define LORAWAN_NVM_BASE_ADDRESS ((void *)0x0803F000UL)
/* USER CODE BEGIN PD */
static const char *slotStrings[] = { "1", "2", "C", "C_MC", "P", "P_MC" };
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private function prototypes -----------------------------------------------*/
/**
* @brief LoRa End Node send request
*/
static void SendTxData(void);
/**
* @brief TX timer callback function
* @param context ptr of timer context
*/
static void OnTxTimerEvent(void *context);
/**
* @brief join event callback function
* @param joinParams status of join
*/
static void OnJoinRequest(LmHandlerJoinParams_t *joinParams);
/**
* @brief callback when LoRaWAN application has sent a frame
* @brief tx event callback function
* @param params status of last Tx
*/
static void OnTxData(LmHandlerTxParams_t *params);
/**
* @brief callback when LoRaWAN application has received a frame
* @param appData data received in the last Rx
* @param params status of last Rx
*/
static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params);
/**
* @brief callback when LoRaWAN Beacon status is updated
* @param params status of Last Beacon
*/
static void OnBeaconStatusChange(LmHandlerBeaconParams_t *params);
/**
* @brief callback when system time has been updated
*/
static void OnSysTimeUpdate(void);
/**
* @brief callback when LoRaWAN application Class is changed
* @param deviceClass new class
*/
static void OnClassChange(DeviceClass_t deviceClass);
/**
* @brief LoRa store context in Non Volatile Memory
*/
static void StoreContext(void);
/**
* @brief stop current LoRa execution to switch into non default Activation mode
*/
static void StopJoin(void);
/**
* @brief Join switch timer callback function
* @param context ptr of Join switch context
*/
static void OnStopJoinTimerEvent(void *context);
/**
* @brief Notifies the upper layer that the NVM context has changed
* @param state Indicates if we are storing (true) or restoring (false) the NVM context
*/
static void OnNvmDataChange(LmHandlerNvmContextStates_t state);
/**
* @brief Store the NVM Data context to the Flash
* @param nvm ptr on nvm structure
* @param nvm_size number of data bytes which were stored
*/
static void OnStoreContextRequest(void *nvm, uint32_t nvm_size);
/**
* @brief Restore the NVM Data context from the Flash
* @param nvm ptr on nvm structure
* @param nvm_size number of data bytes which were restored
*/
static void OnRestoreContextRequest(void *nvm, uint32_t nvm_size);
/**
* Will be called each time a Radio IRQ is handled by the MAC layer
*
*/
static void OnMacProcessNotify(void);
/**
* @brief Change the periodicity of the uplink frames
* @param periodicity uplink frames period in ms
* @note Compliance test protocol callbacks
*/
static void OnTxPeriodicityChanged(uint32_t periodicity);
/**
* @brief Change the confirmation control of the uplink frames
* @param isTxConfirmed Indicates if the uplink requires an acknowledgement
* @note Compliance test protocol callbacks
*/
static void OnTxFrameCtrlChanged(LmHandlerMsgTypes_t isTxConfirmed);
/**
* @brief Change the periodicity of the ping slot frames
* @param pingSlotPeriodicity ping slot frames period in ms
* @note Compliance test protocol callbacks
*/
static void OnPingSlotPeriodicityChanged(uint8_t pingSlotPeriodicity);
/**
* @brief Will be called to reset the system
* @note Compliance test protocol callbacks
*/
static void OnSystemReset(void);
/* USER CODE BEGIN PFP */
/**
* @brief LED Tx timer callback function
* @param context ptr of LED context
*/
static void OnTxTimerLedEvent(void *context);
/**
* @brief LED Rx timer callback function
* @param context ptr of LED context
*/
static void OnRxTimerLedEvent(void *context);
/**
* @brief LED Join timer callback function
* @param context ptr of LED context
*/
static void OnJoinTimerLedEvent(void *context);
/* USER CODE END PFP */
/* Private variables ---------------------------------------------------------*/
/**
* @brief LoRaWAN default activation type
*/
static ActivationType_t ActivationType = LORAWAN_DEFAULT_ACTIVATION_TYPE;
/**
* @brief LoRaWAN force rejoin even if the NVM context is restored
*/
static bool ForceRejoin = LORAWAN_FORCE_REJOIN_AT_BOOT;
/**
* @brief LoRaWAN handler Callbacks
*/
static LmHandlerCallbacks_t LmHandlerCallbacks =
{
.GetBatteryLevel = GetBatteryLevel,
.GetTemperature = GetTemperatureLevel,
.GetUniqueId = GetUniqueId,
.GetDevAddr = GetDevAddr,
.OnRestoreContextRequest = OnRestoreContextRequest,
.OnStoreContextRequest = OnStoreContextRequest,
.OnMacProcess = OnMacProcessNotify,
.OnNvmDataChange = OnNvmDataChange,
.OnJoinRequest = OnJoinRequest,
.OnTxData = OnTxData,
.OnRxData = OnRxData,
.OnBeaconStatusChange = OnBeaconStatusChange,
.OnSysTimeUpdate = OnSysTimeUpdate,
.OnClassChange = OnClassChange,
.OnTxPeriodicityChanged = OnTxPeriodicityChanged,
.OnTxFrameCtrlChanged = OnTxFrameCtrlChanged,
.OnPingSlotPeriodicityChanged = OnPingSlotPeriodicityChanged,
.OnSystemReset = OnSystemReset,
};
/**
* @brief LoRaWAN handler parameters
*/
static LmHandlerParams_t LmHandlerParams =
{
.ActiveRegion = ACTIVE_REGION,
.DefaultClass = LORAWAN_DEFAULT_CLASS,
.AdrEnable = LORAWAN_ADR_STATE,
.IsTxConfirmed = LORAWAN_DEFAULT_CONFIRMED_MSG_STATE,
.TxDatarate = LORAWAN_DEFAULT_DATA_RATE,
.TxPower = LORAWAN_DEFAULT_TX_POWER,
.PingSlotPeriodicity = LORAWAN_DEFAULT_PING_SLOT_PERIODICITY,
.RxBCTimeout = LORAWAN_DEFAULT_CLASS_B_C_RESP_TIMEOUT
};
/**
* @brief Type of Event to generate application Tx
*/
static TxEventType_t EventType = TX_ON_TIMER;
/**
* @brief Timer to handle the application Tx
*/
static UTIL_TIMER_Object_t TxTimer;
/**
* @brief Tx Timer period
*/
static UTIL_TIMER_Time_t TxPeriodicity = APP_TX_DUTYCYCLE;
/**
* @brief Join Timer period
*/
static UTIL_TIMER_Object_t StopJoinTimer;
/* USER CODE BEGIN PV */
/**
* @brief User application buffer
*/
static uint8_t AppDataBuffer[LORAWAN_APP_DATA_BUFFER_MAX_SIZE];
/**
* @brief User application data structure
*/
static LmHandlerAppData_t AppData = { 0, 0, AppDataBuffer };
/**
* @brief Specifies the state of the application LED
*/
static uint8_t AppLedStateOn = RESET;
/**
* @brief Timer to handle the application Tx Led to toggle
*/
static UTIL_TIMER_Object_t TxLedTimer;
/**
* @brief Timer to handle the application Rx Led to toggle
*/
static UTIL_TIMER_Object_t RxLedTimer;
/**
* @brief Timer to handle the application Join Led to toggle
*/
static UTIL_TIMER_Object_t JoinLedTimer;
/* USER CODE END PV */
/* Exported functions ---------------------------------------------------------*/
/* USER CODE BEGIN EF */
/* USER CODE END EF */
void LoRaWAN_Init(void)
{
/* USER CODE BEGIN LoRaWAN_Init_LV */
uint32_t feature_version = 0UL;
/* USER CODE END LoRaWAN_Init_LV */
/* USER CODE BEGIN LoRaWAN_Init_1 */
/* Get LoRaWAN APP version*/
APP_LOG(TS_OFF, VLEVEL_M, "APPLICATION_VERSION: V%X.%X.%X\r\n",
(uint8_t)(APP_VERSION_MAIN),
(uint8_t)(APP_VERSION_SUB1),
(uint8_t)(APP_VERSION_SUB2));
/* Get MW LoRaWAN info */
APP_LOG(TS_OFF, VLEVEL_M, "MW_LORAWAN_VERSION: V%X.%X.%X\r\n",
(uint8_t)(LORAWAN_VERSION_MAIN),
(uint8_t)(LORAWAN_VERSION_SUB1),
(uint8_t)(LORAWAN_VERSION_SUB2));
/* Get MW SubGhz_Phy info */
APP_LOG(TS_OFF, VLEVEL_M, "MW_RADIO_VERSION: V%X.%X.%X\r\n",
(uint8_t)(SUBGHZ_PHY_VERSION_MAIN),
(uint8_t)(SUBGHZ_PHY_VERSION_SUB1),
(uint8_t)(SUBGHZ_PHY_VERSION_SUB2));
/* Get LoRaWAN Link Layer info */
LmHandlerGetVersion(LORAMAC_HANDLER_L2_VERSION, &feature_version);
APP_LOG(TS_OFF, VLEVEL_M, "L2_SPEC_VERSION: V%X.%X.%X\r\n",
(uint8_t)(feature_version >> 24),
(uint8_t)(feature_version >> 16),
(uint8_t)(feature_version >> 8));
/* Get LoRaWAN Regional Parameters info */
LmHandlerGetVersion(LORAMAC_HANDLER_REGION_VERSION, &feature_version);
APP_LOG(TS_OFF, VLEVEL_M, "RP_SPEC_VERSION: V%X-%X.%X.%X\r\n",
(uint8_t)(feature_version >> 24),
(uint8_t)(feature_version >> 16),
(uint8_t)(feature_version >> 8),
(uint8_t)(feature_version));
UTIL_TIMER_Create(&TxLedTimer, LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnTxTimerLedEvent, NULL);
UTIL_TIMER_Create(&RxLedTimer, LED_PERIOD_TIME, UTIL_TIMER_ONESHOT, OnRxTimerLedEvent, NULL);
UTIL_TIMER_Create(&JoinLedTimer, LED_PERIOD_TIME, UTIL_TIMER_PERIODIC, OnJoinTimerLedEvent, NULL);
if (FLASH_IF_Init(NULL) != FLASH_IF_OK)
{
Error_Handler();
}
/* USER CODE END LoRaWAN_Init_1 */
UTIL_TIMER_Create(&StopJoinTimer, JOIN_TIME, UTIL_TIMER_ONESHOT, OnStopJoinTimerEvent, NULL);
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LmHandlerProcess), UTIL_SEQ_RFU, LmHandlerProcess);
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), UTIL_SEQ_RFU, SendTxData);
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaStoreContextEvent), UTIL_SEQ_RFU, StoreContext);
UTIL_SEQ_RegTask((1 << CFG_SEQ_Task_LoRaStopJoinEvent), UTIL_SEQ_RFU, StopJoin);
/* Init Info table used by LmHandler*/
LoraInfo_Init();
/* Init the Lora Stack*/
LmHandlerInit(&LmHandlerCallbacks, APP_VERSION);
LmHandlerConfigure(&LmHandlerParams);
/* USER CODE BEGIN LoRaWAN_Init_2 */
UTIL_TIMER_Start(&JoinLedTimer);
/* USER CODE END LoRaWAN_Init_2 */
LmHandlerJoin(ActivationType, ForceRejoin);
if (EventType == TX_ON_TIMER)
{
/* send every time timer elapses */
UTIL_TIMER_Create(&TxTimer, TxPeriodicity, UTIL_TIMER_ONESHOT, OnTxTimerEvent, NULL);
UTIL_TIMER_Start(&TxTimer);
}
else
{
/* USER CODE BEGIN LoRaWAN_Init_3 */
/* USER CODE END LoRaWAN_Init_3 */
}
/* USER CODE BEGIN LoRaWAN_Init_Last */
/* USER CODE END LoRaWAN_Init_Last */
}
/* USER CODE BEGIN PB_Callbacks */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
switch (GPIO_Pin)
{
case BUT1_Pin:
//Note: when "EventType == TX_ON_TIMER" this GPIO is not initialized
if (EventType == TX_ON_EVENT)
{
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0);
}
break;
case BUT2_Pin:
if (EventType == TX_ON_EVENT)
{
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0);
}
break;
case BUT3_Pin:
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaStoreContextEvent), CFG_SEQ_Prio_0);
break;
default:
break;
}
}
/* USER CODE END PB_Callbacks */
/* Private functions ---------------------------------------------------------*/
/* USER CODE BEGIN PrFD */
/* USER CODE END PrFD */
static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params)
{
/* USER CODE BEGIN OnRxData_1 */
uint8_t RxPort = 0;
if (params != NULL)
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); /* LED_BLUE */
//DEF_LED_RED_ALARM_ON;
UTIL_TIMER_Start(&RxLedTimer);
if (params->IsMcpsIndication)
{
if (appData != NULL)
{
RxPort = appData->Port;
if (appData->Buffer != NULL)
{
switch (appData->Port)
{
case LORAWAN_SWITCH_CLASS_PORT:
/*this port switches the class*/
if (appData->BufferSize == 1)
{
switch (appData->Buffer[0])
{
case 0:
{
LmHandlerRequestClass(CLASS_A);
break;
}
case 1:
{
LmHandlerRequestClass(CLASS_B);
break;
}
case 2:
{
LmHandlerRequestClass(CLASS_C);
break;
}
default:
break;
}
}
break;
case LORAWAN_USER_APP_PORT:
if (appData->BufferSize == 1)
{
}
break;
default:
break;
}
}
}
}
if (params->RxSlot < RX_SLOT_NONE)
{
APP_LOG(TS_OFF, VLEVEL_H, "###### D/L FRAME:%04d | PORT:%d | DR:%d | SLOT:%s | RSSI:%d | SNR:%d\r\n",
params->DownlinkCounter, RxPort, params->Datarate, slotStrings[params->RxSlot],
params->Rssi, params->Snr);
}
}
}
static void SendTxData(void)
{
uint16_t bateria;
if(movimento_uplink==1) //Tiago: Criei essa função para enviar dados somente quando necessário
{
movimento_uplink=0;
LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR;
uint8_t batteryLevel = GetBatteryLevel();
sensor_t sensor_data;
UTIL_TIMER_Time_t nextTxIn = 0;
if (LmHandlerIsBusy() == false)
{
#ifdef CAYENNE_LPP
uint8_t channel = 0;
#else
uint16_t pressure = 0;
int16_t temperature = 0;
uint16_t humidity = 0;
uint32_t i = 0;
int32_t latitude = 0;
int32_t longitude = 0;
uint16_t altitudeGps = 0;
#endif /* CAYENNE_LPP */
EnvSensors_Read(&sensor_data);
APP_LOG(TS_ON, VLEVEL_M, "VDDA: %d\r\n", batteryLevel);
APP_LOG(TS_ON, VLEVEL_M, "temp: %d\r\n", (int16_t)(sensor_data.temperature));
AppData.Port = LORAWAN_USER_APP_PORT;
#ifdef CAYENNE_LPP
CayenneLppReset();
CayenneLppAddBarometricPressure(channel++, sensor_data.pressure);
CayenneLppAddTemperature(channel++, sensor_data.temperature);
CayenneLppAddRelativeHumidity(channel++, (uint16_t)(sensor_data.humidity));
if ((LmHandlerParams.ActiveRegion != LORAMAC_REGION_US915) && (LmHandlerParams.ActiveRegion != LORAMAC_REGION_AU915)
&& (LmHandlerParams.ActiveRegion != LORAMAC_REGION_AS923))
{
CayenneLppAddDigitalInput(channel++, GetBatteryLevel());
CayenneLppAddDigitalOutput(channel++, AppLedStateOn);
}
CayenneLppCopy(AppData.Buffer);
AppData.BufferSize = CayenneLppGetSize();
#else /* not CAYENNE_LPP */
humidity = (uint16_t)(sensor_data.humidity * 10); /* in %*10 */
temperature = (int16_t)(sensor_data.temperature);
pressure = (uint16_t)(sensor_data.pressure * 100 / 10); /* in hPa / 10 */
//AppData.Buffer[i++] = AppLedStateOn;
//AppData.Buffer[i++] = (uint8_t)((pressure >> 8) & 0xFF);
//AppData.Buffer[i++] = (uint8_t)(pressure & 0xFF);
//AppData.Buffer[i++] = (uint8_t)((humidity >> 8) & 0xFF);
//AppData.Buffer[i++] = (uint8_t)(humidity & 0xFF);
if ((LmHandlerParams.ActiveRegion == LORAMAC_REGION_US915) || (LmHandlerParams.ActiveRegion == LORAMAC_REGION_AU915)
|| (LmHandlerParams.ActiveRegion == LORAMAC_REGION_AS923))
{
/*Tiago Fernandes (17/10/2023)
Para obter um resultado exato na medição, foi utilizado uma fonte de alimentação HP ajustada
em 3,67Vdc e 2,50Vdc.
Com a fonte ajustara em 2,50Vdc a função GetBatteryLevel() enviou para o servidor TTN o valor 90
Com a fonte ajustara em 3,67Vdc a função GetBatteryLevel() enviou para o servidor TTN o valor 254
Com base nesses resultados, foi calculada a equação da reta abaixo
NOTA: Foi verificado que o módulo não consegue fazer uplink com a tensão ajustada abaixo de 2,50Vdc*/
//********************TEMPERATURA********************
AppData.Buffer[i++] = (uint8_t)(temperature & 0xFF);
temperatura_celcius = (uint8_t)(temperature & 0xFF);
//*******************************PONTO FECHADO*************************************
//*******************************PONTO FECHADO*************************************
//*******************************PONTO FECHADO*************************************
/* if(valor_porcento_anterior>=-histerese_alarme && valor_porcento_anterior<=histerese_alarme)
{
//********************BATERIA********************
//AppData.Buffer[i++] = Get_Bat();
//********************TEMPERATURA********************
AppData.Buffer[i++] = (uint8_t)(temperature & 0xFF);
temperatura_celcius = (uint8_t)(temperature & 0xFF);
//********************POSIÇÃO********************
AppData.Buffer[i++] = (int)(0);
//********************ALARMES********************
//AppData.Buffer[i++] = (uint8_t)(un_ALM.Int);
//AppData.Buffer[i++] = Get_Alarms(Get_Bat());
}*/
//*******************************PONTO ABERTO*************************************
//*******************************PONTO ABERTO*************************************
//*******************************PONTO ABERTO*************************************
/* else if(valor_porcento_anterior>=(100-histerese_alarme) && valor_porcento_anterior<=(100+histerese_alarme))
{
//********************BATERIA********************
//AppData.Buffer[i++] = Get_Bat();
//********************TEMPERATURA********************
AppData.Buffer[i++] = (uint8_t)(temperature & 0xFF);
temperatura_celcius = (uint8_t)(temperature & 0xFF);
//********************POSIÇÃO********************
AppData.Buffer[i++] = (int)(100);
//********************ALARME********************
//AppData.Buffer[i++] = Get_Alarms(Get_Bat());
}*/
/* else
{
//********************BATERIA********************
//AppData.Buffer[i++] = Get_Bat();
//********************TEMPERATURA********************
AppData.Buffer[i++] = (uint8_t)(temperature & 0xFF);
temperatura_celcius = (uint8_t)(temperature & 0xFF);
//********************POSIÇÃO********************
//AppData.Buffer[i++] = (int)(valor_porcento);
//********************ALARME********************
//AppData.Buffer[i++] = Get_Alarms(Get_Bat());
}*/
//trava_send_uplink=1;
HAL_Delay(3000); //Coloquei esse delay para dar tempo de fazer a transmissão uplink para o servidor, antes que ocorra um novo pedido de transmissão
}
else
{
latitude = sensor_data.latitude;
longitude = sensor_data.longitude;
//AppData.Buffer[i++] = GetBatteryLevel(); /* 1 (very low) to 254 (fully charged) */
AppData.Buffer[i++] = (uint8_t)((latitude >> 16) & 0xFF);
AppData.Buffer[i++] = (uint8_t)((latitude >> 8) & 0xFF);
AppData.Buffer[i++] = (uint8_t)(latitude & 0xFF);
AppData.Buffer[i++] = (uint8_t)((longitude >> 16) & 0xFF);
AppData.Buffer[i++] = (uint8_t)((longitude >> 8) & 0xFF);
AppData.Buffer[i++] = (uint8_t)(longitude & 0xFF);
AppData.Buffer[i++] = (uint8_t)((altitudeGps >> 8) & 0xFF);
AppData.Buffer[i++] = (uint8_t)(altitudeGps & 0xFF);
}
AppData.BufferSize = i;
#endif /* CAYENNE_LPP */
if ((JoinLedTimer.IsRunning) && (LmHandlerJoinStatus() == LORAMAC_HANDLER_SET))
{
UTIL_TIMER_Stop(&JoinLedTimer);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */
}
status = LmHandlerSend(&AppData, LmHandlerParams.IsTxConfirmed, false);
if (LORAMAC_HANDLER_SUCCESS == status)
{
APP_LOG(TS_ON, VLEVEL_L, "SEND REQUEST\r\n");
}
else if (LORAMAC_HANDLER_DUTYCYCLE_RESTRICTED == status)
{
nextTxIn = LmHandlerGetDutyCycleWaitTime();
if (nextTxIn > 0)
{
APP_LOG(TS_ON, VLEVEL_L, "Next Tx in : ~%d second(s)\r\n", (nextTxIn / 1000));
}
}
}
if (EventType == TX_ON_TIMER)
{
UTIL_TIMER_Stop(&TxTimer);
UTIL_TIMER_SetPeriod(&TxTimer, MAX(nextTxIn, TxPeriodicity));
UTIL_TIMER_Start(&TxTimer);
}
}
/* USER CODE END SendTxData_1 */
}
static void OnTxTimerEvent(void *context)
{
/* USER CODE BEGIN OnTxTimerEvent_1 */
/* USER CODE END OnTxTimerEvent_1 */
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaSendOnTxTimerOrButtonEvent), CFG_SEQ_Prio_0);
/*Wait for next tx slot*/
UTIL_TIMER_Start(&TxTimer);
/* USER CODE BEGIN OnTxTimerEvent_2 */
/* USER CODE END OnTxTimerEvent_2 */
}
/* USER CODE BEGIN PrFD_LedEvents */
static void OnTxTimerLedEvent(void *context)
{
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); /* LED_GREEN */
}
static void OnRxTimerLedEvent(void *context)
{
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); /* LED_BLUE */
}
static void OnJoinTimerLedEvent(void *context)
{
HAL_GPIO_TogglePin(LED3_GPIO_Port, LED3_Pin); /* LED_RED */
}
/* USER CODE END PrFD_LedEvents */
static void OnTxData(LmHandlerTxParams_t *params)
{
/* USER CODE BEGIN OnTxData_1 */
if ((params != NULL))
{
/* Process Tx event only if its a mcps response to prevent some internal events (mlme) */
if (params->IsMcpsConfirm != 0)
{
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET); /* LED_GREEN */
UTIL_TIMER_Start(&TxLedTimer);
APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### ========== MCPS-Confirm =============\r\n");
APP_LOG(TS_OFF, VLEVEL_H, "###### U/L FRAME:%04d | PORT:%d | DR:%d | PWR:%d", params->UplinkCounter,
params->AppData.Port, params->Datarate, params->TxPower);
APP_LOG(TS_OFF, VLEVEL_H, " | MSG TYPE:");
if (params->MsgType == LORAMAC_HANDLER_CONFIRMED_MSG)
{
APP_LOG(TS_OFF, VLEVEL_H, "CONFIRMED [%s]\r\n", (params->AckReceived != 0) ? "ACK" : "NACK");
}
else
{
APP_LOG(TS_OFF, VLEVEL_H, "UNCONFIRMED\r\n");
}
}
}
/* USER CODE END OnTxData_1 */
}
static void OnJoinRequest(LmHandlerJoinParams_t *joinParams)
{
/* USER CODE BEGIN OnJoinRequest_1 */
if (joinParams != NULL)
{
if (joinParams->Status == LORAMAC_HANDLER_SUCCESS)
{
UTIL_TIMER_Stop(&JoinLedTimer);
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */
APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### = JOINED = ");
if (joinParams->Mode == ACTIVATION_TYPE_ABP)
{
APP_LOG(TS_OFF, VLEVEL_M, "ABP ======================\r\n");
}
else
{
APP_LOG(TS_OFF, VLEVEL_M, "OTAA =====================\r\n");
//Sinaliza_Joined ();
Maq_Est_Status_Join = DEF_FINALIZA_PROCESSO;
DEF_LED_BLUE_CONF_ON;
HAL_Delay(1000);
DEF_LED_BLUE_CONF_OFF;
join = 1;
}
}
else
{
APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### = JOIN FAILED\r\n");
//Sinaliza_Join_Failed ();
//status_monitor = DEF_DORMINDO;
Maq_Est_Status_Join = DEF_RESET;
//Func_Reset_Fabrica();
DEF_LED_RED_ALARM_ON;
HAL_Delay(1000);
DEF_LED_RED_ALARM_OFF;
join = 0;
}
APP_LOG(TS_OFF, VLEVEL_H, "###### U/L FRAME:JOIN | DR:%d | PWR:%d\r\n", joinParams->Datarate, joinParams->TxPower);
}
/* USER CODE END OnJoinRequest_1 */
}
static void OnBeaconStatusChange(LmHandlerBeaconParams_t *params)
{
/* USER CODE BEGIN OnBeaconStatusChange_1 */
if (params != NULL)
{
switch (params->State)
{
default:
case LORAMAC_HANDLER_BEACON_LOST:
{
APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### BEACON LOST\r\n");
break;
}
case LORAMAC_HANDLER_BEACON_RX:
{
APP_LOG(TS_OFF, VLEVEL_M,
"\r\n###### BEACON RECEIVED | DR:%d | RSSI:%d | SNR:%d | FQ:%d | TIME:%d | DESC:%d | "
"INFO:02X%02X%02X %02X%02X%02X\r\n",
params->Info.Datarate, params->Info.Rssi, params->Info.Snr, params->Info.Frequency,
params->Info.Time.Seconds, params->Info.GwSpecific.InfoDesc,
params->Info.GwSpecific.Info[0], params->Info.GwSpecific.Info[1],
params->Info.GwSpecific.Info[2], params->Info.GwSpecific.Info[3],
params->Info.GwSpecific.Info[4], params->Info.GwSpecific.Info[5]);
break;
}
case LORAMAC_HANDLER_BEACON_NRX:
{
APP_LOG(TS_OFF, VLEVEL_M, "\r\n###### BEACON NOT RECEIVED\r\n");
break;
}
}
}
/* USER CODE END OnBeaconStatusChange_1 */
}
static void OnSysTimeUpdate(void)
{
/* USER CODE BEGIN OnSysTimeUpdate_1 */
/* USER CODE END OnSysTimeUpdate_1 */
}
static void OnClassChange(DeviceClass_t deviceClass)
{
/* USER CODE BEGIN OnClassChange_1 */
APP_LOG(TS_OFF, VLEVEL_M, "Switch to Class %c done\r\n", "ABC"[deviceClass]);
/* USER CODE END OnClassChange_1 */
}
static void OnMacProcessNotify(void)
{
/* USER CODE BEGIN OnMacProcessNotify_1 */
/* USER CODE END OnMacProcessNotify_1 */
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LmHandlerProcess), CFG_SEQ_Prio_0);
/* USER CODE BEGIN OnMacProcessNotify_2 */
/* USER CODE END OnMacProcessNotify_2 */
}
static void OnTxPeriodicityChanged(uint32_t periodicity)
{
/* USER CODE BEGIN OnTxPeriodicityChanged_1 */
/* USER CODE END OnTxPeriodicityChanged_1 */
TxPeriodicity = periodicity;
if (TxPeriodicity == 0)
{
/* Revert to application default periodicity */
TxPeriodicity = APP_TX_DUTYCYCLE;
}
/* Update timer periodicity */
UTIL_TIMER_Stop(&TxTimer);
UTIL_TIMER_SetPeriod(&TxTimer, TxPeriodicity);
UTIL_TIMER_Start(&TxTimer);
/* USER CODE BEGIN OnTxPeriodicityChanged_2 */
/* USER CODE END OnTxPeriodicityChanged_2 */
}
void Wakeup_Long_Timer(uint32_t periodicity)
{
/* USER CODE BEGIN OnTxPeriodicityChanged_1 */
/* USER CODE END OnTxPeriodicityChanged_1 */
//TxPeriodicity = periodicity*1000;
TxPeriodicity = periodicity;
if (TxPeriodicity == 0)
{
/* Revert to application default periodicity */
//TxPeriodicity = periodicity*1000;
TxPeriodicity = periodicity;
}
/* Update timer periodicity */
UTIL_TIMER_Stop(&TxTimer);
UTIL_TIMER_SetPeriod(&TxTimer, TxPeriodicity);
UTIL_TIMER_Start(&TxTimer);
/* USER CODE BEGIN OnTxPeriodicityChanged_2 */
/* USER CODE END OnTxPeriodicityChanged_2 */
}
void Wakeup_Short_Timer(uint32_t periodicity)
{
/* USER CODE BEGIN OnTxPeriodicityChanged_1 */
/* USER CODE END OnTxPeriodicityChanged_1 */
TxPeriodicity = periodicity*1000;
if (TxPeriodicity == 0)
{
/* Revert to application default periodicity */
TxPeriodicity = periodicity*1000;
}
/* Update timer periodicity */
UTIL_TIMER_Stop(&TxTimer);
UTIL_TIMER_SetPeriod(&TxTimer, TxPeriodicity);
UTIL_TIMER_Start(&TxTimer);
/* USER CODE BEGIN OnTxPeriodicityChanged_2 */
/* USER CODE END OnTxPeriodicityChanged_2 */
}
static void OnTxFrameCtrlChanged(LmHandlerMsgTypes_t isTxConfirmed)
{
/* USER CODE BEGIN OnTxFrameCtrlChanged_1 */
/* USER CODE END OnTxFrameCtrlChanged_1 */
LmHandlerParams.IsTxConfirmed = isTxConfirmed;
/* USER CODE BEGIN OnTxFrameCtrlChanged_2 */
/* USER CODE END OnTxFrameCtrlChanged_2 */
}
static void OnPingSlotPeriodicityChanged(uint8_t pingSlotPeriodicity)
{
/* USER CODE BEGIN OnPingSlotPeriodicityChanged_1 */
/* USER CODE END OnPingSlotPeriodicityChanged_1 */
LmHandlerParams.PingSlotPeriodicity = pingSlotPeriodicity;
/* USER CODE BEGIN OnPingSlotPeriodicityChanged_2 */
/* USER CODE END OnPingSlotPeriodicityChanged_2 */
}
static void OnSystemReset(void)
{
/* USER CODE BEGIN OnSystemReset_1 */
/* USER CODE END OnSystemReset_1 */
if ((LORAMAC_HANDLER_SUCCESS == LmHandlerHalt()) && (LmHandlerJoinStatus() == LORAMAC_HANDLER_SET))
{
NVIC_SystemReset();
}
/* USER CODE BEGIN OnSystemReset_Last */
/* USER CODE END OnSystemReset_Last */
}
static void StopJoin(void)
{
/* USER CODE BEGIN StopJoin_1 */
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); /* LED_BLUE */
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET); /* LED_GREEN */
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET); /* LED_RED */
/* USER CODE END StopJoin_1 */
UTIL_TIMER_Stop(&TxTimer);
if (LORAMAC_HANDLER_SUCCESS != LmHandlerStop())
{
APP_LOG(TS_OFF, VLEVEL_M, "LmHandler Stop on going ...\r\n");
}
else
{
APP_LOG(TS_OFF, VLEVEL_M, "LmHandler Stopped\r\n");
if (LORAWAN_DEFAULT_ACTIVATION_TYPE == ACTIVATION_TYPE_ABP)
{
ActivationType = ACTIVATION_TYPE_OTAA;
APP_LOG(TS_OFF, VLEVEL_M, "LmHandler switch to OTAA mode\r\n");
}
else
{
ActivationType = ACTIVATION_TYPE_ABP;
APP_LOG(TS_OFF, VLEVEL_M, "LmHandler switch to ABP mode\r\n");
}
LmHandlerConfigure(&LmHandlerParams);
LmHandlerJoin(ActivationType, true);
UTIL_TIMER_Start(&TxTimer);
}
UTIL_TIMER_Start(&StopJoinTimer);
/* USER CODE BEGIN StopJoin_Last */
/* USER CODE END StopJoin_Last */
}
static void OnStopJoinTimerEvent(void *context)
{
/* USER CODE BEGIN OnStopJoinTimerEvent_1 */
/* USER CODE END OnStopJoinTimerEvent_1 */
if (ActivationType == LORAWAN_DEFAULT_ACTIVATION_TYPE)
{
UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_LoRaStopJoinEvent), CFG_SEQ_Prio_0);
}
/* USER CODE BEGIN OnStopJoinTimerEvent_Last */
HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET); /* LED_BLUE */
HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET); /* LED_GREEN */
HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */
/* USER CODE END OnStopJoinTimerEvent_Last */
}
static void StoreContext(void)
{
LmHandlerErrorStatus_t status = LORAMAC_HANDLER_ERROR;
/* USER CODE BEGIN StoreContext_1 */
/* USER CODE END StoreContext_1 */
status = LmHandlerNvmDataStore();
if (status == LORAMAC_HANDLER_NVM_DATA_UP_TO_DATE)
{
APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA UP TO DATE\r\n");
}
else if (status == LORAMAC_HANDLER_ERROR)
{
APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA STORE FAILED\r\n");
}
/* USER CODE BEGIN StoreContext_Last */
/* USER CODE END StoreContext_Last */
}
static void OnNvmDataChange(LmHandlerNvmContextStates_t state)
{
/* USER CODE BEGIN OnNvmDataChange_1 */
/* USER CODE END OnNvmDataChange_1 */
if (state == LORAMAC_HANDLER_NVM_STORE)
{
APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA STORED\r\n");
}
else
{
APP_LOG(TS_OFF, VLEVEL_M, "NVM DATA RESTORED\r\n");
}
/* USER CODE BEGIN OnNvmDataChange_Last */
/* USER CODE END OnNvmDataChange_Last */
}
static void OnStoreContextRequest(void *nvm, uint32_t nvm_size)
{
/* USER CODE BEGIN OnStoreContextRequest_1 */
/* USER CODE END OnStoreContextRequest_1 */
/* store nvm in flash */
if (FLASH_IF_Erase(LORAWAN_NVM_BASE_ADDRESS, FLASH_PAGE_SIZE) == FLASH_IF_OK)
{
FLASH_IF_Write(LORAWAN_NVM_BASE_ADDRESS, (const void *)nvm, nvm_size);
}
/* USER CODE BEGIN OnStoreContextRequest_Last */
/* USER CODE END OnStoreContextRequest_Last */
}
static void OnRestoreContextRequest(void *nvm, uint32_t nvm_size)
{
/* USER CODE BEGIN OnRestoreContextRequest_1 */
/* USER CODE END OnRestoreContextRequest_1 */
FLASH_IF_Read(nvm, LORAWAN_NVM_BASE_ADDRESS, nvm_size);
/* USER CODE BEGIN OnRestoreContextRequest_Last */
/* USER CODE END OnRestoreContextRequest_Last */
}