ENEL400
/
Aloha
Aloha implementation of LoRa technology
Fork of SX1276PingPong by
main.cpp@15:f790f35839db, 2016-05-31 (annotated)
- 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?
User | Revision | Line number | New 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 | } |