From a355a098e6543cb2101f10b5a2d517e7c6301a65 Mon Sep 17 00:00:00 2001 From: jgromes Date: Sun, 12 Apr 2020 11:32:07 +0200 Subject: [PATCH] [SX128x] Added BLE modem support --- .../SX128x_BLE_Modem/SX128x_BLE_Modem.ino | 114 ++++++++++++++++++ keywords.txt | 1 + src/modules/SX128x/SX128x.cpp | 61 +++++++++- src/modules/SX128x/SX128x.h | 26 ++++ 4 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino diff --git a/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino b/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino new file mode 100644 index 00000000..166215b7 --- /dev/null +++ b/examples/SX128x/SX128x_BLE_Modem/SX128x_BLE_Modem.ino @@ -0,0 +1,114 @@ +/* + RadioLib SX128x BLE Modem Example + + This example shows how to use BLE modem in SX128x chips. + RadioLib does not provide BLE protocol support (yet), + only compatibility with the physical layer. + + NOTE: The sketch below is just a guide on how to use + BLE modem, so this code should not be run directly! + Instead, modify the other examples to use BLE + modem and use the appropriate configuration + methods. + + For full API reference, see the GitHub Pages + https://jgromes.github.io/RadioLib/ +*/ + +// include the library +#include + +// SX1280 has the following connections: +// NSS pin: 10 +// DIO1 pin: 2 +// NRST pin: 3 +// BUSY pin: 9 +SX1280 ble = new Module(10, 2, 3, 9); + +// or using RadioShield +// https://github.com/jgromes/RadioShield +//SX1280 ble = RadioShield.ModuleA; + +void setup() { + Serial.begin(9600); + + // initialize SX1280 with default settings + Serial.print(F("[SX1280] Initializing ... ")); + // carrier frequency: 2400.0 MHz + // bit rate: 800 kbps + // frequency deviation: 400.0 kHz + // output power: 10 dBm + // preamble length: 16 bits + // data shaping: Gaussian, BT = 0.5 + // CRC: enabled, CRC16 (CCIT) + int state = ble.beginBLE(); + if (state == ERR_NONE) { + Serial.println(F("success!")); + } else { + Serial.print(F("failed, code ")); + Serial.println(state); + while (true); + } + + // if needed, you can switch between LoRa and FSK modes + // + // ble.begin() start LoRa mode (and disable BLE) + // lora.beginBLE() start BLE mode (and disable LoRa) + + // the following settings can also + // be modified at run-time + state = ble.setFrequency(2410.5); + state = ble.setBitRate(200); + state = ble.setFrequencyDeviation(100.0); + state = ble.setOutputPower(5); + state = ble.setDataShaping(1.0); + state = ble.setAccessAddress(0x12345678); + if (state != ERR_NONE) { + Serial.print(F("Unable to set configuration, code ")); + Serial.println(state); + while (true); + } + + #warning "This sketch is just an API guide! Read the note at line 6." +} + +void loop() { + // BLE modem can use the same transmit/receive methods + // as the LoRa modem, even their interrupt-driven versions + + // transmit BLE packet + int state = ble.transmit("Hello World!"); + /* + byte byteArr[] = {0x01, 0x23, 0x45, 0x67, + 0x89, 0xAB, 0xCD, 0xEF}; + int state = ble.transmit(byteArr, 8); + */ + if (state == ERR_NONE) { + Serial.println(F("[SX1280] Packet transmitted successfully!")); + } else if (state == ERR_PACKET_TOO_LONG) { + Serial.println(F("[SX1280] Packet too long!")); + } else if (state == ERR_TX_TIMEOUT) { + Serial.println(F("[SX1280] Timed out while transmitting!")); + } else { + Serial.println(F("[SX1280] Failed to transmit packet, code ")); + Serial.println(state); + } + + // receive BLE packet + String str; + state = ble.receive(str); + /* + byte byteArr[8]; + int state = ble.receive(byteArr, 8); + */ + if (state == ERR_NONE) { + Serial.println(F("[SX1280] Received packet!")); + Serial.print(F("[SX1280] Data:\t")); + Serial.println(str); + } else if (state == ERR_RX_TIMEOUT) { + Serial.println(F("[SX1280] Timed out while waiting for packet!")); + } else { + Serial.print(F("[SX1280] Failed to receive packet, code ")); + Serial.println(state); + } +} diff --git a/keywords.txt b/keywords.txt index af21ca40..6afdf6ba 100644 --- a/keywords.txt +++ b/keywords.txt @@ -216,6 +216,7 @@ getPictureHeight KEYWORD2 beginGFSK KEYWORD2 beginFLRC KEYWORD2 beginBLE KEYWORD2 +setAccessAddress KEYWORD2 range KEYWORD2 startRanging KEYWORD2 getRangingResult KEYWORD2 diff --git a/src/modules/SX128x/SX128x.cpp b/src/modules/SX128x/SX128x.cpp index 73a25fe5..2404e420 100644 --- a/src/modules/SX128x/SX128x.cpp +++ b/src/modules/SX128x/SX128x.cpp @@ -114,6 +114,54 @@ int16_t SX128x::beginGFSK(float freq, uint16_t br, float freqDev, int8_t power, return(state); } +int16_t SX128x::beginBLE(float freq, uint16_t br, float freqDev, int8_t power, float dataShaping) { + // set module properties + _mod->init(RADIOLIB_USE_SPI); + Module::pinMode(_mod->getIrq(), INPUT); + Module::pinMode(_mod->getGpio(), INPUT); + + // initialize BLE modulation variables + _brKbps = br; + _br = SX128X_BLE_GFSK_BR_0_800_BW_2_4; + _modIndexReal = 1.0; + _modIndex = SX128X_BLE_GFSK_MOD_IND_1_00; + _shaping = SX128X_BLE_GFSK_BT_0_5; + + // initialize BLE packet variables + _crcGFSK = SX128X_BLE_CRC_3_BYTE; + _whitening = SX128X_GFSK_BLE_WHITENING_ON; + + // reset the module and verify startup + int16_t state = reset(); + RADIOLIB_ASSERT(state); + + // set mode to standby + state = standby(); + RADIOLIB_ASSERT(state); + + // configure settings not accessible by API + state = config(SX128X_PACKET_TYPE_BLE); + RADIOLIB_ASSERT(state); + + // configure publicly accessible settings + state = setFrequency(freq); + RADIOLIB_ASSERT(state); + + state = setBitRate(br); + RADIOLIB_ASSERT(state); + + state = setFrequencyDeviation(freqDev); + RADIOLIB_ASSERT(state); + + state = setOutputPower(power); + RADIOLIB_ASSERT(state); + + state = setDataShaping(dataShaping); + RADIOLIB_ASSERT(state); + + return(state); +} + int16_t SX128x::beginFLRC(float freq, uint16_t br, uint8_t cr, int8_t power, uint16_t preambleLength, float dataShaping) { // set module properties _mod->init(RADIOLIB_USE_SPI); @@ -468,7 +516,7 @@ int16_t SX128x::readData(uint8_t* data, size_t len) { if(getPacketType() == SX128X_PACKET_TYPE_RANGING) { return(ERR_WRONG_MODEM); } - + // set mode to standby int16_t state = standby(); RADIOLIB_ASSERT(state); @@ -896,6 +944,17 @@ int16_t SX128x::setWhitening(bool enabled) { return(setPacketParamsBLE(_connectionState, _crcBLE, _bleTestPayload, _whitening)); } +int16_t SX128x::setAccessAddress(uint32_t addr) { + // check active modem + if(getPacketType() != SX128X_PACKET_TYPE_BLE) { + return(ERR_WRONG_MODEM); + } + + // use setSyncWord to set the address + uint8_t syncWord[] = { (uint8_t)((addr >> 24) & 0xFF), (uint8_t)((addr >> 16) & 0xFF), (uint8_t)((addr >> 8) & 0xFF), (uint8_t)(addr & 0xFF) }; + return(setSyncWord(syncWord, 4)); +} + float SX128x::getRSSI() { // get packet status uint8_t packetStatus[5]; diff --git a/src/modules/SX128x/SX128x.h b/src/modules/SX128x/SX128x.h index 6548f511..82e19884 100644 --- a/src/modules/SX128x/SX128x.h +++ b/src/modules/SX128x/SX128x.h @@ -384,6 +384,23 @@ class SX128x: public PhysicalLayer { */ int16_t beginGFSK(float freq = 2400.0, uint16_t br = 800, float freqDev = 400.0, int8_t power = 10, uint16_t preambleLength = 16, float dataShaping = 0.5); + /*! + \brief Initialization method for BLE modem. + + \param freq Carrier frequency in MHz. Defaults to 2400.0 MHz. + + \param br BLE bit rate in kbps. Defaults to 800 kbps. + + \param freqDev Frequency deviation from carrier frequency in kHz. Defaults to 400.0 kHz. + + \param power Output power in dBm. Defaults to 10 dBm. + + \param dataShaping Time-bandwidth product of the Gaussian filter to be used for shaping. Defaults to 0.5. + + \returns \ref status_codes + */ + int16_t beginBLE(float freq = 2400.0, uint16_t br = 800, float freqDev = 400.0, int8_t power = 10, float dataShaping = 0.5); + /*! \brief Initialization method for FLRC modem. @@ -654,6 +671,15 @@ class SX128x: public PhysicalLayer { */ int16_t setWhitening(bool enabled); + /*! + \brief Sets BLE access address. + + \param addr BLE access address. + + \returns \ref status_codes + */ + int16_t setAccessAddress(uint32_t addr); + /*! \brief Gets RSSI (Recorded Signal Strength Indicator) of the last received packet.