Aloha implementation of LoRa technology

Dependencies:   SX1276Lib mbed

Fork of SX1276PingPong by Semtech

Committer:
rba90
Date:
Tue May 31 09:52:21 2016 +0000
Revision:
15:f790f35839db
Parent:
14:c7251480feb9
Child:
16:c3c6b13c3c42
Initial prototype

Who changed what in which revision?

UserRevisionLine numberNew contents of line
GregCr 0:1ed39951ab7b 1 #include "mbed.h"
GregCr 4:5ece30264cd9 2 #include "main.h"
GregCr 14:c7251480feb9 3 #include "sx1276-hal.h"
GregCr 8:f956dee63a56 4 #include "debug.h"
rba90 15:f790f35839db 5 #include "Aloha.h"
rba90 15:f790f35839db 6 #include "AlohaPacket.h"
GregCr 0:1ed39951ab7b 7
GregCr 0:1ed39951ab7b 8 /* Set this flag to '1' to display debug messages on the console */
rba90 15:f790f35839db 9 #define DEBUG_MESSAGE 1
GregCr 0:1ed39951ab7b 10
GregCr 5:f2431c4fe3bb 11 #define RF_FREQUENCY 868000000 // Hz
GregCr 0:1ed39951ab7b 12 #define TX_OUTPUT_POWER 14 // 14 dBm
rba90 15:f790f35839db 13 #define LORA_BANDWIDTH 2 // [0: 125 kHz,
rba90 15:f790f35839db 14 // 1: 250 kHz,
rba90 15:f790f35839db 15 // 2: 500 kHz,
rba90 15:f790f35839db 16 // 3: Reserved]
rba90 15:f790f35839db 17 #define LORA_SPREADING_FACTOR 7 // [SF7..SF12]
rba90 15:f790f35839db 18 #define LORA_CODINGRATE 1 // [1: 4/5,
rba90 15:f790f35839db 19 // 2: 4/6,
rba90 15:f790f35839db 20 // 3: 4/7,
rba90 15:f790f35839db 21 // 4: 4/8]
rba90 15:f790f35839db 22 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx
rba90 15:f790f35839db 23 #define LORA_SYMBOL_TIMEOUT 5 // Symbols
rba90 15:f790f35839db 24 #define LORA_FIX_LENGTH_PAYLOAD_ON false
rba90 15:f790f35839db 25 #define LORA_FHSS_ENABLED false
rba90 15:f790f35839db 26 #define LORA_NB_SYMB_HOP 4
rba90 15:f790f35839db 27 #define LORA_IQ_INVERSION_ON false
rba90 15:f790f35839db 28 #define LORA_CRC_ENABLED true
GregCr 0:1ed39951ab7b 29
GregCr 0:1ed39951ab7b 30
GregCr 7:c1bbd6c56979 31 #define RX_TIMEOUT_VALUE 3500000 // in us
rba90 15:f790f35839db 32 #define BUFFER_SIZE 4 // Define the payload size here
GregCr 0:1ed39951ab7b 33
GregCr 3:8b9e2a4df4b5 34 DigitalOut led(LED2);
rba90 15:f790f35839db 35
rba90 15:f790f35839db 36 uint16_t BufferSize = BUFFER_SIZE;
rba90 15:f790f35839db 37 uint8_t Buffer[BUFFER_SIZE];
rba90 15:f790f35839db 38
rba90 15:f790f35839db 39 int16_t RssiValue = 0.0;
rba90 15:f790f35839db 40 int8_t SnrValue = 0.0;
GregCr 3:8b9e2a4df4b5 41
GregCr 0:1ed39951ab7b 42 /*
GregCr 0:1ed39951ab7b 43 * Global variables declarations
GregCr 0:1ed39951ab7b 44 */
mluis 10:7af820d1e1df 45 typedef enum
mluis 10:7af820d1e1df 46 {
mluis 10:7af820d1e1df 47 LOWPOWER = 0,
mluis 10:7af820d1e1df 48 IDLE,
mluis 10:7af820d1e1df 49
mluis 10:7af820d1e1df 50 RX,
mluis 10:7af820d1e1df 51 RX_TIMEOUT,
mluis 10:7af820d1e1df 52 RX_ERROR,
mluis 10:7af820d1e1df 53
mluis 10:7af820d1e1df 54 TX,
mluis 10:7af820d1e1df 55 TX_TIMEOUT,
mluis 10:7af820d1e1df 56
mluis 10:7af820d1e1df 57 CAD,
mluis 10:7af820d1e1df 58 CAD_DONE
mluis 10:7af820d1e1df 59 }AppStates_t;
GregCr 0:1ed39951ab7b 60
mluis 10:7af820d1e1df 61 volatile AppStates_t State = LOWPOWER;
mluis 10:7af820d1e1df 62
rba90 15:f790f35839db 63
mluis 10:7af820d1e1df 64 /*!
mluis 10:7af820d1e1df 65 * Radio events function pointer
mluis 10:7af820d1e1df 66 */
mluis 10:7af820d1e1df 67 static RadioEvents_t RadioEvents;
mluis 10:7af820d1e1df 68
mluis 10:7af820d1e1df 69 /*
mluis 10:7af820d1e1df 70 * Global variables declarations
mluis 10:7af820d1e1df 71 */
GregCr 14:c7251480feb9 72 SX1276MB1xAS Radio( NULL );
GregCr 0:1ed39951ab7b 73
rba90 15:f790f35839db 74 // aloha protocol
rba90 15:f790f35839db 75 Aloha aloha;
GregCr 0:1ed39951ab7b 76
rba90 15:f790f35839db 77 void setExpire()
GregCr 0:1ed39951ab7b 78 {
rba90 15:f790f35839db 79 if (aloha.attempts >= ALOHA_MAX_ATTEMPT)
rba90 15:f790f35839db 80 {
rba90 15:f790f35839db 81 aloha.state = Aloha::EXPIRED;
rba90 15:f790f35839db 82 }
rba90 15:f790f35839db 83 else
rba90 15:f790f35839db 84 {
rba90 15:f790f35839db 85 aloha.state = Aloha::RETRANSMIT;
rba90 15:f790f35839db 86 aloha.delay = aloha.delay * aloha.delay;
rba90 15:f790f35839db 87 }
rba90 15:f790f35839db 88 }
mluis 10:7af820d1e1df 89
rba90 15:f790f35839db 90 void RadioInit()
rba90 15:f790f35839db 91 {
mluis 10:7af820d1e1df 92 // Initialize Radio driver
mluis 10:7af820d1e1df 93 RadioEvents.TxDone = OnTxDone;
mluis 10:7af820d1e1df 94 RadioEvents.RxDone = OnRxDone;
mluis 10:7af820d1e1df 95 RadioEvents.RxError = OnRxError;
mluis 10:7af820d1e1df 96 RadioEvents.TxTimeout = OnTxTimeout;
mluis 10:7af820d1e1df 97 RadioEvents.RxTimeout = OnRxTimeout;
mluis 10:7af820d1e1df 98 Radio.Init( &RadioEvents );
GregCr 0:1ed39951ab7b 99
rba90 15:f790f35839db 100 // detect radio hardware
GregCr 7:c1bbd6c56979 101 while( Radio.Read( REG_VERSION ) == 0x00 )
GregCr 2:59e108728d71 102 {
rba90 15:f790f35839db 103 printf( "Radio could not be detected!\n\r" );
GregCr 7:c1bbd6c56979 104 wait( 1 );
GregCr 2:59e108728d71 105 }
rba90 15:f790f35839db 106 printf("RadioRegVersion: %d\r\n", Radio.Read( REG_VERSION ));
GregCr 14:c7251480feb9 107
rba90 15:f790f35839db 108 // set radio frequency channel
GregCr 0:1ed39951ab7b 109 Radio.SetChannel( RF_FREQUENCY );
GregCr 3:8b9e2a4df4b5 110
rba90 15:f790f35839db 111 // set radio parameter
GregCr 0:1ed39951ab7b 112 Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH,
GregCr 0:1ed39951ab7b 113 LORA_SPREADING_FACTOR, LORA_CODINGRATE,
GregCr 0:1ed39951ab7b 114 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON,
GregCr 3:8b9e2a4df4b5 115 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
GregCr 7:c1bbd6c56979 116 LORA_IQ_INVERSION_ON, 2000000 );
GregCr 0:1ed39951ab7b 117
GregCr 0:1ed39951ab7b 118 Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR,
GregCr 0:1ed39951ab7b 119 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH,
mluis 9:e764990e45df 120 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0,
GregCr 3:8b9e2a4df4b5 121 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP,
GregCr 3:8b9e2a4df4b5 122 LORA_IQ_INVERSION_ON, true );
rba90 15:f790f35839db 123 }
rba90 15:f790f35839db 124
GregCr 0:1ed39951ab7b 125
rba90 15:f790f35839db 126 int main()
rba90 15:f790f35839db 127 {
rba90 15:f790f35839db 128 RadioInit();
GregCr 0:1ed39951ab7b 129
rba90 15:f790f35839db 130 while (1)
GregCr 0:1ed39951ab7b 131 {
GregCr 0:1ed39951ab7b 132 switch( State )
GregCr 0:1ed39951ab7b 133 {
GregCr 0:1ed39951ab7b 134 case RX:
rba90 15:f790f35839db 135 // if the receive frame is an ack, then cancel the timer
rba90 15:f790f35839db 136 // otherwise process the frame
rba90 15:f790f35839db 137 HeaderStruct header;
rba90 15:f790f35839db 138 memset(&header, 0, sizeof(header));
rba90 15:f790f35839db 139
rba90 15:f790f35839db 140 if (header.fid == 0x01)
GregCr 0:1ed39951ab7b 141 {
rba90 15:f790f35839db 142 aloha.AlohaAckTimeout.detach();
GregCr 0:1ed39951ab7b 143 }
rba90 15:f790f35839db 144
rba90 15:f790f35839db 145 // TODO: process the frame
GregCr 0:1ed39951ab7b 146 break;
rba90 15:f790f35839db 147 case TX:
rba90 15:f790f35839db 148 // transmit done
rba90 15:f790f35839db 149 // then set state to aloha pending and start the timer
rba90 15:f790f35839db 150 aloha.state = Aloha::PENDING;
rba90 15:f790f35839db 151 aloha.delay = Radio.Random();
rba90 15:f790f35839db 152 aloha.AlohaAckTimeout.detach();
rba90 15:f790f35839db 153 aloha.AlohaAckTimeout.attach_us(&setExpire, aloha.delay);
rba90 15:f790f35839db 154 aloha.attempts += 1;
GregCr 0:1ed39951ab7b 155 break;
GregCr 0:1ed39951ab7b 156 case RX_TIMEOUT:
rba90 15:f790f35839db 157 // enter listening mode
GregCr 0:1ed39951ab7b 158 break;
GregCr 0:1ed39951ab7b 159 case RX_ERROR:
rba90 15:f790f35839db 160 // we don't handle crc failed situation
GregCr 0:1ed39951ab7b 161 break;
GregCr 0:1ed39951ab7b 162 case TX_TIMEOUT:
rba90 15:f790f35839db 163 // we don't handle hardware error
GregCr 0:1ed39951ab7b 164 break;
GregCr 0:1ed39951ab7b 165 case LOWPOWER:
GregCr 0:1ed39951ab7b 166 break;
GregCr 0:1ed39951ab7b 167 default:
rba90 15:f790f35839db 168 break;
rba90 15:f790f35839db 169 }
rba90 15:f790f35839db 170
rba90 15:f790f35839db 171 switch (aloha.state)
rba90 15:f790f35839db 172 {
rba90 15:f790f35839db 173 case Aloha::IDLE:
rba90 15:f790f35839db 174 // transmit packet if any
rba90 15:f790f35839db 175 break;
rba90 15:f790f35839db 176
rba90 15:f790f35839db 177 case Aloha::PENDING:
rba90 15:f790f35839db 178 // set rx time
GregCr 0:1ed39951ab7b 179 break;
rba90 15:f790f35839db 180
rba90 15:f790f35839db 181 case Aloha::RETRANSMIT:
rba90 15:f790f35839db 182 // send the packet again
rba90 15:f790f35839db 183 // and setup the timer with new backoff delay
rba90 15:f790f35839db 184 aloha.AlohaAckTimeout.attach(&setExpire, aloha.delay);
rba90 15:f790f35839db 185 aloha.state = Aloha::PENDING;
rba90 15:f790f35839db 186 break;
rba90 15:f790f35839db 187 case Aloha::EXPIRED:
rba90 15:f790f35839db 188 // give up the transmission
rba90 15:f790f35839db 189 // back to idle
rba90 15:f790f35839db 190 aloha.state = Aloha::IDLE;
rba90 15:f790f35839db 191 break;
rba90 15:f790f35839db 192 }
GregCr 0:1ed39951ab7b 193 }
GregCr 0:1ed39951ab7b 194 }
GregCr 0:1ed39951ab7b 195
GregCr 0:1ed39951ab7b 196 void OnTxDone( void )
GregCr 0:1ed39951ab7b 197 {
GregCr 5:f2431c4fe3bb 198 Radio.Sleep( );
GregCr 0:1ed39951ab7b 199 State = TX;
rba90 15:f790f35839db 200 printf( "> OnTxDone\n\r" );
GregCr 0:1ed39951ab7b 201 }
GregCr 0:1ed39951ab7b 202
GregCr 4:5ece30264cd9 203 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
GregCr 0:1ed39951ab7b 204 {
GregCr 0:1ed39951ab7b 205 Radio.Sleep( );
GregCr 0:1ed39951ab7b 206 BufferSize = size;
GregCr 0:1ed39951ab7b 207 memcpy( Buffer, payload, BufferSize );
GregCr 0:1ed39951ab7b 208 RssiValue = rssi;
GregCr 0:1ed39951ab7b 209 SnrValue = snr;
GregCr 0:1ed39951ab7b 210 State = RX;
rba90 15:f790f35839db 211 printf( "> OnRxDone\n\r" );
GregCr 0:1ed39951ab7b 212 }
GregCr 0:1ed39951ab7b 213
GregCr 0:1ed39951ab7b 214 void OnTxTimeout( void )
GregCr 0:1ed39951ab7b 215 {
GregCr 0:1ed39951ab7b 216 Radio.Sleep( );
GregCr 0:1ed39951ab7b 217 State = TX_TIMEOUT;
rba90 15:f790f35839db 218 printf( "> OnTxTimeout\n\r" );
GregCr 0:1ed39951ab7b 219 }
GregCr 0:1ed39951ab7b 220
GregCr 0:1ed39951ab7b 221 void OnRxTimeout( void )
GregCr 0:1ed39951ab7b 222 {
GregCr 0:1ed39951ab7b 223 Radio.Sleep( );
GregCr 1:126d70d374f6 224 Buffer[ BufferSize ] = 0;
GregCr 0:1ed39951ab7b 225 State = RX_TIMEOUT;
rba90 15:f790f35839db 226 printf( "> OnRxTimeout\n\r" );
GregCr 0:1ed39951ab7b 227 }
GregCr 0:1ed39951ab7b 228
GregCr 0:1ed39951ab7b 229 void OnRxError( void )
GregCr 0:1ed39951ab7b 230 {
GregCr 0:1ed39951ab7b 231 Radio.Sleep( );
GregCr 0:1ed39951ab7b 232 State = RX_ERROR;
rba90 15:f790f35839db 233 printf( "> OnRxError\n\r" );
GregCr 0:1ed39951ab7b 234 }