application layer with: button, LED, pot, tempSense

Dependencies:   mbed SX1272Lib

Fork of LoRaWAN-demo-72-bootcamp by Semtech

Use with sx1272 shield with grove peripherals connected:

D8 D9: ButtonRX TXA3 A4: TempSense
D6 D7:SCL SDA : LEDA1 A2: Pot

Button

Sends to different payloads: short press (under 1 sec)
long press: held down > 1 sec.

serial console keys

115200bps, 8N1
Enter key not used
Keys '0' to '3': cayenne channel number
'0': pot (rotary sensor)
'1': temperature
' 2': digital out
'3': analog out

Committer:
Wayne Roberts
Date:
Mon Feb 12 11:25:50 2018 -0800
Revision:
12:662ff73ce484
Parent:
11:018e7e28161d
Child:
13:f88dd77772b6
add user button trigger for automatic uplink

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:45496a70a8a5 1 /*
mluis 0:45496a70a8a5 2 / _____) _ | |
mluis 0:45496a70a8a5 3 ( (____ _____ ____ _| |_ _____ ____| |__
mluis 0:45496a70a8a5 4 \____ \| ___ | (_ _) ___ |/ ___) _ \
mluis 0:45496a70a8a5 5 _____) ) ____| | | || |_| ____( (___| | | |
mluis 0:45496a70a8a5 6 (______/|_____)_|_|_| \__)_____)\____)_| |_|
mluis 0:45496a70a8a5 7 (C)2015 Semtech
mluis 0:45496a70a8a5 8
mluis 0:45496a70a8a5 9 Description: LoRaMac classA device implementation
mluis 0:45496a70a8a5 10
mluis 0:45496a70a8a5 11 License: Revised BSD License, see LICENSE.TXT file include in the project
mluis 0:45496a70a8a5 12
mluis 0:45496a70a8a5 13 Maintainer: Miguel Luis and Gregory Cristian
mluis 0:45496a70a8a5 14 */
mluis 0:45496a70a8a5 15 #include "mbed.h"
mluis 0:45496a70a8a5 16 #include "board.h"
mluis 0:45496a70a8a5 17 #include "radio.h"
mluis 0:45496a70a8a5 18
mluis 0:45496a70a8a5 19 #include "LoRaMac.h"
mluis 9:0083afd69815 20 #include "Commissioning.h"
mluis 0:45496a70a8a5 21 #include "SerialDisplay.h"
mluis 0:45496a70a8a5 22
mluis 0:45496a70a8a5 23 /*!
mluis 9:0083afd69815 24 * Defines the application data transmission duty cycle. 5s, value in [ms].
mluis 0:45496a70a8a5 25 */
mluis 9:0083afd69815 26 #define APP_TX_DUTYCYCLE 5000
mluis 0:45496a70a8a5 27
mluis 0:45496a70a8a5 28 /*!
mluis 0:45496a70a8a5 29 * Defines a random delay for application data transmission duty cycle. 1s,
mluis 9:0083afd69815 30 * value in [ms].
mluis 0:45496a70a8a5 31 */
mluis 9:0083afd69815 32 #define APP_TX_DUTYCYCLE_RND 1000
mluis 0:45496a70a8a5 33
mluis 0:45496a70a8a5 34 /*!
mluis 5:fa113b25f612 35 * Default datarate
mluis 0:45496a70a8a5 36 */
GregCr 2:48d8d4806d48 37 #define LORAWAN_DEFAULT_DATARATE DR_5
mluis 0:45496a70a8a5 38
mluis 0:45496a70a8a5 39 /*!
mluis 0:45496a70a8a5 40 * LoRaWAN confirmed messages
mluis 0:45496a70a8a5 41 */
GregCr 2:48d8d4806d48 42 #define LORAWAN_CONFIRMED_MSG_ON false
mluis 0:45496a70a8a5 43
mluis 0:45496a70a8a5 44 /*!
mluis 0:45496a70a8a5 45 * LoRaWAN Adaptive Data Rate
mluis 0:45496a70a8a5 46 *
mluis 0:45496a70a8a5 47 * \remark Please note that when ADR is enabled the end-device should be static
mluis 0:45496a70a8a5 48 */
mluis 0:45496a70a8a5 49 #define LORAWAN_ADR_ON 1
mluis 0:45496a70a8a5 50
mluis 0:45496a70a8a5 51 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 52
mluis 0:45496a70a8a5 53 #include "LoRaMacTest.h"
mluis 0:45496a70a8a5 54
mluis 0:45496a70a8a5 55 /*!
mluis 0:45496a70a8a5 56 * LoRaWAN ETSI duty cycle control enable/disable
mluis 0:45496a70a8a5 57 *
mluis 0:45496a70a8a5 58 * \remark Please note that ETSI mandates duty cycled transmissions. Use only for test purposes
mluis 0:45496a70a8a5 59 */
GregCr 2:48d8d4806d48 60 #define LORAWAN_DUTYCYCLE_ON false
mluis 0:45496a70a8a5 61
mluis 5:fa113b25f612 62 #define USE_SEMTECH_DEFAULT_CHANNEL_LINEUP 1
mluis 5:fa113b25f612 63
mluis 9:0083afd69815 64 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
mluis 5:fa113b25f612 65
mluis 5:fa113b25f612 66 #define LC4 { 867100000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 5:fa113b25f612 67 #define LC5 { 867300000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 5:fa113b25f612 68 #define LC6 { 867500000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 5:fa113b25f612 69 #define LC7 { 867700000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 5:fa113b25f612 70 #define LC8 { 867900000, { ( ( DR_5 << 4 ) | DR_0 ) }, 0 }
mluis 5:fa113b25f612 71 #define LC9 { 868800000, { ( ( DR_7 << 4 ) | DR_7 ) }, 2 }
mluis 5:fa113b25f612 72 #define LC10 { 868300000, { ( ( DR_6 << 4 ) | DR_6 ) }, 1 }
mluis 5:fa113b25f612 73
mluis 5:fa113b25f612 74 #endif
mluis 5:fa113b25f612 75
mluis 0:45496a70a8a5 76 #endif
mluis 0:45496a70a8a5 77
mluis 0:45496a70a8a5 78 /*!
mluis 0:45496a70a8a5 79 * LoRaWAN application port
mluis 0:45496a70a8a5 80 */
GregCr 3:d4142832d5af 81 #define LORAWAN_APP_PORT 10
mluis 0:45496a70a8a5 82
mluis 0:45496a70a8a5 83 /*!
mluis 0:45496a70a8a5 84 * User application data buffer size
mluis 0:45496a70a8a5 85 */
mluis 0:45496a70a8a5 86 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
mluis 0:45496a70a8a5 87 #define LORAWAN_APP_DATA_SIZE 6
mluis 0:45496a70a8a5 88
mluis 0:45496a70a8a5 89 #else
GregCr 3:d4142832d5af 90 #define LORAWAN_APP_DATA_SIZE 5
mluis 0:45496a70a8a5 91
mluis 0:45496a70a8a5 92 #endif
mluis 0:45496a70a8a5 93
mluis 0:45496a70a8a5 94 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
mluis 0:45496a70a8a5 95 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
mluis 0:45496a70a8a5 96 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
mluis 0:45496a70a8a5 97
mluis 7:ceb4063e6863 98 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 0:45496a70a8a5 99
mluis 0:45496a70a8a5 100 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
mluis 0:45496a70a8a5 101 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
mluis 0:45496a70a8a5 102
mluis 0:45496a70a8a5 103 /*!
mluis 0:45496a70a8a5 104 * Device address
mluis 0:45496a70a8a5 105 */
mluis 0:45496a70a8a5 106 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
mluis 0:45496a70a8a5 107
mluis 0:45496a70a8a5 108 #endif
mluis 0:45496a70a8a5 109
mluis 0:45496a70a8a5 110 /*!
mluis 0:45496a70a8a5 111 * Application port
mluis 0:45496a70a8a5 112 */
mluis 0:45496a70a8a5 113 static uint8_t AppPort = LORAWAN_APP_PORT;
mluis 0:45496a70a8a5 114
mluis 0:45496a70a8a5 115 /*!
mluis 0:45496a70a8a5 116 * User application data size
mluis 0:45496a70a8a5 117 */
dudmuck 11:018e7e28161d 118 static uint8_t gAppDataSize = LORAWAN_APP_DATA_SIZE;
mluis 0:45496a70a8a5 119
mluis 0:45496a70a8a5 120 /*!
mluis 0:45496a70a8a5 121 * User application data buffer size
mluis 0:45496a70a8a5 122 */
mluis 0:45496a70a8a5 123 #define LORAWAN_APP_DATA_MAX_SIZE 64
mluis 0:45496a70a8a5 124
mluis 0:45496a70a8a5 125 /*!
mluis 0:45496a70a8a5 126 * User application data
mluis 0:45496a70a8a5 127 */
mluis 0:45496a70a8a5 128 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
mluis 0:45496a70a8a5 129
mluis 0:45496a70a8a5 130 /*!
mluis 0:45496a70a8a5 131 * Indicates if the node is sending confirmed or unconfirmed messages
mluis 0:45496a70a8a5 132 */
dudmuck 11:018e7e28161d 133 static uint8_t gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
mluis 0:45496a70a8a5 134
mluis 0:45496a70a8a5 135 /*!
mluis 0:45496a70a8a5 136 * Device states
mluis 0:45496a70a8a5 137 */
dudmuck 10:52810ecbd83b 138 static enum eDeviceState {
dudmuck 10:52810ecbd83b 139 DEVICE_STATE_INIT = 0,
mluis 0:45496a70a8a5 140 DEVICE_STATE_JOIN,
dudmuck 10:52810ecbd83b 141 DEVICE_STATE_JOIN_OK,
mluis 0:45496a70a8a5 142 DEVICE_STATE_SEND,
dudmuck 10:52810ecbd83b 143 DEVICE_STATE_TRIGGER,
mluis 0:45496a70a8a5 144 DEVICE_STATE_SLEEP
dudmuck 10:52810ecbd83b 145 } DeviceState;
mluis 0:45496a70a8a5 146
mluis 0:45496a70a8a5 147 /*!
mluis 0:45496a70a8a5 148 * LoRaWAN compliance tests support data
mluis 0:45496a70a8a5 149 */
dudmuck 10:52810ecbd83b 150 struct ComplianceTest_s {
mluis 0:45496a70a8a5 151 bool Running;
mluis 0:45496a70a8a5 152 uint8_t State;
mluis 0:45496a70a8a5 153 bool IsTxConfirmed;
mluis 0:45496a70a8a5 154 uint8_t AppPort;
mluis 0:45496a70a8a5 155 uint8_t AppDataSize;
mluis 0:45496a70a8a5 156 uint8_t *AppDataBuffer;
mluis 0:45496a70a8a5 157 uint16_t DownLinkCounter;
mluis 0:45496a70a8a5 158 bool LinkCheck;
mluis 0:45496a70a8a5 159 uint8_t DemodMargin;
mluis 0:45496a70a8a5 160 uint8_t NbGateways;
dudmuck 10:52810ecbd83b 161 } ComplianceTest;
mluis 0:45496a70a8a5 162
mluis 0:45496a70a8a5 163 /*
mluis 0:45496a70a8a5 164 * SerialDisplay managment variables
mluis 0:45496a70a8a5 165 */
mluis 0:45496a70a8a5 166
mluis 0:45496a70a8a5 167 /*!
mluis 0:45496a70a8a5 168 * Strucure containing the Uplink status
mluis 0:45496a70a8a5 169 */
dudmuck 10:52810ecbd83b 170 struct sLoRaMacUplinkStatus {
mluis 0:45496a70a8a5 171 uint8_t Acked;
mluis 0:45496a70a8a5 172 int8_t Datarate;
mluis 0:45496a70a8a5 173 uint16_t UplinkCounter;
mluis 0:45496a70a8a5 174 uint8_t Port;
mluis 0:45496a70a8a5 175 uint8_t *Buffer;
mluis 0:45496a70a8a5 176 uint8_t BufferSize;
dudmuck 10:52810ecbd83b 177 } LoRaMacUplinkStatus;
mluis 0:45496a70a8a5 178
mluis 0:45496a70a8a5 179 /*!
mluis 0:45496a70a8a5 180 * Strucure containing the Downlink status
mluis 0:45496a70a8a5 181 */
dudmuck 10:52810ecbd83b 182 struct sLoRaMacDownlinkStatus {
mluis 0:45496a70a8a5 183 int16_t Rssi;
mluis 0:45496a70a8a5 184 int8_t Snr;
mluis 0:45496a70a8a5 185 uint16_t DownlinkCounter;
mluis 0:45496a70a8a5 186 bool RxData;
mluis 0:45496a70a8a5 187 uint8_t Port;
mluis 0:45496a70a8a5 188 uint8_t *Buffer;
mluis 0:45496a70a8a5 189 uint8_t BufferSize;
dudmuck 10:52810ecbd83b 190 } LoRaMacDownlinkStatus;
mluis 0:45496a70a8a5 191 volatile bool DownlinkStatusUpdated = false;
mluis 0:45496a70a8a5 192
mluis 0:45496a70a8a5 193 void SerialDisplayRefresh( void )
mluis 0:45496a70a8a5 194 {
mluis 0:45496a70a8a5 195 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 196
mluis 0:45496a70a8a5 197 SerialDisplayInit( );
mluis 0:45496a70a8a5 198 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:45496a70a8a5 199
mluis 0:45496a70a8a5 200 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 0:45496a70a8a5 201 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 0:45496a70a8a5 202 SerialDisplayUpdateDevAddr( DevAddr );
mluis 0:45496a70a8a5 203 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 0:45496a70a8a5 204 SerialDisplayUpdateKey( 13, AppSKey );
mluis 7:ceb4063e6863 205 #endif
mluis 0:45496a70a8a5 206 SerialDisplayUpdateEui( 5, DevEui );
mluis 0:45496a70a8a5 207 SerialDisplayUpdateEui( 6, AppEui );
mluis 0:45496a70a8a5 208 SerialDisplayUpdateKey( 7, AppKey );
mluis 0:45496a70a8a5 209
mluis 0:45496a70a8a5 210 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 211 LoRaMacMibGetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 212 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
mluis 0:45496a70a8a5 213
mluis 0:45496a70a8a5 214 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:45496a70a8a5 215 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 216 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 217 #else
mluis 0:45496a70a8a5 218 SerialDisplayUpdateDutyCycle( false );
mluis 0:45496a70a8a5 219 #endif
mluis 0:45496a70a8a5 220 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
dudmuck 10:52810ecbd83b 221
dudmuck 10:52810ecbd83b 222 //SerialDisplayUpdateLedState( 3, AppLedStateOn );
mluis 0:45496a70a8a5 223 }
mluis 0:45496a70a8a5 224
dudmuck 11:018e7e28161d 225
dudmuck 11:018e7e28161d 226 void LoRaMacStatus_toString(LoRaMacStatus_t s, char* out)
dudmuck 11:018e7e28161d 227 {
dudmuck 11:018e7e28161d 228 switch (s) {
dudmuck 11:018e7e28161d 229 case LORAMAC_STATUS_PARAMETER_INVALID:
dudmuck 11:018e7e28161d 230 strcpy(out, "PARAMTER_INVALID");
dudmuck 11:018e7e28161d 231 break;
dudmuck 11:018e7e28161d 232 case LORAMAC_STATUS_BUSY:
dudmuck 11:018e7e28161d 233 strcpy(out, "BUSY");
dudmuck 11:018e7e28161d 234 break;
dudmuck 11:018e7e28161d 235 default:
dudmuck 11:018e7e28161d 236 sprintf(out, "<%u>", s);
dudmuck 11:018e7e28161d 237 break;
dudmuck 11:018e7e28161d 238 }
dudmuck 11:018e7e28161d 239 }
dudmuck 11:018e7e28161d 240
dudmuck 11:018e7e28161d 241 volatile unsigned sendCnt = 0;
dudmuck 11:018e7e28161d 242 /*!
dudmuck 11:018e7e28161d 243 * \brief Prepares the payload of the frame
dudmuck 11:018e7e28161d 244 *
dudmuck 11:018e7e28161d 245 * \retval [0: frame could be send, 1: error]
dudmuck 11:018e7e28161d 246 */
dudmuck 11:018e7e28161d 247 static bool SendFrame( uint8_t len, bool conf )
dudmuck 11:018e7e28161d 248 {
dudmuck 11:018e7e28161d 249 char str[48];
dudmuck 11:018e7e28161d 250 LoRaMacStatus_t status;
dudmuck 11:018e7e28161d 251 McpsReq_t mcpsReq;
dudmuck 11:018e7e28161d 252 LoRaMacTxInfo_t txInfo;
dudmuck 11:018e7e28161d 253
dudmuck 11:018e7e28161d 254 if( LoRaMacQueryTxPossible( len, &txInfo ) != LORAMAC_STATUS_OK ) {
dudmuck 11:018e7e28161d 255 // Send empty frame in order to flush MAC commands
dudmuck 11:018e7e28161d 256 mcpsReq.Type = MCPS_UNCONFIRMED;
dudmuck 11:018e7e28161d 257 mcpsReq.Req.Unconfirmed.fBuffer = NULL;
dudmuck 11:018e7e28161d 258 mcpsReq.Req.Unconfirmed.fBufferSize = 0;
dudmuck 11:018e7e28161d 259 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
dudmuck 11:018e7e28161d 260
dudmuck 11:018e7e28161d 261 LoRaMacUplinkStatus.Acked = false;
dudmuck 11:018e7e28161d 262 LoRaMacUplinkStatus.Port = 0;
dudmuck 11:018e7e28161d 263 LoRaMacUplinkStatus.Buffer = NULL;
dudmuck 11:018e7e28161d 264 LoRaMacUplinkStatus.BufferSize = 0;
dudmuck 11:018e7e28161d 265 SerialDisplayUpdateFrameType( false );
dudmuck 11:018e7e28161d 266 } else {
dudmuck 11:018e7e28161d 267 LoRaMacUplinkStatus.Acked = false;
dudmuck 11:018e7e28161d 268 LoRaMacUplinkStatus.Port = AppPort;
dudmuck 11:018e7e28161d 269 LoRaMacUplinkStatus.Buffer = AppData;
dudmuck 11:018e7e28161d 270 LoRaMacUplinkStatus.BufferSize = len;//AppDataSize;
dudmuck 11:018e7e28161d 271 SerialDisplayUpdateFrameType( conf/*IsTxConfirmed*/ );
dudmuck 11:018e7e28161d 272
dudmuck 11:018e7e28161d 273 if( conf == false ) {
dudmuck 11:018e7e28161d 274 mcpsReq.Type = MCPS_UNCONFIRMED;
dudmuck 11:018e7e28161d 275 mcpsReq.Req.Unconfirmed.fPort = AppPort;
dudmuck 11:018e7e28161d 276 mcpsReq.Req.Unconfirmed.fBuffer = AppData;
dudmuck 11:018e7e28161d 277 mcpsReq.Req.Unconfirmed.fBufferSize = len;
dudmuck 11:018e7e28161d 278 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
dudmuck 11:018e7e28161d 279 } else {
dudmuck 11:018e7e28161d 280 mcpsReq.Type = MCPS_CONFIRMED;
dudmuck 11:018e7e28161d 281 mcpsReq.Req.Confirmed.fPort = AppPort;
dudmuck 11:018e7e28161d 282 mcpsReq.Req.Confirmed.fBuffer = AppData;
dudmuck 11:018e7e28161d 283 mcpsReq.Req.Confirmed.fBufferSize = len;
dudmuck 11:018e7e28161d 284 mcpsReq.Req.Confirmed.NbTrials = 8;
dudmuck 11:018e7e28161d 285 mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
dudmuck 11:018e7e28161d 286 }
dudmuck 11:018e7e28161d 287 }
dudmuck 11:018e7e28161d 288
dudmuck 11:018e7e28161d 289 sendCnt++;
dudmuck 11:018e7e28161d 290 status = LoRaMacMcpsRequest( &mcpsReq );
dudmuck 11:018e7e28161d 291 if (status == LORAMAC_STATUS_OK) {
dudmuck 11:018e7e28161d 292 vt.SetCursorPos( 44, 1 );
dudmuck 11:018e7e28161d 293 vt.printf("%u sendFrame() OK\e[K", sendCnt);
dudmuck 11:018e7e28161d 294 SerialDisplayUpdateUplink(
dudmuck 11:018e7e28161d 295 LoRaMacUplinkStatus.Acked,
dudmuck 11:018e7e28161d 296 LoRaMacUplinkStatus.Datarate,
dudmuck 11:018e7e28161d 297 LoRaMacUplinkStatus.UplinkCounter,
dudmuck 11:018e7e28161d 298 LoRaMacUplinkStatus.Port,
dudmuck 11:018e7e28161d 299 LoRaMacUplinkStatus.Buffer,
dudmuck 11:018e7e28161d 300 LoRaMacUplinkStatus.BufferSize
dudmuck 11:018e7e28161d 301 );
dudmuck 11:018e7e28161d 302 return false;
dudmuck 11:018e7e28161d 303 }
dudmuck 11:018e7e28161d 304 LoRaMacStatus_toString(status, str);
dudmuck 11:018e7e28161d 305 vt.SetCursorPos( 44, 1 );
dudmuck 11:018e7e28161d 306 vt.printf("%u sendFrame() %s\e[K", sendCnt, str);
dudmuck 11:018e7e28161d 307 return true;
Wayne Roberts 12:662ff73ce484 308 } // ..SendFrame()
Wayne Roberts 12:662ff73ce484 309
Wayne Roberts 12:662ff73ce484 310 TimerEvent_t event;
Wayne Roberts 12:662ff73ce484 311 #define TX_INTERVAL_MS 15000
Wayne Roberts 12:662ff73ce484 312 void autoUplink()
Wayne Roberts 12:662ff73ce484 313 {
Wayne Roberts 12:662ff73ce484 314 DeviceState = DEVICE_STATE_SEND;
dudmuck 11:018e7e28161d 315 }
dudmuck 11:018e7e28161d 316
Wayne Roberts 12:662ff73ce484 317 char statusTxt[64];
Wayne Roberts 12:662ff73ce484 318
dudmuck 10:52810ecbd83b 319 uint8_t c_ch;
dudmuck 10:52810ecbd83b 320
mluis 0:45496a70a8a5 321 void SerialRxProcess( void )
mluis 0:45496a70a8a5 322 {
dudmuck 11:018e7e28161d 323 LoRaMacStatus_t status;
dudmuck 11:018e7e28161d 324 MlmeReq_t mlmeReq;
dudmuck 11:018e7e28161d 325
dudmuck 10:52810ecbd83b 326 if( SerialDisplayReadable( ) == true ) {
dudmuck 10:52810ecbd83b 327 char ch = SerialDisplayGetChar();
dudmuck 11:018e7e28161d 328 if ( ch >= '0' && ch <= '9') {
dudmuck 10:52810ecbd83b 329 c_ch = ch - '0';
dudmuck 10:52810ecbd83b 330 DeviceState = DEVICE_STATE_SEND;
dudmuck 10:52810ecbd83b 331 return;
dudmuck 10:52810ecbd83b 332 }
dudmuck 10:52810ecbd83b 333 switch( ch ) {
mluis 0:45496a70a8a5 334 case 'R':
mluis 0:45496a70a8a5 335 case 'r':
mluis 0:45496a70a8a5 336 // Refresh Serial screen
mluis 0:45496a70a8a5 337 SerialDisplayRefresh( );
mluis 0:45496a70a8a5 338 break;
dudmuck 11:018e7e28161d 339 case 'L':
dudmuck 11:018e7e28161d 340 mlmeReq.Type = MLME_LINK_CHECK;
dudmuck 11:018e7e28161d 341 status = LoRaMacMlmeRequest( &mlmeReq );
dudmuck 11:018e7e28161d 342 if (status == LORAMAC_STATUS_OK)
dudmuck 11:018e7e28161d 343 SendFrame(0, false);
dudmuck 11:018e7e28161d 344 break;
Wayne Roberts 12:662ff73ce484 345 case 'j':
Wayne Roberts 12:662ff73ce484 346 DeviceState = DEVICE_STATE_JOIN;
Wayne Roberts 12:662ff73ce484 347 break;
Wayne Roberts 12:662ff73ce484 348 case 'u':
Wayne Roberts 12:662ff73ce484 349 TimerInit(&event, autoUplink);
Wayne Roberts 12:662ff73ce484 350 TimerSetValue(&event, TX_INTERVAL_MS);
Wayne Roberts 12:662ff73ce484 351 TimerStart(&event);
Wayne Roberts 12:662ff73ce484 352 sprintf(statusTxt, "timer on %u", TX_INTERVAL_MS);
mluis 0:45496a70a8a5 353 default:
mluis 0:45496a70a8a5 354 break;
mluis 0:45496a70a8a5 355 }
mluis 0:45496a70a8a5 356 }
mluis 0:45496a70a8a5 357 }
mluis 0:45496a70a8a5 358
dudmuck 10:52810ecbd83b 359 #define LPP_DIGITAL_INPUT 0 // 1 byte
dudmuck 10:52810ecbd83b 360 #define LPP_DIGITAL_OUTPUT 1 // 1 byte
dudmuck 10:52810ecbd83b 361 #define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed
dudmuck 10:52810ecbd83b 362 #define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed
dudmuck 10:52810ecbd83b 363 #define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned
dudmuck 10:52810ecbd83b 364 #define LPP_PRESENCE 102 // 1 byte, 1
dudmuck 10:52810ecbd83b 365 #define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed
dudmuck 10:52810ecbd83b 366 #define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned
dudmuck 10:52810ecbd83b 367 #define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G
dudmuck 10:52810ecbd83b 368 #define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned
dudmuck 10:52810ecbd83b 369 #define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s
dudmuck 10:52810ecbd83b 370 #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m
dudmuck 10:52810ecbd83b 371
dudmuck 10:52810ecbd83b 372
dudmuck 10:52810ecbd83b 373 // Data ID + Data Type + Data Size
dudmuck 10:52810ecbd83b 374 #define LPP_DIGITAL_INPUT_SIZE 3
dudmuck 10:52810ecbd83b 375 #define LPP_DIGITAL_OUTPUT_SIZE 3
dudmuck 10:52810ecbd83b 376 #define LPP_ANALOG_INPUT_SIZE 4
dudmuck 10:52810ecbd83b 377 #define LPP_ANALOG_OUTPUT_SIZE 4
dudmuck 10:52810ecbd83b 378 #define LPP_LUMINOSITY_SIZE 4
dudmuck 10:52810ecbd83b 379 #define LPP_PRESENCE_SIZE 3
dudmuck 10:52810ecbd83b 380 #define LPP_TEMPERATURE_SIZE 4
dudmuck 10:52810ecbd83b 381 #define LPP_RELATIVE_HUMIDITY_SIZE 3
dudmuck 10:52810ecbd83b 382 #define LPP_ACCELEROMETER_SIZE 8
dudmuck 10:52810ecbd83b 383 #define LPP_BAROMETRIC_PRESSURE_SIZE 4
dudmuck 10:52810ecbd83b 384 #define LPP_GYROMETER_SIZE 8
dudmuck 10:52810ecbd83b 385 #define LPP_GPS_SIZE 11
dudmuck 10:52810ecbd83b 386
dudmuck 10:52810ecbd83b 387 #define CAYENNE_CH_DOUT 2
dudmuck 10:52810ecbd83b 388 #define CAYENNE_CH_AOUT 3
dudmuck 10:52810ecbd83b 389 #define CAYENNE_CH_TEMP 0
dudmuck 10:52810ecbd83b 390 #define CAYENNE_CH_POT 1
dudmuck 10:52810ecbd83b 391 AnalogIn a1(A1);
dudmuck 10:52810ecbd83b 392 AnalogIn a2(A2);
dudmuck 10:52810ecbd83b 393 AnalogIn a3(A3);
dudmuck 10:52810ecbd83b 394 AnalogIn a4(A4);
dudmuck 10:52810ecbd83b 395
dudmuck 10:52810ecbd83b 396 const unsigned R0 = 100000;
dudmuck 10:52810ecbd83b 397 const unsigned B = 4275;
dudmuck 10:52810ecbd83b 398
dudmuck 11:018e7e28161d 399
dudmuck 10:52810ecbd83b 400 volatile TimerTime_t buttonStartAt;
dudmuck 10:52810ecbd83b 401 DigitalIn d8(D8);
Wayne Roberts 12:662ff73ce484 402 DigitalIn userBut(USER_BUTTON);
dudmuck 10:52810ecbd83b 403 DigitalOut extLed(D15);
dudmuck 10:52810ecbd83b 404 PwmOut pwm(PB_11);
dudmuck 10:52810ecbd83b 405 volatile int cayenne_ack_ch;
mluis 0:45496a70a8a5 406 /*!
mluis 0:45496a70a8a5 407 * \brief Prepares the payload of the frame
mluis 0:45496a70a8a5 408 */
mluis 0:45496a70a8a5 409 static void PrepareTxFrame( uint8_t port )
mluis 0:45496a70a8a5 410 {
dudmuck 10:52810ecbd83b 411 uint16_t u16, rot;
dudmuck 10:52810ecbd83b 412 float t, f, R;
dudmuck 10:52810ecbd83b 413
dudmuck 10:52810ecbd83b 414 if (c_ch != 0xff) {
dudmuck 11:018e7e28161d 415 gAppDataSize = 0;
dudmuck 11:018e7e28161d 416 AppData[gAppDataSize++] = c_ch;
dudmuck 10:52810ecbd83b 417 switch (c_ch) {
dudmuck 10:52810ecbd83b 418 case CAYENNE_CH_TEMP:
dudmuck 11:018e7e28161d 419 AppData[gAppDataSize++] = LPP_TEMPERATURE;
dudmuck 11:018e7e28161d 420 u16 = a3.read_u16() >> 4;
dudmuck 11:018e7e28161d 421 R = 4096.0 / u16 - 1.0;
dudmuck 10:52810ecbd83b 422 R = R0 * R;
dudmuck 10:52810ecbd83b 423 t = 1.0/(log(R/R0)/B+1/298.15)-273.15;
dudmuck 10:52810ecbd83b 424 u16 = t * 10; // 0.1C per bit
dudmuck 11:018e7e28161d 425 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 426 AppData[gAppDataSize++] = u16;
dudmuck 10:52810ecbd83b 427 break;
dudmuck 10:52810ecbd83b 428 case CAYENNE_CH_POT:
dudmuck 11:018e7e28161d 429 AppData[gAppDataSize++] = LPP_ANALOG_INPUT;
dudmuck 10:52810ecbd83b 430 u16 = a1.read_u16(); // pot (rotary angle)
dudmuck 10:52810ecbd83b 431 f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit
dudmuck 10:52810ecbd83b 432 rot = (uint16_t) f;
dudmuck 11:018e7e28161d 433 AppData[gAppDataSize++] = rot >> 8;
dudmuck 11:018e7e28161d 434 AppData[gAppDataSize++] = rot;
dudmuck 10:52810ecbd83b 435 break;
dudmuck 10:52810ecbd83b 436 case CAYENNE_CH_DOUT:
dudmuck 11:018e7e28161d 437 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 438 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 439 break;
dudmuck 10:52810ecbd83b 440 case CAYENNE_CH_AOUT:
dudmuck 11:018e7e28161d 441 AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT;
dudmuck 10:52810ecbd83b 442 u16 = pwm.read() * 100;
dudmuck 11:018e7e28161d 443 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 444 AppData[gAppDataSize++] = u16;
dudmuck 10:52810ecbd83b 445 break;
GregCr 2:48d8d4806d48 446 }
dudmuck 10:52810ecbd83b 447 return;
dudmuck 10:52810ecbd83b 448 } else if (cayenne_ack_ch != -1) {
dudmuck 10:52810ecbd83b 449 switch (cayenne_ack_ch) {
dudmuck 10:52810ecbd83b 450 case CAYENNE_CH_DOUT:
dudmuck 11:018e7e28161d 451 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 452 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 453 break;
dudmuck 10:52810ecbd83b 454 case CAYENNE_CH_AOUT:
dudmuck 11:018e7e28161d 455 AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT;
dudmuck 10:52810ecbd83b 456 u16 = pwm.read() * 100;
dudmuck 11:018e7e28161d 457 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 458 AppData[gAppDataSize++] = u16;
dudmuck 10:52810ecbd83b 459 break;
mluis 0:45496a70a8a5 460 }
dudmuck 10:52810ecbd83b 461 cayenne_ack_ch = -1;
dudmuck 10:52810ecbd83b 462 }
dudmuck 10:52810ecbd83b 463
dudmuck 10:52810ecbd83b 464 while (d8.read() == 1) {
dudmuck 10:52810ecbd83b 465 TimerTime_t duration = TimerGetCurrentTime() - buttonStartAt;
dudmuck 10:52810ecbd83b 466 vt.SetCursorPos( 41, 1 );
dudmuck 10:52810ecbd83b 467 if (duration > 1000) {
dudmuck 11:018e7e28161d 468 gAppDataSize = 0;
dudmuck 11:018e7e28161d 469 AppData[gAppDataSize++] = CAYENNE_CH_DOUT;
dudmuck 11:018e7e28161d 470 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 471 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 472 vt.printf("send outputs ", duration);
dudmuck 10:52810ecbd83b 473 return;
dudmuck 10:52810ecbd83b 474 } else
dudmuck 10:52810ecbd83b 475 vt.printf("dur %u ", duration);
dudmuck 10:52810ecbd83b 476 }
dudmuck 10:52810ecbd83b 477
dudmuck 10:52810ecbd83b 478 switch( port ) {
dudmuck 10:52810ecbd83b 479 case LORAWAN_APP_PORT:
dudmuck 11:018e7e28161d 480 gAppDataSize = 0;
dudmuck 11:018e7e28161d 481 AppData[gAppDataSize++] = CAYENNE_CH_TEMP;
dudmuck 11:018e7e28161d 482 AppData[gAppDataSize++] = LPP_TEMPERATURE;
dudmuck 11:018e7e28161d 483 u16 = a3.read_u16() >> 4;
dudmuck 11:018e7e28161d 484 R = 4096.0 / u16 - 1.0;
dudmuck 10:52810ecbd83b 485 R = R0 * R;
dudmuck 10:52810ecbd83b 486 t = 1.0/(log(R/R0)/B+1/298.15)-273.15;
dudmuck 10:52810ecbd83b 487 u16 = t * 10; // 0.1C per bit
dudmuck 11:018e7e28161d 488 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 489 AppData[gAppDataSize++] = u16;
dudmuck 11:018e7e28161d 490 AppData[gAppDataSize++] = CAYENNE_CH_POT;
dudmuck 11:018e7e28161d 491 AppData[gAppDataSize++] = LPP_ANALOG_INPUT;
dudmuck 10:52810ecbd83b 492 u16 = a1.read_u16(); // pot (rotary angle)
dudmuck 10:52810ecbd83b 493 f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit
dudmuck 10:52810ecbd83b 494 rot = (uint16_t) f;
dudmuck 11:018e7e28161d 495 AppData[gAppDataSize++] = rot >> 8;
dudmuck 11:018e7e28161d 496 AppData[gAppDataSize++] = rot;
dudmuck 10:52810ecbd83b 497
dudmuck 11:018e7e28161d 498 AppData[gAppDataSize++] = CAYENNE_CH_DOUT;
dudmuck 11:018e7e28161d 499 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 500 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 501 vt.SetCursorPos( 41, 1 );
dudmuck 10:52810ecbd83b 502 vt.printf("u16:%u, f:%f, rot:%u t:%.1f\e[K", u16, f, rot, t);
dudmuck 10:52810ecbd83b 503 break;
dudmuck 10:52810ecbd83b 504 case 224:
dudmuck 10:52810ecbd83b 505 if( ComplianceTest.LinkCheck == true ) {
dudmuck 10:52810ecbd83b 506 ComplianceTest.LinkCheck = false;
dudmuck 11:018e7e28161d 507 gAppDataSize = 3;
dudmuck 10:52810ecbd83b 508 AppData[0] = 5;
dudmuck 10:52810ecbd83b 509 AppData[1] = ComplianceTest.DemodMargin;
dudmuck 10:52810ecbd83b 510 AppData[2] = ComplianceTest.NbGateways;
mluis 0:45496a70a8a5 511 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 512 } else {
dudmuck 10:52810ecbd83b 513 switch( ComplianceTest.State ) {
dudmuck 10:52810ecbd83b 514 case 4:
dudmuck 10:52810ecbd83b 515 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 516 break;
dudmuck 10:52810ecbd83b 517 case 1:
dudmuck 11:018e7e28161d 518 gAppDataSize = 2;
dudmuck 10:52810ecbd83b 519 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
dudmuck 10:52810ecbd83b 520 AppData[1] = ComplianceTest.DownLinkCounter;
dudmuck 10:52810ecbd83b 521 break;
dudmuck 10:52810ecbd83b 522 }
mluis 0:45496a70a8a5 523 }
dudmuck 10:52810ecbd83b 524 break;
dudmuck 10:52810ecbd83b 525 default:
dudmuck 10:52810ecbd83b 526 break;
mluis 0:45496a70a8a5 527 }
Wayne Roberts 12:662ff73ce484 528 } // ..PrepareTxFrame()
mluis 0:45496a70a8a5 529
mluis 0:45496a70a8a5 530
dudmuck 10:52810ecbd83b 531 void LoRaMacEventInfoStatus_toString(LoRaMacEventInfoStatus_t s, char* out)
mluis 0:45496a70a8a5 532 {
dudmuck 10:52810ecbd83b 533 switch (s) {
dudmuck 10:52810ecbd83b 534 case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
dudmuck 10:52810ecbd83b 535 strcpy(out, "JOIN_FAIL");
dudmuck 10:52810ecbd83b 536 break;
dudmuck 10:52810ecbd83b 537 case LORAMAC_EVENT_INFO_STATUS_ERROR:
dudmuck 10:52810ecbd83b 538 strcpy(out, "ERROR");
dudmuck 10:52810ecbd83b 539 break;
dudmuck 10:52810ecbd83b 540 case LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT:
dudmuck 10:52810ecbd83b 541 strcpy(out, "RX2_TIMEOUT");
dudmuck 10:52810ecbd83b 542 break;
dudmuck 10:52810ecbd83b 543 case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
dudmuck 10:52810ecbd83b 544 strcpy(out, "ADDRESS_FAIL");
dudmuck 10:52810ecbd83b 545 break;
dudmuck 10:52810ecbd83b 546 case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS:
dudmuck 10:52810ecbd83b 547 strcpy(out, "FRAMES_LOSS");
dudmuck 10:52810ecbd83b 548 break;
dudmuck 10:52810ecbd83b 549 case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED:
dudmuck 10:52810ecbd83b 550 strcpy(out, "DOWNLINK_REPEATED");
dudmuck 10:52810ecbd83b 551 break; // confirmed downlink retry?
dudmuck 10:52810ecbd83b 552 case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
dudmuck 10:52810ecbd83b 553 strcpy(out, "MIC_FAIL");
dudmuck 10:52810ecbd83b 554 break;
dudmuck 10:52810ecbd83b 555 case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
dudmuck 10:52810ecbd83b 556 strcpy(out, "TX_TIMEOUT");
dudmuck 10:52810ecbd83b 557 break;
dudmuck 10:52810ecbd83b 558 case LORAMAC_EVENT_INFO_STATUS_RX1_ERROR:
dudmuck 10:52810ecbd83b 559 strcpy(out, "RX1_ERROR");
dudmuck 10:52810ecbd83b 560 break;
dudmuck 10:52810ecbd83b 561 case LORAMAC_EVENT_INFO_STATUS_RX2_ERROR:
dudmuck 10:52810ecbd83b 562 strcpy(out, "RX2_ERROR");
dudmuck 10:52810ecbd83b 563 break;
dudmuck 10:52810ecbd83b 564 case LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR:
dudmuck 10:52810ecbd83b 565 strcpy(out, "SIZE");
dudmuck 10:52810ecbd83b 566 break;
mluis 0:45496a70a8a5 567
mluis 0:45496a70a8a5 568
dudmuck 10:52810ecbd83b 569 default:
dudmuck 10:52810ecbd83b 570 sprintf(out, "<%d>", s);
dudmuck 10:52810ecbd83b 571 break;
dudmuck 10:52810ecbd83b 572 }
GregCr 3:d4142832d5af 573 }
GregCr 3:d4142832d5af 574
Wayne Roberts 12:662ff73ce484 575
GregCr 3:d4142832d5af 576 /*!
mluis 0:45496a70a8a5 577 * \brief MCPS-Confirm event function
mluis 0:45496a70a8a5 578 *
mluis 5:fa113b25f612 579 * \param [IN] mcpsConfirm - Pointer to the confirm structure,
mluis 0:45496a70a8a5 580 * containing confirm attributes.
mluis 0:45496a70a8a5 581 */
mluis 5:fa113b25f612 582 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
mluis 0:45496a70a8a5 583 {
dudmuck 10:52810ecbd83b 584 if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
dudmuck 10:52810ecbd83b 585 switch( mcpsConfirm->McpsRequest ) {
dudmuck 10:52810ecbd83b 586 case MCPS_UNCONFIRMED: {
mluis 0:45496a70a8a5 587 // Check Datarate
mluis 0:45496a70a8a5 588 // Check TxPower
mluis 0:45496a70a8a5 589 break;
mluis 0:45496a70a8a5 590 }
dudmuck 10:52810ecbd83b 591 case MCPS_CONFIRMED: {
mluis 0:45496a70a8a5 592 // Check Datarate
mluis 0:45496a70a8a5 593 // Check TxPower
mluis 0:45496a70a8a5 594 // Check AckReceived
mluis 5:fa113b25f612 595 // Check NbTrials
mluis 5:fa113b25f612 596 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
mluis 0:45496a70a8a5 597 break;
mluis 0:45496a70a8a5 598 }
dudmuck 10:52810ecbd83b 599 case MCPS_PROPRIETARY: {
mluis 0:45496a70a8a5 600 break;
mluis 0:45496a70a8a5 601 }
mluis 0:45496a70a8a5 602 default:
mluis 0:45496a70a8a5 603 break;
mluis 0:45496a70a8a5 604 }
mluis 5:fa113b25f612 605 LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
mluis 5:fa113b25f612 606 LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
dudmuck 10:52810ecbd83b 607 } else {
dudmuck 10:52810ecbd83b 608 char str[48];
dudmuck 10:52810ecbd83b 609 LoRaMacEventInfoStatus_toString(mcpsConfirm->Status, str);
Wayne Roberts 12:662ff73ce484 610 strcpy(statusTxt, "mcpsConf ");
Wayne Roberts 12:662ff73ce484 611 strcat(statusTxt, str);
mluis 5:fa113b25f612 612
dudmuck 10:52810ecbd83b 613 }
mluis 7:ceb4063e6863 614
dudmuck 10:52810ecbd83b 615 DeviceState = DEVICE_STATE_TRIGGER;
Wayne Roberts 12:662ff73ce484 616 } // ..McpsConfirm()
dudmuck 10:52810ecbd83b 617
mluis 0:45496a70a8a5 618 /*!
mluis 0:45496a70a8a5 619 * \brief MCPS-Indication event function
mluis 0:45496a70a8a5 620 *
mluis 5:fa113b25f612 621 * \param [IN] mcpsIndication - Pointer to the indication structure,
mluis 0:45496a70a8a5 622 * containing indication attributes.
mluis 0:45496a70a8a5 623 */
mluis 5:fa113b25f612 624 static void McpsIndication( McpsIndication_t *mcpsIndication )
mluis 0:45496a70a8a5 625 {
dudmuck 10:52810ecbd83b 626 if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) {
dudmuck 10:52810ecbd83b 627 char str[48];
dudmuck 10:52810ecbd83b 628 LoRaMacEventInfoStatus_toString(mcpsIndication->Status, str);
Wayne Roberts 12:662ff73ce484 629 strcpy(statusTxt, "mcpsInd ");
Wayne Roberts 12:662ff73ce484 630 strcat(statusTxt, str);
mluis 0:45496a70a8a5 631 return;
mluis 0:45496a70a8a5 632 }
mluis 0:45496a70a8a5 633
dudmuck 10:52810ecbd83b 634 switch( mcpsIndication->McpsIndication ) {
dudmuck 10:52810ecbd83b 635 case MCPS_UNCONFIRMED: {
mluis 0:45496a70a8a5 636 break;
mluis 0:45496a70a8a5 637 }
dudmuck 10:52810ecbd83b 638 case MCPS_CONFIRMED: {
mluis 0:45496a70a8a5 639 break;
mluis 0:45496a70a8a5 640 }
dudmuck 10:52810ecbd83b 641 case MCPS_PROPRIETARY: {
mluis 0:45496a70a8a5 642 break;
mluis 0:45496a70a8a5 643 }
dudmuck 10:52810ecbd83b 644 case MCPS_MULTICAST: {
mluis 0:45496a70a8a5 645 break;
mluis 0:45496a70a8a5 646 }
mluis 0:45496a70a8a5 647 default:
mluis 0:45496a70a8a5 648 break;
mluis 0:45496a70a8a5 649 }
mluis 0:45496a70a8a5 650
mluis 0:45496a70a8a5 651 // Check Multicast
mluis 0:45496a70a8a5 652 // Check Port
mluis 0:45496a70a8a5 653 // Check Datarate
mluis 0:45496a70a8a5 654 // Check FramePending
mluis 0:45496a70a8a5 655 // Check Buffer
mluis 0:45496a70a8a5 656 // Check BufferSize
mluis 0:45496a70a8a5 657 // Check Rssi
mluis 0:45496a70a8a5 658 // Check Snr
mluis 0:45496a70a8a5 659 // Check RxSlot
mluis 5:fa113b25f612 660 LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
dudmuck 10:52810ecbd83b 661 if( mcpsIndication->Snr & 0x80 ) { // The SNR sign bit is 1
mluis 0:45496a70a8a5 662 // Invert and divide by 4
mluis 5:fa113b25f612 663 LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
mluis 0:45496a70a8a5 664 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
dudmuck 10:52810ecbd83b 665 } else {
mluis 0:45496a70a8a5 666 // Divide by 4
mluis 5:fa113b25f612 667 LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
mluis 0:45496a70a8a5 668 }
mluis 0:45496a70a8a5 669 LoRaMacDownlinkStatus.DownlinkCounter++;
mluis 5:fa113b25f612 670 LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
mluis 5:fa113b25f612 671 LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
mluis 5:fa113b25f612 672 LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
mluis 5:fa113b25f612 673 LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
mluis 0:45496a70a8a5 674
dudmuck 10:52810ecbd83b 675 if( ComplianceTest.Running == true ) {
mluis 0:45496a70a8a5 676 ComplianceTest.DownLinkCounter++;
mluis 0:45496a70a8a5 677 }
mluis 0:45496a70a8a5 678
dudmuck 10:52810ecbd83b 679 if( mcpsIndication->RxData == true ) {
dudmuck 10:52810ecbd83b 680 unsigned n;
dudmuck 10:52810ecbd83b 681 for (n = 0; n < mcpsIndication->BufferSize; n += 4) {
dudmuck 10:52810ecbd83b 682 uint16_t val = mcpsIndication->Buffer[n+1] << 8;
dudmuck 10:52810ecbd83b 683 val += mcpsIndication->Buffer[n+2];
dudmuck 10:52810ecbd83b 684 cayenne_ack_ch = mcpsIndication->Buffer[n];
dudmuck 10:52810ecbd83b 685 switch (mcpsIndication->Buffer[n]) {
dudmuck 10:52810ecbd83b 686 case CAYENNE_CH_DOUT:
dudmuck 10:52810ecbd83b 687 extLed.write(val);
dudmuck 10:52810ecbd83b 688 break;
dudmuck 10:52810ecbd83b 689 case CAYENNE_CH_AOUT:
dudmuck 10:52810ecbd83b 690 pwm.write(val / 100.0);
dudmuck 10:52810ecbd83b 691 break;
dudmuck 10:52810ecbd83b 692 default:
dudmuck 10:52810ecbd83b 693 break;
GregCr 2:48d8d4806d48 694 }
dudmuck 10:52810ecbd83b 695 }
mluis 9:0083afd69815 696
dudmuck 10:52810ecbd83b 697 switch( mcpsIndication->Port ) {
dudmuck 10:52810ecbd83b 698 case 1: // The application LED can be controlled on port 1 or 2
dudmuck 10:52810ecbd83b 699 case 2:
dudmuck 10:52810ecbd83b 700 if( mcpsIndication->BufferSize == 1 ) {
dudmuck 10:52810ecbd83b 701 //AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
dudmuck 10:52810ecbd83b 702 //Led3StateChanged = true;
mluis 0:45496a70a8a5 703 }
dudmuck 10:52810ecbd83b 704 break;
dudmuck 10:52810ecbd83b 705 case 224:
dudmuck 10:52810ecbd83b 706 if( ComplianceTest.Running == false ) {
dudmuck 10:52810ecbd83b 707 // Check compliance test enable command (i)
dudmuck 10:52810ecbd83b 708 if( ( mcpsIndication->BufferSize == 4 ) &&
dudmuck 10:52810ecbd83b 709 ( mcpsIndication->Buffer[0] == 0x01 ) &&
dudmuck 10:52810ecbd83b 710 ( mcpsIndication->Buffer[1] == 0x01 ) &&
dudmuck 10:52810ecbd83b 711 ( mcpsIndication->Buffer[2] == 0x01 ) &&
dudmuck 10:52810ecbd83b 712 ( mcpsIndication->Buffer[3] == 0x01 ) ) {
dudmuck 11:018e7e28161d 713 gIsTxConfirmed = false;
dudmuck 10:52810ecbd83b 714 AppPort = 224;
dudmuck 11:018e7e28161d 715 gAppDataSize = 2;
mluis 9:0083afd69815 716 ComplianceTest.DownLinkCounter = 0;
dudmuck 10:52810ecbd83b 717 ComplianceTest.LinkCheck = false;
dudmuck 10:52810ecbd83b 718 ComplianceTest.DemodMargin = 0;
dudmuck 10:52810ecbd83b 719 ComplianceTest.NbGateways = 0;
dudmuck 10:52810ecbd83b 720 ComplianceTest.Running = true;
dudmuck 10:52810ecbd83b 721 ComplianceTest.State = 1;
mluis 9:0083afd69815 722
mluis 9:0083afd69815 723 MibRequestConfirm_t mibReq;
mluis 9:0083afd69815 724 mibReq.Type = MIB_ADR;
dudmuck 10:52810ecbd83b 725 mibReq.Param.AdrEnable = true;
mluis 9:0083afd69815 726 LoRaMacMibSetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 727
mluis 9:0083afd69815 728 #if defined( USE_BAND_868 )
dudmuck 10:52810ecbd83b 729 LoRaMacTestSetDutyCycleOn( false );
dudmuck 10:52810ecbd83b 730 #endif
dudmuck 10:52810ecbd83b 731 }
dudmuck 10:52810ecbd83b 732 } else {
dudmuck 10:52810ecbd83b 733 ComplianceTest.State = mcpsIndication->Buffer[0];
dudmuck 10:52810ecbd83b 734 switch( ComplianceTest.State ) {
dudmuck 10:52810ecbd83b 735 case 0: // Check compliance test disable command (ii)
dudmuck 11:018e7e28161d 736 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
dudmuck 10:52810ecbd83b 737 AppPort = LORAWAN_APP_PORT;
dudmuck 11:018e7e28161d 738 gAppDataSize = LORAWAN_APP_DATA_SIZE;
dudmuck 10:52810ecbd83b 739 ComplianceTest.DownLinkCounter = 0;
dudmuck 10:52810ecbd83b 740 ComplianceTest.Running = false;
dudmuck 10:52810ecbd83b 741
dudmuck 10:52810ecbd83b 742 MibRequestConfirm_t mibReq;
dudmuck 10:52810ecbd83b 743 mibReq.Type = MIB_ADR;
dudmuck 10:52810ecbd83b 744 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
dudmuck 10:52810ecbd83b 745 LoRaMacMibSetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 746 #if defined( USE_BAND_868 )
dudmuck 10:52810ecbd83b 747 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
dudmuck 10:52810ecbd83b 748 #endif
dudmuck 10:52810ecbd83b 749 break;
dudmuck 10:52810ecbd83b 750 case 1: // (iii, iv)
dudmuck 11:018e7e28161d 751 gAppDataSize = 2;
dudmuck 10:52810ecbd83b 752 break;
dudmuck 10:52810ecbd83b 753 case 2: // Enable confirmed messages (v)
dudmuck 11:018e7e28161d 754 gIsTxConfirmed = true;
dudmuck 10:52810ecbd83b 755 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 756 break;
dudmuck 10:52810ecbd83b 757 case 3: // Disable confirmed messages (vi)
dudmuck 11:018e7e28161d 758 gIsTxConfirmed = false;
dudmuck 10:52810ecbd83b 759 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 760 break;
dudmuck 10:52810ecbd83b 761 case 4: // (vii)
dudmuck 11:018e7e28161d 762 gAppDataSize = mcpsIndication->BufferSize;
dudmuck 10:52810ecbd83b 763
dudmuck 10:52810ecbd83b 764 AppData[0] = 4;
dudmuck 11:018e7e28161d 765 for( uint8_t i = 1; i < gAppDataSize; i++ ) {
dudmuck 10:52810ecbd83b 766 AppData[i] = mcpsIndication->Buffer[i] + 1;
dudmuck 10:52810ecbd83b 767 }
dudmuck 10:52810ecbd83b 768 break;
dudmuck 10:52810ecbd83b 769 case 5: { // (viii)
dudmuck 10:52810ecbd83b 770 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 771 mlmeReq.Type = MLME_LINK_CHECK;
dudmuck 10:52810ecbd83b 772 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 773 }
dudmuck 10:52810ecbd83b 774 break;
dudmuck 10:52810ecbd83b 775 case 6: { // (ix)
dudmuck 10:52810ecbd83b 776 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 777
dudmuck 10:52810ecbd83b 778 // Disable TestMode and revert back to normal operation
dudmuck 11:018e7e28161d 779 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
dudmuck 10:52810ecbd83b 780 AppPort = LORAWAN_APP_PORT;
dudmuck 11:018e7e28161d 781 gAppDataSize = LORAWAN_APP_DATA_SIZE;
dudmuck 10:52810ecbd83b 782 ComplianceTest.DownLinkCounter = 0;
dudmuck 10:52810ecbd83b 783 ComplianceTest.Running = false;
dudmuck 10:52810ecbd83b 784
dudmuck 10:52810ecbd83b 785 MibRequestConfirm_t mibReq;
dudmuck 10:52810ecbd83b 786 mibReq.Type = MIB_ADR;
dudmuck 10:52810ecbd83b 787 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
dudmuck 10:52810ecbd83b 788 LoRaMacMibSetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 789 #if defined( USE_BAND_868 )
dudmuck 10:52810ecbd83b 790 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 9:0083afd69815 791 #endif
mluis 9:0083afd69815 792
dudmuck 10:52810ecbd83b 793 mlmeReq.Type = MLME_JOIN;
mluis 7:ceb4063e6863 794
dudmuck 10:52810ecbd83b 795 mlmeReq.Req.Join.DevEui = DevEui;
dudmuck 10:52810ecbd83b 796 mlmeReq.Req.Join.AppEui = AppEui;
dudmuck 10:52810ecbd83b 797 mlmeReq.Req.Join.AppKey = AppKey;
dudmuck 10:52810ecbd83b 798 mlmeReq.Req.Join.NbTrials = 3;
dudmuck 10:52810ecbd83b 799
mluis 9:0083afd69815 800 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 801 DeviceState = DEVICE_STATE_SLEEP;
mluis 9:0083afd69815 802 }
dudmuck 10:52810ecbd83b 803 break;
dudmuck 10:52810ecbd83b 804 case 7: { // (x)
dudmuck 10:52810ecbd83b 805 if( mcpsIndication->BufferSize == 3 ) {
dudmuck 10:52810ecbd83b 806 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 807 mlmeReq.Type = MLME_TXCW;
dudmuck 10:52810ecbd83b 808 mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
dudmuck 10:52810ecbd83b 809 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 810 } else if( mcpsIndication->BufferSize == 7 ) {
dudmuck 10:52810ecbd83b 811 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 812 mlmeReq.Type = MLME_TXCW_1;
dudmuck 10:52810ecbd83b 813 mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
dudmuck 10:52810ecbd83b 814 mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100;
dudmuck 10:52810ecbd83b 815 mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
dudmuck 10:52810ecbd83b 816 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 817 }
dudmuck 10:52810ecbd83b 818 ComplianceTest.State = 1;
mluis 9:0083afd69815 819 }
dudmuck 10:52810ecbd83b 820 break;
dudmuck 10:52810ecbd83b 821 default:
dudmuck 10:52810ecbd83b 822 break;
mluis 9:0083afd69815 823 }
mluis 0:45496a70a8a5 824 }
dudmuck 10:52810ecbd83b 825 break;
dudmuck 10:52810ecbd83b 826 default:
dudmuck 10:52810ecbd83b 827 break;
mluis 0:45496a70a8a5 828 }
mluis 0:45496a70a8a5 829 }
mluis 0:45496a70a8a5 830
mluis 0:45496a70a8a5 831 DownlinkStatusUpdated = true;
mluis 0:45496a70a8a5 832 }
mluis 0:45496a70a8a5 833
dudmuck 10:52810ecbd83b 834
dudmuck 10:52810ecbd83b 835
mluis 0:45496a70a8a5 836 /*!
mluis 0:45496a70a8a5 837 * \brief MLME-Confirm event function
mluis 0:45496a70a8a5 838 *
mluis 5:fa113b25f612 839 * \param [IN] mlmeConfirm - Pointer to the confirm structure,
mluis 0:45496a70a8a5 840 * containing confirm attributes.
mluis 0:45496a70a8a5 841 */
mluis 5:fa113b25f612 842 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
mluis 0:45496a70a8a5 843 {
Wayne Roberts 12:662ff73ce484 844 char str[48];
Wayne Roberts 12:662ff73ce484 845
Wayne Roberts 12:662ff73ce484 846 strcpy(statusTxt, "MlmeConfirm() ");
Wayne Roberts 12:662ff73ce484 847
dudmuck 10:52810ecbd83b 848 switch( mlmeConfirm->MlmeRequest ) {
dudmuck 10:52810ecbd83b 849 case MLME_JOIN: {
Wayne Roberts 12:662ff73ce484 850 strcat(statusTxt, "MLME_JOIN ");
dudmuck 10:52810ecbd83b 851 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
Wayne Roberts 12:662ff73ce484 852 strcat(statusTxt, "OK");
dudmuck 10:52810ecbd83b 853 DeviceState = DEVICE_STATE_JOIN_OK;
dudmuck 10:52810ecbd83b 854 extLed = 0;
dudmuck 10:52810ecbd83b 855 } else {
dudmuck 10:52810ecbd83b 856 LoRaMacEventInfoStatus_toString(mlmeConfirm->Status, str);
Wayne Roberts 12:662ff73ce484 857 strcat(statusTxt, str);
mluis 9:0083afd69815 858 DeviceState = DEVICE_STATE_JOIN;
mluis 0:45496a70a8a5 859 }
mluis 9:0083afd69815 860 break;
mluis 9:0083afd69815 861 }
dudmuck 10:52810ecbd83b 862 case MLME_LINK_CHECK: {
Wayne Roberts 12:662ff73ce484 863 strcat(statusTxt, "MLME_LINK_CHECK ");
dudmuck 10:52810ecbd83b 864 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
Wayne Roberts 12:662ff73ce484 865 strcat(statusTxt, "OK");
mluis 0:45496a70a8a5 866 // Check DemodMargin
mluis 0:45496a70a8a5 867 // Check NbGateways
dudmuck 10:52810ecbd83b 868 if( ComplianceTest.Running == true ) {
mluis 0:45496a70a8a5 869 ComplianceTest.LinkCheck = true;
mluis 5:fa113b25f612 870 ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
mluis 5:fa113b25f612 871 ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
mluis 0:45496a70a8a5 872 }
mluis 0:45496a70a8a5 873 }
mluis 9:0083afd69815 874 break;
mluis 0:45496a70a8a5 875 }
mluis 9:0083afd69815 876 default:
Wayne Roberts 12:662ff73ce484 877 sprintf(str, "<%d>", mlmeConfirm->MlmeRequest);
Wayne Roberts 12:662ff73ce484 878 strcat(statusTxt, str);
mluis 9:0083afd69815 879 break;
mluis 0:45496a70a8a5 880 }
Wayne Roberts 12:662ff73ce484 881 } // ..MlmeConfirm()
dudmuck 10:52810ecbd83b 882
Wayne Roberts 12:662ff73ce484 883 void poll()
dudmuck 10:52810ecbd83b 884 {
dudmuck 11:018e7e28161d 885 float R, temp;
dudmuck 11:018e7e28161d 886 uint16_t u16;
Wayne Roberts 12:662ff73ce484 887 static unsigned prevBut = 1;
dudmuck 11:018e7e28161d 888
dudmuck 10:52810ecbd83b 889 vt.SetCursorPos( 43, 1 );
dudmuck 11:018e7e28161d 890
dudmuck 11:018e7e28161d 891 u16 = a3.read_u16() >> 4;
dudmuck 11:018e7e28161d 892 R = 4096.0 / u16 - 1.0;
dudmuck 11:018e7e28161d 893 R = R0 * R;
dudmuck 11:018e7e28161d 894 temp = 1.0/(log(R/R0)/B+1/298.15)-273.15;
dudmuck 11:018e7e28161d 895
Wayne Roberts 12:662ff73ce484 896 vt.printf("%u d8:%u,%u (%03x %03x %03x %03x) %.2fC\e[K", DeviceState,
Wayne Roberts 12:662ff73ce484 897 d8.read(), userBut.read(),
Wayne Roberts 12:662ff73ce484 898 a1.read_u16() >> 4, a2.read_u16() >> 4, a3.read_u16() >> 4, a4.read_u16(), temp);
Wayne Roberts 12:662ff73ce484 899
Wayne Roberts 12:662ff73ce484 900 if (statusTxt[0] != 0) {
Wayne Roberts 12:662ff73ce484 901 vt.SetCursorPos( 45, 1 );
Wayne Roberts 12:662ff73ce484 902 vt.printf("%s\e[K", statusTxt);
Wayne Roberts 12:662ff73ce484 903 statusTxt[0] = 0;
Wayne Roberts 12:662ff73ce484 904 }
Wayne Roberts 12:662ff73ce484 905
Wayne Roberts 12:662ff73ce484 906 if (prevBut == 0 && userBut.read() == 1) {
Wayne Roberts 12:662ff73ce484 907 /* user button release */
Wayne Roberts 12:662ff73ce484 908 TimerInit(&event, autoUplink);
Wayne Roberts 12:662ff73ce484 909 TimerSetValue(&event, TX_INTERVAL_MS);
Wayne Roberts 12:662ff73ce484 910 TimerStart(&event);
Wayne Roberts 12:662ff73ce484 911 sprintf(statusTxt, "timer on %u", TX_INTERVAL_MS);
Wayne Roberts 12:662ff73ce484 912 }
Wayne Roberts 12:662ff73ce484 913 prevBut = userBut.read();
mluis 0:45496a70a8a5 914 }
mluis 0:45496a70a8a5 915
dudmuck 10:52810ecbd83b 916 const LoRaMacPrimitives_t LoRaMacPrimitives = {
dudmuck 10:52810ecbd83b 917 McpsConfirm,
dudmuck 10:52810ecbd83b 918 McpsIndication,
dudmuck 10:52810ecbd83b 919 MlmeConfirm
dudmuck 10:52810ecbd83b 920
dudmuck 10:52810ecbd83b 921 };
dudmuck 10:52810ecbd83b 922 const LoRaMacCallback_t LoRaMacCallbacks = {
dudmuck 10:52810ecbd83b 923 BoardGetBatteryLevel
dudmuck 10:52810ecbd83b 924 };
dudmuck 10:52810ecbd83b 925
mluis 0:45496a70a8a5 926 /**
mluis 0:45496a70a8a5 927 * Main application entry point.
mluis 0:45496a70a8a5 928 */
mluis 0:45496a70a8a5 929 int main( void )
mluis 0:45496a70a8a5 930 {
mluis 0:45496a70a8a5 931 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 932
mluis 0:45496a70a8a5 933 BoardInit( );
mluis 0:45496a70a8a5 934 SerialDisplayInit( );
mluis 0:45496a70a8a5 935
mluis 7:ceb4063e6863 936 SerialDisplayUpdateEui( 5, DevEui );
mluis 7:ceb4063e6863 937 SerialDisplayUpdateEui( 6, AppEui );
mluis 7:ceb4063e6863 938 SerialDisplayUpdateKey( 7, AppKey );
mluis 7:ceb4063e6863 939
mluis 7:ceb4063e6863 940 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 7:ceb4063e6863 941 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 7:ceb4063e6863 942 SerialDisplayUpdateDevAddr( DevAddr );
mluis 7:ceb4063e6863 943 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 7:ceb4063e6863 944 SerialDisplayUpdateKey( 13, AppSKey );
mluis 7:ceb4063e6863 945 #endif
mluis 7:ceb4063e6863 946
mluis 0:45496a70a8a5 947 DeviceState = DEVICE_STATE_INIT;
mluis 0:45496a70a8a5 948
dudmuck 10:52810ecbd83b 949 while( 1 ) {
Wayne Roberts 12:662ff73ce484 950 poll();
mluis 0:45496a70a8a5 951 SerialRxProcess( );
dudmuck 10:52810ecbd83b 952
dudmuck 10:52810ecbd83b 953 if( DownlinkStatusUpdated == true ) {
mluis 0:45496a70a8a5 954 DownlinkStatusUpdated = false;
mluis 0:45496a70a8a5 955 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
mluis 0:45496a70a8a5 956 }
dudmuck 10:52810ecbd83b 957
dudmuck 10:52810ecbd83b 958 switch( DeviceState ) {
dudmuck 10:52810ecbd83b 959 case DEVICE_STATE_INIT: {
dudmuck 10:52810ecbd83b 960 pwm.period(1.0 / 60);
dudmuck 10:52810ecbd83b 961 cayenne_ack_ch = -1;
dudmuck 10:52810ecbd83b 962 c_ch = 0xff;
dudmuck 10:52810ecbd83b 963 d8.mode(PullDown);
dudmuck 10:52810ecbd83b 964
mluis 0:45496a70a8a5 965 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
mluis 0:45496a70a8a5 966
mluis 0:45496a70a8a5 967 mibReq.Type = MIB_ADR;
mluis 0:45496a70a8a5 968 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
mluis 0:45496a70a8a5 969 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 970
mluis 0:45496a70a8a5 971 mibReq.Type = MIB_PUBLIC_NETWORK;
mluis 0:45496a70a8a5 972 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
mluis 0:45496a70a8a5 973 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 974
mluis 0:45496a70a8a5 975 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 976 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 977 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 5:fa113b25f612 978
mluis 9:0083afd69815 979 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
mluis 5:fa113b25f612 980 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
mluis 5:fa113b25f612 981 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
mluis 5:fa113b25f612 982 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
mluis 5:fa113b25f612 983 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
mluis 5:fa113b25f612 984 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
mluis 5:fa113b25f612 985 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
mluis 5:fa113b25f612 986 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
mluis 7:ceb4063e6863 987
mluis 9:0083afd69815 988 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
dudmuck 10:52810ecbd83b 989 mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ) {
dudmuck 10:52810ecbd83b 990 869525000, DR_3
dudmuck 10:52810ecbd83b 991 };
mluis 9:0083afd69815 992 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 9:0083afd69815 993
mluis 7:ceb4063e6863 994 mibReq.Type = MIB_RX2_CHANNEL;
dudmuck 10:52810ecbd83b 995 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ) {
dudmuck 10:52810ecbd83b 996 869525000, DR_3
dudmuck 10:52810ecbd83b 997 };
mluis 7:ceb4063e6863 998 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 5:fa113b25f612 999 #endif
mluis 5:fa113b25f612 1000
mluis 0:45496a70a8a5 1001 #endif
mluis 0:45496a70a8a5 1002 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:45496a70a8a5 1003 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:45496a70a8a5 1004 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
mluis 0:45496a70a8a5 1005
mluis 0:45496a70a8a5 1006 LoRaMacDownlinkStatus.DownlinkCounter = 0;
mluis 0:45496a70a8a5 1007
mluis 0:45496a70a8a5 1008 DeviceState = DEVICE_STATE_JOIN;
mluis 0:45496a70a8a5 1009 break;
mluis 0:45496a70a8a5 1010 }
dudmuck 10:52810ecbd83b 1011 case DEVICE_STATE_JOIN: {
mluis 0:45496a70a8a5 1012 #if( OVER_THE_AIR_ACTIVATION != 0 )
dudmuck 10:52810ecbd83b 1013 LoRaMacStatus_t s;
mluis 0:45496a70a8a5 1014 MlmeReq_t mlmeReq;
mluis 0:45496a70a8a5 1015 mlmeReq.Type = MLME_JOIN;
mluis 0:45496a70a8a5 1016
mluis 0:45496a70a8a5 1017 mlmeReq.Req.Join.DevEui = DevEui;
mluis 0:45496a70a8a5 1018 mlmeReq.Req.Join.AppEui = AppEui;
mluis 0:45496a70a8a5 1019 mlmeReq.Req.Join.AppKey = AppKey;
Wayne Roberts 12:662ff73ce484 1020 mlmeReq.Req.Join.NbTrials = 1;
mluis 0:45496a70a8a5 1021
dudmuck 10:52810ecbd83b 1022 s = LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 1023 if (s != LORAMAC_STATUS_OK) {
dudmuck 10:52810ecbd83b 1024 char str[48];
dudmuck 10:52810ecbd83b 1025 LoRaMacStatus_toString(s, str);
dudmuck 10:52810ecbd83b 1026 vt.SetCursorPos( 44, 1 );
dudmuck 10:52810ecbd83b 1027 vt.printf("mlmeReq join %s\e[K", str);
Wayne Roberts 12:662ff73ce484 1028 }
Wayne Roberts 12:662ff73ce484 1029 DeviceState = DEVICE_STATE_SLEEP;
dudmuck 10:52810ecbd83b 1030
dudmuck 10:52810ecbd83b 1031 extLed = 1;
mluis 0:45496a70a8a5 1032 #else
mluis 0:45496a70a8a5 1033 mibReq.Type = MIB_NET_ID;
mluis 0:45496a70a8a5 1034 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
mluis 0:45496a70a8a5 1035 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1036
mluis 0:45496a70a8a5 1037 mibReq.Type = MIB_DEV_ADDR;
mluis 0:45496a70a8a5 1038 mibReq.Param.DevAddr = DevAddr;
mluis 0:45496a70a8a5 1039 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1040
mluis 0:45496a70a8a5 1041 mibReq.Type = MIB_NWK_SKEY;
mluis 0:45496a70a8a5 1042 mibReq.Param.NwkSKey = NwkSKey;
mluis 0:45496a70a8a5 1043 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1044
mluis 0:45496a70a8a5 1045 mibReq.Type = MIB_APP_SKEY;
mluis 0:45496a70a8a5 1046 mibReq.Param.AppSKey = AppSKey;
mluis 0:45496a70a8a5 1047 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1048
mluis 0:45496a70a8a5 1049 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 1050 mibReq.Param.IsNetworkJoined = true;
mluis 0:45496a70a8a5 1051 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1052 DeviceState = DEVICE_STATE_SEND;
mluis 0:45496a70a8a5 1053 #endif
mluis 0:45496a70a8a5 1054 break;
mluis 0:45496a70a8a5 1055 }
dudmuck 10:52810ecbd83b 1056 case DEVICE_STATE_JOIN_OK:
dudmuck 10:52810ecbd83b 1057 MibRequestConfirm_t mibReq;
dudmuck 10:52810ecbd83b 1058 mibReq.Type = MIB_NETWORK_JOINED;
dudmuck 10:52810ecbd83b 1059 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1060 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
dudmuck 10:52810ecbd83b 1061 mibReq.Type = MIB_DEV_ADDR;
dudmuck 10:52810ecbd83b 1062 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1063 SerialDisplayUpdateDevAddr(mibReq.Param.DevAddr);
dudmuck 10:52810ecbd83b 1064 mibReq.Type = MIB_NWK_SKEY;
dudmuck 10:52810ecbd83b 1065 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1066 SerialDisplayUpdateKey( 12, mibReq.Param.NwkSKey );
dudmuck 10:52810ecbd83b 1067 mibReq.Type = MIB_APP_SKEY;
dudmuck 10:52810ecbd83b 1068 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1069 SerialDisplayUpdateKey( 13, mibReq.Param.AppSKey );
dudmuck 10:52810ecbd83b 1070 //SerialDisplayUpdateNwkId( uint8_t id );
dudmuck 10:52810ecbd83b 1071 DeviceState = DEVICE_STATE_TRIGGER;
dudmuck 10:52810ecbd83b 1072 break;
dudmuck 10:52810ecbd83b 1073 case DEVICE_STATE_SEND: {
dudmuck 10:52810ecbd83b 1074 SerialDisplayUpdateUplinkAcked( false );
dudmuck 10:52810ecbd83b 1075 SerialDisplayUpdateDonwlinkRxData( false );
dudmuck 10:52810ecbd83b 1076 PrepareTxFrame( AppPort );
mluis 0:45496a70a8a5 1077
dudmuck 11:018e7e28161d 1078 SendFrame(gAppDataSize, gIsTxConfirmed);
dudmuck 10:52810ecbd83b 1079
dudmuck 10:52810ecbd83b 1080 DeviceState = DEVICE_STATE_SLEEP;
mluis 0:45496a70a8a5 1081 break;
mluis 0:45496a70a8a5 1082 }
dudmuck 10:52810ecbd83b 1083 case DEVICE_STATE_SLEEP: {
mluis 0:45496a70a8a5 1084 // Wake up through events
mluis 0:45496a70a8a5 1085 break;
mluis 0:45496a70a8a5 1086 }
dudmuck 10:52810ecbd83b 1087 case DEVICE_STATE_TRIGGER:
dudmuck 10:52810ecbd83b 1088 if (d8.read() == 1) {
dudmuck 10:52810ecbd83b 1089 c_ch = 0xff;
dudmuck 10:52810ecbd83b 1090 DeviceState = DEVICE_STATE_SEND;
dudmuck 10:52810ecbd83b 1091 buttonStartAt = TimerGetCurrentTime();
dudmuck 10:52810ecbd83b 1092 }
dudmuck 10:52810ecbd83b 1093 break;
Wayne Roberts 12:662ff73ce484 1094 default:
mluis 0:45496a70a8a5 1095 DeviceState = DEVICE_STATE_INIT;
mluis 0:45496a70a8a5 1096 break;
Wayne Roberts 12:662ff73ce484 1097
Wayne Roberts 12:662ff73ce484 1098 } // ..switch( DeviceState )
dudmuck 10:52810ecbd83b 1099
Wayne Roberts 12:662ff73ce484 1100 } // ..while( 1 )
mluis 0:45496a70a8a5 1101 }