testing lora and ble on nrf51

Dependencies:   BLE_API LoRaWAN-lib SX1276Lib mbed nRF51822

Committer:
olav
Date:
Mon May 09 08:07:23 2016 +0000
Revision:
1:ca647cbbe4fb
Parent:
0:4c1fcbfcc7bf
initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
olav 0:4c1fcbfcc7bf 1 #include "mbed.h"
olav 0:4c1fcbfcc7bf 2 #include "board.h"
olav 0:4c1fcbfcc7bf 3 #include "radio.h"
olav 0:4c1fcbfcc7bf 4
olav 0:4c1fcbfcc7bf 5 #include "LoRaMac.h"
olav 0:4c1fcbfcc7bf 6 #include "Comissioning.h"
olav 0:4c1fcbfcc7bf 7
olav 0:4c1fcbfcc7bf 8 /*!
olav 0:4c1fcbfcc7bf 9 * Join requests trials duty cycle.
olav 0:4c1fcbfcc7bf 10 */
olav 0:4c1fcbfcc7bf 11 #define OVER_THE_AIR_ACTIVATION_DUTYCYCLE 10000000 // 10 [s] value in us
olav 0:4c1fcbfcc7bf 12
olav 0:4c1fcbfcc7bf 13 /*!
olav 0:4c1fcbfcc7bf 14 * Defines the application data transmission duty cycle. 5s, value in [us].
olav 0:4c1fcbfcc7bf 15 */
olav 0:4c1fcbfcc7bf 16 #define APP_TX_DUTYCYCLE 5000000
olav 0:4c1fcbfcc7bf 17
olav 0:4c1fcbfcc7bf 18 /*!
olav 0:4c1fcbfcc7bf 19 * Defines a random delay for application data transmission duty cycle. 1s,
olav 0:4c1fcbfcc7bf 20 * value in [us].
olav 0:4c1fcbfcc7bf 21 */
olav 0:4c1fcbfcc7bf 22 #define APP_TX_DUTYCYCLE_RND 1000000
olav 0:4c1fcbfcc7bf 23
olav 0:4c1fcbfcc7bf 24 /*!
olav 0:4c1fcbfcc7bf 25 * Default mote datarate
olav 0:4c1fcbfcc7bf 26 */
olav 0:4c1fcbfcc7bf 27 #define LORAWAN_DEFAULT_DATARATE DR_0
olav 0:4c1fcbfcc7bf 28
olav 0:4c1fcbfcc7bf 29 /*!
olav 0:4c1fcbfcc7bf 30 * LoRaWAN confirmed messages
olav 0:4c1fcbfcc7bf 31 */
olav 0:4c1fcbfcc7bf 32 #define LORAWAN_CONFIRMED_MSG_ON false
olav 0:4c1fcbfcc7bf 33
olav 0:4c1fcbfcc7bf 34 #define LORAWAN_ADR_ON 1
olav 0:4c1fcbfcc7bf 35
olav 0:4c1fcbfcc7bf 36 #define LORAWAN_DUTYCYCLE_ON false
olav 0:4c1fcbfcc7bf 37
olav 0:4c1fcbfcc7bf 38 #define LORAWAN_APP_PORT 15
olav 0:4c1fcbfcc7bf 39
olav 0:4c1fcbfcc7bf 40 /*!
olav 0:4c1fcbfcc7bf 41 * User application data buffer size
olav 0:4c1fcbfcc7bf 42 */
olav 0:4c1fcbfcc7bf 43 #if ( LORAWAN_CONFIRMED_MSG_ON == 1 )
olav 0:4c1fcbfcc7bf 44 #define LORAWAN_APP_DATA_SIZE 6
olav 0:4c1fcbfcc7bf 45
olav 0:4c1fcbfcc7bf 46 #else
olav 0:4c1fcbfcc7bf 47 #define LORAWAN_APP_DATA_SIZE 1
olav 0:4c1fcbfcc7bf 48
olav 0:4c1fcbfcc7bf 49 #endif
olav 0:4c1fcbfcc7bf 50
olav 0:4c1fcbfcc7bf 51 #if( OVER_THE_AIR_ACTIVATION != 0 )
olav 0:4c1fcbfcc7bf 52
olav 0:4c1fcbfcc7bf 53 static uint8_t DevEui[] = LORAWAN_DEVICE_EUI;
olav 0:4c1fcbfcc7bf 54 static uint8_t AppEui[] = LORAWAN_APPLICATION_EUI;
olav 0:4c1fcbfcc7bf 55 static uint8_t AppKey[] = LORAWAN_APPLICATION_KEY;
olav 0:4c1fcbfcc7bf 56
olav 0:4c1fcbfcc7bf 57 #else
olav 0:4c1fcbfcc7bf 58
olav 0:4c1fcbfcc7bf 59 static uint8_t NwkSKey[] = LORAWAN_NWKSKEY;
olav 0:4c1fcbfcc7bf 60 static uint8_t AppSKey[] = LORAWAN_APPSKEY;
olav 0:4c1fcbfcc7bf 61
olav 0:4c1fcbfcc7bf 62 /*!
olav 0:4c1fcbfcc7bf 63 * Device address
olav 0:4c1fcbfcc7bf 64 */
olav 0:4c1fcbfcc7bf 65 static uint32_t DevAddr = LORAWAN_DEVICE_ADDRESS;
olav 0:4c1fcbfcc7bf 66
olav 0:4c1fcbfcc7bf 67 #endif
olav 0:4c1fcbfcc7bf 68
olav 0:4c1fcbfcc7bf 69 /*!
olav 0:4c1fcbfcc7bf 70 * Application port
olav 0:4c1fcbfcc7bf 71 */
olav 0:4c1fcbfcc7bf 72 static uint8_t AppPort = LORAWAN_APP_PORT;
olav 0:4c1fcbfcc7bf 73
olav 0:4c1fcbfcc7bf 74 /*!
olav 0:4c1fcbfcc7bf 75 * User application data size
olav 0:4c1fcbfcc7bf 76 */
olav 0:4c1fcbfcc7bf 77 static uint8_t AppDataSize = LORAWAN_APP_DATA_SIZE;
olav 0:4c1fcbfcc7bf 78
olav 0:4c1fcbfcc7bf 79 /*!
olav 0:4c1fcbfcc7bf 80 * User application data buffer size
olav 0:4c1fcbfcc7bf 81 */
olav 0:4c1fcbfcc7bf 82 #define LORAWAN_APP_DATA_MAX_SIZE 64
olav 0:4c1fcbfcc7bf 83
olav 0:4c1fcbfcc7bf 84 /*!
olav 0:4c1fcbfcc7bf 85 * User application data
olav 0:4c1fcbfcc7bf 86 */
olav 0:4c1fcbfcc7bf 87 static uint8_t AppData[LORAWAN_APP_DATA_MAX_SIZE];
olav 0:4c1fcbfcc7bf 88
olav 0:4c1fcbfcc7bf 89 /*!
olav 0:4c1fcbfcc7bf 90 * Indicates if the node is sending confirmed or unconfirmed messages
olav 0:4c1fcbfcc7bf 91 */
olav 0:4c1fcbfcc7bf 92 static uint8_t IsTxConfirmed = LORAWAN_CONFIRMED_MSG_ON;
olav 0:4c1fcbfcc7bf 93
olav 0:4c1fcbfcc7bf 94 /*!
olav 0:4c1fcbfcc7bf 95 * Defines the application data transmission duty cycle
olav 0:4c1fcbfcc7bf 96 */
olav 0:4c1fcbfcc7bf 97 static uint32_t TxDutyCycleTime;
olav 0:4c1fcbfcc7bf 98
olav 0:4c1fcbfcc7bf 99 /*!
olav 0:4c1fcbfcc7bf 100 * Timer to handle the application data transmission duty cycle
olav 0:4c1fcbfcc7bf 101 */
olav 0:4c1fcbfcc7bf 102 static TimerEvent_t TxNextPacketTimer;
olav 0:4c1fcbfcc7bf 103
olav 0:4c1fcbfcc7bf 104 /*!
olav 0:4c1fcbfcc7bf 105 * Indicates if a new packet can be sent
olav 0:4c1fcbfcc7bf 106 */
olav 0:4c1fcbfcc7bf 107 static bool NextTx = true;
olav 0:4c1fcbfcc7bf 108
olav 0:4c1fcbfcc7bf 109 /*!
olav 0:4c1fcbfcc7bf 110 * Device states
olav 0:4c1fcbfcc7bf 111 */
olav 0:4c1fcbfcc7bf 112 static enum eDevicState
olav 0:4c1fcbfcc7bf 113 {
olav 0:4c1fcbfcc7bf 114 DEVICE_STATE_INIT,
olav 0:4c1fcbfcc7bf 115 DEVICE_STATE_JOIN,
olav 0:4c1fcbfcc7bf 116 DEVICE_STATE_SEND,
olav 0:4c1fcbfcc7bf 117 DEVICE_STATE_CYCLE,
olav 0:4c1fcbfcc7bf 118 DEVICE_STATE_SLEEP
olav 0:4c1fcbfcc7bf 119 }DeviceState;
olav 0:4c1fcbfcc7bf 120
olav 0:4c1fcbfcc7bf 121 /*!
olav 0:4c1fcbfcc7bf 122 * Strucure containing the Downlink status
olav 0:4c1fcbfcc7bf 123 */
olav 0:4c1fcbfcc7bf 124 struct sLoRaMacDownlinkStatus
olav 0:4c1fcbfcc7bf 125 {
olav 0:4c1fcbfcc7bf 126 int16_t Rssi;
olav 0:4c1fcbfcc7bf 127 int8_t Snr;
olav 0:4c1fcbfcc7bf 128 uint16_t DownlinkCounter;
olav 0:4c1fcbfcc7bf 129 bool RxData;
olav 0:4c1fcbfcc7bf 130 uint8_t Port;
olav 0:4c1fcbfcc7bf 131 uint8_t *Buffer;
olav 0:4c1fcbfcc7bf 132 uint8_t BufferSize;
olav 0:4c1fcbfcc7bf 133 }LoRaMacDownlinkStatus;
olav 0:4c1fcbfcc7bf 134
olav 0:4c1fcbfcc7bf 135 /*!
olav 0:4c1fcbfcc7bf 136 * Strucure containing the Uplink status
olav 0:4c1fcbfcc7bf 137 */
olav 0:4c1fcbfcc7bf 138 struct sLoRaMacUplinkStatus
olav 0:4c1fcbfcc7bf 139 {
olav 0:4c1fcbfcc7bf 140 uint8_t Acked;
olav 0:4c1fcbfcc7bf 141 int8_t Datarate;
olav 0:4c1fcbfcc7bf 142 uint16_t UplinkCounter;
olav 0:4c1fcbfcc7bf 143 uint8_t Port;
olav 0:4c1fcbfcc7bf 144 uint8_t *Buffer;
olav 0:4c1fcbfcc7bf 145 uint8_t BufferSize;
olav 0:4c1fcbfcc7bf 146 }LoRaMacUplinkStatus;
olav 0:4c1fcbfcc7bf 147
olav 0:4c1fcbfcc7bf 148 MibRequestConfirm_t mibReq;
olav 0:4c1fcbfcc7bf 149
olav 0:4c1fcbfcc7bf 150 InterruptIn button(BUTTON3);
olav 0:4c1fcbfcc7bf 151 DigitalOut led1(LED1);
olav 0:4c1fcbfcc7bf 152 DigitalOut led2(LED2);
olav 0:4c1fcbfcc7bf 153
olav 0:4c1fcbfcc7bf 154 /*!
olav 0:4c1fcbfcc7bf 155 * Indicates if the MAC layer network join status has changed.
olav 0:4c1fcbfcc7bf 156 */
olav 0:4c1fcbfcc7bf 157 static bool IsNetworkJoinedStatusUpdate = false;
olav 0:4c1fcbfcc7bf 158
olav 0:4c1fcbfcc7bf 159 static void PrepareTxFrame( uint8_t port )
olav 0:4c1fcbfcc7bf 160 {
olav 0:4c1fcbfcc7bf 161 switch( port )
olav 0:4c1fcbfcc7bf 162 {
olav 0:4c1fcbfcc7bf 163 case 15:
olav 0:4c1fcbfcc7bf 164 {}
olav 0:4c1fcbfcc7bf 165 default:
olav 0:4c1fcbfcc7bf 166 {
olav 0:4c1fcbfcc7bf 167 AppData[0] = 1;
olav 0:4c1fcbfcc7bf 168 if( IsTxConfirmed == true )
olav 0:4c1fcbfcc7bf 169 {
olav 0:4c1fcbfcc7bf 170 AppData[1] = LoRaMacDownlinkStatus.DownlinkCounter >> 8;
olav 0:4c1fcbfcc7bf 171 AppData[2] = LoRaMacDownlinkStatus.DownlinkCounter;
olav 0:4c1fcbfcc7bf 172 AppData[3] = LoRaMacDownlinkStatus.Rssi >> 8;
olav 0:4c1fcbfcc7bf 173 AppData[4] = LoRaMacDownlinkStatus.Rssi;
olav 0:4c1fcbfcc7bf 174 AppData[5] = LoRaMacDownlinkStatus.Snr;
olav 0:4c1fcbfcc7bf 175
olav 0:4c1fcbfcc7bf 176 AppData[6] = 1;
olav 0:4c1fcbfcc7bf 177 }
olav 0:4c1fcbfcc7bf 178 else
olav 0:4c1fcbfcc7bf 179 {
olav 0:4c1fcbfcc7bf 180 AppData[1] = 1;
olav 0:4c1fcbfcc7bf 181 }
olav 0:4c1fcbfcc7bf 182 }
olav 0:4c1fcbfcc7bf 183 break;
olav 0:4c1fcbfcc7bf 184 }
olav 0:4c1fcbfcc7bf 185 }
olav 0:4c1fcbfcc7bf 186
olav 0:4c1fcbfcc7bf 187 /*!
olav 0:4c1fcbfcc7bf 188 * \brief MCPS-Confirm event function
olav 0:4c1fcbfcc7bf 189 *
olav 0:4c1fcbfcc7bf 190 * \param [IN] McpsConfirm - Pointer to the confirm structure,
olav 0:4c1fcbfcc7bf 191 * containing confirm attributes.
olav 0:4c1fcbfcc7bf 192 */
olav 0:4c1fcbfcc7bf 193 static void McpsConfirm( McpsConfirm_t *McpsConfirm )
olav 0:4c1fcbfcc7bf 194 {
olav 0:4c1fcbfcc7bf 195 if( McpsConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
olav 0:4c1fcbfcc7bf 196 {
olav 0:4c1fcbfcc7bf 197 switch( McpsConfirm->McpsRequest )
olav 0:4c1fcbfcc7bf 198 {
olav 0:4c1fcbfcc7bf 199 case MCPS_UNCONFIRMED:
olav 0:4c1fcbfcc7bf 200 {
olav 0:4c1fcbfcc7bf 201 // Check Datarate
olav 0:4c1fcbfcc7bf 202 // Check TxPower
olav 0:4c1fcbfcc7bf 203 break;
olav 0:4c1fcbfcc7bf 204 }
olav 0:4c1fcbfcc7bf 205 case MCPS_CONFIRMED:
olav 0:4c1fcbfcc7bf 206 {
olav 0:4c1fcbfcc7bf 207 // Check Datarate
olav 0:4c1fcbfcc7bf 208 // Check TxPower
olav 0:4c1fcbfcc7bf 209 // Check AckReceived
olav 0:4c1fcbfcc7bf 210 // Check NbRetries
olav 0:4c1fcbfcc7bf 211 break;
olav 0:4c1fcbfcc7bf 212 }
olav 0:4c1fcbfcc7bf 213 case MCPS_PROPRIETARY:
olav 0:4c1fcbfcc7bf 214 {
olav 0:4c1fcbfcc7bf 215 break;
olav 0:4c1fcbfcc7bf 216 }
olav 0:4c1fcbfcc7bf 217 default:
olav 0:4c1fcbfcc7bf 218 break;
olav 0:4c1fcbfcc7bf 219 }
olav 0:4c1fcbfcc7bf 220 }
olav 0:4c1fcbfcc7bf 221 NextTx = true;
olav 0:4c1fcbfcc7bf 222 }
olav 0:4c1fcbfcc7bf 223
olav 0:4c1fcbfcc7bf 224 /*!
olav 0:4c1fcbfcc7bf 225 * \brief MCPS-Indication event function
olav 0:4c1fcbfcc7bf 226 *
olav 0:4c1fcbfcc7bf 227 * \param [IN] McpsIndication - Pointer to the indication structure,
olav 0:4c1fcbfcc7bf 228 * containing indication attributes.
olav 0:4c1fcbfcc7bf 229 */
olav 0:4c1fcbfcc7bf 230 static void McpsIndication( McpsIndication_t *McpsIndication )
olav 0:4c1fcbfcc7bf 231 {
olav 0:4c1fcbfcc7bf 232 printf("Downstream message! \r\n");
olav 0:4c1fcbfcc7bf 233 if( McpsIndication->Status != LORAMAC_EVENT_INFO_STATUS_OK )
olav 0:4c1fcbfcc7bf 234 {
olav 0:4c1fcbfcc7bf 235 printf("Something fishy %d \r\n", McpsIndication->Status);
olav 0:4c1fcbfcc7bf 236 return;
olav 0:4c1fcbfcc7bf 237 }
olav 0:4c1fcbfcc7bf 238
olav 0:4c1fcbfcc7bf 239 switch( McpsIndication->McpsIndication )
olav 0:4c1fcbfcc7bf 240 {
olav 0:4c1fcbfcc7bf 241 case MCPS_UNCONFIRMED:
olav 0:4c1fcbfcc7bf 242 {
olav 0:4c1fcbfcc7bf 243 break;
olav 0:4c1fcbfcc7bf 244 }
olav 0:4c1fcbfcc7bf 245 case MCPS_CONFIRMED:
olav 0:4c1fcbfcc7bf 246 {
olav 0:4c1fcbfcc7bf 247 break;
olav 0:4c1fcbfcc7bf 248 }
olav 0:4c1fcbfcc7bf 249 case MCPS_PROPRIETARY:
olav 0:4c1fcbfcc7bf 250 {
olav 0:4c1fcbfcc7bf 251 break;
olav 0:4c1fcbfcc7bf 252 }
olav 0:4c1fcbfcc7bf 253 case MCPS_MULTICAST:
olav 0:4c1fcbfcc7bf 254 {
olav 0:4c1fcbfcc7bf 255 break;
olav 0:4c1fcbfcc7bf 256 }
olav 0:4c1fcbfcc7bf 257 default:
olav 0:4c1fcbfcc7bf 258 break;
olav 0:4c1fcbfcc7bf 259 }
olav 0:4c1fcbfcc7bf 260
olav 0:4c1fcbfcc7bf 261 // Check Multicast
olav 0:4c1fcbfcc7bf 262 // Check Port
olav 0:4c1fcbfcc7bf 263 // Check Datarate
olav 0:4c1fcbfcc7bf 264 // Check FramePending
olav 0:4c1fcbfcc7bf 265 // Check Buffer
olav 0:4c1fcbfcc7bf 266 // Check BufferSize
olav 0:4c1fcbfcc7bf 267 // Check Rssi
olav 0:4c1fcbfcc7bf 268 // Check Snr
olav 0:4c1fcbfcc7bf 269 // Check RxSlot
olav 0:4c1fcbfcc7bf 270
olav 0:4c1fcbfcc7bf 271 LoRaMacDownlinkStatus.Rssi = McpsIndication->Rssi;
olav 0:4c1fcbfcc7bf 272 if( McpsIndication->Snr & 0x80 ) // The SNR sign bit is 1
olav 0:4c1fcbfcc7bf 273 {
olav 0:4c1fcbfcc7bf 274 // Invert and divide by 4
olav 0:4c1fcbfcc7bf 275 LoRaMacDownlinkStatus.Snr = ( ( ~McpsIndication->Snr + 1 ) & 0xFF ) >> 2;
olav 0:4c1fcbfcc7bf 276 LoRaMacDownlinkStatus.Snr = -LoRaMacDownlinkStatus.Snr;
olav 0:4c1fcbfcc7bf 277 }
olav 0:4c1fcbfcc7bf 278 else
olav 0:4c1fcbfcc7bf 279 {
olav 0:4c1fcbfcc7bf 280 // Divide by 4
olav 0:4c1fcbfcc7bf 281 LoRaMacDownlinkStatus.Snr = ( McpsIndication->Snr & 0xFF ) >> 2;
olav 0:4c1fcbfcc7bf 282 }
olav 0:4c1fcbfcc7bf 283 LoRaMacDownlinkStatus.DownlinkCounter++;
olav 0:4c1fcbfcc7bf 284 LoRaMacDownlinkStatus.RxData = McpsIndication->RxData;
olav 0:4c1fcbfcc7bf 285 LoRaMacDownlinkStatus.Port = McpsIndication->Port;
olav 0:4c1fcbfcc7bf 286 LoRaMacDownlinkStatus.Buffer = McpsIndication->Buffer;
olav 0:4c1fcbfcc7bf 287 LoRaMacDownlinkStatus.BufferSize = McpsIndication->BufferSize;
olav 0:4c1fcbfcc7bf 288
olav 0:4c1fcbfcc7bf 289 if( McpsIndication->RxData == true )
olav 0:4c1fcbfcc7bf 290 {
olav 0:4c1fcbfcc7bf 291 printf("Got a nice thingie! \r\n");
olav 0:4c1fcbfcc7bf 292 switch( McpsIndication->Port )
olav 0:4c1fcbfcc7bf 293 {
olav 0:4c1fcbfcc7bf 294 case 1:
olav 0:4c1fcbfcc7bf 295 printf("Logic for port1 %u\r\n", McpsIndication->Buffer[0]);
olav 0:4c1fcbfcc7bf 296 if( McpsIndication->BufferSize == 1 )
olav 0:4c1fcbfcc7bf 297 {
olav 0:4c1fcbfcc7bf 298 led1 = !McpsIndication->Buffer[0];
olav 0:4c1fcbfcc7bf 299 }
olav 0:4c1fcbfcc7bf 300 break;
olav 0:4c1fcbfcc7bf 301 case 2:
olav 0:4c1fcbfcc7bf 302 printf("Logic for port2 %u\r\n", McpsIndication->Buffer[0]);
olav 0:4c1fcbfcc7bf 303 if( McpsIndication->BufferSize == 1 )
olav 0:4c1fcbfcc7bf 304 {
olav 0:4c1fcbfcc7bf 305 led2 = !McpsIndication->Buffer[0];
olav 0:4c1fcbfcc7bf 306 }
olav 0:4c1fcbfcc7bf 307 break;
olav 0:4c1fcbfcc7bf 308 default:
olav 0:4c1fcbfcc7bf 309 break;
olav 0:4c1fcbfcc7bf 310 }
olav 0:4c1fcbfcc7bf 311 }
olav 0:4c1fcbfcc7bf 312 }
olav 0:4c1fcbfcc7bf 313
olav 0:4c1fcbfcc7bf 314 /*!
olav 0:4c1fcbfcc7bf 315 * \brief MLME-Confirm event function
olav 0:4c1fcbfcc7bf 316 *
olav 0:4c1fcbfcc7bf 317 * \param [IN] MlmeConfirm - Pointer to the confirm structure,
olav 0:4c1fcbfcc7bf 318 * containing confirm attributes.
olav 0:4c1fcbfcc7bf 319 */
olav 0:4c1fcbfcc7bf 320 static void MlmeConfirm( MlmeConfirm_t *MlmeConfirm )
olav 0:4c1fcbfcc7bf 321 {
olav 0:4c1fcbfcc7bf 322 if( MlmeConfirm->Status == LORAMAC_EVENT_INFO_STATUS_OK )
olav 0:4c1fcbfcc7bf 323 {
olav 0:4c1fcbfcc7bf 324 switch( MlmeConfirm->MlmeRequest )
olav 0:4c1fcbfcc7bf 325 {
olav 0:4c1fcbfcc7bf 326 case MLME_JOIN:
olav 0:4c1fcbfcc7bf 327 {
olav 0:4c1fcbfcc7bf 328 printf("We joined! \r\n");
olav 0:4c1fcbfcc7bf 329 // Status is OK, node has joined the network
olav 0:4c1fcbfcc7bf 330 IsNetworkJoinedStatusUpdate = true;
olav 0:4c1fcbfcc7bf 331 break;
olav 0:4c1fcbfcc7bf 332 }
olav 0:4c1fcbfcc7bf 333 default:
olav 0:4c1fcbfcc7bf 334 break;
olav 0:4c1fcbfcc7bf 335 }
olav 0:4c1fcbfcc7bf 336 }
olav 0:4c1fcbfcc7bf 337 NextTx = true;
olav 0:4c1fcbfcc7bf 338 }
olav 0:4c1fcbfcc7bf 339
olav 0:4c1fcbfcc7bf 340 /*!
olav 0:4c1fcbfcc7bf 341 * \brief Prepares the payload of the frame
olav 0:4c1fcbfcc7bf 342 *
olav 0:4c1fcbfcc7bf 343 * \retval [0: frame could be send, 1: error]
olav 0:4c1fcbfcc7bf 344 */
olav 0:4c1fcbfcc7bf 345 static bool SendFrame( void )
olav 0:4c1fcbfcc7bf 346 {
olav 0:4c1fcbfcc7bf 347 printf("Sending!\r\n");
olav 0:4c1fcbfcc7bf 348 McpsReq_t mcpsReq;
olav 0:4c1fcbfcc7bf 349 LoRaMacTxInfo_t txInfo;
olav 0:4c1fcbfcc7bf 350
olav 0:4c1fcbfcc7bf 351 if( LoRaMacQueryTxPossible( AppDataSize, &txInfo ) != LORAMAC_STATUS_OK )
olav 0:4c1fcbfcc7bf 352 {
olav 0:4c1fcbfcc7bf 353 printf("Flush mac\r\n");
olav 0:4c1fcbfcc7bf 354 // Send empty frame in order to flush MAC commands
olav 0:4c1fcbfcc7bf 355 mcpsReq.Type = MCPS_UNCONFIRMED;
olav 0:4c1fcbfcc7bf 356 mcpsReq.Req.Unconfirmed.fBuffer = NULL;
olav 0:4c1fcbfcc7bf 357 mcpsReq.Req.Unconfirmed.fBufferSize = 0;
olav 0:4c1fcbfcc7bf 358 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
olav 0:4c1fcbfcc7bf 359 }
olav 0:4c1fcbfcc7bf 360 else
olav 0:4c1fcbfcc7bf 361 {
olav 0:4c1fcbfcc7bf 362 if( IsTxConfirmed == false )
olav 0:4c1fcbfcc7bf 363 {
olav 0:4c1fcbfcc7bf 364 mcpsReq.Type = MCPS_UNCONFIRMED;
olav 0:4c1fcbfcc7bf 365 mcpsReq.Req.Unconfirmed.fPort = AppPort;
olav 0:4c1fcbfcc7bf 366 mcpsReq.Req.Unconfirmed.fBuffer = AppData;
olav 0:4c1fcbfcc7bf 367 mcpsReq.Req.Unconfirmed.fBufferSize = AppDataSize;
olav 0:4c1fcbfcc7bf 368 mcpsReq.Req.Unconfirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
olav 0:4c1fcbfcc7bf 369 }
olav 0:4c1fcbfcc7bf 370 else
olav 0:4c1fcbfcc7bf 371 {
olav 0:4c1fcbfcc7bf 372 mcpsReq.Type = MCPS_CONFIRMED;
olav 0:4c1fcbfcc7bf 373 mcpsReq.Req.Confirmed.fPort = AppPort;
olav 0:4c1fcbfcc7bf 374 mcpsReq.Req.Confirmed.fBuffer = AppData;
olav 0:4c1fcbfcc7bf 375 mcpsReq.Req.Confirmed.fBufferSize = AppDataSize;
olav 0:4c1fcbfcc7bf 376 mcpsReq.Req.Confirmed.NbTrials = 8;
olav 0:4c1fcbfcc7bf 377 mcpsReq.Req.Confirmed.Datarate = LORAWAN_DEFAULT_DATARATE;
olav 0:4c1fcbfcc7bf 378 }
olav 0:4c1fcbfcc7bf 379 }
olav 0:4c1fcbfcc7bf 380 if( LoRaMacMcpsRequest( &mcpsReq ) == LORAMAC_STATUS_OK )
olav 0:4c1fcbfcc7bf 381 {
olav 0:4c1fcbfcc7bf 382 return false;
olav 0:4c1fcbfcc7bf 383 }
olav 0:4c1fcbfcc7bf 384
olav 0:4c1fcbfcc7bf 385 return true;
olav 0:4c1fcbfcc7bf 386 }
olav 0:4c1fcbfcc7bf 387
olav 0:4c1fcbfcc7bf 388 /*!
olav 0:4c1fcbfcc7bf 389 * \brief Function executed on TxNextPacket Timeout event
olav 0:4c1fcbfcc7bf 390 */
olav 0:4c1fcbfcc7bf 391 static void OnTxNextPacketTimerEvent( void )
olav 0:4c1fcbfcc7bf 392 {
olav 0:4c1fcbfcc7bf 393 LoRaMacStatus_t status;
olav 0:4c1fcbfcc7bf 394 status = LoRaMacMibGetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 395
olav 0:4c1fcbfcc7bf 396 TimerStop( &TxNextPacketTimer );
olav 0:4c1fcbfcc7bf 397
olav 0:4c1fcbfcc7bf 398 if( status == LORAMAC_STATUS_OK )
olav 0:4c1fcbfcc7bf 399 {
olav 0:4c1fcbfcc7bf 400 if( mibReq.Param.IsNetworkJoined == true )
olav 0:4c1fcbfcc7bf 401 {
olav 0:4c1fcbfcc7bf 402 //DeviceState = DEVICE_STATE_SEND;
olav 0:4c1fcbfcc7bf 403 DeviceState = DEVICE_STATE_SLEEP;
olav 0:4c1fcbfcc7bf 404 NextTx = true;
olav 0:4c1fcbfcc7bf 405 }
olav 0:4c1fcbfcc7bf 406 else
olav 0:4c1fcbfcc7bf 407 {
olav 0:4c1fcbfcc7bf 408 DeviceState = DEVICE_STATE_JOIN;
olav 0:4c1fcbfcc7bf 409 }
olav 0:4c1fcbfcc7bf 410 }
olav 0:4c1fcbfcc7bf 411 }
olav 0:4c1fcbfcc7bf 412
olav 0:4c1fcbfcc7bf 413 void buttonPressedCallback(void)
olav 0:4c1fcbfcc7bf 414 {
olav 0:4c1fcbfcc7bf 415 printf("Button pressed \r\n");
olav 0:4c1fcbfcc7bf 416 PrepareTxFrame( AppPort );
olav 0:4c1fcbfcc7bf 417 NextTx = SendFrame( );
olav 0:4c1fcbfcc7bf 418 printf("res: %d \r\n",NextTx);
olav 0:4c1fcbfcc7bf 419 }
olav 0:4c1fcbfcc7bf 420
olav 0:4c1fcbfcc7bf 421 int main( void )
olav 0:4c1fcbfcc7bf 422 {
olav 0:4c1fcbfcc7bf 423
olav 0:4c1fcbfcc7bf 424 button.fall(buttonPressedCallback);
olav 0:4c1fcbfcc7bf 425
olav 0:4c1fcbfcc7bf 426 printf("Hello world! \r\n");
olav 0:4c1fcbfcc7bf 427 LoRaMacPrimitives_t LoRaMacPrimitives;
olav 0:4c1fcbfcc7bf 428 LoRaMacCallback_t LoRaMacCallbacks;
olav 0:4c1fcbfcc7bf 429
olav 0:4c1fcbfcc7bf 430 BoardInit( );
olav 0:4c1fcbfcc7bf 431
olav 0:4c1fcbfcc7bf 432 DeviceState = DEVICE_STATE_INIT;
olav 0:4c1fcbfcc7bf 433
olav 0:4c1fcbfcc7bf 434 while( 1 )
olav 0:4c1fcbfcc7bf 435 {
olav 0:4c1fcbfcc7bf 436 if (DeviceState != DEVICE_STATE_SLEEP)
olav 0:4c1fcbfcc7bf 437 printf("State: %d \r\n", DeviceState);
olav 0:4c1fcbfcc7bf 438
olav 0:4c1fcbfcc7bf 439 if( IsNetworkJoinedStatusUpdate == true )
olav 0:4c1fcbfcc7bf 440 {
olav 0:4c1fcbfcc7bf 441 printf("Joined okay \r\n");
olav 0:4c1fcbfcc7bf 442 IsNetworkJoinedStatusUpdate = false;
olav 0:4c1fcbfcc7bf 443 mibReq.Type = MIB_NETWORK_JOINED;
olav 0:4c1fcbfcc7bf 444 LoRaMacMibGetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 445 }
olav 0:4c1fcbfcc7bf 446 switch( DeviceState )
olav 0:4c1fcbfcc7bf 447 {
olav 0:4c1fcbfcc7bf 448 case DEVICE_STATE_INIT:
olav 0:4c1fcbfcc7bf 449 {
olav 0:4c1fcbfcc7bf 450 LoRaMacPrimitives.MacMcpsConfirm = McpsConfirm;
olav 0:4c1fcbfcc7bf 451 LoRaMacPrimitives.MacMcpsIndication = McpsIndication;
olav 0:4c1fcbfcc7bf 452 LoRaMacPrimitives.MacMlmeConfirm = MlmeConfirm;
olav 0:4c1fcbfcc7bf 453 LoRaMacCallbacks.GetBatteryLevel = BoardGetBatteryLevel;
olav 0:4c1fcbfcc7bf 454 LoRaMacInitialization( &LoRaMacPrimitives, &LoRaMacCallbacks );
olav 0:4c1fcbfcc7bf 455
olav 0:4c1fcbfcc7bf 456 TimerInit( &TxNextPacketTimer, OnTxNextPacketTimerEvent );
olav 0:4c1fcbfcc7bf 457 mibReq.Type = MIB_ADR;
olav 0:4c1fcbfcc7bf 458 mibReq.Param.AdrEnable = LORAWAN_ADR_ON;
olav 0:4c1fcbfcc7bf 459 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 460
olav 0:4c1fcbfcc7bf 461 mibReq.Type = MIB_PUBLIC_NETWORK;
olav 0:4c1fcbfcc7bf 462 mibReq.Param.EnablePublicNetwork = LORAWAN_PUBLIC_NETWORK;
olav 0:4c1fcbfcc7bf 463 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 464
olav 0:4c1fcbfcc7bf 465 LoRaMacTestSetDutyCycleOn( false );
olav 0:4c1fcbfcc7bf 466
olav 0:4c1fcbfcc7bf 467 DeviceState = DEVICE_STATE_JOIN;
olav 0:4c1fcbfcc7bf 468 break;
olav 0:4c1fcbfcc7bf 469 }
olav 0:4c1fcbfcc7bf 470 case DEVICE_STATE_JOIN:
olav 0:4c1fcbfcc7bf 471 {
olav 0:4c1fcbfcc7bf 472 #if( OVER_THE_AIR_ACTIVATION != 0 )
olav 0:4c1fcbfcc7bf 473 MlmeReq_t mlmeReq;
olav 0:4c1fcbfcc7bf 474
olav 0:4c1fcbfcc7bf 475 mlmeReq.Type = MLME_JOIN;
olav 0:4c1fcbfcc7bf 476
olav 0:4c1fcbfcc7bf 477 mlmeReq.Req.Join.DevEui = DevEui;
olav 0:4c1fcbfcc7bf 478 mlmeReq.Req.Join.AppEui = AppEui;
olav 0:4c1fcbfcc7bf 479 mlmeReq.Req.Join.AppKey = AppKey;
olav 0:4c1fcbfcc7bf 480
olav 0:4c1fcbfcc7bf 481 if( NextTx == true )
olav 0:4c1fcbfcc7bf 482 {
olav 0:4c1fcbfcc7bf 483 LoRaMacMlmeRequest( &mlmeReq );
olav 0:4c1fcbfcc7bf 484 }
olav 0:4c1fcbfcc7bf 485
olav 0:4c1fcbfcc7bf 486 // Schedule next packet transmission
olav 0:4c1fcbfcc7bf 487 TxDutyCycleTime = OVER_THE_AIR_ACTIVATION_DUTYCYCLE;
olav 0:4c1fcbfcc7bf 488 DeviceState = DEVICE_STATE_CYCLE;
olav 0:4c1fcbfcc7bf 489
olav 0:4c1fcbfcc7bf 490 #else
olav 0:4c1fcbfcc7bf 491 mibReq.Type = MIB_NET_ID;
olav 0:4c1fcbfcc7bf 492 mibReq.Param.NetID = LORAWAN_NETWORK_ID;
olav 0:4c1fcbfcc7bf 493 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 494
olav 0:4c1fcbfcc7bf 495 mibReq.Type = MIB_DEV_ADDR;
olav 0:4c1fcbfcc7bf 496 mibReq.Param.DevAddr = DevAddr;
olav 0:4c1fcbfcc7bf 497 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 498
olav 0:4c1fcbfcc7bf 499 mibReq.Type = MIB_NWK_SKEY;
olav 0:4c1fcbfcc7bf 500 mibReq.Param.NwkSKey = NwkSKey;
olav 0:4c1fcbfcc7bf 501 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 502
olav 0:4c1fcbfcc7bf 503 mibReq.Type = MIB_APP_SKEY;
olav 0:4c1fcbfcc7bf 504 mibReq.Param.AppSKey = AppSKey;
olav 0:4c1fcbfcc7bf 505 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 506
olav 0:4c1fcbfcc7bf 507 mibReq.Type = MIB_NETWORK_JOINED;
olav 0:4c1fcbfcc7bf 508 mibReq.Param.IsNetworkJoined = true;
olav 0:4c1fcbfcc7bf 509 LoRaMacMibSetRequestConfirm( &mibReq );
olav 0:4c1fcbfcc7bf 510
olav 0:4c1fcbfcc7bf 511 DeviceState = DEVICE_STATE_SEND;
olav 0:4c1fcbfcc7bf 512 #endif
olav 0:4c1fcbfcc7bf 513 IsNetworkJoinedStatusUpdate = true;
olav 0:4c1fcbfcc7bf 514 break;
olav 0:4c1fcbfcc7bf 515 }
olav 0:4c1fcbfcc7bf 516 case DEVICE_STATE_SEND:
olav 0:4c1fcbfcc7bf 517 {
olav 0:4c1fcbfcc7bf 518 if( NextTx == true )
olav 0:4c1fcbfcc7bf 519 {
olav 0:4c1fcbfcc7bf 520 printf("Send a frame! \r\n");
olav 0:4c1fcbfcc7bf 521 PrepareTxFrame( AppPort );
olav 0:4c1fcbfcc7bf 522
olav 0:4c1fcbfcc7bf 523 NextTx = SendFrame( );
olav 0:4c1fcbfcc7bf 524
olav 0:4c1fcbfcc7bf 525 }
olav 0:4c1fcbfcc7bf 526
olav 0:4c1fcbfcc7bf 527 // Schedule next packet transmission
olav 0:4c1fcbfcc7bf 528 TxDutyCycleTime = APP_TX_DUTYCYCLE + randr( -APP_TX_DUTYCYCLE_RND, APP_TX_DUTYCYCLE_RND );
olav 0:4c1fcbfcc7bf 529
olav 0:4c1fcbfcc7bf 530 DeviceState = DEVICE_STATE_CYCLE;
olav 0:4c1fcbfcc7bf 531 break;
olav 0:4c1fcbfcc7bf 532 }
olav 0:4c1fcbfcc7bf 533 case DEVICE_STATE_CYCLE:
olav 0:4c1fcbfcc7bf 534 {
olav 0:4c1fcbfcc7bf 535 // Schedule next packet transmission
olav 0:4c1fcbfcc7bf 536 printf("Do some cycling .. \r\n");
olav 0:4c1fcbfcc7bf 537 TimerSetValue( &TxNextPacketTimer, TxDutyCycleTime );
olav 0:4c1fcbfcc7bf 538 TimerStart( &TxNextPacketTimer );
olav 0:4c1fcbfcc7bf 539
olav 0:4c1fcbfcc7bf 540 DeviceState = DEVICE_STATE_SLEEP;
olav 0:4c1fcbfcc7bf 541 break;
olav 0:4c1fcbfcc7bf 542 }
olav 0:4c1fcbfcc7bf 543 case DEVICE_STATE_SLEEP:
olav 0:4c1fcbfcc7bf 544 {
olav 0:4c1fcbfcc7bf 545 // Wake up through events
olav 0:4c1fcbfcc7bf 546 break;
olav 0:4c1fcbfcc7bf 547 }
olav 0:4c1fcbfcc7bf 548 default:
olav 0:4c1fcbfcc7bf 549 {
olav 0:4c1fcbfcc7bf 550 DeviceState = DEVICE_STATE_INIT;
olav 0:4c1fcbfcc7bf 551 break;
olav 0:4c1fcbfcc7bf 552 }
olav 0:4c1fcbfcc7bf 553 }
olav 0:4c1fcbfcc7bf 554 }
olav 0:4c1fcbfcc7bf 555 }