Initial commit

This commit is contained in:
2026-01-17 09:53:08 +02:00
commit 159633e837
148 changed files with 42795 additions and 0 deletions

View File

@@ -0,0 +1,8 @@
# The following lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
# "Trim" the build. Include the minimal set of components, main, and anything it depends on.
idf_build_set_property(MINIMAL_BUILD ON)
project(test_lr1121)

View File

@@ -0,0 +1,3 @@
idf_component_register(SRCS "lr1121_config.c" "test_lr1121.c"
PRIV_REQUIRES spi_flash driver
INCLUDE_DIRS "")

View File

@@ -0,0 +1,8 @@
## IDF Component Manager Manifest File
dependencies:
## Required IDF version
idf: ">=5.3.0"
esp_lora_1121:
version: "*"
path: "../../../esp_lora_1121"

View File

@@ -0,0 +1,394 @@
/*!
* @file lr1121_config.c
*
* @brief Common functions shared by the examples
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2022. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the disclaimer
* below) provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Semtech corporation nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
* THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "lr1121_config.h"
lr1121_t lr1121;
// LoRa modulation parameters
static lr11xx_radio_mod_params_lora_t lora_mod_params = {
.sf = LORA_SPREADING_FACTOR, // Spreading factor
.bw = LORA_BANDWIDTH, // Bandwidth
.cr = LORA_CODING_RATE, // Coding rate
.ldro = 0 // Low Data Rate Optimization (initialized in radio init)
};
// LoRa packet parameters
static const lr11xx_radio_pkt_params_lora_t lora_pkt_params = {
.preamble_len_in_symb = LORA_PREAMBLE_LENGTH, // Preamble length in symbols
.header_type = LORA_PKT_LEN_MODE, // Header type (implicit or explicit)
.pld_len_in_bytes = PAYLOAD_LENGTH, // Payload length in bytes
.crc = LORA_CRC, // CRC mode
.iq = LORA_IQ, // IQ inversion
};
// GFSK modulation parameters
static const lr11xx_radio_mod_params_gfsk_t gfsk_mod_params = {
.br_in_bps = FSK_BITRATE, // Bitrate in bps
.pulse_shape = FSK_PULSE_SHAPE, // Pulse shape
.bw_dsb_param = FSK_BANDWIDTH, // Bandwidth parameter
.fdev_in_hz = FSK_FDEV, // Frequency deviation in Hz
};
// GFSK packet parameters
static const lr11xx_radio_pkt_params_gfsk_t gfsk_pkt_params = {
.preamble_len_in_bits = FSK_PREAMBLE_LENGTH, // Preamble length in bits
.preamble_detector = FSK_PREAMBLE_DETECTOR, // Preamble detector type
.sync_word_len_in_bits = FSK_SYNCWORD_LENGTH, // Sync word length in bits
.address_filtering = FSK_ADDRESS_FILTERING, // Address filtering mode
.header_type = FSK_HEADER_TYPE, // Header type
.pld_len_in_bytes = PAYLOAD_LENGTH, // Payload length in bytes
.crc_type = FSK_CRC_TYPE, // CRC type
.dc_free = FSK_DC_FREE, // DC-free encoding mode
};
static const lr11xx_radio_mod_params_bpsk_t bpsk_mod_params = {
.br_in_bps = BPSK_BITRATE_IN_BPS,
.pulse_shape = LR11XX_RADIO_DBPSK_PULSE_SHAPE,
};
static lr11xx_radio_pkt_params_bpsk_t bpsk_pkt_params = {
.pld_len_in_bytes = 0, // Will be initialized in radio init
.ramp_up_delay = 0,
.ramp_down_delay = 0,
.pld_len_in_bits = 0, // Will be initialized in radio init
};
void print_lora_configuration( void );
void print_gfsk_configuration( void );
// Initialize the LR1121 system
void lora_system_init( const void* context )
{
lr11xx_system_reset( ( void* ) context ); // Reset the LR1121 system
lr11xx_hal_wakeup( ( void* ) context ); // Wake up the device
// Enable or disable CRC over SPI
#if defined(USE_LR11XX_CRC_OVER_SPI)
lr11xx_system_enable_spi_crc(( void* ) context, true);
#else
lr11xx_system_enable_spi_crc(( void* ) context, false);
#endif
// Set the LR1121 to standby mode using the external oscillator
lr11xx_system_set_standby(( void* ) context, LR11XX_SYSTEM_STANDBY_CFG_XOSC);
// Calibrate the image
lr11xx_system_calibrate_image(( void* ) context,0x6B,0x6E); // Calibrate for 430~440MHz
// lr11xx_system_calibrate_image(( void* ) context,0xD7,0xDB); // Calibrate for 863~870MHz
// Configure the regulator mode
const lr11xx_system_reg_mode_t regulator = smtc_shield_lr11xx_common_get_reg_mode();
lr11xx_system_set_reg_mode( ( void* ) context, regulator );
// Configure the RF switch
const lr11xx_system_rfswitch_cfg_t* rf_switch_setup = smtc_shield_lr11xx_common_get_rf_switch_cfg();
lr11xx_system_set_dio_as_rf_switch( context, rf_switch_setup );
// Enable the TCXO
lr11xx_system_set_tcxo_mode( context, LR11XX_SYSTEM_TCXO_CTRL_3_0V, 300 );
// Configure the low-frequency clock source
lr11xx_system_cfg_lfclk( context, LR11XX_SYSTEM_LFCLK_XTAL, true );
// Clear all pending error flags
lr11xx_system_clear_errors( context );
// Calibrate the system
lr11xx_system_calibrate( context, 0x3F );
uint16_t errors;
// Retrieve system errors
lr11xx_system_get_errors( context, &errors );
if(errors & LR11XX_SYSTEM_ERRORS_IMG_CALIB_MASK)
{
printf("Image calibration error\r\n");
}
// Clear all pending error flags
lr11xx_system_clear_errors( context );
// Clear all pending IRQ status bits
lr11xx_system_clear_irq_status( context, LR11XX_SYSTEM_IRQ_ALL_MASK );
}
// Initialize the LR1121 radio module
void lora_radio_init( const void* context )
{
// Retrieve the PA power configuration for the target frequency and power level
const smtc_shield_lr11xx_pa_pwr_cfg_t* pa_pwr_cfg =
smtc_shield_lr1121mb1gis_get_pa_pwr_cfg( RF_FREQ_IN_HZ, TX_OUTPUT_POWER_DBM );
if( pa_pwr_cfg == NULL )
{
printf( "Invalid target frequency or power level\n" );
while( true )
{
}
}
// Print common configuration parameters
printf( "Common parameters:\n" );
printf( " Packet type = %s\n", lr11xx_radio_pkt_type_to_str( PACKET_TYPE ) );
printf( " RF frequency = %u Hz\n", RF_FREQ_IN_HZ );
printf( " Output power = %i dBm\n", TX_OUTPUT_POWER_DBM );
printf( " Fallback mode = %s\n", lr11xx_radio_fallback_modes_to_str( FALLBACK_MODE ) );
printf( ( ENABLE_RX_BOOST_MODE == true ) ? " Rx boost activated\n" : " Rx boost deactivated\n" );
printf( "\n" );
// Set the packet type
lr11xx_radio_set_pkt_type( context, PACKET_TYPE );
// Verify the packet type setting
lr11xx_radio_pkt_type_t spi_check;
lr11xx_radio_get_pkt_type(context, &spi_check);
if(spi_check == LR11XX_RADIO_PKT_TYPE_LORA)
{
printf("LoRa modulation\r\n" );
}
else if(spi_check == LR11XX_RADIO_PKT_TYPE_GFSK)
{
printf("GFSK modulation\r\n" );
}
else
printf("spi_check_err\r\n" );
// Set the RF frequency
lr11xx_radio_set_rf_freq( context, RF_FREQ_IN_HZ );
// Set the RSSI calibration table
lr11xx_radio_set_rssi_calibration(context, smtc_shield_lr11xx_get_rssi_calibration_table( RF_FREQ_IN_HZ ));
// Configure the PA settings
lr11xx_radio_set_pa_cfg( context, &( pa_pwr_cfg->pa_config ) );
// Set the TX power and ramp time
lr11xx_radio_set_tx_params( context, pa_pwr_cfg->power, PA_RAMP_TIME );
// Set the fallback mode after TX/RX operations
lr11xx_radio_set_rx_tx_fallback_mode( context, FALLBACK_MODE );
// Configure the RX boost mode
lr11xx_radio_cfg_rx_boosted( context, ENABLE_RX_BOOST_MODE );
// Configure LoRa or GFSK parameters based on the packet type
if( PACKET_TYPE == LR11XX_RADIO_PKT_TYPE_LORA )
{
print_lora_configuration( );
lora_mod_params.ldro = smtc_shield_lr11xx_common_compute_lora_ldro( LORA_SPREADING_FACTOR, LORA_BANDWIDTH );
lr11xx_radio_set_lora_mod_params( context, &lora_mod_params );
lr11xx_radio_set_lora_pkt_params( context, &lora_pkt_params );
lr11xx_radio_set_lora_sync_word( context, LORA_SYNCWORD );
}
// Configure the radio for GFSK modulation
else if( PACKET_TYPE == LR11XX_RADIO_PKT_TYPE_GFSK )
{
// Print the current GFSK configuration
print_gfsk_configuration( );
// Set the GFSK modulation parameters
lr11xx_radio_set_gfsk_mod_params( context, &gfsk_mod_params );
// Set the GFSK packet parameters
lr11xx_radio_set_gfsk_pkt_params( context, &gfsk_pkt_params );
// Set the GFSK sync word
lr11xx_radio_set_gfsk_sync_word( context, gfsk_sync_word );
// If DC-free encoding is enabled, set the whitening seed
if( FSK_DC_FREE != LR11XX_RADIO_GFSK_DC_FREE_OFF )
{
lr11xx_radio_set_gfsk_whitening_seed( context, FSK_WHITENING_SEED );
}
// If CRC is enabled, set the CRC parameters
if( FSK_CRC_TYPE != LR11XX_RADIO_GFSK_CRC_OFF )
{
lr11xx_radio_set_gfsk_crc_params( context, FSK_CRC_SEED, FSK_CRC_POLYNOMIAL );
}
// If address filtering is enabled, set the packet address
if( FSK_ADDRESS_FILTERING != LR11XX_RADIO_GFSK_ADDRESS_FILTERING_DISABLE )
{
lr11xx_radio_set_pkt_address( context, FSK_NODE_ADDRESS, FSK_BROADCAST_ADDRESS );
}
}
// Configure the radio for LR-FHSS modulation
else if( PACKET_TYPE == LR11XX_RADIO_PKT_TYPE_LR_FHSS )
{
// Define the LR-FHSS modulation parameters
const lr11xx_radio_mod_params_lr_fhss_t mod_lr_fhss = {
.br_in_bps = LR11XX_RADIO_LR_FHSS_BITRATE_488_BPS, // Bitrate in bps
.pulse_shape = LR11XX_RADIO_LR_FHSS_PULSE_SHAPE_BT_1, // Pulse shape
};
// Set the LR-FHSS modulation parameters
lr11xx_radio_set_lr_fhss_mod_params( context, &mod_lr_fhss );
}
}
void lora_radio_dbpsk_init( const void* context, const uint8_t payload_len )
{
const smtc_shield_lr11xx_pa_pwr_cfg_t* pa_pwr_cfg =
smtc_shield_lr1121mb1gis_get_pa_pwr_cfg( SIGFOX_UPLINK_RF_FREQ_IN_HZ, SIGFOX_TX_OUTPUT_POWER_DBM );
if( pa_pwr_cfg == NULL )
{
printf( "Invalid target frequency or power level\n" );
while( true )
{
}
}
printf( "Sigfox parameters:\n" );
printf( " Packet type = %s\n", lr11xx_radio_pkt_type_to_str( LR11XX_RADIO_PKT_TYPE_BPSK ) );
printf( " RF frequency = %u Hz\n", SIGFOX_UPLINK_RF_FREQ_IN_HZ );
printf( " Output power = %i dBm\n", SIGFOX_TX_OUTPUT_POWER_DBM );
lr11xx_radio_set_pkt_type( context, LR11XX_RADIO_PKT_TYPE_BPSK );
lr11xx_radio_set_rf_freq( context, SIGFOX_UPLINK_RF_FREQ_IN_HZ );
lr11xx_radio_set_rssi_calibration(
context, smtc_shield_lr11xx_get_rssi_calibration_table( SIGFOX_UPLINK_RF_FREQ_IN_HZ ) );
lr11xx_radio_set_pa_cfg( context, &( pa_pwr_cfg->pa_config ) );
lr11xx_radio_set_tx_params( context, pa_pwr_cfg->power, PA_RAMP_TIME ) ;
lr11xx_radio_set_bpsk_mod_params( context, &bpsk_mod_params );
bpsk_pkt_params.pld_len_in_bytes = smtc_dbpsk_get_pld_len_in_bytes( payload_len << 3 );
bpsk_pkt_params.pld_len_in_bits = smtc_dbpsk_get_pld_len_in_bits( payload_len << 3 );
if( BPSK_BITRATE_IN_BPS == 100 )
{
bpsk_pkt_params.ramp_up_delay = LR11XX_RADIO_SIGFOX_DBPSK_RAMP_UP_TIME_100_BPS;
bpsk_pkt_params.ramp_down_delay = LR11XX_RADIO_SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS;
}
else if( BPSK_BITRATE_IN_BPS == 600 )
{
bpsk_pkt_params.ramp_up_delay = LR11XX_RADIO_SIGFOX_DBPSK_RAMP_UP_TIME_600_BPS;
bpsk_pkt_params.ramp_down_delay = LR11XX_RADIO_SIGFOX_DBPSK_RAMP_DOWN_TIME_600_BPS;
}
else
{
bpsk_pkt_params.ramp_up_delay = LR11XX_RADIO_SIGFOX_DBPSK_RAMP_UP_TIME_DEFAULT;
bpsk_pkt_params.ramp_down_delay = LR11XX_RADIO_SIGFOX_DBPSK_RAMP_DOWN_TIME_DEFAULT;
}
lr11xx_radio_set_bpsk_pkt_params( context, &bpsk_pkt_params );
}
// Print the LoRa configuration parameters
void print_lora_configuration(void)
{
// Print LoRa modulation parameters
printf( "LoRa modulation parameters:\n" );
printf( " Spreading factor = %s\n", lr11xx_radio_lora_sf_to_str( LORA_SPREADING_FACTOR ) ); // Spreading factor
printf( " Bandwidth = %s\n", lr11xx_radio_lora_bw_to_str( LORA_BANDWIDTH ) ); // Bandwidth
printf( " Coding rate = %s\n", lr11xx_radio_lora_cr_to_str( LORA_CODING_RATE ) ); // Coding rate
printf( "\n" );
// Print LoRa packet parameters
printf( "LoRa packet parameters:\n" );
printf( " Preamble length = %d symbol(s)\n", LORA_PREAMBLE_LENGTH ); // Preamble length in symbols
printf( " Header mode = %s\n", lr11xx_radio_lora_pkt_len_modes_to_str( LORA_PKT_LEN_MODE ) ); // Header mode
printf( " Payload length = %d byte(s)\n", PAYLOAD_LENGTH ); // Payload length in bytes
printf( " CRC mode = %s\n", lr11xx_radio_lora_crc_to_str( LORA_CRC ) ); // CRC mode
printf( " IQ = %s\n", lr11xx_radio_lora_iq_to_str( LORA_IQ ) ); // IQ inversion
printf( "\n" );
// Print LoRa syncword
printf( "LoRa syncword = 0x%02X\n", LORA_SYNCWORD );
printf( "\n" );
}
// Print the GFSK configuration parameters
void print_gfsk_configuration( void )
{
// Print GFSK modulation parameters
printf( "GFSK modulation parameters:\n" );
printf( " Bitrate = %u bps\n", FSK_BITRATE ); // Bitrate in bps
printf( " Pulse shape = %s\n", lr11xx_radio_gfsk_pulse_shape_to_str( FSK_PULSE_SHAPE ) ); // Pulse shape
printf( " Bandwidth = %s\n", lr11xx_radio_gfsk_bw_to_str( FSK_BANDWIDTH ) ); // Bandwidth
printf( " Frequency deviation = %u Hz\n", FSK_FDEV ); // Frequency deviation in Hz
printf( "\n" );
// Print GFSK packet parameters
printf( "GFSK packet parameters:\n" );
printf( " Preamble length = %d bit(s)\n", FSK_PREAMBLE_LENGTH ); // Preamble length in bits
printf( " Preamble detector = %s\n", lr11xx_radio_gfsk_preamble_detector_to_str( FSK_PREAMBLE_DETECTOR ) ); // Preamble detector
printf( " Syncword length = %d bit(s)\n", FSK_SYNCWORD_LENGTH ); // Syncword length in bits
printf( " Address filtering = %s\n", lr11xx_radio_gfsk_address_filtering_to_str( FSK_ADDRESS_FILTERING ) ); // Address filtering mode
if( FSK_ADDRESS_FILTERING != LR11XX_RADIO_GFSK_ADDRESS_FILTERING_DISABLE )
{
printf( " (Node address = 0x%02X)\n", FSK_NODE_ADDRESS ); // Node address
if( FSK_ADDRESS_FILTERING == LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_AND_BROADCAST_ADDRESSES )
{
printf( " (Broadcast address = 0x%02X)\n", FSK_BROADCAST_ADDRESS ); // Broadcast address
}
}
printf( " Header mode = %s\n", lr11xx_radio_gfsk_pkt_len_modes_to_str( FSK_HEADER_TYPE ) ); // Header mode
printf( " Payload length = %d byte(s)\n", PAYLOAD_LENGTH ); // Payload length in bytes
printf( " CRC mode = %s\n", lr11xx_radio_gfsk_crc_type_to_str( FSK_CRC_TYPE ) ); // CRC mode
if( FSK_CRC_TYPE != LR11XX_RADIO_GFSK_CRC_OFF )
{
printf( " (CRC seed = 0x%08X)\n", FSK_CRC_SEED ); // CRC seed
printf( " (CRC polynomial = 0x%08X)\n", FSK_CRC_POLYNOMIAL ); // CRC polynomial
}
printf( " DC free = %s\n", lr11xx_radio_gfsk_dc_free_to_str( FSK_DC_FREE ) ); // DC-free encoding mode
if( FSK_DC_FREE != LR11XX_RADIO_GFSK_DC_FREE_OFF )
{
printf( " (Whitening seed = 0x%04X)\n", FSK_WHITENING_SEED ); // Whitening seed
}
printf( "\n" );
}
// Calculate the time on air for the configured packet
uint32_t get_time_on_air_in_ms( void )
{
// Determine the time on air based on the packet type
switch( PACKET_TYPE )
{
case LR11XX_RADIO_PKT_TYPE_LORA:
{
// Calculate time on air for LoRa
return lr11xx_radio_get_lora_time_on_air_in_ms( &lora_pkt_params, &lora_mod_params );
}
case LR11XX_RADIO_PKT_TYPE_GFSK:
{
// Calculate time on air for GFSK
return lr11xx_radio_get_gfsk_time_on_air_in_ms( &gfsk_pkt_params, &gfsk_mod_params );
}
default:
{
// Return 0 if the packet type is not recognized
return 0;
}
}
}

View File

@@ -0,0 +1,212 @@
/*!
* @file lr1121_config.h
*
* @brief Common functions shared by the examples
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2022. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted (subject to the limitations in the disclaimer
* below) provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of the Semtech corporation nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY
* THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
* NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SEMTECH CORPORATION BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef LR1121_CONFIG_H
#define LR1121_CONFIG_H
#include "esp_lora_1121.h"
#define RX_CONTINUOUS 0xFFFFFF
/*!
* @brief General parameters
*/
#define PACKET_TYPE LR11XX_RADIO_PKT_TYPE_LORA //LR11XX_RADIO_PKT_TYPE_GFSK LR11XX_RADIO_PKT_TYPE_LORA
#define RF_FREQ_IN_HZ 434 * 1000 * 1000
#define TX_OUTPUT_POWER_DBM 22 //-9~22
#define PA_RAMP_TIME LR11XX_RADIO_RAMP_48_US
#define FALLBACK_MODE LR11XX_RADIO_FALLBACK_STDBY_RC
#define ENABLE_RX_BOOST_MODE true
#define PAYLOAD_LENGTH 7
/*!
* @brief Modulation parameters for LoRa packets
*/
#define LORA_SPREADING_FACTOR LR11XX_RADIO_LORA_SF7
#define LORA_BANDWIDTH LR11XX_RADIO_LORA_BW_125
#define LORA_CODING_RATE LR11XX_RADIO_LORA_CR_4_5
/*!
* @brief Packet parameters for LoRa packets
*/
#define LORA_PREAMBLE_LENGTH 8
#define LORA_PKT_LEN_MODE LR11XX_RADIO_LORA_PKT_EXPLICIT
#define LORA_IQ LR11XX_RADIO_LORA_IQ_STANDARD
#define LORA_CRC LR11XX_RADIO_LORA_CRC_OFF
#define LORA_SYNCWORD 0x12 // 0x12 Private Network, 0x34 Public Network
/*!
* @brief Modulation parameters for GFSK packets
*/
#ifndef FSK_FDEV
#define FSK_FDEV 25000U // Hz
#endif
#ifndef FSK_BITRATE
#define FSK_BITRATE 50000U // bps
#endif
#ifndef FSK_BANDWIDTH
#define FSK_BANDWIDTH LR11XX_RADIO_GFSK_BW_117300 // Make sure to follow the rule: (2 * FDEV + BITRATE) < BW
#endif
#ifndef FSK_PULSE_SHAPE
#define FSK_PULSE_SHAPE LR11XX_RADIO_GFSK_PULSE_SHAPE_OFF
#endif
/*!
* @brief Packet parameters for GFSK packets
*/
#ifndef FSK_PREAMBLE_LENGTH
#define FSK_PREAMBLE_LENGTH 32 // bits
#endif
#ifndef FSK_PREAMBLE_DETECTOR
#define FSK_PREAMBLE_DETECTOR LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_16BITS
#endif
#ifndef FSK_SYNCWORD_LENGTH
#define FSK_SYNCWORD_LENGTH 40 // bits
#endif
#ifndef FSK_ADDRESS_FILTERING
#define FSK_ADDRESS_FILTERING LR11XX_RADIO_GFSK_ADDRESS_FILTERING_DISABLE
#endif
#ifndef FSK_HEADER_TYPE
#define FSK_HEADER_TYPE LR11XX_RADIO_GFSK_PKT_VAR_LEN
#endif
#ifndef FSK_CRC_TYPE
#define FSK_CRC_TYPE LR11XX_RADIO_GFSK_CRC_1_BYTE_INV
#endif
#ifndef FSK_DC_FREE
#define FSK_DC_FREE LR11XX_RADIO_GFSK_DC_FREE_OFF
#endif
/*!
* @brief GFSK sync word
*/
static const uint8_t gfsk_sync_word[8] = { 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF };
/*!
* @brief GFSK whitening seed
*/
#ifndef FSK_WHITENING_SEED
#define FSK_WHITENING_SEED 0x0123
#endif
/*!
* @brief GFSK CRC seed
*/
#ifndef FSK_CRC_SEED
#define FSK_CRC_SEED 0x01234567
#endif
/*!
* @brief GFSK CRC polynomial
*/
#ifndef FSK_CRC_POLYNOMIAL
#define FSK_CRC_POLYNOMIAL 0x01234567
#endif
/*!
* @brief GFSK address filtering - node address
*/
#ifndef FSK_NODE_ADDRESS
#define FSK_NODE_ADDRESS 0x05
#endif
/*!
* @brief GFSK address filtering - broadcast address
*/
#ifndef FSK_BROADCAST_ADDRESS
#define FSK_BROADCAST_ADDRESS 0xAB
#endif
/*!
* @brief Sigfox radio configuration
*/
#ifndef SIGFOX_RC
#define SIGFOX_RC 1
#endif
#if( SIGFOX_RC == 1 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 868130000
#define BPSK_BITRATE_IN_BPS 100
#define SIGFOX_TX_OUTPUT_POWER_DBM 14
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_UP_TIME_100_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#elif( SIGFOX_RC == 2 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 902200000
#define BPSK_BITRATE_IN_BPS 600
#define SIGFOX_TX_OUTPUT_POWER_DBM 22
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_UP_TIME_600_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_600_BPS
#elif( SIGFOX_RC == 3 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 923200000
#define BPSK_BITRATE_IN_BPS 100
#define SIGFOX_TX_OUTPUT_POWER_DBM 14
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#elif( SIGFOX_RC == 4 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 920800000
#define BPSK_BITRATE_IN_BPS 600
#define SIGFOX_TX_OUTPUT_POWER_DBM 22
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_UP_TIME_600_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_600_BPS
#elif( SIGFOX_RC == 5 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 923300000
#define BPSK_BITRATE_IN_BPS 100
#define SIGFOX_TX_OUTPUT_POWER_DBM 12
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#elif( SIGFOX_RC == 6 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 865200000
#define BPSK_BITRATE_IN_BPS 100
#define SIGFOX_TX_OUTPUT_POWER_DBM 14
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#elif( SIGFOX_RC == 7 )
#define SIGFOX_UPLINK_RF_FREQ_IN_HZ 868800000
#define BPSK_BITRATE_IN_BPS 100
#define SIGFOX_TX_OUTPUT_POWER_DBM 14
#define RAMP_UP_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#define RAMP_DOWN_DELAY SIGFOX_DBPSK_RAMP_DOWN_TIME_100_BPS
#else
#error "Select a valid Radio Configuration"
#endif
extern lr1121_t lr1121;
void lora_system_init( const void* context );
void lora_radio_init( const void* context );
void lora_radio_dbpsk_init( const void* context, const uint8_t payload_len );
uint32_t get_time_on_air_in_ms( void );
#endif

View File

@@ -0,0 +1,330 @@
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/i2c_master.h"
#include "esp_log.h"
#include "esp_lora_1121.h"
#include "lr1121_config.h"
static const char *TAG = "lr1121_example";
#define TEST_SPI_MOSI (GPIO_NUM_45)
#define TEST_SPI_MISO (GPIO_NUM_46)
#define TEST_SPI_CLK (GPIO_NUM_40)
#define TEST_SPI_CS (GPIO_NUM_42)
#define TEST_SPI_INT (GPIO_NUM_38)
#define TEST_SPI_RESET (GPIO_NUM_39)
#define TEST_SPI_BUSY (GPIO_NUM_41)
#define TEST_SPI_NUM (SPI3_HOST)
#define TEST_SPI_CLK_SPEED_HZ 8 * 1000 * 1000
#define RX_TIMEOUT_VALUE 600
#define PING_PONG_PREFIX_SIZE 5
#define SYNC_PACKET_THRESHOLD 64
#define ITERATION_INDEX ( PING_PONG_PREFIX_SIZE + 1 )
#define DELAY_BEFORE_TX_MS 20
#define DELAY_PING_PONG_PACE_MS 200
#define IRQ_MASK \
( LR11XX_SYSTEM_IRQ_TX_DONE | LR11XX_SYSTEM_IRQ_RX_DONE | LR11XX_SYSTEM_IRQ_TIMEOUT | \
LR11XX_SYSTEM_IRQ_HEADER_ERROR | LR11XX_SYSTEM_IRQ_CRC_ERROR | LR11XX_SYSTEM_IRQ_FSK_LEN_ERROR )
#define HAL_DBG_TRACE_ARRAY( msg, array, len ) \
do \
{ \
printf( "%s - (%lu bytes):\n", msg, ( uint32_t ) len ); \
for( uint32_t i = 0; i < ( uint32_t ) len; i++ ) \
{ \
if( ( ( i % 16 ) == 0 ) && ( i > 0 ) ) \
{ \
printf( "\n" ); \
} \
printf( " %02X", array[i] ); \
} \
printf( "\n" ); \
} while( 0 );
static spi_device_handle_t spi_handle = NULL;// SPI Handle
static uint8_t buffer_tx[PAYLOAD_LENGTH];
static bool is_master = true;
static const uint8_t ping_msg[PING_PONG_PREFIX_SIZE] = "PING";
static const uint8_t pong_msg[PING_PONG_PREFIX_SIZE] = "PONG";
static uint8_t iteration = 0;
static uint16_t packets_to_sync = 0;
bool irq_flag;
/**
* @brief Handle reception failure for ping-pong example
*/
static void ping_pong_reception_failure_handling( void );
void lora_irq_process( const void* context, lr11xx_system_irq_mask_t irq_filter_mask );
static void IRAM_ATTR isr(void* arg) {
irq_flag = true; // Set the interrupt flag
}
static esp_err_t spi_bus_init() {
spi_bus_config_t buscfg = {
.mosi_io_num = TEST_SPI_MOSI,
.miso_io_num = TEST_SPI_MISO,
.sclk_io_num = TEST_SPI_CLK,
.quadwp_io_num = -1,
.quadhd_io_num = -1,
.max_transfer_sz = 64,
};
spi_device_interface_config_t devcfg = {
.clock_speed_hz = TEST_SPI_CLK_SPEED_HZ, // 8 MHz
.mode = 0, // SPI mode 0: CPOL=0, CPHA=0
.spics_io_num = -1,
.queue_size = 1,
};
// Initialize SPI bus
ESP_ERROR_CHECK(spi_bus_initialize(TEST_SPI_NUM, &buscfg, SPI_DMA_CH_AUTO));
ESP_ERROR_CHECK(spi_bus_add_device(TEST_SPI_NUM, &devcfg, &spi_handle));
return ESP_OK;
}
static void lr1121_test_task(void *arg) {
lora_init_io_context(&lr1121,TEST_SPI_CS,TEST_SPI_RESET,TEST_SPI_BUSY,TEST_SPI_INT); // Initialize the I/O context for the LR1121
lora_init_io(&lr1121); // Initialize the I/O for the LR1121
lora_spi_init(&lr1121, spi_handle); // Initialize the SPI interface for the LR1121
printf( "===== LR11xx Ping-Pong example =====\n\n" );
printf( "LR11XX driver version: %s\n", lr11xx_driver_version_get_version_string( ) );
// Initialize the system
lora_system_init(&lr1121);
// Print the version number for verification
lora_print_version(&lr1121);
// Initialize the LoRa radio
lora_radio_init(&lr1121);
lora_init_irq(&lr1121, isr); // Initialize the interrupt service routine
ASSERT_LR11XX_RC( lr11xx_system_set_dio_irq_params( &lr1121, IRQ_MASK, 0 ) );
ASSERT_LR11XX_RC( lr11xx_system_clear_irq_status( &lr1121, LR11XX_SYSTEM_IRQ_ALL_MASK ) );
/* Intializes random number generator */
srand( 10 );
memcpy( buffer_tx, ping_msg, PING_PONG_PREFIX_SIZE );
buffer_tx[PING_PONG_PREFIX_SIZE] = ( uint8_t ) 0;
buffer_tx[ITERATION_INDEX] = ( uint8_t ) ( iteration );
for( int i = PING_PONG_PREFIX_SIZE + 1 + 1; i < PAYLOAD_LENGTH; i++ )
{
buffer_tx[i] = i;
}
ASSERT_LR11XX_RC( lr11xx_regmem_write_buffer8( &lr1121, buffer_tx, PAYLOAD_LENGTH ) );
ASSERT_LR11XX_RC( lr11xx_radio_set_tx( &lr1121, 0 ) );
while (1)
{
if(irq_flag)
lora_irq_process( &lr1121, IRQ_MASK );
vTaskDelay(1 / portTICK_PERIOD_MS); // Short delay to control the loop speed
}
}
void on_tx_done( void )
{
printf( "Sent message %s, iteration %d\n", buffer_tx, iteration );
vTaskDelay( DELAY_PING_PONG_PACE_MS / portTICK_PERIOD_MS);
ASSERT_LR11XX_RC( lr11xx_radio_set_rx(
&lr1121,
get_time_on_air_in_ms( ) + RX_TIMEOUT_VALUE + rand( ) % 500 ) ); // Random delay to avoid
// unwanted synchronization
}
void lora_receive( const void* context, uint8_t* buffer, uint8_t buffer_length, uint8_t* size )
{
lr11xx_radio_rx_buffer_status_t rx_buffer_status;
lr11xx_radio_pkt_status_lora_t pkt_status_lora;
lr11xx_radio_pkt_status_gfsk_t pkt_status_gfsk;
lr11xx_radio_get_rx_buffer_status( context, &rx_buffer_status );
*size = rx_buffer_status.pld_len_in_bytes;
if( *size > buffer_length )
{
printf( "Received payload (size: %d) is bigger than the buffer (size: %d)!\n", *size,
buffer_length );
return;
}
lr11xx_regmem_read_buffer8( context, buffer, rx_buffer_status.buffer_start_pointer,
rx_buffer_status.pld_len_in_bytes );
HAL_DBG_TRACE_ARRAY( "Packet content", buffer, *size );
printf( "Packet status:\n" );
if( PACKET_TYPE == LR11XX_RADIO_PKT_TYPE_LORA )
{
lr11xx_radio_get_lora_pkt_status( context, &pkt_status_lora );
printf( " - RSSI packet = %i dBm\n", pkt_status_lora.rssi_pkt_in_dbm );
printf( " - Signal RSSI packet = %i dBm\n", pkt_status_lora.signal_rssi_pkt_in_dbm );
printf( " - SNR packet = %i dB\n", pkt_status_lora.snr_pkt_in_db );
}
else if( PACKET_TYPE == LR11XX_RADIO_PKT_TYPE_GFSK )
{
lr11xx_radio_get_gfsk_pkt_status( context, &pkt_status_gfsk );
printf( " - RSSI average = %i dBm\n", pkt_status_gfsk.rssi_avg_in_dbm );
printf( " - RSSI sync = %i dBm\n", pkt_status_gfsk.rssi_sync_in_dbm );
}
}
void on_rx_done( void )
{
uint8_t buffer_rx[PAYLOAD_LENGTH];
uint8_t size;
packets_to_sync = 0;
lora_receive( &lr1121, buffer_rx, PAYLOAD_LENGTH, &size );
iteration = buffer_rx[ITERATION_INDEX];
iteration++;
printf( "Received message %s, iteration %d\n", buffer_rx, iteration );
if( is_master == true )
{
if( memcmp( buffer_rx, ping_msg, PING_PONG_PREFIX_SIZE ) == 0 )
{
is_master = false;
memcpy( buffer_tx, pong_msg, PING_PONG_PREFIX_SIZE );
}
else if( memcmp( buffer_rx, pong_msg, PING_PONG_PREFIX_SIZE ) != 0 )
{
printf( "Unexpected message\n" );
}
}
else
{
if( memcmp( buffer_rx, ping_msg, PING_PONG_PREFIX_SIZE ) != 0 )
{
printf( "Unexpected message\n" );
is_master = true;
memcpy( buffer_tx, ping_msg, PING_PONG_PREFIX_SIZE );
}
}
vTaskDelay( (DELAY_PING_PONG_PACE_MS + DELAY_BEFORE_TX_MS) / portTICK_PERIOD_MS);
buffer_tx[ITERATION_INDEX] = iteration;
ASSERT_LR11XX_RC( lr11xx_regmem_write_buffer8( &lr1121, buffer_tx, PAYLOAD_LENGTH ) );
ASSERT_LR11XX_RC( lr11xx_radio_set_tx( &lr1121, 0 ) );
}
void on_rx_timeout( void )
{
packets_to_sync++;
if( packets_to_sync > SYNC_PACKET_THRESHOLD )
{
printf(
"It looks like synchronisation is still not done, consider resetting one of the board\n" );
}
ping_pong_reception_failure_handling( );
}
void on_rx_crc_error( void )
{
ping_pong_reception_failure_handling( );
}
void on_fsk_len_error( void )
{
ping_pong_reception_failure_handling( );
}
static void ping_pong_reception_failure_handling( void )
{
is_master = true;
iteration = 0;
memcpy( buffer_tx, ping_msg, PING_PONG_PREFIX_SIZE );
buffer_tx[ITERATION_INDEX] = iteration;
ASSERT_LR11XX_RC( lr11xx_regmem_write_buffer8( &lr1121, buffer_tx, PAYLOAD_LENGTH ) );
ASSERT_LR11XX_RC( lr11xx_radio_set_tx( &lr1121, 0 ) );
}
void lora_irq_process( const void* context, lr11xx_system_irq_mask_t irq_filter_mask )
{
irq_flag = false;
lr11xx_system_irq_mask_t irq_regs;
lr11xx_system_get_and_clear_irq_status( context, &irq_regs );
printf( "Interrupt flags = 0x%08lX\n", irq_regs );
irq_regs &= irq_filter_mask;
printf( "Interrupt flags (after filtering) = 0x%08lX\n", irq_regs );
if( ( irq_regs & LR11XX_SYSTEM_IRQ_TX_DONE ) == LR11XX_SYSTEM_IRQ_TX_DONE )
{
printf( "Tx done\n" );
on_tx_done( );
}
if( ( irq_regs & LR11XX_SYSTEM_IRQ_HEADER_ERROR ) == LR11XX_SYSTEM_IRQ_HEADER_ERROR )
{
printf( "Header error\n" );
}
if( ( irq_regs & LR11XX_SYSTEM_IRQ_RX_DONE ) == LR11XX_SYSTEM_IRQ_RX_DONE )
{
if( ( irq_regs & LR11XX_SYSTEM_IRQ_CRC_ERROR ) == LR11XX_SYSTEM_IRQ_CRC_ERROR )
{
printf( "CRC error\n" );
on_rx_crc_error( );
}
else if( ( irq_regs & LR11XX_SYSTEM_IRQ_FSK_LEN_ERROR ) == LR11XX_SYSTEM_IRQ_FSK_LEN_ERROR )
{
printf( "FSK length error\n" );
on_fsk_len_error( );
}
else
{
printf( "Rx done\n" );
on_rx_done( );
}
}
if( ( irq_regs & LR11XX_SYSTEM_IRQ_TIMEOUT ) == LR11XX_SYSTEM_IRQ_TIMEOUT )
{
printf( "Rx timeout\n" );
on_rx_timeout( );
}
printf( "\n" );
}
void app_main(void)
{
ESP_LOGI(TAG, "Initializing SPI...");
esp_err_t ret = spi_bus_init();
if (ret != ESP_OK) {
ESP_LOGE(TAG, "Failed to initialize SPI (error: %d)", ret);
return;
}
xTaskCreate(lr1121_test_task, "lr1121_test_task", 4096, NULL, 5, NULL);
}