├── LoRa V1.2 ├── RF95.c └── RF95.h ├── Master.zip ├── README.md └── Slave.zip /LoRa V1.2/RF95.c: -------------------------------------------------------------------------------- 1 | #include "RF95.h" 2 | extern SPI_HandleTypeDef hspi1; 3 | 4 | RHMode _mode; 5 | uint16_t _cad_timeout = 10000; 6 | uint8_t LoRa_buff[RH_RF95_FIFO_SIZE] = {0}; 7 | 8 | #if Header == Header_used 9 | char _txHeaderTo = 0; 10 | #endif 11 | 12 | char MODEM_CONFIG_TABLE[5][3] = 13 | { 14 | // 1d, 1e, 26 15 | { 0x72, 0x74, 0x00}, // Bw125Cr45Sf128 (the chip default) 16 | { 0x92, 0x74, 0x00}, // Bw500Cr45Sf128 17 | { 0x48, 0x94, 0x00}, // Bw31_25Cr48Sf512 18 | { 0x78, 0xc4, 0x00}, // Bw125Cr48Sf4096 19 | { 0x73, 0x74, 0x00}, // IH_Bw125Cr45Sf128 (the chip default + Implicit header) 20 | }; 21 | 22 | HAL_StatusTypeDef err; 23 | HAL_StatusTypeDef RF95_write(char reg, char wValue) 24 | { 25 | char buff[2]={0}; 26 | 27 | buff[0] = W | reg; 28 | buff[1] = wValue; 29 | 30 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_RESET); 31 | err = HAL_SPI_Transmit(&hspi1, (uint8_t*)&buff, 2, 100); 32 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); 33 | 34 | return err; 35 | } 36 | 37 | 38 | HAL_StatusTypeDef RF95_write_burst(char reg, uint8_t* data) 39 | { 40 | int length = 0; 41 | uint8_t cmd = W | reg; 42 | HAL_StatusTypeDef err; 43 | 44 | length = strlen((const char*)data); 45 | 46 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_RESET); 47 | HAL_SPI_Transmit(&hspi1, (uint8_t*)&cmd, 1, 100); 48 | err = HAL_SPI_Transmit(&hspi1, (uint8_t*)&LoRa_buff, length, 100); 49 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); 50 | 51 | return err; 52 | } 53 | 54 | 55 | char RF95_read(char reg) 56 | { 57 | char buff = R & reg; 58 | 59 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_RESET); 60 | HAL_SPI_Transmit(&hspi1, (uint8_t*)&buff, 1, 100); 61 | HAL_SPI_Receive(&hspi1, (uint8_t*)&buff, 1, 100); 62 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); 63 | 64 | return buff; 65 | } 66 | 67 | 68 | HAL_StatusTypeDef RF95_read_burst(char reg, char* buffer, int length) 69 | { 70 | buffer[0] = R & reg; 71 | HAL_StatusTypeDef err; 72 | 73 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_RESET); 74 | HAL_SPI_Transmit(&hspi1, (uint8_t*)buffer, 1, 100); 75 | err = HAL_SPI_Receive(&hspi1, (uint8_t*)buffer, length, 100); 76 | HAL_GPIO_WritePin(LoRa_CS_GPIO_Port, LoRa_CS_Pin, GPIO_PIN_SET); 77 | 78 | return err; 79 | } 80 | 81 | 82 | void RF95_Reset(void) 83 | { 84 | HAL_GPIO_WritePin(LoRa_RESET_GPIO_Port, LoRa_RESET_Pin, GPIO_PIN_RESET); 85 | HAL_Delay(20); 86 | HAL_GPIO_WritePin(LoRa_RESET_GPIO_Port, LoRa_RESET_Pin, GPIO_PIN_SET); 87 | } 88 | 89 | uint8_t rbuff = 0; 90 | bool RF95_Init(void) 91 | { 92 | RF95_Reset(); 93 | 94 | // Set sleep mode, so we can also set LORA mode: 95 | RF95_sleep(); 96 | 97 | RF95_write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE); 98 | HAL_Delay(20); // Wait for sleep mode to take over from say, CAD 99 | 100 | // Check we are in sleep mode, with LORA set 101 | rbuff = RF95_read(RH_RF95_REG_01_OP_MODE); 102 | if (rbuff != (RH_RF95_MODE_SLEEP | RH_RF95_LONG_RANGE_MODE)) 103 | { 104 | return false; // No device present? 105 | } 106 | 107 | // Set up FIFO 108 | // We configure so that we can use the entire 256 byte FIFO for either receive 109 | // or transmit, but not both at the same time 110 | RF95_write(RH_RF95_REG_0E_FIFO_TX_BASE_ADDR, 0); 111 | RF95_write(RH_RF95_REG_0F_FIFO_RX_BASE_ADDR, 0); 112 | 113 | // Packet format is preamble + explicit-header + payload + crc 114 | // Explicit Header Mode 115 | // payload is TO + FROM + ID + FLAGS + message data 116 | // RX mode is implmented with RXCONTINUOUS 117 | // max message data length is 255 - 4 = 251 octets 118 | 119 | RF95_setModeIdle(); 120 | 121 | // Set up default configuration 122 | // No Sync Words in LORA mode. 123 | RF95_setModemConfig(Bw125Cr45Sf128); // Radio default 124 | RF95_setPreambleLength(8); // Default is 8 125 | // An innocuous ISM frequency, same as RF22's 126 | RF95_setFrequency(868.0); 127 | // Lowish power 128 | RF95_setTxPower(13, false); 129 | 130 | return true; 131 | } 132 | 133 | 134 | bool RF95_setModemConfig(ModemConfigChoice index) 135 | { 136 | RF95_write(RH_RF95_REG_1D_MODEM_CONFIG1, MODEM_CONFIG_TABLE[index][0]); 137 | RF95_write(RH_RF95_REG_1E_MODEM_CONFIG2, MODEM_CONFIG_TABLE[index][1]); 138 | RF95_write(RH_RF95_REG_26_MODEM_CONFIG3, MODEM_CONFIG_TABLE[index][2]); 139 | 140 | return true; 141 | } 142 | 143 | 144 | void RF95_setPreambleLength(uint16_t bytes) 145 | { 146 | RF95_write(RH_RF95_REG_20_PREAMBLE_MSB, bytes >> 8); 147 | RF95_write(RH_RF95_REG_21_PREAMBLE_LSB, bytes & 0xff); 148 | } 149 | 150 | 151 | bool RF95_setFrequency(float centre) 152 | { 153 | // Frf = FRF / FSTEP 154 | uint64_t frf = (uint32_t)((uint32_t)centre * 1000000.0) / (uint32_t)RH_RF95_FSTEP; 155 | RF95_write(RH_RF95_REG_06_FRF_MSB, (frf >> 16) & 0xff); 156 | RF95_write(RH_RF95_REG_07_FRF_MID, (frf >> 8) & 0xff); 157 | RF95_write(RH_RF95_REG_08_FRF_LSB, frf & 0xff); 158 | 159 | return true; 160 | } 161 | 162 | 163 | void RF95_setTxPower(int8_t power, bool useRFO) 164 | { 165 | // Sigh, different behaviours depending on whther the module use PA_BOOST or the RFO pin 166 | // for the transmitter output 167 | if (useRFO) 168 | { 169 | if (power > 14)power = 14; 170 | if (power < -1)power = -1; 171 | RF95_write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_MAX_POWER | (power + 1)); 172 | } 173 | else 174 | { 175 | if (power > 23)power = 23; 176 | if (power < 5)power = 5; 177 | 178 | // For RH_RF95_PA_DAC_ENABLE, manual says '+20dBm on PA_BOOST when OutputPower=0xf' 179 | // RH_RF95_PA_DAC_ENABLE actually adds about 3dBm to all power levels. We will us it 180 | // for 21 and 23dBm 181 | if (power > 20) 182 | { 183 | RF95_write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_ENABLE); 184 | power -= 3; 185 | } 186 | else 187 | { 188 | RF95_write(RH_RF95_REG_4D_PA_DAC, RH_RF95_PA_DAC_DISABLE); 189 | } 190 | 191 | // RFM95/96/97/98 does not have RFO pins connected to anything. Only PA_BOOST 192 | // pin is connected, so must use PA_BOOST 193 | // Pout = 2 + OutputPower. 194 | // The documentation is pretty confusing on this topic: PaSelect says the max power is 20dBm, 195 | // but OutputPower claims it would be 17dBm. 196 | // My measurements show 20dBm is correct 197 | RF95_write(RH_RF95_REG_09_PA_CONFIG, RH_RF95_PA_SELECT | (power-5)); 198 | } 199 | } 200 | 201 | 202 | bool RF95_receive(uint8_t* data) 203 | { 204 | int len = 0; 205 | 206 | if(_mode == RHModeRx) 207 | { 208 | while(!RF95_available()){} 209 | 210 | if(RF95_Check_PayloadCRCError()) 211 | return false; 212 | 213 | 214 | len = RF95_read(RH_RF95_REG_13_RX_NB_BYTES); 215 | 216 | // Reset the fifo read ptr to the beginning of the packet 217 | RF95_write(RH_RF95_REG_0D_FIFO_ADDR_PTR, RF95_read(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR)); 218 | 219 | RF95_read_burst(RH_RF95_REG_00_FIFO, (char*)data, len); 220 | 221 | RF95_setModeIdle(); 222 | 223 | RF95_Clear_IRQ(); 224 | 225 | return true; 226 | } 227 | else 228 | return false; 229 | } 230 | 231 | 232 | bool RF95_receive_Timeout(uint8_t* buf, uint16_t timeout) 233 | { 234 | int len = 0; 235 | 236 | if(_mode == RHModeRx) 237 | { 238 | if(!RF95_available_Timeout(timeout)) 239 | { 240 | return false; 241 | } 242 | 243 | if(RF95_Check_PayloadCRCError()) 244 | return false; 245 | 246 | 247 | len = RF95_read(RH_RF95_REG_13_RX_NB_BYTES); 248 | 249 | // Reset the fifo read ptr to the beginning of the packet 250 | RF95_write(RH_RF95_REG_0D_FIFO_ADDR_PTR, RF95_read(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR)); 251 | 252 | RF95_read_burst(RH_RF95_REG_00_FIFO, (char*)buf, len); 253 | 254 | RF95_setModeIdle(); 255 | 256 | RF95_Clear_IRQ(); 257 | 258 | if(RF95_Check_PayloadCRCError()) 259 | { 260 | return false; 261 | } 262 | else 263 | { 264 | return true; 265 | } 266 | } 267 | else 268 | return false; 269 | } 270 | 271 | 272 | bool RF95_send(uint8_t* data) 273 | { 274 | int len = strlen((char*)data); 275 | 276 | #if Header == Header_used 277 | uint16_t header_len = sizeof(_txHeaderTo); 278 | #endif 279 | 280 | if (len > RH_RF95_MAX_MESSAGE_LEN) 281 | return false; 282 | 283 | RF95_waitPacketSent(); // Make sure we dont interrupt an outgoing message 284 | RF95_setModeIdle(); 285 | 286 | if (!RF95_waitCAD()) 287 | return false; // Check channel activity 288 | 289 | RF95_setModeIdle(); 290 | 291 | // Position at the beginning of the FIFO 292 | RF95_write(RH_RF95_REG_0D_FIFO_ADDR_PTR, 0); 293 | 294 | // The headers 295 | #if Header == Header_used 296 | RF95_write(RH_RF95_REG_00_FIFO, _txHeaderTo); 297 | #endif 298 | 299 | // The message data 300 | RF95_write_burst(RH_RF95_REG_00_FIFO, data); 301 | 302 | #if Header == No_header 303 | RF95_write(RH_RF95_REG_22_PAYLOAD_LENGTH, len); 304 | #else 305 | RF95_write(RH_RF95_REG_22_PAYLOAD_LENGTH, len + header_len); 306 | #endif 307 | 308 | // uint8_t rBuff[15] = {0}; 309 | // uint16_t lenght_ = RF95_read(RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR); 310 | // RF95_write(RH_RF95_REG_0D_FIFO_ADDR_PTR, lenght_); 311 | // RF95_read_burst(RH_RF95_REG_00_FIFO,(char*)rBuff, len); 312 | 313 | RF95_setModeTx(); // Start the transmitter 314 | while(!RF95_Check_TxDone()){} 315 | 316 | RF95_setModeIdle(); 317 | 318 | RF95_Clear_IRQ(); 319 | return true; 320 | } 321 | 322 | 323 | bool RF95_waitCAD(void) 324 | { 325 | if (!_cad_timeout) 326 | return true; 327 | 328 | // Wait for any channel activity to finish or timeout 329 | // Sophisticated DCF function... 330 | // DCF : BackoffTime = random() x aSlotTime 331 | // 100 - 1000 ms 332 | // 10 sec timeout 333 | 334 | RF95_setModeCAD(); 335 | 336 | unsigned long t = HAL_GetTick(); 337 | while (!RF95_Check_CADDone()) 338 | { 339 | if (HAL_GetTick() - t > _cad_timeout) 340 | return false; 341 | } 342 | 343 | return true; 344 | } 345 | 346 | 347 | bool RF95_waitPacketSent(void) 348 | { 349 | if (_mode == RHModeTx) 350 | { 351 | while(!RF95_Check_TxDone()); 352 | } 353 | 354 | return true; 355 | } 356 | 357 | 358 | bool RF95_available(void) 359 | { 360 | while(!RF95_Check_RxDone()) 361 | { 362 | 363 | } 364 | 365 | if(RF95_Check_ValidHeader()) 366 | { 367 | RF95_Clear_IRQ(); 368 | return true; 369 | } 370 | else 371 | return false; 372 | } 373 | 374 | 375 | bool RF95_available_Timeout(uint16_t timeout) 376 | { 377 | unsigned long t = HAL_GetTick(); 378 | 379 | while(!RF95_Check_RxDone()) 380 | { 381 | if (HAL_GetTick() - t > timeout) 382 | return false; 383 | } 384 | 385 | if(RF95_Check_ValidHeader()) 386 | { 387 | RF95_Clear_IRQ(); 388 | return true; 389 | } 390 | else 391 | return false; 392 | } 393 | 394 | 395 | void RF95_setModeCAD(void) 396 | { 397 | if (_mode != RHModeCad) 398 | { 399 | RF95_write(RH_RF95_REG_01_OP_MODE, RH_RF95_MODE_CAD); 400 | RF95_write(RH_RF95_REG_40_DIO_MAPPING1, 0x80); // Interrupt on CadDone 401 | _mode = RHModeCad; 402 | } 403 | } 404 | 405 | uint8_t aux = 0; 406 | void RF95_setModeIdle(void) 407 | { 408 | // uint8_t aux = 0; 409 | if (_mode != RHModeIdle) 410 | { 411 | aux = RF95_read(RH_RF95_REG_01_OP_MODE); 412 | aux &= 0xF8; 413 | aux |= RH_RF95_MODE_STDBY; 414 | RF95_write(RH_RF95_REG_01_OP_MODE, aux); 415 | _mode = RHModeIdle; 416 | } 417 | } 418 | 419 | 420 | bool RF95_sleep(void) 421 | { 422 | // uint8_t aux = 0; 423 | if (_mode != RHModeSleep) 424 | { 425 | aux = RF95_read(RH_RF95_REG_01_OP_MODE); 426 | aux &= 0xF8; 427 | aux |= RH_RF95_MODE_SLEEP; 428 | RF95_write(RH_RF95_REG_01_OP_MODE, aux); 429 | _mode = RHModeSleep; 430 | } 431 | return true; 432 | } 433 | 434 | 435 | void RF95_setModeRx_Single(void) 436 | { 437 | // uint8_t aux = 0; 438 | if (_mode != RHModeRx) 439 | { 440 | aux = RF95_read(RH_RF95_REG_01_OP_MODE); 441 | aux &= 0xF8; 442 | aux |= RH_RF95_MODE_RXSINGLE; 443 | RF95_write(RH_RF95_REG_01_OP_MODE, aux); 444 | RF95_write(RH_RF95_REG_40_DIO_MAPPING1, 0x00); // Interrupt on RxDone 445 | _mode = RHModeRx; 446 | } 447 | } 448 | 449 | 450 | void RF95_setModeRx_Continuous(void) 451 | { 452 | // uint8_t aux = 0; 453 | if (_mode != RHModeRx) 454 | { 455 | aux = RF95_read(RH_RF95_REG_01_OP_MODE); 456 | aux &= 0xF8; 457 | aux |= RH_RF95_MODE_RXCONTINUOUS; 458 | RF95_write(RH_RF95_REG_01_OP_MODE, aux); 459 | RF95_write(RH_RF95_REG_40_DIO_MAPPING1, 0x00); // Interrupt on RxDone 460 | _mode = RHModeRx; 461 | } 462 | } 463 | 464 | 465 | void RF95_setModeTx(void) 466 | { 467 | // uint8_t aux = 0; 468 | if (_mode != RHModeTx) 469 | { 470 | aux = RF95_read(RH_RF95_REG_01_OP_MODE); 471 | aux &= 0xF8; 472 | aux |= RH_RF95_MODE_TX; 473 | RF95_write(RH_RF95_REG_01_OP_MODE, aux); 474 | RF95_write(RH_RF95_REG_40_DIO_MAPPING1, 0x40); // Interrupt on TxDone 475 | _mode = RHModeTx; 476 | } 477 | } 478 | 479 | 480 | bool RF95_Check_RxTimeout(void) 481 | { 482 | char reg_read = 0; 483 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 484 | reg_read = (reg_read & RH_RF95_RX_TIMEOUT) >> 7; 485 | 486 | return reg_read; 487 | } 488 | 489 | 490 | bool RF95_Check_RxDone(void) 491 | { 492 | char reg_read = 0; 493 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 494 | reg_read = (reg_read & RH_RF95_RX_DONE) >> 6; 495 | 496 | return reg_read; 497 | } 498 | 499 | 500 | bool RF95_Check_PayloadCRCError(void) 501 | { 502 | char reg_read = 0; 503 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 504 | reg_read = (reg_read & RH_RF95_PAYLOAD_CRC_ERROR) >> 5; 505 | 506 | return reg_read; 507 | } 508 | 509 | 510 | bool RF95_Check_ValidHeader(void) 511 | { 512 | char reg_read = 0; 513 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 514 | 515 | reg_read = (reg_read & RH_RF95_VALID_HEADER) >> 4; 516 | 517 | return reg_read; 518 | } 519 | 520 | 521 | bool RF95_Check_TxDone(void) 522 | { 523 | char reg_read = 0; 524 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 525 | 526 | reg_read = (reg_read & RH_RF95_TX_DONE) >> 3; 527 | 528 | return reg_read; 529 | } 530 | 531 | 532 | bool RF95_Check_CADDone(void) 533 | { 534 | char reg_read = 0; 535 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 536 | reg_read = (reg_read & RH_RF95_CAD_DONE) >> 2; 537 | 538 | return reg_read; 539 | } 540 | 541 | bool RF95_Check_FhssChannelChange(void) 542 | { 543 | char reg_read = 0; 544 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 545 | reg_read = (reg_read & RH_RF95_FHSS_CHANGE_CHANNEL) >> 1; 546 | 547 | return reg_read; 548 | } 549 | 550 | 551 | bool RF95_Check_CADDetect(void) 552 | { 553 | char reg_read = 0; 554 | reg_read = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 555 | reg_read = (reg_read & RH_RF95_CAD_DETECTED); 556 | 557 | return reg_read; 558 | } 559 | 560 | 561 | void RF95_Clear_IRQ(void) 562 | { 563 | uint8_t irq_flags = 0; 564 | 565 | RF95_write(RH_RF95_REG_12_IRQ_FLAGS, 0xFF); 566 | 567 | irq_flags = RF95_read(RH_RF95_REG_12_IRQ_FLAGS); 568 | if(irq_flags != 0) 569 | RF95_write(RH_RF95_REG_12_IRQ_FLAGS, 0xFF); 570 | } 571 | 572 | 573 | bool RF95_Check_ModemClear(void) 574 | { 575 | char reg_read = 0; 576 | reg_read = RF95_read(RH_RF95_REG_18_MODEM_STAT); 577 | reg_read = (reg_read & RH_RF95_MODEM_STATUS_CLEAR) >> 4; 578 | 579 | return reg_read; 580 | } 581 | 582 | 583 | bool RF95_Check_HeaderInfoValid(void) 584 | { 585 | char reg_read = 0; 586 | reg_read = RF95_read(RH_RF95_REG_18_MODEM_STAT); 587 | reg_read = (reg_read & RH_RF95_MODEM_STATUS_HEADER_INFO_VALID) >> 3; 588 | 589 | return reg_read; 590 | } 591 | 592 | 593 | bool RF95_Check_RxOnGoing(void) 594 | { 595 | char reg_read = 0; 596 | reg_read = RF95_read(RH_RF95_REG_18_MODEM_STAT); 597 | reg_read = (reg_read & RH_RF95_MODEM_STATUS_RX_ONGOING) >> 2; 598 | 599 | return reg_read; 600 | } 601 | 602 | bool RF95_Check_SignalSyncronized(void) 603 | { 604 | char reg_read = 0; 605 | reg_read = RF95_read(RH_RF95_REG_18_MODEM_STAT); 606 | reg_read = (reg_read & RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED) >> 1; 607 | 608 | return reg_read; 609 | } 610 | 611 | 612 | bool RF95_Check_SignalDetect(void) 613 | { 614 | char reg_read = 0; 615 | reg_read = RF95_read(RH_RF95_REG_18_MODEM_STAT); 616 | reg_read = (reg_read & RH_RF95_MODEM_STATUS_SIGNAL_DETECTED); 617 | 618 | return reg_read; 619 | } 620 | 621 | 622 | uint16_t ComputeCRC(uint16_t crc, uint8_t data, uint16_t polynomial) 623 | { 624 | uint8_t i; 625 | for(i = 0; i < 8; i++) 626 | { 627 | if((((crc & 0x8000) >> 8) | (data & 0x80)) != 0) 628 | { 629 | crc <<= 1; 630 | crc |= polynomial; 631 | } 632 | else 633 | { 634 | crc <<= 1; 635 | } 636 | data <<= 1; 637 | } 638 | return crc; 639 | } 640 | 641 | 642 | uint16_t RF95_ComputeCRC(uint8_t *buffer, uint8_t bufferLength, uint8_t crcType) 643 | { 644 | uint8_t i; 645 | uint16_t crc; 646 | uint16_t polynomial; 647 | 648 | polynomial = (crcType == CRC_TYPE_IBM) ? POLYNOMIAL_IBM : POLYNOMIAL_CCITT; 649 | crc = (crcType == CRC_TYPE_IBM) ? CRC_IBM_SEED : CRC_CCITT_SEED; 650 | 651 | for(i = 0; i < bufferLength; i++) 652 | { 653 | crc = ComputeCRC(crc, buffer[i], polynomial); 654 | } 655 | 656 | if(crcType == CRC_TYPE_IBM) 657 | { 658 | return crc; 659 | } 660 | else 661 | { 662 | return (uint16_t)(~crc); 663 | } 664 | } 665 | 666 | 667 | 668 | 669 | //======================================================================== 670 | //=======================Communication protocol=========================== 671 | //======================================================================== 672 | /* The communication protocol uses three kinds of symbols 673 | * + '?' -> to make petitions to a certain node 674 | * + 'O' -> to say something has been done correctly or to continue 675 | * + 'X' -> to say something has gone wrong or to stop 676 | * All of them are followed with the name of the node, which is only a number. 677 | */ 678 | 679 | void Clear_Buffer(uint8_t* buffer) 680 | { 681 | memset(buffer, 0, strlen((const char *)buffer)); 682 | } 683 | 684 | bool RF95_Master_Receive_from_Node(uint16_t node) 685 | { 686 | uint8_t command[3] = {0}; 687 | uint8_t ACK_command[3] = {0}; 688 | bool error = true; //No error happend 689 | bool end_flag = 0; 690 | 691 | //Prepare the ACK command 692 | sprintf((char*)ACK_command, "O%d", node); 693 | 694 | //We prepare the command to send, in this case a request for receiving from the master -> "?X" 695 | //where the X is the node ID 696 | sprintf((char*)command, "?%d", node); 697 | //Request a reception to the node X 698 | do 699 | { 700 | Clear_Buffer(LoRa_buff); 701 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 702 | HAL_Delay(2000); //Wait to give time to the slave to change to receive mode 703 | strcpy((char*)LoRa_buff, (char*)command); 704 | RF95_send(LoRa_buff); //Send the request "?x" 705 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 706 | 707 | while(strcmp((char*)LoRa_buff, (char*)ACK_command) != 0) 708 | { 709 | //Receive the data 710 | Clear_Buffer(LoRa_buff); 711 | if(RF95_waitCAD()) 712 | { 713 | Set_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 714 | RF95_setModeRx_Continuous(); 715 | error = RF95_receive_Timeout(LoRa_buff, 7000); //Receive an answer and if we doesn't receive it in the time 716 | //we send again the petition. 717 | HAL_Delay(1000); 718 | Reset_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 719 | } 720 | } 721 | } while(error == false); 722 | 723 | 724 | //Prepare the command Xx in order to check if the transaction has ended or has to stop 725 | sprintf((char*)command, "X%d", node); 726 | //Clear the LoRa buffer used for transactions to prevent errors 727 | 728 | Clear_Buffer(LoRa_buff); 729 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 730 | HAL_Delay(3000); //Wait to give time to the slave to change to receive mode 731 | strcpy((char*)LoRa_buff, (char*)ACK_command); 732 | RF95_send(LoRa_buff); //Send the ACK to indicate the slave to send the data 733 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 734 | Clear_Buffer(LoRa_buff); 735 | 736 | //Receive the data from the node x 737 | while(end_flag == 0) 738 | { 739 | do 740 | { 741 | //Receive the data 742 | Clear_Buffer(LoRa_buff); 743 | if(RF95_waitCAD()) 744 | { 745 | Set_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 746 | RF95_setModeRx_Continuous(); 747 | error = RF95_receive_Timeout(LoRa_buff, 7000); 748 | HAL_Delay(1000); 749 | Reset_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 750 | 751 | if(strcmp((char *)LoRa_buff, (char *)command) == 0) 752 | { 753 | end_flag = 1; 754 | break; 755 | } 756 | } 757 | /*=====Insert here the code for processing the data received=====*/ 758 | 759 | if(strcmp((char*)LoRa_buff, "This is text message!") == 0) 760 | { 761 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 762 | Set_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 763 | HAL_Delay(3000); 764 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 765 | Reset_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 766 | } 767 | /*===============================================================*/ 768 | if(error == true) 769 | { 770 | //Send ACK to the node x 771 | Clear_Buffer(LoRa_buff); 772 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 773 | HAL_Delay(2000); //Wait to give time to the slave to change to receive mode 774 | strcpy((char*)LoRa_buff, (char *)ACK_command); //Send the ACK indicating we want to continue the transmission 775 | RF95_send(LoRa_buff); 776 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 777 | } 778 | } while(error == false); 779 | } 780 | 781 | Clear_Buffer(LoRa_buff); 782 | return true; 783 | } 784 | 785 | 786 | bool RF95_Master_Receive_from_All_Nodes(void) 787 | { 788 | for(int i = 0; i < Num_of_Nodes; i++) 789 | { 790 | RF95_Master_Receive_from_Node(i + 1); 791 | } 792 | return true; 793 | } 794 | 795 | 796 | bool RF95_Slave_Send(void) 797 | { 798 | uint8_t command[3] = {0}; 799 | uint8_t ACK_command[3] = {0}; 800 | bool error = true; //No error happend 801 | 802 | //Prepare the ACK command 803 | sprintf((char*)ACK_command, "O%d", Node_ID); 804 | 805 | 806 | //We prepare the command to send, in this case a request for receiving from the master -> "?x" 807 | //where the x is the node ID 808 | sprintf((char*)command, "?%d", Node_ID); 809 | //Wait until a receive request is received from Master 810 | while(strcmp((char *)LoRa_buff, (char *)command) != 0) 811 | { 812 | //Receive the data 813 | Clear_Buffer(LoRa_buff); 814 | if(RF95_waitCAD()) 815 | { 816 | Set_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 817 | RF95_setModeRx_Continuous(); 818 | RF95_receive(LoRa_buff); 819 | } 820 | } 821 | HAL_Delay(1000); 822 | Reset_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 823 | 824 | 825 | //If a receive request has happened from the Master, we send the ACK to tell the master we are going to send as 826 | //soon as he send us the ACK 827 | do 828 | { 829 | Clear_Buffer(LoRa_buff); 830 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 831 | HAL_Delay(2000); 832 | strcpy((char*)LoRa_buff, (char *)ACK_command); 833 | RF95_send(LoRa_buff); 834 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 835 | Clear_Buffer(LoRa_buff); 836 | //Wait until a receive The ACK from master, which tells us to start sending data 837 | while(strcmp((char *)LoRa_buff, (char *)ACK_command) != 0) 838 | { 839 | //Receive the data 840 | Clear_Buffer(LoRa_buff); 841 | if(RF95_waitCAD()) 842 | { 843 | Set_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 844 | RF95_setModeRx_Continuous(); 845 | error = RF95_receive_Timeout(LoRa_buff, 7000); 846 | HAL_Delay(1000); 847 | Reset_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 848 | } 849 | } 850 | } while(error == false); 851 | 852 | /*=====Insert here the code for send data / processing the data received=====*/ 853 | 854 | do 855 | { 856 | //Send data to the master 857 | Clear_Buffer(LoRa_buff); 858 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 859 | HAL_Delay(3000); 860 | strcpy((char*) LoRa_buff, "This is text message!"); 861 | RF95_send(LoRa_buff); 862 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 863 | 864 | //Check for ACK 865 | Clear_Buffer(LoRa_buff); 866 | while(strcmp((char *)LoRa_buff, (char *)ACK_command) != 0) 867 | { 868 | //Receive the data 869 | if(RF95_waitCAD()) 870 | { 871 | Set_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 872 | RF95_setModeRx_Continuous(); 873 | error = RF95_receive_Timeout(LoRa_buff, 7000); 874 | HAL_Delay(2000); 875 | Reset_Pin(RX_LED_GPIO_Port, RX_LED_Pin); 876 | } 877 | } 878 | } while(error == false); 879 | 880 | 881 | /*===============================================================*/ 882 | //Prepare the command Xx in order to tell the transaction has ended or has to stop 883 | Clear_Buffer(LoRa_buff); 884 | Set_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 885 | sprintf((char*)LoRa_buff, "X%d", Node_ID); 886 | HAL_Delay(2000); 887 | RF95_send(LoRa_buff); 888 | Reset_Pin(TX_LED_GPIO_Port, TX_LED_Pin); 889 | 890 | Clear_Buffer(LoRa_buff); 891 | return true; 892 | } 893 | 894 | 895 | -------------------------------------------------------------------------------- /LoRa V1.2/RF95.h: -------------------------------------------------------------------------------- 1 | /*============================================================================================================== 2 | * To use this library a buffer called LoRa_buff has been created 3 | * and we'll have to configure the parameters for LoRa in the RF95_Init() 4 | 5 | 1. include the declaration "extern uint8_t LoRa_buff[RH_RF95_FIFO_SIZE];" in the main.c. 6 | 7 | 2. Follow these steps for the sending/reception of data: 8 | 9 | -----------Send Mode------------- 10 | RF95_Init(); 11 | strcpy(LoRa_buff, "Test to send"); //It is necessary to use the buffer LoRa_buff and the function strcpy to 12 | //copy the data to the buffer, if not the program will send nothing. 13 | 14 | RF95_send(LoRa_buff); 15 | ---------------------------------- 16 | 17 | -----------Reception Mode------------- 18 | RF95_Init(); 19 | RF95_setModeRx_Continuous(); 20 | 21 | RF95_receive(LoRa_buff); 22 | ---------------------------------- 23 | 24 | ==============================================================================================================*/ 25 | 26 | 27 | 28 | #ifndef _LORA_RF95_ 29 | #define _LORA_RF95_ 30 | 31 | #include "main.h" 32 | #include "spi.h" 33 | #include "stm32l4xx_hal_def.h" 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include "Useful_Functions.h" 39 | 40 | //Modifiers for read and send 41 | #define W 0x80 42 | #define R 0x7F 43 | 44 | // Max number of bytes the LORA Rx/Tx FIFO can hold 45 | #define RH_RF95_FIFO_SIZE 255 46 | 47 | // This is the maximum number of bytes that can be carried by the LORA. 48 | // We use some for headers, keeping fewer for RadioHead messages 49 | #define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE 50 | 51 | // The length of the headers we add. 52 | // The headers are inside the LORA's payload 53 | #define RH_RF95_HEADER_LEN 4 54 | 55 | // This is the maximum message length that can be supported by this driver. 56 | // Can be pre-defined to a smaller size (to save SRAM) prior to including this header 57 | // Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS 58 | #ifndef RH_RF95_MAX_MESSAGE_LEN 59 | #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN) 60 | #endif 61 | 62 | // The crystal oscillator frequency of the module 63 | #define RH_RF95_FXOSC 32000000.0 64 | 65 | // The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19 66 | #define RH_RF95_FSTEP (RH_RF95_FXOSC / 524288) 67 | 68 | 69 | // Register names (LoRa Mode, from table 85) 70 | #define RH_RF95_REG_00_FIFO 0x00 71 | #define RH_RF95_REG_01_OP_MODE 0x01 72 | #define RH_RF95_REG_02_RESERVED 0x02 73 | #define RH_RF95_REG_03_RESERVED 0x03 74 | #define RH_RF95_REG_04_RESERVED 0x04 75 | #define RH_RF95_REG_05_RESERVED 0x05 76 | #define RH_RF95_REG_06_FRF_MSB 0x06 77 | #define RH_RF95_REG_07_FRF_MID 0x07 78 | #define RH_RF95_REG_08_FRF_LSB 0x08 79 | #define RH_RF95_REG_09_PA_CONFIG 0x09 80 | #define RH_RF95_REG_0A_PA_RAMP 0x0a 81 | #define RH_RF95_REG_0B_OCP 0x0b 82 | #define RH_RF95_REG_0C_LNA 0x0c 83 | #define RH_RF95_REG_0D_FIFO_ADDR_PTR 0x0d 84 | #define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR 0x0e 85 | #define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR 0x0f 86 | #define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR 0x10 87 | #define RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11 88 | #define RH_RF95_REG_12_IRQ_FLAGS 0x12 89 | #define RH_RF95_REG_13_RX_NB_BYTES 0x13 90 | #define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14 91 | #define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15 92 | #define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16 93 | #define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17 94 | #define RH_RF95_REG_18_MODEM_STAT 0x18 95 | #define RH_RF95_REG_19_PKT_SNR_VALUE 0x19 96 | #define RH_RF95_REG_1A_PKT_RSSI_VALUE 0x1a 97 | #define RH_RF95_REG_1B_RSSI_VALUE 0x1b 98 | #define RH_RF95_REG_1C_HOP_CHANNEL 0x1c 99 | #define RH_RF95_REG_1D_MODEM_CONFIG1 0x1d 100 | #define RH_RF95_REG_1E_MODEM_CONFIG2 0x1e 101 | #define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB 0x1f 102 | #define RH_RF95_REG_20_PREAMBLE_MSB 0x20 103 | #define RH_RF95_REG_21_PREAMBLE_LSB 0x21 104 | #define RH_RF95_REG_22_PAYLOAD_LENGTH 0x22 105 | #define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH 0x23 106 | #define RH_RF95_REG_24_HOP_PERIOD 0x24 107 | #define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR 0x25 108 | #define RH_RF95_REG_26_MODEM_CONFIG3 0x26 109 | 110 | #define RH_RF95_REG_40_DIO_MAPPING1 0x40 111 | #define RH_RF95_REG_41_DIO_MAPPING2 0x41 112 | #define RH_RF95_REG_42_VERSION 0x42 113 | 114 | #define RH_RF95_REG_4B_TCXO 0x4b 115 | #define RH_RF95_REG_4D_PA_DAC 0x4d 116 | #define RH_RF95_REG_5B_FORMER_TEMP 0x5b 117 | #define RH_RF95_REG_61_AGC_REF 0x61 118 | #define RH_RF95_REG_62_AGC_THRESH1 0x62 119 | #define RH_RF95_REG_63_AGC_THRESH2 0x63 120 | #define RH_RF95_REG_64_AGC_THRESH3 0x64 121 | 122 | // RH_RF95_REG_01_OP_MODE 0x01 123 | #define RH_RF95_LONG_RANGE_MODE 0x80 124 | #define RH_RF95_ACCESS_SHARED_REG 0x40 125 | #define RH_RF95_MODE 0x07 126 | #define RH_RF95_MODE_SLEEP 0x00 127 | #define RH_RF95_MODE_STDBY 0x01 128 | #define RH_RF95_MODE_FSTX 0x02 129 | #define RH_RF95_MODE_TX 0x03 130 | #define RH_RF95_MODE_FSRX 0x04 131 | #define RH_RF95_MODE_RXCONTINUOUS 0x05 132 | #define RH_RF95_MODE_RXSINGLE 0x06 133 | #define RH_RF95_MODE_CAD 0x07 134 | 135 | // RH_RF95_REG_09_PA_CONFIG 0x09 136 | #define RH_RF95_PA_SELECT 0x80 137 | #define RH_RF95_MAX_POWER 0x70 138 | #define RH_RF95_OUTPUT_POWER 0x0f 139 | 140 | // RH_RF95_REG_0A_PA_RAMP 0x0a 141 | #define RH_RF95_LOW_PN_TX_PLL_OFF 0x10 142 | #define RH_RF95_PA_RAMP 0x0f 143 | #define RH_RF95_PA_RAMP_3_4MS 0x00 144 | #define RH_RF95_PA_RAMP_2MS 0x01 145 | #define RH_RF95_PA_RAMP_1MS 0x02 146 | #define RH_RF95_PA_RAMP_500US 0x03 147 | #define RH_RF95_PA_RAMP_250US 0x0 148 | #define RH_RF95_PA_RAMP_125US 0x05 149 | #define RH_RF95_PA_RAMP_100US 0x06 150 | #define RH_RF95_PA_RAMP_62US 0x07 151 | #define RH_RF95_PA_RAMP_50US 0x08 152 | #define RH_RF95_PA_RAMP_40US 0x09 153 | #define RH_RF95_PA_RAMP_31US 0x0a 154 | #define RH_RF95_PA_RAMP_25US 0x0b 155 | #define RH_RF95_PA_RAMP_20US 0x0c 156 | #define RH_RF95_PA_RAMP_15US 0x0d 157 | #define RH_RF95_PA_RAMP_12US 0x0e 158 | #define RH_RF95_PA_RAMP_10US 0x0f 159 | 160 | // RH_RF95_REG_0B_OCP 0x0b 161 | #define RH_RF95_OCP_ON 0x20 162 | #define RH_RF95_OCP_TRIM 0x1f 163 | 164 | // RH_RF95_REG_0C_LNA 0x0c 165 | #define RH_RF95_LNA_GAIN 0xe0 166 | #define RH_RF95_LNA_BOOST 0x03 167 | #define RH_RF95_LNA_BOOST_DEFAULT 0x00 168 | #define RH_RF95_LNA_BOOST_150PC 0x11 169 | 170 | // RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11 171 | #define RH_RF95_RX_TIMEOUT_MASK 0x80 172 | #define RH_RF95_RX_DONE_MASK 0x40 173 | #define RH_RF95_PAYLOAD_CRC_ERROR_MASK 0x20 174 | #define RH_RF95_VALID_HEADER_MASK 0x10 175 | #define RH_RF95_TX_DONE_MASK 0x08 176 | #define RH_RF95_CAD_DONE_MASK 0x04 177 | #define RH_RF95_FHSS_CHANGE_CHANNEL_MASK 0x02 178 | #define RH_RF95_CAD_DETECTED_MASK 0x01 179 | 180 | // RH_RF95_REG_12_IRQ_FLAGS 0x12 181 | #define RH_RF95_RX_TIMEOUT 0x80 182 | #define RH_RF95_RX_DONE 0x40 183 | #define RH_RF95_PAYLOAD_CRC_ERROR 0x20 184 | #define RH_RF95_VALID_HEADER 0x10 185 | #define RH_RF95_TX_DONE 0x08 186 | #define RH_RF95_CAD_DONE 0x04 187 | #define RH_RF95_FHSS_CHANGE_CHANNEL 0x02 188 | #define RH_RF95_CAD_DETECTED 0x01 189 | 190 | // RH_RF95_REG_18_MODEM_STAT 0x18 191 | #define RH_RF95_RX_CODING_RATE 0xe0 192 | #define RH_RF95_MODEM_STATUS_CLEAR 0x10 193 | #define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08 194 | #define RH_RF95_MODEM_STATUS_RX_ONGOING 0x04 195 | #define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02 196 | #define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01 197 | 198 | // RH_RF95_REG_1C_HOP_CHANNEL 0x1c 199 | #define RH_RF95_PLL_TIMEOUT 0x80 200 | #define RH_RF95_RX_PAYLOAD_CRC_IS_ON 0x40 201 | #define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f 202 | 203 | // RH_RF95_REG_1D_MODEM_CONFIG1 0x1d 204 | #define RH_RF95_BW 0xc0 205 | #define RH_RF95_BW_125KHZ 0x00 206 | #define RH_RF95_BW_250KHZ 0x40 207 | #define RH_RF95_BW_500KHZ 0x80 208 | #define RH_RF95_BW_RESERVED 0xc0 209 | #define RH_RF95_CODING_RATE 0x38 210 | #define RH_RF95_CODING_RATE_4_5 0x00 211 | #define RH_RF95_CODING_RATE_4_6 0x08 212 | #define RH_RF95_CODING_RATE_4_7 0x10 213 | #define RH_RF95_CODING_RATE_4_8 0x18 214 | #define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x04 215 | #define RH_RF95_RX_PAYLOAD_CRC_ON 0x02 216 | #define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x01 217 | 218 | // RH_RF95_REG_1E_MODEM_CONFIG2 0x1e 219 | #define RH_RF95_SPREADING_FACTOR 0xf0 220 | #define RH_RF95_SPREADING_FACTOR_64CPS 0x60 221 | #define RH_RF95_SPREADING_FACTOR_128CPS 0x70 222 | #define RH_RF95_SPREADING_FACTOR_256CPS 0x80 223 | #define RH_RF95_SPREADING_FACTOR_512CPS 0x90 224 | #define RH_RF95_SPREADING_FACTOR_1024CPS 0xa0 225 | #define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0 226 | #define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0 227 | #define RH_RF95_TX_CONTINUOUS_MOE 0x08 228 | #define RH_RF95_AGC_AUTO_ON 0x04 229 | #define RH_RF95_SYM_TIMEOUT_MSB 0x03 230 | 231 | // RH_RF95_REG_4D_PA_DAC 0x4d 232 | #define RH_RF95_PA_DAC_DISABLE 0x04 233 | #define RH_RF95_PA_DAC_ENABLE 0x07 234 | 235 | 236 | #define No_header 0 237 | #define Header_used 1 238 | #define Header No_header 239 | 240 | //CRC Types 241 | #define CRC_TYPE_CCITT 0 242 | #define CRC_TYPE_IBM 1 243 | 244 | //Polynomial = X^16 + X^12 + X^5 + 1 245 | #define POLYNOMIAL_CCITT 0x1021 246 | //Polynomial = X^16 + X^15 + X^2 + 1 247 | #define POLYNOMIAL_IBM 0x8005 248 | 249 | //Seeds 250 | #define CRC_IBM_SEED 0xFFFF 251 | #define CRC_CCITT_SEED 0x1D0F 252 | 253 | 254 | typedef enum 255 | { 256 | Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range 257 | Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range 258 | Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range 259 | Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range 260 | IH_Bw125Cr45Sf128, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range + Implicit Header 261 | } ModemConfigChoice; 262 | 263 | typedef enum 264 | { 265 | RHModeInitialising = 0, ///< Transport is initialising. Initial default value until init() is called.. 266 | RHModeSleep, ///< Transport hardware is in low power sleep mode (if supported) 267 | RHModeIdle, ///< Transport is idle. 268 | RHModeTx, ///< Transport is in the process of transmitting a message. 269 | RHModeRx, ///< Transport is in the process of receiving a message. 270 | RHModeCad, 271 | } RHMode; 272 | 273 | HAL_StatusTypeDef RF95_write(char reg, char wValue); 274 | HAL_StatusTypeDef RF95_write_burst(char reg, uint8_t* data); 275 | char RF95_read(char reg); 276 | HAL_StatusTypeDef RF95_read_burst(char reg, char* buffer, int length); 277 | 278 | //=====Init and configuration=====// 279 | bool RF95_Init(void); 280 | void RF95_Reset(void); 281 | bool RF95_setModemConfig(ModemConfigChoice index); 282 | void RF95_setPreambleLength(uint16_t bytes); 283 | void RF95_setTxPower(int8_t power, bool useRFO); 284 | bool RF95_setFrequency(float centre); 285 | 286 | //=====Send and receive=====// 287 | bool RF95_receive(uint8_t* buf); 288 | bool RF95_receive_Timeout(uint8_t* buf, uint16_t timeout); 289 | bool RF95_send(uint8_t* data); 290 | 291 | //=====Control=====// 292 | bool RF95_available(void); 293 | bool RF95_available_Timeout(uint16_t timeout); 294 | bool RF95_available_Timeout(uint16_t timeout); 295 | bool RF95_waitPacketSent(void); 296 | bool RF95_waitCAD(void); 297 | 298 | //=====Modes Configuration=====// 299 | void RF95_setModeIdle(void); 300 | bool RF95_sleep(void); 301 | void RF95_setModeRx_Continuous(void); 302 | void RF95_setModeRx_Single(void); 303 | void RF95_setModeTx(void); 304 | void RF95_setModeCAD(void); 305 | 306 | 307 | //=====Check flags=====// 308 | bool RF95_Check_RxTimeout(void); 309 | bool RF95_Check_RxDone(void); 310 | bool RF95_Check_PayloadCRCError(void); 311 | bool RF95_Check_ValidHeader(void); 312 | bool RF95_Check_TxDone(void); 313 | bool RF95_Check_CADDone(void); 314 | bool RF95_Check_FhssChannelChange(void); 315 | bool RF95_Check_CADDetect(void); 316 | void RF95_Clear_IRQ(void); 317 | 318 | bool RF95_Check_ModemClear(void); 319 | bool RF95_Check_HeaderInfoValid(void); 320 | bool RF95_Check_RxOnGoing(void); 321 | bool RF95_Check_SignalSyncronized(void); 322 | bool RF95_Check_SignalDetect(void); 323 | 324 | 325 | //=====CRC calculation=====// 326 | uint16_t ComputeCRC(uint16_t crc, uint8_t data, uint16_t polynomial); 327 | uint16_t RF95_ComputeCRC(uint8_t *buffer, uint8_t bufferLength, uint8_t crcType); 328 | 329 | 330 | 331 | 332 | //======================================================================== 333 | //=======================Communication protocol=========================== 334 | //======================================================================== 335 | /* The communication protocol uses three kinds of symbols 336 | * + '?' -> to make petitions to a certain node 337 | * + 'O' -> to say something has been done correctly or to continue 338 | * + 'X' -> to say something has gone wrong or to stop 339 | * All of them are followed with the name of the node, which is only a number. 340 | */ 341 | #define Num_of_Nodes 2 342 | #define Node_ID 1 343 | 344 | void Clear_Buffer(uint8_t* buffer); 345 | bool RF95_Master_Receive_from_Node(uint16_t node); 346 | bool RF95_Master_Receive_from_All_Nodes(void); 347 | bool RF95_Slave_Send(void); 348 | 349 | #endif 350 | 351 | 352 | -------------------------------------------------------------------------------- /Master.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MartiGeek17/LoRa-RFM95-STM32/7719574b4dee682b58636ab2bd23e0b9a27def3d/Master.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LoRa-RFM95-STM32 2 | This repository contains the different versions of a library to be used in STM32 devices for the devices RFM95/96/97/98. It can be adapted to other microcontrollers changing the communication orders. 3 | -------------------------------------------------------------------------------- /Slave.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/MartiGeek17/LoRa-RFM95-STM32/7719574b4dee682b58636ab2bd23e0b9a27def3d/Slave.zip --------------------------------------------------------------------------------