lora experiments
Dependencies: BLE_API LoRaWAN-lib SX1276Lib mbed nRF51822 HCSR04Lib
Fork of LoRa by
main.cpp@0:4c1fcbfcc7bf, 2016-05-09 (annotated)
- Committer:
- olav
- Date:
- Mon May 09 08:06:21 2016 +0000
- Revision:
- 0:4c1fcbfcc7bf
- Child:
- 2:ce7cea075e95
initial commit
Who changed what in which revision?
User | Revision | Line number | New 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 | } |