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,5 @@
idf_component_register(
SRCS "common.c"
INCLUDE_DIRS "include"
PRIV_REQUIRES spi_flash
)

17
components/common/Kconfig Normal file
View File

@@ -0,0 +1,17 @@
menu "LoRa common options"
choice LORA_ROLE
prompt "Device role"
default LORA_ROLE_TX
help
Виберіть роль прошивки за замовчуванням. Для кожної збірки можна
вказати власні sdkconfig.defaults з потрібним вибором.
config LORA_ROLE_TX
bool "Transmitter"
config LORA_ROLE_RX
bool "Receiver"
endchoice
endmenu

View File

@@ -0,0 +1,44 @@
#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_system.h"
#include "esp_log.h"
#define TAG "common"
void common_print_boot_info(void)
{
esp_chip_info_t chip_info;
uint32_t flash_size = 0;
esp_chip_info(&chip_info);
ESP_LOGI(TAG, "Chip: %s, cores: %d, features: %s%s%s%s",
CONFIG_IDF_TARGET,
chip_info.cores,
(chip_info.features & CHIP_FEATURE_WIFI_BGN) ? "WiFi/" : "",
(chip_info.features & CHIP_FEATURE_BT) ? "BT" : "",
(chip_info.features & CHIP_FEATURE_BLE) ? "BLE" : "",
(chip_info.features & CHIP_FEATURE_IEEE802154) ? ", 802.15.4" : "");
unsigned major_rev = chip_info.revision / 100;
unsigned minor_rev = chip_info.revision % 100;
ESP_LOGI(TAG, "Revision: v%u.%u", major_rev, minor_rev);
if (esp_flash_get_size(NULL, &flash_size) != ESP_OK) {
ESP_LOGW(TAG, "Cannot read flash size");
} else {
ESP_LOGI(TAG, "Flash: %" PRIu32 " MB %s",
flash_size / (uint32_t)(1024 * 1024),
(chip_info.features & CHIP_FEATURE_EMB_FLASH) ? "embedded" : "external");
}
ESP_LOGI(TAG, "Min free heap: %" PRIu32 " bytes", esp_get_minimum_free_heap_size());
for (int i = 3; i > 0; i--) {
ESP_LOGI(TAG, "Start in %d...", i);
vTaskDelay(pdMS_TO_TICKS(500));
}
}

View File

@@ -0,0 +1,5 @@
#pragma once
#include "esp_chip_info.h"
void common_print_boot_info(void);

View File

@@ -0,0 +1,20 @@
file(GLOB_RECURSE SRCS src/*.c
src/lr1121_printers/*.c
src/lr1121_modem/*.c
src/lr1121_common/*.c
src/lr11xx_driver/*.c
)
set(INCLUDE_DIRS
include
include/lr1121_printers
include/lr1121_modem
include/lr1121_common
include/lr11xx_driver
)
idf_component_register(
SRCS ${SRCS}
INCLUDE_DIRS ${INCLUDE_DIRS}
REQUIRES esp_timer esp_driver_i2c esp_driver_spi esp_driver_gpio
)

202
components/esp_lora_1121/LICENSE Executable file
View File

@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,117 @@
# LoRa LR1121
[![Component Registry](https://components.espressif.com/components/waveshare/esp_lora_1121/badge.svg)](https://components.espressif.com/components/waveshare/esp_lora_1121)
LR1121 transceiver driver, LR1121 is a multi-band, ultra-low-power RF transceiver.
| LoRa controller | Communication interface | Component name | Link to datasheet |
| :--------------: | :---------------------: | :------------: | :---------------: |
| LR1121 | SPI | esp_lora_1121 | [WIKI](https://files.waveshare.com/wiki/Core1121/LR1121_H2_DS_v2_0.pdf) |
## Add to project
Packages from this repository are uploaded to [Espressif's component service](https://components.espressif.com/).
You can add them to your project via `idf.py add-dependancy`, e.g.
```
idf.py add-dependency waveshare/esp_lora_1121==1.0.0
```
Alternatively, you can create `idf_component.yml`. More is in [Espressif's documentation](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/tools/idf-component-manager.html).
## Example use
### Initialization of the SPI bus
```c
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;
}
```
### LoRa initialization and configuration
```c
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 ) );
```
### Set the data to be sent and send it.
```c
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 ) );
```
### Read the current time and check if the alarm has been triggered
```c
while (1)
{
if(irq_flag)
lora_irq_process( &lr1121, IRQ_MASK );
vTaskDelay(1 / portTICK_PERIOD_MS); // Short delay to control the loop speed
}
```
### Running results
```shell
Interrupt flags = 0x00000004
Interrupt flags (after filtering) = 0x00000004
Tx done
Sent message PING, iteration 50
Interrupt flags = 0x00000038
Interrupt flags (after filtering) = 0x00000008
Rx done
Packet content - (7 bytes):
50 4F 4E 47 00 00 33
Packet status:
- RSSI packet = -6 dBm
- Signal RSSI packet = -5 dBm
- SNR packet = 15 dB
Received message PONG, iteration 52
Interrupt flags = 0x00000004
Interrupt flags (after filtering) = 0x00000004
Tx done
Sent message PING, iteration 52
------------
```

View File

@@ -0,0 +1,6 @@
dependencies:
idf:
version: '>=5.3.0'
description: Board Support Package for LoRa 1121
version: 1.0.0

View File

@@ -0,0 +1,80 @@
#ifndef WAVESHARE_LORA_SPI_H
#define WAVESHARE_LORA_SPI_H
#include <string.h>
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_timer.h"
#include "esp_log.h"
#include "lr11xx_bootloader.h"
#include "lr11xx_hal.h"
#include "lr11xx_system.h"
#include "lr11xx_radio.h"
#include "lr11xx_regmem.h"
#include "lr11xx_lr_fhss.h"
#include "lr11xx_driver_version.h"
#include "lr1121_modem_helper.h"
#include "lr1121_modem_system_types.h"
#include "lr1121_modem_common.h"
#include "lr1121_modem_modem.h"
#include "lr1121_modem_hal.h"
#include "lr1121_modem_system.h"
#include "lr1121_modem_bsp.h"
#include "lr1121_modem_radio.h"
#include "lr11xx_bootloader_types_str.h"
#include "lr11xx_crypto_engine_types_str.h"
#include "lr11xx_lr_fhss_types_str.h"
#include "lr11xx_radio_types_str.h"
#include "lr11xx_rttof_types_str.h"
#include "lr11xx_system_types_str.h"
#include "lr11xx_types_str.h"
#include "lr11xx_printf_info.h"
#include "lr1121_modem_printf_info.h"
#include "lr1121_common.h"
// #define USE_LR11XX_CRC_OVER_SPI
typedef struct lr1121_s
{
int cs;
int reset;
int busy;
int irq;
int led;
spi_device_handle_t spi;
} lr1121_t;
/**
* @brief Initializes the radio I/Os pins context
*
* @param [in] context Radio abstraction
*/
void lora_init_io_context(const void *context,int cs,int reset,int busy,int irq);
/**
* @brief Initializes the radio I/Os pins interface
*
* @param [in] context Radio abstraction
*/
void lora_init_io( const void* context );
void lora_init_irq(const void *context, gpio_isr_t handler);
void lora_spi_init(const void* context, spi_device_handle_t spi);
void lora_spi_write_bytes(const void* context,const uint8_t *wirte,const uint16_t wirte_length);
void lora_spi_read_bytes(const void* context, uint8_t *read,const uint16_t read_length);
/**
* @brief Flush the modem event queue
*
* @param [in] context Radio abstraction
*
* @returns Modem-E response code
*/
lr1121_modem_response_code_t lr1121_modem_board_event_flush( const void* context );
#endif

View File

@@ -0,0 +1,162 @@
#ifndef LR1121_COMMON_H
#define LR1121_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
#include "lr11xx_driver/lr11xx_radio_types.h"
#include "lr11xx_driver/lr11xx_radio.h"
#include "lr11xx_driver/lr11xx_system_types.h"
#include "lr11xx_driver/lr11xx_regmem.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
#define SMTC_SHIELD_LR11XX_SUBGHZ_FREQ_MIN 150000000
#define SMTC_SHIELD_LR11XX_SUBGHZ_FREQ_MAX 960000000
#define SMTC_SHIELD_LR112X_2GHZ_FREQ_MIN 2000000000
#define SMTC_SHIELD_LR112X_2GHZ_FREQ_MAX 2100000000
#define SMTC_SHIELD_LR112X_2_4GHZ_FREQ_MIN 2400000000
#define SMTC_SHIELD_LR112X_2_4GHZ_FREQ_MAX 2500000000
#define SMTC_SHIELD_LR11XX_MIN_PWR -9
#define SMTC_SHIELD_LR11XX_MAX_PWR 22
#define SMTC_SHIELD_LR112X_MIN_PWR_HF -18
#define SMTC_SHIELD_LR112X_MAX_PWR_HF 13
/*!
* @brief Stringify constants
*/
#define xstr( a ) str( a )
#define str( a ) #a
/*!
* @brief Helper macro that returned a human-friendly message if a command does not return LR11XX_STATUS_OK
*
* @remark The macro is implemented to be used with functions returning a @ref lr11xx_status_t
*
* @param[in] rc Return code
*/
#define ASSERT_LR11XX_RC( rc ) \
{ \
const lr11xx_status_t status = rc; \
if( status != LR11XX_STATUS_OK ) \
{ \
if( status == LR11XX_STATUS_ERROR ) \
{ \
printf( "In %s - %s (line %d): %s\n", __FILE__, __func__, __LINE__, \
xstr( LR11XX_STATUS_ERROR ) ); \
} \
} \
}
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief Power amplifier and output power configurations structure definition
*/
typedef struct smtc_shield_lr11xx_pa_pwr_cfg_s
{
int8_t power;
lr11xx_radio_pa_cfg_t pa_config;
} smtc_shield_lr11xx_pa_pwr_cfg_t;
/**
* @brief External 32MHz oscillator configuration structure definition
*/
typedef struct smtc_shield_lr11xx_xosc_cfg_s
{
bool has_tcxo;
lr11xx_system_tcxo_supply_voltage_t supply;
uint32_t startup_time_in_tick;
} smtc_shield_lr11xx_xosc_cfg_t;
/**
* @brief 32kHz clock configuration structure definition
*/
typedef struct smtc_shield_lr11xx_lfclk_cfg_s
{
lr11xx_system_lfclk_cfg_t lf_clk_cfg;
bool wait_32k_ready;
} smtc_shield_lr11xx_lfclk_cfg_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/**
* @see smtc_shield_lr11xx_get_rssi_calibration_table
*/
const lr11xx_radio_rssi_calibration_table_t* smtc_shield_lr11xx_get_rssi_calibration_table(
const uint32_t rf_freq_in_hz );
/**
* @see smtc_shield_lr11xx_get_rf_switch_cfg
*/
const lr11xx_system_rfswitch_cfg_t* smtc_shield_lr11xx_common_get_rf_switch_cfg( void );
/**
* @see smtc_shield_lr11xx_get_reg_mode
*/
lr11xx_system_reg_mode_t smtc_shield_lr11xx_common_get_reg_mode( void );
/**
* @see smtc_shield_lr11xx_get_lfclk_cfg
*/
const smtc_shield_lr11xx_lfclk_cfg_t* smtc_shield_lr11xx_common_get_lfclk_cfg( void );
/**
* @see smtc_shield_lr11xx_get_pa_pwr_cfg
*/
const smtc_shield_lr11xx_pa_pwr_cfg_t* smtc_shield_lr1121mb1gis_get_pa_pwr_cfg( const uint32_t rf_freq_in_hz,
int8_t expected_output_pwr_in_dbm );
const uint8_t smtc_shield_lr11xx_common_compute_lora_ldro( const lr11xx_radio_lora_sf_t sf, const lr11xx_radio_lora_bw_t bw );
/*!
* \brief Given the length of a BPSK frame, in bits, calculate the space necessary to hold the frame after differential
* encoding, in bits.
*
* \param [in] bpsk_pld_len_in_bits Length of a BPSK frame, in bits
* \returns Space required for DBPSK frame, after addition of start/stop bits [bits]
*/
static inline int smtc_dbpsk_get_pld_len_in_bits( int bpsk_pld_len_in_bits )
{
// Hold the last bit one extra bit-time
return bpsk_pld_len_in_bits + 2;
}
/*!
* \brief Given the length of a BPSK frame, in bits, calculate the space necessary to hold the frame after differential
* encoding, in bytes.
*
* \param [in] bpsk_pld_len_in_bits Length of a BPSK frame, in bits
* \returns Space required for DBPSK frame, after addition of start/stop bits [bytes]
*/
static inline int smtc_dbpsk_get_pld_len_in_bytes( int bpsk_pld_len_in_bits )
{
return ( smtc_dbpsk_get_pld_len_in_bits( bpsk_pld_len_in_bits ) + 7 ) >> 3;
}
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,294 @@
/*!
* @file lr1121_modem_bsp.h
*
* @brief BSP driver for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_BSP_H
#define LR1121_MODEM_BSP_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr1121_modem_common.h"
#include "lr1121_modem_bsp_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief This command gets the board-specific correction offset for transmission power to be used (signed integer in
* dB).
*
* @param [in] context Chip implementation context
* @param [out] tx_power_offset Tx power offset correction in dBm
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_tx_power_offset( const void* context, int8_t* tx_power_offset );
/*!
* @brief This command sets the board-specific correction offset for transmission power to be used
*
* The offset depends on the board design and antenna matching and is expressed in dB (signed integer).
* The default value is -2dB.
*
* @param [in] context Chip implementation context
* @param [in] tx_power_offset Tx power offset correction in dBm
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_tx_power_offset( const void* context, const int8_t tx_power_offset );
/*!
* @brief Configure the Output RF per power
*
* This command overload the output RF configuration for the given @p expected_power.
*
* @param [in] context Chip implementation context
* @param [in] output_power_configs Array of Tx output power configurations to set. It is up to the user to ensure it
* contains at least @p n_output_power_configs
* @param [in] n_output_power_configs Number of output power configuration to set. Valid values in range [1:41]
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_output_power_config(
const void* context, const lr1121_modem_output_power_config_t* output_power_configs,
uint8_t n_output_power_configs );
/*!
* @brief This command gets the 41 Tx output power configurations for all Tx powers
*
* In case an @p expected_power is not available due to hardware limitation, all corresponding values in @p
* lr1121_modem_output_power_config_t wil be set to 0x7F.
*
* @param [in] context Chip implementation context
* @param [out] output_power_config Tx output power configuration block list, \see
* lr1121_modem_output_power_config_list_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_output_power_config(
const void* context, lr1121_modem_output_power_config_list_t output_power_config );
/*!
* @brief Configure RF output configuration
*
* @param [in] context Chip implementation context
* @param [in] output RF output @ref lr1121_modem_bsp_radio_pa_selection_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_rf_output( const void* context,
const lr1121_modem_bsp_radio_pa_selection_t output );
/*!
* @brief Get RF output configuration
*
* @param [in] context Chip implementation context
* @param [out] output RF output @ref lr1121_modem_bsp_radio_pa_selection_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_rf_output( const void* context,
const lr1121_modem_bsp_radio_pa_selection_t* output );
/*!
* @brief Get the Crystal error
*
* @param [in] context Chip implementation context
* @param [out] crystal_error_ppm Crystal error in PPM
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_crystal_error( const void* context, uint32_t* crystal_error_ppm );
/*!
* @brief Set the Crystal error of the MCU to fine adjust the rx window for LoRaWAN
*
* The default value is:
* - When the Low-Frequency clock selected is @ref LR1121_MODEM_SYSTEM_LFCLK_RC : 16000 PPM
* - Otherwise: 50 PPM
*
* @param [in] context Chip implementation context
* @param [in] crystal_error_ppm Crystal error in PPM
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_crystal_error( const void* context, const uint32_t crystal_error_ppm );
/*!
* @brief Get the XOSC trimming capacitor
*
* @param [in] context Chip implementation context
* @param [out] capa_trim_a Trimming value for capacitance XTA
* @param [out] capa_trim_b Trimming value for capacitance XTB
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_xosc_capa_trim_a_b( const void* context, uint8_t* capa_trim_a,
uint8_t* capa_trim_b );
/*!
* @brief Set the XOSC trimming capacitor
*
* @p capa_trim_a and @p capa_trim_b both takes value within [0, 47]. It configures the corresponding trimming
* capacitance following \f$ C_{x,uF} = 0.47 \times capa\_trim\_x + N_x \f$ Where:
* - \f$ N_a = 11.3 \f$
* - \f$ N_b = 10.1 \f$
*
* So that \f$ C_{a,uF} \f$ goes from 11.3pF to 33.4pF ; and \f$ C_{b,uF} \f$ goes from 10.1pF to 32.2pF.
*
* Default value is 0x12 for both @p capa_trim_a and @p capa_trim_b which makes respectively 19.7pF and 18.5pF.
*
* Note that when the chip enters sleep mode, the capacitances XTA and XTB are respectively set to 13.6pF and 12.4pF.
* When leaving sleep mode, XTA and XTB are set to the value configured by this command (or to the default ones).
*
* @param [in] context Chip implementation context
* @param [in] capa_trim_a Trimming value for capacitance XTA
* @param [in] capa_trim_b Trimming value for capacitance XTB
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_xosc_capa_trim_a_b( const void* context, const uint8_t capa_trim_a,
const uint8_t capa_trim_b );
/**
* @brief Get the instantaneous power consumption table
*
* The instantaneous power consumption values are used to evaluate the power consumption statistics.
*
* @param [in] context Chip implementation context
* @param [out] consumption_per_power Table of instantaneous consumption
* @return Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_tx_power_consumption_ua(
const void* context, lr1121_modem_tx_power_consumption_list_t consumption_per_power );
/**
* @brief Set the instantaneous power consumption table
*
* The instantaneous power consumption values are used to evaluate the power consumption statistics.
*
* @param [in] context Chip implementation context
* @param [in] consumption_per_power Array of the instantaneous power consumption to set. Setting the field
* consumed_power_ua to 0 reset the instantaneous consumption corresponding to the given Tx RF power to 0. It is up to
* the caller to ensure this array contains at least n_consumption_per_power elements
* @param [in] n_consumption_per_power Number of elements in the array @p consumption_per_power to set. Valid values
* in range of [1:41]
* @return Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_tx_power_consumption_ua(
const void* context, const lr1121_modem_tx_power_consumption_value_t* consumption_per_power,
uint8_t n_consumption_per_power );
/**
* @brief Get LoRa Rx consumption configured
*
* The instantaneous power consumption values are used to evaluate the power consumption statistics.
*
* @param [in] context Chip implementation context
* @param [out] rx_consumption The LoRa instantaneous Rx consumption configured
* @return lr1121_modem_response_code_t
*/
lr1121_modem_response_code_t lr1121_modem_get_lora_rx_power_consumption_ua(
const void* context, lr1121_modem_rx_power_consumption_t* rx_consumption );
/**
* @brief Set the LoRa Rx power consumption configuration
*
* The instantaneous power consumption values are used to evaluate the power consumption statistics.
*
* @param [in] context Chip implementation context
* @param [in] rx_consumption The LoRa Rx consumption structure to set. Setting one field to 0 reset it to its internal
* value.
* @return lr1121_modem_response_code_t
*/
lr1121_modem_response_code_t lr1121_modem_set_lora_rx_power_consumption_ua(
const void* context, const lr1121_modem_rx_power_consumption_t* rx_consumption );
/**
* @brief Get GFSK Rx power consumption configured
*
* The instantaneous power consumption values are used to evaluate the power consumption statistics.
*
* @param [in] context Chip implementation context
* @param [out] rx_consumption The GFSK instantaneous Rx consumption configured
* @return lr1121_modem_response_code_t
*/
lr1121_modem_response_code_t lr1121_modem_get_gfsk_rx_power_consumption_ua(
const void* context, lr1121_modem_rx_power_consumption_t* rx_consumption );
/**
* @brief Set the GFSK Rx power consumption configuration
*
* The instantaneous power consumption values are used to evaluate the power consumption statistics.
*
* @param [in] context Chip implementation context
* @param [in] rx_consumption The GFSK Rx consumption structure to set. Setting one field to 0 reset it to its internal
* value.
* @return lr1121_modem_response_code_t
*/
lr1121_modem_response_code_t lr1121_modem_set_gfsk_rx_power_consumption_ua(
const void* context, const lr1121_modem_rx_power_consumption_t* rx_consumption );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_BSP_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,203 @@
/*!
* @file lr1121_modem_bsp_types.h
*
* @brief BSP driver types for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_BSP_TYPES_H
#define LR1121_MODEM_BSP_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Number of output power config blocks
*/
#define LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS ( 41 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Power Amplifier Selection values
*
* - Low-power Power Amplifier can reach up to 14dBm
* - High-power Power Amplifier can reach up to 22 dBm
*/
typedef enum
{
LR1121_MODEM_BSP_RADIO_PA_SEL_LP = 0x00, //!< Low-power Power Amplifier
LR1121_MODEM_BSP_RADIO_PA_SEL_HP = 0x01, //!< High-power Power Amplifier
LR1121_MODEM_BSP_RADIO_PA_SEL_LP_HP_LF =
0x02, //!< Automatic selection between Low-power and High-power depending on requested power
LR1121_MODEM_BSP_RADIO_PA_SEL_HF = 0x03, //!< High Frequency Power Amplifier
} lr1121_modem_bsp_radio_pa_selection_t;
/*!
* @brief Ramping time for PA
*
* This parameter is the ramping time of the PA. A high value improves spectral quality.
*/
typedef enum
{
LR1121_MODEM_RAMP_16_US = 0x00, //!< 16 us Ramp Time
LR1121_MODEM_RAMP_32_US = 0x01, //!< 32 us Ramp Time
LR1121_MODEM_RAMP_48_US = 0x02, //!< 48 us Ramp Time (Default)
LR1121_MODEM_RAMP_64_US = 0x03, //!< 64 us Ramp Time
LR1121_MODEM_RAMP_80_US = 0x04, //!< 80 us Ramp Time
LR1121_MODEM_RAMP_96_US = 0x05, //!< 96 us Ramp Time
LR1121_MODEM_RAMP_112_US = 0x06, //!< 112 us Ramp Time
LR1121_MODEM_RAMP_128_US = 0x07, //!< 128 us Ramp Time
LR1121_MODEM_RAMP_144_US = 0x08, //!< 144 us Ramp Time
LR1121_MODEM_RAMP_160_US = 0x09, //!< 160 us Ramp Time
LR1121_MODEM_RAMP_176_US = 0x0A, //!< 176 us Ramp Time
LR1121_MODEM_RAMP_192_US = 0x0B, //!< 192 us Ramp Time
LR1121_MODEM_RAMP_208_US = 0x0C, //!< 208 us Ramp Time
LR1121_MODEM_RAMP_240_US = 0x0D, //!< 240 us Ramp Time
LR1121_MODEM_RAMP_272_US = 0x0E, //!< 272 us Ramp Time
LR1121_MODEM_RAMP_304_US = 0x0F, //!< 304 us Ramp Time
} lr1121_modem_ramp_time_t;
/*!
* @brief Select power amplifier supply source
*/
typedef enum
{
LR1121_MODEM_PA_REG_SUPPLY_VREG = 0x00, //!< Power amplifier supplied by the main regulator
LR1121_MODEM_PA_REG_SUPPLY_VBAT = 0x01 //!< Power amplifier supplied by the battery
} lr1121_modem_pa_reg_supply_t;
/*!
* @brief Power Amplifier selection for RF output configuration table
*/
typedef enum
{
LR1121_MODEM_OUTPUT_POWER_CONFIGURATION_PA_SEL_LP = 0x00, //!< Low-power Power Amplifier
LR1121_MODEM_OUTPUT_POWER_CONFIGURATION_PA_SEL_HP = 0x01, //!< High-power Power Amplifier
LR1121_MODEM_OUTPUT_POWER_CONFIGURATION_PA_SEL_HF = 0x02, //!< High Frequency Power Amplifier
} lr1121_modem_output_power_configuration_pa_sel_t;
/*!
* @brief Output Power Config structure
*
* A power configuration for an @p expected_power can be reset to its internal configuration by setting one of the other
* structure field to value 0x7F.
*
* @p pa_duty_cycle controls the duty cycle of Power Amplifier according to:
* \f$ dutycycle = 0.2 + 0.04 \times pa\_duty\_cycle \f$
* It can be used to adapt the TX multi-band operation using a single-matching network.
*
* The allowed duty cycle values for LPA are from 0.2 to 0.48 (by step of 0.04). Therefore possible values for
* pa_duty_cycle go from 0 to 7.
*
* The allowed duty cycle values for HPA go from 0.2 to 0.36 (by step of 0.04). Therefore in this case, the possible
* values for pa_duty_cycle go from 0 to 4.
*
* @p pa_hp_sel controls the number of slices for HPA according to: \f$ \#slices = pa\_hp\_sel + 1 \f$
*/
typedef struct
{
uint8_t expected_power; //!< Expected power in dBm
uint8_t configured_power; //!< Configured power in dBm
lr1121_modem_pa_reg_supply_t pa_supply; //!< Power Amplifier regulator supply source
uint8_t pa_duty_cycle; //!< Power Amplifier duty cycle (Default 0x04)
lr1121_modem_output_power_configuration_pa_sel_t pa_sel; //!< Power Amplifier selection
uint8_t pa_hp_sel; //!< Number of slices for HPA (Default 0x07)
lr1121_modem_ramp_time_t pa_ramp_time; //!< Power amplifier ramp time
} lr1121_modem_output_power_config_t;
/*!
* @brief Output power config type
*/
typedef lr1121_modem_output_power_config_t
lr1121_modem_output_power_config_list_t[LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS];
/**
* @brief Tx power consumption mapping structure
*/
typedef struct
{
int8_t tx_power_dbm; //!< Tx RF output power
uint32_t consumed_power_ua; //!< Corresponding instantaneous power consumption (uA)
} lr1121_modem_tx_power_consumption_value_t;
/**
* @brief Power consumption table
*/
typedef lr1121_modem_tx_power_consumption_value_t
lr1121_modem_tx_power_consumption_list_t[LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS];
/**
* @brief Rx power consumption structure
*
* The Rx power consumption depends on the Rx boosted configuration.
*
* @see lr1121_modem_radio_cfg_rx_boosted
*/
typedef struct
{
uint32_t consumption_rx_boosted_off_ua; //!< Instantaneous consumption without Rx boosted disabled (uA)
uint32_t consumption_rx_boosted_on_ua; //!< Instantaneous consumption without Rx boosted enable (uA)
} lr1121_modem_rx_power_consumption_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_BSP_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,107 @@
/*!
* @file lr1121_modem_common.h
*
* @brief modem driver common definition for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_COMMON_H
#define LR1121_MODEM_COMMON_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Command group identifier
*/
typedef enum
{
LR1121_MODEM_GROUP_ID_BSP = 0x0600, //!< Group ID for BSP commands
LR1121_MODEM_GROUP_ID_MODEM = 0x0601, //!< Group ID for modem commands
LR1121_MODEM_GROUP_ID_LORAWAN = 0x0602, //!< Group ID for LoRaWAN commands
LR1121_MODEM_GROUP_ID_RELAY = 0x0603, //!< Group ID for relay commands
} lr1121_modem_api_group_id_t;
/*!
* @brief Command return code (RC)
*/
typedef enum
{
LR1121_MODEM_RESPONSE_CODE_OK = 0x00, //!< Driver command executed successfully
LR1121_MODEM_RESPONSE_CODE_UNKOWN = 0x01, //!< Command code unknown
LR1121_MODEM_RESPONSE_CODE_NOT_IMPLEMENTED = 0x02, //!< Command not implemented
LR1121_MODEM_RESPONSE_CODE_NOT_INITIALIZED = 0x03, //!< Command not initialized
LR1121_MODEM_RESPONSE_CODE_INVALID = 0x04, //!< Invalid command parameters
LR1121_MODEM_RESPONSE_CODE_BUSY = 0x05, //!< Command cannot be executed now
LR1121_MODEM_RESPONSE_CODE_FAIL = 0x06, //!< Command execution failed
LR1121_MODEM_RESPONSE_CODE_BAD_CRC = 0x08, //!< CRC check failed
LR1121_MODEM_RESPONSE_CODE_BAD_SIZE = 0x0A, //!< Size check failed
LR1121_MODEM_RESPONSE_CODE_FRAME_ERROR = 0x0F, //!< SPI command checksum failed or CRC failed
LR1121_MODEM_RESPONSE_CODE_NO_TIME = 0x10, //!< Modem time is not synchronized
LR1121_MODEM_RESPONSE_CODE_NO_EVENT = 0x12, //!< No Event
} lr1121_modem_response_code_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_COMMON_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,56 @@
/*!
* @file lr1121_modem_driver_version.h
*
* @brief Placeholder to keep the version of LR1121 driver.
*
* The Clear BSD License
* Copyright Semtech Corporation 2024. 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_MODEM_DRIVER_VERSION_H
#define LR1121_MODEM_DRIVER_VERSION_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Version of the driver
*/
#define LR1121_MODEM_DRIVER_VERSION "v1.0.0"
/**
* @brief Returns version string
*/
const char* lr1121_modem_driver_version_get_version_string( void );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_DRIVER_VERSION_H

View File

@@ -0,0 +1,227 @@
/*!
* @file lr1121_modem_hal.h
*
* @brief Hardware Abstraction Layer (HAL) interface for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_HAL_H
#define LR1121_MODEM_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include <stdbool.h>
#include "lr1121_modem_common.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Status reported by the HAL layer
*/
typedef enum lr1121_modem_hal_status_e
{
LR1121_MODEM_HAL_STATUS_OK = 0x00, //!< Operation terminated successfully
LR1121_MODEM_HAL_STATUS_ERROR = 0x01, //!< Operation terminated with error
LR1121_MODEM_HAL_STATUS_BAD_FRAME = 0x0F, //!< Bad frame detected in the exchange
LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT = 0xFF, //!< Timeout occured while waiting for Busy line state
} lr1121_modem_hal_status_t;
/*
* ============================================================================
* API definitions to be implemented by the user
* ============================================================================
*/
/*!
* @brief Return the computed CRC
*
* @param [in] crc_initial_value initial value of the CRC
* @param [in] buffer Buffer used to compute the CRC
* @param [out] crc CRC computed
*
* @returns CRC value
*/
inline static uint8_t lr1121_modem_compute_crc( const uint8_t crc_initial_value, const uint8_t* buffer,
uint16_t length )
{
uint8_t crc = crc_initial_value;
uint8_t extract;
uint8_t sum;
for( int i = 0; i < length; i++ )
{
extract = *buffer;
for( uint8_t j = 8; j; j-- )
{
sum = ( crc ^ extract ) & 0x01;
crc >>= 1;
if( sum )
{
crc ^= 0x65;
}
extract >>= 1;
}
buffer++;
}
return crc;
}
/*!
* Radio data transfer - write
*
* @remark Must be implemented by the upper layer
*
* @param [in] context Radio implementation parameters
* @param [in] command Pointer to the buffer to be transmitted
* @param [in] command_length Buffer size to be transmitted
* @param [in] data Pointer to the buffer to be transmitted
* @param [in] data_length Buffer size to be transmitted
*
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_write( const void* context, const uint8_t* command,
const uint16_t command_length, const uint8_t* data,
const uint16_t data_length );
/*!
* Radio data transfer - read
*
* @remark Must be implemented by the upper layer
*
* @param [in] context Radio implementation parameters
* @param [in] command Pointer to the buffer to be transmitted
* @param [in] command_length Buffer size to be transmitted
* @param [out] data Pointer to the buffer to be received
* @param [in] data_length Buffer size to be received
*
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_read( const void* context, const uint8_t* command,
const uint16_t command_length, uint8_t* data,
const uint16_t data_length );
/*!
* @brief Radio data transfer - write & read in single operation
*
* @remark Must be implemented by the upper layer
* @remark Only required by lr1121_system_get_status command
*
* @param [in] context Radio implementation parameters
* @param [in] command Pointer to the buffer to be transmitted
* @param [out] data Pointer to the buffer to be received
* @param [in] data_length Buffer size to be received
*
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_write_read( const void* context, const uint8_t* command, uint8_t* data,
const uint16_t data_length );
/*!
* @brief Direct read from the SPI bus
*
* @remark Unlike @ref lr1121_modem_hal_read, this is a simple direct SPI bus SS/read/nSS operation. While reading the
* response data, the implementation of this function must ensure that only zero bytes (NOP) are written to the SPI bus.
*
* @remark Only required by the @ref lr1121_modem_system_get_status command
*
* @param [in] context Radio implementation parameters
* @param [out] data Pointer to the buffer to be received
* @param [in] data_length Buffer size to be received
*
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_direct_read( const void* context, uint8_t* data,
const uint16_t data_length );
/*!
* Radio data transfer - write without wait the return code - this API is dedicated to the functions which reset the
* Modem-E
*
* @remark Must be implemented by the upper layer
*
* @param [in] context Radio implementation parameters
* @param [in] command Pointer to the buffer to be transmitted
* @param [in] command_length Buffer size to be transmitted
* @param [in] data Pointer to the buffer to be transmitted
* @param [in] data_length Buffer size to be transmitted
*
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_write_without_rc( const void* context, const uint8_t* command,
const uint16_t command_length, const uint8_t* data,
const uint16_t data_length );
/*!
* Reset the radio
*
* @remark Must be implemented by the upper layer
*
* @param [in] context Radio implementation parameters
*
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_reset( const void* context );
/*!
* Switch the radio in DFU mode
*
* @remark Must be implemented by the upper layer
*
* @param [in] context Radio implementation parameters
*/
void lr1121_modem_hal_enter_dfu( const void* context );
/*!
* Wake the radio up.
*
* @remark Must be implemented by the upper layer
*
* @param [in] context Radio implementation parameters
* @returns Operation status
*/
lr1121_modem_hal_status_t lr1121_modem_hal_wakeup( const void* context );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_HAL_H

View File

@@ -0,0 +1,295 @@
/*!
* @file lr1121_modem_helper.h
*
* @brief helper functions definition for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_HELPER_H
#define LR1121_MODEM_HELPER_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr1121_modem_modem_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief LR1121 Modem helper status
*/
typedef enum
{
LR1121_MODEM_HELPER_STATUS_OK = 0,
LR1121_MODEM_HELPER_STATUS_ERROR = 3,
} lr1121_modem_helper_status_t;
/*!
* @brief TX status values
*
* @see LR1121_MODEM_LORAWAN_EVENT_TX_DONE
*/
typedef enum
{
LR1121_MODEM_TX_NOT_SENT = 0x00,
LR1121_MODEM_UNCONFIRMED_TX = 0x01,
LR1121_MODEM_CONFIRMED_TX = 0x02,
} lr1121_modem_tx_done_event_t;
/*!
* @brief Link check request values
*/
typedef enum
{
LR1121_MODEM_LINK_CHECK_NOT_RECEIVED = 0x00, //!< Link check response has not been received
LR1121_MODEM_LINK_CHECK_RECEIVED = 0x01, //!< Link check response has been received
} lr1121_modem_link_check_event_t;
/*!
* @brief Time request values
*
* @see LR1121_MODEM_LORAWAN_EVENT_LORAWAN_MAC_TIME
*/
typedef enum
{
LR1121_MODEM_TIME_NOT_VALID = 0x00, //!< Time is not valid
LR1121_MODEM_TIME_VALID = 0x01, //!< Time is valid and has been synchronized
LR1121_MODEM_TIME_VALID_BUT_NOT_SYNC = 0x02, //!< Time is still valid but has not been synchronized
} lr1121_modem_mac_time_event_t;
/*!
* @brief class b ping slot info
*
* @see LR1121_MODEM_LORAWAN_EVENT_CLASS_B_PING_SLOT_INFO
*/
typedef enum
{
LR1121_MODEM_CLASS_B_PING_SLOT_INFO_NOT_ANSWERED = 0x00,
LR1121_MODEM_CLASS_B_PING_SLOT_INFO_ANSWERED = 0x01,
} lr1121_modem_class_b_ping_slot_info_t;
/*!
* @brief class b ping slot status
*
* @see LR1121_MODEM_LORAWAN_EVENT_CLASS_B_STATUS
*/
typedef enum
{
LR1121_MODEM_CLASS_B_PING_SLOT_STATUS_NOT_READY = 0x00,
LR1121_MODEM_CLASS_B_PING_SLOT_STATUS_READY = 0x01,
} lr1121_modem_class_b_ping_slot_status_t;
/*!
* @brief Event status for Wake On Radio protocol status change
*
* @see LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_DYNAMIC
*/
typedef enum
{
LR1121_MODEM_RELAY_TX_DYNAMIC_WOR_DISABLED = 0x00,
LR1121_MODEM_RELAY_TX_DYNAMIC_WOR_ENABLED = 0x01,
} lr1121_modem_relay_tx_dynamic_status_t;
/*!
* @brief Event status for relay Tx activation change
*
* @see LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_MODE
*/
typedef enum
{
LR1121_MODEM_RELAY_TX_MODE_DISABLED = 0x00,
LR1121_MODEM_RELAY_TX_MODE_ENABLED = 0x01,
LR1121_MODEM_RELAY_TX_MODE_DYNAMIC = 0x02,
LR1121_MODEM_RELAY_TX_MODE_DEVICE_CONTROLLED = 0x03,
} lr1121_modem_relay_tx_mode_status_t;
/*!
* @brief Event status for relay synchronization change
*
* @see LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_SYNC
*/
typedef enum
{
LR1121_MODEM_RELAY_TX_SYNCHRONIZATION_INIT = 0x00,
LR1121_MODEM_RELAY_TX_UNSYNCHRONIZED = 0x01,
LR1121_MODEM_RELAY_TX_SYNCHRONIZED = 0x02,
} lr1121_modem_relay_tx_sync_status_t;
/**
* @brief Event status on FUOTA done event
*
* @see LR1121_MODEM_LORAWAN_EVENT_FUOTA_DONE
*/
typedef enum
{
LR1121_MODEM_FUOTA_STATUS_TERMINATED_SUCCESSFULLY = 0x00, //!< FUOTA terminated successfully
LR1121_MODEM_FUOTA_STATUS_FAILED = 0x01, //!< FUOTA failed
LR1121_MODEM_FUOTA_STATUS_ONGOING = 0xFF, //!< FUOTA is ongoing
LR1121_MODEM_FUOTA_STATUS_NOT_STARTED = 0xFE, //!< FUOTA is not started
} lr1121_modem_fuota_status_t;
/**
* @brief Event status on test mode event
*
* @see LR1121_MODEM_LORAWAN_EVENT_TEST_MODE
*/
typedef enum
{
LR1121_MODEM_TEST_MODE_STATUS_TX_NOT_SENT = 0x00,
LR1121_MODEM_TEST_MODE_STATUS_TX_SENT = 0x01,
LR1121_MODEM_TEST_MODE_STATUS_TERMINATED_ACTION = 0x02,
} lr1121_modem_test_mode_status_t;
/**
* @brief Event status on regional duty cycle event
*
* The duty cycle status can be obtained by calling @ref lr1121_modem_get_duty_cycle_status.
*
* @see lr1121_modem_get_duty_cycle_status
*/
typedef enum
{
LR1121_MODEM_REGINAL_DUTY_CYCLE_TX_ALLOWED =
0x00, //!< Previously duty cycle constrained transmissions are now allowed
LR1121_MODEM_REGINAL_DUTY_CYCLE_TX_CONSTRAINED = 0x01, //!< Transmissions are constrained by regional duty cycle
} lr1121_modem_regional_duty_cycle_status_t;
/**
* @brief Structure holding event-related data
*/
typedef struct
{
lr1121_modem_lorawan_event_type_t event_type; //!< Type of the event
uint8_t missed_events; //!< Number of @p event_type events missed before the current one
union
{
struct
{
uint16_t count;
} reset;
struct
{
lr1121_modem_tx_done_event_t status;
} txdone;
struct
{
lr1121_modem_link_check_event_t status;
} link_check;
struct
{
lr1121_modem_mac_time_event_t status;
} mac_time;
struct
{
lr1121_modem_class_b_ping_slot_info_t status;
} ping_slot_info;
struct
{
lr1121_modem_class_b_ping_slot_status_t status;
} ping_slot_status;
struct
{
uint8_t mc_group_id;
} new_multicast_class_c_groupid;
struct
{
uint8_t mc_group_id;
} new_multicast_class_b_groupid;
struct
{
lr1121_modem_relay_tx_dynamic_status_t status;
} relay_tx_dynamic_status;
struct
{
lr1121_modem_relay_tx_mode_status_t status;
} relay_tx_mode_status;
struct
{
lr1121_modem_relay_tx_sync_status_t status;
} relay_tx_sync_status;
struct
{
lr1121_modem_fuota_status_t status;
} fuota_status;
struct
{
lr1121_modem_test_mode_status_t status;
} test_mode_status;
struct
{
lr1121_modem_regional_duty_cycle_status_t status;
} regional_duty_cycle_status;
} event_data; //!< Status data associated to the event
} lr1121_modem_event_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/**
* @brief Extract the event data contained in the event field buffer
*
* @param [in] context Chip implementation context
* @param [out] modem_event Struct containing the event data \see lr1121_modem_event_t
*
* @returns Operation status
*/
lr1121_modem_helper_status_t lr1121_modem_helper_get_event_data( const void* context,
lr1121_modem_event_t* modem_event );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_HELPER_H
/* --- EOF ------------------------------------------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,339 @@
/*!
* @file lr1121_modem_lorawan_types.h
*
* @brief LoRaWAN driver types for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_LORAWAN_TYPES_H
#define LR1121_MODEM_LORAWAN_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Length in bytes of a LoRaWAN device eui
*/
#define LR1121_MODEM_DEV_EUI_LENGTH ( 8 )
/*!
* @brief Length in bytes of a LoRaWAN join eui
*/
#define LR1121_MODEM_JOIN_EUI_LENGTH ( 8 )
/*!
* @brief Length in bytes of a LoRaWAN application key
*/
#define LR1121_MODEM_APP_KEY_LENGTH ( 16 )
/*!
* @brief Length in bytes of a LoRaWAN network key
*/
#define LR1121_MODEM_NWK_KEY_LENGTH ( 16 )
/*!
* @brief Length of datarate distribution array
*/
#define LR1121_MODEM_DATARATE_DISTRIBUTION_LENGTH ( 16 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief LoRaWAN class type
*/
typedef enum
{
LR1121_LORAWAN_CLASS_A = 0x00,
LR1121_LORAWAN_CLASS_B = 0x01,
LR1121_LORAWAN_CLASS_C = 0x02,
} lr1121_modem_classes_t;
/**
* @brief LoRaWAN network type
*/
typedef enum
{
LR1121_MODEM_LORAWAN_PRIVATE_NETWORK = 0x00, //!< LoRaWAN private network
LR1121_MODEM_LORAWAN_PUBLIC_NETWORK = 0x01 //!< LoRaWAN public network
} lr1121_modem_network_type_t;
/*!
* @brief LoRaWAN region type
*/
typedef enum
{
LR1121_LORAWAN_REGION_EU868 = 0x01,
LR1121_LORAWAN_REGION_AS923_GRP1 = 0x02,
LR1121_LORAWAN_REGION_US915 = 0x03,
LR1121_LORAWAN_REGION_AU915 = 0x04,
LR1121_LORAWAN_REGION_CN470 = 0x05,
LR1121_LORAWAN_REGION_WW2G4 = 0x06,
LR1121_LORAWAN_REGION_AS923_GRP2 = 0x07,
LR1121_LORAWAN_REGION_AS923_GRP3 = 0x08,
LR1121_LORAWAN_REGION_IN865 = 0x09,
LR1121_LORAWAN_REGION_KR920 = 0x0A,
LR1121_LORAWAN_REGION_RU864 = 0x0B,
LR1121_LORAWAN_REGION_CN470_RP_1_0 = 0x0C,
LR1121_LORAWAN_REGION_AS923_GRP4 = 0x0D,
} lr1121_modem_regions_t;
/*!
* @brief Adaptative Data Rate profiles type
*/
typedef enum
{
LR1121_MODEM_ADR_PROFILE_NETWORK_SERVER_CONTROLLED = 0x00, //!< Network Server Controlled
LR1121_MODEM_ADR_PROFILE_MOBILE_LONG_RANGE = 0x01, //!< Mobile Long Range : 50% MinDr, 25% MinDr + 1, 25% MinDr + 2
LR1121_MODEM_ADR_PROFILE_MOBILE_LOW_POWER =
0x02, //!< Mobile Low Power : 25% MaxDr, 25% MaxDr - 1, 25% MaxDr - 2, 25% MaxDr - 3
LR1121_MODEM_ADR_PROFILE_CUSTOM =
0x03, //!< Custom List A custom ADR profile consists of a list of 16 preferred data rates.
//!< For every transmission, a random entry in that list is selected.
} lr1121_modem_adr_profiles_t;
/*!
* @brief LoRaWAN uplink type
*/
typedef enum
{
LR1121_MODEM_UPLINK_UNCONFIRMED = 0x00,
LR1121_MODEM_UPLINK_CONFIRMED = 0x01,
} lr1121_modem_uplink_type_t;
/*!
* @brief LoRaWAN Duty Cycle activation type
*/
typedef enum
{
LR1121_MODEM_CERTIFICATION_MODE_DISABLE = 0x00,
LR1121_MODEM_CERTIFICATION_MODE_ENABLE = 0x01,
} lr1121_modem_certification_mode_t;
/*!
* @brief Listen Before Talk (LBT) activation type
*/
typedef enum
{
LR1121_MODEM_LBT_MODE_DISABLE = 0x00,
LR1121_MODEM_LBT_MODE_ENABLE = 0x01,
} lr1121_modem_lbt_mode_t;
/*!
* @brief Carrier Sense Multiple Access (CSMA) activation type
*/
typedef enum
{
LR1121_MODEM_CSMA_MODE_DISABLE = 0x00,
LR1121_MODEM_CSMA_MODE_ENABLE = 0x01,
} lr1121_modem_csma_mode_t;
/**
* @brief Carrier Sense Multiple Access (CSMA) backoff activation type
*/
typedef enum
{
LR1121_MODEM_CSMA_BACKOFF_DISABLE = 0x00, //!< Disable CMSA backoff
LR1121_MODEM_CSMA_BACKOFF_ENABLE = 0x01, //!< Enable CMSA backoff
} lr1121_modem_csma_backoff_mode_t;
/*!
* @brief LoRaWAN mac request field
*/
typedef enum
{
LR1121_MODEM_MAC_REQUEST_LINK_CHECK = 0x01, //!< Enable the MAC Link Check request
LR1121_MODEM_MAC_REQUEST_TIME = 0x02, //!< Enable the MAC Time request
LR1121_MODEM_MAC_REQUEST_PING_SLOT_INFO = 0x04, //!< Enable the MAC Ping Slot Info request
} lr1121_modem_mac_request_t;
/**
* @brief Bit mask for lr1121_modem_mac_request_t
*
* @see lr1121_modem_mac_request_t
*/
typedef uint8_t lr1121_modem_mac_request_bitmask_t;
/*!
* @brief RX flags encoding
*/
typedef enum
{
LR1121_MODEM_DOWNLINK_WINDOW_RX1 = 0x01, //!< received on RX1 unicast
LR1121_MODEM_DOWNLINK_WINDOW_RX2 = 0x02, //!< received on RX2 unicast
LR1121_MODEM_DOWNLINK_WINDOW_RXC = 0x03, //!< received on Class C RX unicast
LR1121_MODEM_DOWNLINK_WINDOW_RXC_MULTICAST_GROUP0 = 0x04, //!< received on Class C Multicast RX for group 0
LR1121_MODEM_DOWNLINK_WINDOW_RXC_MULTICAST_GROUP1 = 0x05, //!< received on Class C Multicast RX for group 1
LR1121_MODEM_DOWNLINK_WINDOW_RXC_MULTICAST_GROUP2 = 0x06, //!< received on Class C Multicast RX for group 2
LR1121_MODEM_DOWNLINK_WINDOW_RXC_MULTICAST_GROUP3 = 0x07, //!< received on Class C Multicast RX for group 3
LR1121_MODEM_DOWNLINK_WINDOW_RXB = 0x08, //!< received on Class B RX unicast
LR1121_MODEM_DOWNLINK_WINDOW_RXB_MULTICAST_GROUP0 = 0x09, //!< received on Class B Multicast RX for group 0
LR1121_MODEM_DOWNLINK_WINDOW_RXB_MULTICAST_GROUP1 = 0x0A, //!< received on Class B Multicast RX for group 1
LR1121_MODEM_DOWNLINK_WINDOW_RXB_MULTICAST_GROUP2 = 0x0B, //!< received on Class B Multicast RX for group 2
LR1121_MODEM_DOWNLINK_WINDOW_RXB_MULTICAST_GROUP3 = 0x0C, //!< received on Class B Multicast RX for group 3
LR1121_MODEM_DOWNLINK_WINDOW_RXBEACON = 0x0D, //!< received a Class B beacon
LR1121_MODEM_DOWNLINK_WINDOW_RXRELAY = 0x0E, //!< received on Relay window
} lr1121_modem_downlink_window_t;
/*!
* @brief class b ping slot status
*/
typedef enum
{
LR1121_MODEM_CLASS_B_PING_SLOT_1_S = 0x00, //!< 1 second ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_2_S = 0x01, //!< 2 seconds ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_4_S = 0x02, //!< 4 seconds ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_8_S = 0x03, //!< 8 seconds ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_16_S = 0x04, //!< 16 seconds ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_32_S = 0x05, //!< 32 seconds ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_64_S = 0x06, //!< 64 seconds ping-slot periodicity
LR1121_MODEM_CLASS_B_PING_SLOT_128_S = 0x07, //!< 128 seconds ping-slot periodicity
} lr1121_modem_class_b_ping_slot_t;
/*!
* @brief Select the source of battery level value to use for DevStatusAns MAC command
*
*/
typedef enum
{
LR1121_MODEM_BATTERY_LEVEL_FROM_INTERNAL_VALUE =
0x00, //!< Battery level is obtained from LR1121 VBat (see @ref lr1121_modem_system_get_vbat)
LR1121_MODEM_BATTERY_LEVEL_FROM_USER_VALUE = 0x01, //!< Battery level is provided by user application
} lr1121_modem_battery_level_source_value_t;
/*!
* @brief Join EUI type
*/
typedef uint8_t lr1121_modem_join_eui_t[LR1121_MODEM_JOIN_EUI_LENGTH];
/*!
* @brief Device EUI type
*/
typedef uint8_t lr1121_modem_dev_eui_t[LR1121_MODEM_DEV_EUI_LENGTH];
/*!
* @brief Application key type
*/
typedef uint8_t lr1121_modem_app_key_t[LR1121_MODEM_APP_KEY_LENGTH];
/*!
* @brief Application key type
*/
typedef uint8_t lr1121_modem_nwk_key_t[LR1121_MODEM_NWK_KEY_LENGTH];
/*!
* @brief modem downlink metadata structure
*
* The Signal to Noise Ratio (SNR) is returned as an integer part, and a decimal part in 0.25 dB.
* The SNR in dB is therefore obtained by: \f$ SNR_{dB} = snr\_integer + 0.25 \times snr\_quarter \f$
*/
typedef struct
{
uint8_t stack_id; //!< The stack identifier that receives the downlink
int16_t rssi; //!< The RSSI of the received downlink in dBm
int8_t snr_integer; //!< Signal to Noise Ratio of the received downlink (integer part, in dB)
uint8_t snr_quarter; //!< Signal to Noise Ratio of the received downlink (0.25dB counts)
lr1121_modem_downlink_window_t window; //!< Rx window of the received downlink
uint8_t fport; //!< LoRaWAN port of the received downlink
uint8_t fpending_bit; //!< Frame pending bit of the received downlink
uint32_t frequency_hz; //!< RF frequency of the received downlink
uint8_t datarate; //!< Datarate of the received downlink
} lr1121_modem_downlink_metadata_t;
/*!
* @brief multicast class c status structure
*/
typedef struct
{
uint8_t is_session_started; //!< Indicate if the multicast class C session is started
uint32_t downlink_frequency; //!< Downlink frequency of the multicast class C session
uint8_t downlink_datarate; //!< Datarate of the multicast class C session
} lr1121_modem_multicast_class_c_status_t;
/*!
* @brief multicast class b status structure
*/
typedef struct
{
uint8_t is_session_started; //!< Indicate if the multicast class B session is started
uint32_t downlink_frequency; //!< Downlink frequency of the multicast class B session
uint8_t downlink_datarate; //!< Datarate of the multicast class B session
uint8_t is_session_waiting_for_beacon; //!< Indicates whether the multicast class B session have received a beacon
uint8_t ping_slot_periodicity; //!< Ping slot periodicity of the multicast class B session
} lr1121_modem_multicast_class_b_status_t;
/*!
* @brief LR1121 LoRaWAN version structure
*/
typedef struct
{
uint8_t lorawan_major; //!< Major number of the LoRaWAN standard implemented
uint8_t lorawan_minor; //!< Minor number of the LoRaWAN standard implemented
uint8_t lorawan_patch; //!< Patch number of the LoRaWAN standard implemented
uint8_t lorawan_revision; //!< Revision number of the LoRaWAN standard implemented
uint8_t rp_major; //!< Major number of the regional parameters implemented
uint8_t rp_minor; //!< Minor number of the regional parameters implemented
uint8_t rp_patch; //!< Patch number of the regional parameters implemented
uint8_t rp_revision; //!< Revision number of the regional parameters implemented
} lr1121_modem_lorawan_version_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_LORAWAN_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,144 @@
/*!
* @file lr1121_modem_lr_fhss.h
*
* @brief LR_FHSS driver definition for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_LR_FHSS_H
#define LR1121_MODEM_LR_FHSS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr1121_modem_lr_fhss_types.h"
#include "lr1121_modem_common.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/**
* @brief Length, in bytes, of a LR-FHSS sync word
*/
#define LR_FHSS_SYNC_WORD_BYTES ( 4 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Initialize the LR_FHSS
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_lr_fhss_init( const void* context );
/**
* @brief Get the delay in microsecond between the last bit sent and the TX done interrupt
*
* @param [in] params lr1121 LR-FHSS parameter structure
* @param [in] payload_length Length of application-layer payload
*
* @returns Delay in microseconds
*/
uint16_t lr1121_modem_lr_fhss_get_bit_delay_in_us( const lr1121_modem_lr_fhss_params_t* params,
uint16_t payload_length );
/*!
* @brief Configure a payload to be sent with LR_FHSS
*
* When calling this method, lr1121_modem_radio_set_lr_fhss_sync_word is implicitely called to configure the sync word.
* Note that the syncword must be 4 bytes long.
*
* @param [in] context Chip implementation context
* @param [in] lr_fhss_params Parameter configuration structure of the LRFHSS
* @param [in] hop_sequence_id Seed used to derive the hopping sequence pattern. Only the nine LSBs are taken into
* account
* @param [in] payload The payload to send. It is the responsibility of the caller to ensure that this references an
* array containing at least payload_length elements
* @param [in] payload_length The length of the payload
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_lr_fhss_build_frame( const void* context,
const lr1121_modem_lr_fhss_params_t* lr_fhss_params,
uint16_t hop_sequence_id, const uint8_t* payload,
uint8_t payload_length );
/*!
* @brief Get the time on air in ms for LR-FHSS transmission
*
* @param [in] params LR1121 LR-FHSS parameter structure
* @param [in] payload_length Length of application-layer payload
*
* @returns Time-on-air value in ms for LR-FHSS transmission
*/
uint32_t lr1121_modem_lr_fhss_get_time_on_air_in_ms( const lr1121_modem_lr_fhss_params_t* params,
uint16_t payload_length );
/**
* @brief Return the number of hop sequences available using the given parameters
*
* @param [in] lr_fhss_params Parameter configuration structure of the LRFHSS
*
* @return Returns the number of valid hop sequences (512 or 384)
*/
unsigned int lr1121_modem_lr_fhss_get_hop_sequence_count( const lr1121_modem_lr_fhss_params_t* lr_fhss_params );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_LR_FHSS_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,66 @@
/*!
* @file lr1121_modem_lr_fhss_types.h
*
* @brief LR_FHSS types definition for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_LR_FHSS_TYPES_H
#define LR1121_MODEM_LR_FHSS_TYPES_H
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr_fhss_v1_base_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief LR FHSS parameter structure
*/
typedef struct
{
lr_fhss_v1_params_t lr_fhss_params; //!< Base LR FHSS parameters
int8_t device_offset; //!< Per device offset to avoid collisions over the air. Possible values:
//!< - if lr_fhss_params.grid == LR_FHSS_V1_GRID_25391_HZ:
//!< [-26, 25]
//!< - if lr_fhss_params.grid == LR_FHSS_V1_GRID_3906_HZ:
//!< [-4, 3]
} lr1121_modem_lr_fhss_params_t;
#endif // LR1121_MODEM_LR_FHSS_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,393 @@
/*!
* @file lr1121_modem_modem.h
*
* @brief Modem driver for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_MODEM_H
#define LR1121_MODEM_MODEM_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
#include "lr1121_modem_common.h"
#include "lr1121_modem_modem_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Reset non-volatile settings to their default value
*
* Settings that are reset are:
* - region
* - devnonce
* - joinnonce
* - LoRaWAN certification state
* - low frequency clock source
* - reset counter
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_factory_reset( const void* context );
/*!
* @brief Return the modem version information
*
* @param [in] context Chip implementation context
* @param [out] modem_version Version of the LR1121 modem
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_modem_version( const void* context,
lr1121_modem_version_t* modem_version );
/*!
* @brief Return the modem status
*
* @param [in] context Chip implementation context
* @param [out] status LR1121 mode status bit mask @ref lr1121_modem_lorawan_status_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_status( const void* context,
lr1121_modem_lorawan_status_bitmask_t* status );
/*!
* @brief Return and reset the consumption statistics of the modem
*
* @param [in] context Chip implementation context
* @param [out] charge Charge counter in mAh
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_charge( const void* context, lr1121_modem_charge_t* charge );
/*!
* @brief Get pending events from the modem
*
* Pending events are indicated by the EVENT line. The EVENT line will be de-asserted after all events have been
* retrieved and no further events are available.
* When no event is available this command returns with empty response payload.
*
* @param [in] context Chip implementation context
* @param [out] event_fields \see lr1121_modem_event_fields_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_event( const void* context, lr1121_modem_event_fields_t* event_fields );
/*!
* @brief Suspend or resume the modems radio operations
*
* It can be used to prevent extra power consumption by the modem in case the application MCU temporarily needs more
* power itself and wants to prevent exceeding limits.
*
* @param [in] context Chip implementation context
* @param [in] suspend Operations are suspended with parameter value 0x01 and resumed with parameter value 0x00 @ref
* lr1121_modem_suspend_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_suspend( const void* context, const lr1121_modem_suspend_t suspend );
/*!
* @brief Get suspend or resume state of the the modems radio operations.
*
* @param [in] context Chip implementation context
* @param [out] suspend Operations are suspended with parameter value 0x01 and resumed with parameter value 0x00 @ref
* lr1121_modem_suspend_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_suspend( const void* context, lr1121_modem_suspend_t* suspend );
/*!
* @brief Set an application alarm timer in seconds
*
* When the timer has expired the event @ref LR1121_MODEM_LORAWAN_EVENT_ALARM is generated.
* If this command is applied again before the timer has expired, the timer will be started again with the new period.
* Value 0 immediately generates event @ref LR1121_MODEM_LORAWAN_EVENT_ALARM.
*
* @param [in] context Chip implementation context
* @param [in] seconds Seconds
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_set_alarm_timer( const void* context, uint32_t seconds );
/*!
* @brief Clear the alarm timer
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_clear_alarm_timer( const void* context );
/*!
* @brief Get the application alarm timer remaining time
*
* @param [in] context Chip implementation context
* @param [out] remaining_time Remaining time in seconds
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_alarm_remaining_time( const void* context, uint32_t* remaining_time );
/*!
* @brief Get the crashlog status
*
* @param [in] context Chip implementation context
* @param [out] status Crashlog status, see \ref lr1121_modem_crashlog_status_t
* @param [out] crashlog Function name in ASCII. It is up to the caller to ensure this pointer is at least 242 bytes
* long
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_get_crashlog( const void* context, lr1121_modem_crashlog_status_t* status,
uint8_t* crashlog );
/*!
* @brief Enable test functions
*
* With the exception of the @ref lr1121_modem_test_mode_start command, test commands are only available if test mode is
* active. Test mode can only be activated if the modem has not yet received a command that results in a radio
* operation. Once test mode is active, all other modem commands are disabled.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_mode_start( const void* context );
/*!
* @brief No operation. This command may be used to terminate an ongoing continuous TX operation.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_nop( const void* context );
/*!
* @brief Transmit LoRa packets
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
* @param [in] tx_power Tx power in dBm
* @param [in] payload_length Payload length
* @param [in] sf spreading factor @ref lr1121_modem_tst_mode_lora_sf_t
* @param [in] bw bandwidth @ref lr1121_modem_tst_mode_lora_bw_t
* @param [in] cr Coding Rate @ref lr1121_modem_tst_mode_lora_cr_t
* @param [in] is_iq_inverted Enable IQ inverted
* @param [in] is_crc_enabled Enable CRC field
* @param [in] header_mode Configure header implicit or explicit
* @param [in] preamble_length Number of preamble symbols
* @param [in] number_of_tx Number of packet to send. 0 makes the chip to send packet infinitely until call to @ref
* lr1121_modem_test_nop
* @param [in] delay_ms Delay between two consecutive transmit
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_tx_lora(
const void* context, uint32_t frequency, int8_t tx_power, uint8_t payload_length,
lr1121_modem_tst_mode_lora_sf_t sf, lr1121_modem_tst_mode_lora_bw_t bw, lr1121_modem_tst_mode_lora_cr_t cr,
bool is_iq_inverted, bool is_crc_enabled, lr1121_modem_tst_mode_lora_packet_header_mode_t header_mode,
uint32_t preamble_length, uint32_t number_of_tx, uint32_t delay_ms );
/*!
* @brief Transmit FSK packets
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
* @param [in] tx_power Tx power in dBm
* @param [in] payload_length Payload length
* @param [in] number_of_tx Number of packet to send. 0 makes the chip to send packet infinitely until call to @ref
* lr1121_modem_test_nop
* @param [in] delay_ms Delay between two consecutive transmit
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_tx_fsk( const void* context, uint32_t frequency, int8_t tx_power,
uint8_t payload_length, uint32_t number_of_tx,
uint32_t delay_ms );
/*!
* @brief Transmit LR-FHSS packets
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
* @param [in] tx_power Tx power in dBm
* @param [in] payload_length Payload length
* @param [in] grid LR-FHSS grid
* @param [in] bw LR-FHSS bandwidth
* @param [in] cr LR-FHSS coding rate
* @param [in] number_of_tx Number of packet to send. 0 makes the chip to send packet infinitely until call to @ref
* lr1121_modem_test_nop
* @param [in] delay_ms Delay between two consecutive transmit
* @param [in] is_hopping_enabled Enable LR-FHSS frequency hopping
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_tx_lr_fhss( const void* context, uint32_t frequency, int8_t tx_power,
uint8_t payload_length,
lr1121_modem_tst_mode_lr_fhss_grid_t grid,
lr1121_modem_tst_mode_lr_fhss_bw_t bw,
lr1121_modem_tst_mode_lr_fhss_cr_t cr, uint32_t number_of_tx,
uint32_t delay_ms, bool is_hopping_enabled );
/*!
* @brief Transmit a continuous wave.
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
* @param [in] tx_power Tx power in dBm
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_tx_cw( const void* context, uint32_t frequency, int8_t tx_power );
/*!
* @brief Continuously receive LoRa packets
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
* @param [in] sf spreading factor @ref lr1121_modem_tst_mode_lora_sf_t
* @param [in] bw bandwidth @ref lr1121_modem_tst_mode_lora_bw_t
* @param [in] cr Coding Rate @ref lr1121_modem_tst_mode_lora_cr_t
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_rx_lora_cont( const void* context, uint32_t frequency,
lr1121_modem_tst_mode_lora_sf_t sf,
lr1121_modem_tst_mode_lora_bw_t bw,
lr1121_modem_tst_mode_lora_cr_t cr );
/*!
* @brief Continuously receive FSK packets
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_rx_fsk_cont( const void* context, uint32_t frequency );
/*!
* @brief Read the packet counter received during continuously receive packets test.
*
* @param [in] context Chip implementation context
* @param [in] rx_packet_counter The counter of packet received during RX continuous packet test
*
* @returns Operation status
*
* @see lr1121_modem_test_rx_lora_cont
*/
lr1121_modem_response_code_t lr1121_modem_test_read_packet_counter_rx_cont( const void* context,
uint32_t* rx_packet_counter );
/*!
* @brief Continuously receive packets on Sub-GHz radio path.
*
* @param [in] context Chip implementation context
* @param [in] frequency Frequency in Hz
* @param [in] time_ms time in millisecond of the radio acquisition
* @param [in] bw_hz bandwidth in Hz
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_rssi_subghz( const void* context, uint32_t frequency, uint16_t time_ms,
uint32_t bw_hz );
/*!
* @brief Reset the LR1121 radio.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_radio_rst( const void* context );
/*!
* @brief Exit test mode and reset LR1121 modem.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_exit( const void* context );
/*!
* @brief Read RSSI after a Sub Gig / 2.4 Ghz test rssi command.
*
* @param [in] context Chip implementation context
* @param [out] rssi RSSI in dBm
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_test_read_rssi( const void* context, int16_t* rssi );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_MODEM_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,296 @@
/*!
* @file lr1121_modem_modem_types.h
*
* @brief Modem driver types for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_MODEM_TYPES_H
#define LR1121_MODEM_MODEM_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
#include "lr1121_modem_common.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Modem status bits
*/
typedef enum
{
LR1121_LORAWAN_CRASH = 0x02,
LR1121_LORAWAN_JOINED = 0x08,
LR1121_LORAWAN_SUSPEND = 0x10,
LR1121_LORAWAN_JOINING = 0x40,
} lr1121_modem_lorawan_status_t;
/**
* @brief Bit mask for lr1121_modem_lorawan_status_t
*
* @see lr1121_modem_lorawan_status_t
*/
typedef uint8_t lr1121_modem_lorawan_status_bitmask_t;
/*!
* @brief LoRa spreading factor for test mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LORA_SF5 = 0x05,
LR1121_MODEM_TST_MODE_LORA_SF6 = 0x06,
LR1121_MODEM_TST_MODE_LORA_SF7 = 0x07,
LR1121_MODEM_TST_MODE_LORA_SF8 = 0x08,
LR1121_MODEM_TST_MODE_LORA_SF9 = 0x09,
LR1121_MODEM_TST_MODE_LORA_SF10 = 0x0A,
LR1121_MODEM_TST_MODE_LORA_SF11 = 0x0B,
LR1121_MODEM_TST_MODE_LORA_SF12 = 0x0C,
} lr1121_modem_tst_mode_lora_sf_t;
/*!
* @brief LoRa bandwidth for test mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LORA_10_KHZ = 0x01,
LR1121_MODEM_TST_MODE_LORA_15_KHZ = 0x02,
LR1121_MODEM_TST_MODE_LORA_20_KHZ = 0x03,
LR1121_MODEM_TST_MODE_LORA_31_KHZ = 0x04,
LR1121_MODEM_TST_MODE_LORA_41_KHZ = 0x05,
LR1121_MODEM_TST_MODE_LORA_62_KHZ = 0x06,
LR1121_MODEM_TST_MODE_LORA_125_KHZ = 0x07,
LR1121_MODEM_TST_MODE_LORA_200_KHZ = 0x08,
LR1121_MODEM_TST_MODE_LORA_250_KHZ = 0x09,
LR1121_MODEM_TST_MODE_LORA_400_KHZ = 0x0A,
LR1121_MODEM_TST_MODE_LORA_500_KHZ = 0x0B,
LR1121_MODEM_TST_MODE_LORA_800_KHZ = 0x0C,
} lr1121_modem_tst_mode_lora_bw_t;
/*!
* @brief LoRa coding rate for test mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LORA_CR_4_5 = 0x01,
LR1121_MODEM_TST_MODE_LORA_CR_4_6 = 0x02,
LR1121_MODEM_TST_MODE_LORA_CR_4_7 = 0x03,
LR1121_MODEM_TST_MODE_LORA_CR_4_8 = 0x04,
LR1121_MODEM_TST_MODE_LORA_CR_4_5_LONG_INTERLEAVING = 0x05,
LR1121_MODEM_TST_MODE_LORA_CR_4_6_LONG_INTERLEAVING = 0x06,
LR1121_MODEM_TST_MODE_LORA_CR_4_8_LONG_INTERLEAVING = 0x07,
} lr1121_modem_tst_mode_lora_cr_t;
/**
* @brief LR_FHSS grid for test mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LR_FHSS_GRID_V1_25391_HZ = 0x00,
LR1121_MODEM_TST_MODE_LR_FHSS_GRID_V1_3906_HZ = 0x01,
} lr1121_modem_tst_mode_lr_fhss_grid_t;
/**
* @brief LR-FHSS bandwidth for test mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_39063_HZ = 0x00,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_85938_HZ = 0x01,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_136719_HZ = 0x02,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_183594_HZ = 0x03,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_335938_HZ = 0x04,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_386719_HZ = 0x05,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_722656_HZ = 0x06,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_773438_HZ = 0x07,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_1523438_HZ = 0x08,
LR1121_MODEM_TST_MODE_LR_FHSS_BW_V1_1574219_HZ = 0x09,
} lr1121_modem_tst_mode_lr_fhss_bw_t;
/**
* @brief LR-FHSS coding rate for test mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LR_FHSS_CR_V1_2_3 = 0x01,
LR1121_MODEM_TST_MODE_LR_FHSS_CR_V1_1_3 = 0x03,
} lr1121_modem_tst_mode_lr_fhss_cr_t;
/*!
* @brief Packet header mode
*/
typedef enum
{
LR1121_MODEM_TST_MODE_LORA_PACKET_HEADER_EXPLICIT = 0x00,
LR1121_MODEM_TST_MODE_LORA_PACKET_HEADER_IMPLICIT = 0x01,
} lr1121_modem_tst_mode_lora_packet_header_mode_t;
/*!
* @brief Modem suspend type
*/
typedef enum
{
LR1121_MODEM_RESUMED = 0x00,
LR1121_MODEM_SUSPEND = 0x01,
} lr1121_modem_suspend_t;
/*!
* @brief Modem crashlog status type
*/
typedef enum
{
LR1121_NO_NEW_CRASHLOG = 0x00,
LR1121_NEW_CRASHLOG = 0x01,
} lr1121_modem_crashlog_status_t;
/*!
* @brief LR1121 modem consumption details
*/
typedef struct
{
uint32_t tx_last_toa_ms; //!< Last Tx time-on-air (ms)
uint32_t rx_last_toa_ms; //!< Last Rx time-on-air (ms)
uint32_t tx_cumulated_toa_ms; //!< Cumulated Tx time-on-air (ms)
uint32_t rx_cumulated_toa_ms; //!< Cumulated Rx time-on-air (ms)
uint32_t none_consumption_ms; //!< Cumulated time not in Tx nor in Rx (ms)
uint32_t tx_consumption_ma; //!< Cumulated Tx power consumption (1/1000*uA*ms)
uint32_t rx_consumption_ma; //!< Cumulated Rx power consumption (1/1000*uA*ms)
uint32_t none_consumption_ma; //!< Cumulated power consumption not in Tx nor in Rx (1/1000*uA*ms)
} lr1121_modem_consumption_details_t;
/*!
* @brief LR1121 modem consumption per stack action
*/
typedef struct
{
lr1121_modem_consumption_details_t
suspend; //!< Consumptions when modem is in suspend state. These will always read 0,
//!< even if transceiver commands where called during this state
lr1121_modem_consumption_details_t class_b_beacon; //!< Consumptions of modem related to class B beacon
lr1121_modem_consumption_details_t lr1mac_stack; //!< Consumption of modem corresponding to LoRaWAN stack
lr1121_modem_consumption_details_t lbt; //!< Consumptions of modem related to Listen Before Talk
lr1121_modem_consumption_details_t cad; //!< Consumption of modem related to Channel Activity Detection
lr1121_modem_consumption_details_t class_b_ping_slot; //!< Consumptions of modem related to class B ping slots
lr1121_modem_consumption_details_t test_mode; //!< Consumptions of modem related to test mode
lr1121_modem_consumption_details_t
direct_rp_access; //!< Consumptions when modem is in direct radio planner access state. These will always read
//!< 0, even if transceiver commands where called during this state
lr1121_modem_consumption_details_t relay_tx; //!< Consumption of modem related to relay Tx
lr1121_modem_consumption_details_t class_c; //!< Consumptions of modem related to Class C
} lr1121_modem_charge_t;
/*!
* @brief LR1121 modem version structure
*/
typedef struct
{
uint8_t use_case; //!< Will always read 5 for LR1121 Modem-E
uint8_t modem_major; //!< Major number of Modem-E
uint8_t modem_minor; //!< Minor number of Modem-E
uint8_t modem_patch; //!< Patch number of Modem-E
uint8_t lbm_major; //!< Major number of built-in LoRa Basics Modem
uint8_t lbm_minor; //!< Minor number of built-in LoRa Basics Modem
uint8_t lbm_patch; //!< Patch number of built-in LoRa Basics Modem
} lr1121_modem_version_t;
/*!
* @brief Event type for modem operation
*/
typedef enum
{
LR1121_MODEM_LORAWAN_EVENT_RESET = 0x00, //!< Modem has reset
LR1121_MODEM_LORAWAN_EVENT_ALARM = 0x01, //!< Alarm time expired
LR1121_MODEM_LORAWAN_EVENT_JOINED = 0x02, //!< Network successfully joined
LR1121_MODEM_LORAWAN_EVENT_JOIN_FAIL = 0x03, //!< Attempt to join network failed
LR1121_MODEM_LORAWAN_EVENT_TX_DONE = 0x04, //!< Frame transmitted
LR1121_MODEM_LORAWAN_EVENT_DOWN_DATA = 0x05, //!< Downlink data received
LR1121_MODEM_LORAWAN_EVENT_LINK_CHECK = 0x06, //!< Modem received a LinkADR request
LR1121_MODEM_LORAWAN_EVENT_LORAWAN_MAC_TIME = 0x07, //!< Modem received a LinkADR request
LR1121_MODEM_LORAWAN_EVENT_CLASS_B_PING_SLOT_INFO = 0x08, //!< Ping Slot Info answered or not by network
LR1121_MODEM_LORAWAN_EVENT_CLASS_B_STATUS = 0x09, //!< Downlink class B is ready or not
LR1121_MODEM_LORAWAN_EVENT_NEW_MULTICAST_SESSION_CLASS_C = 0x0A, //!< New active multicast session in class C
LR1121_MODEM_LORAWAN_EVENT_NEW_MULTICAST_SESSION_CLASS_B = 0x0B, //!< New active multicast session in class B
LR1121_MODEM_LORAWAN_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_C = 0x0C, //!< End of multicast session in class C
LR1121_MODEM_LORAWAN_EVENT_NO_MORE_MULTICAST_SESSION_CLASS_B = 0x0D, //!< End of multicast session in class B
LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_DYNAMIC =
0x0E, //!< Relay Tx dynamic mode has enabled or disabled the Wake On Radio
LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_MODE = 0x0F, //!< Relay Tx activation has been updated
LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_SYNC = 0x10, //!< Relay Tx synchronization has changed
LR1121_MODEM_LORAWAN_EVENT_ALC_SYNC_TIME = 0x11, //!< Applicative Layer Clock is synchronized
LR1121_MODEM_LORAWAN_EVENT_FUOTA_DONE = 0x12, //!< FUOTA file download terminated
LR1121_MODEM_LORAWAN_EVENT_TEST_MODE = 0x13, //!< Test mode event
LR1121_MODEM_LORAWAN_EVENT_REGIONAL_DUTY_CYCLE =
0x14, //!< Transmissions are blocked or allowed per regional duty cycle limitation
} lr1121_modem_lorawan_event_type_t;
/*!
* @brief modem event fields structure
*/
typedef struct
{
lr1121_modem_lorawan_event_type_t event_type; //!< Event type
uint8_t missed_events_count; //!< Counter of missed events of type @p event_type
uint16_t data; //!< Event data
} lr1121_modem_event_fields_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_MODEM_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,97 @@
/**
* @file lr1121_modem_radio_timings.h
*
* @brief LR1121 timing helper functions definition
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_RADIO_TIMINGS_H
#define LR1121_MODEM_RADIO_TIMINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr1121_modem_radio_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/**
* @brief Get the time between the last bit sent (on Tx side) and the Rx done event (on Rx side)
*
* @param [in] mod_params Pointer to a structure holding the LoRa modulation parameters used for the computation
*
* @returns Delay in microsecond
*/
uint32_t lr1121_modem_radio_timings_get_delay_between_last_bit_sent_and_rx_done_in_us(
const lr1121_modem_radio_mod_params_lora_t* mod_params );
/**
* @brief Get the time between the last bit sent and the Tx done event
*
* @param [in] ramp_time Power amplifier ramp time
*
* @returns Delay in microsecond
*/
uint32_t lr1121_modem_radio_timings_get_delay_between_last_bit_sent_and_tx_done_in_us(
const lr1121_modem_radio_ramp_time_t ramp_time );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_RADIO_TIMINGS_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,653 @@
/*!
* @file lr1121_modem_radio_types.h
*
* @brief Radio driver types for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_RADIO_TYPES_H
#define LR1121_MODEM_RADIO_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Bit mask to set to indicate a LR-FHSS bitrate is defined in steps of 1/256 bit per seconds
*/
#define LR1121_MODEM_RADIO_LR_FHSS_BITRATE_DIVIDE_BY_256 ( 0x80000000 )
/*!
* @brief LR-FHSS bitrate value at 488.28125 bps defined as steps of 1/256 bitrate per seconds
*/
#define LR1121_MODEM_RADIO_LR_FHSS_BITRATE_IN_256_BPS_STEPS ( 125000 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Power Amplifier Selection values
*
* - Low-power Power Amplifier can reach up to 14dBm
* - High-power Power Amplifier can reach up to 22 dBm
*/
typedef enum
{
LR1121_MODEM_RADIO_PA_SEL_LP = 0x00, //!< Low-power Power Amplifier
LR1121_MODEM_RADIO_PA_SEL_HP = 0x01, //!< High-power Power Amplifier
LR1121_MODEM_RADIO_PA_SEL_HF = 0x02, //!< High-frequency Power Amplifier
} lr1121_modem_radio_pa_selection_t;
/*!
* @brief GFSK Address Filtering configurations
*
* If Address Filtering is enabled but a wrong address is received, therefore the reception is aborted and the address
* error flag of packet status is set.
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_ADDRESS_FILTERING_DISABLE = 0x00, //!< Filter deactivated
LR1121_MODEM_RADIO_GFSK_ADDRESS_FILTERING_NODE_ADDRESS = 0x01, //!< Filter on Node Address
LR1121_MODEM_RADIO_GFSK_ADDRESS_FILTERING_NODE_AND_BROADCAST_ADDRESSES =
0x02, //!< Filtering on Node and Broadcast addresses
} lr1121_modem_radio_gfsk_address_filtering_t;
/*!
* @brief Chip mode after successfull transmission or reception
*
* Unused for RX duty cycle and AutoTxRx operations
*/
typedef enum
{
LR1121_MODEM_RADIO_FALLBACK_STDBY_RC = 0x01, //!< Standby RC (Default)
LR1121_MODEM_RADIO_FALLBACK_STDBY_XOSC = 0x02, //!< Standby XOSC
LR1121_MODEM_RADIO_FALLBACK_FS = 0x03 //!< FS
} lr1121_modem_radio_fallback_modes_t;
/*!
* @brief Ramping time for PA
*
* This parameter is the ramping time of the PA. A high value improves spectral quality.
*/
typedef enum
{
LR1121_MODEM_RADIO_RAMP_16_US = 0x00, //!< 16 us Ramp Time
LR1121_MODEM_RADIO_RAMP_32_US = 0x01, //!< 32 us Ramp Time
LR1121_MODEM_RADIO_RAMP_48_US = 0x02, //!< 48 us Ramp Time (Default)
LR1121_MODEM_RADIO_RAMP_64_US = 0x03, //!< 64 us Ramp Time
LR1121_MODEM_RADIO_RAMP_80_US = 0x04, //!< 80 us Ramp Time
LR1121_MODEM_RADIO_RAMP_96_US = 0x05, //!< 96 us Ramp Time
LR1121_MODEM_RADIO_RAMP_112_US = 0x06, //!< 112 us Ramp Time
LR1121_MODEM_RADIO_RAMP_128_US = 0x07, //!< 128 us Ramp Time
LR1121_MODEM_RADIO_RAMP_144_US = 0x08, //!< 144 us Ramp Time
LR1121_MODEM_RADIO_RAMP_160_US = 0x09, //!< 160 us Ramp Time
LR1121_MODEM_RADIO_RAMP_176_US = 0x0A, //!< 176 us Ramp Time
LR1121_MODEM_RADIO_RAMP_192_US = 0x0B, //!< 192 us Ramp Time
LR1121_MODEM_RADIO_RAMP_208_US = 0x0C, //!< 208 us Ramp Time
LR1121_MODEM_RADIO_RAMP_240_US = 0x0D, //!< 240 us Ramp Time
LR1121_MODEM_RADIO_RAMP_272_US = 0x0E, //!< 272 us Ramp Time
LR1121_MODEM_RADIO_RAMP_304_US = 0x0F, //!< 304 us Ramp Time
} lr1121_modem_radio_ramp_time_t;
/*!
* @brief LoRa network type configuration
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_NETWORK_PRIVATE = 0x00, //!< LoRa private network
LR1121_MODEM_RADIO_LORA_NETWORK_PUBLIC = 0x01, //!< LoRa public network
} lr1121_modem_radio_lora_network_type_t;
/*!
* @brief LoRa Spreading Factor configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_SF5 = 0x05, //!< Spreading Factor 5
LR1121_MODEM_RADIO_LORA_SF6 = 0x06, //!< Spreading Factor 6
LR1121_MODEM_RADIO_LORA_SF7 = 0x07, //!< Spreading Factor 7
LR1121_MODEM_RADIO_LORA_SF8 = 0x08, //!< Spreading Factor 8
LR1121_MODEM_RADIO_LORA_SF9 = 0x09, //!< Spreading Factor 9
LR1121_MODEM_RADIO_LORA_SF10 = 0x0A, //!< Spreading Factor 10
LR1121_MODEM_RADIO_LORA_SF11 = 0x0B, //!< Spreading Factor 11
LR1121_MODEM_RADIO_LORA_SF12 = 0x0C, //!< Spreading Factor 12
} lr1121_modem_radio_lora_sf_t;
/*!
* @brief LoRa Bandwidth configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_BW_10 = 0x08, //!< Bandwidth 10.42 kHz
LR1121_MODEM_RADIO_LORA_BW_15 = 0x01, //!< Bandwidth 15.63 kHz
LR1121_MODEM_RADIO_LORA_BW_20 = 0x09, //!< Bandwidth 20.83 kHz
LR1121_MODEM_RADIO_LORA_BW_31 = 0x02, //!< Bandwidth 31.25 kHz
LR1121_MODEM_RADIO_LORA_BW_41 = 0x0A, //!< Bandwidth 41.67 kHz
LR1121_MODEM_RADIO_LORA_BW_62 = 0x03, //!< Bandwidth 62.50 kHz
LR1121_MODEM_RADIO_LORA_BW_125 = 0x04, //!< Bandwidth 125.00 kHz
LR1121_MODEM_RADIO_LORA_BW_250 = 0x05, //!< Bandwidth 250.00 kHz
LR1121_MODEM_RADIO_LORA_BW_500 = 0x06, //!< Bandwidth 500.00 kHz
LR1121_MODEM_RADIO_LORA_BW_200 = 0x0D, //!< Bandwidth 203.00 kHz, 2G4 and compatible with LR112x chips only
LR1121_MODEM_RADIO_LORA_BW_400 = 0x0E, //!< Bandwidth 406.00 kHz, 2G4 and compatible with LR112x chips only
LR1121_MODEM_RADIO_LORA_BW_800 = 0x0F, //!< Bandwidth 812.00 kHz, 2G4 and compatible with LR112x chips only
} lr1121_modem_radio_lora_bw_t;
/*!
* @brief LoRa Coding Rate configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_NO_CR = 0x00, //!< No Coding Rate
LR1121_MODEM_RADIO_LORA_CR_4_5 = 0x01, //!< Coding Rate 4/5 Short Interleaver
LR1121_MODEM_RADIO_LORA_CR_4_6 = 0x02, //!< Coding Rate 4/6 Short Interleaver
LR1121_MODEM_RADIO_LORA_CR_4_7 = 0x03, //!< Coding Rate 4/7 Short Interleaver
LR1121_MODEM_RADIO_LORA_CR_4_8 = 0x04, //!< Coding Rate 4/8 Short Interleaver
LR1121_MODEM_RADIO_LORA_CR_LI_4_5 = 0x05, //!< Coding Rate 4/5 Long Interleaver
LR1121_MODEM_RADIO_LORA_CR_LI_4_6 = 0x06, //!< Coding Rate 4/6 Long Interleaver
LR1121_MODEM_RADIO_LORA_CR_LI_4_8 = 0x07, //!< Coding Rate 4/8 Long Interleaver
} lr1121_modem_radio_lora_cr_t;
/*!
* @brief Values for intermediary mode
*/
typedef enum
{
LR1121_MODEM_RADIO_MODE_SLEEP = 0x00, //!< Sleep
LR1121_MODEM_RADIO_MODE_STANDBY_RC = 0x01, //!< Standby RC
LR1121_MODEM_RADIO_MODE_STANDBY_XOSC = 0x02, //!< Standby XOSC
LR1121_MODEM_RADIO_MODE_FS = 0x03 //!< Frequency Synthesis
} lr1121_modem_radio_intermediary_mode_t;
/*!
* @brief GFSK Cyclic Redundancy Check configurations
*
* If this value is set to something other than CRC_OFF, a CRC is automatically computed and added after the end of the
* payload on transmitter side. On receiver side, the CRC check is automatically processed.
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_CRC_OFF = 0x01, //!< CRC check deactivated
LR1121_MODEM_RADIO_GFSK_CRC_1_BYTE = 0x00,
LR1121_MODEM_RADIO_GFSK_CRC_2_BYTES = 0x02,
LR1121_MODEM_RADIO_GFSK_CRC_1_BYTE_INV = 0x04,
LR1121_MODEM_RADIO_GFSK_CRC_2_BYTES_INV = 0x06,
} lr1121_modem_radio_gfsk_crc_type_t;
/*!
* @brief GFSK data whitening configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_DC_FREE_OFF = 0x00, //!< Whitening deactivated
LR1121_MODEM_RADIO_GFSK_DC_FREE_WHITENING = 0x01, //!< Whitening enabled
LR1121_MODEM_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP = 0x03, //!< Whitening enabled - SX128x compatibility
} lr1121_modem_radio_gfsk_dc_free_t;
/*!
* @brief GFSK Header Type configurations
*
* This parameter indicates whether or not the payload length is sent and read over the air.
*
* If the payload length is known beforehand by both transmitter and receiver, therefore there is no need to send it
* over the air. Otherwise, setting this parameter to LR1121_MODEM_RADIO_GFSK_PKT_VAR_LEN will make the modem to
* automatically prepand a byte containing the payload length to the the payload on transmitter side. On receiver side,
* this first byte is read to set the payload length to read.
*
* This configuration is only available for GFSK packet types.
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_PKT_FIX_LEN = 0x00, //!< Payload length is not sent/read over the air
LR1121_MODEM_RADIO_GFSK_PKT_VAR_LEN = 0x01, //!< Payload length is sent/read over the air
LR1121_MODEM_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP =
0x02, //!< Payload length is sent/read over the air - SX128x compatibility
} lr1121_modem_radio_gfsk_pkt_len_modes_t;
/*!
* @brief GFSK Preamble Detector Length configurations
*
* This parameter sets the minimum length of preamble bits to be received to continue reception of incoming packet. If a
* packet with preamble length lower than this value is being received, the reception stops without generating IRQ.
*
* This parameter has no impact on TX operations.
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_PREAMBLE_DETECTOR_OFF = 0x00,
LR1121_MODEM_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_8BITS = 0x04,
LR1121_MODEM_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_16BITS = 0x05,
LR1121_MODEM_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_24BITS = 0x06,
LR1121_MODEM_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_32BITS = 0x07
} lr1121_modem_radio_gfsk_preamble_detector_t;
/*!
* @brief LoRa Cyclic Redundancy Check configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_CRC_OFF = 0x00, //!< CRC deactivated
LR1121_MODEM_RADIO_LORA_CRC_ON = 0x01, //!< CRC activated
} lr1121_modem_radio_lora_crc_t;
/*!
* @brief LoRa Header type configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_PKT_EXPLICIT = 0x00, //!< Explicit header: transmitted over the air
LR1121_MODEM_RADIO_LORA_PKT_IMPLICIT = 0x01, //!< Implicit header: not transmitted over the air
} lr1121_modem_radio_lora_pkt_len_modes_t;
/*!
* @brief LoRa IQ mode configurations
*
* LoRa IQ modes are mutually exclusives: a physical packet sent with standard IQ will not be received by a receiver
* configured with inverted IQ.
*/
typedef enum
{
LR1121_MODEM_RADIO_LORA_IQ_STANDARD = 0x00, //!< IQ standard
LR1121_MODEM_RADIO_LORA_IQ_INVERTED = 0x01, //!< IQ inverted
} lr1121_modem_radio_lora_iq_t;
/*!
* @brief Packet type values
*/
typedef enum
{
LR1121_MODEM_RADIO_PKT_NONE = 0x00, //!< State after cold start
LR1121_MODEM_RADIO_PKT_TYPE_GFSK = 0x01, //!< GFSK modulation
LR1121_MODEM_RADIO_PKT_TYPE_LORA = 0x02, //!< LoRa modulation
LR1121_MODEM_RADIO_PKT_TYPE_BPSK = 0x03, //!< BPSK modulation
LR1121_MODEM_RADIO_PKT_TYPE_LR_FHSS = 0x04, //!< LR-FHSS modulation
} lr1121_modem_radio_pkt_type_t;
/*!
* @brief Select power amplifier supply source
*/
typedef enum
{
LR1121_MODEM_RADIO_PA_REG_SUPPLY_VREG = 0x00, //!< Power amplifier supplied by the main regulator
LR1121_MODEM_RADIO_PA_REG_SUPPLY_VBAT = 0x01 //!< Power amplifier supplied by the battery
} lr1121_modem_radio_pa_reg_supply_t;
/*!
* @brief RX Duty Cycle Modes
*/
typedef enum
{
LR1121_MODEM_RADIO_RX_DUTY_CYCLE_MODE_RX = 0x00, //!< LoRa/GFSK: Uses Rx for listening to packets
LR1121_MODEM_RADIO_RX_DUTY_CYCLE_MODE_CAD = 0x01, //!< Only in LoRa: Uses CAD to listen for over-the-air activity
} lr1121_modem_radio_rx_duty_cycle_mode_t;
/*!
* @brief GFSK Bandwidth configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_BW_4800 = 0x1F, //!< Bandwidth 4.8 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_5800 = 0x17, //!< Bandwidth 5.8 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_7300 = 0x0F, //!< Bandwidth 7.3 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_9700 = 0x1E, //!< Bandwidth 9.7 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_11700 = 0x16, //!< Bandwidth 11.7 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_14600 = 0x0E, //!< Bandwidth 14.6 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_19500 = 0x1D, //!< Bandwidth 19.5 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_23400 = 0x15, //!< Bandwidth 23.4 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_29300 = 0x0D, //!< Bandwidth 29.3 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_39000 = 0x1C, //!< Bandwidth 39.0 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_46900 = 0x14, //!< Bandwidth 46.9 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_58600 = 0x0C, //!< Bandwidth 58.6 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_78200 = 0x1B, //!< Bandwidth 78.2 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_93800 = 0x13, //!< Bandwidth 93.8 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_117300 = 0x0B, //!< Bandwidth 117.3 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_156200 = 0x1A, //!< Bandwidth 156.2 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_187200 = 0x12, //!< Bandwidth 187.2 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_234300 = 0x0A, //!< Bandwidth 232.3 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_312000 = 0x19, //!< Bandwidth 312.0 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_373600 = 0x11, //!< Bandwidth 373.6 kHz DSB
LR1121_MODEM_RADIO_GFSK_BW_467000 = 0x09 //!< Bandwidth 467.0 kHz DSB
} lr1121_modem_radio_gfsk_bw_t;
/*!
* @brief Possible automatic actions when Channel Activity Detection operations terminate
*
* For RADIO_EXIT_MODE_CAD_RX, LR1121 enters RX mode on activity detected. The timeout value for this RX operation is
* defined as:
*
* \f$ 31.25us \times timeout \f$
*
* With \f$ timeout \f$ defined in RadioCadParams_t::timeout
*
* If the CAD operation is negative with RADIO_CAD_EXIT_MODE_RX or if CAD operation is positive with
* RADIO_CAD_EXIT_MODE_TX, therefore the LR1121 enters Standby RC mode.
*/
typedef enum
{
LR1121_MODEM_RADIO_CAD_EXIT_MODE_STANDBYRC = 0x00, //!< Enter standby RC mode after CAD operation
LR1121_MODEM_RADIO_CAD_EXIT_MODE_RX = 0x01, //!< Enter in RX mode if an activity is detected
LR1121_MODEM_RADIO_CAD_EXIT_MODE_TX = 0x10, //!< Enter in TX mode if no activity is detected
} lr1121_modem_radio_cad_exit_mode_t;
/*!
* @brief Pulse shape configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_GFSK_PULSE_SHAPE_OFF = 0x00, //!< No filter applied
LR1121_MODEM_RADIO_GFSK_PULSE_SHAPE_BT_03 = 0x08, //!< Gaussian BT 0.3
LR1121_MODEM_RADIO_GFSK_PULSE_SHAPE_BT_05 = 0x09, //!< Gaussian BT 0.5
LR1121_MODEM_RADIO_GFSK_PULSE_SHAPE_BT_07 = 0x0A, //!< Gaussian BT 0.7
LR1121_MODEM_RADIO_GFSK_PULSE_SHAPE_BT_1 = 0x0B //!< Gaussian BT 1.0
} lr1121_modem_radio_gfsk_pulse_shape_t;
/*!
* @brief BPSK pulse shape configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_DBPSK_PULSE_SHAPE = 0x16, //!< Double OSR / RRC / BT 0.7
} lr1121_modem_radio_bpsk_pulse_shape_t;
/*!
* @brief LR-FHSS bitrate configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LR_FHSS_BITRATE_488_BPS =
( int ) ( LR1121_MODEM_RADIO_LR_FHSS_BITRATE_DIVIDE_BY_256 +
LR1121_MODEM_RADIO_LR_FHSS_BITRATE_IN_256_BPS_STEPS ), //!< 488.28215 bps
} lr1121_modem_radio_lr_fhss_bitrate_t;
/*!
* @brief LR-FHSS pulse shape configurations
*/
typedef enum
{
LR1121_MODEM_RADIO_LR_FHSS_PULSE_SHAPE_BT_1 = 0x0B //!< Gaussian BT 1.0
} lr1121_modem_radio_lr_fhss_pulse_shape_t;
/*!
* @brief Channel Activity Detection parameters
*
* Parameters detPeak and detMin are to be used for tuning the sensitivity of Channel Activity Detection. It depends on
* Spreading Factor, Bandwidth and symbolNum.
*
* For detPeak, the 5 MSBits are encoding the integer part, the 3 LSBits are encoding 1/8 of the decimal part. For
* instance, \f$detPeak = 50\f$ (= 0x32) leads to a ratio being \f$6 + 2 * 1/8 = 6.25\f$.
*
* detMin is unit free and represents the ratio between the minimal power of a correlation peak and measurement gain
* that can be considered as a peak detection. It helps to avoid detection on noise. Authorized values a from 0 to 181.
*/
typedef struct lr1121_modem_radio_cad_params_s
{
uint8_t cad_symb_nb; //!< Number of symbols used for CAD detection
uint8_t cad_detect_peak; //!< Ratio for CAD between correlator peak and average
//!< (Default 0x32)
uint8_t cad_detect_min; //!< Minimum power of the correlation peak to be
//!< considered as a positive CAD (Default 0x0A)
lr1121_modem_radio_cad_exit_mode_t cad_exit_mode; //!< Automated action on CAD completion
uint32_t cad_timeout; //!< Value used to compute timeout
} lr1121_modem_radio_cad_params_t;
/*!
* @brief Status of GFSK received packet
*/
typedef struct lr1121_modem_radio_pkt_status_gfsk_s
{
int8_t rssi_sync_in_dbm; //!< RSSI value latched on detection of the last received packet Sync Address
int8_t rssi_avg_in_dbm; //!< RSSI averaged over the payload of the last received packet
uint8_t rx_len_in_bytes; //!< Length of the last received packet [Bytes]
bool is_addr_err; //!< Address filtering status. Asserted if received packet address does not match node address
//!< nor broadcast address
bool is_crc_err; //!< CRC status of the current packet (applicable only in RX, with CRC enabled)
bool is_len_err; //!< Asserted when the length of last received packet is greater than the maximal length
//!< (applicable only in RX with variable length packet)
bool is_abort_err; //!< Asserted when the current packet has been aborted (applicable in RX and TX)
bool is_received; //!< Asserted when packet reception is done (applicable in RX)
bool is_sent; //!< Asserted when packet transmission is done (applicable in TX)
} lr1121_modem_radio_pkt_status_gfsk_t;
/*!
* @brief Status of received packet
*/
typedef struct lr1121_modem_radio_pkt_status_lora_s
{
int8_t rssi_pkt_in_dbm; //!< Average RSSI over last received packet.
int8_t snr_pkt_in_db; //!< SNR estimated on last received packet.
int8_t signal_rssi_pkt_in_dbm; //!< RSSI of last packet latched after
} lr1121_modem_radio_pkt_status_lora_t;
/*!
* @brief Length and offset of received packet
*/
typedef struct lr1121_modem_radio_rx_buffer_status_s
{
uint8_t pld_len_in_bytes; //!< Length of received packet [Bytes]
uint8_t buffer_start_pointer; //!< Offset in the reception buffer of
//!< first byte received [Bytes]
} lr1121_modem_radio_rx_buffer_status_t;
/*!
* @brief GFSK packet statistic structure
*/
typedef struct lr1121_modem_radio_stats_gfsk_s
{
uint16_t nb_pkt_received; //!< Total number of received packets
uint16_t nb_pkt_crc_error; //!< Total number of received packets with CRC error
uint16_t nb_pkt_len_error; //!< Total number of received packets with a length error
} lr1121_modem_radio_stats_gfsk_t;
/*!
* @brief LoRa packet statistic structure
*/
typedef struct lr1121_modem_radio_stats_lora_s
{
uint16_t nb_pkt_received; //!< Total number of received packets
uint16_t nb_pkt_crc_error; //!< Total number of received packets with CRC error
uint16_t nb_pkt_header_error; //!< Total number of packets with header error
uint16_t nb_pkt_falsesync; //!< Total number of false sync
} lr1121_modem_radio_stats_lora_t;
/*!
* @brief Modulation configuration for GFSK packet
*/
typedef struct lr1121_modem_radio_mod_params_gfsk_s
{
uint32_t br_in_bps; //!< GFSK bitrate [bit/s]
lr1121_modem_radio_gfsk_pulse_shape_t pulse_shape; //!< GFSK pulse shape
lr1121_modem_radio_gfsk_bw_t bw_dsb_param; //!< GFSK bandwidth
uint32_t fdev_in_hz; //!< GFSK frequency deviation [Hz]
} lr1121_modem_radio_mod_params_gfsk_t;
/*!
* @brief Modulation configuration for BPSK packet
*/
typedef struct lr1121_modem_radio_mod_params_bpsk_s
{
uint32_t br_in_bps; //!< BPSK bitrate [bit/s]
lr1121_modem_radio_bpsk_pulse_shape_t pulse_shape; //!< BPSK pulse shape
} lr1121_modem_radio_mod_params_bpsk_t;
/*!
* @brief Modulation configuration for LoRa packet
*/
typedef struct lr1121_modem_radio_mod_params_lora_s
{
lr1121_modem_radio_lora_sf_t sf; //!< LoRa spreading factor
lr1121_modem_radio_lora_bw_t bw; //!< LoRa bandwidth
lr1121_modem_radio_lora_cr_t cr; //!< LoRa coding rate
uint8_t ldro; //!< LoRa LDRO
} lr1121_modem_radio_mod_params_lora_t;
/*!
* @brief Modulation configuration for LR-FHSS packets
*/
typedef struct lr1121_modem_radio_mod_params_lr_fhss_s
{
lr1121_modem_radio_lr_fhss_bitrate_t br_in_bps; //!< LR-FHSS bitrate
lr1121_modem_radio_lr_fhss_pulse_shape_t pulse_shape; //!< LR-FHSS pulse shape
} lr1121_modem_radio_mod_params_lr_fhss_t;
/*!
* @brief Packet parameter configuration for GFSK packets
*/
typedef struct lr1121_modem_radio_pkt_params_gfsk_s
{
uint16_t preamble_len_in_bits; //!< GFSK Preamble length [bits]
lr1121_modem_radio_gfsk_preamble_detector_t preamble_detector; //!< GFSK Preamble detection configuration
uint8_t sync_word_len_in_bits; //!< GFSK Syncword length [bits]
lr1121_modem_radio_gfsk_address_filtering_t address_filtering; //!< GFSK Address filtering/comparison configuration
lr1121_modem_radio_gfsk_pkt_len_modes_t header_type; //!< GFSK Header type configuration
uint8_t pld_len_in_bytes; //!< GFSK Payload length [bytes]
lr1121_modem_radio_gfsk_crc_type_t crc_type; //!< GFSK CRC configuration
lr1121_modem_radio_gfsk_dc_free_t dc_free; //!< GFSK Whitening configuration
} lr1121_modem_radio_pkt_params_gfsk_t;
/*!
* @brief Packet parameter configuration for BPSK packets
*/
typedef struct lr1121_modem_radio_pkt_params_bpsk_s
{
uint8_t pld_len_in_bytes; //!< Payload length [bytes]
uint16_t ramp_up_delay; //!< Delay to fine tune ramp-up time, if non-zero
uint16_t ramp_down_delay; //!< Delay to fine tune ramp-down time, if non-zero
uint16_t pld_len_in_bits; //!< If non-zero, used to ramp down PA before end of a payload with length that is not a
//!< multiple of 8. pld_len_in_bits <= pld_len_in_bytes * 8
} lr1121_modem_radio_pkt_params_bpsk_t;
/*!
* @brief Packet parameter configuration for LoRa packets
*/
typedef struct lr1121_modem_radio_pkt_params_lora_s
{
uint16_t preamble_len_in_symb; //!< LoRa Preamble length [symbols]
lr1121_modem_radio_lora_pkt_len_modes_t header_type; //!< LoRa Header type configuration
uint8_t pld_len_in_bytes; //!< LoRa Payload length [bytes]
lr1121_modem_radio_lora_crc_t crc; //!< LoRa CRC configuration
lr1121_modem_radio_lora_iq_t iq; //!< LoRa IQ configuration
} lr1121_modem_radio_pkt_params_lora_t;
/*!
* @brief Configuration of Power Amplifier
*
* @p pa_duty_cycle controls the duty cycle of Power Amplifier according to:
* \f$ dutycycle = 0.2 + 0.04 \times pa\_duty\_cycle \f$
* It can be used to adapt the TX multi-band operation using a single-matching network.
*
* The allowed duty cycle values for LPA are from 0.2 to 0.48 (by step of 0.04). Therefore possible values for
* pa_duty_cycle go from 0 to 7.
*
* The allowed duty cycle values for HPA go from 0.2 to 0.36 (by step of 0.04). Therefore in this case, the possible
* values for pa_duty_cycle go from 0 to 4.
*
* @p pa_hp_sel controls the number of slices for HPA according to: \f$ \#slices = pa\_hp\_sel + 1 \f$
*/
typedef struct lr1121_modem_radio_pa_cfg_s
{
lr1121_modem_radio_pa_selection_t pa_sel; //!< Power Amplifier selection
lr1121_modem_radio_pa_reg_supply_t pa_reg_supply; //!< Power Amplifier regulator supply source
uint8_t pa_duty_cycle; //!< Power Amplifier duty cycle (Default 0x04)
uint8_t pa_hp_sel; //!< Number of slices for HPA (Default 0x07)
} lr1121_modem_radio_pa_cfg_t;
/*!
* @brief RSSI calibration table
*/
typedef struct lr1121_modem_radio_rssi_calibration_table_s
{
struct
{
uint8_t g4;
uint8_t g5;
uint8_t g6;
uint8_t g7;
uint8_t g8;
uint8_t g9;
uint8_t g10;
uint8_t g11;
uint8_t g12;
uint8_t g13;
uint8_t g13hp1;
uint8_t g13hp2;
uint8_t g13hp3;
uint8_t g13hp4;
uint8_t g13hp5;
uint8_t g13hp6;
uint8_t g13hp7;
} gain_tune; //!< Used to set gain tune value for RSSI calibration
int16_t gain_offset; //!< Used to set gain offset value for RSSI calibration
} lr1121_modem_radio_rssi_calibration_table_t;
/*!
* @brief Values to use to setup LNA LF0 configuration
*
* LNA can be configured in either of the 3 modes: Single N, Single P or differential (which is default)
*
*/
typedef enum
{
LR1121_MODEM_RADIO_LNA_MODE_SINGLE_RFI_N_LF0 = 1, //!< Use only RFI_N_LF0 antenna
LR1121_MODEM_RADIO_LNA_MODE_SINGLE_RFI_P_LF0 = 2, //!< Use only RFI_P_LF0 antenna
LR1121_MODEM_RADIO_LNA_MODE_DIFFERENTIAL_LF0 = 3 //!< Configure LNA LF0 in differential mode (default)
} lr1121_modem_radio_lna_mode_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_RADIO_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,209 @@
/*!
* @file lr1121_modem_regmem.h
*
* @brief Register/memory driver definition for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_REGMEM_H
#define LR1121_MODEM_REGMEM_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr1121_modem_common.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Maximum number of words that can be written to / read from a LR1121 chip with regmem32 commands
*/
#define LR1121_MODEM_REGMEM_MAX_WRITE_READ_WORDS 64
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Write up to 64 words into register memory space of LR1121.
*
* A word is 32-bit long. The writing operations write contiguously in register memory, starting at the address
* provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start writing operation
* @param [in] buffer The buffer of words to write into memory. Its size must be enough to contain length words.
* @param [in] length Number of words to write into memory
*
* @returns Operation status
*
* @see lr1121_modem_regmem_read_regmem32
*/
lr1121_modem_response_code_t lr1121_modem_regmem_write_regmem32( const void* context, const uint32_t address,
const uint32_t* buffer, const uint8_t length );
/*!
* @brief Read up to 64 words into register memory space of LR1121.
*
* A word is 32-bit long. The reading operations read contiguously from register memory, starting at the address
* provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start reading operation
* @param [in] length Number of words to read from memory
* @param [out] buffer Pointer to a words array to be filled with content from memory. Its size must be enough to
* contain at least length words.
*
* @returns Operation status
*
* @see lr1121_modem_regmem_write_regmem32
*/
lr1121_modem_response_code_t lr1121_modem_regmem_read_regmem32( const void* context, const uint32_t address,
uint32_t* buffer, const uint8_t length );
/*!
* @brief Write bytes into register memory space of LR1121.
*
* A byte is 8-bit long. The writing operations write contiguously in register memory, starting at the address provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start writing operation
* @param [in] buffer The buffer of bytes to write into memory. Its size must be enough to contain length bytes
* @param [in] length Number of bytes to write into memory
*
* @returns Operation status
*
* @see lr1121_modem_regmem_read_mem8
*/
lr1121_modem_response_code_t lr1121_modem_regmem_write_mem8( const void* context, const uint32_t address,
const uint8_t* buffer, const uint8_t length );
/*!
* @brief Read bytes into register memory space of LR1121.
*
* A byte is 8-bit long. The reading operations read contiguously from register memory, starting at the address
* provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start reading operation
* @param [in] length Number of bytes to read from memory
* @param [in] buffer Pointer to a byte array to be filled with content from memory. Its size must be enough to contain
* at least length bytes
*
* @returns Operation status
*
* @see lr1121_modem_regmem_write_mem8
*/
lr1121_modem_response_code_t lr1121_modem_regmem_read_mem8( const void* context, const uint32_t address,
uint8_t* buffer, const uint8_t length );
/*!
* @brief Write bytes into radio TX buffer memory space of LR1121.
*
* @param [in] context Chip implementation context
* @param [in] buffer The buffer of bytes to write into radio buffer. Its size must be enough to contain length bytes
* @param [in] length Number of bytes to write into radio buffer
*
* @returns Operation status
*
* @see lr1121_modem_regmem_read_buffer8
*/
lr1121_modem_response_code_t lr1121_modem_regmem_write_buffer8( const void* context, const uint8_t* buffer,
const uint8_t length );
/*!
* @brief Read bytes from radio RX buffer memory space of LR1121.
*
* @param [in] context Chip implementation context
* @param [in] buffer Pointer to a byte array to be filled with content from radio buffer. Its size must be enough to
* contain at least length bytes
* @param [in] offset Memory offset to start reading
* @param [in] length Number of bytes to read from radio buffer
*
* @returns Operation status
*
* @see lr1121_modem_regmem_write_buffer8
*/
lr1121_modem_response_code_t lr1121_modem_regmem_read_buffer8( const void* context, uint8_t* buffer,
const uint8_t offset, const uint8_t length );
/*!
* @brief Clear radio RX buffer
*
* Set to 0x00 all content of the radio RX buffer
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_regmem_clear_rxbuffer( const void* context );
/*!
* @brief Read-modify-write data at given register/memory address
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to be modified
* @param [in] mask The mask to be applied on read data
* @param [in] data The data to be written
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_regmem_write_regmem32_mask( const void* context, const uint32_t address,
const uint32_t mask, const uint32_t data );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_REGMEM_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,99 @@
/*!
* @file lr1121_modem_relay.h
*
* @brief Relay driver for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_RELAY_H
#define LR1121_MODEM_RELAY_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_common.h"
#include "lr1121_modem_relay_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Get the Tx relay configuration
*
* @param [in] context Chip implementation context
* @param [out] configuration Tx relay configuration
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_relay_get_tx_config( const void* context,
lr1121_modem_relay_tx_configuration_t* configuration );
/*!
* @brief Set the Tx relay configuration
*
* @param [in] context Chip implementation context
* @param [out] configuration Tx relay configuration to set
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_relay_set_tx_config(
const void* context, const lr1121_modem_relay_tx_configuration_t* configuration );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_RELAY_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,127 @@
/*!
* @file lr1121_modem_relay_types.h
*
* @brief Relay driver types for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_RELAY_TYPES_H
#define LR1121_MODEM_RELAY_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief Relay activation
*
* Refer to LoRaWAN Relay specification document for details.
*/
typedef enum
{
LR1121_MODEM_RELAY_ACTIVATION_DISABLE = 0x00, //!< The relay is disabled
LR1121_MODEM_RELAY_ACTIVATION_ENABLE =
0x01, //!< The relay is enabled, even if no WOR ack nor downlink on RxR is received
LR1121_MODEM_RELAY_ACTIVATION_DYNAMIC =
0x02, //!< The device automatically enable the relay if no downlink is received after several uplinks
LR1121_MODEM_RELAY_ACTIVATION_DEVICE_CONTROLLED = 0x03, //!< The device automatically enable or disable the relay
} lr1121_modem_relay_activation_t;
/**
* @brief Smart level configuration
*
* Refer to LoRaWAN Relay specification document for details.
*/
typedef enum
{
LR1121_MODEM_RELAY_SMART_LEVEL_8 =
0x00, //!< The relay shall be enabled if no valid downlink is received during 8 consecutive uplinks
LR1121_MODEM_RELAY_SMART_LEVEL_16 =
0x01, //!< The relay shall be enabled if no valid downlink is received during 16 consecutive uplinks
LR1121_MODEM_RELAY_SMART_LEVEL_32 =
0x02, //!< The relay shall be enabled if no valid downlink is received during 32 consecutive uplinks
LR1121_MODEM_RELAY_SMART_LEVEL_64 =
0x03, //!< The relay shall be enabled if no valid downlink is received during 64 consecutive uplinks
} lr1121_modem_relay_smart_level_t;
/**
* @brief Configuration of relay Tx
*/
typedef struct
{
uint32_t wor_second_channel_frequency_hz; //!< Frequency of the second Wake On Radio channel (Hz)
uint32_t
wor_ack_second_channel_frequency_hz; //!< Frequency of the second Wake On Radio acknowledgment channel (Hz)
uint8_t wor_second_channel_datarate; //!< Datarate of the second Wake On Radio chanel
uint8_t wor_second_channel_enable; //!< Wake On Radio second channel enable
uint8_t backoff_behavior; //!< Indicate number of missed ACK tolerated before sending the LoRaWAN uplink. Possible
//!< values in [0:63] (0 means the LoRaWAN uplink is always sent)
lr1121_modem_relay_activation_t activation; //!< Relay activation configuration
lr1121_modem_relay_smart_level_t smart_level; //!< Smart level configuration. Only valid if @ref activation is set
//!< to @ref LR1121_MODEM_RELAY_ACTIVATION_DYNAMIC
uint8_t missed_ack_to_unsynchronized_threshold; //!< Number of consecutively WOR ACK to miss before switching to
//!< unsynchronized state
} lr1121_modem_relay_tx_configuration_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_RELAY_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,606 @@
/*!
* @file lr1121_modem_system.h
*
* @brief System driver definition for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_SYSTEM_H
#define LR1121_MODEM_SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
#include "lr1121_modem_common.h"
#include "lr1121_modem_system_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*!
* @brief Frequency step in MHz used to compute the image calibration parameter
*
* @see lr1121_modem_system_calibrate_image_in_mhz
*/
#define LR1121_MODEM_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ 4
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Reset the radio
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_reset( const void* context );
/**
* @brief Wake the radio up from sleep mode.
*
* @param [in] context Chip implementation context.
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_wakeup( const void* context );
/*!
* @brief Return stat1, stat2, and irq_status
*
* @param [in] context Chip implementation context
* @param [out] stat1 Pointer to a variable for holding stat1. Can be NULL.
* @param [out] stat2 Pointer to a variable for holding stat2. Can be NULL.
* @param [out] irq_status Pointer to a variable for holding irq_status. Can be NULL.
*
* @returns Operation status
*
* @remark To simplify system integration, this function does not actually execute the GetStatus command, which would
* require bidirectional SPI communication. It obtains the stat1, stat2, and irq_status values by performing an ordinary
* SPI read (which is required to send null/NOP bytes on the MOSI line). This is possible since the LR1121 returns these
* values automatically whenever a read that does not directly follow a response-carrying command is performed.
* Unlike with the GetStatus command, however, the reset status information is NOT cleared by this command. The function
* @ref lr1121_modem_system_clear_reset_status_info may be used for this purpose when necessary.
*/
lr1121_modem_response_code_t lr1121_modem_system_get_status( const void* context, lr1121_modem_system_stat1_t* stat1,
lr1121_modem_system_stat2_t* stat2,
lr1121_modem_system_irq_mask_t* irq_status );
/*!
* @brief Clear the reset status information stored in stat2
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_clear_reset_status_info( const void* context );
/*!
* @brief Return irq_status
*
* @param [in] context Chip implementation context
* @param [out] irq_status irq_status status variable
*
* @returns Operation status
*/
static inline lr1121_modem_response_code_t lr1121_modem_system_get_irq_status(
const void* context, lr1121_modem_system_irq_mask_t* irq_status )
{
return lr1121_modem_system_get_status( context, 0, 0, irq_status );
}
/*!
* @brief Return the version of the system (hardware and software)
*
* @param [in] context Chip implementation context
* @param [out] version Pointer to the structure holding the system version
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_get_version( const void* context,
lr1121_modem_system_version_t* version );
/*!
* @brief Return the system errors
*
* Errors may be fixed following:
* - calibration error can be fixed by attempting another RC calibration;
* - XOsc related errors may be due to hardware problems, can be fixed by reset;
* - PLL lock related errors can be due to not-locked PLL, or by attempting to use an out-of-band frequency, can be
* fixed by executing a PLL calibration, or by using other frequencies.
*
* @param [in] context Chip implementation context
* @param [out] errors Pointer to a value holding error flags
*
* @returns Operation status
*
* @see lr1121_modem_system_calibrate, lr1121_modem_system_calibrate_image, lr1121_modem_system_clear_errors
*/
lr1121_modem_response_code_t lr1121_modem_system_get_errors( const void* context, uint16_t* errors );
/*!
* @brief Clear all error flags pending.
*
* This function cannot be used to clear flags individually.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*
* @see lr1121_modem_system_get_errors
*/
lr1121_modem_response_code_t lr1121_modem_system_clear_errors( const void* context );
/*!
* @brief lr1121_modem_system_calibrate the requested blocks
*
* This function can be called in any mode of the chip.
*
* The chip will return to standby RC mode on exit. Potential calibration issues can be read out with
* lr1121_modem_system_get_errors command.
*
* @param [in] context Chip implementation context
* @param [in] calib_param Structure holding the reference to blocks to be calibrated
*
* @returns Operation status
*
* @see lr1121_modem_system_get_errors
*/
lr1121_modem_response_code_t lr1121_modem_system_calibrate( const void* context, const uint8_t calib_param );
/*!
* @brief Configure the regulator mode to be used in specific modes
*
* This function shall only be called in standby RC mode.
*
* The reg_mode parameter defines if the DC-DC converter is switched on in the following modes: STANDBY XOSC, FS, RX, TX
* and RX_CAPTURE.
*
* @param [in] context Chip implementation context
* @param [in] reg_mode Regulator mode configuration
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_set_reg_mode( const void* context,
const lr1121_modem_system_reg_mode_t reg_mode );
/*!
* @brief Launch an image calibration valid for all frequencies inside an interval, in steps
*
* This function can be called in any mode of the chip.
*
* The chip will return to standby RC mode on exit. Potential calibration issues can be read out with
* lr1121_modem_system_get_errors command.
*
* The frequencies given in parameters are defined in 4MHz step (Eg. 900MHz corresponds to 0xE1). If freq1 = freq2, only
* one calibration is performed.
*
* @param [in] context Chip implementation context
* @param [in] freq1 Image calibration interval lower bound, in steps
* @param [in] freq2 Image calibration interval upper bound, in steps
*
* @remark freq1 must be less than or equal to freq2
*
* @returns Operation status
*
* @see lr1121_modem_system_get_errors
*/
lr1121_modem_response_code_t lr1121_modem_system_calibrate_image( const void* context, const uint8_t freq1,
const uint8_t freq2 );
/*!
* @brief Launch an image calibration valid for all frequencies inside an interval, in MHz
*
* @remark This function relies on @ref lr1121_modem_system_calibrate_image
*
* @param [in] context Chip implementation context
* @param [in] freq1_in_mhz Image calibration interval lower bound, in MHz
* @param [in] freq2_in_mhz Image calibration interval upper bound, in MHz
*
* @remark freq1 must be less than or equal to freq2
*
* @returns Operation status
*
* @see lr1121_modem_system_calibrate_image
*/
lr1121_modem_response_code_t lr1121_modem_system_calibrate_image_in_mhz( const void* context,
const uint16_t freq1_in_mhz,
const uint16_t freq2_in_mhz );
/*!
* @brief Set the RF switch configurations for each RF setup
*
* This function shall only be called in standby RC mode.
*
* By default, no DIO is used to control a RF switch. All DIOs are set in High-Z mode.
*
* @param [in] context Chip implementation context
* @param [in] rf_switch_cfg Pointer to a structure that holds the switches configuration
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_set_dio_as_rf_switch(
const void* context, const lr1121_modem_system_rfswitch_cfg_t* rf_switch_cfg );
/*!
* @brief Set which interrupt signals are redirected to the dedicated DIO pin
*
* By default, no interrupt signal is redirected.
*
* The dedicated DIO pin will remain asserted until all redirected interrupt signals are cleared with a call to
* lr1121_modem_system_clear_irq_status.
*
* @param [in] context Chip implementation context
* @param [in] irqs_to_enable_dio1 Variable that holds the interrupt mask for dio1
* @param [in] irqs_to_enable_dio2 Variable that holds the interrupt mask for dio2
*
* @returns Operation status
*
* @see lr1121_modem_system_clear_irq_status
*/
lr1121_modem_response_code_t lr1121_modem_system_set_dio_irq_params(
const void* context, const lr1121_modem_system_irq_mask_t irqs_to_enable_dio1,
const lr1121_modem_system_irq_mask_t irqs_to_enable_dio2 );
/*!
* @brief Clear requested bits in the internal pending interrupt register
*
* @param [in] context Chip implementation context
* @param [in] irqs_to_clear Variable that holds the interrupts to be cleared
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_clear_irq_status( const void* context,
const lr1121_modem_system_irq_mask_t irqs_to_clear );
/**
* @brief This helper function clears any radio irq status flags that are set and returns the flags that were cleared.
*
* @param [in] context Chip implementation context.
* @param [out] irq Pointer to a variable for holding the system interrupt status. Can be NULL.
*
* @returns Operation status
*
* @see lr1121_modem_system_get_irq_status, lr1121_modem_system_clear_irq_status
*/
lr1121_modem_response_code_t lr1121_modem_system_get_and_clear_irq_status( const void* context,
lr1121_modem_system_irq_mask_t* irq );
/*!
* @brief Defines which clock is used as Low Frequency (LF) clock
*
* @param [in] context Chip implementation context
* @param [in] lfclock_cfg Low frequency clock configuration
* @param [in] wait_for_32k_ready Tells the radio if it has to check if 32k source is ready before driving busy low
*
* @returns Operation status
*
* @see lr1121_modem_system_calibrate, lr1121_modem_system_calibrate_image
*/
lr1121_modem_response_code_t lr1121_modem_system_cfg_lfclk( const void* context,
const lr1121_modem_system_lfclk_cfg_t lfclock_cfg,
const bool wait_for_32k_ready );
/*!
* @brief Enable and configure TCXO supply voltage and detection timeout
*
* This function shall only be called in standby RC mode.
*
* The timeout parameter is the maximum time the firmware waits for the TCXO to be ready. The timeout duration is given
* by: \f$ timeout\_duration\_us = timeout \times 30.52 \f$
*
* The TCXO mode can be disabled by setting timeout parameter to 0.
*
* @param [in] context Chip implementation context
* @param [in] tune Supply voltage value
* @param [in] timeout Gating time before which the radio starts its Rx / Tx operation
*
* @returns Operation status
*
* @see lr1121_modem_system_calibrate, lr1121_modem_system_calibrate_image
*/
lr1121_modem_response_code_t lr1121_modem_system_set_tcxo_mode( const void* context,
const lr1121_modem_system_tcxo_supply_voltage_t tune,
const uint32_t timeout );
/*!
* @brief Software reset of the chip.
*
* This function should be used to reboot the chip in a specified mode. Rebooting in flash mode presumes that the
* content in flash memory is not corrupted (i.e. the integrity check performed by the bootloader before executing the
* first instruction in flash is OK).
*
* @param [in] context Chip implementation context
* @param [in] stay_in_bootloader Selector to stay in bootloader or execute flash code after reboot. If true, the
* bootloader will not execute the flash code but activate SPI interface to allow firmware upgrade
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_reboot( const void* context, const bool stay_in_bootloader );
/*!
* @brief Returns the value of Vbat
*
* Vbat value (in V) is a function of Vana (typ. 1.35V) using the following
* formula: \f$ Vbat_{V} = (5 \times \frac{Vbat}{255} - 1) \times Vana \f$
*
* @param [in] context Chip implementation context
* @param [out] vbat A pointer to the Vbat value
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_get_vbat( const void* context, uint8_t* vbat );
/*!
* @brief Returns the value of Temp
*
* The temperature (in °C) is a function of Vana (typ. 1.35V), Vbe25 (Vbe voltage @ 25°C, typ. 0.7295V) and VbeSlope
* (typ. -1.7mV/°C) using the following formula:
* \f$ Temperature_{°C} = (\frac{Temp(10:0)}{2047} \times Vana - Vbe25) \times \frac{1000}{VbeSlope} + 25 \f$
*
* @remark If a TCXO is used, make sure to configure it with @ref lr1121_modem_system_set_tcxo_mode before calling this
* function
*
* @param [in] context Chip implementation context
* @param [out] temp A pointer to the Temp value
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_get_temp( const void* context, uint16_t* temp );
/*!
* @brief Set the device into Sleep or Deep Sleep Mode
*
* The \p sleep_cfg parameter defines in which sleep mode is to use.
*
* The \p sleep_time parameter sets the sleep duration in number of clock cycles:
* \f$ sleep\_time\_ms = sleep\_time \times \frac{1}{32.768} \f$
*
* @param [in] context Chip implementation context
* @param [in] sleep_cfg Sleep mode configuration
* @param [in] sleep_time Value of the RTC timeout (if RtcTimeout = 1)
*
* @returns Operation status
*
* @see lr1121_modem_system_set_standby, lr1121_modem_system_set_fs
*/
lr1121_modem_response_code_t lr1121_modem_system_set_sleep( const void* context,
const lr1121_modem_system_sleep_cfg_t sleep_cfg,
const uint32_t sleep_time );
/*!
* @brief Set the device into the requested Standby mode
*
* @param [in] context Chip implementation context
* @param [in] standby_cfg Stand by mode configuration (RC or XOSC)
*
* @returns Operation status
*
* @see lr1121_modem_system_set_sleep, lr1121_modem_system_set_fs
*/
lr1121_modem_response_code_t lr1121_modem_system_set_standby( const void* context,
const lr1121_modem_system_standby_cfg_t standby_cfg );
/*!
* @brief Set the device into Frequency Synthesis (FS) mode
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*
* @see lr1121_modem_system_set_standby, lr1121_modem_system_set_sleep
*/
lr1121_modem_response_code_t lr1121_modem_system_set_fs( const void* context );
/*!
* @brief Erase an info page
*
* @param [in] context Chip implementation context
* @param [in] info_page_id Info page to be erased. Only LR1121_MODEM_SYSTEM_INFOPAGE_1 is allowed.
*
* @returns Operation status
*
* @see lr1121_modem_system_write_infopage, lr1121_modem_system_read_infopage
*/
lr1121_modem_response_code_t lr1121_modem_system_erase_infopage( const void* context,
const lr1121_modem_system_infopage_id_t info_page_id );
/*!
* @brief Write data in an info page
*
* @param [in] context Chip implementation context
* @param [in] info_page_id Info page where data are written. Only LR1121_MODEM_SYSTEM_INFOPAGE_1 is allowed.
* @param [in] address Address within the info page (aligned on 32-bit data)
* @param [in] data Pointer to the data to write (data buffer shall be - at least - length words long)
* @param [in] length Number of 32-bit data to write (maximum value is 64)
*
* @returns Operation status
*
* @see lr1121_modem_system_erase_infopage, lr1121_modem_system_read_infopage
*/
lr1121_modem_response_code_t lr1121_modem_system_write_infopage( const void* context,
const lr1121_modem_system_infopage_id_t info_page_id,
const uint16_t address, const uint32_t* data,
const uint8_t length );
/*!
* @brief Read data from an info page
*
* It is possible to cross from page 0 to 1 if (address + length >= 512)
*
* @param [in] context Chip implementation context
* @param [in] info_page_id Info page where data are read
* @param [in] address Address within the info page (aligned on 32-bit data)
* @param [out] data Pointer to the data to read (data buffer shall be - at least - length words long)
* @param [in] length Number of 32-bit data to read (maximum value is 64)
*
* @returns Operation status
*
* @see lr1121_modem_system_erase_infopage, lr1121_modem_system_write_infopage
*/
lr1121_modem_response_code_t lr1121_modem_system_read_infopage( const void* context,
const lr1121_modem_system_infopage_id_t info_page_id,
const uint16_t address, uint32_t* data,
const uint8_t length );
/*!
* @brief Read and return the Unique Identifier of the LR1121
*
* @param [in] context Chip implementation context
* @param [out] unique_identifier The buffer to be filled with the Unique Identifier of the LR1121. It is up to the
* application to ensure unique_identifier is long enough to hold the unique identifier
*
* @returns Operation status
*
* @see LR1121_MODEM_SYSTEM_UID_LENGTH
*/
lr1121_modem_response_code_t lr1121_modem_system_read_uid( const void* context,
lr1121_modem_system_uid_t unique_identifier );
/*!
* @brief Read and return the Join EUI of the LR1121
*
* @param [in] context Chip implementation context
* @param [out] join_eui The buffer to be filled with Join EUI of the LR1121. It is up to the application to ensure
* join_eui is long enough to hold the join EUI
*
* @returns Operation status
*
* @see LR1121_MODEM_SYSTEM_JOIN_EUI_LENGTH
*/
lr1121_modem_response_code_t lr1121_modem_system_read_join_eui( const void* context,
lr1121_modem_system_join_eui_t join_eui );
/*!
* @brief Compute and return the PIN of the LR1121 based on factory default EUIs
*
* @remark Calling this command also triggers a derivation of network and application keys based on factory default EUIs
*
* @param [in] context Chip implementation context
* @param [out] pin The buffer to be filled with PIN of the LR1121. It is up to the application to ensure pin is long
* enough to hold the PIN
*
* @returns Operation status
*
* @see LR1121_MODEM_SYSTEM_PIN_LENGTH
*/
lr1121_modem_response_code_t lr1121_modem_system_read_pin( const void* context, lr1121_modem_system_pin_t pin );
/*!
* @brief Compute and return the PIN of the LR1121 based on EUIs provided as parameters
*
* @remark Calling this command also triggers a derivation of network and application keys based on EUIs provided as
* parameters
*
* @param [in] context Chip implementation context
* @param [in] device_eui Custom Device EUI
* @param [in] join_eui Custom Join EUI
* @param [in] rfu Parameter RFU - shall be set to 0x00
* @param [out] pin The buffer to be filled with PIN of the LR1121. It is up to the application to ensure pin is long
* enough to hold the PIN
*
* @returns Operation status
*
* @see LR1121_MODEM_SYSTEM_PIN_LENGTH
*/
lr1121_modem_response_code_t lr1121_modem_system_read_pin_custom_eui( const void* context,
lr1121_modem_system_uid_t device_eui,
lr1121_modem_system_join_eui_t join_eui,
uint8_t rfu, lr1121_modem_system_pin_t pin );
/*!
* @brief Read and return a 32-bit random number
*
* @remark Radio operating mode must be set into standby.
*
* @param [in] context Chip implementation context
* @param [out] random_number 32-bit random number
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_get_random_number( const void* context, uint32_t* random_number );
/*!
* @brief Enable the CRC on SPI transactions
*
* @remark This command shall always be sent with a CRC (to both enable and disable the feature). The function does not
* take care of this additional byte - which is under the responsibility of the underlying HAL functions
*
* @param [in] context Chip implementation context
* @param [in] enable_crc CRC
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_enable_spi_crc( const void* context, bool enable_crc );
/*!
* @brief Configure the GPIO drive in sleep mode
*
* @remark GPIO stands for RF switch and IRQ line DIOs
*
* @note This command is available from firmware version 0x0306
*
* @param [in] context Chip implementation context
* @param [in] enable_drive GPIO drive configuration (true: enabled / false: disabled)
*
* @returns Operation status
*/
lr1121_modem_response_code_t lr1121_modem_system_drive_dio_in_sleep_mode( const void* context, bool enable_drive );
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_SYSTEM_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,348 @@
/*!
* @file lr1121_modem_system_types.h
*
* @brief System driver types for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_MODEM_SYSTEM_TYPES_H
#define LR1121_MODEM_SYSTEM_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include <stdbool.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Length of the LR1121 Unique Identifier in bytes
*
* The LR1121 Unique Identifiers is an 8 byte long buffer
*/
#define LR1121_MODEM_SYSTEM_UID_LENGTH ( 8 )
/**
* @brief Length of Join Unique Identifier in bytes
*/
#define LR1121_MODEM_SYSTEM_JOIN_EUI_LENGTH ( 8 )
/**
* @brief Length of PIN number in bytes
*/
#define LR1121_MODEM_SYSTEM_PIN_LENGTH ( 4 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief Fixed-length array to store a UID
*/
typedef uint8_t lr1121_modem_system_uid_t[LR1121_MODEM_SYSTEM_UID_LENGTH];
/**
* @brief Fixed-length array to store a joinEUI
*/
typedef uint8_t lr1121_modem_system_join_eui_t[LR1121_MODEM_SYSTEM_JOIN_EUI_LENGTH];
/**
* @brief Fixed-length array to store a PIN
*/
typedef uint8_t lr1121_modem_system_pin_t[LR1121_MODEM_SYSTEM_PIN_LENGTH];
/**
* @brief Type to store system interrupt flags
*/
typedef uint32_t lr1121_modem_system_irq_mask_t;
/**
* @brief Interrupt flags
*/
enum lr1121_modem_system_irq_e
{
LR1121_MODEM_SYSTEM_IRQ_NONE = ( 0 << 0 ),
LR1121_MODEM_SYSTEM_IRQ_TX_DONE = ( 1 << 2 ),
LR1121_MODEM_SYSTEM_IRQ_RX_DONE = ( 1 << 3 ),
LR1121_MODEM_SYSTEM_IRQ_PREAMBLE_DETECTED = ( 1 << 4 ),
LR1121_MODEM_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID = ( 1 << 5 ),
LR1121_MODEM_SYSTEM_IRQ_HEADER_ERROR = ( 1 << 6 ),
LR1121_MODEM_SYSTEM_IRQ_CRC_ERROR = ( 1 << 7 ),
LR1121_MODEM_SYSTEM_IRQ_CAD_DONE = ( 1 << 8 ),
LR1121_MODEM_SYSTEM_IRQ_CAD_DETECTED = ( 1 << 9 ),
LR1121_MODEM_SYSTEM_IRQ_TIMEOUT = ( 1 << 10 ),
LR1121_MODEM_SYSTEM_IRQ_LR_FHSS_INTRA_PKT_HOP = ( 1 << 11 ),
LR1121_MODEM_SYSTEM_IRQ_EOL = ( 1 << 21 ),
LR1121_MODEM_SYSTEM_IRQ_CMD_ERROR = ( 1 << 22 ),
LR1121_MODEM_SYSTEM_IRQ_ERROR = ( 1 << 23 ),
LR1121_MODEM_SYSTEM_IRQ_FSK_LEN_ERROR = ( 1 << 24 ),
LR1121_MODEM_SYSTEM_IRQ_FSK_ADDR_ERROR = ( 1 << 25 ),
LR1121_MODEM_SYSTEM_IRQ_LORA_RX_TIMESTAMP = ( 1 << 27 ),
LR1121_MODEM_SYSTEM_IRQ_ALL_MASK =
LR1121_MODEM_SYSTEM_IRQ_TX_DONE | LR1121_MODEM_SYSTEM_IRQ_RX_DONE | LR1121_MODEM_SYSTEM_IRQ_PREAMBLE_DETECTED |
LR1121_MODEM_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID | LR1121_MODEM_SYSTEM_IRQ_HEADER_ERROR |
LR1121_MODEM_SYSTEM_IRQ_CRC_ERROR | LR1121_MODEM_SYSTEM_IRQ_CAD_DONE | LR1121_MODEM_SYSTEM_IRQ_CAD_DETECTED |
LR1121_MODEM_SYSTEM_IRQ_TIMEOUT | LR1121_MODEM_SYSTEM_IRQ_LR_FHSS_INTRA_PKT_HOP | LR1121_MODEM_SYSTEM_IRQ_EOL |
LR1121_MODEM_SYSTEM_IRQ_CMD_ERROR | LR1121_MODEM_SYSTEM_IRQ_ERROR | LR1121_MODEM_SYSTEM_IRQ_FSK_LEN_ERROR |
LR1121_MODEM_SYSTEM_IRQ_FSK_ADDR_ERROR | LR1121_MODEM_SYSTEM_IRQ_LORA_RX_TIMESTAMP,
};
/**
* @brief Calibration flags
*/
enum lr1121_modem_system_calibration_e
{
LR1121_MODEM_SYSTEM_CALIB_LF_RC_MASK = ( 1 << 0 ),
LR1121_MODEM_SYSTEM_CALIB_HF_RC_MASK = ( 1 << 1 ),
LR1121_MODEM_SYSTEM_CALIB_PLL_MASK = ( 1 << 2 ),
LR1121_MODEM_SYSTEM_CALIB_ADC_MASK = ( 1 << 3 ),
LR1121_MODEM_SYSTEM_CALIB_IMG_MASK = ( 1 << 4 ),
LR1121_MODEM_SYSTEM_CALIB_PLL_TX_MASK = ( 1 << 5 ),
};
/**
* @brief Type for calibration mask
*
* @see lr1121_modem_system_calibration_e
*/
typedef uint8_t lr1121_modem_system_cal_mask_t;
/**
* @brief Error flags
*/
enum lr1121_modem_system_errors_e
{
LR1121_MODEM_SYSTEM_ERRORS_LF_RC_CALIB_MASK = ( 1 << 0 ),
LR1121_MODEM_SYSTEM_ERRORS_HF_RC_CALIB_MASK = ( 1 << 1 ),
LR1121_MODEM_SYSTEM_ERRORS_ADC_CALIB_MASK = ( 1 << 2 ),
LR1121_MODEM_SYSTEM_ERRORS_PLL_CALIB_MASK = ( 1 << 3 ),
LR1121_MODEM_SYSTEM_ERRORS_IMG_CALIB_MASK = ( 1 << 4 ),
LR1121_MODEM_SYSTEM_ERRORS_HF_XOSC_START_MASK = ( 1 << 5 ),
LR1121_MODEM_SYSTEM_ERRORS_LF_XOSC_START_MASK = ( 1 << 6 ),
LR1121_MODEM_SYSTEM_ERRORS_PLL_LOCK_MASK = ( 1 << 7 ),
};
/**
* @brief Type for system errors mask
*
* @see lr1121_modem_system_errors_e
*/
typedef uint16_t lr1121_modem_system_errors_t;
/**
* @brief Chip modes
*/
typedef enum
{
LR1121_MODEM_SYSTEM_CHIP_MODE_SLEEP = 0x00,
LR1121_MODEM_SYSTEM_CHIP_MODE_STBY_RC = 0x01,
LR1121_MODEM_SYSTEM_CHIP_MODE_STBY_XOSC = 0x02,
LR1121_MODEM_SYSTEM_CHIP_MODE_FS = 0x03,
LR1121_MODEM_SYSTEM_CHIP_MODE_RX = 0x04,
LR1121_MODEM_SYSTEM_CHIP_MODE_TX = 0x05,
LR1121_MODEM_SYSTEM_CHIP_MODE_LOC = 0x06,
} lr1121_modem_system_chip_modes_t;
/**
* @brief Reset status
*/
typedef enum
{
LR1121_MODEM_SYSTEM_RESET_STATUS_CLEARED = 0x00,
LR1121_MODEM_SYSTEM_RESET_STATUS_ANALOG = 0x01,
LR1121_MODEM_SYSTEM_RESET_STATUS_EXTERNAL = 0x02,
LR1121_MODEM_SYSTEM_RESET_STATUS_SYSTEM = 0x03,
LR1121_MODEM_SYSTEM_RESET_STATUS_WATCHDOG = 0x04,
LR1121_MODEM_SYSTEM_RESET_STATUS_IOCD_RESTART = 0x05,
LR1121_MODEM_SYSTEM_RESET_STATUS_RTC_RESTART = 0x06,
} lr1121_modem_system_reset_status_t;
/**
* @brief Command status
*/
typedef enum
{
LR1121_MODEM_SYSTEM_CMD_STATUS_FAIL = 0x00,
LR1121_MODEM_SYSTEM_CMD_STATUS_PERR = 0x01,
LR1121_MODEM_SYSTEM_CMD_STATUS_OK = 0x02,
LR1121_MODEM_SYSTEM_CMD_STATUS_DATA = 0x03,
} lr1121_modem_system_command_status_t;
/**
* @brief Low-frequency clock modes
*/
typedef enum
{
LR1121_MODEM_SYSTEM_LFCLK_RC = 0x00, //!< (Default)
LR1121_MODEM_SYSTEM_LFCLK_XTAL = 0x01,
LR1121_MODEM_SYSTEM_LFCLK_EXT = 0x02
} lr1121_modem_system_lfclk_cfg_t;
/**
* @brief Regulator modes
*/
typedef enum
{
LR1121_MODEM_SYSTEM_REG_MODE_LDO = 0x00, //!< (Default)
LR1121_MODEM_SYSTEM_REG_MODE_DCDC = 0x01,
} lr1121_modem_system_reg_mode_t;
/**
* @brief Info page ID
*/
typedef enum
{
LR1121_MODEM_SYSTEM_INFOPAGE_0 = 0x00, //!< Info page #0
LR1121_MODEM_SYSTEM_INFOPAGE_1 = 0x01, //!< Info page #1
} lr1121_modem_system_infopage_id_t;
/**
* @brief RF switch configuration pin
*/
enum lr1121_modem_system_rfswitch_cfg_pin_e
{
LR1121_MODEM_SYSTEM_RFSW0_HIGH = ( 1 << 0 ),
LR1121_MODEM_SYSTEM_RFSW1_HIGH = ( 1 << 1 ),
LR1121_MODEM_SYSTEM_RFSW2_HIGH = ( 1 << 2 ),
LR1121_MODEM_SYSTEM_RFSW3_HIGH = ( 1 << 3 ),
LR1121_MODEM_SYSTEM_RFSW4_HIGH = ( 1 << 4 ),
};
/**
* @brief RF switch configuration structure definition
*/
typedef struct lr1121_modem_system_rfswitch_cfg_s
{
uint8_t enable; //!< Bitmask for DIO to control as RF switches
uint8_t standby; //!< Bitmask for DIO state while chip is in standby mode
uint8_t rx; //!< Bitmask for DIO state while chip is in reception mode
uint8_t tx; //!< Bitmask for DIO state while chip is in transmission mode
uint8_t tx_hp; //!< Bitmask for DIO state while chip is in high power transmission mode
uint8_t tx_hf; //!< Bitmask for DIO state while chip is in high frequency transmission mode
} lr1121_modem_system_rfswitch_cfg_t;
/**
* @brief Stand by configuration values
*/
typedef enum
{
LR1121_MODEM_SYSTEM_STANDBY_CFG_RC = 0x00,
LR1121_MODEM_SYSTEM_STANDBY_CFG_XOSC = 0x01
} lr1121_modem_system_standby_cfg_t;
/**
* @brief TCXO supply voltage values
*/
typedef enum
{
LR1121_MODEM_SYSTEM_TCXO_CTRL_1_6V = 0x00, //!< Supply voltage = 1.6v
LR1121_MODEM_SYSTEM_TCXO_CTRL_1_7V = 0x01, //!< Supply voltage = 1.7v
LR1121_MODEM_SYSTEM_TCXO_CTRL_1_8V = 0x02, //!< Supply voltage = 1.8v
LR1121_MODEM_SYSTEM_TCXO_CTRL_2_2V = 0x03, //!< Supply voltage = 2.2v
LR1121_MODEM_SYSTEM_TCXO_CTRL_2_4V = 0x04, //!< Supply voltage = 2.4v
LR1121_MODEM_SYSTEM_TCXO_CTRL_2_7V = 0x05, //!< Supply voltage = 2.7v
LR1121_MODEM_SYSTEM_TCXO_CTRL_3_0V = 0x06, //!< Supply voltage = 3.0v
LR1121_MODEM_SYSTEM_TCXO_CTRL_3_3V = 0x07, //!< Supply voltage = 3.3v
} lr1121_modem_system_tcxo_supply_voltage_t;
/**
* @brief Status register 1 structure definition
*/
typedef struct lr1121_modem_system_stat1_s
{
lr1121_modem_system_command_status_t command_status; //!< Status of last command
bool is_interrupt_active; //!< Indicates at least one interrupt is active
} lr1121_modem_system_stat1_t;
/**
* @brief Status register 2 structure definition
*/
typedef struct lr1121_modem_system_stat2_s
{
lr1121_modem_system_reset_status_t reset_status; //!< Source of reset
lr1121_modem_system_chip_modes_t chip_mode; //!< Current mode the chip is running
bool is_running_from_flash; //!< Flag indicating if the chip is currently running from flash
} lr1121_modem_system_stat2_t;
/**
* @brief Chip type values
*/
typedef enum
{
LR1121_MODEM_SYSTEM_VERSION_TYPE_LR1121 = 0x03,
} lr1121_modem_system_version_type_t;
/**
* @brief Version structure definition
*/
typedef struct lr1121_modem_system_version_s
{
uint8_t hw; //!< Hardware field of system version
lr1121_modem_system_version_type_t type; //!< Type field of system version
uint16_t fw; //!< Software field of system version
} lr1121_modem_system_version_t;
/**
* @brief Sleep configuration structure definition
*/
typedef struct lr1121_modem_system_sleep_cfg_s
{
bool is_warm_start; //!< Keep configuration and state in retention memory, allowing warm start
} lr1121_modem_system_sleep_cfg_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR1121_MODEM_SYSTEM_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,75 @@
/*!
* @file lr1121_types.h
*
* @brief Type definitions for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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_TYPES_H
#define LR1121_TYPES_H
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief LR1121 status
*/
typedef enum lr1121_status_e
{
LR1121_STATUS_OK = 0, //!< Operation terminated successfully
LR1121_STATUS_ERROR = 3, //!< Operation terminated with error
} lr1121_status_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#endif // LR1121_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,127 @@
/**
* @file lr_fhss_v1_base_types.h
*
* @brief Radio-independent LR-FHSS base type definitions, version 1
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR_FHSS_V1_BASE_TYPES_H__
#define LR_FHSS_V1_BASE_TYPES_H__
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include <stdbool.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief LR-FHSS modulation type
*/
typedef enum lr_fhss_v1_modulation_type_e
{
LR_FHSS_V1_MODULATION_TYPE_GMSK_488 = 0,
} lr_fhss_v1_modulation_type_t;
/**
* @brief LR-FHSS coding rate
*/
typedef enum lr_fhss_v1_cr_e
{
LR_FHSS_V1_CR_5_6 = 0x00,
LR_FHSS_V1_CR_2_3 = 0x01,
LR_FHSS_V1_CR_1_2 = 0x02,
LR_FHSS_V1_CR_1_3 = 0x03,
} lr_fhss_v1_cr_t;
/**
* @brief LR-FHSS grid
*/
typedef enum lr_fhss_v1_grid_e
{
LR_FHSS_V1_GRID_25391_HZ = 0x00,
LR_FHSS_V1_GRID_3906_HZ = 0x01,
} lr_fhss_v1_grid_t;
/**
* @brief LR-FHSS bandwidth
*/
typedef enum lr_fhss_v1_bw_e
{
LR_FHSS_V1_BW_39063_HZ = 0x00,
LR_FHSS_V1_BW_85938_HZ = 0x01,
LR_FHSS_V1_BW_136719_HZ = 0x02,
LR_FHSS_V1_BW_183594_HZ = 0x03,
LR_FHSS_V1_BW_335938_HZ = 0x04,
LR_FHSS_V1_BW_386719_HZ = 0x05,
LR_FHSS_V1_BW_722656_HZ = 0x06,
LR_FHSS_V1_BW_773438_HZ = 0x07,
LR_FHSS_V1_BW_1523438_HZ = 0x08,
LR_FHSS_V1_BW_1574219_HZ = 0x09,
} lr_fhss_v1_bw_t;
/**
* @brief LR-FHSS parameter structure
*/
typedef struct lr_fhss_v1_params_s
{
const uint8_t* sync_word; /**< 4-byte sync word */
lr_fhss_v1_modulation_type_t modulation_type;
lr_fhss_v1_cr_t cr;
lr_fhss_v1_grid_t grid;
lr_fhss_v1_bw_t bw;
bool enable_hopping;
uint8_t header_count; /**< Number of header blocks */
} lr_fhss_v1_params_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#endif // LR_FHSS_V1_BASE_TYPES_H__
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,141 @@
/**
* @file lr1121_modem_printf_info.h
*
* @brief Common Application Helper functions
*
* @copyright
* @parblock
* The Clear BSD License
* Copyright Semtech Corporation 2024. 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.
* @endparblock
*/
#ifndef LR1121_MODEM_PRINTF_INFO_H
#define LR1121_MODEM_PRINTF_INFO_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "lr1121_modem/lr1121_modem_lorawan.h"
#include "lr1121_modem/lr1121_modem_modem.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/**
* @brief Prints the provided buffer in HEX
*
* @param [in] buffer Buffer to be printed
* @param [in] size Buffer size to be printed
*/
void print_hex_buffer( const uint8_t* buffer, uint8_t size );
/**
* @brief Prints the LoRaWAN keys
*
* @param [in] dev_eui Device EUI to be printed
* @param [in] join_eui Join EUI to be printed
* @param [in] use_internal_credentials specify if the internal credentials are used
*/
void print_lorawan_credentials( const uint8_t* dev_eui, const uint8_t* join_eui, const uint8_t* pin,
const bool use_internal_credentials );
/**
* @brief Prints the LoRaWAN version
*
* @param [in] modem_version Modem version to be printed
*/
void print_version( lr1121_modem_version_t modem_version );
/**
* @brief convert lr1121 modem-e status to string
*/
void modem_status_to_string( lr1121_modem_lorawan_status_t modem_status );
/**
* @brief Get the lorawan region from modem and print it
*
* @param [in] context Chip implementation context
* @param [out] modem_region The LoRaWAN region returned by the modem. This pointer can be NULL: in this case the region
* is only printed, and not returned to caller
*/
void get_and_print_lorawan_region_from_modem( const void* context, lr1121_modem_regions_t* modem_region );
/**
* @brief Prints the LoRaWAN region
*
* @param [in] region Region to be printed
*/
void print_lorawan_region( lr1121_modem_regions_t region );
/**
* @brief Prints the state of certification mode
*
* @param [in] certif_running State of certification mode
*/
void print_certification( lr1121_modem_certification_mode_t certif_running );
/**
* @brief Gets and prints the crashlog if the crashlog status bit is set
*
* @param [in] context Chip implementation context
*/
void get_and_print_crashlog( const void* context );
#ifdef __cplusplus
}
#endif
#endif // APPS_UTILITIES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,48 @@
/*!
* @file lr11xx_bootloader_types_str.h
*
* @brief Printer helper functions for LR11xx bootloader types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_BOOTLOADER_TYPES_STR_H
#define LR11XX_BOOTLOADER_TYPES_STR_H
#include "lr11xx_driver/lr11xx_bootloader_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr11xx_bootloader_chip_modes_to_str( const lr11xx_bootloader_chip_modes_t value );
const char* lr11xx_bootloader_reset_status_to_str( const lr11xx_bootloader_reset_status_t value );
const char* lr11xx_bootloader_command_status_to_str( const lr11xx_bootloader_command_status_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_BOOTLOADER_TYPES_STR_H

View File

@@ -0,0 +1,49 @@
/*!
* @file lr11xx_crypto_engine_types_str.h
*
* @brief Printer helper functions for LR11xx crypto engine types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_CRYPTO_ENGINE_TYPES_STR_H
#define LR11XX_CRYPTO_ENGINE_TYPES_STR_H
#include "lr11xx_driver/lr11xx_crypto_engine_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr11xx_crypto_element_to_str( const lr11xx_crypto_element_t value );
const char* lr11xx_crypto_status_to_str( const lr11xx_crypto_status_t value );
const char* lr11xx_crypto_lorawan_version_to_str( const lr11xx_crypto_lorawan_version_t value );
const char* lr11xx_crypto_keys_idx_to_str( const lr11xx_crypto_keys_idx_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_CRYPTO_ENGINE_TYPES_STR_H

View File

@@ -0,0 +1,49 @@
/*!
* @file lr11xx_lr_fhss_types_str.h
*
* @brief Printer helper functions for LR11xx LRFHSS types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_LR_FHSS_TYPES_STR_H
#define LR11XX_LR_FHSS_TYPES_STR_H
#include "lr11xx_driver/lr11xx_lr_fhss_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr_fhss_v1_modulation_type_to_str( const lr_fhss_v1_modulation_type_t value );
const char* lr_fhss_v1_cr_to_str( const lr_fhss_v1_cr_t value );
const char* lr_fhss_v1_grid_to_str( const lr_fhss_v1_grid_t value );
const char* lr_fhss_v1_bw_to_str( const lr_fhss_v1_bw_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_LR_FHSS_TYPES_STR_H

View File

@@ -0,0 +1,14 @@
#ifndef LR11XX_VER_TEMP_H
#define LR11XX_VER_TEMP_H
#include "lr11xx_driver/lr11xx_system.h"
#ifdef __cplusplus
extern "C" {
#endif
void lora_print_version( const void* context );
void lora_print_temp( const void* context );
void lora_print_vbat( const void* context );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_VER_TEMP_H

View File

@@ -0,0 +1,70 @@
/*!
* @file lr11xx_radio_types_str.h
*
* @brief Printer helper functions for LR11xx radio types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_RADIO_TYPES_STR_H
#define LR11XX_RADIO_TYPES_STR_H
#include "lr11xx_driver/lr11xx_radio_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr11xx_radio_pa_selection_to_str( const lr11xx_radio_pa_selection_t value );
const char* lr11xx_radio_gfsk_address_filtering_to_str( const lr11xx_radio_gfsk_address_filtering_t value );
const char* lr11xx_radio_fallback_modes_to_str( const lr11xx_radio_fallback_modes_t value );
const char* lr11xx_radio_ramp_time_to_str( const lr11xx_radio_ramp_time_t value );
const char* lr11xx_radio_lora_network_type_to_str( const lr11xx_radio_lora_network_type_t value );
const char* lr11xx_radio_lora_sf_to_str( const lr11xx_radio_lora_sf_t value );
const char* lr11xx_radio_lora_bw_to_str( const lr11xx_radio_lora_bw_t value );
const char* lr11xx_radio_lora_cr_to_str( const lr11xx_radio_lora_cr_t value );
const char* lr11xx_radio_intermediary_mode_to_str( const lr11xx_radio_intermediary_mode_t value );
const char* lr11xx_radio_gfsk_crc_type_to_str( const lr11xx_radio_gfsk_crc_type_t value );
const char* lr11xx_radio_gfsk_dc_free_to_str( const lr11xx_radio_gfsk_dc_free_t value );
const char* lr11xx_radio_gfsk_pkt_len_modes_to_str( const lr11xx_radio_gfsk_pkt_len_modes_t value );
const char* lr11xx_radio_gfsk_preamble_detector_to_str( const lr11xx_radio_gfsk_preamble_detector_t value );
const char* lr11xx_radio_lora_crc_to_str( const lr11xx_radio_lora_crc_t value );
const char* lr11xx_radio_lora_pkt_len_modes_to_str( const lr11xx_radio_lora_pkt_len_modes_t value );
const char* lr11xx_radio_lora_iq_to_str( const lr11xx_radio_lora_iq_t value );
const char* lr11xx_radio_pkt_type_to_str( const lr11xx_radio_pkt_type_t value );
const char* lr11xx_radio_pa_reg_supply_to_str( const lr11xx_radio_pa_reg_supply_t value );
const char* lr11xx_radio_rx_duty_cycle_mode_to_str( const lr11xx_radio_rx_duty_cycle_mode_t value );
const char* lr11xx_radio_gfsk_bw_to_str( const lr11xx_radio_gfsk_bw_t value );
const char* lr11xx_radio_cad_exit_mode_to_str( const lr11xx_radio_cad_exit_mode_t value );
const char* lr11xx_radio_gfsk_pulse_shape_to_str( const lr11xx_radio_gfsk_pulse_shape_t value );
const char* lr11xx_radio_bpsk_pulse_shape_to_str( const lr11xx_radio_bpsk_pulse_shape_t value );
const char* lr11xx_radio_lr_fhss_bitrate_to_str( const lr11xx_radio_lr_fhss_bitrate_t value );
const char* lr11xx_radio_lr_fhss_pulse_shape_to_str( const lr11xx_radio_lr_fhss_pulse_shape_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_RADIO_TYPES_STR_H

View File

@@ -0,0 +1,46 @@
/*!
* @file lr11xx_rttof_types_str.h
*
* @brief Printer helper functions for LR11xx RTToF types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_RTTOF_TYPES_STR_H
#define LR11XX_RTTOF_TYPES_STR_H
#include "lr11xx_driver/lr11xx_rttof_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr11xx_rttof_result_type_to_str( const lr11xx_rttof_result_type_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_RTTOF_TYPES_STR_H

View File

@@ -0,0 +1,54 @@
/*!
* @file lr11xx_system_types_str.h
*
* @brief Printer helper functions for LR11xx system types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_SYSTEM_TYPES_STR_H
#define LR11XX_SYSTEM_TYPES_STR_H
#include "lr11xx_driver/lr11xx_system_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr11xx_system_chip_modes_to_str( const lr11xx_system_chip_modes_t value );
const char* lr11xx_system_reset_status_to_str( const lr11xx_system_reset_status_t value );
const char* lr11xx_system_command_status_to_str( const lr11xx_system_command_status_t value );
const char* lr11xx_system_lfclk_cfg_to_str( const lr11xx_system_lfclk_cfg_t value );
const char* lr11xx_system_reg_mode_to_str( const lr11xx_system_reg_mode_t value );
const char* lr11xx_system_infopage_id_to_str( const lr11xx_system_infopage_id_t value );
const char* lr11xx_system_standby_cfg_to_str( const lr11xx_system_standby_cfg_t value );
const char* lr11xx_system_tcxo_supply_voltage_to_str( const lr11xx_system_tcxo_supply_voltage_t value );
const char* lr11xx_system_version_type_to_str( const lr11xx_system_version_type_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_SYSTEM_TYPES_STR_H

View File

@@ -0,0 +1,46 @@
/*!
* @file lr11xx_types_str.h
*
* @brief Printer helper functions for LR11xx types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 LR11XX_TYPES_STR_H
#define LR11XX_TYPES_STR_H
#include "lr11xx_driver/lr11xx_types.h"
#ifdef __cplusplus
extern "C" {
#endif
const char* lr11xx_status_to_str( const lr11xx_status_t value );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_TYPES_STR_H

View File

@@ -0,0 +1,213 @@
/*!
* @file lr11xx_bootloader.h
*
* @brief Bootloader driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_BOOTLOADER_H
#define LR11XX_BOOTLOADER_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_bootloader_types.h"
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
typedef uint32_t lr11xx_bootloader_irq_mask_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Return the status registers and interrupt flags
*
* @remark To simplify system integration, this function does not actually execute the GetStatus command, which would
* require bidirectional SPI communication. It obtains the stat1, stat2, and irq_status values by performing an ordinary
* SPI read (which is required to send null/NOP bytes on the MOSI line). This is possible since the LR11XX returns these
* values automatically whenever a read that does not directly follow a response-carrying command is performed. Unlike
* with the GetStatus command, however, the reset status information is NOT cleared by this command. The function @ref
* lr11xx_bootloader_clear_reset_status_info may be used for this purpose when necessary.
*
* @param [in] context Chip implementation context
* @param [out] stat1 Content of status register 1
* @param [out] stat2 Content of status register 2
* @param [out] irq_status Interrupt flags
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_get_status( const void* context, lr11xx_bootloader_stat1_t* stat1,
lr11xx_bootloader_stat2_t* stat2,
lr11xx_bootloader_irq_mask_t* irq_status );
/*!
* @brief Clear the reset status information stored in stat2
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_clear_reset_status_info( const void* context );
/*!
* @brief Return the version of the system (hardware and software)
*
* @param [in] context Chip implementation context
* @param [out] version Pointer to the structure holding the system version
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_get_version( const void* context, lr11xx_bootloader_version_t* version );
/*!
* @brief Erase the whole flash memory of the chip
*
* This function shall be called before any attempt to write a new firmware in flash memory
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_erase_flash( const void* context );
/*!
* @brief Write encrypted data in program flash memory of the chip
*
* This function shall be used when updating the encrypted flash content of the LR11XX.
* The encrypted flash payload to transfer shall be represented as an array of words (i.e. 4-byte values).
*
* Updating flash code of the chip with this function MUST respect the following constraints:
* - the complete flash image MUST be splitted into chunks of 64 words each, except the last one that can be shorter
* - the chunks MUST be sent to the chip in-order, starting with @p offset_in_byte = 0
*
* @param [in] context Chip implementation context
* @param [in] offset_in_byte The offset from start register of flash in byte
* @param [in] buffer Buffer holding the encrypted content. Its size in words must be at least length
* @param [in] length_in_word Number of words (i.e. 4 bytes) in the buffer to transfer. MUST be 64 for all chunks except
* the last one where it can be lower.
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_write_flash_encrypted( const void* context, const uint32_t offset_in_byte,
const uint32_t* buffer, const uint8_t length_in_word );
/*!
* @brief Write encrypted data in program flash memory of the chip
*
* This function shall be used when updating the encrypted flash content of the LR11XX.
* The encrypted flash payload to transfer shall be represented as an array of words (ie 4-byte values).
*
* @param [in] context Chip implementation context
* @param [in] offset_in_byte The offset from start register of flash in byte
* @param [in] buffer Buffer holding the encrypted content. Its size in words must be at least length
* @param [in] length_in_word Number of words (i.e. 4 bytes) in the buffer to transfer
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_write_flash_encrypted_full( const void* context, const uint32_t offset_in_byte,
const uint32_t* buffer, const uint32_t length_in_word );
/*!
* @brief Software reset of the chip.
*
* This method should be used to reboot the chip in a specified mode.
* Rebooting in flash mode presumes that the content in flash memory is not corrupted (i.e. the integrity check
* performed by the bootloader before executing the first instruction in flash is OK).
*
* @param [in] context Chip implementation context
* @param [in] stay_in_bootloader Selector to stay in bootloader or execute flash code after reboot. If true, the
* bootloader will not execute the flash code but activate SPI interface to allow firmware upgrade
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_reboot( const void* context, const bool stay_in_bootloader );
/*!
* @brief Returns the 4-byte PIN which can be used to claim a device on cloud services.
*
* @param [in] context Chip implementation context
* @param [out] pin Pointer to the array to be populated with the PIN
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_read_pin( const void* context, lr11xx_bootloader_pin_t pin );
/*!
* @brief Read and return the Chip EUI
*
* @param [in] context Chip implementation context
* @param [out] chip_eui The buffer to be filled with chip EUI of the LR11XX. It is up to the application to ensure
* chip_eui is long enough to hold the chip EUI
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_read_chip_eui( const void* context, lr11xx_bootloader_chip_eui_t chip_eui );
/*!
* @brief Read and return the Join EUI
*
* @param [in] context Chip implementation context
* @param [out] join_eui The buffer to be filled with Join EUI of the LR11XX. It is up to the application to ensure
* join_eui is long enough to hold the join EUI
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_bootloader_read_join_eui( const void* context, lr11xx_bootloader_join_eui_t join_eui );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_BOOTLOADER_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,179 @@
/*!
* @file lr11xx_bootloader_types.h
*
* @brief Bootloader driver types for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_BOOTLOADER_TYPES_H
#define LR11XX_BOOTLOADER_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*!
* @brief Length in byte of the LR11XX version blob
*/
#define LR11XX_BL_VERSION_LENGTH ( 4 )
/*!
* @brief Length in bytes of a PIN
*/
#define LR11XX_BL_PIN_LENGTH ( 4 )
/*!
* @brief Length in bytes of a chip EUI
*/
#define LR11XX_BL_CHIP_EUI_LENGTH ( 8 )
/*!
* @brief Length in bytes of a join EUI
*/
#define LR11XX_BL_JOIN_EUI_LENGTH ( 8 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Fixed-length array to store a PIN
*/
typedef uint8_t lr11xx_bootloader_pin_t[LR11XX_BL_PIN_LENGTH];
/*!
* @brief Fixed-length array to store a chipEUI
*/
typedef uint8_t lr11xx_bootloader_chip_eui_t[LR11XX_BL_CHIP_EUI_LENGTH];
/*!
* @brief Fixed-length array to store a joinEUI
*/
typedef uint8_t lr11xx_bootloader_join_eui_t[LR11XX_BL_JOIN_EUI_LENGTH];
/*!
* @brief Chip modes
*/
typedef enum lr11xx_bootloader_chip_modes_e
{
LR11XX_BOOTLOADER_CHIP_MODE_SLEEP = 0x00,
LR11XX_BOOTLOADER_CHIP_MODE_STBY_RC = 0x01,
LR11XX_BOOTLOADER_CHIP_MODE_STBY_XOSC = 0x02,
LR11XX_BOOTLOADER_CHIP_MODE_FS = 0x03,
LR11XX_BOOTLOADER_CHIP_MODE_RX = 0x04,
LR11XX_BOOTLOADER_CHIP_MODE_TX = 0x05,
LR11XX_BOOTLOADER_CHIP_MODE_LOC = 0x06,
} lr11xx_bootloader_chip_modes_t;
/*!
* @brief Reset status
*/
typedef enum lr11xx_bootloader_reset_status_e
{
LR11XX_BOOTLOADER_RESET_STATUS_CLEARED = 0x00,
LR11XX_BOOTLOADER_RESET_STATUS_ANALOG = 0x01,
LR11XX_BOOTLOADER_RESET_STATUS_EXTERNAL = 0x02,
LR11XX_BOOTLOADER_RESET_STATUS_SYSTEM = 0x03,
LR11XX_BOOTLOADER_RESET_STATUS_WATCHDOG = 0x04,
LR11XX_BOOTLOADER_RESET_STATUS_IOCD_RESTART = 0x05,
LR11XX_BOOTLOADER_RESET_STATUS_RTC_RESTART = 0x06,
} lr11xx_bootloader_reset_status_t;
/*!
* @brief Command status
*/
typedef enum lr11xx_bootloader_command_status_e
{
LR11XX_BOOTLOADER_CMD_STATUS_FAIL = 0x00,
LR11XX_BOOTLOADER_CMD_STATUS_PERR = 0x01,
LR11XX_BOOTLOADER_CMD_STATUS_OK = 0x02,
LR11XX_BOOTLOADER_CMD_STATUS_DATA = 0x03,
} lr11xx_bootloader_command_status_t;
/*!
* @brief Status register 1 structure definition
*/
typedef struct lr11xx_bootloader_stat1_s
{
lr11xx_bootloader_command_status_t command_status;
bool is_interrupt_active;
} lr11xx_bootloader_stat1_t;
/*!
* @brief Status register 2 structure definition
*/
typedef struct lr11xx_bootloader_stat2_s
{
lr11xx_bootloader_reset_status_t reset_status;
lr11xx_bootloader_chip_modes_t chip_mode;
bool is_running_from_flash;
} lr11xx_bootloader_stat2_t;
/*!
* @brief Bootloader version structure definition
*/
typedef struct lr11xx_bootloader_version_s
{
uint8_t hw;
uint8_t type;
uint16_t fw;
} lr11xx_bootloader_version_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_BOOTLOADER_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,342 @@
/*!
* @file lr11xx_crypto_engine.h
*
* @brief Cryptographic engine driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_CRYPTO_ENGINE_H
#define LR11XX_CRYPTO_ENGINE_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include "lr11xx_crypto_engine_types.h"
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Select the crypto element to be used
*
* By default, the internal crypto engine is selected. It is not needed to call this command if one plans to use the
* internal crypto engine.
*
* @param [in] context Chip implementation context
* @param [in] element The type of crypto element to use
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_crypto_select( const void* context, const lr11xx_crypto_element_t element );
/*!
* @brief Set a key in the previously selected crypto element.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] key_id The identifier of the key to be set
* @param [in] key The key to be set
*
* @returns Operation status
*
* @see lr11xx_crypto_derive_key
*/
lr11xx_status_t lr11xx_crypto_set_key( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const lr11xx_crypto_key_t key );
/*!
* @brief Derive a key previously set.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] src_key_id The identifier of the key to be derived
* @param [in] dest_key_id The identifier where the derived key will be stored after call to @ref
* lr11xx_crypto_store_to_flash
* @param [in] nonce The nonce to be used to perform the derivation
*
* @returns Operation status
*
* @see lr11xx_crypto_set_key
*/
lr11xx_status_t lr11xx_crypto_derive_key( const void* context, lr11xx_crypto_status_t* status, const uint8_t src_key_id,
const uint8_t dest_key_id, const lr11xx_crypto_nonce_t nonce );
/*!
* @brief Perform the needed operations to extract the payload from a join accept message.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] dec_key_id The identifier of the key used for message decryption
* @param [in] ver_key_id The identifier of the key used for MIC verification
* @param [in] lorawan_version LoRaWAN version to know the size of the header
* @param [in] header The header to compute (length linked to lorawan_version)
* @param [in] data The data to compute
* @param [in] length The length in bytes of the data to compute
* @param [out] data_out Placeholder for the decrypted data
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_crypto_process_join_accept( const void* context, lr11xx_crypto_status_t* status,
const uint8_t dec_key_id, const uint8_t ver_key_id,
const lr11xx_crypto_lorawan_version_t lorawan_version,
const uint8_t* header, const uint8_t* data, const uint8_t length,
uint8_t* data_out );
/*!
* @brief Compute an AES-CMAC.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] key_id The identifier of the keyused for the computation
* @param [in] data The data to compute
* @param [in] length The length in bytes of the data to compute
* @param [out] mic Placeholder for the computed MIC (first 4 bytes of the AES-CMAC)
*
* @returns Operation status
*
* @see lr11xx_crypto_verify_aes_cmac
*/
lr11xx_status_t lr11xx_crypto_compute_aes_cmac( const void* context, lr11xx_crypto_status_t* status,
const uint8_t key_id, const uint8_t* data, const uint16_t length,
lr11xx_crypto_mic_t mic );
/*!
* @brief Compute an AES-CMAC and make a comparison with a value given as parameter.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] key_id The identifier of the key to be used for the computation
* @param [in] data The data to compute
* @param [in] length The length in bytes of the data to compute
* @param [in] mic The MIC value (first 4 bytes of the CMAC) use for comparison
*
* @returns Operation status
*
* @see lr11xx_crypto_compute_aes_cmac
*/
lr11xx_status_t lr11xx_crypto_verify_aes_cmac( const void* context, lr11xx_crypto_status_t* status,
const uint8_t key_id, const uint8_t* data, const uint16_t length,
const lr11xx_crypto_mic_t mic );
/*!
* @brief Compute an AES encryption with a key ID specified in parameter.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] key_id The identifier of the key to be used for the computation
* @param [in] data The data to encrypt
* @param [in] length The length in bytes of the data to encrypt - this value shall be a multiple of 16
* @param [out] result A pointer to a data buffer that will be filled with the encrypted data. Values of this buffer are
* meaningful if and only if the return status is LR11XX_CRYPTO_STATUS_SUCCESS
*
* @returns Operation status
*
* @see lr11xx_crypto_set_key, lr11xx_crypto_derive_key
*/
lr11xx_status_t lr11xx_crypto_aes_encrypt_01( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const uint8_t* data, const uint16_t length, uint8_t* result );
/*!
* @brief Compute an AES encryption with a key ID specified in parameter.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] key_id The identifier of the key to be used for the computation
* @param [in] data The data to encrypt
* @param [in] length The length in bytes of the data to encrypt - this value shall be a multiple of 16
* @param [out] result A pointer to a data buffer that will be filled with the encrypted data. Values of this buffer are
* meaningful if and only if the return status is LR11XX_CRYPTO_STATUS_SUCCESS
*
* @returns Operation status
*
* @see lr11xx_crypto_set_key, lr11xx_crypto_derive_key
*/
lr11xx_status_t lr11xx_crypto_aes_encrypt( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const uint8_t* data, const uint16_t length, uint8_t* result );
/*!
* @brief Compute an AES decryption with a key ID specified in parameter.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] key_id The identifier of the key to be used for the computation
* @param [in] data The data to decrypt
* @param [in] length The length in bytes of the data to decrypt - this value shall be a multiple of 16
* @param [out] result A pointer to a data buffer that will be filled with the decrypted data. Values of this buffer are
* meaningful if and only if the return status is LR11XX_CRYPTO_STATUS_SUCCESS
*
* @returns Operation status
*
* @see lr11xx_crypto_set_key, lr11xx_crypto_derive_key
*/
lr11xx_status_t lr11xx_crypto_aes_decrypt( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const uint8_t* data, const uint16_t length, uint8_t* result );
/*!
* @brief Store the crypto data (keys, parameters) from RAM into the flash memory.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
*
* @returns Operation status
*
* @see lr11xx_crypto_restore_from_flash
*/
lr11xx_status_t lr11xx_crypto_store_to_flash( const void* context, lr11xx_crypto_status_t* status );
/*!
* @brief Restore the crypto data (keys, parameters) from flash memory into RAM.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
*
* @returns Operation status
*
* @see lr11xx_crypto_store_to_flash
*/
lr11xx_status_t lr11xx_crypto_restore_from_flash( const void* context, lr11xx_crypto_status_t* status );
/*!
* @brief Set a specific parameter identified by param_id in the crypto RAM.
*
* This function does not store a parameter in the flash memory. The parameters shall be stored after using @ref
* lr11xx_crypto_store_to_flash command.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] param_id The identifier of the parameter to be set
* @param [in] parameter The parameter to be set
*
* @returns Operation status
*
* @see lr11xx_crypto_get_parameter
*/
lr11xx_status_t lr11xx_crypto_set_parameter( const void* context, lr11xx_crypto_status_t* status,
const uint8_t param_id, const lr11xx_crypto_param_t parameter );
/*!
* @brief Get a specific parameter identified by paramID from the crypto RAM.
*
* This function does not fetch a parameter from the flash memory. The parameters shall be restored before using @ref
* lr11xx_crypto_restore_from_flash command.
*
* @param [in] context Chip implementation context
* @param [out] status The status returned by the execution of this cryptographic function
* @param [in] param_id The identifier of the parameter to get
* @param [out] parameter The placeholder to store the parameter
*
* @returns Operation status
*
* @see lr11xx_crypto_set_parameter
*/
lr11xx_status_t lr11xx_crypto_get_parameter( const void* context, lr11xx_crypto_status_t* status,
const uint8_t param_id, lr11xx_crypto_param_t parameter );
/*!
* @brief Check if an encrypted firmware image is suitable for the transceiver on which the check is done
*
* @remark The result can be read by calling @ref lr11xx_crypto_get_check_encrypted_firmware_image_result
*
* @remark A user checks the suitability of a firmware image by calling this function with 64-word long chunk of data
* sent in-order (except for the last one that can be shorter).
*
* @param [in] context Chip implementation context
* @param [in] offset_in_byte Offset of data buffer in firmware image - has to be a multiple of 4
* @param [in] data Buffer holding the encrypted content. Its size in words must be at least length
* @param [in] length_in_word Number of words (i.e. 4 bytes) in the buffer to transfer. This value must be in the range
* [0:64]
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_crypto_check_encrypted_firmware_image( const void* context, const uint32_t offset_in_byte,
const uint32_t* data, const uint8_t length_in_word );
/*!
* @brief Check if an encrypted firmware image is suitable for the transceiver on which the check is done
*
* @remark The result can be read by calling @ref lr11xx_crypto_get_check_encrypted_firmware_image_result
*
* @remark This function is developed on top of @ref lr11xx_crypto_check_encrypted_firmware_image and takes care of the
* whole firmware image transfer
*
* @param [in] context Chip implementation context
* @param [in] offset_in_byte Offset of data buffer in firmware image - has to be a multiple of 4
* @param [in] data Buffer holding the encrypted content. Its size in words must be at least length
* @param [in] length_in_word Number of words (i.e. 4 bytes) in the buffer to transfer
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_crypto_check_encrypted_firmware_image_full( const void* context, const uint32_t offset_in_byte,
const uint32_t* data,
const uint32_t length_in_word );
/*!
* @brief Get the result of the encrypted firmware image check
*
* @param [in] context Chip implementation context
* @param [out] is_encrypted_fw_image_ok Result of the encrypted firmware image check
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_crypto_get_check_encrypted_firmware_image_result( const void* context,
bool* is_encrypted_fw_image_ok );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_CRYPTO_ENGINE_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,199 @@
/*!
* @file lr11xx_crypto_engine_types.h
*
* @brief Cryptographic engine driver types for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_CRYPTO_ENGINE_TYPES_H
#define LR11XX_CRYPTO_ENGINE_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*!
* @brief Length in bytes of a MIC
*/
#define LR11XX_CRYPTO_MIC_LENGTH 0x04
/*!
* @brief Length in bytes of a AES CMAC
*/
#define LR11XX_CRYPTO_AES_CMAC_LENGTH 0x10
/*!
* @brief Maximum length in bytes of data to be encrypted / decrypted
*/
#define LR11XX_CRYPTO_DATA_MAX_LENGTH 0x0100
/*!
* @brief Length in bytes of a key for AES computation
*/
#define LR11XX_CRYPTO_KEY_LENGTH 0x10
/*!
* @brief Length in bytes of a nonce
*/
#define LR11XX_CRYPTO_NONCE_LENGTH 0x10
/*!
* @brief Length in bytes of a crypto parameter
*/
#define LR11XX_CRYPTO_PARAMETER_LENGTH 0x04
/*!
* @brief Length in bytes of the status returned by an API
*/
#define LR11XX_CRYPTO_STATUS_LENGTH 0x01
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Fixed-length array to store an AES CMAC
*/
typedef uint8_t lr11xx_crypto_mic_t[LR11XX_CRYPTO_MIC_LENGTH];
/*!
* @brief Fixed-length array to store an AES CMAC
*/
typedef uint8_t lr11xx_crypto_aes_cmac_t[LR11XX_CRYPTO_AES_CMAC_LENGTH];
/*!
* @brief Fixed-length array to store a crypto key
*/
typedef uint8_t lr11xx_crypto_key_t[LR11XX_CRYPTO_KEY_LENGTH];
/*!
* @brief Fixed-length array to store a crypto nonce
*/
typedef uint8_t lr11xx_crypto_nonce_t[LR11XX_CRYPTO_NONCE_LENGTH];
/*!
* @brief Fixed-length array to store a crypto parameter
*/
typedef uint8_t lr11xx_crypto_param_t[LR11XX_CRYPTO_PARAMETER_LENGTH];
/*!
* @brief The supported crypto elements
*/
typedef enum
{
LR11XX_CRYPTO_ELEMENT_CRYPTO_ENGINE = 0x00, //!< Internal crypto engine (default)
LR11XX_CRYPTO_ELEMENT_SECURE_ELEMENT = 0x01, //!< External secure element
} lr11xx_crypto_element_t;
/*!
* @brief The status returned by the crypto API
*/
typedef enum
{
LR11XX_CRYPTO_STATUS_SUCCESS = 0x00, //!< The API command was successful
LR11XX_CRYPTO_STATUS_ERROR_FAIL_CMAC = 0x01, //!< AES-CMAC invalid or comparison failed
LR11XX_CRYPTO_STATUS_ERROR_INVALID_KEY_ID = 0x03, //!< Invalid key ID (source, destination)
LR11XX_CRYPTO_STATUS_ERROR_BUFFER_SIZE = 0x05, //!< Invalid data buffer size
LR11XX_CRYPTO_STATUS_ERROR = 0x06, //!< Other error
} lr11xx_crypto_status_t;
/*!
* @brief The supported LoRaWAN versions
*/
typedef enum
{
LR11XX_CRYPTO_LORAWAN_VERSION_1_0_X = 0x00,
LR11XX_CRYPTO_LORAWAN_VERSION_1_1_X = 0x01,
} lr11xx_crypto_lorawan_version_t;
/*!
* @brief Crypto keys table index definition.
*/
typedef enum lr11xx_crypto_keys_idx_e
{
LR11XX_CRYPTO_KEYS_IDX_MOTHER_KEY = 1,
LR11XX_CRYPTO_KEYS_IDX_NWK_KEY = 2,
LR11XX_CRYPTO_KEYS_IDX_APP_KEY = 3,
LR11XX_CRYPTO_KEYS_IDX_J_S_ENC_KEY = 4,
LR11XX_CRYPTO_KEYS_IDX_J_S_INT_KEY = 5,
LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_0 = 6,
LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_1 = 7,
LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_2 = 8,
LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_3 = 9,
LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_4 = 10,
LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_5 = 11,
LR11XX_CRYPTO_KEYS_IDX_APP_S_KEY = 12,
LR11XX_CRYPTO_KEYS_IDX_F_NWK_S_INT_KEY = 13,
LR11XX_CRYPTO_KEYS_IDX_S_NWK_S_INT_KEY = 14,
LR11XX_CRYPTO_KEYS_IDX_NWK_S_ENC_KEY = 15,
LR11XX_CRYPTO_KEYS_IDX_RFU_0 = 16,
LR11XX_CRYPTO_KEYS_IDX_RFU_1 = 17,
LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_0 = 18,
LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_1 = 19,
LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_2 = 20,
LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_3 = 21,
LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_0 = 22,
LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_1 = 23,
LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_2 = 24,
LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_3 = 25,
LR11XX_CRYPTO_KEYS_IDX_GP0 = 26,
LR11XX_CRYPTO_KEYS_IDX_GP1 = 27,
} lr11xx_crypto_keys_idx_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_CRYPTO_ENGINE_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,90 @@
/*!
* @file lr11xx_driver_version.h
*
* @brief Placeholder to keep the version of LR11XX driver.
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_DRIVER_VERSION_H
#define LR11XX_DRIVER_VERSION_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
#define LR11XX_DRIVER_VERSION_MAJOR 2
#define LR11XX_DRIVER_VERSION_MINOR 4
#define LR11XX_DRIVER_VERSION_PATCH 1
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Compare version information with current ones
*
* This macro expands to true boolean value if the version information provided in argument is compatible or
* retro-compatible with the version of this code base
*/
#define LR11XX_DRIVER_VERSION_CHECK( x, y, z ) \
( x == LR11XX_DRIVER_VERSION_MAJOR && \
( y < LR11XX_DRIVER_VERSION_MINOR || \
( y == LR11XX_DRIVER_VERSION_MINOR && z <= LR11XX_DRIVER_VERSION_PATCH ) ) )
const char* lr11xx_driver_version_get_version_string( void );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_DRIVER_VERSION_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,757 @@
/*!
* @file lr11xx_gnss.h
*
* @brief GNSS scan driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_GNSS_H
#define LR11XX_GNSS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_gnss_types.h"
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Get the size of results
*
* This method returns the size in bytes of the results available in LR11XX result buffer.
*
* @param [in] context Chip implementation context
* @param [out] result_size Result size
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_result_size( const void* context, uint16_t* result_size );
/*!
* @brief Read GNSS results
*
* The GNSS results are pushed into a buffer directly. This buffer is provided by the application using the driver. It
* MUST be long enough to contains at least result_buffer_size bytes.
*
* @warning No check is done on result_buffer size. If this application provided buffer is too small, there will be a
* buffer overflow bug!
*
* @param [in] context Chip implementation context
* @param [out] result_buffer Application provided buffer to be filled with result
* @param [in] result_buffer_size The number of bytes to read from the LR11XX
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_results( const void* context, uint8_t* result_buffer,
const uint16_t result_buffer_size );
/*!
* @brief Update almanacs given as parameter
*
* @remark Note that information header and almanacs for all 128 SV (i.e. 129 20-byte long blocks) must be updated in a
* row for the whole operation to be successful. Therefore, this function must be called as many times as needed without
* any other operations in between.
*
* @param [in] context Chip implementation context
* @param [in] blocks Buffer containing at least (nb_of_blocks * LR11XX_GNSS_SINGLE_ALMANAC_WRITE_SIZE) bytes of almanac
* @param [in] nb_of_blocks Number of blocks to transfer
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_almanac_update( const void* context, const uint8_t* blocks, const uint8_t nb_of_blocks );
/*!
* @brief Read the almanac
*
* @param [in] context Chip implementation context
* @param [out] almanac_bytestream The bytestream of the almanac
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_almanac( const void* context,
lr11xx_gnss_almanac_full_read_bytestream_t almanac_bytestream );
/*!
* @brief Function to read the frequency search space around the Doppler frequency
*
* @param [in] radio Radio abstraction
* @param [out] freq_search_space Frequency search space configuration read from the chip
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_freq_search_space( const void* radio,
lr11xx_gnss_freq_search_space_t* freq_search_space );
/*!
* @brief Function to set the frequency search space around the Doppler frequency
*
* @param [in] radio Radio abstraction
* @param [in] freq_search_space Frequency search space configuration to be applied
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_set_freq_search_space( const void* radio,
const lr11xx_gnss_freq_search_space_t freq_search_space );
/*!
* @brief Get almanac age for a satellite
*
* @param [in] context Chip implementation context
* @param [in] sv_id ID of the satellite corresponding the to almanac requested
* @param [out] almanac_age Almanac age in days since last GPS time overlap
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_almanac_age_for_satellite( const void* context, const lr11xx_gnss_satellite_id_t sv_id,
uint16_t* almanac_age );
/*!
* @brief Push data received from solver to LR11XX
*
* @param [in] context Chip implementation context
* @param [in] payload Payload received from solver
* @param [in] payload_size Size of the payload received from solver (in bytes)
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_push_solver_msg( const void* context, const uint8_t* payload, const uint16_t payload_size );
/**
* @brief Return the theoretical number of visible satellites based on the given parameters.
*
* @param [in] context Chip implementation context
* @param [in] date The actual date of scan. Its format is the number of seconds elapsed since January the 6th 1980
* 00:00:00 with leap seconds included.
* @param [in] assistance_position, latitude 12 bits and longitude 12 bits
* @param [in] constellation Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values
* @param [out] nb_visible_sv theoretical number of visible satellites
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_nb_visible_satellites(
const void* context, const lr11xx_gnss_date_t date,
const lr11xx_gnss_solver_assistance_position_t* assistance_position,
const lr11xx_gnss_constellation_t constellation, uint8_t* nb_visible_sv );
/**
* @brief Return the theoretical doppler information of theoretical visible satellites, this function shall be called
* after lr11xx_gnss_get_nb_visible_satellites function.
*
* @param [in] context Chip implementation context
* @param [in] nb_visible_satellites number of visible satellites returned by lr11xx_gnss_get_nb_visible_satellites
* function,
* @param [out] visible_satellite_id_doppler Doppler information of each satellite.
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_visible_satellites( const void* context, const uint8_t nb_visible_satellites,
lr11xx_gnss_visible_satellite_t* visible_satellite_id_doppler );
/*!
* @brief Activate the GNSS scan constellation
*
* @param [in] context Chip implementation context
* @param [in] constellation_mask Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values
*
* @returns Operation status
*
* @see lr11xx_gnss_read_used_constellations
*/
lr11xx_status_t lr11xx_gnss_set_constellations_to_use( const void* context,
const lr11xx_gnss_constellation_mask_t constellation_mask );
/*!
* @brief Read constellation used by the GNSS scanner from the almanac update configuration
*
* @param [in] context Chip implementation context
* @param [out] constellations_used Bit mask of the constellations used. See @ref lr11xx_gnss_constellation_t for the
* possible values
*
* @returns Operation status
*
* @see lr11xx_gnss_set_constellations_to_use
*/
lr11xx_status_t lr11xx_gnss_read_used_constellations( const void* context,
lr11xx_gnss_constellation_mask_t* constellations_used );
/*!
* @brief Activate the almanac update
*
* @param [in] context Chip implementation context
* @param [in] constellations_to_update Bit mask of the constellations to mark to update. See @ref
* lr11xx_gnss_constellation_t for the possible values
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_set_almanac_update( const void* context,
const lr11xx_gnss_constellation_mask_t constellations_to_update );
/*!
* @brief Function to read the almanac update configuration
*
* @param [in] context Chip implementation context
* @param [out] constellations_to_update Bit mask of the constellations to mark to update. See @ref
* lr11xx_gnss_constellation_t for the possible values
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_almanac_update( const void* context,
lr11xx_gnss_constellation_mask_t* constellations_to_update );
/*!
* @brief Function to read the GNSS firmware version
*
* @param [in] context Chip implementation context
* @param [in] version GNSS Firmware version currently running on the chip
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_firmware_version( const void* context, lr11xx_gnss_version_t* version );
/*!
* @brief Function to read the supported constellation, GPS or BEIDOU other constellations
*
* @param [in] context Chip implementation context
* @param [out] supported_constellations Bit mask of the constellations used. See @ref lr11xx_gnss_constellation_t for
* the possible values
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_supported_constellations( const void* context,
lr11xx_gnss_constellation_mask_t* supported_constellations );
/*!
* @brief Function to set the GNSS scan mode configuration
*
* @param [in] context Chip implementation context
* @param [in] scan_mode GNSS scan mode
*
* @returns Operation status
*
* @see lr11xx_gnss_scan_mode_t
*/
lr11xx_status_t lr11xx_gnss_set_scan_mode( const void* context, const lr11xx_gnss_scan_mode_t scan_mode );
/*!
* @brief Start the gnss scan
*
* @param [in] context Chip implementation context
* @param [in] effort_mode Effort mode @ref lr11xx_gnss_search_mode_t
* @param [in] gnss_input_parameters Bit mask indicating which information is added in the output payload @ref
* lr11xx_gnss_result_fields_e
* @param [in] nb_sat The expected number of satellite to provide. This value must be in the range [0:128]
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_scan( const void* context, const lr11xx_gnss_search_mode_t effort_mode,
const uint8_t gnss_input_parameters, const uint8_t nb_sat );
/*!
* @brief Function to set the assistance position.
*
* @param [in] context Chip implementation context
* @param [in] assistance_position, latitude 12 bits and longitude 12 bits
*
* @returns Operation status
*
* @see lr11xx_gnss_solver_assistance_position_t
*/
lr11xx_status_t lr11xx_gnss_set_assistance_position(
const void* context, const lr11xx_gnss_solver_assistance_position_t* assistance_position );
/*!
* @brief Function to read the assistance position.
*
* The assistance position read may be different from the one set beforehand with @ref
* lr11xx_gnss_set_assistance_position due to a scaling computation.
*
* @param [in] context Chip implementation context
* @param [in] assistance_position, latitude 12 bits and longitude 12 bits
*
* @returns Operation status
*
* @see lr11xx_gnss_solver_assistance_position_t
*/
lr11xx_status_t lr11xx_gnss_read_assistance_position( const void* context,
lr11xx_gnss_solver_assistance_position_t* assistance_position );
/*!
* @brief Host receives an update from the network or assembles itself the update message and send it to the LR11XX.
*
* @param [in] context Chip implementation context
* @param [in] dmc_msg buffer containing the update the network
* @param [in] dmc_msg_len length of this buffer
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_push_dmc_msg( const void* context, uint8_t* dmc_msg, uint16_t dmc_msg_len );
/*!
* @brief Get the GNSS context status
*
* This function returns the GNSS context status as a raw buffer. It is possible to use
* lr11xx_gnss_parse_context_status_buffer to obtain the details of the context status.
*
* @param [in] context Chip implementation context
* @param [out] context_status_buffer Pointer to a buffer to be filled with context status information. Must be at least
* 7 bytes long. It is up to the caller to ensure there is enough place in this buffer.
*
* @returns Operation status
*
* @see lr11xx_gnss_parse_context_status_buffer
*/
lr11xx_status_t lr11xx_gnss_get_context_status( const void* context,
lr11xx_gnss_context_status_bytestream_t context_status_buffer );
/*!
* @brief Get the number of detected satellites during last scan
*
* @param [in] context Chip implementation context
* @param [out] nb_detected_satellites Number of satellites detected
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_nb_detected_satellites( const void* context, uint8_t* nb_detected_satellites );
/*!
* @brief Get the satellites detected on last scan with their IDs, C/N (aka CNR) and doppler
*
* @note Doppler is returned with 6ppm accuracy.
*
* @param [in] context Chip implementation context
* @param [in] nb_detected_satellites Number of detected satellites on last scan (obtained by calling
* lr11xx_gnss_get_nb_detected_satellites)
* @param [out] detected_satellite_id_snr_doppler Pointer to an array of structures of size big enough to contain
* nb_detected_satellites elements
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_detected_satellites(
const void* context, const uint8_t nb_detected_satellites,
lr11xx_gnss_detected_satellite_t* detected_satellite_id_snr_doppler );
/*!
* @brief Read almanacs per satellite range
*
* @note Doppler is returned with 6ppm accuracy.
*
* @param [in] context Chip implementation context
* @param [in] sv_id_init Index of the satellite to start reading almanac from
* @param [in] n_sv Number of satellite almanac to read from sv_id_init
* @param [out] almanacs Pointer to an array to be filled by almanac data. It is up to the caller to ensure the
* available length of almanacs buffer is at least (n_sv * LR11XX_GNSS_SINGLE_ALMANAC_READ_SIZE)
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_almanac_per_satellites( const void* context, uint8_t sv_id_init, uint8_t n_sv,
uint8_t* almanacs );
/*!
* @brief Read RSSI on GNSS path
*
* This is a test function to read RSSI on GNSS path.
*
* @param [in] context Chip implementation context
* @param [out] rssi_gnss_dbm RSSI read on GNSS path in dbm
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_gnss_rssi_test( const void* context, int8_t* rssi_gnss_dbm );
/**
* @brief Parse a raw buffer of context status
*
* @param [in] context_status_bytestream The raw buffer of context status to parse. It is up to the caller to ensure the
* buffer is at least LR11XX_GNSS_CONTEXT_STATUS_LENGTH bytes long
* @param [out] context_status Pointer to a structure of lr11xx_gnss_context_status_t to be filled with information from
* context_status_bytestream
*
* @returns Operation status
*
* @see lr11xx_gnss_get_context_status
*/
lr11xx_status_t lr11xx_gnss_parse_context_status_buffer(
const lr11xx_gnss_context_status_bytestream_t context_status_bytestream,
lr11xx_gnss_context_status_t* context_status );
/**
* @brief Extract the destination from the result returned by a GNSS scan
*
* @param [in] result_buffer Pointer to the buffer holding the result
* @param [in] result_buffer_size Size of the result in byte
* @param [out] destination Destination of the result
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_result_destination( const uint8_t* result_buffer, const uint16_t result_buffer_size,
lr11xx_gnss_destination_t* destination );
/**
* @brief Helper function that computes the age of an almanac.
*
* This function does not call the LR11XX.
* The almanac age is computed based on the following elements:
* - almanac age as obtained from lr11xx_gnss_get_almanac_age_for_satellite
* - the number of days elapsed between Epoch (January 6th 1980) and the GPS rollover reference of the current
* almanac
* - the GPS date of today expressed in number of days elapsed since Epoch
*
* @remark It is important to use for nb_days_between_epoch_and_corresponding_gps_time_rollover the GPS time rollover
* corresponding to the reference of the almanac_date. This is especially true when current date is just after a GPS
* time rollover.
*
* @param [in] almanac_date Almanac date as obtained from lr11xx_gnss_get_almanac_age_for_satellite
* @param [in] nb_days_between_epoch_and_corresponding_gps_time_rollover Number of days elapsed between GPS Epoch and
* the GPS rollover corresponding to the almanac_date
* @param [in] nb_days_since_epoch Number of days elapsed between January 6th 1980 and now
*
* @returns Age of the almanac expressed in number of days between its start valid instant and now
*/
uint16_t lr11xx_gnss_compute_almanac_age( uint16_t almanac_date,
uint16_t nb_days_between_epoch_and_corresponding_gps_time_rollover,
uint16_t nb_days_since_epoch );
/*!
* @brief Start the time acquisition/domulation.
*
* @param [in] context Chip implementation context
* @param [in] effort_mode Effort mode @ref lr11xx_gnss_search_mode_t, note that LR11XX_GNSS_OPTION_HIGH_EFFORT is not
* supported here
* @param [in] option Fetch time option @ref lr11xx_gnss_fetch_time_option_t
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_fetch_time( const void* context, const lr11xx_gnss_search_mode_t effort_mode,
const lr11xx_gnss_fetch_time_option_t option );
/*!
* @brief Read time from LR11XX.
*
* @param [in] context Chip implementation context
* @param [out] time Structure containing the time \ref lr11xx_gnss_time_t
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_time( const void* context, lr11xx_gnss_time_t* time );
/*!
* @brief Reset the internal time.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_reset_time( const void* context );
/*!
* @brief Reset the location and the history Doppler buffer.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_reset_position( const void* context );
/*!
* @brief Read the week number rollover.
*
* @param [in] context Chip implementation context
* @param [out] wn_rollover_status Week number rollover status \ref lr11xx_gnss_week_number_rollover_status_t
* @param [out] wn_number_rollover Week number rollover since 1980
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_week_number_rollover( const void* context,
lr11xx_gnss_week_number_rollover_status_t* wn_rollover_status,
uint8_t* wn_number_rollover );
/*!
* @brief Read demod status.
*
* @param [in] context Chip implementation context
* @param [out] demod_status Demodulation status \ref lr11xx_gnss_demod_status_t
* @param [out] demod_info Demodulation info \ref lr11xx_gnss_demod_info_t
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_demod_status( const void* context, lr11xx_gnss_demod_status_t* demod_status,
lr11xx_gnss_demod_info_t* demod_info );
/*!
* @brief Read cumulative timing.
*
* @param [in] context Chip implementation context
* @param [out] cumulative_timing Cumulative timing status \ref lr11xx_gnss_cumulative_timing_t, The value of time is in
* counter of 32KhZ, to have it in second, the counter must be divided by 32768
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_cumulative_timing( const void* context,
lr11xx_gnss_cumulative_timing_t* cumulative_timing );
/*!
* @brief Compute power consumption based on timings and instantaneous power consumption.
*
* @param [in] cumulative_timing Timings read from lr11xx_gnss_read_cumulative_timing API \ref
* lr11xx_gnss_cumulative_timing_t
* @param [in] instantaneous_power_consumption_ua Instantaneous power consumption associated to each timings \ref
* lr11xx_gnss_instantaneous_power_consumption_ua_t
* @param [out] power_consumption_nah Power consumption computed in nAh
* @param [out] power_consumption_nwh Power consumption computed in nWh
*/
void lr11xx_gnss_compute_power_consumption(
const lr11xx_gnss_cumulative_timing_t* cumulative_timing,
const lr11xx_gnss_instantaneous_power_consumption_ua_t* instantaneous_power_consumption_ua,
uint32_t* power_consumption_nah, uint32_t* power_consumption_nwh );
/*!
* @brief Set the GPS time.
*
* This command is to be used when the 32kHz clock feeding the LR11xx is turned off.
* The LR11xx needs the 32kHz clock to track the absolute time. However if the clock is turned off, it will attempt to
* get the absolute time from GNSS SV demodulation on next GNSS scan, which is power consuming.
* However, if the MCU has capability to keep the absolute time when 32kHz clock is turned off, then it can use this
* command to configure the LR11xx, so that the LR11xx is more power efficient when fetching time from SV signal.
*
* Typical usage is:
* 1. MCU get absolute GPS time from any (possibly not accurate) source (like LoRaWAN network for instance)
* 2. On next scan, the MCU turns on the 32kHz clock, uses lr11xx_gnss_set_time to set the time, with an accuracy that
* depends on its crystal drift, and start the scan
* 3. MCU reads the time from LR11xx (lr11xx_gnss_read_time) and stores it internally
* 4. MCU turns off 32kHz clock of the LR11xx
*
* @param [in] context Chip implementation context
* @param [in] time GPS time in sec from 6 January 1980 00:00:00
* @param [in] time_accuracy Accuracy in millisecond of the time given. If set to 0, the accuracy of time given is
* considered to be unknown
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_set_time( const void* context, const uint32_t time, const uint16_t time_accuracy );
/*!
* @brief Configures the time delay in sec. If the time elapsed from last Assistance position update is larger than this
* delay and there is always no SV detected, LR11xx will reset the Assistance position and the GNSS scan switches from
* assisted scan to autonomous scan.
*
* @param [in] context Chip implementation context
* @param [in] delay Delay in second on 3 bytes
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_config_delay_reset_assistance_position( const void* context, const uint32_t delay );
/*!
* @brief Read the assisted position based on the internal doppler solver executed during lr11xx_gnss_scan or
* lr11xx_gnss_almanac_update_from_sat functions.
*
* @param [in] context Chip implementation context
* @param [out] results \ref lr11xx_gnss_doppler_solver_result_t
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_doppler_solver_result( const void* context,
lr11xx_gnss_doppler_solver_result_t* results );
/*!
* @brief Read the time delay in sec. If the time elapsed from last Assistance position update is larger than this
* delay and there is always no SV detected, LR11xx will reset the Assistance position and the GNSS scan switches from
* assisted scan to autonomous scan.
*
* @param [in] context Chip implementation context
* @param [out] delay Delay in second on 3 bytes
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_delay_reset_assistance_position( const void* context, uint32_t* delay );
/*!
* @brief This command launches one scan to download from satellite almanac parameters broadcasted in one page by one
* constellation.
*
* @param [in] context Chip implementation context
* @param [in] constellation_mask Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values
* @param [in] effort_mode Effort mode @ref lr11xx_gnss_search_mode_t, note that LR11XX_GNSS_OPTION_HIGH_EFFORT is not
* supported here
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_almanac_update_from_sat( const void* context,
const lr11xx_gnss_constellation_mask_t constellation_mask,
const lr11xx_gnss_search_mode_t effort_mode );
/*!
* @brief This command read the number of visible satellites and the time elapsed from last detected satellite list
* update of this constellation.
*
* @param [in] context Chip implementation context
* @param [in] constellation_mask Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values. Only one constellation shall be selected otherwise the command will return an error
* @param [out] nb_visible_sat number of visible satellites
* @param [out] time_elapsed elapsed from last sv list update in ms
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_keep_sync_status( const void* context,
const lr11xx_gnss_constellation_mask_t constellation_mask,
uint8_t* nb_visible_sat, uint32_t* time_elapsed );
/*!
* @brief This command returns the actual state of almanac GPS and Beidou.
*
* @param [in] context Chip implementation context
* @param [in] almanac_status almanac status for GPS and Beidou @ref lr11xx_gnss_read_almanac_status_t
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_almanac_status( const void* context,
lr11xx_gnss_read_almanac_status_t* almanac_status );
/*!
* @brief Configures the almanac update period.
*
* @param [in] context Chip implementation context
* @param [in] constellation_mask Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values. Only one constellation shall be selected otherwise the command will return an error
* @param [in] sv_type sv type to configure. See @ref lr11xx_gnss_sv_type_t for
* the possible values. This parameter has no impact when constellation_mask is set to LR11XX_GNSS_GPS_MASK but is value
* must be a valid lr11xx_gnss_sv_type_t one
* @param [in] period delta in day computed between age of almanac in flash and current day and compared to this period
* to indicate to the application during a lr11xx_gnss_read_almanac_status if it must be downloaded
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_config_almanac_update_period( const void* context,
const lr11xx_gnss_constellation_mask_t constellation_mask,
const lr11xx_gnss_sv_type_t sv_type, const uint16_t period );
/*!
* @brief Read the almanac update period.
*
* @param [in] context Chip implementation context
* @param [in] constellation_mask Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values. Only one constellation shall be selected otherwise the command will return an error
* @param [in] sv_type sv type of satellites to read period from. See @ref lr11xx_gnss_sv_type_t for
* the possible values. This parameter has no impact when constellation_mask is set to LR11XX_GNSS_GPS_MASK but is value
* must be a valid lr11xx_gnss_sv_type_t one
* @param [out] period delta in day computed between age of almanac in flash and current day and compared to this period
* to indicate to the application during a lr11xx_gnss_read_almanac_status if it must be downloaded
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_almanac_update_period( const void* context,
const lr11xx_gnss_constellation_mask_t constellation_mask,
const lr11xx_gnss_sv_type_t sv_type, uint16_t* period );
/*!
* @brief Returns the list of satellite for the next keep sync scan.
*
* @param [in] context Chip implementation context
* @param [in] constellation_mask Bit mask of the constellations to use. See @ref lr11xx_gnss_constellation_t for
* the possible values. Only one constellation shall be selected otherwise the command will return an error
* @param [in] nb_sv_to_get Number of sv to read, the user must call lr11xx_gnss_read_keep_sync_status to know exactly
* the number of satellites in the list
* @param [out] sv_sync_list list of sync. It is up to the caller to ensure it is at least nb_sv_to_get byte long
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_get_sv_sync( const void* context, const lr11xx_gnss_constellation_mask_t constellation_mask,
const uint8_t nb_sv_to_get, uint8_t* sv_sync_list );
/*!
* @brief Configures the ability of the LR11xx to search almanac for each GPS satellites.
*
* @param [in] context Chip implementation context
* @param [in] gps_sat_activated_1_32 32-bit bit mask sat activated: sat 1-32 activated (default value: 0xFFFFFFFF)
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_set_gps_bit_mask_sat_activated( const void* context,
const uint32_t gps_sat_activated_1_32 );
/*!
* @brief Configures the ability of the LR11xx to search almanac for each Beidou satellites.
*
* @param [in] context Chip implementation context
* @param [in] beidou_sat_activated_1_32 32-bit bit mask sat activated: sat 1-32 activated (default value: 0xBFFCBFFF))
* @param [in] beidou_sat_activated_33_63 32-bit bit mask sat activated: sat 33-63 activated (default value: 0xC0007FF))
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_set_beidou_bit_mask_sat_activated( const void* context,
const uint32_t beidou_sat_activated_1_32,
const uint32_t beidou_sat_activated_33_63 );
/*!
* @brief Get the type of scan launched during the last scan
*
* @param [in] context Chip implementation context
* @param [out] last_scan_mode last scan launched. See @ref lr11xx_gnss_scan_mode_launched_t for
* the possible values.
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_gnss_read_last_scan_mode_launched( const void* context,
lr11xx_gnss_scan_mode_launched_t* last_scan_mode );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_GNSS_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,573 @@
/*!
* @file lr11xx_gnss_types.h
*
* @brief GNSS scan driver types for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_GNSS_TYPES_H
#define LR11XX_GNSS_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*!
* @brief Maximal buffer size
*/
#define LR11XX_GNSS_MAX_SIZE_ARRAY 2820 //!< (128sv * 22bytes + 4bytes for CRC)
/*!
* @brief Number of almanacs in full update payload
*/
#define LR11XX_GNSS_FULL_UPDATE_N_ALMANACS ( 128 )
/*!
* @brief Size of the almanac of a single satellite when reading
*/
#define LR11XX_GNSS_SINGLE_ALMANAC_READ_SIZE ( 22 )
/*!
* @brief Size of the almanac of a single satellite when writing
*/
#define LR11XX_GNSS_SINGLE_ALMANAC_WRITE_SIZE ( 20 )
/*!
* @brief Size of the almanac of the GNSS context status buffer
*/
#define LR11XX_GNSS_CONTEXT_STATUS_LENGTH ( 9 )
/*!
* @brief Size of the whole almanac when reading
*/
#define LR11XX_GNSS_FULL_ALMANAC_READ_BUFFER_SIZE \
( ( LR11XX_GNSS_FULL_UPDATE_N_ALMANACS * LR11XX_GNSS_SINGLE_ALMANAC_READ_SIZE ) + 4 )
#define LR11XX_GNSS_DMC_ALMANAC_UPDATE_POS ( 1U )
#define LR11XX_GNSS_DMC_ALMANAC_UPDATE_GPS_MASK ( 0x01UL << LR11XX_GNSS_DMC_ALMANAC_UPDATE_POS )
#define LR11XX_GNSS_DMC_ALMANAC_UPDATE_BEIDOU_MASK ( 0x02UL << LR11XX_GNSS_DMC_ALMANAC_UPDATE_POS )
#define LR11XX_GNSS_DMC_FREQUENCY_SEARCH_SPACE_MSB_POS ( 0U )
#define LR11XX_GNSS_DMC_FREQUENCY_SEARCH_SPACE_MSB_MASK ( 0x01UL << LR11XX_GNSS_DMC_FREQUENCY_SEARCH_SPACE_MSB_POS )
#define LR11XX_GNSS_DMC_FREQUENCY_SEARCH_SPACE_LSB_POS ( 7U )
#define LR11XX_GNSS_DMC_FREQUENCY_SEARCH_SPACE_LSB_MASK ( 0x01UL << LR11XX_GNSS_DMC_FREQUENCY_SEARCH_SPACE_LSB_POS )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Satellite ID type
*/
typedef uint8_t lr11xx_gnss_satellite_id_t;
/*!
* @brief bit mask indicating which information is added in the output payload
*/
enum lr11xx_gnss_result_fields_e
{
LR11XX_GNSS_RESULTS_DOPPLER_ENABLE_MASK = ( 1 << 0 ), //!< Add Doppler information if set
LR11XX_GNSS_RESULTS_DOPPLER_MASK = ( 1 << 1 ), //!< Add up to 14 Doppler if set - up to 7 if not. Valid if @ref
//!< LR11XX_GNSS_RESULTS_DOPPLER_ENABLE_MASK is set
LR11XX_GNSS_RESULTS_BIT_CHANGE_MASK =
( 1 << 2 ), //!< Add bit change if set, LR11XX_GNSS_SCAN_MODE_3_SINGLE_SCAN_AND_5_FAST_SCANS mode only
LR11XX_GNSS_RESULTS_DEMODULATE_TIME_MASK =
( 1 << 3 ), //!< Add time demodulation if set, LR11XX_GNSS_SCAN_MODE_3_SINGLE_SCAN_AND_5_FAST_SCANS mode only
LR11XX_GNSS_RESULTS_REMOVE_TIME_FROM_NAV_MASK = ( 1 << 4 ), //!< Remove time from NAV if set
LR11XX_GNSS_RESULTS_REMOVE_AP_FROM_NAV_MASK = ( 1 << 5 ), //!< Remove aiding position from NAV if set
};
/*!
* @brief Constellation identifiers
*/
typedef enum
{
LR11XX_GNSS_GPS_MASK = 0x01,
LR11XX_GNSS_BEIDOU_MASK = 0x02,
} lr11xx_gnss_constellation_t;
/*!
* @brief Bit mask of constellation configurations
*
* @see lr11xx_gnss_constellation_t
*/
typedef uint8_t lr11xx_gnss_constellation_mask_t;
/*!
* @brief Search mode for GNSS scan
*/
typedef enum
{
LR11XX_GNSS_OPTION_LOW_EFFORT = 0x00, //!< Search all requested satellites or fail, scan duration is low
LR11XX_GNSS_OPTION_MID_EFFORT =
0x01, //!< Add additional search if not all satellites are found, scan duration is standard
LR11XX_GNSS_OPTION_HIGH_EFFORT =
0x02, //!< Add additional search if not all satellites are found, scan duration is very high
} lr11xx_gnss_search_mode_t;
/*!
* @brief GNSS response type indicates the destination: Host MCU, GNSS solver or GNSS DMC
*/
typedef enum
{
LR11XX_GNSS_DESTINATION_HOST = 0x00, //!< Host MCU
LR11XX_GNSS_DESTINATION_SOLVER = 0x01, //!< GNSS Solver
LR11XX_GNSS_DESTINATION_DMC = 0x02, //!< GNSS DMC
} lr11xx_gnss_destination_t;
/*!
* @brief Message to host indicating the status of the message
*/
typedef enum
{
LR11XX_GNSS_HOST_OK = 0x00,
LR11XX_GNSS_HOST_UNEXPECTED_CMD = 0x01,
LR11XX_GNSS_HOST_UNIMPLEMENTED_CMD = 0x02,
LR11XX_GNSS_HOST_INVALID_PARAMETERS = 0x03,
LR11XX_GNSS_HOST_MESSAGE_SANITY_CHECK_ERROR = 0x04,
LR11XX_GNSS_HOST_IQ_CAPTURE_FAILS = 0x05,
LR11XX_GNSS_HOST_NO_TIME = 0x06,
LR11XX_GNSS_HOST_NO_SATELLITE_DETECTED = 0x07,
LR11XX_GNSS_HOST_ALMANAC_IN_FLASH_TOO_OLD = 0x08,
LR11XX_GNSS_HOST_ALMANAC_UPDATE_FAILS_CRC_ERROR = 0x09,
LR11XX_GNSS_HOST_ALMANAC_UPDATE_FAILS_FLASH_INTEGRITY_ERROR = 0x0A,
LR11XX_GNSS_HOST_ALMANAC_UPDATE_NOT_ALLOWED = 0x0C,
LR11XX_GNSS_HOST_ALMANAC_CRC_ERROR = 0x0D,
LR11XX_GNSS_HOST_ALMANAC_VERSION_NOT_SUPPORTED = 0x0E,
LR11XX_GNSS_HOST_NOT_ENOUGH_SV_DETECTED_TO_BUILD_A_NAV_MESSAGE = 0x10,
LR11XX_GNSS_HOST_TIME_DEMODULATION_FAIL = 0x11,
LR11XX_GNSS_HOST_ALMANAC_DEMODULATION_FAIL = 0x12,
LR11XX_GNSS_HOST_AT_LEAST_THE_DETECTED_SV_OF_ONE_CONSTELLATION_ARE_DEACTIVATED = 0x13,
LR11XX_GNSS_HOST_ASSISTANCE_POSITION_POSSIBLY_WRONG_BUT_FAILS_TO_UPDATE = 0x14,
LR11XX_GNSS_HOST_SCAN_ABORTED = 0x15,
LR11XX_GNSS_HOST_NAV_MESSAGE_CANNOT_BE_GENERATED_INTERVAL_GREATER_THAN_63_SEC = 0x16,
} lr11xx_gnss_message_host_status_t;
/*!
* @brief Message to DMC operation code
*/
typedef enum
{
LR11XX_GNSS_DMC_STATUS = 0x18, //!< Status message in payload
} lr11xx_gnss_message_dmc_opcode_t;
/*!
* @brief GNSS single or double scan mode
*/
typedef enum
{
LR11XX_GNSS_SCAN_MODE_0_SINGLE_SCAN_LEGACY = 0x00, //!< Generated NAV message format = NAV3
LR11XX_GNSS_SCAN_MODE_3_SINGLE_SCAN_AND_5_FAST_SCANS = 0x03, //!< Generated NAV message format = NAV3
} lr11xx_gnss_scan_mode_t;
/*!
* @brief GNSS error codes
*/
typedef enum lr11xx_gnss_error_code_e
{
LR11XX_GNSS_NO_ERROR = 0,
LR11XX_GNSS_ERROR_ALMANAC_TOO_OLD = 1,
LR11XX_GNSS_ERROR_UPDATE_CRC_MISMATCH = 2,
LR11XX_GNSS_ERROR_UPDATE_FLASH_MEMORY_INTEGRITY = 3,
LR11XX_GNSS_ERROR_ALMANAC_UPDATE_NOT_ALLOWED = 4, //!< Impossible to update more than one constellation at a time
} lr11xx_gnss_error_code_t;
/*!
* @brief GNSS frequency search space
*/
typedef enum lr11xx_gnss_freq_search_space_e
{
LR11XX_GNSS_FREQUENCY_SEARCH_SPACE_250_HZ = 0,
LR11XX_GNSS_FREQUENCY_SEARCH_SPACE_500_HZ = 1,
LR11XX_GNSS_FREQUENCY_SEARCH_SPACE_1_KHZ = 2,
LR11XX_GNSS_FREQUENCY_SEARCH_SPACE_2_KHZ = 3,
} lr11xx_gnss_freq_search_space_t;
/*!
* @brief GNSS fetch time option
*/
typedef enum lr11xx_gnss_fetch_time_option_e
{
LR11XX_GNSS_SEARCH_TOW = 0, //!< Fetch the time of week. This option can only be used either after a successful
//!< GNSS scan, or after a successful call to lr11xx_gnss_fetch_time with option
//!< LR11XX_GNSS_SEARCH_TOW_WN or LR11XX_GNSS_SEARCH_TOW_WN_ROLLOVER
LR11XX_GNSS_SEARCH_TOW_WN = 1, //!< Fetch the time of week and the week number
LR11XX_GNSS_SEARCH_TOW_WN_ROLLOVER =
2, //!< Fetch the time of week, week number and week number rollover since 1980
} lr11xx_gnss_fetch_time_option_t;
/*!
* @brief GNSS time status
*/
typedef enum lr11xx_gnss_read_time_status_e
{
LR11XX_GNSS_READ_TIME_STATUS_NO_ERROR = 0,
LR11XX_GNSS_READ_TIME_STATUS_32K_STOPPED = 1,
LR11XX_GNSS_READ_TIME_STATUS_WN_TOW_NOT_SET = 2
} lr11xx_gnss_read_time_status_t;
/*!
* @brief GNSS week number number rollover status
*/
typedef enum lr11xx_gnss_week_number_rollover_status_e
{
LR11XX_GNSS_WN_ROLLOVER_ROLLOVER_NEVER_SET = 0,
LR11XX_GNSS_WN_ROLLOVER_ROLLOVER_SET_BY_SCAN = 1,
} lr11xx_gnss_week_number_rollover_status_t;
/*!
* @brief GNSS demod status
*/
typedef enum lr11xx_gnss_demod_status_e
{
LR11XX_GNSS_NO_DEMOD_BDS_ALMANAC_SV31_43 = -21,
LR11XX_GNSS_SV_SELECTED_FOR_DEMOD_LOST = -20,
LR11XX_GNSS_ALMANAC_DEMOD_ERROR = -19,
LR11XX_GNSS_WAKE_UP_AFTER_PREAMBLE = -18,
LR11XX_GNSS_20MS_REAL_TIME_FAILURE = -17,
LR11XX_GNSS_WAKE_UP_SYNC_FAILURE = -16,
LR11XX_GNSS_WEEK_NUMBER_NOT_VALIDATED = -15,
LR11XX_GNSS_NO_ACTIVATED_SAT_IN_SV_LIST = -14,
LR11XX_GNSS_SLEEP_TIME_TOO_LONG = -13,
LR11XX_GNSS_WRONG_TIME_OF_WEEK_DEMOD = -12,
LR11XX_GNSS_PREAMBLE_NOT_VALIDATED = -11,
LR11XX_GNSS_DEMOD_DISABLE = -10,
LR11XX_GNSS_DEMOD_EXTRACTION_FAILURE = -9,
LR11XX_GNSS_NO_BIT_CHANGE_FOUND_DURING_START_DEMOD = -8,
LR11XX_GNSS_NO_BIT_CHANGE_FOUND_DURING_MULTISCAN = -7,
LR11XX_GNSS_NO_SAT_FOUND = -6,
LR11XX_GNSS_WORD_SYNC_LOST = -5,
LR11XX_GNSS_NOT_ENOUGH_PARITY_CHECK_FOUND = -3,
LR11XX_GNSS_TOO_MANY_PARITY_CHECK_FOUND = -2,
LR11XX_GNSS_NO_PARITY_CHECK_FOUND = -1,
LR11XX_GNSS_WORD_SYNC_SEARCH_NOT_STARTED = 0,
LR11XX_GNSS_WORD_SYNC_POTENTIALLY_FOUND = 1,
LR11XX_GNSS_WORD_SYNC_FOUND = 2,
LR11XX_GNSS_TIME_OF_WEEK_FOUND = 3,
LR11XX_GNSS_WEEK_NUMBER_FOUND = 4,
LR11XX_GNSS_ALMANAC_FOUND_BUT_NO_SAVED = 5,
LR11XX_GNSS_HALF_ALMANAC_FOUND_AND_SAVED = 6,
LR11XX_GNSS_ALMANAC_FOUND_AND_SAVED = 7,
} lr11xx_gnss_demod_status_t;
/*!
* @brief GNSS doppler solver error code
*/
typedef enum lr11xx_gnss_doppler_solver_error_code_e
{
LR11XX_GNSS_DOPPLER_SOLVER_NO_ERROR = 0,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_RESIDUE_HIGH = 1,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_NOT_CONVERGED = 2,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_NOT_ENOUGH_SV = 3,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_ILL_MATRIX = 4,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_TIME_ERROR = 5,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_PARTIAL_ALMANAC_TOO_OLD = 6,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_NOT_CONSISTENT_WITH_HISTORY = 7,
LR11XX_GNSS_DOPPLER_SOLVER_ERROR_ALL_ALMANAC_TOO_OLD = 8,
} lr11xx_gnss_doppler_solver_error_code_t;
/*!
* @brief GNSS almanac status
*/
typedef enum lr11xx_gnss_almanac_status_e
{
LR11XX_GNSS_INTERNAL_ACCURACY_TOO_LOW = -4,
LR11XX_GNSS_NO_TIME_SET = -3,
LR11XX_GNSS_IMPOSSIBLE_TO_FIND_NEXT_TIME = -2,
LR11XX_GNSS_NO_PAGE_ID_KNOWN = -1,
LR11XX_GNSS_NO_SAT_TO_UPDATE = 0,
LR11XX_GNSS_AT_LEAST_ONE_SAT_MUST_BE_UPDATED = 1,
} lr11xx_gnss_almanac_status_t;
/*!
* @brief GNSS SV type
*/
typedef enum lr11xx_gnss_sv_type_e
{
LR11XX_GNSS_MEO_SAT = 0,
LR11XX_GNSS_IGSO_SAT = 1,
} lr11xx_gnss_sv_type_t;
typedef enum
{
LR11XX_GNSS_LAST_SCAN_MODE_ASSISTED = 3,
LR11XX_GNSS_LAST_SCAN_MODE_AUTONOMOUS_NO_TIME_NO_AP = 4,
LR11XX_GNSS_LAST_SCAN_MODE_AUTONOMOUS_NO_AP = 5,
LR11XX_GNSS_LAST_SCAN_FETCH_TIME_OR_DOPPLER_SOLVER = 6,
LR11XX_GNSS_LAST_SCAN_ALMANAC_UPDATE = 7,
LR11XX_GNSS_LAST_SCAN_KEEP_SYNC = 8,
LR11XX_GNSS_LAST_SCAN_ALMANAC_UPDATE_1_CONSTELLATION = 9,
LR11XX_GNSS_LAST_SCAN_ALMANAC_UPDATE_2_CONSTELLATIONS = 10,
} lr11xx_gnss_scan_mode_launched_t;
/*!
* @brief GNSS time structure
*/
typedef struct lr11xx_gnss_time_s
{
lr11xx_gnss_read_time_status_t error_code;
uint32_t gps_time_s;
uint32_t nb_us_in_s;
uint32_t time_accuracy;
} lr11xx_gnss_time_t;
/*!
* @brief GNSS demod info structure
*/
typedef struct lr11xx_gnss_demod_info_s
{
bool word_sync_found; //!< 0: no word synchronization found / 1: a word synchronization has been found
bool first_tow_found; //!< 0: no Time Of Week found / 1: a Time Of Week has been found
bool wn_demodulated; //!< 0: no Week number demodulated / 1: a Week Number has been demodulated
bool wn_found; //!< 0: no Week number found / 1: a Week Number has been found
bool sub1_found; //!< 0: subframe ID not found / 1: subframe ID found
bool sub4_found; //!< 0: subframe ID not found / 1: subframe ID found
bool sub5_found; //!< 0: subframe ID not found / 1: subframe ID found
} lr11xx_gnss_demod_info_t;
/*!
* @brief GNSS cumulative_timing
*/
typedef struct lr11xx_gnss_cumulative_timing_s
{
uint32_t init;
uint32_t phase1_gps_capture;
uint32_t phase1_gps_process;
uint32_t multiscan_gps_capture;
uint32_t multiscan_gps_process;
uint32_t multiscan_gps_sleep_32k;
uint32_t phase1_beidou_capture;
uint32_t phase1_beidou_process;
uint32_t multiscan_beidou_capture;
uint32_t multiscan_beidou_process;
uint32_t multiscan_beidou_sleep_32k;
uint32_t demod_capture;
uint32_t demod_process;
uint32_t demod_sleep_32k;
uint32_t demod_sleep_32m;
uint32_t total_gps_capture;
uint32_t total_gps_process;
uint32_t total_gps_sleep_32k;
uint32_t total_gps_sleep_32m;
uint32_t total_gps;
uint32_t total_beidou_capture;
uint32_t total_beidou_process;
uint32_t total_beidou_sleep_32k;
uint32_t total_beidou_sleep_32m;
uint32_t total_beidou;
uint32_t total_capture;
uint32_t total_process;
uint32_t total_sleep_32k;
uint32_t total_sleep_32m;
uint32_t total;
uint32_t last_capture_size_32k_cnt;
uint8_t constellation_demod;
} lr11xx_gnss_cumulative_timing_t;
/*!
* @brief GNSS instantaneous power consumption in ua
*/
typedef struct lr11xx_gnss_instantaneous_power_consumption_ua_s
{
uint16_t board_voltage_mv;
uint16_t init_ua;
uint16_t phase1_gps_capture_ua;
uint16_t phase1_gps_process_ua;
uint16_t multiscan_gps_capture_ua;
uint16_t multiscan_gps_process_ua;
uint16_t phase1_beidou_capture_ua;
uint16_t phase1_beidou_process_ua;
uint16_t multiscan_beidou_capture_ua;
uint16_t multiscan_beidou_process_ua;
uint16_t sleep_32k_ua;
uint16_t demod_sleep_32m_ua;
} lr11xx_gnss_instantaneous_power_consumption_ua_t;
/*!
* @brief
*/
typedef struct lr11xx_gnss_doppler_solver_result_s
{
lr11xx_gnss_doppler_solver_error_code_t error_code;
uint8_t nb_sv_used;
uint16_t one_shot_latitude;
uint16_t one_shot_longitude;
uint16_t one_shot_accuracy;
uint16_t one_shot_xtal_ppb;
uint16_t filtered_latitude;
uint16_t filtered_longitude;
uint16_t filtered_accuracy;
uint16_t filtered_xtal_ppb;
} lr11xx_gnss_doppler_solver_result_t;
/*!
* @brief
*/
typedef struct lr11xx_gnss_read_almanac_status_s
{
lr11xx_gnss_almanac_status_t status_gps;
uint32_t next_gps_time_sat_to_update; //!< Next gps time sat to update: give the duration in milliseconds before
//!< the next start subframe where to catch the new almanac
uint8_t next_gps_nb_subframe_to_demodulate;
uint8_t next_gps_sat_id_to_update_in_sub_4; //!< Next gps sat id to update in subframe 4: satellite number that can
//!< be demodulated in next subframe 4
uint8_t next_gps_sat_id_to_update_in_sub_5; //!< Next gps sat id to update in subframe 5: satellite number that can
//!< be demodulated in next subframe 5
uint8_t nb_sat_gps_to_update; //!< the number total gps and bds that needs almanac update
uint8_t next_gps_subframe_id_start; //!< Next gps subframe ID start: can be equal to 4, 5 or 0
uint32_t sat_id_gps_to_update; //!< Sat id gps to update: bit mask indicating which sat id almanac must be updated.
//!< bit at 0 : almanac is already updated, bit at 1: almanac sat must be updated
uint32_t sat_id_gps_activated; //!< Sat id gps activated : bit mask indicating which sat id is activated . bit at 0
//!< : sat id is not activated, bit at 1: sat id is activated
lr11xx_gnss_almanac_status_t status_beidou;
uint32_t next_beidou_time_sat_to_update; //!< Next beidou time sat to update: give the duration in milliseconds
//!< before the next start subframe where to catch the new almanac
uint8_t next_beidou_nb_subframe_to_demodulate;
uint8_t next_beidou_sat_id_to_update_in_sub_4; //!< Next beidou sat id to update in subframe 4: satellite number
//!< that can be demodulated in next subframe 4
uint8_t next_beidou_sat_id_to_update_in_sub_5; //!< Next beidou sat id to update in subframe 5: satellite number
//!< that can be demodulated in next subframe 5
uint8_t nb_sat_beidou_to_update; //!< the number total gps and bds that needs almanac update
uint8_t next_beidou_subframe_id_start; //!< Next beidou subframe ID start: can be equal to 4, 5 or 0
uint32_t sat_id_beidou_to_update[2]; //!< Sat id beidou to update: bit mask indicating which sat id almanac must be
//!< updated. bit at 0 : almanac is already updated, bit at 1: almanac sat
//!< must be updated
uint32_t sat_id_beidou_activated[2]; //!< Sat id gps activated : bit mask indicating which sat id is activated .
//!< bit at 0 : sat id is not activated, bit at 1: sat id is activated
uint32_t sat_id_beidou_black_list[2]; //!< Sat id bds black list: bit mask indicating which bds sv does not
//!< broadcast the almanac
//!< bit at 0 : sat id is not black listed, bit at 1: sat id is black listed
uint8_t next_am_id; //!< Next AmID: For beidou only. Page 11-24 of subframe 5 are used to broadcast almanac of sat
//!< 31 to 63
} lr11xx_gnss_read_almanac_status_t;
/*!
* @brief Representation of absolute time for GNSS operations
*
* The GNSS absolute time is represented as a 32 bits word that is the number of seconds elapsed since January 6th
* 1980, 00:00:00
*
* The GNSS absolute time must take into account the Leap Seconds between UTC time and GPS time.
*/
typedef uint32_t lr11xx_gnss_date_t;
/*!
* @brief Buffer that holds data for all almanacs full update - when reading
*/
typedef uint8_t lr11xx_gnss_almanac_full_read_bytestream_t[LR11XX_GNSS_FULL_ALMANAC_READ_BUFFER_SIZE];
/*!
* @brief Buffer that holds data for context status
*/
typedef uint8_t lr11xx_gnss_context_status_bytestream_t[LR11XX_GNSS_CONTEXT_STATUS_LENGTH];
/*!
* @brief Assistance position.
*/
typedef struct lr11xx_gnss_solver_assistance_position_s
{
float latitude; //!< Latitude 12 bits (latitude in degree * 2048/90) with resolution 0.044°
float longitude; //!< Longitude 12 bits (longitude in degree * 2048/180) with resolution 0.088°
} lr11xx_gnss_solver_assistance_position_t;
/*!
* @brief Detected SV structure
*/
typedef struct lr11xx_gnss_detected_satellite_s
{
lr11xx_gnss_satellite_id_t satellite_id;
int8_t cnr; //!< Carrier-to-noise ration (C/N) in dB
int16_t doppler; //!< SV doppler in Hz
} lr11xx_gnss_detected_satellite_t;
/*!
* @brief Version structure of the LR11XX GNSS firmware
*/
typedef struct lr11xx_gnss_version_s
{
uint8_t gnss_firmware; //!< Version of the firmware
uint8_t gnss_almanac; //!< Version of the almanac format
} lr11xx_gnss_version_t;
/*!
* @brief Structure for GNSS context status
*/
typedef struct lr11xx_gnss_context_status_s
{
uint8_t firmware_version;
uint32_t global_almanac_crc;
lr11xx_gnss_error_code_t error_code;
bool almanac_update_gps;
bool almanac_update_beidou;
lr11xx_gnss_freq_search_space_t freq_search_space;
} lr11xx_gnss_context_status_t;
/*!
* @brief Structure for information about visible SV
*/
typedef struct lr11xx_gnss_visible_satellite_s
{
lr11xx_gnss_satellite_id_t satellite_id; //!< SV ID
int16_t doppler; //!< SV doppler in Hz
int16_t doppler_error; //!< SV doppler error - step of 125Hz
} lr11xx_gnss_visible_satellite_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_GNSS_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,211 @@
/*!
* @file lr11xx_hal.h
*
* @brief Hardware Abstraction Layer (HAL) interface for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_HAL_H
#define LR11XX_HAL_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/**
* @brief Write this to SPI bus while reading data, or as a dummy/placeholder
*/
#define LR11XX_NOP ( 0x00 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief LR11XX HAL status
*/
typedef enum lr11xx_hal_status_e
{
LR11XX_HAL_STATUS_OK = 0,
LR11XX_HAL_STATUS_ERROR = 3,
} lr11xx_hal_status_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Radio data transfer - write
*
* @param [in] context Radio implementation parameters
* @param [in] command Pointer to the buffer to be transmitted
* @param [in] command_length Buffer size to be transmitted
* @param [in] data Pointer to the buffer to be transmitted
* @param [in] data_length Buffer size to be transmitted
*
* @returns Operation status
*/
lr11xx_hal_status_t lr11xx_hal_write( const void* context, const uint8_t* command, const uint16_t command_length,
const uint8_t* data, const uint16_t data_length );
/*!
* @brief Radio data transfer - read
*
* @remark This is a two-step radio read operation. It consists of writing the command, releasing then re-asserting the
* NSS line, then reading a discarded dummy byte followed by data_length bytes of response data from the transceiver.
* While reading the dummy bytes and the response data, the implementation of this function must ensure that only zero
* bytes (NOP) are written to the SPI bus.
*
* @param [in] context Radio implementation parameters
* @param [in] command Pointer to the buffer to be transmitted
* @param [in] command_length Buffer size to be transmitted
* @param [out] data Pointer to the buffer to be received
* @param [in] data_length Buffer size to be received
*
* @returns Operation status
*
* @remark Some hardware SPI implementations write arbitary values on the MOSI line while reading. If this is done on
* the LR11XX, non-zero values may be interpreted as commands. This driver does not exploit this functionality, and
* expects that zeros be sent on the MOSI line when this command is reading the command response data.
*/
lr11xx_hal_status_t lr11xx_hal_read( const void* context, const uint8_t* command, const uint16_t command_length,
uint8_t* data, const uint16_t data_length );
/*!
* @brief Direct read from the SPI bus
*
* @remark Unlike @ref lr11xx_hal_read, this is a simple direct SPI bus SS/read/nSS operation. While reading the
* response data, the implementation of this function must ensure that only zero bytes (NOP) are written to the SPI bus.
*
* @remark Formerly, that function depended on a lr11xx_hal_write_read API function, which required bidirectional SPI
* communication. Given that all other radio functionality can be implemented with unidirectional SPI, it has been
* decided to make this HAL API change to simplify implementation requirements.
*
* @remark Only required by the @ref lr11xx_system_get_status and @ref lr11xx_bootloader_get_status commands
*
* @param [in] context Radio implementation parameters
* @param [out] data Pointer to the buffer to be received
* @param [in] data_length Buffer size to be received
*
* @returns Operation status
*/
lr11xx_hal_status_t lr11xx_hal_direct_read( const void* context, uint8_t* data, const uint16_t data_length );
/*!
* @brief Reset the radio
*
* @param [in] context Radio implementation parameters
*
* @returns Operation status
*/
lr11xx_hal_status_t lr11xx_hal_reset( const void* context );
/*!
* @brief Wake the radio up.
*
* @param [in] context Radio implementation parameters
*
* @returns Operation status
*/
lr11xx_hal_status_t lr11xx_hal_wakeup( const void* context );
/*!
* @brief Abort a blocking command
*
* @param [in] context Radio implementation parameters
*
* @returns Operation status
*/
lr11xx_hal_status_t lr11xx_hal_abort_blocking_cmd( const void* context );
/*!
* @brief Return the computed CRC
*
* @param [in] initial_value initial value of the CRC
* @param [in] buffer Buffer containing data used to compute the CRC
* @param [in] length Length of buffer
*
* @returns CRC value
*/
inline static uint8_t lr11xx_hal_compute_crc( const uint8_t initial_value, const uint8_t* buffer, uint16_t length )
{
uint8_t crc = initial_value;
if (buffer == NULL) {
printf("Error: buffer is NULL!\n");
return 0;
}
for( uint16_t i = 0; i < length; i++ )
{
// printf("%d %d %d\r\n",i,length,sizeof(buffer) / sizeof(buffer[0]));
uint8_t extract = buffer[i];
uint8_t sum;
for( uint8_t j = 8; j > 0; j-- )
{
sum = ( crc ^ extract ) & 0x01;
crc >>= 1;
if( sum != 0 )
{
crc ^= 0x65;
}
extract >>= 1;
}
}
return crc;
}
#ifdef __cplusplus
}
#endif
#endif // LR11XX_HAL_H

View File

@@ -0,0 +1,138 @@
/*!
* @file lr11xx_lr_fhss.h
*
* @brief LR_FHSS driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_LR_FHSS_H
#define LR11XX_LR_FHSS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_lr_fhss_types.h"
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/**
* @brief Length, in bytes, of a LR-FHSS sync word
*/
#define LR_FHSS_SYNC_WORD_BYTES ( 4 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Initialize the LR_FHSS
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_lr_fhss_init( const void* context );
/**
* @brief Get the delay in microsecond between the last bit sent and the TX done interrupt
*
* @param [in] params lr11xx LR-FHSS parameter structure
* @param [in] payload_length Length of application-layer payload
*
* @returns Delay in microseconds
*/
uint16_t lr11xx_lr_fhss_get_bit_delay_in_us( const lr11xx_lr_fhss_params_t* params, uint16_t payload_length );
/*!
* @brief Configure a payload to be sent with LR_FHSS
*
* When calling this method, lr11xx_radio_set_lr_fhss_sync_word is implicitely called to configure the sync word.
* Note that the syncword must be 4 bytes long.
*
* @param [in] context Chip implementation context
* @param [in] lr_fhss_params Parameter configuration structure of the LRFHSS
* @param [in] hop_sequence_id Seed used to derive the hopping sequence pattern. Only the nine LSBs are taken into
* account
* @param [in] payload The payload to send. It is the responsibility of the caller to ensure that this references an
* array containing at least payload_length elements
* @param [in] payload_length The length of the payload
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_lr_fhss_build_frame( const void* context, const lr11xx_lr_fhss_params_t* lr_fhss_params,
uint16_t hop_sequence_id, const uint8_t* payload, uint8_t payload_length );
/*!
* @brief Get the time on air in ms for LR-FHSS transmission
*
* @param [in] params LR11XX LR-FHSS parameter structure
* @param [in] payload_length Length of application-layer payload
*
* @returns Time-on-air value in ms for LR-FHSS transmission
*/
uint32_t lr11xx_lr_fhss_get_time_on_air_in_ms( const lr11xx_lr_fhss_params_t* params, uint16_t payload_length );
/**
* @brief Return the number of hop sequences available using the given parameters
*
* @param [in] lr_fhss_params Parameter configuration structure of the LRFHSS
*
* @return Returns the number of valid hop sequences (512 or 384)
*/
unsigned int lr11xx_lr_fhss_get_hop_sequence_count( const lr11xx_lr_fhss_params_t* lr_fhss_params );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_LR_FHSS_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,65 @@
/*!
* @file lr11xx_lr_fhss_types.h
*
* @brief LR_FHSS types definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_LR_FHSS_TYPES_H
#define LR11XX_LR_FHSS_TYPES_H
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr_fhss_v1_base_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief LR FHSS parameter structure
*/
typedef struct
{
lr_fhss_v1_params_t lr_fhss_params; //!< Base LR FHSS parameters
int8_t device_offset; //<! Per device offset to avoid collisions over the air. Possible values:
//<! - if lr_fhss_params.grid == LR_FHSS_V1_GRID_25391_HZ:
//<! [-26, 25]
//<! - if lr_fhss_params.grid == LR_FHSS_V1_GRID_3906_HZ:
//<! [-4, 3]
} lr11xx_lr_fhss_params_t;
#endif // LR11XX_LR_FHSS_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,95 @@
/**
* @file lr11xx_radio_timings.h
*
* @brief LR11XX timing helper functions definition
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_RADIO_TIMINGS_H
#define LR11XX_RADIO_TIMINGS_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_radio_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/**
* @brief Get the time between the last bit sent (on Tx side) and the Rx done event (on Rx side)
*
* @param [in] mod_params Pointer to a structure holding the LoRa modulation parameters used for the computation
*
* @returns Delay in microsecond
*/
uint32_t lr11xx_radio_timings_get_delay_between_last_bit_sent_and_rx_done_in_us(
const lr11xx_radio_mod_params_lora_t* mod_params );
/**
* @brief Get the time between the last bit sent and the Tx done event
*
* @param [in] ramp_time Power amplifier ramp time
*
* @returns Delay in microsecond
*/
uint32_t lr11xx_radio_timings_get_delay_between_last_bit_sent_and_tx_done_in_us(
const lr11xx_radio_ramp_time_t ramp_time );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_RADIO_TIMINGS_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,654 @@
/*!
* @file lr11xx_radio_types.h
*
* @brief Radio driver types for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_RADIO_TYPES_H
#define LR11XX_RADIO_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Bit mask to set to indicate a LR-FHSS bitrate is defined in steps of 1/256 bit per seconds
*/
#define LR11XX_RADIO_LR_FHSS_BITRATE_DIVIDE_BY_256 ( 0x80000000 )
/*!
* @brief LR-FHSS bitrate value at 488.28125 bps defined as steps of 1/256 bitrate per seconds
*/
#define LR11XX_RADIO_LR_FHSS_BITRATE_IN_256_BPS_STEPS ( 125000 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Power Amplifier Selection values
*
* - Low-power Power Amplifier can reach up to 14dBm
* - High-power Power Amplifier can reach up to 22 dBm
*/
typedef enum
{
LR11XX_RADIO_PA_SEL_LP = 0x00, //!< Low-power Power Amplifier
LR11XX_RADIO_PA_SEL_HP = 0x01, //!< High-power Power Amplifier
LR11XX_RADIO_PA_SEL_HF = 0x02, //!< High-frequency Power Amplifier
} lr11xx_radio_pa_selection_t;
/*!
* @brief GFSK Address Filtering configurations
*
* If Address Filtering is enabled but a wrong address is received, therefore the reception is aborted and the address
* error flag of packet status is set.
*/
typedef enum
{
LR11XX_RADIO_GFSK_ADDRESS_FILTERING_DISABLE = 0x00, //!< Filter deactivated
LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_ADDRESS = 0x01, //!< Filter on Node Address
LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_AND_BROADCAST_ADDRESSES =
0x02, //!< Filtering on Node and Broadcast addresses
} lr11xx_radio_gfsk_address_filtering_t;
/*!
* @brief Chip mode after successfull transmission or reception
*
* Unused for RX duty cycle and AutoTxRx operations
*/
typedef enum
{
LR11XX_RADIO_FALLBACK_STDBY_RC = 0x01, //!< Standby RC (Default)
LR11XX_RADIO_FALLBACK_STDBY_XOSC = 0x02, //!< Standby XOSC
LR11XX_RADIO_FALLBACK_FS = 0x03 //!< FS
} lr11xx_radio_fallback_modes_t;
/*!
* @brief Ramping time for PA
*
* This parameter is the ramping time of the PA. A high value improves spectral quality.
*/
typedef enum
{
LR11XX_RADIO_RAMP_16_US = 0x00, //!< 16 us Ramp Time
LR11XX_RADIO_RAMP_32_US = 0x01, //!< 32 us Ramp Time
LR11XX_RADIO_RAMP_48_US = 0x02, //!< 48 us Ramp Time (Default)
LR11XX_RADIO_RAMP_64_US = 0x03, //!< 64 us Ramp Time
LR11XX_RADIO_RAMP_80_US = 0x04, //!< 80 us Ramp Time
LR11XX_RADIO_RAMP_96_US = 0x05, //!< 96 us Ramp Time
LR11XX_RADIO_RAMP_112_US = 0x06, //!< 112 us Ramp Time
LR11XX_RADIO_RAMP_128_US = 0x07, //!< 128 us Ramp Time
LR11XX_RADIO_RAMP_144_US = 0x08, //!< 144 us Ramp Time
LR11XX_RADIO_RAMP_160_US = 0x09, //!< 160 us Ramp Time
LR11XX_RADIO_RAMP_176_US = 0x0A, //!< 176 us Ramp Time
LR11XX_RADIO_RAMP_192_US = 0x0B, //!< 192 us Ramp Time
LR11XX_RADIO_RAMP_208_US = 0x0C, //!< 208 us Ramp Time
LR11XX_RADIO_RAMP_240_US = 0x0D, //!< 240 us Ramp Time
LR11XX_RADIO_RAMP_272_US = 0x0E, //!< 272 us Ramp Time
LR11XX_RADIO_RAMP_304_US = 0x0F, //!< 304 us Ramp Time
} lr11xx_radio_ramp_time_t;
/*!
* @brief LoRa network type configuration
*/
typedef enum
{
LR11XX_RADIO_LORA_NETWORK_PRIVATE = 0x00, //!< LoRa private network
LR11XX_RADIO_LORA_NETWORK_PUBLIC = 0x01, //!< LoRa public network
} lr11xx_radio_lora_network_type_t;
/*!
* @brief LoRa Spreading Factor configurations
*/
typedef enum
{
LR11XX_RADIO_LORA_SF5 = 0x05, //!< Spreading Factor 5
LR11XX_RADIO_LORA_SF6 = 0x06, //!< Spreading Factor 6
LR11XX_RADIO_LORA_SF7 = 0x07, //!< Spreading Factor 7
LR11XX_RADIO_LORA_SF8 = 0x08, //!< Spreading Factor 8
LR11XX_RADIO_LORA_SF9 = 0x09, //!< Spreading Factor 9
LR11XX_RADIO_LORA_SF10 = 0x0A, //!< Spreading Factor 10
LR11XX_RADIO_LORA_SF11 = 0x0B, //!< Spreading Factor 11
LR11XX_RADIO_LORA_SF12 = 0x0C, //!< Spreading Factor 12
} lr11xx_radio_lora_sf_t;
/*!
* @brief LoRa Bandwidth configurations
*/
typedef enum
{
LR11XX_RADIO_LORA_BW_10 = 0x08, //!< Bandwidth 10.42 kHz
LR11XX_RADIO_LORA_BW_15 = 0x01, //!< Bandwidth 15.63 kHz
LR11XX_RADIO_LORA_BW_20 = 0x09, //!< Bandwidth 20.83 kHz
LR11XX_RADIO_LORA_BW_31 = 0x02, //!< Bandwidth 31.25 kHz
LR11XX_RADIO_LORA_BW_41 = 0x0A, //!< Bandwidth 41.67 kHz
LR11XX_RADIO_LORA_BW_62 = 0x03, //!< Bandwidth 62.50 kHz
LR11XX_RADIO_LORA_BW_125 = 0x04, //!< Bandwidth 125.00 kHz
LR11XX_RADIO_LORA_BW_250 = 0x05, //!< Bandwidth 250.00 kHz
LR11XX_RADIO_LORA_BW_500 = 0x06, //!< Bandwidth 500.00 kHz
LR11XX_RADIO_LORA_BW_200 = 0x0D, //!< Bandwidth 203.00 kHz, 2G4 and compatible with LR112x chips only
LR11XX_RADIO_LORA_BW_400 = 0x0E, //!< Bandwidth 406.00 kHz, 2G4 and compatible with LR112x chips only
LR11XX_RADIO_LORA_BW_800 = 0x0F, //!< Bandwidth 812.00 kHz, 2G4 and compatible with LR112x chips only
} lr11xx_radio_lora_bw_t;
/*!
* @brief LoRa Coding Rate configurations
*/
typedef enum
{
LR11XX_RADIO_LORA_NO_CR = 0x00, //!< No Coding Rate
LR11XX_RADIO_LORA_CR_4_5 = 0x01, //!< Coding Rate 4/5 Short Interleaver
LR11XX_RADIO_LORA_CR_4_6 = 0x02, //!< Coding Rate 4/6 Short Interleaver
LR11XX_RADIO_LORA_CR_4_7 = 0x03, //!< Coding Rate 4/7 Short Interleaver
LR11XX_RADIO_LORA_CR_4_8 = 0x04, //!< Coding Rate 4/8 Short Interleaver
LR11XX_RADIO_LORA_CR_LI_4_5 = 0x05, //!< Coding Rate 4/5 Long Interleaver
LR11XX_RADIO_LORA_CR_LI_4_6 = 0x06, //!< Coding Rate 4/6 Long Interleaver
LR11XX_RADIO_LORA_CR_LI_4_8 = 0x07, //!< Coding Rate 4/8 Long Interleaver
} lr11xx_radio_lora_cr_t;
/*!
* @brief Values for intermediary mode
*/
typedef enum
{
LR11XX_RADIO_MODE_SLEEP = 0x00, //!< Sleep / Not recommended with LR1110 FW from 0x0303 to 0x0307 and LR1120 FW
//!< 0x0101 in case of transition from Rx to Tx in LoRa
LR11XX_RADIO_MODE_STANDBY_RC = 0x01, //!< Standby RC
LR11XX_RADIO_MODE_STANDBY_XOSC = 0x02, //!< Standby XOSC
LR11XX_RADIO_MODE_FS = 0x03 //!< Frequency Synthesis
} lr11xx_radio_intermediary_mode_t;
/*!
* @brief GFSK Cyclic Redundancy Check configurations
*
* If this value is set to something other than CRC_OFF, a CRC is automatically computed and added after the end of the
* payload on transmitter side. On receiver side, the CRC check is automatically processed.
*/
typedef enum
{
LR11XX_RADIO_GFSK_CRC_OFF = 0x01, //!< CRC check deactivated
LR11XX_RADIO_GFSK_CRC_1_BYTE = 0x00,
LR11XX_RADIO_GFSK_CRC_2_BYTES = 0x02,
LR11XX_RADIO_GFSK_CRC_1_BYTE_INV = 0x04,
LR11XX_RADIO_GFSK_CRC_2_BYTES_INV = 0x06,
} lr11xx_radio_gfsk_crc_type_t;
/*!
* @brief GFSK data whitening configurations
*/
typedef enum
{
LR11XX_RADIO_GFSK_DC_FREE_OFF = 0x00, //!< Whitening deactivated
LR11XX_RADIO_GFSK_DC_FREE_WHITENING = 0x01, //!< Whitening enabled
LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP = 0x03, //!< Whitening enabled - SX128x compatibility
} lr11xx_radio_gfsk_dc_free_t;
/*!
* @brief GFSK Header Type configurations
*
* This parameter indicates whether or not the payload length is sent and read over the air.
*
* If the payload length is known beforehand by both transmitter and receiver, therefore there is no need to send it
* over the air. Otherwise, setting this parameter to LR11XX_RADIO_GFSK_PKT_VAR_LEN will make the modem to automatically
* prepand a byte containing the payload length to the the payload on transmitter side. On receiver side, this first
* byte is read to set the payload length to read.
*
* This configuration is only available for GFSK packet types.
*/
typedef enum
{
LR11XX_RADIO_GFSK_PKT_FIX_LEN = 0x00, //!< Payload length is not sent/read over the air
LR11XX_RADIO_GFSK_PKT_VAR_LEN = 0x01, //!< Payload length is sent/read over the air
LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP =
0x02, //!< Payload length is sent/read over the air - SX128x compatibility
} lr11xx_radio_gfsk_pkt_len_modes_t;
/*!
* @brief GFSK Preamble Detector Length configurations
*
* This parameter sets the minimum length of preamble bits to be received to continue reception of incoming packet. If a
* packet with preamble length lower than this value is being received, the reception stops without generating IRQ.
*
* This parameter has no impact on TX operations.
*/
typedef enum
{
LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_OFF = 0x00,
LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_8BITS = 0x04,
LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_16BITS = 0x05,
LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_24BITS = 0x06,
LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_32BITS = 0x07
} lr11xx_radio_gfsk_preamble_detector_t;
/*!
* @brief LoRa Cyclic Redundancy Check configurations
*/
typedef enum
{
LR11XX_RADIO_LORA_CRC_OFF = 0x00, //!< CRC deactivated
LR11XX_RADIO_LORA_CRC_ON = 0x01, //!< CRC activated
} lr11xx_radio_lora_crc_t;
/*!
* @brief LoRa Header type configurations
*/
typedef enum
{
LR11XX_RADIO_LORA_PKT_EXPLICIT = 0x00, //!< Explicit header: transmitted over the air
LR11XX_RADIO_LORA_PKT_IMPLICIT = 0x01, //!< Implicit header: not transmitted over the air
} lr11xx_radio_lora_pkt_len_modes_t;
/*!
* @brief LoRa IQ mode configurations
*
* LoRa IQ modes are mutually exclusives: a physical packet sent with standard IQ will not be received by a receiver
* configured with inverted IQ.
*/
typedef enum
{
LR11XX_RADIO_LORA_IQ_STANDARD = 0x00, //!< IQ standard
LR11XX_RADIO_LORA_IQ_INVERTED = 0x01, //!< IQ inverted
} lr11xx_radio_lora_iq_t;
/*!
* @brief Packet type values
*/
typedef enum
{
LR11XX_RADIO_PKT_NONE = 0x00, //!< State after cold start, Wi-Fi or GNSS capture
LR11XX_RADIO_PKT_TYPE_GFSK = 0x01, //!< GFSK modulation
LR11XX_RADIO_PKT_TYPE_LORA = 0x02, //!< LoRa modulation
LR11XX_RADIO_PKT_TYPE_BPSK = 0x03, //!< BPSK modulation
LR11XX_RADIO_PKT_TYPE_LR_FHSS = 0x04, //!< LR-FHSS modulation
LR11XX_RADIO_PKT_TYPE_RTTOF = 0x05, //!< RTToF (Ranging) packet
} lr11xx_radio_pkt_type_t;
/*!
* @brief Select power amplifier supply source
*/
typedef enum
{
LR11XX_RADIO_PA_REG_SUPPLY_VREG = 0x00, //!< Power amplifier supplied by the main regulator
LR11XX_RADIO_PA_REG_SUPPLY_VBAT = 0x01 //!< Power amplifier supplied by the battery
} lr11xx_radio_pa_reg_supply_t;
/*!
* @brief RX Duty Cycle Modes
*/
typedef enum
{
LR11XX_RADIO_RX_DUTY_CYCLE_MODE_RX = 0x00, //!< LoRa/GFSK: Uses Rx for listening to packets
LR11XX_RADIO_RX_DUTY_CYCLE_MODE_CAD = 0x01, //!< Only in LoRa: Uses CAD to listen for over-the-air activity
} lr11xx_radio_rx_duty_cycle_mode_t;
/*!
* @brief GFSK Bandwidth configurations
*/
typedef enum
{
LR11XX_RADIO_GFSK_BW_4800 = 0x1F, //!< Bandwidth 4.8 kHz DSB
LR11XX_RADIO_GFSK_BW_5800 = 0x17, //!< Bandwidth 5.8 kHz DSB
LR11XX_RADIO_GFSK_BW_7300 = 0x0F, //!< Bandwidth 7.3 kHz DSB
LR11XX_RADIO_GFSK_BW_9700 = 0x1E, //!< Bandwidth 9.7 kHz DSB
LR11XX_RADIO_GFSK_BW_11700 = 0x16, //!< Bandwidth 11.7 kHz DSB
LR11XX_RADIO_GFSK_BW_14600 = 0x0E, //!< Bandwidth 14.6 kHz DSB
LR11XX_RADIO_GFSK_BW_19500 = 0x1D, //!< Bandwidth 19.5 kHz DSB
LR11XX_RADIO_GFSK_BW_23400 = 0x15, //!< Bandwidth 23.4 kHz DSB
LR11XX_RADIO_GFSK_BW_29300 = 0x0D, //!< Bandwidth 29.3 kHz DSB
LR11XX_RADIO_GFSK_BW_39000 = 0x1C, //!< Bandwidth 39.0 kHz DSB
LR11XX_RADIO_GFSK_BW_46900 = 0x14, //!< Bandwidth 46.9 kHz DSB
LR11XX_RADIO_GFSK_BW_58600 = 0x0C, //!< Bandwidth 58.6 kHz DSB
LR11XX_RADIO_GFSK_BW_78200 = 0x1B, //!< Bandwidth 78.2 kHz DSB
LR11XX_RADIO_GFSK_BW_93800 = 0x13, //!< Bandwidth 93.8 kHz DSB
LR11XX_RADIO_GFSK_BW_117300 = 0x0B, //!< Bandwidth 117.3 kHz DSB
LR11XX_RADIO_GFSK_BW_156200 = 0x1A, //!< Bandwidth 156.2 kHz DSB
LR11XX_RADIO_GFSK_BW_187200 = 0x12, //!< Bandwidth 187.2 kHz DSB
LR11XX_RADIO_GFSK_BW_234300 = 0x0A, //!< Bandwidth 232.3 kHz DSB
LR11XX_RADIO_GFSK_BW_312000 = 0x19, //!< Bandwidth 312.0 kHz DSB
LR11XX_RADIO_GFSK_BW_373600 = 0x11, //!< Bandwidth 373.6 kHz DSB
LR11XX_RADIO_GFSK_BW_467000 = 0x09 //!< Bandwidth 467.0 kHz DSB
} lr11xx_radio_gfsk_bw_t;
/*!
* @brief Possible automatic actions when Channel Activity Detection operations terminate
*
* For RADIO_EXIT_MODE_CAD_RX, LR11XX enters RX mode on activity detected. The timeout value for this RX operation is
* defined as:
*
* \f$ 31.25us \times timeout \f$
*
* With \f$ timeout \f$ defined in RadioCadParams_t::timeout
*
* If the CAD operation is negative with RADIO_CAD_EXIT_MODE_RX or if CAD operation is positive with
* RADIO_CAD_EXIT_MODE_TX, therefore the LR11XX enters Standby RC mode.
*/
typedef enum
{
LR11XX_RADIO_CAD_EXIT_MODE_STANDBYRC = 0x00, //!< Enter standby RC mode after CAD operation
LR11XX_RADIO_CAD_EXIT_MODE_RX = 0x01, //!< Enter in RX mode if an activity is detected
LR11XX_RADIO_CAD_EXIT_MODE_TX = 0x10, //!< Enter in TX mode if no activity is detected
} lr11xx_radio_cad_exit_mode_t;
/*!
* @brief Pulse shape configurations
*/
typedef enum
{
LR11XX_RADIO_GFSK_PULSE_SHAPE_OFF = 0x00, //!< No filter applied
LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_03 = 0x08, //!< Gaussian BT 0.3
LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_05 = 0x09, //!< Gaussian BT 0.5
LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_07 = 0x0A, //!< Gaussian BT 0.7
LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_1 = 0x0B //!< Gaussian BT 1.0
} lr11xx_radio_gfsk_pulse_shape_t;
/*!
* @brief BPSK pulse shape configurations
*/
typedef enum
{
LR11XX_RADIO_DBPSK_PULSE_SHAPE = 0x16, //!< Double OSR / RRC / BT 0.7
} lr11xx_radio_bpsk_pulse_shape_t;
/*!
* @brief LR-FHSS bitrate configurations
*/
typedef enum
{
LR11XX_RADIO_LR_FHSS_BITRATE_488_BPS =
( int ) ( LR11XX_RADIO_LR_FHSS_BITRATE_DIVIDE_BY_256 +
LR11XX_RADIO_LR_FHSS_BITRATE_IN_256_BPS_STEPS ), //!< 488.28215 bps
} lr11xx_radio_lr_fhss_bitrate_t;
/*!
* @brief LR-FHSS pulse shape configurations
*/
typedef enum
{
LR11XX_RADIO_LR_FHSS_PULSE_SHAPE_BT_1 = 0x0B //!< Gaussian BT 1.0
} lr11xx_radio_lr_fhss_pulse_shape_t;
/*!
* @brief Channel Activity Detection parameters
*
* Parameters detPeak and detMin are to be used for tuning the sensitivity of Channel Activity Detection. It depends on
* Spreading Factor, Bandwidth and symbolNum.
*
* For detPeak, the 5 MSBits are encoding the integer part, the 3 LSBits are encoding 1/8 of the decimal part. For
* instance, \f$detPeak = 50\f$ (= 0x32) leads to a ratio being \f$6 + 2 * 1/8 = 6.25\f$.
*
* detMin is unit free and represents the ratio between the minimal power of a correlation peak and measurement gain
* that can be considered as a peak detection. It helps to avoid detection on noise. Authorized values a from 0 to 181.
*/
typedef struct lr11xx_radio_cad_params_s
{
uint8_t cad_symb_nb; //!< Number of symbols used for CAD detection
uint8_t cad_detect_peak; //!< Ratio for CAD between correlator peak and average
//!< (Default 0x32)
uint8_t cad_detect_min; //!< Minimum power of the correlation peak to be
//!< considered as a positive CAD (Default 0x0A)
lr11xx_radio_cad_exit_mode_t cad_exit_mode; //!< Automated action on CAD completion
uint32_t cad_timeout; //!< Value used to compute timeout
} lr11xx_radio_cad_params_t;
/*!
* @brief Status of GFSK received packet
*/
typedef struct lr11xx_radio_pkt_status_gfsk_s
{
int8_t rssi_sync_in_dbm; //!< RSSI value latched on detection of the last received packet Sync Address
int8_t rssi_avg_in_dbm; //!< RSSI averaged over the payload of the last received packet
uint8_t rx_len_in_bytes; //!< Length of the last received packet [Bytes]
bool is_addr_err; //!< Address filtering status. Asserted if received packet address does not match node address
//!< nor broadcast address
bool is_crc_err; //!< CRC status of the current packet (applicable only in RX, with CRC enabled)
bool is_len_err; //!< Asserted when the length of last received packet is greater than the maximal length
//!< (applicable only in RX with variable length packet)
bool is_abort_err; //!< Asserted when the current packet has been aborted (applicable in RX and TX)
bool is_received; //!< Asserted when packet reception is done (applicable in RX)
bool is_sent; //!< Asserted when packet transmission is done (applicable in TX)
} lr11xx_radio_pkt_status_gfsk_t;
/*!
* @brief Status of received packet
*/
typedef struct lr11xx_radio_pkt_status_lora_s
{
int8_t rssi_pkt_in_dbm; //!< Average RSSI over last received packet.
int8_t snr_pkt_in_db; //!< SNR estimated on last received packet.
int8_t signal_rssi_pkt_in_dbm; //!< RSSI of last packet latched after
} lr11xx_radio_pkt_status_lora_t;
/*!
* @brief Length and offset of received packet
*/
typedef struct lr11xx_radio_rx_buffer_status_s
{
uint8_t pld_len_in_bytes; //!< Length of received packet [Bytes]
uint8_t buffer_start_pointer; //!< Offset in the reception buffer of
//!< first byte received [Bytes]
} lr11xx_radio_rx_buffer_status_t;
/*!
* @brief GFSK packet statistic structure
*/
typedef struct lr11xx_radio_stats_gfsk_s
{
uint16_t nb_pkt_received; //!< Total number of received packets
uint16_t nb_pkt_crc_error; //!< Total number of received packets with CRC error
uint16_t nb_pkt_len_error; //!< Total number of received packets with a length error
} lr11xx_radio_stats_gfsk_t;
/*!
* @brief LoRa packet statistic structure
*/
typedef struct lr11xx_radio_stats_lora_s
{
uint16_t nb_pkt_received; //!< Total number of received packets
uint16_t nb_pkt_crc_error; //!< Total number of received packets with CRC error
uint16_t nb_pkt_header_error; //!< Total number of packets with header error
uint16_t nb_pkt_falsesync; //!< Total number of false sync
} lr11xx_radio_stats_lora_t;
/*!
* @brief Modulation configuration for GFSK packet
*/
typedef struct lr11xx_radio_mod_params_gfsk_s
{
uint32_t br_in_bps; //!< GFSK bitrate [bit/s]
lr11xx_radio_gfsk_pulse_shape_t pulse_shape; //!< GFSK pulse shape
lr11xx_radio_gfsk_bw_t bw_dsb_param; //!< GFSK bandwidth
uint32_t fdev_in_hz; //!< GFSK frequency deviation [Hz]
} lr11xx_radio_mod_params_gfsk_t;
/*!
* @brief Modulation configuration for BPSK packet
*/
typedef struct lr11xx_radio_mod_params_bpsk_s
{
uint32_t br_in_bps; //!< BPSK bitrate [bit/s]
lr11xx_radio_bpsk_pulse_shape_t pulse_shape; //!< BPSK pulse shape
} lr11xx_radio_mod_params_bpsk_t;
/*!
* @brief Modulation configuration for LoRa packet
*/
typedef struct lr11xx_radio_mod_params_lora_s
{
lr11xx_radio_lora_sf_t sf; //!< LoRa spreading factor
lr11xx_radio_lora_bw_t bw; //!< LoRa bandwidth
lr11xx_radio_lora_cr_t cr; //!< LoRa coding rate
uint8_t ldro; //!< LoRa LDRO
} lr11xx_radio_mod_params_lora_t;
/*!
* @brief Modulation configuration for LR-FHSS packets
*/
typedef struct lr11xx_radio_mod_params_lr_fhss_s
{
lr11xx_radio_lr_fhss_bitrate_t br_in_bps; //!< LR-FHSS bitrate
lr11xx_radio_lr_fhss_pulse_shape_t pulse_shape; //!< LR-FHSS pulse shape
} lr11xx_radio_mod_params_lr_fhss_t;
/*!
* @brief Packet parameter configuration for GFSK packets
*/
typedef struct lr11xx_radio_pkt_params_gfsk_s
{
uint16_t preamble_len_in_bits; //!< GFSK Preamble length [bits]
lr11xx_radio_gfsk_preamble_detector_t preamble_detector; //!< GFSK Preamble detection configuration
uint8_t sync_word_len_in_bits; //!< GFSK Syncword length [bits]
lr11xx_radio_gfsk_address_filtering_t address_filtering; //!< GFSK Address filtering/comparison configuration
lr11xx_radio_gfsk_pkt_len_modes_t header_type; //!< GFSK Header type configuration
uint8_t pld_len_in_bytes; //!< GFSK Payload length [bytes]
lr11xx_radio_gfsk_crc_type_t crc_type; //!< GFSK CRC configuration
lr11xx_radio_gfsk_dc_free_t dc_free; //!< GFSK Whitening configuration
} lr11xx_radio_pkt_params_gfsk_t;
/*!
* @brief Packet parameter configuration for BPSK packets
*/
typedef struct lr11xx_radio_pkt_params_bpsk_s
{
uint8_t pld_len_in_bytes; //!< Payload length [bytes]
uint16_t ramp_up_delay; //!< Delay to fine tune ramp-up time, if non-zero
uint16_t ramp_down_delay; //!< Delay to fine tune ramp-down time, if non-zero
uint16_t pld_len_in_bits; //!< If non-zero, used to ramp down PA before end of a payload with length that is not a
//!< multiple of 8. pld_len_in_bits <= pld_len_in_bytes * 8
} lr11xx_radio_pkt_params_bpsk_t;
/*!
* @brief Packet parameter configuration for LoRa packets
*/
typedef struct lr11xx_radio_pkt_params_lora_s
{
uint16_t preamble_len_in_symb; //!< LoRa Preamble length [symbols]
lr11xx_radio_lora_pkt_len_modes_t header_type; //!< LoRa Header type configuration
uint8_t pld_len_in_bytes; //!< LoRa Payload length [bytes]
lr11xx_radio_lora_crc_t crc; //!< LoRa CRC configuration
lr11xx_radio_lora_iq_t iq; //!< LoRa IQ configuration
} lr11xx_radio_pkt_params_lora_t;
/*!
* @brief Configuration of Power Amplifier
*
* @ref pa_duty_cycle controls the duty cycle of Power Amplifier according to:
* \f$ dutycycle = 0.2 + 0.04 \times pa_duty_cycle \f$
* It can be used to adapt the TX multi-band operation using a single-matching network.
*
* The allowed duty cycle values for LPA are from 0.2 to 0.48 (by step of 0.04). Therefore possible values for
* pa_duty_cycle go from 0 to 7.
*
* The allowed duty cycle values for HPA go from 0.2 to 0.36 (by step of 0.04). Therefore in this case, the possible
* values for pa_duty_cycle go from 0 to 4.
*
* @ref pa_hp_sel controls the number of slices for HPA according to: \f$ \#slices = pa_hp_sel + 1 \f$
*/
typedef struct lr11xx_radio_pa_cfg_s
{
lr11xx_radio_pa_selection_t pa_sel; //!< Power Amplifier selection
lr11xx_radio_pa_reg_supply_t pa_reg_supply; //!< Power Amplifier regulator supply source
uint8_t pa_duty_cycle; //!< Power Amplifier duty cycle (Default 0x04)
uint8_t pa_hp_sel; //!< Number of slices for HPA (Default 0x07)
} lr11xx_radio_pa_cfg_t;
/*!
* @brief RSSI calibration table
*/
typedef struct lr11xx_radio_rssi_calibration_table_s
{
struct
{
uint8_t g4;
uint8_t g5;
uint8_t g6;
uint8_t g7;
uint8_t g8;
uint8_t g9;
uint8_t g10;
uint8_t g11;
uint8_t g12;
uint8_t g13;
uint8_t g13hp1;
uint8_t g13hp2;
uint8_t g13hp3;
uint8_t g13hp4;
uint8_t g13hp5;
uint8_t g13hp6;
uint8_t g13hp7;
} gain_tune; //!< Used to set gain tune value for RSSI calibration
int16_t gain_offset; //!< Used to set gain offset value for RSSI calibration
} lr11xx_radio_rssi_calibration_table_t;
/*!
* @brief Values to use to setup LNA LF0 configuration
*
* LNA can be configured in either of the 3 modes: Single N, Single P or differential (which is default)
*
*/
typedef enum
{
LR11XX_RADIO_LNA_MODE_SINGLE_RFI_N_LF0 = 1, //!< Use only RFI_N_LF0 antenna
LR11XX_RADIO_LNA_MODE_SINGLE_RFI_P_LF0 = 2, //!< Use only RFI_P_LF0 antenna
LR11XX_RADIO_LNA_MODE_DIFFERENTIAL_LF0 = 3 //!< Configure LNA LF0 in differential mode (default)
} lr11xx_radio_lna_mode_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_RADIO_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,207 @@
/*!
* @file lr11xx_regmem.h
*
* @brief Register/memory driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_REGMEM_H
#define LR11XX_REGMEM_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*!
* @brief Maximum number of words that can be written to / read from a LR11XX chip with regmem32 commands
*/
#define LR11XX_REGMEM_MAX_WRITE_READ_WORDS 64
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Write up to 64 words into register memory space of LR11XX.
*
* A word is 32-bit long. The writing operations write contiguously in register memory, starting at the address
* provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start writing operation
* @param [in] data The buffer of words to write into memory. Its size must be enough to contain length words.
* @param [in] length Number of words to write into memory
*
* @returns Operation status
*
* @see lr11xx_regmem_read_regmem32
*/
lr11xx_status_t lr11xx_regmem_write_regmem32( const void* context, const uint32_t address, const uint32_t* buffer,
const uint8_t length );
/*!
* @brief Read up to 64 words into register memory space of LR11XX.
*
* A word is 32-bit long. The reading operations read contiguously from register memory, starting at the address
* provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start reading operation
* @param [in] length Number of words to read from memory
* @param [out] buffer Pointer to a words array to be filled with content from memory. Its size must be enough to
* contain at least length words.
*
* @returns Operation status
*
* @see lr11xx_regmem_write_regmem32
*/
lr11xx_status_t lr11xx_regmem_read_regmem32( const void* context, const uint32_t address, uint32_t* buffer,
const uint8_t length );
/*!
* @brief Write bytes into register memory space of LR11XX.
*
* A byte is 8-bit long. The writing operations write contiguously in register memory, starting at the address provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start writing operation
* @param [in] data The buffer of bytes to write into memory. Its size must be enough to contain length bytes
* @param [in] length Number of bytes to write into memory
*
* @returns Operation status
*
* @see lr11xx_regmem_read_mem8
*/
lr11xx_status_t lr11xx_regmem_write_mem8( const void* context, const uint32_t address, const uint8_t* buffer,
const uint8_t length );
/*!
* @brief Read bytes into register memory space of LR11XX.
*
* A byte is 8-bit long. The reading operations read contiguously from register memory, starting at the address
* provided.
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to start reading operation
* @param [in] length Number of bytes to read from memory
* @param [in] buffer Pointer to a byte array to be filled with content from memory. Its size must be enough to contain
* at least length bytes
*
* @returns Operation status
*
* @see lr11xx_regmem_write_mem8
*/
lr11xx_status_t lr11xx_regmem_read_mem8( const void* context, const uint32_t address, uint8_t* buffer,
const uint8_t length );
/*!
* @brief Write bytes into radio TX buffer memory space of LR11XX.
*
* @param [in] context Chip implementation context
* @param [in] data The buffer of bytes to write into radio buffer. Its size must be enough to contain length bytes
* @param [in] length Number of bytes to write into radio buffer
*
* @returns Operation status
*
* @see lr11xx_regmem_read_buffer8
*/
lr11xx_status_t lr11xx_regmem_write_buffer8( const void* context, const uint8_t* buffer, const uint8_t length );
/*!
* @brief Read bytes from radio RX buffer memory space of LR11XX.
*
* @param [in] context Chip implementation context
* @param [in] offset Memory offset to start reading
* @param [in] length Number of bytes to read from radio buffer
* @param [in] data Pointer to a byte array to be filled with content from radio buffer. Its size must be enough to
* contain at least length bytes
*
* @returns Operation status
*
* @see lr11xx_regmem_write_buffer8
*/
lr11xx_status_t lr11xx_regmem_read_buffer8( const void* context, uint8_t* buffer, const uint8_t offset,
const uint8_t length );
/*!
* @brief Clear radio RX buffer
*
* Set to 0x00 all content of the radio RX buffer
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_regmem_clear_rxbuffer( const void* context );
/*!
* @brief Read-modify-write data at given register/memory address
*
* @param [in] context Chip implementation context
* @param [in] address The register memory address to be modified
* @param [in] mask The mask to be applied on read data
* @param [in] data The data to be written
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_regmem_write_regmem32_mask( const void* context, const uint32_t address, const uint32_t mask,
const uint32_t data );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_REGMEM_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,201 @@
/**
* @file lr11xx_rttof.h
*
* @brief Round-Trip Time of Flight (RTToF) driver definition for LR11XX
*
* 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 LR11XX_RTTOF_H
#define LR11XX_RTTOF_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr11xx_rttof_types.h"
#include "lr11xx_radio_types.h"
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/**
* @brief Length in byte of the RTToF result
*/
#define LR11XX_RTTOF_RESULT_LENGTH ( 4 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTION PROTOTYPES ---------------------------------------------
*/
/**
* @brief Set the RTToF address for this subordinate device.
*
* @param [in] context Chip implementation context
* @param [in] address 32-bit subordinate address (default is 0x00000019)
* @param [in] check_length Number of bytes to be checked when comparing the device's
* address with request address value contained in received
* RTToF frames (valid range 1..4, default is 4)
*
* @returns Operation status
*
* @note The address set by this function is only used in subordinate mode, that is,
* when receiving RTToF requests. While processing received request packets,
* the RTToF subordinate compares @p check_length bytes (LSB first) of
* the request address with its own address. Packets with non-matching request
* addresses are discarded.
*/
lr11xx_status_t lr11xx_rttof_set_address( const void* context, const uint32_t address, const uint8_t check_length );
/**
* @brief Set the RTToF address used for requests sent in manager mode.
*
* @param [in] context Chip implementation context
* @param [in] request_address 32-bit request address (default is 0x00000019)
*
* @returns Operation status
*
* @note The request address set by this function is only used in manager mode,
* that is, when sending RTToF requests. The @p request_address is copied
* into the corresponding field in the next RTToF request sent.
*/
lr11xx_status_t lr11xx_rttof_set_request_address( const void* context, const uint32_t request_address );
/**
* @brief Set the transceiver RX/TX delay indicator to be compensated during RTToF.
*
* The transceiver hardware induces a delay depending on the physical layer
* configuration (bandwidth, spreading factor). To achieve the desired RTToF
* accuracy, this delay needs to be compensated by a calibration value.
*
* @param [in] context Chip implementation context
* @param [in] delay_indicator Delay value corresponding to the used bandwidth and spreading factor
*
* @returns lr11xx_status_t Operation status
*
* @note The same delay_indicator value needs to be configured in both manager and subordinate devices.
*/
lr11xx_status_t lr11xx_rttof_set_rx_tx_delay_indicator( const void* context, const uint32_t delay_indicator );
/**
* @brief Configure RTToF specific parameters.
*
* It is recommended to always call this command when configuring the RTToF operation with @p nb_symbols = 15.
* This value balances the RTToF accuracy and power consumption.
*
* @param [in] context Chip implementation context
* @param [in] nb_symbols Number of symbols contained in responses sent by subordinates
*
* @returns lr11xx_status_t Operation status
*
* @note The RTToF parameters need to be configured in both manager and subordinate devices.
*/
lr11xx_status_t lr11xx_rttof_set_parameters( const void* context, const uint8_t nb_symbols );
/**
* @brief Get the RTToF result on the manager device.
*
* Retrieve the RTToF result item corresponding to the given item type @p type.
*
* @param [in] context Chip implementation context
* @param [in] type Result item type to be retrieved
* @param [out] result Result data buffer
*
* @returns lr11xx_status_t Operation status
*
* @note This function is only available on devices in manager mode after
* the RTToF is terminated.
*/
lr11xx_status_t lr11xx_rttof_get_raw_result( const void* context, const lr11xx_rttof_result_type_t type,
uint8_t result[LR11XX_RTTOF_RESULT_LENGTH] );
/**
* @brief Convert the raw distance result obtained from the device to a distance result [m].
*
* This function is meaningful only to convert a RTToF result obtained by calling @p lr11xx_rttof_get_raw_result
* with type set to @p LR11XX_RTTOF_RESULT_TYPE_RAW
*
* @param [in] rttof_bw Bandwidth used during RTToF
* @param [in] raw_distance_buf Buffer containing the raw distance result
*
* @returns int32_t Distance result [m]
*
* @see lr11xx_rttof_get_raw_result
*
* @note The caller must ensure that the @p rttof_bw parameter is one of the supported ones,
* i.e., #LR11XX_RADIO_LORA_BW_125, #LR11XX_RADIO_LORA_BW_250, #LR11XX_RADIO_LORA_BW_500.
*/
int32_t lr11xx_rttof_distance_raw_to_meter( lr11xx_radio_lora_bw_t rttof_bw,
const uint8_t raw_distance_buf[LR11XX_RTTOF_RESULT_LENGTH] );
/**
* @brief Convert the raw RSSI result obtained from the device to an RSSI result.
*
* This function is meaningful only to convert a RTToF result obtained by calling @p lr11xx_rttof_get_raw_result
* with type set to @p LR11XX_RTTOF_RESULT_TYPE_RSSI
*
* @param [in] raw_rssi_buf Buffer containing the raw RSSI result
*
* @returns int8_t RSSI result [dBm]
*
* @see lr11xx_rttof_get_raw_result
*/
static inline int8_t lr11xx_rttof_rssi_raw_to_value( const uint8_t raw_rssi_buf[LR11XX_RTTOF_RESULT_LENGTH] )
{
// Only the last byte is meaningful
return -( int8_t )( raw_rssi_buf[3] >> 1 );
}
#ifdef __cplusplus
}
#endif
#endif // LR11XX_RTTOF_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,82 @@
/**
* @file lr11xx_rttof_types.h
*
* @brief Round-Trip Time of Flight (RTToF) driver types for LR11XX
*
* 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 LR11XX_RTTOF_TYPES_H
#define LR11XX_RTTOF_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief Round-Trip Time of Flight result types
*/
typedef enum lr11xx_rttof_result_type_e
{
LR11XX_RTTOF_RESULT_TYPE_RAW = 0, ///< Raw distance result
LR11XX_RTTOF_RESULT_TYPE_RSSI, ///< RTToF RSSI
} lr11xx_rttof_result_type_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTION PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_RTTOF_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,594 @@
/*!
* @file lr11xx_system.h
*
* @brief System driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_SYSTEM_H
#define LR11XX_SYSTEM_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_system_types.h"
#include "lr11xx_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*!
* @brief Frequency step in MHz used to compute the image calibration parameter
*
* @see lr11xx_system_calibrate_image_in_mhz
*/
#define LR11XX_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ 4
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Reset the radio
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_reset( const void* context );
/**
* @brief Wake the radio up from sleep mode.
*
* @param [in] context Chip implementation context.
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_wakeup( const void* context );
/**
* @brief Abort a blocking command.
*
* @param [in] context Chip implementation context.
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_abort_blocking_cmd( const void* context );
/*!
* @brief Return stat1, stat2, and irq_status
*
* @param [in] context Chip implementation context
* @param [out] stat1 Pointer to a variable for holding stat1. Can be NULL.
* @param [out] stat2 Pointer to a variable for holding stat2. Can be NULL.
* @param [out] irq_status Pointer to a variable for holding irq_status. Can be NULL.
*
* @returns Operation status
*
* @remark To simplify system integration, this function does not actually execute the GetStatus command, which would
* require bidirectional SPI communication. It obtains the stat1, stat2, and irq_status values by performing an ordinary
* SPI read (which is required to send null/NOP bytes on the MOSI line). This is possible since the LR11XX returns these
* values automatically whenever a read that does not directly follow a response-carrying command is performed.
* Unlike with the GetStatus command, however, the reset status information is NOT cleared by this command. The function
* @ref lr11xx_system_clear_reset_status_info may be used for this purpose when necessary.
*/
lr11xx_status_t lr11xx_system_get_status( const void* context, lr11xx_system_stat1_t* stat1,
lr11xx_system_stat2_t* stat2, lr11xx_system_irq_mask_t* irq_status );
/*!
* @brief Clear the reset status information stored in stat2
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_clear_reset_status_info( const void* context );
/*!
* @brief Return irq_status
*
* @param [in] context Chip implementation context
* @param [out] irq_status irq_status status variable
*
* @returns Operation status
*/
static inline lr11xx_status_t lr11xx_system_get_irq_status( const void* context, lr11xx_system_irq_mask_t* irq_status )
{
return lr11xx_system_get_status( context, 0, 0, irq_status );
}
/*!
* @brief Return the version of the system (hardware and software)
*
* @param [in] context Chip implementation context
* @param [out] version Pointer to the structure holding the system version
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_get_version( const void* context, lr11xx_system_version_t* version );
/*!
* @brief Return the system errors
*
* Errors may be fixed following:
* - calibration error can be fixed by attempting another RC calibration;
* - XOsc related errors may be due to hardware problems, can be fixed by reset;
* - PLL lock related errors can be due to not-locked PLL, or by attempting to use an out-of-band frequency, can be
* fixed by executing a PLL calibration, or by using other frequencies.
*
* @param [in] context Chip implementation context
* @param [out] errors Pointer to a value holding error flags
*
* @returns Operation status
*
* @see lr11xx_system_calibrate, lr11xx_system_calibrate_image, lr11xx_system_clear_errors
*/
lr11xx_status_t lr11xx_system_get_errors( const void* context, uint16_t* errors );
/*!
* @brief Clear all error flags pending.
*
* This function cannot be used to clear flags individually.
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*
* @see lr11xx_system_get_errors
*/
lr11xx_status_t lr11xx_system_clear_errors( const void* context );
/*!
* @brief lr11xx_system_calibrate the requested blocks
*
* This function can be called in any mode of the chip.
*
* The chip will return to standby RC mode on exit. Potential calibration issues can be read out with
* lr11xx_system_get_errors command.
*
* @param [in] context Chip implementation context
* @param [in] calib_param Structure holding the reference to blocks to be calibrated
*
* @returns Operation status
*
* @see lr11xx_system_get_errors
*/
lr11xx_status_t lr11xx_system_calibrate( const void* context, const uint8_t calib_param );
/*!
* @brief Configure the regulator mode to be used in specific modes
*
* This function shall only be called in standby RC mode.
*
* The reg_mode parameter defines if the DC-DC converter is switched on in the following modes: STANDBY XOSC, FS, RX, TX
* and RX_CAPTURE.
*
* @param [in] context Chip implementation context
* @param [in] reg_mode Regulator mode configuration
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_set_reg_mode( const void* context, const lr11xx_system_reg_mode_t reg_mode );
/*!
* @brief Launch an image calibration valid for all frequencies inside an interval, in steps
*
* This function can be called in any mode of the chip.
*
* The chip will return to standby RC mode on exit. Potential calibration issues can be read out with
* lr11xx_system_get_errors command.
*
* The frequencies given in parameters are defined in 4MHz step (Eg. 900MHz corresponds to 0xE1). If freq1 = freq2, only
* one calibration is performed.
*
* @param [in] context Chip implementation context
* @param [in] freq1 Image calibration interval lower bound, in steps
* @param [in] freq2 Image calibration interval upper bound, in steps
*
* @remark freq1 must be less than or equal to freq2
*
* @returns Operation status
*
* @see lr11xx_system_get_errors
*/
lr11xx_status_t lr11xx_system_calibrate_image( const void* context, const uint8_t freq1, const uint8_t freq2 );
/*!
* @brief Launch an image calibration valid for all frequencies inside an interval, in MHz
*
* @remark This function relies on @ref lr11xx_system_calibrate_image
*
* @param [in] context Chip implementation context
* @param [in] freq1_in_mhz Image calibration interval lower bound, in MHz
* @param [in] freq2_in_mhz Image calibration interval upper bound, in MHz
*
* @remark freq1 must be less than or equal to freq2
*
* @returns Operation status
*
* @see lr11xx_system_calibrate_image
*/
lr11xx_status_t lr11xx_system_calibrate_image_in_mhz( const void* context, const uint16_t freq1_in_mhz,
const uint16_t freq2_in_mhz );
/*!
* @brief Set the RF switch configurations for each RF setup
*
* This function shall only be called in standby RC mode.
*
* By default, no DIO is used to control a RF switch. All DIOs are set in High-Z mode.
*
* @param [in] context Chip implementation context
* @param [in] rf_switch_cfg Pointer to a structure that holds the switches configuration
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_set_dio_as_rf_switch( const void* context,
const lr11xx_system_rfswitch_cfg_t* rf_switch_cfg );
/*!
* @brief Set which interrupt signals are redirected to the dedicated DIO pin
*
* By default, no interrupt signal is redirected.
*
* The dedicated DIO pin will remain asserted until all redirected interrupt signals are cleared with a call to
* lr11xx_system_clear_irq_status.
*
* @param [in] context Chip implementation context
* @param [in] irqs_to_enable_dio1 Variable that holds the interrupt mask for dio1
* @param [in] irqs_to_enable_dio2 Variable that holds the interrupt mask for dio2
*
* @returns Operation status
*
* @see lr11xx_system_clear_irq_status
*/
lr11xx_status_t lr11xx_system_set_dio_irq_params( const void* context,
const lr11xx_system_irq_mask_t irqs_to_enable_dio1,
const lr11xx_system_irq_mask_t irqs_to_enable_dio2 );
/*!
* @brief Clear requested bits in the internal pending interrupt register
*
* @param [in] context Chip implementation context
* @param [in] irqs_to_clear Variable that holds the interrupts to be cleared
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_clear_irq_status( const void* context, const lr11xx_system_irq_mask_t irqs_to_clear );
/**
* @brief This helper function clears any radio irq status flags that are set and returns the flags that were cleared.
*
* @param [in] context Chip implementation context.
* @param [out] irq Pointer to a variable for holding the system interrupt status. Can be NULL.
*
* @returns Operation status
*
* @see lr11xx_system_get_irq_status, lr11xx_system_clear_irq_status
*/
lr11xx_status_t lr11xx_system_get_and_clear_irq_status( const void* context, lr11xx_system_irq_mask_t* irq );
/*!
* @brief Defines which clock is used as Low Frequency (LF) clock
*
* @param [in] context Chip implementation context
* @param [in] lfclock_cfg Low frequency clock configuration
* @param [in] wait_for_32k_ready Tells the radio if it has to check if 32k source is ready before driving busy low
*
* @returns Operation status
*
* @see lr11xx_system_calibrate, lr11xx_system_calibrate_image
*/
lr11xx_status_t lr11xx_system_cfg_lfclk( const void* context, const lr11xx_system_lfclk_cfg_t lfclock_cfg,
const bool wait_for_32k_ready );
/*!
* @brief Enable and configure TCXO supply voltage and detection timeout
*
* This function shall only be called in standby RC mode.
*
* The timeout parameter is the maximum time the firmware waits for the TCXO to be ready. The timeout duration is given
* by: \f$ timeout\_duration\_us = timeout \times 30.52 \f$
*
* The TCXO mode can be disabled by setting timeout parameter to 0.
*
* @param [in] context Chip implementation context
* @param [in] tune Supply voltage value
* @param [in] timeout Gating time before which the radio starts its Rx / Tx operation
*
* @returns Operation status
*
* @see lr11xx_system_calibrate, lr11xx_system_calibrate_image
*/
lr11xx_status_t lr11xx_system_set_tcxo_mode( const void* context, const lr11xx_system_tcxo_supply_voltage_t tune,
const uint32_t timeout );
/*!
* @brief Software reset of the chip.
*
* This function should be used to reboot the chip in a specified mode. Rebooting in flash mode presumes that the
* content in flash memory is not corrupted (i.e. the integrity check performed by the bootloader before executing the
* first instruction in flash is OK).
*
* @param [in] context Chip implementation context
* @param [in] stay_in_bootloader Selector to stay in bootloader or execute flash code after reboot. If true, the
* bootloader will not execute the flash code but activate SPI interface to allow firmware upgrade
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_reboot( const void* context, const bool stay_in_bootloader );
/*!
* @brief Returns the value of Vbat
*
* Vbat value (in V) is a function of Vana (typ. 1.35V) using the following
* formula: \f$ Vbat_{V} = (5 \times \frac{Vbat}{255} - 1) \times Vana \f$
*
* @param [in] context Chip implementation context
* @param [out] vbat A pointer to the Vbat value
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_get_vbat( const void* context, uint8_t* vbat );
/*!
* @brief Returns the value of Temp
*
* The temperature (in °C) is a function of Vana (typ. 1.35V), Vbe25 (Vbe voltage @ 25°C, typ. 0.7295V) and VbeSlope
* (typ. -1.7mV/°C) using the following formula:
* \f$ Temperature_{°C} = (\frac{Temp(10:0)}{2047} \times Vana - Vbe25) \times \frac{1000}{VbeSlope} + 25 \f$
*
* @remark If a TCXO is used, make sure to configure it with @ref lr11xx_system_set_tcxo_mode before calling this
* function
*
* @param [in] context Chip implementation context
* @param [out] temp A pointer to the Temp value
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_get_temp( const void* context, uint16_t* temp );
/*!
* @brief Set the device into Sleep or Deep Sleep Mode
*
* The sleep_cfg parameter defines in which sleep mode the device is put and if it wakes up after a given time on the
* RTC event.
*
* The sleep_time parameter is taken into account only when RtcTimeout = 1. It sets the sleep time in number of clock
* cycles: \f$ sleep\_time\_ms = sleep_time \times \frac{1}{32.768} \f$
*
* @param [in] context Chip implementation context
* @param [in] sleep_cfg Sleep mode configuration
* @param [in] sleep_time Value of the RTC timeout (if RtcTimeout = 1)
*
* @returns Operation status
*
* @see lr11xx_system_set_standby, lr11xx_system_set_fs
*/
lr11xx_status_t lr11xx_system_set_sleep( const void* context, const lr11xx_system_sleep_cfg_t sleep_cfg,
const uint32_t sleep_time );
/*!
* @brief Set the device into the requested Standby mode
*
* @param [in] context Chip implementation context
* @param [in] standby_cfg Stand by mode configuration (RC or XOSC)
*
* @returns Operation status
*
* @see lr11xx_system_set_sleep, lr11xx_system_set_fs
*/
lr11xx_status_t lr11xx_system_set_standby( const void* context, const lr11xx_system_standby_cfg_t standby_cfg );
/*!
* @brief Set the device into Frequency Synthesis (FS) mode
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*
* @see lr11xx_system_set_standby, lr11xx_system_set_sleep
*/
lr11xx_status_t lr11xx_system_set_fs( const void* context );
/*!
* @brief Erase an info page
*
* @param [in] context Chip implementation context
* @param [in] info_page_id Info page to be erased. Only LR11XX_SYSTEM_INFOPAGE_1 is allowed.
*
* @returns Operation status
*
* @see lr11xx_system_write_infopage, lr11xx_system_read_infopage
*/
lr11xx_status_t lr11xx_system_erase_infopage( const void* context, const lr11xx_system_infopage_id_t info_page_id );
/*!
* @brief Write data in an info page
*
* @param [in] context Chip implementation context
* @param [in] info_page_id Info page where data are written. Only LR11XX_SYSTEM_INFOPAGE_1 is allowed.
* @param [in] address Address within the info page (aligned on 32-bit data)
* @param [in] data Pointer to the data to write (data buffer shall be - at least - length words long)
* @param [in] length Number of 32-bit data to write (maximum value is 64)
*
* @returns Operation status
*
* @see lr11xx_system_erase_infopage, lr11xx_system_read_infopage
*/
lr11xx_status_t lr11xx_system_write_infopage( const void* context, const lr11xx_system_infopage_id_t info_page_id,
const uint16_t address, const uint32_t* data, const uint8_t length );
/*!
* @brief Read data from an info page
*
* It is possible to cross from page 0 to 1 if (address + length >= 512)
*
* @param [in] context Chip implementation context
* @param [in] info_page_id Info page where data are read
* @param [in] address Address within the info page (aligned on 32-bit data)
* @param [out] data Pointer to the data to read (data buffer shall be - at least - length words long)
* @param [in] length Number of 32-bit data to read (maximum value is 64)
*
* @returns Operation status
*
* @see lr11xx_system_erase_infopage, lr11xx_system_write_infopage
*/
lr11xx_status_t lr11xx_system_read_infopage( const void* context, const lr11xx_system_infopage_id_t info_page_id,
const uint16_t address, uint32_t* data, const uint8_t length );
/*!
* @brief Read and return the Unique Identifier of the LR11XX
*
* @param [in] context Chip implementation context
* @param [out] unique_identifier The buffer to be filled with the Unique Identifier of the LR11XX. It is up to the
* application to ensure unique_identifier is long enough to hold the unique identifier
*
* @returns Operation status
*
* @see LR11XX_SYSTEM_UID_LENGTH
*/
lr11xx_status_t lr11xx_system_read_uid( const void* context, lr11xx_system_uid_t unique_identifier );
/*!
* @brief Read and return the Join EUI of the LR11XX
*
* @param [in] context Chip implementation context
* @param [out] join_eui The buffer to be filled with Join EUI of the LR11XX. It is up to the application to ensure
* join_eui is long enough to hold the join EUI
*
* @returns Operation status
*
* @see LR11XX_SYSTEM_JOIN_EUI_LENGTH
*/
lr11xx_status_t lr11xx_system_read_join_eui( const void* context, lr11xx_system_join_eui_t join_eui );
/*!
* @brief Compute and return the PIN of the LR11XX based on factory default EUIs
*
* @remark Calling this command also triggers a derivation of network and application keys (available as @ref
* LR11XX_CRYPTO_KEYS_IDX_NWK_KEY and @ref LR11XX_CRYPTO_KEYS_IDX_APP_KEY) based on factory default EUIs
*
* @param [in] context Chip implementation context
* @param [out] pin The buffer to be filled with PIN of the LR11XX. It is up to the application to ensure pin is long
* enough to hold the PIN
*
* @returns Operation status
*
* @see LR11XX_SYSTEM_PIN_LENGTH
*/
lr11xx_status_t lr11xx_system_read_pin( const void* context, lr11xx_system_pin_t pin );
/*!
* @brief Compute and return the PIN of the LR11XX based on EUIs provided as parameters
*
* @remark Calling this command also triggers a derivation of network and application keys (available as @ref
* LR11XX_CRYPTO_KEYS_IDX_NWK_KEY and @ref LR11XX_CRYPTO_KEYS_IDX_APP_KEY) based on EUIs provided as parameters
*
* @param [in] context Chip implementation context
* @param [in] device_eui Custom Device EUI
* @param [in] join_eui Custom Join EUI
* @param [in] rfu Parameter RFU - shall be set to 0x00
* @param [out] pin The buffer to be filled with PIN of the LR11XX. It is up to the application to ensure pin is long
* enough to hold the PIN
*
* @returns Operation status
*
* @see LR11XX_SYSTEM_PIN_LENGTH
*/
lr11xx_status_t lr11xx_system_read_pin_custom_eui( const void* context, lr11xx_system_uid_t device_eui,
lr11xx_system_join_eui_t join_eui, uint8_t rfu,
lr11xx_system_pin_t pin );
/*!
* @brief Read and return a 32-bit random number
*
* @remark Radio operating mode must be set into standby.
*
* @param [in] context Chip implementation context
* @param [out] random_number 32-bit random number
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_get_random_number( const void* context, uint32_t* random_number );
/*!
* @brief Enable the CRC on SPI transactions
*
* @remark This command shall always be sent with a CRC (to both enable and disable the feature). The function does not
* take care of this additional byte - which is under the responsibility of the underlying HAL functions
*
* @param [in] context Chip implementation context
* @param [in] enable_crc CRC
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_enable_spi_crc( const void* context, bool enable_crc );
/*!
* @brief Configure the GPIO drive in sleep mode
*
* @remark GPIO stands for RF switch and IRQ line DIOs
*
* @note This command is available from firmware version 0x0306
*
* @param [in] context Chip implementation context
* @param [in] enable_drive GPIO drive configuration (true: enabled / false: disabled)
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_system_drive_dio_in_sleep_mode( const void* context, bool enable_drive );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_SYSTEM_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,349 @@
/*!
* @file lr11xx_system_types.h
*
* @brief System driver types for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_SYSTEM_TYPES_H
#define LR11XX_SYSTEM_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include <stdbool.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*!
* @brief Length in byte of the LR11XX version blob
*/
#define LR11XX_SYSTEM_VERSION_LENGTH ( 4 )
/*!
* @brief Length of the LR11XX Unique Identifier in bytes
*
* The LR11XX Unique Identifiers is an 8 byte long buffer
*/
#define LR11XX_SYSTEM_UID_LENGTH ( 8 )
#define LR11XX_SYSTEM_JOIN_EUI_LENGTH ( 8 )
#define LR11XX_SYSTEM_PIN_LENGTH ( 4 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief Fixed-length array to store a UID
*/
typedef uint8_t lr11xx_system_uid_t[LR11XX_SYSTEM_UID_LENGTH];
/**
* @brief Fixed-length array to store a joinEUI
*/
typedef uint8_t lr11xx_system_join_eui_t[LR11XX_SYSTEM_JOIN_EUI_LENGTH];
/**
* @brief Fixed-length array to store a PIN
*/
typedef uint8_t lr11xx_system_pin_t[LR11XX_SYSTEM_PIN_LENGTH];
/**
* @brief Type to store system interrupt flags
*/
typedef uint32_t lr11xx_system_irq_mask_t;
/**
* @brief Interrupt flags
*/
enum lr11xx_system_irq_e
{
LR11XX_SYSTEM_IRQ_NONE = ( 0 << 0 ),
LR11XX_SYSTEM_IRQ_TX_DONE = ( 1 << 2 ),
LR11XX_SYSTEM_IRQ_RX_DONE = ( 1 << 3 ),
LR11XX_SYSTEM_IRQ_PREAMBLE_DETECTED = ( 1 << 4 ),
LR11XX_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID = ( 1 << 5 ),
LR11XX_SYSTEM_IRQ_HEADER_ERROR = ( 1 << 6 ),
LR11XX_SYSTEM_IRQ_CRC_ERROR = ( 1 << 7 ),
LR11XX_SYSTEM_IRQ_CAD_DONE = ( 1 << 8 ),
LR11XX_SYSTEM_IRQ_CAD_DETECTED = ( 1 << 9 ),
LR11XX_SYSTEM_IRQ_TIMEOUT = ( 1 << 10 ),
LR11XX_SYSTEM_IRQ_LR_FHSS_INTRA_PKT_HOP = ( 1 << 11 ),
LR11XX_SYSTEM_IRQ_RTTOF_REQ_VALID = ( 1 << 14 ),
LR11XX_SYSTEM_IRQ_RTTOF_REQ_DISCARDED = ( 1 << 15 ),
LR11XX_SYSTEM_IRQ_RTTOF_RESP_DONE = ( 1 << 16 ),
LR11XX_SYSTEM_IRQ_RTTOF_EXCH_VALID = ( 1 << 17 ),
LR11XX_SYSTEM_IRQ_RTTOF_TIMEOUT = ( 1 << 18 ),
LR11XX_SYSTEM_IRQ_GNSS_SCAN_DONE = ( 1 << 19 ),
LR11XX_SYSTEM_IRQ_WIFI_SCAN_DONE = ( 1 << 20 ),
LR11XX_SYSTEM_IRQ_EOL = ( 1 << 21 ),
LR11XX_SYSTEM_IRQ_CMD_ERROR = ( 1 << 22 ),
LR11XX_SYSTEM_IRQ_ERROR = ( 1 << 23 ),
LR11XX_SYSTEM_IRQ_FSK_LEN_ERROR = ( 1 << 24 ),
LR11XX_SYSTEM_IRQ_FSK_ADDR_ERROR = ( 1 << 25 ),
LR11XX_SYSTEM_IRQ_LORA_RX_TIMESTAMP =
( 1 << 27 ), //!< Available since firmware LR1110 0x0308 / LR1120 0x0102 / LR1121 0x0102
LR11XX_SYSTEM_IRQ_ALL_MASK =
LR11XX_SYSTEM_IRQ_TX_DONE | LR11XX_SYSTEM_IRQ_RX_DONE | LR11XX_SYSTEM_IRQ_PREAMBLE_DETECTED |
LR11XX_SYSTEM_IRQ_SYNC_WORD_HEADER_VALID | LR11XX_SYSTEM_IRQ_HEADER_ERROR | LR11XX_SYSTEM_IRQ_CRC_ERROR |
LR11XX_SYSTEM_IRQ_CAD_DONE | LR11XX_SYSTEM_IRQ_CAD_DETECTED | LR11XX_SYSTEM_IRQ_TIMEOUT |
LR11XX_SYSTEM_IRQ_LR_FHSS_INTRA_PKT_HOP | LR11XX_SYSTEM_IRQ_RTTOF_REQ_VALID |
LR11XX_SYSTEM_IRQ_RTTOF_REQ_DISCARDED | LR11XX_SYSTEM_IRQ_RTTOF_RESP_DONE | LR11XX_SYSTEM_IRQ_RTTOF_EXCH_VALID |
LR11XX_SYSTEM_IRQ_RTTOF_TIMEOUT | LR11XX_SYSTEM_IRQ_GNSS_SCAN_DONE | LR11XX_SYSTEM_IRQ_WIFI_SCAN_DONE |
LR11XX_SYSTEM_IRQ_EOL | LR11XX_SYSTEM_IRQ_CMD_ERROR | LR11XX_SYSTEM_IRQ_ERROR |
LR11XX_SYSTEM_IRQ_FSK_LEN_ERROR | LR11XX_SYSTEM_IRQ_FSK_ADDR_ERROR | LR11XX_SYSTEM_IRQ_LORA_RX_TIMESTAMP,
};
/**
* @brief Calibration flags
*/
enum lr11xx_system_calibration_e
{
LR11XX_SYSTEM_CALIB_LF_RC_MASK = ( 1 << 0 ),
LR11XX_SYSTEM_CALIB_HF_RC_MASK = ( 1 << 1 ),
LR11XX_SYSTEM_CALIB_PLL_MASK = ( 1 << 2 ),
LR11XX_SYSTEM_CALIB_ADC_MASK = ( 1 << 3 ),
LR11XX_SYSTEM_CALIB_IMG_MASK = ( 1 << 4 ),
LR11XX_SYSTEM_CALIB_PLL_TX_MASK = ( 1 << 5 ),
};
typedef uint8_t lr11xx_system_cal_mask_t;
/**
* @brief Error flags
*/
enum lr11xx_system_errors_e
{
LR11XX_SYSTEM_ERRORS_LF_RC_CALIB_MASK = ( 1 << 0 ),
LR11XX_SYSTEM_ERRORS_HF_RC_CALIB_MASK = ( 1 << 1 ),
LR11XX_SYSTEM_ERRORS_ADC_CALIB_MASK = ( 1 << 2 ),
LR11XX_SYSTEM_ERRORS_PLL_CALIB_MASK = ( 1 << 3 ),
LR11XX_SYSTEM_ERRORS_IMG_CALIB_MASK = ( 1 << 4 ),
LR11XX_SYSTEM_ERRORS_HF_XOSC_START_MASK = ( 1 << 5 ),
LR11XX_SYSTEM_ERRORS_LF_XOSC_START_MASK = ( 1 << 6 ),
LR11XX_SYSTEM_ERRORS_PLL_LOCK_MASK = ( 1 << 7 ),
};
typedef uint16_t lr11xx_system_errors_t;
/**
* @brief Chip modes
*/
typedef enum
{
LR11XX_SYSTEM_CHIP_MODE_SLEEP = 0x00,
LR11XX_SYSTEM_CHIP_MODE_STBY_RC = 0x01,
LR11XX_SYSTEM_CHIP_MODE_STBY_XOSC = 0x02,
LR11XX_SYSTEM_CHIP_MODE_FS = 0x03,
LR11XX_SYSTEM_CHIP_MODE_RX = 0x04,
LR11XX_SYSTEM_CHIP_MODE_TX = 0x05,
LR11XX_SYSTEM_CHIP_MODE_LOC = 0x06,
} lr11xx_system_chip_modes_t;
/**
* @brief Reset status
*/
typedef enum
{
LR11XX_SYSTEM_RESET_STATUS_CLEARED = 0x00,
LR11XX_SYSTEM_RESET_STATUS_ANALOG = 0x01,
LR11XX_SYSTEM_RESET_STATUS_EXTERNAL = 0x02,
LR11XX_SYSTEM_RESET_STATUS_SYSTEM = 0x03,
LR11XX_SYSTEM_RESET_STATUS_WATCHDOG = 0x04,
LR11XX_SYSTEM_RESET_STATUS_IOCD_RESTART = 0x05,
LR11XX_SYSTEM_RESET_STATUS_RTC_RESTART = 0x06,
} lr11xx_system_reset_status_t;
/**
* @brief Command status
*/
typedef enum
{
LR11XX_SYSTEM_CMD_STATUS_FAIL = 0x00,
LR11XX_SYSTEM_CMD_STATUS_PERR = 0x01,
LR11XX_SYSTEM_CMD_STATUS_OK = 0x02,
LR11XX_SYSTEM_CMD_STATUS_DATA = 0x03,
} lr11xx_system_command_status_t;
/**
* @brief Low-frequency clock modes
*/
typedef enum
{
LR11XX_SYSTEM_LFCLK_RC = 0x00, //!< (Default)
LR11XX_SYSTEM_LFCLK_XTAL = 0x01,
LR11XX_SYSTEM_LFCLK_EXT = 0x02
} lr11xx_system_lfclk_cfg_t;
/**
* @brief Regulator modes
*/
typedef enum
{
LR11XX_SYSTEM_REG_MODE_LDO = 0x00, //!< (Default)
LR11XX_SYSTEM_REG_MODE_DCDC = 0x01,
} lr11xx_system_reg_mode_t;
/**
* @brief Info page ID
*/
typedef enum
{
LR11XX_SYSTEM_INFOPAGE_0 = 0x00, //!< Info page #0
LR11XX_SYSTEM_INFOPAGE_1 = 0x01, //!< Info page #1
} lr11xx_system_infopage_id_t;
/**
* @brief RF switch configuration pin
*/
enum lr11xx_system_rfswitch_cfg_pin_e
{
LR11XX_SYSTEM_RFSW0_HIGH = ( 1 << 0 ),
LR11XX_SYSTEM_RFSW1_HIGH = ( 1 << 1 ),
LR11XX_SYSTEM_RFSW2_HIGH = ( 1 << 2 ),
LR11XX_SYSTEM_RFSW3_HIGH = ( 1 << 3 ),
LR11XX_SYSTEM_RFSW4_HIGH = ( 1 << 4 ),
};
/**
* @brief RF switch configuration structure definition
*/
typedef struct lr11xx_system_rfswitch_cfg_s
{
uint8_t enable;
uint8_t standby;
uint8_t rx;
uint8_t tx;
uint8_t tx_hp;
uint8_t tx_hf;
uint8_t gnss;
uint8_t wifi;
} lr11xx_system_rfswitch_cfg_t;
/**
* @brief Stand by configuration values
*/
typedef enum
{
LR11XX_SYSTEM_STANDBY_CFG_RC = 0x00,
LR11XX_SYSTEM_STANDBY_CFG_XOSC = 0x01
} lr11xx_system_standby_cfg_t;
/**
* @brief TCXO supply voltage values
*/
typedef enum
{
LR11XX_SYSTEM_TCXO_CTRL_1_6V = 0x00, //!< Supply voltage = 1.6v
LR11XX_SYSTEM_TCXO_CTRL_1_7V = 0x01, //!< Supply voltage = 1.7v
LR11XX_SYSTEM_TCXO_CTRL_1_8V = 0x02, //!< Supply voltage = 1.8v
LR11XX_SYSTEM_TCXO_CTRL_2_2V = 0x03, //!< Supply voltage = 2.2v
LR11XX_SYSTEM_TCXO_CTRL_2_4V = 0x04, //!< Supply voltage = 2.4v
LR11XX_SYSTEM_TCXO_CTRL_2_7V = 0x05, //!< Supply voltage = 2.7v
LR11XX_SYSTEM_TCXO_CTRL_3_0V = 0x06, //!< Supply voltage = 3.0v
LR11XX_SYSTEM_TCXO_CTRL_3_3V = 0x07, //!< Supply voltage = 3.3v
} lr11xx_system_tcxo_supply_voltage_t;
/**
* @brief Status register 1 structure definition
*/
typedef struct lr11xx_system_stat1_s
{
lr11xx_system_command_status_t command_status;
bool is_interrupt_active;
} lr11xx_system_stat1_t;
/**
* @brief Status register 2 structure definition
*/
typedef struct lr11xx_system_stat2_s
{
lr11xx_system_reset_status_t reset_status;
lr11xx_system_chip_modes_t chip_mode;
bool is_running_from_flash;
} lr11xx_system_stat2_t;
/**
* @brief Chip type values
*/
typedef enum
{
LR11XX_SYSTEM_VERSION_TYPE_LR1110 = 0x01,
LR11XX_SYSTEM_VERSION_TYPE_LR1120 = 0x02,
LR11XX_SYSTEM_VERSION_TYPE_LR1121 = 0x03,
} lr11xx_system_version_type_t;
/**
* @brief Version structure definition
*/
typedef struct lr11xx_system_version_s
{
uint8_t hw;
lr11xx_system_version_type_t type;
uint16_t fw;
} lr11xx_system_version_t;
/**
* @brief Sleep configuration structure definition
*/
typedef struct lr11xx_system_sleep_cfg_s
{
bool is_warm_start;
bool is_rtc_timeout;
} lr11xx_system_sleep_cfg_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_SYSTEM_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,76 @@
/*!
* @file lr11xx_types.h
*
* @brief Type definitions for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_TYPES_H
#define LR11XX_TYPES_H
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
#define LR11XX_CMD_LENGTH_MAX ( 512 )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief LR11XX status
*/
typedef enum lr11xx_status_e
{
LR11XX_STATUS_OK = 0,
LR11XX_STATUS_ERROR = 3,
} lr11xx_status_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#endif // LR11XX_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,628 @@
/*!
* @file lr11xx_wifi.h
*
* @brief Wi-Fi passive scan driver definition for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_WIFI_H
#define LR11XX_WIFI_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_regmem.h"
#include "lr11xx_wifi_types.h"
#include "lr11xx_types.h"
#include "lr11xx_system_types.h"
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
#ifndef LR11XX_WIFI_N_RESULTS_MAX_PER_CHUNK
/*!
* @brief The number of results max to fetch per SPI communication with the chip
*
* This macro is used by the internals of the driver to size the internal
* buffers of the driver used in the *read results* functions.
*
* It can be defined externally at compile time, or just before including this file.
*
* Its value can be programmatically obtained at runtime by calling lr11xx_wifi_get_nb_results_max_per_chunk() function.
*
* Its default value is set to the maximum number of results saved by LR11XX chip.
*
* @warning Its value must be in the range [1,32] (inclusive). Defining out of this range leads to undefined behavior.
*/
#define LR11XX_WIFI_N_RESULTS_MAX_PER_CHUNK LR11XX_WIFI_MAX_RESULTS
#endif // LR11XX_WIFI_N_RESULTS_MAX_PER_CHUNK
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
/*!
* @brief Start a Wi-Fi passive scan operation
*
* During the complete passive scan operation, the LR11XX remains busy and cannot receive any commands. Using this
* command **DOES** reset the results already obtained by previous passive scan operations.
*
* The result can be read at the end of the passive scan issuing the command lr11xx_wifi_get_nb_results (to get the
* number of results to read) and lr11xx_wifi_read_basic_complete_results or
* lr11xx_wifi_read_basic_mac_type_channel_results to actually get the result bytes.
*
* @param [in] context Chip implementation context
* @param [in] signal_type The type of Wi-Fi Signals to scan for. If LR11XX_WIFI_TYPE_SCAN_B_G_N is selected, the LR11XX
* already starts by scanning all selected channels for Wi-Fi signals B. Then the LR11XX scans all selected channels for
* Wi-Fi signals G/N.
* @param [in] channels Mask of the Wi-Fi channels to scan
* @param [in] scan_mode Scan mode to execute
* @param [in] max_results The maximal number of results to gather. When this limit is reached, the passive scan
* automatically stop. Range of allowed values is [1:32]. Note that value 0 is forbidden.
* @param [in] nb_scan_per_channel The number of internal scan sequences per channel scanned. Range of accepted values
* is [1:255]. Note that value 0 is forbidden.
* @param [in] timeout_in_ms The maximal duration of a single preamble search. Expressed in ms. Range of allowed values
* is [1:65535]. Note that value 0 is forbidden.
* @param [in] abort_on_timeout If true, the beacon search jumps to next configured Wi-Fi channel (or stop if there is
* no more channel to scan) as soon as a search timeout is encountered
*
* @returns Operation status
*
* @see lr11xx_wifi_read_basic_complete_results, lr11xx_wifi_read_basic_mac_type_channel_results
*/
lr11xx_status_t lr11xx_wifi_scan( const void* context, const lr11xx_wifi_signal_type_scan_t signal_type,
const lr11xx_wifi_channel_mask_t channels, const lr11xx_wifi_mode_t scan_mode,
const uint8_t max_results, const uint8_t nb_scan_per_channel,
const uint16_t timeout_in_ms, const bool abort_on_timeout );
/*!
* @brief Start a Wi-Fi passive scan for country codes extraction
*
* This command starts a Wi-Fi passive scan operation for Beacons and Probe Responses on Wi-Fi type B only. It is to be
* used to extract the Country Code fields.
*
* During the passive scan, the results are filtered to keep only single MAC addresses.
*
* @param [in] context Chip implementation context
* @param [in] channels_mask Mask of the Wi-Fi channels to scan
* @param [in] nb_max_results The maximum number of country code to gather. When this limit is reached, the passive scan
* automatically stops. Maximal value is 32
* @param [in] nb_scan_per_channel Maximal number of scan attempts per channel. Maximal value is 255
* @param [in] timeout_in_ms The maximal duration of a single beacon search. Expressed in ms. Maximal value is 65535 ms
* @param [in] abort_on_timeout If true, the beacon search jumps to next configured Wi-Fi channel (or stop if there is
* no more channel to scan) as soon as a search timeout is encountered
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_search_country_code( const void* context, const lr11xx_wifi_channel_mask_t channels_mask,
const uint8_t nb_max_results, const uint8_t nb_scan_per_channel,
const uint16_t timeout_in_ms, const bool abort_on_timeout );
/*!
* @brief Start a Wi-Fi passive scan operation with duration stop conditions
*
* This passive scan API does not require the number of scan per channel, so
* that it searches for Wi-Fi signals until it finds one, or until the
* exhaustion of timeout_per_scan_ms or timeout_per_channel_ms.
*
* The maximal duration of a scan is determined by the number of channels to scan times the timeout_per_channel_ms
* configured. However, this duration may be exceeded depending on the crystal drift of the clock source and on the
* instant the last Wi-Fi signal is detected by the device.
* Therefore the maximal duration of a Wi-Fi scan with this API is provided by the following equations:
*
* For signal type being `LR11XX_WIFI_TYPE_SCAN_B`, `LR11XX_WIFI_TYPE_SCAN_G` or `LR11XX_WIFI_TYPE_SCAN_N`:
*
* \f$ T_{max} = N_{channel} \times ((1 + Xtal_{precision})timeout\_per\_channel + T_{offset} ) \f$
*
* \f$ Xtal_{precision} \f$ depends on the crystal used as clock source.
* If the clock source is configured with 32kHz internal RC, then \f$ Xtal_{precision} = 1/100 \f$
*
* \f$ T_{offset} \f$ depends on the \f$ signal\_type \f$ and the \f$scan\_mode\f$ selected:
*
* - LR11XX_WIFI_TYPE_SCAN_B:
* - if \f$scan\_mode != LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$: 2.31 ms
* - if \f$scan\_mode == LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$: 9.59 ms
* - LR11XX_WIFI_TYPE_SCAN_G:
* - if \f$scan\_mode != LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$: 52.55 ms
* - if \f$scan\_mode == LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$: N/A
*
* For signal type being `LR11XX_WIFI_TYPE_SCAN_B_G_N`:
*
* \f$ T_{max} = 2 \times N_{channel} \times (1 + Xtal_{precision})timeout\_per\_channel + T_{offset} \f$
*
* \f$ T_{offset} \f$ depends on the \f$scan\_mode\f$ selected:
* - \f$scan\_mode != LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$: 54.86 ms
* - \f$scan\_mode == LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$: 9.59 ms.
*
* @note With \f$scan\_mode != LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$ the T_offset is actually the worst case of
* Wi-Fi type B and Wi-Fi type G/N. Moreover, the Wi-Fi types G and N are scanned within the same steps (it is not two
* different scans). So the T_offset is the addition of 2.31 + 52.55 = 54.86.
*
* @note With \f$scan\_mode == LR11XX\_WIFI\_SCAN\_MODE\_FULL\_BEACON\f$, only Wi-Fi types B can be scanned. So scans
* for Wi-Fi types G/N are silently discarded. Therefore the T_offset is the same as for scan with Wi-Fi type B.
*
* @param [in] context Chip implementation context
* @param [in] signal_type The type of Wi-Fi Signals to scan for. If LR11XX_WIFI_TYPE_SCAN_B_G_N is selected, the LR11XX
* already starts by scanning all selected channels for Wi-Fi signals B. Then the LR11XX scans all selected channels for
* Wi-Fi signals G/N.
* @param [in] channels Mask of the Wi-Fi channels to scan
* @param [in] scan_mode Scan mode to execute
* @param [in] max_results The maximal number of results to gather. When this
* limit is reached, the passive scan automatically stop. Maximal value is 32
* @param [in] timeout_per_channel_ms The time to spend scanning one channel. Expressed in ms. Value 0 is forbidden and
* will result in the raise of WIFI_SCAN_DONE interrupt, with stat1.command_status being set to
* LR11XX_SYSTEM_CMD_STATUS_PERR
* @param [in] timeout_per_scan_ms The maximal time to spend in preamble detection for each single scan. The time spent
* on preamble search is reset at each new preamble search. If the time spent on preamble search reach this timeout, the
* scan on the current channel stops and start on next channel. If set to 0, the command will keep listening until
* exhaustion of timeout_per_channel_ms or until nb_max_results is reached. Expressed in ms. Range of allowed values is
* [0:65535].
*
* @returns Operation status
*
* @see lr11xx_wifi_read_basic_results, lr11xx_wifi_read_extended_results
*/
lr11xx_status_t lr11xx_wifi_scan_time_limit( const void* context, const lr11xx_wifi_signal_type_scan_t signal_type,
const lr11xx_wifi_channel_mask_t channels,
const lr11xx_wifi_mode_t scan_mode, const uint8_t max_results,
const uint16_t timeout_per_channel_ms,
const uint16_t timeout_per_scan_ms );
/*!
* @brief Start a Wi-Fi passive scan for country codes extraction with duration stop conditions
*
* This command starts a Wi-Fi passive scan operation for Beacons and Probe Responses on Wi-Fi type B only. It is to be
* used to extract the Country Code fields.
* This passive scan API does not require the number of scan per channel, so that it searches for Wi-Fi signals until it
* finds one, or until the exhaustion of timeout_per_scan_ms or timeout_per_channel_ms.
*
* The maximal duration of a scan is determined by the number of channels to scan times the timeout_per_channel_ms
* configured. However, this duration may be exceeded depending on the crystal drift of the clock source and on the
* instant the last Wi-Fi signal is detected by the device.
* Therefore the maximal duration of a Wi-Fi scan with this API is provided by the following equation:
*
* \f$ T_{max} = N_{channel} \times ((1 + Xtal_{precision})timeout\_per\_channel + T_{offset} ) \f$
*
* \f$ Xtal_{precision} \f$ depends on the crystal used as clock source.
* If the clock source is configured with 32kHz internal RC, then \f$ Xtal_{precision} = 1/100 \f$
*
* \f$ T_{offset} \f$ is always the same: 9.59 ms.
*
* @param [in] context Chip implementation context
* @param [in] channels_mask Mask of the Wi-Fi channels to scan
* @param [in] nb_max_results The maximum number of country code to gather. When this limit is reached, the passive scan
* automatically stops. Maximal value is 32
* @param [in] timeout_per_channel_ms The time to spend scanning one channel. Expressed in ms. Value 0 is forbidden and
* will result in the raise of WIFI_SCAN_DONE interrupt, with stat1.command_status being set to
* LR11XX_SYSTEM_CMD_STATUS_PERR
* @param [in] timeout_per_scan_ms The maximal time to spend in preamble detection for each single scan. The time spent
* on preamble search is reset at each new preamble search. If the time spent on preamble search reach this timeout, the
* scan on the current channel stops and start on next channel. If set to 0, the command will keep listening until
* exhaustion of timeout_per_channel_ms or until nb_max_results is reached. Expressed in ms. Range of allowed values is
* [0:65535].
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_search_country_code_time_limit( const void* context,
const lr11xx_wifi_channel_mask_t channels_mask,
const uint8_t nb_max_results,
const uint16_t timeout_per_channel_ms,
const uint16_t timeout_per_scan_ms );
/*!
* @brief Returns the number of results currently available in LR11XX
*
* It can be called before lr11xx_wifi_read_basic_complete_results or lr11xx_wifi_read_basic_mac_type_channel_results to
* know the number of results.
*
* @param [in] context Chip implementation context
* @param [out] nb_results The number of results available in the LR11XX
*
* @returns Operation status
*
* @see lr11xx_wifi_read_basic_complete_results, lr11xx_wifi_read_basic_mac_type_channel_results
*/
lr11xx_status_t lr11xx_wifi_get_nb_results( const void* context, uint8_t* nb_results );
/*!
* @brief Read basic complete results
*
* This function can be used to fetch all results in a row, or one after the other.
* It corresponds to result format @ref ::LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE.
*
* An example of usage to fetch all results in a row is:
* \code{.cpp}
* uint8_t nb_results = 0;
* lr11xx_wifi_get_nb_results(&radio, &nb_results);
* lr11xx_wifi_basic_complete_result_t all_results[LR11XX_WIFI_MAX_RESULTS] = {0};
* lr11xx_wifi_read_basic_complete_results(&radio, 0, nb_results, all_results);
* \endcode
*
* On the other hand, fetching result one after the other:
* \code{.cpp}
* uint8_t nb_results = 0;
* lr11xx_wifi_get_nb_results(&radio, &nb_results);
* lr11xx_wifi_basic_complete_result_t single_results = {0};
* for(uint8_t index_result = 0; index_result < nb_results; index_result++){
* lr11xx_wifi_read_basic_complete_results(&radio, index_result, 1, &single_results);
* // Do something with single_results
* }
* \endcode
*
* @remark This result fetching function **MUST** be used only if the scan function call was made with Scan Mode set to
* @ref ::LR11XX_WIFI_SCAN_MODE_BEACON or @ref ::LR11XX_WIFI_SCAN_MODE_BEACON_AND_PKT.
* Refer to @ref lr11xx_wifi_are_scan_mode_result_format_compatible to know which scan mode and result format are
* compatible.
*
* @param [in] radio Radio abstraction
* @param [in] start_result_index Result index from which starting to fetch the results
* @param [in] nb_results Number of results to fetch
* @param [out] results Pointer to an array of result structures to populate. It is up to the caller to ensure this
* array can hold at least nb_results elements.
*
* @returns Operation status
*
* @see lr11xx_wifi_are_scan_mode_result_format_compatible, lr11xx_wifi_read_basic_mac_type_channel_results,
* lr11xx_wifi_read_extended_full_results
*/
lr11xx_status_t lr11xx_wifi_read_basic_complete_results( const void* context, const uint8_t start_result_index,
const uint8_t nb_results,
lr11xx_wifi_basic_complete_result_t* results );
/*!
* @brief Read basic MAC, Wi-Fi type and channel results
*
* This function can be used to fetch all results in a row, or one after the other.
* It corresponds to result format @ref ::LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL.
*
* An example of usage to fetch all results in a row is:
* \code{.cpp}
* uint8_t nb_results = 0;
* lr11xx_wifi_get_nb_results(&radio, &nb_results);
* lr11xx_wifi_basic_mac_type_channel_result_t all_results[LR11XX_WIFI_MAX_RESULTS] = {0};
* lr11xx_wifi_read_basic_mac_type_channel_results(&radio, 0, nb_results, all_results);
* \endcode
*
* On the other hand, fetching result one after the other:
* \code{.cpp}
* uint8_t nb_results = 0;
* lr11xx_wifi_get_nb_results(&radio, &nb_results);
* lr11xx_wifi_basic_mac_type_channel_result_t single_results = {0};
* for(uint8_t index_result = 0; index_result < nb_results; index_result++){
* lr11xx_wifi_read_basic_mac_type_channel_results(&radio, index_result, 1, &single_results);
* // Do something with single_results
* }
* \endcode
*
* @remark This result fetching function **MUST** be used only if the scan function call was made with Scan Mode set to
* @ref ::LR11XX_WIFI_SCAN_MODE_BEACON or @ref ::LR11XX_WIFI_SCAN_MODE_BEACON_AND_PKT.
* Refer to @ref lr11xx_wifi_are_scan_mode_result_format_compatible to know which scan mode and result format are
* compatible.
*
* @param [in] radio Radio abstraction
* @param [in] start_result_index Result index from which starting to fetch the results
* @param [in] nb_results Number of results to fetch
* @param [out] results Pointer to an array of result structures to populate. It is up to the caller to ensure this
* array can hold at least nb_results elements.
*
* @returns Operation status
*
* @see lr11xx_wifi_are_scan_mode_result_format_compatible, lr11xx_wifi_read_basic_complete_results,
* lr11xx_wifi_read_extended_full_results
*/
lr11xx_status_t lr11xx_wifi_read_basic_mac_type_channel_results( const void* context, const uint8_t start_result_index,
const uint8_t nb_results,
lr11xx_wifi_basic_mac_type_channel_result_t* results );
/*!
* @brief Read extended complete results
*
* This function can be used to fetch all results in a row, or one after the other.
* It corresponds to result format @ref ::LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL.
*
* An example of usage to fetch all results in a row is:
* \code{.cpp}
* uint8_t nb_results = 0;
* lr11xx_wifi_get_nb_results(&radio, &nb_results);
* lr11xx_wifi_extended_full_result_t all_results[LR11XX_WIFI_MAX_RESULTS] = {0};
* lr11xx_wifi_read_extended_full_results(&radio, 0, nb_results, all_results);
* \endcode
*
* On the other hand, fetching result one after the other:
* \code{.cpp}
* uint8_t nb_results = 0;
* lr11xx_wifi_get_nb_results(&radio, &nb_results);
* lr11xx_wifi_extended_full_result_t single_results = {0};
* for(uint8_t index_result = 0; index_result < nb_results; index_result++){
* lr11xx_wifi_read_extended_full_results(&radio, index_result, 1, &single_results);
* // Do something with single_results
* }
* \endcode
*
* @remark This result fetching function **MUST** be used only if the scan function call was made with Scan Mode set to
* @ref ::LR11XX_WIFI_SCAN_MODE_FULL_BEACON.
* Refer to @ref lr11xx_wifi_are_scan_mode_result_format_compatible to know which scan mode and result format are
* compatible.
*
* @param [in] radio Radio abstraction
* @param [in] start_result_index Result index from which starting to fetch the results
* @param [in] nb_results Number of results to fetch
* @param [out] results Pointer to an array of result structures to populate. It is up to the caller to ensure this
* array can hold at least nb_results elements.
*
* @returns Operation status
*
* @see lr11xx_wifi_are_scan_mode_result_format_compatible, lr11xx_wifi_read_basic_complete_results,
* lr11xx_wifi_read_basic_mac_type_channel_results
*/
lr11xx_status_t lr11xx_wifi_read_extended_full_results( const void* radio, const uint8_t start_result_index,
const uint8_t nb_results,
lr11xx_wifi_extended_full_result_t* results );
/*!
* @brief Reset the internal counters of cumulative timing
*
* @param [in] context Chip implementation context
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_reset_cumulative_timing( const void* context );
/*!
* @brief Read the internal counters of cumulative timing
*
* @param [in] context Chip implementation context
* @param [out] timing A pointer to the cumulative timing structure to populate
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_read_cumulative_timing( const void* context, lr11xx_wifi_cumulative_timings_t* timing );
/*!
* @brief Get size of country code search results
*
* @param [in] context Chip implementation context
* @param [out] nb_country_code_results Number of country results to read
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_get_nb_country_code_results( const void* context, uint8_t* nb_country_code_results );
/*!
* @brief Read country code results
*
* The total number of country code results to read is obtained from a previous call to
* lr11xx_wifi_get_nb_country_code_results
*
* @param [in] context Chip implementation context
* @param [in] start_result_index The result index to start reading results from
* @param [in] nb_country_results Number of country code results to read
* @param [out] country_code_results An array of lr11xx_wifi_country_code_t to be filled. It is up to the application to
* ensure this array is big enough to hold nb_country_results elements
*
* @returns Operation status
*
* @see lr11xx_wifi_get_nb_country_code_results, lr11xx_wifi_search_country_code
*/
lr11xx_status_t lr11xx_wifi_read_country_code_results( const void* context, const uint8_t start_result_index,
const uint8_t nb_country_results,
lr11xx_wifi_country_code_t* country_code_results );
/*!
* @brief Configure the timestamp used to discriminate mobile access points from gateways.
*
* This filtering is based on the hypothesis that mobile access points have timestamp shorter than gateways.
*
* @param [in] context Chip implementation context
* @param [in] timestamp_in_s Timestamp value in second
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_cfg_timestamp_ap_phone( const void* context, uint32_t timestamp_in_s );
/*!
* @brief Get the internal wifi firmware version
*
* @param [in] context Chip implementation context
* @param [out] wifi_version The wifi version structure populated with version numbers
*
* @returns Operation status
*/
lr11xx_status_t lr11xx_wifi_read_version( const void* context, lr11xx_wifi_version_t* wifi_version );
/*!
* @brief Retreive channel information from channel info byte
*
* This method is to be called with on the WiFi channel info byte of a scan result.
*
* As the WiFi passive scan allows to get Access Point MAC address from Packet WiFi frames, it is possible that the
* frame does not comes from the Access Point, but from a device. In that case, the RSSI reported by LR11XX is the one
* of the frame received from the device and not from the Access Point. The rssi_validity flag allows to detect that
* case.
*
* It is possible for an Access Point to be a mobile AP, which is of low interest for location purpose. The LR11XX tries
* to detect mobile AP based on Access Point up time and set the flag mac_origin_estimation accordingly.
*
* @param [in] channel_info The channel info byte to retrieve channel information from. It is obtained from WiFi
* passive scan result
* @param [out] channel The channel of the scanned mac address
* @param [out] rssi_validity The validity of the scanned MAC address
* @param [out] mac_origin_estimation Indicates the estimation of MAC address origin by LR11XX
*
* @see lr11xx_wifi_read_basic_complete_results, lr11xx_wifi_read_basic_mac_type_channel_results,
* lr11xx_wifi_cfg_timestamp_ap_phone
*/
void lr11xx_wifi_parse_channel_info( const lr11xx_wifi_channel_info_byte_t channel_info, lr11xx_wifi_channel_t* channel,
bool* rssi_validity, lr11xx_wifi_mac_origin_t* mac_origin_estimation );
/*!
* @brief Helper method to retrieve channel from channel info byte
*
* @param [in] channel_info The chanel info byte from passive scan result
*
* @returns The channel of scanned MAC address
*
* @see lr11xx_wifi_parse_channel_info
*/
lr11xx_wifi_channel_t lr11xx_wifi_extract_channel_from_info_byte( const lr11xx_wifi_channel_info_byte_t channel_info );
/*!
* @brief Retrieve the Frame Type, Frame Subtype, To/From DS fields from a frame info byte
*
* This method is intended to be called on the channel info byte of a passive scan result structure.
*
* The from_ds/to_ds (Distribution Station) fields have the following meaning:
*
* <table>
* <tr><th> to_ds value </th><th> from_ds value </th><th> Meaning </th>
* <tr><td> False </td><td> False </td><td> Frame was between two Stations
* </td> <tr><td> True </td><td> False </td><td> Frame was from Station to
* Access Point </td> <tr><td> False </td><td> True </td><td> Frame was sent
* from Access Point or Distribution Stations </td> <tr><td> True </td><td>
* True </td><td> Mesh network only, frame was between Stations </td>
* </table>
*
* @param [in] frame_type_info The frame info byte from passive scan result
* @param [out] frame_type The Frame Type of the received frame
* @param [out] frame_sub_type The Frame SubType of the frame received
* @param [out] to_ds to_ds field of the frame received
* @param [out] from_ds from_ds field of the frame received
*/
void lr11xx_wifi_parse_frame_type_info( const lr11xx_wifi_frame_type_info_byte_t frame_type_info,
lr11xx_wifi_frame_type_t* frame_type,
lr11xx_wifi_frame_sub_type_t* frame_sub_type, bool* to_ds, bool* from_ds );
/*!
* @brief Retrieve the data rate information from data rate info byte
*
* This method is intended to be called on a data rate info byte of a passive scan result structure.
*
* @param [in] data_rate_info The data rate info byte from a passive scan result
* @param [out] wifi_signal_type The wifi signal type of the scanned frame
* @param [out] wifi_data_rate The data rate of the scanned frame
*/
void lr11xx_wifi_parse_data_rate_info( const lr11xx_wifi_datarate_info_byte_t data_rate_info,
lr11xx_wifi_signal_type_result_t* wifi_signal_type,
lr11xx_wifi_datarate_t* wifi_data_rate );
/*!
* @brief Return the maximal number of results to read per SPI communication
*
* This function **DOES NOT** communicates with the LR11XX. It returns the driver maximal number of Wi-Fi results it can
* retrieve per SPI communication.
*
* @remark It is a driver limitation, not a LR11XX limitation, that avoid allocating temporary buffers of size too big
* when reading Wi-Fi passive scan results.
*
* @returns The maximal number of results to fetch per SPI calls
*
* @see LR11XX_WIFI_N_RESULTS_MAX_PER_CHUNK
*/
uint8_t lr11xx_wifi_get_nb_results_max_per_chunk( void );
/*!
* @brief Helper method to retrieve the signal type from data rate info byte
*
* @param [in] data_rate_info The data rate info byte from a passive scan result
*
* @returns The Signal Type of the scanned frame
*/
lr11xx_wifi_signal_type_result_t lr11xx_wifi_extract_signal_type_from_data_rate_info(
const lr11xx_wifi_datarate_info_byte_t data_rate_info );
/*!
* @brief Helper function to check if a buffer is a well-formed UTF-8 byte sequence
*
* @param [in] buffer The buffer holding the bytes to be analyzed
* @param [in] length The number of bytes in the buffer
*
* @returns The result of the check
*/
bool lr11xx_wifi_is_well_formed_utf8_byte_sequence( const uint8_t* buffer, const uint8_t length );
/*!
* @brief Check that Wi-Fi scan mode and result format are compatible
*
* The possible combination of Wi-Fi scan modes and result format are the following:
*
* <table>
* <tr> <th> Scan Mode <th> Type/Sub-type selected <th> Corresponding read result function
* <tr> <td> @ref ::LR11XX_WIFI_SCAN_MODE_BEACON <td> Management/Beacon and Management/Probe Response <td rowspan="2">
* @ref lr11xx_wifi_read_basic_complete_results, @ref lr11xx_wifi_read_basic_mac_type_channel_results <tr> <td>
* @ref ::LR11XX_WIFI_SCAN_MODE_BEACON_AND_PKT <td> Some from Management, Control and Data Types <tr> <td>
* @ref ::LR11XX_WIFI_SCAN_MODE_FULL_BEACON <td> Management/Beacon and Management/Probe Response <td rowspan="2"> @ref
* lr11xx_wifi_read_extended_full_results <tr> <td> @ref ::LR11XX_WIFI_SCAN_MODE_UNTIL_SSID <td> Management/Beacon and
* Management/Probe Response - until SSID field
* </table>
*
* @param scan_mode The scan mode used when calling the scan API
* @param result_format The result format used when calling the read result API
* @retval true The scan mode and result format are compatible
* @retval false The scan mode and result format are not compatible.
*/
bool lr11xx_wifi_are_scan_mode_result_format_compatible( lr11xx_wifi_mode_t scan_mode,
lr11xx_wifi_result_format_t result_format );
/**
* @brief Compute the power consumption in nAh based on the cumulative timing.
*
* @param [in] regulator The regulator used during last Wi-Fi passive scan
* @param [in] timing Cumulative timing structure to use for computation
*
* @returns Current consumption in nAh
*/
uint32_t lr11xx_wifi_get_consumption_nah( lr11xx_system_reg_mode_t regulator, lr11xx_wifi_cumulative_timings_t timing );
#ifdef __cplusplus
}
#endif
#endif // LR11XX_WIFI_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,410 @@
/*!
* @file lr11xx_wifi_types.h
*
* @brief Wi-Fi passive scan driver types for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR11XX_WIFI_TYPES_H
#define LR11XX_WIFI_TYPES_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdbool.h>
#include <stdint.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
#define LR11XX_WIFI_MAC_ADDRESS_LENGTH ( 6 )
#define LR11XX_WIFI_MAX_RESULTS ( 32 )
#define LR11XX_WIFI_RESULT_SSID_LENGTH ( 32 )
#define LR11XX_WIFI_MAX_COUNTRY_CODE ( 32 )
#define LR11XX_WIFI_STR_COUNTRY_CODE_SIZE ( 2 )
#define LR11XX_WIFI_CHANNEL_1_POS ( 0U ) //!< Channel at frequency 2.412 GHz
#define LR11XX_WIFI_CHANNEL_1_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_1_POS )
#define LR11XX_WIFI_CHANNEL_2_POS ( 1U ) //!< Channel at frequency 2.417 GHz
#define LR11XX_WIFI_CHANNEL_2_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_2_POS )
#define LR11XX_WIFI_CHANNEL_3_POS ( 2U ) //!< Channel at frequency 2.422 GHz
#define LR11XX_WIFI_CHANNEL_3_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_3_POS )
#define LR11XX_WIFI_CHANNEL_4_POS ( 3U ) //!< Channel at frequency 2.427 GHz
#define LR11XX_WIFI_CHANNEL_4_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_4_POS )
#define LR11XX_WIFI_CHANNEL_5_POS ( 4U ) //!< Channel at frequency 2.432 GHz
#define LR11XX_WIFI_CHANNEL_5_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_5_POS )
#define LR11XX_WIFI_CHANNEL_6_POS ( 5U ) //!< Channel at frequency 2.437 GHz
#define LR11XX_WIFI_CHANNEL_6_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_6_POS )
#define LR11XX_WIFI_CHANNEL_7_POS ( 6U ) //!< Channel at frequency 2.442 GHz
#define LR11XX_WIFI_CHANNEL_7_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_7_POS )
#define LR11XX_WIFI_CHANNEL_8_POS ( 7U ) //!< Channel at frequency 2.447 GHz
#define LR11XX_WIFI_CHANNEL_8_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_8_POS )
#define LR11XX_WIFI_CHANNEL_9_POS ( 8U ) //!< Channel at frequency 2.452 GHz
#define LR11XX_WIFI_CHANNEL_9_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_9_POS )
#define LR11XX_WIFI_CHANNEL_10_POS ( 9U ) //!< Channel at frequency 2.457 GHz
#define LR11XX_WIFI_CHANNEL_10_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_10_POS )
#define LR11XX_WIFI_CHANNEL_11_POS ( 10U ) //!< Channel at frequency 2.462 GHz
#define LR11XX_WIFI_CHANNEL_11_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_11_POS )
#define LR11XX_WIFI_CHANNEL_12_POS ( 11U ) //!< Channel at frequency 2.467 GHz
#define LR11XX_WIFI_CHANNEL_12_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_12_POS )
#define LR11XX_WIFI_CHANNEL_13_POS ( 12U ) //!< Channel at frequency 2.472 GHz
#define LR11XX_WIFI_CHANNEL_13_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_13_POS )
#define LR11XX_WIFI_CHANNEL_14_POS ( 13U ) //!< Channel at frequency 2.484 GHz
#define LR11XX_WIFI_CHANNEL_14_MASK ( 0x01UL << LR11XX_WIFI_CHANNEL_14_POS )
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/*!
* @brief Type to store a Wi-Fi channel mask
*/
typedef uint16_t lr11xx_wifi_channel_mask_t;
/*!
* @brief Type to store a Wi-Fi channel info byte
*/
typedef uint8_t lr11xx_wifi_channel_info_byte_t;
/*!
* @brief Type to store a Wi-Fi datarate info byte
*/
typedef uint8_t lr11xx_wifi_datarate_info_byte_t;
/*!
* @brief Type to store a Wi-Fi frame type info byte
*/
typedef uint8_t lr11xx_wifi_frame_type_info_byte_t;
/*!
* @brief Type to store a Wi-Fi frame sub_type
*/
typedef uint8_t lr11xx_wifi_frame_sub_type_t;
/*!
* @brief Wi-Fi FCS info byte
*/
typedef struct lr11xx_wifi_fcs_info_byte_s
{
bool is_fcs_ok; //!< True if the LR11XX has checked the FCS and the check succeeded
bool is_fcs_checked; //!< True if the LR11XX has checked the FCS
} lr11xx_wifi_fcs_info_byte_t;
/*!
* @brief Type to store a MAC address
*/
typedef uint8_t lr11xx_wifi_mac_address_t[LR11XX_WIFI_MAC_ADDRESS_LENGTH];
/*!
* @brief Type to store the Country Code
*/
typedef uint8_t lr11xx_wifi_country_code_str_t[LR11XX_WIFI_STR_COUNTRY_CODE_SIZE];
/*!
* @brief Wi-Fi Channels index
*/
typedef enum
{
LR11XX_WIFI_NO_CHANNEL = 0x00,
LR11XX_WIFI_CHANNEL_1 = 0x01, //!< Channel at frequency 2.412 GHz
LR11XX_WIFI_CHANNEL_2 = 0x02, //!< Channel at frequency 2.417 GHz
LR11XX_WIFI_CHANNEL_3 = 0x03, //!< Channel at frequency 2.422 GHz
LR11XX_WIFI_CHANNEL_4 = 0x04, //!< Channel at frequency 2.427 GHz
LR11XX_WIFI_CHANNEL_5 = 0x05, //!< Channel at frequency 2.432 GHz
LR11XX_WIFI_CHANNEL_6 = 0x06, //!< Channel at frequency 2.437 GHz
LR11XX_WIFI_CHANNEL_7 = 0x07, //!< Channel at frequency 2.442 GHz
LR11XX_WIFI_CHANNEL_8 = 0x08, //!< Channel at frequency 2.447 GHz
LR11XX_WIFI_CHANNEL_9 = 0x09, //!< Channel at frequency 2.452 GHz
LR11XX_WIFI_CHANNEL_10 = 0x0A, //!< Channel at frequency 2.457 GHz
LR11XX_WIFI_CHANNEL_11 = 0x0B, //!< Channel at frequency 2.462 GHz
LR11XX_WIFI_CHANNEL_12 = 0x0C, //!< Channel at frequency 2.467 GHz
LR11XX_WIFI_CHANNEL_13 = 0x0D, //!< Channel at frequency 2.472 GHz
LR11XX_WIFI_CHANNEL_14 = 0x0E, //!< Channel at frequency 2.484 GHz
LR11XX_WIFI_ALL_CHANNELS = 0x0F,
} lr11xx_wifi_channel_t;
/*!
* @brief WiFi theoretical Datarates
*/
typedef enum
{
LR11XX_WIFI_DATARATE_1_MBPS = 1,
LR11XX_WIFI_DATARATE_2_MBPS = 2,
LR11XX_WIFI_DATARATE_6_MBPS = 3,
LR11XX_WIFI_DATARATE_9_MBPS = 4,
LR11XX_WIFI_DATARATE_12_MBPS = 5,
LR11XX_WIFI_DATARATE_18_MBPS = 6,
LR11XX_WIFI_DATARATE_24_MBPS = 7,
LR11XX_WIFI_DATARATE_36_MBPS = 8,
LR11XX_WIFI_DATARATE_48_MBPS = 9,
LR11XX_WIFI_DATARATE_54_MBPS = 10,
LR11XX_WIFI_DATARATE_6_5_MBPS = 11,
LR11XX_WIFI_DATARATE_13_MBPS = 12,
LR11XX_WIFI_DATARATE_19_5_MBPS = 13,
LR11XX_WIFI_DATARATE_26_MBPS = 14,
LR11XX_WIFI_DATARATE_39_MBPS = 15,
LR11XX_WIFI_DATARATE_52_MBPS = 16,
LR11XX_WIFI_DATARATE_58_MBPS = 17,
LR11XX_WIFI_DATARATE_65_MBPS = 18,
LR11XX_WIFI_DATARATE_7_2_MBPS = 19,
LR11XX_WIFI_DATARATE_14_4_MBPS = 20,
LR11XX_WIFI_DATARATE_21_7_MBPS = 21,
LR11XX_WIFI_DATARATE_28_9_MBPS = 22,
LR11XX_WIFI_DATARATE_43_3_MBPS = 23,
LR11XX_WIFI_DATARATE_57_8_MBPS = 24,
LR11XX_WIFI_DATARATE_65_2_MBPS = 25,
LR11XX_WIFI_DATARATE_72_2_MBPS = 26,
} lr11xx_wifi_datarate_t;
/*!
* @brief WiFi Frame Types
*/
typedef enum
{
LR11XX_WIFI_FRAME_TYPE_MANAGEMENT = 0x00,
LR11XX_WIFI_FRAME_TYPE_CONTROL = 0x01,
LR11XX_WIFI_FRAME_TYPE_DATA = 0x02,
} lr11xx_wifi_frame_type_t;
/*!
* @brief The WiFi MAC address origin
*
* @see lr11xx_wifi_parse_channel_info for details about the MAC address origin estimation of the LR11XX
*/
typedef enum
{
LR11XX_WIFI_ORIGIN_BEACON_FIX_AP = 1, //!< MAC address extracted from a packet coming from a fix Access Point
LR11XX_WIFI_ORIGIN_BEACON_MOBILE_AP = 2, //!< MAC address extracted from a packet coming from a mobile Access Point
LR11XX_WIFI_ORIGIN_UNKNOWN = 3, //!< Impossible to determine the origin of the packet the MAC is extracted from
} lr11xx_wifi_mac_origin_t;
/*!
* @brief Wi-Fi signal type for passive scanning configuration
*
* Note it is not possible to configure the WiFi passive scanning to search Wi-Fi type N GreenField. Only Wi-Fi type N
* Mixed Mode can be scanned by LR11XX.
*
* @warning ::LR11XX_WIFI_TYPE_SCAN_G and ::LR11XX_WIFI_TYPE_SCAN_N configurations are implemented the same way, and
* both will scan Wi-Fi type G **AND** Wi-Fi type N.
*/
typedef enum
{
LR11XX_WIFI_TYPE_SCAN_B = 0x01, //!< Wi-Fi B
LR11XX_WIFI_TYPE_SCAN_G = 0x02, //!< Wi-Fi G
LR11XX_WIFI_TYPE_SCAN_N = 0x03, //!< Wi-Fi N
LR11XX_WIFI_TYPE_SCAN_B_G_N = 0x04, //!< Wi-Fi B and Wi-Fi G/N
} lr11xx_wifi_signal_type_scan_t;
/*!
* @brief Wi-Fi signal type for passive scan results
*
* Note that the Wi-Fi N detected is Wi-Fi N Mixed mode, and not GreenField.
*/
typedef enum
{
LR11XX_WIFI_TYPE_RESULT_B = 0x01, //!< WiFi B
LR11XX_WIFI_TYPE_RESULT_G = 0x02, //!< WiFi G
LR11XX_WIFI_TYPE_RESULT_N = 0x03, //!< WiFi N
} lr11xx_wifi_signal_type_result_t;
/*!
* @brief Wi-Fi scan mode
*
* When the LR11XX receives a Wi-Fi frame, it starts demodulating it. Depending on the scan mode selected, only some
* Wi-Fi frame type/sub-types are to be kept. The demodulation step is stopped as soon as the LR11XX detects the current
* Wi-Fi frame is not of the required type/sub-types. This saves scan time and consumption.
*
* A Wi-Fi frame is never completely demodulated. The ::LR11XX_WIFI_SCAN_MODE_FULL_BEACON uses a special configuration
* allowing to demodulate more fields (until Frame Check Sequence field), at a price of higher scan duration and higher
* consumption.
*
* @note Not all results formats are available depending on the scan mode selected. Refer to
* @ref lr11xx_wifi_are_scan_mode_result_format_compatible to know which result formats are available depending on scan
* mode selected.
*
* @see lr11xx_wifi_are_scan_mode_result_format_compatible
*/
typedef enum
{
LR11XX_WIFI_SCAN_MODE_BEACON =
1, //!< Exposes Beacons and Probe Responses Access Points frames until Period Beacon field (Basic result)
LR11XX_WIFI_SCAN_MODE_BEACON_AND_PKT =
2, //!< Exposes some Management Access Points frames until Period Beacon field, and some other packets frame
//!< until third Mac Address field (Basic result)
LR11XX_WIFI_SCAN_MODE_FULL_BEACON =
4, //!< Exposes Beacons and Probes Responses Access Points frames until Frame Check Sequence (FCS) field
//!< (Extended result). In this mode, only signal type LR11XX_WIFI_TYPE_SCAN_B is executed and other signal
//!< types are silently discarded.
LR11XX_WIFI_SCAN_MODE_UNTIL_SSID = 5, //!< Exposes Beacons and Probes Responses Access Points frames until the end
//!< of SSID field (Extended result) - available since firmware 0x0306
} lr11xx_wifi_mode_t;
/*!
* @brief Cumulative timings
*
* This structure is representing the cumulative time spent in the different modes of Wi-Fi passive scanning procedure.
* All timings are provided in [us].
* */
typedef struct lr11xx_wifi_cumulative_timings_s
{
uint32_t rx_detection_us; //!< Cumulative time spent during NFE or TOA
uint32_t rx_correlation_us; //!< Cumulative time spent during preamble detection
uint32_t rx_capture_us; //!< Cumulative time spent during signal acquisition
uint32_t demodulation_us; //!< Cumulative time spent during software demodulation
} lr11xx_wifi_cumulative_timings_t;
/*!
* @brief Basic complete result structure
*
* The beacon period is expressed in TU (Time Unit). 1 TU is 1024 microseconds.
*/
typedef struct lr11xx_wifi_basic_complete_result_s
{
lr11xx_wifi_datarate_info_byte_t data_rate_info_byte;
lr11xx_wifi_channel_info_byte_t channel_info_byte;
int8_t rssi;
lr11xx_wifi_frame_type_info_byte_t frame_type_info_byte;
lr11xx_wifi_mac_address_t mac_address;
int16_t phi_offset;
uint64_t timestamp_us; //!< Indicate the up-time of the Access Point transmitting the Beacon [us]
uint16_t beacon_period_tu;
} lr11xx_wifi_basic_complete_result_t;
/*!
* @brief Basic MAC, type, channel result structure
*/
typedef struct lr11xx_wifi_basic_mac_type_channel_result_s
{
lr11xx_wifi_datarate_info_byte_t data_rate_info_byte;
lr11xx_wifi_channel_info_byte_t channel_info_byte;
int8_t rssi;
lr11xx_wifi_mac_address_t mac_address;
} lr11xx_wifi_basic_mac_type_channel_result_t;
/*!
* @brief Extended full result structure
*
* @note The beacon period is expressed in TU (Time Unit). 1 TU is 1024 microseconds.
*
* @remark When used with @ref ::LR11XX_WIFI_SCAN_MODE_UNTIL_SSID, the following field are always set to 0:
* - field is_fcs_ok and is_fcs_checked in fcs_check_byte structure
* - current_channel
* - country_code
* - io_regulation
*/
typedef struct
{
lr11xx_wifi_datarate_info_byte_t data_rate_info_byte;
lr11xx_wifi_channel_info_byte_t channel_info_byte;
int8_t rssi;
uint8_t rate; //!< Rate index
uint16_t service; //!< Service value
uint16_t length; //!< Length of MPDU (in microseconds for WiFi B, bytes for WiFi G)
uint16_t frame_control; //!< Frame Control structure
lr11xx_wifi_mac_address_t mac_address_1;
lr11xx_wifi_mac_address_t mac_address_2;
lr11xx_wifi_mac_address_t mac_address_3;
uint64_t timestamp_us; //!< Indicate the up-time of the Access Point
//!< transmitting the Beacon [us]
uint16_t beacon_period_tu;
uint16_t seq_control; //!< Sequence Control value
uint8_t ssid_bytes[LR11XX_WIFI_RESULT_SSID_LENGTH]; //!< Service Set
//!< IDentifier
lr11xx_wifi_channel_t current_channel; //!< Current channel indicated in the Wi-Fi frame
lr11xx_wifi_country_code_str_t country_code; //!< Country Code
uint8_t io_regulation; //!< Input Output Regulation
lr11xx_wifi_fcs_info_byte_t fcs_check_byte; //!< Frame Check Sequence info
int16_t phi_offset;
} lr11xx_wifi_extended_full_result_t;
/*!
* @brief Wi-Fi scan result formats
*
* @note Result format to use depends on the scan mode selected when calling @ref lr11xx_wifi_scan or @ref
* lr11xx_wifi_scan_time_limit API. Refer to @ref lr11xx_wifi_are_scan_mode_result_format_compatible to know which
* result formats are available depending on scan mode selected.
*
* @see lr11xx_wifi_are_scan_mode_result_format_compatible
*/
typedef enum
{
LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE, //!< Basic complete result format: @ref
//!< lr11xx_wifi_basic_complete_result_t
LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL, //!< Basic MAC/type/channel result format: @ref
//!< lr11xx_wifi_basic_mac_type_channel_result_t
LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL, //!< Extended full result format: @ref lr11xx_wifi_extended_full_result_t
} lr11xx_wifi_result_format_t;
/*!
* @brief Wi-Fi country code structure
*/
typedef struct lr11xx_wifi_country_code_s
{
lr11xx_wifi_country_code_str_t country_code;
uint8_t io_regulation; //!< Input Output Regulation
lr11xx_wifi_channel_info_byte_t channel_info_byte;
lr11xx_wifi_mac_address_t mac_address;
} lr11xx_wifi_country_code_t;
/*!
* @brief Wi-Fi firmware version
*/
typedef struct lr11xx_wifi_version_s
{
uint8_t major;
uint8_t minor;
} lr11xx_wifi_version_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#ifdef __cplusplus
}
#endif
#endif // LR11XX_WIFI_TYPES_H
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,127 @@
/**
* @file lr_fhss_v1_base_types.h
*
* @brief Radio-independent LR-FHSS base type definitions, version 1
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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 LR_FHSS_V1_BASE_TYPES_H__
#define LR_FHSS_V1_BASE_TYPES_H__
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include <stdbool.h>
/*
* -----------------------------------------------------------------------------
* --- PUBLIC MACROS -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC CONSTANTS --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC TYPES ------------------------------------------------------------
*/
/**
* @brief LR-FHSS modulation type
*/
typedef enum lr_fhss_v1_modulation_type_e
{
LR_FHSS_V1_MODULATION_TYPE_GMSK_488 = 0,
} lr_fhss_v1_modulation_type_t;
/**
* @brief LR-FHSS coding rate
*/
typedef enum lr_fhss_v1_cr_e
{
LR_FHSS_V1_CR_5_6 = 0x00,
LR_FHSS_V1_CR_2_3 = 0x01,
LR_FHSS_V1_CR_1_2 = 0x02,
LR_FHSS_V1_CR_1_3 = 0x03,
} lr_fhss_v1_cr_t;
/**
* @brief LR-FHSS grid
*/
typedef enum lr_fhss_v1_grid_e
{
LR_FHSS_V1_GRID_25391_HZ = 0x00,
LR_FHSS_V1_GRID_3906_HZ = 0x01,
} lr_fhss_v1_grid_t;
/**
* @brief LR-FHSS bandwidth
*/
typedef enum lr_fhss_v1_bw_e
{
LR_FHSS_V1_BW_39063_HZ = 0x00,
LR_FHSS_V1_BW_85938_HZ = 0x01,
LR_FHSS_V1_BW_136719_HZ = 0x02,
LR_FHSS_V1_BW_183594_HZ = 0x03,
LR_FHSS_V1_BW_335938_HZ = 0x04,
LR_FHSS_V1_BW_386719_HZ = 0x05,
LR_FHSS_V1_BW_722656_HZ = 0x06,
LR_FHSS_V1_BW_773438_HZ = 0x07,
LR_FHSS_V1_BW_1523438_HZ = 0x08,
LR_FHSS_V1_BW_1574219_HZ = 0x09,
} lr_fhss_v1_bw_t;
/**
* @brief LR-FHSS parameter structure
*/
typedef struct lr_fhss_v1_params_s
{
const uint8_t* sync_word; /**< 4-byte sync word */
lr_fhss_v1_modulation_type_t modulation_type;
lr_fhss_v1_cr_t cr;
lr_fhss_v1_grid_t grid;
lr_fhss_v1_bw_t bw;
bool enable_hopping;
uint8_t header_count; /**< Number of header blocks */
} lr_fhss_v1_params_t;
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS PROTOTYPES ---------------------------------------------
*/
#endif // LR_FHSS_V1_BASE_TYPES_H__
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,112 @@
#include "esp_lora_1121.h"
void lora_init_io_context(const void *context,int cs,int reset,int busy,int irq)
{
((lr1121_t *)context)->cs = cs;
((lr1121_t *)context)->reset = reset;
((lr1121_t *)context)->irq = irq;
((lr1121_t *)context)->busy = busy;
}
void lora_init_io(const void *context)
{
//Set the output pin
gpio_config_t io_conf = {};
io_conf.intr_type = GPIO_INTR_DISABLE; // Disable interrupts for this pin
if (((lr1121_t *)context)->cs >= 0) {
io_conf.pin_bit_mask = 1ULL << ((lr1121_t *)context)->cs;
if (((lr1121_t *)context)->reset >= 0) {
io_conf.pin_bit_mask |= 1ULL << ((lr1121_t *)context)->reset; // Select the GPIO pin using a bitmask
}
io_conf.mode = GPIO_MODE_INPUT_OUTPUT; // Set pin as input
io_conf.pull_up_en = GPIO_PULLUP_DISABLE; // Enable internal pull-up resistor
gpio_config(&io_conf); // Apply the configuration
}
//Set the input pin
io_conf.pin_bit_mask = 0;
if (((lr1121_t *)context)->busy >= 0) {
io_conf.pin_bit_mask |= 1ULL << ((lr1121_t *)context)->busy;
}
if (((lr1121_t *)context)->irq >= 0) {
io_conf.pin_bit_mask |= 1ULL << ((lr1121_t *)context)->irq; // Select the GPIO pin using a bitmask
}
if (io_conf.pin_bit_mask) {
io_conf.mode = GPIO_MODE_INPUT; // Set pin as input
io_conf.pull_up_en = GPIO_PULLUP_ENABLE; // Enable internal pull-up resistor
gpio_config(&io_conf); // Apply the configuration
}
if (((lr1121_t *)context)->cs >= 0) {
gpio_set_level(((lr1121_t *)context)->cs, 1); // Set the GPIO pin level
}
if (((lr1121_t *)context)->reset >= 0) {
gpio_set_level(((lr1121_t *)context)->reset, 1); // Set the GPIO pin level
}
}
void lora_init_irq(const void *context, gpio_isr_t handler)
{
if (handler == NULL || ((lr1121_t *)context)->irq < 0) {
return;
}
// Zero-initialize the GPIO configuration structure
gpio_config_t io_conf = {};
io_conf.intr_type = GPIO_INTR_POSEDGE; // Trigger on negative edge (falling edge)
io_conf.mode = GPIO_MODE_INPUT; // Set pin as input mode
io_conf.pull_down_en = GPIO_PULLDOWN_DISABLE; // Disable pull-down
io_conf.pull_up_en = GPIO_PULLUP_ENABLE; // Enable pull-up resistor
if (((lr1121_t *)context)->irq < 0) {
return;
}
io_conf.pin_bit_mask = 1ULL << ((lr1121_t *)context)->irq; // Select the GPIO pin using a bitmask
gpio_config(&io_conf); // Apply the configuration
// Install the GPIO interrupt service if not already installed
gpio_install_isr_service(0); // Pass 0 for default ISR flags
// Register the interrupt handler for the specified pin
gpio_isr_handler_add(((lr1121_t *)context)->irq, handler, (void *)((lr1121_t *)context)->irq);
}
void lora_spi_init(const void* context, spi_device_handle_t spi)
{
((lr1121_t *)context)->spi = spi;
}
void lora_spi_write_bytes(const void* context,const uint8_t *wirte,const uint16_t wirte_length)
{
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = wirte_length * 8; // Length is in bits
t.tx_buffer = wirte;
ESP_ERROR_CHECK(spi_device_transmit(((lr1121_t *)context)->spi, &t));
}
void lora_spi_read_bytes(const void* context, uint8_t *read,const uint16_t read_length)
{
spi_transaction_t t;
memset(&t, 0, sizeof(t));
t.length = read_length * 8; // Length is in bits
t.rx_buffer = read;
ESP_ERROR_CHECK(spi_device_transmit(((lr1121_t *)context)->spi, &t));
}
lr1121_modem_response_code_t lr1121_modem_board_event_flush( const void* context )
{
lr1121_modem_response_code_t modem_response_code = LR1121_MODEM_RESPONSE_CODE_OK;
lr1121_modem_event_fields_t event_fields;
do
{
modem_response_code = lr1121_modem_get_event( context, &event_fields );
} while( modem_response_code != LR1121_MODEM_RESPONSE_CODE_NO_EVENT );
return modem_response_code;
}

View File

@@ -0,0 +1,837 @@
#include "lr1121_common.h"
#include <stddef.h>
#include <stdio.h>
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
static const lr11xx_radio_rssi_calibration_table_t smtc_shield_lr11xx_common_rssi_calibration_table_below_600mhz = {
.gain_offset = 0,
.gain_tune = { .g4 = 12,
.g5 = 12,
.g6 = 14,
.g7 = 0,
.g8 = 1,
.g9 = 3,
.g10 = 4,
.g11 = 4,
.g12 = 3,
.g13 = 6,
.g13hp1 = 6,
.g13hp2 = 6,
.g13hp3 = 6,
.g13hp4 = 6,
.g13hp5 = 6,
.g13hp6 = 6,
.g13hp7 = 6 },
};
static const lr11xx_radio_rssi_calibration_table_t
smtc_shield_lr11xx_common_rssi_calibration_table_from_600mhz_to_2ghz = {
.gain_offset = 0,
.gain_tune = { .g4 = 2,
.g5 = 2,
.g6 = 2,
.g7 = 3,
.g8 = 3,
.g9 = 4,
.g10 = 5,
.g11 = 4,
.g12 = 4,
.g13 = 6,
.g13hp1 = 5,
.g13hp2 = 5,
.g13hp3 = 6,
.g13hp4 = 6,
.g13hp5 = 6,
.g13hp6 = 7,
.g13hp7 = 6 },
};
static const lr11xx_radio_rssi_calibration_table_t smtc_shield_lr11xx_common_rssi_calibration_table_above_2ghz = {
.gain_offset = 2030,
.gain_tune = { .g4 = 6,
.g5 = 7,
.g6 = 6,
.g7 = 4,
.g8 = 3,
.g9 = 4,
.g10 = 14,
.g11 = 12,
.g12 = 14,
.g13 = 12,
.g13hp1 = 12,
.g13hp2 = 12,
.g13hp3 = 12,
.g13hp4 = 8,
.g13hp5 = 8,
.g13hp6 = 9,
.g13hp7 = 9 },
};
const lr11xx_system_rfswitch_cfg_t smtc_shield_lr11xx_common_rf_switch_cfg = {
.enable = LR11XX_SYSTEM_RFSW0_HIGH | LR11XX_SYSTEM_RFSW1_HIGH ,
.standby = 0,
.rx = LR11XX_SYSTEM_RFSW0_HIGH,
.tx = LR11XX_SYSTEM_RFSW1_HIGH,
.tx_hp = LR11XX_SYSTEM_RFSW1_HIGH,
.tx_hf = 0,
.gnss = 0,
.wifi = 0,
};
const smtc_shield_lr11xx_lfclk_cfg_t smtc_shield_lr11xx_common_lfclk_cfg = {
.lf_clk_cfg = LR11XX_SYSTEM_LFCLK_XTAL,
.wait_32k_ready = true,
};
const smtc_shield_lr11xx_pa_pwr_cfg_t smtc_shield_lr1121mb1gis_pa_pwr_cfg_table[SMTC_SHIELD_LR11XX_MAX_PWR - SMTC_SHIELD_LR11XX_MIN_PWR + 1] = {
{ // Expected output power = -9dBm
.power = -9,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -8dBm
.power = -8,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -7dBm
.power = -7,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -6dBm
.power = -6,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -5dBm
.power = -5,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -4dBm
.power = -4,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -3dBm
.power = -3,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -2dBm
.power = -2,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = -1dBm
.power = -1,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 0dBm
.power = 0,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 1dBm
.power = 1,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 2dBm
.power = 2,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 3dBm
.power = 3,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 4dBm
.power = 4,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 5dBm
.power = 5,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 6dBm
.power = 6,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 7dBm
.power = 7,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 8dBm
.power = 8,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 9dBm
.power = 9,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 10dBm
.power = 10,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 11dBm
.power = 11,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 12dBm
.power = 12,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 13dBm
.power = 13,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 14dBm
.power = 14,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 15dBm
.power = 15,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 16dBm
.power = 16,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 17dBm
.power = 17,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 18dBm
.power = 18,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 19dBm
.power = 19,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 20dBm
.power = 20,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 21dBm
.power = 21,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
{ // Expected output power = 22dBm
.power = 22,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HP,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VBAT,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x07,
},
},
};
const smtc_shield_lr11xx_pa_pwr_cfg_t smtc_shield_lr1121mb1gis_pa_pwr_hf_cfg_table[SMTC_SHIELD_LR112X_MAX_PWR_HF - SMTC_SHIELD_LR112X_MIN_PWR_HF + 1] = {
{ // Expected output power = -18dBm
.power = -18,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -17dBm
.power = -17,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -16dBm
.power = -17,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -15dBm
.power = -16,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -14dBm
.power = -15,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -13dBm
.power = -14,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -12dBm
.power = -13,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -11dBm
.power = -12,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x05,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -10dBm
.power = -10,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -9dBm
.power = -9,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -8dBm
.power = -8,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -7dBm
.power = -7,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -6dBm
.power = -6,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -5dBm
.power = -5,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -4dBm
.power = -4,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -3dBm
.power = -3,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -2dBm
.power = -2,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x03,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = -1dBm
.power = -1,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x05,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 0dBm
.power = 0,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x04,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 1dBm
.power = 2,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 2dBm
.power = 2,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x00,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 3dBm
.power = 4,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 4dBm
.power = 5,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 5dBm
.power = 6,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 6dBm
.power = 7,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 7dBm
.power = 8,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 8dBm
.power = 9,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 9dBm
.power = 10,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 10dBm
.power = 11,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x05,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 11dBm
.power = 12,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x03,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 12dBm
.power = 13,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x07,
.pa_hp_sel = 0x00,
},
},
{ // Expected output power = 13dBm
.power = 13,
.pa_config = {
.pa_sel = LR11XX_RADIO_PA_SEL_HF,
.pa_reg_supply = LR11XX_RADIO_PA_REG_SUPPLY_VREG,
.pa_duty_cycle = 0x00,
.pa_hp_sel = 0x00,
},
},
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC VARIABLES --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
const lr11xx_radio_rssi_calibration_table_t* smtc_shield_lr11xx_get_rssi_calibration_table(
const uint32_t rf_freq_in_hz )
{
if( rf_freq_in_hz < 600000000 )
{
return &smtc_shield_lr11xx_common_rssi_calibration_table_below_600mhz;
}
else if( ( 600000000 <= rf_freq_in_hz ) && ( rf_freq_in_hz <= 2000000000 ) )
{
return &smtc_shield_lr11xx_common_rssi_calibration_table_from_600mhz_to_2ghz;
}
else
{
return &smtc_shield_lr11xx_common_rssi_calibration_table_above_2ghz;
}
}
const lr11xx_system_rfswitch_cfg_t* smtc_shield_lr11xx_common_get_rf_switch_cfg( void )
{
return &smtc_shield_lr11xx_common_rf_switch_cfg;
}
lr11xx_system_reg_mode_t smtc_shield_lr11xx_common_get_reg_mode( void )
{
return LR11XX_SYSTEM_REG_MODE_DCDC;
}
const smtc_shield_lr11xx_lfclk_cfg_t* smtc_shield_lr11xx_common_get_lfclk_cfg( void )
{
return &smtc_shield_lr11xx_common_lfclk_cfg;
}
const smtc_shield_lr11xx_pa_pwr_cfg_t* smtc_shield_lr1121mb1gis_get_pa_pwr_cfg( const uint32_t rf_freq_in_hz,
int8_t expected_output_pwr_in_dbm )
{
if( ( SMTC_SHIELD_LR11XX_SUBGHZ_FREQ_MIN <= rf_freq_in_hz ) &&
( rf_freq_in_hz <= SMTC_SHIELD_LR11XX_SUBGHZ_FREQ_MAX ) )
{
if( ( SMTC_SHIELD_LR11XX_MIN_PWR <= expected_output_pwr_in_dbm ) &&
( expected_output_pwr_in_dbm <= SMTC_SHIELD_LR11XX_MAX_PWR ) )
{
return &(
smtc_shield_lr1121mb1gis_pa_pwr_cfg_table[expected_output_pwr_in_dbm - SMTC_SHIELD_LR11XX_MIN_PWR] );
}
}
else if( ( ( SMTC_SHIELD_LR112X_2GHZ_FREQ_MIN <= rf_freq_in_hz ) &&
( rf_freq_in_hz <= SMTC_SHIELD_LR112X_2GHZ_FREQ_MAX ) ) ||
( ( SMTC_SHIELD_LR112X_2_4GHZ_FREQ_MIN <= rf_freq_in_hz ) &&
( rf_freq_in_hz <= SMTC_SHIELD_LR112X_2_4GHZ_FREQ_MAX ) ) )
{
if( ( SMTC_SHIELD_LR112X_MIN_PWR_HF <= expected_output_pwr_in_dbm ) &&
( expected_output_pwr_in_dbm <= SMTC_SHIELD_LR112X_MAX_PWR_HF ) )
{
return &( smtc_shield_lr1121mb1gis_pa_pwr_hf_cfg_table[expected_output_pwr_in_dbm -
SMTC_SHIELD_LR112X_MIN_PWR_HF] );
}
}
return NULL;
}
/*!
* @brief A function to get the value for low data rate optimization setting
*
* @param [in] sf LoRa Spreading Factor
* @param [in] bw LoRa Bandwidth
*/
const uint8_t smtc_shield_lr11xx_common_compute_lora_ldro( const lr11xx_radio_lora_sf_t sf, const lr11xx_radio_lora_bw_t bw )
{
switch( bw )
{
case LR11XX_RADIO_LORA_BW_500:
return 0;
case LR11XX_RADIO_LORA_BW_250:
if( sf == LR11XX_RADIO_LORA_SF12 )
{
return 1;
}
else
{
return 0;
}
case LR11XX_RADIO_LORA_BW_800:
case LR11XX_RADIO_LORA_BW_400:
case LR11XX_RADIO_LORA_BW_200:
case LR11XX_RADIO_LORA_BW_125:
if( ( sf == LR11XX_RADIO_LORA_SF12 ) || ( sf == LR11XX_RADIO_LORA_SF11 ) )
{
return 1;
}
else
{
return 0;
}
case LR11XX_RADIO_LORA_BW_62:
if( ( sf == LR11XX_RADIO_LORA_SF12 ) || ( sf == LR11XX_RADIO_LORA_SF11 ) || ( sf == LR11XX_RADIO_LORA_SF10 ) )
{
return 1;
}
else
{
return 0;
}
case LR11XX_RADIO_LORA_BW_41:
if( ( sf == LR11XX_RADIO_LORA_SF12 ) || ( sf == LR11XX_RADIO_LORA_SF11 ) || ( sf == LR11XX_RADIO_LORA_SF10 ) ||
( sf == LR11XX_RADIO_LORA_SF9 ) )
{
return 1;
}
else
{
return 0;
}
case LR11XX_RADIO_LORA_BW_31:
case LR11XX_RADIO_LORA_BW_20:
case LR11XX_RADIO_LORA_BW_15:
case LR11XX_RADIO_LORA_BW_10:
// case LR11XX_RADIO_LORA_BW_7:
return 1;
default:
return 0;
}
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,472 @@
/*!
* @file lr1121_modem_bsp.c
*
* @brief BSP driver implementation for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_bsp.h"
#include "lr1121_modem_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*!
* @brief Power config block length
*/
#define LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH ( 5 )
#define LR1121_MODEM_TX_POWER_CONSUMPTION_SIZE_BYTE ( 5 )
#define LR1121_MODEM_GET_TX_POWER_OFFSET_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_TX_POWER_OFFSET_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_GET_OUTPUT_POWER_CONFIG_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_OUTPUT_POWER_CONFIG_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_RF_OUTPUT_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_RF_OUTPUT_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_GET_CRYSTAL_ERROR_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_CRYSTAL_ERROR_CMD_LENGTH ( 3 + 4 )
#define LR1121_MODEM_GET_XOSC_CAPA_TRIM_A_B_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_XOSC_CAPA_TRIM_A_B_CMD_LENGTH ( 3 + 2 )
#define LR1121_MODEM_GET_TX_POWER_CONSUMPTION_UA_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_RX_POWER_CONSUMPTION_UA_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_RX_POWER_CONSUMPTION_UA_CMD_LENGTH ( 3 + 8 )
#define LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA_CMD_LENGTH ( 3 )
#define LR1121_MODEM_MODEM_GET_OUTPUT_POWER_CONFIG_RBUFFER_LENGTH \
( LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS * LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH )
#define LR1121_MODEM_GET_TX_POWER_CONSUMPTION_RBUFFER_LENGTH \
( LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS * LR1121_MODEM_TX_POWER_CONSUMPTION_SIZE_BYTE )
#define LR1121_MODEM_GET_RX_POWER_CONSUMPTION_RBUFFER_LENGTH ( 8 )
#define LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA_DBUFFER_MAX_LENGTH \
( LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS * LR1121_MODEM_TX_POWER_CONSUMPTION_SIZE_BYTE )
#define LR1121_MODEM_SET_TX_OUTPUT_POWER_CONFIGURATION_DBUFFER_MAX_LENGTH \
( LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH * LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operation code command
*/
enum
{
LR1121_MODEM_GET_TX_POWER_OFFSET_CMD = 0x00,
LR1121_MODEM_SET_TX_POWER_OFFSET_CMD = 0x01,
LR1121_MODEM_GET_OUTPUT_POWER_CONFIG_CMD = 0x02,
LR1121_MODEM_SET_OUTPUT_POWER_CONFIG_CMD = 0x03,
LR1121_MODEM_GET_RF_OUTPUT_CMD = 0x04,
LR1121_MODEM_SET_RF_OUTPUT_CMD = 0x05,
LR1121_MODEM_GET_CRYSTAL_ERROR_CMD = 0x06,
LR1121_MODEM_SET_CRYSTAL_ERROR_CMD = 0x07,
LR1121_MODEM_GET_XOSC_CAPA_TRIM_A_B = 0x08,
LR1121_MODEM_SET_XOSC_CAPA_TRIM_A_B = 0x09,
LR1121_MODEM_GET_TX_POWER_CONSUMPTION_UA = 0x0A,
LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA = 0x0B,
LR1121_MODEM_GET_LORA_RX_POWER_CONSUMPTION_UA = 0x0C,
LR1121_MODEM_SET_LORA_RX_POWER_CONSUMPTION_UA = 0x0D,
LR1121_MODEM_GET_GFSK_RX_POWER_CONSUMPTION_UA = 0x0E,
LR1121_MODEM_SET_GFSK_RX_POWER_CONSUMPTION_UA = 0x0F,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
static uint32_t lr1121_uint8_to_uint32( const uint8_t value[4] );
static lr1121_modem_response_code_t lr1121_modem_get_rx_power_consumption_ua(
const void* context, lr1121_modem_rx_power_consumption_t* rx_consumption, uint8_t opcode );
static lr1121_modem_response_code_t lr1121_modem_set_rx_power_consumption_ua(
const void* context, const lr1121_modem_rx_power_consumption_t* rx_consumption, uint8_t opcode );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_response_code_t lr1121_modem_get_tx_power_offset( const void* context, int8_t* tx_power_offset )
{
const uint8_t cbuffer[LR1121_MODEM_GET_TX_POWER_OFFSET_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_GET_TX_POWER_OFFSET_CMD,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_TX_POWER_OFFSET_CMD_LENGTH, ( uint8_t* ) tx_power_offset, sizeof( int8_t ) );
}
lr1121_modem_response_code_t lr1121_modem_set_tx_power_offset( const void* context, const int8_t tx_power_offset )
{
const uint8_t cbuffer[LR1121_MODEM_SET_TX_POWER_OFFSET_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_SET_TX_POWER_OFFSET_CMD,
( uint8_t ) tx_power_offset,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SET_TX_POWER_OFFSET_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_set_output_power_config(
const void* context, const lr1121_modem_output_power_config_t* output_power_configs,
uint8_t n_output_power_configs )
{
const uint8_t cbuffer[LR1121_MODEM_SET_OUTPUT_POWER_CONFIG_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_SET_OUTPUT_POWER_CONFIG_CMD,
};
// Array of maximal size is allocated
uint8_t dbuffer[LR1121_MODEM_SET_TX_OUTPUT_POWER_CONFIGURATION_DBUFFER_MAX_LENGTH] = { 0 };
for( uint8_t index_power_config = 0; index_power_config < n_output_power_configs; index_power_config++ )
{
const lr1121_modem_output_power_config_t local_power_config = output_power_configs[index_power_config];
const uint8_t local_dbuffer_index = index_power_config * LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH;
dbuffer[local_dbuffer_index] = local_power_config.expected_power;
dbuffer[local_dbuffer_index + 1] = local_power_config.configured_power;
dbuffer[local_dbuffer_index + 2] =
( uint8_t )( ( local_power_config.pa_supply & 0x0F ) | ( local_power_config.pa_sel << 4 ) );
dbuffer[local_dbuffer_index + 3] =
( ( local_power_config.pa_duty_cycle & 0x0F ) << 4 ) | ( local_power_config.pa_hp_sel & 0x0F );
dbuffer[local_dbuffer_index + 4] = ( uint8_t ) local_power_config.pa_ramp_time;
}
const uint8_t dbuffer_size = n_output_power_configs * LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH;
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SET_OUTPUT_POWER_CONFIG_CMD_LENGTH, dbuffer, dbuffer_size );
}
lr1121_modem_response_code_t lr1121_modem_get_output_power_config(
const void* context, lr1121_modem_output_power_config_list_t output_power_config )
{
uint8_t rbuffer[LR1121_MODEM_MODEM_GET_OUTPUT_POWER_CONFIG_RBUFFER_LENGTH] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_OUTPUT_POWER_CONFIG_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_GET_OUTPUT_POWER_CONFIG_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_OUTPUT_POWER_CONFIG_CMD_LENGTH, rbuffer,
LR1121_MODEM_MODEM_GET_OUTPUT_POWER_CONFIG_RBUFFER_LENGTH );
for( uint8_t i = 0; i < LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS; i++ )
{
const uint8_t local_rbuffer_index = i * LR1121_MODEM_OUTPUT_POWER_CONFIG_BLOCK_LENGTH;
output_power_config[i].expected_power = rbuffer[local_rbuffer_index];
output_power_config[i].configured_power = rbuffer[local_rbuffer_index + 1];
output_power_config[i].pa_supply = ( lr1121_modem_pa_reg_supply_t )( rbuffer[local_rbuffer_index + 2] & 0x0F );
output_power_config[i].pa_sel =
( lr1121_modem_output_power_configuration_pa_sel_t )( ( rbuffer[local_rbuffer_index + 2] >> 4 ) & 0x0F );
output_power_config[i].pa_duty_cycle = ( rbuffer[local_rbuffer_index + 3] & 0xF0 ) >> 4;
output_power_config[i].pa_hp_sel = rbuffer[local_rbuffer_index + 3] & 0x0F;
output_power_config[i].pa_ramp_time = ( lr1121_modem_ramp_time_t )( rbuffer[local_rbuffer_index + 4] );
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_set_rf_output( const void* context,
const lr1121_modem_bsp_radio_pa_selection_t output )
{
const uint8_t cbuffer[LR1121_MODEM_SET_RF_OUTPUT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_SET_RF_OUTPUT_CMD,
( uint8_t ) output,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SET_RF_OUTPUT_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_get_rf_output( const void* context,
const lr1121_modem_bsp_radio_pa_selection_t* output )
{
const uint8_t cbuffer[LR1121_MODEM_GET_RF_OUTPUT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_GET_RF_OUTPUT_CMD,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_RF_OUTPUT_CMD_LENGTH, ( uint8_t* ) output, sizeof( uint8_t ) );
}
lr1121_modem_response_code_t lr1121_modem_get_crystal_error( const void* context, uint32_t* crystal_error_ppm )
{
uint8_t rbuffer[sizeof( uint32_t )] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_CRYSTAL_ERROR_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_GET_CRYSTAL_ERROR_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_CRYSTAL_ERROR_CMD_LENGTH, rbuffer, sizeof( uint32_t ) );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
*crystal_error_ppm = ( ( uint32_t ) rbuffer[0] << 24 ) + ( ( uint32_t ) rbuffer[1] << 16 ) +
( ( uint32_t ) rbuffer[2] << 8 ) + ( ( uint32_t ) rbuffer[3] );
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_set_crystal_error( const void* context, const uint32_t crystal_error_ppm )
{
const uint8_t cbuffer[LR1121_MODEM_SET_CRYSTAL_ERROR_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_SET_CRYSTAL_ERROR_CMD,
( uint8_t )( crystal_error_ppm >> 24 ),
( uint8_t )( crystal_error_ppm >> 16 ),
( uint8_t )( crystal_error_ppm >> 8 ),
( uint8_t ) crystal_error_ppm,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SET_CRYSTAL_ERROR_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_get_xosc_capa_trim_a_b( const void* context, uint8_t* capa_trim_a,
uint8_t* capa_trim_b )
{
uint8_t rbuffer[sizeof( uint16_t )] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_XOSC_CAPA_TRIM_A_B_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_GET_XOSC_CAPA_TRIM_A_B,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_XOSC_CAPA_TRIM_A_B_CMD_LENGTH, rbuffer, sizeof( uint16_t ) );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
*capa_trim_a = rbuffer[0];
*capa_trim_b = rbuffer[1];
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_set_xosc_capa_trim_a_b( const void* context, const uint8_t capa_trim_a,
const uint8_t capa_trim_b )
{
const uint8_t cbuffer[LR1121_MODEM_SET_XOSC_CAPA_TRIM_A_B_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_BSP >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_BSP,
LR1121_MODEM_SET_XOSC_CAPA_TRIM_A_B,
capa_trim_a,
capa_trim_b,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SET_XOSC_CAPA_TRIM_A_B_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_get_tx_power_consumption_ua(
const void* context, lr1121_modem_tx_power_consumption_list_t consumption_per_power )
{
const uint8_t cbuffer[LR1121_MODEM_GET_TX_POWER_CONSUMPTION_UA_CMD_LENGTH] = {
( LR1121_MODEM_GROUP_ID_BSP >> 8 ) & 0xFF,
LR1121_MODEM_GROUP_ID_BSP & 0xFF,
LR1121_MODEM_GET_TX_POWER_CONSUMPTION_UA,
};
uint8_t rbuffer[LR1121_MODEM_GET_TX_POWER_CONSUMPTION_RBUFFER_LENGTH] = { 0 };
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_TX_POWER_CONSUMPTION_UA_CMD_LENGTH, rbuffer,
LR1121_MODEM_GET_TX_POWER_CONSUMPTION_RBUFFER_LENGTH );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
for( uint8_t index_power = 0; index_power < LR1121_MODEM_NB_OUTPUT_POWER_CONFIG_BLOCKS; index_power++ )
{
lr1121_modem_tx_power_consumption_value_t* local_value = &consumption_per_power[index_power];
local_value->tx_power_dbm = rbuffer[index_power * 5];
local_value->consumed_power_ua =
( rbuffer[index_power * 5 + 1] << 24 ) + ( rbuffer[index_power * 5 + 2] << 16 ) +
( rbuffer[index_power * 5 + 3] << 8 ) + ( rbuffer[index_power * 5 + 4] << 0 );
}
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_set_tx_power_consumption_ua(
const void* context, const lr1121_modem_tx_power_consumption_value_t* consumption_per_power,
uint8_t n_consumption_per_power )
{
const uint8_t cbuffer[LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA_CMD_LENGTH] = {
( LR1121_MODEM_GROUP_ID_BSP >> 8 ) & 0xFF,
LR1121_MODEM_GROUP_ID_BSP & 0xFF,
LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA,
};
// Array of maximal size is allocated
uint8_t dbuffer[LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA_DBUFFER_MAX_LENGTH] = { 0 };
for( uint8_t power_table_index = 0; power_table_index < n_consumption_per_power; power_table_index++ )
{
const lr1121_modem_tx_power_consumption_value_t local_consumption_value =
consumption_per_power[power_table_index];
const uint8_t local_dbuffer_index = power_table_index * LR1121_MODEM_TX_POWER_CONSUMPTION_SIZE_BYTE;
dbuffer[local_dbuffer_index] = local_consumption_value.tx_power_dbm;
dbuffer[local_dbuffer_index + 1] = ( uint8_t )( local_consumption_value.consumed_power_ua >> 24 );
dbuffer[local_dbuffer_index + 2] = ( uint8_t )( local_consumption_value.consumed_power_ua >> 16 );
dbuffer[local_dbuffer_index + 3] = ( uint8_t )( local_consumption_value.consumed_power_ua >> 8 );
dbuffer[local_dbuffer_index + 4] = ( uint8_t ) local_consumption_value.consumed_power_ua;
}
// Number of meaningful bytes from dbuffer to transmit to the chip
const uint8_t dbuffer_size = n_consumption_per_power * LR1121_MODEM_TX_POWER_CONSUMPTION_SIZE_BYTE;
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SET_TX_POWER_CONSUMPTION_UA_CMD_LENGTH, dbuffer, dbuffer_size );
}
lr1121_modem_response_code_t lr1121_modem_get_lora_rx_power_consumption_ua(
const void* context, lr1121_modem_rx_power_consumption_t* rx_consumption )
{
return lr1121_modem_get_rx_power_consumption_ua( context, rx_consumption,
LR1121_MODEM_GET_LORA_RX_POWER_CONSUMPTION_UA );
}
lr1121_modem_response_code_t lr1121_modem_set_lora_rx_power_consumption_ua(
const void* context, const lr1121_modem_rx_power_consumption_t* rx_consumption )
{
return lr1121_modem_set_rx_power_consumption_ua( context, rx_consumption,
LR1121_MODEM_SET_LORA_RX_POWER_CONSUMPTION_UA );
}
lr1121_modem_response_code_t lr1121_modem_get_gfsk_rx_power_consumption_ua(
const void* context, lr1121_modem_rx_power_consumption_t* rx_consumption )
{
return lr1121_modem_get_rx_power_consumption_ua( context, rx_consumption,
LR1121_MODEM_GET_GFSK_RX_POWER_CONSUMPTION_UA );
}
lr1121_modem_response_code_t lr1121_modem_set_gfsk_rx_power_consumption_ua(
const void* context, const lr1121_modem_rx_power_consumption_t* rx_consumption )
{
return lr1121_modem_set_rx_power_consumption_ua( context, rx_consumption,
LR1121_MODEM_SET_GFSK_RX_POWER_CONSUMPTION_UA );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
uint32_t lr1121_uint8_to_uint32( const uint8_t value[4] )
{
return ( ( ( uint32_t ) value[0] ) << 24 ) + ( ( ( uint32_t ) value[1] ) << 16 ) +
( ( ( uint32_t ) value[2] ) << 8 ) + ( ( ( uint32_t ) value[3] ) );
}
lr1121_modem_response_code_t lr1121_modem_get_rx_power_consumption_ua(
const void* context, lr1121_modem_rx_power_consumption_t* rx_consumption, uint8_t opcode )
{
const uint8_t cbuffer[LR1121_MODEM_GET_RX_POWER_CONSUMPTION_UA_CMD_LENGTH] = {
( LR1121_MODEM_GROUP_ID_BSP >> 8 ) & 0xFF,
LR1121_MODEM_GROUP_ID_BSP & 0xFF,
opcode,
};
uint8_t rbuffer[LR1121_MODEM_GET_RX_POWER_CONSUMPTION_RBUFFER_LENGTH] = { 0 };
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_RX_POWER_CONSUMPTION_UA_CMD_LENGTH, rbuffer,
LR1121_MODEM_GET_RX_POWER_CONSUMPTION_RBUFFER_LENGTH );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
rx_consumption->consumption_rx_boosted_off_ua = lr1121_uint8_to_uint32( rbuffer );
rx_consumption->consumption_rx_boosted_on_ua = lr1121_uint8_to_uint32( rbuffer + 4 );
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_set_rx_power_consumption_ua(
const void* context, const lr1121_modem_rx_power_consumption_t* rx_consumption, uint8_t opcode )
{
const uint8_t cbuffer[LR1121_MODEM_SET_RX_POWER_CONSUMPTION_UA_CMD_LENGTH] = {
( LR1121_MODEM_GROUP_ID_BSP >> 8 ) & 0xFF,
LR1121_MODEM_GROUP_ID_BSP & 0xFF,
opcode,
( uint8_t )( rx_consumption->consumption_rx_boosted_off_ua >> 24 ),
( uint8_t )( rx_consumption->consumption_rx_boosted_off_ua >> 16 ),
( uint8_t )( rx_consumption->consumption_rx_boosted_off_ua >> 8 ),
( uint8_t ) rx_consumption->consumption_rx_boosted_off_ua,
( uint8_t )( rx_consumption->consumption_rx_boosted_on_ua >> 24 ),
( uint8_t )( rx_consumption->consumption_rx_boosted_on_ua >> 16 ),
( uint8_t )( rx_consumption->consumption_rx_boosted_on_ua >> 8 ),
( uint8_t ) rx_consumption->consumption_rx_boosted_on_ua,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SET_RX_POWER_CONSUMPTION_UA_CMD_LENGTH, 0, 0 );
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,83 @@
/**
* @file lr1121_modem_driver_version.c
*
* @brief Implementation of the get version function
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_driver_version.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
const char* lr1121_modem_driver_version_get_version_string( void )
{
return ( const char* ) LR1121_MODEM_DRIVER_VERSION;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,170 @@
/*!
* @file lr1121_modem_helper.c
*
* @brief helper functions implementation for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_helper.h"
#include "lr1121_modem_common.h"
#include "lr1121_modem_modem.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_helper_status_t lr1121_modem_helper_get_event_data( const void* context,
lr1121_modem_event_t* modem_event )
{
lr1121_modem_helper_status_t status = LR1121_MODEM_HELPER_STATUS_ERROR;
lr1121_modem_event_fields_t event_fields = { 0 };
const lr1121_modem_response_code_t modem_response_code = lr1121_modem_get_event( context, &event_fields );
if( modem_response_code == LR1121_MODEM_RESPONSE_CODE_OK )
{
status = LR1121_MODEM_HELPER_STATUS_OK;
modem_event->event_type = event_fields.event_type;
modem_event->missed_events = event_fields.missed_events_count;
switch( modem_event->event_type )
{
case LR1121_MODEM_LORAWAN_EVENT_RESET:
modem_event->event_data.reset.count = event_fields.data;
break;
case LR1121_MODEM_LORAWAN_EVENT_TX_DONE:
modem_event->event_data.txdone.status = ( lr1121_modem_tx_done_event_t )( event_fields.data >> 8 );
break;
case LR1121_MODEM_LORAWAN_EVENT_LINK_CHECK:
modem_event->event_data.link_check.status = ( lr1121_modem_link_check_event_t )( event_fields.data >> 8 );
break;
case LR1121_MODEM_LORAWAN_EVENT_LORAWAN_MAC_TIME:
modem_event->event_data.mac_time.status = ( lr1121_modem_mac_time_event_t )( event_fields.data >> 8 );
break;
case LR1121_MODEM_LORAWAN_EVENT_CLASS_B_PING_SLOT_INFO:
modem_event->event_data.ping_slot_info.status =
( lr1121_modem_class_b_ping_slot_info_t )( event_fields.data >> 8 );
break;
case LR1121_MODEM_LORAWAN_EVENT_CLASS_B_STATUS:
modem_event->event_data.ping_slot_status.status =
( lr1121_modem_class_b_ping_slot_status_t )( event_fields.data >> 8 );
break;
case LR1121_MODEM_LORAWAN_EVENT_NEW_MULTICAST_SESSION_CLASS_C:
{
modem_event->event_data.new_multicast_class_c_groupid.mc_group_id = ( uint8_t )( event_fields.data >> 8 );
break;
}
case LR1121_MODEM_LORAWAN_EVENT_NEW_MULTICAST_SESSION_CLASS_B:
{
modem_event->event_data.new_multicast_class_b_groupid.mc_group_id = ( uint8_t )( event_fields.data >> 8 );
break;
}
case LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_DYNAMIC:
{
modem_event->event_data.relay_tx_dynamic_status.status =
( lr1121_modem_relay_tx_dynamic_status_t )( event_fields.data >> 8 );
break;
}
case LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_MODE:
{
modem_event->event_data.relay_tx_mode_status.status =
( lr1121_modem_relay_tx_mode_status_t )( event_fields.data >> 8 );
break;
}
case LR1121_MODEM_LORAWAN_EVENT_RELAY_TX_SYNC:
{
modem_event->event_data.relay_tx_sync_status.status =
( lr1121_modem_relay_tx_sync_status_t )( event_fields.data >> 8 );
break;
}
case LR1121_MODEM_LORAWAN_EVENT_FUOTA_DONE:
{
modem_event->event_data.fuota_status.status =
( lr1121_modem_fuota_status_t )( event_fields.data >> 8 ) & 0x00FF;
break;
}
case LR1121_MODEM_LORAWAN_EVENT_TEST_MODE:
{
modem_event->event_data.test_mode_status.status =
( lr1121_modem_test_mode_status_t )( event_fields.data >> 8 ) & 0x00FF;
break;
}
case LR1121_MODEM_LORAWAN_EVENT_REGIONAL_DUTY_CYCLE:
{
modem_event->event_data.regional_duty_cycle_status.status =
( lr1121_modem_regional_duty_cycle_status_t )( ( uint8_t )( event_fields.data >> 8 ) );
break;
}
default:
break;
}
}
return status;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
/* --- EOF ------------------------------------------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,226 @@
/*!
* @file lr1121_modem_lr_fhss.c
*
* @brief LR_FHSS driver implementation for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_lr_fhss.h"
#include "lr1121_modem_hal.h"
#include "lr1121_modem_radio.h"
#include "lr1121_modem_radio_types.h"
#include "lr_fhss_v1_base_types.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
#define LR1121_MODEM_LR_FHSS_BUILD_FRAME_LENGTH ( 2 + 9 )
#define LR1121_MODEM_LR_FHSS_HEADER_BITS ( 114 )
#define LR1121_MODEM_LR_FHSS_FRAG_BITS ( 48 )
#define LR1121_MODEM_LR_FHSS_BLOCK_PREAMBLE_BITS ( 2 )
#define LR1121_MODEM_LR_FHSS_BLOCK_BITS ( LR1121_MODEM_LR_FHSS_FRAG_BITS + LR1121_MODEM_LR_FHSS_BLOCK_PREAMBLE_BITS )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for radio-related operations
*/
enum
{
LR1121_MODEM_LR_FHSS_BUILD_FRAME_OC = 0x022C,
};
/*!
* @brief Hopping enable/disabled enumerations for \ref lr1121_modem_lr_fhss_build_frame
*/
typedef enum
{
LR1121_MODEM_LR_FHSS_HOPPING_DISABLE = 0x00,
LR1121_MODEM_LR_FHSS_HOPPING_ENABLE = 0x01,
} lr1121_modem_lr_fhss_hopping_configuration_t;
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Get the bit count and block count for a LR-FHSS frame
*
* @param [in] params Parameter structure
* @param [in] payload_length Length of physical payload, in bytes
*
* @returns Length of physical payload, in bits
*/
static uint16_t lr1121_modem_lr_fhss_get_nb_bits( const lr_fhss_v1_params_t* params, uint16_t payload_length );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_response_code_t lr1121_modem_lr_fhss_init( const void* context )
{
const lr1121_modem_response_code_t set_packet_type_status =
lr1121_modem_radio_set_pkt_type( context, LR1121_MODEM_RADIO_PKT_TYPE_LR_FHSS );
if( set_packet_type_status != LR1121_MODEM_RESPONSE_CODE_OK )
{
return set_packet_type_status;
}
const lr1121_modem_radio_mod_params_lr_fhss_t mod_lr_fhss = {
.br_in_bps = LR1121_MODEM_RADIO_LR_FHSS_BITRATE_488_BPS,
.pulse_shape = LR1121_MODEM_RADIO_LR_FHSS_PULSE_SHAPE_BT_1,
};
const lr1121_modem_response_code_t set_modulation_param_status =
lr1121_modem_radio_set_lr_fhss_mod_params( context, &mod_lr_fhss );
return set_modulation_param_status;
}
uint16_t lr1121_modem_lr_fhss_get_bit_delay_in_us( const lr1121_modem_lr_fhss_params_t* params,
uint16_t payload_length )
{
const uint16_t nb_bits = lr1121_modem_lr_fhss_get_nb_bits( &( params->lr_fhss_params ), payload_length );
const uint8_t nb_padding_bits = 1 + ( ( 32768 - nb_bits ) & 0x07 );
return 1600 + nb_padding_bits * 2048;
}
lr1121_modem_response_code_t lr1121_modem_lr_fhss_build_frame( const void* context,
const lr1121_modem_lr_fhss_params_t* lr_fhss_params,
uint16_t hop_sequence_id, const uint8_t* payload,
uint8_t payload_length )
{
// Since the build_frame command is last, it is possible to check status through stat1
lr1121_modem_response_code_t status =
lr1121_modem_radio_set_lr_fhss_sync_word( context, lr_fhss_params->lr_fhss_params.sync_word );
if( status != LR1121_MODEM_RESPONSE_CODE_OK )
{
return status;
}
const uint8_t cbuffer[LR1121_MODEM_LR_FHSS_BUILD_FRAME_LENGTH] = {
( uint8_t )( LR1121_MODEM_LR_FHSS_BUILD_FRAME_OC >> 8 ),
( uint8_t )( LR1121_MODEM_LR_FHSS_BUILD_FRAME_OC >> 0 ),
( uint8_t ) lr_fhss_params->lr_fhss_params.header_count,
( uint8_t ) lr_fhss_params->lr_fhss_params.cr,
( uint8_t ) lr_fhss_params->lr_fhss_params.modulation_type,
( uint8_t ) lr_fhss_params->lr_fhss_params.grid,
( uint8_t )( lr_fhss_params->lr_fhss_params.enable_hopping ? LR1121_MODEM_LR_FHSS_HOPPING_ENABLE
: LR1121_MODEM_LR_FHSS_HOPPING_DISABLE ),
( uint8_t ) lr_fhss_params->lr_fhss_params.bw,
( uint8_t )( hop_sequence_id >> 8 ),
( uint8_t )( hop_sequence_id >> 0 ),
( uint8_t ) lr_fhss_params->device_offset,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_LR_FHSS_BUILD_FRAME_LENGTH, payload, payload_length );
}
uint32_t lr1121_modem_lr_fhss_get_time_on_air_in_ms( const lr1121_modem_lr_fhss_params_t* params,
uint16_t payload_length )
{
// Multiply by 1000 / 488.28125, or equivalently 256/125, rounding up
return ( ( lr1121_modem_lr_fhss_get_nb_bits( &params->lr_fhss_params, payload_length ) << 8 ) + 124 ) / 125;
}
unsigned int lr1121_modem_lr_fhss_get_hop_sequence_count( const lr1121_modem_lr_fhss_params_t* lr_fhss_params )
{
if( ( lr_fhss_params->lr_fhss_params.grid == LR_FHSS_V1_GRID_25391_HZ ) ||
( ( lr_fhss_params->lr_fhss_params.grid == LR_FHSS_V1_GRID_3906_HZ ) &&
( lr_fhss_params->lr_fhss_params.bw < LR_FHSS_V1_BW_335938_HZ ) ) )
{
return 384;
}
return 512;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION ---------------------------------------------
*/
uint16_t lr1121_modem_lr_fhss_get_nb_bits( const lr_fhss_v1_params_t* params, uint16_t payload_length )
{
uint16_t length_bits = ( payload_length + 2 ) * 8 + 6;
switch( params->cr )
{
case LR_FHSS_V1_CR_5_6:
length_bits = ( ( length_bits * 6 ) + 4 ) / 5;
break;
case LR_FHSS_V1_CR_2_3:
length_bits = length_bits * 3 / 2;
break;
case LR_FHSS_V1_CR_1_2:
length_bits = length_bits * 2;
break;
case LR_FHSS_V1_CR_1_3:
length_bits = length_bits * 3;
break;
}
uint16_t payload_bits = ( length_bits / LR1121_MODEM_LR_FHSS_FRAG_BITS ) * LR1121_MODEM_LR_FHSS_BLOCK_BITS;
uint16_t last_block_bits = length_bits % LR1121_MODEM_LR_FHSS_FRAG_BITS;
if( last_block_bits > 0 )
{
payload_bits += last_block_bits + 2;
}
return LR1121_MODEM_LR_FHSS_HEADER_BITS * params->header_count + payload_bits;
}

View File

@@ -0,0 +1,672 @@
/*!
* @file lr1121_modem_modem.c
*
* @brief modem driver implementation for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_modem.h"
#include "lr1121_modem_common.h"
#include "lr1121_modem_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR1121_MODEM_FACTORY_RESET_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_VERSION_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_STATUS_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_CHARGE_CMD_LENGTH ( 3 )
#define LR1121_MODEM_RESET_CHARGE_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_EVENT_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_SUSPEND_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_GET_SUSPEND_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SET_ALARM_TIMER_CMD_LENGTH ( 3 + 4 )
#define LR1121_MODEM_CLEAR_ALARM_TIMER_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_ALARM_REMAINING_TIME_CMD_LENGTH ( 3 )
#define LR1121_MODEM_GET_CRASHLOG_CMD_LENGTH ( 3 )
#define LR1121_MODEM_TEST_MODE_TST_START_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_TEST_MODE_TST_NOP_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_TEST_MODE_TST_TX_LORA_CMD_LENGTH ( 3 + 25 )
#define LR1121_MODEM_TEST_MODE_TST_TX_FSK_CMD_LENGTH ( 3 + 15 )
#define LR1121_MODEM_TEST_MODE_TST_TX_LR_FHSS_CMD_LENGTH ( 3 + 19 )
#define LR1121_MODEM_TEST_MODE_TST_TX_CONT_CMD_LENGTH ( 3 + 10 )
#define LR1121_MODEM_TEST_MODE_TST_CW_CMD_LENGTH ( 3 + 6 )
#define LR1121_MODEM_TEST_MODE_TST_RX_LORA_CONT_CMD_LENGTH ( 3 + 8 )
#define LR1121_MODEM_TEST_MODE_TST_RX_FSK_CONT_CMD_LENGTH ( 3 + 5 )
#define LR1121_MODEM_TEST_MODE_TST_READ_PKT_COUNTER_RX_CONT_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_TEST_MODE_TST_RSSI_SUBGHZ_CMD_LENGTH ( 3 + 11 )
#define LR1121_MODEM_TEST_MODE_TST_RADIO_RST_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_TEST_MODE_TST_EXIT_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_TEST_MODE_TST_TX_SINGLE_PREAM_CMD_LENGTH ( 3 + 12 )
#define LR1121_MODEM_TEST_MODE_READ_RSSI_CMD_LENGTH ( 3 + 1 )
#define LR1121_MODEM_GET_CHARGE_RBUFFER_LENGTH ( 320 )
#define LR1121_MODEM_GET_CRASHLOG_RBUFFER_LENGTH ( 243 )
#define LR1121_MODEM_GET_VERSION_RBUFFER_LENGTH ( 9 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operation code command
*/
enum
{
LR1121_MODEM_FACTORY_RESET_CMD = 0x00,
LR1121_MODEM_GET_VERSION_CMD = 0x01,
LR1121_MODEM_GET_STATUS_CMD = 0x02,
LR1121_MODEM_GET_CHARGE_CMD = 0x03,
LR1121_MODEM_GET_EVENT_CMD = 0x04,
LR1121_MODEM_TEST_CMD = 0x05,
LR1121_MODEM_GET_SUSPEND_MODEM_COM_CMD = 0x06,
LR1121_MODEM_SET_SUSPEND_MODEM_COM_CMD = 0x07,
LR1121_MODEM_SET_ALARM_TIMER_CMD = 0x08,
LR1121_MODEM_CLEAR_ALARM_TIMER_CMD = 0x09,
LR1121_MODEM_GET_ALARM_REMAINING_TIME_CMD = 0x0A,
LR1121_MODEM_GET_CRASHLOG_CMD = 0x0B,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*!
* @brief Radio test mode type
*/
typedef enum
{
LR1121_MODEM_TEST_MODE_TST_START = 0x00,
LR1121_MODEM_TEST_MODE_TST_EXIT = 0x01,
LR1121_MODEM_TEST_MODE_TST_NOP = 0x02,
LR1121_MODEM_TEST_MODE_TST_TX_LORA = 0x03,
LR1121_MODEM_TEST_MODE_TST_TX_FSK = 0x04,
LR1121_MODEM_TEST_MODE_TST_TX_LR_FHSS = 0x05,
LR1121_MODEM_TEST_MODE_TST_TX_CW = 0x06,
LR1121_MODEM_TEST_MODE_TST_RX_LORA_CONT = 0x07,
LR1121_MODEM_TEST_MODE_TST_RX_FSK_CONT = 0x08,
LR1121_MODEM_TEST_MODE_TST_READ_RX_PKT_COUNTER_RX_CONT = 0x09,
LR1121_MODEM_TEST_MODE_TST_RSSI_SUBGHZ = 0x0A,
LR1121_MODEM_TEST_MODE_READ_RSSI = 0x0B,
LR1121_MODEM_TEST_MODE_TST_RADIO_RST = 0x0E,
LR1121_MODEM_TEST_MODE_TST_READ_REGISTER = 0x0F,
LR1121_MODEM_TEST_MODE_TST_WRITE_REGISTER = 0x10,
} lr1121_modem_test_mode_t;
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Helper function that convert an array of uint8_t into a uint32_t single value
*
* @warning It is up to the caller to ensure that value points to an array of at least sizeof(uint32_t) elements.
*
* @param [in] value Array of uint8_t to be translated into a uint32_t
*
* @returns 32-bit value
*/
static uint32_t lr1121_uint8_to_uint32( const uint8_t value[4] );
static void lr1121_parse_charge_hook_id( const uint8_t* buffer, uint8_t hook_id, lr1121_modem_consumption_details_t* hook );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_response_code_t lr1121_modem_factory_reset( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_FACTORY_RESET_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_FACTORY_RESET_CMD,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write_without_rc(
context, cbuffer, LR1121_MODEM_FACTORY_RESET_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_get_modem_version( const void* context,
lr1121_modem_version_t* modem_version )
{
uint8_t rbuffer[LR1121_MODEM_GET_VERSION_RBUFFER_LENGTH] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_VERSION_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_VERSION_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_VERSION_CMD_LENGTH, rbuffer, LR1121_MODEM_GET_VERSION_RBUFFER_LENGTH );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
modem_version->use_case = rbuffer[0];
modem_version->modem_major = rbuffer[1];
modem_version->modem_minor = rbuffer[2];
modem_version->modem_patch = rbuffer[3];
modem_version->lbm_major = rbuffer[5];
modem_version->lbm_minor = rbuffer[6];
modem_version->lbm_patch = rbuffer[7];
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_get_status( const void* context,
lr1121_modem_lorawan_status_bitmask_t* status )
{
const uint8_t cbuffer[LR1121_MODEM_GET_STATUS_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_STATUS_CMD,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read( context, cbuffer, LR1121_MODEM_GET_STATUS_CMD_LENGTH,
( uint8_t* ) status, sizeof( uint8_t ) );
}
lr1121_modem_response_code_t lr1121_modem_get_charge( const void* context, lr1121_modem_charge_t* charge )
{
uint8_t rbuffer[LR1121_MODEM_GET_CHARGE_RBUFFER_LENGTH] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_CHARGE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_CHARGE_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_CHARGE_CMD_LENGTH, rbuffer, LR1121_MODEM_GET_CHARGE_RBUFFER_LENGTH );
lr1121_parse_charge_hook_id( rbuffer, 0, &charge->suspend );
lr1121_parse_charge_hook_id( rbuffer, 1, &charge->class_b_beacon );
lr1121_parse_charge_hook_id( rbuffer, 2, &charge->lr1mac_stack );
lr1121_parse_charge_hook_id( rbuffer, 3, &charge->lbt );
lr1121_parse_charge_hook_id( rbuffer, 4, &charge->cad );
lr1121_parse_charge_hook_id( rbuffer, 5, &charge->class_b_ping_slot );
lr1121_parse_charge_hook_id( rbuffer, 6, &charge->test_mode );
lr1121_parse_charge_hook_id( rbuffer, 7, &charge->direct_rp_access );
lr1121_parse_charge_hook_id( rbuffer, 8, &charge->relay_tx );
lr1121_parse_charge_hook_id( rbuffer, 9, &charge->class_c );
return rc;
}
lr1121_modem_response_code_t lr1121_modem_get_event( const void* context, lr1121_modem_event_fields_t* event_fields )
{
uint8_t rbuffer[sizeof( uint32_t )] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_EVENT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_EVENT_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_EVENT_CMD_LENGTH, rbuffer, sizeof( uint32_t ) );
event_fields->event_type = ( lr1121_modem_lorawan_event_type_t ) rbuffer[0];
event_fields->missed_events_count = rbuffer[1];
event_fields->data = ( ( uint16_t ) rbuffer[2] << 8 ) + ( ( uint16_t ) rbuffer[3] );
return rc;
}
lr1121_modem_response_code_t lr1121_modem_set_suspend( const void* context, const lr1121_modem_suspend_t suspend )
{
const uint8_t cbuffer[LR1121_MODEM_SET_SUSPEND_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_SET_SUSPEND_MODEM_COM_CMD,
suspend,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SET_SUSPEND_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_get_suspend( const void* context, lr1121_modem_suspend_t* suspend )
{
const uint8_t cbuffer[LR1121_MODEM_GET_SUSPEND_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_SUSPEND_MODEM_COM_CMD,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_SUSPEND_CMD_LENGTH, ( uint8_t* ) suspend, sizeof( uint8_t ) );
}
lr1121_modem_response_code_t lr1121_modem_set_alarm_timer( const void* context, uint32_t seconds )
{
const uint8_t cbuffer[LR1121_MODEM_SET_ALARM_TIMER_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_SET_ALARM_TIMER_CMD,
( uint8_t )( seconds >> 24 ),
( uint8_t )( seconds >> 16 ),
( uint8_t )( seconds >> 8 ),
( uint8_t ) seconds,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SET_ALARM_TIMER_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_clear_alarm_timer( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_CLEAR_ALARM_TIMER_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_CLEAR_ALARM_TIMER_CMD,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_CLEAR_ALARM_TIMER_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_get_alarm_remaining_time( const void* context, uint32_t* remaining_time )
{
uint8_t rbuffer[sizeof( uint32_t )] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_ALARM_REMAINING_TIME_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_ALARM_REMAINING_TIME_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_ALARM_REMAINING_TIME_CMD_LENGTH, rbuffer, sizeof( uint32_t ) );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
*remaining_time = ( ( uint32_t ) rbuffer[0] << 24 ) + ( ( uint32_t ) rbuffer[1] << 16 ) +
( ( uint32_t ) rbuffer[2] << 8 ) + ( ( uint32_t ) rbuffer[3] );
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_get_crashlog( const void* context, lr1121_modem_crashlog_status_t* status,
uint8_t* crashlog )
{
uint8_t rbuffer[LR1121_MODEM_GET_CRASHLOG_RBUFFER_LENGTH] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_GET_CRASHLOG_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_GET_CRASHLOG_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_GET_CRASHLOG_CMD_LENGTH, rbuffer, LR1121_MODEM_GET_CRASHLOG_RBUFFER_LENGTH );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
*status = ( lr1121_modem_crashlog_status_t ) rbuffer[0];
for( uint8_t i = 0; i < LR1121_MODEM_GET_CRASHLOG_RBUFFER_LENGTH - 1; i++ )
{
crashlog[i] = rbuffer[1 + i];
}
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_test_mode_start( const void* context )
{
const uint8_t test_msg[8] = { 'T', 'E', 'S', 'T', 'T', 'E', 'S', 'T' };
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_START_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_START,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_START_CMD_LENGTH, test_msg, 8 );
}
lr1121_modem_response_code_t lr1121_modem_test_exit( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_EXIT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_EXIT,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_TEST_MODE_TST_EXIT_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_nop( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_NOP_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_NOP,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_TEST_MODE_TST_NOP_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_tx_lora(
const void* context, uint32_t frequency, int8_t tx_power, uint8_t payload_length,
lr1121_modem_tst_mode_lora_sf_t sf, lr1121_modem_tst_mode_lora_bw_t bw, lr1121_modem_tst_mode_lora_cr_t cr,
bool is_iq_inverted, bool is_crc_enabled, lr1121_modem_tst_mode_lora_packet_header_mode_t header_mode,
uint32_t preamble_length, uint32_t number_of_tx, uint32_t delay_ms )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_TX_LORA_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_TX_LORA,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
( uint8_t ) tx_power,
payload_length,
( uint8_t ) sf,
( uint8_t ) bw,
( uint8_t ) cr,
( uint8_t )( is_iq_inverted ? 0x01 : 0x00 ),
( uint8_t )( is_crc_enabled ? 0x01 : 0x00 ),
( uint8_t ) header_mode,
( uint8_t )( preamble_length >> 24 ),
( uint8_t )( preamble_length >> 16 ),
( uint8_t )( preamble_length >> 8 ),
( uint8_t ) preamble_length,
( uint8_t )( number_of_tx >> 24 ),
( uint8_t )( number_of_tx >> 16 ),
( uint8_t )( number_of_tx >> 8 ),
( uint8_t ) number_of_tx,
( uint8_t )( delay_ms >> 24 ),
( uint8_t )( delay_ms >> 16 ),
( uint8_t )( delay_ms >> 8 ),
( uint8_t ) delay_ms,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_TX_LORA_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_tx_fsk( const void* context, uint32_t frequency, int8_t tx_power,
uint8_t payload_length, uint32_t number_of_tx,
uint32_t delay_ms )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_TX_FSK_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_TX_FSK,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
( uint8_t ) tx_power,
payload_length,
( uint8_t )( number_of_tx >> 24 ),
( uint8_t )( number_of_tx >> 16 ),
( uint8_t )( number_of_tx >> 8 ),
( uint8_t ) number_of_tx,
( uint8_t )( delay_ms >> 24 ),
( uint8_t )( delay_ms >> 16 ),
( uint8_t )( delay_ms >> 8 ),
( uint8_t ) delay_ms,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_TX_FSK_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_tx_lr_fhss( const void* context, uint32_t frequency, int8_t tx_power,
uint8_t payload_length,
lr1121_modem_tst_mode_lr_fhss_grid_t grid,
lr1121_modem_tst_mode_lr_fhss_bw_t bw,
lr1121_modem_tst_mode_lr_fhss_cr_t cr, uint32_t number_of_tx,
uint32_t delay_ms, bool is_hopping_enabled )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_TX_LR_FHSS_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_TX_LR_FHSS,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
( uint8_t ) tx_power,
payload_length,
( uint8_t ) grid,
( uint8_t ) bw,
( uint8_t ) cr,
( uint8_t )( number_of_tx >> 24 ),
( uint8_t )( number_of_tx >> 16 ),
( uint8_t )( number_of_tx >> 8 ),
( uint8_t ) number_of_tx,
( uint8_t )( delay_ms >> 24 ),
( uint8_t )( delay_ms >> 16 ),
( uint8_t )( delay_ms >> 8 ),
( uint8_t ) delay_ms,
is_hopping_enabled ? 0x01 : 0x00,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_TX_LR_FHSS_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_tx_cw( const void* context, uint32_t frequency, int8_t tx_power )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_CW_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_TX_CW,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
( uint8_t ) tx_power,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_TEST_MODE_TST_CW_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_rx_lora_cont( const void* context, uint32_t frequency,
lr1121_modem_tst_mode_lora_sf_t sf,
lr1121_modem_tst_mode_lora_bw_t bw,
lr1121_modem_tst_mode_lora_cr_t cr )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_RX_LORA_CONT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_RX_LORA_CONT,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
( uint8_t ) sf,
( uint8_t ) bw,
( uint8_t ) cr,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_RX_LORA_CONT_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_rx_fsk_cont( const void* context, uint32_t frequency )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_RX_FSK_CONT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_RX_FSK_CONT,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_RX_FSK_CONT_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_read_packet_counter_rx_cont( const void* context,
uint32_t* rx_packet_counter )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_READ_PKT_COUNTER_RX_CONT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_READ_RX_PKT_COUNTER_RX_CONT,
};
uint8_t rbuffer[sizeof( uint32_t )] = { 0 };
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_READ_PKT_COUNTER_RX_CONT_CMD_LENGTH, rbuffer, sizeof( uint32_t ) );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
*rx_packet_counter = ( ( uint32_t ) rbuffer[0] << 24 ) + ( ( uint32_t ) rbuffer[1] << 16 ) +
( ( uint32_t ) rbuffer[2] << 8 ) + ( ( uint32_t ) rbuffer[3] );
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_test_rssi_subghz( const void* context, uint32_t frequency, uint16_t time_ms,
uint32_t bw_hz )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_RSSI_SUBGHZ_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_RSSI_SUBGHZ,
( uint8_t )( ( frequency & 0xFF000000 ) >> 24 ),
( uint8_t )( ( frequency & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( frequency & 0x0000FF00 ) >> 8 ),
( uint8_t )( frequency & 0x000000FF ),
( uint8_t )( time_ms >> 8 ),
( uint8_t )( time_ms ),
( uint8_t )( ( bw_hz & 0xFF000000 ) >> 24 ),
( uint8_t )( ( bw_hz & 0x00FF0000 ) >> 16 ),
( uint8_t )( ( bw_hz & 0x0000FF00 ) >> 8 ),
( uint8_t )( bw_hz & 0x000000FF ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_RSSI_SUBGHZ_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_test_read_rssi( const void* context, int16_t* rssi )
{
uint8_t rbuffer[sizeof( uint8_t )] = { 0x00 };
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_READ_RSSI_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_READ_RSSI,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_TEST_MODE_READ_RSSI_CMD_LENGTH, rbuffer, sizeof( uint8_t ) );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
*rssi = ( int16_t )( ( int8_t ) rbuffer[0] - 64 );
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_test_radio_rst( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_TEST_MODE_TST_RADIO_RST_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_MODEM >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_MODEM,
LR1121_MODEM_TEST_CMD,
LR1121_MODEM_TEST_MODE_TST_RADIO_RST,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_TEST_MODE_TST_RADIO_RST_CMD_LENGTH, 0, 0 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
uint32_t lr1121_uint8_to_uint32( const uint8_t value[4] )
{
return ( ( ( uint32_t ) value[0] ) << 24 ) + ( ( ( uint32_t ) value[1] ) << 16 ) +
( ( ( uint32_t ) value[2] ) << 8 ) + ( ( ( uint32_t ) value[3] ) );
}
void lr1121_parse_charge_hook_id( const uint8_t* buffer, uint8_t hook_id, lr1121_modem_consumption_details_t* hook )
{
hook->tx_last_toa_ms = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 0 );
hook->rx_last_toa_ms = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 4 );
hook->tx_cumulated_toa_ms = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 8 );
hook->rx_cumulated_toa_ms = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 12 );
hook->none_consumption_ms = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 16 );
hook->tx_consumption_ma = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 20 );
hook->rx_consumption_ma = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 24 );
hook->none_consumption_ma = lr1121_uint8_to_uint32( buffer + 32 * hook_id + 28 );
}
/* --- EOF ------------------------------------------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,234 @@
/**
* @file lr1121_modem_radio_timings.c
*
* @brief LR1121 timing helper functions implementation
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_radio_timings.h"
#include "lr1121_modem_radio.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/**
* @brief Time in microsecond taken by the chip to process the Rx done interrupt
*/
#define RX_DONE_IRQ_PROCESSING_TIME_IN_US 74
/**
* @brief Time in microsecond taken by the chip to process the Tx done interrupt
*/
#define TX_DONE_IRQ_PROCESSING_TIME_IN_US 111
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/**
* @brief Get the power amplifier ramp time for a given power amplifier ramp time parameter
*
* @param [in] ramp_time Power amplifier ramp time parameter
*
* @returns Ramp time in microsecond
*/
static uint32_t lr1121_modem_radio_timings_get_pa_ramp_time_in_us( const lr1121_modem_radio_ramp_time_t ramp_time );
/**
* @brief Get the LoRa reception input delay
*
* @param [in] bw LoRa bandwidth
*
* @returns LoRa reception input delay in microsecond
*/
static uint32_t lr1121_modem_radio_timings_get_lora_rx_input_delay_in_us( lr1121_modem_radio_lora_bw_t bw );
/**
* @brief Get the LoRa symbol time
*
* @param [in] bw LoRa bandwidth
* @param [in] sf LoRa spreading factor
*
* @returns LoRa symbol time in microsecond
*/
static uint32_t lr1121_modem_radio_timings_get_lora_symb_time_in_us( const lr1121_modem_radio_lora_sf_t sf,
const lr1121_modem_radio_lora_bw_t bw );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
uint32_t lr1121_modem_radio_timings_get_delay_between_last_bit_sent_and_rx_done_in_us(
const lr1121_modem_radio_mod_params_lora_t* mod_params )
{
return lr1121_modem_radio_timings_get_lora_rx_input_delay_in_us( mod_params->bw ) +
2 * lr1121_modem_radio_timings_get_lora_symb_time_in_us( mod_params->sf, mod_params->bw ) +
RX_DONE_IRQ_PROCESSING_TIME_IN_US;
}
uint32_t lr1121_modem_radio_timings_get_delay_between_last_bit_sent_and_tx_done_in_us(
const lr1121_modem_radio_ramp_time_t ramp_time )
{
return lr1121_modem_radio_timings_get_pa_ramp_time_in_us( ramp_time ) + TX_DONE_IRQ_PROCESSING_TIME_IN_US;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
static uint32_t lr1121_modem_radio_timings_get_pa_ramp_time_in_us( const lr1121_modem_radio_ramp_time_t ramp_time )
{
switch( ramp_time )
{
case LR1121_MODEM_RADIO_RAMP_16_US:
{
return 16;
}
case LR1121_MODEM_RADIO_RAMP_32_US:
{
return 32;
}
case LR1121_MODEM_RADIO_RAMP_48_US:
{
return 48;
}
case LR1121_MODEM_RADIO_RAMP_64_US:
{
return 64;
}
case LR1121_MODEM_RADIO_RAMP_80_US:
{
return 80;
}
case LR1121_MODEM_RADIO_RAMP_96_US:
{
return 96;
}
case LR1121_MODEM_RADIO_RAMP_112_US:
{
return 112;
}
case LR1121_MODEM_RADIO_RAMP_128_US:
{
return 128;
}
case LR1121_MODEM_RADIO_RAMP_144_US:
{
return 144;
}
case LR1121_MODEM_RADIO_RAMP_160_US:
{
return 160;
}
case LR1121_MODEM_RADIO_RAMP_176_US:
{
return 176;
}
case LR1121_MODEM_RADIO_RAMP_192_US:
{
return 192;
}
case LR1121_MODEM_RADIO_RAMP_208_US:
{
return 208;
}
case LR1121_MODEM_RADIO_RAMP_240_US:
{
return 240;
}
case LR1121_MODEM_RADIO_RAMP_272_US:
{
return 272;
}
case LR1121_MODEM_RADIO_RAMP_304_US:
{
return 304;
}
default:
return 0;
}
}
static uint32_t lr1121_modem_radio_timings_get_lora_rx_input_delay_in_us( lr1121_modem_radio_lora_bw_t bw )
{
switch( bw )
{
case LR1121_MODEM_RADIO_LORA_BW_500:
{
return 16;
}
case LR1121_MODEM_RADIO_LORA_BW_250:
{
return 31;
}
case LR1121_MODEM_RADIO_LORA_BW_125:
{
return 57;
}
default:
{
return 0;
}
}
}
static uint32_t lr1121_modem_radio_timings_get_lora_symb_time_in_us( const lr1121_modem_radio_lora_sf_t sf,
const lr1121_modem_radio_lora_bw_t bw )
{
return ( 1 << ( uint8_t ) sf ) * 1000000 / lr1121_modem_radio_get_lora_bw_in_hz( bw );
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,332 @@
/*!
* @file lr1121_modem_regmem.c
*
* @brief Register/memory driver implementation for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_regmem.h"
#include "lr1121_modem_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR1121_MODEM_REGMEM_CLEAR_RXBUFFER_CMD_LENGTH 2
#define LR1121_MODEM_REGMEM_WRITE_REGMEM32_CMD_LENGTH ( 2 + 4 )
#define LR1121_MODEM_REGMEM_READ_REGMEM32_CMD_LENGTH ( 2 + 4 + 1 )
#define LR1121_MODEM_REGMEM_WRITE_MEM8_CMD_LENGTH ( 2 + 4 )
#define LR1121_MODEM_REGMEM_READ_MEM8_CMD_LENGTH ( 2 + 4 + 1 )
#define LR1121_MODEM_REGMEM_WRITE_BUFFER8_CMD_LENGTH ( 2 )
#define LR1121_MODEM_REGMEM_READ_BUFFER8_CMD_LENGTH ( 2 + 2 )
#define LR1121_MODEM_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH ( 2 + 4 + 4 + 4 )
#define LR1121_MODEM_REGMEM_BUFFER_SIZE_MAX ( 256 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for register and memory related operations
*/
enum
{
LR1121_MODEM_REGMEM_WRITE_REGMEM32_OC = 0x0105,
LR1121_MODEM_REGMEM_READ_REGMEM32_OC = 0x0106,
LR1121_MODEM_REGMEM_WRITE_MEM8_OC = 0x0107,
LR1121_MODEM_REGMEM_READ_MEM8_OC = 0x0108,
LR1121_MODEM_REGMEM_WRITE_BUFFER8_OC = 0x0109,
LR1121_MODEM_REGMEM_READ_BUFFER8_OC = 0x010A,
LR1121_MODEM_REGMEM_CLEAR_RXBUFFER_OC = 0x010B,
LR1121_MODEM_REGMEM_WRITE_REGMEM32_MASK_OC = 0x010C,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Helper function that fill both cbuffer with opcode and memory address
*
* It is typically used in read/write regmem32 functions.
*
* @warning It is up to the caller to ensure cbuffer is big enough to contain opcode and address!
*/
static void lr1121_modem_regmem_fill_cbuffer_opcode_address( uint8_t* cbuffer, uint16_t opcode, uint32_t address );
/*!
* @brief Helper function that fill both cbuffer with opcode memory address, and data length to read
*
* It is typically used in read functions.
*
* @warning It is up to the caller to ensure cbuffer is big enough to contain opcode and address!
*/
static void lr1121_modem_regmem_fill_cbuffer_opcode_address_length( uint8_t* cbuffer, uint16_t opcode, uint32_t address,
uint8_t length );
/*!
* @brief Helper function that fill both cbuffer with data
*
* It is typically used in write write regmem32 functions.
*
* @warning It is up to the caller to ensure cdata is big enough to contain all data!
*/
static void lr1121_modem_regmem_fill_cdata( uint8_t* cdata, const uint32_t* data, uint8_t data_length );
/*!
* @brief Helper function that fill both cbuffer and cdata buffers with opcode, memory address and data
*
* It is typically used to factorize and write regmem32 operations. Behind the scene it calls the other helpers
* lr1121_modem_regmem_fill_cbuffer_opcode_address and lr1121_modem_regmem_fill_cdata.
*
* @warning It is up to the caller to ensure cbuffer and cdata are big enough to contain their respective information!
*/
static void lr1121_modem_regmem_fill_cbuffer_cdata_opcode_address_data( uint8_t* cbuffer, uint8_t* cdata,
uint16_t opcode, uint32_t address,
const uint32_t* data, uint8_t data_length );
/*!
* @brief Helper function that convert an array of uint8_t into an array of uint32_t
*
* Typically used in the read function returning uint32_t array.
*
* @warning It is up to the caller to ensure the raw_buffer is of length at least "out_buffer_length *
* sizeof(uint32_t)"!
*/
static void lr1121_modem_regmem_fill_out_buffer_from_raw_buffer( uint32_t* out_buffer, const uint8_t* raw_buffer,
uint8_t out_buffer_length );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_response_code_t lr1121_modem_regmem_write_regmem32( const void* context, const uint32_t address,
const uint32_t* buffer, const uint8_t length )
{
uint8_t cbuffer[LR1121_MODEM_REGMEM_WRITE_REGMEM32_CMD_LENGTH];
uint8_t cdata[LR1121_MODEM_REGMEM_BUFFER_SIZE_MAX];
if( length > LR1121_MODEM_REGMEM_MAX_WRITE_READ_WORDS )
{
return LR1121_MODEM_RESPONSE_CODE_BAD_SIZE;
}
lr1121_modem_regmem_fill_cbuffer_cdata_opcode_address_data( cbuffer, cdata, LR1121_MODEM_REGMEM_WRITE_REGMEM32_OC,
address, buffer, length );
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_REGMEM_WRITE_REGMEM32_CMD_LENGTH, cdata, length * sizeof( uint32_t ) );
}
lr1121_modem_response_code_t lr1121_modem_regmem_read_regmem32( const void* context, const uint32_t address,
uint32_t* buffer, const uint8_t length )
{
uint8_t cbuffer[LR1121_MODEM_REGMEM_READ_REGMEM32_CMD_LENGTH] = { 0 };
if( length > LR1121_MODEM_REGMEM_MAX_WRITE_READ_WORDS )
{
return LR1121_MODEM_RESPONSE_CODE_BAD_SIZE;
}
lr1121_modem_regmem_fill_cbuffer_opcode_address_length( cbuffer, LR1121_MODEM_REGMEM_READ_REGMEM32_OC, address,
length );
const lr1121_modem_response_code_t status = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_REGMEM_READ_REGMEM32_CMD_LENGTH, ( uint8_t* ) buffer,
length * sizeof( uint32_t ) );
if( status == LR1121_MODEM_RESPONSE_CODE_OK )
{
lr1121_modem_regmem_fill_out_buffer_from_raw_buffer( buffer, ( const uint8_t* ) buffer, length );
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_regmem_write_mem8( const void* context, const uint32_t address,
const uint8_t* buffer, const uint8_t length )
{
uint8_t cbuffer[LR1121_MODEM_REGMEM_WRITE_MEM8_CMD_LENGTH];
lr1121_modem_regmem_fill_cbuffer_opcode_address( cbuffer, LR1121_MODEM_REGMEM_WRITE_MEM8_OC, address );
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_REGMEM_WRITE_MEM8_CMD_LENGTH, buffer, length );
}
lr1121_modem_response_code_t lr1121_modem_regmem_read_mem8( const void* context, const uint32_t address,
uint8_t* buffer, const uint8_t length )
{
uint8_t cbuffer[LR1121_MODEM_REGMEM_READ_MEM8_CMD_LENGTH];
lr1121_modem_regmem_fill_cbuffer_opcode_address_length( cbuffer, LR1121_MODEM_REGMEM_READ_MEM8_OC, address,
length );
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_REGMEM_READ_MEM8_CMD_LENGTH, buffer, length );
}
lr1121_modem_response_code_t lr1121_modem_regmem_write_buffer8( const void* context, const uint8_t* buffer,
const uint8_t length )
{
const uint8_t cbuffer[LR1121_MODEM_REGMEM_WRITE_BUFFER8_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_REGMEM_WRITE_BUFFER8_OC >> 8 ),
( uint8_t )( LR1121_MODEM_REGMEM_WRITE_BUFFER8_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_REGMEM_WRITE_BUFFER8_CMD_LENGTH, buffer, length );
}
lr1121_modem_response_code_t lr1121_modem_regmem_read_buffer8( const void* context, uint8_t* buffer,
const uint8_t offset, const uint8_t length )
{
const uint8_t cbuffer[LR1121_MODEM_REGMEM_READ_BUFFER8_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_REGMEM_READ_BUFFER8_OC >> 8 ),
( uint8_t )( LR1121_MODEM_REGMEM_READ_BUFFER8_OC >> 0 ),
offset,
length,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_REGMEM_READ_BUFFER8_CMD_LENGTH, buffer, length );
}
lr1121_modem_response_code_t lr1121_modem_regmem_clear_rxbuffer( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_REGMEM_CLEAR_RXBUFFER_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_REGMEM_CLEAR_RXBUFFER_OC >> 8 ),
( uint8_t )( LR1121_MODEM_REGMEM_CLEAR_RXBUFFER_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_REGMEM_CLEAR_RXBUFFER_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_regmem_write_regmem32_mask( const void* context, const uint32_t address,
const uint32_t mask, const uint32_t data )
{
uint8_t cbuffer[LR1121_MODEM_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH];
lr1121_modem_regmem_fill_cbuffer_opcode_address( cbuffer, LR1121_MODEM_REGMEM_WRITE_REGMEM32_MASK_OC, address );
cbuffer[6] = ( uint8_t )( mask >> 24 );
cbuffer[7] = ( uint8_t )( mask >> 16 );
cbuffer[8] = ( uint8_t )( mask >> 8 );
cbuffer[9] = ( uint8_t )( mask >> 0 );
cbuffer[10] = ( uint8_t )( data >> 24 );
cbuffer[11] = ( uint8_t )( data >> 16 );
cbuffer[12] = ( uint8_t )( data >> 8 );
cbuffer[13] = ( uint8_t )( data >> 0 );
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH, 0, 0 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
void lr1121_modem_regmem_fill_cbuffer_opcode_address( uint8_t* cbuffer, uint16_t opcode, uint32_t address )
{
cbuffer[0] = ( uint8_t )( opcode >> 8 );
cbuffer[1] = ( uint8_t )( opcode >> 0 );
cbuffer[2] = ( uint8_t )( address >> 24 );
cbuffer[3] = ( uint8_t )( address >> 16 );
cbuffer[4] = ( uint8_t )( address >> 8 );
cbuffer[5] = ( uint8_t )( address >> 0 );
}
void lr1121_modem_regmem_fill_cbuffer_opcode_address_length( uint8_t* cbuffer, uint16_t opcode, uint32_t address,
uint8_t length )
{
lr1121_modem_regmem_fill_cbuffer_opcode_address( cbuffer, opcode, address );
cbuffer[6] = length;
}
void lr1121_modem_regmem_fill_cdata( uint8_t* cdata, const uint32_t* data, uint8_t data_length )
{
for( uint16_t index = 0; index < data_length; index++ )
{
uint8_t* cdata_local = &cdata[index * sizeof( uint32_t )];
cdata_local[0] = ( uint8_t )( data[index] >> 24 );
cdata_local[1] = ( uint8_t )( data[index] >> 16 );
cdata_local[2] = ( uint8_t )( data[index] >> 8 );
cdata_local[3] = ( uint8_t )( data[index] >> 0 );
}
}
void lr1121_modem_regmem_fill_cbuffer_cdata_opcode_address_data( uint8_t* cbuffer, uint8_t* cdata, uint16_t opcode,
uint32_t address, const uint32_t* data,
uint8_t data_length )
{
lr1121_modem_regmem_fill_cbuffer_opcode_address( cbuffer, opcode, address );
lr1121_modem_regmem_fill_cdata( cdata, data, data_length );
}
void lr1121_modem_regmem_fill_out_buffer_from_raw_buffer( uint32_t* out_buffer, const uint8_t* raw_buffer,
uint8_t out_buffer_length )
{
for( uint8_t out_index = 0; out_index < out_buffer_length; out_index++ )
{
const uint8_t* raw_buffer_local = &raw_buffer[out_index * 4];
out_buffer[out_index] = ( ( uint32_t ) raw_buffer_local[0] << 24 ) +
( ( uint32_t ) raw_buffer_local[1] << 16 ) + ( ( uint32_t ) raw_buffer_local[2] << 8 ) +
( ( uint32_t ) raw_buffer_local[3] << 0 );
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,159 @@
/*!
* @file lr1121_modem_relay.c
*
* @brief Relay driver implementation for LR1121 modem
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_relay.h"
#include <stdint.h>
#include "lr1121_modem_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
#define LR1121_MODEM_RELAY_GET_TX_CONFIG_CMD_LENGTH ( 3 )
#define LR1121_MODEM_RELAY_SET_TX_CONFIG_RBUFFER_LENGTH ( 3 + 14 )
#define LR1121_MODEM_RELAY_GET_TX_CONFIG_RBUFFER_LENGTH ( 14 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operation code command
*/
enum
{
LR1121_MODEM_RELAY_GET_TX_CONFIG_CMD = 0x00,
LR1121_MODEM_RELAY_SET_TX_CONFIG_CMD = 0x01,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
static uint32_t lr1121_uint8_to_uint32( const uint8_t value[4] );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_response_code_t lr1121_modem_relay_get_tx_config( const void* context,
lr1121_modem_relay_tx_configuration_t* configuration )
{
uint8_t rbuffer[LR1121_MODEM_RELAY_GET_TX_CONFIG_RBUFFER_LENGTH] = { 0 };
const uint8_t cbuffer[LR1121_MODEM_RELAY_GET_TX_CONFIG_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_RELAY >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_RELAY,
LR1121_MODEM_RELAY_GET_TX_CONFIG_CMD,
};
const lr1121_modem_response_code_t rc = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_RELAY_GET_TX_CONFIG_CMD_LENGTH, rbuffer,
LR1121_MODEM_RELAY_GET_TX_CONFIG_RBUFFER_LENGTH );
if( rc == LR1121_MODEM_RESPONSE_CODE_OK )
{
configuration->wor_second_channel_frequency_hz = lr1121_uint8_to_uint32( rbuffer + 0 );
configuration->wor_ack_second_channel_frequency_hz = lr1121_uint8_to_uint32( rbuffer + 4 );
configuration->wor_second_channel_datarate = rbuffer[8];
configuration->wor_second_channel_enable = rbuffer[9];
configuration->backoff_behavior = rbuffer[10];
configuration->activation = ( lr1121_modem_relay_activation_t ) rbuffer[11];
configuration->smart_level = ( lr1121_modem_relay_smart_level_t ) rbuffer[12];
configuration->missed_ack_to_unsynchronized_threshold = rbuffer[13];
}
return rc;
}
lr1121_modem_response_code_t lr1121_modem_relay_set_tx_config(
const void* context, const lr1121_modem_relay_tx_configuration_t* configuration )
{
const uint8_t cbuffer[LR1121_MODEM_RELAY_SET_TX_CONFIG_RBUFFER_LENGTH] = {
( uint8_t )( LR1121_MODEM_GROUP_ID_RELAY >> 8 ),
( uint8_t ) LR1121_MODEM_GROUP_ID_RELAY,
LR1121_MODEM_RELAY_SET_TX_CONFIG_CMD,
( uint8_t )( configuration->wor_second_channel_frequency_hz >> 24 ),
( uint8_t )( configuration->wor_second_channel_frequency_hz >> 16 ),
( uint8_t )( configuration->wor_second_channel_frequency_hz >> 8 ),
( uint8_t ) configuration->wor_second_channel_frequency_hz,
( uint8_t )( configuration->wor_ack_second_channel_frequency_hz >> 24 ),
( uint8_t )( configuration->wor_ack_second_channel_frequency_hz >> 16 ),
( uint8_t )( configuration->wor_ack_second_channel_frequency_hz >> 8 ),
( uint8_t ) configuration->wor_ack_second_channel_frequency_hz,
configuration->wor_second_channel_datarate,
configuration->wor_second_channel_enable,
configuration->backoff_behavior,
( uint8_t ) configuration->activation,
( uint8_t ) configuration->smart_level,
configuration->missed_ack_to_unsynchronized_threshold,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_RELAY_SET_TX_CONFIG_RBUFFER_LENGTH, 0, 0 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
uint32_t lr1121_uint8_to_uint32( const uint8_t value[4] )
{
return ( ( ( uint32_t ) value[0] ) << 24 ) + ( ( ( uint32_t ) value[1] ) << 16 ) +
( ( ( uint32_t ) value[2] ) << 8 ) + ( ( ( uint32_t ) value[3] ) );
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,699 @@
/*!
* @file lr1121_modem_system.c
*
* @brief System driver implementation for LR1121
*
* @copyright Copyright Semtech Corporation 2024. All rights reserved.
*
* @license{The Clear BSD License
* @par
* 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.
* @par
* 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.}
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdlib.h>
#include "lr1121_modem_system.h"
#include "lr1121_modem_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*!
* @brief Length in byte of the LR1121 version blob
*/
#define LR1121_MODEM_SYSTEM_VERSION_LENGTH ( 4 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR1121_MODEM_SYSTEM_GET_VERSION_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_GET_ERRORS_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_CLEAR_ERRORS_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_CALIBRATE_CMD_LENGTH ( 2 + 1 )
#define LR1121_MODEM_SYSTEM_SET_REGMODE_CMD_LENGTH ( 2 + 1 )
#define LR1121_MODEM_SYSTEM_CALIBRATE_IMAGE_CMD_LENGTH ( 2 + 2 )
#define LR1121_MODEM_SYSTEM_SET_DIO_AS_RF_SWITCH_CMD_LENGTH ( 2 + 8 )
#define LR1121_MODEM_SYSTEM_SET_DIO_IRQ_PARAMS_CMD_LENGTH ( 2 + 8 )
#define LR1121_MODEM_SYSTEM_CLEAR_IRQ_CMD_LENGTH ( 2 + 4 )
#define LR1121_MODEM_SYSTEM_CFG_LFCLK_CMD_LENGTH ( 2 + 1 )
#define LR1121_MODEM_SYSTEM_SET_TCXO_MODE_CMD_LENGTH ( 2 + 4 )
#define LR1121_MODEM_SYSTEM_REBOOT_CMD_LENGTH ( 2 + 1 )
#define LR1121_MODEM_SYSTEM_GET_VBAT_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_GET_TEMP_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_SET_SLEEP_CMD_LENGTH ( 2 + 5 )
#define LR1121_MODEM_SYSTEM_SET_STANDBY_CMD_LENGTH ( 2 + 1 )
#define LR1121_MODEM_SYSTEM_SET_FS_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_ERASE_INFOPAGE_CMD_LENGTH ( 2 + 1 )
#define LR1121_MODEM_SYSTEM_WRITE_INFOPAGE_CMD_LENGTH ( 2 + 3 )
#define LR1121_MODEM_SYSTEM_READ_INFOPAGE_CMD_LENGTH ( 2 + 4 )
#define LR1121_MODEM_SYSTEM_READ_UID_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_READ_JOIN_EUI_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_READ_PIN_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_READ_PIN_CUSTOM_EUI_CMD_LENGTH ( LR1121_MODEM_SYSTEM_READ_PIN_CMD_LENGTH + 17 )
#define LR1121_MODEM_SYSTEM_GET_RANDOM_CMD_LENGTH ( 2 )
#define LR1121_MODEM_SYSTEM_ENABLE_SPI_CRC_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_CMD_LENGTH ( 3 )
#define LR1121_MODEM_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH ( 6 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for system-related operations
*/
enum
{
LR1121_MODEM_SYSTEM_GET_STATUS_OC = 0x0100,
LR1121_MODEM_SYSTEM_GET_VERSION_OC = 0x0101,
LR1121_MODEM_SYSTEM_GET_ERRORS_OC = 0x010D,
LR1121_MODEM_SYSTEM_CLEAR_ERRORS_OC = 0x010E,
LR1121_MODEM_SYSTEM_CALIBRATE_OC = 0x010F,
LR1121_MODEM_SYSTEM_SET_REGMODE_OC = 0x0110,
LR1121_MODEM_SYSTEM_CALIBRATE_IMAGE_OC = 0x0111,
LR1121_MODEM_SYSTEM_SET_DIO_AS_RF_SWITCH_OC = 0x0112,
LR1121_MODEM_SYSTEM_SET_DIOIRQPARAMS_OC = 0x0113,
LR1121_MODEM_SYSTEM_CLEAR_IRQ_OC = 0x0114,
LR1121_MODEM_SYSTEM_CFG_LFCLK_OC = 0x0116,
LR1121_MODEM_SYSTEM_SET_TCXO_MODE_OC = 0x0117,
LR1121_MODEM_SYSTEM_REBOOT_OC = 0x0118,
LR1121_MODEM_SYSTEM_GET_VBAT_OC = 0x0119,
LR1121_MODEM_SYSTEM_GET_TEMP_OC = 0x011A,
LR1121_MODEM_SYSTEM_SET_SLEEP_OC = 0x011B,
LR1121_MODEM_SYSTEM_SET_STANDBY_OC = 0x011C,
LR1121_MODEM_SYSTEM_SET_FS_OC = 0x011D,
LR1121_MODEM_SYSTEM_GET_RANDOM_OC = 0x0120,
LR1121_MODEM_SYSTEM_ERASE_INFOPAGE_OC = 0x0121,
LR1121_MODEM_SYSTEM_WRITE_INFOPAGE_OC = 0x0122,
LR1121_MODEM_SYSTEM_READ_INFOPAGE_OC = 0x0123,
LR1121_MODEM_SYSTEM_READ_UID_OC = 0x0125,
LR1121_MODEM_SYSTEM_READ_JOIN_EUI_OC = 0x0126,
LR1121_MODEM_SYSTEM_READ_PIN_OC = 0x0127,
LR1121_MODEM_SYSTEM_ENABLE_SPI_CRC_OC = 0x0128,
LR1121_MODEM_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_OC = 0x012A,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Fill stat1 structure with data from stat1_byte
*
* @param [in] stat1_byte stat1 byte
* @param [out] stat1 stat1 structure
*/
static void lr1121_modem_system_convert_stat1_byte_to_enum( uint8_t stat1_byte, lr1121_modem_system_stat1_t* stat1 );
/*!
* @brief Fill stat2 structure with data from stat2_byte
*
* @param [in] stat2_byte stat2 byte
* @param [out] stat2 stat2 structure
*/
static void lr1121_modem_system_convert_stat2_byte_to_enum( uint8_t stat2_byte, lr1121_modem_system_stat2_t* stat2 );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr1121_modem_response_code_t lr1121_modem_system_reset( const void* context )
{
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_reset( context );
}
lr1121_modem_response_code_t lr1121_modem_system_get_status( const void* context, lr1121_modem_system_stat1_t* stat1,
lr1121_modem_system_stat2_t* stat2,
lr1121_modem_system_irq_mask_t* irq_status )
{
uint8_t data[LR1121_MODEM_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH] = { 0 };
const lr1121_modem_response_code_t status = ( lr1121_modem_response_code_t ) lr1121_modem_hal_direct_read(
context, data, LR1121_MODEM_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH );
if( status == LR1121_MODEM_RESPONSE_CODE_OK )
{
lr1121_modem_system_convert_stat1_byte_to_enum( data[0], stat1 );
lr1121_modem_system_convert_stat2_byte_to_enum( data[1], stat2 );
if( irq_status != NULL )
{
*irq_status = ( ( lr1121_modem_system_irq_mask_t ) data[2] << 24 ) +
( ( lr1121_modem_system_irq_mask_t ) data[3] << 16 ) +
( ( lr1121_modem_system_irq_mask_t ) data[4] << 8 ) +
( ( lr1121_modem_system_irq_mask_t ) data[5] << 0 );
}
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_system_clear_reset_status_info( const void* context )
{
uint8_t cbuffer[2] = {
( uint8_t )( LR1121_MODEM_SYSTEM_GET_STATUS_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_GET_STATUS_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer, sizeof( cbuffer ), 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_get_version( const void* context,
lr1121_modem_system_version_t* version )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_GET_VERSION_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_GET_VERSION_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_GET_VERSION_OC >> 0 ),
};
uint8_t rbuffer[LR1121_MODEM_SYSTEM_VERSION_LENGTH] = { 0x00 };
const lr1121_modem_response_code_t status = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_GET_VERSION_CMD_LENGTH, rbuffer, LR1121_MODEM_SYSTEM_VERSION_LENGTH );
if( status == LR1121_MODEM_RESPONSE_CODE_OK )
{
version->hw = rbuffer[0];
version->type = ( lr1121_modem_system_version_type_t ) rbuffer[1];
version->fw = ( ( uint16_t ) rbuffer[2] << 8 ) + ( uint16_t ) rbuffer[3];
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_system_get_errors( const void* context, lr1121_modem_system_errors_t* errors )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_GET_ERRORS_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_GET_ERRORS_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_GET_ERRORS_OC >> 0 ),
};
uint8_t rbuffer[sizeof( errors )] = { 0x00 };
const lr1121_modem_response_code_t status = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_GET_ERRORS_CMD_LENGTH, rbuffer, sizeof( *errors ) );
if( status == LR1121_MODEM_RESPONSE_CODE_OK )
{
*errors = ( ( uint16_t ) rbuffer[0] << 8 ) + ( uint16_t ) rbuffer[1];
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_system_clear_errors( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_CLEAR_ERRORS_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_CLEAR_ERRORS_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_CLEAR_ERRORS_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_CLEAR_ERRORS_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_calibrate( const void* context, const uint8_t calib_param )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_CALIBRATE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_CALIBRATE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_CALIBRATE_OC >> 0 ),
calib_param,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_CALIBRATE_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_set_reg_mode( const void* context,
const lr1121_modem_system_reg_mode_t reg_mode )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_REGMODE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_REGMODE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_REGMODE_OC >> 0 ),
( uint8_t ) reg_mode,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_SET_REGMODE_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_calibrate_image( const void* context, const uint8_t freq1,
const uint8_t freq2 )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_CALIBRATE_IMAGE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_CALIBRATE_IMAGE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_CALIBRATE_IMAGE_OC >> 0 ),
freq1,
freq2,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_CALIBRATE_IMAGE_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_calibrate_image_in_mhz( const void* context,
const uint16_t freq1_in_mhz,
const uint16_t freq2_in_mhz )
{
// Perform a floor() to get a value for freq1 corresponding to a frequency lower than or equal to freq1_in_mhz
const uint8_t freq1 = freq1_in_mhz / LR1121_MODEM_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ;
// Perform a ceil() to get a value for freq2 corresponding to a frequency higher than or equal to freq2_in_mhz
const uint8_t freq2 = ( freq2_in_mhz + LR1121_MODEM_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ - 1 ) /
LR1121_MODEM_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ;
return lr1121_modem_system_calibrate_image( context, freq1, freq2 );
}
lr1121_modem_response_code_t lr1121_modem_system_set_dio_as_rf_switch(
const void* context, const lr1121_modem_system_rfswitch_cfg_t* rf_switch_cfg )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_DIO_AS_RF_SWITCH_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_DIO_AS_RF_SWITCH_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_DIO_AS_RF_SWITCH_OC >> 0 ),
rf_switch_cfg->enable,
rf_switch_cfg->standby,
rf_switch_cfg->rx,
rf_switch_cfg->tx,
rf_switch_cfg->tx_hp,
rf_switch_cfg->tx_hf,
0x00,
0x00,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_SET_DIO_AS_RF_SWITCH_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_set_dio_irq_params(
const void* context, const lr1121_modem_system_irq_mask_t irqs_to_enable_dio1,
const lr1121_modem_system_irq_mask_t irqs_to_enable_dio2 )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_DIO_IRQ_PARAMS_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_DIOIRQPARAMS_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_DIOIRQPARAMS_OC >> 0 ),
( uint8_t )( irqs_to_enable_dio1 >> 24 ),
( uint8_t )( irqs_to_enable_dio1 >> 16 ),
( uint8_t )( irqs_to_enable_dio1 >> 8 ),
( uint8_t )( irqs_to_enable_dio1 >> 0 ),
( uint8_t )( irqs_to_enable_dio2 >> 24 ),
( uint8_t )( irqs_to_enable_dio2 >> 16 ),
( uint8_t )( irqs_to_enable_dio2 >> 8 ),
( uint8_t )( irqs_to_enable_dio2 >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_SET_DIO_IRQ_PARAMS_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_clear_irq_status( const void* context,
const lr1121_modem_system_irq_mask_t irqs_to_clear )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_CLEAR_IRQ_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_CLEAR_IRQ_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_CLEAR_IRQ_OC >> 0 ),
( uint8_t )( irqs_to_clear >> 24 ),
( uint8_t )( irqs_to_clear >> 16 ),
( uint8_t )( irqs_to_clear >> 8 ),
( uint8_t )( irqs_to_clear >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_CLEAR_IRQ_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_get_and_clear_irq_status( const void* context,
lr1121_modem_system_irq_mask_t* irq )
{
lr1121_modem_system_irq_mask_t lr1121_modem_irq_mask = LR1121_MODEM_SYSTEM_IRQ_NONE;
lr1121_modem_response_code_t status = lr1121_modem_system_get_irq_status( context, &lr1121_modem_irq_mask );
if( ( status == LR1121_MODEM_RESPONSE_CODE_OK ) && ( lr1121_modem_irq_mask != 0 ) )
{
status = lr1121_modem_system_clear_irq_status( context, lr1121_modem_irq_mask );
}
if( ( status == LR1121_MODEM_RESPONSE_CODE_OK ) && ( irq != NULL ) )
{
*irq = lr1121_modem_irq_mask;
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_system_cfg_lfclk( const void* context,
const lr1121_modem_system_lfclk_cfg_t lfclock_cfg,
const bool wait_for_32k_ready )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_CFG_LFCLK_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_CFG_LFCLK_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_CFG_LFCLK_OC >> 0 ),
( uint8_t )( lfclock_cfg | ( wait_for_32k_ready << 2 ) ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_CFG_LFCLK_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_set_tcxo_mode( const void* context,
const lr1121_modem_system_tcxo_supply_voltage_t tune,
const uint32_t timeout )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_TCXO_MODE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_TCXO_MODE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_TCXO_MODE_OC >> 0 ),
( uint8_t ) tune,
( uint8_t )( timeout >> 16 ),
( uint8_t )( timeout >> 8 ),
( uint8_t )( timeout >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_SET_TCXO_MODE_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_reboot( const void* context, const bool stay_in_bootloader )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_REBOOT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_REBOOT_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_REBOOT_OC >> 0 ),
( stay_in_bootloader == true ) ? 0x03 : 0x00,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_REBOOT_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_get_vbat( const void* context, uint8_t* vbat )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_GET_VBAT_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_GET_VBAT_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_GET_VBAT_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_GET_VBAT_CMD_LENGTH, vbat, sizeof( *vbat ) );
}
lr1121_modem_response_code_t lr1121_modem_system_get_temp( const void* context, uint16_t* temp )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_GET_TEMP_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_GET_TEMP_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_GET_TEMP_OC >> 0 ),
};
uint8_t rbuffer[sizeof( uint16_t )] = { 0x00 };
const lr1121_modem_response_code_t status = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_GET_TEMP_CMD_LENGTH, rbuffer, sizeof( uint16_t ) );
if( status == LR1121_MODEM_RESPONSE_CODE_OK )
{
*temp = ( ( uint16_t ) rbuffer[0] << 8 ) + ( uint16_t ) rbuffer[1];
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_system_set_sleep( const void* context,
const lr1121_modem_system_sleep_cfg_t sleep_cfg,
const uint32_t sleep_time )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_SLEEP_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_SLEEP_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_SLEEP_OC >> 0 ),
0x02u + sleep_cfg.is_warm_start,
( uint8_t )( sleep_time >> 24 ),
( uint8_t )( sleep_time >> 16 ),
( uint8_t )( sleep_time >> 8 ),
( uint8_t )( sleep_time >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_SET_SLEEP_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_set_standby( const void* context,
const lr1121_modem_system_standby_cfg_t standby_cfg )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_STANDBY_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_STANDBY_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_STANDBY_OC >> 0 ),
( uint8_t ) standby_cfg,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_SET_STANDBY_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_wakeup( const void* context )
{
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_wakeup( context );
}
lr1121_modem_response_code_t lr1121_modem_system_set_fs( const void* context )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_SET_FS_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_SET_FS_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_SET_FS_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write( context, cbuffer,
LR1121_MODEM_SYSTEM_SET_FS_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_erase_infopage( const void* context,
const lr1121_modem_system_infopage_id_t infopage_id )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_ERASE_INFOPAGE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_ERASE_INFOPAGE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_ERASE_INFOPAGE_OC >> 0 ),
( uint8_t ) infopage_id,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_ERASE_INFOPAGE_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_write_infopage( const void* context,
const lr1121_modem_system_infopage_id_t infopage_id,
const uint16_t address, const uint32_t* data,
const uint8_t length )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_WRITE_INFOPAGE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_WRITE_INFOPAGE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_WRITE_INFOPAGE_OC >> 0 ),
( uint8_t ) infopage_id,
( uint8_t )( address >> 8 ),
( uint8_t )( address >> 0 ),
};
uint8_t cdata[256];
for( uint16_t index = 0; index < length; index++ )
{
uint8_t* cdata_local = &cdata[index * sizeof( uint32_t )];
cdata_local[0] = ( uint8_t )( data[index] >> 24 );
cdata_local[1] = ( uint8_t )( data[index] >> 16 );
cdata_local[2] = ( uint8_t )( data[index] >> 8 );
cdata_local[3] = ( uint8_t )( data[index] >> 0 );
}
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_WRITE_INFOPAGE_CMD_LENGTH, cdata, length * sizeof( uint32_t ) );
}
lr1121_modem_response_code_t lr1121_modem_system_read_infopage( const void* context,
const lr1121_modem_system_infopage_id_t infopage_id,
const uint16_t address, uint32_t* data,
const uint8_t length )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_READ_INFOPAGE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_READ_INFOPAGE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_READ_INFOPAGE_OC >> 0 ),
( uint8_t ) infopage_id,
( uint8_t )( address >> 8 ),
( uint8_t )( address >> 0 ),
length,
};
const lr1121_modem_response_code_t status = ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_READ_INFOPAGE_CMD_LENGTH, ( uint8_t* ) data, length * sizeof( *data ) );
if( status == LR1121_MODEM_RESPONSE_CODE_OK )
{
for( uint8_t index = 0; index < length; index++ )
{
uint8_t* buffer_local = ( uint8_t* ) &data[index];
data[index] = ( ( uint32_t ) buffer_local[0] << 24 ) + ( ( uint32_t ) buffer_local[1] << 16 ) +
( ( uint32_t ) buffer_local[2] << 8 ) + ( ( uint32_t ) buffer_local[3] << 0 );
}
}
return status;
}
lr1121_modem_response_code_t lr1121_modem_system_read_uid( const void* context,
lr1121_modem_system_uid_t unique_identifier )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_READ_UID_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_READ_UID_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_READ_UID_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_READ_UID_CMD_LENGTH, unique_identifier, LR1121_MODEM_SYSTEM_UID_LENGTH );
}
lr1121_modem_response_code_t lr1121_modem_system_read_join_eui( const void* context,
lr1121_modem_system_join_eui_t join_eui )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_READ_JOIN_EUI_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_READ_JOIN_EUI_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_READ_JOIN_EUI_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_READ_JOIN_EUI_CMD_LENGTH, join_eui, LR1121_MODEM_SYSTEM_JOIN_EUI_LENGTH );
}
lr1121_modem_response_code_t lr1121_modem_system_read_pin( const void* context, lr1121_modem_system_pin_t pin )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_READ_PIN_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_READ_PIN_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_READ_PIN_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_READ_PIN_CMD_LENGTH, pin, LR1121_MODEM_SYSTEM_PIN_LENGTH );
}
lr1121_modem_response_code_t lr1121_modem_system_read_pin_custom_eui( const void* context,
lr1121_modem_system_uid_t device_eui,
lr1121_modem_system_join_eui_t join_eui,
uint8_t rfu, lr1121_modem_system_pin_t pin )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_READ_PIN_CUSTOM_EUI_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_READ_PIN_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_READ_PIN_OC >> 0 ),
device_eui[0],
device_eui[1],
device_eui[2],
device_eui[3],
device_eui[4],
device_eui[5],
device_eui[6],
device_eui[7],
join_eui[0],
join_eui[1],
join_eui[2],
join_eui[3],
join_eui[4],
join_eui[5],
join_eui[6],
join_eui[7],
rfu,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_READ_PIN_CUSTOM_EUI_CMD_LENGTH, pin, LR1121_MODEM_SYSTEM_PIN_LENGTH );
}
lr1121_modem_response_code_t lr1121_modem_system_get_random_number( const void* context, uint32_t* random_number )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_GET_RANDOM_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_GET_RANDOM_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_GET_RANDOM_OC >> 0 ),
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_read(
context, cbuffer, LR1121_MODEM_SYSTEM_GET_RANDOM_CMD_LENGTH, ( uint8_t* ) random_number, sizeof( uint32_t ) );
}
lr1121_modem_response_code_t lr1121_modem_system_enable_spi_crc( const void* context, bool enable_crc )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_ENABLE_SPI_CRC_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_ENABLE_SPI_CRC_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_ENABLE_SPI_CRC_OC >> 0 ),
( enable_crc == true ) ? 0x01 : 0x00,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_ENABLE_SPI_CRC_CMD_LENGTH, 0, 0 );
}
lr1121_modem_response_code_t lr1121_modem_system_drive_dio_in_sleep_mode( const void* context, bool enable_drive )
{
const uint8_t cbuffer[LR1121_MODEM_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_CMD_LENGTH] = {
( uint8_t )( LR1121_MODEM_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_OC >> 8 ),
( uint8_t )( LR1121_MODEM_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_OC >> 0 ),
( enable_drive == true ) ? 0x01 : 0x00,
};
return ( lr1121_modem_response_code_t ) lr1121_modem_hal_write(
context, cbuffer, LR1121_MODEM_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_CMD_LENGTH, 0, 0 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
static void lr1121_modem_system_convert_stat1_byte_to_enum( uint8_t stat1_byte, lr1121_modem_system_stat1_t* stat1 )
{
if( stat1 != NULL )
{
stat1->is_interrupt_active = ( ( stat1_byte & 0x01 ) != 0 ) ? true : false;
stat1->command_status = ( lr1121_modem_system_command_status_t )( stat1_byte >> 1 );
}
}
static void lr1121_modem_system_convert_stat2_byte_to_enum( uint8_t stat2_byte, lr1121_modem_system_stat2_t* stat2 )
{
if( stat2 != NULL )
{
stat2->is_running_from_flash = ( ( stat2_byte & 0x01 ) != 0 ) ? true : false;
stat2->chip_mode = ( lr1121_modem_system_chip_modes_t )( ( stat2_byte & 0x0F ) >> 1 );
stat2->reset_status = ( lr1121_modem_system_reset_status_t )( ( stat2_byte & 0xF0 ) >> 4 );
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,344 @@
/*!
* @file lr1121_modem_hal.c
*
* @brief Hardware Abstraction Layer (HAL) implementation for lr1121
*
* The Clear BSD License
* Copyright Semtech Corporation 2024. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdint.h>
#include "esp_lora_1121.h"
/*!
* @brief lr1121_modem_hal.h API implementation
*/
/*!
* @brief Function to wait that the lr1121 modem-e busy line fall to low
*
* @param [in] context Chip implementation context
* @param [in] timeout_ms timeout in millisec before leave the function
*
* @returns lr1121_hal_status_t
*/
static lr1121_modem_hal_status_t lr1121_modem_hal_wait_on_busy(const void *context, uint32_t timeout_ms);
/*!
* @brief Function to wait the that lr1121 modem-e busy line raise to high
*
* @param [in] context Chip implementation context
* @param [in] timeout_ms timeout in millisec before leave the function
*
* @returns lr1121_hal_status_t
*/
static lr1121_modem_hal_status_t lr1121_modem_hal_wait_on_unbusy(const void *context, uint32_t timeout_ms);
lr1121_modem_hal_status_t lr1121_modem_hal_write(const void *context, const uint8_t *command,
const uint16_t command_length, const uint8_t *data,
const uint16_t data_length)
{
if (lr1121_modem_hal_wakeup( context ) == LR1121_MODEM_HAL_STATUS_OK)
{
uint8_t crc = 0;
uint8_t crc_received = 0;
lr1121_modem_hal_status_t status;
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* Send CMD */
lora_spi_write_bytes(context, (uint8_t *)command, command_length);
/* Send Data */
if (data_length > 0)
{
lora_spi_write_bytes(context, (uint8_t *)data, data_length);
}
/* Compute and send CRC */
crc = lr1121_modem_compute_crc( 0xFF, command, command_length );
if (data_length > 0)
{
crc = lr1121_modem_compute_crc( crc, data, data_length );
}
/* Send CRC */
lora_spi_write_bytes(context, (uint8_t *)&crc, 1);
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
/* Wait on busy pin up to 1000 ms */
if( lr1121_modem_hal_wait_on_busy( context, 1000 ) != LR1121_MODEM_HAL_STATUS_OK )
{
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
/* Send dummy byte to retrieve RC & CRC */
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* read RC */
lora_spi_read_bytes(context, ( uint8_t* ) &status, 1);
lora_spi_read_bytes(context, ( uint8_t* ) &crc_received, 1);
/* Compute response crc */
crc = lr1121_modem_compute_crc( 0xFF, ( uint8_t* ) &status, 1 );
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
if( crc != crc_received )
{
/* change the response code */
status = LR1121_MODEM_HAL_STATUS_BAD_FRAME;
}
/* Wait on busy pin up to 1000 ms */
if( lr1121_modem_hal_wait_on_unbusy( context, 1000 ) != LR1121_MODEM_HAL_STATUS_OK )
{
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
return status;
}
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
lr1121_modem_hal_status_t lr1121_modem_hal_write_without_rc( const void* context, const uint8_t* command,
const uint16_t command_length, const uint8_t* data,
const uint16_t data_length )
{
if( lr1121_modem_hal_wakeup( context ) == LR1121_MODEM_HAL_STATUS_OK )
{
uint8_t crc = 0;
lr1121_modem_hal_status_t status = LR1121_MODEM_HAL_STATUS_OK;
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* Send CMD */
lora_spi_write_bytes(context, (uint8_t *)command, command_length);
/* Send Data */
if (data_length > 0)
{
lora_spi_write_bytes(context, (uint8_t *)data, data_length);
}
/* Compute and send CRC */
crc = lr1121_modem_compute_crc( 0xFF, command, command_length );
crc = lr1121_modem_compute_crc( crc, data, data_length );
/* Send CRC */
lora_spi_write_bytes(context, (uint8_t *)&crc, 1);
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
return status;
}
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
lr1121_modem_hal_status_t lr1121_modem_hal_read(const void *context, const uint8_t *command,
const uint16_t command_length, uint8_t *data,
const uint16_t data_length)
{
if (lr1121_modem_hal_wakeup( context ) == LR1121_MODEM_HAL_STATUS_OK)
{
uint8_t crc = 0;
uint8_t crc_received = 0;
lr1121_modem_hal_status_t status = LR1121_MODEM_HAL_STATUS_ERROR;
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* Send CMD */
lora_spi_write_bytes(context, (uint8_t *)command, command_length);
/* Compute and send CRC */
crc = lr1121_modem_compute_crc( 0xFF, command, command_length );
/* Send CRC */
lora_spi_write_bytes(context, &crc, 1);
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
/* Wait on busy pin up to 1000 ms */
if (lr1121_modem_hal_wait_on_busy(context, 1000) != LR1121_MODEM_HAL_STATUS_OK)
{
return LR1121_MODEM_HAL_STATUS_ERROR;
}
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* read RC */
lora_spi_read_bytes(context, ( uint8_t* ) &status, 1);
// printf("status:%d\r\n",status);
if( status == LR1121_MODEM_HAL_STATUS_OK )
{
// printf("data_length:%d\r\n",data_length);
lora_spi_read_bytes(context, data, data_length);
}
lora_spi_read_bytes( context, ( uint8_t* ) &crc_received, 1 );
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
/* Compute response crc */
crc = lr1121_modem_compute_crc( 0xFF, ( uint8_t* ) &status, 1 );
if( status == LR1121_MODEM_HAL_STATUS_OK )
{
crc = lr1121_modem_compute_crc( crc, data, data_length );
}
if( crc != crc_received )
{
if( crc != crc_received )
/* change the response code */
status = LR1121_MODEM_HAL_STATUS_BAD_FRAME;
}
/* Wait on busy pin up to 1000 ms */
if( lr1121_modem_hal_wait_on_unbusy( context, 1000 ) != LR1121_MODEM_HAL_STATUS_OK )
{
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
return status;
}
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
lr1121_modem_hal_status_t lr1121_modem_hal_direct_read(const void *context, uint8_t *data,
const uint16_t data_length)
{
if (lr1121_modem_hal_wait_on_unbusy(context, 10000) == LR1121_MODEM_HAL_STATUS_OK)
{
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
lora_spi_read_bytes(context, data, data_length);
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
return LR1121_MODEM_HAL_STATUS_OK;
}
return LR1121_MODEM_HAL_STATUS_ERROR;
}
lr1121_modem_hal_status_t lr1121_modem_hal_reset(const void *context)
{
if (((lr1121_t *)context)->reset >= 0)
{
gpio_set_level(((lr1121_t *)context)->reset, 0);
vTaskDelay(1 / portTICK_PERIOD_MS);
gpio_set_level(((lr1121_t *)context)->reset, 1);
}
return LR1121_MODEM_HAL_STATUS_OK;
}
lr1121_modem_hal_status_t lr1121_modem_hal_wakeup(const void *context)
{
if( lr1121_modem_hal_wait_on_busy( context, 10000 ) == LR1121_MODEM_HAL_STATUS_OK )
{
/* Wakeup radio */
gpio_set_level(((lr1121_t *)context)->cs, 0);
vTaskDelay(1 / portTICK_PERIOD_MS);
gpio_set_level(((lr1121_t *)context)->cs, 1);
vTaskDelay(1 / portTICK_PERIOD_MS);
}
else
{
return LR1121_MODEM_HAL_STATUS_BUSY_TIMEOUT;
}
/* Wait on busy pin for 1000 ms */
return lr1121_modem_hal_wait_on_unbusy( context, 1000 );
}
static lr1121_modem_hal_status_t lr1121_modem_hal_wait_on_busy(const void *context, uint32_t timeout_ms)
{
#if 0
while( gpio_get_level( ( ( lr1121_t* ) context )->busy ) == 0 )
{
;
}
#else
if (((lr1121_t *)context)->busy < 0)
{
return LR1121_MODEM_HAL_STATUS_OK;
}
uint32_t start = esp_timer_get_time() / 1000;
uint32_t current = 0;
while (gpio_get_level(((lr1121_t *)context)->busy) == 0)
{
current = esp_timer_get_time() / 1000;
if ((int32_t)(current - start) > (int32_t)timeout_ms)
{
return LR1121_MODEM_HAL_STATUS_ERROR;
}
}
#endif
return LR1121_MODEM_HAL_STATUS_OK;
}
static lr1121_modem_hal_status_t lr1121_modem_hal_wait_on_unbusy(const void *context, uint32_t timeout_ms)
{
#if 0
while( gpio_get_level( ( ( lr1121_t* ) context )->busy ) == 1 )
{
;
}
#else
if (((lr1121_t *)context)->busy < 0)
{
return LR1121_MODEM_HAL_STATUS_OK;
}
uint32_t start = esp_timer_get_time() / 1000;
uint32_t current = 0;
while (gpio_get_level(((lr1121_t *)context)->busy) == 1)
{
current = esp_timer_get_time() / 1000;
if ((int32_t)(current - start) > (int32_t)timeout_ms)
{
return LR1121_MODEM_HAL_STATUS_ERROR;
}
}
#endif
return LR1121_MODEM_HAL_STATUS_OK;
}

View File

@@ -0,0 +1,315 @@
/*!
* @file lr1121_modem_printf_info.c
*
* @brief Common Application Helper function implementations
*
* @copyright
* @parblock
* The Clear BSD License
* Copyright Semtech Corporation 2024. 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.
* @endparblock
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr1121_modem_printf_info.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC VARIABLES --------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
void print_hex_buffer(const uint8_t *buffer, uint8_t size)
{
uint8_t newline = 0;
for (uint8_t i = 0; i < size; i++)
{
if (newline != 0)
{
printf("\n\n");
newline = 0;
}
printf("%02X ", buffer[i]);
if (((i + 1) % 16) == 0)
{
newline = 1;
}
}
printf("\n\n");
}
void print_version(lr1121_modem_version_t modem_version)
{
printf("###### ===== lr1121 MODEM-E VERSION ==== ######\n\n\n");
printf("USE CASE : %02X\n", modem_version.use_case);
printf("MODEM : %02X.%02X.%02X\n", modem_version.modem_major, modem_version.modem_minor,
modem_version.modem_patch);
printf("LBM : %02X.%02X.%02X\n\n", modem_version.lbm_major, modem_version.lbm_minor,
modem_version.lbm_patch);
}
void print_lorawan_credentials(const uint8_t *dev_eui, const uint8_t *join_eui, const uint8_t *pin,
const bool use_internal_credentials)
{
if (use_internal_credentials)
{
printf("---=== INTERNAL CREDENTIALS ===---\n\n");
}
else
{
printf("---=== CUSTOM CREDENTIALS ===---\n\n");
}
printf("DevEui : %02X", dev_eui[0]);
for (int i = 1; i < 8; i++)
{
printf("-%02X", dev_eui[i]);
}
printf("\n");
printf("JoinEui : %02X", join_eui[0]);
for (int i = 1; i < 8; i++)
{
printf("-%02X", join_eui[i]);
}
printf("\n");
printf("Pin : %02X", pin[0]);
for (int i = 1; i < 4; i++)
{
printf("-%02X", pin[i]);
}
printf("\n\n");
}
void modem_status_to_string(lr1121_modem_lorawan_status_t modem_status)
{
printf("Modem status : ");
if ((modem_status & LR1121_LORAWAN_CRASH) == LR1121_LORAWAN_CRASH)
{
printf("CRASH ");
}
if ((modem_status & LR1121_LORAWAN_JOINED) == LR1121_LORAWAN_JOINED)
{
printf("JOINED ");
}
if ((modem_status & LR1121_LORAWAN_SUSPEND) == LR1121_LORAWAN_SUSPEND)
{
printf("SUSPEND ");
}
if ((modem_status & LR1121_LORAWAN_JOINING) == LR1121_LORAWAN_JOINING)
{
printf("JOINING ");
}
printf("\n\n\n");
}
void get_and_print_lorawan_region_from_modem(const void *context, lr1121_modem_regions_t *modem_region)
{
// 1. Get the region from modem
lr1121_modem_regions_t local_region = LR1121_LORAWAN_REGION_EU868;
const lr1121_modem_response_code_t response_code = lr1121_modem_get_region(context, &local_region);
if (response_code == LR1121_MODEM_RESPONSE_CODE_OK)
{
// 2a. If the get from the modem is successful print it.
// And the output pointer is not null: return the region
if (modem_region != NULL)
{
*modem_region = local_region;
}
print_lorawan_region(*modem_region);
}
else
{
// 2b. If the get from modem failed: print an error message
printf("Error on lr1121_modem_get_region, get response code: %d\n", response_code);
}
}
void print_lorawan_region(lr1121_modem_regions_t region)
{
switch (region)
{
case LR1121_LORAWAN_REGION_EU868:
{
printf("REGION : EU868\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_US915:
{
printf("REGION : US915\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_AU915:
{
printf("REGION : AU915\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_AS923_GRP1:
{
printf("REGION : AS923_GRP1\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_CN470:
{
printf("REGION : CN470\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_AS923_GRP2:
{
printf("REGION : AS923_GRP2\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_AS923_GRP3:
{
printf("REGION : AS923_GRP3\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_AS923_GRP4:
{
printf("REGION : AS923_GRP4\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_IN865:
{
printf("REGION : IN865\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_KR920:
{
// printf( "LBT : ACTIVATE LBT\n\n" );
printf("REGION : KR920\n\n\n");
break;
}
case LR1121_LORAWAN_REGION_RU864:
{
printf("REGION : RU864\n\n\n");
break;
}
default:
printf("No supported region selected\n\n\n");
break;
}
}
void print_certification(lr1121_modem_certification_mode_t certif_running)
{
if (certif_running == LR1121_MODEM_CERTIFICATION_MODE_ENABLE)
{
printf("###### ===================================== ######\n");
printf("###### ===== CERTIFICATION MODE ENABLED ==== ######\n");
printf("###### ===================================== ######\n\n\n");
}
else
{
printf("###### ====================================== ######\n");
printf("###### ===== CERTIFICATION MODE DISABLED ==== ######\n");
printf("###### ====================================== ######\n\n\n");
}
}
void get_and_print_crashlog(const void *context)
{
lr1121_modem_response_code_t response_code = LR1121_MODEM_RESPONSE_CODE_OK;
lr1121_modem_lorawan_status_t modem_status;
response_code = lr1121_modem_get_status(context, (lr1121_modem_lorawan_status_bitmask_t*)&modem_status);
// Check if the crashlog bit is set in modem_status
if (response_code == LR1121_MODEM_RESPONSE_CODE_OK)
{
if ((modem_status & LR1121_LORAWAN_CRASH) == LR1121_LORAWAN_CRASH)
{
lr1121_modem_crashlog_status_t status_crashlog = LR1121_NO_NEW_CRASHLOG;
uint8_t crashlog[242] = {0};
// Get the crashlog
response_code = lr1121_modem_get_crashlog(context, &status_crashlog, crashlog);
if ((response_code == LR1121_MODEM_RESPONSE_CODE_OK) && (status_crashlog == LR1121_NEW_CRASHLOG))
{
printf("###### ===================================== ######\n");
printf("###### =========== MODEM CRASHED =========== ######\n");
printf("###### ===================================== ######\n\n");
// HAL_DBG_TRACE_ARRAY( "Crashlog: ", crashlog, 242 );
printf("%s - (%u bytes):\n", "Crashlog: ", 242);
for (uint32_t i = 0; i < 242; i++)
{
if (((i % 16) == 0) && (i > 0))
{
printf("\n");
}
printf(" %02X", crashlog[i]);
}
printf("\n");
printf("\n\n");
}
}
}
else
{
printf("Error on lr1121_modem_get_status, get response code: %d\n", response_code);
}
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,159 @@
/*!
* @file lr11xx_bootloader_types_str.c
*
* @brief Printer helper functions for LR11xx bootloader types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_bootloader_types_str.h"
const char* lr11xx_bootloader_chip_modes_to_str( const lr11xx_bootloader_chip_modes_t value )
{
switch( value )
{
case LR11XX_BOOTLOADER_CHIP_MODE_SLEEP:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_SLEEP";
}
case LR11XX_BOOTLOADER_CHIP_MODE_STBY_RC:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_STBY_RC";
}
case LR11XX_BOOTLOADER_CHIP_MODE_STBY_XOSC:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_STBY_XOSC";
}
case LR11XX_BOOTLOADER_CHIP_MODE_FS:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_FS";
}
case LR11XX_BOOTLOADER_CHIP_MODE_RX:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_RX";
}
case LR11XX_BOOTLOADER_CHIP_MODE_TX:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_TX";
}
case LR11XX_BOOTLOADER_CHIP_MODE_LOC:
{
return ( const char* ) "LR11XX_BOOTLOADER_CHIP_MODE_LOC";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_bootloader_reset_status_to_str( const lr11xx_bootloader_reset_status_t value )
{
switch( value )
{
case LR11XX_BOOTLOADER_RESET_STATUS_CLEARED:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_CLEARED";
}
case LR11XX_BOOTLOADER_RESET_STATUS_ANALOG:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_ANALOG";
}
case LR11XX_BOOTLOADER_RESET_STATUS_EXTERNAL:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_EXTERNAL";
}
case LR11XX_BOOTLOADER_RESET_STATUS_SYSTEM:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_SYSTEM";
}
case LR11XX_BOOTLOADER_RESET_STATUS_WATCHDOG:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_WATCHDOG";
}
case LR11XX_BOOTLOADER_RESET_STATUS_IOCD_RESTART:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_IOCD_RESTART";
}
case LR11XX_BOOTLOADER_RESET_STATUS_RTC_RESTART:
{
return ( const char* ) "LR11XX_BOOTLOADER_RESET_STATUS_RTC_RESTART";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_bootloader_command_status_to_str( const lr11xx_bootloader_command_status_t value )
{
switch( value )
{
case LR11XX_BOOTLOADER_CMD_STATUS_FAIL:
{
return ( const char* ) "LR11XX_BOOTLOADER_CMD_STATUS_FAIL";
}
case LR11XX_BOOTLOADER_CMD_STATUS_PERR:
{
return ( const char* ) "LR11XX_BOOTLOADER_CMD_STATUS_PERR";
}
case LR11XX_BOOTLOADER_CMD_STATUS_OK:
{
return ( const char* ) "LR11XX_BOOTLOADER_CMD_STATUS_OK";
}
case LR11XX_BOOTLOADER_CMD_STATUS_DATA:
{
return ( const char* ) "LR11XX_BOOTLOADER_CMD_STATUS_DATA";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,260 @@
/*!
* @file lr11xx_crypto_engine_types_str.c
*
* @brief Printer helper functions for LR11xx crypto engine types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_crypto_engine_types_str.h"
const char* lr11xx_crypto_element_to_str( const lr11xx_crypto_element_t value )
{
switch( value )
{
case LR11XX_CRYPTO_ELEMENT_CRYPTO_ENGINE:
{
return ( const char* ) "LR11XX_CRYPTO_ELEMENT_CRYPTO_ENGINE";
}
case LR11XX_CRYPTO_ELEMENT_SECURE_ELEMENT:
{
return ( const char* ) "LR11XX_CRYPTO_ELEMENT_SECURE_ELEMENT";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_crypto_status_to_str( const lr11xx_crypto_status_t value )
{
switch( value )
{
case LR11XX_CRYPTO_STATUS_SUCCESS:
{
return ( const char* ) "LR11XX_CRYPTO_STATUS_SUCCESS";
}
case LR11XX_CRYPTO_STATUS_ERROR_FAIL_CMAC:
{
return ( const char* ) "LR11XX_CRYPTO_STATUS_ERROR_FAIL_CMAC";
}
case LR11XX_CRYPTO_STATUS_ERROR_INVALID_KEY_ID:
{
return ( const char* ) "LR11XX_CRYPTO_STATUS_ERROR_INVALID_KEY_ID";
}
case LR11XX_CRYPTO_STATUS_ERROR_BUFFER_SIZE:
{
return ( const char* ) "LR11XX_CRYPTO_STATUS_ERROR_BUFFER_SIZE";
}
case LR11XX_CRYPTO_STATUS_ERROR:
{
return ( const char* ) "LR11XX_CRYPTO_STATUS_ERROR";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_crypto_lorawan_version_to_str( const lr11xx_crypto_lorawan_version_t value )
{
switch( value )
{
case LR11XX_CRYPTO_LORAWAN_VERSION_1_0_X:
{
return ( const char* ) "LR11XX_CRYPTO_LORAWAN_VERSION_1_0_X";
}
case LR11XX_CRYPTO_LORAWAN_VERSION_1_1_X:
{
return ( const char* ) "LR11XX_CRYPTO_LORAWAN_VERSION_1_1_X";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_crypto_keys_idx_to_str( const lr11xx_crypto_keys_idx_t value )
{
switch( value )
{
case LR11XX_CRYPTO_KEYS_IDX_MOTHER_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MOTHER_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_NWK_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_NWK_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_APP_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_APP_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_J_S_ENC_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_J_S_ENC_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_J_S_INT_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_J_S_INT_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_0:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_0";
}
case LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_1:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_1";
}
case LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_2:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_2";
}
case LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_3:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_3";
}
case LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_4:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_4";
}
case LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_5:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP_KE_KEY_5";
}
case LR11XX_CRYPTO_KEYS_IDX_APP_S_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_APP_S_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_F_NWK_S_INT_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_F_NWK_S_INT_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_S_NWK_S_INT_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_S_NWK_S_INT_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_NWK_S_ENC_KEY:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_NWK_S_ENC_KEY";
}
case LR11XX_CRYPTO_KEYS_IDX_RFU_0:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_RFU_0";
}
case LR11XX_CRYPTO_KEYS_IDX_RFU_1:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_RFU_1";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_0:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_0";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_1:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_1";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_2:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_2";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_3:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_APP_S_KEY_3";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_0:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_0";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_1:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_1";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_2:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_2";
}
case LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_3:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_MC_NWK_S_KEY_3";
}
case LR11XX_CRYPTO_KEYS_IDX_GP0:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP0";
}
case LR11XX_CRYPTO_KEYS_IDX_GP1:
{
return ( const char* ) "LR11XX_CRYPTO_KEYS_IDX_GP1";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,165 @@
/*!
* @file lr11xx_lr_fhss_types_str.c
*
* @brief Printer helper functions for LR11xx LRFHSS types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_lr_fhss_types_str.h"
const char* lr_fhss_v1_modulation_type_to_str( const lr_fhss_v1_modulation_type_t value )
{
switch( value )
{
case LR_FHSS_V1_MODULATION_TYPE_GMSK_488:
{
return ( const char* ) "LR_FHSS_V1_MODULATION_TYPE_GMSK_488";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr_fhss_v1_cr_to_str( const lr_fhss_v1_cr_t value )
{
switch( value )
{
case LR_FHSS_V1_CR_5_6:
{
return ( const char* ) "LR_FHSS_V1_CR_5_6";
}
case LR_FHSS_V1_CR_2_3:
{
return ( const char* ) "LR_FHSS_V1_CR_2_3";
}
case LR_FHSS_V1_CR_1_2:
{
return ( const char* ) "LR_FHSS_V1_CR_1_2";
}
case LR_FHSS_V1_CR_1_3:
{
return ( const char* ) "LR_FHSS_V1_CR_1_3";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr_fhss_v1_grid_to_str( const lr_fhss_v1_grid_t value )
{
switch( value )
{
case LR_FHSS_V1_GRID_25391_HZ:
{
return ( const char* ) "LR_FHSS_V1_GRID_25391_HZ";
}
case LR_FHSS_V1_GRID_3906_HZ:
{
return ( const char* ) "LR_FHSS_V1_GRID_3906_HZ";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr_fhss_v1_bw_to_str( const lr_fhss_v1_bw_t value )
{
switch( value )
{
case LR_FHSS_V1_BW_39063_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_39063_HZ";
}
case LR_FHSS_V1_BW_85938_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_85938_HZ";
}
case LR_FHSS_V1_BW_136719_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_136719_HZ";
}
case LR_FHSS_V1_BW_183594_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_183594_HZ";
}
case LR_FHSS_V1_BW_335938_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_335938_HZ";
}
case LR_FHSS_V1_BW_386719_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_386719_HZ";
}
case LR_FHSS_V1_BW_722656_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_722656_HZ";
}
case LR_FHSS_V1_BW_773438_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_773438_HZ";
}
case LR_FHSS_V1_BW_1523438_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_1523438_HZ";
}
case LR_FHSS_V1_BW_1574219_HZ:
{
return ( const char* ) "LR_FHSS_V1_BW_1574219_HZ";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,40 @@
#include "lr11xx_printf_info.h"
#include "lr1121_common/lr1121_common.h"
#include "stdio.h"
// Print the version information of LR1121
void lora_print_version( const void* context )
{
lr11xx_system_version_t ver; // Variable to store version information
if(lr11xx_system_get_version(context, &ver) == 0) // Check if version information is successfully retrieved
{
if(ver.type == LR11XX_SYSTEM_VERSION_TYPE_LR1121) // Check if the device is LR1121
{
printf( "LR1121 information:\n" ); // Print header for LR1121 information
printf( " - Firmware = 0x%04X\n",ver.fw ); // Print firmware version in hexadecimal format
printf( " - Hardware = 0x%02X\n", ver.hw ); // Print hardware version in hexadecimal format
}
else
printf("NO LR1121\r\n"); // Print message if the device is not LR1121
}
}
// Print the temperature information of LR1121
void lora__print_temp( const void* context )
{
uint16_t temp; // Variable to store raw temperature value
float t; // Variable to store calculated temperature in Celsius
lr11xx_system_get_temp(context,&temp); // Retrieve raw temperature value from the device
t = ((((float)(temp&0x07ff)/2047) * 1.35)-0.7295)*(1000/(-1.7)) + 25; // Calculate temperature in Celsius based on the raw value
printf( " LR1121 Temp = %0.2f ℃\n", t); // Print temperature with two decimal places
}
// Print the battery voltage information of LR1121
void lora_print_vbat( const void* context )
{
uint8_t vbat; // Variable to store raw battery voltage value
float v; // Variable to store calculated battery voltage in volts
lr11xx_system_get_vbat(context,&vbat); // Retrieve raw battery voltage value from the device
v = (((float)(5*vbat)/255)-1)*1.35; // Calculate battery voltage in volts based on the raw value
printf( " LR1121 Vbat = %0.2fV\n", v); // Print battery voltage with two decimal places
}

View File

@@ -0,0 +1,926 @@
/*!
* @file lr11xx_radio_types_str.c
*
* @brief Printer helper functions for LR11xx radio types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_radio_types_str.h"
const char* lr11xx_radio_pa_selection_to_str( const lr11xx_radio_pa_selection_t value )
{
switch( value )
{
case LR11XX_RADIO_PA_SEL_LP:
{
return ( const char* ) "LR11XX_RADIO_PA_SEL_LP";
}
case LR11XX_RADIO_PA_SEL_HP:
{
return ( const char* ) "LR11XX_RADIO_PA_SEL_HP";
}
case LR11XX_RADIO_PA_SEL_HF:
{
return ( const char* ) "LR11XX_RADIO_PA_SEL_HF";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_address_filtering_to_str( const lr11xx_radio_gfsk_address_filtering_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_ADDRESS_FILTERING_DISABLE:
{
return ( const char* ) "LR11XX_RADIO_GFSK_ADDRESS_FILTERING_DISABLE";
}
case LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_ADDRESS:
{
return ( const char* ) "LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_ADDRESS";
}
case LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_AND_BROADCAST_ADDRESSES:
{
return ( const char* ) "LR11XX_RADIO_GFSK_ADDRESS_FILTERING_NODE_AND_BROADCAST_ADDRESSES";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_fallback_modes_to_str( const lr11xx_radio_fallback_modes_t value )
{
switch( value )
{
case LR11XX_RADIO_FALLBACK_STDBY_RC:
{
return ( const char* ) "LR11XX_RADIO_FALLBACK_STDBY_RC";
}
case LR11XX_RADIO_FALLBACK_STDBY_XOSC:
{
return ( const char* ) "LR11XX_RADIO_FALLBACK_STDBY_XOSC";
}
case LR11XX_RADIO_FALLBACK_FS:
{
return ( const char* ) "LR11XX_RADIO_FALLBACK_FS";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_ramp_time_to_str( const lr11xx_radio_ramp_time_t value )
{
switch( value )
{
case LR11XX_RADIO_RAMP_16_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_16_US";
}
case LR11XX_RADIO_RAMP_32_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_32_US";
}
case LR11XX_RADIO_RAMP_48_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_48_US";
}
case LR11XX_RADIO_RAMP_64_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_64_US";
}
case LR11XX_RADIO_RAMP_80_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_80_US";
}
case LR11XX_RADIO_RAMP_96_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_96_US";
}
case LR11XX_RADIO_RAMP_112_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_112_US";
}
case LR11XX_RADIO_RAMP_128_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_128_US";
}
case LR11XX_RADIO_RAMP_144_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_144_US";
}
case LR11XX_RADIO_RAMP_160_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_160_US";
}
case LR11XX_RADIO_RAMP_176_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_176_US";
}
case LR11XX_RADIO_RAMP_192_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_192_US";
}
case LR11XX_RADIO_RAMP_208_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_208_US";
}
case LR11XX_RADIO_RAMP_240_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_240_US";
}
case LR11XX_RADIO_RAMP_272_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_272_US";
}
case LR11XX_RADIO_RAMP_304_US:
{
return ( const char* ) "LR11XX_RADIO_RAMP_304_US";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_network_type_to_str( const lr11xx_radio_lora_network_type_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_NETWORK_PRIVATE:
{
return ( const char* ) "LR11XX_RADIO_LORA_NETWORK_PRIVATE";
}
case LR11XX_RADIO_LORA_NETWORK_PUBLIC:
{
return ( const char* ) "LR11XX_RADIO_LORA_NETWORK_PUBLIC";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_sf_to_str( const lr11xx_radio_lora_sf_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_SF5:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF5";
}
case LR11XX_RADIO_LORA_SF6:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF6";
}
case LR11XX_RADIO_LORA_SF7:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF7";
}
case LR11XX_RADIO_LORA_SF8:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF8";
}
case LR11XX_RADIO_LORA_SF9:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF9";
}
case LR11XX_RADIO_LORA_SF10:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF10";
}
case LR11XX_RADIO_LORA_SF11:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF11";
}
case LR11XX_RADIO_LORA_SF12:
{
return ( const char* ) "LR11XX_RADIO_LORA_SF12";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_bw_to_str( const lr11xx_radio_lora_bw_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_BW_10:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_10";
}
case LR11XX_RADIO_LORA_BW_15:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_15";
}
case LR11XX_RADIO_LORA_BW_20:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_20";
}
case LR11XX_RADIO_LORA_BW_31:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_31";
}
case LR11XX_RADIO_LORA_BW_41:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_41";
}
case LR11XX_RADIO_LORA_BW_62:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_62";
}
case LR11XX_RADIO_LORA_BW_125:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_125";
}
case LR11XX_RADIO_LORA_BW_250:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_250";
}
case LR11XX_RADIO_LORA_BW_500:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_500";
}
case LR11XX_RADIO_LORA_BW_200:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_200";
}
case LR11XX_RADIO_LORA_BW_400:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_400";
}
case LR11XX_RADIO_LORA_BW_800:
{
return ( const char* ) "LR11XX_RADIO_LORA_BW_800";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_cr_to_str( const lr11xx_radio_lora_cr_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_NO_CR:
{
return ( const char* ) "LR11XX_RADIO_LORA_NO_CR";
}
case LR11XX_RADIO_LORA_CR_4_5:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_4_5";
}
case LR11XX_RADIO_LORA_CR_4_6:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_4_6";
}
case LR11XX_RADIO_LORA_CR_4_7:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_4_7";
}
case LR11XX_RADIO_LORA_CR_4_8:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_4_8";
}
case LR11XX_RADIO_LORA_CR_LI_4_5:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_LI_4_5";
}
case LR11XX_RADIO_LORA_CR_LI_4_6:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_LI_4_6";
}
case LR11XX_RADIO_LORA_CR_LI_4_8:
{
return ( const char* ) "LR11XX_RADIO_LORA_CR_LI_4_8";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_intermediary_mode_to_str( const lr11xx_radio_intermediary_mode_t value )
{
switch( value )
{
case LR11XX_RADIO_MODE_SLEEP:
{
return ( const char* ) "LR11XX_RADIO_MODE_SLEEP";
}
case LR11XX_RADIO_MODE_STANDBY_RC:
{
return ( const char* ) "LR11XX_RADIO_MODE_STANDBY_RC";
}
case LR11XX_RADIO_MODE_STANDBY_XOSC:
{
return ( const char* ) "LR11XX_RADIO_MODE_STANDBY_XOSC";
}
case LR11XX_RADIO_MODE_FS:
{
return ( const char* ) "LR11XX_RADIO_MODE_FS";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_crc_type_to_str( const lr11xx_radio_gfsk_crc_type_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_CRC_OFF:
{
return ( const char* ) "LR11XX_RADIO_GFSK_CRC_OFF";
}
case LR11XX_RADIO_GFSK_CRC_1_BYTE:
{
return ( const char* ) "LR11XX_RADIO_GFSK_CRC_1_BYTE";
}
case LR11XX_RADIO_GFSK_CRC_2_BYTES:
{
return ( const char* ) "LR11XX_RADIO_GFSK_CRC_2_BYTES";
}
case LR11XX_RADIO_GFSK_CRC_1_BYTE_INV:
{
return ( const char* ) "LR11XX_RADIO_GFSK_CRC_1_BYTE_INV";
}
case LR11XX_RADIO_GFSK_CRC_2_BYTES_INV:
{
return ( const char* ) "LR11XX_RADIO_GFSK_CRC_2_BYTES_INV";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_dc_free_to_str( const lr11xx_radio_gfsk_dc_free_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_DC_FREE_OFF:
{
return ( const char* ) "LR11XX_RADIO_GFSK_DC_FREE_OFF";
}
case LR11XX_RADIO_GFSK_DC_FREE_WHITENING:
{
return ( const char* ) "LR11XX_RADIO_GFSK_DC_FREE_WHITENING";
}
case LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP:
{
return ( const char* ) "LR11XX_RADIO_GFSK_DC_FREE_WHITENING_SX128X_COMP";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_pkt_len_modes_to_str( const lr11xx_radio_gfsk_pkt_len_modes_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_PKT_FIX_LEN:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PKT_FIX_LEN";
}
case LR11XX_RADIO_GFSK_PKT_VAR_LEN:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PKT_VAR_LEN";
}
case LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PKT_VAR_LEN_SX128X_COMP";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_preamble_detector_to_str( const lr11xx_radio_gfsk_preamble_detector_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_OFF:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_OFF";
}
case LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_8BITS:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_8BITS";
}
case LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_16BITS:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_16BITS";
}
case LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_24BITS:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_24BITS";
}
case LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_32BITS:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PREAMBLE_DETECTOR_MIN_32BITS";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_crc_to_str( const lr11xx_radio_lora_crc_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_CRC_OFF:
{
return ( const char* ) "LR11XX_RADIO_LORA_CRC_OFF";
}
case LR11XX_RADIO_LORA_CRC_ON:
{
return ( const char* ) "LR11XX_RADIO_LORA_CRC_ON";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_pkt_len_modes_to_str( const lr11xx_radio_lora_pkt_len_modes_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_PKT_EXPLICIT:
{
return ( const char* ) "LR11XX_RADIO_LORA_PKT_EXPLICIT";
}
case LR11XX_RADIO_LORA_PKT_IMPLICIT:
{
return ( const char* ) "LR11XX_RADIO_LORA_PKT_IMPLICIT";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lora_iq_to_str( const lr11xx_radio_lora_iq_t value )
{
switch( value )
{
case LR11XX_RADIO_LORA_IQ_STANDARD:
{
return ( const char* ) "LR11XX_RADIO_LORA_IQ_STANDARD";
}
case LR11XX_RADIO_LORA_IQ_INVERTED:
{
return ( const char* ) "LR11XX_RADIO_LORA_IQ_INVERTED";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_pkt_type_to_str( const lr11xx_radio_pkt_type_t value )
{
switch( value )
{
case LR11XX_RADIO_PKT_NONE:
{
return ( const char* ) "LR11XX_RADIO_PKT_NONE";
}
case LR11XX_RADIO_PKT_TYPE_GFSK:
{
return ( const char* ) "LR11XX_RADIO_PKT_TYPE_GFSK";
}
case LR11XX_RADIO_PKT_TYPE_LORA:
{
return ( const char* ) "LR11XX_RADIO_PKT_TYPE_LORA";
}
case LR11XX_RADIO_PKT_TYPE_BPSK:
{
return ( const char* ) "LR11XX_RADIO_PKT_TYPE_BPSK";
}
case LR11XX_RADIO_PKT_TYPE_LR_FHSS:
{
return ( const char* ) "LR11XX_RADIO_PKT_TYPE_LR_FHSS";
}
case LR11XX_RADIO_PKT_TYPE_RTTOF:
{
return ( const char* ) "LR11XX_RADIO_PKT_TYPE_RTTOF";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_pa_reg_supply_to_str( const lr11xx_radio_pa_reg_supply_t value )
{
switch( value )
{
case LR11XX_RADIO_PA_REG_SUPPLY_VREG:
{
return ( const char* ) "LR11XX_RADIO_PA_REG_SUPPLY_VREG";
}
case LR11XX_RADIO_PA_REG_SUPPLY_VBAT:
{
return ( const char* ) "LR11XX_RADIO_PA_REG_SUPPLY_VBAT";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_rx_duty_cycle_mode_to_str( const lr11xx_radio_rx_duty_cycle_mode_t value )
{
switch( value )
{
case LR11XX_RADIO_RX_DUTY_CYCLE_MODE_RX:
{
return ( const char* ) "LR11XX_RADIO_RX_DUTY_CYCLE_MODE_RX";
}
case LR11XX_RADIO_RX_DUTY_CYCLE_MODE_CAD:
{
return ( const char* ) "LR11XX_RADIO_RX_DUTY_CYCLE_MODE_CAD";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_bw_to_str( const lr11xx_radio_gfsk_bw_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_BW_4800:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_4800";
}
case LR11XX_RADIO_GFSK_BW_5800:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_5800";
}
case LR11XX_RADIO_GFSK_BW_7300:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_7300";
}
case LR11XX_RADIO_GFSK_BW_9700:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_9700";
}
case LR11XX_RADIO_GFSK_BW_11700:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_11700";
}
case LR11XX_RADIO_GFSK_BW_14600:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_14600";
}
case LR11XX_RADIO_GFSK_BW_19500:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_19500";
}
case LR11XX_RADIO_GFSK_BW_23400:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_23400";
}
case LR11XX_RADIO_GFSK_BW_29300:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_29300";
}
case LR11XX_RADIO_GFSK_BW_39000:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_39000";
}
case LR11XX_RADIO_GFSK_BW_46900:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_46900";
}
case LR11XX_RADIO_GFSK_BW_58600:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_58600";
}
case LR11XX_RADIO_GFSK_BW_78200:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_78200";
}
case LR11XX_RADIO_GFSK_BW_93800:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_93800";
}
case LR11XX_RADIO_GFSK_BW_117300:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_117300";
}
case LR11XX_RADIO_GFSK_BW_156200:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_156200";
}
case LR11XX_RADIO_GFSK_BW_187200:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_187200";
}
case LR11XX_RADIO_GFSK_BW_234300:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_234300";
}
case LR11XX_RADIO_GFSK_BW_312000:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_312000";
}
case LR11XX_RADIO_GFSK_BW_373600:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_373600";
}
case LR11XX_RADIO_GFSK_BW_467000:
{
return ( const char* ) "LR11XX_RADIO_GFSK_BW_467000";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_cad_exit_mode_to_str( const lr11xx_radio_cad_exit_mode_t value )
{
switch( value )
{
case LR11XX_RADIO_CAD_EXIT_MODE_STANDBYRC:
{
return ( const char* ) "LR11XX_RADIO_CAD_EXIT_MODE_STANDBYRC";
}
case LR11XX_RADIO_CAD_EXIT_MODE_RX:
{
return ( const char* ) "LR11XX_RADIO_CAD_EXIT_MODE_RX";
}
case LR11XX_RADIO_CAD_EXIT_MODE_TX:
{
return ( const char* ) "LR11XX_RADIO_CAD_EXIT_MODE_TX";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_gfsk_pulse_shape_to_str( const lr11xx_radio_gfsk_pulse_shape_t value )
{
switch( value )
{
case LR11XX_RADIO_GFSK_PULSE_SHAPE_OFF:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PULSE_SHAPE_OFF";
}
case LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_03:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_03";
}
case LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_05:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_05";
}
case LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_07:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_07";
}
case LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_1:
{
return ( const char* ) "LR11XX_RADIO_GFSK_PULSE_SHAPE_BT_1";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_bpsk_pulse_shape_to_str( const lr11xx_radio_bpsk_pulse_shape_t value )
{
switch( value )
{
case LR11XX_RADIO_DBPSK_PULSE_SHAPE:
{
return ( const char* ) "LR11XX_RADIO_DBPSK_PULSE_SHAPE";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lr_fhss_bitrate_to_str( const lr11xx_radio_lr_fhss_bitrate_t value )
{
switch( value )
{
case LR11XX_RADIO_LR_FHSS_BITRATE_488_BPS:
{
return ( const char* ) "LR11XX_RADIO_LR_FHSS_BITRATE_488_BPS";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_radio_lr_fhss_pulse_shape_to_str( const lr11xx_radio_lr_fhss_pulse_shape_t value )
{
switch( value )
{
case LR11XX_RADIO_LR_FHSS_PULSE_SHAPE_BT_1:
{
return ( const char* ) "LR11XX_RADIO_LR_FHSS_PULSE_SHAPE_BT_1";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,57 @@
/*!
* @file lr11xx_rttof_types_str.c
*
* @brief Printer helper functions for LR11xx RTToF types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_rttof_types_str.h"
const char* lr11xx_rttof_result_type_to_str( const lr11xx_rttof_result_type_t value )
{
switch( value )
{
case LR11XX_RTTOF_RESULT_TYPE_RAW:
{
return ( const char* ) "LR11XX_RTTOF_RESULT_TYPE_RAW";
}
case LR11XX_RTTOF_RESULT_TYPE_RSSI:
{
return ( const char* ) "LR11XX_RTTOF_RESULT_TYPE_RSSI";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,325 @@
/*!
* @file lr11xx_system_types_str.c
*
* @brief Printer helper functions for LR11xx system types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_system_types_str.h"
const char* lr11xx_system_chip_modes_to_str( const lr11xx_system_chip_modes_t value )
{
switch( value )
{
case LR11XX_SYSTEM_CHIP_MODE_SLEEP:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_SLEEP";
}
case LR11XX_SYSTEM_CHIP_MODE_STBY_RC:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_STBY_RC";
}
case LR11XX_SYSTEM_CHIP_MODE_STBY_XOSC:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_STBY_XOSC";
}
case LR11XX_SYSTEM_CHIP_MODE_FS:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_FS";
}
case LR11XX_SYSTEM_CHIP_MODE_RX:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_RX";
}
case LR11XX_SYSTEM_CHIP_MODE_TX:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_TX";
}
case LR11XX_SYSTEM_CHIP_MODE_LOC:
{
return ( const char* ) "LR11XX_SYSTEM_CHIP_MODE_LOC";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_reset_status_to_str( const lr11xx_system_reset_status_t value )
{
switch( value )
{
case LR11XX_SYSTEM_RESET_STATUS_CLEARED:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_CLEARED";
}
case LR11XX_SYSTEM_RESET_STATUS_ANALOG:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_ANALOG";
}
case LR11XX_SYSTEM_RESET_STATUS_EXTERNAL:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_EXTERNAL";
}
case LR11XX_SYSTEM_RESET_STATUS_SYSTEM:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_SYSTEM";
}
case LR11XX_SYSTEM_RESET_STATUS_WATCHDOG:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_WATCHDOG";
}
case LR11XX_SYSTEM_RESET_STATUS_IOCD_RESTART:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_IOCD_RESTART";
}
case LR11XX_SYSTEM_RESET_STATUS_RTC_RESTART:
{
return ( const char* ) "LR11XX_SYSTEM_RESET_STATUS_RTC_RESTART";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_command_status_to_str( const lr11xx_system_command_status_t value )
{
switch( value )
{
case LR11XX_SYSTEM_CMD_STATUS_FAIL:
{
return ( const char* ) "LR11XX_SYSTEM_CMD_STATUS_FAIL";
}
case LR11XX_SYSTEM_CMD_STATUS_PERR:
{
return ( const char* ) "LR11XX_SYSTEM_CMD_STATUS_PERR";
}
case LR11XX_SYSTEM_CMD_STATUS_OK:
{
return ( const char* ) "LR11XX_SYSTEM_CMD_STATUS_OK";
}
case LR11XX_SYSTEM_CMD_STATUS_DATA:
{
return ( const char* ) "LR11XX_SYSTEM_CMD_STATUS_DATA";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_lfclk_cfg_to_str( const lr11xx_system_lfclk_cfg_t value )
{
switch( value )
{
case LR11XX_SYSTEM_LFCLK_RC:
{
return ( const char* ) "LR11XX_SYSTEM_LFCLK_RC";
}
case LR11XX_SYSTEM_LFCLK_XTAL:
{
return ( const char* ) "LR11XX_SYSTEM_LFCLK_XTAL";
}
case LR11XX_SYSTEM_LFCLK_EXT:
{
return ( const char* ) "LR11XX_SYSTEM_LFCLK_EXT";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_reg_mode_to_str( const lr11xx_system_reg_mode_t value )
{
switch( value )
{
case LR11XX_SYSTEM_REG_MODE_LDO:
{
return ( const char* ) "LR11XX_SYSTEM_REG_MODE_LDO";
}
case LR11XX_SYSTEM_REG_MODE_DCDC:
{
return ( const char* ) "LR11XX_SYSTEM_REG_MODE_DCDC";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_infopage_id_to_str( const lr11xx_system_infopage_id_t value )
{
switch( value )
{
case LR11XX_SYSTEM_INFOPAGE_0:
{
return ( const char* ) "LR11XX_SYSTEM_INFOPAGE_0";
}
case LR11XX_SYSTEM_INFOPAGE_1:
{
return ( const char* ) "LR11XX_SYSTEM_INFOPAGE_1";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_standby_cfg_to_str( const lr11xx_system_standby_cfg_t value )
{
switch( value )
{
case LR11XX_SYSTEM_STANDBY_CFG_RC:
{
return ( const char* ) "LR11XX_SYSTEM_STANDBY_CFG_RC";
}
case LR11XX_SYSTEM_STANDBY_CFG_XOSC:
{
return ( const char* ) "LR11XX_SYSTEM_STANDBY_CFG_XOSC";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_tcxo_supply_voltage_to_str( const lr11xx_system_tcxo_supply_voltage_t value )
{
switch( value )
{
case LR11XX_SYSTEM_TCXO_CTRL_1_6V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_1_6V";
}
case LR11XX_SYSTEM_TCXO_CTRL_1_7V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_1_7V";
}
case LR11XX_SYSTEM_TCXO_CTRL_1_8V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_1_8V";
}
case LR11XX_SYSTEM_TCXO_CTRL_2_2V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_2_2V";
}
case LR11XX_SYSTEM_TCXO_CTRL_2_4V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_2_4V";
}
case LR11XX_SYSTEM_TCXO_CTRL_2_7V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_2_7V";
}
case LR11XX_SYSTEM_TCXO_CTRL_3_0V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_3_0V";
}
case LR11XX_SYSTEM_TCXO_CTRL_3_3V:
{
return ( const char* ) "LR11XX_SYSTEM_TCXO_CTRL_3_3V";
}
default:
{
return ( const char* ) "Unknown";
}
}
}
const char* lr11xx_system_version_type_to_str( const lr11xx_system_version_type_t value )
{
switch( value )
{
case LR11XX_SYSTEM_VERSION_TYPE_LR1110:
{
return ( const char* ) "LR11XX_SYSTEM_VERSION_TYPE_LR1110";
}
case LR11XX_SYSTEM_VERSION_TYPE_LR1120:
{
return ( const char* ) "LR11XX_SYSTEM_VERSION_TYPE_LR1120";
}
case LR11XX_SYSTEM_VERSION_TYPE_LR1121:
{
return ( const char* ) "LR11XX_SYSTEM_VERSION_TYPE_LR1121";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,57 @@
/*!
* @file lr11xx_types_str.c
*
* @brief Printer helper functions for LR11xx types
*
* @copyright
* The Clear BSD License
* Copyright Semtech Corporation 2023. 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 "lr11xx_types_str.h"
const char* lr11xx_status_to_str( const lr11xx_status_t value )
{
switch( value )
{
case LR11XX_STATUS_OK:
{
return ( const char* ) "LR11XX_STATUS_OK";
}
case LR11XX_STATUS_ERROR:
{
return ( const char* ) "LR11XX_STATUS_ERROR";
}
default:
{
return ( const char* ) "Unknown";
}
}
}

View File

@@ -0,0 +1,294 @@
/*!
* @file lr11xx_bootloader.c
*
* @brief Bootloader driver implementation for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_bootloader.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR11XX_FLASH_DATA_MAX_LENGTH_UINT32 ( 64 )
#define LR11XX_FLASH_DATA_MAX_LENGTH_UINT8 ( LR11XX_FLASH_DATA_MAX_LENGTH_UINT32 * 4 )
#define LR11XX_BL_CMD_NO_PARAM_LENGTH ( 2 )
#define LR11XX_BL_GET_STATUS_CMD_LENGTH ( 2 + 4 )
#define LR11XX_BL_VERSION_CMD_LENGTH LR11XX_BL_CMD_NO_PARAM_LENGTH
#define LR11XX_BL_ERASE_FLASH_CMD_LENGTH LR11XX_BL_CMD_NO_PARAM_LENGTH
#define LR11XX_BL_WRITE_FLASH_ENCRYPTED_CMD_LENGTH ( LR11XX_BL_CMD_NO_PARAM_LENGTH + 4 )
#define LR11XX_BL_REBOOT_CMD_LENGTH ( LR11XX_BL_CMD_NO_PARAM_LENGTH + 1 )
#define LR11XX_BL_GET_PIN_CMD_LENGTH ( LR11XX_BL_CMD_NO_PARAM_LENGTH )
#define LR11XX_BL_READ_CHIP_EUI_CMD_LENGTH ( LR11XX_BL_CMD_NO_PARAM_LENGTH )
#define LR11XX_BL_READ_JOIN_EUI_CMD_LENGTH ( LR11XX_BL_CMD_NO_PARAM_LENGTH )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for bootloader-related operations
*/
enum
{
LR11XX_BL_GET_STATUS_OC = 0x0100,
LR11XX_BL_GET_VERSION_OC = 0x0101,
LR11XX_BL_ERASE_FLASH_OC = 0x8000,
LR11XX_BL_WRITE_FLASH_ENCRYPTED_OC = 0x8003,
LR11XX_BL_REBOOT_OC = 0x8005,
LR11XX_BL_GET_PIN_OC = 0x800B,
LR11XX_BL_READ_CHIP_EUI_OC = 0x800C,
LR11XX_BL_READ_JOIN_EUI_OC = 0x800D,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Returns the minimum of the operand given as parameter and the maximum allowed block size
*
* @param [in] operand Size to compare
*
* @returns Minimum between operand and @ref LR11XX_FLASH_DATA_MAX_LENGTH_UINT32
*/
static uint8_t lr11xx_bootloader_get_min_from_operand_and_max_block_size( uint32_t operand );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr11xx_status_t lr11xx_bootloader_get_status( const void* context, lr11xx_bootloader_stat1_t* stat1,
lr11xx_bootloader_stat2_t* stat2,
lr11xx_bootloader_irq_mask_t* irq_status )
{
uint8_t data[LR11XX_BL_GET_STATUS_CMD_LENGTH] = { 0 };
const lr11xx_status_t status =
( lr11xx_status_t ) lr11xx_hal_direct_read( context, data, LR11XX_BL_GET_STATUS_CMD_LENGTH );
if( status == LR11XX_STATUS_OK )
{
stat1->is_interrupt_active = ( ( data[0] & 0x01 ) != 0 ) ? true : false;
stat1->command_status = ( lr11xx_bootloader_command_status_t ) ( data[0] >> 1 );
stat2->is_running_from_flash = ( ( data[1] & 0x01 ) != 0 ) ? true : false;
stat2->chip_mode = ( lr11xx_bootloader_chip_modes_t ) ( ( data[1] & 0x0F ) >> 1 );
stat2->reset_status = ( lr11xx_bootloader_reset_status_t ) ( ( data[1] & 0xF0 ) >> 4 );
*irq_status =
( ( lr11xx_bootloader_irq_mask_t ) data[2] << 24 ) + ( ( lr11xx_bootloader_irq_mask_t ) data[3] << 16 ) +
( ( lr11xx_bootloader_irq_mask_t ) data[4] << 8 ) + ( ( lr11xx_bootloader_irq_mask_t ) data[5] << 0 );
}
return status;
}
lr11xx_status_t lr11xx_bootloader_clear_reset_status_info( const void* context )
{
const uint8_t cbuffer[LR11XX_BL_CMD_NO_PARAM_LENGTH] = {
( uint8_t ) ( LR11XX_BL_GET_STATUS_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_GET_STATUS_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_BL_CMD_NO_PARAM_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_bootloader_get_version( const void* context, lr11xx_bootloader_version_t* version )
{
const uint8_t cbuffer[LR11XX_BL_VERSION_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_GET_VERSION_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_GET_VERSION_OC >> 0 ),
};
uint8_t rbuffer[LR11XX_BL_VERSION_LENGTH] = { 0x00 };
const lr11xx_status_t status = ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_BL_VERSION_CMD_LENGTH,
rbuffer, LR11XX_BL_VERSION_LENGTH );
if( status == LR11XX_STATUS_OK )
{
version->hw = rbuffer[0];
version->type = rbuffer[1];
version->fw = ( ( uint16_t ) rbuffer[2] << 8 ) + ( uint16_t ) rbuffer[3];
}
return status;
}
lr11xx_status_t lr11xx_bootloader_erase_flash( const void* context )
{
const uint8_t cbuffer[LR11XX_BL_ERASE_FLASH_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_ERASE_FLASH_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_ERASE_FLASH_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_BL_ERASE_FLASH_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_bootloader_write_flash_encrypted( const void* context, const uint32_t offset_in_byte,
const uint32_t* data, uint8_t length_in_word )
{
const uint8_t cbuffer[LR11XX_BL_WRITE_FLASH_ENCRYPTED_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_WRITE_FLASH_ENCRYPTED_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_WRITE_FLASH_ENCRYPTED_OC >> 0 ),
( uint8_t ) ( offset_in_byte >> 24 ),
( uint8_t ) ( offset_in_byte >> 16 ),
( uint8_t ) ( offset_in_byte >> 8 ),
( uint8_t ) ( offset_in_byte >> 0 ),
};
uint8_t cdata[LR11XX_FLASH_DATA_MAX_LENGTH_UINT8] = { 0 };
for( uint8_t index = 0; index < length_in_word; index++ )
{
uint8_t* cdata_local = &cdata[index * sizeof( uint32_t )];
cdata_local[0] = ( uint8_t ) ( data[index] >> 24 );
cdata_local[1] = ( uint8_t ) ( data[index] >> 16 );
cdata_local[2] = ( uint8_t ) ( data[index] >> 8 );
cdata_local[3] = ( uint8_t ) ( data[index] >> 0 );
}
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_BL_WRITE_FLASH_ENCRYPTED_CMD_LENGTH, cdata,
length_in_word * sizeof( uint32_t ) );
}
lr11xx_status_t lr11xx_bootloader_write_flash_encrypted_full( const void* context, const uint32_t offset_in_byte,
const uint32_t* buffer, const uint32_t length_in_word )
{
uint32_t remaining_length = length_in_word;
uint32_t local_offset = offset_in_byte;
uint32_t loop = 0;
while( remaining_length != 0 )
{
const lr11xx_status_t status = lr11xx_bootloader_write_flash_encrypted(
context, local_offset, buffer + loop * LR11XX_FLASH_DATA_MAX_LENGTH_UINT32,
lr11xx_bootloader_get_min_from_operand_and_max_block_size( remaining_length ) );
if( status != LR11XX_STATUS_OK )
{
return status;
}
local_offset += LR11XX_FLASH_DATA_MAX_LENGTH_UINT8;
remaining_length = ( remaining_length < LR11XX_FLASH_DATA_MAX_LENGTH_UINT32 )
? 0
: ( remaining_length - LR11XX_FLASH_DATA_MAX_LENGTH_UINT32 );
loop++;
}
return LR11XX_STATUS_OK;
}
lr11xx_status_t lr11xx_bootloader_reboot( const void* context, const bool stay_in_bootloader )
{
const uint8_t cbuffer[LR11XX_BL_REBOOT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_REBOOT_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_REBOOT_OC >> 0 ),
( stay_in_bootloader == true ) ? 0x03 : 0x00,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_BL_REBOOT_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_bootloader_read_pin( const void* context, lr11xx_bootloader_pin_t pin )
{
const uint8_t cbuffer[LR11XX_BL_GET_PIN_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_GET_PIN_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_GET_PIN_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_BL_GET_PIN_CMD_LENGTH, pin,
LR11XX_BL_PIN_LENGTH );
}
lr11xx_status_t lr11xx_bootloader_read_chip_eui( const void* context, lr11xx_bootloader_chip_eui_t chip_eui )
{
const uint8_t cbuffer[LR11XX_BL_READ_CHIP_EUI_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_READ_CHIP_EUI_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_READ_CHIP_EUI_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_BL_READ_CHIP_EUI_CMD_LENGTH, chip_eui,
LR11XX_BL_CHIP_EUI_LENGTH );
}
lr11xx_status_t lr11xx_bootloader_read_join_eui( const void* context, lr11xx_bootloader_join_eui_t join_eui )
{
const uint8_t cbuffer[LR11XX_BL_READ_JOIN_EUI_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_BL_READ_JOIN_EUI_OC >> 8 ),
( uint8_t ) ( LR11XX_BL_READ_JOIN_EUI_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_BL_READ_JOIN_EUI_CMD_LENGTH, join_eui,
LR11XX_BL_JOIN_EUI_LENGTH );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
uint8_t lr11xx_bootloader_get_min_from_operand_and_max_block_size( uint32_t operand )
{
if( operand > LR11XX_FLASH_DATA_MAX_LENGTH_UINT32 )
{
return LR11XX_FLASH_DATA_MAX_LENGTH_UINT32;
}
else
{
return ( uint8_t ) operand;
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,589 @@
/*!
* @file lr11xx_crypto_engine.c
*
* @brief Cryptographic engine driver implementation for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_crypto_engine.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32 ( 64 )
#define LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT8 ( LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32 * 4 )
#define LR11XX_CRYPTO_SELECT_CMD_LENGTH ( 2 + 1 )
#define LR11XX_CRYPTO_SET_KEY_CMD_LENGTH ( 2 + 17 )
#define LR11XX_CRYPTO_DERIVE_KEY_CMD_LENGTH ( 2 + 18 )
#define LR11XX_CRYPTO_PROCESS_JOIN_ACCEPT_CMD_LENGTH ( 2 + 3 + 12 + 32 )
#define LR11XX_CRYPTO_COMPUTE_AES_CMAC_CMD_LENGTH ( 2 + 1 + 272 )
#define LR11XX_CRYPTO_VERIFY_AES_CMAC_CMD_LENGTH ( 2 + 1 + 4 + 256 )
#define LR11XX_CRYPTO_AES_ENCRYPT_CMD_LENGTH ( 2 + 1 + 256 )
#define LR11XX_CRYPTO_AES_DECRYPT_CMD_LENGTH ( 2 + 1 + 256 )
#define LR11XX_CRYPTO_STORE_TO_FLASH_CMD_LENGTH ( 2 )
#define LR11XX_CRYPTO_RESTORE_FROM_FLASH_CMD_LENGTH ( 2 )
#define LR11XX_CRYPTO_SET_PARAMETER_CMD_LENGTH ( 2 + 1 + 4 )
#define LR11XX_CRYPTO_GET_PARAMETER_CMD_LENGTH ( 2 + 1 )
#define LR11XX_CRYPTO_CHECK_ENCRYPTED_FW_IMAGE_CMD_LENGTH ( 2 + 4 )
#define LR11XX_CRYPTO_GET_CHECK_ENCRYPTED_FW_IMAGE_RESULT_CMD_LENGTH ( 2 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for crypto-related operations
*/
enum
{
LR11XX_CRYPTO_SELECT_OC = 0x0500,
LR11XX_CRYPTO_SET_KEY_OC = 0x0502,
LR11XX_CRYPTO_DERIVE_KEY_OC = 0x0503,
LR11XX_CRYPTO_PROCESS_JOIN_ACCEPT_OC = 0x0504,
LR11XX_CRYPTO_COMPUTE_AES_CMAC_OC = 0x0505,
LR11XX_CRYPTO_VERIFY_AES_CMAC_OC = 0x0506,
LR11XX_CRYPTO_ENCRYPT_AES_01_OC = 0x0507,
LR11XX_CRYPTO_ENCRYPT_AES_OC = 0x0508,
LR11XX_CRYPTO_DECRYPT_AES_OC = 0x0509,
LR11XX_CRYPTO_STORE_TO_FLASH_OC = 0x050A,
LR11XX_CRYPTO_RESTORE_FROM_FLASH_OC = 0x050B,
LR11XX_CRYPTO_SET_PARAMETER_OC = 0x050D,
LR11XX_CRYPTO_GET_PARAMETER_OC = 0x050E,
LR11XX_CRYPTO_CHECK_ENCRYPTED_FW_IMAGE_OC = 0x050F,
LR11XX_CRYPTO_GET_CHECK_ENCRYPTED_FW_IMAGE_RESULT_OC = 0x0510,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Helper function that fill the cbuffer provided in first argument with the command opcode, the key id
* and the data to encrypt/decrypt/compute aes cmac
*
* @param [out] cbuffer Buffer used to build the frame
* @param [in] opcode Opcode to be added to the frame
* @param [in] key_id Key ID to be added to the frame
* @param [in] data Data to be added to the frame
* @param [in] length Number of bytes from data to be added to the frame
*
* @warning The caller MUST ensure cbuffer is array is big enough to contain opcode, key_id, and data!
*/
static void lr11xx_crypto_fill_cbuffer_opcode_key_data( uint8_t* cbuffer, uint16_t opcode, uint8_t key_id,
const uint8_t* data, uint16_t length );
/*!
* @brief Returns the minimum of the operand given as parameter and the maximum allowed block size
*
* @param [in] operand Size to compare
*
* @returns Minimum between operand and @ref LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32
*/
static uint8_t lr11xx_crypto_get_min_from_operand_and_max_block_size( uint32_t operand );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr11xx_status_t lr11xx_crypto_select( const void* context, const lr11xx_crypto_element_t element )
{
uint8_t cbuffer[LR11XX_CRYPTO_SELECT_CMD_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_SELECT_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_SELECT_OC >> 0 );
cbuffer[2] = element;
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_CRYPTO_SELECT_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_crypto_set_key( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const lr11xx_crypto_key_t key )
{
uint8_t cbuffer[LR11XX_CRYPTO_SET_KEY_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_SET_KEY_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_SET_KEY_OC >> 0 );
cbuffer[2] = key_id;
for( uint8_t index = 0; index < sizeof( lr11xx_crypto_key_t ); index++ )
{
cbuffer[3 + index] = key[index];
}
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, LR11XX_CRYPTO_SET_KEY_CMD_LENGTH, rbuffer, LR11XX_CRYPTO_STATUS_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_derive_key( const void* context, lr11xx_crypto_status_t* status, const uint8_t src_key_id,
const uint8_t dest_key_id, const lr11xx_crypto_nonce_t nonce )
{
uint8_t cbuffer[LR11XX_CRYPTO_DERIVE_KEY_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_DERIVE_KEY_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_DERIVE_KEY_OC >> 0 );
cbuffer[2] = src_key_id;
cbuffer[3] = dest_key_id;
for( uint8_t index = 0; index < LR11XX_CRYPTO_NONCE_LENGTH; index++ )
{
cbuffer[4 + index] = nonce[index];
}
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, LR11XX_CRYPTO_DERIVE_KEY_CMD_LENGTH, rbuffer, LR11XX_CRYPTO_STATUS_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_process_join_accept( const void* context, lr11xx_crypto_status_t* status,
const uint8_t dec_key_id, const uint8_t ver_key_id,
const lr11xx_crypto_lorawan_version_t lorawan_version,
const uint8_t* header, const uint8_t* data_in, const uint8_t length,
uint8_t* data_out )
{
uint8_t cbuffer[LR11XX_CRYPTO_PROCESS_JOIN_ACCEPT_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH + 32] = { 0x00 };
uint8_t header_length = ( lorawan_version == 0 ) ? 1 : 12;
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_PROCESS_JOIN_ACCEPT_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_PROCESS_JOIN_ACCEPT_OC >> 0 );
cbuffer[2] = dec_key_id;
cbuffer[3] = ver_key_id;
cbuffer[4] = ( uint8_t ) lorawan_version;
for( uint8_t index = 0; index < header_length; index++ )
{
cbuffer[5 + index] = header[index];
}
for( uint8_t index = 0; index < length; index++ )
{
cbuffer[5 + header_length + index] = data_in[index];
}
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, 2 + 3 + header_length + length, rbuffer, 1 + length );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
if( *status == LR11XX_CRYPTO_STATUS_SUCCESS )
{
for( uint8_t index = 0; index < length; index++ )
{
data_out[index] = rbuffer[1 + index];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_compute_aes_cmac( const void* context, lr11xx_crypto_status_t* status,
const uint8_t key_id, const uint8_t* data, const uint16_t length,
lr11xx_crypto_mic_t mic )
{
uint8_t cbuffer[LR11XX_CRYPTO_COMPUTE_AES_CMAC_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_MIC_LENGTH] = { 0x00 };
lr11xx_crypto_fill_cbuffer_opcode_key_data( cbuffer, LR11XX_CRYPTO_COMPUTE_AES_CMAC_OC, key_id, data, length );
const lr11xx_hal_status_t hal_status = lr11xx_hal_read( context, cbuffer, 3 + length, rbuffer,
LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_MIC_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
if( *status == LR11XX_CRYPTO_STATUS_SUCCESS )
{
for( uint8_t index = 0; index < LR11XX_CRYPTO_MIC_LENGTH; index++ )
{
mic[index] = rbuffer[1 + index];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_verify_aes_cmac( const void* context, lr11xx_crypto_status_t* status,
const uint8_t key_id, const uint8_t* data, const uint16_t length,
const lr11xx_crypto_mic_t mic )
{
uint8_t cbuffer[LR11XX_CRYPTO_VERIFY_AES_CMAC_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_VERIFY_AES_CMAC_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_VERIFY_AES_CMAC_OC >> 0 );
cbuffer[2] = key_id;
for( uint8_t index = 0; index < LR11XX_CRYPTO_MIC_LENGTH; index++ )
{
cbuffer[3 + index] = mic[index];
}
for( uint16_t index = 0; index < length; index++ )
{
cbuffer[3 + LR11XX_CRYPTO_MIC_LENGTH + index] = data[index];
}
const lr11xx_hal_status_t hal_status = lr11xx_hal_read( context, cbuffer, 3 + LR11XX_CRYPTO_MIC_LENGTH + length,
rbuffer, LR11XX_CRYPTO_STATUS_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_aes_encrypt_01( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const uint8_t* data, const uint16_t length, uint8_t* result )
{
uint8_t cbuffer[LR11XX_CRYPTO_AES_ENCRYPT_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_DATA_MAX_LENGTH] = { 0x00 };
lr11xx_crypto_fill_cbuffer_opcode_key_data( cbuffer, LR11XX_CRYPTO_ENCRYPT_AES_01_OC, key_id, data, length );
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, 3 + length, rbuffer, LR11XX_CRYPTO_STATUS_LENGTH + length );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
if( *status == LR11XX_CRYPTO_STATUS_SUCCESS )
{
for( uint16_t index = 0; index < length; index++ )
{
result[index] = rbuffer[1 + index];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_aes_encrypt( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const uint8_t* data, const uint16_t length, uint8_t* result )
{
uint8_t cbuffer[LR11XX_CRYPTO_AES_ENCRYPT_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_DATA_MAX_LENGTH] = { 0x00 };
lr11xx_crypto_fill_cbuffer_opcode_key_data( cbuffer, LR11XX_CRYPTO_ENCRYPT_AES_OC, key_id, data, length );
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, 3 + length, rbuffer, LR11XX_CRYPTO_STATUS_LENGTH + length );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
if( *status == LR11XX_CRYPTO_STATUS_SUCCESS )
{
for( uint16_t index = 0; index < length; index++ )
{
result[index] = rbuffer[1 + index];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_aes_decrypt( const void* context, lr11xx_crypto_status_t* status, const uint8_t key_id,
const uint8_t* data, const uint16_t length, uint8_t* result )
{
uint8_t cbuffer[LR11XX_CRYPTO_AES_DECRYPT_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_DATA_MAX_LENGTH] = { 0x00 };
lr11xx_crypto_fill_cbuffer_opcode_key_data( cbuffer, LR11XX_CRYPTO_DECRYPT_AES_OC, key_id, data, length );
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, 3 + length, rbuffer, LR11XX_CRYPTO_STATUS_LENGTH + length );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
if( *status == LR11XX_CRYPTO_STATUS_SUCCESS )
{
for( uint16_t index = 0; index < length; index++ )
{
result[index] = rbuffer[1 + index];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_store_to_flash( const void* context, lr11xx_crypto_status_t* status )
{
uint8_t cbuffer[LR11XX_CRYPTO_STORE_TO_FLASH_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_STORE_TO_FLASH_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_STORE_TO_FLASH_OC >> 0 );
const lr11xx_hal_status_t hal_status = lr11xx_hal_read( context, cbuffer, LR11XX_CRYPTO_STORE_TO_FLASH_CMD_LENGTH,
rbuffer, LR11XX_CRYPTO_STATUS_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_restore_from_flash( const void* context, lr11xx_crypto_status_t* status )
{
uint8_t cbuffer[LR11XX_CRYPTO_RESTORE_FROM_FLASH_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_RESTORE_FROM_FLASH_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_RESTORE_FROM_FLASH_OC >> 0 );
const lr11xx_hal_status_t hal_status = lr11xx_hal_read(
context, cbuffer, LR11XX_CRYPTO_RESTORE_FROM_FLASH_CMD_LENGTH, rbuffer, LR11XX_CRYPTO_STATUS_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_set_parameter( const void* context, lr11xx_crypto_status_t* status,
const uint8_t param_id, const lr11xx_crypto_param_t parameter )
{
uint8_t cbuffer[LR11XX_CRYPTO_SET_PARAMETER_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_SET_PARAMETER_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_SET_PARAMETER_OC >> 0 );
cbuffer[2] = param_id;
for( uint8_t index = 0; index < LR11XX_CRYPTO_PARAMETER_LENGTH; index++ )
{
cbuffer[3 + index] = parameter[index];
}
const lr11xx_hal_status_t hal_status = lr11xx_hal_read( context, cbuffer, LR11XX_CRYPTO_SET_PARAMETER_CMD_LENGTH,
rbuffer, LR11XX_CRYPTO_STATUS_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_get_parameter( const void* context, lr11xx_crypto_status_t* status,
const uint8_t param_id, lr11xx_crypto_param_t parameter )
{
uint8_t cbuffer[LR11XX_CRYPTO_GET_PARAMETER_CMD_LENGTH] = { 0x00 };
uint8_t rbuffer[LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_PARAMETER_LENGTH] = { 0x00 };
cbuffer[0] = ( uint8_t ) ( LR11XX_CRYPTO_GET_PARAMETER_OC >> 8 );
cbuffer[1] = ( uint8_t ) ( LR11XX_CRYPTO_GET_PARAMETER_OC >> 0 );
cbuffer[2] = param_id;
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, LR11XX_CRYPTO_GET_PARAMETER_CMD_LENGTH, rbuffer,
LR11XX_CRYPTO_STATUS_LENGTH + LR11XX_CRYPTO_PARAMETER_LENGTH );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
*status = ( lr11xx_crypto_status_t ) rbuffer[0];
if( *status == LR11XX_CRYPTO_STATUS_SUCCESS )
{
for( uint8_t index = 0; index < LR11XX_CRYPTO_PARAMETER_LENGTH; index++ )
{
parameter[index] = rbuffer[1 + index];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_crypto_check_encrypted_firmware_image( const void* context, const uint32_t offset_in_byte,
const uint32_t* data, const uint8_t length_in_word )
{
const uint8_t cbuffer[LR11XX_CRYPTO_CHECK_ENCRYPTED_FW_IMAGE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_CRYPTO_CHECK_ENCRYPTED_FW_IMAGE_OC >> 8 ),
( uint8_t ) ( LR11XX_CRYPTO_CHECK_ENCRYPTED_FW_IMAGE_OC >> 0 ),
( uint8_t ) ( offset_in_byte >> 24 ),
( uint8_t ) ( offset_in_byte >> 16 ),
( uint8_t ) ( offset_in_byte >> 8 ),
( uint8_t ) ( offset_in_byte >> 0 ),
};
uint8_t cdata[256] = { 0 };
for( uint8_t index = 0; index < length_in_word; index++ )
{
uint8_t* cdata_local = &cdata[index * sizeof( uint32_t )];
cdata_local[0] = ( uint8_t ) ( data[index] >> 24 );
cdata_local[1] = ( uint8_t ) ( data[index] >> 16 );
cdata_local[2] = ( uint8_t ) ( data[index] >> 8 );
cdata_local[3] = ( uint8_t ) ( data[index] >> 0 );
}
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_CRYPTO_CHECK_ENCRYPTED_FW_IMAGE_CMD_LENGTH,
cdata, length_in_word * sizeof( uint32_t ) );
}
lr11xx_status_t lr11xx_crypto_check_encrypted_firmware_image_full( const void* context, const uint32_t offset_in_byte,
const uint32_t* buffer,
const uint32_t length_in_word )
{
uint32_t remaining_length = length_in_word;
uint32_t local_offset = offset_in_byte;
uint32_t loop = 0;
while( remaining_length != 0 )
{
const lr11xx_status_t status = lr11xx_crypto_check_encrypted_firmware_image(
context, local_offset, buffer + loop * LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32,
lr11xx_crypto_get_min_from_operand_and_max_block_size( remaining_length ) );
if( status != LR11XX_STATUS_OK )
{
return status;
}
local_offset += LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT8;
remaining_length = ( remaining_length < LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32 )
? 0
: ( remaining_length - LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32 );
loop++;
}
return LR11XX_STATUS_OK;
}
lr11xx_status_t lr11xx_crypto_get_check_encrypted_firmware_image_result( const void* context,
bool* is_encrypted_fw_image_ok )
{
const uint8_t cbuffer[LR11XX_CRYPTO_GET_CHECK_ENCRYPTED_FW_IMAGE_RESULT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_CRYPTO_GET_CHECK_ENCRYPTED_FW_IMAGE_RESULT_OC >> 8 ),
( uint8_t ) ( LR11XX_CRYPTO_GET_CHECK_ENCRYPTED_FW_IMAGE_RESULT_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer,
LR11XX_CRYPTO_GET_CHECK_ENCRYPTED_FW_IMAGE_RESULT_CMD_LENGTH,
( uint8_t* ) is_encrypted_fw_image_ok, 1 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
static void lr11xx_crypto_fill_cbuffer_opcode_key_data( uint8_t* cbuffer, uint16_t opcode, uint8_t key_id,
const uint8_t* data, uint16_t length )
{
cbuffer[0] = ( uint8_t ) ( opcode >> 8 );
cbuffer[1] = ( uint8_t ) ( opcode >> 0 );
cbuffer[2] = key_id;
for( uint16_t index = 0; index < length; index++ )
{
cbuffer[3 + index] = data[index];
}
}
uint8_t lr11xx_crypto_get_min_from_operand_and_max_block_size( uint32_t operand )
{
if( operand > LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32 )
{
return LR11XX_CRYPTO_FW_IMAGE_DATA_MAX_LENGTH_UINT32;
}
else
{
return ( uint8_t ) operand; // Downcast done on purpose given that the value is smaller than 64
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,88 @@
/*!
* @file lr11xx_driver_version.c
*
* @brief Placeholder to keep the version of LR11XX driver.
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_driver_version.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
#define STR_HELPER( x ) #x
#define STR( x ) STR_HELPER( x )
#define LR11XX_DRIVER_VERSION_FULL \
"v" STR( LR11XX_DRIVER_VERSION_MAJOR ) "." STR( LR11XX_DRIVER_VERSION_MINOR ) "." STR( LR11XX_DRIVER_VERSION_PATCH )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
const char* lr11xx_driver_version_get_version_string( void )
{
return ( const char* ) LR11XX_DRIVER_VERSION_FULL;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
/* --- EOF ------------------------------------------------------------------ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,216 @@
/*!
* @file lr11xx_lr_fhss.c
*
* @brief LR_FHSS driver implementation for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_lr_fhss.h"
#include "lr11xx_radio.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
#define LR11XX_LR_FHSS_BUILD_FRAME_LENGTH ( 2 + 9 )
#define LR11XX_LR_FHSS_HEADER_BITS ( 114 )
#define LR11XX_LR_FHSS_FRAG_BITS ( 48 )
#define LR11XX_LR_FHSS_BLOCK_PREAMBLE_BITS ( 2 )
#define LR11XX_LR_FHSS_BLOCK_BITS ( LR11XX_LR_FHSS_FRAG_BITS + LR11XX_LR_FHSS_BLOCK_PREAMBLE_BITS )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for radio-related operations
*/
enum
{
LR11XX_LR_FHSS_BUILD_FRAME_OC = 0x022C,
};
/*!
* @brief Hopping enable/disabled enumerations for \ref lr11xx_lr_fhss_build_frame
*/
typedef enum
{
LR11XX_LR_FHSS_HOPPING_DISABLE = 0x00,
LR11XX_LR_FHSS_HOPPING_ENABLE = 0x01,
} lr11xx_lr_fhss_hopping_configuration_t;
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Get the bit count and block count for a LR-FHSS frame
*
* @param [in] params Parameter structure
* @param [in] payload_length Length of physical payload, in bytes
*
* @returns Length of physical payload, in bits
*/
static uint16_t lr11xx_lr_fhss_get_nb_bits( const lr_fhss_v1_params_t* params, uint16_t payload_length );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr11xx_status_t lr11xx_lr_fhss_init( const void* context )
{
const lr11xx_status_t set_packet_type_status = lr11xx_radio_set_pkt_type( context, LR11XX_RADIO_PKT_TYPE_LR_FHSS );
if( set_packet_type_status != LR11XX_STATUS_OK )
{
return set_packet_type_status;
}
const lr11xx_radio_mod_params_lr_fhss_t mod_lr_fhss = {
.br_in_bps = LR11XX_RADIO_LR_FHSS_BITRATE_488_BPS,
.pulse_shape = LR11XX_RADIO_LR_FHSS_PULSE_SHAPE_BT_1,
};
const lr11xx_status_t set_modulation_param_status = lr11xx_radio_set_lr_fhss_mod_params( context, &mod_lr_fhss );
return set_modulation_param_status;
}
uint16_t lr11xx_lr_fhss_get_bit_delay_in_us( const lr11xx_lr_fhss_params_t* params, uint16_t payload_length )
{
const uint16_t nb_bits = lr11xx_lr_fhss_get_nb_bits( &( params->lr_fhss_params ), payload_length );
const uint8_t nb_padding_bits = 1 + ( ( 32768 - nb_bits ) & 0x07 );
return 1600 + nb_padding_bits * 2048;
}
lr11xx_status_t lr11xx_lr_fhss_build_frame( const void* context, const lr11xx_lr_fhss_params_t* lr_fhss_params,
uint16_t hop_sequence_id, const uint8_t* payload, uint8_t payload_length )
{
// Since the build_frame command is last, it is possible to check status through stat1
lr11xx_status_t status = lr11xx_radio_set_lr_fhss_sync_word( context, lr_fhss_params->lr_fhss_params.sync_word );
if( status != LR11XX_STATUS_OK )
{
return status;
}
const uint8_t cbuffer[LR11XX_LR_FHSS_BUILD_FRAME_LENGTH] = {
( uint8_t ) ( LR11XX_LR_FHSS_BUILD_FRAME_OC >> 8 ),
( uint8_t ) ( LR11XX_LR_FHSS_BUILD_FRAME_OC >> 0 ),
( uint8_t ) lr_fhss_params->lr_fhss_params.header_count,
( uint8_t ) lr_fhss_params->lr_fhss_params.cr,
( uint8_t ) lr_fhss_params->lr_fhss_params.modulation_type,
( uint8_t ) lr_fhss_params->lr_fhss_params.grid,
( uint8_t ) ( lr_fhss_params->lr_fhss_params.enable_hopping ? LR11XX_LR_FHSS_HOPPING_ENABLE
: LR11XX_LR_FHSS_HOPPING_DISABLE ),
( uint8_t ) lr_fhss_params->lr_fhss_params.bw,
( uint8_t ) ( hop_sequence_id >> 8 ),
( uint8_t ) ( hop_sequence_id >> 0 ),
( uint8_t ) lr_fhss_params->device_offset,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_LR_FHSS_BUILD_FRAME_LENGTH, payload,
payload_length );
}
uint32_t lr11xx_lr_fhss_get_time_on_air_in_ms( const lr11xx_lr_fhss_params_t* params, uint16_t payload_length )
{
// Multiply by 1000 / 488.28125, or equivalently 256/125, rounding up
return ( ( lr11xx_lr_fhss_get_nb_bits( &params->lr_fhss_params, payload_length ) << 8 ) + 124 ) / 125;
}
unsigned int lr11xx_lr_fhss_get_hop_sequence_count( const lr11xx_lr_fhss_params_t* lr_fhss_params )
{
if( ( lr_fhss_params->lr_fhss_params.grid == LR_FHSS_V1_GRID_25391_HZ ) ||
( ( lr_fhss_params->lr_fhss_params.grid == LR_FHSS_V1_GRID_3906_HZ ) &&
( lr_fhss_params->lr_fhss_params.bw < LR_FHSS_V1_BW_335938_HZ ) ) )
{
return 384;
}
return 512;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION ---------------------------------------------
*/
uint16_t lr11xx_lr_fhss_get_nb_bits( const lr_fhss_v1_params_t* params, uint16_t payload_length )
{
uint16_t length_bits = ( payload_length + 2 ) * 8 + 6;
switch( params->cr )
{
case LR_FHSS_V1_CR_5_6:
length_bits = ( ( length_bits * 6 ) + 4 ) / 5;
break;
case LR_FHSS_V1_CR_2_3:
length_bits = length_bits * 3 / 2;
break;
case LR_FHSS_V1_CR_1_2:
length_bits = length_bits * 2;
break;
case LR_FHSS_V1_CR_1_3:
length_bits = length_bits * 3;
break;
}
uint16_t payload_bits = ( length_bits / LR11XX_LR_FHSS_FRAG_BITS ) * LR11XX_LR_FHSS_BLOCK_BITS;
uint16_t last_block_bits = length_bits % LR11XX_LR_FHSS_FRAG_BITS;
if( last_block_bits > 0 )
{
payload_bits += last_block_bits + 2;
}
return LR11XX_LR_FHSS_HEADER_BITS * params->header_count + payload_bits;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,233 @@
/**
* @file lr11xx_radio_timings.c
*
* @brief LR11XX timing helper functions implementation
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_radio_timings.h"
#include "lr11xx_radio.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
/**
* @brief Time in microsecond taken by the chip to process the Rx done interrupt
*/
#define RX_DONE_IRQ_PROCESSING_TIME_IN_US 74
/**
* @brief Time in microsecond taken by the chip to process the Tx done interrupt
*/
#define TX_DONE_IRQ_PROCESSING_TIME_IN_US 111
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/**
* @brief Get the power amplifier ramp time for a given power amplifier ramp time parameter
*
* @param [in] ramp_time Power amplifier ramp time parameter
*
* @returns Ramp time in microsecond
*/
static uint32_t lr11xx_radio_timings_get_pa_ramp_time_in_us( const lr11xx_radio_ramp_time_t ramp_time );
/**
* @brief Get the LoRa reception input delay
*
* @param [in] bw LoRa bandwidth
*
* @returns LoRa reception input delay in microsecond
*/
static uint32_t lr11xx_radio_timings_get_lora_rx_input_delay_in_us( lr11xx_radio_lora_bw_t bw );
/**
* @brief Get the LoRa symbol time
*
* @param [in] bw LoRa bandwidth
* @param [in] sf LoRa spreading factor
*
* @returns LoRa symbol time in microsecond
*/
static uint32_t lr11xx_radio_timings_get_lora_symb_time_in_us( const lr11xx_radio_lora_sf_t sf,
const lr11xx_radio_lora_bw_t bw );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
uint32_t lr11xx_radio_timings_get_delay_between_last_bit_sent_and_rx_done_in_us(
const lr11xx_radio_mod_params_lora_t* mod_params )
{
return lr11xx_radio_timings_get_lora_rx_input_delay_in_us( mod_params->bw ) +
2 * lr11xx_radio_timings_get_lora_symb_time_in_us( mod_params->sf, mod_params->bw ) +
RX_DONE_IRQ_PROCESSING_TIME_IN_US;
}
uint32_t lr11xx_radio_timings_get_delay_between_last_bit_sent_and_tx_done_in_us(
const lr11xx_radio_ramp_time_t ramp_time )
{
return lr11xx_radio_timings_get_pa_ramp_time_in_us( ramp_time ) + TX_DONE_IRQ_PROCESSING_TIME_IN_US;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
static uint32_t lr11xx_radio_timings_get_pa_ramp_time_in_us( const lr11xx_radio_ramp_time_t ramp_time )
{
switch( ramp_time )
{
case LR11XX_RADIO_RAMP_16_US:
{
return 16;
}
case LR11XX_RADIO_RAMP_32_US:
{
return 32;
}
case LR11XX_RADIO_RAMP_48_US:
{
return 48;
}
case LR11XX_RADIO_RAMP_64_US:
{
return 64;
}
case LR11XX_RADIO_RAMP_80_US:
{
return 80;
}
case LR11XX_RADIO_RAMP_96_US:
{
return 96;
}
case LR11XX_RADIO_RAMP_112_US:
{
return 112;
}
case LR11XX_RADIO_RAMP_128_US:
{
return 128;
}
case LR11XX_RADIO_RAMP_144_US:
{
return 144;
}
case LR11XX_RADIO_RAMP_160_US:
{
return 160;
}
case LR11XX_RADIO_RAMP_176_US:
{
return 176;
}
case LR11XX_RADIO_RAMP_192_US:
{
return 192;
}
case LR11XX_RADIO_RAMP_208_US:
{
return 208;
}
case LR11XX_RADIO_RAMP_240_US:
{
return 240;
}
case LR11XX_RADIO_RAMP_272_US:
{
return 272;
}
case LR11XX_RADIO_RAMP_304_US:
{
return 304;
}
default:
return 0;
}
}
static uint32_t lr11xx_radio_timings_get_lora_rx_input_delay_in_us( lr11xx_radio_lora_bw_t bw )
{
switch( bw )
{
case LR11XX_RADIO_LORA_BW_500:
{
return 16;
}
case LR11XX_RADIO_LORA_BW_250:
{
return 31;
}
case LR11XX_RADIO_LORA_BW_125:
{
return 57;
}
default:
{
return 0;
}
}
}
static uint32_t lr11xx_radio_timings_get_lora_symb_time_in_us( const lr11xx_radio_lora_sf_t sf,
const lr11xx_radio_lora_bw_t bw )
{
return ( 1 << ( uint8_t ) sf ) * 1000000 / lr11xx_radio_get_lora_bw_in_hz( bw );
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,323 @@
/*!
* @file lr11xx_regmem.c
*
* @brief Register/memory driver implementation for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_regmem.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR11XX_REGMEM_CLEAR_RXBUFFER_CMD_LENGTH 2
#define LR11XX_REGMEM_WRITE_REGMEM32_CMD_LENGTH ( 2 + 4 )
#define LR11XX_REGMEM_READ_REGMEM32_CMD_LENGTH ( 2 + 4 + 1 )
#define LR11XX_REGMEM_WRITE_MEM8_CMD_LENGTH ( 2 + 4 )
#define LR11XX_REGMEM_READ_MEM8_CMD_LENGTH ( 2 + 4 + 1 )
#define LR11XX_REGMEM_WRITE_BUFFER8_CMD_LENGTH ( 2 )
#define LR11XX_REGMEM_READ_BUFFER8_CMD_LENGTH ( 2 + 2 )
#define LR11XX_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH ( 2 + 4 + 4 + 4 )
#define LR11XX_REGMEM_BUFFER_SIZE_MAX ( 256 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for register and memory related operations
*/
enum
{
LR11XX_REGMEM_WRITE_REGMEM32_OC = 0x0105,
LR11XX_REGMEM_READ_REGMEM32_OC = 0x0106,
LR11XX_REGMEM_WRITE_MEM8_OC = 0x0107,
LR11XX_REGMEM_READ_MEM8_OC = 0x0108,
LR11XX_REGMEM_WRITE_BUFFER8_OC = 0x0109,
LR11XX_REGMEM_READ_BUFFER8_OC = 0x010A,
LR11XX_REGMEM_CLEAR_RXBUFFER_OC = 0x010B,
LR11XX_REGMEM_WRITE_REGMEM32_MASK_OC = 0x010C,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Helper function that fill both cbuffer with opcode and memory address
*
* It is typically used in read/write regmem32 functions.
*
* @warning It is up to the caller to ensure cbuffer is big enough to contain opcode and address!
*/
static void lr11xx_regmem_fill_cbuffer_opcode_address( uint8_t* cbuffer, uint16_t opcode, uint32_t address );
/*!
* @brief Helper function that fill both cbuffer with opcode memory address, and data length to read
*
* It is typically used in read functions.
*
* @warning It is up to the caller to ensure cbuffer is big enough to contain opcode and address!
*/
static void lr11xx_regmem_fill_cbuffer_opcode_address_length( uint8_t* cbuffer, uint16_t opcode, uint32_t address,
uint8_t length );
/*!
* @brief Helper function that fill both cbuffer with data
*
* It is typically used in write write regmem32 functions.
*
* @warning It is up to the caller to ensure cdata is big enough to contain all data!
*/
static void lr11xx_regmem_fill_cdata( uint8_t* cdata, const uint32_t* data, uint8_t data_length );
/*!
* @brief Helper function that fill both cbuffer and cdata buffers with opcode, memory address and data
*
* It is typically used to factorize and write regmem32 operations. Behind the scene it calls the other helpers
* lr11xx_regmem_fill_cbuffer_opcode_address and lr11xx_regmem_fill_cdata.
*
* @warning It is up to the caller to ensure cbuffer and cdata are big enough to contain their respective information!
*/
static void lr11xx_regmem_fill_cbuffer_cdata_opcode_address_data( uint8_t* cbuffer, uint8_t* cdata, uint16_t opcode,
uint32_t address, const uint32_t* data,
uint8_t data_length );
/*!
* @brief Helper function that convert an array of uint8_t into an array of uint32_t
*
* Typically used in the read function returning uint32_t array.
*
* @warning It is up to the caller to ensure the raw_buffer is of length at least "out_buffer_length *
* sizeof(uint32_t)"!
*/
static void lr11xx_regmem_fill_out_buffer_from_raw_buffer( uint32_t* out_buffer, const uint8_t* raw_buffer,
uint8_t out_buffer_length );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr11xx_status_t lr11xx_regmem_write_regmem32( const void* context, const uint32_t address, const uint32_t* buffer,
const uint8_t length )
{
uint8_t cbuffer[LR11XX_REGMEM_WRITE_REGMEM32_CMD_LENGTH];
uint8_t cdata[LR11XX_REGMEM_BUFFER_SIZE_MAX];
if( length > LR11XX_REGMEM_MAX_WRITE_READ_WORDS )
{
return LR11XX_STATUS_ERROR;
}
lr11xx_regmem_fill_cbuffer_cdata_opcode_address_data( cbuffer, cdata, LR11XX_REGMEM_WRITE_REGMEM32_OC, address,
buffer, length );
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_REGMEM_WRITE_REGMEM32_CMD_LENGTH, cdata,
length * sizeof( uint32_t ) );
}
lr11xx_status_t lr11xx_regmem_read_regmem32( const void* context, const uint32_t address, uint32_t* buffer,
const uint8_t length )
{
uint8_t cbuffer[LR11XX_REGMEM_READ_REGMEM32_CMD_LENGTH] = { 0 };
if( length > LR11XX_REGMEM_MAX_WRITE_READ_WORDS )
{
return LR11XX_STATUS_ERROR;
}
lr11xx_regmem_fill_cbuffer_opcode_address_length( cbuffer, LR11XX_REGMEM_READ_REGMEM32_OC, address, length );
const lr11xx_status_t status = ( lr11xx_status_t ) lr11xx_hal_read(
context, cbuffer, LR11XX_REGMEM_READ_REGMEM32_CMD_LENGTH, ( uint8_t* ) buffer, length * sizeof( uint32_t ) );
if( status == LR11XX_STATUS_OK )
{
lr11xx_regmem_fill_out_buffer_from_raw_buffer( buffer, ( const uint8_t* ) buffer, length );
}
return status;
}
lr11xx_status_t lr11xx_regmem_write_mem8( const void* context, const uint32_t address, const uint8_t* buffer,
const uint8_t length )
{
uint8_t cbuffer[LR11XX_REGMEM_WRITE_MEM8_CMD_LENGTH];
lr11xx_regmem_fill_cbuffer_opcode_address( cbuffer, LR11XX_REGMEM_WRITE_MEM8_OC, address );
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_REGMEM_WRITE_MEM8_CMD_LENGTH, buffer,
length );
}
lr11xx_status_t lr11xx_regmem_read_mem8( const void* context, const uint32_t address, uint8_t* buffer,
const uint8_t length )
{
uint8_t cbuffer[LR11XX_REGMEM_READ_MEM8_CMD_LENGTH];
lr11xx_regmem_fill_cbuffer_opcode_address_length( cbuffer, LR11XX_REGMEM_READ_MEM8_OC, address, length );
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_REGMEM_READ_MEM8_CMD_LENGTH, buffer, length );
}
lr11xx_status_t lr11xx_regmem_write_buffer8( const void* context, const uint8_t* buffer, const uint8_t length )
{
const uint8_t cbuffer[LR11XX_REGMEM_WRITE_BUFFER8_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_REGMEM_WRITE_BUFFER8_OC >> 8 ),
( uint8_t ) ( LR11XX_REGMEM_WRITE_BUFFER8_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_REGMEM_WRITE_BUFFER8_CMD_LENGTH, buffer,
length );
}
lr11xx_status_t lr11xx_regmem_read_buffer8( const void* context, uint8_t* buffer, const uint8_t offset,
const uint8_t length )
{
const uint8_t cbuffer[LR11XX_REGMEM_READ_BUFFER8_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_REGMEM_READ_BUFFER8_OC >> 8 ),
( uint8_t ) ( LR11XX_REGMEM_READ_BUFFER8_OC >> 0 ),
offset,
length,
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_REGMEM_READ_BUFFER8_CMD_LENGTH, buffer,
length );
}
lr11xx_status_t lr11xx_regmem_clear_rxbuffer( const void* context )
{
const uint8_t cbuffer[LR11XX_REGMEM_CLEAR_RXBUFFER_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_REGMEM_CLEAR_RXBUFFER_OC >> 8 ),
( uint8_t ) ( LR11XX_REGMEM_CLEAR_RXBUFFER_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_REGMEM_CLEAR_RXBUFFER_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_regmem_write_regmem32_mask( const void* context, const uint32_t address, const uint32_t mask,
const uint32_t data )
{
uint8_t cbuffer[LR11XX_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH];
lr11xx_regmem_fill_cbuffer_opcode_address( cbuffer, LR11XX_REGMEM_WRITE_REGMEM32_MASK_OC, address );
cbuffer[6] = ( uint8_t ) ( mask >> 24 );
cbuffer[7] = ( uint8_t ) ( mask >> 16 );
cbuffer[8] = ( uint8_t ) ( mask >> 8 );
cbuffer[9] = ( uint8_t ) ( mask >> 0 );
cbuffer[10] = ( uint8_t ) ( data >> 24 );
cbuffer[11] = ( uint8_t ) ( data >> 16 );
cbuffer[12] = ( uint8_t ) ( data >> 8 );
cbuffer[13] = ( uint8_t ) ( data >> 0 );
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_REGMEM_WRITE_REGMEM32_MASK_CMD_LENGTH, 0, 0 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
void lr11xx_regmem_fill_cbuffer_opcode_address( uint8_t* cbuffer, uint16_t opcode, uint32_t address )
{
cbuffer[0] = ( uint8_t ) ( opcode >> 8 );
cbuffer[1] = ( uint8_t ) ( opcode >> 0 );
cbuffer[2] = ( uint8_t ) ( address >> 24 );
cbuffer[3] = ( uint8_t ) ( address >> 16 );
cbuffer[4] = ( uint8_t ) ( address >> 8 );
cbuffer[5] = ( uint8_t ) ( address >> 0 );
}
void lr11xx_regmem_fill_cbuffer_opcode_address_length( uint8_t* cbuffer, uint16_t opcode, uint32_t address,
uint8_t length )
{
lr11xx_regmem_fill_cbuffer_opcode_address( cbuffer, opcode, address );
cbuffer[6] = length;
}
void lr11xx_regmem_fill_cdata( uint8_t* cdata, const uint32_t* data, uint8_t data_length )
{
for( uint16_t index = 0; index < data_length; index++ )
{
uint8_t* cdata_local = &cdata[index * sizeof( uint32_t )];
cdata_local[0] = ( uint8_t ) ( data[index] >> 24 );
cdata_local[1] = ( uint8_t ) ( data[index] >> 16 );
cdata_local[2] = ( uint8_t ) ( data[index] >> 8 );
cdata_local[3] = ( uint8_t ) ( data[index] >> 0 );
}
}
void lr11xx_regmem_fill_cbuffer_cdata_opcode_address_data( uint8_t* cbuffer, uint8_t* cdata, uint16_t opcode,
uint32_t address, const uint32_t* data, uint8_t data_length )
{
lr11xx_regmem_fill_cbuffer_opcode_address( cbuffer, opcode, address );
lr11xx_regmem_fill_cdata( cdata, data, data_length );
}
void lr11xx_regmem_fill_out_buffer_from_raw_buffer( uint32_t* out_buffer, const uint8_t* raw_buffer,
uint8_t out_buffer_length )
{
for( uint8_t out_index = 0; out_index < out_buffer_length; out_index++ )
{
const uint8_t* raw_buffer_local = &raw_buffer[out_index * 4];
out_buffer[out_index] = ( ( uint32_t ) raw_buffer_local[0] << 24 ) +
( ( uint32_t ) raw_buffer_local[1] << 16 ) + ( ( uint32_t ) raw_buffer_local[2] << 8 ) +
( ( uint32_t ) raw_buffer_local[3] << 0 );
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,194 @@
/**
* @file lr11xx_rttof.c
*
* @brief Round-Trip Time of Flight (RTToF) driver implementation for LR11XX
*
* 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdint.h>
#include "lr11xx_rttof.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR11XX_RTTOF_SET_ADDRESS_CMD_LENGTH ( 2 + 5 )
#define LR11XX_RTTOF_SET_REQUEST_ADDRESS_CMD_LENGTH ( 2 + 4 )
#define LR11XX_RTTOF_SET_RX_TX_DELAY_CMD_LENGTH ( 2 + 4 )
#define LR11XX_RTTOF_SET_PARAMETERS_CMD_LENGTH ( 2 + 2 )
#define LR11XX_RTTOF_GET_RESULT_CMD_LENGTH ( 2 + 1 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/**
* @brief Operating codes for RTToF-related operations
*/
enum
{
LR11XX_RTTOF_SET_ADDRESS = 0x021C,
LR11XX_RTTOF_SET_REQUEST_ADDRESS = 0x021D,
LR11XX_RTTOF_SET_RX_TX_DELAY = 0x021F,
LR11XX_RTTOF_SET_PARAMETERS = 0x0228,
LR11XX_RTTOF_GET_RESULT = 0x021E,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTION DECLARATIONS -------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTION DEFINITIONS ---------------------------------------------
*/
lr11xx_status_t lr11xx_rttof_set_address( const void* context, const uint32_t address, const uint8_t check_length )
{
const uint8_t cbuffer[LR11XX_RTTOF_SET_ADDRESS_CMD_LENGTH] = {
( uint8_t )( LR11XX_RTTOF_SET_ADDRESS >> 8 ),
( uint8_t )( LR11XX_RTTOF_SET_ADDRESS >> 0 ),
( uint8_t )( address >> 24 ),
( uint8_t )( address >> 16 ),
( uint8_t )( address >> 8 ),
( uint8_t )( address >> 0 ),
check_length,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_ADDRESS_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_rttof_set_request_address( const void* context, const uint32_t request_address )
{
const uint8_t cbuffer[LR11XX_RTTOF_SET_REQUEST_ADDRESS_CMD_LENGTH] = {
( uint8_t )( LR11XX_RTTOF_SET_REQUEST_ADDRESS >> 8 ),
( uint8_t )( LR11XX_RTTOF_SET_REQUEST_ADDRESS >> 0 ),
( uint8_t )( request_address >> 24 ),
( uint8_t )( request_address >> 16 ),
( uint8_t )( request_address >> 8 ),
( uint8_t )( request_address >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_REQUEST_ADDRESS_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_rttof_set_rx_tx_delay_indicator( const void* context, const uint32_t delay_indicator )
{
const uint8_t cbuffer[LR11XX_RTTOF_SET_RX_TX_DELAY_CMD_LENGTH] = {
( uint8_t )( LR11XX_RTTOF_SET_RX_TX_DELAY >> 8 ),
( uint8_t )( LR11XX_RTTOF_SET_RX_TX_DELAY >> 0 ),
( uint8_t )( delay_indicator >> 24 ),
( uint8_t )( delay_indicator >> 16 ),
( uint8_t )( delay_indicator >> 8 ),
( uint8_t )( delay_indicator >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_RX_TX_DELAY_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_rttof_set_parameters( const void* context, const uint8_t nb_symbols )
{
const uint8_t cbuffer[LR11XX_RTTOF_SET_PARAMETERS_CMD_LENGTH] = { ( uint8_t )( LR11XX_RTTOF_SET_PARAMETERS >> 8 ),
( uint8_t )( LR11XX_RTTOF_SET_PARAMETERS >> 0 ),
0x00, nb_symbols };
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_RTTOF_SET_PARAMETERS_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_rttof_get_raw_result( const void* context, const lr11xx_rttof_result_type_t type,
uint8_t result[LR11XX_RTTOF_RESULT_LENGTH] )
{
const uint8_t cbuffer[LR11XX_RTTOF_GET_RESULT_CMD_LENGTH] = {
( uint8_t )( LR11XX_RTTOF_GET_RESULT >> 8 ),
( uint8_t )( LR11XX_RTTOF_GET_RESULT >> 0 ),
( uint8_t ) type,
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_RTTOF_GET_RESULT_CMD_LENGTH, result,
LR11XX_RTTOF_RESULT_LENGTH );
}
int32_t lr11xx_rttof_distance_raw_to_meter( lr11xx_radio_lora_bw_t rttof_bw,
const uint8_t raw_distance_buf[LR11XX_RTTOF_RESULT_LENGTH] )
{
const uint8_t bitcnt = 24u;
uint8_t bw_scaling = 0u;
const uint32_t raw_distance =
( ( uint32_t ) raw_distance_buf[3] << 0 ) + ( ( uint32_t ) raw_distance_buf[2] << 8 ) +
( ( uint32_t ) raw_distance_buf[1] << 16 ) + ( ( uint32_t ) raw_distance_buf[0] << 24 );
if( rttof_bw == LR11XX_RADIO_LORA_BW_500 )
{
bw_scaling = 1u;
}
else if( rttof_bw == LR11XX_RADIO_LORA_BW_250 )
{
bw_scaling = 2u;
}
else if( rttof_bw == LR11XX_RADIO_LORA_BW_125 )
{
bw_scaling = 4u;
}
int32_t retval = raw_distance;
if( raw_distance >= ( 1 << ( bitcnt - 1 ) ) )
{
retval -= ( 1 << bitcnt );
}
return 300 * bw_scaling * retval / 4096;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTION DEFINITIONS --------------------------------------------
*/
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,664 @@
/*!
* @file lr11xx_system.c
*
* @brief System driver implementation for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdlib.h>
#include "lr11xx_system.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR11XX_SYSTEM_GET_VERSION_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_GET_ERRORS_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_CLEAR_ERRORS_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_CALIBRATE_CMD_LENGTH ( 2 + 1 )
#define LR11XX_SYSTEM_SET_REGMODE_CMD_LENGTH ( 2 + 1 )
#define LR11XX_SYSTEM_CALIBRATE_IMAGE_CMD_LENGTH ( 2 + 2 )
#define LR11XX_SYSTEM_SET_DIO_AS_RF_SWITCH_CMD_LENGTH ( 2 + 8 )
#define LR11XX_SYSTEM_SET_DIO_IRQ_PARAMS_CMD_LENGTH ( 2 + 8 )
#define LR11XX_SYSTEM_CLEAR_IRQ_CMD_LENGTH ( 2 + 4 )
#define LR11XX_SYSTEM_CFG_LFCLK_CMD_LENGTH ( 2 + 1 )
#define LR11XX_SYSTEM_SET_TCXO_MODE_CMD_LENGTH ( 2 + 4 )
#define LR11XX_SYSTEM_REBOOT_CMD_LENGTH ( 2 + 1 )
#define LR11XX_SYSTEM_GET_VBAT_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_GET_TEMP_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_SET_SLEEP_CMD_LENGTH ( 2 + 5 )
#define LR11XX_SYSTEM_SET_STANDBY_CMD_LENGTH ( 2 + 1 )
#define LR11XX_SYSTEM_SET_FS_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_ERASE_INFOPAGE_CMD_LENGTH ( 2 + 1 )
#define LR11XX_SYSTEM_WRITE_INFOPAGE_CMD_LENGTH ( 2 + 3 )
#define LR11XX_SYSTEM_READ_INFOPAGE_CMD_LENGTH ( 2 + 4 )
#define LR11XX_SYSTEM_READ_UID_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_READ_JOIN_EUI_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_READ_PIN_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_READ_PIN_CUSTOM_EUI_CMD_LENGTH ( LR11XX_SYSTEM_READ_PIN_CMD_LENGTH + 17 )
#define LR11XX_SYSTEM_GET_RANDOM_CMD_LENGTH ( 2 )
#define LR11XX_SYSTEM_ENABLE_SPI_CRC_CMD_LENGTH ( 3 )
#define LR11XX_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_CMD_LENGTH ( 3 )
#define LR11XX_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH ( 6 )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for system-related operations
*/
enum
{
LR11XX_SYSTEM_GET_STATUS_OC = 0x0100,
LR11XX_SYSTEM_GET_VERSION_OC = 0x0101,
LR11XX_SYSTEM_GET_ERRORS_OC = 0x010D,
LR11XX_SYSTEM_CLEAR_ERRORS_OC = 0x010E,
LR11XX_SYSTEM_CALIBRATE_OC = 0x010F,
LR11XX_SYSTEM_SET_REGMODE_OC = 0x0110,
LR11XX_SYSTEM_CALIBRATE_IMAGE_OC = 0x0111,
LR11XX_SYSTEM_SET_DIO_AS_RF_SWITCH_OC = 0x0112,
LR11XX_SYSTEM_SET_DIOIRQPARAMS_OC = 0x0113,
LR11XX_SYSTEM_CLEAR_IRQ_OC = 0x0114,
LR11XX_SYSTEM_CFG_LFCLK_OC = 0x0116,
LR11XX_SYSTEM_SET_TCXO_MODE_OC = 0x0117,
LR11XX_SYSTEM_REBOOT_OC = 0x0118,
LR11XX_SYSTEM_GET_VBAT_OC = 0x0119,
LR11XX_SYSTEM_GET_TEMP_OC = 0x011A,
LR11XX_SYSTEM_SET_SLEEP_OC = 0x011B,
LR11XX_SYSTEM_SET_STANDBY_OC = 0x011C,
LR11XX_SYSTEM_SET_FS_OC = 0x011D,
LR11XX_SYSTEM_GET_RANDOM_OC = 0x0120,
LR11XX_SYSTEM_ERASE_INFOPAGE_OC = 0x0121,
LR11XX_SYSTEM_WRITE_INFOPAGE_OC = 0x0122,
LR11XX_SYSTEM_READ_INFOPAGE_OC = 0x0123,
LR11XX_SYSTEM_READ_UID_OC = 0x0125,
LR11XX_SYSTEM_READ_JOIN_EUI_OC = 0x0126,
LR11XX_SYSTEM_READ_PIN_OC = 0x0127,
LR11XX_SYSTEM_ENABLE_SPI_CRC_OC = 0x0128,
LR11XX_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_OC = 0x012A,
};
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Fill stat1 structure with data from stat1_byte
*
* @param [in] stat1_byte stat1 byte
* @param [out] stat1 stat1 structure
*/
static void lr11xx_system_convert_stat1_byte_to_enum( uint8_t stat1_byte, lr11xx_system_stat1_t* stat1 );
/*!
* @brief Fill stat2 structure with data from stat2_byte
*
* @param [in] stat2_byte stat2 byte
* @param [out] stat2 stat2 structure
*/
static void lr11xx_system_convert_stat2_byte_to_enum( uint8_t stat2_byte, lr11xx_system_stat2_t* stat2 );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr11xx_status_t lr11xx_system_reset( const void* context )
{
return ( lr11xx_status_t ) lr11xx_hal_reset( context );
}
lr11xx_status_t lr11xx_system_get_status( const void* context, lr11xx_system_stat1_t* stat1,
lr11xx_system_stat2_t* stat2, lr11xx_system_irq_mask_t* irq_status )
{
uint8_t data[LR11XX_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH] = { 0 };
const lr11xx_status_t status =
( lr11xx_status_t ) lr11xx_hal_direct_read( context, data, LR11XX_SYSTEM_GET_STATUS_DIRECT_READ_LENGTH );
if( status == LR11XX_STATUS_OK )
{
lr11xx_system_convert_stat1_byte_to_enum( data[0], stat1 );
lr11xx_system_convert_stat2_byte_to_enum( data[1], stat2 );
if( irq_status != NULL )
{
*irq_status = ( ( lr11xx_system_irq_mask_t ) data[2] << 24 ) +
( ( lr11xx_system_irq_mask_t ) data[3] << 16 ) +
( ( lr11xx_system_irq_mask_t ) data[4] << 8 ) + ( ( lr11xx_system_irq_mask_t ) data[5] << 0 );
}
}
return status;
}
lr11xx_status_t lr11xx_system_clear_reset_status_info( const void* context )
{
uint8_t cbuffer[2] = {
( uint8_t ) ( LR11XX_SYSTEM_GET_STATUS_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_GET_STATUS_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, sizeof( cbuffer ), 0, 0 );
}
lr11xx_status_t lr11xx_system_get_version( const void* context, lr11xx_system_version_t* version )
{
const uint8_t cbuffer[LR11XX_SYSTEM_GET_VERSION_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_GET_VERSION_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_GET_VERSION_OC >> 0 ),
};
uint8_t rbuffer[LR11XX_SYSTEM_VERSION_LENGTH] = { 0x00 };
const lr11xx_status_t status = ( lr11xx_status_t ) lr11xx_hal_read(
context, cbuffer, LR11XX_SYSTEM_GET_VERSION_CMD_LENGTH, rbuffer, LR11XX_SYSTEM_VERSION_LENGTH );
if( status == LR11XX_STATUS_OK )
{
version->hw = rbuffer[0];
version->type = ( lr11xx_system_version_type_t ) rbuffer[1];
version->fw = ( ( uint16_t ) rbuffer[2] << 8 ) + ( uint16_t ) rbuffer[3];
}
return status;
}
lr11xx_status_t lr11xx_system_get_errors( const void* context, lr11xx_system_errors_t* errors )
{
const uint8_t cbuffer[LR11XX_SYSTEM_GET_ERRORS_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_GET_ERRORS_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_GET_ERRORS_OC >> 0 ),
};
uint8_t rbuffer[sizeof( errors )] = { 0x00 };
const lr11xx_status_t status = ( lr11xx_status_t ) lr11xx_hal_read(
context, cbuffer, LR11XX_SYSTEM_GET_ERRORS_CMD_LENGTH, rbuffer, sizeof( *errors ) );
if( status == LR11XX_STATUS_OK )
{
*errors = ( ( uint16_t ) rbuffer[0] << 8 ) + ( uint16_t ) rbuffer[1];
}
return status;
}
lr11xx_status_t lr11xx_system_clear_errors( const void* context )
{
const uint8_t cbuffer[LR11XX_SYSTEM_CLEAR_ERRORS_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_CLEAR_ERRORS_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_CLEAR_ERRORS_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_CLEAR_ERRORS_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_calibrate( const void* context, const uint8_t calib_param )
{
const uint8_t cbuffer[LR11XX_SYSTEM_CALIBRATE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_CALIBRATE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_CALIBRATE_OC >> 0 ),
calib_param,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_CALIBRATE_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_set_reg_mode( const void* context, const lr11xx_system_reg_mode_t reg_mode )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_REGMODE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_REGMODE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_REGMODE_OC >> 0 ),
( uint8_t ) reg_mode,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_REGMODE_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_calibrate_image( const void* context, const uint8_t freq1, const uint8_t freq2 )
{
const uint8_t cbuffer[LR11XX_SYSTEM_CALIBRATE_IMAGE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_CALIBRATE_IMAGE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_CALIBRATE_IMAGE_OC >> 0 ),
freq1,
freq2,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_CALIBRATE_IMAGE_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_calibrate_image_in_mhz( const void* context, const uint16_t freq1_in_mhz,
const uint16_t freq2_in_mhz )
{
// Perform a floor() to get a value for freq1 corresponding to a frequency lower than or equal to freq1_in_mhz
const uint8_t freq1 = freq1_in_mhz / LR11XX_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ;
// Perform a ceil() to get a value for freq2 corresponding to a frequency higher than or equal to freq2_in_mhz
const uint8_t freq2 = ( freq2_in_mhz + LR11XX_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ - 1 ) /
LR11XX_SYSTEM_IMAGE_CALIBRATION_STEP_IN_MHZ;
return lr11xx_system_calibrate_image( context, freq1, freq2 );
}
lr11xx_status_t lr11xx_system_set_dio_as_rf_switch( const void* context,
const lr11xx_system_rfswitch_cfg_t* rf_switch_cfg )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_DIO_AS_RF_SWITCH_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_DIO_AS_RF_SWITCH_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_DIO_AS_RF_SWITCH_OC >> 0 ),
rf_switch_cfg->enable,
rf_switch_cfg->standby,
rf_switch_cfg->rx,
rf_switch_cfg->tx,
rf_switch_cfg->tx_hp,
rf_switch_cfg->tx_hf,
rf_switch_cfg->gnss,
rf_switch_cfg->wifi,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_DIO_AS_RF_SWITCH_CMD_LENGTH, 0,
0 );
}
lr11xx_status_t lr11xx_system_set_dio_irq_params( const void* context,
const lr11xx_system_irq_mask_t irqs_to_enable_dio1,
const lr11xx_system_irq_mask_t irqs_to_enable_dio2 )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_DIO_IRQ_PARAMS_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_DIOIRQPARAMS_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_DIOIRQPARAMS_OC >> 0 ),
( uint8_t ) ( irqs_to_enable_dio1 >> 24 ),
( uint8_t ) ( irqs_to_enable_dio1 >> 16 ),
( uint8_t ) ( irqs_to_enable_dio1 >> 8 ),
( uint8_t ) ( irqs_to_enable_dio1 >> 0 ),
( uint8_t ) ( irqs_to_enable_dio2 >> 24 ),
( uint8_t ) ( irqs_to_enable_dio2 >> 16 ),
( uint8_t ) ( irqs_to_enable_dio2 >> 8 ),
( uint8_t ) ( irqs_to_enable_dio2 >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_DIO_IRQ_PARAMS_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_clear_irq_status( const void* context, const lr11xx_system_irq_mask_t irqs_to_clear )
{
const uint8_t cbuffer[LR11XX_SYSTEM_CLEAR_IRQ_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_CLEAR_IRQ_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_CLEAR_IRQ_OC >> 0 ),
( uint8_t ) ( irqs_to_clear >> 24 ),
( uint8_t ) ( irqs_to_clear >> 16 ),
( uint8_t ) ( irqs_to_clear >> 8 ),
( uint8_t ) ( irqs_to_clear >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_CLEAR_IRQ_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_get_and_clear_irq_status( const void* context, lr11xx_system_irq_mask_t* irq )
{
lr11xx_system_irq_mask_t lr11xx_irq_mask = LR11XX_SYSTEM_IRQ_NONE;
lr11xx_status_t status = lr11xx_system_get_irq_status( context, &lr11xx_irq_mask );
if( ( status == LR11XX_STATUS_OK ) && ( lr11xx_irq_mask != 0 ) )
{
status = lr11xx_system_clear_irq_status( context, lr11xx_irq_mask );
}
if( ( status == LR11XX_STATUS_OK ) && ( irq != NULL ) )
{
*irq = lr11xx_irq_mask;
}
return status;
}
lr11xx_status_t lr11xx_system_cfg_lfclk( const void* context, const lr11xx_system_lfclk_cfg_t lfclock_cfg,
const bool wait_for_32k_ready )
{
const uint8_t cbuffer[LR11XX_SYSTEM_CFG_LFCLK_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_CFG_LFCLK_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_CFG_LFCLK_OC >> 0 ),
( uint8_t ) ( lfclock_cfg | ( wait_for_32k_ready << 2 ) ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_CFG_LFCLK_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_set_tcxo_mode( const void* context, const lr11xx_system_tcxo_supply_voltage_t tune,
const uint32_t timeout )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_TCXO_MODE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_TCXO_MODE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_TCXO_MODE_OC >> 0 ),
( uint8_t ) tune,
( uint8_t ) ( timeout >> 16 ),
( uint8_t ) ( timeout >> 8 ),
( uint8_t ) ( timeout >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_TCXO_MODE_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_reboot( const void* context, const bool stay_in_bootloader )
{
const uint8_t cbuffer[LR11XX_SYSTEM_REBOOT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_REBOOT_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_REBOOT_OC >> 0 ),
( stay_in_bootloader == true ) ? 0x03 : 0x00,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_REBOOT_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_get_vbat( const void* context, uint8_t* vbat )
{
const uint8_t cbuffer[LR11XX_SYSTEM_GET_VBAT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_GET_VBAT_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_GET_VBAT_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_SYSTEM_GET_VBAT_CMD_LENGTH, vbat,
sizeof( *vbat ) );
}
lr11xx_status_t lr11xx_system_get_temp( const void* context, uint16_t* temp )
{
const uint8_t cbuffer[LR11XX_SYSTEM_GET_TEMP_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_GET_TEMP_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_GET_TEMP_OC >> 0 ),
};
uint8_t rbuffer[sizeof( uint16_t )] = { 0x00 };
const lr11xx_status_t status = ( lr11xx_status_t ) lr11xx_hal_read(
context, cbuffer, LR11XX_SYSTEM_GET_TEMP_CMD_LENGTH, rbuffer, sizeof( uint16_t ) );
if( status == LR11XX_STATUS_OK )
{
*temp = ( ( uint16_t ) rbuffer[0] << 8 ) + ( uint16_t ) rbuffer[1];
}
return status;
}
lr11xx_status_t lr11xx_system_set_sleep( const void* context, const lr11xx_system_sleep_cfg_t sleep_cfg,
const uint32_t sleep_time )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_SLEEP_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_SLEEP_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_SLEEP_OC >> 0 ),
( sleep_cfg.is_rtc_timeout << 1 ) + sleep_cfg.is_warm_start,
( uint8_t ) ( sleep_time >> 24 ),
( uint8_t ) ( sleep_time >> 16 ),
( uint8_t ) ( sleep_time >> 8 ),
( uint8_t ) ( sleep_time >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_SLEEP_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_set_standby( const void* context, const lr11xx_system_standby_cfg_t standby_cfg )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_STANDBY_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_STANDBY_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_STANDBY_OC >> 0 ),
( uint8_t ) standby_cfg,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_STANDBY_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_wakeup( const void* context )
{
return ( lr11xx_status_t ) lr11xx_hal_wakeup( context );
}
lr11xx_status_t lr11xx_system_abort_blocking_cmd( const void* context )
{
return ( lr11xx_status_t ) lr11xx_hal_abort_blocking_cmd( context );
}
lr11xx_status_t lr11xx_system_set_fs( const void* context )
{
const uint8_t cbuffer[LR11XX_SYSTEM_SET_FS_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_SET_FS_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_SET_FS_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_SET_FS_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_erase_infopage( const void* context, const lr11xx_system_infopage_id_t infopage_id )
{
const uint8_t cbuffer[LR11XX_SYSTEM_ERASE_INFOPAGE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_ERASE_INFOPAGE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_ERASE_INFOPAGE_OC >> 0 ),
( uint8_t ) infopage_id,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_ERASE_INFOPAGE_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_write_infopage( const void* context, const lr11xx_system_infopage_id_t infopage_id,
const uint16_t address, const uint32_t* data, const uint8_t length )
{
const uint8_t cbuffer[LR11XX_SYSTEM_WRITE_INFOPAGE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_WRITE_INFOPAGE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_WRITE_INFOPAGE_OC >> 0 ),
( uint8_t ) infopage_id,
( uint8_t ) ( address >> 8 ),
( uint8_t ) ( address >> 0 ),
};
uint8_t cdata[256];
for( uint16_t index = 0; index < length; index++ )
{
uint8_t* cdata_local = &cdata[index * sizeof( uint32_t )];
cdata_local[0] = ( uint8_t ) ( data[index] >> 24 );
cdata_local[1] = ( uint8_t ) ( data[index] >> 16 );
cdata_local[2] = ( uint8_t ) ( data[index] >> 8 );
cdata_local[3] = ( uint8_t ) ( data[index] >> 0 );
}
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_WRITE_INFOPAGE_CMD_LENGTH, cdata,
length * sizeof( uint32_t ) );
}
lr11xx_status_t lr11xx_system_read_infopage( const void* context, const lr11xx_system_infopage_id_t infopage_id,
const uint16_t address, uint32_t* data, const uint8_t length )
{
const uint8_t cbuffer[LR11XX_SYSTEM_READ_INFOPAGE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_READ_INFOPAGE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_READ_INFOPAGE_OC >> 0 ),
( uint8_t ) infopage_id,
( uint8_t ) ( address >> 8 ),
( uint8_t ) ( address >> 0 ),
length,
};
const lr11xx_status_t status = ( lr11xx_status_t ) lr11xx_hal_read(
context, cbuffer, LR11XX_SYSTEM_READ_INFOPAGE_CMD_LENGTH, ( uint8_t* ) data, length * sizeof( *data ) );
if( status == LR11XX_STATUS_OK )
{
for( uint8_t index = 0; index < length; index++ )
{
uint8_t* buffer_local = ( uint8_t* ) &data[index];
data[index] = ( ( uint32_t ) buffer_local[0] << 24 ) + ( ( uint32_t ) buffer_local[1] << 16 ) +
( ( uint32_t ) buffer_local[2] << 8 ) + ( ( uint32_t ) buffer_local[3] << 0 );
}
}
return status;
}
lr11xx_status_t lr11xx_system_read_uid( const void* context, lr11xx_system_uid_t unique_identifier )
{
const uint8_t cbuffer[LR11XX_SYSTEM_READ_UID_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_READ_UID_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_READ_UID_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_SYSTEM_READ_UID_CMD_LENGTH, unique_identifier,
LR11XX_SYSTEM_UID_LENGTH );
}
lr11xx_status_t lr11xx_system_read_join_eui( const void* context, lr11xx_system_join_eui_t join_eui )
{
const uint8_t cbuffer[LR11XX_SYSTEM_READ_JOIN_EUI_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_READ_JOIN_EUI_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_READ_JOIN_EUI_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_SYSTEM_READ_JOIN_EUI_CMD_LENGTH, join_eui,
LR11XX_SYSTEM_JOIN_EUI_LENGTH );
}
lr11xx_status_t lr11xx_system_read_pin( const void* context, lr11xx_system_pin_t pin )
{
const uint8_t cbuffer[LR11XX_SYSTEM_READ_PIN_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_READ_PIN_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_READ_PIN_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_SYSTEM_READ_PIN_CMD_LENGTH, pin,
LR11XX_SYSTEM_PIN_LENGTH );
}
lr11xx_status_t lr11xx_system_read_pin_custom_eui( const void* context, lr11xx_system_uid_t device_eui,
lr11xx_system_join_eui_t join_eui, uint8_t rfu,
lr11xx_system_pin_t pin )
{
const uint8_t cbuffer[LR11XX_SYSTEM_READ_PIN_CUSTOM_EUI_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_READ_PIN_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_READ_PIN_OC >> 0 ),
device_eui[0],
device_eui[1],
device_eui[2],
device_eui[3],
device_eui[4],
device_eui[5],
device_eui[6],
device_eui[7],
join_eui[0],
join_eui[1],
join_eui[2],
join_eui[3],
join_eui[4],
join_eui[5],
join_eui[6],
join_eui[7],
rfu,
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_SYSTEM_READ_PIN_CUSTOM_EUI_CMD_LENGTH, pin,
LR11XX_SYSTEM_PIN_LENGTH );
}
lr11xx_status_t lr11xx_system_get_random_number( const void* context, uint32_t* random_number )
{
const uint8_t cbuffer[LR11XX_SYSTEM_GET_RANDOM_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_GET_RANDOM_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_GET_RANDOM_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_SYSTEM_GET_RANDOM_CMD_LENGTH,
( uint8_t* ) random_number, sizeof( uint32_t ) );
}
lr11xx_status_t lr11xx_system_enable_spi_crc( const void* context, bool enable_crc )
{
const uint8_t cbuffer[LR11XX_SYSTEM_ENABLE_SPI_CRC_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_ENABLE_SPI_CRC_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_ENABLE_SPI_CRC_OC >> 0 ),
( enable_crc == true ) ? 0x01 : 0x00,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_ENABLE_SPI_CRC_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_system_drive_dio_in_sleep_mode( const void* context, bool enable_drive )
{
const uint8_t cbuffer[LR11XX_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_OC >> 8 ),
( uint8_t ) ( LR11XX_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_OC >> 0 ),
( enable_drive == true ) ? 0x01 : 0x00,
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_SYSTEM_DRIVE_DIO_IN_SLEEP_MODE_CMD_LENGTH, 0,
0 );
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
static void lr11xx_system_convert_stat1_byte_to_enum( uint8_t stat1_byte, lr11xx_system_stat1_t* stat1 )
{
if( stat1 != NULL )
{
stat1->is_interrupt_active = ( ( stat1_byte & 0x01 ) != 0 ) ? true : false;
stat1->command_status = ( lr11xx_system_command_status_t ) ( stat1_byte >> 1 );
}
}
static void lr11xx_system_convert_stat2_byte_to_enum( uint8_t stat2_byte, lr11xx_system_stat2_t* stat2 )
{
if( stat2 != NULL )
{
stat2->is_running_from_flash = ( ( stat2_byte & 0x01 ) != 0 ) ? true : false;
stat2->chip_mode = ( lr11xx_system_chip_modes_t ) ( ( stat2_byte & 0x0F ) >> 1 );
stat2->reset_status = ( lr11xx_system_reset_status_t ) ( ( stat2_byte & 0xF0 ) >> 4 );
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,940 @@
/*!
* @file lr11xx_wifi.c
*
* @brief Wi-Fi passive scan driver implementation for LR11XX
*
* The Clear BSD License
* Copyright Semtech Corporation 2021. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include "lr11xx_wifi.h"
#include "lr11xx_system_types.h"
#include "lr11xx_hal.h"
/*
* -----------------------------------------------------------------------------
* --- PRIVATE MACROS-----------------------------------------------------------
*/
#ifndef MIN
#define MIN( a, b ) ( ( a > b ) ? b : a )
#endif // MIN
/*!
* @brief Check if a value is inferior to another one - included
*/
#define IS_INFERIOR( value, max ) ( value <= max )
/*!
* @brief Check if a value is in between min and max - included
*/
#define IS_BETWEEN( value, min, max ) ( IS_INFERIOR(min, value) && IS_INFERIOR(value, max) )
/*!
* @brief Check if a value is in between 0x80 and 0xBF - included
*/
#define IS_BETWEEN_0x80_AND_0xBF( value ) IS_BETWEEN( value, 0x80, 0xBF )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE CONSTANTS -------------------------------------------------------
*/
#define LR11XX_WIFI_BASIC_COMPLETE_RESULT_SIZE ( 22 )
#define LR11XX_WIFI_BASIC_MAC_TYPE_CHANNEL_RESULT_SIZE ( 9 )
#define LR11XX_WIFI_MAX_SIZE_PER_SPI( single_size ) \
( single_size * ( LR11XX_WIFI_MAX_RESULT_PER_TRANSACTION( single_size ) ) )
#define LR11XX_WIFI_MAX_RESULT_PER_TRANSACTION( single_size ) \
( MIN( ( LR11XX_WIFI_READ_RESULT_LIMIT ) / ( single_size ), LR11XX_WIFI_N_RESULTS_MAX_PER_CHUNK ) )
#define LR11XX_WIFI_ALL_CUMULATIVE_TIMING_SIZE ( 16 )
#define LR11XX_WIFI_VERSION_SIZE ( 2 )
#define LR11XX_WIFI_READ_RESULT_LIMIT ( 1020 )
#define LR11XX_WIFI_COUNTRY_RESULT_LENGTH_SIZE ( 1 )
#define LR11XX_WIFI_EXTENDED_COMPLETE_RESULT_SIZE ( 79 )
#define LR11XX_WIFI_SCAN_SINGLE_COUNTRY_CODE_RESULT_SIZE ( 10 )
#define LR11XX_WIFI_MAX_COUNTRY_CODE_RESULT_SIZE \
( LR11XX_WIFI_MAX_COUNTRY_CODE * LR11XX_WIFI_SCAN_SINGLE_COUNTRY_CODE_RESULT_SIZE )
// Command length
#define LR11XX_WIFI_SCAN_CMD_LENGTH ( 2 + 9 )
#define LR11XX_WIFI_SEARCH_COUNTRY_CODE_CMD_LENGTH ( 2 + 7 )
#define LR11XX_WIFI_SCAN_TIME_LIMIT_CMD_LENGTH ( 2 + 9 )
#define LR11XX_WIFI_COUNTRY_CODE_TIME_LIMIT_CMD_LENGTH ( 2 + 7 )
#define LR11XX_WIFI_GET_RESULT_SIZE_CMD_LENGTH ( 2 )
#define LR11XX_WIFI_READ_RESULT_CMD_LENGTH ( 2 + 3 )
#define LR11XX_WIFI_RESET_CUMUL_TIMING_CMD_LENGTH ( 2 )
#define LR11XX_WIFI_READ_CUMUL_TIMING_CMD_LENGTH ( 2 )
#define LR11XX_WIFI_GET_SIZE_COUNTRY_RESULT_CMD_LENGTH ( 2 )
#define LR11XX_WIFI_READ_COUNTRY_CODE_CMD_LENGTH ( 2 + 2 )
#define LR11XX_WIFI_CFG_TIMESTAMP_AP_PHONE_CMD_LENGTH ( 2 + 4 )
#define LR11XX_WIFI_GET_VERSION_CMD_LENGTH ( 2 )
/*!
* @brief Wi-Fi scan power consumption in nA
*
* @note these numbers are given for information, it should be modified according to the used hardware.
*/
#define LR11XX_WIFI_CORRELATION_NA ( 12000000ULL )
#define LR11XX_WIFI_CAPTURE_NA ( 12000000ULL )
#define LR11XX_WIFI_DEMODULATION_NA ( 4000000ULL )
/*
* -----------------------------------------------------------------------------
* --- PRIVATE TYPES -----------------------------------------------------------
*/
/*!
* @brief Operating codes for Wi-Fi-related operations
*/
enum
{
LR11XX_WIFI_SCAN_OC = 0x0300,
LR11XX_WIFI_SCAN_TIME_LIMIT = 0x0301,
LR11XX_WIFI_SEARCH_COUNTRY_CODE_OC = 0x0302,
LR11XX_WIFI_COUNTRY_CODE_TIME_LIMIT_OC = 0x0303,
LR11XX_WIFI_GET_RESULT_SIZE_OC = 0x0305,
LR11XX_WIFI_READ_RESULT_OC = 0x0306,
LR11XX_WIFI_RESET_CUMUL_TIMING_OC = 0x0307,
LR11XX_WIFI_READ_CUMUL_TIMING_OC = 0x0308,
LR11XX_WIFI_GET_SIZE_COUNTRY_RESULT_OC = 0x0309,
LR11XX_WIFI_READ_COUNTRY_CODE_OC = 0x030A,
LR11XX_WIFI_CONFIGURE_TIMESTAMP_AP_PHONE_OC = 0x030B,
LR11XX_WIFI_GET_VERSION_OC = 0x0320,
};
/*!
* @brief Wi-Fi scan results interface
*/
typedef union
{
lr11xx_wifi_basic_complete_result_t* basic_complete;
lr11xx_wifi_basic_mac_type_channel_result_t* basic_mac_type_channel;
lr11xx_wifi_extended_full_result_t* extended_complete;
} lr11xx_wifi_result_interface_t;
/*
* -----------------------------------------------------------------------------
* --- PRIVATE VARIABLES -------------------------------------------------------
*/
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DECLARATION -------------------------------------------
*/
/*!
* @brief Return a uint16 value by reading a buffer of uint8 from index.
*
* This function interpret the array MSB first. It is equivalent to:
* return array[index] * 256 + array[index+1]
*
* @returns The uint16 value
*/
static uint16_t uint16_from_array( const uint8_t* array, const uint16_t index );
/*!
* @brief Return a uint64 value by reading a buffer of uint8 from index.
*
* This function interpret the array MSB first.
*
* @returns The uint64 value
*/
static uint64_t uint64_from_array( const uint8_t* array, const uint16_t index );
/*!
* @brief Propagate the result buffer interpretation depending on the format_code selected
*
* @see interpret_basic_complete_result_from_buffer, interpret_basic_mac_type_channel_result_from_buffer,
* interpret_extended_full_result_from_buffer
*/
static void generic_results_interpreter( const uint8_t n_result_to_parse, const uint8_t index_result_start_writing,
const uint8_t* buffer, lr11xx_wifi_result_interface_t result_interface,
const lr11xx_wifi_result_format_t format_code );
/*!
* @brief Parse basic complete result
*/
static void interpret_basic_complete_result_from_buffer( const uint8_t nb_results,
const uint8_t index_result_start_writing,
const uint8_t* buffer,
lr11xx_wifi_basic_complete_result_t* result );
/*!
* @brief Parse basic MAC - type - channel result
*/
static void interpret_basic_mac_type_channel_result_from_buffer( const uint8_t nb_results,
const uint8_t index_result_start_writing,
const uint8_t* buffer,
lr11xx_wifi_basic_mac_type_channel_result_t* result );
/*!
* @brief Parse extended full result
*/
static void interpret_extended_full_result_from_buffer( const uint8_t nb_results,
const uint8_t index_result_start_writing, const uint8_t* buffer,
lr11xx_wifi_extended_full_result_t* result );
/*!
* @brief Parse basic MAC - type - channel result
*/
static lr11xx_status_t fetch_and_aggregate_all_results( const void* context, const uint8_t index_result_start,
const uint8_t nb_results,
const uint8_t nb_results_per_chunk_max,
const lr11xx_wifi_result_format_t result_format_code,
uint8_t* result_buffer,
lr11xx_wifi_result_interface_t result_structures );
/*!
* @brief Share the size of a result format
*
* @returns Size in byte of the format given as parameter
*/
static uint8_t lr11xx_wifi_get_result_size_from_format( const lr11xx_wifi_result_format_t format );
/*!
* @brief Fetch results from the radio after a successful Wi-Fi passive scan
*
* @returns Operation status
*/
static lr11xx_hal_status_t lr11xx_wifi_read_results_helper( const void* context, const uint8_t start_index,
const uint8_t n_elem, uint8_t* buffer,
const lr11xx_wifi_result_format_t result_format );
/*!
* @brief Extract Wi-Fi MAC address from a buffer
*/
static void lr11xx_wifi_read_mac_address_from_buffer( const uint8_t* buffer, const uint16_t index_in_buffer,
lr11xx_wifi_mac_address_t mac_address );
/*!
* @brief Share the format code corresponding to a result format
*
* @returns Format code
*/
static uint8_t lr11xx_wifi_get_format_code( const lr11xx_wifi_result_format_t format );
/*
* -----------------------------------------------------------------------------
* --- PUBLIC FUNCTIONS DEFINITION ---------------------------------------------
*/
lr11xx_status_t lr11xx_wifi_scan( const void* context, const lr11xx_wifi_signal_type_scan_t signal_type,
const lr11xx_wifi_channel_mask_t channels, const lr11xx_wifi_mode_t scan_mode,
const uint8_t max_results, const uint8_t nb_scan_per_channel,
const uint16_t timeout_in_ms, const bool abort_on_timeout )
{
const uint8_t cbuffer[LR11XX_WIFI_SCAN_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_SCAN_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_SCAN_OC >> 0 ),
( uint8_t ) signal_type,
( uint8_t ) ( channels >> 8 ),
( uint8_t ) ( channels >> 0 ),
( uint8_t ) scan_mode,
max_results,
nb_scan_per_channel,
( uint8_t ) ( timeout_in_ms >> 8 ),
( uint8_t ) ( timeout_in_ms >> 0 ),
( uint8_t ) ( ( abort_on_timeout == true ) ? 1 : 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_WIFI_SCAN_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_wifi_search_country_code( const void* context, const lr11xx_wifi_channel_mask_t channels_mask,
const uint8_t nb_max_results, const uint8_t nb_scan_per_channel,
const uint16_t timeout_in_ms, const bool abort_on_timeout )
{
const uint8_t cbuffer[LR11XX_WIFI_SEARCH_COUNTRY_CODE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_SEARCH_COUNTRY_CODE_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_SEARCH_COUNTRY_CODE_OC >> 0 ),
( uint8_t ) ( channels_mask >> 8 ),
( uint8_t ) ( channels_mask >> 0 ),
nb_max_results,
nb_scan_per_channel,
( uint8_t ) ( timeout_in_ms >> 8 ),
( uint8_t ) ( timeout_in_ms >> 0 ),
( uint8_t ) ( ( abort_on_timeout == true ) ? 1 : 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_WIFI_SEARCH_COUNTRY_CODE_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_wifi_scan_time_limit( const void* radio, const lr11xx_wifi_signal_type_scan_t signal_type,
const lr11xx_wifi_channel_mask_t channels,
const lr11xx_wifi_mode_t scan_mode, const uint8_t max_results,
const uint16_t timeout_per_channel_ms, const uint16_t timeout_per_scan_ms )
{
const uint8_t cbuffer[LR11XX_WIFI_SCAN_TIME_LIMIT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_SCAN_TIME_LIMIT >> 8 ),
( uint8_t ) ( LR11XX_WIFI_SCAN_TIME_LIMIT >> 0 ),
( uint8_t ) signal_type,
( uint8_t ) ( channels >> 8 ),
( uint8_t ) ( channels >> 0 ),
( uint8_t ) scan_mode,
max_results,
( uint8_t ) ( timeout_per_channel_ms >> 8 ),
( uint8_t ) ( timeout_per_channel_ms >> 0 ),
( uint8_t ) ( timeout_per_scan_ms >> 8 ),
( uint8_t ) ( timeout_per_scan_ms >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( radio, cbuffer, LR11XX_WIFI_SCAN_TIME_LIMIT_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_wifi_search_country_code_time_limit( const void* radio,
const lr11xx_wifi_channel_mask_t channels,
const uint8_t max_results,
const uint16_t timeout_per_channel_ms,
const uint16_t timeout_per_scan_ms )
{
const uint8_t cbuffer[LR11XX_WIFI_COUNTRY_CODE_TIME_LIMIT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_COUNTRY_CODE_TIME_LIMIT_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_COUNTRY_CODE_TIME_LIMIT_OC >> 0 ),
( uint8_t ) ( channels >> 8 ),
( uint8_t ) ( channels >> 0 ),
( uint8_t ) max_results,
( uint8_t ) ( timeout_per_channel_ms >> 8 ),
( uint8_t ) ( timeout_per_channel_ms >> 0 ),
( uint8_t ) ( timeout_per_scan_ms >> 8 ),
( uint8_t ) ( timeout_per_scan_ms >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( radio, cbuffer, LR11XX_WIFI_COUNTRY_CODE_TIME_LIMIT_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_wifi_get_nb_results( const void* context, uint8_t* nb_results )
{
const uint8_t cbuffer[LR11XX_WIFI_GET_RESULT_SIZE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_GET_RESULT_SIZE_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_GET_RESULT_SIZE_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_read( context, cbuffer, LR11XX_WIFI_GET_RESULT_SIZE_CMD_LENGTH, nb_results,
sizeof( *nb_results ) );
}
lr11xx_status_t lr11xx_wifi_read_basic_complete_results( const void* context, const uint8_t start_result_index,
const uint8_t nb_results,
lr11xx_wifi_basic_complete_result_t* results )
{
uint8_t result_buffer[LR11XX_WIFI_MAX_SIZE_PER_SPI( LR11XX_WIFI_BASIC_COMPLETE_RESULT_SIZE )] = { 0 };
const uint8_t nb_results_per_chunk_max =
LR11XX_WIFI_MAX_RESULT_PER_TRANSACTION( LR11XX_WIFI_BASIC_COMPLETE_RESULT_SIZE );
lr11xx_wifi_result_interface_t result_interface = { 0 };
result_interface.basic_complete = results;
return fetch_and_aggregate_all_results( context, start_result_index, nb_results, nb_results_per_chunk_max,
LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE, result_buffer, result_interface );
}
lr11xx_status_t lr11xx_wifi_read_basic_mac_type_channel_results( const void* context, const uint8_t start_result_index,
const uint8_t nb_results,
lr11xx_wifi_basic_mac_type_channel_result_t* results )
{
uint8_t result_buffer[LR11XX_WIFI_MAX_SIZE_PER_SPI( LR11XX_WIFI_BASIC_MAC_TYPE_CHANNEL_RESULT_SIZE )] = { 0 };
const uint8_t nb_results_per_chunk_max =
LR11XX_WIFI_MAX_RESULT_PER_TRANSACTION( LR11XX_WIFI_BASIC_MAC_TYPE_CHANNEL_RESULT_SIZE );
lr11xx_wifi_result_interface_t result_interface = { 0 };
result_interface.basic_mac_type_channel = results;
return fetch_and_aggregate_all_results( context, start_result_index, nb_results, nb_results_per_chunk_max,
LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL, result_buffer,
result_interface );
}
lr11xx_status_t lr11xx_wifi_read_extended_full_results( const void* radio, const uint8_t start_result_index,
const uint8_t nb_results,
lr11xx_wifi_extended_full_result_t* results )
{
uint8_t result_buffer[LR11XX_WIFI_MAX_SIZE_PER_SPI( LR11XX_WIFI_EXTENDED_COMPLETE_RESULT_SIZE )] = { 0 };
const uint8_t nb_results_per_chunk_max =
LR11XX_WIFI_MAX_RESULT_PER_TRANSACTION( LR11XX_WIFI_EXTENDED_COMPLETE_RESULT_SIZE );
lr11xx_wifi_result_interface_t result_interface = { 0 };
result_interface.extended_complete = results;
return fetch_and_aggregate_all_results( radio, start_result_index, nb_results, nb_results_per_chunk_max,
LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL, result_buffer, result_interface );
}
lr11xx_status_t lr11xx_wifi_reset_cumulative_timing( const void* context )
{
const uint8_t cbuffer[LR11XX_WIFI_RESET_CUMUL_TIMING_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_RESET_CUMUL_TIMING_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_RESET_CUMUL_TIMING_OC >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_WIFI_RESET_CUMUL_TIMING_CMD_LENGTH, 0, 0 );
}
lr11xx_status_t lr11xx_wifi_read_cumulative_timing( const void* context, lr11xx_wifi_cumulative_timings_t* timing )
{
const uint8_t cbuffer[LR11XX_WIFI_READ_CUMUL_TIMING_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_READ_CUMUL_TIMING_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_READ_CUMUL_TIMING_OC >> 0 ),
};
uint8_t buffer_out[LR11XX_WIFI_ALL_CUMULATIVE_TIMING_SIZE] = { 0 };
const lr11xx_hal_status_t hal_status = lr11xx_hal_read( context, cbuffer, LR11XX_WIFI_READ_CUMUL_TIMING_CMD_LENGTH,
buffer_out, LR11XX_WIFI_ALL_CUMULATIVE_TIMING_SIZE );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
timing->rx_detection_us =
( buffer_out[0] << 24 ) + ( buffer_out[1] << 16 ) + ( buffer_out[2] << 8 ) + buffer_out[3];
timing->rx_correlation_us =
( buffer_out[4] << 24 ) + ( buffer_out[5] << 16 ) + ( buffer_out[6] << 8 ) + buffer_out[7];
timing->rx_capture_us =
( buffer_out[8] << 24 ) + ( buffer_out[9] << 16 ) + ( buffer_out[10] << 8 ) + buffer_out[11];
timing->demodulation_us =
( buffer_out[12] << 24 ) + ( buffer_out[13] << 16 ) + ( buffer_out[14] << 8 ) + buffer_out[15];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_wifi_get_nb_country_code_results( const void* context, uint8_t* country_result_size )
{
const uint8_t cbuffer[LR11XX_WIFI_GET_SIZE_COUNTRY_RESULT_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_GET_SIZE_COUNTRY_RESULT_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_GET_SIZE_COUNTRY_RESULT_OC >> 0 ),
};
uint8_t rbuffer[LR11XX_WIFI_COUNTRY_RESULT_LENGTH_SIZE] = { 0 };
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, LR11XX_WIFI_GET_SIZE_COUNTRY_RESULT_CMD_LENGTH, rbuffer,
LR11XX_WIFI_COUNTRY_RESULT_LENGTH_SIZE );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
( *country_result_size ) = rbuffer[0];
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_wifi_read_country_code_results( const void* context, const uint8_t start_result_index,
const uint8_t nb_country_results,
lr11xx_wifi_country_code_t* country_code_results )
{
const uint8_t cbuffer[LR11XX_WIFI_READ_COUNTRY_CODE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_READ_COUNTRY_CODE_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_READ_COUNTRY_CODE_OC >> 0 ),
start_result_index,
nb_country_results,
};
uint8_t rbuffer[LR11XX_WIFI_MAX_COUNTRY_CODE_RESULT_SIZE] = { 0 };
const uint16_t country_code_result_size_to_read =
nb_country_results * LR11XX_WIFI_SCAN_SINGLE_COUNTRY_CODE_RESULT_SIZE;
const lr11xx_hal_status_t hal_status = lr11xx_hal_read( context, cbuffer, LR11XX_WIFI_READ_COUNTRY_CODE_CMD_LENGTH,
rbuffer, country_code_result_size_to_read );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
for( uint8_t result_index = 0; result_index < nb_country_results; result_index++ )
{
const uint8_t local_index = result_index * LR11XX_WIFI_SCAN_SINGLE_COUNTRY_CODE_RESULT_SIZE;
lr11xx_wifi_country_code_t* local_country_code_result = &country_code_results[result_index];
local_country_code_result->country_code[0] = rbuffer[local_index + 0];
local_country_code_result->country_code[1] = rbuffer[local_index + 1];
local_country_code_result->io_regulation = rbuffer[local_index + 2];
local_country_code_result->channel_info_byte = rbuffer[local_index + 3];
for( uint8_t field_mac_index = 0; field_mac_index < LR11XX_WIFI_MAC_ADDRESS_LENGTH; field_mac_index++ )
{
local_country_code_result->mac_address[field_mac_index] =
rbuffer[local_index + ( LR11XX_WIFI_MAC_ADDRESS_LENGTH - field_mac_index - 1 ) + 4];
}
}
}
return ( lr11xx_status_t ) hal_status;
}
lr11xx_status_t lr11xx_wifi_cfg_timestamp_ap_phone( const void* context, uint32_t timestamp_in_s )
{
const uint8_t cbuffer[LR11XX_WIFI_CFG_TIMESTAMP_AP_PHONE_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_CONFIGURE_TIMESTAMP_AP_PHONE_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_CONFIGURE_TIMESTAMP_AP_PHONE_OC >> 0 ),
( uint8_t ) ( timestamp_in_s >> 24 ),
( uint8_t ) ( timestamp_in_s >> 16 ),
( uint8_t ) ( timestamp_in_s >> 8 ),
( uint8_t ) ( timestamp_in_s >> 0 ),
};
return ( lr11xx_status_t ) lr11xx_hal_write( context, cbuffer, LR11XX_WIFI_CFG_TIMESTAMP_AP_PHONE_CMD_LENGTH, 0,
0 );
}
lr11xx_status_t lr11xx_wifi_read_version( const void* context, lr11xx_wifi_version_t* wifi_version )
{
const uint8_t cbuffer[LR11XX_WIFI_GET_VERSION_CMD_LENGTH] = {
( uint8_t ) ( LR11XX_WIFI_GET_VERSION_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_GET_VERSION_OC >> 0 ),
};
uint8_t rbuffer[LR11XX_WIFI_VERSION_SIZE] = { 0 };
const lr11xx_hal_status_t hal_status =
lr11xx_hal_read( context, cbuffer, LR11XX_WIFI_GET_VERSION_CMD_LENGTH, rbuffer, LR11XX_WIFI_VERSION_SIZE );
if( hal_status == LR11XX_HAL_STATUS_OK )
{
wifi_version->major = rbuffer[0];
wifi_version->minor = rbuffer[1];
}
return ( lr11xx_status_t ) hal_status;
}
uint8_t lr11xx_wifi_get_nb_results_max_per_chunk( void )
{
return ( uint8_t ) LR11XX_WIFI_N_RESULTS_MAX_PER_CHUNK;
}
void lr11xx_wifi_parse_channel_info( const lr11xx_wifi_channel_info_byte_t channel_info, lr11xx_wifi_channel_t* channel,
bool* rssi_validity, lr11xx_wifi_mac_origin_t* mac_origin_estimation )
{
( *channel ) = lr11xx_wifi_extract_channel_from_info_byte( channel_info );
( *mac_origin_estimation ) = ( lr11xx_wifi_mac_origin_t ) ( ( channel_info & 0x30 ) >> 4 );
( *rssi_validity ) = ( ( channel_info & 0x40 ) == 0 ) ? true : false;
}
lr11xx_wifi_channel_t lr11xx_wifi_extract_channel_from_info_byte( const lr11xx_wifi_channel_info_byte_t channel_info )
{
return ( lr11xx_wifi_channel_t ) ( channel_info & 0x0F );
}
void lr11xx_wifi_parse_frame_type_info( const lr11xx_wifi_frame_type_info_byte_t frame_type_info,
lr11xx_wifi_frame_type_t* frame_type,
lr11xx_wifi_frame_sub_type_t* frame_sub_type, bool* to_ds, bool* from_ds )
{
( *frame_type ) = ( lr11xx_wifi_frame_type_t ) ( ( frame_type_info >> 6 ) & 0x03 );
( *frame_sub_type ) = ( lr11xx_wifi_frame_sub_type_t ) ( ( frame_type_info >> 2 ) & 0x0F );
( *to_ds ) = ( bool ) ( ( frame_type_info >> 1 ) & 0x01 );
( *from_ds ) = ( bool ) ( frame_type_info & 0x01 );
}
void lr11xx_wifi_parse_data_rate_info( const lr11xx_wifi_datarate_info_byte_t data_rate_info,
lr11xx_wifi_signal_type_result_t* wifi_signal_type,
lr11xx_wifi_datarate_t* wifi_data_rate )
{
( *wifi_signal_type ) = lr11xx_wifi_extract_signal_type_from_data_rate_info( data_rate_info );
( *wifi_data_rate ) = ( lr11xx_wifi_datarate_t ) ( data_rate_info >> 2 );
}
lr11xx_wifi_signal_type_result_t lr11xx_wifi_extract_signal_type_from_data_rate_info(
const lr11xx_wifi_datarate_info_byte_t data_rate_info )
{
return ( lr11xx_wifi_signal_type_result_t ) ( data_rate_info & 0x03 );
}
uint32_t lr11xx_wifi_get_consumption_nah( lr11xx_system_reg_mode_t regulator, lr11xx_wifi_cumulative_timings_t timing )
{
float wifi_scan_consumption_nah = 0;
wifi_scan_consumption_nah = ( ( float ) timing.rx_capture_us * LR11XX_WIFI_CAPTURE_NA ) +
( ( float ) timing.demodulation_us * LR11XX_WIFI_DEMODULATION_NA ) +
( ( float ) timing.rx_correlation_us * LR11XX_WIFI_CORRELATION_NA );
wifi_scan_consumption_nah = wifi_scan_consumption_nah /
( 3600000000.0 - ( ( float ) timing.rx_capture_us + ( float ) timing.demodulation_us +
( float ) timing.rx_correlation_us ) );
if( regulator == LR11XX_SYSTEM_REG_MODE_LDO )
{
wifi_scan_consumption_nah *= 2.0;
}
return ( uint32_t ) wifi_scan_consumption_nah;
}
/*
* -----------------------------------------------------------------------------
* --- PRIVATE FUNCTIONS DEFINITION --------------------------------------------
*/
static lr11xx_hal_status_t lr11xx_wifi_read_results_helper( const void* context, const uint8_t start_index,
const uint8_t n_elem, uint8_t* buffer,
const lr11xx_wifi_result_format_t result_format )
{
const uint8_t size_single_elem = lr11xx_wifi_get_result_size_from_format( result_format );
const uint8_t result_format_code = lr11xx_wifi_get_format_code( result_format );
const uint8_t cbuffer[LR11XX_WIFI_READ_RESULT_CMD_LENGTH] = { ( uint8_t ) ( LR11XX_WIFI_READ_RESULT_OC >> 8 ),
( uint8_t ) ( LR11XX_WIFI_READ_RESULT_OC & 0x00FF ),
start_index, n_elem, result_format_code };
const uint16_t size_total = n_elem * size_single_elem;
return lr11xx_hal_read( context, cbuffer, LR11XX_WIFI_READ_RESULT_CMD_LENGTH, buffer, size_total );
}
static uint16_t uint16_from_array( const uint8_t* array, const uint16_t index )
{
return ( uint16_t ) ( array[index] << 8 ) + ( ( uint16_t ) ( array[index + 1] ) );
}
static uint64_t uint64_from_array( const uint8_t* array, const uint16_t index )
{
return ( ( uint64_t ) ( array[index] ) << 56 ) + ( ( uint64_t ) ( array[index + 1] ) << 48 ) +
( ( uint64_t ) ( array[index + 2] ) << 40 ) + ( ( uint64_t ) ( array[index + 3] ) << 32 ) +
( ( uint64_t ) ( array[index + 4] ) << 24 ) + ( ( uint64_t ) ( array[index + 5] ) << 16 ) +
( ( uint64_t ) ( array[index + 6] ) << 8 ) + ( uint64_t ) ( array[index + 7] );
}
static void lr11xx_wifi_read_mac_address_from_buffer( const uint8_t* buffer, const uint16_t index_in_buffer,
lr11xx_wifi_mac_address_t mac_address )
{
for( uint8_t field_mac_index = 0; field_mac_index < LR11XX_WIFI_MAC_ADDRESS_LENGTH; field_mac_index++ )
{
mac_address[field_mac_index] = buffer[index_in_buffer + field_mac_index];
}
}
static uint8_t lr11xx_wifi_get_format_code( const lr11xx_wifi_result_format_t format )
{
uint8_t format_code = 0x00;
switch( format )
{
case LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE:
{
format_code = 0x01;
break;
}
case LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL:
{
format_code = 0x04;
break;
}
case LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL:
{
format_code = 0x01;
break;
}
}
return format_code;
}
static uint8_t lr11xx_wifi_get_result_size_from_format( const lr11xx_wifi_result_format_t format )
{
uint8_t result_size = 0;
switch( format )
{
case LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE:
{
result_size = LR11XX_WIFI_BASIC_COMPLETE_RESULT_SIZE;
break;
}
case LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL:
{
result_size = LR11XX_WIFI_BASIC_MAC_TYPE_CHANNEL_RESULT_SIZE;
break;
}
case LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL:
{
result_size = LR11XX_WIFI_EXTENDED_COMPLETE_RESULT_SIZE;
break;
}
}
return result_size;
}
static lr11xx_status_t fetch_and_aggregate_all_results( const void* context, const uint8_t index_result_start,
const uint8_t nb_results,
const uint8_t nb_results_per_chunk_max,
const lr11xx_wifi_result_format_t result_format_code,
uint8_t* result_buffer,
lr11xx_wifi_result_interface_t result_structures )
{
uint8_t index_to_read = index_result_start;
uint8_t index_result_start_writing = 0;
uint8_t remaining_results = nb_results;
lr11xx_hal_status_t hal_status = LR11XX_HAL_STATUS_OK;
while( remaining_results > 0 )
{
uint8_t results_to_read = MIN( remaining_results, nb_results_per_chunk_max );
lr11xx_hal_status_t local_hal_status = lr11xx_wifi_read_results_helper( context, index_to_read, results_to_read,
result_buffer, result_format_code );
if( local_hal_status != LR11XX_HAL_STATUS_OK )
{
return ( lr11xx_status_t ) local_hal_status;
}
generic_results_interpreter( results_to_read, index_result_start_writing, result_buffer, result_structures,
result_format_code );
// Reset the content of the result_buffer in case there are still results to fetch
{
const uint16_t result_buffer_size =
LR11XX_WIFI_MAX_SIZE_PER_SPI( lr11xx_wifi_get_result_size_from_format( result_format_code ) );
for( uint16_t index = 0; index < result_buffer_size; index++ )
{
result_buffer[index] = 0;
}
}
index_to_read += results_to_read;
index_result_start_writing += results_to_read;
remaining_results -= results_to_read;
}
return ( lr11xx_status_t ) hal_status;
}
static void generic_results_interpreter( const uint8_t n_result_to_parse, const uint8_t index_result_start_writing,
const uint8_t* buffer, lr11xx_wifi_result_interface_t result_interface,
const lr11xx_wifi_result_format_t format_code )
{
switch( format_code )
{
case LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE:
{
interpret_basic_complete_result_from_buffer( n_result_to_parse, index_result_start_writing, buffer,
result_interface.basic_complete );
break;
}
case LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL:
{
interpret_basic_mac_type_channel_result_from_buffer( n_result_to_parse, index_result_start_writing, buffer,
result_interface.basic_mac_type_channel );
break;
}
case LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL:
{
interpret_extended_full_result_from_buffer( n_result_to_parse, index_result_start_writing, buffer,
result_interface.extended_complete );
break;
}
}
}
static void interpret_basic_complete_result_from_buffer( const uint8_t nb_results,
const uint8_t index_result_start_writing,
const uint8_t* buffer,
lr11xx_wifi_basic_complete_result_t* result )
{
for( uint8_t result_index = 0; result_index < nb_results; result_index++ )
{
const uint16_t local_index_start = LR11XX_WIFI_BASIC_COMPLETE_RESULT_SIZE * result_index;
lr11xx_wifi_basic_complete_result_t* local_wifi_result = &result[index_result_start_writing + result_index];
local_wifi_result->data_rate_info_byte = buffer[local_index_start + 0];
local_wifi_result->channel_info_byte = buffer[local_index_start + 1];
local_wifi_result->rssi = buffer[local_index_start + 2];
local_wifi_result->frame_type_info_byte = buffer[local_index_start + 3];
lr11xx_wifi_read_mac_address_from_buffer( buffer, local_index_start + 4, local_wifi_result->mac_address );
local_wifi_result->phi_offset = uint16_from_array( buffer, local_index_start + 10 );
local_wifi_result->timestamp_us = uint64_from_array( buffer, local_index_start + 12 );
local_wifi_result->beacon_period_tu = uint16_from_array( buffer, local_index_start + 20 );
}
}
static void interpret_basic_mac_type_channel_result_from_buffer( const uint8_t nb_results,
const uint8_t index_result_start_writing,
const uint8_t* buffer,
lr11xx_wifi_basic_mac_type_channel_result_t* result )
{
for( uint8_t result_index = 0; result_index < nb_results; result_index++ )
{
const uint16_t local_index_start = LR11XX_WIFI_BASIC_MAC_TYPE_CHANNEL_RESULT_SIZE * result_index;
lr11xx_wifi_basic_mac_type_channel_result_t* local_wifi_result =
&result[index_result_start_writing + result_index];
local_wifi_result->data_rate_info_byte = buffer[local_index_start + 0];
local_wifi_result->channel_info_byte = buffer[local_index_start + 1];
local_wifi_result->rssi = buffer[local_index_start + 2];
lr11xx_wifi_read_mac_address_from_buffer( buffer, local_index_start + 3, local_wifi_result->mac_address );
}
}
void interpret_extended_full_result_from_buffer( const uint8_t nb_results, const uint8_t index_result_start_writing,
const uint8_t* buffer, lr11xx_wifi_extended_full_result_t* result )
{
for( uint8_t result_index = 0; result_index < nb_results; result_index++ )
{
const uint16_t local_index_start = LR11XX_WIFI_EXTENDED_COMPLETE_RESULT_SIZE * result_index;
lr11xx_wifi_extended_full_result_t* local_wifi_result = &result[index_result_start_writing + result_index];
local_wifi_result->data_rate_info_byte = buffer[local_index_start + 0];
local_wifi_result->channel_info_byte = buffer[local_index_start + 1];
local_wifi_result->rssi = buffer[local_index_start + 2];
local_wifi_result->rate = buffer[local_index_start + 3];
local_wifi_result->service = uint16_from_array( buffer, local_index_start + 4 );
local_wifi_result->length = uint16_from_array( buffer, local_index_start + 6 );
local_wifi_result->frame_control = uint16_from_array( buffer, local_index_start + 8 );
lr11xx_wifi_read_mac_address_from_buffer( buffer, local_index_start + 10, local_wifi_result->mac_address_1 );
lr11xx_wifi_read_mac_address_from_buffer( buffer, local_index_start + 16, local_wifi_result->mac_address_2 );
lr11xx_wifi_read_mac_address_from_buffer( buffer, local_index_start + 22, local_wifi_result->mac_address_3 );
local_wifi_result->timestamp_us = uint64_from_array( buffer, local_index_start + 28 );
local_wifi_result->beacon_period_tu = uint16_from_array( buffer, local_index_start + 36 );
local_wifi_result->seq_control = uint16_from_array( buffer, local_index_start + 38 );
for( uint8_t ssid_index = 0; ssid_index < LR11XX_WIFI_RESULT_SSID_LENGTH; ssid_index++ )
{
local_wifi_result->ssid_bytes[ssid_index] = buffer[local_index_start + ssid_index + 40];
}
local_wifi_result->current_channel = ( lr11xx_wifi_channel_t ) buffer[local_index_start + 72];
local_wifi_result->country_code[0] = buffer[local_index_start + 73];
local_wifi_result->country_code[1] = buffer[local_index_start + 74];
local_wifi_result->io_regulation = buffer[local_index_start + 75];
local_wifi_result->fcs_check_byte.is_fcs_checked = ( ( buffer[local_index_start + 76] & 0x01 ) == 0x01 );
local_wifi_result->fcs_check_byte.is_fcs_ok = ( ( buffer[local_index_start + 76] & 0x02 ) == 0x02 );
local_wifi_result->phi_offset = uint16_from_array( buffer, local_index_start + 77 );
}
}
bool lr11xx_wifi_is_well_formed_utf8_byte_sequence( const uint8_t* buffer, const uint8_t length )
{
uint8_t index = 0;
while( index < length )
{
if( IS_INFERIOR( buffer[index], 0x7F ) )
{
index += 1;
continue;
}
if( length - index >= 2 )
{
if( IS_BETWEEN( buffer[index], 0xC2, 0xDF ) && IS_BETWEEN_0x80_AND_0xBF( buffer[index + 1] ) )
{
index += 2;
continue;
}
if( length - index >= 3 )
{
if( ( buffer[index] == 0xE0 ) && IS_BETWEEN( buffer[index + 1], 0xA0, 0xBF ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) )
{
index += 3;
continue;
}
else if( IS_BETWEEN( buffer[index], 0xE1, 0xEC ) && IS_BETWEEN_0x80_AND_0xBF( buffer[index + 1] ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) )
{
index += 3;
continue;
}
else if( ( buffer[index] == 0xED ) && IS_BETWEEN( buffer[index + 1], 0x80, 0x9F ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) )
{
index += 3;
continue;
}
else if( IS_BETWEEN( buffer[index], 0xEE, 0xEF ) && IS_BETWEEN_0x80_AND_0xBF( buffer[index + 1] ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) )
{
index += 3;
continue;
}
if( length - index >= 4 )
{
if( ( buffer[index] == 0xF0 ) && IS_BETWEEN( buffer[index + 1], 0x90, 0xBF ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) && IS_BETWEEN_0x80_AND_0xBF( buffer[index + 3] ) )
{
index += 4;
continue;
}
else if( IS_BETWEEN( buffer[index], 0xF1, 0xF3 ) && IS_BETWEEN_0x80_AND_0xBF( buffer[index + 1] ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 3] ) )
{
index += 4;
continue;
}
else if( ( buffer[index] == 0xF4 ) && IS_BETWEEN( buffer[index + 1], 0x80, 0x8F ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 2] ) &&
IS_BETWEEN_0x80_AND_0xBF( buffer[index + 3] ) )
{
index += 4;
continue;
}
}
}
}
return false;
}
return true;
}
bool lr11xx_wifi_are_scan_mode_result_format_compatible( lr11xx_wifi_mode_t scan_mode,
lr11xx_wifi_result_format_t result_format )
{
switch( scan_mode )
{
case LR11XX_WIFI_SCAN_MODE_BEACON:
case LR11XX_WIFI_SCAN_MODE_BEACON_AND_PKT:
{
switch( result_format )
{
case LR11XX_WIFI_RESULT_FORMAT_BASIC_COMPLETE:
case LR11XX_WIFI_RESULT_FORMAT_BASIC_MAC_TYPE_CHANNEL:
{
return true;
}
default:
{
return false;
}
}
break;
}
case LR11XX_WIFI_SCAN_MODE_FULL_BEACON:
case LR11XX_WIFI_SCAN_MODE_UNTIL_SSID:
{
switch( result_format )
{
case LR11XX_WIFI_RESULT_FORMAT_EXTENDED_FULL:
{
return true;
}
default:
{
return false;
}
}
}
default:
{
return false;
}
}
}
/* --- EOF ------------------------------------------------------------------ */

View File

@@ -0,0 +1,220 @@
/*!
* @file lr11xx_hal.c
*
* @brief Hardware Abstraction Layer (HAL) implementation for lr1121
*
* The Clear BSD License
* Copyright Semtech Corporation 2024. 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.
*/
/*
* -----------------------------------------------------------------------------
* --- DEPENDENCIES ------------------------------------------------------------
*/
#include <stdlib.h>
#include <stdint.h>
#include "esp_lora_1121.h"
/*!
* @brief lr11xx_hal.h API implementation
*/
/*!
* @brief Function to wait the that lr1121 modem-e busy line raise to high
*
* @param [in] context Chip implementation context
* @param [in] timeout_ms timeout in millisec before leave the function
*
* @returns lr1121_hal_status_t
*/
static lr11xx_hal_status_t lr11xx_hal_wait_on_unbusy(const void *context, uint32_t timeout_ms);
lr11xx_hal_status_t lr11xx_hal_write(const void *context, const uint8_t *command,
const uint16_t command_length, const uint8_t *data,
const uint16_t data_length)
{
#if defined(USE_LR11XX_CRC_OVER_SPI)
uint8_t cmd_crc = lr11xx_hal_compute_crc(0xFF, command, command_length);
if (data_length > 0){
cmd_crc = lr11xx_hal_compute_crc(cmd_crc, data, data_length);
}
#endif
if (lr11xx_hal_wait_on_unbusy(context, 10000) == LR11XX_HAL_STATUS_OK)
{
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* Send CMD */
lora_spi_write_bytes(context, (uint8_t *)command, command_length);
/* Send Data */
if (data_length > 0)
{
lora_spi_write_bytes(context, (uint8_t *)data, data_length);
}
#if defined(USE_LR11XX_CRC_OVER_SPI)
lora_spi_write_bytes(context, &cmd_crc, 1);
#endif
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
return LR11XX_HAL_STATUS_OK;
}
return LR11XX_HAL_STATUS_ERROR;
}
lr11xx_hal_status_t lr11xx_hal_read(const void *context, const uint8_t *command,
const uint16_t command_length, uint8_t *data,
const uint16_t data_length)
{
#if defined(USE_LR11XX_CRC_OVER_SPI)
const uint8_t cmd_crc = lr11xx_hal_compute_crc(0xFF, command, command_length);
#endif
uint8_t dummy_byte_rx = LR11XX_NOP;
if (lr11xx_hal_wait_on_unbusy(context, 10000) == LR11XX_HAL_STATUS_OK)
{
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* Send CMD */
// uint8_t rx_data[16] = {0};
lora_spi_write_bytes(context, (uint8_t *)command, command_length);
#if defined(USE_LR11XX_CRC_OVER_SPI)
lora_spi_write_bytes(context, &cmd_crc, 1);
#endif
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
/* Wait on busy pin up to 1000 ms */
if (lr11xx_hal_wait_on_unbusy(context, 1000) != LR11XX_HAL_STATUS_OK)
{
return LR11XX_HAL_STATUS_ERROR;
}
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
/* dummy read */
lora_spi_read_bytes(context, &dummy_byte_rx, 1);
lora_spi_read_bytes(context, data, data_length);
#if defined(USE_LR11XX_CRC_OVER_SPI)
uint8_t crc_rx;
lora_spi_read_bytes(context, &crc_rx, 1);
#endif
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
#if defined( USE_LR11XX_CRC_OVER_SPI )
uint8_t crc_computed = lr11xx_hal_compute_crc( 0xFF, &dummy_byte_rx, 1 );
if(data_length > 0)
{
crc_computed = lr11xx_hal_compute_crc( crc_computed, data, data_length );
}
if( crc_rx != crc_computed )
{
return LR11XX_HAL_STATUS_ERROR;
}
#endif
return LR11XX_HAL_STATUS_OK;
}
return LR11XX_HAL_STATUS_ERROR;
}
lr11xx_hal_status_t lr11xx_hal_direct_read(const void *context, uint8_t *data,
const uint16_t data_length)
{
if (lr11xx_hal_wait_on_unbusy(context, 10000) == LR11XX_HAL_STATUS_OK)
{
/* NSS low */
gpio_set_level(((lr1121_t *)context)->cs, 0);
lora_spi_read_bytes(context, data, data_length);
/* NSS high */
gpio_set_level(((lr1121_t *)context)->cs, 1);
return LR11XX_HAL_STATUS_OK;
}
return LR11XX_HAL_STATUS_ERROR;
}
lr11xx_hal_status_t lr11xx_hal_reset(const void *context)
{
if (((lr1121_t *)context)->reset < 0)
{
return LR11XX_HAL_STATUS_OK;
}
gpio_set_level(((lr1121_t *)context)->reset, 0);
vTaskDelay(10 / portTICK_PERIOD_MS);
gpio_set_level(((lr1121_t *)context)->reset, 1);
return LR11XX_HAL_STATUS_OK;
}
lr11xx_hal_status_t lr11xx_hal_wakeup(const void *context)
{
/* Wakeup radio */
gpio_set_level(((lr1121_t *)context)->cs, 0);
vTaskDelay(10 / portTICK_PERIOD_MS);
gpio_set_level(((lr1121_t *)context)->cs, 1);
/* Wait on busy pin for 1000 ms */
return LR11XX_HAL_STATUS_OK;
}
static lr11xx_hal_status_t lr11xx_hal_wait_on_unbusy(const void *context, uint32_t timeout_ms)
{
#if 0
while( gpio_get_level( ( ( lr1121_t* ) context )->busy ) == 1 )
{
;
}
#else
if (((lr1121_t *)context)->busy < 0)
{
return LR11XX_HAL_STATUS_OK;
}
uint32_t start = esp_timer_get_time() / 1000;
uint32_t current = 0;
while (gpio_get_level(((lr1121_t *)context)->busy) == 1)
{
current = esp_timer_get_time() / 1000;
if ((int32_t)(current - start) > (int32_t)timeout_ms)
{
return LR11XX_HAL_STATUS_ERROR;
}
}
#endif
return LR11XX_HAL_STATUS_OK;
}

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 "")

Some files were not shown because too many files have changed in this diff Show More