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:
Tue Feb 20 22:16:57 2018 +0000
Revision:
14:f8c7c85fc8e8
Parent:
13:f88dd77772b6
add frame count to digital input

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