SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf

esp-idf-sx127x

SX1276/77/78/79 Low Power Long Range Transceiver driver for esp-idf.

I based on this.

Changes from the original

  • Added support for ESP32S2, ESP32S3 and ESP32C3.
  • I left the control of CS to the driver.
  • Added a sample of ping-pong.
  • Added some API functions.

Software requirements

esp-idf v4.4 or later.
This is because this version supports ESP32-C3.

Installation

git clone https://github.com/nopnop2002/esp-idf-sx127x
cd esp-idf-sx127x/basic/
idf.py set-target {esp32/esp32s2/esp32s3/esp32c3}
idf.py menuconfig
idf.py flash

Note for ESP32C3
For some reason, there are development boards that cannot use GPIO06, GPIO08, GPIO09, GPIO19 for SPI clock pins.
According to the ESP32C3 specifications, these pins can also be used as SPI clocks.
I used a raw ESP-C3-13 to verify that these pins could be used as SPI clocks.

Configuration for Transceiver

config-lora-1 config-lora-2

Wirering

SX127X ESP32 ESP32-S2/S3 ESP32-C3
RST -- GPIO16 GPIO38 GPIO8
MISO -- GPIO19 GPIO37 GPIO18
SCK -- GPIO18 GPIO36 GPIO10
MOSI -- GPIO23 GPIO35 GPIO19
NSS -- GPIO15 GPIO34 GPIO7
GND -- GND GND GND
VCC -- 3.3V 3.3V 3.3V

You can change it to any pin using menuconfig.

Communication with SX126X

LoRa's packet format is strictly specified.
Therefore, if the following three parameters are the same, they can communicate with each other.

  • Signal Bandwidth (= BW)
  • Error Cording Rate (= CR)
  • Spreading Factor (= SF)

Reference

https://github.com/nopnop2002/esp-idf-sx126x

Comments
  • Which sx127*  module ?

    Which sx127* module ?

    Hello, which SX127* module are you using for dev this library ? i guess hoperf rfm95 or any board with an esp32 and lora module like Liligo.

    Why i ask ? Because im looking for support of EbYTES sx1276/78 modules like E19-868M30S Those modules are designed with some added pin like TXEN/RXEN that must be respetively HIGH when sending or receiving. But i never see ESP-IDF library which implement this.

  • Conflict with SPI sdcard driver (InstrFetchProhibited)

    Conflict with SPI sdcard driver (InstrFetchProhibited)

    I've ported part of the IRQ handling code from https://github.com/bkgoodman/esp-idf-lora, to your implementation. However, I'm seeing a conflict with both the IRQ handling and the SPI bus initialization:

        esp_err_t err = ESP_OK;
    
    #ifdef LED_PIN
        gpio_set_direction(LED_PIN, GPIO_MODE_OUTPUT);
    #endif
    
    #if CONFIG_I2C_INTERFACE
        int i2c_sda = CONFIG_SDA_GPIO;
        int i2c_sclk = CONFIG_SCL_GPIO;
        int reset_pin = CONFIG_RESET_GPIO;
    
    	ESP_LOGI(TAG, "INTERFACE is i2c");
    	ESP_LOGI(TAG, "CONFIG_SDA_GPIO=%d",CONFIG_SDA_GPIO);
    	ESP_LOGI(TAG, "CONFIG_SCL_GPIO=%d",CONFIG_SCL_GPIO);
    	ESP_LOGI(TAG, "CONFIG_RESET_GPIO=%d",CONFIG_RESET_GPIO);
    
        i2c_config_t i2c_config = {
    		.mode = I2C_MODE_MASTER,
    		.sda_io_num = i2c_sda,
    		.scl_io_num = i2c_sclk,
            .sda_pullup_en = GPIO_PULLUP_ENABLE,
            .scl_pullup_en = GPIO_PULLUP_ENABLE,
            .master.clk_speed = I2C_MASTER_FREQ_HZ
    	};
    
    	ESP_ERROR_CHECK(i2c_param_config(I2C_NUM, &i2c_config));
    	ESP_ERROR_CHECK(i2c_driver_install(I2C_NUM, I2C_MODE_MASTER, 0, 0, 0));
    
        if (reset_pin >= 0) {
    		//gpio_pad_select_gpio(reset);
    		gpio_reset_pin(reset_pin);
    		gpio_set_direction(reset_pin, GPIO_MODE_OUTPUT);
    		gpio_set_level(reset_pin, 0);
    		vTaskDelay(50 / portTICK_PERIOD_MS);
    		gpio_set_level(reset_pin, 1);
    	}
    
    #ifdef HAS_OLED_DISPLAY
        ssd1306_init(&ssd1306_dev, 128, 64);
        ssd1306_clear_screen(&ssd1306_dev, false);
    	ssd1306_contrast(&ssd1306_dev, 0xff);
    #endif
    #endif // CONFIG_I2C_INTERFACE
    
    #ifdef USE_SDCARD
        spi_bus_config_t bus_cfg = {
            .mosi_io_num = SDCARD_MOSI,
            .miso_io_num = SDCARD_MISO,
            .sclk_io_num = SDCARD_SCK,
            .quadwp_io_num = -1,
            .quadhd_io_num = -1,
            .max_transfer_sz = 4000,
        };
        ret = spi_bus_initialize(host.slot, &bus_cfg, SDSPI_DEFAULT_HOST);
        if (ret != ESP_OK) {
            ESP_LOGE(TAG, "Failed to initialize bus.");
            return ret;
        }
    #endif
    
        err = lora_setup(cfg);
        if (err != ESP_OK)
            ESP_LOGW(TAG, "RF communications not functional. Missing component?");
    
    

    My SD card code is identical to:

    https://raw.githubusercontent.com/espressif/esp-idf/a82e6e63d98bb051d4c59cb3d440c537ab9f74b0/examples/storage/sd_card/sdspi/main/sd_card_example_main.c

    My TTGO LORA32 board configuration:

    #define OLED_RST    -1
    #define OLED_SDA    21
    #define OLED_SCL    22
    
    #define CONFIG_SDA_GPIO OLED_SDA
    #define CONFIG_SCL_GPIO OLED_SCL
    #define CONFIG_RESET_GPIO OLED_RST
    
    #define SDCARD_SCK      14
    #define SDCARD_MOSI     15
    #define SDCARD_MISO     2
    #define SDCARD_CS       13
    
    #define LORA_MOSI       27
    #define LORA_MISO       19
    #define LORA_SCLK       5
    #define LORA_CS         18
    #define LORA_RST        23
    #define LORA_DIO0       26
    #define LORA_ISR        LORA_DIO0
    
    #define CONFIG_LORA_CS_GPIO  LORA_CS
    #define CONFIG_LORA_RST_GPIO LORA_RST
    #define CONFIG_LORA_MISO_GPIO LORA_MISO
    #define CONFIG_LORA_MOSI_GPIO LORA_MOSI
    #define CONFIG_LORA_SCK_GPIO LORA_SCLK
    #define CONFIG_LORA_IRQ_GPIO LORA_ISR
    

    LORA setup:

    esp_err_t lora_init(void)
    {
       esp_err_t ret;
    
       /*
        * Configure CPU hardware to communicate with the radio chip
        */
       gpio_pad_select_gpio(CONFIG_LORA_RST_GPIO);
       gpio_set_direction(CONFIG_LORA_RST_GPIO, GPIO_MODE_OUTPUT);
    
       gpio_reset_pin(CONFIG_LORA_CS_GPIO);
       gpio_pad_select_gpio(CONFIG_LORA_CS_GPIO);
       gpio_set_direction(CONFIG_LORA_CS_GPIO, GPIO_MODE_OUTPUT);
       gpio_set_level(CONFIG_LORA_CS_GPIO, 1);
    
    
       spi_bus_config_t bus = {
          .miso_io_num = CONFIG_LORA_MISO_GPIO,
          .mosi_io_num = CONFIG_LORA_MOSI_GPIO,
          .sclk_io_num = CONFIG_LORA_SCK_GPIO,
          .quadwp_io_num = -1,
          .quadhd_io_num = -1,
          .max_transfer_sz = 0
       };
       
       ret = spi_bus_initialize(SPI_HOST_ID, &bus, SPI_DMA_CH_AUTO);
       if (ret != ESP_OK)
          return ret;
    
       spi_device_interface_config_t dev = {
          .clock_speed_hz = 9000000,
          .mode = 0,
          .spics_io_num = CONFIG_LORA_CS_GPIO,
          .queue_size = 7,
          .flags = 0,
          .pre_cb = NULL
       };
    
       ret = spi_bus_add_device(SPI_HOST_ID, &dev, &__spi);
       if (ret != ESP_OK)
          return ret;
    
       /*
        * Perform hardware reset.
        */
       lora_reset();
    
       /*
        * Check version.
        */
       uint8_t version;
       uint8_t i = 0;
       while(i++ < TIMEOUT_RESET) {
          version = lora_read_reg(REG_VERSION);
          if(version == 0x12) break;
          vTaskDelay(2);
       }
       assert(i <= TIMEOUT_RESET + 1); // at the end of the loop above, the max value i can reach is TIMEOUT_RESET + 1
    
       /*
        * Default configuration.
        */
       lora_sleep();
       lora_write_reg(REG_FIFO_RX_BASE_ADDR, 0);
       lora_write_reg(REG_FIFO_TX_BASE_ADDR, 0);
       lora_write_reg(REG_LNA, lora_read_reg(REG_LNA) | 0x03);
       lora_write_reg(REG_MODEM_CONFIG_3, 0x04);
       lora_set_tx_power(17);
    
       lora_idle();
       return ESP_OK;
    }
    

    I've been trying to follow the steps described here: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/peripherals/sdspi_share.html

    Guru Meditation Error: Core  0 panic'ed (InstrFetchProhibited). Exception was unhandled.
    
    Core  0 register dump:
    PC      : 0x00000000  PS      : 0x00060030  A0      : 0x00000000  A1      : 0x3ffbc510  
    A2      : 0x3ffb9750  A3      : 0x00000000  A4      : 0x3ffb4610  A5      : 0x3ffb4620  
    A6      : 0x00000001  A7      : 0x00000060  A8      : 0x8008cec4  A9      : 0x3ffbc4f0  
    A10     : 0x3ffb9750  A11     : 0x00000092  A12     : 0x00000091  A13     : 0x00000060  
    A14     : 0x00000000  A15     : 0x00000001  SAR     : 0x00000000  EXCCAUSE: 0x00000014  
    EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0x00000000  
    

    I'm happy to send you the entire lora.c file. Thank you for your excellent work again, your repositories are an absolute time saver and great reference.

  • stack overflow on esp32-c3

    stack overflow on esp32-c3

    creating task with 1024*2 stack size is too small and therefore lead to carsh loop with stack overflow when lauching either task_rx or task_tx in basic exemple.

    #if CONFIG_SENDER                                                                                                                                                                                          
             xTaskCreate(&task_tx, "task_tx", 1024*4, NULL, 5, NULL);                                                                                                                                           
    #endif                                                                                                                                                                                                     
    #if CONFIG_RECEIVER                                                                                                                                                                                                  
             xTaskCreate(&task_rx, "task_rx", 1024*4, NULL, 5, NULL);                
    

    Solution is to increase stack size at task creation.

  • Enhancement requests

    Enhancement requests

    I'd like to make a few enhancements to your LoRa library. Would you be open to me making the following enhancements?

    1. Add support for FSK operation e.g.: typedef enum { sx_mode_lora, sx_mode_fsk } sx_radio_mode; void lora_set_mode(sx_radio_mode new_mode); // default init mode is LoRa void lora_set_fsk_bitrate(unsigned bps); // auto-sets other FSK parameters void lora_get_fsk_fei(void); // read frequency error

    2. Add support for making the reset pin optional if set to -1 and/or adding an installer for an optional external reset function (Because the ESP32 is so short on pins, I use an external GPIO expander wherever possible)

    3. Add optional support for interrupt-driven operation using at least DIO0 rather than polling using vTaskDelay()

    Thanks for providing the library!

  • Any plans to support dio0 and dio1?

    Any plans to support dio0 and dio1?

    I'm trying to move over to the idf from Arduino because the esp32c3 usb support is absolutely terrible there. I was using the radiolib arduino library for the sx1276 and it works great. But it doesn't work in the idf obviously. It does have support for dio0 dio1 (and rxen txen pins that a lot of modules have). Are these pins going to be added in the future?

CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf
CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf

esp-idf-cc2500 CC2500 Low-Cost Low-Power 2.4 GHz RF Transceiver driver for esp-idf. I ported from this. 2.00mm pitch External Antena 1.27mm pitch PCB

May 29, 2022
Veml7700-esp-idf - VEML7700 Light Sensor driver for ESP-IDF
Veml7700-esp-idf - VEML7700 Light Sensor driver for ESP-IDF

VEML7700 Light Sensor driver for ESP-IDF Overview This project aims to provide a very simple interface for configuring and reading data from the VEML7

Jul 29, 2022
SI4432 ISM Transceiver driver for esp-idf
SI4432 ISM Transceiver driver for esp-idf

esp-idf-si4432 SI4432 ISM Transceiver driver for esp-idf. I refered this. Software requirements esp-idf v4.4 or later. This is because this version su

May 29, 2022
To simplify the development of ESP32 in ESP-IDF, Easyio provides a complete driver library

Easyio 开源驱动库 Easyio 是一款适配于ESP-IDF框架的开源驱动库,以支持ESP32的简便开发。目的是简化乐鑫ESP-IDF开发框架的使用难度。(真要方便的话,有现成的Arduino和Platform可以用,不过实在迫于工作要求,有的开源东西不让用,同时便于对接FAE,于是就有了 E

Sep 16, 2022
Packages for simulating the Tethys-class Long-Range AUV (LRAUV) from the Monterey Bay Aquarium Research Institute (MBARI).
Packages for simulating the Tethys-class Long-Range AUV (LRAUV) from the Monterey Bay Aquarium Research Institute (MBARI).

LRAUV Simulation This repository contains packages for simulating the Tethys-class Long-Range AUV (LRAUV) from the Monterey Bay Aquarium Research Inst

Aug 3, 2022
idf.py.exe, wrapper tool to invoke idf.py on Windows

IDF wrapper tool (idf.py.exe) This tools helps invoke idf.py in Windows CMD shell. In Windows CMD shell, python scripts can be executed directly (by t

Dec 13, 2021
An Arduino wrapper to @sdima1357's usb_soft_host esp-idf example
An Arduino wrapper to @sdima1357's usb_soft_host esp-idf example

ESP32 USB Soft Host library for Arduino IDE This is mainly a wrapper around the excellent work of Dmitry Samsonov (@sdima1357) with esp32_usb_soft_hos

Sep 15, 2022
GFX Demo for the ESP-IDF
GFX Demo for the ESP-IDF

Display Drivers and Demo for GFX This is a Demo of GFX With Several Display Drivers This is not GFX itself, but it includes it. GFX Documentation is b

Sep 7, 2022
ESP32 S2 C++ host library compatible with arduino, esp-idf.

Info I would like to announce USB host library for esp32 S2 compatible with arduino, esp-idf and PIO (when pio will be updated to most recent esp-idf)

Jun 2, 2022
使用ESP-IDF、ESP-ADF、LVGL等库,基于ESP32S2实现简单的网络收音机和FM收音机功能。
使用ESP-IDF、ESP-ADF、LVGL等库,基于ESP32S2实现简单的网络收音机和FM收音机功能。

【电子森林项目】网络收音机/FM收音机 这个项目是报名《硬禾“暑期一起练”第3个平台 - 基于ESP32-S2模块的网络收音机和音频信号处理》所做的。 基本功能: 可以连接WiFi收听HLS协议的网络电台节目 收听空中的FM电台88MHz~108MHz OLED0.96寸显示 四个独立按键控制两种模

Aug 4, 2022
LVGL8 for ESP-IDF

X-UI LVGL8 for ESP-IDF 移植自X-TRACK项目的页面栈框架,新增支持异步通信的订阅发布数据中心 特点 使用C语言重构,方便继承复用 核心文件 ui_page_manager.h、ui_page_manager.c 实现页面栈、订阅发布数据中心 完整页面生命周期 MVC架构 数

Aug 5, 2022
Additional components for ESP-IDF, maintained by Espressif

Espressif IDF Extra Components This repository aims to store ESP-IDF extra components which have been seperated and uploaded into IDF Component Manage

Sep 10, 2022
Add tensilica esp32 cpu and a board to qemu and dump the rom to learn more about esp-idf

qemu_esp32 Add tensilica esp32 cpu and a board to qemu and dump the rom to learn more about esp-idf ESP32 in QEMU. This documents how to add an esp32

Sep 16, 2022
This FreeRTOS example builds a simple Timer application for Linux using the ESP-IDF

Supported Targets Linux This FreeRTOS example builds a simple Timer application for Linux using the ESP-IDF. Build Source the IDF environment as usual

Apr 4, 2022
WireGuard Implementation for ESP-IDF

esp_wireguard, WireGuard Implementation for ESP-IDF This is an implementation of the WireGuard® for ESP-IDF, based on WireGuard Implementation for lwI

Sep 10, 2022
Collection of additional Ethernet drivers for ESP-IDF

Collection of additional Ethernet drivers for ESP-IDF This repository aims to store additional Ethernet drivers which are not available directly in ES

Sep 19, 2022
RemixDB: A read- and write-optimized concurrent KV store. Fast point and range queries. Extremely low write-amplification.

REMIX and RemixDB The REMIX data structure was introduced in paper "REMIX: Efficient Range Query for LSM-trees", FAST'21. This repository maintains a

Sep 10, 2022
mCube's ultra-low-power wake-on-motion 3-axis accelerometer
mCube's ultra-low-power wake-on-motion 3-axis accelerometer

MC3635 mCube's ultra-low-power wake-on-motion 3-axis accelerometer Based on mCube's Arduino demo driver, this sketch is specific for the MC3635 3-axis

Aug 26, 2022
A couple of demos showing how to use the Ultra Low Power coprocessor on the ESP32
A couple of demos showing how to use the Ultra Low Power coprocessor on the ESP32

ESP32 Ultra Low Power (ULP) coprocessor You can watch a video explanation of this code here This repo contains two demo project: ulp-gpio Shows you ho

Jan 21, 2022