IBM LoRa MAC in C (LMiC) mbed library port

Dependents:   lora-temperature LoRaWAN-lmic-app_HS LoRaWAN-lmic-app_huynh

LoRa WAN in C for sx1276 shield

Currently version 1.5


LoRaWAN network configuration for end-device

The following three pieces of information uniquely identifies end-device to network to allow over-the-air activation. These are stored in the end-device prior to join procedure.

AppEUI

Uniquely identifies application provider of end-device.

Least-significant byte first, 8 bytes, use reverse memcpy() to keep same order as shown on lora server.

example C code

static const u1_t APPEUI[8]  = { 0x01, 0x00, 0x01, 0x00, 0x00, 0x0C, 0x25, 0x00 };

This is copied into LMIC by os_getArtEui() callback function in application.

DevEUI

End-device ID, unique to each end-node.

Least-significant byte first, 8 bytes, use reverse memcpy() to keep same order as shown on lora server.

example C code

static const u1_t DEVEUI[8]  = { 0x00, 0x00, 0x00, 0x00, 0x01, 0x0C, 0x25, 0x00 }; 

This is copied into LMIC by os_getDevEui() callback function in application.

AppKey (aka DevKey)

128-bit (16byte) AES key.

example C code

static const u1_t DEVKEY[16] = { 0xe4, 0x72, 0x71, 0xc5, 0xf5, 0x30, 0xa9, 0x9f, 0xcf, 0xc4, 0x0e, 0xab, 0xea, 0xd7, 0x19, 0x42 };

This is copied into LMIC by os_getDevKey() callback function in application.

Using over-the air activation, the end-device (LMIC) performs a join procedure every time it starts for first time, or has lost session context information. When join procedure has successfully completed, the end-device will have a network session key (NwkSKey) and an application session key (AppSKey), which are used for encryption and message integrity check.


US915 configuration with http://us01-iot.semtech.com/

  • log in to server
  • click on Applications
  • find your application and click it
  • go to configure motes
  • to create a mote, you may enter a new DevEUI
    • you may copy-paste the 16byte application key from an already existing mote, if you desire.
CHNL_HYBRID125KHz500KHz
defined valuechannelschannel
00 to 764
18 to 1565
216 to 2366
324 to 3167
432 to 3968
540 to 4769
648 to 5570
756 to 6371
undef0 to 6364 to 71
Committer:
mluis
Date:
Thu Nov 26 17:17:08 2015 +0000
Revision:
4:85b2b647cb64
Parent:
3:519c71d29a06
Parent:
2:974cafbfb159
Merged branches

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mluis 0:62d1edcc13d1 1 /*******************************************************************************
mluis 1:d3b7bde3995c 2 * Copyright (c) 2014-2015 IBM Corporation.
mluis 0:62d1edcc13d1 3 * All rights reserved. This program and the accompanying materials
mluis 0:62d1edcc13d1 4 * are made available under the terms of the Eclipse Public License v1.0
mluis 0:62d1edcc13d1 5 * which accompanies this distribution, and is available at
mluis 0:62d1edcc13d1 6 * http://www.eclipse.org/legal/epl-v10.html
mluis 0:62d1edcc13d1 7 *
mluis 0:62d1edcc13d1 8 * Contributors:
mluis 0:62d1edcc13d1 9 * IBM Zurich Research Lab - initial API, implementation and documentation
mluis 0:62d1edcc13d1 10 * Semtech Apps Team - Modified to support the MBED sx1276 driver
mluis 0:62d1edcc13d1 11 * library.
mluis 0:62d1edcc13d1 12 * Possibility to use original or Semtech's MBED
mluis 0:62d1edcc13d1 13 * radio driver. The selection is done by setting
mluis 0:62d1edcc13d1 14 * USE_SMTC_RADIO_DRIVER preprocessing directive
mluis 0:62d1edcc13d1 15 * in lmic.h
mluis 0:62d1edcc13d1 16 *******************************************************************************/
mluis 1:d3b7bde3995c 17
mluis 0:62d1edcc13d1 18 #include "lmic.h"
mluis 0:62d1edcc13d1 19
mluis 0:62d1edcc13d1 20 #if USE_SMTC_RADIO_DRIVER
mluis 0:62d1edcc13d1 21 #include "sx1276-hal.h"
mluis 0:62d1edcc13d1 22
mluis 0:62d1edcc13d1 23 /*!
mluis 1:d3b7bde3995c 24 * Syncword for lora networks
mluis 0:62d1edcc13d1 25 */
mluis 1:d3b7bde3995c 26 #define LORA_MAC_SYNCWORD 0x34
mluis 0:62d1edcc13d1 27
mluis 0:62d1edcc13d1 28 /*
mluis 0:62d1edcc13d1 29 * Callback functions prototypes
mluis 0:62d1edcc13d1 30 */
mluis 0:62d1edcc13d1 31 /*!
mluis 0:62d1edcc13d1 32 * @brief Function to be executed on Radio Tx Done event
mluis 0:62d1edcc13d1 33 */
mluis 0:62d1edcc13d1 34 void OnTxDone( void );
mluis 0:62d1edcc13d1 35
mluis 0:62d1edcc13d1 36 /*!
mluis 0:62d1edcc13d1 37 * @brief Function to be executed on Radio Rx Done event
mluis 0:62d1edcc13d1 38 */
mluis 0:62d1edcc13d1 39 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr );
mluis 0:62d1edcc13d1 40
mluis 0:62d1edcc13d1 41 /*!
mluis 0:62d1edcc13d1 42 * @brief Function executed on Radio Tx Timeout event
mluis 0:62d1edcc13d1 43 */
mluis 0:62d1edcc13d1 44 void OnTxTimeout( void );
mluis 0:62d1edcc13d1 45
mluis 0:62d1edcc13d1 46 /*!
mluis 0:62d1edcc13d1 47 * @brief Function executed on Radio Rx Timeout event
mluis 0:62d1edcc13d1 48 */
mluis 0:62d1edcc13d1 49 void OnRxTimeout( void );
mluis 0:62d1edcc13d1 50
mluis 0:62d1edcc13d1 51 /*!
mluis 0:62d1edcc13d1 52 * @brief Function executed on Radio Rx Error event
mluis 0:62d1edcc13d1 53 */
mluis 0:62d1edcc13d1 54 void OnRxError( void );
mluis 0:62d1edcc13d1 55
mluis 0:62d1edcc13d1 56 /*!
mluis 0:62d1edcc13d1 57 * @brief Function executed on Radio Fhss Change Channel event
mluis 0:62d1edcc13d1 58 */
mluis 0:62d1edcc13d1 59 void OnFhssChangeChannel( uint8_t channelIndex );
mluis 0:62d1edcc13d1 60
mluis 0:62d1edcc13d1 61 /*!
mluis 0:62d1edcc13d1 62 * @brief Function executed on CAD Done event
mluis 0:62d1edcc13d1 63 */
mluis 0:62d1edcc13d1 64 void OnCadDone( void );
mluis 0:62d1edcc13d1 65
mluis 3:519c71d29a06 66 /*!
mluis 3:519c71d29a06 67 * Radio events function pointer
mluis 3:519c71d29a06 68 */
mluis 3:519c71d29a06 69 static RadioEvents_t RadioEvents;
mluis 3:519c71d29a06 70
mluis 0:62d1edcc13d1 71 /*
mluis 0:62d1edcc13d1 72 * Radio object declraration
mluis 0:62d1edcc13d1 73 */
mluis 3:519c71d29a06 74 SX1276MB1xAS Radio( NULL );
mluis 0:62d1edcc13d1 75
mluis 0:62d1edcc13d1 76 static const u2_t LORA_RXDONE_FIXUP[] = {
mluis 0:62d1edcc13d1 77 [FSK] = us2osticks(0), // ( 0 ticks)
mluis 0:62d1edcc13d1 78 [SF7] = us2osticks(0), // ( 0 ticks)
mluis 0:62d1edcc13d1 79 [SF8] = us2osticks(1648), // ( 54 ticks)
mluis 0:62d1edcc13d1 80 [SF9] = us2osticks(3265), // ( 107 ticks)
mluis 0:62d1edcc13d1 81 [SF10] = us2osticks(7049), // ( 231 ticks)
mluis 0:62d1edcc13d1 82 [SF11] = us2osticks(13641), // ( 447 ticks)
mluis 0:62d1edcc13d1 83 [SF12] = us2osticks(31189), // (1022 ticks)
mluis 0:62d1edcc13d1 84 };
mluis 0:62d1edcc13d1 85
mluis 0:62d1edcc13d1 86 void OnTxDone( void )
mluis 0:62d1edcc13d1 87 {
mluis 0:62d1edcc13d1 88 ostime_t now = os_getTime( );
mluis 0:62d1edcc13d1 89 // save exact tx time
mluis 1:d3b7bde3995c 90 LMIC.txend = now - us2osticks( RADIO_WAKEUP_TIME ); // TXDONE FIXUP
mluis 0:62d1edcc13d1 91
mluis 0:62d1edcc13d1 92 // go from stanby to sleep
mluis 0:62d1edcc13d1 93 Radio.Sleep( );
mluis 0:62d1edcc13d1 94 // run os job (use preset func ptr)
mluis 0:62d1edcc13d1 95 os_setCallback( &LMIC.osjob, LMIC.osjob.func );
mluis 0:62d1edcc13d1 96 }
mluis 0:62d1edcc13d1 97
mluis 0:62d1edcc13d1 98 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr )
mluis 0:62d1edcc13d1 99 {
mluis 0:62d1edcc13d1 100 ostime_t now = os_getTime( );
mluis 0:62d1edcc13d1 101 // save exact rx time
mluis 1:d3b7bde3995c 102 if( getBw( LMIC.rps ) == BW125 )
mluis 1:d3b7bde3995c 103 {
mluis 1:d3b7bde3995c 104 now -= LORA_RXDONE_FIXUP[getSf( LMIC.rps )];
mluis 1:d3b7bde3995c 105 }
mluis 1:d3b7bde3995c 106 LMIC.rxtime = now;
mluis 0:62d1edcc13d1 107 // read the PDU and inform the MAC that we received something
mluis 0:62d1edcc13d1 108 LMIC.dataLen = size;
mluis 0:62d1edcc13d1 109 // now read the FIFO
mluis 0:62d1edcc13d1 110 memcpy( LMIC.frame, payload, size );
mluis 0:62d1edcc13d1 111 // read rx quality parameters
mluis 1:d3b7bde3995c 112 LMIC.snr = snr; // SNR [dB] * 4
mluis 1:d3b7bde3995c 113 LMIC.rssi = rssi; // RSSI [dBm] (-196...+63)
mluis 0:62d1edcc13d1 114
mluis 0:62d1edcc13d1 115 // go from stanby to sleep
mluis 0:62d1edcc13d1 116 Radio.Sleep( );
mluis 0:62d1edcc13d1 117 // run os job (use preset func ptr)
mluis 0:62d1edcc13d1 118 os_setCallback( &LMIC.osjob, LMIC.osjob.func );
mluis 0:62d1edcc13d1 119 }
mluis 0:62d1edcc13d1 120
mluis 0:62d1edcc13d1 121 void OnTxTimeout( void )
mluis 0:62d1edcc13d1 122 {
mluis 0:62d1edcc13d1 123 ostime_t now = os_getTime( );
mluis 0:62d1edcc13d1 124
mluis 0:62d1edcc13d1 125 // indicate error
mluis 1:d3b7bde3995c 126 LMIC.dataLen = 0;
mluis 1:d3b7bde3995c 127
mluis 0:62d1edcc13d1 128 // go from stanby to sleep
mluis 0:62d1edcc13d1 129 Radio.Sleep( );
mluis 0:62d1edcc13d1 130 // run os job (use preset func ptr)
mluis 0:62d1edcc13d1 131 os_setCallback( &LMIC.osjob, LMIC.osjob.func );
mluis 0:62d1edcc13d1 132 }
mluis 0:62d1edcc13d1 133
mluis 0:62d1edcc13d1 134 void OnRxTimeout( void )
mluis 0:62d1edcc13d1 135 {
mluis 0:62d1edcc13d1 136 ostime_t now = os_getTime( );
mluis 0:62d1edcc13d1 137 // indicate timeout
mluis 0:62d1edcc13d1 138 LMIC.dataLen = 0;
mluis 0:62d1edcc13d1 139
mluis 0:62d1edcc13d1 140 // go from stanby to sleep
mluis 0:62d1edcc13d1 141 Radio.Sleep( );
mluis 0:62d1edcc13d1 142 // run os job (use preset func ptr)
mluis 0:62d1edcc13d1 143 os_setCallback( &LMIC.osjob, LMIC.osjob.func );
mluis 0:62d1edcc13d1 144 }
mluis 0:62d1edcc13d1 145
mluis 0:62d1edcc13d1 146 void OnRxError( void )
mluis 0:62d1edcc13d1 147 {
mluis 0:62d1edcc13d1 148 ostime_t now = os_getTime( );
mluis 0:62d1edcc13d1 149
mluis 0:62d1edcc13d1 150 // indicate error
mluis 0:62d1edcc13d1 151 LMIC.dataLen = 0;
mluis 0:62d1edcc13d1 152
mluis 0:62d1edcc13d1 153 // go from stanby to sleep
mluis 0:62d1edcc13d1 154 Radio.Sleep( );
mluis 0:62d1edcc13d1 155 // run os job (use preset func ptr)
mluis 0:62d1edcc13d1 156 os_setCallback( &LMIC.osjob, LMIC.osjob.func );
mluis 0:62d1edcc13d1 157 }
mluis 0:62d1edcc13d1 158
mluis 0:62d1edcc13d1 159 /*!
mluis 0:62d1edcc13d1 160 * LMIC API implementation
mluis 0:62d1edcc13d1 161 */
mluis 0:62d1edcc13d1 162 // RADIO STATE
mluis 0:62d1edcc13d1 163 // (initialized by radio_init( ), used by radio_rand1( ))
mluis 0:62d1edcc13d1 164 static u1_t randbuf[16];
mluis 0:62d1edcc13d1 165
mluis 0:62d1edcc13d1 166 // get random seed from wideband noise rssi
mluis 0:62d1edcc13d1 167 void radio_init( void )
mluis 0:62d1edcc13d1 168 {
mluis 0:62d1edcc13d1 169 hal_disableIRQs( );
mluis 3:519c71d29a06 170
mluis 3:519c71d29a06 171 // Initialize Radio driver
mluis 3:519c71d29a06 172 RadioEvents.TxDone = OnTxDone;
mluis 3:519c71d29a06 173 RadioEvents.RxDone = OnRxDone;
mluis 3:519c71d29a06 174 RadioEvents.RxError = OnRxError;
mluis 3:519c71d29a06 175 RadioEvents.TxTimeout = OnTxTimeout;
mluis 3:519c71d29a06 176 RadioEvents.RxTimeout = OnRxTimeout;
mluis 3:519c71d29a06 177 Radio.Init( &RadioEvents );
mluis 0:62d1edcc13d1 178
mluis 0:62d1edcc13d1 179 // seed 15-byte randomness via noise rssi
mluis 0:62d1edcc13d1 180 // Set LoRa modem ON
mluis 0:62d1edcc13d1 181 Radio.SetModem( MODEM_LORA );
mluis 0:62d1edcc13d1 182 // Disable LoRa modem interrupts
mluis 0:62d1edcc13d1 183 Radio.Write( REG_LR_IRQFLAGSMASK, RFLR_IRQFLAGS_RXTIMEOUT |
mluis 0:62d1edcc13d1 184 RFLR_IRQFLAGS_RXDONE |
mluis 0:62d1edcc13d1 185 RFLR_IRQFLAGS_PAYLOADCRCERROR |
mluis 0:62d1edcc13d1 186 RFLR_IRQFLAGS_VALIDHEADER |
mluis 0:62d1edcc13d1 187 RFLR_IRQFLAGS_TXDONE |
mluis 0:62d1edcc13d1 188 RFLR_IRQFLAGS_CADDONE |
mluis 0:62d1edcc13d1 189 RFLR_IRQFLAGS_FHSSCHANGEDCHANNEL |
mluis 0:62d1edcc13d1 190 RFLR_IRQFLAGS_CADDETECTED );
mluis 0:62d1edcc13d1 191
mluis 0:62d1edcc13d1 192 // Set radio in continuous reception
mluis 0:62d1edcc13d1 193 Radio.Rx( 0 );
mluis 0:62d1edcc13d1 194
mluis 0:62d1edcc13d1 195 for( int i = 1; i < 16; i++ )
mluis 0:62d1edcc13d1 196 {
mluis 0:62d1edcc13d1 197 for( int j = 0; j < 8; j++ )
mluis 0:62d1edcc13d1 198 {
mluis 0:62d1edcc13d1 199 u1_t b; // wait for two non-identical subsequent least-significant bits
mluis 0:62d1edcc13d1 200 while( ( b = Radio.Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) == ( Radio.Read( REG_LR_RSSIWIDEBAND ) & 0x01 ) );
mluis 0:62d1edcc13d1 201 randbuf[i] = ( randbuf[i] << 1 ) | b;
mluis 0:62d1edcc13d1 202 }
mluis 0:62d1edcc13d1 203 }
mluis 0:62d1edcc13d1 204 randbuf[0] = 16; // set initial index
mluis 0:62d1edcc13d1 205
mluis 0:62d1edcc13d1 206 // Change LoRa modem SyncWord
mluis 0:62d1edcc13d1 207 Radio.Write( REG_LR_SYNCWORD, LORA_MAC_SYNCWORD );
mluis 0:62d1edcc13d1 208
mluis 0:62d1edcc13d1 209 Radio.Sleep( );
mluis 0:62d1edcc13d1 210
mluis 0:62d1edcc13d1 211 hal_enableIRQs( );
mluis 0:62d1edcc13d1 212 }
mluis 0:62d1edcc13d1 213
mluis 0:62d1edcc13d1 214 // return next random byte derived from seed buffer
mluis 0:62d1edcc13d1 215 // (buf[0] holds index of next byte to be returned)
mluis 0:62d1edcc13d1 216 u1_t radio_rand1( void )
mluis 0:62d1edcc13d1 217 {
mluis 0:62d1edcc13d1 218 u1_t i = randbuf[0];
mluis 0:62d1edcc13d1 219 ASSERT( i != 0 );
mluis 0:62d1edcc13d1 220 if( i == 16 )
mluis 0:62d1edcc13d1 221 {
mluis 0:62d1edcc13d1 222 os_aes( AES_ENC, randbuf, 16 ); // encrypt seed with any key
mluis 0:62d1edcc13d1 223 i = 0;
mluis 0:62d1edcc13d1 224 }
mluis 0:62d1edcc13d1 225 u1_t v = randbuf[i++];
mluis 0:62d1edcc13d1 226 randbuf[0] = i;
mluis 0:62d1edcc13d1 227 return v;
mluis 0:62d1edcc13d1 228 }
mluis 0:62d1edcc13d1 229
mluis 0:62d1edcc13d1 230 void os_radio( u1_t mode )
mluis 0:62d1edcc13d1 231 {
mluis 0:62d1edcc13d1 232 hal_disableIRQs( );
mluis 0:62d1edcc13d1 233 switch( mode )
mluis 0:62d1edcc13d1 234 {
mluis 0:62d1edcc13d1 235 case RADIO_RST:
mluis 0:62d1edcc13d1 236 // put radio to sleep
mluis 0:62d1edcc13d1 237 Radio.Sleep( );
mluis 0:62d1edcc13d1 238 break;
mluis 0:62d1edcc13d1 239
mluis 0:62d1edcc13d1 240 case RADIO_TX:
mluis 0:62d1edcc13d1 241 // transmit frame now
mluis 0:62d1edcc13d1 242 //ASSERT( Radio.GetState( ) == IDLE );
mluis 0:62d1edcc13d1 243
mluis 0:62d1edcc13d1 244 Radio.SetChannel( LMIC.freq );
mluis 0:62d1edcc13d1 245 if( getSf( LMIC.rps ) == FSK )
mluis 0:62d1edcc13d1 246 { // FSK modem
mluis 0:62d1edcc13d1 247 Radio.SetTxConfig( MODEM_FSK, LMIC.txpow, 25e3, 0, 50e3, 0, 5, false, true, 0, 0, false, 3e6 );
mluis 0:62d1edcc13d1 248 }
mluis 0:62d1edcc13d1 249 else
mluis 0:62d1edcc13d1 250 { // LoRa modem
mluis 0:62d1edcc13d1 251
mluis 1:d3b7bde3995c 252 Radio.SetTxConfig( MODEM_LORA, LMIC.txpow, 0, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 8, getIh( LMIC.rps ) ? true : false, ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, false, 3e6 );
mluis 0:62d1edcc13d1 253 }
mluis 0:62d1edcc13d1 254
mluis 0:62d1edcc13d1 255 //starttx( ); // buf=LMIC.frame, len=LMIC.dataLen
mluis 0:62d1edcc13d1 256 Radio.Send( LMIC.frame, LMIC.dataLen );
mluis 0:62d1edcc13d1 257 break;
mluis 0:62d1edcc13d1 258
mluis 0:62d1edcc13d1 259 case RADIO_RX:
mluis 0:62d1edcc13d1 260 // receive frame now (exactly at rxtime)
mluis 0:62d1edcc13d1 261 //ASSERT( Radio.GetState( ) == IDLE );
mluis 0:62d1edcc13d1 262
mluis 0:62d1edcc13d1 263 Radio.SetChannel( LMIC.freq );
mluis 0:62d1edcc13d1 264 if( getSf( LMIC.rps ) == FSK )
mluis 0:62d1edcc13d1 265 { // FSK modem
mluis 0:62d1edcc13d1 266 //Radio.SetRxConfig( MODEM_FSK, 50e3, 50e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, false );
mluis 0:62d1edcc13d1 267 Radio.SetRxConfig( MODEM_FSK, 50e3, 50e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, true );
mluis 0:62d1edcc13d1 268 }
mluis 0:62d1edcc13d1 269 else
mluis 0:62d1edcc13d1 270 { // LoRa modem
mluis 1:d3b7bde3995c 271 if( ( getSf( LMIC.rps ) <= SF9 ) && ( LMIC.rxsyms < 8 ) )
mluis 1:d3b7bde3995c 272 {
mluis 1:d3b7bde3995c 273 Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms + 3, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, false );
mluis 1:d3b7bde3995c 274 }
mluis 1:d3b7bde3995c 275 else
mluis 1:d3b7bde3995c 276 {
mluis 1:d3b7bde3995c 277 Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, false );
mluis 1:d3b7bde3995c 278 }
mluis 0:62d1edcc13d1 279 }
mluis 0:62d1edcc13d1 280
mluis 0:62d1edcc13d1 281 // now instruct the radio to receive
mluis 0:62d1edcc13d1 282 hal_waitUntil( LMIC.rxtime ); // busy wait until exact rx time
mluis 0:62d1edcc13d1 283
mluis 0:62d1edcc13d1 284 //startrx( RXMODE_SINGLE ); // buf = LMIC.frame, time = LMIC.rxtime, timeout=LMIC.rxsyms
mluis 0:62d1edcc13d1 285 if( getSf( LMIC.rps ) == FSK )
mluis 0:62d1edcc13d1 286 { // FSK modem
mluis 0:62d1edcc13d1 287 Radio.Rx( 50e3 ); // Max Rx window 50 ms
mluis 0:62d1edcc13d1 288 }
mluis 0:62d1edcc13d1 289 else
mluis 0:62d1edcc13d1 290 { // LoRa modem
mluis 0:62d1edcc13d1 291 Radio.Rx( 3e6 ); // Max Rx window 3 seconds
mluis 0:62d1edcc13d1 292 }
mluis 0:62d1edcc13d1 293 break;
mluis 0:62d1edcc13d1 294
mluis 0:62d1edcc13d1 295 case RADIO_RXON:
mluis 0:62d1edcc13d1 296 // start scanning for beacon now
mluis 0:62d1edcc13d1 297
mluis 0:62d1edcc13d1 298 //ASSERT( Radio.GetState( ) == IDLE );
mluis 0:62d1edcc13d1 299
mluis 0:62d1edcc13d1 300 Radio.SetChannel( LMIC.freq );
mluis 0:62d1edcc13d1 301 if( getSf( LMIC.rps ) == FSK )
mluis 0:62d1edcc13d1 302 { // FSK modem
mluis 0:62d1edcc13d1 303 Radio.SetRxConfig( MODEM_FSK, 50e3, 50e3, 0, 83.333e3, 5, 0, false, 0, true, 0, 0, false, true );
mluis 0:62d1edcc13d1 304 }
mluis 0:62d1edcc13d1 305 else
mluis 0:62d1edcc13d1 306 { // LoRa modem
mluis 1:d3b7bde3995c 307 Radio.SetRxConfig( MODEM_LORA, getBw( LMIC.rps ), getSf( LMIC.rps ) + 6, getCr( LMIC.rps ) + 1, 0, 8, LMIC.rxsyms, getIh( LMIC.rps ) ? true : false, getIh( LMIC.rps ), ( getNocrc( LMIC.rps ) == 0 ) ? true : false, 0, 0, true, true );
mluis 0:62d1edcc13d1 308 }
mluis 0:62d1edcc13d1 309
mluis 1:d3b7bde3995c 310 //startrx( RXMODE_SCAN ); // buf = LMIC.frame
mluis 0:62d1edcc13d1 311 Radio.Rx( 0 );
mluis 0:62d1edcc13d1 312 break;
mluis 0:62d1edcc13d1 313 }
mluis 0:62d1edcc13d1 314 hal_enableIRQs( );
mluis 0:62d1edcc13d1 315 }
mluis 0:62d1edcc13d1 316
mluis 0:62d1edcc13d1 317 #else
mluis 0:62d1edcc13d1 318
mluis 0:62d1edcc13d1 319 // ----------------------------------------
mluis 0:62d1edcc13d1 320 // Registers Mapping
mluis 0:62d1edcc13d1 321 #define RegFifo 0x00 // common
mluis 0:62d1edcc13d1 322 #define RegOpMode 0x01 // common
mluis 0:62d1edcc13d1 323 #define FSKRegBitrateMsb 0x02
mluis 0:62d1edcc13d1 324 #define FSKRegBitrateLsb 0x03
mluis 0:62d1edcc13d1 325 #define FSKRegFdevMsb 0x04
mluis 0:62d1edcc13d1 326 #define FSKRegFdevLsb 0x05
mluis 0:62d1edcc13d1 327 #define RegFrfMsb 0x06 // common
mluis 0:62d1edcc13d1 328 #define RegFrfMid 0x07 // common
mluis 0:62d1edcc13d1 329 #define RegFrfLsb 0x08 // common
mluis 0:62d1edcc13d1 330 #define RegPaConfig 0x09 // common
mluis 0:62d1edcc13d1 331 #define RegPaRamp 0x0A // common
mluis 0:62d1edcc13d1 332 #define RegOcp 0x0B // common
mluis 0:62d1edcc13d1 333 #define RegLna 0x0C // common
mluis 0:62d1edcc13d1 334 #define FSKRegRxConfig 0x0D
mluis 0:62d1edcc13d1 335 #define LORARegFifoAddrPtr 0x0D
mluis 0:62d1edcc13d1 336 #define FSKRegRssiConfig 0x0E
mluis 0:62d1edcc13d1 337 #define LORARegFifoTxBaseAddr 0x0E
mluis 0:62d1edcc13d1 338 #define FSKRegRssiCollision 0x0F
mluis 0:62d1edcc13d1 339 #define LORARegFifoRxBaseAddr 0x0F
mluis 0:62d1edcc13d1 340 #define FSKRegRssiThresh 0x10
mluis 0:62d1edcc13d1 341 #define LORARegFifoRxCurrentAddr 0x10
mluis 0:62d1edcc13d1 342 #define FSKRegRssiValue 0x11
mluis 0:62d1edcc13d1 343 #define LORARegIrqFlagsMask 0x11
mluis 0:62d1edcc13d1 344 #define FSKRegRxBw 0x12
mluis 0:62d1edcc13d1 345 #define LORARegIrqFlags 0x12
mluis 0:62d1edcc13d1 346 #define FSKRegAfcBw 0x13
mluis 0:62d1edcc13d1 347 #define LORARegRxNbBytes 0x13
mluis 0:62d1edcc13d1 348 #define FSKRegOokPeak 0x14
mluis 0:62d1edcc13d1 349 #define LORARegRxHeaderCntValueMsb 0x14
mluis 0:62d1edcc13d1 350 #define FSKRegOokFix 0x15
mluis 0:62d1edcc13d1 351 #define LORARegRxHeaderCntValueLsb 0x15
mluis 0:62d1edcc13d1 352 #define FSKRegOokAvg 0x16
mluis 0:62d1edcc13d1 353 #define LORARegRxPacketCntValueMsb 0x16
mluis 0:62d1edcc13d1 354 #define LORARegRxpacketCntValueLsb 0x17
mluis 0:62d1edcc13d1 355 #define LORARegModemStat 0x18
mluis 0:62d1edcc13d1 356 #define LORARegPktSnrValue 0x19
mluis 0:62d1edcc13d1 357 #define FSKRegAfcFei 0x1A
mluis 0:62d1edcc13d1 358 #define LORARegPktRssiValue 0x1A
mluis 0:62d1edcc13d1 359 #define FSKRegAfcMsb 0x1B
mluis 0:62d1edcc13d1 360 #define LORARegRssiValue 0x1B
mluis 0:62d1edcc13d1 361 #define FSKRegAfcLsb 0x1C
mluis 0:62d1edcc13d1 362 #define LORARegHopChannel 0x1C
mluis 0:62d1edcc13d1 363 #define FSKRegFeiMsb 0x1D
mluis 0:62d1edcc13d1 364 #define LORARegModemConfig1 0x1D
mluis 0:62d1edcc13d1 365 #define FSKRegFeiLsb 0x1E
mluis 0:62d1edcc13d1 366 #define LORARegModemConfig2 0x1E
mluis 0:62d1edcc13d1 367 #define FSKRegPreambleDetect 0x1F
mluis 0:62d1edcc13d1 368 #define LORARegSymbTimeoutLsb 0x1F
mluis 0:62d1edcc13d1 369 #define FSKRegRxTimeout1 0x20
mluis 0:62d1edcc13d1 370 #define LORARegPreambleMsb 0x20
mluis 0:62d1edcc13d1 371 #define FSKRegRxTimeout2 0x21
mluis 0:62d1edcc13d1 372 #define LORARegPreambleLsb 0x21
mluis 0:62d1edcc13d1 373 #define FSKRegRxTimeout3 0x22
mluis 0:62d1edcc13d1 374 #define LORARegPayloadLength 0x22
mluis 0:62d1edcc13d1 375 #define FSKRegRxDelay 0x23
mluis 0:62d1edcc13d1 376 #define LORARegPayloadMaxLength 0x23
mluis 0:62d1edcc13d1 377 #define FSKRegOsc 0x24
mluis 0:62d1edcc13d1 378 #define LORARegHopPeriod 0x24
mluis 0:62d1edcc13d1 379 #define FSKRegPreambleMsb 0x25
mluis 0:62d1edcc13d1 380 #define LORARegFifoRxByteAddr 0x25
mluis 0:62d1edcc13d1 381 #define LORARegModemConfig3 0x26
mluis 0:62d1edcc13d1 382 #define FSKRegPreambleLsb 0x26
mluis 0:62d1edcc13d1 383 #define FSKRegSyncConfig 0x27
mluis 0:62d1edcc13d1 384 #define LORARegFeiMsb 0x28
mluis 0:62d1edcc13d1 385 #define FSKRegSyncValue1 0x28
mluis 0:62d1edcc13d1 386 #define LORAFeiMib 0x29
mluis 0:62d1edcc13d1 387 #define FSKRegSyncValue2 0x29
mluis 0:62d1edcc13d1 388 #define LORARegFeiLsb 0x2A
mluis 0:62d1edcc13d1 389 #define FSKRegSyncValue3 0x2A
mluis 0:62d1edcc13d1 390 #define FSKRegSyncValue4 0x2B
mluis 0:62d1edcc13d1 391 #define LORARegRssiWideband 0x2C
mluis 0:62d1edcc13d1 392 #define FSKRegSyncValue5 0x2C
mluis 0:62d1edcc13d1 393 #define FSKRegSyncValue6 0x2D
mluis 0:62d1edcc13d1 394 #define FSKRegSyncValue7 0x2E
mluis 0:62d1edcc13d1 395 #define FSKRegSyncValue8 0x2F
mluis 0:62d1edcc13d1 396 #define FSKRegPacketConfig1 0x30
mluis 0:62d1edcc13d1 397 #define FSKRegPacketConfig2 0x31
mluis 0:62d1edcc13d1 398 #define LORARegDetectOptimize 0x31
mluis 0:62d1edcc13d1 399 #define FSKRegPayloadLength 0x32
mluis 0:62d1edcc13d1 400 #define FSKRegNodeAdrs 0x33
mluis 0:62d1edcc13d1 401 #define LORARegInvertIQ 0x33
mluis 0:62d1edcc13d1 402 #define FSKRegBroadcastAdrs 0x34
mluis 0:62d1edcc13d1 403 #define FSKRegFifoThresh 0x35
mluis 0:62d1edcc13d1 404 #define FSKRegSeqConfig1 0x36
mluis 0:62d1edcc13d1 405 #define FSKRegSeqConfig2 0x37
mluis 0:62d1edcc13d1 406 #define LORARegDetectionThreshold 0x37
mluis 0:62d1edcc13d1 407 #define FSKRegTimerResol 0x38
mluis 0:62d1edcc13d1 408 #define FSKRegTimer1Coef 0x39
mluis 0:62d1edcc13d1 409 #define LORARegSyncWord 0x39
mluis 0:62d1edcc13d1 410 #define FSKRegTimer2Coef 0x3A
mluis 0:62d1edcc13d1 411 #define FSKRegImageCal 0x3B
mluis 0:62d1edcc13d1 412 #define FSKRegTemp 0x3C
mluis 0:62d1edcc13d1 413 #define FSKRegLowBat 0x3D
mluis 0:62d1edcc13d1 414 #define FSKRegIrqFlags1 0x3E
mluis 0:62d1edcc13d1 415 #define FSKRegIrqFlags2 0x3F
mluis 0:62d1edcc13d1 416 #define RegDioMapping1 0x40 // common
mluis 0:62d1edcc13d1 417 #define RegDioMapping2 0x41 // common
mluis 0:62d1edcc13d1 418 #define RegVersion 0x42 // common
mluis 0:62d1edcc13d1 419 // #define RegAgcRef 0x43 // common
mluis 0:62d1edcc13d1 420 // #define RegAgcThresh1 0x44 // common
mluis 0:62d1edcc13d1 421 // #define RegAgcThresh2 0x45 // common
mluis 0:62d1edcc13d1 422 // #define RegAgcThresh3 0x46 // common
mluis 0:62d1edcc13d1 423 // #define RegPllHop 0x4B // common
mluis 0:62d1edcc13d1 424 // #define RegTcxo 0x58 // common
mluis 0:62d1edcc13d1 425 #define RegPaDac 0x5A // common
mluis 0:62d1edcc13d1 426 // #define RegPll 0x5C // common
mluis 0:62d1edcc13d1 427 // #define RegPllLowPn 0x5E // common
mluis 0:62d1edcc13d1 428 // #define RegFormerTemp 0x6C // common
mluis 0:62d1edcc13d1 429 // #define RegBitRateFrac 0x70 // common
mluis 0:62d1edcc13d1 430
mluis 0:62d1edcc13d1 431 // ----------------------------------------
mluis 0:62d1edcc13d1 432 // spread factors and mode for RegModemConfig2
mluis 0:62d1edcc13d1 433 #define SX1272_MC2_FSK 0x00
mluis 0:62d1edcc13d1 434 #define SX1272_MC2_SF7 0x70
mluis 0:62d1edcc13d1 435 #define SX1272_MC2_SF8 0x80
mluis 0:62d1edcc13d1 436 #define SX1272_MC2_SF9 0x90
mluis 0:62d1edcc13d1 437 #define SX1272_MC2_SF10 0xA0
mluis 0:62d1edcc13d1 438 #define SX1272_MC2_SF11 0xB0
mluis 0:62d1edcc13d1 439 #define SX1272_MC2_SF12 0xC0
mluis 0:62d1edcc13d1 440 // bandwidth for RegModemConfig1
mluis 0:62d1edcc13d1 441 #define SX1272_MC1_BW_125 0x00
mluis 0:62d1edcc13d1 442 #define SX1272_MC1_BW_250 0x40
mluis 0:62d1edcc13d1 443 #define SX1272_MC1_BW_500 0x80
mluis 0:62d1edcc13d1 444 // coding rate for RegModemConfig1
mluis 0:62d1edcc13d1 445 #define SX1272_MC1_CR_4_5 0x08
mluis 0:62d1edcc13d1 446 #define SX1272_MC1_CR_4_6 0x10
mluis 0:62d1edcc13d1 447 #define SX1272_MC1_CR_4_7 0x18
mluis 0:62d1edcc13d1 448 #define SX1272_MC1_CR_4_8 0x20
mluis 0:62d1edcc13d1 449 #define SX1272_MC1_IMPLICIT_HEADER_MODE_ON 0x04 // required for receive
mluis 0:62d1edcc13d1 450 #define SX1272_MC1_RX_PAYLOAD_CRCON 0x02
mluis 0:62d1edcc13d1 451 #define SX1272_MC1_LOW_DATA_RATE_OPTIMIZE 0x01 // mandated for SF11 and SF12
mluis 0:62d1edcc13d1 452 // transmit power configuration for RegPaConfig
mluis 0:62d1edcc13d1 453 #define SX1272_PAC_PA_SELECT_PA_BOOST 0x80
mluis 0:62d1edcc13d1 454 #define SX1272_PAC_PA_SELECT_RFIO_PIN 0x00
mluis 0:62d1edcc13d1 455
mluis 0:62d1edcc13d1 456
mluis 0:62d1edcc13d1 457 // sx1276 RegModemConfig1
mluis 0:62d1edcc13d1 458 #define SX1276_MC1_BW_125 0x70
mluis 0:62d1edcc13d1 459 #define SX1276_MC1_BW_250 0x80
mluis 0:62d1edcc13d1 460 #define SX1276_MC1_BW_500 0x90
mluis 0:62d1edcc13d1 461 #define SX1276_MC1_CR_4_5 0x02
mluis 0:62d1edcc13d1 462 #define SX1276_MC1_CR_4_6 0x04
mluis 0:62d1edcc13d1 463 #define SX1276_MC1_CR_4_7 0x06
mluis 0:62d1edcc13d1 464 #define SX1276_MC1_CR_4_8 0x08
mluis 0:62d1edcc13d1 465
mluis 0:62d1edcc13d1 466 #define SX1276_MC1_IMPLICIT_HEADER_MODE_ON 0x01
mluis 0:62d1edcc13d1 467
mluis 0:62d1edcc13d1 468 // sx1276 RegModemConfig2
mluis 0:62d1edcc13d1 469 #define SX1276_MC2_RX_PAYLOAD_CRCON 0x04
mluis 0:62d1edcc13d1 470
mluis 0:62d1edcc13d1 471 // sx1276 RegModemConfig3
mluis 0:62d1edcc13d1 472 #define SX1276_MC3_LOW_DATA_RATE_OPTIMIZE 0x08
mluis 0:62d1edcc13d1 473 #define SX1276_MC3_AGCAUTO 0x04
mluis 0:62d1edcc13d1 474
mluis 0:62d1edcc13d1 475 // preamble for lora networks (nibbles swapped)
mluis 1:d3b7bde3995c 476 #define LORA_MAC_PREAMBLE 0x34
mluis 0:62d1edcc13d1 477
mluis 0:62d1edcc13d1 478 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1 0x0A
mluis 0:62d1edcc13d1 479 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 480 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x70
mluis 0:62d1edcc13d1 481 #elif CFG_sx1272_radio
mluis 0:62d1edcc13d1 482 #define RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2 0x74
mluis 0:62d1edcc13d1 483 #endif
mluis 0:62d1edcc13d1 484
mluis 0:62d1edcc13d1 485
mluis 0:62d1edcc13d1 486
mluis 0:62d1edcc13d1 487 // ----------------------------------------
mluis 0:62d1edcc13d1 488 // Constants for radio registers
mluis 0:62d1edcc13d1 489 #define OPMODE_LORA 0x80
mluis 0:62d1edcc13d1 490 #define OPMODE_MASK 0x07
mluis 0:62d1edcc13d1 491 #define OPMODE_SLEEP 0x00
mluis 0:62d1edcc13d1 492 #define OPMODE_STANDBY 0x01
mluis 0:62d1edcc13d1 493 #define OPMODE_FSTX 0x02
mluis 0:62d1edcc13d1 494 #define OPMODE_TX 0x03
mluis 0:62d1edcc13d1 495 #define OPMODE_FSRX 0x04
mluis 0:62d1edcc13d1 496 #define OPMODE_RX 0x05
mluis 0:62d1edcc13d1 497 #define OPMODE_RX_SINGLE 0x06
mluis 0:62d1edcc13d1 498 #define OPMODE_CAD 0x07
mluis 0:62d1edcc13d1 499
mluis 0:62d1edcc13d1 500 // ----------------------------------------
mluis 0:62d1edcc13d1 501 // Bits masking the corresponding IRQs from the radio
mluis 0:62d1edcc13d1 502 #define IRQ_LORA_RXTOUT_MASK 0x80
mluis 0:62d1edcc13d1 503 #define IRQ_LORA_RXDONE_MASK 0x40
mluis 0:62d1edcc13d1 504 #define IRQ_LORA_CRCERR_MASK 0x20
mluis 0:62d1edcc13d1 505 #define IRQ_LORA_HEADER_MASK 0x10
mluis 0:62d1edcc13d1 506 #define IRQ_LORA_TXDONE_MASK 0x08
mluis 0:62d1edcc13d1 507 #define IRQ_LORA_CDDONE_MASK 0x04
mluis 0:62d1edcc13d1 508 #define IRQ_LORA_FHSSCH_MASK 0x02
mluis 0:62d1edcc13d1 509 #define IRQ_LORA_CDDETD_MASK 0x01
mluis 0:62d1edcc13d1 510
mluis 0:62d1edcc13d1 511 #define IRQ_FSK1_MODEREADY_MASK 0x80
mluis 0:62d1edcc13d1 512 #define IRQ_FSK1_RXREADY_MASK 0x40
mluis 0:62d1edcc13d1 513 #define IRQ_FSK1_TXREADY_MASK 0x20
mluis 0:62d1edcc13d1 514 #define IRQ_FSK1_PLLLOCK_MASK 0x10
mluis 0:62d1edcc13d1 515 #define IRQ_FSK1_RSSI_MASK 0x08
mluis 0:62d1edcc13d1 516 #define IRQ_FSK1_TIMEOUT_MASK 0x04
mluis 0:62d1edcc13d1 517 #define IRQ_FSK1_PREAMBLEDETECT_MASK 0x02
mluis 0:62d1edcc13d1 518 #define IRQ_FSK1_SYNCADDRESSMATCH_MASK 0x01
mluis 0:62d1edcc13d1 519 #define IRQ_FSK2_FIFOFULL_MASK 0x80
mluis 0:62d1edcc13d1 520 #define IRQ_FSK2_FIFOEMPTY_MASK 0x40
mluis 0:62d1edcc13d1 521 #define IRQ_FSK2_FIFOLEVEL_MASK 0x20
mluis 0:62d1edcc13d1 522 #define IRQ_FSK2_FIFOOVERRUN_MASK 0x10
mluis 0:62d1edcc13d1 523 #define IRQ_FSK2_PACKETSENT_MASK 0x08
mluis 0:62d1edcc13d1 524 #define IRQ_FSK2_PAYLOADREADY_MASK 0x04
mluis 0:62d1edcc13d1 525 #define IRQ_FSK2_CRCOK_MASK 0x02
mluis 0:62d1edcc13d1 526 #define IRQ_FSK2_LOWBAT_MASK 0x01
mluis 0:62d1edcc13d1 527
mluis 0:62d1edcc13d1 528 // ----------------------------------------
mluis 0:62d1edcc13d1 529 // DIO function mappings D0D1D2D3
mluis 0:62d1edcc13d1 530 #define MAP_DIO0_LORA_RXDONE 0x00 // 00------
mluis 0:62d1edcc13d1 531 #define MAP_DIO0_LORA_TXDONE 0x40 // 01------
mluis 0:62d1edcc13d1 532 #define MAP_DIO1_LORA_RXTOUT 0x00 // --00----
mluis 0:62d1edcc13d1 533 #define MAP_DIO1_LORA_NOP 0x30 // --11----
mluis 0:62d1edcc13d1 534 #define MAP_DIO2_LORA_NOP 0xC0 // ----11--
mluis 0:62d1edcc13d1 535
mluis 0:62d1edcc13d1 536 #define MAP_DIO0_FSK_READY 0x00 // 00------ (packet sent / payload ready)
mluis 0:62d1edcc13d1 537 #define MAP_DIO1_FSK_NOP 0x30 // --11----
mluis 0:62d1edcc13d1 538 #define MAP_DIO2_FSK_TXNOP 0x04 // ----01--
mluis 0:62d1edcc13d1 539 #define MAP_DIO2_FSK_TIMEOUT 0x08 // ----10--
mluis 0:62d1edcc13d1 540
mluis 0:62d1edcc13d1 541
mluis 0:62d1edcc13d1 542 // FSK IMAGECAL defines
mluis 0:62d1edcc13d1 543 #define RF_IMAGECAL_AUTOIMAGECAL_MASK 0x7F
mluis 0:62d1edcc13d1 544 #define RF_IMAGECAL_AUTOIMAGECAL_ON 0x80
mluis 0:62d1edcc13d1 545 #define RF_IMAGECAL_AUTOIMAGECAL_OFF 0x00 // Default
mluis 0:62d1edcc13d1 546
mluis 0:62d1edcc13d1 547 #define RF_IMAGECAL_IMAGECAL_MASK 0xBF
mluis 0:62d1edcc13d1 548 #define RF_IMAGECAL_IMAGECAL_START 0x40
mluis 0:62d1edcc13d1 549
mluis 0:62d1edcc13d1 550 #define RF_IMAGECAL_IMAGECAL_RUNNING 0x20
mluis 0:62d1edcc13d1 551 #define RF_IMAGECAL_IMAGECAL_DONE 0x00 // Default
mluis 0:62d1edcc13d1 552
mluis 0:62d1edcc13d1 553
mluis 0:62d1edcc13d1 554 // RADIO STATE
mluis 0:62d1edcc13d1 555 // (initialized by radio_init(), used by radio_rand1())
mluis 0:62d1edcc13d1 556 static u1_t randbuf[16];
mluis 0:62d1edcc13d1 557
mluis 0:62d1edcc13d1 558
mluis 0:62d1edcc13d1 559 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 560 #define LNA_RX_GAIN (0x20|0x1)
mluis 0:62d1edcc13d1 561 #elif CFG_sx1272_radio
mluis 0:62d1edcc13d1 562 #define LNA_RX_GAIN (0x20|0x03)
mluis 0:62d1edcc13d1 563 #else
mluis 0:62d1edcc13d1 564 #error Missing CFG_sx1272_radio/CFG_sx1276_radio
mluis 0:62d1edcc13d1 565 #endif
mluis 0:62d1edcc13d1 566
mluis 1:d3b7bde3995c 567 #define RADIO_DBG
mluis 1:d3b7bde3995c 568 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 569 DigitalOut txStateIo( PB_8 );
mluis 1:d3b7bde3995c 570 DigitalOut rxStateIo( PB_9 );
mluis 1:d3b7bde3995c 571 #endif
mluis 1:d3b7bde3995c 572
mluis 0:62d1edcc13d1 573 static void writeReg (u1_t addr, u1_t data ) {
mluis 0:62d1edcc13d1 574 hal_pin_nss(0);
mluis 0:62d1edcc13d1 575 hal_spi(addr | 0x80);
mluis 0:62d1edcc13d1 576 hal_spi(data);
mluis 0:62d1edcc13d1 577 hal_pin_nss(1);
mluis 0:62d1edcc13d1 578 }
mluis 0:62d1edcc13d1 579
mluis 0:62d1edcc13d1 580 static u1_t readReg (u1_t addr) {
mluis 0:62d1edcc13d1 581 hal_pin_nss(0);
mluis 0:62d1edcc13d1 582 hal_spi(addr & 0x7F);
mluis 0:62d1edcc13d1 583 u1_t val = hal_spi(0x00);
mluis 0:62d1edcc13d1 584 hal_pin_nss(1);
mluis 0:62d1edcc13d1 585 return val;
mluis 0:62d1edcc13d1 586 }
mluis 0:62d1edcc13d1 587
mluis 0:62d1edcc13d1 588 static void writeBuf (u1_t addr, xref2u1_t buf, u1_t len) {
mluis 0:62d1edcc13d1 589 hal_pin_nss(0);
mluis 0:62d1edcc13d1 590 hal_spi(addr | 0x80);
mluis 0:62d1edcc13d1 591 for (u1_t i=0; i<len; i++) {
mluis 0:62d1edcc13d1 592 hal_spi(buf[i]);
mluis 0:62d1edcc13d1 593 }
mluis 0:62d1edcc13d1 594 hal_pin_nss(1);
mluis 0:62d1edcc13d1 595 }
mluis 0:62d1edcc13d1 596
mluis 0:62d1edcc13d1 597 static void readBuf (u1_t addr, xref2u1_t buf, u1_t len) {
mluis 0:62d1edcc13d1 598 hal_pin_nss(0);
mluis 0:62d1edcc13d1 599 hal_spi(addr & 0x7F);
mluis 0:62d1edcc13d1 600 for (u1_t i=0; i<len; i++) {
mluis 0:62d1edcc13d1 601 buf[i] = hal_spi(0x00);
mluis 0:62d1edcc13d1 602 }
mluis 0:62d1edcc13d1 603 hal_pin_nss(1);
mluis 0:62d1edcc13d1 604 }
mluis 0:62d1edcc13d1 605
mluis 0:62d1edcc13d1 606 static void opmode (u1_t mode) {
mluis 0:62d1edcc13d1 607 writeReg(RegOpMode, (readReg(RegOpMode) & ~OPMODE_MASK) | mode);
mluis 0:62d1edcc13d1 608 }
mluis 0:62d1edcc13d1 609
mluis 1:d3b7bde3995c 610 static void opmodeLora() {
mluis 0:62d1edcc13d1 611 u1_t u = OPMODE_LORA;
mluis 0:62d1edcc13d1 612 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 613 u |= 0x8; // TBD: sx1276 high freq
mluis 0:62d1edcc13d1 614 #endif
mluis 0:62d1edcc13d1 615 writeReg(RegOpMode, u);
mluis 0:62d1edcc13d1 616 }
mluis 0:62d1edcc13d1 617
mluis 1:d3b7bde3995c 618 static void opmodeFSK() {
mluis 0:62d1edcc13d1 619 u1_t u = 0;
mluis 0:62d1edcc13d1 620 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 621 u |= 0x8; // TBD: sx1276 high freq
mluis 0:62d1edcc13d1 622 #endif
mluis 0:62d1edcc13d1 623 writeReg(RegOpMode, u);
mluis 0:62d1edcc13d1 624 }
mluis 0:62d1edcc13d1 625
mluis 0:62d1edcc13d1 626 // configure LoRa modem (cfg1, cfg2)
mluis 1:d3b7bde3995c 627 static void configLoraModem () {
mluis 0:62d1edcc13d1 628 sf_t sf = getSf(LMIC.rps);
mluis 0:62d1edcc13d1 629
mluis 0:62d1edcc13d1 630 #ifdef CFG_sx1276_radio
mluis 1:d3b7bde3995c 631 u1_t mc1 = 0, mc2 = 0, mc3 = 0;
mluis 0:62d1edcc13d1 632
mluis 1:d3b7bde3995c 633 switch (getBw(LMIC.rps)) {
mluis 1:d3b7bde3995c 634 case BW125: mc1 |= SX1276_MC1_BW_125; break;
mluis 1:d3b7bde3995c 635 case BW250: mc1 |= SX1276_MC1_BW_250; break;
mluis 1:d3b7bde3995c 636 case BW500: mc1 |= SX1276_MC1_BW_500; break;
mluis 1:d3b7bde3995c 637 default:
mluis 1:d3b7bde3995c 638 ASSERT(0);
mluis 1:d3b7bde3995c 639 }
mluis 1:d3b7bde3995c 640 switch( getCr(LMIC.rps) ) {
mluis 1:d3b7bde3995c 641 case CR_4_5: mc1 |= SX1276_MC1_CR_4_5; break;
mluis 1:d3b7bde3995c 642 case CR_4_6: mc1 |= SX1276_MC1_CR_4_6; break;
mluis 1:d3b7bde3995c 643 case CR_4_7: mc1 |= SX1276_MC1_CR_4_7; break;
mluis 1:d3b7bde3995c 644 case CR_4_8: mc1 |= SX1276_MC1_CR_4_8; break;
mluis 1:d3b7bde3995c 645 default:
mluis 1:d3b7bde3995c 646 ASSERT(0);
mluis 1:d3b7bde3995c 647 }
mluis 0:62d1edcc13d1 648
mluis 1:d3b7bde3995c 649 if (getIh(LMIC.rps)) {
mluis 1:d3b7bde3995c 650 mc1 |= SX1276_MC1_IMPLICIT_HEADER_MODE_ON;
mluis 1:d3b7bde3995c 651 writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
mluis 1:d3b7bde3995c 652 }
mluis 1:d3b7bde3995c 653 // set ModemConfig1
mluis 1:d3b7bde3995c 654 writeReg(LORARegModemConfig1, mc1);
mluis 0:62d1edcc13d1 655
mluis 1:d3b7bde3995c 656 mc2 = (SX1272_MC2_SF7 + ((sf-1)<<4));
mluis 1:d3b7bde3995c 657 if (getNocrc(LMIC.rps) == 0) {
mluis 1:d3b7bde3995c 658 mc2 |= SX1276_MC2_RX_PAYLOAD_CRCON;
mluis 1:d3b7bde3995c 659 }
mluis 1:d3b7bde3995c 660 writeReg(LORARegModemConfig2, mc2);
mluis 1:d3b7bde3995c 661
mluis 1:d3b7bde3995c 662 mc3 = SX1276_MC3_AGCAUTO;
mluis 1:d3b7bde3995c 663 if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
mluis 1:d3b7bde3995c 664 mc3 |= SX1276_MC3_LOW_DATA_RATE_OPTIMIZE;
mluis 1:d3b7bde3995c 665 }
mluis 1:d3b7bde3995c 666 writeReg(LORARegModemConfig3, mc3);
mluis 0:62d1edcc13d1 667 #elif CFG_sx1272_radio
mluis 1:d3b7bde3995c 668 u1_t mc1 = (getBw(LMIC.rps)<<6);
mluis 0:62d1edcc13d1 669
mluis 1:d3b7bde3995c 670 switch( getCr(LMIC.rps) ) {
mluis 1:d3b7bde3995c 671 case CR_4_5: mc1 |= SX1272_MC1_CR_4_5; break;
mluis 1:d3b7bde3995c 672 case CR_4_6: mc1 |= SX1272_MC1_CR_4_6; break;
mluis 1:d3b7bde3995c 673 case CR_4_7: mc1 |= SX1272_MC1_CR_4_7; break;
mluis 1:d3b7bde3995c 674 case CR_4_8: mc1 |= SX1272_MC1_CR_4_8; break;
mluis 1:d3b7bde3995c 675 }
mluis 1:d3b7bde3995c 676
mluis 1:d3b7bde3995c 677 if ((sf == SF11 || sf == SF12) && getBw(LMIC.rps) == BW125) {
mluis 1:d3b7bde3995c 678 mc1 |= SX1272_MC1_LOW_DATA_RATE_OPTIMIZE;
mluis 1:d3b7bde3995c 679 }
mluis 1:d3b7bde3995c 680
mluis 1:d3b7bde3995c 681 if (getNocrc(LMIC.rps) == 0) {
mluis 1:d3b7bde3995c 682 mc1 |= SX1272_MC1_RX_PAYLOAD_CRCON;
mluis 1:d3b7bde3995c 683 }
mluis 1:d3b7bde3995c 684
mluis 1:d3b7bde3995c 685 if (getIh(LMIC.rps)) {
mluis 1:d3b7bde3995c 686 mc1 |= SX1272_MC1_IMPLICIT_HEADER_MODE_ON;
mluis 1:d3b7bde3995c 687 writeReg(LORARegPayloadLength, getIh(LMIC.rps)); // required length
mluis 1:d3b7bde3995c 688 }
mluis 1:d3b7bde3995c 689 // set ModemConfig1
mluis 1:d3b7bde3995c 690 writeReg(LORARegModemConfig1, mc1);
mluis 1:d3b7bde3995c 691
mluis 1:d3b7bde3995c 692 // set ModemConfig2 (sf, AgcAutoOn=1 SymbTimeoutHi=00)
mluis 1:d3b7bde3995c 693 writeReg(LORARegModemConfig2, (SX1272_MC2_SF7 + ((sf-1)<<4)) | 0x04);
mluis 0:62d1edcc13d1 694 #else
mluis 0:62d1edcc13d1 695 #error Missing CFG_sx1272_radio/CFG_sx1276_radio
mluis 0:62d1edcc13d1 696 #endif /* CFG_sx1272_radio */
mluis 0:62d1edcc13d1 697 }
mluis 0:62d1edcc13d1 698
mluis 1:d3b7bde3995c 699 static void configChannel () {
mluis 0:62d1edcc13d1 700 // set frequency: FQ = (FRF * 32 Mhz) / (2 ^ 19)
mluis 0:62d1edcc13d1 701 u8_t frf = ((u8_t)LMIC.freq << 19) / 32000000;
mluis 0:62d1edcc13d1 702 writeReg(RegFrfMsb, (u1_t)(frf>>16));
mluis 0:62d1edcc13d1 703 writeReg(RegFrfMid, (u1_t)(frf>> 8));
mluis 0:62d1edcc13d1 704 writeReg(RegFrfLsb, (u1_t)(frf>> 0));
mluis 0:62d1edcc13d1 705 }
mluis 0:62d1edcc13d1 706
mluis 0:62d1edcc13d1 707
mluis 0:62d1edcc13d1 708
mluis 1:d3b7bde3995c 709 static void configPower () {
mluis 0:62d1edcc13d1 710 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 711 // no boost used for now
mluis 0:62d1edcc13d1 712 s1_t pw = (s1_t)LMIC.txpow;
mluis 1:d3b7bde3995c 713 if(pw >= 17) {
mluis 1:d3b7bde3995c 714 pw = 15;
mluis 1:d3b7bde3995c 715 } else if(pw < 2) {
mluis 1:d3b7bde3995c 716 pw = 2;
mluis 0:62d1edcc13d1 717 }
mluis 0:62d1edcc13d1 718 // check board type for BOOST pin
mluis 1:d3b7bde3995c 719 writeReg(RegPaConfig, (u1_t)(0x80|(pw&0xf)));
mluis 0:62d1edcc13d1 720 writeReg(RegPaDac, readReg(RegPaDac)|0x4);
mluis 0:62d1edcc13d1 721
mluis 0:62d1edcc13d1 722 #elif CFG_sx1272_radio
mluis 0:62d1edcc13d1 723 // set PA config (2-17 dBm using PA_BOOST)
mluis 0:62d1edcc13d1 724 s1_t pw = (s1_t)LMIC.txpow;
mluis 0:62d1edcc13d1 725 if(pw > 17) {
mluis 1:d3b7bde3995c 726 pw = 17;
mluis 0:62d1edcc13d1 727 } else if(pw < 2) {
mluis 1:d3b7bde3995c 728 pw = 2;
mluis 0:62d1edcc13d1 729 }
mluis 0:62d1edcc13d1 730 writeReg(RegPaConfig, (u1_t)(0x80|(pw-2)));
mluis 0:62d1edcc13d1 731 #else
mluis 0:62d1edcc13d1 732 #error Missing CFG_sx1272_radio/CFG_sx1276_radio
mluis 0:62d1edcc13d1 733 #endif /* CFG_sx1272_radio */
mluis 0:62d1edcc13d1 734 }
mluis 0:62d1edcc13d1 735
mluis 1:d3b7bde3995c 736 static void txfsk () {
mluis 0:62d1edcc13d1 737 // select FSK modem (from sleep mode)
mluis 0:62d1edcc13d1 738 writeReg(RegOpMode, 0x10); // FSK, BT=0.5
mluis 0:62d1edcc13d1 739 ASSERT(readReg(RegOpMode) == 0x10);
mluis 0:62d1edcc13d1 740 // enter standby mode (required for FIFO loading))
mluis 0:62d1edcc13d1 741 opmode(OPMODE_STANDBY);
mluis 1:d3b7bde3995c 742 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 743 txStateIo = 0;
mluis 1:d3b7bde3995c 744 rxStateIo = 0;
mluis 1:d3b7bde3995c 745 #endif
mluis 0:62d1edcc13d1 746 // set bitrate
mluis 0:62d1edcc13d1 747 writeReg(FSKRegBitrateMsb, 0x02); // 50kbps
mluis 0:62d1edcc13d1 748 writeReg(FSKRegBitrateLsb, 0x80);
mluis 0:62d1edcc13d1 749 // set frequency deviation
mluis 0:62d1edcc13d1 750 writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz
mluis 0:62d1edcc13d1 751 writeReg(FSKRegFdevLsb, 0x99);
mluis 0:62d1edcc13d1 752 // frame and packet handler settings
mluis 0:62d1edcc13d1 753 writeReg(FSKRegPreambleMsb, 0x00);
mluis 0:62d1edcc13d1 754 writeReg(FSKRegPreambleLsb, 0x05);
mluis 0:62d1edcc13d1 755 writeReg(FSKRegSyncConfig, 0x12);
mluis 0:62d1edcc13d1 756 writeReg(FSKRegPacketConfig1, 0xD0);
mluis 0:62d1edcc13d1 757 writeReg(FSKRegPacketConfig2, 0x40);
mluis 0:62d1edcc13d1 758 writeReg(FSKRegSyncValue1, 0xC1);
mluis 0:62d1edcc13d1 759 writeReg(FSKRegSyncValue2, 0x94);
mluis 0:62d1edcc13d1 760 writeReg(FSKRegSyncValue3, 0xC1);
mluis 0:62d1edcc13d1 761 // configure frequency
mluis 0:62d1edcc13d1 762 configChannel();
mluis 0:62d1edcc13d1 763 // configure output power
mluis 0:62d1edcc13d1 764 configPower();
mluis 0:62d1edcc13d1 765
mluis 0:62d1edcc13d1 766 // set the IRQ mapping DIO0=PacketSent DIO1=NOP DIO2=NOP
mluis 0:62d1edcc13d1 767 writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TXNOP);
mluis 0:62d1edcc13d1 768
mluis 0:62d1edcc13d1 769 // initialize the payload size and address pointers
mluis 0:62d1edcc13d1 770 writeReg(FSKRegPayloadLength, LMIC.dataLen+1); // (insert length byte into payload))
mluis 0:62d1edcc13d1 771
mluis 0:62d1edcc13d1 772 // download length byte and buffer to the radio FIFO
mluis 0:62d1edcc13d1 773 writeReg(RegFifo, LMIC.dataLen);
mluis 0:62d1edcc13d1 774 writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);
mluis 0:62d1edcc13d1 775
mluis 0:62d1edcc13d1 776 // enable antenna switch for TX
mluis 0:62d1edcc13d1 777 hal_pin_rxtx(1);
mluis 0:62d1edcc13d1 778
mluis 0:62d1edcc13d1 779 // now we actually start the transmission
mluis 0:62d1edcc13d1 780 opmode(OPMODE_TX);
mluis 1:d3b7bde3995c 781 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 782 txStateIo = 1;
mluis 1:d3b7bde3995c 783 #endif
mluis 0:62d1edcc13d1 784 }
mluis 0:62d1edcc13d1 785
mluis 1:d3b7bde3995c 786 static void txlora () {
mluis 0:62d1edcc13d1 787 // select LoRa modem (from sleep mode)
mluis 0:62d1edcc13d1 788 //writeReg(RegOpMode, OPMODE_LORA);
mluis 0:62d1edcc13d1 789 opmodeLora();
mluis 0:62d1edcc13d1 790 ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
mluis 0:62d1edcc13d1 791
mluis 0:62d1edcc13d1 792 // enter standby mode (required for FIFO loading))
mluis 0:62d1edcc13d1 793 opmode(OPMODE_STANDBY);
mluis 1:d3b7bde3995c 794 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 795 txStateIo = 0;
mluis 1:d3b7bde3995c 796 rxStateIo = 0;
mluis 1:d3b7bde3995c 797 #endif
mluis 0:62d1edcc13d1 798 // configure LoRa modem (cfg1, cfg2)
mluis 0:62d1edcc13d1 799 configLoraModem();
mluis 0:62d1edcc13d1 800 // configure frequency
mluis 0:62d1edcc13d1 801 configChannel();
mluis 0:62d1edcc13d1 802 // configure output power
mluis 0:62d1edcc13d1 803 writeReg(RegPaRamp, (readReg(RegPaRamp) & 0xF0) | 0x08); // set PA ramp-up time 50 uSec
mluis 0:62d1edcc13d1 804 configPower();
mluis 0:62d1edcc13d1 805 // set sync word
mluis 0:62d1edcc13d1 806 writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
mluis 0:62d1edcc13d1 807
mluis 0:62d1edcc13d1 808 // set the IRQ mapping DIO0=TxDone DIO1=NOP DIO2=NOP
mluis 0:62d1edcc13d1 809 writeReg(RegDioMapping1, MAP_DIO0_LORA_TXDONE|MAP_DIO1_LORA_NOP|MAP_DIO2_LORA_NOP);
mluis 0:62d1edcc13d1 810 // clear all radio IRQ flags
mluis 0:62d1edcc13d1 811 writeReg(LORARegIrqFlags, 0xFF);
mluis 0:62d1edcc13d1 812 // mask all IRQs but TxDone
mluis 0:62d1edcc13d1 813 writeReg(LORARegIrqFlagsMask, ~IRQ_LORA_TXDONE_MASK);
mluis 0:62d1edcc13d1 814
mluis 0:62d1edcc13d1 815 // initialize the payload size and address pointers
mluis 0:62d1edcc13d1 816 writeReg(LORARegFifoTxBaseAddr, 0x00);
mluis 0:62d1edcc13d1 817 writeReg(LORARegFifoAddrPtr, 0x00);
mluis 0:62d1edcc13d1 818 writeReg(LORARegPayloadLength, LMIC.dataLen);
mluis 0:62d1edcc13d1 819
mluis 0:62d1edcc13d1 820 // download buffer to the radio FIFO
mluis 0:62d1edcc13d1 821 writeBuf(RegFifo, LMIC.frame, LMIC.dataLen);
mluis 0:62d1edcc13d1 822
mluis 0:62d1edcc13d1 823 // enable antenna switch for TX
mluis 0:62d1edcc13d1 824 hal_pin_rxtx(1);
mluis 0:62d1edcc13d1 825
mluis 0:62d1edcc13d1 826 // now we actually start the transmission
mluis 0:62d1edcc13d1 827 opmode(OPMODE_TX);
mluis 0:62d1edcc13d1 828 }
mluis 0:62d1edcc13d1 829
mluis 0:62d1edcc13d1 830 // start transmitter (buf=LMIC.frame, len=LMIC.dataLen)
mluis 1:d3b7bde3995c 831 static void starttx () {
mluis 0:62d1edcc13d1 832 ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP );
mluis 0:62d1edcc13d1 833 if(getSf(LMIC.rps) == FSK) { // FSK modem
mluis 0:62d1edcc13d1 834 txfsk();
mluis 0:62d1edcc13d1 835 } else { // LoRa modem
mluis 0:62d1edcc13d1 836 txlora();
mluis 0:62d1edcc13d1 837 }
mluis 0:62d1edcc13d1 838 // the radio will go back to STANDBY mode as soon as the TX is finished
mluis 0:62d1edcc13d1 839 // the corresponding IRQ will inform us about completion.
mluis 0:62d1edcc13d1 840 }
mluis 0:62d1edcc13d1 841
mluis 0:62d1edcc13d1 842 enum { RXMODE_SINGLE, RXMODE_SCAN, RXMODE_RSSI };
mluis 0:62d1edcc13d1 843
mluis 0:62d1edcc13d1 844 static const u1_t rxlorairqmask[] = {
mluis 0:62d1edcc13d1 845 [RXMODE_SINGLE] = IRQ_LORA_RXDONE_MASK|IRQ_LORA_RXTOUT_MASK,
mluis 0:62d1edcc13d1 846 [RXMODE_SCAN] = IRQ_LORA_RXDONE_MASK,
mluis 0:62d1edcc13d1 847 [RXMODE_RSSI] = 0x00,
mluis 0:62d1edcc13d1 848 };
mluis 0:62d1edcc13d1 849
mluis 0:62d1edcc13d1 850 // start LoRa receiver (time=LMIC.rxtime, timeout=LMIC.rxsyms, result=LMIC.frame[LMIC.dataLen])
mluis 0:62d1edcc13d1 851 static void rxlora (u1_t rxmode) {
mluis 0:62d1edcc13d1 852 // select LoRa modem (from sleep mode)
mluis 0:62d1edcc13d1 853 opmodeLora();
mluis 0:62d1edcc13d1 854 ASSERT((readReg(RegOpMode) & OPMODE_LORA) != 0);
mluis 0:62d1edcc13d1 855 // enter standby mode (warm up))
mluis 0:62d1edcc13d1 856 opmode(OPMODE_STANDBY);
mluis 1:d3b7bde3995c 857 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 858 txStateIo = 0;
mluis 1:d3b7bde3995c 859 rxStateIo = 0;
mluis 1:d3b7bde3995c 860 #endif
mluis 0:62d1edcc13d1 861 // don't use MAC settings at startup
mluis 0:62d1edcc13d1 862 if(rxmode == RXMODE_RSSI) { // use fixed settings for rssi scan
mluis 0:62d1edcc13d1 863 writeReg(LORARegModemConfig1, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG1);
mluis 0:62d1edcc13d1 864 writeReg(LORARegModemConfig2, RXLORA_RXMODE_RSSI_REG_MODEM_CONFIG2);
mluis 0:62d1edcc13d1 865 } else { // single or continuous rx mode
mluis 0:62d1edcc13d1 866 // configure LoRa modem (cfg1, cfg2)
mluis 0:62d1edcc13d1 867 configLoraModem();
mluis 0:62d1edcc13d1 868 // configure frequency
mluis 0:62d1edcc13d1 869 configChannel();
mluis 0:62d1edcc13d1 870 }
mluis 0:62d1edcc13d1 871 // set LNA gain
mluis 0:62d1edcc13d1 872 writeReg(RegLna, LNA_RX_GAIN);
mluis 0:62d1edcc13d1 873 // set max payload size
mluis 0:62d1edcc13d1 874 writeReg(LORARegPayloadMaxLength, 64);
mluis 0:62d1edcc13d1 875 // use inverted I/Q signal (prevent mote-to-mote communication)
mluis 0:62d1edcc13d1 876 writeReg(LORARegInvertIQ, readReg(LORARegInvertIQ)|(1<<6));
mluis 0:62d1edcc13d1 877 // set symbol timeout (for single rx)
mluis 0:62d1edcc13d1 878 writeReg(LORARegSymbTimeoutLsb, LMIC.rxsyms);
mluis 0:62d1edcc13d1 879 // set sync word
mluis 0:62d1edcc13d1 880 writeReg(LORARegSyncWord, LORA_MAC_PREAMBLE);
mluis 0:62d1edcc13d1 881
mluis 0:62d1edcc13d1 882 // configure DIO mapping DIO0=RxDone DIO1=RxTout DIO2=NOP
mluis 0:62d1edcc13d1 883 writeReg(RegDioMapping1, MAP_DIO0_LORA_RXDONE|MAP_DIO1_LORA_RXTOUT|MAP_DIO2_LORA_NOP);
mluis 0:62d1edcc13d1 884 // clear all radio IRQ flags
mluis 0:62d1edcc13d1 885 writeReg(LORARegIrqFlags, 0xFF);
mluis 0:62d1edcc13d1 886 // enable required radio IRQs
mluis 0:62d1edcc13d1 887 writeReg(LORARegIrqFlagsMask, ~rxlorairqmask[rxmode]);
mluis 0:62d1edcc13d1 888
mluis 0:62d1edcc13d1 889 // enable antenna switch for RX
mluis 0:62d1edcc13d1 890 hal_pin_rxtx(0);
mluis 0:62d1edcc13d1 891
mluis 0:62d1edcc13d1 892 // now instruct the radio to receive
mluis 0:62d1edcc13d1 893 if (rxmode == RXMODE_SINGLE) { // single rx
mluis 0:62d1edcc13d1 894 hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
mluis 1:d3b7bde3995c 895 opmode(OPMODE_RX_SINGLE);
mluis 1:d3b7bde3995c 896 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 897 rxStateIo = 1;
mluis 1:d3b7bde3995c 898 #endif
mluis 0:62d1edcc13d1 899 } else { // continous rx (scan or rssi)
mluis 1:d3b7bde3995c 900 opmode(OPMODE_RX);
mluis 1:d3b7bde3995c 901 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 902 rxStateIo = 1;
mluis 1:d3b7bde3995c 903 #endif
mluis 0:62d1edcc13d1 904 }
mluis 0:62d1edcc13d1 905 }
mluis 0:62d1edcc13d1 906
mluis 0:62d1edcc13d1 907 static void rxfsk (u1_t rxmode) {
mluis 0:62d1edcc13d1 908 // only single rx (no continuous scanning, no noise sampling)
mluis 0:62d1edcc13d1 909 ASSERT( rxmode == RXMODE_SINGLE );
mluis 0:62d1edcc13d1 910 // select FSK modem (from sleep mode)
mluis 0:62d1edcc13d1 911 //writeReg(RegOpMode, 0x00); // (not LoRa)
mluis 0:62d1edcc13d1 912 opmodeFSK();
mluis 0:62d1edcc13d1 913 ASSERT((readReg(RegOpMode) & OPMODE_LORA) == 0);
mluis 0:62d1edcc13d1 914 // enter standby mode (warm up))
mluis 0:62d1edcc13d1 915 opmode(OPMODE_STANDBY);
mluis 1:d3b7bde3995c 916 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 917 txStateIo = 0;
mluis 1:d3b7bde3995c 918 rxStateIo = 0;
mluis 1:d3b7bde3995c 919 #endif
mluis 0:62d1edcc13d1 920 // configure frequency
mluis 0:62d1edcc13d1 921 configChannel();
mluis 0:62d1edcc13d1 922 // set LNA gain
mluis 0:62d1edcc13d1 923 //writeReg(RegLna, 0x20|0x03); // max gain, boost enable
mluis 0:62d1edcc13d1 924 writeReg(RegLna, LNA_RX_GAIN);
mluis 0:62d1edcc13d1 925 // configure receiver
mluis 0:62d1edcc13d1 926 writeReg(FSKRegRxConfig, 0x1E); // AFC auto, AGC, trigger on preamble?!?
mluis 0:62d1edcc13d1 927 // set receiver bandwidth
mluis 0:62d1edcc13d1 928 writeReg(FSKRegRxBw, 0x0B); // 50kHz SSb
mluis 0:62d1edcc13d1 929 // set AFC bandwidth
mluis 0:62d1edcc13d1 930 writeReg(FSKRegAfcBw, 0x12); // 83.3kHz SSB
mluis 0:62d1edcc13d1 931 // set preamble detection
mluis 0:62d1edcc13d1 932 writeReg(FSKRegPreambleDetect, 0xAA); // enable, 2 bytes, 10 chip errors
mluis 0:62d1edcc13d1 933 // set sync config
mluis 0:62d1edcc13d1 934 writeReg(FSKRegSyncConfig, 0x12); // no auto restart, preamble 0xAA, enable, fill FIFO, 3 bytes sync
mluis 0:62d1edcc13d1 935 // set packet config
mluis 0:62d1edcc13d1 936 writeReg(FSKRegPacketConfig1, 0xD8); // var-length, whitening, crc, no auto-clear, no adr filter
mluis 0:62d1edcc13d1 937 writeReg(FSKRegPacketConfig2, 0x40); // packet mode
mluis 0:62d1edcc13d1 938 // set sync value
mluis 0:62d1edcc13d1 939 writeReg(FSKRegSyncValue1, 0xC1);
mluis 0:62d1edcc13d1 940 writeReg(FSKRegSyncValue2, 0x94);
mluis 0:62d1edcc13d1 941 writeReg(FSKRegSyncValue3, 0xC1);
mluis 0:62d1edcc13d1 942 // set preamble timeout
mluis 0:62d1edcc13d1 943 writeReg(FSKRegRxTimeout2, 0xFF);//(LMIC.rxsyms+1)/2);
mluis 0:62d1edcc13d1 944 // set bitrate
mluis 0:62d1edcc13d1 945 writeReg(FSKRegBitrateMsb, 0x02); // 50kbps
mluis 0:62d1edcc13d1 946 writeReg(FSKRegBitrateLsb, 0x80);
mluis 0:62d1edcc13d1 947 // set frequency deviation
mluis 0:62d1edcc13d1 948 writeReg(FSKRegFdevMsb, 0x01); // +/- 25kHz
mluis 0:62d1edcc13d1 949 writeReg(FSKRegFdevLsb, 0x99);
mluis 0:62d1edcc13d1 950
mluis 0:62d1edcc13d1 951 // configure DIO mapping DIO0=PayloadReady DIO1=NOP DIO2=TimeOut
mluis 0:62d1edcc13d1 952 writeReg(RegDioMapping1, MAP_DIO0_FSK_READY|MAP_DIO1_FSK_NOP|MAP_DIO2_FSK_TIMEOUT);
mluis 0:62d1edcc13d1 953
mluis 0:62d1edcc13d1 954 // enable antenna switch for RX
mluis 0:62d1edcc13d1 955 hal_pin_rxtx(0);
mluis 0:62d1edcc13d1 956
mluis 0:62d1edcc13d1 957 // now instruct the radio to receive
mluis 0:62d1edcc13d1 958 hal_waitUntil(LMIC.rxtime); // busy wait until exact rx time
mluis 0:62d1edcc13d1 959 opmode(OPMODE_RX); // no single rx mode available in FSK
mluis 1:d3b7bde3995c 960 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 961 rxStateIo = 1;
mluis 1:d3b7bde3995c 962 #endif
mluis 0:62d1edcc13d1 963 }
mluis 0:62d1edcc13d1 964
mluis 0:62d1edcc13d1 965 static void startrx (u1_t rxmode) {
mluis 0:62d1edcc13d1 966 ASSERT( (readReg(RegOpMode) & OPMODE_MASK) == OPMODE_SLEEP );
mluis 0:62d1edcc13d1 967 if(getSf(LMIC.rps) == FSK) { // FSK modem
mluis 0:62d1edcc13d1 968 rxfsk(rxmode);
mluis 0:62d1edcc13d1 969 } else { // LoRa modem
mluis 0:62d1edcc13d1 970 rxlora(rxmode);
mluis 0:62d1edcc13d1 971 }
mluis 0:62d1edcc13d1 972 // the radio will go back to STANDBY mode as soon as the RX is finished
mluis 0:62d1edcc13d1 973 // or timed out, and the corresponding IRQ will inform us about completion.
mluis 0:62d1edcc13d1 974 }
mluis 0:62d1edcc13d1 975
mluis 0:62d1edcc13d1 976 // get random seed from wideband noise rssi
mluis 1:d3b7bde3995c 977 void radio_init () {
mluis 0:62d1edcc13d1 978 hal_disableIRQs();
mluis 0:62d1edcc13d1 979
mluis 0:62d1edcc13d1 980 // manually reset radio
mluis 0:62d1edcc13d1 981 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 982 hal_pin_rst(0); // drive RST pin low
mluis 0:62d1edcc13d1 983 #else
mluis 0:62d1edcc13d1 984 hal_pin_rst(1); // drive RST pin high
mluis 0:62d1edcc13d1 985 #endif
mluis 0:62d1edcc13d1 986 hal_waitUntil(os_getTime()+ms2osticks(1)); // wait >100us
mluis 0:62d1edcc13d1 987 hal_pin_rst(2); // configure RST pin floating!
mluis 0:62d1edcc13d1 988 hal_waitUntil(os_getTime()+ms2osticks(5)); // wait 5ms
mluis 0:62d1edcc13d1 989
mluis 0:62d1edcc13d1 990 opmode(OPMODE_SLEEP);
mluis 1:d3b7bde3995c 991 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 992 txStateIo = 0;
mluis 1:d3b7bde3995c 993 rxStateIo = 0;
mluis 1:d3b7bde3995c 994 #endif
mluis 0:62d1edcc13d1 995 // some sanity checks, e.g., read version number
mluis 0:62d1edcc13d1 996 u1_t v = readReg(RegVersion);
mluis 0:62d1edcc13d1 997 #ifdef CFG_sx1276_radio
mluis 0:62d1edcc13d1 998 ASSERT(v == 0x12 );
mluis 0:62d1edcc13d1 999 #elif CFG_sx1272_radio
mluis 0:62d1edcc13d1 1000 ASSERT(v == 0x22);
mluis 0:62d1edcc13d1 1001 #else
mluis 0:62d1edcc13d1 1002 #error Missing CFG_sx1272_radio/CFG_sx1276_radio
mluis 0:62d1edcc13d1 1003 #endif
mluis 0:62d1edcc13d1 1004 // seed 15-byte randomness via noise rssi
mluis 0:62d1edcc13d1 1005 rxlora(RXMODE_RSSI);
mluis 0:62d1edcc13d1 1006 while( (readReg(RegOpMode) & OPMODE_MASK) != OPMODE_RX ); // continuous rx
mluis 0:62d1edcc13d1 1007 for(int i=1; i<16; i++) {
mluis 0:62d1edcc13d1 1008 for(int j=0; j<8; j++) {
mluis 0:62d1edcc13d1 1009 u1_t b; // wait for two non-identical subsequent least-significant bits
mluis 0:62d1edcc13d1 1010 while( (b = readReg(LORARegRssiWideband) & 0x01) == (readReg(LORARegRssiWideband) & 0x01) );
mluis 0:62d1edcc13d1 1011 randbuf[i] = (randbuf[i] << 1) | b;
mluis 0:62d1edcc13d1 1012 }
mluis 0:62d1edcc13d1 1013 }
mluis 0:62d1edcc13d1 1014 randbuf[0] = 16; // set initial index
mluis 0:62d1edcc13d1 1015
mluis 1:d3b7bde3995c 1016 #ifdef CFG_sx1276mb1_board
mluis 0:62d1edcc13d1 1017 // chain calibration
mluis 0:62d1edcc13d1 1018 writeReg(RegPaConfig, 0);
mluis 0:62d1edcc13d1 1019
mluis 0:62d1edcc13d1 1020 // Launch Rx chain calibration for LF band
mluis 0:62d1edcc13d1 1021 writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
mluis 0:62d1edcc13d1 1022 while((readReg(FSKRegImageCal)&RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING){ ; }
mluis 0:62d1edcc13d1 1023
mluis 0:62d1edcc13d1 1024 // Sets a Frequency in HF band
mluis 0:62d1edcc13d1 1025 u4_t frf = 868000000;
mluis 0:62d1edcc13d1 1026 writeReg(RegFrfMsb, (u1_t)(frf>>16));
mluis 0:62d1edcc13d1 1027 writeReg(RegFrfMid, (u1_t)(frf>> 8));
mluis 0:62d1edcc13d1 1028 writeReg(RegFrfLsb, (u1_t)(frf>> 0));
mluis 0:62d1edcc13d1 1029
mluis 0:62d1edcc13d1 1030 // Launch Rx chain calibration for HF band
mluis 0:62d1edcc13d1 1031 writeReg(FSKRegImageCal, (readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_MASK)|RF_IMAGECAL_IMAGECAL_START);
mluis 0:62d1edcc13d1 1032 while((readReg(FSKRegImageCal) & RF_IMAGECAL_IMAGECAL_RUNNING) == RF_IMAGECAL_IMAGECAL_RUNNING) { ; }
mluis 1:d3b7bde3995c 1033 #endif /* CFG_sx1276mb1_board */
mluis 0:62d1edcc13d1 1034
mluis 0:62d1edcc13d1 1035 opmode(OPMODE_SLEEP);
mluis 1:d3b7bde3995c 1036 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 1037 txStateIo = 0;
mluis 1:d3b7bde3995c 1038 rxStateIo = 0;
mluis 1:d3b7bde3995c 1039 #endif
mluis 0:62d1edcc13d1 1040 hal_enableIRQs();
mluis 0:62d1edcc13d1 1041 }
mluis 0:62d1edcc13d1 1042
mluis 0:62d1edcc13d1 1043 // return next random byte derived from seed buffer
mluis 0:62d1edcc13d1 1044 // (buf[0] holds index of next byte to be returned)
mluis 1:d3b7bde3995c 1045 u1_t radio_rand1 () {
mluis 0:62d1edcc13d1 1046 u1_t i = randbuf[0];
mluis 0:62d1edcc13d1 1047 ASSERT( i != 0 );
mluis 0:62d1edcc13d1 1048 if( i==16 ) {
mluis 0:62d1edcc13d1 1049 os_aes(AES_ENC, randbuf, 16); // encrypt seed with any key
mluis 0:62d1edcc13d1 1050 i = 0;
mluis 0:62d1edcc13d1 1051 }
mluis 0:62d1edcc13d1 1052 u1_t v = randbuf[i++];
mluis 0:62d1edcc13d1 1053 randbuf[0] = i;
mluis 0:62d1edcc13d1 1054 return v;
mluis 0:62d1edcc13d1 1055 }
mluis 0:62d1edcc13d1 1056
mluis 1:d3b7bde3995c 1057 u1_t radio_rssi () {
mluis 0:62d1edcc13d1 1058 hal_disableIRQs();
mluis 0:62d1edcc13d1 1059 u1_t r = readReg(LORARegRssiValue);
mluis 0:62d1edcc13d1 1060 hal_enableIRQs();
mluis 0:62d1edcc13d1 1061 return r;
mluis 0:62d1edcc13d1 1062 }
mluis 0:62d1edcc13d1 1063
mluis 0:62d1edcc13d1 1064 static const u2_t LORA_RXDONE_FIXUP[] = {
mluis 0:62d1edcc13d1 1065 [FSK] = us2osticks(0), // ( 0 ticks)
mluis 0:62d1edcc13d1 1066 [SF7] = us2osticks(0), // ( 0 ticks)
mluis 0:62d1edcc13d1 1067 [SF8] = us2osticks(1648), // ( 54 ticks)
mluis 0:62d1edcc13d1 1068 [SF9] = us2osticks(3265), // ( 107 ticks)
mluis 0:62d1edcc13d1 1069 [SF10] = us2osticks(7049), // ( 231 ticks)
mluis 0:62d1edcc13d1 1070 [SF11] = us2osticks(13641), // ( 447 ticks)
mluis 0:62d1edcc13d1 1071 [SF12] = us2osticks(31189), // (1022 ticks)
mluis 0:62d1edcc13d1 1072 };
mluis 0:62d1edcc13d1 1073
mluis 0:62d1edcc13d1 1074 // called by hal ext IRQ handler
mluis 0:62d1edcc13d1 1075 // (radio goes to stanby mode after tx/rx operations)
mluis 0:62d1edcc13d1 1076 void radio_irq_handler (u1_t dio) {
mluis 0:62d1edcc13d1 1077 ostime_t now = os_getTime();
mluis 0:62d1edcc13d1 1078 if( (readReg(RegOpMode) & OPMODE_LORA) != 0) { // LORA modem
mluis 1:d3b7bde3995c 1079 u1_t flags = readReg(LORARegIrqFlags);
mluis 1:d3b7bde3995c 1080 if( flags & IRQ_LORA_TXDONE_MASK ) {
mluis 1:d3b7bde3995c 1081 // save exact tx time
mluis 1:d3b7bde3995c 1082 LMIC.txend = now - us2osticks(43); // TXDONE FIXUP
mluis 1:d3b7bde3995c 1083 } else if( flags & IRQ_LORA_RXDONE_MASK ) {
mluis 1:d3b7bde3995c 1084 // save exact rx time
mluis 1:d3b7bde3995c 1085 if(getBw(LMIC.rps) == BW125) {
mluis 1:d3b7bde3995c 1086 now -= LORA_RXDONE_FIXUP[getSf(LMIC.rps)];
mluis 1:d3b7bde3995c 1087 }
mluis 1:d3b7bde3995c 1088 LMIC.rxtime = now;
mluis 1:d3b7bde3995c 1089 // read the PDU and inform the MAC that we received something
mluis 1:d3b7bde3995c 1090 LMIC.dataLen = (readReg(LORARegModemConfig1) & SX1272_MC1_IMPLICIT_HEADER_MODE_ON) ?
mluis 1:d3b7bde3995c 1091 readReg(LORARegPayloadLength) : readReg(LORARegRxNbBytes);
mluis 1:d3b7bde3995c 1092 // set FIFO read address pointer
mluis 1:d3b7bde3995c 1093 writeReg(LORARegFifoAddrPtr, readReg(LORARegFifoRxCurrentAddr));
mluis 1:d3b7bde3995c 1094 // now read the FIFO
mluis 1:d3b7bde3995c 1095 readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
mluis 1:d3b7bde3995c 1096 // read rx quality parameters
mluis 1:d3b7bde3995c 1097 LMIC.snr = readReg(LORARegPktSnrValue); // SNR [dB] * 4
mluis 1:d3b7bde3995c 1098 LMIC.rssi = readReg(LORARegPktRssiValue) - 125 + 64; // RSSI [dBm] (-196...+63)
mluis 1:d3b7bde3995c 1099 } else if( flags & IRQ_LORA_RXTOUT_MASK ) {
mluis 1:d3b7bde3995c 1100 // indicate timeout
mluis 1:d3b7bde3995c 1101 LMIC.dataLen = 0;
mluis 1:d3b7bde3995c 1102 }
mluis 0:62d1edcc13d1 1103 // mask all radio IRQs
mluis 0:62d1edcc13d1 1104 writeReg(LORARegIrqFlagsMask, 0xFF);
mluis 0:62d1edcc13d1 1105 // clear radio IRQ flags
mluis 0:62d1edcc13d1 1106 writeReg(LORARegIrqFlags, 0xFF);
mluis 0:62d1edcc13d1 1107 } else { // FSK modem
mluis 1:d3b7bde3995c 1108 u1_t flags1 = readReg(FSKRegIrqFlags1);
mluis 1:d3b7bde3995c 1109 u1_t flags2 = readReg(FSKRegIrqFlags2);
mluis 1:d3b7bde3995c 1110 if( flags2 & IRQ_FSK2_PACKETSENT_MASK ) {
mluis 1:d3b7bde3995c 1111 // save exact tx time
mluis 1:d3b7bde3995c 1112 LMIC.txend = now;
mluis 0:62d1edcc13d1 1113 } else if( flags2 & IRQ_FSK2_PAYLOADREADY_MASK ) {
mluis 1:d3b7bde3995c 1114 // save exact rx time
mluis 1:d3b7bde3995c 1115 LMIC.rxtime = now;
mluis 1:d3b7bde3995c 1116 // read the PDU and inform the MAC that we received something
mluis 1:d3b7bde3995c 1117 LMIC.dataLen = readReg(FSKRegPayloadLength);
mluis 1:d3b7bde3995c 1118 // now read the FIFO
mluis 1:d3b7bde3995c 1119 readBuf(RegFifo, LMIC.frame, LMIC.dataLen);
mluis 1:d3b7bde3995c 1120 // read rx quality parameters
mluis 1:d3b7bde3995c 1121 LMIC.snr = 0; // determine snr
mluis 1:d3b7bde3995c 1122 LMIC.rssi = 0; // determine rssi
mluis 1:d3b7bde3995c 1123 } else if( flags1 & IRQ_FSK1_TIMEOUT_MASK ) {
mluis 1:d3b7bde3995c 1124 // indicate timeout
mluis 1:d3b7bde3995c 1125 LMIC.dataLen = 0;
mluis 1:d3b7bde3995c 1126 } else {
mluis 0:62d1edcc13d1 1127 while(1);
mluis 0:62d1edcc13d1 1128 }
mluis 0:62d1edcc13d1 1129 }
mluis 0:62d1edcc13d1 1130 // go from stanby to sleep
mluis 0:62d1edcc13d1 1131 opmode(OPMODE_SLEEP);
mluis 1:d3b7bde3995c 1132 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 1133 txStateIo = 0;
mluis 1:d3b7bde3995c 1134 rxStateIo = 0;
mluis 1:d3b7bde3995c 1135 #endif
mluis 0:62d1edcc13d1 1136 // run os job (use preset func ptr)
mluis 0:62d1edcc13d1 1137 os_setCallback(&LMIC.osjob, LMIC.osjob.func);
mluis 0:62d1edcc13d1 1138 }
mluis 0:62d1edcc13d1 1139
mluis 0:62d1edcc13d1 1140 void os_radio (u1_t mode) {
mluis 0:62d1edcc13d1 1141 hal_disableIRQs();
mluis 0:62d1edcc13d1 1142 switch (mode) {
mluis 0:62d1edcc13d1 1143 case RADIO_RST:
mluis 0:62d1edcc13d1 1144 // put radio to sleep
mluis 0:62d1edcc13d1 1145 opmode(OPMODE_SLEEP);
mluis 1:d3b7bde3995c 1146 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 1147 txStateIo = 0;
mluis 1:d3b7bde3995c 1148 rxStateIo = 0;
mluis 1:d3b7bde3995c 1149 #endif
mluis 0:62d1edcc13d1 1150 break;
mluis 0:62d1edcc13d1 1151
mluis 0:62d1edcc13d1 1152 case RADIO_TX:
mluis 1:d3b7bde3995c 1153 // transmit frame now
mluis 0:62d1edcc13d1 1154 starttx(); // buf=LMIC.frame, len=LMIC.dataLen
mluis 1:d3b7bde3995c 1155 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 1156 txStateIo = 1;
mluis 1:d3b7bde3995c 1157 #endif
mluis 0:62d1edcc13d1 1158 break;
mluis 0:62d1edcc13d1 1159
mluis 0:62d1edcc13d1 1160 case RADIO_RX:
mluis 1:d3b7bde3995c 1161 // receive frame now (exactly at rxtime)
mluis 0:62d1edcc13d1 1162 startrx(RXMODE_SINGLE); // buf=LMIC.frame, time=LMIC.rxtime, timeout=LMIC.rxsyms
mluis 1:d3b7bde3995c 1163 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 1164 rxStateIo = 1;
mluis 1:d3b7bde3995c 1165 #endif
mluis 0:62d1edcc13d1 1166 break;
mluis 0:62d1edcc13d1 1167
mluis 0:62d1edcc13d1 1168 case RADIO_RXON:
mluis 0:62d1edcc13d1 1169 // start scanning for beacon now
mluis 0:62d1edcc13d1 1170 startrx(RXMODE_SCAN); // buf=LMIC.frame
mluis 1:d3b7bde3995c 1171 #if defined(RADIO_DBG)
mluis 1:d3b7bde3995c 1172 rxStateIo = 1;
mluis 1:d3b7bde3995c 1173 #endif
mluis 0:62d1edcc13d1 1174 break;
mluis 0:62d1edcc13d1 1175 }
mluis 0:62d1edcc13d1 1176 hal_enableIRQs();
mluis 0:62d1edcc13d1 1177 }
mluis 0:62d1edcc13d1 1178
mluis 0:62d1edcc13d1 1179 #endif // USE_SMTC_RADIO_DRIVER