ENEL400
/
Aloha
Aloha implementation of LoRa technology
Fork of SX1276PingPong by
Embed:
(wiki syntax)
Show/hide line numbers
main.cpp
00001 #include "mbed.h" 00002 #include "main.h" 00003 #include "sx1276-hal.h" 00004 #include "debug.h" 00005 #include "Aloha.h" 00006 #include "AlohaPacket.h" 00007 00008 /* Set this flag to '1' to display debug messages on the console */ 00009 #define DEBUG_MESSAGE 1 00010 00011 #define RF_FREQUENCY 868000000 // Hz 00012 #define TX_OUTPUT_POWER 14 // 14 dBm 00013 #define LORA_BANDWIDTH 2 // [0: 125 kHz, 00014 // 1: 250 kHz, 00015 // 2: 500 kHz, 00016 // 3: Reserved] 00017 #define LORA_SPREADING_FACTOR 7 // [SF7..SF12] 00018 #define LORA_CODINGRATE 1 // [1: 4/5, 00019 // 2: 4/6, 00020 // 3: 4/7, 00021 // 4: 4/8] 00022 #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx 00023 #define LORA_SYMBOL_TIMEOUT 5 // Symbols 00024 #define LORA_FIX_LENGTH_PAYLOAD_ON false 00025 #define LORA_FHSS_ENABLED false 00026 #define LORA_NB_SYMB_HOP 4 00027 #define LORA_IQ_INVERSION_ON false 00028 #define LORA_CRC_ENABLED true 00029 00030 00031 #define RX_TIMEOUT_VALUE 3500000 // in us 00032 #define BUFFER_SIZE 4 // Define the payload size here 00033 00034 DigitalOut led(LED2); 00035 00036 uint16_t BufferSize = BUFFER_SIZE; 00037 uint8_t Buffer[BUFFER_SIZE]; 00038 00039 int16_t RssiValue = 0.0; 00040 int8_t SnrValue = 0.0; 00041 00042 /* 00043 * Global variables declarations 00044 */ 00045 typedef enum 00046 { 00047 LOWPOWER = 0, 00048 IDLE, 00049 00050 RX, 00051 RX_TIMEOUT, 00052 RX_ERROR, 00053 00054 TX, 00055 TX_TIMEOUT, 00056 00057 CAD, 00058 CAD_DONE 00059 }AppStates_t; 00060 00061 volatile AppStates_t State = LOWPOWER; 00062 00063 00064 /*! 00065 * Radio events function pointer 00066 */ 00067 static RadioEvents_t RadioEvents; 00068 00069 /* 00070 * Global variables declarations 00071 */ 00072 SX1276MB1xAS Radio( NULL ); 00073 00074 // aloha protocol 00075 Aloha aloha; 00076 00077 // user button 00078 InterruptIn UserButton(USER_BUTTON); 00079 static int seqid = 0; 00080 00081 void sendMessage() 00082 { 00083 HeaderStruct header; 00084 DataStruct data; 00085 00086 memset(&header, 0, sizeof(header)); 00087 memset(&data, 0, sizeof(data)); 00088 00089 header.fid = 0x0; 00090 header.no = (uint8_t) seqid; 00091 data.pd0 = 0xff; 00092 data.pd1 = 0xff; 00093 00094 uint8_t buffer[4]; 00095 createAlohaPacket(buffer, &header, &data); 00096 00097 Radio.Send(buffer, 4); 00098 } 00099 00100 void sendAck(int id) 00101 { 00102 HeaderStruct header; 00103 DataStruct data; 00104 00105 memset(&header, 0, sizeof(header)); 00106 memset(&data, 0, sizeof(data)); 00107 00108 header.fid = 0x1; 00109 header.no = (uint8_t) id; 00110 data.pd0 = 0x00; 00111 data.pd1 = 0x00; 00112 00113 uint8_t buffer[4]; 00114 createAlohaPacket(buffer, &header, &data); 00115 00116 Radio.Send(buffer, 4); 00117 } 00118 00119 00120 void setExpire() 00121 { 00122 if (aloha.attempts >= ALOHA_MAX_ATTEMPT) 00123 { 00124 aloha.state = Aloha::EXPIRED; 00125 } 00126 else 00127 { 00128 aloha.state = Aloha::RETRANSMIT; 00129 } 00130 } 00131 00132 void userButtonHandler() 00133 { 00134 seqid += 1; 00135 sendMessage(); 00136 } 00137 00138 void RadioInit() 00139 { 00140 // Initialize Radio driver 00141 RadioEvents.TxDone = OnTxDone; 00142 RadioEvents.RxDone = OnRxDone; 00143 RadioEvents.RxError = OnRxError; 00144 RadioEvents.TxTimeout = OnTxTimeout; 00145 RadioEvents.RxTimeout = OnRxTimeout; 00146 Radio.Init( &RadioEvents ); 00147 00148 // detect radio hardware 00149 while( Radio.Read( REG_VERSION ) == 0x00 ) 00150 { 00151 printf( "Radio could not be detected!\n\r" ); 00152 wait( 1 ); 00153 } 00154 printf("RadioRegVersion: %d\r\n", Radio.Read( REG_VERSION )); 00155 00156 // set radio frequency channel 00157 Radio.SetChannel( RF_FREQUENCY ); 00158 00159 // set radio parameter 00160 Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, 00161 LORA_SPREADING_FACTOR, LORA_CODINGRATE, 00162 LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, 00163 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00164 LORA_IQ_INVERSION_ON, 2000000 ); 00165 00166 Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, 00167 LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, 00168 LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, 00169 LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, 00170 LORA_IQ_INVERSION_ON, true ); 00171 } 00172 00173 00174 int main() 00175 { 00176 RadioInit(); 00177 UserButton.rise(userButtonHandler); 00178 00179 Radio.Rx( RX_TIMEOUT_VALUE ); 00180 while (1) 00181 { 00182 switch( State ) 00183 { 00184 case RX: 00185 // if the receive frame is an ack, then cancel the timer 00186 // otherwise process the frame 00187 HeaderStruct header; 00188 DataStruct data; 00189 00190 memset(&header, 0, sizeof(header)); 00191 memset(&data, 0, sizeof(data)); 00192 00193 // decode data 00194 dissectAlohaPacket(Buffer, &header, &data); 00195 00196 // process packet 00197 switch (header.fid) 00198 { 00199 case 0x0: // data packet 00200 sendAck(header.no); 00201 break; 00202 00203 case 0x1: // ack received 00204 aloha.AlohaAckTimeout.detach(); 00205 aloha.state = Aloha::IDLE; 00206 break; 00207 00208 default: 00209 break; 00210 } 00211 00212 if (header.fid == 0x01) 00213 { 00214 aloha.AlohaAckTimeout.detach(); 00215 } 00216 00217 // TODO: process the frame 00218 00219 00220 printf("RECV::fid=0x%x, seqid=0x%x, pd0=0x%x, pd1=0x%x\r\n", header.fid, header.no, data.pd0, data.pd1); 00221 00222 // enter listening mode 00223 Radio.Rx( RX_TIMEOUT_VALUE ); 00224 00225 State = LOWPOWER; 00226 break; 00227 case TX: 00228 // transmit done 00229 // set the state to pending and attach the timer with random delay 00230 00231 // we dont need ack for ack 00232 if (aloha.state == Aloha::ACK_RESP) 00233 { 00234 aloha.state = Aloha::IDLE; 00235 break; 00236 } 00237 00238 // set delay time 00239 if (aloha.state == Aloha::IDLE) 00240 { 00241 aloha.delay = (Radio.Random() % 1000) / 1000.0f; 00242 } 00243 else if (aloha.state == Aloha::RETRANSMIT) 00244 { 00245 aloha.delay *= 2; 00246 } 00247 00248 aloha.AlohaAckTimeout.detach(); 00249 aloha.AlohaAckTimeout.attach(&setExpire, aloha.delay); 00250 00251 // increase the attempt counter 00252 aloha.attempts += 1; 00253 00254 // enter listening mode 00255 Radio.Rx( RX_TIMEOUT_VALUE ); 00256 00257 // state transition 00258 aloha.state = Aloha::PENDING; 00259 00260 State = LOWPOWER; 00261 break; 00262 case RX_TIMEOUT: 00263 // enter listening mode 00264 Radio.Rx( RX_TIMEOUT_VALUE ); 00265 00266 State = LOWPOWER; 00267 break; 00268 case RX_ERROR: 00269 // we don't handle crc failed situation 00270 // enter listening mode 00271 Radio.Rx( RX_TIMEOUT_VALUE ); 00272 00273 State = LOWPOWER; 00274 break; 00275 case TX_TIMEOUT: 00276 // we don't handle hardware error 00277 // enter listening mode 00278 Radio.Rx( RX_TIMEOUT_VALUE ); 00279 00280 State = LOWPOWER; 00281 break; 00282 case LOWPOWER: 00283 break; 00284 default: 00285 State = LOWPOWER; 00286 break; 00287 } 00288 00289 switch (aloha.state) 00290 { 00291 case Aloha::IDLE: 00292 // transmit packet if any 00293 // printf("Aloha::IDLE\r\n"); 00294 break; 00295 00296 case Aloha::PENDING: 00297 // set rx time 00298 // printf("Aloha::PENDING, delay=%f, attempt=%d\r\n", aloha.delay, aloha.attempts); 00299 break; 00300 00301 case Aloha::RETRANSMIT: 00302 // send the packet again 00303 sendMessage(); 00304 00305 // printf("Aloha::RETRANSMIT\r\n"); 00306 break; 00307 case Aloha::EXPIRED: 00308 // give up the transmission 00309 // back to idle 00310 aloha.attempts = 0; 00311 00312 aloha.state = Aloha::IDLE; 00313 // printf("Aloha::EXPIRED\r\n"); 00314 break; 00315 case Aloha::ACK_RESP: 00316 break; 00317 default: 00318 break; 00319 } 00320 } 00321 } 00322 00323 void OnTxDone( void ) 00324 { 00325 Radio.Sleep( ); 00326 State = TX; 00327 printf( "> OnTxDone\n\r" ); 00328 } 00329 00330 void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) 00331 { 00332 Radio.Sleep( ); 00333 BufferSize = size; 00334 memcpy( Buffer, payload, BufferSize ); 00335 RssiValue = rssi; 00336 SnrValue = snr; 00337 State = RX; 00338 printf( "> OnRxDone\n\r" ); 00339 } 00340 00341 void OnTxTimeout( void ) 00342 { 00343 Radio.Sleep( ); 00344 State = TX_TIMEOUT; 00345 printf( "> OnTxTimeout\n\r" ); 00346 } 00347 00348 void OnRxTimeout( void ) 00349 { 00350 Radio.Sleep( ); 00351 Buffer[ BufferSize ] = 0; 00352 State = RX_TIMEOUT; 00353 printf( "> OnRxTimeout\n\r" ); 00354 } 00355 00356 void OnRxError( void ) 00357 { 00358 Radio.Sleep( ); 00359 State = RX_ERROR; 00360 printf( "> OnRxError\n\r" ); 00361 }
Generated on Mon Jul 18 2022 00:06:05 by 1.7.2