terça-feira, 9 de julho de 2024

LSM110A - LoRaWAN - Compilando APP (LORA_ENDDEVICE) - bare metal - WISOL - EVERYNET - LA915

   


Baseado no canais de uplink, downlink, dwell, etc

LA915 · Everynet Network Server Máscara de canais (Join, Uplink, Downlink)

Foram alterados os arquivos RegionCommon.h, RegionAU915.h e RegionAU915.c para serem compatíveis com EVERYNET.

Em RegionCommon.h

/*!
 * Receive delay of 1 second.
 */
#define REGION_COMMON_DEFAULT_RECEIVE_DELAY1            5000

/*!
 * Receive delay of 2 seconds.
 */
#define REGION_COMMON_DEFAULT_RECEIVE_DELAY2            ( REGION_COMMON_DEFAULT_RECEIVE_DELAY1 + 1000 )

/*!
 * Join accept delay of 5 seconds.
 */
#define REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1        5000

/*!
 * Join accept delay of 6 seconds.
 */
#define REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2        ( REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1 + 1000 )

/*!

* \file RegionAU915.h

*

* \brief Region definition for AU915

*

* \copyright Revised BSD License, see section \ref LICENSE.

*

* \code

* ______ _

* / _____) _ | |

* ( (____ _____ ____ _| |_ _____ ____| |__

* \____ \| ___ | (_ _) ___ |/ ___) _ \

* _____) ) ____| | | || |_| ____( (___| | | |

* (______/|_____)_|_|_| \__)_____)\____)_| |_|

* (C)2013-2017 Semtech

*

* ___ _____ _ ___ _ _____ ___ ___ ___ ___

* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|

* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|

* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|

* embedded.connectivity.solutions===============

*

* \endcode

*

* \author Miguel Luis ( Semtech )

*

* \author Gregory Cristian ( Semtech )

*

* \author Daniel Jaeckle ( STACKFORCE )

*

* \author Johannes Bruder ( STACKFORCE )

*

* \defgroup REGIONAU915 Region AU915

* Implementation according to LoRaWAN Specification v1.0.2.

* \{

*/

#ifndef __REGION_AU915_H__

#define __REGION_AU915_H__


#include "region/Region.h"



#define AU915_PING_SLOT_CHANNEL_FREQ 923300000


/*!

* LoRaMac maximum number of channels

*/

#define AU915_MAX_NB_CHANNELS 72


/*!

* Minimal datarate that can be used by the node

*/

#define AU915_TX_MIN_DATARATE DR_0


/*!

* Maximal datarate that can be used by the node

*/

#define AU915_TX_MAX_DATARATE DR_5


/*!

* Minimal datarate that can be used by the node

*/

#define AU915_RX_MIN_DATARATE DR_8


/*!

* Maximal datarate that can be used by the node

*/

#define AU915_RX_MAX_DATARATE DR_13


/*!

* Default datarate used by the node

*/

#define AU915_DEFAULT_DATARATE DR_0


/*!

* The minimum datarate which is used when the

* dwell time is limited.

*/

#define AU915_DWELL_LIMIT_DATARATE DR_2


/*!

* Minimal Rx1 receive datarate offset

*/

#define AU915_MIN_RX1_DR_OFFSET 0


/*!

* Maximal Rx1 receive datarate offset

*/

#define AU915_MAX_RX1_DR_OFFSET 3


/*!

* Default Rx1 receive datarate offset

*/

#define AU915_DEFAULT_RX1_DR_OFFSET 0


/*!

* Minimal Tx output power that can be used by the node

*/

#define AU915_MIN_TX_POWER TX_POWER_10


/*!

* Maximal Tx output power that can be used by the node

*/

#define AU915_MAX_TX_POWER TX_POWER_0


/*!

* Default Tx output power used by the node

*/

#define AU915_DEFAULT_TX_POWER TX_POWER_5


/*!

* Default uplink dwell time configuration

*/

#define AU915_DEFAULT_UPLINK_DWELL_TIME 0


/*!

* Default downlink dwell time configuration

*/

#define AU915_DEFAULT_DOWNLINK_DWELL_TIME 0


/*!

* Default Max EIRP

*/

#define AU915_DEFAULT_MAX_EIRP 30.0f


/*!

* Default antenna gain

*/

#define AU915_DEFAULT_ANTENNA_GAIN 0.0f


/*!

* ADR Ack limit

*/

#define AU915_ADR_ACK_LIMIT 64


/*!

* ADR Ack delay

*/

#define AU915_ADR_ACK_DELAY 32


/*!

* Enabled or disabled the duty cycle

*/

#define AU915_DUTY_CYCLE_ENABLED 0


/*!

* Maximum RX window duration

*/

#define AU915_MAX_RX_WINDOW 1000


/*!

* Receive delay 1

*/

#define AU915_RECEIVE_DELAY1 5000


/*!

* Receive delay 2

*/

#define AU915_RECEIVE_DELAY2 6000


/*!

* Join accept delay 1

*/

#define AU915_JOIN_ACCEPT_DELAY1 5000


/*!

* Join accept delay 2

*/

#define AU915_JOIN_ACCEPT_DELAY2 6000


/*!

* Maximum frame counter gap

*/

#define AU915_MAX_FCNT_GAP 16384


/*!

* Ack timeout

*/

#define AU915_ACKTIMEOUT 2000


/*!

* Random ack timeout limits

*/

#define AU915_ACK_TIMEOUT_RND 1000


/*!

* Second reception window channel frequency definition.

*/

#define AU915_RX_WND_2_FREQ 923300000


/*!

* Second reception window channel datarate definition.

*/

#define AU915_RX_WND_2_DR DR_8


/*

* CLASS B

*/

/*!

* Beacon frequency

*/

#define AU915_BEACON_CHANNEL_FREQ 923300000


/*!

* Beacon frequency channel stepwidth

*/

#define AU915_BEACON_CHANNEL_STEPWIDTH 600000


/*!

* Number of possible beacon channels

*/

#define AU915_BEACON_NB_CHANNELS 8


/*!

* Payload size of a beacon frame

*/

#define AU915_BEACON_SIZE 19


/*!

* Size of RFU 1 field

*/

#define AU915_RFU1_SIZE 3


/*!

* Size of RFU 2 field

*/

#define AU915_RFU2_SIZE 1


/*!

* Datarate of the beacon channel

*/

#define AU915_BEACON_CHANNEL_DR DR_10


/*!

* Bandwith of the beacon channel

*/

#define AU915_BEACON_CHANNEL_BW 2


/*!

* Ping slot channel datarate

*/

#define AU915_PING_SLOT_CHANNEL_DR DR_10


/*!

* LoRaMac maximum number of bands

*/

#define AU915_MAX_NB_BANDS 1


/*!

* Band 0 definition

* { DutyCycle, TxMaxPower, LastJoinTxDoneTime, LastTxDoneTime, TimeOff }

*/

#define AU915_BAND0 { 1, AU915_MAX_TX_POWER, 0, 0, 0 } // 100.0 %


/*!

* Defines the first channel for RX window 1 for US band

*/

#define AU915_FIRST_RX1_CHANNEL ( (uint32_t) 923300000 )


/*!

* Defines the last channel for RX window 1 for US band

*/

#define AU915_LAST_RX1_CHANNEL ( (uint32_t) 927500000 )


/*!

* Defines the step width of the channels for RX window 1

*/

#define AU915_STEPWIDTH_RX1_CHANNEL ( (uint32_t) 600000 )


/*!

* Data rates table definition

*/

static const uint8_t DataratesAU915[] = { 12, 11, 10, 9, 8, 7, 8, 0, 12, 11, 10, 9, 8, 7, 0, 0 };


/*!

* Bandwidths table definition in Hz

*/

static const uint32_t BandwidthsAU915[] = { 125000, 125000, 125000, 125000, 125000, 125000, 500000, 0, 500000, 500000, 500000, 500000, 500000, 500000, 0, 0 };


/*!

* Up/Down link data rates offset definition

*/

static const int8_t DatarateOffsetsAU915[7][6] =

{

{ DR_8 , DR_8 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_0

{ DR_9 , DR_8 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_1

{ DR_10, DR_9 , DR_8 , DR_8 , DR_8 , DR_8 }, // DR_2

{ DR_11, DR_10, DR_9 , DR_8 , DR_8 , DR_8 }, // DR_3

{ DR_12, DR_11, DR_10, DR_9 , DR_8 , DR_8 }, // DR_4

{ DR_13, DR_12, DR_11, DR_10, DR_9 , DR_8 }, // DR_5

{ DR_13, DR_13, DR_12, DR_11, DR_10, DR_9 }, // DR_6

};


/*!

* Maximum payload with respect to the datarate index. Cannot operate with repeater.

* The table is valid for the dwell time configuration of 0 for uplinks.

*/

static const uint8_t MaxPayloadOfDatarateDwell0AU915[] = { 51, 51, 51, 115, 242, 242, 242, 0, 53, 129, 242, 242, 242, 242, 0, 0 };


/*!

* Maximum payload with respect to the datarate index. Can operate with repeater.

* The table is valid for the dwell time configuration of 0 for uplinks. The table provides

* repeater support.

*/

static const uint8_t MaxPayloadOfDatarateRepeaterDwell0AU915[] = { 51, 51, 51, 115, 222, 222, 222, 0, 33, 109, 222, 222, 222, 222, 0, 0 };


/*!

* Maximum payload with respect to the datarate index. Cannot operate with repeater.

* The table is valid for the dwell time configuration of 1 for uplinks.

*/

static const uint8_t MaxPayloadOfDatarateDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 53, 129, 129, 242, 242, 242, 242 };


/*!

* Maximum payload with respect to the datarate index. Can operate with repeater.

* The table is valid for the dwell time configuration of 1 for uplinks. The table provides

* repeater support.

*/

static const uint8_t MaxPayloadOfDatarateRepeaterDwell1AU915[] = { 0, 0, 11, 53, 125, 242, 242, 0, 33, 119, 129, 242, 242, 242, 242 };


/*!

* \brief The function gets a value of a specific phy attribute.

*

* \param [IN] getPhy Pointer to the function parameters.

*

* \retval Returns a structure containing the PHY parameter.

*/

PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy );


/*!

* \brief Updates the last TX done parameters of the current channel.

*

* \param [IN] txDone Pointer to the function parameters.

*/

void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone );


/*!

* \brief Initializes the channels masks and the channels.

*

* \param [IN] type Sets the initialization type.

*/

void RegionAU915InitDefaults( InitDefaultsParams_t* params );


/*!

* \brief Returns a pointer to the internal context and its size.

*

* \param [OUT] params Pointer to the function parameters.

*

* \retval Points to a structure where the module store its non-volatile context.

*/

void* RegionAU915GetNvmCtx( GetPhyParams_t* params );


/*!

* \brief Verifies a parameter.

*

* \param [IN] verify Pointer to the function parameters.

*

* \param [IN] type Sets the initialization type.

*

* \retval Returns true, if the parameter is valid.

*/

bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute );


/*!

* \brief The function parses the input buffer and sets up the channels of the

* CF list.

*

* \param [IN] applyCFList Pointer to the function parameters.

*/

void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList );


/*!

* \brief Sets a channels mask.

*

* \param [IN] chanMaskSet Pointer to the function parameters.

*

* \retval Returns true, if the channels mask could be set.

*/

bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet );


/*!

* Computes the Rx window timeout and offset.

*

* \param [IN] datarate Rx window datarate index to be used

*

* \param [IN] minRxSymbols Minimum required number of symbols to detect an Rx frame.

*

* \param [IN] rxError System maximum timing error of the receiver. In milliseconds

* The receiver will turn on in a [-rxError : +rxError] ms

* interval around RxOffset

*

* \param [OUT]rxConfigParams Returns updated WindowTimeout and WindowOffset fields.

*/

void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams );


/*!

* \brief Configuration of the RX windows.

*

* \param [IN] rxConfig Pointer to the function parameters.

*

* \param [OUT] datarate The datarate index which was set.

*

* \retval Returns true, if the configuration was applied successfully.

*/

bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate );


/*!

* \brief TX configuration.

*

* \param [IN] txConfig Pointer to the function parameters.

*

* \param [OUT] txPower The tx power index which was set.

*

* \param [OUT] txTimeOnAir The time-on-air of the frame.

*

* \retval Returns true, if the configuration was applied successfully.

*/

bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir );


/*!

* \brief The function processes a Link ADR Request.

*

* \param [IN] linkAdrReq Pointer to the function parameters.

*

* \retval Returns the status of the operation, according to the LoRaMAC specification.

*/

uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed );


/*!

* \brief The function processes a RX Parameter Setup Request.

*

* \param [IN] rxParamSetupReq Pointer to the function parameters.

*

* \retval Returns the status of the operation, according to the LoRaMAC specification.

*/

uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq );


/*!

* \brief The function processes a Channel Request.

*

* \param [IN] newChannelReq Pointer to the function parameters.

*

* \retval Returns the status of the operation, according to the LoRaMAC specification.

*/

uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq );


/*!

* \brief The function processes a TX ParamSetup Request.

*

* \param [IN] txParamSetupReq Pointer to the function parameters.

*

* \retval Returns the status of the operation, according to the LoRaMAC specification.

* Returns -1, if the functionality is not implemented. In this case, the end node

* shall not process the command.

*/

int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq );


/*!

* \brief The function processes a DlChannel Request.

*

* \param [IN] dlChannelReq Pointer to the function parameters.

*

* \retval Returns the status of the operation, according to the LoRaMAC specification.

*/

uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq );


/*!

* \brief Alternates the datarate of the channel for the join request.

*

* \param [IN] currentDr Current datarate.

*

* \retval Datarate to apply.

*/

int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type );


/*!

* \brief Calculates the back-off time.

*

* \param [IN] calcBackOff Pointer to the function parameters.

*/


//void RegionAU915CalcBackOff( CalcBackOffParams_t* calcBackOff );


/*!

* \brief Searches and set the next random available channel

*

* \param [OUT] channel Next channel to use for TX.

*

* \param [OUT] time Time to wait for the next transmission according to the duty

* cycle.

*

* \param [OUT] aggregatedTimeOff Updates the aggregated time off.

*

* \retval Function status [1: OK, 0: Unable to find a channel on the current datarate]

*/

LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff );


/*!

* \brief Adds a channel.

*

* \param [IN] channelAdd Pointer to the function parameters.

*

* \retval Status of the operation.

*/

LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd );


/*!

* \brief Removes a channel.

*

* \param [IN] channelRemove Pointer to the function parameters.

*

* \retval Returns true, if the channel was removed successfully.

*/

bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove );


/*!

* \brief Sets the radio into continuous wave mode.

*

* \param [IN] continuousWave Pointer to the function parameters.

*/

//////void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave );


/*!

* \brief Computes new datarate according to the given offset

*

* \param [IN] downlinkDwellTime Downlink dwell time configuration. 0: No limit, 1: 400ms

*

* \param [IN] dr Current datarate

*

* \param [IN] drOffset Offset to be applied

*

* \retval newDr Computed datarate.

*/

uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset );


/*!

* \brief Sets the radio into beacon reception mode

*

* \param [IN] rxBeaconSetup Pointer to the function parameters

*/

void RegionAU915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr );


/*! \} defgroup REGIONAU915 */


#endif // __REGION_AU915_H__




/*!

* \file RegionAU915.c

*

* \brief Region implementation for AU915

*

* \copyright Revised BSD License, see section \ref LICENSE.

*

* \code

* ______ _

* / _____) _ | |

* ( (____ _____ ____ _| |_ _____ ____| |__

* \____ \| ___ | (_ _) ___ |/ ___) _ \

* _____) ) ____| | | || |_| ____( (___| | | |

* (______/|_____)_|_|_| \__)_____)\____)_| |_|

* (C)2013-2017 Semtech

*

* ___ _____ _ ___ _ _____ ___ ___ ___ ___

* / __|_ _/_\ / __| |/ / __/ _ \| _ \/ __| __|

* \__ \ | |/ _ \ (__| ' <| _| (_) | / (__| _|

* |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|

* embedded.connectivity.solutions===============

*

* \endcode

*

* \author Miguel Luis ( Semtech )

*

* \author Gregory Cristian ( Semtech )

*

* \author Daniel Jaeckle ( STACKFORCE )

*/

/**

******************************************************************************

*

* Portions COPYRIGHT 2020 STMicroelectronics

*

* @file RegionAU915.c

* @author MCD Application Team

* @brief Region implementation for AU915

******************************************************************************

*/

#include "radio.h"

#include "RegionAU915.h"

#include "RegionBaseUS.h"


// Definitions

#define CHANNELS_MASK_SIZE 6


// A mask to select only valid 500KHz channels

#define CHANNELS_MASK_500KHZ_MASK 0x00FF


/* The HYBRID_DEFAULT_MASKx define the enabled channels in Hybrid mode*/

/* Note: they can be redefined in lorawan_conf.h*/

#ifndef HYBRID_DEFAULT_MASK0 /*enabled channels from channel 15 down to channel 0*/

#define HYBRID_DEFAULT_MASK0 0x00FF /*channel 7 down to channel 0 enabled*/

#endif

#ifndef HYBRID_DEFAULT_MASK1 /*enabled channels from channel 31 down to channel 16*/

#define HYBRID_DEFAULT_MASK1 0x0000

#endif

#ifndef HYBRID_DEFAULT_MASK2 /*enabled channels from channel 47 down to channel 32*/

#define HYBRID_DEFAULT_MASK2 0x0000

#endif

#ifndef HYBRID_DEFAULT_MASK3 /*enabled channels from channel 63 down to channel 48*/

#define HYBRID_DEFAULT_MASK3 0x0000

#endif

#ifndef HYBRID_DEFAULT_MASK4 /*enabled channels from channel 71 down to channel 64*/

#define HYBRID_DEFAULT_MASK4 0x0000

#endif


#if defined( REGION_AU915 )

/*

* Non-volatile module context.

*/

static RegionNvmDataGroup1_t* RegionNvmGroup1;

static RegionNvmDataGroup2_t* RegionNvmGroup2;

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

static Band_t* RegionBands;

#endif /* REGION_VERSION */


static bool VerifyRfFreq( uint32_t freq )

{

// Check radio driver support

if( Radio.CheckRfFrequency( freq ) == false )

{

return false;

}


// Rx frequencies

if( ( freq < AU915_FIRST_RX1_CHANNEL ) ||

( freq > AU915_LAST_RX1_CHANNEL ) ||

( ( ( freq - ( uint32_t ) AU915_FIRST_RX1_CHANNEL ) % ( uint32_t ) AU915_STEPWIDTH_RX1_CHANNEL ) != 0 ) )

{

return false;

}


// Tx frequencies for 125kHz

// Also includes the range for 500kHz channels

if( ( freq < 915200000 ) || ( freq > 927800000 ) )

{

return false;

}

return true;

}


static TimerTime_t GetTimeOnAir( int8_t datarate, uint16_t pktLen )

{

int8_t phyDr = DataratesAU915[datarate];

uint32_t bandwidth = RegionCommonGetBandwidth( datarate, BandwidthsAU915 );


return Radio.TimeOnAir( MODEM_LORA, bandwidth, phyDr, 1, 8, false, pktLen, true );

}

#endif /* REGION_AU915 */


PhyParam_t RegionAU915GetPhyParam( GetPhyParams_t* getPhy )

{

PhyParam_t phyParam = { 0 };


#if defined( REGION_AU915 )

switch( getPhy->Attribute )

{

case PHY_MIN_RX_DR:

{

if( getPhy->DownlinkDwellTime == 0)

{

phyParam.Value = AU915_RX_MIN_DATARATE;

}

else

{

phyParam.Value = AU915_DWELL_LIMIT_DATARATE;

}

break;

}

case PHY_MIN_TX_DR:

{

if( getPhy->UplinkDwellTime == 0)

{

phyParam.Value = AU915_TX_MIN_DATARATE;

}

else

{

phyParam.Value = AU915_DWELL_LIMIT_DATARATE;

}

break;

}

case PHY_DEF_TX_DR:

{

phyParam.Value = AU915_DEFAULT_DATARATE;

break;

}

case PHY_NEXT_LOWER_TX_DR:

{

RegionCommonGetNextLowerTxDrParams_t nextLowerTxDrParams =

{

.CurrentDr = getPhy->Datarate,

.MaxDr = ( int8_t )AU915_TX_MAX_DATARATE,

.MinDr = ( int8_t )( ( getPhy->UplinkDwellTime == 0 ) ? AU915_TX_MIN_DATARATE : AU915_DWELL_LIMIT_DATARATE ),

.NbChannels = AU915_MAX_NB_CHANNELS,

.ChannelsMask = RegionNvmGroup2->ChannelsMask,

.Channels = RegionNvmGroup2->Channels,

};

phyParam.Value = RegionCommonGetNextLowerTxDr( &nextLowerTxDrParams );

break;

}

case PHY_MAX_TX_POWER:

{

phyParam.Value = AU915_MAX_TX_POWER;

break;

}

case PHY_DEF_TX_POWER:

{

phyParam.Value = AU915_DEFAULT_TX_POWER;

break;

}

case PHY_DEF_ADR_ACK_LIMIT:

{

phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_LIMIT;

break;

}

case PHY_DEF_ADR_ACK_DELAY:

{

phyParam.Value = REGION_COMMON_DEFAULT_ADR_ACK_DELAY;

break;

}

case PHY_MAX_PAYLOAD:

{

if( getPhy->UplinkDwellTime == 0 )

{

phyParam.Value = MaxPayloadOfDatarateDwell0AU915[getPhy->Datarate];

}

else

{

phyParam.Value = MaxPayloadOfDatarateDwell1AU915[getPhy->Datarate];

}

break;

}

/* ST_WORKAROUND_BEGIN: Keep repeater feature */

case PHY_MAX_PAYLOAD_REPEATER:

{

if( getPhy->UplinkDwellTime == 0)

{

phyParam.Value = MaxPayloadOfDatarateRepeaterDwell0AU915[getPhy->Datarate];

}

else

{

phyParam.Value = MaxPayloadOfDatarateRepeaterDwell1AU915[getPhy->Datarate];

}

break;

}

/* ST_WORKAROUND_END */

case PHY_DUTY_CYCLE:

{

phyParam.Value = AU915_DUTY_CYCLE_ENABLED;

break;

}

case PHY_MAX_RX_WINDOW:

{

phyParam.Value = AU915_MAX_RX_WINDOW;

break;

}

case PHY_RECEIVE_DELAY1:

{

phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY1;

break;

}

case PHY_RECEIVE_DELAY2:

{

phyParam.Value = REGION_COMMON_DEFAULT_RECEIVE_DELAY2;

break;

}

case PHY_JOIN_ACCEPT_DELAY1:

{

phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY1;

break;

}

case PHY_JOIN_ACCEPT_DELAY2:

{

phyParam.Value = REGION_COMMON_DEFAULT_JOIN_ACCEPT_DELAY2;

break;

}

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x01010003 ))

case PHY_MAX_FCNT_GAP:

{

phyParam.Value = REGION_COMMON_DEFAULT_MAX_FCNT_GAP;

break;

}

case PHY_ACK_TIMEOUT:

{

phyParam.Value = ( REGION_COMMON_DEFAULT_ACK_TIMEOUT + randr( -REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND, REGION_COMMON_DEFAULT_ACK_TIMEOUT_RND ) );

break;

}

#elif (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

case PHY_RETRANSMIT_TIMEOUT:

{

phyParam.Value = ( REGION_COMMON_DEFAULT_RETRANSMIT_TIMEOUT + randr( -REGION_COMMON_DEFAULT_RETRANSMIT_TIMEOUT_RND, REGION_COMMON_DEFAULT_RETRANSMIT_TIMEOUT_RND ) );

break;

}

#endif /* REGION_VERSION */

case PHY_DEF_DR1_OFFSET:

{

phyParam.Value = REGION_COMMON_DEFAULT_RX1_DR_OFFSET;

break;

}

case PHY_DEF_RX2_FREQUENCY:

{

phyParam.Value = AU915_RX_WND_2_FREQ;

break;

}

case PHY_DEF_RX2_DR:

{

phyParam.Value = AU915_RX_WND_2_DR;

break;

}

case PHY_CHANNELS_MASK:

{

phyParam.ChannelsMask = RegionNvmGroup2->ChannelsMask;

break;

}

case PHY_CHANNELS_DEFAULT_MASK:

{

phyParam.ChannelsMask = RegionNvmGroup2->ChannelsDefaultMask;

break;

}

case PHY_MAX_NB_CHANNELS:

{

phyParam.Value = AU915_MAX_NB_CHANNELS;

break;

}

case PHY_CHANNELS:

{

phyParam.Channels = RegionNvmGroup2->Channels;

break;

}

case PHY_DEF_UPLINK_DWELL_TIME:

{

phyParam.Value = AU915_DEFAULT_UPLINK_DWELL_TIME;

break;

}

case PHY_DEF_DOWNLINK_DWELL_TIME:

{

phyParam.Value = REGION_COMMON_DEFAULT_DOWNLINK_DWELL_TIME;

break;

}

case PHY_DEF_MAX_EIRP:

{

phyParam.fValue = AU915_DEFAULT_MAX_EIRP;

break;

}

case PHY_DEF_ANTENNA_GAIN:

{

phyParam.fValue = AU915_DEFAULT_ANTENNA_GAIN;

break;

}

case PHY_BEACON_CHANNEL_FREQ:

{

phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel,

AU915_BEACON_CHANNEL_FREQ,

AU915_BEACON_CHANNEL_STEPWIDTH );

break;

}

case PHY_BEACON_FORMAT:

{

phyParam.BeaconFormat.BeaconSize = AU915_BEACON_SIZE;

phyParam.BeaconFormat.Rfu1Size = AU915_RFU1_SIZE;

phyParam.BeaconFormat.Rfu2Size = AU915_RFU2_SIZE;

break;

}

case PHY_BEACON_CHANNEL_DR:

{

phyParam.Value = AU915_BEACON_CHANNEL_DR;

break;

}

case PHY_BEACON_NB_CHANNELS:

{

phyParam.Value = AU915_BEACON_NB_CHANNELS;

break;

}

case PHY_PING_SLOT_CHANNEL_FREQ:

{

phyParam.Value = RegionBaseUSCalcDownlinkFrequency( getPhy->Channel,

AU915_PING_SLOT_CHANNEL_FREQ,

AU915_BEACON_CHANNEL_STEPWIDTH );

break;

}

case PHY_PING_SLOT_CHANNEL_DR:

{

phyParam.Value = AU915_PING_SLOT_CHANNEL_DR;

break;

}

case PHY_PING_SLOT_NB_CHANNELS:

{

phyParam.Value = AU915_BEACON_NB_CHANNELS;

break;

}

case PHY_SF_FROM_DR:

{

phyParam.Value = DataratesAU915[getPhy->Datarate];

break;

}

case PHY_BW_FROM_DR:

{

phyParam.Value = RegionCommonGetBandwidth( getPhy->Datarate, BandwidthsAU915 );

break;

}

default:

{

break;

}

}


#endif /* REGION_AU915 */

return phyParam;

}


void RegionAU915SetBandTxDone( SetBandTxDoneParams_t* txDone )

{

#if defined( REGION_AU915 )

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x01010003 ))

RegionCommonSetBandTxDone( &RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txDone->Channel].Band],

txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );

#elif (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

RegionCommonSetBandTxDone( &RegionBands[RegionNvmGroup2->Channels[txDone->Channel].Band],

txDone->LastTxAirTime, txDone->Joined, txDone->ElapsedTimeSinceStartUp );

#endif /* REGION_VERSION */

#endif /* REGION_AU915 */

}


void RegionAU915InitDefaults( InitDefaultsParams_t* params )

{

#if defined( REGION_AU915 )

Band_t bands[AU915_MAX_NB_BANDS] =

{

AU915_BAND0

};


switch( params->Type )

{

case INIT_TYPE_DEFAULTS:

{

if( ( params->NvmGroup1 == NULL ) || ( params->NvmGroup2 == NULL ) )

{

return;

}


RegionNvmGroup1 = (RegionNvmDataGroup1_t*) params->NvmGroup1;

RegionNvmGroup2 = (RegionNvmDataGroup2_t*) params->NvmGroup2;

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

RegionBands = (Band_t*) params->Bands;

#endif /* REGION_VERSION */


// Initialize 8 bit channel groups index

RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0;


// Initialize the join trials counter

RegionNvmGroup1->JoinTrialsCounter = 0;


// Default bands

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x01010003 ))

memcpy1( ( uint8_t* )RegionNvmGroup1->Bands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS );

#elif (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

memcpy1( ( uint8_t* )RegionBands, ( uint8_t* )bands, sizeof( Band_t ) * AU915_MAX_NB_BANDS );

#endif /* REGION_VERSION */


// Channels

for( uint8_t i = 0; i < AU915_MAX_NB_CHANNELS - 8; i++ )

{

// 125 kHz channels

RegionNvmGroup2->Channels[i].Frequency = 915200000 + i * 200000;

RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_5 << 4 ) | DR_0;

RegionNvmGroup2->Channels[i].Band = 0;

}

for( uint8_t i = AU915_MAX_NB_CHANNELS - 8; i < AU915_MAX_NB_CHANNELS; i++ )

{

// 500 kHz channels

RegionNvmGroup2->Channels[i].Frequency = 915900000 + ( i - ( AU915_MAX_NB_CHANNELS - 8 ) ) * 1600000;

RegionNvmGroup2->Channels[i].DrRange.Value = ( DR_6 << 4 ) | DR_6;

RegionNvmGroup2->Channels[i].Band = 0;

}


// Initialize channels default mask

/* ST_WORKAROUND_BEGIN: Hybrid mode */

#if ( HYBRID_ENABLED == 1 )

RegionNvmGroup2->ChannelsDefaultMask[0] = HYBRID_DEFAULT_MASK0;

RegionNvmGroup2->ChannelsDefaultMask[1] = HYBRID_DEFAULT_MASK1;

RegionNvmGroup2->ChannelsDefaultMask[2] = HYBRID_DEFAULT_MASK2;

RegionNvmGroup2->ChannelsDefaultMask[3] = HYBRID_DEFAULT_MASK3;

RegionNvmGroup2->ChannelsDefaultMask[4] = HYBRID_DEFAULT_MASK4;

RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000;

#else

RegionNvmGroup2->ChannelsDefaultMask[0] = 0x00FF;

RegionNvmGroup2->ChannelsDefaultMask[1] = 0x0000;

RegionNvmGroup2->ChannelsDefaultMask[2] = 0x0000;

RegionNvmGroup2->ChannelsDefaultMask[3] = 0x0000;

RegionNvmGroup2->ChannelsDefaultMask[4] = 0x0000;

RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000;

#endif /* HYBRID_ENABLED == 1 */

/* ST_WORKAROUND_END */


// Copy channels default mask

RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE );


// Copy into channels mask remaining

RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, CHANNELS_MASK_SIZE );

break;

}

case INIT_TYPE_RESET_TO_DEFAULT_CHANNELS:

{

// Intentional fallthrough

}

case INIT_TYPE_ACTIVATE_DEFAULT_CHANNELS:

{

// Copy channels default mask

RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, RegionNvmGroup2->ChannelsDefaultMask, CHANNELS_MASK_SIZE );


for( uint8_t i = 0; i < CHANNELS_MASK_SIZE; i++ )

{ // Copy-And the channels mask

RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i];

}

break;

}

default:

{

break;

}

}

#endif /* REGION_AU915 */

}


bool RegionAU915Verify( VerifyParams_t* verify, PhyAttribute_t phyAttribute )

{

#if defined( REGION_AU915 )

switch( phyAttribute )

{

case PHY_FREQUENCY:

{

return VerifyRfFreq( verify->Frequency );

}

case PHY_TX_DR:

case PHY_DEF_TX_DR:

{

if( verify->DatarateParams.UplinkDwellTime == 0 )

{

return RegionCommonValueInRange( verify->DatarateParams.Datarate, AU915_TX_MIN_DATARATE, AU915_TX_MAX_DATARATE );

}

else

{

return RegionCommonValueInRange( verify->DatarateParams.Datarate, AU915_DWELL_LIMIT_DATARATE, AU915_TX_MAX_DATARATE );

}

}

case PHY_RX_DR:

{

if( verify->DatarateParams.UplinkDwellTime == 0 )

{

return RegionCommonValueInRange( verify->DatarateParams.Datarate, AU915_RX_MIN_DATARATE, AU915_RX_MAX_DATARATE );

}

else

{

return RegionCommonValueInRange( verify->DatarateParams.Datarate, AU915_DWELL_LIMIT_DATARATE, AU915_RX_MAX_DATARATE );

}

}

case PHY_DEF_TX_POWER:

case PHY_TX_POWER:

{

// Remark: switched min and max!

return RegionCommonValueInRange( verify->TxPower, AU915_MAX_TX_POWER, AU915_MIN_TX_POWER );

}

case PHY_DUTY_CYCLE:

{

return AU915_DUTY_CYCLE_ENABLED;

}

default:

return false;

}

#else

return false;

#endif /* REGION_AU915 */

}


void RegionAU915ApplyCFList( ApplyCFListParams_t* applyCFList )

{

#if defined( REGION_AU915 )

// Size of the optional CF list must be 16 byte

if( applyCFList->Size != 16 )

{

return;

}


// Last byte CFListType must be 0x01 to indicate the CFList contains a series of ChMask fields

if( applyCFList->Payload[15] != 0x01 )

{

return;

}


// ChMask0 - ChMask4 must be set (every ChMask has 16 bit)

for( uint8_t chMaskItr = 0, cntPayload = 0; chMaskItr <= 4; chMaskItr++, cntPayload+=2 )

{

RegionNvmGroup2->ChannelsMask[chMaskItr] = (uint16_t) (0x00FF & applyCFList->Payload[cntPayload]);

RegionNvmGroup2->ChannelsMask[chMaskItr] |= (uint16_t) (applyCFList->Payload[cntPayload+1] << 8);

if( chMaskItr == 4 )

{

RegionNvmGroup2->ChannelsMask[chMaskItr] = RegionNvmGroup2->ChannelsMask[chMaskItr] & CHANNELS_MASK_500KHZ_MASK;

}

// Set the channel mask to the remaining

RegionNvmGroup1->ChannelsMaskRemaining[chMaskItr] &= RegionNvmGroup2->ChannelsMask[chMaskItr];

}

#endif /* REGION_AU915 */

}


bool RegionAU915ChanMaskSet( ChanMaskSetParams_t* chanMaskSet )

{

#if defined( REGION_AU915 )

switch( chanMaskSet->ChannelsMaskType )

{

case CHANNELS_MASK:

{

RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE );


RegionNvmGroup2->ChannelsDefaultMask[4] = RegionNvmGroup2->ChannelsDefaultMask[4] & CHANNELS_MASK_500KHZ_MASK;

RegionNvmGroup2->ChannelsDefaultMask[5] = 0x0000;


for( uint8_t i = 0; i < 6; i++ )

{ // Copy-And the channels mask

RegionNvmGroup1->ChannelsMaskRemaining[i] &= RegionNvmGroup2->ChannelsMask[i];

}

break;

}

case CHANNELS_DEFAULT_MASK:

{

RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsDefaultMask, chanMaskSet->ChannelsMaskIn, CHANNELS_MASK_SIZE );

break;

}

default:

return false;

}

return true;

#else

return false;

#endif /* REGION_AU915 */

}


void RegionAU915ComputeRxWindowParameters( int8_t datarate, uint8_t minRxSymbols, uint32_t rxError, RxConfigParams_t *rxConfigParams )

{

#if defined( REGION_AU915 )

uint32_t tSymbolInUs = 0;


// Get the datarate, perform a boundary check

rxConfigParams->Datarate = MIN( datarate, AU915_RX_MAX_DATARATE );

rxConfigParams->Bandwidth = RegionCommonGetBandwidth( rxConfigParams->Datarate, BandwidthsAU915 );


tSymbolInUs = RegionCommonComputeSymbolTimeLoRa( DataratesAU915[rxConfigParams->Datarate], BandwidthsAU915[rxConfigParams->Datarate] );


RegionCommonComputeRxWindowParameters( tSymbolInUs, minRxSymbols, rxError, Radio.GetWakeupTime( ), &rxConfigParams->WindowTimeout, &rxConfigParams->WindowOffset );

#endif /* REGION_AU915 */

}


bool RegionAU915RxConfig( RxConfigParams_t* rxConfig, int8_t* datarate )

{

#if defined( REGION_AU915 )

int8_t dr = rxConfig->Datarate;

uint8_t maxPayload = 0;

int8_t phyDr = 0;

uint32_t frequency = rxConfig->Frequency;


if( Radio.GetStatus( ) != RF_IDLE )

{

return false;

}


if( rxConfig->RxSlot == RX_SLOT_WIN_1 )

{

// Apply window 1 frequency

frequency = AU915_FIRST_RX1_CHANNEL + ( rxConfig->Channel % 8 ) * AU915_STEPWIDTH_RX1_CHANNEL;

}


// Read the physical datarate from the datarates table

phyDr = DataratesAU915[dr];


Radio.SetChannel( frequency );


// Radio configuration

Radio.SetRxConfig( MODEM_LORA, rxConfig->Bandwidth, phyDr, 1, 0, 8, rxConfig->WindowTimeout, false, 0, false, 0, 0, true, rxConfig->RxContinuous );


/* ST_WORKAROUND_BEGIN: Keep repeater feature */

if( rxConfig->RepeaterSupport == true )

{

maxPayload = MaxPayloadOfDatarateRepeaterDwell0AU915[dr];

}

else

{

maxPayload = MaxPayloadOfDatarateDwell0AU915[dr];

}

Radio.SetMaxPayloadLength( MODEM_LORA, maxPayload + LORAMAC_FRAME_PAYLOAD_OVERHEAD_SIZE );

/* ST_WORKAROUND_END */


/* ST_WORKAROUND_BEGIN: Print Rx config */

RegionCommonRxConfigPrint(rxConfig->RxSlot, frequency, dr);

/* ST_WORKAROUND_END */


*datarate = (uint8_t) dr;

return true;

#else

return false;

#endif /* REGION_AU915 */

}


bool RegionAU915TxConfig( TxConfigParams_t* txConfig, int8_t* txPower, TimerTime_t* txTimeOnAir )

{

#if defined( REGION_AU915 )

int8_t phyDr = DataratesAU915[txConfig->Datarate];

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x01010003 ))

int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower );

#elif (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

int8_t txPowerLimited = RegionCommonLimitTxPower( txConfig->TxPower, RegionBands[RegionNvmGroup2->Channels[txConfig->Channel].Band].TxMaxPower );

#endif /* REGION_VERSION */

uint32_t bandwidth = RegionCommonGetBandwidth( txConfig->Datarate, BandwidthsAU915 );

int8_t phyTxPower = 0;


// Calculate physical TX power

phyTxPower = RegionCommonComputeTxPower( txPowerLimited, txConfig->MaxEirp, txConfig->AntennaGain );


// Setup the radio frequency

Radio.SetChannel( RegionNvmGroup2->Channels[txConfig->Channel].Frequency );


Radio.SetTxConfig( MODEM_LORA, phyTxPower, 0, bandwidth, phyDr, 1, 8, false, true, 0, 0, false, 4000 );

/* ST_WORKAROUND_BEGIN: Print Tx config */

RegionCommonTxConfigPrint(RegionNvmGroup2->Channels[txConfig->Channel].Frequency, txConfig->Datarate);

/* ST_WORKAROUND_END */


// Setup maximum payload length of the radio driver

Radio.SetMaxPayloadLength( MODEM_LORA, txConfig->PktLen );


// Update time-on-air

*txTimeOnAir = GetTimeOnAir( txConfig->Datarate, txConfig->PktLen );


*txPower = txPowerLimited;

return true;

#else

return false;

#endif /* REGION_AU915 */

}


uint8_t RegionAU915LinkAdrReq( LinkAdrReqParams_t* linkAdrReq, int8_t* drOut, int8_t* txPowOut, uint8_t* nbRepOut, uint8_t* nbBytesParsed )

{

uint8_t status = 0x07;

#if defined( REGION_AU915 )

RegionCommonLinkAdrParams_t linkAdrParams = { 0 };

uint8_t nextIndex = 0;

uint8_t bytesProcessed = 0;

uint16_t channelsMask[6] = { 0, 0, 0, 0, 0, 0 };

GetPhyParams_t getPhy;

PhyParam_t phyParam;

RegionCommonLinkAdrReqVerifyParams_t linkAdrVerifyParams;


// Initialize local copy of channels mask

RegionCommonChanMaskCopy( channelsMask, RegionNvmGroup2->ChannelsMask, 6 );


while( bytesProcessed < linkAdrReq->PayloadSize )

{

nextIndex = RegionCommonParseLinkAdrReq( &( linkAdrReq->Payload[bytesProcessed] ), &linkAdrParams );


if( nextIndex == 0 )

break; // break loop, since no more request has been found


// Update bytes processed

bytesProcessed += nextIndex;


// Revert status, as we only check the last ADR request for the channel mask KO

status = 0x07;


if( linkAdrParams.ChMaskCtrl == 6 )

{

// Enable all 125 kHz channels

channelsMask[0] = 0xFFFF;

channelsMask[1] = 0xFFFF;

channelsMask[2] = 0xFFFF;

channelsMask[3] = 0xFFFF;

// Apply chMask to channels 64 to 71

channelsMask[4] = linkAdrParams.ChMask & CHANNELS_MASK_500KHZ_MASK;

}

else if( linkAdrParams.ChMaskCtrl == 7 )

{

// Disable all 125 kHz channels

channelsMask[0] = 0x0000;

channelsMask[1] = 0x0000;

channelsMask[2] = 0x0000;

channelsMask[3] = 0x0000;

// Apply chMask to channels 64 to 71

channelsMask[4] = linkAdrParams.ChMask & CHANNELS_MASK_500KHZ_MASK;

}

else if( linkAdrParams.ChMaskCtrl == 5 )

{

// Start value for comparison

uint8_t bitMask = 1;


// cntChannelMask for channelsMask[0] until channelsMask[3]

uint8_t cntChannelMask = 0;


// i will be 1, 2, 3, ..., 7

for( uint8_t i = 0; i <= 7; i++ )

{

// 8 MSBs of ChMask are RFU

// Checking if the ChMask is set, then true

if( ( ( linkAdrParams.ChMask & 0x00FF ) & ( bitMask << i ) ) != 0 )

{

if( ( i % 2 ) == 0 )

{

// Enable a bank of 8 125kHz channels, 8 LSBs

channelsMask[cntChannelMask] |= 0x00FF;

// Enable the corresponding 500kHz channel

channelsMask[4] |= ( bitMask << i );

}

else

{

// Enable a bank of 8 125kHz channels, 8 MSBs

channelsMask[cntChannelMask] |= 0xFF00;

// Enable the corresponding 500kHz channel

channelsMask[4] |= ( bitMask << i );

// cntChannelMask increment for uneven i

cntChannelMask++;

}

}

// ChMask is not set

else

{

if( ( i % 2 ) == 0 )

{

// Disable a bank of 8 125kHz channels, 8 LSBs

channelsMask[cntChannelMask] &= 0xFF00;

// Disable the corresponding 500kHz channel

channelsMask[4] &= ~( bitMask << i );

}

else

{

// Enable a bank of 8 125kHz channels, 8 MSBs

channelsMask[cntChannelMask] &= 0x00FF;

// Disable the corresponding 500kHz channel

channelsMask[4] &= ~( bitMask << i );

// cntChannelMask increment for uneven i

cntChannelMask++;

}

}

}

}

else

{

channelsMask[linkAdrParams.ChMaskCtrl] = linkAdrParams.ChMask;

}

}


// FCC 15.247 paragraph F mandates to hop on at least 2 125 kHz channels

if( ( linkAdrParams.Datarate < DR_6 ) && ( RegionCommonCountChannels( channelsMask, 0, 4 ) < 2 ) )

{

status &= 0xFE; // Channel mask KO

}


// Get the minimum possible datarate

getPhy.Attribute = PHY_MIN_TX_DR;

getPhy.UplinkDwellTime = linkAdrReq->UplinkDwellTime;

phyParam = RegionAU915GetPhyParam( &getPhy );


linkAdrVerifyParams.Status = status;

linkAdrVerifyParams.AdrEnabled = linkAdrReq->AdrEnabled;

linkAdrVerifyParams.Datarate = linkAdrParams.Datarate;

linkAdrVerifyParams.TxPower = linkAdrParams.TxPower;

linkAdrVerifyParams.NbRep = linkAdrParams.NbRep;

linkAdrVerifyParams.CurrentDatarate = linkAdrReq->CurrentDatarate;

linkAdrVerifyParams.CurrentTxPower = linkAdrReq->CurrentTxPower;

linkAdrVerifyParams.CurrentNbRep = linkAdrReq->CurrentNbRep;

linkAdrVerifyParams.NbChannels = AU915_MAX_NB_CHANNELS;

linkAdrVerifyParams.ChannelsMask = channelsMask;

linkAdrVerifyParams.MinDatarate = ( int8_t )phyParam.Value;

linkAdrVerifyParams.MaxDatarate = AU915_TX_MAX_DATARATE;

linkAdrVerifyParams.Channels = RegionNvmGroup2->Channels;

linkAdrVerifyParams.MinTxPower = AU915_MIN_TX_POWER;

linkAdrVerifyParams.MaxTxPower = AU915_MAX_TX_POWER;

linkAdrVerifyParams.Version = linkAdrReq->Version;


// Verify the parameters and update, if necessary

status = RegionCommonLinkAdrReqVerifyParams( &linkAdrVerifyParams, &linkAdrParams.Datarate, &linkAdrParams.TxPower, &linkAdrParams.NbRep );


// Update channelsMask if everything is correct

if( status == 0x07 )

{

// Copy Mask

RegionCommonChanMaskCopy( RegionNvmGroup2->ChannelsMask, channelsMask, 6 );


RegionNvmGroup1->ChannelsMaskRemaining[0] &= RegionNvmGroup2->ChannelsMask[0];

RegionNvmGroup1->ChannelsMaskRemaining[1] &= RegionNvmGroup2->ChannelsMask[1];

RegionNvmGroup1->ChannelsMaskRemaining[2] &= RegionNvmGroup2->ChannelsMask[2];

RegionNvmGroup1->ChannelsMaskRemaining[3] &= RegionNvmGroup2->ChannelsMask[3];

RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4];

RegionNvmGroup1->ChannelsMaskRemaining[5] = RegionNvmGroup2->ChannelsMask[5];

}


// Update status variables

*drOut = linkAdrParams.Datarate;

*txPowOut = linkAdrParams.TxPower;

*nbRepOut = linkAdrParams.NbRep;

*nbBytesParsed = bytesProcessed;


#endif /* REGION_AU915 */

return status;

}


uint8_t RegionAU915RxParamSetupReq( RxParamSetupReqParams_t* rxParamSetupReq )

{

uint8_t status = 0x07;

#if defined( REGION_AU915 )


// Verify radio frequency

if( VerifyRfFreq( rxParamSetupReq->Frequency ) == false )

{

status &= 0xFE; // Channel frequency KO

}


// Verify datarate

if( RegionCommonValueInRange( rxParamSetupReq->Datarate, AU915_RX_MIN_DATARATE, AU915_RX_MAX_DATARATE ) == false )

{

status &= 0xFD; // Datarate KO

}

if( ( rxParamSetupReq->Datarate == DR_7 ) ||

( rxParamSetupReq->Datarate > DR_13 ) )

{

status &= 0xFD; // Datarate KO

}


// Verify datarate offset

if( RegionCommonValueInRange( rxParamSetupReq->DrOffset, AU915_MIN_RX1_DR_OFFSET, AU915_MAX_RX1_DR_OFFSET ) == false )

{

status &= 0xFB; // Rx1DrOffset range KO

}


#endif /* REGION_AU915 */

return status;

}



uint8_t RegionAU915NewChannelReq( NewChannelReqParams_t* newChannelReq )

{

// Do not accept the request

return -1;

}


int8_t RegionAU915TxParamSetupReq( TxParamSetupReqParams_t* txParamSetupReq )

{

// Accept the request

return 0;

}


uint8_t RegionAU915DlChannelReq( DlChannelReqParams_t* dlChannelReq )

{

// Do not accept the request

return -1;

}


int8_t RegionAU915AlternateDr( int8_t currentDr, AlternateDrType_t type )

{

#if defined( REGION_AU915 )

// Alternates the data rate according to the channel sequence:

// Eight times a 125kHz DR_2 and then one 500kHz DR_6 channel

if( type == ALTERNATE_DR )

{

RegionNvmGroup1->JoinTrialsCounter++;

}

else

{

RegionNvmGroup1->JoinTrialsCounter--;

}


if( RegionNvmGroup1->JoinTrialsCounter % 9 == 0 )

{

// Use DR_6 every 9th times.

currentDr = DR_6;

}

else

{

currentDr = DR_2;

}

return currentDr;

#else

return -1;

#endif /* REGION_AU915 */

}


LoRaMacStatus_t RegionAU915NextChannel( NextChanParams_t* nextChanParams, uint8_t* channel, TimerTime_t* time, TimerTime_t* aggregatedTimeOff )

{

#if defined( REGION_AU915 )

uint8_t nbEnabledChannels = 0;

uint8_t nbRestrictedChannels = 0;

uint8_t enabledChannels[AU915_MAX_NB_CHANNELS] = { 0 };

RegionCommonIdentifyChannelsParam_t identifyChannelsParam;

RegionCommonCountNbOfEnabledChannelsParams_t countChannelsParams;

LoRaMacStatus_t status = LORAMAC_STATUS_NO_CHANNEL_FOUND;


// Count 125kHz channels

if( RegionCommonCountChannels( RegionNvmGroup1->ChannelsMaskRemaining, 0, 4 ) == 0 )

{ // Reactivate default channels

RegionCommonChanMaskCopy( RegionNvmGroup1->ChannelsMaskRemaining, RegionNvmGroup2->ChannelsMask, 4 );


RegionNvmGroup1->JoinChannelGroupsCurrentIndex = 0;

}

// Check other channels

if( nextChanParams->Datarate >= DR_6 )

{

if( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) == 0 )

{

RegionNvmGroup1->ChannelsMaskRemaining[4] = RegionNvmGroup2->ChannelsMask[4];

}

}


// Search how many channels are enabled

countChannelsParams.Joined = nextChanParams->Joined;

countChannelsParams.Datarate = nextChanParams->Datarate;

countChannelsParams.ChannelsMask = RegionNvmGroup1->ChannelsMaskRemaining;

countChannelsParams.Channels = RegionNvmGroup2->Channels;

#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x01010003 ))

countChannelsParams.Bands = RegionNvmGroup1->Bands;

#elif (defined( REGION_VERSION ) && ( REGION_VERSION == 0x02010001 ))

countChannelsParams.Bands = RegionBands;

#endif /* REGION_VERSION */

countChannelsParams.MaxNbChannels = AU915_MAX_NB_CHANNELS;

countChannelsParams.JoinChannels = NULL;


identifyChannelsParam.AggrTimeOff = nextChanParams->AggrTimeOff;

identifyChannelsParam.LastAggrTx = nextChanParams->LastAggrTx;

identifyChannelsParam.DutyCycleEnabled = nextChanParams->DutyCycleEnabled;

identifyChannelsParam.MaxBands = AU915_MAX_NB_BANDS;


identifyChannelsParam.ElapsedTimeSinceStartUp = nextChanParams->ElapsedTimeSinceStartUp;

identifyChannelsParam.LastTxIsJoinRequest = nextChanParams->LastTxIsJoinRequest;

identifyChannelsParam.ExpectedTimeOnAir = GetTimeOnAir( nextChanParams->Datarate, nextChanParams->PktLen );


identifyChannelsParam.CountNbOfEnabledChannelsParam = &countChannelsParams;


status = RegionCommonIdentifyChannels( &identifyChannelsParam, aggregatedTimeOff, enabledChannels,

&nbEnabledChannels, &nbRestrictedChannels, time );


if( status == LORAMAC_STATUS_OK )

{

if( nextChanParams->Joined == true )

{

// Choose randomly on of the remaining channels

*channel = enabledChannels[randr( 0, nbEnabledChannels - 1 )];

}

else

{

// For rapid network acquisition in mixed gateway channel plan environments, the device

// follow a random channel selection sequence. It probes alternating one out of a

// group of eight 125 kHz channels followed by probing one 500 kHz channel each pass.

// Each time a 125 kHz channel will be selected from another group.


// 125kHz Channels (0 - 63) DR2

if( nextChanParams->Datarate == DR_2 )

{

if( RegionBaseUSComputeNext125kHzJoinChannel( ( uint16_t* ) RegionNvmGroup1->ChannelsMaskRemaining,

&RegionNvmGroup1->JoinChannelGroupsCurrentIndex, channel ) == LORAMAC_STATUS_PARAMETER_INVALID )

{

return LORAMAC_STATUS_PARAMETER_INVALID;

}

}

// 500kHz Channels (64 - 71) DR6

else

{

// Choose the next available channel

uint8_t i = 0;

while( ( ( RegionNvmGroup1->ChannelsMaskRemaining[4] & CHANNELS_MASK_500KHZ_MASK ) & ( 1 << i ) ) == 0 )

{

i++;

}

*channel = 64 + i;

}

}


// Disable the channel in the mask

RegionCommonChanDisable( RegionNvmGroup1->ChannelsMaskRemaining, *channel, AU915_MAX_NB_CHANNELS );

}

return status;

#else

return LORAMAC_STATUS_NO_CHANNEL_FOUND;

#endif /* REGION_AU915 */

}


LoRaMacStatus_t RegionAU915ChannelAdd( ChannelAddParams_t* channelAdd )

{

return LORAMAC_STATUS_PARAMETER_INVALID;

}


bool RegionAU915ChannelsRemove( ChannelRemoveParams_t* channelRemove )

{

return LORAMAC_STATUS_PARAMETER_INVALID;

}


#if (defined( REGION_VERSION ) && ( REGION_VERSION == 0x01010003 ))

void RegionAU915SetContinuousWave( ContinuousWaveParams_t* continuousWave )

{

#if defined( REGION_AU915 )

int8_t txPowerLimited = RegionCommonLimitTxPower( continuousWave->TxPower, RegionNvmGroup1->Bands[RegionNvmGroup2->Channels[continuousWave->Channel].Band].TxMaxPower );

int8_t phyTxPower = 0;

uint32_t frequency = RegionNvmGroup2->Channels[continuousWave->Channel].Frequency;


// Calculate physical TX power

phyTxPower = RegionCommonComputeTxPower( txPowerLimited, continuousWave->MaxEirp, continuousWave->AntennaGain );


Radio.SetTxContinuousWave( frequency, phyTxPower, continuousWave->Timeout );

#endif /* REGION_AU915 */

}

#endif /* REGION_VERSION */


uint8_t RegionAU915ApplyDrOffset( uint8_t downlinkDwellTime, int8_t dr, int8_t drOffset )

{

#if defined( REGION_AU915 )

int8_t datarate = DatarateOffsetsAU915[dr][drOffset];


if( datarate < 0 )

{

if( downlinkDwellTime == 0 )

{

datarate = AU915_TX_MIN_DATARATE;

}

else

{

datarate = AU915_DWELL_LIMIT_DATARATE;

}

}

return datarate;

#else

return 0;

#endif /* REGION_AU915 */

}


void RegionAU915RxBeaconSetup( RxBeaconSetup_t* rxBeaconSetup, uint8_t* outDr )

{

#if defined( REGION_AU915 )

RegionCommonRxBeaconSetupParams_t regionCommonRxBeaconSetup;


regionCommonRxBeaconSetup.Datarates = DataratesAU915;

regionCommonRxBeaconSetup.Frequency = rxBeaconSetup->Frequency;

regionCommonRxBeaconSetup.BeaconSize = AU915_BEACON_SIZE;

regionCommonRxBeaconSetup.BeaconDatarate = AU915_BEACON_CHANNEL_DR;

regionCommonRxBeaconSetup.BeaconChannelBW = AU915_BEACON_CHANNEL_BW;

regionCommonRxBeaconSetup.RxTime = rxBeaconSetup->RxTime;

regionCommonRxBeaconSetup.SymbolTimeout = rxBeaconSetup->SymbolTimeout;


RegionCommonRxBeaconSetup( &regionCommonRxBeaconSetup );


// Store downlink datarate

*outDr = AU915_BEACON_CHANNEL_DR;

#endif /* REGION_AU915 */

}


Entre em contato para testes.

A VERSÃO DO LORAMAC  É 1.0.4

Também alterado

// LoRaWAN/App/lora_app.h
/* LoraWAN application configuration (Mw is configured by lorawan_conf.h) */
/* Available: LORAMAC_REGION_AS923, LORAMAC_REGION_AU915, LORAMAC_REGION_EU868, LORAMAC_REGION_KR920, LORAMAC_REGION_IN865, LORAMAC_REGION_US915, LORAMAC_REGION_RU864 */
#define ACTIVE_REGION LORAMAC_REGION_AU915 //<=====================
#define LORAWAN_DEFAULT_CONFIRMED_MSG_STATE         LORAMAC_HANDLER_CONFIRMED_MSG

Também

stm32wlxx_nucleo_radio.h

#define RF_SW_CTRL1_PIN GPIO_PIN_12 #define RF_SW_CTRL1_GPIO_PORT GPIOB #define RF_SW_CTRL1_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE() #define RF_SW_RX_GPIO_CLK_DISABLE() __HAL_RCC_GPIOB_CLK_DISABLE() #define RF_SW_CTRL2_PIN GPIO_PIN_13 #define RF_SW_CTRL2_GPIO_PORT GPIOC #define RF_SW_CTRL2_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE() #define RF_SW_CTRL2_GPIO_CLK_DISABLE() __HAL_RCC_GPIOC_CLK_DISABLE()

stm32wlxx_nucleo_radio.c

/** * @brief Configure Radio Switch. * @param Config: Specifies the Radio RF switch path to be set. * This parameter can be one of following parameters: * @arg RADIO_SWITCH_OFF * @arg RADIO_SWITCH_RX * @arg RADIO_SWITCH_RFO_LP * @arg RADIO_SWITCH_RFO_HP * @retval BSP status */ int32_t BSP_RADIO_ConfigRFSwitch(BSP_RADIO_Switch_TypeDef Config) { switch (Config) { case RADIO_SWITCH_OFF: { /* Turn off switch */ HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET); break; } case RADIO_SWITCH_RX: { /*Turns On in Rx Mode the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET); break; } case RADIO_SWITCH_RFO_LP: { /*Turns On in Tx Low Power the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET); break; } case RADIO_SWITCH_RFO_HP: { /*Turns On in Tx High Power the RF Switch */ HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET); HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET); break; } default: break; } return BSP_ERROR_NONE; }







































stm32wlxx_nucleo_radio.c

#define LSM_RF_CHANNEL_SWITCH 1

/**

******************************************************************************

* @file stm32wlxx_nucleo_radio.c

* @author MCD Application Team

* @brief This file provides set of firmware functions to manage:

* - RF circuitry available on STM32WLXX-Nucleo

* Kit from STMicroelectronics

******************************************************************************

* @attention

*

* Copyright (c) 2020-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.

*

******************************************************************************

*/


/* Includes ------------------------------------------------------------------*/

#include "stm32wlxx_nucleo_radio.h"


/** @addtogroup BSP

* @{

*/


/** @addtogroup STM32WLXX_NUCLEO

* @{

*/


/** @addtogroup STM32WLXX_NUCLEO_RADIO_LOW_LEVEL

* @brief This file provides set of firmware functions to Radio switch

* available on STM32WLXX-Nucleo Kit from STMicroelectronics.

* @{

*/


/** @addtogroup STM32WLXX_NUCLEO_RADIO_LOW_LEVEL_Exported_Functions

* @{

*/

/**

* @brief Init Radio Switch

* @retval BSP status

*/

int32_t BSP_RADIO_Init(void)

{


/* USER CODE END RBI_Init_1 */

#if defined(USE_BSP_DRIVER)

/* code generated by MX does not support BSP */

/* In order to use BSP driver, add the correspondent files in the IDE workspace */

/* and define USE_BSP_DRIVER in the preprocessor definitions or in platform.h */

return BSP_RADIO_Init();

#else

/* should be calling BSP_RADIO_Init() but not supported by MX*/


GPIO_InitTypeDef gpio_init_structure = {0};


#if LSM_RF_CHANNEL_SWITCH

/* Enable the Radio Switch Clock */

RF_SW_CTRL1_GPIO_CLK_ENABLE();

RF_SW_CTRL2_GPIO_CLK_ENABLE();

/* Configure the Radio Switch pin */

gpio_init_structure.Pin = RF_SW_CTRL1_PIN;

gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;

gpio_init_structure.Pull = GPIO_NOPULL;

gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;

HAL_GPIO_Init(RF_SW_CTRL1_GPIO_PORT, &gpio_init_structure);

gpio_init_structure.Pin = RF_SW_CTRL2_PIN;

HAL_GPIO_Init(RF_SW_CTRL2_GPIO_PORT, &gpio_init_structure);


HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

#else /* LSM_RF_CHANNEL_SWITCH */

/* Enable the Radio Switch Clock */

RF_SW_CTRL3_GPIO_CLK_ENABLE();


/* Configure the Radio Switch pin */

gpio_init_structure.Pin = RF_SW_CTRL1_PIN;

gpio_init_structure.Mode = GPIO_MODE_OUTPUT_PP;

gpio_init_structure.Pull = GPIO_NOPULL;

gpio_init_structure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;


HAL_GPIO_Init(RF_SW_CTRL1_GPIO_PORT, &gpio_init_structure);


gpio_init_structure.Pin = RF_SW_CTRL2_PIN;

HAL_GPIO_Init(RF_SW_CTRL2_GPIO_PORT, &gpio_init_structure);


gpio_init_structure.Pin = RF_SW_CTRL3_PIN;

HAL_GPIO_Init(RF_SW_CTRL3_GPIO_PORT, &gpio_init_structure);


HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_RESET);

#endif /* LSM_RF_CHANNEL_SWITCH */


return 0;

#endif /* USE_BSP_DRIVER */

/* USER CODE BEGIN RBI_Init_3 */


/* USER CODE END RBI_Init_3 */

}


/**

* @brief DeInit Radio Switch

* @retval BSP status

*/

int32_t BSP_RADIO_DeInit(void)

{

/* USER CODE BEGIN RBI_DeInit_1 */


/* USER CODE END RBI_DeInit_1 */

#if defined(USE_BSP_DRIVER)

/* code generated by MX does not support BSP */

/* In order to use BSP driver, add the correspondent files in the IDE workspace */

/* and define USE_BSP_DRIVER in the preprocessor definitions or in platform.h */

return BSP_RADIO_DeInit();

#else

#if LSM_RF_CHANNEL_SWITCH

RF_SW_CTRL1_GPIO_CLK_ENABLE();

RF_SW_CTRL2_GPIO_CLK_ENABLE();


/* Turn off switch */

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);


/* DeInit the Radio Switch pin */

HAL_GPIO_DeInit(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN);

HAL_GPIO_DeInit(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN);

#else /* LSM_RF_CHANNEL_SWITCH */

RF_SW_CTRL3_GPIO_CLK_ENABLE();


/* Turn off switch */

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_RESET);


/* DeInit the Radio Switch pin */

HAL_GPIO_DeInit(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN);

HAL_GPIO_DeInit(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN);

HAL_GPIO_DeInit(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN);

#endif /* LSM_RF_CHANNEL_SWITCH */


return 0;

#endif /* USE_BSP_DRIVER */

/* USER CODE BEGIN RBI_DeInit_3 */


/* USER CODE END RBI_DeInit_3 */

}


/**

* @brief Configure Radio Switch.

* @param Config: Specifies the Radio RF switch path to be set.

* This parameter can be one of following parameters:

* @arg RADIO_SWITCH_OFF

* @arg RADIO_SWITCH_RX

* @arg RADIO_SWITCH_RFO_LP

* @arg RADIO_SWITCH_RFO_HP

* @retval BSP status

*/

int32_t BSP_RADIO_ConfigRFSwitch(BSP_RADIO_Switch_TypeDef Config)

{

/* USER CODE BEGIN RBI_ConfigRFSwitch_1 */


/* USER CODE END RBI_ConfigRFSwitch_1 */

#if defined(USE_BSP_DRIVER)

/* code generated by MX does not support BSP */

/* In order to use BSP driver, add the correspondent files in the IDE workspace */

/* and define USE_BSP_DRIVER in the preprocessor definitions or in platform.h */

return BSP_RADIO_ConfigRFSwitch((BSP_RADIO_Switch_TypeDef) Config);

#else

switch (Config)

{

case RADIO_SWITCH_OFF:

{

#if LSM_RF_CHANNEL_SWITCH

/* Turn off switch */

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

#else /* LSM_RF_CHANNEL_SWITCH */

/* Turn off switch */

HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

#endif /* LSM_RF_CHANNEL_SWITCH */

break;

}

case RADIO_SWITCH_RX:

{

#if LSM_RF_CHANNEL_SWITCH

/*Turns On in Rx Mode the RF Switch */

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

#else /* LSM_RF_CHANNEL_SWITCH */

/*Turns On in Rx Mode the RF Switch */

HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_RESET);

#endif /* LSM_RF_CHANNEL_SWITCH */

break;

}

case RADIO_SWITCH_RFO_LP:

{

#if LSM_RF_CHANNEL_SWITCH

/*Turns On in Tx Low Power the RF Switch */

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET);

#else /* LSM_RF_CHANNEL_SWITCH */

/*Turns On in Tx Low Power the RF Switch */

HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET);

#endif /* LSM_RF_CHANNEL_SWITCH */

break;

}

case RADIO_SWITCH_RFO_HP:

{

#if LSM_RF_CHANNEL_SWITCH

/*Turns On in Tx High Power the RF Switch */

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET);

#else /* LSM_RF_CHANNEL_SWITCH */

/*Turns On in Tx High Power the RF Switch */

HAL_GPIO_WritePin(RF_SW_CTRL3_GPIO_PORT, RF_SW_CTRL3_PIN, GPIO_PIN_SET);

HAL_GPIO_WritePin(RF_SW_CTRL1_GPIO_PORT, RF_SW_CTRL1_PIN, GPIO_PIN_RESET);

HAL_GPIO_WritePin(RF_SW_CTRL2_GPIO_PORT, RF_SW_CTRL2_PIN, GPIO_PIN_SET);

#endif /* LSM_RF_CHANNEL_SWITCH */

break;

}

default:

break;

}


return 0;

#endif /* USE_BSP_DRIVER */

/* USER CODE BEGIN RBI_ConfigRFSwitch_3 */


/* USER CODE END RBI_ConfigRFSwitch_3 */

}


/**

* @brief Return Board Configuration

* @retval

* RADIO_CONF_RFO_LP_HP

* RADIO_CONF_RFO_LP

* RADIO_CONF_RFO_HP

*/

int32_t BSP_RADIO_GetTxConfig(void)

{

/* USER CODE BEGIN RBI_GetTxConfig_1 */


/* USER CODE END RBI_GetTxConfig_1 */

#if defined(USE_BSP_DRIVER)

/* Important note: BSP code is board dependent

* STM32WL_Nucleo code can be found

* either in STM32CubeWL package under Drivers/BSP/STM32WLxx_Nucleo/

* or at https://github.com/STMicroelectronics/STM32CubeWL/tree/main/Drivers/BSP/STM32WLxx_Nucleo/

* 1/ For User boards, the BSP/STM32WLxx_Nucleo/ directory can be copied and replaced in the project. The copy must then be updated depending:

* on board RF switch configuration (pin control, number of port etc)

* on TCXO configuration

* on DC/DC configuration

* on maximum output power that the board can deliver*/

return BSP_RADIO_GetTxConfig();

#else

/* 2/ Or implement RBI_GetTxConfig here */

int32_t retcode = RADIO_CONF_RFO_LP_HP;

/* USER CODE BEGIN RBI_GetTxConfig_2 */

//#warning user to provide its board code or to call his board driver functions

/* USER CODE END RBI_GetTxConfig_2 */

return retcode;

#endif /* USE_BSP_DRIVER */

}


/**

* @brief Get If TCXO is to be present on board

* @note never remove called by MW,

* @retval

* RADIO_CONF_TCXO_NOT_SUPPORTED

* RADIO_CONF_TCXO_SUPPORTED

*/

int32_t BSP_RADIO_IsTCXO(void)

{

/* USER CODE BEGIN RBI_IsTCXO_1 */


/* USER CODE END RBI_IsTCXO_1 */

#if defined(USE_BSP_DRIVER)

/* Important note: BSP code is board dependent

* STM32WL_Nucleo code can be found

* either in STM32CubeWL package under Drivers/BSP/STM32WLxx_Nucleo/

* or at https://github.com/STMicroelectronics/STM32CubeWL/tree/main/Drivers/BSP/STM32WLxx_Nucleo/

* 1/ For User boards, the BSP/STM32WLxx_Nucleo/ directory can be copied and replaced in the project. The copy must then be updated depending:

* on board RF switch configuration (pin control, number of port etc)

* on TCXO configuration

* on DC/DC configuration

* on maximum output power that the board can deliver*/

return BSP_RADIO_IsTCXO();

#else

/* 2/ Or implement RBI_IsTCXO here */

int32_t retcode = RADIO_CONF_TCXO_SUPPORTED;

/* USER CODE BEGIN RBI_IsTCXO_2 */

//#warning user to provide its board code or to call his board driver functions

/* USER CODE END RBI_IsTCXO_2 */

return retcode;

#endif /* USE_BSP_DRIVER */

}


/**

* @brief Get If DCDC is to be present on board

* @note never remove called by MW,

* @retval

* RADIO_CONF_DCDC_NOT_SUPPORTED

* RADIO_CONF_DCDC_SUPPORTED

*/

int32_t BSP_RADIO_IsDCDC(void)

{

/* USER CODE BEGIN RBI_IsDCDC_1 */


/* USER CODE END RBI_IsDCDC_1 */

#if defined(USE_BSP_DRIVER)

/* Important note: BSP code is board dependent

* STM32WL_Nucleo code can be found

* either in STM32CubeWL package under Drivers/BSP/STM32WLxx_Nucleo/

* or at https://github.com/STMicroelectronics/STM32CubeWL/tree/main/Drivers/BSP/STM32WLxx_Nucleo/

* 1/ For User boards, the BSP/STM32WLxx_Nucleo/ directory can be copied and replaced in the project. The copy must then be updated depending:

* on board RF switch configuration (pin control, number of port etc)

* on TCXO configuration

* on DC/DC configuration

* on maximum output power that the board can deliver*/

return BSP_RADIO_IsDCDC();

#else

/* 2/ Or implement RBI_IsDCDC here */

int32_t retcode = RADIO_CONF_DCDC_SUPPORTED;

/* USER CODE BEGIN RBI_IsDCDC_2 */

//#warning user to provide its board code or to call his board driver functions

/* USER CODE END RBI_IsDCDC_2 */

return retcode;

#endif /* USE_BSP_DRIVER */

}


/**

* @brief Return RF Output Max Power Configuration

* @retval

* RADIO_CONF_RFO_LP_MAX_15_dBm for LP mode

* RADIO_CONF_RFO_HP_MAX_22_dBm for HP mode

*/

int32_t BSP_RADIO_GetRFOMaxPowerConfig(BSP_RADIO_RFOMaxPowerConfig_TypeDef Config)

{

/* USER CODE BEGIN RBI_GetRFOMaxPowerConfig_1 */


/* USER CODE END RBI_GetRFOMaxPowerConfig_1 */

#if defined(USE_BSP_DRIVER)

/* Important note: BSP code is board dependent

* STM32WL_Nucleo code can be found

* either in STM32CubeWL package under Drivers/BSP/STM32WLxx_Nucleo/

* or at https://github.com/STMicroelectronics/STM32CubeWL/tree/main/Drivers/BSP/STM32WLxx_Nucleo/

* 1/ For User boards, the BSP/STM32WLxx_Nucleo/ directory can be copied and replaced in the project. The copy must then be updated depending:

* on board RF switch configuration (pin control, number of port etc)

* on TCXO configuration

* on DC/DC configuration

* on maximum output power that the board can deliver*/

return BSP_RADIO_GetRFOMaxPowerConfig((BSP_RADIO_RFOMaxPowerConfig_TypeDef) Config);

#else

/* 2/ Or implement RBI_RBI_GetRFOMaxPowerConfig here */

int32_t ret = 0;

/* USER CODE BEGIN RBI_GetRFOMaxPowerConfig_2 */

//#warning user to provide its board code or to call his board driver functions

if (Config == RADIO_RFO_LP_MAXPOWER)

{

ret = 15; /*dBm*/

}

else

{

ret = 22; /*dBm*/

}

/* USER CODE END RBI_GetRFOMaxPowerConfig_2 */

return ret;

#endif /* USE_BSP_DRIVER */

}


/**

* @}

*/


/**

* @}

*/


/**

* @}

*/


/**

* @}

*/


Alterado também o código do programa Lora_app.c: Função static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params),para pegar mensagem de downlink.

static void OnRxData(LmHandlerAppData_t *appData, LmHandlerRxParams_t *params)

{

/* USER CODE BEGIN OnRxData_1 */

uint8_t RxPort = 0;


//MIGUEL

if (params->IsMcpsIndication == MCPS_CONFIRMED || params->IsMcpsIndication == MCPS_UNCONFIRMED)

{

if(!(appData->BufferSize==0))

APP_LOG(TS_ON, VLEVEL_L, "+EVT:RX_%d, PORT %d, DR %d, RSSI %d, SNR %d %s\r\n", params->RxSlot, appData->Port,

params->Datarate, params->Rssi, params->Snr,appData->Buffer);

APP_LOG(TS_ON, VLEVEL_L, "\r\n");

}


if (params != NULL)

{

HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_SET); /* LED_BLUE */


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)

{

AppLedStateOn = appData->Buffer[0] & 0x01;

if (AppLedStateOn == RESET)

{

APP_LOG(TS_OFF, VLEVEL_H, "LED OFF\r\n");

HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_RESET); /* LED_RED */

}

else

{

APP_LOG(TS_OFF, VLEVEL_H, "LED ON\r\n");

HAL_GPIO_WritePin(LED3_GPIO_Port, LED3_Pin, GPIO_PIN_SET); /* LED_RED */

}

}

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);

}

}

/* USER CODE END OnRxData_1 */

}


Este documento é um guia básico (resumo) sobre instalação do SDK da WISOL para a módulo LoRa/SigFox LSM110A LoRa/Sigfox da Seongji e geração da APP como comandos AT, bem como os primeiros acessos à rede LoRaWAN e envio de pacotes com os comandos AT. Também é mostrado como configurar para trabalhar em uma faixa de frequências e região.


LSM110A Starter KIT
Módulo

O LSM110A é um módulo de última geração que integra o STMicroelectronics STM32WL. É muito menos consumo atual para o dispositivo IoT para estender a vida útil da bateria. E, também suporta ambas as tecnologias – Sigfox e LoRa – com o próprio módulo LSM110A.

Você pode trocar Sigfox ou LoRa com ele para que você também possa reduzir o custo. É altamente otimizado para solução de IoT (Alto Consumo de Energia, Baixo Custo)

Compilação do Firmware 

Para gerar o firmware para o LSM1x0A, será necessário que você instale o STM32CubeIDE em sua máquina.


SDK Build

Ferramentas de desenvolvimento de software ST STM32CubeIDE
Após executar o STM32CubeIDE 

Escolhe seu WorkSpace preferido


Uma tela com Documentação do STM32Cube aparecerá, mas você pode fechá-la.


  • No menu File new stm32 project procure por LoRaWAN

  • Selecione em  Example Selector o projeto LoRaWAN_End_Node

  •     Após o projeto ser importado, ele é criado e mostrado no Project Explorer (Tab) no canto superior esquerdo



Compilando o SDK

Altere para Release o projeto


Execute Build All no menu Project




    Após fazer o Build All,um HEX é criado no folder Released



    Fazendo o UPLOAD do Firmware HEX Gerado

    Será necessário que você instale em sua máquina o STM32 CUBE Programmer
    
    Conectando S-TLINK V2 no LSM110A Starter KIT, via SWD
    

    Conecte o ST-LINK V2 na USB e execute o STM32 CUBE Programmer



    Enquanto segurando o botão Reset do LSM110A Starter KIT, pressione Connect no STM32 CUBE Programmer e libere o botão de Reset.
    

    
  


    
    Click então em Start Programming



    Testando o Bootloader com o APP com comandos AT

    Conecte o LSM110A Starter KIT na USB do computador e abra um emulador de terminal na COMM que foi criada (9600,N,8,1) e veja o que deve aparecer.
    


ATENÇÃO: PARA UTILIZAR SERVIÇOS DA EVERYNET, CONTATE E PEÇA OS BROKERS.

A American Tower é uma multi nacional presente em mais de 16 países, com de 160.000 sites no mundo onde ela aluga espaço para as operadoras colocarem suas torres celulares e rádios. No Brasil ela possui mais de 19.000 sites, tendo uma ampla presença geográfica. Ela decidiu de forma pioneira no Brasil lançar uma rede LoRaWAN junto com a EveryNet, de forma a permitir o avanço do IoT.

O cliente que tem um produto que siga o padrão LoRaWAN pode contratar o serviço de dados da American Tower / EveyNet de forma a se preocupar somente com seus devices e aplicação, sem ter que se focar na infra-estrutura e gateways.





OTAA

• Vantagem: a rede gera e envia as chaves de criptografia; isto torna mais seguro. Devido ao maior nível de segurança, o OTAA é o método mais utilizado em IoT / LoRaWAN. 

• AppEUI: Este é um identificador de aplicativo exclusivo usado para agrupar objetos. este
endereço, 64 bits, é usado para classificar os dispositivos periféricos por aplicação. Essa configuração pode seja ajustado. 

• DevEUI: Este identificador, configurado de fábrica, torna cada objeto único. Em princípio, esta
configuração não pode ser ajustada. 

• AppKey: esta é uma chave secreta compartilhada entre o dispositivo periférico e a rede. É usado para determinar as chaves da sessão. Essa configuração pode ser ajustada.

Concentre-se na OTAA 

O Servido de Rede é o componente de software encarregado de estabelecer uma conexão com os objetos e gerenciando o núcleo da rede. Durante a conexão OTAA, e supondo que o dispositivo esteja autorizado a conectar-se a rede, a rede troca chaves de criptografia específicas da sessão com o núcleo da rede. O Servidor de Rede então aloca informações específicas para a sessão e as envia para o aparelho periférico:

DevAddr: Endereço lógico (equivalente a um endereço IP) que será usado para todos comunicação subseqüente.

 NetSKey (chave de sessão de rede): chave de criptografia entre o objeto e o operador usado para transmissões e para validar a integridade das mensagens. 

•   AppSKey (chave de sessão do aplicativo): chave de criptografia entre o objeto e operador (através da aplicação) utilizado para as transmissões e para validar a integridade das mensagens

1.1 Entrando na EveryNet

Passo 1: Cadastre-se uma conta de usuário no servidor EveryNet, em https://ns.atc.everynet.io




1.2 Adicionar um dispositivo EndDevice LoRaWan




Esta seção mostra como adicionar um dispositivo EndDevice LoRaWAN à rede LoRaWAN e ver os dados pelo web site da EveryNet. Usamos o LSM110A como um dispositivo de referência - a configuração para outros dispositivos LoRaWAN será semelhante.

Passo 1​: Criar uma definição de dispositivos no EveryNet

Três códigos são necessários para definir o dispositivo no EveryNet: 

Device EUI - código de identificação único para um dispositivo em particular. 
Application EUI - código de identificação para um aplicativo definido no Everynet. 
Application key - Chave exclusiva para proteger as comunicações com um dispositivo em particular.

Para o servidor EveryNet, você pode usar os códigos estabelecidos por você ou criados pelo servidor.

Pressione o sinal de + para abrir a tela abaixo e adicionar device!





Mude para Activation para OTAA e Encryption para NS

LA915-928


Dicas

Device EUI –  deixe o sistema gerar
Application EUI – deixe o sistema gerar
Application key – deixe o sistema gerar

Nota-se que há uma APP EUI já criado por EveryNet, mas esta não é a definida no dispositivo. Para adicionar o APP EUI do dispositivo LSM110A, utilize comandos AT.

Introduzir os códigos ApplicationEUI ApplicationKey obtidos do site da EveryNet e SET para cada um.




Passo 2: Ligar dispositivo LSM110A e vai juntar-se automaticamente a rede EveryNet. 


Depois de ingressar com sucesso, ele vai começar a fazer upload de mensagens para a EveryNet. Selecione a guia Dados e você vai ver os dados que aparecem no painel.

Note que isso pode levar algum tempo para que os dados do dispositivo para aparecer no visor EveryNet.

Dados são mostrados no final da página

Configuração no Servidor final.

Não esquecer de especificar "LoRaWAN protocol version" que você está utilizando em seu EndDevice (LoRaWAN protocol version)



  • Configure agora o módulo LSM1x0A
Deve ser alterado o arquivo se-identity.h

/*!
 * \file      se-identity.h
 *
 * \brief     Secure Element identity and keys
 *
 * \copyright Revised BSD License, see section \ref LICENSE.
 *
 * \code
 *                ______                              _
 *               / _____)             _              | |
 *              ( (____  _____ ____ _| |_ _____  ____| |__
 *               \____ \| ___ |    (_   _) ___ |/ ___)  _ \
 *               _____) ) ____| | | || |_| ____( (___| | | |
 *              (______/|_____)_|_|_| \__)_____)\____)_| |_|
 *              (C)2020 Semtech
 *
 *               ___ _____ _   ___ _  _____ ___  ___  ___ ___
 *              / __|_   _/_\ / __| |/ / __/ _ \| _ \/ __| __|
 *              \__ \ | |/ _ \ (__| ' <| _| (_) |   / (__| _|
 *              |___/ |_/_/ \_\___|_|\_\_| \___/|_|_\\___|___|
 *              embedded.connectivity.solutions===============
 *
 * \endcode
 *
 */
/**
  ******************************************************************************
  *
  *          Portions COPYRIGHT 2020 STMicroelectronics
  *
  * @file    se-identity.h
  * @author  MCD Application Team
  * @brief   Secure Element identity and keys
  ******************************************************************************
  */

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SOFT_SE_IDENTITY_H__
#define __SOFT_SE_IDENTITY_H__

#ifdef __cplusplus
extern "C" {
#endif

/* Exported Includes --------------------------------------------------------*/
/* USER CODE BEGIN Includes */

/* USER CODE END Includes */

/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */

/* USER CODE END ET */

/* Exported constants --------------------------------------------------------*/

/*!
 ******************************************************************************
 ********************************** WARNING ***********************************
 ******************************************************************************
  The secure-element implementation supports both 1.0.x and 1.1.x LoRaWAN
  versions of the specification.
  Thus it has been decided to use the 1.1.x keys and EUI name definitions.
  The below table shows the names equivalence between versions:
               +---------------------+-------------------------+
               |       1.0.x         |          1.1.x          |
               +=====================+=========================+
               | LORAWAN_DEVICE_EUI  | LORAWAN_DEVICE_EUI      |
               +---------------------+-------------------------+
               | LORAWAN_APP_EUI     | LORAWAN_JOIN_EUI        |
               +---------------------+-------------------------+
               | LORAWAN_GEN_APP_KEY | LORAWAN_APP_KEY         |
               +---------------------+-------------------------+
               | LORAWAN_APP_KEY     | LORAWAN_NWK_KEY         |
               +---------------------+-------------------------+
               | LORAWAN_NWK_S_KEY   | LORAWAN_F_NWK_S_INT_KEY |
               +---------------------+-------------------------+
               | LORAWAN_NWK_S_KEY   | LORAWAN_S_NWK_S_INT_KEY |
               +---------------------+-------------------------+
               | LORAWAN_NWK_S_KEY   | LORAWAN_NWK_S_ENC_KEY   |
               +---------------------+-------------------------+
               | LORAWAN_APP_S_KEY   | LORAWAN_APP_S_KEY       |
               +---------------------+-------------------------+
 ******************************************************************************
 ******************************************************************************
 ******************************************************************************
 */
/*!
 * End-device IEEE EUI (big endian)
 * When set to 00,00,00,00,00,00,00,00 DevEui is automatically set with a value provided by MCU platform
 */
#define LORAWAN_DEVICE_EUI                                 00,80,e1,15,05,1f,cc,25

/*!
 * App/Join server IEEE EUI (big endian)
 */
#define LORAWAN_JOIN_EUI                                   53,4a,e9,67,7f,fc,1c,41

/*!
 * Device address on the network (big endian)
 * When set to 00,00,00,00 DevAddr is automatically set with a value provided by MCU platform
 */
#define LORAWAN_DEVICE_ADDRESS                             00,00,00,00

/*!
 * Application root key
 */
#define LORAWAN_APP_KEY                                    70,8c,e3,cf,ac,f8,8f,24,eb,88,da,47,8c,e5,6f,ca

/*!
 * Network root key
 */
#define LORAWAN_NWK_KEY                                    70,8c,e3,cf,ac,f8,8f,24,eb,88,da,47,8c,e5,6f,ca

/*!
 * Forwarding Network session key
 */
#define LORAWAN_NWK_S_KEY                                  2B,7E,15,16,28,AE,D2,A6,AB,F7,15,88,09,CF,4F,3C

/*!
 * Application session key
 */
#define LORAWAN_APP_S_KEY                                  2B,7E,15,16,28,AE,D2,A6,AB,F7,15,88,09,CF,4F,3C

/*!
 * Format commissioning keys
 */
#define RAW_TO_INT8A(a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) {0x##a,0x##b,0x##c,0x##d,\
                                                       0x##e,0x##f,0x##g,0x##h,\
                                                       0x##i,0x##j,0x##k,0x##l,\
                                                       0x##m,0x##n,0x##o,0x##p}

#define RAW8_TO_INT8A(a,b,c,d) 0x##a##b##c##d
#define RAW32_TO_INT8A(a,b,c,d,e,f,g,h) {0x##a,0x##b,0x##c,0x##d,\
                                         0x##e,0x##f,0x##g,0x##h}

#define FORMAT_KEY(...) RAW_TO_INT8A(__VA_ARGS__)
#define FORMAT8_KEY(...) RAW8_TO_INT8A(__VA_ARGS__)
#define FORMAT32_KEY(...) RAW32_TO_INT8A(__VA_ARGS__)

#if (defined( LORAMAC_VERSION ) && ( LORAMAC_VERSION == 0x01010100 ))
#define SESSION_KEYS_LIST                                                                                           \
        {                                                                                                           \
            /*!                                                                                                     \
             * Join session integrity key (Dynamically updated)                                                     \
             * WARNING: NOT USED FOR 1.0.x DEVICES                                                                  \
             */                                                                                                     \
            .KeyID    = J_S_INT_KEY,                                                                                \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Join session encryption key (Dynamically updated)                                                    \
             * WARNING: NOT USED FOR 1.0.x DEVICES                                                                  \
             */                                                                                                     \
            .KeyID    = J_S_ENC_KEY,                                                                                \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Forwarding Network session integrity key                                                             \
             * WARNING: NWK_S_KEY FOR 1.0.x DEVICES                                                                 \
             */                                                                                                     \
            .KeyID    = F_NWK_S_INT_KEY,                                                                            \
            .KeyValue = FORMAT_KEY(LORAWAN_NWK_S_KEY),                                                              \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Serving Network session integrity key                                                                \
             * WARNING: NOT USED FOR 1.0.x DEVICES. MUST BE THE SAME AS \ref LORAWAN_F_NWK_S_INT_KEY                \
             */                                                                                                     \
            .KeyID    = S_NWK_S_INT_KEY,                                                                            \
            .KeyValue = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, \
                          0x3C },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Network session encryption key                                                                       \
             * WARNING: NOT USED FOR 1.0.x DEVICES. MUST BE THE SAME AS \ref LORAWAN_F_NWK_S_INT_KEY                \
             */                                                                                                     \
            .KeyID    = NWK_S_ENC_KEY,                                                                              \
            .KeyValue = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, \
                          0x3C },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Application session key                                                                              \
             */                                                                                                     \
            .KeyID    = APP_S_KEY,                                                                                  \
            .KeyValue = FORMAT_KEY(LORAWAN_APP_S_KEY),                                                              \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Datablock MIC key                                                                                    \
             */                                                                                                     \
            .KeyID    = DATABLOCK_INT_KEY,                                                                          \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },
#else
#define SESSION_KEYS_LIST                                                                                           \
        {                                                                                                           \
            /*!                                                                                                     \
             * Network session key                                                                                  \
             */                                                                                                     \
            .KeyID    = NWK_S_KEY,                                                                                  \
            .KeyValue = FORMAT_KEY(LORAWAN_NWK_S_KEY),                                                              \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Application session key                                                                              \
             */                                                                                                     \
            .KeyID    = APP_S_KEY,                                                                                  \
            .KeyValue = FORMAT_KEY(LORAWAN_APP_S_KEY),                                                              \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Datablock MIC key                                                                                    \
             */                                                                                                     \
            .KeyID    = DATABLOCK_INT_KEY,                                                                          \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },
#endif /* LORAMAC_VERSION */

#if (LORAMAC_MAX_MC_CTX == 1)
#define SESSION_MC_KEYS_LIST                                                                                        \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #0 root key (Dynamically updated)                                                    \
             */                                                                                                     \
            .KeyID    = MC_KEY_0,                                                                                   \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #0 application session key (Dynamically updated)                                     \
             */                                                                                                     \
            .KeyID    = MC_APP_S_KEY_0,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #0 network session key (Dynamically updated)                                         \
             */                                                                                                     \
            .KeyID    = MC_NWK_S_KEY_0,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },
#else /* LORAMAC_MAX_MC_CTX > 1 */
#define SESSION_MC_KEYS_LIST                                                                                        \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #0 root key (Dynamically updated)                                                    \
             */                                                                                                     \
            .KeyID    = MC_KEY_0,                                                                                   \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #0 application session key (Dynamically updated)                                     \
             */                                                                                                     \
            .KeyID    = MC_APP_S_KEY_0,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #0 network session key (Dynamically updated)                                         \
             */                                                                                                     \
            .KeyID    = MC_NWK_S_KEY_0,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #1 root key (Dynamically updated)                                                    \
             */                                                                                                     \
            .KeyID    = MC_KEY_1,                                                                                   \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #1 application session key (Dynamically updated)                                     \
             */                                                                                                     \
            .KeyID    = MC_APP_S_KEY_1,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #1 network session key (Dynamically updated)                                         \
             */                                                                                                     \
            .KeyID    = MC_NWK_S_KEY_1,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #2 root key (Dynamically updated)                                                    \
             */                                                                                                     \
            .KeyID    = MC_KEY_2,                                                                                   \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #2 application session key (Dynamically updated)                                     \
             */                                                                                                     \
            .KeyID    = MC_APP_S_KEY_2,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #2 network session key (Dynamically updated)                                         \
             */                                                                                                     \
            .KeyID    = MC_NWK_S_KEY_2,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #3 root key (Dynamically updated)                                                    \
             */                                                                                                     \
            .KeyID    = MC_KEY_3,                                                                                   \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #3 application session key (Dynamically updated)                                     \
             */                                                                                                     \
            .KeyID    = MC_APP_S_KEY_3,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast group #3 network session key (Dynamically updated)                                         \
             */                                                                                                     \
            .KeyID    = MC_NWK_S_KEY_3,                                                                             \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },
#endif /* LORAMAC_MAX_MC_CTX */

#define SOFT_SE_KEY_LIST                                                                                            \
    {                                                                                                               \
        {                                                                                                           \
            /*!                                                                                                     \
             * Application root key                                                                                 \
             * WARNING: FOR 1.0.x DEVICES IT IS THE \ref LORAWAN_GEN_APP_KEY                                        \
             */                                                                                                     \
            .KeyID    = APP_KEY,                                                                                    \
            .KeyValue = FORMAT_KEY(LORAWAN_APP_KEY),                                                                \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Network root key                                                                                     \
             * WARNING: FOR 1.0.x DEVICES IT IS THE \ref LORAWAN_APP_KEY                                            \
             */                                                                                                     \
            .KeyID    = NWK_KEY,                                                                                    \
            .KeyValue = FORMAT_KEY(LORAWAN_NWK_KEY),                                                                \
        },                                                                                                          \
        SESSION_KEYS_LIST                                                                                           \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast root key (Dynamically updated)                                                             \
             */                                                                                                     \
            .KeyID    = MC_ROOT_KEY,                                                                                \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        {                                                                                                           \
            /*!                                                                                                     \
             * Multicast key encryption key (Dynamically updated)                                                   \
             */                                                                                                     \
            .KeyID    = MC_KE_KEY,                                                                                  \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
        SESSION_MC_KEYS_LIST                                                                                        \
        {                                                                                                           \
            /*!                                                                                                     \
             * All zeros key. (ClassB usage)(constant)                                                              \
             */                                                                                                     \
            .KeyID    = SLOT_RAND_ZERO_KEY,                                                                         \
            .KeyValue = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
                          0x00 },                                                                                   \
        },                                                                                                          \
    }

#define SOFT_SE_ID_LIST                                                                                             \
    .SeNvmDevJoinKey.DevEui = FORMAT32_KEY(LORAWAN_DEVICE_EUI),                                                     \
    .SeNvmDevJoinKey.JoinEui = FORMAT32_KEY(LORAWAN_JOIN_EUI),                                                      \
    .SeNvmDevJoinKey.DevAddrOTAA = FORMAT8_KEY(LORAWAN_DEVICE_ADDRESS),                                             \
    .SeNvmDevJoinKey.DevAddrABP = FORMAT8_KEY(LORAWAN_DEVICE_ADDRESS)                                               \

/* USER CODE BEGIN EC */

/* USER CODE END EC */

#ifdef __cplusplus
}
#endif

#endif  /*  __SOFT_SE_IDENTITY_H__ */


TESTES

JOIN EM OTAA

ENVIADO PACOTE



DOWNLINK

Alterado LmHandler.c

static void McpsIndication( McpsIndication_t *mcpsIndication, LoRaMacRxStatus_t *rxStatus )

{

LmHandlerAppData_t appData;

DeviceClass_t deviceClass = CLASS_A;

RxParams.IsMcpsIndication = 1;

RxParams.Status = mcpsIndication->Status;


if( RxParams.Status != LORAMAC_EVENT_INFO_STATUS_OK )

{

return;

}


RxParams.Datarate = mcpsIndication->RxDatarate;

RxParams.Rssi = rxStatus->Rssi;

RxParams.Snr = rxStatus->Snr;

RxParams.RxSlot = rxStatus->RxSlot;

RxParams.DownlinkCounter = mcpsIndication->DownLinkCounter;


appData.Port = mcpsIndication->Port;

appData.BufferSize = mcpsIndication->BufferSize;

appData.Buffer = mcpsIndication->Buffer;


//MIGUEL

if (mcpsIndication->McpsIndication == MCPS_CONFIRMED || mcpsIndication->McpsIndication == MCPS_UNCONFIRMED)

{

if(!(mcpsIndication->BufferSize==0))

{

APP_LOG(TS_ON, VLEVEL_L, "Received downlink data of size: %d\r\n", mcpsIndication->BufferSize);

for (int i = 0; i < mcpsIndication->BufferSize; i++)

APP_LOG(TS_ON, VLEVEL_L, "Data[%d]: %c\r\n", i, mcpsIndication->Buffer[i]);

APP_LOG(TS_ON, VLEVEL_L, "\r\n");

}

}

//MIGUEL


if( LmHandlerCallbacks->OnRxData != NULL )

{

LmHandlerCallbacks->OnRxData( &appData, &RxParams );

}


if( ( LmHandlerCallbacks->OnSysTimeUpdate != NULL ) && ( mcpsIndication->DeviceTimeAnsReceived == true ) )

{

LmHandlerCallbacks->OnSysTimeUpdate( );

}

/* Call packages RxProcess function */

LmHandlerPackagesNotify( PACKAGE_MCPS_INDICATION, mcpsIndication );


LmHandlerGetCurrentClass( &deviceClass );

#if (defined( LORAMAC_VERSION ) && ( LORAMAC_VERSION == 0x01000300 ))

if( mcpsIndication->IsUplinkTxPending != 0 )

{

/* The server signals that it has pending data to be sent. */

/* We schedule an uplink as soon as possible to flush the server. */


/* Send an empty message */

LmHandlerAppData_t appData =

{

.Buffer = NULL,

.BufferSize = 0,

.Port = 0

};

LmHandlerSend( &appData, LORAMAC_HANDLER_UNCONFIRMED_MSG, true );

}

#elif (defined( LORAMAC_VERSION ) && (( LORAMAC_VERSION == 0x01000400 ) || ( LORAMAC_VERSION == 0x01010100 )))

if( mcpsIndication->IsUplinkTxPending != 0 )

{

/* The server signals that it has pending data to be sent. */

/* We schedule an uplink as soon as possible to flush the server. */

IsUplinkTxPending = true;

}

#endif /* LORAMAC_VERSION */

}


Downlink 


Dúvidas
suporte@smartcore.com.br

Kit de avaliação para módulo LoRa e Sigfox Wisol Seong JI SJI LSM110A

Operação em rede pública e privada LoRaWAN  e também ponto a ponto (P2P)

Opera também em Sigfox

Alterne entre LoRa e Sigfox por comando AT, não precisa trocar o Firmware!

Permite embarcar sua aplicação


Módulo LoRa e Sigfox Wisol Seong JI SJI LSM110A

Módulo LoRa e Sigfox compacto

Escolha entre operação LoRa e Sigfox por comando "on the fly", sem precisar trocar firmware !

LoRa: para operação redes públicas e privadas LoRaWAN bem como ponto a ponto (P2P)
Sigfox: zonas RCZ2 e RCZ4 (inclui Brasil)

Caracteristicas:

- Permite embarcar a aplicação
- Dimensão: 14x15x2,8mm
- Frequência: RCZ2 Tx 902,2MHz  Rx 905,2MHz
- Potência de saida: configurável até +22dBm
- Sensibilidade:  -129dBm@LoRa(BW=500KHz, SF=12)
                  -124dBm@Sigfox(0.6Kbps)
- Tensão de operação: 1,8 - 3,6Vdc
- Interface UART 9600 8N1
- Baixo consumo
- Na operação P2P não necessita de gateway LoRaWAN

Aplicações:
- Medição individualizada de água, energia, gás
- Automação comercial, industrial residencial;
- Rede de sensores;
- Sistemas de alarme e segurança;
- Estações meteorológicas;
- Automação agrícola.
 

NÃO TESTADO - OPENCPU (API MODE) - NÃO TESTADO

Caso queira utilizar como OpenCPU e embarcar sua aplicação:
  • utilize o SDK do STM32 
  • veja como é estruturado a troca de mensagens em (Message Sequence Chart) numa conexão com LoraWAN

Lembrando que não há nenhum exemplo no momento por parte da Smartcore ou Wisol quando utilizado como OPENCPU. Requer conhecimento em programação C baseado no STM32.


Mas estes vídeos mostram como utilizar o STM32WL com SDK da STM



Gerando HEX


Referências


  • DevNonce is too small error in the device events: If the device is using LoRaWAN MAC version 1.1 or 1.0.4, this error occurs when DevNonce is not being incremented, so the Join Server ignores Join Requests with the same or lower DevNonce value comparing to the previous one. Contact your device’s manufacturer to find out the correct LoRaWAN MAC and PHY versions, and configure the device in The Things Stack accordingly

Sobre a SMARTCORE

A SmartCore fornece módulos para comunicação wireless, biometria, conectividade, rastreamento e automação.
Nosso portfólio inclui modem 2G/3G/4G/NB-IoT/Cat.M, satelital, módulos WiFi, Bluetooth, GNSS / GPS, Sigfox, LoRa, leitor de cartão, leitor QR code, mecanismo de impressão, mini-board PC, antena, pigtail, LCD, bateria, repetidor GPS e sensores.

Mais detalhes em www.smartcore.com.br

Nenhum comentário:

Postar um comentário