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:
Wed Feb 14 14:03:42 2018 -0800
Revision:
13:f88dd77772b6
Parent:
12:662ff73ce484
Child:
14:f8c7c85fc8e8
replace user button with jumper

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 13:f88dd77772b6 310 char statusTxt[64];
Wayne Roberts 13:f88dd77772b6 311 DigitalOut jumper_out(PC_10);
Wayne Roberts 13:f88dd77772b6 312 InterruptIn jumper_in(PC_12);
Wayne Roberts 12:662ff73ce484 313 TimerEvent_t event;
Wayne Roberts 12:662ff73ce484 314 #define TX_INTERVAL_MS 15000
Wayne Roberts 12:662ff73ce484 315 void autoUplink()
Wayne Roberts 12:662ff73ce484 316 {
Wayne Roberts 13:f88dd77772b6 317 if (jumper_in.read())
Wayne Roberts 13:f88dd77772b6 318 DeviceState = DEVICE_STATE_SEND;
Wayne Roberts 13:f88dd77772b6 319 else {
Wayne Roberts 13:f88dd77772b6 320 TimerStop(&event);
Wayne Roberts 13:f88dd77772b6 321 sprintf(statusTxt, "timer off");
Wayne Roberts 13:f88dd77772b6 322 }
dudmuck 11:018e7e28161d 323 }
dudmuck 11:018e7e28161d 324
dudmuck 10:52810ecbd83b 325 uint8_t c_ch;
dudmuck 10:52810ecbd83b 326
mluis 0:45496a70a8a5 327 void SerialRxProcess( void )
mluis 0:45496a70a8a5 328 {
dudmuck 11:018e7e28161d 329 LoRaMacStatus_t status;
dudmuck 11:018e7e28161d 330 MlmeReq_t mlmeReq;
dudmuck 11:018e7e28161d 331
dudmuck 10:52810ecbd83b 332 if( SerialDisplayReadable( ) == true ) {
dudmuck 10:52810ecbd83b 333 char ch = SerialDisplayGetChar();
dudmuck 11:018e7e28161d 334 if ( ch >= '0' && ch <= '9') {
dudmuck 10:52810ecbd83b 335 c_ch = ch - '0';
dudmuck 10:52810ecbd83b 336 DeviceState = DEVICE_STATE_SEND;
dudmuck 10:52810ecbd83b 337 return;
dudmuck 10:52810ecbd83b 338 }
dudmuck 10:52810ecbd83b 339 switch( ch ) {
mluis 0:45496a70a8a5 340 case 'R':
mluis 0:45496a70a8a5 341 case 'r':
mluis 0:45496a70a8a5 342 // Refresh Serial screen
mluis 0:45496a70a8a5 343 SerialDisplayRefresh( );
mluis 0:45496a70a8a5 344 break;
dudmuck 11:018e7e28161d 345 case 'L':
dudmuck 11:018e7e28161d 346 mlmeReq.Type = MLME_LINK_CHECK;
dudmuck 11:018e7e28161d 347 status = LoRaMacMlmeRequest( &mlmeReq );
dudmuck 11:018e7e28161d 348 if (status == LORAMAC_STATUS_OK)
dudmuck 11:018e7e28161d 349 SendFrame(0, false);
dudmuck 11:018e7e28161d 350 break;
Wayne Roberts 12:662ff73ce484 351 case 'j':
Wayne Roberts 12:662ff73ce484 352 DeviceState = DEVICE_STATE_JOIN;
Wayne Roberts 12:662ff73ce484 353 break;
Wayne Roberts 12:662ff73ce484 354 case 'u':
Wayne Roberts 12:662ff73ce484 355 TimerInit(&event, autoUplink);
Wayne Roberts 12:662ff73ce484 356 TimerSetValue(&event, TX_INTERVAL_MS);
Wayne Roberts 12:662ff73ce484 357 TimerStart(&event);
Wayne Roberts 12:662ff73ce484 358 sprintf(statusTxt, "timer on %u", TX_INTERVAL_MS);
mluis 0:45496a70a8a5 359 default:
mluis 0:45496a70a8a5 360 break;
mluis 0:45496a70a8a5 361 }
mluis 0:45496a70a8a5 362 }
mluis 0:45496a70a8a5 363 }
mluis 0:45496a70a8a5 364
dudmuck 10:52810ecbd83b 365 #define LPP_DIGITAL_INPUT 0 // 1 byte
dudmuck 10:52810ecbd83b 366 #define LPP_DIGITAL_OUTPUT 1 // 1 byte
dudmuck 10:52810ecbd83b 367 #define LPP_ANALOG_INPUT 2 // 2 bytes, 0.01 signed
dudmuck 10:52810ecbd83b 368 #define LPP_ANALOG_OUTPUT 3 // 2 bytes, 0.01 signed
dudmuck 10:52810ecbd83b 369 #define LPP_LUMINOSITY 101 // 2 bytes, 1 lux unsigned
dudmuck 10:52810ecbd83b 370 #define LPP_PRESENCE 102 // 1 byte, 1
dudmuck 10:52810ecbd83b 371 #define LPP_TEMPERATURE 103 // 2 bytes, 0.1°C signed
dudmuck 10:52810ecbd83b 372 #define LPP_RELATIVE_HUMIDITY 104 // 1 byte, 0.5% unsigned
dudmuck 10:52810ecbd83b 373 #define LPP_ACCELEROMETER 113 // 2 bytes per axis, 0.001G
dudmuck 10:52810ecbd83b 374 #define LPP_BAROMETRIC_PRESSURE 115 // 2 bytes 0.1 hPa Unsigned
dudmuck 10:52810ecbd83b 375 #define LPP_GYROMETER 134 // 2 bytes per axis, 0.01 °/s
dudmuck 10:52810ecbd83b 376 #define LPP_GPS 136 // 3 byte lon/lat 0.0001 °, 3 bytes alt 0.01m
dudmuck 10:52810ecbd83b 377
dudmuck 10:52810ecbd83b 378
dudmuck 10:52810ecbd83b 379 // Data ID + Data Type + Data Size
dudmuck 10:52810ecbd83b 380 #define LPP_DIGITAL_INPUT_SIZE 3
dudmuck 10:52810ecbd83b 381 #define LPP_DIGITAL_OUTPUT_SIZE 3
dudmuck 10:52810ecbd83b 382 #define LPP_ANALOG_INPUT_SIZE 4
dudmuck 10:52810ecbd83b 383 #define LPP_ANALOG_OUTPUT_SIZE 4
dudmuck 10:52810ecbd83b 384 #define LPP_LUMINOSITY_SIZE 4
dudmuck 10:52810ecbd83b 385 #define LPP_PRESENCE_SIZE 3
dudmuck 10:52810ecbd83b 386 #define LPP_TEMPERATURE_SIZE 4
dudmuck 10:52810ecbd83b 387 #define LPP_RELATIVE_HUMIDITY_SIZE 3
dudmuck 10:52810ecbd83b 388 #define LPP_ACCELEROMETER_SIZE 8
dudmuck 10:52810ecbd83b 389 #define LPP_BAROMETRIC_PRESSURE_SIZE 4
dudmuck 10:52810ecbd83b 390 #define LPP_GYROMETER_SIZE 8
dudmuck 10:52810ecbd83b 391 #define LPP_GPS_SIZE 11
dudmuck 10:52810ecbd83b 392
dudmuck 10:52810ecbd83b 393 #define CAYENNE_CH_DOUT 2
dudmuck 10:52810ecbd83b 394 #define CAYENNE_CH_AOUT 3
dudmuck 10:52810ecbd83b 395 #define CAYENNE_CH_TEMP 0
dudmuck 10:52810ecbd83b 396 #define CAYENNE_CH_POT 1
dudmuck 10:52810ecbd83b 397 AnalogIn a1(A1);
dudmuck 10:52810ecbd83b 398 AnalogIn a2(A2);
dudmuck 10:52810ecbd83b 399 AnalogIn a3(A3);
dudmuck 10:52810ecbd83b 400 AnalogIn a4(A4);
dudmuck 10:52810ecbd83b 401
dudmuck 10:52810ecbd83b 402 const unsigned R0 = 100000;
dudmuck 10:52810ecbd83b 403 const unsigned B = 4275;
dudmuck 10:52810ecbd83b 404
dudmuck 11:018e7e28161d 405
dudmuck 10:52810ecbd83b 406 volatile TimerTime_t buttonStartAt;
dudmuck 10:52810ecbd83b 407 DigitalIn d8(D8);
dudmuck 10:52810ecbd83b 408 DigitalOut extLed(D15);
dudmuck 10:52810ecbd83b 409 PwmOut pwm(PB_11);
Wayne Roberts 13:f88dd77772b6 410
dudmuck 10:52810ecbd83b 411 volatile int cayenne_ack_ch;
mluis 0:45496a70a8a5 412 /*!
mluis 0:45496a70a8a5 413 * \brief Prepares the payload of the frame
mluis 0:45496a70a8a5 414 */
mluis 0:45496a70a8a5 415 static void PrepareTxFrame( uint8_t port )
mluis 0:45496a70a8a5 416 {
dudmuck 10:52810ecbd83b 417 uint16_t u16, rot;
dudmuck 10:52810ecbd83b 418 float t, f, R;
dudmuck 10:52810ecbd83b 419
dudmuck 10:52810ecbd83b 420 if (c_ch != 0xff) {
dudmuck 11:018e7e28161d 421 gAppDataSize = 0;
dudmuck 11:018e7e28161d 422 AppData[gAppDataSize++] = c_ch;
dudmuck 10:52810ecbd83b 423 switch (c_ch) {
dudmuck 10:52810ecbd83b 424 case CAYENNE_CH_TEMP:
dudmuck 11:018e7e28161d 425 AppData[gAppDataSize++] = LPP_TEMPERATURE;
dudmuck 11:018e7e28161d 426 u16 = a3.read_u16() >> 4;
dudmuck 11:018e7e28161d 427 R = 4096.0 / u16 - 1.0;
dudmuck 10:52810ecbd83b 428 R = R0 * R;
dudmuck 10:52810ecbd83b 429 t = 1.0/(log(R/R0)/B+1/298.15)-273.15;
dudmuck 10:52810ecbd83b 430 u16 = t * 10; // 0.1C per bit
dudmuck 11:018e7e28161d 431 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 432 AppData[gAppDataSize++] = u16;
dudmuck 10:52810ecbd83b 433 break;
dudmuck 10:52810ecbd83b 434 case CAYENNE_CH_POT:
dudmuck 11:018e7e28161d 435 AppData[gAppDataSize++] = LPP_ANALOG_INPUT;
dudmuck 10:52810ecbd83b 436 u16 = a1.read_u16(); // pot (rotary angle)
dudmuck 10:52810ecbd83b 437 f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit
dudmuck 10:52810ecbd83b 438 rot = (uint16_t) f;
dudmuck 11:018e7e28161d 439 AppData[gAppDataSize++] = rot >> 8;
dudmuck 11:018e7e28161d 440 AppData[gAppDataSize++] = rot;
dudmuck 10:52810ecbd83b 441 break;
dudmuck 10:52810ecbd83b 442 case CAYENNE_CH_DOUT:
dudmuck 11:018e7e28161d 443 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 444 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 445 break;
dudmuck 10:52810ecbd83b 446 case CAYENNE_CH_AOUT:
dudmuck 11:018e7e28161d 447 AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT;
dudmuck 10:52810ecbd83b 448 u16 = pwm.read() * 100;
dudmuck 11:018e7e28161d 449 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 450 AppData[gAppDataSize++] = u16;
dudmuck 10:52810ecbd83b 451 break;
GregCr 2:48d8d4806d48 452 }
dudmuck 10:52810ecbd83b 453 return;
dudmuck 10:52810ecbd83b 454 } else if (cayenne_ack_ch != -1) {
dudmuck 10:52810ecbd83b 455 switch (cayenne_ack_ch) {
dudmuck 10:52810ecbd83b 456 case CAYENNE_CH_DOUT:
dudmuck 11:018e7e28161d 457 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 458 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 459 break;
dudmuck 10:52810ecbd83b 460 case CAYENNE_CH_AOUT:
dudmuck 11:018e7e28161d 461 AppData[gAppDataSize++] = LPP_ANALOG_OUTPUT;
dudmuck 10:52810ecbd83b 462 u16 = pwm.read() * 100;
dudmuck 11:018e7e28161d 463 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 464 AppData[gAppDataSize++] = u16;
dudmuck 10:52810ecbd83b 465 break;
mluis 0:45496a70a8a5 466 }
dudmuck 10:52810ecbd83b 467 cayenne_ack_ch = -1;
dudmuck 10:52810ecbd83b 468 }
dudmuck 10:52810ecbd83b 469
dudmuck 10:52810ecbd83b 470 while (d8.read() == 1) {
dudmuck 10:52810ecbd83b 471 TimerTime_t duration = TimerGetCurrentTime() - buttonStartAt;
dudmuck 10:52810ecbd83b 472 vt.SetCursorPos( 41, 1 );
dudmuck 10:52810ecbd83b 473 if (duration > 1000) {
dudmuck 11:018e7e28161d 474 gAppDataSize = 0;
dudmuck 11:018e7e28161d 475 AppData[gAppDataSize++] = CAYENNE_CH_DOUT;
dudmuck 11:018e7e28161d 476 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 477 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 478 vt.printf("send outputs ", duration);
dudmuck 10:52810ecbd83b 479 return;
dudmuck 10:52810ecbd83b 480 } else
dudmuck 10:52810ecbd83b 481 vt.printf("dur %u ", duration);
dudmuck 10:52810ecbd83b 482 }
dudmuck 10:52810ecbd83b 483
dudmuck 10:52810ecbd83b 484 switch( port ) {
dudmuck 10:52810ecbd83b 485 case LORAWAN_APP_PORT:
dudmuck 11:018e7e28161d 486 gAppDataSize = 0;
dudmuck 11:018e7e28161d 487 AppData[gAppDataSize++] = CAYENNE_CH_TEMP;
dudmuck 11:018e7e28161d 488 AppData[gAppDataSize++] = LPP_TEMPERATURE;
dudmuck 11:018e7e28161d 489 u16 = a3.read_u16() >> 4;
dudmuck 11:018e7e28161d 490 R = 4096.0 / u16 - 1.0;
dudmuck 10:52810ecbd83b 491 R = R0 * R;
dudmuck 10:52810ecbd83b 492 t = 1.0/(log(R/R0)/B+1/298.15)-273.15;
dudmuck 10:52810ecbd83b 493 u16 = t * 10; // 0.1C per bit
dudmuck 11:018e7e28161d 494 AppData[gAppDataSize++] = u16 >> 8;
dudmuck 11:018e7e28161d 495 AppData[gAppDataSize++] = u16;
dudmuck 11:018e7e28161d 496 AppData[gAppDataSize++] = CAYENNE_CH_POT;
dudmuck 11:018e7e28161d 497 AppData[gAppDataSize++] = LPP_ANALOG_INPUT;
dudmuck 10:52810ecbd83b 498 u16 = a1.read_u16(); // pot (rotary angle)
dudmuck 10:52810ecbd83b 499 f = u16 / 198.6; // scale 65535/3.3 to 0.01v per bit
dudmuck 10:52810ecbd83b 500 rot = (uint16_t) f;
dudmuck 11:018e7e28161d 501 AppData[gAppDataSize++] = rot >> 8;
dudmuck 11:018e7e28161d 502 AppData[gAppDataSize++] = rot;
dudmuck 10:52810ecbd83b 503
dudmuck 11:018e7e28161d 504 AppData[gAppDataSize++] = CAYENNE_CH_DOUT;
dudmuck 11:018e7e28161d 505 AppData[gAppDataSize++] = LPP_DIGITAL_OUTPUT;
dudmuck 11:018e7e28161d 506 AppData[gAppDataSize++] = extLed.read();
dudmuck 10:52810ecbd83b 507 vt.SetCursorPos( 41, 1 );
dudmuck 10:52810ecbd83b 508 vt.printf("u16:%u, f:%f, rot:%u t:%.1f\e[K", u16, f, rot, t);
dudmuck 10:52810ecbd83b 509 break;
dudmuck 10:52810ecbd83b 510 case 224:
dudmuck 10:52810ecbd83b 511 if( ComplianceTest.LinkCheck == true ) {
dudmuck 10:52810ecbd83b 512 ComplianceTest.LinkCheck = false;
dudmuck 11:018e7e28161d 513 gAppDataSize = 3;
dudmuck 10:52810ecbd83b 514 AppData[0] = 5;
dudmuck 10:52810ecbd83b 515 AppData[1] = ComplianceTest.DemodMargin;
dudmuck 10:52810ecbd83b 516 AppData[2] = ComplianceTest.NbGateways;
mluis 0:45496a70a8a5 517 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 518 } else {
dudmuck 10:52810ecbd83b 519 switch( ComplianceTest.State ) {
dudmuck 10:52810ecbd83b 520 case 4:
dudmuck 10:52810ecbd83b 521 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 522 break;
dudmuck 10:52810ecbd83b 523 case 1:
dudmuck 11:018e7e28161d 524 gAppDataSize = 2;
dudmuck 10:52810ecbd83b 525 AppData[0] = ComplianceTest.DownLinkCounter >> 8;
dudmuck 10:52810ecbd83b 526 AppData[1] = ComplianceTest.DownLinkCounter;
dudmuck 10:52810ecbd83b 527 break;
dudmuck 10:52810ecbd83b 528 }
mluis 0:45496a70a8a5 529 }
dudmuck 10:52810ecbd83b 530 break;
dudmuck 10:52810ecbd83b 531 default:
dudmuck 10:52810ecbd83b 532 break;
mluis 0:45496a70a8a5 533 }
Wayne Roberts 12:662ff73ce484 534 } // ..PrepareTxFrame()
mluis 0:45496a70a8a5 535
mluis 0:45496a70a8a5 536
dudmuck 10:52810ecbd83b 537 void LoRaMacEventInfoStatus_toString(LoRaMacEventInfoStatus_t s, char* out)
mluis 0:45496a70a8a5 538 {
dudmuck 10:52810ecbd83b 539 switch (s) {
dudmuck 10:52810ecbd83b 540 case LORAMAC_EVENT_INFO_STATUS_JOIN_FAIL:
dudmuck 10:52810ecbd83b 541 strcpy(out, "JOIN_FAIL");
dudmuck 10:52810ecbd83b 542 break;
dudmuck 10:52810ecbd83b 543 case LORAMAC_EVENT_INFO_STATUS_ERROR:
dudmuck 10:52810ecbd83b 544 strcpy(out, "ERROR");
dudmuck 10:52810ecbd83b 545 break;
dudmuck 10:52810ecbd83b 546 case LORAMAC_EVENT_INFO_STATUS_RX2_TIMEOUT:
dudmuck 10:52810ecbd83b 547 strcpy(out, "RX2_TIMEOUT");
dudmuck 10:52810ecbd83b 548 break;
dudmuck 10:52810ecbd83b 549 case LORAMAC_EVENT_INFO_STATUS_ADDRESS_FAIL:
dudmuck 10:52810ecbd83b 550 strcpy(out, "ADDRESS_FAIL");
dudmuck 10:52810ecbd83b 551 break;
dudmuck 10:52810ecbd83b 552 case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS:
dudmuck 10:52810ecbd83b 553 strcpy(out, "FRAMES_LOSS");
dudmuck 10:52810ecbd83b 554 break;
dudmuck 10:52810ecbd83b 555 case LORAMAC_EVENT_INFO_STATUS_DOWNLINK_REPEATED:
dudmuck 10:52810ecbd83b 556 strcpy(out, "DOWNLINK_REPEATED");
dudmuck 10:52810ecbd83b 557 break; // confirmed downlink retry?
dudmuck 10:52810ecbd83b 558 case LORAMAC_EVENT_INFO_STATUS_MIC_FAIL:
dudmuck 10:52810ecbd83b 559 strcpy(out, "MIC_FAIL");
dudmuck 10:52810ecbd83b 560 break;
dudmuck 10:52810ecbd83b 561 case LORAMAC_EVENT_INFO_STATUS_TX_TIMEOUT:
dudmuck 10:52810ecbd83b 562 strcpy(out, "TX_TIMEOUT");
dudmuck 10:52810ecbd83b 563 break;
dudmuck 10:52810ecbd83b 564 case LORAMAC_EVENT_INFO_STATUS_RX1_ERROR:
dudmuck 10:52810ecbd83b 565 strcpy(out, "RX1_ERROR");
dudmuck 10:52810ecbd83b 566 break;
dudmuck 10:52810ecbd83b 567 case LORAMAC_EVENT_INFO_STATUS_RX2_ERROR:
dudmuck 10:52810ecbd83b 568 strcpy(out, "RX2_ERROR");
dudmuck 10:52810ecbd83b 569 break;
dudmuck 10:52810ecbd83b 570 case LORAMAC_EVENT_INFO_STATUS_TX_DR_PAYLOAD_SIZE_ERROR:
dudmuck 10:52810ecbd83b 571 strcpy(out, "SIZE");
dudmuck 10:52810ecbd83b 572 break;
mluis 0:45496a70a8a5 573
mluis 0:45496a70a8a5 574
dudmuck 10:52810ecbd83b 575 default:
dudmuck 10:52810ecbd83b 576 sprintf(out, "<%d>", s);
dudmuck 10:52810ecbd83b 577 break;
dudmuck 10:52810ecbd83b 578 }
GregCr 3:d4142832d5af 579 }
GregCr 3:d4142832d5af 580
Wayne Roberts 12:662ff73ce484 581
GregCr 3:d4142832d5af 582 /*!
mluis 0:45496a70a8a5 583 * \brief MCPS-Confirm event function
mluis 0:45496a70a8a5 584 *
mluis 5:fa113b25f612 585 * \param [IN] mcpsConfirm - Pointer to the confirm structure,
mluis 0:45496a70a8a5 586 * containing confirm attributes.
mluis 0:45496a70a8a5 587 */
mluis 5:fa113b25f612 588 static void McpsConfirm( McpsConfirm_t *mcpsConfirm )
mluis 0:45496a70a8a5 589 {
dudmuck 10:52810ecbd83b 590 if( mcpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
dudmuck 10:52810ecbd83b 591 switch( mcpsConfirm->McpsRequest ) {
dudmuck 10:52810ecbd83b 592 case MCPS_UNCONFIRMED: {
mluis 0:45496a70a8a5 593 // Check Datarate
mluis 0:45496a70a8a5 594 // Check TxPower
mluis 0:45496a70a8a5 595 break;
mluis 0:45496a70a8a5 596 }
dudmuck 10:52810ecbd83b 597 case MCPS_CONFIRMED: {
mluis 0:45496a70a8a5 598 // Check Datarate
mluis 0:45496a70a8a5 599 // Check TxPower
mluis 0:45496a70a8a5 600 // Check AckReceived
mluis 5:fa113b25f612 601 // Check NbTrials
mluis 5:fa113b25f612 602 LoRaMacUplinkStatus.Acked = mcpsConfirm->AckReceived;
mluis 0:45496a70a8a5 603 break;
mluis 0:45496a70a8a5 604 }
dudmuck 10:52810ecbd83b 605 case MCPS_PROPRIETARY: {
mluis 0:45496a70a8a5 606 break;
mluis 0:45496a70a8a5 607 }
mluis 0:45496a70a8a5 608 default:
mluis 0:45496a70a8a5 609 break;
mluis 0:45496a70a8a5 610 }
mluis 5:fa113b25f612 611 LoRaMacUplinkStatus.Datarate = mcpsConfirm->Datarate;
mluis 5:fa113b25f612 612 LoRaMacUplinkStatus.UplinkCounter = mcpsConfirm->UpLinkCounter;
dudmuck 10:52810ecbd83b 613 } else {
dudmuck 10:52810ecbd83b 614 char str[48];
dudmuck 10:52810ecbd83b 615 LoRaMacEventInfoStatus_toString(mcpsConfirm->Status, str);
Wayne Roberts 12:662ff73ce484 616 strcpy(statusTxt, "mcpsConf ");
Wayne Roberts 12:662ff73ce484 617 strcat(statusTxt, str);
mluis 5:fa113b25f612 618
dudmuck 10:52810ecbd83b 619 }
mluis 7:ceb4063e6863 620
dudmuck 10:52810ecbd83b 621 DeviceState = DEVICE_STATE_TRIGGER;
Wayne Roberts 12:662ff73ce484 622 } // ..McpsConfirm()
dudmuck 10:52810ecbd83b 623
mluis 0:45496a70a8a5 624 /*!
mluis 0:45496a70a8a5 625 * \brief MCPS-Indication event function
mluis 0:45496a70a8a5 626 *
mluis 5:fa113b25f612 627 * \param [IN] mcpsIndication - Pointer to the indication structure,
mluis 0:45496a70a8a5 628 * containing indication attributes.
mluis 0:45496a70a8a5 629 */
mluis 5:fa113b25f612 630 static void McpsIndication( McpsIndication_t *mcpsIndication )
mluis 0:45496a70a8a5 631 {
dudmuck 10:52810ecbd83b 632 if( mcpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK ) {
dudmuck 10:52810ecbd83b 633 char str[48];
dudmuck 10:52810ecbd83b 634 LoRaMacEventInfoStatus_toString(mcpsIndication->Status, str);
Wayne Roberts 12:662ff73ce484 635 strcpy(statusTxt, "mcpsInd ");
Wayne Roberts 12:662ff73ce484 636 strcat(statusTxt, str);
mluis 0:45496a70a8a5 637 return;
mluis 0:45496a70a8a5 638 }
mluis 0:45496a70a8a5 639
dudmuck 10:52810ecbd83b 640 switch( mcpsIndication->McpsIndication ) {
dudmuck 10:52810ecbd83b 641 case MCPS_UNCONFIRMED: {
mluis 0:45496a70a8a5 642 break;
mluis 0:45496a70a8a5 643 }
dudmuck 10:52810ecbd83b 644 case MCPS_CONFIRMED: {
mluis 0:45496a70a8a5 645 break;
mluis 0:45496a70a8a5 646 }
dudmuck 10:52810ecbd83b 647 case MCPS_PROPRIETARY: {
mluis 0:45496a70a8a5 648 break;
mluis 0:45496a70a8a5 649 }
dudmuck 10:52810ecbd83b 650 case MCPS_MULTICAST: {
mluis 0:45496a70a8a5 651 break;
mluis 0:45496a70a8a5 652 }
mluis 0:45496a70a8a5 653 default:
mluis 0:45496a70a8a5 654 break;
mluis 0:45496a70a8a5 655 }
mluis 0:45496a70a8a5 656
mluis 0:45496a70a8a5 657 // Check Multicast
mluis 0:45496a70a8a5 658 // Check Port
mluis 0:45496a70a8a5 659 // Check Datarate
mluis 0:45496a70a8a5 660 // Check FramePending
mluis 0:45496a70a8a5 661 // Check Buffer
mluis 0:45496a70a8a5 662 // Check BufferSize
mluis 0:45496a70a8a5 663 // Check Rssi
mluis 0:45496a70a8a5 664 // Check Snr
mluis 0:45496a70a8a5 665 // Check RxSlot
mluis 5:fa113b25f612 666 LoRaMacDownlinkStatus.Rssi = mcpsIndication->Rssi;
dudmuck 10:52810ecbd83b 667 if( mcpsIndication->Snr & 0x80 ) { // The SNR sign bit is 1
mluis 0:45496a70a8a5 668 // Invert and divide by 4
mluis 5:fa113b25f612 669 LoRaMacDownlinkStatus.Snr = ( ( ~mcpsIndication->Snr + 1 ) & 0xFF ) >> 2;
mluis 0:45496a70a8a5 670 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
dudmuck 10:52810ecbd83b 671 } else {
mluis 0:45496a70a8a5 672 // Divide by 4
mluis 5:fa113b25f612 673 LoRaMacDownlinkStatus.Snr = ( mcpsIndication->Snr & 0xFF ) >> 2;
mluis 0:45496a70a8a5 674 }
mluis 0:45496a70a8a5 675 LoRaMacDownlinkStatus.DownlinkCounter++;
mluis 5:fa113b25f612 676 LoRaMacDownlinkStatus.RxData = mcpsIndication->RxData;
mluis 5:fa113b25f612 677 LoRaMacDownlinkStatus.Port = mcpsIndication->Port;
mluis 5:fa113b25f612 678 LoRaMacDownlinkStatus.Buffer = mcpsIndication->Buffer;
mluis 5:fa113b25f612 679 LoRaMacDownlinkStatus.BufferSize = mcpsIndication->BufferSize;
mluis 0:45496a70a8a5 680
dudmuck 10:52810ecbd83b 681 if( ComplianceTest.Running == true ) {
mluis 0:45496a70a8a5 682 ComplianceTest.DownLinkCounter++;
mluis 0:45496a70a8a5 683 }
mluis 0:45496a70a8a5 684
dudmuck 10:52810ecbd83b 685 if( mcpsIndication->RxData == true ) {
dudmuck 10:52810ecbd83b 686 unsigned n;
dudmuck 10:52810ecbd83b 687 for (n = 0; n < mcpsIndication->BufferSize; n += 4) {
dudmuck 10:52810ecbd83b 688 uint16_t val = mcpsIndication->Buffer[n+1] << 8;
dudmuck 10:52810ecbd83b 689 val += mcpsIndication->Buffer[n+2];
dudmuck 10:52810ecbd83b 690 cayenne_ack_ch = mcpsIndication->Buffer[n];
dudmuck 10:52810ecbd83b 691 switch (mcpsIndication->Buffer[n]) {
dudmuck 10:52810ecbd83b 692 case CAYENNE_CH_DOUT:
dudmuck 10:52810ecbd83b 693 extLed.write(val);
dudmuck 10:52810ecbd83b 694 break;
dudmuck 10:52810ecbd83b 695 case CAYENNE_CH_AOUT:
dudmuck 10:52810ecbd83b 696 pwm.write(val / 100.0);
dudmuck 10:52810ecbd83b 697 break;
dudmuck 10:52810ecbd83b 698 default:
dudmuck 10:52810ecbd83b 699 break;
GregCr 2:48d8d4806d48 700 }
dudmuck 10:52810ecbd83b 701 }
mluis 9:0083afd69815 702
dudmuck 10:52810ecbd83b 703 switch( mcpsIndication->Port ) {
dudmuck 10:52810ecbd83b 704 case 1: // The application LED can be controlled on port 1 or 2
dudmuck 10:52810ecbd83b 705 case 2:
dudmuck 10:52810ecbd83b 706 if( mcpsIndication->BufferSize == 1 ) {
dudmuck 10:52810ecbd83b 707 //AppLedStateOn = mcpsIndication->Buffer[0] & 0x01;
dudmuck 10:52810ecbd83b 708 //Led3StateChanged = true;
mluis 0:45496a70a8a5 709 }
dudmuck 10:52810ecbd83b 710 break;
dudmuck 10:52810ecbd83b 711 case 224:
dudmuck 10:52810ecbd83b 712 if( ComplianceTest.Running == false ) {
dudmuck 10:52810ecbd83b 713 // Check compliance test enable command (i)
dudmuck 10:52810ecbd83b 714 if( ( mcpsIndication->BufferSize == 4 ) &&
dudmuck 10:52810ecbd83b 715 ( mcpsIndication->Buffer[0] == 0x01 ) &&
dudmuck 10:52810ecbd83b 716 ( mcpsIndication->Buffer[1] == 0x01 ) &&
dudmuck 10:52810ecbd83b 717 ( mcpsIndication->Buffer[2] == 0x01 ) &&
dudmuck 10:52810ecbd83b 718 ( mcpsIndication->Buffer[3] == 0x01 ) ) {
dudmuck 11:018e7e28161d 719 gIsTxConfirmed = false;
dudmuck 10:52810ecbd83b 720 AppPort = 224;
dudmuck 11:018e7e28161d 721 gAppDataSize = 2;
mluis 9:0083afd69815 722 ComplianceTest.DownLinkCounter = 0;
dudmuck 10:52810ecbd83b 723 ComplianceTest.LinkCheck = false;
dudmuck 10:52810ecbd83b 724 ComplianceTest.DemodMargin = 0;
dudmuck 10:52810ecbd83b 725 ComplianceTest.NbGateways = 0;
dudmuck 10:52810ecbd83b 726 ComplianceTest.Running = true;
dudmuck 10:52810ecbd83b 727 ComplianceTest.State = 1;
mluis 9:0083afd69815 728
mluis 9:0083afd69815 729 MibRequestConfirm_t mibReq;
mluis 9:0083afd69815 730 mibReq.Type = MIB_ADR;
dudmuck 10:52810ecbd83b 731 mibReq.Param.AdrEnable = true;
mluis 9:0083afd69815 732 LoRaMacMibSetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 733
mluis 9:0083afd69815 734 #if defined( USE_BAND_868 )
dudmuck 10:52810ecbd83b 735 LoRaMacTestSetDutyCycleOn( false );
dudmuck 10:52810ecbd83b 736 #endif
dudmuck 10:52810ecbd83b 737 }
dudmuck 10:52810ecbd83b 738 } else {
dudmuck 10:52810ecbd83b 739 ComplianceTest.State = mcpsIndication->Buffer[0];
dudmuck 10:52810ecbd83b 740 switch( ComplianceTest.State ) {
dudmuck 10:52810ecbd83b 741 case 0: // Check compliance test disable command (ii)
dudmuck 11:018e7e28161d 742 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
dudmuck 10:52810ecbd83b 743 AppPort = LORAWAN_APP_PORT;
dudmuck 11:018e7e28161d 744 gAppDataSize = LORAWAN_APP_DATA_SIZE;
dudmuck 10:52810ecbd83b 745 ComplianceTest.DownLinkCounter = 0;
dudmuck 10:52810ecbd83b 746 ComplianceTest.Running = false;
dudmuck 10:52810ecbd83b 747
dudmuck 10:52810ecbd83b 748 MibRequestConfirm_t mibReq;
dudmuck 10:52810ecbd83b 749 mibReq.Type = MIB_ADR;
dudmuck 10:52810ecbd83b 750 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
dudmuck 10:52810ecbd83b 751 LoRaMacMibSetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 752 #if defined( USE_BAND_868 )
dudmuck 10:52810ecbd83b 753 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
dudmuck 10:52810ecbd83b 754 #endif
dudmuck 10:52810ecbd83b 755 break;
dudmuck 10:52810ecbd83b 756 case 1: // (iii, iv)
dudmuck 11:018e7e28161d 757 gAppDataSize = 2;
dudmuck 10:52810ecbd83b 758 break;
dudmuck 10:52810ecbd83b 759 case 2: // Enable confirmed messages (v)
dudmuck 11:018e7e28161d 760 gIsTxConfirmed = true;
dudmuck 10:52810ecbd83b 761 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 762 break;
dudmuck 10:52810ecbd83b 763 case 3: // Disable confirmed messages (vi)
dudmuck 11:018e7e28161d 764 gIsTxConfirmed = false;
dudmuck 10:52810ecbd83b 765 ComplianceTest.State = 1;
dudmuck 10:52810ecbd83b 766 break;
dudmuck 10:52810ecbd83b 767 case 4: // (vii)
dudmuck 11:018e7e28161d 768 gAppDataSize = mcpsIndication->BufferSize;
dudmuck 10:52810ecbd83b 769
dudmuck 10:52810ecbd83b 770 AppData[0] = 4;
dudmuck 11:018e7e28161d 771 for( uint8_t i = 1; i < gAppDataSize; i++ ) {
dudmuck 10:52810ecbd83b 772 AppData[i] = mcpsIndication->Buffer[i] + 1;
dudmuck 10:52810ecbd83b 773 }
dudmuck 10:52810ecbd83b 774 break;
dudmuck 10:52810ecbd83b 775 case 5: { // (viii)
dudmuck 10:52810ecbd83b 776 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 777 mlmeReq.Type = MLME_LINK_CHECK;
dudmuck 10:52810ecbd83b 778 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 779 }
dudmuck 10:52810ecbd83b 780 break;
dudmuck 10:52810ecbd83b 781 case 6: { // (ix)
dudmuck 10:52810ecbd83b 782 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 783
dudmuck 10:52810ecbd83b 784 // Disable TestMode and revert back to normal operation
dudmuck 11:018e7e28161d 785 gIsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
dudmuck 10:52810ecbd83b 786 AppPort = LORAWAN_APP_PORT;
dudmuck 11:018e7e28161d 787 gAppDataSize = LORAWAN_APP_DATA_SIZE;
dudmuck 10:52810ecbd83b 788 ComplianceTest.DownLinkCounter = 0;
dudmuck 10:52810ecbd83b 789 ComplianceTest.Running = false;
dudmuck 10:52810ecbd83b 790
dudmuck 10:52810ecbd83b 791 MibRequestConfirm_t mibReq;
dudmuck 10:52810ecbd83b 792 mibReq.Type = MIB_ADR;
dudmuck 10:52810ecbd83b 793 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
dudmuck 10:52810ecbd83b 794 LoRaMacMibSetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 795 #if defined( USE_BAND_868 )
dudmuck 10:52810ecbd83b 796 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 9:0083afd69815 797 #endif
mluis 9:0083afd69815 798
dudmuck 10:52810ecbd83b 799 mlmeReq.Type = MLME_JOIN;
mluis 7:ceb4063e6863 800
dudmuck 10:52810ecbd83b 801 mlmeReq.Req.Join.DevEui = DevEui;
dudmuck 10:52810ecbd83b 802 mlmeReq.Req.Join.AppEui = AppEui;
dudmuck 10:52810ecbd83b 803 mlmeReq.Req.Join.AppKey = AppKey;
dudmuck 10:52810ecbd83b 804 mlmeReq.Req.Join.NbTrials = 3;
dudmuck 10:52810ecbd83b 805
mluis 9:0083afd69815 806 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 807 DeviceState = DEVICE_STATE_SLEEP;
mluis 9:0083afd69815 808 }
dudmuck 10:52810ecbd83b 809 break;
dudmuck 10:52810ecbd83b 810 case 7: { // (x)
dudmuck 10:52810ecbd83b 811 if( mcpsIndication->BufferSize == 3 ) {
dudmuck 10:52810ecbd83b 812 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 813 mlmeReq.Type = MLME_TXCW;
dudmuck 10:52810ecbd83b 814 mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
dudmuck 10:52810ecbd83b 815 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 816 } else if( mcpsIndication->BufferSize == 7 ) {
dudmuck 10:52810ecbd83b 817 MlmeReq_t mlmeReq;
dudmuck 10:52810ecbd83b 818 mlmeReq.Type = MLME_TXCW_1;
dudmuck 10:52810ecbd83b 819 mlmeReq.Req.TxCw.Timeout = ( uint16_t )( ( mcpsIndication->Buffer[1] << 8 ) | mcpsIndication->Buffer[2] );
dudmuck 10:52810ecbd83b 820 mlmeReq.Req.TxCw.Frequency = ( uint32_t )( ( mcpsIndication->Buffer[3] << 16 ) | ( mcpsIndication->Buffer[4] << 8 ) | mcpsIndication->Buffer[5] ) * 100;
dudmuck 10:52810ecbd83b 821 mlmeReq.Req.TxCw.Power = mcpsIndication->Buffer[6];
dudmuck 10:52810ecbd83b 822 LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 823 }
dudmuck 10:52810ecbd83b 824 ComplianceTest.State = 1;
mluis 9:0083afd69815 825 }
dudmuck 10:52810ecbd83b 826 break;
dudmuck 10:52810ecbd83b 827 default:
dudmuck 10:52810ecbd83b 828 break;
mluis 9:0083afd69815 829 }
mluis 0:45496a70a8a5 830 }
dudmuck 10:52810ecbd83b 831 break;
dudmuck 10:52810ecbd83b 832 default:
dudmuck 10:52810ecbd83b 833 break;
mluis 0:45496a70a8a5 834 }
mluis 0:45496a70a8a5 835 }
mluis 0:45496a70a8a5 836
mluis 0:45496a70a8a5 837 DownlinkStatusUpdated = true;
mluis 0:45496a70a8a5 838 }
mluis 0:45496a70a8a5 839
dudmuck 10:52810ecbd83b 840
dudmuck 10:52810ecbd83b 841
mluis 0:45496a70a8a5 842 /*!
mluis 0:45496a70a8a5 843 * \brief MLME-Confirm event function
mluis 0:45496a70a8a5 844 *
mluis 5:fa113b25f612 845 * \param [IN] mlmeConfirm - Pointer to the confirm structure,
mluis 0:45496a70a8a5 846 * containing confirm attributes.
mluis 0:45496a70a8a5 847 */
mluis 5:fa113b25f612 848 static void MlmeConfirm( MlmeConfirm_t *mlmeConfirm )
mluis 0:45496a70a8a5 849 {
Wayne Roberts 12:662ff73ce484 850 char str[48];
Wayne Roberts 12:662ff73ce484 851
Wayne Roberts 12:662ff73ce484 852 strcpy(statusTxt, "MlmeConfirm() ");
Wayne Roberts 12:662ff73ce484 853
dudmuck 10:52810ecbd83b 854 switch( mlmeConfirm->MlmeRequest ) {
dudmuck 10:52810ecbd83b 855 case MLME_JOIN: {
Wayne Roberts 12:662ff73ce484 856 strcat(statusTxt, "MLME_JOIN ");
dudmuck 10:52810ecbd83b 857 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
Wayne Roberts 12:662ff73ce484 858 strcat(statusTxt, "OK");
dudmuck 10:52810ecbd83b 859 DeviceState = DEVICE_STATE_JOIN_OK;
dudmuck 10:52810ecbd83b 860 extLed = 0;
dudmuck 10:52810ecbd83b 861 } else {
dudmuck 10:52810ecbd83b 862 LoRaMacEventInfoStatus_toString(mlmeConfirm->Status, str);
Wayne Roberts 12:662ff73ce484 863 strcat(statusTxt, str);
mluis 9:0083afd69815 864 DeviceState = DEVICE_STATE_JOIN;
mluis 0:45496a70a8a5 865 }
mluis 9:0083afd69815 866 break;
mluis 9:0083afd69815 867 }
dudmuck 10:52810ecbd83b 868 case MLME_LINK_CHECK: {
Wayne Roberts 12:662ff73ce484 869 strcat(statusTxt, "MLME_LINK_CHECK ");
dudmuck 10:52810ecbd83b 870 if( mlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK ) {
Wayne Roberts 12:662ff73ce484 871 strcat(statusTxt, "OK");
mluis 0:45496a70a8a5 872 // Check DemodMargin
mluis 0:45496a70a8a5 873 // Check NbGateways
dudmuck 10:52810ecbd83b 874 if( ComplianceTest.Running == true ) {
mluis 0:45496a70a8a5 875 ComplianceTest.LinkCheck = true;
mluis 5:fa113b25f612 876 ComplianceTest.DemodMargin = mlmeConfirm->DemodMargin;
mluis 5:fa113b25f612 877 ComplianceTest.NbGateways = mlmeConfirm->NbGateways;
mluis 0:45496a70a8a5 878 }
mluis 0:45496a70a8a5 879 }
mluis 9:0083afd69815 880 break;
mluis 0:45496a70a8a5 881 }
mluis 9:0083afd69815 882 default:
Wayne Roberts 12:662ff73ce484 883 sprintf(str, "<%d>", mlmeConfirm->MlmeRequest);
Wayne Roberts 12:662ff73ce484 884 strcat(statusTxt, str);
mluis 9:0083afd69815 885 break;
mluis 0:45496a70a8a5 886 }
Wayne Roberts 12:662ff73ce484 887 } // ..MlmeConfirm()
dudmuck 10:52810ecbd83b 888
Wayne Roberts 12:662ff73ce484 889 void poll()
dudmuck 10:52810ecbd83b 890 {
dudmuck 11:018e7e28161d 891 float R, temp;
dudmuck 11:018e7e28161d 892 uint16_t u16;
Wayne Roberts 13:f88dd77772b6 893 static unsigned prevJump = 0;
dudmuck 11:018e7e28161d 894
dudmuck 10:52810ecbd83b 895 vt.SetCursorPos( 43, 1 );
dudmuck 11:018e7e28161d 896
dudmuck 11:018e7e28161d 897 u16 = a3.read_u16() >> 4;
dudmuck 11:018e7e28161d 898 R = 4096.0 / u16 - 1.0;
dudmuck 11:018e7e28161d 899 R = R0 * R;
dudmuck 11:018e7e28161d 900 temp = 1.0/(log(R/R0)/B+1/298.15)-273.15;
dudmuck 11:018e7e28161d 901
Wayne Roberts 12:662ff73ce484 902 vt.printf("%u d8:%u,%u (%03x %03x %03x %03x) %.2fC\e[K", DeviceState,
Wayne Roberts 13:f88dd77772b6 903 d8.read(), jumper_in.read(),
Wayne Roberts 12:662ff73ce484 904 a1.read_u16() >> 4, a2.read_u16() >> 4, a3.read_u16() >> 4, a4.read_u16(), temp);
Wayne Roberts 12:662ff73ce484 905
Wayne Roberts 12:662ff73ce484 906 if (statusTxt[0] != 0) {
Wayne Roberts 12:662ff73ce484 907 vt.SetCursorPos( 45, 1 );
Wayne Roberts 12:662ff73ce484 908 vt.printf("%s\e[K", statusTxt);
Wayne Roberts 12:662ff73ce484 909 statusTxt[0] = 0;
Wayne Roberts 12:662ff73ce484 910 }
Wayne Roberts 12:662ff73ce484 911
Wayne Roberts 13:f88dd77772b6 912 if (prevJump == 0 && jumper_in.read() == 1) {
Wayne Roberts 12:662ff73ce484 913 /* user button release */
Wayne Roberts 12:662ff73ce484 914 TimerInit(&event, autoUplink);
Wayne Roberts 12:662ff73ce484 915 TimerSetValue(&event, TX_INTERVAL_MS);
Wayne Roberts 12:662ff73ce484 916 TimerStart(&event);
Wayne Roberts 12:662ff73ce484 917 sprintf(statusTxt, "timer on %u", TX_INTERVAL_MS);
Wayne Roberts 12:662ff73ce484 918 }
Wayne Roberts 13:f88dd77772b6 919 prevJump = jumper_in.read();
mluis 0:45496a70a8a5 920 }
mluis 0:45496a70a8a5 921
dudmuck 10:52810ecbd83b 922 const LoRaMacPrimitives_t LoRaMacPrimitives = {
dudmuck 10:52810ecbd83b 923 McpsConfirm,
dudmuck 10:52810ecbd83b 924 McpsIndication,
dudmuck 10:52810ecbd83b 925 MlmeConfirm
dudmuck 10:52810ecbd83b 926
dudmuck 10:52810ecbd83b 927 };
dudmuck 10:52810ecbd83b 928 const LoRaMacCallback_t LoRaMacCallbacks = {
dudmuck 10:52810ecbd83b 929 BoardGetBatteryLevel
dudmuck 10:52810ecbd83b 930 };
dudmuck 10:52810ecbd83b 931
mluis 0:45496a70a8a5 932 /**
mluis 0:45496a70a8a5 933 * Main application entry point.
mluis 0:45496a70a8a5 934 */
mluis 0:45496a70a8a5 935 int main( void )
mluis 0:45496a70a8a5 936 {
mluis 0:45496a70a8a5 937 MibRequestConfirm_t mibReq;
mluis 0:45496a70a8a5 938
Wayne Roberts 13:f88dd77772b6 939 jumper_out = 1;
Wayne Roberts 13:f88dd77772b6 940 jumper_in.mode(PullDown);
Wayne Roberts 13:f88dd77772b6 941
mluis 0:45496a70a8a5 942 BoardInit( );
mluis 0:45496a70a8a5 943 SerialDisplayInit( );
mluis 0:45496a70a8a5 944
mluis 7:ceb4063e6863 945 SerialDisplayUpdateEui( 5, DevEui );
mluis 7:ceb4063e6863 946 SerialDisplayUpdateEui( 6, AppEui );
mluis 7:ceb4063e6863 947 SerialDisplayUpdateKey( 7, AppKey );
mluis 7:ceb4063e6863 948
mluis 7:ceb4063e6863 949 #if( OVER_THE_AIR_ACTIVATION == 0 )
mluis 7:ceb4063e6863 950 SerialDisplayUpdateNwkId( LORAWAN_NETWORK_ID );
mluis 7:ceb4063e6863 951 SerialDisplayUpdateDevAddr( DevAddr );
mluis 7:ceb4063e6863 952 SerialDisplayUpdateKey( 12, NwkSKey );
mluis 7:ceb4063e6863 953 SerialDisplayUpdateKey( 13, AppSKey );
mluis 7:ceb4063e6863 954 #endif
mluis 7:ceb4063e6863 955
mluis 0:45496a70a8a5 956 DeviceState = DEVICE_STATE_INIT;
mluis 0:45496a70a8a5 957
dudmuck 10:52810ecbd83b 958 while( 1 ) {
Wayne Roberts 12:662ff73ce484 959 poll();
mluis 0:45496a70a8a5 960 SerialRxProcess( );
dudmuck 10:52810ecbd83b 961
dudmuck 10:52810ecbd83b 962 if( DownlinkStatusUpdated == true ) {
mluis 0:45496a70a8a5 963 DownlinkStatusUpdated = false;
mluis 0:45496a70a8a5 964 SerialDisplayUpdateDownlink( LoRaMacDownlinkStatus.RxData, LoRaMacDownlinkStatus.Rssi, LoRaMacDownlinkStatus.Snr, LoRaMacDownlinkStatus.DownlinkCounter, LoRaMacDownlinkStatus.Port, LoRaMacDownlinkStatus.Buffer, LoRaMacDownlinkStatus.BufferSize );
mluis 0:45496a70a8a5 965 }
dudmuck 10:52810ecbd83b 966
dudmuck 10:52810ecbd83b 967 switch( DeviceState ) {
dudmuck 10:52810ecbd83b 968 case DEVICE_STATE_INIT: {
dudmuck 10:52810ecbd83b 969 pwm.period(1.0 / 60);
dudmuck 10:52810ecbd83b 970 cayenne_ack_ch = -1;
dudmuck 10:52810ecbd83b 971 c_ch = 0xff;
dudmuck 10:52810ecbd83b 972 d8.mode(PullDown);
dudmuck 10:52810ecbd83b 973
mluis 0:45496a70a8a5 974 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
mluis 0:45496a70a8a5 975
mluis 0:45496a70a8a5 976 mibReq.Type = MIB_ADR;
mluis 0:45496a70a8a5 977 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
mluis 0:45496a70a8a5 978 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 979
mluis 0:45496a70a8a5 980 mibReq.Type = MIB_PUBLIC_NETWORK;
mluis 0:45496a70a8a5 981 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
mluis 0:45496a70a8a5 982 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 983
mluis 0:45496a70a8a5 984 #if defined( USE_BAND_868 )
mluis 0:45496a70a8a5 985 LoRaMacTestSetDutyCycleOn( LORAWAN_DUTYCYCLE_ON );
mluis 0:45496a70a8a5 986 SerialDisplayUpdateDutyCycle( LORAWAN_DUTYCYCLE_ON );
mluis 5:fa113b25f612 987
mluis 9:0083afd69815 988 #if( USE_SEMTECH_DEFAULT_CHANNEL_LINEUP == 1 )
mluis 5:fa113b25f612 989 LoRaMacChannelAdd( 3, ( ChannelParams_t )LC4 );
mluis 5:fa113b25f612 990 LoRaMacChannelAdd( 4, ( ChannelParams_t )LC5 );
mluis 5:fa113b25f612 991 LoRaMacChannelAdd( 5, ( ChannelParams_t )LC6 );
mluis 5:fa113b25f612 992 LoRaMacChannelAdd( 6, ( ChannelParams_t )LC7 );
mluis 5:fa113b25f612 993 LoRaMacChannelAdd( 7, ( ChannelParams_t )LC8 );
mluis 5:fa113b25f612 994 LoRaMacChannelAdd( 8, ( ChannelParams_t )LC9 );
mluis 5:fa113b25f612 995 LoRaMacChannelAdd( 9, ( ChannelParams_t )LC10 );
mluis 7:ceb4063e6863 996
mluis 9:0083afd69815 997 mibReq.Type = MIB_RX2_DEFAULT_CHANNEL;
dudmuck 10:52810ecbd83b 998 mibReq.Param.Rx2DefaultChannel = ( Rx2ChannelParams_t ) {
dudmuck 10:52810ecbd83b 999 869525000, DR_3
dudmuck 10:52810ecbd83b 1000 };
mluis 9:0083afd69815 1001 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 9:0083afd69815 1002
mluis 7:ceb4063e6863 1003 mibReq.Type = MIB_RX2_CHANNEL;
dudmuck 10:52810ecbd83b 1004 mibReq.Param.Rx2Channel = ( Rx2ChannelParams_t ) {
dudmuck 10:52810ecbd83b 1005 869525000, DR_3
dudmuck 10:52810ecbd83b 1006 };
mluis 7:ceb4063e6863 1007 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 5:fa113b25f612 1008 #endif
mluis 5:fa113b25f612 1009
mluis 0:45496a70a8a5 1010 #endif
mluis 0:45496a70a8a5 1011 SerialDisplayUpdateActivationMode( OVER_THE_AIR_ACTIVATION );
mluis 0:45496a70a8a5 1012 SerialDisplayUpdateAdr( LORAWAN_ADR_ON );
mluis 0:45496a70a8a5 1013 SerialDisplayUpdatePublicNetwork( LORAWAN_PUBLIC_NETWORK );
mluis 0:45496a70a8a5 1014
mluis 0:45496a70a8a5 1015 LoRaMacDownlinkStatus.DownlinkCounter = 0;
mluis 0:45496a70a8a5 1016
mluis 0:45496a70a8a5 1017 DeviceState = DEVICE_STATE_JOIN;
mluis 0:45496a70a8a5 1018 break;
mluis 0:45496a70a8a5 1019 }
dudmuck 10:52810ecbd83b 1020 case DEVICE_STATE_JOIN: {
mluis 0:45496a70a8a5 1021 #if( OVER_THE_AIR_ACTIVATION != 0 )
dudmuck 10:52810ecbd83b 1022 LoRaMacStatus_t s;
mluis 0:45496a70a8a5 1023 MlmeReq_t mlmeReq;
mluis 0:45496a70a8a5 1024 mlmeReq.Type = MLME_JOIN;
mluis 0:45496a70a8a5 1025
mluis 0:45496a70a8a5 1026 mlmeReq.Req.Join.DevEui = DevEui;
mluis 0:45496a70a8a5 1027 mlmeReq.Req.Join.AppEui = AppEui;
mluis 0:45496a70a8a5 1028 mlmeReq.Req.Join.AppKey = AppKey;
Wayne Roberts 12:662ff73ce484 1029 mlmeReq.Req.Join.NbTrials = 1;
mluis 0:45496a70a8a5 1030
dudmuck 10:52810ecbd83b 1031 s = LoRaMacMlmeRequest( &mlmeReq );
dudmuck 10:52810ecbd83b 1032 if (s != LORAMAC_STATUS_OK) {
dudmuck 10:52810ecbd83b 1033 char str[48];
dudmuck 10:52810ecbd83b 1034 LoRaMacStatus_toString(s, str);
dudmuck 10:52810ecbd83b 1035 vt.SetCursorPos( 44, 1 );
dudmuck 10:52810ecbd83b 1036 vt.printf("mlmeReq join %s\e[K", str);
Wayne Roberts 12:662ff73ce484 1037 }
Wayne Roberts 12:662ff73ce484 1038 DeviceState = DEVICE_STATE_SLEEP;
dudmuck 10:52810ecbd83b 1039
dudmuck 10:52810ecbd83b 1040 extLed = 1;
mluis 0:45496a70a8a5 1041 #else
mluis 0:45496a70a8a5 1042 mibReq.Type = MIB_NET_ID;
mluis 0:45496a70a8a5 1043 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
mluis 0:45496a70a8a5 1044 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1045
mluis 0:45496a70a8a5 1046 mibReq.Type = MIB_DEV_ADDR;
mluis 0:45496a70a8a5 1047 mibReq.Param.DevAddr = DevAddr;
mluis 0:45496a70a8a5 1048 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1049
mluis 0:45496a70a8a5 1050 mibReq.Type = MIB_NWK_SKEY;
mluis 0:45496a70a8a5 1051 mibReq.Param.NwkSKey = NwkSKey;
mluis 0:45496a70a8a5 1052 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1053
mluis 0:45496a70a8a5 1054 mibReq.Type = MIB_APP_SKEY;
mluis 0:45496a70a8a5 1055 mibReq.Param.AppSKey = AppSKey;
mluis 0:45496a70a8a5 1056 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1057
mluis 0:45496a70a8a5 1058 mibReq.Type = MIB_NETWORK_JOINED;
mluis 0:45496a70a8a5 1059 mibReq.Param.IsNetworkJoined = true;
mluis 0:45496a70a8a5 1060 LoRaMacMibSetRequestConfirm( &mibReq );
mluis 0:45496a70a8a5 1061 DeviceState = DEVICE_STATE_SEND;
mluis 0:45496a70a8a5 1062 #endif
mluis 0:45496a70a8a5 1063 break;
mluis 0:45496a70a8a5 1064 }
dudmuck 10:52810ecbd83b 1065 case DEVICE_STATE_JOIN_OK:
dudmuck 10:52810ecbd83b 1066 MibRequestConfirm_t mibReq;
dudmuck 10:52810ecbd83b 1067 mibReq.Type = MIB_NETWORK_JOINED;
dudmuck 10:52810ecbd83b 1068 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1069 SerialDisplayUpdateNetworkIsJoined( mibReq.Param.IsNetworkJoined );
dudmuck 10:52810ecbd83b 1070 mibReq.Type = MIB_DEV_ADDR;
dudmuck 10:52810ecbd83b 1071 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1072 SerialDisplayUpdateDevAddr(mibReq.Param.DevAddr);
dudmuck 10:52810ecbd83b 1073 mibReq.Type = MIB_NWK_SKEY;
dudmuck 10:52810ecbd83b 1074 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1075 SerialDisplayUpdateKey( 12, mibReq.Param.NwkSKey );
dudmuck 10:52810ecbd83b 1076 mibReq.Type = MIB_APP_SKEY;
dudmuck 10:52810ecbd83b 1077 LoRaMacMibGetRequestConfirm( &mibReq );
dudmuck 10:52810ecbd83b 1078 SerialDisplayUpdateKey( 13, mibReq.Param.AppSKey );
dudmuck 10:52810ecbd83b 1079 //SerialDisplayUpdateNwkId( uint8_t id );
dudmuck 10:52810ecbd83b 1080 DeviceState = DEVICE_STATE_TRIGGER;
dudmuck 10:52810ecbd83b 1081 break;
dudmuck 10:52810ecbd83b 1082 case DEVICE_STATE_SEND: {
dudmuck 10:52810ecbd83b 1083 SerialDisplayUpdateUplinkAcked( false );
dudmuck 10:52810ecbd83b 1084 SerialDisplayUpdateDonwlinkRxData( false );
dudmuck 10:52810ecbd83b 1085 PrepareTxFrame( AppPort );
mluis 0:45496a70a8a5 1086
dudmuck 11:018e7e28161d 1087 SendFrame(gAppDataSize, gIsTxConfirmed);
dudmuck 10:52810ecbd83b 1088
dudmuck 10:52810ecbd83b 1089 DeviceState = DEVICE_STATE_SLEEP;
mluis 0:45496a70a8a5 1090 break;
mluis 0:45496a70a8a5 1091 }
dudmuck 10:52810ecbd83b 1092 case DEVICE_STATE_SLEEP: {
mluis 0:45496a70a8a5 1093 // Wake up through events
mluis 0:45496a70a8a5 1094 break;
mluis 0:45496a70a8a5 1095 }
dudmuck 10:52810ecbd83b 1096 case DEVICE_STATE_TRIGGER:
dudmuck 10:52810ecbd83b 1097 if (d8.read() == 1) {
dudmuck 10:52810ecbd83b 1098 c_ch = 0xff;
dudmuck 10:52810ecbd83b 1099 DeviceState = DEVICE_STATE_SEND;
dudmuck 10:52810ecbd83b 1100 buttonStartAt = TimerGetCurrentTime();
dudmuck 10:52810ecbd83b 1101 }
dudmuck 10:52810ecbd83b 1102 break;
Wayne Roberts 12:662ff73ce484 1103 default:
mluis 0:45496a70a8a5 1104 DeviceState = DEVICE_STATE_INIT;
mluis 0:45496a70a8a5 1105 break;
Wayne Roberts 12:662ff73ce484 1106
Wayne Roberts 12:662ff73ce484 1107 } // ..switch( DeviceState )
dudmuck 10:52810ecbd83b 1108
Wayne Roberts 12:662ff73ce484 1109 } // ..while( 1 )
mluis 0:45496a70a8a5 1110 }