Skip to content

[WIP] Add Waveshare Pico-LoRa-SX1262-868M support #15

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
.vscode/

build/

10 changes: 5 additions & 5 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

```c
// pin configuration for SX1276 radio module
struct lorawan_sx1276_settings sx1276_settings = {
struct lorawan_sx12xx_settings sx12xx_settings = {
.spi = {
.inst = PICO_DEFAULT_SPI_INSTANCE, // RP2040 SPI instance
.mosi = PICO_DEFAULT_SPI_TX_PIN, // SPI MOSI GPIO
Expand Down Expand Up @@ -47,10 +47,10 @@ const struct lorawan_abp_settings abp_settings = {
.channel_mask = NULL,
};

int lorawan_init_abp(const struct lorawan_sx1276_settings* sx1276_settings, LoRaMacRegion_t region, const struct lorawan_abp_settings* abp_settings);
int lorawan_init_abp(const struct lorawan_sx12xx_settings* sx12xx_settings, LoRaMacRegion_t region, const struct lorawan_abp_settings* abp_settings);
```

- `sx1276_settings` - pointer to settings for SX1276 SPI and GPIO pins
- `sx12xx_settings` - pointer to settings for SX1276 SPI and GPIO pins
- `region` - region to use, see [`enum LoRaMacRegion_t
`](http://stackforce.github.io/LoRaMac-doc/LoRaMac-doc-v4.5.1/group___l_o_r_a_m_a_c.html#ga3b9d54f0355b51e85df8b33fd1757eec)for supported values]
- `abp_settings` - pointer to LoRaWAN ABP settings
Expand All @@ -77,10 +77,10 @@ const struct lorawan_otaa_settings otaa_settings = {
.channel_mask = NULL,
};

int lorawan_init_otaa(const struct lorawan_sx1276_settings* sx1276_settings, LoRaMacRegion_t region, const struct lorawan_otaa_settings* otaa_settings);
int lorawan_init_otaa(const struct lorawan_sx12xx_settings* sx12xx_settings, LoRaMacRegion_t region, const struct lorawan_otaa_settings* otaa_settings);
```

- `sx1276_settings` - pointer to settings for SX1276 SPI and GPIO pins
- `sx12xx_settings` - pointer to settings for SX1276 SPI and GPIO pins
- `region` - region to use, see [`enum LoRaMacRegion_t
`](http://stackforce.github.io/LoRaMac-doc/LoRaMac-doc-v4.5.1/group___l_o_r_a_m_a_c.html#ga3b9d54f0355b51e85df8b33fd1757eec)for supported values]
- `otaa_settings` - pointer to LoRaWAN OTAA settings
Expand Down
53 changes: 46 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,30 @@ pico_sdk_init()

set(LORAMAC_NODE_PATH ${CMAKE_CURRENT_LIST_DIR}/lib/LoRaMac-node)

# Choose whether to enable Waveshare SX1262 module support instead of SX1276 support.
# This will control cmake's build behavior.
option(WITH_WAVESHARE_SX126X "Enable Waveshare SX1262 Raspberry Pi LoRa module support instead of SX1276" OFF)

# Enable for use with SX126X, e.g. Waveshare Raspberry Pi Pico LoRa module SX1262 by uncommenting:
#set(WITH_WAVESHARE_SX126X ON)

## Depending on previous selection, add the following items
if(WITH_WAVESHARE_SX126X)
message("Building for SX126X")
set(SX12XX_RADIO_FILES
${LORAMAC_NODE_PATH}/src/radio/sx126x/sx126x.c
${LORAMAC_NODE_PATH}/src/radio/sx126x/radio.c
)
set(SX12XX_BOARD_FILES ${CMAKE_CURRENT_LIST_DIR}/src/boards/rp2040/sx126x-board.c)
else()
message("Building for SX1276")
set(SX12XX_RADIO_FILES
${LORAMAC_NODE_PATH}/src/radio/sx1276/sx1276.c
)
set(SX12XX_BOARD_FILES ${CMAKE_CURRENT_LIST_DIR}/src/boards/rp2040/sx1276-board.c)
endif()


add_library(pico_loramac_node INTERFACE)

target_sources(pico_loramac_node INTERFACE
Expand Down Expand Up @@ -65,7 +89,7 @@ target_sources(pico_loramac_node INTERFACE
${LORAMAC_NODE_PATH}/src/peripherals/soft-se/soft-se-hal.c
${LORAMAC_NODE_PATH}/src/peripherals/soft-se/soft-se.c

${LORAMAC_NODE_PATH}/src/radio/sx1276/sx1276.c
${SX12XX_RADIO_FILES}

${LORAMAC_NODE_PATH}/src/system/delay.c
${LORAMAC_NODE_PATH}/src/system/gpio.c
Expand All @@ -79,7 +103,8 @@ target_sources(pico_loramac_node INTERFACE
${CMAKE_CURRENT_LIST_DIR}/src/boards/rp2040/gpio-board.c
${CMAKE_CURRENT_LIST_DIR}/src/boards/rp2040/rtc-board.c
${CMAKE_CURRENT_LIST_DIR}/src/boards/rp2040/spi-board.c
${CMAKE_CURRENT_LIST_DIR}/src/boards/rp2040/sx1276-board.c

${SX12XX_BOARD_FILES}
)

target_include_directories(pico_loramac_node INTERFACE
Expand Down Expand Up @@ -108,7 +133,11 @@ target_compile_definitions(pico_loramac_node INTERFACE -DREGION_CN470)
target_compile_definitions(pico_loramac_node INTERFACE -DREGION_KR920)
target_compile_definitions(pico_loramac_node INTERFACE -DREGION_IN865)
target_compile_definitions(pico_loramac_node INTERFACE -DREGION_RU864)
target_compile_definitions(pico_loramac_node INTERFACE -DACTIVE_REGION=LORAMAC_REGION_US915)
if(WITH_WAVESHARE_SX126X)
target_compile_definitions(pico_loramac_node INTERFACE -DACTIVE_REGION=LORAMAC_REGION_EU868)
else()
target_compile_definitions(pico_loramac_node INTERFACE -DACTIVE_REGION=LORAMAC_REGION_US915)
endif()

add_library(pico_lorawan INTERFACE)

Expand All @@ -122,7 +151,17 @@ target_include_directories(pico_lorawan INTERFACE

target_link_libraries(pico_lorawan INTERFACE pico_loramac_node)

add_subdirectory("examples/default_dev_eui")
add_subdirectory("examples/hello_abp")
add_subdirectory("examples/hello_otaa")
add_subdirectory("examples/otaa_temperature_led")
# define sx1262 for preprocessor if Waveshare sx1262 support is enabled in cmake.
# Also do not build all examples for now (they are partly incompatible)
if(WITH_WAVESHARE_SX126X)
add_definitions(-Dsx126x)
add_subdirectory("examples/otaa_temperature_led")
else()
add_definitions(-Dsx1276)
add_subdirectory("examples/default_dev_eui")
add_subdirectory("examples/hello_abp")
add_subdirectory("examples/hello_otaa")
add_subdirectory("examples/otaa_temperature_led")
endif()


63 changes: 62 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# pico-lorawan
Enable LoRaWAN communications on your [Raspberry Pi Pico](https://www.raspberrypi.org/products/raspberry-pi-pico/) or any RP2040 based board using a [Semtech SX1276 radio module](https://www.semtech.com/apps/product.php?pn=SX1276).
Enable LoRaWAN communications on your [Raspberry Pi Pico](https://www.raspberrypi.org/products/raspberry-pi-pico/) or any RP2040 based board using a [Semtech SX1276 radio module](https://www.semtech.com/apps/product.php?pn=SX1276) or [Waveshare's SX1262-based LoRaWAN module](https://www.waveshare.com/wiki/Pico-LoRa-SX1262-868M).

Based on the Semtech's [LoRaWAN end-device stack implementation and example projects](https://github.com/Lora-net/LoRaMac-node).

Expand All @@ -11,9 +11,13 @@ Based on the Semtech's [LoRaWAN end-device stack implementation and example proj
* Semtech SX1276 board
* [Adafruit RFM95W LoRa Radio Transceiver Breakout - 868 or 915 MHz - RadioFruit](https://www.adafruit.com/product/3072)
* [Adafruit LoRa Radio FeatherWing - RFM95W 900 MHz - RadioFruit](https://www.adafruit.com/product/3231)
* Semtech SX1262 board
* [Waveshare Pico-LoRa-SX1262-868M](https://www.waveshare.com/wiki/Pico-LoRa-SX1262-868M) | [Shop](https://www.waveshare.com/pico-lora-sx1262-868m.htm)

### Default Pinout

Default Pinout for Semtech SX1276:

| Raspberry Pi Pico / RP2040 | Semtech SX1276 |
| ----------------- | -------------- |
| 3.3V | VCC |
Expand All @@ -26,8 +30,63 @@ Based on the Semtech's [LoRaWAN end-device stack implementation and example proj
| GPIO 9 | RESET |
| GPIO 10 | DIO1 / G1 |

Default Pinout for Semtech SX1262 on Waveshare Pico-LoRa-SX1262-868M:

| Raspberry Pi Pico / RP2040 | Waveshare Pico-LoRa-SX1262-868M |
| ----------------- | -------------- |
| 3.3V | VCC |
| GND | GND |
| GPIO 10 | SCK |
| GPIO 11 | MOSI |
| GPIO 12 | MISO |
| GPIO 3 | NSS / CS |
| GPIO 15 | RESET |
| GPIO 20 | DIO1 |
| GPIO 2 | BUSY |

GPIO pins are configurable in examples or API.

## Enabling support for Waveshare Pico-LoRa-SX1262-868M

By default this library only supports the Semtech SX1276 boards mentioned in the first section. Support for Waveshare's SX1262-based Raspberry Pi Pico Hat is available, but needs to be enabled actively.

Take the following steps to switch from SX1276 to Waveshare SX1262 support:

Uncomment

```
set(WITH_WAVESHARE_SX126X ON)
```

in `CMakeLists.txt`.

In your example application, e.g. otaa_temperature_led/ set the region to EU868 in `config.h`:

```
#define LORAWAN_REGION LORAMAC_REGION_EU868
```

_(and also provide your Device EUI, App EUI and App Key here!)_

In the example application's `main.c` make sure that you're using the proper `sx12xx_settings` for your SX1262 Waveshare module:

```
const struct lorawan_sx12xx_settings sx12xx_settings = {
.spi = {
.inst = spi1,
.mosi = 11,
.miso = 12,
.sck = 10,
.nss = 3
},
.reset = 15,
.busy = 2,
.dio1 = 20
};
```

_**There is no guarantee that other SX1262-based boards will work. Tests have only been run using Waveshare's board.**_

## Examples

See [examples](examples/) folder.
Expand Down Expand Up @@ -60,5 +119,7 @@ make

A big thanks to [Alasdair Allan](https://github.com/aallan) for his initial testing of EU868 support!

Thanks to Waveshare and [siuwahzhong](https://github.com/siuwahzhong) for providing their modified version of this library. Parts of their work have been merged back into this library by [Thomas Leister](https://github.com/ThomasLeister). Original source: [ZIP](https://www.waveshare.com/w/upload/0/08/Pico-LoRa-SX1262-868M_Code.zip) | [GitHub](https://github.com/siuwahzhong/lorawan-library-for-pico)

This project was created on behalf of the [Arm Software Developers](https://developer.arm.com/) team, follow them on Twitter: [@ArmSoftwareDev](https://twitter.com/armsoftwaredev) and YouTube: [Arm Software Developers](https://www.youtube.com/channel/UCHUAckhCfRom2EHDGxwhfOg) for more resources!

30 changes: 24 additions & 6 deletions examples/hello_abp/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,38 @@
// edit with LoRaWAN Node Region and ABP settings
#include "config.h"

// pin configuration for SX1276 radio module
const struct lorawan_sx1276_settings sx1276_settings = {
/*
* Pin configuration for SX1276 radio module (default)
*/
const struct lorawan_sx12xx_settings sx12xx_settings = {
.spi = {
.inst = PICO_DEFAULT_SPI_INSTANCE,
.mosi = PICO_DEFAULT_SPI_TX_PIN,
.miso = PICO_DEFAULT_SPI_RX_PIN,
.sck = PICO_DEFAULT_SPI_SCK_PIN,
.nss = 8
.nss = 8
},
.reset = 9,
.dio0 = 7,
.dio1 = 10
.dio0 = 7,
.dio1 = 10
};

/*
* Configuration for SX1262 Waveshare module
*/
//const struct lorawan_sx12xx_settings sx12xx_settings = {
// .spi = {
// .inst = spi1,
// .mosi = 11,
// .miso = 12,
// .sck = 10,
// .nss = 3
// },
// .reset = 15,
// .busy = 2,
// .dio1 = 20
//};

// ABP settings
const struct lorawan_abp_settings abp_settings = {
.device_address = LORAWAN_DEV_ADDR,
Expand Down Expand Up @@ -62,7 +80,7 @@ int main( void )

// initialize the LoRaWAN stack
printf("Initilizating LoRaWAN ... ");
if (lorawan_init_abp(&sx1276_settings, LORAWAN_REGION, &abp_settings) < 0) {
if (lorawan_init_abp(&sx12xx_settings, LORAWAN_REGION, &abp_settings) < 0) {
printf("failed!!!\n");
while (1) {
tight_loop_contents();
Expand Down
24 changes: 21 additions & 3 deletions examples/hello_otaa/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
// edit with LoRaWAN Node Region and OTAA settings
#include "config.h"

// pin configuration for SX1276 radio module
const struct lorawan_sx1276_settings sx1276_settings = {
/*
* Pin configuration for SX1276 radio module (default)
*/
const struct lorawan_sx12xx_settings sx12xx_settings = {
.spi = {
.inst = PICO_DEFAULT_SPI_INSTANCE,
.mosi = PICO_DEFAULT_SPI_TX_PIN,
Expand All @@ -32,6 +34,22 @@ const struct lorawan_sx1276_settings sx1276_settings = {
.dio1 = 10
};

/*
* Configuration for SX1262 Waveshare module
*/
//const struct lorawan_sx12xx_settings sx12xx_settings = {
// .spi = {
// .inst = spi1,
// .mosi = 11,
// .miso = 12,
// .sck = 10,
// .nss = 3
// },
// .reset = 15,
// .busy = 2,
// .dio1 = 20
//};

// OTAA settings
const struct lorawan_otaa_settings otaa_settings = {
.device_eui = LORAWAN_DEVICE_EUI,
Expand Down Expand Up @@ -61,7 +79,7 @@ int main( void )

// initialize the LoRaWAN stack
printf("Initilizating LoRaWAN ... ");
if (lorawan_init_otaa(&sx1276_settings, LORAWAN_REGION, &otaa_settings) < 0) {
if (lorawan_init_otaa(&sx12xx_settings, LORAWAN_REGION, &otaa_settings) < 0) {
printf("failed!!!\n");
while (1) {
tight_loop_contents();
Expand Down
24 changes: 21 additions & 3 deletions examples/otaa_temperature_led/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@
// edit with LoRaWAN Node Region and OTAA settings
#include "config.h"

// pin configuration for SX1276 radio module
const struct lorawan_sx1276_settings sx1276_settings = {
/*
* Pin configuration for SX1276 radio module (default)
*/
const struct lorawan_sx12xx_settings sx12xx_settings = {
.spi = {
.inst = PICO_DEFAULT_SPI_INSTANCE,
.mosi = PICO_DEFAULT_SPI_TX_PIN,
Expand All @@ -36,6 +38,22 @@ const struct lorawan_sx1276_settings sx1276_settings = {
.dio1 = 10
};

/*
* Configuration for SX1262 Waveshare module
*/
//const struct lorawan_sx12xx_settings sx12xx_settings = {
// .spi = {
// .inst = spi1,
// .mosi = 11,
// .miso = 12,
// .sck = 10,
// .nss = 3
// },
// .reset = 15,
// .busy = 2,
// .dio1 = 20
//};

// OTAA settings
const struct lorawan_otaa_settings otaa_settings = {
.device_eui = LORAWAN_DEVICE_EUI,
Expand Down Expand Up @@ -74,7 +92,7 @@ int main( void )

// initialize the LoRaWAN stack
printf("Initilizating LoRaWAN ... ");
if (lorawan_init_otaa(&sx1276_settings, LORAWAN_REGION, &otaa_settings) < 0) {
if (lorawan_init_otaa(&sx12xx_settings, LORAWAN_REGION, &otaa_settings) < 0) {
printf("failed!!!\n");
while (1) {
tight_loop_contents();
Expand Down
2 changes: 1 addition & 1 deletion src/boards/rp2040/eeprom-board.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void EepromMcuInit()

uint8_t EepromMcuReadBuffer( uint16_t addr, uint8_t *buffer, uint16_t size )
{
memcpy(buffer, EEPROM_ADDRESS + addr, size);
memcpy(buffer, eeprom_write_cache + addr, size);

return SUCCESS;
}
Expand Down
10 changes: 10 additions & 0 deletions src/boards/rp2040/gpio-board.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,13 @@ uint32_t GpioMcuRead( Gpio_t *obj )
{
return gpio_get(obj->pin);
}

void GpioMcuSetInterrupt( Gpio_t *obj, IrqModes irqMode, IrqPriorities irqPriority, GpioIrqHandler *irqHandler )
{
gpio_set_irq_enabled_with_callback(obj->pin,GPIO_IRQ_EDGE_RISE,true,irqHandler);
}

void GpioMcuRemoveInterrupt( Gpio_t *obj )
{
gpio_set_irq_enabled(obj->pin,GPIO_IRQ_EDGE_RISE,false);
}
Loading