projet-lievres
/
lora-project
Code du projet lièvres pour LoRa
main.cpp@5:d28a689b1635, 2016-10-14 (annotated)
- Committer:
- aGoelzer
- Date:
- Fri Oct 14 13:12:34 2016 +0000
- Revision:
- 5:d28a689b1635
- Parent:
- 4:954ae88b6664
Tab request
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
bLandais | 0:b239f8883fcc | 1 | #include "mbed.h" |
aGoelzer | 4:954ae88b6664 | 2 | #include "main.h" |
aGoelzer | 4:954ae88b6664 | 3 | #include "sx1272-hal.h" |
aGoelzer | 4:954ae88b6664 | 4 | #include "debug.h" |
aGoelzer | 4:954ae88b6664 | 5 | |
aGoelzer | 4:954ae88b6664 | 6 | /* Set this flag to '1' to display debug messages on the console */ |
aGoelzer | 4:954ae88b6664 | 7 | #define DEBUG_MESSAGE 1 |
aGoelzer | 4:954ae88b6664 | 8 | |
aGoelzer | 4:954ae88b6664 | 9 | /* Set this flag to '1' to use the LoRa modulation or to '0' to use FSK modulation */ |
aGoelzer | 4:954ae88b6664 | 10 | #define USE_MODEM_LORA 1 |
aGoelzer | 4:954ae88b6664 | 11 | #define USE_MODEM_FSK !USE_MODEM_LORA |
aGoelzer | 4:954ae88b6664 | 12 | |
aGoelzer | 4:954ae88b6664 | 13 | #define RF_FREQUENCY 868000000 // Hz |
aGoelzer | 4:954ae88b6664 | 14 | #define TX_OUTPUT_POWER 14 // 14 dBm |
aGoelzer | 4:954ae88b6664 | 15 | |
aGoelzer | 4:954ae88b6664 | 16 | #if USE_MODEM_LORA == 1 |
aGoelzer | 4:954ae88b6664 | 17 | |
aGoelzer | 4:954ae88b6664 | 18 | #define LORA_BANDWIDTH 2 // [0: 125 kHz, |
aGoelzer | 4:954ae88b6664 | 19 | // 1: 250 kHz, |
aGoelzer | 4:954ae88b6664 | 20 | // 2: 500 kHz, |
aGoelzer | 4:954ae88b6664 | 21 | // 3: Reserved] |
aGoelzer | 4:954ae88b6664 | 22 | #define LORA_SPREADING_FACTOR 7 // [SF7..SF12] |
aGoelzer | 4:954ae88b6664 | 23 | #define LORA_CODINGRATE 1 // [1: 4/5, |
aGoelzer | 4:954ae88b6664 | 24 | // 2: 4/6, |
aGoelzer | 4:954ae88b6664 | 25 | // 3: 4/7, |
aGoelzer | 4:954ae88b6664 | 26 | // 4: 4/8] |
aGoelzer | 4:954ae88b6664 | 27 | #define LORA_PREAMBLE_LENGTH 8 // Same for Tx and Rx |
aGoelzer | 4:954ae88b6664 | 28 | #define LORA_SYMBOL_TIMEOUT 5 // Symbols |
aGoelzer | 4:954ae88b6664 | 29 | #define LORA_FIX_LENGTH_PAYLOAD_ON false |
aGoelzer | 4:954ae88b6664 | 30 | #define LORA_FHSS_ENABLED false |
aGoelzer | 4:954ae88b6664 | 31 | #define LORA_NB_SYMB_HOP 4 |
aGoelzer | 4:954ae88b6664 | 32 | #define LORA_IQ_INVERSION_ON false |
aGoelzer | 4:954ae88b6664 | 33 | #define LORA_CRC_ENABLED true |
aGoelzer | 4:954ae88b6664 | 34 | |
aGoelzer | 4:954ae88b6664 | 35 | #elif USE_MODEM_FSK == 1 |
aGoelzer | 4:954ae88b6664 | 36 | |
aGoelzer | 4:954ae88b6664 | 37 | #define FSK_FDEV 25000 // Hz |
aGoelzer | 4:954ae88b6664 | 38 | #define FSK_DATARATE 19200 // bps |
aGoelzer | 4:954ae88b6664 | 39 | #define FSK_BANDWIDTH 50000 // Hz |
aGoelzer | 4:954ae88b6664 | 40 | #define FSK_AFC_BANDWIDTH 83333 // Hz |
aGoelzer | 4:954ae88b6664 | 41 | #define FSK_PREAMBLE_LENGTH 5 // Same for Tx and Rx |
aGoelzer | 4:954ae88b6664 | 42 | #define FSK_FIX_LENGTH_PAYLOAD_ON false |
aGoelzer | 4:954ae88b6664 | 43 | #define FSK_CRC_ENABLED true |
aGoelzer | 4:954ae88b6664 | 44 | |
aGoelzer | 4:954ae88b6664 | 45 | #else |
aGoelzer | 4:954ae88b6664 | 46 | #error "Please define a modem in the compiler options." |
aGoelzer | 4:954ae88b6664 | 47 | #endif |
aGoelzer | 4:954ae88b6664 | 48 | |
aGoelzer | 4:954ae88b6664 | 49 | #define RX_TIMEOUT_VALUE 3500000 // in us |
aGoelzer | 4:954ae88b6664 | 50 | #define BUFFER_SIZE 32 // Define the payload size here |
bLandais | 0:b239f8883fcc | 51 | |
aGoelzer | 4:954ae88b6664 | 52 | #if( defined ( TARGET_KL25Z ) || defined ( TARGET_LPC11U6X ) ) |
aGoelzer | 4:954ae88b6664 | 53 | DigitalOut led(LED2); |
aGoelzer | 4:954ae88b6664 | 54 | #else |
aGoelzer | 4:954ae88b6664 | 55 | DigitalOut led(LED1); |
aGoelzer | 4:954ae88b6664 | 56 | #endif |
aGoelzer | 5:d28a689b1635 | 57 | typedef unsigned char byte; |
aGoelzer | 5:d28a689b1635 | 58 | unsigned short crc16(byte byteArray[], int length) |
aGoelzer | 5:d28a689b1635 | 59 | { |
aGoelzer | 5:d28a689b1635 | 60 | unsigned char x; |
aGoelzer | 5:d28a689b1635 | 61 | unsigned short crc = 0xFFFF; |
aGoelzer | 5:d28a689b1635 | 62 | for (int i = 0; i < length; i++) { |
aGoelzer | 5:d28a689b1635 | 63 | x = crc >> 8 ^ byteArray[i]; |
aGoelzer | 5:d28a689b1635 | 64 | x ^= x >> 4; |
aGoelzer | 5:d28a689b1635 | 65 | crc = (crc << 8) ^ ((unsigned short)(x << 12)) ^ ((unsigned short)(x << 5)) ^ ((unsigned short)x); |
aGoelzer | 5:d28a689b1635 | 66 | } |
aGoelzer | 5:d28a689b1635 | 67 | return crc; |
aGoelzer | 5:d28a689b1635 | 68 | } |
aGoelzer | 5:d28a689b1635 | 69 | |
aGoelzer | 5:d28a689b1635 | 70 | void float2Bytes(float val, byte* bytes_array) |
aGoelzer | 5:d28a689b1635 | 71 | { |
aGoelzer | 5:d28a689b1635 | 72 | union { |
aGoelzer | 5:d28a689b1635 | 73 | float float_variable; |
aGoelzer | 5:d28a689b1635 | 74 | byte temp_array[4]; |
aGoelzer | 5:d28a689b1635 | 75 | } u; |
aGoelzer | 5:d28a689b1635 | 76 | u.float_variable = val; |
aGoelzer | 5:d28a689b1635 | 77 | memcpy(bytes_array, u.temp_array, 4); |
aGoelzer | 5:d28a689b1635 | 78 | } |
aGoelzer | 5:d28a689b1635 | 79 | |
aGoelzer | 5:d28a689b1635 | 80 | class Position |
aGoelzer | 5:d28a689b1635 | 81 | { |
aGoelzer | 5:d28a689b1635 | 82 | public: |
aGoelzer | 5:d28a689b1635 | 83 | bool north; |
aGoelzer | 5:d28a689b1635 | 84 | bool south; |
aGoelzer | 5:d28a689b1635 | 85 | bool east; |
aGoelzer | 5:d28a689b1635 | 86 | bool west; |
aGoelzer | 5:d28a689b1635 | 87 | short degLon; |
aGoelzer | 5:d28a689b1635 | 88 | short degLat; |
aGoelzer | 5:d28a689b1635 | 89 | float minutesLong; |
aGoelzer | 5:d28a689b1635 | 90 | float minutesLat; |
aGoelzer | 5:d28a689b1635 | 91 | float secondesLong; |
aGoelzer | 5:d28a689b1635 | 92 | float secondesLat; |
aGoelzer | 5:d28a689b1635 | 93 | |
aGoelzer | 5:d28a689b1635 | 94 | Position(bool north, bool south, bool east, bool west, short degLon, short degLat, float minutesLong, float minutesLat, float secondesLong, float secondesLat) { |
aGoelzer | 5:d28a689b1635 | 95 | this->north = north; |
aGoelzer | 5:d28a689b1635 | 96 | this->south = south; |
aGoelzer | 5:d28a689b1635 | 97 | this->east = east; |
aGoelzer | 5:d28a689b1635 | 98 | this->west = west; |
aGoelzer | 5:d28a689b1635 | 99 | this->degLon = degLon; |
aGoelzer | 5:d28a689b1635 | 100 | this->degLat = degLat; |
aGoelzer | 5:d28a689b1635 | 101 | this->minutesLong = minutesLong; |
aGoelzer | 5:d28a689b1635 | 102 | this->minutesLat = minutesLat; |
aGoelzer | 5:d28a689b1635 | 103 | this->secondesLong = secondesLong; |
aGoelzer | 5:d28a689b1635 | 104 | this->secondesLat = secondesLat; |
aGoelzer | 5:d28a689b1635 | 105 | } |
aGoelzer | 5:d28a689b1635 | 106 | |
aGoelzer | 5:d28a689b1635 | 107 | Position(byte* posBytes) { |
aGoelzer | 5:d28a689b1635 | 108 | this->north = (posBytes[0] & 1); |
aGoelzer | 5:d28a689b1635 | 109 | this->south = (posBytes[0] & 2) >> 1; |
aGoelzer | 5:d28a689b1635 | 110 | this->east = (posBytes[0] & 4) >> 2; |
aGoelzer | 5:d28a689b1635 | 111 | this->west = (posBytes[0] & 8) >> 3; |
aGoelzer | 5:d28a689b1635 | 112 | this->degLon = posBytes[1] * 256 + posBytes[2]; |
aGoelzer | 5:d28a689b1635 | 113 | this->degLat = posBytes[3] * 256 + posBytes[4]; |
aGoelzer | 5:d28a689b1635 | 114 | this->minutesLong = *(float *)(posBytes + 5); |
aGoelzer | 5:d28a689b1635 | 115 | this->minutesLat = *(float *)(posBytes + 9); |
aGoelzer | 5:d28a689b1635 | 116 | this->secondesLong = *(float *)(posBytes + 13); |
aGoelzer | 5:d28a689b1635 | 117 | this->secondesLat = *(float *)(posBytes + 17); |
aGoelzer | 5:d28a689b1635 | 118 | } |
aGoelzer | 5:d28a689b1635 | 119 | |
aGoelzer | 5:d28a689b1635 | 120 | byte* GetBytes() { |
aGoelzer | 5:d28a689b1635 | 121 | byte* posByte = (byte*)malloc(21 * sizeof(byte)); |
aGoelzer | 5:d28a689b1635 | 122 | posByte[0] = 0; |
aGoelzer | 5:d28a689b1635 | 123 | if (this->north) { |
aGoelzer | 5:d28a689b1635 | 124 | posByte[0] = posByte[0] | 1; |
aGoelzer | 5:d28a689b1635 | 125 | } |
aGoelzer | 5:d28a689b1635 | 126 | if (this->south) { |
aGoelzer | 5:d28a689b1635 | 127 | posByte[0] = posByte[0] | 2; |
aGoelzer | 5:d28a689b1635 | 128 | } |
aGoelzer | 5:d28a689b1635 | 129 | if (this->east) { |
aGoelzer | 5:d28a689b1635 | 130 | posByte[0] = posByte[0] | 4; |
aGoelzer | 5:d28a689b1635 | 131 | } |
aGoelzer | 5:d28a689b1635 | 132 | if (this->west) { |
aGoelzer | 5:d28a689b1635 | 133 | posByte[0] = posByte[0] | 8; |
aGoelzer | 5:d28a689b1635 | 134 | } |
aGoelzer | 5:d28a689b1635 | 135 | posByte[1] = (this->degLon & 0xFF00) >> 8; //Bits de poids fort du short |
aGoelzer | 5:d28a689b1635 | 136 | posByte[2] = (this->degLon & 0x00FF); //Bits de poids faible |
aGoelzer | 5:d28a689b1635 | 137 | posByte[3] = (this->degLat & 0xFF00) >> 8; //Bits de poids fort du short |
aGoelzer | 5:d28a689b1635 | 138 | posByte[4] = (this->degLat & 0x00FF); //Bits de poids faible |
aGoelzer | 5:d28a689b1635 | 139 | float2Bytes(this->minutesLong, posByte + 5); |
aGoelzer | 5:d28a689b1635 | 140 | float2Bytes(this->minutesLat, posByte + 9); |
aGoelzer | 5:d28a689b1635 | 141 | float2Bytes(this->secondesLong, posByte + 13); |
aGoelzer | 5:d28a689b1635 | 142 | float2Bytes(this->secondesLat, posByte + 17); |
aGoelzer | 5:d28a689b1635 | 143 | return posByte; |
aGoelzer | 5:d28a689b1635 | 144 | } |
aGoelzer | 5:d28a689b1635 | 145 | }; |
aGoelzer | 5:d28a689b1635 | 146 | class Date |
aGoelzer | 5:d28a689b1635 | 147 | { |
aGoelzer | 5:d28a689b1635 | 148 | public: |
aGoelzer | 5:d28a689b1635 | 149 | byte jour; |
aGoelzer | 5:d28a689b1635 | 150 | byte mois; |
aGoelzer | 5:d28a689b1635 | 151 | byte annee; |
aGoelzer | 5:d28a689b1635 | 152 | byte heure; |
aGoelzer | 5:d28a689b1635 | 153 | byte minutes; |
aGoelzer | 5:d28a689b1635 | 154 | byte secondes; |
aGoelzer | 5:d28a689b1635 | 155 | |
aGoelzer | 5:d28a689b1635 | 156 | byte* GetBytes() { |
aGoelzer | 5:d28a689b1635 | 157 | byte* dateByte = (byte*)malloc(6 * sizeof(byte)); |
aGoelzer | 5:d28a689b1635 | 158 | dateByte[0] = this->jour; |
aGoelzer | 5:d28a689b1635 | 159 | dateByte[1] = this->mois; |
aGoelzer | 5:d28a689b1635 | 160 | dateByte[2] = this->annee; |
aGoelzer | 5:d28a689b1635 | 161 | dateByte[3] = this->heure; |
aGoelzer | 5:d28a689b1635 | 162 | dateByte[4] = this->minutes; |
aGoelzer | 5:d28a689b1635 | 163 | dateByte[5] = this->secondes; |
aGoelzer | 5:d28a689b1635 | 164 | return dateByte; |
aGoelzer | 5:d28a689b1635 | 165 | } |
aGoelzer | 5:d28a689b1635 | 166 | |
aGoelzer | 5:d28a689b1635 | 167 | Date(byte jour, byte mois, byte annee, byte heure, byte minutes, byte secondes) { |
aGoelzer | 5:d28a689b1635 | 168 | this->jour = jour; |
aGoelzer | 5:d28a689b1635 | 169 | this->mois = mois; |
aGoelzer | 5:d28a689b1635 | 170 | this->annee = annee; |
aGoelzer | 5:d28a689b1635 | 171 | this->heure = heure; |
aGoelzer | 5:d28a689b1635 | 172 | this->minutes = minutes; |
aGoelzer | 5:d28a689b1635 | 173 | this->secondes = secondes; |
aGoelzer | 5:d28a689b1635 | 174 | } |
aGoelzer | 5:d28a689b1635 | 175 | |
aGoelzer | 5:d28a689b1635 | 176 | Date(byte* dateBytes) { |
aGoelzer | 5:d28a689b1635 | 177 | this->jour = dateBytes[0]; |
aGoelzer | 5:d28a689b1635 | 178 | this->mois = dateBytes[1]; |
aGoelzer | 5:d28a689b1635 | 179 | this->annee = dateBytes[2]; |
aGoelzer | 5:d28a689b1635 | 180 | this->heure = dateBytes[3]; |
aGoelzer | 5:d28a689b1635 | 181 | this->minutes = dateBytes[4]; |
aGoelzer | 5:d28a689b1635 | 182 | this->secondes = dateBytes[5]; |
aGoelzer | 5:d28a689b1635 | 183 | } |
aGoelzer | 5:d28a689b1635 | 184 | |
aGoelzer | 5:d28a689b1635 | 185 | }; |
aGoelzer | 5:d28a689b1635 | 186 | |
aGoelzer | 5:d28a689b1635 | 187 | class Content |
aGoelzer | 5:d28a689b1635 | 188 | { |
aGoelzer | 5:d28a689b1635 | 189 | public: |
aGoelzer | 5:d28a689b1635 | 190 | short IDLapin; |
aGoelzer | 5:d28a689b1635 | 191 | Position* positionLapin; |
aGoelzer | 5:d28a689b1635 | 192 | Date* dateLapin; |
aGoelzer | 5:d28a689b1635 | 193 | |
aGoelzer | 5:d28a689b1635 | 194 | byte* GetBytes() { |
aGoelzer | 5:d28a689b1635 | 195 | byte* contByte = (byte*)malloc(29 * sizeof(byte)); |
aGoelzer | 5:d28a689b1635 | 196 | contByte[0] = (this->IDLapin & 0xFF00) << 8; |
aGoelzer | 5:d28a689b1635 | 197 | contByte[1] = (this->IDLapin & 0x00FF); |
aGoelzer | 5:d28a689b1635 | 198 | byte* dateBytes = this->dateLapin->GetBytes(); |
aGoelzer | 5:d28a689b1635 | 199 | byte* positionBytes = this->positionLapin->GetBytes(); |
aGoelzer | 5:d28a689b1635 | 200 | memcpy(contByte + 2, dateBytes, 6); |
aGoelzer | 5:d28a689b1635 | 201 | memcpy(contByte + 8, positionBytes, 21); |
aGoelzer | 5:d28a689b1635 | 202 | free(positionBytes); |
aGoelzer | 5:d28a689b1635 | 203 | free(dateBytes); |
aGoelzer | 5:d28a689b1635 | 204 | return contByte; |
aGoelzer | 5:d28a689b1635 | 205 | } |
aGoelzer | 5:d28a689b1635 | 206 | |
aGoelzer | 5:d28a689b1635 | 207 | Content(short IDLapin, Position* positionLapin, Date* dateLapin) { |
aGoelzer | 5:d28a689b1635 | 208 | this->IDLapin = IDLapin; |
aGoelzer | 5:d28a689b1635 | 209 | this->positionLapin = positionLapin; |
aGoelzer | 5:d28a689b1635 | 210 | this->dateLapin = dateLapin; |
aGoelzer | 5:d28a689b1635 | 211 | } |
aGoelzer | 5:d28a689b1635 | 212 | |
aGoelzer | 5:d28a689b1635 | 213 | Content(byte* contentBytes) { |
aGoelzer | 5:d28a689b1635 | 214 | this->IDLapin = contentBytes[0] * 256 + contentBytes[1]; |
aGoelzer | 5:d28a689b1635 | 215 | byte* positionBytes = (byte*)malloc(21 * sizeof(byte)); |
aGoelzer | 5:d28a689b1635 | 216 | byte* dateBytes = (byte*)malloc(6 * sizeof(byte)); |
aGoelzer | 5:d28a689b1635 | 217 | memcpy(dateBytes, contentBytes + 2, 6); |
aGoelzer | 5:d28a689b1635 | 218 | memcpy(positionBytes, contentBytes + 8, 21); |
aGoelzer | 5:d28a689b1635 | 219 | this->positionLapin = (Position*)(new Position(positionBytes)); |
aGoelzer | 5:d28a689b1635 | 220 | this->dateLapin = (Date*)(new Date(dateBytes)); |
aGoelzer | 5:d28a689b1635 | 221 | free(dateBytes); |
aGoelzer | 5:d28a689b1635 | 222 | free(positionBytes); |
aGoelzer | 5:d28a689b1635 | 223 | } |
aGoelzer | 5:d28a689b1635 | 224 | }; |
aGoelzer | 5:d28a689b1635 | 225 | |
aGoelzer | 5:d28a689b1635 | 226 | byte* CreateMessageBytes(Content* messageContent) |
aGoelzer | 5:d28a689b1635 | 227 | { |
aGoelzer | 5:d28a689b1635 | 228 | byte* messByte = (byte*)malloc(32 * sizeof(byte)); |
aGoelzer | 5:d28a689b1635 | 229 | messByte[0] = 20; |
aGoelzer | 5:d28a689b1635 | 230 | byte* contentBytes = messageContent->GetBytes(); |
aGoelzer | 5:d28a689b1635 | 231 | unsigned short gotHash = crc16(contentBytes, 29); |
aGoelzer | 5:d28a689b1635 | 232 | messByte[1] = (gotHash & 0xFF00) >> 8; |
aGoelzer | 5:d28a689b1635 | 233 | messByte[2] = (gotHash & 0x00FF); |
aGoelzer | 5:d28a689b1635 | 234 | memcpy(messByte + 3, contentBytes, 29); |
aGoelzer | 5:d28a689b1635 | 235 | free(contentBytes); |
aGoelzer | 5:d28a689b1635 | 236 | return messByte; |
aGoelzer | 5:d28a689b1635 | 237 | } |
aGoelzer | 5:d28a689b1635 | 238 | |
aGoelzer | 5:d28a689b1635 | 239 | enum MessageCheckResult { CORRECT = 1, CORRUPTED = 0, NOTFORUS = -1 }; |
aGoelzer | 5:d28a689b1635 | 240 | MessageCheckResult IsCorrectMessage(byte* bytesReceived, int mLength) |
aGoelzer | 5:d28a689b1635 | 241 | { |
aGoelzer | 5:d28a689b1635 | 242 | if (mLength != 32) { |
aGoelzer | 5:d28a689b1635 | 243 | return NOTFORUS; |
aGoelzer | 5:d28a689b1635 | 244 | } |
aGoelzer | 5:d28a689b1635 | 245 | if (bytesReceived[0] != 20) { |
aGoelzer | 5:d28a689b1635 | 246 | return NOTFORUS; |
aGoelzer | 5:d28a689b1635 | 247 | } |
aGoelzer | 5:d28a689b1635 | 248 | if (crc16(bytesReceived + 3, 29) != (bytesReceived[1] * 256 + bytesReceived[2])) { |
aGoelzer | 5:d28a689b1635 | 249 | return CORRUPTED; |
aGoelzer | 5:d28a689b1635 | 250 | } |
aGoelzer | 5:d28a689b1635 | 251 | return CORRECT; |
aGoelzer | 5:d28a689b1635 | 252 | } |
aGoelzer | 5:d28a689b1635 | 253 | |
aGoelzer | 4:954ae88b6664 | 254 | |
aGoelzer | 4:954ae88b6664 | 255 | /* |
aGoelzer | 4:954ae88b6664 | 256 | * Global variables declarations |
aGoelzer | 4:954ae88b6664 | 257 | */ |
aGoelzer | 4:954ae88b6664 | 258 | typedef enum { |
aGoelzer | 4:954ae88b6664 | 259 | LOWPOWER = 0, |
aGoelzer | 4:954ae88b6664 | 260 | IDLE, |
aGoelzer | 4:954ae88b6664 | 261 | |
aGoelzer | 4:954ae88b6664 | 262 | RX, |
aGoelzer | 4:954ae88b6664 | 263 | RX_TIMEOUT, |
aGoelzer | 4:954ae88b6664 | 264 | RX_ERROR, |
aGoelzer | 4:954ae88b6664 | 265 | |
aGoelzer | 4:954ae88b6664 | 266 | TX, |
aGoelzer | 4:954ae88b6664 | 267 | TX_TIMEOUT, |
aGoelzer | 4:954ae88b6664 | 268 | |
aGoelzer | 4:954ae88b6664 | 269 | CAD, |
aGoelzer | 4:954ae88b6664 | 270 | CAD_DONE |
aGoelzer | 4:954ae88b6664 | 271 | } AppStates_t; |
aGoelzer | 4:954ae88b6664 | 272 | |
aGoelzer | 4:954ae88b6664 | 273 | volatile AppStates_t State = LOWPOWER; |
aGoelzer | 4:954ae88b6664 | 274 | |
aGoelzer | 4:954ae88b6664 | 275 | /*! |
aGoelzer | 4:954ae88b6664 | 276 | * Radio events function pointer |
aGoelzer | 4:954ae88b6664 | 277 | */ |
aGoelzer | 4:954ae88b6664 | 278 | static RadioEvents_t RadioEvents; |
aGoelzer | 4:954ae88b6664 | 279 | |
aGoelzer | 4:954ae88b6664 | 280 | /* |
aGoelzer | 4:954ae88b6664 | 281 | * Global variables declarations |
aGoelzer | 4:954ae88b6664 | 282 | */ |
aGoelzer | 4:954ae88b6664 | 283 | SX1272MB2xAS Radio( NULL ); |
aGoelzer | 4:954ae88b6664 | 284 | |
aGoelzer | 4:954ae88b6664 | 285 | uint16_t BufferSize = BUFFER_SIZE; |
aGoelzer | 4:954ae88b6664 | 286 | uint8_t Buffer[BUFFER_SIZE]; |
aGoelzer | 4:954ae88b6664 | 287 | |
aGoelzer | 4:954ae88b6664 | 288 | int16_t RssiValue = 0.0; |
aGoelzer | 4:954ae88b6664 | 289 | int8_t SnrValue = 0.0; |
aGoelzer | 4:954ae88b6664 | 290 | |
aGoelzer | 4:954ae88b6664 | 291 | int main() |
aGoelzer | 4:954ae88b6664 | 292 | { |
aGoelzer | 4:954ae88b6664 | 293 | // Initialize Radio driver |
aGoelzer | 4:954ae88b6664 | 294 | RadioEvents.TxDone = OnTxDone; |
aGoelzer | 4:954ae88b6664 | 295 | RadioEvents.RxDone = OnRxDone; |
aGoelzer | 4:954ae88b6664 | 296 | RadioEvents.RxError = OnRxError; |
aGoelzer | 4:954ae88b6664 | 297 | RadioEvents.TxTimeout = OnTxTimeout; |
aGoelzer | 4:954ae88b6664 | 298 | RadioEvents.RxTimeout = OnRxTimeout; |
aGoelzer | 4:954ae88b6664 | 299 | Radio.Init( &RadioEvents ); |
bLandais | 0:b239f8883fcc | 300 | |
aGoelzer | 4:954ae88b6664 | 301 | // verify the connection with the board |
aGoelzer | 4:954ae88b6664 | 302 | while( Radio.Read( REG_VERSION ) == 0x00 ) { |
aGoelzer | 4:954ae88b6664 | 303 | debug( "Radio could not be detected!\n\r", NULL ); |
aGoelzer | 4:954ae88b6664 | 304 | wait( 1 ); |
aGoelzer | 4:954ae88b6664 | 305 | } |
aGoelzer | 4:954ae88b6664 | 306 | |
aGoelzer | 4:954ae88b6664 | 307 | debug_if( ( DEBUG_MESSAGE & ( Radio.DetectBoardType( ) == SX1272MB2XAS ) ) , "\n\r > Board Type: SX1272MB2xAS < \n\r" ); |
aGoelzer | 4:954ae88b6664 | 308 | |
aGoelzer | 4:954ae88b6664 | 309 | Radio.SetChannel( RF_FREQUENCY ); |
aGoelzer | 4:954ae88b6664 | 310 | |
aGoelzer | 4:954ae88b6664 | 311 | #if USE_MODEM_LORA == 1 |
aGoelzer | 4:954ae88b6664 | 312 | |
aGoelzer | 4:954ae88b6664 | 313 | debug_if( LORA_FHSS_ENABLED, "\n\n\r > LORA FHSS Mode < \n\n\r"); |
aGoelzer | 4:954ae88b6664 | 314 | debug_if( !LORA_FHSS_ENABLED, "\n\n\r > LORA Mode < \n\n\r"); |
aGoelzer | 4:954ae88b6664 | 315 | |
aGoelzer | 4:954ae88b6664 | 316 | Radio.SetTxConfig( MODEM_LORA, TX_OUTPUT_POWER, 0, LORA_BANDWIDTH, |
aGoelzer | 4:954ae88b6664 | 317 | LORA_SPREADING_FACTOR, LORA_CODINGRATE, |
aGoelzer | 4:954ae88b6664 | 318 | LORA_PREAMBLE_LENGTH, LORA_FIX_LENGTH_PAYLOAD_ON, |
aGoelzer | 4:954ae88b6664 | 319 | LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, |
aGoelzer | 4:954ae88b6664 | 320 | LORA_IQ_INVERSION_ON, 2000000 ); |
aGoelzer | 4:954ae88b6664 | 321 | |
aGoelzer | 4:954ae88b6664 | 322 | Radio.SetRxConfig( MODEM_LORA, LORA_BANDWIDTH, LORA_SPREADING_FACTOR, |
aGoelzer | 4:954ae88b6664 | 323 | LORA_CODINGRATE, 0, LORA_PREAMBLE_LENGTH, |
aGoelzer | 4:954ae88b6664 | 324 | LORA_SYMBOL_TIMEOUT, LORA_FIX_LENGTH_PAYLOAD_ON, 0, |
aGoelzer | 4:954ae88b6664 | 325 | LORA_CRC_ENABLED, LORA_FHSS_ENABLED, LORA_NB_SYMB_HOP, |
aGoelzer | 4:954ae88b6664 | 326 | LORA_IQ_INVERSION_ON, true ); |
aGoelzer | 4:954ae88b6664 | 327 | |
aGoelzer | 4:954ae88b6664 | 328 | #elif USE_MODEM_FSK == 1 |
aGoelzer | 4:954ae88b6664 | 329 | |
aGoelzer | 4:954ae88b6664 | 330 | debug("\n\n\r > FSK Mode < \n\n\r"); |
aGoelzer | 4:954ae88b6664 | 331 | Radio.SetTxConfig( MODEM_FSK, TX_OUTPUT_POWER, FSK_FDEV, 0, |
aGoelzer | 4:954ae88b6664 | 332 | FSK_DATARATE, 0, |
aGoelzer | 4:954ae88b6664 | 333 | FSK_PREAMBLE_LENGTH, FSK_FIX_LENGTH_PAYLOAD_ON, |
aGoelzer | 4:954ae88b6664 | 334 | FSK_CRC_ENABLED, 0, 0, 0, 2000000 ); |
aGoelzer | 4:954ae88b6664 | 335 | |
aGoelzer | 4:954ae88b6664 | 336 | Radio.SetRxConfig( MODEM_FSK, FSK_BANDWIDTH, FSK_DATARATE, |
aGoelzer | 4:954ae88b6664 | 337 | 0, FSK_AFC_BANDWIDTH, FSK_PREAMBLE_LENGTH, |
aGoelzer | 4:954ae88b6664 | 338 | 0, FSK_FIX_LENGTH_PAYLOAD_ON, 0, FSK_CRC_ENABLED, |
aGoelzer | 4:954ae88b6664 | 339 | 0, 0, false, true ); |
aGoelzer | 4:954ae88b6664 | 340 | |
aGoelzer | 4:954ae88b6664 | 341 | #else |
aGoelzer | 4:954ae88b6664 | 342 | |
aGoelzer | 4:954ae88b6664 | 343 | #error "Please define a modem in the compiler options." |
aGoelzer | 4:954ae88b6664 | 344 | |
aGoelzer | 4:954ae88b6664 | 345 | #endif |
aGoelzer | 4:954ae88b6664 | 346 | |
aGoelzer | 5:d28a689b1635 | 347 | Radio.Rx(RX_TIMEOUT_VALUE ); |
aGoelzer | 4:954ae88b6664 | 348 | |
aGoelzer | 4:954ae88b6664 | 349 | while( 1 ) { |
aGoelzer | 5:d28a689b1635 | 350 | // Radio.Rx( 100*RX_TIMEOUT_VALUE ); |
aGoelzer | 5:d28a689b1635 | 351 | //SendStr("Bonjour Baudouin"); |
aGoelzer | 4:954ae88b6664 | 352 | } |
aGoelzer | 4:954ae88b6664 | 353 | |
aGoelzer | 4:954ae88b6664 | 354 | } |
aGoelzer | 4:954ae88b6664 | 355 | |
aGoelzer | 4:954ae88b6664 | 356 | void SendStr(char* str) |
aGoelzer | 4:954ae88b6664 | 357 | { |
aGoelzer | 4:954ae88b6664 | 358 | int len = strlen(str); |
aGoelzer | 4:954ae88b6664 | 359 | uint8_t MyBuffer[len]; |
aGoelzer | 4:954ae88b6664 | 360 | strcpy( ( char* )MyBuffer, str ); |
aGoelzer | 4:954ae88b6664 | 361 | debug(str); |
aGoelzer | 4:954ae88b6664 | 362 | Radio.Send(MyBuffer, len); |
aGoelzer | 4:954ae88b6664 | 363 | } |
aGoelzer | 4:954ae88b6664 | 364 | |
aGoelzer | 4:954ae88b6664 | 365 | void OnTxDone( void ) |
aGoelzer | 4:954ae88b6664 | 366 | { |
aGoelzer | 4:954ae88b6664 | 367 | Radio.Sleep(); |
aGoelzer | 4:954ae88b6664 | 368 | State = TX; |
aGoelzer | 4:954ae88b6664 | 369 | debug_if( DEBUG_MESSAGE, "\n\r> Message transmis\n\r" ); |
aGoelzer | 4:954ae88b6664 | 370 | } |
aGoelzer | 4:954ae88b6664 | 371 | |
aGoelzer | 4:954ae88b6664 | 372 | void OnRxDone( uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr) |
aGoelzer | 4:954ae88b6664 | 373 | { |
aGoelzer | 4:954ae88b6664 | 374 | Radio.Sleep(); |
aGoelzer | 4:954ae88b6664 | 375 | BufferSize = size; |
aGoelzer | 4:954ae88b6664 | 376 | memcpy( Buffer, payload, BufferSize ); |
aGoelzer | 4:954ae88b6664 | 377 | RssiValue = rssi; |
aGoelzer | 4:954ae88b6664 | 378 | SnrValue = snr; |
aGoelzer | 4:954ae88b6664 | 379 | State = RX; |
aGoelzer | 5:d28a689b1635 | 380 | debug_if( DEBUG_MESSAGE, "\n\r> Message recu\n\r" ); |
aGoelzer | 5:d28a689b1635 | 381 | //debug("\r\n"); |
aGoelzer | 5:d28a689b1635 | 382 | //debug("SNR = %d\r\n",snr); |
aGoelzer | 5:d28a689b1635 | 383 | //debug("RSSI = %d\r\n",rssi); |
aGoelzer | 5:d28a689b1635 | 384 | if (IsCorrectMessage(Buffer,BufferSize) == 1){ |
aGoelzer | 5:d28a689b1635 | 385 | Content contentReceived = Content(Buffer+3); |
aGoelzer | 5:d28a689b1635 | 386 | debug("%d %d %d %d %d %d", contentReceived.dateLapin->jour, contentReceived.dateLapin->mois,contentReceived.dateLapin->annee ,contentReceived.dateLapin->heure, contentReceived.dateLapin->minutes, contentReceived.dateLapin->secondes); |
aGoelzer | 4:954ae88b6664 | 387 | } |
aGoelzer | 4:954ae88b6664 | 388 | |
aGoelzer | 5:d28a689b1635 | 389 | Radio.Rx(RX_TIMEOUT_VALUE ); |
aGoelzer | 4:954ae88b6664 | 390 | } |
aGoelzer | 4:954ae88b6664 | 391 | |
aGoelzer | 4:954ae88b6664 | 392 | void OnTxTimeout( void ) |
aGoelzer | 4:954ae88b6664 | 393 | { |
aGoelzer | 4:954ae88b6664 | 394 | Radio.Sleep( ); |
aGoelzer | 4:954ae88b6664 | 395 | State = TX_TIMEOUT; |
aGoelzer | 4:954ae88b6664 | 396 | debug_if( DEBUG_MESSAGE, "\n\r> Delai d'attente depasse\n\r" ); |
aGoelzer | 4:954ae88b6664 | 397 | } |
aGoelzer | 4:954ae88b6664 | 398 | |
aGoelzer | 4:954ae88b6664 | 399 | void OnRxTimeout( void ) |
aGoelzer | 4:954ae88b6664 | 400 | { |
aGoelzer | 4:954ae88b6664 | 401 | Radio.Sleep( ); |
aGoelzer | 4:954ae88b6664 | 402 | Buffer[ BufferSize ] = 0; |
aGoelzer | 4:954ae88b6664 | 403 | State = RX_TIMEOUT; |
aGoelzer | 4:954ae88b6664 | 404 | debug_if( DEBUG_MESSAGE, "> OnRxTimeout\n\r" ); |
aGoelzer | 5:d28a689b1635 | 405 | Radio.Rx(RX_TIMEOUT_VALUE ); |
aGoelzer | 4:954ae88b6664 | 406 | } |
aGoelzer | 4:954ae88b6664 | 407 | |
aGoelzer | 4:954ae88b6664 | 408 | void OnRxError( void ) |
aGoelzer | 4:954ae88b6664 | 409 | { |
aGoelzer | 4:954ae88b6664 | 410 | Radio.Sleep( ); |
aGoelzer | 4:954ae88b6664 | 411 | State = RX_ERROR; |
aGoelzer | 4:954ae88b6664 | 412 | debug_if( DEBUG_MESSAGE, "> OnRxError\n\r" ); |
aGoelzer | 5:d28a689b1635 | 413 | Radio.Rx( 10*RX_TIMEOUT_VALUE ); |
aGoelzer | 4:954ae88b6664 | 414 | } |
aGoelzer | 4:954ae88b6664 | 415 |